@shepai/cli 1.163.0 → 1.164.0-pr514.db33061

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 (311) hide show
  1. package/README.md +12 -0
  2. package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts +3 -1
  3. package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.d.ts +19 -0
  5. package/dist/packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.d.ts.map +1 -1
  6. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts +7 -1
  7. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/use-cases/interactive/send-interactive-message.use-case.d.ts +2 -0
  9. package/dist/packages/core/src/application/use-cases/interactive/send-interactive-message.use-case.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/use-cases/interactive/send-interactive-message.use-case.js +1 -1
  11. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/051-add-session-usage-tracking.d.ts +18 -0
  12. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/051-add-session-usage-tracking.d.ts.map +1 -0
  13. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/051-add-session-usage-tracking.js +32 -0
  14. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts +12 -0
  15. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts.map +1 -1
  16. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.js +31 -0
  17. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.d.ts +38 -7
  18. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.d.ts.map +1 -1
  19. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.js +152 -45
  20. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts +17 -1
  21. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts.map +1 -1
  22. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.js +131 -47
  23. package/dist/src/presentation/web/app/actions/get-git-log.d.ts +44 -0
  24. package/dist/src/presentation/web/app/actions/get-git-log.d.ts.map +1 -0
  25. package/dist/src/presentation/web/app/actions/get-git-log.js +125 -0
  26. package/dist/src/presentation/web/app/actions/open-folder.d.ts.map +1 -1
  27. package/dist/src/presentation/web/app/actions/open-folder.js +5 -2
  28. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/messages/route.d.ts.map +1 -1
  29. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/messages/route.js +3 -1
  30. package/dist/src/presentation/web/components/assistant-ui/thread.js +8 -1
  31. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +1 -1
  32. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  33. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +46 -15
  34. package/dist/src/presentation/web/components/common/control-center-drawer/repository-drawer-client.d.ts.map +1 -1
  35. package/dist/src/presentation/web/components/common/control-center-drawer/repository-drawer-client.js +77 -5
  36. package/dist/src/presentation/web/components/common/control-center-drawer/use-drawer-sync.d.ts.map +1 -1
  37. package/dist/src/presentation/web/components/common/control-center-drawer/use-drawer-sync.js +11 -0
  38. package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.d.ts.map +1 -1
  39. package/dist/src/presentation/web/components/common/deployment-status-badge/deployment-status-badge.js +10 -9
  40. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts +5 -1
  41. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
  42. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +24 -13
  43. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +1 -1
  44. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +56 -81
  45. package/dist/src/presentation/web/components/common/open-action-menu/open-action-menu.d.ts.map +1 -1
  46. package/dist/src/presentation/web/components/common/open-action-menu/open-action-menu.js +11 -6
  47. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  48. package/dist/src/presentation/web/components/features/chat/ChatTab.d.ts.map +1 -1
  49. package/dist/src/presentation/web/components/features/chat/ChatTab.js +13 -7
  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 +98 -7
  53. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts.map +1 -1
  54. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.js +1 -1
  55. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  56. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +7 -2
  57. package/dist/src/presentation/web/hooks/use-animations-enabled.d.ts +6 -0
  58. package/dist/src/presentation/web/hooks/use-animations-enabled.d.ts.map +1 -0
  59. package/dist/src/presentation/web/hooks/use-animations-enabled.js +30 -0
  60. package/dist/tsconfig.build.tsbuildinfo +1 -1
  61. package/package.json +2 -2
  62. package/web/.next/BUILD_ID +1 -1
  63. package/web/.next/build-manifest.json +2 -2
  64. package/web/.next/fallback-build-manifest.json +2 -2
  65. package/web/.next/prerender-manifest.json +3 -3
  66. package/web/.next/required-server-files.js +3 -3
  67. package/web/.next/required-server-files.json +3 -3
  68. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  69. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  70. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  71. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  72. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  73. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  74. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
  75. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  76. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  77. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  78. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  79. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  80. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +37 -37
  81. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  82. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  83. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +69 -54
  84. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +1 -1
  85. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  86. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  87. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +69 -54
  88. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  89. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  90. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  91. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  92. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  93. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  94. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
  95. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  96. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  97. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  98. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  99. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  100. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +37 -37
  101. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  102. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  103. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  104. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  105. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  106. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +69 -54
  107. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +1 -1
  108. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  109. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  110. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +69 -54
  111. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  112. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  113. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  114. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  115. package/web/.next/server/app/_global-error.html +2 -2
  116. package/web/.next/server/app/_global-error.rsc +1 -1
  117. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  118. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  119. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  120. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  121. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  122. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  123. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  124. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  125. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  126. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  127. package/web/.next/server/app/api/graph-data/route.js +1 -1
  128. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  129. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  130. package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
  131. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  132. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  133. package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
  134. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  135. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  136. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  137. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  138. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  139. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  140. package/web/.next/server/app/version/page.js.nft.json +1 -1
  141. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  142. package/web/.next/server/chunks/[root-of-the-server]__2b71641f._.js +1 -1
  143. package/web/.next/server/chunks/[root-of-the-server]__2b71641f._.js.map +1 -1
  144. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  145. package/web/.next/server/chunks/{[root-of-the-server]__beda892a._.js → [root-of-the-server]__c78383b1._.js} +2 -2
  146. package/web/.next/server/chunks/{[root-of-the-server]__beda892a._.js.map → [root-of-the-server]__c78383b1._.js.map} +1 -1
  147. package/web/.next/server/chunks/ssr/403f9_next_dist_esm_ceb2fa1e._.js +1 -1
  148. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  149. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  150. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +3 -3
  151. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  152. package/web/.next/server/chunks/ssr/{7f428_lucide-react_dist_esm_icons_4b319ae6._.js → 7f428_lucide-react_dist_esm_icons_281e0ef8._.js} +2 -2
  153. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_281e0ef8._.js.map +1 -0
  154. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_a593f310._.js +3 -0
  155. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_a593f310._.js.map +1 -0
  156. package/web/.next/server/chunks/ssr/[root-of-the-server]__1abe77bb._.js +2 -2
  157. package/web/.next/server/chunks/ssr/[root-of-the-server]__1abe77bb._.js.map +1 -1
  158. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
  159. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
  160. package/web/.next/server/chunks/ssr/[root-of-the-server]__23b5ca2c._.js +1 -1
  161. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  162. package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js +1 -1
  163. package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js.map +1 -1
  164. package/web/.next/server/chunks/ssr/[root-of-the-server]__7528eb6f._.js +1 -1
  165. package/web/.next/server/chunks/ssr/[root-of-the-server]__7562afc6._.js +2 -2
  166. package/web/.next/server/chunks/ssr/[root-of-the-server]__7562afc6._.js.map +1 -1
  167. package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js +1 -1
  168. package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js.map +1 -1
  169. package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js +7 -0
  170. package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js.map +1 -0
  171. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js +1 -1
  172. package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js +1 -1
  173. package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js.map +1 -1
  174. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
  175. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
  176. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js +1 -1
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9777776._.js +1 -1
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9777776._.js.map +1 -1
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__e0be67c7._.js +3 -0
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__e0be67c7._.js.map +1 -0
  182. package/web/.next/server/chunks/ssr/{_8b57edb8._.js → _0020fddd._.js} +2 -2
  183. package/web/.next/server/chunks/ssr/_0020fddd._.js.map +1 -0
  184. package/web/.next/server/chunks/ssr/_02e01240._.js +4 -0
  185. package/web/.next/server/chunks/ssr/_02e01240._.js.map +1 -0
  186. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  187. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  188. package/web/.next/server/chunks/ssr/_0727935d._.js +1 -1
  189. package/web/.next/server/chunks/ssr/_0727935d._.js.map +1 -1
  190. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  191. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  192. package/web/.next/server/chunks/ssr/_18886033._.js +4 -0
  193. package/web/.next/server/chunks/ssr/_18886033._.js.map +1 -0
  194. package/web/.next/server/chunks/ssr/_22e00a14._.js +1 -1
  195. package/web/.next/server/chunks/ssr/_22e00a14._.js.map +1 -1
  196. package/web/.next/server/chunks/ssr/_4d49a312._.js +3 -0
  197. package/web/.next/server/chunks/ssr/_4d49a312._.js.map +1 -0
  198. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  199. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  200. package/web/.next/server/chunks/ssr/_7a6f6a76._.js +3 -0
  201. package/web/.next/server/chunks/ssr/_7a6f6a76._.js.map +1 -0
  202. package/web/.next/server/chunks/ssr/{_def82237._.js → _8276397a._.js} +2 -2
  203. package/web/.next/server/chunks/ssr/{_def82237._.js.map → _8276397a._.js.map} +1 -1
  204. package/web/.next/server/chunks/ssr/_9215e9ec._.js +3 -0
  205. package/web/.next/server/chunks/ssr/_9215e9ec._.js.map +1 -0
  206. package/web/.next/server/chunks/ssr/_a5a5901d._.js +1 -1
  207. package/web/.next/server/chunks/ssr/_a5a5901d._.js.map +1 -1
  208. package/web/.next/server/chunks/ssr/_ad09f271._.js +4 -0
  209. package/web/.next/server/chunks/ssr/_ad09f271._.js.map +1 -0
  210. package/web/.next/server/chunks/ssr/_b7a43c05._.js +3 -0
  211. package/web/.next/server/chunks/ssr/_b7a43c05._.js.map +1 -0
  212. package/web/.next/server/chunks/ssr/_c3f595c6._.js +1 -1
  213. package/web/.next/server/chunks/ssr/_c3f595c6._.js.map +1 -1
  214. package/web/.next/server/chunks/ssr/_c45aee16._.js +3 -0
  215. package/web/.next/server/chunks/ssr/_c45aee16._.js.map +1 -0
  216. package/web/.next/server/chunks/ssr/{_ce97386b._.js → _cc654b75._.js} +3 -3
  217. package/web/.next/server/chunks/ssr/_cc654b75._.js.map +1 -0
  218. package/web/.next/server/chunks/ssr/_ea9e1556._.js +4 -0
  219. package/web/.next/server/chunks/ssr/_ea9e1556._.js.map +1 -0
  220. package/web/.next/server/chunks/ssr/_f1ba9be6._.js +2 -2
  221. package/web/.next/server/chunks/ssr/_f1ba9be6._.js.map +1 -1
  222. package/web/.next/server/chunks/ssr/_f33cd07e._.js +2 -2
  223. package/web/.next/server/chunks/ssr/_f33cd07e._.js.map +1 -1
  224. package/web/.next/server/chunks/ssr/_f8b45233._.js +1 -1
  225. package/web/.next/server/chunks/ssr/_f8b45233._.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/{_b881a389._.js → _fdc356bf._.js} +2 -2
  227. package/web/.next/server/chunks/ssr/_fdc356bf._.js.map +1 -0
  228. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  229. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  230. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +3 -0
  231. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -0
  232. package/web/.next/server/chunks/ssr/node_modules__pnpm_1300ae39._.js +3 -0
  233. package/web/.next/server/chunks/ssr/node_modules__pnpm_1300ae39._.js.map +1 -0
  234. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  235. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js.map +1 -1
  236. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
  237. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
  238. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  239. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  240. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js +1 -1
  241. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js.map +1 -1
  242. package/web/.next/server/pages/500.html +2 -2
  243. package/web/.next/server/server-reference-manifest.js +1 -1
  244. package/web/.next/server/server-reference-manifest.json +190 -154
  245. package/web/.next/static/chunks/16eea21868510afd.js +5 -0
  246. package/web/.next/static/chunks/1ad664f7081cf4c0.js +1 -0
  247. package/web/.next/static/chunks/{0613d3829ce90fe9.js → 4788a37d8c608e30.js} +1 -1
  248. package/web/.next/static/chunks/4f7d9c08a205bc4e.js +1 -0
  249. package/web/.next/static/chunks/5d8c83c576ec1a7b.js +1 -0
  250. package/web/.next/static/chunks/779b5c49587b074e.js +1 -0
  251. package/web/.next/static/chunks/7cec51e9bd7d1f4f.js +1 -0
  252. package/web/.next/static/chunks/{780f688b8568331d.js → 7d40e79e524c8d18.js} +2 -2
  253. package/web/.next/static/chunks/{5f40b5c4f859b573.js → 8094762f5cda4934.js} +1 -1
  254. package/web/.next/static/chunks/9162bb869b3543e2.js +7 -0
  255. package/web/.next/static/chunks/940bca62e44f3e90.js +5 -0
  256. package/web/.next/static/chunks/966eb2688300b7f5.js +1 -0
  257. package/web/.next/static/chunks/971e52f3f386ccfd.js +1 -0
  258. package/web/.next/static/chunks/a760d5829014058d.js +1 -0
  259. package/web/.next/static/chunks/b63e6727c84f30e2.js +1 -0
  260. package/web/.next/static/chunks/d6a1a06ee3c12489.js +1 -0
  261. package/web/.next/static/chunks/dedf6ca63c5468fa.js +5 -0
  262. package/web/.next/static/chunks/e77d053610055e0c.js +1 -0
  263. package/web/.next/static/chunks/{0d9e3aa7e10cf6e6.js → ee9fe376b60c3cab.js} +2 -2
  264. package/web/.next/static/chunks/eeadf13c0ea6cbe0.css +1 -0
  265. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_4b319ae6._.js.map +0 -1
  266. package/web/.next/server/chunks/ssr/[root-of-the-server]__e5ceba65._.js +0 -3
  267. package/web/.next/server/chunks/ssr/[root-of-the-server]__e5ceba65._.js.map +0 -1
  268. package/web/.next/server/chunks/ssr/[root-of-the-server]__e91ffd5e._.js +0 -7
  269. package/web/.next/server/chunks/ssr/[root-of-the-server]__e91ffd5e._.js.map +0 -1
  270. package/web/.next/server/chunks/ssr/_075fae20._.js +0 -4
  271. package/web/.next/server/chunks/ssr/_075fae20._.js.map +0 -1
  272. package/web/.next/server/chunks/ssr/_125c55af._.js +0 -4
  273. package/web/.next/server/chunks/ssr/_125c55af._.js.map +0 -1
  274. package/web/.next/server/chunks/ssr/_391e499a._.js +0 -3
  275. package/web/.next/server/chunks/ssr/_391e499a._.js.map +0 -1
  276. package/web/.next/server/chunks/ssr/_573caadf._.js +0 -3
  277. package/web/.next/server/chunks/ssr/_573caadf._.js.map +0 -1
  278. package/web/.next/server/chunks/ssr/_628621c7._.js +0 -4
  279. package/web/.next/server/chunks/ssr/_628621c7._.js.map +0 -1
  280. package/web/.next/server/chunks/ssr/_68996e5b._.js +0 -3
  281. package/web/.next/server/chunks/ssr/_68996e5b._.js.map +0 -1
  282. package/web/.next/server/chunks/ssr/_8b57edb8._.js.map +0 -1
  283. package/web/.next/server/chunks/ssr/_9412b27f._.js +0 -4
  284. package/web/.next/server/chunks/ssr/_9412b27f._.js.map +0 -1
  285. package/web/.next/server/chunks/ssr/_ac4a3873._.js +0 -3
  286. package/web/.next/server/chunks/ssr/_ac4a3873._.js.map +0 -1
  287. package/web/.next/server/chunks/ssr/_b881a389._.js.map +0 -1
  288. package/web/.next/server/chunks/ssr/_ce97386b._.js.map +0 -1
  289. package/web/.next/server/chunks/ssr/_cfbd1d7e._.js +0 -3
  290. package/web/.next/server/chunks/ssr/_cfbd1d7e._.js.map +0 -1
  291. package/web/.next/server/chunks/ssr/node_modules__pnpm_8ec2c790._.js +0 -3
  292. package/web/.next/server/chunks/ssr/node_modules__pnpm_8ec2c790._.js.map +0 -1
  293. package/web/.next/static/chunks/0a79dfbb8486b66e.js +0 -5
  294. package/web/.next/static/chunks/14d9d9181bb4e337.js +0 -1
  295. package/web/.next/static/chunks/4581eaf51543601d.js +0 -1
  296. package/web/.next/static/chunks/47477ed4c5871747.js +0 -1
  297. package/web/.next/static/chunks/74db65fa7bfb80bd.js +0 -1
  298. package/web/.next/static/chunks/8b64414cdb4a4dc7.js +0 -1
  299. package/web/.next/static/chunks/bf55fb50a69f7350.js +0 -5
  300. package/web/.next/static/chunks/c04ada25ace6f30c.js +0 -1
  301. package/web/.next/static/chunks/c3a67566f78b5bc3.js +0 -1
  302. package/web/.next/static/chunks/ca8752df0e809c1b.js +0 -7
  303. package/web/.next/static/chunks/d2cbeefbc8967b16.js +0 -1
  304. package/web/.next/static/chunks/d39ae882d080aa52.js +0 -1
  305. package/web/.next/static/chunks/d6e702c209c413ce.js +0 -5
  306. package/web/.next/static/chunks/dbfbd9d9ee5eb2d0.js +0 -1
  307. package/web/.next/static/chunks/dc39dd4276779dec.js +0 -1
  308. package/web/.next/static/chunks/e779296e738a812b.css +0 -1
  309. /package/web/.next/static/{qfCnoWSr4qmt2_dT28B-O → lQkUWQQS5aR4vq6WUZ2yr}/_buildManifest.js +0 -0
  310. /package/web/.next/static/{qfCnoWSr4qmt2_dT28B-O → lQkUWQQS5aR4vq6WUZ2yr}/_clientMiddlewareManifest.json +0 -0
  311. /package/web/.next/static/{qfCnoWSr4qmt2_dT28B-O → lQkUWQQS5aR4vq6WUZ2yr}/_ssgManifest.js +0 -0
