@vibedrift/cli 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,27 +21,66 @@ vibedrift ./my-project
21
21
 
22
22
  That's it. No signup, no API key, no config file. The default run produces an interactive HTML report and serves it on a local port.
23
23
 
24
- To unlock AI-powered deep analysis (semantic duplicates, intent mismatches, anomaly detection):
24
+ ### Free deep scan
25
+
26
+ Every account gets **1 free deep scan** on signup — no card required. Deep scans add Claude-powered AI analysis on top of the local scan (semantic duplicates, intent mismatches, anomaly detection):
25
27
 
26
28
  ```bash
27
- vibedrift login # one-time browser sign-in, no password
28
- vibedrift . --deep # run with cloud AI on top of the local scan
29
+ vibedrift login # one-time browser sign-in
30
+ vibedrift . --deep # uses your free credit (or Pro subscription)
29
31
  ```
30
32
 
31
33
  ---
32
34
 
33
35
  ## What It Catches
34
36
 
37
+ ### Layer 1 — Static Analysis (13 analyzers, runs locally)
35
38
  - **Architectural contradictions** — when half your handlers use a repository pattern and the other half hit raw SQL
36
- - **Hidden duplicates** — functions that do the same thing under different names in different files
37
- - **Security gaps** — routes missing auth, validation, or rate limiting
38
39
  - **Naming inconsistency** — `getUserData()`, `get_order_items()`, `FetchProductList()` in the same project
40
+ - **Security patterns** — hardcoded secrets, SQL injection, command injection, weak crypto, unsafe functions
41
+ - **Dependency health** — phantom deps, missing deps, undocumented env vars
42
+ - **Code quality** — cyclomatic complexity, dead code, TODO density, long functions, unclear naming
43
+
44
+ ### Layer 1.5 — Cross-File Drift Detection (5 detectors)
45
+ - **Architectural consistency** — data access patterns, error handling, DI, config approaches
46
+ - **Convention oscillation** — naming conventions, file naming across the whole project
47
+ - **Security consistency** — auth middleware, input validation, rate limiting across routes
48
+ - **Semantic duplication** — functions that do the same thing under different names in different files
39
49
  - **Phantom scaffolding** — CRUD endpoints the AI generated but never wired up
40
50
 
51
+ ### Layer 1.7 — Code DNA Engine (5 modules, runs locally)
52
+ - **Semantic fingerprinting** — normalizes function bodies and hashes them. Identical hashes = exact semantic duplicates at confidence 1.0
53
+ - **Operation sequence analysis** — reduces functions to abstract operations (INPUT, QUERY, MUTATE, RETURN) and compares via LCS
54
+ - **Pattern classification** — structural pattern detection with probability distributions per file
55
+ - **Taint analysis** — tracks user input from sources (req.params) to dangerous sinks (db.query) within functions
56
+ - **Deviation heuristics** — scores whether architectural deviations are justified or accidental
57
+
58
+ ### Layer 2 — AI Deep Analysis (requires `--deep`)
59
+ - **ML duplicate detection** — UniXcoder embeddings + cosine similarity for near-duplicates
60
+ - **Intent mismatch** — detects functions whose name doesn't match their behavior
61
+ - **Anomaly detection** — DBSCAN outlier detection on handler embeddings
62
+ - **Surgical LLM validation** — Claude validates medium-confidence ML findings
63
+
41
64
  VibeDrift learns the dominant patterns your codebase follows and flags files that deviate from them. A codebase isn't wrong because it uses raw SQL — it's *drifting* because 8 of its 10 handlers use a repository and 2 don't.
42
65
 
43
66
  ---
44
67
 
68
+ ## Scoring
69
+
70
+ VibeDrift scores across 5 categories, each 0–20 points:
71
+
72
+ | Category | What it measures |
73
+ |----------|-----------------|
74
+ | **Architectural Consistency** | Naming, imports, error handling, patterns, drift detection |
75
+ | **Redundancy** | Duplicates, dead code, TODO density, Code DNA fingerprints |
76
+ | **Dependency Health** | Phantom/missing deps, env var documentation |
77
+ | **Security Posture** | Hardcoded secrets, injection risks, taint flows, security drift |
78
+ | **Intent Clarity** | Complexity, unclear naming, commented-out code, documentation |
79
+
80
+ **Composite score** = sum of applicable categories (0–100). Grade thresholds: A ≥ 90, B ≥ 75, C ≥ 50, D ≥ 25, F < 25.
81
+
82
+ ---
83
+
45
84
  ## Usage
