@vibecheckai/cli 3.0.2 → 3.0.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.
Files changed (68) hide show
  1. package/package.json +9 -1
  2. package/bin/cli-hygiene.js +0 -241
  3. package/bin/guardrail.js +0 -834
  4. package/bin/runners/cli-utils.js +0 -1070
  5. package/bin/runners/context/ai-task-decomposer.js +0 -337
  6. package/bin/runners/context/analyzer.js +0 -462
  7. package/bin/runners/context/api-contracts.js +0 -427
  8. package/bin/runners/context/context-diff.js +0 -342
  9. package/bin/runners/context/context-pruner.js +0 -291
  10. package/bin/runners/context/dependency-graph.js +0 -414
  11. package/bin/runners/context/generators/claude.js +0 -107
  12. package/bin/runners/context/generators/codex.js +0 -108
  13. package/bin/runners/context/generators/copilot.js +0 -119
  14. package/bin/runners/context/generators/cursor.js +0 -514
  15. package/bin/runners/context/generators/mcp.js +0 -151
  16. package/bin/runners/context/generators/windsurf.js +0 -180
  17. package/bin/runners/context/git-context.js +0 -302
  18. package/bin/runners/context/index.js +0 -1042
  19. package/bin/runners/context/insights.js +0 -173
  20. package/bin/runners/context/mcp-server/generate-rules.js +0 -337
  21. package/bin/runners/context/mcp-server/index.js +0 -1176
  22. package/bin/runners/context/mcp-server/package.json +0 -24
  23. package/bin/runners/context/memory.js +0 -200
  24. package/bin/runners/context/monorepo.js +0 -215
  25. package/bin/runners/context/multi-repo-federation.js +0 -404
  26. package/bin/runners/context/patterns.js +0 -253
  27. package/bin/runners/context/proof-context.js +0 -972
  28. package/bin/runners/context/security-scanner.js +0 -303
  29. package/bin/runners/context/semantic-search.js +0 -350
  30. package/bin/runners/context/shared.js +0 -264
  31. package/bin/runners/context/team-conventions.js +0 -310
  32. package/bin/runners/lib/ai-bridge.js +0 -416
  33. package/bin/runners/lib/analysis-core.js +0 -271
  34. package/bin/runners/lib/analyzers.js +0 -541
  35. package/bin/runners/lib/audit-bridge.js +0 -391
  36. package/bin/runners/lib/auth-truth.js +0 -193
  37. package/bin/runners/lib/auth.js +0 -215
  38. package/bin/runners/lib/backup.js +0 -62
  39. package/bin/runners/lib/billing.js +0 -107
  40. package/bin/runners/lib/claims.js +0 -118
  41. package/bin/runners/lib/cli-ui.js +0 -540
  42. package/bin/runners/lib/compliance-bridge-new.js +0 -0
  43. package/bin/runners/lib/compliance-bridge.js +0 -165
  44. package/bin/runners/lib/contracts/auth-contract.js +0 -194
  45. package/bin/runners/lib/contracts/env-contract.js +0 -178
  46. package/bin/runners/lib/contracts/external-contract.js +0 -198
  47. package/bin/runners/lib/contracts/guard.js +0 -168
  48. package/bin/runners/lib/contracts/index.js +0 -89
  49. package/bin/runners/lib/contracts/plan-validator.js +0 -311
  50. package/bin/runners/lib/contracts/route-contract.js +0 -192
  51. package/bin/runners/lib/detect.js +0 -89
  52. package/bin/runners/lib/doctor/autofix.js +0 -254
  53. package/bin/runners/lib/doctor/index.js +0 -37
  54. package/bin/runners/lib/doctor/modules/dependencies.js +0 -325
  55. package/bin/runners/lib/doctor/modules/index.js +0 -46
  56. package/bin/runners/lib/doctor/modules/network.js +0 -250
  57. package/bin/runners/lib/doctor/modules/project.js +0 -312
  58. package/bin/runners/lib/doctor/modules/runtime.js +0 -224
  59. package/bin/runners/lib/doctor/modules/security.js +0 -348
  60. package/bin/runners/lib/doctor/modules/system.js +0 -213
  61. package/bin/runners/lib/doctor/modules/vibecheck.js +0 -394
  62. package/bin/runners/lib/doctor/reporter.js +0 -262
  63. package/bin/runners/lib/doctor/service.js +0 -262
  64. package/bin/runners/lib/doctor/types.js +0 -113
  65. package/bin/runners/lib/doctor/ui.js +0 -263
  66. package/bin/runners/lib/doctor-enhanced.js +0 -233
  67. package/bin/runners/lib/doctor-v2.js +0 -608
  68. package/bin/runners/lib/enforcement.js +0 -72
