@shepai/cli 1.72.9 → 1.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +20 -1
  2. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +68 -41
  4. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +10 -0
  5. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  6. package/dist/packages/core/src/infrastructure/services/notifications/notification.service.d.ts.map +1 -1
  7. package/dist/packages/core/src/infrastructure/services/notifications/notification.service.js +2 -4
  8. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  9. package/dist/src/presentation/web/app/actions/create-feature.js +20 -2
  10. package/dist/src/presentation/web/app/actions/get-feature-metadata.d.ts +10 -0
  11. package/dist/src/presentation/web/app/actions/get-feature-metadata.d.ts.map +1 -0
  12. package/dist/src/presentation/web/app/actions/get-feature-metadata.js +14 -0
  13. package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
  14. package/dist/src/presentation/web/app/api/agent-events/route.js +15 -0
  15. package/dist/src/presentation/web/app/build-feature-node-data.d.ts.map +1 -1
  16. package/dist/src/presentation/web/app/build-feature-node-data.js +2 -26
  17. package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
  18. package/dist/src/presentation/web/app/build-graph-nodes.js +2 -26
  19. package/dist/src/presentation/web/app/layout.js +1 -1
  20. package/dist/src/presentation/web/components/common/add-repository-button/add-repository-button.d.ts.map +1 -0
  21. package/dist/src/presentation/web/components/common/add-repository-button/index.d.ts +2 -0
  22. package/dist/src/presentation/web/components/common/add-repository-button/index.d.ts.map +1 -0
  23. package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/index.js +0 -1
  24. package/dist/src/presentation/web/components/common/add-repository-button/pick-folder.d.ts.map +1 -0
  25. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
  26. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +13 -18
  27. package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts +2 -0
  28. package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts.map +1 -1
  29. package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.js +11 -11
  30. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  31. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +74 -144
  32. package/dist/src/presentation/web/components/common/control-center-drawer/index.d.ts +0 -1
  33. package/dist/src/presentation/web/components/common/control-center-drawer/index.d.ts.map +1 -1
  34. package/dist/src/presentation/web/components/common/control-center-drawer/index.js +0 -1
  35. package/dist/src/presentation/web/components/common/control-center-drawer/use-artifact-fetch.d.ts +13 -0
  36. package/dist/src/presentation/web/components/common/control-center-drawer/use-artifact-fetch.d.ts.map +1 -0
  37. package/dist/src/presentation/web/components/common/control-center-drawer/use-artifact-fetch.js +46 -0
  38. package/dist/src/presentation/web/components/common/feature-drawer/use-feature-actions.d.ts.map +1 -1
  39. package/dist/src/presentation/web/components/common/feature-drawer/use-feature-actions.js +7 -10
  40. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts +25 -0
  41. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
  42. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +45 -2
  43. package/dist/src/presentation/web/components/common/index.d.ts +2 -3
  44. package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
  45. package/dist/src/presentation/web/components/common/index.js +2 -3
  46. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +1 -1
  47. package/dist/src/presentation/web/components/common/repository-node/use-repository-actions.d.ts.map +1 -1
  48. package/dist/src/presentation/web/components/common/repository-node/use-repository-actions.js +14 -39
  49. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.d.ts +1 -3
  50. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.d.ts.map +1 -1
  51. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.js +3 -7
  52. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.d.ts +0 -1
  53. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.d.ts.map +1 -1
  54. package/dist/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.js +0 -11
  55. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +1 -1
  56. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  57. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +31 -14
  58. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts +0 -11
  59. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
  60. package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +2 -37
  61. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +8 -0
  62. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  63. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +160 -354
  64. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts +2 -10
  65. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  66. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +11 -54
  67. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.d.ts.map +1 -1
  68. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.js +0 -46
  69. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +1 -1
  70. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts +1 -3
  71. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  72. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
  73. package/dist/src/presentation/web/components/ui/alert-dialog.d.ts.map +1 -1
  74. package/dist/src/presentation/web/components/ui/alert-dialog.js +2 -2
  75. package/dist/src/presentation/web/components/ui/dialog.d.ts.map +1 -1
  76. package/dist/src/presentation/web/components/ui/dialog.js +2 -2
  77. package/dist/src/presentation/web/components/ui/scroll-area.js +1 -1
  78. package/dist/src/presentation/web/hooks/agent-events-provider.d.ts.map +1 -1
  79. package/dist/src/presentation/web/hooks/agent-events-provider.js +3 -2
  80. package/dist/src/presentation/web/hooks/use-agent-events.d.ts.map +1 -1
  81. package/dist/src/presentation/web/hooks/use-agent-events.js +18 -5
  82. package/dist/src/presentation/web/hooks/use-deploy-action.d.ts.map +1 -1
  83. package/dist/src/presentation/web/hooks/use-deploy-action.js +8 -3
  84. package/dist/src/presentation/web/hooks/use-graph-state.d.ts +42 -0
  85. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -0
  86. package/dist/src/presentation/web/hooks/use-graph-state.js +257 -0
  87. package/dist/src/presentation/web/hooks/use-notifications.d.ts +1 -5
  88. package/dist/src/presentation/web/hooks/use-notifications.d.ts.map +1 -1
  89. package/dist/src/presentation/web/hooks/use-notifications.js +1 -26
  90. package/dist/src/presentation/web/hooks/use-notifications.stories.d.ts.map +1 -1
  91. package/dist/src/presentation/web/hooks/use-notifications.stories.js +28 -38
  92. package/dist/src/presentation/web/lib/derive-graph.d.ts +52 -0
  93. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -0
  94. package/dist/src/presentation/web/lib/derive-graph.js +126 -0
  95. package/dist/src/presentation/web/lib/layout-with-dagre.d.ts.map +1 -1
  96. package/dist/src/presentation/web/lib/layout-with-dagre.js +1 -2
  97. package/dist/src/presentation/web/lib/logger.d.ts +7 -0
  98. package/dist/src/presentation/web/lib/logger.d.ts.map +1 -0
  99. package/dist/src/presentation/web/lib/logger.js +11 -0
  100. package/dist/tsconfig.build.tsbuildinfo +1 -1
  101. package/package.json +1 -1
  102. package/web/.next/BUILD_ID +1 -1
  103. package/web/.next/build-manifest.json +2 -2
  104. package/web/.next/cache/.previewinfo +1 -1
  105. package/web/.next/cache/.rscinfo +1 -1
  106. package/web/.next/cache/.tsbuildinfo +1 -1
  107. package/web/.next/cache/config.json +3 -3
  108. package/web/.next/fallback-build-manifest.json +2 -2
  109. package/web/.next/prerender-manifest.json +3 -3
  110. package/web/.next/required-server-files.js +1 -1
  111. package/web/.next/required-server-files.json +1 -1
  112. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +34 -34
  113. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +3 -3
  114. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  115. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  116. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +40 -40
  117. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -3
  118. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  119. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  120. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +30 -30
  121. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +3 -3
  122. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  123. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  124. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +34 -34
  125. package/web/.next/server/app/(dashboard)/create/page.js +3 -3
  126. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  127. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  128. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +40 -40
  129. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +3 -3
  130. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  131. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  132. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +30 -30
  133. package/web/.next/server/app/(dashboard)/page.js +3 -3
  134. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  135. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  136. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +30 -30
  137. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +3 -3
  138. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  139. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  140. package/web/.next/server/app/_global-error.html +2 -2
  141. package/web/.next/server/app/_global-error.rsc +1 -1
  142. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  143. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  144. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  145. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  146. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  147. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  148. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  149. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  150. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  151. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  152. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  153. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  154. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  155. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  156. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  157. package/web/.next/server/app/version/page.js.nft.json +1 -1
  158. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  159. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
  160. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
  161. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  162. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  163. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +3 -0
  164. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js.map +1 -0
  165. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +3 -0
  166. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js.map +1 -0
  167. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  168. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js.map +1 -1
  169. package/web/.next/server/chunks/ssr/[root-of-the-server]__2018e25f._.js +1 -1
  170. package/web/.next/server/chunks/ssr/[root-of-the-server]__2018e25f._.js.map +1 -1
  171. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  172. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  173. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js.map +1 -1
  174. package/web/.next/server/chunks/ssr/{[root-of-the-server]__cbae9863._.js → [root-of-the-server]__6258349c._.js} +2 -2
  175. package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js.map +1 -0
  176. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js.map +1 -1
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  182. package/web/.next/server/chunks/ssr/{[root-of-the-server]__e5e09f72._.js → [root-of-the-server]__94a6d275._.js} +2 -2
  183. package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js.map +1 -0
  184. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  185. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  186. package/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
  187. package/web/.next/server/chunks/ssr/_07c2a32a._.js.map +1 -1
  188. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  189. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js.map +1 -1
  190. package/web/.next/server/chunks/ssr/_250a63ae._.js +3 -0
  191. package/web/.next/server/chunks/ssr/_250a63ae._.js.map +1 -0
  192. package/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  193. package/web/.next/server/chunks/ssr/_61351ed3._.js.map +1 -1
  194. package/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  195. package/web/.next/server/chunks/ssr/_8400c8bb._.js.map +1 -1
  196. package/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  197. package/web/.next/server/chunks/ssr/_9f940437._.js.map +1 -1
  198. package/web/.next/server/chunks/ssr/_dee726e3._.js +6 -0
  199. package/web/.next/server/chunks/ssr/_dee726e3._.js.map +1 -0
  200. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5ea689db._.js → server/chunks/ssr/src_presentation_web_2b91e4ec._.js} +2 -2
  201. package/web/.next/server/chunks/ssr/{src_presentation_web_7188a290._.js.map → src_presentation_web_2b91e4ec._.js.map} +1 -1
  202. package/web/.next/server/chunks/ssr/{src_presentation_web_5ea689db._.js → src_presentation_web_5bcc1537._.js} +2 -2
  203. package/web/.next/server/chunks/ssr/{src_presentation_web_5ea689db._.js.map → src_presentation_web_5bcc1537._.js.map} +1 -1
  204. package/web/.next/server/chunks/ssr/src_presentation_web_67178b88._.js +1 -1
  205. package/web/.next/server/chunks/ssr/src_presentation_web_67178b88._.js.map +1 -1
  206. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js +3 -0
  207. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js.map +1 -0
  208. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +3 -0
  209. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -0
  210. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  211. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  212. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  213. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  214. package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +8 -0
  215. package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js.map +1 -0
  216. package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +8 -0
  217. package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js.map +1 -0
  218. package/web/.next/server/pages/500.html +2 -2
  219. package/web/.next/server/server-reference-manifest.js +1 -1
  220. package/web/.next/server/server-reference-manifest.json +142 -142
  221. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  222. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  223. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  224. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  225. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +34 -34
  226. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js +3 -3
  227. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  228. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  229. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +40 -40
  230. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -3
  231. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  232. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  233. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +30 -30
  234. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +3 -3
  235. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  236. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  237. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +34 -34
  238. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js +3 -3
  239. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  240. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  241. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +40 -40
  242. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +3 -3
  243. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  244. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  245. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +30 -30
  246. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js +3 -3
  247. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  248. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  249. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +30 -30
  250. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +3 -3
  251. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  252. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  253. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  254. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  255. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  256. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  257. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  258. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  259. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  260. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  261. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  262. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  263. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  264. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
  265. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  266. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  267. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
  268. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  269. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  270. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
  271. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  272. package/web/.next/standalone/src/presentation/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
  273. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  274. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +3 -0
  275. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +3 -0
  276. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  277. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2018e25f._.js +1 -1
  278. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  279. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  280. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{[root-of-the-server]__cbae9863._.js → [root-of-the-server]__6258349c._.js} +2 -2
  281. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  282. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  283. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  284. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{[root-of-the-server]__e5e09f72._.js → [root-of-the-server]__94a6d275._.js} +2 -2
  285. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  286. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
  287. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  288. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_250a63ae._.js +3 -0
  289. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  290. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  291. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  292. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_dee726e3._.js +6 -0
  293. package/web/.next/{server/chunks/ssr/src_presentation_web_7188a290._.js → standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_2b91e4ec._.js} +2 -2
  294. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{src_presentation_web_7188a290._.js → src_presentation_web_5bcc1537._.js} +2 -2
  295. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_67178b88._.js +1 -1
  296. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js +3 -0
  297. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +3 -0
  298. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  299. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  300. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +8 -0
  301. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +8 -0
  302. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  303. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  304. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +142 -142
  305. package/web/.next/standalone/src/presentation/web/CLAUDE.md +77 -33
  306. package/web/.next/standalone/src/presentation/web/app/actions/create-feature.ts +27 -2
  307. package/web/.next/standalone/src/presentation/web/app/actions/get-feature-metadata.ts +18 -0
  308. package/web/.next/standalone/src/presentation/web/app/api/agent-events/route.ts +17 -0
  309. package/web/.next/standalone/src/presentation/web/app/build-feature-node-data.ts +3 -30
  310. package/web/.next/standalone/src/presentation/web/app/build-graph-nodes.ts +3 -30
  311. package/web/.next/standalone/src/presentation/web/app/layout.tsx +1 -1
  312. package/web/.next/standalone/src/presentation/web/components/common/add-repository-button/index.ts +1 -0
  313. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx +15 -21
  314. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/drawer-view.ts +12 -13
  315. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx +105 -141
  316. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/index.ts +0 -1
  317. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/use-artifact-fetch.ts +56 -0
  318. package/web/.next/standalone/src/presentation/web/components/common/feature-drawer/use-feature-actions.ts +6 -7
  319. package/web/.next/standalone/src/presentation/web/components/common/feature-node/derive-feature-state.ts +63 -2
  320. package/web/.next/standalone/src/presentation/web/components/common/index.ts +2 -12
  321. package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-node.tsx +2 -2
  322. package/web/.next/standalone/src/presentation/web/components/common/repository-node/use-repository-actions.ts +29 -54
  323. package/web/.next/standalone/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.tsx +0 -13
  324. package/web/.next/standalone/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.tsx +1 -45
  325. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-empty-state.tsx +1 -1
  326. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +43 -36
  327. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center.stories.tsx +2 -41
  328. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +203 -440
  329. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx +0 -48
  330. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +13 -76
  331. package/web/.next/standalone/src/presentation/web/components/layouts/app-shell/app-shell.tsx +1 -1
  332. package/web/.next/standalone/src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx +2 -14
  333. package/web/.next/standalone/src/presentation/web/components/ui/alert-dialog.tsx +2 -5
  334. package/web/.next/standalone/src/presentation/web/components/ui/dialog.tsx +2 -5
  335. package/web/.next/standalone/src/presentation/web/components/ui/scroll-area.tsx +1 -1
  336. package/web/.next/standalone/src/presentation/web/hooks/agent-events-provider.tsx +7 -2
  337. package/web/.next/standalone/src/presentation/web/hooks/use-agent-events.ts +19 -5
  338. package/web/.next/standalone/src/presentation/web/hooks/use-deploy-action.ts +11 -3
  339. package/web/.next/standalone/src/presentation/web/hooks/use-graph-state.ts +376 -0
  340. package/web/.next/standalone/src/presentation/web/hooks/use-notifications.stories.tsx +2 -30
  341. package/web/.next/standalone/src/presentation/web/hooks/use-notifications.ts +2 -36
  342. package/web/.next/standalone/src/presentation/web/lib/derive-graph.ts +178 -0
  343. package/web/.next/standalone/src/presentation/web/lib/layout-with-dagre.ts +1 -2
  344. package/web/.next/standalone/src/presentation/web/lib/logger.ts +12 -0
  345. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  346. package/web/.next/static/chunks/0ffccd7be73305c8.css +2 -0
  347. package/web/.next/static/chunks/15ceb197ec725da2.js +1 -0
  348. package/web/.next/static/chunks/3f205fd6adbfd20a.js +7 -0
  349. package/web/.next/static/chunks/{d4492cd12fdf0891.js → 6691ad02dc1efd1f.js} +1 -1
  350. package/web/.next/static/chunks/{64850cf4081a2950.js → 7bff5fbcbf157df5.js} +1 -1
  351. package/web/.next/static/chunks/8959112899679e25.js +1 -0
  352. package/web/.next/static/chunks/{c83897e9213881bf.js → 8f508ef906cbf0fa.js} +1 -1
  353. package/web/.next/static/chunks/9cbb42a6bd516d3b.js +1 -0
  354. package/web/.next/static/chunks/c5603ed8a95d460d.js +1 -0
  355. package/web/.next/static/chunks/cb41849bcfaa304e.js +1 -0
  356. package/web/.next/static/chunks/d7e0cd32364a8d76.js +1 -0
  357. package/web/.next/static/chunks/e69d79bd3f19dec8.js +4 -0
  358. package/web/.next/trace +1 -1
  359. package/web/.next/trace-build +1 -1
  360. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-button.d.ts.map +0 -1
  361. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node-config.d.ts +0 -7
  362. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node-config.d.ts.map +0 -1
  363. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node-config.js +0 -1
  364. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.d.ts +0 -6
  365. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.d.ts.map +0 -1
  366. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.js +0 -23
  367. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.d.ts +0 -10
  368. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.d.ts.map +0 -1
  369. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.js +0 -33
  370. package/dist/src/presentation/web/components/common/add-repository-node/index.d.ts +0 -4
  371. package/dist/src/presentation/web/components/common/add-repository-node/index.d.ts.map +0 -1
  372. package/dist/src/presentation/web/components/common/add-repository-node/pick-folder.d.ts.map +0 -1
  373. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts +0 -12
  374. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts.map +0 -1
  375. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.js +0 -337
  376. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.d.ts +0 -33
  377. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.d.ts.map +0 -1
  378. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.js +0 -214
  379. package/dist/src/presentation/web/components/common/notification-permission-banner/index.d.ts +0 -2
  380. package/dist/src/presentation/web/components/common/notification-permission-banner/index.d.ts.map +0 -1
  381. package/dist/src/presentation/web/components/common/notification-permission-banner/index.js +0 -1
  382. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.d.ts +0 -2
  383. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.d.ts.map +0 -1
  384. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.js +0 -33
  385. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.d.ts +0 -6
  386. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.d.ts.map +0 -1
  387. package/dist/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.js +0 -24
  388. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_3a02d8a5.js +0 -3
  389. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_3a02d8a5.js.map +0 -1
  390. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_a3044852.js +0 -3
  391. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_a3044852.js.map +0 -1
  392. package/web/.next/server/chunks/ssr/[root-of-the-server]__cbae9863._.js.map +0 -1
  393. package/web/.next/server/chunks/ssr/[root-of-the-server]__e5e09f72._.js.map +0 -1
  394. package/web/.next/server/chunks/ssr/_38d24563._.js +0 -6
  395. package/web/.next/server/chunks/ssr/_38d24563._.js.map +0 -1
  396. package/web/.next/server/chunks/ssr/_6e08ce21._.js +0 -3
  397. package/web/.next/server/chunks/ssr/_6e08ce21._.js.map +0 -1
  398. package/web/.next/server/chunks/ssr/src_presentation_web_0a49d9ee._.js +0 -8
  399. package/web/.next/server/chunks/ssr/src_presentation_web_0a49d9ee._.js.map +0 -1
  400. package/web/.next/server/chunks/ssr/src_presentation_web_79b0305a._.js +0 -8
  401. package/web/.next/server/chunks/ssr/src_presentation_web_79b0305a._.js.map +0 -1
  402. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_cc16bd01.js +0 -3
  403. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_cc16bd01.js.map +0 -1
  404. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js +0 -3
  405. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js.map +0 -1
  406. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_3a02d8a5.js +0 -3
  407. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_a3044852.js +0 -3
  408. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_38d24563._.js +0 -6
  409. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_6e08ce21._.js +0 -3
  410. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_0a49d9ee._.js +0 -8
  411. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_79b0305a._.js +0 -8
  412. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_cc16bd01.js +0 -3
  413. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js +0 -3
  414. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/add-repository-node-config.ts +0 -8
  415. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.tsx +0 -70
  416. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/add-repository-node.tsx +0 -49
  417. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/index.ts +0 -3
  418. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.tsx +0 -293
  419. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.tsx +0 -745
  420. package/web/.next/standalone/src/presentation/web/components/common/notification-permission-banner/index.ts +0 -1
  421. package/web/.next/standalone/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.stories.tsx +0 -52
  422. package/web/.next/standalone/src/presentation/web/components/common/notification-permission-banner/notification-permission-banner.tsx +0 -55
  423. package/web/.next/static/chunks/0c54314c8c9c9739.js +0 -7
  424. package/web/.next/static/chunks/10cd08dae8c210ff.js +0 -1
  425. package/web/.next/static/chunks/15bf7ee1da91eb46.js +0 -4
  426. package/web/.next/static/chunks/3c79bca4d3f18f66.js +0 -1
  427. package/web/.next/static/chunks/67f2a7a5e8dc358a.css +0 -2
  428. package/web/.next/static/chunks/6cc840197626843b.js +0 -1
  429. package/web/.next/static/chunks/e3239b6c18cf8b96.js +0 -1
  430. package/web/.next/static/chunks/e9cc53ce8a7bdea6.js +0 -1
  431. package/web/.next/static/chunks/ef916db8c537211a.js +0 -1
  432. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/add-repository-button.d.ts +0 -0
  433. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/add-repository-button.js +0 -0
  434. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/pick-folder.d.ts +0 -0
  435. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/pick-folder.js +0 -0
  436. /package/web/.next/standalone/src/presentation/web/components/common/{add-repository-node → add-repository-button}/add-repository-button.tsx +0 -0
  437. /package/web/.next/standalone/src/presentation/web/components/common/{add-repository-node → add-repository-button}/pick-folder.ts +0 -0
  438. /package/web/.next/static/{Atrl1oUfRQej2kgJ972uS → 1AvkeBASQdtzZt9cm9UYg}/_buildManifest.js +0 -0
  439. /package/web/.next/static/{Atrl1oUfRQej2kgJ972uS → 1AvkeBASQdtzZt9cm9UYg}/_clientMiddlewareManifest.json +0 -0
  440. /package/web/.next/static/{Atrl1oUfRQej2kgJ972uS → 1AvkeBASQdtzZt9cm9UYg}/_ssgManifest.js +0 -0
