@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.
Files changed (84) hide show
  1. package/bin/registry.js +192 -5
  2. package/bin/runners/lib/agent-firewall/change-packet/builder.js +280 -6
  3. package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
  4. package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
  5. package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
  6. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
  7. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
  8. package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
  9. package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
  10. package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
  11. package/bin/runners/lib/agent-firewall/logger.js +141 -0
  12. package/bin/runners/lib/agent-firewall/policy/loader.js +312 -4
  13. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +113 -1
  14. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +133 -6
  15. package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
  16. package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
  17. package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
  18. package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
  19. package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
  20. package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
  21. package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
  22. package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
  23. package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
  24. package/bin/runners/lib/agent-firewall/risk/thresholds.js +321 -0
  25. package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
  26. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
  27. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
  28. package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
  29. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
  30. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
  31. package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
  32. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
  33. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
  34. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
  35. package/bin/runners/lib/analyzers.js +81 -18
  36. package/bin/runners/lib/authority-badge.js +425 -0
  37. package/bin/runners/lib/cli-output.js +7 -1
  38. package/bin/runners/lib/error-handler.js +16 -9
  39. package/bin/runners/lib/exit-codes.js +275 -0
  40. package/bin/runners/lib/global-flags.js +37 -0
  41. package/bin/runners/lib/help-formatter.js +413 -0
  42. package/bin/runners/lib/logger.js +38 -0
  43. package/bin/runners/lib/unified-cli-output.js +604 -0
  44. package/bin/runners/lib/upsell.js +148 -0
  45. package/bin/runners/runApprove.js +1200 -0
  46. package/bin/runners/runAuth.js +324 -95
  47. package/bin/runners/runCheckpoint.js +39 -21
  48. package/bin/runners/runClassify.js +859 -0
  49. package/bin/runners/runContext.js +136 -24
  50. package/bin/runners/runDoctor.js +108 -68
  51. package/bin/runners/runFix.js +6 -5
  52. package/bin/runners/runGuard.js +212 -118
  53. package/bin/runners/runInit.js +3 -2
  54. package/bin/runners/runMcp.js +130 -52
  55. package/bin/runners/runPolish.js +43 -20
  56. package/bin/runners/runProve.js +1 -2
  57. package/bin/runners/runReport.js +3 -2
  58. package/bin/runners/runScan.js +63 -44
  59. package/bin/runners/runShip.js +3 -4
  60. package/bin/runners/runValidate.js +19 -2
  61. package/bin/runners/runWatch.js +104 -53
  62. package/bin/vibecheck.js +106 -19
  63. package/mcp-server/HARDENING_SUMMARY.md +299 -0
  64. package/mcp-server/agent-firewall-interceptor.js +367 -31
  65. package/mcp-server/authority-tools.js +569 -0
  66. package/mcp-server/conductor/conflict-resolver.js +588 -0
  67. package/mcp-server/conductor/execution-planner.js +544 -0
  68. package/mcp-server/conductor/index.js +377 -0
  69. package/mcp-server/conductor/lock-manager.js +615 -0
  70. package/mcp-server/conductor/request-queue.js +550 -0
  71. package/mcp-server/conductor/session-manager.js +500 -0
  72. package/mcp-server/conductor/tools.js +510 -0
  73. package/mcp-server/index.js +1149 -243
  74. package/mcp-server/lib/{api-client.js → api-client.cjs} +40 -4
  75. package/mcp-server/lib/logger.cjs +30 -0
  76. package/mcp-server/logger.js +173 -0
  77. package/mcp-server/package.json +2 -2
  78. package/mcp-server/premium-tools.js +2 -2
  79. package/mcp-server/tier-auth.js +245 -35
  80. package/mcp-server/truth-firewall-tools.js +145 -15
  81. package/mcp-server/vibecheck-tools.js +2 -2
  82. package/package.json +2 -3
  83. package/mcp-server/index.old.js +0 -4137
  84. package/mcp-server/package-lock.json +0 -165
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Critic LLM Prompts
3
+ *
4
+ * Prompt templates for the "savage" critic judge.
5
+ * Philosophy: "If it cannot be proven safe, block it."
6
+ */
7
+
8
+ "use strict";
9
+
10
+ /**
11
+ * System prompt for the critic
12
+ */
13
+ const CRITIC_SYSTEM_PROMPT = `You are a strict code change critic. Your role is to judge whether proposed changes should be allowed.
14
+
15
+ PHILOSOPHY:
16
+ - If a change cannot be proven safe by the repository state, BLOCK it
17
+ - Assumptions that cannot be verified are violations
18
+ - Vague intent is a violation
19
+ - Missing explanations are suspicious
20
+ - Trust nothing, verify everything
21
+
22
+ You output ONLY valid JSON. No explanations outside the JSON.
23
+
24
+ VERDICT OPTIONS:
25
+ - "ALLOW" - Change is safe and well-documented
26
+ - "BLOCK" - Change has unverified assumptions or risks
27
+ - "REQUIRE_CONFIRMATION" - Change needs human review
28
+
29
+ Be conservative. When in doubt, BLOCK.`;
30
+
31
+ /**
32
+ * Prompt template for evaluating a proposal
33
+ */
34
+ const EVALUATION_PROMPT_TEMPLATE = `Evaluate this proposed code change:
35
+
36
+ ## Proposal
37
+ Intent: {{intent}}
38
+ Summary: {{summary}}
39
+ Files touched: {{filesTouched}}
40
+ Operations: {{operationsCount}} ({{operationTypes}})
41
+ Declared confidence: {{confidence}}
42
+
43
+ ## Assumptions Declared
44
+ {{assumptions}}
45
+
46
+ ## Assumption Validation Results
47
+ {{validationResults}}
48
+
49
+ ## Risk Assessment
50
+ Risk Score: {{riskScore}}
51
+ Risk Level: {{riskLevel}}
52
+ Risk Factors:
53
+ {{riskFactors}}
54
+
55
+ ## Simulation Results
56
+ Simulation Passed: {{simulationPassed}}
57
+ Errors: {{simulationErrors}}
58
+ Warnings: {{simulationWarnings}}
59
+
60
+ ## Reality State Summary
61
+ Total files in repo: {{fileCount}}
62
+ Total routes: {{routeCount}}
63
+ Total env vars: {{envVarCount}}
64
+ Affected domains: {{domains}}
65
+
66
+ ---
67
+
68
+ Evaluate and respond with JSON only:
69
+ {
70
+ "verdict": "ALLOW" | "BLOCK" | "REQUIRE_CONFIRMATION",
71
+ "confidence": 0.0 to 1.0,
72
+ "reasoning": ["reason 1", "reason 2", ...],
73
+ "violations": ["violation 1", ...] or [],
74
+ "recommendations": ["recommendation 1", ...] or []
75
+ }`;
76
+
77
+ /**
78
+ * Prompt for detecting vague/hand-wavy proposals
79
+ */
80
+ const VAGUENESS_CHECK_PROMPT = `Analyze this proposal for vagueness:
81
+
82
+ Intent: {{intent}}
83
+ Summary: {{summary}}
84
+ Operation count: {{operationCount}}
85
+
86
+ Rate the specificity on a scale of 1-10 (10 = very specific).
87
+ Identify any vague language.
88
+
89
+ Respond with JSON only:
90
+ {
91
+ "specificityScore": 1-10,
92
+ "vagueTerms": ["term1", "term2"],
93
+ "suggestions": ["be more specific about X", ...]
94
+ }`;
95
+
96
+ /**
97
+ * Prompt for assumption verification
98
+ */
99
+ const ASSUMPTION_VERIFICATION_PROMPT = `Verify these assumptions against the repository state:
100
+
101
+ {{assumptions}}
102
+
103
+ Repository State:
104
+ - Declared env vars: {{declaredEnvVars}}
105
+ - Registered routes: {{registeredRoutes}}
106
+ - Registered services: {{registeredServices}}
107
+
108
+ For each assumption, determine:
109
+ 1. Can it be verified from the repo state?
110
+ 2. Is there evidence supporting it?
111
+ 3. Is it a valid assumption?
112
+
113
+ Respond with JSON only:
114
+ {
115
+ "results": [
116
+ {
117
+ "assumption": "...",
118
+ "verified": true/false,
119
+ "evidence": "..." or null,
120
+ "reason": "..."
121
+ }
122
+ ],
123
+ "overallVerificationRate": 0.0 to 1.0
124
+ }`;
125
+
126
+ /**
127
+ * Build evaluation prompt from data
128
+ * @param {Object} data - Prompt data
129
+ * @returns {string} Filled prompt
130
+ */
131
+ function buildEvaluationPrompt(data) {
132
+ const {
133
+ proposal,
134
+ validationResults,
135
+ riskScore,
136
+ simulationResult,
137
+ realityState,
138
+ } = data;
139
+
140
+ let prompt = EVALUATION_PROMPT_TEMPLATE;
141
+
142
+ // Fill in proposal data
143
+ prompt = prompt.replace("{{intent}}", proposal.intent || "not specified");
144
+ prompt = prompt.replace("{{summary}}", proposal.summary || "not provided");
145
+ prompt = prompt.replace("{{filesTouched}}", (proposal.filesTouched || []).join(", ") || "none");
146
+ prompt = prompt.replace("{{operationsCount}}", String((proposal.operations || []).length));
147
+ prompt = prompt.replace("{{operationTypes}}",
148
+ [...new Set((proposal.operations || []).map(o => o.type))].join(", ") || "none"
149
+ );
150
+ prompt = prompt.replace("{{confidence}}", String(proposal.confidence ?? "not specified"));
151
+
152
+ // Fill in assumptions
153
+ const assumptionsText = (proposal.assumptions || []).length > 0
154
+ ? proposal.assumptions.map(a =>
155
+ `- [${a.type}] ${a.key || a.path}: ${a.reason || "no reason given"}`
156
+ ).join("\n")
157
+ : "None declared";
158
+ prompt = prompt.replace("{{assumptions}}", assumptionsText);
159
+
160
+ // Fill in validation results
161
+ const validationText = validationResults
162
+ ? Object.entries(validationResults).map(([key, val]) =>
163
+ `- ${key}: ${JSON.stringify(val)}`
164
+ ).join("\n")
165
+ : "Not available";
166
+ prompt = prompt.replace("{{validationResults}}", validationText);
167
+
168
+ // Fill in risk assessment
169
+ prompt = prompt.replace("{{riskScore}}", String(riskScore?.total ?? "N/A"));
170
+ prompt = prompt.replace("{{riskLevel}}", riskScore?.level || "N/A");
171
+ prompt = prompt.replace("{{riskFactors}}",
172
+ (riskScore?.reasons || []).map(r => `- ${r}`).join("\n") || "None"
173
+ );
174
+
175
+ // Fill in simulation results
176
+ prompt = prompt.replace("{{simulationPassed}}",
177
+ simulationResult ? String(simulationResult.passed) : "Not run"
178
+ );
179
+ prompt = prompt.replace("{{simulationErrors}}",
180
+ simulationResult?.errors?.length > 0
181
+ ? simulationResult.errors.map(e => `- ${e.message}`).join("\n")
182
+ : "None"
183
+ );
184
+ prompt = prompt.replace("{{simulationWarnings}}",
185
+ simulationResult?.warnings?.length > 0
186
+ ? simulationResult.warnings.map(w => `- ${w.message}`).join("\n")
187
+ : "None"
188
+ );
189
+
190
+ // Fill in reality state
191
+ prompt = prompt.replace("{{fileCount}}", String(realityState?.files?.size ?? "N/A"));
192
+ prompt = prompt.replace("{{routeCount}}", String(realityState?.routes?.length ?? "N/A"));
193
+ prompt = prompt.replace("{{envVarCount}}", String(realityState?.envVars?.size ?? "N/A"));
194
+ prompt = prompt.replace("{{domains}}",
195
+ [...new Set((proposal.operations || []).map(o => classifyDomain(o.path)))].join(", ") || "general"
196
+ );
197
+
198
+ return prompt;
199
+ }
200
+
201
+ /**
202
+ * Simple domain classifier (for prompt building)
203
+ */
204
+ function classifyDomain(filePath) {
205
+ if (!filePath) return "general";
206
+ const s = filePath.toLowerCase();
207
+ if (s.includes("auth")) return "auth";
208
+ if (s.includes("payment") || s.includes("stripe")) return "payments";
209
+ if (s.includes("route") || s.includes("api")) return "routes";
210
+ if (s.includes("db") || s.includes("prisma")) return "database";
211
+ return "general";
212
+ }
213
+
214
+ /**
215
+ * Build vagueness check prompt
216
+ * @param {Object} proposal - Proposal to check
217
+ * @returns {string} Filled prompt
218
+ */
219
+ function buildVaguenessPrompt(proposal) {
220
+ let prompt = VAGUENESS_CHECK_PROMPT;
221
+
222
+ prompt = prompt.replace("{{intent}}", proposal.intent || "not specified");
223
+ prompt = prompt.replace("{{summary}}", proposal.summary || "not provided");
224
+ prompt = prompt.replace("{{operationCount}}", String((proposal.operations || []).length));
225
+
226
+ return prompt;
227
+ }
228
+
229
+ /**
230
+ * Build assumption verification prompt
231
+ * @param {Array} assumptions - Assumptions to verify
232
+ * @param {Object} realityState - Repository state
233
+ * @returns {string} Filled prompt
234
+ */
235
+ function buildVerificationPrompt(assumptions, realityState) {
236
+ let prompt = ASSUMPTION_VERIFICATION_PROMPT;
237
+
238
+ const assumptionsText = assumptions.map(a =>
239
+ `- [${a.type}] ${a.key || a.path}: ${a.reason || "no reason"}`
240
+ ).join("\n");
241
+
242
+ prompt = prompt.replace("{{assumptions}}", assumptionsText);
243
+
244
+ // Extract state summaries
245
+ const declaredEnvVars = realityState?.envVars
246
+ ? [...realityState.envVars.keys()].slice(0, 20).join(", ")
247
+ : "not available";
248
+
249
+ const registeredRoutes = realityState?.routes
250
+ ? realityState.routes.slice(0, 10).map(r => `${r.method} ${r.path}`).join(", ")
251
+ : "not available";
252
+
253
+ const registeredServices = realityState?.services
254
+ ? realityState.services.slice(0, 10).map(s => s.name).join(", ")
255
+ : "not available";
256
+
257
+ prompt = prompt.replace("{{declaredEnvVars}}", declaredEnvVars);
258
+ prompt = prompt.replace("{{registeredRoutes}}", registeredRoutes);
259
+ prompt = prompt.replace("{{registeredServices}}", registeredServices);
260
+
261
+ return prompt;
262
+ }
263
+
264
+ /**
265
+ * Parse critic response
266
+ * @param {string} response - LLM response text
267
+ * @returns {Object} Parsed response
268
+ */
269
+ function parseCriticResponse(response) {
270
+ try {
271
+ // Try to extract JSON from response
272
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
273
+ if (jsonMatch) {
274
+ return JSON.parse(jsonMatch[0]);
275
+ }
276
+
277
+ // If no JSON found, return a default blocked response
278
+ return {
279
+ verdict: "BLOCK",
280
+ confidence: 0.5,
281
+ reasoning: ["Failed to parse critic response"],
282
+ violations: ["Invalid response format"],
283
+ recommendations: [],
284
+ };
285
+ } catch (error) {
286
+ return {
287
+ verdict: "BLOCK",
288
+ confidence: 0.5,
289
+ reasoning: ["Failed to parse critic response: " + error.message],
290
+ violations: ["Invalid JSON in response"],
291
+ recommendations: [],
292
+ };
293
+ }
294
+ }
295
+
296
+ module.exports = {
297
+ CRITIC_SYSTEM_PROMPT,
298
+ EVALUATION_PROMPT_TEMPLATE,
299
+ VAGUENESS_CHECK_PROMPT,
300
+ ASSUMPTION_VERIFICATION_PROMPT,
301
+ buildEvaluationPrompt,
302
+ buildVaguenessPrompt,
303
+ buildVerificationPrompt,
304
+ parseCriticResponse,
305
+ };