byterover-cli 0.4.0 → 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 (478) 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/entities/event.d.ts +1 -1
  49. package/dist/core/domain/entities/event.js +3 -1
  50. package/dist/core/domain/errors/connection-error.d.ts +33 -0
  51. package/dist/core/domain/errors/connection-error.js +54 -0
  52. package/dist/core/domain/errors/core-process-error.d.ts +27 -0
  53. package/dist/core/domain/errors/core-process-error.js +43 -0
  54. package/dist/core/domain/errors/task-error.d.ts +64 -0
  55. package/dist/core/domain/errors/task-error.js +116 -0
  56. package/dist/core/domain/errors/transport-error.d.ts +72 -0
  57. package/dist/core/domain/errors/transport-error.js +114 -0
  58. package/dist/core/domain/instance/index.d.ts +1 -0
  59. package/dist/core/domain/instance/index.js +1 -0
  60. package/dist/core/domain/instance/types.d.ts +57 -0
  61. package/dist/core/domain/instance/types.js +72 -0
  62. package/dist/core/domain/knowledge/directory-manager.d.ts +16 -0
  63. package/dist/core/domain/knowledge/directory-manager.js +31 -0
  64. package/dist/core/domain/transport/index.d.ts +2 -0
  65. package/dist/core/domain/transport/index.js +2 -0
  66. package/dist/core/domain/transport/schemas.d.ts +1149 -0
  67. package/dist/core/domain/transport/schemas.js +554 -0
  68. package/dist/core/domain/transport/types.d.ts +67 -0
  69. package/dist/core/domain/transport/types.js +7 -0
  70. package/dist/core/interfaces/cipher/cipher-services.d.ts +15 -3
  71. package/dist/core/interfaces/cipher/i-chat-session.d.ts +47 -5
  72. package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +39 -4
  73. package/dist/core/interfaces/cipher/i-content-generator.d.ts +3 -5
  74. package/dist/core/interfaces/cipher/i-file-system.d.ts +12 -1
  75. package/dist/core/interfaces/cipher/i-llm-service.d.ts +4 -5
  76. package/dist/core/interfaces/cipher/i-todo-storage.d.ts +24 -0
  77. package/dist/core/interfaces/cipher/i-todo-storage.js +1 -0
  78. package/dist/core/interfaces/cipher/i-tool-plugin.d.ts +90 -0
  79. package/dist/core/interfaces/cipher/i-tool-plugin.js +1 -0
  80. package/dist/core/interfaces/cipher/i-tool-provider.d.ts +3 -2
  81. package/dist/core/interfaces/cipher/i-tool-scheduler.d.ts +4 -0
  82. package/dist/core/interfaces/cipher/index.d.ts +35 -0
  83. package/dist/core/interfaces/cipher/index.js +11 -0
  84. package/dist/core/interfaces/cipher/message-factory.d.ts +155 -0
  85. package/dist/core/interfaces/cipher/message-factory.js +252 -0
  86. package/dist/core/interfaces/cipher/message-type-guards.d.ts +139 -0
  87. package/dist/core/interfaces/cipher/message-type-guards.js +173 -0
  88. package/dist/core/interfaces/cipher/message-types.d.ts +279 -5
  89. package/dist/core/interfaces/cipher/message-types.js +6 -0
  90. package/dist/core/interfaces/cipher/sanitization-types.d.ts +147 -0
  91. package/dist/core/interfaces/cipher/sanitization-types.js +46 -0
  92. package/dist/core/interfaces/executor/i-curate-executor.d.ts +34 -0
  93. package/dist/core/interfaces/executor/i-curate-executor.js +1 -0
  94. package/dist/core/interfaces/executor/i-query-executor.d.ts +32 -0
  95. package/dist/core/interfaces/executor/i-query-executor.js +1 -0
  96. package/dist/core/interfaces/executor/index.d.ts +2 -0
  97. package/dist/core/interfaces/executor/index.js +2 -0
  98. package/dist/core/interfaces/instance/i-instance-discovery.d.ts +45 -0
  99. package/dist/core/interfaces/instance/i-instance-discovery.js +1 -0
  100. package/dist/core/interfaces/instance/i-instance-manager.d.ts +58 -0
  101. package/dist/core/interfaces/instance/i-instance-manager.js +1 -0
  102. package/dist/core/interfaces/instance/index.d.ts +2 -0
  103. package/dist/core/interfaces/instance/index.js +2 -0
  104. package/dist/core/interfaces/noop-implementations.d.ts +53 -0
  105. package/dist/core/interfaces/noop-implementations.js +62 -0
  106. package/dist/core/interfaces/transport/i-transport-client.d.ts +97 -0
  107. package/dist/core/interfaces/transport/i-transport-client.js +1 -0
  108. package/dist/core/interfaces/transport/i-transport-server.d.ts +93 -0
  109. package/dist/core/interfaces/transport/i-transport-server.js +1 -0
  110. package/dist/core/interfaces/transport/index.d.ts +2 -0
  111. package/dist/core/interfaces/transport/index.js +2 -0
  112. package/dist/hooks/init/welcome.js +9 -24
  113. package/dist/infra/cipher/agent/agent-error-codes.d.ts +16 -0
  114. package/dist/infra/cipher/agent/agent-error-codes.js +17 -0
  115. package/dist/infra/cipher/agent/agent-error.d.ts +54 -0
  116. package/dist/infra/cipher/agent/agent-error.js +79 -0
  117. package/dist/infra/cipher/agent/agent-schemas.d.ts +264 -0
  118. package/dist/infra/cipher/agent/agent-schemas.js +97 -0
  119. package/dist/infra/cipher/agent/agent-state-manager.d.ts +140 -0
  120. package/dist/infra/cipher/agent/agent-state-manager.js +275 -0
  121. package/dist/infra/cipher/agent/base-agent.d.ts +118 -0
  122. package/dist/infra/cipher/agent/base-agent.js +240 -0
  123. package/dist/infra/cipher/agent/cipher-agent.d.ts +165 -0
  124. package/dist/infra/cipher/agent/cipher-agent.js +546 -0
  125. package/dist/infra/cipher/agent/index.d.ts +22 -0
  126. package/dist/infra/cipher/agent/index.js +24 -0
  127. package/dist/infra/cipher/agent/service-initializer.d.ts +79 -0
  128. package/dist/infra/cipher/{agent-service-factory.js → agent/service-initializer.js} +117 -68
  129. package/dist/infra/cipher/agent/types.d.ts +35 -0
  130. package/dist/infra/cipher/agent/types.js +1 -0
  131. package/dist/infra/cipher/blob/blob-reference-resolver.d.ts +107 -0
  132. package/dist/infra/cipher/blob/blob-reference-resolver.js +228 -0
  133. package/dist/infra/cipher/blob/blob-reference-utils.d.ts +117 -0
  134. package/dist/infra/cipher/blob/blob-reference-utils.js +230 -0
  135. package/dist/infra/cipher/consumer/consumer-lock.js +1 -0
  136. package/dist/infra/cipher/consumer/consumer-service.js +1 -0
  137. package/dist/infra/cipher/consumer/execution-consumer.d.ts +6 -1
  138. package/dist/infra/cipher/consumer/execution-consumer.js +54 -16
  139. package/dist/infra/cipher/consumer/index.d.ts +1 -1
  140. package/dist/infra/cipher/consumer/index.js +2 -1
  141. package/dist/infra/cipher/consumer/queue-polling-service.js +1 -0
  142. package/dist/infra/cipher/file-system/binary-utils.d.ts +43 -0
  143. package/dist/infra/cipher/file-system/binary-utils.js +164 -0
  144. package/dist/infra/cipher/file-system/context-tree-file-system-factory.d.ts +9 -0
  145. package/dist/infra/cipher/file-system/context-tree-file-system-factory.js +24 -0
  146. package/dist/infra/cipher/file-system/file-system-service.d.ts +17 -1
  147. package/dist/infra/cipher/file-system/file-system-service.js +327 -36
  148. package/dist/infra/cipher/file-system/path-validator.d.ts +32 -0
  149. package/dist/infra/cipher/file-system/path-validator.js +111 -6
  150. package/dist/infra/cipher/interactive-loop.js +41 -33
  151. package/dist/infra/cipher/llm/capability-cache.d.ts +87 -0
  152. package/dist/infra/cipher/llm/capability-cache.js +125 -0
  153. package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +32 -0
  154. package/dist/infra/cipher/llm/context/compaction/compaction-service.js +44 -3
  155. package/dist/infra/cipher/llm/context/compression/enhanced-compaction.d.ts +112 -0
  156. package/dist/infra/cipher/llm/context/compression/enhanced-compaction.js +175 -0
  157. package/dist/infra/cipher/llm/context/compression/filter-compacted.d.ts +83 -0
  158. package/dist/infra/cipher/llm/context/compression/filter-compacted.js +150 -0
  159. package/dist/infra/cipher/llm/context/compression/index.d.ts +5 -0
  160. package/dist/infra/cipher/llm/context/compression/index.js +6 -0
  161. package/dist/infra/cipher/llm/context/compression/reactive-overflow.d.ts +107 -0
  162. package/dist/infra/cipher/llm/context/compression/reactive-overflow.js +272 -0
  163. package/dist/infra/cipher/llm/context/context-manager.d.ts +47 -1
  164. package/dist/infra/cipher/llm/context/context-manager.js +129 -0
  165. package/dist/infra/cipher/llm/context/utils.js +17 -4
  166. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +4 -2
  167. package/dist/infra/cipher/llm/internal-llm-service.d.ts +50 -17
  168. package/dist/infra/cipher/llm/internal-llm-service.js +273 -50
  169. package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +6 -8
  170. package/dist/infra/cipher/llm/openrouter-llm-service.js +14 -16
  171. package/dist/infra/cipher/llm/retry/retry-policy.d.ts +1 -0
  172. package/dist/infra/cipher/llm/retry/retry-policy.js +11 -0
  173. package/dist/infra/cipher/llm/retry/retry-with-backoff.js +3 -2
  174. package/dist/infra/cipher/llm/sanitization/base64-utils.d.ts +102 -0
  175. package/dist/infra/cipher/llm/sanitization/base64-utils.js +182 -0
  176. package/dist/infra/cipher/llm/sanitization/index.d.ts +12 -0
  177. package/dist/infra/cipher/llm/sanitization/index.js +13 -0
  178. package/dist/infra/cipher/llm/sanitization/tool-sanitizer.d.ts +74 -0
  179. package/dist/infra/cipher/llm/sanitization/tool-sanitizer.js +398 -0
  180. package/dist/infra/cipher/llm/stream-processor.d.ts +158 -0
  181. package/dist/infra/cipher/llm/stream-processor.js +276 -0
  182. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.d.ts +13 -20
  183. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.js +17 -24
  184. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.d.ts +12 -11
  185. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.js +16 -15
  186. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.d.ts +15 -7
  187. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.js +22 -10
  188. package/dist/infra/cipher/llm/tool-output-processor.d.ts +51 -0
  189. package/dist/infra/cipher/llm/tool-output-processor.js +139 -0
  190. package/dist/infra/cipher/process/command-validator.d.ts +23 -0
  191. package/dist/infra/cipher/process/command-validator.js +75 -0
  192. package/dist/infra/cipher/process/path-utils.d.ts +66 -0
  193. package/dist/infra/cipher/process/path-utils.js +94 -0
  194. package/dist/infra/cipher/process/process-service.d.ts +32 -0
  195. package/dist/infra/cipher/process/process-service.js +98 -17
  196. package/dist/infra/cipher/session/chat-session.d.ts +56 -7
  197. package/dist/infra/cipher/session/chat-session.js +163 -13
  198. package/dist/infra/cipher/session/index.d.ts +1 -0
  199. package/dist/infra/cipher/session/index.js +2 -0
  200. package/dist/infra/cipher/session/message-queue.d.ts +65 -0
  201. package/dist/infra/cipher/session/message-queue.js +90 -0
  202. package/dist/infra/cipher/session/session-manager.d.ts +106 -5
  203. package/dist/infra/cipher/session/session-manager.js +254 -7
  204. package/dist/infra/cipher/session/session-status.d.ts +137 -0
  205. package/dist/infra/cipher/session/session-status.js +184 -0
  206. package/dist/infra/cipher/session/title-generator.d.ts +8 -0
  207. package/dist/infra/cipher/session/title-generator.js +31 -0
  208. package/dist/infra/cipher/storage/message-storage-service.d.ts +65 -2
  209. package/dist/infra/cipher/storage/message-storage-service.js +300 -54
  210. package/dist/infra/cipher/storage/tool-part-factory.d.ts +116 -0
  211. package/dist/infra/cipher/storage/tool-part-factory.js +197 -0
  212. package/dist/infra/cipher/system-prompt/contributor-schemas.d.ts +516 -0
  213. package/dist/infra/cipher/system-prompt/contributor-schemas.js +85 -0
  214. package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.d.ts +59 -0
  215. package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.js +131 -0
  216. package/dist/infra/cipher/system-prompt/contributors/companion-contributor.d.ts +54 -0
  217. package/dist/infra/cipher/system-prompt/contributors/companion-contributor.js +107 -0
  218. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.d.ts +68 -0
  219. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.js +179 -0
  220. package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.d.ts +25 -0
  221. package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.js +29 -0
  222. package/dist/infra/cipher/system-prompt/contributors/environment-contributor.d.ts +25 -0
  223. package/dist/infra/cipher/system-prompt/contributors/environment-contributor.js +54 -0
  224. package/dist/infra/cipher/system-prompt/contributors/file-contributor.d.ts +60 -0
  225. package/dist/infra/cipher/system-prompt/contributors/file-contributor.js +128 -0
  226. package/dist/infra/cipher/system-prompt/contributors/index.d.ts +13 -0
  227. package/dist/infra/cipher/system-prompt/contributors/index.js +8 -0
  228. package/dist/infra/cipher/system-prompt/contributors/memory-contributor.d.ts +40 -0
  229. package/dist/infra/cipher/system-prompt/contributors/memory-contributor.js +56 -0
  230. package/dist/infra/cipher/system-prompt/contributors/static-contributor.d.ts +26 -0
  231. package/dist/infra/cipher/system-prompt/contributors/static-contributor.js +31 -0
  232. package/dist/infra/cipher/system-prompt/environment-context-builder.d.ts +112 -0
  233. package/dist/infra/cipher/system-prompt/environment-context-builder.js +256 -0
  234. package/dist/infra/cipher/system-prompt/prompt-cache.d.ts +102 -0
  235. package/dist/infra/cipher/system-prompt/prompt-cache.js +156 -0
  236. package/dist/infra/cipher/system-prompt/schemas.d.ts +151 -0
  237. package/dist/infra/cipher/system-prompt/schemas.js +94 -0
  238. package/dist/infra/cipher/system-prompt/system-prompt-manager.d.ts +136 -0
  239. package/dist/infra/cipher/system-prompt/system-prompt-manager.js +307 -0
  240. package/dist/infra/cipher/todos/todo-storage-service.d.ts +26 -0
  241. package/dist/infra/cipher/todos/todo-storage-service.js +28 -0
  242. package/dist/infra/cipher/tools/core-tool-scheduler.js +5 -1
  243. package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
  244. package/dist/infra/cipher/tools/implementations/bash-exec-tool.d.ts +1 -0
  245. package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +27 -10
  246. package/dist/infra/cipher/tools/implementations/bash-output-tool.js +1 -5
  247. package/dist/infra/cipher/tools/implementations/batch-tool.d.ts +12 -0
  248. package/dist/infra/cipher/tools/implementations/batch-tool.js +142 -0
  249. package/dist/infra/cipher/tools/implementations/curate-tool.js +195 -68
  250. package/dist/infra/cipher/tools/implementations/list-directory-tool.d.ts +12 -0
  251. package/dist/infra/cipher/tools/implementations/list-directory-tool.js +52 -0
  252. package/dist/infra/cipher/tools/implementations/read-file-tool.d.ts +8 -1
  253. package/dist/infra/cipher/tools/implementations/read-file-tool.js +17 -7
  254. package/dist/infra/cipher/tools/implementations/read-todos-tool.d.ts +11 -0
  255. package/dist/infra/cipher/tools/implementations/read-todos-tool.js +39 -0
  256. package/dist/infra/cipher/tools/implementations/{detect-domains-tool.d.ts → spec-analyze-tool.d.ts} +1 -1
  257. package/dist/infra/cipher/tools/implementations/{detect-domains-tool.js → spec-analyze-tool.js} +9 -7
  258. package/dist/infra/cipher/tools/implementations/task-tool.d.ts +34 -0
  259. package/dist/infra/cipher/tools/implementations/task-tool.js +207 -0
  260. package/dist/infra/cipher/tools/implementations/write-todos-tool.d.ts +4 -1
  261. package/dist/infra/cipher/tools/implementations/write-todos-tool.js +19 -63
  262. package/dist/infra/cipher/tools/index.d.ts +1 -1
  263. package/dist/infra/cipher/tools/index.js +1 -1
  264. package/dist/infra/cipher/tools/plugins/index.d.ts +3 -0
  265. package/dist/infra/cipher/tools/plugins/index.js +2 -0
  266. package/dist/infra/cipher/tools/plugins/logging-plugin.d.ts +28 -0
  267. package/dist/infra/cipher/tools/plugins/logging-plugin.js +66 -0
  268. package/dist/infra/cipher/tools/plugins/plugin-manager.d.ts +81 -0
  269. package/dist/infra/cipher/tools/plugins/plugin-manager.js +122 -0
  270. package/dist/infra/cipher/tools/streaming/index.d.ts +1 -0
  271. package/dist/infra/cipher/tools/streaming/index.js +1 -0
  272. package/dist/infra/cipher/tools/streaming/metadata-handler.d.ts +31 -0
  273. package/dist/infra/cipher/tools/streaming/metadata-handler.js +39 -0
  274. package/dist/infra/cipher/tools/tool-description-loader.d.ts +57 -0
  275. package/dist/infra/cipher/tools/tool-description-loader.js +108 -0
  276. package/dist/infra/cipher/tools/tool-manager.d.ts +38 -4
  277. package/dist/infra/cipher/tools/tool-manager.js +107 -11
  278. package/dist/infra/cipher/tools/tool-provider-getter.d.ts +6 -0
  279. package/dist/infra/cipher/tools/tool-provider-getter.js +1 -0
  280. package/dist/infra/cipher/tools/tool-provider.d.ts +32 -7
  281. package/dist/infra/cipher/tools/tool-provider.js +81 -25
  282. package/dist/infra/cipher/tools/tool-registry.d.ts +23 -0
  283. package/dist/infra/cipher/tools/tool-registry.js +58 -16
  284. package/dist/infra/context-tree/file-context-tree-snapshot-service.js +10 -4
  285. package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +4 -3
  286. package/dist/infra/context-tree/file-context-tree-writer-service.js +6 -4
  287. package/dist/infra/context-tree/path-utils.d.ts +7 -0
  288. package/dist/infra/context-tree/path-utils.js +7 -0
  289. package/dist/infra/core/executors/curate-executor.d.ts +35 -0
  290. package/dist/infra/core/executors/curate-executor.js +123 -0
  291. package/dist/infra/core/executors/index.d.ts +2 -0
  292. package/dist/infra/core/executors/index.js +2 -0
  293. package/dist/infra/core/executors/query-executor.d.ts +23 -0
  294. package/dist/infra/core/executors/query-executor.js +51 -0
  295. package/dist/infra/core/task-processor.d.ts +81 -0
  296. package/dist/infra/core/task-processor.js +115 -0
  297. package/dist/infra/instance/file-instance-discovery.d.ts +31 -0
  298. package/dist/infra/instance/file-instance-discovery.js +84 -0
  299. package/dist/infra/instance/file-instance-manager.d.ts +46 -0
  300. package/dist/infra/instance/file-instance-manager.js +123 -0
  301. package/dist/infra/instance/index.d.ts +3 -0
  302. package/dist/infra/instance/index.js +3 -0
  303. package/dist/infra/instance/process-utils.d.ts +14 -0
  304. package/dist/infra/instance/process-utils.js +39 -0
  305. package/dist/infra/process/agent-worker.d.ts +20 -0
  306. package/dist/infra/process/agent-worker.js +602 -0
  307. package/dist/infra/process/index.d.ts +12 -0
  308. package/dist/infra/process/index.js +11 -0
  309. package/dist/infra/process/ipc-types.d.ts +55 -0
  310. package/dist/infra/process/ipc-types.js +12 -0
  311. package/dist/infra/process/process-manager.d.ts +154 -0
  312. package/dist/infra/process/process-manager.js +471 -0
  313. package/dist/infra/process/task-queue-manager.d.ts +123 -0
  314. package/dist/infra/process/task-queue-manager.js +226 -0
  315. package/dist/infra/process/transport-handlers.d.ts +124 -0
  316. package/dist/infra/process/transport-handlers.js +348 -0
  317. package/dist/infra/process/transport-worker.d.ts +20 -0
  318. package/dist/infra/process/transport-worker.js +168 -0
  319. package/dist/infra/repl/commands/curate-command.js +0 -5
  320. package/dist/infra/repl/commands/query-command.js +0 -3
  321. package/dist/infra/repl/repl-startup.d.ts +4 -0
  322. package/dist/infra/repl/repl-startup.js +10 -1
  323. package/dist/infra/repl/transport-client-helper.d.ts +9 -0
  324. package/dist/infra/repl/transport-client-helper.js +96 -0
  325. package/dist/infra/transport/index.d.ts +4 -0
  326. package/dist/infra/transport/index.js +4 -0
  327. package/dist/infra/transport/port-utils.d.ts +42 -0
  328. package/dist/infra/transport/port-utils.js +84 -0
  329. package/dist/infra/transport/socket-io-transport-client.d.ts +45 -0
  330. package/dist/infra/transport/socket-io-transport-client.js +270 -0
  331. package/dist/infra/transport/socket-io-transport-server.d.ts +35 -0
  332. package/dist/infra/transport/socket-io-transport-server.js +207 -0
  333. package/dist/infra/transport/transport-client-factory.d.ts +76 -0
  334. package/dist/infra/transport/transport-client-factory.js +168 -0
  335. package/dist/infra/transport/transport-factory.d.ts +33 -0
  336. package/dist/infra/transport/transport-factory.js +59 -0
  337. package/dist/infra/usecase/curate-use-case.d.ts +8 -55
  338. package/dist/infra/usecase/curate-use-case.js +73 -259
  339. package/dist/infra/usecase/init-use-case.js +19 -8
  340. package/dist/infra/usecase/login-use-case.js +9 -3
  341. package/dist/infra/usecase/query-use-case.d.ts +18 -45
  342. package/dist/infra/usecase/query-use-case.js +251 -326
  343. package/dist/infra/usecase/status-use-case.js +1 -1
  344. package/dist/resources/prompts/{curate-context-tree-curation.yml → curate.yml} +25 -22
  345. package/dist/resources/prompts/explore.yml +78 -0
  346. package/dist/resources/prompts/plan.yml +114 -0
  347. package/dist/resources/prompts/reflection.yml +1 -1
  348. package/dist/resources/prompts/system-prompt.yml +15 -8
  349. package/dist/resources/prompts/tool-outputs.yml +0 -5
  350. package/dist/resources/tools/bash_exec.txt +98 -0
  351. package/dist/resources/tools/bash_output.txt +40 -0
  352. package/dist/resources/tools/batch.txt +28 -0
  353. package/dist/resources/tools/create_knowledge_topic.txt +23 -0
  354. package/dist/resources/tools/curate.txt +22 -0
  355. package/dist/resources/tools/delete_memory.txt +1 -0
  356. package/dist/resources/tools/detect_domains.txt +11 -0
  357. package/dist/resources/tools/edit_file.txt +1 -0
  358. package/dist/resources/tools/edit_memory.txt +1 -0
  359. package/dist/resources/tools/glob_files.txt +20 -0
  360. package/dist/resources/tools/grep_content.txt +18 -0
  361. package/dist/resources/tools/kill_process.txt +16 -0
  362. package/dist/resources/tools/list_directory.txt +16 -0
  363. package/dist/resources/tools/list_memories.txt +1 -0
  364. package/dist/resources/tools/read_file.txt +31 -0
  365. package/dist/resources/tools/read_memory.txt +1 -0
  366. package/dist/resources/tools/read_todos.txt +17 -0
  367. package/dist/resources/tools/search_history.txt +1 -0
  368. package/dist/resources/tools/task.txt +23 -0
  369. package/dist/resources/tools/write_file.txt +1 -0
  370. package/dist/resources/tools/write_memory.txt +1 -0
  371. package/dist/resources/tools/write_todos.txt +29 -0
  372. package/dist/tui/app.js +9 -13
  373. package/dist/tui/components/command-details.d.ts +14 -0
  374. package/dist/tui/components/command-details.js +35 -0
  375. package/dist/tui/components/execution/execution-changes.d.ts +5 -0
  376. package/dist/tui/components/execution/execution-changes.js +19 -4
  377. package/dist/tui/components/execution/execution-content.d.ts +4 -2
  378. package/dist/tui/components/execution/execution-content.js +26 -13
  379. package/dist/tui/components/execution/execution-input.js +3 -3
  380. package/dist/tui/components/execution/execution-progress.d.ts +2 -2
  381. package/dist/tui/components/execution/execution-progress.js +8 -6
  382. package/dist/tui/components/execution/log-item.d.ts +3 -4
  383. package/dist/tui/components/execution/log-item.js +2 -5
  384. package/dist/tui/components/footer.js +9 -4
  385. package/dist/tui/components/header.d.ts +3 -3
  386. package/dist/tui/components/header.js +5 -3
  387. package/dist/tui/components/index.d.ts +1 -0
  388. package/dist/tui/components/index.js +1 -0
  389. package/dist/tui/components/onboarding/copyable-prompt.d.ts +5 -3
  390. package/dist/tui/components/onboarding/copyable-prompt.js +7 -8
  391. package/dist/tui/components/onboarding/onboarding-flow.js +35 -25
  392. package/dist/tui/components/scrollable-list.js +12 -10
  393. package/dist/tui/components/suggestions.js +39 -41
  394. package/dist/tui/components/tab-bar.d.ts +2 -1
  395. package/dist/tui/components/tab-bar.js +3 -4
  396. package/dist/tui/constants.d.ts +0 -5
  397. package/dist/tui/constants.js +0 -5
  398. package/dist/tui/contexts/auth-context.js +9 -2
  399. package/dist/tui/contexts/{use-commands.js → commands-context.js} +6 -5
  400. package/dist/tui/contexts/index.d.ts +6 -1
  401. package/dist/tui/contexts/index.js +6 -1
  402. package/dist/tui/contexts/onboarding-context.d.ts +1 -1
  403. package/dist/tui/contexts/onboarding-context.js +9 -9
  404. package/dist/tui/contexts/tasks-context.d.ts +84 -0
  405. package/dist/tui/contexts/tasks-context.js +218 -0
  406. package/dist/tui/contexts/transport-context.d.ts +29 -0
  407. package/dist/tui/contexts/transport-context.js +82 -0
  408. package/dist/tui/hooks/index.d.ts +10 -6
  409. package/dist/tui/hooks/index.js +7 -6
  410. package/dist/tui/hooks/use-activity-logs.d.ts +3 -11
  411. package/dist/tui/hooks/use-activity-logs.js +87 -34
  412. package/dist/tui/hooks/use-auth-polling.d.ts +24 -0
  413. package/dist/tui/hooks/use-auth-polling.js +104 -0
  414. package/dist/tui/hooks/use-slash-command-processor.js +0 -1
  415. package/dist/tui/hooks/use-slash-completion.js +1 -1
  416. package/dist/tui/hooks/use-tab-navigation.d.ts +2 -1
  417. package/dist/tui/hooks/use-tab-navigation.js +16 -7
  418. package/dist/tui/hooks/use-terminal-breakpoint.d.ts +21 -0
  419. package/dist/tui/hooks/use-terminal-breakpoint.js +38 -0
  420. package/dist/tui/hooks/use-ui-heights.d.ts +120 -0
  421. package/dist/tui/hooks/use-ui-heights.js +88 -0
  422. package/dist/tui/providers/app-providers.js +2 -6
  423. package/dist/tui/types/commands.d.ts +0 -26
  424. package/dist/tui/types/index.d.ts +1 -1
  425. package/dist/tui/types/ui.d.ts +9 -4
  426. package/dist/tui/utils/line.d.ts +11 -0
  427. package/dist/tui/utils/line.js +16 -0
  428. package/dist/tui/utils/log.d.ts +27 -0
  429. package/dist/tui/utils/log.js +114 -0
  430. package/dist/tui/views/command-view.d.ts +7 -0
  431. package/dist/tui/views/command-view.js +103 -80
  432. package/dist/tui/views/login-view.js +7 -4
  433. package/dist/tui/views/logs-view.d.ts +13 -0
  434. package/dist/tui/views/logs-view.js +27 -52
  435. package/dist/utils/connection-error-handler.d.ts +16 -0
  436. package/dist/utils/connection-error-handler.js +49 -0
  437. package/dist/utils/crash-log.d.ts +14 -0
  438. package/dist/utils/crash-log.js +19 -0
  439. package/dist/utils/file-helpers.d.ts +14 -0
  440. package/dist/utils/file-helpers.js +21 -0
  441. package/dist/utils/global-logs-path.d.ts +11 -0
  442. package/dist/utils/global-logs-path.js +37 -0
  443. package/dist/utils/process-logger.d.ts +53 -0
  444. package/dist/utils/process-logger.js +253 -0
  445. package/dist/utils/sandbox-detector.d.ts +31 -0
  446. package/dist/utils/sandbox-detector.js +122 -0
  447. package/oclif.manifest.json +10 -198
  448. package/package.json +5 -1
  449. package/dist/commands/cipher-agent/run.d.ts +0 -142
  450. package/dist/commands/cipher-agent/run.js +0 -555
  451. package/dist/commands/cipher-agent/set-prompt.d.ts +0 -16
  452. package/dist/commands/cipher-agent/set-prompt.js +0 -58
  453. package/dist/commands/cipher-agent/show-prompt.d.ts +0 -13
  454. package/dist/commands/cipher-agent/show-prompt.js +0 -53
  455. package/dist/commands/foo.d.ts +0 -14
  456. package/dist/commands/foo.js +0 -66
  457. package/dist/infra/cipher/agent-service-factory.d.ts +0 -93
  458. package/dist/infra/cipher/cipher-agent-state-manager.d.ts +0 -63
  459. package/dist/infra/cipher/cipher-agent-state-manager.js +0 -108
  460. package/dist/infra/cipher/cipher-agent.d.ts +0 -182
  461. package/dist/infra/cipher/cipher-agent.js +0 -317
  462. package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +0 -106
  463. package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +0 -297
  464. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.d.ts +0 -7
  465. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +0 -424
  466. package/dist/resources/prompts/modes/autonomous.yml +0 -9
  467. package/dist/resources/prompts/query-context-tree-retrieval.yml +0 -48
  468. package/dist/tui/contexts/consumer.d.ts +0 -31
  469. package/dist/tui/contexts/consumer.js +0 -56
  470. package/dist/tui/hooks/use-consumer.d.ts +0 -12
  471. package/dist/tui/hooks/use-consumer.js +0 -50
  472. package/dist/tui/hooks/use-queue-polling.d.ts +0 -31
  473. package/dist/tui/hooks/use-queue-polling.js +0 -90
  474. /package/dist/tui/contexts/{use-commands.d.ts → commands-context.d.ts} +0 -0
  475. /package/dist/tui/contexts/{use-mode.d.ts → mode-context.d.ts} +0 -0
  476. /package/dist/tui/contexts/{use-mode.js → mode-context.js} +0 -0
  477. /package/dist/tui/contexts/{use-theme.d.ts → theme-context.d.ts} +0 -0
  478. /package/dist/tui/contexts/{use-theme.js → theme-context.js} +0 -0
