@shepai/cli 1.167.0 → 1.168.0-pr509.b1dd877

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 (479) hide show
  1. package/apis/json-schema/Feature.yaml +10 -0
  2. package/apis/json-schema/SkillInjectionConfig.yaml +17 -0
  3. package/apis/json-schema/SkillSource.yaml +21 -0
  4. package/apis/json-schema/SkillSourceType.yaml +7 -0
  5. package/apis/json-schema/WorkflowConfig.yaml +3 -0
  6. package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts +38 -2
  7. package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/ports/output/services/index.d.ts +1 -0
  9. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts +16 -1
  11. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts.map +1 -1
  12. package/dist/packages/core/src/application/ports/output/services/skill-injector.interface.d.ts +39 -0
  13. package/dist/packages/core/src/application/ports/output/services/skill-injector.interface.d.ts.map +1 -0
  14. package/dist/packages/core/src/application/ports/output/services/skill-injector.interface.js +8 -0
  15. package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.d.ts.map +1 -1
  16. package/dist/packages/core/src/application/use-cases/features/adopt-branch.use-case.js +1 -0
  17. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +3 -1
  18. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  19. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +22 -3
  20. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
  21. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  22. package/dist/packages/core/src/application/use-cases/interactive/index.d.ts +2 -0
  23. package/dist/packages/core/src/application/use-cases/interactive/index.d.ts.map +1 -1
  24. package/dist/packages/core/src/application/use-cases/interactive/index.js +1 -0
  25. package/dist/packages/core/src/application/use-cases/interactive/respond-to-interaction.use-case.d.ts +17 -0
  26. package/dist/packages/core/src/application/use-cases/interactive/respond-to-interaction.use-case.d.ts.map +1 -0
  27. package/dist/packages/core/src/application/use-cases/interactive/respond-to-interaction.use-case.js +34 -0
  28. package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.d.ts.map +1 -1
  29. package/dist/packages/core/src/application/use-cases/repositories/delete-repository.use-case.js +6 -2
  30. package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
  31. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +55 -1
  32. package/dist/packages/core/src/domain/generated/output.d.ts +50 -0
  33. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  34. package/dist/packages/core/src/domain/generated/output.js +5 -0
  35. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  36. package/dist/packages/core/src/infrastructure/di/container.js +7 -0
  37. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +2 -0
  38. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
  39. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +6 -0
  40. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +2 -0
  41. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  42. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +27 -0
  43. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/053-add-skill-injection-config.d.ts +15 -0
  44. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/053-add-skill-injection-config.d.ts.map +1 -0
  45. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/053-add-skill-injection-config.js +23 -0
  46. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/054-add-injected-skills-to-features.d.ts +11 -0
  47. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/054-add-injected-skills-to-features.d.ts.map +1 -0
  48. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/054-add-injected-skills-to-features.js +19 -0
  49. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
  50. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +8 -4
  51. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.d.ts +3 -0
  52. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.d.ts.map +1 -1
  53. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.js +59 -6
  54. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts +7 -0
  55. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts.map +1 -1
  56. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.js +101 -1
  57. package/dist/packages/core/src/infrastructure/services/skill-injector.service.d.ts +26 -0
  58. package/dist/packages/core/src/infrastructure/services/skill-injector.service.d.ts.map +1 -0
  59. package/dist/packages/core/src/infrastructure/services/skill-injector.service.js +201 -0
  60. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  61. package/dist/src/presentation/cli/commands/feat/new.command.js +3 -0
  62. package/dist/src/presentation/web/app/actions/add-injected-skill.d.ts +7 -0
  63. package/dist/src/presentation/web/app/actions/add-injected-skill.d.ts.map +1 -0
  64. package/dist/src/presentation/web/app/actions/add-injected-skill.js +34 -0
  65. package/dist/src/presentation/web/app/actions/create-feature.d.ts +2 -0
  66. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  67. package/dist/src/presentation/web/app/actions/create-feature.js +3 -1
  68. package/dist/src/presentation/web/app/actions/get-workflow-defaults.d.ts +1 -0
  69. package/dist/src/presentation/web/app/actions/get-workflow-defaults.d.ts.map +1 -1
  70. package/dist/src/presentation/web/app/actions/get-workflow-defaults.js +1 -0
  71. package/dist/src/presentation/web/app/actions/remove-injected-skill.d.ts +6 -0
  72. package/dist/src/presentation/web/app/actions/remove-injected-skill.d.ts.map +1 -0
  73. package/dist/src/presentation/web/app/actions/remove-injected-skill.js +35 -0
  74. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/respond/route.d.ts +19 -0
  75. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/respond/route.d.ts.map +1 -0
  76. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/respond/route.js +33 -0
  77. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.d.ts.map +1 -1
  78. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.js +7 -0
  79. package/dist/src/presentation/web/app/build-feature-node-data.d.ts.map +1 -1
  80. package/dist/src/presentation/web/app/build-feature-node-data.js +2 -0
  81. package/dist/src/presentation/web/app/layout.d.ts +0 -1
  82. package/dist/src/presentation/web/app/layout.d.ts.map +1 -1
  83. package/dist/src/presentation/web/app/layout.js +0 -1
  84. package/dist/src/presentation/web/app/skills/page.d.ts.map +1 -1
  85. package/dist/src/presentation/web/app/skills/page.js +6 -1
  86. package/dist/src/presentation/web/components/assistant-ui/thread.d.ts +3 -2
  87. package/dist/src/presentation/web/components/assistant-ui/thread.d.ts.map +1 -1
  88. package/dist/src/presentation/web/components/assistant-ui/thread.js +26 -3
  89. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +2 -0
  90. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  91. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +6 -2
  92. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  93. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +1 -0
  94. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +1 -1
  95. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +10 -4
  96. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +2 -0
  97. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +1 -1
  98. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +12 -0
  99. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +4 -0
  100. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  101. package/dist/src/presentation/web/components/common/react-file-manager-dialog/react-file-manager-dialog.d.ts.map +1 -1
  102. package/dist/src/presentation/web/components/common/react-file-manager-dialog/react-file-manager-dialog.js +68 -56
  103. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.d.ts +1 -0
  104. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.d.ts.map +1 -1
  105. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.js +7 -1
  106. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts +1 -0
  107. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.d.ts.map +1 -1
  108. package/dist/src/presentation/web/components/features/chat/ChatDotIndicator.stories.js +3 -0
  109. package/dist/src/presentation/web/components/features/chat/ChatSheet.d.ts.map +1 -1
  110. package/dist/src/presentation/web/components/features/chat/ChatSheet.js +3 -1
  111. package/dist/src/presentation/web/components/features/chat/ChatTab.d.ts.map +1 -1
  112. package/dist/src/presentation/web/components/features/chat/ChatTab.js +3 -2
  113. package/dist/src/presentation/web/components/features/chat/InteractionBubble.d.ts +33 -0
  114. package/dist/src/presentation/web/components/features/chat/InteractionBubble.d.ts.map +1 -0
  115. package/dist/src/presentation/web/components/features/chat/InteractionBubble.js +155 -0
  116. package/dist/src/presentation/web/components/features/chat/InteractionBubble.stories.d.ts +22 -0
  117. package/dist/src/presentation/web/components/features/chat/InteractionBubble.stories.d.ts.map +1 -0
  118. package/dist/src/presentation/web/components/features/chat/InteractionBubble.stories.js +107 -0
  119. package/dist/src/presentation/web/components/features/chat/useChatRuntime.d.ts +16 -0
  120. package/dist/src/presentation/web/components/features/chat/useChatRuntime.d.ts.map +1 -1
  121. package/dist/src/presentation/web/components/features/chat/useChatRuntime.js +62 -1
  122. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  123. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +18 -3
  124. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +1 -0
  125. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  126. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +1 -1
  127. package/dist/src/presentation/web/components/features/skills/add-skill-dialog.d.ts +10 -0
  128. package/dist/src/presentation/web/components/features/skills/add-skill-dialog.d.ts.map +1 -0
  129. package/dist/src/presentation/web/components/features/skills/add-skill-dialog.js +56 -0
  130. package/dist/src/presentation/web/components/features/skills/add-skill-dialog.stories.d.ts +16 -0
  131. package/dist/src/presentation/web/components/features/skills/add-skill-dialog.stories.d.ts.map +1 -0
  132. package/dist/src/presentation/web/components/features/skills/add-skill-dialog.stories.js +66 -0
  133. package/dist/src/presentation/web/components/features/skills/auto-injected-skills-section.d.ts +8 -0
  134. package/dist/src/presentation/web/components/features/skills/auto-injected-skills-section.d.ts.map +1 -0
  135. package/dist/src/presentation/web/components/features/skills/auto-injected-skills-section.js +42 -0
  136. package/dist/src/presentation/web/components/features/skills/auto-injected-skills-section.stories.d.ts +16 -0
  137. package/dist/src/presentation/web/components/features/skills/auto-injected-skills-section.stories.d.ts.map +1 -0
  138. package/dist/src/presentation/web/components/features/skills/auto-injected-skills-section.stories.js +69 -0
  139. package/dist/src/presentation/web/components/features/skills/skills-page-client.d.ts +3 -1
  140. package/dist/src/presentation/web/components/features/skills/skills-page-client.d.ts.map +1 -1
  141. package/dist/src/presentation/web/components/features/skills/skills-page-client.js +5 -3
  142. package/dist/src/presentation/web/components/features/skills/skills-page-client.stories.d.ts +1 -0
  143. package/dist/src/presentation/web/components/features/skills/skills-page-client.stories.d.ts.map +1 -1
  144. package/dist/src/presentation/web/components/features/skills/skills-page-client.stories.js +27 -0
  145. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
  146. package/dist/src/presentation/web/hooks/use-graph-state.js +16 -0
  147. package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts +1 -1
  148. package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts.map +1 -1
  149. package/dist/src/presentation/web/hooks/use-turn-statuses.js +1 -1
  150. package/dist/translations/ar/cli.json +2 -0
  151. package/dist/translations/ar/web.json +15 -11
  152. package/dist/translations/de/cli.json +2 -0
  153. package/dist/translations/de/web.json +35 -17
  154. package/dist/translations/en/cli.json +2 -0
  155. package/dist/translations/en/web.json +4 -0
  156. package/dist/translations/es/cli.json +2 -0
  157. package/dist/translations/es/web.json +16 -12
  158. package/dist/translations/fr/cli.json +2 -0
  159. package/dist/translations/fr/web.json +16 -12
  160. package/dist/translations/he/cli.json +2 -0
  161. package/dist/translations/he/web.json +16 -12
  162. package/dist/translations/pt/cli.json +2 -0
  163. package/dist/translations/pt/web.json +16 -12
  164. package/dist/translations/ru/cli.json +2 -0
  165. package/dist/translations/ru/web.json +16 -12
  166. package/dist/tsconfig.build.tsbuildinfo +1 -1
  167. package/package.json +1 -1
  168. package/web/.next/BUILD_ID +1 -1
  169. package/web/.next/app-path-routes-manifest.json +1 -0
  170. package/web/.next/build-manifest.json +7 -7
  171. package/web/.next/fallback-build-manifest.json +2 -2
  172. package/web/.next/prerender-manifest.json +3 -3
  173. package/web/.next/required-server-files.js +3 -3
  174. package/web/.next/required-server-files.json +3 -3
  175. package/web/.next/routes-manifest.json +8 -0
  176. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/build-manifest.json +5 -5
  177. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/react-loadable-manifest.json +1 -8
  178. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  179. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -1
  180. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  181. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  182. package/web/.next/server/app/(dashboard)/@drawer/chat/page/build-manifest.json +5 -5
  183. package/web/.next/server/app/(dashboard)/@drawer/chat/page/react-loadable-manifest.json +1 -8
  184. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  185. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +1 -1
  186. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  187. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  188. package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +5 -5
  189. package/web/.next/server/app/(dashboard)/@drawer/create/page/react-loadable-manifest.json +1 -8
  190. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
  191. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  192. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  193. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  194. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +5 -5
  195. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/react-loadable-manifest.json +1 -8
  196. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
  197. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
  198. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  199. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  200. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +5 -5
  201. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/react-loadable-manifest.json +1 -8
  202. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +38 -38
  203. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  204. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  205. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  206. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/build-manifest.json +5 -5
  207. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/react-loadable-manifest.json +1 -8
  208. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  209. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +1 -1
  210. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  211. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  212. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +5 -5
  213. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/react-loadable-manifest.json +1 -8
  214. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  215. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  216. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  217. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  218. package/web/.next/server/app/(dashboard)/chat/page/build-manifest.json +5 -5
  219. package/web/.next/server/app/(dashboard)/chat/page/react-loadable-manifest.json +1 -8
  220. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  221. package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
  222. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  223. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  224. package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +5 -5
  225. package/web/.next/server/app/(dashboard)/create/page/react-loadable-manifest.json +1 -8
  226. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
  227. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  228. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  229. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  230. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +5 -5
  231. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/react-loadable-manifest.json +1 -8
  232. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
  233. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
  234. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  235. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  236. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +5 -5
  237. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/react-loadable-manifest.json +1 -8
  238. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +38 -38
  239. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  240. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  241. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  242. package/web/.next/server/app/(dashboard)/page/build-manifest.json +5 -5
  243. package/web/.next/server/app/(dashboard)/page/react-loadable-manifest.json +1 -8
  244. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  245. package/web/.next/server/app/(dashboard)/page.js +1 -1
  246. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  247. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  248. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/build-manifest.json +5 -5
  249. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/react-loadable-manifest.json +1 -8
  250. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  251. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +1 -1
  252. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  253. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  254. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +5 -5
  255. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/react-loadable-manifest.json +1 -8
  256. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  257. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  258. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  259. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  260. package/web/.next/server/app/_global-error/page/build-manifest.json +5 -5
  261. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  262. package/web/.next/server/app/_global-error.html +2 -2
  263. package/web/.next/server/app/_global-error.rsc +7 -7
  264. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  265. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  266. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  267. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  268. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  269. package/web/.next/server/app/_not-found/page/build-manifest.json +5 -5
  270. package/web/.next/server/app/_not-found/page/react-loadable-manifest.json +1 -8
  271. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  272. package/web/.next/server/app/_not-found/page.js +1 -1
  273. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  274. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  275. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  276. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  277. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  278. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  279. package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route/app-paths-manifest.json +3 -0
  280. package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route/build-manifest.json +11 -0
  281. package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route/server-reference-manifest.json +4 -0
  282. package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route.js +7 -0
  283. package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route.js.map +5 -0
  284. package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route.js.nft.json +1 -0
  285. package/web/.next/server/app/api/interactive/chat/[featureId]/respond/route_client-reference-manifest.js +2 -0
  286. package/web/.next/server/app/settings/page/build-manifest.json +5 -5
  287. package/web/.next/server/app/settings/page/react-loadable-manifest.json +1 -8
  288. package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
  289. package/web/.next/server/app/settings/page.js +3 -3
  290. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  291. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  292. package/web/.next/server/app/skills/page/build-manifest.json +5 -5
  293. package/web/.next/server/app/skills/page/react-loadable-manifest.json +1 -8
  294. package/web/.next/server/app/skills/page/server-reference-manifest.json +52 -22
  295. package/web/.next/server/app/skills/page.js +3 -2
  296. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  297. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  298. package/web/.next/server/app/tools/page/build-manifest.json +5 -5
  299. package/web/.next/server/app/tools/page/react-loadable-manifest.json +1 -8
  300. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  301. package/web/.next/server/app/tools/page.js +1 -1
  302. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  303. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  304. package/web/.next/server/app/version/page/build-manifest.json +5 -5
  305. package/web/.next/server/app/version/page/react-loadable-manifest.json +1 -8
  306. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  307. package/web/.next/server/app/version/page.js +1 -1
  308. package/web/.next/server/app/version/page.js.nft.json +1 -1
  309. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  310. package/web/.next/server/app-paths-manifest.json +1 -0
  311. package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_[featureId]_respond_route_actions_990d51bd.js +3 -0
  312. package/web/.next/server/chunks/8ba4b_server_app_api_interactive_chat_[featureId]_respond_route_actions_990d51bd.js.map +1 -0
  313. package/web/.next/server/chunks/[root-of-the-server]__31944fa2._.js +3 -0
  314. package/web/.next/server/chunks/[root-of-the-server]__31944fa2._.js.map +1 -0
  315. package/web/.next/server/chunks/[root-of-the-server]__8a281f8d._.js +9 -3
  316. package/web/.next/server/chunks/[root-of-the-server]__8a281f8d._.js.map +1 -1
  317. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  318. package/web/.next/server/chunks/[root-of-the-server]__c78383b1._.js +1 -1
  319. package/web/.next/server/chunks/[root-of-the-server]__c78383b1._.js.map +1 -1
  320. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
  321. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  322. package/web/.next/server/chunks/ssr/{_0727935d._.js → 403f9_next_8a33ddee._.js} +2 -2
  323. package/web/.next/server/chunks/ssr/403f9_next_8a33ddee._.js.map +1 -0
  324. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  325. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  326. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +3 -3
  327. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  328. package/web/.next/server/chunks/ssr/{[root-of-the-server]__1abe77bb._.js → [root-of-the-server]__1b4846fd._.js} +3 -3
  329. package/web/.next/server/chunks/ssr/[root-of-the-server]__1b4846fd._.js.map +1 -0
  330. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
  331. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
  332. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  333. package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js +1 -1
  334. package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js.map +1 -1
  335. package/web/.next/server/chunks/ssr/[root-of-the-server]__7562afc6._.js +2 -2
  336. package/web/.next/server/chunks/ssr/[root-of-the-server]__7562afc6._.js.map +1 -1
  337. package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js +1 -1
  338. package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js.map +1 -1
  339. package/web/.next/server/chunks/ssr/{[root-of-the-server]__8b0aac03._.js → [root-of-the-server]__7ded596d._.js} +2 -2
  340. package/web/.next/server/chunks/ssr/[root-of-the-server]__7ded596d._.js.map +1 -0
  341. package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js +2 -2
  342. package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js.map +1 -1
  343. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
  344. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
  345. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js +1 -1
  346. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js.map +1 -1
  347. package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js +1 -1
  348. package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js.map +1 -1
  349. package/web/.next/server/chunks/ssr/[root-of-the-server]__e07df893._.js +3 -0
  350. package/web/.next/server/chunks/ssr/[root-of-the-server]__e07df893._.js.map +1 -0
  351. package/web/.next/server/chunks/ssr/_02e01240._.js +1 -1
  352. package/web/.next/server/chunks/ssr/_02e01240._.js.map +1 -1
  353. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  354. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  355. package/web/.next/server/chunks/ssr/_08e6a4c5._.js +3 -0
  356. package/web/.next/server/chunks/ssr/_08e6a4c5._.js.map +1 -0
  357. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  358. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  359. package/web/.next/server/chunks/ssr/_18886033._.js +1 -1
  360. package/web/.next/server/chunks/ssr/_18886033._.js.map +1 -1
  361. package/web/.next/server/chunks/ssr/_1e08a336._.js.map +1 -1
  362. package/web/.next/server/chunks/ssr/_22e00a14._.js +1 -1
  363. package/web/.next/server/chunks/ssr/_22e00a14._.js.map +1 -1
  364. package/web/.next/server/chunks/ssr/_45496654._.js +3 -0
  365. package/web/.next/server/chunks/ssr/_45496654._.js.map +1 -0
  366. package/web/.next/server/chunks/ssr/_4cbb7f95._.js +3 -0
  367. package/web/.next/server/chunks/ssr/_4cbb7f95._.js.map +1 -0
  368. package/web/.next/server/chunks/ssr/_5119a3df._.js.map +1 -1
  369. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  370. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  371. package/web/.next/server/chunks/ssr/{_a5913a26._.js → _79b66f37._.js} +2 -2
  372. package/web/.next/server/chunks/ssr/{_a5913a26._.js.map → _79b66f37._.js.map} +1 -1
  373. package/web/.next/server/chunks/ssr/{_b4c3ffcc._.js → _8b9129da._.js} +2 -2
  374. package/web/.next/server/chunks/ssr/{_b4c3ffcc._.js.map → _8b9129da._.js.map} +1 -1
  375. package/web/.next/server/chunks/ssr/_a5a5901d._.js +1 -1
  376. package/web/.next/server/chunks/ssr/_a5a5901d._.js.map +1 -1
  377. package/web/.next/server/chunks/ssr/_a963dd3c._.js +3 -0
  378. package/web/.next/server/chunks/ssr/_a963dd3c._.js.map +1 -0
  379. package/web/.next/server/chunks/ssr/_ad09f271._.js +1 -1
  380. package/web/.next/server/chunks/ssr/_ad09f271._.js.map +1 -1
  381. package/web/.next/server/chunks/ssr/_c3f595c6._.js +1 -1
  382. package/web/.next/server/chunks/ssr/_c3f595c6._.js.map +1 -1
  383. package/web/.next/server/chunks/ssr/_d78b2b6e._.js +3 -0
  384. package/web/.next/server/chunks/ssr/_d78b2b6e._.js.map +1 -0
  385. package/web/.next/server/chunks/ssr/_df737cce._.js +3 -0
  386. package/web/.next/server/chunks/ssr/_df737cce._.js.map +1 -0
  387. package/web/.next/server/chunks/ssr/_e3f14907._.js +9 -0
  388. package/web/.next/server/chunks/ssr/_e3f14907._.js.map +1 -0
  389. package/web/.next/server/chunks/ssr/_ea9e1556._.js +1 -1
  390. package/web/.next/server/chunks/ssr/_ea9e1556._.js.map +1 -1
  391. package/web/.next/server/chunks/ssr/_f1ba9be6._.js +2 -2
  392. package/web/.next/server/chunks/ssr/_f1ba9be6._.js.map +1 -1
  393. package/web/.next/server/chunks/ssr/_f33cd07e._.js +2 -2
  394. package/web/.next/server/chunks/ssr/_f33cd07e._.js.map +1 -1
  395. package/web/.next/server/chunks/ssr/_f8b45233._.js +1 -1
  396. package/web/.next/server/chunks/ssr/_f8b45233._.js.map +1 -1
  397. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  398. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  399. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
  400. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
  401. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  402. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
  403. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
  404. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  405. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  406. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +3 -0
  407. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -0
  408. package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_select_tsx_45d6b8ae._.js +1 -1
  409. package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_select_tsx_45d6b8ae._.js.map +1 -1
  410. package/web/.next/server/chunks/ssr/src_presentation_web_db9fa0c2._.js +1 -1
  411. package/web/.next/server/chunks/ssr/src_presentation_web_db9fa0c2._.js.map +1 -1
  412. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js +1 -1
  413. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js.map +1 -1
  414. package/web/.next/server/middleware-build-manifest.js +5 -5
  415. package/web/.next/server/pages/500.html +2 -2
  416. package/web/.next/server/server-reference-manifest.js +1 -1
  417. package/web/.next/server/server-reference-manifest.json +89 -59
  418. package/web/.next/static/chunks/0839854125212e6b.js +1 -0
  419. package/web/.next/static/chunks/{fe70e73feb07bcfd.js → 08ec4c9ab61717aa.js} +1 -1
  420. package/web/.next/static/chunks/{dedf6ca63c5468fa.js → 09edd35d194bec06.js} +3 -3
  421. package/web/.next/static/chunks/{d4d8f0a137bd2eb4.js → 12803afee7d0afc8.js} +2 -2
  422. package/web/.next/static/chunks/19680940c0bb3c3a.js +1 -0
  423. package/web/.next/static/chunks/{0be57768a211221a.js → 37a345c8f447ab56.js} +1 -1
  424. package/web/.next/static/chunks/3cbeac4d756302bc.js +5 -0
  425. package/web/.next/static/chunks/4355f7c193b01832.js +1 -0
  426. package/web/.next/static/chunks/{7a7d7e71cf9b5a4e.js → 4669ea9953c265d2.js} +1 -1
  427. package/web/.next/static/chunks/55e9df1e73af0b3e.js +7 -0
  428. package/web/.next/static/chunks/6deedc27548cd1df.js +1 -0
  429. package/web/.next/static/chunks/7b669373b268c12b.js +1 -0
  430. package/web/.next/static/chunks/7e22b815fb2a5b1b.js +3 -0
  431. package/web/.next/static/chunks/84a181ff3270fd9f.js +1 -0
  432. package/web/.next/static/chunks/89aac43287d73b02.js +1 -0
  433. package/web/.next/static/chunks/{d7eebb5c0aa9e101.js → a818bb026935d536.js} +2 -2
  434. package/web/.next/static/chunks/b2d1da8faf0da41d.js +1 -0
  435. package/web/.next/static/chunks/b7228e77a05ccbba.js +1 -0
  436. package/web/.next/static/chunks/ba251fd9b9fd254b.js +1 -0
  437. package/web/.next/static/chunks/c11bb4718643147f.js +5 -0
  438. package/web/.next/static/chunks/{3f404f608aebc7bb.js → d4a8e02e4be71dcf.js} +1 -1
  439. package/web/.next/static/chunks/f49e0076b62c6826.js +1 -0
  440. package/web/.next/static/chunks/fbff2864f22e8c88.css +1 -0
  441. package/web/.next/static/chunks/{turbopack-432ef324fc27240c.js → turbopack-9f7dcf06ca44886d.js} +1 -1
  442. package/web/.next/server/chunks/ssr/[root-of-the-server]__1abe77bb._.js.map +0 -1
  443. package/web/.next/server/chunks/ssr/[root-of-the-server]__2d0c3840._.js +0 -3
  444. package/web/.next/server/chunks/ssr/[root-of-the-server]__2d0c3840._.js.map +0 -1
  445. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js.map +0 -1
  446. package/web/.next/server/chunks/ssr/_0727935d._.js.map +0 -1
  447. package/web/.next/server/chunks/ssr/_0dc06d07._.js +0 -3
  448. package/web/.next/server/chunks/ssr/_0dc06d07._.js.map +0 -1
  449. package/web/.next/server/chunks/ssr/_3bcda5d7._.js +0 -3
  450. package/web/.next/server/chunks/ssr/_3bcda5d7._.js.map +0 -1
  451. package/web/.next/server/chunks/ssr/_4d49a312._.js +0 -3
  452. package/web/.next/server/chunks/ssr/_4d49a312._.js.map +0 -1
  453. package/web/.next/server/chunks/ssr/_506a3bc3._.js +0 -9
  454. package/web/.next/server/chunks/ssr/_506a3bc3._.js.map +0 -1
  455. package/web/.next/server/chunks/ssr/_5ab8e97d._.js +0 -3
  456. package/web/.next/server/chunks/ssr/_5ab8e97d._.js.map +0 -1
  457. package/web/.next/server/chunks/ssr/_9215e9ec._.js +0 -3
  458. package/web/.next/server/chunks/ssr/_9215e9ec._.js.map +0 -1
  459. package/web/.next/static/chunks/16eea21868510afd.js +0 -5
  460. package/web/.next/static/chunks/3208dc997aaee4d3.css +0 -1
  461. package/web/.next/static/chunks/3deefc76ea55047c.js +0 -1
  462. package/web/.next/static/chunks/40b6bcf1a2de4a0f.js +0 -1
  463. package/web/.next/static/chunks/420eb8b33d83c4cb.js +0 -1
  464. package/web/.next/static/chunks/63b0ad1dbc27a5d0.js +0 -1
  465. package/web/.next/static/chunks/65440524d7ee7d13.js +0 -1
  466. package/web/.next/static/chunks/6c634b447a6a0db8.js +0 -7
  467. package/web/.next/static/chunks/6d7b999c99d6d175.js +0 -9
  468. package/web/.next/static/chunks/6eb32cd5d2795a7c.js +0 -1
  469. package/web/.next/static/chunks/7f4d1ec4e9f921a3.js +0 -1
  470. package/web/.next/static/chunks/8180973e9cd6a99e.css +0 -1
  471. package/web/.next/static/chunks/8866edda931a81c2.js +0 -1
  472. package/web/.next/static/chunks/c0e13e7d1601bc5d.js +0 -1
  473. package/web/.next/static/chunks/c7e793951b20a67f.js +0 -1
  474. package/web/.next/static/chunks/d6a1facd04a52af5.js +0 -5
  475. package/web/.next/static/chunks/da6d0839a24602eb.js +0 -3
  476. package/web/.next/static/chunks/db3bf9eb0b519bae.js +0 -1
  477. /package/web/.next/static/{JjjyVzk5ESdcMWkH6999z → QTub9VF21lk2PO7IJDkNp}/_buildManifest.js +0 -0
  478. /package/web/.next/static/{JjjyVzk5ESdcMWkH6999z → QTub9VF21lk2PO7IJDkNp}/_clientMiddlewareManifest.json +0 -0
  479. /package/web/.next/static/{JjjyVzk5ESdcMWkH6999z → QTub9VF21lk2PO7IJDkNp}/_ssgManifest.js +0 -0
