@shepai/cli 1.70.2 → 1.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/core/src/application/ports/output/services/deployment-service.interface.d.ts +32 -0
- package/dist/packages/core/src/application/ports/output/services/deployment-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts +16 -2
- package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.js +46 -9
- package/dist/packages/core/src/infrastructure/services/deployment/log-ring-buffer.d.ts +23 -0
- package/dist/packages/core/src/infrastructure/services/deployment/log-ring-buffer.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/deployment/log-ring-buffer.js +46 -0
- package/dist/src/presentation/web/app/actions/get-deployment-logs.d.ts +3 -0
- package/dist/src/presentation/web/app/actions/get-deployment-logs.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/get-deployment-logs.js +9 -0
- package/dist/src/presentation/web/app/actions/get-feature-artifact.d.ts +2 -0
- package/dist/src/presentation/web/app/actions/get-feature-artifact.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/get-feature-artifact.js +23 -1
- package/dist/src/presentation/web/app/api/deployment-logs/route.d.ts +15 -0
- package/dist/src/presentation/web/app/api/deployment-logs/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/deployment-logs/route.js +94 -0
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.js +33 -3
- package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.d.ts +2 -1
- package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.js +16 -5
- package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.d.ts +4 -0
- package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.js +8 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/index.d.ts +3 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/index.js +1 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary-config.d.ts +23 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary-config.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary-config.js +1 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.d.ts +3 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.js +13 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.stories.d.ts +14 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.stories.js +74 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.js +1 -1
- package/dist/src/presentation/web/components/common/server-log-viewer/index.d.ts +2 -0
- package/dist/src/presentation/web/components/common/server-log-viewer/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/server-log-viewer/index.js +1 -0
- package/dist/src/presentation/web/components/common/server-log-viewer/server-log-viewer.d.ts +15 -0
- package/dist/src/presentation/web/components/common/server-log-viewer/server-log-viewer.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/server-log-viewer/server-log-viewer.js +31 -0
- package/dist/src/presentation/web/components/common/server-log-viewer/server-log-viewer.stories.d.ts +18 -0
- package/dist/src/presentation/web/components/common/server-log-viewer/server-log-viewer.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/server-log-viewer/server-log-viewer.stories.js +113 -0
- package/dist/src/presentation/web/components/common/tech-decisions-review/index.d.ts +1 -1
- 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 +1 -1
- package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.d.ts +8 -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 +11 -2
- package/dist/src/presentation/web/components/common/tech-review-tabs/index.d.ts +3 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/index.js +1 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.d.ts +17 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.js +1 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.d.ts +3 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.js +12 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.stories.d.ts +16 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.stories.js +110 -0
- package/dist/src/presentation/web/hooks/use-deployment-logs.d.ts +7 -0
- package/dist/src/presentation/web/hooks/use-deployment-logs.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/use-deployment-logs.js +50 -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/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/routes-manifest.json +6 -0
- 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.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/deployment-logs/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/deployment-logs/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/deployment-logs/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/deployment-logs/route.js +6 -0
- package/web/.next/server/app/api/deployment-logs/route.js.map +5 -0
- package/web/.next/server/app/api/deployment-logs/route.js.nft.json +1 -0
- package/web/.next/server/app/api/deployment-logs/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/tools/[id]/install/route.js +1 -1
- package/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -1
- package/web/.next/server/app/page/server-reference-manifest.json +51 -36
- 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/server-reference-manifest.json +25 -10
- package/web/.next/server/app/skills/page.js +1 -1
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page.js +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/app-paths-manifest.json +1 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_deployment-logs_route_actions_b785cd3a.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_deployment-logs_route_actions_b785cd3a.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__9a136c79._.js +9 -0
- package/web/.next/server/chunks/[root-of-the-server]__9a136c79._.js.map +1 -0
- package/web/.next/server/chunks/{[root-of-the-server]__09413611._.js → [root-of-the-server]__e926de65._.js} +2 -2
- package/web/.next/server/chunks/{[root-of-the-server]__09413611._.js.map → [root-of-the-server]__e926de65._.js.map} +1 -1
- 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]__5f968713._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5f968713._.js.map +1 -0
- 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]__249c74f6._.js → [root-of-the-server]__6e8b5181._.js} +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__970ba1be._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__970ba1be._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__97a1f9c2._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__97a1f9c2._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +2 -2
- 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]__ad7c18fa._.js +9 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ad7c18fa._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b22d8535._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b22d8535._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_25e0eb34._.js +3 -0
- package/web/.next/server/chunks/ssr/_25e0eb34._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_49bf495c._.js +1 -1
- package/web/.next/server/chunks/ssr/_49bf495c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_68b5e0de._.js +1 -1
- package/web/.next/server/chunks/ssr/_68b5e0de._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_725584e5._.js +1 -1
- package/web/.next/server/chunks/ssr/_725584e5._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_72ce07df._.js +3 -0
- package/web/.next/server/chunks/ssr/_72ce07df._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{node_modules__pnpm_febcbea6._.js → node_modules__pnpm_3288606c._.js} +2 -2
- package/web/.next/server/chunks/ssr/{node_modules__pnpm_febcbea6._.js.map → node_modules__pnpm_3288606c._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_5124369c._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_5124369c._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_tabs_tsx_b226ea9b._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_tabs_tsx_b226ea9b._.js.map +1 -0
- 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 +64 -42
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/app-path-routes-manifest.json +1 -0
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/routes-manifest.json +6 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.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/api/deployment-logs/route/app-paths-manifest.json +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/deployment-logs/route/build-manifest.json +11 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/deployment-logs/route/server-reference-manifest.json +4 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/deployment-logs/route.js +6 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/deployment-logs/route.js.map +5 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/deployment-logs/route.js.nft.json +1 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/deployment-logs/route_client-reference-manifest.js +2 -0
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +51 -36
- 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/server-reference-manifest.json +25 -10
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js +1 -1
- 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/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/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js +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/app-paths-manifest.json +1 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/744ca_web__next-internal_server_app_api_deployment-logs_route_actions_b785cd3a.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/[root-of-the-server]__9a136c79._.js +9 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/{[root-of-the-server]__09413611._.js → [root-of-the-server]__e926de65._.js} +2 -2
- 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]__5f968713._.js +3 -0
- 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]__249c74f6._.js → [root-of-the-server]__6e8b5181._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__970ba1be._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__97a1f9c2._.js +4 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__ad7c18fa._.js +9 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__b22d8535._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_25e0eb34._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_49bf495c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_68b5e0de._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_725584e5._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_72ce07df._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{node_modules__pnpm_febcbea6._.js → node_modules__pnpm_3288606c._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_5124369c._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_ui_tabs_tsx_b226ea9b._.js +3 -0
- 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 +64 -42
- package/web/.next/standalone/src/presentation/web/app/actions/get-deployment-logs.ts +16 -0
- package/web/.next/standalone/src/presentation/web/app/actions/get-feature-artifact.ts +26 -1
- package/web/.next/standalone/src/presentation/web/app/api/deployment-logs/route.ts +112 -0
- package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx +5 -1
- package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.tsx +42 -4
- package/web/.next/standalone/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.stories.tsx +10 -0
- package/web/.next/standalone/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.tsx +76 -23
- package/web/.next/standalone/src/presentation/web/components/common/product-decisions-summary/index.ts +6 -0
- package/web/.next/standalone/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary-config.ts +24 -0
- package/web/.next/standalone/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.stories.tsx +87 -0
- package/web/.next/standalone/src/presentation/web/components/common/product-decisions-summary/product-decisions-summary.tsx +52 -0
- package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-node.tsx +5 -1
- package/web/.next/standalone/src/presentation/web/components/common/server-log-viewer/index.ts +6 -0
- package/web/.next/standalone/src/presentation/web/components/common/server-log-viewer/server-log-viewer.stories.tsx +168 -0
- package/web/.next/standalone/src/presentation/web/components/common/server-log-viewer/server-log-viewer.tsx +110 -0
- package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/index.ts +1 -1
- package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.tsx +46 -28
- package/web/.next/standalone/src/presentation/web/components/common/tech-review-tabs/index.ts +2 -0
- package/web/.next/standalone/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.ts +17 -0
- package/web/.next/standalone/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.stories.tsx +129 -0
- package/web/.next/standalone/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.tsx +60 -0
- package/web/.next/standalone/src/presentation/web/hooks/use-deployment-logs.ts +67 -0
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/01ae2241bd4b44b6.js +1 -0
- package/web/.next/static/chunks/20f7876f292cfd82.js +1 -0
- package/web/.next/static/chunks/224ed5f5dbd33154.css +2 -0
- package/web/.next/static/chunks/{87421ab1062a39b7.js → 3e1227e02ef8bcc6.js} +2 -2
- package/web/.next/static/chunks/{2eae41f87676d999.js → 62c8ebbd9c7bb287.js} +1 -1
- package/web/.next/static/chunks/673e0c1000a91948.js +1 -0
- package/web/.next/static/chunks/8b6df4f8e194d0ce.js +1 -0
- package/web/.next/static/chunks/b025563d959150a1.js +1 -0
- package/web/.next/static/chunks/{09e70c24eceecf48.js → c7fb052190a02a9c.js} +2 -2
- package/web/.next/static/chunks/d450d8db6be36b8d.js +1 -0
- package/web/.next/static/chunks/d9e3cf214ac2f386.js +1 -0
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/types/link.d.ts +1 -0
- package/web/.next/types/routes.d.ts +2 -1
- package/web/.next/types/validator.ts +9 -0
- package/web/.next/server/chunks/ssr/6769f_@radix-ui_react-roving-focus_dist_index_mjs_b3be3d8e._.js +0 -3
- package/web/.next/server/chunks/ssr/6769f_@radix-ui_react-roving-focus_dist_index_mjs_b3be3d8e._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2ffb27f1._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2ffb27f1._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7f4180a1._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7f4180a1._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e41b5eec._.js +0 -9
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e41b5eec._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__eaf6100f._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__eaf6100f._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_28993370._.js +0 -3
- package/web/.next/server/chunks/ssr/_28993370._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_690ea95f._.js +0 -3
- package/web/.next/server/chunks/ssr/_690ea95f._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_0286756b._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_components_0286756b._.js.map +0 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/6769f_@radix-ui_react-roving-focus_dist_index_mjs_b3be3d8e._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2ffb27f1._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js +0 -4
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__7f4180a1._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__e41b5eec._.js +0 -9
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__eaf6100f._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_28993370._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_690ea95f._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_0286756b._.js +0 -3
- package/web/.next/static/chunks/4b357783626e0916.js +0 -1
- package/web/.next/static/chunks/505c6a9e4c5d0808.js +0 -1
- package/web/.next/static/chunks/a186bbb822ccb655.css +0 -2
- package/web/.next/static/chunks/a5c59952485e875e.js +0 -1
- package/web/.next/static/chunks/a9626385607910b3.js +0 -1
- package/web/.next/static/chunks/b581320ecaa97e4a.js +0 -1
- package/web/.next/static/chunks/d4379644a6145352.js +0 -1
- package/web/.next/static/chunks/fb703cf73aba2eb8.js +0 -1
- /package/web/.next/server/chunks/ssr/{[root-of-the-server]__249c74f6._.js.map → [root-of-the-server]__6e8b5181._.js.map} +0 -0
- /package/web/.next/static/{MoPU_ZZ5QcyEys7Gfl_6r → F3mdpVVEgR5m2xHY_SnYx}/_buildManifest.js +0 -0
- /package/web/.next/static/{MoPU_ZZ5QcyEys7Gfl_6r → F3mdpVVEgR5m2xHY_SnYx}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{MoPU_ZZ5QcyEys7Gfl_6r → F3mdpVVEgR5m2xHY_SnYx}/_ssgManifest.js +0 -0
package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx
CHANGED
|
@@ -156,7 +156,11 @@ function DeployBar({ deployTarget }: { deployTarget: DeployActionInput }) {
|
|
|
156
156
|
</Tooltip>
|
|
157
157
|
</TooltipProvider>
|
|
158
158
|
{isDeploymentActive ? (
|
|
159
|
-
<DeploymentStatusBadge
|
|
159
|
+
<DeploymentStatusBadge
|
|
160
|
+
status={deployAction.status}
|
|
161
|
+
url={deployAction.url}
|
|
162
|
+
targetId={deployTarget.targetId}
|
|
163
|
+
/>
|
|
160
164
|
) : null}
|
|
161
165
|
</div>
|
|
162
166
|
);
|
|
@@ -51,7 +51,8 @@ import { ActionButton } from '@/components/common/action-button';
|
|
|
51
51
|
import { OpenActionMenu } from '@/components/common/open-action-menu';
|
|
52
52
|
import { FeatureCreateDrawer } from '@/components/common/feature-create-drawer';
|
|
53
53
|
import { PrdQuestionnaire } from '@/components/common/prd-questionnaire';
|
|
54
|
-
import {
|
|
54
|
+
import { TechReviewTabs } from '@/components/common/tech-review-tabs';
|
|
55
|
+
import type { ProductDecisionsSummaryData } from '@/components/common/product-decisions-summary';
|
|
55
56
|
import { MergeReview } from '@/components/common/merge-review';
|
|
56
57
|
import { featureNodeStateConfig, lifecycleDisplayLabels } from '@/components/common/feature-node';
|
|
57
58
|
import type { FeatureNodeData } from '@/components/common/feature-node';
|
|
@@ -89,6 +90,12 @@ export function ControlCenterDrawer({
|
|
|
89
90
|
const [techData, setTechData] = useState<TechDecisionsReviewData | null>(null);
|
|
90
91
|
const [isLoadingTech, setIsLoadingTech] = useState(false);
|
|
91
92
|
|
|
93
|
+
// ── Product decisions state (for tech review Product tab) ─────────────
|
|
94
|
+
const [techProductData, setTechProductData] = useState<
|
|
95
|
+
ProductDecisionsSummaryData | null | undefined
|
|
96
|
+
>(undefined);
|
|
97
|
+
const [isLoadingTechProduct, setIsLoadingTechProduct] = useState(false);
|
|
98
|
+
|
|
92
99
|
// ── Merge review state ──────────────────────────────────────────────────
|
|
93
100
|
const [mergeData, setMergeData] = useState<MergeReviewData | null>(null);
|
|
94
101
|
const [isLoadingMerge, setIsLoadingMerge] = useState(false);
|
|
@@ -162,6 +169,32 @@ export function ControlCenterDrawer({
|
|
|
162
169
|
};
|
|
163
170
|
}, [techFeatureId]);
|
|
164
171
|
|
|
172
|
+
// Fetch product decisions for the Product tab in tech review
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
setTechProductData(undefined);
|
|
175
|
+
if (!techFeatureId) return;
|
|
176
|
+
|
|
177
|
+
let cancelled = false;
|
|
178
|
+
setIsLoadingTechProduct(true);
|
|
179
|
+
getFeatureArtifact(techFeatureId)
|
|
180
|
+
.then((result) => {
|
|
181
|
+
if (cancelled) return;
|
|
182
|
+
if (result.productDecisions) {
|
|
183
|
+
setTechProductData(result.productDecisions);
|
|
184
|
+
}
|
|
185
|
+
// Silent failure — product tab shows "not available"
|
|
186
|
+
})
|
|
187
|
+
.catch(() => {
|
|
188
|
+
// Silent failure — the product tab is supplementary
|
|
189
|
+
})
|
|
190
|
+
.finally(() => {
|
|
191
|
+
if (!cancelled) setIsLoadingTechProduct(false);
|
|
192
|
+
});
|
|
193
|
+
return () => {
|
|
194
|
+
cancelled = true;
|
|
195
|
+
};
|
|
196
|
+
}, [techFeatureId]);
|
|
197
|
+
|
|
165
198
|
const mergeFeatureId = view?.type === 'merge-review' ? view.node.featureId : null;
|
|
166
199
|
useEffect(() => {
|
|
167
200
|
setMergeData(null);
|
|
@@ -381,7 +414,11 @@ export function ControlCenterDrawer({
|
|
|
381
414
|
</Tooltip>
|
|
382
415
|
</TooltipProvider>
|
|
383
416
|
{isFeatureDeployActive ? (
|
|
384
|
-
<DeploymentStatusBadge
|
|
417
|
+
<DeploymentStatusBadge
|
|
418
|
+
status={deployAction.status}
|
|
419
|
+
url={deployAction.url}
|
|
420
|
+
targetId={featureDeployTarget?.targetId}
|
|
421
|
+
/>
|
|
385
422
|
) : null}
|
|
386
423
|
</>
|
|
387
424
|
) : null}
|
|
@@ -508,8 +545,9 @@ export function ControlCenterDrawer({
|
|
|
508
545
|
);
|
|
509
546
|
} else if (view?.type === 'tech-review') {
|
|
510
547
|
body = techData ? (
|
|
511
|
-
<
|
|
512
|
-
|
|
548
|
+
<TechReviewTabs
|
|
549
|
+
techData={techData}
|
|
550
|
+
productData={isLoadingTechProduct ? null : techProductData}
|
|
513
551
|
onApprove={handleTechApprove}
|
|
514
552
|
onReject={handleTechReject}
|
|
515
553
|
isProcessing={isLoadingTech}
|
|
@@ -33,3 +33,13 @@ export const Stopped: Story = {
|
|
|
33
33
|
export const NoDeployment: Story = {
|
|
34
34
|
args: { status: null },
|
|
35
35
|
};
|
|
36
|
+
|
|
37
|
+
/** Booting with View Logs button — shows log button next to spinner. */
|
|
38
|
+
export const BootingWithLogs: Story = {
|
|
39
|
+
args: { status: DeploymentState.Booting, targetId: 'demo-target' },
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Ready with View Logs button — shows URL and log button. */
|
|
43
|
+
export const ReadyWithLogs: Story = {
|
|
44
|
+
args: { status: DeploymentState.Ready, url: 'http://localhost:3000', targetId: 'demo-target' },
|
|
45
|
+
};
|
|
@@ -1,40 +1,93 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { Loader2, ExternalLink, Terminal } from 'lucide-react';
|
|
2
5
|
import { DeploymentState } from '@shepai/core/domain/generated/output';
|
|
3
6
|
import { Badge } from '@/components/ui/badge';
|
|
7
|
+
import { ServerLogViewer } from '@/components/common/server-log-viewer';
|
|
4
8
|
|
|
5
9
|
export interface DeploymentStatusBadgeProps {
|
|
6
10
|
status: DeploymentState | null;
|
|
7
11
|
url?: string | null;
|
|
12
|
+
targetId?: string;
|
|
8
13
|
}
|
|
9
14
|
|
|
10
|
-
export function DeploymentStatusBadge({ status, url }: DeploymentStatusBadgeProps) {
|
|
15
|
+
export function DeploymentStatusBadge({ status, url, targetId }: DeploymentStatusBadgeProps) {
|
|
16
|
+
const [logViewerOpen, setLogViewerOpen] = useState(false);
|
|
17
|
+
const showLogButton =
|
|
18
|
+
targetId && (status === DeploymentState.Booting || status === DeploymentState.Ready);
|
|
19
|
+
|
|
11
20
|
switch (status) {
|
|
12
21
|
case DeploymentState.Booting:
|
|
13
22
|
return (
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
<>
|
|
24
|
+
<Badge className="border-transparent bg-blue-50 text-blue-700 hover:bg-blue-50">
|
|
25
|
+
<Loader2 className="mr-1 h-3.5 w-3.5 animate-spin" />
|
|
26
|
+
Starting...
|
|
27
|
+
{showLogButton ? (
|
|
28
|
+
<button
|
|
29
|
+
type="button"
|
|
30
|
+
aria-label="View server logs"
|
|
31
|
+
className="ml-1.5 inline-flex items-center rounded-sm p-0.5 hover:bg-blue-100"
|
|
32
|
+
onClick={(e) => {
|
|
33
|
+
e.stopPropagation();
|
|
34
|
+
setLogViewerOpen(true);
|
|
35
|
+
}}
|
|
36
|
+
>
|
|
37
|
+
<Terminal className="h-3 w-3" />
|
|
38
|
+
</button>
|
|
39
|
+
) : null}
|
|
40
|
+
</Badge>
|
|
41
|
+
{showLogButton ? (
|
|
42
|
+
<ServerLogViewer
|
|
43
|
+
open={logViewerOpen}
|
|
44
|
+
onOpenChange={setLogViewerOpen}
|
|
45
|
+
targetId={targetId}
|
|
46
|
+
/>
|
|
47
|
+
) : null}
|
|
48
|
+
</>
|
|
18
49
|
);
|
|
19
50
|
case DeploymentState.Ready:
|
|
20
51
|
return (
|
|
21
|
-
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
52
|
+
<>
|
|
53
|
+
<Badge className="border-transparent bg-green-50 text-green-700 hover:bg-green-50">
|
|
54
|
+
<span className="mr-1 inline-block h-2 w-2 rounded-full bg-green-500" />
|
|
55
|
+
{url ? (
|
|
56
|
+
<a
|
|
57
|
+
href={url}
|
|
58
|
+
target="_blank"
|
|
59
|
+
rel="noopener noreferrer"
|
|
60
|
+
className="inline-flex items-center gap-1 hover:underline"
|
|
61
|
+
onClick={(e) => e.stopPropagation()}
|
|
62
|
+
>
|
|
63
|
+
{url}
|
|
64
|
+
<ExternalLink className="h-3 w-3" />
|
|
65
|
+
</a>
|
|
66
|
+
) : (
|
|
67
|
+
'Ready'
|
|
68
|
+
)}
|
|
69
|
+
{showLogButton ? (
|
|
70
|
+
<button
|
|
71
|
+
type="button"
|
|
72
|
+
aria-label="View server logs"
|
|
73
|
+
className="ml-1.5 inline-flex items-center rounded-sm p-0.5 hover:bg-green-100"
|
|
74
|
+
onClick={(e) => {
|
|
75
|
+
e.stopPropagation();
|
|
76
|
+
setLogViewerOpen(true);
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
<Terminal className="h-3 w-3" />
|
|
80
|
+
</button>
|
|
81
|
+
) : null}
|
|
82
|
+
</Badge>
|
|
83
|
+
{showLogButton ? (
|
|
84
|
+
<ServerLogViewer
|
|
85
|
+
open={logViewerOpen}
|
|
86
|
+
onOpenChange={setLogViewerOpen}
|
|
87
|
+
targetId={targetId}
|
|
88
|
+
/>
|
|
89
|
+
) : null}
|
|
90
|
+
</>
|
|
38
91
|
);
|
|
39
92
|
default:
|
|
40
93
|
return null;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface ProductDecisionItem {
|
|
2
|
+
/** Question text */
|
|
3
|
+
question: string;
|
|
4
|
+
/** The selected option label */
|
|
5
|
+
selectedOption: string;
|
|
6
|
+
/** Rationale for the selected option */
|
|
7
|
+
rationale: string;
|
|
8
|
+
/** Whether it was the AI-recommended option */
|
|
9
|
+
wasRecommended: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ProductDecisionsSummaryData {
|
|
13
|
+
/** Goal/title from the PRD */
|
|
14
|
+
question: string;
|
|
15
|
+
/** Context description (one-liner) */
|
|
16
|
+
context: string;
|
|
17
|
+
/** Resolved questions with selected options */
|
|
18
|
+
questions: ProductDecisionItem[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ProductDecisionsSummaryProps {
|
|
22
|
+
/** Product decisions data from the feature artifact */
|
|
23
|
+
data: ProductDecisionsSummaryData;
|
|
24
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { ProductDecisionsSummary } from './product-decisions-summary';
|
|
3
|
+
import type { ProductDecisionsSummaryData } from './product-decisions-summary-config';
|
|
4
|
+
|
|
5
|
+
const mockData: ProductDecisionsSummaryData = {
|
|
6
|
+
question: 'Goal',
|
|
7
|
+
context: 'Add user authentication to the application',
|
|
8
|
+
questions: [
|
|
9
|
+
{
|
|
10
|
+
question: 'Which authentication strategy should we use?',
|
|
11
|
+
selectedOption: 'OAuth 2.0',
|
|
12
|
+
rationale: 'Industry standard with broad provider support and well-maintained libraries.',
|
|
13
|
+
wasRecommended: true,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
question: 'How should we handle session management?',
|
|
17
|
+
selectedOption: 'JWT tokens',
|
|
18
|
+
rationale: 'Stateless and scalable across services without shared session storage.',
|
|
19
|
+
wasRecommended: false,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
question: 'What level of MFA should we support?',
|
|
23
|
+
selectedOption: 'Optional TOTP',
|
|
24
|
+
rationale: 'Balances security with user convenience. Power users can opt in.',
|
|
25
|
+
wasRecommended: true,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
question: 'Where should we store user profiles?',
|
|
29
|
+
selectedOption: 'PostgreSQL',
|
|
30
|
+
rationale: 'Relational data model fits well for user attributes and relationships.',
|
|
31
|
+
wasRecommended: false,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const meta: Meta<typeof ProductDecisionsSummary> = {
|
|
37
|
+
title: 'Drawers/Review/ProductDecisionsSummary',
|
|
38
|
+
component: ProductDecisionsSummary,
|
|
39
|
+
tags: ['autodocs'],
|
|
40
|
+
parameters: {
|
|
41
|
+
layout: 'fullscreen',
|
|
42
|
+
},
|
|
43
|
+
decorators: [
|
|
44
|
+
(Story) => (
|
|
45
|
+
<div style={{ height: '600px', width: '400px', border: '1px solid var(--color-border)' }}>
|
|
46
|
+
<Story />
|
|
47
|
+
</div>
|
|
48
|
+
),
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default meta;
|
|
53
|
+
type Story = StoryObj<typeof ProductDecisionsSummary>;
|
|
54
|
+
|
|
55
|
+
/** Default — multiple product decisions with a mix of recommended and non-recommended. */
|
|
56
|
+
export const Default: Story = {
|
|
57
|
+
args: {
|
|
58
|
+
data: mockData,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/** Single question. */
|
|
63
|
+
export const SingleQuestion: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
data: { ...mockData, questions: [mockData.questions[0]] },
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** All recommended — every option was the AI-recommended choice. */
|
|
70
|
+
export const AllRecommended: Story = {
|
|
71
|
+
args: {
|
|
72
|
+
data: {
|
|
73
|
+
...mockData,
|
|
74
|
+
questions: mockData.questions.map((q) => ({ ...q, wasRecommended: true })),
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/** No recommended badges — none of the selected options were AI-recommended. */
|
|
80
|
+
export const NoneRecommended: Story = {
|
|
81
|
+
args: {
|
|
82
|
+
data: {
|
|
83
|
+
...mockData,
|
|
84
|
+
questions: mockData.questions.map((q) => ({ ...q, wasRecommended: false })),
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { ClipboardList } from 'lucide-react';
|
|
4
|
+
import { Badge } from '@/components/ui/badge';
|
|
5
|
+
import type {
|
|
6
|
+
ProductDecisionsSummaryProps,
|
|
7
|
+
ProductDecisionItem,
|
|
8
|
+
} from './product-decisions-summary-config';
|
|
9
|
+
|
|
10
|
+
function ProductDecisionCard({ item, index }: { item: ProductDecisionItem; index: number }) {
|
|
11
|
+
return (
|
|
12
|
+
<div className="border-border rounded-lg border">
|
|
13
|
+
<div className="space-y-2 px-4 py-3">
|
|
14
|
+
<div className="flex items-start gap-2.5">
|
|
15
|
+
<span className="bg-primary text-primary-foreground flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold">
|
|
16
|
+
{index + 1}
|
|
17
|
+
</span>
|
|
18
|
+
<div className="min-w-0 flex-1">
|
|
19
|
+
<h3 className="text-foreground text-sm leading-tight font-semibold">{item.question}</h3>
|
|
20
|
+
<div className="mt-1 flex items-center gap-2">
|
|
21
|
+
<p className="text-muted-foreground text-xs">{item.selectedOption}</p>
|
|
22
|
+
{item.wasRecommended ? (
|
|
23
|
+
<Badge className="px-1.5 py-0 text-[10px]">AI Recommended</Badge>
|
|
24
|
+
) : null}
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function ProductDecisionsSummary({ data }: ProductDecisionsSummaryProps) {
|
|
34
|
+
const { questions } = data;
|
|
35
|
+
|
|
36
|
+
if (questions.length === 0) return null;
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div className="space-y-4 p-4">
|
|
40
|
+
{/* Section heading */}
|
|
41
|
+
<div className="flex items-center gap-2">
|
|
42
|
+
<ClipboardList className="text-primary h-4 w-4" />
|
|
43
|
+
<h3 className="text-foreground text-sm font-bold">Product Decisions</h3>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
{/* Decision cards */}
|
|
47
|
+
{questions.map((item, i) => (
|
|
48
|
+
<ProductDecisionCard key={item.question} item={item} index={i} />
|
|
49
|
+
))}
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -206,7 +206,11 @@ export function RepositoryNode({ data }: { data: RepositoryNodeData; [key: strin
|
|
|
206
206
|
</Tooltip>
|
|
207
207
|
</TooltipProvider>
|
|
208
208
|
{isDeploymentActive ? (
|
|
209
|
-
<DeploymentStatusBadge
|
|
209
|
+
<DeploymentStatusBadge
|
|
210
|
+
status={deployAction.status}
|
|
211
|
+
url={deployAction.url}
|
|
212
|
+
targetId={data.repositoryPath}
|
|
213
|
+
/>
|
|
210
214
|
) : null}
|
|
211
215
|
</>
|
|
212
216
|
) : null}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import type { LogEntry } from '@shepai/core/application/ports/output/services/deployment-service.interface';
|
|
4
|
+
import { ServerLogViewerContent } from './server-log-viewer';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof ServerLogViewerContent> = {
|
|
7
|
+
title: 'Common/ServerLogViewer',
|
|
8
|
+
component: ServerLogViewerContent,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'fullscreen',
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
type Story = StoryObj<typeof ServerLogViewerContent>;
|
|
17
|
+
|
|
18
|
+
function makeLog(line: string, stream: 'stdout' | 'stderr' = 'stdout', offsetMs = 0): LogEntry {
|
|
19
|
+
return {
|
|
20
|
+
targetId: 'story-target',
|
|
21
|
+
stream,
|
|
22
|
+
line,
|
|
23
|
+
timestamp: Date.now() + offsetMs,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function InteractiveWrapper({ logs, isConnected }: { logs: LogEntry[]; isConnected: boolean }) {
|
|
28
|
+
const [open, setOpen] = useState(true);
|
|
29
|
+
return (
|
|
30
|
+
<ServerLogViewerContent
|
|
31
|
+
open={open}
|
|
32
|
+
onOpenChange={setOpen}
|
|
33
|
+
logs={logs}
|
|
34
|
+
isConnected={isConnected}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Empty state — no log output yet. */
|
|
40
|
+
export const Empty: Story = {
|
|
41
|
+
render: () => <InteractiveWrapper logs={[]} isConnected={true} />,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/** A few stdout-only lines. */
|
|
45
|
+
export const FewLines: Story = {
|
|
46
|
+
render: () => (
|
|
47
|
+
<InteractiveWrapper
|
|
48
|
+
logs={[
|
|
49
|
+
makeLog('$ npm run dev', 'stdout', 0),
|
|
50
|
+
makeLog('', 'stdout', 10),
|
|
51
|
+
makeLog('> my-app@1.0.0 dev', 'stdout', 20),
|
|
52
|
+
makeLog('> next dev', 'stdout', 30),
|
|
53
|
+
makeLog('', 'stdout', 40),
|
|
54
|
+
makeLog(' ▲ Next.js 14.2.3', 'stdout', 50),
|
|
55
|
+
makeLog(' - Local: http://localhost:3000', 'stdout', 60),
|
|
56
|
+
makeLog(' - Environments: .env.local', 'stdout', 70),
|
|
57
|
+
makeLog('', 'stdout', 80),
|
|
58
|
+
makeLog(' ✓ Ready in 1.2s', 'stdout', 90),
|
|
59
|
+
]}
|
|
60
|
+
isConnected={true}
|
|
61
|
+
/>
|
|
62
|
+
),
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** Interleaved stdout and stderr showing color differentiation. */
|
|
66
|
+
export const MixedOutput: Story = {
|
|
67
|
+
render: () => (
|
|
68
|
+
<InteractiveWrapper
|
|
69
|
+
logs={[
|
|
70
|
+
makeLog('$ npm run dev', 'stdout', 0),
|
|
71
|
+
makeLog('> next dev', 'stdout', 10),
|
|
72
|
+
makeLog(' ▲ Next.js 14.2.3', 'stdout', 20),
|
|
73
|
+
makeLog(
|
|
74
|
+
'(node:12345) [DEP0040] DeprecationWarning: The punycode module is deprecated.',
|
|
75
|
+
'stderr',
|
|
76
|
+
30
|
|
77
|
+
),
|
|
78
|
+
makeLog('Use `node:punycode` instead.', 'stderr', 31),
|
|
79
|
+
makeLog(' - Local: http://localhost:3000', 'stdout', 40),
|
|
80
|
+
makeLog(' ✓ Ready in 1.8s', 'stdout', 50),
|
|
81
|
+
makeLog(' ○ Compiling /page ...', 'stdout', 100),
|
|
82
|
+
makeLog(' ✓ Compiled /page in 342ms', 'stdout', 200),
|
|
83
|
+
makeLog('GET / 200 in 412ms', 'stdout', 300),
|
|
84
|
+
makeLog('Warning: Each child in a list should have a unique "key" prop.', 'stderr', 310),
|
|
85
|
+
makeLog('GET /api/data 200 in 23ms', 'stdout', 400),
|
|
86
|
+
makeLog('GET /favicon.ico 304 in 2ms', 'stdout', 410),
|
|
87
|
+
makeLog("Error: ENOENT: no such file or directory, open '/tmp/cache.json'", 'stderr', 500),
|
|
88
|
+
makeLog('GET /api/users 500 in 156ms', 'stdout', 510),
|
|
89
|
+
]}
|
|
90
|
+
isConnected={true}
|
|
91
|
+
/>
|
|
92
|
+
),
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/** 100+ lines demonstrating scrollable content. */
|
|
96
|
+
export const ManyLines: Story = {
|
|
97
|
+
render: () => {
|
|
98
|
+
const logs: LogEntry[] = [];
|
|
99
|
+
logs.push(makeLog('$ npm run dev', 'stdout', 0));
|
|
100
|
+
logs.push(makeLog('> next dev', 'stdout', 10));
|
|
101
|
+
logs.push(makeLog(' ✓ Ready in 1.2s', 'stdout', 20));
|
|
102
|
+
for (let i = 0; i < 120; i++) {
|
|
103
|
+
const method = ['GET', 'POST', 'PUT', 'DELETE'][i % 4];
|
|
104
|
+
const path = ['/api/users', '/api/features', '/api/repos', '/api/deploy'][i % 4];
|
|
105
|
+
const status = i % 15 === 0 ? 500 : i % 7 === 0 ? 404 : 200;
|
|
106
|
+
const ms = Math.floor(Math.random() * 500) + 5;
|
|
107
|
+
const stream: 'stdout' | 'stderr' = status >= 500 ? 'stderr' : 'stdout';
|
|
108
|
+
logs.push(makeLog(`${method} ${path}/${i} ${status} in ${ms}ms`, stream, 100 + i * 10));
|
|
109
|
+
}
|
|
110
|
+
return <InteractiveWrapper logs={logs} isConnected={true} />;
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/** Lines exceeding viewport width showing wrap behavior. */
|
|
115
|
+
export const LongLines: Story = {
|
|
116
|
+
render: () => (
|
|
117
|
+
<InteractiveWrapper
|
|
118
|
+
logs={[
|
|
119
|
+
makeLog('Short line', 'stdout', 0),
|
|
120
|
+
makeLog(
|
|
121
|
+
"Error: Module not found: Can't resolve '@/components/features/really-long-component-name/that-goes-on-and-on/sub-component/deeply-nested-module/index.tsx' in '/Users/developer/projects/my-very-long-project-name/src/presentation/web/components/features'",
|
|
122
|
+
'stderr',
|
|
123
|
+
10
|
|
124
|
+
),
|
|
125
|
+
makeLog(
|
|
126
|
+
'at Object.resolve (webpack://my-app/node_modules/enhanced-resolve/lib/Resolver.js?:331:11) at Object.resolve (webpack://my-app/node_modules/enhanced-resolve/lib/Resolver.js?:331:11) at Object.resolve (webpack://my-app/node_modules/enhanced-resolve/lib/Resolver.js?:331:11)',
|
|
127
|
+
'stderr',
|
|
128
|
+
20
|
|
129
|
+
),
|
|
130
|
+
makeLog('Normal log line here', 'stdout', 30),
|
|
131
|
+
makeLog(
|
|
132
|
+
JSON.stringify({
|
|
133
|
+
level: 'info',
|
|
134
|
+
message: 'Request processed',
|
|
135
|
+
metadata: {
|
|
136
|
+
userId: 'usr_abc123',
|
|
137
|
+
path: '/api/features',
|
|
138
|
+
method: 'POST',
|
|
139
|
+
duration: 234,
|
|
140
|
+
headers: { 'content-type': 'application/json', authorization: 'Bearer xxx...xxx' },
|
|
141
|
+
},
|
|
142
|
+
}),
|
|
143
|
+
'stdout',
|
|
144
|
+
40
|
|
145
|
+
),
|
|
146
|
+
makeLog('Another normal line', 'stdout', 50),
|
|
147
|
+
]}
|
|
148
|
+
isConnected={true}
|
|
149
|
+
/>
|
|
150
|
+
),
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/** Disconnected state — shows server stopped message. */
|
|
154
|
+
export const Disconnected: Story = {
|
|
155
|
+
render: () => (
|
|
156
|
+
<InteractiveWrapper
|
|
157
|
+
logs={[
|
|
158
|
+
makeLog('$ npm run dev', 'stdout', 0),
|
|
159
|
+
makeLog('> next dev', 'stdout', 10),
|
|
160
|
+
makeLog(' ✓ Ready in 1.2s', 'stdout', 20),
|
|
161
|
+
makeLog('GET / 200 in 412ms', 'stdout', 100),
|
|
162
|
+
makeLog('GET /api/data 200 in 23ms', 'stdout', 200),
|
|
163
|
+
makeLog('SIGTERM received, shutting down...', 'stderr', 300),
|
|
164
|
+
]}
|
|
165
|
+
isConnected={false}
|
|
166
|
+
/>
|
|
167
|
+
),
|
|
168
|
+
};
|