@cjhyy/code-shell-core 0.5.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/dist/agent/coordinator.d.ts +49 -0
  4. package/dist/agent/coordinator.js +77 -0
  5. package/dist/arena/arena.d.ts +43 -0
  6. package/dist/arena/arena.js +334 -0
  7. package/dist/arena/context/context-tools.d.ts +16 -0
  8. package/dist/arena/context/context-tools.js +231 -0
  9. package/dist/arena/detect-mode.d.ts +20 -0
  10. package/dist/arena/detect-mode.js +78 -0
  11. package/dist/arena/digest-builder.d.ts +25 -0
  12. package/dist/arena/digest-builder.js +120 -0
  13. package/dist/arena/index.d.ts +29 -0
  14. package/dist/arena/index.js +29 -0
  15. package/dist/arena/iterate/convergence.d.ts +25 -0
  16. package/dist/arena/iterate/convergence.js +103 -0
  17. package/dist/arena/iterate/formats/index.d.ts +22 -0
  18. package/dist/arena/iterate/formats/index.js +283 -0
  19. package/dist/arena/iterate/index.d.ts +11 -0
  20. package/dist/arena/iterate/index.js +9 -0
  21. package/dist/arena/iterate/iterative-arena.d.ts +23 -0
  22. package/dist/arena/iterate/iterative-arena.js +237 -0
  23. package/dist/arena/iterate/parse.d.ts +42 -0
  24. package/dist/arena/iterate/parse.js +123 -0
  25. package/dist/arena/iterate/phases/argue.d.ts +22 -0
  26. package/dist/arena/iterate/phases/argue.js +159 -0
  27. package/dist/arena/iterate/phases/revise.d.ts +16 -0
  28. package/dist/arena/iterate/phases/revise.js +62 -0
  29. package/dist/arena/iterate/phases/tournament.d.ts +34 -0
  30. package/dist/arena/iterate/phases/tournament.js +113 -0
  31. package/dist/arena/iterate/tools/web-tools.d.ts +13 -0
  32. package/dist/arena/iterate/tools/web-tools.js +54 -0
  33. package/dist/arena/iterate/types.d.ts +152 -0
  34. package/dist/arena/iterate/types.js +8 -0
  35. package/dist/arena/ledger.d.ts +47 -0
  36. package/dist/arena/ledger.js +151 -0
  37. package/dist/arena/lenses/architecture.d.ts +5 -0
  38. package/dist/arena/lenses/architecture.js +22 -0
  39. package/dist/arena/lenses/engineering.d.ts +5 -0
  40. package/dist/arena/lenses/engineering.js +22 -0
  41. package/dist/arena/lenses/general.d.ts +5 -0
  42. package/dist/arena/lenses/general.js +20 -0
  43. package/dist/arena/lenses/index.d.ts +16 -0
  44. package/dist/arena/lenses/index.js +47 -0
  45. package/dist/arena/lenses/product.d.ts +5 -0
  46. package/dist/arena/lenses/product.js +22 -0
  47. package/dist/arena/model-presets.d.ts +23 -0
  48. package/dist/arena/model-presets.js +44 -0
  49. package/dist/arena/phases/adjudication.d.ts +24 -0
  50. package/dist/arena/phases/adjudication.js +144 -0
  51. package/dist/arena/phases/build-consensus.d.ts +29 -0
  52. package/dist/arena/phases/build-consensus.js +86 -0
  53. package/dist/arena/phases/claim-registry.d.ts +26 -0
  54. package/dist/arena/phases/claim-registry.js +60 -0
  55. package/dist/arena/phases/cross-review.d.ts +45 -0
  56. package/dist/arena/phases/cross-review.js +224 -0
  57. package/dist/arena/phases/debate-rounds.d.ts +27 -0
  58. package/dist/arena/phases/debate-rounds.js +162 -0
  59. package/dist/arena/phases/participant-research.d.ts +38 -0
  60. package/dist/arena/phases/participant-research.js +317 -0
  61. package/dist/arena/phases/planning-detail-expansion.d.ts +38 -0
  62. package/dist/arena/phases/planning-detail-expansion.js +121 -0
  63. package/dist/arena/planner.d.ts +27 -0
  64. package/dist/arena/planner.js +312 -0
  65. package/dist/arena/providers/docs.d.ts +6 -0
  66. package/dist/arena/providers/docs.js +108 -0
  67. package/dist/arena/providers/git.d.ts +8 -0
  68. package/dist/arena/providers/git.js +174 -0
  69. package/dist/arena/providers/index.d.ts +32 -0
  70. package/dist/arena/providers/index.js +132 -0
  71. package/dist/arena/providers/none.d.ts +7 -0
  72. package/dist/arena/providers/none.js +11 -0
  73. package/dist/arena/providers/repo.d.ts +6 -0
  74. package/dist/arena/providers/repo.js +255 -0
  75. package/dist/arena/render/session.d.ts +17 -0
  76. package/dist/arena/render/session.js +190 -0
  77. package/dist/arena/render/terminal.d.ts +34 -0
  78. package/dist/arena/render/terminal.js +286 -0
  79. package/dist/arena/strategies/discussion.d.ts +25 -0
  80. package/dist/arena/strategies/discussion.js +143 -0
  81. package/dist/arena/strategies/index.d.ts +15 -0
  82. package/dist/arena/strategies/index.js +28 -0
  83. package/dist/arena/strategies/language-wrapper.d.ts +17 -0
  84. package/dist/arena/strategies/language-wrapper.js +102 -0
  85. package/dist/arena/strategies/lens-wrapper.d.ts +16 -0
  86. package/dist/arena/strategies/lens-wrapper.js +236 -0
  87. package/dist/arena/strategies/planning.d.ts +30 -0
  88. package/dist/arena/strategies/planning.js +225 -0
  89. package/dist/arena/strategies/review.d.ts +26 -0
  90. package/dist/arena/strategies/review.js +168 -0
  91. package/dist/arena/strategies/utils.d.ts +39 -0
  92. package/dist/arena/strategies/utils.js +647 -0
  93. package/dist/arena/tools/selector.d.ts +17 -0
  94. package/dist/arena/tools/selector.js +61 -0
  95. package/dist/arena/transitions.d.ts +48 -0
  96. package/dist/arena/transitions.js +92 -0
  97. package/dist/arena/types.d.ts +508 -0
  98. package/dist/arena/types.js +27 -0
  99. package/dist/cli/agent-server-stdio.d.ts +32 -0
  100. package/dist/cli/agent-server-stdio.js +116 -0
  101. package/dist/colorizer.d.ts +23 -0
  102. package/dist/colorizer.js +12 -0
  103. package/dist/context/compaction.d.ts +116 -0
  104. package/dist/context/compaction.js +534 -0
  105. package/dist/context/manager.d.ts +145 -0
  106. package/dist/context/manager.js +423 -0
  107. package/dist/context/token-counter.d.ts +27 -0
  108. package/dist/context/token-counter.js +91 -0
  109. package/dist/context/tool-result-storage.d.ts +96 -0
  110. package/dist/context/tool-result-storage.js +296 -0
  111. package/dist/cost-tracker.d.ts +64 -0
  112. package/dist/cost-tracker.js +314 -0
  113. package/dist/cron/scheduler.d.ts +34 -0
  114. package/dist/cron/scheduler.js +115 -0
  115. package/dist/data/deepseek-models.json +46 -0
  116. package/dist/data/gemini-models.json +67 -0
  117. package/dist/data/openai-models.json +175 -0
  118. package/dist/data/openrouter-models.d.ts +35 -0
  119. package/dist/data/openrouter-models.js +36 -0
  120. package/dist/data/openrouter-models.json +4626 -0
  121. package/dist/data/openrouter-sync.d.ts +16 -0
  122. package/dist/data/openrouter-sync.js +53 -0
  123. package/dist/data/static-catalogs.d.ts +25 -0
  124. package/dist/data/static-catalogs.js +26 -0
  125. package/dist/data/zai-models.json +56 -0
  126. package/dist/engine/cost-store.d.ts +22 -0
  127. package/dist/engine/cost-store.js +15 -0
  128. package/dist/engine/engine.d.ts +295 -0
  129. package/dist/engine/engine.js +1467 -0
  130. package/dist/engine/model-facade.d.ts +24 -0
  131. package/dist/engine/model-facade.js +194 -0
  132. package/dist/engine/parse-task.d.ts +59 -0
  133. package/dist/engine/parse-task.js +135 -0
  134. package/dist/engine/patch-orphaned-tools.d.ts +52 -0
  135. package/dist/engine/patch-orphaned-tools.js +95 -0
  136. package/dist/engine/query.d.ts +50 -0
  137. package/dist/engine/query.js +107 -0
  138. package/dist/engine/runtime.d.ts +50 -0
  139. package/dist/engine/runtime.js +59 -0
  140. package/dist/engine/streaming-tool-queue.d.ts +34 -0
  141. package/dist/engine/streaming-tool-queue.js +61 -0
  142. package/dist/engine/token-budget.d.ts +22 -0
  143. package/dist/engine/token-budget.js +40 -0
  144. package/dist/engine/tool-summary.d.ts +13 -0
  145. package/dist/engine/tool-summary.js +35 -0
  146. package/dist/engine/turn-loop.d.ts +122 -0
  147. package/dist/engine/turn-loop.js +602 -0
  148. package/dist/engine/turn-state.d.ts +20 -0
  149. package/dist/engine/turn-state.js +17 -0
  150. package/dist/exceptions.d.ts +61 -0
  151. package/dist/exceptions.js +116 -0
  152. package/dist/git/utils.d.ts +35 -0
  153. package/dist/git/utils.js +98 -0
  154. package/dist/git/worktree.d.ts +36 -0
  155. package/dist/git/worktree.js +139 -0
  156. package/dist/hooks/events.d.ts +114 -0
  157. package/dist/hooks/events.js +4 -0
  158. package/dist/hooks/inject.d.ts +19 -0
  159. package/dist/hooks/inject.js +29 -0
  160. package/dist/hooks/registry.d.ts +15 -0
  161. package/dist/hooks/registry.js +84 -0
  162. package/dist/hooks/shell-runner.d.ts +45 -0
  163. package/dist/hooks/shell-runner.js +173 -0
  164. package/dist/index.d.ts +117 -0
  165. package/dist/index.js +145 -0
  166. package/dist/llm/api-key-sanitize.d.ts +22 -0
  167. package/dist/llm/api-key-sanitize.js +81 -0
  168. package/dist/llm/capabilities/index.d.ts +20 -0
  169. package/dist/llm/capabilities/index.js +39 -0
  170. package/dist/llm/capabilities/rules.d.ts +26 -0
  171. package/dist/llm/capabilities/rules.js +215 -0
  172. package/dist/llm/capabilities/types.d.ts +114 -0
  173. package/dist/llm/capabilities/types.js +24 -0
  174. package/dist/llm/client-base.d.ts +29 -0
  175. package/dist/llm/client-base.js +137 -0
  176. package/dist/llm/client-factory.d.ts +10 -0
  177. package/dist/llm/client-factory.js +29 -0
  178. package/dist/llm/model-cache.d.ts +21 -0
  179. package/dist/llm/model-cache.js +46 -0
  180. package/dist/llm/model-fetcher.d.ts +29 -0
  181. package/dist/llm/model-fetcher.js +282 -0
  182. package/dist/llm/model-pool.d.ts +95 -0
  183. package/dist/llm/model-pool.js +246 -0
  184. package/dist/llm/provider-catalog.d.ts +32 -0
  185. package/dist/llm/provider-catalog.js +50 -0
  186. package/dist/llm/provider-kinds.d.ts +21 -0
  187. package/dist/llm/provider-kinds.js +132 -0
  188. package/dist/llm/providers/anthropic.d.ts +19 -0
  189. package/dist/llm/providers/anthropic.js +267 -0
  190. package/dist/llm/providers/openai.d.ts +64 -0
  191. package/dist/llm/providers/openai.js +606 -0
  192. package/dist/llm/retry.d.ts +12 -0
  193. package/dist/llm/retry.js +17 -0
  194. package/dist/llm/stream-watchdog.d.ts +42 -0
  195. package/dist/llm/stream-watchdog.js +70 -0
  196. package/dist/llm/token-counter.d.ts +17 -0
  197. package/dist/llm/token-counter.js +36 -0
  198. package/dist/llm/types.d.ts +37 -0
  199. package/dist/llm/types.js +4 -0
  200. package/dist/logging/logger.d.ts +109 -0
  201. package/dist/logging/logger.js +390 -0
  202. package/dist/logging/sanitize-messages.d.ts +42 -0
  203. package/dist/logging/sanitize-messages.js +150 -0
  204. package/dist/logging/session-recorder.d.ts +90 -0
  205. package/dist/logging/session-recorder.js +304 -0
  206. package/dist/lsp/client.d.ts +41 -0
  207. package/dist/lsp/client.js +166 -0
  208. package/dist/lsp/manager.d.ts +40 -0
  209. package/dist/lsp/manager.js +124 -0
  210. package/dist/lsp/servers.d.ts +16 -0
  211. package/dist/lsp/servers.js +60 -0
  212. package/dist/migrate-models.d.ts +45 -0
  213. package/dist/migrate-models.js +179 -0
  214. package/dist/onboarding.d.ts +189 -0
  215. package/dist/onboarding.js +625 -0
  216. package/dist/plugins/gitOps.d.ts +32 -0
  217. package/dist/plugins/gitOps.js +62 -0
  218. package/dist/plugins/installedPlugins.d.ts +15 -0
  219. package/dist/plugins/installedPlugins.js +56 -0
  220. package/dist/plugins/knownMarketplaces.d.ts +10 -0
  221. package/dist/plugins/knownMarketplaces.js +46 -0
  222. package/dist/plugins/loadPluginHooks.d.ts +52 -0
  223. package/dist/plugins/loadPluginHooks.js +162 -0
  224. package/dist/plugins/marketplaceManager.d.ts +49 -0
  225. package/dist/plugins/marketplaceManager.js +142 -0
  226. package/dist/plugins/parseMarketplaceInput.d.ts +16 -0
  227. package/dist/plugins/parseMarketplaceInput.js +73 -0
  228. package/dist/plugins/pluginCommandHook.d.ts +54 -0
  229. package/dist/plugins/pluginCommandHook.js +180 -0
  230. package/dist/plugins/pluginCommandsLoader.d.ts +25 -0
  231. package/dist/plugins/pluginCommandsLoader.js +114 -0
  232. package/dist/plugins/pluginInstaller.d.ts +36 -0
  233. package/dist/plugins/pluginInstaller.js +228 -0
  234. package/dist/plugins/schemas.d.ts +9 -0
  235. package/dist/plugins/schemas.js +136 -0
  236. package/dist/plugins/types.d.ts +75 -0
  237. package/dist/plugins/types.js +7 -0
  238. package/dist/plugins/varRewrite.d.ts +42 -0
  239. package/dist/plugins/varRewrite.js +129 -0
  240. package/dist/preset/index.d.ts +60 -0
  241. package/dist/preset/index.js +159 -0
  242. package/dist/product/define.d.ts +60 -0
  243. package/dist/product/define.js +123 -0
  244. package/dist/product/index.d.ts +5 -0
  245. package/dist/product/index.js +4 -0
  246. package/dist/product/types.d.ts +111 -0
  247. package/dist/product/types.js +21 -0
  248. package/dist/prompt/composer.d.ts +49 -0
  249. package/dist/prompt/composer.js +168 -0
  250. package/dist/prompt/instruction-scanner.d.ts +54 -0
  251. package/dist/prompt/instruction-scanner.js +187 -0
  252. package/dist/prompt/section-cache.d.ts +15 -0
  253. package/dist/prompt/section-cache.js +31 -0
  254. package/dist/prompt/section-loader.d.ts +26 -0
  255. package/dist/prompt/section-loader.js +53 -0
  256. package/dist/prompt/sections/base.md +35 -0
  257. package/dist/prompt/sections/coding.md +31 -0
  258. package/dist/prompt/sections/orchestration.md +16 -0
  259. package/dist/prompt/sections/tone.md +9 -0
  260. package/dist/protocol/chat-session-manager.d.ts +33 -0
  261. package/dist/protocol/chat-session-manager.js +65 -0
  262. package/dist/protocol/chat-session.d.ts +49 -0
  263. package/dist/protocol/chat-session.js +86 -0
  264. package/dist/protocol/client.d.ts +104 -0
  265. package/dist/protocol/client.js +260 -0
  266. package/dist/protocol/factories.d.ts +93 -0
  267. package/dist/protocol/factories.js +64 -0
  268. package/dist/protocol/helpers.d.ts +42 -0
  269. package/dist/protocol/helpers.js +55 -0
  270. package/dist/protocol/index.d.ts +4 -0
  271. package/dist/protocol/index.js +4 -0
  272. package/dist/protocol/server.d.ts +80 -0
  273. package/dist/protocol/server.js +855 -0
  274. package/dist/protocol/transport.d.ts +37 -0
  275. package/dist/protocol/transport.js +85 -0
  276. package/dist/protocol/types.d.ts +221 -0
  277. package/dist/protocol/types.js +61 -0
  278. package/dist/remote/bridge.d.ts +37 -0
  279. package/dist/remote/bridge.js +103 -0
  280. package/dist/run/ArtifactTracker.d.ts +38 -0
  281. package/dist/run/ArtifactTracker.js +132 -0
  282. package/dist/run/CheckpointWriter.d.ts +53 -0
  283. package/dist/run/CheckpointWriter.js +135 -0
  284. package/dist/run/EngineRunner.d.ts +72 -0
  285. package/dist/run/EngineRunner.js +119 -0
  286. package/dist/run/Evaluator.d.ts +56 -0
  287. package/dist/run/Evaluator.js +62 -0
  288. package/dist/run/FileRunStore.d.ts +39 -0
  289. package/dist/run/FileRunStore.js +176 -0
  290. package/dist/run/Heartbeat.d.ts +54 -0
  291. package/dist/run/Heartbeat.js +123 -0
  292. package/dist/run/RunApprovalBackend.d.ts +53 -0
  293. package/dist/run/RunApprovalBackend.js +85 -0
  294. package/dist/run/RunLock.d.ts +40 -0
  295. package/dist/run/RunLock.js +98 -0
  296. package/dist/run/RunManager.d.ts +82 -0
  297. package/dist/run/RunManager.js +587 -0
  298. package/dist/run/RunQueue.d.ts +27 -0
  299. package/dist/run/RunQueue.js +73 -0
  300. package/dist/run/RunStore.d.ts +25 -0
  301. package/dist/run/RunStore.js +9 -0
  302. package/dist/run/factory.d.ts +63 -0
  303. package/dist/run/factory.js +51 -0
  304. package/dist/run/index.d.ts +17 -0
  305. package/dist/run/index.js +23 -0
  306. package/dist/run/types.d.ts +136 -0
  307. package/dist/run/types.js +28 -0
  308. package/dist/runtime/safe-spawn.d.ts +118 -0
  309. package/dist/runtime/safe-spawn.js +268 -0
  310. package/dist/services/analytics.d.ts +29 -0
  311. package/dist/services/analytics.js +84 -0
  312. package/dist/services/auto-dream.d.ts +49 -0
  313. package/dist/services/auto-dream.js +124 -0
  314. package/dist/services/diagnostics.d.ts +41 -0
  315. package/dist/services/diagnostics.js +99 -0
  316. package/dist/services/extract-memories.d.ts +31 -0
  317. package/dist/services/extract-memories.js +71 -0
  318. package/dist/services/index.d.ts +11 -0
  319. package/dist/services/index.js +17 -0
  320. package/dist/services/memory-orchestrator.d.ts +60 -0
  321. package/dist/services/memory-orchestrator.js +133 -0
  322. package/dist/services/notifier.d.ts +25 -0
  323. package/dist/services/notifier.js +69 -0
  324. package/dist/services/oauth.d.ts +27 -0
  325. package/dist/services/oauth.js +153 -0
  326. package/dist/services/session-memory.d.ts +37 -0
  327. package/dist/services/session-memory.js +81 -0
  328. package/dist/session/file-history.d.ts +41 -0
  329. package/dist/session/file-history.js +115 -0
  330. package/dist/session/memory.d.ts +104 -0
  331. package/dist/session/memory.js +310 -0
  332. package/dist/session/session-manager.d.ts +41 -0
  333. package/dist/session/session-manager.js +261 -0
  334. package/dist/session/transcript.d.ts +39 -0
  335. package/dist/session/transcript.js +186 -0
  336. package/dist/settings/manager.d.ts +36 -0
  337. package/dist/settings/manager.js +187 -0
  338. package/dist/settings/schema.d.ts +1219 -0
  339. package/dist/settings/schema.js +246 -0
  340. package/dist/skills/frontmatter.d.ts +13 -0
  341. package/dist/skills/frontmatter.js +70 -0
  342. package/dist/skills/index.d.ts +7 -0
  343. package/dist/skills/index.js +6 -0
  344. package/dist/skills/scanner.d.ts +31 -0
  345. package/dist/skills/scanner.js +171 -0
  346. package/dist/state.d.ts +160 -0
  347. package/dist/state.js +267 -0
  348. package/dist/tool-system/builtin/agent-notifications.d.ts +84 -0
  349. package/dist/tool-system/builtin/agent-notifications.js +197 -0
  350. package/dist/tool-system/builtin/agent-registry.d.ts +67 -0
  351. package/dist/tool-system/builtin/agent-registry.js +126 -0
  352. package/dist/tool-system/builtin/agent-transcript-translator.d.ts +22 -0
  353. package/dist/tool-system/builtin/agent-transcript-translator.js +160 -0
  354. package/dist/tool-system/builtin/agent.d.ts +16 -0
  355. package/dist/tool-system/builtin/agent.js +364 -0
  356. package/dist/tool-system/builtin/apply-patch/applier.d.ts +26 -0
  357. package/dist/tool-system/builtin/apply-patch/applier.js +250 -0
  358. package/dist/tool-system/builtin/apply-patch/index.d.ts +20 -0
  359. package/dist/tool-system/builtin/apply-patch/index.js +101 -0
  360. package/dist/tool-system/builtin/apply-patch/parser.d.ts +17 -0
  361. package/dist/tool-system/builtin/apply-patch/parser.js +212 -0
  362. package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +18 -0
  363. package/dist/tool-system/builtin/apply-patch/seek-sequence.js +123 -0
  364. package/dist/tool-system/builtin/apply-patch/types.d.ts +49 -0
  365. package/dist/tool-system/builtin/apply-patch/types.js +13 -0
  366. package/dist/tool-system/builtin/arena.d.ts +31 -0
  367. package/dist/tool-system/builtin/arena.js +416 -0
  368. package/dist/tool-system/builtin/ask-user.d.ts +20 -0
  369. package/dist/tool-system/builtin/ask-user.js +99 -0
  370. package/dist/tool-system/builtin/bash.d.ts +21 -0
  371. package/dist/tool-system/builtin/bash.js +149 -0
  372. package/dist/tool-system/builtin/brief.d.ts +6 -0
  373. package/dist/tool-system/builtin/brief.js +41 -0
  374. package/dist/tool-system/builtin/config.d.ts +6 -0
  375. package/dist/tool-system/builtin/config.js +67 -0
  376. package/dist/tool-system/builtin/cron.d.ts +10 -0
  377. package/dist/tool-system/builtin/cron.js +61 -0
  378. package/dist/tool-system/builtin/edit.d.ts +6 -0
  379. package/dist/tool-system/builtin/edit.js +100 -0
  380. package/dist/tool-system/builtin/file-cache.d.ts +11 -0
  381. package/dist/tool-system/builtin/file-cache.js +39 -0
  382. package/dist/tool-system/builtin/glob.d.ts +7 -0
  383. package/dist/tool-system/builtin/glob.js +76 -0
  384. package/dist/tool-system/builtin/grep.d.ts +7 -0
  385. package/dist/tool-system/builtin/grep.js +150 -0
  386. package/dist/tool-system/builtin/index.d.ts +20 -0
  387. package/dist/tool-system/builtin/index.js +449 -0
  388. package/dist/tool-system/builtin/lsp.d.ts +6 -0
  389. package/dist/tool-system/builtin/lsp.js +141 -0
  390. package/dist/tool-system/builtin/mcp-tools.d.ts +10 -0
  391. package/dist/tool-system/builtin/mcp-tools.js +102 -0
  392. package/dist/tool-system/builtin/memory.d.ts +26 -0
  393. package/dist/tool-system/builtin/memory.js +226 -0
  394. package/dist/tool-system/builtin/notebook-edit.d.ts +6 -0
  395. package/dist/tool-system/builtin/notebook-edit.js +124 -0
  396. package/dist/tool-system/builtin/plan.d.ts +15 -0
  397. package/dist/tool-system/builtin/plan.js +55 -0
  398. package/dist/tool-system/builtin/powershell.d.ts +11 -0
  399. package/dist/tool-system/builtin/powershell.js +64 -0
  400. package/dist/tool-system/builtin/read.d.ts +6 -0
  401. package/dist/tool-system/builtin/read.js +70 -0
  402. package/dist/tool-system/builtin/remote-trigger.d.ts +6 -0
  403. package/dist/tool-system/builtin/remote-trigger.js +54 -0
  404. package/dist/tool-system/builtin/repl.d.ts +11 -0
  405. package/dist/tool-system/builtin/repl.js +82 -0
  406. package/dist/tool-system/builtin/send-message.d.ts +6 -0
  407. package/dist/tool-system/builtin/send-message.js +47 -0
  408. package/dist/tool-system/builtin/skill-prompt.d.ts +20 -0
  409. package/dist/tool-system/builtin/skill-prompt.js +52 -0
  410. package/dist/tool-system/builtin/skill.d.ts +9 -0
  411. package/dist/tool-system/builtin/skill.js +55 -0
  412. package/dist/tool-system/builtin/sleep.d.ts +6 -0
  413. package/dist/tool-system/builtin/sleep.js +33 -0
  414. package/dist/tool-system/builtin/task.d.ts +48 -0
  415. package/dist/tool-system/builtin/task.js +139 -0
  416. package/dist/tool-system/builtin/tool-search.d.ts +11 -0
  417. package/dist/tool-system/builtin/tool-search.js +90 -0
  418. package/dist/tool-system/builtin/web-fetch.d.ts +10 -0
  419. package/dist/tool-system/builtin/web-fetch.js +328 -0
  420. package/dist/tool-system/builtin/web-search.d.ts +25 -0
  421. package/dist/tool-system/builtin/web-search.js +174 -0
  422. package/dist/tool-system/builtin/worktree.d.ts +10 -0
  423. package/dist/tool-system/builtin/worktree.js +95 -0
  424. package/dist/tool-system/builtin/write.d.ts +6 -0
  425. package/dist/tool-system/builtin/write.js +36 -0
  426. package/dist/tool-system/context.d.ts +165 -0
  427. package/dist/tool-system/context.js +18 -0
  428. package/dist/tool-system/executor.d.ts +49 -0
  429. package/dist/tool-system/executor.js +495 -0
  430. package/dist/tool-system/investigation-guard.d.ts +46 -0
  431. package/dist/tool-system/investigation-guard.js +155 -0
  432. package/dist/tool-system/mcp-manager.d.ts +67 -0
  433. package/dist/tool-system/mcp-manager.js +249 -0
  434. package/dist/tool-system/permission.d.ts +111 -0
  435. package/dist/tool-system/permission.js +774 -0
  436. package/dist/tool-system/registry.d.ts +32 -0
  437. package/dist/tool-system/registry.js +131 -0
  438. package/dist/tool-system/sandbox/bwrap.d.ts +13 -0
  439. package/dist/tool-system/sandbox/bwrap.js +63 -0
  440. package/dist/tool-system/sandbox/index.d.ts +78 -0
  441. package/dist/tool-system/sandbox/index.js +222 -0
  442. package/dist/tool-system/sandbox/off.d.ts +2 -0
  443. package/dist/tool-system/sandbox/off.js +8 -0
  444. package/dist/tool-system/sandbox/seatbelt.d.ts +18 -0
  445. package/dist/tool-system/sandbox/seatbelt.js +109 -0
  446. package/dist/tool-system/task-guard.d.ts +29 -0
  447. package/dist/tool-system/task-guard.js +70 -0
  448. package/dist/tool-system/validation.d.ts +5 -0
  449. package/dist/tool-system/validation.js +39 -0
  450. package/dist/types.d.ts +376 -0
  451. package/dist/types.js +4 -0
  452. package/dist/updater.d.ts +65 -0
  453. package/dist/updater.js +405 -0
  454. package/dist/utils/debug.d.ts +41 -0
  455. package/dist/utils/debug.js +110 -0
  456. package/dist/utils/earlyInput.d.ts +43 -0
  457. package/dist/utils/earlyInput.js +166 -0
  458. package/dist/utils/env.d.ts +24 -0
  459. package/dist/utils/env.js +104 -0
  460. package/dist/utils/envUtils.d.ts +51 -0
  461. package/dist/utils/envUtils.js +135 -0
  462. package/dist/utils/execFileNoThrow.d.ts +39 -0
  463. package/dist/utils/execFileNoThrow.js +74 -0
  464. package/dist/utils/format.d.ts +44 -0
  465. package/dist/utils/format.js +236 -0
  466. package/dist/utils/intl.d.ts +22 -0
  467. package/dist/utils/intl.js +83 -0
  468. package/dist/utils/lockfile.d.ts +15 -0
  469. package/dist/utils/lockfile.js +30 -0
  470. package/dist/utils/memoize.d.ts +19 -0
  471. package/dist/utils/memoize.js +14 -0
  472. package/dist/utils/semver.d.ts +6 -0
  473. package/dist/utils/semver.js +13 -0
  474. package/dist/utils/sliceAnsi.d.ts +12 -0
  475. package/dist/utils/sliceAnsi.js +62 -0
  476. package/dist/utils/systemTheme.d.ts +40 -0
  477. package/dist/utils/systemTheme.js +108 -0
  478. package/dist/utils/task-sanitizer.d.ts +6 -0
  479. package/dist/utils/task-sanitizer.js +24 -0
  480. package/dist/utils/theme.d.ts +93 -0
  481. package/dist/utils/theme.js +544 -0
  482. package/dist/utils/toolDisplay.d.ts +31 -0
  483. package/dist/utils/toolDisplay.js +188 -0
  484. package/package.json +72 -0
