byterover-cli 0.4.1 → 1.0.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 (474) hide show
  1. package/README.md +1 -9
  2. package/dist/commands/curate.d.ts +1 -3
  3. package/dist/commands/curate.js +14 -51
  4. package/dist/commands/main.d.ts +8 -0
  5. package/dist/commands/main.js +29 -8
  6. package/dist/commands/query.d.ts +1 -3
  7. package/dist/commands/query.js +8 -35
  8. package/dist/config/context-tree-domains.d.ts +5 -0
  9. package/dist/config/context-tree-domains.js +6 -1
  10. package/dist/config/environment.js +9 -9
  11. package/dist/constants.d.ts +14 -0
  12. package/dist/constants.js +18 -0
  13. package/dist/core/domain/cipher/agent/agent-info.d.ts +199 -0
  14. package/dist/core/domain/cipher/agent/agent-info.js +143 -0
  15. package/dist/core/domain/cipher/agent/agent-registry.d.ts +96 -0
  16. package/dist/core/domain/cipher/agent/agent-registry.js +254 -0
  17. package/dist/core/domain/cipher/agent/index.d.ts +4 -1
  18. package/dist/core/domain/cipher/agent/index.js +7 -1
  19. package/dist/core/domain/cipher/agent-events/types.d.ts +355 -2
  20. package/dist/core/domain/cipher/agent-events/types.js +11 -0
  21. package/dist/core/domain/cipher/errors/error-normalizer.d.ts +156 -0
  22. package/dist/core/domain/cipher/errors/error-normalizer.js +379 -0
  23. package/dist/core/domain/cipher/errors/file-system-error.d.ts +2 -1
  24. package/dist/core/domain/cipher/errors/file-system-error.js +3 -2
  25. package/dist/core/domain/cipher/errors/system-prompt-error-codes.d.ts +79 -0
  26. package/dist/core/domain/cipher/errors/system-prompt-error-codes.js +80 -0
  27. package/dist/core/domain/cipher/errors/system-prompt-error.d.ts +114 -0
  28. package/dist/core/domain/cipher/errors/system-prompt-error.js +144 -0
  29. package/dist/core/domain/cipher/file-system/types.d.ts +57 -0
  30. package/dist/core/domain/cipher/llm/error-codes.d.ts +51 -0
  31. package/dist/core/domain/cipher/llm/error-codes.js +51 -0
  32. package/dist/core/domain/cipher/llm/index.d.ts +9 -0
  33. package/dist/core/domain/cipher/llm/index.js +13 -0
  34. package/dist/core/domain/cipher/llm/registry.d.ts +113 -0
  35. package/dist/core/domain/cipher/llm/registry.js +244 -0
  36. package/dist/core/domain/cipher/llm/schemas.d.ts +155 -0
  37. package/dist/core/domain/cipher/llm/schemas.js +151 -0
  38. package/dist/core/domain/cipher/llm/types.d.ts +121 -0
  39. package/dist/core/domain/cipher/llm/types.js +60 -0
  40. package/dist/core/domain/cipher/storage/message-storage-types.d.ts +114 -5
  41. package/dist/core/domain/cipher/streaming/types.d.ts +119 -0
  42. package/dist/core/domain/cipher/streaming/types.js +16 -0
  43. package/dist/core/domain/cipher/system-prompt/types.d.ts +44 -0
  44. package/dist/core/domain/cipher/todos/types.d.ts +34 -0
  45. package/dist/core/domain/cipher/tools/constants.d.ts +5 -2
  46. package/dist/core/domain/cipher/tools/constants.js +5 -2
  47. package/dist/core/domain/cipher/tools/types.d.ts +31 -0
  48. package/dist/core/domain/errors/connection-error.d.ts +33 -0
  49. package/dist/core/domain/errors/connection-error.js +54 -0
  50. package/dist/core/domain/errors/core-process-error.d.ts +27 -0
  51. package/dist/core/domain/errors/core-process-error.js +43 -0
  52. package/dist/core/domain/errors/task-error.d.ts +64 -0
  53. package/dist/core/domain/errors/task-error.js +116 -0
  54. package/dist/core/domain/errors/transport-error.d.ts +72 -0
  55. package/dist/core/domain/errors/transport-error.js +114 -0
  56. package/dist/core/domain/instance/index.d.ts +1 -0
  57. package/dist/core/domain/instance/index.js +1 -0
  58. package/dist/core/domain/instance/types.d.ts +57 -0
  59. package/dist/core/domain/instance/types.js +72 -0
  60. package/dist/core/domain/knowledge/directory-manager.d.ts +16 -0
  61. package/dist/core/domain/knowledge/directory-manager.js +31 -0
  62. package/dist/core/domain/transport/index.d.ts +2 -0
  63. package/dist/core/domain/transport/index.js +2 -0
  64. package/dist/core/domain/transport/schemas.d.ts +1149 -0
  65. package/dist/core/domain/transport/schemas.js +554 -0
  66. package/dist/core/domain/transport/types.d.ts +67 -0
  67. package/dist/core/domain/transport/types.js +7 -0
  68. package/dist/core/interfaces/cipher/cipher-services.d.ts +15 -3
  69. package/dist/core/interfaces/cipher/i-chat-session.d.ts +47 -5
  70. package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +39 -4
  71. package/dist/core/interfaces/cipher/i-content-generator.d.ts +3 -5
  72. package/dist/core/interfaces/cipher/i-file-system.d.ts +12 -1
  73. package/dist/core/interfaces/cipher/i-llm-service.d.ts +4 -5
  74. package/dist/core/interfaces/cipher/i-todo-storage.d.ts +24 -0
  75. package/dist/core/interfaces/cipher/i-todo-storage.js +1 -0
  76. package/dist/core/interfaces/cipher/i-tool-plugin.d.ts +90 -0
  77. package/dist/core/interfaces/cipher/i-tool-plugin.js +1 -0
  78. package/dist/core/interfaces/cipher/i-tool-provider.d.ts +3 -2
  79. package/dist/core/interfaces/cipher/i-tool-scheduler.d.ts +4 -0
  80. package/dist/core/interfaces/cipher/index.d.ts +35 -0
  81. package/dist/core/interfaces/cipher/index.js +11 -0
  82. package/dist/core/interfaces/cipher/message-factory.d.ts +155 -0
  83. package/dist/core/interfaces/cipher/message-factory.js +252 -0
  84. package/dist/core/interfaces/cipher/message-type-guards.d.ts +139 -0
  85. package/dist/core/interfaces/cipher/message-type-guards.js +173 -0
  86. package/dist/core/interfaces/cipher/message-types.d.ts +279 -5
  87. package/dist/core/interfaces/cipher/message-types.js +6 -0
  88. package/dist/core/interfaces/cipher/sanitization-types.d.ts +147 -0
  89. package/dist/core/interfaces/cipher/sanitization-types.js +46 -0
  90. package/dist/core/interfaces/executor/i-curate-executor.d.ts +34 -0
  91. package/dist/core/interfaces/executor/i-curate-executor.js +1 -0
  92. package/dist/core/interfaces/executor/i-query-executor.d.ts +32 -0
  93. package/dist/core/interfaces/executor/i-query-executor.js +1 -0
  94. package/dist/core/interfaces/executor/index.d.ts +2 -0
  95. package/dist/core/interfaces/executor/index.js +2 -0
  96. package/dist/core/interfaces/instance/i-instance-discovery.d.ts +45 -0
  97. package/dist/core/interfaces/instance/i-instance-discovery.js +1 -0
  98. package/dist/core/interfaces/instance/i-instance-manager.d.ts +58 -0
  99. package/dist/core/interfaces/instance/i-instance-manager.js +1 -0
  100. package/dist/core/interfaces/instance/index.d.ts +2 -0
  101. package/dist/core/interfaces/instance/index.js +2 -0
  102. package/dist/core/interfaces/noop-implementations.d.ts +53 -0
  103. package/dist/core/interfaces/noop-implementations.js +62 -0
  104. package/dist/core/interfaces/transport/i-transport-client.d.ts +97 -0
  105. package/dist/core/interfaces/transport/i-transport-client.js +1 -0
  106. package/dist/core/interfaces/transport/i-transport-server.d.ts +93 -0
  107. package/dist/core/interfaces/transport/i-transport-server.js +1 -0
  108. package/dist/core/interfaces/transport/index.d.ts +2 -0
  109. package/dist/core/interfaces/transport/index.js +2 -0
  110. package/dist/infra/cipher/agent/agent-error-codes.d.ts +16 -0
  111. package/dist/infra/cipher/agent/agent-error-codes.js +17 -0
  112. package/dist/infra/cipher/agent/agent-error.d.ts +54 -0
  113. package/dist/infra/cipher/agent/agent-error.js +79 -0
  114. package/dist/infra/cipher/agent/agent-schemas.d.ts +264 -0
  115. package/dist/infra/cipher/agent/agent-schemas.js +97 -0
  116. package/dist/infra/cipher/agent/agent-state-manager.d.ts +140 -0
  117. package/dist/infra/cipher/agent/agent-state-manager.js +275 -0
  118. package/dist/infra/cipher/agent/base-agent.d.ts +118 -0
  119. package/dist/infra/cipher/agent/base-agent.js +240 -0
  120. package/dist/infra/cipher/agent/cipher-agent.d.ts +165 -0
  121. package/dist/infra/cipher/agent/cipher-agent.js +546 -0
  122. package/dist/infra/cipher/agent/index.d.ts +22 -0
  123. package/dist/infra/cipher/agent/index.js +24 -0
  124. package/dist/infra/cipher/agent/service-initializer.d.ts +79 -0
  125. package/dist/infra/cipher/{agent-service-factory.js → agent/service-initializer.js} +117 -68
  126. package/dist/infra/cipher/agent/types.d.ts +35 -0
  127. package/dist/infra/cipher/agent/types.js +1 -0
  128. package/dist/infra/cipher/blob/blob-reference-resolver.d.ts +107 -0
  129. package/dist/infra/cipher/blob/blob-reference-resolver.js +228 -0
  130. package/dist/infra/cipher/blob/blob-reference-utils.d.ts +117 -0
  131. package/dist/infra/cipher/blob/blob-reference-utils.js +230 -0
  132. package/dist/infra/cipher/consumer/consumer-lock.js +1 -0
  133. package/dist/infra/cipher/consumer/consumer-service.js +1 -0
  134. package/dist/infra/cipher/consumer/execution-consumer.d.ts +6 -1
  135. package/dist/infra/cipher/consumer/execution-consumer.js +54 -16
  136. package/dist/infra/cipher/consumer/index.d.ts +1 -1
  137. package/dist/infra/cipher/consumer/index.js +2 -1
  138. package/dist/infra/cipher/consumer/queue-polling-service.js +1 -0
  139. package/dist/infra/cipher/file-system/binary-utils.d.ts +43 -0
  140. package/dist/infra/cipher/file-system/binary-utils.js +164 -0
  141. package/dist/infra/cipher/file-system/context-tree-file-system-factory.d.ts +9 -0
  142. package/dist/infra/cipher/file-system/context-tree-file-system-factory.js +24 -0
  143. package/dist/infra/cipher/file-system/file-system-service.d.ts +17 -1
  144. package/dist/infra/cipher/file-system/file-system-service.js +327 -36
  145. package/dist/infra/cipher/file-system/path-validator.d.ts +32 -0
  146. package/dist/infra/cipher/file-system/path-validator.js +111 -6
  147. package/dist/infra/cipher/interactive-loop.js +41 -33
  148. package/dist/infra/cipher/llm/capability-cache.d.ts +87 -0
  149. package/dist/infra/cipher/llm/capability-cache.js +125 -0
  150. package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +32 -0
  151. package/dist/infra/cipher/llm/context/compaction/compaction-service.js +44 -3
  152. package/dist/infra/cipher/llm/context/compression/enhanced-compaction.d.ts +112 -0
  153. package/dist/infra/cipher/llm/context/compression/enhanced-compaction.js +175 -0
  154. package/dist/infra/cipher/llm/context/compression/filter-compacted.d.ts +83 -0
  155. package/dist/infra/cipher/llm/context/compression/filter-compacted.js +150 -0
  156. package/dist/infra/cipher/llm/context/compression/index.d.ts +5 -0
  157. package/dist/infra/cipher/llm/context/compression/index.js +6 -0
  158. package/dist/infra/cipher/llm/context/compression/reactive-overflow.d.ts +107 -0
  159. package/dist/infra/cipher/llm/context/compression/reactive-overflow.js +272 -0
  160. package/dist/infra/cipher/llm/context/context-manager.d.ts +47 -1
  161. package/dist/infra/cipher/llm/context/context-manager.js +129 -0
  162. package/dist/infra/cipher/llm/context/utils.js +17 -4
  163. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +4 -2
  164. package/dist/infra/cipher/llm/internal-llm-service.d.ts +50 -17
  165. package/dist/infra/cipher/llm/internal-llm-service.js +273 -50
  166. package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +6 -8
  167. package/dist/infra/cipher/llm/openrouter-llm-service.js +14 -16
  168. package/dist/infra/cipher/llm/retry/retry-policy.d.ts +1 -0
  169. package/dist/infra/cipher/llm/retry/retry-policy.js +11 -0
  170. package/dist/infra/cipher/llm/retry/retry-with-backoff.js +3 -2
  171. package/dist/infra/cipher/llm/sanitization/base64-utils.d.ts +102 -0
  172. package/dist/infra/cipher/llm/sanitization/base64-utils.js +182 -0
  173. package/dist/infra/cipher/llm/sanitization/index.d.ts +12 -0
  174. package/dist/infra/cipher/llm/sanitization/index.js +13 -0
  175. package/dist/infra/cipher/llm/sanitization/tool-sanitizer.d.ts +74 -0
  176. package/dist/infra/cipher/llm/sanitization/tool-sanitizer.js +398 -0
  177. package/dist/infra/cipher/llm/stream-processor.d.ts +158 -0
  178. package/dist/infra/cipher/llm/stream-processor.js +276 -0
  179. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.d.ts +13 -20
  180. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.js +17 -24
  181. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.d.ts +12 -11
  182. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.js +16 -15
  183. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.d.ts +15 -7
  184. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.js +22 -10
  185. package/dist/infra/cipher/llm/tool-output-processor.d.ts +51 -0
  186. package/dist/infra/cipher/llm/tool-output-processor.js +139 -0
  187. package/dist/infra/cipher/process/command-validator.d.ts +23 -0
  188. package/dist/infra/cipher/process/command-validator.js +75 -0
  189. package/dist/infra/cipher/process/path-utils.d.ts +66 -0
  190. package/dist/infra/cipher/process/path-utils.js +94 -0
  191. package/dist/infra/cipher/process/process-service.d.ts +32 -0
  192. package/dist/infra/cipher/process/process-service.js +98 -17
  193. package/dist/infra/cipher/session/chat-session.d.ts +56 -7
  194. package/dist/infra/cipher/session/chat-session.js +163 -13
  195. package/dist/infra/cipher/session/index.d.ts +1 -0
  196. package/dist/infra/cipher/session/index.js +2 -0
  197. package/dist/infra/cipher/session/message-queue.d.ts +65 -0
  198. package/dist/infra/cipher/session/message-queue.js +90 -0
  199. package/dist/infra/cipher/session/session-manager.d.ts +106 -5
  200. package/dist/infra/cipher/session/session-manager.js +254 -7
  201. package/dist/infra/cipher/session/session-status.d.ts +137 -0
  202. package/dist/infra/cipher/session/session-status.js +184 -0
  203. package/dist/infra/cipher/session/title-generator.d.ts +8 -0
  204. package/dist/infra/cipher/session/title-generator.js +31 -0
  205. package/dist/infra/cipher/storage/message-storage-service.d.ts +65 -2
  206. package/dist/infra/cipher/storage/message-storage-service.js +300 -54
  207. package/dist/infra/cipher/storage/tool-part-factory.d.ts +116 -0
  208. package/dist/infra/cipher/storage/tool-part-factory.js +197 -0
  209. package/dist/infra/cipher/system-prompt/contributor-schemas.d.ts +516 -0
  210. package/dist/infra/cipher/system-prompt/contributor-schemas.js +85 -0
  211. package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.d.ts +59 -0
  212. package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.js +131 -0
  213. package/dist/infra/cipher/system-prompt/contributors/companion-contributor.d.ts +54 -0
  214. package/dist/infra/cipher/system-prompt/contributors/companion-contributor.js +107 -0
  215. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.d.ts +68 -0
  216. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.js +179 -0
  217. package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.d.ts +25 -0
  218. package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.js +29 -0
  219. package/dist/infra/cipher/system-prompt/contributors/environment-contributor.d.ts +25 -0
  220. package/dist/infra/cipher/system-prompt/contributors/environment-contributor.js +54 -0
  221. package/dist/infra/cipher/system-prompt/contributors/file-contributor.d.ts +60 -0
  222. package/dist/infra/cipher/system-prompt/contributors/file-contributor.js +128 -0
  223. package/dist/infra/cipher/system-prompt/contributors/index.d.ts +13 -0
  224. package/dist/infra/cipher/system-prompt/contributors/index.js +8 -0
  225. package/dist/infra/cipher/system-prompt/contributors/memory-contributor.d.ts +40 -0
  226. package/dist/infra/cipher/system-prompt/contributors/memory-contributor.js +56 -0
  227. package/dist/infra/cipher/system-prompt/contributors/static-contributor.d.ts +26 -0
  228. package/dist/infra/cipher/system-prompt/contributors/static-contributor.js +31 -0
  229. package/dist/infra/cipher/system-prompt/environment-context-builder.d.ts +112 -0
  230. package/dist/infra/cipher/system-prompt/environment-context-builder.js +256 -0
  231. package/dist/infra/cipher/system-prompt/prompt-cache.d.ts +102 -0
  232. package/dist/infra/cipher/system-prompt/prompt-cache.js +156 -0
  233. package/dist/infra/cipher/system-prompt/schemas.d.ts +151 -0
  234. package/dist/infra/cipher/system-prompt/schemas.js +94 -0
  235. package/dist/infra/cipher/system-prompt/system-prompt-manager.d.ts +136 -0
  236. package/dist/infra/cipher/system-prompt/system-prompt-manager.js +307 -0
  237. package/dist/infra/cipher/todos/todo-storage-service.d.ts +26 -0
  238. package/dist/infra/cipher/todos/todo-storage-service.js +28 -0
  239. package/dist/infra/cipher/tools/core-tool-scheduler.js +5 -1
  240. package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
  241. package/dist/infra/cipher/tools/implementations/bash-exec-tool.d.ts +1 -0
  242. package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +27 -10
  243. package/dist/infra/cipher/tools/implementations/bash-output-tool.js +1 -5
  244. package/dist/infra/cipher/tools/implementations/batch-tool.d.ts +12 -0
  245. package/dist/infra/cipher/tools/implementations/batch-tool.js +142 -0
  246. package/dist/infra/cipher/tools/implementations/curate-tool.js +195 -68
  247. package/dist/infra/cipher/tools/implementations/list-directory-tool.d.ts +12 -0
  248. package/dist/infra/cipher/tools/implementations/list-directory-tool.js +52 -0
  249. package/dist/infra/cipher/tools/implementations/read-file-tool.d.ts +8 -1
  250. package/dist/infra/cipher/tools/implementations/read-file-tool.js +17 -7
  251. package/dist/infra/cipher/tools/implementations/read-todos-tool.d.ts +11 -0
  252. package/dist/infra/cipher/tools/implementations/read-todos-tool.js +39 -0
  253. package/dist/infra/cipher/tools/implementations/{detect-domains-tool.d.ts → spec-analyze-tool.d.ts} +1 -1
  254. package/dist/infra/cipher/tools/implementations/{detect-domains-tool.js → spec-analyze-tool.js} +9 -7
  255. package/dist/infra/cipher/tools/implementations/task-tool.d.ts +34 -0
  256. package/dist/infra/cipher/tools/implementations/task-tool.js +207 -0
  257. package/dist/infra/cipher/tools/implementations/write-todos-tool.d.ts +4 -1
  258. package/dist/infra/cipher/tools/implementations/write-todos-tool.js +19 -63
  259. package/dist/infra/cipher/tools/index.d.ts +1 -1
  260. package/dist/infra/cipher/tools/index.js +1 -1
  261. package/dist/infra/cipher/tools/plugins/index.d.ts +3 -0
  262. package/dist/infra/cipher/tools/plugins/index.js +2 -0
  263. package/dist/infra/cipher/tools/plugins/logging-plugin.d.ts +28 -0
  264. package/dist/infra/cipher/tools/plugins/logging-plugin.js +66 -0
  265. package/dist/infra/cipher/tools/plugins/plugin-manager.d.ts +81 -0
  266. package/dist/infra/cipher/tools/plugins/plugin-manager.js +122 -0
  267. package/dist/infra/cipher/tools/streaming/index.d.ts +1 -0
  268. package/dist/infra/cipher/tools/streaming/index.js +1 -0
  269. package/dist/infra/cipher/tools/streaming/metadata-handler.d.ts +31 -0
  270. package/dist/infra/cipher/tools/streaming/metadata-handler.js +39 -0
  271. package/dist/infra/cipher/tools/tool-description-loader.d.ts +57 -0
  272. package/dist/infra/cipher/tools/tool-description-loader.js +108 -0
  273. package/dist/infra/cipher/tools/tool-manager.d.ts +38 -4
  274. package/dist/infra/cipher/tools/tool-manager.js +107 -11
  275. package/dist/infra/cipher/tools/tool-provider-getter.d.ts +6 -0
  276. package/dist/infra/cipher/tools/tool-provider-getter.js +1 -0
  277. package/dist/infra/cipher/tools/tool-provider.d.ts +32 -7
  278. package/dist/infra/cipher/tools/tool-provider.js +81 -25
  279. package/dist/infra/cipher/tools/tool-registry.d.ts +23 -0
  280. package/dist/infra/cipher/tools/tool-registry.js +58 -16
  281. package/dist/infra/context-tree/file-context-tree-snapshot-service.js +10 -4
  282. package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +4 -3
  283. package/dist/infra/context-tree/file-context-tree-writer-service.js +6 -4
  284. package/dist/infra/context-tree/path-utils.d.ts +7 -0
  285. package/dist/infra/context-tree/path-utils.js +7 -0
  286. package/dist/infra/core/executors/curate-executor.d.ts +35 -0
  287. package/dist/infra/core/executors/curate-executor.js +123 -0
  288. package/dist/infra/core/executors/index.d.ts +2 -0
  289. package/dist/infra/core/executors/index.js +2 -0
  290. package/dist/infra/core/executors/query-executor.d.ts +23 -0
  291. package/dist/infra/core/executors/query-executor.js +51 -0
  292. package/dist/infra/core/task-processor.d.ts +81 -0
  293. package/dist/infra/core/task-processor.js +115 -0
  294. package/dist/infra/instance/file-instance-discovery.d.ts +31 -0
  295. package/dist/infra/instance/file-instance-discovery.js +84 -0
  296. package/dist/infra/instance/file-instance-manager.d.ts +46 -0
  297. package/dist/infra/instance/file-instance-manager.js +123 -0
  298. package/dist/infra/instance/index.d.ts +3 -0
  299. package/dist/infra/instance/index.js +3 -0
  300. package/dist/infra/instance/process-utils.d.ts +14 -0
  301. package/dist/infra/instance/process-utils.js +39 -0
  302. package/dist/infra/process/agent-worker.d.ts +20 -0
  303. package/dist/infra/process/agent-worker.js +602 -0
  304. package/dist/infra/process/index.d.ts +12 -0
  305. package/dist/infra/process/index.js +11 -0
  306. package/dist/infra/process/ipc-types.d.ts +55 -0
  307. package/dist/infra/process/ipc-types.js +12 -0
  308. package/dist/infra/process/process-manager.d.ts +154 -0
  309. package/dist/infra/process/process-manager.js +471 -0
  310. package/dist/infra/process/task-queue-manager.d.ts +123 -0
  311. package/dist/infra/process/task-queue-manager.js +226 -0
  312. package/dist/infra/process/transport-handlers.d.ts +124 -0
  313. package/dist/infra/process/transport-handlers.js +348 -0
  314. package/dist/infra/process/transport-worker.d.ts +20 -0
  315. package/dist/infra/process/transport-worker.js +168 -0
  316. package/dist/infra/repl/commands/curate-command.js +0 -5
  317. package/dist/infra/repl/commands/query-command.js +0 -3
  318. package/dist/infra/repl/repl-startup.d.ts +4 -0
  319. package/dist/infra/repl/repl-startup.js +8 -1
  320. package/dist/infra/repl/transport-client-helper.d.ts +9 -0
  321. package/dist/infra/repl/transport-client-helper.js +96 -0
  322. package/dist/infra/transport/index.d.ts +4 -0
  323. package/dist/infra/transport/index.js +4 -0
  324. package/dist/infra/transport/port-utils.d.ts +42 -0
  325. package/dist/infra/transport/port-utils.js +84 -0
  326. package/dist/infra/transport/socket-io-transport-client.d.ts +45 -0
  327. package/dist/infra/transport/socket-io-transport-client.js +270 -0
  328. package/dist/infra/transport/socket-io-transport-server.d.ts +35 -0
  329. package/dist/infra/transport/socket-io-transport-server.js +207 -0
  330. package/dist/infra/transport/transport-client-factory.d.ts +76 -0
  331. package/dist/infra/transport/transport-client-factory.js +168 -0
  332. package/dist/infra/transport/transport-factory.d.ts +33 -0
  333. package/dist/infra/transport/transport-factory.js +59 -0
  334. package/dist/infra/usecase/curate-use-case.d.ts +8 -55
  335. package/dist/infra/usecase/curate-use-case.js +71 -262
  336. package/dist/infra/usecase/init-use-case.js +3 -2
  337. package/dist/infra/usecase/query-use-case.d.ts +18 -45
  338. package/dist/infra/usecase/query-use-case.js +250 -326
  339. package/dist/infra/usecase/status-use-case.js +1 -1
  340. package/dist/resources/prompts/{curate-context-tree-curation.yml → curate.yml} +25 -22
  341. package/dist/resources/prompts/explore.yml +78 -0
  342. package/dist/resources/prompts/plan.yml +114 -0
  343. package/dist/resources/prompts/reflection.yml +1 -1
  344. package/dist/resources/prompts/system-prompt.yml +15 -8
  345. package/dist/resources/prompts/tool-outputs.yml +0 -5
  346. package/dist/resources/tools/bash_exec.txt +98 -0
  347. package/dist/resources/tools/bash_output.txt +40 -0
  348. package/dist/resources/tools/batch.txt +28 -0
  349. package/dist/resources/tools/create_knowledge_topic.txt +23 -0
  350. package/dist/resources/tools/curate.txt +22 -0
  351. package/dist/resources/tools/delete_memory.txt +1 -0
  352. package/dist/resources/tools/detect_domains.txt +11 -0
  353. package/dist/resources/tools/edit_file.txt +1 -0
  354. package/dist/resources/tools/edit_memory.txt +1 -0
  355. package/dist/resources/tools/glob_files.txt +20 -0
  356. package/dist/resources/tools/grep_content.txt +18 -0
  357. package/dist/resources/tools/kill_process.txt +16 -0
  358. package/dist/resources/tools/list_directory.txt +16 -0
  359. package/dist/resources/tools/list_memories.txt +1 -0
  360. package/dist/resources/tools/read_file.txt +31 -0
  361. package/dist/resources/tools/read_memory.txt +1 -0
  362. package/dist/resources/tools/read_todos.txt +17 -0
  363. package/dist/resources/tools/search_history.txt +1 -0
  364. package/dist/resources/tools/task.txt +23 -0
  365. package/dist/resources/tools/write_file.txt +1 -0
  366. package/dist/resources/tools/write_memory.txt +1 -0
  367. package/dist/resources/tools/write_todos.txt +29 -0
  368. package/dist/tui/app.js +9 -13
  369. package/dist/tui/components/command-details.d.ts +14 -0
  370. package/dist/tui/components/command-details.js +35 -0
  371. package/dist/tui/components/execution/execution-changes.d.ts +5 -0
  372. package/dist/tui/components/execution/execution-changes.js +19 -4
  373. package/dist/tui/components/execution/execution-content.d.ts +4 -2
  374. package/dist/tui/components/execution/execution-content.js +26 -13
  375. package/dist/tui/components/execution/execution-input.js +3 -3
  376. package/dist/tui/components/execution/execution-progress.d.ts +2 -2
  377. package/dist/tui/components/execution/execution-progress.js +8 -6
  378. package/dist/tui/components/execution/log-item.d.ts +3 -4
  379. package/dist/tui/components/execution/log-item.js +2 -5
  380. package/dist/tui/components/footer.js +9 -4
  381. package/dist/tui/components/header.d.ts +3 -3
  382. package/dist/tui/components/header.js +5 -3
  383. package/dist/tui/components/index.d.ts +1 -0
  384. package/dist/tui/components/index.js +1 -0
  385. package/dist/tui/components/onboarding/copyable-prompt.d.ts +5 -3
  386. package/dist/tui/components/onboarding/copyable-prompt.js +7 -8
  387. package/dist/tui/components/onboarding/onboarding-flow.js +35 -25
  388. package/dist/tui/components/scrollable-list.js +12 -10
  389. package/dist/tui/components/suggestions.js +39 -41
  390. package/dist/tui/components/tab-bar.d.ts +2 -1
  391. package/dist/tui/components/tab-bar.js +3 -4
  392. package/dist/tui/constants.d.ts +0 -5
  393. package/dist/tui/constants.js +0 -5
  394. package/dist/tui/contexts/auth-context.js +9 -2
  395. package/dist/tui/contexts/{use-commands.js → commands-context.js} +3 -3
  396. package/dist/tui/contexts/index.d.ts +6 -1
  397. package/dist/tui/contexts/index.js +6 -1
  398. package/dist/tui/contexts/onboarding-context.d.ts +1 -1
  399. package/dist/tui/contexts/onboarding-context.js +9 -9
  400. package/dist/tui/contexts/tasks-context.d.ts +84 -0
  401. package/dist/tui/contexts/tasks-context.js +218 -0
  402. package/dist/tui/contexts/transport-context.d.ts +29 -0
  403. package/dist/tui/contexts/transport-context.js +82 -0
  404. package/dist/tui/hooks/index.d.ts +10 -6
  405. package/dist/tui/hooks/index.js +7 -6
  406. package/dist/tui/hooks/use-activity-logs.d.ts +3 -11
  407. package/dist/tui/hooks/use-activity-logs.js +87 -34
  408. package/dist/tui/hooks/use-auth-polling.d.ts +24 -0
  409. package/dist/tui/hooks/use-auth-polling.js +104 -0
  410. package/dist/tui/hooks/use-slash-command-processor.js +0 -1
  411. package/dist/tui/hooks/use-slash-completion.js +1 -1
  412. package/dist/tui/hooks/use-tab-navigation.d.ts +2 -1
  413. package/dist/tui/hooks/use-tab-navigation.js +16 -7
  414. package/dist/tui/hooks/use-terminal-breakpoint.d.ts +21 -0
  415. package/dist/tui/hooks/use-terminal-breakpoint.js +38 -0
  416. package/dist/tui/hooks/use-ui-heights.d.ts +120 -0
  417. package/dist/tui/hooks/use-ui-heights.js +88 -0
  418. package/dist/tui/providers/app-providers.js +2 -6
  419. package/dist/tui/types/commands.d.ts +0 -26
  420. package/dist/tui/types/index.d.ts +1 -1
  421. package/dist/tui/types/ui.d.ts +9 -4
  422. package/dist/tui/utils/line.d.ts +11 -0
  423. package/dist/tui/utils/line.js +16 -0
  424. package/dist/tui/utils/log.d.ts +27 -0
  425. package/dist/tui/utils/log.js +114 -0
  426. package/dist/tui/views/command-view.d.ts +7 -0
  427. package/dist/tui/views/command-view.js +103 -80
  428. package/dist/tui/views/login-view.js +7 -4
  429. package/dist/tui/views/logs-view.d.ts +13 -0
  430. package/dist/tui/views/logs-view.js +27 -52
  431. package/dist/utils/connection-error-handler.d.ts +16 -0
  432. package/dist/utils/connection-error-handler.js +49 -0
  433. package/dist/utils/crash-log.d.ts +14 -0
  434. package/dist/utils/crash-log.js +19 -0
  435. package/dist/utils/file-helpers.d.ts +14 -0
  436. package/dist/utils/file-helpers.js +21 -0
  437. package/dist/utils/global-logs-path.d.ts +11 -0
  438. package/dist/utils/global-logs-path.js +37 -0
  439. package/dist/utils/process-logger.d.ts +53 -0
  440. package/dist/utils/process-logger.js +253 -0
  441. package/dist/utils/sandbox-detector.d.ts +31 -0
  442. package/dist/utils/sandbox-detector.js +122 -0
  443. package/oclif.manifest.json +10 -198
  444. package/package.json +5 -1
  445. package/dist/commands/cipher-agent/run.d.ts +0 -142
  446. package/dist/commands/cipher-agent/run.js +0 -555
  447. package/dist/commands/cipher-agent/set-prompt.d.ts +0 -16
  448. package/dist/commands/cipher-agent/set-prompt.js +0 -58
  449. package/dist/commands/cipher-agent/show-prompt.d.ts +0 -13
  450. package/dist/commands/cipher-agent/show-prompt.js +0 -53
  451. package/dist/commands/foo.d.ts +0 -14
  452. package/dist/commands/foo.js +0 -66
  453. package/dist/infra/cipher/agent-service-factory.d.ts +0 -93
  454. package/dist/infra/cipher/cipher-agent-state-manager.d.ts +0 -63
  455. package/dist/infra/cipher/cipher-agent-state-manager.js +0 -108
  456. package/dist/infra/cipher/cipher-agent.d.ts +0 -182
  457. package/dist/infra/cipher/cipher-agent.js +0 -317
  458. package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +0 -106
  459. package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +0 -297
  460. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.d.ts +0 -7
  461. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +0 -424
  462. package/dist/resources/prompts/modes/autonomous.yml +0 -9
  463. package/dist/resources/prompts/query-context-tree-retrieval.yml +0 -48
  464. package/dist/tui/contexts/consumer.d.ts +0 -31
  465. package/dist/tui/contexts/consumer.js +0 -56
  466. package/dist/tui/hooks/use-consumer.d.ts +0 -12
  467. package/dist/tui/hooks/use-consumer.js +0 -50
  468. package/dist/tui/hooks/use-queue-polling.d.ts +0 -31
  469. package/dist/tui/hooks/use-queue-polling.js +0 -90
  470. /package/dist/tui/contexts/{use-commands.d.ts → commands-context.d.ts} +0 -0
  471. /package/dist/tui/contexts/{use-mode.d.ts → mode-context.d.ts} +0 -0
  472. /package/dist/tui/contexts/{use-mode.js → mode-context.js} +0 -0
  473. /package/dist/tui/contexts/{use-theme.d.ts → theme-context.d.ts} +0 -0
  474. /package/dist/tui/contexts/{use-theme.js → theme-context.js} +0 -0
