@shepai/cli 1.166.1 → 1.167.0-pr505.5cf8222

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 (406) hide show
  1. package/apis/json-schema/FeatureFlags.yaml +5 -0
  2. package/dist/packages/core/src/application/index.d.ts +1 -0
  3. package/dist/packages/core/src/application/index.d.ts.map +1 -1
  4. package/dist/packages/core/src/application/index.js +1 -0
  5. package/dist/packages/core/src/application/ports/output/agents/agent-run-repository.interface.d.ts +12 -0
  6. package/dist/packages/core/src/application/ports/output/agents/agent-run-repository.interface.d.ts.map +1 -1
  7. package/dist/packages/core/src/application/use-cases/features/update-feature-pinned-config.use-case.d.ts +24 -0
  8. package/dist/packages/core/src/application/use-cases/features/update-feature-pinned-config.use-case.d.ts.map +1 -0
  9. package/dist/packages/core/src/application/use-cases/features/update-feature-pinned-config.use-case.js +107 -0
  10. package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
  11. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +1 -0
  12. package/dist/packages/core/src/domain/generated/output.d.ts +4 -0
  13. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  14. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  15. package/dist/packages/core/src/infrastructure/di/container.js +5 -0
  16. package/dist/packages/core/src/infrastructure/persistence/sqlite/legacy-migrations.d.ts.map +1 -1
  17. package/dist/packages/core/src/infrastructure/persistence/sqlite/legacy-migrations.js +11 -0
  18. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +1 -0
  19. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  20. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +2 -0
  21. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/050-add-feature-flag-inventory.d.ts +11 -0
  22. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/050-add-feature-flag-inventory.d.ts.map +1 -0
  23. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/050-add-feature-flag-inventory.js +17 -0
  24. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts +3 -3
  25. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +3 -3
  26. package/dist/packages/core/src/infrastructure/repositories/agent-run.repository.d.ts +2 -1
  27. package/dist/packages/core/src/infrastructure/repositories/agent-run.repository.d.ts.map +1 -1
  28. package/dist/packages/core/src/infrastructure/repositories/agent-run.repository.js +15 -0
  29. package/dist/packages/core/src/infrastructure/services/web-server.service.d.ts +3 -0
  30. package/dist/packages/core/src/infrastructure/services/web-server.service.d.ts.map +1 -1
  31. package/dist/packages/core/src/infrastructure/services/web-server.service.js +10 -0
  32. package/dist/src/presentation/web/app/actions/update-feature-pinned-config.d.ts +5 -0
  33. package/dist/src/presentation/web/app/actions/update-feature-pinned-config.d.ts.map +1 -0
  34. package/dist/src/presentation/web/app/actions/update-feature-pinned-config.js +29 -0
  35. package/dist/src/presentation/web/app/features/feature-tree-page-client.d.ts +7 -0
  36. package/dist/src/presentation/web/app/features/feature-tree-page-client.d.ts.map +1 -0
  37. package/dist/src/presentation/web/app/features/feature-tree-page-client.js +13 -0
  38. package/dist/src/presentation/web/app/features/get-feature-tree-data.d.ts +10 -0
  39. package/dist/src/presentation/web/app/features/get-feature-tree-data.d.ts.map +1 -0
  40. package/dist/src/presentation/web/app/features/get-feature-tree-data.js +47 -0
  41. package/dist/src/presentation/web/app/features/page.d.ts +4 -0
  42. package/dist/src/presentation/web/app/features/page.d.ts.map +1 -0
  43. package/dist/src/presentation/web/app/features/page.js +9 -0
  44. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  45. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +100 -9
  46. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts +4 -1
  47. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.d.ts.map +1 -1
  48. package/dist/src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.js +3 -3
  49. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts +3 -1
  50. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.d.ts.map +1 -1
  51. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.js +21 -10
  52. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts +4 -0
  53. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.d.ts.map +1 -1
  54. package/dist/src/presentation/web/components/common/feature-drawer-tabs/overview-tab.stories.js +33 -0
  55. package/dist/src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.d.ts +18 -0
  56. package/dist/src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.d.ts.map +1 -0
  57. package/dist/src/presentation/web/components/common/feature-drawer-tabs/pinned-config-utils.js +17 -0
  58. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts.map +1 -1
  59. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.js +1 -0
  60. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts +36 -0
  61. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts.map +1 -0
  62. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.js +196 -0
  63. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.stories.d.ts +12 -0
  64. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.stories.d.ts.map +1 -0
  65. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.stories.js +166 -0
  66. package/dist/src/presentation/web/components/features/feature-tree-table/index.d.ts +3 -0
  67. package/dist/src/presentation/web/components/features/feature-tree-table/index.d.ts.map +1 -0
  68. package/dist/src/presentation/web/components/features/feature-tree-table/index.js +1 -0
  69. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts +2 -0
  70. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts.map +1 -1
  71. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.js +27 -0
  72. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts +10 -1
  73. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts.map +1 -1
  74. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.js +33 -25
  75. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.d.ts.map +1 -1
  76. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.js +3 -0
  77. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.d.ts.map +1 -1
  78. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.js +3 -0
  79. package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
  80. package/dist/src/presentation/web/components/features/settings/settings-page-client.js +5 -0
  81. package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts.map +1 -1
  82. package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.js +1 -0
  83. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  84. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
  85. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.d.ts.map +1 -1
  86. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.js +1 -0
  87. package/dist/src/presentation/web/hooks/feature-flags-context.d.ts.map +1 -1
  88. package/dist/src/presentation/web/hooks/feature-flags-context.js +1 -0
  89. package/dist/src/presentation/web/lib/feature-flags.d.ts +2 -0
  90. package/dist/src/presentation/web/lib/feature-flags.d.ts.map +1 -1
  91. package/dist/src/presentation/web/lib/feature-flags.js +5 -0
  92. package/dist/translations/ar/web.json +3 -0
  93. package/dist/translations/de/web.json +3 -0
  94. package/dist/translations/en/web.json +3 -0
  95. package/dist/translations/es/web.json +3 -0
  96. package/dist/translations/fr/web.json +3 -0
  97. package/dist/translations/he/web.json +3 -0
  98. package/dist/translations/pt/web.json +3 -0
  99. package/dist/translations/ru/web.json +3 -0
  100. package/dist/tsconfig.build.tsbuildinfo +1 -1
  101. package/package.json +1 -1
  102. package/web/.next/BUILD_ID +1 -1
  103. package/web/.next/app-path-routes-manifest.json +1 -0
  104. package/web/.next/build-manifest.json +5 -5
  105. package/web/.next/fallback-build-manifest.json +2 -2
  106. package/web/.next/prerender-manifest.json +3 -3
  107. package/web/.next/required-server-files.js +3 -3
  108. package/web/.next/required-server-files.json +3 -3
  109. package/web/.next/routes-manifest.json +6 -0
  110. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/build-manifest.json +3 -3
  111. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  112. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -1
  113. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  114. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  115. package/web/.next/server/app/(dashboard)/@drawer/chat/page/build-manifest.json +3 -3
  116. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  117. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +1 -1
  118. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  119. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  120. package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +3 -3
  121. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
  122. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  123. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  124. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  125. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +3 -3
  126. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +89 -74
  127. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +2 -2
  128. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  129. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  130. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +3 -3
  131. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +89 -74
  132. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +2 -2
  133. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  134. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  135. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/build-manifest.json +3 -3
  136. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  137. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +1 -1
  138. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  139. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  140. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +3 -3
  141. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  142. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  143. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  144. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  145. package/web/.next/server/app/(dashboard)/chat/page/build-manifest.json +3 -3
  146. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  147. package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
  148. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  149. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  150. package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +3 -3
  151. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
  152. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  153. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  154. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  155. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +3 -3
  156. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +89 -74
  157. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +2 -2
  158. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  159. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  160. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +3 -3
  161. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +89 -74
  162. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +2 -2
  163. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  164. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  165. package/web/.next/server/app/(dashboard)/page/build-manifest.json +3 -3
  166. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  167. package/web/.next/server/app/(dashboard)/page.js +1 -1
  168. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  169. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  170. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/build-manifest.json +3 -3
  171. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  172. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +1 -1
  173. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  174. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  175. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +3 -3
  176. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  177. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  178. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  179. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  180. package/web/.next/server/app/_global-error/page/build-manifest.json +3 -3
  181. package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  182. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  183. package/web/.next/server/app/_global-error.html +2 -2
  184. package/web/.next/server/app/_global-error.rsc +1 -1
  185. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  186. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  187. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  188. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  189. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  190. package/web/.next/server/app/_not-found/page/build-manifest.json +3 -3
  191. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  192. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  193. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  194. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  195. package/web/.next/server/app/api/attachments/upload-from-path/route.js +1 -1
  196. package/web/.next/server/app/api/attachments/upload-from-path/route.js.nft.json +1 -1
  197. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  198. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  199. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  200. package/web/.next/server/app/features/page/app-paths-manifest.json +3 -0
  201. package/web/.next/server/app/features/page/build-manifest.json +18 -0
  202. package/web/.next/server/app/features/page/next-font-manifest.json +6 -0
  203. package/web/.next/server/app/features/page/react-loadable-manifest.json +8 -0
  204. package/web/.next/server/app/features/page/server-reference-manifest.json +95 -0
  205. package/web/.next/server/app/features/page.js +18 -0
  206. package/web/.next/server/app/features/page.js.map +5 -0
  207. package/web/.next/server/app/features/page.js.nft.json +1 -0
  208. package/web/.next/server/app/features/page_client-reference-manifest.js +2 -0
  209. package/web/.next/server/app/settings/page/build-manifest.json +3 -3
  210. package/web/.next/server/app/settings/page/server-reference-manifest.json +9 -9
  211. package/web/.next/server/app/settings/page.js +1 -1
  212. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  213. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  214. package/web/.next/server/app/skills/page/build-manifest.json +3 -3
  215. package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
  216. package/web/.next/server/app/skills/page.js +1 -1
  217. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  218. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  219. package/web/.next/server/app/tools/page/build-manifest.json +3 -3
  220. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  221. package/web/.next/server/app/tools/page.js +1 -1
  222. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  223. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  224. package/web/.next/server/app/version/page/build-manifest.json +3 -3
  225. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  226. package/web/.next/server/app/version/page.js.nft.json +1 -1
  227. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  228. package/web/.next/server/app-paths-manifest.json +1 -0
  229. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  230. package/web/.next/server/chunks/{[root-of-the-server]__ea653642._.js → [root-of-the-server]__a5879003._.js} +2 -2
  231. package/web/.next/server/chunks/{[root-of-the-server]__ea653642._.js.map → [root-of-the-server]__a5879003._.js.map} +1 -1
  232. package/web/.next/server/chunks/[root-of-the-server]__c78383b1._.js.map +1 -1
  233. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  234. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  235. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  236. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +3 -3
  237. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  238. package/web/.next/server/chunks/ssr/[root-of-the-server]__08c912ab._.js +3 -0
  239. package/web/.next/server/chunks/ssr/[root-of-the-server]__08c912ab._.js.map +1 -0
  240. package/web/.next/server/chunks/ssr/{[root-of-the-server]__b062b383._.js → [root-of-the-server]__0c5452c3._.js} +2 -2
  241. package/web/.next/server/chunks/ssr/[root-of-the-server]__0c5452c3._.js.map +1 -0
  242. package/web/.next/server/chunks/ssr/{[root-of-the-server]__2d0c3840._.js → [root-of-the-server]__13fa44e4._.js} +2 -2
  243. package/web/.next/server/chunks/ssr/{[root-of-the-server]__2d0c3840._.js.map → [root-of-the-server]__13fa44e4._.js.map} +1 -1
  244. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
  245. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
  246. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  247. package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js +4 -0
  248. package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js.map +1 -0
  249. package/web/.next/server/chunks/ssr/{[root-of-the-server]__dffa13c5._.js → [root-of-the-server]__69dd3217._.js} +2 -2
  250. package/web/.next/server/chunks/ssr/{[root-of-the-server]__dffa13c5._.js.map → [root-of-the-server]__69dd3217._.js.map} +1 -1
  251. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +4 -0
  252. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +1 -0
  253. package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js +4 -0
  254. package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js.map +1 -0
  255. package/web/.next/server/chunks/ssr/{[root-of-the-server]__7562afc6._.js → [root-of-the-server]__7ffd3598._.js} +3 -3
  256. package/web/.next/server/chunks/ssr/[root-of-the-server]__7ffd3598._.js.map +1 -0
  257. package/web/.next/server/chunks/ssr/{[root-of-the-server]__248ee887._.js → [root-of-the-server]__851f6adb._.js} +2 -2
  258. package/web/.next/server/chunks/ssr/[root-of-the-server]__851f6adb._.js.map +1 -0
  259. package/web/.next/server/chunks/ssr/{[root-of-the-server]__1abe77bb._.js → [root-of-the-server]__b020c17d._.js} +3 -3
  260. package/web/.next/server/chunks/ssr/[root-of-the-server]__b020c17d._.js.map +1 -0
  261. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
  262. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
  263. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js +4 -0
  264. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js.map +1 -0
  265. package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js +4 -0
  266. package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js.map +1 -0
  267. package/web/.next/server/chunks/ssr/{[root-of-the-server]__8b0aac03._.js → [root-of-the-server]__e88da4ee._.js} +3 -3
  268. package/web/.next/server/chunks/ssr/{[root-of-the-server]__8b0aac03._.js.map → [root-of-the-server]__e88da4ee._.js.map} +1 -1
  269. package/web/.next/server/chunks/ssr/_0020fddd._.js +1 -1
  270. package/web/.next/server/chunks/ssr/_0020fddd._.js.map +1 -1
  271. package/web/.next/server/chunks/ssr/_02e01240._.js +1 -1
  272. package/web/.next/server/chunks/ssr/_02e01240._.js.map +1 -1
  273. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  274. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  275. package/web/.next/server/chunks/ssr/_0727935d._.js +1 -1
  276. package/web/.next/server/chunks/ssr/_0727935d._.js.map +1 -1
  277. package/web/.next/server/chunks/ssr/_0dc06d07._.js +1 -1
  278. package/web/.next/server/chunks/ssr/_0dc06d07._.js.map +1 -1
  279. package/web/.next/server/chunks/ssr/_16235e5e._.js +1 -1
  280. package/web/.next/server/chunks/ssr/_16235e5e._.js.map +1 -1
  281. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  282. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  283. package/web/.next/server/chunks/ssr/_18886033._.js +1 -1
  284. package/web/.next/server/chunks/ssr/_18886033._.js.map +1 -1
  285. package/web/.next/server/chunks/ssr/_22e00a14._.js +1 -1
  286. package/web/.next/server/chunks/ssr/_22e00a14._.js.map +1 -1
  287. package/web/.next/server/chunks/ssr/_4a4709c5._.js +4 -0
  288. package/web/.next/server/chunks/ssr/_4a4709c5._.js.map +1 -0
  289. package/web/.next/server/chunks/ssr/_5119a3df._.js.map +1 -1
  290. package/web/.next/server/chunks/ssr/_560f2971._.js +3 -0
  291. package/web/.next/server/chunks/ssr/_560f2971._.js.map +1 -0
  292. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  293. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  294. package/web/.next/server/chunks/ssr/{_0a90d28b._.js → _5c76b6b5._.js} +2 -2
  295. package/web/.next/server/chunks/ssr/{_0a90d28b._.js.map → _5c76b6b5._.js.map} +1 -1
  296. package/web/.next/server/chunks/ssr/{_a65c54ca._.js → _5f099575._.js} +2 -2
  297. package/web/.next/server/chunks/ssr/{_a65c54ca._.js.map → _5f099575._.js.map} +1 -1
  298. package/web/.next/server/chunks/ssr/_a5a5901d._.js +1 -1
  299. package/web/.next/server/chunks/ssr/_a5a5901d._.js.map +1 -1
  300. package/web/.next/server/chunks/ssr/_a69efc34._.js +3 -0
  301. package/web/.next/server/chunks/ssr/{_4d49a312._.js.map → _a69efc34._.js.map} +1 -1
  302. package/web/.next/server/chunks/ssr/_ad09f271._.js +1 -1
  303. package/web/.next/server/chunks/ssr/_ad09f271._.js.map +1 -1
  304. package/web/.next/server/chunks/ssr/_c3f595c6._.js +1 -1
  305. package/web/.next/server/chunks/ssr/_c3f595c6._.js.map +1 -1
  306. package/web/.next/server/chunks/ssr/{_05dae8d0._.js → _cac860bb._.js} +2 -2
  307. package/web/.next/server/chunks/ssr/{_05dae8d0._.js.map → _cac860bb._.js.map} +1 -1
  308. package/web/.next/server/chunks/ssr/{_506a3bc3._.js → _cc936cdc._.js} +2 -2
  309. package/web/.next/server/chunks/ssr/_cc936cdc._.js.map +1 -0
  310. package/web/.next/server/chunks/ssr/_df737cce._.js +3 -0
  311. package/web/.next/server/chunks/ssr/_df737cce._.js.map +1 -0
  312. package/web/.next/server/chunks/ssr/_ea9e1556._.js +1 -1
  313. package/web/.next/server/chunks/ssr/_ea9e1556._.js.map +1 -1
  314. package/web/.next/server/chunks/ssr/_f1ba9be6._.js +2 -2
  315. package/web/.next/server/chunks/ssr/_f1ba9be6._.js.map +1 -1
  316. package/web/.next/server/chunks/ssr/_f33cd07e._.js +2 -2
  317. package/web/.next/server/chunks/ssr/_f33cd07e._.js.map +1 -1
  318. package/web/.next/server/chunks/ssr/_f535d854._.js +3 -0
  319. package/web/.next/server/chunks/ssr/_f535d854._.js.map +1 -0
  320. package/web/.next/server/chunks/ssr/_f79e241b._.js +3 -0
  321. package/web/.next/server/chunks/ssr/{_3bcda5d7._.js.map → _f79e241b._.js.map} +1 -1
  322. package/web/.next/server/chunks/ssr/_f8b45233._.js +1 -1
  323. package/web/.next/server/chunks/ssr/_f8b45233._.js.map +1 -1
  324. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  325. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  326. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
  327. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
  328. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  329. package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js +10 -0
  330. package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js.map +1 -0
  331. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
  332. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
  333. package/web/.next/server/chunks/ssr/src_presentation_web_components_common_page-header_index_ts_bdf4db0b._.js +3 -0
  334. package/web/.next/server/chunks/ssr/src_presentation_web_components_common_page-header_index_ts_bdf4db0b._.js.map +1 -0
  335. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  336. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  337. package/web/.next/server/chunks/ssr/src_presentation_web_db9fa0c2._.js +1 -1
  338. package/web/.next/server/chunks/ssr/src_presentation_web_db9fa0c2._.js.map +1 -1
  339. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js +1 -1
  340. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js.map +1 -1
  341. package/web/.next/server/middleware-build-manifest.js +3 -3
  342. package/web/.next/server/pages/500.html +2 -2
  343. package/web/.next/server/server-reference-manifest.js +1 -1
  344. package/web/.next/server/server-reference-manifest.json +273 -195
  345. package/web/.next/static/chunks/{8c96c49aad817377.js → 110a8827583ae5bb.js} +1 -1
  346. package/web/.next/static/chunks/20f7cc98a013b11c.js +1 -0
  347. package/web/.next/static/chunks/{0b732842dcca8b8d.js → 2615825711ac4e81.js} +3 -3
  348. package/web/.next/static/chunks/2f711373a93c5bc3.css +1 -0
  349. package/web/.next/static/chunks/{ee270565c4bdb7e1.js → 328874065794ea9f.js} +2 -2
  350. package/web/.next/static/chunks/3e393d6a78b2ade4.js +1 -0
  351. package/web/.next/static/chunks/{c60d6c2b2f7b0593.js → 4ac6f8c2bb39a6e4.js} +1 -1
  352. package/web/.next/static/chunks/{44275180f9c50dbb.js → 4ba01cd71cfa981b.js} +1 -1
  353. package/web/.next/static/chunks/4cec255f2754e5ec.js +1 -0
  354. package/web/.next/static/chunks/5d4a8552d5b6a4a8.js +1 -0
  355. package/web/.next/static/chunks/5ed47e998707b519.js +8 -0
  356. package/web/.next/static/chunks/612750555eb00a6c.js +5 -0
  357. package/web/.next/static/chunks/647140fe96a7c88a.js +1 -0
  358. package/web/.next/static/chunks/68127a29d87ba43a.js +1 -0
  359. package/web/.next/static/chunks/92c8c994d9ad0c81.js +1 -0
  360. package/web/.next/static/chunks/{18e8b12721a9316e.js → 9c4927d092875708.js} +1 -1
  361. package/web/.next/static/chunks/{1cd31898fb6e763a.js → 9e2dcc66aa1e3ee7.js} +1 -1
  362. package/web/.next/static/chunks/a262ab91e9288145.js +1 -0
  363. package/web/.next/static/chunks/a825ba5207a10722.js +7 -0
  364. package/web/.next/static/chunks/c3ef3b892f7794ec.js +1 -0
  365. package/web/.next/static/chunks/c4874941c93f4f77.js +1 -0
  366. package/web/.next/static/chunks/c5b3a8430ab26648.css +1 -0
  367. package/web/.next/static/chunks/dc134f3f58cdf850.js +5 -0
  368. package/web/.next/static/chunks/{43eca8783fbc9558.js → f0183c225f31840b.js} +1 -1
  369. package/web/.next/static/chunks/f998b42b5cddafd6.js +1 -0
  370. package/web/.next/static/chunks/{turbopack-432ef324fc27240c.js → turbopack-62782e656a49f322.js} +1 -1
  371. package/web/package.json +2 -0
  372. package/web/.next/server/chunks/ssr/[root-of-the-server]__1abe77bb._.js.map +0 -1
  373. package/web/.next/server/chunks/ssr/[root-of-the-server]__248ee887._.js.map +0 -1
  374. package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js +0 -4
  375. package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js.map +0 -1
  376. package/web/.next/server/chunks/ssr/[root-of-the-server]__7562afc6._.js.map +0 -1
  377. package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js +0 -4
  378. package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js.map +0 -1
  379. package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js +0 -4
  380. package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js.map +0 -1
  381. package/web/.next/server/chunks/ssr/[root-of-the-server]__b062b383._.js.map +0 -1
  382. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js +0 -4
  383. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js.map +0 -1
  384. package/web/.next/server/chunks/ssr/_3bcda5d7._.js +0 -3
  385. package/web/.next/server/chunks/ssr/_4d49a312._.js +0 -3
  386. package/web/.next/server/chunks/ssr/_506a3bc3._.js.map +0 -1
  387. package/web/.next/server/chunks/ssr/_9215e9ec._.js +0 -3
  388. package/web/.next/server/chunks/ssr/_9215e9ec._.js.map +0 -1
  389. package/web/.next/server/chunks/ssr/_b5fc318a._.js +0 -3
  390. package/web/.next/server/chunks/ssr/_b5fc318a._.js.map +0 -1
  391. package/web/.next/static/chunks/16eea21868510afd.js +0 -5
  392. package/web/.next/static/chunks/1e6609edc3367244.css +0 -1
  393. package/web/.next/static/chunks/345246551a96bdb2.js +0 -1
  394. package/web/.next/static/chunks/3deefc76ea55047c.js +0 -1
  395. package/web/.next/static/chunks/40b6bcf1a2de4a0f.js +0 -1
  396. package/web/.next/static/chunks/5fde2118133bc2bb.js +0 -1
  397. package/web/.next/static/chunks/65440524d7ee7d13.js +0 -1
  398. package/web/.next/static/chunks/672e3da3ad26005b.js +0 -1
  399. package/web/.next/static/chunks/9dbfc283af013ec1.js +0 -7
  400. package/web/.next/static/chunks/c0e13e7d1601bc5d.js +0 -1
  401. package/web/.next/static/chunks/c7e793951b20a67f.js +0 -1
  402. package/web/.next/static/chunks/d5dcf6575f5f9dd8.js +0 -5
  403. package/web/.next/static/chunks/dd52a7ae78af4f7f.js +0 -1
  404. /package/web/.next/static/{RH3NxvKaE9Efp8ZrIyCm5 → xAhPAfLhIR5KWVO7DbsJR}/_buildManifest.js +0 -0
  405. /package/web/.next/static/{RH3NxvKaE9Efp8ZrIyCm5 → xAhPAfLhIR5KWVO7DbsJR}/_clientMiddlewareManifest.json +0 -0
  406. /package/web/.next/static/{RH3NxvKaE9Efp8ZrIyCm5 → xAhPAfLhIR5KWVO7DbsJR}/_ssgManifest.js +0 -0
