@shepai/cli 1.152.0 → 1.153.0-pr468.72ce36b

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 (263) hide show
  1. package/apis/json-schema/AgentType.yaml +1 -0
  2. package/dist/packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.d.ts +5 -0
  3. package/dist/packages/core/src/application/ports/output/repositories/interactive-session-repository.interface.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts +5 -0
  5. package/dist/packages/core/src/application/ports/output/services/interactive-session-service.interface.d.ts.map +1 -1
  6. package/dist/packages/core/src/domain/generated/output.d.ts +1 -0
  7. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  8. package/dist/packages/core/src/domain/generated/output.js +1 -0
  9. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  10. package/dist/packages/core/src/infrastructure/di/container.js +4 -0
  11. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts +1 -0
  12. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.d.ts.map +1 -1
  13. package/dist/packages/core/src/infrastructure/repositories/sqlite-interactive-session.repository.js +15 -0
  14. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts.map +1 -1
  15. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.js +22 -0
  16. package/dist/packages/core/src/infrastructure/services/agents/common/agent-validator.service.d.ts.map +1 -1
  17. package/dist/packages/core/src/infrastructure/services/agents/common/agent-validator.service.js +1 -0
  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 +8 -0
  20. package/dist/packages/core/src/infrastructure/services/agents/common/executors/codex-cli-executor.service.d.ts +65 -0
  21. package/dist/packages/core/src/infrastructure/services/agents/common/executors/codex-cli-executor.service.d.ts.map +1 -0
  22. package/dist/packages/core/src/infrastructure/services/agents/common/executors/codex-cli-executor.service.js +655 -0
  23. package/dist/packages/core/src/infrastructure/services/agents/sessions/codex-cli-session.repository.d.ts +62 -0
  24. package/dist/packages/core/src/infrastructure/services/agents/sessions/codex-cli-session.repository.d.ts.map +1 -0
  25. package/dist/packages/core/src/infrastructure/services/agents/sessions/codex-cli-session.repository.js +356 -0
  26. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts +1 -0
  27. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.d.ts.map +1 -1
  28. package/dist/packages/core/src/infrastructure/services/interactive/interactive-session.service.js +51 -5
  29. package/dist/src/presentation/tui/prompts/agent-select.prompt.d.ts +6 -2
  30. package/dist/src/presentation/tui/prompts/agent-select.prompt.d.ts.map +1 -1
  31. package/dist/src/presentation/tui/prompts/agent-select.prompt.js +7 -2
  32. package/dist/src/presentation/web/app/actions/get-all-agent-models.d.ts.map +1 -1
  33. package/dist/src/presentation/web/app/actions/get-all-agent-models.js +4 -2
  34. package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.d.ts +4 -5
  35. package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.d.ts.map +1 -1
  36. package/dist/src/presentation/web/app/api/interactive/chat/turn-statuses/route.js +5 -13
  37. package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.d.ts.map +1 -1
  38. package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.js +26 -1
  39. package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.d.ts +2 -0
  40. package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.d.ts.map +1 -1
  41. package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.js +21 -0
  42. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.d.ts +1 -1
  43. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.d.ts.map +1 -1
  44. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.js +2 -0
  45. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.d.ts.map +1 -1
  46. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.js +1 -0
  47. package/dist/src/presentation/web/components/common/floating-action-button/floating-action-button.d.ts +8 -2
  48. package/dist/src/presentation/web/components/common/floating-action-button/floating-action-button.d.ts.map +1 -1
  49. package/dist/src/presentation/web/components/common/floating-action-button/floating-action-button.js +10 -7
  50. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  51. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +2 -3
  52. package/dist/src/presentation/web/components/features/chat/ChatSheet.d.ts.map +1 -1
  53. package/dist/src/presentation/web/components/features/chat/ChatSheet.js +43 -30
  54. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  55. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +66 -3
  56. package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.d.ts +1 -6
  57. package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.d.ts.map +1 -1
  58. package/dist/src/presentation/web/components/features/features-canvas/canvas-toolbar.js +5 -6
  59. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +1 -1
  60. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts +1 -0
  61. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts.map +1 -1
  62. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.js +7 -0
  63. package/dist/src/presentation/web/components/features/settings/agent-settings-section.d.ts.map +1 -1
  64. package/dist/src/presentation/web/components/features/settings/agent-settings-section.js +1 -0
  65. package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts +1 -0
  66. package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts.map +1 -1
  67. package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.js +8 -0
  68. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.d.ts.map +1 -1
  69. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +9 -5
  70. package/dist/src/presentation/web/hooks/turn-statuses-provider.d.ts +4 -8
  71. package/dist/src/presentation/web/hooks/turn-statuses-provider.d.ts.map +1 -1
  72. package/dist/src/presentation/web/hooks/turn-statuses-provider.js +4 -4
  73. package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts +4 -5
  74. package/dist/src/presentation/web/hooks/use-turn-statuses.d.ts.map +1 -1
  75. package/dist/src/presentation/web/hooks/use-turn-statuses.js +7 -12
  76. package/dist/src/presentation/web/lib/parse-log-line.d.ts +1 -1
  77. package/dist/src/presentation/web/lib/parse-log-line.d.ts.map +1 -1
  78. package/dist/src/presentation/web/lib/parse-log-line.js +1 -1
  79. package/dist/tsconfig.build.tsbuildinfo +1 -1
  80. package/package.json +1 -1
  81. package/web/.next/BUILD_ID +1 -1
  82. package/web/.next/build-manifest.json +2 -2
  83. package/web/.next/fallback-build-manifest.json +2 -2
  84. package/web/.next/prerender-manifest.json +3 -3
  85. package/web/.next/required-server-files.js +3 -3
  86. package/web/.next/required-server-files.json +3 -3
  87. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
  88. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  89. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  90. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +26 -26
  91. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  92. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  93. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +29 -29
  94. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  95. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  96. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  97. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  98. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  99. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
  100. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  101. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  102. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +26 -26
  103. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  104. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  105. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  106. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  107. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  108. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +26 -26
  109. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  110. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  111. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +29 -29
  112. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  113. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  114. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  115. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  116. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  117. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
  118. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  119. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  120. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
  121. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  122. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  123. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +26 -26
  124. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  125. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  126. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  127. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  128. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  129. package/web/.next/server/app/_global-error.html +2 -2
  130. package/web/.next/server/app/_global-error.rsc +1 -1
  131. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  132. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  133. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  134. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  135. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  136. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +5 -5
  137. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  138. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  139. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  140. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  141. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  142. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  143. package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  144. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  145. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  146. package/web/.next/server/app/skills/page/server-reference-manifest.json +10 -10
  147. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  148. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  149. package/web/.next/server/app/tools/page/server-reference-manifest.json +10 -10
  150. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  151. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  152. package/web/.next/server/app/version/page/server-reference-manifest.json +5 -5
  153. package/web/.next/server/app/version/page.js.nft.json +1 -1
  154. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  155. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  156. package/web/.next/server/chunks/[root-of-the-server]__ab4951b1._.js +1 -1
  157. package/web/.next/server/chunks/[root-of-the-server]__ab4951b1._.js.map +1 -1
  158. package/web/.next/server/chunks/[root-of-the-server]__beda892a._.js +1 -1
  159. package/web/.next/server/chunks/[root-of-the-server]__beda892a._.js.map +1 -1
  160. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
  161. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  162. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  163. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  164. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +3 -3
  165. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  166. package/web/.next/server/chunks/ssr/[root-of-the-server]__0b150ddf._.js.map +1 -1
  167. package/web/.next/server/chunks/ssr/[root-of-the-server]__17ed7ed1._.js +1 -1
  168. package/web/.next/server/chunks/ssr/[root-of-the-server]__17ed7ed1._.js.map +1 -1
  169. package/web/.next/server/chunks/ssr/[root-of-the-server]__28d0d265._.js +2 -2
  170. package/web/.next/server/chunks/ssr/[root-of-the-server]__28d0d265._.js.map +1 -1
  171. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  172. package/web/.next/server/chunks/ssr/[root-of-the-server]__42bf1807._.js +1 -1
  173. package/web/.next/server/chunks/ssr/[root-of-the-server]__42bf1807._.js.map +1 -1
  174. package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js +1 -1
  175. package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js.map +1 -1
  176. package/web/.next/server/chunks/ssr/[root-of-the-server]__88f7e8e6._.js +1 -1
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__88f7e8e6._.js.map +1 -1
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js +1 -1
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js.map +1 -1
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__c30f1f82._.js +1 -1
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__c30f1f82._.js.map +1 -1
  182. package/web/.next/server/chunks/ssr/[root-of-the-server]__f80bfc75._.js +1 -1
  183. package/web/.next/server/chunks/ssr/[root-of-the-server]__f80bfc75._.js.map +1 -1
  184. package/web/.next/server/chunks/ssr/[root-of-the-server]__f8dd4422._.js +3 -0
  185. package/web/.next/server/chunks/ssr/[root-of-the-server]__f8dd4422._.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/_16eb4fec._.js +1 -1
  189. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  190. package/web/.next/server/chunks/ssr/_3a0b989f._.js +2 -2
  191. package/web/.next/server/chunks/ssr/_3a0b989f._.js.map +1 -1
  192. package/web/.next/server/chunks/ssr/{_cf1c5b73._.js → _45afffa1._.js} +2 -2
  193. package/web/.next/server/chunks/ssr/{_cf1c5b73._.js.map → _45afffa1._.js.map} +1 -1
  194. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  195. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  196. package/web/.next/server/chunks/ssr/_5f69c13f._.js +1 -1
  197. package/web/.next/server/chunks/ssr/_5f69c13f._.js.map +1 -1
  198. package/web/.next/server/chunks/ssr/_7c5b97c6._.js +1 -1
  199. package/web/.next/server/chunks/ssr/_7c5b97c6._.js.map +1 -1
  200. package/web/.next/server/chunks/ssr/_82c57f10._.js +1 -1
  201. package/web/.next/server/chunks/ssr/_82c57f10._.js.map +1 -1
  202. package/web/.next/server/chunks/ssr/_9495d50b._.js +1 -1
  203. package/web/.next/server/chunks/ssr/_9495d50b._.js.map +1 -1
  204. package/web/.next/server/chunks/ssr/_a0e3f7e4._.js +1 -1
  205. package/web/.next/server/chunks/ssr/_a0e3f7e4._.js.map +1 -1
  206. package/web/.next/server/chunks/ssr/_ac4a3873._.js +1 -1
  207. package/web/.next/server/chunks/ssr/_ca0aa7f0._.js +1 -1
  208. package/web/.next/server/chunks/ssr/_ca0aa7f0._.js.map +1 -1
  209. package/web/.next/server/chunks/ssr/_cb1b56ff._.js +3 -0
  210. package/web/.next/server/chunks/ssr/{_f78b4b9d._.js.map → _cb1b56ff._.js.map} +1 -1
  211. package/web/.next/server/chunks/ssr/_cb5a021e._.js +1 -1
  212. package/web/.next/server/chunks/ssr/_cb5a021e._.js.map +1 -1
  213. package/web/.next/server/chunks/ssr/{_5fce01a7._.js → _cb98ca72._.js} +2 -2
  214. package/web/.next/server/chunks/ssr/{_5fce01a7._.js.map → _cb98ca72._.js.map} +1 -1
  215. package/web/.next/server/chunks/ssr/_d4b20e29._.js.map +1 -1
  216. package/web/.next/server/chunks/ssr/_d86175ae._.js +1 -1
  217. package/web/.next/server/chunks/ssr/_d86175ae._.js.map +1 -1
  218. package/web/.next/server/chunks/ssr/_d8bedf13._.js +1 -1
  219. package/web/.next/server/chunks/ssr/_d8bedf13._.js.map +1 -1
  220. package/web/.next/server/chunks/ssr/_e9a73a63._.js +1 -1
  221. package/web/.next/server/chunks/ssr/_e9a73a63._.js.map +1 -1
  222. package/web/.next/server/chunks/ssr/_fa7efce3._.js +2 -2
  223. package/web/.next/server/chunks/ssr/_fa7efce3._.js.map +1 -1
  224. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  225. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/src_presentation_web_324a47da._.js +3 -0
  227. package/web/.next/server/chunks/ssr/src_presentation_web_324a47da._.js.map +1 -0
  228. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_cdc632e3.js +1 -1
  229. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_cdc632e3.js.map +1 -1
  230. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_39ca0924.js +1 -1
  231. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_39ca0924.js.map +1 -1
  232. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  233. package/web/.next/server/chunks/ssr/src_presentation_web_components_357e3eb0._.js +1 -1
  234. package/web/.next/server/chunks/ssr/src_presentation_web_components_357e3eb0._.js.map +1 -1
  235. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  236. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  237. package/web/.next/server/pages/500.html +2 -2
  238. package/web/.next/server/server-reference-manifest.js +1 -1
  239. package/web/.next/server/server-reference-manifest.json +45 -45
  240. package/web/.next/static/chunks/{a2257ffb1349f838.js → 19e276d1db01686c.js} +1 -1
  241. package/web/.next/static/chunks/{bdd340ad42a34b41.js → 2d971ae371d47be6.js} +1 -1
  242. package/web/.next/static/chunks/{f9a80d3854a8d453.js → 56b4a56ab5ec232c.js} +1 -1
  243. package/web/.next/static/chunks/{277a7f64d4ec189d.js → 644d66ef35bcf689.js} +1 -1
  244. package/web/.next/static/chunks/{80c4c8b3a5c8e0b6.js → 6b21720f1af9d81d.js} +1 -1
  245. package/web/.next/static/chunks/6e873694566b5b29.js +1 -0
  246. package/web/.next/static/chunks/812aef7275df9f5c.js +1 -0
  247. package/web/.next/static/chunks/8590bd2e69b24b9e.css +1 -0
  248. package/web/.next/static/chunks/{ef1c9f43aafff65f.js → 8ad4f8b8b02e48e3.js} +3 -3
  249. package/web/.next/static/chunks/{6bf775818e4ad42e.js → a02bfd8c7a760ec5.js} +1 -1
  250. package/web/.next/static/chunks/bc7522e582566e5b.js +7 -0
  251. package/web/.next/static/chunks/{1b4429259bbf3064.js → c054c1cf57e444e3.js} +2 -2
  252. package/web/.next/static/chunks/{f33efe6a12242a8a.js → e6564e0bc86474b2.js} +1 -1
  253. package/web/public/icons/agents/openai.svg +3 -0
  254. package/web/.next/server/chunks/ssr/[root-of-the-server]__563f2f7a._.js +0 -3
  255. package/web/.next/server/chunks/ssr/[root-of-the-server]__563f2f7a._.js.map +0 -1
  256. package/web/.next/server/chunks/ssr/_f78b4b9d._.js +0 -3
  257. package/web/.next/static/chunks/4908997348bd55f8.js +0 -1
  258. package/web/.next/static/chunks/76858a51f2fbe99a.js +0 -7
  259. package/web/.next/static/chunks/a919a9df4ab12a5c.css +0 -1
  260. package/web/.next/static/chunks/ee20803fb301d59e.js +0 -1
  261. /package/web/.next/static/{lPbWG8a1RwBDDcvRngp58 → k_Awt-2YfRvvLIUlgT2bA}/_buildManifest.js +0 -0
  262. /package/web/.next/static/{lPbWG8a1RwBDDcvRngp58 → k_Awt-2YfRvvLIUlgT2bA}/_clientMiddlewareManifest.json +0 -0
  263. /package/web/.next/static/{lPbWG8a1RwBDDcvRngp58 → k_Awt-2YfRvvLIUlgT2bA}/_ssgManifest.js +0 -0
