byterover-cli 0.3.4 → 0.4.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 (346) hide show
  1. package/README.md +119 -63
  2. package/bin/dev.js +8 -1
  3. package/bin/run.js +7 -0
  4. package/dist/commands/cipher-agent/run.d.ts +30 -0
  5. package/dist/commands/cipher-agent/run.js +123 -61
  6. package/dist/commands/cipher-agent/set-prompt.d.ts +2 -0
  7. package/dist/commands/cipher-agent/set-prompt.js +13 -8
  8. package/dist/commands/cipher-agent/show-prompt.d.ts +2 -0
  9. package/dist/commands/cipher-agent/show-prompt.js +17 -12
  10. package/dist/commands/curate.d.ts +3 -60
  11. package/dist/commands/curate.js +45 -341
  12. package/dist/commands/foo.d.ts +4 -2
  13. package/dist/commands/foo.js +21 -16
  14. package/dist/commands/main.d.ts +9 -0
  15. package/dist/commands/main.js +34 -0
  16. package/dist/commands/query.d.ts +2 -48
  17. package/dist/commands/query.js +19 -287
  18. package/dist/commands/status.d.ts +2 -13
  19. package/dist/commands/status.js +12 -91
  20. package/dist/commands/watch.d.ts +2 -0
  21. package/dist/commands/watch.js +23 -19
  22. package/dist/config/environment.d.ts +1 -1
  23. package/dist/config/environment.js +2 -2
  24. package/dist/constants.d.ts +4 -5
  25. package/dist/constants.js +5 -5
  26. package/dist/core/domain/cipher/errors/storage-error.d.ts +89 -0
  27. package/dist/core/domain/cipher/errors/storage-error.js +130 -0
  28. package/dist/core/domain/cipher/queue/types.d.ts +71 -0
  29. package/dist/core/domain/cipher/queue/types.js +9 -0
  30. package/dist/core/domain/cipher/storage/message-storage-types.d.ts +218 -0
  31. package/dist/core/domain/cipher/storage/message-storage-types.js +18 -0
  32. package/dist/core/domain/cipher/tools/constants.d.ts +1 -0
  33. package/dist/core/domain/cipher/tools/constants.js +1 -0
  34. package/dist/core/domain/entities/event.d.ts +1 -1
  35. package/dist/core/domain/entities/event.js +5 -0
  36. package/dist/core/domain/entities/global-config.d.ts +36 -0
  37. package/dist/core/domain/entities/global-config.js +66 -0
  38. package/dist/core/domain/knowledge/directory-manager.d.ts +10 -0
  39. package/dist/core/domain/knowledge/directory-manager.js +18 -0
  40. package/dist/core/domain/knowledge/markdown-writer.d.ts +9 -0
  41. package/dist/core/domain/knowledge/markdown-writer.js +51 -1
  42. package/dist/core/interfaces/cipher/i-agent-storage.d.ts +152 -0
  43. package/dist/core/interfaces/cipher/i-agent-storage.js +1 -0
  44. package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +2 -0
  45. package/dist/core/interfaces/cipher/i-key-storage.d.ts +91 -0
  46. package/dist/core/interfaces/cipher/i-key-storage.js +1 -0
  47. package/dist/core/interfaces/i-global-config-store.d.ts +34 -0
  48. package/dist/core/interfaces/i-global-config-store.js +1 -0
  49. package/dist/core/interfaces/i-onboarding-preference-store.d.ts +20 -0
  50. package/dist/core/interfaces/i-onboarding-preference-store.js +1 -0
  51. package/dist/core/interfaces/i-terminal.d.ts +146 -0
  52. package/dist/core/interfaces/i-terminal.js +1 -0
  53. package/dist/core/interfaces/i-workspace-detector-service.d.ts +8 -0
  54. package/dist/core/interfaces/i-workspace-detector-service.js +1 -0
  55. package/dist/core/interfaces/usecase/i-clear-use-case.d.ts +6 -0
  56. package/dist/core/interfaces/usecase/i-clear-use-case.js +1 -0
  57. package/dist/core/interfaces/usecase/i-curate-use-case.d.ts +10 -0
  58. package/dist/core/interfaces/usecase/i-curate-use-case.js +1 -0
  59. package/dist/core/interfaces/usecase/i-generate-rules-use-case.d.ts +3 -0
  60. package/dist/core/interfaces/usecase/i-generate-rules-use-case.js +1 -0
  61. package/dist/core/interfaces/usecase/i-init-use-case.d.ts +5 -0
  62. package/dist/core/interfaces/usecase/i-init-use-case.js +1 -0
  63. package/dist/core/interfaces/usecase/i-login-use-case.d.ts +3 -0
  64. package/dist/core/interfaces/usecase/i-login-use-case.js +1 -0
  65. package/dist/core/interfaces/usecase/i-logout-use-case.d.ts +5 -0
  66. package/dist/core/interfaces/usecase/i-logout-use-case.js +1 -0
  67. package/dist/core/interfaces/usecase/i-pull-use-case.d.ts +5 -0
  68. package/dist/core/interfaces/usecase/i-pull-use-case.js +1 -0
  69. package/dist/core/interfaces/usecase/i-push-use-case.d.ts +6 -0
  70. package/dist/core/interfaces/usecase/i-push-use-case.js +1 -0
  71. package/dist/core/interfaces/usecase/i-query-use-case.d.ts +9 -0
  72. package/dist/core/interfaces/usecase/i-query-use-case.js +1 -0
  73. package/dist/core/interfaces/usecase/i-space-list-use-case.d.ts +3 -0
  74. package/dist/core/interfaces/usecase/i-space-list-use-case.js +1 -0
  75. package/dist/core/interfaces/usecase/i-space-switch-use-case.d.ts +3 -0
  76. package/dist/core/interfaces/usecase/i-space-switch-use-case.js +1 -0
  77. package/dist/core/interfaces/usecase/i-status-use-case.d.ts +5 -0
  78. package/dist/core/interfaces/usecase/i-status-use-case.js +1 -0
  79. package/dist/hooks/init/update-notifier.js +1 -5
  80. package/dist/hooks/init/welcome.js +1 -2
  81. package/dist/infra/cipher/agent-service-factory.d.ts +13 -6
  82. package/dist/infra/cipher/agent-service-factory.js +40 -16
  83. package/dist/infra/cipher/cipher-agent.js +4 -4
  84. package/dist/infra/cipher/consumer/consumer-lock.d.ts +20 -0
  85. package/dist/infra/cipher/consumer/consumer-lock.js +40 -0
  86. package/dist/infra/cipher/consumer/consumer-service.d.ts +99 -0
  87. package/dist/infra/cipher/consumer/consumer-service.js +165 -0
  88. package/dist/infra/cipher/consumer/execution-consumer.d.ts +121 -0
  89. package/dist/infra/cipher/consumer/execution-consumer.js +523 -0
  90. package/dist/infra/cipher/consumer/index.d.ts +33 -0
  91. package/dist/infra/cipher/consumer/index.js +33 -0
  92. package/dist/infra/cipher/consumer/queue-polling-service.d.ts +120 -0
  93. package/dist/infra/cipher/consumer/queue-polling-service.js +248 -0
  94. package/dist/infra/cipher/http/internal-llm-http-service.d.ts +94 -0
  95. package/dist/infra/cipher/http/internal-llm-http-service.js +118 -0
  96. package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +106 -0
  97. package/dist/infra/cipher/llm/context/compaction/compaction-service.js +132 -0
  98. package/dist/infra/cipher/llm/context/compaction/index.d.ts +9 -0
  99. package/dist/infra/cipher/llm/context/compaction/index.js +9 -0
  100. package/dist/infra/cipher/llm/context/context-manager.d.ts +46 -2
  101. package/dist/infra/cipher/llm/context/context-manager.js +68 -4
  102. package/dist/infra/cipher/llm/context/rw-lock.d.ts +72 -0
  103. package/dist/infra/cipher/llm/context/rw-lock.js +145 -0
  104. package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +7 -7
  105. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +8 -8
  106. package/dist/infra/cipher/llm/internal-llm-service.js +2 -0
  107. package/dist/infra/cipher/session/session-manager.d.ts +4 -4
  108. package/dist/infra/cipher/session/session-manager.js +5 -5
  109. package/dist/infra/cipher/storage/agent-storage.d.ts +246 -0
  110. package/dist/infra/cipher/storage/agent-storage.js +956 -0
  111. package/dist/infra/cipher/storage/dual-format-history-storage.d.ts +77 -0
  112. package/dist/infra/cipher/storage/dual-format-history-storage.js +149 -0
  113. package/dist/infra/cipher/storage/granular-history-storage.d.ts +65 -0
  114. package/dist/infra/cipher/storage/granular-history-storage.js +118 -0
  115. package/dist/infra/cipher/storage/message-storage-service.d.ts +108 -0
  116. package/dist/infra/cipher/storage/message-storage-service.js +529 -0
  117. package/dist/infra/cipher/storage/process-utils.d.ts +16 -0
  118. package/dist/infra/cipher/storage/process-utils.js +43 -0
  119. package/dist/infra/cipher/storage/sqlite-key-storage.d.ts +105 -0
  120. package/dist/infra/cipher/storage/sqlite-key-storage.js +404 -0
  121. package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +1 -0
  122. package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +7 -0
  123. package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
  124. package/dist/infra/cipher/tools/implementations/curate-tool.d.ts +10 -0
  125. package/dist/infra/cipher/tools/implementations/curate-tool.js +371 -0
  126. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +11 -8
  127. package/dist/infra/cipher/tools/tool-manager.d.ts +8 -2
  128. package/dist/infra/cipher/tools/tool-manager.js +29 -2
  129. package/dist/infra/cipher/tools/tool-registry.js +7 -0
  130. package/dist/infra/http/authenticated-http-client.d.ts +21 -0
  131. package/dist/infra/http/authenticated-http-client.js +38 -0
  132. package/dist/infra/repl/commands/arg-parser.d.ts +97 -0
  133. package/dist/infra/repl/commands/arg-parser.js +129 -0
  134. package/dist/infra/repl/commands/clear-command.d.ts +5 -0
  135. package/dist/infra/repl/commands/clear-command.js +61 -0
  136. package/dist/infra/repl/commands/curate-command.d.ts +9 -0
  137. package/dist/infra/repl/commands/curate-command.js +88 -0
  138. package/dist/infra/repl/commands/gen-rules-command.d.ts +7 -0
  139. package/dist/infra/repl/commands/gen-rules-command.js +38 -0
  140. package/dist/infra/repl/commands/index.d.ts +8 -0
  141. package/dist/infra/repl/commands/index.js +36 -0
  142. package/dist/infra/repl/commands/init-command.d.ts +7 -0
  143. package/dist/infra/repl/commands/init-command.js +83 -0
  144. package/dist/infra/repl/commands/login-command.d.ts +7 -0
  145. package/dist/infra/repl/commands/login-command.js +50 -0
  146. package/dist/infra/repl/commands/logout-command.d.ts +5 -0
  147. package/dist/infra/repl/commands/logout-command.js +48 -0
  148. package/dist/infra/repl/commands/pull-command.d.ts +5 -0
  149. package/dist/infra/repl/commands/pull-command.js +61 -0
  150. package/dist/infra/repl/commands/push-command.d.ts +5 -0
  151. package/dist/infra/repl/commands/push-command.js +66 -0
  152. package/dist/infra/repl/commands/query-command.d.ts +5 -0
  153. package/dist/infra/repl/commands/query-command.js +66 -0
  154. package/dist/infra/repl/commands/space/index.d.ts +5 -0
  155. package/dist/infra/repl/commands/space/index.js +14 -0
  156. package/dist/infra/repl/commands/space/list-command.d.ts +5 -0
  157. package/dist/infra/repl/commands/space/list-command.js +70 -0
  158. package/dist/infra/repl/commands/space/switch-command.d.ts +5 -0
  159. package/dist/infra/repl/commands/space/switch-command.js +37 -0
  160. package/dist/infra/repl/commands/status-command.d.ts +5 -0
  161. package/dist/infra/repl/commands/status-command.js +39 -0
  162. package/dist/infra/repl/repl-startup.d.ts +18 -0
  163. package/dist/infra/repl/repl-startup.js +26 -0
  164. package/dist/infra/storage/file-global-config-store.d.ts +22 -0
  165. package/dist/infra/storage/file-global-config-store.js +65 -0
  166. package/dist/infra/storage/file-onboarding-preference-store.d.ts +10 -0
  167. package/dist/infra/storage/file-onboarding-preference-store.js +46 -0
  168. package/dist/infra/terminal/oclif-terminal.d.ts +19 -0
  169. package/dist/infra/terminal/oclif-terminal.js +60 -0
  170. package/dist/infra/terminal/repl-terminal.d.ts +31 -0
  171. package/dist/infra/terminal/repl-terminal.js +116 -0
  172. package/dist/infra/tracking/mixpanel-tracking-service.d.ts +11 -1
  173. package/dist/infra/tracking/mixpanel-tracking-service.js +18 -13
  174. package/dist/infra/usecase/clear-use-case.d.ts +20 -0
  175. package/dist/infra/usecase/clear-use-case.js +58 -0
  176. package/dist/infra/usecase/curate-use-case.d.ts +66 -0
  177. package/dist/infra/usecase/curate-use-case.js +283 -0
  178. package/dist/{commands/gen-rules.d.ts → infra/usecase/generate-rules-use-case.d.ts} +14 -20
  179. package/dist/{commands/gen-rules.js → infra/usecase/generate-rules-use-case.js} +59 -78
  180. package/dist/infra/usecase/init-use-case.d.ts +139 -0
  181. package/dist/{commands/init.js → infra/usecase/init-use-case.js} +184 -230
  182. package/dist/infra/usecase/login-use-case.d.ts +28 -0
  183. package/dist/infra/usecase/login-use-case.js +88 -0
  184. package/dist/infra/usecase/logout-use-case.d.ts +22 -0
  185. package/dist/infra/usecase/logout-use-case.js +51 -0
  186. package/dist/infra/usecase/pull-use-case.d.ts +35 -0
  187. package/dist/infra/usecase/pull-use-case.js +89 -0
  188. package/dist/infra/usecase/push-use-case.d.ts +37 -0
  189. package/dist/infra/usecase/push-use-case.js +124 -0
  190. package/dist/infra/usecase/query-use-case.d.ts +78 -0
  191. package/dist/infra/usecase/query-use-case.js +401 -0
  192. package/dist/infra/usecase/space-list-use-case.d.ts +27 -0
  193. package/dist/infra/usecase/space-list-use-case.js +64 -0
  194. package/dist/infra/usecase/space-switch-use-case.d.ts +36 -0
  195. package/dist/infra/usecase/space-switch-use-case.js +140 -0
  196. package/dist/infra/usecase/status-use-case.d.ts +27 -0
  197. package/dist/infra/usecase/status-use-case.js +97 -0
  198. package/dist/infra/workspace/workspace-detector-service.d.ts +3 -6
  199. package/dist/resources/prompts/curate-context-tree-curation.yml +23 -11
  200. package/dist/resources/prompts/query-context-tree-retrieval.yml +3 -4
  201. package/dist/resources/prompts/system-prompt.yml +1 -1
  202. package/dist/resources/prompts/tool-outputs.yml +4 -3
  203. package/dist/templates/sections/command-reference.md +12 -0
  204. package/dist/templates/sections/workflow.md +10 -1
  205. package/dist/tui/app.d.ts +9 -0
  206. package/dist/tui/app.js +26 -0
  207. package/dist/tui/components/enter-prompt.d.ts +13 -0
  208. package/dist/tui/components/enter-prompt.js +15 -0
  209. package/dist/tui/components/execution/execution-changes.d.ts +14 -0
  210. package/dist/tui/components/execution/execution-changes.js +15 -0
  211. package/dist/tui/components/execution/execution-content.d.ts +25 -0
  212. package/dist/tui/components/execution/execution-content.js +67 -0
  213. package/dist/tui/components/execution/execution-input.d.ts +12 -0
  214. package/dist/tui/components/execution/execution-input.js +16 -0
  215. package/dist/tui/components/execution/execution-progress.d.ts +21 -0
  216. package/dist/tui/components/execution/execution-progress.js +21 -0
  217. package/dist/tui/components/execution/execution-status.d.ts +13 -0
  218. package/dist/tui/components/execution/execution-status.js +19 -0
  219. package/dist/tui/components/execution/index.d.ts +11 -0
  220. package/dist/tui/components/execution/index.js +11 -0
  221. package/dist/tui/components/execution/log-item.d.ts +17 -0
  222. package/dist/tui/components/execution/log-item.js +25 -0
  223. package/dist/tui/components/footer.d.ts +5 -0
  224. package/dist/tui/components/footer.js +12 -0
  225. package/dist/tui/components/header.d.ts +18 -0
  226. package/dist/tui/components/header.js +18 -0
  227. package/dist/tui/components/index.d.ts +17 -0
  228. package/dist/tui/components/index.js +14 -0
  229. package/dist/tui/components/inline-prompts/index.d.ts +15 -0
  230. package/dist/tui/components/inline-prompts/index.js +10 -0
  231. package/dist/tui/components/inline-prompts/inline-confirm.d.ts +17 -0
  232. package/dist/tui/components/inline-prompts/inline-confirm.js +32 -0
  233. package/dist/tui/components/inline-prompts/inline-file-selector.d.ts +43 -0
  234. package/dist/tui/components/inline-prompts/inline-file-selector.js +185 -0
  235. package/dist/tui/components/inline-prompts/inline-input.d.ts +19 -0
  236. package/dist/tui/components/inline-prompts/inline-input.js +32 -0
  237. package/dist/tui/components/inline-prompts/inline-search.d.ts +20 -0
  238. package/dist/tui/components/inline-prompts/inline-search.js +50 -0
  239. package/dist/tui/components/inline-prompts/inline-select.d.ts +20 -0
  240. package/dist/tui/components/inline-prompts/inline-select.js +34 -0
  241. package/dist/tui/components/logo.d.ts +43 -0
  242. package/dist/tui/components/logo.js +103 -0
  243. package/dist/tui/components/message-item.d.ts +12 -0
  244. package/dist/tui/components/message-item.js +12 -0
  245. package/dist/tui/components/onboarding/copyable-prompt.d.ts +15 -0
  246. package/dist/tui/components/onboarding/copyable-prompt.js +65 -0
  247. package/dist/tui/components/onboarding/index.d.ts +7 -0
  248. package/dist/tui/components/onboarding/index.js +6 -0
  249. package/dist/tui/components/onboarding/onboarding-flow.d.ts +13 -0
  250. package/dist/tui/components/onboarding/onboarding-flow.js +304 -0
  251. package/dist/tui/components/onboarding/onboarding-step.d.ts +23 -0
  252. package/dist/tui/components/onboarding/onboarding-step.js +12 -0
  253. package/dist/tui/components/output-log.d.ts +14 -0
  254. package/dist/tui/components/output-log.js +13 -0
  255. package/dist/tui/components/scrollable-list.d.ts +30 -0
  256. package/dist/tui/components/scrollable-list.js +121 -0
  257. package/dist/tui/components/suggestions.d.ts +16 -0
  258. package/dist/tui/components/suggestions.js +162 -0
  259. package/dist/tui/components/tab-bar.d.ts +10 -0
  260. package/dist/tui/components/tab-bar.js +12 -0
  261. package/dist/tui/constants.d.ts +11 -0
  262. package/dist/tui/constants.js +13 -0
  263. package/dist/tui/contexts/auth-context.d.ts +30 -0
  264. package/dist/tui/contexts/auth-context.js +153 -0
  265. package/dist/tui/contexts/consumer.d.ts +31 -0
  266. package/dist/tui/contexts/consumer.js +56 -0
  267. package/dist/tui/contexts/index.d.ts +6 -0
  268. package/dist/tui/contexts/index.js +6 -0
  269. package/dist/tui/contexts/onboarding-context.d.ts +43 -0
  270. package/dist/tui/contexts/onboarding-context.js +181 -0
  271. package/dist/tui/contexts/services-context.d.ts +29 -0
  272. package/dist/tui/contexts/services-context.js +20 -0
  273. package/dist/tui/contexts/use-commands.d.ts +29 -0
  274. package/dist/tui/contexts/use-commands.js +53 -0
  275. package/dist/tui/contexts/use-mode.d.ts +43 -0
  276. package/dist/tui/contexts/use-mode.js +76 -0
  277. package/dist/tui/contexts/use-theme.d.ts +53 -0
  278. package/dist/tui/contexts/use-theme.js +60 -0
  279. package/dist/tui/hooks/index.d.ts +17 -0
  280. package/dist/tui/hooks/index.js +14 -0
  281. package/dist/tui/hooks/use-activity-logs.d.ts +26 -0
  282. package/dist/tui/hooks/use-activity-logs.js +90 -0
  283. package/dist/tui/hooks/use-consumer.d.ts +12 -0
  284. package/dist/tui/hooks/use-consumer.js +50 -0
  285. package/dist/tui/hooks/use-onboarding.d.ts +7 -0
  286. package/dist/tui/hooks/use-onboarding.js +6 -0
  287. package/dist/tui/hooks/use-queue-polling.d.ts +31 -0
  288. package/dist/tui/hooks/use-queue-polling.js +90 -0
  289. package/dist/tui/hooks/use-slash-command-processor.d.ts +16 -0
  290. package/dist/tui/hooks/use-slash-command-processor.js +132 -0
  291. package/dist/tui/hooks/use-slash-completion.d.ts +30 -0
  292. package/dist/tui/hooks/use-slash-completion.js +230 -0
  293. package/dist/tui/hooks/use-tab-navigation.d.ts +10 -0
  294. package/dist/tui/hooks/use-tab-navigation.js +35 -0
  295. package/dist/tui/hooks/use-visible-window.d.ts +22 -0
  296. package/dist/tui/hooks/use-visible-window.js +37 -0
  297. package/dist/tui/index.d.ts +1 -0
  298. package/dist/tui/index.js +1 -0
  299. package/dist/tui/providers/app-providers.d.ts +25 -0
  300. package/dist/tui/providers/app-providers.js +9 -0
  301. package/dist/tui/types/commands.d.ts +252 -0
  302. package/dist/tui/types/commands.js +16 -0
  303. package/dist/tui/types/dialogs.d.ts +37 -0
  304. package/dist/tui/types/dialogs.js +4 -0
  305. package/dist/tui/types/index.d.ts +11 -0
  306. package/dist/tui/types/index.js +7 -0
  307. package/dist/tui/types/messages.d.ts +55 -0
  308. package/dist/tui/types/messages.js +4 -0
  309. package/dist/tui/types/prompts.d.ts +100 -0
  310. package/dist/tui/types/prompts.js +4 -0
  311. package/dist/tui/types/ui.d.ts +14 -0
  312. package/dist/tui/types/ui.js +4 -0
  313. package/dist/tui/types.d.ts +1 -0
  314. package/dist/tui/types.js +1 -0
  315. package/dist/tui/views/command-view.d.ts +12 -0
  316. package/dist/tui/views/command-view.js +451 -0
  317. package/dist/tui/views/index.d.ts +6 -0
  318. package/dist/tui/views/index.js +6 -0
  319. package/dist/tui/views/login-view.d.ts +10 -0
  320. package/dist/tui/views/login-view.js +30 -0
  321. package/dist/tui/views/logs-view.d.ts +11 -0
  322. package/dist/tui/views/logs-view.js +73 -0
  323. package/dist/utils/file-validator.d.ts +16 -0
  324. package/dist/utils/file-validator.js +81 -0
  325. package/dist/utils/global-config-path.d.ts +15 -0
  326. package/dist/utils/global-config-path.js +38 -0
  327. package/oclif.manifest.json +29 -315
  328. package/package.json +11 -4
  329. package/dist/commands/clear.d.ts +0 -19
  330. package/dist/commands/clear.js +0 -78
  331. package/dist/commands/init.d.ts +0 -130
  332. package/dist/commands/login.d.ts +0 -22
  333. package/dist/commands/login.js +0 -108
  334. package/dist/commands/logout.d.ts +0 -16
  335. package/dist/commands/logout.js +0 -61
  336. package/dist/commands/pull.d.ts +0 -33
  337. package/dist/commands/pull.js +0 -115
  338. package/dist/commands/push.d.ts +0 -35
  339. package/dist/commands/push.js +0 -160
  340. package/dist/commands/space/list.d.ts +0 -25
  341. package/dist/commands/space/list.js +0 -114
  342. package/dist/commands/space/switch.d.ts +0 -36
  343. package/dist/commands/space/switch.js +0 -160
  344. package/dist/infra/cipher/grpc/internal-llm-grpc-service.d.ts +0 -149
  345. package/dist/infra/cipher/grpc/internal-llm-grpc-service.js +0 -364
  346. package/dist/infra/cipher/grpc/internal-llm-grpc.proto +0 -94
