@shepai/cli 1.72.6-pr187.fb842c5 → 1.72.7

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 (282) hide show
  1. package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts +4 -0
  2. package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.js +20 -12
  4. package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts +8 -3
  5. package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts.map +1 -1
  6. package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.js +17 -4
  7. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +1 -1
  8. package/dist/packages/core/src/infrastructure/services/tool-installer/tool-metadata.d.ts.map +1 -1
  9. package/dist/packages/core/src/infrastructure/services/tool-installer/tool-metadata.js +0 -5
  10. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  11. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +2 -6
  12. package/dist/src/presentation/web/app/api/tools/[id]/install/route.d.ts.map +1 -1
  13. package/dist/src/presentation/web/app/api/tools/[id]/install/route.js +4 -9
  14. package/dist/src/presentation/web/app/build-graph-nodes.js +11 -1
  15. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts +3 -1
  16. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -1
  17. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +8 -4
  18. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
  19. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +12 -3
  20. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  21. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +6 -2
  22. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -1
  23. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +1 -1
  24. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  25. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +1 -1
  26. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  27. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +7 -2
  28. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  29. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +6 -2
  30. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  31. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +14 -2
  32. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -5
  33. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  34. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +131 -196
  35. package/dist/src/presentation/web/components/ui/alert-dialog.d.ts +1 -1
  36. package/dist/src/presentation/web/components/ui/alert-dialog.d.ts.map +1 -1
  37. package/dist/src/presentation/web/components/ui/alert-dialog.js +7 -2
  38. package/dist/src/presentation/web/components/ui/dialog.d.ts.map +1 -1
  39. package/dist/src/presentation/web/components/ui/dialog.js +6 -1
  40. package/dist/src/presentation/web/lib/layout-with-dagre.d.ts +2 -0
  41. package/dist/src/presentation/web/lib/layout-with-dagre.d.ts.map +1 -1
  42. package/dist/src/presentation/web/lib/layout-with-dagre.js +86 -4
  43. package/dist/tsconfig.build.tsbuildinfo +1 -1
  44. package/package.json +1 -1
  45. package/web/.next/BUILD_ID +1 -1
  46. package/web/.next/build-manifest.json +2 -2
  47. package/web/.next/cache/.previewinfo +1 -1
  48. package/web/.next/cache/.rscinfo +1 -1
  49. package/web/.next/cache/.tsbuildinfo +1 -1
  50. package/web/.next/cache/config.json +3 -3
  51. package/web/.next/fallback-build-manifest.json +2 -2
  52. package/web/.next/prerender-manifest.json +3 -3
  53. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +14 -14
  54. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  55. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  56. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  57. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +17 -17
  58. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  59. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  60. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  61. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  62. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  63. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  64. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +14 -14
  66. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  67. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  68. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  69. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +17 -17
  70. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  71. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  72. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  73. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +12 -12
  74. package/web/.next/server/app/(dashboard)/page.js +1 -1
  75. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  76. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  77. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  78. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  79. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  80. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  81. package/web/.next/server/app/_global-error.html +2 -2
  82. package/web/.next/server/app/_global-error.rsc +1 -1
  83. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  84. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  85. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  86. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  87. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  88. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  89. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  90. package/web/.next/server/app/api/tools/[id]/install/route.js +1 -1
  91. package/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -1
  92. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  93. package/web/.next/server/app/skills/page.js +1 -1
  94. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  95. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  96. package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  97. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  98. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  99. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  100. package/web/.next/server/chunks/[root-of-the-server]__b1f03347._.js +3 -0
  101. package/web/.next/server/chunks/[root-of-the-server]__b1f03347._.js.map +1 -0
  102. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  103. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  104. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +1 -1
  105. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js.map +1 -1
  106. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +1 -1
  107. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js.map +1 -1
  108. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js → server/chunks/ssr/[root-of-the-server]__07385073._.js} +3 -3
  109. package/web/.next/server/chunks/ssr/{[root-of-the-server]__45dbf93d._.js.map → [root-of-the-server]__07385073._.js.map} +1 -1
  110. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  111. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  113. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  114. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +3 -0
  115. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -0
  116. package/web/.next/server/chunks/ssr/[root-of-the-server]__6db85a66._.js +4 -0
  117. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  118. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  119. package/web/.next/server/chunks/ssr/[root-of-the-server]__8c1a3d66._.js +3 -0
  120. package/web/.next/server/chunks/ssr/{[root-of-the-server]__aef6b3cd._.js.map → [root-of-the-server]__8c1a3d66._.js.map} +1 -1
  121. package/web/.next/server/chunks/ssr/{[root-of-the-server]__f182fa1e._.js → [root-of-the-server]__8fcb9132._.js} +3 -3
  122. package/web/.next/server/chunks/ssr/[root-of-the-server]__8fcb9132._.js.map +1 -0
  123. package/web/.next/server/chunks/ssr/_00e6c698._.js +1 -1
  124. package/web/.next/server/chunks/ssr/_00e6c698._.js.map +1 -1
  125. package/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
  126. package/web/.next/server/chunks/ssr/_07c2a32a._.js.map +1 -1
  127. package/web/.next/server/chunks/ssr/_34a58db8._.js +1 -1
  128. package/web/.next/server/chunks/ssr/_34a58db8._.js.map +1 -1
  129. package/web/.next/server/chunks/ssr/_37259405._.js +1 -1
  130. package/web/.next/server/chunks/ssr/_37259405._.js.map +1 -1
  131. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/_85d0351b._.js → server/chunks/ssr/_63bfa7dd._.js} +2 -2
  132. package/web/.next/server/chunks/ssr/_63bfa7dd._.js.map +1 -0
  133. package/web/.next/server/chunks/ssr/{_7a259f2c._.js → _7215bb0f._.js} +2 -2
  134. package/web/.next/server/chunks/ssr/{_7a259f2c._.js.map → _7215bb0f._.js.map} +1 -1
  135. package/web/.next/server/chunks/ssr/_cb5b3951._.js +1 -1
  136. package/web/.next/server/chunks/ssr/_cb5b3951._.js.map +1 -1
  137. package/web/.next/server/chunks/ssr/_fc3a6895._.js +1 -1
  138. package/web/.next/server/chunks/ssr/_fc3a6895._.js.map +1 -1
  139. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +2 -2
  140. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js.map +1 -1
  141. package/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js +1 -1
  142. package/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js.map +1 -1
  143. package/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js +1 -1
  144. package/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js.map +1 -1
  145. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +1 -1
  146. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js.map +1 -1
  147. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +2 -2
  148. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js.map +1 -1
  149. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  150. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  151. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  152. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  153. package/web/.next/server/pages/500.html +2 -2
  154. package/web/.next/server/server-reference-manifest.js +1 -1
  155. package/web/.next/server/server-reference-manifest.json +20 -20
  156. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  157. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  158. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  159. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +14 -14
  160. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  161. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  162. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  163. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +17 -17
  164. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  165. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  166. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  167. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  168. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  169. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  170. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  171. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +14 -14
  172. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js +1 -1
  173. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  174. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  175. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +17 -17
  176. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  177. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  178. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  179. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +12 -12
  180. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js +1 -1
  181. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  182. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  183. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  184. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  185. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  186. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  187. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  188. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  189. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  190. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  191. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  192. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  193. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  194. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  195. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  196. package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js +1 -1
  197. package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -1
  198. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  199. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js +1 -1
  200. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
  201. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  202. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  203. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  204. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  205. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  206. package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__b1f03347._.js +3 -0
  207. 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
  208. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +1 -1
  209. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +1 -1
  210. package/web/.next/{server/chunks/ssr/[root-of-the-server]__45dbf93d._.js → standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js} +3 -3
  211. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  212. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  213. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +3 -0
  214. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6db85a66._.js +4 -0
  215. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  216. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__8c1a3d66._.js +3 -0
  217. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{[root-of-the-server]__f182fa1e._.js → [root-of-the-server]__8fcb9132._.js} +3 -3
  218. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_00e6c698._.js +1 -1
  219. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
  220. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_34a58db8._.js +1 -1
  221. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_37259405._.js +1 -1
  222. package/web/.next/{server/chunks/ssr/_85d0351b._.js → standalone/src/presentation/web/.next/server/chunks/ssr/_63bfa7dd._.js} +2 -2
  223. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_7a259f2c._.js → _7215bb0f._.js} +2 -2
  224. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_cb5b3951._.js +1 -1
  225. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_fc3a6895._.js +1 -1
  226. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +2 -2
  227. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js +1 -1
  228. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js +1 -1
  229. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +1 -1
  230. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +2 -2
  231. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  232. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  233. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  234. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  235. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +20 -20
  236. package/web/.next/standalone/src/presentation/web/app/(dashboard)/get-graph-data.ts +2 -6
  237. package/web/.next/standalone/src/presentation/web/app/api/tools/[id]/install/route.ts +6 -14
  238. package/web/.next/standalone/src/presentation/web/app/build-graph-nodes.ts +14 -1
  239. package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx +10 -8
  240. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx +13 -3
  241. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx +6 -2
  242. package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx +2 -0
  243. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +8 -5
  244. package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.tsx +30 -24
  245. package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-node.tsx +33 -25
  246. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +25 -3
  247. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +184 -230
  248. package/web/.next/standalone/src/presentation/web/components/ui/alert-dialog.tsx +7 -0
  249. package/web/.next/standalone/src/presentation/web/components/ui/dialog.tsx +7 -1
  250. package/web/.next/standalone/src/presentation/web/lib/layout-with-dagre.ts +93 -4
  251. package/web/.next/static/chunks/0c54314c8c9c9739.js +7 -0
  252. package/web/.next/static/chunks/{5f5c607ffae8b918.js → 304c8593d0a6525d.js} +1 -1
  253. package/web/.next/static/chunks/4558d1663c6f4d2c.js +1 -0
  254. package/web/.next/static/chunks/{c132a0a46d27747c.js → 4df07e765b233622.js} +1 -1
  255. package/web/.next/static/chunks/{fcdedd892adde5ec.js → 585ae19c520e8b72.js} +1 -1
  256. package/web/.next/static/chunks/{49dc58443f686e6f.js → 6e14d8bd5c005e6e.js} +1 -1
  257. package/web/.next/static/chunks/{81fe6a4ff82e2424.js → 8a1eb93510e54db0.js} +1 -1
  258. package/web/.next/static/chunks/b143c7d78a6888e9.js +1 -0
  259. package/web/.next/static/chunks/{69a1d86331a90aee.js → b45344579a43cbb8.js} +1 -1
  260. package/web/.next/static/chunks/dec13bccb136ef7c.css +2 -0
  261. package/web/.next/static/chunks/e4522f7d3134eefe.js +1 -0
  262. package/web/.next/static/chunks/{c59059bb396f7d27.js → fe83a799663fd3cc.js} +1 -1
  263. package/web/.next/trace +1 -1
  264. package/web/.next/trace-build +1 -1
  265. package/web/.next/server/chunks/[root-of-the-server]__0866d2b5._.js +0 -3
  266. package/web/.next/server/chunks/[root-of-the-server]__0866d2b5._.js.map +0 -1
  267. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +0 -3
  268. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +0 -1
  269. package/web/.next/server/chunks/ssr/[root-of-the-server]__aef6b3cd._.js +0 -3
  270. package/web/.next/server/chunks/ssr/_85d0351b._.js.map +0 -1
  271. package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__0866d2b5._.js +0 -3
  272. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +0 -3
  273. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aef6b3cd._.js +0 -3
  274. package/web/.next/static/chunks/06dfd668334ffb4e.js +0 -7
  275. package/web/.next/static/chunks/224ed5f5dbd33154.css +0 -2
  276. package/web/.next/static/chunks/570802c159d4f3c0.js +0 -1
  277. package/web/.next/static/chunks/577fb9c5d5c1c99f.js +0 -1
  278. package/web/.next/static/chunks/e44849eb58a3335f.js +0 -1
  279. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__f182fa1e._.js.map → [root-of-the-server]__6db85a66._.js.map} +0 -0
  280. /package/web/.next/static/{8XK3vr1tAio-lA1vztJt6 → 9bO_bJBssG0NRxEG03iM5}/_buildManifest.js +0 -0
  281. /package/web/.next/static/{8XK3vr1tAio-lA1vztJt6 → 9bO_bJBssG0NRxEG03iM5}/_clientMiddlewareManifest.json +0 -0
  282. /package/web/.next/static/{8XK3vr1tAio-lA1vztJt6 → 9bO_bJBssG0NRxEG03iM5}/_ssgManifest.js +0 -0
