byterover-cli 2.6.0 → 3.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 (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 +1124 -204
  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
@@ -29,24 +29,21 @@ export function computeSummary(operations) {
29
29
  break;
30
30
  }
31
31
  case 'UPSERT': {
32
- // UPSERT is intentionally counted as "updated" — CurateLogSummary has no separate upserted field.
33
- summary.updated++;
32
+ if (op.message?.includes('created new')) {
33
+ summary.added++;
34
+ }
35
+ else {
36
+ summary.updated++;
37
+ }
34
38
  break;
35
39
  }
36
40
  }
37
41
  }
38
42
  return summary;
39
43
  }
40
- // ── CurateLogHandler ──────────────────────────────────────────────────────────
41
- /**
42
- * Lifecycle hook that transparently logs curate task execution.
43
- *
44
- * Wired into TaskRouter via lifecycleHooks[]. Writes log entries to
45
- * per-project FileCurateLogStore. All I/O errors are swallowed — logging
46
- * must never block or affect curate task execution.
47
- */
48
44
  export class CurateLogHandler {
49
45
  createStore;
46
+ onPendingReviews;
50
47
  /** Active task count per projectPath — used to evict idle stores. */
51
48
  activeTaskCount = new Map();
52
49
  /** Per-project store cache (one store per projectPath). Evicted when no active tasks remain. */
@@ -55,9 +52,11 @@ export class CurateLogHandler {
55
52
  tasks = new Map();
56
53
  /**
57
54
  * @param createStore - Optional factory for testing. Default: FileCurateLogStore.
55
+ * @param onPendingReviews - Optional callback fired when curate completes with pending review ops.
58
56
  */
59
- constructor(createStore) {
57
+ constructor(createStore, onPendingReviews) {
60
58
  this.createStore = createStore;
59
+ this.onPendingReviews = onPendingReviews;
61
60
  }
62
61
  cleanup(taskId) {
63
62
  const state = this.tasks.get(taskId);
@@ -73,6 +72,18 @@ export class CurateLogHandler {
73
72
  }
74
73
  }
75
74
  }
75
+ /**
76
+ * Synchronously returns the pending review count from in-memory state.
77
+ * Included in the task:completed payload so the client receives it atomically
78
+ * without relying on a separate review:notify event that arrives after disk I/O.
79
+ */
80
+ getTaskCompletionData(taskId) {
81
+ const state = this.tasks.get(taskId);
82
+ if (!state)
83
+ return {};
84
+ const pendingReviewCount = state.operations.filter((op) => op.reviewStatus === 'pending').length;
85
+ return pendingReviewCount > 0 ? { pendingReviewCount } : {};
86
+ }
76
87
  async onTaskCancelled(taskId, _task) {
77
88
  const state = this.tasks.get(taskId);
78
89
  if (!state)
@@ -89,7 +100,7 @@ export class CurateLogHandler {
89
100
  transportLog(`CurateLogHandler: failed to save cancelled entry for ${taskId}: ${error instanceof Error ? error.message : String(error)}`);
90
101
  });
91
102
  }
92
- async onTaskCompleted(taskId, result, _task) {
103
+ async onTaskCompleted(taskId, result, task) {
93
104
  const state = this.tasks.get(taskId);
94
105
  if (!state)
95
106
  return;
@@ -105,6 +116,18 @@ export class CurateLogHandler {
105
116
  await store.save(updated).catch((error) => {
106
117
  transportLog(`CurateLogHandler: failed to save completed entry for ${taskId}: ${error instanceof Error ? error.message : String(error)}`);
107
118
  });
119
+ // Notify about pending reviews (fire-and-forget)
120
+ if (this.onPendingReviews) {
121
+ const pendingCount = state.operations.filter((op) => op.reviewStatus === 'pending').length;
122
+ if (pendingCount > 0) {
123
+ try {
124
+ this.onPendingReviews({ clientId: task.clientId, pendingCount, projectPath: state.projectPath, taskId });
125
+ }
126
+ catch {
127
+ // Best-effort notification — never block task completion
128
+ }
129
+ }
130
+ }
108
131
  }
109
132
  async onTaskCreate(task) {
110
133
  if (!CURATE_TASK_TYPES.includes(task.type))
@@ -163,7 +186,21 @@ export class CurateLogHandler {
163
186
  if (!state)
164
187
  return;
165
188
  const ops = extractCurateOperations(payload);
166
- state.operations.push(...ops);
189
+ for (const op of ops) {
190
+ if (op.needsReview && op.status === 'success') {
191
+ op.reviewStatus = 'pending';
192
+ }
193
+ // Deduplicate by filePath: keep only the latest operation per file.
194
+ // This ensures the reviewer sees the final version, not intermediate states.
195
+ if (op.filePath) {
196
+ const existingIndex = state.operations.findIndex((existing) => existing.filePath === op.filePath);
197
+ if (existingIndex !== -1) {
198
+ state.operations[existingIndex] = op;
199
+ continue;
200
+ }
201
+ }
202
+ state.operations.push(op);
203
+ }
167
204
  }
168
205
  // ── Private helpers ─────────────────────────────────────────────────────────
169
206
  getOrCreateStore(projectPath) {
@@ -4,8 +4,12 @@
4
4
  * Registers all feature handlers (auth, init, status, etc.) on the transport server.
5
5
  * These handlers implement the TUI ↔ Server event contract.
6
6
  */
7
+ import { join } from 'node:path';
8
+ import { ReviewEvents } from '../../../shared/transport/events/review-events.js';
7
9
  import { getAuthConfig } from '../../config/auth.config.js';
8
10
  import { getCurrentConfig } from '../../config/environment.js';
11
+ import { BRV_DIR } from '../../constants.js';
12
+ import { getProjectDataDir } from '../../utils/path-utils.js';
9
13
  import { OAuthService } from '../auth/oauth-service.js';
10
14
  import { OidcDiscoveryService } from '../auth/oidc-discovery-service.js';
11
15
  import { SystemBrowserLauncher } from '../browser/system-browser-launcher.js';
@@ -21,16 +25,20 @@ import { FileContextTreeService } from '../context-tree/file-context-tree-servic
21
25
  import { FileContextTreeSnapshotService } from '../context-tree/file-context-tree-snapshot-service.js';
22
26
  import { FileContextTreeWriterService } from '../context-tree/file-context-tree-writer-service.js';
23
27
  import { FsFileService } from '../file/fs-file-service.js';
28
+ import { IsomorphicGitService } from '../git/isomorphic-git-service.js';
24
29
  import { CallbackHandler } from '../http/callback-handler.js';
25
30
  import { HubInstallService } from '../hub/hub-install-service.js';
26
31
  import { createHubKeychainStore } from '../hub/hub-keychain-store.js';
27
32
  import { HubRegistryConfigStore } from '../hub/hub-registry-config-store.js';
28
33
  import { HttpSpaceService } from '../space/http-space-service.js';
34
+ import { FileCurateLogStore } from '../storage/file-curate-log-store.js';
35
+ import { FileReviewBackupStore } from '../storage/file-review-backup-store.js';
29
36
  import { createTokenStore } from '../storage/token-store.js';
30
37
  import { HttpTeamService } from '../team/http-team-service.js';
31
38
  import { FsTemplateLoader } from '../template/fs-template-loader.js';
32
- import { AuthHandler, ConfigHandler, ConnectorsHandler, HubHandler, InitHandler, LocationsHandler, ModelHandler, ProviderHandler, PullHandler, PushHandler, ResetHandler, SpaceHandler, StatusHandler, } from '../transport/handlers/index.js';
39
+ import { AuthHandler, ConfigHandler, ConnectorsHandler, HubHandler, InitHandler, LocationsHandler, ModelHandler, ProviderHandler, PullHandler, PushHandler, ResetHandler, ReviewHandler, SpaceHandler, StatusHandler, VcHandler, } from '../transport/handlers/index.js';
33
40
  import { HttpUserService } from '../user/http-user-service.js';
41
+ import { FileVcGitConfigStore } from '../vc/file-vc-git-config-store.js';
34
42
  /**
35
43
  * Setup all feature handlers on the transport server.
36
44
  * These handlers implement the TUI ↔ Server event contract (auth:*, config:*, status:*, etc.).
@@ -85,9 +93,11 @@ export async function setupFeatureHandlers({ authStateStore, broadcastToProject,
85
93
  const templateService = new RuleTemplateService(templateLoader);
86
94
  const connectorManagerFactory = (projectRoot) => new ConnectorManager({ fileService, projectRoot, templateService });
87
95
  // Project-scoped handlers (receive resolveProjectPath for client → project resolution)
96
+ const gitService = new IsomorphicGitService(authStateStore);
88
97
  new StatusHandler({
89
98
  contextTreeService,
90
99
  contextTreeSnapshotService,
100
+ curateLogStoreFactory: (projectPath) => new FileCurateLogStore({ baseDir: getProjectDataDir(projectPath) }),
91
101
  projectConfigStore,
92
102
  resolveProjectPath,
93
103
  tokenStore,
@@ -104,9 +114,12 @@ export async function setupFeatureHandlers({ authStateStore, broadcastToProject,
104
114
  broadcastToProject,
105
115
  cogitPushService,
106
116
  contextFileReader,
117
+ contextTreeService,
107
118
  contextTreeSnapshotService,
119
+ curateLogStoreFactory: (projectPath) => new FileCurateLogStore({ baseDir: getProjectDataDir(projectPath) }),
108
120
  projectConfigStore,
109
121
  resolveProjectPath,
122
+ reviewBackupStoreFactory: (projectPath) => new FileReviewBackupStore(join(projectPath, BRV_DIR)),
110
123
  tokenStore,
111
124
  transport,
112
125
  webAppUrl: envConfig.webAppUrl,
@@ -114,6 +127,7 @@ export async function setupFeatureHandlers({ authStateStore, broadcastToProject,
114
127
  new PullHandler({
115
128
  broadcastToProject,
116
129
  cogitPullService,
130
+ contextTreeService,
117
131
  contextTreeSnapshotService,
118
132
  contextTreeWriterService,
119
133
  projectConfigStore,
@@ -124,13 +138,25 @@ export async function setupFeatureHandlers({ authStateStore, broadcastToProject,
124
138
  new ResetHandler({
125
139
  contextTreeService,
126
140
  contextTreeSnapshotService,
141
+ curateLogStoreFactory: (projectPath) => new FileCurateLogStore({ baseDir: getProjectDataDir(projectPath) }),
142
+ resolveProjectPath,
143
+ reviewBackupStoreFactory: (projectPath) => new FileReviewBackupStore(join(projectPath, BRV_DIR)),
144
+ transport,
145
+ }).setup();
146
+ new ReviewHandler({
147
+ curateLogStoreFactory: (projectPath) => new FileCurateLogStore({ baseDir: getProjectDataDir(projectPath) }),
148
+ onResolved({ projectPath, taskId }) {
149
+ broadcastToProject(projectPath, ReviewEvents.NOTIFY, { pendingCount: 0, reviewUrl: '', taskId });
150
+ },
127
151
  resolveProjectPath,
152
+ reviewBackupStoreFactory: (projectPath) => new FileReviewBackupStore(join(projectPath, BRV_DIR)),
128
153
  transport,
129
154
  }).setup();
130
155
  new SpaceHandler({
131
156
  broadcastToProject,
132
157
  cogitPullService,
133
158
  contextTreeMerger,
159
+ contextTreeService,
134
160
  contextTreeSnapshotService,
135
161
  contextTreeWriterService,
136
162
  projectConfigStore,
@@ -171,5 +197,19 @@ export async function setupFeatureHandlers({ authStateStore, broadcastToProject,
171
197
  tokenStore,
172
198
  transport,
173
199
  }).setup();
200
+ new VcHandler({
201
+ broadcastToProject,
202
+ contextTreeService,
203
+ gitRemoteBaseUrl: envConfig.gitRemoteBaseUrl,
204
+ gitService,
205
+ projectConfigStore,
206
+ resolveProjectPath,
207
+ spaceService,
208
+ teamService,
209
+ tokenStore,
210
+ transport,
211
+ vcGitConfigStore: new FileVcGitConfigStore(),
212
+ webAppUrl: envConfig.webAppUrl,
213
+ }).setup();
174
214
  log('Feature handlers registered');
175
215
  }
@@ -171,15 +171,31 @@ export class TaskRouter {
171
171
  const { result, taskId } = data;
172
172
  const task = this.tasks.get(taskId);
173
173
  transportLog(`Task completed: ${taskId}`);
174
+ // Collect synchronous completion data from hooks (e.g. pendingReviewCount from CurateLogHandler).
175
+ // This runs before task:completed is emitted so the client receives everything atomically,
176
+ // avoiding the race where review:notify would otherwise arrive after task:completed.
177
+ const hookData = {};
178
+ for (const hook of this.lifecycleHooks) {
179
+ if (hook.getTaskCompletionData) {
180
+ try {
181
+ Object.assign(hookData, hook.getTaskCompletionData(taskId));
182
+ }
183
+ catch {
184
+ // Best-effort: never block task:completed delivery
185
+ }
186
+ }
187
+ }
174
188
  if (task) {
175
189
  this.transport.sendTo(task.clientId, TransportTaskEventNames.COMPLETED, {
176
190
  ...(task.logId ? { logId: task.logId } : {}),
191
+ ...hookData,
177
192
  result,
178
193
  taskId,
179
194
  });
180
195
  }
181
196
  broadcastToProjectRoom(this.projectRegistry, this.projectRouter, task?.projectPath, TransportTaskEventNames.COMPLETED, {
182
197
  ...(task?.logId ? { logId: task.logId } : {}),
198
+ ...hookData,
183
199
  result,
184
200
  taskId,
185
201
  }, task?.clientId);
@@ -67,8 +67,10 @@ export class HttpSpaceService {
67
67
  id: spaceData.id,
68
68
  isDefault: spaceData.is_default,
69
69
  name: spaceData.name,
70
+ slug: spaceData.slug,
70
71
  teamId: spaceData.team_id,
71
72
  teamName: spaceData.team.name,
73
+ teamSlug: spaceData.team.slug,
72
74
  });
73
75
  }
74
76
  }
@@ -18,6 +18,10 @@ export declare class FileCurateLogStore implements ICurateLogStore {
18
18
  private readonly logDir;
19
19
  private readonly maxEntries;
20
20
  constructor(opts: FileCurateLogStoreOptions);
21
+ batchUpdateOperationReviewStatus(logId: string, updates: Array<{
22
+ operationIndex: number;
23
+ reviewStatus: 'approved' | 'rejected';
24
+ }>): Promise<boolean>;
21
25
  /**
22
26
  * Retrieve an entry by ID. Returns null if:
23
27
  * - ID format is invalid (security: prevents path traversal)
@@ -49,6 +53,12 @@ export declare class FileCurateLogStore implements ICurateLogStore {
49
53
  * After saving, prunes oldest entries if count exceeds maxEntries (best-effort).
50
54
  */
51
55
  save(entry: CurateLogEntry): Promise<void>;
56
+ /**
57
+ * Update the reviewStatus of a specific operation within a log entry.
58
+ * Reads the entry, updates the operation at the given index, and saves back atomically.
59
+ * Returns false if the entry or operation index is not found.
60
+ */
61
+ updateOperationReviewStatus(logId: string, operationIndex: number, reviewStatus: 'approved' | 'rejected'): Promise<boolean>;
52
62
  private entryPath;
53
63
  private pruneOldest;
54
64
  /**
@@ -5,10 +5,18 @@ import { z } from 'zod';
5
5
  import { CURATE_LOG_DIR, CURATE_LOG_ID_PREFIX } from '../../constants.js';
6
6
  // ── Zod schema for file validation ────────────────────────────────────────────
7
7
  const CurateLogOperationFileSchema = z.object({
8
+ additionalFilePaths: z.array(z.string()).optional(),
9
+ confidence: z.enum(['high', 'low']).optional(),
8
10
  filePath: z.string().optional(),
11
+ impact: z.enum(['high', 'low']).optional(),
9
12
  message: z.string().optional(),
13
+ needsReview: z.boolean().optional(),
10
14
  path: z.string(),
15
+ previousSummary: z.string().optional(),
16
+ reason: z.string().optional(),
17
+ reviewStatus: z.enum(['approved', 'pending', 'rejected']).optional(),
11
18
  status: z.enum(['failed', 'success']),
19
+ summary: z.string().optional(),
12
20
  type: z.enum(['ADD', 'DELETE', 'MERGE', 'UPDATE', 'UPSERT']),
13
21
  });
14
22
  const CurateLogSummaryFileSchema = z.object({
@@ -69,6 +77,18 @@ export class FileCurateLogStore {
69
77
  this.logDir = join(opts.baseDir, CURATE_LOG_DIR);
70
78
  this.maxEntries = opts.maxEntries ?? DEFAULT_MAX_ENTRIES;
71
79
  }
80
+ async batchUpdateOperationReviewStatus(logId, updates) {
81
+ const entry = await this.getById(logId);
82
+ if (!entry)
83
+ return false;
84
+ for (const { operationIndex, reviewStatus } of updates) {
85
+ if (operationIndex < 0 || operationIndex >= entry.operations.length)
86
+ continue;
87
+ entry.operations[operationIndex].reviewStatus = reviewStatus;
88
+ }
89
+ await this.save(entry);
90
+ return true;
91
+ }
72
92
  /**
73
93
  * Retrieve an entry by ID. Returns null if:
74
94
  * - ID format is invalid (security: prevents path traversal)
@@ -159,6 +179,21 @@ export class FileCurateLogStore {
159
179
  // Prune oldest entries (best-effort — ignore errors)
160
180
  this.pruneOldest().catch(() => { });
161
181
  }
182
+ /**
183
+ * Update the reviewStatus of a specific operation within a log entry.
184
+ * Reads the entry, updates the operation at the given index, and saves back atomically.
185
+ * Returns false if the entry or operation index is not found.
186
+ */
187
+ async updateOperationReviewStatus(logId, operationIndex, reviewStatus) {
188
+ const entry = await this.getById(logId);
189
+ if (!entry)
190
+ return false;
191
+ if (operationIndex < 0 || operationIndex >= entry.operations.length)
192
+ return false;
193
+ entry.operations[operationIndex].reviewStatus = reviewStatus;
194
+ await this.save(entry);
195
+ return true;
196
+ }
162
197
  // ── Private helpers ─────────────────────────────────────────────────────────
163
198
  entryPath(id) {
164
199
  return join(this.logDir, `${id}.json`);
@@ -0,0 +1,29 @@
1
+ import type { IReviewBackupStore } from '../../core/interfaces/storage/i-review-backup-store.js';
2
+ /**
3
+ * File-based implementation of IReviewBackupStore.
4
+ *
5
+ * Stores pre-curate file content in {projectBrvDir}/review-backups/{relativePath}.
6
+ * The directory mirrors the context tree structure.
7
+ *
8
+ * First-write-wins: once a backup exists for a path, subsequent save() calls are no-ops.
9
+ * This ensures the backup always reflects the state at the time of the last push (snapshot version).
10
+ */
11
+ export declare class FileReviewBackupStore implements IReviewBackupStore {
12
+ private readonly backupDir;
13
+ constructor(brvDir: string);
14
+ clear(): Promise<void>;
15
+ delete(relativePath: string): Promise<void>;
16
+ has(relativePath: string): Promise<boolean>;
17
+ /**
18
+ * List all backed-up file paths (relative to backup dir).
19
+ * Useful for the review UI to enumerate all files with backups.
20
+ */
21
+ list(): Promise<string[]>;
22
+ read(relativePath: string): Promise<null | string>;
23
+ save(relativePath: string, content: string): Promise<void>;
24
+ /**
25
+ * Remove empty ancestor directories up to and including the backup root.
26
+ * Called after each file deletion to keep the directory tree clean.
27
+ */
28
+ private pruneEmptyDirs;
29
+ }
@@ -0,0 +1,121 @@
1
+ import { mkdir, readdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+ import { REVIEW_BACKUPS_DIR } from '../../constants.js';
4
+ /**
5
+ * File-based implementation of IReviewBackupStore.
6
+ *
7
+ * Stores pre-curate file content in {projectBrvDir}/review-backups/{relativePath}.
8
+ * The directory mirrors the context tree structure.
9
+ *
10
+ * First-write-wins: once a backup exists for a path, subsequent save() calls are no-ops.
11
+ * This ensures the backup always reflects the state at the time of the last push (snapshot version).
12
+ */
13
+ export class FileReviewBackupStore {
14
+ backupDir;
15
+ constructor(brvDir) {
16
+ this.backupDir = join(brvDir, REVIEW_BACKUPS_DIR);
17
+ }
18
+ async clear() {
19
+ try {
20
+ await rm(this.backupDir, { force: true, recursive: true });
21
+ }
22
+ catch {
23
+ // Directory may not exist — that's fine
24
+ }
25
+ }
26
+ async delete(relativePath) {
27
+ const absPath = join(this.backupDir, relativePath);
28
+ try {
29
+ await rm(absPath);
30
+ }
31
+ catch {
32
+ // File may not exist — that's fine
33
+ }
34
+ await this.pruneEmptyDirs(dirname(absPath));
35
+ }
36
+ async has(relativePath) {
37
+ try {
38
+ await stat(join(this.backupDir, relativePath));
39
+ return true;
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ }
45
+ /**
46
+ * List all backed-up file paths (relative to backup dir).
47
+ * Useful for the review UI to enumerate all files with backups.
48
+ */
49
+ async list() {
50
+ const paths = [];
51
+ const scan = async (dir, prefix) => {
52
+ let entries;
53
+ try {
54
+ entries = await readdir(dir, { withFileTypes: true });
55
+ }
56
+ catch {
57
+ return;
58
+ }
59
+ const subdirTasks = [];
60
+ for (const entry of entries) {
61
+ const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
62
+ if (entry.isDirectory()) {
63
+ subdirTasks.push(scan(join(dir, entry.name), relativePath));
64
+ }
65
+ else if (entry.isFile() && !entry.name.endsWith('.tmp')) {
66
+ paths.push(relativePath);
67
+ }
68
+ }
69
+ await Promise.all(subdirTasks);
70
+ };
71
+ await scan(this.backupDir, '');
72
+ return paths;
73
+ }
74
+ async read(relativePath) {
75
+ try {
76
+ return await readFile(join(this.backupDir, relativePath), 'utf8');
77
+ }
78
+ catch {
79
+ return null;
80
+ }
81
+ }
82
+ async save(relativePath, content) {
83
+ const backupPath = join(this.backupDir, relativePath);
84
+ // First-write-wins: skip if backup already exists
85
+ if (await this.has(relativePath))
86
+ return;
87
+ await mkdir(dirname(backupPath), { recursive: true });
88
+ // Write atomically: write to a .tmp sibling then rename so a crash mid-write
89
+ // never leaves a partial (corrupt) backup that first-write-wins would preserve.
90
+ const tmpPath = `${backupPath}.tmp`;
91
+ try {
92
+ await writeFile(tmpPath, content, 'utf8');
93
+ await rename(tmpPath, backupPath);
94
+ }
95
+ catch (error) {
96
+ await rm(tmpPath, { force: true }).catch(() => { });
97
+ throw error;
98
+ }
99
+ }
100
+ /**
101
+ * Remove empty ancestor directories up to and including the backup root.
102
+ * Called after each file deletion to keep the directory tree clean.
103
+ */
104
+ async pruneEmptyDirs(startDir) {
105
+ let dir = startDir;
106
+ while (dir.startsWith(this.backupDir) && dir !== this.backupDir) {
107
+ try {
108
+ // eslint-disable-next-line no-await-in-loop
109
+ const entries = await readdir(dir);
110
+ if (entries.length > 0)
111
+ return;
112
+ // eslint-disable-next-line no-await-in-loop
113
+ await rm(dir, { recursive: true });
114
+ }
115
+ catch {
116
+ return;
117
+ }
118
+ dir = dirname(dir);
119
+ }
120
+ }
121
+ }
@@ -50,7 +50,7 @@ export class AuthHandler {
50
50
  const user = await this.userService.getCurrentUser(token.sessionKey);
51
51
  this.transport.broadcast(AuthEvents.STATE_CHANGED, {
52
52
  isAuthorized: true,
53
- user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id },
53
+ user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id, name: user.name },
54
54
  });
55
55
  }
56
56
  catch {
@@ -73,15 +73,16 @@ export class AuthHandler {
73
73
  tokenType: tokenData.tokenType,
74
74
  userEmail: user.email,
75
75
  userId: user.id,
76
+ userName: user.name,
76
77
  });
77
78
  await this.tokenStore.save(authToken);
78
79
  this.transport.broadcast(AuthEvents.LOGIN_COMPLETED, {
79
80
  success: true,
80
- user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id },
81
+ user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id, name: user.name },
81
82
  });
82
83
  this.transport.broadcast(AuthEvents.STATE_CHANGED, {
83
84
  isAuthorized: true,
84
- user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id },
85
+ user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id, name: user.name },
85
86
  });
86
87
  }
87
88
  catch (error) {
@@ -152,6 +153,7 @@ export class AuthHandler {
152
153
  email: user.email,
153
154
  hasOnboardedCli: user.hasOnboardedCli,
154
155
  id: user.id,
156
+ name: user.name,
155
157
  },
156
158
  };
157
159
  }