@@ -1,5 +1,6 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { COMPACTED_TOOL_OUTPUT_PLACEHOLDER } from '../../../core/domain/cipher/storage/message-storage-types.js';
3
+ import { ToolPartFactory } from './tool-part-factory.js';
3
4
  /**
4
5
  * Service for granular message and part storage.
5
6
  *
@@ -19,6 +20,66 @@ export class MessageStorageService {
19
20
  constructor(keyStorage) {
20
21
  this.keyStorage = keyStorage;
21
22
  }
23
+ /**
24
+ * Add attachments to a completed tool part.
25
+ *
26
+ * @param messageId - ID of the message containing the part
27
+ * @param partId - ID of the tool part
28
+ * @param attachments - Attachments to add
29
+ */
30
+ async addToolPartAttachments(messageId, partId, attachments) {
31
+ await this.keyStorage.update(this.partKey(messageId, partId), (prev) => {
32
+ if (!prev)
33
+ throw new Error(`Part ${partId} not found`);
34
+ if (prev.type !== 'tool' || !prev.toolState) {
35
+ throw new Error(`Part ${partId} is not a tool part`);
36
+ }
37
+ const existingAttachments = prev.toolState.attachments ?? [];
38
+ const newAttachments = attachments.map((att) => ({
39
+ data: att.data,
40
+ filename: att.filename,
41
+ mime: att.mime,
42
+ type: att.type,
43
+ }));
44
+ return {
45
+ ...prev,
46
+ toolState: {
47
+ ...prev.toolState,
48
+ attachments: [...existingAttachments, ...newAttachments],
49
+ },
50
+ };
51
+ });
52
+ }
53
+ /**
54
+ * Create a tool part in pending state and add it to a message.
55
+ *
56
+ * @param options - Options for creating the tool part
57
+ * @returns The created StoredPart
58
+ */
59
+ async createToolPart(options) {
60
+ const { callId, input, messageId, sessionId, toolName } = options;
61
+ // Verify message exists
62
+ const message = await this.keyStorage.get(this.messageKey(sessionId, messageId));
63
+ if (!message) {
64
+ throw new Error(`Message ${messageId} not found in session ${sessionId}`);
65
+ }
66
+ // Create the tool part in pending state
67
+ const toolPart = ToolPartFactory.createPending(messageId, callId, toolName, input);
68
+ // Save the part
69
+ await this.keyStorage.set(this.partKey(messageId, toolPart.id), toolPart);
70
+ // Update message's partIds
71
+ const now = Date.now();
72
+ await this.keyStorage.update(this.messageKey(sessionId, messageId), (prev) => {
73
+ if (!prev)
74
+ throw new Error(`Message ${messageId} not found`);
75
+ return {
76
+ ...prev,
77
+ partIds: [...prev.partIds, toolPart.id],
78
+ updatedAt: now,
79
+ };
80
+ });
81
+ return toolPart;
82
+ }
22
83
  /**
23
84
  * Delete a session and all its messages and parts.
24
85
  */