@@ -15,8 +15,8 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
15
15
  const pathname = usePathname();
16
16
  const selectedFeatureId = useSelectedFeatureId();
17
17
  const clickSound = useSoundAction('click');
18
- const { guardedNavigate, getIsDirty } = useDrawerCloseGuard();
19
- const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleDeleteRepository, createFeatureNode, } = useControlCenterState(initialNodes, initialEdges, getIsDirty);
18
+ const { guardedNavigate } = useDrawerCloseGuard();
19
+ const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleDeleteRepository, createFeatureNode, } = useControlCenterState(initialNodes, initialEdges);
20
20
  // Publish sidebar features to context whenever feature node data changes
21
21
  const { setFeatures: setSidebarFeatures } = useSidebarFeaturesContext();
22
22
  const sidebarKey = useMemo(() => {
@@ -116,6 +116,18 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
116
116
  useEffect(() => {
117
117
  const handler = (e) => {
118
118
  const detail = e.detail;
119
+ // When a parentId is provided, connect to the parent feature node
120
+ // via a dependency edge instead of the repo node.
121
+ if (detail.parentId) {
122
+ const parentNodeId = `feat-${detail.parentId}`;
123
+ createFeatureNode(parentNodeId, {
124
+ state: 'creating',
125
+ name: detail.name,
126
+ description: detail.description,
127
+ repositoryPath: detail.repositoryPath,
128
+ }, 'dependencyEdge');
129
+ return;
130
+ }
119
131
  // Find the repo node to connect to
120
132
  const repoNode = nodes.find((n) => n.type === 'repositoryNode' &&
121
133
  n.data.repositoryPath === detail.repositoryPath);
@@ -9,11 +9,9 @@ export interface ControlCenterState {
9
9
  handleConnect: (connection: Connection) => void;
10
10
  handleAddRepository: (path: string) => void;
11
11
  handleLayout: (direction: LayoutDirection) => void;
12
- handleDeleteFeature: (featureId: string) => Promise<void>;
12
+ handleDeleteFeature: (featureId: string) => void;
13
13
  handleDeleteRepository: (repositoryId: string) => Promise<void>;
14
- createFeatureNode: (sourceNodeId: string | null, dataOverride?: Partial<FeatureNodeData>) => string;
14
+ createFeatureNode: (sourceNodeId: string | null, dataOverride?: Partial<FeatureNodeData>, edgeType?: string) => string;
15
15
  }
16
- export declare function useControlCenterState(initialNodes: CanvasNodeType[], initialEdges: Edge[],
17
- /** When true, background router.refresh() calls (polling / SSE debounce) are suppressed. */
18
- isRefreshBlocked?: () => boolean): ControlCenterState;
16
+ export declare function useControlCenterState(initialNodes: CanvasNodeType[], initialEdges: Edge[]): ControlCenterState;
19
17
  //# sourceMappingURL=use-control-center-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAWhF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,KACpC,MAAM,CAAC;CACb;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE;AACpB,4FAA4F;AAC5F,gBAAgB,CAAC,EAAE,MAAM,OAAO,GAC/B,kBAAkB,CAgiBpB"}
1
+ {"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAWjC,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;CACb;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CA+epB"}
@@ -3,7 +3,7 @@ import { useState, useCallback, useEffect, useRef } from 'react';
3
3
  import { useRouter } from 'next/navigation';
4
4
  import { toast } from 'sonner';
5
5
  import { applyNodeChanges } from '@xyflow/react';
6
- import { layoutWithDagre } from '../../../lib/layout-with-dagre.js';
6
+ import { layoutWithDagre, CANVAS_LAYOUT_DEFAULTS, } from '../../../lib/layout-with-dagre.js';
7
7
  import { deleteFeature } from '../../../app/actions/delete-feature.js';
8
8
  import { addRepository } from '../../../app/actions/add-repository.js';
9
9
  import { deleteRepository } from '../../../app/actions/delete-repository.js';
@@ -11,9 +11,7 @@ import { useAgentEventsContext } from '../../../hooks/agent-events-provider.js';
11
11
  import { useSoundAction } from '../../../hooks/use-sound-action.js';
12
12
  import { mapEventTypeToState, mapPhaseNameToLifecycle, } from '../../common/feature-node/derive-feature-state.js';
13
13
  let nextFeatureId = 0;
14
- export function useControlCenterState(initialNodes, initialEdges,
15
- /** When true, background router.refresh() calls (polling / SSE debounce) are suppressed. */
16
- isRefreshBlocked) {
14
+ export function useControlCenterState(initialNodes, initialEdges) {
17
15
  const router = useRouter();
18
16
  const [nodes, setNodes] = useState(initialNodes);
19
17
  // eslint-disable-next-line react/hook-use-state -- raw setter renamed; public setEdges wrapper keeps edgesRef in sync
@@ -30,7 +28,7 @@ isRefreshBlocked) {
30
28
  }, []);
31
29
  const deleteSound = useSoundAction('delete');
32
30
  const createSound = useSoundAction('create');
33
- // Sync server props into local state when router.refresh() delivers new data
31
+ // Sync server props into local state when parent re-renders with new data
34
32
  const initialNodeKey = initialNodes
35
33
  .map((n) => n.id)
36
34
  .sort()
@@ -61,8 +59,9 @@ isRefreshBlocked) {
61
59
  const creatingNodes = currentNodes.filter((n) => n.type === 'featureNode' &&
62
60
  n.data.state === 'creating' &&
63
61
  !serverIds.has(n.id));
64
- // Merge server nodes with client positions
65
- return initialNodes.map((serverNode) => {
62
+ // Merge server nodes with client positions, tracking if relayout is needed
63
+ let needsRelayout = false;
64
+ const merged = initialNodes.map((serverNode) => {
66
65
  // Node already exists on canvas — keep its position, update data
67
66
  const existing = currentById.get(serverNode.id);
68
67
  if (existing) {
@@ -73,17 +72,28 @@ isRefreshBlocked) {
73
72
  const donor = creatingNodes.shift();
74
73
  return { ...serverNode, position: donor.position };
75
74
  }
76
- // Truly new node with no optimistic counterpart — use server position
75
+ // Truly new node with no optimistic counterpart — needs relayout
76
+ needsRelayout = true;
77
77
  return serverNode;
78
78
  });
79
+ // Also check if non-creating nodes were removed (graph got smaller)
80
+ if (!needsRelayout) {
81
+ needsRelayout = currentNodes.some((cn) => !serverIds.has(cn.id) &&
82
+ !(cn.type === 'featureNode' && cn.data.state === 'creating'));
83
+ }
84
+ if (needsRelayout) {
85
+ const layoutResult = layoutWithDagre(merged, initialEdges, CANVAS_LAYOUT_DEFAULTS);
86
+ setEdges(layoutResult.edges);
87
+ return layoutResult.nodes;
88
+ }
89
+ return merged;
79
90
  });
80
- }, [initialNodeKey, initialNodes]);
91
+ }, [initialNodeKey, initialNodes, initialEdges, setEdges]);
81
92
  useEffect(() => {
82
93
  setEdges(initialEdges);
83
94
  }, [initialEdgeKey, initialEdges, setEdges]);
84
- // Fallback notifications from server-refresh state transitions.
85
- // Fires only when SSE didn't already deliver the matching event for a feature,
86
- // e.g. when the SSE connection was down or the event was seeded into the cache.
95
+ // Fallback notifications from server-prop state transitions.
96
+ // Fires only when SSE didn't already deliver the matching event for a feature.
87
97
  const { events } = useAgentEventsContext();
88
98
  useEffect(() => {
89
99
  const prevStates = prevFeatureStatesRef.current;
@@ -118,14 +128,10 @@ isRefreshBlocked) {
118
128
  prevStates.set(node.id, data.state);
119
129
  }
120
130
  }, [initialDataKey, initialNodes, events, router]);
