@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,520 @@
1
+ /**
2
+ * Shared session directive builder for all platform adaptors.
3
+ *
4
+ * Contains: groupEvents, writeSessionEventsFile, buildSessionDirective, getSessionEvents, getLatestSessionEvents.
5
+ * Each adaptor imports these instead of duplicating the logic.
6
+ */
7
+
8
+ import { writeFileSync } from "node:fs";
9
+
10
+ // ── Leg-boundary helpers (#780) ──
11
+ // The current Claude Code session_id persists across `--continue` legs, so the
12
+ // events array can carry rows written in a PRIOR leg. The last `session_start`
13
+ // lifecycle event (emitted by the prior leg's SessionStart, before this leg's
14
+ // directive is built — sessionstart.mjs:206/258, 277/293) is the boundary that
15
+ // opened the current leg. Rows with created_at < boundary are prior-leg.
16
+ function computeLegBoundary(events) {
17
+ let boundary = null;
18
+ for (const ev of events) {
19
+ if (ev.category === "session_start" && ev.created_at) boundary = ev.created_at;
20
+ }
21
+ return boundary;
22
+ }
23
+
24
+ // True when an event was written in a leg strictly before the current one.
25
+ // No boundary (first leg) → nothing is prior-leg, so everything stays current.
26
+ function isPriorLeg(ev, boundary) {
27
+ return boundary != null && ev.created_at != null && ev.created_at < boundary;
28
+ }
29
+
30
+ // ── Data References sizing (#840) ──
31
+ // Inlining every captured tool-output verbatim defeats context-mode's own
32
+ // raw-bytes-stay-out principle. Inline only a small recent window; reference
33
+ // large blobs with a one-line pointer. The full payloads stay queryable in
34
+ // FTS5 via ctx_search(source: "session-events").
35
+ const DATA_REF_INLINE_MAX = 8; // most-recent captures rendered inline
36
+ const DATA_REF_ENTRY_MAX = 150; // per-entry char cap before it is referenced
37
+
38
+ function renderDataReferences(entries, push, searchHint) {
39
+ const recent = entries.slice(-DATA_REF_INLINE_MAX);
40
+ for (const ev of recent) {
41
+ const raw = ev.data ?? "";
42
+ const text = raw.length > DATA_REF_ENTRY_MAX
43
+ ? `${raw.substring(0, DATA_REF_ENTRY_MAX - 3)}… (${raw.length} bytes — query ${searchHint})`
44
+ : raw;
45
+ push(`- ${text}`);
46
+ }
47
+ const older = entries.length - recent.length;
48
+ if (older > 0) {
49
+ push(`- … ${older} older captures kept in the sandbox — query ${searchHint}.`);
50
+ }
51
+ }
52
+
53
+ // ── Group events by category and extract metadata ──
54
+ export function groupEvents(events) {
55
+ const grouped = {};
56
+ let lastPrompt = "";
57
+ const legBoundary = computeLegBoundary(events);
58
+ for (const ev of events) {
59
+ if (ev.category === "prompt") {
60
+ lastPrompt = ev.data;
61
+ continue;
62
+ }
63
+ if (!grouped[ev.category]) grouped[ev.category] = [];
64
+ grouped[ev.category].push(ev);
65
+ }
66
+ const fileNames = new Set();
67
+ for (const ev of (grouped.file || [])) {
68
+ const path = ev.data.includes(" in ") ? ev.data.split(" in ").pop() : ev.data;
69
+ const base = path?.split(/[/\\]/).pop()?.trim();
70
+ if (base && !base.includes("*")) fileNames.add(base);
71
+ }
72
+ return { grouped, lastPrompt, fileNames, legBoundary };
73
+ }
74
+
75
+ // ── Write session events as markdown for FTS5 auto-indexing ──
76
+ // Structured with H2 headings per category — optimal for FTS5 chunking.
77
+ export function writeSessionEventsFile(events, eventsPath) {
78
+ const { grouped, lastPrompt, fileNames, legBoundary } = groupEvents(events);
79
+
80
+ const lines = [];
81
+ lines.push("# Session Resume");
82
+ lines.push("");
83
+ lines.push(`Events: ${events.length} | Timestamp: ${new Date().toISOString()}`);
84
+ lines.push("");
85
+
86
+ if (fileNames.size > 0) {
87
+ lines.push("## Active Files");
88
+ lines.push("");
89
+ for (const name of fileNames) lines.push(`- ${name}`);
90
+ lines.push("");
91
+ }
92
+
93
+ if (grouped.rule?.length > 0) {
94
+ lines.push("## Project Rules");
95
+ lines.push("");
96
+ for (const ev of grouped.rule) {
97
+ if (ev.type === "rule_content") {
98
+ const downgraded = ev.data.replace(/^(#{1,3}) /gm, (_, hashes) => "#".repeat(hashes.length + 3) + " ");
99
+ lines.push(downgraded);
100
+ lines.push("");
101
+ } else {
102
+ lines.push(`- ${ev.data}`);
103
+ }
104
+ }
105
+ lines.push("");
106
+ }
107
+
108
+ if (grouped.task?.length > 0) {
109
+ const creates = [];
110
+ const updates = {};
111
+ for (const ev of grouped.task) {
112
+ try {
113
+ const parsed = JSON.parse(ev.data);
114
+ if (parsed.subject) {
115
+ creates.push(parsed.subject);
116
+ } else if (parsed.taskId && parsed.status) {
117
+ updates[parsed.taskId] = parsed.status;
118
+ }
119
+ } catch { /* not JSON — dump as-is */
120
+ creates.push(ev.data);
121
+ }
122
+ }
123
+ const DONE = new Set(["completed", "deleted", "failed"]);
124
+ const sortedIds = Object.keys(updates).sort((a, b) => Number(a) - Number(b));
125
+ const pending = [];
126
+ const completed = [];
127
+ for (let i = 0; i < creates.length; i++) {
128
+ const matchedId = sortedIds[i];
129
+ const status = matchedId ? (updates[matchedId] || "pending") : "pending";
130
+ if (DONE.has(status)) {
131
+ completed.push(creates[i]);
132
+ } else {
133
+ pending.push(creates[i]);
134
+ }
135
+ }
136
+ if (pending.length > 0) {
137
+ lines.push("## Tasks In Progress");
138
+ lines.push("");
139
+ for (const task of pending) lines.push(`- ${task}`);
140
+ lines.push("");
141
+ }
142
+ if (completed.length > 0) {
143
+ lines.push("## Tasks Completed");
144
+ lines.push("");
145
+ for (const task of completed) lines.push(`- ${task}`);
146
+ lines.push("");
147
+ }
148
+ }
149
+
150
+ if (grouped.decision?.length > 0) {
151
+ lines.push("## User Decisions");
152
+ lines.push("");
153
+ for (const ev of grouped.decision) lines.push(`- ${ev.data}`);
154
+ lines.push("");
155
+ }
156
+
157
+ if (grouped.git?.length > 0) {
158
+ lines.push("## Git Operations");
159
+ lines.push("");
160
+ for (const ev of grouped.git) lines.push(`- ${ev.data}`);
161
+ lines.push("");
162
+ }
163
+
164
+ if (grouped.env?.length > 0 || grouped.cwd?.length > 0) {
165
+ lines.push("## Environment");
166
+ lines.push("");
167
+ if (grouped.cwd?.length > 0) {
168
+ lines.push(`- cwd: ${grouped.cwd[grouped.cwd.length - 1].data}`);
169
+ }
170
+ for (const ev of (grouped.env || [])) lines.push(`- ${ev.data}`);
171
+ lines.push("");
172
+ }
173
+
174
+ if (grouped.error?.length > 0) {
175
+ lines.push("## Errors Encountered");
176
+ lines.push("");
177
+ for (const ev of grouped.error) lines.push(`- ${ev.data}`);
178
+ lines.push("");
179
+ }
180
+
181
+ if (grouped.mcp?.length > 0) {
182
+ const toolCounts = {};
183
+ for (const ev of grouped.mcp) {
184
+ const tool = ev.data.split(":")[0].trim();
185
+ toolCounts[tool] = (toolCounts[tool] || 0) + 1;
186
+ }
187
+ lines.push("## MCP Tool Usage");
188
+ lines.push("");
189
+ for (const [tool, count] of Object.entries(toolCounts)) {
190
+ lines.push(`- ${tool}: ${count} calls`);
191
+ }
192
+ lines.push("");
193
+ }
194
+
195
+ if (grouped.subagent?.length > 0) {
196
+ // #780 — only current-leg subagent events are "current". Prior-leg ones
197
+ // are reframed as history so stale [completed]/[launched] labels are not
198
+ // re-injected as if the agent ran in this conversation.
199
+ const currentSub = grouped.subagent.filter(ev => !isPriorLeg(ev, legBoundary));
200
+ const priorSub = grouped.subagent.filter(ev => isPriorLeg(ev, legBoundary));
201
+ if (currentSub.length > 0) {
202
+ lines.push("## Subagent Tasks");
203
+ lines.push("");
204
+ for (const ev of currentSub) lines.push(`- ${ev.data}`);
205
+ lines.push("");
206
+ }
207
+ if (priorSub.length > 0) {
208
+ lines.push("## Subagent Tasks (earlier session — not current)");
209
+ lines.push("");
210
+ for (const ev of priorSub) lines.push(`- ${ev.data}`);
211
+ lines.push("");
212
+ }
213
+ }
214
+
215
+ if (grouped.skill?.length > 0) {
216
+ const uniqueSkills = new Set(grouped.skill.map(e => e.data));
217
+ lines.push("## Active Skills");
218
+ lines.push("");
219
+ lines.push(`- ${[...uniqueSkills].join(", ")}`);
220
+ lines.push("");
221
+ }
222
+
223
+ if (grouped.intent?.length > 0) {
224
+ lines.push("## Session Intent");
225
+ lines.push("");
226
+ lines.push(`- ${grouped.intent[grouped.intent.length - 1].data}`);
227
+ lines.push("");
228
+ }
229
+
230
+ if (grouped.role?.length > 0) {
231
+ lines.push("## User Role");
232
+ lines.push("");
233
+ lines.push(`- ${grouped.role[grouped.role.length - 1].data}`);
234
+ lines.push("");
235
+ }
236
+
237
+ if (grouped.data?.length > 0) {
238
+ lines.push("## Data References");
239
+ lines.push("");
240
+ renderDataReferences(
241
+ grouped.data,
242
+ (l) => lines.push(l),
243
+ 'ctx_search(source: "session-events")',
244
+ );
245
+ lines.push("");
246
+ }
247
+
248
+ if (grouped.plan?.length > 0) {
249
+ const hasApproved = grouped.plan.some(e => e.type === "plan_approved");
250
+ const hasRejected = grouped.plan.some(e => e.type === "plan_rejected");
251
+ const lastPlan = grouped.plan[grouped.plan.length - 1];
252
+ const isActive = lastPlan.type === "plan_enter" || lastPlan.type === "plan_file_write";
253
+ lines.push("## Plan Mode");
254
+ lines.push("");
255
+ if (hasApproved) lines.push("- Status: APPROVED AND EXECUTED");
256
+ else if (hasRejected) lines.push("- Status: REJECTED BY USER");
257
+ else if (isActive) lines.push("- Status: ACTIVE (in planning)");
258
+ else lines.push("- Status: COMPLETED");
259
+ for (const ev of grouped.plan) lines.push(`- ${ev.data}`);
260
+ lines.push("");
261
+ }
262
+
263
+ if (lastPrompt) {
264
+ lines.push("## Last User Prompt");
265
+ lines.push("");
266
+ lines.push(lastPrompt);
267
+ lines.push("");
268
+ }
269
+
270
+ writeFileSync(eventsPath, lines.join("\n"), "utf-8");
271
+ return { grouped, lastPrompt, fileNames };
272
+ }
273
+
274
+ // ── Build session guide — actionable narrative for LLM to continue from ──
275
+ export function buildSessionDirective(source, eventMeta, toolNamer) {
276
+ const { grouped, lastPrompt, fileNames, legBoundary } = eventMeta;
277
+ const isCompact = source === "compact";
278
+ const searchTool = toolNamer ? toolNamer("ctx_search") : "ctx_search";
279
+ const dataSearchHint = `${searchTool}(source: "session-events")`;
280
+
281
+ let block = `\n<session_knowledge source="${isCompact ? "compact" : "continue"}">`;
282
+ block += `\n<session_guide>`;
283
+
284
+ // 1. Last request — most critical for continuation
285
+ if (lastPrompt) {
286
+ // Truncate overly long prompts — keep first 300 chars as summary
287
+ const displayPrompt = lastPrompt.length > 300
288
+ ? lastPrompt.substring(0, 297) + "..."
289
+ : lastPrompt;
290
+ block += `\n## Last Request`;
291
+ block += `\n${displayPrompt}`;
292
+ block += `\n`;
293
+ }
294
+
295
+ // 2. Tasks — parsed into readable format, only pending/in-progress shown
296
+ // TaskCreate events have {subject} but no taskId.
297
+ // TaskUpdate events have {taskId, status} but no subject.
298
+ // Match by chronological order: creates[0] → lowest taskId from updates.
299
+ // Completed tasks are excluded — the model should not re-work them.
300
+ if (grouped.task?.length > 0) {
301
+ const creates = [];
302
+ const updates = {};
303
+
304
+ for (const ev of grouped.task) {
305
+ try {
306
+ const parsed = JSON.parse(ev.data);
307
+ if (parsed.subject) {
308
+ creates.push(parsed.subject);
309
+ } else if (parsed.taskId && parsed.status) {
310
+ updates[parsed.taskId] = parsed.status;
311
+ }
312
+ } catch { /* not JSON */ }
313
+ }
314
+
315
+ if (creates.length > 0) {
316
+ const DONE = new Set(["completed", "deleted", "failed"]);
317
+ const sortedIds = Object.keys(updates).sort((a, b) => Number(a) - Number(b));
318
+ const pending = [];
319
+ for (let i = 0; i < creates.length; i++) {
320
+ const matchedId = sortedIds[i];
321
+ const status = matchedId ? (updates[matchedId] || "pending") : "pending";
322
+ if (!DONE.has(status)) {
323
+ pending.push(creates[i]);
324
+ }
325
+ }
326
+ if (pending.length > 0) {
327
+ block += `\n## Pending Tasks`;
328
+ for (const task of pending) {
329
+ block += `\n- ${task}`;
330
+ }
331
+ block += `\n`;
332
+ }
333
+ }
334
+ }
335
+
336
+ // 3. Key decisions
337
+ if (grouped.decision?.length > 0) {
338
+ block += `\n## Key Decisions`;
339
+ for (const ev of grouped.decision) {
340
+ const text = ev.data.length > 150 ? ev.data.substring(0, 147) + "..." : ev.data;
341
+ block += `\n- ${text}`;
342
+ }
343
+ block += `\n`;
344
+ }
345
+
346
+ // 4. Files modified
347
+ if (fileNames.size > 0) {
348
+ block += `\n## Files Modified`;
349
+ block += `\n${[...fileNames].join(", ")}`;
350
+ block += `\n`;
351
+ }
352
+
353
+ // 5. Errors
354
+ if (grouped.error?.length > 0) {
355
+ block += `\n## Unresolved Errors`;
356
+ for (const ev of grouped.error) {
357
+ const text = ev.data.length > 150 ? ev.data.substring(0, 147) + "..." : ev.data;
358
+ block += `\n- ${text}`;
359
+ }
360
+ block += `\n`;
361
+ }
362
+
363
+ // 6. Git state
364
+ if (grouped.git?.length > 0) {
365
+ const uniqueOps = [...new Set(grouped.git.map(e => e.data))];
366
+ block += `\n## Git`;
367
+ block += `\n${uniqueOps.join(", ")}`;
368
+ block += `\n`;
369
+ }
370
+
371
+ // 7. Project rules (paths only)
372
+ if (grouped.rule?.length > 0) {
373
+ const rPaths = grouped.rule
374
+ .filter(e => e.type !== "rule_content")
375
+ .map(e => {
376
+ const parts = e.data.split(/[/\\]/);
377
+ return parts.slice(-2).join("/");
378
+ });
379
+ const uniquePaths = [...new Set(rPaths)];
380
+ if (uniquePaths.length > 0) {
381
+ block += `\n## Project Rules`;
382
+ block += `\n${uniquePaths.join(", ")}`;
383
+ block += `\n`;
384
+ }
385
+ }
386
+
387
+ // 8. MCP tools used
388
+ if (grouped.mcp?.length > 0) {
389
+ const toolCounts = {};
390
+ for (const ev of grouped.mcp) {
391
+ const tool = ev.data.split(":")[0].trim();
392
+ toolCounts[tool] = (toolCounts[tool] || 0) + 1;
393
+ }
394
+ block += `\n## MCP Tools Used`;
395
+ block += `\n${Object.entries(toolCounts).map(([t, c]) => `${t}(${c})`).join(", ")}`;
396
+ block += `\n`;
397
+ }
398
+
399
+ // 9. Subagent tasks — #780: prior-leg events are NOT current work. Render
400
+ // only current-leg subagents under "Subagent Tasks"; reframe prior-leg
401
+ // ones so stale [completed]/[launched] labels don't read as this leg's.
402
+ if (grouped.subagent?.length > 0) {
403
+ const fmt = (ev) => ev.data.length > 120 ? ev.data.substring(0, 117) + "..." : ev.data;
404
+ const currentSub = grouped.subagent.filter(ev => !isPriorLeg(ev, legBoundary));
405
+ const priorSub = grouped.subagent.filter(ev => isPriorLeg(ev, legBoundary));
406
+ if (currentSub.length > 0) {
407
+ block += `\n## Subagent Tasks`;
408
+ for (const ev of currentSub) block += `\n- ${fmt(ev)}`;
409
+ block += `\n`;
410
+ }
411
+ if (priorSub.length > 0) {
412
+ block += `\n## Subagent Tasks (earlier session — not current)`;
413
+ for (const ev of priorSub) block += `\n- ${fmt(ev)}`;
414
+ block += `\n`;
415
+ }
416
+ }
417
+
418
+ // 10. Skills invoked
419
+ if (grouped.skill?.length > 0) {
420
+ const uniqueSkills = [...new Set(grouped.skill.map(e => e.data))];
421
+ block += `\n## Skills Used`;
422
+ block += `\n${uniqueSkills.join(", ")}`;
423
+ block += `\n`;
424
+ }
425
+
426
+ // 11. Environment
427
+ if (grouped.env?.length > 0 || grouped.cwd?.length > 0) {
428
+ block += `\n## Environment`;
429
+ if (grouped.cwd?.length > 0) {
430
+ block += `\ncwd: ${grouped.cwd[grouped.cwd.length - 1].data}`;
431
+ }
432
+ for (const ev of (grouped.env || [])) {
433
+ block += `\n${ev.data}`;
434
+ }
435
+ block += `\n`;
436
+ }
437
+
438
+ // 12. Data references — #840: reference (don't inline) large tool-outputs.
439
+ if (grouped.data?.length > 0) {
440
+ block += `\n## Data References`;
441
+ renderDataReferences(grouped.data, (l) => { block += `\n${l}`; }, dataSearchHint);
442
+ block += `\n`;
443
+ }
444
+
445
+ // 13. Intent / Role (if set)
446
+ if (grouped.intent?.length > 0) {
447
+ block += `\n## Session Intent`;
448
+ block += `\n${grouped.intent[grouped.intent.length - 1].data}`;
449
+ block += `\n`;
450
+ }
451
+ if (grouped.role?.length > 0) {
452
+ block += `\n## User Role`;
453
+ block += `\n${grouped.role[grouped.role.length - 1].data}`;
454
+ block += `\n`;
455
+ }
456
+
457
+ // 14. Plan mode state — critical for preventing stale plan restoration
458
+ if (grouped.plan?.length > 0) {
459
+ const hasApproved = grouped.plan.some(e => e.type === "plan_approved");
460
+ const hasRejected = grouped.plan.some(e => e.type === "plan_rejected");
461
+ const hasFileWrite = grouped.plan.some(e => e.type === "plan_file_write");
462
+ const lastPlan = grouped.plan[grouped.plan.length - 1];
463
+ const isActive = lastPlan.type === "plan_enter" || lastPlan.type === "plan_file_write";
464
+
465
+ block += `\n## Plan Mode`;
466
+ if (hasApproved) {
467
+ block += `\n- Status: APPROVED AND EXECUTED`;
468
+ block += `\n- The plan was approved and executed. Do NOT re-enter plan mode or re-propose the same plan.`;
469
+ } else if (hasRejected) {
470
+ block += `\n- Status: REJECTED BY USER`;
471
+ block += `\n- The user rejected the previous plan. Ask what they want changed before re-planning.`;
472
+ } else if (isActive) {
473
+ block += `\n- Status: ACTIVE (in planning phase)`;
474
+ if (hasFileWrite) {
475
+ block += `\n- Plan file has been written. Awaiting user approval via ExitPlanMode.`;
476
+ }
477
+ } else {
478
+ block += `\n- Status: COMPLETED`;
479
+ block += `\n- The plan has been executed. Do NOT re-enter plan mode or re-propose the same plan.`;
480
+ }
481
+ block += `\n`;
482
+ }
483
+
484
+ block += `\n</session_guide>`;
485
+
486
+ // Search on demand — detailed data lives in FTS5
487
+ block += `\n<session_search>`;
488
+ block += `\nDetailed session data is indexed in context-mode FTS5 (source: "session-events").`;
489
+ block += `\nUse ${searchTool}(queries: [...], source: "session-events") when you need specifics.`;
490
+ block += `\nDo NOT call ctx_index() — data is already indexed.`;
491
+ block += `\n</session_search>`;
492
+
493
+ // Continue instruction
494
+ if (lastPrompt && isCompact) {
495
+ block += `\n<continue_from>Continue working on the last request. Do NOT ask the user to repeat themselves.</continue_from>`;
496
+ }
497
+
498
+ block += `\n</session_knowledge>`;
499
+ return block;
500
+ }
501
+
502
+ // ── Get events for a specific session (used by compact) ──
503
+ export function getSessionEvents(db, sessionId) {
504
+ return db.db.prepare(
505
+ `SELECT session_id, type, category, priority, data, source_hook, created_at
506
+ FROM session_events WHERE session_id = ? ORDER BY created_at ASC`
507
+ ).all(sessionId);
508
+ }
509
+
510
+ // ── Get events from the most recent session that has events (used by resume) ──
511
+ export function getLatestSessionEvents(db) {
512
+ const latest = db.db.prepare(
513
+ `SELECT m.session_id FROM session_meta m
514
+ JOIN session_events e ON m.session_id = e.session_id
515
+ GROUP BY m.session_id
516
+ ORDER BY m.started_at DESC LIMIT 1`
517
+ ).get();
518
+ if (!latest) return [];
519
+ return getSessionEvents(db, latest.session_id);
520
+ }
@@ -0,0 +1,3 @@
1
+ var O={"claude-opus-4-8":{input_per_mtok:5,output_per_mtok:25,cache_read_per_mtok:.5,cache_write_per_mtok:6.25,source:"https://platform.claude.com/docs/en/about-claude/pricing"},"claude-opus-4-7":{input_per_mtok:5,output_per_mtok:25,cache_read_per_mtok:.5,cache_write_per_mtok:6.25,source:"https://platform.claude.com/docs/en/about-claude/pricing"},"claude-opus-4-6":{input_per_mtok:5,output_per_mtok:25,cache_read_per_mtok:.5,cache_write_per_mtok:6.25,source:"https://platform.claude.com/docs/en/about-claude/pricing"},"claude-opus-4-5":{input_per_mtok:5,output_per_mtok:25,cache_read_per_mtok:.5,cache_write_per_mtok:6.25,source:"https://platform.claude.com/docs/en/about-claude/pricing"},"claude-sonnet-4-6":{input_per_mtok:3,output_per_mtok:15,cache_read_per_mtok:.3,cache_write_per_mtok:3.75,source:"https://platform.claude.com/docs/en/about-claude/pricing"},"claude-sonnet-4-5":{input_per_mtok:3,output_per_mtok:15,cache_read_per_mtok:.3,cache_write_per_mtok:3.75,source:"https://platform.claude.com/docs/en/about-claude/pricing"},"claude-haiku-4-5":{input_per_mtok:1,output_per_mtok:5,cache_read_per_mtok:.1,cache_write_per_mtok:1.25,source:"https://platform.claude.com/docs/en/about-claude/pricing"},"claude-3-7-sonnet":{input_per_mtok:3,output_per_mtok:15,cache_read_per_mtok:.3,cache_write_per_mtok:3.75,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"claude-3-5-haiku":{input_per_mtok:.8,output_per_mtok:4,cache_read_per_mtok:.08,cache_write_per_mtok:1,source:"https://platform.claude.com/docs/en/about-claude/pricing"},"claude-fable-5":{input_per_mtok:10,output_per_mtok:50,cache_read_per_mtok:1,cache_write_per_mtok:12.5,source:"https://platform.claude.com/docs/en/about-claude/pricing"},"gpt-5":{input_per_mtok:1.25,output_per_mtok:10,cache_read_per_mtok:.125,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"gpt-5-mini":{input_per_mtok:.25,output_per_mtok:2,cache_read_per_mtok:.025,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"gpt-5-nano":{input_per_mtok:.05,output_per_mtok:.4,cache_read_per_mtok:.005,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"gpt-5-codex":{input_per_mtok:1.25,output_per_mtok:10,cache_read_per_mtok:.125,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"gpt-4.1":{input_per_mtok:2,output_per_mtok:8,cache_read_per_mtok:.5,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"gpt-4.1-mini":{input_per_mtok:.4,output_per_mtok:1.6,cache_read_per_mtok:.1,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"gpt-4.1-nano":{input_per_mtok:.1,output_per_mtok:.4,cache_read_per_mtok:.025,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"gpt-4o":{input_per_mtok:2.5,output_per_mtok:10,cache_read_per_mtok:1.25,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"gpt-4o-mini":{input_per_mtok:.15,output_per_mtok:.6,cache_read_per_mtok:.075,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},o3:{input_per_mtok:2,output_per_mtok:8,cache_read_per_mtok:.5,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"o4-mini":{input_per_mtok:1.1,output_per_mtok:4.4,cache_read_per_mtok:.275,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"o3-mini":{input_per_mtok:1.1,output_per_mtok:4.4,cache_read_per_mtok:.55,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"codex-mini-latest":{input_per_mtok:1.5,output_per_mtok:6,cache_read_per_mtok:.375,cache_write_per_mtok:null,source:"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"},"gemini-2.5-pro":{input_per_mtok:1.25,output_per_mtok:10,cache_read_per_mtok:.125,cache_write_per_mtok:null,source:"https://ai.google.dev/gemini-api/docs/pricing"},"gemini-2.5-flash":{input_per_mtok:.3,output_per_mtok:2.5,cache_read_per_mtok:.03,cache_write_per_mtok:null,source:"https://ai.google.dev/gemini-api/docs/pricing"},"gemini-2.5-flash-lite":{input_per_mtok:.1,output_per_mtok:.4,cache_read_per_mtok:.01,cache_write_per_mtok:null,source:"https://ai.google.dev/gemini-api/docs/pricing"},"gemini-2.0-flash":{input_per_mtok:.1,output_per_mtok:.4,cache_read_per_mtok:.025,cache_write_per_mtok:null,source:"https://ai.google.dev/gemini-api/docs/pricing"},"gemini-2.0-flash-lite":{input_per_mtok:.075,output_per_mtok:.3,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://ai.google.dev/gemini-api/docs/pricing"},"gemini-3-pro-preview":{input_per_mtok:2,output_per_mtok:12,cache_read_per_mtok:.2,cache_write_per_mtok:null,source:"https://ai.google.dev/gemini-api/docs/pricing"},"gemini-3-flash-preview":{input_per_mtok:.5,output_per_mtok:3,cache_read_per_mtok:.05,cache_write_per_mtok:null,source:"https://ai.google.dev/gemini-api/docs/pricing"},"qwen3-coder":{input_per_mtok:1,output_per_mtok:5,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://www.alibabacloud.com/help/en/model-studio/models"},"qwen-max":{input_per_mtok:1.6,output_per_mtok:6.4,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://www.alibabacloud.com/help/en/model-studio/models"},"qwen-plus":{input_per_mtok:.4,output_per_mtok:1.2,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://www.alibabacloud.com/help/en/model-studio/models"},"qwen-turbo":{input_per_mtok:.05,output_per_mtok:.2,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://www.alibabacloud.com/help/en/model-studio/models"},"qwen3-max":{input_per_mtok:1.2,output_per_mtok:6,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://www.alibabacloud.com/help/en/model-studio/models"},"kimi-k2":{input_per_mtok:.6,output_per_mtok:2.5,cache_read_per_mtok:.15,cache_write_per_mtok:null,source:"https://platform.moonshot.ai/docs/pricing/chat"},"kimi-k2-turbo":{input_per_mtok:1.15,output_per_mtok:8,cache_read_per_mtok:.15,cache_write_per_mtok:null,source:"https://platform.moonshot.ai/docs/pricing/chat"},"moonshot-v1-8k":{input_per_mtok:.2,output_per_mtok:2,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://platform.moonshot.ai/docs/pricing"},"moonshot-v1-32k":{input_per_mtok:1,output_per_mtok:3,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://platform.moonshot.ai/docs/pricing"},"moonshot-v1-128k":{input_per_mtok:2,output_per_mtok:5,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://platform.moonshot.ai/docs/pricing"},"deepseek-v3":{input_per_mtok:.27,output_per_mtok:1.1,cache_read_per_mtok:.07,cache_write_per_mtok:0,source:"https://api-docs.deepseek.com/quick_start/pricing"},"deepseek-r1":{input_per_mtok:.55,output_per_mtok:2.19,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://api-docs.deepseek.com/quick_start/pricing"},"deepseek-chat":{input_per_mtok:.14,output_per_mtok:.28,cache_read_per_mtok:.0028,cache_write_per_mtok:null,source:"https://api-docs.deepseek.com/quick_start/pricing"},"deepseek-reasoner":{input_per_mtok:.14,output_per_mtok:.28,cache_read_per_mtok:.0028,cache_write_per_mtok:null,source:"https://api-docs.deepseek.com/quick_start/pricing"},"glm-4.6":{input_per_mtok:.6,output_per_mtok:2.2,cache_read_per_mtok:.11,cache_write_per_mtok:null,source:"https://docs.z.ai/guides/overview/pricing"},"glm-4-air":{input_per_mtok:.2,output_per_mtok:1.1,cache_read_per_mtok:.03,cache_write_per_mtok:null,source:"https://docs.z.ai/guides/overview/pricing"},"grok-4":{input_per_mtok:3,output_per_mtok:15,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://docs.x.ai/docs/pricing"},"grok-3":{input_per_mtok:3,output_per_mtok:15,cache_read_per_mtok:.75,cache_write_per_mtok:null,source:"https://docs.x.ai/docs/pricing"},"grok-code-fast-1":{input_per_mtok:.2,output_per_mtok:1.5,cache_read_per_mtok:.02,cache_write_per_mtok:null,source:"https://docs.x.ai/docs/pricing"},"grok-2":{input_per_mtok:2,output_per_mtok:10,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://docs.x.ai/docs/pricing"},"mistral-large-latest":{input_per_mtok:.5,output_per_mtok:1.5,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://mistral.ai/pricing"},"codestral-latest":{input_per_mtok:.3,output_per_mtok:.9,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://mistral.ai/pricing"},devstral:{input_per_mtok:.4,output_per_mtok:2,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://mistral.ai/pricing"},"mistral-medium":{input_per_mtok:.4,output_per_mtok:2,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://mistral.ai/pricing"},"llama-4-maverick":{input_per_mtok:.27,output_per_mtok:.85,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://www.together.ai/pricing"},"llama-4-scout":{input_per_mtok:.08,output_per_mtok:.3,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://www.together.ai/pricing"},"llama-3.3-70b":{input_per_mtok:.88,output_per_mtok:.88,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://www.together.ai/pricing"},"command-a":{input_per_mtok:2.5,output_per_mtok:10,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://cohere.com/pricing"},"command-r-plus":{input_per_mtok:2.5,output_per_mtok:10,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://cohere.com/pricing"},"amazon-nova-pro":{input_per_mtok:.8,output_per_mtok:3.2,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://aws.amazon.com/bedrock/pricing/"},"amazon-nova-lite":{input_per_mtok:.06,output_per_mtok:.24,cache_read_per_mtok:null,cache_write_per_mtok:null,source:"https://aws.amazon.com/bedrock/pricing/"}};function K(){let t=new Map,e=O;for(let o of Object.keys(e)){let n=e[o];n==null||typeof n!="object"||typeof n.input_per_mtok=="number"&&t.set(o,{input_per_mtok:n.input_per_mtok,output_per_mtok:typeof n.output_per_mtok=="number"?n.output_per_mtok:null,cache_read_per_mtok:typeof n.cache_read_per_mtok=="number"?n.cache_read_per_mtok:null,cache_write_per_mtok:typeof n.cache_write_per_mtok=="number"?n.cache_write_per_mtok:null})}return t}var T=K();function G(t){for(let e=0;e<t.length;e++)if(t.charCodeAt(e)===47)return e===0||e===t.length-1?null:t.slice(e+1);return null}function z(t){return t.trim().toLowerCase()}function I(t){if(typeof t!="string"||t.length===0)return null;let e=T.get(t);if(e)return e;let o=z(t),n=T.get(o);if(n)return n;let r=G(o);if(r){let s=T.get(r);if(s)return s}return null}function E(t,e,o){return t<=0?0:t*(typeof e=="number"?e:o)}function P(t,e){let o=typeof e.input_tokens=="number"?e.input_tokens:0,n=typeof e.output_tokens=="number"?e.output_tokens:0,r=typeof e.cache_read_tokens=="number"?e.cache_read_tokens:0,s=typeof e.cache_creation_tokens=="number"?e.cache_creation_tokens:0;if(o<=0&&n<=0&&r<=0&&s<=0)return null;let i=I(t);if(!i||typeof i.input_per_mtok!="number")return console.warn(`[pricing] no curated price for model id: ${t}`),null;let a=i.input_per_mtok;return(E(o,a,a)+E(n,i.output_per_mtok,a)+E(r,i.cache_read_per_mtok,a)+E(s,i.cache_write_per_mtok,a))/1e6}function x(t){return typeof t=="number"&&Number.isFinite(t)&&t>0?t:0}function L(t){if(!t||typeof t!="object")return null;let e=t;if(typeof e.type=="string"&&e.type!=="usage.record")return null;let o=e.usage;if(!o||typeof o!="object")return null;let n=o,r=x(n.inputOther),s=x(n.output),i=x(n.inputCacheRead),a=x(n.inputCacheCreation);return r<=0&&s<=0&&i<=0&&a<=0?null:{model_id:typeof e.model=="string"?e.model:"",input_tokens:r,output_tokens:s,cache_creation_tokens:a,cache_read_tokens:i,native_cost_usd:null}}function J(t,e){let o=V(e);if(typeof t!="string"||t.length===0)return{events:[],cursor:e??null};let n=[],r=t.split(`
2
+ `);for(let u of r){let c=u.trim();if(c.length===0)continue;let l;try{l=JSON.parse(c)}catch{continue}if(!l||typeof l!="object"||l.type!=="usage.record")continue;let m=L(l);n.push(m??{model_id:"",input_tokens:0,output_tokens:0,cache_creation_tokens:0,cache_read_tokens:0,native_cost_usd:null})}let s=n.length;if(s===0)return{events:[],cursor:e??null};let i;o===null||o<=0?i=n:o>=s?o===s?i=[]:i=n.slice(s-1):i=n.slice(o);let a=new Map;for(let u of i){let c=a.get(u.model_id)??{input:0,output:0,cacheCreate:0,cacheRead:0};c.input+=u.input_tokens,c.output+=u.output_tokens,c.cacheCreate+=u.cache_creation_tokens,c.cacheRead+=u.cache_read_tokens,a.set(u.model_id,c)}let p=[];for(let[u,c]of a){let l=w({model_id:u,input_tokens:c.input,output_tokens:c.output,cache_creation_tokens:c.cacheCreate,cache_read_tokens:c.cacheRead});l&&p.push(l)}return{events:p,cursor:String(s)}}function V(t){if(typeof t!="string"||t.length===0)return null;let e=Number.parseInt(t,10);return!Number.isFinite(e)||e<0?null:e}function A(t){if(typeof t!="number"||!Number.isFinite(t))return 0;let e=Math.floor(t);return e>0?e:0}function N(t){if(!t||typeof t!="object"||Array.isArray(t))return null;let e=t,o=e.usageMetadata;if(!o||typeof o!="object")return null;let n=o,r=A(n.promptTokenCount),s=A(n.candidatesTokenCount),i=A(n.thoughtsTokenCount),a=A(n.cachedContentTokenCount),p=s+i;return r<=0&&p<=0&&a<=0?null:{model_id:typeof e.model=="string"?e.model:"",input_tokens:r,output_tokens:p,cache_creation_tokens:0,cache_read_tokens:a,native_cost_usd:null}}function Q(t){return typeof t.id=="string"&&t.id.length>0?t.id:typeof t.messageId=="string"&&t.messageId.length>0?t.messageId:null}function X(t,e){let o=typeof e=="string"&&e.length>0?e:null;if(typeof t!="string"||t.length===0)return{events:[],cursor:o};let n=[],r=0;for(let u=0;u<=t.length;u++){if(u!==t.length&&t.charCodeAt(u)!==10)continue;let c=t.slice(r,u).trim();if(r=u+1,c.length===0)continue;let l;try{let m=JSON.parse(c);if(!m||typeof m!="object"||Array.isArray(m))continue;l=m}catch{continue}n.push({id:Q(l),counts:N(l)})}if(n.length===0)return{events:[],cursor:o};let s=o;for(let u=n.length-1;u>=0;u--)if(n[u].id!==null){s=n[u].id;break}let i;if(o===null)i=n;else{let u=-1;for(let c=0;c<n.length;c++)if(n[c].id===o){u=c;break}u>=0?i=n.slice(u+1):i=n.slice(n.length-1)}let a=new Map;for(let u of i){let c=u.counts;if(!c)continue;let l=a.get(c.model_id)??{input:0,output:0,cacheCreate:0,cacheRead:0};l.input+=c.input_tokens,l.output+=c.output_tokens,l.cacheCreate+=c.cache_creation_tokens,l.cacheRead+=c.cache_read_tokens,a.set(c.model_id,l)}let p=[];for(let[u,c]of a){let l=w({model_id:u,input_tokens:c.input,output_tokens:c.output,cache_creation_tokens:c.cacheCreate,cache_read_tokens:c.cacheRead});l&&p.push(l)}return{events:p,cursor:s}}function _(t){return t==null?"":String(t)}function B(t){return t==null?"":typeof t=="string"?t:JSON.stringify(t)}function v(t){let e=String(t.tool_response??""),o=String(t.tool_input?.command??"");if(e.startsWith("context-mode:")||o.startsWith('echo "context-mode:')||o.startsWith("echo 'context-mode:"))return!1;let n=t.tool_output?.isError===!0||t.tool_output?.is_error===!0;return t.tool_name==="Bash"&&/exit code [1-9]|error:|Error:|FAIL|failed/i.test(e)||n}function F(t){if(!t)return[];let e=[];for(let n of t.split(/\r?\n/)){if(n.startsWith("*** Add File: ")){e.push({path:n.slice(14).trim(),type:"file_write"});continue}if(n.startsWith("*** Update File: ")){e.push({path:n.slice(17).trim(),type:"file_edit"});continue}if(n.startsWith("*** Delete File: ")){e.push({path:n.slice(17).trim(),type:"file_edit"});continue}n.startsWith("*** Move to: ")&&e.push({path:n.slice(13).trim(),type:"file_edit"})}let o=new Set;return e.filter(n=>{if(!n.path)return!1;let r=`${n.type}:${n.path}`;return o.has(r)?!1:(o.add(r),!0)})}function M(t){return/(?:^|[/\\])\.claude[/\\]plans[/\\]/.test(t)}function Y(t){let{tool_name:e,tool_input:o,tool_response:n}=t,r=[];if(e==="Read"){let s=String(o.file_path??"");return(/(?:CLAUDE|AGENTS(?:\.override)?|GEMINI|QWEN|KIRO)\.md$/i.test(s)||/\/copilot-instructions\.md$/i.test(s)||/\/context-mode\.mdc$/i.test(s)||/\.claude[\\/]/i.test(s)||/[\\/]memor(?:y|ies)[\\/][^\\/]+\.md$/i.test(s))&&(r.push({type:"rule",category:"rule",data:_(s),priority:1}),n&&n.length>0&&r.push({type:"rule_content",category:"rule",data:_(n),priority:1})),r.push({type:"file_read",category:"file",data:_(s),priority:1}),r}if(e==="Edit"){let s=String(o.file_path??"");return r.push({type:"file_edit",category:"file",data:_(s),priority:1}),r}if(e==="NotebookEdit"){let s=String(o.notebook_path??"");return r.push({type:"file_edit",category:"file",data:_(s),priority:1}),r}if(e==="Write"){let s=String(o.file_path??"");return r.push({type:"file_write",category:"file",data:_(s),priority:1}),r}if(e==="apply_patch"){if(v(t))return[];let s=F(String(o.command??o.patch??""));for(let i of s)r.push({type:i.type,category:"file",data:_(i.path),priority:1});return r}if(e==="Glob"){let s=String(o.pattern??"");return r.push({type:"file_glob",category:"file",data:_(s),priority:3}),r}if(e==="Grep"){let s=String(o.pattern??""),i=String(o.path??"");return r.push({type:"file_search",category:"file",data:_(`${s} in ${i}`),priority:3}),r}return r}function Z(t){if(t.tool_name!=="Bash")return[];let o=String(t.tool_input.command??"").match(/\bcd\s+("([^"]+)"|'([^']+)'|(\S+))/);if(!o)return[];let n=o[2]??o[3]??o[4]??"";return[{type:"cwd",category:"cwd",data:_(n),priority:2}]}function tt(t){let{tool_response:e}=t,o=String(e??"");return v(t)?[{type:"error_tool",category:"error",data:_(o),priority:2}]:[]}var H=[{pattern:/\bgit\s+checkout\b/,operation:"branch"},{pattern:/\bgit\s+commit\b/,operation:"commit"},{pattern:/\bgit\s+merge\s+\S+/,operation:"merge"},{pattern:/\bgit\s+rebase\b/,operation:"rebase"},{pattern:/\bgit\s+stash\b/,operation:"stash"},{pattern:/\bgit\s+push\b/,operation:"push"},{pattern:/\bgit\s+pull\b/,operation:"pull"},{pattern:/\bgit\s+log\b/,operation:"log"},{pattern:/\bgit\s+diff\b/,operation:"diff"},{pattern:/\bgit\s+status\b/,operation:"status"},{pattern:/\bgit\s+branch\b/,operation:"branch"},{pattern:/\bgit\s+reset\b/,operation:"reset"},{pattern:/\bgit\s+add\b/,operation:"add"},{pattern:/\bgit\s+cherry-pick\b/,operation:"cherry-pick"},{pattern:/\bgit\s+tag\b/,operation:"tag"},{pattern:/\bgit\s+fetch\b/,operation:"fetch"},{pattern:/\bgit\s+clone\b/,operation:"clone"},{pattern:/\bgit\s+worktree\b/,operation:"worktree"}];function et(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??""),o=ot(e),n;if(o&&o.operation&&(n=H.find(s=>s.operation===o.operation)),n||(n=H.find(s=>s.pattern.test(e))),!n)return[];let r=[];if(o?.scopedDir&&r.push({type:"cwd",category:"cwd",data:_(o.scopedDir),priority:2}),n.operation==="commit"){let s=it(e);if(s)return r.push({type:"git_commit",category:"git",data:_(s),priority:2}),r}return r.push({type:"git",category:"git",data:_(n.operation),priority:2}),r}function nt(t){return typeof t!="string"||t.length===0?t:t==="~"?U():t.startsWith("~/")?U()+t.slice(1):t}function U(){try{return process.env.HOME||process.env.USERPROFILE||(process.env.HOMEDRIVE&&process.env.HOMEPATH?process.env.HOMEDRIVE+process.env.HOMEPATH:"")||"~"}catch{return"~"}}function ot(t){let e=W(t),o=0;for(;o<e.length&&rt(e[o]);)o++;for(;o<e.length&&e[o]!=="git"&&!e[o].endsWith("/git")&&st(e[o]);)o++;if(o>=e.length||e[o]!=="git"&&!e[o].endsWith("/git"))return null;o++;let n=null,r=null;for(;o<e.length;){let s=e[o];if(s==="-C"||s==="--directory"){n=e[o+1]??null,o+=2;continue}if(s.startsWith("--directory=")){n=s.slice(12),o++;continue}if(s.length>0&&s[0]==="-"){o++;continue}r=s;break}return n&&(n=nt(n)),{scopedDir:n,operation:r}}function rt(t){if(t.length===0)return!1;let e=!1;for(let o=0;o<t.length;o++){let n=t.charCodeAt(o);if(o===0){if(!(n>=65&&n<=90||n===95))return!1}else if(n===61){e=!0;break}else if(!(n>=65&&n<=90||n>=48&&n<=57||n===95))return!1}return e}function st(t){switch(t){case"sudo":case"doas":case"env":case"exec":case"time":return!0;default:return!1}}function W(t){let e=[],o=t.length,n=0;for(;n<o;){for(;n<o&&(t[n]===" "||t[n]===" ");)n++;if(n>=o)break;let r="";for(;n<o&&t[n]!==" "&&t[n]!==" ";){let s=t[n];if(s==='"'||s==="'"){let i=s;for(n++;n<o&&t[n]!==i;)t[n]==="\\"&&n+1<o?(r+=t[n+1],n+=2):(r+=t[n],n++);n<o&&n++}else s==="\\"&&n+1<o?(r+=t[n+1],n+=2):(r+=s,n++)}e.push(r)}return e}function it(t){let e=W(t),o="--message=";for(let n=0;n<e.length;n++){let r=e[n];if(r.length>o.length&&r.startsWith(o)){let s=r.slice(o.length);return s.length>0?s:null}if(r==="--message"){let s=e[n+1];return s&&s.length>0?s:null}if(r.length>=2&&r[0]==="-"&&r[1]!=="-"&&r[r.length-1]==="m"&&ct(r,1)){let s=e[n+1];return s&&s.length>0?s:null}}return null}function ct(t,e){if(e>=t.length)return!1;for(let o=e;o<t.length;o++){let n=t.charCodeAt(o);if(n<97||n>122)return!1}return!0}function ut(t){return new Set(["TodoWrite","TaskCreate","TaskUpdate"]).has(t.tool_name)?[{type:t.tool_name==="TaskUpdate"?"task_update":t.tool_name==="TaskCreate"?"task_create":"task",category:"task",data:_(JSON.stringify(t.tool_input)),priority:1}]:[]}function at(t){let e=2166136261;for(let o=0;o<t.length;o++)e^=t.charCodeAt(o),e=Math.imul(e,16777619);return(e>>>0).toString(16).padStart(8,"0")}function pt(t){let e=t.tool_input.plan;if(typeof e=="string"&&e.length>0)return e;let o=t.tool_response;if(typeof o=="string"&&o.length>0)try{let n=JSON.parse(o);if(n&&typeof n=="object"&&typeof n.plan=="string")return n.plan}catch{}return null}function lt(t){if(t.tool_name==="EnterPlanMode")return[{type:"plan_enter",category:"plan",data:"entered plan mode",priority:2}];if(t.tool_name==="ExitPlanMode"){let e=[],o=t.tool_input.allowedPrompts,n=Array.isArray(o)&&o.length>0?`exited plan mode (allowed: ${B(o.map(i=>typeof i=="object"&&i!==null&&"prompt"in i?String(i.prompt):String(i)).join(", "))})`:"exited plan mode",r=pt(t);typeof r=="string"&&r.length>0&&(n+=` plan_bytes:${r.length} plan_hash:${at(r)}`),e.push({type:"plan_exit",category:"plan",data:_(n),priority:2});let s=String(t.tool_response??"").toLowerCase();return s.includes("approved")||s.includes("approve")?e.push({type:"plan_approved",category:"plan",data:"plan approved by user",priority:1}):(s.includes("rejected")||s.includes("decline")||s.includes("denied"))&&e.push({type:"plan_rejected",category:"plan",data:_(`plan rejected: ${t.tool_response??""}`),priority:2}),e}if(t.tool_name==="Write"||t.tool_name==="Edit"){let e=String(t.tool_input.file_path??"");if(M(e))return[{type:"plan_file_write",category:"plan",data:_(`plan file: ${e.split(/[/\\]/).pop()??e}`),priority:2}]}return t.tool_name==="apply_patch"?v(t)?[]:F(String(t.tool_input.command??t.tool_input.patch??"")).filter(o=>M(o.path)).map(o=>({type:"plan_file_write",category:"plan",data:_(`plan file: ${o.path.split(/[/\\]/).pop()??o.path}`),priority:2})):[]}var _t=[/\bsource\s+\S*activate\b/,/\bexport\s+\w+=/,/\bnvm\s+use\b/,/\bpyenv\s+(shell|local|global)\b/,/\bconda\s+activate\b/,/\brbenv\s+(shell|local|global)\b/,/\bnpm\s+install\b/,/\bnpm\s+ci\b/,/\bpip\s+install\b/,/\bbun\s+install\b/,/\byarn\s+(add|install)\b/,/\bpnpm\s+(add|install)\b/,/\bcargo\s+(install|add)\b/,/\bgo\s+(install|get)\b/,/\brustup\b/,/\basdf\b/,/\bvolta\b/,/\bdeno\s+install\b/];function mt(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??"");if(!_t.some(r=>r.test(e)))return[];let n=e.replace(/\bexport\s+(\w+)=\S*/g,"export $1=***");return[{type:"env",category:"env",data:_(n),priority:2}]}function dt(t){if(t.tool_name!=="Skill")return[];let e=String(t.tool_input.skill??"");return[{type:"skill",category:"skill",data:_(e),priority:2}]}function ht(t){if(!t.tool_response?.includes("Error")&&!t.tool_output?.isError)return[];let e=String(t.tool_response||""),o=[/not supported/i,/cannot/i,/does not support/i,/FAIL/i,/refused/i,/permission denied/i,/incompatible/i];for(let n of o){let r=e.match(n);if(r){let s=e.toLowerCase().indexOf(r[0].toLowerCase()),i=e.slice(Math.max(0,s-50),Math.min(e.length,s+200)).trim();return[{type:"constraint_discovered",category:"constraint",data:_(i),priority:2}]}}return[]}function ft(t){if(t.tool_name!=="Agent")return[];let e=_(String(t.tool_input.prompt??t.tool_input.description??"")),o=t.tool_response?_(String(t.tool_response)):"",n=o.length>0;return[{type:n?"subagent_completed":"subagent_launched",category:"subagent",data:_(n?`[completed] ${e} \u2192 ${o}`:`[launched] ${e}`),priority:n?2:3}]}function gt(t){let{tool_name:e,tool_input:o,tool_response:n}=t;if(!e.startsWith("mcp__"))return[];let r=e.split("__"),s=r[r.length-1]||e,i=Object.values(o).find(u=>typeof u=="string"),a=i?`: ${_(String(i))}`:"",p=n&&n.length>0?`
3
+ response: ${_(n)}`:"";return[{type:"mcp",category:"mcp",data:_(`${s}${a}${p}`),priority:3}]}var kt=2048;function yt(t,e){if(Buffer.byteLength(t,"utf8")<=e)return{value:t,truncated:!1};let o=Buffer.from(t,"utf8"),n=e;for(;n>0&&(o[n]&192)===128;)n--;return{value:o.subarray(0,n).toString("utf8"),truncated:!0}}var bt=/(authorization|auth_token|access_token|refresh_token|bearer|token|secret|password|passwd|pwd|api[-_]?key|apikey|cookie|set-cookie|signature|private[-_]?key|client[-_]?secret|x[-_]?api[-_]?key)/i,wt="[REDACTED]";function j(t,e=new WeakSet){if(t==null||typeof t!="object")return t;if(e.has(t))return"[CIRCULAR]";e.add(t);let o;if(Array.isArray(t))o=t.map(n=>j(n,e));else{let n={};for(let[r,s]of Object.entries(t))bt.test(r)?n[r]=wt:n[r]=j(s,e);o=n}return e.delete(t),o}function St(t){let{tool_name:e,tool_input:o}=t;if(!e.startsWith("mcp__"))return[];let n=j(o??{}),r;try{r=JSON.stringify(n)}catch{r="{}"}let{value:s,truncated:i}=yt(r,kt),a=i?`{"tool_name":${JSON.stringify(e)},"params_raw":${JSON.stringify(s)},"truncated":true}`:`{"tool_name":${JSON.stringify(e)},"params":${s}}`,p={type:"mcp_tool_call",category:"mcp_tool_call",data:_(a),priority:4};if(vt(e)){let u=_(t.tool_response);u.length>0&&(p.bytes_retrieved=Buffer.byteLength(u,"utf8"))}return[p]}var Rt=["ctx_search","ctx_fetch_and_index"];function vt(t){for(let e of Rt)if(t.endsWith(e))return!0;return!1}function Et(t){if(t.tool_name!=="AskUserQuestion")return[];let e=t.tool_input.questions,o=Array.isArray(e)&&e.length>0?String(e[0].question??""):"",n=String(t.tool_response??""),r="";try{let p=JSON.parse(n)?.answers;if(p&&typeof p=="object"){let u=l=>typeof l=="string"?l:Array.isArray(l)?l.filter(m=>typeof m=="string").join(" | "):"",c=o?u(p[o]):"";c?r=c:r=Object.values(p).map(u).filter(m=>m.length>0).join(" | ")}}catch{}let s=_(r),i=o?`Q: ${_(o)} \u2192 A: ${s}`:`answer: ${s}`;return[{type:"decision_question",category:"decision",data:_(i),priority:2}]}function xt(t){if(t.tool_name!=="Agent")return[];if(!t.tool_response||t.tool_response.length===0)return[];let e=t.tool_response.length>500?t.tool_response.slice(0,500):t.tool_response;return[{type:"agent_finding",category:"agent-finding",data:_(e),priority:2}]}function At(t){let e=[B(t.tool_input),_(t.tool_response)].join(" ");if(e.length===0)return[];let o=new Set,n=e.match(/https?:\/\/[^\s)]+/g);if(n)for(let p of n)p=p.replace(/["'})\],;.]+$/,""),/localhost|127\.0\.0\.1/i.test(p)||o.add(p);let r=e.match(/(?<!\w)#(\d+)/g);if(r)for(let p of r)o.add(p);if(o.size===0)return[];let s,i=_(t.tool_response).match(/Fetched and indexed[^\(]*\(([\d.]+)\s*KB\)/i);if(i){let p=Number(i[1]);Number.isFinite(p)&&p>0&&(s=Math.round(p*1024))}let a={type:"external_ref",category:"external-ref",data:_(Array.from(o).join(", ")),priority:3};return s!==void 0&&(a.bytes_avoided=s),[a]}function Ct(t){if(t.tool_name==="EnterWorktree"){let e=String(t.tool_input.name??"unnamed");return[{type:"worktree",category:"env",data:_(`entered worktree: ${e}`),priority:2}]}if(t.tool_name==="ExitWorktree"){let e=!!t.tool_input.discard_changes;return[{type:"worktree_exit",category:"env",data:_(`exited worktree (discard_changes:${e})`),priority:2}]}return[]}function Tt(t){if(typeof t!="string"||t.length===0)return null;let e=t.indexOf("://");if(e<0)return null;let o=e+3;if(o>=t.length)return null;let n=t.length;for(let s=o;s<t.length;s++){let i=t.charCodeAt(s);if(i===47||i===63||i===35){n=s;break}}let r=t.slice(o,n);return r.length>0?r:null}function It(t){if(t.tool_name!=="WebFetch")return[];let e=t.tool_response;if(typeof e!="string"||e.length===0)return[];let o;try{o=JSON.parse(e)}catch{return[]}if(!o||typeof o!="object")return[];let n=o,r=[];if(typeof n.code=="number"&&r.push(`code:${n.code}`),typeof n.bytes=="number"&&r.push(`bytes:${n.bytes}`),typeof n.durationMs=="number"&&r.push(`durMs:${n.durationMs}`),typeof n.url=="string"){let s=Tt(n.url);s&&r.push(`host:${s}`)}return r.length===0?[]:[{type:"webfetch_metadata",category:"data",data:_(r.join(" ")),priority:3}]}function jt(t){if(t.tool_name!=="Bash")return[];let e=t.tool_response;if(typeof e!="string"||e.length===0)return[];let o;try{o=JSON.parse(e)}catch{return[]}if(!o||typeof o!="object")return[];let n=o;if(!(typeof n.interrupted=="boolean"||typeof n.stderr=="string"||typeof n.returnCodeInterpretation=="string"))return[];let s=[];return typeof n.interrupted=="boolean"&&s.push(`interrupted:${n.interrupted}`),typeof n.returnCodeInterpretation=="string"&&s.push(`rcInterp:${n.returnCodeInterpretation.slice(0,80)}`),typeof n.stderr=="string"&&s.push(`stderrBytes:${n.stderr.length}`),[{type:"bash_outcome",category:"data",data:_(s.join(" ")),priority:3}]}function $t(t){if(t.tool_name!=="Read")return[];let e=t.tool_response;if(typeof e!="string"||e.length===0)return[];let o;try{o=JSON.parse(e)}catch{return[]}if(!o||typeof o!="object")return[];let n=o,r=n.type;if(r!=="text"&&r!=="image")return[];let s=[`type:${r}`];if(r==="text")typeof n.numLines=="number"&&s.push(`lines:${n.numLines}`),typeof n.totalLines=="number"&&s.push(`totalLines:${n.totalLines}`),typeof n.startLine=="number"&&s.push(`start:${n.startLine}`);else{typeof n.originalSize=="number"&&s.push(`origSize:${n.originalSize}`);let i=n.dimensions;if(i&&typeof i=="object"){let a=i;typeof a.width=="number"&&typeof a.height=="number"&&s.push(`dims:${a.width}x${a.height}`)}}return[{type:"file_read_metadata",category:"data",data:_(s.join(" ")),priority:3}]}function Ot(t,e){let o=[t.tool_input?.model,t.model,e.model];for(let n of o)if(typeof n=="string"&&n.length>0)return n;return""}function Pt(t){for(let e=t.length-1;e>0;e--)if(t.charCodeAt(e)===45)return t.slice(0,e);return null}function Lt(t){let e=t;for(;e&&e.length>0;){if(I(e)!==null)return e;e=Pt(e)}return""}function Nt(t,e,o,n,r){let s=Lt(t);return P(s||t,{input_tokens:e,output_tokens:o,cache_creation_tokens:n,cache_read_tokens:r})}function Mt(t){let e=t.toFixed(6),o=e.length;for(;o>0&&e.charCodeAt(o-1)===48;)o--;return e=e.slice(0,o),e.length>0&&e.charCodeAt(e.length-1)===46&&(e+="0"),e}function Ht(t){if(t.tool_name!=="Task")return[];let e=t.tool_response;if(typeof e!="string"||e.length===0)return[];let o;try{o=JSON.parse(e)}catch{return[]}if(!o||typeof o!="object")return[];let n=o,r=n.usage&&typeof n.usage=="object"?n.usage:{};if(!(typeof n.totalTokens=="number"||typeof n.totalDurationMs=="number"||typeof r.input_tokens=="number"||typeof r.output_tokens=="number"||typeof r.service_tier=="string"))return[];let i=[];typeof n.totalTokens=="number"&&i.push(`totalTokens:${n.totalTokens}`),typeof n.totalDurationMs=="number"&&i.push(`totalDurMs:${n.totalDurationMs}`),typeof r.input_tokens=="number"&&i.push(`tokens_in:${r.input_tokens}`),typeof r.output_tokens=="number"&&i.push(`tokens_out:${r.output_tokens}`),typeof r.cache_creation_input_tokens=="number"&&i.push(`cache_create:${r.cache_creation_input_tokens}`),typeof r.cache_read_input_tokens=="number"&&i.push(`cache_read:${r.cache_read_input_tokens}`),typeof r.service_tier=="string"&&i.push(`tier:${r.service_tier.slice(0,32)}`);let a=Ot(t,n),p={type:"agent_usage",category:"cost",data:_(i.join(" ")),priority:2};return a.length>0&&(p.model_id=a),typeof r.input_tokens=="number"&&(p.input_tokens=r.input_tokens),typeof r.output_tokens=="number"&&(p.output_tokens=r.output_tokens),typeof r.cache_read_input_tokens=="number"&&(p.cache_read_tokens=r.cache_read_input_tokens),typeof r.cache_creation_input_tokens=="number"&&(p.cache_creation_tokens=r.cache_creation_input_tokens),p.usage_scope="task_cumulative",[p]}function Ee(t){if(!t||typeof t!="object")return null;let e=t,o=e.message,n=o&&typeof o=="object"?o:e;if(typeof n.role=="string"&&n.role!=="assistant")return null;let r=n.usage;if(!r||typeof r!="object")return null;let s=r,i=d=>typeof d=="number"&&Number.isFinite(d)&&d>0?d:0,a=i(s.input),p=i(s.output),u=i(s.cacheWrite),c=i(s.cacheRead);if(a<=0&&p<=0&&u<=0&&c<=0)return null;let l=null,m=s.cost;if(m&&typeof m=="object"){let d=m.total;typeof d=="number"&&Number.isFinite(d)&&(l=d)}return{model_id:typeof n.model=="string"?n.model:"",input_tokens:a,output_tokens:p,cache_creation_tokens:u,cache_read_tokens:c,native_cost_usd:l}}function xe(t){if(!t||typeof t!="object")return null;let e=t;if(typeof e.type=="string"&&e.type!=="model.usage")return null;let o=e.usage;if(!o||typeof o!="object")return null;let n=o,r=m=>typeof m=="number"&&Number.isFinite(m)&&m>0?m:0,s=r(n.input),i=r(n.output),a=r(n.cacheWrite),p=r(n.cacheRead);if(s<=0&&i<=0&&a<=0&&p<=0)return null;let u=e.costUsd,c=typeof u=="number"&&Number.isFinite(u)?u:null;return{model_id:typeof e.model=="string"?e.model:"",input_tokens:s,output_tokens:i,cache_creation_tokens:a,cache_read_tokens:p,native_cost_usd:c}}function Ae(t){if(!t||typeof t!="object")return null;let e=t,o=e.event&&typeof e.event=="object"?e.event:e,n=o.properties&&typeof o.properties=="object"?o.properties:o,r=n.info&&typeof n.info=="object"?n.info:e;if(typeof r.role=="string"&&r.role!=="assistant")return null;let s=r.tokens;if(!s||typeof s!="object")return null;let i=s,a=b=>typeof b=="number"&&Number.isFinite(b)&&b>0?b:0,p=i.cache,u=p&&typeof p=="object"?p:{},c=a(i.input),l=a(i.output),m=a(u.read),h=a(u.write);if(c<=0&&l<=0&&h<=0&&m<=0)return null;let d=r.cost,S=typeof d=="number"&&Number.isFinite(d)?d:null,y=typeof r.modelID=="string"?r.modelID:"",R=typeof r.providerID=="string"?r.providerID:"",f="";return y.length>0?f=R.length>0?`${R}/${y}`:y:typeof r.model=="string"&&(f=r.model),{model_id:f,input_tokens:c,output_tokens:l,cache_creation_tokens:h,cache_read_tokens:m,native_cost_usd:S}}function w(t){let{model_id:e,input_tokens:o,output_tokens:n,cache_creation_tokens:r,cache_read_tokens:s,native_cost_usd:i}=t;if(o<=0&&n<=0&&r<=0&&s<=0)return null;let a=[`tokens_in:${o}`,`tokens_out:${n}`];r>0&&a.push(`cache_create:${r}`),s>0&&a.push(`cache_read:${s}`);let p=typeof i=="number"&&Number.isFinite(i)?i:Nt(e,o,n,r,s);p!==null&&a.push(`cost_usd:${Mt(p)}`);let u={type:"agent_usage",category:"cost",data:_(a.join(" ")),priority:2};return e.length>0&&(u.model_id=e),u.input_tokens=o,u.output_tokens=n,s>0&&(u.cache_read_tokens=s),r>0&&(u.cache_creation_tokens=r),p!==null&&(u.cost_usd=p),u}function Ce(t){if(!t||typeof t!="object")return null;let e=t,o=e.llm_response;if(!o||typeof o!="object")return null;let n=o,r=n.usageMetadata;if(!r||typeof r!="object")return null;let s=r,i=y=>typeof y=="number"&&Number.isFinite(y)?y:0,a=i(s.promptTokenCount),p=i(s.candidatesTokenCount),u=i(s.thoughtsTokenCount),c=i(s.cachedContentTokenCount),l=p+u,m=e.llm_request,h=m&&typeof m=="object"&&typeof m.model=="string"?m.model:"",d=typeof n.modelVersion=="string"?n.modelVersion:"",S=d.length>0?d:h;return w({model_id:S,input_tokens:a,output_tokens:l,cache_creation_tokens:0,cache_read_tokens:c})}function Te(t){if(typeof t!="string"||t.length===0)return[];let e=new Map,o=0;for(let r=0;r<=t.length;r++){if(r!==t.length&&t.charCodeAt(r)!==10)continue;let s=t.slice(o,r).trim();if(o=r+1,s.length===0)continue;let i;try{let h=JSON.parse(s);if(!h||typeof h!="object")continue;i=h}catch{continue}if(i.type!=="assistant"||i.isSidechain===!0)continue;let a=i.message;if(!a||typeof a!="object")continue;let p=a,u=typeof p.model=="string"?p.model:"";if(u.length===0)continue;let c=p.usage;if(!c||typeof c!="object")continue;let l=c,m=e.get(u)??{input:0,output:0,cacheCreate:0,cacheRead:0};typeof l.input_tokens=="number"&&(m.input+=l.input_tokens),typeof l.output_tokens=="number"&&(m.output+=l.output_tokens),typeof l.cache_creation_input_tokens=="number"&&(m.cacheCreate+=l.cache_creation_input_tokens),typeof l.cache_read_input_tokens=="number"&&(m.cacheRead+=l.cache_read_input_tokens),e.set(u,m)}let n=[];for(let[r,s]of e){let i=w({model_id:r,input_tokens:s.input,output_tokens:s.output,cache_creation_tokens:s.cacheCreate,cache_read_tokens:s.cacheRead});i&&n.push(i)}return n}function Ie(t,e){let o=typeof e=="string"&&e.length>0?e:null;if(typeof t!="string"||t.length===0)return{events:[],cursor:o};let n=[],r=0;for(let c=0;c<=t.length;c++){if(c!==t.length&&t.charCodeAt(c)!==10)continue;let l=t.slice(r,c).trim();if(r=c+1,l.length===0)continue;let m;try{let b=JSON.parse(l);if(!b||typeof b!="object")continue;m=b}catch{continue}if(m.type!=="assistant"||m.isSidechain===!0)continue;let h=m.message;if(!h||typeof h!="object")continue;let d=h,S=typeof d.model=="string"?d.model:"";if(S.length===0)continue;let y=typeof m.uuid=="string"&&m.uuid.length>0?m.uuid:null,R=d.usage,f=R&&typeof R=="object"?R:{};n.push({uuid:y,model:S,input:typeof f.input_tokens=="number"?f.input_tokens:0,output:typeof f.output_tokens=="number"?f.output_tokens:0,cacheCreate:typeof f.cache_creation_input_tokens=="number"?f.cache_creation_input_tokens:0,cacheRead:typeof f.cache_read_input_tokens=="number"?f.cache_read_input_tokens:0})}if(n.length===0)return{events:[],cursor:o};let s=n[n.length-1].uuid,i=s!==null?s:o,a;if(o===null)a=n;else{let c=-1;for(let l=0;l<n.length;l++)if(n[l].uuid===o){c=l;break}c>=0?a=n.slice(c+1):a=n.slice(n.length-1)}let p=new Map;for(let c of a){let l=p.get(c.model)??{input:0,output:0,cacheCreate:0,cacheRead:0};l.input+=c.input,l.output+=c.output,l.cacheCreate+=c.cacheCreate,l.cacheRead+=c.cacheRead,p.set(c.model,l)}let u=[];for(let[c,l]of p){let m=w({model_id:c,input_tokens:l.input,output_tokens:l.output,cache_creation_tokens:l.cacheCreate,cache_read_tokens:l.cacheRead});m&&u.push(m)}return{events:u,cursor:i}}var D=/[,;,;、،]/u,Ut=15,Bt=500;function Ft(t){if(C.test(t)||!$.test(t)||!D.test(t))return!1;let e=[...t].length;return e>=Ut&&e<=Bt}function Wt(t){let e=t.trim();return Ft(e)?[{type:"decision",category:"decision",data:_(t),priority:2}]:[]}var Dt=8,qt=120,Kt=new RegExp("\\p{L}+\\s+\\p{L}+","u"),Gt=new RegExp("\\p{L}{6,}","u"),zt=new Set(["ok","okay","sure","yeah","yep","yup","alright","fine","well","so","hmm","right","please"]),Jt=["you are","you're","your role","you will be","you act","you will act","act as","act like","behave as","behave like","imagine you","pretend you","assume the role","take the role","play the role","respond as","tu es","tu est","vous etes","vous \xEAtes","sen ","siz ","eres ","t\xFA eres","usted es","\u0442\u044B ","\u0432\u044B ","\u3042\u306A\u305F\u306F","\u541B\u306F","\u304A\u524D\u306F","\u3042\u306A\u305F\u304C","\u4F60\u662F","\u60A8\u662F","\u0924\u0941\u092E ","\u0906\u092A ","\u0924\u0942 ","\u0623\u0646\u062A ","\u0627\u0646\u062A ","\u0623\u0646\u062A\u064E "],Vt=["always ","never ","respond ","reply ","answer ","speak ","write ","prefer ","format ","output ","communicate ","use only "];function Qt(t){let e=t.toLowerCase().trim();if(!e)return!1;let o=e.split(" ").filter(r=>r.length>0);for(;o.length>0&&zt.has(o[0]);)o.shift();let n=o.join(" ");if(!n)return!1;for(let r of Jt)if(n.startsWith(r))return!0;for(let r of Vt)if(n.startsWith(r))return!0;return!1}function Xt(t){let e=t.split(/[.!\n。!]/u)[0].trim();if(C.test(e)||D.test(e)||!$.test(e))return!1;let o=[...e].length;return o<Dt||o>qt||!Qt(e)?!1:Kt.test(e)||Gt.test(e)}function Yt(t){let e=t.trim();return Xt(e)?[{type:"role",category:"role",data:_(t),priority:3}]:[]}var C=/[??؟¿]/u,$=new RegExp("\\p{L}","u"),Zt=60;function te(t){if(C.test(t)||!$.test(t))return!1;let e=[...t].length;return e>0&&e<Zt}function ee(t){let e=t.trim();if(!e)return[];let o;return C.test(e)?o="investigate":te(e)&&(o="implement"),o?[{type:"intent",category:"intent",data:_(o),priority:4}]:[]}var ne=/^(?:\/goal\s+|(?:goal|objective)\s*:\s*)(.+)$/is;function oe(t){let e=t.trim();if(!e)return[];let o=e.match(ne);if(!o)return[];let n=o[1].trim();return n?[{type:"goal",category:"goal",data:_(n),priority:4}]:[]}var re=/(?:\bError\s*:|\bException\s*:|\bTraceback\b|\bat\s+\S+\s*\([^)]*:\d+:\d+\))/u,se=/[✓✔✅☑🎉]/u,ie=/^\s*(?:fixed|resolved)\s*:/iu;function ce(t){let e=[];return se.test(t)||ie.test(t)?(e.push({type:"blocker_resolved",category:"blocked-on",data:_(t),priority:2}),e):(re.test(t)&&e.push({type:"blocker",category:"blocked-on",data:_(t),priority:2}),e)}function ue(t){return t.length<=1024?[]:[{type:"data",category:"data",data:_(t),priority:4}]}var g=null;function ae(t){let{tool_name:e,tool_response:o}=t,n=String(o??"");if(v(t))return g={tool:e,error:n.slice(0,200),callsSince:0},[];if(!g)return[];if(g.callsSince++,g.callsSince>10)return g=null,[];if(!!v(t))return[];let s=e===g.tool,i=g.tool==="Read"&&(e==="Edit"||e==="Write"||e==="apply_patch");if(s||i){let a={type:"error_resolved",category:"error-resolution",data:_(`Error in ${g.tool}: ${g.error} \u2192 Fixed`),priority:2};return g=null,[a]}return[]}function je(){g=null}var k=[];function pe(t){return`${t.length}:${t.slice(0,20)}`}function le(t){let{tool_name:e,tool_input:o}=t,n=pe(JSON.stringify(o).slice(0,200));if(k.push({tool:e,inputHash:n}),k.length>50&&k.splice(0,k.length-50),k.length<3)return[];let r=0;for(let s=k.length-1;s>=0&&(k[s].tool===e&&k[s].inputHash===n);s--)r++;return r>=3?(k.splice(k.length-r),[{type:"retry_detected",category:"iteration-loop",data:_(`${e} called ${r} times with similar input`),priority:2}]):[]}function $e(){k.length=0}var _e={run_shell_command:"Bash",read_file:"Read",read_many_files:"Read",grep_search:"Grep",search_file_content:"Grep",web_fetch:"WebFetch",write_file:"Write",edit:"Edit",glob:"Glob",todo_write:"TodoWrite",ask_user_question:"AskUserQuestion",list_directory:"LS",save_memory:"Memory",skill:"Skill",exit_plan_mode:"ExitPlanMode",agent:"Agent",bash:"Bash",view:"Read",grep:"Grep",fetch:"WebFetch",shell:"Bash",shell_command:"Bash",exec_command:"Bash","container.exec":"Bash",local_shell:"Bash",grep_files:"Grep",run_command:"Bash",view_file:"Read",read_url_content:"WebFetch",list_dir:"LS",search_web:"WebSearch"};function me(t){let e=_e[t.tool_name];return!e||e===t.tool_name?t:{...t,tool_name:e}}function Oe(t){try{let e=me(t),o=[];return o.push(...Y(e)),o.push(...Z(e)),o.push(...tt(e)),o.push(...et(e)),o.push(...mt(e)),o.push(...ut(e)),o.push(...lt(e)),o.push(...dt(e)),o.push(...ft(e)),o.push(...gt(e)),o.push(...St(e)),o.push(...Et(e)),o.push(...ht(e)),o.push(...Ct(e)),o.push(...It(e)),o.push(...jt(e)),o.push(...$t(e)),o.push(...Ht(e)),o.push(...xt(e)),o.push(...At(e)),o.push(...ae(e)),o.push(...le(e)),o}catch{return[]}}function Pe(t){try{let e=[];return e.push(...fe(t)),e.push(...Wt(t)),e.push(...Yt(t)),e.push(...ee(t)),e.push(...oe(t)),e.push(...ce(t)),e.push(...ue(t)),e}catch{return[]}}function Le(t){if(!t||typeof t!="object")return[];let e=t,o=[],n=e.mcp_servers,r=null;return n&&typeof n=="object"&&!Array.isArray(n)&&(r=Object.keys(n),o.push(`mcp_count:${r.length}`),r.length>0&&o.push(`mcp_servers:${r.slice(0,8).join(",")}`)),typeof e.model=="string"&&o.push(`model:${e.model.slice(0,64)}`),typeof e.permission_mode=="string"&&o.push(`permission_mode:${e.permission_mode.slice(0,32)}`),o.length===0?[]:[{type:"session_settings_snapshot",category:"env",data:_(o.join(" ")),priority:2}]}var de=["Latin","Cyrillic","Arabic","Han","Hangul","Hiragana","Katakana","Devanagari","Hebrew","Thai","Greek"],he={prompt_length:0,prompt_word_count:0,prompt_uppercase_ratio:0,prompt_file_ref_count:0,prompt_path_ref_count:0,prompt_script_primary:null,prompt_script_count:0,prompt_question_glyph_count:0,prompt_code_block_count:0,prompt_url_count:0,prompt_word_tokens:[]};function Ne(t){if(typeof t!="string"||t.length===0)return{...he,prompt_word_tokens:[]};let e=t.match(new RegExp("\\p{L}+","gu"))??[],o=(t.match(new RegExp("\\p{Lu}","gu"))??[]).length,n=e.join("").length,r=(t.match(/```/g)??[]).length,s={};for(let u of de){let c=new RegExp(`\\p{Script=${u}}`,"gu"),l=(t.match(c)??[]).length;l>0&&(s[u]=l)}let i=Object.entries(s).sort((u,c)=>c[1]-u[1])[0]?.[0]??null,a=new Set,p=[];for(let u of e){if(u.length<3)continue;let c=u.toLowerCase();a.has(c)||(a.add(c),p.push(c))}return{prompt_length:t.length,prompt_word_count:e.length,prompt_uppercase_ratio:n===0?0:o/n,prompt_file_ref_count:(t.match(/(\w+\/)+\w+\.\w+/g)??[]).length,prompt_path_ref_count:(t.match(/\.{0,2}\/[\w\/.-]+/g)??[]).length,prompt_script_primary:i,prompt_script_count:Object.keys(s).length,prompt_question_glyph_count:(t.match(/[??؟]/gu)??[]).length,prompt_code_block_count:Math.floor(r/2),prompt_url_count:(t.match(/https?:\/\/[^\s]+/gu)??[]).length,prompt_word_tokens:p}}function fe(t){if(typeof t!="string"||t.length===0)return[];let e=0;for(;e<t.length;){let r=t.charCodeAt(e);if(r!==32&&r!==9)break;e++}if(e+5>t.length)return[];if(t.slice(e,e+5)!=="/plan")return[];if(e+5<t.length){let r=t.charCodeAt(e+5);if(!(r===32||r===9||r===10||r===13))return[]}let o=t.slice(e+5).trim(),n=o.length>0?`plan via /plan slash: ${o.slice(0,120)}`:"plan via /plan slash";return[{type:"plan_enter",category:"plan",data:_(n),priority:2}]}export{w as buildAgentUsageEvent,Oe as extractEvents,J as extractKimiUsageSince,X as extractQwenUsageSince,Le as extractSessionSettings,Te as extractTranscriptUsage,Ie as extractTranscriptUsageSince,Pe as extractUserEvents,Ne as extractUserPromptFeatures,Ce as parseGeminiUsage,L as parseKimiUsage,xe as parseOpenclawUsage,Ae as parseOpencodeUsage,Ee as parsePiUsage,N as parseQwenUsage,je as resetErrorResolutionState,$e as resetIterationLoopState};