
Research
/Security News
16 Malicious Firefox Extensions Steal Cryptocurrency Wallet Credentials
Socket found 16 malicious Firefox extensions designed to steal crypto wallet recovery phrases and private keys using cloned Rabby and OKX interfaces.
Clean up vibecoded repos: generate a grounded README and keep an issue trail. Zero dependencies.
Two checks that make an AI-generated repo look maintained. Generates a README from what your code actually contains, and warns when a feature-sized commit has no issue behind it.
You shipped something from v0, Bolt, Lovable, or a long Claude session. It works. The README still says Getting Started with Create React App, there is no record of why anything was built, and the changelog does not exist. vibetidy fixes those two things and stops.
npx vibetidy readme # generate README.md, review the diff, confirm
npx vibetidy issue-check --install-hook # nag on feature commits with no issue
readme — scans the repository (manifest, scripts, dependencies, .env.example, entry points, folder tree, existing README), sends only those verified facts to an LLM, and writes a README in a fixed structure: What it does / Requirements / Setup / Run / Reference / Tech stack / Repository layout / Notes. Shows a diff and waits for confirmation before touching the file.issue-check — classifies your staged changes. New source files or a substantial diff means "feature"; lockfiles, build output, docs and tests are excluded. If it is a feature and no issue number appears in the branch name or the commits, it says so. Offers to create the issue with gh and writes a changelog/unreleased/ fragment.npx vibetidy downloads one package, not three hundred.The scanner is the product; the model is a formatter. Everything the README is allowed to claim comes from the scan, and the prompt says so explicitly: never invent a feature, a flag, an environment variable, a dependency, or a version. When the facts are thin, you get a short accurate README instead of a long plausible one.
You can see exactly what would be sent, with no API key:
npx vibetidy readme --print-context
readme, and only when actually generating. --print-context needs nothing.git, for issue-check.gh), optional — only for the offer-to-create-an-issue path. Everything else works without it.No install step: npx vibetidy <command> runs the latest version. To install it permanently:
npm install -g vibetidy
Point it at a provider with one environment variable:
export OPENAI_API_KEY=sk-... # default provider
# or
export OPENROUTER_API_KEY=sk-or-... # then: --provider openrouter
| Variable | Required | Purpose |
|---|---|---|
OPENAI_API_KEY | for readme on the default provider | OpenAI API key |
VIBETIDY_API_KEY | no | Overrides whichever provider key would otherwise be used |
VIBETIDY_PROVIDER | no | openai (default), openrouter, anthropic, groq, deepseek, together, ollama, lmstudio |
VIBETIDY_MODEL | no | Model id, overriding the provider default |
VIBETIDY_BASE_URL | no | Any other OpenAI-compatible endpoint |
SKIP_ISSUE_CHECK | no | Set to 1 to bypass the pre-commit hook once |
Each provider also reads its own key variable (ANTHROPIC_API_KEY, GROQ_API_KEY, DEEPSEEK_API_KEY, TOGETHER_API_KEY). Local providers need no key at all:
npx vibetidy readme --provider ollama --model llama3.1
npx vibetidy readme # current directory
npx vibetidy readme ./packages/api # somewhere else
npx vibetidy issue-check # check what is staged
npx vibetidy --help
vibetidy readme [path]Scans a repository and writes a README grounded in what it finds. Nothing is written until you confirm.
npx vibetidy readme --print-context # inspect the facts and prompt, no key needed
npx vibetidy readme --dry-run # generate and diff, never write
npx vibetidy readme --yes # write without the prompt (for CI)
| Option | Purpose |
|---|---|
--print-context | Print the scanned facts and the full prompt, then exit |
--dry-run | Generate and show the diff, but never write |
--yes, -y | Skip the confirmation and write |
--output <file> | Write somewhere other than README.md |
--hint <text> | Extra context treated as verified fact — useful when the code alone does not say what the project is for |
--provider <name> | Provider preset (see the table above) |
--model <id> | Override the provider's default model |
--base-url <url> | Any other OpenAI-compatible endpoint |
When a README already exists, accurate prose is preserved and stale claims are rewritten. A README that is still the untouched scaffolding default is detected and replaced outright.
Without a TTY (CI, a pipe) the confirmation cannot be answered, so nothing is written and the command exits 1 — pass --yes for non-interactive runs.
vibetidy issue-check [path]Checks the staged changes — or, with nothing staged, the branch against its base — and looks for an issue number.
npx vibetidy issue-check # warn (exit 0)
npx vibetidy issue-check --strict # block (exit 1)
npx vibetidy issue-check --against main # check a whole branch, e.g. in CI
npx vibetidy issue-check --install-hook # install the pre-commit hook
| Option | Purpose |
|---|---|
--strict | Exit 1 instead of warning |
--threshold <n> | Inserted lines that make a change feature-sized (default 40) |
--against <ref> | Compare against a ref instead of the staged changes |
--create | Create the issue via gh without asking first |
--skip-changelog | Do not write a changelog fragment when creating an issue |
--install-hook | Install the pre-commit hook |
--uninstall-hook | Remove the hook block |
--hook | Hook mode: quieter, never prompts |
What counts as a feature. A new source file, or more than --threshold inserted lines. Lockfiles, dist/, build/, node_modules/, generated directories, minified files, docs and tests are all excluded from the count — a 4000-line lockfile churn is not a feature.
Where it looks for the issue. The branch name (feat/42-add-oauth, 42-add-oauth, issue-42, gh-42) first, then the commit messages on the branch (#42, Closes #42, GH-42). A version number in a branch name (feat/add-oauth2-login) is not mistaken for an issue.
It warns; it does not block. A hook that blocks on day one gets --no-verify'd on day two. Add --strict to the installed hook when the habit has stuck.
npx vibetidy issue-check --install-hook
Writes .git/hooks/pre-commit, honouring core.hooksPath. If a hook already exists, vibetidy asks before appending its block and never overwrites what is there. The block is delimited by markers, so --uninstall-hook removes exactly it and leaves the rest.
If vibetidy is not installed when the hook runs, the block does nothing. A missing tool is never the reason a commit fails.
Bypass one commit with SKIP_ISSUE_CHECK=1 git commit ..., or all hooks with git commit --no-verify.
When gh is installed and authenticated, issue-check offers to file the issue for you. It searches open and closed issues first so you do not file a duplicate, creates the feature / bug / chore labels if missing, and writes the body in a fixed shape:
## Need
Why this is needed.
## Proposal
The shape of the solution.
## Done when
- [ ] Acceptance criteria
It then writes changelog/unreleased/<branch-slug>.md and stages it:
### Added
- Add loyalty banner to checkout (#42)
One fragment file per branch, never a direct edit to CHANGELOG.md. Two pull requests appending a line to the same file on the same day collide on merge; two files named after different branches cannot. Fold the fragments into CHANGELOG.md whenever you cut a release.
| Layer | Technology |
|---|---|
| Runtime | Node.js >= 20.10, ES modules |
| CLI parsing | node:util parseArgs |
| HTTP | global fetch |
| Tests | node:test |
| Runtime dependencies | none |
.
├── bin/
│ └── vibetidy.js # executable entry point
├── src/
│ ├── cli.js # argument parsing and command dispatch
│ ├── index.js # programmatic API
│ ├── commands/
│ │ ├── readme.js # scan -> generate -> diff -> write
│ │ └── issue-check.js # classify -> find refs -> warn/create
│ └── lib/
│ ├── scan.js # repository facts (the grounding layer)
│ ├── issues.js # feature heuristic and issue-ref parsing
│ ├── template.js # README structure and the prompt
│ ├── llm.js # OpenAI-compatible client
│ ├── gh.js # optional GitHub CLI integration
│ ├── hook.js # pre-commit hook install/uninstall
│ ├── diff.js # diff preview
│ └── git.js # git wrappers
└── test/ # node:test suite, no network
readme shows a diff and waits; issue-check only writes when it creates an issue for you, and then only a changelog fragment.--hint is there for exactly that.readme sends repository metadata to your chosen provider: manifest contents, dependency names, script names, environment variable names (never values — it reads .env.example, never .env), the folder tree, and the existing README. It never sends your source code. Use --print-context to see the payload, or --provider ollama to keep it on your machine.import { scan, classifyChange, findIssueRefs } from 'vibetidy';
See CONTRIBUTING.md. Issues and pull requests are welcome.
MIT — see LICENSE.
FAQs
Clean up vibecoded repos: generate a grounded README and keep an issue trail. Zero dependencies.
We found that vibetidy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Research
/Security News
Socket found 16 malicious Firefox extensions designed to steal crypto wallet recovery phrases and private keys using cloned Rabby and OKX interfaces.

Product
Socket now scans VS Code extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.

Research
/Security News
Socket uncovered two malicious VS Code themes in a GlassWorm-linked cluster with thousands of installs across VS Code Marketplace and Open VSX.