Get started with VibeDrift
VibeDrift scans your AI-generated project for contradictions and gives you a score with file-level evidence.
GuideWhat is drift?
Your AI forgets between sessions.
When you use AI to write code across multiple sessions, each session starts fresh. Session 1 uses a repository pattern. Session 3 switches to raw SQL. Session 7 introduces an ORM. None are wrong individually, but together they create drift: a codebase that contradicts itself.
VibeDrift discovers the patterns your code already follows and finds the exceptions. It's a consistency checker, not a style enforcer. A codebase isn't wrong because it uses raw SQL, it's drifting because 8 handlers use a repository and 2 don't.
Drift also shows up as sprawl: the same logic re-implemented again and again across many files because each AI session didn't know the helper already existed. When that re-implementation is dense enough across the codebase, it's a drift signal in its own right, and deep scans now factor it into your score (see Deep scans). A single legacy parallel implementation sitting in otherwise clean code is not penalized, it's the dense, repeated reinvention that counts.
Set up once.
VibeDrift is a Node.js CLI. You need Node 20 or newer. It scans JavaScript, TypeScript, Python, Go, and Rust. No config file, no API key, no signup needed for your first scan.
Stay on the latest
vibedrift update or npm i -g @vibedrift/cli@latest.Run your first scan.
The default output is an HTML report that opens in your browser. The headline is the Vibe Drift Score, 0-100 with an A-F letter grade, measuring how consistently your codebase follows its own cross-file patterns. Alongside it you get a separate, independent Hygiene Score (also 0-100) for generic quality findings like complexity, dead code, and TODOs. The two are independent, hygiene does not move the drift score. The full report is open to everyone, no account needed.
Results appear the moment the scan finishes. Signed out, the report is served on localhost; signed in, the same scan also links to your dashboard so you can track the score over time.
Run it alongside your AI session:
While the watcher is running, every time your agent edits a file, VibeDrift refreshes .vibedrift/context.md, fix-plan.md, and patterns.json so the next AI turn sees up-to-date peer context. Watch mode runs --local-only, so it makes zero network calls. It's a Pro feature, the watcher emits full finding details continuously.
Tell VibeDrift what to scan.
VibeDrift checks your codebase against itself, so it's worth telling it which files are actually yours. Test fixtures, generated code, and vendored files aren't, and scoring them just adds noise. Set this up once:
init detects likely fixtures and generated code, then asks which paths to skip, your CI score floor, and your default report format. It writes two committable files:
Exclude paths without the wizard:
.vibedriftignore uses gitignore syntax and is honored by both the CLI and the MCP server, so excluded paths stop counting toward your score in either (init and ignore refresh the baseline for you). Agents can set up a fresh repo in-loop too: the MCP exposes an init tool that writes the same files.
Unlock deep scans & dashboard.
Free scans run locally with no account. Sign in to unlock deep scans and the dashboard. Full scan history and score trends are part of Pro.
Your monthly allotment (Free 1, Pro 12) and any top-up credits draw from one shared pool, so status shows both. Top-up credits never expire. Run vibedrift usage for the current billing-period scan counts and limits.
AI-powered analysis.
Deep scans add cloud AI on top of the local scan. The CLI sends function snippets only (not full files, never git history) to the VibeDrift API.
Scope a deep scan to changed files with --diff for a fast pre-PR check: vibedrift . --deep --diff compares uncommitted changes against HEAD, and vibedrift . --deep --diff main deep-scans everything that differs from a branch.
What deep scan adds:
- AI finds semantic duplicates that look different but do the same thing
- AI detects when function names don't match their behavior
- AI validates ambiguous findings (confirmed vs disputed)
- Concentrated reimplementation (AI sprawl) is detected and factored into your score
- AI generates a summary with actionable recommendations
Reimplementation scoring (0.14.6). On deep scans, the same logic re-built densely across many files lowers your Vibe Drift Score, because that's AI sprawl, not real structure. The penalty only kicks in when the reimplementation is genuinely concentrated; a single legacy or parallel implementation sitting in otherwise clean code stays informational and never costs you points. Local and free scores are unchanged by this, it applies only to the deep (AI) pass.
Deep findings aren't only a CLI thing. Your AI agent can trigger a deep check in-editor through the MCP deep-scan nudge (see MCP server); those in-loop checks draw a small fraction of a deep scan from the same shared pool.
Privacy: Only function snippets (max 60 lines each) are sent. Never full files, git history, or env vars. Processed in memory, never stored.
Local-only mode: Use --local-only to skip ALL network calls even when logged in, no scan log, no beacon, no deep analysis, no fix-prompt synthesis. Useful for:
- Air-gapped or restricted environments with no outbound internet
- Scanning sensitive codebases where zero egress is a requirement
- Offline development (airplane, train, no WiFi)
- Quick local iterations where upload latency isn't wanted
Telemetry: The analysis runs on your machine. After each scan VibeDrift sends a small anonymous usage beacon (language, file count, lines of code, scan time, CLI version, finding count, score, and four yes-or-no flags, with no code, no file paths, and no identifiers), on by default for everyone whether you are signed in or not. Signed in, scan results also sync to your dashboard, including file paths and short excerpts from findings. Turn the beacon off anytime:
You can also set VIBEDRIFT_TELEMETRY_DISABLED=1, or run --local-only for a fully offline scan with zero network calls. The CLI also checks npm about once a day for updates, controlled by the same flags.
Live peer-pattern context for your AI agent.
VibeDrift's headline feature isn't the scan report, it's the .vibedrift/ folder it writes alongside your CLAUDE.md. Commit it. Your AI coding agent reads it automatically on every new turn and knows exactly which pattern to match.
Without this, every AI session starts cold, it sees the file in front of it but not the 8 sibling files that follow your dominant pattern. So it drifts. The .vibedrift/ folder closes that gap.
One-shot, after a refactor:
Continuous, alongside your AI session:
Point it at your project while Cursor or Claude Code is working. Watch mode runs --local-only, so every save triggers a local rescan with zero network calls and the context files update before the agent's next turn.
Commit it to git. Reference it in CLAUDE.md so every AI session picks it up:
Both --write-context and vibedrift watch need a one-time vibedrift login, the .vibedrift/ files carry the full finding surface and the Pro fix-prompt synthesis. The HTML report itself is open to everyone, no account required.
VibeDrift inside your AI agent (MCP).
The .vibedrift/ folder gives your agent context to read. The MCP server goes further: it lets your agent ask VibeDrift questions while it writes, "what's this repo's error-handling pattern?", "does a function like this already exist?", "would this change introduce drift?", and get an answer from your own code. That turns drift detection into drift prevention.
The core tools are free for everyone, including signed-out users. They run entirely on your machine and never send your code, so your code never leaves your laptop. There's nothing to unlock and no plan to be on, install the server and your agent can use them right away.
Two of them, validate_change and find_similar_function, also take an opt-in deep: true that runs the full deep scan on the single function being checked, intent-mismatch detection plus AI-validated semantic duplicates, so the agent catches a misleading name or a near-clone before the code lands. This is the one metered part: deep mode sends only that one function to the API and draws a small fraction of a deep scan per check from your monthly deep-scan allotment or shared scan pool (hourly-capped, and it falls back to the local result if your budget is empty). Local tools free, deep checks metered.
1. Install the server (once per machine). On Claude Code, VibeDrift is a plugin, two commands wire in the MCP server and the skills with no config editing:
Then run /vibedrift:setup in a repo to give it a baseline. It suggests scan excludes and applies only what you confirm, builds the baseline, writes your repo's dominant patterns into CLAUDE.md, and offers Drift Sessions behind Claude Code's own consent prompt. That last part is per repository only if you want it to be: one folder grant covers every repository under a folder at once, including ones you clone later. If you previously ran claude mcp add vibedrift, run claude mcp remove vibedrift so the server isn't wired in twice. The manual command still works on Claude Code too:
VibeDrift is a standard MCP server, so every other client launches it with the same command. For Cursor (~/.cursor/mcp.json or project .cursor/mcp.json), and for Claude Desktop, Windsurf, Cline, VS Code, Zed and the rest, paste the same block into that client's MCP config, only the location changes, never the command:
2. Build the baseline, run one scan in the repo so the tools have your patterns to read (one-time, then cached):
3. Just code. Your agent calls these tools on its own:
get_dominant_pattern- the repo's convention for a dimension + files to copy
find_similar_function- does a near-duplicate already exist? (reuse, don't re-write)
check_file_drift- does this file match the repo's patterns?
validate_change- would this change introduce drift or a duplicate?
get_intent_hints- the conventions your CLAUDE.md / AGENTS.md declare
init- one-time, writes .vibedrift/config.json + .vibedriftignore on a fresh repo
What changes. Ask your agent to "add a function to cancel a subscription" and, instead of guessing, it checks your repo first:
The core tools run entirely on your machine and are free on any plan, signed in or not. If a tool returns no_baseline, run vibedrift . once to build it. The only thing that can run out is your deep-scan budget: when a deep: true check has nothing left to draw from, it quietly falls back to the local result and points you to top up.
Turn it on once for your whole workspace (preview).
The MCP tools answer when your agent asks. Drift Sessions goes a step further: it rides along inside your Claude Code session and speaks up on its own, the moment an edit drifts from your repo's patterns, so the agent can fix it in the same turn.
You turn it on once, for a folder, not once per repository. Point --dir at the folder you keep your work in, and every repository under it is covered, including ones you clone next month. VibeDrift shows you the resolved path and asks you to confirm by typing; it refuses your home directory and filesystem roots, because a grant that broad is not a choice anyone can meaningfully make.
A worked example. Say you keep three repositories side by side:
One command, vibedrift enable --dir ~/work, and one typed yes covers all three. There is nothing to run inside billing-worker, nothing inside admin-console, and nothing to remember when you clone a fourth repository into ~/work tomorrow: it is covered the first time your agent opens it. If you ever want one of them left out, run vibedrift decline inside it; an explicit no always wins over the folder grant.
What the dashboard then shows. An afternoon where your agent moved between all three repositories is one session, on one row, with the repositories it touched named on it. Open the row and you get the split: how many edits VibeDrift saw in each repository, how many of those edits it actually checked, and what it flagged, fixed, parked or declined in each. The session page carries the same split, plus a filter so you can read the event tape one repository at a time.
Checked is its own number, and it matters. VibeDrift can only compare an edit against a repository's patterns once it has learned them, so a repository you have never scanned records its edits and marks every one of them unchecked. The dashboard shows a dash there rather than a zero, because "nothing was flagged" and "nothing was looked at" are not the same sentence. To turn a repository from unchecked into watched, scan it once; from then on its sessions are checked.
You can still turn on a single repository if that is all you want. Run it inside the project; typing the command is the consent, and that is the whole setup.
With the Claude Code plugin installed, the hooks are already on your machine for every repository, so a folder grant is genuinely all the setup there is; a repository-local install writes the hooks into that one repository instead. Either way, as your agent edits files, VibeDrift checks the edits it can check for four kinds of drift (async style, return shape, data access, and duplicates of functions you already have), each judged against the directory being edited. It streams a running tape of prompts, edits, and flags, and hands the agent a one-line advisory whenever something drifts.
The agent can accept, park, or decline each flag with a reason (through the respond_to_flag MCP tool), and a finding only counts as resolved when the same check re-runs on the re-edited file and passes. Everything is recorded to a local, append-only ledger under ~/.vibedrift/sessions/, secrets in prompts are masked, and capture is fail-open, so it never blocks or breaks your session.
Local by default. Your code and prompts never leave your machine. Because it is a Pro feature, watch-session checks your account with the server when it starts to confirm your Pro or trial access, and that is the only network call it makes on its own. Session data is uploaded only if you opt into the hosted session dashboard with --sync on, a derived-only projection: event types, categories, outcomes, decisions and counts, never your code or prompts. File paths travel as per-repo pseudonyms unless you choose to share names.
Watching is optional. vibedrift enable is all you need. watch-session opens the live tape above and follows along until you stop it, so it is a viewer rather than a second setup step, though it will install the hooks itself if the repo does not have them yet. The two differ in one way worth knowing: enable lets the Claude Code plugin provide the hooks when the installed plugin ships them, so nothing is written into your repo, while watch-session always writes them into that repo and that copy then owns the capture.
Drift Sessions is a preview, and a Pro feature with a one-time trial of five sessions. The trial sessions are full-featured; after that the live tape locks behind a summary of what the trial caught. Your local ledgers always remain yours.
The shapes drift takes.
Under the hood VibeDrift tracks 13 cross-file drift categories, but they roll up into a handful of patterns you'll actually recognize. These are the ones that bite. Click each to see an example.
Architectural Contradictions
The AI chose three different data access patterns across your handlers.
Security Gaps
Auth middleware on 8 routes. Missing on 2.
Hidden Duplicates
Same function, different file, different variable names.
formatCurrency(val) {
return '$' + val.toFixed(2);
}toUSD(amount) {
return '$' + amount.toFixed(2);
}Naming Inconsistency
camelCase on Monday. snake_case on Wednesday. PascalCase on Friday.
Phantom Scaffolding
You asked for a read endpoint. The AI generated full CRUD.
Implementation Gaps
Functions that advertise a shape they don't actually compute. Placeholder returns, NotImplementedError, unimplemented!()
Concentrated Reimplementation (AI sprawl)
The same logic rebuilt over and over across many files because each session didn't know the helper already existed. When it's this dense, deep scans factor it into your score; a single legacy parallel copy in clean code stays informational.
Unlike the other types here, this one is a deep-scan scoring signal layered on duplication detection, not one of the 13 local drift categories. Local scans surface the duplicates; deep scans weigh how concentrated they are and fold that into your score.
Three layers, progressive depth.
Layer 1 and Layer 1.7 run locally on your machine (free; signed out, no source code or file paths are sent). Layer 2 adds cloud AI on a sample of your functions. After each scan the CLI sends a small anonymous usage beacon; turn it off with --local-only or vibedrift telemetry disable.
- 1
Static + Cross-File Analysis
13 static analyzers (naming, imports, error handling, complexity, security) plus 14 cross-file drift detectors that compare files against each other to find the dominant pattern and flag deviations.
- 1.7
Code DNA
Structural fingerprinting. Hash-based duplicate detection. Operation sequence analysis. Taint tracking.
- 2
Deep Scan (AI)
ML semantic embeddings for duplicates static analysis can't see. Intent mismatch detection. AI validation. Concentrated-reimplementation scoring. AI summary.
Most drift is caught locally for free; the deep (AI) pass adds the semantic findings, intent mismatches, and reimplementation scoring that pattern matching alone can't reach.
Understanding your score.
Score grades:
- A
- 90-100
- Highly consistent, minimal drift
- B
- 75-89
- Good shape, a few areas to clean up
- C
- 50-74
- Notable drift, review the findings
- D
- 25-49
- Significant issues across categories
- F
- 0-24
- Heavy drift, sessions weren't coordinated
Four drift categories, plus a separate Hygiene Score:
- Architectural Consistency
- Data access, DI, error handling, import patterns, cross-file drift
- Security Consistency
- Routes that skip the auth the rest of your code applies, plus hardcoded secrets and injection risks
- Redundancy
- Duplicates, Code DNA fingerprints, and (on deep scans) concentrated reimplementation
- Intent Clarity
- Complexity, unclear naming, commented-out code, documentation
- Hygiene Score (separate)
- Generic quality checks like dead code, complexity and TODOs. Independent of drift, never mixed into the Vibe Drift Score
Report sections: Overall score → Category radar → Drift findings (with code evidence) → Per-file rankings (worst to best). Start fixing from the bottom.
One category can drag the headline down. The Vibe Drift Score is a multiplicative blend of the four drift categories, so a single collapsed category (say, security with an unguarded route) pulls the whole grade down hard rather than averaging out. That's deliberate: a 95 everywhere with one 20 isn't a 76-quality codebase. Surface-specific categories with no findings (Security Consistency, Intent Clarity) are shown as not-measured rather than given a free full score.
On deep scans, Redundancy also reflects concentrated reimplementation: dense cross-file reinvention of the same logic lowers the score, while a sparse or legacy parallel implementation stays informational and doesn't.
Track your progress.
When logged in, every scan is saved to vibedrift.ai/dashboard. You get:
- Score timeline, see if fixes actually improve your score
- Scan detail, full report embedded, shareable link
- Project grouping, scans grouped per project folder and named from package.json, Cargo.toml, go.mod or pyproject.toml
- Export, download as JSON, CSV, or DOCX
- API tokens, create and manage CI/CD tokens
- Billing, manage plan, buy a deep-scan top-up, view usage
GitHub Actions.
Set VIBEDRIFT_TOKEN as a repo secret, then add this workflow:
name: VibeDrift
on: [pull_request]
jobs:
drift-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx @vibedrift/cli . \
--deep --json \
--fail-on-score 70
env:
VIBEDRIFT_TOKEN: ${{ secrets.VIBEDRIFT_TOKEN }}--fail-on-score 70 exits with code 1 if the score drops below the threshold, failing the PR check.
--deep on every pull request burns through your monthly deep-scan budget fast (Free 1, Pro 12). Gate it to the branches that matter, e.g. only PRs targeting main, or drop --deep for routine PR checks and let the free local scan gate them. The GitHub Action below shows the branch-gating pattern, and a published action handles PR comments for you.Raw CLI vs the published action. The snippet above is the universal path, npx @vibedrift/cli drops into any pipeline (GitLab, CircleCI, Jenkins, Bitbucket). If you're on GitHub and want a PR comment with the score, grade, finding count and a report link, use the dedicated action in section 14 instead.
All commands.
Scanning
vibedrift [path]- Free local scan (path defaults to .)
vibedrift [path] --deep- AI-powered deep scan (needs login)
vibedrift watch [path]- Rescan on change, refresh .vibedrift/ (local-only)
vibedrift mcp- Run the local MCP server over stdio
Setup
vibedrift init- Guided setup: .vibedriftignore + config
vibedrift ignore <glob>- Add path glob(s) to .vibedriftignore
vibedrift hook <install|uninstall|status>- Manage a pre-push drift-score gate
Options
--format html|terminal|json|csv|docx- Output format (default: html)
--output <path>- Output file path
--json- Shorthand for --format json
--fail-on-score <n>- Exit 1 if score below n (0-100)
--deep- AI deep analysis (requires login)
--diff [ref]- Scope to git-changed files (bare = vs HEAD)
--write-context- Write committable .vibedrift/ files (needs login)
--local-only- Skip ALL network calls (offline scan)
--project-name <name>- Override auto-detected project name
--private- Anonymize project name
--no-codedna- Skip Code DNA layer
--verbose- Verbose output
--include <glob>- Include matching files only
--exclude <glob>- Exclude matching files
Drift Sessions
vibedrift enable --dir <path>- Turn Drift Sessions on once for a whole folder: every repo under it, including ones you clone later (typed confirmation; $HOME and filesystem roots are refused)
vibedrift enable [path]- Turn it on for this one repo (typing it is the consent)
vibedrift decline [path]- Turn it off for this repo; reversible with enable
vibedrift watch-session- Follow the session live on the event tape
vibedrift watch-session --status- Is this repo set up?
vibedrift watch-session --uninstall- Remove the hooks this command installed
vibedrift recheck-session- Close open findings whose flagged code is now gone
Account & billing
vibedrift login- Authenticate via browser (device flow)
vibedrift logout- Remove and revoke credentials
vibedrift status- Account, plan, deep-scan credits
vibedrift usage- Billing-period scan counts + limits
vibedrift upgrade- Open the pricing page
vibedrift billing- Open the Stripe customer portal
Utility
vibedrift telemetry <enable|disable>- Manage the anonymous scan beacon
vibedrift doctor- Diagnose install, auth, connectivity
vibedrift update- Update the CLI to the latest version
vibedrift feedback [msg]- Send feedback
vibedrift --version- Show CLI version
Check your remaining deep-scan budget (monthly allotment + pooled top-up credits) with vibedrift status or vibedrift usage; buy a top-up from vibedrift billing or the dashboard.
What each scan includes.
| Capability | Free | Deep |
|---|---|---|
| Drift score (0-100) | ✓ | ✓ |
| 4 drift categories + Hygiene Score | ✓ | ✓ |
| Cross-file drift findings | ✓ | ✓ |
| Static analysis (13 analyzers) | ✓ | ✓ |
| Code DNA fingerprinting | ✓ | ✓ |
| Per-file rankings | ✓ | ✓ |
| HTML report | ✓ | ✓ |
| CI fail-on-score | ✓ | ✓ |
| AI summary + recommendations | — | ✓ |
| AI semantic duplicate detection | — | ✓ |
| Intent lie-detection (name vs behavior) | — | ✓ |
| In-loop AI verdict on borderline matches | — | ✓ |
| Concentrated reimplementation factored into score | — | ✓ |
| Coherence report graded vs your own patterns (Pro) | — | ✓ |
| Copy-ready fix prompts (Pro) | — | ✓ |
Catch drift before merge.
The VibeDrift GitHub Action runs on every PR and posts a comment with the score, grade, finding count and a link to the full report. Optionally fails the check if the score drops below your threshold.
name: VibeDrift
on: [pull_request]
permissions:
pull-requests: write
jobs:
drift-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: skhan75/vibedrift-actions@v1
with:
token: ${{ secrets.VIBEDRIFT_TOKEN }}
fail-on-score: 70
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Setup:
- Sign up at vibedrift.ai/login (free, no card)
- Go to Dashboard → Settings → copy your API Token
- Add it as VIBEDRIFT_TOKEN in your repo's GitHub Secrets (Settings → Secrets)
- Add the workflow file above, done
What you get on every PR: a comment showing the score, the grade, the finding count, and a link to the full report on your dashboard.
Deep scan on release branches: add deep: ${{ github.base_ref == 'main' }} to run AI analysis only on PRs targeting main. Free scans are unlimited; deep scans draw from your monthly budget (Free 1, Pro 12). Gating deep to release branches keeps you from exhausting it on routine PRs, and if you do run out, a one-time top-up (5 scans for $10) refills the shared pool.
Monorepo: set path: packages/api to scan a subdirectory.
Any CI pipeline (not just GitHub): The GitHub Action is a convenience wrapper. The CLI works in any CI system, just run npx @vibedrift/cli . --json --fail-on-score 70 with VIBEDRIFT_TOKEN set as an environment variable.
# GitLab CI
vibedrift:
stage: test
script:
- npx @vibedrift/cli . --json --fail-on-score 70
variables:
VIBEDRIFT_TOKEN: $VIBEDRIFT_TOKEN
# CircleCI
- run:
name: VibeDrift
command: npx @vibedrift/cli . --json --fail-on-score 70
# Bitbucket Pipelines
- step:
name: VibeDrift
script:
- npx @vibedrift/cli . --json --fail-on-score 70
# Jenkins
stage('VibeDrift') {
sh 'npx @vibedrift/cli . --json --fail-on-score 70'
}The --json flag outputs the full scan result as JSON (parseable by downstream tools). --fail-on-score N exits with code 1 when the score drops below your threshold, blocking the pipeline. Add --deep for AI analysis (uses scan budget).
Offline / air-gapped: use --local-only to skip all network calls. The scan runs fully locally with no dashboard upload and no telemetry.
Simple pricing.
The local CLI scans and the MCP tools are free for everyone. Pro is for Drift Sessions after the trial and for more cloud deep scans.
- Free, $0, unlimited local scans + free local MCP tools, 1 deep scan/month
- Pro, $15/mo, Drift Sessions + 12 deep scans/month + watch mode + git pre-push gate + full scan history
- Enterprise, custom, for needs the plans above don't cover, talk to us
- In-loop MCP deep checks draw a small fraction of a deep scan from the shared pool
Deep-scan top-up. Out of deep scans? Grab a top-up, 5 scans for $10, one-time, buyable on both Free and Pro. Credits stack on a shared scan pool used by both CLI deep scans and in-loop MCP deep checks, and they never expire.
One shared pool. Your monthly allotment, top-up credits, and in-loop MCP deep checks all draw from and feed the same balance, so there's a single number to watch (vibedrift status), not separate buckets to reconcile.