@@ -2,75 +2,54 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useState, useEffect, useRef } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
- import { AlertTriangle, Check, ExternalLink, FileSearch, GitBranch, GitCommitHorizontal, RotateCcw, ShieldCheck, Square, X, Zap, } from 'lucide-react';
5
+ import { AlertTriangle, Check, CheckCircle2, Clock, ExternalLink, FileSearch, GitBranch, GitCommitHorizontal, GitMerge, Info, RefreshCw, Settings, ShieldCheck, X, Zap, } from 'lucide-react';
6
6
  import { InlineAttachments } from '../../common/inline-attachments/index.js';
7
7
  import { PrStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
8
8
  import { cn } from '../../../lib/utils.js';
9
- import { Badge } from '../../ui/badge.js';
10
- import { Separator } from '../../ui/separator.js';
11
9
  import { CiStatusBadge } from '../../common/ci-status-badge/index.js';
12
10
  import { CometSpinner } from '../../ui/comet-spinner.js';
13
- import { featureNodeStateConfig, lifecycleDisplayLabels } from '../../common/feature-node/index.js';
11
+ import { ActionButton } from '../../common/action-button/index.js';
12
+ import { featureNodeStateConfig } from '../../common/feature-node/index.js';
14
13
  import { getAgentTypeIcon, agentTypeLabels, } from '../../common/feature-node/agent-type-icons.js';
15
14
  import { getModelMeta } from '../../../lib/model-metadata.js';
16
15
  import { formatDuration } from '../../../lib/format-duration.js';
17
- import { BranchSyncStatus } from './branch-sync-status.js';
18
- export function OverviewTab({ data, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }) {
19
- const isCompleted = data.lifecycle === 'maintain';
20
- return (_jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-status", className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: lifecycleDisplayLabels[data.lifecycle] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(FeatureStateBadge, { data: data }), data.state === 'error' && data.onRetry ? (_jsxs("button", { "data-testid": "feature-drawer-retry-button", onClick: () => data.onRetry(data.featureId), className: "flex shrink-0 cursor-pointer items-center gap-1.5 rounded-full bg-red-50 px-3 py-1.5 text-sm font-medium text-red-700 transition-colors hover:bg-red-100", children: [_jsx(RotateCcw, { className: "h-3.5 w-3.5" }), "Retry"] })) : null, (data.state === 'running' || data.state === 'action-required') && data.onStop ? (_jsxs("button", { "data-testid": "feature-drawer-stop-button", onClick: () => data.onStop(data.featureId), className: "flex shrink-0 cursor-pointer items-center gap-1.5 rounded-full bg-red-50 px-3 py-1.5 text-sm font-medium text-red-700 transition-colors hover:bg-red-100", children: [_jsx(Square, { className: "h-3.5 w-3.5" }), "Stop"] })) : null] }), !isCompleted && data.progress > 0 ? (_jsxs("div", { "data-testid": "feature-drawer-progress", className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-xs", children: [_jsx("span", { children: "Progress" }), _jsxs("span", { children: [data.progress, "%"] })] }), _jsx("div", { className: "bg-muted h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', featureNodeStateConfig[data.state].progressClass), style: { width: `${data.progress}%` } }) })] })) : null, isCompleted && data.pr ? (_jsx(FeaturePrInfo, { pr: data.pr, hideCiStatus: data.hideCiStatus })) : null] }), _jsx(FeatureInfo, { data: data }), !isCompleted && data.pr ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx("div", { className: "p-4", children: _jsx(FeaturePrInfo, { pr: data.pr, hideCiStatus: data.hideCiStatus }) })] })) : null, _jsx(FeatureDetails, { data: data }), onRebaseOnMain && data.branch && onRefreshSync ? (_jsx(BranchSyncStatus, { syncStatus: syncStatus ?? null, syncLoading: syncLoading ?? false, syncError: syncError ?? null, onRefreshSync: onRefreshSync, onRebaseOnMain: onRebaseOnMain, rebaseLoading: rebaseLoading ?? false, rebaseError: rebaseError ?? null })) : null, _jsx(FeatureSettings, { data: data })] }));
16
+ // ── Primitives ──────────────────────────────────────────────────────
17
+ function Section({ icon: Icon, title, children, }) {
18
+ return (_jsxs("div", { className: "px-3 pt-4 pb-1", children: [_jsxs("div", { className: "text-foreground mb-2 flex items-center gap-1.5 text-sm font-semibold tracking-wider uppercase", children: [_jsx(Icon, { className: "size-4 opacity-50" }), title] }), children] }));
21
19
  }
22
- function FeatureStateBadge({ data }) {
23
- const config = featureNodeStateConfig[data.state];
24
- const Icon = config.icon;
25
- return (_jsxs("div", { className: cn('flex items-center gap-2 rounded-full px-3 py-1.5 text-sm font-medium', config.badgeBgClass, config.badgeClass), children: [data.state === 'running' ? (_jsx(CometSpinner, { size: "sm", className: "shrink-0" })) : (_jsx(Icon, { className: "h-4 w-4 shrink-0" })), _jsx("span", { children: config.label })] }));
20
+ function Card({ children, className }) {
21
+ return (_jsx("div", { className: cn('bg-muted/60 rounded-md border border-transparent p-3', className), children: children }));
26
22
  }
27
- // ── Feature Info section ─────────────────────────────────────────────
23
+ function KV({ label, children }) {
24
+ return (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-foreground/40 text-[11px] font-medium tracking-wider uppercase", children: label }), _jsx("span", { className: "text-sm leading-snug", children: children })] }));
25
+ }
26
+ function Flag({ on, label }) {
27
+ return (_jsxs("span", { className: cn('inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium', on
28
+ ? 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400'
29
+ : 'bg-foreground/[0.04] text-foreground/25'), children: [on ? _jsx(Check, { className: "size-3" }) : _jsx(X, { className: "size-3" }), label] }));
30
+ }
31
+ // ── Helpers ──────────────────────────────────────────────────────────
28
32
  function formatRelativeTime(timestamp) {
29
33
  const now = Date.now();
30
34
  const time = typeof timestamp === 'string' ? new Date(timestamp).getTime() : timestamp;
31
35
  const diffMs = now - time;
32
- const diffSec = Math.floor(diffMs / 1000);
33
- const diffMin = Math.floor(diffSec / 60);
36
+ const diffMin = Math.floor(diffMs / 60000);
34
37
  const diffHr = Math.floor(diffMin / 60);
35
38
  const diffDay = Math.floor(diffHr / 24);
36
- if (diffDay > 30) {
39
+ if (diffDay > 30)
37
40
  return new Date(time).toLocaleDateString(undefined, {
38
41
  year: 'numeric',
39
42
  month: 'short',
40
43
  day: 'numeric',
41
44
  });
42
- }
43
45
  if (diffDay > 0)
44
- return `${diffDay} day${diffDay === 1 ? '' : 's'} ago`;
46
+ return `${diffDay}d ago`;
45
47
  if (diffHr > 0)
46
- return `${diffHr} hour${diffHr === 1 ? '' : 's'} ago`;
48
+ return `${diffHr}h ago`;
47
49
  if (diffMin > 0)
48
- return `${diffMin} minute${diffMin === 1 ? '' : 's'} ago`;
50
+ return `${diffMin}m ago`;
49
51
  return 'just now';
50
52
  }
51
- function FeatureInfo({ data }) {
52
- const { t } = useTranslation('web');
53
- const showSummary = Boolean(data.summary) && !(data.userQuery && data.summary?.trim() === data.userQuery.trim());
54
- const hasInfo = Boolean(data.branch) ||
55
- Boolean(data.oneLiner) ||
56
- showSummary ||
57
- Boolean(data.userQuery) ||
58
- Boolean(data.createdAt);
59
- if (!hasInfo)
60
- return null;
61
- return (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-info", className: "flex flex-col gap-3 p-4", children: [data.branch ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Branch" }), _jsxs("span", { className: "flex items-center gap-1.5 text-sm", children: [_jsx(GitBranch, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx("code", { className: "bg-muted rounded px-1 py-0.5 font-mono text-xs", children: data.branch }), data.baseBranch ? (_jsxs("span", { className: "text-muted-foreground text-xs", children: ["from ", data.baseBranch] })) : null] })] })) : null, data.oneLiner ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "One-Liner" }), _jsx("span", { className: "text-sm leading-relaxed", children: data.oneLiner })] })) : null, data.userQuery ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "User Query" }), _jsx(InlineAttachments, { text: data.userQuery })] })) : null, showSummary ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Summary" }), _jsx("span", { className: "text-sm leading-relaxed", children: data.summary })] })) : null, data.createdAt ? (_jsx(DetailRow, { label: t('overviewTab.created'), value: formatRelativeTime(data.createdAt) })) : null] })] }));
62
- }
63
- // ── PR Info section ──────────────────────────────────────────────────
64
- const prStatusStyles = {
65
- [PrStatus.Open]: 'border-transparent bg-blue-50 text-blue-700 hover:bg-blue-50',
66
- [PrStatus.Merged]: 'border-transparent bg-purple-50 text-purple-700 hover:bg-purple-50',
67
- [PrStatus.Closed]: 'border-transparent bg-red-50 text-red-700 hover:bg-red-50',
68
- };
69
- function FeaturePrInfo({ pr, hideCiStatus, }) {
70
- return (_jsx("div", { "data-testid": "feature-drawer-pr", children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("a", { href: pr.url, target: "_blank", rel: "noopener noreferrer", className: "text-primary flex items-center gap-1.5 text-sm font-semibold underline underline-offset-2", children: ["PR #", pr.number, _jsx(ExternalLink, { className: "h-3.5 w-3.5" })] }), _jsx(Badge, { className: prStatusStyles[pr.status], children: pr.status })] }), pr.ciStatus && hideCiStatus !== true ? (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "CI Status" }), _jsx(CiStatusBadge, { status: pr.ciStatus })] })) : null, pr.mergeable === false ? (_jsxs("div", { "data-testid": "pr-merge-conflict", className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Merge Status" }), _jsxs(Badge, { className: "border-transparent bg-orange-50 text-orange-700 hover:bg-orange-50", children: [_jsx(AlertTriangle, { className: "me-1 h-3.5 w-3.5" }), "Conflicts"] })] })) : null, pr.commitHash ? (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Commit" }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(GitCommitHorizontal, { className: "text-muted-foreground h-3.5 w-3.5" }), _jsx("code", { className: "bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-[11px]", children: pr.commitHash.slice(0, 7) })] })] })) : null] }) }));
71
- }
72
- // ── Details section ──────────────────────────────────────────────────
73
- /** Hook that returns a live-updating elapsed time string for running features. */
74
53
  function useElapsedTime(startedAt) {
75
54
  const [elapsed, setElapsed] = useState(null);
76
55
  const intervalRef = useRef(null);
@@ -79,62 +58,58 @@ function useElapsedTime(startedAt) {
79
58
  setElapsed(null);
80
59
  return;
81
60
  }
82
- // Compute immediately
83
61
  setElapsed(formatDuration(Math.max(0, Date.now() - startedAt)));
84
- // Tick every second
85
62
  intervalRef.current = setInterval(() => {
86
63
  setElapsed(formatDuration(Math.max(0, Date.now() - startedAt)));
87
64
  }, 1000);
88
65
  return () => {
89
- if (intervalRef.current) {
66
+ if (intervalRef.current)
90
67
  clearInterval(intervalRef.current);
91
- intervalRef.current = null;
92
- }
93
68
  };
94
69
  }, [startedAt]);
