@shepai/cli 1.72.8 → 1.72.9-pr220.e1bfec0

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 (365) hide show
  1. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +2 -1
  2. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.js +1 -0
  5. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +20 -1
  6. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  7. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +68 -41
  8. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +10 -0
  9. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
  11. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +1 -0
  12. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +1 -1
  13. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts.map +1 -1
  14. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.js +88 -13
  15. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +1 -1
  16. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +2 -1
  17. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
  18. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +3 -0
  19. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +2 -0
  20. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  21. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +16 -3
  22. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
  23. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +5 -1
  24. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  25. package/dist/src/presentation/web/app/actions/create-feature.js +20 -2
  26. package/dist/src/presentation/web/app/actions/get-feature-metadata.d.ts +10 -0
  27. package/dist/src/presentation/web/app/actions/get-feature-metadata.d.ts.map +1 -0
  28. package/dist/src/presentation/web/app/actions/get-feature-metadata.js +14 -0
  29. package/dist/src/presentation/web/app/actions/get-graph-data.d.ts +10 -0
  30. package/dist/src/presentation/web/app/actions/get-graph-data.d.ts.map +1 -0
  31. package/dist/src/presentation/web/app/actions/get-graph-data.js +10 -0
  32. package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
  33. package/dist/src/presentation/web/app/api/agent-events/route.js +18 -0
  34. package/dist/src/presentation/web/components/common/add-repository-button/add-repository-button.d.ts.map +1 -0
  35. package/dist/src/presentation/web/components/common/add-repository-button/index.d.ts +2 -0
  36. package/dist/src/presentation/web/components/common/add-repository-button/index.d.ts.map +1 -0
  37. package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/index.js +0 -1
  38. package/dist/src/presentation/web/components/common/add-repository-button/pick-folder.d.ts.map +1 -0
  39. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
  40. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +21 -23
  41. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  42. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +35 -16
  43. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.d.ts.map +1 -1
  44. package/dist/src/presentation/web/components/common/feature-node/derive-feature-state.js +2 -0
  45. package/dist/src/presentation/web/components/common/index.d.ts +1 -1
  46. package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
  47. package/dist/src/presentation/web/components/common/index.js +1 -1
  48. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +1 -1
  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 +23 -4
  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 +154 -258
  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 +12 -44
  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/scroll-area.js +1 -1
  74. package/dist/src/presentation/web/hooks/use-graph-state.d.ts +41 -0
  75. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -0
  76. package/dist/src/presentation/web/hooks/use-graph-state.js +230 -0
  77. package/dist/src/presentation/web/lib/derive-graph.d.ts +52 -0
  78. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -0
  79. package/dist/src/presentation/web/lib/derive-graph.js +126 -0
  80. package/dist/src/presentation/web/lib/layout-with-dagre.d.ts.map +1 -1
  81. package/dist/src/presentation/web/lib/layout-with-dagre.js +1 -2
  82. package/dist/tsconfig.build.tsbuildinfo +1 -1
  83. package/package.json +1 -1
  84. package/web/.next/BUILD_ID +1 -1
  85. package/web/.next/build-manifest.json +2 -2
  86. package/web/.next/cache/.previewinfo +1 -1
  87. package/web/.next/cache/.rscinfo +1 -1
  88. package/web/.next/cache/.tsbuildinfo +1 -1
  89. package/web/.next/cache/config.json +3 -3
  90. package/web/.next/fallback-build-manifest.json +2 -2
  91. package/web/.next/prerender-manifest.json +3 -3
  92. package/web/.next/required-server-files.js +1 -1
  93. package/web/.next/required-server-files.json +1 -1
  94. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +43 -28
  95. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  96. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  97. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  98. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +49 -34
  99. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  100. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  101. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  102. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +39 -24
  103. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  104. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  105. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  106. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +43 -28
  107. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  108. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  109. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  110. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +49 -34
  111. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  112. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  113. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  114. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +39 -24
  115. package/web/.next/server/app/(dashboard)/page.js +1 -1
  116. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  117. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  118. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +39 -24
  119. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  120. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  121. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  122. package/web/.next/server/app/_global-error.html +2 -2
  123. package/web/.next/server/app/_global-error.rsc +1 -1
  124. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  125. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  126. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  127. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  128. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  129. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  130. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  131. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  132. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  133. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  134. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  135. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  136. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  137. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  138. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  139. package/web/.next/server/app/version/page.js.nft.json +1 -1
  140. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  141. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
  142. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
  143. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  144. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  145. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +3 -0
  146. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js.map +1 -0
  147. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +3 -0
  148. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js.map +1 -0
  149. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  150. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js.map +1 -1
  151. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  152. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  153. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js.map +1 -1
  154. package/web/.next/server/chunks/ssr/{[root-of-the-server]__cbae9863._.js → [root-of-the-server]__6258349c._.js} +2 -2
  155. package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js.map +1 -0
  156. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  157. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  158. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  159. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js.map +1 -1
  160. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  161. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  162. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__e5e09f72._.js → server/chunks/ssr/[root-of-the-server]__94a6d275._.js} +2 -2
  163. package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js.map +1 -0
  164. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  165. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  166. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  167. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js.map +1 -1
  168. package/web/.next/server/chunks/ssr/_250a63ae._.js.map +1 -1
  169. package/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  170. package/web/.next/server/chunks/ssr/_61351ed3._.js.map +1 -1
  171. package/web/.next/server/chunks/ssr/_63688261._.js +6 -0
  172. package/web/.next/server/chunks/ssr/_63688261._.js.map +1 -0
  173. package/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  174. package/web/.next/server/chunks/ssr/_8400c8bb._.js.map +1 -1
  175. package/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  176. package/web/.next/server/chunks/ssr/_9f940437._.js.map +1 -1
  177. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js → server/chunks/ssr/src_presentation_web_2b91e4ec._.js} +2 -2
  178. package/web/.next/server/chunks/ssr/{src_presentation_web_5c87e8e4._.js.map → src_presentation_web_2b91e4ec._.js.map} +1 -1
  179. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js → server/chunks/ssr/src_presentation_web_5bcc1537._.js} +2 -2
  180. package/web/.next/server/chunks/ssr/{src_presentation_web_398553b0._.js.map → src_presentation_web_5bcc1537._.js.map} +1 -1
  181. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js +3 -0
  182. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5955c012.js.map +1 -0
  183. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  184. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  185. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  186. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  187. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  188. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  189. package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +8 -0
  190. package/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js.map +1 -0
  191. package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +8 -0
  192. package/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js.map +1 -0
  193. package/web/.next/server/pages/500.html +2 -2
  194. package/web/.next/server/server-reference-manifest.js +1 -1
  195. package/web/.next/server/server-reference-manifest.json +175 -118
  196. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  197. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  198. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  199. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  200. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +43 -28
  201. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  202. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  203. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  204. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +49 -34
  205. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  206. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  207. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  208. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +39 -24
  209. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  210. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  211. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  212. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +43 -28
  213. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js +1 -1
  214. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  215. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  216. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +49 -34
  217. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  218. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  219. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  220. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +39 -24
  221. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js +1 -1
  222. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  223. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  224. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +39 -24
  225. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  226. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  227. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  228. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  229. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  230. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  231. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  232. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  233. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  234. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  235. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  236. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  237. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  238. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  239. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
  240. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  241. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  242. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
  243. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  244. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  245. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
  246. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  247. package/web/.next/standalone/src/presentation/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +2 -2
  248. 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
  249. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_816618e2.js +3 -0
  250. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_ba2e050f.js +3 -0
  251. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  252. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  253. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  254. 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
  255. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  256. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  257. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  258. package/web/.next/{server/chunks/ssr/[root-of-the-server]__e5e09f72._.js → standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js} +2 -2
  259. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  260. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  261. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  262. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_63688261._.js +6 -0
  263. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  264. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  265. package/web/.next/{server/chunks/ssr/src_presentation_web_398553b0._.js → standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_2b91e4ec._.js} +2 -2
  266. package/web/.next/{server/chunks/ssr/src_presentation_web_5c87e8e4._.js → standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5bcc1537._.js} +2 -2
  267. 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
  268. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  269. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  270. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  271. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_d5b0cb86._.js +8 -0
  272. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_e626b63c._.js +8 -0
  273. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  274. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  275. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +175 -118
  276. package/web/.next/standalone/src/presentation/web/CLAUDE.md +191 -0
  277. package/web/.next/standalone/src/presentation/web/app/actions/create-feature.ts +27 -2
  278. package/web/.next/standalone/src/presentation/web/app/actions/get-feature-metadata.ts +18 -0
  279. package/web/.next/standalone/src/presentation/web/app/actions/get-graph-data.ts +12 -0
  280. package/web/.next/standalone/src/presentation/web/app/api/agent-events/route.ts +21 -1
  281. package/web/.next/standalone/src/presentation/web/components/common/add-repository-button/index.ts +1 -0
  282. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx +23 -26
  283. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx +44 -18
  284. package/web/.next/standalone/src/presentation/web/components/common/feature-node/derive-feature-state.ts +2 -0
  285. package/web/.next/standalone/src/presentation/web/components/common/index.ts +1 -5
  286. package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-node.tsx +2 -2
  287. package/web/.next/standalone/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.stories.tsx +0 -13
  288. package/web/.next/standalone/src/presentation/web/components/common/sidebar-section-header/sidebar-section-header.tsx +1 -45
  289. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-empty-state.tsx +1 -1
  290. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +24 -8
  291. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center.stories.tsx +2 -41
  292. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +183 -326
  293. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx +0 -48
  294. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +34 -82
  295. package/web/.next/standalone/src/presentation/web/components/layouts/app-shell/app-shell.tsx +1 -1
  296. package/web/.next/standalone/src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx +2 -14
  297. package/web/.next/standalone/src/presentation/web/components/ui/scroll-area.tsx +1 -1
  298. package/web/.next/standalone/src/presentation/web/hooks/use-graph-state.ts +343 -0
  299. package/web/.next/standalone/src/presentation/web/lib/derive-graph.ts +178 -0
  300. package/web/.next/standalone/src/presentation/web/lib/layout-with-dagre.ts +1 -2
  301. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  302. package/web/.next/static/chunks/{71cf72022f08a8c9.js → 0a883e2efecfd563.js} +1 -1
  303. package/web/.next/static/chunks/{ebf172a84c9596ed.js → 596ca28d78baae25.js} +1 -1
  304. package/web/.next/static/chunks/{1c07b21eb8b32f25.js → 638824249d103905.js} +1 -1
  305. package/web/.next/static/chunks/63a80e9d4c4b0253.js +4 -0
  306. package/web/.next/static/chunks/71c9ecdceac1939f.css +2 -0
  307. package/web/.next/static/chunks/a040b058d79f4ade.js +1 -0
  308. package/web/.next/static/chunks/{fcafb841e3860687.js → c575ab63c138645b.js} +1 -1
  309. package/web/.next/static/chunks/cdc92cdf81005c84.js +1 -0
  310. package/web/.next/static/chunks/{fabfa54940973cc7.js → e05eb1cc84ee254a.js} +1 -1
  311. package/web/.next/static/chunks/{8682dcb376de62de.js → ef8f8940eac6c542.js} +1 -1
  312. package/web/.next/static/chunks/f32c98a709949c5b.js +1 -0
  313. package/web/.next/trace +1 -1
  314. package/web/.next/trace-build +1 -1
  315. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-button.d.ts.map +0 -1
  316. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node-config.d.ts +0 -7
  317. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node-config.d.ts.map +0 -1
  318. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node-config.js +0 -1
  319. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.d.ts +0 -6
  320. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.d.ts.map +0 -1
  321. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.js +0 -23
  322. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.d.ts +0 -10
  323. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.d.ts.map +0 -1
  324. package/dist/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.js +0 -33
  325. package/dist/src/presentation/web/components/common/add-repository-node/index.d.ts +0 -4
  326. package/dist/src/presentation/web/components/common/add-repository-node/index.d.ts.map +0 -1
  327. package/dist/src/presentation/web/components/common/add-repository-node/pick-folder.d.ts.map +0 -1
  328. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +0 -3
  329. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js.map +0 -1
  330. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +0 -3
  331. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js.map +0 -1
  332. package/web/.next/server/chunks/ssr/[root-of-the-server]__cbae9863._.js.map +0 -1
  333. package/web/.next/server/chunks/ssr/[root-of-the-server]__e5e09f72._.js.map +0 -1
  334. package/web/.next/server/chunks/ssr/_47ef589d._.js +0 -6
  335. package/web/.next/server/chunks/ssr/_47ef589d._.js.map +0 -1
  336. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +0 -8
  337. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js.map +0 -1
  338. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +0 -3
  339. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js.map +0 -1
  340. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +0 -8
  341. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js.map +0 -1
  342. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +0 -3
  343. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +0 -3
  344. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_47ef589d._.js +0 -6
  345. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +0 -8
  346. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +0 -3
  347. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +0 -8
  348. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/add-repository-node-config.ts +0 -8
  349. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/add-repository-node.stories.tsx +0 -70
  350. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/add-repository-node.tsx +0 -49
  351. package/web/.next/standalone/src/presentation/web/components/common/add-repository-node/index.ts +0 -3
  352. package/web/.next/static/chunks/3c79bca4d3f18f66.js +0 -1
  353. package/web/.next/static/chunks/5cd24ca47061a21d.js +0 -4
  354. package/web/.next/static/chunks/67f2a7a5e8dc358a.css +0 -2
  355. package/web/.next/static/chunks/991d4490d7a338d8.js +0 -1
  356. package/web/.next/static/chunks/c71589df79020ecb.js +0 -1
  357. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/add-repository-button.d.ts +0 -0
  358. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/add-repository-button.js +0 -0
  359. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/pick-folder.d.ts +0 -0
  360. /package/dist/src/presentation/web/components/common/{add-repository-node → add-repository-button}/pick-folder.js +0 -0
  361. /package/web/.next/standalone/src/presentation/web/components/common/{add-repository-node → add-repository-button}/add-repository-button.tsx +0 -0
  362. /package/web/.next/standalone/src/presentation/web/components/common/{add-repository-node → add-repository-button}/pick-folder.ts +0 -0
  363. /package/web/.next/static/{IKuYPxAuMvc4BtwKHlj30 → uMxPSDPwZCludF5408rWJ}/_buildManifest.js +0 -0
  364. /package/web/.next/static/{IKuYPxAuMvc4BtwKHlj30 → uMxPSDPwZCludF5408rWJ}/_clientMiddlewareManifest.json +0 -0
  365. /package/web/.next/static/{IKuYPxAuMvc4BtwKHlj30 → uMxPSDPwZCludF5408rWJ}/_ssgManifest.js +0 -0
