@shepai/cli 1.66.3 → 1.67.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/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +26 -11
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +16 -10
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +21 -1
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts +15 -1
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.js +16 -2
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts +12 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.js +284 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.d.ts +33 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.js +210 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts +56 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.js +32 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/index.d.ts +3 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/index.js +2 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.d.ts +0 -4
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +18 -12
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.d.ts +4 -6
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.js +5 -13
- 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 +2 -13
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +2 -10
- 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 +21 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.js +14 -20
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.d.ts +7 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.js +37 -2
- package/dist/src/presentation/web/components/common/index.d.ts +1 -0
- package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/index.js +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review.js +2 -2
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.js +1 -2
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.js +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.js +1 -2
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.js +5 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts +2 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.js +13 -2
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.js +5 -2
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.stories.js +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.js +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.js +1 -2
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +20 -215
- 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 +2 -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/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +5 -5
- 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/_global-error/page/build-manifest.json +3 -3
- 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/build-manifest.json +3 -3
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- 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/page/build-manifest.json +3 -3
- package/web/.next/server/app/page/server-reference-manifest.json +88 -88
- package/web/.next/server/app/page.js +1 -1
- package/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/build-manifest.json +3 -3
- package/web/.next/server/app/skills/page/server-reference-manifest.json +5 -5
- 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/build-manifest.json +3 -3
- package/web/.next/server/app/tools/page/server-reference-manifest.json +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/build-manifest.json +3 -3
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- 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/ssr/403f9_next_dist_a53cb908._.js +3 -0
- package/web/.next/server/chunks/ssr/403f9_next_dist_a53cb908._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__f5830fa9._.js → [root-of-the-server]__2ffb27f1._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__f5830fa9._.js.map → [root-of-the-server]__2ffb27f1._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.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]__7f4180a1._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7f4180a1._.js.map +1 -0
- 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]__9add7c3a._.js +4 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e41b5eec._.js +9 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__f648005b._.js.map → [root-of-the-server]__e41b5eec._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__eaf6100f._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__eaf6100f._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_23c92688._.js +6 -0
- package/web/.next/server/chunks/ssr/_23c92688._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_28993370._.js +1 -1
- package/web/.next/server/chunks/ssr/_28993370._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_49bf495c._.js +3 -0
- package/web/.next/server/chunks/ssr/_49bf495c._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_690ea95f._.js +3 -0
- package/web/.next/server/chunks/ssr/{_2900ed94._.js.map → _690ea95f._.js.map} +1 -1
- package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/_c52cace8._.js → server/chunks/ssr/_725584e5._.js} +2 -2
- package/web/.next/server/chunks/ssr/_725584e5._.js.map +1 -0
- 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/middleware-build-manifest.js +3 -3
- 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 +115 -115
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +5 -5
- 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/_global-error/page/build-manifest.json +3 -3
- 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/build-manifest.json +3 -3
- 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.js.nft.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/page/build-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +88 -88
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/build-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +5 -5
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
- 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/build-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/build-manifest.json +3 -3
- 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.js.nft.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/403f9_next_dist_a53cb908._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{[root-of-the-server]__f5830fa9._.js → [root-of-the-server]__2ffb27f1._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.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]__7f4180a1._.js +3 -0
- 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]__9add7c3a._.js +4 -4
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__e41b5eec._.js +9 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__eaf6100f._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_23c92688._.js +6 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_28993370._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_49bf495c._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_690ea95f._.js +3 -0
- package/web/.next/{server/chunks/ssr/_c52cace8._.js → standalone/src/presentation/web/.next/server/chunks/ssr/_725584e5._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/middleware-build-manifest.js +3 -3
- 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 +115 -115
- package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.stories.tsx +16 -2
- package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx +35 -6
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.tsx +285 -0
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.tsx +650 -0
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/drawer-view.ts +82 -0
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/index.ts +2 -0
- package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.ts +0 -4
- package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.tsx +5 -14
- package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx +58 -51
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx +42 -1
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +2 -16
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/index.ts +1 -0
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.tsx +55 -2
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer/feature-drawer.tsx +97 -106
- package/web/.next/standalone/src/presentation/web/components/common/index.ts +6 -0
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.stories.tsx +1 -2
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.tsx +1 -2
- package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.tsx +1 -2
- package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.tsx +1 -1
- package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-drawer.stories.tsx +28 -2
- package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-drawer.tsx +7 -2
- package/web/.next/standalone/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.stories.tsx +1 -1
- package/web/.next/standalone/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.tsx +7 -6
- package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.tsx +1 -2
- package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.tsx +1 -2
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +30 -348
- package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +2 -1
- package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +5 -1
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/38ca82d1243738e3.js +1 -0
- package/web/.next/static/chunks/{35f41ba0a6d626d7.js → 491ae2bbae40857c.js} +1 -1
- package/web/.next/static/chunks/4b6cc9f65260f2bd.js +2 -0
- package/web/.next/static/chunks/67599679ca9ac863.js +1 -0
- package/web/.next/static/chunks/{ed887cce7b31c91b.js → 6ece250c7d0ec203.js} +1 -1
- package/web/.next/static/chunks/a186bbb822ccb655.css +2 -0
- package/web/.next/static/chunks/a5c59952485e875e.js +1 -0
- package/web/.next/static/chunks/{8c60d1bd87239066.js → a9626385607910b3.js} +1 -1
- package/web/.next/static/chunks/c1c15470a7b058c8.js +1 -0
- package/web/.next/static/chunks/caa2e7e1618e2179.js +1 -0
- package/web/.next/static/chunks/ed799a306922f03e.js +10 -0
- package/web/.next/static/chunks/fb703cf73aba2eb8.js +1 -0
- package/web/.next/static/chunks/{turbopack-b6b5b4f015327a9a.js → turbopack-958ac34b879d0dce.js} +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/server/chunks/ssr/403f9_next_dist_623b646a._.js +0 -3
- package/web/.next/server/chunks/ssr/403f9_next_dist_623b646a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb51fac._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb51fac._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c1f0f2a8._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c1f0f2a8._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f648005b._.js +0 -9
- package/web/.next/server/chunks/ssr/_2900ed94._.js +0 -3
- package/web/.next/server/chunks/ssr/_6978d868._.js +0 -3
- package/web/.next/server/chunks/ssr/_6978d868._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_85965278._.js +0 -6
- package/web/.next/server/chunks/ssr/_85965278._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_c52cace8._.js.map +0 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/403f9_next_dist_623b646a._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6bb51fac._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__c1f0f2a8._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__f648005b._.js +0 -9
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_2900ed94._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_6978d868._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_85965278._.js +0 -6
- package/web/.next/static/chunks/41a2adc09edfffaf.js +0 -1
- package/web/.next/static/chunks/5054c72b1c8f5912.js +0 -1
- package/web/.next/static/chunks/7bcbfc56e5733034.js +0 -1
- package/web/.next/static/chunks/86c0cc1097427f74.js +0 -10
- package/web/.next/static/chunks/96f49affaceab206.css +0 -2
- package/web/.next/static/chunks/a6d1d774260fc927.js +0 -2
- package/web/.next/static/chunks/c0f7284a71378f26.js +0 -1
- package/web/.next/static/chunks/f5fb2f182ae9b015.js +0 -1
- /package/web/.next/static/{Cp8hg2DFpA4DyEezlBYOw → GdqfiIUVMj2wj_3lbrUqd}/_buildManifest.js +0 -0
- /package/web/.next/static/{Cp8hg2DFpA4DyEezlBYOw → GdqfiIUVMj2wj_3lbrUqd}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{Cp8hg2DFpA4DyEezlBYOw → GdqfiIUVMj2wj_3lbrUqd}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACd,MAAM,iEAAiE,CAAC;AAsBzE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1E,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;IACnE;;;OAGG;IACH,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1F,YAAY,EAAE,aAAa,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAGnC,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"merge.node.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+DAA+D,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yEAAyE,CAAC;AAClH,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACd,MAAM,iEAAiE,CAAC;AAsBzE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1E,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;IACnE;;;OAGG;IACH,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1F,YAAY,EAAE,aAAa,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,IAGnC,OAAO,iBAAiB,KAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAiP7E"}
|
|
@@ -147,31 +147,46 @@ export function createMergeNode(deps) {
|
|
|
147
147
|
else {
|
|
148
148
|
log.info('Merge approved — skipping commit/push/PR, continuing to post-merge');
|
|
149
149
|
messages.push(`[merge] Approved — continuing`);
|
|
150
|
+
// Restore PR data from feature record (persisted before interrupt, but
|
|
151
|
+
// not returned in graph state because interrupt() threw before the return).
|
|
152
|
+
if (feature?.pr) {
|
|
153
|
+
prUrl = feature.pr.url ?? prUrl;
|
|
154
|
+
prNumber = feature.pr.number ?? prNumber;
|
|
155
|
+
commitHash = feature.pr.commitHash ?? commitHash;
|
|
156
|
+
ciStatus = feature.pr.ciStatus ?? ciStatus;
|
|
157
|
+
}
|
|
150
158
|
}
|
|
151
|
-
// ---
|
|
159
|
+
// --- Merge ---
|
|
152
160
|
// Merge when: allowMerge is true (auto-merge), OR user explicitly
|
|
153
161
|
// approved at the merge gate (isResumeAfterInterrupt means they
|
|
154
162
|
// clicked Approve). The approval IS permission to merge.
|
|
155
163
|
let merged = false;
|
|
156
164
|
const userApprovedMerge = isResumeAfterInterrupt && state._approvalAction !== 'rejected';
|
|
157
165
|
if (state.approvalGates?.allowMerge || userApprovedMerge) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
+
if (prUrl && prNumber) {
|
|
167
|
+
// PR exists: merge via GitHub API directly — no agent or local merge needed.
|
|
168
|
+
log.info(`Merging PR #${prNumber} via GitHub API (squash)`);
|
|
169
|
+
await deps.gitPrService.mergePr(cwd, prNumber, 'squash');
|
|
170
|
+
messages.push(`[merge] PR #${prNumber} merged via squash`);
|
|
171
|
+
merged = true;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// No PR: local merge via agent in the ORIGINAL repo (not the worktree,
|
|
175
|
+
// which IS the feature branch and must not be modified during merge).
|
|
176
|
+
log.info('Agent call: merge/squash (local, no PR)');
|
|
177
|
+
const mergePrompt = buildMergeSquashPrompt({ ...state, prUrl, prNumber, commitHash }, branch, baseBranch, remoteAvailable);
|
|
178
|
+
const mergeOptions = { ...options, cwd: state.repositoryPath };
|
|
179
|
+
await retryExecute(executor, mergePrompt, mergeOptions, { logger: log });
|
|
180
|
+
// Verify the merge actually succeeded (agent may report success without merging)
|
|
166
181
|
const mergeVerified = await deps.verifyMerge(state.repositoryPath, branch, baseBranch);
|
|
167
182
|
if (!mergeVerified) {
|
|
168
183
|
throw new Error(`Merge verification failed: ${branch} was not merged into ${baseBranch}. ` +
|
|
169
184
|
`The agent may have encountered errors during the merge operation.`);
|
|
170
185
|
}
|
|
171
186
|
log.info('Merge verified: feature branch is ancestor of base branch');
|
|
187
|
+
messages.push(`[merge] Agent completed local merge operation`);
|
|
188
|
+
merged = true;
|
|
172
189
|
}
|
|
173
|
-
messages.push(`[merge] Agent completed merge operation`);
|
|
174
|
-
merged = true;
|
|
175
190
|
}
|
|
176
191
|
// --- Update feature lifecycle ---
|
|
177
192
|
const newLifecycle = merged ? SdlcLifecycle.Maintain : SdlcLifecycle.Review;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-pr.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-pr.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAC5G,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,YAAY,EACb,MAAM,wEAAwE,CAAC;AAQhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,qBACa,YAAa,YAAW,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgF9C,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvE,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAuClE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,aAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"git-pr.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-pr.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wEAAwE,CAAC;AAC5G,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,YAAY,EACb,MAAM,wEAAwE,CAAC;AAQhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,qBACa,YAAa,YAAW,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgF9C,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvE,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAuClE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,aAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAsBjE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAmDjF,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhF,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAevE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAkCpD,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWrF,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAW3F,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,aAAa;CAiBtB"}
|
|
@@ -182,15 +182,20 @@ let GitPrService = class GitPrService {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
async getCiStatus(cwd, branch) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
185
|
+
try {
|
|
186
|
+
const { stdout } = await this.execFile('gh', ['run', 'list', '--branch', branch, '--json', 'conclusion,url', '--limit', '1'], { cwd });
|
|
187
|
+
const runs = JSON.parse(stdout);
|
|
188
|
+
if (runs.length === 0 || !runs[0].conclusion) {
|
|
189
|
+
return { status: 'pending', runUrl: runs[0]?.url };
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
status: runs[0].conclusion === 'success' ? 'success' : 'failure',
|
|
193
|
+
runUrl: runs[0].url,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
throw this.parseGhError(error);
|
|
189
198
|
}
|
|
190
|
-
return {
|
|
191
|
-
status: runs[0].conclusion === 'success' ? 'success' : 'failure',
|
|
192
|
-
runUrl: runs[0].url,
|
|
193
|
-
};
|
|
194
199
|
}
|
|
195
200
|
async watchCi(cwd, branch, timeoutMs) {
|
|
196
201
|
try {
|
|
@@ -207,9 +212,10 @@ let GitPrService = class GitPrService {
|
|
|
207
212
|
cwd,
|
|
208
213
|
...(timeoutMs ? { timeout: timeoutMs } : {}),
|
|
209
214
|
});
|
|
210
|
-
|
|
215
|
+
// gh run watch --exit-status exits 0 when the run succeeds.
|
|
216
|
+
// If we reach here (no exception), CI passed — no need for fragile stdout parsing.
|
|
211
217
|
return {
|
|
212
|
-
status:
|
|
218
|
+
status: 'success',
|
|
213
219
|
logExcerpt: stdout.trim(),
|
|
214
220
|
};
|
|
215
221
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/base-drawer/base-drawer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"base-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/base-drawer/base-drawer.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAalE,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAGpF,QAAA,MAAM,cAAc;;8EAUlB,CAAC;AAEH,MAAM,WAAW,eAAgB,SAAQ,YAAY,CAAC,OAAO,cAAc,CAAC;IAC1E,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,OAAO,EACP,KAAa,EACb,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,MAAM,EACN,SAAS,EACT,aAAa,EAAE,MAAM,EACrB,YAAY,GACb,EAAE,eAAe,2CAyEjB"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRef, useEffect } from 'react';
|
|
3
4
|
import { XIcon, Play, Square } from 'lucide-react';
|
|
4
5
|
import { cva } from 'class-variance-authority';
|
|
5
6
|
import { cn } from '../../../lib/utils.js';
|
|
6
7
|
import { ActionButton } from '../../common/action-button/index.js';
|
|
7
8
|
import { DeploymentStatusBadge } from '../../common/deployment-status-badge/index.js';
|
|
8
9
|
import { Drawer, DrawerContent, DrawerHeader, DrawerFooter, DrawerOverlay, } from '../../ui/drawer.js';
|
|
10
|
+
import { Separator } from '../../ui/separator.js';
|
|
9
11
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
|
|
10
12
|
import { useDeployAction } from '../../../hooks/use-deploy-action.js';
|
|
11
13
|
import { featureFlags } from '../../../lib/feature-flags.js';
|
|
@@ -21,10 +23,28 @@ const drawerVariants = cva('', {
|
|
|
21
23
|
},
|
|
22
24
|
});
|
|
23
25
|
export function BaseDrawer({ open, onClose, modal = false, size, header, children, footer, className, 'data-testid': testId, deployTarget, }) {
|
|
26
|
+
const contentRef = useRef(null);
|
|
27
|
+
// Close when clicking outside the drawer panel (no overlay needed — canvas stays draggable).
|
|
28
|
+
// Uses `click` (not `pointerdown`) so canvas drags don't trigger this.
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!open || modal)
|
|
31
|
+
return;
|
|
32
|
+
const handleClick = (e) => {
|
|
33
|
+
const target = e.target;
|
|
34
|
+
if (contentRef.current?.contains(target))
|
|
35
|
+
return;
|
|
36
|
+
// Don't close when clicking inside the canvas or other Radix overlays
|
|
37
|
+
if (target.closest('[data-no-drawer-close], [role="alertdialog"], [role="menu"], [role="listbox"], [data-radix-popper-content-wrapper]'))
|
|
38
|
+
return;
|
|
39
|
+
onClose();
|
|
40
|
+
};
|
|
41
|
+
document.addEventListener('click', handleClick);
|
|
42
|
+
return () => document.removeEventListener('click', handleClick);
|
|
43
|
+
}, [open, modal, onClose]);
|
|
24
44
|
return (_jsxs(Drawer, { direction: "right", modal: modal, handleOnly: true, open: open, onOpenChange: (isOpen) => {
|
|
25
45
|
if (!isOpen)
|
|
26
46
|
onClose();
|
|
27
|
-
}, children: [modal ? _jsx(DrawerOverlay, {}) : null, _jsxs(DrawerContent, { direction: "right", showCloseButton: false, className: cn(drawerVariants({ size }), className), "data-testid": testId, children: [_jsxs("button", { type: "button", "aria-label": "Close", onClick: onClose, className: "ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden", "data-testid": testId ? `${testId}-close-button` : undefined, children: [_jsx(XIcon, { className: "size-4" }), _jsx("span", { className: "sr-only", children: "Close" })] }), header ? _jsx(DrawerHeader, { children: header }) : null, featureFlags.envDeploy && deployTarget ? _jsx(DeployBar, { deployTarget: deployTarget }) : null, _jsx("div", { className: "flex
|
|
47
|
+
}, children: [modal ? _jsx(DrawerOverlay, {}) : null, _jsxs(DrawerContent, { ref: contentRef, direction: "right", showCloseButton: false, className: cn(drawerVariants({ size }), className), "data-testid": testId, children: [_jsxs("button", { type: "button", "aria-label": "Close", onClick: onClose, className: "ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden", "data-testid": testId ? `${testId}-close-button` : undefined, children: [_jsx(XIcon, { className: "size-4" }), _jsx("span", { className: "sr-only", children: "Close" })] }), header ? _jsx(DrawerHeader, { className: "shrink-0", children: header }) : null, header ? _jsx(Separator, {}) : null, featureFlags.envDeploy && deployTarget ? _jsx(DeployBar, { deployTarget: deployTarget }) : null, _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: children }), footer ? _jsx(DrawerFooter, { className: "shrink-0", children: footer }) : null] })] }));
|
|
28
48
|
}
|
|
29
49
|
function DeployBar({ deployTarget }) {
|
|
30
50
|
const deployAction = useDeployAction(deployTarget);
|
|
@@ -19,6 +19,20 @@ export declare const WithFooter: Story;
|
|
|
19
19
|
export declare const WithHeaderAndFooter: Story;
|
|
20
20
|
/** Drawer with deployTarget prop showing the dev server bar below the header. */
|
|
21
21
|
export declare const WithDevServerBar: Story;
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Drawer with content that exceeds viewport to demonstrate scroll behavior.
|
|
24
|
+
*
|
|
25
|
+
* **Fixed Header/Footer Layout:**
|
|
26
|
+
* - The header (DrawerTitle + DrawerDescription) remains fixed at the top while scrolling
|
|
27
|
+
* - A Separator is automatically rendered below the header — no need to add one manually
|
|
28
|
+
* - The footer (if present, e.g., DrawerActionBar) remains fixed at the bottom while scrolling
|
|
29
|
+
* - Only the content area (children) scrolls when drawer content exceeds available height
|
|
30
|
+
*
|
|
31
|
+
* **Spacing Conventions:**
|
|
32
|
+
* - Content consumers should add `p-4` padding for consistent spacing (as shown in this example)
|
|
33
|
+
* - Footer components like DrawerActionBar should use `border-t` for visual separation
|
|
34
|
+
*
|
|
35
|
+
* Try scrolling the content below to see the fixed header behavior.
|
|
36
|
+
*/
|
|
23
37
|
export declare const ScrollableContent: Story;
|
|
24
38
|
//# sourceMappingURL=base-drawer.stories.d.ts.map
|
package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/base-drawer/base-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI3C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,CAOjC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,UAAU,CAAC,CAAC;AAuBzC,6DAA6D;AAC7D,eAAO,MAAM,OAAO,EAAE,KAQrB,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,SAAS,EAAE,KAkBvB,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,UAAU,EAAE,KAiBxB,CAAC;AAEF,iCAAiC;AACjC,eAAO,MAAM,KAAK,EAAE,KAUnB,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,UAAU,EAAE,KAexB,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,UAAU,EAAE,KAiBxB,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB,EAAE,KAsCjC,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,EAAE,KAuB9B,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"base-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/base-drawer/base-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI3C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,CAOjC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,UAAU,CAAC,CAAC;AAuBzC,6DAA6D;AAC7D,eAAO,MAAM,OAAO,EAAE,KAQrB,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,SAAS,EAAE,KAkBvB,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,UAAU,EAAE,KAiBxB,CAAC;AAEF,iCAAiC;AACjC,eAAO,MAAM,KAAK,EAAE,KAUnB,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,UAAU,EAAE,KAexB,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,UAAU,EAAE,KAiBxB,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB,EAAE,KAsCjC,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,EAAE,KAuB9B,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAsB/B,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { BaseDrawer } from './base-drawer.js';
|
|
|
4
4
|
import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
|
|
5
5
|
import { Button } from '../../ui/button.js';
|
|
6
6
|
const meta = {
|
|
7
|
-
title: '
|
|
7
|
+
title: 'Drawers/Base/BaseDrawer',
|
|
8
8
|
component: BaseDrawer,
|
|
9
9
|
tags: ['autodocs'],
|
|
10
10
|
parameters: {
|
|
@@ -59,7 +59,21 @@ export const WithDevServerBar = {
|
|
|
59
59
|
branch: 'feat/auth-module',
|
|
60
60
|
}, children: _jsx("div", { className: "p-4", children: _jsx("p", { className: "text-muted-foreground text-sm", children: "The deploy bar appears between the header and this content." }) }) })),
|
|
61
61
|
};
|
|
62
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Drawer with content that exceeds viewport to demonstrate scroll behavior.
|
|
64
|
+
*
|
|
65
|
+
* **Fixed Header/Footer Layout:**
|
|
66
|
+
* - The header (DrawerTitle + DrawerDescription) remains fixed at the top while scrolling
|
|
67
|
+
* - A Separator is automatically rendered below the header — no need to add one manually
|
|
68
|
+
* - The footer (if present, e.g., DrawerActionBar) remains fixed at the bottom while scrolling
|
|
69
|
+
* - Only the content area (children) scrolls when drawer content exceeds available height
|
|
70
|
+
*
|
|
71
|
+
* **Spacing Conventions:**
|
|
72
|
+
* - Content consumers should add `p-4` padding for consistent spacing (as shown in this example)
|
|
73
|
+
* - Footer components like DrawerActionBar should use `border-t` for visual separation
|
|
74
|
+
*
|
|
75
|
+
* Try scrolling the content below to see the fixed header behavior.
|
|
76
|
+
*/
|
|
63
77
|
export const ScrollableContent = {
|
|
64
78
|
render: () => (_jsx(DrawerTrigger, { header: _jsxs(_Fragment, { children: [_jsx(DrawerTitle, { children: "Scrollable Content" }), _jsx(DrawerDescription, { children: "Content below overflows and scrolls" })] }), children: _jsx("div", { className: "flex flex-col gap-4 p-4", children: Array.from({ length: 30 }, (_, i) => (_jsxs("div", { className: "border-border rounded-md border p-3", children: [_jsxs("h4", { className: "text-sm font-medium", children: ["Item ", i + 1] }), _jsx("p", { className: "text-muted-foreground text-xs", children: "This is a scrollable content item to demonstrate overflow handling." })] }, i))) }) })),
|
|
65
79
|
};
|
package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FeatureCreatePayload } from '../../common/feature-create-drawer/index.js';
|
|
2
|
+
import type { DrawerView } from './drawer-view.js';
|
|
3
|
+
export interface ControlCenterDrawerProps {
|
|
4
|
+
view: DrawerView | null;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
onDelete?: (featureId: string) => void;
|
|
7
|
+
isDeleting?: boolean;
|
|
8
|
+
onCreateSubmit: (data: FeatureCreatePayload) => void;
|
|
9
|
+
isSubmitting?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function ControlCenterDrawer({ view, onClose, onDelete, isDeleting, onCreateSubmit, isSubmitting, }: ControlCenterDrawerProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=control-center-drawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-center-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/control-center-drawer.tsx"],"names":[],"mappings":"AAwDA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,UAAU,EACV,cAAc,EACd,YAAY,GACb,EAAE,wBAAwB,2CAke1B"}
|
package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.js
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
4
|
+
import { toast } from 'sonner';
|
|
5
|
+
import { Loader2, Trash2, ExternalLink, GitCommitHorizontal, Code2, Terminal, FolderOpen, } from 'lucide-react';
|
|
6
|
+
import { PrStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
|
|
7
|
+
import { approveFeature } from '../../../app/actions/approve-feature.js';
|
|
8
|
+
import { rejectFeature } from '../../../app/actions/reject-feature.js';
|
|
9
|
+
import { getFeatureArtifact } from '../../../app/actions/get-feature-artifact.js';
|
|
10
|
+
import { getResearchArtifact } from '../../../app/actions/get-research-artifact.js';
|
|
11
|
+
import { getMergeReviewData } from '../../../app/actions/get-merge-review-data.js';
|
|
12
|
+
import { cn } from '../../../lib/utils.js';
|
|
13
|
+
import { useSoundAction } from '../../../hooks/use-sound-action.js';
|
|
14
|
+
import { BaseDrawer } from '../../common/base-drawer/index.js';
|
|
15
|
+
import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
|
|
16
|
+
import { Button } from '../../ui/button.js';
|
|
17
|
+
import { Badge } from '../../ui/badge.js';
|
|
18
|
+
import { Separator } from '../../ui/separator.js';
|
|
19
|
+
import { CometSpinner } from '../../ui/comet-spinner.js';
|
|
20
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from '../../ui/alert-dialog.js';
|
|
21
|
+
import { CiStatusBadge } from '../../common/ci-status-badge/index.js';
|
|
22
|
+
import { ActionButton } from '../../common/action-button/index.js';
|
|
23
|
+
import { OpenActionMenu } from '../../common/open-action-menu/index.js';
|
|
24
|
+
import { FeatureCreateDrawer } from '../../common/feature-create-drawer/index.js';
|
|
25
|
+
import { PrdQuestionnaire } from '../../common/prd-questionnaire/index.js';
|
|
26
|
+
import { TechDecisionsReview } from '../../common/tech-decisions-review/index.js';
|
|
27
|
+
import { MergeReview } from '../../common/merge-review/index.js';
|
|
28
|
+
import { featureNodeStateConfig, lifecycleDisplayLabels } from '../../common/feature-node/index.js';
|
|
29
|
+
import { useFeatureActions } from '../../common/feature-drawer/use-feature-actions.js';
|
|
30
|
+
import { useRepositoryActions } from '../../common/repository-node/use-repository-actions.js';
|
|
31
|
+
export function ControlCenterDrawer({ view, onClose, onDelete, isDeleting, onCreateSubmit, isSubmitting, }) {
|
|
32
|
+
// ── PRD questionnaire state ─────────────────────────────────────────────
|
|
33
|
+
const [prdData, setPrdData] = useState(null);
|
|
34
|
+
const [prdSelections, setPrdSelections] = useState({});
|
|
35
|
+
const [isLoadingPrd, setIsLoadingPrd] = useState(false);
|
|
36
|
+
// ── Tech decisions state ────────────────────────────────────────────────
|
|
37
|
+
const [techData, setTechData] = useState(null);
|
|
38
|
+
const [isLoadingTech, setIsLoadingTech] = useState(false);
|
|
39
|
+
// ── Merge review state ──────────────────────────────────────────────────
|
|
40
|
+
const [mergeData, setMergeData] = useState(null);
|
|
41
|
+
const [isLoadingMerge, setIsLoadingMerge] = useState(false);
|
|
42
|
+
// ── Shared reject state ─────────────────────────────────────────────────
|
|
43
|
+
const [isRejecting, setIsRejecting] = useState(false);
|
|
44
|
+
const rejectSound = useSoundAction('reject');
|
|
45
|
+
// ── Data fetching ───────────────────────────────────────────────────────
|
|
46
|
+
const prdFeatureId = view?.type === 'prd-review' ? view.node.featureId : null;
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
setPrdSelections({});
|
|
49
|
+
setPrdData(null);
|
|
50
|
+
if (!prdFeatureId)
|
|
51
|
+
return;
|
|
52
|
+
let cancelled = false;
|
|
53
|
+
setIsLoadingPrd(true);
|
|
54
|
+
getFeatureArtifact(prdFeatureId)
|
|
55
|
+
.then((result) => {
|
|
56
|
+
if (cancelled)
|
|
57
|
+
return;
|
|
58
|
+
if (result.error) {
|
|
59
|
+
toast.error(result.error);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (result.questionnaire) {
|
|
63
|
+
setPrdData(result.questionnaire);
|
|
64
|
+
const defaults = {};
|
|
65
|
+
for (const q of result.questionnaire.questions) {
|
|
66
|
+
const recommended = q.options.find((o) => o.recommended);
|
|
67
|
+
if (recommended)
|
|
68
|
+
defaults[q.id] = recommended.id;
|
|
69
|
+
}
|
|
70
|
+
setPrdSelections(defaults);
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
.catch(() => {
|
|
74
|
+
if (!cancelled)
|
|
75
|
+
toast.error('Failed to load questionnaire');
|
|
76
|
+
})
|
|
77
|
+
.finally(() => {
|
|
78
|
+
if (!cancelled)
|
|
79
|
+
setIsLoadingPrd(false);
|
|
80
|
+
});
|
|
81
|
+
return () => {
|
|
82
|
+
cancelled = true;
|
|
83
|
+
};
|
|
84
|
+
}, [prdFeatureId]);
|
|
85
|
+
const techFeatureId = view?.type === 'tech-review' ? view.node.featureId : null;
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
setTechData(null);
|
|
88
|
+
if (!techFeatureId)
|
|
89
|
+
return;
|
|
90
|
+
let cancelled = false;
|
|
91
|
+
setIsLoadingTech(true);
|
|
92
|
+
getResearchArtifact(techFeatureId)
|
|
93
|
+
.then((result) => {
|
|
94
|
+
if (cancelled)
|
|
95
|
+
return;
|
|
96
|
+
if (result.error) {
|
|
97
|
+
toast.error(result.error);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (result.techDecisions)
|
|
101
|
+
setTechData(result.techDecisions);
|
|
102
|
+
})
|
|
103
|
+
.catch(() => {
|
|
104
|
+
if (!cancelled)
|
|
105
|
+
toast.error('Failed to load tech decisions');
|
|
106
|
+
})
|
|
107
|
+
.finally(() => {
|
|
108
|
+
if (!cancelled)
|
|
109
|
+
setIsLoadingTech(false);
|
|
110
|
+
});
|
|
111
|
+
return () => {
|
|
112
|
+
cancelled = true;
|
|
113
|
+
};
|
|
114
|
+
}, [techFeatureId]);
|
|
115
|
+
const mergeFeatureId = view?.type === 'merge-review' ? view.node.featureId : null;
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
setMergeData(null);
|
|
118
|
+
if (!mergeFeatureId)
|
|
119
|
+
return;
|
|
120
|
+
let cancelled = false;
|
|
121
|
+
setIsLoadingMerge(true);
|
|
122
|
+
getMergeReviewData(mergeFeatureId)
|
|
123
|
+
.then((result) => {
|
|
124
|
+
if (cancelled)
|
|
125
|
+
return;
|
|
126
|
+
if ('error' in result) {
|
|
127
|
+
toast.error(result.error);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
setMergeData(result);
|
|
131
|
+
})
|
|
132
|
+
.catch(() => {
|
|
133
|
+
if (!cancelled)
|
|
134
|
+
toast.error('Failed to load merge review data');
|
|
135
|
+
})
|
|
136
|
+
.finally(() => {
|
|
137
|
+
if (!cancelled)
|
|
138
|
+
setIsLoadingMerge(false);
|
|
139
|
+
});
|
|
140
|
+
return () => {
|
|
141
|
+
cancelled = true;
|
|
142
|
+
};
|
|
143
|
+
}, [mergeFeatureId]);
|
|
144
|
+
// ── Approve / reject handlers ───────────────────────────────────────────
|
|
145
|
+
const reviewNode = view?.type === 'prd-review' || view?.type === 'tech-review' || view?.type === 'merge-review'
|
|
146
|
+
? view.node
|
|
147
|
+
: null;
|
|
148
|
+
const handleReject = useCallback(async (feedback, label, onDone) => {
|
|
149
|
+
if (!reviewNode?.featureId)
|
|
150
|
+
return;
|
|
151
|
+
setIsRejecting(true);
|
|
152
|
+
try {
|
|
153
|
+
const result = await rejectFeature(reviewNode.featureId, feedback);
|
|
154
|
+
if (!result.rejected) {
|
|
155
|
+
toast.error(result.error ?? `Failed to reject ${label.toLowerCase()}`);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
rejectSound.play();
|
|
159
|
+
toast.success(`${label} rejected — agent re-iterating (iteration ${result.iteration})`);
|
|
160
|
+
if (result.iterationWarning) {
|
|
161
|
+
toast.warning(`Iteration ${result.iteration} — consider approving or adjusting feedback to avoid excessive iterations`);
|
|
162
|
+
}
|
|
163
|
+
onClose();
|
|
164
|
+
onDone?.();
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
setIsRejecting(false);
|
|
168
|
+
}
|
|
169
|
+
}, [reviewNode, onClose, rejectSound]);
|
|
170
|
+
const handlePrdReject = useCallback((feedback) => handleReject(feedback, 'Requirements', () => setPrdSelections({})), [handleReject]);
|
|
171
|
+
const handleTechReject = useCallback((feedback) => handleReject(feedback, 'Plan'), [handleReject]);
|
|
172
|
+
const handleMergeReject = useCallback((feedback) => handleReject(feedback, 'Merge'), [handleReject]);
|
|
173
|
+
const handleSimpleApprove = useCallback(async (label) => {
|
|
174
|
+
if (!reviewNode?.featureId)
|
|
175
|
+
return;
|
|
176
|
+
const result = await approveFeature(reviewNode.featureId);
|
|
177
|
+
if (!result.approved) {
|
|
178
|
+
toast.error(result.error ?? `Failed to approve ${label.toLowerCase()}`);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
toast.success(`${label} approved — agent resuming`);
|
|
182
|
+
onClose();
|
|
183
|
+
}, [reviewNode, onClose]);
|
|
184
|
+
const handlePrdApprove = useCallback(async (_actionId) => {
|
|
185
|
+
if (view?.type !== 'prd-review')
|
|
186
|
+
return;
|
|
187
|
+
let payload;
|
|
188
|
+
if (prdData) {
|
|
189
|
+
const changedSelections = [];
|
|
190
|
+
for (const [questionId, optionId] of Object.entries(prdSelections)) {
|
|
191
|
+
const question = prdData.questions.find((q) => q.id === questionId);
|
|
192
|
+
const option = question?.options.find((o) => o.id === optionId);
|
|
193
|
+
if (question && option) {
|
|
194
|
+
changedSelections.push({ questionId: question.question, selectedOption: option.label });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
payload = { approved: true, changedSelections };
|
|
198
|
+
}
|
|
199
|
+
const result = await approveFeature(view.node.featureId, payload);
|
|
200
|
+
if (!result.approved) {
|
|
201
|
+
toast.error(result.error ?? 'Failed to approve requirements');
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
toast.success('Requirements approved — agent resuming');
|
|
205
|
+
setPrdSelections({});
|
|
206
|
+
onClose();
|
|
207
|
+
}, [view, prdData, prdSelections, onClose]);
|
|
208
|
+
const handleTechApprove = useCallback(() => handleSimpleApprove('Plan'), [handleSimpleApprove]);
|
|
209
|
+
const handleMergeApprove = useCallback(() => handleSimpleApprove('Merge'), [handleSimpleApprove]);
|
|
210
|
+
// ── Derived view data ───────────────────────────────────────────────────
|
|
211
|
+
const isCreateView = view?.type === 'feature-create';
|
|
212
|
+
const createView = isCreateView ? view : null;
|
|
213
|
+
const featureNode = view?.type === 'feature' ||
|
|
214
|
+
view?.type === 'prd-review' ||
|
|
215
|
+
view?.type === 'tech-review' ||
|
|
216
|
+
view?.type === 'merge-review'
|
|
217
|
+
? view.node
|
|
218
|
+
: null;
|
|
219
|
+
const repoData = view?.type === 'repository' ? view.data : null;
|
|
220
|
+
// ── Hooks (always called unconditionally per Rules of Hooks) ────────────
|
|
221
|
+
const featureActionsInput = featureNode?.repositoryPath && featureNode?.branch
|
|
222
|
+
? {
|
|
223
|
+
repositoryPath: featureNode.repositoryPath,
|
|
224
|
+
branch: featureNode.branch,
|
|
225
|
+
specPath: featureNode.specPath,
|
|
226
|
+
}
|
|
227
|
+
: null;
|
|
228
|
+
const featureActions = useFeatureActions(featureActionsInput);
|
|
229
|
+
const repoActions = useRepositoryActions(repoData?.repositoryPath ? { repositoryPath: repoData.repositoryPath } : null);
|
|
230
|
+
// ── Header ──────────────────────────────────────────────────────────────
|
|
231
|
+
let header = undefined;
|
|
232
|
+
if (featureNode) {
|
|
233
|
+
header = (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: featureNode.name }), featureNode.description ? (_jsx(DrawerDescription, { children: featureNode.description })) : featureNode.featureId ? (_jsx(DrawerDescription, { className: "sr-only", children: featureNode.featureId })) : null] }), featureActionsInput ? (_jsxs("div", { className: "flex items-center gap-2 pt-2", children: [_jsx(OpenActionMenu, { actions: featureActions, repositoryPath: featureActionsInput.repositoryPath, showSpecs: !!featureActionsInput.specPath }), onDelete && featureNode.featureId ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "bg-border mx-1 h-4 w-px" }), _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Delete feature", disabled: isDeleting, className: "text-muted-foreground hover:text-destructive", "data-testid": "feature-drawer-delete", children: isDeleting ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : (_jsx(Trash2, { className: "size-4" })) }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete feature?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: featureNode.name }), " (", featureNode.featureId, "). This action cannot be undone.", featureNode.state === 'running' ? (_jsx(_Fragment, { children: " This feature has a running agent that will be stopped." })) : null] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isDeleting, children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: isDeleting, onClick: () => onDelete(featureNode.featureId), children: isDeleting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Deleting\u2026"] })) : ('Delete') })] })] })] })] })) : null] })) : null] }));
|
|
234
|
+
}
|
|
235
|
+
else if (repoData) {
|
|
236
|
+
header = (_jsxs("div", { "data-testid": "repository-drawer-header", children: [_jsx(DrawerTitle, { children: repoData.name }), repoData.repositoryPath ? (_jsx(DrawerDescription, { className: "truncate font-mono text-xs", children: repoData.repositoryPath })) : null] }));
|
|
237
|
+
}
|
|
238
|
+
// ── Body ────────────────────────────────────────────────────────────────
|
|
239
|
+
let body = null;
|
|
240
|
+
if (view?.type === 'feature' && featureNode) {
|
|
241
|
+
body = (_jsxs("div", { className: "flex-1 overflow-y-auto", children: [_jsxs("div", { "data-testid": "feature-drawer-status", className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: lifecycleDisplayLabels[featureNode.lifecycle] }), _jsx(FeatureStateBadge, { data: featureNode }), featureNode.progress > 0 ? (_jsxs("div", { "data-testid": "feature-drawer-progress", className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-xs", children: [_jsx("span", { children: "Progress" }), _jsxs("span", { children: [featureNode.progress, "%"] })] }), _jsx("div", { className: "bg-muted h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', featureNodeStateConfig[featureNode.state].progressClass), style: { width: `${featureNode.progress}%` } }) })] })) : null] }), featureNode.pr ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx(FeaturePrInfo, { pr: featureNode.pr })] })) : null, _jsx(FeatureDetails, { data: featureNode })] }));
|
|
242
|
+
}
|
|
243
|
+
else if (view?.type === 'prd-review') {
|
|
244
|
+
body = prdData ? (_jsx(PrdQuestionnaire, { data: prdData, selections: prdSelections, onSelect: (qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId })), onApprove: handlePrdApprove, onReject: handlePrdReject, isProcessing: isLoadingPrd, isRejecting: isRejecting })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
|
|
245
|
+
}
|
|
246
|
+
else if (view?.type === 'tech-review') {
|
|
247
|
+
body = techData ? (_jsx(TechDecisionsReview, { data: techData, onApprove: handleTechApprove, onReject: handleTechReject, isProcessing: isLoadingTech, isRejecting: isRejecting })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
|
|
248
|
+
}
|
|
249
|
+
else if (view?.type === 'merge-review') {
|
|
250
|
+
body = mergeData ? (_jsx(MergeReview, { data: mergeData, onApprove: handleMergeApprove, onReject: handleMergeReject, isProcessing: isLoadingMerge, isRejecting: isRejecting })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
|
|
251
|
+
}
|
|
252
|
+
else if (view?.type === 'repository' && repoData?.repositoryPath) {
|
|
253
|
+
body = (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "OPEN WITH" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(ActionButton, { label: "Open in IDE", onClick: repoActions.openInIde, loading: repoActions.ideLoading, error: !!repoActions.ideError, icon: Code2, variant: "outline", size: "sm" }), _jsx(ActionButton, { label: "Open in Shell", onClick: repoActions.openInShell, loading: repoActions.shellLoading, error: !!repoActions.shellError, icon: Terminal, variant: "outline", size: "sm" }), _jsx(ActionButton, { label: "Open Folder", onClick: repoActions.openFolder, loading: repoActions.folderLoading, error: !!repoActions.folderError, icon: FolderOpen, variant: "outline", size: "sm" })] })] })] }));
|
|
254
|
+
}
|
|
255
|
+
// ── Render ──────────────────────────────────────────────────────────────
|
|
256
|
+
return (_jsxs(_Fragment, { children: [_jsx(BaseDrawer, { open: view !== null && !isCreateView, onClose: onClose, size: "md", modal: false, header: header, "data-testid": view?.type === 'feature'
|
|
257
|
+
? 'feature-drawer'
|
|
258
|
+
: view?.type === 'repository'
|
|
259
|
+
? 'repository-drawer'
|
|
260
|
+
: 'review-drawer', children: body }), _jsx(FeatureCreateDrawer, { open: isCreateView, onClose: onClose, onSubmit: onCreateSubmit, repositoryPath: createView?.repositoryPath ?? '', features: createView?.features ?? [], workflowDefaults: createView?.workflowDefaults, initialParentId: createView?.initialParentId, isSubmitting: isSubmitting })] }));
|
|
261
|
+
}
|
|
262
|
+
// ── Private sub-components ────────────────────────────────────────────────────
|
|
263
|
+
function FeatureStateBadge({ data }) {
|
|
264
|
+
const config = featureNodeStateConfig[data.state];
|
|
265
|
+
const Icon = config.icon;
|
|
266
|
+
return (_jsxs("div", { className: cn('flex items-center gap-2 rounded-full px-3 py-1.5 text-sm font-medium', config.badgeBgClass, config.badgeClass), children: [data.state === 'running' ? (_jsx(CometSpinner, { size: "sm", className: "shrink-0" })) : (_jsx(Icon, { className: "h-4 w-4 shrink-0" })), _jsx("span", { children: config.label })] }));
|
|
267
|
+
}
|
|
268
|
+
const prStatusStyles = {
|
|
269
|
+
[PrStatus.Open]: 'border-transparent bg-blue-50 text-blue-700 hover:bg-blue-50',
|
|
270
|
+
[PrStatus.Merged]: 'border-transparent bg-purple-50 text-purple-700 hover:bg-purple-50',
|
|
271
|
+
[PrStatus.Closed]: 'border-transparent bg-red-50 text-red-700 hover:bg-red-50',
|
|
272
|
+
};
|
|
273
|
+
function FeaturePrInfo({ pr }) {
|
|
274
|
+
return (_jsx("div", { "data-testid": "feature-drawer-pr", className: "border-border mx-4 rounded-lg border", children: _jsxs("div", { className: "space-y-3 px-4 py-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("a", { href: pr.url, target: "_blank", rel: "noopener noreferrer", className: "text-primary flex items-center gap-1.5 text-sm font-semibold underline underline-offset-2", children: ["PR #", pr.number, _jsx(ExternalLink, { className: "h-3.5 w-3.5" })] }), _jsx(Badge, { className: prStatusStyles[pr.status], children: pr.status })] }), pr.ciStatus ? (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "CI Status" }), _jsx(CiStatusBadge, { status: pr.ciStatus })] })) : null, pr.commitHash ? (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Commit" }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(GitCommitHorizontal, { className: "text-muted-foreground h-3.5 w-3.5" }), _jsx("code", { className: "bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]", children: pr.commitHash.slice(0, 7) })] })] })) : null] }) }));
|
|
275
|
+
}
|
|
276
|
+
function FeatureDetails({ data }) {
|
|
277
|
+
const hasAnyDetail = data.agentType ?? data.runtime ?? data.blockedBy ?? data.errorMessage;
|
|
278
|
+
if (!hasAnyDetail)
|
|
279
|
+
return null;
|
|
280
|
+
return (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-details", className: "flex flex-col gap-3 p-4", children: [data.agentType ? _jsx(DetailRow, { label: "Agent", value: data.agentType }) : null, data.runtime ? _jsx(DetailRow, { label: "Runtime", value: data.runtime }) : null, data.blockedBy ? _jsx(DetailRow, { label: "Blocked by", value: data.blockedBy }) : null, data.errorMessage ? _jsx(DetailRow, { label: "Error", value: data.errorMessage }) : null] })] }));
|
|
281
|
+
}
|
|
282
|
+
function DetailRow({ label, value }) {
|
|
283
|
+
return (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: label }), _jsx("span", { className: "text-sm", children: value })] }));
|
|
284
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { ControlCenterDrawer } from './control-center-drawer.js';
|
|
3
|
+
declare const meta: Meta<typeof ControlCenterDrawer>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof ControlCenterDrawer>;
|
|
6
|
+
/** Feature info view — running state with progress. Default story. */
|
|
7
|
+
export declare const Default: Story;
|
|
8
|
+
/** Feature info view — completed (maintain lifecycle, done state, merged PR). */
|
|
9
|
+
export declare const FeatureDone: Story;
|
|
10
|
+
/** Feature info view — error state. */
|
|
11
|
+
export declare const FeatureError: Story;
|
|
12
|
+
/**
|
|
13
|
+
* PRD review view — loads questionnaire data via server action.
|
|
14
|
+
* Shows spinner in Storybook (no real API available).
|
|
15
|
+
*/
|
|
16
|
+
export declare const PrdReview: Story;
|
|
17
|
+
/**
|
|
18
|
+
* Tech decisions review view — loads research artifact via server action.
|
|
19
|
+
* Shows spinner in Storybook.
|
|
20
|
+
*/
|
|
21
|
+
export declare const TechReview: Story;
|
|
22
|
+
/**
|
|
23
|
+
* Merge review view — loads merge review data via server action.
|
|
24
|
+
* Shows spinner in Storybook.
|
|
25
|
+
*/
|
|
26
|
+
export declare const MergeReview: Story;
|
|
27
|
+
/** Feature create form. */
|
|
28
|
+
export declare const FeatureCreate: Story;
|
|
29
|
+
/** Repository actions view. */
|
|
30
|
+
export declare const Repository: Story;
|
|
31
|
+
/** Interactive — click any view type to open that drawer panel. */
|
|
32
|
+
export declare const AllViews: Story;
|
|
33
|
+
//# sourceMappingURL=control-center-drawer.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-center-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG9D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,mBAAmB,CAO1C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,mBAAmB,CAAC,CAAC;AA+JlD,sEAAsE;AACtE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,uCAAuC;AACvC,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,2BAA2B;AAC3B,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AA0DF,mEAAmE;AACnE,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC"}
|