byterover-cli 0.4.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/README.md +1 -9
  2. package/dist/commands/curate.d.ts +1 -3
  3. package/dist/commands/curate.js +14 -51
  4. package/dist/commands/main.d.ts +8 -0
  5. package/dist/commands/main.js +29 -8
  6. package/dist/commands/query.d.ts +1 -3
  7. package/dist/commands/query.js +8 -35
  8. package/dist/config/context-tree-domains.d.ts +5 -0
  9. package/dist/config/context-tree-domains.js +6 -1
  10. package/dist/config/environment.js +9 -9
  11. package/dist/constants.d.ts +14 -0
  12. package/dist/constants.js +18 -0
  13. package/dist/core/domain/cipher/agent/agent-info.d.ts +199 -0
  14. package/dist/core/domain/cipher/agent/agent-info.js +143 -0
  15. package/dist/core/domain/cipher/agent/agent-registry.d.ts +96 -0
  16. package/dist/core/domain/cipher/agent/agent-registry.js +254 -0
  17. package/dist/core/domain/cipher/agent/index.d.ts +4 -1
  18. package/dist/core/domain/cipher/agent/index.js +7 -1
  19. package/dist/core/domain/cipher/agent-events/types.d.ts +355 -2
  20. package/dist/core/domain/cipher/agent-events/types.js +11 -0
  21. package/dist/core/domain/cipher/errors/error-normalizer.d.ts +156 -0
  22. package/dist/core/domain/cipher/errors/error-normalizer.js +379 -0
  23. package/dist/core/domain/cipher/errors/file-system-error.d.ts +2 -1
  24. package/dist/core/domain/cipher/errors/file-system-error.js +3 -2
  25. package/dist/core/domain/cipher/errors/system-prompt-error-codes.d.ts +79 -0
  26. package/dist/core/domain/cipher/errors/system-prompt-error-codes.js +80 -0
  27. package/dist/core/domain/cipher/errors/system-prompt-error.d.ts +114 -0
  28. package/dist/core/domain/cipher/errors/system-prompt-error.js +144 -0
  29. package/dist/core/domain/cipher/file-system/types.d.ts +57 -0
  30. package/dist/core/domain/cipher/llm/error-codes.d.ts +51 -0
  31. package/dist/core/domain/cipher/llm/error-codes.js +51 -0
  32. package/dist/core/domain/cipher/llm/index.d.ts +9 -0
  33. package/dist/core/domain/cipher/llm/index.js +13 -0
  34. package/dist/core/domain/cipher/llm/registry.d.ts +113 -0
  35. package/dist/core/domain/cipher/llm/registry.js +244 -0
  36. package/dist/core/domain/cipher/llm/schemas.d.ts +155 -0
  37. package/dist/core/domain/cipher/llm/schemas.js +151 -0
  38. package/dist/core/domain/cipher/llm/types.d.ts +121 -0
  39. package/dist/core/domain/cipher/llm/types.js +60 -0
  40. package/dist/core/domain/cipher/storage/message-storage-types.d.ts +114 -5
  41. package/dist/core/domain/cipher/streaming/types.d.ts +119 -0
  42. package/dist/core/domain/cipher/streaming/types.js +16 -0
  43. package/dist/core/domain/cipher/system-prompt/types.d.ts +44 -0
  44. package/dist/core/domain/cipher/todos/types.d.ts +34 -0
  45. package/dist/core/domain/cipher/tools/constants.d.ts +5 -2
  46. package/dist/core/domain/cipher/tools/constants.js +5 -2
  47. package/dist/core/domain/cipher/tools/types.d.ts +31 -0
  48. package/dist/core/domain/errors/connection-error.d.ts +33 -0
  49. package/dist/core/domain/errors/connection-error.js +54 -0
  50. package/dist/core/domain/errors/core-process-error.d.ts +27 -0
  51. package/dist/core/domain/errors/core-process-error.js +43 -0
  52. package/dist/core/domain/errors/task-error.d.ts +64 -0
  53. package/dist/core/domain/errors/task-error.js +116 -0
  54. package/dist/core/domain/errors/transport-error.d.ts +72 -0
  55. package/dist/core/domain/errors/transport-error.js +114 -0
  56. package/dist/core/domain/instance/index.d.ts +1 -0
  57. package/dist/core/domain/instance/index.js +1 -0
  58. package/dist/core/domain/instance/types.d.ts +57 -0
  59. package/dist/core/domain/instance/types.js +72 -0
  60. package/dist/core/domain/knowledge/directory-manager.d.ts +16 -0
  61. package/dist/core/domain/knowledge/directory-manager.js +31 -0
  62. package/dist/core/domain/transport/index.d.ts +2 -0
  63. package/dist/core/domain/transport/index.js +2 -0
  64. package/dist/core/domain/transport/schemas.d.ts +1149 -0
  65. package/dist/core/domain/transport/schemas.js +554 -0
  66. package/dist/core/domain/transport/types.d.ts +67 -0
  67. package/dist/core/domain/transport/types.js +7 -0
  68. package/dist/core/interfaces/cipher/cipher-services.d.ts +15 -3
  69. package/dist/core/interfaces/cipher/i-chat-session.d.ts +47 -5
  70. package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +39 -4
  71. package/dist/core/interfaces/cipher/i-content-generator.d.ts +3 -5
  72. package/dist/core/interfaces/cipher/i-file-system.d.ts +12 -1
  73. package/dist/core/interfaces/cipher/i-llm-service.d.ts +4 -5
  74. package/dist/core/interfaces/cipher/i-todo-storage.d.ts +24 -0
  75. package/dist/core/interfaces/cipher/i-todo-storage.js +1 -0
  76. package/dist/core/interfaces/cipher/i-tool-plugin.d.ts +90 -0
  77. package/dist/core/interfaces/cipher/i-tool-plugin.js +1 -0
  78. package/dist/core/interfaces/cipher/i-tool-provider.d.ts +3 -2
  79. package/dist/core/interfaces/cipher/i-tool-scheduler.d.ts +4 -0
  80. package/dist/core/interfaces/cipher/index.d.ts +35 -0
  81. package/dist/core/interfaces/cipher/index.js +11 -0
  82. package/dist/core/interfaces/cipher/message-factory.d.ts +155 -0
  83. package/dist/core/interfaces/cipher/message-factory.js +252 -0
  84. package/dist/core/interfaces/cipher/message-type-guards.d.ts +139 -0
  85. package/dist/core/interfaces/cipher/message-type-guards.js +173 -0
  86. package/dist/core/interfaces/cipher/message-types.d.ts +279 -5
  87. package/dist/core/interfaces/cipher/message-types.js +6 -0
  88. package/dist/core/interfaces/cipher/sanitization-types.d.ts +147 -0
  89. package/dist/core/interfaces/cipher/sanitization-types.js +46 -0
  90. package/dist/core/interfaces/executor/i-curate-executor.d.ts +34 -0
  91. package/dist/core/interfaces/executor/i-curate-executor.js +1 -0
  92. package/dist/core/interfaces/executor/i-query-executor.d.ts +32 -0
  93. package/dist/core/interfaces/executor/i-query-executor.js +1 -0
  94. package/dist/core/interfaces/executor/index.d.ts +2 -0
  95. package/dist/core/interfaces/executor/index.js +2 -0
  96. package/dist/core/interfaces/instance/i-instance-discovery.d.ts +45 -0
  97. package/dist/core/interfaces/instance/i-instance-discovery.js +1 -0
  98. package/dist/core/interfaces/instance/i-instance-manager.d.ts +58 -0
  99. package/dist/core/interfaces/instance/i-instance-manager.js +1 -0
  100. package/dist/core/interfaces/instance/index.d.ts +2 -0
  101. package/dist/core/interfaces/instance/index.js +2 -0
  102. package/dist/core/interfaces/noop-implementations.d.ts +53 -0
  103. package/dist/core/interfaces/noop-implementations.js +62 -0
  104. package/dist/core/interfaces/transport/i-transport-client.d.ts +97 -0
  105. package/dist/core/interfaces/transport/i-transport-client.js +1 -0
  106. package/dist/core/interfaces/transport/i-transport-server.d.ts +93 -0
  107. package/dist/core/interfaces/transport/i-transport-server.js +1 -0
  108. package/dist/core/interfaces/transport/index.d.ts +2 -0
  109. package/dist/core/interfaces/transport/index.js +2 -0
  110. package/dist/infra/cipher/agent/agent-error-codes.d.ts +16 -0
  111. package/dist/infra/cipher/agent/agent-error-codes.js +17 -0
  112. package/dist/infra/cipher/agent/agent-error.d.ts +54 -0
  113. package/dist/infra/cipher/agent/agent-error.js +79 -0
  114. package/dist/infra/cipher/agent/agent-schemas.d.ts +264 -0
  115. package/dist/infra/cipher/agent/agent-schemas.js +97 -0
  116. package/dist/infra/cipher/agent/agent-state-manager.d.ts +140 -0
  117. package/dist/infra/cipher/agent/agent-state-manager.js +275 -0
  118. package/dist/infra/cipher/agent/base-agent.d.ts +118 -0
  119. package/dist/infra/cipher/agent/base-agent.js +240 -0
  120. package/dist/infra/cipher/agent/cipher-agent.d.ts +165 -0
  121. package/dist/infra/cipher/agent/cipher-agent.js +546 -0
  122. package/dist/infra/cipher/agent/index.d.ts +22 -0
  123. package/dist/infra/cipher/agent/index.js +24 -0
  124. package/dist/infra/cipher/agent/service-initializer.d.ts +79 -0
  125. package/dist/infra/cipher/{agent-service-factory.js → agent/service-initializer.js} +117 -68
  126. package/dist/infra/cipher/agent/types.d.ts +35 -0
  127. package/dist/infra/cipher/agent/types.js +1 -0
  128. package/dist/infra/cipher/blob/blob-reference-resolver.d.ts +107 -0
  129. package/dist/infra/cipher/blob/blob-reference-resolver.js +228 -0
  130. package/dist/infra/cipher/blob/blob-reference-utils.d.ts +117 -0
  131. package/dist/infra/cipher/blob/blob-reference-utils.js +230 -0
  132. package/dist/infra/cipher/consumer/consumer-lock.js +1 -0
  133. package/dist/infra/cipher/consumer/consumer-service.js +1 -0
  134. package/dist/infra/cipher/consumer/execution-consumer.d.ts +6 -1
  135. package/dist/infra/cipher/consumer/execution-consumer.js +54 -16
  136. package/dist/infra/cipher/consumer/index.d.ts +1 -1
  137. package/dist/infra/cipher/consumer/index.js +2 -1
  138. package/dist/infra/cipher/consumer/queue-polling-service.js +1 -0
  139. package/dist/infra/cipher/file-system/binary-utils.d.ts +43 -0
  140. package/dist/infra/cipher/file-system/binary-utils.js +164 -0
  141. package/dist/infra/cipher/file-system/context-tree-file-system-factory.d.ts +9 -0
  142. package/dist/infra/cipher/file-system/context-tree-file-system-factory.js +24 -0
  143. package/dist/infra/cipher/file-system/file-system-service.d.ts +17 -1
  144. package/dist/infra/cipher/file-system/file-system-service.js +327 -36
  145. package/dist/infra/cipher/file-system/path-validator.d.ts +32 -0
  146. package/dist/infra/cipher/file-system/path-validator.js +111 -6
  147. package/dist/infra/cipher/interactive-loop.js +41 -33
  148. package/dist/infra/cipher/llm/capability-cache.d.ts +87 -0
  149. package/dist/infra/cipher/llm/capability-cache.js +125 -0
  150. package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +32 -0
  151. package/dist/infra/cipher/llm/context/compaction/compaction-service.js +44 -3
  152. package/dist/infra/cipher/llm/context/compression/enhanced-compaction.d.ts +112 -0
  153. package/dist/infra/cipher/llm/context/compression/enhanced-compaction.js +175 -0
  154. package/dist/infra/cipher/llm/context/compression/filter-compacted.d.ts +83 -0
  155. package/dist/infra/cipher/llm/context/compression/filter-compacted.js +150 -0
  156. package/dist/infra/cipher/llm/context/compression/index.d.ts +5 -0
  157. package/dist/infra/cipher/llm/context/compression/index.js +6 -0
  158. package/dist/infra/cipher/llm/context/compression/reactive-overflow.d.ts +107 -0
  159. package/dist/infra/cipher/llm/context/compression/reactive-overflow.js +272 -0
  160. package/dist/infra/cipher/llm/context/context-manager.d.ts +47 -1
  161. package/dist/infra/cipher/llm/context/context-manager.js +129 -0
  162. package/dist/infra/cipher/llm/context/utils.js +17 -4
  163. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +4 -2
  164. package/dist/infra/cipher/llm/internal-llm-service.d.ts +50 -17
  165. package/dist/infra/cipher/llm/internal-llm-service.js +273 -50
  166. package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +6 -8
  167. package/dist/infra/cipher/llm/openrouter-llm-service.js +14 -16
  168. package/dist/infra/cipher/llm/retry/retry-policy.d.ts +1 -0
  169. package/dist/infra/cipher/llm/retry/retry-policy.js +11 -0
  170. package/dist/infra/cipher/llm/retry/retry-with-backoff.js +3 -2
  171. package/dist/infra/cipher/llm/sanitization/base64-utils.d.ts +102 -0
  172. package/dist/infra/cipher/llm/sanitization/base64-utils.js +182 -0
  173. package/dist/infra/cipher/llm/sanitization/index.d.ts +12 -0
  174. package/dist/infra/cipher/llm/sanitization/index.js +13 -0
  175. package/dist/infra/cipher/llm/sanitization/tool-sanitizer.d.ts +74 -0
  176. package/dist/infra/cipher/llm/sanitization/tool-sanitizer.js +398 -0
  177. package/dist/infra/cipher/llm/stream-processor.d.ts +158 -0
  178. package/dist/infra/cipher/llm/stream-processor.js +276 -0
  179. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.d.ts +13 -20
  180. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.js +17 -24
  181. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.d.ts +12 -11
  182. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.js +16 -15
  183. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.d.ts +15 -7
  184. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.js +22 -10
  185. package/dist/infra/cipher/llm/tool-output-processor.d.ts +51 -0
  186. package/dist/infra/cipher/llm/tool-output-processor.js +139 -0
  187. package/dist/infra/cipher/process/command-validator.d.ts +23 -0
  188. package/dist/infra/cipher/process/command-validator.js +75 -0
  189. package/dist/infra/cipher/process/path-utils.d.ts +66 -0
  190. package/dist/infra/cipher/process/path-utils.js +94 -0
  191. package/dist/infra/cipher/process/process-service.d.ts +32 -0
  192. package/dist/infra/cipher/process/process-service.js +98 -17
  193. package/dist/infra/cipher/session/chat-session.d.ts +56 -7
  194. package/dist/infra/cipher/session/chat-session.js +163 -13
  195. package/dist/infra/cipher/session/index.d.ts +1 -0
  196. package/dist/infra/cipher/session/index.js +2 -0
  197. package/dist/infra/cipher/session/message-queue.d.ts +65 -0
  198. package/dist/infra/cipher/session/message-queue.js +90 -0
  199. package/dist/infra/cipher/session/session-manager.d.ts +106 -5
  200. package/dist/infra/cipher/session/session-manager.js +254 -7
  201. package/dist/infra/cipher/session/session-status.d.ts +137 -0
  202. package/dist/infra/cipher/session/session-status.js +184 -0
  203. package/dist/infra/cipher/session/title-generator.d.ts +8 -0
  204. package/dist/infra/cipher/session/title-generator.js +31 -0
  205. package/dist/infra/cipher/storage/message-storage-service.d.ts +65 -2
  206. package/dist/infra/cipher/storage/message-storage-service.js +300 -54
  207. package/dist/infra/cipher/storage/tool-part-factory.d.ts +116 -0
  208. package/dist/infra/cipher/storage/tool-part-factory.js +197 -0
  209. package/dist/infra/cipher/system-prompt/contributor-schemas.d.ts +516 -0
  210. package/dist/infra/cipher/system-prompt/contributor-schemas.js +85 -0
  211. package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.d.ts +59 -0
  212. package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.js +131 -0
  213. package/dist/infra/cipher/system-prompt/contributors/companion-contributor.d.ts +54 -0
  214. package/dist/infra/cipher/system-prompt/contributors/companion-contributor.js +107 -0
  215. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.d.ts +68 -0
  216. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.js +179 -0
  217. package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.d.ts +25 -0
  218. package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.js +29 -0
  219. package/dist/infra/cipher/system-prompt/contributors/environment-contributor.d.ts +25 -0
  220. package/dist/infra/cipher/system-prompt/contributors/environment-contributor.js +54 -0
  221. package/dist/infra/cipher/system-prompt/contributors/file-contributor.d.ts +60 -0
  222. package/dist/infra/cipher/system-prompt/contributors/file-contributor.js +128 -0
  223. package/dist/infra/cipher/system-prompt/contributors/index.d.ts +13 -0
  224. package/dist/infra/cipher/system-prompt/contributors/index.js +8 -0
  225. package/dist/infra/cipher/system-prompt/contributors/memory-contributor.d.ts +40 -0
  226. package/dist/infra/cipher/system-prompt/contributors/memory-contributor.js +56 -0
  227. package/dist/infra/cipher/system-prompt/contributors/static-contributor.d.ts +26 -0
  228. package/dist/infra/cipher/system-prompt/contributors/static-contributor.js +31 -0
  229. package/dist/infra/cipher/system-prompt/environment-context-builder.d.ts +112 -0
  230. package/dist/infra/cipher/system-prompt/environment-context-builder.js +256 -0
  231. package/dist/infra/cipher/system-prompt/prompt-cache.d.ts +102 -0
  232. package/dist/infra/cipher/system-prompt/prompt-cache.js +156 -0
  233. package/dist/infra/cipher/system-prompt/schemas.d.ts +151 -0
  234. package/dist/infra/cipher/system-prompt/schemas.js +94 -0
  235. package/dist/infra/cipher/system-prompt/system-prompt-manager.d.ts +136 -0
  236. package/dist/infra/cipher/system-prompt/system-prompt-manager.js +307 -0
  237. package/dist/infra/cipher/todos/todo-storage-service.d.ts +26 -0
  238. package/dist/infra/cipher/todos/todo-storage-service.js +28 -0
  239. package/dist/infra/cipher/tools/core-tool-scheduler.js +5 -1
  240. package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
  241. package/dist/infra/cipher/tools/implementations/bash-exec-tool.d.ts +1 -0
  242. package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +27 -10
  243. package/dist/infra/cipher/tools/implementations/bash-output-tool.js +1 -5
  244. package/dist/infra/cipher/tools/implementations/batch-tool.d.ts +12 -0
  245. package/dist/infra/cipher/tools/implementations/batch-tool.js +142 -0
  246. package/dist/infra/cipher/tools/implementations/curate-tool.js +195 -68
  247. package/dist/infra/cipher/tools/implementations/list-directory-tool.d.ts +12 -0
  248. package/dist/infra/cipher/tools/implementations/list-directory-tool.js +52 -0
  249. package/dist/infra/cipher/tools/implementations/read-file-tool.d.ts +8 -1
  250. package/dist/infra/cipher/tools/implementations/read-file-tool.js +17 -7
  251. package/dist/infra/cipher/tools/implementations/read-todos-tool.d.ts +11 -0
  252. package/dist/infra/cipher/tools/implementations/read-todos-tool.js +39 -0
  253. package/dist/infra/cipher/tools/implementations/{detect-domains-tool.d.ts → spec-analyze-tool.d.ts} +1 -1
  254. package/dist/infra/cipher/tools/implementations/{detect-domains-tool.js → spec-analyze-tool.js} +9 -7
  255. package/dist/infra/cipher/tools/implementations/task-tool.d.ts +34 -0
  256. package/dist/infra/cipher/tools/implementations/task-tool.js +207 -0
  257. package/dist/infra/cipher/tools/implementations/write-todos-tool.d.ts +4 -1
  258. package/dist/infra/cipher/tools/implementations/write-todos-tool.js +19 -63
  259. package/dist/infra/cipher/tools/index.d.ts +1 -1
  260. package/dist/infra/cipher/tools/index.js +1 -1
  261. package/dist/infra/cipher/tools/plugins/index.d.ts +3 -0
  262. package/dist/infra/cipher/tools/plugins/index.js +2 -0
  263. package/dist/infra/cipher/tools/plugins/logging-plugin.d.ts +28 -0
  264. package/dist/infra/cipher/tools/plugins/logging-plugin.js +66 -0
  265. package/dist/infra/cipher/tools/plugins/plugin-manager.d.ts +81 -0
  266. package/dist/infra/cipher/tools/plugins/plugin-manager.js +122 -0
  267. package/dist/infra/cipher/tools/streaming/index.d.ts +1 -0
  268. package/dist/infra/cipher/tools/streaming/index.js +1 -0
  269. package/dist/infra/cipher/tools/streaming/metadata-handler.d.ts +31 -0
  270. package/dist/infra/cipher/tools/streaming/metadata-handler.js +39 -0
  271. package/dist/infra/cipher/tools/tool-description-loader.d.ts +57 -0
  272. package/dist/infra/cipher/tools/tool-description-loader.js +108 -0
  273. package/dist/infra/cipher/tools/tool-manager.d.ts +38 -4
  274. package/dist/infra/cipher/tools/tool-manager.js +107 -11
  275. package/dist/infra/cipher/tools/tool-provider-getter.d.ts +6 -0
  276. package/dist/infra/cipher/tools/tool-provider-getter.js +1 -0
  277. package/dist/infra/cipher/tools/tool-provider.d.ts +32 -7
  278. package/dist/infra/cipher/tools/tool-provider.js +81 -25
  279. package/dist/infra/cipher/tools/tool-registry.d.ts +23 -0
  280. package/dist/infra/cipher/tools/tool-registry.js +58 -16
  281. package/dist/infra/context-tree/file-context-tree-snapshot-service.js +10 -4
  282. package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +4 -3
  283. package/dist/infra/context-tree/file-context-tree-writer-service.js +6 -4
  284. package/dist/infra/context-tree/path-utils.d.ts +7 -0
  285. package/dist/infra/context-tree/path-utils.js +7 -0
  286. package/dist/infra/core/executors/curate-executor.d.ts +35 -0
  287. package/dist/infra/core/executors/curate-executor.js +123 -0
  288. package/dist/infra/core/executors/index.d.ts +2 -0
  289. package/dist/infra/core/executors/index.js +2 -0
  290. package/dist/infra/core/executors/query-executor.d.ts +23 -0
  291. package/dist/infra/core/executors/query-executor.js +51 -0
  292. package/dist/infra/core/task-processor.d.ts +81 -0
  293. package/dist/infra/core/task-processor.js +115 -0
  294. package/dist/infra/instance/file-instance-discovery.d.ts +31 -0
  295. package/dist/infra/instance/file-instance-discovery.js +84 -0
  296. package/dist/infra/instance/file-instance-manager.d.ts +46 -0
  297. package/dist/infra/instance/file-instance-manager.js +123 -0
  298. package/dist/infra/instance/index.d.ts +3 -0
  299. package/dist/infra/instance/index.js +3 -0
  300. package/dist/infra/instance/process-utils.d.ts +14 -0
  301. package/dist/infra/instance/process-utils.js +39 -0
  302. package/dist/infra/process/agent-worker.d.ts +20 -0
  303. package/dist/infra/process/agent-worker.js +602 -0
  304. package/dist/infra/process/index.d.ts +12 -0
  305. package/dist/infra/process/index.js +11 -0
  306. package/dist/infra/process/ipc-types.d.ts +55 -0
  307. package/dist/infra/process/ipc-types.js +12 -0
  308. package/dist/infra/process/process-manager.d.ts +154 -0
  309. package/dist/infra/process/process-manager.js +471 -0
  310. package/dist/infra/process/task-queue-manager.d.ts +123 -0
  311. package/dist/infra/process/task-queue-manager.js +226 -0
  312. package/dist/infra/process/transport-handlers.d.ts +124 -0
  313. package/dist/infra/process/transport-handlers.js +348 -0
  314. package/dist/infra/process/transport-worker.d.ts +20 -0
  315. package/dist/infra/process/transport-worker.js +168 -0
  316. package/dist/infra/repl/commands/curate-command.js +0 -5
  317. package/dist/infra/repl/commands/query-command.js +0 -3
  318. package/dist/infra/repl/repl-startup.d.ts +4 -0
  319. package/dist/infra/repl/repl-startup.js +8 -1
  320. package/dist/infra/repl/transport-client-helper.d.ts +9 -0
  321. package/dist/infra/repl/transport-client-helper.js +96 -0
  322. package/dist/infra/transport/index.d.ts +4 -0
  323. package/dist/infra/transport/index.js +4 -0
  324. package/dist/infra/transport/port-utils.d.ts +42 -0
  325. package/dist/infra/transport/port-utils.js +84 -0
  326. package/dist/infra/transport/socket-io-transport-client.d.ts +45 -0
  327. package/dist/infra/transport/socket-io-transport-client.js +270 -0
  328. package/dist/infra/transport/socket-io-transport-server.d.ts +35 -0
  329. package/dist/infra/transport/socket-io-transport-server.js +207 -0
  330. package/dist/infra/transport/transport-client-factory.d.ts +76 -0
  331. package/dist/infra/transport/transport-client-factory.js +168 -0
  332. package/dist/infra/transport/transport-factory.d.ts +33 -0
  333. package/dist/infra/transport/transport-factory.js +59 -0
  334. package/dist/infra/usecase/curate-use-case.d.ts +8 -55
  335. package/dist/infra/usecase/curate-use-case.js +71 -262
  336. package/dist/infra/usecase/init-use-case.js +3 -2
  337. package/dist/infra/usecase/query-use-case.d.ts +18 -45
  338. package/dist/infra/usecase/query-use-case.js +250 -326
  339. package/dist/infra/usecase/status-use-case.js +1 -1
  340. package/dist/resources/prompts/{curate-context-tree-curation.yml → curate.yml} +25 -22
  341. package/dist/resources/prompts/explore.yml +78 -0
  342. package/dist/resources/prompts/plan.yml +114 -0
  343. package/dist/resources/prompts/reflection.yml +1 -1
  344. package/dist/resources/prompts/system-prompt.yml +15 -8
  345. package/dist/resources/prompts/tool-outputs.yml +0 -5
  346. package/dist/resources/tools/bash_exec.txt +98 -0
  347. package/dist/resources/tools/bash_output.txt +40 -0
  348. package/dist/resources/tools/batch.txt +28 -0
  349. package/dist/resources/tools/create_knowledge_topic.txt +23 -0
  350. package/dist/resources/tools/curate.txt +22 -0
  351. package/dist/resources/tools/delete_memory.txt +1 -0
  352. package/dist/resources/tools/detect_domains.txt +11 -0
  353. package/dist/resources/tools/edit_file.txt +1 -0
  354. package/dist/resources/tools/edit_memory.txt +1 -0
  355. package/dist/resources/tools/glob_files.txt +20 -0
  356. package/dist/resources/tools/grep_content.txt +18 -0
  357. package/dist/resources/tools/kill_process.txt +16 -0
  358. package/dist/resources/tools/list_directory.txt +16 -0
  359. package/dist/resources/tools/list_memories.txt +1 -0
  360. package/dist/resources/tools/read_file.txt +31 -0
  361. package/dist/resources/tools/read_memory.txt +1 -0
  362. package/dist/resources/tools/read_todos.txt +17 -0
  363. package/dist/resources/tools/search_history.txt +1 -0
  364. package/dist/resources/tools/task.txt +23 -0
  365. package/dist/resources/tools/write_file.txt +1 -0
  366. package/dist/resources/tools/write_memory.txt +1 -0
  367. package/dist/resources/tools/write_todos.txt +29 -0
  368. package/dist/tui/app.js +9 -13
  369. package/dist/tui/components/command-details.d.ts +14 -0
  370. package/dist/tui/components/command-details.js +35 -0
  371. package/dist/tui/components/execution/execution-changes.d.ts +5 -0
  372. package/dist/tui/components/execution/execution-changes.js +19 -4
  373. package/dist/tui/components/execution/execution-content.d.ts +4 -2
  374. package/dist/tui/components/execution/execution-content.js +26 -13
  375. package/dist/tui/components/execution/execution-input.js +3 -3
  376. package/dist/tui/components/execution/execution-progress.d.ts +2 -2
  377. package/dist/tui/components/execution/execution-progress.js +8 -6
  378. package/dist/tui/components/execution/log-item.d.ts +3 -4
  379. package/dist/tui/components/execution/log-item.js +2 -5
  380. package/dist/tui/components/footer.js +9 -4
  381. package/dist/tui/components/header.d.ts +3 -3
  382. package/dist/tui/components/header.js +5 -3
  383. package/dist/tui/components/index.d.ts +1 -0
  384. package/dist/tui/components/index.js +1 -0
  385. package/dist/tui/components/onboarding/copyable-prompt.d.ts +5 -3
  386. package/dist/tui/components/onboarding/copyable-prompt.js +7 -8
  387. package/dist/tui/components/onboarding/onboarding-flow.js +35 -25
  388. package/dist/tui/components/scrollable-list.js +12 -10
  389. package/dist/tui/components/suggestions.js +39 -41
  390. package/dist/tui/components/tab-bar.d.ts +2 -1
  391. package/dist/tui/components/tab-bar.js +3 -4
  392. package/dist/tui/constants.d.ts +0 -5
  393. package/dist/tui/constants.js +0 -5
  394. package/dist/tui/contexts/auth-context.js +9 -2
  395. package/dist/tui/contexts/{use-commands.js → commands-context.js} +3 -3
  396. package/dist/tui/contexts/index.d.ts +6 -1
  397. package/dist/tui/contexts/index.js +6 -1
  398. package/dist/tui/contexts/onboarding-context.d.ts +1 -1
  399. package/dist/tui/contexts/onboarding-context.js +9 -9
  400. package/dist/tui/contexts/tasks-context.d.ts +84 -0
  401. package/dist/tui/contexts/tasks-context.js +218 -0
  402. package/dist/tui/contexts/transport-context.d.ts +29 -0
  403. package/dist/tui/contexts/transport-context.js +82 -0
  404. package/dist/tui/hooks/index.d.ts +10 -6
  405. package/dist/tui/hooks/index.js +7 -6
  406. package/dist/tui/hooks/use-activity-logs.d.ts +3 -11
  407. package/dist/tui/hooks/use-activity-logs.js +87 -34
  408. package/dist/tui/hooks/use-auth-polling.d.ts +24 -0
  409. package/dist/tui/hooks/use-auth-polling.js +104 -0
  410. package/dist/tui/hooks/use-slash-command-processor.js +0 -1
  411. package/dist/tui/hooks/use-slash-completion.js +1 -1
  412. package/dist/tui/hooks/use-tab-navigation.d.ts +2 -1
  413. package/dist/tui/hooks/use-tab-navigation.js +16 -7
  414. package/dist/tui/hooks/use-terminal-breakpoint.d.ts +21 -0
  415. package/dist/tui/hooks/use-terminal-breakpoint.js +38 -0
  416. package/dist/tui/hooks/use-ui-heights.d.ts +120 -0
  417. package/dist/tui/hooks/use-ui-heights.js +88 -0
  418. package/dist/tui/providers/app-providers.js +2 -6
  419. package/dist/tui/types/commands.d.ts +0 -26
  420. package/dist/tui/types/index.d.ts +1 -1
  421. package/dist/tui/types/ui.d.ts +9 -4
  422. package/dist/tui/utils/line.d.ts +11 -0
  423. package/dist/tui/utils/line.js +16 -0
  424. package/dist/tui/utils/log.d.ts +27 -0
  425. package/dist/tui/utils/log.js +114 -0
  426. package/dist/tui/views/command-view.d.ts +7 -0
  427. package/dist/tui/views/command-view.js +103 -80
  428. package/dist/tui/views/login-view.js +7 -4
  429. package/dist/tui/views/logs-view.d.ts +13 -0
  430. package/dist/tui/views/logs-view.js +27 -52
  431. package/dist/utils/connection-error-handler.d.ts +16 -0
  432. package/dist/utils/connection-error-handler.js +49 -0
  433. package/dist/utils/crash-log.d.ts +14 -0
  434. package/dist/utils/crash-log.js +19 -0
  435. package/dist/utils/file-helpers.d.ts +14 -0
  436. package/dist/utils/file-helpers.js +21 -0
  437. package/dist/utils/global-logs-path.d.ts +11 -0
  438. package/dist/utils/global-logs-path.js +37 -0
  439. package/dist/utils/process-logger.d.ts +53 -0
  440. package/dist/utils/process-logger.js +253 -0
  441. package/dist/utils/sandbox-detector.d.ts +31 -0
  442. package/dist/utils/sandbox-detector.js +122 -0
  443. package/oclif.manifest.json +10 -198
  444. package/package.json +5 -1
  445. package/dist/commands/cipher-agent/run.d.ts +0 -142
  446. package/dist/commands/cipher-agent/run.js +0 -555
  447. package/dist/commands/cipher-agent/set-prompt.d.ts +0 -16
  448. package/dist/commands/cipher-agent/set-prompt.js +0 -58
  449. package/dist/commands/cipher-agent/show-prompt.d.ts +0 -13
  450. package/dist/commands/cipher-agent/show-prompt.js +0 -53
  451. package/dist/commands/foo.d.ts +0 -14
  452. package/dist/commands/foo.js +0 -66
  453. package/dist/infra/cipher/agent-service-factory.d.ts +0 -93
  454. package/dist/infra/cipher/cipher-agent-state-manager.d.ts +0 -63
  455. package/dist/infra/cipher/cipher-agent-state-manager.js +0 -108
  456. package/dist/infra/cipher/cipher-agent.d.ts +0 -182
  457. package/dist/infra/cipher/cipher-agent.js +0 -317
  458. package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +0 -106
  459. package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +0 -297
  460. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.d.ts +0 -7
  461. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +0 -424
  462. package/dist/resources/prompts/modes/autonomous.yml +0 -9
  463. package/dist/resources/prompts/query-context-tree-retrieval.yml +0 -48
  464. package/dist/tui/contexts/consumer.d.ts +0 -31
  465. package/dist/tui/contexts/consumer.js +0 -56
  466. package/dist/tui/hooks/use-consumer.d.ts +0 -12
  467. package/dist/tui/hooks/use-consumer.js +0 -50
  468. package/dist/tui/hooks/use-queue-polling.d.ts +0 -31
  469. package/dist/tui/hooks/use-queue-polling.js +0 -90
  470. /package/dist/tui/contexts/{use-commands.d.ts → commands-context.d.ts} +0 -0
  471. /package/dist/tui/contexts/{use-mode.d.ts → mode-context.d.ts} +0 -0
  472. /package/dist/tui/contexts/{use-mode.js → mode-context.js} +0 -0
  473. /package/dist/tui/contexts/{use-theme.d.ts → theme-context.d.ts} +0 -0
  474. /package/dist/tui/contexts/{use-theme.js → theme-context.js} +0 -0