@@ -1,27 +1,19 @@
1
1
  import type { Connection, Edge, NodeChange } from '@xyflow/react';
2
2
  import type { FeatureNodeType } from '../../common/feature-node/index.js';
3
3
  import type { RepositoryNodeType } from '../../common/repository-node/index.js';
4
- import type { AddRepositoryNodeType } from '../../common/add-repository-node/index.js';
5
- export type CanvasNodeType = FeatureNodeType | RepositoryNodeType | AddRepositoryNodeType;
4
+ export type CanvasNodeType = FeatureNodeType | RepositoryNodeType;
6
5
  export interface FeaturesCanvasProps {
7
6
  nodes: CanvasNodeType[];
8
7
  edges: Edge[];
9
8
  selectedFeatureId?: string | null;
10
9
  onNodesChange?: (changes: NodeChange<CanvasNodeType>[]) => void;
11
10
  onAddFeature?: () => void;
12
- onNodeAction?: (nodeId: string) => void;
13
- onNodeSettings?: (nodeId: string) => void;
14
11
  onNodeClick?: (event: React.MouseEvent, node: CanvasNodeType) => void;
15
12
  onPaneClick?: (event: React.MouseEvent) => void;
16
- onRepositoryAdd?: (repoNodeId: string) => void;
17
- onRepositoryClick?: (nodeId: string) => void;
18
- onRepositoryDelete?: (repositoryId: string) => void;
19
- onFeatureDelete?: (featureId: string) => void;
20
13
  onConnect?: (connection: Connection) => void;
21
- onRepositorySelect?: (path: string) => void;
22
14
  onCanvasDrag?: () => void;
23
15
  toolbar?: React.ReactNode;
24
16
  emptyState?: React.ReactNode;
25
17
  }
