@shepai/cli 1.135.3 → 1.136.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/dist/src/presentation/web/app/actions/check-agent-auth.d.ts +2 -0
- 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 +8 -1
- package/dist/src/presentation/web/app/actions/check-tool-status.d.ts +14 -0
- package/dist/src/presentation/web/app/actions/check-tool-status.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/check-tool-status.js +53 -0
- package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
- package/dist/src/presentation/web/app/build-graph-nodes.js +1 -9
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +17 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.js +91 -0
- 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 +54 -64
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +85 -19
- 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 -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 +35 -9
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.stories.d.ts +17 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.stories.js +110 -1
- 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/features-canvas.stories.d.ts +1 -0
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.js +443 -10
- package/dist/src/presentation/web/lib/layout-with-dagre.js +1 -1
- 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 +63 -48
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +3 -3
- 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/create/page/server-reference-manifest.json +63 -48
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +3 -3
- 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 +75 -60
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +3 -3
- 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 +75 -60
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -3
- 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 +59 -44
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +3 -3
- 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 +63 -48
- package/web/.next/server/app/(dashboard)/create/page.js +3 -3
- 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 +75 -60
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +3 -3
- 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 +75 -60
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +3 -3
- 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 +59 -44
- package/web/.next/server/app/(dashboard)/page.js +3 -3
- 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 +59 -44
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +3 -3
- 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 +3 -3
- 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/settings/page/server-reference-manifest.json +8 -8
- 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 +8 -8
- package/web/.next/server/app/skills/page.js +1 -1
- 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 +8 -8
- package/web/.next/server/app/tools/page.js +1 -1
- 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 +3 -3
- 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/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__b4102cc7._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_b49d9c97.js +3 -0
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_b49d9c97.js.map +1 -0
- 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_28632197.js +3 -0
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_28632197.js.map +1 -0
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_10695d37.js +3 -0
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_10695d37.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__31bc28da._.js → [root-of-the-server]__47ded061._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__31bc28da._.js.map → [root-of-the-server]__47ded061._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__32ecbed9._.js → [root-of-the-server]__68ce373c._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__90f9ae71._.js.map → [root-of-the-server]__68ce373c._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6ec59045._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6ec59045._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__90f9ae71._.js → [root-of-the-server]__718766da._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__90ce4b6d._.js.map → [root-of-the-server]__718766da._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__96670392._.js → [root-of-the-server]__a5f9c6e5._.js} +3 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a5f9c6e5._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b3dbadca._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b3dbadca._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +3 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__7894f27f._.js.map → [root-of-the-server]__d48c5b11._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__90ce4b6d._.js → [root-of-the-server]__fdd058b2._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__32ecbed9._.js.map → [root-of-the-server]__fdd058b2._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_02ec1aea._.js +1 -1
- package/web/.next/server/chunks/ssr/_02ec1aea._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
- package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
- package/web/.next/server/chunks/ssr/_a9f57758._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_aec44907._.js +3 -0
- package/web/.next/server/chunks/ssr/_aec44907._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_e69a26ba._.js +4 -0
- package/web/.next/server/chunks/ssr/_e69a26ba._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_d17bc20a._.js → _e700d6a8._.js} +2 -2
- package/web/.next/server/chunks/ssr/_e700d6a8._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
- package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +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/src_presentation_web_53666118._.js +5 -0
- package/web/.next/server/chunks/ssr/{src_presentation_web_b9023017._.js.map → src_presentation_web_53666118._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_d95e128d.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_d95e128d.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.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_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.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_127fb482._.js → src_presentation_web_d8202508._.js} +2 -2
- package/web/.next/server/chunks/ssr/{src_presentation_web_127fb482._.js.map → src_presentation_web_d8202508._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e4df6dd7._.js +5 -0
- package/web/.next/server/chunks/ssr/{src_presentation_web_8e7fe0d1._.js.map → src_presentation_web_e4df6dd7._.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 +374 -296
- package/web/.next/static/chunks/{9154973d61eae190.js → 00754162862ab75f.js} +1 -1
- package/web/.next/static/chunks/{d8a0dd9bfd0f22fa.js → 07ea878c8d769b40.js} +1 -1
- package/web/.next/static/chunks/{8c42b7752187f48c.js → 1693f840144b12bb.js} +2 -2
- package/web/.next/static/chunks/{7875a9370622a064.js → 3d6119fadfa8596f.js} +1 -1
- package/web/.next/static/chunks/3e571ee5f5afd401.js +1 -0
- package/web/.next/static/chunks/{d5342f9be437afd9.js → 4916dcd902d80072.js} +1 -1
- package/web/.next/static/chunks/{fdc719494dcd9c92.js → 75d552e0e611e3f4.js} +2 -2
- package/web/.next/static/chunks/{61f7d4f0f0f770a4.js → 90af5015ea1684d2.js} +1 -1
- package/web/.next/static/chunks/92cd6f523639a6fa.css +1 -0
- package/web/.next/static/chunks/98888e44c7c02a19.js +1 -0
- package/web/.next/static/chunks/{15e6a74ef39fda73.js → a17edbc379ad2f40.js} +1 -1
- package/web/.next/static/chunks/{1a9dfc34432387f5.js → ae5bf7c402bb02ad.js} +1 -1
- package/web/.next/static/chunks/d0dff217a94d4ee1.js +1 -0
- package/web/.next/static/chunks/ff9b5942b2cae4f7.js +1 -0
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.js +0 -3
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_4e741df2.js.map +0 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js +0 -3
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_026fdffa.js.map +0 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.js +0 -3
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_8b91e197.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7894f27f._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__96670392._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9c45d070._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9c45d070._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_313c9690._.js +0 -3
- package/web/.next/server/chunks/ssr/_313c9690._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_b6960ca0._.js +0 -4
- package/web/.next/server/chunks/ssr/_b6960ca0._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_d17bc20a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_8e7fe0d1._.js +0 -5
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_ca051134.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_b9023017._.js +0 -5
- package/web/.next/static/chunks/314b8314f77d6921.js +0 -1
- package/web/.next/static/chunks/3e2d7d07926b05bf.css +0 -1
- package/web/.next/static/chunks/55a1c86671bb1a5b.js +0 -1
- package/web/.next/static/chunks/c0c287da1631752f.js +0 -1
- package/web/.next/static/chunks/e6b87832e1382949.js +0 -1
- /package/web/.next/static/{p0KCxpQ0DqKcttVypdnix → PlnxcoPHipclEMFHMWF11}/_buildManifest.js +0 -0
- /package/web/.next/static/{p0KCxpQ0DqKcttVypdnix → PlnxcoPHipclEMFHMWF11}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{p0KCxpQ0DqKcttVypdnix → PlnxcoPHipclEMFHMWF11}/_ssgManifest.js +0 -0
|
@@ -2,13 +2,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { expect, fn, waitFor } from '@storybook/test';
|
|
4
4
|
import { ReactFlowProvider, ReactFlow, useNodesState } from '@xyflow/react';
|
|
5
|
-
import { DeploymentState } from '../../../../../../packages/core/src/domain/generated/output.js';
|
|
5
|
+
import { DeploymentState, PrStatus, CiStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
|
|
6
6
|
import { FeatureNode } from './feature-node.js';
|
|
7
7
|
const nodeTypes = { featureNode: FeatureNode };
|
|
8
8
|
/** Renders a single FeatureNode as a proper React Flow node (with node wrapper + pointer events). */
|
|
9
9
|
function FeatureNodeCanvas({ data, style = { width: 600, height: 400 }, }) {
|
|
10
10
|
const nodes = useMemo(() => [{ id: 'node-1', type: 'featureNode', position: { x: 0, y: 0 }, data }], [data]);
|
|
11
|
-
return (_jsx("div", { style: style, children: _jsx(ReactFlowProvider, { children: _jsx(ReactFlow, { nodes: nodes, nodeTypes: nodeTypes, nodesDraggable: false, nodesConnectable: false, proOptions: { hideAttribution: true }, fitView: true }) }) }));
|
|
11
|
+
return (_jsx("div", { style: style, children: _jsx(ReactFlowProvider, { children: _jsx(ReactFlow, { nodes: nodes, nodeTypes: nodeTypes, nodesDraggable: false, nodesConnectable: false, panOnDrag: false, zoomOnScroll: false, proOptions: { hideAttribution: true }, fitView: true, className: "[&_.react-flow__pane]:!cursor-default" }) }) }));
|
|
12
12
|
}
|
|
13
13
|
const meta = {
|
|
14
14
|
title: 'Composed/FeatureNode',
|
|
@@ -19,10 +19,17 @@ const meta = {
|
|
|
19
19
|
args: {
|
|
20
20
|
name: 'Auth Module',
|
|
21
21
|
description: 'Implement OAuth2 authentication flow',
|
|
22
|
-
featureId: '
|
|
23
|
-
lifecycle: '
|
|
22
|
+
featureId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
|
|
23
|
+
lifecycle: 'implementation',
|
|
24
24
|
state: 'running',
|
|
25
25
|
progress: 45,
|
|
26
|
+
agentType: 'claude-code',
|
|
27
|
+
modelId: 'claude-sonnet-4-6',
|
|
28
|
+
repositoryPath: '/home/user/my-repo',
|
|
29
|
+
repositoryName: 'my-repo',
|
|
30
|
+
branch: 'feat/auth-module',
|
|
31
|
+
hasAgentRun: true,
|
|
32
|
+
hasPlan: true,
|
|
26
33
|
},
|
|
27
34
|
};
|
|
28
35
|
export default meta;
|
|
@@ -32,66 +39,92 @@ export const Default = {
|
|
|
32
39
|
const allStatesData = [
|
|
33
40
|
{
|
|
34
41
|
name: 'User Onboarding',
|
|
35
|
-
description: 'Implement guided onboarding wizard',
|
|
42
|
+
description: 'Implement guided onboarding wizard with step-by-step tutorial',
|
|
36
43
|
featureId: '',
|
|
37
44
|
lifecycle: 'requirements',
|
|
38
45
|
state: 'creating',
|
|
39
46
|
progress: 0,
|
|
40
47
|
repositoryPath: '/home/user/my-repo',
|
|
48
|
+
repositoryName: 'my-repo',
|
|
41
49
|
branch: '',
|
|
42
50
|
},
|
|
43
51
|
{
|
|
44
52
|
name: 'Auth Module',
|
|
45
|
-
description: 'Implement OAuth2 authentication flow',
|
|
46
|
-
featureId: '
|
|
53
|
+
description: 'Implement OAuth2 authentication flow with SSO support',
|
|
54
|
+
featureId: '11111111-1111-1111-1111-111111111111',
|
|
47
55
|
lifecycle: 'implementation',
|
|
48
56
|
state: 'running',
|
|
49
57
|
progress: 45,
|
|
50
58
|
agentType: 'claude-code',
|
|
51
59
|
modelId: 'claude-sonnet-4-6',
|
|
52
60
|
repositoryPath: '/home/user/my-repo',
|
|
61
|
+
repositoryName: 'my-repo',
|
|
53
62
|
branch: 'feat/auth-module',
|
|
63
|
+
worktreePath: '/home/user/.shep/repos/abc123/wt/feat-auth-module',
|
|
64
|
+
hasAgentRun: true,
|
|
65
|
+
hasPlan: true,
|
|
66
|
+
deployment: { status: DeploymentState.Ready, url: 'http://localhost:3001' },
|
|
54
67
|
},
|
|
55
68
|
{
|
|
56
69
|
name: 'API Rate Limiting',
|
|
57
|
-
description: 'Implement sliding window rate limiting for public
|
|
58
|
-
featureId: '
|
|
70
|
+
description: 'Implement sliding window rate limiting for public endpoints',
|
|
71
|
+
featureId: '22222222-2222-2222-2222-222222222222',
|
|
59
72
|
lifecycle: 'requirements',
|
|
60
73
|
state: 'action-required',
|
|
61
74
|
progress: 22,
|
|
62
75
|
agentType: 'claude-code',
|
|
63
76
|
modelId: 'claude-sonnet-4-6',
|
|
64
77
|
repositoryPath: '/home/user/my-repo',
|
|
78
|
+
repositoryName: 'my-repo',
|
|
65
79
|
branch: 'feat/api-rate-limiting',
|
|
80
|
+
worktreePath: '/home/user/.shep/repos/abc123/wt/feat-api-rate-limiting',
|
|
81
|
+
hasAgentRun: true,
|
|
82
|
+
hasPlan: true,
|
|
66
83
|
},
|
|
67
84
|
{
|
|
68
85
|
name: 'Data Pipeline',
|
|
69
86
|
description: 'ETL pipeline for analytics dashboard',
|
|
70
|
-
featureId: '
|
|
87
|
+
featureId: '33333333-3333-3333-3333-333333333333',
|
|
71
88
|
lifecycle: 'implementation',
|
|
72
89
|
state: 'action-required',
|
|
73
90
|
progress: 40,
|
|
74
91
|
agentType: 'cursor',
|
|
75
92
|
modelId: 'claude-opus-4-6',
|
|
76
93
|
repositoryPath: '/home/user/my-repo',
|
|
94
|
+
repositoryName: 'my-repo',
|
|
77
95
|
branch: 'feat/data-pipeline',
|
|
96
|
+
worktreePath: '/home/user/.shep/repos/abc123/wt/feat-data-pipeline',
|
|
97
|
+
hasAgentRun: true,
|
|
98
|
+
hasPlan: true,
|
|
99
|
+
deployment: { status: DeploymentState.Booting },
|
|
78
100
|
},
|
|
79
101
|
{
|
|
80
102
|
name: 'Merge Review',
|
|
81
103
|
description: 'PR ready for merge approval',
|
|
82
|
-
featureId: '
|
|
104
|
+
featureId: '44444444-4444-4444-4444-444444444444',
|
|
83
105
|
lifecycle: 'review',
|
|
84
106
|
state: 'action-required',
|
|
85
107
|
progress: 90,
|
|
86
108
|
agentType: 'gemini-cli',
|
|
87
109
|
modelId: 'gemini-2.5-pro',
|
|
88
110
|
repositoryPath: '/home/user/my-repo',
|
|
111
|
+
repositoryName: 'my-repo',
|
|
89
112
|
branch: 'feat/merge-review',
|
|
113
|
+
worktreePath: '/home/user/.shep/repos/abc123/wt/feat-merge-review',
|
|
114
|
+
hasAgentRun: true,
|
|
115
|
+
hasPlan: true,
|
|
116
|
+
pr: {
|
|
117
|
+
url: 'https://github.com/user/my-repo/pull/87',
|
|
118
|
+
number: 87,
|
|
119
|
+
status: PrStatus.Open,
|
|
120
|
+
ciStatus: CiStatus.Success,
|
|
121
|
+
mergeable: true,
|
|
122
|
+
},
|
|
90
123
|
},
|
|
91
124
|
{
|
|
92
125
|
name: 'Payment Gateway',
|
|
93
126
|
description: 'Stripe integration for subscriptions',
|
|
94
|
-
featureId: '
|
|
127
|
+
featureId: '55555555-5555-5555-5555-555555555555',
|
|
95
128
|
lifecycle: 'deploy',
|
|
96
129
|
state: 'done',
|
|
97
130
|
progress: 100,
|
|
@@ -99,12 +132,24 @@ const allStatesData = [
|
|
|
99
132
|
agentType: 'claude-code',
|
|
100
133
|
modelId: 'claude-sonnet-4-6',
|
|
101
134
|
repositoryPath: '/home/user/my-repo',
|
|
135
|
+
repositoryName: 'my-repo',
|
|
102
136
|
branch: 'feat/payment-gateway',
|
|
137
|
+
worktreePath: '/home/user/.shep/repos/abc123/wt/feat-payment-gateway',
|
|
138
|
+
fastMode: true,
|
|
139
|
+
hasAgentRun: true,
|
|
140
|
+
hasPlan: true,
|
|
141
|
+
pr: {
|
|
142
|
+
url: 'https://github.com/user/my-repo/pull/85',
|
|
143
|
+
number: 85,
|
|
144
|
+
status: PrStatus.Merged,
|
|
145
|
+
ciStatus: CiStatus.Success,
|
|
146
|
+
},
|
|
147
|
+
deployment: { status: DeploymentState.Ready, url: 'http://localhost:3002' },
|
|
103
148
|
},
|
|
104
149
|
{
|
|
105
150
|
name: 'Search Index',
|
|
106
151
|
description: 'Elasticsearch full-text search setup',
|
|
107
|
-
featureId: '
|
|
152
|
+
featureId: '66666666-6666-6666-6666-666666666666',
|
|
108
153
|
lifecycle: 'implementation',
|
|
109
154
|
state: 'blocked',
|
|
110
155
|
progress: 20,
|
|
@@ -112,40 +157,61 @@ const allStatesData = [
|
|
|
112
157
|
agentType: 'claude-code',
|
|
113
158
|
modelId: 'claude-opus-4-6',
|
|
114
159
|
repositoryPath: '/home/user/my-repo',
|
|
160
|
+
repositoryName: 'my-repo',
|
|
115
161
|
branch: 'feat/search-index',
|
|
162
|
+
worktreePath: '/home/user/.shep/repos/abc123/wt/feat-search-index',
|
|
163
|
+
hasAgentRun: true,
|
|
164
|
+
hasPlan: true,
|
|
116
165
|
},
|
|
117
166
|
{
|
|
118
167
|
name: 'Email Service',
|
|
119
168
|
description: 'Transactional email with SendGrid',
|
|
120
|
-
featureId: '
|
|
169
|
+
featureId: '77777777-7777-7777-7777-777777777777',
|
|
121
170
|
lifecycle: 'review',
|
|
122
171
|
state: 'error',
|
|
123
172
|
progress: 30,
|
|
124
|
-
errorMessage: 'Build failed:
|
|
125
|
-
agentType: '
|
|
126
|
-
modelId: '
|
|
173
|
+
errorMessage: 'Build failed: Cannot find module @sendgrid/mail',
|
|
174
|
+
agentType: 'aider',
|
|
175
|
+
modelId: 'claude-sonnet-4-6',
|
|
127
176
|
repositoryPath: '/home/user/my-repo',
|
|
177
|
+
repositoryName: 'my-repo',
|
|
128
178
|
branch: 'feat/email-service',
|
|
179
|
+
worktreePath: '/home/user/.shep/repos/abc123/wt/feat-email-service',
|
|
180
|
+
hasAgentRun: true,
|
|
181
|
+
hasPlan: true,
|
|
182
|
+
pr: {
|
|
183
|
+
url: 'https://github.com/user/my-repo/pull/86',
|
|
184
|
+
number: 86,
|
|
185
|
+
status: PrStatus.Open,
|
|
186
|
+
ciStatus: CiStatus.Failure,
|
|
187
|
+
},
|
|
188
|
+
onRetry: fn(),
|
|
129
189
|
},
|
|
130
190
|
{
|
|
131
191
|
name: 'Notification Service',
|
|
132
192
|
description: 'Push notification integration',
|
|
133
|
-
featureId: '
|
|
193
|
+
featureId: '88888888-8888-8888-8888-888888888888',
|
|
134
194
|
lifecycle: 'pending',
|
|
135
195
|
state: 'pending',
|
|
136
196
|
progress: 0,
|
|
137
197
|
repositoryPath: '/home/user/my-repo',
|
|
198
|
+
repositoryName: 'my-repo',
|
|
138
199
|
branch: 'feat/notification-service',
|
|
200
|
+
onStart: fn(),
|
|
139
201
|
},
|
|
140
202
|
{
|
|
141
203
|
name: 'Legacy API Cleanup',
|
|
142
204
|
description: 'Remove deprecated REST endpoints',
|
|
143
|
-
featureId: '
|
|
205
|
+
featureId: '99999999-9999-9999-9999-999999999999',
|
|
144
206
|
lifecycle: 'implementation',
|
|
145
207
|
state: 'deleting',
|
|
146
208
|
progress: 0,
|
|
147
209
|
repositoryPath: '/home/user/my-repo',
|
|
210
|
+
repositoryName: 'my-repo',
|
|
148
211
|
branch: 'feat/legacy-api-cleanup',
|
|
212
|
+
worktreePath: '/home/user/.shep/repos/abc123/wt/feat-legacy-api-cleanup',
|
|
213
|
+
agentType: 'claude-code',
|
|
214
|
+
hasAgentRun: true,
|
|
149
215
|
},
|
|
150
216
|
];
|
|
151
217
|
export const AllStates = {
|
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":"AAmCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAOnE,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAOnE,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,2CAqa5F"}
|
|
@@ -71,15 +71,17 @@ export function RepositoryNode({ data }) {
|
|
|
71
71
|
e.stopPropagation();
|
|
72
72
|
data.onClick?.();
|
|
73
73
|
}
|
|
74
|
-
}, className: "nodrag bg-card flex w-[26rem] cursor-pointer flex-col overflow-hidden rounded-xl border shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-3 px-4 py-3", children: [_jsx(Github, { className: "text-muted-foreground h-5 w-5 shrink-0" }), _jsx("span", { "data-testid": "repository-node-name", className: "min-w-0 truncate text-sm font-medium", children: data.name }), _jsxs("div", { className: cn('flex shrink-0 items-center gap-2', (data.repositoryPath ?? data.onAdd) && 'ml-auto'), onClick: (e) => e.stopPropagation(), children: [data.repositoryPath ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in IDE", onClick: actions.openInIde, loading: actions.ideLoading, error: !!actions.ideError, icon: Code2, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in IDE" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in Shell", onClick: actions.openInShell, loading: actions.shellLoading, error: !!actions.shellError, icon: Terminal, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in Shell" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open Folder", onClick: actions.openFolder, loading: actions.folderLoading, error: !!actions.folderError, icon: FolderOpen, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open Folder" })] }) }), _jsx(FeatureSessionsDropdown, { repositoryPath: data.repositoryPath, onCreateFromSession: handleCreateFromSession })] })) : null, data.onAdd ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Add feature", "data-testid": "repository-node-add-button", onClick: (e) => {
|
|
74
|
+
}, className: "nodrag bg-card flex w-[26rem] cursor-pointer flex-col overflow-hidden rounded-xl border shadow-sm dark:bg-neutral-800/80", children: [_jsxs("div", { className: "flex items-center gap-3 px-4 py-3", children: [_jsx(Github, { className: "text-muted-foreground h-5 w-5 shrink-0" }), _jsx("span", { "data-testid": "repository-node-name", className: "min-w-0 truncate text-sm font-medium", children: data.name }), _jsxs("div", { className: cn('flex shrink-0 items-center gap-2', (data.repositoryPath ?? data.onAdd) && 'ml-auto'), onClick: (e) => e.stopPropagation(), children: [data.repositoryPath ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in IDE", onClick: actions.openInIde, loading: actions.ideLoading, error: !!actions.ideError, icon: Code2, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in IDE" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in Shell", onClick: actions.openInShell, loading: actions.shellLoading, error: !!actions.shellError, icon: Terminal, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in Shell" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open Folder", onClick: actions.openFolder, loading: actions.folderLoading, error: !!actions.folderError, icon: FolderOpen, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open Folder" })] }) }), _jsx(FeatureSessionsDropdown, { repositoryPath: data.repositoryPath, onCreateFromSession: handleCreateFromSession })] })) : null, data.onAdd ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": "Add feature", "data-testid": "repository-node-add-button", onClick: (e) => {
|
|
75
75
|
e.stopPropagation();
|
|
76
76
|
data.onAdd?.();
|
|
77
77
|
}, className: cn('text-muted-foreground hover:bg-accent dark:hover:bg-accent/50 flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded-full transition-colors hover:text-blue-500', data.pulseAdd &&
|
|
78
|
-
'animate-pulse-cta bg-blue-100 text-blue-500 dark:bg-blue-900/40'), children: _jsx(Plus, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Add feature" })] }) })) : null] })] }), data.branch ? (_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-git-info", className: "text-muted-foreground border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-3 text-xs", children: [_jsxs("span", { className: "flex items-center gap-1 truncate", "data-testid": "repository-node-branch", children: [_jsx(GitBranch, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: data.branch })] }), data.behindCount != null && data.behindCount > 0 ? (_jsxs("span", { className: "flex shrink-0 items-center gap-1 whitespace-nowrap text-amber-500", "data-testid": "repository-node-behind", children: [_jsx(ArrowDown, { className: "h-3 w-3 shrink-0" }), data.behindCount, " behind"] })) : null] }) }), data.commitMessage ? (_jsx("div", { "data-testid": "repository-node-commit-info", className: "text-muted-foreground border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [_jsx(GitCommitHorizontal, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "min-w-0 truncate", "data-testid": "repository-node-commit-message", children: data.commitMessage }), data.committer ? (_jsxs("span", { className: "text-muted-foreground/70 ml-auto flex shrink-0 items-center gap-1", "data-testid": "repository-node-committer", children: [_jsx(User, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: data.committer })] })) : null] }) })) : null] })) : data.gitInfoStatus === 'not-a-repo' ? (
|
|
78
|
+
'animate-pulse-cta bg-blue-100 text-blue-500 dark:bg-blue-900/40'), children: _jsx(Plus, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Add feature" })] }) })) : null] })] }), data.branch ? (_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-git-info", className: "text-muted-foreground border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-3 text-xs", children: [_jsxs("span", { className: "flex items-center gap-1 truncate", "data-testid": "repository-node-branch", children: [_jsx(GitBranch, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: data.branch })] }), data.behindCount != null && data.behindCount > 0 ? (_jsxs("span", { className: "flex shrink-0 items-center gap-1 whitespace-nowrap text-amber-500", "data-testid": "repository-node-behind", children: [_jsx(ArrowDown, { className: "h-3 w-3 shrink-0" }), data.behindCount, " behind"] })) : null] }) }), data.commitMessage ? (_jsx("div", { "data-testid": "repository-node-commit-info", className: "text-muted-foreground border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [_jsx(GitCommitHorizontal, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "min-w-0 truncate", "data-testid": "repository-node-commit-message", children: data.commitMessage }), data.committer ? (_jsxs("span", { className: "text-muted-foreground/70 ml-auto flex shrink-0 items-center gap-1", "data-testid": "repository-node-committer", children: [_jsx(User, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: data.committer })] })) : null] }) })) : null] })) : data.gitInfoStatus === 'not-a-repo' ? (
|
|
79
79
|
/* Not a git repo — two rows for consistency with loading/ready states */
|
|
80
|
-
_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-not-repo", className: "text-muted-foreground border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [_jsx(FolderOpen, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "min-w-0 truncate opacity-60", children: data.repositoryPath ?? 'Unknown path' })] }) }), _jsx("div", { className: "text-muted-foreground border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs opacity-40", children: [_jsx(GitBranch, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: "Not a git repository" })] }) })] })) : data.gitInfoStatus !== 'ready' ? (
|
|
80
|
+
_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-not-repo", className: "text-muted-foreground border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [_jsx(FolderOpen, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "min-w-0 truncate opacity-60", children: data.repositoryPath ?? 'Unknown path' })] }) }), _jsx("div", { className: "text-muted-foreground border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs opacity-40", children: [_jsx(GitBranch, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: "Not a git repository" })] }) })] })) : data.gitInfoStatus !== 'ready' ? (
|
|
81
81
|
/* Loading — show skeleton placeholders for both rows */
|
|
82
|
-
_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-git-loading", className: "border-t px-4 py-2", children: _jsxs("div", { className: "flex h-4 items-center gap-2 text-xs", children: [_jsx(GitBranch, { className: "text-muted-foreground h-3 w-3 shrink-0" }), _jsx("span", { className: "bg-muted h-3 w-20 animate-pulse rounded" })] }) }), _jsx("div", { className: "border-t px-4 py-2", children: _jsxs("div", { className: "flex h-4 items-center gap-2 text-xs", children: [_jsx(GitCommitHorizontal, { className: "text-muted-foreground h-3 w-3 shrink-0" }), _jsx("span", { className: "bg-muted h-3 w-36 animate-pulse rounded" })] }) })] })) : null, featureFlags.envDeploy && data.repositoryPath ? (_jsx("div", { "data-testid": "repository-node-dev-preview", className: "border-t px-4 py-2", onClick: (e) => e.stopPropagation(), children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [deployAction.deployError ? (_jsx("span", { className: "truncate text-xs text-red-500", children: deployAction.deployError })) : isDeploymentActive ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "mr-0.5 inline-block h-2 w-2 shrink-0 rounded-full bg-green-500" }), deployAction.url ? (_jsx("a", { href: deployAction.url, target: "_blank", rel: "noopener noreferrer", className: "truncate text-green-700 hover:underline dark:text-green-400", children: deployAction.url })) : (_jsx("span", { className: "text-muted-foreground", children: "Starting..." }))] })) : (_jsxs("span", { className: "text-muted-foreground", children: ["Run", _jsx("span", { className: "text-muted-foreground/50 ml-2 text-[10px]", children: "start local environment" })] })), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className:
|
|
82
|
+
_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-git-loading", className: "border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex h-4 items-center gap-2 text-xs", children: [_jsx(GitBranch, { className: "text-muted-foreground h-3 w-3 shrink-0" }), _jsx("span", { className: "bg-muted h-3 w-20 animate-pulse rounded" })] }) }), _jsx("div", { className: "border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex h-4 items-center gap-2 text-xs", children: [_jsx(GitCommitHorizontal, { className: "text-muted-foreground h-3 w-3 shrink-0" }), _jsx("span", { className: "bg-muted h-3 w-36 animate-pulse rounded" })] }) })] })) : null, featureFlags.envDeploy && data.repositoryPath ? (_jsx("div", { "data-testid": "repository-node-dev-preview", className: "border-border/50 border-t px-4 py-2", onClick: (e) => e.stopPropagation(), children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [deployAction.deployError ? (_jsx("span", { className: "truncate text-xs text-red-500", children: deployAction.deployError })) : isDeploymentActive ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "mr-0.5 inline-block h-2 w-2 shrink-0 rounded-full bg-green-500" }), deployAction.url ? (_jsx("a", { href: deployAction.url, target: "_blank", rel: "noopener noreferrer", className: "truncate text-green-700 hover:underline dark:text-green-400", children: deployAction.url })) : (_jsx("span", { className: "text-muted-foreground", children: "Starting..." }))] })) : (_jsxs("span", { className: "text-muted-foreground", children: ["Run", _jsx("span", { className: "text-muted-foreground/50 ml-2 text-[10px]", children: "start local environment" })] })), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: cn('ml-auto flex items-center', !isDeploymentActive &&
|
|
83
|
+
!deployAction.deployError &&
|
|
84
|
+
'[&_button]:text-green-600 [&_button]:hover:text-green-700 dark:[&_button]:text-green-400 dark:[&_button]:hover:text-green-300'), children: _jsx(ActionButton, { label: deployAction.deployError
|
|
83
85
|
? 'Retry'
|
|
84
86
|
: isDeploymentActive
|
|
85
87
|
? 'Stop Dev Server'
|
|
@@ -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":"AAyBA,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,kDAmM9B"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
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, } from 'lucide-react';
|
|
4
|
+
import { FolderOpen, Copy, Check, Loader2, CheckCircle2, AlertCircle, Terminal, ChevronDown, ExternalLink, } from 'lucide-react';
|
|
5
5
|
import { cn } from '../../../lib/utils.js';
|
|
6
6
|
import { pickFolder } from '../../common/add-repository-button/pick-folder.js';
|
|
7
7
|
import { ReactFileManagerDialog } from '../../common/react-file-manager-dialog/index.js';
|
|
8
8
|
import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
|
|
9
9
|
import { isAgentSetupComplete } from '../../../app/actions/agent-setup-flag.js';
|
|
10
10
|
import { checkAgentAuth } from '../../../app/actions/check-agent-auth.js';
|
|
11
|
+
import { checkToolStatus } from '../../../app/actions/check-tool-status.js';
|
|
11
12
|
import { WelcomeAgentSetup } from './welcome-agent-setup.js';
|
|
12
13
|
const commands = ['cd ~/my-repo', 'shep feat new "sleek dashboard"'];
|
|
13
14
|
export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
@@ -17,6 +18,7 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
17
18
|
const [agentReady, setAgentReady] = useState(null);
|
|
18
19
|
const [authStatus, setAuthStatus] = useState(null);
|
|
19
20
|
const [cliExpanded, setCliExpanded] = useState(false);
|
|
21
|
+
const [toolStatus, setToolStatus] = useState(null);
|
|
20
22
|
const { reactFileManager: useReactFileManager } = useFeatureFlags();
|
|
21
23
|
useEffect(() => {
|
|
22
24
|
isAgentSetupComplete().then((done) => {
|
|
@@ -27,6 +29,7 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
27
29
|
if (!agentReady)
|
|
28
30
|
return;
|
|
29
31
|
checkAgentAuth().then(setAuthStatus);
|
|
32
|
+
checkToolStatus().then(setToolStatus);
|
|
30
33
|
}, [agentReady]);
|
|
31
34
|
async function handlePickerClick() {
|
|
32
35
|
if (loading)
|
|
@@ -74,7 +77,7 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
74
77
|
/* Agent setup wizard — owns its own hero */
|
|
75
78
|
_jsx(WelcomeAgentSetup, { onComplete: handleAgentSetupComplete })) : (
|
|
76
79
|
/* Repository step — fade in to match wizard transitions */
|
|
77
|
-
_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: "Add a project" }), _jsxs("p", { className: "text-muted-foreground mt-3 text-center text-lg leading-relaxed font-light", children: ["Add your project folder to unlock feature creation.", _jsx("br", {}), "Describe what you need \u2014 Shep handles the rest."] }),
|
|
80
|
+
_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: "Add a project" }), _jsxs("p", { className: "text-muted-foreground mt-3 text-center text-lg leading-relaxed font-light", children: ["Add your project folder to unlock feature creation.", _jsx("br", {}), "Describe what you need \u2014 Shep handles the rest."] }), _jsxs("div", { className: "mt-8 flex w-full flex-col gap-3", children: [_jsx(AgentAuthBanner, { status: authStatus, onRetry: handleRetryAuth }), _jsx(ToolStatusRow, { label: "Git", status: toolStatus?.git ?? null, missingHint: "Required for all phases" }), _jsx(ToolStatusRow, { label: "GitHub CLI", status: toolStatus?.gh ?? null, missingHint: "Required for pull requests" })] }), _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 ? 'Opening…' : 'Choose a Folder'] }), _jsx("p", { className: "text-muted-foreground/60 mt-3 text-center text-sm", children: "Any folder works \u2014 git will be initialized automatically if needed." })] })), agentReady ? (_jsxs("div", { className: "absolute bottom-8 flex flex-col items-center", style: {
|
|
78
81
|
animationDelay: '400ms',
|
|
79
82
|
animationDuration: '600ms',
|
|
80
83
|
animationFillMode: 'both',
|
|
@@ -83,24 +86,47 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
83
86
|
setShowReactPicker(false);
|
|
84
87
|
}, onSelect: handleReactPickerSelect })] }));
|
|
85
88
|
}
|
|
86
|
-
/**
|
|
89
|
+
/** Status row for the AI agent (Claude Code, etc.) */
|
|
87
90
|
function AgentAuthBanner({ status, onRetry, }) {
|
|
88
91
|
if (!status) {
|
|
89
|
-
return (
|
|
92
|
+
return (_jsx(ChecklistRow, { icon: _jsx(Loader2, { className: "text-muted-foreground/50 h-4 w-4 animate-spin" }), children: _jsx("span", { className: "text-muted-foreground/50 text-sm", children: "Checking setup\u2026" }) }));
|
|
90
93
|
}
|
|
91
94
|
if (status.installed && status.authenticated) {
|
|
92
|
-
return (
|
|
95
|
+
return (_jsx(ChecklistRow, { icon: _jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-500" }), children: _jsxs("span", { className: "text-sm text-emerald-600 dark:text-emerald-400", children: [status.label, " ready"] }) }));
|
|
93
96
|
}
|
|
94
97
|
if (!status.installed) {
|
|
95
|
-
return (_jsxs(
|
|
98
|
+
return (_jsxs(ChecklistRow, { icon: _jsx(AlertCircle, { className: "h-4 w-4 text-amber-500" }), children: [_jsxs("span", { className: "text-sm font-medium text-amber-600 dark:text-amber-400", children: [status.label, " not installed"] }), status.installCommand ? _jsx(CopyableCommand, { command: status.installCommand }) : null, _jsx("button", { type: "button", onClick: onRetry, className: "text-xs text-amber-600 underline underline-offset-2 hover:text-amber-800 dark:text-amber-400", children: "Re-check" })] }));
|
|
96
99
|
}
|
|
97
|
-
return (_jsxs(
|
|
100
|
+
return (_jsxs(ChecklistRow, { icon: _jsx(AlertCircle, { className: "h-4 w-4 text-amber-500" }), children: [_jsxs("span", { className: "text-sm font-medium text-amber-600 dark:text-amber-400", children: [status.label, " needs authentication"] }), status.authCommand ? _jsx(CopyableCommand, { command: status.authCommand }) : null, _jsxs("div", { className: "flex items-center gap-3", children: [status.binaryName ? (_jsxs("button", { type: "button", "data-testid": "auth-banner-open-terminal", onClick: async () => {
|
|
98
101
|
try {
|
|
99
102
|
const toolId = status.agentType === 'claude-code' ? 'claude-code' : status.agentType;
|
|
100
103
|
await fetch(`/api/tools/${toolId}/launch`, { method: 'POST' });
|
|
101
104
|
}
|
|
102
105
|
catch {
|
|
103
|
-
|
|
106
|
+
/* best effort */
|
|
104
107
|
}
|
|
105
|
-
}, className: "flex items-center gap-1
|
|
108
|
+
}, className: "flex items-center gap-1 text-xs font-medium text-amber-600 underline underline-offset-2 hover:text-amber-800 dark:text-amber-400", children: [_jsx(Terminal, { className: "h-3 w-3" }), "Open ", status.label] })) : null, _jsx("button", { type: "button", onClick: onRetry, className: "text-xs text-amber-600 underline underline-offset-2 hover:text-amber-800 dark:text-amber-400", children: "Re-check" })] })] }));
|
|
109
|
+
}
|
|
110
|
+
/** Status row for system tools (git, gh) */
|
|
111
|
+
function ToolStatusRow({ label, status, missingHint, }) {
|
|
112
|
+
if (!status) {
|
|
113
|
+
return (_jsx(ChecklistRow, { icon: _jsx(Loader2, { className: "text-muted-foreground/50 h-4 w-4 animate-spin" }), children: _jsxs("span", { className: "text-muted-foreground/50 text-sm", children: ["Checking ", label, "\u2026"] }) }));
|
|
114
|
+
}
|
|
115
|
+
if (status.installed) {
|
|
116
|
+
return (_jsx(ChecklistRow, { icon: _jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-500" }), children: _jsxs("span", { className: "flex items-baseline gap-2", children: [_jsxs("span", { className: "text-sm text-emerald-600 dark:text-emerald-400", children: [label, " ready"] }), status.version ? (_jsxs("span", { className: "text-muted-foreground/40 text-xs", children: ["v", status.version] })) : null] }) }));
|
|
117
|
+
}
|
|
118
|
+
return (_jsxs(ChecklistRow, { icon: _jsx(AlertCircle, { className: "h-4 w-4 text-amber-500" }), children: [_jsxs("span", { className: "text-sm font-medium text-amber-600 dark:text-amber-400", children: [label, " not found"] }), _jsx("span", { className: "text-muted-foreground/50 text-xs", children: missingHint }), status.installCommand ? _jsx(CopyableCommand, { command: status.installCommand }) : null, status.installUrl ? (_jsxs("a", { href: status.installUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 text-xs text-amber-600 underline underline-offset-2 hover:text-amber-800 dark:text-amber-400", children: ["Docs ", _jsx(ExternalLink, { className: "h-3 w-3" })] })) : null] }));
|
|
119
|
+
}
|
|
120
|
+
/** Checklist row: icon pinned left, children stacked vertically and fill width */
|
|
121
|
+
function ChecklistRow({ icon, children }) {
|
|
122
|
+
return (_jsxs("div", { className: "animate-in fade-in flex items-start gap-2.5", children: [_jsx("div", { className: "mt-0.5 shrink-0", children: icon }), _jsx("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: children })] }));
|
|
123
|
+
}
|
|
124
|
+
/** Compact copyable command block — fills available row width */
|
|
125
|
+
function CopyableCommand({ command }) {
|
|
126
|
+
const [copied, setCopied] = useState(false);
|
|
127
|
+
return (_jsxs("button", { type: "button", onClick: async () => {
|
|
128
|
+
await navigator.clipboard.writeText(command);
|
|
129
|
+
setCopied(true);
|
|
130
|
+
setTimeout(() => setCopied(false), 2000);
|
|
131
|
+
}, className: "group/cmd flex cursor-pointer items-center justify-between gap-2 rounded-md bg-zinc-100 py-1 pr-2 pl-2.5 text-left transition-colors hover:bg-zinc-200 dark:bg-zinc-800 dark:hover:bg-zinc-700", children: [_jsx("code", { className: "min-w-0 truncate text-[11px] leading-relaxed text-zinc-600 dark:text-zinc-300", children: command }), copied ? (_jsx(Check, { className: "h-3 w-3 shrink-0 text-emerald-500" })) : (_jsx(Copy, { className: "h-3 w-3 shrink-0 text-zinc-400 opacity-0 transition-opacity group-hover/cmd:opacity-100" }))] }));
|
|
106
132
|
}
|
|
@@ -3,6 +3,22 @@ import { ControlCenterEmptyState } from './control-center-empty-state.js';
|
|
|
3
3
|
declare const meta: Meta<typeof ControlCenterEmptyState>;
|
|
4
4
|
export default meta;
|
|
5
5
|
type Story = StoryObj<typeof meta>;
|
|
6
|
-
|
|
6
|
+
/** All tools installed — the happy path */
|
|
7
|
+
export declare const AllToolsReady: Story;
|
|
8
|
+
/** Git is missing — blocks all workflow phases */
|
|
9
|
+
export declare const GitMissing: Story;
|
|
10
|
+
/** GitHub CLI is missing — PR features unavailable */
|
|
11
|
+
export declare const GhCliMissing: Story;
|
|
12
|
+
/** Both git and gh are missing */
|
|
13
|
+
export declare const BothToolsMissing: Story;
|
|
14
|
+
/** Claude Code not installed */
|
|
15
|
+
export declare const ClaudeCodeNotInstalled: Story;
|
|
16
|
+
/** Cursor CLI not installed */
|
|
17
|
+
export declare const CursorCliNotInstalled: Story;
|
|
18
|
+
/** Gemini CLI not installed */
|
|
19
|
+
export declare const GeminiCliNotInstalled: Story;
|
|
20
|
+
/** Agent not installed + tools missing — worst case */
|
|
21
|
+
export declare const EverythingMissing: Story;
|
|
22
|
+
/** With callback — for interaction testing */
|
|
7
23
|
export declare const WithCallback: Story;
|
|
8
24
|
//# sourceMappingURL=control-center-empty-state.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-center-empty-state.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,uBAAuB,CAc9C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"control-center-empty-state.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,uBAAuB,CAc9C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AA+FnC,2CAA2C;AAC3C,eAAO,MAAM,aAAa,EAAE,KAG3B,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,UAAU,EAAE,KAGxB,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAC;AAEF,kCAAkC;AAClC,eAAO,MAAM,gBAAgB,EAAE,KAG9B,CAAC;AAEF,gCAAgC;AAChC,eAAO,MAAM,sBAAsB,EAAE,KAGpC,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,qBAAqB,EAAE,KAGnC,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,qBAAqB,EAAE,KAGnC,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,EAAE,KAG/B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,YAAY,EAAE,KAO1B,CAAC"}
|
|
@@ -12,9 +12,118 @@ const meta = {
|
|
|
12
12
|
],
|
|
13
13
|
};
|
|
14
14
|
export default meta;
|
|
15
|
-
|
|
15
|
+
const agentReady = {
|
|
16
|
+
agentType: 'claude-code',
|
|
17
|
+
installed: true,
|
|
18
|
+
authenticated: true,
|
|
19
|
+
label: 'Claude Code',
|
|
20
|
+
binaryName: 'claude',
|
|
21
|
+
installCommand: 'curl -fsSL https://claude.ai/install.sh | bash',
|
|
22
|
+
authCommand: null,
|
|
23
|
+
};
|
|
24
|
+
const claudeNotInstalled = {
|
|
25
|
+
agentType: 'claude-code',
|
|
26
|
+
installed: false,
|
|
27
|
+
authenticated: false,
|
|
28
|
+
label: 'Claude Code',
|
|
29
|
+
binaryName: 'claude',
|
|
30
|
+
installCommand: 'curl -fsSL https://claude.ai/install.sh | bash',
|
|
31
|
+
authCommand: 'Install Claude Code first',
|
|
32
|
+
};
|
|
33
|
+
const cursorNotInstalled = {
|
|
34
|
+
agentType: 'cursor',
|
|
35
|
+
installed: false,
|
|
36
|
+
authenticated: false,
|
|
37
|
+
label: 'Cursor CLI',
|
|
38
|
+
binaryName: 'cursor-agent',
|
|
39
|
+
installCommand: 'curl https://cursor.com/install -fsS | bash',
|
|
40
|
+
authCommand: 'Install Cursor CLI first',
|
|
41
|
+
};
|
|
42
|
+
const geminiNotInstalled = {
|
|
43
|
+
agentType: 'gemini-cli',
|
|
44
|
+
installed: false,
|
|
45
|
+
authenticated: false,
|
|
46
|
+
label: 'Gemini CLI',
|
|
47
|
+
binaryName: 'gemini',
|
|
48
|
+
installCommand: 'npm install -g @google/gemini-cli',
|
|
49
|
+
authCommand: 'Install Gemini CLI first',
|
|
50
|
+
};
|
|
51
|
+
const gitReady = {
|
|
52
|
+
installed: true,
|
|
53
|
+
version: '2.43.0',
|
|
54
|
+
installCommand: 'sudo apt-get install -y git',
|
|
55
|
+
installUrl: 'https://git-scm.com',
|
|
56
|
+
};
|
|
57
|
+
const gitMissing = {
|
|
58
|
+
installed: false,
|
|
59
|
+
version: null,
|
|
60
|
+
installCommand: 'sudo apt-get install -y git',
|
|
61
|
+
installUrl: 'https://git-scm.com',
|
|
62
|
+
};
|
|
63
|
+
const ghReady = {
|
|
64
|
+
installed: true,
|
|
65
|
+
version: '2.40.1',
|
|
66
|
+
installCommand: 'sudo apt install gh -y',
|
|
67
|
+
installUrl: 'https://cli.github.com',
|
|
68
|
+
};
|
|
69
|
+
const ghMissing = {
|
|
70
|
+
installed: false,
|
|
71
|
+
version: null,
|
|
72
|
+
installCommand: 'sudo apt install gh -y',
|
|
73
|
+
installUrl: 'https://cli.github.com',
|
|
74
|
+
};
|
|
75
|
+
function setMocks(agent, git, gh) {
|
|
76
|
+
return () => {
|
|
77
|
+
const win = globalThis;
|
|
78
|
+
win.__mockAgentAuth = agent;
|
|
79
|
+
win.__mockToolStatus = { git, gh };
|
|
80
|
+
return () => {
|
|
81
|
+
delete win.__mockAgentAuth;
|
|
82
|
+
delete win.__mockToolStatus;
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/** All tools installed — the happy path */
|
|
87
|
+
export const AllToolsReady = {
|
|
88
|
+
args: {},
|
|
89
|
+
beforeEach: setMocks(agentReady, gitReady, ghReady),
|
|
90
|
+
};
|
|
91
|
+
/** Git is missing — blocks all workflow phases */
|
|
92
|
+
export const GitMissing = {
|
|
93
|
+
args: {},
|
|
94
|
+
beforeEach: setMocks(agentReady, gitMissing, ghReady),
|
|
95
|
+
};
|
|
96
|
+
/** GitHub CLI is missing — PR features unavailable */
|
|
97
|
+
export const GhCliMissing = {
|
|
98
|
+
args: {},
|
|
99
|
+
beforeEach: setMocks(agentReady, gitReady, ghMissing),
|
|
100
|
+
};
|
|
101
|
+
/** Both git and gh are missing */
|
|
102
|
+
export const BothToolsMissing = {
|
|
103
|
+
args: {},
|
|
104
|
+
beforeEach: setMocks(agentReady, gitMissing, ghMissing),
|
|
105
|
+
};
|
|
106
|
+
/** Claude Code not installed */
|
|
107
|
+
export const ClaudeCodeNotInstalled = {
|
|
108
|
+
args: {},
|
|
109
|
+
beforeEach: setMocks(claudeNotInstalled, gitReady, ghReady),
|
|
110
|
+
};
|
|
111
|
+
/** Cursor CLI not installed */
|
|
112
|
+
export const CursorCliNotInstalled = {
|
|
113
|
+
args: {},
|
|
114
|
+
beforeEach: setMocks(cursorNotInstalled, gitReady, ghReady),
|
|
115
|
+
};
|
|
116
|
+
/** Gemini CLI not installed */
|
|
117
|
+
export const GeminiCliNotInstalled = {
|
|
118
|
+
args: {},
|
|
119
|
+
beforeEach: setMocks(geminiNotInstalled, gitReady, ghReady),
|
|
120
|
+
};
|
|
121
|
+
/** Agent not installed + tools missing — worst case */
|
|
122
|
+
export const EverythingMissing = {
|
|
16
123
|
args: {},
|
|
124
|
+
beforeEach: setMocks(claudeNotInstalled, gitMissing, ghMissing),
|
|
17
125
|
};
|
|
126
|
+
/** With callback — for interaction testing */
|
|
18
127
|
export const WithCallback = {
|
|
19
128
|
args: {
|
|
20
129
|
onRepositorySelect: (path) => {
|
package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAMvF,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAG9E,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,QAAQ,CAAC;IACjC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAmBD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,eAAe,EACf,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAMvF,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAG9E,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,QAAQ,CAAC;IACjC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAmBD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,eAAe,EACf,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,2CA4HrB"}
|
|
@@ -60,5 +60,5 @@ export function FeaturesCanvas({ nodes, edges, selectedFeatureId, defaultViewpor
|
|
|
60
60
|
}, [isEmpty]);
|
|
61
61
|
const fallbackEmptyState = isEmpty && !emptyState ? (_jsx(EmptyState, { title: "No features yet", description: "Get started by creating your first feature.", action: _jsxs(Button, { onClick: onAddFeature, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "New Feature"] }) })) : null;
|
|
62
62
|
const overlayContent = emptyState ?? fallbackEmptyState;
|
|
63
|
-
return (_jsxs("div", { "data-testid": isEmpty ? 'features-canvas-empty' : 'features-canvas', "data-no-drawer-close": true, className: "dark:bg-background pointer-events-auto relative h-full w-full bg-[#f6f7f8]", children: [_jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, onMoveStart: onCanvasDrag, onMoveEnd: onMoveEnd, defaultViewport: defaultViewport ?? FALLBACK_VIEWPORT, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, proOptions: { hideAttribution: true }, children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 24, size: 1, color: "#b8bcc4", className: "dark:[&_circle]:!fill-white/[0.1]" }), !isEmpty && (_jsx(Controls, { showInteractive: false, children: onResetViewport ? _jsx(ResetButton, { onResetViewport: onResetViewport }) : null })), toolbar] }), showOverlay && overlayContent ? (_jsx("div", { className: cn('pointer-events-none absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300', overlayExiting ? 'opacity-0' : 'animate-in fade-in opacity-100 duration-200'), children: _jsx("div", { className: "pointer-events-auto h-full w-full", children: overlayContent }) })) : null] }));
|
|
63
|
+
return (_jsxs("div", { "data-testid": isEmpty ? 'features-canvas-empty' : 'features-canvas', "data-no-drawer-close": true, className: "dark:bg-background pointer-events-auto relative h-full w-full bg-[#f6f7f8]", children: [_jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, onMoveStart: onCanvasDrag, onMoveEnd: onMoveEnd, defaultViewport: defaultViewport ?? FALLBACK_VIEWPORT, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, proOptions: { hideAttribution: true }, className: "[&_.react-flow__pane]:!cursor-default", children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 24, size: 1, color: "#b8bcc4", className: "dark:[&_circle]:!fill-white/[0.1]" }), !isEmpty && (_jsx(Controls, { showInteractive: false, children: onResetViewport ? _jsx(ResetButton, { onResetViewport: onResetViewport }) : null })), toolbar] }), showOverlay && overlayContent ? (_jsx("div", { className: cn('pointer-events-none absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300', overlayExiting ? 'opacity-0' : 'animate-in fade-in opacity-100 duration-200'), children: _jsx("div", { className: "pointer-events-auto h-full w-full", children: overlayContent }) })) : null] }));
|
|
64
64
|
}
|
package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.d.ts
CHANGED
|
@@ -17,4 +17,5 @@ export declare const InteractiveWithRepository: Story;
|
|
|
17
17
|
export declare const WithSavedViewport: Story;
|
|
18
18
|
export declare const ZoomedOutViewport: Story;
|
|
19
19
|
export declare const FastModeFeatures: Story;
|
|
20
|
+
export declare const FullSpectrum: Story;
|
|
20
21
|
//# sourceMappingURL=features-canvas.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features-canvas.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"features-canvas.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIvD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOnD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAcrC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAyNnC,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAK3B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAK5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KASzB,CAAC;AAoDF,eAAO,MAAM,mCAAmC,EAAE,KAKjD,CAAC;AA4BF,eAAO,MAAM,gCAAgC,EAAE,KAO9C,CAAC;AA0DF,eAAO,MAAM,gCAAgC,EAAE,KAS9C,CAAC;AAiDF,eAAO,MAAM,oBAAoB,EAAE,KAQlC,CAAC;AAqGF,eAAO,MAAM,oCAAoC,EAAE,KAKlD,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KAMvC,CAAC;AAIF,eAAO,MAAM,iBAAiB,EAAE,KAO/B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAO/B,CAAC;AAsEF,eAAO,MAAM,gBAAgB,EAAE,KAM9B,CAAC;AAoYF,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC"}
|