@shepai/cli 1.151.2-pr460.ba381d8 → 1.151.2-pr460.d6300bd
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/interactive-session-repository.interface.d.ts +19 -0
- package/dist/packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts +13 -0
- package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/interactive-session.mapper.d.ts +2 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/interactive-session.mapper.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/interactive-session.mapper.js +2 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/047-add-agent-session-id.d.ts +15 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/047-add-agent-session-id.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/047-add-agent-session-id.js +27 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/048-add-turn-status.d.ts +15 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/048-add-turn-status.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/048-add-turn-status.js +20 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts +4 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.js +37 -0
- package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts +4 -2
- 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 +89 -32
- package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.d.ts +19 -0
- package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.js +24 -0
- package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.d.ts +13 -0
- package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.js +36 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.js +5 -2
- package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-node.js +7 -2
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.d.ts +14 -0
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.js +13 -0
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts +9 -0
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.js +19 -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 +4 -1
- package/dist/src/presentation/web/components/features/chat/useChatRuntime.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/chat/useChatRuntime.js +6 -0
- 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 +9 -2
- package/dist/src/presentation/web/hooks/turn-statuses-provider.d.ts +19 -0
- package/dist/src/presentation/web/hooks/turn-statuses-provider.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/turn-statuses-provider.js +26 -0
- package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts +13 -0
- package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/use-turn-statuses.js +31 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +2 -0
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/routes-manifest.json +14 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +29 -29
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +29 -29
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +5 -5
- 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/attachments/upload-from-path/route.js +1 -1
- package/web/.next/server/app/api/attachments/upload-from-path/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]/mark-read/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route.js +7 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route.js.map +5 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route.js.nft.json +1 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
- package/web/.next/server/app/api/interactive/chat/turn-statuses/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/interactive/chat/turn-statuses/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/interactive/chat/turn-statuses/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/interactive/chat/turn-statuses/route.js +7 -0
- package/web/.next/server/app/api/interactive/chat/turn-statuses/route.js.map +5 -0
- package/web/.next/server/app/api/interactive/chat/turn-statuses/route.js.nft.json +1 -0
- package/web/.next/server/app/api/interactive/chat/turn-statuses/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/api/sessions-batch/route.js +1 -1
- package/web/.next/server/app/api/sessions-batch/route.js.nft.json +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +10 -10
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +10 -10
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +5 -5
- 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 +2 -0
- package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_[featureId]_mark-read_route_actions_ce79c730.js +3 -0
- package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_[featureId]_mark-read_route_actions_ce79c730.js.map +1 -0
- package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_turn-statuses_route_actions_f97e4de7.js +3 -0
- package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_turn-statuses_route_actions_f97e4de7.js.map +1 -0
- package/web/.next/server/chunks/{[root-of-the-server]__0d33c29e._.js → [root-of-the-server]__31598852._.js} +2 -2
- package/web/.next/server/chunks/{[root-of-the-server]__0d33c29e._.js.map → [root-of-the-server]__31598852._.js.map} +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__32b04219._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__32b04219._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__ab4951b1._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__ab4951b1._.js.map +1 -0
- package/web/.next/server/chunks/{[root-of-the-server]__a5879003._.js → [root-of-the-server]__ea653642._.js} +2 -2
- package/web/.next/server/chunks/{[root-of-the-server]__a5879003._.js.map → [root-of-the-server]__ea653642._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/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]__17ed7ed1._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__17ed7ed1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__28d0d265._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__42bf1807._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__42bf1807._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__563f2f7a._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__563f2f7a._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__88f7e8e6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__88f7e8e6._.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]__c30f1f82._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c30f1f82._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__31f1c3b0._.js → [root-of-the-server]__e91ffd5e._.js} +3 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e91ffd5e._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f80bfc75._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f80bfc75._.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/_16eb4fec._.js +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_3a0b989f._.js +2 -2
- package/web/.next/server/chunks/ssr/_3a0b989f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
- package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_5f69c13f._.js +1 -1
- package/web/.next/server/chunks/ssr/_5f69c13f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_6f48569b._.js +3 -0
- package/web/.next/server/chunks/ssr/{_de71404e._.js.map → _6f48569b._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_7c5b97c6._.js +1 -1
- package/web/.next/server/chunks/ssr/_7c5b97c6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_82c57f10._.js +1 -1
- package/web/.next/server/chunks/ssr/_82c57f10._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_9495d50b._.js +1 -1
- package/web/.next/server/chunks/ssr/_9495d50b._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_4c42590e._.js → _9ab5e836._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_4c42590e._.js.map → _9ab5e836._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_eb9467e9._.js → _9ecb7d6d._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_eb9467e9._.js.map → _9ecb7d6d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_a0e3f7e4._.js +1 -1
- package/web/.next/server/chunks/ssr/_a0e3f7e4._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_ac4a3873._.js +1 -1
- package/web/.next/server/chunks/ssr/_ca0aa7f0._.js +1 -1
- package/web/.next/server/chunks/ssr/_ca0aa7f0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_cb5a021e._.js +1 -1
- package/web/.next/server/chunks/ssr/_cb5a021e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_d86175ae._.js +1 -1
- package/web/.next/server/chunks/ssr/_d86175ae._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_d8bedf13._.js +1 -1
- package/web/.next/server/chunks/ssr/_d8bedf13._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_48e5757d._.js → _e9a73a63._.js} +2 -2
- package/web/.next/server/chunks/ssr/_e9a73a63._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_fa7efce3._.js +2 -2
- package/web/.next/server/chunks/ssr/_fa7efce3._.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/node_modules__pnpm_ef15a0bd._.js +3 -0
- package/web/.next/server/chunks/ssr/node_modules__pnpm_ef15a0bd._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_cdc632e3.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_cdc632e3.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_39ca0924.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_39ca0924.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_357e3eb0._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_357e3eb0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +45 -45
- package/web/.next/static/chunks/{e51493c981deb9fd.js → 00ddf2682e26248f.js} +1 -1
- package/web/.next/static/chunks/{6a5c79587318fe1e.js → 0d07a524b56a91ae.js} +1 -1
- package/web/.next/static/chunks/{73b5be3394d27358.js → 3011d2b0e84898b9.js} +2 -2
- package/web/.next/static/chunks/{c80523e4d172cdea.js → 3d780d0c67e9c6d7.js} +2 -2
- package/web/.next/static/chunks/{9dd319c237b73197.js → 3f314c0cfed1a31f.js} +1 -1
- package/web/.next/static/chunks/{b546fac6810f555b.js → 4dcd3fddd166e847.js} +1 -1
- package/web/.next/static/chunks/{ce18a48f7d5d53c0.js → 6b96db4c6afb337c.js} +1 -1
- package/web/.next/static/chunks/8ba1c07ef18b15a9.js +1 -0
- package/web/.next/static/chunks/91ca5103e9d37ecf.js +7 -0
- package/web/.next/static/chunks/a919a9df4ab12a5c.css +1 -0
- package/web/.next/static/chunks/afc4212532319046.js +1 -0
- package/web/.next/static/chunks/{feed0046c419c228.js → b4cde06eff374c59.js} +3 -3
- package/web/.next/static/chunks/{ec7cd7e136a1b320.js → c9d93e106e541ea5.js} +1 -1
- package/web/.next/static/chunks/{0e73b25a355804a2.js → d1beeb17dc36ae56.js} +2 -2
- package/web/.next/static/chunks/{487a3d47f76ba2ce.js → dd72af4aa0e5a751.js} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__31f1c3b0._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ede6df1f._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ede6df1f._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_48e5757d._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_de71404e._.js +0 -3
- package/web/.next/static/chunks/16f6471485cbfed1.css +0 -1
- package/web/.next/static/chunks/476ebad4abb27ee8.js +0 -7
- package/web/.next/static/chunks/f0b1a5ded6ab6885.js +0 -1
- /package/web/.next/static/{VIJH9LQh8Ro1-nip3v-Am → Pz2jBHo89UcoWoV7z5vJp}/_buildManifest.js +0 -0
- /package/web/.next/static/{VIJH9LQh8Ro1-nip3v-Am → Pz2jBHo89UcoWoV7z5vJp}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{VIJH9LQh8Ro1-nip3v-Am → Pz2jBHo89UcoWoV7z5vJp}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bulk turn-status API.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/interactive/chat/turn-statuses?featureIds=id1,id2,...
|
|
5
|
+
*
|
|
6
|
+
* Returns a map of featureId → turnStatus ('idle' | 'processing' | 'unread')
|
|
7
|
+
* for all requested features. Used by UI dot indicators on chat buttons.
|
|
8
|
+
*/
|
|
9
|
+
import { NextResponse } from 'next/server';
|
|
10
|
+
import { resolve } from '../../../../../lib/server-container.js';
|
|
11
|
+
export const dynamic = 'force-dynamic';
|
|
12
|
+
export async function GET(request) {
|
|
13
|
+
try {
|
|
14
|
+
const featureIdsParam = request.nextUrl.searchParams.get('featureIds');
|
|
15
|
+
if (!featureIdsParam) {
|
|
16
|
+
return NextResponse.json({});
|
|
17
|
+
}
|
|
18
|
+
const featureIds = featureIdsParam.split(',').filter(Boolean);
|
|
19
|
+
if (featureIds.length === 0) {
|
|
20
|
+
return NextResponse.json({});
|
|
21
|
+
}
|
|
22
|
+
const service = resolve('IInteractiveSessionService');
|
|
23
|
+
const statuses = await service.getTurnStatuses(featureIds);
|
|
24
|
+
// Convert Map to plain object for JSON serialization
|
|
25
|
+
const result = {};
|
|
26
|
+
for (const [id, status] of statuses) {
|
|
27
|
+
result[id] = status;
|
|
28
|
+
}
|
|
29
|
+
return NextResponse.json(result);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
// eslint-disable-next-line no-console
|
|
33
|
+
console.error('[GET /api/interactive/chat/turn-statuses]', error);
|
|
34
|
+
return NextResponse.json({ error: error instanceof Error ? error.message : 'Internal server error' }, { status: 500 });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA4CnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAymBA"}
|
|
@@ -8,6 +8,8 @@ import { cn } from '../../../lib/utils.js';
|
|
|
8
8
|
import { ActionButton } from '../../common/action-button/action-button.js';
|
|
9
9
|
import { Button } from '../../ui/button.js';
|
|
10
10
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
|
|
11
|
+
import { ChatDotIndicator } from '../../features/chat/ChatDotIndicator.js';
|
|
12
|
+
import { useTurnStatus } from '../../../hooks/turn-statuses-provider.js';
|
|
11
13
|
import { useDeployAction } from '../../../hooks/use-deploy-action.js';
|
|
12
14
|
import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
|
|
13
15
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '../../ui/alert-dialog.js';
|
|
@@ -62,6 +64,7 @@ export function FeatureNode({ data, selected, }) {
|
|
|
62
64
|
const [idCopied, setIdCopied] = useState(false);
|
|
63
65
|
const [archiveConfirmOpen, setArchiveConfirmOpen] = useState(false);
|
|
64
66
|
const featureFlags = useFeatureFlags();
|
|
67
|
+
const chatTurnStatus = useTurnStatus(data.featureId);
|
|
65
68
|
const deployTarget = featureFlags.envDeploy && data.repositoryPath && data.branch
|
|
66
69
|
? {
|
|
67
70
|
targetId: data.featureId,
|
|
@@ -116,10 +119,10 @@ export function FeatureNode({ data, selected, }) {
|
|
|
116
119
|
navigator.clipboard.writeText(data.featureId);
|
|
117
120
|
setIdCopied(true);
|
|
118
121
|
setTimeout(() => setIdCopied(false), 1500);
|
|
119
|
-
}, children: idCopied ? (_jsx("span", { className: "text-emerald-500", children: "Copied!" })) : (data.featureId.slice(0, 6)) }) }), _jsxs(TooltipContent, { side: "top", children: ["Click to copy: ", data.featureId] })] }) })) : null, (data.worktreePath ?? data.repositoryPath) ? (_jsx(FeatureSessionsDropdown, { repositoryPath: data.worktreePath ?? data.repositoryPath })) : null, data.state !== 'creating' && data.state !== 'deleting' && (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children:
|
|
122
|
+
}, children: idCopied ? (_jsx("span", { className: "text-emerald-500", children: "Copied!" })) : (data.featureId.slice(0, 6)) }) }), _jsxs(TooltipContent, { side: "top", children: ["Click to copy: ", data.featureId] })] }) })) : null, (data.worktreePath ?? data.repositoryPath) ? (_jsx(FeatureSessionsDropdown, { repositoryPath: data.worktreePath ?? data.repositoryPath })) : null, data.state !== 'creating' && data.state !== 'deleting' && (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "xs", "aria-label": "Open chat", "data-testid": "feature-node-chat-button", onClick: (e) => {
|
|
120
123
|
e.stopPropagation();
|
|
121
124
|
router.push(`/feature/${data.featureId}/chat`);
|
|
122
|
-
}, className: "nodrag relative cursor-pointer text-violet-500 hover:text-violet-600 dark:text-violet-400 dark:hover:text-violet-300", children: _jsx(MessageSquare, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { side: "top", children: _jsx("p", { className: "text-xs", children: "Chat with agent" }) })] }) })), deployTarget && data.state !== 'deleting' && data.state !== 'creating' ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "bg-border h-3 w-px shrink-0" }), isDeployReady ? (
|
|
125
|
+
}, className: "nodrag relative cursor-pointer text-violet-500 hover:text-violet-600 dark:text-violet-400 dark:hover:text-violet-300", children: [_jsx(MessageSquare, { className: "h-3 w-3" }), _jsx(ChatDotIndicator, { status: chatTurnStatus })] }) }), _jsx(TooltipContent, { side: "top", children: _jsx("p", { className: "text-xs", children: "Chat with agent" }) })] }) })), deployTarget && data.state !== 'deleting' && data.state !== 'creating' ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "bg-border h-3 w-px shrink-0" }), isDeployReady ? (
|
|
123
126
|
/* Ready: Globe + URL — Globe morphs to Stop on hover */
|
|
124
127
|
_jsxs("span", { className: "group/deploy nodrag flex min-w-0 items-center gap-1.5", "data-testid": "feature-node-deploy-button", onClick: (e) => e.stopPropagation(), children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": "Stop Dev Server", className: "flex h-5 shrink-0 cursor-pointer items-center justify-center rounded-full transition-colors", onClick: (e) => {
|
|
125
128
|
e.stopPropagation();
|
package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAicA"}
|
|
@@ -12,11 +12,16 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../
|
|
|
12
12
|
import { useDeployAction } from '../../../hooks/use-deploy-action.js';
|
|
13
13
|
import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
|
|
14
14
|
import { useRepositoryActions } from './use-repository-actions.js';
|
|
15
|
+
import { ChatDotIndicator } from '../../features/chat/ChatDotIndicator.js';
|
|
16
|
+
import { useTurnStatuses } from '../../../hooks/use-turn-statuses.js';
|
|
15
17
|
import { FeatureSessionsDropdown, } from '../../common/feature-node/feature-sessions-dropdown.js';
|
|
16
18
|
export function RepositoryNode({ data, selected, }) {
|
|
17
19
|
const router = useRouter();
|
|
18
20
|
const featureFlags = useFeatureFlags();
|
|
19
21
|
const [confirmOpen, setConfirmOpen] = useState(false);
|
|
22
|
+
const repoScopeId = data.id ? `repo-${data.id}` : `repo-${data.name}`;
|
|
23
|
+
const turnStatuses = useTurnStatuses([repoScopeId]);
|
|
24
|
+
const chatTurnStatus = turnStatuses[repoScopeId] ?? 'idle';
|
|
20
25
|
const actions = useRepositoryActions(data.repositoryPath ? { repositoryId: data.id, repositoryPath: data.repositoryPath } : null);
|
|
21
26
|
const deployAction = useDeployAction(data.repositoryPath
|
|
22
27
|
? {
|
|
@@ -71,11 +76,11 @@ export function RepositoryNode({ data, selected, }) {
|
|
|
71
76
|
e.stopPropagation();
|
|
72
77
|
data.onClick?.();
|
|
73
78
|
}
|
|
74
|
-
}, className: cn('nodrag bg-card flex w-[26rem] cursor-pointer flex-col overflow-hidden rounded-xl border shadow-sm transition-[border-color,box-shadow] duration-200 dark:bg-neutral-800/80', selected && 'border-blue-400 dark:border-amber-500/60'), children: [_jsxs("div", { className: "flex items-center gap-3 px-4 py-3", children: [_jsx(Github, { className: "text-muted-foreground h-5 w-5 shrink-0" }), _jsx("span", { "data-testid": "repository-node-name", className: "min-w-0 truncate text-sm font-medium", children: data.name }), _jsxs("div", { className: cn('flex shrink-0 items-center gap-2', (data.repositoryPath ?? data.onAdd) && 'ml-auto'), onClick: (e) => e.stopPropagation(), children: [data.repositoryPath ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in IDE", onClick: actions.openInIde, loading: actions.ideLoading, error: !!actions.ideError, icon: Code2, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in IDE" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in Shell", onClick: actions.openInShell, loading: actions.shellLoading, error: !!actions.shellError, icon: Terminal, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in Shell" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open Folder", onClick: actions.openFolder, loading: actions.folderLoading, error: !!actions.folderError, icon: FolderOpen, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open Folder" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children:
|
|
79
|
+
}, className: cn('nodrag bg-card flex w-[26rem] cursor-pointer flex-col overflow-hidden rounded-xl border shadow-sm transition-[border-color,box-shadow] duration-200 dark:bg-neutral-800/80', selected && 'border-blue-400 dark:border-amber-500/60'), children: [_jsxs("div", { className: "flex items-center gap-3 px-4 py-3", children: [_jsx(Github, { className: "text-muted-foreground h-5 w-5 shrink-0" }), _jsx("span", { "data-testid": "repository-node-name", className: "min-w-0 truncate text-sm font-medium", children: data.name }), _jsxs("div", { className: cn('flex shrink-0 items-center gap-2', (data.repositoryPath ?? data.onAdd) && 'ml-auto'), onClick: (e) => e.stopPropagation(), children: [data.repositoryPath ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in IDE", onClick: actions.openInIde, loading: actions.ideLoading, error: !!actions.ideError, icon: Code2, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in IDE" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in Shell", onClick: actions.openInShell, loading: actions.shellLoading, error: !!actions.shellError, icon: Terminal, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in Shell" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open Folder", onClick: actions.openFolder, loading: actions.folderLoading, error: !!actions.folderError, icon: FolderOpen, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open Folder" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "icon-xs", "aria-label": "Chat with agent", onClick: (e) => {
|
|
75
80
|
e.stopPropagation();
|
|
76
81
|
if (data.id)
|
|
77
82
|
router.push(`/repository/${data.id}/chat`);
|
|
78
|
-
}, className: "nodrag cursor-pointer text-violet-500 hover:text-violet-600 dark:text-violet-400 dark:hover:text-violet-300", children: _jsx(MessageSquare, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { children: "Chat with agent" })] }) }), _jsx(FeatureSessionsDropdown, { repositoryPath: data.repositoryPath, includeWorktrees: true, onCreateFromSession: handleCreateFromSession })] })) : null, data.onAdd ? _jsx("div", { className: "ml-1.5" }) : null, data.onAdd ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { "aria-label": "New feature", "data-testid": "repository-node-add-button", onClick: (e) => {
|
|
83
|
+
}, className: "nodrag relative cursor-pointer text-violet-500 hover:text-violet-600 dark:text-violet-400 dark:hover:text-violet-300", children: [_jsx(MessageSquare, { className: "h-3 w-3" }), _jsx(ChatDotIndicator, { status: chatTurnStatus })] }) }), _jsx(TooltipContent, { children: "Chat with agent" })] }) }), _jsx(FeatureSessionsDropdown, { repositoryPath: data.repositoryPath, includeWorktrees: true, onCreateFromSession: handleCreateFromSession })] })) : null, data.onAdd ? _jsx("div", { className: "ml-1.5" }) : null, data.onAdd ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { "aria-label": "New feature", "data-testid": "repository-node-add-button", onClick: (e) => {
|
|
79
84
|
e.stopPropagation();
|
|
80
85
|
data.onAdd?.();
|
|
81
86
|
}, className: cn('flex h-6 shrink-0 cursor-pointer items-center gap-0.5 rounded bg-blue-500 px-1.5 text-[11px] font-bold text-white transition-colors hover:bg-blue-600 dark:bg-amber-500 dark:hover:bg-amber-400', data.pulseAdd && 'animate-pulse-cta'), children: [_jsx(Plus, { className: "h-3 w-3" }), _jsx("span", { className: "translate-y-px", children: "New" })] }) }), _jsx(TooltipContent, { side: "top", children: "New feature" })] }) })) : null] })] }), data.branch ? (_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-git-info", className: "text-muted-foreground border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-3 text-xs", children: [_jsxs("span", { className: "flex items-center gap-1 truncate", "data-testid": "repository-node-branch", children: [_jsx(GitBranch, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: data.branch })] }), data.behindCount != null && data.behindCount > 0 ? (_jsxs("span", { className: "flex shrink-0 items-center gap-1 whitespace-nowrap text-amber-500", "data-testid": "repository-node-behind", children: [_jsx(ArrowDown, { className: "h-3 w-3 shrink-0" }), data.behindCount, " behind"] })) : null] }) }), data.commitMessage ? (_jsx("div", { "data-testid": "repository-node-commit-info", className: "text-muted-foreground border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [_jsx(GitCommitHorizontal, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "min-w-0 truncate", "data-testid": "repository-node-commit-message", children: data.commitMessage }), data.committer ? (_jsxs("span", { className: "text-muted-foreground/70 ml-auto flex shrink-0 items-center gap-1", "data-testid": "repository-node-committer", children: [_jsx(User, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: data.committer })] })) : null] }) })) : null] })) : data.gitInfoStatus === 'not-a-repo' ? (
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TurnStatus } from '../../../hooks/use-turn-statuses.js';
|
|
2
|
+
interface ChatDotIndicatorProps {
|
|
3
|
+
status: TurnStatus;
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Dot indicator for chat buttons showing agent activity state:
|
|
8
|
+
* - idle: no dot (hidden)
|
|
9
|
+
* - processing: pulsing blue dot
|
|
10
|
+
* - unread: static green dot
|
|
11
|
+
*/
|
|
12
|
+
export declare function ChatDotIndicator({ status, className }: ChatDotIndicatorProps): import("react/jsx-runtime").JSX.Element | null;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=ChatDotIndicator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatDotIndicator.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatDotIndicator.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,UAAU,qBAAqB;IAC7B,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,SAAc,EAAE,EAAE,qBAAqB,kDAUjF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Dot indicator for chat buttons showing agent activity state:
|
|
5
|
+
* - idle: no dot (hidden)
|
|
6
|
+
* - processing: pulsing blue dot
|
|
7
|
+
* - unread: static green dot
|
|
8
|
+
*/
|
|
9
|
+
export function ChatDotIndicator({ status, className = '' }) {
|
|
10
|
+
if (status === 'idle')
|
|
11
|
+
return null;
|
|
12
|
+
return (_jsx("span", { className: `absolute -top-0.5 -right-0.5 block rounded-full ${status === 'processing' ? 'h-2.5 w-2.5 animate-pulse bg-blue-500' : 'h-2 w-2 bg-green-500'} ${className}` }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { ChatDotIndicator } from './ChatDotIndicator.js';
|
|
3
|
+
declare const meta: Meta<typeof ChatDotIndicator>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof ChatDotIndicator>;
|
|
6
|
+
export declare const Idle: Story;
|
|
7
|
+
export declare const Processing: Story;
|
|
8
|
+
export declare const Unread: Story;
|
|
9
|
+
//# sourceMappingURL=ChatDotIndicator.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatDotIndicator.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatDotIndicator.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,gBAAgB,CAWvC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/C,eAAO,MAAM,IAAI,EAAE,KAElB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,KAEpB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ChatDotIndicator } from './ChatDotIndicator.js';
|
|
3
|
+
const meta = {
|
|
4
|
+
title: 'Features/Chat/ChatDotIndicator',
|
|
5
|
+
component: ChatDotIndicator,
|
|
6
|
+
decorators: [
|
|
7
|
+
(Story) => (_jsxs("div", { className: "relative inline-block rounded-md bg-zinc-800 p-4", children: [_jsx("span", { className: "text-white", children: "Chat" }), _jsx(Story, {})] })),
|
|
8
|
+
],
|
|
9
|
+
};
|
|
10
|
+
export default meta;
|
|
11
|
+
export const Idle = {
|
|
12
|
+
args: { status: 'idle' },
|
|
13
|
+
};
|
|
14
|
+
export const Processing = {
|
|
15
|
+
args: { status: 'processing' },
|
|
16
|
+
};
|
|
17
|
+
export const Unread = {
|
|
18
|
+
args: { status: 'unread' },
|
|
19
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatSheet.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatSheet.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChatSheet.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatSheet.tsx"],"names":[],"mappings":"AAmDA,wBAAgB,eAAe,4CAyX9B"}
|
|
@@ -5,6 +5,8 @@ import { MessageSquare, X, Bot, GripVertical, Maximize2, Minimize2 } from 'lucid
|
|
|
5
5
|
import { cn } from '../../../lib/utils.js';
|
|
6
6
|
import { Button } from '../../ui/button.js';
|
|
7
7
|
import { ChatTab } from './ChatTab.js';
|
|
8
|
+
import { ChatDotIndicator } from './ChatDotIndicator.js';
|
|
9
|
+
import { useTurnStatus } from '../../../hooks/turn-statuses-provider.js';
|
|
8
10
|
// ── Persistent global chat popup (draggable + resizable) ──────────────────
|
|
9
11
|
const DEFAULT_W = 520;
|
|
10
12
|
const DEFAULT_H_VH = 70; // percentage of viewport height
|
|
@@ -38,6 +40,7 @@ export function GlobalChatPopup() {
|
|
|
38
40
|
const [isOpen, setIsOpen] = useState(false);
|
|
39
41
|
const [hasOpened, setHasOpened] = useState(false);
|
|
40
42
|
const [isMaximized, setIsMaximized] = useState(false);
|
|
43
|
+
const globalChatTurnStatus = useTurnStatus('global');
|
|
41
44
|
// Position/size — initialized from localStorage
|
|
42
45
|
// eslint-disable-next-line react/hook-use-state -- wrapped setters below
|
|
43
46
|
const [pos, setPosRaw] = useState(() => loadPersistedState().pos);
|
|
@@ -239,5 +242,5 @@ export function GlobalChatPopup() {
|
|
|
239
242
|
document.addEventListener('mouseup', onUp);
|
|
240
243
|
}, className: "absolute right-0 bottom-0 z-10 h-4 w-4 cursor-se-resize" })) : null] })) : null, _jsxs("div", { className: cn('group/fab absolute bottom-4 left-4 z-30 flex items-center', isMaximized && 'hidden'), children: [_jsxs(Button, { size: "icon", onClick: toggle, className: cn('relative h-14 w-14 rounded-full shadow-lg', 'transition-all duration-200 hover:scale-105 hover:shadow-xl active:scale-95', isOpen
|
|
241
244
|
? 'bg-violet-600 text-white hover:bg-violet-500'
|
|
242
|
-
: 'bg-violet-500 text-white hover:bg-violet-400 dark:bg-violet-500 dark:hover:bg-violet-400'), children: [_jsx(MessageSquare, { className: cn('absolute h-7 w-7 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-0 rotate-90 opacity-0' : 'scale-100 rotate-0 opacity-100') }), _jsx(X, { className: cn('absolute h-6 w-6 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-100 rotate-0 opacity-100' : 'scale-0 -rotate-90 opacity-0') })] }), _jsx("div", { className: "pointer-events-none ml-3 flex translate-x-[-4px] items-center gap-2 opacity-0 transition-all duration-200 group-hover/fab:translate-x-0 group-hover/fab:opacity-100", children: _jsxs("div", { className: "bg-foreground rounded-lg px-3 py-1.5 shadow-lg", children: [_jsx("p", { className: "text-background text-xs font-medium", children: "Shep Chat" }), _jsxs("p", { className: "text-background/50 mt-0.5 flex items-center gap-1 text-[10px]", children: [_jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "\u2318" }), _jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "\u21E7" }), _jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "K" })] })] }) })] })] }));
|
|
245
|
+
: 'bg-violet-500 text-white hover:bg-violet-400 dark:bg-violet-500 dark:hover:bg-violet-400'), children: [_jsx(MessageSquare, { className: cn('absolute h-7 w-7 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-0 rotate-90 opacity-0' : 'scale-100 rotate-0 opacity-100') }), _jsx(X, { className: cn('absolute h-6 w-6 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-100 rotate-0 opacity-100' : 'scale-0 -rotate-90 opacity-0') }), !isOpen && _jsx(ChatDotIndicator, { status: globalChatTurnStatus, className: "top-0 right-0" })] }), _jsx("div", { className: "pointer-events-none ml-3 flex translate-x-[-4px] items-center gap-2 opacity-0 transition-all duration-200 group-hover/fab:translate-x-0 group-hover/fab:opacity-100", children: _jsxs("div", { className: "bg-foreground rounded-lg px-3 py-1.5 shadow-lg", children: [_jsx("p", { className: "text-background text-xs font-medium", children: "Shep Chat" }), _jsxs("p", { className: "text-background/50 mt-0.5 flex items-center gap-1 text-[10px]", children: [_jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "\u2318" }), _jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "\u21E7" }), _jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "K" })] })] }) })] })] }));
|
|
243
246
|
}
|
|
@@ -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":"AAkBA,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;CACxB;AAgDD,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;CAC5B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,kBAAkB;;;;;;;EAiQ7B"}
|
|
@@ -49,6 +49,12 @@ export function useChatRuntime(featureId, worktreePath, options) {
|
|
|
49
49
|
queryFn: () => fetchChatState(featureId),
|
|
50
50
|
refetchInterval: 3000, // Fallback polling every 3s
|
|
51
51
|
});
|
|
52
|
+
// Auto-mark as read when chat tab is open and turn status is 'unread'
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (chatState?.turnStatus === 'unread') {
|
|
55
|
+
void fetch(`/api/interactive/chat/${featureId}/mark-read`, { method: 'POST' });
|
|
56
|
+
}
|
|
57
|
+
}, [chatState?.turnStatus, featureId]);
|
|
52
58
|
const messages = useMemo(() => chatState?.messages ?? [], [chatState?.messages]);
|
|
53
59
|
const sessionStatus = chatState?.sessionStatus ?? null;
|
|
54
60
|
const backendStreamingText = chatState?.streamingText ?? null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-shell/app-shell.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-shell/app-shell.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA6C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAmBlF,UAAU,aAAa;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA4GD,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,aAAa,2CAYhE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
4
|
import { useRouter } from 'next/navigation';
|
|
5
5
|
import { SidebarProvider, SidebarInset } from '../../ui/sidebar.js';
|
|
6
6
|
import { AppSidebar } from '../../layouts/app-sidebar/index.js';
|
|
@@ -11,6 +11,7 @@ import { GitHubImportDialog } from '../../common/github-import-dialog/index.js';
|
|
|
11
11
|
import { AgentEventsProvider } from '../../../hooks/agent-events-provider.js';
|
|
12
12
|
import { DrawerCloseGuardProvider, useDrawerCloseGuard } from '../../../hooks/drawer-close-guard.js';
|
|
13
13
|
import { SidebarFeaturesProvider, useSidebarFeaturesContext, } from '../../../hooks/sidebar-features-context.js';
|
|
14
|
+
import { TurnStatusesProvider } from '../../../hooks/turn-statuses-provider.js';
|
|
14
15
|
import { useNotifications } from '../../../hooks/use-notifications.js';
|
|
15
16
|
import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
|
|
16
17
|
function AppShellInner({ children, sidebarOpen }) {
|
|
@@ -72,6 +73,12 @@ function AppShellInner({ children, sidebarOpen }) {
|
|
|
72
73
|
setShowReactPicker(false);
|
|
73
74
|
}, onSelect: handleReactPickerSelect })] }));
|
|
74
75
|
}
|
|
76
|
+
/** Wraps children with TurnStatusesProvider, collecting scope IDs from sidebar features. */
|
|
77
|
+
function TurnStatusesBridge({ children }) {
|
|
78
|
+
const { features } = useSidebarFeaturesContext();
|
|
79
|
+
const scopeIds = useMemo(() => ['global', ...features.map((f) => f.featureId)], [features]);
|
|
80
|
+
return _jsx(TurnStatusesProvider, { scopeIds: scopeIds, children: children });
|
|
81
|
+
}
|
|
75
82
|
export function AppShell({ children, sidebarOpen }) {
|
|
76
|
-
return (_jsx(AgentEventsProvider, { children: _jsx(DrawerCloseGuardProvider, { children: _jsx(SidebarFeaturesProvider, { children: _jsx(AppShellInner, { sidebarOpen: sidebarOpen, children: children }) }) }) }));
|
|
83
|
+
return (_jsx(AgentEventsProvider, { children: _jsx(DrawerCloseGuardProvider, { children: _jsx(SidebarFeaturesProvider, { children: _jsx(TurnStatusesBridge, { children: _jsx(AppShellInner, { sidebarOpen: sidebarOpen, children: children }) }) }) }) }));
|
|
77
84
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type TurnStatus } from './use-turn-statuses.js';
|
|
3
|
+
interface TurnStatusesProviderProps {
|
|
4
|
+
/** All scope IDs to poll turn statuses for */
|
|
5
|
+
scopeIds: string[];
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Polls turn statuses for all provided scope IDs in a single API call.
|
|
10
|
+
* Children use `useTurnStatus(scopeId)` to read individual statuses.
|
|
11
|
+
*/
|
|
12
|
+
export declare function TurnStatusesProvider({ scopeIds, children }: TurnStatusesProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
/**
|
|
14
|
+
* Get the turn status for a specific scope ID.
|
|
15
|
+
* Must be used within a TurnStatusesProvider.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useTurnStatus(scopeId: string): TurnStatus;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=turn-statuses-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-statuses-provider.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/turn-statuses-provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAWvE,UAAU,yBAAyB;IACjC,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,yBAAyB,2CAWrF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAGzD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext, useMemo } from 'react';
|
|
4
|
+
import { useTurnStatuses } from './use-turn-statuses.js';
|
|
5
|
+
const TurnStatusesContext = createContext({
|
|
6
|
+
getStatus: () => 'idle',
|
|
7
|
+
});
|
|
8
|
+
/**
|
|
9
|
+
* Polls turn statuses for all provided scope IDs in a single API call.
|
|
10
|
+
* Children use `useTurnStatus(scopeId)` to read individual statuses.
|
|
11
|
+
*/
|
|
12
|
+
export function TurnStatusesProvider({ scopeIds, children }) {
|
|
13
|
+
const statuses = useTurnStatuses(scopeIds);
|
|
14
|
+
const value = useMemo(() => ({
|
|
15
|
+
getStatus: (scopeId) => statuses[scopeId] ?? 'idle',
|
|
16
|
+
}), [statuses]);
|
|
17
|
+
return _jsx(TurnStatusesContext.Provider, { value: value, children: children });
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get the turn status for a specific scope ID.
|
|
21
|
+
* Must be used within a TurnStatusesProvider.
|
|
22
|
+
*/
|
|
23
|
+
export function useTurnStatus(scopeId) {
|
|
24
|
+
const ctx = useContext(TurnStatusesContext);
|
|
25
|
+
return ctx.getStatus(scopeId);
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type TurnStatus = 'idle' | 'processing' | 'unread';
|
|
2
|
+
/**
|
|
3
|
+
* Polls turn statuses for multiple feature/scope IDs.
|
|
4
|
+
* Returns a map of featureId → TurnStatus for dot indicator rendering.
|
|
5
|
+
*
|
|
6
|
+
* Polls every 3 seconds to keep indicators responsive.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useTurnStatuses(featureIds: string[]): Record<string, TurnStatus>;
|
|
9
|
+
/**
|
|
10
|
+
* Marks a feature's chat as read (clears 'unread' → 'idle').
|
|
11
|
+
*/
|
|
12
|
+
export declare function markChatRead(featureId: string): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=use-turn-statuses.d.ts.map
|
|
@@ -0,0 +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;AAE1D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAgBhF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useQuery } from '@tanstack/react-query';
|
|
3
|
+
/**
|
|
4
|
+
* Polls turn statuses for multiple feature/scope IDs.
|
|
5
|
+
* Returns a map of featureId → TurnStatus for dot indicator rendering.
|
|
6
|
+
*
|
|
7
|
+
* Polls every 3 seconds to keep indicators responsive.
|
|
8
|
+
*/
|
|
9
|
+
export function useTurnStatuses(featureIds) {
|
|
10
|
+
const sortedIds = [...featureIds].sort().join(',');
|
|
11
|
+
const { data } = useQuery({
|
|
12
|
+
queryKey: ['turn-statuses', sortedIds],
|
|
13
|
+
queryFn: async () => {
|
|
14
|
+
if (!sortedIds)
|
|
15
|
+
return {};
|
|
16
|
+
const res = await fetch(`/api/interactive/chat/turn-statuses?featureIds=${sortedIds}`);
|
|
17
|
+
if (!res.ok)
|
|
18
|
+
return {};
|
|
19
|
+
return res.json();
|
|
20
|
+
},
|
|
21
|
+
refetchInterval: 3_000,
|
|
22
|
+
enabled: featureIds.length > 0,
|
|
23
|
+
});
|
|
24
|
+
return data ?? {};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Marks a feature's chat as read (clears 'unread' → 'idle').
|
|
28
|
+
*/
|
|
29
|
+
export async function markChatRead(featureId) {
|
|
30
|
+
await fetch(`/api/interactive/chat/${featureId}/mark-read`, { method: 'POST' });
|
|
31
|
+
}
|