@@ -34,6 +34,9 @@ const defaultDeps = {
34
34
  * Development: import.meta.dirname = <root>/packages/core/src/infrastructure/services/
35
35
  * → 5 levels up → <root>/src/presentation/web/
36
36
  *
37
+ * Workspace dist: import.meta.dirname = <root>/dist/packages/core/src/infrastructure/services/
38
+ * → 6 levels up → <root>/src/presentation/web/
39
+ *
37
40
  * Production (npm install): import.meta.dirname = <root>/dist/packages/core/src/infrastructure/services/
38
41
  * → 6 levels up → <root>/web/
39
42
  */
@@ -44,6 +47,12 @@ export function resolveWebDir() {
44
47
  if (fs.existsSync(path.join(devDir, 'next.config.ts'))) {
45
48
  return { dir: devDir, dev: true };
46
49
  }
50
+ // Dist CLI inside a workspace checkout: the built CLI lives under dist/,
51
+ // but the source web app still exists at the repository root.
52
+ const workspaceDevDir = path.resolve(import.meta.dirname, '../../../../../../src/presentation/web');
53
+ if (fs.existsSync(path.join(workspaceDevDir, 'next.config.ts'))) {
54
+ return { dir: workspaceDevDir, dev: true };
55
+ }
47
56
  // Production: web UI is shipped alongside dist/ in the package
48
57
  // From dist/packages/core/src/infrastructure/services/ → 6 levels up to package root
49
58
  const prodDir = path.resolve(import.meta.dirname, '../../../../../../web');
@@ -53,6 +62,7 @@ export function resolveWebDir() {
53
62
  throw new Error(`Web UI directory not found. Ensure the web UI is built (pnpm build:web).\n` +
54
63
  ` Searched:\n` +
55
64
  ` dev: ${devDir} (next.config.ts: ${fs.existsSync(path.join(devDir, 'next.config.ts'))})\n` +
65
+ ` workspace: ${workspaceDevDir} (next.config.ts: ${fs.existsSync(path.join(workspaceDevDir, 'next.config.ts'))})\n` +
56
66
  ` prod: ${prodDir} (.next: ${fs.existsSync(path.join(prodDir, '.next'))})\n` +
57
67
  ` import.meta.dirname: ${import.meta.dirname}`);
58
68
  }
@@ -0,0 +1,5 @@
1
+ export declare function updateFeaturePinnedConfig(featureId: string, agentType: string, modelId: string): Promise<{
2
+ ok: boolean;
3
+ error?: string;
4
+ }>;
5
+ //# sourceMappingURL=update-feature-pinned-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-feature-pinned-config.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/update-feature-pinned-config.ts"],"names":[],"mappings":"AAKA,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6B1C"}
@@ -0,0 +1,29 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ export async function updateFeaturePinnedConfig(featureId, agentType, modelId) {
4
+ const normalizedFeatureId = featureId.trim();
5
+ if (!normalizedFeatureId) {
6
+ return { ok: false, error: 'Feature id is required' };
7
+ }
8
+ const normalizedAgentType = agentType.trim();
9
+ if (!normalizedAgentType) {
10
+ return { ok: false, error: 'Agent type is required' };
11
+ }
12
+ const normalizedModelId = modelId.trim();
13
+ if (!normalizedModelId) {
14
+ return { ok: false, error: 'Model id is required' };
15
+ }
16
+ try {
17
+ const useCase = resolve('UpdateFeaturePinnedConfigUseCase');
18
+ await useCase.execute({
19
+ featureId: normalizedFeatureId,
20
+ agentType: normalizedAgentType,
21
+ modelId: normalizedModelId,
22
+ });
23
+ return { ok: true };
24
+ }
25
+ catch (error) {
26
+ const message = error instanceof Error ? error.message : 'Failed to update feature pinned config';
27
+ return { ok: false, error: message };
28
+ }
29
+ }
@@ -0,0 +1,7 @@
1
+ import type { FeatureTreeRow, InventoryRepo } from '../../components/features/feature-tree-table/index.js';
2
+ export interface FeatureTreePageClientProps {
3
+ features: FeatureTreeRow[];
4
+ repos: InventoryRepo[];
5
+ }
6
+ export declare function FeatureTreePageClient({ features, repos }: FeatureTreePageClientProps): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=feature-tree-page-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-tree-page-client.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/feature-tree-page-client.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAG9F,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,0BAA0B,2CAkBpF"}
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useRouter } from 'next/navigation';
4
+ import { useCallback } from 'react';
5
+ import { FeatureTreeTable } from '../../components/features/feature-tree-table/index.js';
6
+ import { PageHeader } from '../../components/common/page-header/index.js';
7
+ export function FeatureTreePageClient({ features, repos }) {
8
+ const router = useRouter();
9
+ const handleFeatureClick = useCallback((featureId) => {
10
+ router.push(`/feature/${featureId}/overview`);
11
+ }, [router]);
12
+ return (_jsxs("div", { "data-testid": "feature-tree-page", className: "flex h-full flex-col gap-4", children: [_jsx(PageHeader, { title: "Inventory", description: "All repositories and features" }), _jsx("div", { className: "min-h-0 flex-1", children: _jsx(FeatureTreeTable, { data: features, repos: repos, onFeatureClick: handleFeatureClick }) })] }));
13
+ }
@@ -0,0 +1,10 @@
1
+ import type { FeatureTreeRow } from '../../components/features/feature-tree-table/index.js';
2
+ export interface InventoryRepo {
3
+ name: string;
4
+ remoteUrl?: string;
5
+ }
6
+ export declare function getFeatureTreeData(): Promise<{
7
+ features: FeatureTreeRow[];
8
+ repos: InventoryRepo[];
9
+ }>;
10
+ //# sourceMappingURL=get-feature-tree-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-feature-tree-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/get-feature-tree-data.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAI/E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAClD,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB,CAAC,CAgCD"}
@@ -0,0 +1,47 @@
1
+ import { resolve } from '../../lib/server-container.js';
2
+ import { SdlcLifecycle } from '../../../../../packages/core/src/domain/generated/output.js';
3
+ const LIFECYCLE_TO_STATUS = {
4
+ [SdlcLifecycle.Started]: 'pending',
5
+ [SdlcLifecycle.Analyze]: 'in-progress',
6
+ [SdlcLifecycle.Requirements]: 'action-needed',
7
+ [SdlcLifecycle.Research]: 'in-progress',
8
+ [SdlcLifecycle.Planning]: 'in-progress',
9
+ [SdlcLifecycle.Implementation]: 'in-progress',
10
+ [SdlcLifecycle.Review]: 'action-needed',
11
+ [SdlcLifecycle.Maintain]: 'done',
12
+ [SdlcLifecycle.Blocked]: 'blocked',
13
+ [SdlcLifecycle.Pending]: 'pending',
14
+ [SdlcLifecycle.Deleting]: 'blocked',
15
+ [SdlcLifecycle.AwaitingUpstream]: 'action-needed',
16
+ [SdlcLifecycle.Archived]: 'done',
17
+ };
18
+ function lifecycleToStatus(lifecycle) {
19
+ return LIFECYCLE_TO_STATUS[lifecycle] ?? 'pending';
20
+ }
21
+ export async function getFeatureTreeData() {
22
+ const listFeatures = resolve('ListFeaturesUseCase');
23
+ const listRepos = resolve('ListRepositoriesUseCase');
24
+ const [features, repositories] = await Promise.all([listFeatures.execute(), listRepos.execute()]);
25
+ const repoByPath = new Map();
26
+ for (const repo of repositories) {
27
+ repoByPath.set(repo.path, { name: repo.name, remoteUrl: repo.remoteUrl });
28
+ }
29
+ const featureRows = features.map((feature) => {
30
+ const repo = repoByPath.get(feature.repositoryPath);
31
+ return {
32
+ id: feature.id,
33
+ name: feature.name,
34
+ status: lifecycleToStatus(feature.lifecycle),
35
+ lifecycle: feature.lifecycle,
36
+ branch: feature.branch,
37
+ repositoryName: repo?.name ?? feature.repositoryPath.split('/').pop() ?? feature.repositoryPath,
38
+ remoteUrl: repo?.remoteUrl,
39
+ parentId: feature.parentId ?? undefined,
40
+ };
41
+ });
42
+ const repos = repositories.map((repo) => ({
43
+ name: repo.name,
44
+ remoteUrl: repo.remoteUrl,
45
+ }));
46
+ return { features: featureRows, repos };
47
+ }
@@ -0,0 +1,4 @@
1
+ /** Skip static pre-rendering since we need runtime DI container and server context. */
2
+ export declare const dynamic = "force-dynamic";
3
+ export default function FeaturesPage(): Promise<import("react/jsx-runtime").JSX.Element>;
4
+ //# sourceMappingURL=page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/page.tsx"],"names":[],"mappings":"AAGA,uFAAuF;AACvF,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,wBAA8B,YAAY,qDAQzC"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { FeatureTreePageClient } from './feature-tree-page-client.js';
3
+ import { getFeatureTreeData } from './get-feature-tree-data.js';
4
+ /** Skip static pre-rendering since we need runtime DI container and server context. */
5
+ export const dynamic = 'force-dynamic';
6
+ export default async function FeaturesPage() {
7
+ const { features, repos } = await getFeatureTreeData();
8
+ return (_jsx("div", { className: "features-page-dotted-bg flex h-full flex-col p-6", children: _jsx(FeatureTreePageClient, { features: features, repos: repos }) }));
9
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAK/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EAAE,WAAW,EACjB,MAAM,EACN,uBAA8B,GAC/B,EAAE,wBAAwB,2CAoxB1B"}
1
+ {"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAW/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EAAE,WAAW,EACjB,MAAM,EACN,uBAA8B,GAC/B,EAAE,wBAAwB,2CAq4B1B"}
@@ -31,6 +31,8 @@ import { deriveInitialTab } from './drawer-view.js';
31
31
  import { useArtifactFetch } from './use-artifact-fetch.js';
32
32
  import { useDrawerSync } from './use-drawer-sync.js';
33
33
  import { useBranchSyncStatus } from '../../../hooks/use-branch-sync-status.js';
34
+ import { updateFeaturePinnedConfig } from '../../../app/actions/update-feature-pinned-config.js';
35
+ import { canSwitchPinnedConfig, getPinnedConfigSelection, } from '../../common/feature-drawer-tabs/pinned-config-utils.js';
34
36
  export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgentEnabled = true, }) {
35
37
  const featureFlags = useFeatureFlags();
36
38
  const { t } = useTranslation('web');
@@ -38,6 +40,11 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
38
40
  const rejectSound = useSoundAction('reject');
39
41
  // Track the view locally so SSE events can update the drawer type in real-time
40
42
  const [view, setView] = useState(initialView);
43
+ const [pinnedConfigSelection, setPinnedConfigSelection] = useState(() => (initialView.type === 'feature' ? getPinnedConfigSelection(initialView.node) : null));
44
+ const [lastSavedPinnedConfig, setLastSavedPinnedConfig] = useState(() => (initialView.type === 'feature' ? getPinnedConfigSelection(initialView.node) : null));
45
+ const [pinnedConfigSaving, setPinnedConfigSaving] = useState(false);
46
+ const [pinnedConfigError, setPinnedConfigError] = useState(null);
47
+ const syncedPinnedConfigKeyRef = useRef(null);
41
48
  // Sync when server re-renders with new props (e.g. after navigation).
42
49
  // When reopening the SAME feature, merge server data into the existing view
43
50
  // to preserve enriched fields (repositoryName, baseBranch, oneLiner, remoteUrl)
@@ -56,6 +63,25 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
56
63
  });
