@shepai/cli 1.95.0 → 1.96.0
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.
- package/dist/packages/core/src/application/use-cases/settings/complete-web-onboarding.use-case.d.ts +19 -0
- package/dist/packages/core/src/application/use-cases/settings/complete-web-onboarding.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/settings/complete-web-onboarding.use-case.js +52 -0
- package/dist/packages/core/src/application/use-cases/settings/index.d.ts +2 -0
- package/dist/packages/core/src/application/use-cases/settings/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/settings/index.js +1 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +5 -0
- package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/new.command.js +9 -0
- package/dist/src/presentation/cli/index.js +0 -12
- package/dist/src/presentation/web/app/actions/agent-setup-flag.d.ts +6 -0
- package/dist/src/presentation/web/app/actions/agent-setup-flag.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/agent-setup-flag.js +14 -0
- package/dist/src/presentation/web/app/actions/check-agent-tool.d.ts +11 -0
- package/dist/src/presentation/web/app/actions/check-agent-tool.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/check-agent-tool.js +35 -0
- package/dist/src/presentation/web/app/actions/update-agent-and-model.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/update-agent-and-model.js +6 -12
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +20 -4
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts +6 -0
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.js +222 -0
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.stories.d.ts +7 -0
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.stories.js +20 -0
- package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +2 -2
- package/web/.next/required-server-files.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +92 -62
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +102 -42
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +102 -42
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +88 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +92 -62
- package/web/.next/server/app/(dashboard)/create/page.js +2 -2
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +102 -42
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +2 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +102 -42
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +2 -2
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +88 -28
- package/web/.next/server/app/(dashboard)/page.js +2 -2
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +88 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +2 -2
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_2b65878f._.js +3 -0
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_2b65878f._.js.map +1 -0
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_6ba7eb21._.js +3 -0
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_6ba7eb21._.js.map +1 -0
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_c757eb00.js +3 -0
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_c757eb00.js.map +1 -0
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_7eb49631.js +3 -0
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_7eb49631.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__17143953._.js → [root-of-the-server]__19fb0bfe._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__5cc4752a._.js.map → [root-of-the-server]__19fb0bfe._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__45aad79d._.js → [root-of-the-server]__3d6f6b0e._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__17143953._.js.map → [root-of-the-server]__3d6f6b0e._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__5cc4752a._.js → [root-of-the-server]__42020c54._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__9de266fa._.js.map → [root-of-the-server]__42020c54._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7b49fcb3._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7b49fcb3._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__9de266fa._.js → [root-of-the-server]__9cb60e1e._.js} +2 -2
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__45aad79d._.js.map → [root-of-the-server]__9cb60e1e._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_3533fed7._.js → _25804645._.js} +2 -2
- package/web/.next/server/chunks/ssr/_25804645._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_29706078._.js +3 -0
- package/web/.next/server/chunks/ssr/_29706078._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_5e112f82._.js +3 -0
- package/web/.next/server/chunks/ssr/_5e112f82._.js.map +1 -0
- package/web/.next/server/chunks/ssr/{_c2399eb5._.js → _89642645._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_c2399eb5._.js.map → _89642645._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_3c53a23d._.js +5 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_3c53a23d._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_befd865a.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_befd865a.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_3d0aa70c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ec8c7a4f._.js +5 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_ec8c7a4f._.js.map +1 -0
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +482 -242
- package/web/.next/static/chunks/{465f63a101981da8.js → 062edbb0027f7706.js} +1 -1
- package/web/.next/static/chunks/16f95844a435acec.js +1 -0
- package/web/.next/static/chunks/{3c68b85c9dd7f200.js → 2a7239eb16bfe1c6.js} +1 -1
- package/web/.next/static/chunks/441c4c4fac0587bc.js +1 -0
- package/web/.next/static/chunks/447660fbaba174d4.js +1 -0
- package/web/.next/static/chunks/71d785d1de4b86f6.css +1 -0
- package/web/.next/static/chunks/{98767389c1aad0b2.js → 7ae799537de2a498.js} +1 -1
- package/web/.next/static/chunks/896bf4b2aed373c1.js +1 -0
- package/web/.next/static/chunks/{c4bbbfcfc008cba4.js → 8a2dfd7720cc95d2.js} +1 -1
- package/web/.next/static/chunks/{59b988d41943386c.js → 8bae17e4a4833517.js} +1 -1
- package/web/.next/static/chunks/8bd300e88a189928.js +1 -0
- package/web/.next/static/chunks/b272ac93b52dceeb.js +1 -0
- package/web/.next/static/chunks/d4a066dfc6f5dab7.js +1 -0
- package/web/.next/static/chunks/{f0bbc2f086d7d996.js → f47c30133739a043.js} +2 -2
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_81a06555._.js +0 -3
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_81a06555._.js.map +0 -1
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js +0 -3
- package/web/.next/server/chunks/ssr/7f428_lucide-react_dist_esm_icons_rocket_1575cd4d.js.map +0 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +0 -3
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js.map +0 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +0 -3
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4be9a9bb._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4be9a9bb._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9dc40036._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9dc40036._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_3533fed7._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_364346ad._.js +0 -3
- package/web/.next/server/chunks/ssr/_364346ad._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_df15bd24._.js +0 -3
- package/web/.next/server/chunks/ssr/_df15bd24._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_f50485a5._.js +0 -3
- package/web/.next/server/chunks/ssr/_f50485a5._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +0 -3
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js +0 -5
- package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js.map +0 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js +0 -5
- package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js.map +0 -1
- package/web/.next/static/chunks/2536dce61f55daad.js +0 -1
- package/web/.next/static/chunks/35b142afe3405da9.js +0 -1
- package/web/.next/static/chunks/42040482bd2ec9aa.js +0 -1
- package/web/.next/static/chunks/490407527f8234cb.js +0 -1
- package/web/.next/static/chunks/6d61b6eaca9f925a.js +0 -1
- package/web/.next/static/chunks/8ec10587d1c608a2.css +0 -1
- package/web/.next/static/chunks/d9247a52ae260218.js +0 -1
- package/web/.next/static/chunks/eb981f9e02a74f15.js +0 -1
- /package/web/.next/static/{AT8BmALAnMpq68TlqG9FY → EPem_w0RRU96dbLFoOYwF}/_buildManifest.js +0 -0
- /package/web/.next/static/{AT8BmALAnMpq68TlqG9FY → EPem_w0RRU96dbLFoOYwF}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{AT8BmALAnMpq68TlqG9FY → EPem_w0RRU96dbLFoOYwF}/_ssgManifest.js +0 -0
package/dist/packages/core/src/application/use-cases/settings/complete-web-onboarding.use-case.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complete Web Onboarding Use Case
|
|
3
|
+
*
|
|
4
|
+
* Lighter variant of CompleteOnboardingUseCase for the web UI wizard.
|
|
5
|
+
* Only updates agent type, model, and sets onboardingComplete=true.
|
|
6
|
+
* Other settings (IDE, workflow defaults) keep their current values.
|
|
7
|
+
*/
|
|
8
|
+
import type { Settings, AgentType } from '../../../domain/generated/output.js';
|
|
9
|
+
import type { ISettingsRepository } from '../../ports/output/repositories/settings.repository.interface.js';
|
|
10
|
+
export interface CompleteWebOnboardingInput {
|
|
11
|
+
agentType: AgentType;
|
|
12
|
+
model: string | null;
|
|
13
|
+
}
|
|
14
|
+
export declare class CompleteWebOnboardingUseCase {
|
|
15
|
+
private readonly settingsRepository;
|
|
16
|
+
constructor(settingsRepository: ISettingsRepository);
|
|
17
|
+
execute(input: CompleteWebOnboardingInput): Promise<Settings>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=complete-web-onboarding.use-case.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete-web-onboarding.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/settings/complete-web-onboarding.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAE5G,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,qBACa,4BAA4B;IAGrC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,mBAAmB;IAGpD,OAAO,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,QAAQ,CAAC;CAsBpE"}
|
package/dist/packages/core/src/application/use-cases/settings/complete-web-onboarding.use-case.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complete Web Onboarding Use Case
|
|
3
|
+
*
|
|
4
|
+
* Lighter variant of CompleteOnboardingUseCase for the web UI wizard.
|
|
5
|
+
* Only updates agent type, model, and sets onboardingComplete=true.
|
|
6
|
+
* Other settings (IDE, workflow defaults) keep their current values.
|
|
7
|
+
*/
|
|
8
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
9
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
10
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
11
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
12
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
13
|
+
};
|
|
14
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
16
|
+
};
|
|
17
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
18
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
19
|
+
};
|
|
20
|
+
import { injectable, inject } from 'tsyringe';
|
|
21
|
+
let CompleteWebOnboardingUseCase = class CompleteWebOnboardingUseCase {
|
|
22
|
+
settingsRepository;
|
|
23
|
+
constructor(settingsRepository) {
|
|
24
|
+
this.settingsRepository = settingsRepository;
|
|
25
|
+
}
|
|
26
|
+
async execute(input) {
|
|
27
|
+
const settings = await this.settingsRepository.load();
|
|
28
|
+
if (!settings) {
|
|
29
|
+
throw new Error('Settings not found. Please run initialization first.');
|
|
30
|
+
}
|
|
31
|
+
const updatedSettings = {
|
|
32
|
+
...settings,
|
|
33
|
+
agent: {
|
|
34
|
+
...settings.agent,
|
|
35
|
+
type: input.agentType,
|
|
36
|
+
},
|
|
37
|
+
models: {
|
|
38
|
+
default: input.model?.trim() ?? settings.models.default,
|
|
39
|
+
},
|
|
40
|
+
onboardingComplete: true,
|
|
41
|
+
updatedAt: new Date(),
|
|
42
|
+
};
|
|
43
|
+
await this.settingsRepository.update(updatedSettings);
|
|
44
|
+
return updatedSettings;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
CompleteWebOnboardingUseCase = __decorate([
|
|
48
|
+
injectable(),
|
|
49
|
+
__param(0, inject('ISettingsRepository')),
|
|
50
|
+
__metadata("design:paramtypes", [Object])
|
|
51
|
+
], CompleteWebOnboardingUseCase);
|
|
52
|
+
export { CompleteWebOnboardingUseCase };
|
|
@@ -9,4 +9,6 @@ export { UpdateSettingsUseCase } from './update-settings.use-case.js';
|
|
|
9
9
|
export { CheckOnboardingStatusUseCase } from './check-onboarding-status.use-case.js';
|
|
10
10
|
export { CompleteOnboardingUseCase } from './complete-onboarding.use-case.js';
|
|
11
11
|
export type { CompleteOnboardingInput } from './complete-onboarding.use-case.js';
|
|
12
|
+
export { CompleteWebOnboardingUseCase } from './complete-web-onboarding.use-case.js';
|
|
13
|
+
export type { CompleteWebOnboardingInput } from './complete-web-onboarding.use-case.js';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/settings/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,YAAY,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/settings/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,YAAY,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AACrF,YAAY,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC"}
|
|
@@ -8,3 +8,4 @@ export { LoadSettingsUseCase } from './load-settings.use-case.js';
|
|
|
8
8
|
export { UpdateSettingsUseCase } from './update-settings.use-case.js';
|
|
9
9
|
export { CheckOnboardingStatusUseCase } from './check-onboarding-status.use-case.js';
|
|
10
10
|
export { CompleteOnboardingUseCase } from './complete-onboarding.use-case.js';
|
|
11
|
+
export { CompleteWebOnboardingUseCase } from './complete-web-onboarding.use-case.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/src/infrastructure/di/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAiHrC;;;;;;GAMG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,SAAS,CAAC,CA0SrE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -45,6 +45,7 @@ import { InitializeSettingsUseCase } from '../../application/use-cases/settings/
|
|
|
45
45
|
import { LoadSettingsUseCase } from '../../application/use-cases/settings/load-settings.use-case.js';
|
|
46
46
|
import { UpdateSettingsUseCase } from '../../application/use-cases/settings/update-settings.use-case.js';
|
|
47
47
|
import { CompleteOnboardingUseCase } from '../../application/use-cases/settings/complete-onboarding.use-case.js';
|
|
48
|
+
import { CompleteWebOnboardingUseCase } from '../../application/use-cases/settings/complete-web-onboarding.use-case.js';
|
|
48
49
|
import { ConfigureAgentUseCase } from '../../application/use-cases/agents/configure-agent.use-case.js';
|
|
49
50
|
import { ValidateAgentAuthUseCase } from '../../application/use-cases/agents/validate-agent-auth.use-case.js';
|
|
50
51
|
import { RunAgentUseCase } from '../../application/use-cases/agents/run-agent.use-case.js';
|
|
@@ -244,6 +245,7 @@ export async function initializeContainer() {
|
|
|
244
245
|
container.registerSingleton(LoadSettingsUseCase);
|
|
245
246
|
container.registerSingleton(UpdateSettingsUseCase);
|
|
246
247
|
container.registerSingleton(CompleteOnboardingUseCase);
|
|
248
|
+
container.registerSingleton(CompleteWebOnboardingUseCase);
|
|
247
249
|
container.registerSingleton(ConfigureAgentUseCase);
|
|
248
250
|
container.registerSingleton(ValidateAgentAuthUseCase);
|
|
249
251
|
container.registerSingleton(RunAgentUseCase);
|
|
@@ -352,6 +354,9 @@ export async function initializeContainer() {
|
|
|
352
354
|
container.register('UpdateSettingsUseCase', {
|
|
353
355
|
useFactory: (c) => c.resolve(UpdateSettingsUseCase),
|
|
354
356
|
});
|
|
357
|
+
container.register('CompleteWebOnboardingUseCase', {
|
|
358
|
+
useFactory: (c) => c.resolve(CompleteWebOnboardingUseCase),
|
|
359
|
+
});
|
|
355
360
|
container.register('CleanupFeatureWorktreeUseCase', {
|
|
356
361
|
useFactory: (c) => c.resolve(CleanupFeatureWorktreeUseCase),
|
|
357
362
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"new.command.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/cli/commands/feat/new.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4DpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAwI1C"}
|
|
@@ -19,6 +19,8 @@ import { SdlcLifecycle } from '../../../../../packages/core/src/domain/generated
|
|
|
19
19
|
import { colors, messages, spinner } from '../../ui/index.js';
|
|
20
20
|
import { getShepHomeDir } from '../../../../../packages/core/src/infrastructure/services/filesystem/shep-directory.service.js';
|
|
21
21
|
import { getSettings, hasSettings } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
|
|
22
|
+
import { CheckOnboardingStatusUseCase } from '../../../../../packages/core/src/application/use-cases/settings/check-onboarding-status.use-case.js';
|
|
23
|
+
import { onboardingWizard } from '../../../tui/wizards/onboarding/onboarding.wizard.js';
|
|
22
24
|
/** Commander collect pattern for repeatable options. */
|
|
23
25
|
function collect(value, previous) {
|
|
24
26
|
return [...previous, value];
|
|
@@ -58,6 +60,13 @@ export function createNewCommand() {
|
|
|
58
60
|
.option('--attach <path>', 'Attach a file (repeatable)', collect, [])
|
|
59
61
|
.action(async (description, options) => {
|
|
60
62
|
try {
|
|
63
|
+
// First-run onboarding gate — only for interactive terminals
|
|
64
|
+
if (process.stdin.isTTY) {
|
|
65
|
+
const { isComplete } = await new CheckOnboardingStatusUseCase().execute();
|
|
66
|
+
if (!isComplete) {
|
|
67
|
+
await onboardingWizard();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
61
70
|
const useCase = container.resolve(CreateFeatureUseCase);
|
|
62
71
|
const repoPath = options.repo ?? process.cwd();
|
|
63
72
|
// Resolve openPr from CLI flags or settings defaults
|
|
@@ -54,7 +54,6 @@ import { startDaemon } from './commands/daemon/start-daemon.js';
|
|
|
54
54
|
import { initializeContainer, container } from '../../../packages/core/src/infrastructure/di/container.js';
|
|
55
55
|
import { InitializeSettingsUseCase } from '../../../packages/core/src/application/use-cases/settings/initialize-settings.use-case.js';
|
|
56
56
|
import { initializeSettings } from '../../../packages/core/src/infrastructure/services/settings.service.js';
|
|
57
|
-
import { CheckOnboardingStatusUseCase } from '../../../packages/core/src/application/use-cases/settings/check-onboarding-status.use-case.js';
|
|
58
57
|
/**
|
|
59
58
|
* Bootstrap function - initializes all dependencies before CLI starts.
|
|
60
59
|
* Performs async initialization (database, settings) before parsing commands.
|
|
@@ -83,17 +82,6 @@ async function bootstrap() {
|
|
|
83
82
|
messages.error('Failed to initialize settings', err);
|
|
84
83
|
throw error;
|
|
85
84
|
}
|
|
86
|
-
// Step 2.5: First-run onboarding gate
|
|
87
|
-
// Only run in interactive terminals (the wizard needs TTY for prompts)
|
|
88
|
-
if (process.stdin.isTTY) {
|
|
89
|
-
const onboardingCheck = new CheckOnboardingStatusUseCase();
|
|
90
|
-
const { isComplete } = await onboardingCheck.execute();
|
|
91
|
-
if (!isComplete) {
|
|
92
|
-
// Lazy-import to avoid ~460ms startup cost when onboarding is already complete
|
|
93
|
-
const { onboardingWizard } = await import('../tui/wizards/onboarding/onboarding.wizard.js');
|
|
94
|
-
await onboardingWizard();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
85
|
// Step 3: Set up Commander CLI
|
|
98
86
|
const versionService = container.resolve('IVersionService');
|
|
99
87
|
const { version, description } = versionService.getVersion();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-setup-flag.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/agent-setup-flag.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAM7D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { getSettings } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
|
|
3
|
+
/**
|
|
4
|
+
* Check whether onboarding has been completed.
|
|
5
|
+
* Delegates to the in-memory settings singleton (zero DB overhead).
|
|
6
|
+
*/
|
|
7
|
+
export async function isAgentSetupComplete() {
|
|
8
|
+
try {
|
|
9
|
+
return getSettings().onboardingComplete;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
/** CLI binary name for manual run instructions (e.g. "claude", "gemini") */
|
|
8
|
+
binaryName: string | null;
|
|
9
|
+
}
|
|
10
|
+
export declare function checkAgentTool(agentType: string): Promise<AgentToolStatus>;
|
|
11
|
+
//# 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;AAmB7F,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;IACnB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAmBhF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
/** CLI binary names matching the `binary` field in each tool JSON */
|
|
13
|
+
const AGENT_BINARY_MAP = {
|
|
14
|
+
'claude-code': 'claude',
|
|
15
|
+
cursor: 'cursor',
|
|
16
|
+
'gemini-cli': 'gemini',
|
|
17
|
+
};
|
|
18
|
+
export async function checkAgentTool(agentType) {
|
|
19
|
+
const toolId = AGENT_TOOL_MAP[agentType] ?? null;
|
|
20
|
+
const binaryName = AGENT_BINARY_MAP[agentType] ?? null;
|
|
21
|
+
// Dev agent and unknown agents don't need a tool
|
|
22
|
+
if (!toolId) {
|
|
23
|
+
return { agentType, toolId: null, tool: null, installed: true, binaryName: null };
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const useCase = resolve('ListToolsUseCase');
|
|
27
|
+
const tools = await useCase.execute();
|
|
28
|
+
const tool = tools.find((t) => t.id === toolId) ?? null;
|
|
29
|
+
const installed = tool?.status.status === 'available';
|
|
30
|
+
return { agentType, toolId, tool, installed, binaryName };
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return { agentType, toolId, tool: null, installed: false, binaryName };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-agent-and-model.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/update-agent-and-model.ts"],"names":[],"mappings":"AAUA,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"update-agent-and-model.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/update-agent-and-model.ts"],"names":[],"mappings":"AAUA,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoB1C"}
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
'use server';
|
|
2
2
|
import { resolve } from '../../lib/server-container.js';
|
|
3
|
-
import {
|
|
3
|
+
import { resetSettings, initializeSettings, } from '../../../../../packages/core/src/infrastructure/services/settings.service.js';
|
|
4
4
|
export async function updateAgentAndModel(agentType, model) {
|
|
5
5
|
if (!agentType.trim()) {
|
|
6
6
|
return { ok: false, error: 'agent type is required' };
|
|
7
7
|
}
|
|
8
8
|
try {
|
|
9
|
-
const
|
|
10
|
-
const updatedSettings = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type: agentType.trim(),
|
|
15
|
-
},
|
|
16
|
-
models: { default: model?.trim() ?? currentSettings.models.default },
|
|
17
|
-
};
|
|
18
|
-
const updateUseCase = resolve('UpdateSettingsUseCase');
|
|
19
|
-
await updateUseCase.execute(updatedSettings);
|
|
9
|
+
const useCase = resolve('CompleteWebOnboardingUseCase');
|
|
10
|
+
const updatedSettings = await useCase.execute({
|
|
11
|
+
agentType: agentType.trim(),
|
|
12
|
+
model,
|
|
13
|
+
});
|
|
20
14
|
resetSettings();
|
|
21
15
|
initializeSettings(updatedSettings);
|
|
22
16
|
return { ok: true };
|
|
@@ -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":"
|
|
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":"AASA,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,2CAiI9B"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useCallback } from 'react';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback, useEffect } 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
|
-
|
|
7
|
+
import { isAgentSetupComplete } from '../../../app/actions/agent-setup-flag.js';
|
|
8
|
+
import { WelcomeAgentSetup } from './welcome-agent-setup.js';
|
|
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(false);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
isAgentSetupComplete().then((done) => {
|
|
16
|
+
if (done)
|
|
17
|
+
setAgentReady(true);
|
|
18
|
+
});
|
|
19
|
+
}, []);
|
|
11
20
|
async function handlePickerClick() {
|
|
12
21
|
if (loading)
|
|
13
22
|
return;
|
|
@@ -27,5 +36,12 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
27
36
|
setCopied(true);
|
|
28
37
|
setTimeout(() => setCopied(false), 2000);
|
|
29
38
|
}, []);
|
|
30
|
-
|
|
39
|
+
const handleAgentSetupComplete = useCallback(() => {
|
|
40
|
+
setAgentReady(true);
|
|
41
|
+
}, []);
|
|
42
|
+
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 ? (
|
|
43
|
+
/* Step 1: Agent setup */
|
|
44
|
+
_jsx(WelcomeAgentSetup, { onComplete: handleAgentSetupComplete })) : (
|
|
45
|
+
/* Step 2: Add repository (shown after agent is configured) */
|
|
46
|
+
_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
47
|
}
|
|
@@ -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
|
package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map
ADDED
|
@@ -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":"AA0BA,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,2CAoTlF"}
|
|
@@ -0,0 +1,222 @@
|
|
|
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, Terminal, ExternalLink, } 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', 'authenticate'];
|
|
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 handleProceedToAuth = useCallback(() => {
|
|
75
|
+
transitionTo('authenticate');
|
|
76
|
+
}, [transitionTo]);
|
|
77
|
+
const handleBack = useCallback(() => {
|
|
78
|
+
if (step === 'select-model') {
|
|
79
|
+
transitionTo('select-agent', () => {
|
|
80
|
+
setSelectedAgent(null);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else if (step === 'check-tool') {
|
|
84
|
+
if (activeGroup && activeGroup.models.length > 0) {
|
|
85
|
+
transitionTo('select-model', () => {
|
|
86
|
+
setSelectedModel(null);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
transitionTo('select-agent', () => {
|
|
91
|
+
setSelectedAgent(null);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (step === 'authenticate') {
|
|
96
|
+
// If tool needed install, go back to check-tool; otherwise skip to model/agent
|
|
97
|
+
if (toolStatus && !toolStatus.installed && toolStatus.toolId) {
|
|
98
|
+
transitionTo('check-tool');
|
|
99
|
+
}
|
|
100
|
+
else if (activeGroup && activeGroup.models.length > 0) {
|
|
101
|
+
transitionTo('select-model', () => {
|
|
102
|
+
setSelectedModel(null);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
transitionTo('select-agent', () => {
|
|
107
|
+
setSelectedAgent(null);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}, [step, activeGroup, toolStatus, transitionTo]);
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (step !== 'check-tool' || !selectedAgent)
|
|
114
|
+
return;
|
|
115
|
+
setCheckingTool(true);
|
|
116
|
+
checkAgentTool(selectedAgent)
|
|
117
|
+
.then((status) => {
|
|
118
|
+
setToolStatus(status);
|
|
119
|
+
// Auto-skip to authenticate when tool is already available or not required
|
|
120
|
+
if (status.installed || !status.toolId) {
|
|
121
|
+
transitionTo('authenticate');
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
.finally(() => setCheckingTool(false));
|
|
125
|
+
}, [step, selectedAgent, transitionTo]);
|
|
126
|
+
const handleConfirm = useCallback(async () => {
|
|
127
|
+
if (!selectedAgent)
|
|
128
|
+
return;
|
|
129
|
+
setSaving(true);
|
|
130
|
+
try {
|
|
131
|
+
await updateAgentAndModel(selectedAgent, selectedModel ?? null);
|
|
132
|
+
onComplete();
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
setSaving(false);
|
|
136
|
+
}
|
|
137
|
+
}, [selectedAgent, selectedModel, onComplete]);
|
|
138
|
+
if (loading) {
|
|
139
|
+
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" })] }));
|
|
140
|
+
}
|
|
141
|
+
const stepIndex = STEPS.indexOf(step);
|
|
142
|
+
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
|
|
143
|
+
? (() => {
|
|
144
|
+
const AgentIcon = getAgentTypeIcon(activeGroup.agentType);
|
|
145
|
+
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"] })] }));
|
|
146
|
+
})()
|
|
147
|
+
: 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" })] })), step === 'authenticate' && activeGroup
|
|
148
|
+
? (() => {
|
|
149
|
+
const AgentIcon = getAgentTypeIcon(activeGroup.agentType);
|
|
150
|
+
return (_jsxs(_Fragment, { children: [_jsx(AgentIcon, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "text-[10px] font-semibold tracking-widest uppercase", children: "Authenticate" })] }));
|
|
151
|
+
})()
|
|
152
|
+
: null] }) }), _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) => {
|
|
153
|
+
const GroupIcon = getAgentTypeIcon(group.agentType);
|
|
154
|
+
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));
|
|
155
|
+
}) })), 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) => {
|
|
156
|
+
const meta = getModelMeta(m.id);
|
|
157
|
+
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));
|
|
158
|
+
}) })] })) : null, step === 'check-tool' && (_jsx(ToolCheckStep, { toolStatus: toolStatus, checking: checkingTool, saving: false, onConfirm: handleProceedToAuth, onBack: handleBack, onToolInstalled: () => {
|
|
159
|
+
if (selectedAgent) {
|
|
160
|
+
setCheckingTool(true);
|
|
161
|
+
checkAgentTool(selectedAgent)
|
|
162
|
+
.then(setToolStatus)
|
|
163
|
+
.finally(() => setCheckingTool(false));
|
|
164
|
+
}
|
|
165
|
+
} })), step === 'authenticate' && toolStatus ? (_jsx(AuthenticateStep, { toolStatus: toolStatus, agentLabel: activeGroup?.label ?? selectedAgent ?? 'Agent', saving: saving, onConfirm: handleConfirm, onBack: handleBack })) : null] })] }));
|
|
166
|
+
}
|
|
167
|
+
/** Sub-component for the tool verification step */
|
|
168
|
+
function ToolCheckStep({ toolStatus, checking, saving, onConfirm, onBack, onToolInstalled, }) {
|
|
169
|
+
if (checking || !toolStatus) {
|
|
170
|
+
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" })] }));
|
|
171
|
+
}
|
|
172
|
+
// Agent doesn't require a tool (e.g., dev/demo)
|
|
173
|
+
if (!toolStatus.toolId) {
|
|
174
|
+
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 })] }));
|
|
175
|
+
}
|
|
176
|
+
if (toolStatus.installed) {
|
|
177
|
+
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 })] }));
|
|
178
|
+
}
|
|
179
|
+
return (_jsx(ToolInstallInline, { toolStatus: toolStatus, saving: saving, onConfirm: onConfirm, onBack: onBack, onInstalled: onToolInstalled }));
|
|
180
|
+
}
|
|
181
|
+
/** Shared back + continue row */
|
|
182
|
+
function ConfirmRow({ saving, onConfirm, onBack, label = 'Continue', }) {
|
|
183
|
+
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" }), label] })] }));
|
|
184
|
+
}
|
|
185
|
+
/** Authenticate step — optional agent launch for auth */
|
|
186
|
+
function AuthenticateStep({ toolStatus, agentLabel, saving, onConfirm, onBack, }) {
|
|
187
|
+
const [launching, setLaunching] = useState(false);
|
|
188
|
+
const [launched, setLaunched] = useState(false);
|
|
189
|
+
const handleLaunch = useCallback(async () => {
|
|
190
|
+
if (!toolStatus.toolId)
|
|
191
|
+
return;
|
|
192
|
+
setLaunching(true);
|
|
193
|
+
try {
|
|
194
|
+
const res = await fetch(`/api/tools/${toolStatus.toolId}/launch`, { method: 'POST' });
|
|
195
|
+
if (res.ok)
|
|
196
|
+
setLaunched(true);
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
setLaunching(false);
|
|
200
|
+
}
|
|
201
|
+
}, [toolStatus.toolId]);
|
|
202
|
+
// No tool = no auth needed, skip straight to confirm
|
|
203
|
+
if (!toolStatus.toolId) {
|
|
204
|
+
return (_jsxs("div", { className: "flex w-full flex-col items-center gap-3", children: [_jsx("p", { className: "text-muted-foreground text-[10px]", children: "No authentication required" }), _jsx(ConfirmRow, { saving: saving, onConfirm: onConfirm, onBack: onBack, label: "Done" })] }));
|
|
205
|
+
}
|
|
206
|
+
return (_jsxs("div", { className: "flex w-full flex-col items-center gap-3", children: [_jsxs("p", { className: "text-muted-foreground text-center text-[10px] leading-relaxed", children: ["Open ", agentLabel, " in a terminal to sign in.", _jsx("br", {}), "Follow the prompts, then come back here."] }), _jsxs("button", { type: "button", "data-testid": "agent-setup-launch", disabled: launching, onClick: handleLaunch, 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:opacity-50", children: [launching ? (_jsx(Loader2, { className: "text-muted-foreground h-4 w-4 animate-spin" })) : (_jsx(Terminal, { className: "text-muted-foreground h-4 w-4" })), _jsx("span", { className: "flex-1 text-left text-xs font-medium", children: launched ? 'Open again' : `Open ${agentLabel}` }), _jsx(ExternalLink, { className: "text-muted-foreground h-3 w-3" })] }), launched ? (_jsx("p", { className: "text-muted-foreground text-[10px]", children: "Terminal opened \u2014 complete sign-in there" })) : null, toolStatus.binaryName ? (_jsxs("div", { className: "flex w-full flex-col gap-1", children: [_jsx("p", { className: "text-muted-foreground text-[10px]", children: "Or run manually in any terminal:" }), _jsxs("div", { className: "w-full rounded-md bg-zinc-900 px-3 py-1.5 font-mono text-[11px] text-zinc-300", children: [_jsx("span", { className: "text-zinc-500 select-none", children: "$ " }), toolStatus.binaryName] })] })) : 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"] }), _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" }), launched ? 'Done' : 'Skip'] })] })] }));
|
|
207
|
+
}
|
|
208
|
+
/** Inline tool installer for the welcome wizard */
|
|
209
|
+
function ToolInstallInline({ toolStatus, saving, onConfirm, onBack, onInstalled, }) {
|
|
210
|
+
const toolId = toolStatus.toolId ?? '';
|
|
211
|
+
const { logs, status, startInstall } = useToolInstallStream(toolId);
|
|
212
|
+
const isInstallDone = status === 'done';
|
|
213
|
+
const isInstallError = status === 'error';
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
if (isInstallDone) {
|
|
216
|
+
onInstalled();
|
|
217
|
+
}
|
|
218
|
+
}, [isInstallDone, onInstalled]);
|
|
219
|
+
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) => (
|
|
220
|
+
// eslint-disable-next-line react/no-array-index-key -- logs are append-only, never reorder
|
|
221
|
+
_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] })] }));
|
|
222
|
+
}
|
|
@@ -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
|