@vibecheckai/cli 3.2.6 → 3.3.0
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/bin/registry.js +192 -5
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +280 -6
- package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
- package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
- package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
- package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
- package/bin/runners/lib/agent-firewall/logger.js +141 -0
- package/bin/runners/lib/agent-firewall/policy/loader.js +312 -4
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +113 -1
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +133 -6
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
- package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
- package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
- package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
- package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
- package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
- package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
- package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +321 -0
- package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
- package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
- package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
- package/bin/runners/lib/analyzers.js +81 -18
- package/bin/runners/lib/authority-badge.js +425 -0
- package/bin/runners/lib/cli-output.js +7 -1
- package/bin/runners/lib/error-handler.js +16 -9
- package/bin/runners/lib/exit-codes.js +275 -0
- package/bin/runners/lib/global-flags.js +37 -0
- package/bin/runners/lib/help-formatter.js +413 -0
- package/bin/runners/lib/logger.js +38 -0
- package/bin/runners/lib/unified-cli-output.js +604 -0
- package/bin/runners/lib/upsell.js +148 -0
- package/bin/runners/runApprove.js +1200 -0
- package/bin/runners/runAuth.js +324 -95
- package/bin/runners/runCheckpoint.js +39 -21
- package/bin/runners/runClassify.js +859 -0
- package/bin/runners/runContext.js +136 -24
- package/bin/runners/runDoctor.js +108 -68
- package/bin/runners/runFix.js +6 -5
- package/bin/runners/runGuard.js +212 -118
- package/bin/runners/runInit.js +3 -2
- package/bin/runners/runMcp.js +130 -52
- package/bin/runners/runPolish.js +43 -20
- package/bin/runners/runProve.js +1 -2
- package/bin/runners/runReport.js +3 -2
- package/bin/runners/runScan.js +63 -44
- package/bin/runners/runShip.js +3 -4
- package/bin/runners/runValidate.js +19 -2
- package/bin/runners/runWatch.js +104 -53
- package/bin/vibecheck.js +106 -19
- package/mcp-server/HARDENING_SUMMARY.md +299 -0
- package/mcp-server/agent-firewall-interceptor.js +367 -31
- package/mcp-server/authority-tools.js +569 -0
- package/mcp-server/conductor/conflict-resolver.js +588 -0
- package/mcp-server/conductor/execution-planner.js +544 -0
- package/mcp-server/conductor/index.js +377 -0
- package/mcp-server/conductor/lock-manager.js +615 -0
- package/mcp-server/conductor/request-queue.js +550 -0
- package/mcp-server/conductor/session-manager.js +500 -0
- package/mcp-server/conductor/tools.js +510 -0
- package/mcp-server/index.js +1149 -243
- package/mcp-server/lib/{api-client.js → api-client.cjs} +40 -4
- package/mcp-server/lib/logger.cjs +30 -0
- package/mcp-server/logger.js +173 -0
- package/mcp-server/package.json +2 -2
- package/mcp-server/premium-tools.js +2 -2
- package/mcp-server/tier-auth.js +245 -35
- package/mcp-server/truth-firewall-tools.js +145 -15
- package/mcp-server/vibecheck-tools.js +2 -2
- package/package.json +2 -3
- package/mcp-server/index.old.js +0 -4137
- package/mcp-server/package-lock.json +0 -165
|
@@ -1,22 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* runContext.js - AI Rules Generator
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
* World-Class AI Context Generation
|
|
6
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
7
|
*/
|
|
6
8
|
|
|
7
9
|
const path = require("path");
|
|
10
|
+
const fs = require("fs");
|
|
8
11
|
const { runContext: contextRunner } = require("./context");
|
|
9
|
-
const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
|
|
12
|
+
const { parseGlobalFlags, shouldShowBanner, shouldSuppressOutput, isJsonMode } = require("./lib/global-flags");
|
|
13
|
+
const { EXIT } = require("./lib/exit-codes");
|
|
14
|
+
const {
|
|
15
|
+
ansi,
|
|
16
|
+
sym,
|
|
17
|
+
renderMinimalHeader,
|
|
18
|
+
renderSectionHeader,
|
|
19
|
+
renderSuccess,
|
|
20
|
+
renderError,
|
|
21
|
+
renderBullet,
|
|
22
|
+
renderFooter,
|
|
23
|
+
Spinner,
|
|
24
|
+
getTierFromKey,
|
|
25
|
+
} = require("./lib/unified-cli-output");
|
|
10
26
|
|
|
11
27
|
async function runContext(args) {
|
|
12
|
-
// Parse global flags first
|
|
13
28
|
const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
|
|
14
|
-
|
|
29
|
+
const quiet = shouldSuppressOutput(globalFlags);
|
|
30
|
+
const json = isJsonMode(globalFlags);
|
|
15
31
|
const root = globalFlags.path || process.cwd();
|
|
32
|
+
const startTime = Date.now();
|
|
16
33
|
|
|
17
34
|
// Parse command-specific args
|
|
18
35
|
const opts = {
|
|
19
|
-
...globalFlags,
|
|
36
|
+
...globalFlags,
|
|
20
37
|
output: null,
|
|
21
38
|
format: "all"
|
|
22
39
|
};
|
|
@@ -29,34 +46,129 @@ async function runContext(args) {
|
|
|
29
46
|
}
|
|
30
47
|
|
|
31
48
|
if (opts.help) {
|
|
32
|
-
|
|
33
|
-
${
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
console.log(`
|
|
50
|
+
${ansi.bold}USAGE${ansi.reset}
|
|
51
|
+
${ansi.cyan}vibecheck context${ansi.reset} [options]
|
|
52
|
+
|
|
53
|
+
${ansi.dim}Aliases: rules, ai-rules, mdc${ansi.reset}
|
|
54
|
+
|
|
55
|
+
Generate project-aware AI coding rules for your IDE. These rules help
|
|
56
|
+
AI assistants understand your codebase conventions, preventing common
|
|
57
|
+
mistakes and enforcing patterns.
|
|
58
|
+
|
|
59
|
+
${ansi.bold}FORMATS${ansi.reset}
|
|
60
|
+
${ansi.cyan}cursor${ansi.reset} .cursorrules file for Cursor IDE
|
|
61
|
+
${ansi.cyan}mdc${ansi.reset} MDC format (.cursor/rules/*.mdc)
|
|
62
|
+
${ansi.cyan}windsurf${ansi.reset} Windsurf rules directory
|
|
63
|
+
${ansi.cyan}copilot${ansi.reset} GitHub Copilot instructions
|
|
64
|
+
${ansi.cyan}all${ansi.reset} Generate all formats (default)
|
|
65
|
+
|
|
66
|
+
${ansi.bold}OPTIONS${ansi.reset}
|
|
67
|
+
${ansi.cyan}-f, --format <fmt>${ansi.reset} Format to generate (default: all)
|
|
68
|
+
${ansi.cyan}-o, --output <dir>${ansi.reset} Output directory (default: project root)
|
|
69
|
+
${ansi.cyan}--json${ansi.reset} Output result as JSON
|
|
70
|
+
${ansi.cyan}--quiet, -q${ansi.reset} Suppress non-essential output
|
|
71
|
+
${ansi.cyan}--help, -h${ansi.reset} Show this help
|
|
72
|
+
|
|
73
|
+
${ansi.bold}EXAMPLES${ansi.reset}
|
|
74
|
+
${ansi.dim}# Generate all rule files${ansi.reset}
|
|
75
|
+
vibecheck context
|
|
76
|
+
|
|
77
|
+
${ansi.dim}# Generate only Cursor rules${ansi.reset}
|
|
78
|
+
vibecheck context --format cursor
|
|
79
|
+
|
|
80
|
+
${ansi.dim}# Custom output directory${ansi.reset}
|
|
81
|
+
vibecheck context --output ./ai-rules
|
|
82
|
+
|
|
83
|
+
${ansi.bold}OUTPUT FILES${ansi.reset}
|
|
84
|
+
.cursorrules Cursor IDE rules
|
|
85
|
+
.cursor/rules/*.mdc MDC format rules
|
|
86
|
+
.windsurf/rules/*.md Windsurf rules
|
|
87
|
+
.github/copilot-instructions.md
|
|
88
|
+
|
|
89
|
+
${ansi.dim}────────────────────────────────────────────────────────────────────${ansi.reset}
|
|
90
|
+
${ansi.dim}Documentation: https://docs.vibecheckai.dev/cli/context${ansi.reset}
|
|
46
91
|
`);
|
|
47
|
-
return
|
|
92
|
+
return EXIT.SUCCESS;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Validate project path exists
|
|
96
|
+
if (!fs.existsSync(root)) {
|
|
97
|
+
if (json) {
|
|
98
|
+
console.log(JSON.stringify({ success: false, error: `Project path does not exist: ${root}` }));
|
|
99
|
+
} else {
|
|
100
|
+
renderError(`Project path does not exist: ${root}`);
|
|
101
|
+
console.log(` ${ansi.dim}Verify the path and try again.${ansi.reset}`);
|
|
102
|
+
}
|
|
103
|
+
return EXIT.NOT_FOUND;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Validate format option
|
|
107
|
+
const validFormats = ["all", "cursor", "mdc", "windsurf", "copilot"];
|
|
108
|
+
if (!validFormats.includes(opts.format)) {
|
|
109
|
+
if (json) {
|
|
110
|
+
console.log(JSON.stringify({ success: false, error: `Unknown format: ${opts.format}`, validFormats }));
|
|
111
|
+
} else {
|
|
112
|
+
renderError(`Unknown format: ${opts.format}`);
|
|
113
|
+
console.log(` ${ansi.dim}Valid formats: ${validFormats.join(", ")}${ansi.reset}`);
|
|
114
|
+
}
|
|
115
|
+
return EXIT.USER_ERROR;
|
|
48
116
|
}
|
|
49
117
|
|
|
50
118
|
try {
|
|
51
|
-
|
|
119
|
+
if (!quiet && !json) {
|
|
120
|
+
renderMinimalHeader("context", "starter");
|
|
121
|
+
renderSectionHeader("Generating AI Rules", sym.gear);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const spinner = !quiet && !json ? new Spinner(`Analyzing project and generating ${opts.format} rules`).start() : null;
|
|
125
|
+
|
|
126
|
+
const result = await contextRunner({
|
|
52
127
|
repoRoot: root,
|
|
53
128
|
output: opts.output,
|
|
54
129
|
format: opts.format
|
|
55
130
|
});
|
|
56
|
-
|
|
131
|
+
|
|
132
|
+
const duration = Date.now() - startTime;
|
|
133
|
+
|
|
134
|
+
if (json) {
|
|
135
|
+
console.log(JSON.stringify({
|
|
136
|
+
success: true,
|
|
137
|
+
format: opts.format,
|
|
138
|
+
files: result?.files || [],
|
|
139
|
+
path: root,
|
|
140
|
+
duration,
|
|
141
|
+
}));
|
|
142
|
+
} else if (!quiet) {
|
|
143
|
+
spinner?.succeed("AI rules generated successfully");
|
|
144
|
+
|
|
145
|
+
// Show generated files
|
|
146
|
+
if (result?.files && result.files.length > 0) {
|
|
147
|
+
console.log();
|
|
148
|
+
console.log(` ${ansi.bold}Generated files:${ansi.reset}`);
|
|
149
|
+
result.files.forEach(f => {
|
|
150
|
+
renderBullet(`${ansi.cyan}${f}${ansi.reset}`, 4);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
renderFooter({
|
|
155
|
+
nextSteps: [
|
|
156
|
+
{ cmd: "vibecheck scan", desc: "analyze code quality" },
|
|
157
|
+
{ cmd: "vibecheck guard", desc: "validate AI outputs" },
|
|
158
|
+
],
|
|
159
|
+
docsUrl: "https://docs.vibecheckai.dev/cli/context",
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return EXIT.SUCCESS;
|
|
57
164
|
} catch (error) {
|
|
58
|
-
|
|
59
|
-
|
|
165
|
+
if (json) {
|
|
166
|
+
console.log(JSON.stringify({ success: false, error: error.message }));
|
|
167
|
+
} else {
|
|
168
|
+
renderError(`Failed to generate context: ${error.message}`);
|
|
169
|
+
console.log(` ${ansi.dim}Run "vibecheck doctor" to check your setup.${ansi.reset}`);
|
|
170
|
+
}
|
|
171
|
+
return EXIT.INTERNAL_ERROR;
|
|
60
172
|
}
|
|
61
173
|
}
|
|
62
174
|
|
package/bin/runners/runDoctor.js
CHANGED
|
@@ -18,7 +18,10 @@ const {
|
|
|
18
18
|
verdictToExitCode,
|
|
19
19
|
saveArtifact
|
|
20
20
|
} = require("./lib/cli-output");
|
|
21
|
-
const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
|
|
21
|
+
const { parseGlobalFlags, shouldShowBanner, shouldSuppressOutput, isJsonMode } = require("./lib/global-flags");
|
|
22
|
+
const { EXIT } = require("./lib/exit-codes");
|
|
23
|
+
const { formatWorkflowUpsell } = require("./lib/upsell");
|
|
24
|
+
const { getApiKey } = require("./lib/auth");
|
|
22
25
|
|
|
23
26
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
24
27
|
// ADVANCED TERMINAL - ANSI CODES & UTILITIES
|
|
@@ -298,86 +301,110 @@ async function runDoctor(args, context = {}) {
|
|
|
298
301
|
const startTime = context.startTime || new Date().toISOString();
|
|
299
302
|
|
|
300
303
|
const opts = parseArgs(args);
|
|
304
|
+
const quiet = shouldSuppressOutput(opts);
|
|
305
|
+
const json = isJsonMode(opts);
|
|
301
306
|
const executionStart = Date.now();
|
|
302
307
|
|
|
303
308
|
if (opts.help) {
|
|
304
309
|
printHelp(shouldShowBanner(opts));
|
|
305
|
-
return
|
|
310
|
+
return EXIT.SUCCESS;
|
|
306
311
|
}
|
|
307
312
|
|
|
308
313
|
const projectPath = path.resolve(opts.path || process.cwd());
|
|
309
|
-
const projectName = path.basename(projectPath);
|
|
310
314
|
|
|
311
|
-
//
|
|
312
|
-
if (
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
315
|
+
// Validate project path exists
|
|
316
|
+
if (!fs.existsSync(projectPath)) {
|
|
317
|
+
if (json) {
|
|
318
|
+
console.log(JSON.stringify({ success: false, error: `Project path does not exist: ${projectPath}` }));
|
|
319
|
+
} else {
|
|
320
|
+
console.error(` ❌ Project path does not exist: ${projectPath}`);
|
|
321
|
+
}
|
|
322
|
+
return EXIT.NOT_FOUND;
|
|
317
323
|
}
|
|
324
|
+
const projectName = path.basename(projectPath);
|
|
318
325
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
categories: opts.categories,
|
|
328
|
-
skipNetwork: opts.skipNetwork,
|
|
329
|
-
saveReport: opts.saveReport,
|
|
330
|
-
failOnWarn: opts.failOnWarn,
|
|
331
|
-
runId,
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
const results = await doctor.run();
|
|
326
|
+
try {
|
|
327
|
+
// Print banner conditionally
|
|
328
|
+
if (shouldShowBanner(opts) && !quiet) {
|
|
329
|
+
printBanner();
|
|
330
|
+
console.log(` ${c.dim}Project:${c.reset} ${c.bold}${projectName}${c.reset}`);
|
|
331
|
+
console.log(` ${c.dim}Path:${c.reset} ${projectPath}`);
|
|
332
|
+
console.log();
|
|
333
|
+
}
|
|
335
334
|
|
|
336
|
-
//
|
|
337
|
-
if (
|
|
338
|
-
const
|
|
335
|
+
// Use new DoctorService if available
|
|
336
|
+
if (DoctorService.name === 'DoctorService') {
|
|
337
|
+
const doctor = new DoctorService(projectPath, {
|
|
338
|
+
json: opts.json,
|
|
339
|
+
fix: opts.fix,
|
|
340
|
+
fixDryRun: opts.dryRun,
|
|
341
|
+
quiet: opts.quiet || quiet,
|
|
342
|
+
verbose: opts.verbose,
|
|
343
|
+
categories: opts.categories,
|
|
344
|
+
skipNetwork: opts.skipNetwork,
|
|
345
|
+
saveReport: opts.saveReport,
|
|
346
|
+
failOnWarn: opts.failOnWarn,
|
|
339
347
|
runId,
|
|
340
|
-
command: "doctor",
|
|
341
|
-
startTime,
|
|
342
|
-
exitCode: results.exitCode || 0,
|
|
343
|
-
verdict: exitCodeToVerdict(results.exitCode || 0),
|
|
344
|
-
result: {
|
|
345
|
-
health: results.health || "unknown",
|
|
346
|
-
checks: results.checks || [],
|
|
347
|
-
fixes: results.fixes || [],
|
|
348
|
-
summary: {
|
|
349
|
-
total: results.totalChecks || 0,
|
|
350
|
-
passed: results.passedChecks || 0,
|
|
351
|
-
warnings: results.warnings || 0,
|
|
352
|
-
errors: results.errors || 0,
|
|
353
|
-
}
|
|
354
|
-
},
|
|
355
|
-
tier: "free",
|
|
356
|
-
version: require("../../package.json").version,
|
|
357
|
-
artifacts: results.reportPath ? [{
|
|
358
|
-
type: "report",
|
|
359
|
-
path: results.reportPath,
|
|
360
|
-
description: "Doctor report"
|
|
361
|
-
}] : []
|
|
362
348
|
});
|
|
363
349
|
|
|
364
|
-
|
|
350
|
+
const results = await doctor.run();
|
|
351
|
+
|
|
352
|
+
// Apply CLI output conventions
|
|
353
|
+
if (opts.json || json) {
|
|
354
|
+
const output = createJsonOutput({
|
|
355
|
+
runId,
|
|
356
|
+
command: "doctor",
|
|
357
|
+
startTime,
|
|
358
|
+
exitCode: results.exitCode || EXIT.SUCCESS,
|
|
359
|
+
verdict: exitCodeToVerdict(results.exitCode || EXIT.SUCCESS),
|
|
360
|
+
result: {
|
|
361
|
+
health: results.health || "unknown",
|
|
362
|
+
checks: results.checks || [],
|
|
363
|
+
fixes: results.fixes || [],
|
|
364
|
+
summary: {
|
|
365
|
+
total: results.totalChecks || 0,
|
|
366
|
+
passed: results.passedChecks || 0,
|
|
367
|
+
warnings: results.warnings || 0,
|
|
368
|
+
errors: results.errors || 0,
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
tier: "free",
|
|
372
|
+
version: require("../../package.json").version,
|
|
373
|
+
artifacts: results.reportPath ? [{
|
|
374
|
+
type: "report",
|
|
375
|
+
path: results.reportPath,
|
|
376
|
+
description: "Doctor report"
|
|
377
|
+
}] : []
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
writeJsonOutput(output, opts.output);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Save artifacts
|
|
384
|
+
if (results.checks) {
|
|
385
|
+
saveArtifact(runId, "checks", results.checks);
|
|
386
|
+
}
|
|
387
|
+
if (results.fixes) {
|
|
388
|
+
saveArtifact(runId, "fixes", results.fixes);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Map results to proper exit codes
|
|
392
|
+
if (results.errors > 0) return EXIT.BLOCKING;
|
|
393
|
+
if (results.warnings > 0) return EXIT.WARNINGS;
|
|
394
|
+
return EXIT.SUCCESS;
|
|
365
395
|
}
|
|
366
396
|
|
|
367
|
-
//
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if (
|
|
372
|
-
|
|
397
|
+
// Legacy fallback
|
|
398
|
+
const doctor = new DoctorService(projectPath, opts);
|
|
399
|
+
return await doctor.diagnose();
|
|
400
|
+
} catch (error) {
|
|
401
|
+
if (json) {
|
|
402
|
+
console.log(JSON.stringify({ success: false, error: error.message }));
|
|
403
|
+
} else {
|
|
404
|
+
console.error(` ❌ Doctor check failed: ${error.message}`);
|
|
373
405
|
}
|
|
374
|
-
|
|
375
|
-
return results.exitCode || 0;
|
|
406
|
+
return EXIT.INTERNAL_ERROR;
|
|
376
407
|
}
|
|
377
|
-
|
|
378
|
-
// Legacy fallback
|
|
379
|
-
const doctor = new DoctorService(projectPath, opts);
|
|
380
|
-
return await doctor.diagnose();
|
|
381
408
|
}
|
|
382
409
|
|
|
383
410
|
function parseArgs(args) {
|
|
@@ -573,20 +600,33 @@ function runDoctorLegacy() {
|
|
|
573
600
|
}
|
|
574
601
|
|
|
575
602
|
console.log("");
|
|
603
|
+
|
|
604
|
+
// Get tier for upsell
|
|
605
|
+
const { key } = getApiKey();
|
|
606
|
+
const currentTier = key ? "starter" : "free";
|
|
607
|
+
|
|
576
608
|
if (hasIssues) {
|
|
577
609
|
console.log(" ❌ Issues found. Fix them and run doctor again.");
|
|
578
610
|
console.log();
|
|
579
611
|
console.log(` ${c.dim}Need help?${c.reset} ${colors.accent}vibecheck fix${c.reset} ${c.dim}can auto-repair many issues${c.reset}`);
|
|
580
|
-
|
|
612
|
+
if (currentTier === "free") {
|
|
613
|
+
console.log(` ${c.dim}Requires STARTER plan • vibecheckai.dev${c.reset}`);
|
|
614
|
+
}
|
|
581
615
|
console.log();
|
|
582
|
-
return
|
|
616
|
+
return EXIT.BLOCKING;
|
|
583
617
|
} else {
|
|
584
618
|
console.log(" ✅ Environment healthy!");
|
|
585
619
|
console.log();
|
|
586
|
-
|
|
587
|
-
|
|
620
|
+
|
|
621
|
+
// Workflow upsell
|
|
622
|
+
const workflow = formatWorkflowUpsell("doctor", currentTier);
|
|
623
|
+
if (workflow) {
|
|
624
|
+
console.log(` ${workflow}`);
|
|
625
|
+
} else {
|
|
626
|
+
console.log(` ${c.dim}Ready to scan?${c.reset} ${colors.accent}vibecheck scan${c.reset} ${c.dim}finds AI mistakes before they ship${c.reset}`);
|
|
627
|
+
}
|
|
588
628
|
console.log();
|
|
589
|
-
return
|
|
629
|
+
return EXIT.SUCCESS;
|
|
590
630
|
}
|
|
591
631
|
}
|
|
592
632
|
|
package/bin/runners/runFix.js
CHANGED
|
@@ -33,6 +33,7 @@ const { backupFiles, restoreBackup } = require('./lib/backup');
|
|
|
33
33
|
const { validatePatchResponse, parseDiffTouchedFiles } = require('./lib/validate-patch');
|
|
34
34
|
const { buildSharePack } = require('./lib/share-pack');
|
|
35
35
|
const { parseGlobalFlags, shouldShowBanner } = require('./lib/global-flags');
|
|
36
|
+
const { EXIT, verdictToExitCode } = require('./lib/exit-codes');
|
|
36
37
|
|
|
37
38
|
// Entitlements enforcement
|
|
38
39
|
const entitlements = require('./lib/entitlements-v2');
|
|
@@ -696,7 +697,7 @@ async function runFix(args) {
|
|
|
696
697
|
} catch (e) {
|
|
697
698
|
stopSpinner('LLM failed', false);
|
|
698
699
|
console.log(` ${colors.blockRed}${ICONS.cross}${c.reset} ${e.message}`);
|
|
699
|
-
return
|
|
700
|
+
return EXIT.INTERNAL_ERROR;
|
|
700
701
|
}
|
|
701
702
|
|
|
702
703
|
const respPath = path.join(outDir, `step_${String(step).padStart(2,"0")}_${mission.id}_response.json`);
|
|
@@ -722,7 +723,7 @@ async function runFix(args) {
|
|
|
722
723
|
console.log(` ${colors.warnAmber}${ICONS.warning}${c.reset} ${w}`);
|
|
723
724
|
}
|
|
724
725
|
}
|
|
725
|
-
return
|
|
726
|
+
return EXIT.BLOCKING;
|
|
726
727
|
}
|
|
727
728
|
|
|
728
729
|
if (v.warnings.length) {
|
|
@@ -753,7 +754,7 @@ async function runFix(args) {
|
|
|
753
754
|
console.log(` ${colors.blockRed}${ICONS.cross}${c.reset} Patch apply failed: ${res.error}`);
|
|
754
755
|
restoreBackup(root, backupRoot);
|
|
755
756
|
console.log(` ${colors.rollback}${ICONS.rollback}${c.reset} Restored from backup`);
|
|
756
|
-
return
|
|
757
|
+
return EXIT.INTERNAL_ERROR;
|
|
757
758
|
}
|
|
758
759
|
console.log(` ${colors.patch}${ICONS.patch}${c.reset} Applied: ${c.dim}${ed.path}${c.reset}`);
|
|
759
760
|
}
|
|
@@ -789,7 +790,7 @@ async function runFix(args) {
|
|
|
789
790
|
console.log();
|
|
790
791
|
console.log(` ${colors.blockRed}${ICONS.stop}${c.reset} Stopping: stagnation limit reached (${stagnant}/${stagnationLimit})`);
|
|
791
792
|
console.log();
|
|
792
|
-
return
|
|
793
|
+
return EXIT.BLOCKING;
|
|
793
794
|
}
|
|
794
795
|
continue;
|
|
795
796
|
}
|
|
@@ -820,7 +821,7 @@ async function runFix(args) {
|
|
|
820
821
|
}
|
|
821
822
|
}
|
|
822
823
|
|
|
823
|
-
return
|
|
824
|
+
return EXIT.WARNINGS; // Max steps reached, incomplete
|
|
824
825
|
}
|
|
825
826
|
|
|
826
827
|
// ═══════════════════════════════════════════════════════════════════════════════
|