byterover-cli 2.6.0 → 3.0.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 (316) hide show
  1. package/.env.production +1 -0
  2. package/README.md +240 -14
  3. package/dist/agent/core/domain/knowledge/conflict-detector.d.ts +38 -0
  4. package/dist/agent/core/domain/knowledge/conflict-detector.js +71 -0
  5. package/dist/agent/core/domain/knowledge/conflict-resolver.d.ts +17 -0
  6. package/dist/agent/core/domain/knowledge/conflict-resolver.js +118 -0
  7. package/dist/agent/core/domain/knowledge/utils.d.ts +4 -0
  8. package/dist/agent/core/domain/knowledge/utils.js +6 -0
  9. package/dist/agent/core/interfaces/i-curate-service.d.ts +6 -0
  10. package/dist/agent/infra/tools/implementations/curate-tool.d.ts +67 -34
  11. package/dist/agent/infra/tools/implementations/curate-tool.js +294 -47
  12. package/dist/agent/resources/prompts/system-prompt.yml +15 -8
  13. package/dist/agent/resources/tools/code_exec.txt +3 -0
  14. package/dist/agent/resources/tools/curate.txt +12 -3
  15. package/dist/oclif/commands/connectors/install.d.ts +2 -1
  16. package/dist/oclif/commands/connectors/install.js +38 -3
  17. package/dist/oclif/commands/curate/index.d.ts +18 -0
  18. package/dist/oclif/commands/curate/index.js +78 -1
  19. package/dist/oclif/commands/init.d.ts +12 -0
  20. package/dist/oclif/commands/init.js +75 -0
  21. package/dist/oclif/commands/locations.js +1 -1
  22. package/dist/oclif/commands/providers/connect.d.ts +31 -1
  23. package/dist/oclif/commands/providers/connect.js +307 -27
  24. package/dist/oclif/commands/pull.d.ts +1 -0
  25. package/dist/oclif/commands/pull.js +7 -0
  26. package/dist/oclif/commands/push.d.ts +1 -0
  27. package/dist/oclif/commands/push.js +8 -0
  28. package/dist/oclif/commands/review/approve.d.ts +17 -0
  29. package/dist/oclif/commands/review/approve.js +37 -0
  30. package/dist/oclif/commands/review/base-review-decision.d.ts +18 -0
  31. package/dist/oclif/commands/review/base-review-decision.js +71 -0
  32. package/dist/oclif/commands/review/pending.d.ts +13 -0
  33. package/dist/oclif/commands/review/pending.js +94 -0
  34. package/dist/oclif/commands/review/reject.d.ts +17 -0
  35. package/dist/oclif/commands/review/reject.js +38 -0
  36. package/dist/oclif/commands/space/list.d.ts +2 -2
  37. package/dist/oclif/commands/space/list.js +13 -35
  38. package/dist/oclif/commands/space/switch.d.ts +2 -7
  39. package/dist/oclif/commands/space/switch.js +13 -56
  40. package/dist/oclif/commands/status.d.ts +1 -0
  41. package/dist/oclif/commands/status.js +11 -1
  42. package/dist/oclif/commands/vc/add.d.ts +7 -0
  43. package/dist/oclif/commands/vc/add.js +29 -0
  44. package/dist/oclif/commands/vc/branch.d.ts +15 -0
  45. package/dist/oclif/commands/vc/branch.js +70 -0
  46. package/dist/oclif/commands/vc/checkout.d.ts +14 -0
  47. package/dist/oclif/commands/vc/checkout.js +47 -0
  48. package/dist/oclif/commands/vc/clone.d.ts +9 -0
  49. package/dist/oclif/commands/vc/clone.js +61 -0
  50. package/dist/oclif/commands/vc/commit.d.ts +10 -0
  51. package/dist/oclif/commands/vc/commit.js +32 -0
  52. package/dist/oclif/commands/vc/config.d.ts +10 -0
  53. package/dist/oclif/commands/vc/config.js +30 -0
  54. package/dist/oclif/commands/vc/fetch.d.ts +10 -0
  55. package/dist/oclif/commands/vc/fetch.js +42 -0
  56. package/dist/oclif/commands/vc/index.d.ts +6 -0
  57. package/dist/oclif/commands/vc/index.js +8 -0
  58. package/dist/oclif/commands/vc/init.d.ts +6 -0
  59. package/dist/oclif/commands/vc/init.js +25 -0
  60. package/dist/oclif/commands/vc/log.d.ts +13 -0
  61. package/dist/oclif/commands/vc/log.js +48 -0
  62. package/dist/oclif/commands/vc/merge.d.ts +19 -0
  63. package/dist/oclif/commands/vc/merge.js +130 -0
  64. package/dist/oclif/commands/vc/pull.d.ts +13 -0
  65. package/dist/oclif/commands/vc/pull.js +60 -0
  66. package/dist/oclif/commands/vc/push.d.ts +13 -0
  67. package/dist/oclif/commands/vc/push.js +60 -0
  68. package/dist/oclif/commands/vc/remote/add.d.ts +10 -0
  69. package/dist/oclif/commands/vc/remote/add.js +30 -0
  70. package/dist/oclif/commands/vc/remote/index.d.ts +6 -0
  71. package/dist/oclif/commands/vc/remote/index.js +16 -0
  72. package/dist/oclif/commands/vc/remote/set-url.d.ts +10 -0
  73. package/dist/oclif/commands/vc/remote/set-url.js +30 -0
  74. package/dist/oclif/commands/vc/reset.d.ts +13 -0
  75. package/dist/oclif/commands/vc/reset.js +62 -0
  76. package/dist/oclif/commands/vc/status.d.ts +8 -0
  77. package/dist/oclif/commands/vc/status.js +106 -0
  78. package/dist/oclif/hooks/init/validate-brv-config.d.ts +26 -0
  79. package/dist/oclif/hooks/init/validate-brv-config.js +62 -0
  80. package/dist/oclif/lib/daemon-client.d.ts +2 -0
  81. package/dist/oclif/lib/daemon-client.js +36 -10
  82. package/dist/oclif/lib/prompt-utils.d.ts +43 -0
  83. package/dist/oclif/lib/prompt-utils.js +84 -0
  84. package/dist/oclif/lib/spinner.d.ts +8 -0
  85. package/dist/oclif/lib/spinner.js +23 -0
  86. package/dist/oclif/lib/task-client.d.ts +5 -0
  87. package/dist/oclif/lib/task-client.js +15 -2
  88. package/dist/server/config/environment.d.ts +2 -0
  89. package/dist/server/config/environment.js +2 -0
  90. package/dist/server/constants.d.ts +3 -0
  91. package/dist/server/constants.js +9 -0
  92. package/dist/server/core/domain/entities/auth-token.d.ts +2 -0
  93. package/dist/server/core/domain/entities/auth-token.js +7 -1
  94. package/dist/server/core/domain/entities/curate-log-entry.d.ts +11 -0
  95. package/dist/server/core/domain/entities/space.d.ts +4 -0
  96. package/dist/server/core/domain/entities/space.js +8 -0
  97. package/dist/server/core/domain/entities/team.d.ts +2 -0
  98. package/dist/server/core/domain/entities/team.js +4 -0
  99. package/dist/server/core/domain/errors/git-error.d.ts +6 -0
  100. package/dist/server/core/domain/errors/git-error.js +12 -0
  101. package/dist/server/core/domain/errors/task-error.d.ts +4 -0
  102. package/dist/server/core/domain/errors/task-error.js +8 -0
  103. package/dist/server/core/domain/errors/vc-error.d.ts +5 -0
  104. package/dist/server/core/domain/errors/vc-error.js +8 -0
  105. package/dist/server/core/domain/knowledge/markdown-writer.d.ts +4 -1
  106. package/dist/server/core/domain/knowledge/markdown-writer.js +37 -7
  107. package/dist/server/core/domain/transport/schemas.d.ts +6 -6
  108. package/dist/server/core/interfaces/context-tree/i-context-tree-service.d.ts +11 -0
  109. package/dist/server/core/interfaces/process/i-task-lifecycle-hook.d.ts +6 -0
  110. package/dist/server/core/interfaces/services/i-git-service.d.ts +234 -0
  111. package/dist/server/core/interfaces/services/i-git-service.js +1 -0
  112. package/dist/server/core/interfaces/storage/i-curate-log-store.d.ts +5 -0
  113. package/dist/server/core/interfaces/storage/i-review-backup-store.d.ts +19 -0
  114. package/dist/server/core/interfaces/storage/i-review-backup-store.js +1 -0
  115. package/dist/server/core/interfaces/vc/i-vc-git-config-store.d.ts +8 -0
  116. package/dist/server/core/interfaces/vc/i-vc-git-config-store.js +1 -0
  117. package/dist/server/infra/config/auto-init.d.ts +0 -2
  118. package/dist/server/infra/config/auto-init.js +0 -1
  119. package/dist/server/infra/context-tree/file-context-tree-service.d.ts +2 -0
  120. package/dist/server/infra/context-tree/file-context-tree-service.js +13 -0
  121. package/dist/server/infra/daemon/brv-server.js +23 -3
  122. package/dist/server/infra/git/cogit-url.d.ts +17 -0
  123. package/dist/server/infra/git/cogit-url.js +39 -0
  124. package/dist/server/infra/git/git-http-wrapper.d.ts +20 -0
  125. package/dist/server/infra/git/git-http-wrapper.js +334 -0
  126. package/dist/server/infra/git/isomorphic-git-service.d.ts +78 -0
  127. package/dist/server/infra/git/isomorphic-git-service.js +983 -0
  128. package/dist/server/infra/http/review-api-handler.d.ts +13 -0
  129. package/dist/server/infra/http/review-api-handler.js +286 -0
  130. package/dist/server/infra/http/review-ui.d.ts +7 -0
  131. package/dist/server/infra/http/review-ui.js +606 -0
  132. package/dist/server/infra/mcp/tools/brv-curate-tool.d.ts +2 -2
  133. package/dist/server/infra/process/curate-log-handler.d.ts +18 -2
  134. package/dist/server/infra/process/curate-log-handler.js +50 -13
  135. package/dist/server/infra/process/feature-handlers.js +41 -1
  136. package/dist/server/infra/process/task-router.js +16 -0
  137. package/dist/server/infra/space/http-space-service.js +2 -0
  138. package/dist/server/infra/storage/file-curate-log-store.d.ts +10 -0
  139. package/dist/server/infra/storage/file-curate-log-store.js +35 -0
  140. package/dist/server/infra/storage/file-review-backup-store.d.ts +29 -0
  141. package/dist/server/infra/storage/file-review-backup-store.js +121 -0
  142. package/dist/server/infra/transport/handlers/auth-handler.js +9 -5
  143. package/dist/server/infra/transport/handlers/handler-types.d.ts +9 -0
  144. package/dist/server/infra/transport/handlers/handler-types.js +11 -0
  145. package/dist/server/infra/transport/handlers/index.d.ts +4 -0
  146. package/dist/server/infra/transport/handlers/index.js +2 -0
  147. package/dist/server/infra/transport/handlers/init-handler.d.ts +1 -0
  148. package/dist/server/infra/transport/handlers/init-handler.js +13 -1
  149. package/dist/server/infra/transport/handlers/pull-handler.d.ts +3 -0
  150. package/dist/server/infra/transport/handlers/pull-handler.js +5 -1
  151. package/dist/server/infra/transport/handlers/push-handler.d.ts +20 -0
  152. package/dist/server/infra/transport/handlers/push-handler.js +116 -14
  153. package/dist/server/infra/transport/handlers/reset-handler.d.ts +11 -0
  154. package/dist/server/infra/transport/handlers/reset-handler.js +37 -1
  155. package/dist/server/infra/transport/handlers/review-handler.d.ts +35 -0
  156. package/dist/server/infra/transport/handlers/review-handler.js +162 -0
  157. package/dist/server/infra/transport/handlers/space-handler.d.ts +3 -0
  158. package/dist/server/infra/transport/handlers/space-handler.js +4 -1
  159. package/dist/server/infra/transport/handlers/status-handler.d.ts +5 -0
  160. package/dist/server/infra/transport/handlers/status-handler.js +51 -16
  161. package/dist/server/infra/transport/handlers/vc-handler.d.ts +100 -0
  162. package/dist/server/infra/transport/handlers/vc-handler.js +1050 -0
  163. package/dist/server/infra/transport/socket-io-transport-server.d.ts +7 -0
  164. package/dist/server/infra/transport/socket-io-transport-server.js +12 -1
  165. package/dist/server/infra/transport/transport-connector.d.ts +1 -1
  166. package/dist/server/infra/transport/transport-connector.js +2 -1
  167. package/dist/server/infra/vc/file-vc-git-config-store.d.ts +11 -0
  168. package/dist/server/infra/vc/file-vc-git-config-store.js +43 -0
  169. package/dist/server/templates/skill/SKILL.md +167 -33
  170. package/dist/server/utils/curate-result-parser.d.ts +64 -0
  171. package/dist/server/utils/curate-result-parser.js +8 -0
  172. package/dist/server/utils/gitignore.d.ts +9 -0
  173. package/dist/server/utils/gitignore.js +47 -0
  174. package/dist/shared/transport/events/index.d.ts +6 -0
  175. package/dist/shared/transport/events/index.js +3 -0
  176. package/dist/shared/transport/events/init-events.d.ts +8 -0
  177. package/dist/shared/transport/events/init-events.js +1 -0
  178. package/dist/shared/transport/events/push-events.d.ts +6 -0
  179. package/dist/shared/transport/events/review-events.d.ts +41 -0
  180. package/dist/shared/transport/events/review-events.js +5 -0
  181. package/dist/shared/transport/events/vc-events.d.ts +257 -0
  182. package/dist/shared/transport/events/vc-events.js +67 -0
  183. package/dist/shared/transport/types/dto.d.ts +6 -1
  184. package/dist/tui/app/pages/init-project-page.d.ts +9 -0
  185. package/dist/tui/app/pages/init-project-page.js +54 -0
  186. package/dist/tui/app/pages/protected-routes.js +14 -6
  187. package/dist/tui/components/index.d.ts +0 -2
  188. package/dist/tui/components/index.js +0 -1
  189. package/dist/tui/features/activity/hooks/use-activity-logs.js +7 -1
  190. package/dist/tui/features/commands/definitions/index.js +3 -0
  191. package/dist/tui/features/commands/definitions/space-list.js +9 -18
  192. package/dist/tui/features/commands/definitions/space-switch.js +10 -6
  193. package/dist/tui/features/commands/definitions/vc-add.d.ts +2 -0
  194. package/dist/tui/features/commands/definitions/vc-add.js +15 -0
  195. package/dist/tui/features/commands/definitions/vc-branch.d.ts +2 -0
  196. package/dist/tui/features/commands/definitions/vc-branch.js +33 -0
  197. package/dist/tui/features/commands/definitions/vc-checkout.d.ts +2 -0
  198. package/dist/tui/features/commands/definitions/vc-checkout.js +32 -0
  199. package/dist/tui/features/commands/definitions/vc-clone.d.ts +2 -0
  200. package/dist/tui/features/commands/definitions/vc-clone.js +18 -0
  201. package/dist/tui/features/commands/definitions/vc-commit.d.ts +2 -0
  202. package/dist/tui/features/commands/definitions/vc-commit.js +32 -0
  203. package/dist/tui/features/commands/definitions/vc-config.d.ts +2 -0
  204. package/dist/tui/features/commands/definitions/vc-config.js +40 -0
  205. package/dist/tui/features/commands/definitions/vc-fetch.d.ts +2 -0
  206. package/dist/tui/features/commands/definitions/vc-fetch.js +37 -0
  207. package/dist/tui/features/commands/definitions/vc-init.d.ts +2 -0
  208. package/dist/tui/features/commands/definitions/vc-init.js +11 -0
  209. package/dist/tui/features/commands/definitions/vc-log.d.ts +2 -0
  210. package/dist/tui/features/commands/definitions/vc-log.js +25 -0
  211. package/dist/tui/features/commands/definitions/vc-merge.d.ts +2 -0
  212. package/dist/tui/features/commands/definitions/vc-merge.js +48 -0
  213. package/dist/tui/features/commands/definitions/vc-pull.d.ts +2 -0
  214. package/dist/tui/features/commands/definitions/vc-pull.js +42 -0
  215. package/dist/tui/features/commands/definitions/vc-push.d.ts +2 -0
  216. package/dist/tui/features/commands/definitions/vc-push.js +38 -0
  217. package/dist/tui/features/commands/definitions/vc-remote.d.ts +2 -0
  218. package/dist/tui/features/commands/definitions/vc-remote.js +57 -0
  219. package/dist/tui/features/commands/definitions/vc-reset.d.ts +2 -0
  220. package/dist/tui/features/commands/definitions/vc-reset.js +35 -0
  221. package/dist/tui/features/commands/definitions/vc-status.d.ts +2 -0
  222. package/dist/tui/features/commands/definitions/vc-status.js +11 -0
  223. package/dist/tui/features/commands/definitions/vc.d.ts +2 -0
  224. package/dist/tui/features/commands/definitions/vc.js +36 -0
  225. package/dist/tui/features/commands/hooks/use-slash-command-processor.js +5 -5
  226. package/dist/tui/features/log/api/execute-log.d.ts +8 -0
  227. package/dist/tui/features/log/api/execute-log.js +13 -0
  228. package/dist/tui/features/log/components/log-flow.d.ts +14 -0
  229. package/dist/tui/features/log/components/log-flow.js +29 -0
  230. package/dist/tui/features/log/utils/format-log.d.ts +3 -0
  231. package/dist/tui/features/log/utils/format-log.js +42 -0
  232. package/dist/tui/features/onboarding/hooks/use-app-view-mode.d.ts +9 -5
  233. package/dist/tui/features/onboarding/hooks/use-app-view-mode.js +12 -5
  234. package/dist/tui/features/push/components/push-flow.js +9 -2
  235. package/dist/tui/features/reset/components/reset-flow.js +2 -1
  236. package/dist/tui/features/status/components/status-view.js +2 -1
  237. package/dist/tui/features/status/utils/format-status.js +9 -0
  238. package/dist/tui/features/tasks/hooks/use-task-subscriptions.js +11 -0
  239. package/dist/tui/features/tasks/stores/tasks-store.d.ts +10 -0
  240. package/dist/tui/features/tasks/stores/tasks-store.js +16 -0
  241. package/dist/tui/features/vc/add/api/execute-vc-add.d.ts +8 -0
  242. package/dist/tui/features/vc/add/api/execute-vc-add.js +13 -0
  243. package/dist/tui/features/vc/add/components/vc-add-flow.d.ts +7 -0
  244. package/dist/tui/features/vc/add/components/vc-add-flow.js +35 -0
  245. package/dist/tui/features/vc/branch/api/execute-vc-branch.d.ts +8 -0
  246. package/dist/tui/features/vc/branch/api/execute-vc-branch.js +13 -0
  247. package/dist/tui/features/vc/branch/components/vc-branch-flow.d.ts +8 -0
  248. package/dist/tui/features/vc/branch/components/vc-branch-flow.js +53 -0
  249. package/dist/tui/features/vc/branch/utils/format-branch.d.ts +4 -0
  250. package/dist/tui/features/vc/branch/utils/format-branch.js +12 -0
  251. package/dist/tui/features/vc/checkout/api/execute-vc-checkout.d.ts +8 -0
  252. package/dist/tui/features/vc/checkout/api/execute-vc-checkout.js +13 -0
  253. package/dist/tui/features/vc/checkout/components/vc-checkout-flow.d.ts +8 -0
  254. package/dist/tui/features/vc/checkout/components/vc-checkout-flow.js +33 -0
  255. package/dist/tui/features/vc/clone/api/execute-vc-clone.d.ts +8 -0
  256. package/dist/tui/features/vc/clone/api/execute-vc-clone.js +13 -0
  257. package/dist/tui/features/vc/clone/components/vc-clone-flow.d.ts +7 -0
  258. package/dist/tui/features/vc/clone/components/vc-clone-flow.js +79 -0
  259. package/dist/tui/features/vc/commit/api/execute-vc-commit.d.ts +8 -0
  260. package/dist/tui/features/vc/commit/api/execute-vc-commit.js +13 -0
  261. package/dist/tui/features/vc/commit/components/vc-commit-flow.d.ts +7 -0
  262. package/dist/tui/features/vc/commit/components/vc-commit-flow.js +29 -0
  263. package/dist/tui/features/vc/config/api/execute-vc-config.d.ts +8 -0
  264. package/dist/tui/features/vc/config/api/execute-vc-config.js +13 -0
  265. package/dist/tui/features/vc/config/components/vc-config-flow.d.ts +9 -0
  266. package/dist/tui/features/vc/config/components/vc-config-flow.js +30 -0
  267. package/dist/tui/features/vc/fetch/api/execute-vc-fetch.d.ts +8 -0
  268. package/dist/tui/features/vc/fetch/api/execute-vc-fetch.js +13 -0
  269. package/dist/tui/features/vc/fetch/components/vc-fetch-flow.d.ts +8 -0
  270. package/dist/tui/features/vc/fetch/components/vc-fetch-flow.js +75 -0
  271. package/dist/tui/features/vc/init/api/execute-vc-init.d.ts +8 -0
  272. package/dist/tui/features/vc/init/api/execute-vc-init.js +13 -0
  273. package/dist/tui/features/vc/init/components/vc-init-flow.d.ts +10 -0
  274. package/dist/tui/features/vc/init/components/vc-init-flow.js +37 -0
  275. package/dist/tui/features/vc/merge/api/execute-vc-merge.d.ts +8 -0
  276. package/dist/tui/features/vc/merge/api/execute-vc-merge.js +13 -0
  277. package/dist/tui/features/vc/merge/components/vc-merge-flow.d.ts +11 -0
  278. package/dist/tui/features/vc/merge/components/vc-merge-flow.js +72 -0
  279. package/dist/tui/features/vc/pull/api/execute-vc-pull.d.ts +8 -0
  280. package/dist/tui/features/vc/pull/api/execute-vc-pull.js +13 -0
  281. package/dist/tui/features/vc/pull/components/vc-pull-flow.d.ts +9 -0
  282. package/dist/tui/features/vc/pull/components/vc-pull-flow.js +83 -0
  283. package/dist/tui/features/vc/push/api/execute-vc-push.d.ts +8 -0
  284. package/dist/tui/features/vc/push/api/execute-vc-push.js +13 -0
  285. package/dist/tui/features/vc/push/components/vc-push-flow.d.ts +8 -0
  286. package/dist/tui/features/vc/push/components/vc-push-flow.js +83 -0
  287. package/dist/tui/features/vc/remote/api/execute-vc-remote.d.ts +8 -0
  288. package/dist/tui/features/vc/remote/api/execute-vc-remote.js +13 -0
  289. package/dist/tui/features/vc/remote/components/vc-remote-flow.d.ts +9 -0
  290. package/dist/tui/features/vc/remote/components/vc-remote-flow.js +42 -0
  291. package/dist/tui/features/vc/reset/api/execute-vc-reset.d.ts +8 -0
  292. package/dist/tui/features/vc/reset/api/execute-vc-reset.js +13 -0
  293. package/dist/tui/features/vc/reset/components/vc-reset-flow.d.ts +10 -0
  294. package/dist/tui/features/vc/reset/components/vc-reset-flow.js +63 -0
  295. package/dist/tui/features/vc/status/api/execute-vc-status.d.ts +8 -0
  296. package/dist/tui/features/vc/status/api/execute-vc-status.js +13 -0
  297. package/dist/tui/features/vc/status/components/vc-status-flow.d.ts +10 -0
  298. package/dist/tui/features/vc/status/components/vc-status-flow.js +133 -0
  299. package/dist/tui/lib/environment.d.ts +8 -0
  300. package/dist/tui/lib/environment.js +8 -0
  301. package/dist/tui/utils/error-messages.d.ts +5 -1
  302. package/dist/tui/utils/error-messages.js +32 -3
  303. package/oclif.manifest.json +1018 -98
  304. package/package.json +9 -3
  305. package/dist/oclif/hooks/prerun/validate-brv-config-version.d.ts +0 -33
  306. package/dist/oclif/hooks/prerun/validate-brv-config-version.js +0 -86
  307. package/dist/tui/components/init.d.ts +0 -33
  308. package/dist/tui/components/init.js +0 -234
  309. package/dist/tui/features/space/api/get-spaces.d.ts +0 -16
  310. package/dist/tui/features/space/api/get-spaces.js +0 -17
  311. package/dist/tui/features/space/api/switch-space.d.ts +0 -11
  312. package/dist/tui/features/space/api/switch-space.js +0 -24
  313. package/dist/tui/features/space/components/space-list-view.d.ts +0 -12
  314. package/dist/tui/features/space/components/space-list-view.js +0 -56
  315. package/dist/tui/features/space/components/space-switch-flow.d.ts +0 -13
  316. package/dist/tui/features/space/components/space-switch-flow.js +0 -97
