@shepai/cli 1.65.1 → 1.66.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 (326) hide show
  1. package/dist/packages/core/src/application/ports/output/repositories/repository-repository.interface.d.ts +1 -1
  2. package/dist/packages/core/src/application/ports/output/repositories/repository-repository.interface.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/ports/output/services/deployment-service.interface.d.ts +62 -0
  4. package/dist/packages/core/src/application/ports/output/services/deployment-service.interface.d.ts.map +1 -0
  5. package/dist/packages/core/src/application/ports/output/services/deployment-service.interface.js +12 -0
  6. package/dist/packages/core/src/application/ports/output/services/index.d.ts +1 -0
  7. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  9. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +4 -1
  10. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  11. package/dist/packages/core/src/infrastructure/di/container.js +3 -0
  12. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
  13. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +25 -0
  14. package/dist/packages/core/src/infrastructure/repositories/sqlite-repository.repository.d.ts +1 -1
  15. package/dist/packages/core/src/infrastructure/repositories/sqlite-repository.repository.d.ts.map +1 -1
  16. package/dist/packages/core/src/infrastructure/repositories/sqlite-repository.repository.js +5 -2
  17. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
  18. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +23 -2
  19. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  20. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +11 -7
  21. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.d.ts.map +1 -1
  22. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/plan.prompt.js +11 -7
  23. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.d.ts.map +1 -1
  24. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/requirements.prompt.js +11 -7
  25. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts +57 -0
  26. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts.map +1 -0
  27. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.js +192 -0
  28. package/dist/packages/core/src/infrastructure/services/deployment/detect-dev-script.d.ts +26 -0
  29. package/dist/packages/core/src/infrastructure/services/deployment/detect-dev-script.d.ts.map +1 -0
  30. package/dist/packages/core/src/infrastructure/services/deployment/detect-dev-script.js +59 -0
  31. package/dist/packages/core/src/infrastructure/services/deployment/parse-port.d.ts +15 -0
  32. package/dist/packages/core/src/infrastructure/services/deployment/parse-port.d.ts.map +1 -0
  33. package/dist/packages/core/src/infrastructure/services/deployment/parse-port.js +52 -0
  34. package/dist/src/presentation/cli/commands/_serve.command.d.ts.map +1 -1
  35. package/dist/src/presentation/cli/commands/_serve.command.js +2 -0
  36. package/dist/src/presentation/web/app/actions/deploy-feature.d.ts +7 -0
  37. package/dist/src/presentation/web/app/actions/deploy-feature.d.ts.map +1 -0
  38. package/dist/src/presentation/web/app/actions/deploy-feature.js +28 -0
  39. package/dist/src/presentation/web/app/actions/deploy-repository.d.ts +7 -0
  40. package/dist/src/presentation/web/app/actions/deploy-repository.d.ts.map +1 -0
  41. package/dist/src/presentation/web/app/actions/deploy-repository.js +21 -0
  42. package/dist/src/presentation/web/app/actions/get-deployment-status.d.ts +3 -0
  43. package/dist/src/presentation/web/app/actions/get-deployment-status.d.ts.map +1 -0
  44. package/dist/src/presentation/web/app/actions/get-deployment-status.js +9 -0
  45. package/dist/src/presentation/web/app/actions/stop-deployment.d.ts +5 -0
  46. package/dist/src/presentation/web/app/actions/stop-deployment.d.ts.map +1 -0
  47. package/dist/src/presentation/web/app/actions/stop-deployment.js +16 -0
  48. package/dist/src/presentation/web/app/build-graph-nodes.d.ts +20 -0
  49. package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -0
  50. package/dist/src/presentation/web/app/build-graph-nodes.js +142 -0
  51. package/dist/src/presentation/web/app/page.d.ts.map +1 -1
  52. package/dist/src/presentation/web/app/page.js +2 -112
  53. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts +3 -1
  54. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -1
  55. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +13 -3
  56. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts +2 -0
  57. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts.map +1 -1
  58. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.js +9 -0
  59. package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.d.ts +7 -0
  60. package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.d.ts.map +1 -0
  61. package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.js +14 -0
  62. package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.d.ts +14 -0
  63. package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.d.ts.map +1 -0
  64. package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.js +27 -0
  65. package/dist/src/presentation/web/components/common/deployment-status-badge/index.d.ts +2 -0
  66. package/dist/src/presentation/web/components/common/deployment-status-badge/index.d.ts.map +1 -0
  67. package/dist/src/presentation/web/components/common/deployment-status-badge/index.js +1 -0
  68. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts.map +1 -1
  69. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.js +8 -1
  70. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts.map +1 -1
  71. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.js +7 -1
  72. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  73. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +13 -2
  74. package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.d.ts.map +1 -1
  75. package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.js +12 -2
  76. package/dist/src/presentation/web/hooks/use-deploy-action.d.ts +18 -0
  77. package/dist/src/presentation/web/hooks/use-deploy-action.d.ts.map +1 -0
  78. package/dist/src/presentation/web/hooks/use-deploy-action.js +130 -0
  79. package/dist/src/presentation/web/lib/feature-flags.d.ts +1 -0
  80. package/dist/src/presentation/web/lib/feature-flags.d.ts.map +1 -1
  81. package/dist/src/presentation/web/lib/feature-flags.js +1 -0
  82. package/dist/tsconfig.build.tsbuildinfo +1 -1
  83. package/package.json +1 -1
  84. package/web/.next/BUILD_ID +1 -1
  85. package/web/.next/build-manifest.json +7 -6
  86. package/web/.next/cache/.previewinfo +1 -1
  87. package/web/.next/cache/.rscinfo +1 -1
  88. package/web/.next/cache/.tsbuildinfo +1 -1
  89. package/web/.next/cache/config.json +3 -3
  90. package/web/.next/fallback-build-manifest.json +2 -2
  91. package/web/.next/prerender-manifest.json +3 -3
  92. package/web/.next/required-server-files.js +1 -1
  93. package/web/.next/required-server-files.json +1 -1
  94. package/web/.next/server/app/_global-error/page/build-manifest.json +5 -4
  95. package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  96. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  97. package/web/.next/server/app/_global-error.html +2 -2
  98. package/web/.next/server/app/_global-error.rsc +1 -1
  99. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  100. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  101. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  102. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  103. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  104. package/web/.next/server/app/_not-found/page/build-manifest.json +5 -4
  105. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  106. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  107. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  108. package/web/.next/server/app/api/tools/[id]/install/route.js +1 -1
  109. package/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -1
  110. package/web/.next/server/app/page/build-manifest.json +5 -4
  111. package/web/.next/server/app/page/server-reference-manifest.json +88 -28
  112. package/web/.next/server/app/page.js +2 -2
  113. package/web/.next/server/app/page.js.nft.json +1 -1
  114. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  115. package/web/.next/server/app/skills/page/build-manifest.json +5 -4
  116. package/web/.next/server/app/skills/page/server-reference-manifest.json +62 -2
  117. package/web/.next/server/app/skills/page.js +2 -2
  118. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  119. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  120. package/web/.next/server/app/tools/page/build-manifest.json +5 -4
  121. package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  122. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  123. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  124. package/web/.next/server/app/version/page/build-manifest.json +5 -4
  125. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  126. package/web/.next/server/app/version/page.js +1 -1
  127. package/web/.next/server/app/version/page.js.nft.json +1 -1
  128. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  129. package/web/.next/server/chunks/{[root-of-the-server]__e926de65._.js → [root-of-the-server]__09413611._.js} +2 -2
  130. package/web/.next/server/chunks/{[root-of-the-server]__e926de65._.js.map → [root-of-the-server]__09413611._.js.map} +1 -1
  131. package/web/.next/server/chunks/ssr/403f9_next_dist_623b646a._.js +3 -0
  132. package/web/.next/server/chunks/ssr/403f9_next_dist_623b646a._.js.map +1 -0
  133. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  134. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
  135. package/web/.next/server/chunks/ssr/{[root-of-the-server]__685eaa45._.js → [root-of-the-server]__248ee887._.js} +2 -2
  136. package/web/.next/server/chunks/ssr/{[root-of-the-server]__685eaa45._.js.map → [root-of-the-server]__248ee887._.js.map} +1 -1
  137. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js → server/chunks/ssr/[root-of-the-server]__249c74f6._.js} +2 -2
  138. package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js +4 -0
  139. package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js.map +1 -0
  140. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  141. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  142. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb51fac._.js +3 -0
  143. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb51fac._.js.map +1 -0
  144. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  145. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  146. package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
  147. package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js.map +1 -1
  148. package/web/.next/server/chunks/ssr/[root-of-the-server]__c1f0f2a8._.js +3 -0
  149. package/web/.next/server/chunks/ssr/[root-of-the-server]__c1f0f2a8._.js.map +1 -0
  150. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__dd5b62cb._.js → server/chunks/ssr/[root-of-the-server]__f5830fa9._.js} +2 -2
  151. package/web/.next/server/chunks/ssr/[root-of-the-server]__f5830fa9._.js.map +1 -0
  152. package/web/.next/server/chunks/ssr/[root-of-the-server]__f648005b._.js +9 -0
  153. package/web/.next/server/chunks/ssr/[root-of-the-server]__f648005b._.js.map +1 -0
  154. package/web/.next/server/chunks/ssr/_28993370._.js +3 -0
  155. package/web/.next/server/chunks/ssr/_28993370._.js.map +1 -0
  156. package/web/.next/server/chunks/ssr/_380c6567._.js +1 -1
  157. package/web/.next/server/chunks/ssr/_380c6567._.js.map +1 -1
  158. package/web/.next/server/chunks/ssr/_45715073._.js +3 -0
  159. package/web/.next/server/chunks/ssr/{_d81184e2._.js.map → _45715073._.js.map} +1 -1
  160. package/web/.next/server/chunks/ssr/_6978d868._.js +3 -0
  161. package/web/.next/server/chunks/ssr/_6978d868._.js.map +1 -0
  162. package/web/.next/server/chunks/ssr/_85965278._.js +6 -0
  163. package/web/.next/server/chunks/ssr/_85965278._.js.map +1 -0
  164. package/web/.next/server/chunks/ssr/_c52cace8._.js +3 -0
  165. package/web/.next/server/chunks/ssr/_c52cace8._.js.map +1 -0
  166. package/web/.next/server/chunks/ssr/_ed9132c9._.js +3 -0
  167. package/web/.next/server/chunks/ssr/_ed9132c9._.js.map +1 -0
  168. package/web/.next/server/chunks/ssr/{node_modules__pnpm_87f920e7._.js → node_modules__pnpm_febcbea6._.js} +2 -2
  169. package/web/.next/server/chunks/ssr/node_modules__pnpm_febcbea6._.js.map +1 -0
  170. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  171. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  172. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  173. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
  174. package/web/.next/server/middleware-build-manifest.js +5 -4
  175. package/web/.next/server/pages/500.html +2 -2
  176. package/web/.next/server/server-reference-manifest.js +1 -1
  177. package/web/.next/server/server-reference-manifest.json +118 -30
  178. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  179. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +7 -6
  180. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  181. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  182. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error/page/build-manifest.json +5 -4
  183. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  184. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  185. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  186. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  187. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  188. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  189. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  190. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  191. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  192. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/build-manifest.json +5 -4
  193. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  194. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  195. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  196. package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js +1 -1
  197. package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -1
  198. package/web/.next/standalone/src/presentation/web/.next/server/app/page/build-manifest.json +5 -4
  199. package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +88 -28
  200. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js +2 -2
  201. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
  202. package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
  203. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/build-manifest.json +5 -4
  204. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +62 -2
  205. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js +2 -2
  206. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
  207. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  208. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/build-manifest.json +5 -4
  209. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  210. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
  211. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  212. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/build-manifest.json +5 -4
  213. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  214. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js +1 -1
  215. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
  216. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  217. package/web/.next/standalone/src/presentation/web/.next/server/chunks/{[root-of-the-server]__e926de65._.js → [root-of-the-server]__09413611._.js} +2 -2
  218. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/403f9_next_dist_623b646a._.js +3 -0
  219. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  220. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{[root-of-the-server]__685eaa45._.js → [root-of-the-server]__248ee887._.js} +2 -2
  221. package/web/.next/{server/chunks/ssr/[root-of-the-server]__fbc89707._.js → standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js} +2 -2
  222. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js +4 -0
  223. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  224. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6bb51fac._.js +3 -0
  225. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  226. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
  227. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__c1f0f2a8._.js +3 -0
  228. package/web/.next/{server/chunks/ssr/[root-of-the-server]__dd5b62cb._.js → standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__f5830fa9._.js} +2 -2
  229. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__f648005b._.js +9 -0
  230. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_28993370._.js +3 -0
  231. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_380c6567._.js +1 -1
  232. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_45715073._.js +3 -0
  233. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_6978d868._.js +3 -0
  234. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_85965278._.js +6 -0
  235. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_c52cace8._.js +3 -0
  236. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_ed9132c9._.js +3 -0
  237. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{node_modules__pnpm_87f920e7._.js → node_modules__pnpm_febcbea6._.js} +2 -2
  238. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  239. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  240. package/web/.next/standalone/src/presentation/web/.next/server/middleware-build-manifest.js +5 -4
  241. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  242. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  243. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +118 -30
  244. package/web/.next/standalone/src/presentation/web/app/actions/deploy-feature.ts +39 -0
  245. package/web/.next/standalone/src/presentation/web/app/actions/deploy-repository.ts +28 -0
  246. package/web/.next/standalone/src/presentation/web/app/actions/get-deployment-status.ts +16 -0
  247. package/web/.next/standalone/src/presentation/web/app/actions/stop-deployment.ts +22 -0
  248. package/web/.next/standalone/src/presentation/web/app/build-graph-nodes.ts +180 -0
  249. package/web/.next/standalone/src/presentation/web/app/page.tsx +2 -129
  250. package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.stories.tsx +26 -0
  251. package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx +45 -1
  252. package/web/.next/standalone/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.tsx +35 -0
  253. package/web/.next/standalone/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.tsx +42 -0
  254. package/web/.next/standalone/src/presentation/web/components/common/deployment-status-badge/index.ts +1 -0
  255. package/web/.next/standalone/src/presentation/web/components/common/feature-drawer/feature-drawer.tsx +10 -0
  256. package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-drawer.tsx +9 -0
  257. package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-node.tsx +43 -2
  258. package/web/.next/standalone/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.tsx +79 -44
  259. package/web/.next/standalone/src/presentation/web/hooks/use-deploy-action.ts +161 -0
  260. package/web/.next/standalone/src/presentation/web/lib/feature-flags.ts +1 -0
  261. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  262. package/web/.next/static/chunks/0b99eb9664d47ca7.js +1 -0
  263. package/web/.next/static/chunks/2ec0c24b265971c3.js +1 -0
  264. package/web/.next/static/chunks/41a2adc09edfffaf.js +1 -0
  265. package/web/.next/static/chunks/5054c72b1c8f5912.js +1 -0
  266. package/web/.next/static/chunks/7ad36bef63f15bc6.js +1 -0
  267. package/web/.next/static/chunks/{15f4f62844c3ea0e.js → 86a68ddb0ac40c02.js} +7 -7
  268. package/web/.next/static/chunks/{3b941e59ac013e12.js → 87421ab1062a39b7.js} +2 -2
  269. package/web/.next/static/chunks/{21541b346dd4dd28.js → 8c60d1bd87239066.js} +1 -1
  270. package/web/.next/static/chunks/96f49affaceab206.css +2 -0
  271. package/web/.next/static/chunks/a6d1d774260fc927.js +2 -0
  272. package/web/.next/static/chunks/c7e793951b20a67f.js +1 -0
  273. package/web/.next/static/chunks/f5fb2f182ae9b015.js +1 -0
  274. package/web/.next/static/chunks/faf6eb7311aa7529.js +1 -0
  275. package/web/.next/static/chunks/fffaa0530ef1686d.js +1 -0
  276. package/web/.next/static/chunks/turbopack-b6b5b4f015327a9a.js +4 -0
  277. package/web/.next/trace +1 -1
  278. package/web/.next/trace-build +1 -1
  279. package/web/.next/server/chunks/ssr/[root-of-the-server]__5e0f14e9._.js +0 -3
  280. package/web/.next/server/chunks/ssr/[root-of-the-server]__5e0f14e9._.js.map +0 -1
  281. package/web/.next/server/chunks/ssr/[root-of-the-server]__ae251147._.js +0 -3
  282. package/web/.next/server/chunks/ssr/[root-of-the-server]__ae251147._.js.map +0 -1
  283. package/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js +0 -9
  284. package/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js.map +0 -1
  285. package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +0 -4
  286. package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js.map +0 -1
  287. package/web/.next/server/chunks/ssr/[root-of-the-server]__dd5b62cb._.js.map +0 -1
  288. package/web/.next/server/chunks/ssr/[root-of-the-server]__edca9510._.js +0 -3
  289. package/web/.next/server/chunks/ssr/[root-of-the-server]__edca9510._.js.map +0 -1
  290. package/web/.next/server/chunks/ssr/_73d14b70._.js +0 -3
  291. package/web/.next/server/chunks/ssr/_73d14b70._.js.map +0 -1
  292. package/web/.next/server/chunks/ssr/_7f386377._.js +0 -3
  293. package/web/.next/server/chunks/ssr/_7f386377._.js.map +0 -1
  294. package/web/.next/server/chunks/ssr/_d3711354._.js +0 -6
  295. package/web/.next/server/chunks/ssr/_d3711354._.js.map +0 -1
  296. package/web/.next/server/chunks/ssr/_d81184e2._.js +0 -3
  297. package/web/.next/server/chunks/ssr/node_modules__pnpm_0ce0b44d._.js +0 -3
  298. package/web/.next/server/chunks/ssr/node_modules__pnpm_0ce0b44d._.js.map +0 -1
  299. package/web/.next/server/chunks/ssr/node_modules__pnpm_87f920e7._.js.map +0 -1
  300. package/web/.next/server/chunks/ssr/src_presentation_web_components_7a0b09da._.js +0 -3
  301. package/web/.next/server/chunks/ssr/src_presentation_web_components_7a0b09da._.js.map +0 -1
  302. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__5e0f14e9._.js +0 -3
  303. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__ae251147._.js +0 -3
  304. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js +0 -9
  305. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +0 -4
  306. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__edca9510._.js +0 -3
  307. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_73d14b70._.js +0 -3
  308. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_7f386377._.js +0 -3
  309. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_d3711354._.js +0 -6
  310. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_d81184e2._.js +0 -3
  311. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_0ce0b44d._.js +0 -3
  312. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_7a0b09da._.js +0 -3
  313. package/web/.next/static/chunks/0c6654ec27f11c7e.js +0 -1
  314. package/web/.next/static/chunks/12c70bfd5951cf9b.js +0 -1
  315. package/web/.next/static/chunks/1887af4ad3781531.js +0 -2
  316. package/web/.next/static/chunks/78919481e7c5ad4f.js +0 -1
  317. package/web/.next/static/chunks/a5b6a22de303e877.css +0 -2
  318. package/web/.next/static/chunks/aa33d2874dacee4a.js +0 -1
  319. package/web/.next/static/chunks/acdb8af5a21f1ae9.js +0 -1
  320. package/web/.next/static/chunks/af7a5bcb7c49e46e.js +0 -1
  321. package/web/.next/static/chunks/be784143669bb992.js +0 -1
  322. package/web/.next/static/chunks/turbopack-eb24b869babb34b4.js +0 -4
  323. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__fbc89707._.js.map → [root-of-the-server]__249c74f6._.js.map} +0 -0
  324. /package/web/.next/static/{7tTtII__gsa2CGwarYgOr → VQhryfJCxF8IeQiBJFQyJ}/_buildManifest.js +0 -0
  325. /package/web/.next/static/{7tTtII__gsa2CGwarYgOr → VQhryfJCxF8IeQiBJFQyJ}/_clientMiddlewareManifest.json +0 -0
  326. /package/web/.next/static/{7tTtII__gsa2CGwarYgOr → VQhryfJCxF8IeQiBJFQyJ}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- self.__RSC_SERVER_MANIFEST="{\n \"node\": {\n \"00a359398edb367a523a72d4b891a73da9edcf06c4\": {\n \"workers\": {\n \"app/_not-found/page\": {\n \"moduleId\": 66973,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n },\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n },\n \"app/skills/page\": {\n \"moduleId\": 41115,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n },\n \"app/tools/page\": {\n \"moduleId\": 19036,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n },\n \"app/version/page\": {\n \"moduleId\": 86139,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n }\n },\n \"layer\": {\n \"app/_not-found/page\": \"action-browser\",\n \"app/page\": \"action-browser\",\n \"app/skills/page\": \"action-browser\",\n \"app/tools/page\": \"action-browser\",\n \"app/version/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\",\n \"exportedName\": \"pickFolder\"\n },\n \"60c9525251d028bce732fea7299dee05ea8de7e0bb\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"approveFeature\",\n \"filename\": \"src/presentation/web/app/actions/approve-feature.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/approve-feature.ts\",\n \"exportedName\": \"approveFeature\"\n },\n \"602b442e41faa5aa260bbe5384ab82a79d752e6c34\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"rejectFeature\",\n \"filename\": \"src/presentation/web/app/actions/reject-feature.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/reject-feature.ts\",\n \"exportedName\": \"rejectFeature\"\n },\n \"40bde38ff657f740c207f4202a40e20bbf7a94ee41\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"getFeatureArtifact\",\n \"filename\": \"src/presentation/web/app/actions/get-feature-artifact.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/get-feature-artifact.ts\",\n \"exportedName\": \"getFeatureArtifact\"\n },\n \"4083a2fb7dd36fa3732166159da8e823ebbf4fe9ed\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"getResearchArtifact\",\n \"filename\": \"src/presentation/web/app/actions/get-research-artifact.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/get-research-artifact.ts\",\n \"exportedName\": \"getResearchArtifact\"\n },\n \"007e2a25fa70e0a9e71587c6de37fcbc6a7d4c5c97\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"getWorkflowDefaults\",\n \"filename\": \"src/presentation/web/app/actions/get-workflow-defaults.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/get-workflow-defaults.ts\",\n \"exportedName\": \"getWorkflowDefaults\"\n },\n \"40ef89aa99539c5573ed7a22160ce3c7763206bb78\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"getMergeReviewData\",\n \"filename\": \"src/presentation/web/app/actions/get-merge-review-data.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/get-merge-review-data.ts\",\n \"exportedName\": \"getMergeReviewData\"\n },\n \"40cc00c1ac8c2e305bb03aebea80e1e77fe54596a0\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"openIde\",\n \"filename\": \"src/presentation/web/app/actions/open-ide.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/open-ide.ts\",\n \"exportedName\": \"openIde\"\n },\n \"40cd70e6dc9ab5cb424fe22b935fb7dd508ab72ad6\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"openShell\",\n \"filename\": \"src/presentation/web/app/actions/open-shell.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/open-shell.ts\",\n \"exportedName\": \"openShell\"\n },\n \"408fe7cdc71037a0922c9ca2c067c66a93d799ecfb\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"openFolder\",\n \"filename\": \"src/presentation/web/app/actions/open-folder.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/open-folder.ts\",\n \"exportedName\": \"openFolder\"\n },\n \"40317195b99a3c9c1c083963f3141a66c1a6d89ce9\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"createFeature\",\n \"filename\": \"src/presentation/web/app/actions/create-feature.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/create-feature.ts\",\n \"exportedName\": \"createFeature\"\n },\n \"409e290e843f104c745ec12484572be7abeebd72b8\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"deleteFeature\",\n \"filename\": \"src/presentation/web/app/actions/delete-feature.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/delete-feature.ts\",\n \"exportedName\": \"deleteFeature\"\n },\n \"40fc7289a81343009e8b04dd4caa0bdf7974453341\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"addRepository\",\n \"filename\": \"src/presentation/web/app/actions/add-repository.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/add-repository.ts\",\n \"exportedName\": \"addRepository\"\n },\n \"403119fcc47c50d87666d1132793a84ecf17abddad\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 16555,\n \"async\": false,\n \"exportedName\": \"deleteRepository\",\n \"filename\": \"src/presentation/web/app/actions/delete-repository.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/delete-repository.ts\",\n \"exportedName\": \"deleteRepository\"\n }\n },\n \"edge\": {},\n \"encryptionKey\": \"MTN+8ywKN3Cpy4Rjh9h+D8yEYUL8X1IZLK5EUHmIHco=\"\n}"
