@shepai/cli 1.126.0 → 1.127.0-pr406.05077bf

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 (372) hide show
  1. package/apis/json-schema/FeatureFlags.yaml +5 -0
  2. package/dist/packages/core/src/application/ports/output/repositories/feature-repository.interface.d.ts +11 -0
  3. package/dist/packages/core/src/application/ports/output/repositories/feature-repository.interface.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +5 -2
  5. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
  6. package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts +25 -0
  7. package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.d.ts.map +1 -1
  9. package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.js +7 -2
  10. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.d.ts.map +1 -1
  11. package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.js +7 -2
  12. package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts +49 -0
  13. package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts.map +1 -0
  14. package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.js +188 -0
  15. package/dist/packages/core/src/application/use-cases/features/branch-name-utils.d.ts +33 -0
  16. package/dist/packages/core/src/application/use-cases/features/branch-name-utils.d.ts.map +1 -0
  17. package/dist/packages/core/src/application/use-cases/features/branch-name-utils.js +77 -0
  18. package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
  19. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +1 -0
  20. package/dist/packages/core/src/domain/generated/output.d.ts +4 -0
  21. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  22. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  23. package/dist/packages/core/src/infrastructure/di/container.js +5 -0
  24. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +1 -0
  25. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  26. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +2 -0
  27. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/040-add-feature-flag-adopt-branch.d.ts +10 -0
  28. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/040-add-feature-flag-adopt-branch.d.ts.map +1 -0
  29. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/040-add-feature-flag-adopt-branch.js +15 -0
  30. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts +5 -0
  31. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
  32. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +9 -0
  33. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts +1 -0
  34. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
  35. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +8 -0
  36. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
  37. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +3 -2
  38. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
  39. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +1 -0
  40. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  41. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +3 -2
  42. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +1 -1
  43. package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts +2 -0
  44. package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
  45. package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +39 -0
  46. package/dist/src/presentation/cli/commands/feat/adopt.command.d.ts +14 -0
  47. package/dist/src/presentation/cli/commands/feat/adopt.command.d.ts.map +1 -0
  48. package/dist/src/presentation/cli/commands/feat/adopt.command.js +46 -0
  49. package/dist/src/presentation/cli/commands/feat/index.d.ts.map +1 -1
  50. package/dist/src/presentation/cli/commands/feat/index.js +3 -1
  51. package/dist/src/presentation/web/app/(dashboard)/@drawer/adopt/page.d.ts +10 -0
  52. package/dist/src/presentation/web/app/(dashboard)/@drawer/adopt/page.d.ts.map +1 -0
  53. package/dist/src/presentation/web/app/(dashboard)/@drawer/adopt/page.js +32 -0
  54. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  55. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +37 -32
  56. package/dist/src/presentation/web/app/actions/adopt-branch.d.ts +11 -0
  57. package/dist/src/presentation/web/app/actions/adopt-branch.d.ts.map +1 -0
  58. package/dist/src/presentation/web/app/actions/adopt-branch.js +20 -0
  59. package/dist/src/presentation/web/app/actions/approve-feature.d.ts.map +1 -1
  60. package/dist/src/presentation/web/app/actions/approve-feature.js +4 -9
  61. package/dist/src/presentation/web/app/actions/list-branches.d.ts +6 -0
  62. package/dist/src/presentation/web/app/actions/list-branches.d.ts.map +1 -0
  63. package/dist/src/presentation/web/app/actions/list-branches.js +18 -0
  64. package/dist/src/presentation/web/app/actions/reject-feature.d.ts.map +1 -1
  65. package/dist/src/presentation/web/app/actions/reject-feature.js +4 -9
  66. package/dist/src/presentation/web/app/build-feature-node-data.d.ts.map +1 -1
  67. package/dist/src/presentation/web/app/build-feature-node-data.js +1 -0
  68. package/dist/src/presentation/web/app/build-graph-nodes.js +1 -0
  69. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.d.ts +20 -0
  70. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.d.ts.map +1 -0
  71. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.js +105 -0
  72. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.d.ts +38 -0
  73. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.d.ts.map +1 -0
  74. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.js +161 -0
  75. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-drawer-client.d.ts +7 -0
  76. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-drawer-client.d.ts.map +1 -0
  77. package/dist/src/presentation/web/components/common/control-center-drawer/adopt-drawer-client.js +78 -0
  78. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
  79. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +4 -1
  80. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
  81. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +4 -0
  82. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +2 -0
  83. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  84. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.d.ts.map +1 -1
  85. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.js +3 -1
  86. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.d.ts.map +1 -1
  87. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.js +3 -0
  88. package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
  89. package/dist/src/presentation/web/components/features/settings/settings-page-client.js +10 -1
  90. package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts.map +1 -1
  91. package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.js +1 -0
  92. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.d.ts.map +1 -1
  93. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +16 -3
  94. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.js +1 -1
  95. package/dist/src/presentation/web/hooks/feature-flags-context.d.ts.map +1 -1
  96. package/dist/src/presentation/web/hooks/feature-flags-context.js +6 -1
  97. package/dist/src/presentation/web/hooks/use-feature-logs.d.ts.map +1 -1
  98. package/dist/src/presentation/web/hooks/use-feature-logs.js +7 -2
  99. package/dist/src/presentation/web/lib/feature-flags.d.ts +2 -0
  100. package/dist/src/presentation/web/lib/feature-flags.d.ts.map +1 -1
  101. package/dist/src/presentation/web/lib/feature-flags.js +5 -0
  102. package/dist/tsconfig.build.tsbuildinfo +1 -1
  103. package/package.json +1 -1
  104. package/web/.next/BUILD_ID +1 -1
  105. package/web/.next/app-path-routes-manifest.json +1 -0
  106. package/web/.next/build-manifest.json +4 -4
  107. package/web/.next/fallback-build-manifest.json +2 -2
  108. package/web/.next/prerender-manifest.json +3 -3
  109. package/web/.next/required-server-files.js +3 -3
  110. package/web/.next/required-server-files.json +3 -3
  111. package/web/.next/routes-manifest.json +6 -0
  112. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/app-paths-manifest.json +3 -0
  113. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/build-manifest.json +18 -0
  114. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/next-font-manifest.json +6 -0
  115. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/react-loadable-manifest.json +1 -0
  116. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +335 -0
  117. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +21 -0
  118. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.map +5 -0
  119. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -0
  120. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +2 -0
  121. package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +2 -2
  122. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
  123. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  124. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  125. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  126. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +2 -2
  127. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  128. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
  129. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  130. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  131. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +2 -2
  132. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
  133. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  134. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  135. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  136. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +2 -2
  137. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  138. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  139. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  140. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  141. package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +2 -2
  142. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
  143. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  144. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  145. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  146. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +2 -2
  147. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
  148. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
  149. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  150. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  151. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +2 -2
  152. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
  153. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  154. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  155. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  156. package/web/.next/server/app/(dashboard)/page/build-manifest.json +2 -2
  157. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
  158. package/web/.next/server/app/(dashboard)/page.js +1 -1
  159. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  160. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  161. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +2 -2
  162. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
  163. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  164. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  165. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  166. package/web/.next/server/app/_global-error/page/build-manifest.json +2 -2
  167. package/web/.next/server/app/_global-error/page.js +1 -1
  168. package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  169. package/web/.next/server/app/_global-error.html +2 -2
  170. package/web/.next/server/app/_global-error.rsc +1 -1
  171. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  172. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  173. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  174. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  175. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  176. package/web/.next/server/app/_not-found/page/build-manifest.json +2 -2
  177. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  178. package/web/.next/server/app/_not-found/page.js +1 -1
  179. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  180. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  181. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  182. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  183. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  184. package/web/.next/server/app/settings/page/build-manifest.json +2 -2
  185. package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
  186. package/web/.next/server/app/settings/page.js +1 -1
  187. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  188. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  189. package/web/.next/server/app/skills/page/build-manifest.json +2 -2
  190. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  191. package/web/.next/server/app/skills/page.js +3 -3
  192. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  193. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  194. package/web/.next/server/app/tools/page/build-manifest.json +2 -2
  195. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  196. package/web/.next/server/app/tools/page.js +1 -1
  197. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  198. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  199. package/web/.next/server/app/version/page/build-manifest.json +2 -2
  200. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  201. package/web/.next/server/app/version/page.js +1 -1
  202. package/web/.next/server/app/version/page.js.nft.json +1 -1
  203. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  204. package/web/.next/server/app-paths-manifest.json +1 -0
  205. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  206. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  207. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  208. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  209. package/web/.next/server/chunks/[root-of-the-server]__dcd4f847._.js.map +1 -1
  210. package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_94d75bc3._.js +3 -0
  211. package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_94d75bc3._.js.map +1 -0
  212. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_fbb88113.js +3 -0
  213. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_fbb88113.js.map +1 -0
  214. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  215. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  216. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_fdfbf5cc.js +1 -1
  217. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_fdfbf5cc.js.map +1 -1
  218. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_d8fa0b5f.js +1 -1
  219. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_d8fa0b5f.js.map +1 -1
  220. package/web/.next/server/chunks/ssr/[root-of-the-server]__02c84e6b._.js +3 -0
  221. package/web/.next/server/chunks/ssr/[root-of-the-server]__02c84e6b._.js.map +1 -0
  222. package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
  223. package/web/.next/server/chunks/ssr/[root-of-the-server]__23b5ca2c._.js +1 -1
  224. package/web/.next/server/chunks/ssr/[root-of-the-server]__248b9fc3._.js +1 -1
  225. package/web/.next/server/chunks/ssr/[root-of-the-server]__248b9fc3._.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/[root-of-the-server]__357de47c._.js +2 -2
  227. package/web/.next/server/chunks/ssr/[root-of-the-server]__357de47c._.js.map +1 -1
  228. package/web/.next/server/chunks/ssr/{[root-of-the-server]__2dddfea9._.js → [root-of-the-server]__4af0afe0._.js} +2 -2
  229. package/web/.next/server/chunks/ssr/{[root-of-the-server]__2dddfea9._.js.map → [root-of-the-server]__4af0afe0._.js.map} +1 -1
  230. package/web/.next/server/chunks/ssr/[root-of-the-server]__4ed9b909._.js +3 -0
  231. package/web/.next/server/chunks/ssr/[root-of-the-server]__4ed9b909._.js.map +1 -0
  232. package/web/.next/server/chunks/ssr/[root-of-the-server]__5edfc56b._.js +1 -1
  233. package/web/.next/server/chunks/ssr/[root-of-the-server]__6677a82c._.js +1 -1
  234. package/web/.next/server/chunks/ssr/[root-of-the-server]__6677a82c._.js.map +1 -1
  235. package/web/.next/server/chunks/ssr/[root-of-the-server]__67fe07fe._.js +1 -1
  236. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  237. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  238. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +2 -2
  239. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  240. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  241. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  242. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c553503._.js +2 -2
  243. package/web/.next/server/chunks/ssr/{[root-of-the-server]__4c7486cb._.js → [root-of-the-server]__9bc1434f._.js} +2 -2
  244. package/web/.next/server/chunks/ssr/{[root-of-the-server]__4c7486cb._.js.map → [root-of-the-server]__9bc1434f._.js.map} +1 -1
  245. package/web/.next/server/chunks/ssr/[root-of-the-server]__a50a7e39._.js +2 -2
  246. package/web/.next/server/chunks/ssr/[root-of-the-server]__a50a7e39._.js.map +1 -1
  247. package/web/.next/server/chunks/ssr/[root-of-the-server]__c1262d08._.js +3 -0
  248. package/web/.next/server/chunks/ssr/[root-of-the-server]__c1262d08._.js.map +1 -0
  249. package/web/.next/server/chunks/ssr/[root-of-the-server]__dfc367f2._.js +1 -1
  250. package/web/.next/server/chunks/ssr/[root-of-the-server]__dfc367f2._.js.map +1 -1
  251. package/web/.next/server/chunks/ssr/[root-of-the-server]__e7f61cc6._.js +1 -1
  252. package/web/.next/server/chunks/ssr/[root-of-the-server]__e7f61cc6._.js.map +1 -1
  253. package/web/.next/server/chunks/ssr/[root-of-the-server]__fe48d2dc._.js +1 -1
  254. package/web/.next/server/chunks/ssr/[root-of-the-server]__fe48d2dc._.js.map +1 -1
  255. package/web/.next/server/chunks/ssr/{_821bbcc5._.js → _1f0cbda2._.js} +2 -2
  256. package/web/.next/server/chunks/ssr/{_821bbcc5._.js.map → _1f0cbda2._.js.map} +1 -1
  257. package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
  258. package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
  259. package/web/.next/server/chunks/ssr/_4093a637._.js +5 -0
  260. package/web/.next/server/chunks/ssr/_4093a637._.js.map +1 -0
  261. package/web/.next/server/chunks/ssr/_583a83fb._.js +3 -0
  262. package/web/.next/server/chunks/ssr/_583a83fb._.js.map +1 -0
  263. package/web/.next/server/chunks/ssr/_794c45e6._.js +3 -0
  264. package/web/.next/server/chunks/ssr/_794c45e6._.js.map +1 -0
  265. package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
  266. package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
  267. package/web/.next/server/chunks/ssr/_918887c5._.js +1 -1
  268. package/web/.next/server/chunks/ssr/_918887c5._.js.map +1 -1
  269. package/web/.next/server/chunks/ssr/_9f56cf8f._.js +3 -0
  270. package/web/.next/server/chunks/ssr/_9f56cf8f._.js.map +1 -0
  271. package/web/.next/server/chunks/ssr/_a187fd7e._.js +3 -0
  272. package/web/.next/server/chunks/ssr/_a187fd7e._.js.map +1 -0
  273. package/web/.next/server/chunks/ssr/_a37f5f18._.js +1 -1
  274. package/web/.next/server/chunks/ssr/_a37f5f18._.js.map +1 -1
  275. package/web/.next/server/chunks/ssr/_a5aa6371._.js +9 -0
  276. package/web/.next/server/chunks/ssr/_a5aa6371._.js.map +1 -0
  277. package/web/.next/server/chunks/ssr/_a9f57758._.js +3 -0
  278. package/web/.next/server/chunks/ssr/_a9f57758._.js.map +1 -0
  279. package/web/.next/server/chunks/ssr/_b730ac57._.js +3 -0
  280. package/web/.next/server/chunks/ssr/_b730ac57._.js.map +1 -0
  281. package/web/.next/server/chunks/ssr/_d4b20e29._.js.map +1 -1
  282. package/web/.next/server/chunks/ssr/_d5206f22._.js +4 -0
  283. package/web/.next/server/chunks/ssr/_d5206f22._.js.map +1 -0
  284. package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
  285. package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
  286. package/web/.next/server/chunks/ssr/_f4d222d6._.js +1 -1
  287. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  288. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  289. package/web/.next/server/chunks/ssr/f7870_sonner_dist_index_mjs_dbf63824._.js +3 -0
  290. package/web/.next/server/chunks/ssr/f7870_sonner_dist_index_mjs_dbf63824._.js.map +1 -0
  291. package/web/.next/server/chunks/ssr/node_modules__pnpm_026172d1._.js +3 -0
  292. package/web/.next/server/chunks/ssr/node_modules__pnpm_026172d1._.js.map +1 -0
  293. package/web/.next/server/chunks/ssr/src_presentation_web_1dac2051._.js +3 -0
  294. package/web/.next/server/chunks/ssr/src_presentation_web_1dac2051._.js.map +1 -0
  295. package/web/.next/server/chunks/ssr/src_presentation_web_9db47db7._.js +2 -2
  296. package/web/.next/server/chunks/ssr/src_presentation_web_9db47db7._.js.map +1 -1
  297. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f66cd328.js +1 -1
  298. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f66cd328.js.map +1 -1
  299. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  300. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  301. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  302. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  303. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  304. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  305. package/web/.next/server/chunks/ssr/src_presentation_web_db9fa0c2._.js +3 -0
  306. package/web/.next/server/chunks/ssr/src_presentation_web_db9fa0c2._.js.map +1 -0
  307. package/web/.next/server/chunks/ssr/src_presentation_web_ede4a227._.js +2 -2
  308. package/web/.next/server/chunks/ssr/src_presentation_web_ede4a227._.js.map +1 -1
  309. package/web/.next/server/middleware-build-manifest.js +2 -2
  310. package/web/.next/server/pages/500.html +2 -2
  311. package/web/.next/server/server-reference-manifest.js +1 -1
  312. package/web/.next/server/server-reference-manifest.json +204 -34
  313. package/web/.next/static/chunks/05e9c71e5e4cf531.js +1 -0
  314. package/web/.next/static/chunks/{044f4665499a9656.js → 1040108af0ee2e3c.js} +1 -1
  315. package/web/.next/static/chunks/1214f13d8edee410.js +1 -0
  316. package/web/.next/static/chunks/{4ac11847f73b50d6.js → 18370eb43da93775.js} +1 -1
  317. package/web/.next/static/chunks/33d2f67ad4814aba.css +1 -0
  318. package/web/.next/static/chunks/4cfbbf947d205588.js +1 -0
  319. package/web/.next/static/chunks/4e10357c1c01f8a7.js +1 -0
  320. package/web/.next/static/chunks/6300c246e812fd4a.js +1 -0
  321. package/web/.next/static/chunks/8080c842b0358904.js +1 -0
  322. package/web/.next/static/chunks/{112cf5891d1ca558.js → 82f7582061933bd7.js} +1 -1
  323. package/web/.next/static/chunks/{ed3a602003bcb31b.js → 89aac43287d73b02.js} +1 -1
  324. package/web/.next/static/chunks/a668451a590d746f.js +1 -0
  325. package/web/.next/static/chunks/a8ba3f3e2b0f87aa.js +1 -0
  326. package/web/.next/static/chunks/{dcfed2c9b7cd1cb4.js → b4c03f76a4c23504.js} +1 -1
  327. package/web/.next/static/chunks/{37ada233462bcaec.js → cd45aed9c46e1bf5.js} +1 -1
  328. package/web/.next/static/chunks/d04de4be30ab78ca.js +3 -0
  329. package/web/.next/static/chunks/{4ac4a43b7eb441e1.js → d2d01dc183a6d94e.js} +2 -2
  330. package/web/.next/static/chunks/facfb85307fb64ca.js +2 -0
  331. package/web/.next/static/chunks/{turbopack-426d9bc2450816ba.js → turbopack-080e470ea902d0ba.js} +1 -1
  332. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_d0119342._.js +0 -3
  333. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_d0119342._.js.map +0 -1
  334. package/web/.next/server/chunks/ssr/[root-of-the-server]__52485955._.js +0 -3
  335. package/web/.next/server/chunks/ssr/[root-of-the-server]__52485955._.js.map +0 -1
  336. package/web/.next/server/chunks/ssr/[root-of-the-server]__56ecbe40._.js +0 -3
  337. package/web/.next/server/chunks/ssr/[root-of-the-server]__56ecbe40._.js.map +0 -1
  338. package/web/.next/server/chunks/ssr/_243e3685._.js +0 -3
  339. package/web/.next/server/chunks/ssr/_243e3685._.js.map +0 -1
  340. package/web/.next/server/chunks/ssr/_3a4c94e3._.js +0 -3
  341. package/web/.next/server/chunks/ssr/_3a4c94e3._.js.map +0 -1
  342. package/web/.next/server/chunks/ssr/_6d26a08f._.js +0 -3
  343. package/web/.next/server/chunks/ssr/_6d26a08f._.js.map +0 -1
  344. package/web/.next/server/chunks/ssr/_9ac70f88._.js +0 -5
  345. package/web/.next/server/chunks/ssr/_9ac70f88._.js.map +0 -1
  346. package/web/.next/server/chunks/ssr/_b56e7571._.js +0 -3
  347. package/web/.next/server/chunks/ssr/_b56e7571._.js.map +0 -1
  348. package/web/.next/server/chunks/ssr/_e9703421._.js +0 -3
  349. package/web/.next/server/chunks/ssr/_e9703421._.js.map +0 -1
  350. package/web/.next/server/chunks/ssr/_f1a649e3._.js +0 -9
  351. package/web/.next/server/chunks/ssr/_f1a649e3._.js.map +0 -1
  352. package/web/.next/server/chunks/ssr/node_modules__pnpm_bc66dcc6._.js +0 -3
  353. package/web/.next/server/chunks/ssr/node_modules__pnpm_bc66dcc6._.js.map +0 -1
  354. package/web/.next/server/chunks/ssr/src_presentation_web_aeddd007._.js +0 -3
  355. package/web/.next/server/chunks/ssr/src_presentation_web_aeddd007._.js.map +0 -1
  356. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +0 -3
  357. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +0 -1
  358. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +0 -3
  359. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js.map +0 -1
  360. package/web/.next/static/chunks/1be7ac7a24009333.css +0 -1
  361. package/web/.next/static/chunks/303a1217006489b9.js +0 -1
  362. package/web/.next/static/chunks/4443ee9c7733399b.js +0 -1
  363. package/web/.next/static/chunks/52b56677c842e45f.js +0 -3
  364. package/web/.next/static/chunks/5fb66ee5a353a6c6.js +0 -1
  365. package/web/.next/static/chunks/6cfc75060a243290.js +0 -1
  366. package/web/.next/static/chunks/d60f93a1a25ab09d.js +0 -1
  367. package/web/.next/static/chunks/dbbb446493f21874.js +0 -1
  368. package/web/.next/static/chunks/de66f8d6a67c2361.js +0 -1
  369. package/web/.next/static/chunks/de8b0265f780e212.js +0 -2
  370. /package/web/.next/static/{4hN7Gtw--ruMbDn0FRI2- → QmKY2sB2k_AgVUOVaOm0n}/_buildManifest.js +0 -0
  371. /package/web/.next/static/{4hN7Gtw--ruMbDn0FRI2- → QmKY2sB2k_AgVUOVaOm0n}/_clientMiddlewareManifest.json +0 -0
  372. /package/web/.next/static/{4hN7Gtw--ruMbDn0FRI2- → QmKY2sB2k_AgVUOVaOm0n}/_ssgManifest.js +0 -0
