@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,346 @@
1
+ /**
2
+ * Import Resolver
3
+ *
4
+ * Resolves and validates import statements in JavaScript/TypeScript code.
5
+ * Used by the diff simulator to detect broken imports.
6
+ */
7
+
8
+ "use strict";
9
+
10
+ const fs = require("fs");
11
+ const path = require("path");
12
+
13
+ /**
14
+ * Extract imports from source code
15
+ * @param {string} content - File content
16
+ * @returns {Array} Array of import objects
17
+ */
18
+ function extractImports(content) {
19
+ const imports = [];
20
+
21
+ // ES6 imports: import X from 'Y', import { X } from 'Y', import 'Y'
22
+ const importRegex = /import\s+(?:(?:(\w+)(?:\s*,\s*)?)?(?:\{([^}]+)\})?\s+from\s+)?['"]([^'"]+)['"]/g;
23
+ let match;
24
+
25
+ while ((match = importRegex.exec(content)) !== null) {
26
+ const [, defaultImport, namedImports, source] = match;
27
+ imports.push({
28
+ type: "esm",
29
+ source,
30
+ defaultImport: defaultImport || null,
31
+ namedImports: namedImports ? namedImports.split(",").map(s => s.trim()) : [],
32
+ line: content.substring(0, match.index).split("\n").length,
33
+ });
34
+ }
35
+
36
+ // Dynamic imports: import('X'), await import('X')
37
+ const dynamicRegex = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
38
+ while ((match = dynamicRegex.exec(content)) !== null) {
39
+ imports.push({
40
+ type: "dynamic",
41
+ source: match[1],
42
+ defaultImport: null,
43
+ namedImports: [],
44
+ line: content.substring(0, match.index).split("\n").length,
45
+ });
46
+ }
47
+
48
+ // CommonJS requires: require('X'), require("X")
49
+ const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
50
+ while ((match = requireRegex.exec(content)) !== null) {
51
+ imports.push({
52
+ type: "commonjs",
53
+ source: match[1],
54
+ defaultImport: null,
55
+ namedImports: [],
56
+ line: content.substring(0, match.index).split("\n").length,
57
+ });
58
+ }
59
+
60
+ return imports;
61
+ }
62
+
63
+ /**
64
+ * Extract exports from source code
65
+ * @param {string} content - File content
66
+ * @returns {Array} Array of export objects
67
+ */
68
+ function extractExports(content) {
69
+ const exports = [];
70
+
71
+ // Named exports: export const X, export function X, export class X
72
+ const namedRegex = /export\s+(?:const|let|var|function|class|interface|type|enum)\s+(\w+)/g;
73
+ let match;
74
+
75
+ while ((match = namedRegex.exec(content)) !== null) {
76
+ exports.push({
77
+ type: "named",
78
+ name: match[1],
79
+ line: content.substring(0, match.index).split("\n").length,
80
+ });
81
+ }
82
+
83
+ // Export list: export { X, Y as Z }
84
+ const listRegex = /export\s+\{([^}]+)\}/g;
85
+ while ((match = listRegex.exec(content)) !== null) {
86
+ const names = match[1].split(",").map(s => {
87
+ const parts = s.trim().split(/\s+as\s+/);
88
+ return { original: parts[0].trim(), alias: parts[1]?.trim() || parts[0].trim() };
89
+ });
90
+ for (const name of names) {
91
+ exports.push({
92
+ type: "named",
93
+ name: name.alias,
94
+ originalName: name.original,
95
+ line: content.substring(0, match.index).split("\n").length,
96
+ });
97
+ }
98
+ }
99
+
100
+ // Default export: export default X
101
+ const defaultRegex = /export\s+default\s+(?:class\s+(\w+)|function\s+(\w+)|(\w+))/g;
102
+ while ((match = defaultRegex.exec(content)) !== null) {
103
+ const name = match[1] || match[2] || match[3];
104
+ exports.push({
105
+ type: "default",
106
+ name: name || "default",
107
+ line: content.substring(0, match.index).split("\n").length,
108
+ });
109
+ }
110
+
111
+ // Re-exports: export * from 'X', export { X } from 'X'
112
+ const reExportRegex = /export\s+(?:\*|{[^}]+})\s+from\s+['"]([^'"]+)['"]/g;
113
+ while ((match = reExportRegex.exec(content)) !== null) {
114
+ exports.push({
115
+ type: "reexport",
116
+ source: match[1],
117
+ line: content.substring(0, match.index).split("\n").length,
118
+ });
119
+ }
120
+
121
+ // module.exports
122
+ if (content.includes("module.exports")) {
123
+ exports.push({
124
+ type: "commonjs",
125
+ name: "module.exports",
126
+ line: content.indexOf("module.exports"),
127
+ });
128
+ }
129
+
130
+ return exports;
131
+ }
132
+
133
+ /**
134
+ * Resolve import path to actual file
135
+ * @param {string} importPath - Import path
136
+ * @param {string} fromFile - File containing the import
137
+ * @param {string} projectRoot - Project root directory
138
+ * @param {Map} virtualFiles - Virtual file system (for simulation)
139
+ * @returns {Object} Resolution result
140
+ */
141
+ function resolveImportPath(importPath, fromFile, projectRoot, virtualFiles = new Map()) {
142
+ // Node built-ins
143
+ const builtins = [
144
+ "fs", "path", "os", "http", "https", "crypto", "util", "events",
145
+ "stream", "buffer", "url", "querystring", "child_process", "net",
146
+ "assert", "zlib", "readline", "cluster", "dns", "tls", "dgram",
147
+ ];
148
+
149
+ if (builtins.includes(importPath) || importPath.startsWith("node:")) {
150
+ return { resolved: true, type: "builtin", path: importPath };
151
+ }
152
+
153
+ // External packages (don't start with . or /)
154
+ if (!importPath.startsWith(".") && !importPath.startsWith("/") && !importPath.startsWith("@/")) {
155
+ // Check if it looks like a scoped package
156
+ const isScoped = importPath.startsWith("@") && !importPath.startsWith("@/");
157
+ return { resolved: true, type: "external", path: importPath, isScoped };
158
+ }
159
+
160
+ // Resolve relative imports
161
+ const fromDir = path.dirname(fromFile);
162
+ let resolvedPath;
163
+
164
+ // Handle alias imports (@/)
165
+ if (importPath.startsWith("@/")) {
166
+ resolvedPath = path.join(projectRoot, "src", importPath.slice(2));
167
+ } else if (importPath.startsWith("~/")) {
168
+ resolvedPath = path.join(projectRoot, importPath.slice(2));
169
+ } else {
170
+ resolvedPath = path.resolve(fromDir, importPath);
171
+ }
172
+
173
+ // Try different extensions
174
+ const extensions = ["", ".ts", ".tsx", ".js", ".jsx", ".json", "/index.ts", "/index.tsx", "/index.js", "/index.jsx"];
175
+
176
+ for (const ext of extensions) {
177
+ const fullPath = resolvedPath + ext;
178
+ const relativePath = path.relative(projectRoot, fullPath).replace(/\\/g, "/");
179
+
180
+ // Check virtual files first
181
+ if (virtualFiles.has(relativePath)) {
182
+ return { resolved: true, type: "internal", path: relativePath, virtual: true };
183
+ }
184
+
185
+ // Check real file system
186
+ if (fs.existsSync(fullPath)) {
187
+ return { resolved: true, type: "internal", path: relativePath };
188
+ }
189
+ }
190
+
191
+ // Unresolved
192
+ return {
193
+ resolved: false,
194
+ type: "unresolved",
195
+ path: importPath,
196
+ attemptedPaths: extensions.map(ext => resolvedPath + ext),
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Check if an import can be resolved with changes applied
202
+ * @param {Object} importObj - Import object
203
+ * @param {string} fromFile - Source file
204
+ * @param {string} projectRoot - Project root
205
+ * @param {Map} virtualFiles - Virtual file system state
206
+ * @param {Set} deletedFiles - Deleted files
207
+ * @returns {Object} Validation result
208
+ */
209
+ function validateImport(importObj, fromFile, projectRoot, virtualFiles, deletedFiles) {
210
+ const resolution = resolveImportPath(importObj.source, fromFile, projectRoot, virtualFiles);
211
+
212
+ // Check if resolved file is deleted
213
+ if (resolution.resolved && resolution.type === "internal") {
214
+ if (deletedFiles.has(resolution.path)) {
215
+ return {
216
+ valid: false,
217
+ import: importObj,
218
+ resolution,
219
+ error: `Import '${importObj.source}' resolves to deleted file '${resolution.path}'`,
220
+ };
221
+ }
222
+ }
223
+
224
+ // Check if import is unresolved
225
+ if (!resolution.resolved) {
226
+ return {
227
+ valid: false,
228
+ import: importObj,
229
+ resolution,
230
+ error: `Cannot resolve import '${importObj.source}' from '${fromFile}'`,
231
+ };
232
+ }
233
+
234
+ return {
235
+ valid: true,
236
+ import: importObj,
237
+ resolution,
238
+ };
239
+ }
240
+
241
+ /**
242
+ * Build import graph from files
243
+ * @param {Map} files - Map of file path to content
244
+ * @param {string} projectRoot - Project root
245
+ * @returns {Object} Import graph
246
+ */
247
+ function buildImportGraph(files, projectRoot) {
248
+ const graph = {
249
+ nodes: new Map(),
250
+ edges: [],
251
+ circularDeps: [],
252
+ };
253
+
254
+ // Build nodes and edges
255
+ for (const [filePath, content] of files) {
256
+ const imports = extractImports(content);
257
+ const exports = extractExports(content);
258
+
259
+ graph.nodes.set(filePath, {
260
+ path: filePath,
261
+ imports,
262
+ exports,
263
+ importCount: imports.length,
264
+ exportCount: exports.length,
265
+ });
266
+
267
+ // Add edges
268
+ for (const imp of imports) {
269
+ const resolution = resolveImportPath(imp.source, filePath, projectRoot, files);
270
+ if (resolution.type === "internal") {
271
+ graph.edges.push({
272
+ from: filePath,
273
+ to: resolution.path,
274
+ import: imp,
275
+ });
276
+ }
277
+ }
278
+ }
279
+
280
+ // Detect circular dependencies
281
+ graph.circularDeps = detectCircularDeps(graph.edges);
282
+
283
+ return graph;
284
+ }
285
+
286
+ /**
287
+ * Detect circular dependencies in import graph
288
+ * @param {Array} edges - Graph edges
289
+ * @returns {Array} Array of circular dependency chains
290
+ */
291
+ function detectCircularDeps(edges) {
292
+ const graph = new Map();
293
+
294
+ // Build adjacency list
295
+ for (const edge of edges) {
296
+ if (!graph.has(edge.from)) {
297
+ graph.set(edge.from, []);
298
+ }
299
+ graph.get(edge.from).push(edge.to);
300
+ }
301
+
302
+ const visited = new Set();
303
+ const inStack = new Set();
304
+ const cycles = [];
305
+
306
+ function dfs(node, path) {
307
+ if (inStack.has(node)) {
308
+ // Found cycle
309
+ const cycleStart = path.indexOf(node);
310
+ const cycle = path.slice(cycleStart);
311
+ cycle.push(node);
312
+ cycles.push(cycle);
313
+ return;
314
+ }
315
+
316
+ if (visited.has(node)) return;
317
+
318
+ visited.add(node);
319
+ inStack.add(node);
320
+ path.push(node);
321
+
322
+ const neighbors = graph.get(node) || [];
323
+ for (const neighbor of neighbors) {
324
+ dfs(neighbor, [...path]);
325
+ }
326
+
327
+ inStack.delete(node);
328
+ }
329
+
330
+ for (const node of graph.keys()) {
331
+ if (!visited.has(node)) {
332
+ dfs(node, []);
333
+ }
334
+ }
335
+
336
+ return cycles;
337
+ }
338
+
339
+ module.exports = {
340
+ extractImports,
341
+ extractExports,
342
+ resolveImportPath,
343
+ validateImport,
344
+ buildImportGraph,
345
+ detectCircularDeps,
346
+ };
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Diff Simulator Module
3
+ *
4
+ * Entry point for the diff simulation engine.
5
+ * Validates changes in memory before applying to disk.
6
+ *
7
+ * Usage:
8
+ * const { simulator } = require('./simulator');
9
+ *
10
+ * const result = simulator.simulate(projectRoot, [
11
+ * { type: 'create', path: 'src/new.ts', content: '...' },
12
+ * { type: 'modify', path: 'src/existing.ts', content: '...' },
13
+ * { type: 'delete', path: 'src/old.ts' },
14
+ * ]);
15
+ *
16
+ * if (!result.passed) {
17
+ * console.log('Simulation failed:', result.errors);
18
+ * }
19
+ */
20
+
21
+ "use strict";
22
+
23
+ const {
24
+ simulate,
25
+ quickSimulate,
26
+ buildVirtualFS,
27
+ validateImportsAfterChanges,
28
+ detectOrphanedFiles,
29
+ formatResult,
30
+ } = require("./diff-simulator");
31
+
32
+ const {
33
+ extractImports,
34
+ extractExports,
35
+ resolveImportPath,
36
+ validateImport,
37
+ buildImportGraph,
38
+ detectCircularDeps,
39
+ } = require("./import-resolver");
40
+
41
+ const {
42
+ extractRoutes,
43
+ validateRoutes,
44
+ findRouteReferences,
45
+ } = require("./route-validator");
46
+
47
+ /**
48
+ * Simulator singleton
49
+ */
50
+ const simulator = {
51
+ /**
52
+ * Run full simulation
53
+ * @param {string} projectRoot - Project root directory
54
+ * @param {Array} changes - Array of change operations
55
+ * @param {Object} options - Simulation options
56
+ * @returns {Object} Simulation result
57
+ */
58
+ simulate(projectRoot, changes, options = {}) {
59
+ return simulate(projectRoot, changes, options);
60
+ },
61
+
62
+ /**
63
+ * Quick simulation for single file
64
+ * @param {string} projectRoot - Project root
65
+ * @param {string} filePath - File path
66
+ * @param {string} newContent - New content
67
+ * @param {string} oldContent - Old content (optional)
68
+ * @returns {Object} Simulation result
69
+ */
70
+ quick(projectRoot, filePath, newContent, oldContent = null) {
71
+ return quickSimulate(projectRoot, filePath, newContent, oldContent);
72
+ },
73
+
74
+ /**
75
+ * Validate imports only
76
+ * @param {string} projectRoot - Project root
77
+ * @param {Array} changes - Change operations
78
+ * @returns {Object} Import validation result
79
+ */
80
+ validateImports(projectRoot, changes) {
81
+ const vfs = buildVirtualFS(projectRoot, changes);
82
+ return validateImportsAfterChanges(projectRoot, vfs);
83
+ },
84
+
85
+ /**
86
+ * Validate routes only
87
+ * @param {Array} existingRoutes - Current routes
88
+ * @param {Map} changedFiles - Changed files
89
+ * @param {Set} deletedFiles - Deleted files
90
+ * @returns {Object} Route validation result
91
+ */
92
+ validateRoutes(existingRoutes, changedFiles, deletedFiles) {
93
+ return validateRoutes(existingRoutes, changedFiles, deletedFiles);
94
+ },
95
+
96
+ /**
97
+ * Extract imports from content
98
+ * @param {string} content - File content
99
+ * @returns {Array} Imports
100
+ */
101
+ extractImports(content) {
102
+ return extractImports(content);
103
+ },
104
+
105
+ /**
106
+ * Extract exports from content
107
+ * @param {string} content - File content
108
+ * @returns {Array} Exports
109
+ */
110
+ extractExports(content) {
111
+ return extractExports(content);
112
+ },
113
+
114
+ /**
115
+ * Extract routes from content
116
+ * @param {string} content - File content
117
+ * @param {string} filePath - File path
118
+ * @returns {Array} Routes
119
+ */
120
+ extractRoutes(content, filePath) {
121
+ return extractRoutes(content, filePath);
122
+ },
123
+
124
+ /**
125
+ * Build import graph
126
+ * @param {Map} files - File map
127
+ * @param {string} projectRoot - Project root
128
+ * @returns {Object} Import graph
129
+ */
130
+ buildImportGraph(files, projectRoot) {
131
+ return buildImportGraph(files, projectRoot);
132
+ },
133
+
134
+ /**
135
+ * Detect circular dependencies
136
+ * @param {Array} edges - Graph edges
137
+ * @returns {Array} Cycles found
138
+ */
139
+ detectCircularDeps(edges) {
140
+ return detectCircularDeps(edges);
141
+ },
142
+
143
+ /**
144
+ * Format result for display
145
+ * @param {Object} result - Simulation result
146
+ * @returns {string} Formatted output
147
+ */
148
+ format(result) {
149
+ return formatResult(result);
150
+ },
151
+
152
+ /**
153
+ * Build virtual file system from changes
154
+ * @param {string} projectRoot - Project root
155
+ * @param {Array} changes - Changes
156
+ * @returns {Object} Virtual FS state
157
+ */
158
+ buildVirtualFS(projectRoot, changes) {
159
+ return buildVirtualFS(projectRoot, changes);
160
+ },
161
+ };
162
+
163
+ module.exports = {
164
+ simulator,
165
+ // Direct exports
166
+ simulate,
167
+ quickSimulate,
168
+ buildVirtualFS,
169
+ validateImportsAfterChanges,
170
+ detectOrphanedFiles,
171
+ formatResult,
172
+ extractImports,
173
+ extractExports,
174
+ resolveImportPath,
175
+ validateImport,
176
+ buildImportGraph,
177
+ detectCircularDeps,
178
+ extractRoutes,
179
+ validateRoutes,
180
+ findRouteReferences,
181
+ };