57
64
  }, [initialView]);
58
65
  const featureNode = view.type === 'feature' ? view.node : null;
66
+ const canSwitchPinnedConfigForFeature = featureNode
67
+ ? canSwitchPinnedConfig(featureNode.state)
68
+ : false;
69
+ useEffect(() => {
70
+ if (view.type !== 'feature' || pinnedConfigSaving) {
71
+ return;
72
+ }
73
+ const nextSelection = getPinnedConfigSelection(view.node);
74
+ const nextKey = nextSelection
75
+ ? `${view.node.featureId}:${nextSelection.agentType}:${nextSelection.modelId}`
76
+ : `${view.node.featureId}:none`;
77
+ const changed = syncedPinnedConfigKeyRef.current !== nextKey;
78
+ syncedPinnedConfigKeyRef.current = nextKey;
79
+ setPinnedConfigSelection(nextSelection);
80
+ setLastSavedPinnedConfig(nextSelection);
81
+ if (changed) {
82
+ setPinnedConfigError(null);
83
+ }
84
+ }, [view, pinnedConfigSaving]);
59
85
  // SSE: update drawer view when feature state changes
60
86
  const { events } = useAgentEventsContext();
61
87
  const processedCountRef = useRef(0);
@@ -222,7 +248,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
222
248
  const { attemptClose } = useGuardedDrawerClose({ open: isOpen, isDirty, onClose, onReset });
