@vibecheckai/cli 3.7.0 → 3.8.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 (99) hide show
  1. package/README.md +135 -63
  2. package/bin/_deprecations.js +447 -19
  3. package/bin/_router.js +1 -1
  4. package/bin/registry.js +347 -280
  5. package/bin/runners/context/generators/cursor-enhanced.js +2439 -0
  6. package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
  7. package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
  8. package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
  9. package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
  10. package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
  11. package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
  12. package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
  13. package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
  14. package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
  15. package/bin/runners/lib/agent-firewall/index.js +200 -0
  16. package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
  17. package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
  18. package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +622 -0
  19. package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
  20. package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
  21. package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
  22. package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
  23. package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
  24. package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
  25. package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
  26. package/bin/runners/lib/agent-firewall/session/index.js +26 -0
  27. package/bin/runners/lib/artifact-envelope.js +540 -0
  28. package/bin/runners/lib/auth-shared.js +977 -0
  29. package/bin/runners/lib/checkpoint.js +941 -0
  30. package/bin/runners/lib/cleanup/engine.js +571 -0
  31. package/bin/runners/lib/cleanup/index.js +53 -0
  32. package/bin/runners/lib/cleanup/output.js +375 -0
  33. package/bin/runners/lib/cleanup/rules.js +1060 -0
  34. package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
  35. package/bin/runners/lib/doctor/failure-signatures.js +526 -0
  36. package/bin/runners/lib/doctor/fix-script.js +336 -0
  37. package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
  38. package/bin/runners/lib/doctor/modules/index.js +62 -3
  39. package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
  40. package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
  41. package/bin/runners/lib/doctor/safe-repair.js +384 -0
  42. package/bin/runners/lib/engines/attack-detector.js +1192 -0
  43. package/bin/runners/lib/entitlements-v2.js +2 -2
  44. package/bin/runners/lib/missions/briefing.js +427 -0
  45. package/bin/runners/lib/missions/checkpoint.js +753 -0
  46. package/bin/runners/lib/missions/hardening.js +851 -0
  47. package/bin/runners/lib/missions/plan.js +421 -32
  48. package/bin/runners/lib/missions/safety-gates.js +645 -0
  49. package/bin/runners/lib/missions/schema.js +478 -0
  50. package/bin/runners/lib/packs/bundle.js +675 -0
  51. package/bin/runners/lib/packs/evidence-pack.js +671 -0
  52. package/bin/runners/lib/packs/pack-factory.js +837 -0
  53. package/bin/runners/lib/packs/permissions-pack.js +686 -0
  54. package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
  55. package/bin/runners/lib/safelist/index.js +96 -0
  56. package/bin/runners/lib/safelist/integration.js +334 -0
  57. package/bin/runners/lib/safelist/matcher.js +696 -0
  58. package/bin/runners/lib/safelist/schema.js +948 -0
  59. package/bin/runners/lib/safelist/store.js +438 -0
  60. package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
  61. package/bin/runners/lib/ship-gate.js +832 -0
  62. package/bin/runners/lib/ship-manifest.js +1153 -0
  63. package/bin/runners/lib/ship-output.js +1 -1
  64. package/bin/runners/lib/unified-cli-output.js +710 -383
  65. package/bin/runners/lib/upsell.js +3 -3
  66. package/bin/runners/lib/why-tree.js +650 -0
  67. package/bin/runners/runAllowlist.js +33 -4
  68. package/bin/runners/runApprove.js +240 -1122
  69. package/bin/runners/runAudit.js +692 -0
  70. package/bin/runners/runAuth.js +325 -29
  71. package/bin/runners/runCheckpoint.js +442 -494
  72. package/bin/runners/runCleanup.js +343 -0
  73. package/bin/runners/runDoctor.js +269 -19
  74. package/bin/runners/runFix.js +411 -32
  75. package/bin/runners/runForge.js +411 -0
  76. package/bin/runners/runIntent.js +906 -0
  77. package/bin/runners/runKickoff.js +878 -0
  78. package/bin/runners/runLaunch.js +2000 -0
  79. package/bin/runners/runLink.js +785 -0
  80. package/bin/runners/runMcp.js +1741 -837
  81. package/bin/runners/runPacks.js +2089 -0
  82. package/bin/runners/runPolish.js +41 -0
  83. package/bin/runners/runSafelist.js +1190 -0
  84. package/bin/runners/runScan.js +21 -9
  85. package/bin/runners/runShield.js +1282 -0
  86. package/bin/runners/runShip.js +395 -16
  87. package/bin/vibecheck.js +34 -6
  88. package/mcp-server/README.md +117 -158
  89. package/mcp-server/handlers/tool-handler.ts +3 -3
  90. package/mcp-server/index.js +16 -0
  91. package/mcp-server/intent-firewall-interceptor.js +529 -0
  92. package/mcp-server/manifest.json +473 -0
  93. package/mcp-server/package.json +1 -1
  94. package/mcp-server/registry/tool-registry.js +315 -523
  95. package/mcp-server/registry/tools.json +442 -428
  96. package/mcp-server/tier-auth.js +68 -11
  97. package/mcp-server/tools-v3.js +70 -16
  98. package/package.json +1 -1
  99. package/bin/runners/runProof.zip +0 -0
