@shepai/cli 1.72.6 → 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.
- package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts +4 -0
- package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/delete-feature.use-case.js +20 -12
- package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts +8 -3
- package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.js +17 -4
- package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +1 -1
- package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
- package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +2 -6
- package/dist/src/presentation/web/app/build-graph-nodes.js +11 -1
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts +3 -1
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +8 -4
- package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +12 -3
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +6 -2
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.js +7 -2
- package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.js +6 -2
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +14 -2
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -5
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +131 -196
- package/dist/src/presentation/web/components/ui/alert-dialog.d.ts +1 -1
- package/dist/src/presentation/web/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/alert-dialog.js +7 -2
- package/dist/src/presentation/web/components/ui/dialog.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/dialog.js +6 -1
- package/dist/src/presentation/web/lib/layout-with-dagre.d.ts +2 -0
- package/dist/src/presentation/web/lib/layout-with-dagre.d.ts.map +1 -1
- package/dist/src/presentation/web/lib/layout-with-dagre.js +86 -4
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +14 -14
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +17 -17
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +14 -14
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +17 -17
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +12 -12
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6db85a66._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8fcb9132._.js +2 -2
- package/web/.next/server/chunks/ssr/_00e6c698._.js +1 -1
- package/web/.next/server/chunks/ssr/_00e6c698._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
- package/web/.next/server/chunks/ssr/_07c2a32a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_34a58db8._.js +1 -1
- package/web/.next/server/chunks/ssr/_34a58db8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_37259405._.js +1 -1
- package/web/.next/server/chunks/ssr/_37259405._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_85d0351b._.js → _63bfa7dd._.js} +2 -2
- package/web/.next/server/chunks/ssr/_63bfa7dd._.js.map +1 -0
- package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/_e50484ec._.js → server/chunks/ssr/_7215bb0f._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_e50484ec._.js.map → _7215bb0f._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_cb5b3951._.js +1 -1
- package/web/.next/server/chunks/ssr/_cb5b3951._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_fc3a6895._.js +1 -1
- package/web/.next/server/chunks/ssr/_fc3a6895._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +20 -20
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +17 -17
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +17 -17
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +12 -12
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- 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
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6db85a66._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__8fcb9132._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_00e6c698._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_07c2a32a._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_34a58db8._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_37259405._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_85d0351b._.js → _63bfa7dd._.js} +2 -2
- package/web/.next/{server/chunks/ssr/_e50484ec._.js → standalone/src/presentation/web/.next/server/chunks/ssr/_7215bb0f._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_cb5b3951._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_fc3a6895._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js +1 -1
- 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
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +20 -20
- package/web/.next/standalone/src/presentation/web/app/(dashboard)/get-graph-data.ts +2 -6
- package/web/.next/standalone/src/presentation/web/app/build-graph-nodes.ts +14 -1
- package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx +10 -8
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx +13 -3
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx +6 -2
- package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx +2 -0
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +8 -5
- package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.tsx +30 -24
- package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-node.tsx +33 -25
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +25 -3
- package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +184 -230
- package/web/.next/standalone/src/presentation/web/components/ui/alert-dialog.tsx +7 -0
- package/web/.next/standalone/src/presentation/web/components/ui/dialog.tsx +7 -1
- package/web/.next/standalone/src/presentation/web/lib/layout-with-dagre.ts +93 -4
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/0c54314c8c9c9739.js +7 -0
- package/web/.next/static/chunks/{5f5c607ffae8b918.js → 304c8593d0a6525d.js} +1 -1
- package/web/.next/static/chunks/4558d1663c6f4d2c.js +1 -0
- package/web/.next/static/chunks/{32957ff277daec59.js → 4df07e765b233622.js} +1 -1
- package/web/.next/static/chunks/{fc07834e422b1caa.js → 585ae19c520e8b72.js} +1 -1
- package/web/.next/static/chunks/{ecb2130572a7fbe7.js → 6e14d8bd5c005e6e.js} +1 -1
- package/web/.next/static/chunks/{412a3ac70c529c5b.js → 8a1eb93510e54db0.js} +1 -1
- package/web/.next/static/chunks/{550bf3cb8220cbf0.js → b143c7d78a6888e9.js} +1 -1
- package/web/.next/static/chunks/{8b36e07129a1471f.js → b45344579a43cbb8.js} +1 -1
- package/web/.next/static/chunks/dec13bccb136ef7c.css +2 -0
- package/web/.next/static/chunks/e4522f7d3134eefe.js +1 -0
- package/web/.next/static/chunks/{d4ecce2ac7795bd9.js → fe83a799663fd3cc.js} +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/server/chunks/ssr/_85d0351b._.js.map +0 -1
- package/web/.next/static/chunks/06b6b02bab76aee7.js +0 -1
- package/web/.next/static/chunks/06dfd668334ffb4e.js +0 -7
- package/web/.next/static/chunks/224ed5f5dbd33154.css +0 -2
- package/web/.next/static/chunks/e44849eb58a3335f.js +0 -1
- /package/web/.next/static/{7K6dTYQIJ7__PLUYLLfZV → 9bO_bJBssG0NRxEG03iM5}/_buildManifest.js +0 -0
- /package/web/.next/static/{7K6dTYQIJ7__PLUYLLfZV → 9bO_bJBssG0NRxEG03iM5}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{7K6dTYQIJ7__PLUYLLfZV → 9bO_bJBssG0NRxEG03iM5}/_ssgManifest.js +0 -0
|
@@ -7,7 +7,11 @@ import { applyNodeChanges } from '@xyflow/react';
|
|
|
7
7
|
import type { Connection, Edge, NodeChange } from '@xyflow/react';
|
|
8
8
|
import type { FeatureNodeData } from '@/components/common/feature-node';
|
|
9
9
|
import type { CanvasNodeType } from '@/components/features/features-canvas';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
layoutWithDagre,
|
|
12
|
+
CANVAS_LAYOUT_DEFAULTS,
|
|
13
|
+
type LayoutDirection,
|
|
14
|
+
} from '@/lib/layout-with-dagre';
|
|
11
15
|
import { deleteFeature } from '@/app/actions/delete-feature';
|
|
12
16
|
import { addRepository } from '@/app/actions/add-repository';
|
|
13
17
|
import { deleteRepository } from '@/app/actions/delete-repository';
|
|
@@ -25,11 +29,12 @@ export interface ControlCenterState {
|
|
|
25
29
|
handleConnect: (connection: Connection) => void;
|
|
26
30
|
handleAddRepository: (path: string) => void;
|
|
27
31
|
handleLayout: (direction: LayoutDirection) => void;
|
|
28
|
-
handleDeleteFeature: (featureId: string) =>
|
|
32
|
+
handleDeleteFeature: (featureId: string) => void;
|
|
29
33
|
handleDeleteRepository: (repositoryId: string) => Promise<void>;
|
|
30
34
|
createFeatureNode: (
|
|
31
35
|
sourceNodeId: string | null,
|
|
32
|
-
dataOverride?: Partial<FeatureNodeData
|
|
36
|
+
dataOverride?: Partial<FeatureNodeData>,
|
|
37
|
+
edgeType?: string
|
|
33
38
|
) => string;
|
|
34
39
|
}
|
|
35
40
|
|
|
@@ -37,9 +42,7 @@ let nextFeatureId = 0;
|
|
|
37
42
|
|
|
38
43
|
export function useControlCenterState(
|
|
39
44
|
initialNodes: CanvasNodeType[],
|
|
40
|
-
initialEdges: Edge[]
|
|
41
|
-
/** When true, background router.refresh() calls (polling / SSE debounce) are suppressed. */
|
|
42
|
-
isRefreshBlocked?: () => boolean
|
|
45
|
+
initialEdges: Edge[]
|
|
43
46
|
): ControlCenterState {
|
|
44
47
|
const router = useRouter();
|
|
45
48
|
const [nodes, setNodes] = useState<CanvasNodeType[]>(initialNodes);
|
|
@@ -59,7 +62,7 @@ export function useControlCenterState(
|
|
|
59
62
|
const deleteSound = useSoundAction('delete');
|
|
60
63
|
const createSound = useSoundAction('create');
|
|
61
64
|
|
|
62
|
-
// Sync server props into local state when
|
|
65
|
+
// Sync server props into local state when parent re-renders with new data
|
|
63
66
|
const initialNodeKey = initialNodes
|
|
64
67
|
.map((n) => n.id)
|
|
65
68
|
.sort()
|
|
@@ -98,8 +101,9 @@ export function useControlCenterState(
|
|
|
98
101
|
!serverIds.has(n.id)
|
|
99
102
|
);
|
|
100
103
|
|
|
101
|
-
// Merge server nodes with client positions
|
|
102
|
-
|
|
104
|
+
// Merge server nodes with client positions, tracking if relayout is needed
|
|
105
|
+
let needsRelayout = false;
|
|
106
|
+
const merged = initialNodes.map((serverNode) => {
|
|
103
107
|
// Node already exists on canvas — keep its position, update data
|
|
104
108
|
const existing = currentById.get(serverNode.id);
|
|
105
109
|
if (existing) {
|
|
@@ -112,19 +116,36 @@ export function useControlCenterState(
|
|
|
112
116
|
return { ...serverNode, position: donor.position };
|
|
113
117
|
}
|
|
114
118
|
|
|
115
|
-
// Truly new node with no optimistic counterpart —
|
|
119
|
+
// Truly new node with no optimistic counterpart — needs relayout
|
|
120
|
+
needsRelayout = true;
|
|
116
121
|
return serverNode;
|
|
117
122
|
});
|
|
123
|
+
|
|
124
|
+
// Also check if non-creating nodes were removed (graph got smaller)
|
|
125
|
+
if (!needsRelayout) {
|
|
126
|
+
needsRelayout = currentNodes.some(
|
|
127
|
+
(cn) =>
|
|
128
|
+
!serverIds.has(cn.id) &&
|
|
129
|
+
!(cn.type === 'featureNode' && (cn.data as FeatureNodeData).state === 'creating')
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (needsRelayout) {
|
|
134
|
+
const layoutResult = layoutWithDagre(merged, initialEdges, CANVAS_LAYOUT_DEFAULTS);
|
|
135
|
+
setEdges(layoutResult.edges);
|
|
136
|
+
return layoutResult.nodes;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return merged;
|
|
118
140
|
});
|
|
119
|
-
}, [initialNodeKey, initialNodes]);
|
|
141
|
+
}, [initialNodeKey, initialNodes, initialEdges, setEdges]);
|
|
120
142
|
|
|
121
143
|
useEffect(() => {
|
|
122
144
|
setEdges(initialEdges);
|
|
123
145
|
}, [initialEdgeKey, initialEdges, setEdges]);
|
|
124
146
|
|
|
125
|
-
// Fallback notifications from server-
|
|
126
|
-
// Fires only when SSE didn't already deliver the matching event for a feature
|
|
127
|
-
// e.g. when the SSE connection was down or the event was seeded into the cache.
|
|
147
|
+
// Fallback notifications from server-prop state transitions.
|
|
148
|
+
// Fires only when SSE didn't already deliver the matching event for a feature.
|
|
128
149
|
const { events } = useAgentEventsContext();
|
|
129
150
|
|
|
130
151
|
useEffect(() => {
|
|
@@ -164,15 +185,10 @@ export function useControlCenterState(
|
|
|
164
185
|
}
|
|
165
186
|
}, [initialDataKey, initialNodes, events, router]);
|
|
166
187
|
|
|
167
|
-
// Targeted optimistic updates from SSE agent events
|
|
188
|
+
// Targeted optimistic updates from SSE agent events.
|
|
168
189
|
// Uses `events` array (not `lastEvent`) so that React batching cannot silently
|
|
169
190
|
// drop events when multiple SSE messages arrive in the same tick.
|
|
170
191
|
const processedEventCountRef = useRef(0);
|
|
171
|
-
const reconcileTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
|
|
172
|
-
|
|
173
|
-
useEffect(() => {
|
|
174
|
-
return () => clearTimeout(reconcileTimerRef.current);
|
|
175
|
-
}, []);
|
|
176
192
|
|
|
177
193
|
useEffect(() => {
|
|
178
194
|
if (events.length <= processedEventCountRef.current) return;
|
|
@@ -201,33 +217,7 @@ export function useControlCenterState(
|
|
|
201
217
|
})
|
|
202
218
|
);
|
|
203
219
|
}
|
|
204
|
-
|
|
205
|
-
// Debounced background reconciliation (3s after last SSE event)
|
|
206
|
-
clearTimeout(reconcileTimerRef.current);
|
|
207
|
-
reconcileTimerRef.current = setTimeout(() => {
|
|
208
|
-
if (!isRefreshBlocked?.()) router.refresh();
|
|
209
|
-
}, 3000);
|
|
210
|
-
}, [events, router, isRefreshBlocked]);
|
|
211
|
-
|
|
212
|
-
// Periodic polling fallback: refresh server data every 5s when any feature
|
|
213
|
-
// is in an active state (running/action-required). This ensures the UI stays
|
|
214
|
-
// current even if the SSE connection drops — belt-and-suspenders alongside SSE.
|
|
215
|
-
useEffect(() => {
|
|
216
|
-
const hasActiveFeature = nodes.some((n) => {
|
|
217
|
-
if (n.type !== 'featureNode') return false;
|
|
218
|
-
const data = n.data as FeatureNodeData;
|
|
219
|
-
return (
|
|
220
|
-
data.state === 'running' || data.state === 'action-required' || data.state === 'creating'
|
|
221
|
-
);
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
if (!hasActiveFeature) return;
|
|
225
|
-
|
|
226
|
-
const interval = setInterval(() => {
|
|
227
|
-
if (!isRefreshBlocked?.()) router.refresh();
|
|
228
|
-
}, 5_000);
|
|
229
|
-
return () => clearInterval(interval);
|
|
230
|
-
}, [nodes, router, isRefreshBlocked]);
|
|
220
|
+
}, [events]);
|
|
231
221
|
|
|
232
222
|
const onNodesChange = useCallback((changes: NodeChange<CanvasNodeType>[]) => {
|
|
233
223
|
setNodes((ns) => applyNodeChanges(changes, ns));
|
|
@@ -285,103 +275,54 @@ export function useControlCenterState(
|
|
|
285
275
|
};
|
|
286
276
|
|
|
287
277
|
setNodes((currentNodes) => {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
:
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
let position: { x: number; y: number };
|
|
296
|
-
|
|
297
|
-
if (siblings.length > 0) {
|
|
298
|
-
// Place below the bottom-most sibling, matching X
|
|
299
|
-
const sortedYs = siblings.map((n) => n.position.y).sort((a, b) => a - b);
|
|
300
|
-
const maxY = sortedYs[sortedYs.length - 1];
|
|
301
|
-
// Derive gap from existing spacing between siblings, or use default
|
|
302
|
-
const gap = sortedYs.length > 1 ? sortedYs[1] - sortedYs[0] : 160;
|
|
303
|
-
position = { x: siblings[0].position.x, y: maxY + gap };
|
|
304
|
-
} else if (sourceNodeId) {
|
|
305
|
-
// First child — position to the right of parent
|
|
306
|
-
const parent = currentNodes.find((n) => n.id === sourceNodeId);
|
|
307
|
-
// Parent width (288) + 200px gap matching dagre ranksep
|
|
308
|
-
const xOffset = 488;
|
|
309
|
-
position = parent
|
|
310
|
-
? { x: parent.position.x + xOffset, y: parent.position.y }
|
|
311
|
-
: { x: 400, y: 200 };
|
|
312
|
-
} else {
|
|
313
|
-
// Standalone feature — place below all existing nodes
|
|
314
|
-
const maxY =
|
|
315
|
-
currentNodes.length > 0 ? Math.max(...currentNodes.map((n) => n.position.y)) : 0;
|
|
316
|
-
position = { x: 400, y: currentNodes.length > 0 ? maxY + 160 : 200 };
|
|
317
|
-
}
|
|
278
|
+
const newNode = {
|
|
279
|
+
id,
|
|
280
|
+
type: 'featureNode' as const,
|
|
281
|
+
position: { x: 0, y: 0 },
|
|
282
|
+
data: newFeatureData,
|
|
283
|
+
} as CanvasNodeType;
|
|
318
284
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
return {
|
|
354
|
-
...n,
|
|
355
|
-
position: { ...n.position, y: groupCenter - parentHeight / 2 },
|
|
356
|
-
};
|
|
357
|
-
})
|
|
358
|
-
: shifted;
|
|
359
|
-
|
|
360
|
-
return [
|
|
361
|
-
...recentered,
|
|
362
|
-
{
|
|
363
|
-
id,
|
|
364
|
-
type: 'featureNode' as const,
|
|
365
|
-
position,
|
|
366
|
-
data: newFeatureData,
|
|
367
|
-
} as CanvasNodeType,
|
|
285
|
+
const newEdge = sourceNodeId
|
|
286
|
+
? {
|
|
287
|
+
id:
|
|
288
|
+
edgeType === 'dependencyEdge'
|
|
289
|
+
? `dep-${sourceNodeId}-${id}`
|
|
290
|
+
: `edge-${sourceNodeId}-${id}`,
|
|
291
|
+
source: sourceNodeId,
|
|
292
|
+
target: id,
|
|
293
|
+
...(edgeType ? { type: edgeType } : { style: { strokeDasharray: '5 5' } }),
|
|
294
|
+
}
|
|
295
|
+
: null;
|
|
296
|
+
|
|
297
|
+
const allEdges = newEdge
|
|
298
|
+
? [...edgesRef.current.filter((e) => e.id !== newEdge.id), newEdge]
|
|
299
|
+
: edgesRef.current;
|
|
300
|
+
|
|
301
|
+
// Insert the new node after the last sibling connected to the same source,
|
|
302
|
+
// so dagre's input-order preservation keeps repo groups together.
|
|
303
|
+
let insertIndex = currentNodes.length;
|
|
304
|
+
if (sourceNodeId) {
|
|
305
|
+
const siblingIds = new Set(
|
|
306
|
+
allEdges.filter((e) => e.source === sourceNodeId).map((e) => e.target)
|
|
307
|
+
);
|
|
308
|
+
for (let i = currentNodes.length - 1; i >= 0; i--) {
|
|
309
|
+
if (siblingIds.has(currentNodes[i].id)) {
|
|
310
|
+
insertIndex = i + 1;
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const allNodes = [
|
|
316
|
+
...currentNodes.slice(0, insertIndex),
|
|
317
|
+
newNode,
|
|
318
|
+
...currentNodes.slice(insertIndex),
|
|
368
319
|
];
|
|
369
|
-
});
|
|
370
320
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
edgeType === 'dependencyEdge'
|
|
377
|
-
? `dep-${sourceNodeId}-${id}`
|
|
378
|
-
: `edge-${sourceNodeId}-${id}`,
|
|
379
|
-
source: sourceNodeId,
|
|
380
|
-
target: id,
|
|
381
|
-
...(edgeType ? { type: edgeType } : { style: { strokeDasharray: '5 5' } }),
|
|
382
|
-
},
|
|
383
|
-
]);
|
|
384
|
-
}
|
|
321
|
+
// Run dagre layout on the full graph so the new node is positioned consistently
|
|
322
|
+
const layoutResult = layoutWithDagre(allNodes, allEdges, CANVAS_LAYOUT_DEFAULTS);
|
|
323
|
+
setEdges(layoutResult.edges);
|
|
324
|
+
return layoutResult.nodes;
|
|
325
|
+
});
|
|
385
326
|
|
|
386
327
|
return id;
|
|
387
328
|
},
|
|
@@ -389,80 +330,115 @@ export function useControlCenterState(
|
|
|
389
330
|
);
|
|
390
331
|
|
|
391
332
|
const handleDeleteFeature = useCallback(
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
const result = await deleteFeature(featureId);
|
|
333
|
+
(featureId: string) => {
|
|
334
|
+
const nodeId = `feat-${featureId}`;
|
|
395
335
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
}
|
|
336
|
+
// Snapshot current state for rollback
|
|
337
|
+
const prevNodes = nodes;
|
|
338
|
+
const prevEdges = edgesRef.current;
|
|
400
339
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
)
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
340
|
+
// Optimistic removal — update UI immediately
|
|
341
|
+
setNodes((currentNodes) => {
|
|
342
|
+
const remainingNodes = currentNodes.filter((n) => n.id !== nodeId);
|
|
343
|
+
const remainingEdges = edgesRef.current.filter(
|
|
344
|
+
(e) => e.source !== nodeId && e.target !== nodeId
|
|
345
|
+
);
|
|
346
|
+
const layoutResult = layoutWithDagre(
|
|
347
|
+
remainingNodes,
|
|
348
|
+
remainingEdges,
|
|
349
|
+
CANVAS_LAYOUT_DEFAULTS
|
|
350
|
+
);
|
|
351
|
+
setEdges(layoutResult.edges);
|
|
352
|
+
return layoutResult.nodes;
|
|
353
|
+
});
|
|
354
|
+
deleteSound.play();
|
|
355
|
+
toast.success('Feature deleted successfully');
|
|
356
|
+
router.push('/');
|
|
357
|
+
|
|
358
|
+
// Persist in background — rollback on failure
|
|
359
|
+
deleteFeature(featureId)
|
|
360
|
+
.then((result) => {
|
|
361
|
+
if (result.error) {
|
|
362
|
+
setNodes(prevNodes);
|
|
363
|
+
setEdges(prevEdges);
|
|
364
|
+
toast.error(result.error);
|
|
365
|
+
}
|
|
366
|
+
})
|
|
367
|
+
.catch(() => {
|
|
368
|
+
setNodes(prevNodes);
|
|
369
|
+
setEdges(prevEdges);
|
|
370
|
+
toast.error('Failed to delete feature');
|
|
413
371
|
});
|
|
414
|
-
deleteSound.play();
|
|
415
|
-
toast.success('Feature deleted successfully');
|
|
416
|
-
router.refresh();
|
|
417
|
-
} catch {
|
|
418
|
-
toast.error('Failed to delete feature');
|
|
419
|
-
}
|
|
420
372
|
},
|
|
421
|
-
[
|
|
373
|
+
[nodes, router, deleteSound, setEdges]
|
|
422
374
|
);
|
|
423
375
|
|
|
424
376
|
const handleDeleteRepository = useCallback(
|
|
425
377
|
async (repositoryId: string) => {
|
|
426
378
|
const repoNodeId = `repo-${repositoryId}`;
|
|
427
379
|
|
|
428
|
-
//
|
|
429
|
-
|
|
430
|
-
|
|
380
|
+
// Snapshot for rollback
|
|
381
|
+
const prevNodes = nodes;
|
|
382
|
+
const prevEdges = edgesRef.current;
|
|
383
|
+
|
|
384
|
+
// Optimistic: remove repo node, its child feature nodes, and all related edges
|
|
385
|
+
setNodes((currentNodes) => {
|
|
386
|
+
// Find feature node IDs connected to this repo via edges
|
|
387
|
+
const childFeatureIds = new Set(
|
|
388
|
+
edgesRef.current.filter((e) => e.source === repoNodeId).map((e) => e.target)
|
|
389
|
+
);
|
|
390
|
+
const remainingNodes = currentNodes.filter(
|
|
391
|
+
(n) => n.id !== repoNodeId && !childFeatureIds.has(n.id)
|
|
392
|
+
);
|
|
393
|
+
const remainingEdges = edgesRef.current.filter(
|
|
394
|
+
(e) =>
|
|
395
|
+
e.source !== repoNodeId &&
|
|
396
|
+
e.target !== repoNodeId &&
|
|
397
|
+
!childFeatureIds.has(e.source) &&
|
|
398
|
+
!childFeatureIds.has(e.target)
|
|
399
|
+
);
|
|
400
|
+
const layoutResult = layoutWithDagre(
|
|
401
|
+
remainingNodes,
|
|
402
|
+
remainingEdges,
|
|
403
|
+
CANVAS_LAYOUT_DEFAULTS
|
|
404
|
+
);
|
|
405
|
+
setEdges(layoutResult.edges);
|
|
406
|
+
return layoutResult.nodes;
|
|
407
|
+
});
|
|
431
408
|
|
|
432
409
|
try {
|
|
433
410
|
const result = await deleteRepository(repositoryId);
|
|
434
411
|
|
|
435
412
|
if (!result.success) {
|
|
436
413
|
toast.error(result.error ?? 'Failed to remove repository');
|
|
437
|
-
|
|
414
|
+
setNodes(prevNodes);
|
|
415
|
+
setEdges(prevEdges);
|
|
438
416
|
return;
|
|
439
417
|
}
|
|
440
418
|
|
|
441
419
|
deleteSound.play();
|
|
442
420
|
toast.success('Repository removed');
|
|
443
|
-
router.refresh();
|
|
444
421
|
} catch {
|
|
445
422
|
toast.error('Failed to remove repository');
|
|
446
|
-
|
|
423
|
+
setNodes(prevNodes);
|
|
424
|
+
setEdges(prevEdges);
|
|
447
425
|
}
|
|
448
426
|
},
|
|
449
|
-
[
|
|
427
|
+
[nodes, deleteSound, setEdges]
|
|
450
428
|
);
|
|
451
429
|
|
|
452
430
|
const handleLayout = useCallback(
|
|
453
431
|
(direction: LayoutDirection) => {
|
|
454
432
|
setNodes((currentNodes) => {
|
|
455
|
-
const
|
|
456
|
-
|
|
433
|
+
const result = layoutWithDagre(currentNodes, edgesRef.current, {
|
|
434
|
+
...CANVAS_LAYOUT_DEFAULTS,
|
|
457
435
|
direction,
|
|
458
|
-
ranksep: 60,
|
|
459
|
-
nodesep: 20,
|
|
460
436
|
});
|
|
461
437
|
setEdges(result.edges);
|
|
462
438
|
return result.nodes;
|
|
463
439
|
});
|
|
464
440
|
},
|
|
465
|
-
[
|
|
441
|
+
[setEdges]
|
|
466
442
|
);
|
|
467
443
|
|
|
468
444
|
const handleAddRepository = useCallback(
|
|
@@ -474,58 +450,36 @@ export function useControlCenterState(
|
|
|
474
450
|
.split(/[\\/]/)
|
|
475
451
|
.pop() ?? path;
|
|
476
452
|
|
|
477
|
-
// Optimistic UI: add node immediately
|
|
478
|
-
let savedAddRepoY = 0;
|
|
453
|
+
// Optimistic UI: add node and re-layout immediately
|
|
479
454
|
setNodes((currentNodes) => {
|
|
480
|
-
const repoNodes = currentNodes.filter((n) => n.type === 'repositoryNode');
|
|
481
|
-
const addRepoNode = currentNodes.find((n) => n.type === 'addRepositoryNode');
|
|
482
|
-
|
|
483
|
-
// Save addRepoNode's original Y for rollback on error
|
|
484
|
-
if (addRepoNode) savedAddRepoY = addRepoNode.position.y;
|
|
485
|
-
|
|
486
|
-
// Place in the repo column, at the addRepoNode's current position
|
|
487
|
-
const repoX = repoNodes[0]?.position.x ?? addRepoNode?.position.x ?? 50;
|
|
488
|
-
const repoHeight = 50; // repositoryNode height
|
|
489
|
-
const gap = 15; // match dagre nodesep
|
|
490
|
-
|
|
491
|
-
const position = {
|
|
492
|
-
x: repoX,
|
|
493
|
-
y: addRepoNode ? addRepoNode.position.y : 0,
|
|
494
|
-
};
|
|
495
|
-
|
|
496
455
|
const newNode = {
|
|
497
456
|
id: tempId,
|
|
498
457
|
type: 'repositoryNode' as const,
|
|
499
|
-
position,
|
|
458
|
+
position: { x: 0, y: 0 },
|
|
500
459
|
data: { name: repoName, repositoryPath: path, id: tempId },
|
|
501
460
|
} as CanvasNodeType;
|
|
502
461
|
|
|
503
|
-
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
return currentNodes
|
|
509
|
-
.map((n) =>
|
|
510
|
-
n.type === 'addRepositoryNode' ? { ...n, position: { ...n.position, y: addRepoY } } : n
|
|
511
|
-
)
|
|
512
|
-
.concat(newNode);
|
|
462
|
+
const allNodes = [...currentNodes, newNode];
|
|
463
|
+
const layoutResult = layoutWithDagre(allNodes, edgesRef.current, CANVAS_LAYOUT_DEFAULTS);
|
|
464
|
+
setEdges(layoutResult.edges);
|
|
465
|
+
return layoutResult.nodes;
|
|
513
466
|
});
|
|
514
467
|
|
|
515
468
|
// Persist via server action
|
|
516
469
|
addRepository({ path, name: repoName })
|
|
517
470
|
.then((result) => {
|
|
518
471
|
if (result.error) {
|
|
519
|
-
// Rollback optimistic node and
|
|
520
|
-
setNodes((prev) =>
|
|
521
|
-
prev
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
472
|
+
// Rollback optimistic node and re-layout
|
|
473
|
+
setNodes((prev) => {
|
|
474
|
+
const remaining = prev.filter((n) => n.id !== tempId);
|
|
475
|
+
const layoutResult = layoutWithDagre(
|
|
476
|
+
remaining,
|
|
477
|
+
edgesRef.current,
|
|
478
|
+
CANVAS_LAYOUT_DEFAULTS
|
|
479
|
+
);
|
|
480
|
+
setEdges(layoutResult.edges);
|
|
481
|
+
return layoutResult.nodes;
|
|
482
|
+
});
|
|
529
483
|
toast.error(result.error);
|
|
530
484
|
return;
|
|
531
485
|
}
|
|
@@ -554,23 +508,23 @@ export function useControlCenterState(
|
|
|
554
508
|
);
|
|
555
509
|
|
|
556
510
|
createSound.play();
|
|
557
|
-
router.refresh();
|
|
558
511
|
})
|
|
559
512
|
.catch(() => {
|
|
560
|
-
// Rollback optimistic node and
|
|
561
|
-
setNodes((prev) =>
|
|
562
|
-
prev
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
513
|
+
// Rollback optimistic node and re-layout
|
|
514
|
+
setNodes((prev) => {
|
|
515
|
+
const remaining = prev.filter((n) => n.id !== tempId);
|
|
516
|
+
const layoutResult = layoutWithDagre(
|
|
517
|
+
remaining,
|
|
518
|
+
edgesRef.current,
|
|
519
|
+
CANVAS_LAYOUT_DEFAULTS
|
|
520
|
+
);
|
|
521
|
+
setEdges(layoutResult.edges);
|
|
522
|
+
return layoutResult.nodes;
|
|
523
|
+
});
|
|
570
524
|
toast.error('Failed to add repository');
|
|
571
525
|
});
|
|
572
526
|
},
|
|
573
|
-
[
|
|
527
|
+
[createSound, setEdges]
|
|
574
528
|
);
|
|
575
529
|
|
|
576
530
|
return {
|
|
@@ -22,6 +22,7 @@ function AlertDialogPortal({ ...props }: React.ComponentProps<typeof AlertDialog
|
|
|
22
22
|
|
|
23
23
|
function AlertDialogOverlay({
|
|
24
24
|
className,
|
|
25
|
+
onClick,
|
|
25
26
|
...props
|
|
26
27
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
|
|
27
28
|
return (
|
|
@@ -31,6 +32,12 @@ function AlertDialogOverlay({
|
|
|
31
32
|
'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',
|
|
32
33
|
className
|
|
33
34
|
)}
|
|
35
|
+
onClick={(e) => {
|
|
36
|
+
// Prevent overlay clicks from propagating to document-level handlers
|
|
37
|
+
// (e.g. BaseDrawer outside-click) — only the dialog should dismiss.
|
|
38
|
+
e.stopPropagation();
|
|
39
|
+
onClick?.(e);
|
|
40
|
+
}}
|
|
34
41
|
{...props}
|
|
35
42
|
/>
|
|
36
43
|
);
|
|
@@ -17,13 +17,19 @@ const DialogClose = DialogPrimitive.Close;
|
|
|
17
17
|
const DialogOverlay = React.forwardRef<
|
|
18
18
|
React.ComponentRef<typeof DialogPrimitive.Overlay>,
|
|
19
19
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
|
20
|
-
>(({ className, ...props }, ref) => (
|
|
20
|
+
>(({ className, onClick, ...props }, ref) => (
|
|
21
21
|
<DialogPrimitive.Overlay
|
|
22
22
|
ref={ref}
|
|
23
23
|
className={cn(
|
|
24
24
|
'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',
|
|
25
25
|
className
|
|
26
26
|
)}
|
|
27
|
+
onClick={(e) => {
|
|
28
|
+
// Prevent overlay clicks from propagating to document-level handlers
|
|
29
|
+
// (e.g. BaseDrawer outside-click) — only the dialog should dismiss.
|
|
30
|
+
e.stopPropagation();
|
|
31
|
+
onClick?.(e);
|
|
32
|
+
}}
|
|
27
33
|
{...props}
|
|
28
34
|
/>
|
|
29
35
|
));
|