95
70
  return elapsed;
96
71
  }
97
- function FeatureDetails({ data }) {
98
- const { t } = useTranslation('web');
72
+ const prColor = {
73
+ [PrStatus.Open]: 'text-blue-600 dark:text-blue-400',
74
+ [PrStatus.Merged]: 'text-purple-600 dark:text-purple-400',
75
+ [PrStatus.Closed]: 'text-red-600 dark:text-red-400',
76
+ };
77
+ export function OverviewTab({ data, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }) {
78
+ const isCompleted = data.lifecycle === 'maintain';
99
79
  const isRunning = data.state === 'running' || data.state === 'action-required';
100
80
  const elapsedTime = useElapsedTime(isRunning ? data.startedAt : undefined);
101
- const hasAnyDetail = data.fastMode ??
102
- data.agentType ??
103
- data.runtime ??
104
- elapsedTime ??
105
- data.blockedBy ??
106
- data.errorMessage;
107
- if (!hasAnyDetail)
108
- return null;
109
- return (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-details", className: "flex flex-col gap-3 p-4", children: [data.fastMode ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Mode" }), _jsxs("span", { className: "flex items-center gap-2 text-sm", children: [_jsx(Zap, { className: "h-4 w-4 shrink-0 text-amber-500" }), "Fast Mode"] })] })) : null, data.agentType ? _jsx(AgentDetailRow, { agentType: data.agentType }) : null, data.runtime ? _jsx(DetailRow, { label: t('overviewTab.runtime'), value: data.runtime }) : null, !data.runtime && elapsedTime ? (_jsx(DetailRow, { label: t('overviewTab.runningFor'), value: elapsedTime })) : null, data.blockedBy ? (_jsx(DetailRow, { label: t('overviewTab.blockedBy'), value: data.blockedBy })) : null, data.errorMessage ? (_jsx(DetailRow, { label: t('overviewTab.error'), value: data.errorMessage })) : null] })] }));
110
- }
111
- function AgentDetailRow({ agentType }) {
112
- const Icon = getAgentTypeIcon(agentType);
113
- const label = agentTypeLabels[agentType] ?? agentType;
114
- return (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Agent" }), _jsxs("span", { className: "flex items-center gap-2 text-sm", children: [_jsx(Icon, { className: "h-4 w-4 shrink-0" }), label] })] }));
115
- }
116
- // ── Settings section ─────────────────────────────────────────────────
117
- function SettingBadge({ enabled, label }) {
118
- return (_jsxs("span", { className: cn('inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium', enabled ? 'bg-emerald-50 text-emerald-700' : 'bg-muted text-muted-foreground'), children: [enabled ? _jsx(Check, { className: "h-3 w-3" }) : _jsx(X, { className: "h-3 w-3" }), label] }));
81
+ const config = featureNodeStateConfig[data.state];
82
+ const showSummary = Boolean(data.summary) && !(data.userQuery && data.summary?.trim() === data.userQuery.trim());
83
+ return (_jsxs("div", { "data-testid": "feature-drawer-status", className: "pb-4", children: [!isCompleted && data.progress > 0 ? (_jsx("div", { "data-testid": "feature-drawer-progress", className: "px-3 pb-2", children: _jsx("div", { className: "bg-foreground/[0.06] h-1.5 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', config.progressClass), style: { width: `${data.progress}%` } }) }) })) : null, data.oneLiner || data.userQuery || showSummary ? (_jsx(Section, { icon: Info, title: "Description", children: _jsxs(Card, { className: "flex flex-col gap-2", children: [data.oneLiner ? _jsx(KV, { label: "One-Liner", children: data.oneLiner }) : null, data.userQuery ? (_jsx(KV, { label: "Query", children: _jsx(InlineAttachments, { text: data.userQuery }) })) : null, showSummary ? (_jsx(KV, { label: "Summary", children: _jsx("span", { className: "leading-snug", children: data.summary }) })) : null] }) })) : null, data.pr ? (_jsx(Section, { icon: GitCommitHorizontal, title: "Pull Request", children: _jsx(Card, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("a", { href: data.pr.url, target: "_blank", rel: "noopener noreferrer", className: "text-primary inline-flex items-center gap-1 text-sm font-semibold hover:underline", children: ["#", data.pr.number, " ", _jsx(ExternalLink, { className: "size-3" })] }), _jsx("span", { className: cn('text-xs font-semibold', prColor[data.pr.status]), children: data.pr.status }), data.pr.mergeable === false ? (_jsxs("span", { className: "inline-flex items-center gap-1 text-xs font-medium text-orange-600 dark:text-orange-400", children: [_jsx(AlertTriangle, { className: "size-3 shrink-0" }), " Conflicts"] })) : null, data.pr.ciStatus && data.hideCiStatus !== true ? (_jsx(CiStatusBadge, { status: data.pr.ciStatus })) : null, data.pr.commitHash ? (_jsx("code", { className: "text-foreground/40 ml-auto font-mono text-[11px]", children: data.pr.commitHash.slice(0, 7) })) : null] }) }) })) : null, _jsxs("div", { className: "grid grid-cols-2 gap-2 px-3 pb-1", children: [data.branch ? (_jsx(Card, { children: _jsxs(KV, { label: "Branch", children: [_jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(GitBranch, { className: "text-foreground/30 size-3 shrink-0" }), _jsx("code", { className: "font-mono text-[11px]", children: data.branch })] }), data.baseBranch ? (_jsxs("span", { className: "text-foreground/30 block text-[10px]", children: ["from ", data.baseBranch] })) : null] }) })) : null, data.agentType || data.modelId ? (_jsx(Card, { children: _jsx(KV, { label: "Agent", children: _jsxs("span", { className: "inline-flex items-center gap-1.5", children: [data.agentType
84
+ ? (() => {
85
+ const I = getAgentTypeIcon(data.agentType);
86
+ return _jsx(I, { className: "size-3.5 shrink-0 opacity-50" });
87
+ })()
88
+ : null, data.agentType ? (_jsx("span", { children: agentTypeLabels[data.agentType] ??
89
+ data.agentType })) : null, data.agentType && data.modelId ? (_jsx("span", { className: "text-foreground/20", children: "/" })) : null, data.modelId ? (_jsx("span", { className: "text-foreground/50 text-[12px]", children: getModelMeta(data.modelId).displayName || data.modelId })) : null] }) }) })) : null, data.createdAt ? (_jsx(Card, { children: _jsx(KV, { label: "Created", children: _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(Clock, { className: "text-foreground/30 size-3 shrink-0" }), formatRelativeTime(data.createdAt)] }) }) })) : null, data.fastMode ? (_jsx(Card, { children: _jsx(KV, { label: "Mode", children: _jsxs("span", { className: "inline-flex items-center gap-1 text-amber-600 dark:text-amber-400", children: [_jsx(Zap, { className: "size-3.5" }), " Fast"] }) }) })) : null, data.runtime || elapsedTime ? (_jsx(Card, { children: _jsx(KV, { label: data.runtime ? 'Runtime' : 'Elapsed', children: _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx(Clock, { className: "text-foreground/30 size-3 shrink-0" }), data.runtime ?? elapsedTime] }) }) })) : null] }), data.blockedBy || data.errorMessage ? (_jsx(Section, { icon: AlertTriangle, title: "Issues", children: _jsxs(Card, { className: "border-destructive/20 bg-destructive/5", children: [data.blockedBy ? _jsx(KV, { label: "Blocked By", children: data.blockedBy }) : null, data.errorMessage ? (_jsx(KV, { label: "Error", children: _jsx("span", { className: "text-destructive", children: data.errorMessage }) })) : null] }) })) : null, onRebaseOnMain && data.branch && onRefreshSync ? (_jsx(Section, { icon: RefreshCw, title: "Branch Sync", children: _jsx(SyncCard, { syncStatus: syncStatus ?? null, syncLoading: syncLoading ?? false, syncError: syncError ?? null, onRefreshSync: onRefreshSync, onRebaseOnMain: onRebaseOnMain, rebaseLoading: rebaseLoading ?? false, rebaseError: rebaseError ?? null }) })) : null, _jsx(SettingsBlock, { data: data })] }));
119
90
  }
