@vibecheckai/cli 3.4.0 → 3.5.1

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 (228) hide show
  1. package/bin/registry.js +154 -338
  2. package/bin/runners/context/generators/mcp.js +13 -15
  3. package/bin/runners/context/proof-context.js +1 -248
  4. package/bin/runners/lib/analysis-core.js +180 -198
  5. package/bin/runners/lib/analyzers.js +223 -1669
  6. package/bin/runners/lib/cli-output.js +210 -242
  7. package/bin/runners/lib/detectors-v2.js +785 -547
  8. package/bin/runners/lib/entitlements-v2.js +458 -96
  9. package/bin/runners/lib/error-handler.js +9 -16
  10. package/bin/runners/lib/global-flags.js +0 -37
  11. package/bin/runners/lib/route-truth.js +322 -1167
  12. package/bin/runners/lib/scan-output.js +469 -448
  13. package/bin/runners/lib/ship-output.js +27 -280
  14. package/bin/runners/lib/terminal-ui.js +733 -231
  15. package/bin/runners/lib/truth.js +321 -1004
  16. package/bin/runners/lib/unified-output.js +158 -162
  17. package/bin/runners/lib/upsell.js +204 -104
  18. package/bin/runners/runAllowlist.js +324 -0
  19. package/bin/runners/runAuth.js +95 -324
  20. package/bin/runners/runCheckpoint.js +21 -39
  21. package/bin/runners/runContext.js +24 -136
  22. package/bin/runners/runDoctor.js +67 -115
  23. package/bin/runners/runEvidencePack.js +219 -0
  24. package/bin/runners/runFix.js +5 -6
  25. package/bin/runners/runGuard.js +118 -212
  26. package/bin/runners/runInit.js +2 -14
  27. package/bin/runners/runInstall.js +281 -0
  28. package/bin/runners/runLabs.js +341 -0
  29. package/bin/runners/runMcp.js +52 -130
  30. package/bin/runners/runPolish.js +20 -43
  31. package/bin/runners/runProve.js +3 -13
  32. package/bin/runners/runReality.js +0 -14
  33. package/bin/runners/runReport.js +2 -3
  34. package/bin/runners/runScan.js +44 -511
  35. package/bin/runners/runShip.js +14 -28
  36. package/bin/runners/runValidate.js +2 -19
  37. package/bin/runners/runWatch.js +54 -118
  38. package/bin/vibecheck.js +41 -148
  39. package/mcp-server/ARCHITECTURE.md +339 -0
  40. package/mcp-server/__tests__/cache.test.ts +313 -0
  41. package/mcp-server/__tests__/executor.test.ts +239 -0
  42. package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +1 -0
  43. package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +3 -0
  44. package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +3 -0
  45. package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +3 -0
  46. package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +3 -0
  47. package/mcp-server/__tests__/fixtures/exclusion-test/package.json +5 -0
  48. package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +5 -0
  49. package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +4 -0
  50. package/mcp-server/__tests__/ids.test.ts +345 -0
  51. package/mcp-server/__tests__/integration/tools.test.ts +410 -0
  52. package/mcp-server/__tests__/registry.test.ts +365 -0
  53. package/mcp-server/__tests__/sandbox.test.ts +323 -0
  54. package/mcp-server/__tests__/schemas.test.ts +372 -0
  55. package/mcp-server/benchmarks/run-benchmarks.ts +304 -0
  56. package/mcp-server/examples/doctor.request.json +14 -0
  57. package/mcp-server/examples/doctor.response.json +53 -0
  58. package/mcp-server/examples/error.response.json +15 -0
  59. package/mcp-server/examples/scan.request.json +14 -0
  60. package/mcp-server/examples/scan.response.json +108 -0
  61. package/mcp-server/handlers/tool-handler.ts +671 -0
  62. package/mcp-server/index-v3.ts +293 -0
  63. package/mcp-server/index.js +1072 -1573
  64. package/mcp-server/index.old.js +4137 -0
  65. package/mcp-server/lib/cache.ts +341 -0
  66. package/mcp-server/lib/errors.ts +346 -0
  67. package/mcp-server/lib/executor.ts +792 -0
  68. package/mcp-server/lib/ids.ts +238 -0
  69. package/mcp-server/lib/logger.ts +368 -0
  70. package/mcp-server/lib/metrics.ts +365 -0
  71. package/mcp-server/lib/sandbox.ts +337 -0
  72. package/mcp-server/lib/validator.ts +229 -0
  73. package/mcp-server/package-lock.json +165 -0
  74. package/mcp-server/package.json +32 -7
  75. package/mcp-server/premium-tools.js +2 -2
  76. package/mcp-server/registry/tools.json +476 -0
  77. package/mcp-server/schemas/error-envelope.schema.json +125 -0
  78. package/mcp-server/schemas/finding.schema.json +167 -0
  79. package/mcp-server/schemas/report-artifact.schema.json +88 -0
  80. package/mcp-server/schemas/run-request.schema.json +75 -0
  81. package/mcp-server/schemas/verdict.schema.json +168 -0
  82. package/mcp-server/tier-auth.d.ts +71 -0
  83. package/mcp-server/tier-auth.js +371 -183
  84. package/mcp-server/truth-context.js +90 -131
  85. package/mcp-server/truth-firewall-tools.js +1000 -1611
  86. package/mcp-server/tsconfig.json +34 -0
  87. package/mcp-server/vibecheck-tools.js +2 -2
  88. package/mcp-server/vitest.config.ts +16 -0
  89. package/package.json +3 -4
  90. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +0 -474
  91. package/bin/runners/lib/agent-firewall/change-packet/builder.js +0 -488
  92. package/bin/runners/lib/agent-firewall/change-packet/schema.json +0 -228
  93. package/bin/runners/lib/agent-firewall/change-packet/store.js +0 -200
  94. package/bin/runners/lib/agent-firewall/claims/claim-types.js +0 -21
  95. package/bin/runners/lib/agent-firewall/claims/extractor.js +0 -303
  96. package/bin/runners/lib/agent-firewall/claims/patterns.js +0 -24
  97. package/bin/runners/lib/agent-firewall/critic/index.js +0 -151
  98. package/bin/runners/lib/agent-firewall/critic/judge.js +0 -432
  99. package/bin/runners/lib/agent-firewall/critic/prompts.js +0 -305
  100. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +0 -88
  101. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +0 -75
  102. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +0 -127
  103. package/bin/runners/lib/agent-firewall/evidence/resolver.js +0 -102
  104. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +0 -213
  105. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +0 -145
  106. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +0 -19
  107. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +0 -87
  108. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +0 -184
  109. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +0 -163
  110. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +0 -107
  111. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +0 -68
  112. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +0 -66
  113. package/bin/runners/lib/agent-firewall/interceptor/base.js +0 -304
  114. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +0 -35
  115. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +0 -35
  116. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +0 -34
  117. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +0 -465
  118. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +0 -604
  119. package/bin/runners/lib/agent-firewall/lawbook/index.js +0 -304
  120. package/bin/runners/lib/agent-firewall/lawbook/registry.js +0 -514
  121. package/bin/runners/lib/agent-firewall/lawbook/schema.js +0 -420
  122. package/bin/runners/lib/agent-firewall/logger.js +0 -141
  123. package/bin/runners/lib/agent-firewall/policy/default-policy.json +0 -90
  124. package/bin/runners/lib/agent-firewall/policy/engine.js +0 -103
  125. package/bin/runners/lib/agent-firewall/policy/loader.js +0 -451
  126. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +0 -50
  127. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +0 -50
  128. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +0 -86
  129. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +0 -162
  130. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +0 -189
  131. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +0 -93
  132. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +0 -57
  133. package/bin/runners/lib/agent-firewall/policy/schema.json +0 -183
  134. package/bin/runners/lib/agent-firewall/policy/verdict.js +0 -54
  135. package/bin/runners/lib/agent-firewall/proposal/extractor.js +0 -394
  136. package/bin/runners/lib/agent-firewall/proposal/index.js +0 -212
  137. package/bin/runners/lib/agent-firewall/proposal/schema.js +0 -251
  138. package/bin/runners/lib/agent-firewall/proposal/validator.js +0 -386
  139. package/bin/runners/lib/agent-firewall/reality/index.js +0 -332
  140. package/bin/runners/lib/agent-firewall/reality/state.js +0 -625
  141. package/bin/runners/lib/agent-firewall/reality/watcher.js +0 -322
  142. package/bin/runners/lib/agent-firewall/risk/index.js +0 -173
  143. package/bin/runners/lib/agent-firewall/risk/scorer.js +0 -328
  144. package/bin/runners/lib/agent-firewall/risk/thresholds.js +0 -321
  145. package/bin/runners/lib/agent-firewall/risk/vectors.js +0 -421
  146. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +0 -472
  147. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +0 -346
  148. package/bin/runners/lib/agent-firewall/simulator/index.js +0 -181
  149. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +0 -380
  150. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +0 -661
  151. package/bin/runners/lib/agent-firewall/time-machine/index.js +0 -267
  152. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +0 -436
  153. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +0 -490
  154. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +0 -530
  155. package/bin/runners/lib/agent-firewall/truthpack/index.js +0 -67
  156. package/bin/runners/lib/agent-firewall/truthpack/loader.js +0 -137
  157. package/bin/runners/lib/agent-firewall/unblock/planner.js +0 -337
  158. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +0 -118
  159. package/bin/runners/lib/api-client.js +0 -269
  160. package/bin/runners/lib/authority-badge.js +0 -425
  161. package/bin/runners/lib/engines/accessibility-engine.js +0 -190
  162. package/bin/runners/lib/engines/api-consistency-engine.js +0 -162
  163. package/bin/runners/lib/engines/ast-cache.js +0 -99
  164. package/bin/runners/lib/engines/code-quality-engine.js +0 -255
  165. package/bin/runners/lib/engines/console-logs-engine.js +0 -115
  166. package/bin/runners/lib/engines/cross-file-analysis-engine.js +0 -268
  167. package/bin/runners/lib/engines/dead-code-engine.js +0 -198
  168. package/bin/runners/lib/engines/deprecated-api-engine.js +0 -226
  169. package/bin/runners/lib/engines/empty-catch-engine.js +0 -150
  170. package/bin/runners/lib/engines/file-filter.js +0 -131
  171. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +0 -251
  172. package/bin/runners/lib/engines/mock-data-engine.js +0 -272
  173. package/bin/runners/lib/engines/parallel-processor.js +0 -71
  174. package/bin/runners/lib/engines/performance-issues-engine.js +0 -265
  175. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +0 -243
  176. package/bin/runners/lib/engines/todo-fixme-engine.js +0 -115
  177. package/bin/runners/lib/engines/type-aware-engine.js +0 -152
  178. package/bin/runners/lib/engines/unsafe-regex-engine.js +0 -225
  179. package/bin/runners/lib/engines/vibecheck-engines/README.md +0 -53
  180. package/bin/runners/lib/engines/vibecheck-engines/index.js +0 -15
  181. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
  182. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
  183. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
  184. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
  185. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
  186. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
  187. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
  188. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +0 -139
  189. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
  190. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
  191. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
  192. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
  193. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
  194. package/bin/runners/lib/engines/vibecheck-engines/package.json +0 -13
  195. package/bin/runners/lib/exit-codes.js +0 -275
  196. package/bin/runners/lib/fingerprint.js +0 -377
  197. package/bin/runners/lib/help-formatter.js +0 -413
  198. package/bin/runners/lib/logger.js +0 -38
  199. package/bin/runners/lib/ship-output-enterprise.js +0 -239
  200. package/bin/runners/lib/unified-cli-output.js +0 -604
  201. package/bin/runners/runAgent.d.ts +0 -5
  202. package/bin/runners/runAgent.js +0 -161
  203. package/bin/runners/runApprove.js +0 -1200
  204. package/bin/runners/runClassify.js +0 -859
  205. package/bin/runners/runContext.d.ts +0 -4
  206. package/bin/runners/runFirewall.d.ts +0 -5
  207. package/bin/runners/runFirewall.js +0 -134
  208. package/bin/runners/runFirewallHook.d.ts +0 -5
  209. package/bin/runners/runFirewallHook.js +0 -56
  210. package/bin/runners/runPolish.d.ts +0 -4
  211. package/bin/runners/runProof.zip +0 -0
  212. package/bin/runners/runTruth.d.ts +0 -5
  213. package/bin/runners/runTruth.js +0 -101
  214. package/mcp-server/HARDENING_SUMMARY.md +0 -299
  215. package/mcp-server/agent-firewall-interceptor.js +0 -500
  216. package/mcp-server/authority-tools.js +0 -569
  217. package/mcp-server/conductor/conflict-resolver.js +0 -588
  218. package/mcp-server/conductor/execution-planner.js +0 -544
  219. package/mcp-server/conductor/index.js +0 -377
  220. package/mcp-server/conductor/lock-manager.js +0 -615
  221. package/mcp-server/conductor/request-queue.js +0 -550
  222. package/mcp-server/conductor/session-manager.js +0 -500
  223. package/mcp-server/conductor/tools.js +0 -510
  224. package/mcp-server/lib/api-client.cjs +0 -13
  225. package/mcp-server/lib/logger.cjs +0 -30
  226. package/mcp-server/logger.js +0 -173
  227. package/mcp-server/tools-v3.js +0 -706
  228. package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
