@mxalbert/context-mode 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/.claude-plugin/marketplace.json +33 -0
  2. package/.claude-plugin/plugin.json +31 -0
  3. package/.codex-plugin/hooks.json +65 -0
  4. package/.codex-plugin/mcp.json +13 -0
  5. package/.codex-plugin/plugin.json +31 -0
  6. package/.openclaw-plugin/index.ts +12 -0
  7. package/.openclaw-plugin/openclaw.plugin.json +38 -0
  8. package/.openclaw-plugin/package.json +28 -0
  9. package/LICENSE +94 -0
  10. package/README.md +1619 -0
  11. package/bin/statusline.mjs +378 -0
  12. package/build/adapters/antigravity/index.d.ts +51 -0
  13. package/build/adapters/antigravity/index.js +169 -0
  14. package/build/adapters/antigravity-cli/index.d.ts +51 -0
  15. package/build/adapters/antigravity-cli/index.js +342 -0
  16. package/build/adapters/base.d.ts +92 -0
  17. package/build/adapters/base.js +135 -0
  18. package/build/adapters/claude-code/config.d.ts +8 -0
  19. package/build/adapters/claude-code/config.js +8 -0
  20. package/build/adapters/claude-code/hooks.d.ts +106 -0
  21. package/build/adapters/claude-code/hooks.js +183 -0
  22. package/build/adapters/claude-code/index.d.ts +80 -0
  23. package/build/adapters/claude-code/index.js +569 -0
  24. package/build/adapters/claude-code-base.d.ts +49 -0
  25. package/build/adapters/claude-code-base.js +113 -0
  26. package/build/adapters/client-map.d.ts +10 -0
  27. package/build/adapters/client-map.js +42 -0
  28. package/build/adapters/codex/config.d.ts +8 -0
  29. package/build/adapters/codex/config.js +8 -0
  30. package/build/adapters/codex/hooks.d.ts +55 -0
  31. package/build/adapters/codex/hooks.js +64 -0
  32. package/build/adapters/codex/index.d.ts +87 -0
  33. package/build/adapters/codex/index.js +995 -0
  34. package/build/adapters/codex/paths.d.ts +1 -0
  35. package/build/adapters/codex/paths.js +12 -0
  36. package/build/adapters/codex/usage.d.ts +107 -0
  37. package/build/adapters/codex/usage.js +227 -0
  38. package/build/adapters/copilot-base.d.ts +94 -0
  39. package/build/adapters/copilot-base.js +297 -0
  40. package/build/adapters/copilot-cli/hooks.d.ts +33 -0
  41. package/build/adapters/copilot-cli/hooks.js +64 -0
  42. package/build/adapters/copilot-cli/index.d.ts +48 -0
  43. package/build/adapters/copilot-cli/index.js +341 -0
  44. package/build/adapters/cursor/config.d.ts +4 -0
  45. package/build/adapters/cursor/config.js +4 -0
  46. package/build/adapters/cursor/hooks.d.ts +55 -0
  47. package/build/adapters/cursor/hooks.js +82 -0
  48. package/build/adapters/cursor/index.d.ts +64 -0
  49. package/build/adapters/cursor/index.js +517 -0
  50. package/build/adapters/detect.d.ts +136 -0
  51. package/build/adapters/detect.js +623 -0
  52. package/build/adapters/gemini-cli/config.d.ts +8 -0
  53. package/build/adapters/gemini-cli/config.js +8 -0
  54. package/build/adapters/gemini-cli/hooks.d.ts +83 -0
  55. package/build/adapters/gemini-cli/hooks.js +115 -0
  56. package/build/adapters/gemini-cli/index.d.ts +80 -0
  57. package/build/adapters/gemini-cli/index.js +483 -0
  58. package/build/adapters/jetbrains-copilot/config.d.ts +8 -0
  59. package/build/adapters/jetbrains-copilot/config.js +8 -0
  60. package/build/adapters/jetbrains-copilot/hooks.d.ts +59 -0
  61. package/build/adapters/jetbrains-copilot/hooks.js +87 -0
  62. package/build/adapters/jetbrains-copilot/index.d.ts +31 -0
  63. package/build/adapters/jetbrains-copilot/index.js +131 -0
  64. package/build/adapters/kimi/config.d.ts +8 -0
  65. package/build/adapters/kimi/config.js +8 -0
  66. package/build/adapters/kimi/hooks.d.ts +28 -0
  67. package/build/adapters/kimi/hooks.js +34 -0
  68. package/build/adapters/kimi/index.d.ts +66 -0
  69. package/build/adapters/kimi/index.js +537 -0
  70. package/build/adapters/kimi/paths.d.ts +21 -0
  71. package/build/adapters/kimi/paths.js +52 -0
  72. package/build/adapters/kimi/usage.d.ts +82 -0
  73. package/build/adapters/kimi/usage.js +217 -0
  74. package/build/adapters/kiro/hooks.d.ts +61 -0
  75. package/build/adapters/kiro/hooks.js +94 -0
  76. package/build/adapters/kiro/index.d.ts +61 -0
  77. package/build/adapters/kiro/index.js +301 -0
  78. package/build/adapters/omp/index.d.ts +65 -0
  79. package/build/adapters/omp/index.js +182 -0
  80. package/build/adapters/omp/plugin.d.ts +81 -0
  81. package/build/adapters/omp/plugin.js +331 -0
  82. package/build/adapters/omp/usage.d.ts +49 -0
  83. package/build/adapters/omp/usage.js +110 -0
  84. package/build/adapters/openclaw/config.d.ts +8 -0
  85. package/build/adapters/openclaw/config.js +8 -0
  86. package/build/adapters/openclaw/hooks.d.ts +50 -0
  87. package/build/adapters/openclaw/hooks.js +61 -0
  88. package/build/adapters/openclaw/index.d.ts +74 -0
  89. package/build/adapters/openclaw/index.js +439 -0
  90. package/build/adapters/openclaw/mcp-tools.d.ts +54 -0
  91. package/build/adapters/openclaw/mcp-tools.js +207 -0
  92. package/build/adapters/openclaw/plugin.d.ts +141 -0
  93. package/build/adapters/openclaw/plugin.js +818 -0
  94. package/build/adapters/openclaw/session-db.d.ts +55 -0
  95. package/build/adapters/openclaw/session-db.js +88 -0
  96. package/build/adapters/openclaw/usage.d.ts +34 -0
  97. package/build/adapters/openclaw/usage.js +52 -0
  98. package/build/adapters/openclaw/workspace-router.d.ts +29 -0
  99. package/build/adapters/openclaw/workspace-router.js +64 -0
  100. package/build/adapters/opencode/config.d.ts +8 -0
  101. package/build/adapters/opencode/config.js +8 -0
  102. package/build/adapters/opencode/hooks.d.ts +38 -0
  103. package/build/adapters/opencode/hooks.js +50 -0
  104. package/build/adapters/opencode/index.d.ts +144 -0
  105. package/build/adapters/opencode/index.js +638 -0
  106. package/build/adapters/opencode/plugin.d.ts +249 -0
  107. package/build/adapters/opencode/plugin.js +1536 -0
  108. package/build/adapters/opencode/v2.d.ts +117 -0
  109. package/build/adapters/opencode/v2.js +224 -0
  110. package/build/adapters/opencode/zod3tov4.d.ts +1 -0
  111. package/build/adapters/opencode/zod3tov4.js +132 -0
  112. package/build/adapters/pi/extension.d.ts +81 -0
  113. package/build/adapters/pi/extension.js +861 -0
  114. package/build/adapters/pi/index.d.ts +57 -0
  115. package/build/adapters/pi/index.js +173 -0
  116. package/build/adapters/pi/mcp-bridge.d.ts +268 -0
  117. package/build/adapters/pi/mcp-bridge.js +894 -0
  118. package/build/adapters/qwen-code/hooks.d.ts +26 -0
  119. package/build/adapters/qwen-code/hooks.js +29 -0
  120. package/build/adapters/qwen-code/index.d.ts +40 -0
  121. package/build/adapters/qwen-code/index.js +361 -0
  122. package/build/adapters/qwen-code/usage.d.ts +90 -0
  123. package/build/adapters/qwen-code/usage.js +222 -0
  124. package/build/adapters/types.d.ts +360 -0
  125. package/build/adapters/types.js +118 -0
  126. package/build/adapters/vscode-copilot/config.d.ts +8 -0
  127. package/build/adapters/vscode-copilot/config.js +8 -0
  128. package/build/adapters/vscode-copilot/hooks.d.ts +71 -0
  129. package/build/adapters/vscode-copilot/hooks.js +98 -0
  130. package/build/adapters/vscode-copilot/index.d.ts +32 -0
  131. package/build/adapters/vscode-copilot/index.js +222 -0
  132. package/build/adapters/zed/index.d.ts +40 -0
  133. package/build/adapters/zed/index.js +163 -0
  134. package/build/cli.d.ts +34 -0
  135. package/build/cli.js +1828 -0
  136. package/build/db-base.d.ts +250 -0
  137. package/build/db-base.js +756 -0
  138. package/build/executor.d.ts +72 -0
  139. package/build/executor.js +678 -0
  140. package/build/exit-classify.d.ts +19 -0
  141. package/build/exit-classify.js +12 -0
  142. package/build/fetch/blocks.d.ts +145 -0
  143. package/build/fetch/blocks.js +244 -0
  144. package/build/fetch/extract.d.ts +68 -0
  145. package/build/fetch/extract.js +123 -0
  146. package/build/fetch/page-store.d.ts +66 -0
  147. package/build/fetch/page-store.js +174 -0
  148. package/build/fetch-cache.d.ts +13 -0
  149. package/build/fetch-cache.js +15 -0
  150. package/build/lifecycle.d.ts +124 -0
  151. package/build/lifecycle.js +278 -0
  152. package/build/package-identity.d.ts +26 -0
  153. package/build/package-identity.js +28 -0
  154. package/build/runPool.d.ts +36 -0
  155. package/build/runPool.js +51 -0
  156. package/build/runtime.d.ts +71 -0
  157. package/build/runtime.js +659 -0
  158. package/build/search/auto-memory.d.ts +47 -0
  159. package/build/search/auto-memory.js +170 -0
  160. package/build/search/ctx-search-schema.d.ts +90 -0
  161. package/build/search/ctx-search-schema.js +135 -0
  162. package/build/search/flood-guard.d.ts +57 -0
  163. package/build/search/flood-guard.js +80 -0
  164. package/build/search/unified.d.ts +56 -0
  165. package/build/search/unified.js +104 -0
  166. package/build/security.d.ts +206 -0
  167. package/build/security.js +780 -0
  168. package/build/server.d.ts +240 -0
  169. package/build/server.js +5034 -0
  170. package/build/session/analytics.d.ts +773 -0
  171. package/build/session/analytics.js +2420 -0
  172. package/build/session/db.d.ts +468 -0
  173. package/build/session/db.js +1330 -0
  174. package/build/session/error-classifier.d.ts +87 -0
  175. package/build/session/error-classifier.js +303 -0
  176. package/build/session/event-emit.d.ts +48 -0
  177. package/build/session/event-emit.js +101 -0
  178. package/build/session/extract.d.ts +333 -0
  179. package/build/session/extract.js +2688 -0
  180. package/build/session/model-prices.json +429 -0
  181. package/build/session/persist-tool-calls.d.ts +54 -0
  182. package/build/session/persist-tool-calls.js +105 -0
  183. package/build/session/pricing.d.ts +64 -0
  184. package/build/session/pricing.js +151 -0
  185. package/build/session/project-attribution.d.ts +73 -0
  186. package/build/session/project-attribution.js +245 -0
  187. package/build/session/purge.d.ts +138 -0
  188. package/build/session/purge.js +240 -0
  189. package/build/session/retrieval-marker.d.ts +39 -0
  190. package/build/session/retrieval-marker.js +65 -0
  191. package/build/session/snapshot.d.ts +46 -0
  192. package/build/session/snapshot.js +532 -0
  193. package/build/store-directory.d.ts +56 -0
  194. package/build/store-directory.js +254 -0
  195. package/build/store.d.ts +147 -0
  196. package/build/store.js +1714 -0
  197. package/build/truncate.d.ts +57 -0
  198. package/build/truncate.js +142 -0
  199. package/build/types.d.ts +117 -0
  200. package/build/types.js +20 -0
  201. package/build/util/claude-config.d.ts +32 -0
  202. package/build/util/claude-config.js +84 -0
  203. package/build/util/hook-config.d.ts +27 -0
  204. package/build/util/hook-config.js +76 -0
  205. package/build/util/jsonc.d.ts +14 -0
  206. package/build/util/jsonc.js +104 -0
  207. package/build/util/plugin-cache-integrity.d.ts +51 -0
  208. package/build/util/plugin-cache-integrity.js +146 -0
  209. package/build/util/project-dir.d.ts +149 -0
  210. package/build/util/project-dir.js +340 -0
  211. package/build/util/sibling-mcp.d.ts +79 -0
  212. package/build/util/sibling-mcp.js +181 -0
  213. package/cli.bundle.mjs +1495 -0
  214. package/configs/antigravity/GEMINI.md +68 -0
  215. package/configs/antigravity/mcp_config.json +7 -0
  216. package/configs/antigravity-cli/hooks/hooks.json +37 -0
  217. package/configs/antigravity-cli/hooks.json +37 -0
  218. package/configs/antigravity-cli/mcp_config.json +10 -0
  219. package/configs/antigravity-cli/plugin.json +14 -0
  220. package/configs/antigravity-cli/rules/context-mode.md +77 -0
  221. package/configs/antigravity-cli/skills/context-mode/SKILL.md +77 -0
  222. package/configs/claude-code/CLAUDE.md +91 -0
  223. package/configs/codex/AGENTS.md +99 -0
  224. package/configs/codex/config.toml +8 -0
  225. package/configs/codex/hooks.json +47 -0
  226. package/configs/copilot-cli/.github/plugin/plugin.json +23 -0
  227. package/configs/copilot-cli/.mcp.json +12 -0
  228. package/configs/copilot-cli/README.md +47 -0
  229. package/configs/copilot-cli/hooks.json +41 -0
  230. package/configs/copilot-cli/skills/context-mode/SKILL.md +38 -0
  231. package/configs/cursor/context-mode.mdc +76 -0
  232. package/configs/cursor/hooks.json +21 -0
  233. package/configs/cursor/mcp.json +7 -0
  234. package/configs/gemini-cli/GEMINI.md +88 -0
  235. package/configs/gemini-cli/mcp.json +7 -0
  236. package/configs/gemini-cli/settings.json +60 -0
  237. package/configs/jetbrains-copilot/copilot-instructions.md +80 -0
  238. package/configs/jetbrains-copilot/hooks.json +16 -0
  239. package/configs/jetbrains-copilot/mcp.json +7 -0
  240. package/configs/kilo/AGENTS.md +84 -0
  241. package/configs/kilo/kilo.json +6 -0
  242. package/configs/kimi/hooks.json +54 -0
  243. package/configs/kiro/KIRO.md +84 -0
  244. package/configs/kiro/agent.json +18 -0
  245. package/configs/kiro/mcp.json +7 -0
  246. package/configs/omp/SYSTEM.md +85 -0
  247. package/configs/omp/mcp.json +7 -0
  248. package/configs/openclaw/AGENTS.md +87 -0
  249. package/configs/openclaw/openclaw.json +13 -0
  250. package/configs/opencode/AGENTS.md +84 -0
  251. package/configs/opencode/opencode.json +6 -0
  252. package/configs/pi/AGENTS.md +3 -0
  253. package/configs/qwen-code/QWEN.md +91 -0
  254. package/configs/vscode-copilot/copilot-instructions.md +80 -0
  255. package/configs/vscode-copilot/hooks.json +16 -0
  256. package/configs/vscode-copilot/mcp.json +7 -0
  257. package/configs/zed/AGENTS.md +68 -0
  258. package/hooks/antigravity-cli/payload.mjs +98 -0
  259. package/hooks/antigravity-cli/posttooluse.mjs +138 -0
  260. package/hooks/antigravity-cli/pretooluse.mjs +78 -0
  261. package/hooks/antigravity-cli/stop.mjs +58 -0
  262. package/hooks/auto-injection.mjs +102 -0
  263. package/hooks/cache-heal-utils.mjs +379 -0
  264. package/hooks/codex/platform.mjs +1 -0
  265. package/hooks/codex/posttooluse.mjs +66 -0
  266. package/hooks/codex/precompact.mjs +70 -0
  267. package/hooks/codex/pretooluse.mjs +42 -0
  268. package/hooks/codex/sessionstart.mjs +121 -0
  269. package/hooks/codex/stop.mjs +138 -0
  270. package/hooks/codex/userpromptsubmit.mjs +75 -0
  271. package/hooks/copilot-cli/posttooluse.mjs +79 -0
  272. package/hooks/copilot-cli/precompact.mjs +66 -0
  273. package/hooks/copilot-cli/pretooluse.mjs +41 -0
  274. package/hooks/copilot-cli/sessionstart.mjs +121 -0
  275. package/hooks/copilot-cli/stop.mjs +59 -0
  276. package/hooks/copilot-cli/userpromptsubmit.mjs +77 -0
  277. package/hooks/core/codex-caps.mjs +112 -0
  278. package/hooks/core/formatters.mjs +356 -0
  279. package/hooks/core/mcp-ready.mjs +109 -0
  280. package/hooks/core/platform-detect.mjs +49 -0
  281. package/hooks/core/routing.mjs +1050 -0
  282. package/hooks/core/stdin.mjs +90 -0
  283. package/hooks/core/tool-naming.mjs +57 -0
  284. package/hooks/cursor/afteragentresponse.mjs +74 -0
  285. package/hooks/cursor/hooks.json +31 -0
  286. package/hooks/cursor/posttooluse.mjs +72 -0
  287. package/hooks/cursor/pretooluse.mjs +26 -0
  288. package/hooks/cursor/sessionstart.mjs +97 -0
  289. package/hooks/cursor/stop.mjs +48 -0
  290. package/hooks/ensure-deps.mjs +254 -0
  291. package/hooks/formatters/claude-code.mjs +113 -0
  292. package/hooks/formatters/cursor.mjs +37 -0
  293. package/hooks/formatters/gemini-cli.mjs +55 -0
  294. package/hooks/formatters/vscode-copilot.mjs +55 -0
  295. package/hooks/gemini-cli/aftermodel.mjs +70 -0
  296. package/hooks/gemini-cli/aftertool.mjs +61 -0
  297. package/hooks/gemini-cli/beforeagent.mjs +99 -0
  298. package/hooks/gemini-cli/beforetool.mjs +27 -0
  299. package/hooks/gemini-cli/precompress.mjs +55 -0
  300. package/hooks/gemini-cli/sessionstart.mjs +137 -0
  301. package/hooks/heal-partial-install.mjs +712 -0
  302. package/hooks/hooks.json +143 -0
  303. package/hooks/jetbrains-copilot/posttooluse.mjs +61 -0
  304. package/hooks/jetbrains-copilot/precompact.mjs +55 -0
  305. package/hooks/jetbrains-copilot/pretooluse.mjs +27 -0
  306. package/hooks/jetbrains-copilot/sessionstart.mjs +124 -0
  307. package/hooks/kimi/platform.mjs +1 -0
  308. package/hooks/kimi/posttooluse.mjs +72 -0
  309. package/hooks/kimi/precompact.mjs +80 -0
  310. package/hooks/kimi/pretooluse.mjs +42 -0
  311. package/hooks/kimi/sessionend.mjs +61 -0
  312. package/hooks/kimi/sessionstart.mjs +113 -0
  313. package/hooks/kimi/stop.mjs +132 -0
  314. package/hooks/kimi/userpromptsubmit.mjs +90 -0
  315. package/hooks/kiro/agentspawn.mjs +97 -0
  316. package/hooks/kiro/posttooluse.mjs +51 -0
  317. package/hooks/kiro/pretooluse.mjs +64 -0
  318. package/hooks/kiro/userpromptsubmit.mjs +88 -0
  319. package/hooks/normalize-hooks.mjs +323 -0
  320. package/hooks/platform-bridge.mjs +340 -0
  321. package/hooks/posttooluse.mjs +225 -0
  322. package/hooks/precompact.mjs +100 -0
  323. package/hooks/pretooluse.mjs +227 -0
  324. package/hooks/qwen-code/platform.mjs +1 -0
  325. package/hooks/qwen-code/stop.mjs +168 -0
  326. package/hooks/routing-block.mjs +105 -0
  327. package/hooks/run-hook.mjs +95 -0
  328. package/hooks/security.bundle.mjs +2 -0
  329. package/hooks/session-attribution.bundle.mjs +1 -0
  330. package/hooks/session-db.bundle.mjs +145 -0
  331. package/hooks/session-directive.mjs +520 -0
  332. package/hooks/session-extract.bundle.mjs +3 -0
  333. package/hooks/session-helpers.mjs +428 -0
  334. package/hooks/session-loaders.mjs +448 -0
  335. package/hooks/session-snapshot.bundle.mjs +32 -0
  336. package/hooks/sessionstart.mjs +464 -0
  337. package/hooks/stop.mjs +82 -0
  338. package/hooks/suppress-stderr.mjs +25 -0
  339. package/hooks/userpromptsubmit.mjs +108 -0
  340. package/hooks/vscode-copilot/posttooluse.mjs +61 -0
  341. package/hooks/vscode-copilot/precompact.mjs +55 -0
  342. package/hooks/vscode-copilot/pretooluse.mjs +27 -0
  343. package/hooks/vscode-copilot/sessionstart.mjs +129 -0
  344. package/openclaw.plugin.json +38 -0
  345. package/package.json +132 -0
  346. package/scripts/heal-better-sqlite3.mjs +430 -0
  347. package/scripts/heal-installed-plugins.mjs +635 -0
  348. package/scripts/plugin-cache-integrity.mjs +248 -0
  349. package/scripts/postinstall.mjs +397 -0
  350. package/server.bundle.mjs +1421 -0
  351. package/server.js +5 -0
  352. package/skills/.ignore +7 -0
  353. package/skills/context-mode/SKILL.md +300 -0
  354. package/skills/context-mode/references/anti-patterns.md +283 -0
  355. package/skills/context-mode/references/patterns-javascript.md +298 -0
  356. package/skills/context-mode/references/patterns-python.md +304 -0
  357. package/skills/context-mode/references/patterns-shell.md +277 -0
  358. package/skills/ctx-doctor/SKILL.md +22 -0
  359. package/skills/ctx-index/SKILL.md +46 -0
  360. package/skills/ctx-insight/SKILL.md +24 -0
  361. package/skills/ctx-purge/SKILL.md +49 -0
  362. package/skills/ctx-search/SKILL.md +35 -0
  363. package/skills/ctx-stats/SKILL.md +26 -0
  364. package/skills/ctx-upgrade/SKILL.md +31 -0
  365. package/start.mjs +616 -0