120
- function FeatureSettings({ data }) {
91
+ // ── Sync card ───────────────────────────────────────────────────────
92
+ function SyncCard({ syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }) {
121
93
  const { t } = useTranslation('web');
122
- const hasSettings = data.approvalGates != null ||
94
+ const isBehind = syncStatus != null && syncStatus.behind > 0;
95
+ const isUpToDate = syncStatus?.behind === 0;
96
+ const base = syncStatus?.baseBranch ?? 'main';
97
+ return (_jsxs(Card, { children: [_jsxs("div", { "data-testid": "branch-sync-status", className: "flex items-center justify-between", children: [_jsx("div", { className: "flex items-center gap-1.5 text-[13px]", children: syncLoading && !syncStatus ? (_jsxs(_Fragment, { children: [_jsx(CometSpinner, { size: "sm" }), _jsx("span", { className: "text-foreground/40", children: "Checking..." })] })) : syncError ? (_jsxs(_Fragment, { children: [_jsx(AlertTriangle, { className: "size-3.5 text-red-500" }), _jsx("span", { className: "text-destructive text-xs", children: syncError })] })) : rebaseLoading ? (_jsxs(_Fragment, { children: [_jsx(CometSpinner, { size: "sm" }), _jsxs("span", { children: ["Rebasing on ", _jsx("code", { className: "font-mono text-[11px]", children: base }), "..."] })] })) : isBehind ? (_jsxs(_Fragment, { children: [_jsx(AlertTriangle, { className: "size-3.5 text-orange-500" }), _jsxs("span", { children: [syncStatus.behind, " behind ", _jsx("code", { className: "font-mono text-[11px]", children: base }), syncStatus.ahead > 0 ? (_jsxs("span", { className: "text-foreground/30 ml-1 text-[11px]", children: ["\u00B7 ", syncStatus.ahead, " ahead"] })) : null] })] })) : isUpToDate ? (_jsxs(_Fragment, { children: [_jsx(CheckCircle2, { className: "size-3.5 text-green-500" }), _jsxs("span", { children: ["Up to date \u00B7 ", _jsx("code", { className: "font-mono text-[11px]", children: base }), syncStatus.ahead > 0 ? (_jsxs("span", { className: "text-foreground/30 ml-1 text-[11px]", children: ["\u00B7 ", syncStatus.ahead, " ahead"] })) : null] })] })) : null }), (syncStatus || syncError) && !rebaseLoading ? (_jsx("button", { onClick: onRefreshSync, disabled: syncLoading, className: "text-foreground/30 hover:text-foreground/60 hover:bg-foreground/5 inline-flex size-6 items-center justify-center rounded-sm disabled:opacity-50", "aria-label": t('branchSyncStatus.refreshSyncStatus'), children: _jsx(RefreshCw, { className: cn('size-3', syncLoading && 'animate-spin') }) })) : null] }), isBehind && !rebaseLoading ? (_jsx("div", { className: "pt-2", children: _jsx(ActionButton, { label: t('branchSyncStatus.rebaseOnMain'), onClick: onRebaseOnMain, loading: false, error: !!rebaseError, icon: GitMerge, variant: "outline", size: "sm" }) })) : null, rebaseError ? _jsx("p", { className: "text-destructive pt-1 text-[11px]", children: rebaseError }) : null] }));
98
+ }
99
+ // ── Settings ────────────────────────────────────────────────────────
100
+ function SettingsBlock({ data }) {
101
+ const has = data.approvalGates != null ||
123
102
  data.push != null ||
124
103
  data.openPr != null ||
125
104
  data.ciWatchEnabled != null ||
126
105
  data.enableEvidence != null ||
127
106
  data.forkAndPr != null ||
128
- data.commitSpecs != null ||
129
- data.modelId;
130
- if (!hasSettings)
107
+ data.commitSpecs != null;
108
+ if (!has)
131
109
  return null;
132
- return (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-settings", className: "flex flex-col gap-3 p-4", children: [_jsx("span", { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "SETTINGS" }), data.modelId ? (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Model" }), _jsx("span", { className: "text-sm", children: getModelMeta(data.modelId).displayName || data.modelId })] })) : null, data.approvalGates ? (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("span", { className: "text-muted-foreground flex items-center gap-1 text-xs font-medium", children: [_jsx(ShieldCheck, { className: "h-3 w-3" }), "Auto-Approve"] }), _jsxs("div", { className: "flex flex-wrap gap-1.5", children: [_jsx(SettingBadge, { enabled: data.approvalGates.allowPrd, label: t('overviewTab.prd') }), _jsx(SettingBadge, { enabled: data.approvalGates.allowPlan, label: t('overviewTab.plan') }), _jsx(SettingBadge, { enabled: data.approvalGates.allowMerge, label: t('overviewTab.merge') })] })] })) : null, data.enableEvidence != null ? (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("span", { className: "text-muted-foreground flex items-center gap-1 text-xs font-medium", children: [_jsx(FileSearch, { className: "h-3 w-3" }), "Evidence"] }), _jsxs("div", { className: "flex flex-wrap gap-1.5", children: [_jsx(SettingBadge, { enabled: data.enableEvidence, label: t('overviewTab.collect') }), data.commitEvidence != null ? (_jsx(SettingBadge, { enabled: data.commitEvidence, label: t('overviewTab.addToPr') })) : null] })] })) : null, data.push != null ||
133
- data.openPr != null ||
134
- data.ciWatchEnabled != null ||
135
- data.commitSpecs != null ||
136
- data.forkAndPr != null ? (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("span", { className: "text-muted-foreground flex items-center gap-1 text-xs font-medium", children: [_jsx(GitBranch, { className: "h-3 w-3" }), "Git"] }), _jsxs("div", { className: "flex flex-wrap gap-1.5", children: [data.push != null ? (_jsx(SettingBadge, { enabled: data.push, label: t('overviewTab.push') })) : null, data.openPr != null ? (_jsx(SettingBadge, { enabled: data.openPr, label: t('overviewTab.pr') })) : null, data.ciWatchEnabled != null ? (_jsx(SettingBadge, { enabled: data.ciWatchEnabled, label: t('overviewTab.watch') })) : null, data.commitSpecs != null ? (_jsx(SettingBadge, { enabled: data.commitSpecs, label: t('overviewTab.commitSpecs') })) : null, data.forkAndPr != null ? (_jsx(SettingBadge, { enabled: data.forkAndPr, label: t('overviewTab.forkAndPr') })) : null] })] })) : null] })] }));
137
- }
138
- function DetailRow({ label, value }) {
139
- return (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: label }), _jsx("span", { className: "text-sm", children: value })] }));
110
+ return (_jsx(Section, { icon: Settings, title: "Settings", children: _jsxs("div", { className: "grid grid-cols-3 gap-2", children: [data.approvalGates ? (_jsxs(Card, { children: [_jsxs("div", { className: "text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(ShieldCheck, { className: "size-3" }), " Approve"] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx(Flag, { on: data.approvalGates.allowPrd, label: "PRD" }), _jsx(Flag, { on: data.approvalGates.allowPlan, label: "Plan" }), _jsx(Flag, { on: data.approvalGates.allowMerge, label: "Merge" })] })] })) : null, data.enableEvidence != null ? (_jsxs(Card, { children: [_jsxs("div", { className: "text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(FileSearch, { className: "size-3" }), " Evidence"] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx(Flag, { on: data.enableEvidence, label: "Collect" }), data.commitEvidence != null ? (_jsx(Flag, { on: data.commitEvidence, label: "Add to PR" })) : null] })] })) : null, data.push != null ||
111
+ data.openPr != null ||
112
+ data.ciWatchEnabled != null ||
113
+ data.commitSpecs != null ||
114
+ data.forkAndPr != null ? (_jsxs(Card, { children: [_jsxs("div", { className: "text-foreground/40 mb-1.5 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(GitBranch, { className: "size-3" }), " Git"] }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [data.push != null ? _jsx(Flag, { on: data.push, label: "Push" }) : null, data.openPr != null ? _jsx(Flag, { on: data.openPr, label: "PR" }) : null, data.ciWatchEnabled != null ? _jsx(Flag, { on: data.ciWatchEnabled, label: "Watch" }) : null, data.commitSpecs != null ? _jsx(Flag, { on: data.commitSpecs, label: "Specs" }) : null, data.forkAndPr != null ? _jsx(Flag, { on: data.forkAndPr, label: "Fork" }) : null] })] })) : null] }) }));
140
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"open-action-menu.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/open-action-menu/open-action-menu.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAIpD,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,cAAc,EACd,YAAY,EACZ,SAAS,GACV,EAAE,mBAAmB,2CAqGrB"}
1
+ {"version":3,"file":"open-action-menu.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/open-action-menu/open-action-menu.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAqBpD,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,cAAc,EACd,YAAY,EACZ,SAAS,GACV,EAAE,mBAAmB,2CAmGrB"}
@@ -1,10 +1,17 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState } from 'react';
4
- import { Code2, Terminal, FolderOpen, ChevronDown, Copy, Check, Loader2, CircleAlert, } from 'lucide-react';
5
- import { Button } from '../../ui/button.js';
6
- import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '../../ui/dropdown-menu.js';
4
+ import { Code2, Terminal, FolderOpen, FileText, Copy, Check, Loader2, CircleAlert, } from 'lucide-react';
5
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
7
6
  const COPY_FEEDBACK_DELAY = 2000;
7
+ const tbBtn = 'text-muted-foreground hover:bg-foreground/8 hover:text-foreground inline-flex size-8 items-center justify-center rounded-[3px] disabled:opacity-40';
8
+ function TbIcon({ loading, error, icon: Icon, }) {
9
+ if (loading)
10
+ return _jsx(Loader2, { className: "size-3.5 animate-spin" });
11
+ if (error)
12
+ return _jsx(CircleAlert, { className: "text-destructive size-3.5" });
13
+ return _jsx(Icon, { className: "size-4" });
14
+ }
8
15
  export function OpenActionMenu({ actions, repositoryPath, worktreePath, showSpecs, }) {
9
16
  const [copied, setCopied] = useState(false);
10
17
  const handleCopyPath = () => {
@@ -12,7 +19,5 @@ export function OpenActionMenu({ actions, repositoryPath, worktreePath, showSpec
12
19
  setCopied(true);
13
20
  setTimeout(() => setCopied(false), COPY_FEEDBACK_DELAY);
14
21
  };
15
- const anyLoading = actions.ideLoading || actions.shellLoading || actions.folderLoading || actions.specsLoading;
16
- const anyError = actions.ideError ?? actions.shellError ?? actions.folderError ?? actions.specsError;
17
- return (_jsxs(DropdownMenu, { modal: false, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "sm", className: "gap-1.5", disabled: anyLoading, children: [anyLoading ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : anyError ? (_jsx(CircleAlert, { className: "text-destructive size-4" })) : (_jsx(FolderOpen, { className: "size-4" })), "Open", _jsx(ChevronDown, { className: "size-3 opacity-60" })] }) }), _jsxs(DropdownMenuContent, { align: "start", className: "w-48", children: [_jsx(DropdownMenuLabel, { children: "Open in" }), _jsxs(DropdownMenuItem, { onClick: actions.openInIde, disabled: actions.ideLoading, className: "gap-2", children: [actions.ideLoading ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : actions.ideError ? (_jsx(CircleAlert, { className: "text-destructive size-4" })) : (_jsx(Code2, { className: "size-4" })), "IDE"] }), _jsxs(DropdownMenuItem, { onClick: actions.openInShell, disabled: actions.shellLoading, className: "gap-2", children: [actions.shellLoading ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : actions.shellError ? (_jsx(CircleAlert, { className: "text-destructive size-4" })) : (_jsx(Terminal, { className: "size-4" })), "Terminal"] }), _jsxs(DropdownMenuItem, { onClick: actions.openFolder, disabled: actions.folderLoading, className: "gap-2", children: [actions.folderLoading ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : actions.folderError ? (_jsx(CircleAlert, { className: "text-destructive size-4" })) : (_jsx(FolderOpen, { className: "size-4" })), "Folder"] }), _jsxs(DropdownMenuItem, { onClick: actions.openSpecsFolder, disabled: actions.specsLoading || !showSpecs, className: "gap-2", children: [actions.specsLoading ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : actions.specsError ? (_jsx(CircleAlert, { className: "text-destructive size-4" })) : (_jsx(FolderOpen, { className: "size-4" })), "Specs Folder"] }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onClick: handleCopyPath, className: "gap-2", children: [copied ? _jsx(Check, { className: "size-4 text-green-600" }) : _jsx(Copy, { className: "size-4" }), copied ? 'Copied!' : 'Copy path'] })] })] }));
22
+ return (_jsx(TooltipProvider, { delayDuration: 300, children: _jsxs("div", { className: "flex items-center", children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", className: tbBtn, onClick: actions.openInIde, disabled: actions.ideLoading, "aria-label": "Open in IDE", children: _jsx(TbIcon, { loading: actions.ideLoading, error: actions.ideError, icon: Code2 }) }) }), _jsx(TooltipContent, { side: "bottom", className: "text-xs", children: "Open in IDE" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", className: tbBtn, onClick: actions.openInShell, disabled: actions.shellLoading, "aria-label": "Open terminal", children: _jsx(TbIcon, { loading: actions.shellLoading, error: actions.shellError, icon: Terminal }) }) }), _jsx(TooltipContent, { side: "bottom", className: "text-xs", children: "Open terminal" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", className: tbBtn, onClick: actions.openFolder, disabled: actions.folderLoading, "aria-label": "Open folder", children: _jsx(TbIcon, { loading: actions.folderLoading, error: actions.folderError, icon: FolderOpen }) }) }), _jsx(TooltipContent, { side: "bottom", className: "text-xs", children: "Open folder" })] }), showSpecs ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", className: tbBtn, onClick: actions.openSpecsFolder, disabled: actions.specsLoading, "aria-label": "Open specs", children: _jsx(TbIcon, { loading: actions.specsLoading, error: actions.specsError, icon: FileText }) }) }), _jsx(TooltipContent, { side: "bottom", className: "text-xs", children: "Open specs" })] })) : null, _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", className: tbBtn, onClick: handleCopyPath, "aria-label": "Copy path", children: copied ? _jsx(Check, { className: "size-3.5 text-green-500" }) : _jsx(Copy, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "bottom", className: "text-xs", children: copied ? 'Copied!' : 'Copy path' })] })] }) }));
18
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAwcA"}
1
+ {"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CA2cA"}
@@ -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;AAED,wBAAgB,OAAO,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,YAAY,2CAgGhE"}
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"}
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import { useCallback, useState } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { AssistantRuntimeProvider } from '@assistant-ui/react';
6
- import { Trash2, Square, Cpu } from 'lucide-react';
6
+ import { Trash2, Cpu } from 'lucide-react';
7
7
  import { cn } from '../../../lib/utils.js';