@@ -172,11 +174,12 @@ export class AuthHandler {
172
174
  tokenType: 'unnecessary',
173
175
  userEmail: user.email,
174
176
  userId: user.id,
177
+ userName: user.name,
175
178
  });
176
179
  await this.tokenStore.save(authToken);
177
180
  this.transport.broadcast(AuthEvents.STATE_CHANGED, {
178
181
  isAuthorized: true,
179
- user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id },
182
+ user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id, name: user.name },
180
183
  });
181
184
  return { success: true, userEmail: user.email };
182
185
  }
@@ -214,11 +217,12 @@ export class AuthHandler {
214
217
  tokenType: refreshedTokenData.tokenType,
215
218
  userEmail: user.email,
216
219
  userId: user.id,
220
+ userName: user.name,
217
221
  });
218
222
  await this.tokenStore.save(newToken);
219
223
  this.transport.broadcast(AuthEvents.STATE_CHANGED, {
220
224
  isAuthorized: true,
221
- user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id },
225
+ user: { email: user.email, hasOnboardedCli: user.hasOnboardedCli, id: user.id, name: user.name },
222
226
  });
223
227
  return { success: true };
224
228
  }
@@ -1,4 +1,5 @@
1
1
  import type { ContextTreeChanges } from '../../../../shared/types/context-tree-changes.js';