@@ -8,24 +8,20 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  import { Box, Text, useInput } from 'ink';
9
9
  import Spinner from 'ink-spinner';
10
10
  import { useCallback, useMemo, useState } from 'react';
11
- import { useAuth } from '../../contexts/auth-context.js';
12
- import { useConsumer } from '../../contexts/index.js';
13
- import { useActivityLogs, useCommands, useMode, useTheme } from '../../hooks/index.js';
11
+ import { useAuth, useTransport } from '../../contexts/index.js';
12
+ import { useActivityLogs, useCommands, useMode, useTheme, useUIHeights } from '../../hooks/index.js';
14
13
  import { useOnboarding } from '../../hooks/use-onboarding.js';
14
+ import { calculateLogContentLimit } from '../../utils/log.js';
15
15
  import { EnterPrompt } from '../enter-prompt.js';
16
16
  import { LogItem } from '../execution/index.js';
17
17
  import { InlineConfirm, InlineInput, InlineSearch, InlineSelect } from '../inline-prompts/index.js';
18
18
  import { CopyablePrompt } from './copyable-prompt.js';
19
19
  import { OnboardingStep } from './onboarding-step.js';
20
20
  /** Example prompts for curate and query steps */
21
- const CURATE_PROMPT = 'brv curate "Auth uses JWT with 24h expiry. Tokens stored in httpOnly cookies"';
22
- const QUERY_PROMPT = 'brv query "How is authentication implemented?"';
21
+ const CURATE_PROMPT = 'run `brv curate "Auth uses JWT with 24h expiry. Tokens stored in httpOnly cookies"`';
22
+ const QUERY_PROMPT = 'run `brv query "How is authentication implemented?"`';
23
23
  /** Minimum output lines to show before truncation */