8
8
  import { Thread } from '../../assistant-ui/thread.js';
9
9
  import { useAttachments } from '../../../hooks/use-attachments.js';
@@ -11,12 +11,20 @@ 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
+ const IS_DEV = process.env.NODE_ENV === 'development';
14
15
  export function ChatTab({ featureId, worktreePath }) {
15
16
  const [overrideAgent, setOverrideAgent] = useState(undefined);
16
17
  const [overrideModel, setOverrideModel] = useState(undefined);
18
+ const [debugMode, setDebugMode] = useState(false);
17
19
  const att = useAttachments();
18
20
  const contentTransform = useCallback((content) => composeUserInput(content, att.completedAttachments.map((a) => ({ path: a.path, name: a.name, notes: a.notes }))), [att.completedAttachments]);
19
- const { runtime, status, clearChat, stopAgent, sessionInfo, isChatLoading } = useChatRuntime(featureId, worktreePath, { contentTransform, onMessageSent: att.clearAttachments });
21
+ const { runtime, status, clearChat, sessionInfo, isChatLoading } = useChatRuntime(featureId, worktreePath, {
22
+ contentTransform,
23
+ onMessageSent: att.clearAttachments,
24
+ model: overrideModel,
25
+ agentType: overrideAgent,
26
+ debugMode,
27
+ });
20
28
  const handlePickFiles = useCallback(async () => {
21
29
  try {
22
30
  const res = await fetch('/api/dialog/pick-files');
@@ -46,18 +54,16 @@ export function ChatTab({ featureId, worktreePath }) {
46
54
  setOverrideAgent(agent);
47
55
  setOverrideModel(model);
48
56
  }, className: "w-55" }) }));