223
249
  // ── Approve / reject handlers ─────────────────────────────────────────
224
250
  const handleReject = useCallback(async (feedback, label, attachments = [], onDone) => {
225
- if (!featureNode?.featureId)
251
+ if (pinnedConfigSaving || !featureNode?.featureId)
226
252
  return;
227
253
  isRejectingRef.current = true;
228
254
  setIsRejecting(true);
@@ -254,12 +280,12 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
254
280
  isRejectingRef.current = false;
255
281
  setIsRejecting(false);
256
282
  }
257
- }, [featureNode, onClose, rejectSound]);
283
+ }, [featureNode, onClose, pinnedConfigSaving, rejectSound]);
258
284
  const handlePrdReject = useCallback((feedback, attachments) => handleReject(feedback, 'Requirements', attachments, () => setPrdSelections({})), [handleReject]);
259
285
  const handleTechReject = useCallback((feedback, attachments) => handleReject(feedback, 'Plan', attachments), [handleReject]);
260
286
  const handleMergeReject = useCallback((feedback, attachments) => handleReject(feedback, 'Merge', attachments), [handleReject]);
261
287
  const handleSimpleApprove = useCallback(async (label) => {
262
- if (!featureNode?.featureId)
288
+ if (pinnedConfigSaving || !featureNode?.featureId)
263
289
  return;
264
290
  const result = await approveFeature(featureNode.featureId);
265
291
  if (!result.approved) {
@@ -273,9 +299,9 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
273
299
  detail: { featureId: featureNode.featureId },
274
300
  }));
