context-mode 1.0.169 → 2.0.0-next.5

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 (379) hide show
  1. package/.claude-plugin/marketplace.json +4 -22
  2. package/.claude-plugin/plugin.json +9 -24
  3. package/SHA256SUMS +31 -0
  4. package/claude-code/skills/ctx-doctor/SKILL.md +6 -0
  5. package/claude-code/skills/ctx-stats/SKILL.md +6 -0
  6. package/claude-code/skills/ctx-upgrade/SKILL.md +6 -0
  7. package/cli.mjs +6744 -0
  8. package/copilot/plugin.json +14 -0
  9. package/fixtures/hook-roundtrip.json +22 -0
  10. package/gemini-extension.json +14 -0
  11. package/hook.mjs +202 -0
  12. package/hooks/claude-code.json +50 -0
  13. package/hooks/codex.json +50 -0
  14. package/hooks/copilot-cli.json +33 -0
  15. package/hooks/hooks.json +16 -111
  16. package/hooks/kiro.json +69 -0
  17. package/hooks/qwen.json +50 -0
  18. package/hooks/vscode.json +40 -0
  19. package/hooks/zcode.json +53 -0
  20. package/opencode/plugin.js +22456 -0
  21. package/package.json +29 -114
  22. package/pi/index.js +50841 -0
  23. package/pi/skills/ctx-doctor/SKILL.md +6 -0
  24. package/pi/skills/ctx-stats/SKILL.md +6 -0
  25. package/pi/skills/ctx-upgrade/SKILL.md +6 -0
  26. package/qwen-extension.json +15 -0
  27. package/run.mjs +5633 -0
  28. package/search.mjs +5633 -0
  29. package/server.mjs +48198 -0
  30. package/skills/ctx-doctor/SKILL.md +3 -19
  31. package/skills/ctx-stats/SKILL.md +3 -23
  32. package/skills/ctx-upgrade/SKILL.md +3 -28
  33. package/.codex-plugin/hooks.json +0 -65
  34. package/.codex-plugin/mcp.json +0 -13
  35. package/.codex-plugin/plugin.json +0 -31
  36. package/.openclaw-plugin/index.ts +0 -12
  37. package/.openclaw-plugin/openclaw.plugin.json +0 -38
  38. package/.openclaw-plugin/package.json +0 -28
  39. package/LICENSE +0 -94
  40. package/README.md +0 -1619
  41. package/bin/statusline.mjs +0 -378
  42. package/build/adapters/antigravity/index.d.ts +0 -51
  43. package/build/adapters/antigravity/index.js +0 -169
  44. package/build/adapters/antigravity-cli/index.d.ts +0 -51
  45. package/build/adapters/antigravity-cli/index.js +0 -342
  46. package/build/adapters/base.d.ts +0 -92
  47. package/build/adapters/base.js +0 -135
  48. package/build/adapters/claude-code/config.d.ts +0 -8
  49. package/build/adapters/claude-code/config.js +0 -8
  50. package/build/adapters/claude-code/hooks.d.ts +0 -106
  51. package/build/adapters/claude-code/hooks.js +0 -183
  52. package/build/adapters/claude-code/index.d.ts +0 -80
  53. package/build/adapters/claude-code/index.js +0 -569
  54. package/build/adapters/claude-code-base.d.ts +0 -49
  55. package/build/adapters/claude-code-base.js +0 -113
  56. package/build/adapters/client-map.d.ts +0 -10
  57. package/build/adapters/client-map.js +0 -42
  58. package/build/adapters/codex/config.d.ts +0 -8
  59. package/build/adapters/codex/config.js +0 -8
  60. package/build/adapters/codex/hooks.d.ts +0 -55
  61. package/build/adapters/codex/hooks.js +0 -64
  62. package/build/adapters/codex/index.d.ts +0 -87
  63. package/build/adapters/codex/index.js +0 -992
  64. package/build/adapters/codex/paths.d.ts +0 -1
  65. package/build/adapters/codex/paths.js +0 -12
  66. package/build/adapters/codex/usage.d.ts +0 -107
  67. package/build/adapters/codex/usage.js +0 -227
  68. package/build/adapters/copilot-base.d.ts +0 -94
  69. package/build/adapters/copilot-base.js +0 -297
  70. package/build/adapters/copilot-cli/hooks.d.ts +0 -33
  71. package/build/adapters/copilot-cli/hooks.js +0 -64
  72. package/build/adapters/copilot-cli/index.d.ts +0 -48
  73. package/build/adapters/copilot-cli/index.js +0 -341
  74. package/build/adapters/cursor/config.d.ts +0 -4
  75. package/build/adapters/cursor/config.js +0 -4
  76. package/build/adapters/cursor/hooks.d.ts +0 -55
  77. package/build/adapters/cursor/hooks.js +0 -82
  78. package/build/adapters/cursor/index.d.ts +0 -64
  79. package/build/adapters/cursor/index.js +0 -517
  80. package/build/adapters/detect.d.ts +0 -136
  81. package/build/adapters/detect.js +0 -623
  82. package/build/adapters/gemini-cli/config.d.ts +0 -8
  83. package/build/adapters/gemini-cli/config.js +0 -8
  84. package/build/adapters/gemini-cli/hooks.d.ts +0 -83
  85. package/build/adapters/gemini-cli/hooks.js +0 -115
  86. package/build/adapters/gemini-cli/index.d.ts +0 -80
  87. package/build/adapters/gemini-cli/index.js +0 -483
  88. package/build/adapters/jetbrains-copilot/config.d.ts +0 -8
  89. package/build/adapters/jetbrains-copilot/config.js +0 -8
  90. package/build/adapters/jetbrains-copilot/hooks.d.ts +0 -59
  91. package/build/adapters/jetbrains-copilot/hooks.js +0 -87
  92. package/build/adapters/jetbrains-copilot/index.d.ts +0 -31
  93. package/build/adapters/jetbrains-copilot/index.js +0 -131
  94. package/build/adapters/kimi/config.d.ts +0 -8
  95. package/build/adapters/kimi/config.js +0 -8
  96. package/build/adapters/kimi/hooks.d.ts +0 -28
  97. package/build/adapters/kimi/hooks.js +0 -34
  98. package/build/adapters/kimi/index.d.ts +0 -66
  99. package/build/adapters/kimi/index.js +0 -537
  100. package/build/adapters/kimi/paths.d.ts +0 -21
  101. package/build/adapters/kimi/paths.js +0 -52
  102. package/build/adapters/kimi/usage.d.ts +0 -82
  103. package/build/adapters/kimi/usage.js +0 -217
  104. package/build/adapters/kiro/hooks.d.ts +0 -61
  105. package/build/adapters/kiro/hooks.js +0 -94
  106. package/build/adapters/kiro/index.d.ts +0 -61
  107. package/build/adapters/kiro/index.js +0 -301
  108. package/build/adapters/omp/index.d.ts +0 -65
  109. package/build/adapters/omp/index.js +0 -182
  110. package/build/adapters/omp/plugin.d.ts +0 -81
  111. package/build/adapters/omp/plugin.js +0 -331
  112. package/build/adapters/omp/usage.d.ts +0 -49
  113. package/build/adapters/omp/usage.js +0 -110
  114. package/build/adapters/openclaw/config.d.ts +0 -8
  115. package/build/adapters/openclaw/config.js +0 -8
  116. package/build/adapters/openclaw/hooks.d.ts +0 -50
  117. package/build/adapters/openclaw/hooks.js +0 -61
  118. package/build/adapters/openclaw/index.d.ts +0 -74
  119. package/build/adapters/openclaw/index.js +0 -439
  120. package/build/adapters/openclaw/mcp-tools.d.ts +0 -54
  121. package/build/adapters/openclaw/mcp-tools.js +0 -207
  122. package/build/adapters/openclaw/plugin.d.ts +0 -141
  123. package/build/adapters/openclaw/plugin.js +0 -818
  124. package/build/adapters/openclaw/session-db.d.ts +0 -55
  125. package/build/adapters/openclaw/session-db.js +0 -88
  126. package/build/adapters/openclaw/usage.d.ts +0 -34
  127. package/build/adapters/openclaw/usage.js +0 -52
  128. package/build/adapters/openclaw/workspace-router.d.ts +0 -29
  129. package/build/adapters/openclaw/workspace-router.js +0 -64
  130. package/build/adapters/opencode/config.d.ts +0 -8
  131. package/build/adapters/opencode/config.js +0 -8
  132. package/build/adapters/opencode/hooks.d.ts +0 -38
  133. package/build/adapters/opencode/hooks.js +0 -50
  134. package/build/adapters/opencode/index.d.ts +0 -67
  135. package/build/adapters/opencode/index.js +0 -463
  136. package/build/adapters/opencode/plugin.d.ts +0 -184
  137. package/build/adapters/opencode/plugin.js +0 -558
  138. package/build/adapters/opencode/zod3tov4.d.ts +0 -1
  139. package/build/adapters/opencode/zod3tov4.js +0 -132
  140. package/build/adapters/pi/extension.d.ts +0 -81
  141. package/build/adapters/pi/extension.js +0 -861
  142. package/build/adapters/pi/index.d.ts +0 -57
  143. package/build/adapters/pi/index.js +0 -173
  144. package/build/adapters/pi/mcp-bridge.d.ts +0 -268
  145. package/build/adapters/pi/mcp-bridge.js +0 -894
  146. package/build/adapters/qwen-code/hooks.d.ts +0 -26
  147. package/build/adapters/qwen-code/hooks.js +0 -29
  148. package/build/adapters/qwen-code/index.d.ts +0 -40
  149. package/build/adapters/qwen-code/index.js +0 -361
  150. package/build/adapters/qwen-code/usage.d.ts +0 -90
  151. package/build/adapters/qwen-code/usage.js +0 -222
  152. package/build/adapters/types.d.ts +0 -360
  153. package/build/adapters/types.js +0 -118
  154. package/build/adapters/vscode-copilot/config.d.ts +0 -8
  155. package/build/adapters/vscode-copilot/config.js +0 -8
  156. package/build/adapters/vscode-copilot/hooks.d.ts +0 -71
  157. package/build/adapters/vscode-copilot/hooks.js +0 -98
  158. package/build/adapters/vscode-copilot/index.d.ts +0 -32
  159. package/build/adapters/vscode-copilot/index.js +0 -222
  160. package/build/adapters/zed/index.d.ts +0 -40
  161. package/build/adapters/zed/index.js +0 -163
  162. package/build/cli.d.ts +0 -34
  163. package/build/cli.js +0 -1827
  164. package/build/db-base.d.ts +0 -179
  165. package/build/db-base.js +0 -569
  166. package/build/executor.d.ts +0 -72
  167. package/build/executor.js +0 -678
  168. package/build/exit-classify.d.ts +0 -19
  169. package/build/exit-classify.js +0 -12
  170. package/build/fetch-cache.d.ts +0 -13
  171. package/build/fetch-cache.js +0 -15
  172. package/build/lifecycle.d.ts +0 -124
  173. package/build/lifecycle.js +0 -278
  174. package/build/runPool.d.ts +0 -36
  175. package/build/runPool.js +0 -51
  176. package/build/runtime.d.ts +0 -71
  177. package/build/runtime.js +0 -659
  178. package/build/search/auto-memory.d.ts +0 -47
  179. package/build/search/auto-memory.js +0 -170
  180. package/build/search/ctx-search-schema.d.ts +0 -90
  181. package/build/search/ctx-search-schema.js +0 -135
  182. package/build/search/flood-guard.d.ts +0 -57
  183. package/build/search/flood-guard.js +0 -80
  184. package/build/search/unified.d.ts +0 -56
  185. package/build/search/unified.js +0 -104
  186. package/build/security.d.ts +0 -206
  187. package/build/security.js +0 -780
  188. package/build/server.d.ts +0 -184
  189. package/build/server.js +0 -4563
  190. package/build/session/analytics.d.ts +0 -773
  191. package/build/session/analytics.js +0 -2420
  192. package/build/session/db.d.ts +0 -468
  193. package/build/session/db.js +0 -1308
  194. package/build/session/error-classifier.d.ts +0 -87
  195. package/build/session/error-classifier.js +0 -303
  196. package/build/session/event-emit.d.ts +0 -48
  197. package/build/session/event-emit.js +0 -101
  198. package/build/session/extract.d.ts +0 -333
  199. package/build/session/extract.js +0 -2688
  200. package/build/session/model-prices.json +0 -429
  201. package/build/session/persist-tool-calls.d.ts +0 -54
  202. package/build/session/persist-tool-calls.js +0 -105
  203. package/build/session/pricing.d.ts +0 -64
  204. package/build/session/pricing.js +0 -151
  205. package/build/session/project-attribution.d.ts +0 -73
  206. package/build/session/project-attribution.js +0 -245
  207. package/build/session/purge.d.ts +0 -138
  208. package/build/session/purge.js +0 -240
  209. package/build/session/retrieval-marker.d.ts +0 -39
  210. package/build/session/retrieval-marker.js +0 -65
  211. package/build/session/snapshot.d.ts +0 -46
  212. package/build/session/snapshot.js +0 -532
  213. package/build/store-directory.d.ts +0 -56
  214. package/build/store-directory.js +0 -254
  215. package/build/store.d.ts +0 -147
  216. package/build/store.js +0 -1714
  217. package/build/truncate.d.ts +0 -57
  218. package/build/truncate.js +0 -142
  219. package/build/types.d.ts +0 -117
  220. package/build/types.js +0 -20
  221. package/build/util/claude-config.d.ts +0 -32
  222. package/build/util/claude-config.js +0 -84
  223. package/build/util/hook-config.d.ts +0 -27
  224. package/build/util/hook-config.js +0 -76
  225. package/build/util/jsonc.d.ts +0 -14
  226. package/build/util/jsonc.js +0 -104
  227. package/build/util/plugin-cache-integrity.d.ts +0 -51
  228. package/build/util/plugin-cache-integrity.js +0 -146
  229. package/build/util/project-dir.d.ts +0 -149
  230. package/build/util/project-dir.js +0 -340
  231. package/build/util/sibling-mcp.d.ts +0 -79
  232. package/build/util/sibling-mcp.js +0 -181
  233. package/cli.bundle.mjs +0 -1236
  234. package/configs/antigravity/GEMINI.md +0 -68
  235. package/configs/antigravity/mcp_config.json +0 -7
  236. package/configs/antigravity-cli/hooks/hooks.json +0 -37
  237. package/configs/antigravity-cli/hooks.json +0 -37
  238. package/configs/antigravity-cli/mcp_config.json +0 -10
  239. package/configs/antigravity-cli/plugin.json +0 -14
  240. package/configs/antigravity-cli/rules/context-mode.md +0 -77
  241. package/configs/antigravity-cli/skills/context-mode/SKILL.md +0 -77
  242. package/configs/claude-code/CLAUDE.md +0 -91
  243. package/configs/codex/AGENTS.md +0 -99
  244. package/configs/codex/config.toml +0 -8
  245. package/configs/codex/hooks.json +0 -47
  246. package/configs/copilot-cli/.github/plugin/plugin.json +0 -23
  247. package/configs/copilot-cli/.mcp.json +0 -12
  248. package/configs/copilot-cli/README.md +0 -47
  249. package/configs/copilot-cli/hooks.json +0 -41
  250. package/configs/copilot-cli/skills/context-mode/SKILL.md +0 -38
  251. package/configs/cursor/context-mode.mdc +0 -76
  252. package/configs/cursor/hooks.json +0 -21
  253. package/configs/cursor/mcp.json +0 -7
  254. package/configs/gemini-cli/GEMINI.md +0 -88
  255. package/configs/gemini-cli/mcp.json +0 -7
  256. package/configs/gemini-cli/settings.json +0 -60
  257. package/configs/jetbrains-copilot/copilot-instructions.md +0 -80
  258. package/configs/jetbrains-copilot/hooks.json +0 -16
  259. package/configs/jetbrains-copilot/mcp.json +0 -7
  260. package/configs/kilo/AGENTS.md +0 -84
  261. package/configs/kilo/kilo.json +0 -6
  262. package/configs/kimi/hooks.json +0 -54
  263. package/configs/kiro/KIRO.md +0 -84
  264. package/configs/kiro/agent.json +0 -18
  265. package/configs/kiro/mcp.json +0 -7
  266. package/configs/omp/SYSTEM.md +0 -85
  267. package/configs/omp/mcp.json +0 -7
  268. package/configs/openclaw/AGENTS.md +0 -87
  269. package/configs/openclaw/openclaw.json +0 -13
  270. package/configs/opencode/AGENTS.md +0 -84
  271. package/configs/opencode/opencode.json +0 -6
  272. package/configs/pi/AGENTS.md +0 -3
  273. package/configs/qwen-code/QWEN.md +0 -91
  274. package/configs/vscode-copilot/copilot-instructions.md +0 -80
  275. package/configs/vscode-copilot/hooks.json +0 -16
  276. package/configs/vscode-copilot/mcp.json +0 -7
  277. package/configs/zed/AGENTS.md +0 -68
  278. package/hooks/antigravity-cli/payload.mjs +0 -98
  279. package/hooks/antigravity-cli/posttooluse.mjs +0 -138
  280. package/hooks/antigravity-cli/pretooluse.mjs +0 -78
  281. package/hooks/antigravity-cli/stop.mjs +0 -58
  282. package/hooks/auto-injection.mjs +0 -102
  283. package/hooks/cache-heal-utils.mjs +0 -379
  284. package/hooks/codex/platform.mjs +0 -1
  285. package/hooks/codex/posttooluse.mjs +0 -66
  286. package/hooks/codex/precompact.mjs +0 -70
  287. package/hooks/codex/pretooluse.mjs +0 -42
  288. package/hooks/codex/sessionstart.mjs +0 -121
  289. package/hooks/codex/stop.mjs +0 -138
  290. package/hooks/codex/userpromptsubmit.mjs +0 -75
  291. package/hooks/copilot-cli/posttooluse.mjs +0 -79
  292. package/hooks/copilot-cli/precompact.mjs +0 -66
  293. package/hooks/copilot-cli/pretooluse.mjs +0 -41
  294. package/hooks/copilot-cli/sessionstart.mjs +0 -121
  295. package/hooks/copilot-cli/stop.mjs +0 -59
  296. package/hooks/copilot-cli/userpromptsubmit.mjs +0 -77
  297. package/hooks/core/codex-caps.mjs +0 -112
  298. package/hooks/core/formatters.mjs +0 -356
  299. package/hooks/core/mcp-ready.mjs +0 -109
  300. package/hooks/core/platform-detect.mjs +0 -49
  301. package/hooks/core/routing.mjs +0 -1017
  302. package/hooks/core/stdin.mjs +0 -90
  303. package/hooks/core/tool-naming.mjs +0 -57
  304. package/hooks/cursor/afteragentresponse.mjs +0 -74
  305. package/hooks/cursor/hooks.json +0 -31
  306. package/hooks/cursor/posttooluse.mjs +0 -72
  307. package/hooks/cursor/pretooluse.mjs +0 -26
  308. package/hooks/cursor/sessionstart.mjs +0 -97
  309. package/hooks/cursor/stop.mjs +0 -48
  310. package/hooks/ensure-deps.mjs +0 -254
  311. package/hooks/formatters/claude-code.mjs +0 -113
  312. package/hooks/formatters/cursor.mjs +0 -37
  313. package/hooks/formatters/gemini-cli.mjs +0 -55
  314. package/hooks/formatters/vscode-copilot.mjs +0 -55
  315. package/hooks/gemini-cli/aftermodel.mjs +0 -70
  316. package/hooks/gemini-cli/aftertool.mjs +0 -61
  317. package/hooks/gemini-cli/beforeagent.mjs +0 -99
  318. package/hooks/gemini-cli/beforetool.mjs +0 -27
  319. package/hooks/gemini-cli/precompress.mjs +0 -55
  320. package/hooks/gemini-cli/sessionstart.mjs +0 -137
  321. package/hooks/heal-partial-install.mjs +0 -712
  322. package/hooks/jetbrains-copilot/posttooluse.mjs +0 -61
  323. package/hooks/jetbrains-copilot/precompact.mjs +0 -55
  324. package/hooks/jetbrains-copilot/pretooluse.mjs +0 -27
  325. package/hooks/jetbrains-copilot/sessionstart.mjs +0 -124
  326. package/hooks/kimi/platform.mjs +0 -1
  327. package/hooks/kimi/posttooluse.mjs +0 -72
  328. package/hooks/kimi/precompact.mjs +0 -80
  329. package/hooks/kimi/pretooluse.mjs +0 -42
  330. package/hooks/kimi/sessionend.mjs +0 -61
  331. package/hooks/kimi/sessionstart.mjs +0 -113
  332. package/hooks/kimi/stop.mjs +0 -132
  333. package/hooks/kimi/userpromptsubmit.mjs +0 -90
  334. package/hooks/kiro/agentspawn.mjs +0 -97
  335. package/hooks/kiro/posttooluse.mjs +0 -51
  336. package/hooks/kiro/pretooluse.mjs +0 -64
  337. package/hooks/kiro/userpromptsubmit.mjs +0 -88
  338. package/hooks/normalize-hooks.mjs +0 -323
  339. package/hooks/platform-bridge.mjs +0 -340
  340. package/hooks/posttooluse.mjs +0 -225
  341. package/hooks/precompact.mjs +0 -100
  342. package/hooks/pretooluse.mjs +0 -227
  343. package/hooks/qwen-code/platform.mjs +0 -1
  344. package/hooks/qwen-code/stop.mjs +0 -168
  345. package/hooks/routing-block.mjs +0 -105
  346. package/hooks/run-hook.mjs +0 -95
  347. package/hooks/security.bundle.mjs +0 -2
  348. package/hooks/session-attribution.bundle.mjs +0 -1
  349. package/hooks/session-db.bundle.mjs +0 -144
  350. package/hooks/session-directive.mjs +0 -520
  351. package/hooks/session-extract.bundle.mjs +0 -3
  352. package/hooks/session-helpers.mjs +0 -428
  353. package/hooks/session-loaders.mjs +0 -448
  354. package/hooks/session-snapshot.bundle.mjs +0 -32
  355. package/hooks/sessionstart.mjs +0 -464
  356. package/hooks/stop.mjs +0 -82
  357. package/hooks/suppress-stderr.mjs +0 -25
  358. package/hooks/userpromptsubmit.mjs +0 -108
  359. package/hooks/vscode-copilot/posttooluse.mjs +0 -61
  360. package/hooks/vscode-copilot/precompact.mjs +0 -55
  361. package/hooks/vscode-copilot/pretooluse.mjs +0 -27
  362. package/hooks/vscode-copilot/sessionstart.mjs +0 -129
  363. package/openclaw.plugin.json +0 -38
  364. package/scripts/heal-better-sqlite3.mjs +0 -430
  365. package/scripts/heal-installed-plugins.mjs +0 -598
  366. package/scripts/plugin-cache-integrity.mjs +0 -248
  367. package/scripts/postinstall.mjs +0 -384
  368. package/server.bundle.mjs +0 -1162
  369. package/skills/.ignore +0 -7
  370. package/skills/context-mode/SKILL.md +0 -300
  371. package/skills/context-mode/references/anti-patterns.md +0 -283
  372. package/skills/context-mode/references/patterns-javascript.md +0 -298
  373. package/skills/context-mode/references/patterns-python.md +0 -304
  374. package/skills/context-mode/references/patterns-shell.md +0 -277
  375. package/skills/ctx-index/SKILL.md +0 -46
  376. package/skills/ctx-insight/SKILL.md +0 -24
  377. package/skills/ctx-purge/SKILL.md +0 -49
  378. package/skills/ctx-search/SKILL.md +0 -35
  379. package/start.mjs +0 -616