@@ -0,0 +1,384 @@
1
+ /**
2
+ * Safe Repair Mode
3
+ *
4
+ * Executes only safe, non-destructive repair actions.
5
+ * Actions that can cause data loss or require elevated permissions are excluded.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const { execSync, spawnSync } = require('child_process');
11
+ const { SEVERITY, FIX_TYPE } = require('./types');
12
+
13
+ const REPAIR_RESULT = {
14
+ SUCCESS: 'success',
15
+ FAILED: 'failed',
16
+ SKIPPED: 'skipped',
17
+ NOT_APPLICABLE: 'not_applicable',
18
+ };
19
+
20
+ /**
21
+ * Safe repair actions that can be automatically executed
22
+ */
23
+ const SAFE_REPAIR_ACTIONS = [
24
+ {
25
+ id: 'clear-npm-cache',
26
+ name: 'Clear npm cache',
27
+ description: 'Removes npm cache to fix integrity issues',
28
+ applicableTo: ['npm-cache-corrupt', 'npm-permission-error'],
29
+ check: () => true, // Always applicable
30
+ execute: async (projectPath, options) => {
31
+ try {
32
+ execSync('npm cache clean --force', {
33
+ cwd: projectPath,
34
+ encoding: 'utf8',
35
+ timeout: 60000,
36
+ stdio: ['pipe', 'pipe', 'pipe'],
37
+ });
38
+ return { status: REPAIR_RESULT.SUCCESS, message: 'npm cache cleared' };
39
+ } catch (err) {
40
+ return { status: REPAIR_RESULT.FAILED, message: err.message };
41
+ }
42
+ },
43
+ },
44
+ {
45
+ id: 'clear-node-modules-cache',
46
+ name: 'Clear node_modules cache directories',
47
+ description: 'Removes .cache directories inside node_modules',
48
+ applicableTo: ['cache-large', 'build-cache-corrupt'],
49
+ check: (projectPath) => {
50
+ const cachePath = path.join(projectPath, 'node_modules', '.cache');
51
+ return fs.existsSync(cachePath);
52
+ },
53
+ execute: async (projectPath, options) => {
54
+ const cachePath = path.join(projectPath, 'node_modules', '.cache');
55
+ try {
56
+ fs.rmSync(cachePath, { recursive: true, force: true });
57
+ return { status: REPAIR_RESULT.SUCCESS, message: 'node_modules/.cache cleared' };
58
+ } catch (err) {
59
+ return { status: REPAIR_RESULT.FAILED, message: err.message };
60
+ }
61
+ },
62
+ },
63
+ {
64
+ id: 'remove-eslint-cache',
65
+ name: 'Remove ESLint cache',
66
+ description: 'Removes .eslintcache file',
67
+ applicableTo: ['eslint-error', 'cache-large'],
68
+ check: (projectPath) => fs.existsSync(path.join(projectPath, '.eslintcache')),
69
+ execute: async (projectPath, options) => {
70
+ try {
71
+ fs.unlinkSync(path.join(projectPath, '.eslintcache'));
72
+ return { status: REPAIR_RESULT.SUCCESS, message: '.eslintcache removed' };
73
+ } catch (err) {
74
+ return { status: REPAIR_RESULT.FAILED, message: err.message };
75
+ }
76
+ },
77
+ },
78
+ {
79
+ id: 'remove-tsbuildinfo',
80
+ name: 'Remove TypeScript build info',
81
+ description: 'Removes tsconfig.tsbuildinfo for clean TypeScript rebuild',
82
+ applicableTo: ['typescript-error', 'build-error'],
83
+ check: (projectPath) => {
84
+ // Check for any .tsbuildinfo file
85
+ return fs.existsSync(path.join(projectPath, 'tsconfig.tsbuildinfo')) ||
86
+ fs.existsSync(path.join(projectPath, '.tsbuildinfo'));
87
+ },
88
+ execute: async (projectPath, options) => {
89
+ const removed = [];
90
+ const files = ['tsconfig.tsbuildinfo', '.tsbuildinfo'];
91
+
92
+ for (const file of files) {
93
+ const fullPath = path.join(projectPath, file);
94
+ if (fs.existsSync(fullPath)) {
95
+ try {
96
+ fs.unlinkSync(fullPath);
97
+ removed.push(file);
98
+ } catch {}
99
+ }
100
+ }
101
+
102
+ if (removed.length > 0) {
103
+ return { status: REPAIR_RESULT.SUCCESS, message: `Removed: ${removed.join(', ')}` };
104
+ }
105
+ return { status: REPAIR_RESULT.NOT_APPLICABLE, message: 'No build info files found' };
106
+ },
107
+ },
108
+ {
109
+ id: 'remove-git-lock',
110
+ name: 'Remove git lock files',
111
+ description: 'Removes stale .git/*.lock files',
112
+ applicableTo: ['git-lock-file'],
113
+ check: (projectPath) => {
114
+ const gitDir = path.join(projectPath, '.git');
115
+ if (!fs.existsSync(gitDir)) return false;
116
+
117
+ try {
118
+ const files = fs.readdirSync(gitDir);
119
+ return files.some(f => f.endsWith('.lock'));
120
+ } catch {
121
+ return false;
122
+ }
123
+ },
124
+ execute: async (projectPath, options) => {
125
+ const gitDir = path.join(projectPath, '.git');
126
+ const removed = [];
127
+
128
+ try {
129
+ const files = fs.readdirSync(gitDir);
130
+ for (const file of files) {
131
+ if (file.endsWith('.lock')) {
132
+ fs.unlinkSync(path.join(gitDir, file));
133
+ removed.push(file);
134
+ }
135
+ }
136
+ } catch (err) {
137
+ return { status: REPAIR_RESULT.FAILED, message: err.message };
138
+ }
139
+
140
+ if (removed.length > 0) {
141
+ return { status: REPAIR_RESULT.SUCCESS, message: `Removed: ${removed.join(', ')}` };
142
+ }
143
+ return { status: REPAIR_RESULT.NOT_APPLICABLE, message: 'No lock files found' };
144
+ },
145
+ },
146
+ {
147
+ id: 'create-vibecheck-dir',
148
+ name: 'Create .vibecheck directory',
149
+ description: 'Creates missing .vibecheck output directory',
150
+ applicableTo: ['vibecheck-dir-missing'],
151
+ check: (projectPath) => !fs.existsSync(path.join(projectPath, '.vibecheck')),
152
+ execute: async (projectPath, options) => {
153
+ try {
154
+ fs.mkdirSync(path.join(projectPath, '.vibecheck'), { recursive: true });
155
+ return { status: REPAIR_RESULT.SUCCESS, message: '.vibecheck directory created' };
156
+ } catch (err) {
157
+ return { status: REPAIR_RESULT.FAILED, message: err.message };
158
+ }
159
+ },
160
+ },
161
+ {
162
+ id: 'fix-npm-registry',
163
+ name: 'Reset npm registry URL',
164
+ description: 'Sets npm registry to default npmjs.org',
165
+ applicableTo: ['npm-network-error'],
166
+ check: () => true,
167
+ execute: async (projectPath, options) => {
168
+ try {
169
+ execSync('npm config set registry https://registry.npmjs.org/', {
170
+ encoding: 'utf8',
171
+ timeout: 10000,
172
+ stdio: ['pipe', 'pipe', 'pipe'],
173
+ });
174
+ return { status: REPAIR_RESULT.SUCCESS, message: 'npm registry reset to default' };
175
+ } catch (err) {
176
+ return { status: REPAIR_RESULT.FAILED, message: err.message };
177
+ }
178
+ },
179
+ },
180
+ {
181
+ id: 'npm-dedupe',
182
+ name: 'Deduplicate npm packages',
183
+ description: 'Runs npm dedupe to reduce duplicate packages',
184
+ applicableTo: ['dependencies-large', 'peer-deps'],
185
+ check: (projectPath) => fs.existsSync(path.join(projectPath, 'node_modules')),
186
+ execute: async (projectPath, options) => {
187
+ try {
188
+ execSync('npm dedupe', {
189
+ cwd: projectPath,
190
+ encoding: 'utf8',
191
+ timeout: 120000, // 2 minutes
192
+ stdio: ['pipe', 'pipe', 'pipe'],
193
+ });
194
+ return { status: REPAIR_RESULT.SUCCESS, message: 'npm dedupe completed' };
195
+ } catch (err) {
196
+ return { status: REPAIR_RESULT.FAILED, message: err.message };
197
+ }
198
+ },
199
+ },
200
+ {
201
+ id: 'rebuild-native-modules',
202
+ name: 'Rebuild native modules',
203
+ description: 'Runs npm rebuild for native module issues',
204
+ applicableTo: ['native-module-build', 'node-version-mismatch'],
205
+ check: (projectPath) => fs.existsSync(path.join(projectPath, 'node_modules')),
206
+ execute: async (projectPath, options) => {
207
+ try {
208
+ execSync('npm rebuild', {
209
+ cwd: projectPath,
210
+ encoding: 'utf8',
211
+ timeout: 300000, // 5 minutes
212
+ stdio: ['pipe', 'pipe', 'pipe'],
213
+ });
214
+ return { status: REPAIR_RESULT.SUCCESS, message: 'npm rebuild completed' };
215
+ } catch (err) {
216
+ return { status: REPAIR_RESULT.FAILED, message: err.message };
217
+ }
218
+ },
219
+ },
220
+ {
221
+ id: 'prune-dev-dependencies',
222
+ name: 'Prune development dependencies',
223
+ description: 'Removes extraneous packages',
224
+ applicableTo: ['dependencies-large'],
225
+ check: (projectPath) => fs.existsSync(path.join(projectPath, 'node_modules')),
226
+ execute: async (projectPath, options) => {
227
+ try {
228
+ execSync('npm prune', {
229
+ cwd: projectPath,
230
+ encoding: 'utf8',
231
+ timeout: 60000,
232
+ stdio: ['pipe', 'pipe', 'pipe'],
233
+ });
234
+ return { status: REPAIR_RESULT.SUCCESS, message: 'npm prune completed' };
235
+ } catch (err) {
236
+ return { status: REPAIR_RESULT.FAILED, message: err.message };
237
+ }
238
+ },
239
+ },
240
+ ];
241
+
242
+ /**
243
+ * Run safe repair on a project
244
+ * @param {object[]} diagnostics - Diagnostic results
245
+ * @param {string} projectPath - Project path
246
+ * @param {object} options - Repair options
247
+ * @returns {object} Repair results
248
+ */
249
+ async function runSafeRepair(diagnostics, projectPath, options = {}) {
250
+ const {
251
+ dryRun = false,
252
+ verbose = false,
253
+ maxActions = 10,
254
+ } = options;
255
+
256
+ const results = [];
257
+ let actionsRun = 0;
258
+
259
+ // Identify which repairs are applicable
260
+ const applicableRepairs = [];
261
+
262
+ for (const action of SAFE_REPAIR_ACTIONS) {
263
+ // Check if this repair applies to any diagnostics
264
+ const relevantDiag = diagnostics.find(d =>
265
+ (d.severity === SEVERITY.ERROR || d.severity === SEVERITY.WARNING) &&
266
+ action.applicableTo.some(pattern => d.id.includes(pattern) || d.message?.toLowerCase().includes(pattern))
267
+ );
268
+
269
+ if (relevantDiag && action.check(projectPath)) {
270
+ applicableRepairs.push({
271
+ action,
272
+ diagnostic: relevantDiag,
273
+ });
274
+ }
275
+ }
276
+
277
+ // Execute repairs
278
+ for (const { action, diagnostic } of applicableRepairs) {
279
+ if (actionsRun >= maxActions) break;
280
+
281
+ const result = {
282
+ actionId: action.id,
283
+ actionName: action.name,
284
+ description: action.description,
285
+ relatedDiagnostic: diagnostic.id,
286
+ };
287
+
288
+ if (dryRun) {
289
+ result.status = REPAIR_RESULT.SKIPPED;
290
+ result.message = 'Dry run - would execute';
291
+ results.push(result);
292
+ continue;
293
+ }
294
+
295
+ try {
296
+ const execResult = await action.execute(projectPath, options);
297
+ result.status = execResult.status;
298
+ result.message = execResult.message;
299
+
300
+ if (execResult.status === REPAIR_RESULT.SUCCESS) {
301
+ actionsRun++;
302
+ }
303
+ } catch (err) {
304
+ result.status = REPAIR_RESULT.FAILED;
305
+ result.message = err.message;
306
+ }
307
+
308
+ results.push(result);
309
+ }
310
+
311
+ // Summary
312
+ const summary = {
313
+ total: results.length,
314
+ succeeded: results.filter(r => r.status === REPAIR_RESULT.SUCCESS).length,
315
+ failed: results.filter(r => r.status === REPAIR_RESULT.FAILED).length,
316
+ skipped: results.filter(r => r.status === REPAIR_RESULT.SKIPPED).length,
317
+ notApplicable: results.filter(r => r.status === REPAIR_RESULT.NOT_APPLICABLE).length,
318
+ };
319
+
320
+ return {
321
+ projectPath,
322
+ timestamp: new Date().toISOString(),
323
+ dryRun,
324
+ results,
325
+ summary,
326
+ needsRecheck: summary.succeeded > 0,
327
+ };
328
+ }
329
+
330
+ /**
331
+ * Get list of all available safe repair actions
332
+ * @returns {object[]} Safe repair actions
333
+ */
334
+ function listSafeRepairActions() {
335
+ return SAFE_REPAIR_ACTIONS.map(a => ({
336
+ id: a.id,
337
+ name: a.name,
338
+ description: a.description,
339
+ applicableTo: a.applicableTo,
340
+ }));
341
+ }
342
+
343
+ /**
344
+ * Run a specific repair action by ID
345
+ * @param {string} actionId - Action ID to run
346
+ * @param {string} projectPath - Project path
347
+ * @param {object} options - Options
348
+ * @returns {object} Result
349
+ */
350
+ async function runRepairAction(actionId, projectPath, options = {}) {
351
+ const action = SAFE_REPAIR_ACTIONS.find(a => a.id === actionId);
352
+
353
+ if (!action) {
354
+ return {
355
+ status: REPAIR_RESULT.FAILED,
356
+ message: `Unknown repair action: ${actionId}`,
357
+ };
358
+ }
359
+
360
+ if (!action.check(projectPath)) {
361
+ return {
362
+ status: REPAIR_RESULT.NOT_APPLICABLE,
363
+ message: 'Repair action not applicable to current project state',
364
+ };
365
+ }
366
+
367
+ if (options.dryRun) {
368
+ return {
369
+ status: REPAIR_RESULT.SKIPPED,
370
+ message: 'Dry run - would execute',
371
+ action: action.name,
372
+ };
373
+ }
374
+
375
+ return action.execute(projectPath, options);
376
+ }
377
+
378
+ module.exports = {
379
+ REPAIR_RESULT,
380
+ SAFE_REPAIR_ACTIONS,
381
+ runSafeRepair,
382
+ listSafeRepairActions,
383
+ runRepairAction,
384
+ };