121
- // Targeted optimistic updates from SSE agent events + debounced reconciliation.
131
+ // Targeted optimistic updates from SSE agent events.
122
132
  // Uses `events` array (not `lastEvent`) so that React batching cannot silently
123
133
  // drop events when multiple SSE messages arrive in the same tick.
124
134
  const processedEventCountRef = useRef(0);
125
- const reconcileTimerRef = useRef(undefined);
126
- useEffect(() => {
127
- return () => clearTimeout(reconcileTimerRef.current);
128
- }, []);
129
135
  useEffect(() => {
130
136
  if (events.length <= processedEventCountRef.current)
131
137
  return;
@@ -151,31 +157,7 @@ isRefreshBlocked) {
151
157
  };
152
158
  }));
153
159
  }
154
- // Debounced background reconciliation (3s after last SSE event)
155
- clearTimeout(reconcileTimerRef.current);
156
- reconcileTimerRef.current = setTimeout(() => {
157
- if (!isRefreshBlocked?.())
158
- router.refresh();
159
- }, 3000);
160
- }, [events, router, isRefreshBlocked]);
161
- // Periodic polling fallback: refresh server data every 5s when any feature
162
- // is in an active state (running/action-required). This ensures the UI stays
163
- // current even if the SSE connection drops — belt-and-suspenders alongside SSE.
164
- useEffect(() => {
165
- const hasActiveFeature = nodes.some((n) => {
166
- if (n.type !== 'featureNode')
167
- return false;
168
- const data = n.data;
169
- return (data.state === 'running' || data.state === 'action-required' || data.state === 'creating');
170
- });
171
- if (!hasActiveFeature)
172
- return;
173
- const interval = setInterval(() => {
174
- if (!isRefreshBlocked?.())
175
- router.refresh();
176
- }, 5_000);
177
- return () => clearInterval(interval);
178
- }, [nodes, router, isRefreshBlocked]);
160
+ }, [events]);
179
161
  const onNodesChange = useCallback((changes) => {
180
162
  setNodes((ns) => applyNodeChanges(changes, ns));
181
163
  }, []);
