@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.
Files changed (224) hide show
  1. package/bin/registry.js +214 -237
  2. package/bin/runners/cli-utils.js +33 -2
  3. package/bin/runners/context/analyzer.js +52 -1
  4. package/bin/runners/context/generators/cursor.js +2 -49
  5. package/bin/runners/context/git-context.js +3 -1
  6. package/bin/runners/context/team-conventions.js +33 -7
  7. package/bin/runners/lib/analysis-core.js +25 -5
  8. package/bin/runners/lib/analyzers.js +431 -481
  9. package/bin/runners/lib/default-config.js +127 -0
  10. package/bin/runners/lib/doctor/modules/security.js +3 -1
  11. package/bin/runners/lib/engine/ast-cache.js +210 -0
  12. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  13. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  14. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  15. package/bin/runners/lib/engine/env-extractor.js +207 -0
  16. package/bin/runners/lib/engine/express-extractor.js +208 -0
  17. package/bin/runners/lib/engine/extractors.js +849 -0
  18. package/bin/runners/lib/engine/index.js +207 -0
  19. package/bin/runners/lib/engine/repo-index.js +514 -0
  20. package/bin/runners/lib/engine/types.js +124 -0
  21. package/bin/runners/lib/engines/accessibility-engine.js +18 -218
  22. package/bin/runners/lib/engines/api-consistency-engine.js +30 -335
  23. package/bin/runners/lib/engines/cross-file-analysis-engine.js +27 -292
  24. package/bin/runners/lib/engines/empty-catch-engine.js +17 -127
  25. package/bin/runners/lib/engines/mock-data-engine.js +10 -53
  26. package/bin/runners/lib/engines/performance-issues-engine.js +36 -176
  27. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +54 -382
  28. package/bin/runners/lib/engines/type-aware-engine.js +39 -263
  29. package/bin/runners/lib/engines/vibecheck-engines/index.js +13 -122
  30. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  31. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  32. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  33. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  34. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  35. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  36. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  37. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +73 -373
  38. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  39. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  40. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  41. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  42. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  43. package/bin/runners/lib/entitlements-v2.js +73 -97
  44. package/bin/runners/lib/error-handler.js +44 -3
  45. package/bin/runners/lib/error-messages.js +289 -0
  46. package/bin/runners/lib/evidence-pack.js +7 -1
  47. package/bin/runners/lib/finding-id.js +69 -0
  48. package/bin/runners/lib/finding-sorter.js +89 -0
  49. package/bin/runners/lib/html-proof-report.js +700 -350
  50. package/bin/runners/lib/missions/plan.js +6 -46
  51. package/bin/runners/lib/missions/templates.js +0 -232
  52. package/bin/runners/lib/next-action.js +560 -0
  53. package/bin/runners/lib/prerequisites.js +149 -0
  54. package/bin/runners/lib/route-detection.js +137 -68
  55. package/bin/runners/lib/scan-output.js +91 -76
  56. package/bin/runners/lib/scan-runner.js +135 -0
  57. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  58. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  59. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  60. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  61. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  62. package/bin/runners/lib/schemas/validator.js +27 -0
  63. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  64. package/bin/runners/lib/ship-output-enterprise.js +23 -23
  65. package/bin/runners/lib/ship-output.js +75 -31
  66. package/bin/runners/lib/terminal-ui.js +6 -113
  67. package/bin/runners/lib/truth.js +351 -10
  68. package/bin/runners/lib/unified-cli-output.js +430 -603
  69. package/bin/runners/lib/unified-output.js +13 -9
  70. package/bin/runners/runAIAgent.js +10 -5
  71. package/bin/runners/runAgent.js +0 -3
  72. package/bin/runners/runAllowlist.js +389 -0
  73. package/bin/runners/runApprove.js +0 -33
  74. package/bin/runners/runAuth.js +73 -45
  75. package/bin/runners/runCheckpoint.js +51 -11
  76. package/bin/runners/runClassify.js +85 -21
  77. package/bin/runners/runContext.js +0 -3
  78. package/bin/runners/runDoctor.js +41 -28
  79. package/bin/runners/runEvidencePack.js +362 -0
  80. package/bin/runners/runFirewall.js +0 -3
  81. package/bin/runners/runFirewallHook.js +0 -3
  82. package/bin/runners/runFix.js +66 -76
  83. package/bin/runners/runGuard.js +18 -411
  84. package/bin/runners/runInit.js +113 -30
  85. package/bin/runners/runLabs.js +424 -0
  86. package/bin/runners/runMcp.js +19 -25
  87. package/bin/runners/runPolish.js +64 -240
  88. package/bin/runners/runPromptFirewall.js +12 -5
  89. package/bin/runners/runProve.js +57 -22
  90. package/bin/runners/runQuickstart.js +531 -0
  91. package/bin/runners/runReality.js +59 -68
  92. package/bin/runners/runReport.js +38 -33
  93. package/bin/runners/runRuntime.js +8 -5
  94. package/bin/runners/runScan.js +1413 -190
  95. package/bin/runners/runShip.js +113 -719
  96. package/bin/runners/runTruth.js +0 -3
  97. package/bin/runners/runValidate.js +13 -9
  98. package/bin/runners/runWatch.js +23 -14
  99. package/bin/scan.js +6 -1
  100. package/bin/vibecheck.js +204 -185
  101. package/mcp-server/deprecation-middleware.js +282 -0
  102. package/mcp-server/handlers/index.ts +15 -0
  103. package/mcp-server/handlers/tool-handler.ts +554 -0
  104. package/mcp-server/index-v1.js +698 -0
  105. package/mcp-server/index.js +210 -238
  106. package/mcp-server/lib/cache-wrapper.cjs +383 -0
  107. package/mcp-server/lib/error-envelope.js +138 -0
  108. package/mcp-server/lib/executor.ts +499 -0
  109. package/mcp-server/lib/index.ts +19 -0
  110. package/mcp-server/lib/rate-limiter.js +166 -0
  111. package/mcp-server/lib/sandbox.test.ts +519 -0
  112. package/mcp-server/lib/sandbox.ts +395 -0
  113. package/mcp-server/lib/types.ts +267 -0
  114. package/mcp-server/package.json +12 -3
  115. package/mcp-server/registry/tool-registry.js +794 -0
  116. package/mcp-server/registry/tools.json +605 -0
  117. package/mcp-server/registry.test.ts +334 -0
  118. package/mcp-server/tests/tier-gating.test.js +297 -0
  119. package/mcp-server/tier-auth.js +378 -45
  120. package/mcp-server/tools-v3.js +353 -442
  121. package/mcp-server/tsconfig.json +37 -0
  122. package/mcp-server/vibecheck-2.0-tools.js +14 -1
  123. package/package.json +1 -1
  124. package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
  125. package/bin/runners/lib/audit-logger.js +0 -532
  126. package/bin/runners/lib/authority/authorities/architecture.js +0 -364
  127. package/bin/runners/lib/authority/authorities/compliance.js +0 -341
  128. package/bin/runners/lib/authority/authorities/human.js +0 -343
  129. package/bin/runners/lib/authority/authorities/quality.js +0 -420
  130. package/bin/runners/lib/authority/authorities/security.js +0 -228
  131. package/bin/runners/lib/authority/index.js +0 -293
  132. package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
  133. package/bin/runners/lib/cli-charts.js +0 -368
  134. package/bin/runners/lib/cli-config-display.js +0 -405
  135. package/bin/runners/lib/cli-demo.js +0 -275
  136. package/bin/runners/lib/cli-errors.js +0 -438
  137. package/bin/runners/lib/cli-help-formatter.js +0 -439
  138. package/bin/runners/lib/cli-interactive-menu.js +0 -509
  139. package/bin/runners/lib/cli-prompts.js +0 -441
  140. package/bin/runners/lib/cli-scan-cards.js +0 -362
  141. package/bin/runners/lib/compliance-reporter.js +0 -710
  142. package/bin/runners/lib/conductor/index.js +0 -671
  143. package/bin/runners/lib/easy/README.md +0 -123
  144. package/bin/runners/lib/easy/index.js +0 -140
  145. package/bin/runners/lib/easy/interactive-wizard.js +0 -788
  146. package/bin/runners/lib/easy/one-click-firewall.js +0 -564
  147. package/bin/runners/lib/easy/zero-config-reality.js +0 -714
  148. package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
  149. package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
  150. package/bin/runners/lib/engines/confidence-scoring.js +0 -276
  151. package/bin/runners/lib/engines/context-detection.js +0 -264
  152. package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
  153. package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
  154. package/bin/runners/lib/engines/env-variables-engine.js +0 -458
  155. package/bin/runners/lib/engines/error-handling-engine.js +0 -437
  156. package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
  157. package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
  158. package/bin/runners/lib/engines/framework-detection.js +0 -508
  159. package/bin/runners/lib/engines/import-order-engine.js +0 -429
  160. package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
  161. package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
  162. package/bin/runners/lib/engines/orchestrator.js +0 -334
  163. package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
  164. package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
  165. package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
  166. package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
  167. package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
  168. package/bin/runners/lib/enhanced-features/index.js +0 -305
  169. package/bin/runners/lib/enhanced-output.js +0 -631
  170. package/bin/runners/lib/enterprise.js +0 -300
  171. package/bin/runners/lib/firewall/command-validator.js +0 -351
  172. package/bin/runners/lib/firewall/config.js +0 -341
  173. package/bin/runners/lib/firewall/content-validator.js +0 -519
  174. package/bin/runners/lib/firewall/index.js +0 -101
  175. package/bin/runners/lib/firewall/path-validator.js +0 -256
  176. package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
  177. package/bin/runners/lib/mcp-utils.js +0 -425
  178. package/bin/runners/lib/output/index.js +0 -1022
  179. package/bin/runners/lib/policy-engine.js +0 -652
  180. package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
  181. package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
  182. package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
  183. package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
  184. package/bin/runners/lib/polish/autofix/index.js +0 -200
  185. package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
  186. package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
  187. package/bin/runners/lib/polish/backend-checks.js +0 -148
  188. package/bin/runners/lib/polish/documentation-checks.js +0 -111
  189. package/bin/runners/lib/polish/frontend-checks.js +0 -168
  190. package/bin/runners/lib/polish/index.js +0 -71
  191. package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
  192. package/bin/runners/lib/polish/library-detection.js +0 -175
  193. package/bin/runners/lib/polish/performance-checks.js +0 -100
  194. package/bin/runners/lib/polish/security-checks.js +0 -148
  195. package/bin/runners/lib/polish/utils.js +0 -203
  196. package/bin/runners/lib/prompt-builder.js +0 -540
  197. package/bin/runners/lib/proof-certificate.js +0 -634
  198. package/bin/runners/lib/reality/accessibility-audit.js +0 -946
  199. package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
  200. package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
  201. package/bin/runners/lib/reality/performance-tracker.js +0 -1077
  202. package/bin/runners/lib/reality/scenario-generator.js +0 -1404
  203. package/bin/runners/lib/reality/visual-regression.js +0 -852
  204. package/bin/runners/lib/reality-profiler.js +0 -717
  205. package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
  206. package/bin/runners/lib/review/ai-code-review.js +0 -832
  207. package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
  208. package/bin/runners/lib/sbom-generator.js +0 -641
  209. package/bin/runners/lib/scan-output-enhanced.js +0 -512
  210. package/bin/runners/lib/security/owasp-scanner.js +0 -939
  211. package/bin/runners/lib/validators/contract-validator.js +0 -283
  212. package/bin/runners/lib/validators/dead-export-detector.js +0 -279
  213. package/bin/runners/lib/validators/dep-audit.js +0 -245
  214. package/bin/runners/lib/validators/env-validator.js +0 -319
  215. package/bin/runners/lib/validators/index.js +0 -120
  216. package/bin/runners/lib/validators/license-checker.js +0 -252
  217. package/bin/runners/lib/validators/route-validator.js +0 -290
  218. package/bin/runners/runAuthority.js +0 -528
  219. package/bin/runners/runConductor.js +0 -772
  220. package/bin/runners/runContainer.js +0 -366
  221. package/bin/runners/runEasy.js +0 -410
  222. package/bin/runners/runIaC.js +0 -372
  223. package/bin/runners/runVibe.js +0 -791
  224. 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
@@ -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 { PromptBuilder, buildRealityFirewall } = require('./lib/prompt-builder');
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 UI - Import from shared module
43
+ // ADVANCED TERMINAL - ANSI CODES & UTILITIES
44
44
  // ═══════════════════════════════════════════════════════════════════════════════
45
45
 
46
- const { c, rgb, bgRgb, icons, Spinner } = require('./lib/terminal-ui');
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
- // Unified Output System
49
- const { output } = require("./lib/output/index.js");
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
- // Extended color palette for fix command
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
- // Enhanced mission types
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
- // Enhanced mission types
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
- // Build prompt using consolidated PromptBuilder with enforcement
652
- const promptBuilder = new PromptBuilder(root);
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 LLM response structure
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,