@@ -1,87 +0,0 @@
1
- /**
2
- * error-classifier — PRD-context-as-a-service §5 ABI parity
3
- *
4
- * Pure classifiers that derive per-event metadata from PostToolUse hook
5
- * stdin, mirroring the seed shape produced by context-mode-platform's
6
- * `seed.ts` so the bridge can ship full seed-shape parity.
7
- *
8
- * The dashboard reads three derived columns that are populated by the
9
- * platform seeder but, per the OSS handoff (ANOMALY #3), are NEVER READ
10
- * by the engine when ingesting live events:
11
- *
12
- * • error_category — one of 10 fixed buckets
13
- * • error_tool — tool name that produced the error
14
- * • command_type — git / test / build / lint / install / format / run / other
15
- * • command_tool — first token of the command (npm, git, pytest, …)
16
- * • duration_bucket — fast / medium / slow / timeout
17
- *
18
- * We populate them anyway, with sane defaults derived from message text
19
- * and tool name, so the dashboard renders symmetrically with seed.
20
- *
21
- * Hard constraints:
22
- * 1. Pure functions — no I/O, no globals, no module state.
23
- * 2. `error_category` MUST match seed's `pickErrorClassification`
24
- * output exactly. The literal union below is the ABI.
25
- * 3. No external dependencies; TypeScript stdlib only.
26
- * 4. Robust to null / undefined / empty / malformed input.
27
- */
28
- export type ErrorCategory = "file_not_found" | "command_not_found" | "edit_match_failed" | "test_failed" | "syntax_error" | "runtime_error" | "permission_denied" | "git_conflict" | "timeout" | "unknown";
29
- export type CommandType = "test" | "build" | "lint" | "git" | "install" | "format" | "run" | "other";
30
- export type DurationBucket = "fast" | "medium" | "slow" | "timeout";
31
- export interface ErrorClassification {
32
- error_category: ErrorCategory;
33
- error_tool: string;
34
- }
35
- export interface CommandClassification {
36
- command_type: CommandType;
37
- command_tool: string;
38
- }
39
- /**
40
- * Classify an error message + tool name into one of seed's 10 categories.
41
- *
42
- * Patterns (ordered most-specific → least-specific so the first match
43
- * wins). Rationale for each pattern is inline.
44
- *
45
- * • file_not_found — Node's ENOENT, Python's FileNotFoundError, and
46
- * Claude's "Cannot find module" all signal a
47
- * missing file/path.
48
- * • command_not_found — POSIX shells emit "command not found" (exit 127)
49
- * and "bash: <bin>: not found"; npx prints similar.
50
- * • edit_match_failed — Claude's Edit tool prints "old_string not found"
51
- * or "matches multiple locations" when the patch
52
- * context is stale.
53
- * • test_failed — vitest/jest/pytest format `FAIL ` prefix; npm
54
- * prints "Test failed".
55
- * • syntax_error — SyntaxError (JS/TS), tsc TS-codes, or Python's
56
- * SyntaxError header.
57
- * • runtime_error — TypeError/ReferenceError/RangeError (uncaught).
58
- * • permission_denied — EACCES / "permission denied" from fs or sudo.
59
- * • git_conflict — git's "CONFLICT" header on rebase/merge, plus
60
- * "Merge conflict in".
61
- * • timeout — explicit "timeout"/"timed out"/"ETIMEDOUT".
62
- * • unknown — fallthrough; never throws.
63
- */
64
- export declare function classifyError(message: unknown, toolName: unknown): ErrorClassification;
65
- /**
66
- * Classify a Bash command into a workflow bucket. The bucket is derived
67
- * from the (tool, sub-verb) pair: `npm test` → test, `npm run build` →
68
- * build, `git commit` → git, `pip install` → install, etc.
69
- *
70
- * Heuristic ordering — most-specific verb checks first; falls through to
71
- * `run` for generic execution and `other` for anything we can't classify.
72
- */
73
- export declare function classifyCommand(command: unknown): CommandClassification;
74
- /**
75
- * Bucketise a latency_ms reading into the four fixed buckets the
76
- * dashboard renders. Bucket edges (in ms):
77
- *
78
- * fast : [0, 1_000)
79
- * medium : [1_000, 10_000)
80
- * slow : [10_000, 60_000)
81
- * timeout : [60_000, ∞)
82
- *
83
- * Defensive: negative and non-numeric inputs collapse to `fast` (the
84
- * neutral bucket) rather than throwing, because hooks have been seen
85
- * to emit `null` for very short calls.
86
- */
87
- export declare function bucketizeDuration(latencyMs: unknown): DurationBucket;
@@ -1,303 +0,0 @@
1
- /**
2
- * error-classifier — PRD-context-as-a-service §5 ABI parity
3
- *
4
- * Pure classifiers that derive per-event metadata from PostToolUse hook
5
- * stdin, mirroring the seed shape produced by context-mode-platform's
6
- * `seed.ts` so the bridge can ship full seed-shape parity.
7
- *
8
- * The dashboard reads three derived columns that are populated by the
9
- * platform seeder but, per the OSS handoff (ANOMALY #3), are NEVER READ
10
- * by the engine when ingesting live events:
11
- *
12
- * • error_category — one of 10 fixed buckets
13
- * • error_tool — tool name that produced the error
14
- * • command_type — git / test / build / lint / install / format / run / other
15
- * • command_tool — first token of the command (npm, git, pytest, …)
16
- * • duration_bucket — fast / medium / slow / timeout
17
- *
18
- * We populate them anyway, with sane defaults derived from message text
19
- * and tool name, so the dashboard renders symmetrically with seed.
20
- *
21
- * Hard constraints:
22
- * 1. Pure functions — no I/O, no globals, no module state.
23
- * 2. `error_category` MUST match seed's `pickErrorClassification`
24
- * output exactly. The literal union below is the ABI.
25
- * 3. No external dependencies; TypeScript stdlib only.
26
- * 4. Robust to null / undefined / empty / malformed input.
27
- */
28
- // ── Internal helpers ────────────────────────────────────────────────────
29
- /**
30
- * Normalise message for case-insensitive substring matching. Coerces
31
- * non-string input (null, undefined, numbers from errno objects) to
32
- * empty string so downstream `.includes()` is always safe.
33
- */
34
- function normalise(s) {
35
- if (typeof s !== "string")
36
- return "";
37
- return s.toLowerCase();
38
- }
39
- /**
40
- * Best-effort `error_tool` derivation. Prefers the PostToolUse-supplied
41
- * `toolName`; falls back to scanning the message for a canonical tool
42
- * name (Read/Edit/Write/Bash/Grep/Glob) so isolated error strings still
43
- * resolve to a useful value rather than the literal "unknown".
44
- */
45
- function deriveErrorTool(toolName, message) {
46
- if (typeof toolName === "string" && toolName.trim().length > 0) {
47
- return toolName.trim();
48
- }
49
- // Canonical Claude Code tool names that may appear in error strings.
50
- const known = ["Edit", "Read", "Write", "Bash", "Grep", "Glob", "MultiEdit"];
51
- for (const t of known) {
52
- if (message.toLowerCase().includes(t.toLowerCase()))
53
- return t;
54
- }
55
- return "unknown";
56
- }
57
- // ── Error classifier ────────────────────────────────────────────────────
58
- /**
59
- * Classify an error message + tool name into one of seed's 10 categories.
60
- *
61
- * Patterns (ordered most-specific → least-specific so the first match
62
- * wins). Rationale for each pattern is inline.
63
- *
64
- * • file_not_found — Node's ENOENT, Python's FileNotFoundError, and
65
- * Claude's "Cannot find module" all signal a
66
- * missing file/path.
67
- * • command_not_found — POSIX shells emit "command not found" (exit 127)
68
- * and "bash: <bin>: not found"; npx prints similar.
69
- * • edit_match_failed — Claude's Edit tool prints "old_string not found"
70
- * or "matches multiple locations" when the patch
71
- * context is stale.
72
- * • test_failed — vitest/jest/pytest format `FAIL ` prefix; npm
73
- * prints "Test failed".
74
- * • syntax_error — SyntaxError (JS/TS), tsc TS-codes, or Python's
75
- * SyntaxError header.
76
- * • runtime_error — TypeError/ReferenceError/RangeError (uncaught).
77
- * • permission_denied — EACCES / "permission denied" from fs or sudo.
78
- * • git_conflict — git's "CONFLICT" header on rebase/merge, plus
79
- * "Merge conflict in".
80
- * • timeout — explicit "timeout"/"timed out"/"ETIMEDOUT".
81
- * • unknown — fallthrough; never throws.
82
- */
83
- export function classifyError(message, toolName) {
84
- const msg = normalise(message);
85
- const tool = typeof toolName === "string" ? toolName : "";
86
- const error_tool = deriveErrorTool(toolName, typeof message === "string" ? message : "");
87
- // Empty / malformed input → unknown bucket but still return a valid tool.
88
- if (msg.length === 0) {
89
- return { error_category: "unknown", error_tool };
90
- }
91
- // ── file_not_found ────────────────────────────────────────────────
92
- // Node's ENOENT carries "no such file or directory"; Claude's Read
93
- // tool surfaces the raw errno line. "cannot find module" is the
94
- // require-resolution variant.
95
- if (msg.includes("enoent") ||
96
- msg.includes("no such file") ||
97
- msg.includes("cannot find module") ||
98
- msg.includes("filenotfounderror")) {
99
- return { error_category: "file_not_found", error_tool };
100
- }
101
- // ── command_not_found ────────────────────────────────────────────
102
- // POSIX shells: "<shell>: <bin>: command not found" → exit 127.
103
- // Some hooks surface the bare exit code without the message.
104
- if (msg.includes("command not found") ||
105
- msg.includes(": not found") ||
106
- /\bexit(?:\s+code)?\s*[:=]?\s*127\b/.test(msg)) {
107
- return { error_category: "command_not_found", error_tool };
108
- }
109
- // ── edit_match_failed ────────────────────────────────────────────
110
- // Claude Code's Edit tool prints these exact phrases when the
111
- // `old_string` parameter no longer matches the file contents.
112
- // Gate on the Edit tool to avoid false positives when a Bash script
113
- // happens to contain the literal text "old_string".
114
- if ((tool === "Edit" || tool === "MultiEdit") &&
115
- (msg.includes("old_string") ||
116
- msg.includes("could not find string") ||
117
- msg.includes("string to replace not found") ||
118
- msg.includes("matches multiple"))) {
119
- return { error_category: "edit_match_failed", error_tool };
120
- }
121
- // Edit-style failure can also leak without tool name — match the
122
- // distinctive Claude phrasing alone.
123
- if (msg.includes("old_string not found") || msg.includes("string to replace not found")) {
124
- return { error_category: "edit_match_failed", error_tool };
125
- }
126
- // ── git_conflict ─────────────────────────────────────────────────
127
- // Check BEFORE test_failed because "CONFLICT" can co-occur with the
128
- // word "fail" in some merge outputs.
129
- if (msg.includes("conflict") &&
130
- (msg.includes("merge") || msg.includes("rebase") || msg.includes("git"))) {
131
- return { error_category: "git_conflict", error_tool };
132
- }
133
- if (msg.startsWith("conflict") || msg.includes("merge conflict")) {
134
- return { error_category: "git_conflict", error_tool };
135
- }
136
- // ── timeout ──────────────────────────────────────────────────────
137
- // Check BEFORE test_failed; "test timed out" should bucket as timeout.
138
- if (msg.includes("etimedout") ||
139
- msg.includes("timed out") ||
140
- msg.includes("timeout") ||
141
- msg.includes("deadline exceeded")) {
142
- return { error_category: "timeout", error_tool };
143
- }
144
- // ── permission_denied ────────────────────────────────────────────
145
- if (msg.includes("eacces") ||
146
- msg.includes("permission denied") ||
147
- msg.includes("operation not permitted") ||
148
- msg.includes("eperm")) {
149
- return { error_category: "permission_denied", error_tool };
150
- }
151
- // ── syntax_error ─────────────────────────────────────────────────
152
- // tsc errors look like "error TS2322"; JS SyntaxError header is exact.
153
- if (msg.includes("syntaxerror") ||
154
- /\berror\s+ts\d{3,5}\b/.test(msg) ||
155
- msg.includes("unexpected token") ||
156
- msg.includes("unexpected end of") ||
157
- msg.includes("parse error")) {
158
- return { error_category: "syntax_error", error_tool };
159
- }
160
- // ── test_failed ──────────────────────────────────────────────────
161
- // vitest/jest print `FAIL `; npm test prints "Test failed".
162
- // pytest prints "FAILED" capital. Bias to Bash tool but accept
163
- // unscoped messages because hooks sometimes drop tool name.
164
- if (msg.includes("test failed") ||
165
- msg.includes("tests failed") ||
166
- /\bfail(?:ed)?\b.*\btest\b/.test(msg) ||
167
- /\b\d+\s+tests?\s+failed\b/.test(msg) ||
168
- msg.includes("assertion") ||
169
- /^fail\s/.test(msg) ||
170
- /\nfail\s/.test(msg)) {
171
- return { error_category: "test_failed", error_tool };
172
- }
173
- // ── runtime_error ────────────────────────────────────────────────
174
- // Catch-all for uncaught JS exceptions and the common Python ones.
175
- // Placed near the end so more specific buckets (syntax_error) win
176
- // when both could match.
177
- if (msg.includes("typeerror") ||
178
- msg.includes("referenceerror") ||
179
- msg.includes("rangeerror") ||
180
- msg.includes("uncaught exception") ||
181
- msg.includes("traceback (most recent call last)") ||
182
- msg.includes("nullpointerexception")) {
183
- return { error_category: "runtime_error", error_tool };
184
- }
185
- // Fallthrough — categorisation is best-effort; the dashboard renders
186
- // "unknown" as a neutral bucket rather than dropping the event.
187
- return { error_category: "unknown", error_tool };
188
- }
189
- // ── Command classifier ──────────────────────────────────────────────────
190
- /**
191
- * Tokenise a shell command, stripping leading env-var prefixes
192
- * (`FOO=bar npm run build`) and `sudo`/`time` wrappers so the first
193
- * meaningful token is returned.
194
- */
195
- function firstToken(command) {
196
- const parts = command.trim().split(/\s+/);
197
- let i = 0;
198
- // Skip env-var assignments: KEY=value
199
- while (i < parts.length && /^[A-Za-z_][A-Za-z0-9_]*=.*/.test(parts[i]))
200
- i++;
201
- // Skip common wrappers that aren't the "real" tool.
202
- while (i < parts.length && (parts[i] === "sudo" || parts[i] === "time" || parts[i] === "nice"))
203
- i++;
204
- return parts[i] ?? "";
205
- }
206
- /**
207
- * Classify a Bash command into a workflow bucket. The bucket is derived
208
- * from the (tool, sub-verb) pair: `npm test` → test, `npm run build` →
209
- * build, `git commit` → git, `pip install` → install, etc.
210
- *
211
- * Heuristic ordering — most-specific verb checks first; falls through to
212
- * `run` for generic execution and `other` for anything we can't classify.
213
- */
214
- export function classifyCommand(command) {
215
- if (typeof command !== "string" || command.trim().length === 0) {
216
- return { command_type: "other", command_tool: "" };
217
- }
218
- const raw = command.trim();
219
- const tool = firstToken(raw).toLowerCase();
220
- const lower = raw.toLowerCase();
221
- // ── git ──────────────────────────────────────────────────────────
222
- if (tool === "git") {
223
- return { command_type: "git", command_tool: "git" };
224
- }
225
- // ── install ──────────────────────────────────────────────────────
226
- // npm/pnpm/yarn/pip install variants come before generic test/build
227
- // because `npm install --save-dev jest` would otherwise match test.
228
- if (/\b(install|add|ci)\b/.test(lower) &&
229
- (tool === "npm" || tool === "pnpm" || tool === "yarn" || tool === "bun" || tool === "pip" || tool === "pip3")) {
230
- return { command_type: "install", command_tool: tool };
231
- }
232
- if (tool === "brew" && /\binstall\b/.test(lower)) {
233
- return { command_type: "install", command_tool: "brew" };
234
- }
235
- // ── test ─────────────────────────────────────────────────────────
236
- // Direct test runners, plus `npm test` / `pnpm test` / `yarn test`.
237
- if (tool === "vitest" || tool === "jest" || tool === "pytest" ||
238
- tool === "mocha" || tool === "playwright" || tool === "cypress") {
239
- return { command_type: "test", command_tool: tool };
240
- }
241
- if ((tool === "npm" || tool === "pnpm" || tool === "yarn" || tool === "bun") &&
242
- /\btest\b/.test(lower)) {
243
- return { command_type: "test", command_tool: tool };
244
- }
245
- // ── lint ─────────────────────────────────────────────────────────
246
- if (tool === "eslint" || tool === "tslint" || tool === "ruff" || tool === "flake8" || tool === "pylint") {
247
- return { command_type: "lint", command_tool: tool };
248
- }
249
- if (/\blint\b/.test(lower) && (tool === "npm" || tool === "pnpm" || tool === "yarn" || tool === "bun")) {
250
- return { command_type: "lint", command_tool: tool };
251
- }
252
- // ── format ───────────────────────────────────────────────────────
253
- if (tool === "prettier" || tool === "black" || tool === "gofmt" || tool === "rustfmt") {
254
- return { command_type: "format", command_tool: tool };
255
- }
256
- if (/\b(format|fmt)\b/.test(lower) && (tool === "npm" || tool === "pnpm" || tool === "yarn" || tool === "bun")) {
257
- return { command_type: "format", command_tool: tool };
258
- }
259
- // ── build ────────────────────────────────────────────────────────
260
- if (tool === "tsc" || tool === "webpack" || tool === "rollup" || tool === "vite" || tool === "esbuild" || tool === "make") {
261
- return { command_type: "build", command_tool: tool };
262
- }
263
- if (/\bbuild\b/.test(lower) && (tool === "npm" || tool === "pnpm" || tool === "yarn" || tool === "bun" || tool === "cargo" || tool === "go")) {
264
- return { command_type: "build", command_tool: tool };
265
- }
266
- // ── run ──────────────────────────────────────────────────────────
267
- // Generic execution — `npm run …` (with no recognised sub-verb),
268
- // `node script.js`, `python -m foo`, etc.
269
- if ((tool === "npm" || tool === "pnpm" || tool === "yarn" || tool === "bun") &&
270
- /\brun\b/.test(lower)) {
271
- return { command_type: "run", command_tool: tool };
272
- }
273
- if (tool === "node" || tool === "python" || tool === "python3" || tool === "deno" || tool === "bun") {
274
- return { command_type: "run", command_tool: tool };
275
- }
276
- // Fallthrough — preserves the tool name so the dashboard can still
277
- // chart "other" commands by their underlying binary.
278
- return { command_type: "other", command_tool: tool || "" };
279
- }
280
- // ── Duration bucketiser ────────────────────────────────────────────────
281
- /**
282
- * Bucketise a latency_ms reading into the four fixed buckets the
283
- * dashboard renders. Bucket edges (in ms):
284
- *
285
- * fast : [0, 1_000)
286
- * medium : [1_000, 10_000)
287
- * slow : [10_000, 60_000)
288
- * timeout : [60_000, ∞)
289
- *
290
- * Defensive: negative and non-numeric inputs collapse to `fast` (the
291
- * neutral bucket) rather than throwing, because hooks have been seen
292
- * to emit `null` for very short calls.
293
- */
294
- export function bucketizeDuration(latencyMs) {
295
- const n = typeof latencyMs === "number" && Number.isFinite(latencyMs) ? latencyMs : 0;
296
- if (n < 1_000)
297
- return "fast";
298
- if (n < 10_000)
299
- return "medium";
300
- if (n < 60_000)
301
- return "slow";
302
- return "timeout";
303
- }
@@ -1,48 +0,0 @@
1
- /**
2
- * event-emit — Phase 5+7 of D2 PRD (stats-event-driven-architecture)
3
- *
4
- * Server-side helpers that record sandbox / index / cache work into
5
- * `session_events` with the new `bytes_avoided` / `bytes_returned`
6
- * columns so the renderer can compute the real $ saved instead of the
7
- * conservative `events × 256` token estimate.
8
- *
9
- * Design notes
10
- * ────────────
11
- * - Uses the public `SessionDB.insertEvent(... , bytes)` API the schema
12
- * engineer extended in this branch — same dedup + FIFO eviction +
13
- * transaction wrapping you'd get from any other event source.
14
- * - Best-effort error swallowing matches `persistToolCallCounter` in
15
- * `persist-tool-calls.ts`. A stats-side failure must NEVER break the
16
- * parent MCP tool call.
17
- * - Resolves the latest `session_id` from `session_meta` so the wiring
18
- * in `server.ts` is `setImmediate(() => emit*({...}))` — no need to
19
- * plumb session ids through every handler.
20
- */
21
- /**
22
- * Record a `ctx_execute` / `ctx_execute_file` / `ctx_batch_execute` run.
23
- * `bytesReturned` is the size of the stdout text the user actually saw —
24
- * the rest of the sandbox output stayed out of context.
25
- */
26
- export declare function emitSandboxExecuteEvent(opts: {
27
- sessionDbPath: string;
28
- toolName: string;
29
- bytesReturned: number;
30
- }): void;
31
- /**
32
- * Record a `ctx_index` / `trackIndexed` write — content kept out of
33
- * context by being chunked into FTS5 instead of returned inline.
34
- */
35
- export declare function emitIndexWriteEvent(opts: {
36
- sessionDbPath: string;
37
- source: string;
38
- bytesAvoided: number;
39
- }): void;
40
- /**
41
- * Record a `ctx_fetch_and_index` TTL cache hit — bytes the user would
42
- * have spent re-fetching the same URL within the 24h cache window.
43
- */
44
- export declare function emitCacheHitEvent(opts: {
45
- sessionDbPath: string;
46
- source: string;
47
- bytesAvoided: number;
48
- }): void;
@@ -1,101 +0,0 @@
1
- /**
2
- * event-emit — Phase 5+7 of D2 PRD (stats-event-driven-architecture)
3
- *
4
- * Server-side helpers that record sandbox / index / cache work into
5
- * `session_events` with the new `bytes_avoided` / `bytes_returned`
6
- * columns so the renderer can compute the real $ saved instead of the
7
- * conservative `events × 256` token estimate.
8
- *
9
- * Design notes
10
- * ────────────
11
- * - Uses the public `SessionDB.insertEvent(... , bytes)` API the schema
12
- * engineer extended in this branch — same dedup + FIFO eviction +
13
- * transaction wrapping you'd get from any other event source.
14
- * - Best-effort error swallowing matches `persistToolCallCounter` in
15
- * `persist-tool-calls.ts`. A stats-side failure must NEVER break the
16
- * parent MCP tool call.
17
- * - Resolves the latest `session_id` from `session_meta` so the wiring
18
- * in `server.ts` is `setImmediate(() => emit*({...}))` — no need to
19
- * plumb session ids through every handler.
20
- */
21
- import { existsSync } from "node:fs";
22
- import { SessionDB } from "./db.js";
23
- /**
24
- * Open the SessionDB at `dbPath`, find the latest session_id, and run
25
- * `fn` with both. Wraps everything in try/catch so callers stay
26
- * fire-and-forget.
27
- */
28
- function withLatestSession(dbPath, fn) {
29
- try {
30
- if (!existsSync(dbPath))
31
- return;
32
- const sdb = new SessionDB({ dbPath });
33
- try {
34
- const sid = sdb.getLatestSessionId();
35
- if (!sid)
36
- return;
37
- fn(sdb, sid);
38
- }
39
- finally {
40
- try {
41
- sdb.close();
42
- }
43
- catch { /* ignore */ }
44
- }
45
- }
46
- catch {
47
- // Best-effort: never break the parent MCP tool call.
48
- }
49
- }
50
- /**
51
- * Record a `ctx_execute` / `ctx_execute_file` / `ctx_batch_execute` run.
52
- * `bytesReturned` is the size of the stdout text the user actually saw —
53
- * the rest of the sandbox output stayed out of context.
54
- */
55
- export function emitSandboxExecuteEvent(opts) {
56
- withLatestSession(opts.sessionDbPath, (sdb, sid) => {
57
- sdb.insertEvent(sid, {
58
- type: "sandbox-execute",
59
- category: "sandbox",
60
- priority: 1,
61
- data: opts.toolName,
62
- project_dir: "",
63
- attribution_source: "server",
64
- attribution_confidence: 1,
65
- }, "ctx-server", undefined, { bytesReturned: opts.bytesReturned });
66
- });
67
- }
68
- /**
69
- * Record a `ctx_index` / `trackIndexed` write — content kept out of
70
- * context by being chunked into FTS5 instead of returned inline.
71
- */
72
- export function emitIndexWriteEvent(opts) {
73
- withLatestSession(opts.sessionDbPath, (sdb, sid) => {
74
- sdb.insertEvent(sid, {
75
- type: "index-write",
76
- category: "sandbox",
77
- priority: 1,
78
- data: opts.source,
79
- project_dir: "",
80
- attribution_source: "server",
81
- attribution_confidence: 1,
82
- }, "ctx-server", undefined, { bytesAvoided: opts.bytesAvoided });
83
- });
84
- }
85
- /**
86
- * Record a `ctx_fetch_and_index` TTL cache hit — bytes the user would
87
- * have spent re-fetching the same URL within the 24h cache window.
88
- */
89
- export function emitCacheHitEvent(opts) {
90
- withLatestSession(opts.sessionDbPath, (sdb, sid) => {
91
- sdb.insertEvent(sid, {
92
- type: "cache-hit",
93
- category: "cache",
94
- priority: 1,
95
- data: opts.source,
96
- project_dir: "",
97
- attribution_source: "server",
98
- attribution_confidence: 1,
99
- }, "ctx-server", undefined, { bytesAvoided: opts.bytesAvoided });
100
- });
101
- }