@@ -220,202 +202,155 @@ isRefreshBlocked) {
220
202
  branch: dataOverride?.branch ?? '',
221
203
  };
222
204
  setNodes((currentNodes) => {
223
- // Read edges from ref to avoid closure dependency on `edges` state.
224
- // edgesRef is kept in sync by the setEdges wrapper.
225
- const siblingIds = sourceNodeId
226
- ? new Set(edgesRef.current.filter((e) => e.source === sourceNodeId).map((e) => e.target))
227
- : new Set();
228
- const siblings = currentNodes.filter((n) => siblingIds.has(n.id));
229
- let position;
230
- if (siblings.length > 0) {
231
- // Place below the bottom-most sibling, matching X
232
- const sortedYs = siblings.map((n) => n.position.y).sort((a, b) => a - b);
233
- const maxY = sortedYs[sortedYs.length - 1];
234
- // Derive gap from existing spacing between siblings, or use default
235
- const gap = sortedYs.length > 1 ? sortedYs[1] - sortedYs[0] : 160;
236
- position = { x: siblings[0].position.x, y: maxY + gap };
237
- }
238
- else if (sourceNodeId) {
239
- // First child — position to the right of parent
240
- const parent = currentNodes.find((n) => n.id === sourceNodeId);
241
- // Parent width (288) + 200px gap matching dagre ranksep
242
- const xOffset = 488;
243
- position = parent
244
- ? { x: parent.position.x + xOffset, y: parent.position.y }
245
- : { x: 400, y: 200 };
246
- }
247
- else {
248
- // Standalone feature — place below all existing nodes
249
- const maxY = currentNodes.length > 0 ? Math.max(...currentNodes.map((n) => n.position.y)) : 0;
250
- position = { x: 400, y: currentNodes.length > 0 ? maxY + 160 : 200 };
251
- }
252
- // The new node's bottom edge (featureNode height = 140)
253
- const newBottom = position.y + 140;
254
- // Find the old group bottom before adding the new node
255
- const groupNodeIds = new Set([sourceNodeId, ...siblingIds]);
256
- const oldGroupBottom = currentNodes
257
- .filter((n) => groupNodeIds.has(n.id))
258
- .reduce((max, n) => {
259
- const h = n.type === 'featureNode' ? 140 : 50;
260
- return Math.max(max, n.position.y + h);
261
- }, 0);
262
- // Shift amount: how much the group grew past its old bottom
263
- const shift = Math.max(0, newBottom - oldGroupBottom);
264
- // Push down all nodes that are below the old group bottom
265
- const shifted = shift > 0
266
- ? currentNodes.map((n) => {
267
- if (groupNodeIds.has(n.id) || siblingIds.has(n.id))
268
- return n;
269
- if (n.position.y >= oldGroupBottom) {
270
- return { ...n, position: { ...n.position, y: n.position.y + shift } };
271
- }
272
- return n;
273
- })
274
- : currentNodes;
275
- // Re-center the parent node vertically to its children
276
- const recentered = sourceNodeId
277
- ? shifted.map((n) => {
278
- if (n.id !== sourceNodeId)
279
- return n;
280
- const allChildYs = [...siblings.map((s) => s.position.y), position.y];
281
- const groupCenter = (Math.min(...allChildYs) + Math.max(...allChildYs) + 140) / 2;
282
- const parentHeight = n.type === 'featureNode' ? 140 : 50;
283
- return {
284
- ...n,
285
- position: { ...n.position, y: groupCenter - parentHeight / 2 },
286
- };
287
- })
288
- : shifted;
289
- return [
290
- ...recentered,
291
- {
292
- id,
293
- type: 'featureNode',
294
- position,
295
- data: newFeatureData,
296
- },
297
- ];
298
- });
299
- if (sourceNodeId) {
300
- setEdges((currentEdges) => [
301
- ...currentEdges,
302
- {
205
+ const newNode = {
206
+ id,
207
+ type: 'featureNode',
208
+ position: { x: 0, y: 0 },
209
+ data: newFeatureData,
210
+ };
211
+ const newEdge = sourceNodeId
212
+ ? {
303
213
  id: edgeType === 'dependencyEdge'
304
214
  ? `dep-${sourceNodeId}-${id}`
305
215
  : `edge-${sourceNodeId}-${id}`,
306
216
  source: sourceNodeId,
307
217
  target: id,
308
218
  ...(edgeType ? { type: edgeType } : { style: { strokeDasharray: '5 5' } }),
309
- },
310
- ]);
311
- }
219
+ }
220
+ : null;
221
+ const allEdges = newEdge
222
+ ? [...edgesRef.current.filter((e) => e.id !== newEdge.id), newEdge]
223
+ : edgesRef.current;
224
+ // Insert the new node after the last sibling connected to the same source,
225
+ // so dagre's input-order preservation keeps repo groups together.
226
+ let insertIndex = currentNodes.length;
227
+ if (sourceNodeId) {
228
+ const siblingIds = new Set(allEdges.filter((e) => e.source === sourceNodeId).map((e) => e.target));
229
+ for (let i = currentNodes.length - 1; i >= 0; i--) {
230
+ if (siblingIds.has(currentNodes[i].id)) {
231
+ insertIndex = i + 1;
232
+ break;
233
+ }
234
+ }
235
+ }
236
+ const allNodes = [
237
+ ...currentNodes.slice(0, insertIndex),
238
+ newNode,
239
+ ...currentNodes.slice(insertIndex),
240
+ ];
241
+ // Run dagre layout on the full graph so the new node is positioned consistently
242
+ const layoutResult = layoutWithDagre(allNodes, allEdges, CANVAS_LAYOUT_DEFAULTS);
243
+ setEdges(layoutResult.edges);
244
+ return layoutResult.nodes;
245
+ });
312
246
  return id;