26
- export declare function FeaturesCanvas({ nodes, edges, selectedFeatureId, onNodesChange, onAddFeature, onNodeAction, onNodeSettings, onConnect, onNodeClick, onPaneClick, onRepositoryAdd, onRepositoryClick, onRepositoryDelete, onFeatureDelete, onRepositorySelect, onCanvasDrag, toolbar, emptyState, }: FeaturesCanvasProps): import("react/jsx-runtime").JSX.Element;
18
+ export declare function FeaturesCanvas({ nodes, edges, selectedFeatureId, onNodesChange, onAddFeature, onConnect, onNodeClick, onPaneClick, onCanvasDrag, toolbar, emptyState, }: FeaturesCanvasProps): import("react/jsx-runtime").JSX.Element;
27
19
  //# sourceMappingURL=features-canvas.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAGrF,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AAE1F,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,SAAS,EACT,WAAW,EACX,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,2CAmIrB"}
1
+ {"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAG9E,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,2CAmGrB"}
@@ -1,19 +1,17 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useCallback, useMemo } from 'react';
4
- import { ReactFlow, Background, Controls, ReactFlowProvider } from '@xyflow/react';
3
+ import { useMemo, useCallback } from 'react';
4
+ import { ReactFlow, Background, Controls } from '@xyflow/react';
5
5
  import { Plus } from 'lucide-react';
6
6
  import { Button } from '../../ui/button.js';
7
7
  import { EmptyState } from '../../common/empty-state/index.js';
8
8
  import { FeatureNode } from '../../common/feature-node/index.js';
9
9
  import { RepositoryNode } from '../../common/repository-node/index.js';
10
- import { AddRepositoryNode } from '../../common/add-repository-node/index.js';
11
10
  import { DependencyEdge } from './dependency-edge.js';
