@shepai/cli 1.92.1 → 1.92.2-pr278.ee19983

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 (219) hide show
  1. package/dist/src/presentation/web/app/actions/check-agent-tool.d.ts +9 -0
  2. package/dist/src/presentation/web/app/actions/check-agent-tool.d.ts.map +1 -0
  3. package/dist/src/presentation/web/app/actions/check-agent-tool.js +28 -0
  4. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.d.ts +2 -0
  5. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.d.ts.map +1 -1
  6. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.js +16 -0
  7. package/dist/src/presentation/web/components/common/feature-status-badges/feature-status-badges.stories.js +6 -6
  8. package/dist/src/presentation/web/components/common/feature-status-config.d.ts +1 -1
  9. package/dist/src/presentation/web/components/common/feature-status-config.d.ts.map +1 -1
  10. package/dist/src/presentation/web/components/common/feature-status-config.js +20 -2
  11. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.d.ts.map +1 -1
  12. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +18 -3
  13. package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts +6 -0
  14. package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map +1 -0
  15. package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.js +169 -0
  16. package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.stories.d.ts +7 -0
  17. package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.stories.d.ts.map +1 -0
  18. package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.stories.js +20 -0
  19. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +1 -1
  20. package/dist/src/presentation/web/hooks/sidebar-features-context.d.ts +1 -1
  21. package/dist/src/presentation/web/hooks/sidebar-features-context.js +4 -4
  22. package/dist/src/presentation/web/lib/layout-with-dagre.d.ts.map +1 -1
  23. package/dist/src/presentation/web/lib/layout-with-dagre.js +78 -55
  24. package/dist/tsconfig.build.tsbuildinfo +1 -1
  25. package/package.json +1 -1
  26. package/web/.next/BUILD_ID +1 -1
  27. package/web/.next/build-manifest.json +2 -2
  28. package/web/.next/fallback-build-manifest.json +2 -2
  29. package/web/.next/prerender-manifest.json +3 -3
  30. package/web/.next/required-server-files.js +3 -3
  31. package/web/.next/required-server-files.json +3 -3
  32. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +77 -62
  33. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +2 -2
  34. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  35. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  36. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +87 -42
  37. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +2 -2
  38. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  39. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  40. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +87 -42
  41. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +2 -2
  42. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  43. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  44. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +73 -28
  45. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +2 -2
  46. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  47. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  48. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +77 -62
  49. package/web/.next/server/app/(dashboard)/create/page.js +2 -2
  50. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  51. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +87 -42
  53. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +2 -2
  54. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  55. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +87 -42
  57. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +2 -2
  58. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  59. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  60. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +73 -28
  61. package/web/.next/server/app/(dashboard)/page.js +2 -2
  62. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  63. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +73 -28
  65. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +2 -2
  66. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  67. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  68. package/web/.next/server/app/_global-error.html +2 -2
  69. package/web/.next/server/app/_global-error.rsc +1 -1
  70. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  71. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  72. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  73. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  74. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  75. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  76. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  77. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  78. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  79. package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
  80. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  81. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  82. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  83. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  84. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  85. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  86. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  87. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  88. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  89. package/web/.next/server/app/version/page.js.nft.json +1 -1
  90. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  91. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  92. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  93. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_2b65878f._.js +3 -0
  94. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_2b65878f._.js.map +1 -0
  95. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_6ba7eb21._.js +3 -0
  96. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_6ba7eb21._.js.map +1 -0
  97. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_002ab1c0.js +3 -0
  98. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_002ab1c0.js.map +1 -0
  99. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_1bab40be.js +3 -0
  100. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_1bab40be.js.map +1 -0
  101. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
  102. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
  103. package/web/.next/server/chunks/ssr/{[root-of-the-server]__17143953._.js → [root-of-the-server]__22751bba._.js} +2 -2
  104. package/web/.next/server/chunks/ssr/{[root-of-the-server]__9de266fa._.js.map → [root-of-the-server]__22751bba._.js.map} +1 -1
  105. package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +4 -0
  106. package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js.map +1 -0
  107. package/web/.next/server/chunks/ssr/{[root-of-the-server]__45aad79d._.js → [root-of-the-server]__31fc8960._.js} +2 -2
  108. package/web/.next/server/chunks/ssr/{[root-of-the-server]__5cc4752a._.js.map → [root-of-the-server]__31fc8960._.js.map} +1 -1
  109. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  110. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
  111. package/web/.next/server/chunks/ssr/[root-of-the-server]__7b49fcb3._.js +3 -0
  112. package/web/.next/server/chunks/ssr/[root-of-the-server]__7b49fcb3._.js.map +1 -0
  113. package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js +3 -0
  114. package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js.map +1 -0
  115. package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
  116. package/web/.next/server/chunks/ssr/{[root-of-the-server]__5cc4752a._.js → [root-of-the-server]__9497d008._.js} +2 -2
  117. package/web/.next/server/chunks/ssr/{[root-of-the-server]__45aad79d._.js.map → [root-of-the-server]__9497d008._.js.map} +1 -1
  118. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  119. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/{[root-of-the-server]__9de266fa._.js → [root-of-the-server]__fb487740._.js} +2 -2
  121. package/web/.next/server/chunks/ssr/{[root-of-the-server]__17143953._.js.map → [root-of-the-server]__fb487740._.js.map} +1 -1
  122. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
  123. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  125. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  126. package/web/.next/server/chunks/ssr/_27d8284c._.js +3 -0
  127. package/web/.next/server/chunks/ssr/_27d8284c._.js.map +1 -0
  128. package/web/.next/server/chunks/ssr/_5e112f82._.js +3 -0
  129. package/web/.next/server/chunks/ssr/_5e112f82._.js.map +1 -0
  130. package/web/.next/server/chunks/ssr/{_f02f4210._.js → _7b21ec40._.js} +2 -2
  131. package/web/.next/server/chunks/ssr/_7b21ec40._.js.map +1 -0
  132. package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
  133. package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
  134. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  135. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  136. package/web/.next/server/chunks/ssr/{_3533fed7._.js → _e8b48c1f._.js} +2 -2
  137. package/web/.next/server/chunks/ssr/_e8b48c1f._.js.map +1 -0
  138. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  139. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  140. package/web/.next/server/chunks/ssr/src_presentation_web_3a8fc63d._.js +5 -0
  141. package/web/.next/server/chunks/ssr/src_presentation_web_3a8fc63d._.js.map +1 -0
  142. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1695630c.js +3 -0
  143. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1695630c.js.map +1 -0
  144. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  145. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  146. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  147. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  148. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js +1 -1
  149. package/web/.next/server/chunks/ssr/src_presentation_web_app_(dashboard)_get-graph-data_ts_b018483e._.js.map +1 -1
  150. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  151. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +1 -1
  152. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  153. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js.map +1 -1
  154. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  155. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  156. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  157. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  158. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js +1 -1
  159. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js.map +1 -1
  160. package/web/.next/server/chunks/ssr/src_presentation_web_f16e6874._.js +5 -0
  161. package/web/.next/server/chunks/ssr/src_presentation_web_f16e6874._.js.map +1 -0
  162. package/web/.next/server/pages/500.html +2 -2
  163. package/web/.next/server/server-reference-manifest.js +1 -1
  164. package/web/.next/server/server-reference-manifest.json +411 -242
  165. package/web/.next/static/chunks/22df66703eb5f3da.js +1 -0
  166. package/web/.next/static/chunks/{bea7a5f44d99512f.js → 2cae690a6e6d0e72.js} +1 -1
  167. package/web/.next/static/chunks/{2d02a8deb3cfb404.js → 34d3d111db7690d8.js} +1 -1
  168. package/web/.next/static/chunks/3f3372acc5e80c45.js +1 -0
  169. package/web/.next/static/chunks/{5b3dd4146a57ce02.js → 4da377f74674081d.js} +1 -1
  170. package/web/.next/static/chunks/{2ddedc7a1d0d0a35.js → 5f0035a26f2c4011.js} +1 -1
  171. package/web/.next/static/chunks/6166463c2782ca01.js +1 -0
  172. package/web/.next/static/chunks/61c4d617e4b83d4b.css +1 -0
  173. package/web/.next/static/chunks/8bd300e88a189928.js +1 -0
  174. package/web/.next/static/chunks/926187ca93fe781a.js +1 -0
  175. package/web/.next/static/chunks/{e1adbd3c092ccc3c.js → 99c6d0f90a29e17a.js} +2 -2
  176. package/web/.next/static/chunks/acf2e05520520b66.js +1 -0
  177. package/web/.next/static/chunks/b272ac93b52dceeb.js +1 -0
  178. package/web/.next/static/chunks/c198094e39d8c479.js +11 -0
  179. package/web/.next/static/chunks/c76adccb47c1ccd2.css +1 -0
  180. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_81a06555._.js +0 -3
  181. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_81a06555._.js.map +0 -1
  182. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js +0 -3
  183. package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js.map +0 -1
  184. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +0 -3
  185. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js.map +0 -1
  186. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +0 -3
  187. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js.map +0 -1
  188. package/web/.next/server/chunks/ssr/[root-of-the-server]__4be9a9bb._.js +0 -4
  189. package/web/.next/server/chunks/ssr/[root-of-the-server]__4be9a9bb._.js.map +0 -1
  190. package/web/.next/server/chunks/ssr/[root-of-the-server]__9dc40036._.js +0 -3
  191. package/web/.next/server/chunks/ssr/[root-of-the-server]__9dc40036._.js.map +0 -1
  192. package/web/.next/server/chunks/ssr/[root-of-the-server]__e630cc47._.js +0 -3
  193. package/web/.next/server/chunks/ssr/[root-of-the-server]__e630cc47._.js.map +0 -1
  194. package/web/.next/server/chunks/ssr/_21c75883._.js +0 -3
  195. package/web/.next/server/chunks/ssr/_21c75883._.js.map +0 -1
  196. package/web/.next/server/chunks/ssr/_3533fed7._.js.map +0 -1
  197. package/web/.next/server/chunks/ssr/_a5c23e45._.js +0 -3
  198. package/web/.next/server/chunks/ssr/_a5c23e45._.js.map +0 -1
  199. package/web/.next/server/chunks/ssr/_f02f4210._.js.map +0 -1
  200. package/web/.next/server/chunks/ssr/_f50485a5._.js +0 -3
  201. package/web/.next/server/chunks/ssr/_f50485a5._.js.map +0 -1
  202. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +0 -3
  203. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js.map +0 -1
  204. package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js +0 -5
  205. package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js.map +0 -1
  206. package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js +0 -5
  207. package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js.map +0 -1
  208. package/web/.next/static/chunks/1a2af08680037549.js +0 -1
  209. package/web/.next/static/chunks/30a344bb33a015e4.js +0 -1
  210. package/web/.next/static/chunks/4f94860011f9fb20.css +0 -2
  211. package/web/.next/static/chunks/8a174308ba4bd69d.js +0 -1
  212. package/web/.next/static/chunks/d7f984a3e8043cb0.js +0 -1
  213. package/web/.next/static/chunks/d9247a52ae260218.js +0 -1
  214. package/web/.next/static/chunks/dac26a484f476f36.js +0 -1
  215. package/web/.next/static/chunks/dd04e12ee5ccb0ad.js +0 -1
  216. package/web/.next/static/chunks/f54b972c149092b5.js +0 -11
  217. /package/web/.next/static/{UOxWj8CnreBdyLxAYAGYQ → wmnBSet3smW0EP_P18pPA}/_buildManifest.js +0 -0
  218. /package/web/.next/static/{UOxWj8CnreBdyLxAYAGYQ → wmnBSet3smW0EP_P18pPA}/_clientMiddlewareManifest.json +0 -0
  219. /package/web/.next/static/{UOxWj8CnreBdyLxAYAGYQ → wmnBSet3smW0EP_P18pPA}/_ssgManifest.js +0 -0