313
247
  }, [setEdges]);
314
- const handleDeleteFeature = useCallback(async (featureId) => {
315
- try {
316
- const result = await deleteFeature(featureId);
248
+ const handleDeleteFeature = useCallback((featureId) => {
249
+ const nodeId = `feat-${featureId}`;
250
+ // Snapshot current state for rollback
251
+ const prevNodes = nodes;
252
+ const prevEdges = edgesRef.current;
253
+ // Optimistic removal — update UI immediately
254
+ setNodes((currentNodes) => {
255
+ const remainingNodes = currentNodes.filter((n) => n.id !== nodeId);
256
+ const remainingEdges = edgesRef.current.filter((e) => e.source !== nodeId && e.target !== nodeId);
257
+ const layoutResult = layoutWithDagre(remainingNodes, remainingEdges, CANVAS_LAYOUT_DEFAULTS);
258
+ setEdges(layoutResult.edges);
259
+ return layoutResult.nodes;
260
+ });
261
+ deleteSound.play();
262
+ toast.success('Feature deleted successfully');
263
+ router.push('/');
264
+ // Persist in background — rollback on failure
265
+ deleteFeature(featureId)
266
+ .then((result) => {
317
267
  if (result.error) {
268
+ setNodes(prevNodes);
269
+ setEdges(prevEdges);
318
270
  toast.error(result.error);
319
- return;
320
271
  }
321
- setNodes((currentNodes) => {
322
- const remainingNodes = currentNodes.filter((n) => n.id !== featureId);
323
- const remainingEdges = edges.filter((e) => e.source !== featureId && e.target !== featureId);
324
- const layoutResult = layoutWithDagre(remainingNodes, remainingEdges, {
325
- direction: 'LR',
326
- ranksep: 200,
327
- nodesep: 60,
328
- });
329
- setEdges(layoutResult.edges);
330
- return layoutResult.nodes;
331
- });
332
- deleteSound.play();
333
- toast.success('Feature deleted successfully');
334
- router.refresh();
335
- }
336
- catch {
272
+ })
273
+ .catch(() => {
274
+ setNodes(prevNodes);
275
+ setEdges(prevEdges);
337
276
  toast.error('Failed to delete feature');
338
- }
339
- }, [router, edges, deleteSound, setEdges]);
277
+ });
278
+ }, [nodes, router, deleteSound, setEdges]);
340
279
  const handleDeleteRepository = useCallback(async (repositoryId) => {
341
280
  const repoNodeId = `repo-${repositoryId}`;
342
- // Optimistic: remove node and its edges immediately
343
- setNodes((prev) => prev.filter((n) => n.id !== repoNodeId));
344
- setEdges((prev) => prev.filter((e) => e.source !== repoNodeId && e.target !== repoNodeId));
281
+ // Snapshot for rollback
282
+ const prevNodes = nodes;
283
+ const prevEdges = edgesRef.current;
284
+ // Optimistic: remove repo node, its child feature nodes, and all related edges
285
+ setNodes((currentNodes) => {
286
+ // Find feature node IDs connected to this repo via edges
287
+ const childFeatureIds = new Set(edgesRef.current.filter((e) => e.source === repoNodeId).map((e) => e.target));
288
+ const remainingNodes = currentNodes.filter((n) => n.id !== repoNodeId && !childFeatureIds.has(n.id));
289
+ const remainingEdges = edgesRef.current.filter((e) => e.source !== repoNodeId &&
290
+ e.target !== repoNodeId &&
291
+ !childFeatureIds.has(e.source) &&
292
+ !childFeatureIds.has(e.target));
293
+ const layoutResult = layoutWithDagre(remainingNodes, remainingEdges, CANVAS_LAYOUT_DEFAULTS);
294
+ setEdges(layoutResult.edges);
295
+ return layoutResult.nodes;
296
+ });
345
297
  try {
346
298
  const result = await deleteRepository(repositoryId);
347
299
  if (!result.success) {
348
300
  toast.error(result.error ?? 'Failed to remove repository');
349
- router.refresh();
301
+ setNodes(prevNodes);
302
+ setEdges(prevEdges);
350
303
  return;
351
304
  }
352
305
  deleteSound.play();
353
306
  toast.success('Repository removed');
354
- router.refresh();
355
307
  }
356
308
  catch {
357
309
  toast.error('Failed to remove repository');
358
- router.refresh();
310
+ setNodes(prevNodes);
311
+ setEdges(prevEdges);
359
312
  }
360
- }, [router, deleteSound, setEdges]);
313
+ }, [nodes, deleteSound, setEdges]);
361
314
  const handleLayout = useCallback((direction) => {
362
315
  setNodes((currentNodes) => {
363
- const currentEdges = edges;
364
- const result = layoutWithDagre(currentNodes, currentEdges, {
316
+ const result = layoutWithDagre(currentNodes, edgesRef.current, {
317
+ ...CANVAS_LAYOUT_DEFAULTS,
365
318
  direction,
366
- ranksep: 60,
367
- nodesep: 20,
368
319
  });
369
320
  setEdges(result.edges);
370
321
  return result.nodes;
371
322
  });
372
- }, [edges, setEdges]);
323
+ }, [setEdges]);
373
324
  const handleAddRepository = useCallback((path) => {
374
325
  const tempId = `repo-temp-${Date.now()}`;
375
326
  const repoName = path
376
327
  .replace(/[\\/]+$/, '')
377
328
  .split(/[\\/]/)
378
329
  .pop() ?? path;
379
- // Optimistic UI: add node immediately
380
- let savedAddRepoY = 0;
330
+ // Optimistic UI: add node and re-layout immediately
381
331
  setNodes((currentNodes) => {
382
- const repoNodes = currentNodes.filter((n) => n.type === 'repositoryNode');
383
- const addRepoNode = currentNodes.find((n) => n.type === 'addRepositoryNode');
384
- // Save addRepoNode's original Y for rollback on error
385
- if (addRepoNode)
386
- savedAddRepoY = addRepoNode.position.y;
387
- // Place in the repo column, at the addRepoNode's current position
388
- const repoX = repoNodes[0]?.position.x ?? addRepoNode?.position.x ?? 50;
389
- const repoHeight = 50; // repositoryNode height
390
- const gap = 15; // match dagre nodesep
391
- const position = {
392
- x: repoX,
393
- y: addRepoNode ? addRepoNode.position.y : 0,
394
- };
395
332
  const newNode = {
396
333
  id: tempId,
397
334
  type: 'repositoryNode',
398
- position,
335
+ position: { x: 0, y: 0 },
399
336
  data: { name: repoName, repositoryPath: path, id: tempId },
400
337
  };
401
- // Shift addRepo button down by exactly one slot
402
- const addRepoY = addRepoNode
403
- ? addRepoNode.position.y + repoHeight + gap
404
- : position.y + repoHeight + gap;
405
- return currentNodes
406
- .map((n) => n.type === 'addRepositoryNode' ? { ...n, position: { ...n.position, y: addRepoY } } : n)
407
- .concat(newNode);
338
+ const allNodes = [...currentNodes, newNode];
339
+ const layoutResult = layoutWithDagre(allNodes, edgesRef.current, CANVAS_LAYOUT_DEFAULTS);
340
+ setEdges(layoutResult.edges);
341
+ return layoutResult.nodes;
408
342
  });
409
343
  // Persist via server action
410
344
  addRepository({ path, name: repoName })
411
345
  .then((result) => {
412
346
  if (result.error) {
413
- // Rollback optimistic node and restore addRepoNode position
414
- setNodes((prev) => prev
415
- .filter((n) => n.id !== tempId)
416
- .map((n) => n.type === 'addRepositoryNode'
417
- ? { ...n, position: { ...n.position, y: savedAddRepoY } }
418
- : n));
347
+ // Rollback optimistic node and re-layout
348
+ setNodes((prev) => {
349
+ const remaining = prev.filter((n) => n.id !== tempId);
350
+ const layoutResult = layoutWithDagre(remaining, edgesRef.current, CANVAS_LAYOUT_DEFAULTS);
351
+ setEdges(layoutResult.edges);
352
+ return layoutResult.nodes;
353
+ });
419
354
  toast.error(result.error);
420
355
  return;
421
356
  }
@@ -436,18 +371,18 @@ isRefreshBlocked) {
436
371
  id: e.id.replace(tempId, realId),
437
372
  })));
