@shepai/cli 1.178.1 → 1.179.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 (323) hide show
  1. package/README.md +2 -0
  2. package/dist/packages/core/src/application/ports/output/services/deployment-service.interface.d.ts +17 -0
  3. package/dist/packages/core/src/application/ports/output/services/deployment-service.interface.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/ports/output/services/file-system-service.interface.d.ts +7 -0
  5. package/dist/packages/core/src/application/ports/output/services/file-system-service.interface.d.ts.map +1 -1
  6. package/dist/packages/core/src/application/ports/output/services/shep-instance-service.interface.d.ts +22 -0
  7. package/dist/packages/core/src/application/ports/output/services/shep-instance-service.interface.d.ts.map +1 -0
  8. package/dist/packages/core/src/application/ports/output/services/shep-instance-service.interface.js +11 -0
  9. package/dist/packages/core/src/application/use-cases/deployments/get-deployment-status.use-case.d.ts +13 -0
  10. package/dist/packages/core/src/application/use-cases/deployments/get-deployment-status.use-case.d.ts.map +1 -0
  11. package/dist/packages/core/src/application/use-cases/deployments/get-deployment-status.use-case.js +37 -0
  12. package/dist/packages/core/src/application/use-cases/deployments/list-deployments.use-case.d.ts +14 -0
  13. package/dist/packages/core/src/application/use-cases/deployments/list-deployments.use-case.d.ts.map +1 -0
  14. package/dist/packages/core/src/application/use-cases/deployments/list-deployments.use-case.js +35 -0
  15. package/dist/packages/core/src/application/use-cases/deployments/start-feature-deployment.use-case.d.ts +27 -0
  16. package/dist/packages/core/src/application/use-cases/deployments/start-feature-deployment.use-case.d.ts.map +1 -0
  17. package/dist/packages/core/src/application/use-cases/deployments/start-feature-deployment.use-case.js +68 -0
  18. package/dist/packages/core/src/application/use-cases/deployments/start-repository-deployment.use-case.d.ts +23 -0
  19. package/dist/packages/core/src/application/use-cases/deployments/start-repository-deployment.use-case.d.ts.map +1 -0
  20. package/dist/packages/core/src/application/use-cases/deployments/start-repository-deployment.use-case.js +58 -0
  21. package/dist/packages/core/src/application/use-cases/deployments/stop-deployment.use-case.d.ts +13 -0
  22. package/dist/packages/core/src/application/use-cases/deployments/stop-deployment.use-case.d.ts.map +1 -0
  23. package/dist/packages/core/src/application/use-cases/deployments/stop-deployment.use-case.js +37 -0
  24. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  25. package/dist/packages/core/src/infrastructure/di/container.js +29 -0
  26. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts +9 -1
  27. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts.map +1 -1
  28. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.js +66 -0
  29. package/dist/packages/core/src/infrastructure/services/file-system.service.d.ts +1 -0
  30. package/dist/packages/core/src/infrastructure/services/file-system.service.d.ts.map +1 -1
  31. package/dist/packages/core/src/infrastructure/services/file-system.service.js +4 -0
  32. package/dist/packages/core/src/infrastructure/services/git/pr-branding.d.ts +1 -1
  33. package/dist/packages/core/src/infrastructure/services/git/pr-branding.d.ts.map +1 -1
  34. package/dist/packages/core/src/infrastructure/services/git/pr-branding.js +1 -1
  35. package/dist/packages/core/src/infrastructure/services/shep-instance.service.d.ts +16 -0
  36. package/dist/packages/core/src/infrastructure/services/shep-instance.service.d.ts.map +1 -0
  37. package/dist/packages/core/src/infrastructure/services/shep-instance.service.js +39 -0
  38. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts +2 -0
  39. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  40. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +9 -19
  41. package/dist/src/presentation/web/app/(dashboard)/layout.d.ts.map +1 -1
  42. package/dist/src/presentation/web/app/(dashboard)/layout.js +3 -2
  43. package/dist/src/presentation/web/app/actions/deploy-feature.d.ts +1 -1
  44. package/dist/src/presentation/web/app/actions/deploy-feature.d.ts.map +1 -1
  45. package/dist/src/presentation/web/app/actions/deploy-feature.js +4 -33
  46. package/dist/src/presentation/web/app/actions/deploy-repository.d.ts +1 -1
  47. package/dist/src/presentation/web/app/actions/deploy-repository.d.ts.map +1 -1
  48. package/dist/src/presentation/web/app/actions/deploy-repository.js +4 -24
  49. package/dist/src/presentation/web/app/actions/get-deployment-status.d.ts.map +1 -1
  50. package/dist/src/presentation/web/app/actions/get-deployment-status.js +2 -5
  51. package/dist/src/presentation/web/app/actions/list-deployments.d.ts +3 -0
  52. package/dist/src/presentation/web/app/actions/list-deployments.d.ts.map +1 -0
  53. package/dist/src/presentation/web/app/actions/list-deployments.js +6 -0
  54. package/dist/src/presentation/web/app/actions/stop-deployment.d.ts.map +1 -1
  55. package/dist/src/presentation/web/app/actions/stop-deployment.js +2 -5
  56. package/dist/src/presentation/web/app/api/graph-data/route.d.ts +1 -0
  57. package/dist/src/presentation/web/app/api/graph-data/route.d.ts.map +1 -1
  58. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  59. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +7 -2
  60. package/dist/src/presentation/web/hooks/deployment-status-provider.d.ts +41 -0
  61. package/dist/src/presentation/web/hooks/deployment-status-provider.d.ts.map +1 -0
  62. package/dist/src/presentation/web/hooks/deployment-status-provider.js +205 -0
  63. package/dist/src/presentation/web/hooks/deployment-status-store.d.ts +42 -0
  64. package/dist/src/presentation/web/hooks/deployment-status-store.d.ts.map +1 -0
  65. package/dist/src/presentation/web/hooks/deployment-status-store.js +99 -0
  66. package/dist/src/presentation/web/hooks/use-deploy-action.d.ts +2 -6
  67. package/dist/src/presentation/web/hooks/use-deploy-action.d.ts.map +1 -1
  68. package/dist/src/presentation/web/hooks/use-deploy-action.js +42 -159
  69. package/dist/tsconfig.build.tsbuildinfo +1 -1
  70. package/package.json +1 -1
  71. package/web/.next/BUILD_ID +1 -1
  72. package/web/.next/build-manifest.json +2 -2
  73. package/web/.next/fallback-build-manifest.json +2 -2
  74. package/web/.next/prerender-manifest.json +3 -3
  75. package/web/.next/required-server-files.js +2 -2
  76. package/web/.next/required-server-files.json +2 -2
  77. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +30 -30
  78. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +4 -4
  79. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  80. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  81. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +28 -28
  82. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +4 -4
  83. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  84. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  85. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +31 -31
  86. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +4 -4
  87. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  88. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  89. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +39 -39
  90. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +4 -4
  91. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  92. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  93. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +39 -39
  94. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +4 -4
  95. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  96. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  97. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +29 -29
  98. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +4 -4
  99. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  100. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  101. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +29 -29
  102. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +4 -4
  103. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  104. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  105. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +28 -28
  106. package/web/.next/server/app/(dashboard)/chat/page.js +4 -4
  107. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  108. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  109. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +31 -31
  110. package/web/.next/server/app/(dashboard)/create/page.js +4 -4
  111. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  112. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  113. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +39 -39
  114. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +4 -4
  115. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  116. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  117. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +39 -39
  118. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +4 -4
  119. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  120. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  121. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +28 -28
  122. package/web/.next/server/app/(dashboard)/page.js +4 -4
  123. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  124. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  125. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +29 -29
  126. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +4 -4
  127. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  128. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  129. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +29 -29
  130. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +4 -4
  131. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  132. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  133. package/web/.next/server/app/_global-error.html +2 -2
  134. package/web/.next/server/app/_global-error.rsc +1 -1
  135. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  136. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  137. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  138. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  139. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  140. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  141. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  142. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  143. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  144. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  145. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  146. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  147. package/web/.next/server/app/features/page/server-reference-manifest.json +6 -6
  148. package/web/.next/server/app/features/page.js.nft.json +1 -1
  149. package/web/.next/server/app/features/page_client-reference-manifest.js +1 -1
  150. package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
  151. package/web/.next/server/app/settings/page.js +1 -1
  152. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  153. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  154. package/web/.next/server/app/skills/page/server-reference-manifest.json +13 -13
  155. package/web/.next/server/app/skills/page.js +2 -3
  156. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  157. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  158. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  159. package/web/.next/server/app/tools/page.js +1 -2
  160. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  161. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  162. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  163. package/web/.next/server/app/version/page.js.nft.json +1 -1
  164. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  165. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  166. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  167. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  168. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_bdff55d6.js +3 -0
  169. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_bdff55d6.js.map +1 -0
  170. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_6aa77d75.js +3 -0
  171. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_6aa77d75.js.map +1 -0
  172. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_24adb073.js +3 -0
  173. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_24adb073.js.map +1 -0
  174. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  175. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  176. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
  177. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/{[root-of-the-server]__69dd3217._.js → [root-of-the-server]__16c1388b._.js} +2 -2
  179. package/web/.next/server/chunks/ssr/{[root-of-the-server]__69dd3217._.js.map → [root-of-the-server]__16c1388b._.js.map} +1 -1
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
  182. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  183. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +1 -1
  184. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +1 -1
  185. package/web/.next/server/chunks/ssr/[root-of-the-server]__75070d2e._.js +3 -0
  186. package/web/.next/server/chunks/ssr/[root-of-the-server]__75070d2e._.js.map +1 -0
  187. package/web/.next/server/chunks/ssr/{_f8c55130._.js → [root-of-the-server]__7c634c0f._.js} +3 -3
  188. package/web/.next/server/chunks/ssr/[root-of-the-server]__7c634c0f._.js.map +1 -0
  189. package/web/.next/server/chunks/ssr/{[root-of-the-server]__1cd4327c._.js → [root-of-the-server]__8f02b364._.js} +3 -3
  190. package/web/.next/server/chunks/ssr/[root-of-the-server]__8f02b364._.js.map +1 -0
  191. package/web/.next/server/chunks/ssr/[root-of-the-server]__9dde817e._.js +3 -0
  192. package/web/.next/server/chunks/ssr/[root-of-the-server]__9dde817e._.js.map +1 -0
  193. package/web/.next/server/chunks/ssr/[root-of-the-server]__a00db173._.js +3 -0
  194. package/web/.next/server/chunks/ssr/[root-of-the-server]__a00db173._.js.map +1 -0
  195. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
  196. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
  197. package/web/.next/server/chunks/ssr/[root-of-the-server]__cf751517._.js +4 -0
  198. package/web/.next/server/chunks/ssr/[root-of-the-server]__cf751517._.js.map +1 -0
  199. package/web/.next/server/chunks/ssr/[root-of-the-server]__e0592c69._.js +3 -0
  200. package/web/.next/server/chunks/ssr/{[root-of-the-server]__4ed9b909._.js.map → [root-of-the-server]__e0592c69._.js.map} +1 -1
  201. package/web/.next/server/chunks/ssr/[root-of-the-server]__e5f31e9a._.js +3 -0
  202. package/web/.next/server/chunks/ssr/[root-of-the-server]__e5f31e9a._.js.map +1 -0
  203. package/web/.next/server/chunks/ssr/_15f6bbd4._.js +3 -0
  204. package/web/.next/server/chunks/ssr/{_79a4a04a._.js.map → _15f6bbd4._.js.map} +1 -1
  205. package/web/.next/server/chunks/ssr/{_16eb4fec._.js → _396a6887._.js} +2 -2
  206. package/web/.next/server/chunks/ssr/_396a6887._.js.map +1 -0
  207. package/web/.next/server/chunks/ssr/_45496654._.js +1 -1
  208. package/web/.next/server/chunks/ssr/_45496654._.js.map +1 -1
  209. package/web/.next/server/chunks/ssr/_496c9117._.js +1 -1
  210. package/web/.next/server/chunks/ssr/_496c9117._.js.map +1 -1
  211. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  212. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  213. package/web/.next/server/chunks/ssr/{_a1cc5e68._.js → _5889596f._.js} +2 -2
  214. package/web/.next/server/chunks/ssr/{_a1cc5e68._.js.map → _5889596f._.js.map} +1 -1
  215. package/web/.next/server/chunks/ssr/_6abfa39e._.js +1 -1
  216. package/web/.next/server/chunks/ssr/_6abfa39e._.js.map +1 -1
  217. package/web/.next/server/chunks/ssr/{_d9c0a97a._.js → _74a1a173._.js} +2 -2
  218. package/web/.next/server/chunks/ssr/{_d9c0a97a._.js.map → _74a1a173._.js.map} +1 -1
  219. package/web/.next/server/chunks/ssr/{_a2e317b3._.js → _7d50fed0._.js} +2 -2
  220. package/web/.next/server/chunks/ssr/{_a2e317b3._.js.map → _7d50fed0._.js.map} +1 -1
  221. package/web/.next/server/chunks/ssr/_9bbdd461._.js +4 -0
  222. package/web/.next/server/chunks/ssr/_9bbdd461._.js.map +1 -0
  223. package/web/.next/server/chunks/ssr/_bcd239dd._.js +3 -0
  224. package/web/.next/server/chunks/ssr/_bcd239dd._.js.map +1 -0
  225. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  226. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  227. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
  228. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
  229. package/web/.next/server/chunks/ssr/src_presentation_web_0338c789._.js +3 -0
  230. package/web/.next/server/chunks/ssr/src_presentation_web_0338c789._.js.map +1 -0
  231. package/web/.next/server/chunks/ssr/src_presentation_web_071f1e80._.js +5 -0
  232. package/web/.next/server/chunks/ssr/src_presentation_web_071f1e80._.js.map +1 -0
  233. package/web/.next/server/chunks/ssr/src_presentation_web_55c1ff7d._.js +3 -0
  234. package/web/.next/server/chunks/ssr/src_presentation_web_55c1ff7d._.js.map +1 -0
  235. package/web/.next/server/chunks/ssr/src_presentation_web_9a543843._.js +3 -0
  236. package/web/.next/server/chunks/ssr/src_presentation_web_9a543843._.js.map +1 -0
  237. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ad14a90f.js +3 -0
  238. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ad14a90f.js.map +1 -0
  239. package/web/.next/server/chunks/ssr/src_presentation_web_bade80bd._.js +3 -0
  240. package/web/.next/server/chunks/ssr/src_presentation_web_bade80bd._.js.map +1 -0
  241. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
  242. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
  243. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +1 -1
  244. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -1
  245. package/web/.next/server/chunks/ssr/src_presentation_web_d5838156._.js +3 -0
  246. package/web/.next/server/chunks/ssr/src_presentation_web_d5838156._.js.map +1 -0
  247. package/web/.next/server/chunks/ssr/src_presentation_web_dc28bc60._.js +5 -0
  248. package/web/.next/server/chunks/ssr/src_presentation_web_dc28bc60._.js.map +1 -0
  249. package/web/.next/server/chunks/ssr/src_presentation_web_dcb020e3._.js +3 -0
  250. package/web/.next/server/chunks/ssr/src_presentation_web_dcb020e3._.js.map +1 -0
  251. package/web/.next/server/pages/500.html +2 -2
  252. package/web/.next/server/server-reference-manifest.js +1 -1
  253. package/web/.next/server/server-reference-manifest.json +51 -51
  254. package/web/.next/static/chunks/{f7741bf45b42ac62.js → 200e07d995bd9a42.js} +1 -1
  255. package/web/.next/static/chunks/22e3a3738308da2e.js +1 -0
  256. package/web/.next/static/chunks/{bbc95353509ede89.js → 25d3c4d18b8aecff.js} +1 -1
  257. package/web/.next/static/chunks/34444901ca3a1c3b.js +1 -0
  258. package/web/.next/static/chunks/{0ff97e3b2c05f514.js → 3cf86457869c47bc.js} +1 -1
  259. package/web/.next/static/chunks/{44dc686d971c7513.js → 55060446f5490f20.js} +3 -3
  260. package/web/.next/static/chunks/59bff7b33ebe5f68.js +1 -0
  261. package/web/.next/static/chunks/{f2ec6318c5ff73b8.js → 5a2bdbc57ed1368e.js} +1 -1
  262. package/web/.next/static/chunks/{b567f6c06cc7013a.js → 981c6f3f1db99b4e.js} +1 -1
  263. package/web/.next/static/chunks/{46e2693dbc9262fd.js → c94a6a3d54dd4997.js} +2 -2
  264. package/web/.next/static/chunks/{374e00e5b4ab142e.js → d04d868f0971941d.js} +1 -1
  265. package/web/.next/static/chunks/{0b6c8ca8403db859.js → d26d0a7bc1a9b5a4.js} +1 -1
  266. package/web/.next/static/chunks/e7502fb670f32235.js +1 -0
  267. package/web/.next/static/chunks/{8ecdaada8068211c.js → f5c61237675acc89.js} +1 -1
  268. package/web/.next/static/chunks/{27b1e99ab97bdf52.js → fb7211d94190d010.js} +3 -3
  269. package/dist/src/presentation/web/lib/is-same-shep-instance.d.ts +0 -7
  270. package/dist/src/presentation/web/lib/is-same-shep-instance.d.ts.map +0 -1
  271. package/dist/src/presentation/web/lib/is-same-shep-instance.js +0 -18
  272. package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js.map +0 -1
  273. package/web/.next/server/chunks/ssr/[root-of-the-server]__46b10380._.js +0 -3
  274. package/web/.next/server/chunks/ssr/[root-of-the-server]__46b10380._.js.map +0 -1
  275. package/web/.next/server/chunks/ssr/[root-of-the-server]__4ed9b909._.js +0 -3
  276. package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js +0 -4
  277. package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js.map +0 -1
  278. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b512877._.js +0 -3
  279. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b512877._.js.map +0 -1
  280. package/web/.next/server/chunks/ssr/[root-of-the-server]__990dba2d._.js +0 -3
  281. package/web/.next/server/chunks/ssr/[root-of-the-server]__990dba2d._.js.map +0 -1
  282. package/web/.next/server/chunks/ssr/[root-of-the-server]__cc9c7bbb._.js +0 -3
  283. package/web/.next/server/chunks/ssr/[root-of-the-server]__cc9c7bbb._.js.map +0 -1
  284. package/web/.next/server/chunks/ssr/_05c23ad9._.js +0 -3
  285. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +0 -1
  286. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +0 -1
  287. package/web/.next/server/chunks/ssr/_79a4a04a._.js +0 -3
  288. package/web/.next/server/chunks/ssr/_f8c55130._.js.map +0 -1
  289. package/web/.next/server/chunks/ssr/src_presentation_web_06109d28._.js +0 -5
  290. package/web/.next/server/chunks/ssr/src_presentation_web_06109d28._.js.map +0 -1
  291. package/web/.next/server/chunks/ssr/src_presentation_web_0bca70f8._.js +0 -3
  292. package/web/.next/server/chunks/ssr/src_presentation_web_0bca70f8._.js.map +0 -1
  293. package/web/.next/server/chunks/ssr/src_presentation_web_367cdbe0._.js +0 -3
  294. package/web/.next/server/chunks/ssr/src_presentation_web_367cdbe0._.js.map +0 -1
  295. package/web/.next/server/chunks/ssr/src_presentation_web_57fed7fd._.js +0 -3
  296. package/web/.next/server/chunks/ssr/src_presentation_web_57fed7fd._.js.map +0 -1
  297. package/web/.next/server/chunks/ssr/src_presentation_web_7f567f6d._.js +0 -3
  298. package/web/.next/server/chunks/ssr/src_presentation_web_7f567f6d._.js.map +0 -1
  299. package/web/.next/server/chunks/ssr/src_presentation_web_972f58d5._.js +0 -3
  300. package/web/.next/server/chunks/ssr/src_presentation_web_972f58d5._.js.map +0 -1
  301. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js +0 -3
  302. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js.map +0 -1
  303. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js +0 -3
  304. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js.map +0 -1
  305. package/web/.next/server/chunks/ssr/src_presentation_web_a71b18a2._.js +0 -3
  306. package/web/.next/server/chunks/ssr/src_presentation_web_a71b18a2._.js.map +0 -1
  307. package/web/.next/server/chunks/ssr/src_presentation_web_bebe675e._.js +0 -3
  308. package/web/.next/server/chunks/ssr/src_presentation_web_bebe675e._.js.map +0 -1
  309. package/web/.next/server/chunks/ssr/src_presentation_web_c93e8bc6._.js +0 -3
  310. package/web/.next/server/chunks/ssr/src_presentation_web_c93e8bc6._.js.map +0 -1
  311. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +0 -3
  312. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +0 -1
  313. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +0 -3
  314. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +0 -1
  315. package/web/.next/server/chunks/ssr/src_presentation_web_e729f44a._.js +0 -5
  316. package/web/.next/server/chunks/ssr/src_presentation_web_e729f44a._.js.map +0 -1
  317. package/web/.next/static/chunks/28ad440cbb92bebe.js +0 -1
  318. package/web/.next/static/chunks/2ce798babf8adbc5.js +0 -1
  319. package/web/.next/static/chunks/64a765a6eec07603.js +0 -1
  320. package/web/.next/static/chunks/b2c52514837b4fc4.js +0 -1
  321. /package/web/.next/static/{d9JsHxuahs7UrJKwH-FGH → mLJ1Qa4FUFmmZm0crRH2U}/_buildManifest.js +0 -0
  322. /package/web/.next/static/{d9JsHxuahs7UrJKwH-FGH → mLJ1Qa4FUFmmZm0crRH2U}/_clientMiddlewareManifest.json +0 -0
  323. /package/web/.next/static/{d9JsHxuahs7UrJKwH-FGH → mLJ1Qa4FUFmmZm0crRH2U}/_ssgManifest.js +0 -0
