@shepai/cli 1.178.0 → 1.178.1-pr536.42a22c6

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 (474) hide show
  1. package/apis/json-schema/Application.yaml +40 -0
  2. package/apis/json-schema/ApplicationStatus.yaml +8 -0
  3. package/dist/packages/core/src/application/ports/output/repositories/application-repository.interface.d.ts +17 -0
  4. package/dist/packages/core/src/application/ports/output/repositories/application-repository.interface.d.ts.map +1 -0
  5. package/dist/packages/core/src/application/ports/output/repositories/application-repository.interface.js +6 -0
  6. package/dist/packages/core/src/application/ports/output/repositories/index.d.ts +1 -0
  7. package/dist/packages/core/src/application/ports/output/repositories/index.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/use-cases/applications/create-application.use-case.d.ts +29 -0
  9. package/dist/packages/core/src/application/use-cases/applications/create-application.use-case.d.ts.map +1 -0
  10. package/dist/packages/core/src/application/use-cases/applications/create-application.use-case.js +135 -0
  11. package/dist/packages/core/src/application/use-cases/applications/delete-application.use-case.d.ts +15 -0
  12. package/dist/packages/core/src/application/use-cases/applications/delete-application.use-case.d.ts.map +1 -0
  13. package/dist/packages/core/src/application/use-cases/applications/delete-application.use-case.js +45 -0
  14. package/dist/packages/core/src/application/use-cases/applications/get-application.use-case.d.ts +13 -0
  15. package/dist/packages/core/src/application/use-cases/applications/get-application.use-case.d.ts.map +1 -0
  16. package/dist/packages/core/src/application/use-cases/applications/get-application.use-case.js +33 -0
  17. package/dist/packages/core/src/application/use-cases/applications/index.d.ts +13 -0
  18. package/dist/packages/core/src/application/use-cases/applications/index.d.ts.map +1 -0
  19. package/dist/packages/core/src/application/use-cases/applications/index.js +10 -0
  20. package/dist/packages/core/src/application/use-cases/applications/list-applications.use-case.d.ts +13 -0
  21. package/dist/packages/core/src/application/use-cases/applications/list-applications.use-case.d.ts.map +1 -0
  22. package/dist/packages/core/src/application/use-cases/applications/list-applications.use-case.js +33 -0
  23. package/dist/packages/core/src/application/use-cases/applications/update-application.use-case.d.ts +14 -0
  24. package/dist/packages/core/src/application/use-cases/applications/update-application.use-case.d.ts.map +1 -0
  25. package/dist/packages/core/src/application/use-cases/applications/update-application.use-case.js +33 -0
  26. package/dist/packages/core/src/domain/generated/output.d.ts +42 -0
  27. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  28. package/dist/packages/core/src/domain/generated/output.js +6 -0
  29. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  30. package/dist/packages/core/src/infrastructure/di/container.js +32 -0
  31. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/application.mapper.d.ts +37 -0
  32. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/application.mapper.d.ts.map +1 -0
  33. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/application.mapper.js +52 -0
  34. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/056-create-applications-table.d.ts +5 -0
  35. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/056-create-applications-table.d.ts.map +1 -0
  36. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/056-create-applications-table.js +34 -0
  37. package/dist/packages/core/src/infrastructure/repositories/sqlite-application.repository.d.ts +21 -0
  38. package/dist/packages/core/src/infrastructure/repositories/sqlite-application.repository.d.ts.map +1 -0
  39. package/dist/packages/core/src/infrastructure/repositories/sqlite-application.repository.js +98 -0
  40. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
  41. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +31 -5
  42. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts +14 -0
  43. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  44. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +63 -0
  45. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
  46. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +57 -10
  47. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.d.ts.map +1 -1
  48. package/dist/src/presentation/web/app/(dashboard)/get-graph-data.js +11 -1
  49. package/dist/src/presentation/web/app/actions/check-all-agents-status.d.ts +7 -0
  50. package/dist/src/presentation/web/app/actions/check-all-agents-status.d.ts.map +1 -0
  51. package/dist/src/presentation/web/app/actions/check-all-agents-status.js +30 -0
  52. package/dist/src/presentation/web/app/actions/create-application.d.ts +13 -0
  53. package/dist/src/presentation/web/app/actions/create-application.d.ts.map +1 -0
  54. package/dist/src/presentation/web/app/actions/create-application.js +20 -0
  55. package/dist/src/presentation/web/app/actions/create-project-and-feature.d.ts +20 -0
  56. package/dist/src/presentation/web/app/actions/create-project-and-feature.d.ts.map +1 -0
  57. package/dist/src/presentation/web/app/actions/create-project-and-feature.js +84 -0
  58. package/dist/src/presentation/web/app/actions/delete-application.d.ts +4 -0
  59. package/dist/src/presentation/web/app/actions/delete-application.d.ts.map +1 -0
  60. package/dist/src/presentation/web/app/actions/delete-application.js +16 -0
  61. package/dist/src/presentation/web/app/application/[id]/page.d.ts +11 -0
  62. package/dist/src/presentation/web/app/application/[id]/page.d.ts.map +1 -0
  63. package/dist/src/presentation/web/app/application/[id]/page.js +16 -0
  64. package/dist/src/presentation/web/app/build-graph-nodes.d.ts +3 -1
  65. package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
  66. package/dist/src/presentation/web/app/build-graph-nodes.js +19 -0
  67. package/dist/src/presentation/web/components/common/application-node/application-node-config.d.ts +24 -0
  68. package/dist/src/presentation/web/components/common/application-node/application-node-config.d.ts.map +1 -0
  69. package/dist/src/presentation/web/components/common/application-node/application-node-config.js +1 -0
  70. package/dist/src/presentation/web/components/common/application-node/application-node.d.ts +7 -0
  71. package/dist/src/presentation/web/components/common/application-node/application-node.d.ts.map +1 -0
  72. package/dist/src/presentation/web/components/common/application-node/application-node.js +41 -0
  73. package/dist/src/presentation/web/components/common/application-node/application-node.stories.d.ts +12 -0
  74. package/dist/src/presentation/web/components/common/application-node/application-node.stories.d.ts.map +1 -0
  75. package/dist/src/presentation/web/components/common/application-node/application-node.stories.js +100 -0
  76. package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.d.ts.map +1 -1
  77. package/dist/src/presentation/web/components/common/attachment-chip/attachment-chip.js +1 -1
  78. package/dist/src/presentation/web/components/features/application-page/application-page.d.ts +8 -0
  79. package/dist/src/presentation/web/components/features/application-page/application-page.d.ts.map +1 -0
  80. package/dist/src/presentation/web/components/features/application-page/application-page.js +86 -0
  81. package/dist/src/presentation/web/components/features/application-page/application-page.stories.d.ts +9 -0
  82. package/dist/src/presentation/web/components/features/application-page/application-page.stories.d.ts.map +1 -0
  83. package/dist/src/presentation/web/components/features/application-page/application-page.stories.js +51 -0
  84. package/dist/src/presentation/web/components/features/chat/ChatSheet.d.ts.map +1 -1
  85. package/dist/src/presentation/web/components/features/chat/ChatSheet.js +4 -2
  86. package/dist/src/presentation/web/components/features/chat/ChatTab.d.ts +5 -1
  87. package/dist/src/presentation/web/components/features/chat/ChatTab.d.ts.map +1 -1
  88. package/dist/src/presentation/web/components/features/chat/ChatTab.js +3 -3
  89. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.d.ts +3 -1
  90. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.d.ts.map +1 -1
  91. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +181 -120
  92. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.stories.d.ts +4 -16
  93. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.stories.d.ts.map +1 -1
  94. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.stories.js +16 -109
  95. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  96. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +21 -3
  97. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +4 -0
  98. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  99. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +25 -1
  100. package/dist/src/presentation/web/components/features/control-center/use-fab-actions.d.ts +2 -1
  101. package/dist/src/presentation/web/components/features/control-center/use-fab-actions.d.ts.map +1 -1
  102. package/dist/src/presentation/web/components/features/control-center/use-fab-actions.js +9 -2
  103. package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map +1 -1
  104. package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.js +2 -9
  105. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts +2 -1
  106. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  107. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +2 -0
  108. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts +3 -1
  109. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.d.ts.map +1 -1
  110. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/index.js +9 -4
  111. package/dist/src/presentation/web/hooks/use-graph-state.d.ts +5 -0
  112. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
  113. package/dist/src/presentation/web/hooks/use-graph-state.js +37 -2
  114. package/dist/src/presentation/web/lib/derive-graph.d.ts +11 -1
  115. package/dist/src/presentation/web/lib/derive-graph.d.ts.map +1 -1
  116. package/dist/src/presentation/web/lib/derive-graph.js +35 -1
  117. package/dist/src/presentation/web/lib/layout-with-dagre.d.ts.map +1 -1
  118. package/dist/src/presentation/web/lib/layout-with-dagre.js +1 -0
  119. package/dist/translations/ar/web.json +2 -1
  120. package/dist/translations/de/web.json +2 -1
  121. package/dist/translations/en/web.json +2 -1
  122. package/dist/translations/es/web.json +2 -1
  123. package/dist/translations/fr/web.json +2 -1
  124. package/dist/translations/he/web.json +2 -1
  125. package/dist/translations/pt/web.json +2 -1
  126. package/dist/translations/ru/web.json +2 -1
  127. package/dist/translations/uk/web.json +2 -1
  128. package/dist/tsconfig.build.tsbuildinfo +1 -1
  129. package/package.json +1 -1
  130. package/web/.next/BUILD_ID +1 -1
  131. package/web/.next/app-path-routes-manifest.json +1 -0
  132. package/web/.next/build-manifest.json +2 -2
  133. package/web/.next/fallback-build-manifest.json +2 -2
  134. package/web/.next/prerender-manifest.json +3 -3
  135. package/web/.next/required-server-files.js +3 -3
  136. package/web/.next/required-server-files.json +3 -3
  137. package/web/.next/routes-manifest.json +8 -0
  138. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +96 -81
  139. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +4 -3
  140. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  141. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  142. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +92 -77
  143. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +4 -3
  144. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  145. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  146. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +98 -83
  147. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +4 -3
  148. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  149. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  150. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +114 -99
  151. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +4 -3
  152. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  153. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  154. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +114 -99
  155. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +4 -3
  156. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  157. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  158. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +94 -79
  159. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +4 -3
  160. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  161. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  162. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +94 -79
  163. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +4 -3
  164. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  165. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  166. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +92 -77
  167. package/web/.next/server/app/(dashboard)/chat/page.js +4 -3
  168. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  169. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  170. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +98 -83
  171. package/web/.next/server/app/(dashboard)/create/page.js +4 -3
  172. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  173. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  174. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +114 -99
  175. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +4 -3
  176. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  177. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  178. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +114 -99
  179. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +4 -3
  180. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  181. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  182. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +92 -77
  183. package/web/.next/server/app/(dashboard)/page.js +4 -3
  184. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  185. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  186. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +94 -79
  187. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +4 -3
  188. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  189. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  190. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +94 -79
  191. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +4 -3
  192. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  193. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  194. package/web/.next/server/app/_global-error/page.js +1 -1
  195. package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  196. package/web/.next/server/app/_global-error.html +2 -2
  197. package/web/.next/server/app/_global-error.rsc +1 -1
  198. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  199. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  200. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  201. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  202. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  203. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +27 -12
  204. package/web/.next/server/app/_not-found/page.js +2 -2
  205. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  206. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  207. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  208. package/web/.next/server/app/api/attachments/upload-from-path/route.js +1 -1
  209. package/web/.next/server/app/api/attachments/upload-from-path/route.js.nft.json +1 -1
  210. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  211. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  212. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  213. package/web/.next/server/app/application/[id]/page/app-paths-manifest.json +3 -0
  214. package/web/.next/server/app/application/[id]/page/build-manifest.json +18 -0
  215. package/web/.next/server/app/application/[id]/page/next-font-manifest.json +6 -0
  216. package/web/.next/server/app/application/[id]/page/react-loadable-manifest.json +1 -0
  217. package/web/.next/server/app/application/[id]/page/server-reference-manifest.json +110 -0
  218. package/web/.next/server/app/application/[id]/page.js +18 -0
  219. package/web/.next/server/app/application/[id]/page.js.map +5 -0
  220. package/web/.next/server/app/application/[id]/page.js.nft.json +1 -0
  221. package/web/.next/server/app/application/[id]/page_client-reference-manifest.js +2 -0
  222. package/web/.next/server/app/features/page/server-reference-manifest.json +27 -12
  223. package/web/.next/server/app/features/page.js +2 -2
  224. package/web/.next/server/app/features/page.js.nft.json +1 -1
  225. package/web/.next/server/app/features/page_client-reference-manifest.js +1 -1
  226. package/web/.next/server/app/settings/page/server-reference-manifest.json +33 -18
  227. package/web/.next/server/app/settings/page.js +2 -2
  228. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  229. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  230. package/web/.next/server/app/skills/page/server-reference-manifest.json +41 -26
  231. package/web/.next/server/app/skills/page.js +2 -2
  232. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  233. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  234. package/web/.next/server/app/tools/page/server-reference-manifest.json +37 -22
  235. package/web/.next/server/app/tools/page.js +2 -2
  236. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  237. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  238. package/web/.next/server/app/version/page/server-reference-manifest.json +27 -12
  239. package/web/.next/server/app/version/page.js +2 -2
  240. package/web/.next/server/app/version/page.js.nft.json +1 -1
  241. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  242. package/web/.next/server/app-paths-manifest.json +1 -0
  243. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  244. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  245. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  246. package/web/.next/server/chunks/{[root-of-the-server]__ea653642._.js → [root-of-the-server]__a5879003._.js} +2 -2
  247. package/web/.next/server/chunks/{[root-of-the-server]__ea653642._.js.map → [root-of-the-server]__a5879003._.js.map} +1 -1
  248. package/web/.next/server/chunks/[root-of-the-server]__c78383b1._.js +1 -1
  249. package/web/.next/server/chunks/[root-of-the-server]__c78383b1._.js.map +1 -1
  250. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
  251. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  252. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_17d0c3c1.js +3 -0
  253. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_17d0c3c1.js.map +1 -0
  254. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_717a531e.js +3 -0
  255. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_717a531e.js.map +1 -0
  256. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_6ed3ab8b.js +3 -0
  257. package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_6ed3ab8b.js.map +1 -0
  258. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  259. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  260. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
  261. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  262. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_281e0ef8._.js +1 -1
  263. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_281e0ef8._.js.map +1 -1
  264. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_a593f310._.js +1 -1
  265. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_a593f310._.js.map +1 -1
  266. package/web/.next/server/chunks/ssr/[root-of-the-server]__00efb844._.js +4 -0
  267. package/web/.next/server/chunks/ssr/[root-of-the-server]__00efb844._.js.map +1 -0
  268. package/web/.next/server/chunks/ssr/{[root-of-the-server]__d1040bd1._.js → [root-of-the-server]__090f24cb._.js} +2 -2
  269. package/web/.next/server/chunks/ssr/{[root-of-the-server]__d1040bd1._.js.map → [root-of-the-server]__090f24cb._.js.map} +1 -1
  270. package/web/.next/server/chunks/ssr/[root-of-the-server]__0d64745d._.js +3 -0
  271. package/web/.next/server/chunks/ssr/[root-of-the-server]__0d64745d._.js.map +1 -0
  272. package/web/.next/server/chunks/ssr/[root-of-the-server]__17dadd08._.js +4 -0
  273. package/web/.next/server/chunks/ssr/[root-of-the-server]__17dadd08._.js.map +1 -0
  274. package/web/.next/server/chunks/ssr/[root-of-the-server]__1a9687c4._.js +4 -0
  275. package/web/.next/server/chunks/ssr/[root-of-the-server]__1a9687c4._.js.map +1 -0
  276. package/web/.next/server/chunks/ssr/[root-of-the-server]__28c4e836._.js +3 -0
  277. package/web/.next/server/chunks/ssr/[root-of-the-server]__28c4e836._.js.map +1 -0
  278. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  279. package/web/.next/server/chunks/ssr/[root-of-the-server]__3b7cba7e._.js +3 -0
  280. package/web/.next/server/chunks/ssr/[root-of-the-server]__3b7cba7e._.js.map +1 -0
  281. package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js +2 -2
  282. package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js.map +1 -1
  283. package/web/.next/server/chunks/ssr/[root-of-the-server]__63272afd._.js +4 -0
  284. package/web/.next/server/chunks/ssr/[root-of-the-server]__63272afd._.js.map +1 -0
  285. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7e2919._.js +3 -0
  286. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7e2919._.js.map +1 -0
  287. package/web/.next/server/chunks/ssr/{[root-of-the-server]__efeeaed4._.js → [root-of-the-server]__7aa484f5._.js} +2 -2
  288. package/web/.next/server/chunks/ssr/{[root-of-the-server]__efeeaed4._.js.map → [root-of-the-server]__7aa484f5._.js.map} +1 -1
  289. package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js +2 -2
  290. package/web/.next/server/chunks/ssr/[root-of-the-server]__86ff0bc5._.js.map +1 -1
  291. package/web/.next/server/chunks/ssr/[root-of-the-server]__964b00e8._.js +3 -0
  292. package/web/.next/server/chunks/ssr/[root-of-the-server]__964b00e8._.js.map +1 -0
  293. package/web/.next/server/chunks/ssr/[root-of-the-server]__dd3e834e._.js +4 -0
  294. package/web/.next/server/chunks/ssr/[root-of-the-server]__dd3e834e._.js.map +1 -0
  295. package/web/.next/server/chunks/ssr/[root-of-the-server]__df7bfd53._.js +3 -0
  296. package/web/.next/server/chunks/ssr/[root-of-the-server]__df7bfd53._.js.map +1 -0
  297. package/web/.next/server/chunks/ssr/[root-of-the-server]__f5f982ad._.js +3 -0
  298. package/web/.next/server/chunks/ssr/[root-of-the-server]__f5f982ad._.js.map +1 -0
  299. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  300. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  301. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  302. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  303. package/web/.next/server/chunks/ssr/_1879404a._.js +1 -1
  304. package/web/.next/server/chunks/ssr/_1879404a._.js.map +1 -1
  305. package/web/.next/server/chunks/ssr/_295fffde._.js.map +1 -1
  306. package/web/.next/server/chunks/ssr/_2bea8166._.js +4 -0
  307. package/web/.next/server/chunks/ssr/_2bea8166._.js.map +1 -0
  308. package/web/.next/server/chunks/ssr/_45496654._.js.map +1 -1
  309. package/web/.next/server/chunks/ssr/_46a35540._.js +3 -0
  310. package/web/.next/server/chunks/ssr/_46a35540._.js.map +1 -0
  311. package/web/.next/server/chunks/ssr/_4e42f1b7._.js +3 -0
  312. package/web/.next/server/chunks/ssr/_4e42f1b7._.js.map +1 -0
  313. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  314. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  315. package/web/.next/server/chunks/ssr/_6dff070a._.js +3 -0
  316. package/web/.next/server/chunks/ssr/_6dff070a._.js.map +1 -0
  317. package/web/.next/server/chunks/ssr/_73e62e34._.js +7 -0
  318. package/web/.next/server/chunks/ssr/_73e62e34._.js.map +1 -0
  319. package/web/.next/server/chunks/ssr/{_83e1c526._.js → _946a7fc6._.js} +3 -3
  320. package/web/.next/server/chunks/ssr/_946a7fc6._.js.map +1 -0
  321. package/web/.next/server/chunks/ssr/_b0311e50._.js +3 -0
  322. package/web/.next/server/chunks/ssr/_b0311e50._.js.map +1 -0
  323. package/web/.next/server/chunks/ssr/_b7a43c05._.js +1 -1
  324. package/web/.next/server/chunks/ssr/_b7a43c05._.js.map +1 -1
  325. package/web/.next/server/chunks/ssr/_d485d3b9._.js +3 -0
  326. package/web/.next/server/chunks/ssr/_d485d3b9._.js.map +1 -0
  327. package/web/.next/server/chunks/ssr/_f3cd7f63._.js +9 -0
  328. package/web/.next/server/chunks/ssr/_f3cd7f63._.js.map +1 -0
  329. package/web/.next/server/chunks/ssr/{_496c9117._.js → _f86fc1bf._.js} +2 -2
  330. package/web/.next/server/chunks/ssr/_f86fc1bf._.js.map +1 -0
  331. package/web/.next/server/chunks/ssr/_f8c55130._.js +1 -1
  332. package/web/.next/server/chunks/ssr/_f8c55130._.js.map +1 -1
  333. package/web/.next/server/chunks/ssr/_f916587a._.js +3 -0
  334. package/web/.next/server/chunks/ssr/_f916587a._.js.map +1 -0
  335. package/web/.next/server/chunks/ssr/{_49b9ba41._.js → _fb9934d4._.js} +2 -2
  336. package/web/.next/server/chunks/ssr/{_49b9ba41._.js.map → _fb9934d4._.js.map} +1 -1
  337. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  338. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  339. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
  340. package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
  341. package/web/.next/server/chunks/ssr/src_presentation_web_2478c24c._.js +3 -0
  342. package/web/.next/server/chunks/ssr/src_presentation_web_2478c24c._.js.map +1 -0
  343. package/web/.next/server/chunks/ssr/src_presentation_web_25da4cf4._.js +3 -0
  344. package/web/.next/server/chunks/ssr/src_presentation_web_25da4cf4._.js.map +1 -0
  345. package/web/.next/server/chunks/ssr/src_presentation_web_35084e19._.js +3 -0
  346. package/web/.next/server/chunks/ssr/src_presentation_web_35084e19._.js.map +1 -0
  347. package/web/.next/server/chunks/ssr/src_presentation_web_4ed08aa4._.js +3 -0
  348. package/web/.next/server/chunks/ssr/src_presentation_web_4ed08aa4._.js.map +1 -0
  349. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5149e11b.js +3 -0
  350. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_5149e11b.js.map +1 -0
  351. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1619f987.js +3 -0
  352. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1619f987.js.map +1 -0
  353. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_1b3c83ff.js +3 -0
  354. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_1b3c83ff.js.map +1 -0
  355. package/web/.next/server/chunks/ssr/src_presentation_web_a9f3bc05._.js +3 -0
  356. package/web/.next/server/chunks/ssr/src_presentation_web_a9f3bc05._.js.map +1 -0
  357. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +32 -0
  358. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js.map +1 -0
  359. package/web/.next/server/chunks/ssr/src_presentation_web_b360e85a._.js +3 -0
  360. package/web/.next/server/chunks/ssr/src_presentation_web_b360e85a._.js.map +1 -0
  361. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
  362. package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
  363. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
  364. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
  365. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  366. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  367. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +1 -1
  368. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -1
  369. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js +1 -1
  370. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js.map +1 -1
  371. package/web/.next/server/pages/500.html +2 -2
  372. package/web/.next/server/server-reference-manifest.js +1 -1
  373. package/web/.next/server/server-reference-manifest.json +898 -701
  374. package/web/.next/static/chunks/{25a0d3f50b0a26c1.js → 04b48827bdc55056.js} +1 -1
  375. package/web/.next/static/chunks/07dd0cd365169ac6.js +1 -0
  376. package/web/.next/static/chunks/0dbc8228223540f0.js +1 -0
  377. package/web/.next/static/chunks/14742749d118b339.js +1 -0
  378. package/web/.next/static/chunks/{2cc487403c107f3f.js → 48b1ee6f9460e08a.js} +2 -2
  379. package/web/.next/static/chunks/54a8ad22d3f9a857.js +3 -0
  380. package/web/.next/static/chunks/57cc43fa9970f8d7.js +1 -0
  381. package/web/.next/static/chunks/63e6ce2311b8c44f.js +7 -0
  382. package/web/.next/static/chunks/73e5026c618f964b.css +1 -0
  383. package/web/.next/static/chunks/771b8283dff48366.js +5 -0
  384. package/web/.next/static/chunks/79f687a9b9f2dca3.js +1 -0
  385. package/web/.next/static/chunks/{35bf9838f21d1818.js → 82189e222fa39768.js} +1 -1
  386. package/web/.next/static/chunks/{e167803ac69c66c7.js → 9718f0d839d204ee.js} +1 -1
  387. package/web/.next/static/chunks/994f0ac30cd8661a.js +1 -0
  388. package/web/.next/static/chunks/a9dbf887ff5ea94d.js +1 -0
  389. package/web/.next/static/chunks/afd205387569eb16.js +1 -0
  390. package/web/.next/static/chunks/b99506a6f7bc2fa8.js +1 -0
  391. package/web/.next/static/chunks/{09edd35d194bec06.js → bcbae49e0f6d65ca.js} +3 -3
  392. package/web/.next/static/chunks/{5f57f0d80d3db147.js → c5e9b56c67a4f3d4.js} +1 -1
  393. package/web/.next/static/chunks/c9bd1dea77920749.js +1 -0
  394. package/web/.next/static/chunks/ce8d4b5094c4dd62.js +1 -0
  395. package/web/.next/static/chunks/e2644573ed9ceb22.js +1 -0
  396. package/web/.next/static/chunks/{36e3d626ed8defca.js → f202967c5b0ff87f.js} +2 -2
  397. package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js +0 -4
  398. package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js.map +0 -1
  399. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +0 -4
  400. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +0 -1
  401. package/web/.next/server/chunks/ssr/[root-of-the-server]__22d17c66._.js +0 -3
  402. package/web/.next/server/chunks/ssr/[root-of-the-server]__22d17c66._.js.map +0 -1
  403. package/web/.next/server/chunks/ssr/[root-of-the-server]__46b10380._.js +0 -3
  404. package/web/.next/server/chunks/ssr/[root-of-the-server]__46b10380._.js.map +0 -1
  405. package/web/.next/server/chunks/ssr/[root-of-the-server]__69dd3217._.js +0 -3
  406. package/web/.next/server/chunks/ssr/[root-of-the-server]__69dd3217._.js.map +0 -1
  407. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +0 -4
  408. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +0 -1
  409. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b512877._.js +0 -3
  410. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b512877._.js.map +0 -1
  411. package/web/.next/server/chunks/ssr/[root-of-the-server]__990dba2d._.js +0 -3
  412. package/web/.next/server/chunks/ssr/[root-of-the-server]__990dba2d._.js.map +0 -1
  413. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +0 -4
  414. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +0 -1
  415. package/web/.next/server/chunks/ssr/[root-of-the-server]__cc9c7bbb._.js +0 -3
  416. package/web/.next/server/chunks/ssr/[root-of-the-server]__cc9c7bbb._.js.map +0 -1
  417. package/web/.next/server/chunks/ssr/_43ba79e7._.js +0 -3
  418. package/web/.next/server/chunks/ssr/_43ba79e7._.js.map +0 -1
  419. package/web/.next/server/chunks/ssr/_496c9117._.js.map +0 -1
  420. package/web/.next/server/chunks/ssr/_64efdf53._.js +0 -3
  421. package/web/.next/server/chunks/ssr/_64efdf53._.js.map +0 -1
  422. package/web/.next/server/chunks/ssr/_6abfa39e._.js +0 -3
  423. package/web/.next/server/chunks/ssr/_6abfa39e._.js.map +0 -1
  424. package/web/.next/server/chunks/ssr/_7cb0396e._.js +0 -3
  425. package/web/.next/server/chunks/ssr/_7cb0396e._.js.map +0 -1
  426. package/web/.next/server/chunks/ssr/_83e1c526._.js.map +0 -1
  427. package/web/.next/server/chunks/ssr/_d9c0a97a._.js +0 -7
  428. package/web/.next/server/chunks/ssr/_d9c0a97a._.js.map +0 -1
  429. package/web/.next/server/chunks/ssr/_e680c57c._.js +0 -9
  430. package/web/.next/server/chunks/ssr/_e680c57c._.js.map +0 -1
  431. package/web/.next/server/chunks/ssr/node_modules__pnpm_ef15a0bd._.js +0 -3
  432. package/web/.next/server/chunks/ssr/node_modules__pnpm_ef15a0bd._.js.map +0 -1
  433. package/web/.next/server/chunks/ssr/src_presentation_web_06109d28._.js +0 -5
  434. package/web/.next/server/chunks/ssr/src_presentation_web_06109d28._.js.map +0 -1
  435. package/web/.next/server/chunks/ssr/src_presentation_web_0bca70f8._.js +0 -3
  436. package/web/.next/server/chunks/ssr/src_presentation_web_0bca70f8._.js.map +0 -1
  437. package/web/.next/server/chunks/ssr/src_presentation_web_367cdbe0._.js +0 -3
  438. package/web/.next/server/chunks/ssr/src_presentation_web_367cdbe0._.js.map +0 -1
  439. package/web/.next/server/chunks/ssr/src_presentation_web_57fed7fd._.js +0 -3
  440. package/web/.next/server/chunks/ssr/src_presentation_web_57fed7fd._.js.map +0 -1
  441. package/web/.next/server/chunks/ssr/src_presentation_web_7f567f6d._.js +0 -3
  442. package/web/.next/server/chunks/ssr/src_presentation_web_7f567f6d._.js.map +0 -1
  443. package/web/.next/server/chunks/ssr/src_presentation_web_972f58d5._.js +0 -3
  444. package/web/.next/server/chunks/ssr/src_presentation_web_972f58d5._.js.map +0 -1
  445. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js +0 -3
  446. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js.map +0 -1
  447. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js +0 -3
  448. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js.map +0 -1
  449. package/web/.next/server/chunks/ssr/src_presentation_web_a71b18a2._.js +0 -3
  450. package/web/.next/server/chunks/ssr/src_presentation_web_a71b18a2._.js.map +0 -1
  451. package/web/.next/server/chunks/ssr/src_presentation_web_bebe675e._.js +0 -3
  452. package/web/.next/server/chunks/ssr/src_presentation_web_bebe675e._.js.map +0 -1
  453. package/web/.next/server/chunks/ssr/src_presentation_web_c93e8bc6._.js +0 -3
  454. package/web/.next/server/chunks/ssr/src_presentation_web_c93e8bc6._.js.map +0 -1
  455. package/web/.next/server/chunks/ssr/src_presentation_web_e729f44a._.js +0 -5
  456. package/web/.next/server/chunks/ssr/src_presentation_web_e729f44a._.js.map +0 -1
  457. package/web/.next/static/chunks/0b7251e5d717dd17.js +0 -1
  458. package/web/.next/static/chunks/0fd39d549d277843.js +0 -1
  459. package/web/.next/static/chunks/124b79a5d2a760fb.css +0 -1
  460. package/web/.next/static/chunks/4052a4971fbbac9c.js +0 -1
  461. package/web/.next/static/chunks/46e2693dbc9262fd.js +0 -5
  462. package/web/.next/static/chunks/5df9da8b40e298ee.js +0 -7
  463. package/web/.next/static/chunks/8286914ac835a1cc.js +0 -1
  464. package/web/.next/static/chunks/8777b2a0a2e85fd1.js +0 -3
  465. package/web/.next/static/chunks/8b0a9cb5109fe899.js +0 -1
  466. package/web/.next/static/chunks/971e52f3f386ccfd.js +0 -1
  467. package/web/.next/static/chunks/9e9cddf8e38342e8.js +0 -1
  468. package/web/.next/static/chunks/ac586c86d71187fc.js +0 -1
  469. package/web/.next/static/chunks/b63e6727c84f30e2.js +0 -1
  470. package/web/.next/static/chunks/c10c0d6d458453bc.js +0 -1
  471. package/web/.next/static/chunks/c6fdd161a9e5b554.js +0 -1
  472. /package/web/.next/static/{sfBZvlx-erv7S1C49vRSU → gxMya5XttXE_aSwszy4nE}/_buildManifest.js +0 -0
  473. /package/web/.next/static/{sfBZvlx-erv7S1C49vRSU → gxMya5XttXE_aSwszy4nE}/_clientMiddlewareManifest.json +0 -0
  474. /package/web/.next/static/{sfBZvlx-erv7S1C49vRSU → gxMya5XttXE_aSwszy4nE}/_ssgManifest.js +0 -0