49
- return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsx(ChatHeader, { sessionInfo: sessionInfo, isAgentActive: status.isRunning, onClear: clearChat, onStop: stopAgent }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: isChatLoading ? (_jsx(ChatSkeleton, {})) : (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(Thread, { composer: composer }) })) })] }));
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 }) })) })] }));
50
58
  }
51
59
  // ── Loading skeleton ────────────────────────────────────────────────────────
52
60
  function ChatSkeleton() {
53
61
  return (_jsxs("div", { className: "flex flex-1 flex-col gap-3 p-4 pt-6", children: [_jsxs("div", { className: "flex items-start gap-2.5", children: [_jsx("div", { className: "bg-muted h-6 w-6 animate-pulse rounded-full" }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "bg-muted h-4 w-48 animate-pulse rounded-lg" }), _jsx("div", { className: "bg-muted h-4 w-72 animate-pulse rounded-lg" }), _jsx("div", { className: "bg-muted h-4 w-36 animate-pulse rounded-lg" })] })] }), _jsxs("div", { className: "flex items-start gap-2.5", children: [_jsx("div", { className: "bg-muted h-6 w-6 animate-pulse rounded-full" }), _jsx("div", { className: "bg-muted h-4 w-32 animate-pulse rounded-lg" })] }), _jsxs("div", { className: "flex items-start gap-2.5", children: [_jsx("div", { className: "bg-muted h-6 w-6 animate-pulse rounded-full" }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "bg-muted h-4 w-56 animate-pulse rounded-lg" }), _jsx("div", { className: "bg-muted h-4 w-64 animate-pulse rounded-lg" })] })] })] }));
