@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
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Engine-side image compression — the fallback for hosts that didn't
3
+ * pre-compress.
4
+ *
5
+ * The desktop renderer already compresses via <canvas> + Blob before
6
+ * sending; the TUI and MCP image-returning tools historically didn't.
7
+ * When the {@link enforceImagePolicy} gate would otherwise refuse a
8
+ * turn for "image too large", we try to bring the offender(s) under
9
+ * the limit first by:
10
+ *
11
+ * 1. Decoding the base64 payload.
12
+ * 2. Resizing the longest edge down to {@link IMAGE_TARGETS.targetMaxDimension}.
13
+ * 3. Re-encoding as JPEG at {@link IMAGE_TARGETS.jpegQuality}.
14
+ *
15
+ * jimp is the obvious pick — pure-JS, no native binaries, runs in
16
+ * both Node and Bun, supports PNG / JPEG / WebP input. But shipping
17
+ * it as a hard `core` dep would balloon the published bundle for
18
+ * every consumer. So we resolve it dynamically: hosts that want
19
+ * automatic compression just `npm install jimp`; everyone else gets
20
+ * the existing "image too large" refusal.
21
+ *
22
+ * Hosts can also inject a custom {@link ImageCompressor} via
23
+ * {@link setEngineImageCompressor} — useful for tests, future
24
+ * sharp-based compressors, or arena agents with different size
25
+ * targets.
26
+ *
27
+ * The defaults must stay pure-JS so this module is safe to bundle for
28
+ * Electron preload / browser worker contexts. Anything that needs
29
+ * native code (e.g. sharp) should be injected explicitly.
30
+ */
31
+ import { IMAGE_LIMITS, IMAGE_TARGETS, byteLengthFromBase64 } from "./image-policy.js";
32
+ /**
33
+ * No-op compressor: returns the input unchanged. Used when the host
34
+ * didn't install jimp and didn't inject anything else, so behavior
35
+ * stays the same as before this module existed.
36
+ */
37
+ const NOOP_COMPRESSOR = {
38
+ async compress(image, _maxBytes) {
39
+ const bytes = byteLengthFromBase64(image.base64);
40
+ return {
41
+ image,
42
+ compressed: false,
43
+ originalBytes: bytes,
44
+ finalBytes: bytes,
45
+ };
46
+ },
47
+ };
48
+ let activeCompressor = null;
49
+ /**
50
+ * Override the engine's active compressor. Pass `null` to clear the
51
+ * override and fall back to lazy jimp resolution. Hosts that want
52
+ * deterministic behavior in tests typically call this with a stub.
53
+ */
54
+ export function setEngineImageCompressor(c) {
55
+ activeCompressor = c;
56
+ }
57
+ /** Reset state — for tests. */
58
+ export function resetEngineImageCompressor() {
59
+ activeCompressor = null;
60
+ cachedJimpCompressor = null;
61
+ }
62
+ let cachedJimpCompressor = null;
63
+ /**
64
+ * Resolve a jimp-backed compressor on first call. If jimp isn't
65
+ * installed, cache the no-op and stop retrying.
66
+ *
67
+ * jimp's API: `await Jimp.read(buffer)` → resize / quality / getBuffer.
68
+ * v0.x used CamelCase constants (e.g. `Jimp.MIME_JPEG`); v1 moved to
69
+ * an explicit string mime arg. We accept both by feature-testing.
70
+ */
71
+ async function resolveJimpCompressor() {
72
+ if (cachedJimpCompressor)
73
+ return cachedJimpCompressor;
74
+ try {
75
+ // Dynamic import so consumers without jimp installed don't pay
76
+ // the bundle cost. The default export shape differs across v0/v1,
77
+ // hence the `any` cast. The literal module specifier is a string
78
+ // we resolve at runtime — TS sees no type info for it and would
79
+ // otherwise error TS2307 when jimp isn't on the host's path.
80
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
+ const dynImport = (s) =>
82
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
83
+ Function("s", "return import(s)")(s);
84
+ const mod = (await dynImport("jimp"));
85
+ const Jimp = (mod.default ?? mod.Jimp ?? mod);
86
+ cachedJimpCompressor = {
87
+ async compress(image, maxBytes) {
88
+ const original = Buffer.from(image.base64, "base64");
89
+ const originalBytes = original.byteLength;
90
+ if (originalBytes <= maxBytes) {
91
+ return { image, compressed: false, originalBytes, finalBytes: originalBytes };
92
+ }
93
+ let pic;
94
+ try {
95
+ pic = await Jimp.read(original);
96
+ }
97
+ catch {
98
+ // Unknown / corrupt format. Leave it alone; the policy gate
99
+ // will refuse and surface a meaningful message to the user.
100
+ return { image, compressed: false, originalBytes, finalBytes: originalBytes };
101
+ }
102
+ // Scale longest edge down to the target. We may still be over
103
+ // after one pass for very large source images, so loop with
104
+ // decreasing quality / dimension until under cap or we hit the
105
+ // floor.
106
+ const targets = [
107
+ { dim: IMAGE_TARGETS.targetMaxDimension, q: Math.round(IMAGE_TARGETS.jpegQuality * 100) },
108
+ { dim: 1280, q: 75 },
109
+ { dim: 1024, q: 65 },
110
+ { dim: 800, q: 55 },
111
+ ];
112
+ const mime = Jimp.MIME_JPEG ?? "image/jpeg";
113
+ let bestBuf = null;
114
+ for (const t of targets) {
115
+ const w = pic.bitmap?.width ?? t.dim;
116
+ const h = pic.bitmap?.height ?? t.dim;
117
+ const longest = Math.max(w, h);
118
+ // Only scale down — never up an already-small image.
119
+ if (longest > t.dim) {
120
+ if (w >= h) {
121
+ pic.resize(t.dim, Math.round((h / w) * t.dim));
122
+ }
123
+ else {
124
+ pic.resize(Math.round((w / h) * t.dim), t.dim);
125
+ }
126
+ }
127
+ pic.quality(t.q);
128
+ const buf = await pic.getBufferAsync(mime);
129
+ if (buf.byteLength <= maxBytes) {
130
+ bestBuf = buf;
131
+ break;
132
+ }
133
+ bestBuf = buf;
134
+ }
135
+ if (!bestBuf) {
136
+ return { image, compressed: false, originalBytes, finalBytes: originalBytes };
137
+ }
138
+ const finalBytes = bestBuf.byteLength;
139
+ const out = {
140
+ ...image,
141
+ base64: bestBuf.toString("base64"),
142
+ mime: "image/jpeg",
143
+ };
144
+ return {
145
+ image: out,
146
+ compressed: true,
147
+ originalBytes,
148
+ finalBytes,
149
+ };
150
+ },
151
+ };
152
+ }
153
+ catch {
154
+ cachedJimpCompressor = NOOP_COMPRESSOR;
155
+ }
156
+ return cachedJimpCompressor;
157
+ }
158
+ /**
159
+ * Try compressing every image in the batch so it fits under the
160
+ * single-image cap. Returns the (possibly transformed) batch plus a
161
+ * summary of what changed. Callers should hand the returned images
162
+ * back into {@link enforceImagePolicy} to confirm; this function
163
+ * doesn't itself decide whether the result is acceptable.
164
+ */
165
+ export async function tryCompressImages(images) {
166
+ if (images.length === 0)
167
+ return { images: [], anyCompressed: false };
168
+ const compressor = activeCompressor ?? (await resolveJimpCompressor());
169
+ if (compressor === NOOP_COMPRESSOR) {
170
+ return { images: images.slice(), anyCompressed: false };
171
+ }
172
+ const out = [];
173
+ let anyCompressed = false;
174
+ for (const img of images) {
175
+ const bytes = byteLengthFromBase64(img.base64);
176
+ if (bytes <= IMAGE_LIMITS.maxBytesPerImage) {
177
+ out.push(img);
178
+ continue;
179
+ }
180
+ const result = await compressor.compress(img, IMAGE_LIMITS.maxBytesPerImage);
181
+ out.push(result.image);
182
+ if (result.compressed)
183
+ anyCompressed = true;
184
+ }
185
+ return { images: out, anyCompressed };
186
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Engine-side image policy: a single source of truth for what counts as
3
+ * an "OK to ship to the model" attachment.
4
+ *
5
+ * Why this exists
6
+ * ---------------
7
+ * The desktop renderer happily takes a 4 MB screenshot, base64-encodes it,
8
+ * and ships it to the LLM. OpenAI-compatible providers stream the request
9
+ * body; a payload that fat plus a flaky link manifests as
10
+ * `OpenAI API error: Connection error.` with no useful classification,
11
+ * three retries deep. That bug is in our session log
12
+ * `s-mppk3ot5-02d35ca4`: textLen=4,364,933, promptTokens=1,091,232.
13
+ *
14
+ * The right fix is to keep the bytes small *before* they leave the host.
15
+ * But not every entry point has the same compressor available:
16
+ * - desktop renderer has <canvas> + Blob, no native deps
17
+ * - TUI runs in plain Node and has neither
18
+ * - MCP tools / future arena agents will need it too
19
+ *
20
+ * So this module owns:
21
+ * 1. The shared *thresholds* every host honors before sending to the LLM
22
+ * (`IMAGE_LIMITS`).
23
+ * 2. A `byteLengthFromBase64()` helper everyone uses to measure decoded
24
+ * payload size without actually decoding it.
25
+ * 3. An `enforceImagePolicy()` engine gate that runs *after* parse-task
26
+ * and *before* the message hits the provider. When a single image
27
+ * blows the limit, the gate refuses the turn with a friendly error
28
+ * and a hint telling the user what to do. The engine is the last
29
+ * place we can refuse cheaply — the next step is a $0.10 vision call
30
+ * over a flaky socket.
31
+ *
32
+ * Hosts (desktop, TUI) are encouraged to compress upstream so this gate
33
+ * never fires in practice. When it does fire, the user gets a clear
34
+ * message instead of "Connection error. Connection error. Connection
35
+ * error.".
36
+ *
37
+ * Pure + no I/O — safe to use from any caller.
38
+ */
39
+ import type { ParsedImage } from "./parse-task.js";
40
+ /**
41
+ * Hard limits the engine enforces. Soft hints (target sizes) live in
42
+ * `IMAGE_TARGETS` so hosts know what to aim for when they pre-compress.
43
+ *
44
+ * Rationale for each number:
45
+ * - `maxBytesPerImage`: 2 MB decoded. OpenAI's `gpt-4o` accepts up to
46
+ * 20 MB but charges by tile count; 2 MB ≈ a 2048×2048 PNG which is
47
+ * plenty for every UI screenshot. Above this we've measured the
48
+ * "Connection error" failure mode in practice.
49
+ * - `maxBytesPerTurn`: 6 MB total, regardless of count. The four-image
50
+ * attach is the typical worst case from the desktop UI, and 4× the
51
+ * per-image cap would blow past most providers' rate-limited request
52
+ * body sizes.
53
+ * - `maxImagesPerTurn`: 6 (matches the desktop renderer's UI limit, so
54
+ * a wider engine gate is just dead defense).
55
+ */
56
+ export declare const IMAGE_LIMITS: {
57
+ readonly maxBytesPerImage: number;
58
+ readonly maxBytesPerTurn: number;
59
+ readonly maxImagesPerTurn: 6;
60
+ };
61
+ /**
62
+ * Soft targets hosts use when pre-compressing. `targetMaxDimension` is
63
+ * the longest-edge pixel cap that *almost always* keeps a JPEG under
64
+ * `maxBytesPerImage`. Hosts re-encode at `jpegQuality` and only escalate
65
+ * the compression if the result is still over.
66
+ */
67
+ export declare const IMAGE_TARGETS: {
68
+ readonly targetMaxDimension: 2048;
69
+ readonly jpegQuality: 0.82;
70
+ };
71
+ /**
72
+ * Decode-free size estimate of a base64 string.
73
+ *
74
+ * Returns the count of bytes the base64 string would produce *after*
75
+ * decoding. Used everywhere we need to "weigh" an image without paying
76
+ * the cost of `Buffer.from(s, "base64")` allocation.
77
+ *
78
+ * - 4 base64 chars → 3 decoded bytes.
79
+ * - Trailing `=` padding subtracts from the byte count.
80
+ * - Tolerates whitespace and missing padding by working off `length`
81
+ * modulo 4 — the wire format strips whitespace via parse-task, so
82
+ * this only matters when an exotic caller hands us raw textarea text.
83
+ */
84
+ export declare function byteLengthFromBase64(b64: string): number;
85
+ /**
86
+ * Verdict returned by {@link enforceImagePolicy}. `ok: true` means the
87
+ * caller can proceed with the original images unchanged. `ok: false`
88
+ * carries a user-facing message + machine-readable reason so callers can
89
+ * decide whether to render an error card or refuse the turn outright.
90
+ */
91
+ export type ImagePolicyVerdict = {
92
+ ok: true;
93
+ } | {
94
+ ok: false;
95
+ /**
96
+ * Stable string the engine surfaces as the run's terminal reason.
97
+ * Distinct values so a future UI could pick different icons.
98
+ */
99
+ code: "image_too_large" | "images_total_too_large" | "too_many_images";
100
+ /** User-facing message — Chinese-friendly because both UIs are zh. */
101
+ message: string;
102
+ /** Optional fields the UI may use for finer-grained reporting. */
103
+ offender?: {
104
+ name: string;
105
+ mime: string;
106
+ bytes: number;
107
+ };
108
+ totals: {
109
+ imageCount: number;
110
+ totalBytes: number;
111
+ };
112
+ };
113
+ /**
114
+ * Run the per-turn image policy.
115
+ *
116
+ * Three failure modes, all surfaced with a Chinese-language hint that
117
+ * tells the user *what to do next*:
118
+ *
119
+ * 1. Per-image cap exceeded → name the file + the cap, suggest
120
+ * re-saving / cropping. (`code: "image_too_large"`)
121
+ * 2. Per-turn cumulative cap exceeded → total bytes + cap. The user
122
+ * likely attached too many screenshots; suggest removing some.
123
+ * (`code: "images_total_too_large"`)
124
+ * 3. Count cap exceeded → the desktop UI already caps at 6, so this
125
+ * mostly catches future-MCP / TUI batch paths. (`code: "too_many_images"`)
126
+ *
127
+ * The gate is **strict** — no silent truncation. The "Connection error"
128
+ * failure mode this exists to prevent was effectively a silent truncate
129
+ * (bytes lost mid-stream); a friendly refusal is strictly better.
130
+ */
131
+ /**
132
+ * Drop the images that exceed {@link IMAGE_LIMITS.maxBytesPerImage}
133
+ * and return a textual placeholder describing what was removed. The
134
+ * engine uses this to keep a poisoned image out of conversation
135
+ * history while still letting the rest of the turn proceed — Claude
136
+ * Code's "5MB brick session" failure mode is exactly the bug where
137
+ * a too-large image enters history and every subsequent request
138
+ * re-sends it (see docs/research-cc-vs-codex-image-handling.md §A).
139
+ *
140
+ * Returns the filtered image list and, when anything was dropped, a
141
+ * Chinese-language note suitable for prepending to the user text.
142
+ */
143
+ export interface DropOversizedResult {
144
+ /** Images that fit under the per-image cap (in original order). */
145
+ kept: ParsedImage[];
146
+ /** A human-readable note about what was removed, or "" if nothing was. */
147
+ placeholder: string;
148
+ /** Number of images removed. */
149
+ droppedCount: number;
150
+ }
151
+ export declare function dropOversizedImages(images: readonly ParsedImage[]): DropOversizedResult;
152
+ export declare function enforceImagePolicy(images: readonly ParsedImage[]): ImagePolicyVerdict;
153
+ /**
154
+ * Collect the workspace file paths of any attached images that came from a
155
+ * real file (the desktop composer's path-attach flow sets ParsedImage.name to
156
+ * the absolute path). Pasted screenshots whose name is a bare filename, or any
157
+ * name that doesn't resolve to an existing file, are excluded.
158
+ *
159
+ * Pure given an `exists` predicate + `resolve` joiner, so it's unit-testable
160
+ * without touching the real fs. The engine passes `existsSync` and a
161
+ * cwd-aware joiner; downstream this surfaces the paths to the model so tools
162
+ * like GenerateImage(referenceImages) can use them (the path the composer
163
+ * already knew was otherwise dropped on the way to the LLM).
164
+ */
165
+ export declare function collectAttachedImagePaths(images: ReadonlyArray<ParsedImage>, resolve: (name: string) => string, exists: (absPath: string) => boolean): string[];
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Engine-side image policy: a single source of truth for what counts as
3
+ * an "OK to ship to the model" attachment.
4
+ *
5
+ * Why this exists
6
+ * ---------------
7
+ * The desktop renderer happily takes a 4 MB screenshot, base64-encodes it,
8
+ * and ships it to the LLM. OpenAI-compatible providers stream the request
9
+ * body; a payload that fat plus a flaky link manifests as
10
+ * `OpenAI API error: Connection error.` with no useful classification,
11
+ * three retries deep. That bug is in our session log
12
+ * `s-mppk3ot5-02d35ca4`: textLen=4,364,933, promptTokens=1,091,232.
13
+ *
14
+ * The right fix is to keep the bytes small *before* they leave the host.
15
+ * But not every entry point has the same compressor available:
16
+ * - desktop renderer has <canvas> + Blob, no native deps
17
+ * - TUI runs in plain Node and has neither
18
+ * - MCP tools / future arena agents will need it too
19
+ *
20
+ * So this module owns:
21
+ * 1. The shared *thresholds* every host honors before sending to the LLM
22
+ * (`IMAGE_LIMITS`).
23
+ * 2. A `byteLengthFromBase64()` helper everyone uses to measure decoded
24
+ * payload size without actually decoding it.
25
+ * 3. An `enforceImagePolicy()` engine gate that runs *after* parse-task
26
+ * and *before* the message hits the provider. When a single image
27
+ * blows the limit, the gate refuses the turn with a friendly error
28
+ * and a hint telling the user what to do. The engine is the last
29
+ * place we can refuse cheaply — the next step is a $0.10 vision call
30
+ * over a flaky socket.
31
+ *
32
+ * Hosts (desktop, TUI) are encouraged to compress upstream so this gate
33
+ * never fires in practice. When it does fire, the user gets a clear
34
+ * message instead of "Connection error. Connection error. Connection
35
+ * error.".
36
+ *
37
+ * Pure + no I/O — safe to use from any caller.
38
+ */
39
+ /**
40
+ * Hard limits the engine enforces. Soft hints (target sizes) live in
41
+ * `IMAGE_TARGETS` so hosts know what to aim for when they pre-compress.
42
+ *
43
+ * Rationale for each number:
44
+ * - `maxBytesPerImage`: 2 MB decoded. OpenAI's `gpt-4o` accepts up to
45
+ * 20 MB but charges by tile count; 2 MB ≈ a 2048×2048 PNG which is
46
+ * plenty for every UI screenshot. Above this we've measured the
47
+ * "Connection error" failure mode in practice.
48
+ * - `maxBytesPerTurn`: 6 MB total, regardless of count. The four-image
49
+ * attach is the typical worst case from the desktop UI, and 4× the
50
+ * per-image cap would blow past most providers' rate-limited request
51
+ * body sizes.
52
+ * - `maxImagesPerTurn`: 6 (matches the desktop renderer's UI limit, so
53
+ * a wider engine gate is just dead defense).
54
+ */
55
+ export const IMAGE_LIMITS = {
56
+ maxBytesPerImage: 2 * 1024 * 1024,
57
+ maxBytesPerTurn: 6 * 1024 * 1024,
58
+ maxImagesPerTurn: 6,
59
+ };
60
+ /**
61
+ * Soft targets hosts use when pre-compressing. `targetMaxDimension` is
62
+ * the longest-edge pixel cap that *almost always* keeps a JPEG under
63
+ * `maxBytesPerImage`. Hosts re-encode at `jpegQuality` and only escalate
64
+ * the compression if the result is still over.
65
+ */
66
+ export const IMAGE_TARGETS = {
67
+ targetMaxDimension: 2048,
68
+ jpegQuality: 0.82,
69
+ };
70
+ /**
71
+ * Decode-free size estimate of a base64 string.
72
+ *
73
+ * Returns the count of bytes the base64 string would produce *after*
74
+ * decoding. Used everywhere we need to "weigh" an image without paying
75
+ * the cost of `Buffer.from(s, "base64")` allocation.
76
+ *
77
+ * - 4 base64 chars → 3 decoded bytes.
78
+ * - Trailing `=` padding subtracts from the byte count.
79
+ * - Tolerates whitespace and missing padding by working off `length`
80
+ * modulo 4 — the wire format strips whitespace via parse-task, so
81
+ * this only matters when an exotic caller hands us raw textarea text.
82
+ */
83
+ export function byteLengthFromBase64(b64) {
84
+ if (!b64)
85
+ return 0;
86
+ // Strip whitespace defensively; the parser already does this, but other
87
+ // callers (logging stubs, MCP image blocks) might not.
88
+ const clean = b64.replace(/\s+/g, "");
89
+ const padding = clean.endsWith("==") ? 2 : clean.endsWith("=") ? 1 : 0;
90
+ return Math.floor((clean.length * 3) / 4) - padding;
91
+ }
92
+ function fmtMB(bytes) {
93
+ return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
94
+ }
95
+ export function dropOversizedImages(images) {
96
+ const kept = [];
97
+ const dropped = [];
98
+ for (const img of images) {
99
+ const bytes = byteLengthFromBase64(img.base64);
100
+ if (bytes > IMAGE_LIMITS.maxBytesPerImage) {
101
+ dropped.push({ name: img.name || "(未命名)", bytes });
102
+ }
103
+ else {
104
+ kept.push(img);
105
+ }
106
+ }
107
+ if (dropped.length === 0) {
108
+ return { kept, placeholder: "", droppedCount: 0 };
109
+ }
110
+ const list = dropped
111
+ .map((d) => `「${d.name}」(~${fmtMB(d.bytes)})`)
112
+ .join("、");
113
+ const placeholder = `[已自动跳过 ${dropped.length} 张超大图片:${list};` +
114
+ `单图上限 ${fmtMB(IMAGE_LIMITS.maxBytesPerImage)}。` +
115
+ `图片未进入对话历史,本轮其余内容继续。]`;
116
+ return { kept, placeholder, droppedCount: dropped.length };
117
+ }
118
+ export function enforceImagePolicy(images) {
119
+ if (images.length === 0)
120
+ return { ok: true };
121
+ if (images.length > IMAGE_LIMITS.maxImagesPerTurn) {
122
+ return {
123
+ ok: false,
124
+ code: "too_many_images",
125
+ message: `一次最多附 ${IMAGE_LIMITS.maxImagesPerTurn} 张图片,` +
126
+ `本次有 ${images.length} 张。请删掉一些再发。`,
127
+ totals: {
128
+ imageCount: images.length,
129
+ totalBytes: images.reduce((s, i) => s + byteLengthFromBase64(i.base64), 0),
130
+ },
131
+ };
132
+ }
133
+ let totalBytes = 0;
134
+ for (const img of images) {
135
+ const bytes = byteLengthFromBase64(img.base64);
136
+ if (bytes > IMAGE_LIMITS.maxBytesPerImage) {
137
+ return {
138
+ ok: false,
139
+ code: "image_too_large",
140
+ message: `图片「${img.name || "(未命名)"}」解码后约 ${fmtMB(bytes)},` +
141
+ `超过单图上限 ${fmtMB(IMAGE_LIMITS.maxBytesPerImage)}。` +
142
+ `请先截图压缩或保存为 JPEG(最长边 ≤ ${IMAGE_TARGETS.targetMaxDimension}px)再发。`,
143
+ offender: { name: img.name, mime: img.mime, bytes },
144
+ totals: {
145
+ imageCount: images.length,
146
+ totalBytes: totalBytes + bytes,
147
+ },
148
+ };
149
+ }
150
+ totalBytes += bytes;
151
+ }
152
+ if (totalBytes > IMAGE_LIMITS.maxBytesPerTurn) {
153
+ return {
154
+ ok: false,
155
+ code: "images_total_too_large",
156
+ message: `本次附图合计约 ${fmtMB(totalBytes)},超过每轮上限 ${fmtMB(IMAGE_LIMITS.maxBytesPerTurn)}。` +
157
+ `请删掉一些图片,或先把图片压缩后再发。`,
158
+ totals: {
159
+ imageCount: images.length,
160
+ totalBytes,
161
+ },
162
+ };
163
+ }
164
+ return { ok: true };
165
+ }
166
+ /**
167
+ * Collect the workspace file paths of any attached images that came from a
168
+ * real file (the desktop composer's path-attach flow sets ParsedImage.name to
169
+ * the absolute path). Pasted screenshots whose name is a bare filename, or any
170
+ * name that doesn't resolve to an existing file, are excluded.
171
+ *
172
+ * Pure given an `exists` predicate + `resolve` joiner, so it's unit-testable
173
+ * without touching the real fs. The engine passes `existsSync` and a
174
+ * cwd-aware joiner; downstream this surfaces the paths to the model so tools
175
+ * like GenerateImage(referenceImages) can use them (the path the composer
176
+ * already knew was otherwise dropped on the way to the LLM).
177
+ */
178
+ export function collectAttachedImagePaths(images, resolve, exists) {
179
+ const out = [];
180
+ for (const img of images) {
181
+ const name = img.name?.trim();
182
+ if (!name)
183
+ continue;
184
+ const abs = resolve(name);
185
+ if (exists(abs))
186
+ out.push(abs);
187
+ }
188
+ return out;
189
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Bridge settings.modelConnections[] (the unified instance store) into
3
+ * ModelPool entries, so the engine sends requests using the new catalog-driven
4
+ * model selection. Pure: instances + catalog → ModelEntry[]. apiKeyRef is
5
+ * dereferenced via resolveInstance; protocol/baseUrl/token limits come from the
6
+ * resolved catalog entry + preset.
7
+ * See docs/superpowers/specs/2026-06-15-unified-model-catalog-design.md §6.
8
+ */
9
+ import { type ModelInstance, type Credential } from "../model-catalog/resolve.js";
10
+ import type { CatalogEntry } from "../model-catalog/index.js";
11
+ import type { ModelEntry } from "../llm/model-pool.js";
12
+ export type { ModelInstance, Credential } from "../model-catalog/resolve.js";
13
+ /**
14
+ * Convert text model connections into ModelPool register entries. Non-text
15
+ * instances and ones whose catalogId doesn't resolve are skipped.
16
+ */
17
+ export declare function modelEntriesFromConnections(connections: ModelInstance[], credentials: Credential[], catalog: CatalogEntry[]): ModelEntry[];
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Bridge settings.modelConnections[] (the unified instance store) into
3
+ * ModelPool entries, so the engine sends requests using the new catalog-driven
4
+ * model selection. Pure: instances + catalog → ModelEntry[]. apiKeyRef is
5
+ * dereferenced via resolveInstance; protocol/baseUrl/token limits come from the
6
+ * resolved catalog entry + preset.
7
+ * See docs/superpowers/specs/2026-06-15-unified-model-catalog-design.md §6.
8
+ */
9
+ import { resolveInstance } from "../model-catalog/resolve.js";
10
+ import { applyParams } from "../model-catalog/params.js";
11
+ /** Map a catalog entry's protocol to the ModelPool `provider` (LLM client). */
12
+ function clientProvider(entry) {
13
+ return entry.protocol === "anthropic-style" ? "anthropic" : "openai";
14
+ }
15
+ /**
16
+ * Map a connection's `paramValues.reasoning` to the engine's ReasoningSetting,
17
+ * so the new param store flows through the existing reasoning request pipeline
18
+ * (no new request-layer plumbing). enum→effort, number→budget, boolean→on/off.
19
+ */
20
+ function reasoningFromParamValues(paramValues) {
21
+ const v = paramValues?.reasoning;
22
+ if (typeof v === "string") {
23
+ return { mode: "effort", effort: v };
24
+ }
25
+ if (typeof v === "number")
26
+ return { mode: "budget", budgetTokens: v };
27
+ if (typeof v === "boolean")
28
+ return v ? { mode: "on" } : { mode: "off" };
29
+ return undefined;
30
+ }
31
+ /**
32
+ * Convert text model connections into ModelPool register entries. Non-text
33
+ * instances and ones whose catalogId doesn't resolve are skipped.
34
+ */
35
+ export function modelEntriesFromConnections(connections, credentials, catalog) {
36
+ const out = [];
37
+ for (const inst of connections) {
38
+ if (inst.tag !== "text")
39
+ continue;
40
+ const resolved = resolveInstance(inst, credentials, catalog);
41
+ if (!resolved)
42
+ continue;
43
+ const { entry, preset } = resolved;
44
+ const reasoning = reasoningFromParamValues(inst.paramValues);
45
+ // Generic param passthrough: map the connection's paramValues to request-body
46
+ // fields via each ParamSpec's wire.field. Exclude `reasoning` — it rides the
47
+ // dedicated entry.reasoning path (per-model dynamic translation in the client);
48
+ // emitting it here too would double-send it.
49
+ const passthroughParams = (preset?.params ?? []).filter((p) => p.name !== "reasoning");
50
+ const extraBody = applyParams(inst.paramValues ?? {}, passthroughParams);
51
+ const e = {
52
+ key: inst.id,
53
+ provider: clientProvider(entry),
54
+ model: resolved.model,
55
+ baseUrl: resolved.baseUrl,
56
+ needsKey: resolved.needsKey,
57
+ ...(resolved.apiKey !== undefined ? { apiKey: resolved.apiKey } : {}),
58
+ ...(preset?.maxContextTokens !== undefined ? { maxContextTokens: preset.maxContextTokens } : {}),
59
+ ...(preset?.maxOutputTokens !== undefined ? { maxOutputTokens: preset.maxOutputTokens } : {}),
60
+ ...(reasoning !== undefined ? { reasoning } : {}),
61
+ ...(Object.keys(extraBody).length > 0 ? { extraBody } : {}),
62
+ };
63
+ out.push(e);
64
+ }
65
+ return out;
66
+ }
@@ -4,6 +4,16 @@
4
4
  import type { LLMClientBase } from "../llm/client-base.js";
5
5
  import type { Message, ToolDefinition, LLMResponse, StreamCallback } from "../types.js";
6
6
  import { Transcript } from "../session/transcript.js";
7
+ /**
8
+ * Prompt-cache hit rate for one request, as CC computes it:
9
+ * cacheRead / (cacheRead + cacheCreation + uncachedInput)
10
+ * where uncachedInput = promptTokens − cacheRead − cacheCreation (promptTokens
11
+ * already includes the cached portion). Returns undefined when the provider
12
+ * reported no cache info at all, so `llm.request` only carries the field when
13
+ * it's meaningful. Makes hit-rate observable in logs — the prerequisite for
14
+ * any caching tuning (docs/todo/prompt-cache-optimization.md §四 step 1).
15
+ */
16
+ export declare function cacheHitRate(usage: LLMResponse["usage"]): number | undefined;
7
17
  export declare class ModelFacade {
8
18
  private readonly client;
9
19
  private readonly transcript;