2
+ import type { IContextTreeService } from '../../../core/interfaces/context-tree/i-context-tree-service.js';
2
3
  /**
3
4
  * Resolves a transport client ID to its associated project path.
4
5
  * Returns undefined for global-scope clients that haven't been associated with a project.
@@ -21,3 +22,11 @@ export type ProjectBroadcaster = <T = unknown>(projectPath: string, event: strin
21
22
  * Returns true if the changes object has any additions, modifications, or deletions.
22
23
  */
23
24
  export declare function hasAnyChanges(changes: ContextTreeChanges): boolean;
25
+ /**
26
+ * Throws GitVcInitializedError if the project has ByteRover version control initialized.
27
+ * Used by old snapshot-based handlers to block operations when the user has switched to /vc commands.
28
+ */
29
+ export declare function guardAgainstGitVc(params: {
30
+ contextTreeService: IContextTreeService;
31
+ projectPath: string;
32
+ }): Promise<void>;
@@ -1,3 +1,4 @@
1
+ import { GitVcInitializedError } from '../../../core/domain/errors/task-error.js';
1
2
  /**
2
3
  * Resolves the project path for a client, throwing if unavailable.
3
4
  * Use this in handlers that REQUIRE a project context.
@@ -19,3 +20,13 @@ export function resolveRequiredProjectPath(resolver, clientId) {
19
20
  export function hasAnyChanges(changes) {
20
21
  return changes.added.length > 0 || changes.modified.length > 0 || changes.deleted.length > 0;
21
22
  }
23
+ /**
24
+ * Throws GitVcInitializedError if the project has ByteRover version control initialized.
25
+ * Used by old snapshot-based handlers to block operations when the user has switched to /vc commands.
26
+ */
27
+ export async function guardAgainstGitVc(params) {
28
+ const hasGitVc = await params.contextTreeService.hasGitRepo(params.projectPath);
29
+ if (hasGitVc) {
30
+ throw new GitVcInitializedError('ByteRover version control is initialized');
31
+ }
32
+ }
@@ -22,7 +22,11 @@ export { PushHandler } from './push-handler.js';
22
22
  export type { PushHandlerDeps } from './push-handler.js';