@@ -0,0 +1,429 @@
1
+ {
2
+ "claude-opus-4-8": {
3
+ "input_per_mtok": 5,
4
+ "output_per_mtok": 25,
5
+ "cache_read_per_mtok": 0.5,
6
+ "cache_write_per_mtok": 6.25,
7
+ "source": "https://platform.claude.com/docs/en/about-claude/pricing"
8
+ },
9
+ "claude-opus-4-7": {
10
+ "input_per_mtok": 5,
11
+ "output_per_mtok": 25,
12
+ "cache_read_per_mtok": 0.5,
13
+ "cache_write_per_mtok": 6.25,
14
+ "source": "https://platform.claude.com/docs/en/about-claude/pricing"
15
+ },
16
+ "claude-opus-4-6": {
17
+ "input_per_mtok": 5,
18
+ "output_per_mtok": 25,
19
+ "cache_read_per_mtok": 0.5,
20
+ "cache_write_per_mtok": 6.25,
21
+ "source": "https://platform.claude.com/docs/en/about-claude/pricing"
22
+ },
23
+ "claude-opus-4-5": {
24
+ "input_per_mtok": 5,
25
+ "output_per_mtok": 25,
26
+ "cache_read_per_mtok": 0.5,
27
+ "cache_write_per_mtok": 6.25,
28
+ "source": "https://platform.claude.com/docs/en/about-claude/pricing"
29
+ },
30
+ "claude-sonnet-4-6": {
31
+ "input_per_mtok": 3,
32
+ "output_per_mtok": 15,
33
+ "cache_read_per_mtok": 0.3,
34
+ "cache_write_per_mtok": 3.75,
35
+ "source": "https://platform.claude.com/docs/en/about-claude/pricing"
36
+ },
37
+ "claude-sonnet-4-5": {
38
+ "input_per_mtok": 3,
39
+ "output_per_mtok": 15,
40
+ "cache_read_per_mtok": 0.3,
41
+ "cache_write_per_mtok": 3.75,
42
+ "source": "https://platform.claude.com/docs/en/about-claude/pricing"
43
+ },
44
+ "claude-haiku-4-5": {
45
+ "input_per_mtok": 1,
46
+ "output_per_mtok": 5,
47
+ "cache_read_per_mtok": 0.1,
48
+ "cache_write_per_mtok": 1.25,
49
+ "source": "https://platform.claude.com/docs/en/about-claude/pricing"
50
+ },
51
+ "claude-3-7-sonnet": {
52
+ "input_per_mtok": 3,
53
+ "output_per_mtok": 15,
54
+ "cache_read_per_mtok": 0.3,
55
+ "cache_write_per_mtok": 3.75,
56
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
57
+ },
58
+ "claude-3-5-haiku": {
59
+ "input_per_mtok": 0.8,
60
+ "output_per_mtok": 4,
61
+ "cache_read_per_mtok": 0.08,
62
+ "cache_write_per_mtok": 1,
63
+ "source": "https://platform.claude.com/docs/en/about-claude/pricing"
64
+ },
65
+ "claude-fable-5": {
66
+ "input_per_mtok": 10,
67
+ "output_per_mtok": 50,
68
+ "cache_read_per_mtok": 1,
69
+ "cache_write_per_mtok": 12.5,
70
+ "source": "https://platform.claude.com/docs/en/about-claude/pricing"
71
+ },
72
+ "gpt-5": {
73
+ "input_per_mtok": 1.25,
74
+ "output_per_mtok": 10,
75
+ "cache_read_per_mtok": 0.125,
76
+ "cache_write_per_mtok": null,
77
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
78
+ },
79
+ "gpt-5-mini": {
80
+ "input_per_mtok": 0.25,
81
+ "output_per_mtok": 2,
82
+ "cache_read_per_mtok": 0.025,
83
+ "cache_write_per_mtok": null,
84
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
85
+ },
86
+ "gpt-5-nano": {
87
+ "input_per_mtok": 0.05,
88
+ "output_per_mtok": 0.4,
89
+ "cache_read_per_mtok": 0.005,
90
+ "cache_write_per_mtok": null,
91
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
92
+ },
93
+ "gpt-5-codex": {
94
+ "input_per_mtok": 1.25,
95
+ "output_per_mtok": 10,
96
+ "cache_read_per_mtok": 0.125,
97
+ "cache_write_per_mtok": null,
98
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
99
+ },
100
+ "gpt-4.1": {
101
+ "input_per_mtok": 2,
102
+ "output_per_mtok": 8,
103
+ "cache_read_per_mtok": 0.5,
104
+ "cache_write_per_mtok": null,
105
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
106
+ },
107
+ "gpt-4.1-mini": {
108
+ "input_per_mtok": 0.4,
109
+ "output_per_mtok": 1.6,
110
+ "cache_read_per_mtok": 0.1,
111
+ "cache_write_per_mtok": null,
112
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
113
+ },
114
+ "gpt-4.1-nano": {
115
+ "input_per_mtok": 0.1,
116
+ "output_per_mtok": 0.4,
117
+ "cache_read_per_mtok": 0.025,
118
+ "cache_write_per_mtok": null,
119
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
120
+ },
121
+ "gpt-4o": {
122
+ "input_per_mtok": 2.5,
123
+ "output_per_mtok": 10,
124
+ "cache_read_per_mtok": 1.25,
125
+ "cache_write_per_mtok": null,
126
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
127
+ },
128
+ "gpt-4o-mini": {
129
+ "input_per_mtok": 0.15,
130
+ "output_per_mtok": 0.6,
131
+ "cache_read_per_mtok": 0.075,
132
+ "cache_write_per_mtok": null,
133
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
134
+ },
135
+ "o3": {
136
+ "input_per_mtok": 2,
137
+ "output_per_mtok": 8,
138
+ "cache_read_per_mtok": 0.5,
139
+ "cache_write_per_mtok": null,
140
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
141
+ },
142
+ "o4-mini": {
143
+ "input_per_mtok": 1.1,
144
+ "output_per_mtok": 4.4,
145
+ "cache_read_per_mtok": 0.275,
146
+ "cache_write_per_mtok": null,
147
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
148
+ },
149
+ "o3-mini": {
150
+ "input_per_mtok": 1.1,
151
+ "output_per_mtok": 4.4,
152
+ "cache_read_per_mtok": 0.55,
153
+ "cache_write_per_mtok": null,
154
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
155
+ },
156
+ "codex-mini-latest": {
157
+ "input_per_mtok": 1.5,
158
+ "output_per_mtok": 6,
159
+ "cache_read_per_mtok": 0.375,
160
+ "cache_write_per_mtok": null,
161
+ "source": "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"
162
+ },
163
+ "gemini-2.5-pro": {
164
+ "input_per_mtok": 1.25,
165
+ "output_per_mtok": 10,
166
+ "cache_read_per_mtok": 0.125,
167
+ "cache_write_per_mtok": null,
168
+ "source": "https://ai.google.dev/gemini-api/docs/pricing"
169
+ },
170
+ "gemini-2.5-flash": {
171
+ "input_per_mtok": 0.3,
172
+ "output_per_mtok": 2.5,
173
+ "cache_read_per_mtok": 0.03,
174
+ "cache_write_per_mtok": null,
175
+ "source": "https://ai.google.dev/gemini-api/docs/pricing"
176
+ },
177
+ "gemini-2.5-flash-lite": {
178
+ "input_per_mtok": 0.1,
179
+ "output_per_mtok": 0.4,
180
+ "cache_read_per_mtok": 0.01,
181
+ "cache_write_per_mtok": null,
182
+ "source": "https://ai.google.dev/gemini-api/docs/pricing"
183
+ },
184
+ "gemini-2.0-flash": {
185
+ "input_per_mtok": 0.1,
186
+ "output_per_mtok": 0.4,
187
+ "cache_read_per_mtok": 0.025,
188
+ "cache_write_per_mtok": null,
189
+ "source": "https://ai.google.dev/gemini-api/docs/pricing"
190
+ },
191
+ "gemini-2.0-flash-lite": {
192
+ "input_per_mtok": 0.075,
193
+ "output_per_mtok": 0.3,
194
+ "cache_read_per_mtok": null,
195
+ "cache_write_per_mtok": null,
196
+ "source": "https://ai.google.dev/gemini-api/docs/pricing"
197
+ },
198
+ "gemini-3-pro-preview": {
199
+ "input_per_mtok": 2,
200
+ "output_per_mtok": 12,
201
+ "cache_read_per_mtok": 0.2,
202
+ "cache_write_per_mtok": null,
203
+ "source": "https://ai.google.dev/gemini-api/docs/pricing"
204
+ },
205
+ "gemini-3-flash-preview": {
206
+ "input_per_mtok": 0.5,
207
+ "output_per_mtok": 3,
208
+ "cache_read_per_mtok": 0.05,
209
+ "cache_write_per_mtok": null,
210
+ "source": "https://ai.google.dev/gemini-api/docs/pricing"
211
+ },
212
+ "qwen3-coder": {
213
+ "input_per_mtok": 1,
214
+ "output_per_mtok": 5,
215
+ "cache_read_per_mtok": null,
216
+ "cache_write_per_mtok": null,
217
+ "source": "https://www.alibabacloud.com/help/en/model-studio/models"
218
+ },
219
+ "qwen-max": {
220
+ "input_per_mtok": 1.6,
221
+ "output_per_mtok": 6.4,
222
+ "cache_read_per_mtok": null,
223
+ "cache_write_per_mtok": null,
224
+ "source": "https://www.alibabacloud.com/help/en/model-studio/models"
225
+ },
226
+ "qwen-plus": {
227
+ "input_per_mtok": 0.4,
228
+ "output_per_mtok": 1.2,
229
+ "cache_read_per_mtok": null,
230
+ "cache_write_per_mtok": null,
231
+ "source": "https://www.alibabacloud.com/help/en/model-studio/models"
232
+ },
233
+ "qwen-turbo": {
234
+ "input_per_mtok": 0.05,
235
+ "output_per_mtok": 0.2,
236
+ "cache_read_per_mtok": null,
237
+ "cache_write_per_mtok": null,
238
+ "source": "https://www.alibabacloud.com/help/en/model-studio/models"
239
+ },
240
+ "qwen3-max": {
241
+ "input_per_mtok": 1.2,
242
+ "output_per_mtok": 6,
243
+ "cache_read_per_mtok": null,
244
+ "cache_write_per_mtok": null,
245
+ "source": "https://www.alibabacloud.com/help/en/model-studio/models"
246
+ },
247
+ "kimi-k2": {
248
+ "input_per_mtok": 0.6,
249
+ "output_per_mtok": 2.5,
250
+ "cache_read_per_mtok": 0.15,
251
+ "cache_write_per_mtok": null,
252
+ "source": "https://platform.moonshot.ai/docs/pricing/chat"
253
+ },
254
+ "kimi-k2-turbo": {
255
+ "input_per_mtok": 1.15,
256
+ "output_per_mtok": 8,
257
+ "cache_read_per_mtok": 0.15,
258
+ "cache_write_per_mtok": null,
259
+ "source": "https://platform.moonshot.ai/docs/pricing/chat"
260
+ },
261
+ "moonshot-v1-8k": {
262
+ "input_per_mtok": 0.2,
263
+ "output_per_mtok": 2,
264
+ "cache_read_per_mtok": null,
265
+ "cache_write_per_mtok": null,
266
+ "source": "https://platform.moonshot.ai/docs/pricing"
267
+ },
268
+ "moonshot-v1-32k": {
269
+ "input_per_mtok": 1,
270
+ "output_per_mtok": 3,
271
+ "cache_read_per_mtok": null,
272
+ "cache_write_per_mtok": null,
273
+ "source": "https://platform.moonshot.ai/docs/pricing"
274
+ },
275
+ "moonshot-v1-128k": {
276
+ "input_per_mtok": 2,
277
+ "output_per_mtok": 5,
278
+ "cache_read_per_mtok": null,
279
+ "cache_write_per_mtok": null,
280
+ "source": "https://platform.moonshot.ai/docs/pricing"
281
+ },
282
+ "deepseek-v3": {
283
+ "input_per_mtok": 0.27,
284
+ "output_per_mtok": 1.1,
285
+ "cache_read_per_mtok": 0.07,
286
+ "cache_write_per_mtok": 0,
287
+ "source": "https://api-docs.deepseek.com/quick_start/pricing"
288
+ },
289
+ "deepseek-r1": {
290
+ "input_per_mtok": 0.55,
291
+ "output_per_mtok": 2.19,
292
+ "cache_read_per_mtok": null,
293
+ "cache_write_per_mtok": null,
294
+ "source": "https://api-docs.deepseek.com/quick_start/pricing"
295
+ },
296
+ "deepseek-chat": {
297
+ "input_per_mtok": 0.14,
298
+ "output_per_mtok": 0.28,
299
+ "cache_read_per_mtok": 0.0028,
300
+ "cache_write_per_mtok": null,
301
+ "source": "https://api-docs.deepseek.com/quick_start/pricing"
302
+ },
303
+ "deepseek-reasoner": {
304
+ "input_per_mtok": 0.14,
305
+ "output_per_mtok": 0.28,
306
+ "cache_read_per_mtok": 0.0028,
307
+ "cache_write_per_mtok": null,
308
+ "source": "https://api-docs.deepseek.com/quick_start/pricing"
309
+ },
310
+ "glm-4.6": {
311
+ "input_per_mtok": 0.6,
312
+ "output_per_mtok": 2.2,
313
+ "cache_read_per_mtok": 0.11,
314
+ "cache_write_per_mtok": null,
315
+ "source": "https://docs.z.ai/guides/overview/pricing"
316
+ },
317
+ "glm-4-air": {
318
+ "input_per_mtok": 0.2,
319
+ "output_per_mtok": 1.1,
320
+ "cache_read_per_mtok": 0.03,
321
+ "cache_write_per_mtok": null,
322
+ "source": "https://docs.z.ai/guides/overview/pricing"
323
+ },
324
+ "grok-4": {
325
+ "input_per_mtok": 3,
326
+ "output_per_mtok": 15,
327
+ "cache_read_per_mtok": null,
328
+ "cache_write_per_mtok": null,
329
+ "source": "https://docs.x.ai/docs/pricing"
330
+ },
331
+ "grok-3": {
332
+ "input_per_mtok": 3,
333
+ "output_per_mtok": 15,
334
+ "cache_read_per_mtok": 0.75,
335
+ "cache_write_per_mtok": null,
336
+ "source": "https://docs.x.ai/docs/pricing"
337
+ },
338
+ "grok-code-fast-1": {
339
+ "input_per_mtok": 0.2,
340
+ "output_per_mtok": 1.5,
341
+ "cache_read_per_mtok": 0.02,
342
+ "cache_write_per_mtok": null,
343
+ "source": "https://docs.x.ai/docs/pricing"
344
+ },
345
+ "grok-2": {
346
+ "input_per_mtok": 2,
347
+ "output_per_mtok": 10,
348
+ "cache_read_per_mtok": null,
349
+ "cache_write_per_mtok": null,
350
+ "source": "https://docs.x.ai/docs/pricing"
351
+ },
352
+ "mistral-large-latest": {
353
+ "input_per_mtok": 0.5,
354
+ "output_per_mtok": 1.5,
355
+ "cache_read_per_mtok": null,
356
+ "cache_write_per_mtok": null,
357
+ "source": "https://mistral.ai/pricing"
358
+ },
359
+ "codestral-latest": {
360
+ "input_per_mtok": 0.3,
361
+ "output_per_mtok": 0.9,
362
+ "cache_read_per_mtok": null,
363
+ "cache_write_per_mtok": null,
364
+ "source": "https://mistral.ai/pricing"
365
+ },
366
+ "devstral": {
367
+ "input_per_mtok": 0.4,
368
+ "output_per_mtok": 2,
369
+ "cache_read_per_mtok": null,
370
+ "cache_write_per_mtok": null,
371
+ "source": "https://mistral.ai/pricing"
372
+ },
373
+ "mistral-medium": {
374
+ "input_per_mtok": 0.4,
375
+ "output_per_mtok": 2,
376
+ "cache_read_per_mtok": null,
377
+ "cache_write_per_mtok": null,
378
+ "source": "https://mistral.ai/pricing"
379
+ },
380
+ "llama-4-maverick": {
381
+ "input_per_mtok": 0.27,
382
+ "output_per_mtok": 0.85,
383
+ "cache_read_per_mtok": null,
384
+ "cache_write_per_mtok": null,
385
+ "source": "https://www.together.ai/pricing"
386
+ },
387
+ "llama-4-scout": {
388
+ "input_per_mtok": 0.08,
389
+ "output_per_mtok": 0.3,
390
+ "cache_read_per_mtok": null,
391
+ "cache_write_per_mtok": null,
392
+ "source": "https://www.together.ai/pricing"
393
+ },
394
+ "llama-3.3-70b": {
395
+ "input_per_mtok": 0.88,
396
+ "output_per_mtok": 0.88,
397
+ "cache_read_per_mtok": null,
398
+ "cache_write_per_mtok": null,
399
+ "source": "https://www.together.ai/pricing"
400
+ },
401
+ "command-a": {
402
+ "input_per_mtok": 2.5,
403
+ "output_per_mtok": 10,
404
+ "cache_read_per_mtok": null,
405
+ "cache_write_per_mtok": null,
406
+ "source": "https://cohere.com/pricing"
407
+ },
408
+ "command-r-plus": {
409
+ "input_per_mtok": 2.5,
410
+ "output_per_mtok": 10,
411
+ "cache_read_per_mtok": null,
412
+ "cache_write_per_mtok": null,
413
+ "source": "https://cohere.com/pricing"
414
+ },
415
+ "amazon-nova-pro": {
416
+ "input_per_mtok": 0.8,
417
+ "output_per_mtok": 3.2,
418
+ "cache_read_per_mtok": null,
419
+ "cache_write_per_mtok": null,
420
+ "source": "https://aws.amazon.com/bedrock/pricing/"
421
+ },
422
+ "amazon-nova-lite": {
423
+ "input_per_mtok": 0.06,
424
+ "output_per_mtok": 0.24,
425
+ "cache_read_per_mtok": null,
426
+ "cache_write_per_mtok": null,
427
+ "source": "https://aws.amazon.com/bedrock/pricing/"
428
+ }
429
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * persist-tool-calls — runtime glue between MCP server's in-memory
3
+ * `sessionStats` and the on-disk `tool_calls` SessionDB table.
4
+ *
5
+ * Why this module exists
6
+ * ──────────────────────
7
+ * Commit 4742160 (May 2 16:58) added the SessionDB write path so the
8
+ * statusline counters survived `npm update -g @mxalbert/context-mode` and
9
+ * `claude --continue`. Commit b392c2f (May 2 21:43) — the concurrency
10
+ * refactor — silently dropped that wiring as collateral. Same-session
11
+ * `/ctx-upgrade` flips the statusline back to `0 calls / $0.00`
12
+ * because the new PID starts with an empty `sessionStats` and never
13
+ * looks at the table the old PID was writing to.
14
+ *
15
+ * This module re-introduces the write path AND adds the read-side
16
+ * restore that 4742160 never shipped — both pure helpers so the
17
+ * server.ts wiring is a one-liner and the unit tests don't need to
18
+ * boot the MCP server.
19
+ */
20
+ /**
21
+ * Shape returned by {@link restoreSessionStats}. Subset of the in-memory
22
+ * `sessionStats` object the MCP server keeps — only the fields that can
23
+ * be recovered from SessionDB.
24
+ */
25
+ export interface RestoredSessionStats {
26
+ /** Per-tool call counts. */
27
+ calls: Record<string, number>;
28
+ /** Per-tool returned bytes. */
29
+ bytesReturned: Record<string, number>;
30
+ /**
31
+ * Epoch-ms for `session_meta.started_at` of the latest session, so the
32
+ * statusline `uptime_ms` reflects the original session start instead of
33
+ * resetting to `Date.now()` on every PID change.
34
+ */
35
+ sessionStart: number;
36
+ }
37
+ /**
38
+ * Increment the persistent tool-call counter for `toolName` under whatever
39
+ * session_id `session_meta` currently treats as the most recent. This is
40
+ * called from {@link trackResponse} on every tool response and must be
41
+ * cheap, non-throwing, and best-effort — a stats failure must never break
42
+ * the MCP tool call.
43
+ */
44
+ export declare function persistToolCallCounter(sessionDbPath: string, toolName: string, bytes: number): void;
45
+ /**
46
+ * Read the latest session's tool-call totals back out of SessionDB so the
47
+ * MCP server can hydrate its in-memory `sessionStats` on startup. Returns
48
+ * `null` when the DB is missing or empty so the caller can keep the
49
+ * default zero-state without branching twice.
50
+ *
51
+ * Used during MCP server boot (BEFORE the heartbeat fires) so the
52
+ * statusline doesn't briefly flash `0 calls / $0.00` after upgrade.
53
+ */
54
+ export declare function restoreSessionStats(sessionDbPath: string): RestoredSessionStats | null;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * persist-tool-calls — runtime glue between MCP server's in-memory
3
+ * `sessionStats` and the on-disk `tool_calls` SessionDB table.
4
+ *
5
+ * Why this module exists
6
+ * ──────────────────────
7
+ * Commit 4742160 (May 2 16:58) added the SessionDB write path so the
8
+ * statusline counters survived `npm update -g @mxalbert/context-mode` and
9
+ * `claude --continue`. Commit b392c2f (May 2 21:43) — the concurrency
10
+ * refactor — silently dropped that wiring as collateral. Same-session
11
+ * `/ctx-upgrade` flips the statusline back to `0 calls / $0.00`
12
+ * because the new PID starts with an empty `sessionStats` and never
13
+ * looks at the table the old PID was writing to.
14
+ *
15
+ * This module re-introduces the write path AND adds the read-side
16
+ * restore that 4742160 never shipped — both pure helpers so the
17
+ * server.ts wiring is a one-liner and the unit tests don't need to
18
+ * boot the MCP server.
19
+ */
20
+ import { existsSync } from "node:fs";
21
+ import { SessionDB } from "./db.js";
22
+ /**
23
+ * Increment the persistent tool-call counter for `toolName` under whatever
24
+ * session_id `session_meta` currently treats as the most recent. This is
25
+ * called from {@link trackResponse} on every tool response and must be
26
+ * cheap, non-throwing, and best-effort — a stats failure must never break
27
+ * the MCP tool call.
28
+ */
29
+ export function persistToolCallCounter(sessionDbPath, toolName, bytes) {
30
+ try {
31
+ if (!existsSync(sessionDbPath))
32
+ return;
33
+ const sdb = new SessionDB({ dbPath: sessionDbPath });
34
+ try {
35
+ const sid = sdb.getLatestSessionId();
36
+ if (!sid)
37
+ return;
38
+ sdb.incrementToolCall(sid, toolName, bytes);
39
+ }
40
+ finally {
41
+ sdb.close();
42
+ }
43
+ }
44
+ catch {
45
+ // Best-effort: counter must never throw and break the parent tool call.
46
+ }
47
+ }
48
+ /**
49
+ * Read the latest session's tool-call totals back out of SessionDB so the
50
+ * MCP server can hydrate its in-memory `sessionStats` on startup. Returns
51
+ * `null` when the DB is missing or empty so the caller can keep the
52
+ * default zero-state without branching twice.
53
+ *
54
+ * Used during MCP server boot (BEFORE the heartbeat fires) so the
55
+ * statusline doesn't briefly flash `0 calls / $0.00` after upgrade.
56
+ */
57
+ export function restoreSessionStats(sessionDbPath) {
58
+ try {
59
+ if (!existsSync(sessionDbPath))
60
+ return null;
61
+ const sdb = new SessionDB({ dbPath: sessionDbPath });
62
+ try {
63
+ const sid = sdb.getLatestSessionId();
64
+ if (!sid)
65
+ return null;
66
+ const stats = sdb.getToolCallStats(sid);
67
+ const calls = {};
68
+ const bytesReturned = {};
69
+ for (const [tool, row] of Object.entries(stats.byTool)) {
70
+ calls[tool] = row.calls;
71
+ bytesReturned[tool] = row.bytesReturned;
72
+ }
73
+ // started_at is "YYYY-MM-DD HH:MM:SS" in UTC (SQLite datetime() default);
74
+ // append "Z" so Date.parse interprets it as UTC, matching how the
75
+ // session was actually persisted.
76
+ let sessionStart = Date.now();
77
+ try {
78
+ const meta = sdb.getSessionStats(sid);
79
+ if (meta?.started_at) {
80
+ const parsed = Date.parse(`${meta.started_at}Z`);
81
+ if (Number.isFinite(parsed) && parsed > 0)
82
+ sessionStart = parsed;
83
+ }
84
+ }
85
+ catch {
86
+ // best-effort — keep `Date.now()` fallback
87
+ }
88
+ // Skip empty restores so callers can `if (restored)` and not stomp
89
+ // their already-zero default with another zero.
90
+ if (Object.keys(calls).length === 0 &&
91
+ Object.keys(bytesReturned).length === 0) {
92
+ // Still useful to return sessionStart so uptime_ms doesn't reset
93
+ // even when no tool calls were made — but only if we found a session.
94
+ return { calls, bytesReturned, sessionStart };
95
+ }
96
+ return { calls, bytesReturned, sessionStart };
97
+ }
98
+ finally {
99
+ sdb.close();
100
+ }
101
+ }
102
+ catch {
103
+ return null;
104
+ }
105
+ }
@@ -0,0 +1,64 @@
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
+ /** Per-Mtok price for one model. Any of the four rates may be null ("unknown"). */
27
+ export interface Price {
28
+ input_per_mtok: number | null;
29
+ output_per_mtok: number | null;
30
+ cache_read_per_mtok: number | null;
31
+ cache_write_per_mtok: number | null;
32
+ }
33
+ /** Token counts for one turn. All fields optional; absent ⇒ treated as 0. */
34
+ export interface TokenCounts {
35
+ input_tokens?: number;
36
+ output_tokens?: number;
37
+ cache_read_tokens?: number;
38
+ cache_creation_tokens?: number;
39
+ }
40
+ /**
41
+ * Resolve a model id to its curated Price, or null on miss.
42
+ * Strategy: exact, then normalized (trim+lowercase), then provider-stripped
43
+ * normalized. Misses return null so the caller can decide (warn / fall back).
44
+ */
45
+ export declare function lookupPrice(modelId: string): Price | null;
46
+ /**
47
+ * Σ tokens × per-Mtok price / 1e6 over the four buckets. Returns null when no
48
+ * price is found OR every token count is zero/absent (so dashboards never show
49
+ * a misleading "$0.00 for nothing" row). On a price miss, warns exactly once
50
+ * with the unmatched id so the curated catalog can be extended.
51
+ *
52
+ * Bucket → price mapping:
53
+ * input_tokens → input_per_mtok
54
+ * output_tokens → output_per_mtok (null ⇒ input rate)
55
+ * cache_read_tokens → cache_read_per_mtok (null ⇒ input rate)
56
+ * cache_creation_tokens → cache_write_per_mtok (null ⇒ input rate)
57
+ */
58
+ export declare function computeCostUsd(modelId: string, t: TokenCounts): number | null;
59
+ /**
60
+ * Prefer a provider-supplied native cost when present, else compute from the
61
+ * catalog. A native cost of exactly 0 is a real value (free tier) and passes
62
+ * through — only null/undefined defers to computeCostUsd.
63
+ */
64
+ export declare function nativeOrComputed(modelId: string, t: TokenCounts, nativeCostUsd?: number | null): number | null;