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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/dist/agent/coordinator.d.ts +49 -0
  4. package/dist/agent/coordinator.js +77 -0
  5. package/dist/arena/arena.d.ts +43 -0
  6. package/dist/arena/arena.js +334 -0
  7. package/dist/arena/context/context-tools.d.ts +16 -0
  8. package/dist/arena/context/context-tools.js +231 -0
  9. package/dist/arena/detect-mode.d.ts +20 -0
  10. package/dist/arena/detect-mode.js +78 -0
  11. package/dist/arena/digest-builder.d.ts +25 -0
  12. package/dist/arena/digest-builder.js +120 -0
  13. package/dist/arena/index.d.ts +29 -0
  14. package/dist/arena/index.js +29 -0
  15. package/dist/arena/iterate/convergence.d.ts +25 -0
  16. package/dist/arena/iterate/convergence.js +103 -0
  17. package/dist/arena/iterate/formats/index.d.ts +22 -0
  18. package/dist/arena/iterate/formats/index.js +283 -0
  19. package/dist/arena/iterate/index.d.ts +11 -0
  20. package/dist/arena/iterate/index.js +9 -0
  21. package/dist/arena/iterate/iterative-arena.d.ts +23 -0
  22. package/dist/arena/iterate/iterative-arena.js +237 -0
  23. package/dist/arena/iterate/parse.d.ts +42 -0
  24. package/dist/arena/iterate/parse.js +123 -0
  25. package/dist/arena/iterate/phases/argue.d.ts +22 -0
  26. package/dist/arena/iterate/phases/argue.js +159 -0
  27. package/dist/arena/iterate/phases/revise.d.ts +16 -0
  28. package/dist/arena/iterate/phases/revise.js +62 -0
  29. package/dist/arena/iterate/phases/tournament.d.ts +34 -0
  30. package/dist/arena/iterate/phases/tournament.js +113 -0
  31. package/dist/arena/iterate/tools/web-tools.d.ts +13 -0
  32. package/dist/arena/iterate/tools/web-tools.js +54 -0
  33. package/dist/arena/iterate/types.d.ts +152 -0
  34. package/dist/arena/iterate/types.js +8 -0
  35. package/dist/arena/ledger.d.ts +47 -0
  36. package/dist/arena/ledger.js +151 -0
  37. package/dist/arena/lenses/architecture.d.ts +5 -0
  38. package/dist/arena/lenses/architecture.js +22 -0
  39. package/dist/arena/lenses/engineering.d.ts +5 -0
  40. package/dist/arena/lenses/engineering.js +22 -0
  41. package/dist/arena/lenses/general.d.ts +5 -0
  42. package/dist/arena/lenses/general.js +20 -0
  43. package/dist/arena/lenses/index.d.ts +16 -0
  44. package/dist/arena/lenses/index.js +47 -0
  45. package/dist/arena/lenses/product.d.ts +5 -0
  46. package/dist/arena/lenses/product.js +22 -0
  47. package/dist/arena/model-presets.d.ts +23 -0
  48. package/dist/arena/model-presets.js +44 -0
  49. package/dist/arena/phases/adjudication.d.ts +24 -0
  50. package/dist/arena/phases/adjudication.js +144 -0
  51. package/dist/arena/phases/build-consensus.d.ts +29 -0
  52. package/dist/arena/phases/build-consensus.js +86 -0
  53. package/dist/arena/phases/claim-registry.d.ts +26 -0
  54. package/dist/arena/phases/claim-registry.js +60 -0
  55. package/dist/arena/phases/cross-review.d.ts +45 -0
  56. package/dist/arena/phases/cross-review.js +224 -0
  57. package/dist/arena/phases/debate-rounds.d.ts +27 -0
  58. package/dist/arena/phases/debate-rounds.js +162 -0
  59. package/dist/arena/phases/participant-research.d.ts +38 -0
  60. package/dist/arena/phases/participant-research.js +317 -0
  61. package/dist/arena/phases/planning-detail-expansion.d.ts +38 -0
  62. package/dist/arena/phases/planning-detail-expansion.js +121 -0
  63. package/dist/arena/planner.d.ts +27 -0
  64. package/dist/arena/planner.js +312 -0
  65. package/dist/arena/providers/docs.d.ts +6 -0
  66. package/dist/arena/providers/docs.js +108 -0
  67. package/dist/arena/providers/git.d.ts +8 -0
  68. package/dist/arena/providers/git.js +174 -0
  69. package/dist/arena/providers/index.d.ts +32 -0
  70. package/dist/arena/providers/index.js +132 -0
  71. package/dist/arena/providers/none.d.ts +7 -0
  72. package/dist/arena/providers/none.js +11 -0
  73. package/dist/arena/providers/repo.d.ts +6 -0
  74. package/dist/arena/providers/repo.js +255 -0
  75. package/dist/arena/render/session.d.ts +17 -0
  76. package/dist/arena/render/session.js +190 -0
  77. package/dist/arena/render/terminal.d.ts +34 -0
  78. package/dist/arena/render/terminal.js +286 -0
  79. package/dist/arena/strategies/discussion.d.ts +25 -0
  80. package/dist/arena/strategies/discussion.js +143 -0
  81. package/dist/arena/strategies/index.d.ts +15 -0
  82. package/dist/arena/strategies/index.js +28 -0
  83. package/dist/arena/strategies/language-wrapper.d.ts +17 -0
  84. package/dist/arena/strategies/language-wrapper.js +102 -0
  85. package/dist/arena/strategies/lens-wrapper.d.ts +16 -0
  86. package/dist/arena/strategies/lens-wrapper.js +236 -0
  87. package/dist/arena/strategies/planning.d.ts +30 -0
  88. package/dist/arena/strategies/planning.js +225 -0
  89. package/dist/arena/strategies/review.d.ts +26 -0
  90. package/dist/arena/strategies/review.js +168 -0
  91. package/dist/arena/strategies/utils.d.ts +39 -0
  92. package/dist/arena/strategies/utils.js +647 -0
  93. package/dist/arena/tools/selector.d.ts +17 -0
  94. package/dist/arena/tools/selector.js +61 -0
  95. package/dist/arena/transitions.d.ts +48 -0
  96. package/dist/arena/transitions.js +92 -0
  97. package/dist/arena/types.d.ts +508 -0
  98. package/dist/arena/types.js +27 -0
  99. package/dist/cli/agent-server-stdio.d.ts +32 -0
  100. package/dist/cli/agent-server-stdio.js +116 -0
  101. package/dist/colorizer.d.ts +23 -0
  102. package/dist/colorizer.js +12 -0
  103. package/dist/context/compaction.d.ts +116 -0
  104. package/dist/context/compaction.js +534 -0
  105. package/dist/context/manager.d.ts +145 -0
  106. package/dist/context/manager.js +423 -0
  107. package/dist/context/token-counter.d.ts +27 -0
  108. package/dist/context/token-counter.js +91 -0
  109. package/dist/context/tool-result-storage.d.ts +96 -0
  110. package/dist/context/tool-result-storage.js +296 -0
  111. package/dist/cost-tracker.d.ts +64 -0
  112. package/dist/cost-tracker.js +314 -0
  113. package/dist/cron/scheduler.d.ts +34 -0
  114. package/dist/cron/scheduler.js +115 -0
  115. package/dist/data/deepseek-models.json +46 -0
  116. package/dist/data/gemini-models.json +67 -0
  117. package/dist/data/openai-models.json +175 -0
  118. package/dist/data/openrouter-models.d.ts +35 -0
  119. package/dist/data/openrouter-models.js +36 -0
  120. package/dist/data/openrouter-models.json +4626 -0
  121. package/dist/data/openrouter-sync.d.ts +16 -0
  122. package/dist/data/openrouter-sync.js +53 -0
  123. package/dist/data/static-catalogs.d.ts +25 -0
  124. package/dist/data/static-catalogs.js +26 -0
  125. package/dist/data/zai-models.json +56 -0
  126. package/dist/engine/cost-store.d.ts +22 -0
  127. package/dist/engine/cost-store.js +15 -0
  128. package/dist/engine/engine.d.ts +295 -0
  129. package/dist/engine/engine.js +1467 -0
  130. package/dist/engine/model-facade.d.ts +24 -0
  131. package/dist/engine/model-facade.js +194 -0
  132. package/dist/engine/parse-task.d.ts +59 -0
  133. package/dist/engine/parse-task.js +135 -0
  134. package/dist/engine/patch-orphaned-tools.d.ts +52 -0
  135. package/dist/engine/patch-orphaned-tools.js +95 -0
  136. package/dist/engine/query.d.ts +50 -0
  137. package/dist/engine/query.js +107 -0
  138. package/dist/engine/runtime.d.ts +50 -0
  139. package/dist/engine/runtime.js +59 -0
  140. package/dist/engine/streaming-tool-queue.d.ts +34 -0
  141. package/dist/engine/streaming-tool-queue.js +61 -0
  142. package/dist/engine/token-budget.d.ts +22 -0
  143. package/dist/engine/token-budget.js +40 -0
  144. package/dist/engine/tool-summary.d.ts +13 -0
  145. package/dist/engine/tool-summary.js +35 -0
  146. package/dist/engine/turn-loop.d.ts +122 -0
  147. package/dist/engine/turn-loop.js +602 -0
  148. package/dist/engine/turn-state.d.ts +20 -0
  149. package/dist/engine/turn-state.js +17 -0
  150. package/dist/exceptions.d.ts +61 -0
  151. package/dist/exceptions.js +116 -0
  152. package/dist/git/utils.d.ts +35 -0
  153. package/dist/git/utils.js +98 -0
  154. package/dist/git/worktree.d.ts +36 -0
  155. package/dist/git/worktree.js +139 -0
  156. package/dist/hooks/events.d.ts +114 -0
  157. package/dist/hooks/events.js +4 -0
  158. package/dist/hooks/inject.d.ts +19 -0
  159. package/dist/hooks/inject.js +29 -0
  160. package/dist/hooks/registry.d.ts +15 -0
  161. package/dist/hooks/registry.js +84 -0
  162. package/dist/hooks/shell-runner.d.ts +45 -0
  163. package/dist/hooks/shell-runner.js +173 -0
  164. package/dist/index.d.ts +117 -0
  165. package/dist/index.js +145 -0
  166. package/dist/llm/api-key-sanitize.d.ts +22 -0
  167. package/dist/llm/api-key-sanitize.js +81 -0
  168. package/dist/llm/capabilities/index.d.ts +20 -0
  169. package/dist/llm/capabilities/index.js +39 -0
  170. package/dist/llm/capabilities/rules.d.ts +26 -0
  171. package/dist/llm/capabilities/rules.js +215 -0
  172. package/dist/llm/capabilities/types.d.ts +114 -0
  173. package/dist/llm/capabilities/types.js +24 -0
  174. package/dist/llm/client-base.d.ts +29 -0
  175. package/dist/llm/client-base.js +137 -0
  176. package/dist/llm/client-factory.d.ts +10 -0
  177. package/dist/llm/client-factory.js +29 -0
  178. package/dist/llm/model-cache.d.ts +21 -0
  179. package/dist/llm/model-cache.js +46 -0
  180. package/dist/llm/model-fetcher.d.ts +29 -0
  181. package/dist/llm/model-fetcher.js +282 -0
  182. package/dist/llm/model-pool.d.ts +95 -0
  183. package/dist/llm/model-pool.js +246 -0
  184. package/dist/llm/provider-catalog.d.ts +32 -0
  185. package/dist/llm/provider-catalog.js +50 -0
  186. package/dist/llm/provider-kinds.d.ts +21 -0
  187. package/dist/llm/provider-kinds.js +132 -0
  188. package/dist/llm/providers/anthropic.d.ts +19 -0
  189. package/dist/llm/providers/anthropic.js +267 -0
  190. package/dist/llm/providers/openai.d.ts +64 -0
  191. package/dist/llm/providers/openai.js +606 -0
  192. package/dist/llm/retry.d.ts +12 -0
  193. package/dist/llm/retry.js +17 -0
  194. package/dist/llm/stream-watchdog.d.ts +42 -0
  195. package/dist/llm/stream-watchdog.js +70 -0
  196. package/dist/llm/token-counter.d.ts +17 -0
  197. package/dist/llm/token-counter.js +36 -0
  198. package/dist/llm/types.d.ts +37 -0
  199. package/dist/llm/types.js +4 -0
  200. package/dist/logging/logger.d.ts +109 -0
  201. package/dist/logging/logger.js +390 -0
  202. package/dist/logging/sanitize-messages.d.ts +42 -0
  203. package/dist/logging/sanitize-messages.js +150 -0
  204. package/dist/logging/session-recorder.d.ts +90 -0
  205. package/dist/logging/session-recorder.js +304 -0
  206. package/dist/lsp/client.d.ts +41 -0
  207. package/dist/lsp/client.js +166 -0
  208. package/dist/lsp/manager.d.ts +40 -0
  209. package/dist/lsp/manager.js +124 -0
  210. package/dist/lsp/servers.d.ts +16 -0
  211. package/dist/lsp/servers.js +60 -0
  212. package/dist/migrate-models.d.ts +45 -0
  213. package/dist/migrate-models.js +179 -0
  214. package/dist/onboarding.d.ts +189 -0
  215. package/dist/onboarding.js +625 -0
  216. package/dist/plugins/gitOps.d.ts +32 -0
  217. package/dist/plugins/gitOps.js +62 -0
  218. package/dist/plugins/installedPlugins.d.ts +15 -0
  219. package/dist/plugins/installedPlugins.js +56 -0
  220. package/dist/plugins/knownMarketplaces.d.ts +10 -0
  221. package/dist/plugins/knownMarketplaces.js +46 -0
  222. package/dist/plugins/loadPluginHooks.d.ts +52 -0
  223. package/dist/plugins/loadPluginHooks.js +162 -0
  224. package/dist/plugins/marketplaceManager.d.ts +49 -0
  225. package/dist/plugins/marketplaceManager.js +142 -0
  226. package/dist/plugins/parseMarketplaceInput.d.ts +16 -0
  227. package/dist/plugins/parseMarketplaceInput.js +73 -0
  228. package/dist/plugins/pluginCommandHook.d.ts +54 -0
  229. package/dist/plugins/pluginCommandHook.js +180 -0
  230. package/dist/plugins/pluginCommandsLoader.d.ts +25 -0
  231. package/dist/plugins/pluginCommandsLoader.js +114 -0
  232. package/dist/plugins/pluginInstaller.d.ts +36 -0
  233. package/dist/plugins/pluginInstaller.js +228 -0
  234. package/dist/plugins/schemas.d.ts +9 -0
  235. package/dist/plugins/schemas.js +136 -0
  236. package/dist/plugins/types.d.ts +75 -0
  237. package/dist/plugins/types.js +7 -0
  238. package/dist/plugins/varRewrite.d.ts +42 -0
  239. package/dist/plugins/varRewrite.js +129 -0
  240. package/dist/preset/index.d.ts +60 -0
  241. package/dist/preset/index.js +159 -0
  242. package/dist/product/define.d.ts +60 -0
  243. package/dist/product/define.js +123 -0
  244. package/dist/product/index.d.ts +5 -0
  245. package/dist/product/index.js +4 -0
  246. package/dist/product/types.d.ts +111 -0
  247. package/dist/product/types.js +21 -0
  248. package/dist/prompt/composer.d.ts +49 -0
  249. package/dist/prompt/composer.js +168 -0
  250. package/dist/prompt/instruction-scanner.d.ts +54 -0
  251. package/dist/prompt/instruction-scanner.js +187 -0
  252. package/dist/prompt/section-cache.d.ts +15 -0
  253. package/dist/prompt/section-cache.js +31 -0
  254. package/dist/prompt/section-loader.d.ts +26 -0
  255. package/dist/prompt/section-loader.js +53 -0
  256. package/dist/prompt/sections/base.md +35 -0
  257. package/dist/prompt/sections/coding.md +31 -0
  258. package/dist/prompt/sections/orchestration.md +16 -0
  259. package/dist/prompt/sections/tone.md +9 -0
  260. package/dist/protocol/chat-session-manager.d.ts +33 -0
  261. package/dist/protocol/chat-session-manager.js +65 -0
  262. package/dist/protocol/chat-session.d.ts +49 -0
  263. package/dist/protocol/chat-session.js +86 -0
  264. package/dist/protocol/client.d.ts +104 -0
  265. package/dist/protocol/client.js +260 -0
  266. package/dist/protocol/factories.d.ts +93 -0
  267. package/dist/protocol/factories.js +64 -0
  268. package/dist/protocol/helpers.d.ts +42 -0
  269. package/dist/protocol/helpers.js +55 -0
  270. package/dist/protocol/index.d.ts +4 -0
  271. package/dist/protocol/index.js +4 -0
  272. package/dist/protocol/server.d.ts +80 -0
  273. package/dist/protocol/server.js +855 -0
  274. package/dist/protocol/transport.d.ts +37 -0
  275. package/dist/protocol/transport.js +85 -0
  276. package/dist/protocol/types.d.ts +221 -0
  277. package/dist/protocol/types.js +61 -0
  278. package/dist/remote/bridge.d.ts +37 -0
  279. package/dist/remote/bridge.js +103 -0
  280. package/dist/run/ArtifactTracker.d.ts +38 -0
  281. package/dist/run/ArtifactTracker.js +132 -0
  282. package/dist/run/CheckpointWriter.d.ts +53 -0
  283. package/dist/run/CheckpointWriter.js +135 -0
  284. package/dist/run/EngineRunner.d.ts +72 -0
  285. package/dist/run/EngineRunner.js +119 -0
  286. package/dist/run/Evaluator.d.ts +56 -0
  287. package/dist/run/Evaluator.js +62 -0
  288. package/dist/run/FileRunStore.d.ts +39 -0
  289. package/dist/run/FileRunStore.js +176 -0
  290. package/dist/run/Heartbeat.d.ts +54 -0
  291. package/dist/run/Heartbeat.js +123 -0
  292. package/dist/run/RunApprovalBackend.d.ts +53 -0
  293. package/dist/run/RunApprovalBackend.js +85 -0
  294. package/dist/run/RunLock.d.ts +40 -0
  295. package/dist/run/RunLock.js +98 -0
  296. package/dist/run/RunManager.d.ts +82 -0
  297. package/dist/run/RunManager.js +587 -0
  298. package/dist/run/RunQueue.d.ts +27 -0
  299. package/dist/run/RunQueue.js +73 -0
  300. package/dist/run/RunStore.d.ts +25 -0
  301. package/dist/run/RunStore.js +9 -0
  302. package/dist/run/factory.d.ts +63 -0
  303. package/dist/run/factory.js +51 -0
  304. package/dist/run/index.d.ts +17 -0
  305. package/dist/run/index.js +23 -0
  306. package/dist/run/types.d.ts +136 -0
  307. package/dist/run/types.js +28 -0
  308. package/dist/runtime/safe-spawn.d.ts +118 -0
  309. package/dist/runtime/safe-spawn.js +268 -0
  310. package/dist/services/analytics.d.ts +29 -0
  311. package/dist/services/analytics.js +84 -0
  312. package/dist/services/auto-dream.d.ts +49 -0
  313. package/dist/services/auto-dream.js +124 -0
  314. package/dist/services/diagnostics.d.ts +41 -0
  315. package/dist/services/diagnostics.js +99 -0
  316. package/dist/services/extract-memories.d.ts +31 -0
  317. package/dist/services/extract-memories.js +71 -0
  318. package/dist/services/index.d.ts +11 -0
  319. package/dist/services/index.js +17 -0
  320. package/dist/services/memory-orchestrator.d.ts +60 -0
  321. package/dist/services/memory-orchestrator.js +133 -0
  322. package/dist/services/notifier.d.ts +25 -0
  323. package/dist/services/notifier.js +69 -0
  324. package/dist/services/oauth.d.ts +27 -0
  325. package/dist/services/oauth.js +153 -0
  326. package/dist/services/session-memory.d.ts +37 -0
  327. package/dist/services/session-memory.js +81 -0
  328. package/dist/session/file-history.d.ts +41 -0
  329. package/dist/session/file-history.js +115 -0
  330. package/dist/session/memory.d.ts +104 -0
  331. package/dist/session/memory.js +310 -0
  332. package/dist/session/session-manager.d.ts +41 -0
  333. package/dist/session/session-manager.js +261 -0
  334. package/dist/session/transcript.d.ts +39 -0
  335. package/dist/session/transcript.js +186 -0
  336. package/dist/settings/manager.d.ts +36 -0
  337. package/dist/settings/manager.js +187 -0
  338. package/dist/settings/schema.d.ts +1219 -0
  339. package/dist/settings/schema.js +246 -0
  340. package/dist/skills/frontmatter.d.ts +13 -0
  341. package/dist/skills/frontmatter.js +70 -0
  342. package/dist/skills/index.d.ts +7 -0
  343. package/dist/skills/index.js +6 -0
  344. package/dist/skills/scanner.d.ts +31 -0
  345. package/dist/skills/scanner.js +171 -0
  346. package/dist/state.d.ts +160 -0
  347. package/dist/state.js +267 -0
  348. package/dist/tool-system/builtin/agent-notifications.d.ts +84 -0
  349. package/dist/tool-system/builtin/agent-notifications.js +197 -0
  350. package/dist/tool-system/builtin/agent-registry.d.ts +67 -0
  351. package/dist/tool-system/builtin/agent-registry.js +126 -0
  352. package/dist/tool-system/builtin/agent-transcript-translator.d.ts +22 -0
  353. package/dist/tool-system/builtin/agent-transcript-translator.js +160 -0
  354. package/dist/tool-system/builtin/agent.d.ts +16 -0
  355. package/dist/tool-system/builtin/agent.js +364 -0
  356. package/dist/tool-system/builtin/apply-patch/applier.d.ts +26 -0
  357. package/dist/tool-system/builtin/apply-patch/applier.js +250 -0
  358. package/dist/tool-system/builtin/apply-patch/index.d.ts +20 -0
  359. package/dist/tool-system/builtin/apply-patch/index.js +101 -0
  360. package/dist/tool-system/builtin/apply-patch/parser.d.ts +17 -0
  361. package/dist/tool-system/builtin/apply-patch/parser.js +212 -0
  362. package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +18 -0
  363. package/dist/tool-system/builtin/apply-patch/seek-sequence.js +123 -0
  364. package/dist/tool-system/builtin/apply-patch/types.d.ts +49 -0
  365. package/dist/tool-system/builtin/apply-patch/types.js +13 -0
  366. package/dist/tool-system/builtin/arena.d.ts +31 -0
  367. package/dist/tool-system/builtin/arena.js +416 -0
  368. package/dist/tool-system/builtin/ask-user.d.ts +20 -0
  369. package/dist/tool-system/builtin/ask-user.js +99 -0
  370. package/dist/tool-system/builtin/bash.d.ts +21 -0
  371. package/dist/tool-system/builtin/bash.js +149 -0
  372. package/dist/tool-system/builtin/brief.d.ts +6 -0
  373. package/dist/tool-system/builtin/brief.js +41 -0
  374. package/dist/tool-system/builtin/config.d.ts +6 -0
  375. package/dist/tool-system/builtin/config.js +67 -0
  376. package/dist/tool-system/builtin/cron.d.ts +10 -0
  377. package/dist/tool-system/builtin/cron.js +61 -0
  378. package/dist/tool-system/builtin/edit.d.ts +6 -0
  379. package/dist/tool-system/builtin/edit.js +100 -0
  380. package/dist/tool-system/builtin/file-cache.d.ts +11 -0
  381. package/dist/tool-system/builtin/file-cache.js +39 -0
  382. package/dist/tool-system/builtin/glob.d.ts +7 -0
  383. package/dist/tool-system/builtin/glob.js +76 -0
  384. package/dist/tool-system/builtin/grep.d.ts +7 -0
  385. package/dist/tool-system/builtin/grep.js +150 -0
  386. package/dist/tool-system/builtin/index.d.ts +20 -0
  387. package/dist/tool-system/builtin/index.js +449 -0
  388. package/dist/tool-system/builtin/lsp.d.ts +6 -0
  389. package/dist/tool-system/builtin/lsp.js +141 -0
  390. package/dist/tool-system/builtin/mcp-tools.d.ts +10 -0
  391. package/dist/tool-system/builtin/mcp-tools.js +102 -0
  392. package/dist/tool-system/builtin/memory.d.ts +26 -0
  393. package/dist/tool-system/builtin/memory.js +226 -0
  394. package/dist/tool-system/builtin/notebook-edit.d.ts +6 -0
  395. package/dist/tool-system/builtin/notebook-edit.js +124 -0
  396. package/dist/tool-system/builtin/plan.d.ts +15 -0
  397. package/dist/tool-system/builtin/plan.js +55 -0
  398. package/dist/tool-system/builtin/powershell.d.ts +11 -0
  399. package/dist/tool-system/builtin/powershell.js +64 -0
  400. package/dist/tool-system/builtin/read.d.ts +6 -0
  401. package/dist/tool-system/builtin/read.js +70 -0
  402. package/dist/tool-system/builtin/remote-trigger.d.ts +6 -0
  403. package/dist/tool-system/builtin/remote-trigger.js +54 -0
  404. package/dist/tool-system/builtin/repl.d.ts +11 -0
  405. package/dist/tool-system/builtin/repl.js +82 -0
  406. package/dist/tool-system/builtin/send-message.d.ts +6 -0
  407. package/dist/tool-system/builtin/send-message.js +47 -0
  408. package/dist/tool-system/builtin/skill-prompt.d.ts +20 -0
  409. package/dist/tool-system/builtin/skill-prompt.js +52 -0
  410. package/dist/tool-system/builtin/skill.d.ts +9 -0
  411. package/dist/tool-system/builtin/skill.js +55 -0
  412. package/dist/tool-system/builtin/sleep.d.ts +6 -0
  413. package/dist/tool-system/builtin/sleep.js +33 -0
  414. package/dist/tool-system/builtin/task.d.ts +48 -0
  415. package/dist/tool-system/builtin/task.js +139 -0
  416. package/dist/tool-system/builtin/tool-search.d.ts +11 -0
  417. package/dist/tool-system/builtin/tool-search.js +90 -0
  418. package/dist/tool-system/builtin/web-fetch.d.ts +10 -0
  419. package/dist/tool-system/builtin/web-fetch.js +328 -0
  420. package/dist/tool-system/builtin/web-search.d.ts +25 -0
  421. package/dist/tool-system/builtin/web-search.js +174 -0
  422. package/dist/tool-system/builtin/worktree.d.ts +10 -0
  423. package/dist/tool-system/builtin/worktree.js +95 -0
  424. package/dist/tool-system/builtin/write.d.ts +6 -0
  425. package/dist/tool-system/builtin/write.js +36 -0
  426. package/dist/tool-system/context.d.ts +165 -0
  427. package/dist/tool-system/context.js +18 -0
  428. package/dist/tool-system/executor.d.ts +49 -0
  429. package/dist/tool-system/executor.js +495 -0
  430. package/dist/tool-system/investigation-guard.d.ts +46 -0
  431. package/dist/tool-system/investigation-guard.js +155 -0
  432. package/dist/tool-system/mcp-manager.d.ts +67 -0
  433. package/dist/tool-system/mcp-manager.js +249 -0
  434. package/dist/tool-system/permission.d.ts +111 -0
  435. package/dist/tool-system/permission.js +774 -0
  436. package/dist/tool-system/registry.d.ts +32 -0
  437. package/dist/tool-system/registry.js +131 -0
  438. package/dist/tool-system/sandbox/bwrap.d.ts +13 -0
  439. package/dist/tool-system/sandbox/bwrap.js +63 -0
  440. package/dist/tool-system/sandbox/index.d.ts +78 -0
  441. package/dist/tool-system/sandbox/index.js +222 -0
  442. package/dist/tool-system/sandbox/off.d.ts +2 -0
  443. package/dist/tool-system/sandbox/off.js +8 -0
  444. package/dist/tool-system/sandbox/seatbelt.d.ts +18 -0
  445. package/dist/tool-system/sandbox/seatbelt.js +109 -0
  446. package/dist/tool-system/task-guard.d.ts +29 -0
  447. package/dist/tool-system/task-guard.js +70 -0
  448. package/dist/tool-system/validation.d.ts +5 -0
  449. package/dist/tool-system/validation.js +39 -0
  450. package/dist/types.d.ts +376 -0
  451. package/dist/types.js +4 -0
  452. package/dist/updater.d.ts +65 -0
  453. package/dist/updater.js +405 -0
  454. package/dist/utils/debug.d.ts +41 -0
  455. package/dist/utils/debug.js +110 -0
  456. package/dist/utils/earlyInput.d.ts +43 -0
  457. package/dist/utils/earlyInput.js +166 -0
  458. package/dist/utils/env.d.ts +24 -0
  459. package/dist/utils/env.js +104 -0
  460. package/dist/utils/envUtils.d.ts +51 -0
  461. package/dist/utils/envUtils.js +135 -0
  462. package/dist/utils/execFileNoThrow.d.ts +39 -0
  463. package/dist/utils/execFileNoThrow.js +74 -0
  464. package/dist/utils/format.d.ts +44 -0
  465. package/dist/utils/format.js +236 -0
  466. package/dist/utils/intl.d.ts +22 -0
  467. package/dist/utils/intl.js +83 -0
  468. package/dist/utils/lockfile.d.ts +15 -0
  469. package/dist/utils/lockfile.js +30 -0
  470. package/dist/utils/memoize.d.ts +19 -0
  471. package/dist/utils/memoize.js +14 -0
  472. package/dist/utils/semver.d.ts +6 -0
  473. package/dist/utils/semver.js +13 -0
  474. package/dist/utils/sliceAnsi.d.ts +12 -0
  475. package/dist/utils/sliceAnsi.js +62 -0
  476. package/dist/utils/systemTheme.d.ts +40 -0
  477. package/dist/utils/systemTheme.js +108 -0
  478. package/dist/utils/task-sanitizer.d.ts +6 -0
  479. package/dist/utils/task-sanitizer.js +24 -0
  480. package/dist/utils/theme.d.ts +93 -0
  481. package/dist/utils/theme.js +544 -0
  482. package/dist/utils/toolDisplay.d.ts +31 -0
  483. package/dist/utils/toolDisplay.js +188 -0
  484. package/package.json +72 -0
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Session Memory service — automatic session memory maintenance.
3
+ *
4
+ * Extracts and maintains conversation context as persistent memory
5
+ * entries that survive across sessions.
6
+ */
7
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { homedir } from "node:os";
10
+ const MEMORY_DIR = join(homedir(), ".code-shell", "session-memories");
11
+ /**
12
+ * Save a session memory entry.
13
+ */
14
+ export function saveSessionMemory(entry) {
15
+ mkdirSync(MEMORY_DIR, { recursive: true });
16
+ const file = join(MEMORY_DIR, `${entry.sessionId}.json`);
17
+ writeFileSync(file, JSON.stringify(entry, null, 2), "utf-8");
18
+ }
19
+ /**
20
+ * Load a session memory by session ID.
21
+ */
22
+ export function loadSessionMemory(sessionId) {
23
+ const file = join(MEMORY_DIR, `${sessionId}.json`);
24
+ if (!existsSync(file))
25
+ return null;
26
+ try {
27
+ return JSON.parse(readFileSync(file, "utf-8"));
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /**
34
+ * List all session memories, most recent first.
35
+ */
36
+ export function listSessionMemories(limit = 50) {
37
+ if (!existsSync(MEMORY_DIR))
38
+ return [];
39
+ const files = readdirSync(MEMORY_DIR)
40
+ .filter((f) => f.endsWith(".json"))
41
+ .sort()
42
+ .reverse()
43
+ .slice(0, limit);
44
+ const entries = [];
45
+ for (const file of files) {
46
+ try {
47
+ const entry = JSON.parse(readFileSync(join(MEMORY_DIR, file), "utf-8"));
48
+ entries.push(entry);
49
+ }
50
+ catch { }
51
+ }
52
+ return entries;
53
+ }
54
+ /**
55
+ * Search session memories by keyword.
56
+ */
57
+ export function searchSessionMemories(query) {
58
+ const all = listSessionMemories(200);
59
+ const q = query.toLowerCase();
60
+ return all.filter((m) => m.summary.toLowerCase().includes(q) ||
61
+ m.keyTopics.some((t) => t.toLowerCase().includes(q)) ||
62
+ m.decisions.some((d) => d.toLowerCase().includes(q)));
63
+ }
64
+ /**
65
+ * Build a prompt for extracting session memory from a conversation.
66
+ */
67
+ export function buildSessionMemoryPrompt(messages) {
68
+ const text = messages
69
+ .map((m) => `[${m.role}]: ${m.content.slice(0, 2000)}`)
70
+ .join("\n\n");
71
+ return `Extract a concise session memory from this conversation:
72
+
73
+ ${text.slice(0, 30000)}
74
+
75
+ Respond with JSON:
76
+ {
77
+ "summary": "One paragraph summarizing what was discussed and accomplished",
78
+ "keyTopics": ["topic1", "topic2", ...],
79
+ "decisions": ["decision1", "decision2", ...]
80
+ }`;
81
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * File history — automatic backup of files before modifications.
3
+ *
4
+ * Stores snapshots in the session directory under file-history/.
5
+ * Supports restoring files to a previous state.
6
+ */
7
+ export interface FileSnapshot {
8
+ filePath: string;
9
+ timestamp: number;
10
+ backupPath: string;
11
+ hash: string;
12
+ size: number;
13
+ }
14
+ export declare class FileHistory {
15
+ private readonly historyDir;
16
+ private snapshots;
17
+ constructor(sessionDir: string);
18
+ /**
19
+ * Save a snapshot of a file before it is modified.
20
+ * Returns the snapshot record, or null if the file doesn't exist.
21
+ */
22
+ saveSnapshot(filePath: string): FileSnapshot | null;
23
+ /**
24
+ * Get all snapshots for a specific file.
25
+ */
26
+ getSnapshots(filePath: string): FileSnapshot[];
27
+ /**
28
+ * Restore a file to a specific snapshot.
29
+ */
30
+ restore(snapshot: FileSnapshot): boolean;
31
+ /**
32
+ * Restore a file to its most recent snapshot.
33
+ */
34
+ restoreLatest(filePath: string): boolean;
35
+ /**
36
+ * Get all tracked files.
37
+ */
38
+ getTrackedFiles(): string[];
39
+ private saveIndex;
40
+ static loadFromDir(sessionDir: string): FileHistory;
41
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * File history — automatic backup of files before modifications.
3
+ *
4
+ * Stores snapshots in the session directory under file-history/.
5
+ * Supports restoring files to a previous state.
6
+ */
7
+ import { mkdirSync, existsSync, readFileSync, writeFileSync, copyFileSync } from "node:fs";
8
+ import { join, resolve } from "node:path";
9
+ import { createHash } from "node:crypto";
10
+ export class FileHistory {
11
+ historyDir;
12
+ snapshots = [];
13
+ constructor(sessionDir) {
14
+ this.historyDir = join(sessionDir, "file-history");
15
+ mkdirSync(this.historyDir, { recursive: true });
16
+ }
17
+ /**
18
+ * Save a snapshot of a file before it is modified.
19
+ * Returns the snapshot record, or null if the file doesn't exist.
20
+ */
21
+ saveSnapshot(filePath) {
22
+ const absPath = resolve(filePath);
23
+ if (!existsSync(absPath))
24
+ return null;
25
+ try {
26
+ const content = readFileSync(absPath);
27
+ const hash = createHash("md5").update(content).digest("hex");
28
+ // Check if we already have this exact version
29
+ const existing = this.snapshots.find((s) => s.filePath === absPath && s.hash === hash);
30
+ if (existing)
31
+ return existing;
32
+ // Create backup
33
+ const timestamp = Date.now();
34
+ const safeName = absPath.replace(/[/\\:]/g, "_").slice(-100);
35
+ const backupPath = join(this.historyDir, `${timestamp}_${safeName}`);
36
+ copyFileSync(absPath, backupPath);
37
+ const snapshot = {
38
+ filePath: absPath,
39
+ timestamp,
40
+ backupPath,
41
+ hash,
42
+ size: content.length,
43
+ };
44
+ this.snapshots.push(snapshot);
45
+ // Write index
46
+ this.saveIndex();
47
+ return snapshot;
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ /**
54
+ * Get all snapshots for a specific file.
55
+ */
56
+ getSnapshots(filePath) {
57
+ const absPath = resolve(filePath);
58
+ return this.snapshots
59
+ .filter((s) => s.filePath === absPath)
60
+ .sort((a, b) => b.timestamp - a.timestamp);
61
+ }
62
+ /**
63
+ * Restore a file to a specific snapshot.
64
+ */
65
+ restore(snapshot) {
66
+ try {
67
+ if (!existsSync(snapshot.backupPath))
68
+ return false;
69
+ // Save current state before restoring
70
+ this.saveSnapshot(snapshot.filePath);
71
+ copyFileSync(snapshot.backupPath, snapshot.filePath);
72
+ return true;
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ /**
79
+ * Restore a file to its most recent snapshot.
80
+ */
81
+ restoreLatest(filePath) {
82
+ const snapshots = this.getSnapshots(filePath);
83
+ if (snapshots.length === 0)
84
+ return false;
85
+ return this.restore(snapshots[0]);
86
+ }
87
+ /**
88
+ * Get all tracked files.
89
+ */
90
+ getTrackedFiles() {
91
+ return [...new Set(this.snapshots.map((s) => s.filePath))];
92
+ }
93
+ saveIndex() {
94
+ try {
95
+ const indexPath = join(this.historyDir, "index.json");
96
+ writeFileSync(indexPath, JSON.stringify(this.snapshots, null, 2), "utf-8");
97
+ }
98
+ catch {
99
+ // Silent fail
100
+ }
101
+ }
102
+ static loadFromDir(sessionDir) {
103
+ const history = new FileHistory(sessionDir);
104
+ const indexPath = join(history.historyDir, "index.json");
105
+ if (existsSync(indexPath)) {
106
+ try {
107
+ history.snapshots = JSON.parse(readFileSync(indexPath, "utf-8"));
108
+ }
109
+ catch {
110
+ // Start fresh
111
+ }
112
+ }
113
+ return history;
114
+ }
115
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Memory system — persistent cross-session memory.
3
+ *
4
+ * Stores structured memory entries as individual markdown files under a base
5
+ * directory. Resolution order for the base directory:
6
+ * 1. explicit `baseDir` constructor arg
7
+ * 2. CODE_SHELL_HOME env var
8
+ * 3. ~/.code-shell
9
+ *
10
+ * Two scopes are isolated on disk:
11
+ * - user/ Things the user explicitly asked to remember, plus the legacy
12
+ * auto-extracted entries (extract-memories output). LLM may
13
+ * only modify these through permission-gated tool calls.
14
+ * - dream/ The dream pipeline's workspace. The LLM is free to add /
15
+ * merge / delete entries here; user/ is read-only to dream.
16
+ *
17
+ * MEMORY.md is the index file (one per scope).
18
+ *
19
+ * Deletes are SOFT — files are moved to <baseDir>/memory-trash/<ISO>/<scope>/
20
+ * rather than removed, so accidental deletions are recoverable.
21
+ */
22
+ export type MemoryScope = "user" | "dream";
23
+ export interface MemoryEntry {
24
+ name: string;
25
+ description: string;
26
+ type: "user" | "feedback" | "project" | "reference";
27
+ content: string;
28
+ fileName: string;
29
+ scope: MemoryScope;
30
+ }
31
+ export interface MemoryManagerOptions {
32
+ /** Project root path; when set, memories are scoped under projects/<hash>/memory. */
33
+ projectDir?: string;
34
+ /** Override the base directory (~/.code-shell by default). Takes precedence over env. */
35
+ baseDir?: string;
36
+ /** Which scope this manager operates on. Defaults to "user". */
37
+ scope?: MemoryScope;
38
+ }
39
+ export declare function resolveMemoryBaseDir(override?: string): string;
40
+ export declare class MemoryManager {
41
+ private readonly baseDir;
42
+ /** Root containing both scope subdirs (the "memory" dir per project/global). */
43
+ private readonly memoryRoot;
44
+ private readonly scope;
45
+ /** Scope-specific directory: <memoryRoot>/<scope>. */
46
+ private readonly memoryDir;
47
+ private readonly indexPath;
48
+ private indexCache;
49
+ constructor(options?: MemoryManagerOptions | string);
50
+ getMemoryDir(): string;
51
+ getScope(): MemoryScope;
52
+ /**
53
+ * Save a memory entry. Creates the file and updates the index.
54
+ */
55
+ save(entry: Omit<MemoryEntry, "fileName" | "scope">): string;
56
+ /**
57
+ * Load all memory entries.
58
+ */
59
+ loadAll(): MemoryEntry[];
60
+ /**
61
+ * Load a single memory file.
62
+ */
63
+ private loadFile;
64
+ /**
65
+ * Soft-delete a memory by name or filename — moves the file into
66
+ * <baseDir>/memory-trash/<ISO>/<scope>/ instead of unlinking it. The user
67
+ * can recover by moving it back; we never hard-delete from this code path.
68
+ */
69
+ delete(nameOrFile: string): boolean;
70
+ /**
71
+ * Get the MEMORY.md index content for injection into prompts.
72
+ */
73
+ getIndex(): string;
74
+ /**
75
+ * Build a prompt-friendly summary of all memories. Includes BOTH scopes
76
+ * (user + dream) regardless of the manager's own scope, since prompts
77
+ * should surface every memory the LLM might care about. Entries are
78
+ * tagged with their origin so the model can tell user-owned from
79
+ * dream-generated.
80
+ */
81
+ buildMemoryContext(): string;
82
+ /**
83
+ * Load every entry belonging to the given scope, without changing the
84
+ * manager's own scope. Used by buildMemoryContext to merge user + dream
85
+ * in one pass and by tools that need cross-scope visibility.
86
+ */
87
+ loadScope(scope: MemoryScope): MemoryEntry[];
88
+ private loadFileFromDir;
89
+ /**
90
+ * Move pre-scope flat-layout entries (entries that lived directly under
91
+ * <memoryRoot>/ before user/dream split) into <memoryRoot>/user/. Runs at
92
+ * most once per directory — subsequent constructions find no flat .md
93
+ * files and return immediately.
94
+ */
95
+ private migrateFlatLayout;
96
+ /**
97
+ * Lazy-build the in-memory index from disk on first use, then
98
+ * keep it in sync incrementally via save/delete. Avoids the
99
+ * O(N²) re-read of every memory file on every save.
100
+ */
101
+ private ensureIndexCache;
102
+ private writeIndex;
103
+ private slugify;
104
+ }
@@ -0,0 +1,310 @@
1
+ /**
2
+ * Memory system — persistent cross-session memory.
3
+ *
4
+ * Stores structured memory entries as individual markdown files under a base
5
+ * directory. Resolution order for the base directory:
6
+ * 1. explicit `baseDir` constructor arg
7
+ * 2. CODE_SHELL_HOME env var
8
+ * 3. ~/.code-shell
9
+ *
10
+ * Two scopes are isolated on disk:
11
+ * - user/ Things the user explicitly asked to remember, plus the legacy
12
+ * auto-extracted entries (extract-memories output). LLM may
13
+ * only modify these through permission-gated tool calls.
14
+ * - dream/ The dream pipeline's workspace. The LLM is free to add /
15
+ * merge / delete entries here; user/ is read-only to dream.
16
+ *
17
+ * MEMORY.md is the index file (one per scope).
18
+ *
19
+ * Deletes are SOFT — files are moved to <baseDir>/memory-trash/<ISO>/<scope>/
20
+ * rather than removed, so accidental deletions are recoverable.
21
+ */
22
+ import { mkdirSync, existsSync, readFileSync, writeFileSync, readdirSync, renameSync, statSync, } from "node:fs";
23
+ import { join } from "node:path";
24
+ import { homedir } from "node:os";
25
+ export function resolveMemoryBaseDir(override) {
26
+ if (override)
27
+ return override;
28
+ const fromEnv = process.env.CODE_SHELL_HOME;
29
+ if (fromEnv && fromEnv.length > 0)
30
+ return fromEnv;
31
+ return join(homedir(), ".code-shell");
32
+ }
33
+ export class MemoryManager {
34
+ baseDir;
35
+ /** Root containing both scope subdirs (the "memory" dir per project/global). */
36
+ memoryRoot;
37
+ scope;
38
+ /** Scope-specific directory: <memoryRoot>/<scope>. */
39
+ memoryDir;
40
+ indexPath;
41
+ // Per-instance cache of {fileName -> {name, description}} so the
42
+ // index can be rewritten without re-reading every memory file
43
+ // every time a single entry is saved/deleted (the previous code
44
+ // path called loadAll() on every save, giving O(N²) total I/O).
45
+ // null = "not initialized yet, fall back to disk on next access."
46
+ indexCache = null;
47
+ constructor(options) {
48
+ // Back-compat: old signature was `new MemoryManager(projectDir?: string)`.
49
+ const opts = typeof options === "string" ? { projectDir: options } : (options ?? {});
50
+ this.baseDir = resolveMemoryBaseDir(opts.baseDir);
51
+ this.scope = opts.scope ?? "user";
52
+ if (opts.projectDir) {
53
+ const projectHash = opts.projectDir.replace(/[/\\:]/g, "-").replace(/^-/, "");
54
+ this.memoryRoot = join(this.baseDir, "projects", projectHash, "memory");
55
+ }
56
+ else {
57
+ this.memoryRoot = join(this.baseDir, "memory");
58
+ }
59
+ this.memoryDir = join(this.memoryRoot, this.scope);
60
+ this.indexPath = join(this.memoryDir, "MEMORY.md");
61
+ mkdirSync(this.memoryDir, { recursive: true });
62
+ // One-shot migration: if memoryRoot contains *.md files directly (pre-scope
63
+ // layout), move them into user/. Idempotent — once migrated, the root has
64
+ // no flat .md files and this becomes a no-op.
65
+ this.migrateFlatLayout();
66
+ }
67
+ getMemoryDir() { return this.memoryDir; }
68
+ getScope() { return this.scope; }
69
+ /**
70
+ * Save a memory entry. Creates the file and updates the index.
71
+ */
72
+ save(entry) {
73
+ const fileName = this.slugify(entry.name) + ".md";
74
+ const filePath = join(this.memoryDir, fileName);
75
+ const content = `---\n` +
76
+ `name: ${entry.name}\n` +
77
+ `description: ${entry.description}\n` +
78
+ `type: ${entry.type}\n` +
79
+ `---\n\n` +
80
+ `${entry.content}\n`;
81
+ writeFileSync(filePath, content, "utf-8");
82
+ // Incremental index update. Initialize the cache on first
83
+ // save by paying one loadAll() — every save after that just
84
+ // mutates the cache and rewrites MEMORY.md.
85
+ const cache = this.ensureIndexCache();
86
+ cache.set(fileName, { name: entry.name, description: entry.description });
87
+ this.writeIndex(cache);
88
+ return fileName;
89
+ }
90
+ /**
91
+ * Load all memory entries.
92
+ */
93
+ loadAll() {
94
+ if (!existsSync(this.memoryDir))
95
+ return [];
96
+ const files = readdirSync(this.memoryDir).filter((f) => f.endsWith(".md") && f !== "MEMORY.md");
97
+ const entries = [];
98
+ for (const file of files) {
99
+ const entry = this.loadFile(file);
100
+ if (entry)
101
+ entries.push(entry);
102
+ }
103
+ return entries;
104
+ }
105
+ /**
106
+ * Load a single memory file.
107
+ */
108
+ loadFile(fileName) {
109
+ const filePath = join(this.memoryDir, fileName);
110
+ if (!existsSync(filePath))
111
+ return null;
112
+ try {
113
+ const raw = readFileSync(filePath, "utf-8");
114
+ const frontmatterMatch = raw.match(/^---\n([\s\S]*?)\n---\n\n?([\s\S]*)$/);
115
+ if (!frontmatterMatch)
116
+ return null;
117
+ const frontmatter = frontmatterMatch[1];
118
+ const content = frontmatterMatch[2].trim();
119
+ const name = frontmatter.match(/name:\s*(.+)/)?.[1]?.trim() ?? fileName;
120
+ const description = frontmatter.match(/description:\s*(.+)/)?.[1]?.trim() ?? "";
121
+ const type = (frontmatter.match(/type:\s*(.+)/)?.[1]?.trim() ?? "project");
122
+ return { name, description, type, content, fileName, scope: this.scope };
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ }
128
+ /**
129
+ * Soft-delete a memory by name or filename — moves the file into
130
+ * <baseDir>/memory-trash/<ISO>/<scope>/ instead of unlinking it. The user
131
+ * can recover by moving it back; we never hard-delete from this code path.
132
+ */
133
+ delete(nameOrFile) {
134
+ const entries = this.loadAll();
135
+ const entry = entries.find((e) => e.name === nameOrFile || e.fileName === nameOrFile);
136
+ if (!entry)
137
+ return false;
138
+ try {
139
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
140
+ const trashDir = join(this.baseDir, "memory-trash", stamp, this.scope);
141
+ mkdirSync(trashDir, { recursive: true });
142
+ renameSync(join(this.memoryDir, entry.fileName), join(trashDir, entry.fileName));
143
+ const cache = this.ensureIndexCache();
144
+ cache.delete(entry.fileName);
145
+ this.writeIndex(cache);
146
+ return true;
147
+ }
148
+ catch {
149
+ return false;
150
+ }
151
+ }
152
+ /**
153
+ * Get the MEMORY.md index content for injection into prompts.
154
+ */
155
+ getIndex() {
156
+ if (!existsSync(this.indexPath))
157
+ return "";
158
+ return readFileSync(this.indexPath, "utf-8");
159
+ }
160
+ /**
161
+ * Build a prompt-friendly summary of all memories. Includes BOTH scopes
162
+ * (user + dream) regardless of the manager's own scope, since prompts
163
+ * should surface every memory the LLM might care about. Entries are
164
+ * tagged with their origin so the model can tell user-owned from
165
+ * dream-generated.
166
+ */
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");
174
+ if (userEntries.length === 0 && dreamEntries.length === 0)
175
+ return "";
176
+ const lines = [];
177
+ if (userEntries.length > 0) {
178
+ lines.push("## User memories (you own these — needs permission to modify)");
179
+ for (const e of userEntries) {
180
+ lines.push(`- [${e.type}] ${e.name}: ${e.description}`);
181
+ }
182
+ }
183
+ if (dreamEntries.length > 0) {
184
+ if (lines.length > 0)
185
+ lines.push("");
186
+ lines.push("## Dream memories (auto-consolidated workspace — freely modifiable)");
187
+ for (const e of dreamEntries) {
188
+ lines.push(`- [${e.type}] ${e.name}: ${e.description}`);
189
+ }
190
+ }
191
+ return (`# Persistent Memory\n\n` +
192
+ `The following memories from previous sessions may be relevant:\n\n` +
193
+ lines.join("\n") +
194
+ `\n\nTo read a specific memory, look under ${this.memoryRoot}/{user,dream}/`);
195
+ }
196
+ /**
197
+ * Load every entry belonging to the given scope, without changing the
198
+ * manager's own scope. Used by buildMemoryContext to merge user + dream
199
+ * in one pass and by tools that need cross-scope visibility.
200
+ */
201
+ loadScope(scope) {
202
+ const dir = join(this.memoryRoot, scope);
203
+ if (!existsSync(dir))
204
+ return [];
205
+ const files = readdirSync(dir).filter((f) => f.endsWith(".md") && f !== "MEMORY.md");
206
+ const entries = [];
207
+ for (const file of files) {
208
+ const e = this.loadFileFromDir(dir, file, scope);
209
+ if (e)
210
+ entries.push(e);
211
+ }
212
+ return entries;
213
+ }
214
+ 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
+ }
233
+ }
234
+ /**
235
+ * Move pre-scope flat-layout entries (entries that lived directly under
236
+ * <memoryRoot>/ before user/dream split) into <memoryRoot>/user/. Runs at
237
+ * most once per directory — subsequent constructions find no flat .md
238
+ * files and return immediately.
239
+ */
240
+ migrateFlatLayout() {
241
+ if (!existsSync(this.memoryRoot))
242
+ return;
243
+ let entries;
244
+ try {
245
+ entries = readdirSync(this.memoryRoot);
246
+ }
247
+ catch {
248
+ return;
249
+ }
250
+ const flatFiles = entries.filter((f) => {
251
+ if (!f.endsWith(".md"))
252
+ return false;
253
+ try {
254
+ return statSync(join(this.memoryRoot, f)).isFile();
255
+ }
256
+ catch {
257
+ return false;
258
+ }
259
+ });
260
+ if (flatFiles.length === 0)
261
+ return;
262
+ const userDir = join(this.memoryRoot, "user");
263
+ mkdirSync(userDir, { recursive: true });
264
+ for (const file of flatFiles) {
265
+ const src = join(this.memoryRoot, file);
266
+ const dst = join(userDir, file);
267
+ if (existsSync(dst))
268
+ continue; // don't clobber
269
+ try {
270
+ renameSync(src, dst);
271
+ }
272
+ catch {
273
+ // best-effort migration; partial failure leaves user with a hybrid
274
+ // layout but loadScope("user") will still pick up whatever moved.
275
+ }
276
+ }
277
+ }
278
+ /**
279
+ * Lazy-build the in-memory index from disk on first use, then
280
+ * keep it in sync incrementally via save/delete. Avoids the
281
+ * O(N²) re-read of every memory file on every save.
282
+ */
283
+ ensureIndexCache() {
284
+ if (this.indexCache !== null)
285
+ return this.indexCache;
286
+ const cache = new Map();
287
+ for (const entry of this.loadAll()) {
288
+ cache.set(entry.fileName, { name: entry.name, description: entry.description });
289
+ }
290
+ this.indexCache = cache;
291
+ return cache;
292
+ }
293
+ writeIndex(cache) {
294
+ const lines = [];
295
+ for (const [fileName, meta] of cache) {
296
+ lines.push(`- [${meta.name}](${fileName}) — ${meta.description}`);
297
+ }
298
+ const content = lines.length > 0
299
+ ? lines.join("\n") + "\n"
300
+ : "(no memories stored)\n";
301
+ writeFileSync(this.indexPath, content, "utf-8");
302
+ }
303
+ slugify(text) {
304
+ return text
305
+ .toLowerCase()
306
+ .replace(/[^a-z0-9]+/g, "-")
307
+ .replace(/^-|-$/g, "")
308
+ .slice(0, 60);
309
+ }
310
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Session lifecycle manager.
3
+ */
4
+ import type { SessionState } from "../types.js";
5
+ import { Transcript } from "./transcript.js";
6
+ export interface SessionBundle {
7
+ state: SessionState;
8
+ transcript: Transcript;
9
+ }
10
+ export declare class SessionManager {
11
+ private readonly sessionsDir;
12
+ constructor(storageDir?: string);
13
+ /**
14
+ * Create a new on-disk session. If `explicitSessionId` is passed, use
15
+ * it verbatim (ChatSessionManager-driven hosts choose a logical sid like
16
+ * "tui-main" and expect us to honor it). Otherwise generate one with
17
+ * nanoid. Either way the on-disk directory is materialized and the
18
+ * state.json + transcript.jsonl files are written before return.
19
+ */
20
+ create(cwd: string, model: string, provider: string, explicitSessionId?: string): SessionBundle;
21
+ /**
22
+ * Whether a session directory exists on disk. Used by ChatSession-driven
23
+ * cold starts to decide between resume vs create-with-explicit-sid
24
+ * without catching SessionError.
25
+ */
26
+ exists(sessionId: string): boolean;
27
+ resume(sessionId: string): SessionBundle;
28
+ saveState(state: SessionState): void;
29
+ /**
30
+ * Fork a session from a specific point.
31
+ * Creates a new session that shares events up to the given turn,
32
+ * then diverges independently.
33
+ */
34
+ fork(sourceSessionId: string, forkAtTurn?: number): SessionBundle;
35
+ list(limit?: number): SessionListEntry[];
36
+ }
37
+ export type SessionListEntry = SessionState & {
38
+ preview?: string;
39
+ /** Last activity time — transcript mtime, falling back to startedAt. */
40
+ lastActiveAt: number;
41
+ };