@@ -1,138 +1,199 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState, useCallback, useEffect } from 'react';
4
- import { FolderOpen, FolderPlus, Copy, Check, Loader2, CheckCircle2, AlertCircle, Terminal, ChevronDown, ExternalLink, } from 'lucide-react';
3
+ import { useState, useCallback, useRef, useEffect } from 'react';
4
+ import { SendHorizontal, Paperclip, Loader2, LayoutGrid, Zap, ClipboardList, ChevronDown, Check, X, } from 'lucide-react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { cn } from '../../../lib/utils.js';
7
- import { pickFolder } from '../../common/add-repository-button/pick-folder.js';
8
- import { ReactFileManagerDialog } from '../../common/react-file-manager-dialog/index.js';
9
- import { useFeatureFlags } from '../../../hooks/feature-flags-context.js';
10
- import { isAgentSetupComplete } from '../../../app/actions/agent-setup-flag.js';
11
- import { checkAgentAuth } from '../../../app/actions/check-agent-auth.js';
12
- import { checkToolStatus } from '../../../app/actions/check-tool-status.js';
13
- import { WelcomeAgentSetup } from './welcome-agent-setup.js';
14
- import { NewProjectDialog } from './new-project-dialog.js';
15
- const commands = ['cd ~/my-repo', 'shep feat new "sleek dashboard"'];
16
- export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
7
+ import { createProjectAndFeature } from '../../../app/actions/create-project-and-feature.js';
8
+ import { createApplication } from '../../../app/actions/create-application.js';
9
+ import { AgentModelPicker } from '../../features/settings/AgentModelPicker/index.js';
10
+ import { AttachmentChip } from '../../common/attachment-chip/index.js';
11
+ import { ShepLogo } from '../../common/shep-logo/index.js';
12
+ import { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip.js';
13
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '../../ui/dropdown-menu.js';
14
+ import { useAttachments } from '../../../hooks/use-attachments.js';
15
+ const BUILD_MODES = ['application', 'fast', 'spec'];
16
+ const BUILD_MODE_CONFIG = {
17
+ application: {
18
+ icon: LayoutGrid,
19
+ label: 'Application',
20
+ placeholder: 'Build a modern e-commerce storefront with product catalog...',
21
+ suggestions: [
22
+ 'A landing page with hero, features, and pricing sections',
23
+ 'Full-stack SaaS app with auth, billing, and dashboard',
24
+ 'Mobile-first social media app with real-time chat',
25
+ 'Personal portfolio with blog and project showcase',
26
+ ],
27
+ },
28
+ fast: {
29
+ icon: Zap,
30
+ label: 'Fast',
31
+ placeholder: 'Add a dark mode toggle to the settings page...',
32
+ suggestions: [
33
+ 'Add pagination to the users list endpoint',
34
+ 'Fix the broken logout redirect',
35
+ 'Add input validation to the signup form',
36
+ 'Refactor the API error handling middleware',
37
+ ],
38
+ },
39
+ spec: {
40
+ icon: ClipboardList,
41
+ label: 'Spec Driven',
42
+ placeholder: 'Implement a role-based access control system with audit logging...',
43
+ suggestions: [
44
+ 'OAuth2 authentication with SSO and MFA support',
45
+ 'Event-driven notification system with email and push',
46
+ 'REST API with versioning, rate limiting, and OpenAPI docs',
47
+ 'Data pipeline with ETL, validation, and monitoring',
48
+ ],
49
+ },
50
+ };
51
+ export function ControlCenterEmptyState({ onRepositorySelect, onApplicationCreated, onClose, className, }) {
17
52
  const { t } = useTranslation('web');
18
- const [copied, setCopied] = useState(false);
19
- const [loading, setLoading] = useState(false);
20
- const [showReactPicker, setShowReactPicker] = useState(false);
21
- const [agentReady, setAgentReady] = useState(null);
22
- const [authStatus, setAuthStatus] = useState(null);
23
- const [cliExpanded, setCliExpanded] = useState(false);
24
- const [toolStatus, setToolStatus] = useState(null);
25
- const [newProjectOpen, setNewProjectOpen] = useState(false);
26
- const { reactFileManager: useReactFileManager } = useFeatureFlags();
27
- useEffect(() => {
28
- isAgentSetupComplete().then((done) => {
29
- setAgentReady(done);
53
+ const [description, setDescription] = useState('');
54
+ const [overrideAgent, setOverrideAgent] = useState(undefined);
55
+ const [overrideModel, setOverrideModel] = useState(undefined);
56
+ const [buildMode, setBuildMode] = useState('application');
57
+ const [submitting, setSubmitting] = useState(false);
58
+ const [error, setError] = useState(null);
59
+ const [isFocused, setIsFocused] = useState(false);
60
+ const textareaRef = useRef(null);
61
+ const att = useAttachments();
62
+ // Circular mode switching with Shift+Tab, close overlay with Escape
63
+ const cycleBuildMode = useCallback(() => {
64
+ setBuildMode((prev) => {
65
+ const idx = BUILD_MODES.indexOf(prev);
66
+ return BUILD_MODES[(idx + 1) % BUILD_MODES.length];
30
67
  });
31
68
  }, []);
32
69
  useEffect(() => {
33
- if (!agentReady)
34
- return;
35
- checkAgentAuth().then(setAuthStatus);
36
- checkToolStatus().then(setToolStatus);
37
- }, [agentReady]);
38
- async function handlePickerClick() {
39
- if (loading)
40
- return;
41
- if (useReactFileManager) {
42
- setShowReactPicker(true);
70
+ const handleGlobalKeyDown = (e) => {
71
+ if (e.key === 'Escape' && onClose)
72
+ onClose();
73
+ if (e.key === 'Tab' && e.shiftKey) {
74
+ e.preventDefault();
75
+ cycleBuildMode();
76
+ }
77
+ };
78
+ window.addEventListener('keydown', handleGlobalKeyDown);
79
+ return () => window.removeEventListener('keydown', handleGlobalKeyDown);
80
+ }, [onClose, cycleBuildMode]);
81
+ const handleSubmit = useCallback(async () => {
82
+ if (!description.trim() || submitting)
43
83
  return;
44
- }
45
- setLoading(true);
84
+ setSubmitting(true);
85
+ setError(null);
46
86
  try {
47
- const path = await pickFolder();
48
- if (path) {
49
- onRepositorySelect?.(path);
87
+ if (buildMode === 'application') {
88
+ const result = await createApplication({
89
+ description: description.trim(),
90
+ agentType: overrideAgent,
91
+ modelOverride: overrideModel,
92
+ });
93
+ if (result.error) {
94
+ setError(result.error);
95
+ setSubmitting(false);
96
+ return;
97
+ }
98
+ // Applications navigate straight to /application/${id} — no canvas
99
+ // flash and no companion Repository node. The canvas reloads its
100
+ // graph data when the user navigates back, picking the Application
101
+ // up from the DB via ListApplicationsUseCase.
102
+ if (result.application) {
103
+ onApplicationCreated?.(result.application.id, description.trim());
104
+ }
105
+ }
106
+ else {
107
+ const result = await createProjectAndFeature({
108
+ description: description.trim(),
109
+ attachments: att.completedAttachments.map((a) => ({
110
+ path: a.path,
111
+ name: a.name,
112
+ notes: a.notes,
113
+ })),
114
+ agentType: overrideAgent,
115
+ model: overrideModel,
116
+ fast: buildMode === 'fast',
117
+ });
118
+ if (result.error) {
119
+ setError(result.error);
120
+ setSubmitting(false);
121
+ return;
122
+ }
123
+ if (result.repositoryPath) {
124
+ onRepositorySelect?.(result.repositoryPath);
125
+ }
126
+ if (result.feature && result.repositoryPath) {
127
+ window.dispatchEvent(new CustomEvent('shep:feature-created', {
128
+ detail: {
129
+ featureId: result.feature.id,
130
+ name: result.feature.name,
131
+ description: result.feature.description,
132
+ repositoryPath: result.repositoryPath,
133
+ },
134
+ }));
135
+ }
50
136
  }
51
137
  }
52
138
  catch {
53
- // Native picker failed fall back to React file manager
54
- setShowReactPicker(true);
139
+ setError('Something went wrong. Please try again.');
140
+ setSubmitting(false);
55
141
  }
56
- finally {
57
- setLoading(false);
142
+ }, [
143
+ description,
144
+ submitting,
145
+ buildMode,
146
+ att.completedAttachments,
147
+ overrideAgent,
148
+ overrideModel,
149
+ onRepositorySelect,
150
+ onApplicationCreated,
151
+ ]);
152
+ const handleKeyDown = useCallback((e) => {
153
+ if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
154
+ e.preventDefault();
155
+ handleSubmit();
58
156
  }
59
- }
60
- function handleReactPickerSelect(path) {
61
- if (path) {
62
- onRepositorySelect?.(path);
157
+ }, [handleSubmit]);
158
+ const handlePickFiles = useCallback(async () => {
159
+ try {
160
+ const res = await fetch('/api/dialog/pick-files');
161
+ if (!res.ok)
162
+ return;
163
+ const data = (await res.json());
164
+ if (!data.paths?.length)
165
+ return;
166
+ for (const filePath of data.paths) {
167
+ const uploadRes = await fetch('/api/attachments/upload-from-path', {
168
+ method: 'POST',
169
+ headers: { 'Content-Type': 'application/json' },
170
+ body: JSON.stringify({ path: filePath, sessionId: 'onboarding' }),
171
+ });
172
+ if (!uploadRes.ok)
173
+ continue;
174
+ const uploaded = (await uploadRes.json());
175
+ att.addAttachment(uploaded);
176
+ }
63
177
  }
64
- setShowReactPicker(false);
65
- }
66
- const handleCopy = useCallback(async () => {
67
- await navigator.clipboard.writeText(commands.join('\n'));
68
- setCopied(true);
69
- setTimeout(() => setCopied(false), 2000);
70
- }, []);
71
- const handleAgentSetupComplete = useCallback(() => {
72
- setAgentReady(true);
73
- }, []);
74
- const handleRetryAuth = useCallback(() => {
75
- setAuthStatus(null);
76
- checkAgentAuth().then(setAuthStatus);
178
+ catch {
179
+ // Native picker not available — ignore
180
+ }
181
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- att.addAttachment is stable
182
+ }, [att.addAttachment]);
183
+ const handleSuggestionClick = useCallback((suggestion) => {
184
+ setDescription(suggestion);
185
+ textareaRef.current?.focus();
77
186
  }, []);
78
- if (agentReady === null)
79
- return null;
80
- return (_jsxs("div", { "data-testid": "control-center-empty-state", className: cn('relative flex h-full w-full flex-col items-center justify-center px-8', className), children: [!agentReady ? (
81
- /* Agent setup wizard owns its own hero */
82
- _jsx(WelcomeAgentSetup, { onComplete: handleAgentSetupComplete })) : (
83
- /* Repository step — fade in to match wizard transitions */
84
- _jsxs("div", { className: "animate-in fade-in flex w-full max-w-md flex-col items-center duration-300", children: [_jsx("h1", { className: "text-foreground/90 text-center text-5xl font-extralight tracking-tight", children: t('emptyState.addProject') }), _jsxs("p", { className: "text-muted-foreground mt-3 text-center text-lg leading-relaxed font-light", children: [t('emptyState.addProjectDescription'), _jsx("br", {}), t('emptyState.addProjectDescriptionLine2')] }), _jsxs("div", { className: "mt-8 flex w-full flex-col gap-3", children: [_jsx(AgentAuthBanner, { status: authStatus, onRetry: handleRetryAuth }), _jsx(ToolStatusRow, { label: t('emptyState.git'), status: toolStatus?.git ?? null, missingHint: t('emptyState.gitRequired') }), _jsx(ToolStatusRow, { label: t('emptyState.githubCli'), status: toolStatus?.gh ?? null, missingHint: t('emptyState.githubCliRequired') })] }), _jsxs("button", { type: "button", "data-testid": "empty-state-add-repository", onClick: handlePickerClick, disabled: loading, className: "bg-foreground text-background hover:bg-foreground/90 mt-10 flex w-full cursor-pointer items-center justify-center gap-2.5 rounded-xl px-6 py-4 text-base font-medium shadow-lg transition-all duration-200 hover:shadow-xl active:scale-[0.98] disabled:cursor-wait disabled:opacity-50", children: [loading ? (_jsx(Loader2, { className: "h-5 w-5 animate-spin" })) : (_jsx(FolderOpen, { className: "h-5 w-5" })), loading ? t('emptyState.opening') : t('emptyState.chooseFolder')] }), _jsxs("button", { type: "button", "data-testid": "empty-state-new-project", onClick: () => setNewProjectOpen(true), disabled: loading, className: "border-foreground/15 text-foreground/80 hover:bg-foreground/5 hover:border-foreground/25 mt-3 flex w-full cursor-pointer items-center justify-center gap-2.5 rounded-xl border px-6 py-3.5 text-sm font-medium transition-all duration-200 active:scale-[0.98] disabled:cursor-not-allowed disabled:opacity-50", children: [_jsx(FolderPlus, { className: "h-4 w-4" }), "New Project"] }), _jsx("p", { className: "text-muted-foreground/60 mt-3 text-center text-sm", children: t('emptyState.folderHint') })] })), agentReady ? (_jsxs("div", { className: "absolute bottom-8 flex flex-col items-center", style: {
85
- animationDelay: '400ms',
86
- animationDuration: '600ms',
87
- animationFillMode: 'both',
88
- }, children: [_jsxs("button", { type: "button", onClick: () => setCliExpanded(!cliExpanded), className: "text-muted-foreground hover:text-foreground flex cursor-pointer items-center gap-1.5 transition-colors duration-200", children: [_jsx(Terminal, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-sm", children: t('emptyState.orUseCli') }), _jsx(ChevronDown, { className: cn('h-3.5 w-3.5 transition-transform duration-200', cliExpanded ? '' : 'rotate-180') })] }), cliExpanded ? (_jsx("div", { className: "animate-in fade-in slide-in-from-top-1 mt-3 w-80 duration-200", children: _jsxs("div", { "data-testid": "cli-code-block", className: "relative rounded-xl bg-zinc-900 px-5 py-4 font-mono text-[13px] leading-relaxed text-zinc-400", children: [_jsx("button", { type: "button", "data-testid": "cli-code-block-copy", onClick: handleCopy, className: "absolute top-3 right-3 cursor-pointer rounded-md p-1.5 text-zinc-600 transition-colors hover:bg-zinc-800 hover:text-zinc-300", "aria-label": t('emptyState.copyCommands'), children: copied ? (_jsx(Check, { className: "h-3.5 w-3.5 text-emerald-400" })) : (_jsx(Copy, { className: "h-3.5 w-3.5" })) }), _jsx("div", { className: "space-y-1", children: commands.map((cmd) => (_jsxs("div", { className: "whitespace-nowrap", children: [_jsx("span", { className: "text-zinc-600 select-none", children: "$ " }), _jsx("span", { className: "text-zinc-300", children: cmd })] }, cmd))) })] }) })) : null] })) : null, _jsx(ReactFileManagerDialog, { open: showReactPicker, onOpenChange: (open) => {
89
- if (!open)
90
- setShowReactPicker(false);
91
- }, onSelect: handleReactPickerSelect }), _jsx(NewProjectDialog, { open: newProjectOpen, onOpenChange: setNewProjectOpen, onCreated: (path) => onRepositorySelect?.(path) })] }));
92
- }
93
- /** Status row for the AI agent (Claude Code, etc.) */
94
- function AgentAuthBanner({ status, onRetry, }) {
95
- const { t } = useTranslation('web');
96
- if (!status) {
97
- return (_jsx(ChecklistRow, { icon: _jsx(Loader2, { className: "text-muted-foreground/50 h-4 w-4 animate-spin" }), children: _jsx("span", { className: "text-muted-foreground/50 text-sm", children: t('emptyState.checkingSetup') }) }));
98
- }
99
- if (status.installed && status.authenticated) {
100
- return (_jsx(ChecklistRow, { icon: _jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-500" }), children: _jsx("span", { className: "text-sm text-emerald-600 dark:text-emerald-400", children: t('emptyState.ready', { label: status.label }) }) }));
101
- }
102
- if (!status.installed) {
103
- return (_jsxs(ChecklistRow, { icon: _jsx(AlertCircle, { className: "h-4 w-4 text-amber-500" }), children: [_jsx("span", { className: "text-sm font-medium text-amber-600 dark:text-amber-400", children: t('emptyState.notInstalled', { label: status.label }) }), status.installCommand ? _jsx(CopyableCommand, { command: status.installCommand }) : null, _jsx("button", { type: "button", onClick: onRetry, className: "text-xs text-amber-600 underline underline-offset-2 hover:text-amber-800 dark:text-amber-400", children: t('emptyState.reCheck') })] }));
104
- }
105
- return (_jsxs(ChecklistRow, { icon: _jsx(AlertCircle, { className: "h-4 w-4 text-amber-500" }), children: [_jsx("span", { className: "text-sm font-medium text-amber-600 dark:text-amber-400", children: t('emptyState.needsAuth', { label: status.label }) }), status.authCommand ? _jsx(CopyableCommand, { command: status.authCommand }) : null, _jsxs("div", { className: "flex items-center gap-3", children: [status.binaryName ? (_jsxs("button", { type: "button", "data-testid": "auth-banner-open-terminal", onClick: async () => {
106
- try {
107
- const toolId = status.agentType === 'claude-code' ? 'claude-code' : status.agentType;
108
- await fetch(`/api/tools/${toolId}/launch`, { method: 'POST' });
109
- }
110
- catch {
111
- /* best effort */
112
- }
113
- }, className: "flex items-center gap-1 text-xs font-medium text-amber-600 underline underline-offset-2 hover:text-amber-800 dark:text-amber-400", children: [_jsx(Terminal, { className: "h-3 w-3" }), t('emptyState.open', { label: status.label })] })) : null, _jsx("button", { type: "button", onClick: onRetry, className: "text-xs text-amber-600 underline underline-offset-2 hover:text-amber-800 dark:text-amber-400", children: t('emptyState.reCheck') })] })] }));
114
- }
115
- /** Status row for system tools (git, gh) */
116
- function ToolStatusRow({ label, status, missingHint, }) {
117
- const { t } = useTranslation('web');
118
- if (!status) {
119
- return (_jsx(ChecklistRow, { icon: _jsx(Loader2, { className: "text-muted-foreground/50 h-4 w-4 animate-spin" }), children: _jsx("span", { className: "text-muted-foreground/50 text-sm", children: t('emptyState.checking', { label }) }) }));
120
- }
121
- if (status.installed) {
122
- return (_jsx(ChecklistRow, { icon: _jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-500" }), children: _jsxs("span", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-sm text-emerald-600 dark:text-emerald-400", children: t('emptyState.ready', { label }) }), status.version ? (_jsxs("span", { className: "text-muted-foreground/40 text-xs", children: ["v", status.version] })) : null] }) }));
123
- }
124
- return (_jsxs(ChecklistRow, { icon: _jsx(AlertCircle, { className: "h-4 w-4 text-amber-500" }), children: [_jsx("span", { className: "text-sm font-medium text-amber-600 dark:text-amber-400", children: t('emptyState.notFound', { label }) }), _jsx("span", { className: "text-muted-foreground/50 text-xs", children: missingHint }), status.installCommand ? _jsx(CopyableCommand, { command: status.installCommand }) : null, status.installUrl ? (_jsxs("a", { href: status.installUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 text-xs text-amber-600 underline underline-offset-2 hover:text-amber-800 dark:text-amber-400", children: [t('emptyState.docs'), " ", _jsx(ExternalLink, { className: "h-3 w-3" })] })) : null] }));
125
- }
126
- /** Checklist row: icon pinned left, children stacked vertically and fill width */
127
- function ChecklistRow({ icon, children }) {
128
- return (_jsxs("div", { className: "animate-in fade-in flex items-start gap-2.5", children: [_jsx("div", { className: "mt-0.5 shrink-0", children: icon }), _jsx("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: children })] }));
129
- }
130
- /** Compact copyable command block — fills available row width */
131
- function CopyableCommand({ command }) {
132
- const [copied, setCopied] = useState(false);
133
- return (_jsxs("button", { type: "button", onClick: async () => {
134
- await navigator.clipboard.writeText(command);
135
- setCopied(true);
136
- setTimeout(() => setCopied(false), 2000);
137
- }, className: "group/cmd flex cursor-pointer items-center justify-between gap-2 rounded-md bg-zinc-100 py-1 ps-2.5 pe-2 text-start transition-colors hover:bg-zinc-200 dark:bg-zinc-800 dark:hover:bg-zinc-700", children: [_jsx("code", { className: "min-w-0 truncate text-[11px] leading-relaxed text-zinc-600 dark:text-zinc-300", children: command }), copied ? (_jsx(Check, { className: "h-3 w-3 shrink-0 text-emerald-500" })) : (_jsx(Copy, { className: "h-3 w-3 shrink-0 text-zinc-400 opacity-0 transition-opacity group-hover/cmd:opacity-100" }))] }));
187
+ const modeConfig = BUILD_MODE_CONFIG[buildMode];
188
+ const ModeIcon = modeConfig.icon;
189
+ return (_jsxs("div", { "data-testid": "control-center-empty-state", className: cn('relative flex h-full w-full flex-col items-center justify-center overflow-hidden px-8', className), children: [_jsx("div", { className: "onboard-bg pointer-events-none absolute inset-0 animate-[onboard-fade-in_1.2s_ease-out_both]" }), onClose ? (_jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "text-muted-foreground hover:text-foreground hover:bg-accent/50 absolute top-4 right-4 z-10 cursor-pointer rounded p-1.5 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })) : null, _jsxs("div", { className: "relative flex w-full max-w-2xl flex-col items-center", children: [_jsx("div", { className: "mb-6 animate-[onboard-logo_0.8s_cubic-bezier(0.16,1,0.3,1)_both]", style: { animationDelay: '0ms' }, children: _jsx(ShepLogo, { size: 72, className: "text-foreground" }) }), _jsx("h1", { className: "text-foreground animate-[onboard-fade-up_0.7s_cubic-bezier(0.16,1,0.3,1)_both] text-center text-5xl font-extralight tracking-tight", style: { animationDelay: '120ms' }, children: "What do you want to build?" }), _jsx("p", { className: "text-muted-foreground mt-3 animate-[onboard-fade-up_0.7s_cubic-bezier(0.16,1,0.3,1)_both] text-center text-lg leading-relaxed font-light", style: { animationDelay: '220ms' }, children: "Describe your idea and Shep creates the project for you." }), _jsxs("div", { className: "mt-10 w-full animate-[onboard-fade-up_0.7s_cubic-bezier(0.16,1,0.3,1)_both]", style: { animationDelay: '350ms' }, children: [_jsxs("div", { onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), onDragEnter: att.handleDragEnter, onDragLeave: att.handleDragLeave, onDragOver: att.handleDragOver, onDrop: att.handleDrop, className: cn('flex flex-col rounded-xl border transition-all duration-200', 'border-border/60 bg-background shadow-sm dark:border-white/10 dark:bg-white/[0.04]', isFocused &&
190
+ 'ring-ring/50 border-ring shadow-md ring-[3px] dark:border-orange-500/40 dark:ring-orange-500/25', att.isDragOver && 'border-primary/50 bg-primary/5', submitting && 'opacity-70'), children: [_jsx("textarea", { ref: textareaRef, rows: 2, autoFocus: true, value: description, onChange: (e) => setDescription(e.target.value), onKeyDown: handleKeyDown, onPaste: att.handlePaste, placeholder: modeConfig.placeholder, disabled: submitting, className: "text-foreground placeholder:text-muted-foreground/60 max-h-[10rem] min-h-[4.5rem] w-full resize-none border-0 bg-transparent px-4 py-3.5 text-sm leading-relaxed focus:outline-none disabled:cursor-not-allowed" }), att.attachments.length > 0 ? (_jsx("div", { className: "flex shrink-0 items-center gap-2.5 overflow-x-auto overflow-y-visible px-5 pt-2 pb-2", children: att.attachments.map((file) => (_jsx(AttachmentChip, { name: file.name, size: file.size, mimeType: file.mimeType, path: file.path, onRemove: () => att.removeAttachment(file.id), loading: file.loading, notes: file.notes, onNotesChange: (notes) => att.updateNotes(file.id, notes) }, file.id))) })) : null, att.uploadError ? (_jsx("p", { className: "text-destructive px-4 pb-2 text-xs", children: att.uploadError })) : null, _jsxs("div", { className: "border-border/60 flex shrink-0 items-center gap-3 border-t px-3 py-2 dark:border-white/10", children: [_jsx(AgentModelPicker, { initialAgentType: overrideAgent ?? 'claude-code', initialModel: overrideModel ?? 'claude-sonnet-4-6', mode: "override", showInstallStatus: true, onAgentModelChange: (agent, model) => {
191
+ setOverrideAgent(agent);
192
+ setOverrideModel(model);
193
+ }, className: "w-55" }), _jsx("div", { className: "flex-1" }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs("button", { type: "button", "data-testid": "build-mode-selector", className: "text-muted-foreground hover:text-foreground hover:bg-accent/50 flex cursor-pointer items-center gap-1.5 rounded-md px-2 py-1 text-xs transition-colors", children: [_jsxs("span", { className: "flex animate-[onboard-fade-up_0.25s_ease-out_both] items-center gap-1.5", children: [_jsx(ModeIcon, { className: "h-3.5 w-3.5" }), modeConfig.label] }, buildMode), _jsx(ChevronDown, { className: "h-3 w-3 opacity-50" })] }) }), _jsx(DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: BUILD_MODES.map((mode) => {
194
+ const cfg = BUILD_MODE_CONFIG[mode];
195
+ const Icon = cfg.icon;
196
+ const isActive = buildMode === mode;
197
+ return (_jsxs(DropdownMenuItem, { onClick: () => setBuildMode(mode), "data-testid": `build-mode-${mode}`, className: "flex items-center gap-2", children: [_jsx(Icon, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "flex-1", children: cfg.label }), isActive ? _jsx(Check, { className: "text-foreground h-3.5 w-3.5" }) : null] }, mode));
198
+ }) })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: handlePickFiles, disabled: submitting, "aria-label": t('chat.attachFiles'), className: "text-muted-foreground hover:text-foreground cursor-pointer rounded p-1 transition-colors disabled:opacity-50", children: _jsx(Paperclip, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { side: "top", children: t('chat.attachFiles') })] }), _jsx("button", { type: "button", onClick: handleSubmit, disabled: !description.trim() || submitting, className: cn('bg-foreground text-background inline-flex h-8 w-8 shrink-0 cursor-pointer items-center justify-center rounded-lg', 'hover:bg-foreground/90 disabled:pointer-events-none disabled:opacity-30', 'transition-all duration-150'), children: submitting ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(SendHorizontal, { className: "h-3.5 w-3.5" })) })] })] }), error ? _jsx("p", { className: "text-destructive mt-2 text-center text-sm", children: error }) : null] }), _jsx("div", { className: "mt-6 flex animate-[onboard-fade-up_0.4s_ease-out_both] flex-wrap justify-center gap-2", children: modeConfig.suggestions.map((suggestion) => (_jsx("button", { type: "button", onClick: () => handleSuggestionClick(suggestion), disabled: submitting, className: "text-muted-foreground hover:text-foreground border-border/60 hover:border-border hover:bg-accent/50 cursor-pointer rounded-full border px-3.5 py-1.5 text-xs transition-all duration-150 disabled:opacity-50 dark:border-white/10 dark:hover:border-white/20 dark:hover:bg-white/[0.06]", children: suggestion }, suggestion))) }, buildMode)] })] }));
138
199
  }
@@ -3,22 +3,10 @@ import { ControlCenterEmptyState } from './control-center-empty-state.js';
3
3
  declare const meta: Meta<typeof ControlCenterEmptyState>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof meta>;
6
- /** All tools installed — the happy path */
7
- export declare const AllToolsReady: Story;
8
- /** Git is missing — blocks all workflow phases */
9
- export declare const GitMissing: Story;
10
- /** GitHub CLI is missing — PR features unavailable */
11
- export declare const GhCliMissing: Story;
12
- /** Both git and gh are missing */
13
- export declare const BothToolsMissing: Story;
14
- /** Claude Code not installed */
15
- export declare const ClaudeCodeNotInstalled: Story;
16
- /** Cursor CLI not installed */
17
- export declare const CursorCliNotInstalled: Story;
18
- /** Gemini CLI not installed */
19
- export declare const GeminiCliNotInstalled: Story;
20
- /** Agent not installed + tools missing — worst case */
21
- export declare const EverythingMissing: Story;
6
+ /** Prompt-first onboarding — the default view after agent setup */
7
+ export declare const Default: Story;
22
8
  /** With callback — for interaction testing */
23
9
  export declare const WithCallback: Story;
10
+ /** As overlay — with close button */
11
+ export declare const AsOverlay: Story;
24
12
  //# sourceMappingURL=control-center-empty-state.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"control-center-empty-state.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,uBAAuB,CAc9C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AA+FnC,2CAA2C;AAC3C,eAAO,MAAM,aAAa,EAAE,KAG3B,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,UAAU,EAAE,KAGxB,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAC;AAEF,kCAAkC;AAClC,eAAO,MAAM,gBAAgB,EAAE,KAG9B,CAAC;AAEF,gCAAgC;AAChC,eAAO,MAAM,sBAAsB,EAAE,KAGpC,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,qBAAqB,EAAE,KAGnC,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,qBAAqB,EAAE,KAGnC,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,EAAE,KAG/B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,YAAY,EAAE,KAO1B,CAAC"}
1
+ {"version":3,"file":"control-center-empty-state.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,uBAAuB,CAc9C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,mEAAmE;AACnE,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,YAAY,EAAE,KAW1B,CAAC;AAEF,qCAAqC;AACrC,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC"}
@@ -12,116 +12,9 @@ const meta = {
12
12
  ],
13
13
  };
14
14
  export default meta;
15
- const agentReady = {
16
- agentType: 'claude-code',
17
- installed: true,
18
- authenticated: true,
19
- label: 'Claude Code',
20
- binaryName: 'claude',
21
- installCommand: 'curl -fsSL https://claude.ai/install.sh | bash',
22
- authCommand: null,
23
- };
24
- const claudeNotInstalled = {
25
- agentType: 'claude-code',
26
- installed: false,
27
- authenticated: false,
28
- label: 'Claude Code',
29
- binaryName: 'claude',
30
- installCommand: 'curl -fsSL https://claude.ai/install.sh | bash',
31
- authCommand: 'Install Claude Code first',
32
- };
33
- const cursorNotInstalled = {
34
- agentType: 'cursor',
35
- installed: false,
36
- authenticated: false,
37
- label: 'Cursor CLI',
38
- binaryName: 'cursor-agent',
39
- installCommand: 'curl https://cursor.com/install -fsS | bash',
40
- authCommand: 'Install Cursor CLI first',
41
- };
42
- const geminiNotInstalled = {
43
- agentType: 'gemini-cli',
44
- installed: false,
45
- authenticated: false,
46
- label: 'Gemini CLI',
47
- binaryName: 'gemini',
48
- installCommand: 'npm install -g @google/gemini-cli',
49
- authCommand: 'Install Gemini CLI first',
50
- };
51
- const gitReady = {
52
- installed: true,
53
- version: '2.43.0',
54
- installCommand: 'sudo apt-get install -y git',
55
- installUrl: 'https://git-scm.com',
56
- };
57
- const gitMissing = {
58
- installed: false,
59
- version: null,
60
- installCommand: 'sudo apt-get install -y git',
61
- installUrl: 'https://git-scm.com',
62
- };
63
- const ghReady = {
64
- installed: true,
65
- version: '2.40.1',
66
- installCommand: 'sudo apt install gh -y',
67
- installUrl: 'https://cli.github.com',
68
- };
69
- const ghMissing = {
70
- installed: false,
71
- version: null,
72
- installCommand: 'sudo apt install gh -y',
73
- installUrl: 'https://cli.github.com',
74
- };
75
- function setMocks(agent, git, gh) {
76
- return () => {
77
- const win = globalThis;
78
- win.__mockAgentAuth = agent;
79
- win.__mockToolStatus = { git, gh };
80
- return () => {
81
- delete win.__mockAgentAuth;
82
- delete win.__mockToolStatus;
83
- };
84
- };
85
- }
86
- /** All tools installed — the happy path */
87
- export const AllToolsReady = {
15
+ /** Prompt-first onboarding — the default view after agent setup */
16
+ export const Default = {
88
17
  args: {},
89
- beforeEach: setMocks(agentReady, gitReady, ghReady),
90
- };
91
- /** Git is missing — blocks all workflow phases */
92
- export const GitMissing = {
93
- args: {},
94
- beforeEach: setMocks(agentReady, gitMissing, ghReady),
95
- };
96
- /** GitHub CLI is missing — PR features unavailable */
97
- export const GhCliMissing = {
98
- args: {},
99
- beforeEach: setMocks(agentReady, gitReady, ghMissing),
100
- };
101
- /** Both git and gh are missing */
102
- export const BothToolsMissing = {
103
- args: {},
104
- beforeEach: setMocks(agentReady, gitMissing, ghMissing),
105
- };
106
- /** Claude Code not installed */
107
- export const ClaudeCodeNotInstalled = {
108
- args: {},
109
- beforeEach: setMocks(claudeNotInstalled, gitReady, ghReady),
110
- };
111
- /** Cursor CLI not installed */
112
- export const CursorCliNotInstalled = {
113
- args: {},
114
- beforeEach: setMocks(cursorNotInstalled, gitReady, ghReady),
115
- };
116
- /** Gemini CLI not installed */
117
- export const GeminiCliNotInstalled = {
118
- args: {},
119
- beforeEach: setMocks(geminiNotInstalled, gitReady, ghReady),
120
- };
121
- /** Agent not installed + tools missing — worst case */
122
- export const EverythingMissing = {
123
- args: {},
124
- beforeEach: setMocks(claudeNotInstalled, gitMissing, ghMissing),
125
18
  };
126
19
  /** With callback — for interaction testing */
127
20
  export const WithCallback = {
@@ -130,5 +23,19 @@ export const WithCallback = {
130
23
  // eslint-disable-next-line no-console
131
24
  console.log('Selected repository:', path);
132
25
  },
26
+ onApplicationCreated: (appId) => {
27
+ // eslint-disable-next-line no-console
28
+ console.log('Application created:', appId);
29
+ },
30
+ },
31
+ };
32
+ /** As overlay — with close button */
33
+ export const AsOverlay = {
34
+ args: {
35
+ onClose: () => {
36
+ // eslint-disable-next-line no-console
37
+ console.log('Close clicked');
38
+ },
39
+ className: 'bg-background',
133
40
  },
134
41
  };
@@ -1 +1 @@
1
- {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAoBpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAoC5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CA2iBzF"}
1
+ {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAoBpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAoC5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CAklBzF"}
@@ -46,7 +46,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
46
46
  const { fitView } = useReactFlow();
47
47
  const drawerTimerRef = useRef(null);
48
48
  const { defaultViewport, onMoveEnd: handleViewportChange, resetViewport, } = useViewportPersistence();
49
- const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleArchiveFeature, handleDeleteFeature, handleRetryFeature, handleStartFeature, handleStopFeature, handleUnarchiveFeature, handleDeleteRepository, createFeatureNode, showArchived, setShowArchived, setCallbacks, } = useControlCenterState(initialNodes, initialEdges);
49
+ const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleArchiveFeature, handleDeleteFeature, handleRetryFeature, handleStartFeature, handleStopFeature, handleUnarchiveFeature, handleDeleteRepository, handleDeleteApplication, createFeatureNode, showArchived, setShowArchived, setCallbacks, } = useControlCenterState(initialNodes, initialEdges);
50
50
  // ── Workspaces (client-only prototype) ────────────────────────────────
51
51
  const { workspaces, activeWorkspace, isDefaultActive, setActiveWorkspace, createWorkspace, renameWorkspace, deleteWorkspace, setWorkspaceMembers, addToActiveWorkspace, } = useWorkspaces();
52
52
  // Tracks the set of node ids we've already seen, so we can detect new
@@ -98,6 +98,9 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
98
98
  setSidebarFeatures(sidebarItems);
99
99
  }, [sidebarKey, featureNodes, setSidebarFeatures]);
100
100
  // ── URL-based navigation handlers ────────────────────────────────────
101
+ const handleApplicationClick = useCallback((applicationId) => {
102
+ guardedNavigate(() => router.push(`/application/${applicationId}`));
103
+ }, [router, guardedNavigate]);
101
104
  const handleNodeClick = useCallback((event, node) => {
102
105
  if (node.type === 'featureNode') {
103
106
  const data = node.data;
@@ -223,6 +226,8 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
223
226
  onRepositoryAdd: handleAddFeatureToRepo,
224
227
  onRepositoryClick: handleRepositoryClick,
225
228
  onRepositoryDelete: handleDeleteRepository,
229
+ onApplicationClick: handleApplicationClick,
230
+ onApplicationDelete: handleDeleteApplication,
226
231
  });
227
232
  }, [
228
233
  setCallbacks,
@@ -236,6 +241,8 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
236
241
  handleAddFeatureToRepo,
237
242
  handleRepositoryClick,
238
243
  handleDeleteRepository,
244
+ handleApplicationClick,
245
+ handleDeleteApplication,
239
246
  ]);
240
247
  const handleMoveEnd = useCallback((_event, viewport) => {
241
248
  handleViewportChange(viewport);
@@ -348,7 +355,11 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
348
355
  // here — and crucially, leaves the workspace selector visible via the
349
356
  // toolbar so users can switch back to the default workspace.
350
357
  const workspaceFilteredEmpty = hasRepositories && !isDefaultActive && workspaceFilteredNodes.length === 0;
351
- const emptyStateNode = workspaceFilteredEmpty ? (_jsxs("div", { className: "pointer-events-auto flex h-full w-full flex-col items-center justify-center px-8", children: [_jsx("div", { className: "bg-primary/10 text-primary mb-5 flex h-12 w-12 items-center justify-center rounded-2xl", children: _jsx(Layers, { className: "h-6 w-6" }) }), _jsx("h2", { className: "text-foreground/90 text-center text-2xl font-light tracking-tight", children: "This workspace is empty" }), _jsx("p", { className: "text-muted-foreground mt-2 max-w-sm text-center text-sm leading-relaxed", children: "Add repositories or features from the canvas, or switch back to the default workspace to see everything." }), _jsxs("div", { className: "mt-6 flex items-center gap-2", children: [_jsxs(Button, { size: "sm", onClick: () => setWorkspaceNewProjectOpen(true), className: "bg-blue-500 text-white hover:bg-blue-600", children: [_jsx(FolderPlus, { className: "me-1.5 h-3.5 w-3.5" }), "New project"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setManageWorkspaceOpen(true), children: [_jsx(Plus, { className: "me-1.5 h-3.5 w-3.5" }), "Manage items"] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setActiveWorkspace(DEFAULT_WORKSPACE_ID), children: "Switch to Default" })] })] })) : (_jsx(ControlCenterEmptyState, { onRepositorySelect: addRepoAndFocus }));
358
+ const emptyStateNode = workspaceFilteredEmpty ? (_jsxs("div", { className: "pointer-events-auto flex h-full w-full flex-col items-center justify-center px-8", children: [_jsx("div", { className: "bg-primary/10 text-primary mb-5 flex h-12 w-12 items-center justify-center rounded-2xl", children: _jsx(Layers, { className: "h-6 w-6" }) }), _jsx("h2", { className: "text-foreground/90 text-center text-2xl font-light tracking-tight", children: "This workspace is empty" }), _jsx("p", { className: "text-muted-foreground mt-2 max-w-sm text-center text-sm leading-relaxed", children: "Add repositories or features from the canvas, or switch back to the default workspace to see everything." }), _jsxs("div", { className: "mt-6 flex items-center gap-2", children: [_jsxs(Button, { size: "sm", onClick: () => setWorkspaceNewProjectOpen(true), className: "bg-blue-500 text-white hover:bg-blue-600", children: [_jsx(FolderPlus, { className: "me-1.5 h-3.5 w-3.5" }), "New project"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => setManageWorkspaceOpen(true), children: [_jsx(Plus, { className: "me-1.5 h-3.5 w-3.5" }), "Manage items"] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setActiveWorkspace(DEFAULT_WORKSPACE_ID), children: "Switch to Default" })] })] })) : (_jsx(ControlCenterEmptyState, { onRepositorySelect: addRepoAndFocus, onApplicationCreated: (appId, initialPrompt) => {
359
+ router.push(`/application/${appId}?prompt=${encodeURIComponent(initialPrompt)}`);
360
+ } }));
361
+ // ── Full-screen create prompt overlay ────────────────────────────────
362
+ const [showCreatePrompt, setShowCreatePrompt] = useState(false);
352
363
  const featureFlags = useFeatureFlags();
353
364
  // (+) FAB actions — only visible on control center. Action list lives in
354
365
  // its own hook so this component stays focused on graph state + rendering.
@@ -358,6 +369,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
358
369
  guardedNavigate,
359
370
  handlePickFolder,
360
371
  onNewProject: () => setWorkspaceNewProjectOpen(true),
372
+ onNewApplication: () => setShowCreatePrompt(true),
361
373
  featureFlags,
362
374
  });
363
375
  const canvasToolbar = (_jsx(CanvasToolbar, { showArchived: showArchived, onToggleArchived: () => setShowArchived(!showArchived), onResetViewport: resetViewport, startSlot: _jsx(WorkspaceSelector, { workspaces: workspaces, activeWorkspace: activeWorkspace, onSelect: setActiveWorkspace, onRequestCreate: () => setCreateWorkspaceOpen(true), onRequestRename: () => setRenameWorkspaceOpen(true), onRequestDelete: (id) => {
@@ -377,7 +389,13 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
377
389
  deleteWorkspace(pendingDeleteWorkspaceId);
378
390
  setPendingDeleteWorkspaceId(null);
379
391
  }
380
- }, children: "Delete" })] })] }) })] }));
392
+ }, children: "Delete" })] })] }) }), showCreatePrompt ? (_jsx("div", { className: "absolute inset-0 z-50", children: _jsx(ControlCenterEmptyState, { onRepositorySelect: (path) => {
393
+ setShowCreatePrompt(false);
394
+ addRepoAndFocus(path);
395
+ }, onApplicationCreated: (appId, initialPrompt) => {
396
+ setShowCreatePrompt(false);
397
+ router.push(`/application/${appId}?prompt=${encodeURIComponent(initialPrompt)}`);
398
+ }, onClose: () => setShowCreatePrompt(false), className: "bg-background" }) })) : null] }));
381
399
  }
