byterover-cli 0.3.5 → 0.4.1

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 (345) 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 +8 -1
  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/welcome.js +10 -26
  80. package/dist/infra/cipher/agent-service-factory.d.ts +13 -6
  81. package/dist/infra/cipher/agent-service-factory.js +40 -16
  82. package/dist/infra/cipher/cipher-agent.js +4 -4
  83. package/dist/infra/cipher/consumer/consumer-lock.d.ts +20 -0
  84. package/dist/infra/cipher/consumer/consumer-lock.js +40 -0
  85. package/dist/infra/cipher/consumer/consumer-service.d.ts +99 -0
  86. package/dist/infra/cipher/consumer/consumer-service.js +165 -0
  87. package/dist/infra/cipher/consumer/execution-consumer.d.ts +121 -0
  88. package/dist/infra/cipher/consumer/execution-consumer.js +523 -0
  89. package/dist/infra/cipher/consumer/index.d.ts +33 -0
  90. package/dist/infra/cipher/consumer/index.js +33 -0
  91. package/dist/infra/cipher/consumer/queue-polling-service.d.ts +120 -0
  92. package/dist/infra/cipher/consumer/queue-polling-service.js +248 -0
  93. package/dist/infra/cipher/http/internal-llm-http-service.d.ts +94 -0
  94. package/dist/infra/cipher/http/internal-llm-http-service.js +118 -0
  95. package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +106 -0
  96. package/dist/infra/cipher/llm/context/compaction/compaction-service.js +132 -0
  97. package/dist/infra/cipher/llm/context/compaction/index.d.ts +9 -0
  98. package/dist/infra/cipher/llm/context/compaction/index.js +9 -0
  99. package/dist/infra/cipher/llm/context/context-manager.d.ts +46 -2
  100. package/dist/infra/cipher/llm/context/context-manager.js +68 -4
  101. package/dist/infra/cipher/llm/context/rw-lock.d.ts +72 -0
  102. package/dist/infra/cipher/llm/context/rw-lock.js +145 -0
  103. package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +7 -7
  104. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +8 -8
  105. package/dist/infra/cipher/llm/internal-llm-service.js +2 -0
  106. package/dist/infra/cipher/session/session-manager.d.ts +4 -4
  107. package/dist/infra/cipher/session/session-manager.js +5 -5
  108. package/dist/infra/cipher/storage/agent-storage.d.ts +246 -0
  109. package/dist/infra/cipher/storage/agent-storage.js +956 -0
  110. package/dist/infra/cipher/storage/dual-format-history-storage.d.ts +77 -0
  111. package/dist/infra/cipher/storage/dual-format-history-storage.js +149 -0
  112. package/dist/infra/cipher/storage/granular-history-storage.d.ts +65 -0
  113. package/dist/infra/cipher/storage/granular-history-storage.js +118 -0
  114. package/dist/infra/cipher/storage/message-storage-service.d.ts +108 -0
  115. package/dist/infra/cipher/storage/message-storage-service.js +529 -0
  116. package/dist/infra/cipher/storage/process-utils.d.ts +16 -0
  117. package/dist/infra/cipher/storage/process-utils.js +43 -0
  118. package/dist/infra/cipher/storage/sqlite-key-storage.d.ts +105 -0
  119. package/dist/infra/cipher/storage/sqlite-key-storage.js +404 -0
  120. package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +1 -0
  121. package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +7 -0
  122. package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
  123. package/dist/infra/cipher/tools/implementations/curate-tool.d.ts +10 -0
  124. package/dist/infra/cipher/tools/implementations/curate-tool.js +371 -0
  125. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +11 -8
  126. package/dist/infra/cipher/tools/tool-manager.d.ts +8 -2
  127. package/dist/infra/cipher/tools/tool-manager.js +29 -2
  128. package/dist/infra/cipher/tools/tool-registry.js +7 -0
  129. package/dist/infra/http/authenticated-http-client.d.ts +21 -0
  130. package/dist/infra/http/authenticated-http-client.js +38 -0
  131. package/dist/infra/repl/commands/arg-parser.d.ts +97 -0
  132. package/dist/infra/repl/commands/arg-parser.js +129 -0
  133. package/dist/infra/repl/commands/clear-command.d.ts +5 -0
  134. package/dist/infra/repl/commands/clear-command.js +61 -0
  135. package/dist/infra/repl/commands/curate-command.d.ts +9 -0
  136. package/dist/infra/repl/commands/curate-command.js +88 -0
  137. package/dist/infra/repl/commands/gen-rules-command.d.ts +7 -0
  138. package/dist/infra/repl/commands/gen-rules-command.js +38 -0
  139. package/dist/infra/repl/commands/index.d.ts +8 -0
  140. package/dist/infra/repl/commands/index.js +36 -0
  141. package/dist/infra/repl/commands/init-command.d.ts +7 -0
  142. package/dist/infra/repl/commands/init-command.js +83 -0
  143. package/dist/infra/repl/commands/login-command.d.ts +7 -0
  144. package/dist/infra/repl/commands/login-command.js +50 -0
  145. package/dist/infra/repl/commands/logout-command.d.ts +5 -0
  146. package/dist/infra/repl/commands/logout-command.js +48 -0
  147. package/dist/infra/repl/commands/pull-command.d.ts +5 -0
  148. package/dist/infra/repl/commands/pull-command.js +61 -0
  149. package/dist/infra/repl/commands/push-command.d.ts +5 -0
  150. package/dist/infra/repl/commands/push-command.js +66 -0
  151. package/dist/infra/repl/commands/query-command.d.ts +5 -0
  152. package/dist/infra/repl/commands/query-command.js +66 -0
  153. package/dist/infra/repl/commands/space/index.d.ts +5 -0
  154. package/dist/infra/repl/commands/space/index.js +14 -0
  155. package/dist/infra/repl/commands/space/list-command.d.ts +5 -0
  156. package/dist/infra/repl/commands/space/list-command.js +70 -0
  157. package/dist/infra/repl/commands/space/switch-command.d.ts +5 -0
  158. package/dist/infra/repl/commands/space/switch-command.js +37 -0
  159. package/dist/infra/repl/commands/status-command.d.ts +5 -0
  160. package/dist/infra/repl/commands/status-command.js +39 -0
  161. package/dist/infra/repl/repl-startup.d.ts +18 -0
  162. package/dist/infra/repl/repl-startup.js +28 -0
  163. package/dist/infra/storage/file-global-config-store.d.ts +22 -0
  164. package/dist/infra/storage/file-global-config-store.js +65 -0
  165. package/dist/infra/storage/file-onboarding-preference-store.d.ts +10 -0
  166. package/dist/infra/storage/file-onboarding-preference-store.js +46 -0
  167. package/dist/infra/terminal/oclif-terminal.d.ts +19 -0
  168. package/dist/infra/terminal/oclif-terminal.js +60 -0
  169. package/dist/infra/terminal/repl-terminal.d.ts +31 -0
  170. package/dist/infra/terminal/repl-terminal.js +116 -0
  171. package/dist/infra/tracking/mixpanel-tracking-service.d.ts +11 -1
  172. package/dist/infra/tracking/mixpanel-tracking-service.js +18 -13
  173. package/dist/infra/usecase/clear-use-case.d.ts +20 -0
  174. package/dist/infra/usecase/clear-use-case.js +58 -0
  175. package/dist/infra/usecase/curate-use-case.d.ts +66 -0
  176. package/dist/infra/usecase/curate-use-case.js +288 -0
  177. package/dist/{commands/gen-rules.d.ts → infra/usecase/generate-rules-use-case.d.ts} +14 -20
  178. package/dist/{commands/gen-rules.js → infra/usecase/generate-rules-use-case.js} +59 -78
  179. package/dist/infra/usecase/init-use-case.d.ts +139 -0
  180. package/dist/{commands/init.js → infra/usecase/init-use-case.js} +197 -233
  181. package/dist/infra/usecase/login-use-case.d.ts +28 -0
  182. package/dist/infra/usecase/login-use-case.js +94 -0
  183. package/dist/infra/usecase/logout-use-case.d.ts +22 -0
  184. package/dist/infra/usecase/logout-use-case.js +51 -0
  185. package/dist/infra/usecase/pull-use-case.d.ts +35 -0
  186. package/dist/infra/usecase/pull-use-case.js +89 -0
  187. package/dist/infra/usecase/push-use-case.d.ts +37 -0
  188. package/dist/infra/usecase/push-use-case.js +124 -0
  189. package/dist/infra/usecase/query-use-case.d.ts +78 -0
  190. package/dist/infra/usecase/query-use-case.js +402 -0
  191. package/dist/infra/usecase/space-list-use-case.d.ts +27 -0
  192. package/dist/infra/usecase/space-list-use-case.js +64 -0
  193. package/dist/infra/usecase/space-switch-use-case.d.ts +36 -0
  194. package/dist/infra/usecase/space-switch-use-case.js +140 -0
  195. package/dist/infra/usecase/status-use-case.d.ts +27 -0
  196. package/dist/infra/usecase/status-use-case.js +97 -0
  197. package/dist/infra/workspace/workspace-detector-service.d.ts +3 -6
  198. package/dist/resources/prompts/curate-context-tree-curation.yml +23 -11
  199. package/dist/resources/prompts/query-context-tree-retrieval.yml +3 -4
  200. package/dist/resources/prompts/system-prompt.yml +1 -1
  201. package/dist/resources/prompts/tool-outputs.yml +4 -3
  202. package/dist/templates/sections/command-reference.md +12 -0
  203. package/dist/templates/sections/workflow.md +10 -1
  204. package/dist/tui/app.d.ts +9 -0
  205. package/dist/tui/app.js +26 -0
  206. package/dist/tui/components/enter-prompt.d.ts +13 -0
  207. package/dist/tui/components/enter-prompt.js +15 -0
  208. package/dist/tui/components/execution/execution-changes.d.ts +14 -0
  209. package/dist/tui/components/execution/execution-changes.js +15 -0
  210. package/dist/tui/components/execution/execution-content.d.ts +25 -0
  211. package/dist/tui/components/execution/execution-content.js +67 -0
  212. package/dist/tui/components/execution/execution-input.d.ts +12 -0
  213. package/dist/tui/components/execution/execution-input.js +16 -0
  214. package/dist/tui/components/execution/execution-progress.d.ts +21 -0
  215. package/dist/tui/components/execution/execution-progress.js +21 -0
  216. package/dist/tui/components/execution/execution-status.d.ts +13 -0
  217. package/dist/tui/components/execution/execution-status.js +19 -0
  218. package/dist/tui/components/execution/index.d.ts +11 -0
  219. package/dist/tui/components/execution/index.js +11 -0
  220. package/dist/tui/components/execution/log-item.d.ts +17 -0
  221. package/dist/tui/components/execution/log-item.js +25 -0
  222. package/dist/tui/components/footer.d.ts +5 -0
  223. package/dist/tui/components/footer.js +12 -0
  224. package/dist/tui/components/header.d.ts +18 -0
  225. package/dist/tui/components/header.js +18 -0
  226. package/dist/tui/components/index.d.ts +17 -0
  227. package/dist/tui/components/index.js +14 -0
  228. package/dist/tui/components/inline-prompts/index.d.ts +15 -0
  229. package/dist/tui/components/inline-prompts/index.js +10 -0
  230. package/dist/tui/components/inline-prompts/inline-confirm.d.ts +17 -0
  231. package/dist/tui/components/inline-prompts/inline-confirm.js +32 -0
  232. package/dist/tui/components/inline-prompts/inline-file-selector.d.ts +43 -0
  233. package/dist/tui/components/inline-prompts/inline-file-selector.js +185 -0
  234. package/dist/tui/components/inline-prompts/inline-input.d.ts +19 -0
  235. package/dist/tui/components/inline-prompts/inline-input.js +32 -0
  236. package/dist/tui/components/inline-prompts/inline-search.d.ts +20 -0
  237. package/dist/tui/components/inline-prompts/inline-search.js +50 -0
  238. package/dist/tui/components/inline-prompts/inline-select.d.ts +20 -0
  239. package/dist/tui/components/inline-prompts/inline-select.js +34 -0
  240. package/dist/tui/components/logo.d.ts +43 -0
  241. package/dist/tui/components/logo.js +103 -0
  242. package/dist/tui/components/message-item.d.ts +12 -0
  243. package/dist/tui/components/message-item.js +12 -0
  244. package/dist/tui/components/onboarding/copyable-prompt.d.ts +15 -0
  245. package/dist/tui/components/onboarding/copyable-prompt.js +65 -0
  246. package/dist/tui/components/onboarding/index.d.ts +7 -0
  247. package/dist/tui/components/onboarding/index.js +6 -0
  248. package/dist/tui/components/onboarding/onboarding-flow.d.ts +13 -0
  249. package/dist/tui/components/onboarding/onboarding-flow.js +304 -0
  250. package/dist/tui/components/onboarding/onboarding-step.d.ts +23 -0
  251. package/dist/tui/components/onboarding/onboarding-step.js +12 -0
  252. package/dist/tui/components/output-log.d.ts +14 -0
  253. package/dist/tui/components/output-log.js +13 -0
  254. package/dist/tui/components/scrollable-list.d.ts +30 -0
  255. package/dist/tui/components/scrollable-list.js +121 -0
  256. package/dist/tui/components/suggestions.d.ts +16 -0
  257. package/dist/tui/components/suggestions.js +162 -0
  258. package/dist/tui/components/tab-bar.d.ts +10 -0
  259. package/dist/tui/components/tab-bar.js +12 -0
  260. package/dist/tui/constants.d.ts +11 -0
  261. package/dist/tui/constants.js +13 -0
  262. package/dist/tui/contexts/auth-context.d.ts +30 -0
  263. package/dist/tui/contexts/auth-context.js +153 -0
  264. package/dist/tui/contexts/consumer.d.ts +31 -0
  265. package/dist/tui/contexts/consumer.js +56 -0
  266. package/dist/tui/contexts/index.d.ts +6 -0
  267. package/dist/tui/contexts/index.js +6 -0
  268. package/dist/tui/contexts/onboarding-context.d.ts +43 -0
  269. package/dist/tui/contexts/onboarding-context.js +181 -0
  270. package/dist/tui/contexts/services-context.d.ts +29 -0
  271. package/dist/tui/contexts/services-context.js +20 -0
  272. package/dist/tui/contexts/use-commands.d.ts +29 -0
  273. package/dist/tui/contexts/use-commands.js +54 -0
  274. package/dist/tui/contexts/use-mode.d.ts +43 -0
  275. package/dist/tui/contexts/use-mode.js +76 -0
  276. package/dist/tui/contexts/use-theme.d.ts +53 -0
  277. package/dist/tui/contexts/use-theme.js +60 -0
  278. package/dist/tui/hooks/index.d.ts +17 -0
  279. package/dist/tui/hooks/index.js +14 -0
  280. package/dist/tui/hooks/use-activity-logs.d.ts +26 -0
  281. package/dist/tui/hooks/use-activity-logs.js +90 -0
  282. package/dist/tui/hooks/use-consumer.d.ts +12 -0
  283. package/dist/tui/hooks/use-consumer.js +50 -0
  284. package/dist/tui/hooks/use-onboarding.d.ts +7 -0
  285. package/dist/tui/hooks/use-onboarding.js +6 -0
  286. package/dist/tui/hooks/use-queue-polling.d.ts +31 -0
  287. package/dist/tui/hooks/use-queue-polling.js +90 -0
  288. package/dist/tui/hooks/use-slash-command-processor.d.ts +16 -0
  289. package/dist/tui/hooks/use-slash-command-processor.js +132 -0
  290. package/dist/tui/hooks/use-slash-completion.d.ts +30 -0
  291. package/dist/tui/hooks/use-slash-completion.js +230 -0
  292. package/dist/tui/hooks/use-tab-navigation.d.ts +10 -0
  293. package/dist/tui/hooks/use-tab-navigation.js +35 -0
  294. package/dist/tui/hooks/use-visible-window.d.ts +22 -0
  295. package/dist/tui/hooks/use-visible-window.js +37 -0
  296. package/dist/tui/index.d.ts +1 -0
  297. package/dist/tui/index.js +1 -0
  298. package/dist/tui/providers/app-providers.d.ts +25 -0
  299. package/dist/tui/providers/app-providers.js +9 -0
  300. package/dist/tui/types/commands.d.ts +252 -0
  301. package/dist/tui/types/commands.js +16 -0
  302. package/dist/tui/types/dialogs.d.ts +37 -0
  303. package/dist/tui/types/dialogs.js +4 -0
  304. package/dist/tui/types/index.d.ts +11 -0
  305. package/dist/tui/types/index.js +7 -0
  306. package/dist/tui/types/messages.d.ts +55 -0
  307. package/dist/tui/types/messages.js +4 -0
  308. package/dist/tui/types/prompts.d.ts +100 -0
  309. package/dist/tui/types/prompts.js +4 -0
  310. package/dist/tui/types/ui.d.ts +14 -0
  311. package/dist/tui/types/ui.js +4 -0
  312. package/dist/tui/types.d.ts +1 -0
  313. package/dist/tui/types.js +1 -0
  314. package/dist/tui/views/command-view.d.ts +12 -0
  315. package/dist/tui/views/command-view.js +451 -0
  316. package/dist/tui/views/index.d.ts +6 -0
  317. package/dist/tui/views/index.js +6 -0
  318. package/dist/tui/views/login-view.d.ts +10 -0
  319. package/dist/tui/views/login-view.js +30 -0
  320. package/dist/tui/views/logs-view.d.ts +11 -0
  321. package/dist/tui/views/logs-view.js +73 -0
  322. package/dist/utils/file-validator.d.ts +16 -0
  323. package/dist/utils/file-validator.js +81 -0
  324. package/dist/utils/global-config-path.d.ts +15 -0
  325. package/dist/utils/global-config-path.js +38 -0
  326. package/oclif.manifest.json +29 -315
  327. package/package.json +11 -4
  328. package/dist/commands/clear.d.ts +0 -19
  329. package/dist/commands/clear.js +0 -78
  330. package/dist/commands/init.d.ts +0 -130
  331. package/dist/commands/login.d.ts +0 -22
  332. package/dist/commands/login.js +0 -108
  333. package/dist/commands/logout.d.ts +0 -16
  334. package/dist/commands/logout.js +0 -61
  335. package/dist/commands/pull.d.ts +0 -33
  336. package/dist/commands/pull.js +0 -115
  337. package/dist/commands/push.d.ts +0 -35
  338. package/dist/commands/push.js +0 -160
  339. package/dist/commands/space/list.d.ts +0 -25
  340. package/dist/commands/space/list.js +0 -114
  341. package/dist/commands/space/switch.d.ts +0 -36
  342. package/dist/commands/space/switch.js +0 -160
  343. package/dist/infra/cipher/grpc/internal-llm-grpc-service.d.ts +0 -149
  344. package/dist/infra/cipher/grpc/internal-llm-grpc-service.js +0 -364
  345. package/dist/infra/cipher/grpc/internal-llm-grpc.proto +0 -94