@@ -0,0 +1,90 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ /**
3
+ * Service for buffering user messages when a session is busy executing.
4
+ *
5
+ * When the LLM is processing a request, new messages from the user are
6
+ * queued and coalesced into a single input when the session becomes available.
7
+ *
8
+ * This improves UX by allowing users to add context while waiting for responses.
9
+ */
10
+ export class MessageQueueService {
11
+ eventBus;
12
+ queue = [];
13
+ /**
14
+ * Creates a new message queue service.
15
+ *
16
+ * @param eventBus - Optional session event bus for queue events
17
+ */
18
+ constructor(eventBus) {
19
+ this.eventBus = eventBus;
20
+ }
21
+ /**
22
+ * Clear all queued messages without processing.
23
+ */
24
+ clear() {
25
+ this.queue.length = 0;
26
+ }
27
+ /**
28
+ * Dequeue all messages and coalesce into single input.
29
+ * Messages are combined intelligently based on count.
30
+ *
31
+ * @returns Coalesced content with images/files, or null if queue is empty
32
+ */
33
+ dequeueAll() {
34
+ if (this.queue.length === 0) {
35
+ return null;
36
+ }
37
+ const messages = [...this.queue];
38
+ this.queue.length = 0;
39
+ this.eventBus?.emit('message:dequeued', { count: messages.length });
40
+ // Collect all attachments
41
+ const images = [];
42
+ const files = [];
43
+ for (const msg of messages) {
44
+ if (msg.imageData)
45
+ images.push(msg.imageData);
46
+ if (msg.fileData)
47
+ files.push(msg.fileData);
48
+ }
49
+ // Coalesce message content based on count
50
+ let content;
51
+ if (messages.length === 1) {
52
+ content = messages[0].content;
53
+ }
54
+ else if (messages.length === 2) {
55
+ content = `First: ${messages[0].content}\n\nAlso: ${messages[1].content}`;
56
+ }
57
+ else {
58
+ content = messages.map((m, i) => `[${i + 1}]: ${m.content}`).join('\n\n');
59
+ }
60
+ return { content, files, images };
61
+ }
62
+ /**
63
+ * Queue a message for later processing.
64
+ *
65
+ * @param message - Message to queue (without id and queuedAt)
66
+ * @returns Queue position (1-based)
67
+ */
68
+ enqueue(message) {
69
+ const queued = {
70
+ ...message,
71
+ id: randomUUID(),
72
+ queuedAt: Date.now(),
73
+ };
74
+ this.queue.push(queued);
75
+ this.eventBus?.emit('message:queued', { message: queued, position: this.queue.length });
76
+ return this.queue.length;
77
+ }
78
+ /**
79
+ * Check if there are pending messages in the queue.
80
+ */
81
+ hasPending() {
82
+ return this.queue.length > 0;
83
+ }
84
+ /**
85
+ * Get the number of pending messages.
86
+ */
87
+ pendingCount() {
88
+ return this.queue.length;
89
+ }
90
+ }
@@ -1,6 +1,33 @@
1
1
  import type { CipherAgentServices, SessionManagerConfig } from '../../../core/interfaces/cipher/cipher-services.js';