23
23
  export { ResetHandler } from './reset-handler.js';
24
24
  export type { ResetHandlerDeps } from './reset-handler.js';
25
+ export { ReviewHandler } from './review-handler.js';
26
+ export type { ReviewHandlerDeps } from './review-handler.js';
25
27
  export { SpaceHandler } from './space-handler.js';
26
28
  export type { SpaceHandlerDeps } from './space-handler.js';
27
29
  export { StatusHandler } from './status-handler.js';
28
30
  export type { StatusHandlerDeps } from './status-handler.js';
31
+ export { VcHandler } from './vc-handler.js';
32
+ export type { IVcHandlerDeps } from './vc-handler.js';
@@ -10,5 +10,7 @@ export { ProviderHandler } from './provider-handler.js';
10
10
  export { PullHandler } from './pull-handler.js';
11
11
  export { PushHandler } from './push-handler.js';
12
12
  export { ResetHandler } from './reset-handler.js';
13
+ export { ReviewHandler } from './review-handler.js';
13
14
  export { SpaceHandler } from './space-handler.js';
14
15
  export { StatusHandler } from './status-handler.js';
16
+ export { VcHandler } from './vc-handler.js';
@@ -47,4 +47,5 @@ export declare class InitHandler {
47
47
  private handleGetAgents;
48
48
  private handleGetSpaces;
49
49
  private handleGetTeams;
50
+ private handleLocalInit;
50
51
  }