46
85
 
47
86
  ```
@@ -57,6 +96,7 @@ Commands:
57
96
  billing Open the Stripe Customer Portal
58
97
  doctor Diagnose CLI installation, auth, and API
59
98
  update Update the CLI to the latest version
99
+ feedback [message] Send feedback, bug reports, or feature requests
60
100
 
61
101
  Scan options:
62
102
  --format <type> Output format: html, terminal, json, csv, docx (default: html)
@@ -64,9 +104,11 @@ Scan options:
64
104
  --json Shorthand for --format json
65
105
  --fail-on-score <n> Exit with code 1 if composite score is below threshold
66
106
  --no-codedna Skip Code DNA semantic analysis
67
- --deep Enable AI-powered deep analysis (requires `vibedrift login`)
107
+ --deep Enable AI-powered deep analysis (requires login)
108
+ --project-name <name> Override the auto-detected project name
68
109
  --include <pattern> Only scan files matching this glob (repeatable)
69
110
  --exclude <pattern> Exclude files matching this glob (repeatable)
111
+ --feedback [message] Send feedback (alias for `vibedrift feedback`)
70
112
  --update Update the VibeDrift CLI to the latest version
71
113
  --verbose Show timing breakdown and analyzer details
72
114
  -V, --version Show installed version
@@ -76,6 +118,7 @@ Scan options:
76
118
  ### Examples
77
119
 
78
120
  ```bash
121
+ # Scanning
79
122
  vibedrift # scan the current directory
80
123
  vibedrift ./my-project # scan a specific project
81
124
  vibedrift --format terminal # print results to the terminal
@@ -83,12 +126,20 @@ vibedrift --json > report.json # pipe JSON output to a file
83
126
  vibedrift --fail-on-score 70 # fail CI if score drops below 70
84
127
  vibedrift --include "src/**" # only scan files under src/
85
128
  vibedrift --exclude "**/*.spec.*" # skip test files
86
- vibedrift --deep # run premium AI-powered deep analysis
87
- vibedrift login # sign in to enable --deep
88
- vibedrift status # check current auth state
129
+ vibedrift --deep # run AI-powered deep analysis
130
+
131
+ # Account
132
+ vibedrift login # sign in (opens browser)
133
+ vibedrift status # check auth + credit balance
89
134
  vibedrift usage # view this month's scan usage
90
- vibedrift billing # manage your Stripe subscription
135
+ vibedrift billing # manage your subscription
91
136
  vibedrift update # update to the latest version
137
+
138
+ # Feedback
139
+ vibedrift feedback # interactive prompt
140
+ vibedrift feedback "the report is great but needs dark mode"
141
+ vibedrift --feedback "inline shortcut works too"
142
+ echo "piped input" | vibedrift feedback
92
143
  ```
93
144
 
94
145
  ### Environment
@@ -103,27 +154,56 @@ vibedrift update # update to the latest version
103
154
 
104
155
  | Format | Description |
105
156
  |--------|-------------|
106
- | `html` (default) | Interactive report with charts, file rankings, and exports |
157
+ | `html` (default) | Interactive report with charts, category breakdowns, drift findings, Code DNA results, and export options |
107
158
  | `terminal` | Color-coded terminal output with tables |
108
- | `json` | Full result serialization for CI pipelines |
109
- | `csv` | Tabular export of all findings |
110
- | `docx` | Word document with formatted sections |
159
+ | `json` | Full ScanResult serialization for CI pipelines |
160
+ | `csv` | Multi-section tabular export (metadata, scores, findings, drift, Code DNA, per-file) |
161
+ | `docx` | Word document with formatted title page, AI summary, scores, and all findings |
111
162
 
112
163
  ### CI Integration
113
164
 
114
- ```bash
115
- # Fail the build if score drops below 70
116
- npx @vibedrift/cli . --format json --fail-on-score 70
117
-
118
- # Same, with deep AI analysis (token from VIBEDRIFT_TOKEN secret)
119
- VIBEDRIFT_TOKEN=$VIBEDRIFT_TOKEN \
120
- npx @vibedrift/cli . --deep --format json --fail-on-score 70
165
+ ```yaml
166
+ # GitHub Actions
167
+ name: VibeDrift
168
+ on: [pull_request]
169
+ jobs:
170
+ drift-check:
171
+ runs-on: ubuntu-latest
172
+ steps:
173
+ - uses: actions/checkout@v4
174
+ - run: npx @vibedrift/cli . --deep --json --fail-on-score 70
175
+ env:
176
+ VIBEDRIFT_TOKEN: ${{ secrets.VIBEDRIFT_TOKEN }}
121
177
  ```