@@ -0,0 +1,9 @@
1
+ import type { ToolItem } from '../../../../../packages/core/src/application/use-cases/tools/list-tools.use-case.js';
2
+ export interface AgentToolStatus {
3
+ agentType: string;
4
+ toolId: string | null;
5
+ tool: ToolItem | null;
6
+ installed: boolean;
7
+ }
8
+ export declare function checkAgentTool(agentType: string): Promise<AgentToolStatus>;
9
+ //# sourceMappingURL=check-agent-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-agent-tool.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/check-agent-tool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8DAA8D,CAAC;AAY7F,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAkBhF"}
@@ -0,0 +1,28 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ /**
4
+ * Maps agent types to their corresponding tool IDs in the tool registry.
5
+ * These IDs match the JSON file names in tool-installer/tools/.
6
+ */
7
+ const AGENT_TOOL_MAP = {
8
+ 'claude-code': 'claude-code',
9
+ cursor: 'cursor-cli',
10
+ 'gemini-cli': 'gemini-cli',
11
+ };
12
+ export async function checkAgentTool(agentType) {
13
+ const toolId = AGENT_TOOL_MAP[agentType] ?? null;
14
+ // Dev agent and unknown agents don't need a tool
15
+ if (!toolId) {
16
+ return { agentType, toolId: null, tool: null, installed: true };
17
+ }
18
+ try {
19
+ const useCase = resolve('ListToolsUseCase');
20
+ const tools = await useCase.execute();
21
+ const tool = tools.find((t) => t.id === toolId) ?? null;
22
+ const installed = tool?.status.status === 'available';
23
+ return { agentType, toolId, tool, installed };
24
+ }
25
+ catch {
26
+ return { agentType, toolId, tool: null, installed: false };
27
+ }
28
+ }
@@ -6,6 +6,8 @@ type Story = StoryObj<typeof meta>;
6
6
  export declare const ActionNeeded: Story;