@@ -51,6 +112,24 @@ export class MessageStorageService {
51
112
  async getSession(sessionId) {
52
113
  return this.keyStorage.get(this.sessionKey(sessionId));
53
114
  }
115
+ /**
116
+ * Get a tool part by call ID from a message.
117
+ *
118
+ * @param messageId - ID of the message
119
+ * @param callId - Call ID of the tool part
120
+ * @returns The tool part if found
121
+ */
122
+ async getToolPartByCallId(messageId, callId) {
123
+ const partKeys = await this.keyStorage.list(this.partPrefix(messageId));
124
+ for (const partKey of partKeys) {
125
+ // eslint-disable-next-line no-await-in-loop
126
+ const part = await this.keyStorage.get(partKey);
127
+ if (part?.type === 'tool' && part.toolState?.callId === callId) {
128
+ return part;
129
+ }
130
+ }
131
+ return undefined;
132
+ }
54
133
  /**
55
134
  * Check if a session exists in granular format.
56
135
  */
@@ -145,15 +224,20 @@ export class MessageStorageService {
145
224
  /**
146
225
  * Prune old tool outputs by marking them as compacted.
147
226
  * Keeps the most recent tool outputs up to the specified token limit.
227
+ *
228
+ * Turn-based protection: Protects tool outputs in the most recent N user turns.
229
+ * Minimum threshold: Only executes if the minimum token threshold can be saved.
148
230
  */
149
231
  async pruneToolOutputs(options) {
150
- const { keepTokens = 40_000, sessionId } = options;
232
+ const { keepTokens = 40_000, minimumTokens = 20_000, protectedTurns = 2, sessionId } = options;
151
233
  const session = await this.getSession(sessionId);
152
234
  if (!session || !session.newestMessageId) {
153
235
  return { compactedCount: 0, tokensSaved: 0 };
154
236
  }
155
237
  // Collect all tool output parts, newest first
238
+ // Track user turns for turn-based protection
156
239
  const toolOutputParts = [];
240
+ let userTurnCount = 0;
157
241
  // Traverse messages from newest to oldest
158
242
  let currentMessageId = session.newestMessageId;
159
243
  while (currentMessageId) {
@@ -161,6 +245,15 @@ export class MessageStorageService {
161
245
  const storedMsg = await this.keyStorage.get(this.messageKey(sessionId, currentMessageId));
162
246
  if (!storedMsg)
163
247
  break;
248
+ // Stop at existing compaction boundary
249
+ if (storedMsg.compactionBoundary)
250
+ break;
251
+ // Track user turns for turn-based protection
252
+ if (storedMsg.role === 'user') {
253
+ userTurnCount++;
254
+ }
255
+ // Determine if this message's tool outputs are protected
256
+ const isProtected = userTurnCount <= protectedTurns;
164
257
  // Collect tool output parts from this message
165
258
  for (const partId of storedMsg.partIds) {
166
259
  // eslint-disable-next-line no-await-in-loop
@@ -169,33 +262,46 @@ export class MessageStorageService {
169
262
  toolOutputParts.push({
170
263
  key: this.partKey(storedMsg.id, partId),
171
264
  part,
265
+ protected: isProtected,
172
266
  });
173
267
  }
174
268
  }
175
269
  currentMessageId = storedMsg.prevMessageId;
176
270
  }
177
- // Estimate tokens (rough: 1 token ≈ 4 chars)
271
+ // First pass: Calculate potential tokens saved (only from unprotected parts)
178
272
  let keptTokens = 0;
179
- let compactedCount = 0;
180
- let tokensSaved = 0;
181
- const now = Date.now();
182
- for (const { key, part } of toolOutputParts) {
273
+ let potentialTokensSaved = 0;
274
+ const partsToCompact = [];
275
+ for (const { key, part, protected: isProtected } of toolOutputParts) {
183
276
  const estimatedTokens = Math.ceil(part.content.length / 4);
184
- if (keptTokens < keepTokens) {
277
+ if (isProtected || keptTokens < keepTokens) {
278
+ // Keep this part (either protected or within token limit)
185
279
  keptTokens += estimatedTokens;
186
280
  }
187
281
  else {
188
- // Mark this part as compacted
189
- // eslint-disable-next-line no-await-in-loop
190
- await this.keyStorage.set(key, {
191
- ...part,
192
- compactedAt: now,
193
- content: '', // Clear the content to save space
194
- });
195
- compactedCount++;
196
- tokensSaved += estimatedTokens;
282
+ // This part is a candidate for compaction
283
+ partsToCompact.push({ key, part, tokens: estimatedTokens });
284
+ potentialTokensSaved += estimatedTokens;
197
285
  }
198
286
  }
287
+ // Check minimum threshold: only proceed if we can save enough tokens
288
+ if (potentialTokensSaved < minimumTokens) {
289
+ return { compactedCount: 0, tokensSaved: 0 };
290
+ }
291
+ // Second pass: Actually compact the parts
292
+ let compactedCount = 0;
293
+ let tokensSaved = 0;
294
+ const now = Date.now();
295
+ for (const { key, part, tokens } of partsToCompact) {
296
+ // eslint-disable-next-line no-await-in-loop
297
+ await this.keyStorage.set(key, {
298
+ ...part,
299
+ compactedAt: now,
300
+ content: '', // Clear the content to save space
301
+ });
302
+ compactedCount++;
303
+ tokensSaved += tokens;
304
+ }
199
305
  return { compactedCount, tokensSaved };
200
306
  }
201
307
  /**
@@ -324,46 +430,16 @@ export class MessageStorageService {
324
430
  if (parts.length > 0) {
325
431
  const contentParts = [];
326
432
  for (const part of parts) {
327
- if (part.compactedAt) {
328
- // Show placeholder for compacted parts
329
- contentParts.push({
330
- text: part.type === 'tool_output' ? COMPACTED_TOOL_OUTPUT_PLACEHOLDER : '[Content cleared]',
331
- type: 'text',
332
- });
433
+ const converted = this.convertStoredPartToMessagePart(part);
434
+ if (converted.messagePart) {
435
+ contentParts.push(converted.messagePart);
333
436
  }
334
- else {
335
- switch (part.type) {
336
- case 'file': {
337
- contentParts.push({
338
- data: part.content,
339
- filename: part.filename,
340
- mimeType: part.mimeType || 'application/octet-stream',
341
- type: 'file',
342
- });
343
- break;
344
- }
345
- case 'image': {
346
- contentParts.push({
347
- image: part.content,
348
- mimeType: part.mimeType,
349
- type: 'image',
350
- });
351
- break;
352
- }
353
- case 'text': {
354
- contentParts.push({ text: part.content, type: 'text' });
355
- break;
356
- }
357
- case 'tool_output': {
358
- // Tool output becomes text content for tool messages
359
- content = part.content;
360
- break;
361
- }
362
- }
437
+ if (converted.toolOutputContent !== undefined) {
438
+ content = converted.toolOutputContent;
363
439
  }
364
440
  }
365
- // Only use content parts array if we have non-tool parts
366
- if (contentParts.length > 0 && message.role === 'user') {
441
+ // Only use content parts array if we have non-tool parts or tool parts
442
+ if (contentParts.length > 0 && (message.role === 'user' || message.role === 'assistant')) {
367
443
  content = contentParts;
368
444
  }
369
445
  }
@@ -385,6 +461,95 @@ export class MessageStorageService {
385
461
  toInternalMessages(messages) {
386
462
  return messages.map((msg) => this.toInternalMessage(msg));
387
463
  }
464
+ /**
465
+ * Update a tool part's state.
466
+ * Used for transitioning through pending → running → completed/error.
467
+ *
468
+ * @param messageId - ID of the message containing the part
469
+ * @param partId - ID of the tool part to update
470
+ * @param update - Partial tool state update
471
+ */
472
+ async updateToolPartState(messageId, partId, update) {
473
+ await this.keyStorage.update(this.partKey(messageId, partId), (prev) => {
474
+ if (!prev)
475
+ throw new Error(`Part ${partId} not found`);
476
+ if (prev.type !== 'tool' || !prev.toolState) {
477
+ throw new Error(`Part ${partId} is not a tool part`);
478
+ }
479
+ return {
480
+ ...prev,
481
+ toolState: {
482
+ ...prev.toolState,
483
+ ...update,
484
+ },
485
+ };
486
+ });
487
+ }
488
+ /**
489
+ * Convert a StoredPart to a MessagePart for reconstruction.
490
+ * Returns the converted part and optionally tool output content.
491
+ */
492
+ convertStoredPartToMessagePart(part) {
493
+ // Handle compacted parts
494
+ if (part.compactedAt) {
495
+ return {
496
+ messagePart: {
497
+ text: part.type === 'tool_output' ? COMPACTED_TOOL_OUTPUT_PLACEHOLDER : '[Content cleared]',
498
+ type: 'text',
499
+ },
500
+ };
501
+ }
502
+ // Convert based on part type
503
+ switch (part.type) {
504
+ case 'file': {
505
+ return {
506
+ messagePart: {
507
+ data: part.content,
508
+ filename: part.filename,
509
+ mimeType: part.mimeType || 'application/octet-stream',
510
+ type: 'file',
511
+ },
512
+ };
513
+ }
514
+ case 'image': {
515
+ return {
516
+ messagePart: {
517
+ image: part.content,
518
+ mimeType: part.mimeType,
519
+ type: 'image',
520
+ },
521
+ };
522
+ }
523
+ case 'reasoning': {
524
+ return {
525
+ messagePart: {
526
+ summary: part.reasoningSummary,
527
+ text: part.content,
528
+ type: 'reasoning',
529
+ },
530
+ };
531
+ }
532
+ case 'text': {
533
+ return {
534
+ messagePart: { text: part.content, type: 'text' },
535
+ };
536
+ }
537
+ case 'tool': {
538
+ if (!part.toolState)
539
+ return {};
540
+ return {
541
+ messagePart: this.storedPartToToolPart(part),
542
+ };
543
+ }
544
+ case 'tool_output': {
545
+ // Tool output becomes text content for tool messages
546
+ return { toolOutputContent: part.content };
547
+ }
548
+ default: {
549
+ return {};
550
+ }
551
+ }
552
+ }
388
553
  /**
389
554
  * Extract parts from an InternalMessage.
390
555
  */
@@ -443,6 +608,17 @@ export class MessageStorageService {
443
608
  });
444
609
  break;
445
610
  }
611
+ case 'reasoning': {
612
+ parts.push({
613
+ content: part.text,
614
+ createdAt: now,
615
+ id: partId,
616
+ messageId,
617
+ reasoningSummary: part.summary,
618
+ type: 'reasoning',
619
+ });
620
+ break;
621
+ }
446
622
  case 'text': {
447
623
  parts.push({
448
624
  content: part.text,
@@ -453,9 +629,14 @@ export class MessageStorageService {
453
629
  });
454
630
  break;
455
631
  }
632
+ case 'tool': {
633
+ // Store tool part with full state
634
+ parts.push(this.toolPartToStoredPart(part, partId, messageId, now));
635
+ break;
636
+ }
456
637
  }
457
638
  }
458
- // For user messages, content is reconstructed from parts
639
+ // For user/assistant messages, content is reconstructed from parts
459
640
  // but we can store a text preview
460
641
  const textParts = message.content.filter((p) => p.type === 'text');
461
642
  if (textParts.length > 0) {
@@ -520,6 +701,71 @@ export class MessageStorageService {
520
701
  sessionKey(sessionId) {
521
702
  return ['session', sessionId];
522
703
  }
704
+ /**
705
+ * Convert a stored part with tool state to a ToolPart.
706
+ */
707
+ storedPartToToolPart(part) {
708
+ if (!part.toolState || !part.toolName) {
709
+ throw new Error('Cannot convert non-tool part to ToolPart');
710
+ }
711
+ return {
712
+ callId: part.toolState.callId,
713
+ state: ToolPartFactory.toToolPartState(part.toolState),
714
+ toolName: part.toolName,
715
+ type: 'tool',
716
+ };
717
+ }
718
+ /**
719
+ * Convert a ToolPart to a StoredPart.
720
+ */
721
+ toolPartToStoredPart(part, partId, messageId, now) {
722
+ const { callId, state, toolName } = part;
723
+ // Build stored tool state from ToolPart state
724
+ const toolState = {
725
+ callId,
726
+ input: state.input,
727
+ status: state.status,
728
+ };
729
+ // Add state-specific fields
730
+ switch (state.status) {
731
+ case 'completed': {
732
+ toolState.attachments = state.attachments?.map((att) => ({
733
+ data: att.data,
734
+ filename: att.filename,
735
+ mime: att.mime,
736
+ type: att.type,
737
+ }));
738
+ toolState.completedAt = state.time.end;
739
+ toolState.output = state.output;
740
+ toolState.startedAt = state.time.start;
741
+ toolState.title = state.title;
742
+ break;
743
+ }
744
+ case 'error': {
745
+ toolState.completedAt = state.time.end;
746
+ toolState.error = state.error;
747
+ toolState.startedAt = state.time.start;
748
+ break;
749
+ }
750
+ case 'pending': {
751
+ // No additional fields for pending state
752
+ break;
753
+ }
754
+ case 'running': {
755
+ toolState.startedAt = state.startedAt;
756
+ break;
757
+ }
758
+ }
759
+ return {
760
+ content: '',
761
+ createdAt: now,
762
+ id: partId,
763
+ messageId,
764
+ toolName,
765
+ toolState,
766
+ type: 'tool',
767
+ };
768
+ }
523
769
  }
524
770
  /**
525
771
  * Factory function to create MessageStorageService.
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Factory for creating and managing tool parts with state machine.
3
+ *
4
+ * This module provides utilities for:
5
+ * - Creating tool parts in pending state
6
+ * - Transitioning tool parts through their lifecycle (pending → running → completed/error)
7
+ * - Marking tool parts as compacted for pruning
8
+ *
9
+ * Based on OpenCode's tool state machine pattern.
10
+ */
11
+ import type { StoredPart, StoredToolState } from '../../../core/domain/cipher/storage/message-storage-types.js';
12
+ import type { AttachmentPart } from '../../../core/interfaces/cipher/message-types.js';
13
+ /**
14
+ * Options for creating a completed tool state.
15
+ */
16
+ export interface ToolCompletionOptions {
17
+ /** Attachments produced by the tool (images, files) */
18
+ attachments?: AttachmentPart[];
19
+ /** Additional metadata about the execution */
20
+ metadata?: Record<string, unknown>;
21
+ /** Human-readable title for display */
22
+ title?: string;
23
+ }
24
+ /**
25
+ * Factory for creating and managing tool parts with state machine.
26
+ *
27
+ * Tool parts track the full lifecycle of a tool call:
28
+ * 1. Pending: Tool call received from LLM, not yet started
29
+ * 2. Running: Execution has started
30
+ * 3. Completed: Execution finished successfully with output
31
+ * 4. Error: Execution failed with error message
32
+ *
33
+ * This enables:
34
+ * - Real-time UI feedback during tool execution
35
+ * - Better conversation history representation
36
+ * - Efficient compaction (mark individual outputs as compacted)
37
+ */
38
+ export declare const ToolPartFactory: {
39
+ /**
40
+ * Create a new tool part in pending state.
41
+ *
42
+ * @param messageId - ID of the message this part belongs to
43
+ * @param callId - Unique identifier for this tool call
44
+ * @param toolName - Name of the tool being called
45
+ * @param input - Parsed input arguments
46
+ * @returns StoredPart with pending tool state
47
+ */
48
+ createPending(messageId: string, callId: string, toolName: string, input: Record<string, unknown>): StoredPart;
49
+ /**
50
+ * Mark a tool part as compacted.
51
+ * Clears the output while preserving the state structure.
52
+ *
53
+ * @param part - The tool part to mark as compacted
54
+ * @returns Updated StoredPart with compactedAt timestamp
55
+ */
56
+ markCompacted(part: StoredPart): StoredPart;
57
+ /**
58
+ * Convert a StoredPart's tool state to the format used in message-types.ts.
59
+ * Useful for reconstructing InternalMessage from stored parts.
60
+ *
61
+ * @param toolState - The stored tool state
62
+ * @returns Tool state in the format expected by ToolPart
63
+ */
64
+ toToolPartState(toolState: StoredToolState): {
65
+ attachments?: AttachmentPart[];
66
+ compactedAt?: number;
67
+ input: Record<string, unknown>;
68
+ metadata?: Record<string, unknown>;
69
+ output: string;
70
+ status: "completed";
71
+ time: {
72
+ end: number;
73
+ start: number;
74
+ };
75
+ title?: string;
76
+ } | {
77
+ error: string;
78
+ input: Record<string, unknown>;
79
+ status: "error";
80
+ time: {
81
+ end: number;
82
+ start: number;
83
+ };
84
+ } | {
85
+ input: Record<string, unknown>;
86
+ startedAt: number;
87
+ status: "running";
88
+ } | {
89
+ input: Record<string, unknown>;
90
+ status: "pending";
91
+ };
92
+ /**
93
+ * Transition a tool part to completed state.
94
+ *
95
+ * @param part - The tool part to update
96
+ * @param output - Tool output content
97
+ * @param options - Additional options (title, metadata, attachments)
98
+ * @returns Updated StoredPart with completed state
99
+ */
100
+ transitionToCompleted(part: StoredPart, output: string, options?: ToolCompletionOptions): StoredPart;
101
+ /**
102
+ * Transition a tool part to error state.
103
+ *
104
+ * @param part - The tool part to update
105
+ * @param error - Error message
106
+ * @returns Updated StoredPart with error state
107
+ */
108
+ transitionToError(part: StoredPart, error: string): StoredPart;
109
+ /**
110
+ * Transition a tool part to running state.
111
+ *
112
+ * @param part - The tool part to update
113
+ * @returns Updated StoredPart with running state
114
+ */
115
+ transitionToRunning(part: StoredPart): StoredPart;
116
+ };