@@ -322,6 +322,62 @@ export class DeploymentService {
322
322
  log.debug(`getStatus("${targetId}") — no deployment found`);
323
323
  return null;
324
324
  }
325
+ /**
326
+ * List all tracked deployments with live processes.
327
+ *
328
+ * Merges in-memory entries with any DB rows not yet re-adopted. Any
329
+ * dead processes encountered are cleaned up (both in-memory and DB).
330
+ */
331
+ listAll() {
332
+ const entries = [];
333
+ const seen = new Set();
334
+ // 1) In-memory entries (validated for liveness)
335
+ for (const [targetId, entry] of this.deployments) {
336
+ if (!this.deps.isAlive(entry.pid)) {
337
+ log.info(`listAll — pid=${entry.pid} for "${targetId}" is dead, cleaning up`);
338
+ this.deployments.delete(targetId);
339
+ this.dbDelete(targetId);
340
+ continue;
341
+ }
342
+ seen.add(targetId);
343
+ entries.push({
344
+ targetId,
345
+ targetType: entry.targetType,
346
+ state: entry.state,
347
+ url: entry.url,
348
+ });
349
+ }
350
+ // 2) DB rows not yet in memory — re-adopt live ones, drop dead
351
+ const rows = this.dbFindAll();
352
+ for (const row of rows) {
353
+ if (seen.has(row.target_id))
354
+ continue;
355
+ if (!this.deps.isAlive(row.pid)) {
356
+ this.dbDelete(row.target_id);
357
+ continue;
358
+ }
359
+ const recovered = {
360
+ pid: row.pid,
361
+ child: null,
362
+ state: row.state,
363
+ url: row.url,
364
+ targetId: row.target_id,
365
+ targetPath: row.target_path,
366
+ targetType: row.target_type,
367
+ stdoutBuffer: '',
368
+ stderrBuffer: '',
369
+ logs: new LogRingBuffer(),
370
+ };
371
+ this.deployments.set(row.target_id, recovered);
372
+ entries.push({
373
+ targetId: row.target_id,
374
+ targetType: row.target_type,
375
+ state: recovered.state,
376
+ url: recovered.url,
377
+ });
378
+ }
379
+ return entries;
380
+ }
325
381
  /**
326
382
  * Stop a deployment gracefully: SIGTERM → poll → SIGKILL.
327
383
  */
