@shepai/cli 1.76.0 → 1.77.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/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +1 -0
- package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/spec-initializer.interface.d.ts +4 -1
- package/dist/packages/core/src/application/ports/output/services/spec-initializer.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +5 -2
- package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
- package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts +220 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.js +66 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +3 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +10 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/lifecycle-context.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/lifecycle-context.js +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.d.ts +21 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.js +60 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.d.ts +25 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.js +176 -0
- package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.js +8 -3
- package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/new.command.js +2 -0
- package/dist/src/presentation/web/app/actions/create-feature.d.ts +2 -0
- package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/create-feature.js +3 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +2 -0
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +5 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +18 -0
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +49 -0
- 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 +28 -4
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +4 -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 +6 -3
- 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 +71 -2
- package/dist/src/presentation/web/hooks/use-graph-state.d.ts +2 -0
- package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-graph-state.js +4 -0
- package/dist/src/presentation/web/hooks/use-viewport-persistence.d.ts +1 -0
- package/dist/src/presentation/web/hooks/use-viewport-persistence.d.ts.map +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/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +16 -16
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +19 -19
- 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 +14 -14
- 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 +16 -16
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +19 -19
- 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 +14 -14
- 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 +14 -14
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
- package/web/.next/server/chunks/ssr/_0e9d6bf7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_a3854150._.js → _2a862f34._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_a3854150._.js.map → _2a862f34._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
- package/web/.next/server/chunks/ssr/_61351ed3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
- package/web/.next/server/chunks/ssr/_8400c8bb._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
- package/web/.next/server/chunks/ssr/_9f940437._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_163038ba._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_163038ba._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_459cb687._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_459cb687._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +22 -22
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +16 -16
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +19 -19
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +16 -16
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +19 -19
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_a3854150._.js → _2a862f34._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_163038ba._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_459cb687._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +22 -22
- package/web/.next/standalone/src/presentation/web/app/actions/create-feature.ts +6 -1
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx +57 -0
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +21 -0
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +32 -4
- package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +9 -4
- package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx +81 -2
- package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +1 -1
- package/web/.next/standalone/src/presentation/web/hooks/use-graph-state.ts +7 -0
- package/web/.next/standalone/src/presentation/web/hooks/use-viewport-persistence.ts +2 -0
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/{293231ccc0b144fa.js → 5968047406179daf.js} +1 -1
- package/web/.next/static/chunks/{255140c45a023ff4.js → 6a45ff0fe9faf80e.js} +1 -1
- package/web/.next/static/chunks/{9a765e022ef2b815.js → 7ea9e0b8236d5f48.js} +1 -1
- package/web/.next/static/chunks/{6931ae67c2484ddf.js → a3a1392c422107d6.js} +1 -1
- package/web/.next/static/chunks/{3bc2a07d02372939.js → c558d0da468011b6.js} +1 -1
- package/web/.next/static/chunks/{c1dbeb3307dab443.js → ce67a6fcc19c61dc.js} +3 -3
- package/web/.next/static/chunks/d5b885838e1da36a.js +1 -0
- package/web/.next/static/chunks/{d7786685ec8efe10.js → e8637d52f6093074.js} +1 -1
- package/web/.next/static/chunks/{716547ef8d13139d.js → efaf0f0eb50be73f.js} +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/static/chunks/11a6c88ffcbac93f.js +0 -1
- /package/web/.next/static/{L6_6jZ4TnQuuDXIF5GZEf → TkQduVaaKmOXMiLB6CK5h}/_buildManifest.js +0 -0
- /package/web/.next/static/{L6_6jZ4TnQuuDXIF5GZEf → TkQduVaaKmOXMiLB6CK5h}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{L6_6jZ4TnQuuDXIF5GZEf → TkQduVaaKmOXMiLB6CK5h}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fast-Implement Prompt Builder
|
|
3
|
+
*
|
|
4
|
+
* Builds a single-pass implementation prompt for fast mode.
|
|
5
|
+
* Combines the user's raw query with lightweight codebase context
|
|
6
|
+
* (CLAUDE.md, package.json, shallow directory listing).
|
|
7
|
+
*
|
|
8
|
+
* The prompt instructs the executor to implement changes and run tests,
|
|
9
|
+
* but NOT to commit, push, or create PRs (that's the merge node's job).
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync, readdirSync, statSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import yaml from 'js-yaml';
|
|
14
|
+
import { readSpecFile } from '../node-helpers.js';
|
|
15
|
+
/**
|
|
16
|
+
* Read a file from the worktree, returning empty string if not found.
|
|
17
|
+
*/
|
|
18
|
+
function readWorktreeFile(worktreePath, filename) {
|
|
19
|
+
try {
|
|
20
|
+
return readFileSync(join(worktreePath, filename), 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build a shallow directory listing (depth 1-2) of the worktree.
|
|
28
|
+
* Returns a tree-style string. Skips common noise directories.
|
|
29
|
+
*/
|
|
30
|
+
function buildDirectoryListing(worktreePath) {
|
|
31
|
+
const SKIP_DIRS = new Set([
|
|
32
|
+
'node_modules',
|
|
33
|
+
'.git',
|
|
34
|
+
'.next',
|
|
35
|
+
'dist',
|
|
36
|
+
'build',
|
|
37
|
+
'coverage',
|
|
38
|
+
'.turbo',
|
|
39
|
+
'.cache',
|
|
40
|
+
'.shep',
|
|
41
|
+
]);
|
|
42
|
+
const lines = [];
|
|
43
|
+
try {
|
|
44
|
+
const topLevel = readdirSync(worktreePath);
|
|
45
|
+
for (const entry of topLevel) {
|
|
46
|
+
if (SKIP_DIRS.has(entry))
|
|
47
|
+
continue;
|
|
48
|
+
const fullPath = join(worktreePath, entry);
|
|
49
|
+
let isDir = false;
|
|
50
|
+
try {
|
|
51
|
+
isDir = statSync(fullPath).isDirectory();
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (isDir) {
|
|
57
|
+
lines.push(`${entry}/`);
|
|
58
|
+
try {
|
|
59
|
+
const children = readdirSync(fullPath);
|
|
60
|
+
for (const child of children) {
|
|
61
|
+
if (SKIP_DIRS.has(child))
|
|
62
|
+
continue;
|
|
63
|
+
const childPath = join(fullPath, child);
|
|
64
|
+
let childIsDir = false;
|
|
65
|
+
try {
|
|
66
|
+
childIsDir = statSync(childPath).isDirectory();
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
lines.push(` ${child}${childIsDir ? '/' : ''}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Cannot read subdirectory — skip
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
lines.push(entry);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return '(unable to list directory)';
|
|
85
|
+
}
|
|
86
|
+
return lines.join('\n');
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Extract the user query from spec.yaml's userQuery field.
|
|
90
|
+
* Falls back to the raw YAML content if parsing fails.
|
|
91
|
+
*/
|
|
92
|
+
function extractUserQuery(specDir) {
|
|
93
|
+
const specContent = readSpecFile(specDir, 'spec.yaml');
|
|
94
|
+
if (!specContent)
|
|
95
|
+
return '';
|
|
96
|
+
try {
|
|
97
|
+
const data = yaml.load(specContent);
|
|
98
|
+
const userQuery = data?.userQuery;
|
|
99
|
+
if (typeof userQuery === 'string' && userQuery.trim()) {
|
|
100
|
+
return userQuery.trim();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Fall through to raw content
|
|
105
|
+
}
|
|
106
|
+
return specContent;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Build the fast-implement prompt from user query + codebase context.
|
|
110
|
+
*
|
|
111
|
+
* The prompt includes:
|
|
112
|
+
* 1. User's raw query (from spec.yaml userQuery field)
|
|
113
|
+
* 2. CLAUDE.md content (if exists)
|
|
114
|
+
* 3. package.json (if exists)
|
|
115
|
+
* 4. Shallow directory listing (depth 1-2)
|
|
116
|
+
*
|
|
117
|
+
* Instructs the executor to implement, test, and validate — but NOT
|
|
118
|
+
* commit/push/PR (that's the merge node's job).
|
|
119
|
+
*/
|
|
120
|
+
export function buildFastImplementPrompt(state) {
|
|
121
|
+
const cwd = state.worktreePath || state.repositoryPath;
|
|
122
|
+
const userQuery = extractUserQuery(state.specDir);
|
|
123
|
+
// Read optional context files
|
|
124
|
+
const claudeMd = readWorktreeFile(cwd, 'CLAUDE.md');
|
|
125
|
+
const packageJson = readWorktreeFile(cwd, 'package.json');
|
|
126
|
+
const dirListing = buildDirectoryListing(cwd);
|
|
127
|
+
// Build sections conditionally
|
|
128
|
+
const sections = [];
|
|
129
|
+
sections.push(`You are a senior software engineer implementing a change directly from a user request.
|
|
130
|
+
|
|
131
|
+
## User Request
|
|
132
|
+
|
|
133
|
+
${userQuery}
|
|
134
|
+
|
|
135
|
+
## Implementation Instructions
|
|
136
|
+
|
|
137
|
+
1. Implement the requested changes in the codebase
|
|
138
|
+
2. Write tests for your changes where appropriate
|
|
139
|
+
3. Run the test suite and fix any failures
|
|
140
|
+
4. Run the linter and fix any issues
|
|
141
|
+
5. Ensure the project builds successfully
|
|
142
|
+
6. Do NOT commit, push, or create a PR — just make the code changes
|
|
143
|
+
|
|
144
|
+
## Working Directory
|
|
145
|
+
|
|
146
|
+
${cwd}`);
|
|
147
|
+
if (claudeMd) {
|
|
148
|
+
sections.push(`## Project Guidelines (CLAUDE.md)
|
|
149
|
+
|
|
150
|
+
${claudeMd}`);
|
|
151
|
+
}
|
|
152
|
+
if (packageJson) {
|
|
153
|
+
// Truncate large package.json to stay within prompt budget
|
|
154
|
+
const truncated = packageJson.length > 3000 ? `${packageJson.slice(0, 3000)}\n...(truncated)` : packageJson;
|
|
155
|
+
sections.push(`## Package Configuration (package.json)
|
|
156
|
+
|
|
157
|
+
\`\`\`json
|
|
158
|
+
${truncated}
|
|
159
|
+
\`\`\``);
|
|
160
|
+
}
|
|
161
|
+
if (dirListing && dirListing !== '(unable to list directory)') {
|
|
162
|
+
sections.push(`## Project Structure
|
|
163
|
+
|
|
164
|
+
\`\`\`
|
|
165
|
+
${dirListing}
|
|
166
|
+
\`\`\``);
|
|
167
|
+
}
|
|
168
|
+
sections.push(`## Constraints
|
|
169
|
+
|
|
170
|
+
- Implement ONLY what the user requested — nothing more
|
|
171
|
+
- Follow existing codebase conventions and patterns
|
|
172
|
+
- Do NOT commit, push, or create pull requests
|
|
173
|
+
- Do NOT modify any spec YAML files
|
|
174
|
+
- Keep changes focused and minimal`);
|
|
175
|
+
return sections.join('\n\n');
|
|
176
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { ISpecInitializerService, SpecInitializerResult } from '../../../application/ports/output/services/spec-initializer.interface.js';
|
|
9
9
|
export declare class SpecInitializerService implements ISpecInitializerService {
|
|
10
|
-
initialize(basePath: string, slug: string, featureNumber: number, description: string): Promise<SpecInitializerResult>;
|
|
10
|
+
initialize(basePath: string, slug: string, featureNumber: number, description: string, mode?: 'fast'): Promise<SpecInitializerResult>;
|
|
11
11
|
/**
|
|
12
12
|
* Scan specs/ for existing NNN-* directories and return the next available number.
|
|
13
13
|
* Uses the DB-derived hint as a minimum, but always respects filesystem state.
|
package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-initializer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/spec/spec-initializer.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,mEAAmE,CAAC;AA8P3E,qBAAa,sBAAuB,YAAW,uBAAuB;IAC9D,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"spec-initializer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/spec/spec-initializer.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,mEAAmE,CAAC;AA8P3E,qBAAa,sBAAuB,YAAW,uBAAuB;IAC9D,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,qBAAqB,CAAC;IAqCjC;;;OAGG;YACW,iBAAiB;CAoBhC"}
|
|
@@ -240,7 +240,7 @@ const TEMPLATES = [
|
|
|
240
240
|
{ filename: 'feature.yaml', content: FEATURE_YAML },
|
|
241
241
|
];
|
|
242
242
|
export class SpecInitializerService {
|
|
243
|
-
async initialize(basePath, slug, featureNumber, description) {
|
|
243
|
+
async initialize(basePath, slug, featureNumber, description, mode) {
|
|
244
244
|
// Scan existing specs/ directory for highest NNN prefix to avoid collisions
|
|
245
245
|
// (specs may have been created outside the DB, e.g., via /shep-kit:new-feature)
|
|
246
246
|
const resolvedNumber = await this.resolveNextNumber(basePath, featureNumber);
|
|
@@ -253,8 +253,13 @@ export class SpecInitializerService {
|
|
|
253
253
|
const date = now.toISOString().split('T')[0];
|
|
254
254
|
const timestamp = now.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
255
255
|
const vars = { nnn, slug, featureNumber: resolvedNumber, date, timestamp, description };
|
|
256
|
-
//
|
|
257
|
-
|
|
256
|
+
// In fast mode, write feature.yaml + spec.yaml (spec.yaml stores the user query
|
|
257
|
+
// which the fast-implement node reads; no research/plan/tasks needed)
|
|
258
|
+
const templates = mode === 'fast'
|
|
259
|
+
? TEMPLATES.filter(({ filename }) => filename === 'feature.yaml' || filename === 'spec.yaml')
|
|
260
|
+
: TEMPLATES;
|
|
261
|
+
// Write template files
|
|
262
|
+
await Promise.all(templates.map(({ filename, content }) => writeFile(join(specDir, filename), applyTemplate(content, vars), 'utf-8')));
|
|
258
263
|
return { specDir, featureNumber: nnn };
|
|
259
264
|
}
|
|
260
265
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkDpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CA8G1C"}
|
|
@@ -48,6 +48,7 @@ export function createNewCommand() {
|
|
|
48
48
|
.option('--allow-merge', 'Auto-approve merge phase')
|
|
49
49
|
.option('--allow-all', 'Run fully autonomous (no approval pauses)')
|
|
50
50
|
.option('--parent <fid>', 'Parent feature ID (full or partial prefix)')
|
|
51
|
+
.option('--fast', 'Skip SDLC phases and implement directly from your prompt')
|
|
51
52
|
.action(async (description, options) => {
|
|
52
53
|
try {
|
|
53
54
|
const useCase = container.resolve(CreateFeatureUseCase);
|
|
@@ -83,6 +84,7 @@ export function createNewCommand() {
|
|
|
83
84
|
push,
|
|
84
85
|
openPr,
|
|
85
86
|
...(parentId !== undefined && { parentId }),
|
|
87
|
+
...(options.fast && { fast: true }),
|
|
86
88
|
}));
|
|
87
89
|
const { feature, warning } = result;
|
|
88
90
|
const repoHash = createHash('sha256').update(repoPath).digest('hex').slice(0, 16);
|
|
@@ -15,6 +15,8 @@ interface CreateFeatureInput {
|
|
|
15
15
|
push?: boolean;
|
|
16
16
|
openPr?: boolean;
|
|
17
17
|
parentId?: string;
|
|
18
|
+
/** When true, skip SDLC phases and implement directly from the prompt. */
|
|
19
|
+
fast?: boolean;
|
|
18
20
|
}
|
|
19
21
|
export declare function createFeature(input: CreateFeatureInput): Promise<{
|
|
20
22
|
feature?: Feature;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/create-feature.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAEpE,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAQD,UAAU,kBAAkB;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE;QACd,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"create-feature.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/create-feature.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAEpE,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAQD,UAAU,kBAAkB;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE;QACd,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAaD,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA4DhD"}
|
|
@@ -9,7 +9,7 @@ function composeUserInput(description, attachments) {
|
|
|
9
9
|
return userInput;
|
|
10
10
|
}
|
|
11
11
|
export async function createFeature(input) {
|
|
12
|
-
const { description, repositoryPath, attachments, approvalGates, push, openPr, parentId } = input;
|
|
12
|
+
const { description, repositoryPath, attachments, approvalGates, push, openPr, parentId, fast } = input;
|
|
13
13
|
if (!description?.trim()) {
|
|
14
14
|
return { error: 'description is required' };
|
|
15
15
|
}
|
|
@@ -33,6 +33,7 @@ export async function createFeature(input) {
|
|
|
33
33
|
openPr: openPr ?? false,
|
|
34
34
|
...(parentId ? { parentId } : {}),
|
|
35
35
|
description,
|
|
36
|
+
...(fast ? { fast } : {}),
|
|
36
37
|
});
|
|
37
38
|
// Phase 2 (background): metadata generation, worktree, spec, agent spawn
|
|
38
39
|
// Fire-and-forget — the UI gets the real feature ID immediately
|
|
@@ -44,6 +45,7 @@ export async function createFeature(input) {
|
|
|
44
45
|
push: push ?? false,
|
|
45
46
|
openPr: openPr ?? false,
|
|
46
47
|
...(parentId ? { parentId } : {}),
|
|
48
|
+
...(fast ? { fast } : {}),
|
|
47
49
|
}, shouldSpawn)
|
|
48
50
|
.catch((err) => {
|
|
49
51
|
// eslint-disable-next-line no-console
|
package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ export interface FeatureCreatePayload {
|
|
|
18
18
|
push: boolean;
|
|
19
19
|
openPr: boolean;
|
|
20
20
|
parentId?: string;
|
|
21
|
+
/** When true, skip SDLC phases and implement directly from the prompt. */
|
|
22
|
+
fast: boolean;
|
|
21
23
|
}
|
|
22
24
|
export interface FeatureCreateDrawerProps {
|
|
23
25
|
open: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,YAAY,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAE/F,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,YAAY,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAE/F,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,IAAI,EAAE,OAAO,CAAC;CACf;AAcD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,kGAAkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,YAAoB,EACpB,gBAAgB,EAChB,QAAQ,EACR,eAAe,GAChB,EAAE,wBAAwB,2CA+Q1B"}
|
package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js
CHANGED
|
@@ -37,6 +37,7 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
|
|
|
37
37
|
const [push, setPush] = useState(defaultPush);
|
|
38
38
|
const [openPr, setOpenPr] = useState(defaultOpenPr);
|
|
39
39
|
const [parentId, setParentId] = useState(undefined);
|
|
40
|
+
const [fast, setFast] = useState(false);
|
|
40
41
|
// Sync state when workflowDefaults load asynchronously
|
|
41
42
|
useEffect(() => {
|
|
42
43
|
if (workflowDefaults) {
|
|
@@ -58,6 +59,7 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
|
|
|
58
59
|
setPush(defaultPush);
|
|
59
60
|
setOpenPr(defaultOpenPr);
|
|
60
61
|
setParentId(undefined);
|
|
62
|
+
setFast(false);
|
|
61
63
|
}, [defaultGates, defaultPush, defaultOpenPr]);
|
|
62
64
|
// Track whether the form has unsaved data
|
|
63
65
|
const isDirty = description.trim() !== '' || attachments.length > 0;
|
|
@@ -79,6 +81,7 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
|
|
|
79
81
|
},
|
|
80
82
|
push: push || openPr,
|
|
81
83
|
openPr,
|
|
84
|
+
fast,
|
|
82
85
|
...(parentId ? { parentId } : {}),
|
|
83
86
|
});
|
|
84
87
|
resetForm();
|
|
@@ -90,6 +93,7 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
|
|
|
90
93
|
onSubmit,
|
|
91
94
|
push,
|
|
92
95
|
openPr,
|
|
96
|
+
fast,
|
|
93
97
|
parentId,
|
|
94
98
|
createSound,
|
|
95
99
|
resetForm,
|
|
@@ -109,7 +113,7 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
|
|
|
109
113
|
setAttachments((prev) => prev.filter((f) => f.path !== path));
|
|
110
114
|
}, []);
|
|
111
115
|
const hasFeatures = features && features.length > 0;
|
|
112
|
-
return (_jsx(BaseDrawer, { open: open, onClose: attemptClose, size: "md", modal: false, dismissOnOutsideClick: true, "data-testid": "feature-create-drawer", header: _jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-2.5 w-2.5 shrink-0 rounded-full bg-blue-500" }), _jsx(DrawerTitle, { children: "NEW FEATURE" })] }), isSubmitting ? (_jsx(DrawerDescription, { asChild: true, children: _jsx("div", { children: _jsx(Badge, { variant: "secondary", children: "Creating..." }) }) })) : null] }), footer: _jsxs("div", { className: "flex flex-row justify-end gap-2", children: [_jsx(Button, { variant: "outline", onClick: attemptClose, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { type: "submit", form: "create-feature-form", disabled: !description.trim() || isSubmitting, children: isSubmitting ? 'Creating...' : '+ Create Feature' })] }), children: _jsx("div", { className: "overflow-y-auto p-4", children: _jsxs("form", { id: "create-feature-form", onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-description", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "DESCRIBE YOUR FEATURE" }), _jsx(Textarea, { id: "feature-description", placeholder: "e.g. Add GitHub OAuth login with callback handling and token refresh...", value: description, onChange: (e) => setDescription(e.target.value), rows: 4, required: true, disabled: isSubmitting })] }), hasFeatures ? (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "parent-feature", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "PARENT FEATURE" }), _jsx(ParentFeatureCombobox, { features: features, value: parentId, onChange: setParentId, disabled: isSubmitting })] })) : null, _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "APPROVE" }), _jsx(CheckboxGroup, { label: "Autonomous Mode", description: "YOLO!", parentAriaLabel: "Auto approve all", options: AUTO_APPROVE_OPTIONS, value: approvalGates, onValueChange: setApprovalGates, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "GIT" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(CheckboxGroupItem, { id: "push", label: "Push", description: "Push branch to remote after implementation.", checked: push || openPr, onCheckedChange: setPush, disabled: openPr || isSubmitting }), _jsx(CheckboxGroupItem, { id: "open-pr", label: "Create PR", description: "Open a pull request after pushing.", checked: openPr, onCheckedChange: setOpenPr, disabled: isSubmitting })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: ["ATTACHMENTS", attachments.length > 0 && (_jsxs("span", { className: "text-muted-foreground/60 ml-1.5", children: ["(", attachments.length, ")"] }))] }), _jsxs(Button, { type: "button", variant: "outline", size: "xs", onClick: handleAddFiles, disabled: isSubmitting, children: [_jsx(PlusIcon, { className: "size-3" }), "Add Files"] })] }), attachments.length > 0 && (_jsx("div", { className: "flex flex-col gap-2", children: attachments.map((file) => (_jsx(AttachmentCard, { file: file, onRemove: () => handleRemoveFile(file.path), disabled: isSubmitting }, file.path))) }))] })] }) }) }));
|
|
116
|
+
return (_jsx(BaseDrawer, { open: open, onClose: attemptClose, size: "md", modal: false, dismissOnOutsideClick: true, "data-testid": "feature-create-drawer", header: _jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-2.5 w-2.5 shrink-0 rounded-full bg-blue-500" }), _jsx(DrawerTitle, { children: "NEW FEATURE" })] }), isSubmitting ? (_jsx(DrawerDescription, { asChild: true, children: _jsx("div", { children: _jsx(Badge, { variant: "secondary", children: "Creating..." }) }) })) : null] }), footer: _jsxs("div", { className: "flex flex-row justify-end gap-2", children: [_jsx(Button, { variant: "outline", onClick: attemptClose, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { type: "submit", form: "create-feature-form", disabled: !description.trim() || isSubmitting, children: isSubmitting ? 'Creating...' : '+ Create Feature' })] }), children: _jsx("div", { className: "overflow-y-auto p-4", children: _jsxs("form", { id: "create-feature-form", onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-description", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "DESCRIBE YOUR FEATURE" }), _jsx(Textarea, { id: "feature-description", placeholder: "e.g. Add GitHub OAuth login with callback handling and token refresh...", value: description, onChange: (e) => setDescription(e.target.value), rows: 4, required: true, disabled: isSubmitting })] }), hasFeatures ? (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "parent-feature", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "PARENT FEATURE" }), _jsx(ParentFeatureCombobox, { features: features, value: parentId, onChange: setParentId, disabled: isSubmitting })] })) : null, _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "MODE" }), _jsx(CheckboxGroupItem, { id: "fast-mode", label: "Fast Mode", description: "Skip SDLC phases and implement directly from your prompt.", checked: fast, onCheckedChange: setFast, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "APPROVE" }), _jsx(CheckboxGroup, { label: "Autonomous Mode", description: "YOLO!", parentAriaLabel: "Auto approve all", options: AUTO_APPROVE_OPTIONS, value: approvalGates, onValueChange: setApprovalGates, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "GIT" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(CheckboxGroupItem, { id: "push", label: "Push", description: "Push branch to remote after implementation.", checked: push || openPr, onCheckedChange: setPush, disabled: openPr || isSubmitting }), _jsx(CheckboxGroupItem, { id: "open-pr", label: "Create PR", description: "Open a pull request after pushing.", checked: openPr, onCheckedChange: setOpenPr, disabled: isSubmitting })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: ["ATTACHMENTS", attachments.length > 0 && (_jsxs("span", { className: "text-muted-foreground/60 ml-1.5", children: ["(", attachments.length, ")"] }))] }), _jsxs(Button, { type: "button", variant: "outline", size: "xs", onClick: handleAddFiles, disabled: isSubmitting, children: [_jsx(PlusIcon, { className: "size-3" }), "Add Files"] })] }), attachments.length > 0 && (_jsx("div", { className: "flex flex-col gap-2", children: attachments.map((file) => (_jsx(AttachmentCard, { file: file, onRemove: () => handleRemoveFile(file.path), disabled: isSubmitting }, file.path))) }))] })] }) }) }));
|
|
113
117
|
}
|
|
114
118
|
function ParentFeatureCombobox({ features, value, onChange, disabled, }) {
|
|
115
119
|
const [open, setOpen] = useState(false);
|
|
@@ -77,6 +77,24 @@ export declare const PushOnly: Story;
|
|
|
77
77
|
* checked, but "Push" is non-interactive (disabled).
|
|
78
78
|
*/
|
|
79
79
|
export declare const PrChecked: Story;
|
|
80
|
+
/**
|
|
81
|
+
* Fast Mode off (default) — the "Fast Mode" checkbox in the MODE section
|
|
82
|
+
* is unchecked. The full SDLC pipeline (analyze, requirements, research,
|
|
83
|
+
* plan, implement) will run.
|
|
84
|
+
*/
|
|
85
|
+
export declare const FastModeOff: Story;
|
|
86
|
+
/**
|
|
87
|
+
* Fast Mode on — the "Fast Mode" checkbox is checked. When submitted,
|
|
88
|
+
* `fast: true` is included in the payload, skipping SDLC phases and
|
|
89
|
+
* implementing directly from the user's prompt.
|
|
90
|
+
*/
|
|
91
|
+
export declare const FastModeOn: Story;
|
|
92
|
+
/**
|
|
93
|
+
* Fast Mode combined with approval gates and git options — demonstrates
|
|
94
|
+
* that fast mode works alongside other form controls. Here fast mode,
|
|
95
|
+
* auto-approve all, push, and create PR are all enabled.
|
|
96
|
+
*/
|
|
97
|
+
export declare const FastModeWithOptions: Story;
|
|
80
98
|
/**
|
|
81
99
|
* Drawer pre-populated from workflow settings — PRD and Plan approval gates
|
|
82
100
|
* are checked, Push and Create PR are enabled. These values come from
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-create-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAU9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,mBAAmB,CAgC1C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAiDlD,uFAAuF;AACvF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAiBvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAMhC,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,KAUxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,KAUrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAUvB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,KAUvB,CAAC;AAYF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAWlC,CAAC;AAgDF,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAgBjC,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,KAsCzB,CAAC"}
|
|
1
|
+
{"version":3,"file":"feature-create-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAU9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,mBAAmB,CAgC1C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAiDlD,uFAAuF;AACvF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAiBvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAMhC,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,KAUxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,KAUrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAUvB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,KAUvB,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,KAMzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,KAUxB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAgBjC,CAAC;AAYF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAWlC,CAAC;AAgDF,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAgBjC,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,KAsCzB,CAAC"}
|
|
@@ -212,6 +212,55 @@ export const PrChecked = {
|
|
|
212
212
|
await userEvent.click(prCheckbox);
|
|
213
213
|
},
|
|
214
214
|
};
|
|
215
|
+
/* ---------------------------------------------------------------------------
|
|
216
|
+
* Fast mode stories
|
|
217
|
+
* ------------------------------------------------------------------------- */
|
|
218
|
+
/**
|
|
219
|
+
* Fast Mode off (default) — the "Fast Mode" checkbox in the MODE section
|
|
220
|
+
* is unchecked. The full SDLC pipeline (analyze, requirements, research,
|
|
221
|
+
* plan, implement) will run.
|
|
222
|
+
*/
|
|
223
|
+
export const FastModeOff = {
|
|
224
|
+
render: () => _jsx(CreateDrawerTrigger, { label: "Open (Fast Mode Off)" }),
|
|
225
|
+
play: async ({ canvasElement }) => {
|
|
226
|
+
const canvas = within(canvasElement);
|
|
227
|
+
await userEvent.click(canvas.getByRole('button', { name: 'Open (Fast Mode Off)' }));
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Fast Mode on — the "Fast Mode" checkbox is checked. When submitted,
|
|
232
|
+
* `fast: true` is included in the payload, skipping SDLC phases and
|
|
233
|
+
* implementing directly from the user's prompt.
|
|
234
|
+
*/
|
|
235
|
+
export const FastModeOn = {
|
|
236
|
+
render: () => _jsx(CreateDrawerTrigger, { label: "Open (Fast Mode On)" }),
|
|
237
|
+
play: async ({ canvasElement }) => {
|
|
238
|
+
const canvas = within(canvasElement);
|
|
239
|
+
await userEvent.click(canvas.getByRole('button', { name: 'Open (Fast Mode On)' }));
|
|
240
|
+
const body = within(canvasElement.ownerDocument.body);
|
|
241
|
+
const fastCheckbox = await body.findByLabelText('Fast Mode');
|
|
242
|
+
await userEvent.click(fastCheckbox);
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* Fast Mode combined with approval gates and git options — demonstrates
|
|
247
|
+
* that fast mode works alongside other form controls. Here fast mode,
|
|
248
|
+
* auto-approve all, push, and create PR are all enabled.
|
|
249
|
+
*/
|
|
250
|
+
export const FastModeWithOptions = {
|
|
251
|
+
render: () => _jsx(CreateDrawerTrigger, { label: "Open (Fast + Options)" }),
|
|
252
|
+
play: async ({ canvasElement }) => {
|
|
253
|
+
const canvas = within(canvasElement);
|
|
254
|
+
await userEvent.click(canvas.getByRole('button', { name: 'Open (Fast + Options)' }));
|
|
255
|
+
const body = within(canvasElement.ownerDocument.body);
|
|
256
|
+
const fastCheckbox = await body.findByLabelText('Fast Mode');
|
|
257
|
+
await userEvent.click(fastCheckbox);
|
|
258
|
+
const autoApprove = body.getByLabelText('Auto approve all');
|
|
259
|
+
await userEvent.click(autoApprove);
|
|
260
|
+
const prCheckbox = body.getByLabelText('Create PR');
|
|
261
|
+
await userEvent.click(prCheckbox);
|
|
262
|
+
},
|
|
263
|
+
};
|
|
215
264
|
/* ---------------------------------------------------------------------------
|
|
216
265
|
* Workflow defaults stories
|
|
217
266
|
* ------------------------------------------------------------------------- */
|
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":"AAIA,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":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAsB5E,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,2CAuQzF"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { useCallback, useEffect, useMemo } from 'react';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import { useRouter, usePathname } from 'next/navigation';
|
|
5
|
+
import { useReactFlow } from '@xyflow/react';
|
|
5
6
|
import { FeaturesCanvas } from '../../features/features-canvas/index.js';
|
|
6
7
|
import { useSidebarFeaturesContext, mapNodeStateToSidebarStatus, } from '../../../hooks/sidebar-features-context.js';
|
|
7
8
|
import { useSelectedFeatureId } from '../../../hooks/use-selected-feature-id.js';
|
|
@@ -10,12 +11,20 @@ import { useDrawerCloseGuard } from '../../../hooks/drawer-close-guard.js';
|
|
|
10
11
|
import { useViewportPersistence } from '../../../hooks/use-viewport-persistence.js';
|
|
11
12
|
import { ControlCenterEmptyState } from './control-center-empty-state.js';
|
|
12
13
|
import { useControlCenterState } from './use-control-center-state.js';
|
|
14
|
+
const AUTO_FOCUS_OPTIONS = {
|
|
15
|
+
maxZoom: 1.0,
|
|
16
|
+
padding: 0.5,
|
|
17
|
+
duration: 500,
|
|
18
|
+
};
|
|
19
|
+
const AUTO_FOCUS_DRAWER_DELAY_MS = 600;
|
|
13
20
|
export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
14
21
|
const router = useRouter();
|
|
15
22
|
const pathname = usePathname();
|
|
16
23
|
const selectedFeatureId = useSelectedFeatureId();
|
|
17
24
|
const clickSound = useSoundAction('click');
|
|
18
25
|
const { guardedNavigate } = useDrawerCloseGuard();
|
|
26
|
+
const { fitView } = useReactFlow();
|
|
27
|
+
const drawerTimerRef = useRef(null);
|
|
19
28
|
const { defaultViewport, onMoveEnd: handleViewportChange, resetViewport, } = useViewportPersistence();
|
|
20
29
|
const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleDeleteRepository, createFeatureNode, setCallbacks, } = useControlCenterState(initialNodes, initialEdges);
|
|
21
30
|
// Publish sidebar features to context whenever feature node data changes
|
|
@@ -107,11 +116,26 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
107
116
|
useEffect(() => {
|
|
108
117
|
const handler = (e) => {
|
|
109
118
|
const path = e.detail.path;
|
|
110
|
-
handleAddRepository(path);
|
|
119
|
+
const { wasEmpty, repoPath } = handleAddRepository(path);
|
|
120
|
+
if (wasEmpty) {
|
|
121
|
+
// Wait for next render so the repo node exists in the DOM, then auto-focus
|
|
122
|
+
setTimeout(() => {
|
|
123
|
+
fitView(AUTO_FOCUS_OPTIONS);
|
|
124
|
+
// Open the create-feature drawer after the fitView animation completes
|
|
125
|
+
drawerTimerRef.current = setTimeout(() => {
|
|
126
|
+
guardedNavigate(() => router.push(`/create?repo=${encodeURIComponent(repoPath)}`));
|
|
127
|
+
}, AUTO_FOCUS_DRAWER_DELAY_MS);
|
|
128
|
+
}, 0);
|
|
129
|
+
}
|
|
111
130
|
};
|
|
112
131
|
window.addEventListener('shep:add-repository', handler);
|
|
113
|
-
return () =>
|
|
114
|
-
|
|
132
|
+
return () => {
|
|
133
|
+
window.removeEventListener('shep:add-repository', handler);
|
|
134
|
+
if (drawerTimerRef.current != null) {
|
|
135
|
+
clearTimeout(drawerTimerRef.current);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}, [handleAddRepository, fitView, guardedNavigate, router]);
|
|
115
139
|
// Listen for create events from the create drawer (with real feature ID from server)
|
|
116
140
|
useEffect(() => {
|
|
117
141
|
const handler = (e) => {
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts
CHANGED
|
@@ -9,7 +9,10 @@ export interface ControlCenterState {
|
|
|
9
9
|
edges: Edge[];
|
|
10
10
|
onNodesChange: (changes: NodeChange<CanvasNodeType>[]) => void;
|
|
11
11
|
handleConnect: (connection: Connection) => void;
|
|
12
|
-
handleAddRepository: (path: string) =>
|
|
12
|
+
handleAddRepository: (path: string) => {
|
|
13
|
+
wasEmpty: boolean;
|
|
14
|
+
repoPath: string;
|
|
15
|
+
};
|
|
13
16
|
handleLayout: (direction: LayoutDirection) => void;
|
|
14
17
|
handleDeleteFeature: (featureId: string) => void;
|
|
15
18
|
handleDeleteRepository: (repositoryId: string) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAcjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAcjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/E,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;IACZ,wDAAwD;IACxD,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAQD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CAuXpB"}
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js
CHANGED
|
@@ -18,11 +18,12 @@ const POLL_INTERVAL_MS = 3_000;
|
|
|
18
18
|
/** Must match the message string emitted by the SSE route in agent-events/route.ts */
|
|
19
19
|
const METADATA_UPDATED_MESSAGE = 'Feature metadata updated';
|
|
20
20
|
let nextFeatureId = 0;
|
|
21
|
+
let nextRepoTempId = 0;
|
|
21
22
|
export function useControlCenterState(initialNodes, initialEdges) {
|
|
22
23
|
const router = useRouter();
|
|
23
24
|
const deleteSound = useSoundAction('delete');
|
|
24
25
|
const createSound = useSoundAction('create');
|
|
25
|
-
const { nodes, edges, reconcile, updateFeature, addPendingFeature, removeFeature, restoreFeature, addRepository: addRepositoryToMap, removeRepository, replaceRepository, getFeatureRepositoryPath, getRepositoryData, setCallbacks, } = useGraphState(initialNodes, initialEdges);
|
|
26
|
+
const { nodes, edges, reconcile, updateFeature, addPendingFeature, removeFeature, restoreFeature, addRepository: addRepositoryToMap, removeRepository, replaceRepository, getFeatureRepositoryPath, getRepositoryData, getRepoMapSize, setCallbacks, } = useGraphState(initialNodes, initialEdges);
|
|
26
27
|
// Refs for stable access to latest nodes/edges without callback recreation
|
|
27
28
|
const nodesRef = useRef(nodes);
|
|
28
29
|
const edgesRef = useRef(edges);
|
|
@@ -274,7 +275,8 @@ export function useControlCenterState(initialNodes, initialEdges) {
|
|
|
274
275
|
reconcile(result.nodes, result.edges);
|
|
275
276
|
}, [reconcile]);
|
|
276
277
|
const handleAddRepository = useCallback((path) => {
|
|
277
|
-
const
|
|
278
|
+
const wasEmpty = getRepoMapSize() === 0;
|
|
279
|
+
const tempId = `repo-temp-${++nextRepoTempId}`;
|
|
278
280
|
const repoName = path
|
|
279
281
|
.replace(/[\\/]+$/, '')
|
|
280
282
|
.split(/[\\/]/)
|
|
@@ -300,7 +302,8 @@ export function useControlCenterState(initialNodes, initialEdges) {
|
|
|
300
302
|
removeRepository(tempId);
|
|
301
303
|
toast.error('Failed to add repository');
|
|
302
304
|
});
|
|
303
|
-
|
|
305
|
+
return { wasEmpty, repoPath: path };
|
|
306
|
+
}, [addRepositoryToMap, removeRepository, replaceRepository, createSound, getRepoMapSize]);
|
|
304
307
|
return {
|
|
305
308
|
nodes,
|
|
306
309
|
edges,
|
|
@@ -15,7 +15,7 @@ function ResetButton({ onResetViewport }) {
|
|
|
15
15
|
const viewport = onResetViewport();
|
|
16
16
|
setViewport(viewport, { duration: 400 });
|
|
17
17
|
}, [onResetViewport, setViewport]);
|
|
18
|
-
return (_jsx(ControlButton, { onClick: handleReset, title: "Reset view", "aria-label": "Reset view", children: _jsx(RotateCcw, {}) }));
|
|
18
|
+
return (_jsx(ControlButton, { onClick: handleReset, title: "Reset view", "aria-label": "Reset view", children: _jsx(RotateCcw, { style: { fill: 'none' } }) }));
|
|
19
19
|
}
|
|
20
20
|
export function FeaturesCanvas({ nodes, edges, selectedFeatureId, defaultViewport, onNodesChange, onAddFeature, onConnect, onNodeClick, onPaneClick, onCanvasDrag, onMoveEnd, onResetViewport, toolbar, emptyState, }) {
|
|
21
21
|
const nodeTypes = useMemo(() => ({
|
package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.d.ts
CHANGED
|
@@ -16,4 +16,5 @@ export declare const MultipleRepositoriesMixedConnections: Story;
|
|
|
16
16
|
export declare const InteractiveWithRepository: Story;
|
|
17
17
|
export declare const WithSavedViewport: Story;
|
|
18
18
|
export declare const ZoomedOutViewport: Story;
|
|
19
|
+
export declare const FastModeFeatures: Story;
|
|
19
20
|
//# 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;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"features-canvas.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOnD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAcrC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAwKnC,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAK3B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAK5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,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"}
|