@vibecheckai/cli 3.5.0 → 3.5.2
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 +214 -237
- package/bin/runners/cli-utils.js +33 -2
- package/bin/runners/context/analyzer.js +52 -1
- package/bin/runners/context/generators/cursor.js +2 -49
- package/bin/runners/context/git-context.js +3 -1
- package/bin/runners/context/team-conventions.js +33 -7
- package/bin/runners/lib/analysis-core.js +25 -5
- package/bin/runners/lib/analyzers.js +431 -481
- package/bin/runners/lib/default-config.js +127 -0
- package/bin/runners/lib/doctor/modules/security.js +3 -1
- package/bin/runners/lib/engine/ast-cache.js +210 -0
- package/bin/runners/lib/engine/auth-extractor.js +211 -0
- package/bin/runners/lib/engine/billing-extractor.js +112 -0
- package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
- package/bin/runners/lib/engine/env-extractor.js +207 -0
- package/bin/runners/lib/engine/express-extractor.js +208 -0
- package/bin/runners/lib/engine/extractors.js +849 -0
- package/bin/runners/lib/engine/index.js +207 -0
- package/bin/runners/lib/engine/repo-index.js +514 -0
- package/bin/runners/lib/engine/types.js +124 -0
- package/bin/runners/lib/engines/accessibility-engine.js +18 -218
- package/bin/runners/lib/engines/api-consistency-engine.js +30 -335
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +27 -292
- package/bin/runners/lib/engines/empty-catch-engine.js +17 -127
- package/bin/runners/lib/engines/mock-data-engine.js +10 -53
- package/bin/runners/lib/engines/performance-issues-engine.js +36 -176
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +54 -382
- package/bin/runners/lib/engines/type-aware-engine.js +39 -263
- package/bin/runners/lib/engines/vibecheck-engines/index.js +13 -122
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +73 -373
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
- package/bin/runners/lib/entitlements-v2.js +73 -97
- package/bin/runners/lib/error-handler.js +44 -3
- package/bin/runners/lib/error-messages.js +289 -0
- package/bin/runners/lib/evidence-pack.js +7 -1
- package/bin/runners/lib/finding-id.js +69 -0
- package/bin/runners/lib/finding-sorter.js +89 -0
- package/bin/runners/lib/html-proof-report.js +700 -350
- package/bin/runners/lib/missions/plan.js +6 -46
- package/bin/runners/lib/missions/templates.js +0 -232
- package/bin/runners/lib/next-action.js +560 -0
- package/bin/runners/lib/prerequisites.js +149 -0
- package/bin/runners/lib/route-detection.js +137 -68
- package/bin/runners/lib/scan-output.js +91 -76
- package/bin/runners/lib/scan-runner.js +135 -0
- package/bin/runners/lib/schemas/ajv-validator.js +464 -0
- package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
- package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
- package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
- package/bin/runners/lib/schemas/run-request.schema.json +108 -0
- package/bin/runners/lib/schemas/validator.js +27 -0
- package/bin/runners/lib/schemas/verdict.schema.json +140 -0
- package/bin/runners/lib/ship-output-enterprise.js +23 -23
- package/bin/runners/lib/ship-output.js +75 -31
- package/bin/runners/lib/terminal-ui.js +6 -113
- package/bin/runners/lib/truth.js +351 -10
- package/bin/runners/lib/unified-cli-output.js +430 -603
- package/bin/runners/lib/unified-output.js +13 -9
- package/bin/runners/runAIAgent.js +10 -5
- package/bin/runners/runAgent.js +0 -3
- package/bin/runners/runAllowlist.js +389 -0
- package/bin/runners/runApprove.js +0 -33
- package/bin/runners/runAuth.js +73 -45
- package/bin/runners/runCheckpoint.js +51 -11
- package/bin/runners/runClassify.js +85 -21
- package/bin/runners/runContext.js +0 -3
- package/bin/runners/runDoctor.js +41 -28
- package/bin/runners/runEvidencePack.js +362 -0
- package/bin/runners/runFirewall.js +0 -3
- package/bin/runners/runFirewallHook.js +0 -3
- package/bin/runners/runFix.js +66 -76
- package/bin/runners/runGuard.js +18 -411
- package/bin/runners/runInit.js +113 -30
- package/bin/runners/runLabs.js +424 -0
- package/bin/runners/runMcp.js +19 -25
- package/bin/runners/runPolish.js +64 -240
- package/bin/runners/runPromptFirewall.js +12 -5
- package/bin/runners/runProve.js +57 -22
- package/bin/runners/runQuickstart.js +531 -0
- package/bin/runners/runReality.js +59 -68
- package/bin/runners/runReport.js +38 -33
- package/bin/runners/runRuntime.js +8 -5
- package/bin/runners/runScan.js +1413 -190
- package/bin/runners/runShip.js +113 -719
- package/bin/runners/runTruth.js +0 -3
- package/bin/runners/runValidate.js +13 -9
- package/bin/runners/runWatch.js +23 -14
- package/bin/scan.js +6 -1
- package/bin/vibecheck.js +204 -185
- package/mcp-server/deprecation-middleware.js +282 -0
- package/mcp-server/handlers/index.ts +15 -0
- package/mcp-server/handlers/tool-handler.ts +554 -0
- package/mcp-server/index-v1.js +698 -0
- package/mcp-server/index.js +210 -238
- package/mcp-server/lib/cache-wrapper.cjs +383 -0
- package/mcp-server/lib/error-envelope.js +138 -0
- package/mcp-server/lib/executor.ts +499 -0
- package/mcp-server/lib/index.ts +19 -0
- package/mcp-server/lib/rate-limiter.js +166 -0
- package/mcp-server/lib/sandbox.test.ts +519 -0
- package/mcp-server/lib/sandbox.ts +395 -0
- package/mcp-server/lib/types.ts +267 -0
- package/mcp-server/package.json +12 -3
- package/mcp-server/registry/tool-registry.js +794 -0
- package/mcp-server/registry/tools.json +605 -0
- package/mcp-server/registry.test.ts +334 -0
- package/mcp-server/tests/tier-gating.test.js +297 -0
- package/mcp-server/tier-auth.js +378 -45
- package/mcp-server/tools-v3.js +353 -442
- package/mcp-server/tsconfig.json +37 -0
- package/mcp-server/vibecheck-2.0-tools.js +14 -1
- package/package.json +1 -1
- package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
- package/bin/runners/lib/audit-logger.js +0 -532
- package/bin/runners/lib/authority/authorities/architecture.js +0 -364
- package/bin/runners/lib/authority/authorities/compliance.js +0 -341
- package/bin/runners/lib/authority/authorities/human.js +0 -343
- package/bin/runners/lib/authority/authorities/quality.js +0 -420
- package/bin/runners/lib/authority/authorities/security.js +0 -228
- package/bin/runners/lib/authority/index.js +0 -293
- package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
- package/bin/runners/lib/cli-charts.js +0 -368
- package/bin/runners/lib/cli-config-display.js +0 -405
- package/bin/runners/lib/cli-demo.js +0 -275
- package/bin/runners/lib/cli-errors.js +0 -438
- package/bin/runners/lib/cli-help-formatter.js +0 -439
- package/bin/runners/lib/cli-interactive-menu.js +0 -509
- package/bin/runners/lib/cli-prompts.js +0 -441
- package/bin/runners/lib/cli-scan-cards.js +0 -362
- package/bin/runners/lib/compliance-reporter.js +0 -710
- package/bin/runners/lib/conductor/index.js +0 -671
- package/bin/runners/lib/easy/README.md +0 -123
- package/bin/runners/lib/easy/index.js +0 -140
- package/bin/runners/lib/easy/interactive-wizard.js +0 -788
- package/bin/runners/lib/easy/one-click-firewall.js +0 -564
- package/bin/runners/lib/easy/zero-config-reality.js +0 -714
- package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
- package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
- package/bin/runners/lib/engines/confidence-scoring.js +0 -276
- package/bin/runners/lib/engines/context-detection.js +0 -264
- package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
- package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
- package/bin/runners/lib/engines/env-variables-engine.js +0 -458
- package/bin/runners/lib/engines/error-handling-engine.js +0 -437
- package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
- package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
- package/bin/runners/lib/engines/framework-detection.js +0 -508
- package/bin/runners/lib/engines/import-order-engine.js +0 -429
- package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
- package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
- package/bin/runners/lib/engines/orchestrator.js +0 -334
- package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
- package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
- package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
- package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
- package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
- package/bin/runners/lib/enhanced-features/index.js +0 -305
- package/bin/runners/lib/enhanced-output.js +0 -631
- package/bin/runners/lib/enterprise.js +0 -300
- package/bin/runners/lib/firewall/command-validator.js +0 -351
- package/bin/runners/lib/firewall/config.js +0 -341
- package/bin/runners/lib/firewall/content-validator.js +0 -519
- package/bin/runners/lib/firewall/index.js +0 -101
- package/bin/runners/lib/firewall/path-validator.js +0 -256
- package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
- package/bin/runners/lib/mcp-utils.js +0 -425
- package/bin/runners/lib/output/index.js +0 -1022
- package/bin/runners/lib/policy-engine.js +0 -652
- package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
- package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
- package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
- package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
- package/bin/runners/lib/polish/autofix/index.js +0 -200
- package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
- package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
- package/bin/runners/lib/polish/backend-checks.js +0 -148
- package/bin/runners/lib/polish/documentation-checks.js +0 -111
- package/bin/runners/lib/polish/frontend-checks.js +0 -168
- package/bin/runners/lib/polish/index.js +0 -71
- package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
- package/bin/runners/lib/polish/library-detection.js +0 -175
- package/bin/runners/lib/polish/performance-checks.js +0 -100
- package/bin/runners/lib/polish/security-checks.js +0 -148
- package/bin/runners/lib/polish/utils.js +0 -203
- package/bin/runners/lib/prompt-builder.js +0 -540
- package/bin/runners/lib/proof-certificate.js +0 -634
- package/bin/runners/lib/reality/accessibility-audit.js +0 -946
- package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
- package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
- package/bin/runners/lib/reality/performance-tracker.js +0 -1077
- package/bin/runners/lib/reality/scenario-generator.js +0 -1404
- package/bin/runners/lib/reality/visual-regression.js +0 -852
- package/bin/runners/lib/reality-profiler.js +0 -717
- package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
- package/bin/runners/lib/review/ai-code-review.js +0 -832
- package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
- package/bin/runners/lib/sbom-generator.js +0 -641
- package/bin/runners/lib/scan-output-enhanced.js +0 -512
- package/bin/runners/lib/security/owasp-scanner.js +0 -939
- package/bin/runners/lib/validators/contract-validator.js +0 -283
- package/bin/runners/lib/validators/dead-export-detector.js +0 -279
- package/bin/runners/lib/validators/dep-audit.js +0 -245
- package/bin/runners/lib/validators/env-validator.js +0 -319
- package/bin/runners/lib/validators/index.js +0 -120
- package/bin/runners/lib/validators/license-checker.js +0 -252
- package/bin/runners/lib/validators/route-validator.js +0 -290
- package/bin/runners/runAuthority.js +0 -528
- package/bin/runners/runConductor.js +0 -772
- package/bin/runners/runContainer.js +0 -366
- package/bin/runners/runEasy.js +0 -410
- package/bin/runners/runIaC.js +0 -372
- package/bin/runners/runVibe.js +0 -791
- package/mcp-server/tools.js +0 -495
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vibecheck evidence-pack - Bundle Proof Artifacts
|
|
3
|
+
*
|
|
4
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
* Creates shareable evidence packs from vibecheck proof runs.
|
|
6
|
+
* Bundles videos, traces, screenshots, and findings into a single artifact.
|
|
7
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
const fs = require("fs");
|
|
13
|
+
const path = require("path");
|
|
14
|
+
|
|
15
|
+
// Colors
|
|
16
|
+
const c = {
|
|
17
|
+
reset: '\x1b[0m',
|
|
18
|
+
bold: '\x1b[1m',
|
|
19
|
+
dim: '\x1b[2m',
|
|
20
|
+
green: '\x1b[32m',
|
|
21
|
+
yellow: '\x1b[33m',
|
|
22
|
+
cyan: '\x1b[36m',
|
|
23
|
+
red: '\x1b[31m',
|
|
24
|
+
magenta: '\x1b[35m',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const rgb = (r, g, b) => `\x1b[38;2;${r};${g};${b}m`;
|
|
28
|
+
|
|
29
|
+
const colors = {
|
|
30
|
+
accent: rgb(0, 212, 255),
|
|
31
|
+
success: rgb(16, 185, 129),
|
|
32
|
+
warning: rgb(245, 158, 11),
|
|
33
|
+
error: rgb(239, 68, 68),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const ICONS = {
|
|
37
|
+
pack: '📦',
|
|
38
|
+
check: '✓',
|
|
39
|
+
cross: '✗',
|
|
40
|
+
video: '🎥',
|
|
41
|
+
trace: '📊',
|
|
42
|
+
screenshot: '📸',
|
|
43
|
+
file: '📄',
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
function printHelp(opts = {}) {
|
|
47
|
+
console.log(`
|
|
48
|
+
${c.bold}vibecheck evidence-pack${c.reset} - Bundle Proof Artifacts
|
|
49
|
+
|
|
50
|
+
${c.bold}Usage:${c.reset} vibecheck evidence-pack [options]
|
|
51
|
+
|
|
52
|
+
${c.bold}What It Bundles:${c.reset}
|
|
53
|
+
${ICONS.video} ${c.dim}Videos${c.reset} Browser session recordings
|
|
54
|
+
${ICONS.trace} ${c.dim}Traces${c.reset} Playwright traces (view at trace.playwright.dev)
|
|
55
|
+
${ICONS.screenshot} ${c.dim}Screenshots${c.reset} Finding screenshots
|
|
56
|
+
${ICONS.file} ${c.dim}Reports${c.reset} JSON reports with evidence
|
|
57
|
+
|
|
58
|
+
${c.bold}Options:${c.reset}
|
|
59
|
+
${colors.accent}--output, -o <path>${c.reset} Output directory ${c.dim}(default: .vibecheck/evidence-packs/)${c.reset}
|
|
60
|
+
${colors.accent}--run-id <id>${c.reset} Bundle specific run by ID
|
|
61
|
+
${colors.accent}--latest${c.reset} Bundle the most recent run ${c.dim}(default)${c.reset}
|
|
62
|
+
${colors.accent}--no-videos${c.reset} Exclude video recordings
|
|
63
|
+
${colors.accent}--no-traces${c.reset} Exclude Playwright traces
|
|
64
|
+
${colors.accent}--no-screenshots${c.reset} Exclude screenshots
|
|
65
|
+
${colors.accent}--markdown${c.reset} Generate markdown report
|
|
66
|
+
${colors.accent}--json${c.reset} Output JSON manifest only
|
|
67
|
+
${colors.accent}--help, -h${c.reset} Show this help
|
|
68
|
+
|
|
69
|
+
${c.bold}Examples:${c.reset}
|
|
70
|
+
${c.dim}# Create evidence pack from latest run${c.reset}
|
|
71
|
+
vibecheck evidence-pack
|
|
72
|
+
|
|
73
|
+
${c.dim}# Custom output path${c.reset}
|
|
74
|
+
vibecheck evidence-pack --output ./artifacts/proof
|
|
75
|
+
|
|
76
|
+
${c.dim}# Bundle specific run${c.reset}
|
|
77
|
+
vibecheck evidence-pack --run-id abc123
|
|
78
|
+
|
|
79
|
+
${c.dim}# Generate markdown report${c.reset}
|
|
80
|
+
vibecheck evidence-pack --markdown > evidence-report.md
|
|
81
|
+
|
|
82
|
+
${c.dim}# Exclude large files${c.reset}
|
|
83
|
+
vibecheck evidence-pack --no-videos --no-traces
|
|
84
|
+
`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function runEvidencePack(args = [], context = {}) {
|
|
88
|
+
// Parse arguments
|
|
89
|
+
const getArg = (flags) => {
|
|
90
|
+
for (const f of flags) {
|
|
91
|
+
const idx = args.indexOf(f);
|
|
92
|
+
if (idx !== -1 && idx < args.length - 1) return args[idx + 1];
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const hasFlag = (flags) => flags.some(f => args.includes(f));
|
|
98
|
+
|
|
99
|
+
if (hasFlag(["--help", "-h"])) {
|
|
100
|
+
printHelp();
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const options = {
|
|
105
|
+
repoRoot: context.repoRoot || process.cwd(),
|
|
106
|
+
output: getArg(["--output", "-o"]),
|
|
107
|
+
runId: getArg(["--run-id"]),
|
|
108
|
+
latest: hasFlag(["--latest"]) || !getArg(["--run-id"]),
|
|
109
|
+
includeVideos: !hasFlag(["--no-videos"]),
|
|
110
|
+
includeTraces: !hasFlag(["--no-traces"]),
|
|
111
|
+
includeScreenshots: !hasFlag(["--no-screenshots"]),
|
|
112
|
+
markdown: hasFlag(["--markdown"]),
|
|
113
|
+
json: hasFlag(["--json"]),
|
|
114
|
+
quiet: hasFlag(["--quiet", "-q"]),
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const root = options.repoRoot;
|
|
118
|
+
const vibecheckDir = path.join(root, ".vibecheck");
|
|
119
|
+
const runsDir = path.join(vibecheckDir, "runs");
|
|
120
|
+
|
|
121
|
+
if (!options.quiet && !options.json && !options.markdown) {
|
|
122
|
+
console.log(`\n ${ICONS.pack} ${c.bold}Building Evidence Pack${c.reset}\n`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
// Find the run to bundle
|
|
127
|
+
let runId = options.runId;
|
|
128
|
+
|
|
129
|
+
if (options.latest || !runId) {
|
|
130
|
+
// Find the most recent run
|
|
131
|
+
if (!fs.existsSync(runsDir)) {
|
|
132
|
+
throw new Error("No runs found. Run 'vibecheck prove' first.");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const runs = fs.readdirSync(runsDir)
|
|
136
|
+
.filter(d => fs.statSync(path.join(runsDir, d)).isDirectory())
|
|
137
|
+
.map(d => {
|
|
138
|
+
const manifestPath = path.join(runsDir, d, "manifest.json");
|
|
139
|
+
if (fs.existsSync(manifestPath)) {
|
|
140
|
+
try {
|
|
141
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
142
|
+
return { id: d, timestamp: manifest.timestamp || 0 };
|
|
143
|
+
} catch {
|
|
144
|
+
return { id: d, timestamp: 0 };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return { id: d, timestamp: 0 };
|
|
148
|
+
})
|
|
149
|
+
.sort((a, b) => b.timestamp - a.timestamp);
|
|
150
|
+
|
|
151
|
+
if (runs.length === 0) {
|
|
152
|
+
throw new Error("No runs found. Run 'vibecheck prove' first.");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
runId = runs[0].id;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const runDir = path.join(runsDir, runId);
|
|
159
|
+
if (!fs.existsSync(runDir)) {
|
|
160
|
+
throw new Error(`Run not found: ${runId}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Build the evidence pack
|
|
164
|
+
const pack = await buildEvidencePack(runDir, runId, options);
|
|
165
|
+
|
|
166
|
+
// Output based on format
|
|
167
|
+
if (options.markdown) {
|
|
168
|
+
console.log(generateMarkdownReport(pack));
|
|
169
|
+
return pack.summary.verdict === 'SHIP' ? 0 : pack.summary.verdict === 'WARN' ? 1 : 2;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (options.json) {
|
|
173
|
+
console.log(JSON.stringify(pack.manifest, null, 2));
|
|
174
|
+
return pack.summary.verdict === 'SHIP' ? 0 : pack.summary.verdict === 'WARN' ? 1 : 2;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Print summary
|
|
178
|
+
const { summary, manifest } = pack;
|
|
179
|
+
const verdictColor = summary.verdict === 'SHIP' ? colors.success :
|
|
180
|
+
summary.verdict === 'WARN' ? colors.warning : colors.error;
|
|
181
|
+
|
|
182
|
+
console.log(` ${c.dim}Pack ID:${c.reset} ${pack.id}`);
|
|
183
|
+
console.log(` ${c.dim}Run ID:${c.reset} ${runId}`);
|
|
184
|
+
console.log(` ${c.dim}Verdict:${c.reset} ${verdictColor}${c.bold}${summary.verdict}${c.reset}`);
|
|
185
|
+
console.log(` ${c.dim}Score:${c.reset} ${summary.score}/100`);
|
|
186
|
+
console.log(` ${c.dim}Findings:${c.reset} ${summary.totalFindings}`);
|
|
187
|
+
console.log();
|
|
188
|
+
|
|
189
|
+
// Artifact summary
|
|
190
|
+
const artifacts = manifest.artifacts;
|
|
191
|
+
if (artifacts.screenshots && artifacts.screenshots.length > 0) {
|
|
192
|
+
console.log(` ${ICONS.screenshot} Screenshots: ${artifacts.screenshots.length}`);
|
|
193
|
+
}
|
|
194
|
+
if (artifacts.videos && artifacts.videos.length > 0) {
|
|
195
|
+
console.log(` ${ICONS.video} Videos: ${artifacts.videos.length}`);
|
|
196
|
+
}
|
|
197
|
+
if (artifacts.traces && artifacts.traces.length > 0) {
|
|
198
|
+
console.log(` ${ICONS.trace} Traces: ${artifacts.traces.length}`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
console.log();
|
|
202
|
+
console.log(` ${colors.success}${ICONS.check}${c.reset} Output: ${path.relative(root, pack.outputDir)}`);
|
|
203
|
+
console.log();
|
|
204
|
+
|
|
205
|
+
// Tips
|
|
206
|
+
if (artifacts.traces && artifacts.traces.length > 0) {
|
|
207
|
+
console.log(` ${c.dim}View traces at: ${c.cyan}https://trace.playwright.dev${c.reset}`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return summary.verdict === 'SHIP' ? 0 : summary.verdict === 'WARN' ? 1 : 2;
|
|
211
|
+
|
|
212
|
+
} catch (error) {
|
|
213
|
+
if (options.json) {
|
|
214
|
+
console.log(JSON.stringify({ error: error.message }, null, 2));
|
|
215
|
+
} else {
|
|
216
|
+
console.error(`\n ${colors.error}${ICONS.cross}${c.reset} ${error.message}\n`);
|
|
217
|
+
}
|
|
218
|
+
return 1;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function buildEvidencePack(runDir, runId, options) {
|
|
223
|
+
const packId = `pack_${Date.now().toString(36)}`;
|
|
224
|
+
const outputDir = options.output || path.join(path.dirname(path.dirname(runDir)), "evidence-packs", packId);
|
|
225
|
+
|
|
226
|
+
// Create output directory
|
|
227
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
228
|
+
|
|
229
|
+
// Read run manifest
|
|
230
|
+
const manifestPath = path.join(runDir, "manifest.json");
|
|
231
|
+
let runManifest = {};
|
|
232
|
+
if (fs.existsSync(manifestPath)) {
|
|
233
|
+
runManifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Read summary
|
|
237
|
+
const summaryPath = path.join(runDir, "artifacts", "summary.json");
|
|
238
|
+
let summary = { verdict: 'UNKNOWN', score: 0, totalFindings: 0 };
|
|
239
|
+
if (fs.existsSync(summaryPath)) {
|
|
240
|
+
summary = JSON.parse(fs.readFileSync(summaryPath, "utf-8"));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Collect artifacts
|
|
244
|
+
const artifacts = {
|
|
245
|
+
screenshots: [],
|
|
246
|
+
videos: [],
|
|
247
|
+
traces: [],
|
|
248
|
+
reports: [],
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const artifactsDir = path.join(runDir, "artifacts");
|
|
252
|
+
if (fs.existsSync(artifactsDir)) {
|
|
253
|
+
const files = fs.readdirSync(artifactsDir);
|
|
254
|
+
|
|
255
|
+
for (const file of files) {
|
|
256
|
+
const filePath = path.join(artifactsDir, file);
|
|
257
|
+
const stat = fs.statSync(filePath);
|
|
258
|
+
|
|
259
|
+
if (stat.isFile()) {
|
|
260
|
+
const ext = path.extname(file).toLowerCase();
|
|
261
|
+
const destPath = path.join(outputDir, file);
|
|
262
|
+
|
|
263
|
+
if (['.png', '.jpg', '.jpeg'].includes(ext) && options.includeScreenshots) {
|
|
264
|
+
fs.copyFileSync(filePath, destPath);
|
|
265
|
+
artifacts.screenshots.push({ name: file, size: stat.size });
|
|
266
|
+
} else if (['.webm', '.mp4'].includes(ext) && options.includeVideos) {
|
|
267
|
+
fs.copyFileSync(filePath, destPath);
|
|
268
|
+
artifacts.videos.push({ name: file, size: stat.size });
|
|
269
|
+
} else if (ext === '.zip' && file.includes('trace') && options.includeTraces) {
|
|
270
|
+
fs.copyFileSync(filePath, destPath);
|
|
271
|
+
artifacts.traces.push({ name: file, size: stat.size });
|
|
272
|
+
} else if (ext === '.json') {
|
|
273
|
+
fs.copyFileSync(filePath, destPath);
|
|
274
|
+
artifacts.reports.push({ name: file, size: stat.size });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Create pack manifest
|
|
281
|
+
const packManifest = {
|
|
282
|
+
id: packId,
|
|
283
|
+
runId,
|
|
284
|
+
createdAt: new Date().toISOString(),
|
|
285
|
+
summary,
|
|
286
|
+
artifacts,
|
|
287
|
+
source: runManifest,
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const packManifestPath = path.join(outputDir, "manifest.json");
|
|
291
|
+
fs.writeFileSync(packManifestPath, JSON.stringify(packManifest, null, 2));
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
id: packId,
|
|
295
|
+
runId,
|
|
296
|
+
outputDir,
|
|
297
|
+
manifestPath: packManifestPath,
|
|
298
|
+
manifest: packManifest,
|
|
299
|
+
summary,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function generateMarkdownReport(pack) {
|
|
304
|
+
const { manifest, summary } = pack;
|
|
305
|
+
const verdictEmoji = summary.verdict === 'SHIP' ? '✅' : summary.verdict === 'WARN' ? '⚠️' : '🚫';
|
|
306
|
+
|
|
307
|
+
let md = `# Evidence Pack Report
|
|
308
|
+
|
|
309
|
+
## Summary
|
|
310
|
+
|
|
311
|
+
| Metric | Value |
|
|
312
|
+
|--------|-------|
|
|
313
|
+
| Pack ID | \`${pack.id}\` |
|
|
314
|
+
| Run ID | \`${pack.runId}\` |
|
|
315
|
+
| Verdict | ${verdictEmoji} **${summary.verdict}** |
|
|
316
|
+
| Score | ${summary.score}/100 |
|
|
317
|
+
| Findings | ${summary.totalFindings} |
|
|
318
|
+
| Created | ${manifest.createdAt} |
|
|
319
|
+
|
|
320
|
+
## Artifacts
|
|
321
|
+
|
|
322
|
+
`;
|
|
323
|
+
|
|
324
|
+
if (manifest.artifacts.screenshots.length > 0) {
|
|
325
|
+
md += `### Screenshots (${manifest.artifacts.screenshots.length})\n\n`;
|
|
326
|
+
for (const s of manifest.artifacts.screenshots) {
|
|
327
|
+
md += `- \`${s.name}\` (${formatBytes(s.size)})\n`;
|
|
328
|
+
}
|
|
329
|
+
md += '\n';
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (manifest.artifacts.videos.length > 0) {
|
|
333
|
+
md += `### Videos (${manifest.artifacts.videos.length})\n\n`;
|
|
334
|
+
for (const v of manifest.artifacts.videos) {
|
|
335
|
+
md += `- \`${v.name}\` (${formatBytes(v.size)})\n`;
|
|
336
|
+
}
|
|
337
|
+
md += '\n';
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (manifest.artifacts.traces.length > 0) {
|
|
341
|
+
md += `### Traces (${manifest.artifacts.traces.length})\n\n`;
|
|
342
|
+
md += `View traces at [trace.playwright.dev](https://trace.playwright.dev)\n\n`;
|
|
343
|
+
for (const t of manifest.artifacts.traces) {
|
|
344
|
+
md += `- \`${t.name}\` (${formatBytes(t.size)})\n`;
|
|
345
|
+
}
|
|
346
|
+
md += '\n';
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
md += `---\n\n*Generated by vibecheck evidence-pack*\n`;
|
|
350
|
+
|
|
351
|
+
return md;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function formatBytes(bytes) {
|
|
355
|
+
if (bytes === 0) return '0 B';
|
|
356
|
+
const k = 1024;
|
|
357
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
358
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
359
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
module.exports = { runEvidencePack };
|
|
@@ -13,9 +13,6 @@ const { loadPolicy, savePolicy, getDefaultPolicy } = require("./lib/agent-firewa
|
|
|
13
13
|
const { getPacketStats, queryPackets } = require("./lib/agent-firewall/change-packet/store");
|
|
14
14
|
const { isTruthpackFresh } = require("./lib/agent-firewall/truthpack/loader");
|
|
15
15
|
|
|
16
|
-
// Unified Output System
|
|
17
|
-
const { output } = require("./lib/output/index.js");
|
|
18
|
-
|
|
19
16
|
/**
|
|
20
17
|
* Run firewall command
|
|
21
18
|
* @param {object} options - Command options
|
|
@@ -10,9 +10,6 @@ const { installFileSystemHook, startFileSystemHook, stopFileSystemHook } = requi
|
|
|
10
10
|
const fs = require("fs");
|
|
11
11
|
const path = require("path");
|
|
12
12
|
|
|
13
|
-
// Unified Output System
|
|
14
|
-
const { output } = require("./lib/output/index.js");
|
|
15
|
-
|
|
16
13
|
/**
|
|
17
14
|
* Run firewall hook command
|
|
18
15
|
* @param {object} options - Command options
|
package/bin/runners/runFix.js
CHANGED
|
@@ -26,7 +26,7 @@ const { shipCore } = require('./runShip');
|
|
|
26
26
|
const { planMissions } = require('./lib/missions/plan');
|
|
27
27
|
const { templateForMissionType } = require('./lib/missions/templates');
|
|
28
28
|
const { expandEvidence } = require('./lib/missions/evidence');
|
|
29
|
-
const {
|
|
29
|
+
const { buildRealityFirewall } = require('./lib/firewall-prompt');
|
|
30
30
|
const { generatePatchJson } = require('./lib/llm');
|
|
31
31
|
const { applyUnifiedDiff } = require('./lib/patch');
|
|
32
32
|
const { backupFiles, restoreBackup } = require('./lib/backup');
|
|
@@ -40,15 +40,68 @@ const entitlements = require('./lib/entitlements-v2');
|
|
|
40
40
|
const upsell = require('./lib/upsell');
|
|
41
41
|
|
|
42
42
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
43
|
-
// TERMINAL
|
|
43
|
+
// ADVANCED TERMINAL - ANSI CODES & UTILITIES
|
|
44
44
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
45
45
|
|
|
46
|
-
const
|
|
46
|
+
const c = {
|
|
47
|
+
reset: '\x1b[0m',
|
|
48
|
+
bold: '\x1b[1m',
|
|
49
|
+
dim: '\x1b[2m',
|
|
50
|
+
italic: '\x1b[3m',
|
|
51
|
+
underline: '\x1b[4m',
|
|
52
|
+
blink: '\x1b[5m',
|
|
53
|
+
inverse: '\x1b[7m',
|
|
54
|
+
hidden: '\x1b[8m',
|
|
55
|
+
strike: '\x1b[9m',
|
|
56
|
+
// Colors
|
|
57
|
+
black: '\x1b[30m',
|
|
58
|
+
red: '\x1b[31m',
|
|
59
|
+
green: '\x1b[32m',
|
|
60
|
+
yellow: '\x1b[33m',
|
|
61
|
+
blue: '\x1b[34m',
|
|
62
|
+
magenta: '\x1b[35m',
|
|
63
|
+
cyan: '\x1b[36m',
|
|
64
|
+
white: '\x1b[37m',
|
|
65
|
+
// Bright colors
|
|
66
|
+
gray: '\x1b[90m',
|
|
67
|
+
brightRed: '\x1b[91m',
|
|
68
|
+
brightGreen: '\x1b[92m',
|
|
69
|
+
brightYellow: '\x1b[93m',
|
|
70
|
+
brightBlue: '\x1b[94m',
|
|
71
|
+
brightMagenta: '\x1b[95m',
|
|
72
|
+
brightCyan: '\x1b[96m',
|
|
73
|
+
brightWhite: '\x1b[97m',
|
|
74
|
+
// Background
|
|
75
|
+
bgBlack: '\x1b[40m',
|
|
76
|
+
bgRed: '\x1b[41m',
|
|
77
|
+
bgGreen: '\x1b[42m',
|
|
78
|
+
bgYellow: '\x1b[43m',
|
|
79
|
+
bgBlue: '\x1b[44m',
|
|
80
|
+
bgMagenta: '\x1b[45m',
|
|
81
|
+
bgCyan: '\x1b[46m',
|
|
82
|
+
bgWhite: '\x1b[47m',
|
|
83
|
+
bgBrightBlack: '\x1b[100m',
|
|
84
|
+
bgBrightRed: '\x1b[101m',
|
|
85
|
+
bgBrightGreen: '\x1b[102m',
|
|
86
|
+
bgBrightYellow: '\x1b[103m',
|
|
87
|
+
// Cursor control
|
|
88
|
+
cursorUp: (n = 1) => `\x1b[${n}A`,
|
|
89
|
+
cursorDown: (n = 1) => `\x1b[${n}B`,
|
|
90
|
+
cursorRight: (n = 1) => `\x1b[${n}C`,
|
|
91
|
+
cursorLeft: (n = 1) => `\x1b[${n}D`,
|
|
92
|
+
clearLine: '\x1b[2K',
|
|
93
|
+
clearScreen: '\x1b[2J',
|
|
94
|
+
saveCursor: '\x1b[s',
|
|
95
|
+
restoreCursor: '\x1b[u',
|
|
96
|
+
hideCursor: '\x1b[?25l',
|
|
97
|
+
showCursor: '\x1b[?25h',
|
|
98
|
+
};
|
|
47
99
|
|
|
48
|
-
//
|
|
49
|
-
const
|
|
100
|
+
// 256-color / True color support
|
|
101
|
+
const rgb = (r, g, b) => `\x1b[38;2;${r};${g};${b}m`;
|
|
102
|
+
const bgRgb = (r, g, b) => `\x1b[48;2;${r};${g};${b}m`;
|
|
50
103
|
|
|
51
|
-
//
|
|
104
|
+
// Premium color palette
|
|
52
105
|
const colors = {
|
|
53
106
|
// Gradients for banner
|
|
54
107
|
gradient1: rgb(255, 150, 50), // Orange
|
|
@@ -278,7 +331,7 @@ function getMissionIcon(missionType) {
|
|
|
278
331
|
'FIX_FAKE_SUCCESS': ICONS.ghost,
|
|
279
332
|
'FIX_ENV_CONTRACT': ICONS.env,
|
|
280
333
|
'FIX_DEAD_UI': ICONS.dead,
|
|
281
|
-
//
|
|
334
|
+
// New enhanced mission types
|
|
282
335
|
'FIX_EMPTY_CATCH': ICONS.bug,
|
|
283
336
|
'FIX_TEST_KEYS': ICONS.key,
|
|
284
337
|
'FIX_MOCK_DOMAINS': ICONS.link,
|
|
@@ -289,19 +342,6 @@ function getMissionIcon(missionType) {
|
|
|
289
342
|
'SYNC_CONTRACTS': ICONS.graph,
|
|
290
343
|
'FIX_ROUTE_DRIFT': ICONS.route,
|
|
291
344
|
'FIX_AUTH_DRIFT': ICONS.shield,
|
|
292
|
-
// V5: New pattern-based mission types
|
|
293
|
-
'FIX_REACT_PATTERN': '⚛️',
|
|
294
|
-
'FIX_DATABASE_PATTERN': '🗄️',
|
|
295
|
-
'FIX_ASYNC_PATTERN': '⏳',
|
|
296
|
-
'FIX_ERROR_HANDLING': ICONS.bug,
|
|
297
|
-
'FIX_SECURITY_VULN': ICONS.shield,
|
|
298
|
-
'FIX_PERFORMANCE': ICONS.lightning,
|
|
299
|
-
'FIX_BUNDLE_SIZE': ICONS.package,
|
|
300
|
-
'FIX_API_CONSISTENCY': '📡',
|
|
301
|
-
'FIX_ENV_VALIDATION': ICONS.env,
|
|
302
|
-
'FIX_ENV_SETUP': ICONS.env,
|
|
303
|
-
'FIX_ACCESSIBILITY': '♿',
|
|
304
|
-
'FIX_CODE_QUALITY': ICONS.gear,
|
|
305
345
|
};
|
|
306
346
|
return icons[missionType] || ICONS.mission;
|
|
307
347
|
}
|
|
@@ -316,7 +356,7 @@ function getMissionColor(missionType) {
|
|
|
316
356
|
'FIX_FAKE_SUCCESS': colors.medium,
|
|
317
357
|
'FIX_ENV_CONTRACT': colors.low,
|
|
318
358
|
'FIX_DEAD_UI': colors.low,
|
|
319
|
-
//
|
|
359
|
+
// New enhanced mission types
|
|
320
360
|
'FIX_EMPTY_CATCH': colors.high,
|
|
321
361
|
'FIX_TEST_KEYS': colors.critical,
|
|
322
362
|
'FIX_MOCK_DOMAINS': colors.critical,
|
|
@@ -327,19 +367,6 @@ function getMissionColor(missionType) {
|
|
|
327
367
|
'SYNC_CONTRACTS': colors.medium,
|
|
328
368
|
'FIX_ROUTE_DRIFT': colors.medium,
|
|
329
369
|
'FIX_AUTH_DRIFT': colors.critical,
|
|
330
|
-
// V5: New pattern-based mission types
|
|
331
|
-
'FIX_REACT_PATTERN': colors.high, // React issues can cause hard bugs
|
|
332
|
-
'FIX_DATABASE_PATTERN': colors.high, // N+1 and SQL injection are serious
|
|
333
|
-
'FIX_ASYNC_PATTERN': colors.medium, // Async issues cause intermittent bugs
|
|
334
|
-
'FIX_ERROR_HANDLING': colors.medium, // Important but not critical
|
|
335
|
-
'FIX_SECURITY_VULN': colors.critical, // Security is always critical
|
|
336
|
-
'FIX_PERFORMANCE': colors.low, // Performance can wait
|
|
337
|
-
'FIX_BUNDLE_SIZE': colors.low, // Bundle size can wait
|
|
338
|
-
'FIX_API_CONSISTENCY': colors.medium, // API design matters
|
|
339
|
-
'FIX_ENV_VALIDATION': colors.medium, // Prevents runtime crashes
|
|
340
|
-
'FIX_ENV_SETUP': colors.low, // Developer experience
|
|
341
|
-
'FIX_ACCESSIBILITY': colors.medium, // Important for inclusivity
|
|
342
|
-
'FIX_CODE_QUALITY': colors.low, // Can be fixed over time
|
|
343
370
|
};
|
|
344
371
|
return colorMap[missionType] || colors.accent;
|
|
345
372
|
}
|
|
@@ -473,13 +500,6 @@ async function runFix(args) {
|
|
|
473
500
|
const opts = parseArgs(args);
|
|
474
501
|
const startTime = Date.now();
|
|
475
502
|
|
|
476
|
-
// Configure unified output mode
|
|
477
|
-
output.setMode({
|
|
478
|
-
json: opts.json,
|
|
479
|
-
quiet: opts.quiet,
|
|
480
|
-
ci: opts.ci
|
|
481
|
-
});
|
|
482
|
-
|
|
483
503
|
if (opts.help) {
|
|
484
504
|
printHelp();
|
|
485
505
|
return 0;
|
|
@@ -648,24 +668,14 @@ async function runFix(args) {
|
|
|
648
668
|
const allowedFiles = expanded.allowedFiles;
|
|
649
669
|
const snippets = expanded.snippets;
|
|
650
670
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
const promptResult = promptBuilder.buildFixPrompt({
|
|
671
|
+
const prompt = buildRealityFirewall({
|
|
672
|
+
truthpackSummary: truthpackSummary(before.truthpack),
|
|
654
673
|
mission,
|
|
674
|
+
template,
|
|
655
675
|
findings: targetFindings,
|
|
656
|
-
truthpackSummary: truthpackSummary(before.truthpack),
|
|
657
676
|
fileSnippets: snippets,
|
|
658
|
-
allowedFiles
|
|
677
|
+
allowedFiles
|
|
659
678
|
});
|
|
660
|
-
|
|
661
|
-
const prompt = promptResult.prompt;
|
|
662
|
-
|
|
663
|
-
// Show enforcement warnings if any
|
|
664
|
-
if (promptResult.warnings && promptResult.warnings.length > 0) {
|
|
665
|
-
for (const warning of promptResult.warnings) {
|
|
666
|
-
console.log(` ${colors.warnAmber}${ICONS.warning}${c.reset} ${c.dim}${warning}${c.reset}`);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
679
|
|
|
670
680
|
const promptPath = path.join(outDir, `step_${String(step).padStart(2,"0")}_${mission.id}_prompt.txt`);
|
|
671
681
|
fs.writeFileSync(promptPath, prompt, "utf8");
|
|
@@ -693,27 +703,7 @@ async function runFix(args) {
|
|
|
693
703
|
const respPath = path.join(outDir, `step_${String(step).padStart(2,"0")}_${mission.id}_response.json`);
|
|
694
704
|
fs.writeFileSync(respPath, JSON.stringify(patchJson, null, 2), "utf8");
|
|
695
705
|
|
|
696
|
-
// Validate
|
|
697
|
-
const responseValidation = promptBuilder.validateResponse(patchJson, 'fix');
|
|
698
|
-
if (!responseValidation.valid) {
|
|
699
|
-
console.log(` ${colors.blockRed}${ICONS.cross}${c.reset} Invalid LLM response structure:`);
|
|
700
|
-
for (const err of responseValidation.errors) {
|
|
701
|
-
console.log(` ${c.dim}${ICONS.bullet}${c.reset} ${err}`);
|
|
702
|
-
}
|
|
703
|
-
return EXIT.INTERNAL_ERROR;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
// Validate edits against allowed files
|
|
707
|
-
const editsValidation = promptBuilder.validateEditsAgainstAllowedFiles(patchJson.edits, allowedFiles);
|
|
708
|
-
if (!editsValidation.valid) {
|
|
709
|
-
console.log(` ${colors.blockRed}${ICONS.cross}${c.reset} LLM tried to edit files outside allowed list:`);
|
|
710
|
-
for (const v of editsValidation.violations) {
|
|
711
|
-
console.log(` ${c.dim}${ICONS.bullet}${c.reset} ${v.path}: ${v.message}`);
|
|
712
|
-
}
|
|
713
|
-
return EXIT.BLOCKING;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
// Validate patch (existing validator)
|
|
706
|
+
// Validate patch
|
|
717
707
|
const v = validatePatchResponse({
|
|
718
708
|
repoRoot: root,
|
|
719
709
|
patchJson,
|