@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,151 @@
1
+ /**
2
+ * Dream consolidation — the LLM tool-call loop that cleans up the `dream`
3
+ * memory scope (deduplicate, merge, drop stale, improve descriptions).
4
+ *
5
+ * This logic used to live as two private methods on Engine
6
+ * (`runDreamLoop` + `dispatchDreamTool`). It was extracted here so it can be
7
+ * driven from two places:
8
+ * - the end-of-session auto-dream pipeline (Engine.runDreamLoop delegates here)
9
+ * - a manual "整理 / Dream" trigger from the desktop host, which constructs a
10
+ * seed Engine purely to obtain a toolRegistry + LLM client and then calls
11
+ * this directly (it never runs a turn).
12
+ *
13
+ * The loop is intentionally small and offline:
14
+ * - No streaming, no UI events — it runs in the background.
15
+ * - No permission prompts — there is no interactive backend on this path, so
16
+ * we hard-reject any attempt to Save/Delete in the "user" scope before
17
+ * dispatching. The "dream" scope is the LLM's workspace and goes through
18
+ * freely.
19
+ * - Capped at MAX_TURNS LLM round-trips and MAX_WRITES total mutations to
20
+ * bound damage on misbehavior.
21
+ */
22
+ import { MemoryManager } from "../session/memory.js";
23
+ import { buildDreamSystemPrompt, buildDreamUserPrompt, } from "./auto-dream.js";
24
+ import { logger } from "../logging/logger.js";
25
+ const MAX_TURNS = 8;
26
+ const MAX_WRITES = 10;
27
+ const MEMORY_TOOL_NAMES = ["MemoryList", "MemoryRead", "MemorySave", "MemoryDelete"];
28
+ /**
29
+ * Drive the dream-scope consolidation tool-call loop.
30
+ *
31
+ * Loads both scopes (user is read-only context; dream is the workspace),
32
+ * builds the dream prompts, and runs the LLM with a whitelisted subset of
33
+ * memory tools until it stops calling tools or hits the turn cap.
34
+ *
35
+ * Returns `ran: false` if the registry is missing the memory tools (nothing
36
+ * happened); otherwise `ran: true` with the final summary text.
37
+ */
38
+ export async function runDreamConsolidation(input) {
39
+ const { llmClient, toolRegistry, projectDir, sessionId } = input;
40
+ const memoryTools = MEMORY_TOOL_NAMES
41
+ .map((n) => toolRegistry.getTool(n))
42
+ .filter((t) => t != null);
43
+ if (memoryTools.length < MEMORY_TOOL_NAMES.length) {
44
+ logger.warn("memory.dream_missing_tools", {
45
+ sessionId,
46
+ found: memoryTools.map((t) => t.name),
47
+ });
48
+ return { ran: false, summary: "" };
49
+ }
50
+ // Dream sees BOTH scopes — user/ is read-only context so it can spot
51
+ // duplicates spanning scopes, dream/ is the workspace it edits.
52
+ const mm = new MemoryManager({ projectDir });
53
+ const userMems = mm.loadScope("user");
54
+ const dreamMems = mm.loadScope("dream");
55
+ const systemPrompt = buildDreamSystemPrompt();
56
+ const userPrompt = buildDreamUserPrompt(userMems, dreamMems);
57
+ // Strip RegisteredTool down to the shape createMessage expects.
58
+ const toolDefs = memoryTools.map((t) => ({
59
+ name: t.name,
60
+ description: t.description,
61
+ inputSchema: t.inputSchema,
62
+ }));
63
+ const toolCtx = {
64
+ ...input.toolContext,
65
+ cwd: projectDir ?? process.cwd(),
66
+ };
67
+ const messages = [{ role: "user", content: userPrompt }];
68
+ let writeBudget = MAX_WRITES;
69
+ for (let turn = 0; turn < MAX_TURNS; turn++) {
70
+ const resp = await llmClient.createMessage({
71
+ systemPrompt,
72
+ messages,
73
+ tools: toolDefs,
74
+ maxTokens: 2048,
75
+ recordUsage: false,
76
+ reasoning: { mode: "off" },
77
+ });
78
+ if (resp.toolCalls.length === 0) {
79
+ logger.info("memory.dream_finished", {
80
+ sessionId,
81
+ turn,
82
+ finalText: resp.text.slice(0, 500),
83
+ });
84
+ return { ran: true, summary: resp.text };
85
+ }
86
+ // Echo the assistant turn back so subsequent turns see the tool_use ids.
87
+ const assistantContent = [];
88
+ if (resp.text)
89
+ assistantContent.push({ type: "text", text: resp.text });
90
+ for (const tc of resp.toolCalls) {
91
+ assistantContent.push({
92
+ type: "tool_use",
93
+ id: tc.id,
94
+ name: tc.toolName,
95
+ input: tc.args,
96
+ });
97
+ }
98
+ messages.push({ role: "assistant", content: assistantContent });
99
+ // Dispatch every tool call requested in this turn.
100
+ const toolResults = [];
101
+ for (const tc of resp.toolCalls) {
102
+ const result = await dispatchDreamTool(tc, toolRegistry, toolCtx, () => {
103
+ if (writeBudget <= 0)
104
+ return false;
105
+ writeBudget--;
106
+ return true;
107
+ });
108
+ toolResults.push({
109
+ type: "tool_result",
110
+ tool_use_id: tc.id,
111
+ content: result,
112
+ });
113
+ }
114
+ messages.push({ role: "user", content: toolResults });
115
+ }
116
+ logger.warn("memory.dream_hit_turn_cap", { sessionId, maxTurns: MAX_TURNS });
117
+ return { ran: true, summary: "" };
118
+ }
119
+ /**
120
+ * Execute one memory tool call inside the dream loop. Enforces the two
121
+ * dream-loop invariants the prompt also states:
122
+ * - Only the 4 memory tools are dispatchable.
123
+ * - Save/Delete in "user" scope is refused (returned as a tool error)
124
+ * because dream runs without an interactive permission backend.
125
+ */
126
+ async function dispatchDreamTool(tc, toolRegistry, ctx, consumeWriteBudget) {
127
+ const allowed = new Set(MEMORY_TOOL_NAMES);
128
+ if (!allowed.has(tc.toolName)) {
129
+ return `Error: tool "${tc.toolName}" is not available in the dream loop`;
130
+ }
131
+ const isWrite = tc.toolName === "MemorySave" || tc.toolName === "MemoryDelete";
132
+ if (isWrite) {
133
+ const scope = tc.args?.scope;
134
+ if (scope !== "dream") {
135
+ return (`Error: dream loop may only write to scope "dream", got "${scope}". ` +
136
+ `User-scope changes require interactive permission, which is not available here.`);
137
+ }
138
+ if (!consumeWriteBudget()) {
139
+ return "Error: dream write budget exhausted — stop calling write tools and summarize instead.";
140
+ }
141
+ }
142
+ try {
143
+ const result = await toolRegistry.executeTool(tc.toolName, tc.args, { ctx });
144
+ if (result.isError)
145
+ return result.error ?? `Error executing ${tc.toolName}`;
146
+ return result.result ?? "";
147
+ }
148
+ catch (err) {
149
+ return `Error executing ${tc.toolName}: ${err.message}`;
150
+ }
151
+ }
@@ -6,6 +6,14 @@
6
6
  */
