@shepai/cli 1.167.0 → 1.168.0

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