context-mode 1.0.168 → 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 (395) 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/cache-heal.d.ts +0 -48
  163. package/build/cache-heal.js +0 -150
  164. package/build/cli.d.ts +0 -34
  165. package/build/cli.js +0 -1827
  166. package/build/concurrency/runPool.d.ts +0 -36
  167. package/build/concurrency/runPool.js +0 -51
  168. package/build/db-base.d.ts +0 -179
  169. package/build/db-base.js +0 -569
  170. package/build/executor.d.ts +0 -72
  171. package/build/executor.js +0 -678
  172. package/build/exit-classify.d.ts +0 -19
  173. package/build/exit-classify.js +0 -12
  174. package/build/fetch-cache.d.ts +0 -13
  175. package/build/fetch-cache.js +0 -15
  176. package/build/lifecycle.d.ts +0 -124
  177. package/build/lifecycle.js +0 -278
  178. package/build/openclaw/mcp-tools.d.ts +0 -54
  179. package/build/openclaw/mcp-tools.js +0 -198
  180. package/build/openclaw/workspace-router.d.ts +0 -29
  181. package/build/openclaw/workspace-router.js +0 -64
  182. package/build/openclaw-plugin.d.ts +0 -130
  183. package/build/openclaw-plugin.js +0 -626
  184. package/build/opencode-plugin.d.ts +0 -122
  185. package/build/opencode-plugin.js +0 -375
  186. package/build/pi-extension.d.ts +0 -14
  187. package/build/pi-extension.js +0 -451
  188. package/build/routing-block.d.ts +0 -8
  189. package/build/routing-block.js +0 -86
  190. package/build/runPool.d.ts +0 -36
  191. package/build/runPool.js +0 -51
  192. package/build/runtime.d.ts +0 -71
  193. package/build/runtime.js +0 -659
  194. package/build/search/auto-memory.d.ts +0 -47
  195. package/build/search/auto-memory.js +0 -170
  196. package/build/search/ctx-search-schema.d.ts +0 -90
  197. package/build/search/ctx-search-schema.js +0 -135
  198. package/build/search/flood-guard.d.ts +0 -57
  199. package/build/search/flood-guard.js +0 -80
  200. package/build/search/unified.d.ts +0 -56
  201. package/build/search/unified.js +0 -104
  202. package/build/security.d.ts +0 -206
  203. package/build/security.js +0 -780
  204. package/build/server.d.ts +0 -184
  205. package/build/server.js +0 -4542
  206. package/build/session/analytics.d.ts +0 -745
  207. package/build/session/analytics.js +0 -2369
  208. package/build/session/db.d.ts +0 -468
  209. package/build/session/db.js +0 -1308
  210. package/build/session/error-classifier.d.ts +0 -87
  211. package/build/session/error-classifier.js +0 -303
  212. package/build/session/event-emit.d.ts +0 -48
  213. package/build/session/event-emit.js +0 -101
  214. package/build/session/extract.d.ts +0 -333
  215. package/build/session/extract.js +0 -2688
  216. package/build/session/model-prices.json +0 -429
  217. package/build/session/persist-tool-calls.d.ts +0 -54
  218. package/build/session/persist-tool-calls.js +0 -105
  219. package/build/session/pricing.d.ts +0 -64
  220. package/build/session/pricing.js +0 -151
  221. package/build/session/project-attribution.d.ts +0 -73
  222. package/build/session/project-attribution.js +0 -245
  223. package/build/session/purge.d.ts +0 -138
  224. package/build/session/purge.js +0 -240
  225. package/build/session/snapshot.d.ts +0 -46
  226. package/build/session/snapshot.js +0 -532
  227. package/build/store-directory.d.ts +0 -56
  228. package/build/store-directory.js +0 -254
  229. package/build/store.d.ts +0 -147
  230. package/build/store.js +0 -1714
  231. package/build/tool-naming.d.ts +0 -4
  232. package/build/tool-naming.js +0 -24
  233. package/build/truncate.d.ts +0 -57
  234. package/build/truncate.js +0 -142
  235. package/build/types.d.ts +0 -117
  236. package/build/types.js +0 -20
  237. package/build/util/claude-config.d.ts +0 -32
  238. package/build/util/claude-config.js +0 -84
  239. package/build/util/hook-config.d.ts +0 -27
  240. package/build/util/hook-config.js +0 -76
  241. package/build/util/jsonc.d.ts +0 -14
  242. package/build/util/jsonc.js +0 -104
  243. package/build/util/plugin-cache-integrity.d.ts +0 -51
  244. package/build/util/plugin-cache-integrity.js +0 -146
  245. package/build/util/project-dir.d.ts +0 -149
  246. package/build/util/project-dir.js +0 -340
  247. package/build/util/sibling-mcp.d.ts +0 -79
  248. package/build/util/sibling-mcp.js +0 -181
  249. package/cli.bundle.mjs +0 -1235
  250. package/configs/antigravity/GEMINI.md +0 -68
  251. package/configs/antigravity/mcp_config.json +0 -7
  252. package/configs/antigravity-cli/hooks/hooks.json +0 -37
  253. package/configs/antigravity-cli/hooks.json +0 -37
  254. package/configs/antigravity-cli/mcp_config.json +0 -10
  255. package/configs/antigravity-cli/plugin.json +0 -14
  256. package/configs/antigravity-cli/rules/context-mode.md +0 -77
  257. package/configs/antigravity-cli/skills/context-mode/SKILL.md +0 -77
  258. package/configs/claude-code/CLAUDE.md +0 -91
  259. package/configs/codex/AGENTS.md +0 -99
  260. package/configs/codex/config.toml +0 -8
  261. package/configs/codex/hooks.json +0 -47
  262. package/configs/copilot-cli/.github/plugin/plugin.json +0 -23
  263. package/configs/copilot-cli/.mcp.json +0 -12
  264. package/configs/copilot-cli/README.md +0 -47
  265. package/configs/copilot-cli/hooks.json +0 -41
  266. package/configs/copilot-cli/skills/context-mode/SKILL.md +0 -38
  267. package/configs/cursor/context-mode.mdc +0 -76
  268. package/configs/cursor/hooks.json +0 -21
  269. package/configs/cursor/mcp.json +0 -7
  270. package/configs/gemini-cli/GEMINI.md +0 -88
  271. package/configs/gemini-cli/mcp.json +0 -7
  272. package/configs/gemini-cli/settings.json +0 -60
  273. package/configs/jetbrains-copilot/copilot-instructions.md +0 -80
  274. package/configs/jetbrains-copilot/hooks.json +0 -16
  275. package/configs/jetbrains-copilot/mcp.json +0 -7
  276. package/configs/kilo/AGENTS.md +0 -84
  277. package/configs/kilo/kilo.json +0 -6
  278. package/configs/kimi/hooks.json +0 -54
  279. package/configs/kiro/KIRO.md +0 -84
  280. package/configs/kiro/agent.json +0 -18
  281. package/configs/kiro/mcp.json +0 -7
  282. package/configs/omp/SYSTEM.md +0 -85
  283. package/configs/omp/mcp.json +0 -7
  284. package/configs/openclaw/AGENTS.md +0 -87
  285. package/configs/openclaw/openclaw.json +0 -13
  286. package/configs/opencode/AGENTS.md +0 -84
  287. package/configs/opencode/opencode.json +0 -6
  288. package/configs/pi/AGENTS.md +0 -3
  289. package/configs/qwen-code/QWEN.md +0 -91
  290. package/configs/vscode-copilot/copilot-instructions.md +0 -80
  291. package/configs/vscode-copilot/hooks.json +0 -16
  292. package/configs/vscode-copilot/mcp.json +0 -7
  293. package/configs/zed/AGENTS.md +0 -68
  294. package/hooks/antigravity-cli/payload.mjs +0 -98
  295. package/hooks/antigravity-cli/posttooluse.mjs +0 -138
  296. package/hooks/antigravity-cli/pretooluse.mjs +0 -78
  297. package/hooks/antigravity-cli/stop.mjs +0 -58
  298. package/hooks/auto-injection.mjs +0 -102
  299. package/hooks/cache-heal-utils.mjs +0 -379
  300. package/hooks/codex/platform.mjs +0 -1
  301. package/hooks/codex/posttooluse.mjs +0 -66
  302. package/hooks/codex/precompact.mjs +0 -70
  303. package/hooks/codex/pretooluse.mjs +0 -42
  304. package/hooks/codex/sessionstart.mjs +0 -121
  305. package/hooks/codex/stop.mjs +0 -138
  306. package/hooks/codex/userpromptsubmit.mjs +0 -75
  307. package/hooks/copilot-cli/posttooluse.mjs +0 -79
  308. package/hooks/copilot-cli/precompact.mjs +0 -66
  309. package/hooks/copilot-cli/pretooluse.mjs +0 -41
  310. package/hooks/copilot-cli/sessionstart.mjs +0 -121
  311. package/hooks/copilot-cli/stop.mjs +0 -59
  312. package/hooks/copilot-cli/userpromptsubmit.mjs +0 -77
  313. package/hooks/core/codex-caps.mjs +0 -112
  314. package/hooks/core/formatters.mjs +0 -356
  315. package/hooks/core/mcp-ready.mjs +0 -109
  316. package/hooks/core/platform-detect.mjs +0 -49
  317. package/hooks/core/routing.mjs +0 -1017
  318. package/hooks/core/stdin.mjs +0 -90
  319. package/hooks/core/tool-naming.mjs +0 -57
  320. package/hooks/cursor/afteragentresponse.mjs +0 -74
  321. package/hooks/cursor/hooks.json +0 -31
  322. package/hooks/cursor/posttooluse.mjs +0 -72
  323. package/hooks/cursor/pretooluse.mjs +0 -26
  324. package/hooks/cursor/sessionstart.mjs +0 -97
  325. package/hooks/cursor/stop.mjs +0 -48
  326. package/hooks/ensure-deps.mjs +0 -254
  327. package/hooks/formatters/claude-code.mjs +0 -113
  328. package/hooks/formatters/cursor.mjs +0 -37
  329. package/hooks/formatters/gemini-cli.mjs +0 -55
  330. package/hooks/formatters/vscode-copilot.mjs +0 -55
  331. package/hooks/gemini-cli/aftermodel.mjs +0 -70
  332. package/hooks/gemini-cli/aftertool.mjs +0 -61
  333. package/hooks/gemini-cli/beforeagent.mjs +0 -99
  334. package/hooks/gemini-cli/beforetool.mjs +0 -27
  335. package/hooks/gemini-cli/precompress.mjs +0 -55
  336. package/hooks/gemini-cli/sessionstart.mjs +0 -137
  337. package/hooks/heal-partial-install.mjs +0 -712
  338. package/hooks/jetbrains-copilot/posttooluse.mjs +0 -61
  339. package/hooks/jetbrains-copilot/precompact.mjs +0 -55
  340. package/hooks/jetbrains-copilot/pretooluse.mjs +0 -27
  341. package/hooks/jetbrains-copilot/sessionstart.mjs +0 -124
  342. package/hooks/kimi/platform.mjs +0 -1
  343. package/hooks/kimi/posttooluse.mjs +0 -72
  344. package/hooks/kimi/precompact.mjs +0 -80
  345. package/hooks/kimi/pretooluse.mjs +0 -42
  346. package/hooks/kimi/sessionend.mjs +0 -61
  347. package/hooks/kimi/sessionstart.mjs +0 -113
  348. package/hooks/kimi/stop.mjs +0 -132
  349. package/hooks/kimi/userpromptsubmit.mjs +0 -90
  350. package/hooks/kiro/agentspawn.mjs +0 -97
  351. package/hooks/kiro/posttooluse.mjs +0 -51
  352. package/hooks/kiro/pretooluse.mjs +0 -64
  353. package/hooks/kiro/userpromptsubmit.mjs +0 -88
  354. package/hooks/normalize-hooks.mjs +0 -323
  355. package/hooks/platform-bridge.mjs +0 -340
  356. package/hooks/posttooluse.mjs +0 -187
  357. package/hooks/precompact.mjs +0 -100
  358. package/hooks/pretooluse.mjs +0 -227
  359. package/hooks/qwen-code/platform.mjs +0 -1
  360. package/hooks/qwen-code/stop.mjs +0 -168
  361. package/hooks/routing-block.mjs +0 -105
  362. package/hooks/run-hook.mjs +0 -95
  363. package/hooks/security.bundle.mjs +0 -2
  364. package/hooks/session-attribution.bundle.mjs +0 -1
  365. package/hooks/session-db.bundle.mjs +0 -144
  366. package/hooks/session-directive.mjs +0 -520
  367. package/hooks/session-extract.bundle.mjs +0 -3
  368. package/hooks/session-helpers.mjs +0 -428
  369. package/hooks/session-loaders.mjs +0 -448
  370. package/hooks/session-snapshot.bundle.mjs +0 -32
  371. package/hooks/sessionstart.mjs +0 -464
  372. package/hooks/stop.mjs +0 -82
  373. package/hooks/suppress-stderr.mjs +0 -25
  374. package/hooks/userpromptsubmit.mjs +0 -108
  375. package/hooks/vscode-copilot/posttooluse.mjs +0 -61
  376. package/hooks/vscode-copilot/precompact.mjs +0 -55
  377. package/hooks/vscode-copilot/pretooluse.mjs +0 -27
  378. package/hooks/vscode-copilot/sessionstart.mjs +0 -129
  379. package/openclaw.plugin.json +0 -38
  380. package/scripts/heal-better-sqlite3.mjs +0 -430
  381. package/scripts/heal-installed-plugins.mjs +0 -598
  382. package/scripts/plugin-cache-integrity.mjs +0 -248
  383. package/scripts/postinstall.mjs +0 -384
  384. package/server.bundle.mjs +0 -1161
  385. package/skills/.ignore +0 -7
  386. package/skills/context-mode/SKILL.md +0 -300
  387. package/skills/context-mode/references/anti-patterns.md +0 -283
  388. package/skills/context-mode/references/patterns-javascript.md +0 -298
  389. package/skills/context-mode/references/patterns-python.md +0 -304
  390. package/skills/context-mode/references/patterns-shell.md +0 -277
  391. package/skills/ctx-index/SKILL.md +0 -46
  392. package/skills/ctx-insight/SKILL.md +0 -24
  393. package/skills/ctx-purge/SKILL.md +0 -49
  394. package/skills/ctx-search/SKILL.md +0 -35
  395. package/start.mjs +0 -616
