@cjhyy/code-shell-core 0.5.0-rc.1 → 0.6.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. package/README.md +13 -10
  2. package/dist/agent/agent-definition-registry.d.ts +21 -3
  3. package/dist/agent/agent-definition-registry.js +49 -18
  4. package/dist/agent/agent-definition.d.ts +32 -0
  5. package/dist/agent/agent-definition.js +49 -4
  6. package/dist/arena/arena.js +11 -12
  7. package/dist/arena/context/context-tools.js +47 -6
  8. package/dist/arena/context/within-root.d.ts +7 -0
  9. package/dist/arena/context/within-root.js +15 -0
  10. package/dist/arena/iterate/phases/argue.js +8 -2
  11. package/dist/arena/iterate/phases/revise.js +1 -1
  12. package/dist/arena/iterate/phases/tournament.js +3 -3
  13. package/dist/arena/ledger.js +9 -1
  14. package/dist/arena/phases/adjudication.js +1 -4
  15. package/dist/arena/phases/build-consensus.js +1 -4
  16. package/dist/arena/phases/cross-review.js +2 -8
  17. package/dist/arena/phases/debate-rounds.js +1 -4
  18. package/dist/arena/phases/participant-research.js +1 -4
  19. package/dist/arena/phases/planning-detail-expansion.js +8 -10
  20. package/dist/arena/planner.js +0 -1
  21. package/dist/arena/providers/docs.d.ts +1 -0
  22. package/dist/arena/providers/docs.js +5 -2
  23. package/dist/arena/providers/repo.d.ts +1 -0
  24. package/dist/arena/providers/repo.js +5 -2
  25. package/dist/arena/strategies/utils.d.ts +1 -4
  26. package/dist/arena/strategies/utils.js +7 -51
  27. package/dist/arena/transitions.d.ts +7 -2
  28. package/dist/arena/transitions.js +9 -4
  29. package/dist/arena/types.d.ts +8 -2
  30. package/dist/automation/cron-expr.d.ts +41 -0
  31. package/dist/automation/cron-expr.js +169 -0
  32. package/dist/automation/index.d.ts +41 -0
  33. package/dist/automation/index.js +39 -0
  34. package/dist/automation/runner.d.ts +84 -0
  35. package/dist/automation/runner.js +92 -0
  36. package/dist/automation/scheduler.d.ts +194 -0
  37. package/dist/automation/scheduler.js +623 -0
  38. package/dist/automation/store.d.ts +39 -0
  39. package/dist/automation/store.js +122 -0
  40. package/dist/automation/write-policy.d.ts +34 -0
  41. package/dist/automation/write-policy.js +113 -0
  42. package/dist/automation/write-run.d.ts +51 -0
  43. package/dist/automation/write-run.js +38 -0
  44. package/dist/capability-control/disabled-lists.d.ts +25 -0
  45. package/dist/capability-control/disabled-lists.js +57 -0
  46. package/dist/capability-control/index.d.ts +5 -0
  47. package/dist/capability-control/index.js +3 -0
  48. package/dist/capability-control/overlay.d.ts +64 -0
  49. package/dist/capability-control/overlay.js +116 -0
  50. package/dist/capability-control/project.d.ts +65 -0
  51. package/dist/capability-control/project.js +147 -0
  52. package/dist/capability-control/service.d.ts +70 -0
  53. package/dist/capability-control/service.js +147 -0
  54. package/dist/capability-control/types.d.ts +62 -0
  55. package/dist/capability-control/types.js +17 -0
  56. package/dist/cc-orchestrator/agent-adapter.d.ts +50 -0
  57. package/dist/cc-orchestrator/agent-adapter.js +133 -0
  58. package/dist/cc-orchestrator/cc-capability.d.ts +19 -0
  59. package/dist/cc-orchestrator/cc-capability.js +53 -0
  60. package/dist/cc-orchestrator/codex-session-discovery.d.ts +24 -0
  61. package/dist/cc-orchestrator/codex-session-discovery.js +191 -0
  62. package/dist/cc-orchestrator/codex-session-history.d.ts +25 -0
  63. package/dist/cc-orchestrator/codex-session-history.js +187 -0
  64. package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
  65. package/dist/cc-orchestrator/external-agent-changes.js +214 -0
  66. package/dist/cc-orchestrator/external-agent-driver.d.ts +18 -0
  67. package/dist/cc-orchestrator/external-agent-driver.js +69 -0
  68. package/dist/cc-orchestrator/index.d.ts +8 -0
  69. package/dist/cc-orchestrator/index.js +8 -0
  70. package/dist/cc-orchestrator/relevance-judge.d.ts +15 -0
  71. package/dist/cc-orchestrator/relevance-judge.js +29 -0
  72. package/dist/cc-orchestrator/session-discovery.d.ts +46 -0
  73. package/dist/cc-orchestrator/session-discovery.js +125 -0
  74. package/dist/cc-orchestrator/session-history.d.ts +19 -0
  75. package/dist/cc-orchestrator/session-history.js +67 -0
  76. package/dist/cli/agent-server-stdio.d.ts +26 -1
  77. package/dist/cli/agent-server-stdio.js +221 -28
  78. package/dist/cli/agent-server-tcp.d.ts +20 -0
  79. package/dist/cli/agent-server-tcp.js +134 -0
  80. package/dist/cli/graceful-shutdown.d.ts +27 -0
  81. package/dist/cli/graceful-shutdown.js +30 -0
  82. package/dist/context/compaction.d.ts +56 -0
  83. package/dist/context/compaction.js +209 -15
  84. package/dist/context/manager.d.ts +0 -20
  85. package/dist/context/manager.js +25 -41
  86. package/dist/cost-tracker.js +5 -61
  87. package/dist/credentials/cipher.d.ts +49 -0
  88. package/dist/credentials/cipher.js +45 -0
  89. package/dist/credentials/cookie-jar.d.ts +24 -0
  90. package/dist/credentials/cookie-jar.js +40 -0
  91. package/dist/credentials/index.d.ts +7 -0
  92. package/dist/credentials/index.js +5 -0
  93. package/dist/credentials/inject-credential-tool.d.ts +20 -0
  94. package/dist/credentials/inject-credential-tool.js +130 -0
  95. package/dist/credentials/store.d.ts +72 -0
  96. package/dist/credentials/store.js +184 -0
  97. package/dist/credentials/types.d.ts +56 -0
  98. package/dist/credentials/use-credential-tool.d.ts +29 -0
  99. package/dist/credentials/use-credential-tool.js +205 -0
  100. package/dist/credentials/use-gate.d.ts +56 -0
  101. package/dist/credentials/use-gate.js +52 -0
  102. package/dist/cron/cron-runtime.d.ts +2 -0
  103. package/dist/cron/cron-runtime.js +2 -0
  104. package/dist/cron/cron-store.d.ts +2 -0
  105. package/dist/cron/cron-store.js +2 -0
  106. package/dist/cron/scheduler.d.ts +5 -32
  107. package/dist/cron/scheduler.js +5 -113
  108. package/dist/data/model-metadata.d.ts +77 -0
  109. package/dist/data/model-metadata.js +56 -0
  110. package/dist/data/model-metadata.json +216 -0
  111. package/dist/data/openrouter-models.d.ts +18 -7
  112. package/dist/data/openrouter-models.js +35 -8
  113. package/dist/data/openrouter-sync.js +1 -1
  114. package/dist/engine/aux-key.d.ts +10 -0
  115. package/dist/engine/aux-key.js +11 -0
  116. package/dist/engine/dynamic-tool-defs.d.ts +19 -0
  117. package/dist/engine/dynamic-tool-defs.js +36 -0
  118. package/dist/engine/engine.d.ts +431 -108
  119. package/dist/engine/engine.js +1630 -279
  120. package/dist/engine/friendly-error.d.ts +18 -0
  121. package/dist/engine/friendly-error.js +63 -0
  122. package/dist/engine/goal.d.ts +187 -0
  123. package/dist/engine/goal.js +196 -0
  124. package/dist/engine/image-compression.d.ts +81 -0
  125. package/dist/engine/image-compression.js +186 -0
  126. package/dist/engine/image-policy.d.ts +165 -0
  127. package/dist/engine/image-policy.js +189 -0
  128. package/dist/engine/model-connections-pool.d.ts +17 -0
  129. package/dist/engine/model-connections-pool.js +66 -0
  130. package/dist/engine/model-facade.d.ts +10 -0
  131. package/dist/engine/model-facade.js +25 -0
  132. package/dist/engine/patch-orphaned-tools.js +3 -0
  133. package/dist/engine/reactive-threshold.d.ts +13 -0
  134. package/dist/engine/reactive-threshold.js +17 -0
  135. package/dist/engine/resolve-llm-config.d.ts +16 -0
  136. package/dist/engine/resolve-llm-config.js +44 -0
  137. package/dist/engine/runtime.js +9 -1
  138. package/dist/engine/sandbox-cache-key.d.ts +10 -0
  139. package/dist/engine/sandbox-cache-key.js +9 -0
  140. package/dist/engine/sandbox-config.d.ts +31 -0
  141. package/dist/engine/sandbox-config.js +38 -0
  142. package/dist/engine/session-title.d.ts +13 -0
  143. package/dist/engine/session-title.js +34 -0
  144. package/dist/engine/session-usage.d.ts +19 -0
  145. package/dist/engine/session-usage.js +25 -0
  146. package/dist/engine/steer-queue.d.ts +32 -0
  147. package/dist/engine/steer-queue.js +26 -0
  148. package/dist/engine/streaming-tool-queue.d.ts +12 -0
  149. package/dist/engine/streaming-tool-queue.js +50 -10
  150. package/dist/engine/turn-loop.d.ts +94 -9
  151. package/dist/engine/turn-loop.js +775 -342
  152. package/dist/engine/types.d.ts +175 -0
  153. package/dist/engine/types.js +13 -0
  154. package/dist/external-agents/config.d.ts +2 -0
  155. package/dist/external-agents/config.js +15 -0
  156. package/dist/external-agents/types.d.ts +31 -0
  157. package/dist/external-agents/types.js +1 -0
  158. package/dist/git/parse-log.d.ts +13 -0
  159. package/dist/git/parse-log.js +21 -0
  160. package/dist/git/utils.d.ts +8 -6
  161. package/dist/git/utils.js +62 -26
  162. package/dist/git/worktree.d.ts +48 -0
  163. package/dist/git/worktree.js +111 -20
  164. package/dist/hooks/events.d.ts +23 -1
  165. package/dist/hooks/goal-stop-hook.d.ts +58 -0
  166. package/dist/hooks/goal-stop-hook.js +279 -0
  167. package/dist/hooks/hook-output.d.ts +33 -0
  168. package/dist/hooks/hook-output.js +79 -0
  169. package/dist/hooks/registry.d.ts +15 -0
  170. package/dist/hooks/registry.js +57 -1
  171. package/dist/hooks/shell-runner.d.ts +2 -0
  172. package/dist/hooks/shell-runner.js +48 -18
  173. package/dist/index.d.ts +79 -11
  174. package/dist/index.js +89 -6
  175. package/dist/llm/capabilities/param-specs.d.ts +14 -0
  176. package/dist/llm/capabilities/param-specs.js +62 -0
  177. package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
  178. package/dist/llm/capabilities/reasoning-control.js +38 -0
  179. package/dist/llm/capabilities/rules.js +37 -3
  180. package/dist/llm/capabilities/types.d.ts +32 -2
  181. package/dist/llm/clamp-max-tokens.d.ts +11 -0
  182. package/dist/llm/clamp-max-tokens.js +17 -0
  183. package/dist/llm/client-base.d.ts +69 -5
  184. package/dist/llm/client-base.js +185 -25
  185. package/dist/llm/client-factory.d.ts +3 -3
  186. package/dist/llm/client-factory.js +2 -2
  187. package/dist/llm/model-cache.js +4 -2
  188. package/dist/llm/model-pool.d.ts +29 -11
  189. package/dist/llm/model-pool.js +36 -20
  190. package/dist/llm/provider-auth.d.ts +41 -0
  191. package/dist/llm/provider-auth.js +76 -0
  192. package/dist/llm/provider-catalog.d.ts +6 -2
  193. package/dist/llm/providers/anthropic.d.ts +32 -2
  194. package/dist/llm/providers/anthropic.js +207 -18
  195. package/dist/llm/providers/openai.d.ts +47 -2
  196. package/dist/llm/providers/openai.js +478 -71
  197. package/dist/llm/reasoning-setting.d.ts +51 -0
  198. package/dist/llm/reasoning-setting.js +40 -0
  199. package/dist/llm/stop-reason.d.ts +13 -0
  200. package/dist/llm/stop-reason.js +21 -0
  201. package/dist/llm/stream-watchdog.js +5 -1
  202. package/dist/llm/strip-vision.d.ts +32 -0
  203. package/dist/llm/strip-vision.js +94 -0
  204. package/dist/llm/token-counter.js +9 -2
  205. package/dist/llm/types.d.ts +9 -6
  206. package/dist/logging/logger.js +18 -4
  207. package/dist/logging/sanitize-messages.d.ts +10 -0
  208. package/dist/logging/sanitize-messages.js +112 -0
  209. package/dist/lsp/client.js +28 -8
  210. package/dist/lsp/manager.d.ts +1 -1
  211. package/dist/lsp/manager.js +42 -11
  212. package/dist/lsp/root-path.d.ts +9 -0
  213. package/dist/lsp/root-path.js +12 -0
  214. package/dist/model-catalog/builtin.d.ts +12 -0
  215. package/dist/model-catalog/builtin.js +407 -0
  216. package/dist/model-catalog/gen-connections.d.ts +20 -0
  217. package/dist/model-catalog/gen-connections.js +28 -0
  218. package/dist/model-catalog/index.d.ts +41 -0
  219. package/dist/model-catalog/index.js +90 -0
  220. package/dist/model-catalog/params.d.ts +20 -0
  221. package/dist/model-catalog/params.js +45 -0
  222. package/dist/model-catalog/resolve.d.ts +48 -0
  223. package/dist/model-catalog/resolve.js +33 -0
  224. package/dist/model-catalog/save-entry.d.ts +32 -0
  225. package/dist/model-catalog/save-entry.js +104 -0
  226. package/dist/model-catalog/types.d.ts +561 -0
  227. package/dist/model-catalog/types.js +93 -0
  228. package/dist/model-catalog/upsert.d.ts +9 -0
  229. package/dist/model-catalog/upsert.js +8 -0
  230. package/dist/onboarding.d.ts +12 -82
  231. package/dist/onboarding.js +75 -333
  232. package/dist/plugins/gitOps.d.ts +53 -0
  233. package/dist/plugins/gitOps.js +130 -5
  234. package/dist/plugins/installer/checkUpdate.d.ts +16 -0
  235. package/dist/plugins/installer/checkUpdate.js +32 -0
  236. package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
  237. package/dist/plugins/installer/codex/convertAgents.js +55 -0
  238. package/dist/plugins/installer/codex/convertCommands.d.ts +19 -0
  239. package/dist/plugins/installer/codex/convertCommands.js +46 -0
  240. package/dist/plugins/installer/codex/convertMcp.d.ts +11 -0
  241. package/dist/plugins/installer/codex/convertMcp.js +85 -0
  242. package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
  243. package/dist/plugins/installer/codex/convertSkills.js +33 -0
  244. package/dist/plugins/installer/detectFormat.d.ts +2 -0
  245. package/dist/plugins/installer/detectFormat.js +6 -0
  246. package/dist/plugins/installer/install.d.ts +7 -0
  247. package/dist/plugins/installer/install.js +123 -0
  248. package/dist/plugins/installer/installFromArchive.d.ts +43 -0
  249. package/dist/plugins/installer/installFromArchive.js +134 -0
  250. package/dist/plugins/installer/installFromSource.d.ts +13 -0
  251. package/dist/plugins/installer/installFromSource.js +51 -0
  252. package/dist/plugins/installer/list.d.ts +9 -0
  253. package/dist/plugins/installer/list.js +30 -0
  254. package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
  255. package/dist/plugins/installer/loadPluginAgents.js +27 -0
  256. package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
  257. package/dist/plugins/installer/loadPluginMcp.js +107 -0
  258. package/dist/plugins/installer/parseSource.d.ts +20 -0
  259. package/dist/plugins/installer/parseSource.js +74 -0
  260. package/dist/plugins/installer/paths.d.ts +5 -0
  261. package/dist/plugins/installer/paths.js +25 -0
  262. package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
  263. package/dist/plugins/installer/pruneDisabled.js +73 -0
  264. package/dist/plugins/installer/types.d.ts +52 -0
  265. package/dist/plugins/installer/types.js +28 -0
  266. package/dist/plugins/installer/uninstall.d.ts +2 -0
  267. package/dist/plugins/installer/uninstall.js +18 -0
  268. package/dist/plugins/installer/unzip.d.ts +14 -0
  269. package/dist/plugins/installer/unzip.js +82 -0
  270. package/dist/plugins/installer/update.d.ts +28 -0
  271. package/dist/plugins/installer/update.js +97 -0
  272. package/dist/plugins/loadPluginHooks.d.ts +54 -1
  273. package/dist/plugins/loadPluginHooks.js +83 -1
  274. package/dist/plugins/marketplaceManager.d.ts +15 -1
  275. package/dist/plugins/marketplaceManager.js +58 -4
  276. package/dist/plugins/pluginCommandHook.js +34 -14
  277. package/dist/plugins/pluginContent.d.ts +30 -0
  278. package/dist/plugins/pluginContent.js +83 -0
  279. package/dist/plugins/pluginInstaller.d.ts +34 -0
  280. package/dist/plugins/pluginInstaller.js +168 -35
  281. package/dist/plugins/schemas.js +41 -6
  282. package/dist/plugins/types.d.ts +10 -0
  283. package/dist/preset/index.d.ts +7 -1
  284. package/dist/preset/index.js +112 -6
  285. package/dist/product/types.d.ts +1 -1
  286. package/dist/prompt/composer.d.ts +31 -0
  287. package/dist/prompt/composer.js +95 -25
  288. package/dist/prompt/instruction-scanner.js +5 -3
  289. package/dist/prompt/section-loader.js +1 -0
  290. package/dist/prompt/sections/base.md +1 -0
  291. package/dist/prompt/sections/browser.md +10 -0
  292. package/dist/prompt/sections/coding.md +4 -0
  293. package/dist/prompt/sections/orchestration.md +8 -0
  294. package/dist/protocol/chat-session-manager.d.ts +15 -2
  295. package/dist/protocol/chat-session-manager.js +46 -0
  296. package/dist/protocol/chat-session.d.ts +82 -0
  297. package/dist/protocol/chat-session.js +121 -1
  298. package/dist/protocol/client.d.ts +27 -0
  299. package/dist/protocol/client.js +38 -0
  300. package/dist/protocol/redact.d.ts +50 -0
  301. package/dist/protocol/redact.js +71 -0
  302. package/dist/protocol/server.d.ts +153 -2
  303. package/dist/protocol/server.js +807 -39
  304. package/dist/protocol/tcp-transport.d.ts +45 -0
  305. package/dist/protocol/tcp-transport.js +74 -0
  306. package/dist/protocol/transport.js +3 -2
  307. package/dist/protocol/types.d.ts +69 -0
  308. package/dist/protocol/types.js +22 -0
  309. package/dist/quota/credentials.d.ts +3 -0
  310. package/dist/quota/credentials.js +80 -0
  311. package/dist/quota/index.d.ts +36 -0
  312. package/dist/quota/index.js +155 -0
  313. package/dist/quota/types.d.ts +48 -0
  314. package/dist/quota/types.js +13 -0
  315. package/dist/remote/bridge.d.ts +11 -2
  316. package/dist/remote/bridge.js +61 -33
  317. package/dist/review/review-prompt.d.ts +28 -0
  318. package/dist/review/review-prompt.js +81 -0
  319. package/dist/run/ArtifactTracker.js +5 -4
  320. package/dist/run/EngineRunner.d.ts +27 -1
  321. package/dist/run/EngineRunner.js +46 -8
  322. package/dist/run/FileRunStore.js +40 -11
  323. package/dist/run/RunApprovalBackend.js +25 -5
  324. package/dist/run/RunLock.d.ts +28 -2
  325. package/dist/run/RunLock.js +49 -7
  326. package/dist/run/RunManager.d.ts +12 -0
  327. package/dist/run/RunManager.js +86 -3
  328. package/dist/run/RunQueue.d.ts +1 -0
  329. package/dist/run/RunQueue.js +8 -2
  330. package/dist/run/factory.d.ts +8 -1
  331. package/dist/run/factory.js +1 -0
  332. package/dist/run/index.d.ts +2 -2
  333. package/dist/run/index.js +1 -1
  334. package/dist/run/redirect-target.d.ts +7 -0
  335. package/dist/run/redirect-target.js +13 -0
  336. package/dist/run/types.js +1 -1
  337. package/dist/runtime/background-shell.d.ts +139 -0
  338. package/dist/runtime/background-shell.js +495 -0
  339. package/dist/runtime/output-clean.d.ts +24 -0
  340. package/dist/runtime/output-clean.js +41 -0
  341. package/dist/runtime/ring-file.d.ts +64 -0
  342. package/dist/runtime/ring-file.js +174 -0
  343. package/dist/runtime/safe-spawn.js +15 -34
  344. package/dist/runtime/spawn-common.d.ts +148 -0
  345. package/dist/runtime/spawn-common.js +303 -0
  346. package/dist/runtime/truncate-output.d.ts +22 -0
  347. package/dist/runtime/truncate-output.js +49 -0
  348. package/dist/runtime/utf8-cut.d.ts +11 -0
  349. package/dist/runtime/utf8-cut.js +23 -0
  350. package/dist/services/auto-dream.d.ts +4 -0
  351. package/dist/services/auto-dream.js +26 -26
  352. package/dist/services/browser-open.d.ts +13 -0
  353. package/dist/services/browser-open.js +16 -0
  354. package/dist/services/diagnostics.d.ts +1 -2
  355. package/dist/services/diagnostics.js +12 -7
  356. package/dist/services/dream-consolidation.d.ts +57 -0
  357. package/dist/services/dream-consolidation.js +151 -0
  358. package/dist/services/extract-memories.d.ts +14 -1
  359. package/dist/services/extract-memories.js +45 -6
  360. package/dist/services/memory-orchestrator.d.ts +21 -0
  361. package/dist/services/memory-orchestrator.js +125 -32
  362. package/dist/services/notifier.d.ts +8 -0
  363. package/dist/services/notifier.js +39 -25
  364. package/dist/services/oauth.js +5 -7
  365. package/dist/services/session-memory-sort.d.ts +8 -0
  366. package/dist/services/session-memory-sort.js +9 -0
  367. package/dist/services/session-memory.js +30 -19
  368. package/dist/session/file-history.d.ts +124 -1
  369. package/dist/session/file-history.js +232 -9
  370. package/dist/session/memory.d.ts +116 -2
  371. package/dist/session/memory.js +250 -28
  372. package/dist/session/session-manager.d.ts +63 -1
  373. package/dist/session/session-manager.js +186 -5
  374. package/dist/session/simple-diff.d.ts +23 -0
  375. package/dist/session/simple-diff.js +84 -0
  376. package/dist/session/transcript.d.ts +25 -1
  377. package/dist/session/transcript.js +35 -2
  378. package/dist/session/undo-target.d.ts +67 -0
  379. package/dist/session/undo-target.js +144 -0
  380. package/dist/settings/disk-defaults.d.ts +42 -0
  381. package/dist/settings/disk-defaults.js +33 -0
  382. package/dist/settings/feature-flags.d.ts +64 -0
  383. package/dist/settings/feature-flags.js +61 -0
  384. package/dist/settings/manager.d.ts +101 -1
  385. package/dist/settings/manager.js +345 -15
  386. package/dist/settings/migrate-config.d.ts +45 -0
  387. package/dist/settings/migrate-config.js +125 -0
  388. package/dist/settings/personalization.d.ts +19 -0
  389. package/dist/settings/personalization.js +7 -0
  390. package/dist/settings/schema-export.d.ts +25 -0
  391. package/dist/settings/schema-export.js +38 -0
  392. package/dist/settings/schema.d.ts +1827 -396
  393. package/dist/settings/schema.js +361 -81
  394. package/dist/skills/scanner.d.ts +9 -0
  395. package/dist/skills/scanner.js +30 -2
  396. package/dist/stt/resolve-transcribe.d.ts +31 -0
  397. package/dist/stt/resolve-transcribe.js +108 -0
  398. package/dist/stt/transcribe.d.ts +51 -0
  399. package/dist/stt/transcribe.js +65 -0
  400. package/dist/tool-system/browser-bridge.d.ts +226 -0
  401. package/dist/tool-system/browser-bridge.js +163 -0
  402. package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
  403. package/dist/tool-system/builtin/add-marketplace.js +76 -0
  404. package/dist/tool-system/builtin/agent-heartbeat.d.ts +49 -0
  405. package/dist/tool-system/builtin/agent-heartbeat.js +89 -0
  406. package/dist/tool-system/builtin/agent-notifications.d.ts +12 -3
  407. package/dist/tool-system/builtin/agent-notifications.js +9 -3
  408. package/dist/tool-system/builtin/agent-output-file.d.ts +38 -0
  409. package/dist/tool-system/builtin/agent-output-file.js +72 -0
  410. package/dist/tool-system/builtin/agent-registry.d.ts +23 -0
  411. package/dist/tool-system/builtin/agent-registry.js +16 -4
  412. package/dist/tool-system/builtin/agent.d.ts +50 -11
  413. package/dist/tool-system/builtin/agent.js +576 -73
  414. package/dist/tool-system/builtin/apply-patch/applier.js +66 -8
  415. package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +10 -0
  416. package/dist/tool-system/builtin/apply-patch/backup-targets.js +30 -0
  417. package/dist/tool-system/builtin/apply-patch/index.js +7 -3
  418. package/dist/tool-system/builtin/arena.js +6 -7
  419. package/dist/tool-system/builtin/background-jobs.d.ts +76 -0
  420. package/dist/tool-system/builtin/background-jobs.js +124 -0
  421. package/dist/tool-system/builtin/background-shell-tools.d.ts +20 -0
  422. package/dist/tool-system/builtin/background-shell-tools.js +108 -0
  423. package/dist/tool-system/builtin/background-work.d.ts +67 -0
  424. package/dist/tool-system/builtin/background-work.js +86 -0
  425. package/dist/tool-system/builtin/bash-output-style.d.ts +32 -0
  426. package/dist/tool-system/builtin/bash-output-style.js +40 -0
  427. package/dist/tool-system/builtin/bash.d.ts +5 -2
  428. package/dist/tool-system/builtin/bash.js +98 -62
  429. package/dist/tool-system/builtin/browser-tools.d.ts +33 -0
  430. package/dist/tool-system/builtin/browser-tools.js +312 -0
  431. package/dist/tool-system/builtin/cancel-goal.d.ts +31 -0
  432. package/dist/tool-system/builtin/cancel-goal.js +64 -0
  433. package/dist/tool-system/builtin/check-quota.d.ts +15 -0
  434. package/dist/tool-system/builtin/check-quota.js +34 -0
  435. package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
  436. package/dist/tool-system/builtin/complete-goal.js +45 -0
  437. package/dist/tool-system/builtin/config.js +7 -0
  438. package/dist/tool-system/builtin/cron.d.ts +7 -0
  439. package/dist/tool-system/builtin/cron.js +105 -9
  440. package/dist/tool-system/builtin/drive-claude-code.d.ts +30 -0
  441. package/dist/tool-system/builtin/drive-claude-code.js +157 -0
  442. package/dist/tool-system/builtin/edit-model-catalog.d.ts +3 -0
  443. package/dist/tool-system/builtin/edit-model-catalog.js +94 -0
  444. package/dist/tool-system/builtin/edit.d.ts +2 -1
  445. package/dist/tool-system/builtin/edit.js +21 -12
  446. package/dist/tool-system/builtin/eol.d.ts +29 -0
  447. package/dist/tool-system/builtin/eol.js +37 -0
  448. package/dist/tool-system/builtin/file-cache.d.ts +6 -0
  449. package/dist/tool-system/builtin/file-cache.js +8 -0
  450. package/dist/tool-system/builtin/generate-image.d.ts +60 -0
  451. package/dist/tool-system/builtin/generate-image.js +374 -0
  452. package/dist/tool-system/builtin/generate-video.d.ts +55 -0
  453. package/dist/tool-system/builtin/generate-video.js +361 -0
  454. package/dist/tool-system/builtin/grep.js +6 -2
  455. package/dist/tool-system/builtin/image-providers.d.ts +86 -0
  456. package/dist/tool-system/builtin/image-providers.js +190 -0
  457. package/dist/tool-system/builtin/image-uploader.d.ts +33 -0
  458. package/dist/tool-system/builtin/image-uploader.js +74 -0
  459. package/dist/tool-system/builtin/index.d.ts +24 -1
  460. package/dist/tool-system/builtin/index.js +310 -25
  461. package/dist/tool-system/builtin/mcp-tools.js +23 -3
  462. package/dist/tool-system/builtin/memory.js +45 -7
  463. package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
  464. package/dist/tool-system/builtin/notebook-edit.js +1 -1
  465. package/dist/tool-system/builtin/powershell.js +4 -1
  466. package/dist/tool-system/builtin/read.d.ts +2 -1
  467. package/dist/tool-system/builtin/read.js +11 -3
  468. package/dist/tool-system/builtin/repl.js +4 -1
  469. package/dist/tool-system/builtin/skill.js +9 -0
  470. package/dist/tool-system/builtin/sleep.js +12 -5
  471. package/dist/tool-system/builtin/task.js +4 -1
  472. package/dist/tool-system/builtin/tool-search.js +25 -7
  473. package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
  474. package/dist/tool-system/builtin/update-automation-memory.js +60 -0
  475. package/dist/tool-system/builtin/video-providers.d.ts +154 -0
  476. package/dist/tool-system/builtin/video-providers.js +235 -0
  477. package/dist/tool-system/builtin/view-image.d.ts +18 -0
  478. package/dist/tool-system/builtin/view-image.js +96 -0
  479. package/dist/tool-system/builtin/web-fetch.js +12 -2
  480. package/dist/tool-system/builtin/web-search.d.ts +4 -1
  481. package/dist/tool-system/builtin/web-search.js +57 -10
  482. package/dist/tool-system/builtin/worktree.d.ts +2 -1
  483. package/dist/tool-system/builtin/worktree.js +31 -4
  484. package/dist/tool-system/builtin/write.d.ts +2 -1
  485. package/dist/tool-system/builtin/write.js +1 -1
  486. package/dist/tool-system/context.d.ts +166 -6
  487. package/dist/tool-system/executor.d.ts +3 -2
  488. package/dist/tool-system/executor.js +197 -119
  489. package/dist/tool-system/investigation-guard.d.ts +4 -1
  490. package/dist/tool-system/investigation-guard.js +20 -4
  491. package/dist/tool-system/mcp-manager.d.ts +78 -16
  492. package/dist/tool-system/mcp-manager.js +357 -28
  493. package/dist/tool-system/path-policy.d.ts +99 -0
  494. package/dist/tool-system/path-policy.js +578 -0
  495. package/dist/tool-system/permission.d.ts +36 -1
  496. package/dist/tool-system/permission.js +322 -117
  497. package/dist/tool-system/plan-mode-allowlist.d.ts +32 -0
  498. package/dist/tool-system/plan-mode-allowlist.js +65 -0
  499. package/dist/tool-system/registry.d.ts +1 -0
  500. package/dist/tool-system/registry.js +26 -1
  501. package/dist/tool-system/sandbox/index.d.ts +8 -0
  502. package/dist/tool-system/sandbox/index.js +7 -2
  503. package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
  504. package/dist/tool-system/validate-tool-metadata.js +63 -0
  505. package/dist/tool-system/validation.d.ts +10 -0
  506. package/dist/tool-system/validation.js +16 -3
  507. package/dist/types.d.ts +301 -15
  508. package/dist/updater.js +20 -9
  509. package/dist/utils/envUtils.d.ts +0 -9
  510. package/dist/utils/envUtils.js +3 -28
  511. package/dist/utils/exec.d.ts +40 -0
  512. package/dist/utils/exec.js +144 -0
  513. package/dist/utils/format.js +4 -2
  514. package/dist/utils/json.d.ts +12 -0
  515. package/dist/utils/json.js +92 -0
  516. package/dist/utils/lockfile.js +9 -2
  517. package/dist/utils/theme.d.ts +7 -1
  518. package/dist/utils/theme.js +5 -3
  519. package/dist/utils/toolDisplay.js +0 -1
  520. package/package.json +14 -7
  521. package/dist/agent/coordinator.d.ts +0 -49
  522. package/dist/agent/coordinator.js +0 -77
  523. package/dist/settings/manager.test.js +0 -73
  524. package/dist/tool-system/builtin/remote-trigger.d.ts +0 -6
  525. package/dist/tool-system/builtin/remote-trigger.js +0 -54
  526. package/dist/tool-system/builtin/send-message.d.ts +0 -6
  527. package/dist/tool-system/builtin/send-message.js +0 -47
  528. /package/dist/{settings/manager.test.d.ts → credentials/types.js} +0 -0