@@ -1,29 +1,11 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useRef, useState } from 'react';
4
- import dynamic from 'next/dynamic';
5
- import { Loader2 } from 'lucide-react';
4
+ import { ChevronRight, Folder, FolderOpen, Loader2, Pencil } from 'lucide-react';
6
5
  import { toast } from 'sonner';
7
- import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
6
+ import { Dialog, DialogContent, DialogDescription, DialogTitle } from '../../ui/dialog.js';
8
7
  import { Button } from '../../ui/button.js';
9
- const FileManager = dynamic(() => import('@cubone/react-file-manager').then((mod) => mod.FileManager), { ssr: false, loading: () => _jsx(FileManagerSkeleton, {}) });
10
- function FileManagerSkeleton() {
11
- return (_jsx("div", { className: "flex h-full w-full items-center justify-center", children: _jsx(Loader2, { className: "text-muted-foreground h-8 w-8 animate-spin" }) }));
12
- }
13
- function toFileManagerFiles(entries) {
14
- // The @cubone/react-file-manager component filters visible files by matching
15
- // file.path === currentPath + "/" + file.name. Since we dynamically fetch
16
- // directory contents on each navigation, we present all entries at the
17
- // FileManager's root level by using path = "/" + name. The real absolute
18
- // path is preserved in a custom `absolutePath` field for selection/navigation.
19
- return entries.map((entry) => ({
20
- name: entry.name,
21
- isDirectory: true,
22
- path: `/${entry.name}`,
23
- absolutePath: entry.path,
24
- updatedAt: entry.updatedAt,
25
- }));
26
- }
8
+ import { ScrollArea } from '../../ui/scroll-area.js';
27
9
  async function fetchDirectory(dirPath) {
28
10
  const params = new URLSearchParams();
29
11
  if (dirPath) {
@@ -36,19 +18,76 @@ async function fetchDirectory(dirPath) {
36
18
  }
37
19
  return res.json();
38
20
  }
21
+ function parseBreadcrumbs(currentPath) {
22
+ if (!currentPath)
23
+ return [];
24
+ const isWindows = /^[a-zA-Z]:/.test(currentPath);
25
+ const separator = isWindows ? '\\' : '/';
26
+ const parts = currentPath.split(/[\\/]/).filter(Boolean);
27
+ const crumbs = [];
28
+ for (let i = 0; i < parts.length; i++) {
29
+ const path = isWindows
30
+ ? parts.slice(0, i + 1).join(separator)
31
+ : separator + parts.slice(0, i + 1).join(separator);
32
+ crumbs.push({ label: parts[i], path });
33
+ }
34
+ return crumbs;
35
+ }
36
+ const MAX_VISIBLE_CRUMBS = 3;
37
+ function AddressBar({ currentPath, isEditing, onToggleEdit, onNavigate, }) {
38
+ const inputRef = useRef(null);
39
+ const [inputValue, setInputValue] = useState(currentPath);
40
+ useEffect(() => {
41
+ setInputValue(currentPath);
42
+ }, [currentPath]);
43
+ useEffect(() => {
44
+ if (isEditing && inputRef.current) {
45
+ inputRef.current.focus();
46
+ inputRef.current.select();
47
+ }
48
+ }, [isEditing]);
49
+ function handleSubmit() {
50
+ const trimmed = inputValue.trim();
51
+ if (trimmed) {
52
+ onNavigate(trimmed);
53
+ }
54
+ }
55
+ function closeEdit() {
56
+ setInputValue(currentPath);
57
+ onToggleEdit();
58
+ }
59
+ const breadcrumbs = parseBreadcrumbs(currentPath);
60
+ const needsCollapse = breadcrumbs.length > MAX_VISIBLE_CRUMBS;
61
+ const visibleCrumbs = needsCollapse ? breadcrumbs.slice(-MAX_VISIBLE_CRUMBS) : breadcrumbs;
62
+ return (_jsxs("div", { className: "border-b px-4 py-3", children: [_jsx("h2", { className: "text-foreground mb-2.5 text-sm font-semibold tracking-[-0.01em]", children: "Select Folder" }), isEditing ? (_jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), onKeyDown: (e) => {
63
+ if (e.key === 'Enter') {
64
+ e.preventDefault();
65
+ handleSubmit();
66
+ }
67
+ if (e.key === 'Escape') {
68
+ e.preventDefault();
69
+ closeEdit();
70
+ }
71
+ }, onBlur: closeEdit, className: "bg-muted/60 border-border focus:ring-ring/20 focus:border-ring w-full rounded-lg border px-3 py-2 font-mono text-xs transition-all outline-none focus:ring-2", placeholder: "Type a path and press Enter...", spellCheck: false, autoComplete: "off" })) : (_jsxs("div", { className: "bg-muted/40 flex items-center gap-1 rounded-lg px-2.5 py-2", children: [_jsx("button", { type: "button", onClick: () => onNavigate('/'), className: "text-muted-foreground hover:text-foreground hover:bg-background shrink-0 rounded px-1.5 py-0.5 font-mono text-xs transition-colors", children: "/" }), needsCollapse ? (_jsxs(_Fragment, { children: [_jsx(ChevronRight, { className: "text-muted-foreground/30 h-3 w-3 shrink-0" }), _jsx("span", { className: "text-muted-foreground/40 font-mono text-xs", children: "..." })] })) : null, visibleCrumbs.map((crumb, i) => {
72
+ const isLast = i === visibleCrumbs.length - 1;
73
+ return (_jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [_jsx(ChevronRight, { className: "text-muted-foreground/30 h-3 w-3" }), isLast ? (_jsx("span", { className: "bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-medium", children: crumb.label })) : (_jsx("button", { type: "button", onClick: () => onNavigate(crumb.path), className: "text-muted-foreground hover:text-foreground hover:bg-background rounded px-1.5 py-0.5 font-mono text-xs transition-colors", children: crumb.label }))] }, crumb.path));
74
+ }), _jsx("div", { className: "flex-1" }), _jsx("button", { type: "button", onClick: onToggleEdit, className: "text-muted-foreground/40 hover:text-foreground hover:bg-background shrink-0 rounded p-1 transition-colors", "aria-label": "Edit path", children: _jsx(Pencil, { className: "h-3 w-3" }) })] }))] }));
75
+ }
39
76
  export function ReactFileManagerDialog({ open, onOpenChange, onSelect, initialPath, }) {
40
77
  const [entries, setEntries] = useState([]);
41
78
  const [currentPath, setCurrentPath] = useState('');
42
79
  const [isLoading, setIsLoading] = useState(false);
43
- const [selectedPath, setSelectedPath] = useState(null);
80
+ const [isEditingPath, setIsEditingPath] = useState(false);
44
81
  const hasLoadedRef = useRef(false);
82
+ const [renderKey, setRenderKey] = useState(0);
45
83
  const loadDirectory = useCallback(async (dirPath) => {
46
84
  setIsLoading(true);
47
- setSelectedPath(null);
85
+ setIsEditingPath(false);
48
86
  try {
49
87
  const data = await fetchDirectory(dirPath);
50
88
  setEntries(data.entries);
51
89
  setCurrentPath(data.currentPath);
90
+ setRenderKey((k) => k + 1);
52
91
  }
53
92
  catch (error) {
54
93
  const message = error instanceof Error ? error.message : 'Failed to load directory';
@@ -65,32 +104,13 @@ export function ReactFileManagerDialog({ open, onOpenChange, onSelect, initialPa
65
104
  }
66
105
  if (!open) {
67
106
  hasLoadedRef.current = false;
107
+ setIsEditingPath(false);
68
108
  }
69
109
  }, [open, initialPath, loadDirectory]);
70
- const handleFileOpen = useCallback((file) => {
71
- // Use absolutePath (real filesystem path) for navigation, not the
72
- // virtual path used by the FileManager tree.
73
- const realPath = file.absolutePath;
74
- if (file.isDirectory && realPath) {
75
- loadDirectory(realPath);
76
- }
77
- }, [loadDirectory]);
78
- const handleSelectionChange = useCallback((files) => {
79
- if (files.length === 1 && files[0].isDirectory) {
80
- const realPath = files[0].absolutePath;
81
- setSelectedPath(realPath ?? null);
82
- }
83
- else {
84
- setSelectedPath(null);
85
- }
86
- }, []);
87
- function handleSelect() {
88
- if (selectedPath) {
89
- onSelect(selectedPath);
90
- onOpenChange(false);
91
- }
110
+ function handleNavigate(path) {
111
+ loadDirectory(path);
92
112
  }
93
- function handleSelectCurrentPath() {
113
+ function handleSelect() {
94
114
  if (currentPath) {
95
115
  onSelect(currentPath);
96
116
  onOpenChange(false);
@@ -104,13 +124,5 @@ export function ReactFileManagerDialog({ open, onOpenChange, onSelect, initialPa
104
124
  if (!isOpen) {
105
125
  handleCancel();
106
126
  }
107
- }, children: _jsxs(DialogContent, { className: "flex h-[95dvh] max-w-[95vw] flex-col", onCloseAutoFocus: (e) => e.preventDefault(), children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Select Folder" }), _jsx(DialogDescription, { className: "truncate font-mono text-xs", children: currentPath || 'Loading...' })] }), _jsx("div", { className: "shep-file-manager min-h-0 flex-1 overflow-hidden rounded-md border", children: _jsx(FileManager, { files: toFileManagerFiles(entries), isLoading: isLoading, height: "100%", width: "100%", layout: "list", enableFilePreview: false, permissions: {
108
- upload: false,
109
- delete: false,
110
- create: false,
111
- download: false,
112
- copy: false,
113
- move: false,
114
- rename: false,
115
- }, onFileOpen: handleFileOpen, onSelectionChange: handleSelectionChange, onRefresh: () => loadDirectory(currentPath) }, currentPath) }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: handleCancel, children: "Cancel" }), _jsx(Button, { variant: "secondary", onClick: handleSelectCurrentPath, disabled: !currentPath, children: "Select Current Folder" }), _jsx(Button, { onClick: handleSelect, disabled: !selectedPath, children: "Select Folder" })] })] }) }));
127
+ }, children: _jsxs(DialogContent, { className: "flex h-[min(520px,85dvh)] w-full max-w-[460px] flex-col gap-0 overflow-hidden p-0", onCloseAutoFocus: (e) => e.preventDefault(), children: [_jsx(DialogTitle, { className: "sr-only", children: "Select Folder" }), _jsx(DialogDescription, { className: "sr-only", children: "Navigate to a folder and select it" }), _jsx(AddressBar, { currentPath: currentPath, isEditing: isEditingPath, onToggleEdit: () => setIsEditingPath((v) => !v), onNavigate: handleNavigate }), _jsx(ScrollArea, { className: "min-h-0 flex-1", children: isLoading && entries.length === 0 ? (_jsx("div", { className: "space-y-0.5 p-2", children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "flex items-center gap-3 rounded-lg px-3 py-2.5", style: { opacity: 1 - i * 0.1 }, children: [_jsx("div", { className: "bg-muted h-4 w-4 animate-pulse rounded" }), _jsx("div", { className: "bg-muted h-3.5 animate-pulse rounded", style: { width: `${40 + Math.random() * 35}%` } })] }, `skeleton-${i}`))) })) : entries.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-20", children: [_jsx(FolderOpen, { className: "text-muted-foreground/25 mb-3 h-10 w-10" }), _jsx("p", { className: "text-muted-foreground/60 text-sm", children: "Empty folder" })] })) : (_jsx("div", { className: "p-2", children: entries.map((entry, i) => (_jsxs("button", { type: "button", onClick: () => handleNavigate(entry.path), className: "folder-row group flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-all hover:bg-[var(--color-primary)]/[0.06] active:scale-[0.997]", style: { animationDelay: `${i * 20}ms` }, children: [_jsx(Folder, { className: "text-muted-foreground/50 group-hover:text-primary h-[18px] w-[18px] shrink-0 transition-colors" }), _jsx("span", { className: "text-foreground min-w-0 flex-1 truncate text-[13px] font-medium", children: entry.name }), _jsx(ChevronRight, { className: "text-muted-foreground/0 group-hover:text-muted-foreground/40 h-3.5 w-3.5 shrink-0 transition-all" })] }, entry.path))) }, renderKey)) }), _jsxs("div", { className: "flex items-center gap-2 border-t px-4 py-3", children: [_jsx("p", { className: "text-muted-foreground min-w-0 flex-1 truncate font-mono text-[11px] leading-none", children: currentPath || '\u00A0' }), _jsx(Button, { variant: "ghost", size: "sm", onClick: handleCancel, className: "text-muted-foreground h-8 shrink-0 px-3 text-xs", children: "Cancel" }), _jsxs(Button, { size: "sm", onClick: handleSelect, disabled: !currentPath || isLoading, className: "h-8 shrink-0 px-5 text-xs font-medium", children: [isLoading ? _jsx(Loader2, { className: "mr-1.5 h-3 w-3 animate-spin" }) : null, "Select"] })] })] }) }));
116
128
  }