275
301
  onClose();
276
- }, [featureNode, onClose]);
302
+ }, [featureNode, onClose, pinnedConfigSaving]);
277
303
  const handlePrdApprove = useCallback(async (_actionId) => {
278
- if (view.type !== 'feature' || !featureNode)
304
+ if (pinnedConfigSaving || view.type !== 'feature' || !featureNode)
279
305
  return;
280
306
  let payload;
281
307
  if (prdData) {
@@ -302,7 +328,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
302
328
  }));
303
329
  setPrdSelections({});
304
330
  onClose();
305
- }, [view, featureNode, prdData, prdSelections, onClose]);
331
+ }, [view, featureNode, pinnedConfigSaving, prdData, prdSelections, onClose]);
306
332
  const handleTechApprove = useCallback(() => handleSimpleApprove('Plan'), [handleSimpleApprove]);
307
333
  const handleMergeApprove = useCallback(() => handleSimpleApprove('Merge'), [handleSimpleApprove]);
308
334
  const handleDelete = useCallback(async (featureId, cleanup, cascadeDelete, closePr) => {
@@ -332,6 +358,8 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
332
358
  router.push('/');
333
359
  }, [router]);
334
360
  const handleRetry = useCallback(async (featureId) => {
361
+ if (pinnedConfigSaving)
362
+ return;
335
363
  const result = await resumeFeature(featureId);
336
364
  if (result.error) {
337
365
  toast.error(result.error);
@@ -346,7 +374,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
346
374
  return prev;
347
375
  return { ...prev, node: { ...prev.node, state: 'running' } };
348
376
  });
349
- }, []);
377
+ }, [pinnedConfigSaving]);
350
378
  const handleStop = useCallback(async (featureId) => {
351
379
  const result = await stopFeature(featureId);
352
380
  if (!result.stopped) {
@@ -361,6 +389,8 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
361
389
  });
362
390
  }, []);
363
391
  const handleStart = useCallback(async (featureId) => {
392
+ if (pinnedConfigSaving)
393
+ return;
364
394
  const result = await startFeature(featureId);
365
395
  if (result.error) {
366
396
  toast.error(result.error);
@@ -373,7 +403,61 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
373
403
  return prev;
374
404
  return { ...prev, node: { ...prev.node, state: 'running' } };
375
405
  });
376
- }, []);
406
+ }, [pinnedConfigSaving]);
407
+ const handlePinnedConfigSave = useCallback(async (agentType, modelId) => {
408
+ if (!featureNode) {
409
+ return { ok: false, error: 'Feature is not loaded' };
410
+ }
411
+ if (!canSwitchPinnedConfig(featureNode.state)) {
412
+ return {
413
+ ok: false,
414
+ error: 'Pinned execution can only be changed before start, approval, or retry',
415
+ };
416
+ }
417
+ const previousSelection = lastSavedPinnedConfig ?? getPinnedConfigSelection(featureNode);
418
+ const nextSelection = {
419
+ agentType: agentType,
420
+ modelId,
421
+ };
422
+ setPinnedConfigSelection(nextSelection);
423
+ setPinnedConfigError(null);
424
+ setPinnedConfigSaving(true);
425
+ try {
426
+ const result = await updateFeaturePinnedConfig(featureNode.featureId, agentType, modelId);
427
+ if (!result.ok) {
428
+ const error = result.error ?? 'Failed to save pinned config';
429
+ setPinnedConfigSelection(previousSelection);
430
+ setPinnedConfigError(error);
431
+ toast.error(error);
432
+ return { ok: false, error };
433
+ }
434
+ setLastSavedPinnedConfig(nextSelection);
435
+ setView((prev) => {
436
+ if (prev.type !== 'feature' || prev.node.featureId !== featureNode.featureId) {
437
+ return prev;
438
+ }
439
+ return {
440
+ ...prev,
441
+ node: {
442
+ ...prev.node,
443
+ agentType: nextSelection.agentType,
444
+ modelId,
445
+ },
446
+ };
447
+ });
448
+ return { ok: true };
449
+ }
450
+ catch (error) {
451
+ const message = error instanceof Error ? error.message : 'Failed to save pinned config';
452
+ setPinnedConfigSelection(previousSelection);
453
+ setPinnedConfigError(message);
454
+ toast.error(message);
455
+ return { ok: false, error: message };
456
+ }
457
+ finally {
458
+ setPinnedConfigSaving(false);
459
+ }
460
+ }, [featureNode, lastSavedPinnedConfig]);
377
461
  // ── Hooks (always called unconditionally per Rules of Hooks) ──────────
378
462
  const featureActionsInput = featureNode?.repositoryPath && featureNode?.branch
