@shepai/cli 1.76.0-pr241.9ff2c05 → 1.76.0-pr243.b5a1065
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/apis/json-schema/ModelConfiguration.yaml +5 -20
- package/dist/packages/core/src/application/ports/output/agents/agent-executor-factory.interface.d.ts +8 -0
- package/dist/packages/core/src/application/ports/output/agents/agent-executor-factory.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +1 -0
- package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +1 -0
- package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
- package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts +3 -3
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +5 -8
- package/dist/packages/core/src/domain/generated/output.d.ts +3 -15
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +8 -10
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +15 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +3 -2
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts +8 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.js +28 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/mock-executor-factory.service.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/mock-executor-factory.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/mock-executor-factory.service.js +3 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +3 -0
- package/dist/packages/core/src/infrastructure/services/settings.service.d.ts +1 -1
- package/dist/packages/core/src/infrastructure/services/settings.service.js +1 -1
- package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/new.command.js +2 -0
- package/dist/src/presentation/cli/commands/settings/index.d.ts +1 -0
- package/dist/src/presentation/cli/commands/settings/index.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/settings/index.js +4 -1
- package/dist/src/presentation/cli/commands/settings/model.command.d.ts +17 -0
- package/dist/src/presentation/cli/commands/settings/model.command.d.ts.map +1 -0
- package/dist/src/presentation/cli/commands/settings/model.command.js +62 -0
- package/dist/src/presentation/cli/ui/tables.d.ts.map +1 -1
- package/dist/src/presentation/cli/ui/tables.js +1 -6
- package/dist/src/presentation/web/app/actions/get-supported-models.d.ts +11 -0
- package/dist/src/presentation/web/app/actions/get-supported-models.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/get-supported-models.js +24 -0
- package/dist/src/presentation/web/app/actions/update-model.d.ts +15 -0
- package/dist/src/presentation/web/app/actions/update-model.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/update-model.js +35 -0
- package/dist/src/presentation/web/components/features/settings/ModelPicker/ModelPicker.stories.d.ts +24 -0
- package/dist/src/presentation/web/components/features/settings/ModelPicker/ModelPicker.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/settings/ModelPicker/ModelPicker.stories.js +53 -0
- package/dist/src/presentation/web/components/features/settings/ModelPicker/index.d.ts +18 -0
- package/dist/src/presentation/web/components/features/settings/ModelPicker/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/settings/ModelPicker/index.js +84 -0
- package/dist/src/presentation/web/components/ui/command.d.ts +19 -0
- package/dist/src/presentation/web/components/ui/command.d.ts.map +1 -0
- package/dist/src/presentation/web/components/ui/command.js +26 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +16 -16
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +19 -19
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +16 -16
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +19 -19
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +14 -14
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page.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/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
- package/web/.next/server/chunks/ssr/_0e9d6bf7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_30fd6f01._.js → _435fea24._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_30fd6f01._.js.map → _435fea24._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_5ee4f5a7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
- package/web/.next/server/chunks/ssr/_61351ed3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_6e08ce21._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
- package/web/.next/server/chunks/ssr/_8400c8bb._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
- package/web/.next/server/chunks/ssr/_9f940437._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_163038ba._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_163038ba._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_459cb687._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_459cb687._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +22 -22
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +16 -16
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +19 -19
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +16 -16
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +19 -19
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.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 +6 -6
- 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_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_30fd6f01._.js → _435fea24._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_163038ba._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_459cb687._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +22 -22
- package/web/.next/standalone/src/presentation/web/app/actions/get-supported-models.ts +26 -0
- package/web/.next/standalone/src/presentation/web/app/actions/update-model.ts +45 -0
- package/web/.next/standalone/src/presentation/web/components/features/settings/ModelPicker/ModelPicker.stories.tsx +64 -0
- package/web/.next/standalone/src/presentation/web/components/features/settings/ModelPicker/index.tsx +167 -0
- package/web/.next/standalone/src/presentation/web/components/ui/command.tsx +114 -0
- package/web/.next/static/chunks/115eab1c5d9aea10.js +1 -0
- package/web/.next/static/chunks/{2e2355741bd6a9a7.js → 46c77597b4b8129d.js} +1 -1
- package/web/.next/static/chunks/{dcb8f73fb28b2a26.js → 81e1c1e43ae18086.js} +1 -1
- package/web/.next/static/chunks/8a68cac7c51df846.css +2 -0
- package/web/.next/static/chunks/{45b6a69a50b9d9e8.js → 920d18ed1ff267e7.js} +1 -1
- package/web/.next/static/chunks/{e37d7d4d215db8f5.js → 9678137ccbb5bdc3.js} +1 -1
- package/web/.next/static/chunks/{4e6ecfe539924a71.js → a32ab061aed15a64.js} +1 -1
- package/web/.next/static/chunks/{47b5d582b373816d.js → b1fa3fb02b473f65.js} +1 -1
- package/web/.next/static/chunks/{437a925303b28b53.js → bdbe5f5328a66512.js} +1 -1
- package/web/.next/static/chunks/{b5078ac043e7335a.js → faee95b678e8ec64.js} +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/dist/src/presentation/web/app/actions/get-feature-messages.d.ts +0 -15
- package/dist/src/presentation/web/app/actions/get-feature-messages.d.ts.map +0 -1
- package/dist/src/presentation/web/app/actions/get-feature-messages.js +0 -26
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts +0 -17
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +0 -1
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +0 -25
- package/dist/src/presentation/web/app/actions/get-feature-plan.d.ts +0 -18
- package/dist/src/presentation/web/app/actions/get-feature-plan.d.ts.map +0 -1
- package/dist/src/presentation/web/app/actions/get-feature-plan.js +0 -31
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts +0 -8
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +0 -90
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts +0 -20
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.js +0 -252
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts +0 -7
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +0 -68
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.d.ts +0 -14
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.js +0 -112
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/index.d.ts +0 -3
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/index.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/index.js +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/messages-tab.d.ts +0 -8
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/messages-tab.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/messages-tab.js +0 -24
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/messages-tab.stories.d.ts +0 -18
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/messages-tab.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/messages-tab.stories.js +0 -125
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts +0 -6
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +0 -35
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +0 -28
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +0 -157
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.d.ts +0 -8
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.js +0 -40
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.d.ts +0 -22
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.js +0 -188
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.d.ts +0 -30
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.js +0 -100
- package/web/.next/standalone/src/presentation/web/app/actions/get-feature-messages.ts +0 -42
- package/web/.next/standalone/src/presentation/web/app/actions/get-feature-phase-timings.ts +0 -42
- package/web/.next/standalone/src/presentation/web/app/actions/get-feature-plan.ts +0 -52
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.stories.tsx +0 -272
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.tsx +0 -245
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.stories.tsx +0 -130
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx +0 -136
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/index.ts +0 -2
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/messages-tab.stories.tsx +0 -149
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/messages-tab.tsx +0 -92
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.tsx +0 -186
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.tsx +0 -142
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.stories.tsx +0 -214
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.tsx +0 -121
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.ts +0 -143
- package/web/.next/static/chunks/84d2f2d55e5cf753.css +0 -2
- package/web/.next/static/chunks/90f36476e66cbace.js +0 -1
- /package/web/.next/static/{TuKZpCcwG7RLlpnyasgpZ → dW3UxyG_fKX-TDcK9QVh4}/_buildManifest.js +0 -0
- /package/web/.next/static/{TuKZpCcwG7RLlpnyasgpZ → dW3UxyG_fKX-TDcK9QVh4}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{TuKZpCcwG7RLlpnyasgpZ → dW3UxyG_fKX-TDcK9QVh4}/_ssgManifest.js +0 -0
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { ExternalLink, GitCommitHorizontal } from 'lucide-react';
|
|
4
|
-
import { PrStatus } from '@shepai/core/domain/generated/output';
|
|
5
|
-
import { cn } from '@/lib/utils';
|
|
6
|
-
import { Badge } from '@/components/ui/badge';
|
|
7
|
-
import { Separator } from '@/components/ui/separator';
|
|
8
|
-
import { CiStatusBadge } from '@/components/common/ci-status-badge';
|
|
9
|
-
import { CometSpinner } from '@/components/ui/comet-spinner';
|
|
10
|
-
import { featureNodeStateConfig, lifecycleDisplayLabels } from '@/components/common/feature-node';
|
|
11
|
-
import type { FeatureNodeData } from '@/components/common/feature-node';
|
|
12
|
-
|
|
13
|
-
export interface OverviewTabProps {
|
|
14
|
-
data: FeatureNodeData;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function OverviewTab({ data }: OverviewTabProps) {
|
|
18
|
-
return (
|
|
19
|
-
<>
|
|
20
|
-
<div data-testid="feature-drawer-status" className="flex flex-col gap-3 p-4">
|
|
21
|
-
<div className="text-muted-foreground text-xs font-semibold tracking-wider">
|
|
22
|
-
{lifecycleDisplayLabels[data.lifecycle]}
|
|
23
|
-
</div>
|
|
24
|
-
<FeatureStateBadge data={data} />
|
|
25
|
-
{data.progress > 0 ? (
|
|
26
|
-
<div data-testid="feature-drawer-progress" className="flex flex-col gap-1">
|
|
27
|
-
<div className="text-muted-foreground flex items-center justify-between text-xs">
|
|
28
|
-
<span>Progress</span>
|
|
29
|
-
<span>{data.progress}%</span>
|
|
30
|
-
</div>
|
|
31
|
-
<div className="bg-muted h-2 w-full overflow-hidden rounded-full">
|
|
32
|
-
<div
|
|
33
|
-
className={cn(
|
|
34
|
-
'h-full rounded-full transition-all',
|
|
35
|
-
featureNodeStateConfig[data.state].progressClass
|
|
36
|
-
)}
|
|
37
|
-
style={{ width: `${data.progress}%` }}
|
|
38
|
-
/>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
) : null}
|
|
42
|
-
</div>
|
|
43
|
-
{data.pr ? (
|
|
44
|
-
<>
|
|
45
|
-
<Separator />
|
|
46
|
-
<FeaturePrInfo pr={data.pr} />
|
|
47
|
-
</>
|
|
48
|
-
) : null}
|
|
49
|
-
<FeatureDetails data={data} />
|
|
50
|
-
</>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function FeatureStateBadge({ data }: { data: FeatureNodeData }) {
|
|
55
|
-
const config = featureNodeStateConfig[data.state];
|
|
56
|
-
const Icon = config.icon;
|
|
57
|
-
return (
|
|
58
|
-
<div
|
|
59
|
-
className={cn(
|
|
60
|
-
'flex items-center gap-2 rounded-full px-3 py-1.5 text-sm font-medium',
|
|
61
|
-
config.badgeBgClass,
|
|
62
|
-
config.badgeClass
|
|
63
|
-
)}
|
|
64
|
-
>
|
|
65
|
-
{data.state === 'running' ? (
|
|
66
|
-
<CometSpinner size="sm" className="shrink-0" />
|
|
67
|
-
) : (
|
|
68
|
-
<Icon className="h-4 w-4 shrink-0" />
|
|
69
|
-
)}
|
|
70
|
-
<span>{config.label}</span>
|
|
71
|
-
</div>
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const prStatusStyles: Record<PrStatus, string> = {
|
|
76
|
-
[PrStatus.Open]: 'border-transparent bg-blue-50 text-blue-700 hover:bg-blue-50',
|
|
77
|
-
[PrStatus.Merged]: 'border-transparent bg-purple-50 text-purple-700 hover:bg-purple-50',
|
|
78
|
-
[PrStatus.Closed]: 'border-transparent bg-red-50 text-red-700 hover:bg-red-50',
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
function FeaturePrInfo({ pr }: { pr: NonNullable<FeatureNodeData['pr']> }) {
|
|
82
|
-
return (
|
|
83
|
-
<div data-testid="feature-drawer-pr" className="border-border mx-4 rounded-lg border">
|
|
84
|
-
<div className="space-y-3 px-4 py-3">
|
|
85
|
-
<div className="flex items-center justify-between">
|
|
86
|
-
<a
|
|
87
|
-
href={pr.url}
|
|
88
|
-
target="_blank"
|
|
89
|
-
rel="noopener noreferrer"
|
|
90
|
-
className="text-primary flex items-center gap-1.5 text-sm font-semibold underline underline-offset-2"
|
|
91
|
-
>
|
|
92
|
-
PR #{pr.number}
|
|
93
|
-
<ExternalLink className="h-3.5 w-3.5" />
|
|
94
|
-
</a>
|
|
95
|
-
<Badge className={prStatusStyles[pr.status]}>{pr.status}</Badge>
|
|
96
|
-
</div>
|
|
97
|
-
{pr.ciStatus ? (
|
|
98
|
-
<div className="flex items-center justify-between">
|
|
99
|
-
<span className="text-muted-foreground text-xs font-medium">CI Status</span>
|
|
100
|
-
<CiStatusBadge status={pr.ciStatus} />
|
|
101
|
-
</div>
|
|
102
|
-
) : null}
|
|
103
|
-
{pr.commitHash ? (
|
|
104
|
-
<div className="flex items-center justify-between">
|
|
105
|
-
<span className="text-muted-foreground text-xs font-medium">Commit</span>
|
|
106
|
-
<div className="flex items-center gap-1.5">
|
|
107
|
-
<GitCommitHorizontal className="text-muted-foreground h-3.5 w-3.5" />
|
|
108
|
-
<code className="bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]">
|
|
109
|
-
{pr.commitHash.slice(0, 7)}
|
|
110
|
-
</code>
|
|
111
|
-
</div>
|
|
112
|
-
</div>
|
|
113
|
-
) : null}
|
|
114
|
-
</div>
|
|
115
|
-
</div>
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function FeatureDetails({ data }: { data: FeatureNodeData }) {
|
|
120
|
-
const hasAnyDetail = data.agentType ?? data.runtime ?? data.blockedBy ?? data.errorMessage;
|
|
121
|
-
if (!hasAnyDetail) return null;
|
|
122
|
-
return (
|
|
123
|
-
<>
|
|
124
|
-
<Separator />
|
|
125
|
-
<div data-testid="feature-drawer-details" className="flex flex-col gap-3 p-4">
|
|
126
|
-
{data.agentType ? <DetailRow label="Agent" value={data.agentType} /> : null}
|
|
127
|
-
{data.runtime ? <DetailRow label="Runtime" value={data.runtime} /> : null}
|
|
128
|
-
{data.blockedBy ? <DetailRow label="Blocked by" value={data.blockedBy} /> : null}
|
|
129
|
-
{data.errorMessage ? <DetailRow label="Error" value={data.errorMessage} /> : null}
|
|
130
|
-
</div>
|
|
131
|
-
</>
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function DetailRow({ label, value }: { label: string; value: string }) {
|
|
136
|
-
return (
|
|
137
|
-
<div className="flex flex-col gap-0.5">
|
|
138
|
-
<span className="text-muted-foreground text-xs font-medium">{label}</span>
|
|
139
|
-
<span className="text-sm">{value}</span>
|
|
140
|
-
</div>
|
|
141
|
-
);
|
|
142
|
-
}
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { PlanTab } from './plan-tab';
|
|
3
|
-
import type { PlanData } from '@/app/actions/get-feature-plan';
|
|
4
|
-
|
|
5
|
-
const meta: Meta<typeof PlanTab> = {
|
|
6
|
-
title: 'Drawers/Feature/Tabs/PlanTab',
|
|
7
|
-
component: PlanTab,
|
|
8
|
-
tags: ['autodocs'],
|
|
9
|
-
parameters: {
|
|
10
|
-
layout: 'fullscreen',
|
|
11
|
-
},
|
|
12
|
-
decorators: [
|
|
13
|
-
(Story) => (
|
|
14
|
-
<div style={{ height: '600px', width: '400px', border: '1px solid var(--color-border)' }}>
|
|
15
|
-
<Story />
|
|
16
|
-
</div>
|
|
17
|
-
),
|
|
18
|
-
],
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default meta;
|
|
22
|
-
type Story = StoryObj<typeof PlanTab>;
|
|
23
|
-
|
|
24
|
-
/* ---------------------------------------------------------------------------
|
|
25
|
-
* Data fixtures
|
|
26
|
-
* ------------------------------------------------------------------------- */
|
|
27
|
-
|
|
28
|
-
const mixedTasksPlan: PlanData = {
|
|
29
|
-
state: 'Ready',
|
|
30
|
-
overview:
|
|
31
|
-
'Implement OAuth2 authentication flow with support for Google and GitHub identity providers. The implementation includes token management, callback handling, and user profile sync.',
|
|
32
|
-
tasks: [
|
|
33
|
-
{
|
|
34
|
-
title: 'Set up OAuth provider configuration',
|
|
35
|
-
description: 'Configure Google and GitHub OAuth apps with client IDs and secrets',
|
|
36
|
-
state: 'Done',
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
title: 'Implement callback handler',
|
|
40
|
-
description: 'Handle OAuth callback with authorization code exchange',
|
|
41
|
-
state: 'Done',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
title: 'Add token refresh logic',
|
|
45
|
-
description: 'Implement silent token refresh using refresh tokens stored in httpOnly cookies',
|
|
46
|
-
state: 'Work in Progress',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
title: 'Create user profile sync',
|
|
50
|
-
description: 'Sync user profile data from identity providers on login',
|
|
51
|
-
state: 'Todo',
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
title: 'Write integration tests',
|
|
55
|
-
description: 'Test the full OAuth flow with mocked providers',
|
|
56
|
-
state: 'Todo',
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
title: 'Update API documentation',
|
|
60
|
-
description: 'Document new authentication endpoints and flows',
|
|
61
|
-
state: 'Review',
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const allDonePlan: PlanData = {
|
|
67
|
-
state: 'Ready',
|
|
68
|
-
overview:
|
|
69
|
-
'All implementation tasks for the rate limiting feature have been completed successfully.',
|
|
70
|
-
tasks: [
|
|
71
|
-
{
|
|
72
|
-
title: 'Design sliding window algorithm',
|
|
73
|
-
description: 'Implement Redis-backed sliding window counter',
|
|
74
|
-
state: 'Done',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
title: 'Add rate limit middleware',
|
|
78
|
-
description: 'Express middleware that checks rate limits per IP',
|
|
79
|
-
state: 'Done',
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
title: 'Configure limits per endpoint',
|
|
83
|
-
description: 'Set different rate limits for public vs authenticated endpoints',
|
|
84
|
-
state: 'Done',
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
title: 'Add rate limit headers',
|
|
88
|
-
description: 'Include X-RateLimit-* headers in responses',
|
|
89
|
-
state: 'Done',
|
|
90
|
-
},
|
|
91
|
-
],
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const draftPlan: PlanData = {
|
|
95
|
-
state: 'Requirements',
|
|
96
|
-
overview:
|
|
97
|
-
'Initial plan for implementing the notification system. Requirements are still being gathered.',
|
|
98
|
-
tasks: [
|
|
99
|
-
{
|
|
100
|
-
title: 'Define notification types',
|
|
101
|
-
description: 'Enumerate all notification events and their payloads',
|
|
102
|
-
state: 'Todo',
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
title: 'Set up WebSocket server',
|
|
106
|
-
description: 'Configure Socket.io with Redis adapter for horizontal scaling',
|
|
107
|
-
state: 'Todo',
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
title: 'Implement notification store',
|
|
111
|
-
description: 'Persist notifications in database with read/unread tracking',
|
|
112
|
-
state: 'Todo',
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const clarificationPlan: PlanData = {
|
|
118
|
-
state: 'ClarificationRequired',
|
|
119
|
-
overview: 'Plan requires clarification on the scope of the email template system.',
|
|
120
|
-
tasks: [
|
|
121
|
-
{
|
|
122
|
-
title: 'Set up email provider',
|
|
123
|
-
description: 'Configure SendGrid API integration',
|
|
124
|
-
state: 'Done',
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
title: 'Create template engine',
|
|
128
|
-
description: 'Implement Handlebars-based email template rendering',
|
|
129
|
-
state: 'Todo',
|
|
130
|
-
},
|
|
131
|
-
],
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const noTasksPlan: PlanData = {
|
|
135
|
-
state: 'Requirements',
|
|
136
|
-
overview: 'Plan overview is available but no tasks have been defined yet.',
|
|
137
|
-
tasks: [],
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
/* ---------------------------------------------------------------------------
|
|
141
|
-
* Stories
|
|
142
|
-
* ------------------------------------------------------------------------- */
|
|
143
|
-
|
|
144
|
-
/** Default — plan with tasks in various states (Todo, WIP, Done, Review). */
|
|
145
|
-
export const Default: Story = {
|
|
146
|
-
args: {
|
|
147
|
-
plan: mixedTasksPlan,
|
|
148
|
-
loading: false,
|
|
149
|
-
error: null,
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
/** All tasks completed. */
|
|
154
|
-
export const AllTasksDone: Story = {
|
|
155
|
-
args: {
|
|
156
|
-
plan: allDonePlan,
|
|
157
|
-
loading: false,
|
|
158
|
-
error: null,
|
|
159
|
-
},
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
/** Draft plan in Requirements state. */
|
|
163
|
-
export const DraftPlan: Story = {
|
|
164
|
-
args: {
|
|
165
|
-
plan: draftPlan,
|
|
166
|
-
loading: false,
|
|
167
|
-
error: null,
|
|
168
|
-
},
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
/** Plan requiring clarification — ClarificationRequired state badge. */
|
|
172
|
-
export const ClarificationRequired: Story = {
|
|
173
|
-
args: {
|
|
174
|
-
plan: clarificationPlan,
|
|
175
|
-
loading: false,
|
|
176
|
-
error: null,
|
|
177
|
-
},
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
/** Plan with overview but no tasks defined yet. */
|
|
181
|
-
export const NoTasks: Story = {
|
|
182
|
-
args: {
|
|
183
|
-
plan: noTasksPlan,
|
|
184
|
-
loading: false,
|
|
185
|
-
error: null,
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
/** Loading state — spinner displayed while data is being fetched. */
|
|
190
|
-
export const Loading: Story = {
|
|
191
|
-
args: {
|
|
192
|
-
plan: null,
|
|
193
|
-
loading: true,
|
|
194
|
-
error: null,
|
|
195
|
-
},
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
/** Empty state — no plan created yet. */
|
|
199
|
-
export const Empty: Story = {
|
|
200
|
-
args: {
|
|
201
|
-
plan: null,
|
|
202
|
-
loading: false,
|
|
203
|
-
error: null,
|
|
204
|
-
},
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
/** Error state — inline error message. */
|
|
208
|
-
export const Error: Story = {
|
|
209
|
-
args: {
|
|
210
|
-
plan: null,
|
|
211
|
-
loading: false,
|
|
212
|
-
error: 'Failed to load plan data. Please try again.',
|
|
213
|
-
},
|
|
214
|
-
};
|
package/web/.next/standalone/src/presentation/web/components/common/feature-drawer-tabs/plan-tab.tsx
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { Loader2, Circle, Check, Eye } from 'lucide-react';
|
|
4
|
-
import { AlertCircle, ListTodo } from 'lucide-react';
|
|
5
|
-
import { Badge } from '@/components/ui/badge';
|
|
6
|
-
import type { PlanData, PlanTaskData } from '@/app/actions/get-feature-plan';
|
|
7
|
-
|
|
8
|
-
export interface PlanTabProps {
|
|
9
|
-
plan: PlanData | null;
|
|
10
|
-
loading: boolean;
|
|
11
|
-
error: string | null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const planStateBadgeStyles: Record<string, string> = {
|
|
15
|
-
Requirements: 'border-transparent bg-blue-50 text-blue-700 hover:bg-blue-50',
|
|
16
|
-
ClarificationRequired: 'border-transparent bg-amber-50 text-amber-700 hover:bg-amber-50',
|
|
17
|
-
Ready: 'border-transparent bg-green-50 text-green-700 hover:bg-green-50',
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const taskStateConfig: Record<
|
|
21
|
-
string,
|
|
22
|
-
{ icon: typeof Circle; colorClass: string; spinning?: boolean }
|
|
23
|
-
> = {
|
|
24
|
-
Todo: { icon: Circle, colorClass: 'text-muted-foreground' },
|
|
25
|
-
'Work in Progress': { icon: Loader2, colorClass: 'text-blue-600', spinning: true },
|
|
26
|
-
Done: { icon: Check, colorClass: 'text-emerald-600' },
|
|
27
|
-
Review: { icon: Eye, colorClass: 'text-amber-600' },
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const defaultTaskConfig = { icon: Circle, colorClass: 'text-muted-foreground' };
|
|
31
|
-
|
|
32
|
-
export function PlanTab({ plan, loading, error }: PlanTabProps) {
|
|
33
|
-
if (loading) {
|
|
34
|
-
return (
|
|
35
|
-
<div data-testid="plan-tab-loading" className="flex items-center justify-center p-8">
|
|
36
|
-
<Loader2 className="text-muted-foreground h-6 w-6 animate-spin" />
|
|
37
|
-
</div>
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (error) {
|
|
42
|
-
return (
|
|
43
|
-
<div className="flex items-center gap-2 p-4 text-sm text-red-600">
|
|
44
|
-
<AlertCircle className="h-4 w-4 shrink-0" />
|
|
45
|
-
<span>{error}</span>
|
|
46
|
-
</div>
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!plan) {
|
|
51
|
-
return (
|
|
52
|
-
<div className="flex flex-col items-center justify-center gap-2 p-8">
|
|
53
|
-
<ListTodo className="text-muted-foreground h-8 w-8" />
|
|
54
|
-
<p className="text-muted-foreground text-sm">No plan created yet</p>
|
|
55
|
-
</div>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return (
|
|
60
|
-
<div className="flex flex-col gap-4 p-4">
|
|
61
|
-
<div className="flex items-center gap-2">
|
|
62
|
-
<span className="text-muted-foreground text-xs font-medium">Plan State</span>
|
|
63
|
-
<Badge
|
|
64
|
-
className={
|
|
65
|
-
planStateBadgeStyles[plan.state] ?? 'border-transparent bg-gray-50 text-gray-700'
|
|
66
|
-
}
|
|
67
|
-
>
|
|
68
|
-
{plan.state}
|
|
69
|
-
</Badge>
|
|
70
|
-
</div>
|
|
71
|
-
{plan.overview ? (
|
|
72
|
-
<div className="flex flex-col gap-1">
|
|
73
|
-
<span className="text-muted-foreground text-xs font-medium">Overview</span>
|
|
74
|
-
<p className="text-sm leading-relaxed">{plan.overview}</p>
|
|
75
|
-
</div>
|
|
76
|
-
) : null}
|
|
77
|
-
<TaskList tasks={plan.tasks} />
|
|
78
|
-
</div>
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function TaskList({ tasks }: { tasks: PlanTaskData[] }) {
|
|
83
|
-
if (tasks.length === 0) {
|
|
84
|
-
return (
|
|
85
|
-
<div className="flex flex-col items-center justify-center gap-2 py-4">
|
|
86
|
-
<p className="text-muted-foreground text-sm">No tasks defined yet</p>
|
|
87
|
-
</div>
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return (
|
|
92
|
-
<div className="flex flex-col gap-1">
|
|
93
|
-
<span className="text-muted-foreground text-xs font-medium">Tasks</span>
|
|
94
|
-
<div data-testid="plan-task-list" className="flex flex-col gap-2">
|
|
95
|
-
{tasks.map((task, index) => (
|
|
96
|
-
<TaskItem key={task.title || `task-${index}`} task={task} index={index} />
|
|
97
|
-
))}
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function TaskItem({ task, index }: { task: PlanTaskData; index: number }) {
|
|
104
|
-
const config = taskStateConfig[task.state] ?? defaultTaskConfig;
|
|
105
|
-
const Icon = config.icon;
|
|
106
|
-
|
|
107
|
-
return (
|
|
108
|
-
<div
|
|
109
|
-
data-testid={`plan-task-${index}`}
|
|
110
|
-
className={`flex items-start gap-2 rounded-md border px-3 py-2 ${config.colorClass}`}
|
|
111
|
-
>
|
|
112
|
-
<Icon className={`mt-0.5 h-4 w-4 shrink-0 ${config.spinning ? 'animate-spin' : ''}`} />
|
|
113
|
-
<div className="flex min-w-0 flex-col gap-0.5">
|
|
114
|
-
<span className="text-sm font-medium">{task.title}</span>
|
|
115
|
-
{task.description ? (
|
|
116
|
-
<span className="text-muted-foreground text-xs">{task.description}</span>
|
|
117
|
-
) : null}
|
|
118
|
-
</div>
|
|
119
|
-
</div>
|
|
120
|
-
);
|
|
121
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
4
|
-
|
|
5
|
-
/** State for a single tab's data, loading, and error. */
|
|
6
|
-
export interface TabState<T = unknown> {
|
|
7
|
-
data: T | null;
|
|
8
|
-
loading: boolean;
|
|
9
|
-
error: string | null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/** A function that fetches data for a tab given a feature ID. */
|
|
13
|
-
export type TabFetcher<T = unknown> = (featureId: string) => Promise<T>;
|
|
14
|
-
|
|
15
|
-
/** Map of tab keys to their fetcher functions. */
|
|
16
|
-
export type TabFetchers<K extends string> = Record<K, TabFetcher>;
|
|
17
|
-
|
|
18
|
-
/** Return type of the useTabDataFetch hook. */
|
|
19
|
-
export interface UseTabDataFetchResult<K extends string> {
|
|
20
|
-
/** Per-tab state (data, loading, error). */
|
|
21
|
-
tabs: Record<K, TabState>;
|
|
22
|
-
/** Fetch data for a tab. Uses cache if already fetched. */
|
|
23
|
-
fetchTab: (tab: K) => Promise<void>;
|
|
24
|
-
/** Force re-fetch for a tab, bypassing cache. */
|
|
25
|
-
refreshTab: (tab: K) => Promise<void>;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function createInitialTabState(): TabState {
|
|
29
|
-
return { data: null, loading: false, error: null };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Custom hook for lazy-loading tab data with per-tab caching.
|
|
34
|
-
*
|
|
35
|
-
* - Fetches data only when a tab is explicitly activated via fetchTab().
|
|
36
|
-
* - Caches results so revisiting a loaded tab is instant.
|
|
37
|
-
* - Clears all cached data when featureId changes.
|
|
38
|
-
* - Supports force re-fetch via refreshTab() for SSE-driven updates.
|
|
39
|
-
* - Uses ref-based callbacks to avoid stale closures (matches useArtifactFetch pattern).
|
|
40
|
-
*/
|
|
41
|
-
export function useTabDataFetch<K extends string>(
|
|
42
|
-
featureId: string,
|
|
43
|
-
fetchers: TabFetchers<K>
|
|
44
|
-
): UseTabDataFetchResult<K> {
|
|
45
|
-
const tabKeys = Object.keys(fetchers) as K[];
|
|
46
|
-
|
|
47
|
-
const [tabStates, setTabStates] = useState<Record<K, TabState>>(() => {
|
|
48
|
-
const initial = {} as Record<K, TabState>;
|
|
49
|
-
for (const key of tabKeys) {
|
|
50
|
-
initial[key] = createInitialTabState();
|
|
51
|
-
}
|
|
52
|
-
return initial;
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// Ref-based fetchers to avoid stale closures in callbacks.
|
|
56
|
-
const fetchersRef = useRef(fetchers);
|
|
57
|
-
fetchersRef.current = fetchers;
|
|
58
|
-
|
|
59
|
-
// Ref-based featureId to use current value in callbacks.
|
|
60
|
-
const featureIdRef = useRef(featureId);
|
|
61
|
-
featureIdRef.current = featureId;
|
|
62
|
-
|
|
63
|
-
// Track mounted state to prevent state updates after unmount.
|
|
64
|
-
const mountedRef = useRef(true);
|
|
65
|
-
useEffect(() => {
|
|
66
|
-
mountedRef.current = true;
|
|
67
|
-
return () => {
|
|
68
|
-
mountedRef.current = false;
|
|
69
|
-
};
|
|
70
|
-
}, []);
|
|
71
|
-
|
|
72
|
-
// Clear all cached data when featureId changes.
|
|
73
|
-
const prevFeatureIdRef = useRef(featureId);
|
|
74
|
-
useEffect(() => {
|
|
75
|
-
if (prevFeatureIdRef.current !== featureId) {
|
|
76
|
-
prevFeatureIdRef.current = featureId;
|
|
77
|
-
setTabStates((prev) => {
|
|
78
|
-
const cleared = {} as Record<K, TabState>;
|
|
79
|
-
for (const key of Object.keys(prev) as K[]) {
|
|
80
|
-
cleared[key] = createInitialTabState();
|
|
81
|
-
}
|
|
82
|
-
return cleared;
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}, [featureId]);
|
|
86
|
-
|
|
87
|
-
const doFetch = useCallback(async (tab: K) => {
|
|
88
|
-
const fetcher = fetchersRef.current[tab];
|
|
89
|
-
const currentFeatureId = featureIdRef.current;
|
|
90
|
-
|
|
91
|
-
if (!fetcher) return;
|
|
92
|
-
|
|
93
|
-
if (mountedRef.current) {
|
|
94
|
-
setTabStates((prev) => ({
|
|
95
|
-
...prev,
|
|
96
|
-
[tab]: { ...prev[tab], loading: true, error: null },
|
|
97
|
-
}));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
try {
|
|
101
|
-
const data = await fetcher(currentFeatureId);
|
|
102
|
-
if (mountedRef.current) {
|
|
103
|
-
setTabStates((prev) => ({
|
|
104
|
-
...prev,
|
|
105
|
-
[tab]: { data, loading: false, error: null },
|
|
106
|
-
}));
|
|
107
|
-
}
|
|
108
|
-
} catch (error: unknown) {
|
|
109
|
-
if (mountedRef.current) {
|
|
110
|
-
const message = error instanceof Error ? error.message : 'Failed to fetch tab data';
|
|
111
|
-
setTabStates((prev) => ({
|
|
112
|
-
...prev,
|
|
113
|
-
[tab]: { data: null, loading: false, error: message },
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}, []);
|
|
118
|
-
|
|
119
|
-
const fetchTab = useCallback(
|
|
120
|
-
async (tab: K) => {
|
|
121
|
-
// Check if data is already cached (non-null data means already fetched)
|
|
122
|
-
const current = tabStates[tab];
|
|
123
|
-
if (current && current.data !== null) return;
|
|
124
|
-
// Also skip if currently loading
|
|
125
|
-
if (current && current.loading) return;
|
|
126
|
-
await doFetch(tab);
|
|
127
|
-
},
|
|
128
|
-
[tabStates, doFetch]
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
const refreshTab = useCallback(
|
|
132
|
-
async (tab: K) => {
|
|
133
|
-
await doFetch(tab);
|
|
134
|
-
},
|
|
135
|
-
[doFetch]
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
tabs: tabStates,
|
|
140
|
-
fetchTab,
|
|
141
|
-
refreshTab,
|
|
142
|
-
};
|
|
143
|
-
}
|