24
24
  const MIN_OUTPUT_LINES = 3;
25
- /** Reserved lines for onboarding step (title + description + borders + margins + onboard title + onboard description + content margin top) */
26
- const ONBOARDING_STEP_OVERHEAD = 8;
27
- /** Reserved lines for onboarding curate/query (content margin bottom + 1 line + prompt 'enter' to continue) */
28
- const ONBOARDING_CURATE_QUERY_OVER_BOTTOM = 3;
29
25
  /** Reserved lines for inline search (message + input + margins) */
30
26
  const INLINE_SEARCH_OVERHEAD = 3;
31
27
  /** Minimum visible items for inline search */
@@ -128,18 +124,30 @@ export const OnboardingFlow = ({ availableHeight }) => {
128
124
  const { theme: { colors }, } = useTheme();
129
125
  const { mode } = useMode();
130
126
  const { reloadAuth } = useAuth();
131
- const { restart } = useConsumer();
127
+ const { client } = useTransport();
132
128
  const { handleSlashCommand } = useCommands();
133
129
  const { completeOnboarding, curateAcknowledged, currentStep, hasCurated, hasQueried, queryAcknowledged, setCurateAcknowledged, setQueryAcknowledged, totalSteps, } = useOnboarding();
134
130
  const { logs } = useActivityLogs();
135
- // Calculate max output lines based on available height
136
- // Reserve space for onboarding step title, description, borders, and margins
137
- const maxOutputLines = Math.max(MIN_OUTPUT_LINES, availableHeight - ONBOARDING_STEP_OVERHEAD - ONBOARDING_CURATE_QUERY_OVER_BOTTOM);
138
- // Calculate max visible items for inline search based on available height
139
- const maxSearchItems = Math.max(MIN_SEARCH_ITEMS, maxOutputLines - INLINE_SEARCH_OVERHEAD);
131
+ const { messageItem } = useUIHeights();
140
132
  // Find running or queued curate/query logs
141
133
  const curateLog = useMemo(() => logs.find((log) => log.type === 'curate'), [logs]);
142
134
  const queryLog = useMemo(() => logs.find((log) => log.type === 'query'), [logs]);
135
+ // Onboarding UI overhead: step title (1) + description (1) + content margin top (1)
136
+ const onboardingOverhead = 3;
137
+ const enterPromptHeight = ((currentStep === 'curate' && hasCurated && !curateAcknowledged) ||
138
+ (currentStep === 'query' && hasQueried && !queryAcknowledged))
139
+ ? 4
140
+ : 0;
141
+ const activeLog = currentStep === 'curate' ? curateLog : currentStep === 'query' ? queryLog : null;
142
+ let maxOutputLines = MIN_OUTPUT_LINES;
143
+ if (activeLog) {
144
+ // Calculate available height for the log (subtract onboarding UI and EnterPrompt)
145
+ const logAvailableHeight = availableHeight - onboardingOverhead - enterPromptHeight;
146
+ const parts = calculateLogContentLimit(activeLog, logAvailableHeight, messageItem);
147
+ const contentPart = parts.find((p) => p.field === 'content');
148
+ maxOutputLines = Math.max(MIN_OUTPUT_LINES, contentPart?.lines ?? MIN_OUTPUT_LINES);
149
+ }
150
+ const maxSearchItems = Math.max(MIN_SEARCH_ITEMS, maxOutputLines - INLINE_SEARCH_OVERHEAD);
143
151
  // Streaming state for init command
144
152
  const [isRunningInit, setIsRunningInit] = useState(false);
145
153
  const [streamingMessages, setStreamingMessages] = useState([]);
@@ -173,8 +181,10 @@ export const OnboardingFlow = ({ availableHeight }) => {
173
181
  await result.execute(onMessage, onPrompt);
174
182
  // Reload auth to detect config change
175
183
  await reloadAuth();
176
- // Restart consumer to pick up new project state
177
- await restart();
184
+ // Restart agent to pick up new project state
185
+ if (client) {
186
+ await client.request('agent:restart', { reason: 'Project initialized' });
187
+ }
178
188
  }
179
189
  catch (error) {
180
190
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -189,7 +199,7 @@ export const OnboardingFlow = ({ availableHeight }) => {
189
199
  setInitError(result.content);
190
200
  setIsRunningInit(false);
191
201
  }
192
- }, [handleSlashCommand, isRunningInit, reloadAuth, restart]);
202
+ }, [handleSlashCommand, isRunningInit, reloadAuth, client]);
193
203
  // Process streaming messages to handle action_start/action_stop pairs
