@shepai/cli 1.167.0 → 1.168.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts +38 -2
- package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts +16 -1
- package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/interactive/index.d.ts +2 -0
- package/dist/packages/core/src/application/use-cases/interactive/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/interactive/index.js +1 -0
- package/dist/packages/core/src/application/use-cases/interactive/respond-to-interaction.use-case.d.ts +17 -0
- package/dist/packages/core/src/application/use-cases/interactive/respond-to-interaction.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/interactive/respond-to-interaction.use-case.js +34 -0
- package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.js +6 -2
- 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/services/agents/common/executors/claude-code-interactive-executor.service.d.ts +3 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.js +59 -6
- package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts +7 -0
- package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.js +101 -1
- package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/respond/route.d.ts +19 -0
- package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/respond/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/respond/route.js +33 -0
- package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.d.ts.map +1 -1
- package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.js +7 -0
- package/dist/src/presentation/web/app/layout.d.ts +0 -1
- package/dist/src/presentation/web/app/layout.d.ts.map +1 -1
- package/dist/src/presentation/web/app/layout.js +0 -1
- package/dist/src/presentation/web/components/assistant-ui/thread.d.ts +3 -2
- package/dist/src/presentation/web/components/assistant-ui/thread.d.ts.map +1 -1
- package/dist/src/presentation/web/components/assistant-ui/thread.js +26 -3
- package/dist/src/presentation/web/components/common/react-file-manager-dialog/react-file-manager-dialog.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/react-file-manager-dialog/react-file-manager-dialog.js +68 -56
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.d.ts +1 -0
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.js +7 -1
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts +1 -0
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.js +3 -0
- package/dist/src/presentation/web/components/features/chat/ChatSheet.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatSheet.js +3 -1
- package/dist/src/presentation/web/components/features/chat/ChatTab.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/ChatTab.js +3 -2
- package/dist/src/presentation/web/components/features/chat/InteractionBubble.d.ts +33 -0
- package/dist/src/presentation/web/components/features/chat/InteractionBubble.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/chat/InteractionBubble.js +155 -0
- package/dist/src/presentation/web/components/features/chat/InteractionBubble.stories.d.ts +22 -0
- package/dist/src/presentation/web/components/features/chat/InteractionBubble.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/chat/InteractionBubble.stories.js +107 -0
- package/dist/src/presentation/web/components/features/chat/useChatRuntime.d.ts +16 -0
- package/dist/src/presentation/web/components/features/chat/useChatRuntime.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/useChatRuntime.js +62 -1
- 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 +18 -3
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +1 -0
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +1 -1
- package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-graph-state.js +16 -0
- package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts +1 -1
- package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-turn-statuses.js +1 -1
- 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 +7 -7
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +2 -2
- package/web/.next/required-server-files.json +2 -2
- package/web/.next/routes-manifest.json +8 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/react-loadable-manifest.json +1 -8
- 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 +1 -1
- 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/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/react-loadable-manifest.json +1 -8
- 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 +1 -1
- 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/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/@drawer/create/page/react-loadable-manifest.json +1 -8
- 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 +1 -1
- 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 +5 -5
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
- 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/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/react-loadable-manifest.json +1 -8
- 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 +1 -1
- 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/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/react-loadable-manifest.json +1 -8
- 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 +1 -1
- 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/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/chat/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
- 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/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/create/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
- package/web/.next/server/app/(dashboard)/create/page.js +1 -1
- 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 +5 -5
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
- 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/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/page.js +1 -1
- 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/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/react-loadable-manifest.json +1 -8
- 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 +1 -1
- 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/build-manifest.json +5 -5
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/react-loadable-manifest.json +1 -8
- 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 +1 -1
- 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 +5 -5
- package/web/.next/server/app/_global-error/page.js +1 -1
- package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/web/.next/server/app/_global-error/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 +7 -7
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/build-manifest.json +5 -5
- package/web/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/_not-found/page.js +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/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
- package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route.js +7 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route.js.map +5 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route.js.nft.json +1 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/settings/page/build-manifest.json +5 -5
- package/web/.next/server/app/settings/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
- package/web/.next/server/app/settings/page.js +1 -1
- 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 +5 -5
- package/web/.next/server/app/skills/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/skills/page.js +1 -1
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/build-manifest.json +5 -5
- package/web/.next/server/app/tools/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/tools/page.js +1 -1
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/build-manifest.json +5 -5
- package/web/.next/server/app/version/page/react-loadable-manifest.json +1 -8
- package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/version/page.js +1 -1
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app-paths-manifest.json +1 -0
- package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_[featureId]_respond_route_actions_990d51bd.js +3 -0
- package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_[featureId]_respond_route_actions_990d51bd.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__31944fa2._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__31944fa2._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__8a281f8d._.js +9 -3
- package/web/.next/server/chunks/[root-of-the-server]__8a281f8d._.js.map +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 +2 -2
- 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]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js.map +1 -1
- 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 +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js.map +1 -1
- 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 +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d5e22d1a._.js +3 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__efeeaed4._.js.map → [root-of-the-server]__d5e22d1a._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f2acfd0e._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f2acfd0e._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f5614810._.js +3 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__d1040bd1._.js.map → [root-of-the-server]__f5614810._.js.map} +1 -1
- 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/_0edaf547._.js +3 -0
- package/web/.next/server/chunks/ssr/_0edaf547._.js.map +1 -0
- 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/_1e08a336._.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/_4cbb7f95._.js +3 -0
- package/web/.next/server/chunks/ssr/_4cbb7f95._.js.map +1 -0
- 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/{_a5913a26._.js → _573d0b23._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_a5913a26._.js.map → _573d0b23._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_506a3bc3._.js → _682fc996._.js} +2 -2
- package/web/.next/server/chunks/ssr/_682fc996._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_b4c3ffcc._.js → _7b3ec8ac._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_b4c3ffcc._.js.map → _7b3ec8ac._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_9a9ec6e6._.js +3 -0
- package/web/.next/server/chunks/ssr/_9a9ec6e6._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_a1068852._.js +3 -0
- package/web/.next/server/chunks/ssr/_a1068852._.js.map +1 -0
- 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/_c3f595c6._.js +1 -1
- package/web/.next/server/chunks/ssr/_c3f595c6._.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/node_modules__pnpm_12a7ede0._.js +3 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_12a7ede0._.js.map +1 -0
- 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/chunks/ssr/src_presentation_web_components_ui_select_tsx_45d6b8ae._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_select_tsx_45d6b8ae._.js.map +1 -1
- package/web/.next/server/middleware-build-manifest.js +5 -5
- 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 +48 -48
- package/web/.next/static/chunks/{fe70e73feb07bcfd.js → 08ec4c9ab61717aa.js} +1 -1
- package/web/.next/static/chunks/{dedf6ca63c5468fa.js → 09edd35d194bec06.js} +3 -3
- package/web/.next/static/chunks/{d6a1facd04a52af5.js → 0d5dda068da311fc.js} +3 -3
- package/web/.next/static/chunks/{7a7d7e71cf9b5a4e.js → 0db171679d1838bf.js} +1 -1
- package/web/.next/static/chunks/11cb8f996a5570ac.js +1 -0
- package/web/.next/static/chunks/{d4d8f0a137bd2eb4.js → 12803afee7d0afc8.js} +2 -2
- package/web/.next/static/chunks/14c1725595d10639.js +1 -0
- package/web/.next/static/chunks/{8866edda931a81c2.js → 1d82462f51924d3f.js} +1 -1
- package/web/.next/static/chunks/1fe75f9dd488d557.css +1 -0
- package/web/.next/static/chunks/2547ef4764d5a053.js +7 -0
- package/web/.next/static/chunks/35f8b762c261aa01.js +1 -0
- package/web/.next/static/chunks/4623ea78122c2d4d.js +1 -0
- package/web/.next/static/chunks/{d7eebb5c0aa9e101.js → 72b7a7374227b47e.js} +2 -2
- package/web/.next/static/chunks/84a181ff3270fd9f.js +1 -0
- package/web/.next/static/chunks/9531dfbcff94c28b.js +1 -0
- package/web/.next/static/chunks/{3f404f608aebc7bb.js → d67238b43d323f1d.js} +1 -1
- package/web/.next/static/chunks/daa74d46f5e8b397.js +3 -0
- package/web/.next/static/chunks/ed3a602003bcb31b.js +1 -0
- package/web/.next/static/chunks/ef1faff4c5100183.js +1 -0
- package/web/.next/static/chunks/{0be57768a211221a.js → f0825a7dc6f4fb83.js} +1 -1
- package/web/.next/static/chunks/fa024fa35b1b47ff.js +1 -0
- package/web/.next/static/chunks/{turbopack-432ef324fc27240c.js → turbopack-8a46f5841d1dbe2e.js} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2d0c3840._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2d0c3840._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d1040bd1._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__efeeaed4._.js +0 -3
- package/web/.next/server/chunks/ssr/_3bcda5d7._.js +0 -3
- package/web/.next/server/chunks/ssr/_3bcda5d7._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_4d49a312._.js +0 -3
- package/web/.next/server/chunks/ssr/_4d49a312._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_506a3bc3._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_5ab8e97d._.js +0 -3
- package/web/.next/server/chunks/ssr/_5ab8e97d._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_9215e9ec._.js +0 -3
- package/web/.next/server/chunks/ssr/_9215e9ec._.js.map +0 -1
- package/web/.next/server/chunks/ssr/node_modules__pnpm_1300ae39._.js +0 -3
- package/web/.next/server/chunks/ssr/node_modules__pnpm_1300ae39._.js.map +0 -1
- package/web/.next/static/chunks/3208dc997aaee4d3.css +0 -1
- package/web/.next/static/chunks/3deefc76ea55047c.js +0 -1
- package/web/.next/static/chunks/40b6bcf1a2de4a0f.js +0 -1
- package/web/.next/static/chunks/420eb8b33d83c4cb.js +0 -1
- package/web/.next/static/chunks/63b0ad1dbc27a5d0.js +0 -1
- package/web/.next/static/chunks/65440524d7ee7d13.js +0 -1
- package/web/.next/static/chunks/6c634b447a6a0db8.js +0 -7
- package/web/.next/static/chunks/6d7b999c99d6d175.js +0 -9
- package/web/.next/static/chunks/6eb32cd5d2795a7c.js +0 -1
- package/web/.next/static/chunks/7f4d1ec4e9f921a3.js +0 -1
- package/web/.next/static/chunks/8180973e9cd6a99e.css +0 -1
- package/web/.next/static/chunks/c7e793951b20a67f.js +0 -1
- package/web/.next/static/chunks/da6d0839a24602eb.js +0 -3
- package/web/.next/static/chunks/db3bf9eb0b519bae.js +0 -1
- /package/web/.next/static/{JjjyVzk5ESdcMWkH6999z → kmMMaSvcntYsYhsTwYqdC}/_buildManifest.js +0 -0
- /package/web/.next/static/{JjjyVzk5ESdcMWkH6999z → kmMMaSvcntYsYhsTwYqdC}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{JjjyVzk5ESdcMWkH6999z → kmMMaSvcntYsYhsTwYqdC}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback } from 'react';
|
|
4
|
+
import { Check, MessageCircleQuestion } from 'lucide-react';
|
|
5
|
+
import { cn } from '../../../lib/utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* Renders an agent's AskUserQuestion interaction inline in the chat thread.
|
|
8
|
+
*
|
|
9
|
+
* - Single question: renders options directly
|
|
10
|
+
* - Multiple questions: tabbed interface with header chips as tabs
|
|
11
|
+
*
|
|
12
|
+
* After submission, the bubble disappears and a green summary message
|
|
13
|
+
* is persisted in the conversation history (rendered by InteractionResponseMessage in thread.tsx).
|
|
14
|
+
*/
|
|
15
|
+
export function InteractionBubble({ interaction, onSubmit, className }) {
|
|
16
|
+
const isMultiQuestion = interaction.questions.length > 1;
|
|
17
|
+
return (_jsxs("div", { className: cn('group flex w-full items-start gap-2.5 px-4 py-0.5', className), children: [_jsx("div", { className: "bg-muted flex h-6 w-6 shrink-0 items-center justify-center rounded-full", children: _jsx(MessageCircleQuestion, { className: "h-3.5 w-3.5 text-violet-600 dark:text-violet-400" }) }), _jsx("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: _jsx("div", { className: "text-foreground mt-px overflow-hidden rounded-2xl rounded-tl-sm border border-violet-200 bg-violet-50/50 text-sm leading-relaxed shadow-sm dark:border-violet-500/20 dark:bg-violet-950/20", children: isMultiQuestion ? (_jsx(TabbedQuestions, { questions: interaction.questions, onSubmit: onSubmit })) : (_jsx("div", { className: "px-4 py-3", children: _jsx(SingleQuestion, { question: interaction.questions[0], onSubmit: onSubmit }) })) }) })] }));
|
|
18
|
+
}
|
|
19
|
+
function TabbedQuestions({ questions, onSubmit, }) {
|
|
20
|
+
const [activeTab, setActiveTab] = useState(0);
|
|
21
|
+
// All per-question state lives here — indexed by question text
|
|
22
|
+
const [selections, setSelections] = useState(() => {
|
|
23
|
+
const init = {};
|
|
24
|
+
for (const q of questions) {
|
|
25
|
+
init[q.question] = { selectedOptions: new Set(), otherText: '', isOtherSelected: false };
|
|
26
|
+
}
|
|
27
|
+
return init;
|
|
28
|
+
});
|
|
29
|
+
const updateSelection = useCallback((questionText, updater) => {
|
|
30
|
+
setSelections((prev) => ({
|
|
31
|
+
...prev,
|
|
32
|
+
[questionText]: updater(prev[questionText]),
|
|
33
|
+
}));
|
|
34
|
+
}, []);
|
|
35
|
+
// Derive answers from selections
|
|
36
|
+
const answers = {};
|
|
37
|
+
for (const q of questions) {
|
|
38
|
+
const s = selections[q.question];
|
|
39
|
+
if (!s)
|
|
40
|
+
continue;
|
|
41
|
+
const parts = [...s.selectedOptions];
|
|
42
|
+
if (s.isOtherSelected && s.otherText.trim())
|
|
43
|
+
parts.push(s.otherText.trim());
|
|
44
|
+
if (parts.length > 0)
|
|
45
|
+
answers[q.question] = parts.join(', ');
|
|
46
|
+
}
|
|
47
|
+
const allAnswered = questions.every((q) => answers[q.question]);
|
|
48
|
+
const handleSubmit = useCallback(() => {
|
|
49
|
+
if (!allAnswered)
|
|
50
|
+
return;
|
|
51
|
+
onSubmit(answers);
|
|
52
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- answers is derived, stable enough
|
|
53
|
+
}, [allAnswered, onSubmit, selections]);
|
|
54
|
+
return (_jsxs("div", { children: [_jsx("div", { className: "flex border-b border-violet-200 dark:border-violet-500/20", children: questions.map((q, i) => {
|
|
55
|
+
const isActive = i === activeTab;
|
|
56
|
+
const hasAnswer = !!answers[q.question];
|
|
57
|
+
return (_jsxs("button", { type: "button", onClick: () => setActiveTab(i), className: cn('relative flex items-center gap-1.5 px-4 py-2 text-xs font-medium transition-colors', isActive
|
|
58
|
+
? 'text-violet-700 dark:text-violet-300'
|
|
59
|
+
: 'text-muted-foreground hover:text-foreground'), children: [hasAnswer ? (_jsx(Check, { className: "h-3 w-3 text-emerald-600 dark:text-emerald-400" })) : (_jsxs("span", { className: "text-muted-foreground/50 text-[10px]", children: [i + 1, "."] })), q.header, isActive ? (_jsx("span", { className: "absolute inset-x-0 -bottom-px h-0.5 rounded-full bg-violet-600 dark:bg-violet-400" })) : null] }, q.question));
|
|
60
|
+
}) }), questions.map((q, i) => (_jsx("div", { className: "px-4 py-3", style: { display: i === activeTab ? undefined : 'none' }, children: _jsx(QuestionPanel, { question: q, selection: selections[q.question], onSelectionChange: (updater) => updateSelection(q.question, updater) }) }, q.question))), _jsxs("div", { className: "flex items-center gap-3 border-t border-violet-200 px-4 py-2.5 dark:border-violet-500/20", children: [_jsxs("button", { type: "button", onClick: handleSubmit, disabled: !allAnswered, className: cn('inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-medium transition-all', allAnswered
|
|
61
|
+
? 'bg-violet-600 text-white shadow-sm hover:bg-violet-700 active:scale-[0.98] dark:bg-violet-600 dark:hover:bg-violet-500'
|
|
62
|
+
: 'bg-muted text-muted-foreground cursor-not-allowed opacity-50'), children: [_jsx(Check, { className: "h-3 w-3" }), "Submit all"] }), _jsxs("span", { className: "text-muted-foreground text-[10px]", children: [Object.keys(answers).length, "/", questions.length, " answered"] })] })] }));
|
|
63
|
+
}
|
|
64
|
+
// ── Question panel (used inside tabs) ───────────────────────────────────
|
|
65
|
+
function QuestionPanel({ question, selection, onSelectionChange, }) {
|
|
66
|
+
const handleOptionToggle = useCallback((label) => {
|
|
67
|
+
onSelectionChange((prev) => {
|
|
68
|
+
const next = new Set(prev.selectedOptions);
|
|
69
|
+
if (question.multiSelect) {
|
|
70
|
+
if (next.has(label))
|
|
71
|
+
next.delete(label);
|
|
72
|
+
else
|
|
73
|
+
next.add(label);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
next.clear();
|
|
77
|
+
next.add(label);
|
|
78
|
+
return { ...prev, selectedOptions: next, isOtherSelected: false };
|
|
79
|
+
}
|
|
80
|
+
return { ...prev, selectedOptions: next };
|
|
81
|
+
});
|
|
82
|
+
}, [question.multiSelect, onSelectionChange]);
|
|
83
|
+
const handleOtherToggle = useCallback(() => {
|
|
84
|
+
onSelectionChange((prev) => {
|
|
85
|
+
if (question.multiSelect) {
|
|
86
|
+
return { ...prev, isOtherSelected: !prev.isOtherSelected };
|
|
87
|
+
}
|
|
88
|
+
return { selectedOptions: new Set(), otherText: prev.otherText, isOtherSelected: true };
|
|
89
|
+
});
|
|
90
|
+
}, [question.multiSelect, onSelectionChange]);
|
|
91
|
+
const handleOtherTextChange = useCallback((text) => {
|
|
92
|
+
onSelectionChange((prev) => ({ ...prev, otherText: text }));
|
|
93
|
+
}, [onSelectionChange]);
|
|
94
|
+
return (_jsxs("div", { children: [_jsxs("p", { className: "text-foreground mb-2 text-xs font-medium", children: [question.question, question.multiSelect ? (_jsx("span", { className: "text-muted-foreground ml-1 font-normal", children: "(select multiple)" })) : null] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [question.options.map((opt) => (_jsx(OptionRow, { option: opt, isSelected: selection.selectedOptions.has(opt.label), isMulti: question.multiSelect, onToggle: () => handleOptionToggle(opt.label) }, opt.label))), _jsx(OtherRow, { isSelected: selection.isOtherSelected, isMulti: question.multiSelect, text: selection.otherText, onToggle: handleOtherToggle, onTextChange: handleOtherTextChange })] })] }));
|
|
95
|
+
}
|
|
96
|
+
// ── Single question (no tabs) ───────────────────────────────────────────
|
|
97
|
+
function SingleQuestion({ question, onSubmit, }) {
|
|
98
|
+
const [selectedOptions, setSelectedOptions] = useState(new Set());
|
|
99
|
+
const [otherText, setOtherText] = useState('');
|
|
100
|
+
const [isOtherSelected, setIsOtherSelected] = useState(false);
|
|
101
|
+
const handleOptionToggle = useCallback((label) => {
|
|
102
|
+
setSelectedOptions((prev) => {
|
|
103
|
+
const next = new Set(prev);
|
|
104
|
+
if (question.multiSelect) {
|
|
105
|
+
if (next.has(label))
|
|
106
|
+
next.delete(label);
|
|
107
|
+
else
|
|
108
|
+
next.add(label);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
next.clear();
|
|
112
|
+
next.add(label);
|
|
113
|
+
setIsOtherSelected(false);
|
|
114
|
+
}
|
|
115
|
+
return next;
|
|
116
|
+
});
|
|
117
|
+
if (!question.multiSelect)
|
|
118
|
+
setIsOtherSelected(false);
|
|
119
|
+
}, [question.multiSelect]);
|
|
120
|
+
const handleOtherToggle = useCallback(() => {
|
|
121
|
+
if (question.multiSelect) {
|
|
122
|
+
setIsOtherSelected((prev) => !prev);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
setSelectedOptions(new Set());
|
|
126
|
+
setIsOtherSelected(true);
|
|
127
|
+
}
|
|
128
|
+
}, [question.multiSelect]);
|
|
129
|
+
const handleSubmit = useCallback(() => {
|
|
130
|
+
const parts = [...selectedOptions];
|
|
131
|
+
if (isOtherSelected && otherText.trim())
|
|
132
|
+
parts.push(otherText.trim());
|
|
133
|
+
if (parts.length === 0)
|
|
134
|
+
return;
|
|
135
|
+
onSubmit({ [question.question]: parts.join(', ') });
|
|
136
|
+
}, [selectedOptions, isOtherSelected, otherText, onSubmit, question.question]);
|
|
137
|
+
const hasSelection = selectedOptions.size > 0 || (isOtherSelected && otherText.trim());
|
|
138
|
+
return (_jsxs("div", { children: [_jsxs("div", { className: "mb-2 flex items-start gap-2", children: [_jsx("span", { className: "inline-flex shrink-0 items-center rounded-full bg-violet-100 px-2 py-0.5 text-[10px] font-semibold tracking-wider text-violet-700 uppercase dark:bg-violet-900/50 dark:text-violet-300", children: question.header }), _jsx("span", { className: "font-medium", children: question.question })] }), _jsxs("div", { className: "ml-0.5 flex flex-col gap-1.5", children: [question.options.map((opt) => (_jsx(OptionRow, { option: opt, isSelected: selectedOptions.has(opt.label), isMulti: question.multiSelect, onToggle: () => handleOptionToggle(opt.label) }, opt.label))), _jsx(OtherRow, { isSelected: isOtherSelected, isMulti: question.multiSelect, text: otherText, onToggle: handleOtherToggle, onTextChange: setOtherText })] }), _jsxs("div", { className: "mt-3 flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: handleSubmit, disabled: !hasSelection, className: cn('inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-medium transition-all', hasSelection
|
|
139
|
+
? 'bg-violet-600 text-white shadow-sm hover:bg-violet-700 active:scale-[0.98] dark:bg-violet-600 dark:hover:bg-violet-500'
|
|
140
|
+
: 'bg-muted text-muted-foreground cursor-not-allowed opacity-50'), children: [_jsx(Check, { className: "h-3 w-3" }), "Submit"] }), question.multiSelect ? (_jsx("span", { className: "text-muted-foreground text-[10px]", children: "Select one or more" })) : null] })] }));
|
|
141
|
+
}
|
|
142
|
+
function OptionRow({ option, isSelected, isMulti, onToggle }) {
|
|
143
|
+
return (_jsxs("button", { type: "button", onClick: onToggle, className: cn('flex items-start gap-2.5 rounded-lg border px-3 py-2 text-left text-xs transition-all', isSelected
|
|
144
|
+
? 'border-violet-300 bg-violet-100/60 shadow-sm dark:border-violet-500/40 dark:bg-violet-900/30'
|
|
145
|
+
: 'border-border/50 hover:border-violet-300 hover:bg-violet-50 dark:hover:border-violet-500/30 dark:hover:bg-violet-900/10'), children: [_jsx("span", { className: cn('mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center border transition-colors', isMulti ? 'rounded' : 'rounded-full', isSelected
|
|
146
|
+
? 'border-violet-600 bg-violet-600 dark:border-violet-500 dark:bg-violet-500'
|
|
147
|
+
: 'border-muted-foreground/30'), children: isSelected ? _jsx(Check, { className: "h-2.5 w-2.5 text-white", strokeWidth: 3 }) : null }), _jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsx("span", { className: cn('font-medium', isSelected && 'text-violet-700 dark:text-violet-300'), children: option.label }), _jsx("span", { className: "text-muted-foreground text-[11px] leading-snug", children: option.description })] })] }));
|
|
148
|
+
}
|
|
149
|
+
function OtherRow({ isSelected, isMulti, text, onToggle, onTextChange }) {
|
|
150
|
+
return (_jsxs("div", { className: cn('flex items-start gap-2.5 rounded-lg border px-3 py-2 text-xs transition-all', isSelected
|
|
151
|
+
? 'border-violet-300 bg-violet-100/60 shadow-sm dark:border-violet-500/40 dark:bg-violet-900/30'
|
|
152
|
+
: 'border-border/50 hover:border-violet-300 dark:hover:border-violet-500/30'), children: [_jsx("button", { type: "button", onClick: onToggle, className: "mt-0.5 shrink-0", children: _jsx("span", { className: cn('flex h-4 w-4 items-center justify-center border transition-colors', isMulti ? 'rounded' : 'rounded-full', isSelected
|
|
153
|
+
? 'border-violet-600 bg-violet-600 dark:border-violet-500 dark:bg-violet-500'
|
|
154
|
+
: 'border-muted-foreground/30'), children: isSelected ? _jsx(Check, { className: "h-2.5 w-2.5 text-white", strokeWidth: 3 }) : null }) }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [_jsx("span", { className: cn('font-medium', isSelected && 'text-violet-700 dark:text-violet-300'), children: "Other" }), isSelected ? (_jsx("input", { type: "text", value: text, onChange: (e) => onTextChange(e.target.value), placeholder: "Type your answer...", className: "w-full rounded-md border border-violet-200 bg-white/80 px-2 py-1 text-xs outline-none focus:border-violet-400 focus:ring-1 focus:ring-violet-300/30 dark:border-violet-500/30 dark:bg-violet-950/30 dark:focus:border-violet-500/50 dark:focus:ring-violet-500/20", autoFocus: true })) : null] })] }));
|
|
155
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react';
|
|
2
|
+
import { InteractionBubble } from './InteractionBubble.js';
|
|
3
|
+
import type { InteractionData } from './InteractionBubble.js';
|
|
4
|
+
declare const meta: {
|
|
5
|
+
title: string;
|
|
6
|
+
component: typeof InteractionBubble;
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: string;
|
|
9
|
+
};
|
|
10
|
+
decorators: ((Story: import("@storybook/core/csf").PartialStoryFn<import("@storybook/react").ReactRenderer, {
|
|
11
|
+
interaction: InteractionData;
|
|
12
|
+
onSubmit: (answers: Record<string, string>) => void;
|
|
13
|
+
className?: string | undefined;
|
|
14
|
+
}>) => import("react/jsx-runtime").JSX.Element)[];
|
|
15
|
+
};
|
|
16
|
+
export default meta;
|
|
17
|
+
type Story = StoryObj<typeof meta>;
|
|
18
|
+
export declare const SingleSelect: Story;
|
|
19
|
+
export declare const MultiSelect: Story;
|
|
20
|
+
export declare const TabbedMultiQuestion: Story;
|
|
21
|
+
export declare const Submitted: Story;
|
|
22
|
+
//# sourceMappingURL=InteractionBubble.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InteractionBubble.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/InteractionBubble.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,QAAA,MAAM,IAAI;;;;;;;;;;;CAWgC,CAAC;AAE3C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAsFnC,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAGzB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAGjC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAGvB,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { InteractionBubble } from './InteractionBubble.js';
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Features/Chat/InteractionBubble',
|
|
6
|
+
component: InteractionBubble,
|
|
7
|
+
parameters: { layout: 'padded' },
|
|
8
|
+
decorators: [
|
|
9
|
+
(Story) => (_jsx("div", { className: "bg-background mx-auto max-w-xl rounded-lg border p-4", children: _jsx(Story, {}) })),
|
|
10
|
+
],
|
|
11
|
+
};
|
|
12
|
+
export default meta;
|
|
13
|
+
const colorInteraction = {
|
|
14
|
+
toolCallId: 'toolu_color_1',
|
|
15
|
+
questions: [
|
|
16
|
+
{
|
|
17
|
+
question: 'What is your favorite color?',
|
|
18
|
+
header: 'Color',
|
|
19
|
+
multiSelect: false,
|
|
20
|
+
options: [
|
|
21
|
+
{ label: 'Red', description: 'The color red' },
|
|
22
|
+
{ label: 'Blue', description: 'The color blue' },
|
|
23
|
+
{ label: 'Green', description: 'The color green' },
|
|
24
|
+
{ label: 'Yellow', description: 'The color yellow' },
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
const multiSelectInteraction = {
|
|
30
|
+
toolCallId: 'toolu_features_1',
|
|
31
|
+
questions: [
|
|
32
|
+
{
|
|
33
|
+
question: 'Which features do you want to enable?',
|
|
34
|
+
header: 'Features',
|
|
35
|
+
multiSelect: true,
|
|
36
|
+
options: [
|
|
37
|
+
{ label: 'Dark mode', description: 'Enable dark theme support' },
|
|
38
|
+
{ label: 'Notifications', description: 'Push notifications for updates' },
|
|
39
|
+
{ label: 'Analytics', description: 'Usage analytics and reporting' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
const multiQuestionInteraction = {
|
|
45
|
+
toolCallId: 'toolu_setup_1',
|
|
46
|
+
questions: [
|
|
47
|
+
{
|
|
48
|
+
question: "What's your preferred coding environment?",
|
|
49
|
+
header: 'IDE',
|
|
50
|
+
multiSelect: false,
|
|
51
|
+
options: [
|
|
52
|
+
{
|
|
53
|
+
label: 'VS Code',
|
|
54
|
+
description: "Microsoft's popular editor with rich extension ecosystem.",
|
|
55
|
+
},
|
|
56
|
+
{ label: 'Neovim', description: 'Terminal-based, highly customizable.' },
|
|
57
|
+
{ label: 'JetBrains', description: 'Full-featured IDEs with deep language intelligence.' },
|
|
58
|
+
{ label: 'Cursor', description: 'AI-first fork of VS Code.' },
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
question: 'Which of these technologies do you actively use? (pick all that apply)',
|
|
63
|
+
header: 'Tech Stack',
|
|
64
|
+
multiSelect: true,
|
|
65
|
+
options: [
|
|
66
|
+
{ label: 'TypeScript', description: 'Statically typed JavaScript.' },
|
|
67
|
+
{ label: 'Python', description: 'Scripting, data science, ML, or backend.' },
|
|
68
|
+
{ label: 'Go', description: 'Fast, compiled, cloud-native tooling.' },
|
|
69
|
+
{ label: 'Rust', description: 'Systems programming with memory safety.' },
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
question: 'How would you describe your experience level?',
|
|
74
|
+
header: 'Level',
|
|
75
|
+
multiSelect: false,
|
|
76
|
+
options: [
|
|
77
|
+
{ label: 'Junior', description: 'Less than 2 years of experience.' },
|
|
78
|
+
{ label: 'Mid-level', description: '2-5 years of experience.' },
|
|
79
|
+
{ label: 'Senior', description: '5+ years of experience.' },
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
// ── Interactive wrapper ─────────────────────────────────────────────────
|
|
85
|
+
function InteractiveBubble({ interaction }) {
|
|
86
|
+
const [submitted, setSubmitted] = useState(false);
|
|
87
|
+
if (submitted)
|
|
88
|
+
return _jsx("p", { className: "text-muted-foreground px-4 text-xs", children: "Submitted!" });
|
|
89
|
+
return _jsx(InteractionBubble, { interaction: interaction, onSubmit: () => setSubmitted(true) });
|
|
90
|
+
}
|
|
91
|
+
const noop = () => undefined;
|
|
92
|
+
export const SingleSelect = {
|
|
93
|
+
args: { interaction: colorInteraction, onSubmit: noop },
|
|
94
|
+
render: () => _jsx(InteractiveBubble, { interaction: colorInteraction }),
|
|
95
|
+
};
|
|
96
|
+
export const MultiSelect = {
|
|
97
|
+
args: { interaction: multiSelectInteraction, onSubmit: noop },
|
|
98
|
+
render: () => _jsx(InteractiveBubble, { interaction: multiSelectInteraction }),
|
|
99
|
+
};
|
|
100
|
+
export const TabbedMultiQuestion = {
|
|
101
|
+
args: { interaction: multiQuestionInteraction, onSubmit: noop },
|
|
102
|
+
render: () => _jsx(InteractiveBubble, { interaction: multiQuestionInteraction }),
|
|
103
|
+
};
|
|
104
|
+
export const Submitted = {
|
|
105
|
+
args: { interaction: colorInteraction, onSubmit: noop },
|
|
106
|
+
render: () => _jsx(InteractiveBubble, { interaction: colorInteraction }),
|
|
107
|
+
};
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/** Shape matching UserInteractionData from the agent executor interface. */
|
|
2
|
+
export interface InteractionData {
|
|
3
|
+
toolCallId: string;
|
|
4
|
+
questions: {
|
|
5
|
+
question: string;
|
|
6
|
+
header: string;
|
|
7
|
+
options: {
|
|
8
|
+
label: string;
|
|
9
|
+
description: string;
|
|
10
|
+
preview?: string;
|
|
11
|
+
}[];
|
|
12
|
+
multiSelect: boolean;
|
|
13
|
+
}[];
|
|
14
|
+
}
|
|
1
15
|
interface SessionInfo {
|
|
2
16
|
pid: number | null;
|
|
3
17
|
sessionId: string | null;
|
|
@@ -45,6 +59,8 @@ export declare function useChatRuntime(featureId: string, worktreePath?: string,
|
|
|
45
59
|
stopAgent: () => Promise<void>;
|
|
46
60
|
sessionInfo: SessionInfo | null;
|
|
47
61
|
isChatLoading: boolean;
|
|
62
|
+
pendingInteraction: InteractionData | null;
|
|
63
|
+
respondToInteraction: (answers: Record<string, string>) => Promise<void>;
|
|
48
64
|
};
|
|
49
65
|
export {};
|
|
50
66
|
//# sourceMappingURL=useChatRuntime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatRuntime.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/useChatRuntime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useChatRuntime.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/useChatRuntime.ts"],"names":[],"mappings":"AASA,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACpE,WAAW,EAAE,OAAO,CAAC;KACtB,EAAE,CAAC;CACL;AAYD,UAAU,WAAW;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAkDD,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,SAAS,EAAE,OAAO,CAAC;IACnB,qFAAqF;IACrF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAID,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,iEAAiE;AACjE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,kBAAkB;;;;;;;;oCAgXV,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;EAmDzC"}
|
|
@@ -100,6 +100,19 @@ export function useChatRuntime(featureId, worktreePath, options) {
|
|
|
100
100
|
const [awaitingResponse, setAwaitingResponse] = useState(false);
|
|
101
101
|
const awaitingTimerRef = useRef(null);
|
|
102
102
|
const eventSourceRef = useRef(null);
|
|
103
|
+
// ── Interaction state (AskUserQuestion) ─────────────────────────────
|
|
104
|
+
const [pendingInteraction, setPendingInteraction] = useState(null);
|
|
105
|
+
// Sync pending interaction from backend polling (fallback for missed SSE)
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
const backendInteraction = chatState?.pendingInteraction ?? null;
|
|
108
|
+
if (backendInteraction) {
|
|
109
|
+
setPendingInteraction(backendInteraction);
|
|
110
|
+
}
|
|
111
|
+
else if (!backendInteraction && pendingInteraction) {
|
|
112
|
+
// Backend cleared it (e.g. agent continued) — clear local state
|
|
113
|
+
setPendingInteraction(null);
|
|
114
|
+
}
|
|
115
|
+
}, [chatState?.pendingInteraction, pendingInteraction]);
|
|
103
116
|
// Delayed awaiting — only show Thinking bubble after 600ms to avoid flash
|
|
104
117
|
const startAwaiting = useCallback(() => {
|
|
105
118
|
if (awaitingTimerRef.current)
|
|
@@ -163,10 +176,24 @@ export function useChatRuntime(featureId, worktreePath, options) {
|
|
|
163
176
|
// Ignore
|
|
164
177
|
}
|
|
165
178
|
});
|
|
179
|
+
es.addEventListener('interaction', (event) => {
|
|
180
|
+
try {
|
|
181
|
+
const data = JSON.parse(event.data);
|
|
182
|
+
if (data.interaction) {
|
|
183
|
+
cancelAwaiting();
|
|
184
|
+
setPendingInteraction(data.interaction);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Ignore
|
|
189
|
+
}
|
|
190
|
+
});
|
|
166
191
|
es.addEventListener('done', () => {
|
|
167
192
|
setStatusLog(null);
|
|
168
193
|
cancelAwaiting();
|
|
169
194
|
pushDebug('turn_done');
|
|
195
|
+
// Agent turn completed — clear any lingering interaction state
|
|
196
|
+
setPendingInteraction(null);
|
|
170
197
|
// Refetch first, THEN clear local streaming state so there's no gap
|
|
171
198
|
void queryClient.invalidateQueries({ queryKey: chatQueryKey(featureId) }).then(() => {
|
|
172
199
|
setStreamingText('');
|
|
@@ -335,6 +362,7 @@ export function useChatRuntime(featureId, worktreePath, options) {
|
|
|
335
362
|
setDebugEvents([]);
|
|
336
363
|
setStatusLog(null);
|
|
337
364
|
cancelAwaiting();
|
|
365
|
+
setPendingInteraction(null);
|
|
338
366
|
void queryClient.invalidateQueries({ queryKey: chatQueryKey(featureId) });
|
|
339
367
|
}, [featureId, queryClient, cancelAwaiting]);
|
|
340
368
|
// ── Stop agent ────────────────────────────────────────────────────────
|
|
@@ -347,6 +375,30 @@ export function useChatRuntime(featureId, worktreePath, options) {
|
|
|
347
375
|
cancelAwaiting();
|
|
348
376
|
void queryClient.invalidateQueries({ queryKey: chatQueryKey(featureId) });
|
|
349
377
|
}, [featureId, queryClient, cancelAwaiting]);
|
|
378
|
+
// ── Respond to interaction (AskUserQuestion) ───────────────────────────
|
|
379
|
+
const respondToInteraction = useCallback(async (answers) => {
|
|
380
|
+
// Clear the bubble and status log immediately — answers are persisted as
|
|
381
|
+
// a user message by the backend, shown in conversation history on refetch.
|
|
382
|
+
setPendingInteraction(null);
|
|
383
|
+
setStatusLog(null);
|
|
384
|
+
try {
|
|
385
|
+
const res = await fetch(`/api/interactive/chat/${featureId}/respond`, {
|
|
386
|
+
method: 'POST',
|
|
387
|
+
headers: { 'Content-Type': 'application/json' },
|
|
388
|
+
body: JSON.stringify({ answers }),
|
|
389
|
+
});
|
|
390
|
+
if (!res.ok) {
|
|
391
|
+
// eslint-disable-next-line no-console
|
|
392
|
+
console.error(`[respondToInteraction] failed: ${res.status}`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
catch (err) {
|
|
396
|
+
// eslint-disable-next-line no-console
|
|
397
|
+
console.error('[respondToInteraction] error:', err);
|
|
398
|
+
}
|
|
399
|
+
// Refetch to show the persisted user message with answers
|
|
400
|
+
void queryClient.invalidateQueries({ queryKey: chatQueryKey(featureId) });
|
|
401
|
+
}, [featureId, queryClient]);
|
|
350
402
|
// ── Build assistant-ui runtime ──────────────────────────────────────────
|
|
351
403
|
const runtime = useExternalStoreRuntime({
|
|
352
404
|
messages: threadMessages,
|
|
@@ -359,5 +411,14 @@ export function useChatRuntime(featureId, worktreePath, options) {
|
|
|
359
411
|
cancelAwaiting();
|
|
360
412
|
}, [cancelAwaiting]),
|
|
361
413
|
});
|
|
362
|
-
return {
|
|
414
|
+
return {
|
|
415
|
+
runtime,
|
|
416
|
+
status,
|
|
417
|
+
clearChat,
|
|
418
|
+
stopAgent,
|
|
419
|
+
sessionInfo,
|
|
420
|
+
isChatLoading,
|
|
421
|
+
pendingInteraction,
|
|
422
|
+
respondToInteraction,
|
|
423
|
+
};
|
|
363
424
|
}
|
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":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAgC5E,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":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAgC5E,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,2CAiezF"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.js
CHANGED
|
@@ -143,13 +143,28 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
143
143
|
}, AUTO_FOCUS_DRAWER_DELAY_MS);
|
|
144
144
|
}, 0);
|
|
145
145
|
}, [fitView, guardedNavigate, router]);
|
|
146
|
-
//
|
|
146
|
+
// Smoothly pan/zoom to a specific node after it appears on canvas
|
|
147
|
+
const focusOnNode = useCallback((nodeId) => {
|
|
148
|
+
// Wait for next render so the node exists in the DOM
|
|
149
|
+
setTimeout(() => {
|
|
150
|
+
fitView({
|
|
151
|
+
nodes: [{ id: nodeId }],
|
|
152
|
+
maxZoom: 1.0,
|
|
153
|
+
padding: 0.4,
|
|
154
|
+
duration: 600,
|
|
155
|
+
});
|
|
156
|
+
}, 0);
|
|
157
|
+
}, [fitView]);
|
|
158
|
+
// Wrapper: add repo + auto-focus on the new node
|
|
147
159
|
const addRepoAndFocus = useCallback((path) => {
|
|
148
|
-
const { wasEmpty, repoPath } = handleAddRepository(path);
|
|
160
|
+
const { wasEmpty, repoPath, tempNodeId } = handleAddRepository(path);
|
|
149
161
|
if (wasEmpty) {
|
|
150
162
|
focusAndOpenDrawer(repoPath);
|
|
151
163
|
}
|
|
152
|
-
|
|
164
|
+
else {
|
|
165
|
+
focusOnNode(tempNodeId);
|
|
166
|
+
}
|
|
167
|
+
}, [handleAddRepository, focusAndOpenDrawer, focusOnNode]);
|
|
153
168
|
// Listen for global "add repository" events from the top bar button
|
|
154
169
|
useEffect(() => {
|
|
155
170
|
const handler = (e) => {
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface ControlCenterState {
|
|
|
12
12
|
handleAddRepository: (path: string) => {
|
|
13
13
|
wasEmpty: boolean;
|
|
14
14
|
repoPath: string;
|
|
15
|
+
tempNodeId: string;
|
|
15
16
|
};
|
|
16
17
|
handleLayout: (direction: LayoutDirection) => void;
|
|
17
18
|
handleArchiveFeature: (featureId: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAkBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;
|
|
1
|
+
{"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAkBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QACrC,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;IACZ,yDAAyD;IACzD,YAAY,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,wDAAwD;IACxD,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAQD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CAilBpB"}
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js
CHANGED
|
@@ -486,7 +486,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
|
|
|
486
486
|
toast.error('Failed to add repository');
|
|
487
487
|
})
|
|
488
488
|
.finally(() => endMutation());
|
|
489
|
-
return { wasEmpty, repoPath: path };
|
|
489
|
+
return { wasEmpty, repoPath: path, tempNodeId: tempId };
|
|
490
490
|
}, [
|
|
491
491
|
addRepositoryToMap,
|
|
492
492
|
removeRepository,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-graph-state.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-graph-state.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,mDAAmD;IACnD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;;OAIG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAClE,uEAAuE;IACvE,aAAa,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC5E,kEAAkE;IAClE,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1F,yDAAyD;IACzD,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sDAAsD;IACtD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uDAAuD;IACvD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9D,2DAA2D;IAC3D,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAClE,gCAAgC;IAChC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACtF,gEAAgE;IAChE,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,+EAA+E;IAC/E,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD;;;;OAIG;IACH,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B;;;OAGG;IACH,WAAW,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,0EAA0E;IAC1E,UAAU,EAAE,MAAM,OAAO,CAAC;CAC3B;AAuCD,KAAK,kBAAkB,GAAG,OAAO,CAC/B,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC,CACtE,CAAC;AA8BF,wBAAgB,aAAa,CAC3B,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,EACpB,YAAY,UAAQ,GACnB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"use-graph-state.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-graph-state.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,mDAAmD;IACnD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;;OAIG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAClE,uEAAuE;IACvE,aAAa,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC5E,kEAAkE;IAClE,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1F,yDAAyD;IACzD,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sDAAsD;IACtD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uDAAuD;IACvD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9D,2DAA2D;IAC3D,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAClE,gCAAgC;IAChC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACtF,gEAAgE;IAChE,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,yDAAyD;IACzD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,+EAA+E;IAC/E,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD;;;;OAIG;IACH,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B;;;OAGG;IACH,WAAW,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,0EAA0E;IAC1E,UAAU,EAAE,MAAM,OAAO,CAAC;CAC3B;AAuCD,KAAK,kBAAkB,GAAG,OAAO,CAC/B,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAC,CACtE,CAAC;AA8BF,wBAAgB,aAAa,CAC3B,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,EACpB,YAAY,UAAQ,GACnB,mBAAmB,CAicrB"}
|
|
@@ -82,6 +82,9 @@ export function useGraphState(initialNodes, initialEdges, showArchived = false)
|
|
|
82
82
|
// Retained for one extra reconcile cycle so the user sees the deleting state
|
|
83
83
|
// before the node disappears from the canvas.
|
|
84
84
|
const deletingRetainedRef = useRef(new Set());
|
|
85
|
+
// Track deleted repo IDs so reconcile doesn't resurrect them from stale server data.
|
|
86
|
+
// Cleared once reconcile sees the repo is gone from server data.
|
|
87
|
+
const deletedRepoIdsRef = useRef(new Set());
|
|
85
88
|
// Callbacks stored in a ref so changing them doesn't trigger re-render.
|
|
86
89
|
// The stable wrapper object reads from the ref so node closures always use latest callbacks.
|
|
87
90
|
const callbacksRef = useRef({});
|
|
@@ -254,6 +257,17 @@ export function useGraphState(initialNodes, initialEdges, showArchived = false)
|
|
|
254
257
|
setRepoMap((currentRepoMap) => {
|
|
255
258
|
// Start with everything the server returned
|
|
256
259
|
const merged = new Map(newRepoMap);
|
|
260
|
+
// Remove repos that were deleted client-side but the server still returns
|
|
261
|
+
// (stale data). Once the server stops returning the repo, clear the tombstone.
|
|
262
|
+
for (const deletedId of deletedRepoIdsRef.current) {
|
|
263
|
+
if (merged.has(deletedId)) {
|
|
264
|
+
merged.delete(deletedId);
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
// Server confirmed deletion — no longer need the tombstone
|
|
268
|
+
deletedRepoIdsRef.current.delete(deletedId);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
257
271
|
// Build a set of repositoryPaths present in server data for dedup
|
|
258
272
|
const serverPaths = new Set([...newRepoMap.values()].map((e) => e.data.repositoryPath));
|
|
259
273
|
for (const [id, entry] of currentRepoMap) {
|
|
@@ -343,6 +357,7 @@ export function useGraphState(initialNodes, initialEdges, showArchived = false)
|
|
|
343
357
|
}, []);
|
|
344
358
|
const addRepository = useCallback((nodeId, data) => {
|
|
345
359
|
protectedRepoIdsRef.current.add(nodeId);
|
|
360
|
+
deletedRepoIdsRef.current.delete(nodeId);
|
|
346
361
|
setRepoMap((prev) => {
|
|
347
362
|
const next = new Map(prev);
|
|
348
363
|
next.set(nodeId, { nodeId, data });
|
|
@@ -351,6 +366,7 @@ export function useGraphState(initialNodes, initialEdges, showArchived = false)
|
|
|
351
366
|
}, []);
|
|
352
367
|
const removeRepository = useCallback((nodeId) => {
|
|
353
368
|
protectedRepoIdsRef.current.delete(nodeId);
|
|
369
|
+
deletedRepoIdsRef.current.add(nodeId);
|
|
354
370
|
setRepoMap((prev) => {
|
|
355
371
|
if (!prev.has(nodeId))
|
|
356
372
|
return prev;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-turn-statuses.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-turn-statuses.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,YAAY,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"use-turn-statuses.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-turn-statuses.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,YAAY,GAAG,QAAQ,GAAG,gBAAgB,CAAC;AAE7E;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAY/D;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE"}
|