@@ -463,6 +519,16 @@ export class DeploymentService {
463
519
  return null;
464
520
  }
465
521
  }
522
+ dbFindAll() {
523
+ if (!this.db)
524
+ return [];
525
+ try {
526
+ return this.db.prepare('SELECT * FROM dev_servers').all();
527
+ }
528
+ catch {
529
+ return [];
530
+ }
531
+ }
466
532
  // ─── Process helpers ────────────────────────────────────────────────
467
533
  killProcess(entry) {
468
534
  try {
@@ -6,5 +6,6 @@
6
6
  import type { IFileSystemService } from '../../application/ports/output/services/file-system-service.interface.js';
7
7
  export declare class FileSystemService implements IFileSystemService {
8
8
  removeDirectory(dirPath: string): Promise<void>;
9
+ pathExists(path: string): boolean;
9
10
  }
10
11
  //# sourceMappingURL=file-system.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-system.service.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/services/file-system.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0EAA0E,CAAC;AAEnH,qBACa,iBAAkB,YAAW,kBAAkB;IACpD,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGtD"}
1
+ {"version":3,"file":"file-system.service.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/services/file-system.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0EAA0E,CAAC;AAEnH,qBACa,iBAAkB,YAAW,kBAAkB;IACpD,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAGlC"}
@@ -9,12 +9,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
9
9
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
10
10
  return c > 3 && r && Object.defineProperty(target, key, r), r;
11
11
  };
12
+ import { existsSync } from 'node:fs';
12
13
  import { rm } from 'node:fs/promises';
13
14
  import { injectable } from 'tsyringe';
14
15
  let FileSystemService = class FileSystemService {
15
16
  async removeDirectory(dirPath) {
16
17
  await rm(dirPath, { recursive: true, force: true });
17
18
  }
19
+ pathExists(path) {
20
+ return existsSync(path);
21
+ }
18
22
  };
19
23
  FileSystemService = __decorate([
20
24
  injectable()
@@ -6,7 +6,7 @@
6
6
  * PR creation paths (agent-driven, fork-and-PR, etc.).
7
7
  */
8
8
  /** The branding line to append to PR bodies. */
9
- export declare const PR_BRANDING = "Built with Shep \uD83D\uDC11 [Shep Bot](https://github.com/shep-ai/shep)";
9
+ export declare const PR_BRANDING = "[\uD83D\uDC11](https://github.com/shep-ai/shep) Built with [Shep.bot](https://shep.bot)";
10
10
  /**
11
11
  * Ensure a PR body carries the correct Shep branding.
12
12
  *
@@ -1 +1 @@
1
- {"version":3,"file":"pr-branding.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/pr-branding.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gDAAgD;AAChD,eAAO,MAAM,WAAW,6EACoD,CAAC;AAS7E;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAapD"}
1
+ {"version":3,"file":"pr-branding.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/pr-branding.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gDAAgD;AAChD,eAAO,MAAM,WAAW,4FACyD,CAAC;AASlF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAapD"}
@@ -6,7 +6,7 @@
6
6
  * PR creation paths (agent-driven, fork-and-PR, etc.).
7
7
  */
8
8
  /** The branding line to append to PR bodies. */
9
- export const PR_BRANDING = 'Built with Shep \uD83D\uDC11 [Shep Bot](https://github.com/shep-ai/shep)';
9
+ export const PR_BRANDING = '[🐑](https://github.com/shep-ai/shep) Built with [Shep.bot](https://shep.bot)';
10
10
  /**
11
11
  * Pattern matching common AI-tool attribution footers that should be
12
12
  * replaced (e.g. "Generated with Claude Code", "Co-Authored-By: Claude").
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Shep Instance Service
3
+ *
4
+ * Infrastructure implementation of IShepInstanceService.
5
+ * Detects whether a target path is the same directory as the running
6
+ * Shep instance by canonicalizing both paths with realpathSync and
7
+ * comparing them after normalizing separators to forward slashes.
8
+ *
9
+ * The running instance path is read from `SHEP_INSTANCE_PATH` (or the
10
+ * legacy `NEXT_PUBLIC_SHEP_INSTANCE_PATH`) and falls back to `process.cwd()`.
11
+ */
12
+ import type { IShepInstanceService } from '../../application/ports/output/services/shep-instance-service.interface.js';
13
+ export declare class ShepInstanceService implements IShepInstanceService {
14
+ isSameInstance(targetPath: string): boolean;
15
+ }
16
+ //# sourceMappingURL=shep-instance.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shep-instance.service.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/services/shep-instance.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4EAA4E,CAAC;AAEvH,qBACa,mBAAoB,YAAW,oBAAoB;IAC9D,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;CAc5C"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Shep Instance Service
3
+ *
4
+ * Infrastructure implementation of IShepInstanceService.
5
+ * Detects whether a target path is the same directory as the running
6
+ * Shep instance by canonicalizing both paths with realpathSync and
7
+ * comparing them after normalizing separators to forward slashes.
8
+ *
9
+ * The running instance path is read from `SHEP_INSTANCE_PATH` (or the
10
+ * legacy `NEXT_PUBLIC_SHEP_INSTANCE_PATH`) and falls back to `process.cwd()`.
11
+ */
12
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
13
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
15
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
16
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
17
+ };
18
+ import { realpathSync } from 'node:fs';
19
+ import { resolve } from 'node:path';
20
+ import { injectable } from 'tsyringe';
21
+ let ShepInstanceService = class ShepInstanceService {
22
+ isSameInstance(targetPath) {
23
+ const instancePath = process.env.SHEP_INSTANCE_PATH ?? process.env.NEXT_PUBLIC_SHEP_INSTANCE_PATH ?? process.cwd();
24
+ try {
25
+ const normalizedTarget = realpathSync(resolve(targetPath)).replace(/\\/g, '/');
26
+ const normalizedInstance = realpathSync(resolve(instancePath)).replace(/\\/g, '/');
27
+ return normalizedTarget === normalizedInstance;
28
+ }
29
+ catch {
30
+ // Path does not exist or is not accessible — assume "not same instance"
31
+ // so the caller can surface a more specific "path does not exist" error.
32
+ return false;
33
+ }
34
+ }
35
+ };
36
+ ShepInstanceService = __decorate([
37
+ injectable()
38
+ ], ShepInstanceService);
39
+ export { ShepInstanceService };
@@ -1,3 +1,4 @@
1
+ import type { DeploymentStatusEntry } from '../../../../../packages/core/src/application/ports/output/services/deployment-service.interface.js';
1
2
  import type { CanvasNodeType } from '../../components/features/features-canvas/index.js';
2
3
  import type { Edge } from '@xyflow/react';
3
4
  export interface RepoGitInfo {
@@ -17,5 +18,6 @@ export type GitInfoResult = {
17
18
  export declare function getGraphData(): Promise<{
18
19
  nodes: CanvasNodeType[];
19
20
  edges: Edge[];
21
+ deployments: DeploymentStatusEntry[];
20
22
  }>;
21
23
  //# sourceMappingURL=get-graph-data.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAI1C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAiFD,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC;AA6B7B,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CA+ExF"}
1
+ {"version":3,"file":"get-graph-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/get-graph-data.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6EAA6E,CAAC;AAOzH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAI1C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAiFD,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC;AA6B7B,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAC5C,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,WAAW,EAAE,qBAAqB,EAAE,CAAC;CACtC,CAAC,CAqED"}
@@ -143,28 +143,18 @@ export async function getGraphData() {
143
143
  repoGitInfo: repoGitInfoMap,
144
144
  repoGitStatus: repoGitStatusMap,
145
145
  });
146
- // Enrich feature nodes with deployment status
147
- let deploymentService = null;
146
+ // Load all live deployments via the use case. The client-side
147
+ // DeploymentStatusProvider hydrates from this list so node/drawer state
148
+ // survives a page refresh and stays in sync across components.
149
+ let deployments = [];
148
150
  try {
149
- deploymentService = resolve('IDeploymentService');
151
+ const listDeployments = resolve('ListDeploymentsUseCase');
152
+ deployments = await listDeployments.execute();
150
153
  }
151
154
  catch {
152
- // Deployment service may not be registered — skip enrichment
153
- }
154
- if (deploymentService) {
155
- for (const node of nodes) {
156
- if (node.type !== 'featureNode')
157
- continue;
158
- const data = node.data;
159
- const status = deploymentService.getStatus(data.featureId);
160
- if (status && status.state !== 'Stopped') {
161
- data.deployment = {
162
- status: status.state,
163
- ...(status.url && { url: status.url }),
164
- };
165
- }
166
- }
155
+ // Use case not registered — leave deployments empty
167
156
  }
168
157
  const { dir } = getLanguagePreference();
169
- return layoutWithDagre(nodes, edges, getCanvasLayoutDefaults(dir));
158
+ const laidOut = layoutWithDagre(nodes, edges, getCanvasLayoutDefaults(dir));
159
+ return { ...laidOut, deployments };
170
160
  }
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/layout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,uFAAuF;AACvF,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,wBAA8B,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,oBAAoB,oDASvF"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/(dashboard)/layout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,uFAAuF;AACvF,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,wBAA8B,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,oBAAoB,oDAWvF"}
@@ -1,9 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { ControlCenter } from '../../components/features/control-center/index.js';
3
+ import { DeploymentStatusProvider } from '../../hooks/deployment-status-provider.js';
3
4
  import { getGraphData } from './get-graph-data.js';
4
5
  /** Skip static pre-rendering since we need runtime DI container and server context. */
5
6
  export const dynamic = 'force-dynamic';
6
7
  export default async function DashboardLayout({ children, drawer }) {
7
- const { nodes, edges } = await getGraphData();
8
- return (_jsxs("div", { className: "h-screen w-full", children: [_jsx(ControlCenter, { initialNodes: nodes, initialEdges: edges, drawer: drawer }), children] }));
8
+ const { nodes, edges, deployments } = await getGraphData();
9
+ return (_jsx("div", { className: "h-screen w-full", children: _jsxs(DeploymentStatusProvider, { initialDeployments: deployments, children: [_jsx(ControlCenter, { initialNodes: nodes, initialEdges: edges, drawer: drawer }), children] }) }));
9
10
  }
@@ -1,4 +1,4 @@
1
- import { DeploymentState } from '../../../../../packages/core/src/domain/generated/output.js';
1
+ import type { DeploymentState } from '../../../../../packages/core/src/domain/generated/output.js';
2
2
  export declare function deployFeature(featureId: string): Promise<{
3
3
  success: boolean;
4
4
  error?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"deploy-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/deploy-feature.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAKvE,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC,CAgDxE"}
1
+ {"version":3,"file":"deploy-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/deploy-feature.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAI5E,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC,CAaxE"}
@@ -1,43 +1,14 @@
1
1
  'use server';
2
- import { existsSync } from 'node:fs';
3
2
  import { resolve } from '../../lib/server-container.js';
4
3
  import { createDeploymentLogger } from '../../../../../packages/core/src/infrastructure/services/deployment/deployment-logger.js';
5
- import { computeWorktreePath } from '../../../../../packages/core/src/infrastructure/services/ide-launchers/compute-worktree-path.js';
6
- import { DeploymentState } from '../../../../../packages/core/src/domain/generated/output.js';
7
- import { isSameShepInstance } from '../../lib/is-same-shep-instance.js';
8
4
  const log = createDeploymentLogger('[deployFeature]');
9
5
  export async function deployFeature(featureId) {
10
6
  log.info(`called — featureId="${featureId}"`);
11
- if (!featureId?.trim()) {
12
- log.warn('rejected — featureId is empty');
13
- return { success: false, error: 'featureId is required' };
14
- }
15
7
  try {
16
- const featureRepo = resolve('IFeatureRepository');
17
- const feature = await featureRepo.findById(featureId);
18
- if (!feature) {
19
- log.warn(`feature not found in repository: "${featureId}"`);
20
- return { success: false, error: `Feature not found: ${featureId}` };
21
- }
22
- log.info(`feature found — repositoryPath="${feature.repositoryPath}", branch="${feature.branch}"`);
23
- const worktreePath = computeWorktreePath(feature.repositoryPath, feature.branch);
24
- log.info(`computed worktreePath="${worktreePath}"`);
25
- if (!existsSync(worktreePath)) {
26
- log.warn(`worktree path does not exist on disk: "${worktreePath}"`);
27
- return { success: false, error: `Worktree path does not exist: ${worktreePath}` };
28
- }
29
- if (isSameShepInstance(feature.repositoryPath)) {
30
- log.warn('rejected — feature belongs to the running shep instance');
31
- return {
32
- success: false,
33
- error: 'Cannot start a dev server for features of the repository Shep is running from',
34
- };
35
- }
36
- log.info('worktree path exists, calling deploymentService.start()');
37
- const deploymentService = resolve('IDeploymentService');
38
- deploymentService.start(featureId, worktreePath, 'feature');
39
- log.info('start() returned successfully — state=Booting');
40
- return { success: true, state: DeploymentState.Booting };
8
+ const useCase = resolve('StartFeatureDeploymentUseCase');
9
+ const status = await useCase.execute(featureId);
10
+ log.info(`start succeeded — state=${status.state}`);
11
+ return { success: true, state: status.state };
41
12
  }
42
13
  catch (error) {
43
14
  const message = error instanceof Error ? error.message : 'Failed to deploy feature';
@@ -1,4 +1,4 @@
1
- import { DeploymentState } from '../../../../../packages/core/src/domain/generated/output.js';
1
+ import type { DeploymentState } from '../../../../../packages/core/src/domain/generated/output.js';
2
2
  export declare function deployRepository(repositoryPath: string): Promise<{
3
3
  success: boolean;
4
4
  error?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"deploy-repository.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/deploy-repository.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAKvE,wBAAsB,gBAAgB,CACpC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC,CAiCxE"}
1
+ {"version":3,"file":"deploy-repository.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/deploy-repository.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAI5E,wBAAsB,gBAAgB,CACpC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC,CAaxE"}
@@ -1,34 +1,14 @@
1
1
  'use server';
2
- import { existsSync } from 'node:fs';
3
- import { isAbsolute } from 'node:path';
4
2
  import { resolve } from '../../lib/server-container.js';
5
3
  import { createDeploymentLogger } from '../../../../../packages/core/src/infrastructure/services/deployment/deployment-logger.js';
6
- import { DeploymentState } from '../../../../../packages/core/src/domain/generated/output.js';
7
- import { isSameShepInstance } from '../../lib/is-same-shep-instance.js';
8
4
  const log = createDeploymentLogger('[deployRepository]');
9
5
  export async function deployRepository(repositoryPath) {
10
6
  log.info(`called — repositoryPath="${repositoryPath}"`);
11
- if (!repositoryPath || !isAbsolute(repositoryPath)) {
12
- log.warn('rejected — not an absolute path');
13
- return { success: false, error: 'repositoryPath must be an absolute path' };
14
- }
15
7
  try {
16
- if (!existsSync(repositoryPath)) {
17
- log.warn(`directory does not exist: "${repositoryPath}"`);
18
- return { success: false, error: `Directory does not exist: ${repositoryPath}` };
19
- }
20
- if (isSameShepInstance(repositoryPath)) {
21
- log.warn('rejected — target is the running shep instance');
22
- return {
23
- success: false,
24
- error: 'Cannot start a dev server for the repository Shep is running from',
25
- };
26
- }
27
- log.info('directory exists, calling deploymentService.start()');
28
- const deploymentService = resolve('IDeploymentService');
29
- deploymentService.start(repositoryPath, repositoryPath, 'repository');
30
- log.info('start() returned successfully — state=Booting');
31
- return { success: true, state: DeploymentState.Booting };
8
+ const useCase = resolve('StartRepositoryDeploymentUseCase');
9
+ const status = await useCase.execute(repositoryPath);
10
+ log.info(`start succeeded state=${status.state}`);
11
+ return { success: true, state: status.state };
32
12
  }
33
13
  catch (error) {
34
14
  const message = error instanceof Error ? error.message : 'Failed to deploy repository';
@@ -1 +1 @@
1
- {"version":3,"file":"get-deployment-status.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-deployment-status.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,6EAA6E,CAAC;AAErF,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAO5F"}
1
+ {"version":3,"file":"get-deployment-status.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-deployment-status.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6EAA6E,CAAC;AAEpH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAG5F"}
@@ -1,9 +1,6 @@
1
1
  'use server';
2
2
  import { resolve } from '../../lib/server-container.js';
3
3
  export async function getDeploymentStatus(targetId) {
4
- if (!targetId?.trim()) {
5
- return null;
6
- }
7
- const deploymentService = resolve('IDeploymentService');
8
- return deploymentService.getStatus(targetId);
4
+ const useCase = resolve('GetDeploymentStatusUseCase');
5
+ return useCase.execute(targetId);
9
6
  }
@@ -0,0 +1,3 @@
1
+ import type { DeploymentStatusEntry } from '../../../../../packages/core/src/application/ports/output/services/deployment-service.interface.js';
2
+ export declare function listDeployments(): Promise<DeploymentStatusEntry[]>;
3
+ //# sourceMappingURL=list-deployments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-deployments.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/list-deployments.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6EAA6E,CAAC;AAEzH,wBAAsB,eAAe,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAGxE"}
@@ -0,0 +1,6 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ export async function listDeployments() {
4
+ const useCase = resolve('ListDeploymentsUseCase');
5
+ return useCase.execute();
6
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"stop-deployment.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/stop-deployment.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAc/C"}
1
+ {"version":3,"file":"stop-deployment.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/stop-deployment.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAS/C"}
@@ -1,12 +1,9 @@
1
1
  'use server';
2
2
  import { resolve } from '../../lib/server-container.js';
3
3
  export async function stopDeployment(targetId) {
4
- if (!targetId?.trim()) {
5
- return { success: false, error: 'targetId is required' };
6
- }
7
4
  try {
8
- const deploymentService = resolve('IDeploymentService');
9
- await deploymentService.stop(targetId);
5
+ const useCase = resolve('StopDeploymentUseCase');
6
+ await useCase.execute(targetId);
10
7
  return { success: true };
11
8
  }
12
9
  catch (error) {
@@ -10,5 +10,6 @@ export declare const dynamic = "force-dynamic";
10
10
  export declare function GET(): Promise<NextResponse<{
11
11
  nodes: import("../../../components/features/features-canvas/index.js").CanvasNodeType[];
12
12
  edges: import("@xyflow/react").Edge[];
13
+ deployments: import("../../../../../../packages/core/src/application/ports/output/services/deployment-service.interface.js").DeploymentStatusEntry[];
13
14
  }>>;
14
15
  //# sourceMappingURL=route.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/graph-data/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,6EAA6E;AAC7E,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC;;;;;GAKG;AACH,wBAAsB,GAAG;;;IAGxB"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/graph-data/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,6EAA6E;AAC7E,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC;;;;;GAKG;AACH,wBAAsB,GAAG;;;;IAGxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAkBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QACrC,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,EAAE,CACtB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,KACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;IACZ,yDAAyD;IACzD,YAAY,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,wDAAwD;IACxD,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAQD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CAmlBpB"}
1
+ {"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAmBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QACrC,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,EAAE,CACtB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,KACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;IACZ,yDAAyD;IACzD,YAAY,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,wDAAwD;IACxD,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAQD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CA2lBpB"}
@@ -13,6 +13,7 @@ import { addRepository } from '../../../app/actions/add-repository.js';
13
13
  import { deleteRepository } from '../../../app/actions/delete-repository.js';
14
14
  import { getFeatureMetadata } from '../../../app/actions/get-feature-metadata.js';
15
15
  import { useAgentEventsContext } from '../../../hooks/agent-events-provider.js';
16
+ import { useDeploymentStatusContext } from '../../../hooks/deployment-status-provider.js';
16
17
  import { useSoundAction } from '../../../hooks/use-sound-action.js';
17
18
  import { createLogger } from '../../../lib/logger.js';
18
19
  import { mapEventTypeToState, resolveSseEventUpdates, } from '../../common/feature-node/derive-feature-state.js';
@@ -62,6 +63,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
62
63
  // Track previous feature states for fallback notifications
63
64
  const prevFeatureStatesRef = useRef(new Map());
64
65
  const { events } = useAgentEventsContext();
66
+ const { store: deploymentStore } = useDeploymentStatusContext();
65
67
  useEffect(() => {
66
68
  const prevStates = prevFeatureStatesRef.current;
67
69
  for (const node of initialNodes) {
@@ -188,8 +190,11 @@ export function useControlCenterState(initialNodes, initialEdges) {
188
190
  const res = await fetch('/api/graph-data');
189
191
  if (!res.ok)
190
192
  throw new Error(`status ${res.status}`);
191
- const { nodes: freshNodes, edges: freshEdges } = await res.json();
193
+ const { nodes: freshNodes, edges: freshEdges, deployments: freshDeployments, } = await res.json();
192
194
  reconcile(freshNodes, freshEdges);
195
+ if (Array.isArray(freshDeployments)) {
196
+ deploymentStore.hydrate(freshDeployments);
197
+ }
193
198
  }
194
199
  catch {
195
200
  log.warn('poll fetch failed — will retry next interval');
@@ -199,7 +204,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
199
204
  log.debug('polling disabled');
200
205
  clearInterval(timer);
201
206
  };
202
- }, [reconcile, isMutating]);
207
+ }, [reconcile, isMutating, deploymentStore]);
203
208
  // onNodesChange is a no-op: nodes are derived from domain Maps.
204
209
  // Since nodesDraggable=false and elementsSelectable=false, only React Flow's
205
210
  // internal replace/dimensions changes come through — we ignore them all.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * DeploymentStatusProvider
3
+ *
4
+ * Wraps the dashboard with a shared deployment-status store seeded from
5
+ * SSR data (ListDeploymentsUseCase via get-graph-data). All components
6
+ * that call `useDeployAction(targetId)` subscribe to the same store, so
7
+ * the "click Run on node → tab shows URL instantly" bug and the
8
+ * "URL lost after refresh" bug are both resolved by construction.
9
+ *
10
+ * All business logic lives in use cases on the backend. This provider
11
+ * owns only UI state transitions: which entries are hydrated, which are
12
+ * loading, which have errors, and which need polling.
13
+ */
14
+ import { type ReactNode } from 'react';
15
+ import type { DeploymentStatusEntry } from '../../../../packages/core/src/application/ports/output/services/deployment-service.interface.js';
16
+ import { DeploymentStatusStore, type DeploymentEntryState, EMPTY_ENTRY } from './deployment-status-store.js';
17
+ export interface DeployActionInput {
18
+ targetId: string;
19
+ targetType: 'feature' | 'repository';
20
+ repositoryPath: string;
21
+ branch?: string;
22
+ }
23
+ interface DeploymentContextValue {
24
+ store: DeploymentStatusStore;
25
+ deploy: (input: DeployActionInput) => Promise<void>;
26
+ stop: (targetId: string) => Promise<void>;
27
+ ensureHydrated: (targetId: string) => void;
28
+ }
29
+ export declare function DeploymentStatusProvider({ initialDeployments, children, }: {
30
+ initialDeployments: DeploymentStatusEntry[];
31
+ children: ReactNode;
32
+ }): import("react/jsx-runtime").JSX.Element;
33
+ export declare function useDeploymentStatusContext(): DeploymentContextValue;
34
+ /**
35
+ * Non-throwing variant used by presentational hooks (e.g. useDeployAction)
36
+ * that may render inside Storybook or other isolated contexts without
37
+ * a provider. Returns a stub store/actions that do nothing.
38
+ */
39
+ export declare function useDeploymentStatusContextOptional(): DeploymentContextValue;
40
+ export { EMPTY_ENTRY, type DeploymentEntryState };
41
+ //# sourceMappingURL=deployment-status-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment-status-provider.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/deployment-status-provider.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6EAA6E,CAAC;AAOzH,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,WAAW,EACZ,MAAM,2BAA2B,CAAC;AAUnC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,GAAG,YAAY,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,sBAAsB;IAC9B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,MAAM,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAID,wBAAgB,wBAAwB,CAAC,EACvC,kBAAkB,EAClB,QAAQ,GACT,EAAE;IACD,kBAAkB,EAAE,qBAAqB,EAAE,CAAC;IAC5C,QAAQ,EAAE,SAAS,CAAC;CACrB,2CAgKA;AAED,wBAAgB,0BAA0B,IAAI,sBAAsB,CAMnE;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,IAAI,sBAAsB,CAI3E;AAgBD,OAAO,EAAE,WAAW,EAAE,KAAK,oBAAoB,EAAE,CAAC"}