@@ -1,5 +1,6 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import type { IProjectConfigStore } from '../../core/interfaces/i-project-config-store.js';
3
+ import type { ITerminal } from '../../core/interfaces/i-terminal.js';
3
4
  export default class CipherAgentSetPrompt extends Command {
4
5
  static args: {
5
6
  prompt: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
@@ -7,6 +8,7 @@ export default class CipherAgentSetPrompt extends Command {
7
8
  static description: string;
8
9
  static examples: string[];
9
10
  static hidden: boolean;
11
+ protected terminal: ITerminal;
10
12
  protected createServices(): {
11
13
  projectConfigStore: IProjectConfigStore;
12
14
  };
@@ -2,6 +2,7 @@ import { Args, Command } from '@oclif/core';
2
2
  import { isDevelopment } from '../../config/environment.js';
3
3
  import { BrvConfig } from '../../core/domain/entities/brv-config.js';
4
4
  import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
5
+ import { OclifTerminal } from '../../infra/terminal/oclif-terminal.js';
5
6
  import { getErrorMessage } from '../../utils/error-helpers.js';
6
7
  export default class CipherAgentSetPrompt extends Command {
7
8
  static args = {
@@ -13,27 +14,31 @@ export default class CipherAgentSetPrompt extends Command {
13
14
  '<%= config.bin %> <%= command.id %> "You are an expert in refactoring and code quality improvements"',
14
15
  ];
15
16
  static hidden = !isDevelopment();
17
+ terminal = {};
16
18
  createServices() {
19
+ this.terminal = new OclifTerminal(this);
17
20
  return {
18
21
  projectConfigStore: new ProjectConfigStore(),
19
22
  };
20
23
  }
21
24
  async run() {
25
+ const { projectConfigStore } = this.createServices();
22
26
  if (!isDevelopment()) {
23
- this.error('This command is only available in development environment');
27
+ this.terminal.error('This command is only available in development environment');
28
+ return;
24
29
  }
25
30
  const { args } = await this.parse(CipherAgentSetPrompt);
26
31
  try {
27
- const { projectConfigStore } = this.createServices();
28
32
  // Check if config exists
29
33
  const configExists = await projectConfigStore.exists();
30
34
  if (!configExists) {
31
- this.error('No ByteRover config found. Please run "byterover init" first to initialize the project.');
35
+ this.terminal.error('No ByteRover config found. Please run "byterover init" first to initialize the project.');
32
36
  }
33
37
  // Read existing config
34
38
  const existingConfig = await projectConfigStore.read();
35
39
  if (!existingConfig) {
36
- this.error('Failed to read existing config.');
40
+ this.terminal.error('Failed to read existing config.');
41
+ return;
37
42
  }
38
43
  // Create updated config with new system prompt
39
44
  const updatedConfig = new BrvConfig({
@@ -42,12 +47,12 @@ export default class CipherAgentSetPrompt extends Command {
42
47
  });
43
48
  // Write updated config
44
49
  await projectConfigStore.write(updatedConfig);
45
- this.log('✓ CipherAgent system prompt updated successfully!');
46
- this.log('\nNew prompt:');
47
- this.log(args.prompt);
50
+ this.terminal.log('✓ CipherAgent system prompt updated successfully!');
51
+ this.terminal.log('\nNew prompt:');
52
+ this.terminal.log(args.prompt);
48
53
  }
49
54
  catch (error) {
50
- this.error(`Failed to set system prompt: ${getErrorMessage(error)}`);
55
+ this.terminal.error(`Failed to set system prompt: ${getErrorMessage(error)}`);
51
56
  }
52
57
  }
53
58
  }
@@ -1,9 +1,11 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import type { IProjectConfigStore } from '../../core/interfaces/i-project-config-store.js';
3
+ import type { ITerminal } from '../../core/interfaces/i-terminal.js';
3
4
  export default class CipherAgentShowPrompt extends Command {
4
5
  static description: string;
5
6
  static examples: string[];
6
7
  static hidden: boolean;
8
+ protected terminal: ITerminal;
7
9
  protected createServices(): {
8
10
  projectConfigStore: IProjectConfigStore;
9
11
  };
@@ -1,48 +1,53 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import { isDevelopment } from '../../config/environment.js';
3
3
  import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
4
+ import { OclifTerminal } from '../../infra/terminal/oclif-terminal.js';
4
5
  import { getErrorMessage } from '../../utils/error-helpers.js';
5
6
  export default class CipherAgentShowPrompt extends Command {
6
7
  static description = 'Show the current CipherAgent system prompt [Development only]';
7
8
  static examples = ['<%= config.bin %> <%= command.id %>'];
8
9
  static hidden = !isDevelopment();
10
+ terminal = {};
9
11
  createServices() {
12
+ this.terminal = new OclifTerminal(this);
10
13
  return {
11
14
  projectConfigStore: new ProjectConfigStore(),
12
15
  };
13
16
  }
14
17
  async run() {
18
+ const { projectConfigStore } = this.createServices();
15
19
  if (!isDevelopment()) {
16
- this.error('This command is only available in development environment');
20
+ this.terminal.error('This command is only available in development environment');
21
+ return;
17
22
  }
18
23
  try {
19
- const { projectConfigStore } = this.createServices();
20
24
  // Check if config exists
21
25
  const configExists = await projectConfigStore.exists();
22
26
  if (!configExists) {
23
- this.log('No ByteRover config found.');
24
- this.log('CipherAgent will use the default system prompt.');
27
+ this.terminal.log('No ByteRover config found.');
28
+ this.terminal.log('CipherAgent will use the default system prompt.');
25
29
  return;
26
30
  }
27
31
  // Read existing config
28
32
  const config = await projectConfigStore.read();
29
33
  if (!config) {
30
- this.error('Failed to read config.');
34
+ this.terminal.error('Failed to read config.');
35
+ return;
31
36
  }
32
37
  // Show system prompt
33
38
  if (config.cipherAgentSystemPrompt) {
34
- this.log('Current CipherAgent system prompt:');
35
- this.log('─'.repeat(60));
36
- this.log(config.cipherAgentSystemPrompt);
37
- this.log('─'.repeat(60));
39
+ this.terminal.log('Current CipherAgent system prompt:');
40
+ this.terminal.log('─'.repeat(60));
41
+ this.terminal.log(config.cipherAgentSystemPrompt);
42
+ this.terminal.log('─'.repeat(60));
38
43
  }
39
44
  else {
40
- this.log('No custom system prompt configured.');
41
- this.log('CipherAgent is using the default system prompt.');
45
+ this.terminal.log('No custom system prompt configured.');
46
+ this.terminal.log('CipherAgent is using the default system prompt.');
42
47
  }
43
48
  }
44
49
  catch (error) {
45
- this.error(`Failed to show system prompt: ${getErrorMessage(error)}`);
50
+ this.terminal.error(`Failed to show system prompt: ${getErrorMessage(error)}`);
46
51
  }
47
52
  }
48
53
  }
@@ -1,6 +1,5 @@
1
1
  import { Command } from '@oclif/core';
2
- import type { IProjectConfigStore } from '../core/interfaces/i-project-config-store.js';
3
- import type { ITrackingService } from '../core/interfaces/i-tracking-service.js';
2
+ import type { ICurateUseCase } from '../core/interfaces/usecase/i-curate-use-case.js';
4
3
  export default class Curate extends Command {
5
4
  static args: {
6
5
  context: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
@@ -11,64 +10,8 @@ export default class Curate extends Command {
11
10
  apiKey?: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions> | undefined;
12
11
  model?: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions> | undefined;
13
12
  verbose?: import("@oclif/core/interfaces").BooleanFlag<boolean> | undefined;
13
+ files: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
14
  };
15
- catch(error: Error & {
16
- oclif?: {
17
- exit: number;
18
- };
19
- }): Promise<void>;
20
- protected createServices(): {
21
- projectConfigStore: IProjectConfigStore;
22
- trackingService: ITrackingService;
23
- };
24
- /**
25
- * Create topic folder with context.md file
26
- * @param targetPath - The parent path where the topic folder will be created
27
- * @param topicName - The name of the topic folder to create
28
- * @returns The path to the created context.md file
29
- */
30
- protected createTopicWithContextFile(targetPath: string, topicName: string): string;
31
- /**
32
- * Generate a unique session ID for the autonomous agent.
33
- * Uses crypto.randomUUID() for guaranteed uniqueness (122 bits of entropy).
34
- */
35
- protected generateSessionId(): string;
36
- /**
37
- * Navigate through the context tree using file selector
38
- * Returns the selected path relative to context-tree root
39
- */
40
- protected navigateContextTree(): Promise<null | string>;
41
- /**
42
- * Open a file in the default editor
43
- * @param filePath - The path to the file to open
44
- */
45
- protected openFile(filePath: string): Promise<void>;
46
- /**
47
- * Prompt user to enter topic name with validation
48
- * @param targetPath - The path where the topic folder will be created
49
- * @returns The topic name or null if cancelled
50
- */
51
- protected promptForTopicName(targetPath: string): Promise<null | string>;
15
+ protected createUseCase(): ICurateUseCase;
52
16
  run(): Promise<void>;
53
- /**
54
- * Write content to context tree at given path
55
- */
56
- protected writeToContextTree(selectedPath: string, content: string): Promise<void>;
57
- /**
58
- * Handle workspace not initialized error
59
- */
60
- private handleWorkspaceError;
61
- /**
62
- * Run in autonomous mode using CipherAgent
63
- */
64
- private runAutonomous;
65
- /**
66
- * Run in interactive mode with manual prompts
67
- */
68
- private runInteractive;
69
- /**
70
- * Setup event listeners for CipherAgent
71
- */
72
- private setupEventListeners;
73
- private validateTopicName;
74
17
  }
@@ -1,45 +1,43 @@
1
- import { input } from '@inquirer/prompts';
2
1
  import { Args, Command, Flags } from '@oclif/core';
3
- import chalk from 'chalk';
4
- import { fileSelector, ItemType } from 'inquirer-file-selector';
5
- import { randomUUID } from 'node:crypto';
6
- import fs from 'node:fs';
7
- import path from 'node:path';
8
- import open from 'open';
9
- import { CONTEXT_TREE_DOMAINS } from '../config/context-tree-domains.js';
10
- import { getCurrentConfig, isDevelopment } from '../config/environment.js';
11
- import { BRV_DIR, CONTEXT_FILE, CONTEXT_TREE_DIR, PROJECT } from '../constants.js';
12
- import { CipherAgent } from '../infra/cipher/cipher-agent.js';
13
- import { ExitCode, ExitError, exitWithCode } from '../infra/cipher/exit-codes.js';
14
- import { WorkspaceNotInitializedError } from '../infra/cipher/validation/workspace-validator.js';
2
+ import { isDevelopment } from '../config/environment.js';
15
3
  import { ProjectConfigStore } from '../infra/config/file-config-store.js';
4
+ import { FileGlobalConfigStore } from '../infra/storage/file-global-config-store.js';
16
5
  import { KeychainTokenStore } from '../infra/storage/keychain-token-store.js';
6
+ import { OclifTerminal } from '../infra/terminal/oclif-terminal.js';
17
7
  import { MixpanelTrackingService } from '../infra/tracking/mixpanel-tracking-service.js';
18
- import { addErrorPrefix } from '../utils/emoji-helpers.js';
19
- import { formatToolCall, formatToolResult } from '../utils/tool-display-formatter.js';
20
- // Full path to context tree
21
- const CONTEXT_TREE_PATH = path.join(BRV_DIR, CONTEXT_TREE_DIR);
8
+ import { CurateUseCase } from '../infra/usecase/curate-use-case.js';
22
9
  export default class Curate extends Command {
23
10
  static args = {
24
11
  context: Args.string({
25
- description: 'Knowledge context: patterns, decisions, errors, or insights (triggers autonomous mode)',
12
+ description: 'Knowledge context: patterns, decisions, errors, or insights',
26
13
  required: false,
27
14
  }),
28
15
  };
29
- static description = `Curate context to the context tree (interactive or autonomous mode)
30
- Good:
16
+ static description = `Curate context to the context tree (autonomous mode)
17
+
18
+ For interactive mode, use REPL: brv repl then /curate
19
+
20
+ Good examples:
31
21
  - "Auth uses JWT with 24h expiry. Tokens stored in httpOnly cookies via authMiddleware.ts"
32
22
  - "API rate limit is 100 req/min per user. Implemented using Redis with sliding window in rateLimiter.ts"
33
- Bad:
23
+ Bad examples:
34
24
  - "Authentication" or "JWT tokens" (too vague, lacks context)
35
25
  - "Rate limiting" (no implementation details or file references)`;
36
26
  static examples = [
37
- '# Interactive mode (manually choose domain/topic)',
38
- '<%= config.bin %> <%= command.id %>',
39
- '',
40
27
  '# Autonomous mode - LLM auto-categorizes your context',
41
28
  '<%= config.bin %> <%= command.id %> "Auth uses JWT with 24h expiry. Tokens stored in httpOnly cookies via authMiddleware.ts"',
42
29
  '',
30
+ '# Include relevant files for comprehensive context (use sparingly, max 5 files)',
31
+ '- NOTE: CONTEXT argument must come BEFORE --files flag',
32
+ '- NOTE: For multiple files, repeat --files (or -f) flag for each file',
33
+ '- NOTE: Only text/code files from current project directory.',
34
+ '',
35
+ '## Single file',
36
+ '<%= config.bin %> <%= command.id %> "Authentication middleware validates JWT tokens and attaches user context" -f src/middleware/auth.ts',
37
+ '',
38
+ '## Multiple files',
39
+ '<%= config.bin %> <%= command.id %> "JWT authentication implementation with refresh token rotation" --files src/auth/jwt.ts --files docs/auth.md',
40
+ '',
43
41
  ...(isDevelopment()
44
42
  ? [
45
43
  '# Autonomous mode with OpenRouter (development only)',
@@ -51,6 +49,11 @@ Bad:
51
49
  : []),
52
50
  ];
53
51
  static flags = {
52
+ files: Flags.string({
53
+ char: 'f',
54
+ description: 'Include specific file paths for critical context (max 5 files). Only text/code files from the current project directory are allowed. Use sparingly - only for truly relevant files like docs or key implementation details. NOTE: CONTEXT argument must come BEFORE this flag.',
55
+ multiple: true,
56
+ }),
54
57
  ...(isDevelopment()
55
58
  ? {
56
59
  apiKey: Flags.string({
@@ -70,327 +73,28 @@ Bad:
70
73
  }
71
74
  : {}),
72
75
  };
73
- // Override catch to prevent oclif from logging errors that were already displayed
74
- async catch(error) {
75
- // Check if error is ExitError (message already displayed by exitWithCode)
76
- if (error instanceof ExitError) {
77
- return;
78
- }
79
- // Backwards compatibility: also check oclif.exit property
80
- if (error.oclif?.exit !== undefined) {
81
- return;
82
- }
83
- // For other errors, re-throw to let oclif handle them
84
- throw error;
85
- }
86
- createServices() {
87
- return {
76
+ createUseCase() {
77
+ const tokenStore = new KeychainTokenStore();
78
+ const globalConfigStore = new FileGlobalConfigStore();
79
+ return new CurateUseCase({
88
80
  projectConfigStore: new ProjectConfigStore(),
89
- trackingService: new MixpanelTrackingService(new KeychainTokenStore()),
90
- };
91
- }
92
- /**
93
- * Create topic folder with context.md file
94
- * @param targetPath - The parent path where the topic folder will be created
95
- * @param topicName - The name of the topic folder to create
96
- * @returns The path to the created context.md file
97
- */
98
- createTopicWithContextFile(targetPath, topicName) {
99
- const topicPath = path.join(targetPath, topicName);
100
- const contextFilePath = path.join(topicPath, CONTEXT_FILE);
101
- // Create the topic directory
102
- fs.mkdirSync(topicPath, { recursive: true });
103
- // Create the context.md file with initial content
104
- const initialContent = `# ${topicName}\n\n<!-- Add your context here -->\n`;
105
- fs.writeFileSync(contextFilePath, initialContent, 'utf8');
106
- return contextFilePath;
107
- }
108
- /**
109
- * Generate a unique session ID for the autonomous agent.
110
- * Uses crypto.randomUUID() for guaranteed uniqueness (122 bits of entropy).
111
- */
112
- generateSessionId() {
113
- return randomUUID();
114
- }
115
- /**
116
- * Navigate through the context tree using file selector
117
- * Returns the selected path relative to context-tree root
118
- */
119
- async navigateContextTree() {
120
- const contextTreePath = path.resolve(process.cwd(), CONTEXT_TREE_PATH);
121
- // Ensure context tree directory exists
122
- if (!fs.existsSync(contextTreePath)) {
123
- fs.mkdirSync(contextTreePath, { recursive: true });
124
- }
125
- // Ensure predefined domains exist as directories
126
- for (const domain of CONTEXT_TREE_DOMAINS) {
127
- const domainPath = path.join(contextTreePath, domain.name);
128
- if (!fs.existsSync(domainPath)) {
129
- fs.mkdirSync(domainPath, { recursive: true });
130
- }
131
- }
132
- while (true) {
133
- try {
134
- // eslint-disable-next-line no-await-in-loop
135
- const selectedItem = await fileSelector({
136
- allowCancel: true,
137
- basePath: contextTreePath,
138
- filter: (item) => item.isDirectory,
139
- message: 'Target context location:',
140
- pageSize: 15,
141
- theme: {
142
- labels: {
143
- messages: {
144
- cancel: 'Selection cancelled.',
145
- empty: 'No sub-folders. Press Enter to add content here.',
146
- },
147
- },
148
- },
149
- type: ItemType.Directory,
150
- });
151
- // User cancelled
152
- if (!selectedItem) {
153
- return null;
154
- }
155
- // Restrict navigation to stay within the context tree
156
- const normalizedItemPath = path.resolve(selectedItem.path);
157
- const isValid = normalizedItemPath.startsWith(contextTreePath);
158
- if (isValid) {
159
- // Valid selection - proceed
160
- return selectedItem.path;
161
- }
162
- // Invalid selection - retry
163
- this.log(chalk.red('Invalid selection. Please choose a valid location within the context tree.'));
164
- }
165
- catch {
166
- // Error occurred
167
- return null;
168
- }
169
- }
170
- }
171
- /**
172
- * Open a file in the default editor
173
- * @param filePath - The path to the file to open
174
- */
175
- async openFile(filePath) {
176
- await open(filePath);
177
- }
178
- /**
179
- * Prompt user to enter topic name with validation
180
- * @param targetPath - The path where the topic folder will be created
181
- * @returns The topic name or null if cancelled
182
- */
183
- async promptForTopicName(targetPath) {
184
- try {
185
- const topicName = await input({
186
- message: 'New topic name:',
187
- validate: (value) => this.validateTopicName(value, targetPath),
188
- });
189
- return topicName.trim();
190
- }
191
- catch {
192
- return null;
193
- }
81
+ terminal: new OclifTerminal(this),
82
+ tokenStore,
83
+ trackingService: new MixpanelTrackingService({ globalConfigStore, tokenStore }),
84
+ });
194
85
  }
195
86
  async run() {
196
87
  const { args, flags } = await this.parse(Curate);
197
- // Determine mode: autonomous if context is provided via args
198
- const contextInput = args.context;
199
- // Autonomous mode: use CipherAgent to process context
200
- // Interactive mode: manually prompt for domain/topic/context
201
- return contextInput ? this.runAutonomous(contextInput, flags) : this.runInteractive();
202
- }
203
- /**
204
- * Write content to context tree at given path
205
- */
206
- async writeToContextTree(selectedPath, content) {
207
- const targetPath = path.join(CONTEXT_TREE_PATH, selectedPath);
208
- const contextFilePath = path.join(targetPath, CONTEXT_FILE);
209
- // Create directories if they don't exist
210
- fs.mkdirSync(targetPath, { recursive: true });
211
- // Append or create context file
212
- const timestamp = new Date().toISOString();
213
- const entry = `\n## Added on ${timestamp}\n\n${content}\n`;
214
- const isNewFile = !fs.existsSync(contextFilePath);
215
- const title = path.basename(selectedPath); // Use last segment as title
216
- if (isNewFile) {
217
- fs.writeFileSync(contextFilePath, `# ${title}\n${entry}`, 'utf8');
218
- }
219
- else {
220
- fs.appendFileSync(contextFilePath, entry, 'utf8');
221
- }
222
- const action = isNewFile ? 'Created' : 'Updated';
223
- this.log(`\n✓ ${action}: ${contextFilePath}`);
224
- }
225
- /**
226
- * Handle workspace not initialized error
227
- */
228
- handleWorkspaceError(_error) {
229
- const message = 'Project not initialized. Please run "brv init" to select your team and workspace.';
230
- exitWithCode(ExitCode.VALIDATION_ERROR, message);
231
- }
232
- /**
233
- * Run in autonomous mode using CipherAgent
234
- */
235
- async runAutonomous(content, flags) {
236
- const { projectConfigStore, trackingService } = this.createServices();
237
- try {
238
- // Get authentication token
239
- const tokenStore = new KeychainTokenStore();
240
- const token = await tokenStore.load();
241
- if (!token) {
242
- exitWithCode(ExitCode.CONFIG_ERROR, 'Authentication required. Please run "brv login" first.');
243
- }
244
- // Load project config
245
- const brvConfig = await projectConfigStore.read();
246
- // Validate workspace is initialized
247
- if (!brvConfig) {
248
- throw new WorkspaceNotInitializedError('Project not initialized. Please run "brv init" to select your team and workspace.', '.brv');
249
- }
250
- // Create LLM config
251
- const model = flags.model ?? (flags.apiKey ? 'google/gemini-2.5-pro' : 'gemini-2.5-pro');
252
- const envConfig = getCurrentConfig();
253
- const llmConfig = {
254
- accessToken: token.accessToken,
255
- fileSystemConfig: { workingDirectory: process.cwd() },
256
- grpcEndpoint: envConfig.llmGrpcEndpoint,
257
- maxIterations: 10,
258
- maxTokens: 8192,
259
- model,
260
- openRouterApiKey: flags.apiKey,
261
- projectId: PROJECT,
262
- sessionKey: token.sessionKey,
263
- teamId: brvConfig?.teamId ?? '',
264
- temperature: 0.7,
265
- verbose: flags.verbose ?? false,
266
- };
267
- // Create and start CipherAgent
268
- const agent = new CipherAgent(llmConfig, brvConfig);
269
- this.log('Starting autonomous context tree curation...');
270
- await agent.start();
271
- try {
272
- const sessionId = this.generateSessionId();
273
- // Setup event listeners
274
- this.setupEventListeners(agent, flags.verbose ?? false);
275
- // Execute with autonomous mode and add commandType
276
- const prompt = `Add the following context to the context tree:\n\n${content}`;
277
- const response = await agent.execute(prompt, sessionId, {
278
- executionContext: { commandType: 'curate' },
279
- mode: 'autonomous',
280
- });
281
- this.log('\nCipherAgent Response:');
282
- this.log(response);
283
- await trackingService.track('mem:curate');
284
- }
285
- finally {
286
- // console.log('Logic for agent stopping and resource cleanup may go here!')
287
- }
288
- }
289
- catch (error) {
290
- if (error instanceof WorkspaceNotInitializedError) {
291
- this.handleWorkspaceError(error);
292
- return;
293
- }
294
- // Throw error to let oclif handle exit code
295
- this.error(error instanceof Error ? error.message : 'Runtime error occurred', { exit: ExitCode.RUNTIME_ERROR });
296
- }
297
- }
298
- /**
299
- * Run in interactive mode with manual prompts
300
- */
301
- async runInteractive() {
302
- const { trackingService } = this.createServices();
303
- try {
304
- // Navigate to target location in context tree
305
- const targetPath = await this.navigateContextTree();
306
- if (!targetPath) {
307
- this.log('\nOperation cancelled.');
308
- return;
309
- }
310
- // Prompt for topic name with validation
311
- const topicName = await this.promptForTopicName(targetPath);
312
- if (!topicName) {
313
- this.log('\nOperation cancelled.');
314
- return;
315
- }
316
- // Create the topic folder with context.md
317
- const contextFilePath = this.createTopicWithContextFile(targetPath, topicName);
318
- this.log(`\nCreated: ${contextFilePath}`);
319
- // Track the event
320
- trackingService.track('mem:curate');
321
- // Auto-open context.md in default editor
322
- this.log('Opening context.md for editing...');
323
- await this.openFile(contextFilePath);
324
- }
325
- catch (error) {
326
- this.error(error instanceof Error ? error.message : 'Unexpected error occurred');
327
- }
328
- }
329
- /**
330
- * Setup event listeners for CipherAgent
331
- */
332
- setupEventListeners(agent, verbose) {
333
- if (!agent.agentEventBus) {
334
- throw new Error('Agent event bus not initialized');
335
- }
336
- const eventBus = agent.agentEventBus;
337
- if (verbose) {
338
- // Verbose mode: show detailed events
339
- eventBus.on('llmservice:thinking', () => {
340
- this.log('🤔 [Event] LLM is thinking...');
341
- });
342
- eventBus.on('llmservice:response', (payload) => {
343
- this.log(`✅ [Event] LLM Response (${payload.provider}/${payload.model})`);
344
- });
345
- eventBus.on('llmservice:toolCall', (payload) => {
346
- const formattedCall = formatToolCall(payload.toolName, payload.args);
347
- this.log(`🔧 [Event] Tool Call: ${formattedCall}`);
348
- });
349
- eventBus.on('llmservice:toolResult', (payload) => {
350
- const resultSummary = formatToolResult(payload.toolName, payload.success, payload.result, payload.error);
351
- if (payload.success) {
352
- this.log(`✓ [Event] Tool Success: ${payload.toolName} → ${resultSummary}`);
353
- }
354
- else {
355
- this.log(`✗ [Event] Tool Error: ${payload.toolName} → ${resultSummary}`);
356
- }
357
- });
358
- eventBus.on('llmservice:error', (payload) => {
359
- this.log(`❌ [Event] LLM Error: ${payload.error}`);
360
- });
361
- }
362
- else {
363
- // Non-verbose mode: show concise tool progress
364
- eventBus.on('llmservice:toolCall', (payload) => {
365
- this.log(`🔧 ${payload.toolName} → Executing...`);
366
- });
367
- eventBus.on('llmservice:toolResult', (payload) => {
368
- if (payload.success) {
369
- this.log(`✅ ${payload.toolName} → Complete`);
370
- }
371
- else {
372
- this.log(`❌ ${payload.toolName} → Failed: ${payload.error ?? 'Unknown error'}`);
373
- }
374
- });
375
- eventBus.on('llmservice:error', (payload) => {
376
- this.log(addErrorPrefix(payload.error));
377
- });
378
- }
379
- }
380
- validateTopicName(value, targetPath) {
381
- const trimmed = value.trim();
382
- if (!trimmed) {
383
- return 'Topic name cannot be empty';
384
- }
385
- // Check for invalid characters in folder names (filesystem restrictions)
386
- if (/[/\0]/.test(trimmed)) {
387
- return 'Topic name cannot contain "/" or null characters';
388
- }
389
- // Check if folder already exists
390
- const topicPath = path.join(targetPath, trimmed);
391
- if (fs.existsSync(topicPath)) {
392
- return `Topic "${trimmed}" already exists at this location`;
88
+ if (!args.context) {
89
+ this.log('Context argument is required.\nFor interactive mode, use REPL: brv /curate');
90
+ return;
393
91
  }
394
- return true;
92
+ await this.createUseCase().run({
93
+ apiKey: flags.apiKey,
94
+ context: args.context,
95
+ files: flags.files,
96
+ model: flags.model,
97
+ verbose: flags.verbose,
98
+ });
395
99
  }
396
100
  }
@@ -1,9 +1,11 @@
1
1
  import { Command } from '@oclif/core';
2
- import { ICodingAgentLogWatcher } from '../core/interfaces/cipher/i-coding-agent-log-watcher.js';
3
- import { IProjectConfigStore } from '../core/interfaces/i-project-config-store.js';
2
+ import type { ICodingAgentLogWatcher } from '../core/interfaces/cipher/i-coding-agent-log-watcher.js';
3
+ import type { IProjectConfigStore } from '../core/interfaces/i-project-config-store.js';
4
+ import type { ITerminal } from '../core/interfaces/i-terminal.js';
4
5
  export default class Foo extends Command {
5
6
  static description: string;
6
7
  static hidden: boolean;
8
+ protected terminal: ITerminal;
7
9
  protected createServices(): Promise<{
8
10
  codingAgentLogWatcher: ICodingAgentLogWatcher;
9
11
  projectConfigStore: IProjectConfigStore;