@@ -1,5 +1,6 @@
1
1
  import { TaskErrorCode } from '../../server/core/domain/errors/task-error.js';
2
2
  import { LlmEvents, TaskEvents } from '../../shared/transport/events/index.js';
3
+ import { ReviewEvents } from '../../shared/transport/events/review-events.js';
3
4
  import { writeJsonResponse } from './json-response.js';
4
5
  /** Grace period before treating 'reconnecting' as daemon death (ms) */
5
6
  const DISCONNECT_GRACE_MS = 10_000;
@@ -57,6 +58,7 @@ export function waitForTaskCompletion(options, log) {
57
58
  let completed = false;
58
59
  let disconnectTimer;
59
60
  const toolCalls = [];
61
+ let pendingReview;
60
62
  const rejectRetryable = (message) => {
61
63
  if (completed)
62
64
  return;
@@ -169,13 +171,24 @@ export function waitForTaskCompletion(options, log) {
169
171
  return;
170
172
  onResponse(data.content, data.taskId);
171
173
  }),
174
+ // Pending review notification — emitted by server after curate completes with review-required ops
175
+ client.on(ReviewEvents.NOTIFY, (data) => {
176
+ if (data.taskId === taskId) {
177
+ pendingReview = { pendingCount: data.pendingCount, reviewUrl: data.reviewUrl };
178
+ }
179
+ }),
172
180
  // Task completed
173
181
  client.on(TaskEvents.COMPLETED, (payload) => {
174
182
  if (payload.taskId !== taskId || completed)
175
183
  return;
176
184
  completed = true;
177
185
  cleanup();
178
- onCompleted({ logId: payload.logId, result: payload.result, taskId, toolCalls });
186
+ // Prefer pendingReviewCount embedded in payload (set synchronously by server before task:completed).
187
+ // Falls back to review:notify capture for backward compatibility.
188
+ const resolvedPendingReview = payload.pendingReviewCount !== undefined && payload.pendingReviewCount > 0
189
+ ? { pendingCount: payload.pendingReviewCount, reviewUrl: pendingReview?.reviewUrl ?? '' }
190
+ : pendingReview;
191
+ onCompleted({ logId: payload.logId, pendingReview: resolvedPendingReview, result: payload.result, taskId, toolCalls });
179
192
  resolve();
180
193
  }),
181
194
  // Task error
@@ -186,7 +199,7 @@ export function waitForTaskCompletion(options, log) {
186
199
  cleanup();
187
200
  onError({ error: payload.error, logId: payload.logId, taskId, toolCalls });
188
201
  if (isText) {
189
- reject(Object.assign(new Error(payload.error.message), { code: payload.error.code }));
202
+ reject(Object.assign(new Error(payload.error.message), { code: payload.error.code ?? TaskErrorCode.TASK_EXECUTION }));
190
203
  }
191
204
  else {
192
205
  resolve();
@@ -11,6 +11,7 @@ type EnvironmentConfig = {
11
11
  authorizationUrl: string;
12
12
  clientId: string;
13
13
  cogitApiBaseUrl: string;
14
+ gitRemoteBaseUrl: string;
14
15
  hubRegistryUrl: string;
15
16
  issuerUrl: string;
16
17
  llmApiBaseUrl: string;
@@ -19,5 +20,6 @@ type EnvironmentConfig = {
19
20
  webAppUrl: string;
20
21
  };
21
22
  export declare const getCurrentConfig: () => EnvironmentConfig;
23
+ export declare const getGitRemoteBaseUrl: () => string;
22
24
  export declare const isDevelopment: () => boolean;
23
25
  export {};
@@ -29,6 +29,7 @@ export const getCurrentConfig = () => ({
29
29
  authorizationUrl: readRequiredEnv('BRV_AUTHORIZATION_URL'),
30
30
  clientId: DEFAULTS.clientId,
31
31
  cogitApiBaseUrl: readRequiredEnv('BRV_COGIT_API_BASE_URL'),
32
+ gitRemoteBaseUrl: readRequiredEnv('BRV_GIT_REMOTE_BASE_URL'),
32
33
  hubRegistryUrl: DEFAULTS.hubRegistryUrl,
33
34
  issuerUrl: readRequiredEnv('BRV_ISSUER_URL'),
34
35
  llmApiBaseUrl: readRequiredEnv('BRV_LLM_API_BASE_URL'),
@@ -36,4 +37,5 @@ export const getCurrentConfig = () => ({
36
37
  tokenUrl: readRequiredEnv('BRV_TOKEN_URL'),
37
38
  webAppUrl: readRequiredEnv('BRV_WEB_APP_URL'),
38
39
  });
40
+ export const getGitRemoteBaseUrl = () => process.env.BRV_GIT_REMOTE_BASE_URL ?? 'https://byterover.dev';
39
41
  export const isDevelopment = () => ENVIRONMENT === 'development';
@@ -50,6 +50,7 @@ export declare const AGENT_PROCESS_READY_TIMEOUT_MS = 30000;
50
50
  export declare const AGENT_PROCESS_STOP_TIMEOUT_MS = 5000;
51
51
  export declare const CURATE_LOG_DIR = "curate-log";
52
52
  export declare const CURATE_LOG_ID_PREFIX = "cur";
53
+ export declare const REVIEW_BACKUPS_DIR = "review-backups";
53
54
  export declare const SUMMARY_INDEX_FILE = "_index.md";
54
55
  export declare const ARCHIVE_DIR = "_archived";
55
56
  export declare const STUB_EXTENSION = ".stub.md";
@@ -57,3 +58,5 @@ export declare const FULL_ARCHIVE_EXTENSION = ".full.md";
57
58
  export declare const MANIFEST_FILE = "_manifest.json";
58
59
  export declare const ARCHIVE_IMPORTANCE_THRESHOLD = 35;
59
60
  export declare const DEFAULT_GHOST_CUE_MAX_TOKENS = 220;
61
+ /** .gitignore content for the context tree — ignore derived artifacts only */
62
+ export declare const CONTEXT_TREE_GITIGNORE = "# Derived artifacts \u2014 do not track\n.gitignore\n.snapshot.json\n_manifest.json\n_index.md\n";
@@ -68,6 +68,8 @@ export const AGENT_PROCESS_STOP_TIMEOUT_MS = 5000; // 5s max wait for child proc
68
68
  // Curate log
69
69
  export const CURATE_LOG_DIR = 'curate-log';
70
70
  export const CURATE_LOG_ID_PREFIX = 'cur';
71
+ // Review backups (stores pre-curate file content for local HITL review diffs)
72
+ export const REVIEW_BACKUPS_DIR = 'review-backups';
71
73
  // === Hierarchical DAG (summary, archive, manifest) ===
72
74
  export const SUMMARY_INDEX_FILE = '_index.md';
73
75
  export const ARCHIVE_DIR = '_archived';
@@ -76,3 +78,10 @@ export const FULL_ARCHIVE_EXTENSION = '.full.md';
76
78
  export const MANIFEST_FILE = '_manifest.json';
77
79
  export const ARCHIVE_IMPORTANCE_THRESHOLD = 35;
78
80
  export const DEFAULT_GHOST_CUE_MAX_TOKENS = 220;
81
+ /** .gitignore content for the context tree — ignore derived artifacts only */
82
+ export const CONTEXT_TREE_GITIGNORE = `# Derived artifacts — do not track
83
+ .gitignore
84
+ .snapshot.json
85
+ _manifest.json
86
+ _index.md
87
+ `;
@@ -6,6 +6,7 @@ export type AuthTokenParams = {
6
6
  tokenType?: string;
7
7
  userEmail: string;
8
8
  userId: string;
9
+ userName?: string;
9
10
  };
10
11
  /**
11
12
  * Represents an authentication token with access and refresh tokens, expiration, and type.
@@ -18,6 +19,7 @@ export declare class AuthToken {
18
19
  readonly tokenType: string;
19
20
  readonly userEmail: string;
20
21
  readonly userId: string;
22
+ readonly userName?: string;
21
23
  constructor(params: AuthTokenParams);
22
24
  /**
23
25
  * Create an AuthToken instance from a JSON object.
@@ -9,6 +9,7 @@ export class AuthToken {
9
9
  tokenType;
10
10
  userEmail;
11
11
  userId;
12
+ userName;
12
13
  constructor(params) {
13
14
  this.accessToken = params.accessToken;
14
15
  this.expiresAt = params.expiresAt;
@@ -17,6 +18,7 @@ export class AuthToken {
17
18
  this.tokenType = params.tokenType ?? 'Bearer';
18
19
  this.userId = params.userId;
19
20
  this.userEmail = params.userEmail;
21
+ this.userName = params.userName;
20
22
  }
21
23
  /**
22
24
  * Create an AuthToken instance from a JSON object.
@@ -39,6 +41,7 @@ export class AuthToken {
39
41
  tokenType: json.tokenType,
40
42
  userEmail: json.userEmail,
41
43
  userId: json.userId,
44
+ userName: json.userName ?? undefined,
42
45
  });
43
46
  }
44
47
  /**
@@ -60,7 +63,7 @@ export class AuthToken {
60
63
  * @returns A JSON object representing the AuthToken
61
64
  */
62
65
  toJson() {
63
- return {
66
+ const json = {
64
67
  accessToken: this.accessToken,
65
68
  expiresAt: this.expiresAt.toISOString(),
66
69
  refreshToken: this.refreshToken,
@@ -69,5 +72,8 @@ export class AuthToken {
69
72
  userEmail: this.userEmail,
70
73
  userId: this.userId,
71
74
  };
75
+ if (this.userName)
76
+ json.userName = this.userName;
77
+ return json;
72
78
  }
73
79
  }
@@ -1,8 +1,19 @@
1
1
  export type CurateLogOperation = {
2
+ additionalFilePaths?: string[];
3
+ confidence?: 'high' | 'low';
2
4
  filePath?: string;
5
+ impact?: 'high' | 'low';
3
6
  message?: string;
7
+ needsReview?: boolean;
4
8
  path: string;
9
+ /** Semantic summary of the file's content before this operation (for review UI). */
10
+ previousSummary?: string;
11
+ reason?: string;
12
+ /** Local review status. Set to 'pending' when needsReview=true; updated to 'approved'/'rejected' by the review UI. */
13
+ reviewStatus?: 'approved' | 'pending' | 'rejected';
5
14
  status: 'failed' | 'success';
15
+ /** Semantic summary of the file's content after this operation (for review UI). */
16
+ summary?: string;
6
17
  type: 'ADD' | 'DELETE' | 'MERGE' | 'UPDATE' | 'UPSERT';
7
18
  };
8
19
  export type CurateLogSummary = {
@@ -5,8 +5,10 @@ interface SpaceParams {
5
5
  id: string;
6
6
  isDefault: boolean;
7
7
  name: string;
8
+ slug?: string;
8
9
  teamId: string;
9
10
  teamName: string;
11
+ teamSlug?: string;
10
12
  }
11
13
  /**
12
14
  * Represents a ByteRover space that belongs to a team.
@@ -16,8 +18,10 @@ export declare class Space {
16
18
  readonly id: string;
17
19
  readonly isDefault: boolean;
18
20
  readonly name: string;
21
+ readonly slug: string;
19
22
  readonly teamId: string;
20
23
  readonly teamName: string;
24
+ readonly teamSlug: string;
21
25
  constructor(params: SpaceParams);
22
26
  /**
23
27
  * Deserializes a space from JSON format
@@ -6,8 +6,10 @@ export class Space {
6
6
  id;
7
7
  isDefault;
8
8
  name;
9
+ slug;
9
10
  teamId;
10
11
  teamName;
12
+ teamSlug;
11
13
  constructor(params) {
12
14
  if (params.id.trim().length === 0) {
13
15
  throw new Error('Space ID cannot be empty');
@@ -24,8 +26,10 @@ export class Space {
24
26
  this.id = params.id;
25
27
  this.isDefault = params.isDefault;
26
28
  this.name = params.name;
29
+ this.slug = params.slug ?? params.name;
27
30
  this.teamId = params.teamId;
28
31
  this.teamName = params.teamName;
32
+ this.teamSlug = params.teamSlug ?? params.teamName;
29
33
  }
30
34
  /**
31
35
  * Deserializes a space from JSON format
@@ -50,8 +54,10 @@ export class Space {
50
54
  id: json.id,
51
55
  isDefault: json.is_default,
52
56
  name: json.name,
57
+ slug: typeof json.slug === 'string' ? json.slug : json.name,
53
58
  teamId: json.team_id,
54
59
  teamName: json.team_name,
60
+ teamSlug: typeof json.team_slug === 'string' ? json.team_slug : json.team_name,
55
61
  });
56
62
  }
57
63
  /**
@@ -69,8 +75,10 @@ export class Space {
69
75
  id: this.id,
70
76
  isDefault: this.isDefault,
71
77
  name: this.name,
78
+ slug: this.slug,
72
79
  teamId: this.teamId,
73
80
  teamName: this.teamName,
81
+ teamSlug: this.teamSlug,
74
82
  };
75
83
  }
76
84
  }
@@ -10,6 +10,7 @@ interface TeamParams {
10
10
  isActive: boolean;
11
11
  isDefault: boolean;
12
12
  name: string;
13
+ slug: string;
13
14
  updatedAt: Date;
14
15
  }
15
16
  /**
@@ -25,6 +26,7 @@ export declare class Team {
25
26
  readonly isActive: boolean;
26
27
  readonly isDefault: boolean;
27
28
  readonly name: string;
29
+ readonly slug: string;
28
30
  readonly updatedAt: Date;
29
31
  constructor(params: TeamParams);
30
32
  /**
@@ -11,6 +11,7 @@ export class Team {
11
11
  isActive;
12
12
  isDefault;
13
13
  name;
14
+ slug;
14
15
  updatedAt;
15
16
  constructor(params) {
16
17
  if (params.id.trim().length === 0) {
@@ -30,6 +31,7 @@ export class Team {
30
31
  this.isActive = params.isActive;
31
32
  this.isDefault = params.isDefault;
32
33
  this.name = params.name;
34
+ this.slug = params.slug;
33
35
  this.updatedAt = params.updatedAt;
34
36
  }
35
37
  /**
@@ -67,6 +69,7 @@ export class Team {
67
69
  isActive: json.is_active,
68
70
  isDefault: json.is_default,
69
71
  name: json.name,
72
+ slug: typeof json.slug === 'string' ? json.slug : json.name,
70
73
  updatedAt: new Date(json.updated_at),
71
74
  });
72
75
  }
@@ -90,6 +93,7 @@ export class Team {
90
93
  isActive: this.isActive,
91
94
  isDefault: this.isDefault,
92
95
  name: this.name,
96
+ slug: this.slug,
93
97
  updatedAt: this.updatedAt.toISOString(),
94
98
  };
95
99
  }
@@ -0,0 +1,6 @@
1
+ export declare class GitError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class GitAuthError extends GitError {
5
+ constructor(message?: string);
6
+ }
@@ -0,0 +1,12 @@
1
+ export class GitError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = 'GitError';
5
+ }
6
+ }
7
+ export class GitAuthError extends GitError {
8
+ constructor(message = 'Git authentication failed. Try /login again.') {
9
+ super(message);
10
+ this.name = 'GitAuthError';
11
+ }
12
+ }
@@ -21,6 +21,7 @@ export declare const TaskErrorCode: {
21
21
  readonly TASK_EXECUTION: "ERR_TASK_EXECUTION";
22
22
  readonly TASK_TIMEOUT: "ERR_TASK_TIMEOUT";
23
23
  readonly UNKNOWN: "ERR_UNKNOWN";
24
+ readonly VC_GIT_INITIALIZED: "ERR_VC_GIT_INITIALIZED";
24
25
  };
25
26
  export type TaskErrorCodeType = (typeof TaskErrorCode)[keyof typeof TaskErrorCode];
26
27
  /**
@@ -75,6 +76,9 @@ export declare class LocalChangesExistError extends TaskError {
75
76
  export declare class SpaceNotConfiguredError extends TaskError {
76
77
  constructor();
77
78
  }
79
+ export declare class GitVcInitializedError extends TaskError {
80
+ constructor(message: string);
81
+ }
78
82
  export declare class SpaceNotFoundError extends TaskError {
79
83
  constructor();
80
84
  }
@@ -28,6 +28,8 @@ export const TaskErrorCode = {
28
28
  TASK_TIMEOUT: 'ERR_TASK_TIMEOUT',
29
29
  // Unknown
30
30
  UNKNOWN: 'ERR_UNKNOWN',
31
+ // Version control
32
+ VC_GIT_INITIALIZED: 'ERR_VC_GIT_INITIALIZED',
31
33
  };
32
34
  /**
33
35
  * Base error class for task-related errors.
@@ -157,6 +159,12 @@ export class SpaceNotConfiguredError extends TaskError {
157
159
  this.name = 'SpaceNotConfiguredError';
158
160
  }
159
161
  }
162
+ export class GitVcInitializedError extends TaskError {
163
+ constructor(message) {
164
+ super(message, TaskErrorCode.VC_GIT_INITIALIZED);
165
+ this.name = 'GitVcInitializedError';
166
+ }
167
+ }
160
168
  export class SpaceNotFoundError extends TaskError {
161
169
  constructor() {
162
170
  super('Space not found', TaskErrorCode.SPACE_NOT_FOUND);
@@ -0,0 +1,5 @@
1
+ import type { VcErrorCodeType } from '../../../../shared/transport/events/vc-events.js';
2
+ export declare class VcError extends Error {
3
+ readonly code: VcErrorCodeType;
4
+ constructor(message: string, code: VcErrorCodeType);
5
+ }
@@ -0,0 +1,8 @@
1
+ export class VcError extends Error {
2
+ code;
3
+ constructor(message, code) {
4
+ super(message);
5
+ this.name = 'VcError';
6
+ this.code = code;
7
+ }
8
+ }
@@ -48,9 +48,11 @@ export interface ContextData {
48
48
  name: string;
49
49
  narrative?: Narrative;
50
50
  rawConcept?: RawConcept;
51
+ reason?: string;
51
52
  relations?: string[];
52
53
  scoring?: FrontmatterScoring;
53
54
  snippets: string[];
55
+ summary?: string;
54
56
  tags: string[];
55
57
  }
56
58
  interface Frontmatter {
@@ -61,6 +63,7 @@ interface Frontmatter {
61
63
  maturity?: 'core' | 'draft' | 'validated';
62
64
  recency?: number;
63
65
  related: string[];
66
+ summary?: string;
64
67
  tags: string[];
65
68
  title?: string;
66
69
  updateCount?: number;
@@ -88,7 +91,7 @@ export declare function parseFrontmatterScoring(content: string): FrontmatterSco
88
91
  export declare function updateScoringInContent(content: string, scoring: FrontmatterScoring): string;
89
92
  export declare const MarkdownWriter: {
90
93
  generateContext(data: ContextData): string;
91
- mergeContexts(sourceContent: string, targetContent: string): string;
94
+ mergeContexts(sourceContent: string, targetContent: string, reason?: string, summary?: string): string;
92
95
  parseContent(content: string, name?: string): ContextData;
93
96
  };
94
97
  export {};
@@ -5,12 +5,15 @@ import { normalizeRelationPath, parseRelations } from './relation-parser.js';
5
5
  * Generate YAML frontmatter block from context data.
6
6
  * Only includes fields that have values.
7
7
  */
8
- function generateFrontmatter(title, relations, tags = [], keywords = [], scoring) {
8
+ function generateFrontmatter(title, relations, tags = [], keywords = [], scoring, summary) {
9
9
  const normalizedRelations = (relations || []).map(rel => normalizeRelationPath(rel));
10
10
  const fm = {};
11
11
  if (title) {
12
12
  fm.title = title;
13
13
  }
14
+ if (summary) {
15
+ fm.summary = summary;
16
+ }
14
17
  fm.tags = tags;
15
18
  if (normalizedRelations.length > 0) {
16
19
  fm.related = normalizedRelations;
@@ -74,6 +77,9 @@ function parseFrontmatter(content) {
74
77
  if (typeof parsed.title === 'string') {
75
78
  frontmatter.title = parsed.title;
76
79
  }
80
+ if (typeof parsed.summary === 'string') {
81
+ frontmatter.summary = parsed.summary;
82
+ }
77
83
  // Scoring fields (backward compatible — absent in old files)
78
84
  if (typeof parsed.importance === 'number') {
79
85
  frontmatter.importance = parsed.importance;
@@ -333,6 +339,18 @@ function parseFactsSection(content) {
333
339
  }
334
340
  return facts.length > 0 ? facts : undefined;
335
341
  }
342
+ function generateReasonSection(reason) {
343
+ if (!reason)
344
+ return '';
345
+ return `\n## Reason\n${reason}\n`;
346
+ }
347
+ function parseReasonSection(content) {
348
+ const match = content.match(/##\s*Reason\s*\n([\s\S]*?)(?=\n##\s|\n---\n|$)/i);
349
+ if (!match)
350
+ return undefined;
351
+ const text = match[1].trim();
352
+ return text || undefined;
353
+ }
336
354
  function extractSnippetsFromContent(content) {
337
355
  let snippetContent = content;
338
356
  // Forgiving regex patterns for section removal
@@ -340,6 +358,10 @@ function extractSnippetsFromContent(content) {
340
358
  if (relationsMatch) {
341
359
  snippetContent = snippetContent.replace(relationsMatch[0], '').trim();
342
360
  }
361
+ const reasonMatch = snippetContent.match(/##\s*Reason[\s\S]*?(?=\n##\s|\n---\n|$)/i);
362
+ if (reasonMatch) {
363
+ snippetContent = snippetContent.replace(reasonMatch[0], '').trim();
364
+ }
343
365
  const rawConceptMatch = snippetContent.match(/##\s*Raw Concept[\s\S]*?(?=\n##\s|\n---\n|$)/i);
344
366
  if (rawConceptMatch) {
345
367
  snippetContent = snippetContent.replace(rawConceptMatch[0], '').trim();
@@ -518,7 +540,7 @@ export function updateScoringInContent(content, scoring) {
518
540
  return content;
519
541
  }
520
542
  const { body, frontmatter } = parsed;
521
- const updatedFrontmatter = generateFrontmatter(frontmatter.title ?? '', frontmatter.related, frontmatter.tags, frontmatter.keywords, scoring);
543
+ const updatedFrontmatter = generateFrontmatter(frontmatter.title ?? '', frontmatter.related, frontmatter.tags, frontmatter.keywords, scoring, frontmatter.summary);
522
544
  return updatedFrontmatter + body;
523
545
  }
524
546
  function parseContentWithFrontmatter(content) {
@@ -529,6 +551,7 @@ function parseContentWithFrontmatter(content) {
529
551
  keywords: parsed.frontmatter.keywords,
530
552
  relations: parsed.frontmatter.related,
531
553
  scoring: extractScoring(parsed.frontmatter),
554
+ summary: parsed.frontmatter.summary,
532
555
  tags: parsed.frontmatter.tags,
533
556
  title: parsed.frontmatter.title,
534
557
  };
@@ -545,15 +568,16 @@ export const MarkdownWriter = {
545
568
  generateContext(data) {
546
569
  const snippets = (data.snippets || []).filter(s => s && s.trim());
547
570
  const relations = data.relations || [];
548
- const frontmatter = generateFrontmatter(data.name, relations, data.tags, data.keywords, data.scoring);
571
+ const frontmatter = generateFrontmatter(data.name, relations, data.tags, data.keywords, data.scoring, data.summary);
572
+ const reasonSection = generateReasonSection(data.reason);
549
573
  const rawConceptSection = generateRawConceptSection(data.rawConcept);
550
574
  const narrativeSection = generateNarrativeSection(data.narrative);
551
575
  const factsSection = generateFactsSection(data.facts);
552
576
  const hasSnippets = snippets.length > 0;
553
577
  // Build the content parts
554
578
  const parts = [];
555
- // Add sections (rawConcept, narrative, facts) relations are now in frontmatter
556
- const sectionsContent = `${rawConceptSection}${narrativeSection}${factsSection}`.trim();
579
+ // Add sections — reason first (WHY), then content sections, relations in frontmatter
580
+ const sectionsContent = `${reasonSection}${rawConceptSection}${narrativeSection}${factsSection}`.trim();
557
581
  if (sectionsContent) {
558
582
  parts.push(sectionsContent);
559
583
  }
@@ -570,12 +594,14 @@ export const MarkdownWriter = {
570
594
  const body = parts.length > 0 ? parts.join('\n\n---\n\n') + '\n' : '';
571
595
  return `${frontmatter}${body}`;
572
596
  },
573
- mergeContexts(sourceContent, targetContent) {
597
+ mergeContexts(sourceContent, targetContent, reason, summary) {
574
598
  const sourceParsed = parseContentWithFrontmatter(sourceContent);
575
599
  const targetParsed = parseContentWithFrontmatter(targetContent);
576
600
  const mergedRelations = [...new Set([...sourceParsed.relations, ...targetParsed.relations])];
577
601
  const mergedTags = [...new Set([...sourceParsed.tags, ...targetParsed.tags])];
578
602
  const mergedKeywords = [...new Set([...sourceParsed.keywords, ...targetParsed.keywords])];
603
+ // reason: explicit override wins, then source (newer), then target (older)
604
+ const mergedReason = reason ?? parseReasonSection(sourceParsed.body) ?? parseReasonSection(targetParsed.body);
579
605
  // Merge scoring metadata (FinMem-inspired lifecycle)
580
606
  const defaultScoring = { importance: 50, maturity: 'draft', recency: 1 };
581
607
  let mergedScoringData;
@@ -609,23 +635,27 @@ export const MarkdownWriter = {
609
635
  name: sourceParsed.title || targetParsed.title || '',
610
636
  narrative: mergedNarrative,
611
637
  rawConcept: mergedRawConcept,
638
+ reason: mergedReason,
612
639
  relations: mergedRelations,
613
640
  scoring: mergedScoringData,
614
641
  snippets: mergedSnippets,
642
+ summary: summary ?? sourceParsed.summary ?? targetParsed.summary,
615
643
  tags: mergedTags,
616
644
  });
617
645
  },
618
646
  parseContent(content, name = '') {
619
- const { body, keywords, relations, scoring, tags, title } = parseContentWithFrontmatter(content);
647
+ const { body, keywords, relations, scoring, summary, tags, title } = parseContentWithFrontmatter(content);
620
648
  return {
621
649
  facts: parseFactsSection(body),
622
650
  keywords,
623
651
  name: title || name,
624
652
  narrative: parseNarrativeSection(body),
625
653
  rawConcept: parseRawConceptSection(body),
654
+ reason: parseReasonSection(body),
626
655
  relations,
627
656
  scoring,
628
657
  snippets: extractSnippetsFromContent(body),
658
+ summary,
629
659
  tags,
630
660
  };
631
661
  },
@@ -521,18 +521,18 @@ export declare const TaskExecuteSchema: z.ZodObject<{
521
521
  taskId: string;
522
522
  clientId: string;
523
523
  files?: string[] | undefined;
524
+ projectPath?: string | undefined;
524
525
  folderPath?: string | undefined;
525
526
  clientCwd?: string | undefined;
526
- projectPath?: string | undefined;
527
527
  }, {
528
528
  type: "curate" | "query" | "curate-folder";
529
529
  content: string;
530
530
  taskId: string;
531
531
  clientId: string;
532
532
  files?: string[] | undefined;
533
+ projectPath?: string | undefined;
533
534
  folderPath?: string | undefined;
534
535
  clientCwd?: string | undefined;
535
- projectPath?: string | undefined;
536
536
  }>;
537
537
  /**
538
538
  * task:cancel - Transport tells Agent to cancel a task
@@ -718,14 +718,14 @@ export declare const TaskStartedEventSchema: z.ZodObject<{
718
718
  }, "strip", z.ZodTypeAny, {
719
719
  taskId: string;
720
720
  type?: string | undefined;
721
- content?: string | undefined;
722
721
  files?: string[] | undefined;
722
+ content?: string | undefined;
723
723
  clientCwd?: string | undefined;
724
724
  }, {
725
725
  taskId: string;
726
726
  type?: string | undefined;
727
- content?: string | undefined;
728
727
  files?: string[] | undefined;
728
+ content?: string | undefined;
729
729
  clientCwd?: string | undefined;
730
730
  }>;
731
731
  /**
@@ -965,17 +965,17 @@ export declare const TaskCreateRequestSchema: z.ZodObject<{
965
965
  content: string;
966
966
  taskId: string;
967
967
  files?: string[] | undefined;
968
+ projectPath?: string | undefined;
968
969
  folderPath?: string | undefined;
969
970
  clientCwd?: string | undefined;
970
- projectPath?: string | undefined;
971
971
  }, {
972
972
  type: "curate" | "query" | "curate-folder";
973
973
  content: string;
974
974
  taskId: string;
975
975
  files?: string[] | undefined;
976
+ projectPath?: string | undefined;
976
977
  folderPath?: string | undefined;
977
978
  clientCwd?: string | undefined;
978
- projectPath?: string | undefined;
979
979
  }>;
980
980
  /**
981
981
  * Response after task creation
@@ -15,6 +15,12 @@ export interface IContextTreeService {
15
15
  * @returns True if context tree directory exists
16
16
  */
17
17
  exists(directory?: string): Promise<boolean>;
18
+ /**
19
+ * Checks if a git repository (.git directory) exists in the context tree.
20
+ * @param directory - Base directory
21
+ * @returns True if .git directory exists inside the context tree
22
+ */
23
+ hasGitRepo(directory: string): Promise<boolean>;
18
24
  /**
19
25
  * Initializes the context tree directory structure.
20
26
  * Creates .brv/context-tree/ directory with domain subdirectories and context.md files.
@@ -23,4 +29,9 @@ export interface IContextTreeService {
23
29
  * @throws Error if context tree already exists or initialization fails
24
30
  */
25
31
  initialize(directory?: string): Promise<string>;
32
+ /**
33
+ * Returns the absolute path to the context tree directory without creating it.
34
+ * @param directory - Base directory
35
+ */
36
+ resolvePath(directory: string): string;
26
37
  }
@@ -12,6 +12,12 @@ import type { TaskInfo } from '../../domain/transport/task-info.js';
12
12
  export interface ITaskLifecycleHook {
13
13
  /** Called after onTaskCompleted, onTaskError, or onTaskCancelled to release in-memory resources. */
14
14
  cleanup?(taskId: string): void;
15
+ /**
16
+ * Synchronous hook called just before task:completed is emitted.
17
+ * Returns extra data to merge into the task:completed payload (e.g. {pendingReviewCount: 2}).
18
+ * Must be synchronous and must not throw.
19
+ */
20
+ getTaskCompletionData?(taskId: string): Record<string, unknown>;
15
21
  /** Called when a task is cancelled by the user. Distinct from onTaskError. */
16
22
  onTaskCancelled?(taskId: string, task: TaskInfo): Promise<void>;
17
23
  /** Called when a task completes successfully. */