379
463
  ? {
@@ -449,7 +533,14 @@ export function FeatureDrawerClient({ view: initialView, urlTab, interactiveAgen
449
533
  ...(featureNode.state === 'error' && { onRetry: handleRetry }),
450
534
  ...(featureNode.state === 'pending' && { onStart: handleStart }),
451
535
  };
452
- body = (_jsx(FeatureDrawerTabs, { featureName: featureNode.name, headerContent: headerContent, featureNode: enrichedNode, featureId: featureNode.featureId, initialTab: view.initialTab, urlTab: urlTab, sseEvents: events, prdData: prdData, prdSelections: prdSelections, onPrdSelect: (qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId })), onPrdApprove: handlePrdApprove, onPrdReject: handlePrdReject, isPrdLoading: isLoadingPrd, techData: techData, onTechApprove: handleTechApprove, onTechReject: handleTechReject, isTechLoading: isLoadingTech, productData: isLoadingTechProduct ? null : techProductData, mergeData: mergeData, onMergeApprove: handleMergeApprove, onMergeReject: handleMergeReject, isMergeLoading: isLoadingMerge, syncStatus: syncFeatureId ? syncData : undefined, syncLoading: syncLoading, syncError: syncError, onRefreshSync: syncFeatureId ? refreshSync : undefined, onRebaseOnMain: syncFeatureId ? featureActions.rebaseOnMain : undefined, rebaseLoading: featureActions.rebaseLoading, rebaseError: featureActions.rebaseError, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: setChatInput, interactiveAgentEnabled: interactiveAgentEnabled, onRetry: handleRetry, onStop: handleStop, onStart: handleStart }));
536
+ body = (_jsx(FeatureDrawerTabs, { featureName: featureNode.name, headerContent: headerContent, featureNode: enrichedNode, featureId: featureNode.featureId, initialTab: view.initialTab, urlTab: urlTab, sseEvents: events, prdData: prdData, prdSelections: prdSelections, onPrdSelect: (qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId })), onPrdApprove: handlePrdApprove, onPrdReject: handlePrdReject, isPrdLoading: isLoadingPrd, techData: techData, onTechApprove: handleTechApprove, onTechReject: handleTechReject, isTechLoading: isLoadingTech, productData: isLoadingTechProduct ? null : techProductData, mergeData: mergeData, onMergeApprove: handleMergeApprove, onMergeReject: handleMergeReject, isMergeLoading: isLoadingMerge, syncStatus: syncFeatureId ? syncData : undefined, syncLoading: syncLoading, syncError: syncError, onRefreshSync: syncFeatureId ? refreshSync : undefined, onRebaseOnMain: syncFeatureId ? featureActions.rebaseOnMain : undefined, rebaseLoading: featureActions.rebaseLoading, rebaseError: featureActions.rebaseError, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: setChatInput, pinnedConfig: canSwitchPinnedConfigForFeature && pinnedConfigSelection
537
+ ? {
538
+ ...pinnedConfigSelection,
539
+ saving: pinnedConfigSaving,
540
+ error: pinnedConfigError,
541
+ onSave: handlePinnedConfigSave,
542
+ }
543
+ : undefined, continuationActionsDisabled: pinnedConfigSaving, interactiveAgentEnabled: interactiveAgentEnabled, onRetry: handleRetry, onStop: handleStop, onStart: handleStart }));
453
544
  }
454
545
  return (_jsx(BaseDrawer, { open: isOpen, onClose: attemptClose, size: "lg", modal: false, "data-testid": view.type === 'feature' ? 'feature-drawer' : 'repository-drawer', children: body }));
455
546
  }
@@ -7,6 +7,7 @@ import type { MergeReviewData } from '../../common/merge-review/index.js';
7
7
  import type { RejectAttachment } from '../../common/drawer-action-bar/index.js';
8
8
  import type { FeatureTabKey } from '../../common/control-center-drawer/drawer-view.js';
9
9
  import type { BranchSyncData } from '../../../hooks/use-branch-sync-status.js';