2
2
  import type { IChatSession } from '../../../core/interfaces/cipher/i-chat-session.js';
3
- import type { ByteRoverHttpConfig } from '../agent-service-factory.js';
3
+ import type { FileSystemService } from '../file-system/file-system-service.js';
4
+ import { type ByteRoverHttpConfig } from '../agent/service-initializer.js';
5
+ /**
6
+ * Service overrides for creating sessions with custom services.
7
+ * Used to create restricted sessions (e.g., context-tree only search).
8
+ */
9
+ export interface SessionServiceOverrides {
10
+ /**
11
+ * Custom file system service to use for this session.
12
+ * If provided, a new ToolProvider and ToolManager will be created
13
+ * using this file system service instead of the shared one.
14
+ */
15
+ fileSystemService?: FileSystemService;
16
+ }
17
+ /**
18
+ * Metadata about a session for listing purposes.
19
+ */
20
+ export interface SessionMetadata {
21
+ /** Name of the agent running this session (e.g., 'plan', 'query', 'curate') */
22
+ agentName?: string;
23
+ createdAt: number;
24
+ id: string;
25
+ lastActivity: number;
26
+ messageCount: number;
27
+ /** Parent session ID for subagent sessions */
28
+ parentId?: string;
29
+ title?: string;
30
+ }
4
31
  /**
5
32
  * Options for SessionManager constructor
6
33
  */