1
+ self.__RSC_SERVER_MANIFEST="{\n \"node\": {\n \"00772333d20fe2fd0b846c892c3d1c63798dfd8191\": {\n \"workers\": {\n \"app/_not-found/page\": {\n \"moduleId\": 66973,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n },\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n },\n \"app/skills/page\": {\n \"moduleId\": 43368,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n },\n \"app/tools/page\": {\n \"moduleId\": 19036,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n },\n \"app/version/page\": {\n \"moduleId\": 86139,\n \"async\": false,\n \"exportedName\": \"pickFolder\",\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\"\n }\n },\n \"layer\": {\n \"app/_not-found/page\": \"action-browser\",\n \"app/page\": \"action-browser\",\n \"app/skills/page\": \"action-browser\",\n \"app/tools/page\": \"action-browser\",\n \"app/version/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/pick-folder.ts\",\n \"exportedName\": \"pickFolder\"\n },\n \"60584f39d42d848f63b1431a2b308bcceb6125dee1\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"approveFeature\",\n \"filename\": \"src/presentation/web/app/actions/approve-feature.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/approve-feature.ts\",\n \"exportedName\": \"approveFeature\"\n },\n \"602b970412071432fdf7a0c9682f22126e01220ada\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"rejectFeature\",\n \"filename\": \"src/presentation/web/app/actions/reject-feature.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/reject-feature.ts\",\n \"exportedName\": \"rejectFeature\"\n },\n \"4069d886e3d5303a4517f1a93fd3c0fcb48933d6af\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"getFeatureArtifact\",\n \"filename\": \"src/presentation/web/app/actions/get-feature-artifact.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/get-feature-artifact.ts\",\n \"exportedName\": \"getFeatureArtifact\"\n },\n \"405bb978481a3dab6d3a614c3149ae325b5de239f3\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"getResearchArtifact\",\n \"filename\": \"src/presentation/web/app/actions/get-research-artifact.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/get-research-artifact.ts\",\n \"exportedName\": \"getResearchArtifact\"\n },\n \"0036be035ddd030e750008c6de2a90dfdbbbc1007c\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"getWorkflowDefaults\",\n \"filename\": \"src/presentation/web/app/actions/get-workflow-defaults.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/get-workflow-defaults.ts\",\n \"exportedName\": \"getWorkflowDefaults\"\n },\n \"4010499ea3348623ea7f5809b003d356fbecce663a\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"getMergeReviewData\",\n \"filename\": \"src/presentation/web/app/actions/get-merge-review-data.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/get-merge-review-data.ts\",\n \"exportedName\": \"getMergeReviewData\"\n },\n \"40b7b90414ae236c8fc508faeaef4b5a9ed1fd702b\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"deployFeature\",\n \"filename\": \"src/presentation/web/app/actions/deploy-feature.ts\"\n },\n \"app/skills/page\": {\n \"moduleId\": 43368,\n \"async\": false,\n \"exportedName\": \"deployFeature\",\n \"filename\": \"src/presentation/web/app/actions/deploy-feature.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\",\n \"app/skills/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/deploy-feature.ts\",\n \"exportedName\": \"deployFeature\"\n },\n \"40015ffe022cac8955ed69d533655ee9e714863d11\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"deployRepository\",\n \"filename\": \"src/presentation/web/app/actions/deploy-repository.ts\"\n },\n \"app/skills/page\": {\n \"moduleId\": 43368,\n \"async\": false,\n \"exportedName\": \"deployRepository\",\n \"filename\": \"src/presentation/web/app/actions/deploy-repository.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\",\n \"app/skills/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/deploy-repository.ts\",\n \"exportedName\": \"deployRepository\"\n },\n \"40d37277be3479f63d377b3ac59ac7439f54d4c821\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"stopDeployment\",\n \"filename\": \"src/presentation/web/app/actions/stop-deployment.ts\"\n },\n \"app/skills/page\": {\n \"moduleId\": 43368,\n \"async\": false,\n \"exportedName\": \"stopDeployment\",\n \"filename\": \"src/presentation/web/app/actions/stop-deployment.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\",\n \"app/skills/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/stop-deployment.ts\",\n \"exportedName\": \"stopDeployment\"\n },\n \"40212277f184eee3f9ca0a97f9e213df08697ceada\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"getDeploymentStatus\",\n \"filename\": \"src/presentation/web/app/actions/get-deployment-status.ts\"\n },\n \"app/skills/page\": {\n \"moduleId\": 43368,\n \"async\": false,\n \"exportedName\": \"getDeploymentStatus\",\n \"filename\": \"src/presentation/web/app/actions/get-deployment-status.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\",\n \"app/skills/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/get-deployment-status.ts\",\n \"exportedName\": \"getDeploymentStatus\"\n },\n \"401de3917be76564aae0d21b620f077186d6baca20\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"openIde\",\n \"filename\": \"src/presentation/web/app/actions/open-ide.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/open-ide.ts\",\n \"exportedName\": \"openIde\"\n },\n \"4050d2233450bfbf2349a2da7adfce4463a5df750a\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"openShell\",\n \"filename\": \"src/presentation/web/app/actions/open-shell.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/open-shell.ts\",\n \"exportedName\": \"openShell\"\n },\n \"400333f5300f58d3867d321897ccc258a8c6004b0a\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"openFolder\",\n \"filename\": \"src/presentation/web/app/actions/open-folder.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/open-folder.ts\",\n \"exportedName\": \"openFolder\"\n },\n \"40857d75d0a810d2fa1d44c7a2fbb7ee9da72e3d2b\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"createFeature\",\n \"filename\": \"src/presentation/web/app/actions/create-feature.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/create-feature.ts\",\n \"exportedName\": \"createFeature\"\n },\n \"40271fb84b1f82af12a49184290ffa1918e2538aea\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"deleteFeature\",\n \"filename\": \"src/presentation/web/app/actions/delete-feature.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/delete-feature.ts\",\n \"exportedName\": \"deleteFeature\"\n },\n \"40a0a3701bca62e9b7142732f810e1e8fdb39d40cb\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"addRepository\",\n \"filename\": \"src/presentation/web/app/actions/add-repository.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/add-repository.ts\",\n \"exportedName\": \"addRepository\"\n },\n \"407ee4e21078c7d3c23b4166fc902f43b39b75b88a\": {\n \"workers\": {\n \"app/page\": {\n \"moduleId\": 98380,\n \"async\": false,\n \"exportedName\": \"deleteRepository\",\n \"filename\": \"src/presentation/web/app/actions/delete-repository.ts\"\n }\n },\n \"layer\": {\n \"app/page\": \"action-browser\"\n },\n \"filename\": \"src/presentation/web/app/actions/delete-repository.ts\",\n \"exportedName\": \"deleteRepository\"\n }\n },\n \"edge\": {},\n \"encryptionKey\": \"EtIIp1eOgOvp7kuXQ74LNPZTDZb6hQe1b7SCwHK/QA4=\"\n}"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "node": {
3
- "00a359398edb367a523a72d4b891a73da9edcf06c4": {
3
+ "00772333d20fe2fd0b846c892c3d1c63798dfd8191": {
4
4
  "workers": {
5
5
  "app/_not-found/page": {
6
6
  "moduleId": 66973,
@@ -9,13 +9,13 @@
9
9
  "filename": "src/presentation/web/app/actions/pick-folder.ts"
10
10
  },
11
11
  "app/page": {
12
- "moduleId": 16555,
12
+ "moduleId": 98380,
13
13
  "async": false,
14
14
  "exportedName": "pickFolder",
15
15
  "filename": "src/presentation/web/app/actions/pick-folder.ts"
16
16
  },
17
17
  "app/skills/page": {
18
- "moduleId": 41115,
18
+ "moduleId": 43368,
19
19
  "async": false,
20
20
  "exportedName": "pickFolder",
21
21
  "filename": "src/presentation/web/app/actions/pick-folder.ts"
@@ -43,10 +43,10 @@
43
43
  "filename": "src/presentation/web/app/actions/pick-folder.ts",
44
44
  "exportedName": "pickFolder"
45
45
  },
46
- "60c9525251d028bce732fea7299dee05ea8de7e0bb": {
46
+ "60584f39d42d848f63b1431a2b308bcceb6125dee1": {
47
47
  "workers": {
48
48
  "app/page": {
49
- "moduleId": 16555,
49
+ "moduleId": 98380,
50
50
  "async": false,
51
51
  "exportedName": "approveFeature",
52
52
  "filename": "src/presentation/web/app/actions/approve-feature.ts"
@@ -58,10 +58,10 @@
58
58
  "filename": "src/presentation/web/app/actions/approve-feature.ts",
59
59
  "exportedName": "approveFeature"
60
60
  },
61
- "602b442e41faa5aa260bbe5384ab82a79d752e6c34": {
61
+ "602b970412071432fdf7a0c9682f22126e01220ada": {
62
62
  "workers": {
63
63
  "app/page": {
64
- "moduleId": 16555,
64
+ "moduleId": 98380,
65
65
  "async": false,
66
66
  "exportedName": "rejectFeature",
67
67
  "filename": "src/presentation/web/app/actions/reject-feature.ts"
@@ -73,10 +73,10 @@
73
73
  "filename": "src/presentation/web/app/actions/reject-feature.ts",
74
74
  "exportedName": "rejectFeature"
75
75
  },
76
- "40bde38ff657f740c207f4202a40e20bbf7a94ee41": {
76
+ "4069d886e3d5303a4517f1a93fd3c0fcb48933d6af": {
77
77
  "workers": {
78
78
  "app/page": {
79
- "moduleId": 16555,
79
+ "moduleId": 98380,
80
80
  "async": false,
81
81
  "exportedName": "getFeatureArtifact",
82
82
  "filename": "src/presentation/web/app/actions/get-feature-artifact.ts"
@@ -88,10 +88,10 @@
88
88
  "filename": "src/presentation/web/app/actions/get-feature-artifact.ts",
89
89
  "exportedName": "getFeatureArtifact"
90
90
  },
91
- "4083a2fb7dd36fa3732166159da8e823ebbf4fe9ed": {
91
+ "405bb978481a3dab6d3a614c3149ae325b5de239f3": {
92
92
  "workers": {
93
93
  "app/page": {
94
- "moduleId": 16555,
94
+ "moduleId": 98380,
95
95
  "async": false,
96
96
  "exportedName": "getResearchArtifact",
97
97
  "filename": "src/presentation/web/app/actions/get-research-artifact.ts"
@@ -103,10 +103,10 @@
103
103
  "filename": "src/presentation/web/app/actions/get-research-artifact.ts",
104
104
  "exportedName": "getResearchArtifact"
105
105
  },
106
- "007e2a25fa70e0a9e71587c6de37fcbc6a7d4c5c97": {
106
+ "0036be035ddd030e750008c6de2a90dfdbbbc1007c": {
107
107
  "workers": {
108
108
  "app/page": {
109
- "moduleId": 16555,
109
+ "moduleId": 98380,
110
110
  "async": false,
111
111
  "exportedName": "getWorkflowDefaults",
112
112
  "filename": "src/presentation/web/app/actions/get-workflow-defaults.ts"
@@ -118,10 +118,10 @@
118
118
  "filename": "src/presentation/web/app/actions/get-workflow-defaults.ts",
119
119
  "exportedName": "getWorkflowDefaults"
120
120
  },
121
- "40ef89aa99539c5573ed7a22160ce3c7763206bb78": {
121
+ "4010499ea3348623ea7f5809b003d356fbecce663a": {
122
122
  "workers": {
123
123
  "app/page": {
124
- "moduleId": 16555,
124
+ "moduleId": 98380,
125
125
  "async": false,
126
126
  "exportedName": "getMergeReviewData",
127
127
  "filename": "src/presentation/web/app/actions/get-merge-review-data.ts"
@@ -133,10 +133,98 @@
133
133
  "filename": "src/presentation/web/app/actions/get-merge-review-data.ts",
134
134
  "exportedName": "getMergeReviewData"
135
135
  },
136
- "40cc00c1ac8c2e305bb03aebea80e1e77fe54596a0": {
136
+ "40b7b90414ae236c8fc508faeaef4b5a9ed1fd702b": {
137
137
  "workers": {
138
138
  "app/page": {
139
- "moduleId": 16555,
139
+ "moduleId": 98380,
140
+ "async": false,
141
+ "exportedName": "deployFeature",
142
+ "filename": "src/presentation/web/app/actions/deploy-feature.ts"
143
+ },
144
+ "app/skills/page": {
145
+ "moduleId": 43368,
146
+ "async": false,
147
+ "exportedName": "deployFeature",
148
+ "filename": "src/presentation/web/app/actions/deploy-feature.ts"
149
+ }
150
+ },
151
+ "layer": {
152
+ "app/page": "action-browser",
153
+ "app/skills/page": "action-browser"
154
+ },
155
+ "filename": "src/presentation/web/app/actions/deploy-feature.ts",
156
+ "exportedName": "deployFeature"
157
+ },
158
+ "40015ffe022cac8955ed69d533655ee9e714863d11": {
159
+ "workers": {
160
+ "app/page": {
161
+ "moduleId": 98380,
162
+ "async": false,
163
+ "exportedName": "deployRepository",
164
+ "filename": "src/presentation/web/app/actions/deploy-repository.ts"
165
+ },
166
+ "app/skills/page": {
167
+ "moduleId": 43368,
168
+ "async": false,
169
+ "exportedName": "deployRepository",
170
+ "filename": "src/presentation/web/app/actions/deploy-repository.ts"
171
+ }
172
+ },
173
+ "layer": {
174
+ "app/page": "action-browser",
175
+ "app/skills/page": "action-browser"
176
+ },
177
+ "filename": "src/presentation/web/app/actions/deploy-repository.ts",
178
+ "exportedName": "deployRepository"
179
+ },
180
+ "40d37277be3479f63d377b3ac59ac7439f54d4c821": {
181
+ "workers": {
182
+ "app/page": {
183
+ "moduleId": 98380,
184
+ "async": false,
185
+ "exportedName": "stopDeployment",
186
+ "filename": "src/presentation/web/app/actions/stop-deployment.ts"
187
+ },
188
+ "app/skills/page": {
189
+ "moduleId": 43368,
190
+ "async": false,
191
+ "exportedName": "stopDeployment",
192
+ "filename": "src/presentation/web/app/actions/stop-deployment.ts"
193
+ }
194
+ },
195
+ "layer": {
196
+ "app/page": "action-browser",
197
+ "app/skills/page": "action-browser"
198
+ },
199
+ "filename": "src/presentation/web/app/actions/stop-deployment.ts",
200
+ "exportedName": "stopDeployment"
201
+ },
202
+ "40212277f184eee3f9ca0a97f9e213df08697ceada": {
203
+ "workers": {
204
+ "app/page": {
205
+ "moduleId": 98380,
206
+ "async": false,
207
+ "exportedName": "getDeploymentStatus",
208
+ "filename": "src/presentation/web/app/actions/get-deployment-status.ts"
209
+ },
210
+ "app/skills/page": {
211
+ "moduleId": 43368,
212
+ "async": false,
213
+ "exportedName": "getDeploymentStatus",
214
+ "filename": "src/presentation/web/app/actions/get-deployment-status.ts"
215
+ }
216
+ },
217
+ "layer": {
218
+ "app/page": "action-browser",
219
+ "app/skills/page": "action-browser"
220
+ },
221
+ "filename": "src/presentation/web/app/actions/get-deployment-status.ts",
222
+ "exportedName": "getDeploymentStatus"
223
+ },
224
+ "401de3917be76564aae0d21b620f077186d6baca20": {
225
+ "workers": {
226
+ "app/page": {
227
+ "moduleId": 98380,
140
228
  "async": false,
141
229
  "exportedName": "openIde",
142
230
  "filename": "src/presentation/web/app/actions/open-ide.ts"
@@ -148,10 +236,10 @@
148
236
  "filename": "src/presentation/web/app/actions/open-ide.ts",
149
237
  "exportedName": "openIde"
150
238
  },
151
- "40cd70e6dc9ab5cb424fe22b935fb7dd508ab72ad6": {
239
+ "4050d2233450bfbf2349a2da7adfce4463a5df750a": {
152
240
  "workers": {
153
241
  "app/page": {
154
- "moduleId": 16555,
242
+ "moduleId": 98380,
155
243
  "async": false,
156
244
  "exportedName": "openShell",
157
245
  "filename": "src/presentation/web/app/actions/open-shell.ts"
@@ -163,10 +251,10 @@
163
251
  "filename": "src/presentation/web/app/actions/open-shell.ts",
164
252
  "exportedName": "openShell"
165
253
  },
166
- "408fe7cdc71037a0922c9ca2c067c66a93d799ecfb": {
254
+ "400333f5300f58d3867d321897ccc258a8c6004b0a": {
167
255
  "workers": {
168
256
  "app/page": {
169
- "moduleId": 16555,
257
+ "moduleId": 98380,
170
258
  "async": false,
171
259
  "exportedName": "openFolder",
172
260
  "filename": "src/presentation/web/app/actions/open-folder.ts"
@@ -178,10 +266,10 @@
178
266
  "filename": "src/presentation/web/app/actions/open-folder.ts",
179
267
  "exportedName": "openFolder"
180
268
  },
181
- "40317195b99a3c9c1c083963f3141a66c1a6d89ce9": {
269
+ "40857d75d0a810d2fa1d44c7a2fbb7ee9da72e3d2b": {
182
270
  "workers": {
183
271
  "app/page": {
184
- "moduleId": 16555,
272
+ "moduleId": 98380,
185
273
  "async": false,
186
274
  "exportedName": "createFeature",
187
275
  "filename": "src/presentation/web/app/actions/create-feature.ts"
@@ -193,10 +281,10 @@
193
281
  "filename": "src/presentation/web/app/actions/create-feature.ts",
194
282
  "exportedName": "createFeature"
195
283
  },
196
- "409e290e843f104c745ec12484572be7abeebd72b8": {
284
+ "40271fb84b1f82af12a49184290ffa1918e2538aea": {
197
285
  "workers": {
198
286
  "app/page": {
199
- "moduleId": 16555,
287
+ "moduleId": 98380,
200
288
  "async": false,
201
289
  "exportedName": "deleteFeature",
202
290
  "filename": "src/presentation/web/app/actions/delete-feature.ts"
@@ -208,10 +296,10 @@
208
296
  "filename": "src/presentation/web/app/actions/delete-feature.ts",
209
297
  "exportedName": "deleteFeature"
210
298
  },
211
- "40fc7289a81343009e8b04dd4caa0bdf7974453341": {
299
+ "40a0a3701bca62e9b7142732f810e1e8fdb39d40cb": {
212
300
  "workers": {
213
301
  "app/page": {
214
- "moduleId": 16555,
302
+ "moduleId": 98380,
215
303
  "async": false,
216
304
  "exportedName": "addRepository",
217
305
  "filename": "src/presentation/web/app/actions/add-repository.ts"
@@ -223,10 +311,10 @@
223
311
  "filename": "src/presentation/web/app/actions/add-repository.ts",
224
312
  "exportedName": "addRepository"
225
313
  },
226
- "403119fcc47c50d87666d1132793a84ecf17abddad": {
314
+ "407ee4e21078c7d3c23b4166fc902f43b39b75b88a": {
227
315
  "workers": {
228
316
  "app/page": {
229
- "moduleId": 16555,
317
+ "moduleId": 98380,
230
318
  "async": false,
231
319
  "exportedName": "deleteRepository",
232
320
  "filename": "src/presentation/web/app/actions/delete-repository.ts"
@@ -240,5 +328,5 @@
240
328
  }
241
329
  },
242
330
  "edge": {},
243
- "encryptionKey": "MTN+8ywKN3Cpy4Rjh9h+D8yEYUL8X1IZLK5EUHmIHco="
331
+ "encryptionKey": "EtIIp1eOgOvp7kuXQ74LNPZTDZb6hQe1b7SCwHK/QA4="
244
332
  }
@@ -0,0 +1,39 @@
1
+ 'use server';
2
+
3
+ import { existsSync } from 'node:fs';
4
+ import { resolve } from '@/lib/server-container';
5
+ import { computeWorktreePath } from '@shepai/core/infrastructure/services/ide-launchers/compute-worktree-path';
6
+ import type { IFeatureRepository } from '@shepai/core/application/ports/output/repositories/feature-repository.interface';
7
+ import type { IDeploymentService } from '@shepai/core/application/ports/output/services/deployment-service.interface';
8
+ import { DeploymentState } from '@shepai/core/domain/generated/output';
9
+
10
+ export async function deployFeature(
11
+ featureId: string
12
+ ): Promise<{ success: boolean; error?: string; state?: DeploymentState }> {
13
+ if (!featureId?.trim()) {
14
+ return { success: false, error: 'featureId is required' };
15
+ }
16
+
17
+ try {
18
+ const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');
19
+ const feature = await featureRepo.findById(featureId);
20
+
21
+ if (!feature) {
22
+ return { success: false, error: `Feature not found: ${featureId}` };
23
+ }
24
+
25
+ const worktreePath = computeWorktreePath(feature.repositoryPath, feature.branch);
26
+
27
+ if (!existsSync(worktreePath)) {
28
+ return { success: false, error: `Worktree path does not exist: ${worktreePath}` };
29
+ }
30
+
31
+ const deploymentService = resolve<IDeploymentService>('IDeploymentService');
32
+ deploymentService.start(featureId, worktreePath);
33
+
34
+ return { success: true, state: DeploymentState.Booting };
35
+ } catch (error: unknown) {
36
+ const message = error instanceof Error ? error.message : 'Failed to deploy feature';
37
+ return { success: false, error: message };
38
+ }
39
+ }
@@ -0,0 +1,28 @@
1
+ 'use server';
2
+
3
+ import { existsSync } from 'node:fs';
4
+ import { resolve } from '@/lib/server-container';
5
+ import type { IDeploymentService } from '@shepai/core/application/ports/output/services/deployment-service.interface';
6
+ import { DeploymentState } from '@shepai/core/domain/generated/output';
7
+
8
+ export async function deployRepository(
9
+ repositoryPath: string
10
+ ): Promise<{ success: boolean; error?: string; state?: DeploymentState }> {
11
+ if (!repositoryPath?.startsWith('/')) {
12
+ return { success: false, error: 'repositoryPath must be an absolute path' };
13
+ }
14
+
15
+ try {
16
+ if (!existsSync(repositoryPath)) {
17
+ return { success: false, error: `Directory does not exist: ${repositoryPath}` };
18
+ }
19
+
20
+ const deploymentService = resolve<IDeploymentService>('IDeploymentService');
21
+ deploymentService.start(repositoryPath, repositoryPath);
22
+
23
+ return { success: true, state: DeploymentState.Booting };
24
+ } catch (error: unknown) {
25
+ const message = error instanceof Error ? error.message : 'Failed to deploy repository';
26
+ return { success: false, error: message };
27
+ }
28
+ }
@@ -0,0 +1,16 @@
1
+ 'use server';
2
+
3
+ import { resolve } from '@/lib/server-container';
4
+ import type {
5
+ IDeploymentService,
6
+ DeploymentStatus,
7
+ } from '@shepai/core/application/ports/output/services/deployment-service.interface';
8
+
9
+ export async function getDeploymentStatus(targetId: string): Promise<DeploymentStatus | null> {
10
+ if (!targetId?.trim()) {
11
+ return null;
12
+ }
13
+
14
+ const deploymentService = resolve<IDeploymentService>('IDeploymentService');
15
+ return deploymentService.getStatus(targetId);
16
+ }
@@ -0,0 +1,22 @@
1
+ 'use server';
2
+
3
+ import { resolve } from '@/lib/server-container';
4
+ import type { IDeploymentService } from '@shepai/core/application/ports/output/services/deployment-service.interface';
5
+
6
+ export async function stopDeployment(
7
+ targetId: string
8
+ ): Promise<{ success: boolean; error?: string }> {
9
+ if (!targetId?.trim()) {
10
+ return { success: false, error: 'targetId is required' };
11
+ }
12
+
13
+ try {
14
+ const deploymentService = resolve<IDeploymentService>('IDeploymentService');
15
+ await deploymentService.stop(targetId);
16
+
17
+ return { success: true };
18
+ } catch (error: unknown) {
19
+ const message = error instanceof Error ? error.message : 'Failed to stop deployment';
20
+ return { success: false, error: message };
21
+ }
22
+ }
@@ -0,0 +1,180 @@
1
+ import type { Feature, Repository, AgentRun } from '@shepai/core/domain/generated/output';
2
+ import {
3
+ deriveNodeState,
4
+ deriveProgress,
5
+ } from '@/components/common/feature-node/derive-feature-state';
6
+ import type { CanvasNodeType } from '@/components/features/features-canvas';
7
+ import type { Edge } from '@xyflow/react';
8
+ import type { FeatureNodeData, FeatureLifecyclePhase } from '@/components/common/feature-node';
9
+
10
+ /** Map domain SdlcLifecycle enum values to UI FeatureLifecyclePhase (1:1). */
11
+ const lifecycleMap: Record<string, FeatureLifecyclePhase> = {
12
+ Requirements: 'requirements',
13
+ Research: 'research',
14
+ Implementation: 'implementation',
15
+ Review: 'review',
16
+ 'Deploy & QA': 'deploy',
17
+ Maintain: 'maintain',
18
+ };
19
+
20
+ /** Map agent graph node names (from agent_run.result) to UI lifecycle phases. */
21
+ const nodeToLifecyclePhase: Record<string, FeatureLifecyclePhase> = {
22
+ analyze: 'requirements',
23
+ requirements: 'requirements',
24
+ research: 'research',
25
+ plan: 'implementation',
26
+ implement: 'implementation',
27
+ merge: 'review',
28
+ };
29
+
30
+ export interface FeatureWithRun {
31
+ feature: Feature;
32
+ run: AgentRun | null;
33
+ }
34
+
35
+ /**
36
+ * Builds React Flow nodes and edges from persisted repositories and features.
37
+ *
38
+ * Features whose repositoryPath is not covered by any real repository row are
39
+ * grouped under a synthetic "virtual" repository node
40
+ * (id: `virtual-repo-${repositoryPath}`). This ensures the dashboard never
41
+ * renders empty when features exist but their repository rows are missing.
42
+ */
43
+ export function buildGraphNodes(
44
+ repositories: Repository[],
45
+ featuresWithRuns: FeatureWithRun[]
46
+ ): { nodes: CanvasNodeType[]; edges: Edge[] } {
47
+ // Group features by repository path
48
+ const featuresByRepo: Record<string, FeatureWithRun[]> = {};
49
+ featuresWithRuns.forEach((entry) => {
50
+ const repoKey = entry.feature.repositoryPath;
51
+ if (!featuresByRepo[repoKey]) {
52
+ featuresByRepo[repoKey] = [];
53
+ }
54
+ featuresByRepo[repoKey].push(entry);
55
+ });
56
+
57
+ const nodes: CanvasNodeType[] = [];
58
+ const edges: Edge[] = [];
59
+
60
+ // Track which repository paths have been rendered (to avoid orphan duplicates)
61
+ const coveredPaths = new Set<string>();
62
+
63
+ // First, add nodes for all persisted repositories (including those without features)
64
+ for (const repo of repositories) {
65
+ coveredPaths.add(repo.path);
66
+ const repoNodeId = `repo-${repo.id}`;
67
+ nodes.push({
68
+ id: repoNodeId,
69
+ type: 'repositoryNode',
70
+ position: { x: 0, y: 0 },
71
+ data: { name: repo.name, repositoryPath: repo.path, id: repo.id },
72
+ });
73
+
74
+ const repoFeatures = featuresByRepo[repo.path] ?? [];
75
+ appendFeatureNodes(repoFeatures, repoNodeId, featuresWithRuns, nodes, edges);
76
+ }
77
+
78
+ // Second pass: group orphaned features under virtual repository nodes
79
+ for (const [repoPath, orphanFeatures] of Object.entries(featuresByRepo)) {
80
+ if (coveredPaths.has(repoPath)) continue;
81
+
82
+ const virtualRepoNodeId = `virtual-repo-${repoPath}`;
83
+ const repoName = repoPath.split('/').filter(Boolean).at(-1) ?? repoPath;
84
+ nodes.push({
85
+ id: virtualRepoNodeId,
86
+ type: 'repositoryNode',
87
+ position: { x: 0, y: 0 },
88
+ data: { name: repoName, repositoryPath: repoPath },
89
+ });
90
+
91
+ appendFeatureNodes(orphanFeatures, virtualRepoNodeId, featuresWithRuns, nodes, edges);
92
+ }
93
+
94
+ // Add parent→child dependency edges
95
+ for (const { feature } of featuresWithRuns) {
96
+ if (feature.parentId) {
97
+ const parentNodeId = `feat-${feature.parentId}`;
98
+ const childNodeId = `feat-${feature.id}`;
99
+ if (nodes.some((n) => n.id === parentNodeId) && nodes.some((n) => n.id === childNodeId)) {
100
+ edges.push({
101
+ id: `dep-${parentNodeId}-${childNodeId}`,
102
+ source: parentNodeId,
103
+ target: childNodeId,
104
+ type: 'dependencyEdge',
105
+ });
106
+ }
107
+ }
108
+ }
109
+
110
+ return { nodes, edges };
111
+ }
112
+
113
+ function appendFeatureNodes(
114
+ repoFeatures: FeatureWithRun[],
115
+ repoNodeId: string,
116
+ allFeaturesWithRuns: FeatureWithRun[],
117
+ nodes: CanvasNodeType[],
118
+ edges: Edge[]
119
+ ): void {
120
+ repoFeatures.forEach(({ feature, run }) => {
121
+ const agentNode = run?.result?.startsWith('node:') ? run.result.slice(5) : undefined;
122
+ const lifecycle: FeatureLifecyclePhase =
123
+ run?.status === 'completed'
124
+ ? 'maintain'
125
+ : ((agentNode ? nodeToLifecyclePhase[agentNode] : undefined) ??
126
+ lifecycleMap[feature.lifecycle] ??
127
+ 'requirements');
128
+
129
+ // Resolve blockedBy display name from parent feature
130
+ let blockedBy: string | undefined;
131
+ if (feature.parentId && feature.lifecycle === 'Blocked') {
132
+ const parentEntry = allFeaturesWithRuns.find((e) => e.feature.id === feature.parentId);
133
+ if (parentEntry) {
134
+ blockedBy = parentEntry.feature.name;
135
+ }
136
+ }
137
+
138
+ const nodeData: FeatureNodeData = {
139
+ name: feature.name,
140
+ description: feature.description ?? feature.slug,
141
+ featureId: feature.id,
142
+ lifecycle,
143
+ repositoryPath: feature.repositoryPath,
144
+ branch: feature.branch,
145
+ specPath: feature.specPath,
146
+ state: deriveNodeState(feature, run),
147
+ progress: deriveProgress(feature),
148
+ ...(run?.agentType && { agentType: run.agentType as FeatureNodeData['agentType'] }),
149
+ ...(run?.error && { errorMessage: run.error }),
150
+ ...(blockedBy && { blockedBy }),
151
+ ...(feature.pr && {
152
+ pr: {
153
+ url: feature.pr.url,
154
+ number: feature.pr.number,
155
+ status: feature.pr.status,
156
+ ciStatus: feature.pr.ciStatus,
157
+ commitHash: feature.pr.commitHash,
158
+ },
159
+ }),
160
+ };
161
+
162
+ const featureNodeId = `feat-${feature.id}`;
163
+ nodes.push({
164
+ id: featureNodeId,
165
+ type: 'featureNode',
166
+ position: { x: 0, y: 0 },
167
+ data: nodeData,
168
+ });
169
+
170
+ // Child features connect via parent→child dependency edge, not directly to repo
171
+ if (!feature.parentId) {
172
+ edges.push({
173
+ id: `edge-${repoNodeId}-${featureNodeId}`,
174
+ source: repoNodeId,
175
+ target: featureNodeId,
176
+ style: { strokeDasharray: '5 5' },
177
+ });
178
+ }
179
+ });
180
+ }