10
+ import type { FeatureDrawerPinnedConfig } from './pinned-config-utils.js';
10
11
  export interface FeatureDrawerTabsProps {
11
12
  /** Feature name rendered in the inline header. */
12
13
  featureName?: string;
@@ -48,8 +49,10 @@ export interface FeatureDrawerTabsProps {
48
49
  isRejecting?: boolean;
49
50
  chatInput?: string;
50
51
  onChatInputChange?: (value: string) => void;
52
+ pinnedConfig?: FeatureDrawerPinnedConfig;
53
+ continuationActionsDisabled?: boolean;
51
54
  /** When false, the Chat tab is hidden from the tab bar (FR-17). Defaults to true. */
52
55
  interactiveAgentEnabled?: boolean;
53
56
  }
54
- export declare function FeatureDrawerTabs({ featureName, headerContent, featureNode, featureId, initialTab, urlTab, prdData, prdSelections, onPrdSelect, onPrdApprove, onPrdReject, isPrdLoading, techData, onTechApprove, onTechReject, isTechLoading, productData, mergeData, onMergeApprove, onMergeReject, isMergeLoading, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, isRejecting, chatInput, onChatInputChange, sseEvents, interactiveAgentEnabled, onRetry, onStop, onStart, }: FeatureDrawerTabsProps): import("react/jsx-runtime").JSX.Element;
57
+ export declare function FeatureDrawerTabs({ featureName, headerContent, featureNode, featureId, initialTab, urlTab, prdData, prdSelections, onPrdSelect, onPrdApprove, onPrdReject, isPrdLoading, techData, onTechApprove, onTechReject, isTechLoading, productData, mergeData, onMergeApprove, onMergeReject, isMergeLoading, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, isRejecting, chatInput, onChatInputChange, pinnedConfig, continuationActionsDisabled, sseEvents, interactiveAgentEnabled, onRetry, onStop, onStart, }: FeatureDrawerTabsProps): import("react/jsx-runtime").JSX.Element;
55
58
  //# sourceMappingURL=feature-drawer-tabs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-drawer-tabs.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feature-drawer-tabs.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/feature-drawer-tabs.tsx"],"names":[],"mappings":"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"}
@@ -78,7 +78,7 @@ const TAB_FETCHERS = {
78
78
  activity: fetchActivity,
79
79
  plan: fetchPlan,
80
80
  };
81
- export function FeatureDrawerTabs({ featureName, headerContent, featureNode, featureId, initialTab, urlTab, prdData, prdSelections, onPrdSelect, onPrdApprove, onPrdReject, isPrdLoading, techData, onTechApprove, onTechReject, isTechLoading, productData, mergeData, onMergeApprove, onMergeReject, isMergeLoading, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, isRejecting, chatInput, onChatInputChange, sseEvents, interactiveAgentEnabled = true, onRetry, onStop, onStart, }) {
81
+ export function FeatureDrawerTabs({ featureName, headerContent, featureNode, featureId, initialTab, urlTab, prdData, prdSelections, onPrdSelect, onPrdApprove, onPrdReject, isPrdLoading, techData, onTechApprove, onTechReject, isTechLoading, productData, mergeData, onMergeApprove, onMergeReject, isMergeLoading, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, isRejecting, chatInput, onChatInputChange, pinnedConfig, continuationActionsDisabled = false, sseEvents, interactiveAgentEnabled = true, onRetry, onStop, onStart, }) {
82
82
  const pathname = usePathname();
83
83
  const visibleTabs = useMemo(() => computeVisibleTabs(featureNode, interactiveAgentEnabled), [featureNode, interactiveAgentEnabled]);
84
84
  const visibleTabDefs = useMemo(() => ALL_TABS.filter((t) => visibleTabs.includes(t.key)).map((t) => t.key === 'merge-review' && featureNode.lifecycle === 'maintain'
@@ -261,9 +261,9 @@ export function FeatureDrawerTabs({ featureName, headerContent, featureNode, fea
261
261
  }) }), _jsxs("div", { className: "bg-muted/40 shrink-0 border-b", children: [featureName ? (_jsxs("div", { className: "flex h-12 items-stretch gap-2 pr-0 pl-4", "data-testid": "feature-drawer-header", children: [_jsx("div", { className: "flex items-center", children: featureNode.fastMode ? (_jsx(Zap, { className: "size-4 shrink-0 text-amber-500" })) : (_jsx(Layers, { className: "text-muted-foreground/50 size-4 shrink-0" })) }), _jsx("h2", { className: "text-foreground flex min-w-0 items-center truncate text-base font-semibold tracking-tight", children: featureName }), featureNode.repositoryName ? (_jsxs("span", { className: "animate-in fade-in flex shrink-0 items-center gap-1.5 self-center duration-200", children: [_jsx("span", { className: "text-muted-foreground/30 text-sm", children: "/" }), featureNode.remoteUrl ? (_jsx("a", { href: featureNode.remoteUrl, target: "_blank", rel: "noopener noreferrer", className: "text-muted-foreground hover:text-foreground text-sm", children: featureNode.repositoryName })) : (_jsx("span", { className: "text-muted-foreground text-sm", children: featureNode.repositoryName }))] })) : (_jsxs("span", { className: "flex items-center gap-1.5 self-center", children: [_jsx("span", { className: "text-muted-foreground/30 text-sm", children: "/" }), _jsx("span", { className: "bg-muted h-4 w-16 animate-pulse rounded" })] })), _jsx(TooltipProvider, { delayDuration: 300, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "ml-auto flex shrink-0 cursor-default items-center self-stretch text-xs font-medium", children: [_jsxs("div", { className: cn('flex items-center gap-1.5 self-stretch px-3', featureNodeStateConfig[featureNode.state].labelClass), children: [featureNode.state === 'running' ? (_jsx(CometSpinner, { size: "sm", className: "shrink-0" })) : ((() => {
262
262
  const I = featureNodeStateConfig[featureNode.state].icon;
263
263
  return _jsx(I, { className: "size-3.5 shrink-0" });
264
- })()), featureNodeStateConfig[featureNode.state].label] }), featureNode.state === 'pending' && onStart ? (_jsxs("button", { type: "button", onClick: () => onStart(featureNode.featureId), className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-green-500/10 hover:text-green-600 dark:hover:text-green-400", "data-testid": "feature-drawer-start-button", children: [_jsx(Play, { className: "size-3.5" }), " Start"] })) : featureNode.state === 'error' && onRetry ? (_jsxs("button", { type: "button", onClick: () => onRetry(featureNode.featureId), className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400", "data-testid": "feature-drawer-retry-button", children: [_jsx(RotateCcw, { className: "size-3.5" }), " Retry"] })) : featureNode.state === 'running' && onStop ? (_jsxs("button", { type: "button", onClick: () => onStop(featureNode.featureId), className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400", "data-testid": "feature-drawer-stop-button", children: [_jsx(Square, { className: "size-3.5" }), " Stop"] })) : null] }) }), featureNode.errorMessage ? (_jsxs(TooltipContent, { side: "bottom", align: "end", sideOffset: 4, className: "z-[100] max-w-xs cursor-pointer text-xs leading-relaxed select-text", onClick: () => {
264
+ })()), featureNodeStateConfig[featureNode.state].label] }), featureNode.state === 'pending' && onStart ? (_jsxs("button", { type: "button", onClick: () => onStart(featureNode.featureId), disabled: continuationActionsDisabled, className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-green-500/10 hover:text-green-600 disabled:pointer-events-none disabled:opacity-50 dark:hover:text-green-400", "data-testid": "feature-drawer-start-button", children: [_jsx(Play, { className: "size-3.5" }), " Start"] })) : featureNode.state === 'error' && onRetry ? (_jsxs("button", { type: "button", onClick: () => onRetry(featureNode.featureId), disabled: continuationActionsDisabled, className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 disabled:pointer-events-none disabled:opacity-50 dark:hover:text-red-400", "data-testid": "feature-drawer-retry-button", children: [_jsx(RotateCcw, { className: "size-3.5" }), " Retry"] })) : featureNode.state === 'running' && onStop ? (_jsxs("button", { type: "button", onClick: () => onStop(featureNode.featureId), className: "text-muted-foreground flex items-center gap-1 self-stretch px-3 hover:bg-red-500/10 hover:text-red-500 dark:hover:text-red-400", "data-testid": "feature-drawer-stop-button", children: [_jsx(Square, { className: "size-3.5" }), " Stop"] })) : null] }) }), featureNode.errorMessage ? (_jsxs(TooltipContent, { side: "bottom", align: "end", sideOffset: 4, className: "z-[100] max-w-xs cursor-pointer text-xs leading-relaxed select-text", onClick: () => {
265
265
  void navigator.clipboard.writeText(featureNode.errorMessage);
266
- }, children: [featureNode.errorMessage, _jsx("span", { className: "text-muted-foreground ml-1 text-[10px] italic", children: "(click to copy)" })] })) : null] }) })] })) : null, headerContent] }), _jsx(TabsContent, { value: "overview", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(OverviewTab, { data: featureNode, syncStatus: syncStatus, syncLoading: syncLoading, syncError: syncError, onRefreshSync: onRefreshSync, onRebaseOnMain: onRebaseOnMain, rebaseLoading: rebaseLoading, rebaseError: rebaseError }) }), _jsx(TabsContent, { value: "activity", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(ActivityTab, { timings: tabs.activity.data?.timings ?? null, loading: tabs.activity.loading, error: tabs.activity.error, rejectionFeedback: tabs.activity.data?.rejectionFeedback }) }), _jsx(TabsContent, { value: "log", className: "mt-0 flex-1 overflow-hidden", children: _jsx(LogTab, { content: featureLogs.content, isConnected: featureLogs.isConnected, error: featureLogs.error }) }), _jsx(TabsContent, { value: "plan", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(PlanTab, { plan: tabs.plan.data, loading: tabs.plan.loading, error: tabs.plan.error }) }), visibleTabs.includes('prd-review') ? (_jsx(TabsContent, { value: "prd-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: prdData ? (_jsx(PrdQuestionnaire, { data: prdData, selections: prdSelections ?? {}, onSelect: onPrdSelect ?? (() => undefined), onApprove: onPrdApprove ?? (() => undefined), onReject: onPrdReject, isProcessing: isPrdLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('tech-decisions') ? (_jsx(TabsContent, { value: "tech-decisions", className: "mt-0 flex min-h-0 flex-1 flex-col", children: techData ? (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(TechDecisionsContent, { data: techData }) }), _jsx(DrawerActionBarForTech, { onApprove: onTechApprove ?? (() => undefined), onReject: onTechReject, isProcessing: isTechLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })] })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('product-decisions') ? (_jsx(TabsContent, { value: "product-decisions", className: "mt-0 flex-1 overflow-y-auto", children: productData === null ? (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) : productData ? (_jsx(ProductDecisionsSummary, { data: productData })) : (_jsx("p", { className: "text-muted-foreground p-4 text-center text-sm", children: "No product decisions available." })) })) : null, visibleTabs.includes('merge-review') ? (_jsx(TabsContent, { value: "merge-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: mergeData ? (_jsx(MergeReview, { data: mergeData, readOnly: featureNode.lifecycle === 'maintain', onApprove: onMergeApprove ?? (() => undefined), onReject: onMergeReject, isProcessing: isMergeLoading, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: isMergeLoading ? (_jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" })) : (_jsxs("div", { className: "text-muted-foreground flex flex-col items-center gap-2 text-sm", children: [_jsx(AlertCircle, { className: "h-6 w-6" }), _jsx("span", { children: "Merge review data unavailable" })] })) })) })) : null, visibleTabs.includes('chat') ? (_jsx(TabsContent, { value: "chat", className: "mt-0 flex min-h-0 flex-1 flex-col overflow-hidden", children: _jsx(ChatTab, { featureId: featureId, worktreePath: featureNode.worktreePath }) })) : null] }) }));
266
+ }, children: [featureNode.errorMessage, _jsx("span", { className: "text-muted-foreground ml-1 text-[10px] italic", children: "(click to copy)" })] })) : null] }) })] })) : null, headerContent] }), _jsx(TabsContent, { value: "overview", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(OverviewTab, { data: featureNode, pinnedConfig: pinnedConfig, syncStatus: syncStatus, syncLoading: syncLoading, syncError: syncError, onRefreshSync: onRefreshSync, onRebaseOnMain: onRebaseOnMain, rebaseLoading: rebaseLoading, rebaseError: rebaseError }) }), _jsx(TabsContent, { value: "activity", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(ActivityTab, { timings: tabs.activity.data?.timings ?? null, loading: tabs.activity.loading, error: tabs.activity.error, rejectionFeedback: tabs.activity.data?.rejectionFeedback }) }), _jsx(TabsContent, { value: "log", className: "mt-0 flex-1 overflow-hidden", children: _jsx(LogTab, { content: featureLogs.content, isConnected: featureLogs.isConnected, error: featureLogs.error }) }), _jsx(TabsContent, { value: "plan", className: "mt-0 flex-1 overflow-y-auto", children: _jsx(PlanTab, { plan: tabs.plan.data, loading: tabs.plan.loading, error: tabs.plan.error }) }), visibleTabs.includes('prd-review') ? (_jsx(TabsContent, { value: "prd-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: prdData ? (_jsx(PrdQuestionnaire, { data: prdData, selections: prdSelections ?? {}, onSelect: onPrdSelect ?? (() => undefined), onApprove: onPrdApprove ?? (() => undefined), onReject: onPrdReject, isProcessing: Boolean((isPrdLoading ?? false) || continuationActionsDisabled), isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('tech-decisions') ? (_jsx(TabsContent, { value: "tech-decisions", className: "mt-0 flex min-h-0 flex-1 flex-col", children: techData ? (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(TechDecisionsContent, { data: techData }) }), _jsx(DrawerActionBarForTech, { onApprove: onTechApprove ?? (() => undefined), onReject: onTechReject, isProcessing: Boolean((isTechLoading ?? false) || continuationActionsDisabled), isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })] })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) })) : null, visibleTabs.includes('product-decisions') ? (_jsx(TabsContent, { value: "product-decisions", className: "mt-0 flex-1 overflow-y-auto", children: productData === null ? (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" }) })) : productData ? (_jsx(ProductDecisionsSummary, { data: productData })) : (_jsx("p", { className: "text-muted-foreground p-4 text-center text-sm", children: "No product decisions available." })) })) : null, visibleTabs.includes('merge-review') ? (_jsx(TabsContent, { value: "merge-review", className: "mt-0 flex min-h-0 flex-1 flex-col", children: mergeData ? (_jsx(MergeReview, { data: mergeData, readOnly: featureNode.lifecycle === 'maintain', onApprove: onMergeApprove ?? (() => undefined), onReject: onMergeReject, isProcessing: Boolean((isMergeLoading ?? false) || continuationActionsDisabled), isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: onChatInputChange })) : (_jsx("div", { className: "flex items-center justify-center p-8", children: isMergeLoading ? (_jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin" })) : (_jsxs("div", { className: "text-muted-foreground flex flex-col items-center gap-2 text-sm", children: [_jsx(AlertCircle, { className: "h-6 w-6" }), _jsx("span", { children: "Merge review data unavailable" })] })) })) })) : null, visibleTabs.includes('chat') ? (_jsx(TabsContent, { value: "chat", className: "mt-0 flex min-h-0 flex-1 flex-col overflow-hidden", children: _jsx(ChatTab, { featureId: featureId, worktreePath: featureNode.worktreePath }) })) : null] }) }));
267
267
  }
268
268
  // ── Private helper ──────────────────────────────────────────────────────
269
269
  function DrawerActionBarForTech({ onApprove, onReject, isProcessing, isRejecting, chatInput, onChatInputChange, }) {
@@ -1,7 +1,9 @@
1
1
  import type { FeatureNodeData } from '../../common/feature-node/index.js';
2
2
  import type { BranchSyncData } from '../../../hooks/use-branch-sync-status.js';
3
+ import { type FeatureDrawerPinnedConfig } from './pinned-config-utils.js';
3
4
  export interface OverviewTabProps {
4
5
  data: FeatureNodeData;
6
+ pinnedConfig?: FeatureDrawerPinnedConfig;
5
7
  syncStatus?: BranchSyncData | null;
6
8
  syncLoading?: boolean;
7
9
  syncError?: string | null;
@@ -10,5 +12,5 @@ export interface OverviewTabProps {
10
12
  rebaseLoading?: boolean;
11
13
  rebaseError?: string | null;
12
14
  }
13
- export declare function OverviewTab({ data, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }: OverviewTabProps): import("react/jsx-runtime").JSX.Element;
15
+ export declare function OverviewTab({ data, pinnedConfig, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }: OverviewTabProps): import("react/jsx-runtime").JSX.Element;
14
16
  //# sourceMappingURL=overview-tab.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overview-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAOxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AA2GrE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,UAAU,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,UAAU,EACV,WAAW,EACX,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,GACZ,EAAE,gBAAgB,2CAuLlB"}
1
+ {"version":3,"file":"overview-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/overview-tab.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAQxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AA2G9F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC,UAAU,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,GACZ,EAAE,gBAAgB,2CAuLlB"}
@@ -10,9 +10,11 @@ import { CiStatusBadge } from '../../common/ci-status-badge/index.js';
10
10
  import { CometSpinner } from '../../ui/comet-spinner.js';
11
11
  import { ActionButton } from '../../common/action-button/index.js';
12
12
  import { featureNodeStateConfig } from '../../common/feature-node/index.js';
13
+ import { AgentModelPicker } from '../../features/settings/AgentModelPicker/index.js';
13
14
  import { getAgentTypeIcon, agentTypeLabels, } from '../../common/feature-node/agent-type-icons.js';
14
15
  import { getModelMeta } from '../../../lib/model-metadata.js';
15
16
  import { formatDuration } from '../../../lib/format-duration.js';
17
+ import { canSwitchPinnedConfig } from './pinned-config-utils.js';
16
18
  // ── Primitives ──────────────────────────────────────────────────────
17
19
  function Section({ icon: Icon, title, children, }) {
18
20
  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] }));
@@ -74,7 +76,7 @@ const prColor = {
74
76
  [PrStatus.Merged]: 'text-purple-600 dark:text-purple-400',
75
77
  [PrStatus.Closed]: 'text-red-600 dark:text-red-400',
76
78
  };
77
- export function OverviewTab({ data, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }) {
79
+ export function OverviewTab({ data, pinnedConfig, syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }) {
78
80
  const isCompleted = data.lifecycle === 'maintain';
79
81
  const isRunning = data.state === 'running' || data.state === 'action-required';
80
82
  const elapsedTime = useElapsedTime(isRunning ? data.startedAt : undefined);
@@ -86,7 +88,7 @@ export function OverviewTab({ data, syncStatus, syncLoading, syncError, onRefres
86
88
  return _jsx(I, { className: "size-3.5 shrink-0 opacity-50" });
87
89
  })()
88
90
  : 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 })] }));
91
+ 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, pinnedConfig: pinnedConfig })] }));
90
92
  }
