@shepai/cli 1.92.1-pr278.546c1d4 → 1.92.1-pr278.cb26d31
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/src/presentation/web/components/features/control-center/control-center-empty-state.js +3 -3
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.js +82 -48
- 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 +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +19 -19
- 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 +24 -24
- 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 +24 -24
- 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 +17 -17
- 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 +19 -19
- 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 +24 -24
- 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 +24 -24
- 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 +17 -17
- 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 +17 -17
- 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/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_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_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/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_002ab1c0.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_002ab1c0.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_1bab40be.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_1bab40be.js.map +1 -1
- 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]__22751bba._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__22751bba._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__31fc8960._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__31fc8960._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +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]__89e8a5cc._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9497d008._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9497d008._.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]__e630cc47._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e630cc47._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fb487740._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fb487740._.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/_0a272b7a._.js +3 -0
- package/web/.next/server/chunks/ssr/{_8dfa5290._.js.map → _0a272b7a._.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/{_7dac1c7f._.js → _1604fa6d._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_7dac1c7f._.js.map → _1604fa6d._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_0d3964ca._.js → _7d9404a8._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_0d3964ca._.js.map → _7d9404a8._.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_3a8fc63d._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_3a8fc63d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1695630c.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1695630c.js.map +1 -1
- 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_de814675._.js +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_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_f16e6874._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_f16e6874._.js.map +1 -1
- 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 +29 -29
- package/web/.next/static/chunks/{a1008ec2a7af77ce.js → 273d795eddf51be5.js} +1 -1
- package/web/.next/static/chunks/{8925d8a2e9bc3cb0.js → 3e841efeff702339.js} +1 -1
- package/web/.next/static/chunks/{137b4e745802b672.js → 724e8e33f83131c5.js} +2 -2
- package/web/.next/static/chunks/{3872f739442d2f9d.js → 78d41afd01b9bb05.js} +1 -1
- package/web/.next/static/chunks/{b6a5b8dc5b9651b2.js → 83cad139457ef0ed.js} +1 -1
- package/web/.next/static/chunks/{3fd14ab34d58631e.js → 89c8eee25e97720e.js} +1 -1
- package/web/.next/static/chunks/{f4e414fd51a7640b.js → 8dc7694d27eebce6.js} +1 -1
- package/web/.next/static/chunks/{963c8c19873104c6.js → 907d8bdaddcb30db.js} +1 -1
- package/web/.next/static/chunks/{69b188357d9bba01.js → a900defe44e3df43.js} +1 -1
- package/web/.next/static/chunks/{f97c89177e996e7f.js → c9463acac16ef5ae.js} +1 -1
- package/web/.next/static/chunks/d10c356ebeeca835.css +2 -0
- package/web/.next/static/chunks/{fc2befcfcd1a5b72.js → fcd1a04ebb2c0a0c.js} +1 -1
- package/web/.next/server/chunks/ssr/_8dfa5290._.js +0 -3
- package/web/.next/static/chunks/e92dd6b099ceebdc.css +0 -2
- /package/web/.next/static/{oEas8MDXQGNfKej8Xjoyv → Z51AuTPohPDN8HTYggKCN}/_buildManifest.js +0 -0
- /package/web/.next/static/{oEas8MDXQGNfKej8Xjoyv → Z51AuTPohPDN8HTYggKCN}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{oEas8MDXQGNfKej8Xjoyv → Z51AuTPohPDN8HTYggKCN}/_ssgManifest.js +0 -0
package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js
CHANGED
|
@@ -5,7 +5,7 @@ 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 { WelcomeAgentSetup } from './welcome-agent-setup.js';
|
|
8
|
-
const commands = ['cd ~/my-repo', 'shep feat new "
|
|
8
|
+
const commands = ['cd ~/my-repo', 'shep feat new "sleek dashboard"'];
|
|
9
9
|
export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
10
10
|
const [copied, setCopied] = useState(false);
|
|
11
11
|
const [loading, setLoading] = useState(false);
|
|
@@ -32,9 +32,9 @@ export function ControlCenterEmptyState({ onRepositorySelect, className, }) {
|
|
|
32
32
|
const handleAgentSetupComplete = useCallback(() => {
|
|
33
33
|
setAgentReady(true);
|
|
34
34
|
}, []);
|
|
35
|
-
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
|
|
35
|
+
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 ? (
|
|
36
36
|
/* Step 1: Agent setup */
|
|
37
37
|
_jsx(WelcomeAgentSetup, { onComplete: handleAgentSetupComplete })) : (
|
|
38
38
|
/* Step 2: Add repository (shown after agent is configured) */
|
|
39
|
-
_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-muted-foreground flex items-center gap-2", children: [_jsx(Github, { className: "h-
|
|
39
|
+
_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" })] })) }) })] }));
|
|
40
40
|
}
|
package/dist/src/presentation/web/components/features/control-center/welcome-agent-setup.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
4
4
|
import { Check, ChevronRight, ChevronLeft, Download, Loader2, CheckCircle2, Circle, AlertCircle, Bot, } from 'lucide-react';
|
|
5
5
|
import { getAllAgentModels } from '../../../app/actions/get-all-agent-models.js';
|
|
6
6
|
import { checkAgentTool } from '../../../app/actions/check-agent-tool.js';
|
|
@@ -9,6 +9,9 @@ import { getAgentTypeIcon } from '../../common/feature-node/agent-type-icons.js'
|
|
|
9
9
|
import { getModelMeta } from '../../../lib/model-metadata.js';
|
|
10
10
|
import { useToolInstallStream } from '../../../hooks/use-tool-install-stream.js';
|
|
11
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';
|
|
12
15
|
export function WelcomeAgentSetup({ onComplete, className }) {
|
|
13
16
|
const [groups, setGroups] = useState([]);
|
|
14
17
|
const [loading, setLoading] = useState(true);
|
|
@@ -18,46 +21,75 @@ export function WelcomeAgentSetup({ onComplete, className }) {
|
|
|
18
21
|
const [toolStatus, setToolStatus] = useState(null);
|
|
19
22
|
const [checkingTool, setCheckingTool] = useState(false);
|
|
20
23
|
const [saving, setSaving] = useState(false);
|
|
21
|
-
|
|
24
|
+
const [transitioning, setTransitioning] = useState(false);
|
|
25
|
+
const [visible, setVisible] = useState(true);
|
|
26
|
+
const timeoutRef = useRef(undefined);
|
|
22
27
|
useEffect(() => {
|
|
23
28
|
getAllAgentModels()
|
|
24
29
|
.then(setGroups)
|
|
25
30
|
.finally(() => setLoading(false));
|
|
26
31
|
}, []);
|
|
27
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
|
+
}, []);
|
|
28
55
|
const handleAgentSelect = useCallback((agentType) => {
|
|
29
56
|
const group = groups.find((g) => g.agentType === agentType);
|
|
30
|
-
setSelectedAgent(agentType);
|
|
31
57
|
if (group && group.models.length > 0) {
|
|
32
|
-
|
|
58
|
+
transitionTo('select-model', () => {
|
|
59
|
+
setSelectedAgent(agentType);
|
|
60
|
+
});
|
|
33
61
|
}
|
|
34
62
|
else {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
63
|
+
transitionTo('check-tool', () => {
|
|
64
|
+
setSelectedAgent(agentType);
|
|
65
|
+
setSelectedModel('');
|
|
66
|
+
});
|
|
38
67
|
}
|
|
39
|
-
}, [groups]);
|
|
68
|
+
}, [groups, transitionTo]);
|
|
40
69
|
const handleModelSelect = useCallback((model) => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
70
|
+
transitionTo('check-tool', () => {
|
|
71
|
+
setSelectedModel(model);
|
|
72
|
+
});
|
|
73
|
+
}, [transitionTo]);
|
|
44
74
|
const handleBack = useCallback(() => {
|
|
45
75
|
if (step === 'select-model') {
|
|
46
|
-
|
|
47
|
-
|
|
76
|
+
transitionTo('select-agent', () => {
|
|
77
|
+
setSelectedAgent(null);
|
|
78
|
+
});
|
|
48
79
|
}
|
|
49
80
|
else if (step === 'check-tool') {
|
|
50
81
|
if (activeGroup && activeGroup.models.length > 0) {
|
|
51
|
-
|
|
52
|
-
|
|
82
|
+
transitionTo('select-model', () => {
|
|
83
|
+
setSelectedModel(null);
|
|
84
|
+
});
|
|
53
85
|
}
|
|
54
86
|
else {
|
|
55
|
-
|
|
56
|
-
|
|
87
|
+
transitionTo('select-agent', () => {
|
|
88
|
+
setSelectedAgent(null);
|
|
89
|
+
});
|
|
57
90
|
}
|
|
58
91
|
}
|
|
59
|
-
}, [step, activeGroup]);
|
|
60
|
-
// Check tool status when entering check-tool step
|
|
92
|
+
}, [step, activeGroup, transitionTo]);
|
|
61
93
|
useEffect(() => {
|
|
62
94
|
if (step !== 'check-tool' || !selectedAgent)
|
|
63
95
|
return;
|
|
@@ -79,41 +111,47 @@ export function WelcomeAgentSetup({ onComplete, className }) {
|
|
|
79
111
|
}
|
|
80
112
|
}, [selectedAgent, selectedModel, onComplete]);
|
|
81
113
|
if (loading) {
|
|
82
|
-
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-
|
|
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" })] }));
|
|
83
115
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
+
} }))] })] }));
|
|
101
136
|
}
|
|
102
137
|
/** Sub-component for the tool verification step */
|
|
103
138
|
function ToolCheckStep({ toolStatus, checking, saving, onConfirm, onBack, onToolInstalled, }) {
|
|
104
139
|
if (checking || !toolStatus) {
|
|
105
|
-
return (_jsxs("div", { className: "flex flex-col items-center gap-
|
|
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" })] }));
|
|
106
141
|
}
|
|
107
142
|
// Agent doesn't require a tool (e.g., dev/demo)
|
|
108
143
|
if (!toolStatus.toolId) {
|
|
109
|
-
return (_jsxs("div", { className: "flex flex-col items-center gap-
|
|
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 })] }));
|
|
110
145
|
}
|
|
111
146
|
if (toolStatus.installed) {
|
|
112
|
-
return (_jsxs("div", { className: "flex flex-col items-center gap-
|
|
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 })] }));
|
|
113
148
|
}
|
|
114
|
-
// Tool not installed — show install option
|
|
115
149
|
return (_jsx(ToolInstallInline, { toolStatus: toolStatus, saving: saving, onConfirm: onConfirm, onBack: onBack, onInstalled: onToolInstalled }));
|
|
116
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
|
+
}
|
|
117
155
|
/** Inline tool installer for the welcome wizard */
|
|
118
156
|
function ToolInstallInline({ toolStatus, saving, onConfirm, onBack, onInstalled, }) {
|
|
119
157
|
const toolId = toolStatus.toolId ?? '';
|
|
@@ -125,11 +163,7 @@ function ToolInstallInline({ toolStatus, saving, onConfirm, onBack, onInstalled,
|
|
|
125
163
|
onInstalled();
|
|
126
164
|
}
|
|
127
165
|
}, [isInstallDone, onInstalled]);
|
|
128
|
-
return (_jsxs("div", { className: "flex flex-col items-center gap-
|
|
129
|
-
? 'installed successfully'
|
|
130
|
-
: isInstallError
|
|
131
|
-
? 'installation failed'
|
|
132
|
-
: 'is not installed'] })] }), toolStatus.tool?.installCommand && status === 'idle' ? (_jsxs("div", { className: "w-full rounded-lg bg-zinc-900 px-5 py-4 font-mono text-sm text-zinc-100", 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-32 w-full overflow-auto rounded-lg bg-zinc-900 px-5 py-4 font-mono text-[11px] leading-relaxed text-zinc-300", children: [logs.map((line, idx) => (
|
|
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) => (
|
|
133
167
|
// eslint-disable-next-line react/no-array-index-key -- logs are append-only, never reorder
|
|
134
|
-
_jsx("div", { className: "break-all whitespace-pre-wrap", children: line }, idx))), isInstallDone ? (_jsx("div", { className: "mt-1
|
|
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] })] }));
|
|
135
169
|
}
|