194
204
  const processedStreamingMessages = useMemo(() => processMessagesForActions(streamingMessages), [streamingMessages]);
195
205
  // Render streaming message with proper styling
@@ -199,7 +209,7 @@ export const OnboardingFlow = ({ availableHeight }) => {
199
209
  if (msg.isActionRunning) {
200
210
  return (_jsxs(Text, { color: colors.text, children: [_jsx(Spinner, { type: "dots" }), " ", msg.content] }, msg.id));
201
211
  }
202
- return (_jsxs(Text, { color: colors.text, children: [msg.content, msg.stopMessage ? `... ${msg.stopMessage}` : ''] }, msg.id));
212
+ return (_jsx(Text, { color: colors.text, children: msg.stopMessage ? `... ${msg.stopMessage}` : '' }, msg.id));
203
213
  }
204
214
  // Regular messages
205
215
  let color = colors.text;
@@ -272,8 +282,8 @@ export const OnboardingFlow = ({ availableHeight }) => {
272
282
  // Render init step content
273
283
  const renderInitContent = () => {
274
284
  if (isRunningInit) {
275
- const { displayMessages: liveMessages, skippedLines } = getMessagesFromEnd(processedStreamingMessages, maxOutputLines);
276
- return (_jsx(Box, { flexDirection: "column", width: "100%", children: _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)), renderActivePrompt()] }) }));
285
+ const { displayMessages: liveMessages } = getMessagesFromEnd(processedStreamingMessages, maxOutputLines);
286
+ return (_jsx(Box, { flexDirection: "column", width: "100%", children: _jsxs(Box, { borderColor: colors.border, borderStyle: "single", flexDirection: "column", paddingX: 1, paddingY: 0, width: "100%", children: [liveMessages.map((streamMsg) => renderStreamingMessage(streamMsg)), renderActivePrompt()] }) }));
277
287
  }