@@ -0,0 +1,257 @@
1
+ 'use client';
2
+ import { useState, useMemo, useCallback, useRef } from 'react';
3
+ import { deriveGraph, } from '../lib/derive-graph.js';
4
+ import { layoutWithDagre, CANVAS_LAYOUT_DEFAULTS } from '../lib/layout-with-dagre.js';
5
+ /** Parse initialNodes + initialEdges into domain Maps. */
6
+ function parseMaps(initialNodes, initialEdges) {
7
+ // Build parentNodeId map from dependency edges
8
+ const parentByChild = new Map();
9
+ for (const edge of initialEdges) {
10
+ if (edge.type === 'dependencyEdge') {
11
+ parentByChild.set(edge.target, edge.source);
12
+ }
13
+ }
14
+ const featureMap = new Map();
15
+ const repoMap = new Map();
16
+ for (const node of initialNodes) {
17
+ if (node.type === 'featureNode') {
18
+ featureMap.set(node.id, {
19
+ nodeId: node.id,
20
+ data: node.data,
21
+ parentNodeId: parentByChild.get(node.id),
22
+ });
23
+ }
24
+ else if (node.type === 'repositoryNode') {
25
+ repoMap.set(node.id, {
26
+ nodeId: node.id,
27
+ data: node.data,
28
+ });
29
+ }
30
+ }
31
+ return { featureMap, repoMap };
32
+ }
33
+ function isFeatureDataUnchanged(data, updates) {
34
+ return ((updates.state === undefined || updates.state === data.state) &&
35
+ (updates.lifecycle === undefined || updates.lifecycle === data.lifecycle) &&
36
+ (updates.name === undefined || updates.name === data.name) &&
37
+ (updates.description === undefined || updates.description === data.description));
38
+ }
39
+ export function useGraphState(initialNodes, initialEdges) {
40
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- intentional: parse only on mount (like useState initializer)
41
+ const init = useMemo(() => parseMaps(initialNodes, initialEdges), []);
42
+ const [featureMap, setFeatureMap] = useState(init.featureMap);
43
+ const [repoMap, setRepoMap] = useState(init.repoMap);
44
+ const [pendingMap, setPendingMap] = useState(new Map());
45
+ // Buffer for SSE updates that arrive before their feature is in featureMap.
46
+ // When reconcile adds new features, buffered updates are applied automatically.
47
+ const pendingUpdatesRef = useRef(new Map());
48
+ // Callbacks stored in a ref so changing them doesn't trigger re-render.
49
+ // The stable wrapper object reads from the ref so node closures always use latest callbacks.
50
+ const callbacksRef = useRef({});
51
+ const stableCallbacks = useMemo(() => ({
52
+ onNodeAction: (nodeId) => callbacksRef.current.onNodeAction?.(nodeId),
53
+ onNodeSettings: (nodeId) => callbacksRef.current.onNodeSettings?.(nodeId),
54
+ onFeatureDelete: (featureId) => callbacksRef.current.onFeatureDelete?.(featureId),
55
+ onRepositoryAdd: (nodeId) => callbacksRef.current.onRepositoryAdd?.(nodeId),
56
+ onRepositoryClick: (nodeId) => callbacksRef.current.onRepositoryClick?.(nodeId),
57
+ onRepositoryDelete: (repositoryId) => callbacksRef.current.onRepositoryDelete?.(repositoryId),
58
+ }), []);
59
+ // Stable refs for domain Maps (for use in callbacks without depending on state)
60
+ const featureMapRef = useRef(featureMap);
61
+ featureMapRef.current = featureMap;
62
+ const repoMapRef = useRef(repoMap);
63
+ repoMapRef.current = repoMap;
64
+ // Derive graph from domain Maps (runs on every Map change, but dagre only on topology change)
65
+ const derived = useMemo(() => deriveGraph(featureMap, repoMap, pendingMap, stableCallbacks), [featureMap, repoMap, pendingMap, stableCallbacks]);
66
+ // Cache dagre layout positions — only re-run when node set or edge connections change
67
+ const layoutCacheRef = useRef({ key: '', positions: new Map() });
68
+ const { nodes, edges } = useMemo(() => {
69
+ const nodeIds = derived.nodes
70
+ .map((n) => n.id)
71
+ .sort()
72
+ .join(',');
73
+ const edgeKeys = derived.edges
74
+ .map((e) => `${e.source}-${e.target}`)
75
+ .sort()
76
+ .join(',');
77
+ const topologyKey = `${nodeIds}|${edgeKeys}`;
78
+ if (topologyKey !== layoutCacheRef.current.key) {
79
+ // Topology changed — re-run dagre
80
+ const result = layoutWithDagre(derived.nodes, derived.edges, CANVAS_LAYOUT_DEFAULTS);
81
+ const positions = new Map();
82
+ for (const node of result.nodes) {
83
+ positions.set(node.id, {
84
+ position: node.position,
85
+ targetPosition: node.targetPosition,
86
+ sourcePosition: node.sourcePosition,
87
+ });
88
+ }
89
+ layoutCacheRef.current = { key: topologyKey, positions };
90
+ return result;
91
+ }
92
+ // Data-only change — apply cached positions without re-running dagre
93
+ const { positions } = layoutCacheRef.current;
94
+ const nodes = derived.nodes.map((node) => {
95
+ const cached = positions.get(node.id);
96
+ return cached ? { ...node, ...cached } : node;
97
+ });
98
+ return { nodes, edges: derived.edges };
99
+ }, [derived]);
100
+ // --- Mutations ---
101
+ const reconcile = useCallback((newNodes, newEdges) => {
102
+ const { featureMap: newFeatureMap, repoMap: newRepoMap } = parseMaps(newNodes, newEdges);
103
+ // Precompute match keys so we don't scan newFeatureMap.values() per pending entry
104
+ const realFeatureKeys = new Set([...newFeatureMap.values()].map((e) => `${e.data.name}\0${e.data.repositoryPath}`));
105
+ setFeatureMap((currentFeatureMap) => {
106
+ // Preserve pending (creating) nodes unless matched by name+repositoryPath from newFeatureMap
107
+ const pendingEntries = [...currentFeatureMap.entries()].filter(([, e]) => e.data.state === 'creating');
108
+ const merged = new Map(newFeatureMap);
109
+ // Keep pending nodes that don't have a real counterpart in new data
110
+ for (const [tempId, pendingEntry] of pendingEntries) {
111
+ const key = `${pendingEntry.data.name}\0${pendingEntry.data.repositoryPath}`;
112
+ if (!realFeatureKeys.has(key)) {
113
+ merged.set(tempId, pendingEntry);
114
+ }
115
+ }
116
+ // Apply any buffered SSE updates to features that now exist in the map
117
+ for (const [nodeId, updates] of pendingUpdatesRef.current) {
118
+ const entry = merged.get(nodeId);
119
+ if (entry) {
120
+ merged.set(nodeId, { ...entry, data: { ...entry.data, ...updates } });
121
+ pendingUpdatesRef.current.delete(nodeId);
122
+ }
123
+ }
124
+ return merged;
125
+ });
126
+ // Clean pendingMap entries that now have a real counterpart in server data
127
+ setPendingMap((currentPendingMap) => {
128
+ if (currentPendingMap.size === 0)
129
+ return currentPendingMap;
130
+ let changed = false;
131
+ const next = new Map(currentPendingMap);
132
+ for (const [tempId, pendingEntry] of currentPendingMap) {
133
+ const key = `${pendingEntry.data.name}\0${pendingEntry.data.repositoryPath}`;
134
+ if (realFeatureKeys.has(key)) {
135
+ next.delete(tempId);
136
+ changed = true;
137
+ }
138
+ }
139
+ return changed ? next : currentPendingMap;
140
+ });
141
+ setRepoMap(newRepoMap);
142
+ }, []);
143
+ const updateFeature = useCallback((featureNodeId, updates) => {
144
+ setFeatureMap((prev) => {
145
+ const entry = prev.get(featureNodeId);
146
+ if (!entry) {
147
+ // Feature not yet in map — buffer update for when reconcile adds it
148
+ pendingUpdatesRef.current.set(featureNodeId, {
149
+ ...pendingUpdatesRef.current.get(featureNodeId),
150
+ ...updates,
151
+ });
152
+ return prev;
153
+ }
154
+ // Clear any buffered update for this feature since it's now in the map
155
+ pendingUpdatesRef.current.delete(featureNodeId);
156
+ if (isFeatureDataUnchanged(entry.data, updates))
157
+ return prev;
158
+ const next = new Map(prev);
159
+ next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
160
+ return next;
161
+ });
162
+ // Also check pendingMap
163
+ setPendingMap((prev) => {
164
+ const entry = prev.get(featureNodeId);
165
+ if (!entry)
166
+ return prev;
167
+ if (isFeatureDataUnchanged(entry.data, updates))
168
+ return prev;
169
+ const next = new Map(prev);
170
+ next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
171
+ return next;
172
+ });
173
+ }, []);
174
+ const addPendingFeature = useCallback((nodeId, data, parentNodeId) => {
175
+ setPendingMap((prev) => {
176
+ const next = new Map(prev);
177
+ next.set(nodeId, { nodeId, data, parentNodeId });
178
+ return next;
179
+ });
180
+ }, []);
181
+ const removePendingFeature = useCallback((nodeId) => {
182
+ setPendingMap((prev) => {
183
+ if (!prev.has(nodeId))
184
+ return prev;
185
+ const next = new Map(prev);
186
+ next.delete(nodeId);
187
+ return next;
188
+ });
189
+ }, []);
190
+ const removeFeature = useCallback((nodeId) => {
191
+ setFeatureMap((prev) => {
192
+ if (!prev.has(nodeId))
193
+ return prev;
194
+ const next = new Map(prev);
195
+ next.delete(nodeId);
196
+ return next;
197
+ });
198
+ }, []);
199
+ const restoreFeature = useCallback((nodeId, entry) => {
200
+ setFeatureMap((prev) => {
201
+ const next = new Map(prev);
202
+ next.set(nodeId, entry);
203
+ return next;
204
+ });
205
+ }, []);
206
+ const addRepository = useCallback((nodeId, data) => {
207
+ setRepoMap((prev) => {
208
+ const next = new Map(prev);
209
+ next.set(nodeId, { nodeId, data });
210
+ return next;
211
+ });
212
+ }, []);
213
+ const removeRepository = useCallback((nodeId) => {
214
+ setRepoMap((prev) => {
215
+ if (!prev.has(nodeId))
216
+ return prev;
217
+ const next = new Map(prev);
218
+ next.delete(nodeId);
219
+ return next;
220
+ });
221
+ }, []);
222
+ const replaceRepository = useCallback((tempId, realId, data) => {
223
+ setRepoMap((prev) => {
224
+ if (!prev.has(tempId))
225
+ return prev;
226
+ const next = new Map(prev);
227
+ next.delete(tempId);
228
+ next.set(realId, { nodeId: realId, data });
229
+ return next;
230
+ });
231
+ }, []);
232
+ const getFeatureRepositoryPath = useCallback((featureNodeId) => {
233
+ return featureMapRef.current.get(featureNodeId)?.data.repositoryPath;
234
+ }, []);
235
+ const getRepositoryData = useCallback((nodeId) => {
236
+ return repoMapRef.current.get(nodeId)?.data;
237
+ }, []);
238
+ const setCallbacks = useCallback((callbacks) => {
239
+ callbacksRef.current = callbacks;
240
+ }, []);
241
+ return {
242
+ nodes,
243
+ edges,
244
+ reconcile,
245
+ updateFeature,
246
+ addPendingFeature,
247
+ removePendingFeature,
248
+ removeFeature,
249
+ restoreFeature,
250
+ addRepository,
251
+ removeRepository,
252
+ replaceRepository,
253
+ getFeatureRepositoryPath,
254
+ getRepositoryData,
255
+ setCallbacks,
256
+ };
257
+ }
@@ -1,6 +1,2 @@
1
- export interface UseNotificationsResult {
2
- requestBrowserPermission: () => Promise<void>;
3
- browserPermissionState: NotificationPermission;
4
- }
5
- export declare function useNotifications(): UseNotificationsResult;
1
+ export declare function useNotifications(): void;
6
2
  //# sourceMappingURL=use-notifications.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-notifications.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,sBAAsB;IACrC,wBAAwB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,sBAAsB,EAAE,sBAAsB,CAAC;CAChD;AA2CD,wBAAgB,gBAAgB,IAAI,sBAAsB,CAiEzD"}