@@ -5,52 +5,57 @@ import { getSettings } from '../../../../../packages/core/src/infrastructure/ser
5
5
  import { layoutWithDagre, CANVAS_LAYOUT_DEFAULTS } from '../../lib/layout-with-dagre.js';
6
6
  import { buildGraphNodes } from '../build-graph-nodes.js';
7
7
  const execFileAsync = promisify(execFileCb);
8
- async function gitCommand(cwd, args) {
9
- try {
10
- const { stdout } = await execFileAsync('git', args, { cwd });
11
- return stdout.trim();
12
- }
13
- catch {
14
- return null;
15
- }
16
- }
8
+ // Cache git info per repo path — git state rarely changes between polls
9
+ const gitInfoCache = new Map();
10
+ const GIT_INFO_TTL_MS = 30_000; // 30 seconds
11
+ /**
12
+ * Fetch branch, last commit info, and behind-count in a single git process.
13
+ *
14
+ * Results are cached for 5s so repeated polls don't spawn child processes.
15
+ */
17
16
  async function fetchRepoGitInfo(repo) {
17
+ const cached = gitInfoCache.get(repo.path);
18
+ if (cached && Date.now() < cached.expiresAt)
19
+ return cached.info;
20
+ const FIELD_SEP = '\x1f'; // ASCII unit separator — won't appear in commit messages
18
21
  try {
19
- const [currentBranch, commitMessage, committer] = await Promise.all([
20
- gitCommand(repo.path, ['symbolic-ref', '--short', 'HEAD']),
21
- gitCommand(repo.path, ['log', '-1', '--format=%s']),
22
- gitCommand(repo.path, ['log', '-1', '--format=%an']),
23
- ]);
22
+ // Single spawn: branch + commit subject + author
23
+ const { stdout } = await execFileAsync('git', ['-c', 'log.showSignature=false', 'log', '-1', `--format=%D${FIELD_SEP}%s${FIELD_SEP}%an`], { cwd: repo.path });
24
+ const [refsRaw, commitMessage, committer] = stdout.trim().split(FIELD_SEP);
25
+ // Extract current branch from decoration string (e.g. "HEAD -> main, origin/main")
26
+ const branchMatch = refsRaw?.match(/HEAD -> ([^,]+)/);
27
+ const currentBranch = branchMatch?.[1]?.trim() ?? null;
24
28
  if (!currentBranch)
25
29
  return null;
26
- // Try to determine the default branch to compute behind count
30
+ // Determine behind-count with one more spawn only when needed
27
31
  let behindCount = null;
28
- const defaultBranch = await gitCommand(repo.path, [
29
- 'symbolic-ref',
30
- '--short',
31
- 'refs/remotes/origin/HEAD',
32
- ]).then((ref) => ref?.replace('origin/', '') ?? null);
33
- if (defaultBranch && currentBranch !== defaultBranch) {
34
- const behind = await gitCommand(repo.path, [
35
- 'rev-list',
36
- '--count',
37
- `${currentBranch}..origin/${defaultBranch}`,
38
- ]);
39
- behindCount = behind !== null ? parseInt(behind, 10) : null;
40
- if (isNaN(behindCount))
41
- behindCount = null;
32
+ try {
33
+ const { stdout: defaultRef } = await execFileAsync('git', ['symbolic-ref', '--short', 'refs/remotes/origin/HEAD'], { cwd: repo.path });
34
+ const defaultBranch = defaultRef.trim().replace('origin/', '');
35
+ if (currentBranch === defaultBranch) {
36
+ behindCount = 0;
37
+ }
38
+ else {
39
+ const { stdout: countOut } = await execFileAsync('git', ['rev-list', '--count', `${currentBranch}..origin/${defaultBranch}`], { cwd: repo.path });
40
+ behindCount = parseInt(countOut.trim(), 10);
41
+ if (isNaN(behindCount))
42
+ behindCount = null;
43
+ }
42
44
  }
43
- else if (!defaultBranch || currentBranch === defaultBranch) {
44
- behindCount = 0;
45
+ catch {
46
+ // No remote HEAD or rev-list failed — leave as null
45
47
  }
46
- return {
48
+ const info = {
47
49
  branch: currentBranch,
48
50
  commitMessage: commitMessage ?? 'unknown',
49
51
  committer: committer ?? 'unknown',
50
52
  behindCount,
51
53
  };
54
+ gitInfoCache.set(repo.path, { info, expiresAt: Date.now() + GIT_INFO_TTL_MS });
55
+ return info;
52
56
  }
53
57
  catch {
58
+ gitInfoCache.set(repo.path, { info: null, expiresAt: Date.now() + GIT_INFO_TTL_MS });
54
59
  return null;
55
60
  }
56
61
  }
@@ -0,0 +1,11 @@
1
+ import type { Feature } from '../../../../../packages/core/src/domain/generated/output.js';
2
+ interface AdoptBranchInput {
3
+ branchName: string;
4
+ repositoryPath: string;
5
+ }
6
+ export declare function adoptBranch(input: AdoptBranchInput): Promise<{
7
+ feature?: Feature;
8
+ error?: string;
9
+ }>;
10
+ export {};
11
+ //# sourceMappingURL=adopt-branch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt-branch.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/adopt-branch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAEpE,UAAU,gBAAgB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBhD"}
@@ -0,0 +1,20 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ export async function adoptBranch(input) {
4
+ const { branchName, repositoryPath } = input;
5
+ if (!branchName?.trim()) {
6
+ return { error: 'Branch name is required' };
7
+ }
8
+ if (!repositoryPath?.trim()) {
9
+ return { error: 'Repository path is required' };
10
+ }
11
+ try {
12
+ const useCase = resolve('AdoptBranchUseCase');
13
+ const result = await useCase.execute({ branchName, repositoryPath });
14
+ return { feature: result.feature };
15
+ }
16
+ catch (error) {
17
+ const message = error instanceof Error ? error.message : 'Failed to adopt branch';
18
+ return { error: message };
19
+ }
20
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"approve-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/approve-feature.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAK/E,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsChD"}
1
+ {"version":3,"file":"approve-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/approve-feature.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiChD"}
@@ -1,7 +1,5 @@
1
1
  'use server';
2
2
  import { resolve } from '../../lib/server-container.js';
3
- import { AgentRunStatus } from '../../../../../packages/core/src/domain/generated/output.js';
4
- const ERROR_STATUSES = new Set([AgentRunStatus.failed, AgentRunStatus.interrupted]);
5
3
  export async function approveFeature(featureId, payload) {
6
4
  if (!featureId.trim()) {
7
5
  return { approved: false, error: 'Feature id is required' };
@@ -15,13 +13,10 @@ export async function approveFeature(featureId, payload) {
15
13
  if (!feature.agentRunId) {
16
14
  return { approved: false, error: 'Feature has no agent run' };
17
15
  }
18
- const runRepo = resolve('IAgentRunRepository');
19
- const run = await runRepo.findById(feature.agentRunId);
20
- if (run && ERROR_STATUSES.has(run.status)) {
21
- const resumeUseCase = resolve('ResumeFeatureUseCase');
22
- await resumeUseCase.execute(featureId, { promptPrefix: 'User approved. Please continue.' });
23
- return { approved: true };
24
- }
16
+ // Always use ApproveAgentRunUseCase — it handles waitingApproval, failed,
17
+ // and interrupted statuses. This ensures approval is propagated via
18
+ // Command({update: {_approvalAction: 'approved'}}) so the graph node
19
+ // receives it on resume.
25
20
  const approveUseCase = resolve('ApproveAgentRunUseCase');
26
21
  const result = await approveUseCase.execute(feature.agentRunId, payload);
27
22
  if (!result.approved) {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Server action that returns all branch names (local + remote) for a repository.
3
+ * Used by the adopt branch drawer to populate the branch combobox.
4
+ */
5
+ export declare function listBranches(repositoryPath: string): Promise<string[]>;
6
+ //# sourceMappingURL=list-branches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-branches.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/list-branches.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAsB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAW5E"}
@@ -0,0 +1,18 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ /**
4
+ * Server action that returns all branch names (local + remote) for a repository.
5
+ * Used by the adopt branch drawer to populate the branch combobox.
6
+ */
7
+ export async function listBranches(repositoryPath) {
8
+ if (!repositoryPath?.trim()) {
9
+ return [];
10
+ }
11
+ try {
12
+ const worktreeService = resolve('IWorktreeService');
13
+ return await worktreeService.listBranches(repositoryPath);
14
+ }
15
+ catch {
16
+ return [];
17
+ }
18
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"reject-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/reject-feature.ts"],"names":[],"mappings":"AAWA,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC;IACT,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CA8CD"}
1
+ {"version":3,"file":"reject-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/reject-feature.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC;IACT,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAyCD"}
@@ -1,7 +1,5 @@
1
1
  'use server';
2
2
  import { resolve } from '../../lib/server-container.js';
3
- import { AgentRunStatus } from '../../../../../packages/core/src/domain/generated/output.js';
4
- const ERROR_STATUSES = new Set([AgentRunStatus.failed, AgentRunStatus.interrupted]);
5
3
  export async function rejectFeature(featureId, feedback, attachments) {
6
4
  if (!featureId.trim()) {
7
5
  return { rejected: false, error: 'Feature id is required' };
@@ -18,13 +16,10 @@ export async function rejectFeature(featureId, feedback, attachments) {
18
16
  if (!feature.agentRunId) {
19
17
  return { rejected: false, error: 'Feature has no agent run' };
20
18
  }
21
- const runRepo = resolve('IAgentRunRepository');
22
- const run = await runRepo.findById(feature.agentRunId);
23
- if (run && ERROR_STATUSES.has(run.status)) {
24
- const resumeUseCase = resolve('ResumeFeatureUseCase');
25
- await resumeUseCase.execute(featureId, { promptPrefix: feedback });
26
- return { rejected: true, iteration: 1 };
27
- }
19
+ // Always use RejectAgentRunUseCase — it handles waitingApproval, failed,
20
+ // and interrupted statuses. This ensures rejection feedback is propagated
21
+ // via Command({update: {_approvalAction, _rejectionFeedback}}) so the
22
+ // graph node receives the feedback on resume.
28
23
  const rejectUseCase = resolve('RejectAgentRunUseCase');
29
24
  const result = await rejectUseCase.execute(feature.agentRunId, feedback, attachments);
30
25
  if (!result.rejected) {
@@ -1 +1 @@
1
- {"version":3,"file":"build-feature-node-data.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/build-feature-node-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAQ9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAExE,MAAM,WAAW,2BAA2B;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,QAAQ,GAAG,IAAI,EACpB,OAAO,CAAC,EAAE,2BAA2B,GACpC,eAAe,CAgDjB"}
1
+ {"version":3,"file":"build-feature-node-data.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/build-feature-node-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAQ9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAExE,MAAM,WAAW,2BAA2B;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,QAAQ,GAAG,IAAI,EACpB,OAAO,CAAC,EAAE,2BAA2B,GACpC,eAAe,CAiDjB"}
@@ -36,6 +36,7 @@ export function buildFeatureNodeData(feature, run, options) {
36
36
  ...(run?.agentType && { agentType: run.agentType }),
37
37
  ...(run?.modelId && { modelId: run.modelId }),
38
38
  ...(run?.error && { errorMessage: run.error }),
39
+ ...(feature.agentRunId != null && { hasAgentRun: true }),
39
40
  ...(feature.plan != null && { hasPlan: true }),
40
41
  ...(feature.pr && {
41
42
  pr: {
@@ -132,6 +132,7 @@ function appendFeatureNodes(repoFeatures, repoNodeId, allFeaturesWithRuns, nodes
132
132
  ...(run?.modelId && { modelId: run.modelId }),
133
133
  ...(run?.error && { errorMessage: run.error }),
134
134
  ...(blockedBy && { blockedBy }),
135
+ ...(feature.agentRunId != null && { hasAgentRun: true }),
135
136
  ...(feature.plan != null && { hasPlan: true }),
136
137
  ...(feature.pr && {
137
138
  pr: {
@@ -0,0 +1,20 @@
1
+ import type { RepositoryOption } from '../../common/feature-create-drawer/feature-create-drawer.js';
2
+ export interface AdoptBranchDrawerProps {
3
+ open: boolean;
4
+ onClose: () => void;
5
+ onSubmit: (branchName: string, repositoryPath: string) => void;
6
+ isSubmitting?: boolean;
7
+ error?: string;
8
+ /** Available repositories for the repository selector */
9
+ repositories?: RepositoryOption[];
10
+ /** Currently selected repository path */
11
+ selectedRepositoryPath?: string;
12
+ /** Callback when user selects a different repository */
13
+ onRepositoryChange?: (repositoryPath: string) => void;
14
+ /** Available branch names for the combobox dropdown */
15
+ branches?: string[];
16
+ /** Whether branches are still loading */
17
+ branchesLoading?: boolean;
18
+ }
19
+ export declare function AdoptBranchDrawer({ open, onClose, onSubmit, isSubmitting, error, repositories, selectedRepositoryPath, onRepositoryChange, branches, branchesLoading, }: AdoptBranchDrawerProps): import("react/jsx-runtime").JSX.Element;
20
+ //# sourceMappingURL=adopt-branch-drawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt-branch-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iEAAiE,CAAC;AAExG,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAClC,yCAAyC;IACzC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,yCAAyC;IACzC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,YAAoB,EACpB,KAAK,EACL,YAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,QAAa,EACb,eAAuB,GACxB,EAAE,sBAAsB,2CAmVxB"}
@@ -0,0 +1,105 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState, useCallback, useEffect, useRef } from 'react';
4
+ import { Check, CheckIcon, ChevronsUpDown, GitBranch, Loader2 } from 'lucide-react';
5
+ import { BaseDrawer } from '../../common/base-drawer/index.js';
6
+ import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
7
+ import { Button } from '../../ui/button.js';
8
+ import { Input } from '../../ui/input.js';
9
+ import { Label } from '../../ui/label.js';
10
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '../../ui/command.js';
11
+ import { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover.js';
12
+ import { cn } from '../../../lib/utils.js';
13
+ export function AdoptBranchDrawer({ open, onClose, onSubmit, isSubmitting = false, error, repositories = [], selectedRepositoryPath, onRepositoryChange, branches = [], branchesLoading = false, }) {
14
+ const [branchName, setBranchName] = useState('');
15
+ const [comboboxOpen, setComboboxOpen] = useState(false);
16
+ const [inputValue, setInputValue] = useState('');
17
+ const inputRef = useRef(null);
18
+ const [repoOpen, setRepoOpen] = useState(false);
19
+ const [repoQuery, setRepoQuery] = useState('');
20
+ const repoInputRef = useRef(null);
21
+ const selectedRepo = repositories.find((r) => r.path === selectedRepositoryPath);
22
+ const hasRepo = !!selectedRepositoryPath;
23
+ // Reset state when drawer closes
24
+ useEffect(() => {
25
+ if (!open) {
26
+ setBranchName('');
27
+ setInputValue('');
28
+ setComboboxOpen(false);
29
+ setRepoOpen(false);
30
+ setRepoQuery('');
31
+ }
32
+ }, [open]);
33
+ // Reset branch selection when repository changes
34
+ useEffect(() => {
35
+ setBranchName('');
36
+ setInputValue('');
37
+ }, [selectedRepositoryPath]);
38
+ const handleSubmit = useCallback((e) => {
39
+ e.preventDefault();
40
+ const trimmed = branchName.trim();
41
+ if (!trimmed || !selectedRepositoryPath || isSubmitting)
42
+ return;
43
+ onSubmit(trimmed, selectedRepositoryPath);
44
+ }, [branchName, selectedRepositoryPath, isSubmitting, onSubmit]);
45
+ const handleClose = useCallback(() => {
46
+ setBranchName('');
47
+ setInputValue('');
48
+ onClose();
49
+ }, [onClose]);
50
+ const handleSelect = useCallback((branch) => {
51
+ setBranchName(branch);
52
+ setInputValue(branch);
53
+ setComboboxOpen(false);
54
+ }, []);
55
+ const handleInputChange = useCallback((e) => {
56
+ setInputValue(e.target.value);
57
+ if (!comboboxOpen)
58
+ setComboboxOpen(true);
59
+ }, [comboboxOpen]);
60
+ const handleInputKeyDown = useCallback((e) => {
61
+ if (e.key === 'Enter') {
62
+ e.preventDefault();
63
+ const trimmed = inputValue.trim();
64
+ if (trimmed) {
65
+ setBranchName(trimmed);
66
+ setComboboxOpen(false);
67
+ }
68
+ }
69
+ if (e.key === 'Escape') {
70
+ setComboboxOpen(false);
71
+ setInputValue(branchName);
72
+ }
73
+ }, [inputValue, branchName]);
74
+ const handleRepoSelect = useCallback((path) => {
75
+ onRepositoryChange?.(path);
76
+ setRepoOpen(false);
77
+ setRepoQuery('');
78
+ }, [onRepositoryChange]);
79
+ const filteredBranches = branches.filter((b) => b.toLowerCase().includes(inputValue.toLowerCase()));
80
+ const filteredRepos = repoQuery.trim()
81
+ ? repositories.filter((r) => r.name.toLowerCase().includes(repoQuery.toLowerCase()) ||
82
+ r.path.toLowerCase().includes(repoQuery.toLowerCase()))
83
+ : repositories;
84
+ useEffect(() => {
85
+ if (repoOpen) {
86
+ setTimeout(() => repoInputRef.current?.focus(), 0);
87
+ }
88
+ else {
89
+ setRepoQuery('');
90
+ }
91
+ }, [repoOpen]);
92
+ const isDisabled = !branchName.trim() || !selectedRepositoryPath || isSubmitting;
93
+ const header = (_jsxs("div", { children: [_jsxs(DrawerTitle, { className: "flex items-center gap-2", children: [_jsx(GitBranch, { className: "h-4 w-4" }), "Adopt Branch"] }), _jsx(DrawerDescription, { className: "text-muted-foreground text-sm", children: "Import an existing git branch into Shep's feature tracking" })] }));
94
+ return (_jsx(BaseDrawer, { open: open, onClose: handleClose, size: "sm", modal: false, header: header, "data-testid": "adopt-branch-drawer", children: _jsxs("form", { onSubmit: handleSubmit, className: "flex flex-1 flex-col", children: [_jsx("div", { className: "flex-1 overflow-y-auto p-4", children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Repository" }), _jsxs(Popover, { open: repoOpen, onOpenChange: setRepoOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", role: "combobox", "aria-expanded": repoOpen, "aria-label": "Repository", disabled: isSubmitting, "data-testid": "adopt-repo-combobox", className: cn('border-input bg-background ring-offset-background focus:ring-ring flex h-9 w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50', !selectedRepo && 'text-muted-foreground'), children: [_jsx("span", { className: "truncate", children: selectedRepo ? selectedRepo.name : 'Select repository...' }), _jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), _jsx(PopoverContent, { className: "w-80 p-0", align: "start", "data-testid": "adopt-repo-combobox-content", children: _jsxs("div", { className: "flex flex-col", children: [_jsx("div", { className: "border-b p-2", children: _jsx(Input, { ref: repoInputRef, placeholder: "Search repositories...", value: repoQuery, onChange: (e) => setRepoQuery(e.target.value), className: "h-8 border-0 p-0 text-sm shadow-none focus-visible:ring-0", "data-testid": "adopt-repo-search" }) }), _jsx("div", { className: "max-h-48 overflow-y-auto py-1", role: "listbox", "aria-label": "Repositories", children: filteredRepos.length === 0 ? (_jsx("p", { className: "text-muted-foreground px-3 py-2 text-sm", children: "No repositories found." })) : (filteredRepos.map((r) => (_jsxs("button", { type: "button", role: "option", "aria-selected": selectedRepositoryPath === r.path, onClick: () => handleRepoSelect(r.path), className: cn('hover:bg-accent hover:text-accent-foreground flex w-full items-center gap-2 px-3 py-2 text-sm', selectedRepositoryPath === r.path && 'bg-accent/50'), "data-testid": `adopt-repo-option-${r.id}`, children: [_jsx(CheckIcon, { className: cn('h-4 w-4 shrink-0', selectedRepositoryPath !== r.path && 'invisible') }), _jsxs("span", { className: "flex flex-col items-start truncate", children: [_jsx("span", { className: "truncate", children: r.name }), _jsx("span", { className: "text-muted-foreground truncate text-xs", children: r.path })] })] }, r.id)))) })] }) })] }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Select the repository that contains the branch you want to adopt." })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "branch-name", children: "Branch name" }), _jsxs(Popover, { open: comboboxOpen, onOpenChange: setComboboxOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", role: "combobox", "aria-expanded": comboboxOpen, disabled: isSubmitting || !hasRepo, className: "w-full justify-between font-normal", "data-testid": "adopt-branch-input", children: [_jsx("span", { className: "truncate", children: !hasRepo
95
+ ? 'Select a repository first...'
96
+ : branchesLoading
97
+ ? 'Loading branches...'
98
+ : branchName || 'Select a branch...' }), _jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), _jsx(PopoverContent, { className: "w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: _jsxs(Command, { children: [_jsx(CommandInput, { ref: inputRef, placeholder: "Search branches...", value: inputValue, onChange: handleInputChange, onKeyDown: handleInputKeyDown, "data-testid": "adopt-branch-search" }), _jsxs(CommandList, { children: [!branchesLoading && filteredBranches.length === 0 && (_jsx(CommandEmpty, { children: branches.length === 0
99
+ ? 'No branches found.'
100
+ : inputValue
101
+ ? 'No match — press Enter to use this value.'
102
+ : 'No branches available.' })), branchesLoading ? (_jsx(CommandEmpty, { children: _jsx(Loader2, { className: "mx-auto h-4 w-4 animate-spin" }) })) : null, filteredBranches.length > 0 && (_jsx(CommandGroup, { children: filteredBranches.map((branch) => (_jsxs(CommandItem, { selected: branch === branchName, onClick: () => handleSelect(branch), children: [_jsx(Check, { className: cn('mr-2 h-4 w-4', branch === branchName ? 'opacity-100' : 'opacity-0') }), _jsx(GitBranch, { className: "mr-2 h-3 w-3 opacity-50" }), branch] }, branch))) }))] })] }) })] }), _jsx("p", { className: "text-muted-foreground text-xs", children: hasRepo
103
+ ? 'Select a branch from the dropdown or type to search. Local and remote branches are shown.'
104
+ : 'Please select a repository above to see available branches.' })] }), error ? (_jsx("p", { className: "text-destructive text-sm", "data-testid": "adopt-branch-error", children: error })) : null] }) }), _jsx("div", { className: "border-t p-4", children: _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { type: "button", variant: "outline", onClick: handleClose, disabled: isSubmitting, className: "flex-1", children: "Cancel" }), _jsx(Button, { type: "submit", disabled: isDisabled, className: "flex-1", "data-testid": "adopt-branch-submit", children: isSubmitting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Adopting..."] })) : ('Adopt Branch') })] }) })] }) }));
105
+ }
@@ -0,0 +1,38 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { AdoptBranchDrawer } from './adopt-branch-drawer.js';
3
+ /**
4
+ * **AdoptBranchDrawer** is a right-side sliding drawer for importing an
5
+ * existing git branch into Shep's feature tracking system.
6
+ *
7
+ * ### Form
8
+ * - **Repository** (required) — combobox for selecting which repository to adopt from
9
+ * - **Branch name** (required) — combobox with search for selecting a branch (scoped to selected repo)
10
+ * - **Adopt Branch** button — disabled when no repo/branch is selected or submitting
11
+ * - **Cancel** button — closes the drawer
12
+ *
13
+ * ### States
14
+ * - Default: no repo or branch selected, submit disabled
15
+ * - Loading branches: combobox shows loading spinner
16
+ * - Loading submit: button shows spinner
17
+ * - Error: error message shown below combobox
18
+ */
19
+ declare const meta: Meta<typeof AdoptBranchDrawer>;
20
+ export default meta;
21
+ type Story = StoryObj<typeof AdoptBranchDrawer>;
22
+ /** Default — click the trigger button to open the adopt branch drawer with repo and branch selectors. */
23
+ export declare const Default: Story;
24
+ /** Pre-opened drawer with repository and branch comboboxes for quick visual inspection. */
25
+ export declare const PreOpened: Story;
26
+ /** No repository selected — branch selector shows "Select a repository first..." */
27
+ export declare const NoRepoSelected: Story;
28
+ /** Branches loading state — combobox shows "Loading branches..." */
29
+ export declare const BranchesLoading: Story;
30
+ /** Loading state — submit in progress, button shows spinner. */
31
+ export declare const Loading: Story;
32
+ /** Error state — error message visible below combobox. */
33
+ export declare const WithError: Story;
34
+ /** No branches available — empty state in the combobox dropdown. */
35
+ export declare const NoBranches: Story;
36
+ /** Adopt branch drawer rendered inside a full-page context — starts open. */
37
+ export declare const InDrawer: Story;
38
+ //# sourceMappingURL=adopt-branch-drawer.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt-branch-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAO1D;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,iBAAiB,CAmBxC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAuFhD,yGAAyG;AACzG,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,cAAc,EAAE,KAM5B,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,eAAe,EAAE,KAM7B,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,SAAS,EAAE,KAWvB,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAyCF,6EAA6E;AAC7E,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC"}
@@ -0,0 +1,161 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { within, userEvent, fn } from '@storybook/test';
4
+ import { AdoptBranchDrawer } from './adopt-branch-drawer.js';
5
+ import { Button } from '../../ui/button.js';
6
+ /* ---------------------------------------------------------------------------
7
+ * Meta
8
+ * ------------------------------------------------------------------------- */
9
+ /**
10
+ * **AdoptBranchDrawer** is a right-side sliding drawer for importing an
11
+ * existing git branch into Shep's feature tracking system.
12
+ *
13
+ * ### Form
14
+ * - **Repository** (required) — combobox for selecting which repository to adopt from
15
+ * - **Branch name** (required) — combobox with search for selecting a branch (scoped to selected repo)
16
+ * - **Adopt Branch** button — disabled when no repo/branch is selected or submitting
17
+ * - **Cancel** button — closes the drawer
18
+ *
19
+ * ### States
20
+ * - Default: no repo or branch selected, submit disabled
21
+ * - Loading branches: combobox shows loading spinner
22
+ * - Loading submit: button shows spinner
23
+ * - Error: error message shown below combobox
24
+ */
25
+ const meta = {
26
+ title: 'Drawers/Feature/AdoptBranchDrawer',
27
+ component: AdoptBranchDrawer,
28
+ tags: ['autodocs'],
29
+ parameters: {
30
+ layout: 'fullscreen',
31
+ },
32
+ argTypes: {
33
+ open: { control: 'boolean', description: 'Controls drawer visibility' },
34
+ onClose: { description: 'Called when the drawer is dismissed' },
35
+ onSubmit: { description: 'Called with branch name and repo path when submitted' },
36
+ isSubmitting: { control: 'boolean', description: 'Shows loading state' },
37
+ error: { control: 'text', description: 'Error message to display' },
38
+ repositories: { description: 'Available repositories for selection' },
39
+ selectedRepositoryPath: { description: 'Currently selected repository path' },
40
+ onRepositoryChange: { description: 'Called when user selects a different repository' },
41
+ branches: { description: 'Available branch names for the combobox dropdown' },
42
+ branchesLoading: { control: 'boolean', description: 'Whether branches are loading' },
43
+ },
44
+ };
45
+ export default meta;
46
+ /* ---------------------------------------------------------------------------
47
+ * Shared data
48
+ * ------------------------------------------------------------------------- */
49
+ const logSubmit = fn().mockName('onSubmit');
50
+ const logClose = fn().mockName('onClose');
51
+ const logRepoChange = fn().mockName('onRepositoryChange');
52
+ const sampleRepositories = [
53
+ { id: 'repo-1', name: 'my-app', path: '/Users/dev/projects/my-app' },
54
+ { id: 'repo-2', name: 'api-server', path: '/Users/dev/projects/api-server' },
55
+ { id: 'repo-3', name: 'shared-lib', path: '/Users/dev/projects/shared-lib' },
56
+ ];
57
+ const sampleBranches = [
58
+ 'feat/user-auth',
59
+ 'feat/dashboard-redesign',
60
+ 'fix/login-bug',
61
+ 'fix/memory-leak',
62
+ 'chore/update-deps',
63
+ 'refactor/api-layer',
64
+ 'docs/readme-update',
65
+ 'release/v2.0',
66
+ 'hotfix/critical-fix',
67
+ 'develop',
68
+ ];
69
+ /* ---------------------------------------------------------------------------
70
+ * Trigger wrapper
71
+ * ------------------------------------------------------------------------- */
72
+ function AdoptDrawerTrigger({ label = 'Open Adopt Branch', isSubmitting = false, error, repositories = sampleRepositories, selectedRepositoryPath = sampleRepositories[0].path, branches = sampleBranches, branchesLoading = false, }) {
73
+ const [open, setOpen] = useState(false);
74
+ const [selectedRepo, setSelectedRepo] = useState(selectedRepositoryPath);
75
+ return (_jsxs("div", { className: "flex h-screen items-start p-4", children: [_jsx(Button, { variant: "outline", onClick: () => setOpen(true), children: label }), _jsx(AdoptBranchDrawer, { open: open, onClose: () => {
76
+ setOpen(false);
77
+ logClose();
78
+ }, onSubmit: (branchName, repoPath) => {
79
+ logSubmit(branchName, repoPath);
80
+ setOpen(false);
81
+ }, isSubmitting: isSubmitting, error: error, repositories: repositories, selectedRepositoryPath: selectedRepo, onRepositoryChange: (path) => {
82
+ setSelectedRepo(path);
83
+ logRepoChange(path);
84
+ }, branches: branches, branchesLoading: branchesLoading })] }));
85
+ }
86
+ /* ---------------------------------------------------------------------------
87
+ * Stories
88
+ * ------------------------------------------------------------------------- */
89
+ /** Default — click the trigger button to open the adopt branch drawer with repo and branch selectors. */
90
+ export const Default = {
91
+ render: () => _jsx(AdoptDrawerTrigger, {}),
92
+ };
93
+ /** Pre-opened drawer with repository and branch comboboxes for quick visual inspection. */
94
+ export const PreOpened = {
95
+ render: () => _jsx(AdoptDrawerTrigger, { label: "Open Drawer" }),
96
+ play: async ({ canvasElement }) => {
97
+ const canvas = within(canvasElement);
98
+ await userEvent.click(canvas.getByRole('button', { name: 'Open Drawer' }));
99
+ },
100
+ };
101
+ /** No repository selected — branch selector shows "Select a repository first..." */
102
+ export const NoRepoSelected = {
103
+ render: () => _jsx(AdoptDrawerTrigger, { label: "Open (No Repo)", selectedRepositoryPath: "" }),
104
+ play: async ({ canvasElement }) => {
105
+ const canvas = within(canvasElement);
106
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (No Repo)' }));
107
+ },
108
+ };
109
+ /** Branches loading state — combobox shows "Loading branches..." */
110
+ export const BranchesLoading = {
111
+ render: () => _jsx(AdoptDrawerTrigger, { label: "Open (Loading Branches)", branchesLoading: true }),
112
+ play: async ({ canvasElement }) => {
113
+ const canvas = within(canvasElement);
114
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (Loading Branches)' }));
115
+ },
116
+ };
117
+ /** Loading state — submit in progress, button shows spinner. */
118
+ export const Loading = {
119
+ render: () => _jsx(AdoptDrawerTrigger, { label: "Open (Loading)", isSubmitting: true }),
120
+ play: async ({ canvasElement }) => {
121
+ const canvas = within(canvasElement);
122
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (Loading)' }));
123
+ },
124
+ };
125
+ /** Error state — error message visible below combobox. */
126
+ export const WithError = {
127
+ render: () => (_jsx(AdoptDrawerTrigger, { label: "Open (Error)", error: 'Branch "main" cannot be adopted. The main branch should not be tracked as a feature.' })),
128
+ play: async ({ canvasElement }) => {
129
+ const canvas = within(canvasElement);
130
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (Error)' }));
131
+ },
132
+ };
133
+ /** No branches available — empty state in the combobox dropdown. */
134
+ export const NoBranches = {
135
+ render: () => _jsx(AdoptDrawerTrigger, { label: "Open (No Branches)", branches: [] }),
136
+ play: async ({ canvasElement }) => {
137
+ const canvas = within(canvasElement);
138
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (No Branches)' }));
139
+ },
140
+ };
141
+ /* ---------------------------------------------------------------------------
142
+ * Shell template — starts open in full-page context
143
+ * ------------------------------------------------------------------------- */
144
+ function AdoptDrawerShellTemplate() {
145
+ const [open, setOpen] = useState(true);
146
+ const [selectedRepo, setSelectedRepo] = useState(sampleRepositories[0].path);
147
+ return (_jsxs("div", { style: { height: '100vh', background: '#f8fafc', padding: '2rem' }, children: [_jsx("button", { type: "button", onClick: () => setOpen(true), style: { padding: '8px 16px', border: '1px solid #ccc', borderRadius: '6px' }, children: "Open Drawer" }), _jsx(AdoptBranchDrawer, { open: open, onClose: () => {
148
+ setOpen(false);
149
+ logClose();
150
+ }, onSubmit: (branchName, repoPath) => {
151
+ logSubmit(branchName, repoPath);
152
+ setOpen(false);
153
+ }, repositories: sampleRepositories, selectedRepositoryPath: selectedRepo, onRepositoryChange: (path) => {
154
+ setSelectedRepo(path);
155
+ logRepoChange(path);
156
+ }, branches: sampleBranches })] }));
157
+ }
158
+ /** Adopt branch drawer rendered inside a full-page context — starts open. */
159
+ export const InDrawer = {
160
+ render: () => _jsx(AdoptDrawerShellTemplate, {}),
161
+ };
@@ -0,0 +1,7 @@
1
+ import type { RepositoryOption } from '../../common/feature-create-drawer/feature-create-drawer.js';
2
+ export interface AdoptDrawerClientProps {
3
+ repositoryPath: string;
4
+ repositories: RepositoryOption[];
5
+ }
6
+ export declare function AdoptDrawerClient({ repositoryPath, repositories }: AdoptDrawerClientProps): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=adopt-drawer-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/adopt-drawer-client.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iEAAiE,CAAC;AAExG,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,wBAAgB,iBAAiB,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,EAAE,sBAAsB,2CA+FzF"}