278
288
  if (initError) {
279
289
  return (_jsxs(Box, { flexDirection: "column", rowGap: 1, children: [_jsxs(Text, { color: colors.errorText, children: ["Error: ", initError] }), _jsx(EnterPrompt, { action: "try again", active: mode === 'activity' && currentStep === 'init' && !isRunningInit && !activePrompt, onEnter: runInit })] }));
@@ -284,19 +294,19 @@ export const OnboardingFlow = ({ availableHeight }) => {
284
294
  const renderCurateContent = () => {
285
295
  // Show execution progress if curate is running
286
296
  if (curateLog) {
287
- return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsx(LogItem, { log: curateLog, maxContentLines: maxOutputLines }), hasCurated && !curateAcknowledged && (_jsx(EnterPrompt, { action: "continue", active: mode === 'activity' && currentStep === 'curate', onEnter: () => setCurateAcknowledged(true) }))] }));
297
+ return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsx(LogItem, { heights: { ...messageItem, maxContentLines: maxOutputLines }, log: curateLog }), hasCurated && !curateAcknowledged && (_jsx(EnterPrompt, { action: "continue", active: mode === 'activity' && currentStep === 'curate', onEnter: () => setCurateAcknowledged(true) }))] }));
288
298
  }
289
299
  // Show copyable prompt when waiting
290
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.dimText, wrap: "wrap", children: "Copy this command and paste it to your AI agent:" }), _jsx(CopyablePrompt, { isActive: mode === 'activity' && currentStep === 'curate', prompt: CURATE_PROMPT }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: colors.dimText, children: [_jsx(Spinner, { type: "dots" }), " Waiting for curate..."] }), _jsx(Text, { color: colors.dimText, children: " (Press Esc to skip)" })] })] }));
300
+ return (_jsxs(Box, { backgroundColor: colors.bg2, flexDirection: "column", padding: 1, width: "100%", children: [_jsx(Text, { color: colors.text, wrap: "wrap", children: "Try saying this to your AI Agent:" }), _jsx(Box, { marginBottom: 1, paddingLeft: 4, children: _jsx(Text, { color: colors.primary, wrap: "wrap", children: CURATE_PROMPT }) }), _jsxs(Text, { children: [_jsx(CopyablePrompt, { buttonLabel: '[ctrl+y] to copy', isActive: mode === 'activity' && currentStep === 'curate', textToCopy: CURATE_PROMPT }), _jsx(Text, { color: colors.dimText, children: " | [Esc] to skip onboarding" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.dimText, children: "Waiting for curate..." }) })] }));
291
301
  };
292
302
  // Render query step content
293
303
  const renderQueryContent = () => {
294
304
  // Show execution progress if query is running
295
305
  if (queryLog) {
296
- return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsx(LogItem, { log: queryLog, maxContentLines: maxOutputLines }), hasQueried && !queryAcknowledged && (_jsx(EnterPrompt, { action: "continue", active: mode === 'activity' && currentStep === 'query', onEnter: () => setQueryAcknowledged(true) }))] }));
306
+ return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsx(LogItem, { heights: { ...messageItem, maxContentLines: maxOutputLines }, log: queryLog }), hasQueried && !queryAcknowledged && (_jsx(EnterPrompt, { action: "continue", active: mode === 'activity' && currentStep === 'query', onEnter: () => setQueryAcknowledged(true) }))] }));
297
307
  }
298
308
  // Show copyable prompt when waiting