1
+ {"version":3,"file":"use-notifications.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.ts"],"names":[],"mappings":"AA0CA,wBAAgB,gBAAgB,IAAI,IAAI,CA8CvC"}
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { useEffect, useMemo, useRef } from 'react';
3
3
  import { useRouter } from 'next/navigation';
4
4
  import { toast } from 'sonner';
5
5
  import { NotificationEventType, NotificationSeverity } from '../../../../packages/core/src/domain/generated/output.js';
@@ -27,15 +27,6 @@ function dispatchToast(event, navigate) {
27
27
  }),
28
28
  });
29
29
  }
30
- function dispatchBrowserNotification(event) {
31
- if (globalThis.Notification?.permission !== 'granted') {
32
- return;
33
- }
34
- new Notification(`Shep: ${event.featureName}`, {
35
- body: event.message,
36
- icon: '/favicon-light.svg',
37
- });
38
- }
39
30
  const SEVERITY_TO_ACTION = {
40
31
  [NotificationSeverity.Success]: 'notification-success',
41
32
  [NotificationSeverity.Error]: 'notification-error',
@@ -55,11 +46,6 @@ export function useNotifications() {
55
46
  'notification-warning': warningSound,
56
47
  'notification-info': infoSound,
57
48
  }), [successSound, errorSound, warningSound, infoSound]);