@@ -1,26 +1,18 @@
1
1
  /**
2
2
  * Bulk turn-status API.
3
3
  *
4
- * GET /api/interactive/chat/turn-statuses?featureIds=id1,id2,...
4
+ * GET /api/interactive/chat/turn-statuses
5
5
  *
6
- * Returns a map of featureId turnStatus ('idle' | 'processing' | 'unread')
7
- * for all requested features. Used by UI dot indicators on chat buttons.
6
+ * Returns ALL non-idle turn statuses as { featureId: turnStatus }.
7
+ * No parameters needed the backend knows which sessions are active.
8
8
  */
9
9
  import { NextResponse } from 'next/server';
10
10
  import { resolve } from '../../../../../lib/server-container.js';
11
11
  export const dynamic = 'force-dynamic';
12
- export async function GET(request) {
12
+ export async function GET() {
13
13
  try {
14
- const featureIdsParam = request.nextUrl.searchParams.get('featureIds');
15
- if (!featureIdsParam) {
16
- return NextResponse.json({});
17
- }
18
- const featureIds = featureIdsParam.split(',').filter(Boolean);
19
- if (featureIds.length === 0) {
20
- return NextResponse.json({});
21
- }
22
14
  const service = resolve('IInteractiveSessionService');
23
- const statuses = await service.getTurnStatuses(featureIds);
15
+ const statuses = await service.getAllActiveTurnStatuses();
24
16
  // Convert Map to plain object for JSON serialization
25
17
  const result = {};
26
18
  for (const [id, status] of statuses) {
@@ -1 +1 @@
1
- {"version":3,"file":"event-log-viewer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.tsx"],"names":[],"mappings":"AAwBA,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,mBAAmB,kDAa9D"}
1
+ {"version":3,"file":"event-log-viewer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.tsx"],"names":[],"mappings":"AA2BA,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,mBAAmB,kDAa9D"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useMemo } from 'react';
4
- import { FileText, Terminal, MessageSquare, CheckCircle2, Coins, Server, FileCode, } from 'lucide-react';
4
+ import { FileText, Terminal, MessageSquare, CheckCircle2, Coins, Server, FileCode, Play, ArrowRight, AlertCircle, } from 'lucide-react';
5
5
  import { parseLogContent, parseToolCall, parseResultMessage, parseTokensMessage, } from '../../../lib/parse-log-line.js';
6
6
  export function EventLogViewer({ content }) {
7
7
  const lines = useMemo(() => parseLogContent(content), [content]);
@@ -18,12 +18,25 @@ function LogLineRow({ line }) {
18
18
  switch (line.tag) {
19
19
  case 'tool':
20
20
  return _jsx(ToolCallRow, { line: line });
21
+ case 'tool-result':
22
+ return _jsx(ToolResultRow, { line: line });
21
23
  case 'text':
24
+ case 'delta':
22
25
  return _jsx(TextRow, { line: line });
23
26
  case 'result':
24
27
  return _jsx(ResultRow, { line: line });
25
28
  case 'tokens':
29
+ case 'turn':
26
30
  return _jsx(TokensRow, { line: line });
31
+ case 'cmd':
32
+ return _jsx(CommandRow, { line: line });
33
+ case 'file':
34
+ return _jsx(FileChangeRow, { line: line });
35
+ case 'thread':
36
+ case 'event':
37
+ return _jsx(InfoRow, { line: line });
38
+ case 'error':
39
+ return _jsx(ErrorRow, { line: line });
27
40
  case 'worker':
28
41
  return _jsx(WorkerRow, { line: line });
29
42
  case 'info':
@@ -109,6 +122,18 @@ function TokensRow({ line }) {
109
122
  function WorkerRow({ line }) {
110
123
  return (_jsxs("div", { className: "hover:bg-muted/50 flex items-start gap-2 bg-zinc-50 px-3 py-1.5 transition-colors dark:bg-zinc-900/50", children: [_jsx(Timestamp, { value: line.timestamp }), _jsx(PhaseBadge, { phase: line.phase }), _jsxs("div", { className: "flex min-w-0 flex-1 items-start gap-1.5", children: [_jsx(Server, { className: "mt-0.5 h-3 w-3 shrink-0 text-zinc-500" }), _jsx("span", { className: "text-muted-foreground text-xs font-medium break-all", children: line.message })] })] }));
111
124
  }
125
+ function ToolResultRow({ line }) {
126
+ return (_jsxs("div", { className: "hover:bg-muted/50 flex items-start gap-2 px-3 py-1 transition-colors", children: [_jsx(Timestamp, { value: line.timestamp }), _jsx(PhaseBadge, { phase: line.phase }), _jsxs("div", { className: "flex min-w-0 flex-1 items-start gap-1.5", children: [_jsx(ArrowRight, { className: "mt-0.5 h-3 w-3 shrink-0 text-violet-400" }), _jsx("span", { className: "text-muted-foreground min-w-0 font-mono text-[11px] break-all", children: line.message })] })] }));
127
+ }
128
+ function CommandRow({ line }) {
129
+ return (_jsxs("div", { className: "hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors", children: [_jsx(Timestamp, { value: line.timestamp }), _jsx(PhaseBadge, { phase: line.phase }), _jsxs("div", { className: "flex min-w-0 flex-1 items-start gap-1.5", children: [_jsx(Play, { className: "mt-0.5 h-3 w-3 shrink-0 text-cyan-500" }), _jsx("span", { className: "min-w-0 font-mono text-xs break-all text-cyan-700 dark:text-cyan-400", children: line.message })] })] }));
130
+ }
131
+ function FileChangeRow({ line }) {
132
+ return (_jsxs("div", { className: "hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors", children: [_jsx(Timestamp, { value: line.timestamp }), _jsx(PhaseBadge, { phase: line.phase }), _jsxs("div", { className: "flex min-w-0 flex-1 items-start gap-1.5", children: [_jsx(FileCode, { className: "mt-0.5 h-3 w-3 shrink-0 text-orange-500" }), _jsx("span", { className: "min-w-0 text-xs break-all text-orange-700 dark:text-orange-400", children: line.message })] })] }));
133
+ }
134
+ function ErrorRow({ line }) {
135
+ return (_jsxs("div", { className: "hover:bg-muted/50 flex items-start gap-2 bg-red-50 px-3 py-1.5 transition-colors dark:bg-red-950/30", children: [_jsx(Timestamp, { value: line.timestamp }), _jsx(PhaseBadge, { phase: line.phase }), _jsxs("div", { className: "flex min-w-0 flex-1 items-start gap-1.5", children: [_jsx(AlertCircle, { className: "mt-0.5 h-3 w-3 shrink-0 text-red-500" }), _jsx("span", { className: "min-w-0 text-xs font-medium break-all text-red-700 dark:text-red-400", children: line.message })] })] }));
136
+ }
112
137
  function InfoRow({ line }) {
113
138
  return (_jsxs("div", { className: "hover:bg-muted/50 flex items-start gap-2 px-3 py-1.5 transition-colors", children: [_jsx(Timestamp, { value: line.timestamp }), _jsx(PhaseBadge, { phase: line.phase }), _jsx("span", { className: "text-muted-foreground min-w-0 text-xs break-all", children: line.message })] }));
114
139
  }
@@ -13,6 +13,8 @@ export declare const WorkerLifecycle: Story;
13
13
  export declare const ResultsAndTokens: Story;
14
14
  /** MixedContent — all event types including raw fallback */
15
15
  export declare const MixedContent: Story;
16
+ /** CodexCliSession — Codex CLI agent log with all event types */
17
+ export declare const CodexCliSession: Story;
16
18
  /** EmptyContent — no content */
17
19
  export declare const EmptyContent: Story;
18
20
  //# sourceMappingURL=event-log-viewer.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-log-viewer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAqBrC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,cAAc,CAAC,CAAC;AAsD7C,0CAA0C;AAC1C,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,eAAe,EAAE,KAE7B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF,gCAAgC;AAChC,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC"}
1
+ {"version":3,"file":"event-log-viewer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAqBrC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,cAAc,CAAC,CAAC;AAsD7C,0CAA0C;AAC1C,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,eAAe,EAAE,KAE7B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,eAAe,EAAE,KAmB7B,CAAC;AAEF,gCAAgC;AAChC,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC"}
@@ -82,6 +82,27 @@ export const ResultsAndTokens = {
82
82
  export const MixedContent = {
83
83
  args: { content: mixedContent },
84
84
  };
85
+ /** CodexCliSession — Codex CLI agent log with all event types */
86
+ export const CodexCliSession = {
87
+ args: {
88
+ content: `[2026-03-26T10:00:01.000Z] [codex-cli|gpt-5.4] [WORKER] Starting worker — full command:
89
+ [2026-03-26T10:00:01.010Z] [codex-cli|gpt-5.4] [WORKER] Initializing container...
90
+ [2026-03-26T10:00:02.000Z] [implement] [codex-cli|gpt-5.4] [thread] started thread_id=019d2aff-a65f-7253
91
+ [2026-03-26T10:00:03.000Z] [implement] [codex-cli|gpt-5.4] [text] I'll investigate the login page authentication bug. Let me check the auth module first.
92
+ [2026-03-26T10:00:04.000Z] [implement] [codex-cli|gpt-5.4] [tool] exec_command {"cmd":"cat src/auth.ts"}
93
+ [2026-03-26T10:00:05.000Z] [implement] [codex-cli|gpt-5.4] [tool-result] export function login(user: string, pass: string) { return validateToken(user, pass); }
94
+ [2026-03-26T10:00:06.000Z] [implement] [codex-cli|gpt-5.4] [cmd] running: cat src/auth.ts
95
+ [2026-03-26T10:00:07.000Z] [implement] [codex-cli|gpt-5.4] [cmd] exit=0 output: export function login...
96
+ [2026-03-26T10:00:08.000Z] [implement] [codex-cli|gpt-5.4] [delta] Found the issue. The token validation
97
+ [2026-03-26T10:00:09.000Z] [implement] [codex-cli|gpt-5.4] [text] Found the issue. The token validation was missing a null check. I've fixed it.
98
+ [2026-03-26T10:00:10.000Z] [implement] [codex-cli|gpt-5.4] [file] modifying: src/auth.ts
99
+ [2026-03-26T10:00:11.000Z] [implement] [codex-cli|gpt-5.4] [file] modified: src/auth.ts
100
+ [2026-03-26T10:00:12.000Z] [implement] [codex-cli|gpt-5.4] [tokens] 2450 in / 4560 out
101
+ [2026-03-26T10:00:13.000Z] [implement] [codex-cli|gpt-5.4] [turn] completed
102
+ [2026-03-26T10:00:14.000Z] [implement] [codex-cli|gpt-5.4] [error] Rate limit exceeded — retrying in 5s
103
+ [2026-03-26T10:00:20.000Z] [implement] [codex-cli|gpt-5.4] [result] 3200 chars, session=019d2aff-a65f-7253`,
104
+ },
105
+ };
85
106
  /** EmptyContent — no content */
86
107
  export const EmptyContent = {
87
108
  args: { content: '' },
@@ -1,6 +1,6 @@
1
1
  import type { ComponentType, SVGProps } from 'react';
2
2
  /** Agent type values mirroring the TypeSpec AgentType enum. */
3
- export type AgentTypeValue = 'claude-code' | 'cursor' | 'gemini-cli' | 'aider' | 'continue' | 'dev';
3
+ export type AgentTypeValue = 'claude-code' | 'codex-cli' | 'cursor' | 'gemini-cli' | 'aider' | 'continue' | 'dev';
4
4
  type IconProps = SVGProps<SVGSVGElement> & {
5
5
  className?: string;
6
6
  };
@@ -1 +1 @@
1
- {"version":3,"file":"agent-type-icons.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/agent-type-icons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAIrD,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,UAAU,GAAG,KAAK,CAAC;AAEpG,KAAK,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAmBlE,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,2CAOhD;AA2DD,6CAA6C;AAC7C,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAO1D,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAK7E"}
1
+ {"version":3,"file":"agent-type-icons.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/agent-type-icons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAIrD,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,WAAW,GACX,QAAQ,GACR,YAAY,GACZ,OAAO,GACP,UAAU,GACV,KAAK,CAAC;AAEV,KAAK,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAmBlE,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,2CAOhD;AA4DD,6CAA6C;AAC7C,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAQ1D,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAK7E"}
@@ -20,6 +20,7 @@ function DevAgentIcon({ className, ...props }) {
20
20
  DevAgentIcon.displayName = 'DevAgentIcon';
21
21
  const agentTypeIconMap = {
22
22
  'claude-code': createBrandIcon('/icons/agents/claude-ai-icon.svg', 'Claude Code'),
23
+ 'codex-cli': createBrandIcon('/icons/agents/openai.svg', 'Codex CLI'),
23
24
  cursor: createBrandIcon('/icons/agents/cursor.jpeg', 'Cursor'),
24
25
  'gemini-cli': createBrandIcon('/icons/agents/gemini-cli.jpeg', 'Gemini CLI'),
25
26
  aider: createBrandIcon('/icons/agents/aider.png', 'Aider'),
@@ -29,6 +30,7 @@ const agentTypeIconMap = {
29
30
  /** Human-readable labels for agent types. */
30
31
  export const agentTypeLabels = {
31
32
  'claude-code': 'Claude Code',
33
+ 'codex-cli': 'Codex CLI',
32
34
  cursor: 'Cursor',
33
35
  'gemini-cli': 'Gemini CLI',
34
36
  aider: 'Aider',
@@ -1 +1 @@
1
- {"version":3,"file":"agent-type-icons.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/agent-type-icons.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAyCvD,QAAA,MAAM,IAAI,EAAE,IAIX,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAa1B,CAAC"}
1
+ {"version":3,"file":"agent-type-icons.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/agent-type-icons.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AA0CvD,QAAA,MAAM,IAAI,EAAE,IAIX,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAa1B,CAAC"}
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { getAgentTypeIcon, DefaultAgentIcon } from './agent-type-icons.js';
3
3
  const allAgentTypes = [
4
4
  { type: 'claude-code', label: 'Claude Code' },
5
+ { type: 'codex-cli', label: 'Codex CLI' },
5
6
  { type: 'cursor', label: 'Cursor' },
6
7
  { type: 'gemini-cli', label: 'Gemini CLI' },
7
8
  { type: 'aider', label: 'Aider' },
@@ -16,8 +16,14 @@ export interface FloatingActionButtonAction {
16
16
  export interface FloatingActionButtonProps {
17
17
  /** Action items shown when the FAB is expanded. */
18
18
  actions: FloatingActionButtonAction[];
19
- /** Additional CSS classes for the container. */
19
+ /** Additional CSS classes for the wrapper. */
20
20
  className?: string;
21
+ /** Inline styles for the wrapper (e.g. dynamic positioning). */
22
+ style?: React.CSSProperties;
21
23
  }
22
- export declare function FloatingActionButton({ actions, className }: FloatingActionButtonProps): import("react/jsx-runtime").JSX.Element;
24
+ /**
25
+ * (+) FAB with expandable action menu.
26
+ * Renders inline — parent controls positioning.
27
+ */
28
+ export declare function FloatingActionButton({ actions, className, style }: FloatingActionButtonProps): import("react/jsx-runtime").JSX.Element;
23
29
  //# sourceMappingURL=floating-action-button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"floating-action-button.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/floating-action-button/floating-action-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,MAAM,WAAW,0BAA0B;IACzC,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,yCAAyC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,mDAAmD;IACnD,OAAO,EAAE,0BAA0B,EAAE,CAAC;IACtC,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,yBAAyB,2CA2GrF"}
1
+ {"version":3,"file":"floating-action-button.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/floating-action-button/floating-action-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,MAAM,WAAW,0BAA0B;IACzC,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,yCAAyC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,mDAAmD;IACnD,OAAO,EAAE,0BAA0B,EAAE,CAAC;IACtC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAQD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,yBAAyB,2CAyG5F"}
@@ -8,7 +8,11 @@ import { Button } from '../../ui/button.js';
8
8
  const STAGGER_MS = 50;
9
9
  /** Total animation duration in ms. */
10
10
  const DURATION_MS = 250;
11
- export function FloatingActionButton({ actions, className }) {
11
+ /**
12
+ * (+) FAB with expandable action menu.
13
+ * Renders inline — parent controls positioning.
14
+ */
15
+ export function FloatingActionButton({ actions, className, style }) {
12
16
  const [open, setOpen] = useState(false);
13
17
  // Close on Escape key
14
18
  useEffect(() => {
@@ -22,14 +26,13 @@ export function FloatingActionButton({ actions, className }) {
22
26
  document.addEventListener('keydown', handleKeyDown);
23
27
  return () => document.removeEventListener('keydown', handleKeyDown);
24
28
  }, [open]);
25
- return (_jsxs(_Fragment, { children: [open ? (_jsx("div", { "data-testid": "fab-overlay", className: "fixed inset-0 z-40", onClick: () => setOpen(false), "aria-hidden": "true" })) : null, _jsxs("div", { "data-testid": "floating-action-button", className: cn('fixed right-6 bottom-6 z-50', className), children: [_jsx("div", { className: cn('absolute right-[calc(100%+12px)] bottom-0 flex flex-col items-end gap-2', !open && 'pointer-events-none'), "data-testid": "fab-actions", children: actions.map((action, i) => {
29
+ return (_jsxs(_Fragment, { children: [open ? (_jsx("div", { "data-testid": "fab-overlay", className: "fixed inset-0 z-40", onClick: () => setOpen(false), "aria-hidden": "true" })) : null, _jsxs("div", { "data-testid": "floating-action-button", className: cn('relative z-50', className), style: style, children: [_jsx("div", { className: cn('absolute bottom-[calc(100%+24px)] left-0 flex flex-col items-start gap-2', !open && 'pointer-events-none'), "data-testid": "fab-actions", children: actions.map((action, i) => {
26
30
  const openDelay = (actions.length - 1 - i) * STAGGER_MS;
27
- const closeDelay = i * STAGGER_MS;
28
- return (_jsxs("button", { "data-testid": `fab-action-${action.id}`, "aria-label": action.label, disabled: action.disabled ?? action.loading, className: cn('flex h-12 w-52 items-center justify-center gap-3 rounded-full px-4', 'bg-background text-foreground shadow-sm', 'border-border border', 'hover:bg-accent hover:text-accent-foreground', 'disabled:pointer-events-none disabled:opacity-50', open ? 'translate-x-0 opacity-100' : 'pointer-events-none translate-x-0 opacity-0'), style: {
29
- transition: `opacity ${open ? DURATION_MS : 150}ms ease-out ${open ? openDelay : closeDelay}ms`,
31
+ return (_jsxs("button", { "data-testid": `fab-action-${action.id}`, "aria-label": action.label, disabled: action.disabled ?? action.loading, className: cn('flex h-10 items-center gap-2.5 rounded-full px-4', 'bg-background text-foreground shadow-md', 'border-border border', 'hover:bg-accent hover:text-accent-foreground', 'disabled:pointer-events-none disabled:opacity-50', 'text-sm font-medium whitespace-nowrap', open ? 'translate-y-0 opacity-100' : 'pointer-events-none translate-y-0 opacity-0'), style: {
32
+ transition: `opacity ${open ? DURATION_MS : 120}ms ease-out ${open ? openDelay : 0}ms, transform ${open ? DURATION_MS : 120}ms ease-out ${open ? openDelay : 0}ms`,
30
33
  }, onClick: () => {
31
34
  action.onClick();
32
35
  setOpen(false);
33
- }, children: [_jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: action.loading ? _jsx(Loader2, { className: "h-5 w-5 animate-spin" }) : action.icon }), _jsx("span", { className: "text-sm font-medium whitespace-nowrap", children: action.label })] }, action.id));
34
- }) }), _jsx("div", { className: "flex items-center", children: _jsxs(Button, { size: "icon", "data-testid": "fab-trigger", "aria-label": open ? 'Close actions' : 'Open actions', className: cn('relative h-14 w-14 rounded-full shadow-lg', 'bg-indigo-500 text-white hover:bg-indigo-400 dark:bg-indigo-500 dark:hover:bg-indigo-400', 'transition-all duration-200 hover:scale-105 hover:shadow-xl active:scale-95'), onClick: () => setOpen((prev) => !prev), children: [_jsx(Plus, { className: cn('absolute h-8 w-8 stroke-[2.5] transition-all', open ? 'scale-0 rotate-90 opacity-0' : 'scale-100 rotate-0 opacity-100'), style: { transitionDuration: `${DURATION_MS}ms` } }), _jsx(X, { className: cn('absolute h-8 w-8 stroke-[2.5] transition-all', open ? 'scale-100 rotate-0 opacity-100' : 'scale-0 -rotate-90 opacity-0'), style: { transitionDuration: `${DURATION_MS}ms` } })] }) })] })] }));
36
+ }, children: [_jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center", children: action.loading ? _jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : action.icon }), _jsx("span", { children: action.label })] }, action.id));
37
+ }) }), _jsxs(Button, { size: "icon", "data-testid": "fab-trigger", "aria-label": open ? 'Close actions' : 'Create new', className: cn('relative h-14 w-14 rounded-full shadow-lg', 'bg-indigo-500 text-white hover:bg-indigo-400 dark:bg-indigo-500 dark:hover:bg-indigo-400', 'transition-all duration-200 hover:scale-105 hover:shadow-xl active:scale-95'), onClick: () => setOpen((prev) => !prev), children: [_jsx(Plus, { className: cn('absolute h-7 w-7 stroke-[2.5] transition-all', open ? 'scale-0 rotate-90 opacity-0' : 'scale-100 rotate-0 opacity-100'), style: { transitionDuration: `${DURATION_MS}ms` } }), _jsx(X, { className: cn('absolute h-6 w-6 stroke-[2.5] transition-all', open ? 'scale-100 rotate-0 opacity-100' : 'scale-0 -rotate-90 opacity-0'), style: { transitionDuration: `${DURATION_MS}ms` } })] })] })] }));
35
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAicA"}
1
+ {"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAgcA"}
@@ -13,15 +13,14 @@ import { useDeployAction } from '../../../hooks/use-deploy-action.js';
13
13
  import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
14
14
  import { useRepositoryActions } from './use-repository-actions.js';
15
15
  import { ChatDotIndicator } from '../../features/chat/ChatDotIndicator.js';
16
- import { useTurnStatuses } from '../../../hooks/use-turn-statuses.js';
16
+ import { useTurnStatus } from '../../../hooks/turn-statuses-provider.js';
17
17
  import { FeatureSessionsDropdown, } from '../../common/feature-node/feature-sessions-dropdown.js';
18
18
  export function RepositoryNode({ data, selected, }) {
19
19
  const router = useRouter();
20
20
  const featureFlags = useFeatureFlags();
21
21
  const [confirmOpen, setConfirmOpen] = useState(false);
22
22
  const repoScopeId = data.id ? `repo-${data.id}` : `repo-${data.name}`;
23
- const turnStatuses = useTurnStatuses([repoScopeId]);
24
- const chatTurnStatus = turnStatuses[repoScopeId] ?? 'idle';
23
+ const chatTurnStatus = useTurnStatus(repoScopeId);
25
24
  const actions = useRepositoryActions(data.repositoryPath ? { repositoryId: data.id, repositoryPath: data.repositoryPath } : null);
26
25
  const deployAction = useDeployAction(data.repositoryPath
27
26
  ? {
@@ -1 +1 @@
1
- {"version":3,"file":"ChatSheet.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatSheet.tsx"],"names":[],"mappings":"AAmDA,wBAAgB,eAAe,4CAyX9B"}
1
+ {"version":3,"file":"ChatSheet.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatSheet.tsx"],"names":[],"mappings":"AAwDA,wBAAgB,eAAe,4CA+X9B"}
@@ -19,9 +19,14 @@ function loadPersistedState() {
19
19
  if (!raw)
20
20
  return { pos: null, size: null };
21
21
  const parsed = JSON.parse(raw);
22
+ let size = parsed.size ?? null;
23
+ // Clamp persisted size to minimums — prevents invisible panel from bad state
24
+ if (size && (size.w < MIN_W || size.h < MIN_H)) {
25
+ size = { w: Math.max(MIN_W, size.w), h: Math.max(MIN_H, size.h) };
26
+ }
22
27
  return {
23
28
  pos: parsed.pos ?? null,
24
- size: parsed.size ?? null,
29
+ size,
25
30
  };
26
31
  }
27
32
  catch {
@@ -119,13 +124,24 @@ export function GlobalChatPopup() {
119
124
  const timer = setTimeout(() => persistState(pos, size), 300);
120
125
  return () => clearTimeout(timer);
121
126
  }, [pos, size]);
127
+ /** Clamp position so the header (top 48px) stays within viewport. */
128
+ const clampPos = useCallback((x, y, w) => {
129
+ const vw = window.innerWidth;
130
+ const vh = window.innerHeight;
131
+ const HEADER_H = 48;
132
+ return {
133
+ // Keep at least 100px of width visible horizontally
134
+ x: Math.max(-w + 100, Math.min(x, vw - 100)),
135
+ // Keep header on screen: top >= 0, top <= viewport - header height
136
+ y: Math.max(0, Math.min(y, vh - HEADER_H)),
137
+ };
138
+ }, []);
122
139
  // ── Drag handling ──────────────────────────────────────────────────────
123
140
  const onDragStart = useCallback((e) => {
124
141
  e.preventDefault();
125
142
  const panel = panelRef.current;
126
143
  if (!panel)
127
144
  return;
128
- // If no custom position yet, compute from current DOM position
129
145
  const rect = panel.getBoundingClientRect();
130
146
  const currentX = pos?.x ?? rect.left;
131
147
  const currentY = pos?.y ?? rect.top;
@@ -135,15 +151,13 @@ export function GlobalChatPopup() {
135
151
  startPosX: currentX,
136
152
  startPosY: currentY,
137
153
  };
154
+ const panelW = size?.w ?? rect.width;
138
155
  const onMove = (ev) => {
139
156
  if (!dragRef.current)
140
157
  return;
141
158
  const dx = ev.clientX - dragRef.current.startX;
142
159
  const dy = ev.clientY - dragRef.current.startY;
143
- setPos({
144
- x: dragRef.current.startPosX + dx,
145
- y: dragRef.current.startPosY + dy,
146
- });
160
+ setPos(clampPos(dragRef.current.startPosX + dx, dragRef.current.startPosY + dy, panelW));
147
161
  };
148
162
  const onUp = () => {
149
163
  dragRef.current = null;
@@ -152,7 +166,7 @@ export function GlobalChatPopup() {
152
166
  };
153
167
  document.addEventListener('mousemove', onMove);
154
168
  document.addEventListener('mouseup', onUp);
155
- }, [pos, setPos]);
169
+ }, [pos, size, setPos, clampPos]);
156
170
  // ── Resize handling (from top-right corner) ────────────────────────────
157
171
  const onResizeStart = useCallback((e) => {
158
172
  e.preventDefault();
@@ -161,29 +175,27 @@ export function GlobalChatPopup() {
161
175
  if (!panel)
162
176
  return;
163
177
  const rect = panel.getBoundingClientRect();
164
- resizeRef.current = {
165
- startX: e.clientX,
166
- startY: e.clientY,
167
- startW: size?.w ?? rect.width,
168
- startH: size?.h ?? rect.height,
169
- };
170
- // Also capture position if not set yet
178
+ const startW = size?.w ?? rect.width;
179
+ const startH = size?.h ?? rect.height;
180
+ const startX = e.clientX;
181
+ const startY = e.clientY;
182
+ const startPosY = pos?.y ?? rect.top;
183
+ resizeRef.current = { startX, startY, startW, startH };
184
+ // Capture position if not set yet
171
185
  if (!pos) {
172
186
  setPos({ x: rect.left, y: rect.top });
173
187
  }
174
188
  const onMove = (ev) => {
175
189
  if (!resizeRef.current)
176
190
  return;
177
- const dx = ev.clientX - resizeRef.current.startX;
178
- const dy = ev.clientY - resizeRef.current.startY;
179
- setSize({
180
- w: Math.max(MIN_W, resizeRef.current.startW + dx),
181
- h: Math.max(MIN_H, resizeRef.current.startH - dy),
182
- });
183
- // Move top edge up as height increases
184
- if (pos) {
185
- setPos((prev) => (prev ? { ...prev, y: (prev.y ?? 0) + dy } : prev));
186
- }
191
+ const dx = ev.clientX - startX;
192
+ const dy = ev.clientY - startY;
193
+ const newW = Math.max(MIN_W, startW + dx);
194
+ const newH = Math.max(MIN_H, startH - dy);
195
+ // Top edge moves with height change, clamped to viewport
196
+ const newY = Math.max(0, startPosY + dy);
197
+ setSize({ w: newW, h: newH });
198
+ setPos((prev) => clampPos(prev?.x ?? rect.left, newY, newW));
187
199
  };
188
200
  const onUp = () => {
189
201
  resizeRef.current = null;
@@ -192,7 +204,7 @@ export function GlobalChatPopup() {
192
204
  };
193
205
  document.addEventListener('mousemove', onMove);
194
206
  document.addEventListener('mouseup', onUp);
195
- }, [size, pos, setPos, setSize]);
207
+ }, [size, pos, setPos, setSize, clampPos]);
196
208
  // Reset position/size on close for clean reopen
197
209
  const handleClose = useCallback(() => {
198
210
  setIsOpen(false);
@@ -214,8 +226,8 @@ export function GlobalChatPopup() {
214
226
  height: size?.h ?? `${DEFAULT_H_VH}vh`,
215
227
  };
216
228
  return (_jsxs(_Fragment, { children: [hasOpened ? (_jsxs("div", { ref: panelRef, className: cn(isMaximized
217
- ? 'bg-background absolute inset-0 z-30 flex flex-col overflow-hidden dark:bg-neutral-900'
218
- : cn(!pos && 'absolute bottom-24 left-4', 'z-30 flex flex-col overflow-hidden rounded-lg', 'border-border/60 border dark:border-white/10', 'bg-background dark:bg-neutral-900', 'shadow-[0_8px_40px_-8px_rgba(0,0,0,0.2)] dark:shadow-[0_8px_40px_-8px_rgba(0,0,0,0.6)]'), 'transition-opacity duration-300 ease-out', isOpen ? 'pointer-events-auto opacity-100' : 'pointer-events-none opacity-0'), style: panelStyle, children: [!isMaximized ? (_jsx("div", { className: "h-[2px] shrink-0 bg-gradient-to-r from-transparent via-violet-500/50 to-transparent" })) : null, !isMaximized ? (_jsx("div", { onMouseDown: onResizeStart, className: "absolute top-0 right-0 z-10 h-4 w-4 cursor-ne-resize" })) : null, _jsxs("div", { onMouseDown: isMaximized ? undefined : onDragStart, className: cn('relative flex h-11 shrink-0 items-center gap-2.5 border-b border-black/[0.06] px-3.5 dark:border-white/[0.06]', !isMaximized && 'cursor-grab active:cursor-grabbing'), children: [_jsx("div", { className: "from-foreground/[0.02] to-foreground/[0.02] pointer-events-none absolute inset-0 bg-gradient-to-r via-transparent" }), !isMaximized ? (_jsx(GripVertical, { className: "text-foreground/15 relative h-3.5 w-3.5 shrink-0" })) : null, _jsx("div", { className: "relative flex h-5 w-5 items-center justify-center", children: _jsx(Bot, { className: "text-foreground/50 h-4 w-4" }) }), _jsxs("div", { className: "relative flex items-baseline gap-2", children: [_jsx("span", { className: "text-foreground/90 text-base font-bold tracking-tight", children: "Shep" }), _jsx("span", { className: "text-foreground/30 text-xs font-medium tracking-widest uppercase", children: "global" })] }), _jsxs("div", { className: "relative ml-auto flex items-center gap-0.5", children: [_jsx("button", { type: "button", onClick: toggleMaximize, className: "text-foreground/30 hover:text-foreground/60 rounded-md p-1 transition-colors", title: isMaximized ? 'Restore (⌘⇧M)' : 'Maximize (⌘⇧M)', children: isMaximized ? (_jsx(Minimize2, { className: "h-3.5 w-3.5" })) : (_jsx(Maximize2, { className: "h-3.5 w-3.5" })) }), _jsx("button", { type: "button", onClick: handleClose, className: "text-foreground/30 hover:text-foreground/60 rounded-md p-1 transition-colors", title: "Close (\u2318\u21E7K)", children: _jsx(X, { className: "h-3.5 w-3.5" }) })] })] }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: _jsx(ChatTab, { featureId: "global" }) }), !isMaximized ? (_jsx("div", { onMouseDown: (e) => {
229
+ ? 'bg-background fixed inset-0 z-[60] flex flex-col overflow-hidden dark:bg-neutral-900'
230
+ : cn(!pos && 'fixed right-8 bottom-24', 'z-[60] flex flex-col overflow-hidden rounded-lg', 'border-border/60 border dark:border-white/10', 'bg-background dark:bg-neutral-900', 'shadow-[0_8px_40px_-8px_rgba(0,0,0,0.2)] dark:shadow-[0_8px_40px_-8px_rgba(0,0,0,0.6)]'), 'transition-opacity duration-300 ease-out', isOpen ? 'pointer-events-auto opacity-100' : 'pointer-events-none opacity-0'), style: panelStyle, children: [!isMaximized ? (_jsx("div", { className: "h-[2px] shrink-0 bg-gradient-to-r from-transparent via-violet-500/50 to-transparent" })) : null, !isMaximized ? (_jsx("div", { onMouseDown: onResizeStart, className: "absolute top-0 right-0 z-10 h-4 w-4 cursor-ne-resize" })) : null, _jsxs("div", { onMouseDown: isMaximized ? undefined : onDragStart, className: cn('relative flex h-11 shrink-0 items-center gap-2.5 border-b border-black/[0.06] px-3.5 dark:border-white/[0.06]', !isMaximized && 'cursor-grab active:cursor-grabbing'), children: [_jsx("div", { className: "from-foreground/[0.02] to-foreground/[0.02] pointer-events-none absolute inset-0 bg-gradient-to-r via-transparent" }), !isMaximized ? (_jsx(GripVertical, { className: "text-foreground/15 relative h-3.5 w-3.5 shrink-0" })) : null, _jsx("div", { className: "relative flex h-5 w-5 items-center justify-center", children: _jsx(Bot, { className: "text-foreground/50 h-4 w-4" }) }), _jsxs("div", { className: "relative flex items-baseline gap-2", children: [_jsx("span", { className: "text-foreground/90 text-base font-bold tracking-tight", children: "Shep" }), _jsx("span", { className: "text-foreground/30 text-xs font-medium tracking-widest uppercase", children: "global" })] }), _jsxs("div", { className: "relative ml-auto flex items-center gap-0.5", children: [_jsx("button", { type: "button", onClick: toggleMaximize, className: "text-foreground/30 hover:text-foreground/60 rounded-md p-1 transition-colors", title: isMaximized ? 'Restore (⌘⇧M)' : 'Maximize (⌘⇧M)', children: isMaximized ? (_jsx(Minimize2, { className: "h-3.5 w-3.5" })) : (_jsx(Maximize2, { className: "h-3.5 w-3.5" })) }), _jsx("button", { type: "button", onClick: handleClose, className: "text-foreground/30 hover:text-foreground/60 rounded-md p-1 transition-colors", title: "Close (\u2318\u21E7K)", children: _jsx(X, { className: "h-3.5 w-3.5" }) })] })] }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: _jsx(ChatTab, { featureId: "global" }) }), !isMaximized ? (_jsx("div", { onMouseDown: (e) => {
219
231
  e.preventDefault();
220
232
  e.stopPropagation();
221
233
  const panel = panelRef.current;
@@ -229,9 +241,10 @@ export function GlobalChatPopup() {
229
241
  if (!pos)
230
242
  setPos({ x: rect.left, y: rect.top });
231
243
  const onMove = (ev) => {
244
+ const maxH = window.innerHeight - (pos?.y ?? rect.top);
232
245
  setSize({
233
246
  w: Math.max(MIN_W, startW + (ev.clientX - startX)),
234
- h: Math.max(MIN_H, startH + (ev.clientY - startY)),
247
+ h: Math.max(MIN_H, Math.min(startH + (ev.clientY - startY), maxH)),
235
248
  });
236
249
  };
237
250
  const onUp = () => {
@@ -240,7 +253,7 @@ export function GlobalChatPopup() {
240
253
  };
241
254
  document.addEventListener('mousemove', onMove);
242
255
  document.addEventListener('mouseup', onUp);
243
- }, className: "absolute right-0 bottom-0 z-10 h-4 w-4 cursor-se-resize" })) : null] })) : null, _jsxs("div", { className: cn('group/fab absolute bottom-4 left-4 z-30 flex items-center', isMaximized && 'hidden'), children: [_jsxs(Button, { size: "icon", onClick: toggle, className: cn('relative h-14 w-14 rounded-full shadow-lg', 'transition-all duration-200 hover:scale-105 hover:shadow-xl active:scale-95', isOpen
256
+ }, className: "absolute right-0 bottom-0 z-10 h-4 w-4 cursor-se-resize" })) : null] })) : null, _jsxs("div", { className: cn('group/fab fixed right-8 bottom-6 z-30', isMaximized && 'hidden'), children: [_jsxs(Button, { size: "icon", onClick: toggle, className: cn('relative h-14 w-14 rounded-full shadow-lg', 'transition-all duration-200 hover:scale-105 hover:shadow-xl active:scale-95', isOpen
244
257
  ? 'bg-violet-600 text-white hover:bg-violet-500'
245
- : 'bg-violet-500 text-white hover:bg-violet-400 dark:bg-violet-500 dark:hover:bg-violet-400'), children: [_jsx(MessageSquare, { className: cn('absolute h-7 w-7 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-0 rotate-90 opacity-0' : 'scale-100 rotate-0 opacity-100') }), _jsx(X, { className: cn('absolute h-6 w-6 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-100 rotate-0 opacity-100' : 'scale-0 -rotate-90 opacity-0') }), !isOpen && _jsx(ChatDotIndicator, { status: globalChatTurnStatus, className: "top-0 right-0" })] }), _jsx("div", { className: "pointer-events-none ml-3 flex translate-x-[-4px] items-center gap-2 opacity-0 transition-all duration-200 group-hover/fab:translate-x-0 group-hover/fab:opacity-100", children: _jsxs("div", { className: "bg-foreground rounded-lg px-3 py-1.5 shadow-lg", children: [_jsx("p", { className: "text-background text-xs font-medium", children: "Shep Chat" }), _jsxs("p", { className: "text-background/50 mt-0.5 flex items-center gap-1 text-[10px]", children: [_jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "\u2318" }), _jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "\u21E7" }), _jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "K" })] })] }) })] })] }));
258
+ : 'bg-violet-500 text-white hover:bg-violet-400 dark:bg-violet-500 dark:hover:bg-violet-400'), children: [_jsx(MessageSquare, { className: cn('absolute h-7 w-7 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-0 rotate-90 opacity-0' : 'scale-100 rotate-0 opacity-100') }), _jsx(X, { className: cn('absolute h-6 w-6 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-100 rotate-0 opacity-100' : 'scale-0 -rotate-90 opacity-0') }), !isOpen && _jsx(ChatDotIndicator, { status: globalChatTurnStatus, className: "top-0 right-0" })] }), _jsx("div", { className: "pointer-events-none 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: "Shep Chat" }), _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" })] })] }) })] })] }));
246
259
  }