382
400
  /** (+) FAB that tracks sidebar width via CSS var + transition.
383
401
  * When fabLayout.swapPosition is true, moves to the end side (right in LTR). */
@@ -3,6 +3,7 @@ import type { FeatureNodeData } from '../../common/feature-node/index.js';
3
3
  import type { RepositoryNodeData } from '../../common/repository-node/index.js';
4
4
  import type { CanvasNodeType } from '../../features/features-canvas/index.js';
5
5
  import { type LayoutDirection } from '../../../lib/layout-with-dagre.js';
6
+ import type { ApplicationNodeData } from '../../common/application-node/application-node-config.js';
6
7
  import { type GraphCallbacks } from '../../../hooks/use-graph-state.js';
7
8
  export interface ControlCenterState {
8
9
  nodes: CanvasNodeType[];
@@ -24,7 +25,10 @@ export interface ControlCenterState {
24
25
  handleDeleteRepository: (repositoryId: string, options?: {
25
26
  deleteFromDisk?: boolean;
26
27
  }) => Promise<void>;
28
+ handleDeleteApplication: (applicationId: string) => Promise<void>;
27
29
  createFeatureNode: (sourceNodeId: string | null, dataOverride?: Partial<FeatureNodeData>, edgeType?: string) => string;
30
+ /** Add an application node to the canvas optimistically. */
31
+ addApplication: (nodeId: string, data: ApplicationNodeData) => void;
28
32
  /** Whether archived features are shown on the canvas. */
29
33
  showArchived: boolean;
30
34
  /** Toggle archived feature visibility. */