58
- const [browserPermissionState, setBrowserPermissionState] = useState(() => {
59
- if (typeof globalThis.Notification === 'undefined')
60
- return 'default';
61
- return globalThis.Notification.permission;
62
- });
63
49
  // Track how many events from the array we've already processed.
64
50
  // Using the array index (instead of lastEvent) prevents React batching
65
51
  // from silently dropping events when multiple SSE messages arrive together.
@@ -77,19 +63,8 @@ export function useNotifications() {
77
63
  continue;
78
64
  }
79
65
  dispatchToast(event, (path) => router.push(path));
80
- dispatchBrowserNotification(event);
81
66
  const actionName = SEVERITY_TO_ACTION[event.severity];
82
67
  soundsByAction[actionName]?.play();
83
68
  }
84
69
  }, [events, soundsByAction, router]);
85
- const requestBrowserPermission = useCallback(async () => {
86
- if (typeof globalThis.Notification === 'undefined')
87
- return;
88
- const result = await globalThis.Notification.requestPermission();
89
- setBrowserPermissionState(result);
90
- }, []);
91
- return {
92
- requestBrowserPermission,
93
- browserPermissionState,
94
- };
95
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-notifications.stories.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAqKvD,QAAA,MAAM,IAAI,EAAE,IAcX,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
1
+ {"version":3,"file":"use-notifications.stories.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-notifications.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAyIvD,QAAA,MAAM,IAAI,EAAE,IAcX,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useMemo, useState } from 'react';
2
+ import { useCallback, useMemo } from 'react';
3
3
  import { toast } from 'sonner';
4
4
  import { Toaster } from '../components/ui/sonner.js';
5
5
  import { Button } from '../components/ui/button.js';
@@ -24,46 +24,36 @@ function NotificationDemo() {
24
24
  const simulateNotification = useCallback((event) => {
25
25
  const method = event.severity ?? 'info';
26
26
  toast[method](event.featureName, { description: event.message });
27
- if (globalThis.Notification?.permission === 'granted') {
28
- new Notification(event.featureName, { body: event.message });
29
- }
30
27
  const soundName = SEVERITY_SOUNDS[event.severity];
31
28
  soundsByName[soundName]?.play();
32
29
  }, [soundsByName]);
33
- const [browserPermission, setBrowserPermission] = useState(typeof globalThis.Notification !== 'undefined' ? globalThis.Notification.permission : 'default');
34
- const requestPermission = async () => {
35
- if (typeof globalThis.Notification === 'undefined')
36
- return;
37
- const result = await globalThis.Notification.requestPermission();
38
- setBrowserPermission(result);
39
- };
40
- return (_jsxs("div", { className: "flex w-[420px] flex-col gap-6", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h3", { className: "text-sm font-semibold", children: "Browser Notification Permission" }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("span", { className: "text-muted-foreground text-sm", children: ["Status: ", _jsx("code", { className: "bg-muted rounded px-1.5 py-0.5", children: browserPermission })] }), _jsx(Button, { size: "sm", variant: "outline", onClick: requestPermission, children: "Request Permission" })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h3", { className: "text-sm font-semibold", children: "Simulate Notification Events" }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Click a button to fire a toast, browser notification, and sound." }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Button, { size: "sm", variant: "outline", onClick: () => simulateNotification({
41
- eventType: 'agent_started',
42
- severity: 'info',
43
- featureName: 'Auth Module',
44
- message: 'Agent started running',
45
- }), children: "Agent Started" }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => simulateNotification({
46
- eventType: 'phase_completed',
47
- severity: 'info',
48
- featureName: 'Auth Module',
49
- message: 'Completed analyze phase',
50
- phaseName: 'analyze',
51
- }), children: "Phase Completed" }), _jsx(Button, { size: "sm", variant: "secondary", onClick: () => simulateNotification({
52
- eventType: 'waiting_approval',
53
- severity: 'warning',
54
- featureName: 'Auth Module',
55
- message: 'Waiting for user approval',
56
- }), children: "Waiting Approval" }), _jsx(Button, { size: "sm", onClick: () => simulateNotification({
57
- eventType: 'agent_completed',
58
- severity: 'success',
59
- featureName: 'Auth Module',
60
- message: 'Agent completed successfully',
61
- }), children: "Agent Completed" }), _jsx(Button, { size: "sm", variant: "destructive", onClick: () => simulateNotification({
62
- eventType: 'agent_failed',
63
- severity: 'error',
64
- featureName: 'Auth Module',
65
- message: 'Agent failed: token refresh error',
66
- }), children: "Agent Failed" })] })] })] }));
30
+ return (_jsx("div", { className: "flex w-[420px] flex-col gap-6", children: _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h3", { className: "text-sm font-semibold", children: "Simulate Notification Events" }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Click a button to fire a toast and sound." }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Button, { size: "sm", variant: "outline", onClick: () => simulateNotification({
31
+ eventType: 'agent_started',
32
+ severity: 'info',
33
+ featureName: 'Auth Module',
34
+ message: 'Agent started running',
35
+ }), children: "Agent Started" }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => simulateNotification({
36
+ eventType: 'phase_completed',
37
+ severity: 'info',
38
+ featureName: 'Auth Module',
39
+ message: 'Completed analyze phase',
40
+ phaseName: 'analyze',
41
+ }), children: "Phase Completed" }), _jsx(Button, { size: "sm", variant: "secondary", onClick: () => simulateNotification({
42
+ eventType: 'waiting_approval',
43
+ severity: 'warning',
44
+ featureName: 'Auth Module',
45
+ message: 'Waiting for user approval',
46
+ }), children: "Waiting Approval" }), _jsx(Button, { size: "sm", onClick: () => simulateNotification({
47
+ eventType: 'agent_completed',
48
+ severity: 'success',
49
+ featureName: 'Auth Module',
50
+ message: 'Agent completed successfully',
51
+ }), children: "Agent Completed" }), _jsx(Button, { size: "sm", variant: "destructive", onClick: () => simulateNotification({
52
+ eventType: 'agent_failed',
53
+ severity: 'error',
54
+ featureName: 'Auth Module',
55
+ message: 'Agent failed: token refresh error',
56
+ }), children: "Agent Failed" })] })] }) }));
67
57
  }