54
62
  }
55
63
  // ── Chat header — compact session info + actions ─────────────────────────────
56
- function ChatHeader({ sessionInfo, isAgentActive, onClear, onStop, }) {
64
+ function ChatHeader({ sessionInfo, isAgentActive, onClear, debugMode, onDebugToggle, }) {
57
65
  const { t } = useTranslation('web');
58
- return (_jsxs("div", { className: "flex h-8 shrink-0 items-center border-b px-3", children: [_jsx("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: sessionInfo ? (_jsxs(_Fragment, { children: [isAgentActive ? (_jsx("span", { className: "h-1.5 w-1.5 shrink-0 animate-pulse rounded-full bg-emerald-500" })) : (_jsx(Cpu, { className: "text-muted-foreground/40 h-3 w-3 shrink-0" })), _jsxs("span", { className: "text-muted-foreground font-mono text-[10px]", children: [sessionInfo.model ?? 'agent', sessionInfo.sessionId ? ` · ${sessionInfo.sessionId.slice(0, 8)}` : ''] })] })) : (_jsx("span", { className: "text-muted-foreground/40 text-[11px]", children: t('chat.noSession') })) }), _jsxs("div", { className: "flex items-center gap-1 ps-2", children: [sessionInfo ? (_jsxs(_Fragment, { children: [_jsxs(ToolbarButton, { onClick: () => {
59
- void onStop();
60
- }, title: t('chat.forceStopAgent'), variant: "danger", children: [_jsx(Square, { className: "h-2.5 w-2.5 fill-current" }), _jsx("span", { children: t('chat.stop') })] }), _jsx("span", { className: "text-border mx-0.5", children: "|" })] })) : null, _jsxs(ToolbarButton, { onClick: () => {
66
+ return (_jsxs("div", { className: "flex h-8 shrink-0 items-center border-b px-3", children: [_jsx("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: sessionInfo ? (_jsxs(_Fragment, { children: [isAgentActive ? (_jsx("span", { className: "h-1.5 w-1.5 shrink-0 animate-pulse rounded-full bg-emerald-500" })) : (_jsx(Cpu, { className: "text-muted-foreground/40 h-3 w-3 shrink-0" })), _jsxs("span", { className: "text-muted-foreground font-mono text-[10px]", children: [sessionInfo.model ?? 'agent', sessionInfo.sessionId ? ` · ${sessionInfo.sessionId.slice(0, 8)}` : ''] })] })) : (_jsx("span", { className: "text-muted-foreground/40 text-[11px]", children: t('chat.noSession') })) }), _jsxs("div", { className: "flex items-center gap-1 ps-2", children: [onDebugToggle ? (_jsxs("label", { className: "text-muted-foreground/60 flex cursor-pointer items-center gap-1 text-[10px]", children: [_jsx("input", { type: "checkbox", checked: debugMode, onChange: (e) => onDebugToggle(e.target.checked), className: "h-3 w-3 cursor-pointer rounded" }), "Debug"] })) : null, _jsxs(ToolbarButton, { onClick: () => {
61
67
  void onClear();
62
68
  }, title: t('chat.clearChatHistory'), children: [_jsx(Trash2, { className: "h-2.5 w-2.5" }), _jsx("span", { children: t('chat.clear') })] })] })] }));
63
69
  }
@@ -5,6 +5,9 @@ interface SessionInfo {
5
5
  startedAt: string;
6
6
  idleTimeoutMinutes: number;
7
7
  lastActivityAt: string;
8
+ totalCostUsd: number | null;
9
+ totalInputTokens: number | null;
10
+ totalOutputTokens: number | null;
8
11
  }