438
373
  createSound.play();
439
- router.refresh();
440
374
  })
441
375
  .catch(() => {
442
- // Rollback optimistic node and restore addRepoNode position
443
- setNodes((prev) => prev
444
- .filter((n) => n.id !== tempId)
445
- .map((n) => n.type === 'addRepositoryNode'
446
- ? { ...n, position: { ...n.position, y: savedAddRepoY } }
447
- : n));
376
+ // Rollback optimistic node and re-layout
377
+ setNodes((prev) => {
378
+ const remaining = prev.filter((n) => n.id !== tempId);
379
+ const layoutResult = layoutWithDagre(remaining, edgesRef.current, CANVAS_LAYOUT_DEFAULTS);
380
+ setEdges(layoutResult.edges);
381
+ return layoutResult.nodes;
382
+ });
448
383
  toast.error('Failed to add repository');
449
384
  });
450
- }, [router, createSound, setEdges]);
385
+ }, [createSound, setEdges]);
451
386
  return {
452
387
  nodes,
453
388
  edges,
@@ -4,7 +4,7 @@ import { Button } from '../ui/button.js';
4
4
  declare function AlertDialog({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
5
5
  declare function AlertDialogTrigger({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
6
6
  declare function AlertDialogPortal({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>): import("react/jsx-runtime").JSX.Element;
7
- declare function AlertDialogOverlay({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>): import("react/jsx-runtime").JSX.Element;
7
+ declare function AlertDialogOverlay({ className, onClick, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>): import("react/jsx-runtime").JSX.Element;
8
8
  declare function AlertDialogContent({ className, size, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Content> & {
9
9
  size?: 'default' | 'sm';
10
10
  }): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/alert-dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,2CAExF;AAED,iBAAS,kBAAkB,CAAC,EAC1B,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,2CAE3D;AAED,iBAAS,iBAAiB,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,2CAEhG;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,2CAW3D;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG;IAC7D,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB,2CAeA;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW9E;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW9E;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,KAAK,CAAC,2CAWzD;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,WAAW,CAAC,2CAQ/D;AAED,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW7E;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAU9D;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAU9D;AAED,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,GACnB,CAAC"}
1
+ {"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/alert-dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,2CAExF;AAED,iBAAS,kBAAkB,CAAC,EAC1B,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,2CAE3D;AAED,iBAAS,iBAAiB,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,2CAEhG;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,OAAO,EACP,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,2CAiB3D;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG;IAC7D,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB,2CAeA;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW9E;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW9E;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,KAAK,CAAC,2CAWzD;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,WAAW,CAAC,2CAQ/D;AAED,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW7E;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAU9D;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,MAAM,CAAC,GACzD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAU9D;AAED,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,GACnB,CAAC"}
@@ -12,8 +12,13 @@ function AlertDialogTrigger({ ...props }) {
12
12
  function AlertDialogPortal({ ...props }) {
13
13
  return _jsx(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props });
14
14
  }
15
- function AlertDialogOverlay({ className, ...props }) {
16
- return (_jsx(AlertDialogPrimitive.Overlay, { "data-slot": "alert-dialog-overlay", className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50', className), ...props }));
15
+ function AlertDialogOverlay({ className, onClick, ...props }) {
16
+ return (_jsx(AlertDialogPrimitive.Overlay, { "data-slot": "alert-dialog-overlay", className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50', className), onClick: (e) => {
17
+ // Prevent overlay clicks from propagating to document-level handlers
18
+ // (e.g. BaseDrawer outside-click) — only the dialog should dismiss.
19
+ e.stopPropagation();
20
+ onClick?.(e);
21
+ }, ...props }));
17
22
  }
18
23
  function AlertDialogContent({ className, size = 'default', ...props }) {
19
24
  return (_jsxs(AlertDialogPortal, { children: [_jsx(AlertDialogOverlay, {}), _jsx(AlertDialogPrimitive.Content, { "data-slot": "alert-dialog-content", "data-size": size, className: cn('bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg', className), ...props })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAKrD,QAAA,MAAM,MAAM,uCAAuB,CAAC;AAEpC,QAAA,MAAM,aAAa,8GAA0B,CAAC;AAE9C,QAAA,MAAM,YAAY,6CAAyB,CAAC;AAE5C,QAAA,MAAM,WAAW,4GAAwB,CAAC;AAE1C,QAAA,MAAM,aAAa,8JAYjB,CAAC;AAGH,QAAA,MAAM,aAAa,8JAqBjB,CAAC;AAGH,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAElF,CAAC;AAGF,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAKlF,CAAC;AAGF,QAAA,MAAM,WAAW,oKASf,CAAC;AAGH,QAAA,MAAM,iBAAiB,8KASrB,CAAC;AAGH,OAAO,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/ui/dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAKrD,QAAA,MAAM,MAAM,uCAAuB,CAAC;AAEpC,QAAA,MAAM,aAAa,8GAA0B,CAAC;AAE9C,QAAA,MAAM,YAAY,6CAAyB,CAAC;AAE5C,QAAA,MAAM,WAAW,4GAAwB,CAAC;AAE1C,QAAA,MAAM,aAAa,8JAkBjB,CAAC;AAGH,QAAA,MAAM,aAAa,8JAqBjB,CAAC;AAGH,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAElF,CAAC;AAGF,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAKlF,CAAC;AAGF,QAAA,MAAM,WAAW,oKASf,CAAC;AAGH,QAAA,MAAM,iBAAiB,8KASrB,CAAC;AAGH,OAAO,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,CAAC"}
@@ -8,7 +8,12 @@ const Dialog = DialogPrimitive.Root;
8
8
  const DialogTrigger = DialogPrimitive.Trigger;
9
9
  const DialogPortal = DialogPrimitive.Portal;
10
10
  const DialogClose = DialogPrimitive.Close;
11
- const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Overlay, { ref: ref, className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className), ...props })));
11
+ const DialogOverlay = React.forwardRef(({ className, onClick, ...props }, ref) => (_jsx(DialogPrimitive.Overlay, { ref: ref, className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className), onClick: (e) => {
12
+ // Prevent overlay clicks from propagating to document-level handlers
13
+ // (e.g. BaseDrawer outside-click) — only the dialog should dismiss.
14
+ e.stopPropagation();
15
+ onClick?.(e);
16
+ }, ...props })));
12
17
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
13
18
  const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn('bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg', className), ...props, children: [children, _jsxs(DialogPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none", children: [_jsx(X, { className: "h-4 w-4" }), _jsx("span", { className: "sr-only", children: "Close" })] })] })] })));
14
19
  DialogContent.displayName = DialogPrimitive.Content.displayName;
@@ -13,6 +13,8 @@ export interface LayoutOptions {
13
13
  /** Horizontal separation between nodes in the same rank (default 30) */
14
14
  nodesep?: number;
15
15
  }
16
+ /** Canonical layout defaults for the control-center canvas. */
17
+ export declare const CANVAS_LAYOUT_DEFAULTS: LayoutOptions;
16
18
  /**
17
19
  * Compute an automatic hierarchical layout for React Flow nodes and edges
18
20
  * using Dagre. Returns new node/edge arrays — never mutates the originals.
@@ -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;AAmCD;;;;;;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,CAkF/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;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"}