91
93
  // ── Sync card ───────────────────────────────────────────────────────
92
94
  function SyncCard({ syncStatus, syncLoading, syncError, onRefreshSync, onRebaseOnMain, rebaseLoading, rebaseError, }) {
@@ -97,19 +99,28 @@ function SyncCard({ syncStatus, syncLoading, syncError, onRefreshSync, onRebaseO
97
99
  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
100
  }
99
101
  // ── Settings ────────────────────────────────────────────────────────
100
- function SettingsBlock({ data }) {
101
- const has = data.approvalGates != null ||
102
+ function PinnedConfigCard({ pinnedConfig }) {
103
+ const AgentIcon = getAgentTypeIcon(pinnedConfig.agentType);
104
+ const modelName = pinnedConfig.modelId
105
+ ? getModelMeta(pinnedConfig.modelId).displayName || pinnedConfig.modelId
106
+ : 'No model selected';
107
+ return (_jsxs(Card, { "data-testid": "feature-pinned-config-card", className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-foreground/40 flex items-center gap-1 text-[10px] font-medium tracking-wider uppercase", children: [_jsx(Settings, { className: "size-3" }), " Pinned Execution"] }), _jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(AgentIcon, { className: "size-4 shrink-0 opacity-60" }), _jsx("span", { className: "font-medium", children: agentTypeLabels[pinnedConfig.agentType] ??
108
+ pinnedConfig.agentType }), _jsx("span", { className: "text-foreground/20", children: "/" }), _jsx("span", { className: "text-foreground/60", children: modelName })] }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Change the pinned agent and model before the next start, approval, or retry." })] }), _jsx(AgentModelPicker, { initialAgentType: pinnedConfig.agentType, initialModel: pinnedConfig.modelId, agentType: pinnedConfig.agentType, model: pinnedConfig.modelId, onSave: pinnedConfig.onSave, saveError: pinnedConfig.error, saving: pinnedConfig.saving, disabled: pinnedConfig.saving, mode: "settings" })] }));
109
+ }
110
+ function SettingsBlock({ data, pinnedConfig, }) {
111
+ const hasSettings = data.approvalGates != null ||
102
112
  data.push != null ||
103
113
  data.openPr != null ||
104
114
  data.ciWatchEnabled != null ||
105
115
  data.enableEvidence != null ||
106
116
  data.forkAndPr != null ||
107
117
  data.commitSpecs != null;
108
- if (!has)
118
+ const showPinnedConfig = pinnedConfig != null && canSwitchPinnedConfig(data.state);
119
+ if (!hasSettings && !showPinnedConfig)
109
120
  return null;
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] }) }));
121
+ return (_jsx(Section, { icon: Settings, title: "Settings", children: _jsxs("div", { className: "flex flex-col gap-2", children: [showPinnedConfig ? _jsx(PinnedConfigCard, { pinnedConfig: pinnedConfig }) : null, hasSettings ? (_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 ||
122
+ data.openPr != null ||
123
+ data.ciWatchEnabled != null ||
124
+ data.commitSpecs != null ||
125
+ 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] })) : null] }) }));
115
126
  }
@@ -15,6 +15,10 @@ export declare const DoneWithMergedPr: Story;
15
15
  export declare const Blocked: Story;
16
16
  /** Error state showing error message detail. */
17
17
  export declare const Error: Story;
18
+ /** Pending feature with the pinned execution switch visible. */
19
+ export declare const PendingWithPinnedConfigSwitch: Story;
20
+ /** Pending feature showing inline save feedback for the pinned execution switch. */
21
+ export declare const PendingWithPinnedConfigError: Story;
18
22
  /** Error state with retry button visible. */
19
23
  export declare const ErrorWithRetry: Story;
20
24
  /** Running state with stop button visible. */