299
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.dimText, wrap: "wrap", children: "Copy this command and paste it to your AI agent:" }), _jsx(CopyablePrompt, { isActive: mode === 'activity' && currentStep === 'query', prompt: QUERY_PROMPT }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: colors.dimText, children: [_jsx(Spinner, { type: "dots" }), " Waiting for query..."] }), _jsx(Text, { color: colors.dimText, children: " (Press Esc to skip)" })] })] }));
309
+ return (_jsxs(Box, { backgroundColor: colors.bg2, flexDirection: "column", padding: 1, width: "100%", children: [_jsx(Text, { color: colors.text, wrap: "wrap", children: "You can now query your memory:" }), _jsx(Box, { marginBottom: 1, paddingLeft: 4, children: _jsx(Text, { color: colors.primary, wrap: "wrap", children: QUERY_PROMPT }) }), _jsxs(Text, { children: [_jsx(CopyablePrompt, { buttonLabel: '[ctrl+y] to copy', isActive: mode === 'activity' && currentStep === 'query', textToCopy: QUERY_PROMPT }), _jsx(Text, { color: colors.dimText, children: " | [Esc] to skip onboarding" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.dimText, children: "Waiting for query..." }) })] }));
300
310
  };
301
311
  // Render complete step content
302
312
  const renderCompleteContent = () => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.dimText, wrap: "wrap", children: "Activity logs will appear here as you use brv curate and brv query." }), _jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsx(Text, { color: colors.dimText, children: "Tips:" }), _jsx(Text, { color: colors.dimText, children: "- Press [Tab] to switch to commands view" }), _jsx(Text, { color: colors.dimText, children: "- Use /push to sync your context to the cloud" }), _jsx(Text, { color: colors.dimText, children: "- Use /gen-rules to generate agent rules" }), _jsx(Text, { color: colors.dimText, children: "- Type / for available commands" })] }), _jsx(EnterPrompt, { action: "finish onboarding", active: mode === 'activity' && currentStep === 'complete', onEnter: () => completeOnboarding() })] }));
@@ -5,7 +5,7 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
5
5
  * Generic scrollable list that works reliably with Ink's layout.
6
6
  * Uses item-based slicing with dynamic height calculation.
7
7
  */
