@shepai/cli 1.151.2-pr460.095bbae → 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/{_acc33591._.js → _6f48569b._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_acc33591._.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/{_ffa39df5._.js → _9ab5e836._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_ffa39df5._.js.map → _9ab5e836._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_320a4303._.js → _9ecb7d6d._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_320a4303._.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/{932d27878bf6ad1d.js → 00ddf2682e26248f.js} +1 -1
- package/web/.next/static/chunks/{b868f9defe50a18f.js → 0d07a524b56a91ae.js} +1 -1
- package/web/.next/static/chunks/{ade96a2ab608bded.js → 3011d2b0e84898b9.js} +2 -2
- package/web/.next/static/chunks/{036f4b19acb4fcf9.js → 3d780d0c67e9c6d7.js} +2 -2
- package/web/.next/static/chunks/{a9a2a4964b06aedd.js → 3f314c0cfed1a31f.js} +1 -1
- package/web/.next/static/chunks/{101c183087b9984f.js → 4dcd3fddd166e847.js} +1 -1
- package/web/.next/static/chunks/{77e04d00f3460226.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/{95f3089ebd3a0ad8.js → c9d93e106e541ea5.js} +1 -1
- package/web/.next/static/chunks/{686164c73f381a39.js → d1beeb17dc36ae56.js} +2 -2
- package/web/.next/static/chunks/dd72af4aa0e5a751.js +1 -0
- 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/static/chunks/011f98455d1a2f64.js +0 -7
- package/web/.next/static/chunks/16f6471485cbfed1.css +0 -1
- package/web/.next/static/chunks/460a633a069f7114.js +0 -1
- package/web/.next/static/chunks/7b93fa5e0054de38.js +0 -1
- /package/web/.next/static/{2rfPfTfJJx4Mf-4AeVzgA → Pz2jBHo89UcoWoV7z5vJp}/_buildManifest.js +0 -0
- /package/web/.next/static/{2rfPfTfJJx4Mf-4AeVzgA → Pz2jBHo89UcoWoV7z5vJp}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{2rfPfTfJJx4Mf-4AeVzgA → Pz2jBHo89UcoWoV7z5vJp}/_ssgManifest.js +0 -0
|
@@ -50,5 +50,24 @@ export interface IInteractiveSessionRepository {
|
|
|
50
50
|
* Used to enforce the concurrent session cap.
|
|
51
51
|
*/
|
|
52
52
|
countActiveSessions(): Promise<number>;
|
|
53
|
+
/**
|
|
54
|
+
* Persist the agent SDK session ID for resumption across service restarts.
|
|
55
|
+
* Agent-agnostic: works with Claude, Cursor, Codex, or any future agent.
|
|
56
|
+
*/
|
|
57
|
+
updateAgentSessionId(id: string, agentSessionId: string): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Retrieve the agent SDK session ID for a given session.
|
|
60
|
+
*/
|
|
61
|
+
getAgentSessionId(id: string): Promise<string | null>;
|
|
62
|
+
/**
|
|
63
|
+
* Update the turn status for a session.
|
|
64
|
+
* Values: 'idle' | 'processing' | 'unread'
|
|
65
|
+
*/
|
|
66
|
+
updateTurnStatus(id: string, turnStatus: string): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Get turn statuses for multiple feature IDs in a single query.
|
|
69
|
+
* Returns a map of featureId → turnStatus for features that have an active session.
|
|
70
|
+
*/
|
|
71
|
+
getTurnStatuses(featureIds: string[]): Promise<Map<string, string>>;
|
|
53
72
|
}
|
|
54
73
|
//# sourceMappingURL=interactive-session-repository.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-session-repository.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,wCAAwC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAEvE;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE/C;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,wBAAwB,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5F;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE;;;OAGG;IACH,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;OAGG;IACH,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"interactive-session-repository.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,wCAAwC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAEzD;;;;;OAKG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAEvE;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE/C;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,wBAAwB,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5F;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE;;;OAGG;IACH,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;OAGG;IACH,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEvC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExE;;OAEG;IACH,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEtD;;;OAGG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;OAGG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrE"}
|
|
@@ -50,6 +50,8 @@ export interface ChatState {
|
|
|
50
50
|
streamingText: string | null;
|
|
51
51
|
/** Session info for the toolbar (null if no active session) */
|
|
52
52
|
sessionInfo: SessionInfo | null;
|
|
53
|
+
/** Turn activity status: 'idle' | 'processing' | 'unread' (for dot indicators) */
|
|
54
|
+
turnStatus: string;
|
|
53
55
|
}
|
|
54
56
|
/** Live session metadata for the frontend toolbar. */
|
|
55
57
|
export interface SessionInfo {
|
|
@@ -165,5 +167,16 @@ export interface IInteractiveSessionService {
|
|
|
165
167
|
* Idempotent — no-op if no active session exists.
|
|
166
168
|
*/
|
|
167
169
|
stopByFeature(featureId: string): Promise<void>;
|
|
170
|
+
/**
|
|
171
|
+
* Mark a feature's chat as read — clears the 'unread' turn status to 'idle'.
|
|
172
|
+
* Called when the user opens/views the chat tab.
|
|
173
|
+
*/
|
|
174
|
+
markRead(featureId: string): Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* Get turn statuses for multiple features in a single call.
|
|
177
|
+
* Returns a map of featureId → 'idle' | 'processing' | 'unread'.
|
|
178
|
+
* Used by UI to show dot indicators on all chat buttons.
|
|
179
|
+
*/
|
|
180
|
+
getTurnStatuses(featureIds: string[]): Promise<Map<string, string>>;
|
|
168
181
|
}
|
|
169
182
|
//# sourceMappingURL=interactive-session-service.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-session-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/interactive-session-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,wCAAwC,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,EAAE,OAAO,CAAC;IACd,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,GAAG,aAAa,GAAG,UAAU,GAAG,QAAQ,CAAC;IACzD,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,wEAAwE;IACxE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,+DAA+D;IAC/D,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iEAAiE;IACjE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,+DAA+D;IAC/D,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"interactive-session-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/interactive-session-service.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-session.mapper.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/persistence/sqlite/mappers/interactive-session.mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAGjF;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,qBAAqB,
|
|
1
|
+
{"version":3,"file":"interactive-session.mapper.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/persistence/sqlite/mappers/interactive-session.mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAGjF;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,qBAAqB,CAiB7E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,qBAAqB,GAAG,kBAAkB,CAW3E"}
|
|
@@ -18,6 +18,8 @@ export function toDatabase(session) {
|
|
|
18
18
|
id: session.id,
|
|
19
19
|
feature_id: session.featureId,
|
|
20
20
|
status: session.status,
|
|
21
|
+
agent_session_id: null,
|
|
22
|
+
turn_status: 'idle',
|
|
21
23
|
started_at: session.startedAt instanceof Date ? session.startedAt.getTime() : session.startedAt,
|
|
22
24
|
stopped_at: session.stoppedAt instanceof Date ? session.stoppedAt.getTime() : (session.stoppedAt ?? null),
|
|
23
25
|
last_activity_at: session.lastActivityAt instanceof Date
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 047: Add agent_session_id column to interactive_sessions.
|
|
3
|
+
*
|
|
4
|
+
* Persists the agent SDK session ID so sessions can be resumed after
|
|
5
|
+
* service restarts (e.g. Next.js hot-reload, server restart). Previously
|
|
6
|
+
* this was only held in-memory, causing each message after a restart to
|
|
7
|
+
* spawn a brand new agent session instead of resuming the existing one.
|
|
8
|
+
*
|
|
9
|
+
* Agent-agnostic: works with Claude, Cursor, Codex, or any future agent.
|
|
10
|
+
*/
|
|
11
|
+
import type { MigrationParams } from 'umzug';
|
|
12
|
+
import type Database from 'better-sqlite3';
|
|
13
|
+
export declare function up({ context: db }: MigrationParams<Database.Database>): Promise<void>;
|
|
14
|
+
export declare function down({ context: db }: MigrationParams<Database.Database>): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=047-add-agent-session-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"047-add-agent-session-id.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/persistence/sqlite/migrations/047-add-agent-session-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,wBAAsB,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3F;AAED,wBAAsB,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAS7F"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 047: Add agent_session_id column to interactive_sessions.
|
|
3
|
+
*
|
|
4
|
+
* Persists the agent SDK session ID so sessions can be resumed after
|
|
5
|
+
* service restarts (e.g. Next.js hot-reload, server restart). Previously
|
|
6
|
+
* this was only held in-memory, causing each message after a restart to
|
|
7
|
+
* spawn a brand new agent session instead of resuming the existing one.
|
|
8
|
+
*
|
|
9
|
+
* Agent-agnostic: works with Claude, Cursor, Codex, or any future agent.
|
|
10
|
+
*/
|
|
11
|
+
export async function up({ context: db }) {
|
|
12
|
+
const columns = db.pragma('table_info(interactive_sessions)');
|
|
13
|
+
const names = new Set(columns.map((c) => c.name));
|
|
14
|
+
if (!names.has('agent_session_id')) {
|
|
15
|
+
db.exec(`ALTER TABLE interactive_sessions ADD COLUMN agent_session_id TEXT`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export async function down({ context: db }) {
|
|
19
|
+
// SQLite doesn't support DROP COLUMN before 3.35.0; recreate table
|
|
20
|
+
db.exec(`
|
|
21
|
+
CREATE TABLE interactive_sessions_backup AS SELECT
|
|
22
|
+
id, feature_id, status, started_at, stopped_at, last_activity_at, created_at, updated_at
|
|
23
|
+
FROM interactive_sessions
|
|
24
|
+
`);
|
|
25
|
+
db.exec('DROP TABLE interactive_sessions');
|
|
26
|
+
db.exec('ALTER TABLE interactive_sessions_backup RENAME TO interactive_sessions');
|
|
27
|
+
}
|
package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/048-add-turn-status.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 048: Add turn_status column to interactive_sessions.
|
|
3
|
+
*
|
|
4
|
+
* Tracks per-session activity state for UI dot indicators:
|
|
5
|
+
* - idle: no active turn, nothing to show
|
|
6
|
+
* - processing: agent is actively working on a response
|
|
7
|
+
* - unread: agent finished responding but user hasn't seen it yet
|
|
8
|
+
*
|
|
9
|
+
* Used by chat buttons (global/repo/feature) to show activity dots.
|
|
10
|
+
*/
|
|
11
|
+
import type { MigrationParams } from 'umzug';
|
|
12
|
+
import type Database from 'better-sqlite3';
|
|
13
|
+
export declare function up({ context: db }: MigrationParams<Database.Database>): Promise<void>;
|
|
14
|
+
export declare function down({ context: db }: MigrationParams<Database.Database>): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=048-add-turn-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"048-add-turn-status.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/infrastructure/persistence/sqlite/migrations/048-add-turn-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,wBAAsB,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3F;AAED,wBAAsB,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7F"}
|
package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/048-add-turn-status.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 048: Add turn_status column to interactive_sessions.
|
|
3
|
+
*
|
|
4
|
+
* Tracks per-session activity state for UI dot indicators:
|
|
5
|
+
* - idle: no active turn, nothing to show
|
|
6
|
+
* - processing: agent is actively working on a response
|
|
7
|
+
* - unread: agent finished responding but user hasn't seen it yet
|
|
8
|
+
*
|
|
9
|
+
* Used by chat buttons (global/repo/feature) to show activity dots.
|
|
10
|
+
*/
|
|
11
|
+
export async function up({ context: db }) {
|
|
12
|
+
const columns = db.pragma('table_info(interactive_sessions)');
|
|
13
|
+
const names = new Set(columns.map((c) => c.name));
|
|
14
|
+
if (!names.has('turn_status')) {
|
|
15
|
+
db.exec(`ALTER TABLE interactive_sessions ADD COLUMN turn_status TEXT NOT NULL DEFAULT 'idle'`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export async function down({ context: db }) {
|
|
19
|
+
void db;
|
|
20
|
+
}
|
|
@@ -19,5 +19,9 @@ export declare class SQLiteInteractiveSessionRepository implements IInteractiveS
|
|
|
19
19
|
updateLastActivity(id: string, lastActivityAt: Date): Promise<void>;
|
|
20
20
|
markAllActiveStopped(): Promise<void>;
|
|
21
21
|
countActiveSessions(): Promise<number>;
|
|
22
|
+
updateAgentSessionId(id: string, agentSessionId: string): Promise<void>;
|
|
23
|
+
getAgentSessionId(id: string): Promise<string | null>;
|
|
24
|
+
updateTurnStatus(id: string, turnStatus: string): Promise<void>;
|
|
25
|
+
getTurnStatuses(featureIds: string[]): Promise<Map<string, string>>;
|
|
22
26
|
}
|
|
23
27
|
//# sourceMappingURL=sqlite-interactive-session.repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-interactive-session.repository.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yFAAyF,CAAC;AAC7I,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAO5E,qBACa,kCAAmC,YAAW,6BAA6B;IAC1E,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAE5C,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAOxD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAStE,aAAa,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAO9C,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,wBAAwB,EAChC,SAAS,CAAC,EAAE,IAAI,GACf,OAAO,CAAC,IAAI,CAAC;IAeV,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnE,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrC,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"sqlite-interactive-session.repository.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yFAAyF,CAAC;AAC7I,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAO5E,qBACa,kCAAmC,YAAW,6BAA6B;IAC1E,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAE5C,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAOxD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAStE,aAAa,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAO9C,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,wBAAwB,EAChC,SAAS,CAAC,EAAE,IAAI,GACf,OAAO,CAAC,IAAI,CAAC;IAeV,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnE,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrC,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAStC,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvE,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAOrD,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/D,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAwB1E"}
|
package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.js
CHANGED
|
@@ -77,6 +77,43 @@ let SQLiteInteractiveSessionRepository = class SQLiteInteractiveSessionRepositor
|
|
|
77
77
|
.get();
|
|
78
78
|
return result.count;
|
|
79
79
|
}
|
|
80
|
+
async updateAgentSessionId(id, agentSessionId) {
|
|
81
|
+
this.db
|
|
82
|
+
.prepare(`UPDATE interactive_sessions SET agent_session_id = @agent_session_id, updated_at = @updated_at WHERE id = @id`)
|
|
83
|
+
.run({ id, agent_session_id: agentSessionId, updated_at: Date.now() });
|
|
84
|
+
}
|
|
85
|
+
async getAgentSessionId(id) {
|
|
86
|
+
const row = this.db
|
|
87
|
+
.prepare('SELECT agent_session_id FROM interactive_sessions WHERE id = ?')
|
|
88
|
+
.get(id);
|
|
89
|
+
return row?.agent_session_id ?? null;
|
|
90
|
+
}
|
|
91
|
+
async updateTurnStatus(id, turnStatus) {
|
|
92
|
+
this.db
|
|
93
|
+
.prepare(`UPDATE interactive_sessions SET turn_status = @turn_status, updated_at = @updated_at WHERE id = @id`)
|
|
94
|
+
.run({ id, turn_status: turnStatus, updated_at: Date.now() });
|
|
95
|
+
}
|
|
96
|
+
async getTurnStatuses(featureIds) {
|
|
97
|
+
const result = new Map();
|
|
98
|
+
if (featureIds.length === 0)
|
|
99
|
+
return result;
|
|
100
|
+
// Use a single query with placeholders for all feature IDs.
|
|
101
|
+
// For each feature, get the most recent session's turn_status.
|
|
102
|
+
const placeholders = featureIds.map(() => '?').join(',');
|
|
103
|
+
const rows = this.db
|
|
104
|
+
.prepare(`SELECT feature_id, turn_status FROM interactive_sessions
|
|
105
|
+
WHERE feature_id IN (${placeholders})
|
|
106
|
+
AND status IN ('booting','ready')
|
|
107
|
+
ORDER BY created_at DESC`)
|
|
108
|
+
.all(...featureIds);
|
|
109
|
+
// First row per feature wins (most recent due to ORDER BY)
|
|
110
|
+
for (const row of rows) {
|
|
111
|
+
if (!result.has(row.feature_id)) {
|
|
112
|
+
result.set(row.feature_id, row.turn_status);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
80
117
|
};
|
|
81
118
|
SQLiteInteractiveSessionRepository = __decorate([
|
|
82
119
|
injectable(),
|
package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts
CHANGED
|
@@ -39,8 +39,8 @@ export declare class InteractiveSessionService implements IInteractiveSessionSer
|
|
|
39
39
|
private readonly contextBuilder;
|
|
40
40
|
/** Live sessions indexed by sessionId. */
|
|
41
41
|
private sessions;
|
|
42
|
-
/** Cached
|
|
43
|
-
private
|
|
42
|
+
/** Cached agentSessionIds from stopped sessions, keyed by featureId. */
|
|
43
|
+
private stoppedAgentSessionIds;
|
|
44
44
|
constructor(sessionRepo: IInteractiveSessionRepository, messageRepo: IInteractiveMessageRepository, executorFactory: IAgentExecutorFactory, featureRepo: IFeatureRepository, contextBuilder: FeatureContextBuilder);
|
|
45
45
|
startSession(featureId: string, worktreePath: string, model?: string, agentType?: string): Promise<InteractiveSession>;
|
|
46
46
|
/**
|
|
@@ -64,6 +64,8 @@ export declare class InteractiveSessionService implements IInteractiveSessionSer
|
|
|
64
64
|
getChatState(featureId: string): Promise<ChatState>;
|
|
65
65
|
subscribeByFeature(featureId: string, onChunk: (chunk: StreamChunk) => void): UnsubscribeFn;
|
|
66
66
|
stopByFeature(featureId: string): Promise<void>;
|
|
67
|
+
markRead(featureId: string): Promise<void>;
|
|
68
|
+
getTurnStatuses(featureIds: string[]): Promise<Map<string, string>>;
|
|
67
69
|
/** Find the in-memory state for an active session for a feature. */
|
|
68
70
|
private findActiveStateForFeature;
|
|
69
71
|
/** Resolve the agent type from an explicit override or settings. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-session.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/interactive/interactive-session.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACX,aAAa,EACb,SAAS,EACV,MAAM,qFAAqF,CAAC;AAC7F,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,4FAA4F,CAAC;AAChJ,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,4FAA4F,CAAC;AAChJ,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8EAA8E,CAAC;AAE1H,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gFAAgF,CAAC;AACzH,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AASlG,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAsC1E;;;;;;;;;;;;;;GAcG;AACH,qBAAa,yBAA0B,YAAW,0BAA0B;IAOxE,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAVjC,0CAA0C;IAC1C,OAAO,CAAC,QAAQ,CAAmC;IACnD,
|
|
1
|
+
{"version":3,"file":"interactive-session.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/interactive/interactive-session.service.ts"],"names":[],"mappings":"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"}
|
package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.js
CHANGED
|
@@ -42,8 +42,8 @@ export class InteractiveSessionService {
|
|
|
42
42
|
contextBuilder;
|
|
43
43
|
/** Live sessions indexed by sessionId. */
|
|
44
44
|
sessions = new Map();
|
|
45
|
-
/** Cached
|
|
46
|
-
|
|
45
|
+
/** Cached agentSessionIds from stopped sessions, keyed by featureId. */
|
|
46
|
+
stoppedAgentSessionIds = new Map();
|
|
47
47
|
constructor(sessionRepo, messageRepo, executorFactory, featureRepo, contextBuilder) {
|
|
48
48
|
this.sessionRepo = sessionRepo;
|
|
49
49
|
this.messageRepo = messageRepo;
|
|
@@ -72,16 +72,24 @@ export class InteractiveSessionService {
|
|
|
72
72
|
updatedAt: now,
|
|
73
73
|
};
|
|
74
74
|
await this.sessionRepo.create(session);
|
|
75
|
-
// Carry over
|
|
76
|
-
let
|
|
75
|
+
// Carry over agentSessionId from previous session so resumption works
|
|
76
|
+
let previousAgentSessionId;
|
|
77
77
|
for (const [, s] of this.sessions) {
|
|
78
|
-
if (s.featureId === featureId && s.
|
|
79
|
-
|
|
78
|
+
if (s.featureId === featureId && s.agentSessionId) {
|
|
79
|
+
previousAgentSessionId = s.agentSessionId;
|
|
80
80
|
break;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
// Also check stoppedSessions cache (populated on stop)
|
|
84
|
-
|
|
84
|
+
previousAgentSessionId ??= this.stoppedAgentSessionIds.get(featureId);
|
|
85
|
+
// Fall back to DB — the in-memory cache may be empty after service restart
|
|
86
|
+
if (!previousAgentSessionId) {
|
|
87
|
+
const latestDbSession = await this.sessionRepo.findByFeatureId(featureId);
|
|
88
|
+
if (latestDbSession) {
|
|
89
|
+
previousAgentSessionId =
|
|
90
|
+
(await this.sessionRepo.getAgentSessionId(latestDbSession.id)) ?? undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
85
93
|
// Set up in-memory state
|
|
86
94
|
const state = {
|
|
87
95
|
sessionId: session.id,
|
|
@@ -90,7 +98,7 @@ export class InteractiveSessionService {
|
|
|
90
98
|
model,
|
|
91
99
|
agentType,
|
|
92
100
|
handle: null,
|
|
93
|
-
|
|
101
|
+
agentSessionId: previousAgentSessionId,
|
|
94
102
|
timer: null,
|
|
95
103
|
currentAssistantBuffer: '',
|
|
96
104
|
toolEventsLog: [],
|
|
@@ -171,9 +179,9 @@ export class InteractiveSessionService {
|
|
|
171
179
|
// Create the interactive executor and session
|
|
172
180
|
const executor = this.executorFactory.createInteractiveExecutor(resolvedAgentType, authConfig);
|
|
173
181
|
let handle;
|
|
174
|
-
if (state.
|
|
182
|
+
if (state.agentSessionId) {
|
|
175
183
|
// Resume existing SDK session
|
|
176
|
-
handle = await executor.resumeSession(state.
|
|
184
|
+
handle = await executor.resumeSession(state.agentSessionId, {
|
|
177
185
|
cwd: worktreePath,
|
|
178
186
|
model: state.model,
|
|
179
187
|
systemPrompt: context,
|
|
@@ -249,7 +257,9 @@ export class InteractiveSessionService {
|
|
|
249
257
|
// Capture the SDK session ID (available after first message exchange)
|
|
250
258
|
const sdkSessionId = handle.sessionId;
|
|
251
259
|
if (sdkSessionId) {
|
|
252
|
-
state.
|
|
260
|
+
state.agentSessionId = sdkSessionId;
|
|
261
|
+
// Persist to DB so it survives service restarts
|
|
262
|
+
void this.sessionRepo.updateAgentSessionId(state.sessionId, sdkSessionId);
|
|
253
263
|
}
|
|
254
264
|
// Persist greeting and mark session ready
|
|
255
265
|
const greetingMsg = {
|
|
@@ -263,6 +273,11 @@ export class InteractiveSessionService {
|
|
|
263
273
|
};
|
|
264
274
|
await this.messageRepo.create(greetingMsg);
|
|
265
275
|
await this.sessionRepo.updateStatus(state.sessionId, InteractiveSessionStatus.ready);
|
|
276
|
+
// If there's a pending user message, the next turn will set 'processing'.
|
|
277
|
+
// Otherwise boot greeting is expected — mark idle.
|
|
278
|
+
if (!state.pendingUserContent) {
|
|
279
|
+
void this.sessionRepo.updateTurnStatus(state.sessionId, 'idle');
|
|
280
|
+
}
|
|
266
281
|
state.currentAssistantBuffer = '';
|
|
267
282
|
state.toolEventsLog = [];
|
|
268
283
|
// Notify subscribers of end-of-turn
|
|
@@ -294,6 +309,9 @@ export class InteractiveSessionService {
|
|
|
294
309
|
await this.messageRepo.create(greetingMsg);
|
|
295
310
|
}
|
|
296
311
|
await this.sessionRepo.updateStatus(state.sessionId, InteractiveSessionStatus.ready);
|
|
312
|
+
if (!state.pendingUserContent) {
|
|
313
|
+
void this.sessionRepo.updateTurnStatus(state.sessionId, 'idle');
|
|
314
|
+
}
|
|
297
315
|
state.currentAssistantBuffer = '';
|
|
298
316
|
state.toolEventsLog = [];
|
|
299
317
|
this.resetTimer(state);
|
|
@@ -311,8 +329,8 @@ export class InteractiveSessionService {
|
|
|
311
329
|
catch {
|
|
312
330
|
// Best-effort DB update
|
|
313
331
|
}
|
|
314
|
-
if (state.
|
|
315
|
-
this.
|
|
332
|
+
if (state.agentSessionId) {
|
|
333
|
+
this.stoppedAgentSessionIds.set(state.featureId, state.agentSessionId);
|
|
316
334
|
}
|
|
317
335
|
this.sessions.delete(state.sessionId);
|
|
318
336
|
}
|
|
@@ -331,9 +349,9 @@ export class InteractiveSessionService {
|
|
|
331
349
|
state.streamAbort = undefined;
|
|
332
350
|
}
|
|
333
351
|
this.clearTimer(state);
|
|
334
|
-
// Cache
|
|
335
|
-
if (state.
|
|
336
|
-
this.
|
|
352
|
+
// Cache agentSessionId so resumption works when session restarts
|
|
353
|
+
if (state.agentSessionId) {
|
|
354
|
+
this.stoppedAgentSessionIds.set(state.featureId, state.agentSessionId);
|
|
337
355
|
}
|
|
338
356
|
this.sessions.delete(sessionId);
|
|
339
357
|
// Close the SDK session handle
|
|
@@ -347,6 +365,7 @@ export class InteractiveSessionService {
|
|
|
347
365
|
state.handle = null;
|
|
348
366
|
}
|
|
349
367
|
await this.sessionRepo.updateStatus(sessionId, InteractiveSessionStatus.stopped, new Date());
|
|
368
|
+
void this.sessionRepo.updateTurnStatus(sessionId, 'idle');
|
|
350
369
|
}
|
|
351
370
|
async sendMessage(sessionId, content) {
|
|
352
371
|
const dbSession = await this.sessionRepo.findById(sessionId);
|
|
@@ -386,6 +405,8 @@ export class InteractiveSessionService {
|
|
|
386
405
|
}
|
|
387
406
|
state.currentAssistantBuffer = '';
|
|
388
407
|
state.toolEventsLog = [];
|
|
408
|
+
// Mark turn as processing for dot indicator
|
|
409
|
+
void this.sessionRepo.updateTurnStatus(state.sessionId, 'processing');
|
|
389
410
|
// Send the message to the SDK session
|
|
390
411
|
await state.handle.send(prompt);
|
|
391
412
|
// Set up abort controller for this stream
|
|
@@ -455,6 +476,9 @@ export class InteractiveSessionService {
|
|
|
455
476
|
await this.messageRepo.create(msg);
|
|
456
477
|
state.currentAssistantBuffer = '';
|
|
457
478
|
state.toolEventsLog = [];
|
|
479
|
+
// Mark as unread — if user has the chat open, the frontend
|
|
480
|
+
// will immediately call markRead to clear it
|
|
481
|
+
void this.sessionRepo.updateTurnStatus(state.sessionId, 'unread');
|
|
458
482
|
// Notify subscribers of end-of-turn
|
|
459
483
|
state.subscribers.forEach((sub) => sub({ delta: '', done: true }));
|
|
460
484
|
return; // Turn complete
|
|
@@ -465,17 +489,9 @@ export class InteractiveSessionService {
|
|
|
465
489
|
state.subscribers.forEach((sub) => sub({ delta: '', done: true, log: `Error: ${event.content ?? 'unknown'}` }));
|
|
466
490
|
break;
|
|
467
491
|
case 'init':
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
.join(' · ');
|
|
472
|
-
void this.persistToolEvent(state, 'Session started', initDetail);
|
|
473
|
-
state.subscribers.forEach((sub) => sub({
|
|
474
|
-
delta: '',
|
|
475
|
-
done: false,
|
|
476
|
-
activity: { kind: 'system', label: 'Session started', detail: initDetail },
|
|
477
|
-
}));
|
|
478
|
-
}
|
|
492
|
+
// The SDK emits init on every turn, but we only show "Session started"
|
|
493
|
+
// during boot (handled in completeBootAsync). Ignore it here to avoid
|
|
494
|
+
// spamming the chat with repeated session-started messages.
|
|
479
495
|
break;
|
|
480
496
|
case 'api_retry':
|
|
481
497
|
state.subscribers.forEach((sub) => sub({ delta: '', done: false, log: event.content ?? 'Retrying API call...' }));
|
|
@@ -557,8 +573,8 @@ export class InteractiveSessionService {
|
|
|
557
573
|
if (state) {
|
|
558
574
|
await this.stopSession(state.sessionId);
|
|
559
575
|
}
|
|
560
|
-
// Also clear the cached
|
|
561
|
-
this.
|
|
576
|
+
// Also clear the cached agentSessionId so next session starts fresh
|
|
577
|
+
this.stoppedAgentSessionIds.delete(featureId);
|
|
562
578
|
return this.messageRepo.deleteByFeatureId(featureId);
|
|
563
579
|
}
|
|
564
580
|
async getSession(sessionId) {
|
|
@@ -604,7 +620,17 @@ export class InteractiveSessionService {
|
|
|
604
620
|
}
|
|
605
621
|
}
|
|
606
622
|
else {
|
|
607
|
-
// No
|
|
623
|
+
// No in-memory session — check DB for an orphaned active session (e.g. after
|
|
624
|
+
// service restart / hot-reload) and mark it stopped before booting a new one.
|
|
625
|
+
// The agentSessionId is persisted in DB so startSession will pick it up for
|
|
626
|
+
// SDK session resumption.
|
|
627
|
+
const dbSession = await this.sessionRepo.findByFeatureId(featureId);
|
|
628
|
+
if (dbSession &&
|
|
629
|
+
(dbSession.status === InteractiveSessionStatus.ready ||
|
|
630
|
+
dbSession.status === InteractiveSessionStatus.booting)) {
|
|
631
|
+
await this.sessionRepo.updateStatus(dbSession.id, InteractiveSessionStatus.stopped, new Date());
|
|
632
|
+
}
|
|
633
|
+
// Boot a new session — startSession will find the agentSessionId from DB
|
|
608
634
|
const session = await this.startSession(featureId, worktreePath);
|
|
609
635
|
const newState = this.sessions.get(session.id);
|
|
610
636
|
if (newState) {
|
|
@@ -631,7 +657,7 @@ export class InteractiveSessionService {
|
|
|
631
657
|
const displayModel = state.model ?? 'claude-sonnet-4-6';
|
|
632
658
|
sessionInfo = {
|
|
633
659
|
pid: null, // SDK manages process internally
|
|
634
|
-
sessionId: state.
|
|
660
|
+
sessionId: state.agentSessionId ?? state.sessionId,
|
|
635
661
|
model: displayModel,
|
|
636
662
|
startedAt: dbSession?.startedAt
|
|
637
663
|
? new Date(dbSession.startedAt).toISOString()
|
|
@@ -665,7 +691,22 @@ export class InteractiveSessionService {
|
|
|
665
691
|
}
|
|
666
692
|
}
|
|
667
693
|
}
|
|
668
|
-
|
|
694
|
+
// Resolve turn status from DB
|
|
695
|
+
let turnStatus = 'idle';
|
|
696
|
+
const activeState = state;
|
|
697
|
+
if (activeState) {
|
|
698
|
+
const statuses = await this.sessionRepo.getTurnStatuses([featureId]);
|
|
699
|
+
turnStatus = statuses.get(featureId) ?? 'idle';
|
|
700
|
+
}
|
|
701
|
+
else {
|
|
702
|
+
// Check DB for the latest session's turn status
|
|
703
|
+
const latest = await this.sessionRepo.findByFeatureId(featureId);
|
|
704
|
+
if (latest) {
|
|
705
|
+
const statuses = await this.sessionRepo.getTurnStatuses([featureId]);
|
|
706
|
+
turnStatus = statuses.get(featureId) ?? 'idle';
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return { messages, sessionStatus, streamingText, sessionInfo, turnStatus };
|
|
669
710
|
}
|
|
670
711
|
subscribeByFeature(featureId, onChunk) {
|
|
671
712
|
const state = this.findActiveStateForFeature(featureId);
|
|
@@ -693,6 +734,22 @@ export class InteractiveSessionService {
|
|
|
693
734
|
await this.messageRepo.create(msg);
|
|
694
735
|
await this.stopSession(state.sessionId);
|
|
695
736
|
}
|
|
737
|
+
async markRead(featureId) {
|
|
738
|
+
// Find the active session for this feature and clear unread status
|
|
739
|
+
const state = this.findActiveStateForFeature(featureId);
|
|
740
|
+
if (state) {
|
|
741
|
+
void this.sessionRepo.updateTurnStatus(state.sessionId, 'idle');
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
// Fallback: check DB for the latest active session
|
|
745
|
+
const latest = await this.sessionRepo.findByFeatureId(featureId);
|
|
746
|
+
if (latest) {
|
|
747
|
+
void this.sessionRepo.updateTurnStatus(latest.id, 'idle');
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
async getTurnStatuses(featureIds) {
|
|
751
|
+
return this.sessionRepo.getTurnStatuses(featureIds);
|
|
752
|
+
}
|
|
696
753
|
/** Find the in-memory state for an active session for a feature. */
|
|
697
754
|
findActiveStateForFeature(featureId) {
|
|
698
755
|
for (const state of this.sessions.values()) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mark chat as read API.
|
|
3
|
+
*
|
|
4
|
+
* POST /api/interactive/chat/[featureId]/mark-read
|
|
5
|
+
*
|
|
6
|
+
* Clears the 'unread' turn status to 'idle'. Called when the user
|
|
7
|
+
* opens/views the chat tab for a feature.
|
|
8
|
+
*/
|
|
9
|
+
import type { NextRequest } from 'next/server';
|
|
10
|
+
import { NextResponse } from 'next/server';
|
|
11
|
+
export declare const dynamic = "force-dynamic";
|
|
12
|
+
interface RouteParams {
|
|
13
|
+
params: Promise<{
|
|
14
|
+
featureId: string;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
export declare function POST(_request: NextRequest, { params }: RouteParams): Promise<NextResponse>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=route.d.ts.map
|
package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxC;AAED,wBAAsB,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAchG"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mark chat as read API.
|
|
3
|
+
*
|
|
4
|
+
* POST /api/interactive/chat/[featureId]/mark-read
|
|
5
|
+
*
|
|
6
|
+
* Clears the 'unread' turn status to 'idle'. Called when the user
|
|
7
|
+
* opens/views the chat tab for a feature.
|
|
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 POST(_request, { params }) {
|
|
13
|
+
try {
|
|
14
|
+
const { featureId } = await params;
|
|
15
|
+
const service = resolve('IInteractiveSessionService');
|
|
16
|
+
await service.markRead(featureId);
|
|
17
|
+
return NextResponse.json({ ok: true });
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
// eslint-disable-next-line no-console
|
|
21
|
+
console.error('[POST /api/interactive/chat/:featureId/mark-read]', error);
|
|
22
|
+
return NextResponse.json({ error: error instanceof Error ? error.message : 'Internal server error' }, { status: 500 });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
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 type { NextRequest } from 'next/server';
|
|
10
|
+
import { NextResponse } from 'next/server';
|
|
11
|
+
export declare const dynamic = "force-dynamic";
|
|
12
|
+
export declare function GET(request: NextRequest): Promise<NextResponse>;
|
|
13
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/presentation/web/app/api/interactive/chat/turn-statuses/route.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,wBAAsB,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA8BrE"}
|