12
- export function FeaturesCanvas({ nodes, edges, selectedFeatureId, onNodesChange, onAddFeature, onNodeAction, onNodeSettings, onConnect, onNodeClick, onPaneClick, onRepositoryAdd, onRepositoryClick, onRepositoryDelete, onFeatureDelete, onRepositorySelect, onCanvasDrag, toolbar, emptyState, }) {
11
+ export function FeaturesCanvas({ nodes, edges, selectedFeatureId, onNodesChange, onAddFeature, onConnect, onNodeClick, onPaneClick, onCanvasDrag, toolbar, emptyState, }) {
13
12
  const nodeTypes = useMemo(() => ({
14
13
  featureNode: FeatureNode,
15
14
  repositoryNode: RepositoryNode,
16
- addRepositoryNode: AddRepositoryNode,
17
15
  }), []);
18
16
  const edgeTypes = useMemo(() => ({
19
17
  dependencyEdge: DependencyEdge,
@@ -29,49 +27,19 @@ export function FeaturesCanvas({ nodes, edges, selectedFeatureId, onNodesChange,
29
27
  });
30
28
  return !targetAlreadyHasRepo;
31
29
  }, [nodes, edges]);
32
- const enrichedNodes = useMemo(() => nodes.map((node) => ({
33
- ...node,
34
- // React Flow passes `selected` as a prop to the node component
35
- ...(node.type === 'featureNode' && {
36
- selected: selectedFeatureId != null &&
37
- node.data.featureId === selectedFeatureId,
38
- }),
39
- data: {
40
- ...node.data,
41
- showHandles: edges.length > 0,
42
- ...(node.type === 'featureNode' && node.data.state !== 'creating'
43
- ? {
44
- onAction: onNodeAction ? () => onNodeAction(node.id) : undefined,
45
- onSettings: onNodeSettings ? () => onNodeSettings(node.id) : undefined,
46
- onDelete: onFeatureDelete,
47
- }
48
- : {}),
49
- ...(node.type === 'repositoryNode' && {
50
- onAdd: onRepositoryAdd ? () => onRepositoryAdd(node.id) : undefined,
51
- onClick: onRepositoryClick ? () => onRepositoryClick(node.id) : undefined,
52
- onDelete: onRepositoryDelete,
53
- }),
54
- ...(node.type === 'addRepositoryNode' && {
55
- onSelect: onRepositorySelect ? (path) => onRepositorySelect(path) : undefined,
56
- }),
57
- },
58
- })), [
59
- nodes,
60
- edges.length,
61
- selectedFeatureId,
62
- onNodeAction,
63
- onNodeSettings,
64
- onFeatureDelete,
65
- onRepositoryAdd,
66
- onRepositoryClick,
67
- onRepositoryDelete,
68
- onRepositorySelect,
69
- ]);
30
+ // Callbacks and showHandles are already injected into node.data by deriveGraph.
31
+ // Only selectedFeatureId highlighting needs to be applied here.
32
+ const enrichedNodes = useMemo(() => selectedFeatureId == null
33
+ ? nodes
34
+ : nodes.map((node) => node.type === 'featureNode' &&
35
+ node.data.featureId === selectedFeatureId
36
+ ? { ...node, selected: true }
37
+ : node), [nodes, selectedFeatureId]);
70
38
  if (nodes.length === 0) {
71
39
  if (emptyState) {
72
40
  return (_jsx("div", { "data-testid": "features-canvas-empty", className: "h-full w-full", children: emptyState }));
73
41
  }
74
42
  return (_jsx("div", { "data-testid": "features-canvas-empty", children: _jsx(EmptyState, { title: "No features yet", description: "Get started by creating your first feature.", action: _jsxs(Button, { onClick: onAddFeature, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "New Feature"] }) }) }));
75
43
  }
76
- return (_jsx("div", { "data-testid": "features-canvas", "data-no-drawer-close": true, className: "pointer-events-auto h-full w-full", children: _jsx(ReactFlowProvider, { children: _jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, isValidConnection: isValidConnection, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, onMoveStart: onCanvasDrag, defaultViewport: { x: 30, y: 30, zoom: 0.85 }, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, children: [_jsx(Background, {}), _jsx(Controls, {}), toolbar] }) }) }));
44
+ return (_jsx("div", { "data-testid": "features-canvas", "data-no-drawer-close": true, className: "pointer-events-auto h-full w-full", children: _jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, isValidConnection: isValidConnection, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, onMoveStart: onCanvasDrag, defaultViewport: { x: 30, y: 30, zoom: 0.85 }, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, children: [_jsx(Background, {}), _jsx(Controls, {}), toolbar] }) }));
77
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"features-canvas.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOnD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAcrC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAwKnC,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAK3B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAK5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAWzB,CAAC;AA4DF,eAAO,MAAM,mCAAmC,EAAE,KAOjD,CAAC;AAkCF,eAAO,MAAM,gCAAgC,EAAE,KAS9C,CAAC;AAgEF,eAAO,MAAM,gCAAgC,EAAE,KAW9C,CAAC;AAuDF,eAAO,MAAM,oBAAoB,EAAE,KAUlC,CAAC;AA2GF,eAAO,MAAM,oCAAoC,EAAE,KAOlD,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KASvC,CAAC"}
1
+ {"version":3,"file":"features-canvas.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMnD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAcrC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAwKnC,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAK3B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAK5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KASzB,CAAC;AAoDF,eAAO,MAAM,mCAAmC,EAAE,KAKjD,CAAC;AA4BF,eAAO,MAAM,gCAAgC,EAAE,KAO9C,CAAC;AA0DF,eAAO,MAAM,gCAAgC,EAAE,KAS9C,CAAC;AAiDF,eAAO,MAAM,oBAAoB,EAAE,KAQlC,CAAC;AAqGF,eAAO,MAAM,oCAAoC,EAAE,KAKlD,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KAMvC,CAAC"}
@@ -208,8 +208,6 @@ export const Interactive = {
208
208
  { id: 'e3-4', source: 'node-3', target: 'node-4' },
209
209
  ],
210
210
  onAddFeature: () => undefined,
211
- onNodeAction: () => undefined,
212
- onNodeSettings: () => undefined,
213
211
  },
214
212
  };
215
213
  const repoNode = {
@@ -220,15 +218,8 @@ const repoNode = {
220
218
  name: 'shep-ai/cli',
221
219
  },
222
220
  };
