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
@@ -43,23 +43,24 @@ const BashExecInputSchema = z
43
43
  *
44
44
  * Executes shell commands with security validation and approval for dangerous commands.
45
45
  * Supports both foreground (wait for completion) and background (return immediately) execution.
46
+ * When a metadata callback is provided, streams output updates in real-time.
46
47
  *
47
48
  * @param processService - Process service for command execution
48
49
  * @returns bash_exec tool instance
49
50
  */
50
51
  export function createBashExecTool(processService) {
51
52
  return {
52
- description: `Execute a shell command and return its output.
53
-
54
- If there is a memory about suggested commands, read that first.
55
-
56
- **IMPORTANT:** Do not use this tool to start any process that is not intended to terminate quickly, or requires user interaction.
57
-
58
- Examples of inappropriate use:
59
- - Long-running processes (e.g. servers) that are not intended to terminate quickly
60
- - Processes that require user interaction`,
61
- async execute(input, _context) {
53
+ description: `Execute a shell command and return its output.`,
54
+ async execute(input, context) {
62
55
  const { command, cwd, description, runInBackground, timeout } = input;
56
+ // Stream initial status via metadata callback if available
57
+ if (context?.metadata) {
58
+ context.metadata({
59
+ description: description ?? `Executing: ${command.slice(0, 50)}${command.length > 50 ? '...' : ''}`,
60
+ output: '',
61
+ progress: 0,
62
+ });
63
+ }
63
64
  // Execute command via process service
64
65
  const result = await processService.executeCommand(command, {
65
66
  cwd,
@@ -69,6 +70,14 @@ Examples of inappropriate use:
69
70
  });
70
71
  // Return based on execution mode
71
72
  if ('stdout' in result) {
73
+ // Stream final output via metadata callback if available
74
+ if (context?.metadata) {
75
+ context.metadata({
76
+ description: description ?? 'Command completed',
77
+ output: result.stdout + (result.stderr ? `\n[stderr]\n${result.stderr}` : ''),
78
+ progress: 100,
79
+ });
80
+ }
72
81
  // Foreground execution result
73
82
  return {
74
83
  duration: result.duration,
@@ -77,6 +86,14 @@ Examples of inappropriate use:
77
86
  stdout: result.stdout,
78
87
  };
79
88
  }
89
+ // Stream background process info via metadata callback if available
90
+ if (context?.metadata) {
91
+ context.metadata({
92
+ description: `Background process started: ${result.processId}`,
93
+ output: `Process started with PID ${result.pid}`,
94
+ progress: 100,
95
+ });
96
+ }
80
97
  // Background execution handle
81
98
  return {
82
99
  command: result.command,
@@ -22,11 +22,7 @@ const BashOutputInputSchema = z
22
22
  */
23
23
  export function createBashOutputTool(processService) {
24
24
  return {
25
- description: `Retrieve output from a background process started by bash_exec.
26
-
27
- Returns new output since last read (incremental). Reading output clears the buffer, so output is returned only once. Shows process status (running/completed/failed) and includes exit code and duration when completed.
28
-
29
- **IMPORTANT:** Output is truncated if it exceeds buffer limit (default 1MB). Process is automatically cleaned up 1 hour after completion.`,
25
+ description: `Retrieve output from a background process started by bash_exec.`,
30
26
  async execute(input, _context) {
31
27
  const { processId } = input;
32
28
  // Get output from process service
@@ -0,0 +1,12 @@
1
+ import type { Tool } from '../../../../core/domain/cipher/tools/types.js';
2
+ import type { ToolProviderGetter } from '../tool-provider-getter.js';
3
+ /**
4
+ * Create batch tool.
5
+ *
6
+ * Executes multiple independent tool calls concurrently to reduce latency.
7
+ * Best used for gathering context (reads, searches, listings).
8
+ *
9
+ * @param getToolProvider - Lazy getter for tool provider (avoids circular dependency)
10
+ * @returns batch tool instance
11
+ */
12
+ export declare function createBatchTool(getToolProvider: ToolProviderGetter): Tool;
@@ -0,0 +1,142 @@
1
+ import { z } from 'zod';
2
+ import { ToolName } from '../../../../core/domain/cipher/tools/constants.js';
3
+ /**
4
+ * Tools that are not allowed in batch execution.
5
+ * - batch: No nesting of batch calls
6
+ * - edit_file: Sequential edits for proper conflict handling
7
+ * - write_todos: Lightweight, call directly
8
+ */
9
+ const DISALLOWED_TOOLS = new Set(['batch', 'edit_file', 'write_todos']);
10
+ /**
11
+ * Maximum number of tool calls allowed in a single batch.
12
+ */
13
+ const MAX_BATCH_SIZE = 10;
14
+ /**
15
+ * Input schema for batch tool.
16
+ */
17
+ const BatchInputSchema = z
18
+ .object({
19
+ /**
20
+ * Array of tool calls to execute in parallel.
21
+ */
22
+ toolCalls: z
23
+ .array(z.object({
24
+ /**
25
+ * Parameters for the tool.
26
+ */
27
+ parameters: z.record(z.unknown()).describe('Parameters for the tool'),
28
+ /**
29
+ * The name of the tool to execute.
30
+ */
31
+ tool: z.string().describe('The name of the tool to execute'),
32
+ }))
33
+ .min(1, 'Provide at least one tool call')
34
+ .describe('Array of tool calls to execute in parallel'),
35
+ })
36
+ .strict();
37
+ /**
38
+ * Create batch tool.
39
+ *
40
+ * Executes multiple independent tool calls concurrently to reduce latency.
41
+ * Best used for gathering context (reads, searches, listings).
42
+ *
43
+ * @param getToolProvider - Lazy getter for tool provider (avoids circular dependency)
44
+ * @returns batch tool instance
45
+ */
46
+ export function createBatchTool(getToolProvider) {
47
+ return {
48
+ description: 'Execute multiple independent tool calls concurrently.',
49
+ async execute(input, context) {
50
+ const { toolCalls } = input;
51
+ const toolProvider = getToolProvider();
52
+ // Limit to MAX_BATCH_SIZE
53
+ const activeCalls = toolCalls.slice(0, MAX_BATCH_SIZE);
54
+ const discardedCalls = toolCalls.slice(MAX_BATCH_SIZE);
55
+ /**
56
+ * Execute a single tool call and return the result.
57
+ */
58
+ const executeCall = async (call) => {
59
+ const startTime = Date.now();
60
+ // Check if tool is disallowed in batch
61
+ if (DISALLOWED_TOOLS.has(call.tool)) {
62
+ return {
63
+ durationMs: Date.now() - startTime,
64
+ error: `Tool '${call.tool}' is not allowed in batch. Disallowed tools: ${[...DISALLOWED_TOOLS].join(', ')}`,
65
+ success: false,
66
+ tool: call.tool,
67
+ };
68
+ }
69
+ // Check if tool exists
70
+ if (!toolProvider.hasTool(call.tool)) {
71
+ const availableTools = toolProvider.getToolNames().filter((name) => !DISALLOWED_TOOLS.has(name));
72
+ return {
73
+ durationMs: Date.now() - startTime,
74
+ error: `Tool '${call.tool}' not found. Available tools: ${availableTools.join(', ')}`,
75
+ success: false,
76
+ tool: call.tool,
77
+ };
78
+ }
79
+ try {
80
+ const result = await toolProvider.executeTool(call.tool, call.parameters, context?.sessionId, context);
81
+ return {
82
+ durationMs: Date.now() - startTime,
83
+ result,
84
+ success: true,
85
+ tool: call.tool,
86
+ };
87
+ }
88
+ catch (error) {
89
+ return {
90
+ durationMs: Date.now() - startTime,
91
+ error: error instanceof Error ? error.message : String(error),
92
+ success: false,
93
+ tool: call.tool,
94
+ };
95
+ }
96
+ };
97
+ // Execute all calls in parallel
98
+ const results = await Promise.all(activeCalls.map((call) => executeCall(call)));
99
+ // Add discarded calls as errors
100
+ for (const call of discardedCalls) {
101
+ results.push({
102
+ durationMs: 0,
103
+ error: `Maximum of ${MAX_BATCH_SIZE} tools allowed in batch`,
104
+ success: false,
105
+ tool: call.tool,
106
+ });
107
+ }
108
+ const successful = results.filter((r) => r.success).length;
109
+ const failed = results.length - successful;
110
+ // Stream progress update
111
+ if (context?.metadata) {
112
+ context.metadata({
113
+ description: 'Batch execution complete',
114
+ output: `${successful}/${results.length} tools executed successfully`,
115
+ progress: 100,
116
+ });
117
+ }
118
+ // Build output message
119
+ const outputMessage = failed > 0
120
+ ? `Executed ${successful}/${results.length} tools successfully. ${failed} failed.`
121
+ : `All ${successful} tools executed successfully.\n\nKeep using the batch tool for optimal performance!`;
122
+ return {
123
+ metadata: {
124
+ details: results.map((r) => ({ success: r.success, tool: r.tool })),
125
+ failed,
126
+ successful,
127
+ tools: toolCalls.map((c) => c.tool),
128
+ totalCalls: results.length,
129
+ },
130
+ results: results.map((r) => ({
131
+ durationMs: r.durationMs,
132
+ success: r.success,
133
+ tool: r.tool,
134
+ ...(r.success ? { result: r.result } : { error: r.error }),
135
+ })),
136
+ summary: outputMessage,
137
+ };
138
+ },
139
+ id: ToolName.BATCH,
140
+ inputSchema: BatchInputSchema,
141
+ };
142
+ }
@@ -1,9 +1,20 @@
1
+ import * as fs from 'node:fs/promises';
1
2
  import { join } from 'node:path';
2
3
  import { z } from 'zod';
4
+ import { DEFAULT_CONTEXT_TREE_DOMAINS } from '../../../../config/context-tree-domains.js';
3
5
  import { ToolName } from '../../../../core/domain/cipher/tools/constants.js';
4
6
  import { DirectoryManager } from '../../../../core/domain/knowledge/directory-manager.js';
5
7
  import { MarkdownWriter } from '../../../../core/domain/knowledge/markdown-writer.js';
6
- import { sanitizeFolderName } from '../../../../utils/file-helpers.js';
8
+ import { toSnakeCase } from '../../../../utils/file-helpers.js';
9
+ /**
10
+ * Predefined domain names from configuration.
11
+ */
12
+ const PREDEFINED_DOMAIN_NAMES = DEFAULT_CONTEXT_TREE_DOMAINS.map((domain) => domain.name);
13
+ /**
14
+ * Maximum number of custom domains allowed beyond predefined domains.
15
+ * This prevents excessive domain proliferation which degrades query quality.
16
+ */
17
+ const MAX_CUSTOM_DOMAINS = 3;
7
18
  /**
8
19
  * Operation types for curating knowledge topics.
9
20
  * Inspired by ACE Curator patterns.
@@ -25,8 +36,10 @@ const ContentSchema = z.object({
25
36
  const OperationSchema = z.object({
26
37
  content: ContentSchema.optional().describe('Content for ADD/UPDATE operations'),
27
38
  mergeTarget: z.string().optional().describe('Target path for MERGE operation'),
39
+ mergeTargetTitle: z.string().optional().describe('Title of the target file for MERGE operation'),
28
40
  path: z.string().describe('Path: domain/topic or domain/topic/subtopic'),
29
41
  reason: z.string().describe('Reasoning for this operation'),
42
+ title: z.string().optional().describe('Title for the context file (saved as {title}.md in snake_case). Required for ADD/UPDATE/MERGE, optional for DELETE'),
30
43
  type: OperationType.describe('Operation type: ADD, UPDATE, MERGE, or DELETE'),
31
44
  });
32
45
  /**
@@ -50,26 +63,79 @@ function parsePath(path) {
50
63
  topic: parts[1],
51
64
  };
52
65
  }
66
+ /**
67
+ * Get existing domain names from the context tree.
68
+ * Returns domain folder names that exist in the context tree.
69
+ */
70
+ async function getExistingDomains(basePath) {
71
+ try {
72
+ const entries = await fs.readdir(basePath, { withFileTypes: true });
73
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
74
+ }
75
+ catch {
76
+ // Directory doesn't exist yet
77
+ return [];
78
+ }
79
+ }
80
+ /**
81
+ * Check if a domain is valid (either predefined or existing in context tree).
82
+ * Also enforces the maximum custom domains limit.
83
+ */
84
+ async function validateDomain(basePath, domainName) {
85
+ const normalizedDomain = toSnakeCase(domainName);
86
+ const existingDomains = await getExistingDomains(basePath);
87
+ // Check if it's a predefined domain - always allowed
88
+ if (PREDEFINED_DOMAIN_NAMES.includes(normalizedDomain)) {
89
+ return { allowed: true, existingDomains };
90
+ }
91
+ // Check if it already exists in context tree - always allowed
92
+ if (existingDomains.includes(normalizedDomain)) {
93
+ return { allowed: true, existingDomains };
94
+ }
95
+ // Count how many custom domains already exist
96
+ const customDomains = existingDomains.filter((domain) => !PREDEFINED_DOMAIN_NAMES.includes(domain));
97
+ // Check if we've exceeded the custom domain limit
98
+ if (customDomains.length >= MAX_CUSTOM_DOMAINS) {
99
+ return {
100
+ allowed: false,
101
+ existingDomains,
102
+ reason: `Cannot create new domain "${normalizedDomain}". Maximum of ${MAX_CUSTOM_DOMAINS} custom domains allowed. ` +
103
+ `Existing custom domains: ${customDomains.join(', ')}. ` +
104
+ `Please use one of the predefined domains (${PREDEFINED_DOMAIN_NAMES.join(', ')}) or existing domains.`,
105
+ };
106
+ }
107
+ // New custom domain within limit - allowed
108
+ return { allowed: true, existingDomains };
109
+ }
53
110
  /**
54
111
  * Build the full filesystem path from base path and knowledge path.
112
+ * Returns the folder path (not including filename).
55
113
  */
56
114
  function buildFullPath(basePath, knowledgePath) {
57
115
  const parsed = parsePath(knowledgePath);
58
116
  if (!parsed) {
59
117
  throw new Error(`Invalid path format: ${knowledgePath}`);
60
118
  }
61
- const domainPath = join(basePath, sanitizeFolderName(parsed.domain));
62
- const topicPath = join(domainPath, sanitizeFolderName(parsed.topic));
119
+ const domainPath = join(basePath, toSnakeCase(parsed.domain));
120
+ const topicPath = join(domainPath, toSnakeCase(parsed.topic));
63
121
  if (parsed.subtopic) {
64
- return join(topicPath, sanitizeFolderName(parsed.subtopic));
122
+ return join(topicPath, toSnakeCase(parsed.subtopic));
65
123
  }
66
124
  return topicPath;
67
125
  }
68
126
  /**
69
- * Execute ADD operation - create new domain/topic/subtopic with context.md
127
+ * Execute ADD operation - create new domain/topic/subtopic with {title}.md
70
128
  */
71
129
  async function executeAdd(basePath, operation) {
72
- const { content, path, reason } = operation;
130
+ const { content, path, reason, title } = operation;
131
+ if (!title) {
132
+ return {
133
+ message: 'ADD operation requires a title',
134
+ path,
135
+ status: 'failed',
136
+ type: 'ADD',
137
+ };
138
+ }
73
139
  if (!content) {
74
140
  return {
75
141
  message: 'ADD operation requires content',
@@ -88,30 +154,33 @@ async function executeAdd(basePath, operation) {
88
154
  type: 'ADD',
89
155
  };
90
156
  }
91
- // Ensure base structure exists
92
- await DirectoryManager.ensureKnowledgeStructure(basePath);
93
- // Create domain folder
94
- const domainPath = join(basePath, sanitizeFolderName(parsed.domain));
95
- await DirectoryManager.createOrUpdateDomain(domainPath);
96
- // Create topic folder
97
- const topicPath = join(domainPath, sanitizeFolderName(parsed.topic));
98
- await DirectoryManager.createOrUpdateTopic(topicPath);
99
- // Determine final path (topic or subtopic)
100
- let finalPath = topicPath;
101
- if (parsed.subtopic) {
102
- finalPath = join(topicPath, sanitizeFolderName(parsed.subtopic));
103
- await DirectoryManager.createOrUpdateTopic(finalPath);
157
+ // Validate domain before creating
158
+ const domainValidation = await validateDomain(basePath, parsed.domain);
159
+ if (!domainValidation.allowed) {
160
+ return {
161
+ message: domainValidation.reason,
162
+ path,
163
+ status: 'failed',
164
+ type: 'ADD',
165
+ };
104
166
  }
105
- // Generate and write context.md
167
+ // Build the final folder path (topic or subtopic)
168
+ const domainPath = join(basePath, toSnakeCase(parsed.domain));
169
+ const topicPath = join(domainPath, toSnakeCase(parsed.topic));
170
+ const finalPath = parsed.subtopic ? join(topicPath, toSnakeCase(parsed.subtopic)) : topicPath;
171
+ // Generate and write {title}.md (snake_case filename)
172
+ // Note: writeFileAtomic creates parent directories as needed, avoiding empty folder creation
106
173
  const contextContent = MarkdownWriter.generateContext({
107
- name: parsed.subtopic || parsed.topic,
174
+ name: title,
108
175
  relations: content.relations,
109
176
  snippets: content.snippets || [],
110
177
  });
111
- const contextPath = join(finalPath, 'context.md');
178
+ const filename = `${toSnakeCase(title)}.md`;
179
+ const contextPath = join(finalPath, filename);
112
180
  await DirectoryManager.writeFileAtomic(contextPath, contextContent);
113
181
  return {
114
- message: `Created ${path} with ${content.snippets?.length || 0} snippets. Reason: ${reason}`,
182
+ filePath: contextPath,
183
+ message: `Created ${path}/${filename} with ${content.snippets?.length || 0} snippets. Reason: ${reason}`,
115
184
  path,
116
185
  status: 'success',
117
186
  type: 'ADD',
@@ -127,10 +196,18 @@ async function executeAdd(basePath, operation) {
127
196
  }
128
197
  }
129
198
  /**
130
- * Execute UPDATE operation - modify existing context.md
199
+ * Execute UPDATE operation - modify existing {title}.md
131
200
  */
132
201
  async function executeUpdate(basePath, operation) {
133
- const { content, path, reason } = operation;
202
+ const { content, path, reason, title } = operation;
203
+ if (!title) {
204
+ return {
205
+ message: 'UPDATE operation requires a title',
206
+ path,
207
+ status: 'failed',
208
+ type: 'UPDATE',
209
+ };
210
+ }
134
211
  if (!content) {
135
212
  return {
136
213
  message: 'UPDATE operation requires content',
@@ -141,27 +218,28 @@ async function executeUpdate(basePath, operation) {
141
218
  }
142
219
  try {
143
220
  const fullPath = buildFullPath(basePath, path);
144
- const contextPath = join(fullPath, 'context.md');
145
- // Check if topic exists
221
+ const filename = `${toSnakeCase(title)}.md`;
222
+ const contextPath = join(fullPath, filename);
223
+ // Check if the specific titled file exists
146
224
  const exists = await DirectoryManager.fileExists(contextPath);
147
225
  if (!exists) {
148
226
  return {
149
- message: `Topic does not exist: ${path}`,
227
+ message: `File does not exist: ${path}/${filename}`,
150
228
  path,
151
229
  status: 'failed',
152
230
  type: 'UPDATE',
153
231
  };
154
232
  }
155
- // Generate and write updated context.md (full replacement)
156
- const parsed = parsePath(path);
233
+ // Generate and write updated content (full replacement)
157
234
  const contextContent = MarkdownWriter.generateContext({
158
- name: parsed?.subtopic || parsed?.topic || path,
235
+ name: title,
159
236
  relations: content.relations,
160
237
  snippets: content.snippets || [],
161
238
  });
162
239
  await DirectoryManager.writeFileAtomic(contextPath, contextContent);
163
240
  return {
164
- message: `Updated ${path}. Reason: ${reason}`,
241
+ filePath: contextPath,
242
+ message: `Updated ${path}/${filename}. Reason: ${reason}`,
165
243
  path,
166
244
  status: 'success',
167
245
  type: 'UPDATE',
@@ -177,10 +255,18 @@ async function executeUpdate(basePath, operation) {
177
255
  }
178
256
  }
179
257
  /**
180
- * Execute MERGE operation - combine source into target, delete source
258
+ * Execute MERGE operation - combine source file into target file, delete source file
181
259
  */
182
260
  async function executeMerge(basePath, operation) {
183
- const { mergeTarget, path, reason } = operation;
261
+ const { mergeTarget, mergeTargetTitle, path, reason, title } = operation;
262
+ if (!title) {
263
+ return {
264
+ message: 'MERGE operation requires a title (source file)',
265
+ path,
266
+ status: 'failed',
267
+ type: 'MERGE',
268
+ };
269
+ }
184
270
  if (!mergeTarget) {
185
271
  return {
186
272
  message: 'MERGE operation requires mergeTarget',
@@ -189,17 +275,27 @@ async function executeMerge(basePath, operation) {
189
275
  type: 'MERGE',
190
276
  };
191
277
  }
278
+ if (!mergeTargetTitle) {
279
+ return {
280
+ message: 'MERGE operation requires mergeTargetTitle',
281
+ path,
282
+ status: 'failed',
283
+ type: 'MERGE',
284
+ };
285
+ }
192
286
  try {
193
- const sourcePath = buildFullPath(basePath, path);
194
- const targetPath = buildFullPath(basePath, mergeTarget);
195
- const sourceContextPath = join(sourcePath, 'context.md');
196
- const targetContextPath = join(targetPath, 'context.md');
197
- // Check if both exist
287
+ const sourceFolderPath = buildFullPath(basePath, path);
288
+ const targetFolderPath = buildFullPath(basePath, mergeTarget);
289
+ const sourceFilename = `${toSnakeCase(title)}.md`;
290
+ const targetFilename = `${toSnakeCase(mergeTargetTitle)}.md`;
291
+ const sourceContextPath = join(sourceFolderPath, sourceFilename);
292
+ const targetContextPath = join(targetFolderPath, targetFilename);
293
+ // Check if both files exist
198
294
  const sourceExists = await DirectoryManager.fileExists(sourceContextPath);
199
295
  const targetExists = await DirectoryManager.fileExists(targetContextPath);
200
296
  if (!sourceExists) {
201
297
  return {
202
- message: `Source topic does not exist: ${path}`,
298
+ message: `Source file does not exist: ${path}/${sourceFilename}`,
203
299
  path,
204
300
  status: 'failed',
205
301
  type: 'MERGE',
@@ -207,22 +303,23 @@ async function executeMerge(basePath, operation) {
207
303
  }
208
304
  if (!targetExists) {
209
305
  return {
210
- message: `Target topic does not exist: ${mergeTarget}`,
306
+ message: `Target file does not exist: ${mergeTarget}/${targetFilename}`,
211
307
  path,
212
308
  status: 'failed',
213
309
  type: 'MERGE',
214
310
  };
215
311
  }
216
- // Read both contexts
312
+ // Read both files
217
313
  const sourceContent = await DirectoryManager.readFile(sourceContextPath);
218
314
  const targetContent = await DirectoryManager.readFile(targetContextPath);
219
- // Merge the contexts using MarkdownWriter
315
+ // Merge the contents using MarkdownWriter
220
316
  const mergedContent = MarkdownWriter.mergeContexts(sourceContent, targetContent);
221
317
  await DirectoryManager.writeFileAtomic(targetContextPath, mergedContent);
222
- // Delete source folder
223
- await DirectoryManager.deleteTopicRecursive(sourcePath);
318
+ // Delete source file (not the entire folder, just the file)
319
+ await DirectoryManager.deleteFile(sourceContextPath);
224
320
  return {
225
- message: `Merged ${path} into ${mergeTarget}. Reason: ${reason}`,
321
+ filePath: targetContextPath,
322
+ message: `Merged ${path}/${sourceFilename} into ${mergeTarget}/${targetFilename}. Reason: ${reason}`,
226
323
  path,
227
324
  status: 'success',
228
325
  type: 'MERGE',
@@ -238,27 +335,47 @@ async function executeMerge(basePath, operation) {
238
335
  }
239
336
  }
240
337
  /**
241
- * Execute DELETE operation - remove topic/subtopic folder recursively
338
+ * Execute DELETE operation - remove specific file or entire folder
339
+ * If title is provided, deletes specific file; if omitted, deletes entire folder
242
340
  */
243
341
  async function executeDelete(basePath, operation) {
244
- const { path, reason } = operation;
342
+ const { path, reason, title } = operation;
245
343
  try {
246
344
  const fullPath = buildFullPath(basePath, path);
247
- const contextPath = join(fullPath, 'context.md');
248
- // Check if topic exists
249
- const exists = await DirectoryManager.fileExists(contextPath);
345
+ if (title) {
346
+ // Delete specific file
347
+ const filename = `${toSnakeCase(title)}.md`;
348
+ const filePath = join(fullPath, filename);
349
+ const exists = await DirectoryManager.fileExists(filePath);
350
+ if (!exists) {
351
+ return {
352
+ message: `File does not exist: ${path}/${filename}`,
353
+ path,
354
+ status: 'failed',
355
+ type: 'DELETE',
356
+ };
357
+ }
358
+ await DirectoryManager.deleteFile(filePath);
359
+ return {
360
+ message: `Deleted ${path}/${filename}. Reason: ${reason}`,
361
+ path,
362
+ status: 'success',
363
+ type: 'DELETE',
364
+ };
365
+ }
366
+ // Delete entire folder (when no title provided)
367
+ const exists = await DirectoryManager.folderExists(fullPath);
250
368
  if (!exists) {
251
369
  return {
252
- message: `Topic does not exist: ${path}`,
370
+ message: `Folder does not exist: ${path}`,
253
371
  path,
254
372
  status: 'failed',
255
373
  type: 'DELETE',
256
374
  };
257
375
  }
258
- // Delete folder recursively
259
376
  await DirectoryManager.deleteTopicRecursive(fullPath);
260
377
  return {
261
- message: `Deleted ${path}. Reason: ${reason}`,
378
+ message: `Deleted folder ${path}. Reason: ${reason}`,
262
379
  path,
263
380
  status: 'success',
264
381
  type: 'DELETE',
@@ -345,25 +462,35 @@ export function createCurateTool() {
345
462
  description: `Curate knowledge topics with atomic operations. This tool manages the knowledge structure using four operation types:
346
463
 
347
464
  **Operations:**
348
- 1. **ADD** - Create new domain/topic/subtopic with context.md
349
- - Requires: path, content (snippets and/or relations), reason
350
- - Example: { type: "ADD", path: "code_style/error-handling", content: { snippets: ["..."], relations: ["logging/basics"] }, reason: "New pattern identified" }
465
+ 1. **ADD** - Create new titled context file in domain/topic/subtopic
466
+ - Requires: path, title, content (snippets and/or relations), reason
467
+ - Example: { type: "ADD", path: "code_style/error_handling", title: "Best Practices", content: { snippets: ["..."], relations: ["logging/basics"] }, reason: "New pattern" }
468
+ - Creates: code_style/error_handling/best_practices.md
469
+
470
+ 2. **UPDATE** - Modify existing titled context file (full replacement)
471
+ - Requires: path, title, content, reason
472
+ - Example: { type: "UPDATE", path: "code_style/error_handling", title: "Best Practices", content: { snippets: ["Updated"] }, reason: "Improved" }
351
473
 
352
- 2. **UPDATE** - Modify existing context.md (full replacement)
353
- - Requires: path, content, reason
354
- - Example: { type: "UPDATE", path: "code_style/error-handling", content: { snippets: ["Updated content"] }, reason: "Improved guidance" }
474
+ 3. **MERGE** - Combine source file into target file, delete source
475
+ - Requires: path (source), title (source file), mergeTarget (destination path), mergeTargetTitle (destination file), reason
476
+ - Example: { type: "MERGE", path: "code_style/old_topic", title: "Old Guide", mergeTarget: "code_style/new_topic", mergeTargetTitle: "New Guide", reason: "Consolidating" }
355
477
 
356
- 3. **MERGE** - Combine source topic into target, delete source
357
- - Requires: path (source), mergeTarget (destination), reason
358
- - Example: { type: "MERGE", path: "code_style/old-topic", mergeTarget: "code_style/new-topic", reason: "Consolidating duplicates" }
478
+ 4. **DELETE** - Remove specific file or entire folder
479
+ - Requires: path, title (optional), reason
480
+ - With title: deletes specific file; without title: deletes entire folder
481
+ - Example (file): { type: "DELETE", path: "code_style/deprecated", title: "Old Guide", reason: "No longer relevant" }
482
+ - Example (folder): { type: "DELETE", path: "code_style/deprecated", title: "", reason: "Removing topic" }
359
483
 
360
- 4. **DELETE** - Remove topic/subtopic folder recursively
361
- - Requires: path, reason
362
- - Example: { type: "DELETE", path: "code_style/deprecated-topic", reason: "No longer relevant" }
484
+ **Path format:** domain/topic or domain/topic/subtopic (uses snake_case automatically)
485
+ **File naming:** Titles are converted to snake_case (e.g., "Best Practices" -> "best_practices.md")
363
486
 
364
- **Path format:** domain/topic or domain/topic/subtopic
487
+ **Domain constraints:**
488
+ - Predefined domains: code_style, design, structure, compliance, testing, bug_fixes
489
+ - Up to 3 additional custom domains are allowed
490
+ - Always prefer predefined domains when possible
491
+ - Creating new domains beyond the limit will fail
365
492
 
366
- **Output:** Returns applied operations with status (success/failed) and a summary of counts.`,
493
+ **Output:** Returns applied operations with status (success/failed), filePath (for created/modified files), and a summary of counts.`,
367
494
  execute: executeCurate,
368
495
  id: ToolName.CURATE,
369
496
  inputSchema: CurateInputSchema,
@@ -0,0 +1,12 @@
1
+ import type { Tool } from '../../../../core/domain/cipher/tools/types.js';
2
+ import type { IFileSystem } from '../../../../core/interfaces/cipher/i-file-system.js';
3
+ /**
4
+ * Creates the list directory tool.
5
+ *
6
+ * Lists files and directories in a tree structure.
7
+ * Automatically ignores common build artifacts and caches.
8
+ *
9
+ * @param fileSystemService - File system service dependency
10
+ * @returns Configured list directory tool
11
+ */
12
+ export declare function createListDirectoryTool(fileSystemService: IFileSystem): Tool;