@@ -1 +1 @@
1
- {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAwB5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CAmZzF"}
1
+ {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AA8B5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CAwczF"}
@@ -1,16 +1,20 @@
1
1
  'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { useRouter, usePathname } from 'next/navigation';
5
+ import { Sparkles, FolderPlus, Github, GitBranch } from 'lucide-react';
5
6
  import { useReactFlow } from '@xyflow/react';
6
7
  import { FeaturesCanvas } from '../../features/features-canvas/index.js';
7
8
  import { CanvasToolbar } from '../../features/features-canvas/canvas-toolbar.js';
9
+ import { FloatingActionButton, } from '../../common/floating-action-button/index.js';
8
10
  import { useSidebarFeaturesContext, mapNodeStateToSidebarStatus, } from '../../../hooks/sidebar-features-context.js';
11
+ import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
9
12
  import { useSelectedFeatureId } from '../../../hooks/use-selected-feature-id.js';
10
13
  import { useSelectedRepository } from '../../../hooks/use-selected-repository.js';
11
14
  import { useSoundAction } from '../../../hooks/use-sound-action.js';
12
15
  import { useDrawerCloseGuard } from '../../../hooks/drawer-close-guard.js';
13
16
  import { useViewportPersistence } from '../../../hooks/use-viewport-persistence.js';
17
+ import { useSidebar } from '../../ui/sidebar.js';
14
18
  import { ControlCenterEmptyState } from './control-center-empty-state.js';
15
19
  import { useControlCenterState } from './use-control-center-state.js';
16
20
  const AUTO_FOCUS_OPTIONS = {
@@ -291,6 +295,65 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
291
295
  const handlePickFolder = useCallback(() => {
292
296
  window.dispatchEvent(new CustomEvent('shep:pick-folder'));
293
297
  }, []);
294
- const canvasToolbar = (_jsx(CanvasToolbar, { showArchived: showArchived, onToggleArchived: () => setShowArchived(!showArchived), onAddFeature: handleAddFeature, onAddRepository: handlePickFolder, onResetViewport: resetViewport }));
295
- return (_jsx(FeaturesCanvas, { nodes: showCanvas ? displayNodes : [], edges: showCanvas ? edges : [], selectedFeatureId: selectedFeatureId, selectedRepository: selectedRepository, defaultViewport: defaultViewport, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onMoveEnd: handleMoveEnd, toolbar: canvasToolbar, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: addRepoAndFocus }) }));
298
+ const featureFlags = useFeatureFlags();
299
+ // (+) FAB actions only visible on control center
300
+ const fabActions = useMemo(() => {
301
+ const actions = [
302
+ {
303
+ id: 'new-feature',
304
+ label: 'New Feature',
305
+ icon: _jsx(Sparkles, { className: "h-4 w-4" }),
306
+ onClick: () => {
307
+ clickSound.play();
308
+ guardedNavigate(() => router.push('/create'));
309
+ },
310
+ },
311
+ {
312
+ id: 'add-local-repo',
313
+ label: 'Local Folder',
314
+ icon: _jsx(FolderPlus, { className: "h-4 w-4" }),
315
+ onClick: handlePickFolder,
316
+ },
317
+ ];
318
+ if (featureFlags.adoptBranch) {
319
+ actions.push({
320
+ id: 'adopt-branch',
321
+ label: 'Adopt Branch',
322
+ icon: _jsx(GitBranch, { className: "h-4 w-4" }),
323
+ onClick: () => {
324
+ guardedNavigate(() => router.push('/adopt'));
325
+ },
326
+ });
327
+ }
328
+ if (featureFlags.githubImport) {
329
+ actions.push({
330
+ id: 'add-github-repo',
331
+ label: 'From GitHub',
332
+ icon: _jsx(Github, { className: "h-4 w-4" }),
333
+ onClick: () => {
334
+ window.dispatchEvent(new CustomEvent('shep:open-github-import'));
335
+ },
336
+ });
337
+ }
338
+ return actions;
339
+ }, [
340
+ clickSound,
341
+ guardedNavigate,
342
+ router,
343
+ handlePickFolder,
344
+ featureFlags.adoptBranch,
345
+ featureFlags.githubImport,
346
+ ]);
347
+ const canvasToolbar = (_jsx(CanvasToolbar, { showArchived: showArchived, onToggleArchived: () => setShowArchived(!showArchived), onResetViewport: resetViewport }));
348
+ return (_jsxs(_Fragment, { children: [_jsx(FeaturesCanvas, { nodes: showCanvas ? displayNodes : [], edges: showCanvas ? edges : [], selectedFeatureId: selectedFeatureId, selectedRepository: selectedRepository, defaultViewport: defaultViewport, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onMoveEnd: handleMoveEnd, toolbar: canvasToolbar, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: addRepoAndFocus }) }), showCanvas ? _jsx(CreateFab, { actions: fabActions }) : null] }));
349
+ }
350
+ /** (+) FAB that tracks sidebar width via CSS var + transition. */
351
+ function CreateFab({ actions }) {
352
+ const { state } = useSidebar();
353
+ // Sidebar expanded = var(--sidebar-width) = 16rem, collapsed = var(--sidebar-width-icon) = 3rem
354
+ // Position just outside the sidebar edge with 16px gap
355
+ const left = state === 'expanded'
356
+ ? 'calc(var(--sidebar-width) + 32px)'
357
+ : 'calc(var(--sidebar-width-icon) + 32px)';
358
+ return (_jsx(FloatingActionButton, { actions: actions, className: "!fixed bottom-6", style: { left, transition: 'left 200ms ease-in-out' } }));
296
359
  }