223
- const addRepoNode = {
224
- id: 'add-repo',
225
- type: 'addRepositoryNode',
226
- position: { x: 50, y: 302 },
227
- data: {},
228
- };
229
221
  const repoFeatureNodes = [
230
222
  repoNode,
231
- addRepoNode,
232
223
  {
233
224
  id: 'feat-1',
234
225
  type: 'featureNode',
@@ -269,8 +260,6 @@ export const ConnectedRepositoryMultipleFeatures = {
269
260
  args: {
270
261
  nodes: repoFeatureNodes,
271
262
  edges: repoFeatureEdges,
272
- onNodeAction: () => undefined,
273
- onNodeSettings: () => undefined,
274
263
  },
275
264
  };
276
265
  // --- Story 1: Single repository connected to a single feature ---
@@ -281,12 +270,6 @@ const singleRepoSingleFeatureNodes = [
281
270
  position: { x: 50, y: 127 },
282
271
  data: { name: 'shep-ai/cli' },
283
272
  },
284
- {
285
- id: 'add-repo',
286
- type: 'addRepositoryNode',
287
- position: { x: 50, y: 267 },
288
- data: {},
289
- },
290
273
  {
291
274
  id: 'feat-1',
292
275
  type: 'featureNode',
@@ -309,8 +292,6 @@ export const ConnectedRepositorySingleFeature = {
309
292
  edges: [
310
293
  { id: 'e-repo-f1', source: 'repo-1', target: 'feat-1', type: 'straight', ...dashedEdge },
311
294
  ],
312
- onNodeAction: () => undefined,
313
- onNodeSettings: () => undefined,
314
295
  },
315
296
  };
316
297
  // --- Story 2: Single repository connected to multiple features (one-to-many) ---
@@ -321,12 +302,6 @@ const singleRepoMultiFeatNodes = [
321
302
  position: { x: 50, y: 162 },
322
303
  data: { name: 'shep-ai/cli' },
323
304
  },
324
- {
325
- id: 'add-repo',
326
- type: 'addRepositoryNode',
327
- position: { x: 50, y: 450 },
328
- data: {},
329
- },
330
305
  {
331
306
  id: 'feat-1',
332
307
  type: 'featureNode',
@@ -381,8 +356,6 @@ export const SingleRepositoryMultipleFeatures = {
381
356
  { id: 'e-r1-f2', source: 'repo-1', target: 'feat-2', ...dashedEdge },
382
357
  { id: 'e-r1-f3', source: 'repo-1', target: 'feat-3', ...dashedEdge },
383
358
  ],
384
- onNodeAction: () => undefined,
385
- onNodeSettings: () => undefined,
386
359
  },
387
360
  };
388
361
  // --- Story 3: Multiple repositories each with their own features ---
@@ -399,12 +372,6 @@ const multiRepoNodes = [
399
372
  position: { x: 50, y: 270 },
400
373
  data: { name: 'shep-ai/web' },
401
374
  },
402
- {
403
- id: 'add-repo',
404
- type: 'addRepositoryNode',
405
- position: { x: 50, y: 470 },
406
- data: {},
407
- },
408
375
  {
409
376
  id: 'feat-1',
410
377
  type: 'featureNode',
@@ -443,8 +410,6 @@ export const MultipleRepositories = {
443
410
  { id: 'e-r1-f1', source: 'repo-1', target: 'feat-1', ...dashedEdge },
444
411
  { id: 'e-r2-f2', source: 'repo-2', target: 'feat-2', ...dashedEdge },
445
412
  ],
446
- onNodeAction: () => undefined,
447
- onNodeSettings: () => undefined,
448
413
  },
449
414
  };
450
415
  // --- Story 4: Multiple repositories with mixed feature connections (dagre layout) ---
@@ -467,12 +432,6 @@ const mixedRepoFeatureNodesRaw = [
467
432
  position: { x: 0, y: 0 },
468
433
  data: { name: 'shep-ai/api' },
469
434
  },
