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
@@ -0,0 +1,451 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Command View
4
+ *
5
+ * Main view with slash command input and streaming output support.
6
+ * Uses ScrollableList for message history with dynamic height calculation.
7
+ */
8
+ import { Box, Spacer, Text, useApp } from 'ink';
9
+ import Spinner from 'ink-spinner';
10
+ import TextInput from 'ink-text-input';
11
+ import { useCallback, useEffect, useMemo, useState } from 'react';
12
+ import { stopConsumer } from '../../infra/cipher/consumer/execution-consumer.js';
13
+ import { stopQueuePollingService } from '../../infra/cipher/consumer/queue-polling-service.js';
14
+ import { MessageItem, ScrollableList, Suggestions } from '../components/index.js';
15
+ import { InlineConfirm, InlineFileSelector, InlineInput, InlineSearch, InlineSelect, } from '../components/inline-prompts/index.js';
16
+ import { useAuth } from '../contexts/auth-context.js';
17
+ import { useConsumer } from '../contexts/index.js';
18
+ import { useCommands, useMode, useTheme } from '../hooks/index.js';
19
+ /** Fixed height for bottom area (suggestions + input) */
20
+ const BOTTOM_AREA_HEIGHT = 4;
21
+ /** Max visible items in InlineSearch */
22
+ const INLINE_SEARCH_MAX_ITEMS = 7;
23
+ /** Minimum output lines to show before truncation */
24
+ const MIN_OUTPUT_LINES = 5;
25
+ /** Reserved lines for output box (command header + borders + hint line + margin) */
26
+ const OUTPUT_BOX_OVERHEAD = 5;
27
+ /**
28
+ * Count the total number of lines in streaming messages
29
+ * Each message can contain multiple lines (newlines in content)
30
+ */
31
+ function countOutputLines(messages) {
32
+ let total = 0;
33
+ for (const msg of messages) {
34
+ total += msg.content.split('\n').length;
35
+ }
36
+ return total;
37
+ }
38
+ /**
39
+ * Get messages from the end that fit within maxLines, truncating from the beginning (shows newest first)
40
+ * Used for both completed and live streaming output to always show the latest messages
41
+ */
42
+ function getMessagesFromEnd(messages, maxLines) {
43
+ const totalLines = countOutputLines(messages);
44
+ if (totalLines <= maxLines) {
45
+ return { displayMessages: messages, skippedLines: 0, totalLines };
46
+ }
47
+ const displayMessages = [];
48
+ let lineCount = 0;
49
+ // Iterate from the end (newest messages first)
50
+ for (let i = messages.length - 1; i >= 0; i--) {
51
+ const msg = messages[i];
52
+ const msgLineArray = msg.content.split('\n');
53
+ const msgLineCount = msgLineArray.length;
54
+ if (lineCount + msgLineCount <= maxLines) {
55
+ // Message fits completely - prepend to maintain order
56
+ displayMessages.unshift(msg);
57
+ lineCount += msgLineCount;
58
+ }
59
+ else {
60
+ // Message needs to be truncated - show partial lines from the end
61
+ const remainingSpace = maxLines - lineCount;
62
+ if (remainingSpace > 0) {
63
+ // Take only the last lines that fit
64
+ const truncatedContent = msgLineArray.slice(-remainingSpace).join('\n');
65
+ displayMessages.unshift({
66
+ ...msg,
67
+ content: truncatedContent,
68
+ });
69
+ lineCount += remainingSpace;
70
+ }
71
+ break;
72
+ }
73
+ }
74
+ // Ensure we show at least one line
75
+ if (displayMessages.length === 0 && messages.length > 0) {
76
+ const lastMsg = messages.at(-1);
77
+ const lastLines = lastMsg.content.split('\n');
78
+ displayMessages.push({
79
+ ...lastMsg,
80
+ content: lastLines.at(-1) ?? '',
81
+ });
82
+ lineCount = 1;
83
+ }
84
+ return {
85
+ displayMessages,
86
+ skippedLines: totalLines - lineCount,
87
+ totalLines,
88
+ };
89
+ }
90
+ /**
91
+ * Process streaming messages to handle action_start/action_stop pairs
92
+ * - action_start with matching action_stop: mark as completed with stop message
93
+ * - action_start without matching action_stop: mark as running (show spinner)
94
+ * - action_stop messages are filtered out (consumed by their action_start)
95
+ */
96
+ function processMessagesForActions(messages) {
97
+ // Build a map of actionId -> action_stop message
98
+ const stopMessages = new Map();
99
+ for (const msg of messages) {
100
+ if (msg.type === 'action_stop' && msg.actionId) {
101
+ stopMessages.set(msg.actionId, msg.content);
102
+ }
103
+ }
104
+ // Process messages, transforming action_start and filtering action_stop
105
+ const result = [];
106
+ for (const msg of messages) {
107
+ if (msg.type === 'action_stop') {
108
+ // Skip action_stop messages - they're consumed by action_start
109
+ continue;
110
+ }
111
+ if (msg.type === 'action_start' && msg.actionId) {
112
+ const stopMessage = stopMessages.get(msg.actionId);
113
+ result.push({
114
+ ...msg,
115
+ isActionRunning: stopMessage === undefined,
116
+ stopMessage,
117
+ });
118
+ }
119
+ else {
120
+ result.push(msg);
121
+ }
122
+ }
123
+ return result;
124
+ }
125
+ /** Default page size for file selector */
126
+ const INLINE_FILE_SELECTOR_PAGE_SIZE = 7;
127
+ /**
128
+ * Estimate height of an active prompt
129
+ */
130
+ function estimatePromptHeight(prompt) {
131
+ if (!prompt)
132
+ return 0;
133
+ switch (prompt.type) {
134
+ case 'confirm': {
135
+ // Single line: "? message (Y/n) [input]"
136
+ return 3;
137
+ }
138
+ case 'file_selector': {
139
+ // Message + path + separator + items + scroll indicator + hint
140
+ const pageSize = prompt.pageSize ?? INLINE_FILE_SELECTOR_PAGE_SIZE;
141
+ return 5 + pageSize;
142
+ }
143
+ case 'input': {
144
+ // Message line + optional error line
145
+ return 3;
146
+ }
147
+ case 'search': {
148
+ // Message line + up to 7 visible choices (or 1 for "No results")
149
+ // We estimate 7 since we don't know actual results
150
+ return 3 + INLINE_SEARCH_MAX_ITEMS;
151
+ }
152
+ case 'select': {
153
+ // Message line + choices + optional description (with margin)
154
+ const hasDescription = prompt.choices.some((c) => c.description);
155
+ return 1 + prompt.choices.length + (hasDescription ? 2 : 0);
156
+ }
157
+ default: {
158
+ return 4;
159
+ }
160
+ }
161
+ }
162
+ /**
163
+ * Estimate the line height of a command message
164
+ */
165
+ function estimateMessageHeight(msg, options) {
166
+ const { isLast = false, maxOutputLines, promptHeight = 0, streamingLines = 0 } = options;
167
+ let lines = 0;
168
+ if (msg.type === 'command') {
169
+ // Command header with left border
170
+ lines += 1;
171
+ // Output box if present (completed output)
172
+ if (msg.output && msg.output.length > 0) {
173
+ // Count actual lines in the output (each message can have multiple lines)
174
+ const totalOutputLines = countOutputLines(msg.output);
175
+ // Account for truncation: show max lines + 1 for hint
176
+ const displayedLines = totalOutputLines <= maxOutputLines ? totalOutputLines : maxOutputLines + 1;
177
+ // Border top + content + border bottom
178
+ lines += 2 + displayedLines;
179
+ }
180
+ // Live streaming output box (for last message while streaming)
181
+ if (isLast && (streamingLines > 0 || promptHeight > 0)) {
182
+ // Border top + streaming content + prompt + border bottom
183
+ lines += 2 + streamingLines + promptHeight;
184
+ }
185
+ // Top margin for non-first items
186
+ lines += 1;
187
+ }
188
+ else {
189
+ // Other message types (info, error, etc)
190
+ lines += 2;
191
+ }
192
+ return lines;
193
+ }
194
+ export const CommandView = ({ availableHeight }) => {
195
+ const { exit } = useApp();
196
+ const { reloadAuth, reloadBrvConfig } = useAuth();
197
+ const { restart } = useConsumer();
198
+ const [command, setCommand] = useState('');
199
+ const [inputKey, setInputKey] = useState(0);
200
+ const [messages, setMessages] = useState([]);
201
+ const [streamingMessages, setStreamingMessages] = useState([]);
202
+ const [activePrompt, setActivePrompt] = useState(null);
203
+ const [isStreaming, setIsStreaming] = useState(false);
204
+ const { theme: { colors }, } = useTheme();
205
+ // Process streaming messages to handle action_start/action_stop pairs
206
+ const processedStreamingMessages = useMemo(() => processMessagesForActions(streamingMessages), [streamingMessages]);
207
+ const { handleSlashCommand } = useCommands();
208
+ const { appendShortcuts, mode, removeShortcuts } = useMode();
209
+ // Append shortcuts for prompts
210
+ useEffect(() => {
211
+ if (activePrompt?.type === 'search' || activePrompt?.type === 'select') {
212
+ appendShortcuts([{ description: 'select', key: 'enter' }]);
213
+ return () => {
214
+ removeShortcuts(['enter']);
215
+ };
216
+ }
217
+ }, [activePrompt?.type, appendShortcuts, removeShortcuts]);
218
+ const executeCommand = useCallback(async (value) => {
219
+ const trimmed = value.trim();
220
+ if (!trimmed)
221
+ return;
222
+ // Clear command input immediately
223
+ setCommand('');
224
+ setMessages((prev) => [
225
+ ...prev,
226
+ {
227
+ content: '',
228
+ fromCommand: trimmed,
229
+ type: 'command',
230
+ },
231
+ ]);
232
+ const result = await handleSlashCommand(trimmed);
233
+ if (result && result.type === 'message') {
234
+ setMessages((prev) => {
235
+ const last = prev.at(-1);
236
+ return [
237
+ ...(last?.type === 'command' ? prev.slice(0, -1) : [...prev]),
238
+ {
239
+ content: result.content,
240
+ fromCommand: trimmed,
241
+ type: result.messageType === 'error' ? 'error' : 'info',
242
+ },
243
+ ];
244
+ });
245
+ }
246
+ if (result && result.type === 'quit') {
247
+ stopQueuePollingService();
248
+ exit();
249
+ }
250
+ if (result && result.type === 'streaming') {
251
+ setIsStreaming(true);
252
+ setStreamingMessages([]);
253
+ const collectedMessages = [];
254
+ const onMessage = (msg) => {
255
+ collectedMessages.push(msg);
256
+ setStreamingMessages((prev) => [...prev, msg]);
257
+ };
258
+ const onPrompt = (prompt) => {
259
+ setActivePrompt(prompt);
260
+ };
261
+ try {
262
+ await result.execute(onMessage, onPrompt);
263
+ }
264
+ catch (error) {
265
+ const errorMessage = error instanceof Error ? error.message : String(error);
266
+ const errorMsg = {
267
+ content: `Error: ${errorMessage}`,
268
+ id: `error-${Date.now()}`,
269
+ type: 'error',
270
+ };
271
+ collectedMessages.push(errorMsg);
272
+ setStreamingMessages((prev) => [...prev, errorMsg]);
273
+ }
274
+ finally {
275
+ // Store output with the command message
276
+ setMessages((prev) => {
277
+ const updated = [...prev];
278
+ const lastIndex = updated.length - 1;
279
+ if (lastIndex >= 0 && updated[lastIndex].type === 'command') {
280
+ updated[lastIndex] = { ...updated[lastIndex], output: collectedMessages };
281
+ }
282
+ return updated;
283
+ });
284
+ setStreamingMessages([]);
285
+ setIsStreaming(false);
286
+ setActivePrompt(null);
287
+ const needReloadAuth = trimmed.startsWith('/login') || trimmed.startsWith('/logout');
288
+ const needReloadBrvConfig = trimmed.startsWith('/space switch') || trimmed.startsWith('/init');
289
+ // Refresh state after commands that change auth or project state
290
+ if (needReloadAuth || needReloadBrvConfig) {
291
+ // Stop queue polling and consumer
292
+ stopQueuePollingService();
293
+ stopConsumer();
294
+ // Wait for consumer to stop
295
+ setTimeout(async () => {
296
+ if (needReloadAuth)
297
+ await reloadAuth();
298
+ if (needReloadBrvConfig)
299
+ await reloadBrvConfig();
300
+ await restart();
301
+ }, 1000);
302
+ }
303
+ }
304
+ }
305
+ }, [exit, handleSlashCommand, reloadAuth, restart]);
306
+ const handleSubmit = useCallback(async (value) => {
307
+ if (mode === 'console' && !isStreaming)
308
+ await executeCommand(value);
309
+ }, [executeCommand, isStreaming, mode]);
310
+ const handleSelect = useCallback(async (value) => {
311
+ if (!isStreaming)
312
+ await executeCommand(value);
313
+ }, [executeCommand, isStreaming]);
314
+ const handleInsert = useCallback((value) => {
315
+ // Don't add space after directories (ends with /) to allow continued navigation
316
+ const suffix = value.endsWith('/') ? '' : ' ';
317
+ setCommand(value + suffix);
318
+ // TRICK: Force TextInput to remount with cursor at the end
319
+ setInputKey((prev) => prev + 1);
320
+ }, []);
321
+ // Handle prompt response
322
+ const handleSearchResponse = useCallback((value) => {
323
+ if (activePrompt?.type === 'search') {
324
+ activePrompt.onResponse(value);
325
+ setActivePrompt(null);
326
+ }
327
+ }, [activePrompt]);
328
+ const handleConfirmResponse = useCallback((value) => {
329
+ if (activePrompt?.type === 'confirm') {
330
+ activePrompt.onResponse(value);
331
+ setActivePrompt(null);
332
+ }
333
+ }, [activePrompt]);
334
+ const handleSelectResponse = useCallback((value) => {
335
+ if (activePrompt?.type === 'select') {
336
+ activePrompt.onResponse(value);
337
+ setActivePrompt(null);
338
+ }
339
+ }, [activePrompt]);
340
+ const handleInputResponse = useCallback((value) => {
341
+ if (activePrompt?.type === 'input') {
342
+ activePrompt.onResponse(value);
343
+ setActivePrompt(null);
344
+ }
345
+ }, [activePrompt]);
346
+ const handleFileSelectorResponse = useCallback((value) => {
347
+ if (activePrompt?.type === 'file_selector') {
348
+ activePrompt.onResponse(value);
349
+ setActivePrompt(null);
350
+ }
351
+ }, [activePrompt]);
352
+ // Calculate available height for scrollable content
353
+ // Subtract bottom area (suggestions + input)
354
+ const scrollableHeight = Math.max(1, availableHeight - BOTTOM_AREA_HEIGHT);
355
+ // Calculate max output lines based on available height
356
+ // Reserve space for command header, borders, hint line, and margin
357
+ const maxOutputLines = Math.max(MIN_OUTPUT_LINES, scrollableHeight - OUTPUT_BOX_OVERHEAD);
358
+ // Render streaming message (handles ProcessedMessage for action types)
359
+ const renderStreamingMessage = useCallback((msg) => {
360
+ // Handle action messages with spinner
361
+ if (msg.type === 'action_start') {
362
+ if (msg.isActionRunning) {
363
+ // Action is still running - show spinner
364
+ return (_jsxs(Text, { color: colors.text, children: [_jsx(Spinner, { type: "dots" }), " ", msg.content] }, msg.id));
365
+ }
366
+ // Action completed - show with completion message
367
+ return (_jsxs(Text, { color: colors.text, children: [msg.content, msg.stopMessage ? `... ${msg.stopMessage}` : ''] }, msg.id));
368
+ }
369
+ // Regular messages
370
+ let color = colors.text;
371
+ if (msg.type === 'error')
372
+ color = colors.errorText;
373
+ if (msg.type === 'warning')
374
+ color = colors.warning;
375
+ return (_jsx(Text, { color: color, children: msg.content }, msg.id));
376
+ }, [colors]);
377
+ // Render active prompt component based on type
378
+ const renderActivePrompt = useCallback(() => {
379
+ if (!activePrompt)
380
+ return null;
381
+ switch (activePrompt.type) {
382
+ case 'confirm': {
383
+ return (_jsx(InlineConfirm, { default: activePrompt.default, message: activePrompt.message, onConfirm: handleConfirmResponse }));
384
+ }
385
+ case 'file_selector': {
386
+ return (_jsx(InlineFileSelector, { allowCancel: activePrompt.allowCancel, basePath: activePrompt.basePath, filter: activePrompt.filter, message: activePrompt.message, mode: activePrompt.mode, onSelect: handleFileSelectorResponse, pageSize: activePrompt.pageSize }));
387
+ }
388
+ case 'input': {
389
+ return (_jsx(InlineInput, { message: activePrompt.message, onSubmit: handleInputResponse, placeholder: activePrompt.placeholder, validate: activePrompt.validate }));
390
+ }
391
+ case 'search': {
392
+ return (_jsx(InlineSearch, { message: activePrompt.message, onSelect: handleSearchResponse, source: activePrompt.source }));
393
+ }
394
+ case 'select': {
395
+ return (_jsx(InlineSelect, { choices: activePrompt.choices, message: activePrompt.message, onSelect: handleSelectResponse }));
396
+ }
397
+ default: {
398
+ return null;
399
+ }
400
+ }
401
+ }, [
402
+ activePrompt,
403
+ handleConfirmResponse,
404
+ handleFileSelectorResponse,
405
+ handleInputResponse,
406
+ handleSearchResponse,
407
+ handleSelectResponse,
408
+ ]);
409
+ // Render a single message item
410
+ // For the last command message during streaming, show live streaming output
411
+ const renderMessageItem = useCallback((msg, index) => {
412
+ if (msg.type === 'command') {
413
+ const hasOutput = msg.output && msg.output.length > 0;
414
+ const isLastMessage = index === messages.length - 1;
415
+ const showLiveOutput = isLastMessage && (isStreaming || activePrompt) && (streamingMessages.length > 0 || activePrompt);
416
+ return (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, width: "100%", children: [_jsx(Box, { borderBottom: false, borderLeftColor: colors.primary, borderRight: false, borderStyle: "bold", borderTop: false, paddingLeft: 1, children: _jsxs(Text, { color: colors.text, dimColor: true, children: [msg.fromCommand, " ", _jsx(Text, { wrap: "truncate-end", children: msg.content })] }) }), hasOutput &&
417
+ (() => {
418
+ const processedOutput = processMessagesForActions(msg.output);
419
+ const { displayMessages, skippedLines } = getMessagesFromEnd(processedOutput, maxOutputLines);
420
+ return (_jsxs(Box, { borderColor: colors.border, borderStyle: "round", flexDirection: "column", marginTop: 0, paddingX: 1, width: "100%", children: [skippedLines > 0 && (_jsxs(Text, { color: colors.secondary, dimColor: true, children: ["\u2191 ", skippedLines, " more lines above"] })), displayMessages.map((streamMsg) => renderStreamingMessage(streamMsg))] }));
421
+ })(), showLiveOutput &&
422
+ (() => {
423
+ const { displayMessages: liveMessages, skippedLines } = getMessagesFromEnd(processedStreamingMessages, maxOutputLines);
424
+ return (_jsxs(Box, { borderColor: colors.border, borderStyle: "round", flexDirection: "column", paddingX: 1, paddingY: 0, width: "100%", children: [skippedLines > 0 && (_jsxs(Text, { color: colors.secondary, dimColor: true, children: ["\u2191 ", skippedLines, " more lines above"] })), liveMessages.map((streamMsg) => renderStreamingMessage(streamMsg)), isStreaming && !activePrompt && msg.fromCommand.startsWith('/query') && (_jsxs(Text, { color: colors.dimText, children: [_jsx(Spinner, { type: "dots" }), " Processing..."] })), renderActivePrompt()] }));
425
+ })()] }));
426
+ }
427
+ return _jsx(MessageItem, { message: msg });
428
+ }, [
429
+ activePrompt,
430
+ colors,
431
+ isStreaming,
432
+ maxOutputLines,
433
+ messages.length,
434
+ processedStreamingMessages,
435
+ renderActivePrompt,
436
+ renderStreamingMessage,
437
+ ]);
438
+ const keyExtractor = useCallback((_msg, index) => `msg-${index}`, []);
439
+ // Height estimator that accounts for live streaming output and prompts
440
+ const heightEstimator = useCallback((msg, index) => {
441
+ const isLast = index === messages.length - 1;
442
+ const isLive = isLast && (isStreaming || activePrompt);
443
+ return estimateMessageHeight(msg, {
444
+ isLast,
445
+ maxOutputLines,
446
+ promptHeight: isLive ? estimatePromptHeight(activePrompt) : 0,
447
+ streamingLines: isLive ? streamingMessages.length : 0,
448
+ });
449
+ }, [activePrompt, isStreaming, maxOutputLines, messages.length, streamingMessages.length]);
450
+ return (_jsxs(Box, { flexDirection: "column", height: "100%", width: "100%", children: [messages.length > 0 ? (_jsx(Box, { flexDirection: "column", flexGrow: 1, paddingX: 2, children: _jsx(ScrollableList, { autoScrollToBottom: true, availableHeight: scrollableHeight, estimateItemHeight: heightEstimator, isActive: mode === 'console' && !activePrompt && !isStreaming, items: messages, keyExtractor: keyExtractor, renderItem: renderMessageItem }) })) : (_jsx(Spacer, {})), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [!isStreaming && !activePrompt && (_jsx(Suggestions, { input: command, onInsert: handleInsert, onSelect: handleSelect })), _jsxs(Box, { borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", paddingX: 2, children: [_jsx(Text, { color: colors.primary, children: '> ' }), _jsx(TextInput, { focus: !activePrompt && (mode === 'console' || mode === 'suggestions'), onChange: setCommand, onSubmit: handleSubmit, placeholder: isStreaming ? 'Command running...' : 'Use / to view commands', value: command }, inputKey)] })] })] }));
451
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * TUI Views
3
+ */
4
+ export { CommandView } from './command-view.js';
5
+ export { LoginView } from './login-view.js';
6
+ export { LogsView } from './logs-view.js';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * TUI Views
3
+ */
4
+ export { CommandView } from './command-view.js';
5
+ export { LoginView } from './login-view.js';
6
+ export { LogsView } from './logs-view.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Login View
3
+ *
4
+ * Three states:
5
+ * 1. Idle: Prompt user to login
6
+ * 2. Loading: Show spinner and output
7
+ * 3. Completed: Show output and prompt to continue
8
+ */
9
+ import React from 'react';
10
+ export declare const LoginView: React.FC;
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Login View
4
+ *
5
+ * Three states:
6
+ * 1. Idle: Prompt user to login
7
+ * 2. Loading: Show spinner and output
8
+ * 3. Completed: Show output and prompt to continue
9
+ */
10
+ import { Box, Text } from 'ink';
11
+ import Spinner from 'ink-spinner';
12
+ import { useState } from 'react';
13
+ import { EnterPrompt, OutputLog } from '../components/index.js';
14
+ import { useAuth, useConsumer } from '../contexts/index.js';
15
+ import { useTheme } from '../contexts/use-theme.js';
16
+ export const LoginView = () => {
17
+ const { theme } = useTheme();
18
+ const { isLoggingIn, login, loginOutput, reloadAuth } = useAuth();
19
+ const { restart } = useConsumer();
20
+ const [hasStartedLogin, setHasStartedLogin] = useState(false);
21
+ // Derive state from props and local state
22
+ const state = isLoggingIn ? 'loading' : hasStartedLogin ? 'completed' : 'idle';
23
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, paddingTop: 1, children: [state === 'idle' && _jsx(Text, { children: "You are not logged in." }), state === 'loading' && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { children: "Logging in..." })] })), loginOutput.length > 0 && _jsx(OutputLog, { lines: loginOutput, logColor: theme.colors.text }), state === 'idle' && (_jsx(EnterPrompt, { action: "login", onEnter: () => {
24
+ login();
25
+ setHasStartedLogin(true);
26
+ } })), state === 'completed' && _jsx(EnterPrompt, { action: "continue", onEnter: async () => {
27
+ await reloadAuth();
28
+ await restart();
29
+ } })] }));
30
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Logs View
3
+ *
4
+ * Activity log display using ScrollableList with dynamic height calculation
5
+ */
6
+ import React from 'react';
7
+ interface LogsViewProps {
8
+ availableHeight: number;
9
+ }
10
+ export declare const LogsView: React.FC<LogsViewProps>;
11
+ export {};
@@ -0,0 +1,73 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Logs View
4
+ *
5
+ * Activity log display using ScrollableList with dynamic height calculation
6
+ */
7
+ import { Box, Text } from 'ink';
8
+ import { useCallback } from 'react';
9
+ import { LogItem, OnboardingFlow, ScrollableList } from '../components/index.js';
10
+ import { useActivityLogs, useMode, useTheme } from '../hooks/index.js';
11
+ import { useOnboarding } from '../hooks/use-onboarding.js';
12
+ const MAX_PROGRESS_ITEMS = 3;
13
+ /** Minimum content lines to show before truncation */
14
+ const MIN_CONTENT_LINES = 5;
15
+ /** Reserved lines for log item (header + input box + progress + margins) */
16
+ const LOG_ITEM_OVERHEAD = 6;
17
+ /**
18
+ * Estimate the line height of a log item
19
+ */
20
+ function estimateLogHeight(log, maxContentLines) {
21
+ let lines = 0;
22
+ // Header line: [type] @source [timestamp]
23
+ lines += 1;
24
+ // Input box with border (top border + content + bottom border)
25
+ lines += 3;
26
+ // Progress items (max MAX_PROGRESS_ITEMS shown + optional "more" line)
27
+ const progressCount = Math.min(log.progress?.length ?? 0, MAX_PROGRESS_ITEMS);
28
+ lines += progressCount;
29
+ if ((log.progress?.length ?? 0) > MAX_PROGRESS_ITEMS) {
30
+ lines += 1; // "... and X more" line
31
+ }
32
+ // Processing spinner (if running)
33
+ if (log.status === 'running') {
34
+ lines += 1;
35
+ }
36
+ // Content (if completed or failed)
37
+ if (log.status === 'completed' || log.status === 'failed') {
38
+ const contentLineCount = log.content?.split('\n').length ?? 0;
39
+ // Account for truncation: show max lines + 1 for hint if truncated
40
+ const displayedLines = contentLineCount <= maxContentLines ? contentLineCount : maxContentLines + 1;
41
+ lines += displayedLines;
42
+ }
43
+ // Changes sections
44
+ if (log.status === 'completed') {
45
+ if (log.changes.created.length > 0) {
46
+ lines += 1 + log.changes.created.length;
47
+ }
48
+ if (log.changes.updated.length > 0) {
49
+ lines += 1 + log.changes.updated.length;
50
+ }
51
+ }
52
+ // Bottom margin
53
+ lines += 1;
54
+ return lines;
55
+ }
56
+ export const LogsView = ({ availableHeight }) => {
57
+ const { theme: { colors }, } = useTheme();
58
+ const { mode } = useMode();
59
+ const { logs } = useActivityLogs();
60
+ const { shouldShowOnboarding } = useOnboarding();
61
+ // Calculate max content lines based on available height
62
+ const scrollableHeight = Math.max(1, availableHeight - 1);
63
+ const maxContentLines = Math.max(MIN_CONTENT_LINES, scrollableHeight - LOG_ITEM_OVERHEAD);
64
+ const renderLogItem = useCallback((log) => _jsx(LogItem, { log: log, maxContentLines: maxContentLines, maxProgressItems: MAX_PROGRESS_ITEMS }), [maxContentLines]);
65
+ const keyExtractor = useCallback((log) => log.id, []);
66
+ // Height estimator that accounts for content truncation
67
+ const heightEstimator = useCallback((log) => estimateLogHeight(log, maxContentLines), [maxContentLines]);
68
+ // Show onboarding when project is not initialized
69
+ if (shouldShowOnboarding) {
70
+ return _jsx(OnboardingFlow, { availableHeight: scrollableHeight });
71
+ }
72
+ return (_jsx(Box, { borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", borderTop: false, flexDirection: "column", height: "100%", width: "100%", children: logs.length > 0 ? (_jsx(Box, { flexDirection: "column", height: "100%", paddingX: 2, children: _jsx(ScrollableList, { autoScrollToBottom: true, availableHeight: scrollableHeight, estimateItemHeight: heightEstimator, isActive: mode === 'activity', items: logs, keyExtractor: keyExtractor, renderItem: renderLogItem }) })) : (_jsxs(_Fragment, { children: [_jsx(Text, { color: colors.primary, children: "Welcome to ByteRover!" }), _jsx(Text, { color: colors.text, children: "Start by telling your AI Agent what to save or retrieve." }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.text, dimColor: true, children: "Press [Tab] to switch to commands view" }) })] })) }));
73
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Validate file for --files flag in brv curate command
3
+ * Checks:
4
+ * 1. File exists
5
+ * 2. File is within project directory (where .brv exists)
6
+ * 3. File is text/code file (not binary)
7
+ *
8
+ * @param filePath - The file path to validate (can be relative, absolute, or tilde)
9
+ * @param projectRoot - The project root directory (current working directory)
10
+ * @returns Validation result with normalized path or error message
11
+ */
12
+ export declare function validateFileForCurate(filePath: string, projectRoot: string): {
13
+ error?: string;
14
+ normalizedPath?: string;
15
+ valid: boolean;
16
+ };