9
12
  export interface ChatStatus {
10
13
  /** Whether the agent is actively working (booting, thinking, streaming). */
@@ -17,6 +20,19 @@ export interface ChatRuntimeOptions {
17
20
  contentTransform?: (content: string) => string;
18
21
  /** Called after a message is successfully sent (e.g. clear attachments). */
19
22
  onMessageSent?: () => void;
23
+ /** Override model for new sessions (e.g. 'claude-sonnet-4-6'). */
24
+ model?: string;
25
+ /** Override agent type for new sessions (e.g. 'claude-code'). */
26
+ agentType?: string;
27
+ /** When true, inject debug bubbles showing SSE events, session info, etc. */
28
+ debugMode?: boolean;
29
+ }
30
+ /** A debug event captured from SSE for display in debug mode. */
31
+ export interface DebugEvent {
32
+ id: string;
33
+ timestamp: Date;
34
+ label: string;
35
+ detail?: string;
20
36
  }
21
37
  /**
22
38
  * `featureId` is a polymorphic scope key: a feature UUID, "repo-<id>", or "global".
@@ -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;CACxB;AAgDD,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,SAAS,EAAE,OAAO,CAAC;IACnB,qFAAqF;IACrF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAID,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,kBAAkB;;;;;;;EAiQ7B"}
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"}
@@ -13,11 +13,11 @@ async function fetchChatState(featureId) {
13
13
  }
14
14
  return res.json();
15
15
  }
16
- async function postMessage(featureId, content, worktreePath) {
16
+ async function postMessage(featureId, content, worktreePath, model, agentType) {
17
17
  const res = await fetch(`/api/interactive/chat/${featureId}/messages`, {
18
18
  method: 'POST',
19
19
  headers: { 'Content-Type': 'application/json' },
20
- body: JSON.stringify({ content, worktreePath }),
20
+ body: JSON.stringify({ content, worktreePath, model, agentType }),
21
21
  });
22
22
  if (!res.ok)
23
23
  throw new Error(`Failed to send message: ${res.status}`);
@@ -43,6 +43,24 @@ function chatQueryKey(featureId) {
43
43
  */
44
44
  export function useChatRuntime(featureId, worktreePath, options) {
45
45
  const queryClient = useQueryClient();
46
+ // Keep a ref to the latest model/agent so the mutation closure always
47
+ // reads the current value without depending on stale captures.
48
+ const modelRef = useRef(options?.model);
49
+ const agentTypeRef = useRef(options?.agentType);
50
+ modelRef.current = options?.model;
51
+ agentTypeRef.current = options?.agentType;
52
+ // ── Debug events (dev mode only) ────────────────────────────────────────
53
+ const debugModeRef = useRef(options?.debugMode ?? false);
54
+ debugModeRef.current = options?.debugMode ?? false;
55
+ const [debugEvents, setDebugEvents] = useState([]);
56
+ const pushDebug = useCallback((label, detail) => {
57
+ if (!debugModeRef.current)
58
+ return;
59
+ setDebugEvents((prev) => [
60
+ ...prev,
61
+ { id: `dbg-${Date.now()}-${Math.random()}`, timestamp: new Date(), label, detail },
62
+ ]);
63
+ }, []);
46
64
  // ── TanStack Query: fetch messages from backend ─────────────────────────
47
65
  const { data: chatState, isLoading: isChatLoading } = useQuery({
48
66
  queryKey: chatQueryKey(featureId),
@@ -57,6 +75,18 @@ export function useChatRuntime(featureId, worktreePath, options) {
57
75
  }, [chatState?.turnStatus, featureId]);
58
76
  const messages = useMemo(() => chatState?.messages ?? [], [chatState?.messages]);
59
77
  const sessionStatus = chatState?.sessionStatus ?? null;
78
+ // Track session status changes for debug
79
+ const prevSessionStatusRef = useRef(null);
80
+ useEffect(() => {
81
+ if (sessionStatus && sessionStatus !== prevSessionStatusRef.current) {
82
+ const info = chatState?.sessionInfo;
83
+ const detail = info
84
+ ? `model=${info.model ?? '?'}, sid=${info.sessionId?.slice(0, 8) ?? '?'}`
85
+ : undefined;
86
+ pushDebug(`session_${sessionStatus}`, detail);
87
+ }
88
+ prevSessionStatusRef.current = sessionStatus;
89
+ }, [sessionStatus, chatState?.sessionInfo, pushDebug]);
60
90
  const backendStreamingText = chatState?.streamingText ?? null;
61
91
  // Cache last known sessionInfo so PID stays visible after process exits
62
92
  const lastSessionInfoRef = useRef(null);
@@ -106,8 +136,17 @@ export function useChatRuntime(featureId, worktreePath, options) {
106
136
  // Ignore
107
137
  }
108
138
  });
109
- es.addEventListener('activity', () => {
139
+ es.addEventListener('activity', (event) => {
110
140
  cancelAwaiting();
141
+ try {
142
+ const data = JSON.parse(event.data);
143
+ if (data.activity) {
144
+ pushDebug(`[${data.activity.kind}] ${data.activity.label}`, data.activity.detail);
145
+ }
146
+ }
147
+ catch {
148
+ // Ignore
149
+ }
111
150
  // Tool events are already persisted to DB — just refetch to show them
112
151
  void queryClient.invalidateQueries({ queryKey: chatQueryKey(featureId) });
113
152
  });
@@ -117,6 +156,7 @@ export function useChatRuntime(featureId, worktreePath, options) {
117
156
  if (data.log) {
118
157
  cancelAwaiting();
119
158
  setStatusLog(data.log);
159
+ pushDebug('log', data.log);
120
160
  }
121
161
  }
122
162
  catch {
@@ -126,6 +166,7 @@ export function useChatRuntime(featureId, worktreePath, options) {
126
166
  es.addEventListener('done', () => {
127
167
  setStatusLog(null);
128
168
  cancelAwaiting();
169
+ pushDebug('turn_done');
129
170
  // Refetch first, THEN clear local streaming state so there's no gap
130
171
  void queryClient.invalidateQueries({ queryKey: chatQueryKey(featureId) }).then(() => {
131
172
  setStreamingText('');
@@ -138,11 +179,12 @@ export function useChatRuntime(featureId, worktreePath, options) {
138
179
  es.close();
139
180
  eventSourceRef.current = null;
140
181
  };
141
- }, [featureId, queryClient, cancelAwaiting]);
182
+ }, [featureId, queryClient, cancelAwaiting, pushDebug]);
142
183
  // ── Mutation: send user message ─────────────────────────────────────────
143
184
  const sendMutation = useMutation({
144
- mutationFn: (content) => postMessage(featureId, content, worktreePath ?? ''),
185
+ mutationFn: (content) => postMessage(featureId, content, worktreePath ?? '', modelRef.current, agentTypeRef.current),
145
186
  onMutate: async (content) => {
187
+ pushDebug('send_message', `model=${modelRef.current ?? 'default'}, agent=${agentTypeRef.current ?? 'default'}, len=${content.length}`);
146
188
  startAwaiting();
147
189
  // Cancel in-flight refetches so our optimistic update isn't overwritten
148
190
  await queryClient.cancelQueries({ queryKey: chatQueryKey(featureId) });
@@ -184,7 +226,47 @@ export function useChatRuntime(featureId, worktreePath, options) {
184
226
  // ── Build thread messages for assistant-ui ─────────────────────────────
185
227
  const activeStreamText = streamingText ?? backendStreamingText ?? '';
186
228
  const threadMessages = useMemo(() => {
187
- const result = messages.map(toThreadMessage);
229
+ const chatMessages = messages.map(toThreadMessage);
230
+ // Merge debug bubbles into the timeline by timestamp
231
+ let result;
232
+ if (options?.debugMode && debugEvents.length > 0) {
233
+ const debugMessages = debugEvents.map((evt) => ({
234
+ id: evt.id,
235
+ role: 'assistant',
236
+ content: [
237
+ {
238
+ type: 'text',
239
+ text: evt.detail ? `🔧 **${evt.label}** — ${evt.detail}` : `🔧 **${evt.label}**`,
240
+ },
241
+ ],
242
+ createdAt: evt.timestamp,
243
+ }));
244
+ // Merge both arrays (both already sorted by time) into one sorted list
245
+ result = [];
246
+ let ci = 0;
247
+ let di = 0;
248
+ while (ci < chatMessages.length && di < debugMessages.length) {
249
+ const chatTime = chatMessages[ci].createdAt
250
+ ? new Date(chatMessages[ci].createdAt).getTime()
251
+ : 0;
252
+ const dbgTime = debugMessages[di].createdAt
253
+ ? new Date(debugMessages[di].createdAt).getTime()
254
+ : 0;
255
+ if (chatTime <= dbgTime) {
256
+ result.push(chatMessages[ci++]);
257
+ }
258
+ else {
259
+ result.push(debugMessages[di++]);
260
+ }
261
+ }
262
+ while (ci < chatMessages.length)
263
+ result.push(chatMessages[ci++]);
264
+ while (di < debugMessages.length)
265
+ result.push(debugMessages[di++]);
266
+ }
267
+ else {
268
+ result = chatMessages;
269
+ }
188
270
  // Streaming text as the last message — may include a live activity suffix
189
271
  if (activeStreamText.trim()) {
190
272
  const parts = [{ type: 'text', text: activeStreamText }];
@@ -217,7 +299,15 @@ export function useChatRuntime(featureId, worktreePath, options) {
217
299
  });
218
300
  }
219
301
  return result;
220
- }, [messages, activeStreamText, awaitingResponse, sessionStatus, statusLog]);
302
+ }, [
303
+ messages,
304
+ activeStreamText,
305
+ awaitingResponse,
306
+ sessionStatus,
307
+ statusLog,
308
+ options?.debugMode,
309
+ debugEvents,
310
+ ]);
221
311
  // ── Status info for typing indicator ──────────────────────────────────
222
312
  const status = useMemo(() => {
223
313
  if (!isRunning)
@@ -242,6 +332,7 @@ export function useChatRuntime(featureId, worktreePath, options) {
242
332
  if (!res.ok)
243
333
  throw new Error(`Failed to clear chat: ${res.status}`);
244
334
  setStreamingText('');
335
+ setDebugEvents([]);
245
336
  setStatusLog(null);
246
337
  cancelAwaiting();
247
338
  void queryClient.invalidateQueries({ queryKey: chatQueryKey(featureId) });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/components/features/settings/AgentModelPicker/index.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,IAAI,GACL,EAAE,qBAAqB,2CAoNvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/components/features/settings/AgentModelPicker/index.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,IAAI,GACL,EAAE,qBAAqB,2CAqNvB"}
@@ -84,7 +84,7 @@ export function AgentModelPicker({ initialAgentType, initialModel, onAgentModelC
84
84
  const agentLabel = groups.find((g) => g.agentType === agentType)?.label ?? agentType;
85
85
  const modelName = model ? getModelMeta(model).displayName || model : null;
86
86
  const activeGroup = drillAgent ? groups.find((g) => g.agentType === drillAgent) : null;
87
- return (_jsxs("div", { className: cn('flex flex-col gap-1', className), children: [_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", role: "combobox", "aria-expanded": open, disabled: isDisabled, className: "w-auto cursor-pointer justify-start font-normal hover:border-violet-300 hover:bg-violet-50/50 dark:hover:border-violet-700 dark:hover:bg-violet-950/30", children: _jsxs("span", { className: "flex items-center gap-2 truncate", children: [_jsx(AgentIcon, { className: "h-4 w-4 shrink-0" }), loading ? ('Loading…') : (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs", children: agentLabel }), modelName ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-muted-foreground/50 text-xs", children: "\u00B7" }), _jsx("span", { className: "text-xs font-medium", children: modelName })] })) : null] }))] }) }) }), _jsx(PopoverContent, { className: "w-(--radix-popover-trigger-width) overflow-hidden p-0", align: "start", children: _jsxs("div", { className: "flex transition-transform duration-200 ease-in-out", style: { transform: `translateX(${level === 1 ? '-50%' : '0%'})`, width: '200%' }, children: [_jsxs("div", { className: "w-1/2 shrink-0", children: [_jsx("div", { className: "text-muted-foreground border-b px-3 py-2 text-xs font-medium", children: "Select agent" }), groups.map((group) => {
87
+ return (_jsxs("div", { className: cn('flex flex-col gap-1', className), children: [_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "outline", role: "combobox", "aria-expanded": open, disabled: isDisabled, className: "w-auto cursor-pointer justify-start font-normal hover:border-violet-300 hover:bg-violet-50/50 dark:hover:border-violet-700 dark:hover:bg-violet-950/30", children: _jsxs("span", { className: "flex items-center gap-2 truncate", children: [_jsx(AgentIcon, { className: "h-4 w-4 shrink-0" }), loading ? ('Loading…') : (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs", children: agentLabel }), modelName ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-muted-foreground/50 text-xs", children: "\u00B7" }), _jsx("span", { className: "text-xs font-medium", children: modelName })] })) : null] }))] }) }) }), _jsx(PopoverContent, { className: "z-[70] w-(--radix-popover-trigger-width) overflow-hidden p-0", align: "start", children: _jsxs("div", { className: "flex transition-transform duration-200 ease-in-out", style: { transform: `translateX(${level === 1 ? '-50%' : '0%'})`, width: '200%' }, children: [_jsxs("div", { className: "w-1/2 shrink-0", children: [_jsx("div", { className: "text-muted-foreground border-b px-3 py-2 text-xs font-medium", children: "Select agent" }), groups.map((group) => {
88
88
  const GroupIcon = getAgentTypeIcon(group.agentType);
89
89
  const isActive = agentType === group.agentType;
90
90
  const hasModels = group.models.length > 0;
@@ -1 +1 @@
1
- {"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAI/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAEhC,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,YAAY,EAEZ,cAAc,GACf,EAAE,eAAe,2CA6OjB"}
1
+ {"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAI/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAEhC,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,YAAY,EAEZ,cAAc,GACf,EAAE,eAAe,2CAqQjB"}