@@ -2,12 +2,7 @@ import type { Viewport } from '@xyflow/react';
2
2
  export interface CanvasToolbarProps {
3
3
  showArchived: boolean;
4
4
  onToggleArchived: () => void;
5
- onAddFeature: () => void;
6
- onAddRepository: () => void;
7
- addingRepo?: boolean;
8
5
  onResetViewport?: () => Viewport;
9
- /** Extra action buttons (adopt branch, github import, etc.) */
10
- extraActions?: React.ReactNode;
11
6
  }
12
- export declare function CanvasToolbar({ showArchived, onToggleArchived, onAddFeature, onAddRepository, addingRepo, onResetViewport, extraActions, }: CanvasToolbarProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function CanvasToolbar({ showArchived, onToggleArchived, onResetViewport, }: CanvasToolbarProps): import("react/jsx-runtime").JSX.Element;
13
8
  //# sourceMappingURL=canvas-toolbar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvas-toolbar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/canvas-toolbar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAK9C,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,QAAQ,CAAC;IACjC,+DAA+D;IAC/D,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAChC;AAED,wBAAgB,aAAa,CAAC,EAC5B,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,UAAU,EACV,eAAe,EACf,YAAY,GACb,EAAE,kBAAkB,2CAoEpB"}
1
+ {"version":3,"file":"canvas-toolbar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/canvas-toolbar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,QAAQ,CAAC;CAClC;AAED,wBAAgB,aAAa,CAAC,EAC5B,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,EAAE,kBAAkB,2CAqDpB"}