@@ -8,6 +8,7 @@ interface ChatDotIndicatorProps {
8
8
  * - idle: no dot (hidden)
9
9
  * - processing: pulsing blue dot
10
10
  * - unread: static green dot
11
+ * - awaiting_input: pulsing amber dot (agent needs user response)
11
12
  */
12
13
  export declare function ChatDotIndicator({ status, className }: ChatDotIndicatorProps): import("react/jsx-runtime").JSX.Element | null;
13
14
  export {};
@@ -1 +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"}
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;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,SAAc,EAAE,EAAE,qBAAqB,kDAajF"}
@@ -5,9 +5,15 @@ import { jsx as _jsx } from "react/jsx-runtime";
5
5
  * - idle: no dot (hidden)
6
6
  * - processing: pulsing blue dot
7
7
  * - unread: static green dot
8
+ * - awaiting_input: pulsing amber dot (agent needs user response)
8
9
  */
9
10
  export function ChatDotIndicator({ status, className = '' }) {
10
11
  if (status === 'idle')
11
12
  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
+ const dotClass = status === 'awaiting_input'
14
+ ? 'h-2.5 w-2.5 animate-pulse bg-amber-500'
15
+ : status === 'processing'
16
+ ? 'h-2.5 w-2.5 animate-pulse bg-blue-500'
17
+ : 'h-2 w-2 bg-green-500';
18
+ return (_jsx("span", { className: `absolute -top-0.5 -right-0.5 block rounded-full ${dotClass} ${className}` }));
13
19
  }
@@ -6,4 +6,5 @@ type Story = StoryObj<typeof ChatDotIndicator>;
6
6
  export declare const Idle: Story;
7
7
  export declare const Processing: Story;
8
8
  export declare const Unread: Story;
9
+ export declare const AwaitingInput: Story;
9
10
  //# sourceMappingURL=ChatDotIndicator.stories.d.ts.map
@@ -1 +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"}
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;AAEF,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC"}
@@ -17,3 +17,6 @@ export const Processing = {
17
17
  export const Unread = {
18
18
  args: { status: 'unread' },
19
19
  };
20
+ export const AwaitingInput = {
21
+ args: { status: 'awaiting_input' },
22
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"ChatSheet.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatSheet.tsx"],"names":[],"mappings":"AA2DA,wBAAgB,eAAe,4CAwY9B"}
1
+ {"version":3,"file":"ChatSheet.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatSheet.tsx"],"names":[],"mappings":"AA2DA,wBAAgB,eAAe,4CA4Y9B"}
@@ -261,7 +261,9 @@ export function GlobalChatPopup() {
261
261
  document.addEventListener('mouseup', onUp);
262
262
  }, className: "absolute end-0 bottom-0 z-10 h-4 w-4 cursor-se-resize" })) : null] })) : null, _jsxs(ChatFabWrapper, { swapPosition: swapPosition, sidebarState: sidebarState, isMaximized: isMaximized, 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
263
263
  ? 'bg-violet-600 text-white hover:bg-violet-500'
264
- : '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: "end-0 top-0" })] }), _jsx("div", { className: "pointer-events-none absolute bottom-[calc(100%+8px)] left-1/2 -translate-x-1/2 translate-y-1 opacity-0 transition-all duration-200 group-hover/fab:translate-y-0 group-hover/fab:opacity-100", children: _jsxs("div", { className: "bg-foreground rounded-lg px-3 py-1.5 text-center shadow-lg", children: [_jsx("p", { className: "text-background text-xs font-medium whitespace-nowrap", children: t('chat.shepChat') }), _jsxs("p", { className: "text-background/50 mt-0.5 flex items-center justify-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" })] })] }) })] })] }));
264
+ : 'bg-violet-500 text-white hover:bg-violet-400 dark:bg-violet-500 dark:hover:bg-violet-400',
265
+ // Animated states when chat is closed
266
+ !isOpen && globalChatTurnStatus === 'processing' && 'chat-fab-spinning', !isOpen && globalChatTurnStatus === 'unread' && 'chat-fab-glow-unread', !isOpen && globalChatTurnStatus === 'awaiting_input' && 'chat-fab-glow-awaiting'), 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: "end-0 top-0" })] }), _jsx("div", { className: "pointer-events-none absolute bottom-[calc(100%+8px)] left-1/2 -translate-x-1/2 translate-y-1 opacity-0 transition-all duration-200 group-hover/fab:translate-y-0 group-hover/fab:opacity-100", children: _jsxs("div", { className: "bg-foreground rounded-lg px-3 py-1.5 text-center shadow-lg", children: [_jsx("p", { className: "text-background text-xs font-medium whitespace-nowrap", children: t('chat.shepChat') }), _jsxs("p", { className: "text-background/50 mt-0.5 flex items-center justify-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" })] })] }) })] })] }));
265
267
  }
