@ai-zen/cli 0.9.0 → 1.0.0-alpha.1
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/CHANGELOG.md +42 -1
- package/README.md +94 -40
- package/README.zh.md +94 -40
- package/dist/agent-creator.d.ts +7 -1
- package/dist/agent-creator.d.ts.map +1 -1
- package/dist/agent-creator.js +16 -1
- package/dist/agent-creator.js.map +1 -1
- package/dist/agents-store.d.ts +33 -0
- package/dist/agents-store.d.ts.map +1 -0
- package/dist/agents-store.js +50 -0
- package/dist/agents-store.js.map +1 -0
- package/dist/auto-migrate-confirm-plugin.d.ts +7 -7
- package/dist/auto-migrate-confirm-plugin.d.ts.map +1 -1
- package/dist/auto-migrate-confirm-plugin.js +3 -21
- package/dist/auto-migrate-confirm-plugin.js.map +1 -1
- package/dist/config-editor.d.ts +201 -0
- package/dist/config-editor.d.ts.map +1 -0
- package/dist/config-editor.js +511 -0
- package/dist/config-editor.js.map +1 -0
- package/dist/config.d.ts +41 -16
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +32 -29
- package/dist/config.js.map +1 -1
- package/dist/conversation-commands/registry.d.ts +4 -5
- package/dist/conversation-commands/registry.d.ts.map +1 -1
- package/dist/conversation-commands/registry.js +9 -6
- package/dist/conversation-commands/registry.js.map +1 -1
- package/dist/conversation-persist-plugin.d.ts +25 -0
- package/dist/conversation-persist-plugin.d.ts.map +1 -0
- package/dist/conversation-persist-plugin.js +44 -0
- package/dist/conversation-persist-plugin.js.map +1 -0
- package/dist/conversation-repository.d.ts +19 -2
- package/dist/conversation-repository.d.ts.map +1 -1
- package/dist/conversation-repository.js +48 -5
- package/dist/conversation-repository.js.map +1 -1
- package/dist/format-time.d.ts +2 -2
- package/dist/format-time.js +2 -2
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +58 -46
- package/dist/hook.js.map +1 -1
- package/dist/index.js +65 -36
- package/dist/index.js.map +1 -1
- package/dist/migration-service.d.ts +3 -1
- package/dist/migration-service.d.ts.map +1 -1
- package/dist/migration-service.js +26 -23
- package/dist/migration-service.js.map +1 -1
- package/dist/mode.d.ts +56 -0
- package/dist/mode.d.ts.map +1 -0
- package/dist/mode.js +83 -0
- package/dist/mode.js.map +1 -0
- package/dist/session-pointer.d.ts +22 -0
- package/dist/session-pointer.d.ts.map +1 -0
- package/dist/session-pointer.js +49 -0
- package/dist/session-pointer.js.map +1 -0
- package/dist/stdio-runner.d.ts +34 -0
- package/dist/stdio-runner.d.ts.map +1 -0
- package/dist/stdio-runner.js +161 -0
- package/dist/stdio-runner.js.map +1 -0
- package/dist/tui/chat-session.d.ts +100 -0
- package/dist/tui/chat-session.d.ts.map +1 -0
- package/dist/tui/chat-session.js +263 -0
- package/dist/tui/chat-session.js.map +1 -0
- package/dist/tui/components.d.ts +44 -0
- package/dist/tui/components.d.ts.map +1 -0
- package/dist/tui/components.js +62 -0
- package/dist/tui/components.js.map +1 -0
- package/dist/tui/config-wizard/detail.d.ts +51 -0
- package/dist/tui/config-wizard/detail.d.ts.map +1 -0
- package/dist/tui/config-wizard/detail.js +273 -0
- package/dist/tui/config-wizard/detail.js.map +1 -0
- package/dist/tui/config-wizard/engine.d.ts +36 -0
- package/dist/tui/config-wizard/engine.d.ts.map +1 -0
- package/dist/tui/config-wizard/engine.js +187 -0
- package/dist/tui/config-wizard/engine.js.map +1 -0
- package/dist/tui/config-wizard/fields.d.ts +24 -0
- package/dist/tui/config-wizard/fields.d.ts.map +1 -0
- package/dist/tui/config-wizard/fields.js +411 -0
- package/dist/tui/config-wizard/fields.js.map +1 -0
- package/dist/tui/config-wizard/frame.d.ts +27 -0
- package/dist/tui/config-wizard/frame.d.ts.map +1 -0
- package/dist/tui/config-wizard/frame.js +28 -0
- package/dist/tui/config-wizard/frame.js.map +1 -0
- package/dist/tui/config-wizard/index.d.ts +6 -0
- package/dist/tui/config-wizard/index.d.ts.map +1 -0
- package/dist/tui/config-wizard/index.js +7 -0
- package/dist/tui/config-wizard/index.js.map +1 -0
- package/dist/tui/config-wizard/kv-editor.d.ts +18 -0
- package/dist/tui/config-wizard/kv-editor.d.ts.map +1 -0
- package/dist/tui/config-wizard/kv-editor.js +116 -0
- package/dist/tui/config-wizard/kv-editor.js.map +1 -0
- package/dist/tui/config-wizard/list.d.ts +13 -0
- package/dist/tui/config-wizard/list.d.ts.map +1 -0
- package/dist/tui/config-wizard/list.js +29 -0
- package/dist/tui/config-wizard/list.js.map +1 -0
- package/dist/tui/config-wizard/mcp-helpers.d.ts +9 -0
- package/dist/tui/config-wizard/mcp-helpers.d.ts.map +1 -0
- package/dist/tui/config-wizard/mcp-helpers.js +19 -0
- package/dist/tui/config-wizard/mcp-helpers.js.map +1 -0
- package/dist/tui/config-wizard/menu.d.ts +18 -0
- package/dist/tui/config-wizard/menu.d.ts.map +1 -0
- package/dist/tui/config-wizard/menu.js +70 -0
- package/dist/tui/config-wizard/menu.js.map +1 -0
- package/dist/tui/config-wizard/prompt-editor.d.ts +24 -0
- package/dist/tui/config-wizard/prompt-editor.d.ts.map +1 -0
- package/dist/tui/config-wizard/prompt-editor.js +83 -0
- package/dist/tui/config-wizard/prompt-editor.js.map +1 -0
- package/dist/tui/config-wizard/prompt.d.ts +57 -0
- package/dist/tui/config-wizard/prompt.d.ts.map +1 -0
- package/dist/tui/config-wizard/prompt.js +130 -0
- package/dist/tui/config-wizard/prompt.js.map +1 -0
- package/dist/tui/config-wizard/step-agents.d.ts +4 -0
- package/dist/tui/config-wizard/step-agents.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-agents.js +110 -0
- package/dist/tui/config-wizard/step-agents.js.map +1 -0
- package/dist/tui/config-wizard/step-defaults.d.ts +4 -0
- package/dist/tui/config-wizard/step-defaults.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-defaults.js +76 -0
- package/dist/tui/config-wizard/step-defaults.js.map +1 -0
- package/dist/tui/config-wizard/step-endpoints.d.ts +4 -0
- package/dist/tui/config-wizard/step-endpoints.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-endpoints.js +43 -0
- package/dist/tui/config-wizard/step-endpoints.js.map +1 -0
- package/dist/tui/config-wizard/step-mcp.d.ts +4 -0
- package/dist/tui/config-wizard/step-mcp.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-mcp.js +97 -0
- package/dist/tui/config-wizard/step-mcp.js.map +1 -0
- package/dist/tui/config-wizard/step-menu.d.ts +4 -0
- package/dist/tui/config-wizard/step-menu.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-menu.js +28 -0
- package/dist/tui/config-wizard/step-menu.js.map +1 -0
- package/dist/tui/config-wizard/step-models.d.ts +4 -0
- package/dist/tui/config-wizard/step-models.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-models.js +114 -0
- package/dist/tui/config-wizard/step-models.js.map +1 -0
- package/dist/tui/config-wizard/step-new-endpoint.d.ts +4 -0
- package/dist/tui/config-wizard/step-new-endpoint.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-new-endpoint.js +54 -0
- package/dist/tui/config-wizard/step-new-endpoint.js.map +1 -0
- package/dist/tui/config-wizard/step-simple.d.ts +4 -0
- package/dist/tui/config-wizard/step-simple.d.ts.map +1 -0
- package/dist/tui/config-wizard/step-simple.js +55 -0
- package/dist/tui/config-wizard/step-simple.js.map +1 -0
- package/dist/tui/config-wizard/types.d.ts +138 -0
- package/dist/tui/config-wizard/types.d.ts.map +1 -0
- package/dist/tui/config-wizard/types.js +12 -0
- package/dist/tui/config-wizard/types.js.map +1 -0
- package/dist/tui/config-wizard/wizard.d.ts +9 -0
- package/dist/tui/config-wizard/wizard.d.ts.map +1 -0
- package/dist/tui/config-wizard/wizard.js +33 -0
- package/dist/tui/config-wizard/wizard.js.map +1 -0
- package/dist/tui/highlight.d.ts +34 -0
- package/dist/tui/highlight.d.ts.map +1 -0
- package/dist/tui/highlight.js +116 -0
- package/dist/tui/highlight.js.map +1 -0
- package/dist/tui/index.d.ts +33 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +265 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/screens/chat-commands.d.ts +27 -0
- package/dist/tui/screens/chat-commands.d.ts.map +1 -0
- package/dist/tui/screens/chat-commands.js +176 -0
- package/dist/tui/screens/chat-commands.js.map +1 -0
- package/dist/tui/screens/chat.d.ts +25 -0
- package/dist/tui/screens/chat.d.ts.map +1 -0
- package/dist/tui/screens/chat.js +494 -0
- package/dist/tui/screens/chat.js.map +1 -0
- package/dist/tui/screens/index.d.ts +13 -0
- package/dist/tui/screens/index.d.ts.map +1 -0
- package/dist/tui/screens/index.js +14 -0
- package/dist/tui/screens/index.js.map +1 -0
- package/dist/tui/screens/input.d.ts +29 -0
- package/dist/tui/screens/input.d.ts.map +1 -0
- package/dist/tui/screens/input.js +54 -0
- package/dist/tui/screens/input.js.map +1 -0
- package/dist/tui/screens/layout.d.ts +42 -0
- package/dist/tui/screens/layout.d.ts.map +1 -0
- package/dist/tui/screens/layout.js +45 -0
- package/dist/tui/screens/layout.js.map +1 -0
- package/dist/tui/screens/lines.d.ts +71 -0
- package/dist/tui/screens/lines.d.ts.map +1 -0
- package/dist/tui/screens/lines.js +198 -0
- package/dist/tui/screens/lines.js.map +1 -0
- package/dist/tui/screens/overlays.d.ts +12 -0
- package/dist/tui/screens/overlays.d.ts.map +1 -0
- package/dist/tui/screens/overlays.js +34 -0
- package/dist/tui/screens/overlays.js.map +1 -0
- package/dist/tui/screens/render.d.ts +9 -0
- package/dist/tui/screens/render.d.ts.map +1 -0
- package/dist/tui/screens/render.js +97 -0
- package/dist/tui/screens/render.js.map +1 -0
- package/dist/tui/screens/splash.d.ts +5 -0
- package/dist/tui/screens/splash.d.ts.map +1 -0
- package/dist/tui/screens/splash.js +51 -0
- package/dist/tui/screens/splash.js.map +1 -0
- package/dist/tui/screens/state.d.ts +13 -0
- package/dist/tui/screens/state.d.ts.map +1 -0
- package/dist/tui/screens/state.js +75 -0
- package/dist/tui/screens/state.js.map +1 -0
- package/dist/tui/text.d.ts +71 -0
- package/dist/tui/text.d.ts.map +1 -0
- package/dist/tui/text.js +191 -0
- package/dist/tui/text.js.map +1 -0
- package/dist/tui/theme.d.ts +62 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +120 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/types.d.ts +1 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +11 -6
- package/dist/config-wizard.d.ts +0 -6
- package/dist/config-wizard.d.ts.map +0 -1
- package/dist/config-wizard.js +0 -46
- package/dist/config-wizard.js.map +0 -1
- package/dist/conversation-commands/back.d.ts +0 -3
- package/dist/conversation-commands/back.d.ts.map +0 -1
- package/dist/conversation-commands/back.js +0 -144
- package/dist/conversation-commands/back.js.map +0 -1
- package/dist/conversation-commands/clear.d.ts +0 -3
- package/dist/conversation-commands/clear.d.ts.map +0 -1
- package/dist/conversation-commands/clear.js +0 -8
- package/dist/conversation-commands/clear.js.map +0 -1
- package/dist/conversation-commands/editor.d.ts +0 -3
- package/dist/conversation-commands/editor.d.ts.map +0 -1
- package/dist/conversation-commands/editor.js +0 -15
- package/dist/conversation-commands/editor.js.map +0 -1
- package/dist/conversation-commands/exit.d.ts +0 -3
- package/dist/conversation-commands/exit.d.ts.map +0 -1
- package/dist/conversation-commands/exit.js +0 -37
- package/dist/conversation-commands/exit.js.map +0 -1
- package/dist/conversation-commands/help.d.ts +0 -3
- package/dist/conversation-commands/help.d.ts.map +0 -1
- package/dist/conversation-commands/help.js +0 -10
- package/dist/conversation-commands/help.js.map +0 -1
- package/dist/conversation-commands/index.d.ts +0 -13
- package/dist/conversation-commands/index.d.ts.map +0 -1
- package/dist/conversation-commands/index.js +0 -66
- package/dist/conversation-commands/index.js.map +0 -1
- package/dist/conversation-commands/migrate.d.ts +0 -12
- package/dist/conversation-commands/migrate.d.ts.map +0 -1
- package/dist/conversation-commands/migrate.js +0 -56
- package/dist/conversation-commands/migrate.js.map +0 -1
- package/dist/conversation-commands/new.d.ts +0 -3
- package/dist/conversation-commands/new.d.ts.map +0 -1
- package/dist/conversation-commands/new.js +0 -45
- package/dist/conversation-commands/new.js.map +0 -1
- package/dist/conversation-commands/save.d.ts +0 -3
- package/dist/conversation-commands/save.d.ts.map +0 -1
- package/dist/conversation-commands/save.js +0 -32
- package/dist/conversation-commands/save.js.map +0 -1
- package/dist/conversation-runner.d.ts +0 -17
- package/dist/conversation-runner.d.ts.map +0 -1
- package/dist/conversation-runner.js +0 -176
- package/dist/conversation-runner.js.map +0 -1
- package/dist/delta-renderer.d.ts +0 -33
- package/dist/delta-renderer.d.ts.map +0 -1
- package/dist/delta-renderer.js +0 -120
- package/dist/delta-renderer.js.map +0 -1
- package/dist/draft-plugin.d.ts +0 -19
- package/dist/draft-plugin.d.ts.map +0 -1
- package/dist/draft-plugin.js +0 -30
- package/dist/draft-plugin.js.map +0 -1
- package/dist/draft-repository.d.ts +0 -34
- package/dist/draft-repository.d.ts.map +0 -1
- package/dist/draft-repository.js +0 -64
- package/dist/draft-repository.js.map +0 -1
- package/dist/menus/agents.d.ts +0 -5
- package/dist/menus/agents.d.ts.map +0 -1
- package/dist/menus/agents.js +0 -219
- package/dist/menus/agents.js.map +0 -1
- package/dist/menus/common.d.ts +0 -41
- package/dist/menus/common.d.ts.map +0 -1
- package/dist/menus/common.js +0 -104
- package/dist/menus/common.js.map +0 -1
- package/dist/menus/config-display.d.ts +0 -2
- package/dist/menus/config-display.d.ts.map +0 -1
- package/dist/menus/config-display.js +0 -82
- package/dist/menus/config-display.js.map +0 -1
- package/dist/menus/config.d.ts +0 -8
- package/dist/menus/config.d.ts.map +0 -1
- package/dist/menus/config.js +0 -407
- package/dist/menus/config.js.map +0 -1
- package/dist/menus/conversations.d.ts +0 -20
- package/dist/menus/conversations.d.ts.map +0 -1
- package/dist/menus/conversations.js +0 -83
- package/dist/menus/conversations.js.map +0 -1
- package/dist/menus/index.d.ts +0 -5
- package/dist/menus/index.d.ts.map +0 -1
- package/dist/menus/index.js +0 -59
- package/dist/menus/index.js.map +0 -1
- package/dist/menus/start-conversation.d.ts +0 -16
- package/dist/menus/start-conversation.d.ts.map +0 -1
- package/dist/menus/start-conversation.js +0 -176
- package/dist/menus/start-conversation.js.map +0 -1
- package/dist/slash-hint-prompt.d.ts +0 -41
- package/dist/slash-hint-prompt.d.ts.map +0 -1
- package/dist/slash-hint-prompt.js +0 -92
- package/dist/slash-hint-prompt.js.map +0 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Ink 通用组件 —— Spinner / 选择列表 / 状态栏 / 斜杠命令菜单 / 键位提示
|
|
4
|
+
*/
|
|
5
|
+
import { useEffect, useState } from "react";
|
|
6
|
+
import { Box, Text } from "ink";
|
|
7
|
+
import { useInput } from "ink";
|
|
8
|
+
import { theme } from "./theme.js";
|
|
9
|
+
import { clipWidth } from "./text.js";
|
|
10
|
+
// ==================== Spinner ====================
|
|
11
|
+
const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
12
|
+
export function Spinner({ label }) {
|
|
13
|
+
const [frame, setFrame] = useState(0);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const timer = setInterval(() => setFrame((f) => (f + 1) % SPINNER_FRAMES.length), 80);
|
|
16
|
+
return () => clearInterval(timer);
|
|
17
|
+
}, []);
|
|
18
|
+
return (_jsxs(Text, { children: [_jsx(Text, { color: theme.brand[0], children: SPINNER_FRAMES[frame] }), label ? _jsxs(Text, { color: theme.dim, children: [" ", label] }) : null] }));
|
|
19
|
+
}
|
|
20
|
+
/** 把列表项裁到单行(给提示文字留出空间);未提供列数则原样返回 */
|
|
21
|
+
function fitItem(item, columns) {
|
|
22
|
+
if (!columns)
|
|
23
|
+
return item;
|
|
24
|
+
const available = Math.max(8, columns - 4); // 左留白 2 + 光标 2
|
|
25
|
+
if (!item.hint)
|
|
26
|
+
return { ...item, label: clipWidth(item.label, available) };
|
|
27
|
+
const labelMax = Math.max(6, Math.floor(available * 0.55));
|
|
28
|
+
const hintMax = Math.max(4, available - labelMax - 2);
|
|
29
|
+
return { ...item, label: clipWidth(item.label, labelMax), hint: clipWidth(item.hint, hintMax) };
|
|
30
|
+
}
|
|
31
|
+
export function SelectList({ items, onSelect, isActive = true, initialIndex = 0, columns }) {
|
|
32
|
+
const [index, setIndex] = useState(Math.min(initialIndex, Math.max(items.length - 1, 0)));
|
|
33
|
+
useInput((_input, key) => {
|
|
34
|
+
if (items.length === 0)
|
|
35
|
+
return;
|
|
36
|
+
if (key.upArrow)
|
|
37
|
+
setIndex((i) => (i - 1 + items.length) % items.length);
|
|
38
|
+
else if (key.downArrow)
|
|
39
|
+
setIndex((i) => (i + 1) % items.length);
|
|
40
|
+
else if (key.return)
|
|
41
|
+
onSelect(items[index].value);
|
|
42
|
+
}, { isActive });
|
|
43
|
+
return (_jsx(Box, { flexDirection: "column", children: items.map((raw, i) => {
|
|
44
|
+
const item = fitItem(raw, columns);
|
|
45
|
+
const selected = i === index;
|
|
46
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: selected ? theme.brand[0] : theme.faint, wrap: "truncate", children: selected ? "❯ " : " " }), _jsxs(Text, { bold: selected, color: selected ? theme.highlight : theme.assistant, wrap: "truncate", children: [item.icon ? `${item.icon} ` : "", item.label] }), item.hint ? (_jsxs(Text, { color: theme.dim, wrap: "truncate", children: [" ", item.hint] })) : null] }, `${i}-${raw.label}`));
|
|
47
|
+
}) }));
|
|
48
|
+
}
|
|
49
|
+
export function StatusBar({ model, agent, tokens, busy, hint }) {
|
|
50
|
+
return (_jsxs(Box, { paddingX: 1, justifyContent: "space-between", flexShrink: 0, width: "100%", children: [_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: theme.brand[0], children: "\u25C6 " }), _jsx(Text, { color: theme.accent, children: model }), _jsx(Text, { color: theme.dim, children: " \u00B7 agent " }), _jsx(Text, { color: theme.assistant, children: agent }), tokens != null ? _jsxs(Text, { color: theme.dim, children: [" \u00B7 ", tokens, " tok"] }) : null, busy ? _jsx(Text, { color: theme.tool, children: " \u00B7 \u23F3 \u751F\u6210\u4E2D" }) : null] }), _jsx(Text, { color: theme.faint, wrap: "truncate", children: hint ?? "" })] }));
|
|
51
|
+
}
|
|
52
|
+
export function SlashMenu({ hints, selected }) {
|
|
53
|
+
return (_jsx(Box, { flexDirection: "column", paddingLeft: 2, children: hints.map((hint, i) => {
|
|
54
|
+
const active = i === selected;
|
|
55
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: active ? theme.brand[0] : theme.faint, children: active ? "❯ " : " " }), _jsx(Text, { bold: active, color: active ? theme.highlight : theme.assistant, children: hint.label }), _jsxs(Text, { color: theme.dim, children: [" ", hint.description] })] }, hint.label));
|
|
56
|
+
}) }));
|
|
57
|
+
}
|
|
58
|
+
// ==================== 键位提示 ====================
|
|
59
|
+
export function KeyHints({ hints }) {
|
|
60
|
+
return (_jsx(Box, { paddingLeft: 2, gap: 2, children: hints.map(([key, label]) => (_jsxs(Text, { color: theme.faint, wrap: "truncate", children: [_jsx(Text, { color: theme.dim, wrap: "truncate", children: key }), " ", label] }, key))) }));
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../../src/tui/components.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export type DetailFieldKind = "text" | "secret" | "number" | "enum" | "bool" | "map";
|
|
2
|
+
/** 详情屏的一个可编辑字段 */
|
|
3
|
+
export interface DetailField {
|
|
4
|
+
key: string;
|
|
5
|
+
label: string;
|
|
6
|
+
kind: DetailFieldKind;
|
|
7
|
+
/** 展示值(bool → "是"/"否";enum → 当前选项 label;secret → 已掩码的串) */
|
|
8
|
+
value: string;
|
|
9
|
+
/** 进入编辑(text/secret/number)时的初值;缺省用 `value` */
|
|
10
|
+
initial?: string;
|
|
11
|
+
/** enum 选项 */
|
|
12
|
+
options?: {
|
|
13
|
+
label: string;
|
|
14
|
+
value: string;
|
|
15
|
+
}[];
|
|
16
|
+
/** 提交文本 / 枚举值:返回错误信息或 `null`(成功) */
|
|
17
|
+
commit?: (raw: string) => Promise<string | null>;
|
|
18
|
+
/** bool 切换 */
|
|
19
|
+
toggle?: () => Promise<string | null>;
|
|
20
|
+
/** map 类型:按 Enter 进入子屏(键值编辑) */
|
|
21
|
+
open?: () => void;
|
|
22
|
+
}
|
|
23
|
+
/** 详情屏底部的整体动作(如「删除」),危险动作以红色呈现并可二次确认 */
|
|
24
|
+
export interface DetailAction {
|
|
25
|
+
label: string;
|
|
26
|
+
run: () => Promise<string | null>;
|
|
27
|
+
}
|
|
28
|
+
export interface DetailStepProps {
|
|
29
|
+
columns: number;
|
|
30
|
+
rows: number;
|
|
31
|
+
title: string;
|
|
32
|
+
/** 标题下的说明行 */
|
|
33
|
+
details?: string[];
|
|
34
|
+
fields: DetailField[];
|
|
35
|
+
notice?: string | null;
|
|
36
|
+
/** 底部危险动作(如删除) */
|
|
37
|
+
action?: DetailAction;
|
|
38
|
+
onBack: () => void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 通用详情屏 —— 一屏列出某实体的全部字段,就地编辑:
|
|
42
|
+
* - 导航态:`↑ ↓` 在字段(含底部动作)间移动,`Esc` 返回列表;
|
|
43
|
+
* - 文本类(text/secret/number):`Enter` 进入编辑,`Enter` 保存、`Esc` 取消,secret 支持 `Tab` 切明文;
|
|
44
|
+
* - bool:`Enter` 直接切换;enum:`Enter` 弹出选项列表;
|
|
45
|
+
* - 动作行:`Enter` 弹二次确认,确认后执行(通常用于删除)。
|
|
46
|
+
*
|
|
47
|
+
* 文本编辑时光标「就地」落在所选字段的值上(硬件光标同步,IME 候选框跟随);
|
|
48
|
+
* 帧高恒为「终端行数 − 1」,与其它屏一致。
|
|
49
|
+
*/
|
|
50
|
+
export declare function DetailStep({ columns, rows, title, details, fields, notice, action, onBack }: DetailStepProps): import("react").JSX.Element;
|
|
51
|
+
//# sourceMappingURL=detail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detail.d.ts","sourceRoot":"","sources":["../../../src/tui/config-wizard/detail.tsx"],"names":[],"mappings":"AAWA,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAErF,kBAAkB;AAClB,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,eAAe,CAAC;IACtB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc;IACd,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7C,oCAAoC;IACpC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACjD,cAAc;IACd,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtC,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,kBAAkB;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,eAAe,+BAyT5G"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// 由 src/tui/config-wizard.tsx 拆分而来 —— 通用详情屏 DetailStep(就地编辑)
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Box, Text, useCursor, useInput } from "ink";
|
|
5
|
+
import { theme } from "../theme.js";
|
|
6
|
+
import { KeyHints } from "../components.js";
|
|
7
|
+
import { bottomPadding, displayWidth, isTerminalReply } from "../text.js";
|
|
8
|
+
import { Header, WizardFrame, textRows, padDisplay } from "./frame.js";
|
|
9
|
+
import { ListStep } from "./list.js";
|
|
10
|
+
/**
|
|
11
|
+
* 通用详情屏 —— 一屏列出某实体的全部字段,就地编辑:
|
|
12
|
+
* - 导航态:`↑ ↓` 在字段(含底部动作)间移动,`Esc` 返回列表;
|
|
13
|
+
* - 文本类(text/secret/number):`Enter` 进入编辑,`Enter` 保存、`Esc` 取消,secret 支持 `Tab` 切明文;
|
|
14
|
+
* - bool:`Enter` 直接切换;enum:`Enter` 弹出选项列表;
|
|
15
|
+
* - 动作行:`Enter` 弹二次确认,确认后执行(通常用于删除)。
|
|
16
|
+
*
|
|
17
|
+
* 文本编辑时光标「就地」落在所选字段的值上(硬件光标同步,IME 候选框跟随);
|
|
18
|
+
* 帧高恒为「终端行数 − 1」,与其它屏一致。
|
|
19
|
+
*/
|
|
20
|
+
export function DetailStep({ columns, rows, title, details, fields, notice, action, onBack }) {
|
|
21
|
+
const { setCursorPosition } = useCursor();
|
|
22
|
+
const rowCount = Math.max(1, fields.length + (action ? 1 : 0));
|
|
23
|
+
const [index, setIndex] = useState(0);
|
|
24
|
+
const [editing, setEditing] = useState(false);
|
|
25
|
+
const [value, setValue] = useState("");
|
|
26
|
+
const [cursor, setCursor] = useState(0);
|
|
27
|
+
const [revealed, setRevealed] = useState(false);
|
|
28
|
+
const [error, setError] = useState(null);
|
|
29
|
+
const [choosing, setChoosing] = useState(false);
|
|
30
|
+
const [confirming, setConfirming] = useState(false);
|
|
31
|
+
// 行数变化(如 Agent 详情 ↔ 权限子屏共用本组件)时收敛高亮索引,避免越界导致无高亮
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
setIndex((i) => Math.min(i, Math.max(0, rowCount - 1)));
|
|
34
|
+
}, [rowCount]);
|
|
35
|
+
const labelWidth = Math.max(6, ...fields.map((f) => displayWidth(f.label)));
|
|
36
|
+
const valueX = 2 + labelWidth + 2;
|
|
37
|
+
const field = index < fields.length ? fields[index] : undefined;
|
|
38
|
+
const onActionRow = Boolean(action) && index === fields.length;
|
|
39
|
+
const chars = Array.from(value);
|
|
40
|
+
const caret = Math.max(0, Math.min(cursor, chars.length));
|
|
41
|
+
const masked = field?.kind === "secret" && !revealed;
|
|
42
|
+
const beginEdit = () => {
|
|
43
|
+
if (!field)
|
|
44
|
+
return;
|
|
45
|
+
const current = field.initial ?? field.value;
|
|
46
|
+
setValue(current);
|
|
47
|
+
setCursor(Array.from(current).length);
|
|
48
|
+
setRevealed(false);
|
|
49
|
+
setError(null);
|
|
50
|
+
setEditing(true);
|
|
51
|
+
};
|
|
52
|
+
const update = (next, nextCursor) => {
|
|
53
|
+
setValue(next);
|
|
54
|
+
setCursor(nextCursor);
|
|
55
|
+
};
|
|
56
|
+
const insert = (text) => update(chars.slice(0, caret).join("") + text + chars.slice(caret).join(""), caret + Array.from(text).length);
|
|
57
|
+
const deleteBefore = () => {
|
|
58
|
+
if (caret === 0)
|
|
59
|
+
return;
|
|
60
|
+
update(chars.slice(0, caret - 1).join("") + chars.slice(caret).join(""), caret - 1);
|
|
61
|
+
};
|
|
62
|
+
const deleteAfter = () => {
|
|
63
|
+
if (caret >= chars.length)
|
|
64
|
+
return;
|
|
65
|
+
update(chars.slice(0, caret).join("") + chars.slice(caret + 1).join(""), caret);
|
|
66
|
+
};
|
|
67
|
+
const apply = async (run) => {
|
|
68
|
+
setError(null);
|
|
69
|
+
const failure = await run();
|
|
70
|
+
if (failure)
|
|
71
|
+
setError(failure);
|
|
72
|
+
};
|
|
73
|
+
const submit = async () => {
|
|
74
|
+
if (!field?.commit)
|
|
75
|
+
return;
|
|
76
|
+
const raw = value.trim();
|
|
77
|
+
const current = (field.initial ?? field.value).trim();
|
|
78
|
+
if (raw === current) {
|
|
79
|
+
setEditing(false);
|
|
80
|
+
setError(null);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const failure = await field.commit(raw);
|
|
84
|
+
if (failure) {
|
|
85
|
+
setError(failure);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
setEditing(false);
|
|
89
|
+
setError(null);
|
|
90
|
+
};
|
|
91
|
+
useInput((char, key) => {
|
|
92
|
+
if (isTerminalReply(char))
|
|
93
|
+
return;
|
|
94
|
+
if (editing) {
|
|
95
|
+
if (key.escape) {
|
|
96
|
+
setEditing(false);
|
|
97
|
+
setError(null);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (key.return) {
|
|
101
|
+
void submit();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (key.tab && field?.kind === "secret") {
|
|
105
|
+
setRevealed((r) => !r);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (char === "u" && key.ctrl) {
|
|
109
|
+
update("", 0);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (key.leftArrow) {
|
|
113
|
+
setCursor(Math.max(0, caret - 1));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (key.rightArrow) {
|
|
117
|
+
setCursor(Math.min(chars.length, caret + 1));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (key.home) {
|
|
121
|
+
setCursor(0);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (key.end) {
|
|
125
|
+
setCursor(chars.length);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (key.backspace) {
|
|
129
|
+
deleteBefore();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (key.delete) {
|
|
133
|
+
deleteAfter();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (char && !key.ctrl && !key.meta)
|
|
137
|
+
insert(char);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (key.escape) {
|
|
141
|
+
onBack();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (key.upArrow) {
|
|
145
|
+
setIndex((i) => (i - 1 + rowCount) % rowCount);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (key.downArrow) {
|
|
149
|
+
setIndex((i) => (i + 1) % rowCount);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (key.return) {
|
|
153
|
+
if (onActionRow && action) {
|
|
154
|
+
setConfirming(true);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (!field)
|
|
158
|
+
return;
|
|
159
|
+
if (field.kind === "bool") {
|
|
160
|
+
if (field.toggle)
|
|
161
|
+
void apply(field.toggle);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (field.kind === "enum") {
|
|
165
|
+
setChoosing(true);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (field.kind === "map") {
|
|
169
|
+
field.open?.();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
beginEdit();
|
|
173
|
+
}
|
|
174
|
+
}, { isActive: !choosing && !confirming });
|
|
175
|
+
// ---- 子屏:枚举选择 ----
|
|
176
|
+
const enumOptions = field?.options;
|
|
177
|
+
if (choosing && field && enumOptions) {
|
|
178
|
+
const target = field;
|
|
179
|
+
return (_jsx(ListStep, { columns: columns, rows: rows, title: `${target.label} · 选择`, items: enumOptions.map((option) => ({ label: option.label || "(空)", value: option.value })), onPick: (picked) => {
|
|
180
|
+
setChoosing(false);
|
|
181
|
+
if (target.commit)
|
|
182
|
+
void apply(() => target.commit(picked));
|
|
183
|
+
}, onCancel: () => setChoosing(false) }));
|
|
184
|
+
}
|
|
185
|
+
// ---- 子屏:动作二次确认 ----
|
|
186
|
+
if (confirming && action) {
|
|
187
|
+
const target = action;
|
|
188
|
+
return (_jsx(ListStep, { columns: columns, rows: rows, title: `${target.label}?`, subtitle: `${title} —— 此操作不可撤销`, items: [
|
|
189
|
+
{ label: `确认${target.label}`, value: "yes" },
|
|
190
|
+
{ label: "取消", value: "no" },
|
|
191
|
+
], onPick: (picked) => {
|
|
192
|
+
setConfirming(false);
|
|
193
|
+
if (picked === "yes")
|
|
194
|
+
void apply(target.run);
|
|
195
|
+
}, onCancel: () => setConfirming(false) }));
|
|
196
|
+
}
|
|
197
|
+
// ---- 主屏 ----
|
|
198
|
+
const headerRows = [
|
|
199
|
+
...textRows(title, columns, theme.highlight, true),
|
|
200
|
+
...(details ?? []).flatMap((detail) => textRows(detail, columns, theme.dim)),
|
|
201
|
+
...(notice ? textRows(`✔ ${notice}`, columns, theme.ok) : []),
|
|
202
|
+
...(error ? textRows(`✖ ${error}`, columns, theme.error) : []),
|
|
203
|
+
];
|
|
204
|
+
const contentLines = headerRows.length + 1 + fields.length + (action ? 1 : 0) + 1;
|
|
205
|
+
if (editing && field) {
|
|
206
|
+
const shown = masked ? "•".repeat(chars.length) : value;
|
|
207
|
+
const shownChars = Array.from(shown);
|
|
208
|
+
setCursorPosition({
|
|
209
|
+
x: valueX + displayWidth(shownChars.slice(0, caret).join("")),
|
|
210
|
+
y: bottomPadding(rows, contentLines) + headerRows.length + 1 + index,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
setCursorPosition(undefined);
|
|
215
|
+
}
|
|
216
|
+
const hints = editing
|
|
217
|
+
? masked
|
|
218
|
+
? [
|
|
219
|
+
["Enter", "保存"],
|
|
220
|
+
["Tab", "明文/掩码"],
|
|
221
|
+
["Esc", "取消"],
|
|
222
|
+
]
|
|
223
|
+
: [
|
|
224
|
+
["Enter", "保存"],
|
|
225
|
+
["Esc", "取消"],
|
|
226
|
+
]
|
|
227
|
+
: onActionRow
|
|
228
|
+
? [
|
|
229
|
+
["Enter", "执行"],
|
|
230
|
+
["↑ ↓", "移动"],
|
|
231
|
+
["Esc", "返回"],
|
|
232
|
+
]
|
|
233
|
+
: field?.kind === "bool"
|
|
234
|
+
? [
|
|
235
|
+
["Enter", "切换"],
|
|
236
|
+
["↑ ↓", "移动"],
|
|
237
|
+
["Esc", "返回"],
|
|
238
|
+
]
|
|
239
|
+
: field?.kind === "enum"
|
|
240
|
+
? [
|
|
241
|
+
["Enter", "选择"],
|
|
242
|
+
["↑ ↓", "移动"],
|
|
243
|
+
["Esc", "返回"],
|
|
244
|
+
]
|
|
245
|
+
: field?.kind === "map"
|
|
246
|
+
? [
|
|
247
|
+
["Enter", "打开"],
|
|
248
|
+
["↑ ↓", "移动"],
|
|
249
|
+
["Esc", "返回"],
|
|
250
|
+
]
|
|
251
|
+
: [
|
|
252
|
+
["Enter", "编辑"],
|
|
253
|
+
["↑ ↓", "移动"],
|
|
254
|
+
["Esc", "返回"],
|
|
255
|
+
];
|
|
256
|
+
return (_jsxs(WizardFrame, { columns: columns, rows: rows, contentLines: contentLines, children: [_jsx(Header, { rows: headerRows }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [fields.map((f, i) => {
|
|
257
|
+
const selected = i === index;
|
|
258
|
+
const active = editing && selected;
|
|
259
|
+
const rowMasked = f.kind === "secret" && !revealed;
|
|
260
|
+
let before = f.value;
|
|
261
|
+
let at = "";
|
|
262
|
+
let after = "";
|
|
263
|
+
if (active) {
|
|
264
|
+
const shown = rowMasked ? "•".repeat(chars.length) : value;
|
|
265
|
+
const shownChars = Array.from(shown);
|
|
266
|
+
before = shownChars.slice(0, caret).join("");
|
|
267
|
+
at = shownChars[caret] ?? " ";
|
|
268
|
+
after = shownChars.slice(caret + 1).join("");
|
|
269
|
+
}
|
|
270
|
+
return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: selected ? theme.brand[0] : theme.faint, children: selected ? "❯ " : " " }), _jsx(Text, { bold: selected, color: selected ? theme.highlight : theme.assistant, children: padDisplay(f.label, labelWidth) }), _jsx(Text, { children: " " }), active ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: before }), _jsx(Text, { inverse: true, color: theme.brand[0], children: at }), _jsx(Text, { children: after })] })) : (_jsx(Text, { color: f.kind === "text" ? theme.assistant : theme.dim, children: before }))] }, f.key));
|
|
271
|
+
}), action ? (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: index === fields.length ? theme.brand[0] : theme.faint, children: index === fields.length ? "❯ " : " " }), _jsx(Text, { bold: index === fields.length, color: theme.error, children: padDisplay(action.label, labelWidth) })] })) : null] }), _jsx(KeyHints, { hints: hints })] }));
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detail.js","sourceRoot":"","sources":["../../../src/tui/config-wizard/detail.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from "react";
|
|
2
|
+
import { AgentDefinition, AppConfig } from "@ai-zen/agents-sdk";
|
|
3
|
+
import { McpConfig, McpScope } from "../../config.js";
|
|
4
|
+
import { AgentStore, AgentKind } from "../../agents-store.js";
|
|
5
|
+
import { WizardStep, NewEndpointDraft, WizardCloseResult, McpSnapshot, ConfigWizardProps } from "./types.js";
|
|
6
|
+
import { createFieldBuilders } from "./fields.js";
|
|
7
|
+
export interface WizardEngine extends ReturnType<typeof createFieldBuilders> {
|
|
8
|
+
config: AppConfig;
|
|
9
|
+
mcp: McpSnapshot;
|
|
10
|
+
store: AgentStore;
|
|
11
|
+
error: string | null;
|
|
12
|
+
notice: string | null;
|
|
13
|
+
draft: NewEndpointDraft;
|
|
14
|
+
acc: {
|
|
15
|
+
current: WizardCloseResult;
|
|
16
|
+
};
|
|
17
|
+
step: WizardStep;
|
|
18
|
+
activeStep: WizardStep;
|
|
19
|
+
snapshot: () => WizardCloseResult;
|
|
20
|
+
go: (next: WizardStep) => void;
|
|
21
|
+
commit: (next: AppConfig, message: string, changedEndpointIds?: string[], after?: WizardStep | "stay") => Promise<void>;
|
|
22
|
+
persist: (next: AppConfig, message: string, changedEndpointIds?: string[]) => Promise<string | null>;
|
|
23
|
+
persistMcp: (scope: McpScope, next: McpConfig, message: string) => Promise<string | null>;
|
|
24
|
+
saveAgent: (kind: AgentKind, def: AgentDefinition, message: string) => Promise<string | null>;
|
|
25
|
+
deleteAgent: (kind: AgentKind, id: string) => Promise<string | null>;
|
|
26
|
+
setDraft: Dispatch<SetStateAction<NewEndpointDraft>>;
|
|
27
|
+
setError: Dispatch<SetStateAction<string | null>>;
|
|
28
|
+
setStep: Dispatch<SetStateAction<WizardStep>>;
|
|
29
|
+
}
|
|
30
|
+
export interface WizardContext extends WizardEngine {
|
|
31
|
+
cols: number;
|
|
32
|
+
rows: number;
|
|
33
|
+
props: ConfigWizardProps;
|
|
34
|
+
}
|
|
35
|
+
export declare function useWizardEngine(props: ConfigWizardProps): WizardEngine;
|
|
36
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/tui/config-wizard/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,QAAQ,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAiB,SAAS,EAAE,QAAQ,EAAoB,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAA6B,UAAU,EAAE,SAAS,EAAyC,MAAM,uBAAuB,CAAC;AAEhI,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC7G,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,YAAa,SAAQ,UAAU,CAAC,OAAO,mBAAmB,CAAC;IAC1E,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,WAAW,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,GAAG,EAAE;QAAE,OAAO,EAAE,iBAAiB,CAAA;KAAE,CAAC;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;IAClC,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxH,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrG,UAAU,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1F,SAAS,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9F,WAAW,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrE,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACrD,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAClD,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CA+LtE"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// 由 src/tui/config-wizard.tsx 拆分而来 —— 配置向导引擎(状态 + 写盘/跳转处理器)
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
|
+
import { mcpConfigPath, writeMcpConfigAt } from "../../config.js";
|
|
4
|
+
import { agentKindLabel, agentList, findAgentDefinition, createAgentStore } from "../../agents-store.js";
|
|
5
|
+
import { findEndpoint, findMcpServer, findModel } from "../../config-editor.js";
|
|
6
|
+
import { createFieldBuilders } from "./fields.js";
|
|
7
|
+
export function useWizardEngine(props) {
|
|
8
|
+
const [config, setConfig] = useState(props.config);
|
|
9
|
+
const [step, setStep] = useState(props.initialStep ?? { kind: "menu" });
|
|
10
|
+
const [draft, setDraft] = useState({ name: "", baseUrl: "", apiKey: "" });
|
|
11
|
+
const [mcp, setMcp] = useState(props.mcp ?? { global: { mcpServers: {} }, project: { mcpServers: {} } });
|
|
12
|
+
const [store, setStore] = useState(() => props.agentStore ?? createAgentStore([], []));
|
|
13
|
+
const [error, setError] = useState(null);
|
|
14
|
+
const [notice, setNotice] = useState(null);
|
|
15
|
+
// 累加器放 ref:`commit()` 后需要立刻读到最新值再决定是否关闭
|
|
16
|
+
const acc = useRef({ dirty: false, summary: [], changedEndpointIds: [] });
|
|
17
|
+
const snapshot = () => {
|
|
18
|
+
const result = {
|
|
19
|
+
dirty: acc.current.dirty,
|
|
20
|
+
summary: [...acc.current.summary],
|
|
21
|
+
changedEndpointIds: [...acc.current.changedEndpointIds],
|
|
22
|
+
};
|
|
23
|
+
if (acc.current.mcpChanged)
|
|
24
|
+
result.mcpChanged = true;
|
|
25
|
+
if (acc.current.agentsChanged)
|
|
26
|
+
result.agentsChanged = true;
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
const go = (next) => {
|
|
30
|
+
setError(null);
|
|
31
|
+
setStep(next);
|
|
32
|
+
};
|
|
33
|
+
/** 记录一次成功写盘:更新配置快照、累加变更、刷新提示 */
|
|
34
|
+
const record = (next, message, changedEndpointIds = []) => {
|
|
35
|
+
setConfig(next);
|
|
36
|
+
acc.current.dirty = true;
|
|
37
|
+
acc.current.summary.push(message);
|
|
38
|
+
for (const id of changedEndpointIds) {
|
|
39
|
+
if (!acc.current.changedEndpointIds.includes(id))
|
|
40
|
+
acc.current.changedEndpointIds.push(id);
|
|
41
|
+
}
|
|
42
|
+
setNotice(message);
|
|
43
|
+
};
|
|
44
|
+
/** 写盘 + 记录变更,**原地停留**;返回错误信息或 `null`(供详情屏字段提交使用) */
|
|
45
|
+
const persist = async (next, message, changedEndpointIds = []) => {
|
|
46
|
+
try {
|
|
47
|
+
await props.onSave(next);
|
|
48
|
+
}
|
|
49
|
+
catch (cause) {
|
|
50
|
+
return `写入配置失败:${cause?.message ?? cause}`;
|
|
51
|
+
}
|
|
52
|
+
record(next, message, changedEndpointIds);
|
|
53
|
+
return null;
|
|
54
|
+
};
|
|
55
|
+
/** 写盘 MCP 配置 + 记录变更,**原地停留**;返回错误信息或 `null` */
|
|
56
|
+
const persistMcp = async (scope, next, message) => {
|
|
57
|
+
try {
|
|
58
|
+
if (props.onSaveMcp)
|
|
59
|
+
await props.onSaveMcp(scope, next);
|
|
60
|
+
else
|
|
61
|
+
await writeMcpConfigAt(mcpConfigPath(scope), next);
|
|
62
|
+
}
|
|
63
|
+
catch (cause) {
|
|
64
|
+
return `写入 MCP 配置失败:${cause?.message ?? cause}`;
|
|
65
|
+
}
|
|
66
|
+
setMcp((prev) => ({ ...prev, [scope]: next }));
|
|
67
|
+
acc.current.dirty = true;
|
|
68
|
+
acc.current.mcpChanged = true;
|
|
69
|
+
acc.current.summary.push(message);
|
|
70
|
+
setNotice(message);
|
|
71
|
+
return null;
|
|
72
|
+
};
|
|
73
|
+
/** 写盘某个 Agent / Sub-agent 定义(创建或更新),刷新本地快照并记录变更 */
|
|
74
|
+
const saveAgent = async (kind, def, message) => {
|
|
75
|
+
const next = { ...def, updatedAt: new Date().toISOString() };
|
|
76
|
+
try {
|
|
77
|
+
await store.save(kind, next);
|
|
78
|
+
}
|
|
79
|
+
catch (cause) {
|
|
80
|
+
return `写入 Agent 定义失败:${cause?.message ?? cause}`;
|
|
81
|
+
}
|
|
82
|
+
setStore((prev) => {
|
|
83
|
+
const list = [...agentList(prev, kind)];
|
|
84
|
+
const index = list.findIndex((item) => item.id === next.id);
|
|
85
|
+
if (index >= 0)
|
|
86
|
+
list[index] = next;
|
|
87
|
+
else
|
|
88
|
+
list.push(next);
|
|
89
|
+
return kind === "agent" ? { ...prev, agents: list } : { ...prev, subAgents: list };
|
|
90
|
+
});
|
|
91
|
+
acc.current.dirty = true;
|
|
92
|
+
acc.current.agentsChanged = true;
|
|
93
|
+
acc.current.summary.push(message);
|
|
94
|
+
setNotice(message);
|
|
95
|
+
return null;
|
|
96
|
+
};
|
|
97
|
+
/** 静默删除某个定义(用于重命名时清理旧文件;不记录变更) */
|
|
98
|
+
const removeAgentQuiet = async (kind, id) => {
|
|
99
|
+
try {
|
|
100
|
+
await store.remove(kind, id);
|
|
101
|
+
}
|
|
102
|
+
catch (cause) {
|
|
103
|
+
return `删除 Agent 定义失败:${cause?.message ?? cause}`;
|
|
104
|
+
}
|
|
105
|
+
setStore((prev) => {
|
|
106
|
+
const list = agentList(prev, kind).filter((item) => item.id !== id);
|
|
107
|
+
return kind === "agent" ? { ...prev, agents: list } : { ...prev, subAgents: list };
|
|
108
|
+
});
|
|
109
|
+
return null;
|
|
110
|
+
};
|
|
111
|
+
/** 删除某个定义并记录变更 */
|
|
112
|
+
const deleteAgent = async (kind, id) => {
|
|
113
|
+
const failure = await removeAgentQuiet(kind, id);
|
|
114
|
+
if (failure)
|
|
115
|
+
return failure;
|
|
116
|
+
acc.current.dirty = true;
|
|
117
|
+
acc.current.agentsChanged = true;
|
|
118
|
+
acc.current.summary.push(`已删除 ${agentKindLabel(kind)} ${id}`);
|
|
119
|
+
setNotice(`已删除 ${agentKindLabel(kind)} ${id}`);
|
|
120
|
+
return null;
|
|
121
|
+
};
|
|
122
|
+
/** 写盘 + 记录变更 + 跳转;成功且 `closeOnSave` 时直接关闭,否则跳到 `after` 步骤(默认回菜单) */
|
|
123
|
+
const commit = async (next, message, changedEndpointIds = [], after = { kind: "menu" }) => {
|
|
124
|
+
setError(null);
|
|
125
|
+
const failure = await persist(next, message, changedEndpointIds);
|
|
126
|
+
if (failure) {
|
|
127
|
+
setError(failure);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (props.closeOnSave)
|
|
131
|
+
props.onClose(snapshot());
|
|
132
|
+
else if (after !== "stay")
|
|
133
|
+
go(after);
|
|
134
|
+
};
|
|
135
|
+
// 条目可能在向导打开期间被外部删除:渲染前收敛回其列表,避免空指针
|
|
136
|
+
const normalize = (current) => {
|
|
137
|
+
if ((current.kind === "edit" || current.kind === "endpoint") && !findEndpoint(config, current.endpointId)) {
|
|
138
|
+
return { kind: "endpoints" };
|
|
139
|
+
}
|
|
140
|
+
if (current.kind === "model" && !findModel(config, current.modelId))
|
|
141
|
+
return { kind: "models" };
|
|
142
|
+
if (current.kind === "image-model" &&
|
|
143
|
+
!(config.imageModels ?? []).some((model) => model.id === current.modelId)) {
|
|
144
|
+
return { kind: "image-models" };
|
|
145
|
+
}
|
|
146
|
+
if ((current.kind === "mcp-server" || current.kind === "mcp-kv") &&
|
|
147
|
+
!findMcpServer(mcp[current.scope], current.serverId)) {
|
|
148
|
+
return { kind: "mcp", scope: current.scope };
|
|
149
|
+
}
|
|
150
|
+
if ((current.kind === "agent" || current.kind === "agent-perms" || current.kind === "agent-text") &&
|
|
151
|
+
!findAgentDefinition(store, current.agentKind, current.agentId)) {
|
|
152
|
+
return { kind: "agents" };
|
|
153
|
+
}
|
|
154
|
+
return current;
|
|
155
|
+
};
|
|
156
|
+
const activeStep = normalize(step);
|
|
157
|
+
// 字段构造器已抽到 ./fields.js
|
|
158
|
+
const { endpointFields, modelFields, imageModelFields, mcpServerFields, agentFields, agentPermFields } = createFieldBuilders({ config, mcp, store, persist, persistMcp, saveAgent, removeAgentQuiet, go });
|
|
159
|
+
return {
|
|
160
|
+
config,
|
|
161
|
+
mcp,
|
|
162
|
+
store,
|
|
163
|
+
error,
|
|
164
|
+
notice,
|
|
165
|
+
draft,
|
|
166
|
+
acc,
|
|
167
|
+
step,
|
|
168
|
+
activeStep,
|
|
169
|
+
snapshot,
|
|
170
|
+
go,
|
|
171
|
+
commit,
|
|
172
|
+
persist,
|
|
173
|
+
persistMcp,
|
|
174
|
+
saveAgent,
|
|
175
|
+
deleteAgent,
|
|
176
|
+
setDraft,
|
|
177
|
+
setError,
|
|
178
|
+
setStep,
|
|
179
|
+
endpointFields,
|
|
180
|
+
modelFields,
|
|
181
|
+
imageModelFields,
|
|
182
|
+
mcpServerFields,
|
|
183
|
+
agentFields,
|
|
184
|
+
agentPermFields,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=engine.js.map
|