@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,116 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// 由 src/tui/config-wizard.tsx 拆分而来 —— 键值编辑屏 KvEditorScreen(MCP env / headers)
|
|
3
|
+
import { 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 { usableFrameRows } from "../text.js";
|
|
8
|
+
import { kvEntries, parseKvInput } from "../../config-editor.js";
|
|
9
|
+
import { Header, WizardFrame, textRows } from "./frame.js";
|
|
10
|
+
import { PromptScreen } from "./prompt.js";
|
|
11
|
+
/**
|
|
12
|
+
* 键值映射编辑屏(MCP 的环境变量 / 请求头):
|
|
13
|
+
* - 首行为「+ 新增」,其后为各 `KEY = VALUE`;
|
|
14
|
+
* - `Enter` 新增 / 编辑(弹出 KEY=VALUE 输入屏,首个 = 分割);
|
|
15
|
+
* - `Ctrl+D` 或 `Delete` 删除高亮项;`↑ ↓` 移动;`Esc` 返回。
|
|
16
|
+
*/
|
|
17
|
+
export function KvEditorScreen({ columns, rows, title, subtitle, map, notice, onCommit, onBack }) {
|
|
18
|
+
const { setCursorPosition } = useCursor();
|
|
19
|
+
const [index, setIndex] = useState(0);
|
|
20
|
+
const [editing, setEditing] = useState(null);
|
|
21
|
+
const [error, setError] = useState(null);
|
|
22
|
+
const entries = kvEntries(map);
|
|
23
|
+
const rowCount = entries.length + 1;
|
|
24
|
+
const commit = async (next) => {
|
|
25
|
+
const failure = await onCommit(next);
|
|
26
|
+
if (failure)
|
|
27
|
+
setError(failure);
|
|
28
|
+
return failure;
|
|
29
|
+
};
|
|
30
|
+
const remove = async (key) => {
|
|
31
|
+
const next = {};
|
|
32
|
+
for (const [k, v] of Object.entries(map))
|
|
33
|
+
if (k !== key)
|
|
34
|
+
next[k] = v;
|
|
35
|
+
await commit(next);
|
|
36
|
+
};
|
|
37
|
+
const submit = async (raw) => {
|
|
38
|
+
const parsed = parseKvInput(raw);
|
|
39
|
+
if (!parsed) {
|
|
40
|
+
setError("格式应为 KEY=VALUE");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const target = editing;
|
|
44
|
+
if (target.mode === "add" && Object.prototype.hasOwnProperty.call(map, parsed.key)) {
|
|
45
|
+
setError(`已存在 ${parsed.key}`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const next = {};
|
|
49
|
+
for (const [k, v] of Object.entries(map)) {
|
|
50
|
+
if (target.mode === "edit" && target.key === k)
|
|
51
|
+
next[parsed.key] = parsed.value;
|
|
52
|
+
else
|
|
53
|
+
next[k] = v;
|
|
54
|
+
}
|
|
55
|
+
if (target.mode === "add")
|
|
56
|
+
next[parsed.key] = parsed.value;
|
|
57
|
+
const failure = await commit(next);
|
|
58
|
+
if (failure)
|
|
59
|
+
return;
|
|
60
|
+
setEditing(null);
|
|
61
|
+
setError(null);
|
|
62
|
+
};
|
|
63
|
+
useInput((char, key) => {
|
|
64
|
+
if (key.escape) {
|
|
65
|
+
onBack();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (key.upArrow) {
|
|
69
|
+
setIndex((i) => (i - 1 + rowCount) % rowCount);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (key.downArrow) {
|
|
73
|
+
setIndex((i) => (i + 1) % rowCount);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (key.delete || (char === "d" && key.ctrl)) {
|
|
77
|
+
if (index >= 1 && entries[index - 1])
|
|
78
|
+
void remove(entries[index - 1].key);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (key.return) {
|
|
82
|
+
setError(null);
|
|
83
|
+
if (index === 0) {
|
|
84
|
+
setEditing({ mode: "add", initial: "" });
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const entry = entries[index - 1];
|
|
88
|
+
setEditing({ mode: "edit", initial: `${entry.key}=${entry.value}`, key: entry.key });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}, { isActive: !editing });
|
|
92
|
+
if (editing) {
|
|
93
|
+
return (_jsx(PromptScreen, { columns: columns, rows: rows, title: `${title} · ${editing.mode === "add" ? "新增" : "编辑"}`, details: ["格式:KEY=VALUE(键与值以首个 = 分隔)", "例如 PATH=/usr/bin 或 Authorization=Bearer xxx"], initialValue: editing.initial, error: error, hints: [["Enter", "保存"], ["Esc", "取消"]], onSubmit: (value) => void submit(value), onCancel: () => {
|
|
94
|
+
setEditing(null);
|
|
95
|
+
setError(null);
|
|
96
|
+
} }, `kv:${editing.mode}:${editing.key ?? "new"}`));
|
|
97
|
+
}
|
|
98
|
+
setCursorPosition(undefined);
|
|
99
|
+
const headerRows = [
|
|
100
|
+
...textRows(title, columns, theme.highlight, true),
|
|
101
|
+
...(subtitle ? textRows(subtitle, columns, theme.dim) : []),
|
|
102
|
+
...(notice ? textRows(`✔ ${notice}`, columns, theme.ok) : []),
|
|
103
|
+
...(error ? textRows(`✖ ${error}`, columns, theme.error) : []),
|
|
104
|
+
];
|
|
105
|
+
const maxEntries = Math.max(1, usableFrameRows(rows) - (headerRows.length + 4));
|
|
106
|
+
const shown = entries.slice(0, maxEntries);
|
|
107
|
+
const truncated = entries.length > shown.length;
|
|
108
|
+
const listLines = 1 + Math.max(shown.length, 1) + (truncated ? 1 : 0);
|
|
109
|
+
const contentLines = headerRows.length + 1 + listLines + 1;
|
|
110
|
+
const safeIndex = Math.min(index, rowCount - 1);
|
|
111
|
+
return (_jsxs(WizardFrame, { columns: columns, rows: rows, contentLines: contentLines, children: [_jsx(Header, { rows: headerRows }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: safeIndex === 0 ? theme.brand[0] : theme.faint, children: safeIndex === 0 ? "❯ " : " " }), _jsx(Text, { bold: safeIndex === 0, color: safeIndex === 0 ? theme.highlight : theme.assistant, children: "\uFF0B \u65B0\u589E" })] }), shown.length === 0 ? (_jsx(Text, { color: theme.faint, wrap: "truncate", children: " (暂无,按 Enter 新增)" })) : (shown.map((entry, i) => {
|
|
112
|
+
const selected = safeIndex === i + 1;
|
|
113
|
+
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: entry.key }), _jsxs(Text, { color: theme.dim, children: [" = ", entry.value] })] }, entry.key));
|
|
114
|
+
})), truncated ? (_jsx(Text, { color: theme.faint, wrap: "truncate", children: ` (共 ${entries.length} 项,仅显示前 ${shown.length} 项)` })) : null] }), _jsx(KeyHints, { hints: [["Enter", "编辑/新增"], ["Ctrl+D", "删除"], ["↑ ↓", "移动"], ["Esc", "返回"]] })] }));
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=kv-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv-editor.js","sourceRoot":"","sources":["../../../src/tui/config-wizard/kv-editor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SelectItem } from "../components.js";
|
|
2
|
+
export interface ListStepProps<T> {
|
|
3
|
+
columns: number;
|
|
4
|
+
/** 终端行数(吸底布局用) */
|
|
5
|
+
rows: number;
|
|
6
|
+
title: string;
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
items: SelectItem<T>[];
|
|
9
|
+
onPick: (value: T) => void;
|
|
10
|
+
onCancel: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function ListStep<T>({ columns, rows, title, subtitle, items, onPick, onCancel }: ListStepProps<T>): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/tui/config-wizard/list.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAwB,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAMpE,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACvB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC,+BAuCxG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// 由 src/tui/config-wizard.tsx 拆分而来 —— 通用列表选择屏 ListStep
|
|
3
|
+
import { Box, Text, useCursor, useInput } from "ink";
|
|
4
|
+
import { theme } from "../theme.js";
|
|
5
|
+
import { SelectList, KeyHints } from "../components.js";
|
|
6
|
+
import { usableFrameRows } from "../text.js";
|
|
7
|
+
import { Header, WizardFrame, textRows } from "./frame.js";
|
|
8
|
+
export function ListStep({ columns, rows, title, subtitle, items, onPick, onCancel }) {
|
|
9
|
+
const { setCursorPosition } = useCursor();
|
|
10
|
+
// 列表屏无文本编辑:显式隐藏硬件光标,避免沿用上一屏(对话屏)的位置
|
|
11
|
+
setCursorPosition(undefined);
|
|
12
|
+
useInput((_char, key) => {
|
|
13
|
+
if (key.escape)
|
|
14
|
+
onCancel();
|
|
15
|
+
});
|
|
16
|
+
const headerRows = [
|
|
17
|
+
...textRows(title, columns, theme.highlight, true),
|
|
18
|
+
...(subtitle ? textRows(subtitle, columns, theme.dim) : []),
|
|
19
|
+
];
|
|
20
|
+
// 列表项多到装不下时就截断(每项严格占一行,吸底布局才能精确留白)
|
|
21
|
+
const maxItems = Math.max(1, usableFrameRows(rows) - (headerRows.length + 3));
|
|
22
|
+
const visible = items.slice(0, maxItems);
|
|
23
|
+
const truncated = items.length > visible.length;
|
|
24
|
+
const contentLines = headerRows.length + 1 + Math.max(visible.length, 1) + (truncated ? 1 : 0) + 1;
|
|
25
|
+
return (_jsxs(WizardFrame, { columns: columns, rows: rows, contentLines: contentLines, children: [_jsx(Header, { rows: headerRows }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [visible.length > 0 ? (
|
|
26
|
+
// key 绑定标题:切换步骤时强制重建,避免复用上一个列表的高亮索引
|
|
27
|
+
_jsx(SelectList, { items: visible, onSelect: onPick, columns: columns }, title)) : (_jsx(Text, { color: theme.faint, wrap: "truncate", children: " (无可选项)" })), truncated ? (_jsx(Text, { color: theme.faint, wrap: "truncate", children: ` (共 ${items.length} 项,仅显示前 ${visible.length} 项)` })) : null] }), _jsx(KeyHints, { hints: [["↑ ↓", "选择"], ["Enter", "确认"], ["Esc", "返回"]] })] }));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/tui/config-wizard/list.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { McpScope, McpServerEntry } from "../../config.js";
|
|
2
|
+
import { McpSnapshot } from "./types.js";
|
|
3
|
+
/** 作用域中文名 */
|
|
4
|
+
export declare function scopeLabel(scope: McpScope): string;
|
|
5
|
+
/** 某作用域下的服务器数量 */
|
|
6
|
+
export declare function mcpCount(mcp: McpSnapshot, scope: McpScope): number;
|
|
7
|
+
/** MCP 服务器列表项的一行摘要(stdio 显示命令 + 参数,http/sse 显示 URL) */
|
|
8
|
+
export declare function mcpServerHint(entry: McpServerEntry): string;
|
|
9
|
+
//# sourceMappingURL=mcp-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-helpers.d.ts","sourceRoot":"","sources":["../../../src/tui/config-wizard/mcp-helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAIzC,aAAa;AACb,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAElD;AAED,kBAAkB;AAClB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,GAAG,MAAM,CAElE;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAO3D"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// ==================== MCP 展示辅助 ====================
|
|
2
|
+
/** 作用域中文名 */
|
|
3
|
+
export function scopeLabel(scope) {
|
|
4
|
+
return scope === "global" ? "全局" : "项目";
|
|
5
|
+
}
|
|
6
|
+
/** 某作用域下的服务器数量 */
|
|
7
|
+
export function mcpCount(mcp, scope) {
|
|
8
|
+
return Object.keys(mcp[scope].mcpServers).length;
|
|
9
|
+
}
|
|
10
|
+
/** MCP 服务器列表项的一行摘要(stdio 显示命令 + 参数,http/sse 显示 URL) */
|
|
11
|
+
export function mcpServerHint(entry) {
|
|
12
|
+
const type = entry.type ?? "auto";
|
|
13
|
+
const remote = entry.type === "http" || entry.type === "sse";
|
|
14
|
+
const target = remote ? entry.url ?? "(未配置 URL)" : entry.command ?? "(未配置命令)";
|
|
15
|
+
const extra = !remote && entry.args?.length ? ` ${entry.args.join(" ")}` : "";
|
|
16
|
+
const off = entry.disabled === true ? " · 已禁用" : "";
|
|
17
|
+
return `${type} · ${target}${extra}${off}`;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=mcp-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-helpers.js","sourceRoot":"","sources":["../../../src/tui/config-wizard/mcp-helpers.ts"],"names":[],"mappings":"AAIA,qDAAqD;AAErD,aAAa;AACb,MAAM,UAAU,UAAU,CAAC,KAAe;IACxC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC;AAED,kBAAkB;AAClB,MAAM,UAAU,QAAQ,CAAC,GAAgB,EAAE,KAAe;IACxD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC;AACnD,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,aAAa,CAAC,KAAqB;IACjD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC;IAClC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,SAAS,CAAC;IAC9E,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,OAAO,GAAG,IAAI,MAAM,MAAM,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AppConfig } from "@ai-zen/agents-sdk";
|
|
2
|
+
import { AgentStore } from "../../agents-store.js";
|
|
3
|
+
import { McpSnapshot } from "./types.js";
|
|
4
|
+
export interface MenuStepProps {
|
|
5
|
+
columns: number;
|
|
6
|
+
/** 终端行数(吸底布局用) */
|
|
7
|
+
rows: number;
|
|
8
|
+
config: AppConfig;
|
|
9
|
+
mcp: McpSnapshot;
|
|
10
|
+
agentStore: AgentStore;
|
|
11
|
+
savedCount: number;
|
|
12
|
+
/** 最近一次保存提示 */
|
|
13
|
+
notice?: string | null;
|
|
14
|
+
onPick: (action: string) => void;
|
|
15
|
+
onClose: () => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function MenuStep({ columns, rows, config, mcp, agentStore, savedCount, notice, onPick, onClose }: MenuStepProps): import("react").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../src/tui/config-wizard/menu.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMzC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,WAAW,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,aAAa,+BAqEtH"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// 由 src/tui/config-wizard.tsx 拆分而来 —— 配置中心菜单 MenuStep
|
|
3
|
+
import { Box, useCursor, useInput } from "ink";
|
|
4
|
+
import { theme } from "../theme.js";
|
|
5
|
+
import { SelectList, KeyHints } from "../components.js";
|
|
6
|
+
import { CONFIG_FILE } from "../../config.js";
|
|
7
|
+
import { findModel, summarizeEndpoints } from "../../config-editor.js";
|
|
8
|
+
import { Header, WizardFrame, textRows } from "./frame.js";
|
|
9
|
+
import { mcpCount } from "./mcp-helpers.js";
|
|
10
|
+
export function MenuStep({ columns, rows, config, mcp, agentStore, savedCount, notice, onPick, onClose }) {
|
|
11
|
+
const { setCursorPosition } = useCursor();
|
|
12
|
+
setCursorPosition(undefined); // 无文本编辑:隐藏硬件光标
|
|
13
|
+
useInput((_char, key) => {
|
|
14
|
+
if (key.escape)
|
|
15
|
+
onClose();
|
|
16
|
+
});
|
|
17
|
+
const defaultModel = findModel(config, config.defaultModel);
|
|
18
|
+
const defaultImage = (config.imageModels ?? []).find((model) => model.id === config.defaultImageModel);
|
|
19
|
+
const items = [
|
|
20
|
+
{
|
|
21
|
+
label: "端点管理",
|
|
22
|
+
value: "endpoints",
|
|
23
|
+
hint: summarizeEndpoints(config),
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: "模型管理",
|
|
27
|
+
value: "models",
|
|
28
|
+
hint: `${config.models.length} 个 · 默认 ${defaultModel?.name ?? config.defaultModel ?? "未设置"}`,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
label: "图片模型",
|
|
32
|
+
value: "imageModels",
|
|
33
|
+
hint: `${config.imageModels?.length ?? 0} 个 · 默认 ${defaultImage?.name ?? config.defaultImageModel ?? "未设置"}`,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: "MCP 服务器",
|
|
37
|
+
value: "mcp",
|
|
38
|
+
hint: `全局 ${mcpCount(mcp, "global")} · 项目 ${mcpCount(mcp, "project")}`,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
label: "Agent 定义",
|
|
42
|
+
value: "agents",
|
|
43
|
+
hint: `Agent ${agentStore.agents.length} · Sub-agent ${agentStore.subAgents.length}`,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
label: "默认项",
|
|
47
|
+
value: "defaults",
|
|
48
|
+
hint: `Agent ${config.defaultAgent ?? "未设置"} · 迁移 ${config.defaultMigrationModel ?? "未设置"}`,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
label: "工具输出上限",
|
|
52
|
+
value: "maxToolOutput",
|
|
53
|
+
hint: `${config.maxToolOutput ?? 32768} 字符`,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
label: "完成",
|
|
57
|
+
value: "done",
|
|
58
|
+
hint: savedCount > 0 ? `已保存 ${savedCount} 项改动` : "返回对话",
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
const headerRows = [
|
|
62
|
+
...textRows("◆ 配置中心", columns, theme.highlight, true),
|
|
63
|
+
...textRows(`配置文件:${CONFIG_FILE}`, columns, theme.faint),
|
|
64
|
+
...textRows("改动即时写入磁盘;涉及当前端点的改动会重建会话(消息保留)。", columns, theme.dim),
|
|
65
|
+
...(notice ? textRows(`✔ ${notice}`, columns, theme.ok) : []),
|
|
66
|
+
];
|
|
67
|
+
const contentLines = headerRows.length + 1 + items.length + 1;
|
|
68
|
+
return (_jsxs(WizardFrame, { columns: columns, rows: rows, contentLines: contentLines, children: [_jsx(Header, { rows: headerRows }), _jsx(Box, { marginTop: 1, children: _jsx(SelectList, { items: items, onSelect: onPick, columns: columns }) }), _jsx(KeyHints, { hints: [["↑ ↓", "选择"], ["Enter", "确认"], ["Esc", "完成返回"]] })] }));
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../../src/tui/config-wizard/menu.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface PromptEditorScreenProps {
|
|
2
|
+
columns: number;
|
|
3
|
+
rows: number;
|
|
4
|
+
title: string;
|
|
5
|
+
subtitle?: string;
|
|
6
|
+
/** 待编辑的多行文本(当前内容) */
|
|
7
|
+
text: string;
|
|
8
|
+
/** 临时文件扩展名(默认 md;参数 schema 等 JSON 用 json,便于编辑器语法高亮 / 格式化) */
|
|
9
|
+
ext?: string;
|
|
10
|
+
notice?: string | null;
|
|
11
|
+
onSave: (text: string) => Promise<string | null>;
|
|
12
|
+
onBack: () => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 多行文本编辑屏 —— 内容交给**系统编辑器**(复用 `/editor` 的 `suspendTerminal` 模式)。
|
|
16
|
+
*
|
|
17
|
+
* 屏内只预览当前内容;`Enter` 挂起 Ink、用 `$EDITOR`(Windows 默认 notepad)打开临时
|
|
18
|
+
* 文件,保存回读后写盘;`Esc` 返回。
|
|
19
|
+
*
|
|
20
|
+
* 校验失败时**保留用户改后的内容**(`draft`),再次 `Enter` 可在其基础上继续修改 —— 避免
|
|
21
|
+
* JSON 校验失败后改动丢失;内容未改动时直接返回、不写盘。
|
|
22
|
+
*/
|
|
23
|
+
export declare function PromptEditorScreen({ columns, rows, title, subtitle, text, ext, notice, onSave, onBack, }: PromptEditorScreenProps): import("react").JSX.Element;
|
|
24
|
+
//# sourceMappingURL=prompt-editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-editor.d.ts","sourceRoot":"","sources":["../../../src/tui/config-wizard/prompt-editor.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACjD,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,GAAU,EACV,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,uBAAuB,+BAwEzB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// 由 src/tui/config-wizard.tsx 拆分而来 —— 多行文本编辑屏 PromptEditorScreen(系统编辑器)
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Box, Text, useApp, useCursor, useInput } from "ink";
|
|
5
|
+
import { spawnSync } from "child_process";
|
|
6
|
+
import { readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
7
|
+
import { tmpdir } from "os";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
import { theme } from "../theme.js";
|
|
10
|
+
import { KeyHints } from "../components.js";
|
|
11
|
+
import { usableFrameRows, wrapText } from "../text.js";
|
|
12
|
+
import { Header, WizardFrame, textRows } from "./frame.js";
|
|
13
|
+
/**
|
|
14
|
+
* 多行文本编辑屏 —— 内容交给**系统编辑器**(复用 `/editor` 的 `suspendTerminal` 模式)。
|
|
15
|
+
*
|
|
16
|
+
* 屏内只预览当前内容;`Enter` 挂起 Ink、用 `$EDITOR`(Windows 默认 notepad)打开临时
|
|
17
|
+
* 文件,保存回读后写盘;`Esc` 返回。
|
|
18
|
+
*
|
|
19
|
+
* 校验失败时**保留用户改后的内容**(`draft`),再次 `Enter` 可在其基础上继续修改 —— 避免
|
|
20
|
+
* JSON 校验失败后改动丢失;内容未改动时直接返回、不写盘。
|
|
21
|
+
*/
|
|
22
|
+
export function PromptEditorScreen({ columns, rows, title, subtitle, text, ext = "md", notice, onSave, onBack, }) {
|
|
23
|
+
const { setCursorPosition } = useCursor();
|
|
24
|
+
const { suspendTerminal } = useApp();
|
|
25
|
+
const [error, setError] = useState(null);
|
|
26
|
+
const [busy, setBusy] = useState(false);
|
|
27
|
+
const [draft, setDraft] = useState(null);
|
|
28
|
+
const current = draft ?? text;
|
|
29
|
+
const launch = async () => {
|
|
30
|
+
setError(null);
|
|
31
|
+
const before = current;
|
|
32
|
+
const file = join(tmpdir(), `aizen-edit-${Date.now()}.${ext}`);
|
|
33
|
+
try {
|
|
34
|
+
writeFileSync(file, before, "utf-8");
|
|
35
|
+
await suspendTerminal(() => {
|
|
36
|
+
const editor = process.env.EDITOR || process.env.VISUAL || (process.platform === "win32" ? "notepad" : "vi");
|
|
37
|
+
const result = spawnSync(editor, [file], { stdio: "inherit" });
|
|
38
|
+
if (result.error)
|
|
39
|
+
throw result.error;
|
|
40
|
+
});
|
|
41
|
+
const edited = readFileSync(file, "utf-8").replace(/\r\n/g, "\n").trimEnd();
|
|
42
|
+
if (edited === before)
|
|
43
|
+
return; // 未改动:不写盘
|
|
44
|
+
setDraft(edited);
|
|
45
|
+
const failure = await onSave(edited);
|
|
46
|
+
if (failure)
|
|
47
|
+
setError(failure);
|
|
48
|
+
else
|
|
49
|
+
setDraft(null); // 成功:交回父级最新值
|
|
50
|
+
}
|
|
51
|
+
catch (cause) {
|
|
52
|
+
setError(`打开编辑器失败:${cause?.message ?? cause}`);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
try {
|
|
56
|
+
unlinkSync(file);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
/* 忽略 */
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
setCursorPosition(undefined);
|
|
64
|
+
useInput((_char, key) => {
|
|
65
|
+
if (key.escape)
|
|
66
|
+
onBack();
|
|
67
|
+
else if (key.return && !busy) {
|
|
68
|
+
setBusy(true);
|
|
69
|
+
void launch().finally(() => setBusy(false));
|
|
70
|
+
}
|
|
71
|
+
}, { isActive: !busy });
|
|
72
|
+
const headerRows = [
|
|
73
|
+
...textRows(title, columns, theme.highlight, true),
|
|
74
|
+
...(subtitle ? textRows(subtitle, columns, theme.dim) : []),
|
|
75
|
+
...(notice ? textRows(`✔ ${notice}`, columns, theme.ok) : []),
|
|
76
|
+
...(error ? textRows(`✖ ${error}`, columns, theme.error) : []),
|
|
77
|
+
];
|
|
78
|
+
const previewBudget = Math.max(3, usableFrameRows(rows) - headerRows.length - 3);
|
|
79
|
+
const preview = current ? wrapText(current, Math.max(8, columns - 4)).slice(0, previewBudget) : ["(空)"];
|
|
80
|
+
const contentLines = headerRows.length + 1 + preview.length + 1;
|
|
81
|
+
return (_jsxs(WizardFrame, { columns: columns, rows: rows, contentLines: contentLines, children: [_jsx(Header, { rows: headerRows }), _jsx(Box, { marginTop: 1, flexDirection: "column", paddingX: 1, children: preview.map((line, index) => (_jsx(Text, { color: theme.assistant, wrap: "truncate", children: line }, index))) }), _jsx(KeyHints, { hints: [["Enter", busy ? "编辑中…" : "打开系统编辑器"], ["Esc", "返回"]] })] }));
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=prompt-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-editor.js","sourceRoot":"","sources":["../../../src/tui/config-wizard/prompt-editor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export interface PromptLayoutInput {
|
|
2
|
+
/** 终端行数 */
|
|
3
|
+
terminalRows: number;
|
|
4
|
+
/** 标题 + 说明已占行数 */
|
|
5
|
+
headerLines: number;
|
|
6
|
+
/** 输入区折行后的行数 */
|
|
7
|
+
inputLines: number;
|
|
8
|
+
/** 输入区之后额外占用的行数(空值提示 / 错误行 / 明文提示) */
|
|
9
|
+
extraLines: number;
|
|
10
|
+
/** 底部键位提示行数(通常 1) */
|
|
11
|
+
hintLines: number;
|
|
12
|
+
/** 光标在输入区内的行 / 列(列以 code point 计) */
|
|
13
|
+
cursorRow: number;
|
|
14
|
+
cursorCol: number;
|
|
15
|
+
/** 光标所在行的文本(不含提示符) */
|
|
16
|
+
lineText: string;
|
|
17
|
+
}
|
|
18
|
+
export interface PromptLayout {
|
|
19
|
+
/** 内容总行数 */
|
|
20
|
+
contentLines: number;
|
|
21
|
+
/** 顶部留白行数 */
|
|
22
|
+
topPadding: number;
|
|
23
|
+
/** 终端硬件光标坐标(相对整帧原点,供 IME 候选框定位) */
|
|
24
|
+
cursor: {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** 计算输入屏的顶部留白与硬件光标坐标(吸底布局 + IME 跟随) */
|
|
30
|
+
export declare function promptLayout(input: PromptLayoutInput): PromptLayout;
|
|
31
|
+
export interface PromptScreenProps {
|
|
32
|
+
columns: number;
|
|
33
|
+
/** 终端行数(吸底布局用) */
|
|
34
|
+
rows: number;
|
|
35
|
+
title: string;
|
|
36
|
+
/** 标题下的说明行(自动折行) */
|
|
37
|
+
details?: string[];
|
|
38
|
+
/** 输入框初始值 */
|
|
39
|
+
initialValue?: string;
|
|
40
|
+
/** 掩码输入(API Key),Tab 可临时切明文核对 */
|
|
41
|
+
mask?: boolean;
|
|
42
|
+
/** 上级校验错误 */
|
|
43
|
+
error?: string | null;
|
|
44
|
+
hints: [string, string][];
|
|
45
|
+
/** 光标位置变化时回调(用于宿主实时预览,可省略) */
|
|
46
|
+
onChange?: (value: string) => void;
|
|
47
|
+
onSubmit: (value: string) => void;
|
|
48
|
+
onCancel: () => void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 全屏单行输入:标题 + 输入行 + 键位提示(吸底布局)。
|
|
52
|
+
*
|
|
53
|
+
* 硬件光标 y 由 `promptLayout()` 按「顶部留白 + 标题行数 + 输入行内偏移」算出,
|
|
54
|
+
* 而整帧高度恒小于终端行数(不命中 Ink 全屏分支),因此 IME 候选框与自绘光标精确对齐。
|
|
55
|
+
*/
|
|
56
|
+
export declare function PromptScreen(props: PromptScreenProps): import("react").JSX.Element;
|
|
57
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/tui/config-wizard/prompt.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,iBAAiB;IAChC,WAAW;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,MAAM,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClC;AAED,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAYnE;AAID,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BA4JpD"}
|