8
- import { Box, Text, useInput } from 'ink';
8
+ import { Box, Spacer, Text, useInput } from 'ink';
9
9
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
10
10
  export function ScrollableList({ autoScrollToBottom = true, availableHeight, estimateItemHeight = () => 1, isActive = true, items, keyExtractor, onScroll, renderItem, scrollStep = 1, showIndicator = true, }) {
11
11
  const [scrollOffset, setScrollOffset] = useState(0);
@@ -16,11 +16,7 @@ export function ScrollableList({ autoScrollToBottom = true, availableHeight, est
16
16
  return { visibleEndIndex: 0, visibleItems: [], visibleStartIndex: 0 };
17
17
  }
18
18
  // Calculate heights of all items
19
- const itemHeights = [];
20
- for (let i = 0; i < totalItems; i++) {
21
- const h = estimateItemHeight(items[i], i);
22
- itemHeights.push(h);
23
- }
19
+ const itemHeights = items.map((item, index) => estimateItemHeight(item, index));
24
20
  // Reserve space for indicators (1 line each)
25
21
  const indicatorSpace = showIndicator ? 2 : 0;
26
22
  const contentHeight = Math.max(1, availableHeight - indicatorSpace);
@@ -46,10 +42,16 @@ export function ScrollableList({ autoScrollToBottom = true, availableHeight, est
46
42
  const maxOffset = useMemo(() => {
47
43
  if (totalItems === 0)
48
44
  return 0;
49
- // Find the minimum start index that shows the last item
50
- let maxStart = totalItems - 1;
51
45
  const indicatorSpace = showIndicator ? 2 : 0;
52
46
  const contentHeight = Math.max(1, availableHeight - indicatorSpace);
47
+ // Calculate total height of all items
48
+ const totalHeight = items.reduce((sum, item, index) => sum + estimateItemHeight(item, index), 0);
49
+ // If all items fit, maxOffset should be 0
50
+ if (totalHeight <= contentHeight) {
51
+ return 0;
52
+ }
53
+ // Find the minimum start index that shows the last item
54
+ let maxStart = totalItems - 1;
53
55
  let accumulatedHeight = 0;
54
56
  for (let i = totalItems - 1; i >= 0; i--) {
55
57
  const h = estimateItemHeight(items[i], i);
@@ -114,8 +116,8 @@ export function ScrollableList({ autoScrollToBottom = true, availableHeight, est
114
116
  const canScrollDown = scrollOffset < maxOffset;
115
117
  const itemsAbove = visibleStartIndex;
116
118
  const itemsBelow = totalItems - visibleEndIndex;
117
- return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [showIndicator && canScrollUp && (_jsx(Box, { justifyContent: "center", children: _jsxs(Text, { dimColor: true, children: ["\u2191 ", itemsAbove, " more above"] }) })), visibleItems.map((item, idx) => {
119
+ return (_jsxs(Box, { flexDirection: "column", height: availableHeight, justifyContent: "space-between", overflowY: "hidden", width: "100%", children: [showIndicator && canScrollUp && (_jsx(Box, { justifyContent: "center", children: _jsxs(Text, { dimColor: true, children: ["\u2191 ", itemsAbove, " more above"] }) })), visibleItems.map((item, idx) => {
118
120
  const actualIndex = visibleStartIndex + idx;
119
121
  return _jsx(React.Fragment, { children: renderItem(item, actualIndex) }, keyExtractor(item, actualIndex));
120
- }), showIndicator && canScrollDown && (_jsx(Box, { justifyContent: "center", children: _jsxs(Text, { dimColor: true, children: ["\u2193 ", itemsBelow, " more below"] }) }))] }));
122
+ }), _jsx(Spacer, {}), showIndicator && canScrollDown && (_jsx(Box, { justifyContent: "center", children: _jsxs(Text, { dimColor: true, children: ["\u2193 ", itemsBelow, " more below"] }) }))] }));
121
123
  }
@@ -9,28 +9,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  */
10
10
  import { Box, Text, useInput } from 'ink';
11
11
  import { useEffect, useMemo, useRef } from 'react';
12
- import { useMode } from '../contexts/use-mode.js';
13
- import { useTheme } from '../contexts/use-theme.js';
12
+ import { useMode } from '../contexts/mode-context.js';
13
+ import { useTheme } from '../contexts/theme-context.js';
14
14
  import { useSlashCompletion } from '../hooks/index.js';
15
+ import { CommandDetails } from './command-details.js';
15
16
  const MAX_VISIBLE_ITEMS = 5;
16
- /**
17
- * Format usage string from args, flags, and subcommands
18
- */
19
- function formatUsage(label, args, flags, subCommands) {
20
- let usage = label;
21
- if (subCommands?.length) {
22
- usage += ' <subcommand>';
23
- }
24
- if (args?.length) {
25
- const argsStr = args.map((a) => (a.required ? `<${a.name}>` : `[${a.name}]`)).join(' ');
26
- usage += ` ${argsStr}`;
27
- }
28
- if (flags?.length) {
29
- const flagsStr = flags.map((f) => `[--${f.name}]`).join(' ');
30
- usage += ` ${flagsStr}`;
31
- }
32
- return usage;
33
- }
34
17
  export const Suggestions = ({ input, onInsert, onSelect }) => {
35
18
  const { theme: { colors }, } = useTheme();
36
19
  const { mode, setMode } = useMode();
@@ -64,21 +47,40 @@ export const Suggestions = ({ input, onInsert, onSelect }) => {
64
47
  setMode('console');
65
48
  }
66
49
  }, [mode, suggestions.length, isCommandAttempt, hasMatchedCommand, setMode]);
67
- // Calculate visible window based on selected index
50
+ // - No indicators: 5 items
51
+ // - One indicator (top OR bottom): 4 items + 1 indicator
52
+ // - Both indicators: 3 items + 2 indicators
68
53
  const { visibleSuggestions, windowStart } = useMemo(() => {
69
- if (suggestions.length <= MAX_VISIBLE_ITEMS) {
54
+ const totalItems = suggestions.length;
55
+ const totalHeight = MAX_VISIBLE_ITEMS; // 5 lines total
56
+ // All items fit, no indicators needed
57
+ if (totalItems <= totalHeight) {
70
58
  return { visibleSuggestions: suggestions, windowStart: 0 };
71
59
  }
72
- // Calculate window start to keep selected item visible
73
- let start = 0;
74
- if (activeIndex >= MAX_VISIBLE_ITEMS) {
75
- start = activeIndex - MAX_VISIBLE_ITEMS + 1;
60
+ let maxVisibleItems;
61
+ let start;
62
+ // Near start: no top indicator needed
63
+ if (activeIndex < 3) {
64
+ maxVisibleItems = totalHeight - 1; // 4 items + bottom indicator
65
+ start = 0;
66
+ }
67
+ // Near end: no bottom indicator needed
68
+ else if (activeIndex >= totalItems - 3) {
69
+ maxVisibleItems = totalHeight - 1; // top indicator + 4 items
70
+ start = Math.max(0, totalItems - maxVisibleItems);
71
+ }
72
+ // Middle: both indicators needed
73
+ else {
74
+ maxVisibleItems = totalHeight - 2; // top indicator + 3 items + bottom indicator
75
+ // Try to center activeIndex in the viewport
76
+ const centerOffset = Math.floor(maxVisibleItems / 2);
77
+ start = activeIndex - centerOffset;
78
+ // Adjust if we went past the end
79
+ const maxStart = totalItems - maxVisibleItems;
80
+ start = Math.min(start, maxStart);
76
81
  }
77
- // Ensure we don't go past the end
78
- const maxStart = suggestions.length - MAX_VISIBLE_ITEMS;
79
- start = Math.min(start, maxStart);
80
82
  return {
81
- visibleSuggestions: suggestions.slice(start, start + MAX_VISIBLE_ITEMS),
83
+ visibleSuggestions: suggestions.slice(start, start + maxVisibleItems),
82
84
  windowStart: start,
83
85
  };
84
86
  }, [suggestions, activeIndex]);
@@ -138,7 +140,7 @@ export const Suggestions = ({ input, onInsert, onSelect }) => {
138
140
  // Don't show when user is typing arguments for a known command
139
141
  if (suggestions.length === 0) {
140
142
  if (isCommandAttempt && !hasMatchedCommand && input.trim().length > 1) {
141
- return (_jsx(Box, { borderColor: colors.border, borderStyle: "single", paddingX: 1, children: _jsx(Text, { color: colors.dimText, children: "No commands found" }) }));
143
+ return (_jsx(Box, { borderColor: colors.border, borderStyle: "single", height: 7, paddingX: 1, children: _jsx(Text, { color: colors.dimText, children: "No commands found" }) }));
142
144
  }
143
145
  return null;
144
146
  }
@@ -147,16 +149,12 @@ export const Suggestions = ({ input, onInsert, onSelect }) => {
147
149
  const labelWidth = Math.max(maxLabelLength, 12);
148
150
  // Get the selected suggestion
149
151
  const selectedSuggestion = activeIndex >= 0 ? suggestions[activeIndex] : null;
150
- const hasDetails = selectedSuggestion &&
151
- (selectedSuggestion.args?.length || selectedSuggestion.flags?.length || selectedSuggestion.subCommands?.length);
152
152
  // Calculate if there are more items above/below
153
153
  const hasMoreAbove = windowStart > 0;
154
- const hasMoreBelow = windowStart + MAX_VISIBLE_ITEMS < suggestions.length;
155
- return (_jsxs(Box, { borderColor: colors.border, borderStyle: "single", flexDirection: "column", paddingX: 1, children: [hasMoreAbove && (_jsxs(Text, { color: colors.dimText, dimColor: true, children: ["\u2191 ", windowStart, " more above"] })), visibleSuggestions.map((suggestion, index) => {
156
- const actualIndex = windowStart + index;
157
- const isActive = actualIndex === activeIndex;
158
- return (_jsxs(Box, { children: [_jsxs(Text, { backgroundColor: isActive ? colors.dimText : undefined, color: colors.text, children: [isActive ? '❯ ' : ' ', suggestion.label.padEnd(labelWidth)] }), _jsxs(Text, { color: colors.dimText, children: [" ", suggestion.description || ''] })] }, suggestion.value));
159
- }), hasMoreBelow && (_jsxs(Text, { color: colors.dimText, dimColor: true, children: ["\u2193 ", suggestions.length - windowStart - MAX_VISIBLE_ITEMS, " more below"] })), hasDetails && (_jsxs(Box, { borderColor: colors.border, borderStyle: "single", borderTop: true, flexDirection: "column", marginTop: 0, children: [_jsxs(Text, { color: colors.text, children: ["Usage:", ' ', formatUsage(selectedSuggestion.label, selectedSuggestion.args, selectedSuggestion.flags, selectedSuggestion.subCommands)] }), selectedSuggestion.subCommands?.map((sub) => (_jsxs(Text, { color: colors.dimText, children: [' ', _jsx(Text, { color: colors.text, children: sub.name.padEnd(labelWidth + 2) }), ' ', sub.description] }, sub.name))), selectedSuggestion.args?.map((arg) => (_jsxs(Text, { color: colors.dimText, children: [' ', _jsx(Text, { color: colors.text, children: (arg.required ? `<${arg.name}>` : `[${arg.name}]`).padEnd(labelWidth + 2) }), ' ', arg.description] }, arg.name))), selectedSuggestion.flags?.map((flag) => (_jsxs(Text, { color: colors.dimText, children: [' ', _jsx(Text, { color: colors.text, children: (flag.type === 'file'
160
- ? `${flag.char || '@'}file`
161
- : (flag.char ? `-${flag.char}, ` : '') + `--${flag.name}`).padEnd(labelWidth + 2) }), ' ', flag.description, flag.default !== undefined && _jsxs(Text, { children: [" (default: ", String(flag.default), ")"] })] }, flag.name)))] }))] }));
154
+ const hasMoreBelow = windowStart + visibleSuggestions.length < suggestions.length;
155
+ return (_jsxs(Box, { borderColor: colors.border, borderStyle: "single", columnGap: 1, height: 7, paddingX: 1, children: [_jsxs(Box, { flexDirection: 'column', flexShrink: 0, children: [hasMoreAbove && (_jsxs(Text, { color: colors.dimText, dimColor: true, children: ["\u2191 ", windowStart, " more"] })), visibleSuggestions.map((suggestion, index) => {
156
+ const actualIndex = windowStart + index;
157
+ const isActive = actualIndex === activeIndex;
158
+ return (_jsx(Box, { children: _jsxs(Text, { backgroundColor: isActive ? colors.dimText : undefined, color: colors.text, children: [isActive ? '❯ ' : ' ', suggestion.label.padEnd(labelWidth)] }) }, suggestion.value));
159
+ }), hasMoreBelow && (_jsxs(Text, { color: colors.dimText, dimColor: true, children: ["\u2193 ", suggestions.length - windowStart - visibleSuggestions.length, " more"] }))] }), _jsx(CommandDetails, { labelWidth: labelWidth, selectedSuggestion: selectedSuggestion })] }));
162
160
  };
@@ -2,9 +2,10 @@
2
2
  * Tab Bar Component
3
3
  */
4
4
  import React from 'react';
5
- import type { TabId } from '../types.js';
5
+ import type { Tab, TabId } from '../types.js';
6
6
  interface TabBarProps {
7
7
  activeTab: TabId;
8
+ tabs: Tab[];
8
9
  }
9
10
  export declare const TabBar: React.FC<TabBarProps>;
10
11
  export {};
@@ -4,9 +4,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  */
5
5
  import { Box, Text } from 'ink';
6
6
  import React from 'react';
7
- import { TABS } from '../constants.js';
8
- import { useTheme } from '../contexts/use-theme.js';
9
- export const TabBar = ({ activeTab }) => {
7
+ import { useTheme } from '../contexts/theme-context.js';
8
+ export const TabBar = ({ activeTab, tabs = [] }) => {
10
9
  const { theme: { colors }, } = useTheme();
11
- return (_jsxs(Box, { alignItems: "flex-end", paddingX: 1, width: "100%", children: [_jsx(Box, { borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", height: "100%", width: 2 }), TABS.map((tab) => (_jsxs(React.Fragment, { children: [_jsx(Box, { borderBottomColor: activeTab === tab.id ? colors.primary : colors.border, borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", children: _jsx(Text, { children: tab.label }) }), _jsx(Box, { borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", height: "100%", width: 6 })] }, tab.id))), _jsx(Box, { borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", flexGrow: 1, height: "100%" })] }));
10
+ return (_jsxs(Box, { alignItems: "flex-end", paddingX: 1, width: "100%", children: [_jsx(Box, { borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", height: "100%", width: 2 }), tabs.map((tab) => (_jsxs(React.Fragment, { children: [_jsx(Box, { borderBottomColor: activeTab === tab.id ? colors.primary : colors.border, borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", children: _jsx(Text, { children: tab.label }) }), _jsx(Box, { borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", height: "100%", width: 6 })] }, tab.id))), _jsx(Box, { borderColor: colors.border, borderLeft: false, borderRight: false, borderStyle: "single", flexGrow: 1, height: "100%" })] }));
12
11
  };
@@ -3,9 +3,4 @@
3
3
  */
4
4
  import type { Tab } from './types.js';
5
5
  export declare const TABS: Tab[];
6
- export declare const LAYOUT: {
7
- readonly footerHeight: 2;
8
- readonly headerHeight: 4;
9
- readonly tabBarHeight: 2;
10
- };
11
6
  export declare const DEFAULT_TAB: "activity";
@@ -5,9 +5,4 @@ export const TABS = [
5
5
  { id: 'activity', label: 'Activity' },
6
6
  { id: 'console', label: 'Console' },
7
7
  ];
8
- export const LAYOUT = {
9
- footerHeight: 2,
10
- headerHeight: 4,
11
- tabBarHeight: 2,
12
- };
13
8
  export const DEFAULT_TAB = 'activity';
@@ -12,10 +12,11 @@ import { OAuthService } from '../../infra/auth/oauth-service.js';
12
12
  import { OidcDiscoveryService } from '../../infra/auth/oidc-discovery-service.js';
13
13
  import { SystemBrowserLauncher } from '../../infra/browser/system-browser-launcher.js';
14
14
  import { CallbackHandler } from '../../infra/http/callback-handler.js';
15
- import { FileGlobalConfigStore } from "../../infra/storage/file-global-config-store.js";
15
+ import { FileGlobalConfigStore } from '../../infra/storage/file-global-config-store.js';
16
16
  import { MixpanelTrackingService } from '../../infra/tracking/mixpanel-tracking-service.js';
17
17
  import { LoginUseCase } from '../../infra/usecase/login-use-case.js';
18
18
  import { HttpUserService } from '../../infra/user/http-user-service.js';
19
+ import { useAuthPolling } from '../hooks/use-auth-polling.js';
19
20
  import { useServices } from './services-context.js';
20
21
  const AuthContext = createContext(undefined);
21
22
  /**
@@ -129,6 +130,12 @@ export function AuthProvider({ children, initialAuthToken, initialBrvConfig }) {
129
130
  setIsInitialConfigLoaded(true);
130
131
  });
131
132
  }, [reloadBrvConfig]);
133
+ // Auth state polling - check token validity and refresh if needed
134
+ useAuthPolling({
135
+ authToken,
136
+ onTokenChange: setAuthToken,
137
+ tokenStore,
138
+ });
132
139
  // Memoize context value
133
140
  const value = useMemo(() => ({
134
141
  authState,
@@ -140,7 +147,7 @@ export function AuthProvider({ children, initialAuthToken, initialBrvConfig }) {
140
147
  login,
141
148
  loginOutput,
142
149
  reloadAuth,
143
- reloadBrvConfig
150
+ reloadBrvConfig,
144
151
  }), [authToken, brvConfig, isInitialConfigLoaded, isLoggingIn, loginOutput, authState, isAuthorized, login, reloadAuth]);
145
152
  return _jsx(AuthContext.Provider, { value: value, children: children });
146
153
  }
@@ -18,12 +18,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
18
18
  */
19
19
  import { createContext, useContext, useEffect, useMemo, useState } from 'react';
20
20
  import { load } from '../../infra/repl/commands/index.js';
21
- import { useSlashCommandProcessor } from '../hooks/index.js';
21
+ import { useSlashCommandProcessor, useTerminalBreakpoint } from '../hooks/index.js';
22
22
  import { useServices } from './services-context.js';
23
23
  const CommandsContext = createContext(undefined);
24
24
  export function CommandsProvider({ children }) {
25
25
  const [commands, setCommands] = useState([]);
26
26
  const { version } = useServices();
27
+ const { breakpoint, columns, rows } = useTerminalBreakpoint();
27
28
  useEffect(() => {
28
29
  const abortController = new AbortController();
29
30
  async function loadCommands() {
@@ -35,9 +36,8 @@ export function CommandsProvider({ children }) {
35
36
  };
36
37
  }, []);
37
38
  const commandContext = useMemo(() => ({
38
- slashCommands: commands,
39
39
  version,
40
- }), [commands, version]);
40
+ }), [breakpoint, columns, rows, version]);
41
41
  const { handleSlashCommand } = useSlashCommandProcessor(commandContext, commands);
42
42
  const contextValue = useMemo(() => ({
43
43
  commands,
@@ -2,5 +2,10 @@
2
2
  * TUI Contexts
3
3
  */
4
4
  export * from './auth-context.js';
5
- export * from './consumer.js';
5
+ export * from './commands-context.js';
6
+ export * from './mode-context.js';
7
+ export * from './onboarding-context.js';
6
8
  export * from './services-context.js';
9
+ export * from './tasks-context.js';
10
+ export * from './theme-context.js';
11
+ export * from './transport-context.js';
@@ -2,5 +2,10 @@
2
2
  * TUI Contexts
3
3
  */
4
4
  export * from './auth-context.js';
5
- export * from './consumer.js';
5
+ export * from './commands-context.js';
6
+ export * from './mode-context.js';
7
+ export * from './onboarding-context.js';
6
8
  export * from './services-context.js';
9
+ export * from './tasks-context.js';
10
+ export * from './theme-context.js';
11
+ export * from './transport-context.js';
@@ -2,7 +2,7 @@
2
2
  * Onboarding Context
3
3
  *
4
4
  * Global context for managing onboarding state and step derivation.
5
- * State is derived from brvConfig and sessionExecutions.
5
+ * State is derived from brvConfig and tasks from transport events.
6
6
  *
7
7
  * Usage:
8
8
  * ```tsx
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  * Onboarding Context
4
4
  *
5
5
  * Global context for managing onboarding state and step derivation.
6
- * State is derived from brvConfig and sessionExecutions.
6
+ * State is derived from brvConfig and tasks from transport events.
7
7
  *
8
8
  * Usage:
9
9
  * ```tsx
@@ -12,8 +12,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
12
12
  */
13
13
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
14
14
  import { useAuth } from './auth-context.js';
15
- import { useConsumer } from './index.js';
16
15
  import { useServices } from './services-context.js';
16
+ import { useTasks } from './tasks-context.js';
17
17
  const OnboardingContext = createContext(undefined);
18
18
  /**
19
19
  * Provider for onboarding state
@@ -31,7 +31,7 @@ const OnboardingContext = createContext(undefined);
31
31
  const ONBOARDING_COOLDOWN_MS = 7 * 24 * 60 * 60 * 1000;
32
32
  export function OnboardingProvider({ children }) {
33
33
  const { brvConfig, isInitialConfigLoaded } = useAuth();
34
- const { sessionExecutions } = useConsumer();
34
+ const { tasks } = useTasks();
35
35
  const { onboardingPreferenceStore, trackingService } = useServices();
36
36
  const isInitialized = brvConfig !== undefined;
37
37
  // Track if we've already checked initial config state
@@ -95,16 +95,16 @@ export function OnboardingProvider({ children }) {
95
95
  trackingService.track('onboarding:query_completed');
96
96
  }
97
97
  }, [trackingService]);
98
- // Check for completed curate/query executions in session
98
+ // Check for completed curate/query tasks in session
99
99
  const { hasCurated, hasQueried } = useMemo(() => {
100
100
  let curateCompleted = false;
101
101
  let queryCompleted = false;
102
- for (const { execution } of sessionExecutions) {
103
- if (execution.status === 'completed') {
104
- if (execution.type === 'curate') {
102
+ for (const task of tasks.values()) {
103
+ if (task.status === 'completed') {
104
+ if (task.type === 'curate') {
105
105
  curateCompleted = true;
106
106
  }
107
- else if (execution.type === 'query') {
107
+ else if (task.type === 'query') {
108
108
  queryCompleted = true;
109
109
  }
110
110
  }
@@ -113,7 +113,7 @@ export function OnboardingProvider({ children }) {
113
113
  break;
114
114
  }
115
115
  return { hasCurated: curateCompleted, hasQueried: queryCompleted };
116
- }, [sessionExecutions]);
116
+ }, [tasks]);
117
117
  // Derive current step (considering acknowledgment)
118
118
  // Stay on curate/query step until user acknowledges the completion
119
119
  const currentStep = useMemo(() => {
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+ import type { TaskErrorData, ToolErrorType } from '../../core/domain/transport/schemas.js';
3
+ import { TaskStats } from '../types/ui.js';
4
+ /**
5
+ * Task status derived from task lifecycle events.
6
+ */
7
+ export type TaskStatus = 'cancelled' | 'completed' | 'created' | 'error' | 'started';
8
+ /**
9
+ * Tool call tracking with status from toolResult.
10
+ */
11
+ export type ToolCallEvent = {
12
+ args: Record<string, unknown>;
13
+ callId?: string;
14
+ error?: string;
15
+ errorType?: ToolErrorType;
16
+ result?: unknown;
17
+ sessionId: string;
18
+ status: 'completed' | 'error' | 'running';
19
+ toolName: string;
20
+ };
21
+ /**
22
+ * Task data aggregated from transport events.
23
+ */
24
+ export type Task = {
25
+ /** Task completion timestamp */
26
+ completedAt?: number;
27
+ /** Task content/prompt */
28
+ content: string;
29
+ /** Task creation timestamp */
30
+ createdAt: number;
31
+ /** Error data if task failed */
32
+ error?: TaskErrorData;
33
+ /** File paths for curate --files */
34
+ files?: string[];
35
+ /** Input of query/curate */
36
+ input: string;
37
+ /** Result string if task completed */
38
+ result?: string;
39
+ /** Session ID from LLM events */
40
+ sessionId?: string;
41
+ /** Task start timestamp */
42
+ startedAt?: number;
43
+ /** Current task status */
44
+ status: TaskStatus;
45
+ /** Unique task identifier */
46
+ taskId: string;
47
+ /** Tool calls executed during task */
48
+ toolCalls: ToolCallEvent[];
49
+ /** Task type */
50
+ type: 'curate' | 'query';
51
+ };
52
+ /**
53
+ * Context value for tasks state.
54
+ */
55
+ export type TasksContextValue = {
56
+ /** Clear all tasks from memory */
57
+ clearTasks: () => void;
58
+ /** Get a specific task by ID */
59
+ getTask: (taskId: string) => Task | undefined;
60
+ /** Transport statistics */
61
+ stats: TaskStats;
62
+ /** Map of all tasks by taskId */
63
+ tasks: Map<string, Task>;
64
+ };
65
+ /**
66
+ * Provider component that subscribes to task events and maintains task state.
67
+ * Tracks task lifecycle and LLM tool calls for all tasks.
68
+ *
69
+ * Event Flow:
70
+ * 1. task:created → Create task with 'created' status
71
+ * 2. task:started → Update to 'started' status
72
+ * 3. llmservice:toolCall → Add tool call with 'running' status
73
+ * 4. llmservice:toolResult → Update tool call status to 'completed' or 'error'
74
+ * 5. llmservice:response → Update task result content from LLM response
75
+ * 6. task:completed | task:error | task:cancelled → Terminal state
76
+ */
77
+ export declare function TasksProvider({ children }: {
78
+ children: React.ReactNode;
79
+ }): React.ReactElement;
80
+ /**
81
+ * Hook to access tasks context.
82
+ * Must be used within a TasksProvider.
83
+ */
84
+ export declare function useTasks(): TasksContextValue;