@shepai/cli 1.166.0 → 1.166.1-pr521.4139df8
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/index.d.ts +1 -0
- package/dist/packages/core/src/application/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/index.js +1 -0
- package/dist/packages/core/src/application/ports/output/agents/agent-run-repository.interface.d.ts +12 -0
- package/dist/packages/core/src/application/ports/output/agents/agent-run-repository.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/update-feature-pinned-config.use-case.d.ts +24 -0
- package/dist/packages/core/src/application/use-cases/features/update-feature-pinned-config.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/features/update-feature-pinned-config.use-case.js +107 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +8 -0
- package/dist/packages/core/src/infrastructure/repositories/agent-run.repository.d.ts +2 -1
- package/dist/packages/core/src/infrastructure/repositories/agent-run.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/agent-run.repository.js +15 -0
- package/dist/packages/core/src/infrastructure/services/web-server.service.d.ts +3 -0
- package/dist/packages/core/src/infrastructure/services/web-server.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/web-server.service.js +10 -0
- package/dist/src/presentation/web/app/actions/update-feature-pinned-config.d.ts +5 -0
- package/dist/src/presentation/web/app/actions/update-feature-pinned-config.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/update-feature-pinned-config.js +29 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +100 -9
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts +4 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +3 -3
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts +3 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +21 -10
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +4 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +33 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.d.ts +18 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.js +17 -0
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts +2 -0
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.js +27 -0
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts +10 -1
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.js +33 -25
- 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/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +3 -3
- package/web/.next/required-server-files.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
- 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]/[tab]/page/server-reference-manifest.json +89 -74
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +89 -74
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- 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)/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
- 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]/[tab]/page/server-reference-manifest.json +89 -74
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +89 -74
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
- 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]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- 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 +6 -6
- 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/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
- package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
- 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 +11 -11
- 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 +6 -6
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +3 -3
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1abe77bb._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1abe77bb._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2d0c3840._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2d0c3840._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7562afc6._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7562afc6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_02e01240._.js +1 -1
- package/web/.next/server/chunks/ssr/_02e01240._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
- package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0727935d._.js +1 -1
- package/web/.next/server/chunks/ssr/_0727935d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_18886033._.js +1 -1
- package/web/.next/server/chunks/ssr/_18886033._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_22e00a14._.js +1 -1
- package/web/.next/server/chunks/ssr/_22e00a14._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
- package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_8237a552._.js → _80eef198._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_8237a552._.js.map → _80eef198._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_9215e9ec._.js +1 -1
- package/web/.next/server/chunks/ssr/_9215e9ec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_a5a5901d._.js +1 -1
- package/web/.next/server/chunks/ssr/_a5a5901d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_ad09f271._.js +1 -1
- package/web/.next/server/chunks/ssr/_ad09f271._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_42df9dfe._.js → _ad1e8df0._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_42df9dfe._.js.map → _ad1e8df0._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_c3f595c6._.js +1 -1
- package/web/.next/server/chunks/ssr/_c3f595c6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_ddc492d1._.js → _cb46c553._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_ddc492d1._.js.map → _cb46c553._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_ea9e1556._.js +1 -1
- package/web/.next/server/chunks/ssr/_ea9e1556._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f1ba9be6._.js +2 -2
- package/web/.next/server/chunks/ssr/_f1ba9be6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f33cd07e._.js +2 -2
- package/web/.next/server/chunks/ssr/_f33cd07e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_f8b45233._.js +1 -1
- package/web/.next/server/chunks/ssr/_f8b45233._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.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 +231 -195
- package/web/.next/static/chunks/{5aaf70a61ff36c5a.js → 017b47553231a823.js} +1 -1
- package/web/.next/static/chunks/{31f0a6a3634a38cc.js → 0b5d6a720a7881a9.js} +1 -1
- package/web/.next/static/chunks/{09384992ac14d0b1.js → 1d29dba973313f02.js} +1 -1
- package/web/.next/static/chunks/3208dc997aaee4d3.css +1 -0
- package/web/.next/static/chunks/39f6493901c3eea0.js +5 -0
- package/web/.next/static/chunks/{eca136d997cb8da7.js → 3c1fa8ca0fd213dd.js} +1 -1
- package/web/.next/static/chunks/{e2ba7b83074d9104.js → 5afbcdb3d1de34c9.js} +1 -1
- package/web/.next/static/chunks/{4db9c7689add55ee.js → 7324fbbe1b204722.js} +2 -2
- package/web/.next/static/chunks/{352028876229aa6b.js → 902840b67efbdd64.js} +1 -1
- package/web/.next/static/chunks/a260c71a30c63952.js +1 -0
- package/web/.next/static/chunks/{dc3ddb095e1af0e0.js → b2ea14e7d98ca3e8.js} +1 -1
- package/web/.next/static/chunks/{788183384c8a43ba.js → bd4204d2d43217b4.js} +1 -1
- package/web/.next/static/chunks/{e9b6a30fee5ad6c4.js → c26529d3615ad0a3.js} +3 -3
- package/web/.next/static/chunks/{6f74c02d56d084bc.js → ed4aa2bcbf8b63e2.js} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js.map +0 -1
- package/web/.next/static/chunks/1e6609edc3367244.css +0 -1
- package/web/.next/static/chunks/a61378603f8d7259.js +0 -5
- package/web/.next/static/chunks/bd53da44edb8c407.js +0 -1
- /package/web/.next/static/{5K-9Z8FJofHXgZNGHs_YM → WC6AP64Gn0KyMqwIy1VjS}/_buildManifest.js +0 -0
- /package/web/.next/static/{5K-9Z8FJofHXgZNGHs_YM → WC6AP64Gn0KyMqwIy1VjS}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{5K-9Z8FJofHXgZNGHs_YM → WC6AP64Gn0KyMqwIy1VjS}/_ssgManifest.js +0 -0
package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js
CHANGED
|
@@ -78,7 +78,7 @@ const TAB_FETCHERS = {
|
|
|
78
78
|
activity: fetchActivity,
|
|
79
79
|
plan: fetchPlan,
|
|
80
80
|
};
|
|
81
|
-
export function FeatureDrawerTabs({ featureName, headerContent, featureNode, featureId, initialTab, urlTab, prdData, prdSelections, onPrdSelect, onPrdApprove, onPrdReject, isPrdLoading, techData, onTechApprove, onTechReject, isTechLoading, productData, mergeData, onMergeApprove, onMergeReject, isMergeLoading, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, isRejecting, chatInput, onChatInputChange, sseEvents, interactiveAgentEnabled = true, onRetry, onStop, onStart, }) {
|
|
81
|
+
export function FeatureDrawerTabs({ featureName, headerContent, featureNode, featureId, initialTab, urlTab, prdData, prdSelections, onPrdSelect, onPrdApprove, onPrdReject, isPrdLoading, techData, onTechApprove, onTechReject, isTechLoading, productData, mergeData, onMergeApprove, onMergeReject, isMergeLoading, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, isRejecting, chatInput, onChatInputChange, pinnedConfig, continuationActionsDisabled = false, sseEvents, interactiveAgentEnabled = true, onRetry, onStop, onStart, }) {
|
|
82
82
|
const pathname = usePathname();
|
|
83
83
|
const visibleTabs = useMemo(() => computeVisibleTabs(featureNode, interactiveAgentEnabled), [featureNode, interactiveAgentEnabled]);
|
|
84
84
|
const visibleTabDefs = useMemo(() => ALL_TABS.filter((t) => visibleTabs.includes(t.key)).map((t) => t.key === 'merge-review' && featureNode.lifecycle === 'maintain'
|
|
@@ -261,9 +261,9 @@ export function FeatureDrawerTabs({ featureName, headerContent, featureNode, fea
|
|
|
261
261
|
}) }), _jsxs("div", { className: "bg-muted/40 shrink-0 border-b", children: [featureName ? (_jsxs("div", { className: "flex h-12 items-stretch gap-2 pr-0 pl-4", "data-testid": "feature-drawer-header", children: [_jsx("div", { className: "flex items-center", children: featureNode.fastMode ? (_jsx(Zap, { className: "size-4 shrink-0 text-amber-500" })) : (_jsx(Layers, { className: "text-muted-foreground/50 size-4 shrink-0" })) }), _jsx("h2", { className: "text-foreground flex min-w-0 items-center truncate text-base font-semibold tracking-tight", children: featureName }), featureNode.repositoryName ? (_jsxs("span", { className: "animate-in fade-in flex shrink-0 items-center gap-1.5 self-center duration-200", children: [_jsx("span", { className: "text-muted-foreground/30 text-sm", children: "/" }), featureNode.remoteUrl ? (_jsx("a", { href: featureNode.remoteUrl, target: "_blank", rel: "noopener noreferrer", className: "text-muted-foreground hover:text-foreground text-sm", children: featureNode.repositoryName })) : (_jsx("span", { className: "text-muted-foreground text-sm", children: featureNode.repositoryName }))] })) : (_jsxs("span", { className: "flex items-center gap-1.5 self-center", children: [_jsx("span", { className: "text-muted-foreground/30 text-sm", children: "/" }), _jsx("span", { className: "bg-muted h-4 w-16 animate-pulse rounded" })] })), _jsx(TooltipProvider, { delayDuration: 300, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "ml-auto flex shrink-0 cursor-default items-center self-stretch text-xs font-medium", children: [_jsxs("div", { className: cn('flex items-center gap-1.5 self-stretch px-3', featureNodeStateConfig[featureNode.state].labelClass), children: [featureNode.state === 'running' ? (_jsx(CometSpinner, { size: "sm", className: "shrink-0" })) : ((() => {
|
|
262
262
|
const I = featureNodeStateConfig[featureNode.state].icon;
|
|
263
263
|
return _jsx(I, { className: "size-3.5 shrink-0" });
|
|
264
|
-
})()), featureNodeStateConfig[featureNode.state].label] }), featureNode.state === 'pending' && onStart ? (_jsxs("button", { type: "button", onClick: () => onStart(featureNode.featureId), className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-green-500/10 hover:text-green-600 dark:hover:text-green-400", "data-testid": "feature-drawer-start-button", children: [_jsx(Play, { className: "size-3.5" }), " Start"] })) : featureNode.state === 'error' && onRetry ? (_jsxs("button", { type: "button", onClick: () => onRetry(featureNode.featureId), className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400", "data-testid": "feature-drawer-retry-button", children: [_jsx(RotateCcw, { className: "size-3.5" }), " Retry"] })) : featureNode.state === 'running' && onStop ? (_jsxs("button", { type: "button", onClick: () => onStop(featureNode.featureId), className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400", "data-testid": "feature-drawer-stop-button", children: [_jsx(Square, { className: "size-3.5" }), " Stop"] })) : null] }) }), featureNode.errorMessage ? (_jsxs(TooltipContent, { side: "bottom", align: "end", sideOffset: 4, className: "z-[100] max-w-xs cursor-pointer text-xs leading-relaxed select-text", onClick: () => {
|
|
264
|
+
})()), featureNodeStateConfig[featureNode.state].label] }), featureNode.state === 'pending' && onStart ? (_jsxs("button", { type: "button", onClick: () => onStart(featureNode.featureId), disabled: continuationActionsDisabled, className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-green-500/10 hover:text-green-600 disabled:pointer-events-none disabled:opacity-50 dark:hover:text-green-400", "data-testid": "feature-drawer-start-button", children: [_jsx(Play, { className: "size-3.5" }), " Start"] })) : featureNode.state === 'error' && onRetry ? (_jsxs("button", { type: "button", onClick: () => onRetry(featureNode.featureId), disabled: continuationActionsDisabled, className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 disabled:pointer-events-none disabled:opacity-50 dark:hover:text-red-400", "data-testid": "feature-drawer-retry-button", children: [_jsx(RotateCcw, { className: "size-3.5" }), " Retry"] })) : featureNode.state === 'running' && onStop ? (_jsxs("button", { type: "button", onClick: () => onStop(featureNode.featureId), className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400", "data-testid": "feature-drawer-stop-button", children: [_jsx(Square, { className: "size-3.5" }), " Stop"] })) : null] }) }), featureNode.errorMessage ? (_jsxs(TooltipContent, { side: "bottom", align: "end", sideOffset: 4, className: "z-[100] max-w-xs cursor-pointer text-xs leading-relaxed select-text", onClick: () => {
|
|
265
265
|
void navigator.clipboard.writeText(featureNode.errorMessage);
|
|
266
|
-
}, children: [featureNode.errorMessage, _jsx("span", { className: "text-muted-foreground ml-1 text-[10px] italic", children: "(click to copy)" })] })) : null] }) })] })) : null, headerContent] }), _jsx(TabsContent, { value: "overview", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(OverviewTab, { data: featureNode, syncStatus: syncStatus, syncLoading: syncLoading, syncError: syncError, onRefreshSync: onRefreshSync, onRebaseOnMain: onRebaseOnMain, rebaseLoading: rebaseLoading, rebaseError: rebaseError }) }), _jsx(TabsContent, { value: "activity", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(ActivityTab, { timings: tabs.activity.data?.timings ?? null, loading: tabs.activity.loading, error: tabs.activity.error, rejectionFeedback: tabs.activity.data?.rejectionFeedback }) }), _jsx(TabsContent, { value: "log", className: "mt-0 flex-1 overflow-hidden", children: _jsx(LogTab, { content: featureLogs.content, isConnected: featureLogs.isConnected, error: featureLogs.error }) }), _jsx(TabsContent, { value: "plan", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(PlanTab, { plan: tabs.plan.data, loading: tabs.plan.loading, error: tabs.plan.error }) }), visibleTabs.includes('prd-review') ? (_jsx(TabsContent, { value: "prd-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: prdData ? (_jsx(PrdQuestionnaire, { data: prdData, selections: prdSelections ?? {}, onSelect: onPrdSelect ?? (() => undefined), onApprove: onPrdApprove ?? (() => undefined), onReject: onPrdReject, isProcessing: isPrdLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('tech-decisions') ? (_jsx(TabsContent, { value: "tech-decisions", className: "mt-0 flex min-h-0 flex-1 flex-col", children: techData ? (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(TechDecisionsContent, { data: techData }) }), _jsx(DrawerActionBarForTech, { onApprove: onTechApprove ?? (() => undefined), onReject: onTechReject, isProcessing: isTechLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })] })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('product-decisions') ? (_jsx(TabsContent, { value: "product-decisions", className: "mt-0 flex-1 overflow-y-auto", children: productData === null ? (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) : productData ? (_jsx(ProductDecisionsSummary, { data: productData })) : (_jsx("p", { className: "text-muted-foreground p-4 text-center text-sm", children: "No product decisions available." })) })) : null, visibleTabs.includes('merge-review') ? (_jsx(TabsContent, { value: "merge-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: mergeData ? (_jsx(MergeReview, { data: mergeData, readOnly: featureNode.lifecycle === 'maintain', onApprove: onMergeApprove ?? (() => undefined), onReject: onMergeReject, isProcessing: isMergeLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: isMergeLoading ? (_jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" })) : (_jsxs("div", { className: "text-muted-foreground flex flex-col items-center gap-2 text-sm", children: [_jsx(AlertCircle, { className: "h-6 w-6" }), _jsx("span", { children: "Merge review data unavailable" })] })) })) })) : null, visibleTabs.includes('chat') ? (_jsx(TabsContent, { value: "chat", className: "mt-0 flex min-h-0 flex-1 flex-col overflow-hidden", children: _jsx(ChatTab, { featureId: featureId, worktreePath: featureNode.worktreePath }) })) : null] }) }));
|
|
266
|
+
}, children: [featureNode.errorMessage, _jsx("span", { className: "text-muted-foreground ml-1 text-[10px] italic", children: "(click to copy)" })] })) : null] }) })] })) : null, headerContent] }), _jsx(TabsContent, { value: "overview", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(OverviewTab, { data: featureNode, pinnedConfig: pinnedConfig, syncStatus: syncStatus, syncLoading: syncLoading, syncError: syncError, onRefreshSync: onRefreshSync, onRebaseOnMain: onRebaseOnMain, rebaseLoading: rebaseLoading, rebaseError: rebaseError }) }), _jsx(TabsContent, { value: "activity", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(ActivityTab, { timings: tabs.activity.data?.timings ?? null, loading: tabs.activity.loading, error: tabs.activity.error, rejectionFeedback: tabs.activity.data?.rejectionFeedback }) }), _jsx(TabsContent, { value: "log", className: "mt-0 flex-1 overflow-hidden", children: _jsx(LogTab, { content: featureLogs.content, isConnected: featureLogs.isConnected, error: featureLogs.error }) }), _jsx(TabsContent, { value: "plan", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(PlanTab, { plan: tabs.plan.data, loading: tabs.plan.loading, error: tabs.plan.error }) }), visibleTabs.includes('prd-review') ? (_jsx(TabsContent, { value: "prd-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: prdData ? (_jsx(PrdQuestionnaire, { data: prdData, selections: prdSelections ?? {}, onSelect: onPrdSelect ?? (() => undefined), onApprove: onPrdApprove ?? (() => undefined), onReject: onPrdReject, isProcessing: Boolean((isPrdLoading ?? false) || continuationActionsDisabled), isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('tech-decisions') ? (_jsx(TabsContent, { value: "tech-decisions", className: "mt-0 flex min-h-0 flex-1 flex-col", children: techData ? (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(TechDecisionsContent, { data: techData }) }), _jsx(DrawerActionBarForTech, { onApprove: onTechApprove ?? (() => undefined), onReject: onTechReject, isProcessing: Boolean((isTechLoading ?? false) || continuationActionsDisabled), isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })] })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('product-decisions') ? (_jsx(TabsContent, { value: "product-decisions", className: "mt-0 flex-1 overflow-y-auto", children: productData === null ? (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) : productData ? (_jsx(ProductDecisionsSummary, { data: productData })) : (_jsx("p", { className: "text-muted-foreground p-4 text-center text-sm", children: "No product decisions available." })) })) : null, visibleTabs.includes('merge-review') ? (_jsx(TabsContent, { value: "merge-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: mergeData ? (_jsx(MergeReview, { data: mergeData, readOnly: featureNode.lifecycle === 'maintain', onApprove: onMergeApprove ?? (() => undefined), onReject: onMergeReject, isProcessing: Boolean((isMergeLoading ?? false) || continuationActionsDisabled), isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: isMergeLoading ? (_jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" })) : (_jsxs("div", { className: "text-muted-foreground flex flex-col items-center gap-2 text-sm", children: [_jsx(AlertCircle, { className: "h-6 w-6" }), _jsx("span", { children: "Merge review data unavailable" })] })) })) })) : null, visibleTabs.includes('chat') ? (_jsx(TabsContent, { value: "chat", className: "mt-0 flex min-h-0 flex-1 flex-col overflow-hidden", children: _jsx(ChatTab, { featureId: featureId, worktreePath: featureNode.worktreePath }) })) : null] }) }));
|
|
267
267
|
}
|
|
268
268
|
// ── Private helper ──────────────────────────────────────────────────────
|
|
269
269
|
function DrawerActionBarForTech({ onApprove, onReject, isProcessing, isRejecting, chatInput, onChatInputChange, }) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { FeatureNodeData } from '../../common/feature-node/index.js';
|
|
2
2
|
import type { BranchSyncData } from '../../../hooks/use-branch-sync-status.js';
|
|
3
|
+
import { type FeatureDrawerPinnedConfig } from './pinned-config-utils.js';
|
|
3
4
|
export interface OverviewTabProps {
|
|
4
5
|
data: FeatureNodeData;
|
|
6
|
+
pinnedConfig?: FeatureDrawerPinnedConfig;
|
|
5
7
|
syncStatus?: BranchSyncData | null;
|
|
6
8
|
syncLoading?: boolean;
|
|
7
9
|
syncError?: string | null;
|
|
@@ -10,5 +12,5 @@ export interface OverviewTabProps {
|
|
|
10
12
|
rebaseLoading?: boolean;
|
|
11
13
|
rebaseError?: string | null;
|
|
12
14
|
}
|
|
13
|
-
export declare function OverviewTab({ data, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }: OverviewTabProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function OverviewTab({ data, pinnedConfig, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }: OverviewTabProps): import("react/jsx-runtime").JSX.Element;
|
|
14
16
|
//# sourceMappingURL=overview-tab.d.ts.map
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overview-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"overview-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAQxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AA2G9F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC,UAAU,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,GACZ,EAAE,gBAAgB,2CAuLlB"}
|
|
@@ -10,9 +10,11 @@ import { CiStatusBadge } from '../../common/ci-status-badge/index.js';
|
|
|
10
10
|
import { CometSpinner } from '../../ui/comet-spinner.js';
|
|
11
11
|
import { ActionButton } from '../../common/action-button/index.js';
|
|
12
12
|
import { featureNodeStateConfig } from '../../common/feature-node/index.js';
|
|
13
|
+
import { AgentModelPicker } from '../../features/settings/AgentModelPicker/index.js';
|
|
13
14
|
import { getAgentTypeIcon, agentTypeLabels, } from '../../common/feature-node/agent-type-icons.js';
|
|
14
15
|
import { getModelMeta } from '../../../lib/model-metadata.js';
|
|
15
16
|
import { formatDuration } from '../../../lib/format-duration.js';
|
|
17
|
+
import { canSwitchPinnedConfig } from './pinned-config-utils.js';
|
|
16
18
|
// ── Primitives ──────────────────────────────────────────────────────
|
|
17
19
|
function Section({ icon: Icon, title, children, }) {
|
|
18
20
|
return (_jsxs("div", { className: "px-3 pt-4 pb-1", children: [_jsxs("div", { className: "text-foreground mb-2 flex items-center gap-1.5 text-sm font-semibold tracking-wider uppercase", children: [_jsx(Icon, { className: "size-4 opacity-50" }), title] }), children] }));
|
|
@@ -74,7 +76,7 @@ const prColor = {
|
|
|
74
76
|
[PrStatus.Merged]: 'text-purple-600 dark:text-purple-400',
|
|
75
77
|
[PrStatus.Closed]: 'text-red-600 dark:text-red-400',
|
|
76
78
|
};
|
|
77
|
-
export function OverviewTab({ data, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }) {
|
|
79
|
+
export function OverviewTab({ data, pinnedConfig, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }) {
|
|
78
80
|
const isCompleted = data.lifecycle === 'maintain';
|
|
79
81
|
const isRunning = data.state === 'running' || data.state === 'action-required';
|
|
80
82
|
const elapsedTime = useElapsedTime(isRunning ? data.startedAt : undefined);
|
|
@@ -86,7 +88,7 @@ export function OverviewTab({ data, syncStatus, syncLoading, syncError, onRefres
|
|
|
86
88
|
return _jsx(I, { className: "size-3.5 shrink-0 opacity-50" });
|
|
87
89
|
})()
|
|
88
90
|
: null, data.agentType ? (_jsx("span", { children: agentTypeLabels[data.agentType] ??
|
|
89
|
-
data.agentType })) : null, data.agentType && data.modelId ? (_jsx("span", { className: "text-foreground/20", children: "/" })) : null, data.modelId ? (_jsx("span", { className: "text-foreground/50 text-[12px]", children: getModelMeta(data.modelId).displayName || data.modelId })) : null] }) }) })) : null, data.createdAt ? (_jsx(Card, { children: _jsx(KV, { label: "Created", children: _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(Clock, { className: "text-foreground/30 size-3 shrink-0" }), formatRelativeTime(data.createdAt)] }) }) })) : null, data.fastMode ? (_jsx(Card, { children: _jsx(KV, { label: "Mode", children: _jsxs("span", { className: "inline-flex items-center gap-1 text-amber-600 dark:text-amber-400", children: [_jsx(Zap, { className: "size-3.5" }), " Fast"] }) }) })) : null, data.runtime || elapsedTime ? (_jsx(Card, { children: _jsx(KV, { label: data.runtime ? 'Runtime' : 'Elapsed', children: _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(Clock, { className: "text-foreground/30 size-3 shrink-0" }), data.runtime ?? elapsedTime] }) }) })) : null] }), data.blockedBy || data.errorMessage ? (_jsx(Section, { icon: AlertTriangle, title: "Issues", children: _jsxs(Card, { className: "border-destructive/20 bg-destructive/5", children: [data.blockedBy ? _jsx(KV, { label: "Blocked By", children: data.blockedBy }) : null, data.errorMessage ? (_jsx(KV, { label: "Error", children: _jsx("span", { className: "text-destructive", children: data.errorMessage }) })) : null] }) })) : null, onRebaseOnMain && data.branch && onRefreshSync ? (_jsx(Section, { icon: RefreshCw, title: "Branch Sync", children: _jsx(SyncCard, { syncStatus: syncStatus ?? null, syncLoading: syncLoading ?? false, syncError: syncError ?? null, onRefreshSync: onRefreshSync, onRebaseOnMain: onRebaseOnMain, rebaseLoading: rebaseLoading ?? false, rebaseError: rebaseError ?? null }) })) : null, _jsx(SettingsBlock, { data: data })] }));
|
|
91
|
+
data.agentType })) : null, data.agentType && data.modelId ? (_jsx("span", { className: "text-foreground/20", children: "/" })) : null, data.modelId ? (_jsx("span", { className: "text-foreground/50 text-[12px]", children: getModelMeta(data.modelId).displayName || data.modelId })) : null] }) }) })) : null, data.createdAt ? (_jsx(Card, { children: _jsx(KV, { label: "Created", children: _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(Clock, { className: "text-foreground/30 size-3 shrink-0" }), formatRelativeTime(data.createdAt)] }) }) })) : null, data.fastMode ? (_jsx(Card, { children: _jsx(KV, { label: "Mode", children: _jsxs("span", { className: "inline-flex items-center gap-1 text-amber-600 dark:text-amber-400", children: [_jsx(Zap, { className: "size-3.5" }), " Fast"] }) }) })) : null, data.runtime || elapsedTime ? (_jsx(Card, { children: _jsx(KV, { label: data.runtime ? 'Runtime' : 'Elapsed', children: _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(Clock, { className: "text-foreground/30 size-3 shrink-0" }), data.runtime ?? elapsedTime] }) }) })) : null] }), data.blockedBy || data.errorMessage ? (_jsx(Section, { icon: AlertTriangle, title: "Issues", children: _jsxs(Card, { className: "border-destructive/20 bg-destructive/5", children: [data.blockedBy ? _jsx(KV, { label: "Blocked By", children: data.blockedBy }) : null, data.errorMessage ? (_jsx(KV, { label: "Error", children: _jsx("span", { className: "text-destructive", children: data.errorMessage }) })) : null] }) })) : null, onRebaseOnMain && data.branch && onRefreshSync ? (_jsx(Section, { icon: RefreshCw, title: "Branch Sync", children: _jsx(SyncCard, { syncStatus: syncStatus ?? null, syncLoading: syncLoading ?? false, syncError: syncError ?? null, onRefreshSync: onRefreshSync, onRebaseOnMain: onRebaseOnMain, rebaseLoading: rebaseLoading ?? false, rebaseError: rebaseError ?? null }) })) : null, _jsx(SettingsBlock, { data: data, pinnedConfig: pinnedConfig })] }));
|
|
90
92
|
}
|
|
91
93
|
// ── Sync card ───────────────────────────────────────────────────────
|
|
92
94
|
function SyncCard({ syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }) {
|
|
@@ -97,19 +99,28 @@ function SyncCard({ syncStatus, syncLoading, syncError, onRefreshSync, onRebaseO
|
|
|
97
99
|
return (_jsxs(Card, { children: [_jsxs("div", { "data-testid": "branch-sync-status", className: "flex items-center justify-between", children: [_jsx("div", { className: "flex items-center gap-1.5 text-[13px]", children: syncLoading && !syncStatus ? (_jsxs(_Fragment, { children: [_jsx(CometSpinner, { size: "sm" }), _jsx("span", { className: "text-foreground/40", children: "Checking..." })] })) : syncError ? (_jsxs(_Fragment, { children: [_jsx(AlertTriangle, { className: "size-3.5 text-red-500" }), _jsx("span", { className: "text-destructive text-xs", children: syncError })] })) : rebaseLoading ? (_jsxs(_Fragment, { children: [_jsx(CometSpinner, { size: "sm" }), _jsxs("span", { children: ["Rebasing on ", _jsx("code", { className: "font-mono text-[11px]", children: base }), "..."] })] })) : isBehind ? (_jsxs(_Fragment, { children: [_jsx(AlertTriangle, { className: "size-3.5 text-orange-500" }), _jsxs("span", { children: [syncStatus.behind, " behind ", _jsx("code", { className: "font-mono text-[11px]", children: base }), syncStatus.ahead > 0 ? (_jsxs("span", { className: "text-foreground/30 ml-1 text-[11px]", children: ["\u00B7 ", syncStatus.ahead, " ahead"] })) : null] })] })) : isUpToDate ? (_jsxs(_Fragment, { children: [_jsx(CheckCircle2, { className: "size-3.5 text-green-500" }), _jsxs("span", { children: ["Up to date \u00B7 ", _jsx("code", { className: "font-mono text-[11px]", children: base }), syncStatus.ahead > 0 ? (_jsxs("span", { className: "text-foreground/30 ml-1 text-[11px]", children: ["\u00B7 ", syncStatus.ahead, " ahead"] })) : null] })] })) : null }), (syncStatus || syncError) && !rebaseLoading ? (_jsx("button", { onClick: onRefreshSync, disabled: syncLoading, className: "text-foreground/30 hover:text-foreground/60 hover:bg-foreground/5 inline-flex size-6 items-center justify-center rounded-sm disabled:opacity-50", "aria-label": t('branchSyncStatus.refreshSyncStatus'), children: _jsx(RefreshCw, { className: cn('size-3', syncLoading && 'animate-spin') }) })) : null] }), isBehind && !rebaseLoading ? (_jsx("div", { className: "pt-2", children: _jsx(ActionButton, { label: t('branchSyncStatus.rebaseOnMain'), onClick: onRebaseOnMain, loading: false, error: !!rebaseError, icon: GitMerge, variant: "outline", size: "sm" }) })) : null, rebaseError ? _jsx("p", { className: "text-destructive pt-1 text-[11px]", children: rebaseError }) : null] }));
|
|
98
100
|
}
|
|
99
101
|
// ── Settings ────────────────────────────────────────────────────────
|
|
100
|
-
function
|
|
101
|
-
const
|
|
102
|
+
function PinnedConfigCard({ pinnedConfig }) {
|
|
103
|
+
const AgentIcon = getAgentTypeIcon(pinnedConfig.agentType);
|
|
104
|
+
const modelName = pinnedConfig.modelId
|
|
105
|
+
? getModelMeta(pinnedConfig.modelId).displayName || pinnedConfig.modelId
|
|
106
|
+
: 'No model selected';
|
|
107
|
+
return (_jsxs(Card, { "data-testid": "feature-pinned-config-card", className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-foreground/40 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(Settings, { className: "size-3" }), " Pinned Execution"] }), _jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(AgentIcon, { className: "size-4 shrink-0 opacity-60" }), _jsx("span", { className: "font-medium", children: agentTypeLabels[pinnedConfig.agentType] ??
|
|
108
|
+
pinnedConfig.agentType }), _jsx("span", { className: "text-foreground/20", children: "/" }), _jsx("span", { className: "text-foreground/60", children: modelName })] }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Change the pinned agent and model before the next start, approval, or retry." })] }), _jsx(AgentModelPicker, { initialAgentType: pinnedConfig.agentType, initialModel: pinnedConfig.modelId, agentType: pinnedConfig.agentType, model: pinnedConfig.modelId, onSave: pinnedConfig.onSave, saveError: pinnedConfig.error, saving: pinnedConfig.saving, disabled: pinnedConfig.saving, mode: "settings" })] }));
|
|
109
|
+
}
|
|
110
|
+
function SettingsBlock({ data, pinnedConfig, }) {
|
|
111
|
+
const hasSettings = data.approvalGates != null ||
|
|
102
112
|
data.push != null ||
|
|
103
113
|
data.openPr != null ||
|
|
104
114
|
data.ciWatchEnabled != null ||
|
|
105
115
|
data.enableEvidence != null ||
|
|
106
116
|
data.forkAndPr != null ||
|
|
107
117
|
data.commitSpecs != null;
|
|
108
|
-
|
|
118
|
+
const showPinnedConfig = pinnedConfig != null && canSwitchPinnedConfig(data.state);
|
|
119
|
+
if (!hasSettings && !showPinnedConfig)
|
|
109
120
|
return null;
|
|
110
|
-
return (_jsx(Section, { icon: Settings, title: "Settings", children: _jsxs("div", { className: "grid grid-cols-3 gap-2", children: [data.approvalGates ? (_jsxs(Card, { children: [_jsxs("div", { className: "text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(ShieldCheck, { className: "size-3" }), " Approve"] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx(Flag, { on: data.approvalGates.allowPrd, label: "PRD" }), _jsx(Flag, { on: data.approvalGates.allowPlan, label: "Plan" }), _jsx(Flag, { on: data.approvalGates.allowMerge, label: "Merge" })] })] })) : null, data.enableEvidence != null ? (_jsxs(Card, { children: [_jsxs("div", { className: "text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(FileSearch, { className: "size-3" }), " Evidence"] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx(Flag, { on: data.enableEvidence, label: "Collect" }), data.commitEvidence != null ? (_jsx(Flag, { on: data.commitEvidence, label: "Add to PR" })) : null] })] })) : null, data.push != null ||
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
return (_jsx(Section, { icon: Settings, title: "Settings", children: _jsxs("div", { className: "flex flex-col gap-2", children: [showPinnedConfig ? _jsx(PinnedConfigCard, { pinnedConfig: pinnedConfig }) : null, hasSettings ? (_jsxs("div", { className: "grid grid-cols-3 gap-2", children: [data.approvalGates ? (_jsxs(Card, { children: [_jsxs("div", { className: "text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(ShieldCheck, { className: "size-3" }), " Approve"] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx(Flag, { on: data.approvalGates.allowPrd, label: "PRD" }), _jsx(Flag, { on: data.approvalGates.allowPlan, label: "Plan" }), _jsx(Flag, { on: data.approvalGates.allowMerge, label: "Merge" })] })] })) : null, data.enableEvidence != null ? (_jsxs(Card, { children: [_jsxs("div", { className: "text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(FileSearch, { className: "size-3" }), " Evidence"] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx(Flag, { on: data.enableEvidence, label: "Collect" }), data.commitEvidence != null ? (_jsx(Flag, { on: data.commitEvidence, label: "Add to PR" })) : null] })] })) : null, data.push != null ||
|
|
122
|
+
data.openPr != null ||
|
|
123
|
+
data.ciWatchEnabled != null ||
|
|
124
|
+
data.commitSpecs != null ||
|
|
125
|
+
data.forkAndPr != null ? (_jsxs(Card, { children: [_jsxs("div", { className: "text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(GitBranch, { className: "size-3" }), " Git"] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [data.push != null ? _jsx(Flag, { on: data.push, label: "Push" }) : null, data.openPr != null ? _jsx(Flag, { on: data.openPr, label: "PR" }) : null, data.ciWatchEnabled != null ? (_jsx(Flag, { on: data.ciWatchEnabled, label: "Watch" })) : null, data.commitSpecs != null ? _jsx(Flag, { on: data.commitSpecs, label: "Specs" }) : null, data.forkAndPr != null ? _jsx(Flag, { on: data.forkAndPr, label: "Fork" }) : null] })] })) : null] })) : null] }) }));
|
|
115
126
|
}
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export declare const DoneWithMergedPr: Story;
|
|
|
15
15
|
export declare const Blocked: Story;
|
|
16
16
|
/** Error state showing error message detail. */
|
|
17
17
|
export declare const Error: Story;
|
|
18
|
+
/** Pending feature with the pinned execution switch visible. */
|
|
19
|
+
export declare const PendingWithPinnedConfigSwitch: Story;
|
|
20
|
+
/** Pending feature showing inline save feedback for the pinned execution switch. */
|
|
21
|
+
export declare const PendingWithPinnedConfigError: Story;
|
|
18
22
|
/** Error state with retry button visible. */
|
|
19
23
|
export declare const ErrorWithRetry: Story;
|
|
20
24
|
/** Running state with stop button visible. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overview-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAclC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AA0G1C,uEAAuE;AACvE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,IAAI,EAAE,KAElB,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,KAAK,EAAE,KAEnB,CAAC;AAOF,6CAA6C;AAC7C,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,eAAe,EAAE,KAE7B,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAwBF,mEAAmE;AACnE,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAMF,0BAA0B;AAC1B,eAAO,MAAM,iBAAiB,EAAE,KAE/B,CAAC;AAEF,sBAAsB;AACtB,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,oBAAoB;AACpB,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,sBAAsB;AACtB,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,EAAE,KAclC,CAAC;AAqBF,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,EAAE,KAEpC,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,EAAE,KAO9B,CAAC;AAEF,+FAA+F;AAC/F,eAAO,MAAM,eAAe,EAAE,KAgB7B,CAAC;AAMF,oFAAoF;AACpF,eAAO,MAAM,eAAe,EAAE,KAY7B,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,EAAE,KAYrC,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,uBAAuB,EAAE,KAYrC,CAAC;AAEF,2CAA2C;AAC3C,eAAO,MAAM,oBAAoB,EAAE,KAYlC,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,EAAE,KAQjC,CAAC;AAMF,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,sCAAsC;AACtC,eAAO,MAAM,aAAa,EAAE,KAO3B,CAAC;AAEF,mCAAmC;AACnC,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC"}
|
|
1
|
+
{"version":3,"file":"overview-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAclC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AA0G1C,uEAAuE;AACvE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,IAAI,EAAE,KAElB,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,KAAK,EAAE,KAEnB,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,6BAA6B,EAAE,KAc3C,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,4BAA4B,EAAE,KAe1C,CAAC;AAOF,6CAA6C;AAC7C,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,eAAe,EAAE,KAE7B,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAwBF,mEAAmE;AACnE,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAMF,0BAA0B;AAC1B,eAAO,MAAM,iBAAiB,EAAE,KAE/B,CAAC;AAEF,sBAAsB;AACtB,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,oBAAoB;AACpB,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,sBAAsB;AACtB,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,EAAE,KAclC,CAAC;AAqBF,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,EAAE,KAEpC,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,EAAE,KAO9B,CAAC;AAEF,+FAA+F;AAC/F,eAAO,MAAM,eAAe,EAAE,KAgB7B,CAAC;AAMF,oFAAoF;AACpF,eAAO,MAAM,eAAe,EAAE,KAY7B,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,EAAE,KAYrC,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,uBAAuB,EAAE,KAYrC,CAAC;AAEF,2CAA2C;AAC3C,eAAO,MAAM,oBAAoB,EAAE,KAYlC,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,EAAE,KAQjC,CAAC;AAMF,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,KAW9B,CAAC;AAEF,sCAAsC;AACtC,eAAO,MAAM,aAAa,EAAE,KAO3B,CAAC;AAEF,mCAAmC;AACnC,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC"}
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js
CHANGED
|
@@ -133,6 +133,39 @@ export const Blocked = {
|
|
|
133
133
|
export const Error = {
|
|
134
134
|
args: { data: errorData },
|
|
135
135
|
};
|
|
136
|
+
/** Pending feature with the pinned execution switch visible. */
|
|
137
|
+
export const PendingWithPinnedConfigSwitch = {
|
|
138
|
+
args: {
|
|
139
|
+
data: {
|
|
140
|
+
...noProgressData,
|
|
141
|
+
state: 'pending',
|
|
142
|
+
agentType: 'codex-cli',
|
|
143
|
+
modelId: 'gpt-5.4',
|
|
144
|
+
},
|
|
145
|
+
pinnedConfig: {
|
|
146
|
+
agentType: 'codex-cli',
|
|
147
|
+
modelId: 'gpt-5.4',
|
|
148
|
+
onSave: async () => ({ ok: true }),
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
/** Pending feature showing inline save feedback for the pinned execution switch. */
|
|
153
|
+
export const PendingWithPinnedConfigError = {
|
|
154
|
+
args: {
|
|
155
|
+
data: {
|
|
156
|
+
...noProgressData,
|
|
157
|
+
state: 'pending',
|
|
158
|
+
agentType: 'claude-code',
|
|
159
|
+
modelId: 'claude-sonnet-4-6',
|
|
160
|
+
},
|
|
161
|
+
pinnedConfig: {
|
|
162
|
+
agentType: 'claude-code',
|
|
163
|
+
modelId: 'claude-sonnet-4-6',
|
|
164
|
+
error: 'Could not save pinned config',
|
|
165
|
+
onSave: async () => ({ ok: false, error: 'Could not save pinned config' }),
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
};
|
|
136
169
|
const errorWithRetryData = {
|
|
137
170
|
...errorData,
|
|
138
171
|
onRetry: fn(),
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FeatureNodeData } from '../../common/feature-node/index.js';
|
|
2
|
+
export interface PinnedConfigSelection {
|
|
3
|
+
agentType: NonNullable<FeatureNodeData['agentType']>;
|
|
4
|
+
modelId: string;
|
|
5
|
+
}
|
|
6
|
+
export interface FeatureDrawerPinnedConfig {
|
|
7
|
+
agentType: string;
|
|
8
|
+
modelId: string;
|
|
9
|
+
saving?: boolean;
|
|
10
|
+
error?: string | null;
|
|
11
|
+
onSave: (agentType: string, modelId: string) => Promise<{
|
|
12
|
+
ok: boolean;
|
|
13
|
+
error?: string;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
export declare function canSwitchPinnedConfig(state: FeatureNodeData['state']): boolean;
|
|
17
|
+
export declare function getPinnedConfigSelection(node: Pick<FeatureNodeData, 'agentType' | 'modelId'> | null | undefined): PinnedConfigSelection | null;
|
|
18
|
+
//# sourceMappingURL=pinned-config-utils.d.ts.map
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pinned-config-utils.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAQxE,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1F;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,OAAO,CAE9E;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,GACtE,qBAAqB,GAAG,IAAI,CAS9B"}
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const ELIGIBLE_PINNED_CONFIG_STATES = new Set([
|
|
2
|
+
'pending',
|
|
3
|
+
'action-required',
|
|
4
|
+
'error',
|
|
5
|
+
]);
|
|
6
|
+
export function canSwitchPinnedConfig(state) {
|
|
7
|
+
return ELIGIBLE_PINNED_CONFIG_STATES.has(state);
|
|
8
|
+
}
|
|
9
|
+
export function getPinnedConfigSelection(node) {
|
|
10
|
+
if (!node?.agentType) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
agentType: node.agentType,
|
|
15
|
+
modelId: node.modelId ?? '',
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -10,4 +10,6 @@ export declare const CodexCliSelected: Story;
|
|
|
10
10
|
export declare const DemoAgent: Story;
|
|
11
11
|
export declare const OverrideMode: Story;
|
|
12
12
|
export declare const Disabled: Story;
|
|
13
|
+
export declare const SavingState: Story;
|
|
14
|
+
export declare const ParentDrivenSelection: Story;
|
|
13
15
|
//# sourceMappingURL=AgentModelPicker.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentModelPicker.stories.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AgentModelPicker.stories.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,gBAAgB,CAevC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAqBnC,eAAO,MAAM,iBAAiB,EAAE,KAM/B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAM5B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAM9B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAOtB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,KASnC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
2
3
|
import { fn } from '@storybook/test';
|
|
3
4
|
import { AgentModelPicker } from './index.js';
|
|
4
5
|
const meta = {
|
|
@@ -14,6 +15,16 @@ const meta = {
|
|
|
14
15
|
},
|
|
15
16
|
};
|
|
16
17
|
export default meta;
|
|
18
|
+
function ParentDrivenSelectionDemo(props) {
|
|
19
|
+
const [selection, setSelection] = React.useState({
|
|
20
|
+
agentType: props.initialAgentType,
|
|
21
|
+
model: props.initialModel,
|
|
22
|
+
});
|
|
23
|
+
return (_jsx(AgentModelPicker, { ...props, agentType: selection.agentType, model: selection.model, onSave: async (agentType, model) => {
|
|
24
|
+
setSelection({ agentType, model });
|
|
25
|
+
return { ok: true };
|
|
26
|
+
} }));
|
|
27
|
+
}
|
|
17
28
|
export const ClaudeCodeDefault = {
|
|
18
29
|
args: {
|
|
19
30
|
initialAgentType: 'claude-code',
|
|
@@ -64,3 +75,19 @@ export const Disabled = {
|
|
|
64
75
|
disabled: true,
|
|
65
76
|
},
|
|
66
77
|
};
|
|
78
|
+
export const SavingState = {
|
|
79
|
+
args: {
|
|
80
|
+
initialAgentType: 'codex-cli',
|
|
81
|
+
initialModel: 'gpt-5.4',
|
|
82
|
+
mode: 'settings',
|
|
83
|
+
saving: true,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
export const ParentDrivenSelection = {
|
|
87
|
+
render: (args) => (_jsx(ParentDrivenSelectionDemo, { ...args })),
|
|
88
|
+
args: {
|
|
89
|
+
initialAgentType: 'claude-code',
|
|
90
|
+
initialModel: 'claude-sonnet-4-6',
|
|
91
|
+
mode: 'settings',
|
|
92
|
+
},
|
|
93
|
+
};
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
export interface AgentModelPickerProps {
|
|
2
2
|
initialAgentType: string;
|
|
3
3
|
initialModel: string;
|
|
4
|
+
agentType?: string;
|
|
5
|
+
model?: string;
|
|
4
6
|
onAgentModelChange?: (agentType: string, model: string) => void;
|
|
7
|
+
onSave?: (agentType: string, model: string) => Promise<AgentModelPickerSaveResult | void>;
|
|
8
|
+
saveError?: string | null;
|
|
9
|
+
saving?: boolean;
|
|
5
10
|
disabled?: boolean;
|
|
6
11
|
className?: string;
|
|
7
12
|
/** 'settings' persists to DB; 'override' only calls onAgentModelChange */
|
|
8
13
|
mode: 'settings' | 'override';
|
|
9
14
|
}
|
|
10
|
-
export
|
|
15
|
+
export interface AgentModelPickerSaveResult {
|
|
16
|
+
ok: boolean;
|
|
17
|
+
error?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function AgentModelPicker({ initialAgentType, initialModel, agentType: controlledAgentType, model: controlledModel, onAgentModelChange, onSave, saveError, saving, disabled, className, mode, }: AgentModelPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
11
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/components/features/settings/AgentModelPicker/index.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,IAAI,GACL,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/components/features/settings/AgentModelPicker/index.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAAC;IAC1F,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,gBAAgB,EAChB,YAAY,EACZ,SAAS,EAAE,mBAAmB,EAC9B,KAAK,EAAE,eAAe,EACtB,kBAAkB,EAClB,MAAM,EACN,SAAS,EACT,MAAM,EACN,QAAQ,EACR,SAAS,EACT,IAAI,GACL,EAAE,qBAAqB,2CAiOvB"}
|
|
@@ -9,13 +9,14 @@ import { getModelMeta } from '../../../../lib/model-metadata.js';
|
|
|
9
9
|
import { Button } from '../../../ui/button.js';
|
|
10
10
|
import { Popover, PopoverContent, PopoverTrigger } from '../../../ui/popover.js';
|
|
11
11
|
import { cn } from '../../../../lib/utils.js';
|
|
12
|
-
export function AgentModelPicker({ initialAgentType, initialModel, onAgentModelChange, disabled, className, mode, }) {
|
|
12
|
+
export function AgentModelPicker({ initialAgentType, initialModel, agentType: controlledAgentType, model: controlledModel, onAgentModelChange, onSave, saveError, saving, disabled, className, mode, }) {
|
|
13
13
|
const [open, setOpen] = React.useState(false);
|
|
14
14
|
const [groups, setGroups] = React.useState([]);
|
|
15
15
|
const [loading, setLoading] = React.useState(true);
|
|
16
|
-
const [agentType, setAgentType] = React.useState(initialAgentType);
|
|
17
|
-
const [model, setModel] = React.useState(initialModel);
|
|
18
|
-
const [
|
|
16
|
+
const [agentType, setAgentType] = React.useState(controlledAgentType ?? initialAgentType);
|
|
17
|
+
const [model, setModel] = React.useState(controlledModel ?? initialModel);
|
|
18
|
+
const [internalSaving, setInternalSaving] = React.useState(false);
|
|
19
|
+
const [internalError, setInternalError] = React.useState(null);
|
|
19
20
|
// 0 = agent list visible, 1 = model list visible
|
|
20
21
|
const [level, setLevel] = React.useState(0);
|
|
21
22
|
// Which agent's models to show (kept separate from level for animation)
|
|
@@ -25,9 +26,18 @@ export function AgentModelPicker({ initialAgentType, initialModel, onAgentModelC
|
|
|
25
26
|
.then(setGroups)
|
|
26
27
|
.finally(() => setLoading(false));
|
|
27
28
|
}, []);
|
|
28
|
-
// Reset drill-down when popover closes
|
|
29
29
|
React.useEffect(() => {
|
|
30
|
-
|
|
30
|
+
setAgentType(controlledAgentType ?? initialAgentType);
|
|
31
|
+
}, [controlledAgentType, initialAgentType]);
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
setModel(controlledModel ?? initialModel);
|
|
34
|
+
}, [controlledModel, initialModel]);
|
|
35
|
+
// Reset drill-down when popover transitions from open → closed (not on initial mount)
|
|
36
|
+
const prevOpenRef = React.useRef(open);
|
|
37
|
+
React.useEffect(() => {
|
|
38
|
+
const wasOpen = prevOpenRef.current;
|
|
39
|
+
prevOpenRef.current = open;
|
|
40
|
+
if (wasOpen && !open) {
|
|
31
41
|
const t = setTimeout(() => {
|
|
32
42
|
setLevel(0);
|
|
33
43
|
setDrillAgent(null);
|
|
@@ -49,37 +59,35 @@ export function AgentModelPicker({ initialAgentType, initialModel, onAgentModelC
|
|
|
49
59
|
setOpen(false);
|
|
50
60
|
if (newAgentType === agentType && newModel === model)
|
|
51
61
|
return;
|
|
62
|
+
setInternalError(null);
|
|
52
63
|
if (mode === 'override') {
|
|
53
64
|
setAgentType(newAgentType);
|
|
54
65
|
setModel(newModel);
|
|
55
66
|
onAgentModelChange?.(newAgentType, newModel);
|
|
56
67
|
return;
|
|
57
68
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
setAgentType(newAgentType);
|
|
62
|
-
setModel(newModel);
|
|
63
|
-
onAgentModelChange?.(newAgentType, newModel);
|
|
64
|
-
setError(null);
|
|
69
|
+
const persistSelection = onSave ??
|
|
70
|
+
(async (nextAgentType, nextModel) => updateAgentAndModel(nextAgentType, nextModel || null));
|
|
71
|
+
setInternalSaving(true);
|
|
65
72
|
try {
|
|
66
|
-
const result = await
|
|
67
|
-
if (!result.ok) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
setModel(prevModel);
|
|
71
|
-
onAgentModelChange?.(prevAgent, prevModel);
|
|
72
|
-
setError(result.error ?? 'Failed to save');
|
|
73
|
+
const result = await persistSelection(newAgentType, newModel);
|
|
74
|
+
if (result && 'ok' in result && !result.ok) {
|
|
75
|
+
setInternalError(result.error ?? 'Failed to save');
|
|
76
|
+
return;
|
|
73
77
|
}
|
|
78
|
+
setAgentType(newAgentType);
|
|
79
|
+
setModel(newModel);
|
|
80
|
+
onAgentModelChange?.(newAgentType, newModel);
|
|
74
81
|
}
|
|
75
82
|
catch {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
setInternalError('Failed to save');
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
setInternalSaving(false);
|
|
80
87
|
}
|
|
81
88
|
};
|
|
82
|
-
const isDisabled = (disabled ?? false) || loading;
|
|
89
|
+
const isDisabled = (disabled ?? false) || loading || (saving ?? false) || internalSaving;
|
|
90
|
+
const error = saveError ?? internalError;
|
|
83
91
|
const AgentIcon = getAgentTypeIcon(agentType);
|
|
84
92
|
const agentLabel = groups.find((g) => g.agentType === agentType)?.label ?? agentType;
|
|
85
93
|
const modelName = model ? getModelMeta(model).displayName || model : null;
|