@@ -12,16 +39,22 @@ export interface SessionManagerOptions {
12
39
  *
13
40
  * Manages multiple chat sessions with creation, retrieval, and deletion.
14
41
  * Each session gets its own LLM service instance with isolated context.
15
- *
16
- * Following Dexto's pattern: SessionManager uses shared services from the agent
17
42
  * and creates session-specific services (LLM, EventBus) per conversation.
18
43
  */
19
44
  export declare class SessionManager {
45
+ private cleanupTimer?;
20
46
  private readonly config;
21
47
  private readonly httpConfig;
22
48
  private readonly llmConfig;
23
49
  private pendingCreations;
50
+ /** Agent name for each session (e.g., 'plan', 'query', 'curate') */
51
+ private readonly sessionAgentNames;
52
+ private readonly sessionCreatedAt;
53
+ private readonly sessionLastActivity;
54
+ /** Parent session ID for subagent sessions */
55
+ private readonly sessionParentIds;
24
56
  private readonly sessions;
57
+ private readonly sessionTitles;
25
58
  private readonly sharedServices;
26
59
  /**
27
60
  * Creates a new session manager
@@ -48,11 +81,32 @@ export declare class SessionManager {
48
81
  siteName?: string;
49
82
  temperature?: number;
50
83
  }, options?: SessionManagerOptions);
84
+ /**
85
+ * Create a child session for a subagent.
86
+ * Child sessions are linked to their parent and have an agent name.
87
+ *
88
+ * @param parentId - Parent session ID
89
+ * @param agentName - Name of the agent (e.g., 'query', 'curate')
90
+ * @param sessionId - Optional session ID (generates one if not provided)
91
+ * @returns New child chat session instance
92
+ */
93
+ createChildSession(parentId: string, agentName: string, sessionId?: string): Promise<IChatSession>;
94
+ /**
95
+ * Create a child session for a subagent with custom service overrides.
96
+ * This is used to create sessions with restricted file system access
97
+ * (e.g., context-tree only search for query commands).
98
+ *
99
+ * @param parentId - Parent session ID
100
+ * @param agentName - Name of the agent (e.g., 'explore', 'curate')
101
+ * @param sessionId - Optional session ID (generates one if not provided)
102
+ * @param overrides - Service overrides (e.g., restricted FileSystemService)
103
+ * @returns New child chat session instance with overridden services
104
+ */
105
+ createChildSessionWithOverrides(parentId: string, agentName: string, sessionId?: string, overrides?: SessionServiceOverrides): Promise<IChatSession>;
51
106
  /**
52
107
  * Create a new chat session.
53
108
  *
54
109
  * Each session gets its own LLM service instance for isolated conversation context.
55
- * Following Dexto's pattern with race condition protection via pendingCreations tracker.
56
110
  *
57
111
  * @param sessionId - Optional session ID (generates UUID if not provided)
58
112
  * @returns New or existing chat session instance
@@ -65,9 +119,18 @@ export declare class SessionManager {
65
119
  * @returns True if session existed and was deleted
66
120
  */
67
121
  deleteSession(id: string): Promise<boolean>;
122
+ /**
123
+ * Stop cleanup timer and dispose of all resources.
124
+ * Call this when shutting down the session manager.
125
+ *
126
+ * IMPORTANT: This method now properly disposes all sessions to prevent
127
+ * memory leaks from event forwarders and other session resources.
128
+ */
129
+ dispose(): void;
68
130
  /**
69
131
  * End a session (remove from memory, preserve history for future restoration).
70
- * Currently same as deleteSession since we don't have persistent storage yet.
132
+ * Unlike deleteSession, this preserves the conversation history in storage
133
+ * so the session can be restored later.
71
134
  *
72
135
  * @param id - Session ID to end
73
136
  * @returns True if session existed and was ended
@@ -99,6 +162,34 @@ export declare class SessionManager {
99
162
  * @returns Array of session IDs
100
163
  */
101
164
  listSessions(): string[];
165
+ /**
166
+ * List all sessions with metadata.
167
+ * Returns sessions sorted by last activity (most recent first).
168
+ *
169
+ * @returns Array of session metadata
170
+ */
171
+ listSessionsWithMetadata(): SessionMetadata[];
172
+ /**
173
+ * Set session title from the first user message.
174
+ * Uses heuristic extraction (no LLM call).
175
+ *
176
+ * @param sessionId - Session ID
177
+ * @param firstMessage - First user message
178
+ */
179
+ setSessionTitleFromMessage(sessionId: string, firstMessage: string): void;
180
+ /**
181
+ * Update the last activity timestamp for a session.
182
+ * Should be called after each message exchange.
183
+ *
184
+ * @param sessionId - Session ID
185
+ */
186
+ updateSessionActivity(sessionId: string): void;
187
+ /**
188
+ * Remove sessions that have exceeded TTL.
189
+ *
190
+ * @returns Number of sessions cleaned up
191
+ */
192
+ private cleanupExpiredSessions;
102
193
  /**
103
194
  * Internal session creation logic.
104
195
  *
@@ -106,4 +197,14 @@ export declare class SessionManager {
106
197
  * @returns New chat session instance
107
198
  */
108
199
  private createSessionInternal;
200
+ /**
201
+ * Internal session creation with service overrides.
202
+ * Creates a new ToolProvider and ToolManager with the overridden FileSystemService
203
+ * to provide file access restrictions for the session.
204
+ *
205
+ * @param id - Session ID
206
+ * @param overrides - Service overrides (e.g., restricted FileSystemService)
207
+ * @returns New chat session instance with overridden services
208
+ */
209
+ private createSessionWithOverridesInternal;
109
210
  }
@@ -1,21 +1,33 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { createSessionServices } from '../agent-service-factory.js';
2
+ import { createSessionServices } from '../agent/service-initializer.js';
3
+ import { CoreToolScheduler } from '../tools/core-tool-scheduler.js';
4
+ import { DEFAULT_POLICY_RULES } from '../tools/default-policy-rules.js';
5
+ import { PolicyEngine } from '../tools/policy-engine.js';
6
+ import { ToolManager } from '../tools/tool-manager.js';
7
+ import { ToolProvider } from '../tools/tool-provider.js';
3
8
  import { ChatSession } from './chat-session.js';
9
+ import { generateSessionTitle } from './title-generator.js';
4
10
  /**
5
11
  * Session manager.
6
12
  *
7
13
  * Manages multiple chat sessions with creation, retrieval, and deletion.
8
14
  * Each session gets its own LLM service instance with isolated context.
9
- *
10
- * Following Dexto's pattern: SessionManager uses shared services from the agent
11
15
  * and creates session-specific services (LLM, EventBus) per conversation.
12
16
  */
13
17
  export class SessionManager {
18
+ cleanupTimer;
14
19
  config;
15
20
  httpConfig;
16
21
  llmConfig;
17
22
  pendingCreations = new Map();
23
+ /** Agent name for each session (e.g., 'plan', 'query', 'curate') */
24
+ sessionAgentNames = new Map();
25
+ sessionCreatedAt = new Map();
26
+ sessionLastActivity = new Map();
27
+ /** Parent session ID for subagent sessions */
28
+ sessionParentIds = new Map();
18
29
  sessions = new Map();
30
+ sessionTitles = new Map();
19
31
  sharedServices;
20
32
  /**
21
33
  * Creates a new session manager
@@ -41,12 +53,89 @@ export class SessionManager {
41
53
  maxSessions: options?.config?.maxSessions ?? 100,
42
54
  sessionTTL: options?.config?.sessionTTL ?? 3_600_000, // 1 hour
43
55
  };
56
+ // Start periodic cleanup (every 15 minutes or 1/4 TTL, whichever is smaller)
57
+ const cleanupInterval = Math.min(15 * 60 * 1000, this.config.sessionTTL / 4);
58
+ this.cleanupTimer = setInterval(() => {
59
+ this.cleanupExpiredSessions().catch(() => {
60
+ // Silently ignore cleanup errors
61
+ });
62
+ }, cleanupInterval);
63
+ }
64
+ /**
65
+ * Create a child session for a subagent.
66
+ * Child sessions are linked to their parent and have an agent name.
67
+ *
68
+ * @param parentId - Parent session ID
69
+ * @param agentName - Name of the agent (e.g., 'query', 'curate')
70
+ * @param sessionId - Optional session ID (generates one if not provided)
71
+ * @returns New child chat session instance
72
+ */
73
+ async createChildSession(parentId, agentName, sessionId) {
74
+ // Generate session ID if not provided
75
+ const id = sessionId ?? `${agentName}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
76
+ // Create the session using normal flow
77
+ const session = await this.createSession(id);
78
+ // Track parent-child relationship and agent name
79
+ this.sessionParentIds.set(id, parentId);
80
+ this.sessionAgentNames.set(id, agentName);
81
+ return session;
82
+ }
83
+ /**
84
+ * Create a child session for a subagent with custom service overrides.
85
+ * This is used to create sessions with restricted file system access
86
+ * (e.g., context-tree only search for query commands).
87
+ *
88
+ * @param parentId - Parent session ID
89
+ * @param agentName - Name of the agent (e.g., 'explore', 'curate')
90
+ * @param sessionId - Optional session ID (generates one if not provided)
91
+ * @param overrides - Service overrides (e.g., restricted FileSystemService)
92
+ * @returns New child chat session instance with overridden services
93
+ */
94
+ async createChildSessionWithOverrides(parentId, agentName, sessionId, overrides) {
95
+ // If no overrides, use the standard createChildSession
96
+ if (!overrides?.fileSystemService) {
97
+ return this.createChildSession(parentId, agentName, sessionId);
98
+ }
99
+ // Generate session ID if not provided
100
+ const id = sessionId ?? `${agentName}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
101
+ // Check pending operations (race condition protection)
102
+ if (this.pendingCreations.has(id)) {
103
+ const pending = this.pendingCreations.get(id);
104
+ if (!pending) {
105
+ throw new Error(`Pending session ${id} not found. This is a bug.`);
106
+ }
107
+ return pending;
108
+ }
109
+ // Check in-memory cache
110
+ if (this.sessions.has(id)) {
111
+ const existing = this.sessions.get(id);
112
+ if (!existing) {
113
+ throw new Error(`Session ${id} not found in cache. This is a bug.`);
114
+ }
115
+ return existing;
116
+ }
117
+ // Check max sessions limit
118
+ if (this.sessions.size >= this.config.maxSessions) {
119
+ throw new Error(`Maximum sessions (${this.config.maxSessions}) reached. Delete unused sessions or increase maxSessions limit.`);
120
+ }
121
+ // Create with pending tracker
122
+ const creationPromise = this.createSessionWithOverridesInternal(id, overrides);
123
+ this.pendingCreations.set(id, creationPromise);
124
+ try {
125
+ const session = await creationPromise;
126
+ // Track parent-child relationship and agent name
127
+ this.sessionParentIds.set(id, parentId);
128
+ this.sessionAgentNames.set(id, agentName);
129
+ return session;
130
+ }
131
+ finally {
132
+ this.pendingCreations.delete(id);
133
+ }
44
134
  }
45
135
  /**
46
136
  * Create a new chat session.
47
137
  *
48
138
  * Each session gets its own LLM service instance for isolated conversation context.
49
- * Following Dexto's pattern with race condition protection via pendingCreations tracker.
50
139
  *
51
140
  * @param sessionId - Optional session ID (generates UUID if not provided)
52
141
  * @returns New or existing chat session instance
@@ -99,9 +188,38 @@ export class SessionManager {
99
188
  // Remove from memory
100
189
  return this.sessions.delete(id);
101
190
  }
191
+ /**
192
+ * Stop cleanup timer and dispose of all resources.
193
+ * Call this when shutting down the session manager.
194
+ *
195
+ * IMPORTANT: This method now properly disposes all sessions to prevent
196
+ * memory leaks from event forwarders and other session resources.
197
+ */
198
+ dispose() {
199
+ // Clear cleanup timer
200
+ if (this.cleanupTimer) {
201
+ clearInterval(this.cleanupTimer);
202
+ this.cleanupTimer = undefined;
203
+ }
204
+ // Dispose all sessions (prevents event forwarder leaks)
205
+ for (const session of this.sessions.values()) {
206
+ // ChatSession.dispose() removes event forwarders
207
+ ;
208
+ session.dispose();
209
+ }
210
+ this.sessions.clear();
211
+ // Clear all metadata maps
212
+ this.sessionCreatedAt.clear();
213
+ this.sessionLastActivity.clear();
214
+ this.sessionTitles.clear();
215
+ this.sessionAgentNames.clear();
216
+ this.sessionParentIds.clear();
217
+ this.pendingCreations.clear();
218
+ }
102
219
  /**
103
220
  * End a session (remove from memory, preserve history for future restoration).
104
- * Currently same as deleteSession since we don't have persistent storage yet.
221
+ * Unlike deleteSession, this preserves the conversation history in storage
222
+ * so the session can be restored later.
105
223
  *
106
224
  * @param id - Session ID to end
107
225
  * @returns True if session existed and was ended
@@ -111,8 +229,12 @@ export class SessionManager {
111
229
  if (!session) {
112
230
  return false;
113
231
  }
114
- // In the future, this would preserve history in storage
115
- // For now, just remove from memory
232
+ // Ensure history is persisted before removing from memory
233
+ const contextManager = session.getLLMService().getContextManager();
234
+ await contextManager.flush();
235
+ // Cleanup session resources (cancels in-flight ops, preserves history)
236
+ session.cleanup();
237
+ // Remove from memory only - history remains in storage
116
238
  return this.sessions.delete(id);
117
239
  }
118
240
  /**
@@ -149,6 +271,73 @@ export class SessionManager {
149
271
  listSessions() {
150
272
  return [...this.sessions.keys()];
151
273
  }
274
+ /**
275
+ * List all sessions with metadata.
276
+ * Returns sessions sorted by last activity (most recent first).
277
+ *
278
+ * @returns Array of session metadata
279
+ */
280
+ listSessionsWithMetadata() {
281
+ const sessions = [];
282
+ for (const [id, session] of this.sessions) {
283
+ const contextManager = session.getLLMService().getContextManager();
284
+ sessions.push({
285
+ agentName: this.sessionAgentNames.get(id),
286
+ createdAt: this.sessionCreatedAt.get(id) ?? Date.now(),
287
+ id,
288
+ lastActivity: this.sessionLastActivity.get(id) ?? Date.now(),
289
+ messageCount: contextManager.getMessages().length,
290
+ parentId: this.sessionParentIds.get(id),
291
+ title: this.sessionTitles.get(id),
292
+ });
293
+ }
294
+ // Sort by last activity (most recent first)
295
+ return sessions.sort((a, b) => b.lastActivity - a.lastActivity);
296
+ }
297
+ /**
298
+ * Set session title from the first user message.
299
+ * Uses heuristic extraction (no LLM call).
300
+ *
301
+ * @param sessionId - Session ID
302
+ * @param firstMessage - First user message
303
+ */
304
+ setSessionTitleFromMessage(sessionId, firstMessage) {
305
+ const session = this.sessions.get(sessionId);
306
+ if (!session) {
307
+ return;
308
+ }
309
+ const title = generateSessionTitle(firstMessage);
310
+ this.sessionTitles.set(sessionId, title);
311
+ }
312
+ /**
313
+ * Update the last activity timestamp for a session.
314
+ * Should be called after each message exchange.
315
+ *
316
+ * @param sessionId - Session ID
317
+ */
318
+ updateSessionActivity(sessionId) {
319
+ if (this.sessions.has(sessionId)) {
320
+ this.sessionLastActivity.set(sessionId, Date.now());
321
+ }
322
+ }
323
+ /**
324
+ * Remove sessions that have exceeded TTL.
325
+ *
326
+ * @returns Number of sessions cleaned up
327
+ */
328
+ async cleanupExpiredSessions() {
329
+ const now = Date.now();
330
+ let cleaned = 0;
331
+ for (const [id] of this.sessions) {
332
+ const lastActivity = this.sessionLastActivity.get(id) ?? 0;
333
+ if (now - lastActivity > this.config.sessionTTL) {
334
+ // eslint-disable-next-line no-await-in-loop
335
+ await this.endSession(id); // Preserve history
336
+ cleaned++;
337
+ }
338
+ }
339
+ return cleaned;
340
+ }
152
341
  /**
153
342
  * Internal session creation logic.
154
343
  *
@@ -166,6 +355,64 @@ export class SessionManager {
166
355
  await sessionServices.llmService.initialize();
167
356
  // Debug logging removed for cleaner user experience
168
357
  }
358
+ // Track session metadata
359
+ const now = Date.now();
360
+ this.sessionCreatedAt.set(id, now);
361
+ this.sessionLastActivity.set(id, now);
362
+ this.sessions.set(id, session);
363
+ return session;
364
+ }
365
+ /**
366
+ * Internal session creation with service overrides.
367
+ * Creates a new ToolProvider and ToolManager with the overridden FileSystemService
368
+ * to provide file access restrictions for the session.
369
+ *
370
+ * @param id - Session ID
371
+ * @param overrides - Service overrides (e.g., restricted FileSystemService)
372
+ * @returns New chat session instance with overridden services
373
+ */
374
+ async createSessionWithOverridesInternal(id, overrides) {
375
+ // Create a holder object to allow self-reference in the getToolProvider callback
376
+ const toolProviderHolder = {};
377
+ // Create a new ToolProvider with the overridden FileSystemService
378
+ const overriddenToolProvider = new ToolProvider({
379
+ fileSystemService: overrides.fileSystemService,
380
+ getToolProvider: () => toolProviderHolder.provider,
381
+ memoryManager: this.sharedServices.memoryManager,
382
+ processService: this.sharedServices.processService,
383
+ }, this.sharedServices.systemPromptManager);
384
+ toolProviderHolder.provider = overriddenToolProvider;
385
+ await overriddenToolProvider.initialize();
386
+ // Create a new PolicyEngine and ToolScheduler for the overridden session
387
+ const overriddenPolicyEngine = new PolicyEngine({ defaultDecision: 'ALLOW' });
388
+ overriddenPolicyEngine.addRules(DEFAULT_POLICY_RULES);
389
+ const overriddenToolScheduler = new CoreToolScheduler(overriddenToolProvider, overriddenPolicyEngine, undefined, {
390
+ verbose: false,
391
+ });
392
+ // Create a new ToolManager with the overridden ToolProvider
393
+ const overriddenToolManager = new ToolManager(overriddenToolProvider, overriddenToolScheduler);
394
+ await overriddenToolManager.initialize();
395
+ // Create overridden shared services with the new tool stack
396
+ const overriddenSharedServices = {
397
+ ...this.sharedServices,
398
+ fileSystemService: overrides.fileSystemService,
399
+ policyEngine: overriddenPolicyEngine,
400
+ toolManager: overriddenToolManager,
401
+ toolProvider: overriddenToolProvider,
402
+ toolScheduler: overriddenToolScheduler,
403
+ };
404
+ // Create session-specific services using the overridden shared services
405
+ const sessionServices = createSessionServices(id, overriddenSharedServices, this.httpConfig, this.llmConfig);
406
+ // Create session with overridden shared services
407
+ const session = new ChatSession(id, overriddenSharedServices, sessionServices);
408
+ // Initialize LLM service to load persisted history from blob storage
409
+ if ('initialize' in sessionServices.llmService && typeof sessionServices.llmService.initialize === 'function') {
410
+ await sessionServices.llmService.initialize();
411
+ }
412
+ // Track session metadata
413
+ const now = Date.now();
414
+ this.sessionCreatedAt.set(id, now);
415
+ this.sessionLastActivity.set(id, now);
169
416
  this.sessions.set(id, session);
170
417
  return session;
171
418
  }