68
58
  const meta = {
69
59
  title: 'Hooks/useNotifications',
@@ -0,0 +1,52 @@
1
+ /**
2
+ * derive-graph.ts
3
+ *
4
+ * Pure client-side derivation: domain Maps → React Flow nodes + edges.
5
+ * All edges are derived from domain relationships (repositoryPath matching,
6
+ * parentNodeId) — never stored independently.
7
+ */
8
+ import type { Edge } from '@xyflow/react';
9
+ import type { CanvasNodeType } from '../components/features/features-canvas/index.js';
10
+ import type { FeatureNodeData } from '../components/common/feature-node/index.js';
11
+ import type { RepositoryNodeData } from '../components/common/repository-node/index.js';
12
+ /** A feature node entry stored in the domain Map. */
13
+ export interface FeatureEntry {
14
+ nodeId: string;
15
+ data: FeatureNodeData;
16
+ /** If set, this feature connects to a parent feature via a dependency edge (no repo→feature edge). */
17
+ parentNodeId?: string;
18
+ }
19
+ /** A repository node entry stored in the domain Map. */
20
+ export interface RepoEntry {
21
+ nodeId: string;
22
+ data: RepositoryNodeData;
23
+ }
24
+ /** Stable callbacks passed by the consumer, injected into derived node data. */
25
+ export interface GraphCallbacks {
26
+ /** Called when the user triggers an action on a feature node (e.g., adds a sub-feature). */
27
+ onNodeAction?: (nodeId: string) => void;
28
+ /** Called when the user opens settings/details on a feature node. */
29
+ onNodeSettings?: (nodeId: string) => void;
30
+ /** Called when the user deletes a feature. */
31
+ onFeatureDelete?: (featureId: string) => void;
32
+ /** Called when the user clicks the "+" add-feature button on a repo node. */
33
+ onRepositoryAdd?: (repoNodeId: string) => void;
34
+ /** Called when the user clicks a repo node to navigate to its detail page. */
35
+ onRepositoryClick?: (repoNodeId: string) => void;
36
+ /** Called when the user deletes a repository. */
37
+ onRepositoryDelete?: (repositoryId: string) => void;
38
+ }
39
+ /**
40
+ * Derives React Flow nodes and edges from domain Maps.
41
+ *
42
+ * - Feature nodes without a parentNodeId → repo→feature edge (matched by repositoryPath)
43
+ * - Feature nodes without a parentNodeId but with no matching repo → virtual repo node
44
+ * - Feature nodes with a parentNodeId → dependency edge (parentNodeId→nodeId)
45
+ * - Pending feature nodes (creating state) from pendingMap → same rules, no action callbacks
46
+ * - Callbacks are injected into node data via closures
47
+ */
48
+ export declare function deriveGraph(featureMap: Map<string, FeatureEntry>, repoMap: Map<string, RepoEntry>, pendingMap: Map<string, FeatureEntry>, callbacks?: GraphCallbacks): {
49
+ nodes: CanvasNodeType[];
50
+ edges: Edge[];
51
+ };
52
+ //# sourceMappingURL=derive-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive-graph.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/derive-graph.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,eAAe,CAAC;IACtB,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,4FAA4F;IAC5F,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,qEAAqE;IACrE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,8CAA8C;IAC9C,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,6EAA6E;IAC7E,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,SAAS,CAAC,EAAE,cAAc,GACzB;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAyH5C"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * derive-graph.ts
3
+ *
4
+ * Pure client-side derivation: domain Maps → React Flow nodes + edges.
5
+ * All edges are derived from domain relationships (repositoryPath matching,
6
+ * parentNodeId) — never stored independently.
7
+ */
8
+ /**
9
+ * Derives React Flow nodes and edges from domain Maps.
10
+ *
11
+ * - Feature nodes without a parentNodeId → repo→feature edge (matched by repositoryPath)
12
+ * - Feature nodes without a parentNodeId but with no matching repo → virtual repo node
13
+ * - Feature nodes with a parentNodeId → dependency edge (parentNodeId→nodeId)
14
+ * - Pending feature nodes (creating state) from pendingMap → same rules, no action callbacks
15
+ * - Callbacks are injected into node data via closures
16
+ */
17
+ export function deriveGraph(featureMap, repoMap, pendingMap, callbacks) {
18
+ const nodes = [];
19
+ const edges = [];
20
+ // Build a lookup: repositoryPath → repoNodeId
21
+ const repoByPath = new Map();
22
+ for (const [nodeId, entry] of repoMap) {
23
+ if (entry.data.repositoryPath) {
24
+ repoByPath.set(entry.data.repositoryPath, nodeId);
25
+ }
26
+ }
27
+ // Virtual repo nodes created for orphaned features (not in repoMap)
28
+ const virtualRepos = new Map(); // path → virtualNodeId
29
+ function getOrCreateVirtualRepo(repositoryPath) {
30
+ if (virtualRepos.has(repositoryPath)) {
31
+ return virtualRepos.get(repositoryPath);
32
+ }
33
+ const virtualId = `virtual-repo-${repositoryPath}`;
34
+ const repoName = repositoryPath.split('/').filter(Boolean).at(-1) ?? repositoryPath;
35
+ nodes.push({
36
+ id: virtualId,
37
+ type: 'repositoryNode',
38
+ position: { x: 0, y: 0 },
39
+ data: { name: repoName, repositoryPath },
40
+ });
41
+ virtualRepos.set(repositoryPath, virtualId);
42
+ return virtualId;
43
+ }
44
+ // Add repo nodes (real ones)
45
+ for (const [nodeId, entry] of repoMap) {
46
+ const data = {
47
+ ...entry.data,
48
+ ...(callbacks?.onRepositoryAdd && {
49
+ onAdd: () => callbacks.onRepositoryAdd(nodeId),
50
+ }),
51
+ ...(callbacks?.onRepositoryClick && {
52
+ onClick: () => callbacks.onRepositoryClick(nodeId),
53
+ }),
54
+ ...(callbacks?.onRepositoryDelete && {
55
+ onDelete: callbacks.onRepositoryDelete,
56
+ }),
57
+ };
58
+ nodes.push({
59
+ id: nodeId,
60
+ type: 'repositoryNode',
61
+ position: { x: 0, y: 0 },
62
+ data,
63
+ });
64
+ }
65
+ // Process feature entries (both real and pending).
66
+ // Skip pendingMap entries that already exist in featureMap (reconcile may not
67
+ // have cleaned them up yet if the AI-generated name differs from the original).
68
+ const allFeatureEntries = [
69
+ ...[...featureMap.entries()].map(([id, e]) => [id, e, false]),
70
+ ...[...pendingMap.entries()]
71
+ .filter(([id]) => !featureMap.has(id))
72
+ .map(([id, e]) => [id, e, true]),
73
+ ];
74
+ for (const [nodeId, entry, isPending] of allFeatureEntries) {
75
+ const isCreating = entry.data.state === 'creating' || isPending;
76
+ const data = {
77
+ ...entry.data,
78
+ // Callbacks only for non-creating nodes
79
+ ...(!isCreating &&
80
+ callbacks?.onNodeAction && {
81
+ onAction: () => callbacks.onNodeAction(nodeId),
82
+ }),
83
+ ...(!isCreating &&
84
+ callbacks?.onNodeSettings && {
85
+ onSettings: () => callbacks.onNodeSettings(nodeId),
86
+ }),
87
+ ...(!isCreating &&
88
+ callbacks?.onFeatureDelete && {
89
+ onDelete: callbacks.onFeatureDelete,
90
+ }),
91
+ };
92
+ nodes.push({
93
+ id: nodeId,
94
+ type: 'featureNode',
95
+ position: { x: 0, y: 0 },
96
+ data,
97
+ });
98
+ // Edge derivation
99
+ if (entry.parentNodeId) {
100
+ // Dependency edge (parent→child feature)
101
+ edges.push({
102
+ id: `dep-${entry.parentNodeId}-${nodeId}`,
103
+ source: entry.parentNodeId,
104
+ target: nodeId,
105
+ type: 'dependencyEdge',
106
+ });
107
+ }
108
+ else {
109
+ // Repo→feature edge (matched by repositoryPath)
110
+ const repositoryPath = entry.data.repositoryPath;
111
+ const repoNodeId = repoByPath.get(repositoryPath) ?? getOrCreateVirtualRepo(repositoryPath);
112
+ edges.push({
113
+ id: `edge-${repoNodeId}-${nodeId}`,
114
+ source: repoNodeId,
115
+ target: nodeId,
116
+ style: { strokeDasharray: '5 5' },
117
+ });
118
+ }
119
+ }
120
+ // Inject showHandles based on whether there are any edges
121
+ const hasEdges = edges.length > 0;
122
+ for (const node of nodes) {
123
+ node.data.showHandles = hasEdges;
124
+ }
125
+ return { nodes, edges };
126
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"layout-with-dagre.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/layout-with-dagre.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,EAAE,aAIpC,CAAC;AAmCF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,IAAI,EAC5C,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,GAAE,aAAkB,GACvB;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAoK/B"}
1
+ {"version":3,"file":"layout-with-dagre.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/layout-with-dagre.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,EAAE,aAIpC,CAAC;AAkCF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,IAAI,EAC5C,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,GAAE,aAAkB,GACvB;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAoK/B"}
@@ -8,8 +8,7 @@ export const CANVAS_LAYOUT_DEFAULTS = {
8
8
  /** Known node-type dimensions for the canvas node types */
9
9
  const NODE_DIMENSIONS = {
10
10
  featureNode: { width: 288, height: 140 },
11
- repositoryNode: { width: 288, height: 50 },
12
- addRepositoryNode: { width: 224, height: 50 },
11
+ repositoryNode: { width: 328, height: 50 },
13
12
  };
14
13
  function getNodeSize(node, defaultSize) {
15
14
  // Prefer per-node size from data, then type-based lookup, then default
@@ -0,0 +1,7 @@
1
+ export declare function createLogger(prefix: string): {
2
+ info: (...args: unknown[]) => void;
3
+ debug: (...args: unknown[]) => void;
4
+ warn: (...args: unknown[]) => void;
5
+ error: (...args: unknown[]) => void;
6
+ };
7
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/logger.ts"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM;oBAEb,OAAO,EAAE;qBACR,OAAO,EAAE;oBACpB,OAAO,EAAE;qBACR,OAAO,EAAE;EAE7B"}
@@ -0,0 +1,11 @@
1
+ /* eslint-disable no-console */
2
+ const isDebug = !!process.env.NEXT_PUBLIC_DEBUG;
3
+ const noop = () => undefined;
4
+ export function createLogger(prefix) {
5
+ return {
6
+ info: isDebug ? (...args) => console.info(prefix, ...args) : noop,
7
+ debug: isDebug ? (...args) => console.debug(prefix, ...args) : noop,
8
+ warn: (...args) => console.warn(prefix, ...args),
9
+ error: (...args) => console.error(prefix, ...args),
10
+ };
11
+ }