@shepai/cli 1.177.0 → 1.178.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apis/json-schema/Language.yaml +1 -0
- package/dist/packages/core/src/application/ports/output/services/agent-auth-detector.interface.d.ts +23 -0
- package/dist/packages/core/src/application/ports/output/services/agent-auth-detector.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/agent-auth-detector.interface.js +13 -0
- package/dist/packages/core/src/application/ports/output/services/file-system-service.interface.d.ts +18 -0
- package/dist/packages/core/src/application/ports/output/services/file-system-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/file-system-service.interface.js +7 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts +3 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/project-scaffold-service.interface.d.ts +33 -0
- package/dist/packages/core/src/application/ports/output/services/project-scaffold-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/project-scaffold-service.interface.js +9 -0
- package/dist/packages/core/src/application/use-cases/agents/check-agent-auth.use-case.d.ts +42 -0
- package/dist/packages/core/src/application/use-cases/agents/check-agent-auth.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/agents/check-agent-auth.use-case.js +134 -0
- package/dist/packages/core/src/application/use-cases/projects/create-project.use-case.d.ts +43 -0
- package/dist/packages/core/src/application/use-cases/projects/create-project.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/projects/create-project.use-case.js +84 -0
- package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts +13 -2
- 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 +14 -3
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +16 -0
- package/dist/packages/core/src/infrastructure/services/agent-auth-detector/platform-agent-auth-detector.service.d.ts +35 -0
- package/dist/packages/core/src/infrastructure/services/agent-auth-detector/platform-agent-auth-detector.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agent-auth-detector/platform-agent-auth-detector.service.js +165 -0
- package/dist/packages/core/src/infrastructure/services/file-system.service.d.ts +10 -0
- package/dist/packages/core/src/infrastructure/services/file-system.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/file-system.service.js +22 -0
- package/dist/packages/core/src/infrastructure/services/project-scaffold/fs-project-scaffold.service.d.ts +22 -0
- package/dist/packages/core/src/infrastructure/services/project-scaffold/fs-project-scaffold.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/project-scaffold/fs-project-scaffold.service.js +74 -0
- package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts +10 -2
- package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/check-agent-auth.js +7 -199
- package/dist/src/presentation/web/app/actions/create-project-folder.d.ts +16 -0
- package/dist/src/presentation/web/app/actions/create-project-folder.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/create-project-folder.js +18 -0
- package/dist/src/presentation/web/app/actions/delete-repository.d.ts +4 -1
- package/dist/src/presentation/web/app/actions/delete-repository.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/delete-repository.js +2 -2
- 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 +2 -2
- package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts +3 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts.map +1 -1
- 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 +13 -4
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +5 -3
- 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 +134 -124
- package/dist/src/presentation/web/components/features/control-center/new-project-dialog.d.ts +8 -0
- package/dist/src/presentation/web/components/features/control-center/new-project-dialog.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/new-project-dialog.js +43 -0
- package/dist/src/presentation/web/components/features/control-center/use-canvas-event-listeners.d.ts +27 -0
- package/dist/src/presentation/web/components/features/control-center/use-canvas-event-listeners.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/use-canvas-event-listeners.js +84 -0
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -1
- 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 +4 -2
- package/dist/src/presentation/web/components/features/control-center/use-fab-actions.d.ts +21 -0
- package/dist/src/presentation/web/components/features/control-center/use-fab-actions.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/use-fab-actions.js +70 -0
- package/dist/src/presentation/web/components/features/control-center/use-workspace-fit-view.d.ts +27 -0
- package/dist/src/presentation/web/components/features/control-center/use-workspace-fit-view.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/use-workspace-fit-view.js +48 -0
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.js +8 -1
- package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.d.ts +3 -1
- package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.js +3 -3
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/manage-workspace-dialog.d.ts +15 -0
- package/dist/src/presentation/web/components/features/features-canvas/manage-workspace-dialog.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/features-canvas/manage-workspace-dialog.js +74 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-name-dialog.d.ts +11 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-name-dialog.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-name-dialog.js +22 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-selector.d.ts +13 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-selector.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/features-canvas/workspace-selector.js +21 -0
- package/dist/src/presentation/web/hooks/use-workspaces.d.ts +37 -0
- package/dist/src/presentation/web/hooks/use-workspaces.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/use-workspaces.js +219 -0
- package/dist/src/presentation/web/lib/derive-graph.d.ts +3 -1
- package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
- package/dist/translations/ar/web.json +4 -1
- package/dist/translations/de/web.json +4 -1
- package/dist/translations/en/web.json +4 -1
- package/dist/translations/es/web.json +4 -1
- package/dist/translations/fr/web.json +4 -1
- package/dist/translations/he/web.json +4 -1
- package/dist/translations/pt/web.json +4 -1
- package/dist/translations/ru/web.json +4 -1
- package/dist/translations/uk/web.json +3 -0
- 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/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +2 -2
- package/web/.next/required-server-files.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +73 -58
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +69 -54
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +75 -60
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -2
- 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]/[tab]/page/server-reference-manifest.json +91 -76
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +91 -76
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -2
- 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]/[tab]/page/server-reference-manifest.json +71 -56
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +71 -56
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -2
- 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)/chat/page/server-reference-manifest.json +69 -54
- package/web/.next/server/app/(dashboard)/chat/page.js +1 -2
- package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +75 -60
- package/web/.next/server/app/(dashboard)/create/page.js +1 -2
- 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]/[tab]/page/server-reference-manifest.json +91 -76
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +91 -76
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -2
- 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 +69 -54
- package/web/.next/server/app/(dashboard)/page.js +1 -2
- 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]/[tab]/page/server-reference-manifest.json +71 -56
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +1 -2
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +71 -56
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -2
- 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 +6 -6
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
- package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
- package/web/.next/server/app/features/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/features/page.js.nft.json +1 -1
- package/web/.next/server/app/features/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +13 -13
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/tools/page.js.nft.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 +6 -6
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.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/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__23b5ca2c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__46b10380._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__46b10380._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7528eb6f._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8b512877._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8b512877._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__990dba2d._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__990dba2d._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cc9c7bbb._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cc9c7bbb._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
- package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_35b56ded._.js +3 -0
- package/web/.next/server/chunks/ssr/_35b56ded._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_4cbb7f95._.js → _496c9117._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_4cbb7f95._.js.map → _496c9117._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_3fc2374c._.js → _49b9ba41._.js} +2 -2
- package/web/.next/server/chunks/ssr/_49b9ba41._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
- package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_64efdf53._.js +3 -0
- package/web/.next/server/chunks/ssr/_64efdf53._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_6abfa39e._.js +1 -1
- package/web/.next/server/chunks/ssr/{_19a779c6._.js → _83e1c526._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_19a779c6._.js.map → _83e1c526._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_f8c55130._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_06109d28._.js +5 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_06109d28._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_0bca70f8._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_0bca70f8._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_367cdbe0._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_367cdbe0._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_57fed7fd._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_57fed7fd._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_7f567f6d._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_7f567f6d._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_972f58d5._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_972f58d5._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_a71b18a2._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_a71b18a2._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_bebe675e._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_bebe675e._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_c93e8bc6._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_c93e8bc6._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.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/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e729f44a._.js +5 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_e729f44a._.js.map +1 -0
- package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js +1 -1
- package/web/.next/server/chunks/ssr/translations_23dd5e7e._.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 +590 -484
- package/web/.next/static/chunks/{18f429029d702545.js → 0b7251e5d717dd17.js} +1 -1
- package/web/.next/static/chunks/0fd39d549d277843.js +1 -0
- package/web/.next/static/chunks/124b79a5d2a760fb.css +1 -0
- package/web/.next/static/chunks/{b5a916fec4cdc897.js → 25a0d3f50b0a26c1.js} +1 -1
- package/web/.next/static/chunks/{829d2f8ef2715f2f.js → 2cc487403c107f3f.js} +3 -3
- package/web/.next/static/chunks/{0d0e2661bd167e0f.js → 35bf9838f21d1818.js} +1 -1
- package/web/.next/static/chunks/{b5d355eb59916926.js → 36e3d626ed8defca.js} +2 -2
- package/web/.next/static/chunks/4052a4971fbbac9c.js +1 -0
- package/web/.next/static/chunks/{c0e4cd44851a9293.js → 5df9da8b40e298ee.js} +1 -1
- package/web/.next/static/chunks/{efd57b6ffc7cbd54.js → 5f57f0d80d3db147.js} +1 -1
- package/web/.next/static/chunks/{bb479c31b5b53bac.js → 74c37f189bc83156.js} +2 -2
- package/web/.next/static/chunks/8057357cf1f9b4ef.js +1 -0
- package/web/.next/static/chunks/{eaa1b979d63d322b.js → 8286914ac835a1cc.js} +1 -1
- package/web/.next/static/chunks/{0a706f8508eae0a8.js → 8777b2a0a2e85fd1.js} +2 -2
- package/web/.next/static/chunks/{77d6506c7d1f711f.js → 9e9cddf8e38342e8.js} +1 -1
- package/web/.next/static/chunks/ac586c86d71187fc.js +1 -0
- package/web/.next/static/chunks/{ef897f150084ef85.js → c6fdd161a9e5b554.js} +1 -1
- package/web/.next/static/chunks/{4c20d4cd4786a0c8.js → e167803ac69c66c7.js} +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_ad0071c9.js +0 -3
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_ad0071c9.js.map +0 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_90d98b2b.js +0 -3
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_90d98b2b.js.map +0 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_d3828105.js +0 -3
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_d3828105.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__51ec77a8._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__51ec77a8._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__66047a1b._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__66047a1b._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a932cd3a._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a932cd3a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aa72e794._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aa72e794._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_073183f4._.js +0 -3
- package/web/.next/server/chunks/ssr/_073183f4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_3fc2374c._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_57b1af27._.js +0 -3
- package/web/.next/server/chunks/ssr/_57b1af27._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_17d39233._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_17d39233._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_54b02639._.js +0 -5
- package/web/.next/server/chunks/ssr/src_presentation_web_54b02639._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_7b7b9e3b._.js +0 -5
- package/web/.next/server/chunks/ssr/src_presentation_web_7b7b9e3b._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_807cba76._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_807cba76._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_90b5e66e.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_90b5e66e.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e1cd1869._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_e1cd1869._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e3a30e30._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_e3a30e30._.js.map +0 -1
- package/web/.next/static/chunks/3fc5b2287f192799.js +0 -1
- package/web/.next/static/chunks/a20f2d6f76f469b7.css +0 -1
- package/web/.next/static/chunks/ddd34e939acc204f.js +0 -1
- package/web/.next/static/chunks/f9d948464ed409cb.js +0 -1
- package/web/.next/static/chunks/fc0232384ec2b48d.js +0 -1
- /package/web/.next/static/{UZ2czjiAnEl1RF-HTzHyA → sfBZvlx-erv7S1C49vRSU}/_buildManifest.js +0 -0
- /package/web/.next/static/{UZ2czjiAnEl1RF-HTzHyA → sfBZvlx-erv7S1C49vRSU}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{UZ2czjiAnEl1RF-HTzHyA → sfBZvlx-erv7S1C49vRSU}/_ssgManifest.js +0 -0
package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts
CHANGED
|
@@ -21,7 +21,9 @@ export interface RepositoryNodeData {
|
|
|
21
21
|
gitInfoStatus?: 'loading' | 'ready' | 'not-a-repo';
|
|
22
22
|
onClick?: () => void;
|
|
23
23
|
onAdd?: () => void;
|
|
24
|
-
onDelete?: (repositoryId: string
|
|
24
|
+
onDelete?: (repositoryId: string, options?: {
|
|
25
|
+
deleteFromDisk?: boolean;
|
|
26
|
+
}) => void;
|
|
25
27
|
showHandles?: boolean;
|
|
26
28
|
/** When true, the "+" add-feature button shows a pulse attention animation. */
|
|
27
29
|
pulseAdd?: boolean;
|
package/dist/src/presentation/web/components/common/repository-node/repository-node-config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-node-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,qEAAqE;IACrE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+GAA+G;IAC/G,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oHAAoH;IACpH,aAAa,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,YAAY,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"repository-node-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,qEAAqE;IACrE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+GAA+G;IAC/G,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oHAAoH;IACpH,aAAa,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,YAAY,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAClF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC"}
|
package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAueA"}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useCallback } from 'react';
|
|
3
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
4
4
|
import { Handle, Position } from '@xyflow/react';
|
|
5
5
|
import { useRouter } from 'next/navigation';
|
|
6
6
|
import { Github, Plus, Code2, Terminal, FolderOpen, Trash2, Play, Square, GitBranch, GitCommitHorizontal, ArrowDown, User, RotateCcw, MessageSquare, } from 'lucide-react';
|
|
7
|
-
import { useTranslation } from 'react-i18next';
|
|
7
|
+
import { Trans, useTranslation } from 'react-i18next';
|
|
8
8
|
import { cn } from '../../../lib/utils.js';
|
|
9
9
|
import { ActionButton } from '../../common/action-button/index.js';
|
|
10
10
|
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
|
|
11
11
|
import { Button } from '../../ui/button.js';
|
|
12
|
+
import { Checkbox } from '../../ui/checkbox.js';
|
|
13
|
+
import { Label } from '../../ui/label.js';
|
|
12
14
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
|
|
13
15
|
import { useDeployAction } from '../../../hooks/use-deploy-action.js';
|
|
14
16
|
import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
|
|
@@ -24,6 +26,11 @@ export function RepositoryNode({ data, selected, }) {
|
|
|
24
26
|
const sourceHandlePos = isRtl ? Position.Left : Position.Right;
|
|
25
27
|
const featureFlags = useFeatureFlags();
|
|
26
28
|
const [confirmOpen, setConfirmOpen] = useState(false);
|
|
29
|
+
const [deleteFromDisk, setDeleteFromDisk] = useState(false);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (confirmOpen)
|
|
32
|
+
setDeleteFromDisk(false);
|
|
33
|
+
}, [confirmOpen]);
|
|
27
34
|
const repoScopeId = data.id ? `repo-${data.id}` : `repo-${data.name}`;
|
|
28
35
|
const chatTurnStatus = useTurnStatus(repoScopeId);
|
|
29
36
|
const actions = useRepositoryActions(data.repositoryPath ? { repositoryId: data.id, repositoryPath: data.repositoryPath } : null);
|
|
@@ -68,9 +75,11 @@ export function RepositoryNode({ data, selected, }) {
|
|
|
68
75
|
return (_jsxs("div", { className: cn('group relative', data.onDelete && data.id && 'ps-10'), style: { direction: isRtl ? 'rtl' : 'ltr' }, children: [data.showHandles ? (_jsx(Handle, { type: "target", position: targetHandlePos, isConnectable: false, className: "opacity-0!", style: { top: 70 } })) : null, data.onDelete && data.id ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute -start-3 top-1/2 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": t('repositoryNode.removeRepository'), "data-testid": "repository-node-delete-button", onClick: (e) => {
|
|
69
76
|
e.stopPropagation();
|
|
70
77
|
setConfirmOpen(true);
|
|
71
|
-
}, className: "bg-card text-muted-foreground hover:border-destructive hover:text-destructive flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border shadow-sm transition-colors", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: t('repositoryNode.removeRepository') })] }) }) }), _jsx(Dialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(DialogContent, { className: "max-w-
|
|
78
|
+
}, className: "bg-card text-muted-foreground hover:border-destructive hover:text-destructive flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border shadow-sm transition-colors", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: t('repositoryNode.removeRepository') })] }) }) }), _jsx(Dialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(DialogContent, { className: "max-w-sm", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t('repositoryNode.removeConfirmTitle') }), _jsxs(DialogDescription, { children: [_jsx(Trans, { t: t, i18nKey: "repositoryNode.removeConfirmDescription", values: { name: data.name }, components: { strong: _jsx("strong", {}) } }), ' ', deleteFromDisk
|
|
79
|
+
? t('repositoryNode.removeConfirmDescriptionDeleteFiles')
|
|
80
|
+
: t('repositoryNode.removeConfirmDescriptionKeepFiles')] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "repository-delete-from-disk", checked: deleteFromDisk, onCheckedChange: (checked) => setDeleteFromDisk(checked === true), "data-testid": "repository-node-delete-from-disk-checkbox", "aria-label": t('repositoryNode.deleteFromDiskLabel') }), _jsx(Label, { htmlFor: "repository-delete-from-disk", className: "cursor-pointer text-sm font-normal", children: t('repositoryNode.deleteFromDiskLabel') })] }), _jsxs(DialogFooter, { className: "grid grid-cols-2 gap-2 sm:flex-none", children: [_jsx(DialogClose, { asChild: true, children: _jsx(Button, { variant: "outline", children: t('repositoryNode.cancel') }) }), _jsx(Button, { variant: "destructive", "data-testid": "repository-node-delete-confirm-button", onClick: () => {
|
|
72
81
|
setConfirmOpen(false);
|
|
73
|
-
data.onDelete?.(data.id);
|
|
82
|
+
data.onDelete?.(data.id, { deleteFromDisk });
|
|
74
83
|
}, children: t('repositoryNode.remove') })] })] }) })] })) : null, _jsxs("div", { role: "button", tabIndex: 0, "data-testid": "repository-node-card", "data-repo-name": data.name, onClick: (e) => {
|
|
75
84
|
e.stopPropagation();
|
|
76
85
|
data.onClick?.();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-center-empty-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"control-center-empty-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.tsx"],"names":[],"mappings":"AA4BA,MAAM,WAAW,4BAA4B;IAC3C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,uBAAuB,CAAC,EACtC,kBAAkB,EAClB,SAAS,GACV,EAAE,4BAA4B,kDAsN9B"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useCallback, useEffect } from 'react';
|
|
4
|
-
import { FolderOpen, Copy, Check, Loader2, CheckCircle2, AlertCircle, Terminal, ChevronDown, ExternalLink, } from 'lucide-react';
|
|
4
|
+
import { FolderOpen, FolderPlus, Copy, Check, Loader2, CheckCircle2, AlertCircle, Terminal, ChevronDown, ExternalLink, } from 'lucide-react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import { cn } from '../../../lib/utils.js';
|
|
7
7
|
import { pickFolder } from '../../common/add-repository-button/pick-folder.js';
|
|
@@ -11,6 +11,7 @@ import { isAgentSetupComplete } from '../../../app/actions/agent-setup-flag.js';
|
|
|
11
11
|
import { checkAgentAuth } from '../../../app/actions/check-agent-auth.js';
|
|
12
12
|
import { checkToolStatus } from '../../../app/actions/check-tool-status.js';
|
|
13
13
|
import { WelcomeAgentSetup } from './welcome-agent-setup.js';
|
|
14
|
+
import { NewProjectDialog } from './new-project-dialog.js';
|
|
14
15
|
const commands = ['cd ~/my-repo', 'shep feat new "sleek dashboard"'];
|
|
15
16
|
export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
16
17
|
const { t } = useTranslation('web');
|
|
@@ -21,6 +22,7 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
21
22
|
const [authStatus, setAuthStatus] = useState(null);
|
|
22
23
|
const [cliExpanded, setCliExpanded] = useState(false);
|
|
23
24
|
const [toolStatus, setToolStatus] = useState(null);
|
|
25
|
+
const [newProjectOpen, setNewProjectOpen] = useState(false);
|
|
24
26
|
const { reactFileManager: useReactFileManager } = useFeatureFlags();
|
|
25
27
|
useEffect(() => {
|
|
26
28
|
isAgentSetupComplete().then((done) => {
|
|
@@ -79,14 +81,14 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
79
81
|
/* Agent setup wizard — owns its own hero */
|
|
80
82
|
_jsx(WelcomeAgentSetup, { onComplete: handleAgentSetupComplete })) : (
|
|
81
83
|
/* Repository step — fade in to match wizard transitions */
|
|
82
|
-
_jsxs("div", { className: "animate-in fade-in flex w-full max-w-md flex-col items-center duration-300", children: [_jsx("h1", { className: "text-foreground/90 text-center text-5xl font-extralight tracking-tight", children: t('emptyState.addProject') }), _jsxs("p", { className: "text-muted-foreground mt-3 text-center text-lg leading-relaxed font-light", children: [t('emptyState.addProjectDescription'), _jsx("br", {}), t('emptyState.addProjectDescriptionLine2')] }), _jsxs("div", { className: "mt-8 flex w-full flex-col gap-3", children: [_jsx(AgentAuthBanner, { status: authStatus, onRetry: handleRetryAuth }), _jsx(ToolStatusRow, { label: t('emptyState.git'), status: toolStatus?.git ?? null, missingHint: t('emptyState.gitRequired') }), _jsx(ToolStatusRow, { label: t('emptyState.githubCli'), status: toolStatus?.gh ?? null, missingHint: t('emptyState.githubCliRequired') })] }), _jsxs("button", { type: "button", "data-testid": "empty-state-add-repository", onClick: handlePickerClick, disabled: loading, className: "bg-foreground text-background hover:bg-foreground/90 mt-10 flex w-full cursor-pointer items-center justify-center gap-2.5 rounded-xl px-6 py-4 text-base font-medium shadow-lg transition-all duration-200 hover:shadow-xl active:scale-[0.98] disabled:cursor-wait disabled:opacity-50", children: [loading ? (_jsx(Loader2, { className: "h-5 w-5 animate-spin" })) : (_jsx(FolderOpen, { className: "h-5 w-5" })), loading ? t('emptyState.opening') : t('emptyState.chooseFolder')] }), _jsx("p", { className: "text-muted-foreground/60 mt-3 text-center text-sm", children: t('emptyState.folderHint') })] })), agentReady ? (_jsxs("div", { className: "absolute bottom-8 flex flex-col items-center", style: {
|
|
84
|
+
_jsxs("div", { className: "animate-in fade-in flex w-full max-w-md flex-col items-center duration-300", children: [_jsx("h1", { className: "text-foreground/90 text-center text-5xl font-extralight tracking-tight", children: t('emptyState.addProject') }), _jsxs("p", { className: "text-muted-foreground mt-3 text-center text-lg leading-relaxed font-light", children: [t('emptyState.addProjectDescription'), _jsx("br", {}), t('emptyState.addProjectDescriptionLine2')] }), _jsxs("div", { className: "mt-8 flex w-full flex-col gap-3", children: [_jsx(AgentAuthBanner, { status: authStatus, onRetry: handleRetryAuth }), _jsx(ToolStatusRow, { label: t('emptyState.git'), status: toolStatus?.git ?? null, missingHint: t('emptyState.gitRequired') }), _jsx(ToolStatusRow, { label: t('emptyState.githubCli'), status: toolStatus?.gh ?? null, missingHint: t('emptyState.githubCliRequired') })] }), _jsxs("button", { type: "button", "data-testid": "empty-state-add-repository", onClick: handlePickerClick, disabled: loading, className: "bg-foreground text-background hover:bg-foreground/90 mt-10 flex w-full cursor-pointer items-center justify-center gap-2.5 rounded-xl px-6 py-4 text-base font-medium shadow-lg transition-all duration-200 hover:shadow-xl active:scale-[0.98] disabled:cursor-wait disabled:opacity-50", children: [loading ? (_jsx(Loader2, { className: "h-5 w-5 animate-spin" })) : (_jsx(FolderOpen, { className: "h-5 w-5" })), loading ? t('emptyState.opening') : t('emptyState.chooseFolder')] }), _jsxs("button", { type: "button", "data-testid": "empty-state-new-project", onClick: () => setNewProjectOpen(true), disabled: loading, className: "border-foreground/15 text-foreground/80 hover:bg-foreground/5 hover:border-foreground/25 mt-3 flex w-full cursor-pointer items-center justify-center gap-2.5 rounded-xl border px-6 py-3.5 text-sm font-medium transition-all duration-200 active:scale-[0.98] disabled:cursor-not-allowed disabled:opacity-50", children: [_jsx(FolderPlus, { className: "h-4 w-4" }), "New Project"] }), _jsx("p", { className: "text-muted-foreground/60 mt-3 text-center text-sm", children: t('emptyState.folderHint') })] })), agentReady ? (_jsxs("div", { className: "absolute bottom-8 flex flex-col items-center", style: {
|
|
83
85
|
animationDelay: '400ms',
|
|
84
86
|
animationDuration: '600ms',
|
|
85
87
|
animationFillMode: 'both',
|
|
86
88
|
}, children: [_jsxs("button", { type: "button", onClick: () => setCliExpanded(!cliExpanded), className: "text-muted-foreground hover:text-foreground flex cursor-pointer items-center gap-1.5 transition-colors duration-200", children: [_jsx(Terminal, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-sm", children: t('emptyState.orUseCli') }), _jsx(ChevronDown, { className: cn('h-3.5 w-3.5 transition-transform duration-200', cliExpanded ? '' : 'rotate-180') })] }), cliExpanded ? (_jsx("div", { className: "animate-in fade-in slide-in-from-top-1 mt-3 w-80 duration-200", children: _jsxs("div", { "data-testid": "cli-code-block", className: "relative rounded-xl bg-zinc-900 px-5 py-4 font-mono text-[13px] leading-relaxed text-zinc-400", children: [_jsx("button", { type: "button", "data-testid": "cli-code-block-copy", onClick: handleCopy, className: "absolute top-3 right-3 cursor-pointer rounded-md p-1.5 text-zinc-600 transition-colors hover:bg-zinc-800 hover:text-zinc-300", "aria-label": t('emptyState.copyCommands'), children: copied ? (_jsx(Check, { className: "h-3.5 w-3.5 text-emerald-400" })) : (_jsx(Copy, { className: "h-3.5 w-3.5" })) }), _jsx("div", { className: "space-y-1", children: commands.map((cmd) => (_jsxs("div", { className: "whitespace-nowrap", children: [_jsx("span", { className: "text-zinc-600 select-none", children: "$ " }), _jsx("span", { className: "text-zinc-300", children: cmd })] }, cmd))) })] }) })) : null] })) : null, _jsx(ReactFileManagerDialog, { open: showReactPicker, onOpenChange: (open) => {
|
|
87
89
|
if (!open)
|
|
88
90
|
setShowReactPicker(false);
|
|
89
|
-
}, onSelect: handleReactPickerSelect })] }));
|
|
91
|
+
}, onSelect: handleReactPickerSelect }), _jsx(NewProjectDialog, { open: newProjectOpen, onOpenChange: setNewProjectOpen, onCreated: (path) => onRepositorySelect?.(path) })] }));
|
|
90
92
|
}
|
|
91
93
|
/** Status row for the AI agent (Claude Code, etc.) */
|
|
92
94
|
function AgentAuthBanner({ status, onRetry, }) {
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAoBpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAoC5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CA2iBzF"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { useRouter, usePathname } from 'next/navigation';
|
|
5
|
-
import {
|
|
5
|
+
import { FolderPlus } from 'lucide-react';
|
|
6
6
|
import { useReactFlow } from '@xyflow/react';
|
|
7
7
|
import { FeaturesCanvas } from '../../features/features-canvas/index.js';
|
|
8
8
|
import { CanvasToolbar } from '../../features/features-canvas/canvas-toolbar.js';
|
|
9
|
+
import { WorkspaceSelector } from '../../features/features-canvas/workspace-selector.js';
|
|
10
|
+
import { ManageWorkspaceDialog } from '../../features/features-canvas/manage-workspace-dialog.js';
|
|
11
|
+
import { WorkspaceNameDialog } from '../../features/features-canvas/workspace-name-dialog.js';
|
|
12
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '../../ui/alert-dialog.js';
|
|
13
|
+
import { useWorkspaces, DEFAULT_WORKSPACE_ID } from '../../../hooks/use-workspaces.js';
|
|
14
|
+
import { Layers, Plus } from 'lucide-react';
|
|
15
|
+
import { Button } from '../../ui/button.js';
|
|
9
16
|
import { FloatingActionButton, } from '../../common/floating-action-button/index.js';
|
|
10
17
|
import { useSidebarFeaturesContext, mapNodeStateToSidebarStatus, } from '../../../hooks/sidebar-features-context.js';
|
|
11
18
|
import { useTranslation } from 'react-i18next';
|
|
@@ -18,7 +25,11 @@ import { useViewportPersistence } from '../../../hooks/use-viewport-persistence.
|
|
|
18
25
|
import { useSidebar } from '../../ui/sidebar.js';
|
|
19
26
|
import { useFabLayout } from '../../../hooks/fab-layout-context.js';
|
|
20
27
|
import { ControlCenterEmptyState } from './control-center-empty-state.js';
|
|
28
|
+
import { NewProjectDialog } from './new-project-dialog.js';
|
|
21
29
|
import { useControlCenterState } from './use-control-center-state.js';
|
|
30
|
+
import { useCanvasEventListeners } from './use-canvas-event-listeners.js';
|
|
31
|
+
import { useWorkspaceFitView } from './use-workspace-fit-view.js';
|
|
32
|
+
import { useFabActions } from './use-fab-actions.js';
|
|
22
33
|
const AUTO_FOCUS_OPTIONS = {
|
|
23
34
|
maxZoom: 1.0,
|
|
24
35
|
padding: 0.5,
|
|
@@ -26,7 +37,6 @@ const AUTO_FOCUS_OPTIONS = {
|
|
|
26
37
|
};
|
|
27
38
|
const AUTO_FOCUS_DRAWER_DELAY_MS = 600;
|
|
28
39
|
export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
29
|
-
const { t } = useTranslation('web');
|
|
30
40
|
const router = useRouter();
|
|
31
41
|
const pathname = usePathname();
|
|
32
42
|
const selectedFeatureId = useSelectedFeatureId();
|
|
@@ -37,6 +47,21 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
37
47
|
const drawerTimerRef = useRef(null);
|
|
38
48
|
const { defaultViewport, onMoveEnd: handleViewportChange, resetViewport, } = useViewportPersistence();
|
|
39
49
|
const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleArchiveFeature, handleDeleteFeature, handleRetryFeature, handleStartFeature, handleStopFeature, handleUnarchiveFeature, handleDeleteRepository, createFeatureNode, showArchived, setShowArchived, setCallbacks, } = useControlCenterState(initialNodes, initialEdges);
|
|
50
|
+
// ── Workspaces (client-only prototype) ────────────────────────────────
|
|
51
|
+
const { workspaces, activeWorkspace, isDefaultActive, setActiveWorkspace, createWorkspace, renameWorkspace, deleteWorkspace, setWorkspaceMembers, addToActiveWorkspace, } = useWorkspaces();
|
|
52
|
+
// Tracks the set of node ids we've already seen, so we can detect new
|
|
53
|
+
// repo/feature nodes appearing on the canvas and auto-include them in the
|
|
54
|
+
// active workspace (when it isn't the default).
|
|
55
|
+
const knownNodeIdsRef = useRef(new Set());
|
|
56
|
+
const [manageWorkspaceOpen, setManageWorkspaceOpen] = useState(false);
|
|
57
|
+
const [createWorkspaceOpen, setCreateWorkspaceOpen] = useState(false);
|
|
58
|
+
const [renameWorkspaceOpen, setRenameWorkspaceOpen] = useState(false);
|
|
59
|
+
const [deleteWorkspaceOpen, setDeleteWorkspaceOpen] = useState(false);
|
|
60
|
+
// Target of the delete confirmation dialog. Allows deleting any workspace
|
|
61
|
+
// (not just the active one) directly from the workspace dropdown.
|
|
62
|
+
const [pendingDeleteWorkspaceId, setPendingDeleteWorkspaceId] = useState(null);
|
|
63
|
+
// Inline "New Project" dialog launched from the empty-workspace state.
|
|
64
|
+
const [workspaceNewProjectOpen, setWorkspaceNewProjectOpen] = useState(false);
|
|
40
65
|
// Publish sidebar features + repo state to context
|
|
41
66
|
const { setFeatures: setSidebarFeatures, setHasRepositories: setSidebarHasRepos } = useSidebarFeaturesContext();
|
|
42
67
|
const featureNodes = useMemo(() => nodes.filter((n) => n.type === 'featureNode'), [nodes]);
|
|
@@ -165,80 +190,26 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
165
190
|
focusOnNode(tempNodeId);
|
|
166
191
|
}
|
|
167
192
|
}, [handleAddRepository, focusAndOpenDrawer, focusOnNode]);
|
|
168
|
-
//
|
|
193
|
+
// All five window-level CustomEvent listeners (add-repository, feature-
|
|
194
|
+
// created, delete/archive/unarchive requests) live in this hook so the
|
|
195
|
+
// parent component stays focused on graph state + rendering.
|
|
196
|
+
useCanvasEventListeners({
|
|
197
|
+
addRepoAndFocus,
|
|
198
|
+
createFeatureNode,
|
|
199
|
+
nodes,
|
|
200
|
+
handleDeleteFeature,
|
|
201
|
+
handleArchiveFeature,
|
|
202
|
+
handleUnarchiveFeature,
|
|
203
|
+
});
|
|
204
|
+
// Cleanup the drawer timer on unmount. Used to live inside the inlined
|
|
205
|
+
// shep:add-repository listener; now standalone since the listener moved.
|
|
169
206
|
useEffect(() => {
|
|
170
|
-
const handler = (e) => {
|
|
171
|
-
const path = e.detail.path;
|
|
172
|
-
addRepoAndFocus(path);
|
|
173
|
-
};
|
|
174
|
-
window.addEventListener('shep:add-repository', handler);
|
|
175
207
|
return () => {
|
|
176
|
-
window.removeEventListener('shep:add-repository', handler);
|
|
177
208
|
if (drawerTimerRef.current != null) {
|
|
178
209
|
clearTimeout(drawerTimerRef.current);
|
|
179
210
|
}
|
|
180
211
|
};
|
|
181
|
-
}, [
|
|
182
|
-
// Listen for create events from the create drawer (with real feature ID from server)
|
|
183
|
-
useEffect(() => {
|
|
184
|
-
const handler = (e) => {
|
|
185
|
-
const detail = e.detail;
|
|
186
|
-
// When a parentId is provided, connect to the parent feature node
|
|
187
|
-
// via a dependency edge instead of the repo node.
|
|
188
|
-
if (detail.parentId) {
|
|
189
|
-
const parentNodeId = `feat-${detail.parentId}`;
|
|
190
|
-
createFeatureNode(parentNodeId, {
|
|
191
|
-
state: 'creating',
|
|
192
|
-
featureId: detail.featureId,
|
|
193
|
-
name: detail.name,
|
|
194
|
-
description: detail.description,
|
|
195
|
-
repositoryPath: detail.repositoryPath,
|
|
196
|
-
}, 'dependencyEdge');
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
// Find the repo node to connect to
|
|
200
|
-
const repoNode = nodes.find((n) => n.type === 'repositoryNode' &&
|
|
201
|
-
n.data.repositoryPath === detail.repositoryPath);
|
|
202
|
-
createFeatureNode(repoNode?.id ?? null, {
|
|
203
|
-
state: 'running',
|
|
204
|
-
featureId: detail.featureId,
|
|
205
|
-
name: detail.name,
|
|
206
|
-
description: detail.description,
|
|
207
|
-
repositoryPath: detail.repositoryPath,
|
|
208
|
-
});
|
|
209
|
-
};
|
|
210
|
-
window.addEventListener('shep:feature-created', handler);
|
|
211
|
-
return () => window.removeEventListener('shep:feature-created', handler);
|
|
212
|
-
}, [nodes, createFeatureNode]);
|
|
213
|
-
// Listen for delete requests from the feature drawer (fires when the user
|
|
214
|
-
// confirms delete inside the drawer). Delegates to handleDeleteFeature so
|
|
215
|
-
// the canvas gets optimistic state, mutation guard, and node removal.
|
|
216
|
-
useEffect(() => {
|
|
217
|
-
const handler = (e) => {
|
|
218
|
-
const { featureId, cleanup, cascadeDelete, closePr } = e.detail;
|
|
219
|
-
handleDeleteFeature(featureId, cleanup, cascadeDelete, closePr);
|
|
220
|
-
};
|
|
221
|
-
window.addEventListener('shep:feature-delete-requested', handler);
|
|
222
|
-
return () => window.removeEventListener('shep:feature-delete-requested', handler);
|
|
223
|
-
}, [handleDeleteFeature]);
|
|
224
|
-
// Listen for archive requests from the feature drawer.
|
|
225
|
-
useEffect(() => {
|
|
226
|
-
const handler = (e) => {
|
|
227
|
-
const { featureId } = e.detail;
|
|
228
|
-
handleArchiveFeature(featureId);
|
|
229
|
-
};
|
|
230
|
-
window.addEventListener('shep:feature-archive-requested', handler);
|
|
231
|
-
return () => window.removeEventListener('shep:feature-archive-requested', handler);
|
|
232
|
-
}, [handleArchiveFeature]);
|
|
233
|
-
// Listen for unarchive requests from the feature drawer.
|
|
234
|
-
useEffect(() => {
|
|
235
|
-
const handler = (e) => {
|
|
236
|
-
const { featureId } = e.detail;
|
|
237
|
-
handleUnarchiveFeature(featureId);
|
|
238
|
-
};
|
|
239
|
-
window.addEventListener('shep:feature-unarchive-requested', handler);
|
|
240
|
-
return () => window.removeEventListener('shep:feature-unarchive-requested', handler);
|
|
241
|
-
}, [handleUnarchiveFeature]);
|
|
212
|
+
}, []);
|
|
242
213
|
// Wire callbacks into derived node data (via ref — no re-render).
|
|
243
214
|
useEffect(() => {
|
|
244
215
|
setCallbacks({
|
|
@@ -302,72 +273,111 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
302
273
|
clearTimeout(latchTimerRef.current);
|
|
303
274
|
};
|
|
304
275
|
}, [hasRepositories, showCanvas, resetViewport]);
|
|
276
|
+
// Auto-include any newly-appearing repo/feature nodes in the active
|
|
277
|
+
// workspace (skipped when default is active — that workspace shows
|
|
278
|
+
// everything anyway). We diff the current node id list against the set
|
|
279
|
+
// we've already seen so we only add the deltas.
|
|
280
|
+
useEffect(() => {
|
|
281
|
+
const seen = knownNodeIdsRef.current;
|
|
282
|
+
const newRepoIds = [];
|
|
283
|
+
const newFeatureIds = [];
|
|
284
|
+
for (const n of nodes) {
|
|
285
|
+
if (seen.has(n.id))
|
|
286
|
+
continue;
|
|
287
|
+
seen.add(n.id);
|
|
288
|
+
if (n.type === 'repositoryNode')
|
|
289
|
+
newRepoIds.push(n.id);
|
|
290
|
+
else if (n.type === 'featureNode')
|
|
291
|
+
newFeatureIds.push(n.id);
|
|
292
|
+
}
|
|
293
|
+
if (isDefaultActive)
|
|
294
|
+
return;
|
|
295
|
+
if (newRepoIds.length === 0 && newFeatureIds.length === 0)
|
|
296
|
+
return;
|
|
297
|
+
addToActiveWorkspace({ repoIds: newRepoIds, featureIds: newFeatureIds });
|
|
298
|
+
}, [nodes, isDefaultActive, addToActiveWorkspace]);
|
|
299
|
+
// Filter nodes by the active workspace (default workspace = no filter).
|
|
300
|
+
// We always filter from the full `nodes` list so `displayNodes` already
|
|
301
|
+
// reflects workspace membership before pulse-add decoration runs.
|
|
302
|
+
const workspaceFilteredNodes = useMemo(() => {
|
|
303
|
+
if (isDefaultActive)
|
|
304
|
+
return nodes;
|
|
305
|
+
const allowedRepos = new Set(activeWorkspace.repoIds);
|
|
306
|
+
const allowedFeatures = new Set(activeWorkspace.featureIds);
|
|
307
|
+
return nodes.filter((n) => {
|
|
308
|
+
if (n.type === 'repositoryNode')
|
|
309
|
+
return allowedRepos.has(n.id);
|
|
310
|
+
if (n.type === 'featureNode')
|
|
311
|
+
return allowedFeatures.has(n.id);
|
|
312
|
+
return true;
|
|
313
|
+
});
|
|
314
|
+
}, [nodes, isDefaultActive, activeWorkspace]);
|
|
315
|
+
// Drop edges whose endpoints were filtered out.
|
|
316
|
+
const workspaceFilteredEdges = useMemo(() => {
|
|
317
|
+
if (isDefaultActive)
|
|
318
|
+
return edges;
|
|
319
|
+
const visibleIds = new Set(workspaceFilteredNodes.map((n) => n.id));
|
|
320
|
+
return edges.filter((e) => visibleIds.has(e.source) && visibleIds.has(e.target));
|
|
321
|
+
}, [edges, isDefaultActive, workspaceFilteredNodes]);
|
|
305
322
|
// Pulse the "+" button when there's a single repo with no features and the
|
|
306
323
|
// create-feature drawer is not open — draws attention to the next action.
|
|
307
324
|
const isCreateDrawerOpen = pathname.startsWith('/create');
|
|
308
325
|
const displayNodes = useMemo(() => {
|
|
309
|
-
const
|
|
310
|
-
const
|
|
326
|
+
const source = workspaceFilteredNodes;
|
|
327
|
+
const repoNodes = source.filter((n) => n.type === 'repositoryNode');
|
|
328
|
+
const hasFeatures = source.some((n) => n.type === 'featureNode');
|
|
311
329
|
const shouldPulse = repoNodes.length === 1 && !hasFeatures && !isCreateDrawerOpen;
|
|
312
330
|
if (!shouldPulse)
|
|
313
|
-
return
|
|
314
|
-
return
|
|
315
|
-
}, [
|
|
331
|
+
return source;
|
|
332
|
+
return source.map((n) => n.type === 'repositoryNode' ? { ...n, data: { ...n.data, pulseAdd: true } } : n);
|
|
333
|
+
}, [workspaceFilteredNodes, isCreateDrawerOpen]);
|
|
316
334
|
const handlePickFolder = useCallback(() => {
|
|
317
335
|
window.dispatchEvent(new CustomEvent('shep:pick-folder'));
|
|
318
336
|
}, []);
|
|
337
|
+
// Re-fit the viewport when the active workspace's visible node set changes.
|
|
338
|
+
// See use-workspace-fit-view.ts for the scoping rules.
|
|
339
|
+
useWorkspaceFitView({
|
|
340
|
+
activeWorkspace,
|
|
341
|
+
isDefaultActive,
|
|
342
|
+
workspaceFilteredNodes,
|
|
343
|
+
fitView,
|
|
344
|
+
});
|
|
345
|
+
// When the active (non-default) workspace has no members but real repos
|
|
346
|
+
// exist on the canvas, show a workspace-aware empty state instead of the
|
|
347
|
+
// welcome wizard. The wizard would imply "no repos at all", which is wrong
|
|
348
|
+
// here — and crucially, leaves the workspace selector visible via the
|
|
349
|
+
// toolbar so users can switch back to the default workspace.
|
|
350
|
+
const workspaceFilteredEmpty = hasRepositories && !isDefaultActive && workspaceFilteredNodes.length === 0;
|
|
351
|
+
const emptyStateNode = workspaceFilteredEmpty ? (_jsxs("div", { className: "pointer-events-auto flex h-full w-full flex-col items-center justify-center px-8", children: [_jsx("div", { className: "bg-primary/10 text-primary mb-5 flex h-12 w-12 items-center justify-center rounded-2xl", children: _jsx(Layers, { className: "h-6 w-6" }) }), _jsx("h2", { className: "text-foreground/90 text-center text-2xl font-light tracking-tight", children: "This workspace is empty" }), _jsx("p", { className: "text-muted-foreground mt-2 max-w-sm text-center text-sm leading-relaxed", children: "Add repositories or features from the canvas, or switch back to the default workspace to see everything." }), _jsxs("div", { className: "mt-6 flex items-center gap-2", children: [_jsxs(Button, { size: "sm", onClick: () => setWorkspaceNewProjectOpen(true), className: "bg-blue-500 text-white hover:bg-blue-600", children: [_jsx(FolderPlus, { className: "me-1.5 h-3.5 w-3.5" }), "New project"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setManageWorkspaceOpen(true), children: [_jsx(Plus, { className: "me-1.5 h-3.5 w-3.5" }), "Manage items"] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setActiveWorkspace(DEFAULT_WORKSPACE_ID), children: "Switch to Default" })] })] })) : (_jsx(ControlCenterEmptyState, { onRepositorySelect: addRepoAndFocus }));
|
|
319
352
|
const featureFlags = useFeatureFlags();
|
|
320
|
-
// (+) FAB actions — only visible on control center
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
id: 'new-feature',
|
|
325
|
-
label: t('fab.newFeature'),
|
|
326
|
-
icon: _jsx(Sparkles, { className: "h-4 w-4" }),
|
|
327
|
-
onClick: () => {
|
|
328
|
-
clickSound.play();
|
|
329
|
-
guardedNavigate(() => router.push('/create'));
|
|
330
|
-
},
|
|
331
|
-
},
|
|
332
|
-
{
|
|
333
|
-
id: 'add-local-repo',
|
|
334
|
-
label: t('fab.localFolder'),
|
|
335
|
-
icon: _jsx(FolderPlus, { className: "h-4 w-4" }),
|
|
336
|
-
onClick: handlePickFolder,
|
|
337
|
-
},
|
|
338
|
-
];
|
|
339
|
-
if (featureFlags.adoptBranch) {
|
|
340
|
-
actions.push({
|
|
341
|
-
id: 'adopt-branch',
|
|
342
|
-
label: t('fab.adoptBranch'),
|
|
343
|
-
icon: _jsx(GitBranch, { className: "h-4 w-4" }),
|
|
344
|
-
onClick: () => {
|
|
345
|
-
guardedNavigate(() => router.push('/adopt'));
|
|
346
|
-
},
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
if (featureFlags.githubImport) {
|
|
350
|
-
actions.push({
|
|
351
|
-
id: 'add-github-repo',
|
|
352
|
-
label: t('fab.fromGithub'),
|
|
353
|
-
icon: _jsx(Github, { className: "h-4 w-4" }),
|
|
354
|
-
onClick: () => {
|
|
355
|
-
window.dispatchEvent(new CustomEvent('shep:open-github-import'));
|
|
356
|
-
},
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
return actions;
|
|
360
|
-
}, [
|
|
361
|
-
t,
|
|
353
|
+
// (+) FAB actions — only visible on control center. Action list lives in
|
|
354
|
+
// its own hook so this component stays focused on graph state + rendering.
|
|
355
|
+
const fabActions = useFabActions({
|
|
356
|
+
router,
|
|
362
357
|
clickSound,
|
|
363
358
|
guardedNavigate,
|
|
364
|
-
router,
|
|
365
359
|
handlePickFolder,
|
|
366
|
-
|
|
367
|
-
featureFlags
|
|
368
|
-
|
|
369
|
-
const canvasToolbar = (_jsx(CanvasToolbar, { showArchived: showArchived, onToggleArchived: () => setShowArchived(!showArchived), onResetViewport: resetViewport
|
|
370
|
-
|
|
360
|
+
onNewProject: () => setWorkspaceNewProjectOpen(true),
|
|
361
|
+
featureFlags,
|
|
362
|
+
});
|
|
363
|
+
const canvasToolbar = (_jsx(CanvasToolbar, { showArchived: showArchived, onToggleArchived: () => setShowArchived(!showArchived), onResetViewport: resetViewport, startSlot: _jsx(WorkspaceSelector, { workspaces: workspaces, activeWorkspace: activeWorkspace, onSelect: setActiveWorkspace, onRequestCreate: () => setCreateWorkspaceOpen(true), onRequestRename: () => setRenameWorkspaceOpen(true), onRequestDelete: (id) => {
|
|
364
|
+
setPendingDeleteWorkspaceId(id);
|
|
365
|
+
setDeleteWorkspaceOpen(true);
|
|
366
|
+
}, onManage: () => setManageWorkspaceOpen(true) }) }));
|
|
367
|
+
return (_jsxs(_Fragment, { children: [_jsx(FeaturesCanvas, { nodes: showCanvas ? displayNodes : [], edges: showCanvas ? workspaceFilteredEdges : [], selectedFeatureId: selectedFeatureId, selectedRepository: selectedRepository, defaultViewport: defaultViewport, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onMoveEnd: handleMoveEnd, toolbar: canvasToolbar, emptyState: emptyStateNode }), showCanvas ? _jsx(CreateFab, { actions: fabActions }) : null, _jsx(NewProjectDialog, { open: workspaceNewProjectOpen, onOpenChange: setWorkspaceNewProjectOpen, onCreated: (path) => addRepoAndFocus(path) }), _jsx(ManageWorkspaceDialog, { open: manageWorkspaceOpen, onOpenChange: setManageWorkspaceOpen, workspace: activeWorkspace, allNodes: nodes, onSave: (members) => setWorkspaceMembers(activeWorkspace.id, members) }), _jsx(WorkspaceNameDialog, { open: createWorkspaceOpen, onOpenChange: setCreateWorkspaceOpen, title: "New workspace", description: "Create a workspace to filter the canvas to a specific set of repositories and features.", confirmLabel: "Create", onConfirm: (name) => {
|
|
368
|
+
createWorkspace(name);
|
|
369
|
+
setManageWorkspaceOpen(true);
|
|
370
|
+
} }), _jsx(WorkspaceNameDialog, { open: renameWorkspaceOpen, onOpenChange: setRenameWorkspaceOpen, title: "Rename workspace", initialValue: activeWorkspace.name, confirmLabel: "Rename", onConfirm: (name) => renameWorkspace(activeWorkspace.id, name) }), _jsx(AlertDialog, { open: deleteWorkspaceOpen, onOpenChange: (open) => {
|
|
371
|
+
setDeleteWorkspaceOpen(open);
|
|
372
|
+
if (!open)
|
|
373
|
+
setPendingDeleteWorkspaceId(null);
|
|
374
|
+
}, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete workspace?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently remove the workspace \u201C", workspaces.find((w) => w.id === pendingDeleteWorkspaceId)?.name ??
|
|
375
|
+
activeWorkspace.name, "\u201D. The repositories and features themselves are not affected."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", onClick: () => {
|
|
376
|
+
if (pendingDeleteWorkspaceId) {
|
|
377
|
+
deleteWorkspace(pendingDeleteWorkspaceId);
|
|
378
|
+
setPendingDeleteWorkspaceId(null);
|
|
379
|
+
}
|
|
380
|
+
}, children: "Delete" })] })] }) })] }));
|
|
371
381
|
}
|
|
372
382
|
/** (+) FAB that tracks sidebar width via CSS var + transition.
|
|
373
383
|
* When fabLayout.swapPosition is true, moves to the end side (right in LTR). */
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface NewProjectDialogProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onOpenChange: (open: boolean) => void;
|
|
4
|
+
/** Called with the absolute path of the newly-created project folder. */
|
|
5
|
+
onCreated: (path: string) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function NewProjectDialog({ open, onOpenChange, onCreated }: NewProjectDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=new-project-dialog.d.ts.map
|
package/dist/src/presentation/web/components/features/control-center/new-project-dialog.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new-project-dialog.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/new-project-dialog.tsx"],"names":[],"mappings":"AAgBA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,yEAAyE;IACzE,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,qBAAqB,2CAsFxF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { Loader2 } from 'lucide-react';
|
|
5
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
|
|
6
|
+
import { Input } from '../../ui/input.js';
|
|
7
|
+
import { Button } from '../../ui/button.js';
|
|
8
|
+
import { createProjectFolder } from '../../../app/actions/create-project-folder.js';
|
|
9
|
+
export function NewProjectDialog({ open, onOpenChange, onCreated }) {
|
|
10
|
+
const [name, setName] = useState('');
|
|
11
|
+
const [busy, setBusy] = useState(false);
|
|
12
|
+
const [error, setError] = useState(null);
|
|
13
|
+
// Reset state every time the dialog opens.
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (open) {
|
|
16
|
+
setName('');
|
|
17
|
+
setBusy(false);
|
|
18
|
+
setError(null);
|
|
19
|
+
}
|
|
20
|
+
}, [open]);
|
|
21
|
+
const handleSubmit = async (e) => {
|
|
22
|
+
e.preventDefault();
|
|
23
|
+
const trimmed = name.trim();
|
|
24
|
+
if (!trimmed || busy)
|
|
25
|
+
return;
|
|
26
|
+
setBusy(true);
|
|
27
|
+
setError(null);
|
|
28
|
+
const result = await createProjectFolder(trimmed);
|
|
29
|
+
if (!result.ok || !result.path) {
|
|
30
|
+
setError(result.error ?? 'Failed to create project.');
|
|
31
|
+
setBusy(false);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Hand the new path off to the empty state's existing add-repo flow.
|
|
35
|
+
onCreated(result.path);
|
|
36
|
+
onOpenChange(false);
|
|
37
|
+
};
|
|
38
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsx(DialogContent, { className: "max-w-sm", children: _jsxs("form", { onSubmit: handleSubmit, children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "New project" }), _jsx(DialogDescription, { children: "Create an empty project folder inside your Shep home directory. Git will be initialised automatically when the project is added." })] }), _jsxs("div", { className: "py-4", children: [_jsx(Input, { autoFocus: true, value: name, onChange: (e) => {
|
|
39
|
+
setName(e.target.value);
|
|
40
|
+
if (error)
|
|
41
|
+
setError(null);
|
|
42
|
+
}, placeholder: "my-prototype", disabled: busy, "data-testid": "new-project-name-input" }), error ? (_jsx("p", { className: "text-destructive mt-2 text-xs", role: "alert", children: error })) : null] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), disabled: busy, children: "Cancel" }), _jsx(Button, { type: "submit", disabled: !name.trim() || busy, children: busy ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Creating\u2026"] })) : ('Create project') })] })] }) }) }));
|
|
43
|
+
}
|
package/dist/src/presentation/web/components/features/control-center/use-canvas-event-listeners.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire global window events used by the control center canvas to the
|
|
3
|
+
* appropriate handlers. The canvas listens for cross-component requests
|
|
4
|
+
* dispatched as CustomEvents:
|
|
5
|
+
*
|
|
6
|
+
* - shep:add-repository → addRepoAndFocus(path)
|
|
7
|
+
* - shep:feature-created → createFeatureNode(...)
|
|
8
|
+
* - shep:feature-delete-requested → handleDeleteFeature(...)
|
|
9
|
+
* - shep:feature-archive-requested → handleArchiveFeature(...)
|
|
10
|
+
* - shep:feature-unarchive-requested → handleUnarchiveFeature(...)
|
|
11
|
+
*
|
|
12
|
+
* Extracted from control-center-inner.tsx so the parent component stays
|
|
13
|
+
* focused on graph state + rendering, not event-bus plumbing.
|
|
14
|
+
*/
|
|
15
|
+
import type { CanvasNodeType } from '../../features/features-canvas/index.js';
|
|
16
|
+
import type { FeatureNodeData } from '../../common/feature-node/index.js';
|
|
17
|
+
export type CreateFeatureNodeFn = (sourceNodeId: string | null, dataOverride?: Partial<FeatureNodeData>, edgeType?: string) => string;
|
|
18
|
+
export interface CanvasEventListenerHandlers {
|
|
19
|
+
addRepoAndFocus: (path: string) => void;
|
|
20
|
+
createFeatureNode: CreateFeatureNodeFn;
|
|
21
|
+
nodes: CanvasNodeType[];
|
|
22
|
+
handleDeleteFeature: (featureId: string, cleanup?: boolean, cascadeDelete?: boolean, closePr?: boolean) => void;
|
|
23
|
+
handleArchiveFeature: (featureId: string) => void;
|
|
24
|
+
handleUnarchiveFeature: (featureId: string) => void;
|
|
25
|
+
}
|
|
26
|
+
export declare function useCanvasEventListeners(handlers: CanvasEventListenerHandlers): void;
|
|
27
|
+
//# sourceMappingURL=use-canvas-event-listeners.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-canvas-event-listeners.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-canvas-event-listeners.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAExE,MAAM,MAAM,mBAAmB,GAAG,CAChC,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;AAEZ,MAAM,WAAW,2BAA2B;IAC1C,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,iBAAiB,EAAE,mBAAmB,CAAC;IACvC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,IAAI,CAyGnF"}
|