266
268
  /** Wrapper for the Chat FAB that handles position swapping. */
267
269
  function ChatFabWrapper({ swapPosition, sidebarState, isMaximized, children, }) {
@@ -1 +1 @@
1
- {"version":3,"file":"ChatTab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatTab.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,wBAAgB,OAAO,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,YAAY,2CAwGhE"}
1
+ {"version":3,"file":"ChatTab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatTab.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,wBAAgB,OAAO,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,YAAY,2CAsHhE"}
@@ -11,6 +11,7 @@ import { composeUserInput } from '../../../app/actions/compose-user-input.js';
11
11
  import { AgentModelPicker } from '../../features/settings/AgentModelPicker/index.js';
12
12
  import { useChatRuntime } from './useChatRuntime.js';
13
13
  import { ChatComposer } from './ChatComposer.js';
14
+ import { InteractionBubble } from './InteractionBubble.js';
14
15
  const IS_DEV = process.env.NODE_ENV === 'development';
15
16
  export function ChatTab({ featureId, worktreePath }) {
16
17
  const [overrideAgent, setOverrideAgent] = useState(undefined);
@@ -18,7 +19,7 @@ export function ChatTab({ featureId, worktreePath }) {
18
19
  const [debugMode, setDebugMode] = useState(false);
19
20
  const att = useAttachments();
20
21
  const contentTransform = useCallback((content) => composeUserInput(content, att.completedAttachments.map((a) => ({ path: a.path, name: a.name, notes: a.notes }))), [att.completedAttachments]);
21
- const { runtime, status, clearChat, sessionInfo, isChatLoading } = useChatRuntime(featureId, worktreePath, {
22
+ const { runtime, status, clearChat, sessionInfo, isChatLoading, pendingInteraction, respondToInteraction, } = useChatRuntime(featureId, worktreePath, {
22
23
  contentTransform,
23
24
  onMessageSent: att.clearAttachments,
24
25
  model: overrideModel,
@@ -54,7 +55,7 @@ export function ChatTab({ featureId, worktreePath }) {
54
55
  setOverrideAgent(agent);
55
56
  setOverrideModel(model);
56
57
  }, className: "w-55" }) }));
57
- return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsx(ChatHeader, { sessionInfo: sessionInfo, isAgentActive: status.isRunning, onClear: clearChat, debugMode: debugMode, onDebugToggle: IS_DEV ? setDebugMode : undefined }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: isChatLoading ? (_jsx(ChatSkeleton, {})) : (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(Thread, { composer: composer }) })) })] }));
58
+ return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsx(ChatHeader, { sessionInfo: sessionInfo, isAgentActive: status.isRunning, onClear: clearChat, debugMode: debugMode, onDebugToggle: IS_DEV ? setDebugMode : undefined }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: isChatLoading ? (_jsx(ChatSkeleton, {})) : (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(Thread, { composer: composer, afterMessages: pendingInteraction ? (_jsx(InteractionBubble, { interaction: pendingInteraction, onSubmit: respondToInteraction })) : undefined }) })) })] }));
58
59
  }
