@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.
Files changed (259) hide show
  1. package/dist/packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.d.ts +19 -0
  2. package/dist/packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts +13 -0
  4. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts.map +1 -1
  5. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/interactive-session.mapper.d.ts +2 -0
  6. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/interactive-session.mapper.d.ts.map +1 -1
  7. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/interactive-session.mapper.js +2 -0
  8. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/047-add-agent-session-id.d.ts +15 -0
  9. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/047-add-agent-session-id.d.ts.map +1 -0
  10. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/047-add-agent-session-id.js +27 -0
  11. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/048-add-turn-status.d.ts +15 -0
  12. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/048-add-turn-status.d.ts.map +1 -0
  13. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/048-add-turn-status.js +20 -0
  14. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts +4 -0
  15. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts.map +1 -1
  16. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.js +37 -0
  17. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts +4 -2
  18. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts.map +1 -1
  19. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.js +89 -32
  20. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.d.ts +19 -0
  21. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.d.ts.map +1 -0
  22. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/mark-read/route.js +24 -0
  23. package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.d.ts +13 -0
  24. package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.d.ts.map +1 -0
  25. package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.js +36 -0
  26. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  27. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +5 -2
  28. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  29. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +7 -2
  30. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.d.ts +14 -0
  31. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.d.ts.map +1 -0
  32. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.js +13 -0
  33. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts +9 -0
  34. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts.map +1 -0
  35. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.js +19 -0
  36. package/dist/src/presentation/web/components/features/chat/ChatSheet.d.ts.map +1 -1
  37. package/dist/src/presentation/web/components/features/chat/ChatSheet.js +4 -1
  38. package/dist/src/presentation/web/components/features/chat/useChatRuntime.d.ts.map +1 -1
  39. package/dist/src/presentation/web/components/features/chat/useChatRuntime.js +6 -0
  40. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.d.ts.map +1 -1
  41. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +9 -2
  42. package/dist/src/presentation/web/hooks/turn-statuses-provider.d.ts +19 -0
  43. package/dist/src/presentation/web/hooks/turn-statuses-provider.d.ts.map +1 -0
  44. package/dist/src/presentation/web/hooks/turn-statuses-provider.js +26 -0
  45. package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts +13 -0
  46. package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts.map +1 -0
  47. package/dist/src/presentation/web/hooks/use-turn-statuses.js +31 -0
  48. package/dist/tsconfig.build.tsbuildinfo +1 -1
  49. package/package.json +1 -1
  50. package/web/.next/BUILD_ID +1 -1
  51. package/web/.next/app-path-routes-manifest.json +2 -0
  52. package/web/.next/build-manifest.json +2 -2
  53. package/web/.next/fallback-build-manifest.json +2 -2
  54. package/web/.next/prerender-manifest.json +3 -3
  55. package/web/.next/required-server-files.js +1 -1
  56. package/web/.next/required-server-files.json +1 -1
  57. package/web/.next/routes-manifest.json +14 -0
  58. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
  59. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  60. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  61. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +26 -26
  62. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  63. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +29 -29
  65. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  66. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  67. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  68. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  69. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  70. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
  71. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  72. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  73. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +26 -26
  74. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  75. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  77. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  78. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  79. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +26 -26
  80. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  81. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  82. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +29 -29
  83. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  84. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  85. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  86. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  87. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  88. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
  89. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  90. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  91. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
  92. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  93. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  94. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +26 -26
  95. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  96. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  97. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  98. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  99. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  100. package/web/.next/server/app/_global-error.html +2 -2
  101. package/web/.next/server/app/_global-error.rsc +1 -1
  102. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  103. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  104. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  105. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  106. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  107. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +5 -5
  108. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  109. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  110. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  111. package/web/.next/server/app/api/attachments/upload-from-path/route.js +1 -1
  112. package/web/.next/server/app/api/attachments/upload-from-path/route.js.nft.json +1 -1
  113. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  114. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  115. package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route/app-paths-manifest.json +3 -0
  116. package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route/build-manifest.json +11 -0
  117. package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route/server-reference-manifest.json +4 -0
  118. package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route.js +7 -0
  119. package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route.js.map +5 -0
  120. package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route.js.nft.json +1 -0
  121. package/web/.next/server/app/api/interactive/chat/[featureId]/mark-read/route_client-reference-manifest.js +2 -0
  122. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  123. package/web/.next/server/app/api/interactive/chat/turn-statuses/route/app-paths-manifest.json +3 -0
  124. package/web/.next/server/app/api/interactive/chat/turn-statuses/route/build-manifest.json +11 -0
  125. package/web/.next/server/app/api/interactive/chat/turn-statuses/route/server-reference-manifest.json +4 -0
  126. package/web/.next/server/app/api/interactive/chat/turn-statuses/route.js +7 -0
  127. package/web/.next/server/app/api/interactive/chat/turn-statuses/route.js.map +5 -0
  128. package/web/.next/server/app/api/interactive/chat/turn-statuses/route.js.nft.json +1 -0
  129. package/web/.next/server/app/api/interactive/chat/turn-statuses/route_client-reference-manifest.js +2 -0
  130. package/web/.next/server/app/api/sessions-batch/route.js +1 -1
  131. package/web/.next/server/app/api/sessions-batch/route.js.nft.json +1 -1
  132. package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  133. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  134. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  135. package/web/.next/server/app/skills/page/server-reference-manifest.json +10 -10
  136. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  137. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  138. package/web/.next/server/app/tools/page/server-reference-manifest.json +10 -10
  139. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  140. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  141. package/web/.next/server/app/version/page/server-reference-manifest.json +5 -5
  142. package/web/.next/server/app/version/page.js.nft.json +1 -1
  143. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  144. package/web/.next/server/app-paths-manifest.json +2 -0
  145. package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_[featureId]_mark-read_route_actions_ce79c730.js +3 -0
  146. package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_[featureId]_mark-read_route_actions_ce79c730.js.map +1 -0
  147. package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_turn-statuses_route_actions_f97e4de7.js +3 -0
  148. package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_turn-statuses_route_actions_f97e4de7.js.map +1 -0
  149. package/web/.next/server/chunks/{[root-of-the-server]__0d33c29e._.js → [root-of-the-server]__31598852._.js} +2 -2
  150. package/web/.next/server/chunks/{[root-of-the-server]__0d33c29e._.js.map → [root-of-the-server]__31598852._.js.map} +1 -1
  151. package/web/.next/server/chunks/[root-of-the-server]__32b04219._.js +3 -0
  152. package/web/.next/server/chunks/[root-of-the-server]__32b04219._.js.map +1 -0
  153. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  154. package/web/.next/server/chunks/[root-of-the-server]__ab4951b1._.js +3 -0
  155. package/web/.next/server/chunks/[root-of-the-server]__ab4951b1._.js.map +1 -0
  156. package/web/.next/server/chunks/{[root-of-the-server]__a5879003._.js → [root-of-the-server]__ea653642._.js} +2 -2
  157. package/web/.next/server/chunks/{[root-of-the-server]__a5879003._.js.map → [root-of-the-server]__ea653642._.js.map} +1 -1
  158. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  159. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  160. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
  161. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  162. package/web/.next/server/chunks/ssr/[root-of-the-server]__17ed7ed1._.js +1 -1
  163. package/web/.next/server/chunks/ssr/[root-of-the-server]__17ed7ed1._.js.map +1 -1
  164. package/web/.next/server/chunks/ssr/[root-of-the-server]__28d0d265._.js +2 -2
  165. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  166. package/web/.next/server/chunks/ssr/[root-of-the-server]__42bf1807._.js +1 -1
  167. package/web/.next/server/chunks/ssr/[root-of-the-server]__42bf1807._.js.map +1 -1
  168. package/web/.next/server/chunks/ssr/[root-of-the-server]__563f2f7a._.js +3 -0
  169. package/web/.next/server/chunks/ssr/[root-of-the-server]__563f2f7a._.js.map +1 -0
  170. package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js +1 -1
  171. package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js.map +1 -1
  172. package/web/.next/server/chunks/ssr/[root-of-the-server]__88f7e8e6._.js +1 -1
  173. package/web/.next/server/chunks/ssr/[root-of-the-server]__88f7e8e6._.js.map +1 -1
  174. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js +1 -1
  175. package/web/.next/server/chunks/ssr/[root-of-the-server]__c30f1f82._.js +1 -1
  176. package/web/.next/server/chunks/ssr/[root-of-the-server]__c30f1f82._.js.map +1 -1
  177. package/web/.next/server/chunks/ssr/{[root-of-the-server]__31f1c3b0._.js → [root-of-the-server]__e91ffd5e._.js} +3 -3
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__e91ffd5e._.js.map +1 -0
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__f80bfc75._.js +1 -1
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__f80bfc75._.js.map +1 -1
  181. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  182. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  183. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  184. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  185. package/web/.next/server/chunks/ssr/_3a0b989f._.js +2 -2
  186. package/web/.next/server/chunks/ssr/_3a0b989f._.js.map +1 -1
  187. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  188. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  189. package/web/.next/server/chunks/ssr/_5f69c13f._.js +1 -1
  190. package/web/.next/server/chunks/ssr/_5f69c13f._.js.map +1 -1
  191. package/web/.next/server/chunks/ssr/_6f48569b._.js +3 -0
  192. package/web/.next/server/chunks/ssr/{_de71404e._.js.map → _6f48569b._.js.map} +1 -1
  193. package/web/.next/server/chunks/ssr/_7c5b97c6._.js +1 -1
  194. package/web/.next/server/chunks/ssr/_7c5b97c6._.js.map +1 -1
  195. package/web/.next/server/chunks/ssr/_82c57f10._.js +1 -1
  196. package/web/.next/server/chunks/ssr/_82c57f10._.js.map +1 -1
  197. package/web/.next/server/chunks/ssr/_9495d50b._.js +1 -1
  198. package/web/.next/server/chunks/ssr/_9495d50b._.js.map +1 -1
  199. package/web/.next/server/chunks/ssr/{_4c42590e._.js → _9ab5e836._.js} +2 -2
  200. package/web/.next/server/chunks/ssr/{_4c42590e._.js.map → _9ab5e836._.js.map} +1 -1
  201. package/web/.next/server/chunks/ssr/{_eb9467e9._.js → _9ecb7d6d._.js} +2 -2
  202. package/web/.next/server/chunks/ssr/{_eb9467e9._.js.map → _9ecb7d6d._.js.map} +1 -1
  203. package/web/.next/server/chunks/ssr/_a0e3f7e4._.js +1 -1
  204. package/web/.next/server/chunks/ssr/_a0e3f7e4._.js.map +1 -1
  205. package/web/.next/server/chunks/ssr/_ac4a3873._.js +1 -1
  206. package/web/.next/server/chunks/ssr/_ca0aa7f0._.js +1 -1
  207. package/web/.next/server/chunks/ssr/_ca0aa7f0._.js.map +1 -1
  208. package/web/.next/server/chunks/ssr/_cb5a021e._.js +1 -1
  209. package/web/.next/server/chunks/ssr/_cb5a021e._.js.map +1 -1
  210. package/web/.next/server/chunks/ssr/_d86175ae._.js +1 -1
  211. package/web/.next/server/chunks/ssr/_d86175ae._.js.map +1 -1
  212. package/web/.next/server/chunks/ssr/_d8bedf13._.js +1 -1
  213. package/web/.next/server/chunks/ssr/_d8bedf13._.js.map +1 -1
  214. package/web/.next/server/chunks/ssr/{_48e5757d._.js → _e9a73a63._.js} +2 -2
  215. package/web/.next/server/chunks/ssr/_e9a73a63._.js.map +1 -0
  216. package/web/.next/server/chunks/ssr/_fa7efce3._.js +2 -2
  217. package/web/.next/server/chunks/ssr/_fa7efce3._.js.map +1 -1
  218. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  219. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  220. package/web/.next/server/chunks/ssr/node_modules__pnpm_ef15a0bd._.js +3 -0
  221. package/web/.next/server/chunks/ssr/node_modules__pnpm_ef15a0bd._.js.map +1 -0
  222. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_cdc632e3.js +1 -1
  223. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_cdc632e3.js.map +1 -1
  224. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_39ca0924.js +1 -1
  225. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_39ca0924.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  227. package/web/.next/server/chunks/ssr/src_presentation_web_components_357e3eb0._.js +1 -1
  228. package/web/.next/server/chunks/ssr/src_presentation_web_components_357e3eb0._.js.map +1 -1
  229. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  230. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  231. package/web/.next/server/pages/500.html +2 -2
  232. package/web/.next/server/server-reference-manifest.js +1 -1
  233. package/web/.next/server/server-reference-manifest.json +45 -45
  234. package/web/.next/static/chunks/{e51493c981deb9fd.js → 00ddf2682e26248f.js} +1 -1
  235. package/web/.next/static/chunks/{6a5c79587318fe1e.js → 0d07a524b56a91ae.js} +1 -1
  236. package/web/.next/static/chunks/{73b5be3394d27358.js → 3011d2b0e84898b9.js} +2 -2
  237. package/web/.next/static/chunks/{c80523e4d172cdea.js → 3d780d0c67e9c6d7.js} +2 -2
  238. package/web/.next/static/chunks/{9dd319c237b73197.js → 3f314c0cfed1a31f.js} +1 -1
  239. package/web/.next/static/chunks/{b546fac6810f555b.js → 4dcd3fddd166e847.js} +1 -1
  240. package/web/.next/static/chunks/{ce18a48f7d5d53c0.js → 6b96db4c6afb337c.js} +1 -1
  241. package/web/.next/static/chunks/8ba1c07ef18b15a9.js +1 -0
  242. package/web/.next/static/chunks/91ca5103e9d37ecf.js +7 -0
  243. package/web/.next/static/chunks/a919a9df4ab12a5c.css +1 -0
  244. package/web/.next/static/chunks/afc4212532319046.js +1 -0
  245. package/web/.next/static/chunks/{feed0046c419c228.js → b4cde06eff374c59.js} +3 -3
  246. package/web/.next/static/chunks/{ec7cd7e136a1b320.js → c9d93e106e541ea5.js} +1 -1
  247. package/web/.next/static/chunks/{0e73b25a355804a2.js → d1beeb17dc36ae56.js} +2 -2
  248. package/web/.next/static/chunks/{487a3d47f76ba2ce.js → dd72af4aa0e5a751.js} +1 -1
  249. package/web/.next/server/chunks/ssr/[root-of-the-server]__31f1c3b0._.js.map +0 -1
  250. package/web/.next/server/chunks/ssr/[root-of-the-server]__ede6df1f._.js +0 -3
  251. package/web/.next/server/chunks/ssr/[root-of-the-server]__ede6df1f._.js.map +0 -1
  252. package/web/.next/server/chunks/ssr/_48e5757d._.js.map +0 -1
  253. package/web/.next/server/chunks/ssr/_de71404e._.js +0 -3
  254. package/web/.next/static/chunks/16f6471485cbfed1.css +0 -1
  255. package/web/.next/static/chunks/476ebad4abb27ee8.js +0 -7
  256. package/web/.next/static/chunks/f0b1a5ded6ab6885.js +0 -1
  257. /package/web/.next/static/{VIJH9LQh8Ro1-nip3v-Am → Pz2jBHo89UcoWoV7z5vJp}/_buildManifest.js +0 -0
  258. /package/web/.next/static/{VIJH9LQh8Ro1-nip3v-Am → Pz2jBHo89UcoWoV7z5vJp}/_clientMiddlewareManifest.json +0 -0
  259. /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":"AA2CA,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,2CAsmBA"}
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: _jsx(Button, { variant: "ghost", size: "xs", "aria-label": "Open chat", "data-testid": "feature-node-chat-button", onClick: (e) => {
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();
@@ -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;AAOnE,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,2CA6bA"}
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: _jsx(Button, { variant: "ghost", size: "icon-xs", "aria-label": "Chat with agent", onClick: (e) => {
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":"AAiDA,wBAAgB,eAAe,4CAuX9B"}
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":"AAiBA,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;;;;;;;EA0P7B"}
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,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAkBzE,UAAU,aAAa;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAqGD,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,aAAa,2CAUhE"}
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
+ }