470
- {
471
- id: 'add-repo',
472
- type: 'addRepositoryNode',
473
- position: { x: 0, y: 0 },
474
- data: {},
475
- },
476
435
  {
477
436
  id: 'feat-1',
478
437
  type: 'featureNode',
@@ -548,8 +507,6 @@ export const MultipleRepositoriesMixedConnections = {
548
507
  args: {
549
508
  nodes: mixedLayoutedNodes,
550
509
  edges: mixedLayoutedEdges,
551
- onNodeAction: () => undefined,
552
- onNodeSettings: () => undefined,
553
510
  },
554
511
  };
555
512
  export const InteractiveWithRepository = {
@@ -557,8 +514,5 @@ export const InteractiveWithRepository = {
557
514
  nodes: repoFeatureNodes,
558
515
  edges: repoFeatureEdges,
559
516
  onAddFeature: () => undefined,
560
- onNodeAction: () => undefined,
561
- onNodeSettings: () => undefined,
562
- onRepositoryAdd: () => undefined,
563
517
  },
564
518
  };
@@ -4,7 +4,7 @@ import { useCallback } from 'react';
4
4
  import { useRouter } from 'next/navigation';
5
5
  import { SidebarProvider, SidebarInset } from '../../ui/sidebar.js';
6
6
  import { AppSidebar } from '../../layouts/app-sidebar/index.js';
7
- import { AddRepositoryButton } from '../../common/add-repository-node/index.js';
7
+ import { AddRepositoryButton } from '../../common/add-repository-button/index.js';
8
8
  import { ThemeToggle } from '../../common/theme-toggle/index.js';
9
9
  import { SoundToggle } from '../../common/sound-toggle/index.js';
10
10
  import { AgentEventsProvider } from '../../../hooks/agent-events-provider.js';
@@ -10,8 +10,6 @@ export interface AppSidebarProps {
10
10
  features: FeatureItem[];
11
11
  onNewFeature?: () => void;
12
12
  onFeatureClick?: (featureId: string) => void;
13
- onFeaturesFolderClick?: () => void;
14
- onFeaturesMenuClick?: () => void;
15
13
  }
16
- export declare function AppSidebar({ features, onNewFeature, onFeatureClick, onFeaturesFolderClick, onFeaturesMenuClick, }: AppSidebarProps): import("react/jsx-runtime").JSX.Element;
14
+ export declare function AppSidebar({ features, onNewFeature, onFeatureClick }: AppSidebarProps): import("react/jsx-runtime").JSX.Element;
17
15
  //# sourceMappingURL=app-sidebar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAI/E,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;CAClC;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,mBAAmB,GACpB,EAAE,eAAe,2CAyGjB"}
1
+ {"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAI/E,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,eAAe,2CAqGrF"}
@@ -13,7 +13,7 @@ import { SidebarSectionHeader } from '../../common/sidebar-section-header/index.
13
13
  import { featureStatusConfig, featureStatusOrder } from '../../common/feature-status-config.js';
14
14
  import { useDeferredMount } from '../../../hooks/use-deferred-mount.js';
15
15
  import { featureFlags } from '../../../lib/feature-flags.js';
16
- export function AppSidebar({ features, onNewFeature, onFeatureClick, onFeaturesFolderClick, onFeaturesMenuClick, }) {
16
+ export function AppSidebar({ features, onNewFeature, onFeatureClick }) {
17
17
  const pathname = usePathname();
18
18
  const { state } = useSidebar();
19
19
  const collapsed = state === 'collapsed';
@@ -31,5 +31,5 @@ export function AppSidebar({ features, onNewFeature, onFeatureClick, onFeaturesF
31
31
  'min-w-0 overflow-hidden transition-opacity duration-200 ease-out',
32
32
  '[&_[data-sidebar=group-label]]:!mt-0 [&_[data-sidebar=group-label]]:!opacity-100 [&_[data-sidebar=group-label]]:!transition-none',
33
33
  expandedVisible ? 'opacity-100' : 'opacity-0',
34
- ].join(' '), children: [_jsx(SidebarSectionHeader, { label: "Features", onFolderClick: onFeaturesFolderClick, onMenuClick: onFeaturesMenuClick }), _jsx(ScrollArea, { children: grouped.map(({ key, label, items }) => items.length > 0 ? (_jsx(FeatureStatusGroup, { label: label, count: items.length, children: items.map((feature) => (_jsx(FeatureListItem, { name: feature.name, status: feature.status, startedAt: feature.startedAt, duration: feature.duration, onClick: onFeatureClick ? () => onFeatureClick(feature.featureId) : undefined }, feature.featureId))) }, key)) : null) })] })) : null }), _jsx(SidebarFooter, { children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { onClick: onNewFeature, tooltip: "New feature", children: [_jsx(Plus, {}), _jsx("span", { children: "New feature" })] }) }) }) }), _jsx(SidebarRail, {})] }));
34
+ ].join(' '), children: [_jsx(SidebarSectionHeader, { label: "Features" }), _jsx(ScrollArea, { children: grouped.map(({ key, label, items }) => items.length > 0 ? (_jsx(FeatureStatusGroup, { label: label, count: items.length, children: items.map((feature) => (_jsx(FeatureListItem, { name: feature.name, status: feature.status, startedAt: feature.startedAt, duration: feature.duration, onClick: onFeatureClick ? () => onFeatureClick(feature.featureId) : undefined }, feature.featureId))) }, key)) : null) })] })) : null }), _jsx(SidebarFooter, { children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { onClick: onNewFeature, tooltip: "New feature", children: [_jsx(Plus, {}), _jsx("span", { children: "New feature" })] }) }) }) }), _jsx(SidebarRail, {})] }));
35
35
  }
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { ScrollArea as ScrollAreaPrimitive } from 'radix-ui';
4
4
  import { cn } from '../../lib/utils.js';
