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
@@ -0,0 +1,13 @@
1
+ import { type Router } from 'express';
2
+ import type { ICurateLogStore } from '../../core/interfaces/storage/i-curate-log-store.js';
3
+ import type { IReviewBackupStore } from '../../core/interfaces/storage/i-review-backup-store.js';
4
+ export interface ReviewApiOptions {
5
+ /** File operations for the context tree. Defaults to real fs operations. Injectable for testing. */
6
+ contextTreeFs?: {
7
+ deleteFile: (absolutePath: string) => Promise<void>;
8
+ writeFile: (absolutePath: string, content: string) => Promise<void>;
9
+ };
10
+ curateLogStoreFactory: (projectPath: string) => ICurateLogStore;
11
+ reviewBackupStoreFactory: (projectPath: string) => IReviewBackupStore;
12
+ }
13
+ export declare function createReviewApiRouter(options: ReviewApiOptions): Router;
@@ -0,0 +1,286 @@
1
+ import express from 'express';
2
+ import { unlink as fsUnlink, writeFile as fsWriteFile, mkdir, readFile } from 'node:fs/promises';
3
+ import { dirname, isAbsolute, join, relative } from 'node:path';
4
+ import { BRV_DIR, CONTEXT_TREE_DIR } from '../../constants.js';
5
+ import { MarkdownWriter } from '../../core/domain/knowledge/markdown-writer.js';
6
+ import { getReviewPageHtml } from './review-ui.js';
7
+ // ── Helpers ──────────────────────────────────────────────────────────────────
8
+ function decodeProjectPath(encoded) {
9
+ try {
10
+ return Buffer.from(encoded, 'base64url').toString('utf8');
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ }
16
+ function getContextTreeDir(projectPath) {
17
+ return join(projectPath, BRV_DIR, CONTEXT_TREE_DIR);
18
+ }
19
+ /**
20
+ * Returns true if filePath escapes outside the given root directory.
21
+ * Guards against path traversal (e.g. ../../etc/passwd).
22
+ */
23
+ function isTraversal(rootDir, filePath) {
24
+ const resolved = relative(rootDir, join(rootDir, filePath));
25
+ return resolved.startsWith('..') || isAbsolute(resolved);
26
+ }
27
+ /**
28
+ * Extract summary from markdown file content's frontmatter.
29
+ */
30
+ function extractSummaryFromContent(content) {
31
+ try {
32
+ return MarkdownWriter.parseContent(content).summary;
33
+ }
34
+ catch {
35
+ return undefined;
36
+ }
37
+ }
38
+ /**
39
+ * Scans curate log entries for operations with reviewStatus === 'pending'
40
+ * and groups them by file path (relative to context tree).
41
+ *
42
+ * Reads live summaries from the actual files (current + backup) so that
43
+ * reviews always reflect the latest state, even after subsequent curations.
44
+ */
45
+ async function collectPendingFiles(entries, contextTreeDir, backupStore) {
46
+ const pendingByFile = new Map();
47
+ for (const entry of entries) {
48
+ for (let i = 0; i < entry.operations.length; i++) {
49
+ const op = entry.operations[i];
50
+ if (op.reviewStatus !== 'pending')
51
+ continue;
52
+ if (!op.filePath)
53
+ continue;
54
+ const relativePath = relative(contextTreeDir, op.filePath);
55
+ // Skip paths that resolve outside the context tree (e.g., absolute paths from different projects)
56
+ if (relativePath.startsWith('..'))
57
+ continue;
58
+ let ops = pendingByFile.get(relativePath);
59
+ if (!ops) {
60
+ ops = [];
61
+ pendingByFile.set(relativePath, ops);
62
+ }
63
+ ops.push({
64
+ confidence: op.confidence,
65
+ impact: op.impact,
66
+ logId: entry.id,
67
+ operationIndex: i,
68
+ previousSummary: op.previousSummary,
69
+ reason: op.reason,
70
+ summary: op.summary,
71
+ type: op.type,
72
+ });
73
+ }
74
+ }
75
+ // Read live summaries from actual files (current + backup) in parallel
76
+ const sortedEntries = [...pendingByFile.entries()].sort((a, b) => a[0].localeCompare(b[0]));
77
+ const results = await Promise.all(sortedEntries.map(async ([path, operations]) => {
78
+ let currentSummary;
79
+ let previousSummary;
80
+ try {
81
+ const currentContent = await readFile(join(contextTreeDir, path), 'utf8');
82
+ currentSummary = extractSummaryFromContent(currentContent);
83
+ }
84
+ catch {
85
+ // File may have been deleted (DELETE operation) — that's expected
86
+ }
87
+ try {
88
+ const backupContent = await backupStore.read(path);
89
+ if (backupContent !== null) {
90
+ previousSummary = extractSummaryFromContent(backupContent);
91
+ }
92
+ }
93
+ catch {
94
+ // No backup — file was newly added
95
+ }
96
+ // Fall back to curate log values if live reads yielded nothing
97
+ if (!currentSummary && !previousSummary) {
98
+ const lastOp = operations.at(-1);
99
+ currentSummary = lastOp.summary;
100
+ previousSummary = lastOp.previousSummary;
101
+ }
102
+ return { currentSummary, operations, path, previousSummary };
103
+ }));
104
+ return results;
105
+ }
106
+ /**
107
+ * Finds all pending operations that match a given relative file path and
108
+ * returns update tasks (logId + operationIndex + type).
109
+ */
110
+ function findPendingUpdates(entries, contextTreeDir, targetPath) {
111
+ const updates = [];
112
+ for (const entry of entries) {
113
+ for (let i = 0; i < entry.operations.length; i++) {
114
+ const op = entry.operations[i];
115
+ if (op.reviewStatus !== 'pending')
116
+ continue;
117
+ if (!op.filePath)
118
+ continue;
119
+ const relativePath = relative(contextTreeDir, op.filePath);
120
+ if (relativePath === targetPath) {
121
+ updates.push({ additionalFilePaths: op.additionalFilePaths, logId: entry.id, operationIndex: i, type: op.type });
122
+ }
123
+ }
124
+ }
125
+ return updates;
126
+ }
127
+ // ── Router factory ───────────────────────────────────────────────────────────
128
+ export function createReviewApiRouter(options) {
129
+ // eslint-disable-next-line new-cap
130
+ const router = express.Router();
131
+ const ctFs = options.contextTreeFs ?? {
132
+ async deleteFile(absolutePath) {
133
+ await fsUnlink(absolutePath);
134
+ },
135
+ async writeFile(absolutePath, content) {
136
+ await mkdir(dirname(absolutePath), { recursive: true });
137
+ await fsWriteFile(absolutePath, content, 'utf8');
138
+ },
139
+ };
140
+ // Parse JSON request bodies
141
+ router.use(express.json());
142
+ // GET /review — serve the review UI HTML page
143
+ router.get('/review', (_req, res) => {
144
+ res.type('html').send(getReviewPageHtml());
145
+ });
146
+ // GET /api/review/pending?project=<base64url>
147
+ // Returns list of files with pending review operations
148
+ router.get('/api/review/pending', (async (req, res) => {
149
+ const projectEncoded = req.query.project;
150
+ if (typeof projectEncoded !== 'string' || !projectEncoded) {
151
+ res.status(400).json({ error: 'Missing project parameter' });
152
+ return;
153
+ }
154
+ const projectPath = decodeProjectPath(projectEncoded);
155
+ if (!projectPath) {
156
+ res.status(400).json({ error: 'Invalid project parameter' });
157
+ return;
158
+ }
159
+ try {
160
+ const store = options.curateLogStoreFactory(projectPath);
161
+ const entries = await store.list();
162
+ const contextTreeDir = getContextTreeDir(projectPath);
163
+ const backupStore = options.reviewBackupStoreFactory(projectPath);
164
+ const files = await collectPendingFiles(entries, contextTreeDir, backupStore);
165
+ res.json({ files, projectPath });
166
+ }
167
+ catch (error) {
168
+ res.status(500).json({ error: error instanceof Error ? error.message : 'Internal error' });
169
+ }
170
+ }));
171
+ // GET /api/review/diff?project=<base64url>&path=<relative_path>
172
+ // Returns old (backup) and new (current) content for diff rendering
173
+ router.get('/api/review/diff', (async (req, res) => {
174
+ const projectEncoded = req.query.project;
175
+ const filePath = req.query.path;
176
+ if (typeof projectEncoded !== 'string' || typeof filePath !== 'string' || !projectEncoded || !filePath) {
177
+ res.status(400).json({ error: 'Missing project or path parameter' });
178
+ return;
179
+ }
180
+ const projectPath = decodeProjectPath(projectEncoded);
181
+ if (!projectPath) {
182
+ res.status(400).json({ error: 'Invalid project parameter' });
183
+ return;
184
+ }
185
+ try {
186
+ const contextTreeDir = getContextTreeDir(projectPath);
187
+ if (isTraversal(contextTreeDir, filePath)) {
188
+ res.status(400).json({ error: 'Invalid file path' });
189
+ return;
190
+ }
191
+ const backupStore = options.reviewBackupStoreFactory(projectPath);
192
+ // Read backup (pre-curate) content
193
+ const oldContent = (await backupStore.read(filePath)) ?? '';
194
+ // Read current (post-curate) content
195
+ let newContent = '';
196
+ try {
197
+ newContent = await readFile(join(contextTreeDir, filePath), 'utf8');
198
+ }
199
+ catch {
200
+ // File may have been deleted — that's a valid diff (content → empty)
201
+ }
202
+ res.json({ newContent, oldContent, path: filePath });
203
+ }
204
+ catch (error) {
205
+ res.status(500).json({ error: error instanceof Error ? error.message : 'Internal error' });
206
+ }
207
+ }));
208
+ // POST /api/review/decide
209
+ // Body: { project: string (base64url), path: string, decision: 'approved' | 'rejected' }
210
+ // Updates reviewStatus for all pending operations on the given file
211
+ router.post('/api/review/decide', (async (req, res) => {
212
+ const { decision, path: filePath, project: projectEncoded } = req.body;
213
+ if (!projectEncoded || !filePath || !decision) {
214
+ res.status(400).json({ error: 'Missing required fields: project, path, decision' });
215
+ return;
216
+ }
217
+ if (decision !== 'approved' && decision !== 'rejected') {
218
+ res.status(400).json({ error: 'Invalid decision — must be "approved" or "rejected"' });
219
+ return;
220
+ }
221
+ const projectPath = decodeProjectPath(projectEncoded);
222
+ if (!projectPath) {
223
+ res.status(400).json({ error: 'Invalid project parameter' });
224
+ return;
225
+ }
226
+ try {
227
+ const store = options.curateLogStoreFactory(projectPath);
228
+ const contextTreeDir = getContextTreeDir(projectPath);
229
+ if (isTraversal(contextTreeDir, filePath)) {
230
+ res.status(400).json({ error: 'Invalid file path' });
231
+ return;
232
+ }
233
+ const entries = await store.list();
234
+ const updates = findPendingUpdates(entries, contextTreeDir, filePath);
235
+ let reverted = false;
236
+ if (updates.length > 0) {
237
+ const backupStore = options.reviewBackupStoreFactory(projectPath);
238
+ const allAdditionalPaths = [
239
+ ...new Set(updates.flatMap((u) => u.additionalFilePaths ?? [])),
240
+ ];
241
+ if (decision === 'rejected') {
242
+ // Revert the primary file
243
+ const absolutePath = join(contextTreeDir, filePath);
244
+ const backupContent = await backupStore.read(filePath);
245
+ // null means ADD (new file) → remove it; backup exists → restore pre-curate content
246
+ await (backupContent === null
247
+ ? ctFs.deleteFile(absolutePath).catch(() => { })
248
+ : ctFs.writeFile(absolutePath, backupContent));
249
+ // Restore additional files (MERGE source, folder DELETE contents).
250
+ // Best-effort: partial failures must not block the log update below.
251
+ await Promise.allSettled(allAdditionalPaths.map(async (absPath) => {
252
+ const relPath = relative(contextTreeDir, absPath);
253
+ const content = await backupStore.read(relPath);
254
+ if (content !== null) {
255
+ await ctFs.writeFile(absPath, content);
256
+ }
257
+ }));
258
+ reverted = true;
259
+ }
260
+ // On both approve and reject: clear the backup so future modifications
261
+ // use the current state as the new baseline
262
+ await backupStore.delete(filePath);
263
+ await Promise.all(allAdditionalPaths.map((absPath) => backupStore.delete(relative(contextTreeDir, absPath))));
264
+ }
265
+ // Batch-update grouped by logId (one read+write per entry file)
266
+ const byLogId = new Map();
267
+ for (const { logId, operationIndex } of updates) {
268
+ let batch = byLogId.get(logId);
269
+ if (!batch) {
270
+ batch = [];
271
+ byLogId.set(logId, batch);
272
+ }
273
+ batch.push({ operationIndex, reviewStatus: decision });
274
+ }
275
+ const logIdBatches = [...byLogId.entries()];
276
+ const results = await Promise.all(logIdBatches.map(([logId, batch]) => store.batchUpdateOperationReviewStatus(logId, batch)));
277
+ // Assumes all indices in each batch are valid — guaranteed by findPendingUpdates which only produces indices from actual entries.
278
+ const updatedCount = logIdBatches.reduce((sum, [, batch], i) => sum + (results[i] ? batch.length : 0), 0);
279
+ res.json({ reverted, success: true, updatedCount });
280
+ }
281
+ catch (error) {
282
+ res.status(500).json({ error: error instanceof Error ? error.message : 'Internal error' });
283
+ }
284
+ }));
285
+ return router;
286
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Returns the complete HTML page for the local HITL review UI.
3
+ *
4
+ * Self-contained: all CSS and JS are inline. No external dependencies.
5
+ * Shows semantic summaries of previous/current versions for each operation.
6
+ */
7
+ export declare function getReviewPageHtml(): string;