@@ -0,0 +1,371 @@
1
+ import { join } from 'node:path';
2
+ import { z } from 'zod';
3
+ import { ToolName } from '../../../../core/domain/cipher/tools/constants.js';
4
+ import { DirectoryManager } from '../../../../core/domain/knowledge/directory-manager.js';
5
+ import { MarkdownWriter } from '../../../../core/domain/knowledge/markdown-writer.js';
6
+ import { sanitizeFolderName } from '../../../../utils/file-helpers.js';
7
+ /**
8
+ * Operation types for curating knowledge topics.
9
+ * Inspired by ACE Curator patterns.
10
+ */
11
+ const OperationType = z.enum(['ADD', 'UPDATE', 'MERGE', 'DELETE']);
12
+ /**
13
+ * Content structure for ADD and UPDATE operations.
14
+ */
15
+ const ContentSchema = z.object({
16
+ relations: z
17
+ .array(z.string())
18
+ .optional()
19
+ .describe('Related topics using @domain/topic or @domain/topic/subtopic notation'),
20
+ snippets: z.array(z.string()).optional().describe('Code/text snippets'),
21
+ });
22
+ /**
23
+ * Single operation schema for curating knowledge.
24
+ */
25
+ const OperationSchema = z.object({
26
+ content: ContentSchema.optional().describe('Content for ADD/UPDATE operations'),
27
+ mergeTarget: z.string().optional().describe('Target path for MERGE operation'),
28
+ path: z.string().describe('Path: domain/topic or domain/topic/subtopic'),
29
+ reason: z.string().describe('Reasoning for this operation'),
30
+ type: OperationType.describe('Operation type: ADD, UPDATE, MERGE, or DELETE'),
31
+ });
32
+ /**
33
+ * Input schema for curate tool.
34
+ */
35
+ const CurateInputSchema = z.object({
36
+ basePath: z.string().default('.brv/context-tree').describe('Base path for knowledge storage'),
37
+ operations: z.array(OperationSchema).describe('Array of curate operations to apply'),
38
+ });
39
+ /**
40
+ * Parse a path into domain, topic, and optional subtopic.
41
+ */
42
+ function parsePath(path) {
43
+ const parts = path.split('/');
44
+ if (parts.length < 2 || parts.length > 3) {
45
+ return null;
46
+ }
47
+ return {
48
+ domain: parts[0],
49
+ subtopic: parts[2],
50
+ topic: parts[1],
51
+ };
52
+ }
53
+ /**
54
+ * Build the full filesystem path from base path and knowledge path.
55
+ */
56
+ function buildFullPath(basePath, knowledgePath) {
57
+ const parsed = parsePath(knowledgePath);
58
+ if (!parsed) {
59
+ throw new Error(`Invalid path format: ${knowledgePath}`);
60
+ }
61
+ const domainPath = join(basePath, sanitizeFolderName(parsed.domain));
62
+ const topicPath = join(domainPath, sanitizeFolderName(parsed.topic));
63
+ if (parsed.subtopic) {
64
+ return join(topicPath, sanitizeFolderName(parsed.subtopic));
65
+ }
66
+ return topicPath;
67
+ }
68
+ /**
69
+ * Execute ADD operation - create new domain/topic/subtopic with context.md
70
+ */
71
+ async function executeAdd(basePath, operation) {
72
+ const { content, path, reason } = operation;
73
+ if (!content) {
74
+ return {
75
+ message: 'ADD operation requires content',
76
+ path,
77
+ status: 'failed',
78
+ type: 'ADD',
79
+ };
80
+ }
81
+ try {
82
+ const parsed = parsePath(path);
83
+ if (!parsed) {
84
+ return {
85
+ message: `Invalid path format: ${path}. Expected domain/topic or domain/topic/subtopic`,
86
+ path,
87
+ status: 'failed',
88
+ type: 'ADD',
89
+ };
90
+ }
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);
104
+ }
105
+ // Generate and write context.md
106
+ const contextContent = MarkdownWriter.generateContext({
107
+ name: parsed.subtopic || parsed.topic,
108
+ relations: content.relations,
109
+ snippets: content.snippets || [],
110
+ });
111
+ const contextPath = join(finalPath, 'context.md');
112
+ await DirectoryManager.writeFileAtomic(contextPath, contextContent);
113
+ return {
114
+ message: `Created ${path} with ${content.snippets?.length || 0} snippets. Reason: ${reason}`,
115
+ path,
116
+ status: 'success',
117
+ type: 'ADD',
118
+ };
119
+ }
120
+ catch (error) {
121
+ return {
122
+ message: error instanceof Error ? error.message : String(error),
123
+ path,
124
+ status: 'failed',
125
+ type: 'ADD',
126
+ };
127
+ }
128
+ }
129
+ /**
130
+ * Execute UPDATE operation - modify existing context.md
131
+ */
132
+ async function executeUpdate(basePath, operation) {
133
+ const { content, path, reason } = operation;
134
+ if (!content) {
135
+ return {
136
+ message: 'UPDATE operation requires content',
137
+ path,
138
+ status: 'failed',
139
+ type: 'UPDATE',
140
+ };
141
+ }
142
+ try {
143
+ const fullPath = buildFullPath(basePath, path);
144
+ const contextPath = join(fullPath, 'context.md');
145
+ // Check if topic exists
146
+ const exists = await DirectoryManager.fileExists(contextPath);
147
+ if (!exists) {
148
+ return {
149
+ message: `Topic does not exist: ${path}`,
150
+ path,
151
+ status: 'failed',
152
+ type: 'UPDATE',
153
+ };
154
+ }
155
+ // Generate and write updated context.md (full replacement)
156
+ const parsed = parsePath(path);
157
+ const contextContent = MarkdownWriter.generateContext({
158
+ name: parsed?.subtopic || parsed?.topic || path,
159
+ relations: content.relations,
160
+ snippets: content.snippets || [],
161
+ });
162
+ await DirectoryManager.writeFileAtomic(contextPath, contextContent);
163
+ return {
164
+ message: `Updated ${path}. Reason: ${reason}`,
165
+ path,
166
+ status: 'success',
167
+ type: 'UPDATE',
168
+ };
169
+ }
170
+ catch (error) {
171
+ return {
172
+ message: error instanceof Error ? error.message : String(error),
173
+ path,
174
+ status: 'failed',
175
+ type: 'UPDATE',
176
+ };
177
+ }
178
+ }
179
+ /**
180
+ * Execute MERGE operation - combine source into target, delete source
181
+ */
182
+ async function executeMerge(basePath, operation) {
183
+ const { mergeTarget, path, reason } = operation;
184
+ if (!mergeTarget) {
185
+ return {
186
+ message: 'MERGE operation requires mergeTarget',
187
+ path,
188
+ status: 'failed',
189
+ type: 'MERGE',
190
+ };
191
+ }
192
+ 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
198
+ const sourceExists = await DirectoryManager.fileExists(sourceContextPath);
199
+ const targetExists = await DirectoryManager.fileExists(targetContextPath);
200
+ if (!sourceExists) {
201
+ return {
202
+ message: `Source topic does not exist: ${path}`,
203
+ path,
204
+ status: 'failed',
205
+ type: 'MERGE',
206
+ };
207
+ }
208
+ if (!targetExists) {
209
+ return {
210
+ message: `Target topic does not exist: ${mergeTarget}`,
211
+ path,
212
+ status: 'failed',
213
+ type: 'MERGE',
214
+ };
215
+ }
216
+ // Read both contexts
217
+ const sourceContent = await DirectoryManager.readFile(sourceContextPath);
218
+ const targetContent = await DirectoryManager.readFile(targetContextPath);
219
+ // Merge the contexts using MarkdownWriter
220
+ const mergedContent = MarkdownWriter.mergeContexts(sourceContent, targetContent);
221
+ await DirectoryManager.writeFileAtomic(targetContextPath, mergedContent);
222
+ // Delete source folder
223
+ await DirectoryManager.deleteTopicRecursive(sourcePath);
224
+ return {
225
+ message: `Merged ${path} into ${mergeTarget}. Reason: ${reason}`,
226
+ path,
227
+ status: 'success',
228
+ type: 'MERGE',
229
+ };
230
+ }
231
+ catch (error) {
232
+ return {
233
+ message: error instanceof Error ? error.message : String(error),
234
+ path,
235
+ status: 'failed',
236
+ type: 'MERGE',
237
+ };
238
+ }
239
+ }
240
+ /**
241
+ * Execute DELETE operation - remove topic/subtopic folder recursively
242
+ */
243
+ async function executeDelete(basePath, operation) {
244
+ const { path, reason } = operation;
245
+ try {
246
+ const fullPath = buildFullPath(basePath, path);
247
+ const contextPath = join(fullPath, 'context.md');
248
+ // Check if topic exists
249
+ const exists = await DirectoryManager.fileExists(contextPath);
250
+ if (!exists) {
251
+ return {
252
+ message: `Topic does not exist: ${path}`,
253
+ path,
254
+ status: 'failed',
255
+ type: 'DELETE',
256
+ };
257
+ }
258
+ // Delete folder recursively
259
+ await DirectoryManager.deleteTopicRecursive(fullPath);
260
+ return {
261
+ message: `Deleted ${path}. Reason: ${reason}`,
262
+ path,
263
+ status: 'success',
264
+ type: 'DELETE',
265
+ };
266
+ }
267
+ catch (error) {
268
+ return {
269
+ message: error instanceof Error ? error.message : String(error),
270
+ path,
271
+ status: 'failed',
272
+ type: 'DELETE',
273
+ };
274
+ }
275
+ }
276
+ /**
277
+ * Execute curate operations on knowledge topics.
278
+ */
279
+ async function executeCurate(input, _context) {
280
+ const { basePath, operations } = input;
281
+ const applied = [];
282
+ const summary = {
283
+ added: 0,
284
+ deleted: 0,
285
+ failed: 0,
286
+ merged: 0,
287
+ updated: 0,
288
+ };
289
+ // Process operations sequentially to maintain consistency
290
+ /* eslint-disable no-await-in-loop -- Sequential processing required for dependent operations */
291
+ for (const operation of operations) {
292
+ let result;
293
+ switch (operation.type) {
294
+ case 'ADD': {
295
+ result = await executeAdd(basePath, operation);
296
+ if (result.status === 'success')
297
+ summary.added++;
298
+ break;
299
+ }
300
+ case 'DELETE': {
301
+ result = await executeDelete(basePath, operation);
302
+ if (result.status === 'success')
303
+ summary.deleted++;
304
+ break;
305
+ }
306
+ case 'MERGE': {
307
+ result = await executeMerge(basePath, operation);
308
+ if (result.status === 'success')
309
+ summary.merged++;
310
+ break;
311
+ }
312
+ case 'UPDATE': {
313
+ result = await executeUpdate(basePath, operation);
314
+ if (result.status === 'success')
315
+ summary.updated++;
316
+ break;
317
+ }
318
+ default: {
319
+ result = {
320
+ message: `Unknown operation type: ${operation.type}`,
321
+ path: operation.path,
322
+ status: 'failed',
323
+ type: operation.type,
324
+ };
325
+ }
326
+ }
327
+ if (result.status === 'failed') {
328
+ summary.failed++;
329
+ }
330
+ applied.push(result);
331
+ }
332
+ /* eslint-enable no-await-in-loop */
333
+ return { applied, summary };
334
+ }
335
+ /**
336
+ * Creates the curate tool.
337
+ *
338
+ * This tool manages knowledge topics with atomic operations (ADD, UPDATE, MERGE, DELETE).
339
+ * It applies patterns from the ACE Curator for intelligent knowledge curation.
340
+ *
341
+ * @returns Configured curate tool
342
+ */
343
+ export function createCurateTool() {
344
+ return {
345
+ description: `Curate knowledge topics with atomic operations. This tool manages the knowledge structure using four operation types:
346
+
347
+ **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" }
351
+
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" }
355
+
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" }
359
+
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" }
363
+
364
+ **Path format:** domain/topic or domain/topic/subtopic
365
+
366
+ **Output:** Returns applied operations with status (success/failed) and a summary of counts.`,
367
+ execute: executeCurate,
368
+ id: ToolName.CURATE,
369
+ inputSchema: CurateInputSchema,
370
+ };
371
+ }
@@ -1,5 +1,6 @@
1
1
  import { join } from 'node:path';