@@ -0,0 +1,855 @@
1
+ /**
2
+ * AgentServer — wraps ChatSessionManager and exposes it over the protocol.
3
+ *
4
+ * Responsibilities:
5
+ * - Handles RPC requests from the client (run, approve, cancel, configure, query)
6
+ * - Forwards StreamEvents to the client as notifications with sessionId envelope
7
+ * - Manages per-session approval flow
8
+ * - Dispatches agent/run through ChatSessionManager so multiple sessions
9
+ * run concurrently without cross-talk
10
+ *
11
+ * Backward compat: an optional `engine` can be supplied for global operations
12
+ * (model list, config reads/writes, tool registry queries, etc.) that don't
13
+ * yet have a natural "which session" answer. When not supplied the server
14
+ * falls back to borrowing any live session's engine for those reads.
15
+ */
16
+ import { Methods, ErrorCodes, createResponse, createErrorResponse, createNotification, isRequest, } from "./types.js";
17
+ import { setInteractiveApprovalFn } from "../tool-system/permission.js";
18
+ import { getArenaStatus } from "../tool-system/builtin/arena.js";
19
+ import { agentNotificationBus } from "../tool-system/builtin/agent-notifications.js";
20
+ import { nanoid } from "nanoid";
21
+ export class AgentServer {
22
+ chatManager;
23
+ legacyEngine;
24
+ transport;
25
+ // ── Legacy single-engine state (used when chatManager is null) ──
26
+ running = false;
27
+ abortController = null;
28
+ /** Pending approval requests: requestId → resolve function (legacy path) */
29
+ pendingApprovals = new Map();
30
+ /** Timers for approval timeouts */
31
+ approvalTimers = new Map();
32
+ /** Default approval timeout: 5 minutes */
33
+ static APPROVAL_TIMEOUT_MS = 5 * 60 * 1000;
34
+ /**
35
+ * Unsubscribe handle for the process-local `agentNotificationBus`
36
+ * subscription set up in the constructor. Called from `close()` so a
37
+ * shut-down server stops forwarding completion events even if the bus
38
+ * itself outlives the server (it's a process-local singleton).
39
+ */
40
+ bgAgentBusUnsubscribe = null;
41
+ constructor(options) {
42
+ this.chatManager = options.chatManager ?? null;
43
+ this.legacyEngine = options.engine ?? null;
44
+ if (!this.chatManager && !this.legacyEngine) {
45
+ throw new Error("AgentServer: either chatManager or engine must be supplied");
46
+ }
47
+ this.transport = options.transport;
48
+ // Wire up incoming messages
49
+ this.transport.onMessage((msg) => {
50
+ if (isRequest(msg)) {
51
+ this.handleRequest(msg).catch((err) => {
52
+ this.transport.send(createErrorResponse(msg.id, ErrorCodes.InternalError, err.message));
53
+ });
54
+ }
55
+ });
56
+ // Wire approval flow for the legacy single-engine path.
57
+ // In the chatManager path approval flows are per-session and registered
58
+ // when the session's engine raises an approval request via onStream.
59
+ if (this.legacyEngine) {
60
+ setInteractiveApprovalFn((request) => {
61
+ return this.requestApprovalFromClient(request);
62
+ });
63
+ this.legacyEngine.setAskUser((question, opts) => {
64
+ return this.requestAskUserFromClient(question, opts);
65
+ });
66
+ }
67
+ // B2.2 — forward background sub-agent completion events through the
68
+ // protocol so Desktop / SDK / remote AgentClients see them too. The
69
+ // bus is fed from `NotificationQueue.enqueue`, so this single
70
+ // subscription covers every enqueue site (today: only agent.ts). The
71
+ // bus now guarantees a real sessionId (no more legacy-bucket coercion
72
+ // to ""), so we forward whatever sid it hands us.
73
+ this.bgAgentBusUnsubscribe = agentNotificationBus.subscribe((sessionId, event) => {
74
+ this.notify(Methods.StreamEvent, { sessionId, event });
75
+ });
76
+ // Notify client we're ready
77
+ this.notify(Methods.Status, { status: "ready" });
78
+ }
79
+ // ─── Request Dispatch ───────────────────────────────────────────
80
+ async handleRequest(req) {
81
+ switch (req.method) {
82
+ case Methods.Run:
83
+ await this.handleRun(req);
84
+ break;
85
+ case Methods.Approve:
86
+ this.handleApprove(req);
87
+ break;
88
+ case Methods.Cancel:
89
+ this.handleCancel(req);
90
+ break;
91
+ case Methods.Configure:
92
+ this.handleConfigure(req);
93
+ break;
94
+ case Methods.Query:
95
+ await this.handleQuery(req);
96
+ break;
97
+ case Methods.Inject:
98
+ this.handleInject(req);
99
+ break;
100
+ case Methods.CloseSession:
101
+ this.handleCloseSession(req);
102
+ break;
103
+ default:
104
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.MethodNotFound, `Unknown method: ${req.method}`));
105
+ }
106
+ }
107
+ // ─── Run ────────────────────────────────────────────────────────
108
+ async handleRun(req) {
109
+ // ── ChatSessionManager path (multi-session) ──────────────────
110
+ if (this.chatManager) {
111
+ return this.handleRunMulti(req);
112
+ }
113
+ // ── Legacy single-engine path ────────────────────────────────
114
+ return this.handleRunLegacy(req);
115
+ }
116
+ async handleRunMulti(req) {
117
+ const cm = this.chatManager;
118
+ const params = (req.params ?? {});
119
+ if (typeof params.sessionId !== "string" || params.sessionId.length === 0) {
120
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "sessionId is required"));
121
+ return;
122
+ }
123
+ if (!params.task) {
124
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "task is required"));
125
+ return;
126
+ }
127
+ let session;
128
+ try {
129
+ session = cm.getOrCreate(params.sessionId, {
130
+ permissionMode: params.permissionMode,
131
+ cwd: params.cwd,
132
+ });
133
+ }
134
+ catch (err) {
135
+ const code = err.code ?? ErrorCodes.InternalError;
136
+ this.transport.send(createErrorResponse(req.id, code, err.message));
137
+ return;
138
+ }
139
+ if (typeof params.planMode === "boolean") {
140
+ session.engine.setPlanMode(params.planMode);
141
+ }
142
+ const sid = params.sessionId;
143
+ try {
144
+ const result = await session.enqueueTurn(params.task, {
145
+ cwd: params.cwd,
146
+ onStream: (event) => this.notify(Methods.StreamEvent, { sessionId: sid, event }),
147
+ });
148
+ const runResult = {
149
+ text: result.text,
150
+ reason: result.reason,
151
+ sessionId: result.sessionId ?? sid,
152
+ turnCount: result.turnCount,
153
+ usage: result.usage,
154
+ };
155
+ this.transport.send(createResponse(req.id, runResult));
156
+ }
157
+ catch (err) {
158
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
159
+ }
160
+ }
161
+ async handleRunLegacy(req) {
162
+ if (this.running) {
163
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.Overloaded, "Agent is already running"));
164
+ return;
165
+ }
166
+ const params = (req.params ?? {});
167
+ if (!params.task) {
168
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "task is required"));
169
+ return;
170
+ }
171
+ if (params.cwd !== undefined && (typeof params.cwd !== "string" || params.cwd.length === 0)) {
172
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "cwd must be a non-empty string"));
173
+ return;
174
+ }
175
+ if (params.permissionMode !== undefined) {
176
+ const mode = params.permissionMode;
177
+ if (!isValidPermissionMode(mode)) {
178
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, `invalid permission mode: ${mode}`));
179
+ return;
180
+ }
181
+ this.legacyEngine.setPermissionMode(mode);
182
+ // setRuntimeBypass / setInPlanMode singletons were removed in T4/T5;
183
+ // Engine.setPermissionMode now keeps this.permissionMode + this.planMode
184
+ // in sync and tools read them via ToolContext.permissionMode/planMode.
185
+ }
186
+ this.running = true;
187
+ this.abortController = new AbortController();
188
+ this.notify(Methods.Status, { status: "running" });
189
+ const streamToClient = (event) => {
190
+ this.notify(Methods.StreamEvent, { sessionId: params.sessionId ?? "", event });
191
+ };
192
+ // TodoWrite emits task_update directly through ToolContext.streamCallback;
193
+ // no module singleton wiring needed anymore.
194
+ try {
195
+ const result = await this.legacyEngine.run(params.task, {
196
+ cwd: params.cwd,
197
+ sessionId: params.sessionId,
198
+ signal: this.abortController.signal,
199
+ onStream: streamToClient,
200
+ });
201
+ const runResult = {
202
+ text: result.text,
203
+ reason: result.reason,
204
+ sessionId: result.sessionId,
205
+ turnCount: result.turnCount,
206
+ usage: result.usage,
207
+ };
208
+ this.transport.send(createResponse(req.id, runResult));
209
+ }
210
+ catch (err) {
211
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
212
+ }
213
+ finally {
214
+ this.running = false;
215
+ this.abortController = null;
216
+ this.notify(Methods.Status, { status: "ready" });
217
+ }
218
+ }
219
+ // ─── Approve ────────────────────────────────────────────────────
220
+ handleApprove(req) {
221
+ const params = (req.params ?? {});
222
+ // ChatSessionManager path: look up per-session pendingApprovals
223
+ if (this.chatManager && typeof params.sessionId === "string") {
224
+ const s = this.chatManager.get(params.sessionId);
225
+ if (!s) {
226
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, `No such session: ${params.sessionId}`));
227
+ return;
228
+ }
229
+ const resolve = s.pendingApprovals.get(params.requestId);
230
+ if (!resolve) {
231
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, `No pending approval: ${params.requestId}`));
232
+ return;
233
+ }
234
+ s.pendingApprovals.delete(params.requestId);
235
+ resolve(params.decision);
236
+ this.transport.send(createResponse(req.id, { ok: true }));
237
+ return;
238
+ }
239
+ // Legacy path
240
+ const resolve = this.pendingApprovals.get(params.requestId);
241
+ if (!resolve) {
242
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, `No pending approval: ${params.requestId}`));
243
+ return;
244
+ }
245
+ this.pendingApprovals.delete(params.requestId);
246
+ this.clearApprovalTimer(params.requestId);
247
+ resolve(params.decision);
248
+ this.transport.send(createResponse(req.id, { ok: true }));
249
+ }
250
+ // ─── Cancel ─────────────────────────────────────────────────────
251
+ handleCancel(req) {
252
+ const params = (req.params ?? {});
253
+ // ChatSessionManager path: cancel a specific session
254
+ if (this.chatManager) {
255
+ if (typeof params.sessionId !== "string" || params.sessionId.length === 0) {
256
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "sessionId is required"));
257
+ return;
258
+ }
259
+ const s = this.chatManager.get(params.sessionId);
260
+ if (!s) {
261
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, `No such session: ${params.sessionId}`));
262
+ return;
263
+ }
264
+ s.cancel();
265
+ this.transport.send(createResponse(req.id, { ok: true }));
266
+ return;
267
+ }
268
+ // Legacy path
269
+ if (!this.running || !this.abortController) {
270
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, "Agent is not running"));
271
+ return;
272
+ }
273
+ this.abortController.abort();
274
+ for (const [, resolve] of this.pendingApprovals) {
275
+ resolve({ approved: false, reason: "cancelled" });
276
+ }
277
+ this.pendingApprovals.clear();
278
+ this.clearAllApprovalTimers();
279
+ this.transport.send(createResponse(req.id, { ok: true }));
280
+ }
281
+ // ─── CloseSession ───────────────────────────────────────────────
282
+ handleCloseSession(req) {
283
+ const params = (req.params ?? {});
284
+ if (typeof params.sessionId !== "string" || params.sessionId.length === 0) {
285
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "sessionId is required"));
286
+ return;
287
+ }
288
+ if (this.chatManager) {
289
+ this.chatManager.close(params.sessionId);
290
+ }
291
+ this.transport.send(createResponse(req.id, { ok: true }));
292
+ }
293
+ // ─── Configure ──────────────────────────────────────────────────
294
+ handleConfigure(req) {
295
+ const params = (req.params ?? {});
296
+ // If a sessionId is present, mutate that specific session's engine
297
+ if (this.chatManager && typeof params.sessionId === "string") {
298
+ const sid = params.sessionId;
299
+ const s = this.chatManager.get(sid);
300
+ if (!s) {
301
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, `No such session: ${sid}`));
302
+ return;
303
+ }
304
+ if (typeof params.planMode === "boolean")
305
+ s.engine.setPlanMode(params.planMode);
306
+ if (typeof params.permissionMode === "string") {
307
+ s.engine.setPermissionMode(params.permissionMode);
308
+ }
309
+ this.transport.send(createResponse(req.id, { ok: true }));
310
+ return;
311
+ }
312
+ // Global configure — delegate to legacyEngine if available,
313
+ // or to any session's engine from chatManager for settings ops
314
+ const engine = this.legacyEngine ?? this.anyEngine();
315
+ if (params.reloadModels && engine) {
316
+ try {
317
+ engine.reloadModelPool();
318
+ }
319
+ catch (err) {
320
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
321
+ return;
322
+ }
323
+ }
324
+ if (params.model !== undefined && engine) {
325
+ try {
326
+ const entry = engine.switchModel(params.model);
327
+ this.transport.send(createResponse(req.id, { ok: true, model: entry.model, key: entry.key }));
328
+ return;
329
+ }
330
+ catch (err) {
331
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, err.message));
332
+ return;
333
+ }
334
+ }
335
+ if (params.planMode !== undefined && engine) {
336
+ engine.setPlanMode(params.planMode);
337
+ }
338
+ this.transport.send(createResponse(req.id, { ok: true }));
339
+ }
340
+ // ─── Query ──────────────────────────────────────────────────────
341
+ async handleQuery(req) {
342
+ const params = (req.params ?? {});
343
+ // For query operations we prefer the legacyEngine; if absent borrow any
344
+ // session engine from the manager (model pool, settings are shared).
345
+ const engine = this.legacyEngine ?? this.anyEngine();
346
+ switch (params.type) {
347
+ case "tools": {
348
+ if (!engine) {
349
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for tools query"));
350
+ return;
351
+ }
352
+ const registry = engine.getToolRegistry();
353
+ const tools = typeof registry.listToolsDetailed === "function"
354
+ ? registry
355
+ .listToolsDetailed()
356
+ .map((t) => ({ name: t.name, description: t.description ?? "" }))
357
+ : registry.listTools().map((name) => ({ name, description: "" }));
358
+ this.transport.send(createResponse(req.id, { type: "tools", data: tools }));
359
+ break;
360
+ }
361
+ case "sessions": {
362
+ if (this.chatManager) {
363
+ // Return the ChatSessionManager's live sessions
364
+ const sessions = [...this.chatManager.sessions.entries()].map(([id, s]) => ({
365
+ sessionId: id,
366
+ busy: s.isBusy(),
367
+ queueDepth: s.queueDepth(),
368
+ lastActivityAt: s.lastActivityAt,
369
+ }));
370
+ this.transport.send(createResponse(req.id, { type: "sessions", data: sessions }));
371
+ }
372
+ else if (engine) {
373
+ const sessions = engine.getSessionManager().list();
374
+ this.transport.send(createResponse(req.id, { type: "sessions", data: sessions }));
375
+ }
376
+ else {
377
+ this.transport.send(createResponse(req.id, { type: "sessions", data: [] }));
378
+ }
379
+ break;
380
+ }
381
+ case "config": {
382
+ if (!engine) {
383
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for config query"));
384
+ return;
385
+ }
386
+ const config = engine.getConfig();
387
+ this.transport.send(createResponse(req.id, {
388
+ type: "config",
389
+ data: {
390
+ permissionMode: config.permissionMode ?? "default",
391
+ planMode: engine.planMode ?? false,
392
+ preset: config.preset,
393
+ model: config.llm.model,
394
+ cwd: config.cwd,
395
+ maxContextTokens: config.maxContextTokens,
396
+ llm: {
397
+ provider: config.llm.provider,
398
+ model: config.llm.model,
399
+ apiKey: config.llm.apiKey,
400
+ baseUrl: config.llm.baseUrl,
401
+ temperature: config.llm.temperature,
402
+ maxTokens: config.llm.maxTokens,
403
+ enableStreaming: config.llm.enableStreaming,
404
+ },
405
+ },
406
+ }));
407
+ break;
408
+ }
409
+ case "session_detail": {
410
+ if (!engine) {
411
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for session_detail query"));
412
+ return;
413
+ }
414
+ if (params.sessionId) {
415
+ try {
416
+ const bundle = engine.getSessionManager().resume(params.sessionId);
417
+ const data = {
418
+ state: bundle.state,
419
+ transcript: bundle.transcript.getEvents(),
420
+ };
421
+ this.transport.send(createResponse(req.id, { type: "session_detail", data }));
422
+ }
423
+ catch (err) {
424
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionNotFound, err.message));
425
+ }
426
+ }
427
+ else {
428
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "sessionId required for session_detail"));
429
+ }
430
+ break;
431
+ }
432
+ case "compact": {
433
+ if (!engine) {
434
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for compact query"));
435
+ return;
436
+ }
437
+ try {
438
+ const result = engine.forceCompact();
439
+ this.transport.send(createResponse(req.id, {
440
+ type: "compact",
441
+ data: result,
442
+ }));
443
+ }
444
+ catch (err) {
445
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
446
+ }
447
+ break;
448
+ }
449
+ case "models": {
450
+ if (!engine) {
451
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for models query"));
452
+ return;
453
+ }
454
+ const pool = engine.getModelPool();
455
+ const models = pool.list().map((m) => ({
456
+ key: m.key,
457
+ label: m.label ?? m.key,
458
+ model: m.model,
459
+ protocol: m.provider,
460
+ providerKey: m.providerKey,
461
+ active: m.key === pool.getActiveKey(),
462
+ maxOutputTokens: m.maxOutputTokens,
463
+ maxContextTokens: m.maxContextTokens,
464
+ }));
465
+ this.transport.send(createResponse(req.id, { type: "models", data: models }));
466
+ break;
467
+ }
468
+ case "providers": {
469
+ if (!engine) {
470
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for providers query"));
471
+ return;
472
+ }
473
+ try {
474
+ const providersRaw = engine.readSetting("providers");
475
+ const modelsRaw = engine.readSetting("models");
476
+ const providerList = Array.isArray(providersRaw)
477
+ ? providersRaw
478
+ : [];
479
+ const modelsList = Array.isArray(modelsRaw)
480
+ ? modelsRaw
481
+ : [];
482
+ const counts = new Map();
483
+ for (const m of modelsList) {
484
+ const pk = typeof m.providerKey === "string" ? m.providerKey : "";
485
+ if (!pk)
486
+ continue;
487
+ counts.set(pk, (counts.get(pk) ?? 0) + 1);
488
+ }
489
+ const { readCache } = await import("../llm/model-cache.js");
490
+ const { defaultCacheDir } = await import("../llm/model-cache.js");
491
+ const cacheDir = defaultCacheDir();
492
+ const enriched = providerList.map((p) => {
493
+ const key = typeof p.key === "string" ? p.key : "";
494
+ const cache = key ? readCache(cacheDir, key) : undefined;
495
+ return {
496
+ ...p,
497
+ modelCount: counts.get(key) ?? 0,
498
+ cachedModels: cache ? cache.models.length : undefined,
499
+ cachedAt: cache ? cache.fetchedAt : undefined,
500
+ };
501
+ });
502
+ this.transport.send(createResponse(req.id, { type: "providers", data: enriched }));
503
+ }
504
+ catch (err) {
505
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
506
+ }
507
+ break;
508
+ }
509
+ case "arena_status": {
510
+ const status = getArenaStatus();
511
+ this.transport.send(createResponse(req.id, { type: "arena_status", data: status }));
512
+ break;
513
+ }
514
+ case "config_set": {
515
+ if (!engine) {
516
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for config_set"));
517
+ return;
518
+ }
519
+ try {
520
+ const { key, value } = params;
521
+ if (!key)
522
+ throw new Error("key is required for config_set");
523
+ engine.updateConfig(key, value);
524
+ this.transport.send(createResponse(req.id, { type: "config_set", data: { key, value } }));
525
+ }
526
+ catch (err) {
527
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
528
+ }
529
+ break;
530
+ }
531
+ case "config_get": {
532
+ if (!engine) {
533
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for config_get"));
534
+ return;
535
+ }
536
+ try {
537
+ const { key } = params;
538
+ if (!key)
539
+ throw new Error("key is required for config_get");
540
+ const value = engine.readSetting(key);
541
+ this.transport.send(createResponse(req.id, { type: "config_get", data: { key, value } }));
542
+ }
543
+ catch (err) {
544
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
545
+ }
546
+ break;
547
+ }
548
+ case "permission_set": {
549
+ if (!engine) {
550
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for permission_set"));
551
+ return;
552
+ }
553
+ try {
554
+ const value = params.value;
555
+ const valid = ["default", "acceptEdits", "dontAsk", "bypassPermissions", "auto", "plan"];
556
+ if (!value || !valid.includes(value)) {
557
+ throw new Error(`invalid permission mode: ${value}`);
558
+ }
559
+ engine.setPermissionMode(value);
560
+ this.transport.send(createResponse(req.id, {
561
+ type: "permission_set",
562
+ data: { mode: value },
563
+ }));
564
+ }
565
+ catch (err) {
566
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
567
+ }
568
+ break;
569
+ }
570
+ case "provider_add": {
571
+ if (!engine) {
572
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for provider_add"));
573
+ return;
574
+ }
575
+ try {
576
+ const cfg = params.provider;
577
+ if (!cfg ||
578
+ typeof cfg.key !== "string" ||
579
+ typeof cfg.kind !== "string" ||
580
+ typeof cfg.baseUrl !== "string") {
581
+ throw new Error("provider_add: requires {key, kind, baseUrl, ...}");
582
+ }
583
+ const current = engine.readSetting("providers") ?? [];
584
+ const next = [...current, cfg];
585
+ engine.updateConfig("providers", next);
586
+ this.transport.send(createResponse(req.id, { type: "provider_add", data: { ok: true, key: cfg.key } }));
587
+ }
588
+ catch (err) {
589
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
590
+ }
591
+ break;
592
+ }
593
+ case "provider_refresh": {
594
+ if (!engine) {
595
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for provider_refresh"));
596
+ return;
597
+ }
598
+ try {
599
+ const key = params.key;
600
+ if (!key)
601
+ throw new Error("provider_refresh: key required");
602
+ const providers = engine.readSetting("providers") ??
603
+ [];
604
+ const p = providers.find((x) => x.key === key);
605
+ if (!p)
606
+ throw new Error(`provider not found: ${key}`);
607
+ const { fetchModelList } = await import("../llm/model-fetcher.js");
608
+ const { defaultCacheDir } = await import("../llm/model-cache.js");
609
+ const res = await fetchModelList({
610
+ key: p.key,
611
+ kind: p.kind,
612
+ baseUrl: p.baseUrl,
613
+ apiKey: p.apiKey,
614
+ }, { cacheDir: defaultCacheDir(), refresh: true });
615
+ this.transport.send(createResponse(req.id, {
616
+ type: "provider_refresh",
617
+ data: { count: res.models.length, error: res.error },
618
+ }));
619
+ }
620
+ catch (err) {
621
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
622
+ }
623
+ break;
624
+ }
625
+ case "provider_delete": {
626
+ if (!engine) {
627
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for provider_delete"));
628
+ return;
629
+ }
630
+ try {
631
+ const key = params.key;
632
+ if (!key)
633
+ throw new Error("provider_delete: key required");
634
+ const models = engine.readSetting("models") ?? [];
635
+ const refs = models.filter((m) => m.providerKey === key).map((m) => m.key);
636
+ if (refs.length > 0) {
637
+ throw new Error(`provider ${key} referenced by models: ${refs.join(", ")}`);
638
+ }
639
+ const providers = engine.readSetting("providers") ??
640
+ [];
641
+ const next = providers.filter((p) => p.key !== key);
642
+ engine.updateConfig("providers", next);
643
+ this.transport.send(createResponse(req.id, { type: "provider_delete", data: { ok: true } }));
644
+ }
645
+ catch (err) {
646
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
647
+ }
648
+ break;
649
+ }
650
+ case "model_add": {
651
+ if (!engine) {
652
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for model_add"));
653
+ return;
654
+ }
655
+ try {
656
+ const entry = params.model;
657
+ if (!entry || typeof entry.key !== "string" || typeof entry.model !== "string") {
658
+ throw new Error("model_add: requires {key, model, providerKey}");
659
+ }
660
+ const current = engine.readSetting("models") ?? [];
661
+ const next = [...current, entry];
662
+ engine.updateConfig("models", next);
663
+ this.transport.send(createResponse(req.id, { type: "model_add", data: { ok: true, key: entry.key } }));
664
+ }
665
+ catch (err) {
666
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
667
+ }
668
+ break;
669
+ }
670
+ case "model_delete": {
671
+ if (!engine) {
672
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for model_delete"));
673
+ return;
674
+ }
675
+ try {
676
+ const key = params.key;
677
+ if (!key)
678
+ throw new Error("model_delete: key required");
679
+ const current = engine.readSetting("models") ?? [];
680
+ const next = current.filter((m) => m.key !== key);
681
+ engine.updateConfig("models", next);
682
+ this.transport.send(createResponse(req.id, { type: "model_delete", data: { ok: true } }));
683
+ }
684
+ catch (err) {
685
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
686
+ }
687
+ break;
688
+ }
689
+ default:
690
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, `Unknown query type: ${params.type}`));
691
+ }
692
+ }
693
+ // ─── Inject ─────────────────────────────────────────────────────
694
+ handleInject(req) {
695
+ const params = (req.params ?? {});
696
+ if (!params.content || !params.sessionId) {
697
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "content and sessionId required"));
698
+ return;
699
+ }
700
+ // In the chatManager path, inject into the session's engine
701
+ if (this.chatManager) {
702
+ const s = this.chatManager.get(params.sessionId);
703
+ if (!s) {
704
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, `No such session: ${params.sessionId}`));
705
+ return;
706
+ }
707
+ try {
708
+ s.engine.injectContext(params.sessionId, params.content);
709
+ this.transport.send(createResponse(req.id, { ok: true }));
710
+ }
711
+ catch (err) {
712
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
713
+ }
714
+ return;
715
+ }
716
+ try {
717
+ this.legacyEngine.injectContext(params.sessionId, params.content);
718
+ this.transport.send(createResponse(req.id, { ok: true }));
719
+ }
720
+ catch (err) {
721
+ this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
722
+ }
723
+ }
724
+ // ─── Client Communication ───────────────────────────────────────
725
+ /**
726
+ * Ask the client to approve a tool operation (legacy single-engine path).
727
+ */
728
+ requestApprovalFromClient(request) {
729
+ return new Promise((resolve) => {
730
+ const requestId = nanoid(12);
731
+ this.pendingApprovals.set(requestId, resolve);
732
+ const timer = setTimeout(() => {
733
+ if (this.pendingApprovals.has(requestId)) {
734
+ this.pendingApprovals.delete(requestId);
735
+ this.approvalTimers.delete(requestId);
736
+ resolve({ approved: false, reason: "approval timed out" });
737
+ }
738
+ }, AgentServer.APPROVAL_TIMEOUT_MS);
739
+ this.approvalTimers.set(requestId, timer);
740
+ this.notify(Methods.ApprovalRequest, { requestId, request });
741
+ });
742
+ }
743
+ /**
744
+ * Ask the client to answer a question from the agent (legacy single-engine path).
745
+ */
746
+ requestAskUserFromClient(question, opts) {
747
+ return new Promise((resolve) => {
748
+ const requestId = nanoid(12);
749
+ this.pendingApprovals.set(requestId, (result) => {
750
+ this.clearApprovalTimer(requestId);
751
+ if (result.approved) {
752
+ resolve(result.answer ?? "");
753
+ }
754
+ else {
755
+ resolve(result.reason ?? "(user declined to answer)");
756
+ }
757
+ });
758
+ const timer = setTimeout(() => {
759
+ if (this.pendingApprovals.has(requestId)) {
760
+ this.pendingApprovals.delete(requestId);
761
+ this.approvalTimers.delete(requestId);
762
+ resolve("(approval timed out)");
763
+ }
764
+ }, AgentServer.APPROVAL_TIMEOUT_MS);
765
+ this.approvalTimers.set(requestId, timer);
766
+ const args = { question };
767
+ if (opts?.header !== undefined)
768
+ args.header = opts.header;
769
+ if (opts?.options !== undefined)
770
+ args.options = opts.options;
771
+ if (opts?.multiSelect !== undefined)
772
+ args.multiSelect = opts.multiSelect;
773
+ this.notify(Methods.ApprovalRequest, {
774
+ requestId,
775
+ request: {
776
+ toolName: "__ask_user__",
777
+ args,
778
+ description: question,
779
+ riskLevel: "low",
780
+ },
781
+ });
782
+ });
783
+ }
784
+ notify(method, params) {
785
+ this.transport.send(createNotification(method, params));
786
+ }
787
+ /**
788
+ * Get any available engine — used for global query ops when chatManager is
789
+ * present but no legacyEngine was supplied. Borrows the first live session.
790
+ */
791
+ anyEngine() {
792
+ if (!this.chatManager)
793
+ return null;
794
+ // Access private `sessions` map — acceptable for same-package access.
795
+ const sessions = this.chatManager.sessions;
796
+ const first = sessions.values().next().value;
797
+ return first ? first.engine : null;
798
+ }
799
+ // ─── Lifecycle ──────────────────────────────────────────────────
800
+ close() {
801
+ // Detach the bg-agent bus subscription first so a final flurry of
802
+ // completions during shutdown can't race the `shutdown` status
803
+ // notify below. Safe to call repeatedly — the unsubscribe is a
804
+ // single-shot Set.delete.
805
+ if (this.bgAgentBusUnsubscribe) {
806
+ try {
807
+ this.bgAgentBusUnsubscribe();
808
+ }
809
+ catch {
810
+ // swallow
811
+ }
812
+ this.bgAgentBusUnsubscribe = null;
813
+ }
814
+ if (this.chatManager) {
815
+ this.chatManager.closeAll();
816
+ }
817
+ // Legacy path cleanup
818
+ if (this.abortController) {
819
+ try {
820
+ this.abortController.abort("server closing");
821
+ }
822
+ catch {
823
+ // swallow
824
+ }
825
+ }
826
+ for (const [, resolve] of this.pendingApprovals) {
827
+ resolve({ approved: false, reason: "server closing" });
828
+ }
829
+ this.pendingApprovals.clear();
830
+ this.clearAllApprovalTimers();
831
+ this.notify(Methods.Status, { status: "shutdown" });
832
+ this.transport.close();
833
+ }
834
+ clearApprovalTimer(requestId) {
835
+ const timer = this.approvalTimers.get(requestId);
836
+ if (timer) {
837
+ clearTimeout(timer);
838
+ this.approvalTimers.delete(requestId);
839
+ }
840
+ }
841
+ clearAllApprovalTimers() {
842
+ for (const timer of this.approvalTimers.values()) {
843
+ clearTimeout(timer);
844
+ }
845
+ this.approvalTimers.clear();
846
+ }
847
+ }
848
+ function isValidPermissionMode(value) {
849
+ return (value === "default" ||
850
+ value === "acceptEdits" ||
851
+ value === "dontAsk" ||
852
+ value === "bypassPermissions" ||
853
+ value === "auto" ||
854
+ value === "plan");
855
+ }