7
7
  export declare const InProgress: Story;
8
8
  export declare const Done: Story;
9
+ export declare const Blocked: Story;
10
+ export declare const Error: Story;
9
11
  export declare const WithClickHandler: Story;
10
12
  export declare const WithoutAgent: Story;
11
13
  //# sourceMappingURL=feature-list-item.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-list-item.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-list-item/feature-list-item.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,eAAe,CAgBtC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,YAAY,EAAE,KAO1B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAQxB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KAQlB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAQ9B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC"}
1
+ {"version":3,"file":"feature-list-item.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-list-item/feature-list-item.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,eAAe,CAgBtC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,YAAY,EAAE,KAO1B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAQxB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KAQlB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAOnB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAQ9B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC"}
@@ -39,6 +39,22 @@ export const Done = {
39
39
  modelId: 'gemini-2.5-pro',
40
40
  },
41
41
  };
42
+ export const Blocked = {
43
+ args: {
44
+ name: 'Dependency Resolver',
45
+ status: 'blocked',
46
+ agentType: 'claude-code',
47
+ modelId: 'claude-sonnet-4-6',
48
+ },
49
+ };
50
+ export const Error = {
51
+ args: {
52
+ name: 'Broken Pipeline',
53
+ status: 'error',
54
+ agentType: 'cursor',
55
+ modelId: 'claude-opus-4-6',
56
+ },
57
+ };
42
58
  export const WithClickHandler = {
43
59
  args: {
44
60
  name: 'API Gateway',
@@ -15,31 +15,31 @@ const meta = {
15
15
  export default meta;
16
16
  export const AllStatuses = {
17
17
  args: {
18
- counts: { 'action-needed': 2, 'in-progress': 3, done: 5 },
18
+ counts: { 'action-needed': 2, 'in-progress': 3, blocked: 1, error: 1, done: 5 },
19
19
  },
20
20
  };
21
21
  export const ActionNeededOnly = {
22
22
  args: {
23
- counts: { 'action-needed': 4, 'in-progress': 0, done: 0 },
23
+ counts: { 'action-needed': 4, 'in-progress': 0, blocked: 0, error: 0, done: 0 },
24
24
  },
25
25
  };
26
26
  export const InProgressOnly = {
27
27
  args: {
28
- counts: { 'action-needed': 0, 'in-progress': 2, done: 0 },
28
+ counts: { 'action-needed': 0, 'in-progress': 2, blocked: 0, error: 0, done: 0 },
29
29
  },
30
30
  };
31
31
  export const DoneOnly = {
32
32
  args: {
33
- counts: { 'action-needed': 0, 'in-progress': 0, done: 7 },
33
+ counts: { 'action-needed': 0, 'in-progress': 0, blocked: 0, error: 0, done: 7 },
34
34
  },
35
35
  };
36
36
  export const LargeCounts = {
37
37
  args: {
38
- counts: { 'action-needed': 12, 'in-progress': 99, done: 150 },
38
+ counts: { 'action-needed': 12, 'in-progress': 99, blocked: 5, error: 3, done: 150 },
39
39
  },
40
40
  };
41
41
  export const Empty = {
42
42
  args: {
43
- counts: { 'action-needed': 0, 'in-progress': 0, done: 0 },
43
+ counts: { 'action-needed': 0, 'in-progress': 0, blocked: 0, error: 0, done: 0 },
44
44
  },
45
45
  };
@@ -1,5 +1,5 @@
1
1
  import type { LucideIcon } from 'lucide-react';
2
- export type FeatureStatus = 'action-needed' | 'in-progress' | 'done';
2
+ export type FeatureStatus = 'action-needed' | 'in-progress' | 'blocked' | 'error' | 'done';
3
3
  export interface FeatureStatusConfig {
4
4
  icon: LucideIcon;
5
5
  iconClass: string;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-status-config.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/common/feature-status-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,aAAa,GAAG,MAAM,CAAC;AAErE,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,aAAa,EAAE,mBAAmB,CAmB1E,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,aAAa,EAA6C,CAAC"}
1
+ {"version":3,"file":"feature-status-config.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/common/feature-status-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3F,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,aAAa,EAAE,mBAAmB,CA+B1E,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,aAAa,EAM7C,CAAC"}
@@ -1,4 +1,4 @@
1
- import { CircleAlert, Loader2, CircleCheck } from 'lucide-react';
1
+ import { CircleAlert, Loader2, CircleCheck, Ban, CircleX } from 'lucide-react';
2
2
  export const featureStatusConfig = {
3
3
  'action-needed': {
4
4
  icon: CircleAlert,
@@ -12,6 +12,18 @@ export const featureStatusConfig = {
12
12
  bgClass: 'bg-blue-500/10',
13
13
  label: 'In Progress',
14
14
  },
15
+ blocked: {
16
+ icon: Ban,
17
+ iconClass: 'text-gray-400',
18
+ bgClass: 'bg-gray-400/10',
19
+ label: 'Blocked',
20
+ },
21
+ error: {
22
+ icon: CircleX,
23
+ iconClass: 'text-red-500',
24
+ bgClass: 'bg-red-500/10',
25
+ label: 'Error',
26
+ },
15
27
  done: {
16
28
  icon: CircleCheck,
17
29
  iconClass: 'text-emerald-500',
@@ -19,4 +31,10 @@ export const featureStatusConfig = {
19
31
  label: 'Done',
20
32
  },
21
33
  };
22
- export const featureStatusOrder = ['action-needed', 'in-progress', 'done'];
34
+ export const featureStatusOrder = [
35
+ 'action-needed',
36
+ 'error',
37
+ 'blocked',
38
+ 'in-progress',
39
+ 'done',
40
+ ];
@@ -1 +1 @@
1
- {"version":3,"file":"control-center-empty-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,4BAA4B;IAC3C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,uBAAuB,CAAC,EACtC,kBAAkB,EAClB,SAAS,GACV,EAAE,4BAA4B,2CAsG9B"}
1
+ {"version":3,"file":"control-center-empty-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-empty-state.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,4BAA4B;IAC3C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,uBAAuB,CAAC,EACtC,kBAAkB,EAClB,SAAS,GACV,EAAE,4BAA4B,2CA+H9B"}
@@ -1,13 +1,20 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useState, useCallback } from 'react';
4
4
  import { Github, Plus, TerminalSquare, Copy, Check, Loader2 } from 'lucide-react';
5
5
  import { cn } from '../../../lib/utils.js';
6
6
  import { pickFolder } from '../../common/add-repository-button/pick-folder.js';
7
- const commands = ['cd ~/my-repo', 'shep feat new "create modern, sleek dashboards"'];
7
+ import { WelcomeAgentSetup } from './welcome-agent-setup.js';
8
+ const AGENT_CONFIGURED_KEY = 'shep:agent-configured';
9
+ const commands = ['cd ~/my-repo', 'shep feat new "sleek dashboard"'];
8
10
  export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
9
11
  const [copied, setCopied] = useState(false);
10
12
  const [loading, setLoading] = useState(false);
13
+ const [agentReady, setAgentReady] = useState(() => {
14
+ if (typeof window === 'undefined')
15
+ return false;
16
+ return localStorage.getItem(AGENT_CONFIGURED_KEY) === 'true';
17
+ });
11
18
  async function handlePickerClick() {
12
19
  if (loading)
13
20
  return;
@@ -27,5 +34,13 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
27
34
  setCopied(true);
28
35
  setTimeout(() => setCopied(false), 2000);
29
36
  }, []);
30
- return (_jsxs("div", { "data-testid": "control-center-empty-state", className: cn('relative h-full w-full', className), children: [_jsx("div", { className: "absolute inset-0 [background-image:radial-gradient(circle,_var(--color-border)_1px,_transparent_1px)] [background-size:24px_24px]" }), _jsxs("div", { className: "absolute top-8 left-8 z-10", children: [_jsx("h1", { className: "text-4xl font-bold tracking-tight", children: "Features" }), _jsx("p", { className: "text-muted-foreground text-3xl font-light", children: "Control Center" })] }), _jsx("div", { className: "relative z-10 flex h-full items-center justify-center", children: _jsxs("div", { className: "flex max-w-lg flex-col items-center gap-6", children: [_jsxs("div", { className: "text-muted-foreground flex items-center gap-2", children: [_jsx(Github, { className: "h-4 w-4" }), _jsx("span", { className: "text-xs font-semibold tracking-widest uppercase", children: "Repositories" })] }), _jsxs("button", { type: "button", "data-testid": "empty-state-add-repository", onClick: handlePickerClick, disabled: loading, className: "border-muted-foreground/30 hover:border-primary hover:text-primary flex cursor-pointer items-center gap-3 rounded-lg border-2 border-dashed px-8 py-4 transition-colors disabled:cursor-wait disabled:opacity-60", children: [loading ? _jsx(Loader2, { className: "h-5 w-5 animate-spin" }) : _jsx(Plus, { className: "h-5 w-5" }), _jsx("span", { className: "text-sm font-medium", children: loading ? 'Opening...' : 'Add Repository' })] }), _jsxs("div", { className: "text-muted-foreground flex items-center gap-3", children: [_jsx("div", { className: "bg-border h-px w-16" }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(TerminalSquare, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-xs font-semibold tracking-widest uppercase", children: "Or start from the command line" })] }), _jsx("div", { className: "bg-border h-px w-16" })] }), _jsxs("div", { "data-testid": "cli-code-block", className: "relative w-full rounded-lg bg-zinc-900 px-5 py-4 font-mono text-sm text-zinc-100", children: [_jsx("button", { type: "button", "data-testid": "cli-code-block-copy", onClick: handleCopy, className: "absolute top-3 right-3 cursor-pointer rounded p-1.5 text-zinc-400 transition-colors hover:bg-zinc-800 hover:text-zinc-200", "aria-label": "Copy commands", children: copied ? _jsx(Check, { className: "h-4 w-4" }) : _jsx(Copy, { className: "h-4 w-4" }) }), _jsx("div", { className: "space-y-1", children: commands.map((cmd) => (_jsxs("div", { children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), _jsx("span", { children: cmd })] }, cmd))) })] }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Feature will appear on canvas once created" })] }) })] }));
37
+ const handleAgentSetupComplete = useCallback(() => {
38
+ localStorage.setItem(AGENT_CONFIGURED_KEY, 'true');
39
+ setAgentReady(true);
40
+ }, []);
41
+ return (_jsxs("div", { "data-testid": "control-center-empty-state", className: cn('relative h-full w-full', className), children: [_jsx("div", { className: "absolute inset-0 [background-image:radial-gradient(circle,_var(--color-border)_1px,_transparent_1px)] [background-size:24px_24px]" }), _jsxs("div", { className: "absolute top-8 left-8 z-10", children: [_jsx("h1", { className: "text-4xl font-bold tracking-tight", children: "Features" }), _jsx("p", { className: "text-muted-foreground text-3xl font-light", children: "Control Center" })] }), _jsx("div", { className: "relative z-10 flex h-full items-center justify-center", children: _jsx("div", { className: "flex w-72 flex-col items-center gap-4", children: !agentReady ? (
42
+ /* Step 1: Agent setup */
43
+ _jsx(WelcomeAgentSetup, { onComplete: handleAgentSetupComplete })) : (
44
+ /* Step 2: Add repository (shown after agent is configured) */
45
+ _jsxs(_Fragment, { children: [_jsxs("div", { className: "text-muted-foreground flex items-center gap-2", children: [_jsx(Github, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-[10px] font-semibold tracking-widest uppercase", children: "Repositories" })] }), _jsxs("button", { type: "button", "data-testid": "empty-state-add-repository", onClick: handlePickerClick, disabled: loading, className: "border-border hover:border-foreground/40 flex w-full cursor-pointer items-center gap-2.5 rounded-md border border-dashed px-4 py-2.5 transition-colors disabled:cursor-wait disabled:opacity-50", children: [loading ? (_jsx(Loader2, { className: "text-muted-foreground h-4 w-4 animate-spin" })) : (_jsx(Plus, { className: "text-muted-foreground h-4 w-4" })), _jsx("span", { className: "text-xs font-medium", children: loading ? 'Opening…' : 'Add Repository' })] }), _jsxs("div", { className: "text-muted-foreground flex items-center gap-2", children: [_jsx("div", { className: "bg-border h-px w-10" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(TerminalSquare, { className: "h-3 w-3" }), _jsx("span", { className: "text-[10px] font-semibold tracking-widest uppercase", children: "Or via CLI" })] }), _jsx("div", { className: "bg-border h-px w-10" })] }), _jsxs("div", { "data-testid": "cli-code-block", className: "relative w-full rounded-md bg-zinc-900 px-3 py-2 font-mono text-[11px] text-zinc-300", children: [_jsx("button", { type: "button", "data-testid": "cli-code-block-copy", onClick: handleCopy, className: "absolute top-2 right-2 cursor-pointer rounded p-1 text-zinc-500 transition-colors hover:bg-zinc-800 hover:text-zinc-300", "aria-label": "Copy commands", children: copied ? _jsx(Check, { className: "h-3 w-3" }) : _jsx(Copy, { className: "h-3 w-3" }) }), _jsx("div", { className: "space-y-0.5", children: commands.map((cmd) => (_jsxs("div", { className: "whitespace-nowrap", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), _jsx("span", { children: cmd })] }, cmd))) })] }), _jsx("p", { className: "text-muted-foreground text-[10px]", children: "Feature will appear on canvas once created" })] })) }) })] }));
31
46
  }
@@ -0,0 +1,6 @@
1
+ export interface WelcomeAgentSetupProps {
2
+ onComplete: () => void;
3
+ className?: string;
4
+ }
5
+ export declare function WelcomeAgentSetup({ onComplete, className }: WelcomeAgentSetupProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=welcome-agent-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"welcome-agent-setup.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/welcome-agent-setup.tsx"],"names":[],"mappings":"AAwBA,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AASD,wBAAgB,iBAAiB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,sBAAsB,2CAqQlF"}
@@ -0,0 +1,169 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState, useEffect, useCallback, useRef } from 'react';
4
+ import { Check, ChevronRight, ChevronLeft, Download, Loader2, CheckCircle2, Circle, AlertCircle, Bot, } from 'lucide-react';
5
+ import { getAllAgentModels } from '../../../app/actions/get-all-agent-models.js';
6
+ import { checkAgentTool } from '../../../app/actions/check-agent-tool.js';
7
+ import { updateAgentAndModel } from '../../../app/actions/update-agent-and-model.js';
8
+ import { getAgentTypeIcon } from '../../common/feature-node/agent-type-icons.js';
9
+ import { getModelMeta } from '../../../lib/model-metadata.js';
10
+ import { useToolInstallStream } from '../../../hooks/use-tool-install-stream.js';
11
+ import { cn } from '../../../lib/utils.js';
12
+ const STEPS = ['select-agent', 'select-model', 'check-tool'];
13
+ /** Fixed width for the wizard content area to prevent layout jumps */
14
+ const WIZARD_WIDTH = 'w-72';
15
+ export function WelcomeAgentSetup({ onComplete, className }) {
16
+ const [groups, setGroups] = useState([]);
17
+ const [loading, setLoading] = useState(true);
18
+ const [step, setStep] = useState('select-agent');
19
+ const [selectedAgent, setSelectedAgent] = useState(null);
20
+ const [selectedModel, setSelectedModel] = useState(null);
21
+ const [toolStatus, setToolStatus] = useState(null);
22
+ const [checkingTool, setCheckingTool] = useState(false);
23
+ const [saving, setSaving] = useState(false);
24
+ const [transitioning, setTransitioning] = useState(false);
25
+ const [visible, setVisible] = useState(true);
26
+ const timeoutRef = useRef(undefined);
27
+ useEffect(() => {
28
+ getAllAgentModels()
29
+ .then(setGroups)
30
+ .finally(() => setLoading(false));
31
+ }, []);
32
+ const activeGroup = selectedAgent ? groups.find((g) => g.agentType === selectedAgent) : null;
33
+ /** Animate step transition: fade out → change step → fade in */
34
+ const transitionTo = useCallback((nextStep, setup) => {
35
+ setTransitioning(true);
36
+ setVisible(false);
37
+ if (timeoutRef.current)
38
+ clearTimeout(timeoutRef.current);
39
+ timeoutRef.current = setTimeout(() => {
40
+ setup?.();
41
+ setStep(nextStep);
42
+ // Small delay to let React render the new content before fading in
43
+ requestAnimationFrame(() => {
44
+ setVisible(true);
45
+ setTransitioning(false);
46
+ });
47
+ }, 150);
48
+ }, []);
49
+ useEffect(() => {
50
+ return () => {
51
+ if (timeoutRef.current)
52
+ clearTimeout(timeoutRef.current);
53
+ };
54
+ }, []);
55
+ const handleAgentSelect = useCallback((agentType) => {
56
+ const group = groups.find((g) => g.agentType === agentType);
57
+ if (group && group.models.length > 0) {
58
+ transitionTo('select-model', () => {
59
+ setSelectedAgent(agentType);
60
+ });
61
+ }
62
+ else {
63
+ transitionTo('check-tool', () => {
64
+ setSelectedAgent(agentType);
65
+ setSelectedModel('');
66
+ });
67
+ }
68
+ }, [groups, transitionTo]);
69
+ const handleModelSelect = useCallback((model) => {
70
+ transitionTo('check-tool', () => {
71
+ setSelectedModel(model);
72
+ });
73
+ }, [transitionTo]);
74
+ const handleBack = useCallback(() => {
75
+ if (step === 'select-model') {
76
+ transitionTo('select-agent', () => {
77
+ setSelectedAgent(null);
78
+ });
79
+ }
80
+ else if (step === 'check-tool') {
81
+ if (activeGroup && activeGroup.models.length > 0) {
82
+ transitionTo('select-model', () => {
83
+ setSelectedModel(null);
84
+ });
85
+ }
86
+ else {
87
+ transitionTo('select-agent', () => {
88
+ setSelectedAgent(null);
89
+ });
90
+ }
91
+ }
92
+ }, [step, activeGroup, transitionTo]);
93
+ useEffect(() => {
94
+ if (step !== 'check-tool' || !selectedAgent)
95
+ return;
96
+ setCheckingTool(true);
97
+ checkAgentTool(selectedAgent)
98
+ .then(setToolStatus)
99
+ .finally(() => setCheckingTool(false));
100
+ }, [step, selectedAgent]);
101
+ const handleConfirm = useCallback(async () => {
102
+ if (!selectedAgent)
103
+ return;
104
+ setSaving(true);
105
+ try {
106
+ await updateAgentAndModel(selectedAgent, selectedModel ?? null);
107
+ onComplete();
108
+ }
109
+ finally {
110
+ setSaving(false);
111
+ }
112
+ }, [selectedAgent, selectedModel, onComplete]);
113
+ if (loading) {
114
+ return (_jsxs("div", { "data-testid": "welcome-agent-setup", className: cn('flex flex-col items-center justify-center gap-3', className), children: [_jsx(Loader2, { className: "text-muted-foreground h-4 w-4 animate-spin" }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Loading agents\u2026" })] }));
115
+ }
116
+ const stepIndex = STEPS.indexOf(step);
117
+ return (_jsxs("div", { "data-testid": "welcome-agent-setup", className: cn('flex flex-col items-center gap-4', WIZARD_WIDTH, className), children: [_jsx("div", { className: "flex flex-col items-center gap-1", children: _jsxs("div", { className: "text-muted-foreground flex items-center gap-2", children: [step === 'select-agent' && (_jsxs(_Fragment, { children: [_jsx(Bot, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-[10px] font-semibold tracking-widest uppercase", children: "Choose your agent" })] })), step === 'select-model' && activeGroup
118
+ ? (() => {
119
+ const AgentIcon = getAgentTypeIcon(activeGroup.agentType);
120
+ return (_jsxs(_Fragment, { children: [_jsx(AgentIcon, { className: "h-3.5 w-3.5" }), _jsxs("span", { className: "text-[10px] font-semibold tracking-widest uppercase", children: [activeGroup.label, " \u2014 Pick a model"] })] }));
121
+ })()
122
+ : null, step === 'check-tool' && (_jsxs(_Fragment, { children: [_jsx(Bot, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-[10px] font-semibold tracking-widest uppercase", children: "Verifying setup" })] }))] }) }), _jsx("div", { className: "flex w-32 items-center gap-1", children: STEPS.map((s, i) => (_jsx("div", { className: cn('h-0.5 flex-1 rounded-full transition-colors duration-300', i <= stepIndex ? 'bg-foreground/60' : 'bg-muted') }, s))) }), _jsxs("div", { className: cn('flex w-full flex-col items-center transition-opacity duration-150', visible && !transitioning ? 'opacity-100' : 'opacity-0'), children: [step === 'select-agent' && (_jsx("div", { "data-testid": "agent-list", className: "flex w-full flex-col gap-1.5", children: groups.map((group) => {
123
+ const GroupIcon = getAgentTypeIcon(group.agentType);
124
+ return (_jsxs("button", { type: "button", "data-testid": `agent-option-${group.agentType}`, className: "border-border hover:border-foreground/40 flex w-full cursor-pointer items-center gap-2.5 rounded-md border border-dashed px-4 py-2.5 transition-colors", onClick: () => handleAgentSelect(group.agentType), children: [_jsx(GroupIcon, { className: "text-muted-foreground h-4 w-4 shrink-0" }), _jsx("span", { className: "flex-1 text-left text-xs font-medium", children: group.label }), _jsx(ChevronRight, { className: "text-muted-foreground h-3 w-3" })] }, group.agentType));
125
+ }) })), step === 'select-model' && activeGroup ? (_jsxs("div", { "data-testid": "model-list", className: "flex w-full flex-col gap-1.5", children: [_jsxs("button", { type: "button", className: "text-muted-foreground hover:text-foreground mb-0.5 flex cursor-pointer items-center gap-1 self-start text-[10px] font-medium transition-colors", onClick: handleBack, children: [_jsx(ChevronLeft, { className: "h-3 w-3" }), "Back"] }), _jsx("div", { className: "flex max-h-48 w-full flex-col gap-1.5 overflow-y-auto", children: activeGroup.models.map((m) => {
126
+ const meta = getModelMeta(m.id);
127
+ return (_jsxs("button", { type: "button", "data-testid": `model-option-${m.id}`, className: "border-border hover:border-foreground/40 flex w-full cursor-pointer items-center gap-2.5 rounded-md border border-dashed px-4 py-2.5 text-left transition-colors", onClick: () => handleModelSelect(m.id), children: [_jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [_jsx("span", { className: "text-xs font-medium", children: meta.displayName || m.displayName }), _jsx("span", { className: "text-muted-foreground text-[10px] leading-tight", children: meta.description || m.description })] }), _jsx(ChevronRight, { className: "text-muted-foreground h-3 w-3 shrink-0" })] }, m.id));
128
+ }) })] })) : null, step === 'check-tool' && (_jsx(ToolCheckStep, { toolStatus: toolStatus, checking: checkingTool, saving: saving, onConfirm: handleConfirm, onBack: handleBack, onToolInstalled: () => {
129
+ if (selectedAgent) {
130
+ setCheckingTool(true);
131
+ checkAgentTool(selectedAgent)
132
+ .then(setToolStatus)
133
+ .finally(() => setCheckingTool(false));
134
+ }
135
+ } }))] })] }));
136
+ }
137
+ /** Sub-component for the tool verification step */
138
+ function ToolCheckStep({ toolStatus, checking, saving, onConfirm, onBack, onToolInstalled, }) {
139
+ if (checking || !toolStatus) {
140
+ return (_jsxs("div", { className: "flex flex-col items-center gap-2 py-4", children: [_jsx(Loader2, { className: "text-muted-foreground h-4 w-4 animate-spin" }), _jsx("p", { className: "text-muted-foreground text-[10px]", children: "Checking tool availability\u2026" })] }));
141
+ }
142
+ // Agent doesn't require a tool (e.g., dev/demo)
143
+ if (!toolStatus.toolId) {
144
+ return (_jsxs("div", { className: "flex w-full flex-col items-center gap-3", children: [_jsxs("div", { className: "text-muted-foreground flex items-center gap-1.5", children: [_jsx(CheckCircle2, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-xs", children: "No additional tools required" })] }), _jsx(ConfirmRow, { saving: saving, onConfirm: onConfirm, onBack: onBack })] }));
145
+ }
146
+ if (toolStatus.installed) {
147
+ return (_jsxs("div", { className: "flex w-full flex-col items-center gap-3", children: [_jsxs("div", { className: "text-muted-foreground flex items-center gap-1.5", children: [_jsx(CheckCircle2, { className: "h-3.5 w-3.5" }), _jsxs("span", { className: "text-xs", children: [toolStatus.tool?.name ?? toolStatus.toolId, " is installed"] })] }), _jsx(ConfirmRow, { saving: saving, onConfirm: onConfirm, onBack: onBack })] }));
148
+ }
149
+ return (_jsx(ToolInstallInline, { toolStatus: toolStatus, saving: saving, onConfirm: onConfirm, onBack: onBack, onInstalled: onToolInstalled }));
150
+ }
151
+ /** Shared back + continue row */
152
+ function ConfirmRow({ saving, onConfirm, onBack, }) {
153
+ return (_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("button", { type: "button", className: "text-muted-foreground hover:text-foreground cursor-pointer text-[10px] transition-colors", onClick: onBack, children: [_jsx(ChevronLeft, { className: "mr-0.5 inline h-3 w-3" }), "Back"] }), _jsxs("button", { type: "button", "data-testid": "agent-setup-confirm", disabled: saving, className: "border-border hover:border-foreground/40 flex cursor-pointer items-center gap-1.5 rounded-md border border-dashed px-4 py-2 text-xs font-medium transition-colors disabled:opacity-50", onClick: onConfirm, children: [saving ? _jsx(Loader2, { className: "h-3 w-3 animate-spin" }) : _jsx(Check, { className: "h-3 w-3" }), "Continue"] })] }));
154
+ }
155
+ /** Inline tool installer for the welcome wizard */
156
+ function ToolInstallInline({ toolStatus, saving, onConfirm, onBack, onInstalled, }) {
157
+ const toolId = toolStatus.toolId ?? '';
158
+ const { logs, status, startInstall } = useToolInstallStream(toolId);
159
+ const isInstallDone = status === 'done';
160
+ const isInstallError = status === 'error';
161
+ useEffect(() => {
162
+ if (isInstallDone) {
163
+ onInstalled();
164
+ }
165
+ }, [isInstallDone, onInstalled]);
166
+ return (_jsxs("div", { className: "flex w-full flex-col items-center gap-3", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [isInstallDone ? (_jsx(CheckCircle2, { className: "text-muted-foreground h-3.5 w-3.5" })) : isInstallError ? (_jsx(AlertCircle, { className: "text-destructive h-3.5 w-3.5" })) : (_jsx(Circle, { className: "text-muted-foreground h-3.5 w-3.5" })), _jsxs("span", { className: "text-xs", children: [toolStatus.tool?.name ?? toolId, ' ', isInstallDone ? 'installed' : isInstallError ? 'install failed' : 'is not installed'] })] }), toolStatus.tool?.installCommand && status === 'idle' ? (_jsxs("div", { className: "w-full rounded-md bg-zinc-900 px-3 py-2 font-mono text-[11px] text-zinc-300", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), toolStatus.tool.installCommand] })) : null, (status === 'streaming' || isInstallDone || isInstallError) && logs.length > 0 ? (_jsxs("div", { className: "max-h-28 w-full overflow-auto rounded-md bg-zinc-900 px-3 py-2 font-mono text-[10px] leading-relaxed text-zinc-400", children: [logs.map((line, idx) => (
167
+ // eslint-disable-next-line react/no-array-index-key -- logs are append-only, never reorder
168
+ _jsx("div", { className: "break-all whitespace-pre-wrap", children: line }, idx))), isInstallDone ? (_jsx("div", { className: "text-muted-foreground mt-1", children: "Installation complete" })) : null, isInstallError ? (_jsx("div", { className: "text-destructive mt-1", children: "Installation failed \u2014 try manually" })) : null] })) : null, _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("button", { type: "button", className: "text-muted-foreground hover:text-foreground cursor-pointer text-[10px] transition-colors", onClick: onBack, children: [_jsx(ChevronLeft, { className: "mr-0.5 inline h-3 w-3" }), "Back"] }), !isInstallDone && toolStatus.tool?.autoInstall ? (_jsxs("button", { type: "button", "data-testid": "agent-setup-install", disabled: status === 'streaming', className: "border-border hover:border-foreground/40 flex cursor-pointer items-center gap-1.5 rounded-md border border-dashed px-4 py-2 text-xs font-medium transition-colors disabled:opacity-50", onClick: startInstall, children: [status === 'streaming' ? (_jsx(Loader2, { className: "h-3 w-3 animate-spin" })) : (_jsx(Download, { className: "h-3 w-3" })), status === 'streaming' ? 'Installing…' : 'Install'] })) : null, isInstallDone ? (_jsxs("button", { type: "button", "data-testid": "agent-setup-confirm", disabled: saving, className: "border-border hover:border-foreground/40 flex cursor-pointer items-center gap-1.5 rounded-md border border-dashed px-4 py-2 text-xs font-medium transition-colors disabled:opacity-50", onClick: onConfirm, children: [saving ? _jsx(Loader2, { className: "h-3 w-3 animate-spin" }) : _jsx(Check, { className: "h-3 w-3" }), "Continue"] })) : null] })] }));
169
+ }
@@ -0,0 +1,7 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { WelcomeAgentSetup } from './welcome-agent-setup.js';
3
+ declare const meta: Meta<typeof WelcomeAgentSetup>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof meta>;
6
+ export declare const Default: Story;
7
+ //# sourceMappingURL=welcome-agent-setup.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"welcome-agent-setup.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/welcome-agent-setup.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,iBAAiB,CAcxC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { fn } from '@storybook/test';
3
+ import { WelcomeAgentSetup } from './welcome-agent-setup.js';
4
+ const meta = {
5
+ title: 'Features/WelcomeAgentSetup',
6
+ component: WelcomeAgentSetup,
7
+ tags: ['autodocs'],
8
+ parameters: {
9
+ layout: 'centered',
10
+ },
11
+ decorators: [
12
+ (Story) => (_jsx("div", { style: { width: 480, padding: 48, display: 'flex', justifyContent: 'center' }, children: _jsx(Story, {}) })),
13
+ ],
14
+ };
15
+ export default meta;
16
+ export const Default = {
17
+ args: {
18
+ onComplete: fn(),
19
+ },
20
+ };
@@ -29,7 +29,7 @@ function AppShellInner({ children }) {
29
29
  const handleRepositorySelect = useCallback((path) => {
30
30
  window.dispatchEvent(new CustomEvent('shep:add-repository', { detail: { path } }));
31
31
  }, []);
32
- return (_jsxs(SidebarProvider, { children: [_jsx(AppSidebar, { features: features, featureFlags: featureFlags, onNewFeature: handleNewFeature, onFeatureClick: handleFeatureClick }), _jsx(SidebarInset, { children: _jsxs("div", { className: "relative h-full", children: [_jsxs("div", { className: "absolute top-3 right-3 z-50 flex gap-1", children: [_jsx(AddRepositoryButton, { onSelect: handleRepositorySelect }), _jsx(SoundToggle, {}), _jsx(ThemeToggle, {})] }), _jsx("main", { className: "h-full", children: children })] }) })] }));
32
+ return (_jsxs(SidebarProvider, { defaultOpen: false, children: [_jsx(AppSidebar, { features: features, featureFlags: featureFlags, onNewFeature: handleNewFeature, onFeatureClick: handleFeatureClick }), _jsx(SidebarInset, { children: _jsxs("div", { className: "relative h-full", children: [_jsxs("div", { className: "absolute top-3 right-3 z-50 flex gap-1", children: [_jsx(AddRepositoryButton, { onSelect: handleRepositorySelect }), _jsx(SoundToggle, {}), _jsx(ThemeToggle, {})] }), _jsx("main", { className: "h-full", children: children })] }) })] }));
33
33
  }
34
34
  export function AppShell({ children }) {
35
35
  return (_jsx(AgentEventsProvider, { children: _jsx(DrawerCloseGuardProvider, { children: _jsx(SidebarFeaturesProvider, { children: _jsx(AppShellInner, { children: children }) }) }) }));
@@ -11,7 +11,7 @@ export interface SidebarFeatureItem {
11
11
  modelId?: string;
12
12
  }
13
13
  /**
14
- * Maps a canvas FeatureNodeState to the sidebar's 3-state FeatureStatus.
14
+ * Maps a canvas FeatureNodeState to the sidebar's 5-state FeatureStatus.
15
15
  * Returns `null` for `creating` (optimistic UI) — these should be excluded from the sidebar.
16
16
  */
17
17
  export declare function mapNodeStateToSidebarStatus(state: FeatureNodeState): FeatureStatus | null;
@@ -2,18 +2,18 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { createContext, useContext, useState, useMemo } from 'react';
4
4
  // ---------------------------------------------------------------------------
5
- // Pure mapping: FeatureNodeState (6-state) → FeatureStatus (3-state) | null
5
+ // Pure mapping: FeatureNodeState (6-state) → FeatureStatus (5-state) | null
6
6
  // ---------------------------------------------------------------------------
7
7
  const stateMapping = {
8
8
  'action-required': 'action-needed',
9
9
  running: 'in-progress',
10
10
  done: 'done',
11
- blocked: 'in-progress',
12
- error: 'in-progress',
11
+ blocked: 'blocked',
12
+ error: 'error',
13
13
  creating: null,
14
14
  };
15
15
  /**
16
- * Maps a canvas FeatureNodeState to the sidebar's 3-state FeatureStatus.
16
+ * Maps a canvas FeatureNodeState to the sidebar's 5-state FeatureStatus.
17
17
  * Returns `null` for `creating` (optimistic UI) — these should be excluded from the sidebar.
18
18
  */
19
19
  export function mapNodeStateToSidebarStatus(state) {
@@ -1 +1 @@
1
- {"version":3,"file":"layout-with-dagre.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/layout-with-dagre.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,EAAE,aAIpC,CAAC;AAkCF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,IAAI,EAC5C,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,GAAE,aAAkB,GACvB;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAoK/B"}
1
+ {"version":3,"file":"layout-with-dagre.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/layout-with-dagre.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,EAAE,aAIpC,CAAC;AAkCF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,IAAI,EAC5C,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,GAAE,aAAkB,GACvB;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAyL/B"}