@@ -1,267 +0,0 @@
1
- /**
2
- * Time Machine Module
3
- *
4
- * Forensic Replay for AI Actions
5
- * Enables deep analysis and replay of what AI agents did.
6
- *
7
- * Codename: Time Machine
8
- */
9
-
10
- "use strict";
11
-
12
- const { ReplayEngine, createReplayEngine } = require("./replay-engine.js");
13
- const { TimelineBuilder, createTimelineBuilder, EVENT_TYPES } = require("./timeline-builder.js");
14
- const { StateReconstructor, createStateReconstructor } = require("./state-reconstructor.js");
15
- const { IncidentCorrelator, createIncidentCorrelator, RELATIONSHIP_TYPES } = require("./incident-correlator.js");
16
-
17
- /**
18
- * Time Machine singleton for unified access
19
- */
20
- class TimeMachine {
21
- constructor() {
22
- this.replayEngine = null;
23
- this.timelineBuilder = null;
24
- this.stateReconstructor = null;
25
- this.incidentCorrelator = null;
26
- this.projectRoot = null;
27
- this.initialized = false;
28
- }
29
-
30
- /**
31
- * Initialize the Time Machine for a project
32
- * @param {string} projectRoot - Project root directory
33
- * @returns {TimeMachine} This instance
34
- */
35
- init(projectRoot) {
36
- if (this.initialized && this.projectRoot === projectRoot) {
37
- return this;
38
- }
39
-
40
- this.projectRoot = projectRoot;
41
- this.replayEngine = createReplayEngine({ projectRoot });
42
- this.timelineBuilder = createTimelineBuilder({ projectRoot });
43
- this.stateReconstructor = createStateReconstructor({ projectRoot });
44
- this.incidentCorrelator = createIncidentCorrelator({ projectRoot });
45
- this.initialized = true;
46
-
47
- return this;
48
- }
49
-
50
- /**
51
- * Start a replay session
52
- * @param {Object} options - Replay options
53
- * @returns {Object} Replay session
54
- */
55
- async startReplay(options = {}) {
56
- this.ensureInitialized();
57
- return this.replayEngine.startReplay(options);
58
- }
59
-
60
- /**
61
- * Get current snapshot in a replay session
62
- * @param {string} sessionId - Session ID
63
- * @returns {Object|null} Current snapshot
64
- */
65
- getCurrentSnapshot(sessionId) {
66
- this.ensureInitialized();
67
- return this.replayEngine.getCurrentSnapshot(sessionId);
68
- }
69
-
70
- /**
71
- * Move to next snapshot
72
- * @param {string} sessionId - Session ID
73
- * @returns {Object|null} Next snapshot
74
- */
75
- nextSnapshot(sessionId) {
76
- this.ensureInitialized();
77
- return this.replayEngine.nextSnapshot(sessionId);
78
- }
79
-
80
- /**
81
- * Move to previous snapshot
82
- * @param {string} sessionId - Session ID
83
- * @returns {Object|null} Previous snapshot
84
- */
85
- previousSnapshot(sessionId) {
86
- this.ensureInitialized();
87
- return this.replayEngine.previousSnapshot(sessionId);
88
- }
89
-
90
- /**
91
- * Get replay session status
92
- * @param {string} sessionId - Session ID
93
- * @returns {Object|null} Session status
94
- */
95
- getSessionStatus(sessionId) {
96
- this.ensureInitialized();
97
- return this.replayEngine.getSessionStatus(sessionId);
98
- }
99
-
100
- /**
101
- * End a replay session
102
- * @param {string} sessionId - Session ID
103
- */
104
- endReplay(sessionId) {
105
- this.ensureInitialized();
106
- this.replayEngine.endReplay(sessionId);
107
- }
108
-
109
- /**
110
- * Build a forensic timeline
111
- * @param {Object} options - Timeline options
112
- * @returns {Object} Forensic timeline
113
- */
114
- async buildTimeline(options = {}) {
115
- this.ensureInitialized();
116
- return this.timelineBuilder.buildTimeline(options);
117
- }
118
-
119
- /**
120
- * Generate a timeline report
121
- * @param {Object} timeline - Timeline to report on
122
- * @returns {Object} Report
123
- */
124
- generateReport(timeline) {
125
- this.ensureInitialized();
126
- return this.timelineBuilder.generateReport(timeline);
127
- }
128
-
129
- /**
130
- * Compare agent belief vs reality for a snapshot
131
- * @param {Object} snapshot - Snapshot to analyze
132
- * @returns {Object} Comparison result
133
- */
134
- compareBeliefVsReality(snapshot) {
135
- this.ensureInitialized();
136
- return this.replayEngine.compareBeliefVsReality(snapshot);
137
- }
138
-
139
- /**
140
- * Quick replay for an incident
141
- * @param {string} incidentId - Incident ID
142
- * @param {Object} options - Additional options
143
- * @returns {Object} Replay result with timeline
144
- */
145
- async replayIncident(incidentId, options = {}) {
146
- this.ensureInitialized();
147
-
148
- // Build timeline for the incident
149
- const timeline = await this.buildTimeline({
150
- ...options,
151
- includeIncidents: true,
152
- });
153
-
154
- // Find the incident
155
- const incidentEvent = timeline.events.find(
156
- e => e.id === incidentId || e.details?.incidentId === incidentId
157
- );
158
-
159
- if (!incidentEvent) {
160
- return {
161
- success: false,
162
- error: "Incident not found",
163
- };
164
- }
165
-
166
- // Start replay from before the incident
167
- const incidentTime = new Date(incidentEvent.timestamp);
168
- const lookbackMs = options.lookbackMs || 24 * 60 * 60 * 1000; // 24 hours default
169
-
170
- const session = await this.startReplay({
171
- startTime: new Date(incidentTime.getTime() - lookbackMs),
172
- endTime: incidentTime,
173
- ...options,
174
- });
175
-
176
- return {
177
- success: true,
178
- session,
179
- timeline,
180
- incident: incidentEvent,
181
- rootCause: timeline.rootCause,
182
- causalChain: timeline.causalChain,
183
- };
184
- }
185
-
186
- /**
187
- * Reconstruct state at a specific timestamp
188
- * @param {Date} timestamp - Target timestamp
189
- * @param {Object} options - Options
190
- * @returns {Object} Reconstructed state
191
- */
192
- async reconstructState(timestamp, options = {}) {
193
- this.ensureInitialized();
194
- return this.stateReconstructor.reconstructState(timestamp, options);
195
- }
196
-
197
- /**
198
- * Record a new incident
199
- * @param {Object} incidentData - Incident data
200
- * @returns {Object} Created incident
201
- */
202
- recordIncident(incidentData) {
203
- this.ensureInitialized();
204
- return this.incidentCorrelator.recordIncident(incidentData);
205
- }
206
-
207
- /**
208
- * Correlate an incident with firewall events
209
- * @param {string} incidentId - Incident ID
210
- * @param {Object} options - Options
211
- * @returns {Object} Incident report
212
- */
213
- async correlateIncident(incidentId, options = {}) {
214
- this.ensureInitialized();
215
- return this.incidentCorrelator.correlateIncident(incidentId, options);
216
- }
217
-
218
- /**
219
- * Get all recorded incidents
220
- * @returns {Object[]} All incidents
221
- */
222
- getAllIncidents() {
223
- this.ensureInitialized();
224
- return this.incidentCorrelator.getAllIncidents();
225
- }
226
-
227
- /**
228
- * Create a snapshot of current state
229
- * @param {string} snapshotId - Optional snapshot ID
230
- * @returns {string} Snapshot ID
231
- */
232
- async createSnapshot(snapshotId = null) {
233
- this.ensureInitialized();
234
- return this.stateReconstructor.createSnapshot(snapshotId);
235
- }
236
-
237
- /**
238
- * Ensure Time Machine is initialized
239
- */
240
- ensureInitialized() {
241
- if (!this.initialized) {
242
- throw new Error("Time Machine not initialized. Call timeMachine.init(projectRoot) first.");
243
- }
244
- }
245
- }
246
-
247
- // Singleton instance
248
- const timeMachine = new TimeMachine();
249
-
250
- module.exports = {
251
- timeMachine,
252
- TimeMachine,
253
- // Replay Engine
254
- ReplayEngine,
255
- createReplayEngine,
256
- // Timeline Builder
257
- TimelineBuilder,
258
- createTimelineBuilder,
259
- EVENT_TYPES,
260
- // State Reconstructor
261
- StateReconstructor,
262
- createStateReconstructor,
263
- // Incident Correlator
264
- IncidentCorrelator,
265
- createIncidentCorrelator,
266
- RELATIONSHIP_TYPES,
267
- };
@@ -1,436 +0,0 @@
1
- /**
2
- * Time Machine Replay Engine
3
- *
4
- * Reconstructs codebase state at any point in time.
5
- * Enables forensic analysis of AI agent actions.
6
- *
7
- * Codename: Time Machine
8
- */
9
-
10
- "use strict";
11
-
12
- const fs = require("fs");
13
- const path = require("path");
14
- const { timeMachineLogger: log, getErrorMessage } = require("../logger.js");
15
-
16
- /**
17
- * @typedef {Object} ReplaySnapshot
18
- * @property {string} snapshotId - Unique snapshot ID
19
- * @property {Date} timestamp - Point in time
20
- * @property {Object} realityState - What the repo actually was
21
- * @property {Object} agentBelief - What the agent assumed
22
- * @property {Object} proposal - The change proposal
23
- * @property {Object} verdict - The verdict issued
24
- * @property {Object} [overrideContext] - Override info if applicable
25
- */
26
-
27
- /**
28
- * @typedef {Object} ReplaySession
29
- * @property {string} sessionId - Replay session ID
30
- * @property {Date} startTime - When replay started
31
- * @property {Date} targetTime - Point being replayed
32
- * @property {ReplaySnapshot[]} snapshots - Snapshots in this session
33
- * @property {number} currentIndex - Current position in replay
34
- */
35
-
36
- /**
37
- * Replay Engine class
38
- */
39
- class ReplayEngine {
40
- constructor(options = {}) {
41
- this.projectRoot = options.projectRoot || process.cwd();
42
- this.packetsDir = path.join(this.projectRoot, ".vibecheck", "packets");
43
- this.auditDir = path.join(this.projectRoot, ".vibecheck", "audit");
44
- this.snapshotsDir = path.join(this.projectRoot, ".vibecheck", "snapshots");
45
- this.sessions = new Map();
46
- this.packetCache = new Map();
47
- }
48
-
49
- /**
50
- * Start a replay session for a specific time range
51
- * @param {Object} options - Replay options
52
- * @returns {ReplaySession} Replay session
53
- */
54
- async startReplay(options = {}) {
55
- const {
56
- startTime,
57
- endTime = new Date(),
58
- agentId = null,
59
- file = null,
60
- incidentId = null,
61
- } = options;
62
-
63
- const sessionId = `replay_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
64
-
65
- // Load relevant packets
66
- const packets = await this.loadPackets({
67
- startTime,
68
- endTime,
69
- agentId,
70
- file,
71
- });
72
-
73
- // Build snapshots from packets
74
- const snapshots = await this.buildSnapshots(packets);
75
-
76
- const session = {
77
- sessionId,
78
- startTime: new Date(),
79
- targetTime: startTime,
80
- options,
81
- snapshots,
82
- currentIndex: 0,
83
- totalSnapshots: snapshots.length,
84
- };
85
-
86
- this.sessions.set(sessionId, session);
87
-
88
- return session;
89
- }
90
-
91
- /**
92
- * Load change packets for a time range
93
- * @param {Object} filters - Filter options
94
- * @returns {Object[]} Change packets
95
- */
96
- async loadPackets(filters = {}) {
97
- const packets = [];
98
-
99
- if (!fs.existsSync(this.packetsDir)) {
100
- return packets;
101
- }
102
-
103
- const files = fs.readdirSync(this.packetsDir)
104
- .filter(f => f.endsWith(".json"))
105
- .sort();
106
-
107
- for (const file of files) {
108
- try {
109
- const content = fs.readFileSync(path.join(this.packetsDir, file), "utf-8");
110
- const packet = JSON.parse(content);
111
-
112
- // Apply time filter
113
- const packetTime = new Date(packet.timestamp || packet.createdAt);
114
-
115
- if (filters.startTime && packetTime < new Date(filters.startTime)) {
116
- continue;
117
- }
118
-
119
- if (filters.endTime && packetTime > new Date(filters.endTime)) {
120
- continue;
121
- }
122
-
123
- // Apply agent filter
124
- if (filters.agentId && packet.agentId !== filters.agentId) {
125
- continue;
126
- }
127
-
128
- // Apply file filter
129
- if (filters.file) {
130
- const affectedFiles = this.extractAffectedFiles(packet);
131
- if (!affectedFiles.some(f => f.includes(filters.file))) {
132
- continue;
133
- }
134
- }
135
-
136
- packets.push(packet);
137
- } catch (error) {
138
- log.warn(`Failed to load packet ${file}: ${getErrorMessage(error)}`);
139
- }
140
- }
141
-
142
- // Sort by timestamp
143
- packets.sort((a, b) => {
144
- const timeA = new Date(a.timestamp || a.createdAt).getTime();
145
- const timeB = new Date(b.timestamp || b.createdAt).getTime();
146
- return timeA - timeB;
147
- });
148
-
149
- return packets;
150
- }
151
-
152
- /**
153
- * Extract affected files from a packet
154
- * @param {Object} packet - Change packet
155
- * @returns {string[]} Affected file paths
156
- */
157
- extractAffectedFiles(packet) {
158
- const files = [];
159
-
160
- if (packet.file) files.push(packet.file);
161
- if (packet.filePath) files.push(packet.filePath);
162
-
163
- for (const op of packet.operations || []) {
164
- if (op.path) files.push(op.path);
165
- if (op.file) files.push(op.file);
166
- if (op.filePath) files.push(op.filePath);
167
- }
168
-
169
- return files;
170
- }
171
-
172
- /**
173
- * Build replay snapshots from packets
174
- * @param {Object[]} packets - Change packets
175
- * @returns {ReplaySnapshot[]} Replay snapshots
176
- */
177
- async buildSnapshots(packets) {
178
- const snapshots = [];
179
-
180
- for (const packet of packets) {
181
- const snapshot = {
182
- snapshotId: packet.id || `snap_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
183
- timestamp: new Date(packet.timestamp || packet.createdAt),
184
- realityState: await this.extractRealityState(packet),
185
- agentBelief: this.extractAgentBelief(packet),
186
- proposal: this.extractProposal(packet),
187
- verdict: this.extractVerdict(packet),
188
- overrideContext: this.extractOverrideContext(packet),
189
- metadata: {
190
- agentId: packet.agentId,
191
- sessionId: packet.sessionId,
192
- file: packet.file || this.extractAffectedFiles(packet)[0],
193
- },
194
- };
195
-
196
- snapshots.push(snapshot);
197
- }
198
-
199
- return snapshots;
200
- }
201
-
202
- /**
203
- * Extract reality state from a packet
204
- * @param {Object} packet - Change packet
205
- * @returns {Object} Reality state
206
- */
207
- async extractRealityState(packet) {
208
- // Try to load from proof artifact
209
- if (packet.proof?.realitySnapshot) {
210
- return packet.proof.realitySnapshot;
211
- }
212
-
213
- // Build from packet data
214
- return {
215
- files: this.extractAffectedFiles(packet).map(f => ({
216
- path: f,
217
- exists: true, // Would need historical data to verify
218
- })),
219
- timestamp: packet.timestamp || packet.createdAt,
220
- };
221
- }
222
-
223
- /**
224
- * Extract what the agent believed/assumed
225
- * @param {Object} packet - Change packet
226
- * @returns {Object} Agent belief state
227
- */
228
- extractAgentBelief(packet) {
229
- const assumptions = packet.assumptions || packet.proposal?.assumptions || [];
230
-
231
- return {
232
- assumptions: assumptions.map(a => ({
233
- type: a.type,
234
- target: a.target || a.path,
235
- expectedValue: a.expectedValue || a.value,
236
- wasValid: a.valid !== undefined ? a.valid : null,
237
- })),
238
- confidence: packet.confidence || packet.proposal?.confidence,
239
- intent: packet.intent || packet.proposal?.intent,
240
- };
241
- }
242
-
243
- /**
244
- * Extract the proposal from a packet
245
- * @param {Object} packet - Change packet
246
- * @returns {Object} Proposal
247
- */
248
- extractProposal(packet) {
249
- return {
250
- proposalId: packet.proposalId || packet.id,
251
- intent: packet.intent || packet.proposal?.intent,
252
- operations: packet.operations || packet.proposal?.operations || [],
253
- summary: packet.summary || packet.proposal?.summary,
254
- };
255
- }
256
-
257
- /**
258
- * Extract the verdict from a packet
259
- * @param {Object} packet - Change packet
260
- * @returns {Object} Verdict
261
- */
262
- extractVerdict(packet) {
263
- return {
264
- decision: packet.verdict?.decision || packet.proof?.decision || packet.decision,
265
- confidence: packet.verdict?.confidence || packet.proof?.confidence,
266
- rulesTriggered: packet.verdict?.rulesTriggered || packet.proof?.rulesTriggered || [],
267
- riskScore: packet.riskScore || packet.proof?.riskScore,
268
- riskLevel: packet.riskLevel || packet.proof?.riskLevel,
269
- };
270
- }
271
-
272
- /**
273
- * Extract override context if any
274
- * @param {Object} packet - Change packet
275
- * @returns {Object|null} Override context
276
- */
277
- extractOverrideContext(packet) {
278
- if (!packet.proof?.overrideUsed && !packet.override?.used) {
279
- return null;
280
- }
281
-
282
- return {
283
- used: true,
284
- by: packet.proof?.overrideBy || packet.override?.by,
285
- reason: packet.proof?.overrideReason || packet.override?.reason,
286
- timestamp: packet.proof?.overrideTimestamp || packet.override?.timestamp,
287
- };
288
- }
289
-
290
- /**
291
- * Get the current snapshot in a replay session
292
- * @param {string} sessionId - Session ID
293
- * @returns {ReplaySnapshot|null} Current snapshot
294
- */
295
- getCurrentSnapshot(sessionId) {
296
- const session = this.sessions.get(sessionId);
297
- if (!session) return null;
298
-
299
- return session.snapshots[session.currentIndex] || null;
300
- }
301
-
302
- /**
303
- * Move to the next snapshot
304
- * @param {string} sessionId - Session ID
305
- * @returns {ReplaySnapshot|null} Next snapshot or null if at end
306
- */
307
- nextSnapshot(sessionId) {
308
- const session = this.sessions.get(sessionId);
309
- if (!session) return null;
310
-
311
- if (session.currentIndex < session.snapshots.length - 1) {
312
- session.currentIndex++;
313
- return session.snapshots[session.currentIndex];
314
- }
315
-
316
- return null;
317
- }
318
-
319
- /**
320
- * Move to the previous snapshot
321
- * @param {string} sessionId - Session ID
322
- * @returns {ReplaySnapshot|null} Previous snapshot or null if at start
323
- */
324
- previousSnapshot(sessionId) {
325
- const session = this.sessions.get(sessionId);
326
- if (!session) return null;
327
-
328
- if (session.currentIndex > 0) {
329
- session.currentIndex--;
330
- return session.snapshots[session.currentIndex];
331
- }
332
-
333
- return null;
334
- }
335
-
336
- /**
337
- * Jump to a specific snapshot index
338
- * @param {string} sessionId - Session ID
339
- * @param {number} index - Index to jump to
340
- * @returns {ReplaySnapshot|null} Snapshot at index
341
- */
342
- jumpToSnapshot(sessionId, index) {
343
- const session = this.sessions.get(sessionId);
344
- if (!session) return null;
345
-
346
- if (index >= 0 && index < session.snapshots.length) {
347
- session.currentIndex = index;
348
- return session.snapshots[index];
349
- }
350
-
351
- return null;
352
- }
353
-
354
- /**
355
- * Get session status
356
- * @param {string} sessionId - Session ID
357
- * @returns {Object|null} Session status
358
- */
359
- getSessionStatus(sessionId) {
360
- const session = this.sessions.get(sessionId);
361
- if (!session) return null;
362
-
363
- return {
364
- sessionId: session.sessionId,
365
- totalSnapshots: session.totalSnapshots,
366
- currentIndex: session.currentIndex,
367
- currentSnapshot: session.snapshots[session.currentIndex],
368
- isAtStart: session.currentIndex === 0,
369
- isAtEnd: session.currentIndex === session.snapshots.length - 1,
370
- progress: session.totalSnapshots > 0
371
- ? Math.round((session.currentIndex / (session.totalSnapshots - 1)) * 100)
372
- : 100,
373
- };
374
- }
375
-
376
- /**
377
- * End a replay session
378
- * @param {string} sessionId - Session ID
379
- */
380
- endReplay(sessionId) {
381
- this.sessions.delete(sessionId);
382
- }
383
-
384
- /**
385
- * Get all active replay sessions
386
- * @returns {Object[]} Active sessions
387
- */
388
- getActiveSessions() {
389
- return Array.from(this.sessions.values()).map(s => ({
390
- sessionId: s.sessionId,
391
- startTime: s.startTime,
392
- targetTime: s.targetTime,
393
- totalSnapshots: s.totalSnapshots,
394
- currentIndex: s.currentIndex,
395
- }));
396
- }
397
-
398
- /**
399
- * Compare what agent believed vs what was true
400
- * @param {ReplaySnapshot} snapshot - Snapshot to analyze
401
- * @returns {Object} Comparison result
402
- */
403
- compareBeliefVsReality(snapshot) {
404
- const discrepancies = [];
405
-
406
- for (const assumption of snapshot.agentBelief.assumptions || []) {
407
- if (assumption.wasValid === false) {
408
- discrepancies.push({
409
- type: assumption.type,
410
- target: assumption.target,
411
- expected: assumption.expectedValue,
412
- actual: "Did not match reality",
413
- severity: "error",
414
- });
415
- }
416
- }
417
-
418
- return {
419
- hadDiscrepancies: discrepancies.length > 0,
420
- discrepancies,
421
- confidence: snapshot.agentBelief.confidence,
422
- verdictIssued: snapshot.verdict.decision,
423
- };
424
- }
425
- }
426
-
427
- /**
428
- * Create a replay engine instance
429
- * @param {Object} options - Options
430
- * @returns {ReplayEngine} Replay engine
431
- */
432
- function createReplayEngine(options = {}) {
433
- return new ReplayEngine(options);
434
- }
435
-
436
- module.exports = { ReplayEngine, createReplayEngine };