@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
@@ -19,7 +19,16 @@
19
19
  * Deletes are SOFT — files are moved to <baseDir>/memory-trash/<ISO>/<scope>/
20
20
  * rather than removed, so accidental deletions are recoverable.
21
21
  */
22
- export type MemoryScope = "user" | "dream";
22
+ /**
23
+ * Memory scopes (storage subdirs under a memory root):
24
+ * - user user-owned; tool writes here are permission-gated
25
+ * - dream the auto-consolidation workspace (LLM free-write)
26
+ * - pending 待审批门 (用户拍板): auto-extracted memories the LLM 判为"提全局"
27
+ * land here (global root only) and are NOT injected. The user
28
+ * approves (→ moves to user/) or rejects (→ trash) in the settings
29
+ * panel. Keeps the global layer curated — nothing auto-lands global.
30
+ */
31
+ export type MemoryScope = "user" | "dream" | "pending";
23
32
  export interface MemoryEntry {
24
33
  name: string;
25
34
  description: string;
@@ -27,7 +36,45 @@ export interface MemoryEntry {
27
36
  content: string;
28
37
  fileName: string;
29
38
  scope: MemoryScope;
39
+ /** File mtime in epoch ms — drives maxAge filtering (TODO 8.1). 0 if unknown. */
40
+ updatedAt?: number;
41
+ /**
42
+ * 固定/置顶 (feedback#18 方案 A): a pinned memory is exempt from maxAge
43
+ * injection filtering and sorts first in the injected context. UI surfaces
44
+ * pin/unpin; auto flows never set it.
45
+ */
46
+ pinned?: boolean;
47
+ /**
48
+ * Provenance (方案 C): "auto" = written by the end-of-session extractor,
49
+ * "manual" (or absent — legacy files) = written by the user/UI. Lets the
50
+ * UI distinguish curated memories from extractor noise.
51
+ */
52
+ origin?: "auto" | "manual";
53
+ /**
54
+ * Recall lifecycle (召回 TTL). `usageCount` increments each time MemoryRead
55
+ * hits this entry; `lastUsed` is the ISO timestamp of that last hit; `created`
56
+ * is set on first save and preserved across UPDATE. Drives recall-based TTL:
57
+ * a `project`-type memory not read for N days is pruned. Stored in frontmatter
58
+ * — no SQLite. Legacy files lacking these fields read back as
59
+ * {usageCount:0, lastUsed/created ← mtime}, never hidden.
60
+ */
61
+ usageCount?: number;
62
+ lastUsed?: string;
63
+ created?: string;
64
+ /**
65
+ * 审批门 (用户拍板): for `pending`-scope entries, the project cwd the memory
66
+ * was extracted in. On "不批准/降级" the entry falls back to THIS project's
67
+ * user store (not the current one). Absent → fall back to no-repo / global.
68
+ */
69
+ originProject?: string;
30
70
  }
71
+ /**
72
+ * Drop memories older than `maxAgeDays` (by file mtime) for context injection
73
+ * (TODO 8.1). A non-positive/undefined maxAge means no filtering. Entries with
74
+ * an unknown mtime (updatedAt 0/undefined) are KEPT — we never hide a memory
75
+ * just because we couldn't read its timestamp. Pure + testable.
76
+ */
77
+ export declare function filterByAge(entries: MemoryEntry[], maxAgeDays?: number, now?: number): MemoryEntry[];
31
78
  export interface MemoryManagerOptions {
32
79
  /** Project root path; when set, memories are scoped under projects/<hash>/memory. */
33
80
  projectDir?: string;
@@ -61,12 +108,57 @@ export declare class MemoryManager {
61
108
  * Load a single memory file.
62
109
  */
63
110
  private loadFile;
111
+ /**
112
+ * Parse a memory file's frontmatter + body into a MemoryEntry. Shared by both
113
+ * loadFile (own scope) and loadScope (cross-scope) so the parsing of every
114
+ * field — including the lifecycle fields — lives in exactly one place.
115
+ * Returns null on missing file / unparseable frontmatter.
116
+ */
117
+ private parseMemoryFile;
64
118
  /**
65
119
  * Soft-delete a memory by name or filename — moves the file into
66
120
  * <baseDir>/memory-trash/<ISO>/<scope>/ instead of unlinking it. The user
67
121
  * can recover by moving it back; we never hard-delete from this code path.
68
122
  */
69
123
  delete(nameOrFile: string): boolean;
124
+ /**
125
+ * Record a recall: a MemoryRead hit this entry. Bumps usageCount and sets
126
+ * lastUsed=now, rewriting only the frontmatter (content untouched). This is
127
+ * the signal that drives recall-based TTL — a memory that keeps getting read
128
+ * never ages out. Idempotent-safe: missing entry → false, no throw.
129
+ */
130
+ recordRecall(nameOrFile: string, now?: Date): boolean;
131
+ /**
132
+ * Recall-based TTL sweep. Soft-deletes `project`-type memories not read for
133
+ * more than `ttlDays` (by lastUsed). Stable types (user/feedback/reference)
134
+ * and pinned entries are NEVER pruned — only ephemeral project events age out.
135
+ * Returns the names pruned. ttlDays<=0 disables the sweep.
136
+ */
137
+ pruneByRecall(ttlDays: number, now?: Date): string[];
138
+ /**
139
+ * Approve a pending memory: move it from the pending scope into the user scope
140
+ * of the SAME memory root (pending only ever exists at the global root — the
141
+ * approval门 only gates global writes). Must be called on a pending-scope
142
+ * manager. Returns the new user filename, or null if not found / wrong scope.
143
+ *
144
+ * 审批门 (用户拍板): the only path that moves an auto-extracted memory into the
145
+ * curated, injected global user store.
146
+ */
147
+ approvePending(nameOrFile: string): string | null;
148
+ /**
149
+ * Demote a pending memory: 不批准升全局,但它仍是有用记忆 → 落回它来源项目的
150
+ * user store (originProject)。无 originProject 时落全局 user(兜底,不丢)。
151
+ */
152
+ demotePending(nameOrFile: string): string | null;
153
+ /** Shared move for approve(→global user)/demote(→origin-project user). */
154
+ private movePending;
155
+ /**
156
+ * Promote a project-level user memory to the GLOBAL user store (用户手动点
157
+ * "提升到全局")。Must be called on a project-scoped user manager. Copies the
158
+ * entry into global user/ and soft-deletes the project copy. Returns the new
159
+ * global filename, or null if not found.
160
+ */
161
+ promoteToGlobal(nameOrFile: string): string | null;
70
162
  /**
71
163
  * Get the MEMORY.md index content for injection into prompts.
72
164
  */
@@ -78,7 +170,29 @@ export declare class MemoryManager {
78
170
  * tagged with their origin so the model can tell user-owned from
79
171
  * dream-generated.
80
172
  */
81
- buildMemoryContext(): string;
173
+ buildMemoryContext(opts?: {
174
+ maxAgeDays?: number;
175
+ now?: number;
176
+ }): string;
177
+ /**
178
+ * Two-layer injection index (用户拍板). Merges GLOBAL (cross-project
179
+ * experience) + PROJECT (this repo's facts) memories into a compact index —
180
+ * one line per entry, name + description only, NO body. The model reads a
181
+ * specific entry's full content on demand via MemoryRead (which records a
182
+ * recall → drives TTL + UI visibility).
183
+ *
184
+ * This is what fixes "global memory never shows up": global memories are now
185
+ * injected alongside project ones, every session, regardless of cwd.
186
+ *
187
+ * Static because it must construct two managers (global = no projectDir,
188
+ * project = with projectDir). `projectDir` undefined → only global is shown.
189
+ */
190
+ static buildInjectionIndex(opts: {
191
+ projectDir?: string;
192
+ baseDir?: string;
193
+ maxAgeDays?: number;
194
+ now?: number;
195
+ }): string;
82
196
  /**
83
197
  * Load every entry belonging to the given scope, without changing the
84
198
  * manager's own scope. Used by buildMemoryContext to merge user + dream
@@ -22,13 +22,32 @@
22
22
  import { mkdirSync, existsSync, readFileSync, writeFileSync, readdirSync, renameSync, statSync, } from "node:fs";
23
23
  import { join } from "node:path";
24
24
  import { homedir } from "node:os";
25
+ /**
26
+ * Drop memories older than `maxAgeDays` (by file mtime) for context injection
27
+ * (TODO 8.1). A non-positive/undefined maxAge means no filtering. Entries with
28
+ * an unknown mtime (updatedAt 0/undefined) are KEPT — we never hide a memory
29
+ * just because we couldn't read its timestamp. Pure + testable.
30
+ */
31
+ export function filterByAge(entries, maxAgeDays, now = Date.now()) {
32
+ if (!maxAgeDays || maxAgeDays <= 0)
33
+ return entries;
34
+ const cutoff = now - maxAgeDays * 24 * 60 * 60 * 1000;
35
+ // Pinned memories never age out of injection — that's the point of the pin.
36
+ return entries.filter((e) => e.pinned || !e.updatedAt || e.updatedAt >= cutoff);
37
+ }
25
38
  export function resolveMemoryBaseDir(override) {
26
39
  if (override)
27
40
  return override;
28
41
  const fromEnv = process.env.CODE_SHELL_HOME;
29
42
  if (fromEnv && fromEnv.length > 0)
30
43
  return fromEnv;
31
- return join(homedir(), ".code-shell");
44
+ // `process.env.HOME ?? homedir()` (NOT raw homedir()): bun caches homedir()
45
+ // at process start and never re-reads it, so a test's HOME override — and any
46
+ // code that relies on $HOME — would be ignored, and memory would read the
47
+ // REAL ~/.code-shell (leaking global memories into isolated tests). See the
48
+ // homedir()-cache trap; mirrors settings/manager.ts userHome().
49
+ const home = process.env.HOME ?? homedir();
50
+ return join(home, ".code-shell");
32
51
  }
33
52
  export class MemoryManager {
34
53
  baseDir;
@@ -72,10 +91,29 @@ export class MemoryManager {
72
91
  save(entry) {
73
92
  const fileName = this.slugify(entry.name) + ".md";
74
93
  const filePath = join(this.memoryDir, fileName);
94
+ const nowIso = new Date().toISOString();
95
+ // Overwrite = UPDATE: preserve the original `created` and accumulated
96
+ // `usageCount` of the file being replaced (only `created` is load-bearing
97
+ // for TTL; carrying usageCount avoids resetting a popular memory's score).
98
+ // explicit entry fields win over the existing file (lets callers force a value).
99
+ const existing = existsSync(filePath) ? this.loadFile(fileName) : null;
100
+ const created = entry.created ?? existing?.created ?? nowIso;
101
+ const usageCount = entry.usageCount ?? existing?.usageCount ?? 0;
102
+ const lastUsed = entry.lastUsed ?? existing?.lastUsed ?? created;
103
+ const originProject = entry.originProject ?? existing?.originProject;
104
+ // pinned/origin are written only when meaningful so legacy-shaped files
105
+ // stay byte-identical for unpinned manual saves. Lifecycle fields are
106
+ // always written now (created/lastUsed/usageCount) — they're how TTL works.
75
107
  const content = `---\n` +
76
108
  `name: ${entry.name}\n` +
77
109
  `description: ${entry.description}\n` +
78
110
  `type: ${entry.type}\n` +
111
+ (entry.pinned ? `pinned: true\n` : "") +
112
+ (entry.origin ? `origin: ${entry.origin}\n` : "") +
113
+ (originProject ? `originProject: ${originProject}\n` : "") +
114
+ `created: ${created}\n` +
115
+ `lastUsed: ${lastUsed}\n` +
116
+ `usageCount: ${usageCount}\n` +
79
117
  `---\n\n` +
80
118
  `${entry.content}\n`;
81
119
  writeFileSync(filePath, content, "utf-8");
@@ -107,6 +145,17 @@ export class MemoryManager {
107
145
  */
108
146
  loadFile(fileName) {
109
147
  const filePath = join(this.memoryDir, fileName);
148
+ if (!existsSync(filePath))
149
+ return null;
150
+ return this.loadFileFromDir(this.memoryDir, fileName, this.scope);
151
+ }
152
+ /**
153
+ * Parse a memory file's frontmatter + body into a MemoryEntry. Shared by both
154
+ * loadFile (own scope) and loadScope (cross-scope) so the parsing of every
155
+ * field — including the lifecycle fields — lives in exactly one place.
156
+ * Returns null on missing file / unparseable frontmatter.
157
+ */
158
+ parseMemoryFile(filePath, fileName, scope) {
110
159
  if (!existsSync(filePath))
111
160
  return null;
112
161
  try {
@@ -119,7 +168,30 @@ export class MemoryManager {
119
168
  const name = frontmatter.match(/name:\s*(.+)/)?.[1]?.trim() ?? fileName;
120
169
  const description = frontmatter.match(/description:\s*(.+)/)?.[1]?.trim() ?? "";
121
170
  const type = (frontmatter.match(/type:\s*(.+)/)?.[1]?.trim() ?? "project");
122
- return { name, description, type, content, fileName, scope: this.scope };
171
+ const pinned = frontmatter.match(/pinned:\s*(.+)/)?.[1]?.trim() === "true";
172
+ // Anchor with ^…/m so `origin:` doesn't accidentally match the
173
+ // `originProject:` line (and vice-versa).
174
+ const originRaw = frontmatter.match(/^origin:\s*(.+)/m)?.[1]?.trim();
175
+ const origin = originRaw === "auto" || originRaw === "manual" ? originRaw : undefined;
176
+ const originProject = frontmatter.match(/^originProject:\s*(.+)/m)?.[1]?.trim() || undefined;
177
+ let updatedAt = 0;
178
+ try {
179
+ updatedAt = statSync(filePath).mtimeMs;
180
+ }
181
+ catch {
182
+ // mtime best-effort; 0 = unknown (never filtered out by maxAge).
183
+ }
184
+ // Lifecycle fields. Legacy files lack them → fall back to mtime so a TTL
185
+ // sweep treats them as "last used = file age" rather than "never used".
186
+ const mtimeIso = updatedAt > 0 ? new Date(updatedAt).toISOString() : undefined;
187
+ const created = frontmatter.match(/created:\s*(.+)/)?.[1]?.trim() || mtimeIso;
188
+ const lastUsed = frontmatter.match(/lastUsed:\s*(.+)/)?.[1]?.trim() || created;
189
+ const usageRaw = frontmatter.match(/usageCount:\s*(\d+)/)?.[1];
190
+ const usageCount = usageRaw ? parseInt(usageRaw, 10) : 0;
191
+ return {
192
+ name, description, type, content, fileName, scope,
193
+ updatedAt, pinned, origin, usageCount, lastUsed, created, originProject,
194
+ };
123
195
  }
124
196
  catch {
125
197
  return null;
@@ -149,6 +221,129 @@ export class MemoryManager {
149
221
  return false;
150
222
  }
151
223
  }
224
+ /**
225
+ * Record a recall: a MemoryRead hit this entry. Bumps usageCount and sets
226
+ * lastUsed=now, rewriting only the frontmatter (content untouched). This is
227
+ * the signal that drives recall-based TTL — a memory that keeps getting read
228
+ * never ages out. Idempotent-safe: missing entry → false, no throw.
229
+ */
230
+ recordRecall(nameOrFile, now = new Date()) {
231
+ const entry = this.loadAll().find((e) => e.name === nameOrFile || e.fileName === nameOrFile);
232
+ if (!entry)
233
+ return false;
234
+ try {
235
+ this.save({
236
+ name: entry.name,
237
+ description: entry.description,
238
+ type: entry.type,
239
+ content: entry.content,
240
+ pinned: entry.pinned,
241
+ origin: entry.origin,
242
+ created: entry.created,
243
+ usageCount: (entry.usageCount ?? 0) + 1,
244
+ lastUsed: now.toISOString(),
245
+ });
246
+ return true;
247
+ }
248
+ catch {
249
+ return false;
250
+ }
251
+ }
252
+ /**
253
+ * Recall-based TTL sweep. Soft-deletes `project`-type memories not read for
254
+ * more than `ttlDays` (by lastUsed). Stable types (user/feedback/reference)
255
+ * and pinned entries are NEVER pruned — only ephemeral project events age out.
256
+ * Returns the names pruned. ttlDays<=0 disables the sweep.
257
+ */
258
+ pruneByRecall(ttlDays, now = new Date()) {
259
+ if (!ttlDays || ttlDays <= 0)
260
+ return [];
261
+ const cutoff = now.getTime() - ttlDays * 24 * 60 * 60 * 1000;
262
+ const pruned = [];
263
+ for (const e of this.loadAll()) {
264
+ if (e.type !== "project")
265
+ continue; // stable types are exempt
266
+ if (e.pinned)
267
+ continue; // pinned exempt
268
+ const lastUsedMs = e.lastUsed ? new Date(e.lastUsed).getTime() : NaN;
269
+ // Unknown lastUsed (unparseable) → keep, never prune on missing data.
270
+ if (!Number.isFinite(lastUsedMs))
271
+ continue;
272
+ if (lastUsedMs < cutoff) {
273
+ if (this.delete(e.name))
274
+ pruned.push(e.name);
275
+ }
276
+ }
277
+ return pruned;
278
+ }
279
+ /**
280
+ * Approve a pending memory: move it from the pending scope into the user scope
281
+ * of the SAME memory root (pending only ever exists at the global root — the
282
+ * approval门 only gates global writes). Must be called on a pending-scope
283
+ * manager. Returns the new user filename, or null if not found / wrong scope.
284
+ *
285
+ * 审批门 (用户拍板): the only path that moves an auto-extracted memory into the
286
+ * curated, injected global user store.
287
+ */
288
+ approvePending(nameOrFile) {
289
+ return this.movePending(nameOrFile, "global");
290
+ }
291
+ /**
292
+ * Demote a pending memory: 不批准升全局,但它仍是有用记忆 → 落回它来源项目的
293
+ * user store (originProject)。无 originProject 时落全局 user(兜底,不丢)。
294
+ */
295
+ demotePending(nameOrFile) {
296
+ return this.movePending(nameOrFile, "project");
297
+ }
298
+ /** Shared move for approve(→global user)/demote(→origin-project user). */
299
+ movePending(nameOrFile, dest) {
300
+ if (this.scope !== "pending")
301
+ return null;
302
+ const entry = this.loadAll().find((e) => e.name === nameOrFile || e.fileName === nameOrFile);
303
+ if (!entry)
304
+ return null;
305
+ const targetMgr = dest === "project" && entry.originProject
306
+ ? new MemoryManager({ baseDir: this.baseDir, projectDir: entry.originProject, scope: "user" })
307
+ : new MemoryManager({ baseDir: this.baseDir, scope: "user" }); // global, or fallback
308
+ const fileName = targetMgr.save({
309
+ name: entry.name,
310
+ description: entry.description,
311
+ type: entry.type,
312
+ content: entry.content,
313
+ origin: entry.origin ?? "auto",
314
+ created: entry.created,
315
+ lastUsed: entry.lastUsed,
316
+ usageCount: entry.usageCount,
317
+ // originProject is no longer needed once it has landed in a real store.
318
+ });
319
+ this.delete(entry.name); // soft-delete the pending copy
320
+ return fileName;
321
+ }
322
+ /**
323
+ * Promote a project-level user memory to the GLOBAL user store (用户手动点
324
+ * "提升到全局")。Must be called on a project-scoped user manager. Copies the
325
+ * entry into global user/ and soft-deletes the project copy. Returns the new
326
+ * global filename, or null if not found.
327
+ */
328
+ promoteToGlobal(nameOrFile) {
329
+ const entry = this.loadAll().find((e) => e.name === nameOrFile || e.fileName === nameOrFile);
330
+ if (!entry)
331
+ return null;
332
+ const globalMgr = new MemoryManager({ baseDir: this.baseDir, scope: "user" });
333
+ const fileName = globalMgr.save({
334
+ name: entry.name,
335
+ description: entry.description,
336
+ type: entry.type,
337
+ content: entry.content,
338
+ origin: entry.origin,
339
+ pinned: entry.pinned,
340
+ created: entry.created,
341
+ lastUsed: entry.lastUsed,
342
+ usageCount: entry.usageCount,
343
+ });
344
+ this.delete(entry.name); // remove from the project store
345
+ return fileName;
346
+ }
152
347
  /**
153
348
  * Get the MEMORY.md index content for injection into prompts.
154
349
  */
@@ -164,20 +359,20 @@ export class MemoryManager {
164
359
  * tagged with their origin so the model can tell user-owned from
165
360
  * dream-generated.
166
361
  */
167
- buildMemoryContext() {
168
- const userEntries = this.scope === "user"
169
- ? this.loadAll()
170
- : this.loadScope("user");
171
- const dreamEntries = this.scope === "dream"
172
- ? this.loadAll()
173
- : this.loadScope("dream");
362
+ buildMemoryContext(opts) {
363
+ const userEntries = filterByAge(this.scope === "user" ? this.loadAll() : this.loadScope("user"), opts?.maxAgeDays, opts?.now);
364
+ const dreamEntries = filterByAge(this.scope === "dream" ? this.loadAll() : this.loadScope("dream"), opts?.maxAgeDays, opts?.now);
174
365
  if (userEntries.length === 0 && dreamEntries.length === 0)
175
366
  return "";
367
+ // Pinned memories lead the list so the user's hand-picked context is what
368
+ // the model reads first (sort is stable — unpinned keep their order).
369
+ const pinnedFirst = (a, b) => Number(b.pinned ?? false) - Number(a.pinned ?? false);
370
+ userEntries.sort(pinnedFirst);
176
371
  const lines = [];
177
372
  if (userEntries.length > 0) {
178
373
  lines.push("## User memories (you own these — needs permission to modify)");
179
374
  for (const e of userEntries) {
180
- lines.push(`- [${e.type}] ${e.name}: ${e.description}`);
375
+ lines.push(`- ${e.pinned ? "[pinned] " : ""}[${e.type}] ${e.name}: ${e.description}`);
181
376
  }
182
377
  }
183
378
  if (dreamEntries.length > 0) {
@@ -193,6 +388,50 @@ export class MemoryManager {
193
388
  lines.join("\n") +
194
389
  `\n\nTo read a specific memory, look under ${this.memoryRoot}/{user,dream}/`);
195
390
  }
391
+ /**
392
+ * Two-layer injection index (用户拍板). Merges GLOBAL (cross-project
393
+ * experience) + PROJECT (this repo's facts) memories into a compact index —
394
+ * one line per entry, name + description only, NO body. The model reads a
395
+ * specific entry's full content on demand via MemoryRead (which records a
396
+ * recall → drives TTL + UI visibility).
397
+ *
398
+ * This is what fixes "global memory never shows up": global memories are now
399
+ * injected alongside project ones, every session, regardless of cwd.
400
+ *
401
+ * Static because it must construct two managers (global = no projectDir,
402
+ * project = with projectDir). `projectDir` undefined → only global is shown.
403
+ */
404
+ static buildInjectionIndex(opts) {
405
+ const global = new MemoryManager({ baseDir: opts.baseDir });
406
+ const project = opts.projectDir
407
+ ? new MemoryManager({ baseDir: opts.baseDir, projectDir: opts.projectDir })
408
+ : null;
409
+ const pinnedFirst = (a, b) => Number(b.pinned ?? false) - Number(a.pinned ?? false);
410
+ const collect = (mm) => filterByAge([...mm.loadScope("user"), ...mm.loadScope("dream")], opts.maxAgeDays, opts.now).sort(pinnedFirst);
411
+ const globalEntries = collect(global);
412
+ const projectEntries = project ? collect(project) : [];
413
+ if (globalEntries.length === 0 && projectEntries.length === 0)
414
+ return "";
415
+ const fmt = (e) => `- ${e.pinned ? "[pinned] " : ""}[${e.type}] ${e.name}: ${e.description}`;
416
+ const lines = [];
417
+ if (globalEntries.length > 0) {
418
+ lines.push("## Global memories (apply across all projects)");
419
+ for (const e of globalEntries)
420
+ lines.push(fmt(e));
421
+ }
422
+ if (projectEntries.length > 0) {
423
+ if (lines.length > 0)
424
+ lines.push("");
425
+ lines.push("## Project memories (this repo)");
426
+ for (const e of projectEntries)
427
+ lines.push(fmt(e));
428
+ }
429
+ return (`# Persistent Memory (index)\n\n` +
430
+ `These are summaries of memories from previous sessions. Only the summary is shown here.\n` +
431
+ `When a memory looks relevant to the current task, read its full content with the ` +
432
+ `MemoryRead tool (scope = user or dream; location = global or project) before relying on it.\n\n` +
433
+ lines.join("\n"));
434
+ }
196
435
  /**
197
436
  * Load every entry belonging to the given scope, without changing the
198
437
  * manager's own scope. Used by buildMemoryContext to merge user + dream
@@ -212,24 +451,7 @@ export class MemoryManager {
212
451
  return entries;
213
452
  }
214
453
  loadFileFromDir(dir, fileName, scope) {
215
- const filePath = join(dir, fileName);
216
- if (!existsSync(filePath))
217
- return null;
218
- try {
219
- const raw = readFileSync(filePath, "utf-8");
220
- const frontmatterMatch = raw.match(/^---\n([\s\S]*?)\n---\n\n?([\s\S]*)$/);
221
- if (!frontmatterMatch)
222
- return null;
223
- const frontmatter = frontmatterMatch[1];
224
- const content = frontmatterMatch[2].trim();
225
- const name = frontmatter.match(/name:\s*(.+)/)?.[1]?.trim() ?? fileName;
226
- const description = frontmatter.match(/description:\s*(.+)/)?.[1]?.trim() ?? "";
227
- const type = (frontmatter.match(/type:\s*(.+)/)?.[1]?.trim() ?? "project");
228
- return { name, description, type, content, fileName, scope };
229
- }
230
- catch {
231
- return null;
232
- }
454
+ return this.parseMemoryFile(join(dir, fileName), fileName, scope);
233
455
  }
234
456
  /**
235
457
  * Move pre-scope flat-layout entries (entries that lived directly under
@@ -7,6 +7,28 @@ export interface SessionBundle {
7
7
  state: SessionState;
8
8
  transcript: Transcript;
9
9
  }
10
+ /**
11
+ * Validate a session ID before it is joined into a filesystem path.
12
+ *
13
+ * Internally generated IDs use `nanoid(16)` and are trusted by construction.
14
+ * But every public entry point (`create`'s explicitSessionId, `resume`,
15
+ * `exists`, `saveState`'s state.sessionId, `fork`'s sourceSessionId) accepts
16
+ * an ID from an outside caller — protocol clients, ChatSessionManager-driven
17
+ * cold starts, persisted state files — and join()'s it into `sessionsDir`.
18
+ * Without this check a value like "../etc/passwd" or "/tmp/x" would let the
19
+ * caller escape the sessions directory.
20
+ *
21
+ * Exported for direct unit testing.
22
+ */
23
+ export declare function assertSafeSessionId(sessionId: unknown): asserts sessionId is string;
24
+ /**
25
+ * Resolve the `.code-shell` home dir. `CODE_SHELL_HOME` overrides the default
26
+ * `~/.code-shell` — mirrors Codex's `CODEX_HOME`. Tests set it to a temp dir
27
+ * (see bunfig.toml preload) so a `new Engine()` / `new SessionManager()` with
28
+ * no explicit storageDir doesn't pollute the user's real ~/.code-shell/sessions
29
+ * with throwaway test sessions (the rm-usage/test-model sidebar junk).
30
+ */
31
+ export declare function codeShellHome(): string;
10
32
  export declare class SessionManager {
11
33
  private readonly sessionsDir;
12
34
  constructor(storageDir?: string);
@@ -17,13 +39,53 @@ export declare class SessionManager {
17
39
  * nanoid. Either way the on-disk directory is materialized and the
18
40
  * state.json + transcript.jsonl files are written before return.
19
41
  */
20
- create(cwd: string, model: string, provider: string, explicitSessionId?: string): SessionBundle;
42
+ create(cwd: string, model: string, provider: string, explicitSessionId?: string, parentSessionId?: string | null, origin?: import("../types.js").SessionOrigin): SessionBundle;
21
43
  /**
22
44
  * Whether a session directory exists on disk. Used by ChatSession-driven
23
45
  * cold starts to decide between resume vs create-with-explicit-sid
24
46
  * without catching SessionError.
25
47
  */
26
48
  exists(sessionId: string): boolean;
49
+ /**
50
+ * Cheap "what cwd is this session bound to?" probe — reads only state.json,
51
+ * NOT the transcript (unlike resume()). engine.run uses this to recover a
52
+ * resumed session's project directory when the caller omits options.cwd
53
+ * (e.g. a desktop host whose sidebar repo selection has drifted to null),
54
+ * so a project-bound session keeps loading its own agents/settings/memory
55
+ * instead of falling back to process.cwd(). Returns undefined for an
56
+ * unknown, malformed, or traversal-shaped id rather than throwing — the
57
+ * caller treats "no recoverable cwd" the same as "not given".
58
+ */
59
+ readCwd(sessionId: string): string | undefined;
60
+ /**
61
+ * Cheap "does this session have a persisted goal?" probe — reads only
62
+ * state.json, NOT the transcript (like readCwd). A persistent goal lives ONLY
63
+ * in state.activeGoal; it is never appended to the transcript as an event, so
64
+ * a session rebuilt from disk (e.g. localStorage wiped) can't recover the
65
+ * goal from its messages. The desktop host calls this on session load to
66
+ * re-surface the active-goal block + its Cancel button, which would otherwise
67
+ * be invisible (and thus uncancellable) after a reload of an aborted goal
68
+ * run. Returns undefined for an unknown / malformed / traversal-shaped id, or
69
+ * a session with no active goal — never throws.
70
+ */
71
+ readActiveGoal(sessionId: string): import("../engine/goal.js").GoalConfig | undefined;
72
+ /**
73
+ * Disk-only "wipe this session's persistent goal" — the counterpart to
74
+ * readActiveGoal. Reads state.json, removes state.activeGoal, and rewrites it
75
+ * atomically (via saveState). Returns true only if a goal was actually
76
+ * present (idempotent — clearing a session with no goal is a no-op returning
77
+ * false). Never throws on an unknown / malformed / traversal-shaped id
78
+ * (returns false), matching readActiveGoal's tolerance.
79
+ *
80
+ * Why it lives here and not only on Engine: a persistent goal can strand a
81
+ * session whose worker is NOT live (aborted/reloaded) — Engine.clearGoal
82
+ * needs a resumed in-RAM session and a matching in-flight hook, neither of
83
+ * which exists once the worker has exited. Hosts (the desktop bridge) call
84
+ * THIS to clear such a goal off disk without spinning up a full Engine.
85
+ * Engine.clearGoal also delegates its disk write here so the wipe logic lives
86
+ * in exactly one place.
87
+ */
88
+ clearActiveGoal(sessionId: string): boolean;
27
89
  resume(sessionId: string): SessionBundle;
28
90
  saveState(state: SessionState): void;
29
91
  /**