@@ -1,151 +0,0 @@
1
- /**
2
- * Pricing catalog — single source of truth for per-model USD cost.
3
- *
4
- * Deep module, tiny interface. At load it reads one curated multi-vendor JSON
5
- * (src/session/model-prices.json) into a Map<modelId, Price> in per-Mtok units,
6
- * then exposes three pure-ish functions:
7
- *
8
- * lookupPrice(modelId) → Price | null
9
- * computeCostUsd(modelId, tokens) → number | null
10
- * nativeOrComputed(id, t, native) → number | null
11
- *
12
- * WHY THIS EXISTS — the bug it kills:
13
- * The old table in src/session/extract.ts hardcoded ~5 Claude rows plus a
14
- * `default` row, and any unmatched id (every OpenAI / Gemini / Qwen / DeepSeek
15
- * / Grok model) silently inherited Claude-Sonnet pricing. Non-Claude turns were
16
- * therefore mispriced. Here each model is priced from ITS OWN curated row, and
17
- * an unknown id resolves to `null` (no price) instead of a wrong Claude rate.
18
- *
19
- * The large litellm catalog (~1.5MB, ~2900 models) is NOT bundled — it lives at
20
- * tools/pricing/litellm-catalog.json as the dev-only refresh base for this
21
- * curated JSON.
22
- *
23
- * The curated JSON is small (~13KB, 61 models) and esbuild inlines it into the
24
- * hook/server bundles at build time (no runtime fs read, no external file).
25
- */
26
- import catalog from "./model-prices.json" with { type: "json" };
27
- /**
28
- * Read the curated JSON into one Map. A row with a null *input* price is
29
- * unusable for cost (the primary bucket has no rate) and is dropped at load so
30
- * lookupPrice returns null for it — matching "null-priced entries → no price".
31
- * (The two null-input ids are already pruned from the JSON itself; this guard
32
- * keeps the loader robust if one is ever re-added.)
33
- */
34
- function buildCatalog() {
35
- const map = new Map();
36
- const src = catalog;
37
- for (const id of Object.keys(src)) {
38
- const row = src[id];
39
- if (row == null || typeof row !== "object")
40
- continue;
41
- // No input rate ⇒ no usable price for this model.
42
- if (typeof row.input_per_mtok !== "number")
43
- continue;
44
- map.set(id, {
45
- input_per_mtok: row.input_per_mtok,
46
- output_per_mtok: typeof row.output_per_mtok === "number" ? row.output_per_mtok : null,
47
- cache_read_per_mtok: typeof row.cache_read_per_mtok === "number" ? row.cache_read_per_mtok : null,
48
- cache_write_per_mtok: typeof row.cache_write_per_mtok === "number" ? row.cache_write_per_mtok : null,
49
- });
50
- }
51
- return map;
52
- }
53
- const CATALOG = buildCatalog();
54
- /**
55
- * Strip a single leading `provider/` segment, char-algorithmically (NO regex).
56
- * Walks to the first '/'; everything after it is the bare model id. Only the
57
- * FIRST segment is stripped — `openai/gpt-5` → `gpt-5`, `a/b/c` → `b/c` — so a
58
- * model id that legitimately contains a slash keeps its remaining segments.
59
- * Returns null when there is no '/' (caller already tried the raw form).
60
- */
61
- function stripProviderPrefix(id) {
62
- for (let i = 0; i < id.length; i++) {
63
- if (id.charCodeAt(i) === 47 /* '/' */) {
64
- // Guard against a leading or trailing slash producing an empty segment.
65
- if (i === 0 || i === id.length - 1)
66
- return null;
67
- return id.slice(i + 1);
68
- }
69
- }
70
- return null;
71
- }
72
- /** trim + lowercase, char-safe (String.prototype.trim/toLowerCase, no regex). */
73
- function normalize(id) {
74
- return id.trim().toLowerCase();
75
- }
76
- /**
77
- * Resolve a model id to its curated Price, or null on miss.
78
- * Strategy: exact, then normalized (trim+lowercase), then provider-stripped
79
- * normalized. Misses return null so the caller can decide (warn / fall back).
80
- */
81
- export function lookupPrice(modelId) {
82
- if (typeof modelId !== "string" || modelId.length === 0)
83
- return null;
84
- // 1. Exact — fastest path, covers ids already in canonical form.
85
- const exact = CATALOG.get(modelId);
86
- if (exact)
87
- return exact;
88
- // 2. Normalized — trimmed + lowercased.
89
- const norm = normalize(modelId);
90
- const byNorm = CATALOG.get(norm);
91
- if (byNorm)
92
- return byNorm;
93
- // 3. Provider-stripped (pi / openclaw / opencode report `provider/model`).
94
- const bare = stripProviderPrefix(norm);
95
- if (bare) {
96
- const byBare = CATALOG.get(bare);
97
- if (byBare)
98
- return byBare;
99
- }
100
- return null;
101
- }
102
- /** Price one token bucket. A null bucket rate falls back to the input rate. */
103
- function bucketCost(tokens, rate, inputRate) {
104
- if (tokens <= 0)
105
- return 0;
106
- const effective = typeof rate === "number" ? rate : inputRate;
107
- return tokens * effective;
108
- }
109
- /**
110
- * Σ tokens × per-Mtok price / 1e6 over the four buckets. Returns null when no
111
- * price is found OR every token count is zero/absent (so dashboards never show
112
- * a misleading "$0.00 for nothing" row). On a price miss, warns exactly once
113
- * with the unmatched id so the curated catalog can be extended.
114
- *
115
- * Bucket → price mapping:
116
- * input_tokens → input_per_mtok
117
- * output_tokens → output_per_mtok (null ⇒ input rate)
118
- * cache_read_tokens → cache_read_per_mtok (null ⇒ input rate)
119
- * cache_creation_tokens → cache_write_per_mtok (null ⇒ input rate)
120
- */
121
- export function computeCostUsd(modelId, t) {
122
- const input = typeof t.input_tokens === "number" ? t.input_tokens : 0;
123
- const output = typeof t.output_tokens === "number" ? t.output_tokens : 0;
124
- const cacheRead = typeof t.cache_read_tokens === "number" ? t.cache_read_tokens : 0;
125
- const cacheCreate = typeof t.cache_creation_tokens === "number" ? t.cache_creation_tokens : 0;
126
- // All buckets empty ⇒ nothing to price, regardless of model.
127
- if (input <= 0 && output <= 0 && cacheRead <= 0 && cacheCreate <= 0)
128
- return null;
129
- const price = lookupPrice(modelId);
130
- if (!price || typeof price.input_per_mtok !== "number") {
131
- // Unknown model — emit one line so the id can be added to the catalog.
132
- console.warn(`[pricing] no curated price for model id: ${modelId}`);
133
- return null;
134
- }
135
- const inputRate = price.input_per_mtok;
136
- const microDollars = bucketCost(input, inputRate, inputRate) +
137
- bucketCost(output, price.output_per_mtok, inputRate) +
138
- bucketCost(cacheRead, price.cache_read_per_mtok, inputRate) +
139
- bucketCost(cacheCreate, price.cache_write_per_mtok, inputRate);
140
- return microDollars / 1_000_000;
141
- }
142
- /**
143
- * Prefer a provider-supplied native cost when present, else compute from the
144
- * catalog. A native cost of exactly 0 is a real value (free tier) and passes
145
- * through — only null/undefined defers to computeCostUsd.
146
- */
147
- export function nativeOrComputed(modelId, t, nativeCostUsd) {
148
- if (typeof nativeCostUsd === "number")
149
- return nativeCostUsd;
150
- return computeCostUsd(modelId, t);
151
- }
@@ -1,73 +0,0 @@
1
- /**
2
- * Project attribution heuristics for session events.
3
- *
4
- * Goal: avoid pinning all activity to the startup directory when work shifts
5
- * across projects mid-session. This module resolves a best-effort project
6
- * directory per event and attaches a confidence score + source signal.
7
- */
8
- import type { SessionEvent } from "../types.js";
9
- /**
10
- * Confidence scores for project attribution sources.
11
- *
12
- * Higher = more reliable signal. The hierarchy reflects how directly
13
- * the signal indicates the user's intended project:
14
- * - Explicit config (workspace roots) > explicit navigation (cd) > implicit context
15
- * - Path-bearing events score higher than fallbacks without path signals
16
- */
17
- export declare const ATTRIBUTION_CONFIDENCE: {
18
- /** Explicit workspace root from IDE/editor config */
19
- readonly WORKSPACE_ROOT: 0.98;
20
- /** User explicitly navigated here (cd command) */
21
- readonly CWD_EVENT: 0.9;
22
- /** Hook payload cwd — reliable but implicit */
23
- readonly INPUT_CWD: 0.88;
24
- /** Session startup directory */
25
- readonly SESSION_ORIGIN: 0.82;
26
- /** Carry-forward from previous high-confidence event */
27
- readonly LAST_SEEN: 0.76;
28
- /** Inferred from file path prefix matching */
29
- readonly EVENT_PATH: 0.7;
30
- /** Minimum confidence to carry forward as lastKnownProjectDir */
31
- readonly CARRY_FORWARD_THRESHOLD: 0.55;
32
- /** Fallback: input_cwd without path signal */
33
- readonly FALLBACK_INPUT_CWD: 0.45;
34
- /** Fallback: last_seen without path signal */
35
- readonly FALLBACK_LAST_SEEN: 0.4;
36
- /** Fallback: session_origin without path signal */
37
- readonly FALLBACK_SESSION_ORIGIN: 0.35;
38
- };
39
- export type AttributionSource = "event_path" | "cwd_event" | "input_cwd" | "workspace_root" | "last_seen" | "session_origin" | "env" | "test" | "unknown";
40
- export interface ProjectAttribution {
41
- projectDir: string;
42
- source: AttributionSource;
43
- confidence: number;
44
- }
45
- export interface AttributionContext {
46
- sessionOriginDir?: string | null;
47
- inputProjectDir?: string | null;
48
- workspaceRoots?: string[] | null;
49
- lastKnownProjectDir?: string | null;
50
- }
51
- /**
52
- * Resolve the most likely project directory for one event.
53
- */
54
- export declare function resolveProjectAttribution(event: SessionEvent, context: AttributionContext): ProjectAttribution;
55
- /**
56
- * Convenience helper: resolve attributions for a stream of events while
57
- * carrying forward the latest confident project as context.
58
- */
59
- export declare function resolveProjectAttributions(events: SessionEvent[], context: AttributionContext): ProjectAttribution[];
60
- /**
61
- * 0..100 score for UI display.
62
- */
63
- export declare function confidenceToPercent(confidence: number): number;
64
- /**
65
- * True when attribution is strong enough for project-level spending claims.
66
- */
67
- export declare function isHighConfidenceAttribution(confidence: number): boolean;
68
- /**
69
- * Lightweight utility used by some hooks to normalize path separators
70
- * before writing attribution metadata.
71
- */
72
- export declare function normalizeProjectDir(projectDir: string): string;
73
- export declare const PROJECT_ATTRIBUTION_VERSION = 1;
@@ -1,245 +0,0 @@
1
- /**
2
- * Project attribution heuristics for session events.
3
- *
4
- * Goal: avoid pinning all activity to the startup directory when work shifts
5
- * across projects mid-session. This module resolves a best-effort project
6
- * directory per event and attaches a confidence score + source signal.
7
- */
8
- import { dirname, isAbsolute, normalize, resolve, sep } from "node:path";
9
- /**
10
- * Confidence scores for project attribution sources.
11
- *
12
- * Higher = more reliable signal. The hierarchy reflects how directly
13
- * the signal indicates the user's intended project:
14
- * - Explicit config (workspace roots) > explicit navigation (cd) > implicit context
15
- * - Path-bearing events score higher than fallbacks without path signals
16
- */
17
- export const ATTRIBUTION_CONFIDENCE = {
18
- /** Explicit workspace root from IDE/editor config */
19
- WORKSPACE_ROOT: 0.98,
20
- /** User explicitly navigated here (cd command) */
21
- CWD_EVENT: 0.9,
22
- /** Hook payload cwd — reliable but implicit */
23
- INPUT_CWD: 0.88,
24
- /** Session startup directory */
25
- SESSION_ORIGIN: 0.82,
26
- /** Carry-forward from previous high-confidence event */
27
- LAST_SEEN: 0.76,
28
- /** Inferred from file path prefix matching */
29
- EVENT_PATH: 0.7,
30
- /** Minimum confidence to carry forward as lastKnownProjectDir */
31
- CARRY_FORWARD_THRESHOLD: 0.55,
32
- /** Fallback: input_cwd without path signal */
33
- FALLBACK_INPUT_CWD: 0.45,
34
- /** Fallback: last_seen without path signal */
35
- FALLBACK_LAST_SEEN: 0.4,
36
- /** Fallback: session_origin without path signal */
37
- FALLBACK_SESSION_ORIGIN: 0.35,
38
- };
39
- function normalizePath(path) {
40
- const norm = normalize(path).replace(/\\/g, "/");
41
- if (norm.length <= 1)
42
- return norm;
43
- return norm.replace(/\/+$/, "");
44
- }
45
- function isPrefixPath(path, prefix) {
46
- if (!path || !prefix)
47
- return false;
48
- if (path === prefix)
49
- return true;
50
- return path.startsWith(`${prefix}/`);
51
- }
52
- function normalizeRoots(roots) {
53
- if (!roots || roots.length === 0)
54
- return [];
55
- const normalized = roots
56
- .filter((r) => typeof r === "string" && r.trim().length > 0)
57
- .map((r) => normalizePath(r));
58
- // dedupe + longest-first for stable best match
59
- const unique = Array.from(new Set(normalized));
60
- return unique.sort((a, b) => b.length - a.length);
61
- }
62
- function parseFileSearchPath(data) {
63
- const marker = " in ";
64
- const idx = data.lastIndexOf(marker);
65
- if (idx < 0)
66
- return null;
67
- const path = data.slice(idx + marker.length).trim();
68
- return path.length > 0 ? path : null;
69
- }
70
- function looksLikePath(value) {
71
- if (!value)
72
- return false;
73
- // Fast path-like checks: separators, dot segments, drive roots.
74
- return value.includes("/")
75
- || value.includes("\\")
76
- || value.startsWith(".")
77
- || /^[A-Za-z]:[\\/]/.test(value);
78
- }
79
- function extractPathSignal(event) {
80
- if (event.type === "cwd") {
81
- return { rawPath: event.data, fromCwdEvent: true };
82
- }
83
- if (event.type === "file_search") {
84
- const path = parseFileSearchPath(event.data);
85
- if (path)
86
- return { rawPath: path, fromCwdEvent: false };
87
- }
88
- const fileTypes = new Set([
89
- "file_read",
90
- "file_write",
91
- "file_edit",
92
- "file_glob",
93
- "rule",
94
- ]);
95
- if (fileTypes.has(event.type) && looksLikePath(event.data)) {
96
- return { rawPath: event.data, fromCwdEvent: false };
97
- }
98
- return null;
99
- }
100
- function absolutizePath(rawPath, context) {
101
- if (!rawPath)
102
- return null;
103
- // Ignore broad glob-only patterns that aren't useful for attribution.
104
- if (rawPath.includes("*") && !isAbsolute(rawPath) && !/^[A-Za-z]:[\\/]/.test(rawPath)) {
105
- return null;
106
- }
107
- if (isAbsolute(rawPath) || /^[A-Za-z]:[\\/]/.test(rawPath)) {
108
- return normalizePath(rawPath);
109
- }
110
- // For relative paths, anchor to the most recent known project first.
111
- const anchor = context.lastKnownProjectDir
112
- || context.inputProjectDir
113
- || context.sessionOriginDir
114
- || null;
115
- if (!anchor)
116
- return null;
117
- return normalizePath(resolve(anchor, rawPath));
118
- }
119
- function inferProjectFromAbsolutePath(absPath, event, context) {
120
- const normalizedRoots = normalizeRoots(context.workspaceRoots);
121
- const normalizedOrigin = context.sessionOriginDir ? normalizePath(context.sessionOriginDir) : "";
122
- const normalizedInput = context.inputProjectDir ? normalizePath(context.inputProjectDir) : "";
123
- const normalizedLast = context.lastKnownProjectDir ? normalizePath(context.lastKnownProjectDir) : "";
124
- // 1) Prefer explicit workspace roots (highest confidence).
125
- const workspaceRoot = normalizedRoots.find((root) => isPrefixPath(absPath, root));
126
- if (workspaceRoot) {
127
- return { projectDir: workspaceRoot, source: "workspace_root", confidence: ATTRIBUTION_CONFIDENCE.WORKSPACE_ROOT };
128
- }
129
- // 2) Prefer stable known roots from session context.
130
- if (normalizedInput && isPrefixPath(absPath, normalizedInput)) {
131
- return { projectDir: normalizedInput, source: "input_cwd", confidence: ATTRIBUTION_CONFIDENCE.INPUT_CWD };
132
- }
133
- if (normalizedOrigin && isPrefixPath(absPath, normalizedOrigin)) {
134
- return { projectDir: normalizedOrigin, source: "session_origin", confidence: ATTRIBUTION_CONFIDENCE.SESSION_ORIGIN };
135
- }
136
- if (normalizedLast && isPrefixPath(absPath, normalizedLast)) {
137
- return { projectDir: normalizedLast, source: "last_seen", confidence: ATTRIBUTION_CONFIDENCE.LAST_SEEN };
138
- }
139
- // 3) Direct cwd events indicate explicit operator intent to shift project.
140
- if (event.type === "cwd") {
141
- return { projectDir: absPath, source: "cwd_event", confidence: ATTRIBUTION_CONFIDENCE.CWD_EVENT };
142
- }
143
- // 4) Fallback for out-of-root absolute paths.
144
- // For known file events, use parent directory to avoid attributing to a file path.
145
- const fileLike = new Set(["file_read", "file_write", "file_edit", "rule"]);
146
- const projectDir = fileLike.has(event.type) ? normalizePath(dirname(absPath)) : absPath;
147
- return { projectDir, source: "event_path", confidence: ATTRIBUTION_CONFIDENCE.EVENT_PATH };
148
- }
149
- function fallbackAttribution(context) {
150
- if (context.inputProjectDir) {
151
- return {
152
- projectDir: normalizePath(context.inputProjectDir),
153
- source: "input_cwd",
154
- confidence: ATTRIBUTION_CONFIDENCE.FALLBACK_INPUT_CWD,
155
- };
156
- }
157
- if (context.lastKnownProjectDir) {
158
- return {
159
- projectDir: normalizePath(context.lastKnownProjectDir),
160
- source: "last_seen",
161
- confidence: ATTRIBUTION_CONFIDENCE.FALLBACK_LAST_SEEN,
162
- };
163
- }
164
- if (context.sessionOriginDir) {
165
- return {
166
- projectDir: normalizePath(context.sessionOriginDir),
167
- source: "session_origin",
168
- confidence: ATTRIBUTION_CONFIDENCE.FALLBACK_SESSION_ORIGIN,
169
- };
170
- }
171
- return { projectDir: "", source: "unknown", confidence: 0 };
172
- }
173
- /**
174
- * Resolve the most likely project directory for one event.
175
- */
176
- export function resolveProjectAttribution(event, context) {
177
- try {
178
- const pathSignal = extractPathSignal(event);
179
- if (!pathSignal)
180
- return fallbackAttribution(context);
181
- const absPath = absolutizePath(pathSignal.rawPath, context);
182
- if (!absPath)
183
- return fallbackAttribution(context);
184
- return inferProjectFromAbsolutePath(absPath, event, context);
185
- }
186
- catch {
187
- return fallbackAttribution(context);
188
- }
189
- }
190
- /**
191
- * Convenience helper: resolve attributions for a stream of events while
192
- * carrying forward the latest confident project as context.
193
- */
194
- export function resolveProjectAttributions(events, context) {
195
- const out = [];
196
- let lastKnown = context.lastKnownProjectDir ? normalizePath(context.lastKnownProjectDir) : "";
197
- // v1.0.162 Bug 8 — track whether an in-batch CWD-level event has explicitly
198
- // re-scoped the project. When extract.ts emits a cwd event for `cd /projB`
199
- // or `git -C /projB ...`, subsequent path-less events in the same batch
200
- // (e.g. the git operation event itself) currently fall back to the hook's
201
- // inputProjectDir, which still points at the session startup cwd. The
202
- // user's INTENTIONAL scoping should win over the hook's startup cwd —
203
- // shadow inputProjectDir with the carried-forward lastKnown once a high-
204
- // confidence cwd event has fired in this batch.
205
- let inBatchCwdScope = false;
206
- for (const ev of events) {
207
- const effectiveInputCwd = inBatchCwdScope ? lastKnown : context.inputProjectDir;
208
- const attribution = resolveProjectAttribution(ev, {
209
- ...context,
210
- inputProjectDir: effectiveInputCwd,
211
- lastKnownProjectDir: lastKnown || context.lastKnownProjectDir || null,
212
- });
213
- out.push(attribution);
214
- if (attribution.projectDir && attribution.confidence >= ATTRIBUTION_CONFIDENCE.CARRY_FORWARD_THRESHOLD) {
215
- lastKnown = attribution.projectDir;
216
- if (attribution.confidence >= ATTRIBUTION_CONFIDENCE.CWD_EVENT) {
217
- inBatchCwdScope = true;
218
- }
219
- }
220
- }
221
- return out;
222
- }
223
- /**
224
- * 0..100 score for UI display.
225
- */
226
- export function confidenceToPercent(confidence) {
227
- const clamped = Math.max(0, Math.min(1, confidence));
228
- return Math.round(clamped * 100);
229
- }
230
- /**
231
- * True when attribution is strong enough for project-level spending claims.
232
- */
233
- export function isHighConfidenceAttribution(confidence) {
234
- return confidence >= 0.8;
235
- }
236
- /**
237
- * Lightweight utility used by some hooks to normalize path separators
238
- * before writing attribution metadata.
239
- */
240
- export function normalizeProjectDir(projectDir) {
241
- return normalizePath(projectDir);
242
- }
243
- export const PROJECT_ATTRIBUTION_VERSION = 1;
244
- // Keep explicit references to path separator for bundlers that tree-shake too aggressively.
245
- void sep;
@@ -1,138 +0,0 @@
1
- /**
2
- * purgeSession — deep module that wipes ALL session-related on-disk artifacts
3
- * for a single project directory.
4
- *
5
- * Why a deep module instead of an inline handler:
6
- * - The previous inline ctx_purge handler was 100+ lines split across three
7
- * try/catch blocks. Only ONE of those blocks knew about the case-fold
8
- * migration's dual-hash legacy filenames, so a partial upgrade could
9
- * leak orphaned events.md / .cleanup files on macOS / Windows.
10
- * - Centralizing the logic here means: one canonical sidecar list, one
11
- * uniform dual-hash sweep, one place to add new file kinds.
12
- *
13
- * Worktree separation guarantee (carried over from the case-fold migration):
14
- * Every path this module touches is derived deterministically from the input
15
- * `projectDir`. There is NO `readdirSync` + glob-filter loop. Different
16
- * worktrees → different physical paths → different canonical hashes →
17
- * different file names → cannot collapse worktrees on disk.
18
- *
19
- * SQLite sidecar handling:
20
- * Each `.db` file may be accompanied by `-wal` (write-ahead log) and `-shm`
21
- * (shared memory index) sidecars. We unlink the triple unconditionally —
22
- * missing sidecars are not an error. This matches the canonical SQLite
23
- * sidecar naming used elsewhere (see refs/platforms/zed/crates/sqlez:
24
- * `[main, "{main}-wal", "{main}-shm"]`).
25
- *
26
- * Cross-platform notes:
27
- * - All paths are joined via `node:path.join` so Windows backslash
28
- * separators and POSIX forward slashes both work.
29
- * - On macOS / Windows (case-insensitive FS) we sweep BOTH the canonical
30
- * (lowercased) and legacy (raw-cased) project-dir hash variants for the
31
- * session-related kinds. On Linux the two hashes coincide, so the dual
32
- * sweep collapses into a single unique-path pass.
33
- */
34
- export interface PurgeOpts {
35
- /**
36
- * Absolute path to the project root. Drives every other path the module
37
- * touches via the project-dir hash. MUST be the same string the rest of
38
- * the system uses (e.g. `getProjectDir()`); otherwise the wrong DB is
39
- * targeted. Worktree separation is preserved — only files matching
40
- * THIS projectDir's hash are unlinked.
41
- */
42
- projectDir: string;
43
- /**
44
- * Adapter-specific session directory (e.g. `~/.claude/context-mode/sessions`).
45
- * Holds: `<hash><suffix>.db`, `<hash><suffix>-events.md`,
46
- * `<hash><suffix>.cleanup`.
47
- */
48
- sessionsDir: string;
49
- /**
50
- * Absolute path to the per-project FTS5 knowledge-base DB
51
- * (e.g. `~/.claude/context-mode/content/<hash>.db`). When omitted no
52
- * FTS5 wipe runs. Caller is responsible for closing any open handle
53
- * BEFORE invoking purgeSession (Windows file locks).
54
- *
55
- * Use `contentDir` instead for new code — it dual-sweeps the canonical
56
- * AND legacy raw-casing variants, mirroring the session events pattern.
57
- * `storePath` remains for callers that have already pre-resolved a single
58
- * absolute path and only want to wipe that exact file.
59
- */
60
- storePath?: string;
61
- /**
62
- * Per-platform FTS5 content directory (e.g.
63
- * `~/.claude/context-mode/content`). When provided, purgeSession sweeps
64
- * BOTH the canonical and legacy raw-casing hash variants of the FTS5
65
- * store inside this directory plus their `-wal` / `-shm` sidecars. This
66
- * is the recommended input — covers a partial upgrade where the user
67
- * had been writing to a legacy raw-casing FTS5 file before the case-fold
68
- * migration landed.
69
- *
70
- * Mutually-additive with `storePath`: if both are passed, both are swept
71
- * (de-duped on path). Closing FTS5 handles before invoking is still the
72
- * caller's responsibility.
73
- */
74
- contentDir?: string;
75
- /**
76
- * Legacy shared content directory at `~/.context-mode/content`. When
77
- * omitted, the legacy content sweep is skipped.
78
- */
79
- legacyContentDir?: string;
80
- /**
81
- * Hash used to locate the legacy shared content DB. Required when
82
- * `legacyContentDir` is provided. Computed by the caller because the
83
- * legacy code-path uses a different hash function than the canonical
84
- * session DB hash.
85
- */
86
- contentHash?: string;
87
- /**
88
- * Issue #520 — scoped purge.
89
- *
90
- * - `"project"` (default when omitted for back-compat callers that
91
- * only pass `confirm:true` at the MCP layer): wipe ALL session
92
- * artifacts for `projectDir`. This is the legacy destructive
93
- * behavior preserved verbatim.
94
- * - `"session"`: wipe ONLY the rows for `sessionId` inside the
95
- * project's SessionDB plus FTS5 chunks tagged with that
96
- * `session_id`. Project-wide files (events.md, content store
97
- * file, stats file) are left intact. Requires `sessionId`.
98
- *
99
- * When `scope` is omitted but `sessionId` is set, behavior implies
100
- * `scope:"session"` (a sessionId-only call cannot mean "wipe the
101
- * whole project"). When neither is set, behavior implies
102
- * `scope:"project"` for back-compat with the original handler.
103
- */
104
- scope?: "session" | "project";
105
- /**
106
- * Session identifier whose rows should be wiped from the project's
107
- * SessionDB and tagged FTS5 chunks. Only consulted when `scope ===
108
- * "session"`. The `session_events`, `session_meta`, and
109
- * `session_resume` rows for this id are removed; rows for other
110
- * sessions in the same DB are preserved. Match SessionDB.deleteSession
111
- * semantics (see src/session/db.ts).
112
- */
113
- sessionId?: string;
114
- }
115
- export interface PurgeResult {
116
- /**
117
- * Human-readable labels rendered to the user by the ctx_purge handler.
118
- * MUST stay backward-compatible with the existing UI strings:
119
- * "knowledge base (FTS5)", "session events DB", "session events markdown".
120
- * Each label appears at most once, and only when at least one matching
121
- * file was actually unlinked.
122
- */
123
- deleted: string[];
124
- /**
125
- * Every full path that was successfully `unlink`ed. Surfaced for tests
126
- * and for diagnostic logging — NEVER shown to end users (the labels
127
- * above carry the human story).
128
- */
129
- wipedPaths: string[];
130
- }
131
- /**
132
- * Wipe every session-related on-disk artifact for `projectDir`.
133
- *
134
- * This function never throws on missing files (a fresh install is a no-op).
135
- * It throws only when given an invalid argument (e.g. `legacyContentDir`
136
- * without `contentHash`), which is a programmer bug not a runtime concern.
137
- */
138
- export declare function purgeSession(opts: PurgeOpts): PurgeResult;