2
2
  import { z } from 'zod';
3
+ import { BRV_DIR, CONTEXT_FILE, CONTEXT_TREE_DIR } from '../../../../constants.js';
3
4
  import { ToolName } from '../../../../core/domain/cipher/tools/constants.js';
4
5
  import { DirectoryManager } from '../../../../core/domain/knowledge/directory-manager.js';
5
6
  import { parseRelations } from '../../../../core/domain/knowledge/relation-parser.js';
@@ -10,7 +11,7 @@ import { parseRelations } from '../../../../core/domain/knowledge/relation-parse
10
11
  const FindKnowledgeTopicsInputSchema = z.object({
11
12
  basePath: z
12
13
  .string()
13
- .default('.brv/context-tree')
14
+ .default(`${BRV_DIR}/${CONTEXT_TREE_DIR}`)
14
15
  .describe('Base path to context tree structure'),
15
16
  // Scoping
16
17
  domain: z
@@ -96,7 +97,7 @@ async function processSubtopicFile(params) {
96
97
  const subtopicRelativePath = subtopicFile.replace(topicPath, '').replace(/^\//, '');
97
98
  const subtopicParts = subtopicRelativePath.split('/');
98
99
  // Check if this is a subtopic context.md (not the topic's own context.md)
99
- if (subtopicParts.length <= 1 || subtopicParts.at(-1) !== 'context.md') {
100
+ if (subtopicParts.length <= 1 || subtopicParts.at(-1) !== CONTEXT_FILE) {
100
101
  return null;
101
102
  }
102
103
  const subtopicName = subtopicParts[0];
@@ -106,7 +107,7 @@ async function processSubtopicFile(params) {
106
107
  }
107
108
  const subtopicEntry = {
108
109
  name: subtopicName,
109
- path: `${domainName}/${topicName}/${subtopicName}`,
110
+ path: `${BRV_DIR}/${CONTEXT_TREE_DIR}/${domainName}/${topicName}/${subtopicName}/${CONTEXT_FILE}` // Full path
110
111
  };
111
112
  // Include subtopic content preview if requested
112
113
  if (includeContent) {
@@ -210,7 +211,7 @@ async function fetchRelatedTopics(params) {
210
211
  if (parts.length < 2 || parts.length > 3)
211
212
  continue;
212
213
  const [domainName, topicName] = parts;
213
- const contextPath = join(basePath, ...parts, 'context.md');
214
+ const contextPath = join(basePath, ...parts, CONTEXT_FILE);
214
215
  try {
215
216
  // eslint-disable-next-line no-await-in-loop
216
217
  const fileExists = await DirectoryManager.fileExists(contextPath);
@@ -218,7 +219,7 @@ async function fetchRelatedTopics(params) {
218
219
  continue;
219
220
  const entry = {
220
221
  domain: domainName,
221
- path: relationPath,
222
+ path: `${basePath}/${relationPath}/${CONTEXT_FILE}`,
222
223
  topic: topicName,
223
224
  };
224
225
  // Include content preview if requested
@@ -281,8 +282,10 @@ async function executeFindKnowledgeTopics(input, _context) {
281
282
  const isSubtopic = rest.length > 1; // Has subtopic folder
282
283
  // Skip if not a context.md file (only process context files)
283
284
  const fileName = parts.at(-1);
284
- if (fileName !== 'context.md')
285
+ if (fileName !== CONTEXT_FILE)
285
286
  continue;
287
+ if (parts.length === 2)
288
+ continue; // Skip domain context.md files because they don't have much info
286
289
  // Handle subtopic pattern filtering (case-insensitive)
287
290
  if (isSubtopic) {
288
291
  const subtopicName = rest[0];
@@ -309,7 +312,7 @@ async function executeFindKnowledgeTopics(input, _context) {
309
312
  // Build result entry for this topic
310
313
  const entry = {
311
314
  domain: domainName,
312
- path: `${domainName}/${topicName}`,
315
+ path: `${basePath}/${domainName}/${topicName}/${CONTEXT_FILE}`,
313
316
  topic: topicName,
314
317
  };
315
318
  // Include content preview if requested
@@ -413,7 +416,7 @@ This tool helps discover what knowledge has been stored and navigate the domain/
413
416
 
414
417
  **Returns:**
415
418
  - total: Total number of matching topics (before relation traversal)
416
- - results: Array of topic entries with domain, topic name, path, optional relations, subtopics, and content`,
419
+ - results: Array of topic entries with domain, topic name, optional relations, subtopics, and content with complete paths`,
417
420
  execute: executeFindKnowledgeTopics,
418
421
  id: ToolName.FIND_KNOWLEDGE_TOPICS,
419
422
  inputSchema: FindKnowledgeTopicsInputSchema,
@@ -21,6 +21,10 @@ import { type ToolExecutionResult } from '../../../core/domain/cipher/tools/tool
21
21
  * Without a scheduler, tools execute directly via the provider.
22
22
  */
23
23
  export declare class ToolManager {
24
+ /**
25
+ * Tools allowed for curate operations
26
+ */
27
+ private static readonly CURATE_TOOL_NAMES;
24
28
  /**
25
29
  * Read-only tools allowed for query operations
26
30
  */
@@ -83,9 +87,10 @@ export declare class ToolManager {
83
87
  /**
84
88
  * Get filtered tool names based on command type.
85
89
  * For 'query' command, returns only read-only discovery tools.
90
+ * For 'curate' command, returns only curate-specific tools.
86
91
  * For other commands, returns all tools.
87
92
  *
88
- * @param commandType - The command type ('add', 'query', etc.)
93
+ * @param commandType - The command type ('curate', 'query', etc.)
89
94
  * @returns Array of filtered tool names
90
95
  */
91
96
  getToolNamesForCommand(commandType?: string): string[];
@@ -99,9 +104,10 @@ export declare class ToolManager {
99
104
  /**
100
105
  * Get filtered tools based on command type.
101
106
  * For 'query' command, returns only read-only discovery tools.
107
+ * For 'curate' command, returns only curate-specific tools.
102
108
  * For other commands, returns all tools.
103
109
  *
104
- * @param commandType - The command type ('add', 'query', etc.)
110
+ * @param commandType - The command type ('curate', 'query', etc.)
105
111
  * @returns Filtered tool set with JSON Schema definitions
106
112
  */
107
113
  getToolsForCommand(commandType?: string): ToolSet;
@@ -17,6 +17,17 @@ import { ToolError, ToolErrorType, ToolErrorUtils } from '../../../core/domain/c
17
17
  * Without a scheduler, tools execute directly via the provider.
18
18
  */
19
19
  export class ToolManager {
20
+ /**
21
+ * Tools allowed for curate operations
22
+ */
23
+ static CURATE_TOOL_NAMES = [
24
+ 'detect_domains',
25
+ 'find_knowledge_topics',
26
+ 'read_file',
27
+ 'grep_content',
28
+ 'glob_files',
29
+ 'curate',
30
+ ];
20
31
  /**
21
32
  * Read-only tools allowed for query operations
22
33
  */
@@ -124,9 +135,10 @@ export class ToolManager {
124
135
  /**
125
136
  * Get filtered tool names based on command type.
126
137
  * For 'query' command, returns only read-only discovery tools.
138
+ * For 'curate' command, returns only curate-specific tools.
127
139
  * For other commands, returns all tools.
128
140
  *
129
- * @param commandType - The command type ('add', 'query', etc.)
141
+ * @param commandType - The command type ('curate', 'query', etc.)
130
142
  * @returns Array of filtered tool names
131
143
  */
132
144
  getToolNamesForCommand(commandType) {
@@ -134,6 +146,10 @@ export class ToolManager {
134
146
  // For query: only allow read-only tools
135
147
  return [...ToolManager.QUERY_TOOL_NAMES].filter((name) => this.hasTool(name));
136
148
  }
149
+ if (commandType === 'curate') {
150
+ // For curate: only allow curate tools
151
+ return [...ToolManager.CURATE_TOOL_NAMES].filter((name) => this.hasTool(name));
152
+ }
137
153
  // For all other commands: return all tools
138
154
  return this.getToolNames();
139
155
  }
@@ -149,9 +165,10 @@ export class ToolManager {
149
165
  /**
150
166
  * Get filtered tools based on command type.
151
167
  * For 'query' command, returns only read-only discovery tools.
168
+ * For 'curate' command, returns only curate-specific tools.
152
169
  * For other commands, returns all tools.
153
170
  *
154
- * @param commandType - The command type ('add', 'query', etc.)
171
+ * @param commandType - The command type ('curate', 'query', etc.)
155
172
  * @returns Filtered tool set with JSON Schema definitions
156
173
  */
157
174
  getToolsForCommand(commandType) {
@@ -166,6 +183,16 @@ export class ToolManager {
166
183
  }
167
184
  return filteredTools;
168
185
  }
186
+ if (commandType === 'curate') {
187
+ // For curate: only allow curate tools
188
+ const filteredTools = {};
189
+ for (const toolName of ToolManager.CURATE_TOOL_NAMES) {
190
+ if (allTools[toolName]) {
191
+ filteredTools[toolName] = allTools[toolName];
192
+ }
193
+ }
194
+ return filteredTools;
195
+ }
169
196
  // For all other commands: return all tools
170
197
  return allTools;
171
198
  }
@@ -2,6 +2,7 @@ import { ToolName } from '../../../core/domain/cipher/tools/constants.js';
2
2
  import { createBashExecTool } from './implementations/bash-exec-tool.js';
3
3
  import { createBashOutputTool } from './implementations/bash-output-tool.js';
4
4
  import { createCreateKnowledgeTopicTool } from './implementations/create-knowledge-topic-tool.js';
5
+ import { createCurateTool } from './implementations/curate-tool.js';
5
6
  import { createDeleteMemoryTool } from './implementations/delete-memory-tool.js';
6
7
  import { createDetectDomainsTool } from './implementations/detect-domains-tool.js';
7
8
  import { createEditFileTool } from './implementations/edit-file-tool.js';
@@ -59,6 +60,12 @@ export const TOOL_REGISTRY = {
59
60
  outputGuidance: 'create_knowledge_topic',
60
61
  requiredServices: [], // Uses DirectoryManager for file operations
61
62
  },
63
+ [ToolName.CURATE]: {
64
+ factory: () => createCurateTool(),
65
+ markers: [ToolMarker.ContextBuilding, ToolMarker.Modification],
66
+ outputGuidance: 'curate',
67
+ requiredServices: [], // Uses DirectoryManager and MarkdownWriter for file operations
68
+ },
62
69
  [ToolName.DELETE_MEMORY]: {
63
70
  factory: (services) => createDeleteMemoryTool(getRequiredService(services.memoryManager, 'memoryManager')),
64
71
  markers: [ToolMarker.ContextBuilding],
@@ -43,4 +43,25 @@ export declare class AuthenticatedHttpClient implements IHttpClient {
43
43
  * Preserves error information while abstracting axios-specific details.
44
44
  */
45
45
  private handleError;
46
+ /**
47
+ * Type guard to check if error is an axios error with response.
48
+ */
49
+ private isLLMServerError;
50
+ /**
51
+ * Parse HTTP error to extract user-friendly error message.
52
+ *
53
+ * Handles standardized API error responses from the server:
54
+ * ```json
55
+ * {
56
+ * "statusCode": 401,
57
+ * "code": "AUTH_INVALID_TOKEN",
58
+ * "message": "Your authentication token is invalid. Please login again.",
59
+ * "timestamp": "2024-01-01T00:00:00.000Z"
60
+ * }
61
+ * ```
62
+ *
63
+ * @param error - HTTP error object (may contain response data)
64
+ * @returns User-friendly error message
65
+ */
66
+ private parseHttpError;
46
67
  }
@@ -76,6 +76,10 @@ export class AuthenticatedHttpClient {
76
76
  * Preserves error information while abstracting axios-specific details.
77
77
  */
78
78
  handleError(error) {
79
+ if (this.isLLMServerError(error)) {
80
+ // Extract standardized API error message
81
+ return new Error(this.parseHttpError(error));
82
+ }
79
83
  if (isAxiosError(error)) {
80
84
  if (error.response) {
81
85
  // Server responded with error status
@@ -96,4 +100,38 @@ export class AuthenticatedHttpClient {
96
100
  }
97
101
  return new Error('Unknown error occurred');
98
102
  }
103
+ /**
104
+ * Type guard to check if error is an axios error with response.
105
+ */
106
+ isLLMServerError(error) {
107
+ return (typeof error === 'object' &&
108
+ error !== null &&
109
+ 'response' in error &&
110
+ typeof error.response === 'object');
111
+ }
112
+ /**
113
+ * Parse HTTP error to extract user-friendly error message.
114
+ *
115
+ * Handles standardized API error responses from the server:
116
+ * ```json
117
+ * {
118
+ * "statusCode": 401,
119
+ * "code": "AUTH_INVALID_TOKEN",
120
+ * "message": "Your authentication token is invalid. Please login again.",
121
+ * "timestamp": "2024-01-01T00:00:00.000Z"
122
+ * }
123
+ * ```
124
+ *
125
+ * @param error - HTTP error object (may contain response data)
126
+ * @returns User-friendly error message
127
+ */
128
+ parseHttpError(error) {
129
+ const responseData = error.response.data;
130
+ // If server returned standardized API error format, use the message
131
+ if ('message' in responseData && typeof responseData.message === 'string') {
132
+ return responseData.message;
133
+ }
134
+ // Fallback to HTTP status error
135
+ return `HTTP ${error.response.status}: ${error.response.statusText}`;
136
+ }
99
137
  }