@@ -18,6 +18,30 @@ import { estimateMessagesTokens } from "./token-counter.js";
18
18
  export function estimateTokens(messages) {
19
19
  return Math.ceil(estimateMessagesTokens(messages) * (4 / 3));
20
20
  }
21
+ /**
22
+ * Reconcile user-supplied compaction ratios into a safe ordering.
23
+ *
24
+ * The three tiers must satisfy `floor < compact < summarize` or the manager
25
+ * fires them in the wrong order (e.g. an emergency window-compact before the
26
+ * cheaper summary). Users edit these freely in settings.json, so we clamp
27
+ * rather than trust: summarize is pulled up to at least compact, floor is
28
+ * pushed down to at most compact. Absent fields are left undefined so the
29
+ * ContextManager keeps its own default for them.
30
+ */
31
+ export function clampContextRatios(input) {
32
+ const compact = input.compactAtRatio;
33
+ const summarize = input.summarizeAtRatio !== undefined && compact !== undefined
34
+ ? Math.max(input.summarizeAtRatio, compact)
35
+ : input.summarizeAtRatio;
36
+ const floor = input.microcompactFloorRatio !== undefined && compact !== undefined
37
+ ? Math.min(input.microcompactFloorRatio, compact)
38
+ : input.microcompactFloorRatio;
39
+ return {
40
+ compactAtRatio: compact,
41
+ summarizeAtRatio: summarize,
42
+ microcompactFloorRatio: floor,
43
+ };
44
+ }
21
45
  // ─── Tool Use / Result Pair Protection ──────────────────────────────
