@shepai/cli 1.122.2-pr392.a8f2b76 → 1.122.2-pr394.daae4c9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/core/src/application/ports/output/repositories/feature-repository.interface.d.ts +11 -0
- package/dist/packages/core/src/application/ports/output/repositories/feature-repository.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts +15 -0
- package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts +40 -0
- package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.js +146 -0
- package/dist/packages/core/src/application/use-cases/features/branch-name-utils.d.ts +33 -0
- package/dist/packages/core/src/application/use-cases/features/branch-name-utils.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/features/branch-name-utils.js +77 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +5 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +8 -0
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +15 -0
- package/dist/src/presentation/cli/commands/feat/adopt.command.d.ts +14 -0
- package/dist/src/presentation/cli/commands/feat/adopt.command.d.ts.map +1 -0
- package/dist/src/presentation/cli/commands/feat/adopt.command.js +43 -0
- package/dist/src/presentation/cli/commands/feat/index.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/index.js +3 -1
- package/dist/src/presentation/web/app/(dashboard)/@drawer/adopt/page.d.ts +10 -0
- package/dist/src/presentation/web/app/(dashboard)/@drawer/adopt/page.d.ts.map +1 -0
- package/dist/src/presentation/web/app/(dashboard)/@drawer/adopt/page.js +22 -0
- package/dist/src/presentation/web/app/actions/adopt-branch.d.ts +11 -0
- package/dist/src/presentation/web/app/actions/adopt-branch.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/adopt-branch.js +20 -0
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts +0 -2
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/get-feature-phase-timings.js +0 -2
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.d.ts +9 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.js +27 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.d.ts +32 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-branch-drawer.stories.js +115 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-drawer-client.d.ts +5 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-drawer-client.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/adopt-drawer-client.js +56 -0
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +9 -20
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/activity-tab.js +31 -130
- 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 +0 -13
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.js +9 -18
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +18 -18
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +17 -31
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.js +22 -29
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +1 -1
- package/dist/src/presentation/web/components/layouts/app-shell/app-shell.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +14 -5
- package/dist/src/presentation/web/hooks/sidebar-features-context.d.ts +0 -2
- package/dist/src/presentation/web/hooks/sidebar-features-context.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/sidebar-features-context.js +1 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +1 -0
- package/web/.next/build-manifest.json +4 -4
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/routes-manifest.json +6 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/app-paths-manifest.json +3 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/build-manifest.json +18 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/next-font-manifest.json +6 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/react-loadable-manifest.json +1 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +320 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +20 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.map +5 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +2 -0
- package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +22 -22
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +28 -28
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +22 -22
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +28 -28
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +28 -28
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +20 -20
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +20 -20
- 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/page/build-manifest.json +2 -2
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/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/settings/page/build-manifest.json +2 -2
- package/web/.next/server/app/settings/page/server-reference-manifest.json +6 -6
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page.js +4 -4
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/build-manifest.json +2 -2
- 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/build-manifest.json +2 -2
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app-paths-manifest.json +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_94d75bc3._.js +3 -0
- package/web/.next/server/chunks/ssr/403f9_next_dist_client_components_94d75bc3._.js.map +1 -0
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_0b3f4f0d.js +3 -0
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_0b3f4f0d.js.map +1 -0
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_adopt-drawer-client_tsx_6c5e4bbb._.js +3 -0
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_adopt-drawer-client_tsx_6c5e4bbb._.js.map +1 -0
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_f30d0343.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_9f1775bb.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__06fef644._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2698e9f4._.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]__6bb00d90._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.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]__8c553503._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__8e3bf5d7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a022445f._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a7de2711._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c07f9f79._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c605a375._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e2227c0f._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e2227c0f._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e7258841._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e7258841._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ec26e818._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ec26e818._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f0589cc3._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f0589cc3._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_19a2fb35._.js +3 -0
- package/web/.next/server/chunks/ssr/_19a2fb35._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_1e1b2639._.js +3 -0
- package/web/.next/server/chunks/ssr/_1e1b2639._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js +1 -1
- package/web/.next/server/chunks/ssr/_2f6f48b8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_4093a637._.js +5 -0
- package/web/.next/server/chunks/ssr/_4093a637._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_36dccae9._.js → _5317c57e._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_36dccae9._.js.map → _5317c57e._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_a4a44cc0._.js +3 -0
- package/web/.next/server/chunks/ssr/_a4a44cc0._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_b56e7571._.js +3 -0
- package/web/.next/server/chunks/ssr/_b56e7571._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_d5206f22._.js +4 -0
- package/web/.next/server/chunks/ssr/_d5206f22._.js.map +1 -0
- 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/f7870_sonner_dist_index_mjs_dbf63824._.js +3 -0
- package/web/.next/server/chunks/ssr/f7870_sonner_dist_index_mjs_dbf63824._.js.map +1 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_026172d1._.js +3 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_026172d1._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_5f039db1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_2a52b697.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_c4337169._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/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/middleware-build-manifest.js +2 -2
- 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 +189 -34
- package/web/.next/static/chunks/0d2af96e64960ef5.css +1 -0
- package/web/.next/static/chunks/430ef376bd249b14.js +1 -0
- package/web/.next/static/chunks/4796c6e7d84294d7.js +1 -0
- package/web/.next/static/chunks/52c0456129cb8a10.js +1 -0
- package/web/.next/static/chunks/767cf20dbde41522.js +1 -0
- package/web/.next/static/chunks/78e2f79d08767e8d.js +9 -0
- package/web/.next/static/chunks/{90e7434ef9395b62.js → 7f0206527c67e121.js} +1 -1
- package/web/.next/static/chunks/{ed3a602003bcb31b.js → 89aac43287d73b02.js} +1 -1
- package/web/.next/static/chunks/{1c19bf1f99269544.js → 9f4eb9f1618c8bd9.js} +1 -1
- package/web/.next/static/chunks/a8d65187623d628b.js +5 -0
- package/web/.next/static/chunks/{816ee0f2c6b490a4.js → b14644925c7af7f5.js} +2 -2
- package/web/.next/static/chunks/b4a6061718adb25e.js +2 -0
- package/web/.next/static/chunks/bf108ed551e585e6.js +1 -0
- package/web/.next/static/chunks/c6356369a45d19d6.js +1 -0
- package/web/.next/static/chunks/ca946dcbfbb2df74.js +1 -0
- package/web/.next/static/chunks/cafcbd67d82d65db.js +1 -0
- package/web/.next/static/chunks/d6d6af31b7ef545b.js +1 -0
- package/web/.next/static/chunks/f83551c20dcda199.js +1 -0
- package/web/.next/static/chunks/{turbopack-426d9bc2450816ba.js → turbopack-080e470ea902d0ba.js} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__52485955._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__52485955._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__545792ab._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f646b99a._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f646b99a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js +0 -3
- package/web/.next/server/chunks/ssr/_0dc2cfd3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_3a4c94e3._.js +0 -3
- package/web/.next/server/chunks/ssr/_3a4c94e3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_75f4ccb3._.js +0 -3
- package/web/.next/server/chunks/ssr/_75f4ccb3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_9ac70f88._.js +0 -5
- package/web/.next/server/chunks/ssr/_9ac70f88._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_d99705a5._.js +0 -3
- package/web/.next/server/chunks/ssr/_d99705a5._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_60c91521._.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web_60c91521._.js.map +0 -1
- package/web/.next/static/chunks/275f0d403059b5b4.js +0 -1
- package/web/.next/static/chunks/3911a7175044e784.js +0 -1
- package/web/.next/static/chunks/52b56677c842e45f.js +0 -3
- package/web/.next/static/chunks/61df7e9671cf4e76.css +0 -1
- package/web/.next/static/chunks/6272719b144b6c1a.js +0 -11
- package/web/.next/static/chunks/691a93561029b01b.js +0 -2
- package/web/.next/static/chunks/6db4aa6aed9e6545.js +0 -1
- package/web/.next/static/chunks/845d8e58a91014e6.js +0 -1
- package/web/.next/static/chunks/a92706d178a3fa6c.js +0 -1
- package/web/.next/static/chunks/bf479173877b0a2f.js +0 -1
- package/web/.next/static/chunks/dbbb446493f21874.js +0 -1
- package/web/.next/static/chunks/f90f55b8e972bd8e.js +0 -1
- /package/web/.next/static/{x39t_TXToqcf-uNwPMhq8 → eu15XGqVtBSCUjVy2GmoQ}/_buildManifest.js +0 -0
- /package/web/.next/static/{x39t_TXToqcf-uNwPMhq8 → eu15XGqVtBSCUjVy2GmoQ}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{x39t_TXToqcf-uNwPMhq8 → eu15XGqVtBSCUjVy2GmoQ}/_ssgManifest.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useEffect, useRef } from 'react';
|
|
4
|
-
import { Loader2, AlertCircle, Clock, Zap, DollarSign
|
|
4
|
+
import { Loader2, AlertCircle, Clock, Zap, DollarSign } from 'lucide-react';
|
|
5
5
|
import { InlineAttachments } from '../../common/inline-attachments/index.js';
|
|
6
6
|
import { formatDuration } from '../../../lib/format-duration.js';
|
|
7
7
|
/**
|
|
@@ -51,13 +51,6 @@ function formatTokens(count) {
|
|
|
51
51
|
return `${(count / 1_000).toFixed(1)}K`;
|
|
52
52
|
return String(count);
|
|
53
53
|
}
|
|
54
|
-
/** Format a timestamp to a short local time string (e.g. "10:05:30 AM"). */
|
|
55
|
-
function formatTimestamp(value) {
|
|
56
|
-
const d = value instanceof Date ? value : new Date(String(value));
|
|
57
|
-
if (Number.isNaN(d.getTime()))
|
|
58
|
-
return '';
|
|
59
|
-
return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
60
|
-
}
|
|
61
54
|
/** Format a USD cost with appropriate precision. */
|
|
62
55
|
function formatCost(usd) {
|
|
63
56
|
if (usd >= 1)
|
|
@@ -75,48 +68,13 @@ const NODE_TO_PHASE = {
|
|
|
75
68
|
merge: 'Merging',
|
|
76
69
|
};
|
|
77
70
|
const LIFECYCLE_EVENTS = {
|
|
78
|
-
'run:started': {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
},
|
|
84
|
-
'run:
|
|
85
|
-
label: 'resumed',
|
|
86
|
-
colorClass: 'text-blue-600',
|
|
87
|
-
bgClass: 'bg-blue-50 dark:bg-blue-950/30',
|
|
88
|
-
icon: RotateCcw,
|
|
89
|
-
},
|
|
90
|
-
'run:completed': {
|
|
91
|
-
label: 'completed',
|
|
92
|
-
colorClass: 'text-emerald-600',
|
|
93
|
-
bgClass: 'bg-emerald-50 dark:bg-emerald-950/30',
|
|
94
|
-
icon: CheckCircle2,
|
|
95
|
-
},
|
|
96
|
-
'run:failed': {
|
|
97
|
-
label: 'failed',
|
|
98
|
-
colorClass: 'text-red-600',
|
|
99
|
-
bgClass: 'bg-red-50 dark:bg-red-950/30',
|
|
100
|
-
icon: XCircle,
|
|
101
|
-
},
|
|
102
|
-
'run:stopped': {
|
|
103
|
-
label: 'stopped',
|
|
104
|
-
colorClass: 'text-amber-600',
|
|
105
|
-
bgClass: 'bg-amber-50 dark:bg-amber-950/30',
|
|
106
|
-
icon: Square,
|
|
107
|
-
},
|
|
108
|
-
'run:crashed': {
|
|
109
|
-
label: 'crashed',
|
|
110
|
-
colorClass: 'text-red-600',
|
|
111
|
-
bgClass: 'bg-red-50 dark:bg-red-950/30',
|
|
112
|
-
icon: XCircle,
|
|
113
|
-
},
|
|
114
|
-
'run:rejected': {
|
|
115
|
-
label: 'rejected',
|
|
116
|
-
colorClass: 'text-orange-600',
|
|
117
|
-
bgClass: 'bg-orange-50 dark:bg-orange-950/30',
|
|
118
|
-
icon: Ban,
|
|
119
|
-
},
|
|
71
|
+
'run:started': { label: 'started', colorClass: 'text-blue-600' },
|
|
72
|
+
'run:resumed': { label: 'resumed', colorClass: 'text-blue-600' },
|
|
73
|
+
'run:completed': { label: 'completed', colorClass: 'text-emerald-600' },
|
|
74
|
+
'run:failed': { label: 'failed', colorClass: 'text-red-600' },
|
|
75
|
+
'run:stopped': { label: 'stopped', colorClass: 'text-amber-600' },
|
|
76
|
+
'run:crashed': { label: 'crashed', colorClass: 'text-red-600' },
|
|
77
|
+
'run:rejected': { label: 'rejected', colorClass: 'text-orange-600' },
|
|
120
78
|
};
|
|
121
79
|
function isLifecycleEvent(phase) {
|
|
122
80
|
return phase.startsWith('run:');
|
|
@@ -188,26 +146,6 @@ export function buildLifecycleTimeline(timings, feedback) {
|
|
|
188
146
|
}
|
|
189
147
|
return iterations;
|
|
190
148
|
}
|
|
191
|
-
/** Determine the outcome status of an iteration */
|
|
192
|
-
function getIterationOutcome(iteration) {
|
|
193
|
-
const lastLifecycle = [...iteration.timings].reverse().find((t) => isLifecycleEvent(t.phase));
|
|
194
|
-
if (!lastLifecycle)
|
|
195
|
-
return null;
|
|
196
|
-
switch (lastLifecycle.phase) {
|
|
197
|
-
case 'run:rejected':
|
|
198
|
-
return { label: 'Rejected', colorClass: 'text-orange-600', dotClass: 'bg-orange-500' };
|
|
199
|
-
case 'run:completed':
|
|
200
|
-
return { label: 'Completed', colorClass: 'text-emerald-600', dotClass: 'bg-emerald-500' };
|
|
201
|
-
case 'run:failed':
|
|
202
|
-
return { label: 'Failed', colorClass: 'text-red-600', dotClass: 'bg-red-500' };
|
|
203
|
-
case 'run:crashed':
|
|
204
|
-
return { label: 'Crashed', colorClass: 'text-red-600', dotClass: 'bg-red-500' };
|
|
205
|
-
case 'run:stopped':
|
|
206
|
-
return { label: 'Stopped', colorClass: 'text-amber-600', dotClass: 'bg-amber-500' };
|
|
207
|
-
default:
|
|
208
|
-
return null;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
149
|
/* ---------------------------------------------------------------------------
|
|
212
150
|
* Component
|
|
213
151
|
* ------------------------------------------------------------------------- */
|
|
@@ -217,10 +155,10 @@ export function ActivityTab({ timings, loading, error, rejectionFeedback }) {
|
|
|
217
155
|
return (_jsx("div", { "data-testid": "activity-tab-loading", className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) }));
|
|
218
156
|
}
|
|
219
157
|
if (error) {
|
|
220
|
-
return (_jsxs("div", { className: "flex items-center gap-2 p-4 text-
|
|
158
|
+
return (_jsxs("div", { className: "flex items-center gap-2 p-4 text-sm text-red-600", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0" }), _jsx("span", { children: error })] }));
|
|
221
159
|
}
|
|
222
160
|
if (!timings || timings.length === 0) {
|
|
223
|
-
return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [_jsx(Clock, { className: "text-muted-foreground h-8 w-8" }), _jsx("p", { className: "text-muted-foreground text-
|
|
161
|
+
return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [_jsx(Clock, { className: "text-muted-foreground h-8 w-8" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "No activity recorded yet" })] }));
|
|
224
162
|
}
|
|
225
163
|
const nodeTimings = timings.filter((t) => !isLifecycleEvent(t.phase));
|
|
226
164
|
const maxDurationMs = Math.max(...nodeTimings.map((t) => getEffectiveDuration(t, now)), ...nodeTimings.map((t) => t.approvalWaitMs ?? 0), 0);
|
|
@@ -231,70 +169,44 @@ export function ActivityTab({ timings, loading, error, rejectionFeedback }) {
|
|
|
231
169
|
const totalInputTokens = nodeTimings.reduce((sum, t) => sum + (t.inputTokens ?? 0), 0);
|
|
232
170
|
const totalOutputTokens = nodeTimings.reduce((sum, t) => sum + (t.outputTokens ?? 0), 0);
|
|
233
171
|
const totalCostUsd = nodeTimings.reduce((sum, t) => sum + (t.costUsd ?? 0), 0);
|
|
234
|
-
return (_jsxs("div", { className: "flex flex-col gap-
|
|
172
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsx("div", { "data-testid": "activity-timings", className: "flex flex-col gap-3", children: iterations.map((iteration) => (_jsx(IterationGroup, { iteration: iteration, showHeader: hasMultipleIterations, maxDurationMs: maxDurationMs, now: now }, iteration.number))) }), totalExecMs > 0 ? (_jsx(SummaryTotals, { totalExecMs: totalExecMs, totalWaitMs: totalWaitMs, totalInputTokens: totalInputTokens, totalOutputTokens: totalOutputTokens, totalCostUsd: totalCostUsd })) : null] }));
|
|
235
173
|
}
|
|
236
174
|
/* ---------------------------------------------------------------------------
|
|
237
175
|
* Iteration group — one cycle of work
|
|
238
176
|
* ------------------------------------------------------------------------- */
|
|
239
177
|
function IterationGroup({ iteration, showHeader, maxDurationMs, now, }) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
message = iteration.rejectionMessage;
|
|
249
|
-
}
|
|
250
|
-
else if (isFailure) {
|
|
251
|
-
const lastErrorPhase = [...iteration.timings]
|
|
252
|
-
.reverse()
|
|
253
|
-
.find((p) => !isLifecycleEvent(p.phase) && p.errorMessage);
|
|
254
|
-
message = lastErrorPhase?.errorMessage ?? t.errorMessage;
|
|
255
|
-
}
|
|
256
|
-
return (_jsx(LifecycleEventRow, { timing: t, message: message, attachments: isRejection ? iteration.rejectionAttachments : undefined, isFirst: idx === 0, isLast: idx === iteration.timings.length - 1 }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
|
|
257
|
-
}
|
|
258
|
-
return (_jsx(NodeTimingRow, { timing: t, maxDurationMs: maxDurationMs, now: now }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
|
|
259
|
-
})] })] }));
|
|
178
|
+
return (_jsxs("div", { "data-testid": `iteration-${iteration.number}`, className: "flex flex-col gap-1.5", children: [showHeader ? (_jsxs("div", { className: "text-muted-foreground text-xs font-medium", children: ["Iteration ", iteration.number] })) : null, iteration.timings.map((t) => {
|
|
179
|
+
if (isLifecycleEvent(t.phase)) {
|
|
180
|
+
// For run:rejected, the message comes from the iteration, not a separate map
|
|
181
|
+
const isRejection = t.phase === 'run:rejected';
|
|
182
|
+
return (_jsx(LifecycleEventRow, { timing: t, message: isRejection ? iteration.rejectionMessage : undefined, attachments: isRejection ? iteration.rejectionAttachments : undefined }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
|
|
183
|
+
}
|
|
184
|
+
return (_jsx(NodeTimingRow, { timing: t, maxDurationMs: maxDurationMs, now: now }, `${t.agentRunId}-${t.phase}-${t.startedAt}`));
|
|
185
|
+
})] }));
|
|
260
186
|
}
|
|
261
187
|
/* ---------------------------------------------------------------------------
|
|
262
188
|
* Row components
|
|
263
189
|
* ------------------------------------------------------------------------- */
|
|
264
|
-
function LifecycleEventRow({ timing, message, attachments,
|
|
190
|
+
function LifecycleEventRow({ timing, message, attachments, }) {
|
|
265
191
|
const event = LIFECYCLE_EVENTS[timing.phase];
|
|
266
192
|
if (!event)
|
|
267
193
|
return null;
|
|
268
194
|
const hasAttachments = attachments && attachments.length > 0;
|
|
269
|
-
|
|
270
|
-
return (_jsxs("div", { className: `relative flex flex-col gap-1 px-3 ${isFirst ? 'pt-2' : 'pt-1'} ${isLast ? 'pb-2' : 'pb-1'}`, children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: `relative z-10 flex h-5 w-5 shrink-0 items-center justify-center rounded-full ${event.bgClass}`, children: _jsx(Icon, { className: `h-3 w-3 ${event.colorClass}` }) }), _jsx("span", { className: `text-sm font-medium ${event.colorClass}`, children: event.label }), timing.startedAt &&
|
|
271
|
-
!(typeof timing.startedAt === 'string' && timing.startedAt.startsWith('synthetic')) ? (_jsx("span", { className: "text-muted-foreground/60 ml-auto text-xs tabular-nums", children: formatTimestamp(String(timing.startedAt)) })) : null] }), message
|
|
272
|
-
? (() => {
|
|
273
|
-
const isError = timing.phase === 'run:failed' ||
|
|
274
|
-
timing.phase === 'run:crashed' ||
|
|
275
|
-
timing.phase === 'run:stopped';
|
|
276
|
-
return (_jsxs("div", { className: `ml-[26px] flex items-start gap-1.5 rounded-md px-2 py-1.5 ${isError
|
|
277
|
-
? 'bg-red-50/50 dark:bg-red-950/20'
|
|
278
|
-
: 'bg-orange-50/50 dark:bg-orange-950/20'}`, children: [isError ? (_jsx(AlertCircle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-red-400" })) : (_jsx(MessageSquare, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-orange-400" })), _jsxs("span", { "data-testid": isError ? 'error-message-text' : 'rejection-feedback-text', className: "text-muted-foreground text-xs leading-relaxed italic", children: ["\u2014 ", message] })] }));
|
|
279
|
-
})()
|
|
280
|
-
: null, hasAttachments ? (_jsx("div", { "data-testid": "rejection-feedback-attachments", className: "ml-[26px]", children: _jsx(InlineAttachments, { text: "", attachmentPaths: attachments }) })) : null] }));
|
|
195
|
+
return (_jsxs("div", { className: `text-xs ${event.colorClass}`, children: [_jsx("span", { children: event.label }), message ? (_jsxs("span", { "data-testid": "rejection-feedback-text", className: "text-muted-foreground ml-2 font-normal italic", children: ["\u2014 ", message] })) : null, hasAttachments ? (_jsx("div", { "data-testid": "rejection-feedback-attachments", className: "mt-1.5 ml-2", children: _jsx(InlineAttachments, { text: "", attachmentPaths: attachments }) })) : null] }));
|
|
281
196
|
}
|
|
282
197
|
function NodeTimingRow({ timing, maxDurationMs, now, }) {
|
|
283
|
-
const base = timing.phase.includes(':') ? timing.phase.split(':')[0] : timing.phase;
|
|
284
198
|
const suffix = timing.phase.includes(':') ? timing.phase.split(':')[1] : null;
|
|
285
199
|
const isSubPhase = suffix !== null;
|
|
200
|
+
// Distinguish implementation sub-phases (phase-1, phase-2) from rejection retries (2, 3)
|
|
286
201
|
const isImplPhase = suffix?.startsWith('phase-') ?? false;
|
|
287
|
-
const baseName = NODE_TO_PHASE[base] ?? base;
|
|
288
202
|
const label = isImplPhase
|
|
289
203
|
? `Phase ${suffix.replace('phase-', '')}`
|
|
290
204
|
: suffix !== null
|
|
291
|
-
?
|
|
292
|
-
:
|
|
205
|
+
? `retry #${suffix}`
|
|
206
|
+
: (NODE_TO_PHASE[timing.phase] ?? timing.phase);
|
|
293
207
|
const durationMs = getEffectiveDuration(timing, now);
|
|
208
|
+
const barPercent = maxDurationMs > 0 ? Math.max(2, (durationMs / maxDurationMs) * 100) : 2;
|
|
294
209
|
const isRunning = !timing.completedAt && !!timing.startedAt;
|
|
295
|
-
// Running phases get a minimum 15% bar so they're always visually prominent
|
|
296
|
-
const minPercent = isRunning ? 15 : 2;
|
|
297
|
-
const barPercent = maxDurationMs > 0 ? Math.max(minPercent, (durationMs / maxDurationMs) * 100) : minPercent;
|
|
298
210
|
const barColorClass = timing.completedAt
|
|
299
211
|
? isImplPhase
|
|
300
212
|
? 'bg-emerald-400'
|
|
@@ -305,28 +217,17 @@ function NodeTimingRow({ timing, maxDurationMs, now, }) {
|
|
|
305
217
|
const totalTokens = timing.inputTokens != null || timing.outputTokens != null
|
|
306
218
|
? (timing.inputTokens ?? 0) + (timing.outputTokens ?? 0)
|
|
307
219
|
: null;
|
|
308
|
-
return (_jsxs("div", { className:
|
|
309
|
-
? 'bg-blue-500'
|
|
310
|
-
: timing.completedAt
|
|
311
|
-
? 'bg-emerald-500'
|
|
312
|
-
: 'bg-muted-foreground/30'}` }) }), _jsx("span", { className: `w-28 shrink-0 truncate text-sm font-medium ${isSubPhase ? 'text-muted-foreground' : 'text-foreground/80'}`, children: label }), _jsx("div", { className: `bg-muted relative min-w-0 flex-1 overflow-hidden rounded-full ${isSubPhase ? 'h-1.5' : 'h-2'}`, children: isRunning ? (_jsx("div", { className: "absolute inset-0 rounded-full bg-blue-500/30", style: {
|
|
313
|
-
backgroundImage: 'linear-gradient(90deg, transparent 0%, rgb(59 130 246) 50%, transparent 100%)',
|
|
314
|
-
backgroundSize: '200% 100%',
|
|
315
|
-
animation: 'shimmer 1.5s ease-in-out infinite',
|
|
316
|
-
} })) : (_jsx("div", { className: `h-full rounded-full transition-all duration-300 ${barColorClass}`, style: { width: `${Math.min(barPercent, 100)}%` } })) }), _jsx("span", { className: "text-muted-foreground w-14 shrink-0 text-right text-sm font-medium tabular-nums", children: formatDuration(durationMs) })] }), _jsxs("div", { className: "ml-[28px] flex items-center gap-3 text-xs", children: [timing.startedAt ? (_jsx("span", { className: "text-muted-foreground/60 tabular-nums", children: formatTimestamp(timing.startedAt) })) : null, totalTokens != null && totalTokens > 0 ? (_jsxs("span", { className: "text-muted-foreground/70 inline-flex items-center gap-0.5", children: [_jsx(Zap, { className: "h-3 w-3 opacity-50" }), formatTokens(totalTokens)] })) : null, timing.costUsd != null && timing.costUsd > 0 ? (_jsxs("span", { className: "text-muted-foreground/70 inline-flex items-center gap-0.5", children: [_jsx(DollarSign, { className: "h-3 w-3 opacity-50" }), formatCost(timing.costUsd)] })) : null] }), timing.approvalWaitMs != null && timing.approvalWaitMs > 0 ? (_jsx(ApprovalWaitRow, { timing: timing, maxDurationMs: maxDurationMs })) : null] }));
|
|
220
|
+
return (_jsxs("div", { className: isSubPhase ? 'flex flex-col gap-1 pl-6' : 'flex flex-col gap-1', children: [_jsxs("div", { "data-testid": `timing-bar-${timing.phase}`, className: "flex items-center gap-2", children: [_jsx("span", { className: `text-muted-foreground shrink-0 text-xs ${isSubPhase ? 'w-18' : 'w-24'}`, children: label }), _jsx("div", { className: `bg-muted min-w-0 flex-1 overflow-hidden rounded-full ${isSubPhase ? 'h-2.5' : 'h-3'}`, children: _jsx("div", { className: `h-full rounded-full ${barColorClass}${isRunning ? 'animate-pulse' : ''}`, style: { width: `${Math.min(barPercent, 100)}%` } }) }), _jsx("span", { className: "text-muted-foreground w-10 shrink-0 text-right text-xs tabular-nums", children: formatDuration(durationMs) }), _jsx("span", { className: "text-muted-foreground w-12 shrink-0 text-right text-[10px] tabular-nums", children: totalTokens != null && totalTokens > 0 ? (_jsxs("span", { className: "inline-flex items-center gap-0.5", children: [_jsx(Zap, { className: "h-2 w-2 opacity-50" }), formatTokens(totalTokens)] })) : null }), _jsx("span", { className: "text-muted-foreground w-14 shrink-0 text-right text-[10px] tabular-nums", children: timing.costUsd != null && timing.costUsd > 0 ? (_jsxs("span", { className: "inline-flex items-center gap-0.5", children: [_jsx(DollarSign, { className: "h-2 w-2 opacity-50" }), formatCost(timing.costUsd)] })) : null })] }), timing.approvalWaitMs != null && timing.approvalWaitMs > 0 ? (_jsx(ApprovalWaitRow, { timing: timing, maxDurationMs: maxDurationMs })) : null] }));
|
|
317
221
|
}
|
|
318
222
|
function ApprovalWaitRow({ timing, maxDurationMs, }) {
|
|
319
223
|
const waitMs = timing.approvalWaitMs ?? 0;
|
|
320
224
|
const barPercent = maxDurationMs > 0 ? Math.max(2, (waitMs / maxDurationMs) * 100) : 2;
|
|
321
|
-
return (_jsxs("div", { "data-testid": `approval-wait-${timing.phase}`, className: "
|
|
225
|
+
return (_jsxs("div", { "data-testid": `approval-wait-${timing.phase}`, className: "flex items-center gap-2 pl-4", children: [_jsx("span", { className: "text-muted-foreground w-20 shrink-0 text-xs", children: "approval" }), _jsx("div", { className: "bg-muted h-2.5 min-w-0 flex-1 overflow-hidden rounded-full", children: _jsx("div", { className: "h-full rounded-full bg-amber-500", style: { width: `${Math.min(barPercent, 100)}%` } }) }), _jsx("span", { className: "text-muted-foreground w-10 shrink-0 text-right text-xs tabular-nums", children: formatDuration(waitMs) }), _jsx("span", { className: "w-12 shrink-0" }), _jsx("span", { className: "w-14 shrink-0" })] }));
|
|
322
226
|
}
|
|
323
227
|
function SummaryTotals({ totalExecMs, totalWaitMs, totalInputTokens, totalOutputTokens, totalCostUsd, }) {
|
|
324
228
|
const totalTokens = totalInputTokens + totalOutputTokens;
|
|
325
|
-
return (_jsxs("div", { "data-testid": "activity-summary", className: "border-border
|
|
326
|
-
? formatDuration(totalExecMs + totalWaitMs)
|
|
327
|
-
: formatDuration(totalExecMs) }), _jsx(SummaryCell, { icon: DollarSign, label: "Cost", value: totalCostUsd > 0 ? formatCost(totalCostUsd) : 'n/a' }), _jsxs("div", { className: "col-span-2 flex flex-col gap-0.5", children: [_jsxs("span", { className: "text-muted-foreground flex items-center gap-1 text-xs", children: [_jsx(Zap, { className: "h-3 w-3 opacity-40" }), "Tokens"] }), totalTokens > 0 ? (_jsxs("span", { className: "flex items-center gap-2.5 text-sm tabular-nums", children: [_jsx("span", { children: formatTokens(totalTokens) }), _jsxs("span", { className: "text-muted-foreground flex items-center gap-3 text-xs", title: "Input tokens / Output tokens", children: [_jsxs("span", { className: "flex items-center gap-0.5", children: [_jsx(ArrowDownToLine, { className: "h-3 w-3 text-blue-500 opacity-60" }), formatTokens(totalInputTokens)] }), _jsxs("span", { className: "flex items-center gap-0.5", children: [_jsx(ArrowUpFromLine, { className: "h-3 w-3 text-emerald-500 opacity-60" }), formatTokens(totalOutputTokens)] })] })] })) : (_jsx("span", { className: "text-muted-foreground/40 text-sm italic tabular-nums", children: "n/a" }))] })] })] }));
|
|
229
|
+
return (_jsxs("div", { "data-testid": "activity-summary", className: "border-border flex flex-col gap-1.5 border-t pt-3", children: [_jsx(SummaryRow, { label: "Total execution", value: formatDuration(totalExecMs) }), totalWaitMs > 0 ? (_jsxs(_Fragment, { children: [_jsx(SummaryRow, { label: "Total wait", value: formatDuration(totalWaitMs) }), _jsx(SummaryRow, { label: "Total wall-clock", value: formatDuration(totalExecMs + totalWaitMs) })] })) : null, totalTokens > 0 ? (_jsx(SummaryRow, { label: "Total tokens", value: `${formatTokens(totalTokens)} (${formatTokens(totalInputTokens)} in · ${formatTokens(totalOutputTokens)} out)` })) : null, totalCostUsd > 0 ? _jsx(SummaryRow, { label: "Total cost", value: formatCost(totalCostUsd) }) : null] }));
|
|
328
230
|
}
|
|
329
|
-
function
|
|
330
|
-
|
|
331
|
-
return (_jsxs("div", { className: `flex flex-col gap-0.5 ${className}`, children: [_jsxs("span", { className: "text-muted-foreground flex items-center gap-1 text-xs", children: [_jsx(Icon, { className: "h-3 w-3 opacity-40" }), label] }), _jsx("span", { className: `text-sm tabular-nums ${isNA ? 'text-muted-foreground/40 italic' : ''}`, children: value })] }));
|
|
231
|
+
function SummaryRow({ label, value }) {
|
|
232
|
+
return (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: label }), _jsx("span", { className: "text-xs font-medium", children: value })] }));
|
|
332
233
|
}
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-drawer-tabs.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAS9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAMxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAQ9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAC;AA8C3F,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,gFAAgF;IAChF,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAGzC,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,QAAQ,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,WAAW,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAGjD,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC5E,cAAc,CAAC,EAAE,OAAO,CAAC;IAGzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAwBD,wBAAgB,iBAAiB,CAAC,EAChC,WAAW,EACX,SAAS,EACT,UAAU,EACV,MAAM,EACN,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,SAAS,EACT,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,SAAS,GACV,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"feature-drawer-tabs.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAS9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACzF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAMxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAQ9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAC;AA8C3F,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,gFAAgF;IAChF,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAGzC,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,QAAQ,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,WAAW,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAGjD,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC5E,cAAc,CAAC,EAAE,OAAO,CAAC;IAGzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAwBD,wBAAgB,iBAAiB,CAAC,EAChC,WAAW,EACX,SAAS,EACT,UAAU,EACV,MAAM,EACN,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,SAAS,EACT,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,SAAS,GACV,EAAE,sBAAsB,2CAiUxB"}
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js
CHANGED
|
@@ -220,19 +220,6 @@ export function FeatureDrawerTabs({ featureNode, featureId, initialTab, urlTab,
|
|
|
220
220
|
refreshTab(current);
|
|
221
221
|
}
|
|
222
222
|
}, [sseEvents, featureId, refreshTab]);
|
|
223
|
-
// Poll activity data while the feature is actively running.
|
|
224
|
-
// SSE events only fire on state transitions (phase completed, lifecycle changed),
|
|
225
|
-
// so during a long-running phase there are no events and the data goes stale.
|
|
226
|
-
// Poll every 5s when the feature is in a working state to keep data fresh.
|
|
227
|
-
const isFeatureActive = featureNode.state === 'running' || featureNode.state === 'creating';
|
|
228
|
-
useEffect(() => {
|
|
229
|
-
if (!isFeatureActive)
|
|
230
|
-
return;
|
|
231
|
-
const interval = setInterval(() => {
|
|
232
|
-
refreshTab('activity');
|
|
233
|
-
}, 5000);
|
|
234
|
-
return () => clearInterval(interval);
|
|
235
|
-
}, [isFeatureActive, refreshTab]);
|
|
236
223
|
const handleTabChange = useCallback((value) => {
|
|
237
224
|
const tab = value;
|
|
238
225
|
isUserInteraction.current = true;
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tab-data-fetch.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.ts"],"names":[],"mappings":"AAIA,yDAAyD;AACzD,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,iEAAiE;AACjE,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAExE,kDAAkD;AAClD,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,IAAI,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AAElE,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,MAAM;IACrD,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,iDAAiD;IACjD,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAMD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,GACvB,qBAAqB,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"use-tab-data-fetch.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.ts"],"names":[],"mappings":"AAIA,yDAAyD;AACzD,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,iEAAiE;AACjE,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAExE,kDAAkD;AAClD,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,IAAI,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AAElE,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,MAAM;IACrD,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,iDAAiD;IACjD,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAMD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,GACvB,qBAAqB,CAAC,CAAC,CAAC,CAmG1B"}
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/use-tab-data-fetch.js
CHANGED
|
@@ -54,16 +54,11 @@ export function useTabDataFetch(featureId, fetchers) {
|
|
|
54
54
|
const currentFeatureId = featureIdRef.current;
|
|
55
55
|
if (!fetcher)
|
|
56
56
|
return;
|
|
57
|
-
// Only show loading spinner when there's no existing data.
|
|
58
|
-
// On refresh (data already present), keep showing stale data while fetching
|
|
59
|
-
// to avoid flickering the entire tab on every poll cycle.
|
|
60
57
|
if (mountedRef.current) {
|
|
61
|
-
setTabStates((prev) => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return { ...prev, [tab]: { ...prev[tab], loading: true, error: null } };
|
|
66
|
-
});
|
|
58
|
+
setTabStates((prev) => ({
|
|
59
|
+
...prev,
|
|
60
|
+
[tab]: { ...prev[tab], loading: true, error: null },
|
|
61
|
+
}));
|
|
67
62
|
}
|
|
68
63
|
try {
|
|
69
64
|
const data = await fetcher(currentFeatureId);
|
|
@@ -76,15 +71,11 @@ export function useTabDataFetch(featureId, fetchers) {
|
|
|
76
71
|
}
|
|
77
72
|
catch (error) {
|
|
78
73
|
if (mountedRef.current) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
...prev,
|
|
85
|
-
[tab]: { data: existingData, loading: false, error: existingData ? null : message },
|
|
86
|
-
};
|
|
87
|
-
});
|
|
74
|
+
const message = error instanceof Error ? error.message : 'Failed to fetch tab data';
|
|
75
|
+
setTabStates((prev) => ({
|
|
76
|
+
...prev,
|
|
77
|
+
[tab]: { data: null, loading: false, error: message },
|
|
78
|
+
}));
|
|
88
79
|
}
|
|
89
80
|
}
|
|
90
81
|
}, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-center-empty-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"control-center-empty-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.tsx"],"names":[],"mappings":"AAqBA,MAAM,WAAW,4BAA4B;IAC3C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,uBAAuB,CAAC,EACtC,kBAAkB,EAClB,SAAS,GACV,EAAE,4BAA4B,kDA+I9B"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useCallback, useEffect } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { Github, Plus, TerminalSquare, Copy, Check, Loader2, CheckCircle2, AlertCircle, Terminal, } from 'lucide-react';
|
|
5
5
|
import { cn } from '../../../lib/utils.js';
|
|
6
6
|
import { pickFolder } from '../../common/add-repository-button/pick-folder.js';
|
|
7
7
|
import { isAgentSetupComplete } from '../../../app/actions/agent-setup-flag.js';
|
|
@@ -13,12 +13,12 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
13
13
|
const [loading, setLoading] = useState(false);
|
|
14
14
|
const [agentReady, setAgentReady] = useState(null);
|
|
15
15
|
const [authStatus, setAuthStatus] = useState(null);
|
|
16
|
-
const [cliExpanded, setCliExpanded] = useState(false);
|
|
17
16
|
useEffect(() => {
|
|
18
17
|
isAgentSetupComplete().then((done) => {
|
|
19
18
|
setAgentReady(done);
|
|
20
19
|
});
|
|
21
20
|
}, []);
|
|
21
|
+
// Background auth check — runs after agent setup is complete
|
|
22
22
|
useEffect(() => {
|
|
23
23
|
if (!agentReady)
|
|
24
24
|
return;
|
|
@@ -52,28 +52,28 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
52
52
|
}, []);
|
|
53
53
|
if (agentReady === null)
|
|
54
54
|
return null;
|
|
55
|
-
return (
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
animationDelay: '400ms',
|
|
61
|
-
animationDuration: '600ms',
|
|
62
|
-
animationFillMode: 'both',
|
|
63
|
-
}, children: [_jsxs("button", { type: "button", onClick: () => setCliExpanded(!cliExpanded), className: "text-muted-foreground hover:text-foreground flex cursor-pointer items-center gap-1.5 transition-colors duration-200", children: [_jsx(Terminal, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-sm", children: "or use the CLI" }), _jsx(ChevronDown, { className: cn('h-3.5 w-3.5 transition-transform duration-200', cliExpanded ? '' : 'rotate-180') })] }), cliExpanded ? (_jsx("div", { className: "animate-in fade-in slide-in-from-top-1 mt-3 w-80 duration-200", children: _jsxs("div", { "data-testid": "cli-code-block", className: "relative rounded-xl bg-zinc-900 px-5 py-4 font-mono text-[13px] leading-relaxed text-zinc-400", children: [_jsx("button", { type: "button", "data-testid": "cli-code-block-copy", onClick: handleCopy, className: "absolute top-3 right-3 cursor-pointer rounded-md p-1.5 text-zinc-600 transition-colors hover:bg-zinc-800 hover:text-zinc-300", "aria-label": "Copy commands", children: copied ? (_jsx(Check, { className: "h-3.5 w-3.5 text-emerald-400" })) : (_jsx(Copy, { className: "h-3.5 w-3.5" })) }), _jsx("div", { className: "space-y-1", children: commands.map((cmd) => (_jsxs("div", { className: "whitespace-nowrap", children: [_jsx("span", { className: "text-zinc-600 select-none", children: "$ " }), _jsx("span", { className: "text-zinc-300", children: cmd })] }, cmd))) })] }) })) : null] })) : null] }));
|
|
55
|
+
return (_jsx("div", { "data-testid": "control-center-empty-state", className: cn('flex flex-col items-center justify-center', className), children: _jsx("div", { className: "animate-in fade-in slide-in-from-bottom-2 w-96 rounded-2xl border border-white/30 bg-white/50 px-8 py-8 shadow-lg backdrop-blur-xl duration-300 dark:border-white/10 dark:bg-white/5", children: _jsxs("div", { className: "flex flex-col items-center gap-4", children: [_jsxs("div", { className: "mb-2 text-center", children: [_jsx("h1", { className: "text-xl font-bold tracking-tight", children: "Features" }), _jsx("p", { className: "text-muted-foreground text-sm font-light", children: "Control Center" })] }), !agentReady ? (
|
|
56
|
+
/* Step 1: Agent setup */
|
|
57
|
+
_jsx(WelcomeAgentSetup, { onComplete: handleAgentSetupComplete, className: "w-full" })) : (
|
|
58
|
+
/* Step 2: Add repository (shown immediately after agent is configured) */
|
|
59
|
+
_jsxs(_Fragment, { children: [_jsx(AgentAuthBanner, { status: authStatus, onRetry: handleRetryAuth }), _jsxs("div", { className: "text-muted-foreground flex items-center gap-2", children: [_jsx(Github, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-[10px] font-semibold tracking-widest uppercase", children: "Repositories" })] }), _jsxs("button", { type: "button", "data-testid": "empty-state-add-repository", onClick: handlePickerClick, disabled: loading, className: "border-border hover:border-foreground/40 flex w-full cursor-pointer items-center gap-2.5 rounded-md border border-dashed px-4 py-2.5 transition-colors disabled:cursor-wait disabled:opacity-50", children: [loading ? (_jsx(Loader2, { className: "text-muted-foreground h-4 w-4 animate-spin" })) : (_jsx(Plus, { className: "text-muted-foreground h-4 w-4" })), _jsx("span", { className: "text-xs font-medium", children: loading ? 'Opening…' : 'Add Repository' })] }), _jsxs("div", { className: "text-muted-foreground flex items-center gap-2", children: [_jsx("div", { className: "bg-border h-px w-10" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(TerminalSquare, { className: "h-3 w-3" }), _jsx("span", { className: "text-[10px] font-semibold tracking-widest uppercase", children: "Or via CLI" })] }), _jsx("div", { className: "bg-border h-px w-10" })] }), _jsxs("div", { "data-testid": "cli-code-block", className: "relative w-full rounded-md bg-zinc-900 px-3 py-2 font-mono text-[11px] text-zinc-300", children: [_jsx("button", { type: "button", "data-testid": "cli-code-block-copy", onClick: handleCopy, className: "absolute top-2 right-2 cursor-pointer rounded p-1 text-zinc-500 transition-colors hover:bg-zinc-800 hover:text-zinc-300", "aria-label": "Copy commands", children: copied ? _jsx(Check, { className: "h-3 w-3" }) : _jsx(Copy, { className: "h-3 w-3" }) }), _jsx("div", { className: "space-y-0.5", children: commands.map((cmd) => (_jsxs("div", { className: "whitespace-nowrap", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), _jsx("span", { children: cmd })] }, cmd))) })] }), _jsx("p", { className: "text-muted-foreground text-[10px]", children: "Feature will appear on canvas once created" })] }))] }) }) }));
|
|
64
60
|
}
|
|
65
|
-
/**
|
|
61
|
+
/** Compact auth status banner — shows checking/success/error states */
|
|
66
62
|
function AgentAuthBanner({ status, onRetry, }) {
|
|
63
|
+
// Still checking — show subtle spinner
|
|
67
64
|
if (!status) {
|
|
68
|
-
return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Loader2, { className: "text-muted-foreground
|
|
65
|
+
return (_jsxs("div", { className: "bg-muted/50 flex w-full items-center gap-2 rounded-md px-3 py-1.5", children: [_jsx(Loader2, { className: "text-muted-foreground h-3 w-3 animate-spin" }), _jsx("span", { className: "text-muted-foreground text-[10px]", children: "Checking agent setup\u2026" })] }));
|
|
69
66
|
}
|
|
67
|
+
// All good — compact success, auto-fades
|
|
70
68
|
if (status.installed && status.authenticated) {
|
|
71
|
-
return (_jsxs("div", { className: "animate-in fade-in flex items-center gap-2", children: [_jsx(CheckCircle2, { className: "h-
|
|
69
|
+
return (_jsxs("div", { className: "animate-in fade-in flex w-full items-center gap-2 rounded-md bg-emerald-500/10 px-3 py-1.5", children: [_jsx(CheckCircle2, { className: "h-3 w-3 text-emerald-600 dark:text-emerald-400" }), _jsxs("span", { className: "text-[10px] text-emerald-700 dark:text-emerald-300", children: [status.label, " ready"] })] }));
|
|
72
70
|
}
|
|
71
|
+
// Not installed
|
|
73
72
|
if (!status.installed) {
|
|
74
|
-
return (_jsxs("div", { className: "flex flex-col
|
|
73
|
+
return (_jsxs("div", { className: "flex w-full flex-col gap-2 rounded-md bg-amber-500/10 px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-600 dark:text-amber-400" }), _jsxs("span", { className: "text-[10px] font-medium text-amber-700 dark:text-amber-300", children: [status.label, " not installed"] })] }), status.binaryName ? (_jsxs("div", { className: "rounded bg-zinc-900 px-2 py-1 font-mono text-[10px] text-zinc-300", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), "npm install -g ", status.binaryName] })) : null, _jsx("button", { type: "button", onClick: onRetry, className: "self-start text-[10px] font-medium text-amber-700 underline underline-offset-2 hover:text-amber-900 dark:text-amber-300 dark:hover:text-amber-100", children: "Re-check" })] }));
|
|
75
74
|
}
|
|
76
|
-
|
|
75
|
+
// Installed but not authenticated
|
|
76
|
+
return (_jsxs("div", { className: "flex w-full flex-col gap-2 rounded-md bg-amber-500/10 px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-600 dark:text-amber-400" }), _jsxs("span", { className: "text-[10px] font-medium text-amber-700 dark:text-amber-300", children: [status.label, " needs authentication"] })] }), status.authCommand ? (_jsxs("div", { className: "rounded bg-zinc-900 px-2 py-1 font-mono text-[10px] text-zinc-300", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), status.authCommand] })) : null, _jsxs("div", { className: "flex items-center gap-2", children: [status.binaryName ? (_jsxs("button", { type: "button", "data-testid": "auth-banner-open-terminal", onClick: async () => {
|
|
77
77
|
try {
|
|
78
78
|
const toolId = status.agentType === 'claude-code' ? 'claude-code' : status.agentType;
|
|
79
79
|
await fetch(`/api/tools/${toolId}/launch`, { method: 'POST' });
|
|
@@ -81,5 +81,5 @@ function AgentAuthBanner({ status, onRetry, }) {
|
|
|
81
81
|
catch {
|
|
82
82
|
// best effort
|
|
83
83
|
}
|
|
84
|
-
}, className: "flex items-center gap-1.5 text-
|
|
84
|
+
}, className: "flex items-center gap-1 rounded border border-amber-600/30 px-2 py-0.5 text-[10px] font-medium text-amber-700 transition-colors hover:bg-amber-500/10 dark:text-amber-300", children: [_jsx(Terminal, { className: "h-2.5 w-2.5" }), "Open ", status.label] })) : null, _jsx("button", { type: "button", onClick: onRetry, className: "text-[10px] font-medium text-amber-700 underline underline-offset-2 hover:text-amber-900 dark:text-amber-300 dark:hover:text-amber-100", children: "Re-check" })] })] }));
|
|
85
85
|
}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAuB5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAuB5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CA2UzF"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.js
CHANGED
|
@@ -27,8 +27,8 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
27
27
|
const drawerTimerRef = useRef(null);
|
|
28
28
|
const { defaultViewport, onMoveEnd: handleViewportChange, resetViewport, } = useViewportPersistence();
|
|
29
29
|
const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleRetryFeature, handleStartFeature, handleStopFeature, handleDeleteRepository, createFeatureNode, setCallbacks, } = useControlCenterState(initialNodes, initialEdges);
|
|
30
|
-
// Publish sidebar features
|
|
31
|
-
const { setFeatures: setSidebarFeatures
|
|
30
|
+
// Publish sidebar features to context whenever feature node data changes
|
|
31
|
+
const { setFeatures: setSidebarFeatures } = useSidebarFeaturesContext();
|
|
32
32
|
const featureNodes = useMemo(() => nodes.filter((n) => n.type === 'featureNode'), [nodes]);
|
|
33
33
|
const sidebarKey = useMemo(() => {
|
|
34
34
|
return featureNodes
|
|
@@ -119,29 +119,21 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
119
119
|
guardedNavigate(() => router.push('/'));
|
|
120
120
|
}
|
|
121
121
|
}, [router, pathname, guardedNavigate]);
|
|
122
|
-
// Shared: after adding first repo, center canvas and open create drawer
|
|
123
|
-
const focusAndOpenDrawer = useCallback((repoPath) => {
|
|
124
|
-
// Wait for next render so the repo node exists in the DOM
|
|
125
|
-
setTimeout(() => {
|
|
126
|
-
fitView(AUTO_FOCUS_OPTIONS);
|
|
127
|
-
// Open the create-feature drawer after the fitView animation completes
|
|
128
|
-
drawerTimerRef.current = setTimeout(() => {
|
|
129
|
-
guardedNavigate(() => router.push(`/create?repo=${encodeURIComponent(repoPath)}`));
|
|
130
|
-
}, AUTO_FOCUS_DRAWER_DELAY_MS);
|
|
131
|
-
}, 0);
|
|
132
|
-
}, [fitView, guardedNavigate, router]);
|
|
133
|
-
// Wrapper: add repo + auto-focus if canvas was empty
|
|
134
|
-
const addRepoAndFocus = useCallback((path) => {
|
|
135
|
-
const { wasEmpty, repoPath } = handleAddRepository(path);
|
|
136
|
-
if (wasEmpty) {
|
|
137
|
-
focusAndOpenDrawer(repoPath);
|
|
138
|
-
}
|
|
139
|
-
}, [handleAddRepository, focusAndOpenDrawer]);
|
|
140
122
|
// Listen for global "add repository" events from the top bar button
|
|
141
123
|
useEffect(() => {
|
|
142
124
|
const handler = (e) => {
|
|
143
125
|
const path = e.detail.path;
|
|
144
|
-
|
|
126
|
+
const { wasEmpty, repoPath } = handleAddRepository(path);
|
|
127
|
+
if (wasEmpty) {
|
|
128
|
+
// Wait for next render so the repo node exists in the DOM, then auto-focus
|
|
129
|
+
setTimeout(() => {
|
|
130
|
+
fitView(AUTO_FOCUS_OPTIONS);
|
|
131
|
+
// Open the create-feature drawer after the fitView animation completes
|
|
132
|
+
drawerTimerRef.current = setTimeout(() => {
|
|
133
|
+
guardedNavigate(() => router.push(`/create?repo=${encodeURIComponent(repoPath)}`));
|
|
134
|
+
}, AUTO_FOCUS_DRAWER_DELAY_MS);
|
|
135
|
+
}, 0);
|
|
136
|
+
}
|
|
145
137
|
};
|
|
146
138
|
window.addEventListener('shep:add-repository', handler);
|
|
147
139
|
return () => {
|
|
@@ -150,7 +142,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
150
142
|
clearTimeout(drawerTimerRef.current);
|
|
151
143
|
}
|
|
152
144
|
};
|
|
153
|
-
}, [
|
|
145
|
+
}, [handleAddRepository, fitView, guardedNavigate, router]);
|
|
154
146
|
// Listen for create events from the create drawer (with real feature ID from server)
|
|
155
147
|
useEffect(() => {
|
|
156
148
|
const handler = (e) => {
|
|
@@ -220,10 +212,6 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
220
212
|
handleViewportChange(viewport);
|
|
221
213
|
}, [handleViewportChange]);
|
|
222
214
|
const hasRepositories = nodes.some((n) => n.type === 'repositoryNode');
|
|
223
|
-
// Publish repo state to sidebar context so AppShell can hide FAB during onboarding
|
|
224
|
-
useEffect(() => {
|
|
225
|
-
setSidebarHasRepos(hasRepositories);
|
|
226
|
-
}, [hasRepositories, setSidebarHasRepos]);
|
|
227
215
|
// Debounced latch: prevent empty-state flicker during brief reconcile gaps
|
|
228
216
|
// (e.g. stale poll momentarily drops repos), but allow the empty state to
|
|
229
217
|
// return after a real delete once repos stay gone past the debounce window.
|
|
@@ -239,9 +227,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
239
227
|
setShowCanvas(true);
|
|
240
228
|
}
|
|
241
229
|
else if (showCanvas) {
|
|
242
|
-
// Repos gone —
|
|
243
|
-
// then wait before showing empty state (debounce stale polls)
|
|
244
|
-
resetViewport();
|
|
230
|
+
// Repos gone — wait before showing empty state (debounce stale polls)
|
|
245
231
|
latchTimerRef.current = setTimeout(() => {
|
|
246
232
|
setShowCanvas(false);
|
|
247
233
|
latchTimerRef.current = null;
|
|
@@ -251,7 +237,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
251
237
|
if (latchTimerRef.current)
|
|
252
238
|
clearTimeout(latchTimerRef.current);
|
|
253
239
|
};
|
|
254
|
-
}, [hasRepositories, showCanvas
|
|
240
|
+
}, [hasRepositories, showCanvas]);
|
|
255
241
|
// Pulse the "+" button when there's a single repo with no features and the
|
|
256
242
|
// create-feature drawer is not open — draws attention to the next action.
|
|
257
243
|
const isCreateDrawerOpen = pathname.startsWith('/create');
|
|
@@ -263,5 +249,5 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
263
249
|
return nodes;
|
|
264
250
|
return nodes.map((n) => n.type === 'repositoryNode' ? { ...n, data: { ...n.data, pulseAdd: true } } : n);
|
|
265
251
|
}, [nodes, isCreateDrawerOpen]);
|
|
266
|
-
return (_jsx(FeaturesCanvas, { nodes: showCanvas ? displayNodes : [], edges: showCanvas ? edges : [], selectedFeatureId: selectedFeatureId, defaultViewport: defaultViewport, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onMoveEnd: handleMoveEnd, onResetViewport: resetViewport, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect:
|
|
252
|
+
return (_jsx(FeaturesCanvas, { nodes: showCanvas ? displayNodes : [], edges: showCanvas ? edges : [], selectedFeatureId: selectedFeatureId, defaultViewport: defaultViewport, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onMoveEnd: handleMoveEnd, onResetViewport: resetViewport, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository }) }));
|
|
267
253
|
}
|
package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"welcome-agent-setup.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/welcome-agent-setup.tsx"],"names":[],"mappings":"AAWA,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"welcome-agent-setup.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/welcome-agent-setup.tsx"],"names":[],"mappings":"AAWA,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AASD,wBAAgB,iBAAiB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,sBAAsB,2CAuNlF"}
|