@@ -1,192 +0,0 @@
1
- /**
2
- * Route Contract Builder
3
- * Builds routes.json contract from truthpack
4
- */
5
-
6
- "use strict";
7
-
8
- const crypto = require("crypto");
9
-
10
- function sha256(text) {
11
- return crypto.createHash("sha256").update(text).digest("hex").slice(0, 16);
12
- }
13
-
14
- /**
15
- * Build routes contract from truthpack
16
- */
17
- function buildRouteContract(truthpack) {
18
- const contract = {
19
- version: "1.0.0",
20
- generatedAt: new Date().toISOString(),
21
- routes: []
22
- };
23
-
24
- const serverRoutes = truthpack?.routes?.server || [];
25
-
26
- for (const route of serverRoutes) {
27
- const routeSpec = {
28
- id: `route_${sha256(route.method + "_" + route.path)}`,
29
- method: route.method,
30
- path: route.path,
31
- handler: route.handler || "unknown",
32
- auth: inferAuthRequirement(route, truthpack),
33
- roles: inferRoles(route, truthpack),
34
- confidence: route.confidence || "med",
35
- evidence: route.evidence || []
36
- };
37
-
38
- contract.routes.push(routeSpec);
39
- }
40
-
41
- return contract;
42
- }
43
-
44
- /**
45
- * Infer auth requirement from route and truthpack
46
- */
47
- function inferAuthRequirement(route, truthpack) {
48
- const authPatterns = truthpack?.auth?.nextMatcherPatterns || [];
49
- const path = route.path;
50
-
51
- // Check if path matches any protected pattern
52
- for (const pattern of authPatterns) {
53
- if (matchesPattern(path, pattern)) {
54
- return "required";
55
- }
56
- }
57
-
58
- // Check for auth hooks in Fastify
59
- if (route.hooks?.includes("onRequest") || route.hooks?.includes("preHandler")) {
60
- return "required";
61
- }
62
-
63
- // Check for public API patterns
64
- if (path.includes("/public/") || path.includes("/health") || path.includes("/status")) {
65
- return "none";
66
- }
67
-
68
- return "optional";
69
- }
70
-
71
- /**
72
- * Infer roles from route metadata
73
- */
74
- function inferRoles(route, truthpack) {
75
- const roles = [];
76
-
77
- // Check for admin patterns in path
78
- if (route.path.includes("/admin")) {
79
- roles.push("admin");
80
- }
81
-
82
- // Check handler for role patterns
83
- const handler = route.handler || "";
84
- if (handler.includes("admin")) {
85
- roles.push("admin");
86
- }
87
-
88
- return roles.length > 0 ? roles : undefined;
89
- }
90
-
91
- function matchesPattern(path, pattern) {
92
- // Simple pattern matching
93
- const normPattern = pattern.replace(/\*/g, ".*").replace(/\//g, "\\/");
94
- try {
95
- const rx = new RegExp(`^${normPattern}`, "i");
96
- return rx.test(path);
97
- } catch {
98
- return false;
99
- }
100
- }
101
-
102
- /**
103
- * Validate code against route contract
104
- */
105
- function validateAgainstRouteContract(contract, clientRefs) {
106
- const violations = [];
107
- const contractPaths = new Map(contract.routes.map(r => [`${r.method}_${r.path}`, r]));
108
-
109
- for (const ref of clientRefs) {
110
- const key = `${ref.method}_${ref.path}`;
111
- const wildcardKey = `*_${ref.path}`;
112
-
113
- if (!contractPaths.has(key) && !contractPaths.has(wildcardKey)) {
114
- // Check parameterized match
115
- const match = findParameterizedMatch(contract.routes, ref.method, ref.path);
116
-
117
- if (!match) {
118
- violations.push({
119
- type: "undeclared_route",
120
- severity: "BLOCK",
121
- route: { method: ref.method, path: ref.path },
122
- source: ref.source,
123
- message: `Route ${ref.method} ${ref.path} used in client but not declared in contract`,
124
- evidence: ref.evidence || []
125
- });
126
- }
127
- }
128
- }
129
-
130
- return violations;
131
- }
132
-
133
- function findParameterizedMatch(routes, method, path) {
134
- for (const r of routes) {
135
- if (r.method !== "*" && r.method !== method) continue;
136
- if (matchesParameterized(r.path, path)) return r;
137
- }
138
- return null;
139
- }
140
-
141
- function matchesParameterized(pattern, actual) {
142
- const patternParts = pattern.split("/").filter(Boolean);
143
- const actualParts = actual.split("/").filter(Boolean);
144
-
145
- if (patternParts.length !== actualParts.length) return false;
146
-
147
- for (let i = 0; i < patternParts.length; i++) {
148
- const p = patternParts[i];
149
- if (p.startsWith(":") || p.startsWith("*")) continue;
150
- if (p !== actualParts[i]) return false;
151
- }
152
- return true;
153
- }
154
-
155
- /**
156
- * Diff two route contracts
157
- */
158
- function diffRouteContracts(before, after) {
159
- const diff = {
160
- added: [],
161
- removed: [],
162
- changed: []
163
- };
164
-
165
- const beforeMap = new Map(before.routes.map(r => [r.id, r]));
166
- const afterMap = new Map(after.routes.map(r => [r.id, r]));
167
-
168
- for (const [id, route] of afterMap) {
169
- if (!beforeMap.has(id)) {
170
- diff.added.push(route);
171
- } else {
172
- const prev = beforeMap.get(id);
173
- if (prev.auth !== route.auth || JSON.stringify(prev.roles) !== JSON.stringify(route.roles)) {
174
- diff.changed.push({ before: prev, after: route });
175
- }
176
- }
177
- }
178
-
179
- for (const [id, route] of beforeMap) {
180
- if (!afterMap.has(id)) {
181
- diff.removed.push(route);
182
- }
183
- }
184
-
185
- return diff;
186
- }
187
-
188
- module.exports = {
189
- buildRouteContract,
190
- validateAgainstRouteContract,
191
- diffRouteContracts
192
- };
@@ -1,89 +0,0 @@
1
- // bin/runners/lib/detect.js
2
- const fs = require("fs");
3
- const path = require("path");
4
- const fg = require("fast-glob");
5
-
6
- function fileExists(root, rel) {
7
- return fs.existsSync(path.join(root, rel));
8
- }
9
-
10
- function detectPackageManager(root) {
11
- if (fileExists(root, "pnpm-lock.yaml")) return "pnpm";
12
- if (fileExists(root, "yarn.lock")) return "yarn";
13
- if (fileExists(root, "package-lock.json")) return "npm";
14
- return "npm";
15
- }
16
-
17
- function detectNext(root, pkg) {
18
- const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
19
- const hasDep = !!deps.next;
20
- const hasConfig = fileExists(root, "next.config.js") || fileExists(root, "next.config.mjs") || fileExists(root, "next.config.ts");
21
- const hasApp = fileExists(root, "app") || fileExists(root, "src/app");
22
- const hasPages = fileExists(root, "pages") || fileExists(root, "src/pages");
23
- return { enabled: hasDep || hasConfig || hasApp || hasPages, hasDep, hasConfig, hasApp, hasPages };
24
- }
25
-
26
- function detectFastify(root, pkg) {
27
- const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
28
- const hasDep = !!deps.fastify;
29
- return { enabled: hasDep, hasDep };
30
- }
31
-
32
- function scoreFastifyEntry(code, rel) {
33
- let s = 0;
34
- if (/\bfastify\s*\(/.test(code)) s += 10;
35
- if (/from\s+['"]fastify['"]|require\(['"]fastify['"]\)/.test(code)) s += 8;
36
- if (/\baddHook\s*\(/.test(code)) s += 2;
37
- if (/\bregister\s*\(/.test(code)) s += 2;
38
- if (/\.(listen|ready)\s*\(/.test(code)) s += 10;
39
- if (/createServer|http\.createServer/.test(code)) s += 1;
40
- if (rel.includes("server")) s += 2;
41
- if (rel.includes("api")) s += 1;
42
- if (rel.endsWith(".ts")) s += 1;
43
- return s;
44
- }
45
-
46
- async function detectFastifyEntry(root) {
47
- const common = [
48
- "src/server.ts", "src/server.js",
49
- "server.ts", "server.js",
50
- "src/index.ts", "src/index.js",
51
- "index.ts", "index.js",
52
- "src/app.ts", "src/app.js",
53
- "app.ts", "app.js"
54
- ];
55
-
56
- for (const rel of common) {
57
- const abs = path.join(root, rel);
58
- if (!fs.existsSync(abs)) continue;
59
- const code = fs.readFileSync(abs, "utf8");
60
- if (/\bfastify\s*\(/.test(code)) return rel;
61
- }
62
-
63
- const files = await fg(["**/*.{ts,js}"], {
64
- cwd: root,
65
- onlyFiles: true,
66
- absolute: false,
67
- ignore: ["**/node_modules/**", "**/.next/**", "**/dist/**", "**/build/**"]
68
- });
69
-
70
- let best = null;
71
- for (const rel of files.slice(0, 800)) {
72
- const abs = path.join(root, rel);
73
- let code;
74
- try { code = fs.readFileSync(abs, "utf8"); } catch { continue; }
75
- if (!/\bfastify\s*\(/.test(code)) continue;
76
-
77
- const s = scoreFastifyEntry(code, rel);
78
- if (!best || s > best.score) best = { rel, score: s };
79
- }
80
-
81
- return best?.rel || null;
82
- }
83
-
84
- module.exports = {
85
- detectPackageManager,
86
- detectNext,
87
- detectFastify,
88
- detectFastifyEntry
89
- };
@@ -1,254 +0,0 @@
1
- /**
2
- * Doctor Auto-Fix Engine
3
- *
4
- * Executes fixes for diagnostic issues automatically when safe
5
- */
6
-
7
- const fs = require('fs');
8
- const path = require('path');
9
- const { execSync, spawn } = require('child_process');
10
- const { FIX_TYPE, SEVERITY } = require('./types');
11
-
12
- const FIX_RESULT = {
13
- SUCCESS: 'success',
14
- FAILED: 'failed',
15
- SKIPPED: 'skipped',
16
- REQUIRES_CONFIRMATION: 'requires_confirmation',
17
- };
18
-
19
- function canAutoFix(fix) {
20
- if (!fix) return false;
21
- if (fix.dangerous) return false;
22
- if (fix.autoFixable === false) return false;
23
-
24
- // Only auto-fix commands and file operations
25
- return [FIX_TYPE.COMMAND, FIX_TYPE.FILE_CREATE, FIX_TYPE.FILE_EDIT].includes(fix.type);
26
- }
27
-
28
- async function executeFix(fix, projectPath, options = {}) {
29
- const { dryRun = false, interactive = false } = options;
30
-
31
- if (!fix) {
32
- return { status: FIX_RESULT.SKIPPED, reason: 'No fix provided' };
33
- }
34
-
35
- if (fix.dangerous && !options.allowDangerous) {
36
- return {
37
- status: FIX_RESULT.REQUIRES_CONFIRMATION,
38
- reason: 'Fix is marked as dangerous',
39
- fix,
40
- };
41
- }
42
-
43
- if (dryRun) {
44
- return {
45
- status: FIX_RESULT.SKIPPED,
46
- reason: 'Dry run mode',
47
- wouldExecute: fix,
48
- };
49
- }
50
-
51
- try {
52
- switch (fix.type) {
53
- case FIX_TYPE.COMMAND:
54
- return await executeCommand(fix, projectPath, options);
55
-
56
- case FIX_TYPE.FILE_CREATE:
57
- return await createFile(fix, projectPath);
58
-
59
- case FIX_TYPE.FILE_EDIT:
60
- return await editFile(fix, projectPath);
61
-
62
- case FIX_TYPE.MANUAL:
63
- return {
64
- status: FIX_RESULT.SKIPPED,
65
- reason: 'Manual fix required',
66
- instructions: fix.description,
67
- };
68
-
69
- case FIX_TYPE.LINK:
70
- return {
71
- status: FIX_RESULT.SKIPPED,
72
- reason: 'External documentation',
73
- url: fix.url,
74
- };
75
-
76
- default:
77
- return {
78
- status: FIX_RESULT.SKIPPED,
79
- reason: `Unknown fix type: ${fix.type}`,
80
- };
81
- }
82
- } catch (err) {
83
- return {
84
- status: FIX_RESULT.FAILED,
85
- error: err.message,
86
- fix,
87
- };
88
- }
89
- }
90
-
91
- async function executeCommand(fix, projectPath, options = {}) {
92
- const { timeout = 60000 } = options;
93
-
94
- if (!fix.command) {
95
- return { status: FIX_RESULT.SKIPPED, reason: 'No command specified' };
96
- }
97
-
98
- try {
99
- const result = execSync(fix.command, {
100
- cwd: projectPath,
101
- encoding: 'utf8',
102
- timeout,
103
- stdio: ['pipe', 'pipe', 'pipe'],
104
- });
105
-
106
- return {
107
- status: FIX_RESULT.SUCCESS,
108
- command: fix.command,
109
- output: result.trim(),
110
- };
111
- } catch (err) {
112
- return {
113
- status: FIX_RESULT.FAILED,
114
- command: fix.command,
115
- error: err.message,
116
- stderr: err.stderr,
117
- };
118
- }
119
- }
120
-
121
- async function createFile(fix, projectPath) {
122
- if (!fix.path || fix.content === undefined) {
123
- return { status: FIX_RESULT.SKIPPED, reason: 'No path or content specified' };
124
- }
125
-
126
- const fullPath = path.isAbsolute(fix.path) ? fix.path : path.join(projectPath, fix.path);
127
-
128
- // Don't overwrite existing files
129
- if (fs.existsSync(fullPath)) {
130
- return {
131
- status: FIX_RESULT.SKIPPED,
132
- reason: 'File already exists',
133
- path: fullPath,
134
- };
135
- }
136
-
137
- // Ensure directory exists
138
- fs.mkdirSync(path.dirname(fullPath), { recursive: true });
139
-
140
- // Write file
141
- fs.writeFileSync(fullPath, fix.content);
142
-
143
- return {
144
- status: FIX_RESULT.SUCCESS,
145
- action: 'created',
146
- path: fullPath,
147
- };
148
- }
149
-
150
- async function editFile(fix, projectPath) {
151
- if (!fix.path || fix.content === undefined) {
152
- return { status: FIX_RESULT.SKIPPED, reason: 'No path or content specified' };
153
- }
154
-
155
- const fullPath = path.isAbsolute(fix.path) ? fix.path : path.join(projectPath, fix.path);
156
-
157
- // Backup existing file
158
- if (fs.existsSync(fullPath)) {
159
- const backupPath = `${fullPath}.doctor-backup`;
160
- fs.copyFileSync(fullPath, backupPath);
161
- }
162
-
163
- // Write new content
164
- fs.writeFileSync(fullPath, fix.content);
165
-
166
- return {
167
- status: FIX_RESULT.SUCCESS,
168
- action: 'edited',
169
- path: fullPath,
170
- };
171
- }
172
-
173
- async function autoFixAll(diagnostics, projectPath, options = {}) {
174
- const {
175
- dryRun = false,
176
- severity = [SEVERITY.CRITICAL, SEVERITY.ERROR],
177
- maxFixes = 10,
178
- } = options;
179
-
180
- const results = [];
181
- let fixCount = 0;
182
-
183
- // Sort by severity (critical first)
184
- const severityOrder = [SEVERITY.CRITICAL, SEVERITY.ERROR, SEVERITY.WARNING];
185
- const sortedDiagnostics = [...diagnostics].sort((a, b) => {
186
- return severityOrder.indexOf(a.severity) - severityOrder.indexOf(b.severity);
187
- });
188
-
189
- for (const diagnostic of sortedDiagnostics) {
190
- if (fixCount >= maxFixes) break;
191
- if (!severity.includes(diagnostic.severity)) continue;
192
- if (!diagnostic.fixes || diagnostic.fixes.length === 0) continue;
193
-
194
- // Try the first auto-fixable fix
195
- const fix = diagnostic.fixes.find(f => canAutoFix(f));
196
- if (!fix) continue;
197
-
198
- const result = await executeFix(fix, projectPath, { ...options, dryRun });
199
- results.push({
200
- diagnosticId: diagnostic.id,
201
- diagnosticName: diagnostic.name,
202
- ...result,
203
- });
204
-
205
- if (result.status === FIX_RESULT.SUCCESS) {
206
- fixCount++;
207
- }
208
- }
209
-
210
- return {
211
- attempted: results.length,
212
- succeeded: results.filter(r => r.status === FIX_RESULT.SUCCESS).length,
213
- failed: results.filter(r => r.status === FIX_RESULT.FAILED).length,
214
- skipped: results.filter(r => r.status === FIX_RESULT.SKIPPED).length,
215
- results,
216
- };
217
- }
218
-
219
- function getFixCommands(diagnostics, options = {}) {
220
- const { severity = [SEVERITY.CRITICAL, SEVERITY.ERROR, SEVERITY.WARNING] } = options;
221
-
222
- const commands = [];
223
-
224
- for (const diagnostic of diagnostics) {
225
- if (!severity.includes(diagnostic.severity)) continue;
226
- if (!diagnostic.fixes) continue;
227
-
228
- for (const fix of diagnostic.fixes) {
229
- if (fix.type === FIX_TYPE.COMMAND && fix.command) {
230
- commands.push({
231
- diagnosticId: diagnostic.id,
232
- diagnosticName: diagnostic.name,
233
- command: fix.command,
234
- description: fix.description,
235
- dangerous: fix.dangerous,
236
- autoFixable: canAutoFix(fix),
237
- });
238
- }
239
- }
240
- }
241
-
242
- return commands;
243
- }
244
-
245
- module.exports = {
246
- FIX_RESULT,
247
- canAutoFix,
248
- executeFix,
249
- executeCommand,
250
- createFile,
251
- editFile,
252
- autoFixAll,
253
- getFixCommands,
254
- };
@@ -1,37 +0,0 @@
1
- /**
2
- * Doctor Service — Enterprise Environment Diagnostics
3
- *
4
- * Main entry point for the Doctor service
5
- */
6
-
7
- const { DoctorService, diagnose } = require('./service');
8
- const { SEVERITY, CATEGORY, FIX_TYPE, SEVERITY_WEIGHT, CATEGORY_META } = require('./types');
9
- const modules = require('./modules');
10
- const reporter = require('./reporter');
11
- const autofix = require('./autofix');
12
- const ui = require('./ui');
13
-
14
- module.exports = {
15
- // Main service
16
- DoctorService,
17
- diagnose,
18
-
19
- // Types and constants
20
- SEVERITY,
21
- CATEGORY,
22
- FIX_TYPE,
23
- SEVERITY_WEIGHT,
24
- CATEGORY_META,
25
-
26
- // Modules
27
- modules,
28
-
29
- // Reporter
30
- reporter,
31
-
32
- // Auto-fix
33
- autofix,
34
-
35
- // UI utilities
36
- ui,
37
- };