22
46
  /**
23
47
  * Expand a slice start-index backwards so that every tool_result in the
@@ -275,6 +299,168 @@ export function microcompact(messages, options = {}) {
275
299
  }
276
300
  return result;
277
301
  }
302
+ /** Tools whose result is the content of a single file, keyed by path. */
303
+ const FILE_READ_TOOLS = new Set(["Read"]);
304
+ /**
305
+ * Content-aware dedup: when the SAME file is Read more than once, every Read
306
+ * result except the most recent is stale — the file's current state is in the
307
+ * latest read. Clear the older ones (replace with a fingerprint pointing at
308
+ * the newer read) regardless of the recency window or pressure floor, because
309
+ * this is pure waste removal, not lossy compaction: the model never needs two
310
+ * copies of the same file.
311
+ *
312
+ * Distinct from microcompact (which is recency-gated and pressure-gated): a
313
+ * file Read 3 times in the last 3 turns keeps 3 full copies under microcompact
314
+ * but only the newest under this pass. Zero-cost and always safe to run, so the
315
+ * ContextManager calls it as an early tier.
316
+ *
317
+ * Only `Read` is deduped (its result is exactly the file content). Edit/Write
318
+ * results are diffs/confirmations, not full snapshots, so they're left alone.
319
+ */
320
+ export function dedupeFileReads(messages) {
321
+ const idToName = buildToolUseIdToNameMap(messages);
322
+ const idToInput = new Map();
323
+ for (const msg of messages) {
324
+ if (!Array.isArray(msg.content))
325
+ continue;
326
+ for (const block of msg.content) {
327
+ if (block.type === "tool_use" && block.id)
328
+ idToInput.set(block.id, block.input);
329
+ }
330
+ }
331
+ // Resolve a Read tool_use_id to its file_path arg (the dedup key).
332
+ const pathOf = (toolUseId) => {
333
+ const input = idToInput.get(toolUseId);
334
+ const p = input?.file_path ?? input?.path;
335
+ return typeof p === "string" && p.length > 0 ? p : undefined;
336
+ };
337
+ // Collect, per file path, the message indices + block positions of every
338
+ // non-cleared Read result. Walk forward so "last" is the newest.
339
+ const byPath = new Map();
340
+ for (let i = 0; i < messages.length; i++) {
341
+ const msg = messages[i];
342
+ if (!Array.isArray(msg.content))
343
+ continue;
344
+ for (const block of msg.content) {
345
+ if (block.type !== "tool_result" || !block.tool_use_id)
346
+ continue;
347
+ if (!FILE_READ_TOOLS.has(idToName.get(block.tool_use_id) ?? ""))
348
+ continue;
349
+ if (typeof block.content !== "string")
350
+ continue;
351
+ if (block.content.startsWith("[Old tool result cleared"))
352
+ continue;
353
+ const path = pathOf(block.tool_use_id);
354
+ if (!path)
355
+ continue;
356
+ const list = byPath.get(path) ?? [];
357
+ list.push({ msgIdx: i, toolUseId: block.tool_use_id });
358
+ byPath.set(path, list);
359
+ }
360
+ }
361
+ // For each path read more than once, mark all-but-last for clearing.
362
+ const clearIds = new Set();
363
+ for (const [, reads] of byPath) {
364
+ if (reads.length < 2)
365
+ continue;
366
+ for (let k = 0; k < reads.length - 1; k++)
367
+ clearIds.add(reads[k].toolUseId);
368
+ }
369
+ if (clearIds.size === 0)
370
+ return { messages, clearedCount: 0 };
371
+ let clearedCount = 0;
372
+ const result = messages.map((msg) => {
373
+ if (!Array.isArray(msg.content))
374
+ return msg;
375
+ return {
376
+ ...msg,
377
+ content: msg.content.map((block) => {
378
+ if (block.type !== "tool_result" || !block.tool_use_id)
379
+ return block;
380
+ if (!clearIds.has(block.tool_use_id))
381
+ return block;
382
+ const argsSummary = summarizeToolCallArgs("Read", idToInput.get(block.tool_use_id));
383
+ clearedCount++;
384
+ return {
385
+ ...block,
386
+ content: `[Old tool result cleared — superseded by a newer Read${argsSummary ? ` of ${argsSummary}` : ""}]`,
387
+ };
388
+ }),
389
+ };
390
+ });
391
+ return { messages: result, clearedCount };
392
+ }
393
+ /** Build id → true for tool_use blocks that are a browser snapshot observation,
394
+ * i.e. `browser_observe` with mode "snapshot" (the default when mode omitted).
395
+ * Only snapshots produce large, supersede-able element lists worth masking. */
396
+ function buildSnapshotObserveIdSet(messages) {
397
+ const ids = new Set();
398
+ for (const msg of messages) {
399
+ if (!Array.isArray(msg.content))
400
+ continue;
401
+ for (const block of msg.content) {
402
+ if (block.type !== "tool_use" || !block.id || block.name !== "browser_observe")
403
+ continue;
404
+ const mode = block.input?.mode;
405
+ if (mode === undefined || mode === "snapshot")
406
+ ids.add(block.id);
407
+ }
408
+ }
409
+ return ids;
410
+ }
411
+ const OLD_SNAPSHOT_PLACEHOLDER = "[Old browser snapshot collapsed — superseded by a newer browser_observe(snapshot). " +
412
+ "Re-run browser_observe for the current page's elements.]";
413
+ /**
414
+ * Observation masking for browser_observe(snapshot) results (the research's
415
+ * highest-leverage browser-token saving: a page snapshot is large and only the
416
+ * LATEST one matters for the next decision; older ones are stale element lists).
417
+ * Keep the most recent snapshot result verbatim; replace every earlier one with
418
+ * a one-line placeholder. Deterministic — no LLM summarization needed.
419
+ *
420
+ * Keyed on the snapshot OBSERVATION (browser_observe with mode snapshot) — read/
421
+ * extract observations and act results are left untouched. Renamed from
422
+ * maskOldBrowserSnapshots when the 9 browser_* tools collapsed into 3.
423
+ */
424
+ export function maskOldObservations(messages) {
425
+ const snapshotIds = buildSnapshotObserveIdSet(messages);
426
+ const snapResults = [];
427
+ for (const msg of messages) {
428
+ if (!Array.isArray(msg.content))
429
+ continue;
430
+ for (const block of msg.content) {
431
+ if (block.type !== "tool_result" || !block.tool_use_id)
432
+ continue;
433
+ if (!snapshotIds.has(block.tool_use_id))
434
+ continue;
435
+ if (typeof block.content !== "string")
436
+ continue;
437
+ if (block.content.startsWith("[Old browser snapshot collapsed"))
438
+ continue;
439
+ snapResults.push(block.tool_use_id);
440
+ }
441
+ }
442
+ if (snapResults.length < 2)
443
+ return { messages, maskedCount: 0 };
444
+ // Mask all but the last (newest walked-forward).
445
+ const maskIds = new Set(snapResults.slice(0, -1));
446
+ let maskedCount = 0;
447
+ const result = messages.map((msg) => {
448
+ if (!Array.isArray(msg.content))
449
+ return msg;
450
+ return {
451
+ ...msg,
452
+ content: msg.content.map((block) => {
453
+ if (block.type !== "tool_result" || !block.tool_use_id)
454
+ return block;
455
+ if (!maskIds.has(block.tool_use_id))
456
+ return block;
457
+ maskedCount++;
458
+ return { ...block, content: OLD_SNAPSHOT_PLACEHOLDER };
459
+ }),
460
+ };
461
+ });
462
+ return { messages: result, maskedCount };
463
+ }
278
464
  /**
279
465
  * Apply aggregate per-message tool result budget.
280
466
  * When total tool_result content in a single message exceeds maxTotalChars,
@@ -299,28 +485,36 @@ export function applyToolResultBudget(messages, maxTotalChars = 100_000) {
299
485
  return msg;
300
486
  // Sort by size descending — truncate largest first
301
487
  resultBlocks.sort((a, b) => b.size - a.size);
488
+ // Build the exact replacement for a block, so the running budget uses the
489
+ // real post-truncation length (the old code assumed a flat ~200 chars,
490
+ // but the replacement is ~150 boilerplate + up to 500 preview ≈ 650+,
491
+ // which under-truncated and could even leave the message LARGER).
492
+ const truncate = (content) => {
493
+ const preview = content.slice(0, 500);
494
+ const sizeKb = (content.length / 1000).toFixed(0);
495
+ return (`Output too large (${sizeKb}KB) — truncated to fit the per-message budget. ` +
496
+ `Re-run the originating tool if you need the full output.\n\n` +
497
+ `Preview (first 500 chars):\n${preview}`);
498
+ };
302
499
  let remaining = totalSize;
303
- const toTruncate = new Set();
500
+ const replacements = new Map();
304
501
  for (const rb of resultBlocks) {
305
502
  if (remaining <= maxTotalChars)
306
503
  break;
307
- toTruncate.add(rb.index);
308
- remaining -= rb.size;
309
- remaining += 200; // truncated replacement is ~200 chars
504
+ const original = msg.content[rb.index].content;
505
+ const replaced = truncate(original);
506
+ // Only truncate if it actually shrinks the block; otherwise skip it
507
+ // (truncating a barely-oversized block would grow the message).
508
+ if (replaced.length >= rb.size)
509
+ continue;
510
+ replacements.set(rb.index, replaced);
511
+ remaining -= rb.size - replaced.length;
310
512
  }
311
- if (toTruncate.size === 0)
513
+ if (replacements.size === 0)
312
514
  return msg;
313
515
  const newContent = msg.content.map((block, i) => {
314
- if (!toTruncate.has(i))
315
- return block;
316
- const preview = typeof block.content === "string" ? block.content.slice(0, 500) : "";
317
- const sizeKb = (block.content.length / 1000).toFixed(0);
318
- return {
319
- ...block,
320
- content: `Output too large (${sizeKb}KB) — truncated to fit the per-message budget. ` +
321
- `Re-run the originating tool if you need the full output.\n\n` +
322
- `Preview (first 500 chars):\n${preview}`,
323
- };
516
+ const replaced = replacements.get(i);
517
+ return replaced === undefined ? block : { ...block, content: replaced };
324
518
  });
325
519
  return { ...msg, content: newContent };
326
520
  });
@@ -39,7 +39,6 @@ export type OnCompactFn = (info: {
39
39
  }) => void;
40
40
  export declare class ContextManager {
41
41
  private config;
42
- private toolCallHashes;
43
42
  private summarizeFn;
44
43
  private consecutiveSummaryFailures;
45
44
  private lastSummary;
@@ -123,23 +122,4 @@ export declare class ContextManager {
123
122
  needsCompact: boolean;
124
123
  needsEmergency: boolean;
125
124
  };
126
- /**
127
- * Deduplicate tool calls by hashing arguments.
128
- */
129
- deduplicateToolCalls(calls: Array<{
130
- toolName: string;
131
- args: Record<string, unknown>;
132
- }>): {
133
- toExecute: typeof calls;
134
- cached: Array<{
135
- toolName: string;
136
- args: Record<string, unknown>;
137
- result: string;
138
- }>;
139
- };
140
- /**
141
- * Record a tool call result for dedup tracking.
142
- */
143
- recordToolResult(toolName: string, args: Record<string, unknown>, result: string): void;
144
- private hashCall;
145
125
  }
