@shepai/cli 1.78.1 → 1.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.d.ts.map +1 -1
- package/dist/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page.js +14 -1
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts +17 -0
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +25 -0
- package/dist/src/presentation/web/app/actions/get-feature-plan.d.ts +18 -0
- package/dist/src/presentation/web/app/actions/get-feature-plan.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/get-feature-plan.js +31 -0
- package/dist/src/presentation/web/app/api/feature-logs/route.d.ts +16 -0
- package/dist/src/presentation/web/app/api/feature-logs/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/feature-logs/route.js +184 -0
- package/dist/src/presentation/web/app/build-feature-node-data.d.ts +7 -1
- package/dist/src/presentation/web/app/build-feature-node-data.d.ts.map +1 -1
- package/dist/src/presentation/web/app/build-feature-node-data.js +7 -1
- package/dist/src/presentation/web/app/build-graph-nodes.js +7 -3
- package/dist/src/presentation/web/app/settings/page.js +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts +7 -19
- package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/drawer-view.js +6 -6
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +48 -85
- package/dist/src/presentation/web/components/common/feature-drawer/index.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/index.js +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts +8 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +90 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts +20 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.js +252 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts +31 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +123 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.d.ts +20 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.js +315 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/index.d.ts +3 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/index.js +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.d.ts +7 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.js +35 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.d.ts +18 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.js +89 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts +6 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +78 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +28 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +157 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.d.ts +8 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.js +40 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.d.ts +22 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.js +188 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.d.ts +30 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.js +100 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +12 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/index.d.ts +3 -4
- package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/index.js +3 -4
- package/dist/src/presentation/web/components/common/merge-review/index.d.ts +1 -2
- package/dist/src/presentation/web/components/common/merge-review/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/merge-review/index.js +0 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts +0 -8
- 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 -33
- package/dist/src/presentation/web/components/common/prd-questionnaire/index.d.ts +1 -2
- package/dist/src/presentation/web/components/common/prd-questionnaire/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/index.js +0 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts +0 -10
- 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 -38
- package/dist/src/presentation/web/components/common/tech-decisions-review/index.d.ts +1 -2
- package/dist/src/presentation/web/components/common/tech-decisions-review/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/index.js +0 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts +0 -8
- 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 -29
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.js +2 -2
- package/dist/src/presentation/web/components/features/settings/settings-page-client.js +9 -9
- package/dist/src/presentation/web/hooks/use-feature-logs.d.ts +7 -0
- package/dist/src/presentation/web/hooks/use-feature-logs.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/use-feature-logs.js +52 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +1 -0
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/routes-manifest.json +6 -0
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +18 -18
- 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 +68 -38
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
- 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 +18 -18
- 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 +68 -38
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
- 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/api/feature-logs/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/feature-logs/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/feature-logs/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/feature-logs/route.js +6 -0
- package/web/.next/server/app/api/feature-logs/route.js.map +5 -0
- package/web/.next/server/app/api/feature-logs/route.js.nft.json +1 -0
- package/web/.next/server/app/api/feature-logs/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app-paths-manifest.json +1 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_feature-logs_route_actions_177445e7.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_feature-logs_route_actions_177445e7.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__91d44424._.js +12 -0
- package/web/.next/server/chunks/[root-of-the-server]__91d44424._.js.map +1 -0
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_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]__11033878._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4be9a9bb._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6eb2a2b0._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6eb2a2b0._.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/{[root-of-the-server]__a337ca5c._.js → [root-of-the-server]__ae824a5b._.js} +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ae824a5b._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b3a4cef4._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b3a4cef4._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c3c963c6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c3c963c6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f0d8d054._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_1e3cf73b._.js +1 -1
- package/web/.next/server/chunks/ssr/_1e3cf73b._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_34fbed18._.js +1 -1
- package/web/.next/server/chunks/ssr/_34fbed18._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_06db7efd._.js → _3e88ce9d._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_06db7efd._.js.map → _3e88ce9d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_5d4e7151._.js +3 -0
- package/web/.next/server/chunks/ssr/{_5c4ce700._.js.map → _5d4e7151._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_63868199._.js +1 -1
- package/web/.next/server/chunks/ssr/_63868199._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_b0924a46._.js → _83cf28a3._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_b0924a46._.js.map → _83cf28a3._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_4031d614._.js → _887258d0._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_4031d614._.js.map → _887258d0._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_acb6a73d._.js +3 -0
- package/web/.next/server/chunks/ssr/{_a38f282a._.js.map → _acb6a73d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_5dab501b._.js → _ba97cfd3._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_5dab501b._.js.map → _ba97cfd3._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/node_modules__pnpm_d80c1060._.js +3 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_d80c1060._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_7efa14ca._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_7efa14ca._.js.map +1 -0
- 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__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_b59d79db._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_b59d79db._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.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 +108 -64
- package/web/.next/static/chunks/{87152e918f80ea8b.js → 297458261f67218c.js} +1 -1
- package/web/.next/static/chunks/{1f57d0c949dbb44d.js → 2a24ac257fc1c10b.js} +1 -1
- package/web/.next/static/chunks/352e25e1bb2b9edb.js +1 -0
- package/web/.next/static/chunks/{8fe834f8a3c36e2f.js → 47ecde22e9663419.js} +2 -2
- package/web/.next/static/chunks/{27c4a8493483e6f3.js → 49743c83c9bced40.js} +1 -1
- package/web/.next/static/chunks/4b20d522b4f5ca7e.js +1 -0
- package/web/.next/static/chunks/{9d8c6c874071efb2.js → 5688494bf052915d.js} +1 -1
- package/web/.next/static/chunks/77a956d5dd063fef.js +1 -0
- package/web/.next/static/chunks/{78455afb0164395c.js → 8eff15a7f35164f9.js} +2 -2
- package/web/.next/static/chunks/96bab6d3820504f3.css +2 -0
- package/web/.next/static/chunks/a1c2ecb710b44081.js +1 -0
- package/web/.next/static/chunks/{6f7ba7846dcc8b21.js → d8d464c156573994.js} +1 -1
- package/web/.next/static/chunks/e29d1e26c2694f78.js +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts +0 -9
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.js +0 -60
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.d.ts +0 -47
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.js +0 -307
- package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts +0 -3
- package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.js +0 -8
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-drawer.d.ts +0 -3
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-drawer.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-drawer.js +0 -8
- package/dist/src/presentation/web/components/common/review-drawer-shell/index.d.ts +0 -3
- package/dist/src/presentation/web/components/common/review-drawer-shell/index.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/review-drawer-shell/index.js +0 -1
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell-config.d.ts +0 -26
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell-config.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell-config.js +0 -1
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.d.ts +0 -3
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.js +0 -29
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.stories.d.ts +0 -14
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.stories.js +0 -33
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-drawer.d.ts +0 -3
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-drawer.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-drawer.js +0 -8
- package/dist/src/presentation/web/components/common/tech-review-tabs/index.d.ts +0 -3
- package/dist/src/presentation/web/components/common/tech-review-tabs/index.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/tech-review-tabs/index.js +0 -1
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.d.ts +0 -21
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.js +0 -1
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.d.ts +0 -3
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.js +0 -12
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.stories.d.ts +0 -16
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.stories.js +0 -110
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a337ca5c._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_5c4ce700._.js +0 -3
- package/web/.next/server/chunks/ssr/_a38f282a._.js +0 -3
- package/web/.next/server/chunks/ssr/node_modules__pnpm_5412e589._.js +0 -3
- package/web/.next/server/chunks/ssr/node_modules__pnpm_5412e589._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js.map +0 -1
- package/web/.next/static/chunks/08c0a9667c05866c.css +0 -2
- package/web/.next/static/chunks/0fb8038f7ad4d2cf.js +0 -1
- package/web/.next/static/chunks/1211dcaac5963f92.js +0 -1
- package/web/.next/static/chunks/6a3e8ea6e1fd2113.js +0 -1
- package/web/.next/static/chunks/7336f9ec160c7bd8.js +0 -1
- package/web/.next/static/chunks/ba8b2aaa356a5487.js +0 -1
- /package/web/.next/static/{M0oz1_1InoSyr7OMLAKf7 → hVGa8-vd4pFs9splpgq-k}/_buildManifest.js +0 -0
- /package/web/.next/static/{M0oz1_1InoSyr7OMLAKf7 → hVGa8-vd4pFs9splpgq-k}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{M0oz1_1InoSyr7OMLAKf7 → hVGa8-vd4pFs9splpgq-k}/_ssgManifest.js +0 -0
package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js
CHANGED
|
@@ -3,15 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
4
4
|
import { useRouter, usePathname } from 'next/navigation';
|
|
5
5
|
import { toast } from 'sonner';
|
|
6
|
-
import { Loader2, Trash2,
|
|
7
|
-
import { PrStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
|
|
6
|
+
import { Loader2, Trash2, Play, Square, Copy, Check } from 'lucide-react';
|
|
8
7
|
import { approveFeature } from '../../../app/actions/approve-feature.js';
|
|
9
8
|
import { rejectFeature } from '../../../app/actions/reject-feature.js';
|
|
10
9
|
import { getFeatureArtifact } from '../../../app/actions/get-feature-artifact.js';
|
|
11
10
|
import { getResearchArtifact } from '../../../app/actions/get-research-artifact.js';
|
|
12
11
|
import { getMergeReviewData } from '../../../app/actions/get-merge-review-data.js';
|
|
13
12
|
import { deleteFeature } from '../../../app/actions/delete-feature.js';
|
|
14
|
-
import { cn } from '../../../lib/utils.js';
|
|
15
13
|
import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
|
|
16
14
|
import { useSoundAction } from '../../../hooks/use-sound-action.js';
|
|
17
15
|
import { useGuardedDrawerClose } from '../../../hooks/drawer-close-guard.js';
|
|
@@ -21,21 +19,14 @@ import { BaseDrawer } from '../../common/base-drawer/index.js';
|
|
|
21
19
|
import { DeploymentStatusBadge } from '../../common/deployment-status-badge/index.js';
|
|
22
20
|
import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
|
|
23
21
|
import { Button } from '../../ui/button.js';
|
|
24
|
-
import { Badge } from '../../ui/badge.js';
|
|
25
|
-
import { Separator } from '../../ui/separator.js';
|
|
26
22
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
|
|
27
|
-
import { CometSpinner } from '../../ui/comet-spinner.js';
|
|
28
23
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from '../../ui/alert-dialog.js';
|
|
29
|
-
import { CiStatusBadge } from '../../common/ci-status-badge/index.js';
|
|
30
24
|
import { ActionButton } from '../../common/action-button/index.js';
|
|
31
25
|
import { OpenActionMenu } from '../../common/open-action-menu/index.js';
|
|
32
|
-
import {
|
|
33
|
-
import { TechReviewTabs } from '../../common/tech-review-tabs/index.js';
|
|
34
|
-
import { MergeReview } from '../../common/merge-review/index.js';
|
|
35
|
-
import { featureNodeStateConfig, lifecycleDisplayLabels } from '../../common/feature-node/index.js';
|
|
26
|
+
import { FeatureDrawerTabs } from '../../common/feature-drawer-tabs/index.js';
|
|
36
27
|
import { useFeatureActions } from '../../common/feature-drawer/use-feature-actions.js';
|
|
37
28
|
import { resolveSseEventUpdates } from '../../common/feature-node/derive-feature-state.js';
|
|
38
|
-
import {
|
|
29
|
+
import { deriveInitialTab } from './drawer-view.js';
|
|
39
30
|
import { useArtifactFetch } from './use-artifact-fetch.js';
|
|
40
31
|
export function FeatureDrawerClient({ view: initialView }) {
|
|
41
32
|
const featureFlags = useFeatureFlags();
|
|
@@ -48,12 +39,7 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
48
39
|
useEffect(() => {
|
|
49
40
|
setView(initialView);
|
|
50
41
|
}, [initialView]);
|
|
51
|
-
const featureNode = view.type === 'feature'
|
|
52
|
-
view.type === 'prd-review' ||
|
|
53
|
-
view.type === 'tech-review' ||
|
|
54
|
-
view.type === 'merge-review'
|
|
55
|
-
? view.node
|
|
56
|
-
: null;
|
|
42
|
+
const featureNode = view.type === 'feature' ? view.node : null;
|
|
57
43
|
// SSE: update drawer view when feature state changes
|
|
58
44
|
const { events } = useAgentEventsContext();
|
|
59
45
|
const processedCountRef = useRef(0);
|
|
@@ -75,21 +61,18 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
75
61
|
if (isOpenRef.current && !isDirtyRef.current && !isRejectingRef.current)
|
|
76
62
|
router.refresh();
|
|
77
63
|
if (update.state !== undefined || update.lifecycle !== undefined) {
|
|
78
|
-
// Optimistically update the node data AND re-derive the
|
|
79
|
-
// drawer switches immediately (e.g. prd-review →
|
|
64
|
+
// Optimistically update the node data AND re-derive the initial tab so the
|
|
65
|
+
// drawer switches immediately (e.g. prd-review → overview when agent resumes)
|
|
80
66
|
// without waiting for the router.refresh() round-trip.
|
|
81
67
|
setView((prev) => {
|
|
82
|
-
if (prev.type !== 'feature'
|
|
83
|
-
prev.type !== 'prd-review' &&
|
|
84
|
-
prev.type !== 'tech-review' &&
|
|
85
|
-
prev.type !== 'merge-review')
|
|
68
|
+
if (prev.type !== 'feature')
|
|
86
69
|
return prev;
|
|
87
70
|
const updatedNode = {
|
|
88
71
|
...prev.node,
|
|
89
72
|
...(update.state !== undefined && { state: update.state }),
|
|
90
73
|
...(update.lifecycle !== undefined && { lifecycle: update.lifecycle }),
|
|
91
74
|
};
|
|
92
|
-
return { ...prev,
|
|
75
|
+
return { ...prev, node: updatedNode, initialTab: deriveInitialTab(updatedNode) };
|
|
93
76
|
});
|
|
94
77
|
}
|
|
95
78
|
}
|
|
@@ -131,13 +114,15 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
131
114
|
// ── Shared reject state ────────────────────────────────────────────────
|
|
132
115
|
const [isRejecting, setIsRejecting] = useState(false);
|
|
133
116
|
const isRejectingRef = useRef(false);
|
|
134
|
-
// Reset chat input whenever the
|
|
135
|
-
const
|
|
117
|
+
// Reset chat input whenever the initialTab changes (lifecycle transition)
|
|
118
|
+
const initialTab = view.type === 'feature' ? view.initialTab : undefined;
|
|
136
119
|
useEffect(() => {
|
|
137
120
|
setChatInput('');
|
|
138
|
-
}, [
|
|
121
|
+
}, [initialTab]);
|
|
139
122
|
// ── Data fetching ─────────────────────────────────────────────────────
|
|
140
|
-
const prdFeatureId =
|
|
123
|
+
const prdFeatureId = featureNode?.lifecycle === 'requirements' && featureNode?.state === 'action-required'
|
|
124
|
+
? featureNode.featureId
|
|
125
|
+
: null;
|
|
141
126
|
const isLoadingPrd = useArtifactFetch(prdFeatureId, getFeatureArtifact, (result) => {
|
|
142
127
|
if (result.error) {
|
|
143
128
|
toast.error(result.error);
|
|
@@ -159,7 +144,9 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
159
144
|
setPrdDefaultSelections({});
|
|
160
145
|
setPrdData(null);
|
|
161
146
|
}, 'Failed to load questionnaire');
|
|
162
|
-
const techFeatureId =
|
|
147
|
+
const techFeatureId = featureNode?.lifecycle === 'implementation' && featureNode?.state === 'action-required'
|
|
148
|
+
? featureNode.featureId
|
|
149
|
+
: null;
|
|
163
150
|
const isLoadingTech = useArtifactFetch(techFeatureId, getResearchArtifact, (result) => {
|
|
164
151
|
if (result.error) {
|
|
165
152
|
toast.error(result.error);
|
|
@@ -172,7 +159,10 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
172
159
|
if (result.productDecisions)
|
|
173
160
|
setTechProductData(result.productDecisions);
|
|
174
161
|
}, () => setTechProductData(undefined));
|
|
175
|
-
const mergeFeatureId =
|
|
162
|
+
const mergeFeatureId = featureNode?.lifecycle === 'review' &&
|
|
163
|
+
(featureNode?.state === 'action-required' || featureNode?.state === 'error')
|
|
164
|
+
? featureNode.featureId
|
|
165
|
+
: null;
|
|
176
166
|
const isLoadingMerge = useArtifactFetch(mergeFeatureId, getMergeReviewData, (result) => {
|
|
177
167
|
if ('error' in result) {
|
|
178
168
|
toast.error(result.error);
|
|
@@ -182,7 +172,8 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
182
172
|
}, () => setMergeData(null), 'Failed to load merge review data');
|
|
183
173
|
// ── Close guard ──────────────────────────────────────────────────────
|
|
184
174
|
const isChatDirty = chatInput.trim().length > 0;
|
|
185
|
-
const isPrdDirty =
|
|
175
|
+
const isPrdDirty = featureNode?.lifecycle === 'requirements' &&
|
|
176
|
+
featureNode?.state === 'action-required' &&
|
|
186
177
|
Object.keys(prdDefaultSelections).some((k) => prdDefaultSelections[k] !== prdSelections[k]);
|
|
187
178
|
const isDirty = isChatDirty || isPrdDirty;
|
|
188
179
|
// Keep dirty state in a ref so the SSE handler can read the latest value
|
|
@@ -195,16 +186,13 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
195
186
|
}, [prdDefaultSelections]);
|
|
196
187
|
const { attemptClose } = useGuardedDrawerClose({ open: isOpen, isDirty, onClose, onReset });
|
|
197
188
|
// ── Approve / reject handlers ─────────────────────────────────────────
|
|
198
|
-
const reviewNode = view.type === 'prd-review' || view.type === 'tech-review' || view.type === 'merge-review'
|
|
199
|
-
? view.node
|
|
200
|
-
: null;
|
|
201
189
|
const handleReject = useCallback(async (feedback, label, onDone) => {
|
|
202
|
-
if (!
|
|
190
|
+
if (!featureNode?.featureId)
|
|
203
191
|
return;
|
|
204
192
|
isRejectingRef.current = true;
|
|
205
193
|
setIsRejecting(true);
|
|
206
194
|
try {
|
|
207
|
-
const result = await rejectFeature(
|
|
195
|
+
const result = await rejectFeature(featureNode.featureId, feedback);
|
|
208
196
|
if (!result.rejected) {
|
|
209
197
|
toast.error(result.error ?? `Failed to reject ${label.toLowerCase()}`);
|
|
210
198
|
return;
|
|
@@ -222,14 +210,14 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
222
210
|
isRejectingRef.current = false;
|
|
223
211
|
setIsRejecting(false);
|
|
224
212
|
}
|
|
225
|
-
}, [
|
|
213
|
+
}, [featureNode, onClose, rejectSound]);
|
|
226
214
|
const handlePrdReject = useCallback((feedback) => handleReject(feedback, 'Requirements', () => setPrdSelections({})), [handleReject]);
|
|
227
215
|
const handleTechReject = useCallback((feedback) => handleReject(feedback, 'Plan'), [handleReject]);
|
|
228
216
|
const handleMergeReject = useCallback((feedback) => handleReject(feedback, 'Merge'), [handleReject]);
|
|
229
217
|
const handleSimpleApprove = useCallback(async (label) => {
|
|
230
|
-
if (!
|
|
218
|
+
if (!featureNode?.featureId)
|
|
231
219
|
return;
|
|
232
|
-
const result = await approveFeature(
|
|
220
|
+
const result = await approveFeature(featureNode.featureId);
|
|
233
221
|
if (!result.approved) {
|
|
234
222
|
toast.error(result.error ?? `Failed to approve ${label.toLowerCase()}`);
|
|
235
223
|
return;
|
|
@@ -238,12 +226,12 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
238
226
|
toast.success(`${label} approved — agent resuming`);
|
|
239
227
|
// Optimistically update canvas node before SSE arrives (~500ms delay)
|
|
240
228
|
window.dispatchEvent(new CustomEvent('shep:feature-approved', {
|
|
241
|
-
detail: { featureId:
|
|
229
|
+
detail: { featureId: featureNode.featureId },
|
|
242
230
|
}));
|
|
243
231
|
onClose();
|
|
244
|
-
}, [
|
|
232
|
+
}, [featureNode, onClose]);
|
|
245
233
|
const handlePrdApprove = useCallback(async (_actionId) => {
|
|
246
|
-
if (view.type !== '
|
|
234
|
+
if (view.type !== 'feature' || !featureNode)
|
|
247
235
|
return;
|
|
248
236
|
let payload;
|
|
249
237
|
if (prdData) {
|
|
@@ -257,7 +245,7 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
257
245
|
}
|
|
258
246
|
payload = { approved: true, changedSelections };
|
|
259
247
|
}
|
|
260
|
-
const result = await approveFeature(
|
|
248
|
+
const result = await approveFeature(featureNode.featureId, payload);
|
|
261
249
|
if (!result.approved) {
|
|
262
250
|
toast.error(result.error ?? 'Failed to approve requirements');
|
|
263
251
|
return;
|
|
@@ -266,11 +254,11 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
266
254
|
toast.success('Requirements approved — agent resuming');
|
|
267
255
|
// Optimistically update canvas node before SSE arrives (~500ms delay)
|
|
268
256
|
window.dispatchEvent(new CustomEvent('shep:feature-approved', {
|
|
269
|
-
detail: { featureId:
|
|
257
|
+
detail: { featureId: featureNode.featureId },
|
|
270
258
|
}));
|
|
271
259
|
setPrdSelections({});
|
|
272
260
|
onClose();
|
|
273
|
-
}, [view, prdData, prdSelections, onClose]);
|
|
261
|
+
}, [view, featureNode, prdData, prdSelections, onClose]);
|
|
274
262
|
const handleTechApprove = useCallback(() => handleSimpleApprove('Plan'), [handleSimpleApprove]);
|
|
275
263
|
const handleMergeApprove = useCallback(() => handleSimpleApprove('Merge'), [handleSimpleApprove]);
|
|
276
264
|
const handleDelete = useCallback(async (featureId) => {
|
|
@@ -312,51 +300,26 @@ export function FeatureDrawerClient({ view: initialView }) {
|
|
|
312
300
|
: null;
|
|
313
301
|
const deployAction = useDeployAction(featureDeployTarget);
|
|
314
302
|
const isFeatureDeployActive = deployAction.status === 'Booting' || deployAction.status === 'Ready';
|
|
303
|
+
// ── Short ID copy ───────────────────────────────────────────────────
|
|
304
|
+
const COPY_FEEDBACK_DELAY = 2000;
|
|
305
|
+
const [idCopied, setIdCopied] = useState(false);
|
|
306
|
+
const handleCopyId = useCallback(() => {
|
|
307
|
+
if (!featureNode?.featureId)
|
|
308
|
+
return;
|
|
309
|
+
void navigator.clipboard.writeText(featureNode.featureId);
|
|
310
|
+
setIdCopied(true);
|
|
311
|
+
setTimeout(() => setIdCopied(false), COPY_FEEDBACK_DELAY);
|
|
312
|
+
}, [featureNode?.featureId]);
|
|
315
313
|
// ── Header ────────────────────────────────────────────────────────────
|
|
316
314
|
let header = undefined;
|
|
317
315
|
if (featureNode) {
|
|
318
|
-
|
|
316
|
+
const shortId = featureNode.featureId.slice(0, 8);
|
|
317
|
+
header = (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: featureNode.name }), _jsxs("div", { className: "flex items-center gap-1.5 pt-0.5", children: [_jsx("code", { className: "bg-muted text-muted-foreground rounded px-1.5 py-0.5 font-mono text-xs", children: shortId }), _jsx("button", { type: "button", onClick: handleCopyId, className: "text-muted-foreground hover:text-foreground inline-flex items-center rounded p-0.5 transition-colors", "aria-label": "Copy feature ID", "data-testid": "feature-drawer-copy-id", children: idCopied ? (_jsx(Check, { className: "size-3.5 text-green-600" })) : (_jsx(Copy, { className: "size-3.5" })) })] }), featureNode.oneLiner ? (_jsx(DrawerDescription, { children: featureNode.oneLiner })) : featureNode.userQuery ? (_jsx(DrawerDescription, { children: featureNode.userQuery })) : 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 }), featureFlags.envDeploy && featureDeployTarget ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { children: _jsx(ActionButton, { label: isFeatureDeployActive ? 'Stop Dev Server' : 'Start Dev Server', onClick: isFeatureDeployActive ? deployAction.stop : deployAction.deploy, loading: deployAction.deployLoading || deployAction.stopLoading, error: !!deployAction.deployError, icon: isFeatureDeployActive ? Square : Play, iconOnly: true, variant: "outline", size: "icon-sm" }) }) }), _jsx(TooltipContent, { children: isFeatureDeployActive ? 'Stop Dev Server' : 'Start Dev Server' })] }) }), isFeatureDeployActive ? (_jsx(DeploymentStatusBadge, { status: deployAction.status, url: deployAction.url, targetId: featureDeployTarget?.targetId })) : null] })) : null, featureNode.featureId ? (_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 ml-auto", "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: () => handleDelete(featureNode.featureId), children: isDeleting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Deleting\u2026"] })) : ('Delete') })] })] })] })) : null] })) : null] }));
|
|
319
318
|
}
|
|
320
319
|
// ── Body ──────────────────────────────────────────────────────────────
|
|
321
320
|
let body = null;
|
|
322
321
|
if (view.type === 'feature' && featureNode) {
|
|
323
|
-
body = (
|
|
324
|
-
}
|
|
325
|
-
else if (view.type === 'prd-review') {
|
|
326
|
-
body = prdData ? (_jsx(PrdQuestionnaire, { data: prdData, selections: prdSelections, onSelect: (qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId })), onApprove: handlePrdApprove, onReject: handlePrdReject, isProcessing: isLoadingPrd, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: setChatInput })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
|
|
322
|
+
body = (_jsx(FeatureDrawerTabs, { featureNode: featureNode, featureId: featureNode.featureId, initialTab: view.initialTab, prdData: prdData, prdSelections: prdSelections, onPrdSelect: (qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId })), onPrdApprove: handlePrdApprove, onPrdReject: handlePrdReject, isPrdLoading: isLoadingPrd, techData: techData, onTechApprove: handleTechApprove, onTechReject: handleTechReject, isTechLoading: isLoadingTech, productData: isLoadingTechProduct ? null : techProductData, mergeData: mergeData, onMergeApprove: handleMergeApprove, onMergeReject: handleMergeReject, isMergeLoading: isLoadingMerge, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: setChatInput }));
|
|
327
323
|
}
|
|
328
|
-
|
|
329
|
-
body = techData ? (_jsx(TechReviewTabs, { techData: techData, productData: isLoadingTechProduct ? null : techProductData, onApprove: handleTechApprove, onReject: handleTechReject, isProcessing: isLoadingTech, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: setChatInput })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
|
|
330
|
-
}
|
|
331
|
-
else if (view.type === 'merge-review') {
|
|
332
|
-
body = mergeData ? (_jsx(MergeReview, { data: mergeData, onApprove: handleMergeApprove, onReject: handleMergeReject, isProcessing: isLoadingMerge, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: setChatInput })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
|
|
333
|
-
}
|
|
334
|
-
return (_jsx(BaseDrawer, { open: isOpen, onClose: attemptClose, size: "md", modal: false, header: header, "data-testid": view.type === 'feature'
|
|
335
|
-
? 'feature-drawer'
|
|
336
|
-
: view.type === 'repository'
|
|
337
|
-
? 'repository-drawer'
|
|
338
|
-
: 'review-drawer', children: body }));
|
|
339
|
-
}
|
|
340
|
-
// ── Private sub-components ──────────────────────────────────────────────────
|
|
341
|
-
function FeatureStateBadge({ data }) {
|
|
342
|
-
const config = featureNodeStateConfig[data.state];
|
|
343
|
-
const Icon = config.icon;
|
|
344
|
-
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 })] }));
|
|
345
|
-
}
|
|
346
|
-
function FeaturePrInfo({ pr }) {
|
|
347
|
-
const prStatusStyles = {
|
|
348
|
-
[PrStatus.Open]: 'border-transparent bg-blue-50 text-blue-700 hover:bg-blue-50',
|
|
349
|
-
[PrStatus.Merged]: 'border-transparent bg-purple-50 text-purple-700 hover:bg-purple-50',
|
|
350
|
-
[PrStatus.Closed]: 'border-transparent bg-red-50 text-red-700 hover:bg-red-50',
|
|
351
|
-
};
|
|
352
|
-
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] }) }));
|
|
353
|
-
}
|
|
354
|
-
function FeatureDetails({ data }) {
|
|
355
|
-
const hasAnyDetail = data.agentType ?? data.runtime ?? data.blockedBy ?? data.errorMessage;
|
|
356
|
-
if (!hasAnyDetail)
|
|
357
|
-
return null;
|
|
358
|
-
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] })] }));
|
|
359
|
-
}
|
|
360
|
-
function DetailRow({ label, value }) {
|
|
361
|
-
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 })] }));
|
|
324
|
+
return (_jsx(BaseDrawer, { open: isOpen, onClose: attemptClose, size: "md", modal: false, header: header, "data-testid": view.type === 'feature' ? 'feature-drawer' : 'repository-drawer', children: body }));
|
|
362
325
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { useFeatureActions, type FeatureActionsInput, type FeatureActionsState, } from './use-feature-actions.js';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,uBAAuB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { useFeatureActions, } from './use-feature-actions.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PhaseTimingData } from '../../../app/actions/get-feature-phase-timings.js';
|
|
2
|
+
export interface ActivityTabProps {
|
|
3
|
+
timings: PhaseTimingData[] | null;
|
|
4
|
+
loading: boolean;
|
|
5
|
+
error: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function ActivityTab({ timings, loading, error }: ActivityTabProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=activity-tab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE/E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AA+CD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,gBAAgB,2CA0DxE"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Loader2, AlertCircle, Clock } from 'lucide-react';
|
|
4
|
+
const NODE_TO_PHASE = {
|
|
5
|
+
analyze: 'Analyzing',
|
|
6
|
+
requirements: 'Requirements',
|
|
7
|
+
research: 'Researching',
|
|
8
|
+
plan: 'Planning',
|
|
9
|
+
implement: 'Implementing',
|
|
10
|
+
merge: 'Merging',
|
|
11
|
+
};
|
|
12
|
+
const LIFECYCLE_EVENTS = {
|
|
13
|
+
'run:started': { label: 'started', colorClass: 'text-blue-600' },
|
|
14
|
+
'run:resumed': { label: 'resumed', colorClass: 'text-blue-600' },
|
|
15
|
+
'run:completed': { label: 'completed', colorClass: 'text-emerald-600' },
|
|
16
|
+
'run:failed': { label: 'failed', colorClass: 'text-red-600' },
|
|
17
|
+
'run:stopped': { label: 'stopped', colorClass: 'text-amber-600' },
|
|
18
|
+
'run:crashed': { label: 'crashed', colorClass: 'text-red-600' },
|
|
19
|
+
};
|
|
20
|
+
function isLifecycleEvent(phase) {
|
|
21
|
+
return phase.startsWith('run:');
|
|
22
|
+
}
|
|
23
|
+
function formatDuration(ms) {
|
|
24
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
25
|
+
}
|
|
26
|
+
function groupTimingsByRun(timings) {
|
|
27
|
+
const groups = [];
|
|
28
|
+
for (const t of timings) {
|
|
29
|
+
const last = groups[groups.length - 1];
|
|
30
|
+
if (last?.runId === t.agentRunId) {
|
|
31
|
+
last.timings.push(t);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
groups.push({ runId: t.agentRunId, timings: [t] });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return groups;
|
|
38
|
+
}
|
|
39
|
+
export function ActivityTab({ timings, loading, error }) {
|
|
40
|
+
if (loading) {
|
|
41
|
+
return (_jsx("div", { "data-testid": "activity-tab-loading", className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
|
|
42
|
+
}
|
|
43
|
+
if (error) {
|
|
44
|
+
return (_jsxs("div", { className: "flex items-center gap-2 p-4 text-sm text-red-600", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0" }), _jsx("span", { children: error })] }));
|
|
45
|
+
}
|
|
46
|
+
if (!timings || timings.length === 0) {
|
|
47
|
+
return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [_jsx(Clock, { className: "text-muted-foreground h-8 w-8" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "No activity recorded yet" })] }));
|
|
48
|
+
}
|
|
49
|
+
const nodeTimings = timings.filter((t) => !isLifecycleEvent(t.phase));
|
|
50
|
+
const maxDurationMs = Math.max(...nodeTimings.map((t) => t.durationMs ?? 0), ...nodeTimings.map((t) => t.approvalWaitMs ?? 0), 0);
|
|
51
|
+
const groups = groupTimingsByRun(timings);
|
|
52
|
+
const multiRun = groups.length > 1;
|
|
53
|
+
const totalExecMs = nodeTimings.reduce((sum, t) => sum + (t.durationMs ?? 0), 0);
|
|
54
|
+
const totalWaitMs = nodeTimings.reduce((sum, t) => sum + (t.approvalWaitMs ?? 0), 0);
|
|
55
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsx("div", { "data-testid": "activity-timings", className: "flex flex-col gap-3", children: groups.map((group, groupIdx) => (_jsx(RunGroup, { group: group, groupIdx: groupIdx, multiRun: multiRun, maxDurationMs: maxDurationMs }, group.runId))) }), totalExecMs > 0 ? (_jsx(SummaryTotals, { totalExecMs: totalExecMs, totalWaitMs: totalWaitMs })) : null] }));
|
|
56
|
+
}
|
|
57
|
+
function RunGroup({ group, groupIdx, multiRun, maxDurationMs, }) {
|
|
58
|
+
return (_jsxs("div", { className: "flex flex-col gap-1.5", children: [multiRun ? (_jsxs("div", { className: "text-muted-foreground text-xs font-medium", children: ["Run #", groupIdx + 1] })) : null, group.timings.map((t) => {
|
|
59
|
+
if (isLifecycleEvent(t.phase)) {
|
|
60
|
+
return _jsx(LifecycleEventRow, { timing: t }, `${t.agentRunId}-${t.phase}-${t.startedAt}`);
|
|
61
|
+
}
|
|
62
|
+
return (_jsx(NodeTimingRow, { timing: t, maxDurationMs: maxDurationMs }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
|
|
63
|
+
})] }));
|
|
64
|
+
}
|
|
65
|
+
function LifecycleEventRow({ timing }) {
|
|
66
|
+
const event = LIFECYCLE_EVENTS[timing.phase];
|
|
67
|
+
if (!event)
|
|
68
|
+
return null;
|
|
69
|
+
return (_jsx("div", { className: `text-xs ${event.colorClass}`, children: _jsx("span", { children: event.label }) }));
|
|
70
|
+
}
|
|
71
|
+
function NodeTimingRow({ timing, maxDurationMs, }) {
|
|
72
|
+
const label = timing.phase.includes(':')
|
|
73
|
+
? `rev ${timing.phase.split(':')[1]}`
|
|
74
|
+
: (NODE_TO_PHASE[timing.phase] ?? timing.phase);
|
|
75
|
+
const durationMs = timing.durationMs ?? 0;
|
|
76
|
+
const barPercent = maxDurationMs > 0 ? Math.max(2, (durationMs / maxDurationMs) * 100) : 2;
|
|
77
|
+
const barColorClass = timing.completedAt ? 'bg-emerald-500' : 'bg-blue-500';
|
|
78
|
+
return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { "data-testid": `timing-bar-${timing.phase}`, className: "flex items-center gap-3", children: [_jsx("span", { className: "text-muted-foreground w-24 shrink-0 text-xs", children: label }), _jsx("div", { className: "bg-muted h-3 flex-1 overflow-hidden rounded-full", children: _jsx("div", { className: `h-full rounded-full ${barColorClass}`, style: { width: `${Math.min(barPercent, 100)}%` } }) }), _jsx("span", { className: "text-muted-foreground w-14 shrink-0 text-right text-xs", children: formatDuration(durationMs) })] }), timing.approvalWaitMs != null && timing.approvalWaitMs > 0 ? (_jsx(ApprovalWaitRow, { timing: timing, maxDurationMs: maxDurationMs })) : null] }));
|
|
79
|
+
}
|
|
80
|
+
function ApprovalWaitRow({ timing, maxDurationMs, }) {
|
|
81
|
+
const waitMs = timing.approvalWaitMs ?? 0;
|
|
82
|
+
const barPercent = maxDurationMs > 0 ? Math.max(2, (waitMs / maxDurationMs) * 100) : 2;
|
|
83
|
+
return (_jsxs("div", { "data-testid": `approval-wait-${timing.phase}`, className: "flex items-center gap-3 pl-4", children: [_jsx("span", { className: "text-muted-foreground w-20 shrink-0 text-xs", children: "approval" }), _jsx("div", { className: "bg-muted h-2.5 flex-1 overflow-hidden rounded-full", children: _jsx("div", { className: "h-full rounded-full bg-amber-500", style: { width: `${Math.min(barPercent, 100)}%` } }) }), _jsx("span", { className: "text-muted-foreground w-14 shrink-0 text-right text-xs", children: formatDuration(waitMs) })] }));
|
|
84
|
+
}
|
|
85
|
+
function SummaryTotals({ totalExecMs, totalWaitMs }) {
|
|
86
|
+
return (_jsxs("div", { "data-testid": "activity-summary", className: "border-border flex flex-col gap-1.5 border-t pt-3", children: [_jsx(SummaryRow, { label: "Total execution", value: formatDuration(totalExecMs) }), totalWaitMs > 0 ? (_jsxs(_Fragment, { children: [_jsx(SummaryRow, { label: "Total wait", value: formatDuration(totalWaitMs) }), _jsx(SummaryRow, { label: "Total wall-clock", value: formatDuration(totalExecMs + totalWaitMs) })] })) : null] }));
|
|
87
|
+
}
|
|
88
|
+
function SummaryRow({ label, value }) {
|
|
89
|
+
return (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: label }), _jsx("span", { className: "text-xs font-medium", children: value })] }));
|
|
90
|
+
}
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { ActivityTab } from './activity-tab.js';
|
|
3
|
+
declare const meta: Meta<typeof ActivityTab>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof ActivityTab>;
|
|
6
|
+
/** Default — single run with complete phase timings and approval waits. */
|
|
7
|
+
export declare const Default: Story;
|
|
8
|
+
/** Multiple runs with run headers showing grouping. */
|
|
9
|
+
export declare const MultipleRuns: Story;
|
|
10
|
+
/** Running phase — a phase without completedAt shows blue bar. */
|
|
11
|
+
export declare const RunningPhase: Story;
|
|
12
|
+
/** Loading state — spinner displayed while data is being fetched. */
|
|
13
|
+
export declare const Loading: Story;
|
|
14
|
+
/** Empty state — no activity recorded yet. */
|
|
15
|
+
export declare const Empty: Story;
|
|
16
|
+
/** Error state — inline error message. */
|
|
17
|
+
export declare const Error: Story;
|
|
18
|
+
/** Approval wait indicators — phases with approval wait sub-rows. */
|
|
19
|
+
export declare const WithApprovalWaits: Story;
|
|
20
|
+
//# sourceMappingURL=activity-tab.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAclC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AAmK1C,2EAA2E;AAC3E,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,EAAE,KAgC/B,CAAC"}
|