7
7
  export interface ExtractedMemory {
8
8
  type: "user" | "feedback" | "project" | "reference";
9
+ /**
10
+ * Storage location (用户拍板). "global" = a general lesson/preference that
11
+ * still holds in a different project (→ ~/.code-shell/memory). "project" =
12
+ * specific to the current repo (→ projects/<hash>/memory). Decided by the
13
+ * extracting LLM. Missing/invalid → "project" (conservative: don't pollute
14
+ * the global layer with one-off events).
15
+ */
16
+ scope: "global" | "project";
9
17
  name: string;
10
18
  description: string;
11
19
  content: string;
@@ -27,5 +35,10 @@ export declare function buildExtractionPrompt(transcript: Array<{
27
35
  export declare const MAX_MEMORIES_PER_EXTRACTION = 2;
28
36
  /**
29
37
  * Parse extracted memories from LLM response.
38
+ *
39
+ * `maxCount` caps how many memories are accepted from one pass (the code-side
40
+ * guarantee of the prompt rule). Defaults to MAX_MEMORIES_PER_EXTRACTION; a
41
+ * caller can pass `settings.memories.maxCount` to tune it. Non-positive or
42
+ * absent → the default.
30
43
  */
31
- export declare function parseExtractionResponse(response: string): ExtractedMemory[];
44
+ export declare function parseExtractionResponse(response: string, maxCount?: number): ExtractedMemory[];
@@ -23,22 +23,31 @@ ${existingList}
23
23
  ${conversationText.slice(0, 30000)}
24
24
 
25
25
  ## Instructions
26
- Identify NEW information that should be saved as persistent memories. Categories:
26
+ Identify NEW information that should be saved as persistent memories. Categories (type):
27
27
  - **user**: Information about the user's role, preferences, or expertise
28
28
  - **feedback**: Guidance about how to approach work (corrections or confirmations)
29
29
  - **project**: Non-obvious facts about ongoing work, goals, or decisions
30
30
  - **reference**: Pointers to external resources or systems
31
31
 
32
+ Also decide each memory's storage SCOPE. **Be VERY conservative about "global" — default to "project".**
33
+ - **global** (RARE — strong bar): ONLY a general working principle, durable user preference, or fact about WHO THE USER IS that would be useful in literally ANY project or task. Examples that qualify: "the user prefers Chinese replies", "always grep for consumers before declaring code dead", "git subprocess args need a -- separator".
34
+ - A concrete task's setup or domain data is NOT global even though it isn't tied to a code repo. Counter-examples that are **project, NOT global**: a specific daily-news / morning-briefing workflow and its data sources; how to log into a specific website; a particular model's config parameters; one integration's auth choice. These are task/domain specifics → "project".
35
+ - **project** (DEFAULT): anything specific to this repo, this task, or this domain — including the counter-examples above.
36
+ - The test for global: "is this a general way-of-working or who-the-user-is that applies across EVERY project?" Only then global. When in any doubt → project.
37
+
32
38
  Rules:
33
39
  - Extract AT MOST 2 memories per session. Prefer 0 to a marginal one — most sessions are noise.
40
+ - AT MOST 1 of the extracted memories may be "global". The global layer is injected every session, so keep it tiny and high-value. If two candidates both seem global, keep the single most universal one global and make the other "project".
34
41
  - Only extract information that would be useful in FUTURE conversations
35
42
  - Do not duplicate existing memories (re-read the "Existing Memories" list above carefully)
36
43
  - Do not extract code patterns, file structures, or git history (derivable from code)
37
44
  - Do not extract ephemeral task details, progress snapshots, or in-flight work state — those belong in the conversation, not memory
38
45
  - Do not extract one-off research products (news reports, AI industry summaries, slide deck content, daily progress dumps) — they're done and not "durable, reusable information"
46
+ - NEVER include secrets: API keys, tokens, passwords, private URLs with credentials. If the durable fact involves a credential, describe WHERE it lives (e.g. "key is in .env as FOO_KEY"), never the value itself
39
47
  - Each memory should have a clear, specific description
40
48
 
41
- Respond with a JSON array of objects with fields: type, name, description, content
49
+ Respond with a JSON array of objects with fields: type, scope, name, description, content
50
+ (scope must be "global" or "project")
42
51
  If nothing worth remembering, respond with an empty array: []`;
43
52
  }
44
53
  /** Max memories to accept from a single extraction pass. Code-side cap that
@@ -47,8 +56,16 @@ If nothing worth remembering, respond with an empty array: []`;
47
56
  export const MAX_MEMORIES_PER_EXTRACTION = 2;
48
57
  /**
49
58
  * Parse extracted memories from LLM response.
59
+ *
60
+ * `maxCount` caps how many memories are accepted from one pass (the code-side
61
+ * guarantee of the prompt rule). Defaults to MAX_MEMORIES_PER_EXTRACTION; a
62
+ * caller can pass `settings.memories.maxCount` to tune it. Non-positive or
63
+ * absent → the default.
50
64
  */
51
- export function parseExtractionResponse(response) {
65
+ export function parseExtractionResponse(response, maxCount) {
66
+ const cap = typeof maxCount === "number" && maxCount > 0
67
+ ? Math.floor(maxCount)
68
+ : MAX_MEMORIES_PER_EXTRACTION;
52
69
  try {
53
70
  // Find JSON array in response
54
71
  const jsonMatch = response.match(/\[[\s\S]*\]/);
@@ -57,13 +74,35 @@ export function parseExtractionResponse(response) {
57
74
  const parsed = JSON.parse(jsonMatch[0]);
58
75
  if (!Array.isArray(parsed))
59
76
  return [];
60
- const valid = parsed.filter((m) => typeof m === "object" &&
77
+ const valid = parsed
78
+ .filter((m) => typeof m === "object" &&
61
79
  m !== null &&
62
80
  typeof m.type === "string" &&
63
81
  typeof m.name === "string" &&
64
82
  typeof m.content === "string" &&
65
- ["user", "feedback", "project", "reference"].includes(m.type));
66
- return valid.slice(0, MAX_MEMORIES_PER_EXTRACTION);
83
+ ["user", "feedback", "project", "reference"].includes(m.type))
84
+ // Normalize scope: only "global" survives as global; everything else
85
+ // (absent, "project", typos) → "project" — never promote to global by accident.
86
+ .map((m) => ({
87
+ type: m.type,
88
+ scope: m.scope === "global" ? "global" : "project",
89
+ name: m.name,
90
+ description: m.description,
91
+ content: m.content,
92
+ }));
93
+ // Hard cap (用户拍板 克制): at most 1 global per extraction. The prompt asks
94
+ // for this, but the model may ignore it — enforce in code. Keep the first
95
+ // global as-is; demote any further globals to project.
96
+ let globalSeen = false;
97
+ const capped = valid.map((m) => {
98
+ if (m.scope !== "global")
99
+ return m;
100
+ if (globalSeen)
101
+ return { ...m, scope: "project" };
102
+ globalSeen = true;
103
+ return m;
104
+ });
105
+ return capped.slice(0, cap);
67
106
  }
68
107
  catch {
69
108
  return [];
@@ -35,12 +35,33 @@ export interface MemoryOrchestratorOptions {
35
35
  projectDir?: string;
36
36
  /** Optional pre-constructed MemoryManager (avoids re-creating for every call). */
37
37
  memoryManager?: MemoryManager;
38
+ /**
39
+ * Max memories to accept per extraction pass. From settings.memories.maxCount;
40
+ * undefined → the built-in MAX_MEMORIES_PER_EXTRACTION default.
41
+ */
42
+ maxCount?: number;
43
+ /**
44
+ * From settings.memories.autoExtract. `false` skips step 1 (LLM memory
45
+ * extraction) entirely — the user-curated store stops accumulating
46
+ * extractor noise — while session summaries and auto-dream keep running.
47
+ * Absent/true = extract (default behavior).
48
+ */
49
+ autoExtract?: boolean;
50
+ /**
51
+ * Recall-based TTL in days (用户拍板 C). A `project`-type memory not read for
52
+ * this many days is soft-deleted (moved to memory-trash). Stable types
53
+ * (user/feedback/reference) and pinned entries are never pruned. From
54
+ * settings.memories.recallTtlDays; undefined/<=0 → no sweep.
55
+ */
56
+ recallTtlDays?: number;
38
57
  }
39
58
  export interface MemoryOrchestratorResult {
40
59
  /** Number of new memory entries extracted and saved. */
41
60
  extracted: number;
42
61
  /** Whether the auto-dream consolidation was triggered. */
43
62
  dreamTriggered: boolean;
63
+ /** Names of memories pruned by the recall-TTL sweep. */
64
+ pruned: string[];
44
65
  }
45
66
  export declare class MemoryOrchestrator {
46
67
  private readonly options;
@@ -15,6 +15,8 @@
15
15
  import { MemoryManager } from "../session/memory.js";
16
16
  import { buildExtractionPrompt, parseExtractionResponse } from "./extract-memories.js";
17
17
  import { saveSessionMemory, buildSessionMemoryPrompt } from "./session-memory.js";
18
+ import { extractJSON } from "../utils/json.js";
19
+ import { redactSecrets } from "../logging/sanitize-messages.js";
18
20
  import { shouldAutoDream, recordSession, recordDreamComplete, buildDreamSystemPrompt, buildDreamUserPrompt } from "./auto-dream.js";
19
21
  import { logger } from "../logging/logger.js";
20
22
  export class MemoryOrchestrator {
@@ -34,33 +36,83 @@ export class MemoryOrchestrator {
34
36
  const mm = this.options.memoryManager ?? new MemoryManager({ projectDir: this.options.projectDir });
35
37
  const startTime = Date.now();
36
38
  // --------------- 1. Extract durable memories ---------------
39
+ // settings.memories.autoExtract=false skips the extractor entirely (the
40
+ // curated store stops accumulating noise); summaries + dream still run.
37
41
  let extracted = 0;
38
- try {
39
- const existing = mm.loadAll();
40
- const extractionPrompt = buildExtractionPrompt(transcript, existing);
41
- const response = await this.options.callLLM("You are a memory extraction assistant. Extract only durable, reusable information worth carrying into future sessions.", extractionPrompt);
42
- const entries = parseExtractionResponse(response);
43
- for (const entry of entries) {
44
- mm.save({
45
- type: entry.type,
46
- name: entry.name,
47
- description: entry.description,
48
- content: entry.content,
42
+ if (this.options.autoExtract === false) {
43
+ logger.info("memory.extraction_skipped", { sessionId, reason: "autoExtract=false" });
44
+ }
45
+ else
46
+ try {
47
+ let t = Date.now();
48
+ const existing = mm.loadAll();
49
+ const loadMs = Date.now() - t;
50
+ t = Date.now();
51
+ const extractionPrompt = buildExtractionPrompt(transcript, existing);
52
+ const promptMs = Date.now() - t;
53
+ t = Date.now();
54
+ const response = await this.options.callLLM("You are a memory extraction assistant. Extract only durable, reusable information worth carrying into future sessions.", extractionPrompt);
55
+ const llmMs = Date.now() - t;
56
+ t = Date.now();
57
+ const entries = parseExtractionResponse(response, this.options.maxCount);
58
+ const parseMs = Date.now() - t;
59
+ t = Date.now();
60
+ // Route by scope (用户拍板 审批门): "project" memories auto-land in the
61
+ // per-project store (`mm`). "global" memories do NOT auto-land global —
62
+ // they go to the GLOBAL pending scope and wait for the user to approve in
63
+ // the settings panel. Nothing auto-writes the injected global store.
64
+ let pendingMm = null;
65
+ let globalCount = 0;
66
+ for (const entry of entries) {
67
+ const isGlobal = entry.scope === "global";
68
+ const target = isGlobal
69
+ ? (pendingMm ??= new MemoryManager({ scope: "pending" }))
70
+ : mm;
71
+ target.save({
72
+ type: entry.type,
73
+ name: entry.name,
74
+ // Defense-in-depth: the extraction prompt forbids secrets, but a prompt
75
+ // is not a guarantee. An auto-extracted memory is persisted with no user
76
+ // review, so run the model-authored strings through the same
77
+ // redactSecrets the logging path uses — a leaked key never lands on disk.
78
+ description: redactSecrets(entry.description),
79
+ content: redactSecrets(entry.content),
80
+ // Provenance mark (feedback#18 方案 C): extractor writes are "auto"
81
+ // so the UI can tell curated memories from extractor noise.
82
+ origin: "auto",
83
+ // 审批门: stamp the source project on pending entries so "不批准/降级"
84
+ // can fall them back to the project they were extracted in.
85
+ ...(isGlobal && this.options.projectDir
86
+ ? { originProject: this.options.projectDir }
87
+ : {}),
88
+ });
89
+ if (isGlobal)
90
+ globalCount++;
91
+ }
92
+ const saveMs = Date.now() - t;
93
+ extracted = entries.length;
94
+ logger.info("memory.extraction_done", {
95
+ sessionId,
96
+ extracted,
97
+ pendingGlobalCount: globalCount, // global candidates queued for approval
98
+ projectCount: extracted - globalCount,
99
+ elapsedMs: Date.now() - startTime,
100
+ loadMs,
101
+ promptMs,
102
+ llmMs,
103
+ parseMs,
104
+ saveMs,
105
+ existingCount: existing.length,
106
+ transcriptMessages: transcript.length,
107
+ responseChars: response.length,
108
+ });
109
+ }
110
+ catch (err) {
111
+ logger.warn("memory.extraction_failed", {
112
+ sessionId,
113
+ error: err.message,
49
114
  });
50
115
  }
51
- extracted = entries.length;
52
- logger.info("memory.extraction_done", {
53
- sessionId,
54
- extracted,
55
- elapsedMs: Date.now() - startTime,
56
- });
57
- }
58
- catch (err) {
59
- logger.warn("memory.extraction_failed", {
60
- sessionId,
61
- error: err.message,
62
- });
63
- }
64
116
  // --------------- 2. Session summary ---------------
65
117
  try {
66
118
  // Only summarise sessions with enough content to be meaningful.
@@ -68,9 +120,23 @@ export class MemoryOrchestrator {
68
120
  if (messageCount >= 3) {
69
121
  const smPrompt = buildSessionMemoryPrompt(transcript);
70
122
  const smResponse = await this.options.callLLM("You are a session summariser. Output only valid JSON.", smPrompt);
71
- const jsonMatch = smResponse.match(/\{[\s\S]*\}/);
72
- if (jsonMatch) {
73
- const parsed = JSON.parse(jsonMatch[0]);
123
+ // LLM 摘要常带 markdown 围栏 / 围栏外解释文字 / 末尾逗号 → 裸 JSON.parse 易碎。
124
+ // 复用 utils/json 的 extractJSON(剥围栏 + 花括号配平,识别字符串/转义)拿到候选,
125
+ // 解析失败再修一次常见错误(末尾逗号),都不行才放弃(走 catch,该 session 无摘要)
126
+ const candidate = extractJSON(smResponse);
127
+ let parsed = null;
128
+ try {
129
+ parsed = JSON.parse(candidate);
130
+ }
131
+ catch {
132
+ try {
133
+ parsed = JSON.parse(candidate.replace(/,(\s*[}\]])/g, "$1"));
134
+ }
135
+ catch {
136
+ parsed = null;
137
+ }
138
+ }
139
+ if (parsed) {
74
140
  saveSessionMemory({
75
141
  sessionId,
76
142
  summary: String(parsed.summary ?? "").slice(0, 1000),
@@ -99,14 +165,17 @@ export class MemoryOrchestrator {
99
165
  let dreamTriggered = false;
100
166
  try {
101
167
  if (shouldAutoDream() && this.options.runDream) {
102
- // Dream sees BOTH scopes — user/ is read-only context so it can spot
103
- // duplicates spanning scopes, dream/ is the workspace it edits.
168
+ // Dream sees project user/ (read-only context) + project dream/
169
+ // (workspace) + global dream/ (cross-project workspace it also cleans).
104
170
  const userMems = mm.loadScope("user");
105
171
  const dreamMems = mm.loadScope("dream");
106
- if (userMems.length + dreamMems.length > 0) {
172
+ const globalDreamMems = this.options.projectDir
173
+ ? new MemoryManager({ scope: "dream" }).loadScope("dream")
174
+ : [];
175
+ if (userMems.length + dreamMems.length + globalDreamMems.length > 0) {
107
176
  const ran = await this.options.runDream({
108
177
  systemPrompt: buildDreamSystemPrompt(),
109
- userPrompt: buildDreamUserPrompt(userMems, dreamMems),
178
+ userPrompt: buildDreamUserPrompt(userMems, dreamMems, globalDreamMems),
110
179
  projectDir: this.options.projectDir,
111
180
  });
112
181
  if (ran) {
@@ -128,6 +197,30 @@ export class MemoryOrchestrator {
128
197
  error: err.message,
129
198
  });
130
199
  }
131
- return { extracted, dreamTriggered };
200
+ // --------------- 5. Recall-based TTL sweep (用户拍板 C) ---------------
201
+ // Soft-delete project-type memories not read for recallTtlDays. Runs on
202
+ // both the project store and the global store (global also accumulates
203
+ // project-type events if the LLM mis-scopes). Never throws into the result.
204
+ const pruned = [];
205
+ try {
206
+ const ttl = this.options.recallTtlDays;
207
+ if (ttl && ttl > 0) {
208
+ pruned.push(...mm.pruneByRecall(ttl));
209
+ // Only sweep the global store when we're not already it (projectDir set).
210
+ if (this.options.projectDir) {
211
+ pruned.push(...new MemoryManager({ scope: "user" }).pruneByRecall(ttl));
212
+ }
213
+ if (pruned.length > 0) {
214
+ logger.info("memory.recall_ttl_pruned", { sessionId, pruned, ttlDays: ttl });
215
+ }
216
+ }
217
+ }
218
+ catch (err) {
219
+ logger.warn("memory.recall_ttl_failed", {
220
+ sessionId,
221
+ error: err.message,
222
+ });
223
+ }
224
+ return { extracted, dreamTriggered, pruned };
132
225
  }
133
226
  }
@@ -15,6 +15,14 @@ export interface NotificationOptions {
15
15
  * Send a desktop notification.
16
16
  */
17
17
  export declare function notify(options: NotificationOptions): void;
18
+ /** Escape a string for embedding inside an AppleScript double-quoted literal. */
19
+ export declare function escapeAppleScriptString(str: string): string;
20
+ /** Build the osascript argv (a single `-e <script>` pair). */
21
+ export declare function buildOsascriptArgs(title: string, message: string, sound: boolean): string[];
22
+ /** Build the notify-send argv with title/message as separate tokens. */
23
+ export declare function buildNotifySendArgs(title: string, message: string, urgency: "low" | "normal" | "critical"): string[];
24
+ /** Build the powershell.exe argv (a single `-Command <script>` element). */
25
+ export declare function buildPowershellArgs(title: string, message: string): string[];
18
26
  /**
19
27
  * Send a notification that a task/agent has completed.
20
28
  */
@@ -4,7 +4,7 @@
4
4
  * Sends notifications when tasks complete, agents finish, or errors occur.
5
5
  * Falls back gracefully when no notification system is available.
6
6
  */
7
- import { execSync } from "node:child_process";
7
+ import { execFileSync } from "node:child_process";
8
8
  /**
9
9
  * Send a desktop notification.
10
10
  */
@@ -12,37 +12,54 @@ export function notify(options) {
12
12
  const { title, message, sound = false, urgency = "normal" } = options;
13
13
  try {
14
14
  if (process.platform === "darwin") {
15
- // macOS: osascript
16
- const soundFlag = sound ? 'sound name "default"' : "";
17
- execSync(`osascript -e 'display notification "${escape(message)}" with title "${escape(title)}" ${soundFlag}'`, { timeout: 5000 });
15
+ // macOS: osascript. Pass the script as a single -e argv element via
16
+ // execFileSync (no shell), so title/message are never seen by the shell.
17
+ execFileSync("osascript", buildOsascriptArgs(title, message, sound), { timeout: 5000 });
18
18
  }
19
19
  else if (process.platform === "linux") {
20
- // Linux: notify-send
21
- const urgencyFlag = urgency === "critical" ? "-u critical" : urgency === "low" ? "-u low" : "-u normal";
22
- execSync(`notify-send ${urgencyFlag} "${escape(title)}" "${escape(message)}"`, {
23
- timeout: 5000,
24
- });
20
+ // Linux: notify-send. argv keeps title/message as separate tokens.
21
+ execFileSync("notify-send", buildNotifySendArgs(title, message, urgency), { timeout: 5000 });
25
22
  }
26
23
  else if (process.platform === "win32") {
27
- // Windows: PowerShell toast
28
- const ps = `
29
- [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
30
- $xml = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)
31
- $text = $xml.GetElementsByTagName('text')
32
- $text[0].AppendChild($xml.CreateTextNode('${escape(title)}')) | Out-Null
33
- $text[1].AppendChild($xml.CreateTextNode('${escape(message)}')) | Out-Null
34
- $toast = [Windows.UI.Notifications.ToastNotification]::new($xml)
35
- [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('CodeShell').Show($toast)
36
- `.trim();
37
- execSync(`powershell.exe -NoProfile -Command "${ps.replace(/\n/g, "; ")}"`, {
38
- timeout: 5000,
39
- });
24
+ // Windows: PowerShell toast. The script is one -Command argv element
25
+ // (no outer shell); title/message are escaped for PowerShell single
26
+ // quotes (' '').
27
+ execFileSync("powershell.exe", buildPowershellArgs(title, message), { timeout: 5000 });
40
28
  }
41
29
  }
42
30
  catch {
43
31
  // Silently fail — notifications are best-effort
44
32
  }
45
33
  }
34
+ /** Escape a string for embedding inside an AppleScript double-quoted literal. */
35
+ export function escapeAppleScriptString(str) {
36
+ return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, " ");
37
+ }
38
+ /** Build the osascript argv (a single `-e <script>` pair). */
39
+ export function buildOsascriptArgs(title, message, sound) {
40
+ const soundClause = sound ? ' sound name "default"' : "";
41
+ const script = `display notification "${escapeAppleScriptString(message)}"` +
42
+ ` with title "${escapeAppleScriptString(title)}"${soundClause}`;
43
+ return ["-e", script];
44
+ }
45
+ /** Build the notify-send argv with title/message as separate tokens. */
46
+ export function buildNotifySendArgs(title, message, urgency) {
47
+ return ["-u", urgency, title, message];
48
+ }
49
+ /** Build the powershell.exe argv (a single `-Command <script>` element). */
50
+ export function buildPowershellArgs(title, message) {
51
+ const esc = (s) => s.replace(/'/g, "''").replace(/\n/g, " ");
52
+ const ps = [
53
+ "[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null",
54
+ "$xml = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)",
55
+ "$text = $xml.GetElementsByTagName('text')",
56
+ `$text[0].AppendChild($xml.CreateTextNode('${esc(title)}')) | Out-Null`,
57
+ `$text[1].AppendChild($xml.CreateTextNode('${esc(message)}')) | Out-Null`,
58
+ "$toast = [Windows.UI.Notifications.ToastNotification]::new($xml)",
59
+ "[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('CodeShell').Show($toast)",
60
+ ].join("; ");
61
+ return ["-NoProfile", "-Command", ps];
62
+ }
46
63
  /**
47
64
  * Send a notification that a task/agent has completed.
48
65
  */
@@ -64,6 +81,3 @@ export function notifyError(context, error) {
64
81
  urgency: "critical",
65
82
  });
66
83
  }
67
- function escape(str) {
68
- return str.replace(/['"\\]/g, "\\$&").replace(/\n/g, " ");
69
- }
@@ -5,7 +5,8 @@
5
5
  */
6
6
  import { createServer } from "node:http";
7
7
  import { randomBytes, createHash } from "node:crypto";
8
- import { exec } from "node:child_process";
8
+ import { execFile } from "node:child_process";
9
+ import { browserOpenCommand } from "./browser-open.js";
9
10
  /**
10
11
  * Generate PKCE code verifier and challenge.
11
12
  */
@@ -18,12 +19,9 @@ function generatePKCE() {
18
19
  * Open a URL in the system browser.
19
20
  */
20
21
  function openBrowser(url) {
21
- const cmd = process.platform === "darwin"
22
- ? `open "${url}"`
23
- : process.platform === "win32"
24
- ? `start "${url}"`
25
- : `xdg-open "${url}"`;
26
- exec(cmd, () => { });
22
+ // execFile with an argv array — no shell, so the URL can't be interpreted.
23
+ const { cmd, args } = browserOpenCommand(process.platform, url);
24
+ execFile(cmd, args, () => { });
27
25
  }
28
26
  /**
29
27
  * Run the OAuth authorization code flow.
@@ -0,0 +1,8 @@
1
+ import type { SessionMemoryEntry } from "./session-memory.js";
2
+ /**
3
+ * Order session memories most-recent-first by their `createdAt` field. The
4
+ * caller previously sorted by filename (= sessionId), which has no
5
+ * chronological meaning (review-2026-05-30). Returns a new array; input is not
6
+ * mutated.
7
+ */
8
+ export declare function sortSessionMemoriesByRecency(entries: SessionMemoryEntry[]): SessionMemoryEntry[];
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Order session memories most-recent-first by their `createdAt` field. The
3
+ * caller previously sorted by filename (= sessionId), which has no
4
+ * chronological meaning (review-2026-05-30). Returns a new array; input is not
5
+ * mutated.
6
+ */
7
+ export function sortSessionMemoriesByRecency(entries) {
8
+ return [...entries].sort((a, b) => (a.createdAt < b.createdAt ? 1 : a.createdAt > b.createdAt ? -1 : 0));
9
+ }