@@ -5,7 +5,7 @@
5
5
  * Tier 2: LLM summary (async) — generate summary of older messages via model call
6
6
  * Tier 3: window compact (sync, emergency) — aggressive truncation fallback
7
7
  */
8
- import { estimateTokens, microcompact, snipCompact, windowCompact, truncateToolResult, buildSummarizationPrompt, applySummaryCompaction, applyToolResultBudget, extractAnchoredSummary, } from "./compaction.js";
8
+ import { estimateTokens, microcompact, dedupeFileReads, maskOldObservations, snipCompact, windowCompact, truncateToolResult, buildSummarizationPrompt, applySummaryCompaction, applyToolResultBudget, extractAnchoredSummary, } from "./compaction.js";
9
9
  import { applyToolResultPersistence, createContentReplacementState, reconstructContentReplacementState, resolveToolResultsDir, } from "./tool-result-storage.js";
10
10
  import { logger } from "../logging/logger.js";
11
11
  const DEFAULT_CONFIG = {
@@ -39,7 +39,6 @@ function defaultKeepRecent(maxTokens) {
39
39
  }
40
40
  export class ContextManager {
41
41
  config;
42
- toolCallHashes = new Map();
43
42
  summarizeFn;
44
43
  consecutiveSummaryFailures = 0;
45
44
  lastSummary;
@@ -128,6 +127,25 @@ export class ContextManager {
128
127
  // Tier 0c: Aggregate tool result budget (per-message) — char-level
129
128
  // backstop for messages still over the limit after persistence.
130
129
  result = applyToolResultBudget(result);
130
+ // Tier 0d: dedup repeated Reads of the same file — keep only the latest
131
+ // copy (older ones are stale). Always-on + zero-cost: it's pure waste
132
+ // removal (the model never needs two snapshots of one file), unlike the
133
+ // pressure-/recency-gated tiers below. Runs before microcompact so an
134
+ // already-deduped result isn't double-counted toward the keep-recent window.
135
+ const dedup = dedupeFileReads(result);
136
+ if (dedup.clearedCount > 0) {
137
+ result = dedup.messages;
138
+ logger.info("context.dedupe_file_reads", { cleared: dedup.clearedCount });
139
+ }
140
+ // Tier 0d': browser observation masking — keep only the latest
141
+ // browser_snapshot, collapse older ones (stale element lists, often large).
142
+ // Same always-on waste-removal class as dedupeFileReads. The research's
143
+ // top browser-token lever (folding old observations beats LLM summarizing).
144
+ const masked = maskOldObservations(result);
145
+ if (masked.maskedCount > 0) {
146
+ result = masked.messages;
147
+ logger.info("context.mask_browser_snapshots", { masked: masked.maskedCount });
148
+ }
131
149
  // Tier 1: microcompact — fingerprint old whitelisted tool_results.
132
150
  // Only runs above the floor ratio: under-pressure context keeps full
133
151
  // detail so the model isn't forced to re-Read files it just looked at.
@@ -342,20 +360,22 @@ export class ContextManager {
342
360
  */
343
361
  truncateToolResults(messages) {
344
362
  const maxChars = this.config.maxToolResultChars;
345
- let modified = false;
346
363
  const result = messages.map((msg) => {
347
364
  if (!Array.isArray(msg.content))
348
365
  return msg;
366
+ // Per-message flag: a truncation in an earlier message must not force
367
+ // later, unchanged messages to be spread-copied.
368
+ let messageModified = false;
349
369
  const newContent = msg.content.map((block) => {
350
370
  if (block.type === "tool_result" && typeof block.content === "string") {
351
371
  if (block.content.length > maxChars) {
352
- modified = true;
372
+ messageModified = true;
353
373
  return { ...block, content: truncateToolResult(block.content, maxChars) };
354
374
  }
355
375
  }
356
376
  return block;
357
377
  });
358
- return modified ? { ...msg, content: newContent } : msg;
378
+ return messageModified ? { ...msg, content: newContent } : msg;
359
379
  });
360
380
  return result;
361
381
  }
@@ -384,40 +404,4 @@ export class ContextManager {
384
404
  needsEmergency: ratio >= this.config.summarizeAtRatio,
385
405
  };
386
406
  }
387
- /**
388
- * Deduplicate tool calls by hashing arguments.
389
- */
390
- deduplicateToolCalls(calls) {
391
- const toExecute = [];
392
- const cached = [];
393
- for (const call of calls) {
394
- const hash = this.hashCall(call.toolName, call.args);
395
- const existing = this.toolCallHashes.get(hash);
396
- if (existing && existing.count >= 2) {
397
- cached.push({ ...call, result: existing.lastResult });
398
- existing.count++;
399
- }
400
- else {
401
- toExecute.push(call);
402
- }
403
- }
404
- return { toExecute, cached };
405
- }
406
- /**
407
- * Record a tool call result for dedup tracking.
408
- */
409
- recordToolResult(toolName, args, result) {
410
- const hash = this.hashCall(toolName, args);
411
- const existing = this.toolCallHashes.get(hash);
412
- if (existing) {
413
- existing.count++;
414
- existing.lastResult = result;
415
- }
416
- else {
417
- this.toolCallHashes.set(hash, { count: 1, lastResult: result });
418
- }
419
- }
420
- hashCall(toolName, args) {
421
- return `${toolName}:${JSON.stringify(args)}`;
422
- }
423
407
  }
@@ -3,67 +3,11 @@
3
3
  */
4
4
  import { NOOP_COLORIZER } from "./colorizer.js";
5
5
  import { findOpenRouterModel } from "./data/openrouter-models.js";
6
- function pricing(input, output) {
7
- // Default cache pricing: read = 10% of input, write = 125% of input
8
- return { input, output, cacheRead: input * 0.1, cacheWrite: input * 1.25 };
9
- }
10
- const MODEL_PRICING = {
11
- // Anthropic (per 1M tokens, USD)
12
- "claude-opus-4.6": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
13
- "claude-opus-4-6": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 }, // alias
14
- "claude-opus-4.5": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
15
- "claude-opus-4.1": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
16
- "claude-opus-4": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
17
- "claude-sonnet-4.6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
18
- "claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, // alias
19
- "claude-sonnet-4.5": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
20
- "claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
21
- "claude-3.7-sonnet": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
22
- "claude-3-7-sonnet": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
23
- "claude-3.5-haiku": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
24
- "claude-haiku-4.5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
25
- "claude-haiku-4-5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, // alias
26
- // OpenAI
27
- "gpt-5.4": pricing(5, 20),
28
- "gpt-5.4-mini": pricing(1.5, 6),
29
- "gpt-5.4-pro": pricing(10, 40),
30
- "gpt-5": pricing(5, 20),
31
- "gpt-4o": pricing(2.5, 10),
32
- "gpt-4o-mini": pricing(0.15, 0.6),
33
- "gpt-4.1": pricing(2, 8),
34
- "gpt-4.1-mini": pricing(0.4, 1.6),
35
- "o4-mini": pricing(1.1, 4.4),
36
- "o3": pricing(10, 40),
37
- "o3-mini": pricing(1.1, 4.4),
38
- // Google
39
- "gemini-2.5-pro": pricing(1.25, 10),
40
- "gemini-2.5-pro-preview": pricing(1.25, 10),
41
- "gemini-2.5-flash": pricing(0.15, 0.6),
42
- "gemini-3.1-pro-preview": pricing(2, 10),
43
- "gemini-3-flash-preview": pricing(0.15, 0.6),
44
- "gemini-2.0-flash": pricing(0.1, 0.4),
45
- // DeepSeek
46
- "deepseek-v4-flash": pricing(0.126, 0.252),
47
- "deepseek-v4-pro": pricing(0.5, 2),
48
- "deepseek-v3.2": pricing(0.14, 0.28),
49
- "deepseek-chat": pricing(0.14, 0.28),
50
- "deepseek-r1": pricing(0.55, 2.19),
51
- "deepseek-reasoner": pricing(0.55, 2.19),
52
- // Qwen
53
- "qwen3-coder": pricing(0.3, 0.6),
54
- "qwen3-235b-a22b": pricing(0.3, 1.2),
55
- "qwen3-30b-a3b": pricing(0.1, 0.3),
56
- "qwen3-max": pricing(0.5, 2),
57
- // Meta
58
- "llama-4-maverick": pricing(0.2, 0.8),
59
- "llama-4-scout": pricing(0.15, 0.4),
60
- // Mistral
61
- "devstral-medium": pricing(0.5, 1.5),
62
- "mistral-large": pricing(2, 6),
63
- "devstral-small": pricing(0.1, 0.3),
64
- };
65
- // Default fallback pricing
66
- const DEFAULT_PRICING = pricing(3, 15);
6
+ import { MODEL_PRICING, DEFAULT_PRICING, } from "./data/model-metadata.js";
7
+ // Pricing per 1M tokens (USD). The MODEL_PRICING table + DEFAULT_PRICING now
8
+ // live in data/model-metadata.json (loaded by data/model-metadata.ts) so a
9
+ // price change is a data edit, not a code change. cacheRead/cacheWrite are
10
+ // derived there: read = 10% of input, write = 125% of input.
67
11
  /** Build a ModelPricing from an OpenRouter snapshot entry. */
68
12
  function openRouterPricing(hit) {
69
13
  const input = hit.inputPricePerMillion;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Credential encryption boundary.
3
+ *
4
+ * The core has no business owning a platform encryption key — on the desktop
5
+ * the only safe key lives behind Electron `safeStorage`, which is in the main
6
+ * process, not in this worker. So core defines an INTERFACE and the host feeds
7
+ * an implementation: desktop main injects a safeStorage-backed cipher; the
8
+ * headless CLI / SDK inject {@link PlaintextCipher}. This keeps `safeStorage`
9
+ * out of `packages/core` entirely (`grep -R safeStorage packages/core/src`
10
+ * must stay empty) and puts secret crypto where the key actually is.
11
+ *
12
+ * The stored field is a tagged string so a store written by one cipher can be
13
+ * read (or rejected) by another:
14
+ * - `plain:<secret>` — PlaintextCipher, or any pre-cipher legacy value
15
+ * that has no recognized prefix (treated as plain).
16
+ * - `enc:<scheme>:<base64>` — an encrypting cipher; `<scheme>` lets a cipher
17
+ * recognize its own ciphertext via canDecrypt().
18
+ */
19
+ export interface EncryptionCipher {
20
+ /** Encrypt a plaintext secret into its stored (tagged) form. */
21
+ encrypt(plaintext: string): string;
22
+ /** Decrypt a stored value back to plaintext. Must accept this cipher's own
23
+ * output and legacy un-prefixed plaintext; may throw if a value is
24
+ * recognizably foreign and undecryptable. */
25
+ decrypt(stored: string): string;
26
+ /** True when this cipher can decrypt `stored`. Used by the store to decide
27
+ * whether to migrate (re-encrypt on next save) a value written by a
28
+ * different cipher / left as legacy plaintext. */
29
+ canDecrypt?(stored: string): boolean;
30
+ }
31
+ /**
32
+ * The no-encryption strategy — chosen explicitly, not a no-op. Headless and
33
+ * SDK hosts have no safe key store, so they keep credentials as owner-only
34
+ * (0o600) plaintext, exactly as before this boundary existed. Named so the
35
+ * choice reads honestly in host wiring: `new CredentialStore(cwd, new
36
+ * PlaintextCipher())` says "plaintext on purpose", not "forgot to encrypt".
37
+ */
38
+ export declare class PlaintextCipher implements EncryptionCipher {
39
+ encrypt(plaintext: string): string;
40
+ decrypt(stored: string): string;
41
+ canDecrypt(stored: string): boolean;
42
+ }
43
+ /** Reads a value that may be tagged (`plain:`) or legacy bare plaintext. */
44
+ export declare function readPlaintext(stored: string): string;
45
+ /** Host startup hook: install the process-wide credential cipher (desktop main
46
+ * passes a safeStorage-backed implementation). Idempotent; last call wins. */
47
+ export declare function setDefaultCredentialCipher(cipher: EncryptionCipher): void;
48
+ /** The current process-default cipher (PlaintextCipher unless a host set one). */
49
+ export declare function getDefaultCredentialCipher(): EncryptionCipher;
@@ -0,0 +1,45 @@
1
+ const PLAIN_PREFIX = "plain:";
2
+ /**
3
+ * The no-encryption strategy — chosen explicitly, not a no-op. Headless and
4
+ * SDK hosts have no safe key store, so they keep credentials as owner-only
5
+ * (0o600) plaintext, exactly as before this boundary existed. Named so the
6
+ * choice reads honestly in host wiring: `new CredentialStore(cwd, new
7
+ * PlaintextCipher())` says "plaintext on purpose", not "forgot to encrypt".
8
+ */
9
+ export class PlaintextCipher {
10
+ encrypt(plaintext) {
11
+ return `${PLAIN_PREFIX}${plaintext}`;
12
+ }
13
+ decrypt(stored) {
14
+ // Accept our own tag, and treat any un-tagged legacy value as plaintext.
15
+ if (stored.startsWith(PLAIN_PREFIX))
16
+ return stored.slice(PLAIN_PREFIX.length);
17
+ if (stored.startsWith("enc:")) {
18
+ throw new Error("PlaintextCipher cannot decrypt an encrypted credential");
19
+ }
20
+ return stored;
21
+ }
22
+ canDecrypt(stored) {
23
+ return !stored.startsWith("enc:");
24
+ }
25
+ }
26
+ /** Reads a value that may be tagged (`plain:`) or legacy bare plaintext. */
27
+ export function readPlaintext(stored) {
28
+ return stored.startsWith(PLAIN_PREFIX) ? stored.slice(PLAIN_PREFIX.length) : stored;
29
+ }
30
+ // ─── Process-default cipher ──────────────────────────────────────
31
+ // CredentialStore is constructed at ~12 call sites (core + desktop) as
32
+ // `new CredentialStore(cwd)`. Rather than thread a cipher through every one,
33
+ // the host sets the process default ONCE at startup; stores pick it up unless
34
+ // a cipher is passed explicitly. Defaults to PlaintextCipher so any host that
35
+ // never calls the setter behaves exactly as before.
36
+ let defaultCipher = new PlaintextCipher();
37
+ /** Host startup hook: install the process-wide credential cipher (desktop main
38
+ * passes a safeStorage-backed implementation). Idempotent; last call wins. */
39
+ export function setDefaultCredentialCipher(cipher) {
40
+ defaultCipher = cipher;
41
+ }
42
+ /** The current process-default cipher (PlaintextCipher unless a host set one). */
43
+ export function getDefaultCredentialCipher() {
44
+ return defaultCipher;
45
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Cookie jar 工具(凭证模块第二期):core 侧的纯函数,把存进 CredentialStore 的
3
+ * cookie 凭证(序列化的 jar)转成 yt-dlp/curl/wget/aria2 都吃的 Netscape cookies.txt。
4
+ *
5
+ * 形态与 desktop/src/main/credentials-service.ts 的 `formatNetscapeCookies` 一致
6
+ * (desktop 在拓取那一刻用,core 在取用那一刻用)。core 不能 import desktop,故各持一份
7
+ * 同语义的纯实现 —— 都无 Electron 依赖、可单测。
8
+ */
9
+ /** 与 Electron Cookie 对齐的最小子集(jar 里存的就是这个)。 */
10
+ export interface CookieLike {
11
+ domain?: string;
12
+ hostOnly?: boolean;
13
+ path?: string;
14
+ secure?: boolean;
15
+ expirationDate?: number;
16
+ name: string;
17
+ value: string;
18
+ }
19
+ /** Cookie[] → Netscape cookies.txt 字符串。跳过含 TAB/换行的脏 cookie。 */
20
+ export declare function formatNetscapeCookies(cookies: CookieLike[]): string;
21
+ /**
22
+ * 解析 cookie 凭证的 `secret`(序列化 jar)。容错:非数组/坏 JSON → 空数组。
23
+ */
24
+ export declare function parseCookieJar(secret: string | undefined): CookieLike[];
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Cookie jar 工具(凭证模块第二期):core 侧的纯函数,把存进 CredentialStore 的
3
+ * cookie 凭证(序列化的 jar)转成 yt-dlp/curl/wget/aria2 都吃的 Netscape cookies.txt。
4
+ *
5
+ * 形态与 desktop/src/main/credentials-service.ts 的 `formatNetscapeCookies` 一致
6
+ * (desktop 在拓取那一刻用,core 在取用那一刻用)。core 不能 import desktop,故各持一份
7
+ * 同语义的纯实现 —— 都无 Electron 依赖、可单测。
8
+ */
9
+ function bad(s) {
10
+ return s.includes("\t") || s.includes("\n") || s.includes("\r");
11
+ }
12
+ /** Cookie[] → Netscape cookies.txt 字符串。跳过含 TAB/换行的脏 cookie。 */
13
+ export function formatNetscapeCookies(cookies) {
14
+ const lines = ["# Netscape HTTP Cookie File"];
15
+ for (const c of cookies) {
16
+ if (bad(c.name) || bad(c.value) || (c.domain && bad(c.domain)))
17
+ continue;
18
+ const domain = c.domain ?? "";
19
+ const includeSub = c.hostOnly === true ? "FALSE" : "TRUE";
20
+ const path = c.path ?? "/";
21
+ const secure = c.secure ? "TRUE" : "FALSE";
22
+ const expiry = typeof c.expirationDate === "number" ? String(Math.floor(c.expirationDate)) : "0";
23
+ lines.push([domain, includeSub, path, secure, expiry, c.name, c.value].join("\t"));
24
+ }
25
+ return lines.join("\n") + "\n";
26
+ }
27
+ /**
28
+ * 解析 cookie 凭证的 `secret`(序列化 jar)。容错:非数组/坏 JSON → 空数组。
29
+ */
30
+ export function parseCookieJar(secret) {
31
+ if (!secret)
32
+ return [];
33
+ try {
34
+ const parsed = JSON.parse(secret);
35
+ return Array.isArray(parsed) ? parsed : [];
36
+ }
37
+ catch {
38
+ return [];
39
+ }
40
+ }
@@ -0,0 +1,7 @@
1
+ export { CredentialStore } from "./store.js";
2
+ export type { CredentialScope, MaskedCredential } from "./store.js";
3
+ export { type EncryptionCipher, PlaintextCipher, setDefaultCredentialCipher, getDefaultCredentialCipher, } from "./cipher.js";
4
+ export type { Credential, CredentialType, CredentialStoreFile } from "./types.js";
5
+ export { formatNetscapeCookies, parseCookieJar, type CookieLike } from "./cookie-jar.js";
6
+ export { useCredentialToolDef, useCredentialToolDefFor, useCredentialTool, sweepStaleCredentialCookies, } from "./use-credential-tool.js";
7
+ export { credentialUseGate } from "./use-gate.js";
@@ -0,0 +1,5 @@
1
+ export { CredentialStore } from "./store.js";
2
+ export { PlaintextCipher, setDefaultCredentialCipher, getDefaultCredentialCipher, } from "./cipher.js";
3
+ export { formatNetscapeCookies, parseCookieJar } from "./cookie-jar.js";
4
+ export { useCredentialToolDef, useCredentialToolDefFor, useCredentialTool, sweepStaleCredentialCookies, } from "./use-credential-tool.js";
5
+ export { credentialUseGate } from "./use-gate.js";
@@ -0,0 +1,20 @@
1
+ /**
2
+ * InjectCredential 工具:把一条 cookie 凭证「注入内置浏览器」(恢复登录态),
3
+ * 让 AI 能以该账号身份在内置浏览器面板做 UI 操作(配 browser_* 工具)。
4
+ *
5
+ * 与 UseCredential 的区别:
6
+ * - UseCredential 取 cookie 文件路径走 HTTP 请求(curl/yt-dlp),只读、不改浏览器。
7
+ * - InjectCredential 改的是内置浏览器的登录态(先清再灌),副作用更大 →
8
+ * 独立的逐条门 `autoInjectByAI`(不复用 autoUseByAI)。
9
+ *
10
+ * 跨进程:实际的 restoreCookiesToBrowser 在 desktop main(core 够不到 Electron
11
+ * session),经 `ctx.injectCredentialToBrowser` 回调(宿主注入,镜像 askUser)触发。
12
+ */
13
+ import type { ToolDefinition } from "../types.js";
14
+ import type { ToolContext } from "../tool-system/context.js";
15
+ export declare const injectCredentialToolDef: ToolDefinition;
16
+ /** 该工具仅在有 cookie 凭证 且 宿主接了注入回调时才可见(BUILTIN_TOOL_GUARDS)。 */
17
+ export declare function isInjectCredentialAvailable(cwd: string): boolean;
18
+ export declare function injectCredentialTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
19
+ /** 测试钩子:清空会话 allow 集。 */
20
+ export declare function __resetInjectCredentialSessionAllowForTests(): void;