5
5
  function ScrollArea({ className, children, ...props }) {
6
- return (_jsxs(ScrollAreaPrimitive.Root, { "data-slot": "scroll-area", className: cn('relative', className), ...props, children: [_jsx(ScrollAreaPrimitive.Viewport, { "data-slot": "scroll-area-viewport", className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1", children: children }), _jsx(ScrollBar, {}), _jsx(ScrollAreaPrimitive.Corner, {})] }));
6
+ return (_jsxs(ScrollAreaPrimitive.Root, { "data-slot": "scroll-area", className: cn('relative', className), ...props, children: [_jsx(ScrollAreaPrimitive.Viewport, { "data-slot": "scroll-area-viewport", className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&>div]:block!", children: children }), _jsx(ScrollBar, {}), _jsx(ScrollAreaPrimitive.Corner, {})] }));
7
7
  }
8
8
  function ScrollBar({ className, orientation = 'vertical', ...props }) {
9
9
  return (_jsx(ScrollAreaPrimitive.ScrollAreaScrollbar, { "data-slot": "scroll-area-scrollbar", orientation: orientation, className: cn('flex touch-none p-px transition-colors select-none', orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent', orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent', className), ...props, children: _jsx(ScrollAreaPrimitive.ScrollAreaThumb, { "data-slot": "scroll-area-thumb", className: "bg-border relative flex-1 rounded-full" }) }));
@@ -0,0 +1,41 @@
1
+ import type { Edge } from '@xyflow/react';
2
+ import type { CanvasNodeType } from '../components/features/features-canvas/index.js';
3
+ import type { FeatureNodeData } from '../components/common/feature-node/index.js';
4
+ import type { RepositoryNodeData } from '../components/common/repository-node/index.js';
5
+ import { type FeatureEntry, type GraphCallbacks } from '../lib/derive-graph.js';
6
+ export type { GraphCallbacks } from '../lib/derive-graph.js';
7
+ export interface UseGraphStateReturn {
8
+ /** Derived React Flow nodes (from domain Maps). */
9
+ nodes: CanvasNodeType[];
10
+ /** Derived React Flow edges (from domain Maps). */
11
+ edges: Edge[];
12
+ /**
13
+ * Reconcile domain Maps with fresh server data (new initialNodes/initialEdges).
14
+ * Preserves pending (creating) nodes unless a matching real feature appears.
15
+ */
16
+ reconcile: (newNodes: CanvasNodeType[], newEdges: Edge[]) => void;
17
+ /** Update a feature's state/lifecycle/name (e.g., from SSE events). */
18
+ updateFeature: (featureNodeId: string, updates: Partial<Pick<FeatureNodeData, 'state' | 'lifecycle' | 'name' | 'description'>>) => void;
19
+ /** Add a pending (optimistic) feature node (state='creating'). */
20
+ addPendingFeature: (nodeId: string, data: FeatureNodeData, parentNodeId?: string) => void;
21
+ /** Remove a pending feature node (e.g., on rollback). */
22
+ removePendingFeature: (nodeId: string) => void;
23
+ /** Remove a real feature node from the domain Map. */
24
+ removeFeature: (nodeId: string) => void;
25
+ /** Restore a previously removed feature (rollback). */
26
+ restoreFeature: (nodeId: string, entry: FeatureEntry) => void;
27
+ /** Add a repository node (may use a temp ID initially). */
28
+ addRepository: (nodeId: string, data: RepositoryNodeData) => void;
29
+ /** Remove a repository node. */
30
+ removeRepository: (nodeId: string) => void;
31
+ /** Replace a temp repo ID with the real one (atomic). */
32
+ replaceRepository: (tempId: string, realId: string, data: RepositoryNodeData) => void;
33
+ /** Stable lookup: get the repositoryPath for a feature node. */
34
+ getFeatureRepositoryPath: (featureNodeId: string) => string | undefined;
35
+ /** Stable lookup: get repository node data by nodeId. */
36
+ getRepositoryData: (nodeId: string) => RepositoryNodeData | undefined;
37
+ /** Update callbacks injected into node data (does NOT trigger re-render). */
38
+ setCallbacks: (callbacks: GraphCallbacks) => void;
39
+ }
40
+ export declare function useGraphState(initialNodes: CanvasNodeType[], initialEdges: Edge[]): UseGraphStateReturn;
41
+ //# sourceMappingURL=use-graph-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-graph-state.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-graph-state.ts"],"names":[],"mappings":"AAGA,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,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,mDAAmD;IACnD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;OAGG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAClE,uEAAuE;IACvE,aAAa,EAAE,CACb,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC,CAAC,KACpF,IAAI,CAAC;IACV,kEAAkE;IAClE,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1F,yDAAyD;IACzD,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sDAAsD;IACtD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uDAAuD;IACvD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9D,2DAA2D;IAC3D,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAClE,gCAAgC;IAChC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACtF,gEAAgE;IAChE,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,6EAA6E;IAC7E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAuCD,wBAAgB,aAAa,CAC3B,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,mBAAmB,CAwPrB"}
@@ -0,0 +1,230 @@
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' || edge.id.startsWith('dep-')) {
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
+ export function useGraphState(initialNodes, initialEdges) {
34
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- intentional: parse only on mount (like useState initializer)
35
+ const init = useMemo(() => parseMaps(initialNodes, initialEdges), []);
36
+ const [featureMap, setFeatureMap] = useState(init.featureMap);
37
+ const [repoMap, setRepoMap] = useState(init.repoMap);
38
+ const [pendingMap, setPendingMap] = useState(new Map());
39
+ // Buffer for SSE updates that arrive before their feature is in featureMap.
40
+ // When reconcile adds new features, buffered updates are applied automatically.
41
+ const pendingUpdatesRef = useRef(new Map());
42
+ // Callbacks stored in a ref so changing them doesn't trigger re-render.
43
+ // The stable wrapper object reads from the ref so node closures always use latest callbacks.
44
+ const callbacksRef = useRef({});
45
+ const stableCallbacks = useMemo(() => ({
46
+ onNodeAction: (nodeId) => callbacksRef.current.onNodeAction?.(nodeId),
47
+ onNodeSettings: (nodeId) => callbacksRef.current.onNodeSettings?.(nodeId),
48
+ onFeatureDelete: (featureId) => callbacksRef.current.onFeatureDelete?.(featureId),
49
+ onRepositoryAdd: (nodeId) => callbacksRef.current.onRepositoryAdd?.(nodeId),
50
+ onRepositoryClick: (nodeId) => callbacksRef.current.onRepositoryClick?.(nodeId),
51
+ onRepositoryDelete: (repositoryId) => callbacksRef.current.onRepositoryDelete?.(repositoryId),
52
+ }), []);
53
+ // Stable refs for domain Maps (for use in callbacks without depending on state)
54
+ const featureMapRef = useRef(featureMap);
55
+ featureMapRef.current = featureMap;
56
+ const repoMapRef = useRef(repoMap);
57
+ repoMapRef.current = repoMap;
58
+ // Derived nodes/edges — only re-runs when domain Maps change (not callbacks)
59
+ const { nodes, edges } = useMemo(() => {
60
+ const derived = deriveGraph(featureMap, repoMap, pendingMap, stableCallbacks);
61
+ return layoutWithDagre(derived.nodes, derived.edges, CANVAS_LAYOUT_DEFAULTS);
62
+ }, [featureMap, repoMap, pendingMap, stableCallbacks]);
63
+ // --- Mutations ---
64
+ const reconcile = useCallback((newNodes, newEdges) => {
65
+ const { featureMap: newFeatureMap, repoMap: newRepoMap } = parseMaps(newNodes, newEdges);
66
+ setFeatureMap((currentFeatureMap) => {
67
+ // Preserve pending (creating) nodes unless matched by name+repositoryPath from newFeatureMap
68
+ const pendingEntries = [...currentFeatureMap.entries()].filter(([, e]) => e.data.state === 'creating');
69
+ const merged = new Map(newFeatureMap);
70
+ // Keep pending nodes that don't have a real counterpart in new data
71
+ for (const [tempId, pendingEntry] of pendingEntries) {
72
+ const matched = [...newFeatureMap.values()].some((e) => e.data.name === pendingEntry.data.name &&
73
+ e.data.repositoryPath === pendingEntry.data.repositoryPath);
74
+ if (!matched) {
75
+ merged.set(tempId, pendingEntry);
76
+ }
77
+ }
78
+ // Apply any buffered SSE updates to features that now exist in the map
79
+ for (const [nodeId, updates] of pendingUpdatesRef.current) {
80
+ const entry = merged.get(nodeId);
81
+ if (entry) {
82
+ merged.set(nodeId, { ...entry, data: { ...entry.data, ...updates } });
83
+ pendingUpdatesRef.current.delete(nodeId);
84
+ }
85
+ }
86
+ return merged;
87
+ });
88
+ // Clean pendingMap entries that now have a real counterpart in server data
89
+ setPendingMap((currentPendingMap) => {
90
+ if (currentPendingMap.size === 0)
91
+ return currentPendingMap;
92
+ let changed = false;
93
+ const next = new Map(currentPendingMap);
94
+ for (const [tempId, pendingEntry] of currentPendingMap) {
95
+ const matched = [...newFeatureMap.values()].some((e) => e.data.name === pendingEntry.data.name &&
96
+ e.data.repositoryPath === pendingEntry.data.repositoryPath);
97
+ if (matched) {
98
+ next.delete(tempId);
99
+ changed = true;
100
+ }
101
+ }
102
+ return changed ? next : currentPendingMap;
103
+ });
104
+ setRepoMap(newRepoMap);
105
+ }, []);
106
+ const updateFeature = useCallback((featureNodeId, updates) => {
107
+ setFeatureMap((prev) => {
108
+ const entry = prev.get(featureNodeId);
109
+ if (!entry) {
110
+ // Feature not yet in map — buffer update for when reconcile adds it
111
+ pendingUpdatesRef.current.set(featureNodeId, {
112
+ ...pendingUpdatesRef.current.get(featureNodeId),
113
+ ...updates,
114
+ });
115
+ return prev;
116
+ }
117
+ // Clear any buffered update for this feature since it's now in the map
118
+ pendingUpdatesRef.current.delete(featureNodeId);
119
+ // Skip if no actual change (prevents unnecessary re-renders on event replay)
120
+ const stateUnchanged = updates.state === undefined || updates.state === entry.data.state;
121
+ const lifecycleUnchanged = updates.lifecycle === undefined || updates.lifecycle === entry.data.lifecycle;
122
+ const nameUnchanged = updates.name === undefined || updates.name === entry.data.name;
123
+ const descUnchanged = updates.description === undefined || updates.description === entry.data.description;
124
+ if (stateUnchanged && lifecycleUnchanged && nameUnchanged && descUnchanged) {
125
+ return prev;
126
+ }
127
+ const next = new Map(prev);
128
+ next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
129
+ return next;
130
+ });
131
+ // Also check pendingMap
132
+ setPendingMap((prev) => {
133
+ const entry = prev.get(featureNodeId);
134
+ if (!entry)
135
+ return prev;
136
+ const stateUnchanged = updates.state === undefined || updates.state === entry.data.state;
137
+ const lifecycleUnchanged = updates.lifecycle === undefined || updates.lifecycle === entry.data.lifecycle;
138
+ const nameUnchanged = updates.name === undefined || updates.name === entry.data.name;
139
+ const descUnchanged = updates.description === undefined || updates.description === entry.data.description;
140
+ if (stateUnchanged && lifecycleUnchanged && nameUnchanged && descUnchanged)
141
+ return prev;
142
+ const next = new Map(prev);
143
+ next.set(featureNodeId, { ...entry, data: { ...entry.data, ...updates } });
144
+ return next;
145
+ });
146
+ }, []);
147
+ const addPendingFeature = useCallback((nodeId, data, parentNodeId) => {
148
+ setPendingMap((prev) => {
149
+ const next = new Map(prev);
150
+ next.set(nodeId, { nodeId, data, parentNodeId });
151
+ return next;
152
+ });
153
+ }, []);
154
+ const removePendingFeature = useCallback((nodeId) => {
155
+ setPendingMap((prev) => {
156
+ if (!prev.has(nodeId))
157
+ return prev;
158
+ const next = new Map(prev);
159
+ next.delete(nodeId);
160
+ return next;
161
+ });
162
+ }, []);
163
+ const removeFeature = useCallback((nodeId) => {
164
+ setFeatureMap((prev) => {
165
+ if (!prev.has(nodeId))
166
+ return prev;
167
+ const next = new Map(prev);
168
+ next.delete(nodeId);
169
+ return next;
170
+ });
171
+ }, []);
172
+ const restoreFeature = useCallback((nodeId, entry) => {
173
+ setFeatureMap((prev) => {
174
+ const next = new Map(prev);
175
+ next.set(nodeId, entry);
176
+ return next;
177
+ });
178
+ }, []);
179
+ const addRepository = useCallback((nodeId, data) => {
180
+ setRepoMap((prev) => {
181
+ const next = new Map(prev);
182
+ next.set(nodeId, { nodeId, data });
183
+ return next;
184
+ });
185
+ }, []);
186
+ const removeRepository = useCallback((nodeId) => {
187
+ setRepoMap((prev) => {
188
+ if (!prev.has(nodeId))
189
+ return prev;
190
+ const next = new Map(prev);
191
+ next.delete(nodeId);
192
+ return next;
193
+ });
194
+ }, []);
195
+ const replaceRepository = useCallback((tempId, realId, data) => {
196
+ setRepoMap((prev) => {
197
+ if (!prev.has(tempId))
198
+ return prev;
199
+ const next = new Map(prev);
200
+ next.delete(tempId);
201
+ next.set(realId, { nodeId: realId, data });
202
+ return next;
203
+ });
204
+ }, []);
205
+ const getFeatureRepositoryPath = useCallback((featureNodeId) => {
206
+ return featureMapRef.current.get(featureNodeId)?.data.repositoryPath;
207
+ }, []);
208
+ const getRepositoryData = useCallback((nodeId) => {
209
+ return repoMapRef.current.get(nodeId)?.data;
210
+ }, []);
211
+ const setCallbacks = useCallback((callbacks) => {
212
+ callbacksRef.current = callbacks;
213
+ }, []);
214
+ return {
215
+ nodes,
216
+ edges,
217
+ reconcile,
218
+ updateFeature,
219
+ addPendingFeature,
220
+ removePendingFeature,
221
+ removeFeature,
222
+ restoreFeature,
223
+ addRepository,
224
+ removeRepository,
225
+ replaceRepository,
226
+ getFeatureRepositoryPath,
227
+ getRepositoryData,
228
+ setCallbacks,
229
+ };
230
+ }
@@ -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