122
178
 
123
179
  Exit code 1 when the score drops below the threshold. JSON output includes every finding for downstream tooling.
124
180
 
125
181
  ---
126
182
 
183
+ ## Dashboard
184
+
185
+ All scans (free and deep) are logged to your dashboard at [vibedrift.ai/dashboard](https://vibedrift.ai/dashboard) when you're logged in:
186
+
187
+ - **Project overview** — score trends, sparklines, grade history
188
+ - **Scan detail** — embedded HTML report, export (JSON/CSV/DOCX), share via public link
189
+ - **Billing** — manage subscription, cancel/switch plans, view credits
190
+ - **Settings** — API tokens, preferences, account management
191
+
192
+ ---
193
+
194
+ ## Pricing
195
+
196
+ | Tier | Price | What you get |
197
+ |------|-------|-------------|
198
+ | **Free** | $0 | Unlimited local scans + 1 free deep scan on signup |
199
+ | **Per scan** | $5/scan | One-time deep scan credit (Claude AI + ML embeddings) |
200
+ | **Pro** | $29/month | Unlimited deep scans + GitHub Action + dashboard |
201
+ | **Team** | $99/month | Everything in Pro + team features + API access |
202
+
203
+ See [vibedrift.ai/#pricing](https://vibedrift.ai/#pricing) for details.
204
+
205
+ ---
206
+
127
207
  ## Supported Languages
128
208
 
129
209
  JavaScript · TypeScript · Python · Go · Rust
@@ -139,6 +219,18 @@ JavaScript · TypeScript · Python · Go · Rust
139
219
 
140
220
  ---
141
221
 
222
+ ## Feedback
223
+
224
+ Found a bug? Have a feature request? Send it directly from the CLI:
225
+
226
+ ```bash
227
+ vibedrift feedback "the naming analyzer flags Go acronyms incorrectly"
228
+ ```
229
+
230
+ Feedback goes straight to the maintainer. If you're logged in, your account email is attached so we can follow up. Anonymous feedback works too.
231
+
232
+ ---
233
+
142
234
  ## License
143
235
 
144
236
  VibeDrift is proprietary software. Free to install and run for personal and internal commercial use; see [LICENSE](./LICENSE) for full terms.
@@ -155,5 +247,6 @@ For commercial licensing, partnerships, or enterprise terms: **sami.ahmadkhan12@
155
247
 
156
248
  ## Links
157
249
 
158
- - **Website:** https://vibedrift.ai
250
+ - **Website:** [vibedrift.ai](https://vibedrift.ai)
251
+ - **Dashboard:** [vibedrift.ai/dashboard](https://vibedrift.ai/dashboard)
159
252
  - **Issues / Support:** sami.ahmadkhan12@gmail.com
package/dist/index.js CHANGED
@@ -6802,7 +6802,7 @@ function buildAiSummaryWidget(result) {
6802
6802
  return `<section class="section" style="margin-bottom:32px">
6803
6803
  <div style="background:rgba(255,208,0,0.03);border:1px solid var(--border);border-radius:0;padding:24px 28px;position:relative;overflow:hidden">
6804
6804
  <div style="position:absolute;top:0;left:0;width:3px;height:100%;background:var(--border)"></div>
6805
- <div style="display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap">
6805
+ <div class="score-layout" style="display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap">
6806
6806
  <div style="flex:1;min-width:280px">
6807
6807
  <div style="display:flex;align-items:center;gap:8px;margin-bottom:10px">
6808
6808
  <span style="font-size:16px">&#129302;</span>
@@ -6844,7 +6844,7 @@ function buildScoreSection(result) {
6844
6844
  }).join("");
6845
6845
  return `<section class="section">
6846
6846
  <div class="label">SCORE OVERVIEW</div>
6847
- <div style="display:flex;gap:40px;align-items:flex-start;flex-wrap:wrap">
6847
+ <div class="score-layout" style="display:flex;gap:40px;align-items:flex-start;flex-wrap:wrap">
6848
6848
  <div style="text-align:center;min-width:120px">
6849
6849
  <div class="mono" style="font-size:72px;font-weight:800;color:${color};line-height:1">${compositeScore}</div>
6850
6850
  <div class="mono" style="font-size:16px;color:var(--text-tertiary)">/ ${maxCompositeScore}</div>
@@ -6858,7 +6858,7 @@ function buildRadarSection(result) {
6858
6858
  const cats = getDriftCats(result);
6859
6859
  const n = cats.length;
6860
6860
  if (n === 0) return "";
6861
- const cx = 180, cy = 180, r = 140, step = 2 * Math.PI / n;
6861
+ const cx = 260, cy = 200, r = 130, step = 2 * Math.PI / n;
6862
6862
  let grid = "", dots = "", labels = "";
6863
6863
  const pts = [];
6864
6864
  for (const ring of [0.25, 0.5, 0.75, 1]) {
@@ -6875,14 +6875,14 @@ function buildRadarSection(result) {
6875
6875
  const px = cx + r * ratio * Math.cos(a), py = cy + r * ratio * Math.sin(a);
6876
6876
  pts.push(`${px},${py}`);
6877
6877
  dots += `<circle cx="${px}" cy="${py}" r="5" fill="var(--text-secondary)" stroke="var(--bg-page)" stroke-width="2"/>`;
6878
- const labelDist = r + 30;
6878
+ const labelDist = r + 35;
6879
6879
  const lx = cx + labelDist * Math.cos(a), ly = cy + labelDist * Math.sin(a);
6880
6880
  const anchor = Math.abs(Math.cos(a)) < 0.3 ? "middle" : Math.cos(a) > 0 ? "start" : "end";
6881
6881
  const { color: catColor } = gradeFor(cats[i].score, cats[i].max);
6882
6882
  labels += `<text x="${lx}" y="${ly - 7}" fill="${catColor}" font-size="12" font-weight="600" font-family="-apple-system,sans-serif" text-anchor="${anchor}" dominant-baseline="middle">${esc(cats[i].shortName)}</text>`;
6883
6883
  labels += `<text x="${lx}" y="${ly + 8}" fill="#5A6A7E" font-size="11" font-weight="500" font-family="'SF Mono',Consolas,monospace" text-anchor="${anchor}" dominant-baseline="middle">${cats[i].score}/${cats[i].max} ${cats[i].findings > 0 ? "(" + cats[i].findings + " issues)" : ""}</text>`;
6884
6884
  }
6885
- const radar = `<svg viewBox="0 0 360 360" style="width:100%;max-width:420px;height:auto;margin:0 auto;display:block">${grid}<polygon points="${pts.join(" ")}" fill="rgba(255,208,0,0.04)" stroke="rgba(255,208,0,0.3)" stroke-width="1.5"/>${dots}${labels}</svg>`;
6885
+ const radar = `<svg viewBox="0 0 520 440" style="width:100%;max-width:560px;height:auto;margin:0 auto;display:block">${grid}<polygon points="${pts.join(" ")}" fill="rgba(255,208,0,0.04)" stroke="rgba(255,208,0,0.3)" stroke-width="1.5"/>${dots}${labels}</svg>`;
6886
6886
  const weakest = [...cats].sort((a, b) => {
6887
6887
  const pctA = a.max > 0 ? a.score / a.max : 1;
6888
6888
  const pctB = b.max > 0 ? b.score / b.max : 1;
@@ -7475,9 +7475,73 @@ th[data-sort]:hover { color: var(--text-primary); }
7475
7475
  ::-webkit-scrollbar-thumb { background: #3A3A3D; }
7476
7476
  ::-webkit-scrollbar-thumb:hover { background: #555; }
7477
7477
  @media (max-width: 768px) {
7478
- .page { padding: 20px 14px; }
7479
- .score-layout { flex-direction: column !important; }
7478
+ .page { padding: 16px 10px; }
7479
+ .section { margin-bottom: 28px; }
7480
+ .label { font-size: 10px; letter-spacing: 1.5px; margin-bottom: 10px; }
7481
+
7482
+ /* Score hero: stack vertically */
7483
+ .score-layout { flex-direction: column !important; gap: 16px !important; }
7484
+ .score-layout > div { min-width: 0 !important; width: 100% !important; }
7485
+
7486
+ /* Category bars: stack, remove min-widths */
7487
+ .score-layout [style*="min-width:300px"],
7488
+ .score-layout [style*="min-width:280px"],
7489
+ .score-layout [style*="min-width:200px"],
7490
+ .score-layout [style*="min-width:120px"] {
7491
+ min-width: 0 !important; width: 100% !important;
7492
+ }
7493
+
7494
+ /* Radar chart: constrain to viewport */
7495
+ svg[viewBox] { max-width: 100% !important; }
7496
+
7497
+ /* Strongest/Weakest cards: 2-col, tighter */
7498
+ .section > div[style*="display:flex"][style*="gap:12px"] {
7499
+ gap: 8px !important;
7500
+ }
7501
+ .section > div[style*="display:flex"] > div[style*="min-width:160px"] {
7502
+ min-width: 0 !important; flex: 1 !important;
7503
+ }
7504
+
7505
+ /* Findings list: tighter padding */
7506
+ details > div { padding: 8px 10px !important; }
7507
+ details summary { padding: 10px 12px !important; font-size: 13px !important; }
7508
+
7509
+ /* File ranking table: horizontal scroll */
7510
+ table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }
7511
+ table th, table td { padding: 5px 8px !important; font-size: 11px !important; }
7512
+
7513
+ /* Code snippets: wrap text */
7514
+ pre, code { white-space: pre-wrap !important; word-break: break-word !important; font-size: 12px !important; }
7515
+
7516
+ /* Drift coherence bars: full width */
7517
+ .section div[style*="display:flex"][style*="gap:40px"] {
7518
+ flex-direction: column !important; gap: 16px !important;
7519
+ }
7520
+
7521
+ /* Summary + AI section: stack */
7522
+ .section div[style*="display:flex"][style*="gap:20px"] {
7523
+ flex-direction: column !important; gap: 12px !important;
7524
+ }
7525
+
7526
+ /* Sticky header: tighter padding */
7527
+ .sticky-header { padding: 0 12px; font-size: 12px; }
7480
7528
  .sticky-project { display: none !important; }
7529
+
7530
+ /* Export buttons: smaller */
7531
+ .export-btn { padding: 5px 10px; font-size: 11px; }
7532
+
7533
+ /* Code DNA / ML sections: reduce gap */
7534
+ .section div[style*="gap:10px"] { gap: 6px !important; }
7535
+
7536
+ /* Hide long file paths, truncate */
7537
+ td[data-scroll-to] { max-width: 140px !important; }
7538
+ }
7539
+ @media (max-width: 480px) {
7540
+ .page { padding: 12px 8px; }
7541
+ body { font-size: 13px; }
7542
+ .label { font-size: 9px; }
7543
+ .sticky-header { height: 38px; }
7544
+ table th, table td { padding: 4px 6px !important; font-size: 10px !important; }
7481
7545
  }
7482
7546
  @media print {
7483
7547
  body { background: #fff; color: #111; font-size: 11px; line-height: 1.4; }