59
60
  // ── Loading skeleton ────────────────────────────────────────────────────────
60
61
  function ChatSkeleton() {
@@ -0,0 +1,33 @@
1
+ /** Shape matching UserQuestion from the agent executor interface. */
2
+ interface QuestionOption {
3
+ label: string;
4
+ description: string;
5
+ preview?: string;
6
+ }
7
+ interface Question {
8
+ question: string;
9
+ header: string;
10
+ options: QuestionOption[];
11
+ multiSelect: boolean;
12
+ }
13
+ export interface InteractionData {
14
+ toolCallId: string;
15
+ questions: Question[];
16
+ }
17
+ export interface InteractionBubbleProps {
18
+ interaction: InteractionData;
19
+ onSubmit: (answers: Record<string, string>) => void;
20
+ className?: string;
21
+ }
22
+ /**
23
+ * Renders an agent's AskUserQuestion interaction inline in the chat thread.
24
+ *
25
+ * - Single question: renders options directly
26
+ * - Multiple questions: tabbed interface with header chips as tabs
27
+ *
28
+ * After submission, the bubble disappears and a green summary message
29
+ * is persisted in the conversation history (rendered by InteractionResponseMessage in thread.tsx).
30
+ */
31
+ export declare function InteractionBubble({ interaction, onSubmit, className }: InteractionBubbleProps): import("react/jsx-runtime").JSX.Element;
32
+ export {};
33
+ //# sourceMappingURL=InteractionBubble.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InteractionBubble.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/InteractionBubble.tsx"],"names":[],"mappings":"AAMA,qEAAqE;AACrE,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,QAAQ;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,sBAAsB,2CAsB7F"}
@@ -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
+ };