@morndream/mihomo-tui 0.5.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/LICENSE +21 -0
  3. package/README.md +462 -0
  4. package/bin/mihomo-tui +34 -0
  5. package/dist/App.js +161 -0
  6. package/dist/App.js.map +1 -0
  7. package/dist/api/client.js +239 -0
  8. package/dist/api/client.js.map +1 -0
  9. package/dist/api/status.js +43 -0
  10. package/dist/api/status.js.map +1 -0
  11. package/dist/api/stream.js +139 -0
  12. package/dist/api/stream.js.map +1 -0
  13. package/dist/api/types.js +6 -0
  14. package/dist/api/types.js.map +1 -0
  15. package/dist/cli.js +221 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/commands/conn.js +122 -0
  18. package/dist/commands/conn.js.map +1 -0
  19. package/dist/commands/logs.js +99 -0
  20. package/dist/commands/logs.js.map +1 -0
  21. package/dist/commands/output.js +177 -0
  22. package/dist/commands/output.js.map +1 -0
  23. package/dist/commands/provider.js +140 -0
  24. package/dist/commands/provider.js.map +1 -0
  25. package/dist/commands/proxy.js +161 -0
  26. package/dist/commands/proxy.js.map +1 -0
  27. package/dist/commands/proxyEnv.js +193 -0
  28. package/dist/commands/proxyEnv.js.map +1 -0
  29. package/dist/commands/rules.js +87 -0
  30. package/dist/commands/rules.js.map +1 -0
  31. package/dist/commands/status.js +75 -0
  32. package/dist/commands/status.js.map +1 -0
  33. package/dist/components/ConfirmDialog.js +31 -0
  34. package/dist/components/ConfirmDialog.js.map +1 -0
  35. package/dist/components/DelayBadge.js +27 -0
  36. package/dist/components/DelayBadge.js.map +1 -0
  37. package/dist/components/InputDialog.js +325 -0
  38. package/dist/components/InputDialog.js.map +1 -0
  39. package/dist/components/ListDialog.js +86 -0
  40. package/dist/components/ListDialog.js.map +1 -0
  41. package/dist/components/ProgressDialog.js +34 -0
  42. package/dist/components/ProgressDialog.js.map +1 -0
  43. package/dist/components/ScrollList.js +26 -0
  44. package/dist/components/ScrollList.js.map +1 -0
  45. package/dist/components/StatusBar.js +58 -0
  46. package/dist/components/StatusBar.js.map +1 -0
  47. package/dist/components/TextEditor.js +112 -0
  48. package/dist/components/TextEditor.js.map +1 -0
  49. package/dist/components/textEditorModel.js +154 -0
  50. package/dist/components/textEditorModel.js.map +1 -0
  51. package/dist/config/manager.js +296 -0
  52. package/dist/config/manager.js.map +1 -0
  53. package/dist/config/preserveGroups.js +9 -0
  54. package/dist/config/preserveGroups.js.map +1 -0
  55. package/dist/config/ruleDocument.js +88 -0
  56. package/dist/config/ruleDocument.js.map +1 -0
  57. package/dist/config/ruleService.js +256 -0
  58. package/dist/config/ruleService.js.map +1 -0
  59. package/dist/config/ruleValidation.js +98 -0
  60. package/dist/config/ruleValidation.js.map +1 -0
  61. package/dist/config/service.js +63 -0
  62. package/dist/config/service.js.map +1 -0
  63. package/dist/config/settingsService.js +162 -0
  64. package/dist/config/settingsService.js.map +1 -0
  65. package/dist/config/skeleton.js +324 -0
  66. package/dist/config/skeleton.js.map +1 -0
  67. package/dist/config/subscriptionService.js +284 -0
  68. package/dist/config/subscriptionService.js.map +1 -0
  69. package/dist/config/subscriptions.js +200 -0
  70. package/dist/config/subscriptions.js.map +1 -0
  71. package/dist/config/types.js +5 -0
  72. package/dist/config/types.js.map +1 -0
  73. package/dist/config.js +101 -0
  74. package/dist/config.js.map +1 -0
  75. package/dist/hooks/useProviders.js +138 -0
  76. package/dist/hooks/useProviders.js.map +1 -0
  77. package/dist/hooks/useProxies.js +298 -0
  78. package/dist/hooks/useProxies.js.map +1 -0
  79. package/dist/hooks/useStream.js +127 -0
  80. package/dist/hooks/useStream.js.map +1 -0
  81. package/dist/kernel/installer.js +317 -0
  82. package/dist/kernel/installer.js.map +1 -0
  83. package/dist/kernel/releases.js +111 -0
  84. package/dist/kernel/releases.js.map +1 -0
  85. package/dist/kernel/sources.js +98 -0
  86. package/dist/kernel/sources.js.map +1 -0
  87. package/dist/rules/editor.js +181 -0
  88. package/dist/rules/editor.js.map +1 -0
  89. package/dist/rules/matcher.js +83 -0
  90. package/dist/rules/matcher.js.map +1 -0
  91. package/dist/rules/model.js +25 -0
  92. package/dist/rules/model.js.map +1 -0
  93. package/dist/rules/runtime.js +46 -0
  94. package/dist/rules/runtime.js.map +1 -0
  95. package/dist/rules/types.js +10 -0
  96. package/dist/rules/types.js.map +1 -0
  97. package/dist/ui/FooterLine.js +62 -0
  98. package/dist/ui/FooterLine.js.map +1 -0
  99. package/dist/ui/Panel.js +47 -0
  100. package/dist/ui/Panel.js.map +1 -0
  101. package/dist/ui/RowIndicator.js +25 -0
  102. package/dist/ui/RowIndicator.js.map +1 -0
  103. package/dist/ui/SectionHeader.js +14 -0
  104. package/dist/ui/SectionHeader.js.map +1 -0
  105. package/dist/ui/StatusDot.js +15 -0
  106. package/dist/ui/StatusDot.js.map +1 -0
  107. package/dist/ui/TopBar.js +81 -0
  108. package/dist/ui/TopBar.js.map +1 -0
  109. package/dist/ui/exitGuard.js +20 -0
  110. package/dist/ui/exitGuard.js.map +1 -0
  111. package/dist/ui/keyCapture.js +28 -0
  112. package/dist/ui/keyCapture.js.map +1 -0
  113. package/dist/ui/layout.js +32 -0
  114. package/dist/ui/layout.js.map +1 -0
  115. package/dist/ui/rowIndicator.js +42 -0
  116. package/dist/ui/rowIndicator.js.map +1 -0
  117. package/dist/ui/tableHeader.js +33 -0
  118. package/dist/ui/tableHeader.js.map +1 -0
  119. package/dist/ui/theme.js +47 -0
  120. package/dist/ui/theme.js.map +1 -0
  121. package/dist/ui/tone.js +131 -0
  122. package/dist/ui/tone.js.map +1 -0
  123. package/dist/version.js +27 -0
  124. package/dist/version.js.map +1 -0
  125. package/dist/views/Conns.js +107 -0
  126. package/dist/views/Conns.js.map +1 -0
  127. package/dist/views/Logs.js +89 -0
  128. package/dist/views/Logs.js.map +1 -0
  129. package/dist/views/Providers.js +392 -0
  130. package/dist/views/Providers.js.map +1 -0
  131. package/dist/views/Proxies.js +233 -0
  132. package/dist/views/Proxies.js.map +1 -0
  133. package/dist/views/RuleEditor.js +356 -0
  134. package/dist/views/RuleEditor.js.map +1 -0
  135. package/dist/views/Rules.js +286 -0
  136. package/dist/views/Rules.js.map +1 -0
  137. package/dist/views/Settings.js +734 -0
  138. package/dist/views/Settings.js.map +1 -0
  139. package/dist/views/groupDisplay.js +53 -0
  140. package/dist/views/groupDisplay.js.map +1 -0
  141. package/dist/views/subscriptionFields.js +59 -0
  142. package/dist/views/subscriptionFields.js.map +1 -0
  143. package/dist/views/yamlFile.js +32 -0
  144. package/dist/views/yamlFile.js.map +1 -0
  145. package/package.json +66 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * proxy_tui status —— 内核版本、模式、端口、provider 概览。
3
+ * 检查点 1 的验证目标:能连上 19090 并打印 v1.19.24。
4
+ */
5
+ import { MihomoClient } from '../api/client.js';
6
+ import { formatRelativeTime, printJson, renderTable } from './output.js';
7
+ /** /providers/proxies 会把代理组也列为 vehicleType=Compatible 的伪 provider,需剔除 */
8
+ export function realProviders(providers) {
9
+ return Object.entries(providers).filter(([, provider]) => provider.vehicleType === 'HTTP' || provider.vehicleType === 'File');
10
+ }
11
+ export function countAlive(proxies) {
12
+ return proxies.filter((proxy) => proxy.alive && proxy.history.length > 0).length;
13
+ }
14
+ export function isGroup(proxy) {
15
+ return Array.isArray(proxy.all);
16
+ }
17
+ export async function runStatus(config, options) {
18
+ const client = new MihomoClient(config);
19
+ const [version, configs, proxies, providers] = await Promise.all([
20
+ client.version(),
21
+ client.configs(),
22
+ client.proxies(),
23
+ client.providers(),
24
+ ]);
25
+ const groups = Object.values(proxies).filter(isGroup);
26
+ const nodes = Object.values(proxies).filter((proxy) => !isGroup(proxy));
27
+ const subs = realProviders(providers);
28
+ if (options.json) {
29
+ printJson({
30
+ api: client.api,
31
+ version,
32
+ mode: configs.mode,
33
+ logLevel: configs['log-level'],
34
+ mixedPort: configs['mixed-port'],
35
+ allowLan: configs['allow-lan'],
36
+ bindAddress: configs['bind-address'],
37
+ groups: groups.length,
38
+ nodes: nodes.length,
39
+ providers: subs.map(([name, provider]) => ({
40
+ name,
41
+ type: provider.vehicleType,
42
+ nodes: provider.proxies.length,
43
+ alive: countAlive(provider.proxies),
44
+ updatedAt: provider.updatedAt ?? null,
45
+ })),
46
+ });
47
+ return;
48
+ }
49
+ const lines = [
50
+ renderTable(['项目', '值'], [
51
+ ['内核', `mihomo ${version.version}${version.meta ? ' (meta)' : ''}`],
52
+ ['控制口', client.api],
53
+ ['模式', configs.mode],
54
+ ['日志级别', configs['log-level']],
55
+ ['混合代理口', `${configs['bind-address'] || '127.0.0.1'}:${configs['mixed-port']}`],
56
+ ['allow-lan', String(configs['allow-lan'])],
57
+ ['代理组 / 节点', `${groups.length} 组 / ${nodes.length} 节点`],
58
+ ]),
59
+ ];
60
+ if (subs.length > 0) {
61
+ const rows = subs.map(([name, provider]) => [
62
+ name,
63
+ provider.vehicleType.toLowerCase(),
64
+ String(provider.proxies.length),
65
+ String(countAlive(provider.proxies)),
66
+ formatRelativeTime(provider.updatedAt),
67
+ ]);
68
+ lines.push('', renderTable(['PROVIDER', 'TYPE', 'NODES', 'ALIVE', 'UPDATED'], rows));
69
+ }
70
+ else {
71
+ lines.push('', 'provider:无(当前为整份 proxies 配置,尚未迁移到 proxy-providers 架构)');
72
+ }
73
+ process.stdout.write(`${lines.join('\n')}\n`);
74
+ }
75
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * 确认对话框(cc-switch 确认卡片语言,spec 2026-09-13 dialogs-topbar-polish §3.1)。
4
+ * 键帽反色块居中、问题文案居中、大留白;无内部标题行——问题文案即内容。
5
+ * y/Y 确认,n/N/ESC 取消;danger 模式红色边框与文案,用于不可撤销的删除类操作。
6
+ *
7
+ * borderTitle:内嵌边框标题形态(如退出确认的「退出」,Panel 同款顶线)——
8
+ * 键帽紧贴顶线、与文案间隔三行、底部三行留白;缺省保持紧凑确认卡形态。
9
+ */
10
+ import { Box, Text, useInput } from 'ink';
11
+ import { colors, styles } from '../ui/theme.js';
12
+ import { TOP_PREFIX, panelTopParts } from '../ui/Panel.js';
13
+ import { useKeyCapture } from '../ui/keyCapture.js';
14
+ export function ConfirmDialog({ message, danger = false, width = 56, enterConfirms = false, borderTitle, onConfirm, onCancel, }) {
15
+ useKeyCapture(true);
16
+ useInput((input, key) => {
17
+ if (key.escape || input === 'n' || input === 'N') {
18
+ onCancel();
19
+ return;
20
+ }
21
+ if (input === 'y' || input === 'Y' || (enterConfirms && key.return)) {
22
+ onConfirm();
23
+ }
24
+ });
25
+ const lines = Array.isArray(message) ? message : [message];
26
+ const borderColor = danger ? colors.danger : colors.accent;
27
+ const titleStyle = danger ? { color: colors.danger, bold: true } : styles.panelTitle;
28
+ const parts = borderTitle !== undefined ? panelTopParts(borderTitle, width) : null;
29
+ return (_jsxs(Box, { flexDirection: "column", width: width, children: [parts ? (_jsxs(Text, { children: [_jsx(Text, { color: borderColor, children: TOP_PREFIX }), _jsx(Text, { ...titleStyle, children: parts.title }), _jsx(Text, { color: borderColor, children: parts.tail })] })) : null, _jsxs(Box, { flexDirection: "column", alignItems: "center", borderStyle: "round", borderTop: parts ? false : undefined, borderColor: borderColor, paddingX: 1, paddingTop: parts ? 0 : 1, paddingBottom: parts ? 1 : 2, children: [_jsxs(Text, { children: [_jsx(Text, { inverse: true, children: enterConfirms ? 'Enter 确认' : 'y 确认' }), _jsx(Text, { children: ' ' }), _jsx(Text, { inverse: true, children: enterConfirms ? 'Esc 取消' : 'n/Esc 取消' })] }), _jsx(Box, { flexDirection: "column", alignItems: "center", marginTop: parts ? 3 : 1, children: lines.map((line, index) => (_jsx(Text, { color: danger ? colors.danger : undefined, dimColor: !danger && index > 0, children: line }, index))) })] })] }));
30
+ }
31
+ //# sourceMappingURL=ConfirmDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmDialog.js","sourceRoot":"","sources":["../../src/components/ConfirmDialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** 延迟着色标签。五状态对应 SPEC 6.2 的表格。 */
3
+ import { Text } from 'ink';
4
+ import { colors } from '../ui/theme.js';
5
+ const SPINNER = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
6
+ export function spinnerFrame(tick) {
7
+ return SPINNER[tick % SPINNER.length] ?? SPINNER[0];
8
+ }
9
+ export function DelayBadge({ status, delay, testing, width = 7 }) {
10
+ if (testing) {
11
+ return (_jsx(Text, { color: colors.info, children: '测速中'.padStart(width) }));
12
+ }
13
+ switch (status) {
14
+ case 'good':
15
+ return _jsx(Text, { color: colors.success, children: `${delay}ms`.padStart(width) });
16
+ case 'fair':
17
+ return _jsx(Text, { color: colors.warning, children: `${delay}ms`.padStart(width) });
18
+ case 'slow':
19
+ return _jsx(Text, { color: colors.danger, children: `${delay}ms`.padStart(width) });
20
+ case 'dead':
21
+ return _jsx(Text, { color: colors.danger, children: '超时'.padStart(width - 2) });
22
+ default:
23
+ // 未测试 ≠ 不可用:lazy 组在被使用前 history 恒为空(SPEC 3.4)
24
+ return _jsx(Text, { dimColor: true, children: '---'.padStart(width) });
25
+ }
26
+ }
27
+ //# sourceMappingURL=DelayBadge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DelayBadge.js","sourceRoot":"","sources":["../../src/components/DelayBadge.tsx"],"names":[],"mappings":";AAAA,iCAAiC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAWvC,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAElE,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,CAAE,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,GAAG,CAAC,EAAmB;IAC/E,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CACL,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,YAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAQ,CACzD,CAAA;IACH,CAAC;IACD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,OAAO,YAAG,GAAG,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAQ,CAAA;QAC3E,KAAK,MAAM;YACT,OAAO,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,OAAO,YAAG,GAAG,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAQ,CAAA;QAC3E,KAAK,MAAM;YACT,OAAO,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,YAAG,GAAG,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAQ,CAAA;QAC1E,KAAK,MAAM;YACT,OAAO,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,YAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,GAAQ,CAAA;QACtE;YACE,8CAA8C;YAC9C,OAAO,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAQ,CAAA;IACxD,CAAC;AACH,CAAC"}
@@ -0,0 +1,325 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * 通用多字段输入对话框(设计稿 5.1,交互参照 cc-switch 的表单样式重做)。
4
+ *
5
+ * 键位:字符输入当前字段;↑↓/Tab 切换字段;Enter 当前字段合法则前进,
6
+ * 到最后一个字段且整表合法时提交;ESC 取消。
7
+ *
8
+ * 粘贴:ink 7 的 usePaste 走 bracketed paste 独立通道,整串插入当前字段;
9
+ * 终端不支持 bracketed paste 时,粘贴会作为多字符 chunk 进入 useInput,
10
+ * 旧实现 `input.length === 1` 会把整串丢弃(新增订阅框贴不进 URL 的根因),
11
+ * 现按「过滤控制字符后整串插入」兜底。
12
+ *
13
+ * 编辑:←→/Home/End 移动光标(含 Ctrl+A/E/B/F),Backspace/Delete 删字符,
14
+ * Ctrl+U 清空、Ctrl+K 删至行尾、Ctrl+W 向前删一个词。光标始终可见(反色块),
15
+ * 超长值(订阅 URL)按显示宽度开窗滚动,不折行不撑破布局。
16
+ *
17
+ * 实现要点:终端一次 read 往往带来一串字符(快速打字/粘贴),同一轮事件里
18
+ * handler 会被连续调用多次 —— 因此按键处理一律读写 valuesRef/activeRef/
19
+ * cursorRef(始终最新的镜像),不能依赖 useState 闭包里的旧值。
20
+ * 光标与增删一律按码点数组操作,emoji 等代理对不会被 slice 切断。
21
+ */
22
+ import { Box, Text, useInput, usePaste } from 'ink';
23
+ import { FooterLine } from '../ui/FooterLine.js';
24
+ import { ListDialog } from './ListDialog.js';
25
+ import { MIN_PANEL_WIDTH, Panel, TOP_PREFIX, panelTopParts } from '../ui/Panel.js';
26
+ import { colors } from '../ui/theme.js';
27
+ import { useRef, useState } from 'react';
28
+ import { displayWidth, truncateDisplay } from '../commands/output.js';
29
+ import { useKeyCapture } from '../ui/keyCapture.js';
30
+ export function validateField(field, value) {
31
+ if (field.readOnly)
32
+ return undefined;
33
+ if (field.required && value === '')
34
+ return `${field.label}不能为空`;
35
+ return field.validate?.(value);
36
+ }
37
+ /** 逐字段求错误;只读字段恒无错误 */
38
+ export function allErrors(fields, values) {
39
+ const errors = {};
40
+ for (const field of fields) {
41
+ errors[field.key] = validateField(field, values[field.key] ?? '');
42
+ }
43
+ return errors;
44
+ }
45
+ export function isFormValid(fields, values) {
46
+ return Object.values(allErrors(fields, values)).every((error) => error === undefined);
47
+ }
48
+ /** 丢掉控制字符(换行、制表、0x00-0x1f、DEL),保留可打印内容 */
49
+ export function sanitizeInput(raw) {
50
+ return [...raw]
51
+ .filter((char) => char >= ' ' && char !== '\u007f')
52
+ .join('');
53
+ }
54
+ /**
55
+ * 把超长单行值按显示宽度开窗,保证光标字符可见。
56
+ * display 是已经过掩码处理的展示串(secret 字段传 * 串);cursor 是其中的码点下标;
57
+ * max 是可用显示列数。
58
+ */
59
+ export function inputWindow(display, cursor, max) {
60
+ const chars = [...display];
61
+ const clamped = Math.min(Math.max(0, cursor), chars.length);
62
+ const widths = chars.map((char) => displayWidth(char));
63
+ const total = widths.reduce((sum, w) => sum + w, 0);
64
+ if (max <= 0)
65
+ return { text: '', cursorOffset: 0 };
66
+ if (total <= max) {
67
+ return { text: display, cursorOffset: clamped };
68
+ }
69
+ // 以光标为中心向两侧扩张,指示符 … 各预留 1 列
70
+ const cursorWidth = clamped < chars.length ? widths[clamped] ?? 1 : 1;
71
+ let start = clamped; // [start, clamped) 是光标左侧片段
72
+ let end = Math.min(clamped + 1, chars.length); // [clamped, end) 含光标字符与其右侧片段
73
+ let used = cursorWidth;
74
+ while (true) {
75
+ if (start > 0 && used + widths[start - 1] + 2 <= max) {
76
+ start -= 1;
77
+ used += widths[start];
78
+ continue;
79
+ }
80
+ if (end < chars.length && used + widths[end] + 2 <= max) {
81
+ used += widths[end];
82
+ end += 1;
83
+ continue;
84
+ }
85
+ break;
86
+ }
87
+ const markLeft = start > 0;
88
+ const markRight = end < chars.length;
89
+ // 预算里已含两侧 … 的 2 列,这里直接落位
90
+ const middle = chars.slice(start, end).join('');
91
+ const prefix = markLeft ? '…' : '';
92
+ const suffix = markRight ? '…' : '';
93
+ return {
94
+ text: prefix + middle + suffix,
95
+ cursorOffset: (markLeft ? 1 : 0) + (clamped - start),
96
+ };
97
+ }
98
+ export function InputDialog({ title, fields, width = 64, singleLinePaste = false, onSubmit, onCancel }) {
99
+ const [pasteError, setPasteError] = useState('');
100
+ const [values, setValues] = useState(() => {
101
+ const initial = {};
102
+ for (const field of fields)
103
+ initial[field.key] = field.value ?? '';
104
+ return initial;
105
+ });
106
+ const valuesRef = useRef(values);
107
+ const [active, setActive] = useState(0);
108
+ const activeRef = useRef(0);
109
+ const cursorRef = useRef(Math.min(fields[0]?.value?.length ?? 0, Number.MAX_SAFE_INTEGER));
110
+ const [attempted, setAttempted] = useState(false); // 只有在提交被拦后才开始逐字段标红
111
+ // 选择型字段(options)按下 Enter 时弹出的选项列表;null 表示未打开
112
+ const [picking, setPicking] = useState(null);
113
+ const errors = allErrors(fields, values);
114
+ const commitValues = (next) => {
115
+ valuesRef.current = next;
116
+ setValues(next);
117
+ };
118
+ /** 切到某字段时按其当前值末尾落位光标(表单的通行习惯) */
119
+ const moveTo = (index) => {
120
+ const clamped = Math.min(fields.length - 1, Math.max(0, index));
121
+ const field = fields[clamped];
122
+ cursorRef.current = clamped >= 0 && field ? (valuesRef.current[field.key] ?? '').length : 0;
123
+ activeRef.current = clamped;
124
+ setActive(clamped);
125
+ };
126
+ /** 对当前字段按码点数组做一次原位变换,返回 null 表示不修改 */
127
+ const editCurrent = (transform) => {
128
+ const field = fields[activeRef.current];
129
+ if (!field || field.readOnly)
130
+ return;
131
+ const key = field.key;
132
+ const chars = [...(valuesRef.current[key] ?? '')];
133
+ const result = transform(chars, Math.min(cursorRef.current, chars.length));
134
+ if (!result)
135
+ return;
136
+ cursorRef.current = result.cursor;
137
+ commitValues({ ...valuesRef.current, [key]: result.chars.join('') });
138
+ };
139
+ const insertText = (raw) => {
140
+ if (singleLinePaste && /[\r\n\0]/.test(raw)) {
141
+ setPasteError('只能输入单条规则,不允许换行或 NUL');
142
+ return;
143
+ }
144
+ setPasteError('');
145
+ const cleaned = sanitizeInput(raw);
146
+ if (!cleaned)
147
+ return;
148
+ editCurrent((chars, cursor) => ({
149
+ chars: [...chars.slice(0, cursor), ...[...cleaned], ...chars.slice(cursor)],
150
+ cursor: cursor + [...cleaned].length,
151
+ }));
152
+ };
153
+ usePaste(insertText);
154
+ // 对话框存活期间捕获全部按键:App 全局 handler(含 ESC 退出)一律让路
155
+ useKeyCapture(true);
156
+ useInput((input, key) => {
157
+ if (picking)
158
+ return;
159
+ if (key.escape) {
160
+ onCancel();
161
+ return;
162
+ }
163
+ if (key.upArrow) {
164
+ moveTo(activeRef.current - 1);
165
+ return;
166
+ }
167
+ if (key.downArrow || key.tab) {
168
+ moveTo(activeRef.current + 1);
169
+ return;
170
+ }
171
+ // Enter 一律提交整表(与列表页「Enter = 确认」一致)。
172
+ // 选择列表统一用 e 打开:options 为纯选择,suggestions 为可输入也可选。
173
+ if (input === 'e' && !key.ctrl) {
174
+ const current = fields[activeRef.current];
175
+ const choices = current?.options ?? current?.suggestions;
176
+ if (current && choices && choices.length > 0) {
177
+ setPicking(current);
178
+ return;
179
+ }
180
+ }
181
+ if (key.return) {
182
+ if (isFormValid(fields, valuesRef.current)) {
183
+ onSubmit({ ...valuesRef.current });
184
+ }
185
+ else {
186
+ setAttempted(true);
187
+ // 跳到第一个有错误的字段,让问题就地可见
188
+ const current = allErrors(fields, valuesRef.current);
189
+ const firstInvalid = fields.findIndex((field) => current[field.key] !== undefined);
190
+ if (firstInvalid >= 0)
191
+ moveTo(firstInvalid);
192
+ }
193
+ return;
194
+ }
195
+ if (key.leftArrow) {
196
+ editCurrent((chars, cursor) => ({ chars, cursor: Math.max(0, cursor - 1) }));
197
+ return;
198
+ }
199
+ if (key.rightArrow) {
200
+ editCurrent((chars, cursor) => ({ chars, cursor: Math.min(chars.length, cursor + 1) }));
201
+ return;
202
+ }
203
+ if (key.home || (key.ctrl && input === 'a')) {
204
+ editCurrent((chars, cursor) => ({ chars, cursor: 0 }));
205
+ return;
206
+ }
207
+ if (key.end || (key.ctrl && input === 'e')) {
208
+ editCurrent((chars, cursor) => ({ chars, cursor: chars.length }));
209
+ return;
210
+ }
211
+ if (key.backspace) {
212
+ editCurrent((chars, cursor) => cursor === 0 ? null : { chars: [...chars.slice(0, cursor - 1), ...chars.slice(cursor)], cursor: cursor - 1 });
213
+ return;
214
+ }
215
+ if (key.delete) {
216
+ editCurrent((chars, cursor) => cursor >= chars.length ? null : { chars: [...chars.slice(0, cursor), ...chars.slice(cursor + 1)], cursor });
217
+ return;
218
+ }
219
+ if (key.ctrl) {
220
+ if (input === 'b') {
221
+ editCurrent((chars, cursor) => ({ chars, cursor: Math.max(0, cursor - 1) }));
222
+ }
223
+ else if (input === 'f') {
224
+ editCurrent((chars, cursor) => ({ chars, cursor: Math.min(chars.length, cursor + 1) }));
225
+ }
226
+ else if (input === 'u') {
227
+ editCurrent(() => ({ chars: [], cursor: 0 }));
228
+ }
229
+ else if (input === 'k') {
230
+ editCurrent((chars, cursor) => ({ chars: chars.slice(0, cursor), cursor }));
231
+ }
232
+ else if (input === 'w') {
233
+ editCurrent((chars, cursor) => {
234
+ let i = cursor;
235
+ while (i > 0 && chars[i - 1] === ' ')
236
+ i -= 1;
237
+ while (i > 0 && chars[i - 1] !== ' ')
238
+ i -= 1;
239
+ return { chars: [...chars.slice(0, i), ...chars.slice(cursor)], cursor: i };
240
+ });
241
+ }
242
+ return;
243
+ }
244
+ if (key.meta)
245
+ return;
246
+ // 纯选择字段不接受自由输入;带候选项的字段中 e 打开选择列表
247
+ const current = fields[activeRef.current];
248
+ if (current?.options)
249
+ return;
250
+ if (current?.suggestions && input === 'e') {
251
+ setPicking(current);
252
+ return;
253
+ }
254
+ // 整串插入(多字符 chunk = 不带 bracketed paste 标记的粘贴 / 快速输入)
255
+ insertText(input);
256
+ });
257
+ const tried = attempted;
258
+ // 居中窄卡片(spec 2026-09-13 §5.3):min(64, max(44, width-8));
259
+ // 终端窄于 44 列时退化为全宽(无居中),保可用性
260
+ // 字段多时卡片变高,收窄宽度换取纵向空间,避免撑出屏幕
261
+ const cardWidth = width < 44 ? width : Math.min(fields.length > 4 ? 56 : 64, Math.max(44, width - 8));
262
+ // 字段槽位宽:卡片 Panel 边框 2 + paddingX 2;输入盒内可用列再减槽位边框 2 + paddingX 2
263
+ const slotWidth = Math.max(0, cardWidth - 4);
264
+ const innerWidth = Math.max(10, cardWidth - 8);
265
+ // 校验错误集中展示:优先当前字段,其次第一个出错字段(替代逐字段错误行)
266
+ let shownError;
267
+ if (tried) {
268
+ const activeField = fields[active];
269
+ shownError = (activeField && errors[activeField.key]) || fields.map((f) => errors[f.key]).find(Boolean);
270
+ }
271
+ const renderSlotContent = (field, value, isActive) => {
272
+ if (!isActive) {
273
+ const display = field.secret ? '*'.repeat(value.length) : value;
274
+ const optionLabel = field.options?.find((option) => option.value === value)?.label;
275
+ // 未聚焦时按显示宽度截断到一行,超长值(订阅 URL)尾部省略,避免撑高槽位
276
+ const shown = truncateDisplay(optionLabel ?? display, innerWidth) || (field.placeholder ?? '—');
277
+ return _jsx(Text, { dimColor: true, wrap: "truncate", children: shown });
278
+ }
279
+ const display = field.secret ? '*'.repeat(value.length) : value;
280
+ const windowed = value
281
+ ? inputWindow(display, Math.min(cursorRef.current, [...display].length), innerWidth)
282
+ : { text: '', cursorOffset: 0 };
283
+ const windowChars = [...windowed.text];
284
+ const at = value ? (windowChars[windowed.cursorOffset] ?? ' ') : ' ';
285
+ const before = value ? windowChars.slice(0, windowed.cursorOffset).join('') : '';
286
+ const after = value ? windowChars.slice(windowed.cursorOffset + 1).join('') : '';
287
+ return (_jsx(Text, { children: value ? (_jsxs(_Fragment, { children: [before, _jsx(Text, { inverse: true, children: at }), after] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { inverse: true, children: ' ' }), field.options || field.suggestions ? (_jsx(Text, { dimColor: true, children: field.options ? 'e 选择' : 'e 选择已有' })) : field.placeholder ? (_jsx(Text, { dimColor: true, children: field.placeholder })) : null] })) }));
288
+ };
289
+ /** 字段槽位:恒 3 行的内嵌标题 mini-Panel。聚焦 accent 亮起(invalid 转
290
+ * danger),非聚焦/readOnly 退后为 surfaceBorder + dim。顶线复用
291
+ * panelTopParts 的截断/宽度逻辑。marginTop 只加在首个字段之前,字段之间
292
+ * 紧贴,保证多字段时卡片高度一致、不靠字段数撑出参差空白。 */
293
+ const renderSlot = (field, value, index) => {
294
+ const isActive = index === active && !field.readOnly;
295
+ const invalid = tried && isActive && errors[field.key] !== undefined;
296
+ const borderColor = invalid ? colors.danger : isActive ? colors.accent : colors.surfaceBorder;
297
+ const labelStyle = invalid
298
+ ? { color: colors.danger, bold: true }
299
+ : isActive
300
+ ? { color: colors.accent, bold: true }
301
+ : { color: colors.muted };
302
+ const label = field.readOnly ? `${field.label}(只读)` : field.label;
303
+ const fullTitle = field.required ? `${label} *` : label;
304
+ const parts = panelTopParts(fullTitle, slotWidth);
305
+ // required 的 * 单独 danger 色;标题被截断(以 … 结尾)时整段按 labelStyle 渲染
306
+ const starSuffix = field.required && parts.title.endsWith(' *');
307
+ const labelShown = starSuffix ? parts.title.replace(/ \*$/, '') : parts.title;
308
+ return (_jsx(Box, { flexDirection: "column", marginTop: index === 0 ? 1 : 0, width: slotWidth, children: slotWidth < MIN_PANEL_WIDTH ? (_jsxs(_Fragment, { children: [_jsx(Text, { ...labelStyle, children: fullTitle }), renderSlotContent(field, value, isActive)] })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [_jsx(Text, { color: borderColor, children: TOP_PREFIX }), _jsx(Text, { ...labelStyle, children: labelShown }), starSuffix ? _jsx(Text, { color: colors.danger, children: ' *' }) : null, _jsx(Text, { color: borderColor, children: parts.tail })] }), _jsx(Box, { flexDirection: "column", borderStyle: "round", borderTop: false, borderColor: borderColor, paddingX: 1, children: renderSlotContent(field, value, isActive) })] })) }, field.key));
309
+ };
310
+ const card = (_jsxs(Panel, { title: `◆ ${title}`, width: cardWidth, children: [fields.map((field, index) => renderSlot(field, values[field.key] ?? '', index)), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [shownError || pasteError ? _jsx(Text, { color: colors.danger, children: `⚠ ${shownError || pasteError}` }) : null, _jsx(FooterLine, { hints: [
311
+ { key: 'Enter', label: '确认' },
312
+ { key: '↑↓', label: '切换' },
313
+ { key: 'ESC', label: '取消' },
314
+ ], width: cardWidth - 4 })] })] }));
315
+ // 选择型字段:Enter(options)或 e(suggestions)打开选项列表,选中后回填
316
+ const pickingChoices = picking?.options ?? picking?.suggestions;
317
+ if (picking && pickingChoices) {
318
+ return (_jsx(ListDialog, { borderTitle: picking.label, items: pickingChoices.map((option) => ({ value: option.value, label: option.label })), width: cardWidth, onSubmit: (value) => {
319
+ commitValues({ ...valuesRef.current, [picking.key]: value });
320
+ setPicking(null);
321
+ }, onCancel: () => setPicking(null) }));
322
+ }
323
+ return width < 44 ? card : _jsx(Box, { justifyContent: "center", children: card });
324
+ }
325
+ //# sourceMappingURL=InputDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputDialog.js","sourceRoot":"","sources":["../../src/components/InputDialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * 通用列表选择对话框(设置页的日志级别 / 内核版本 / 下载源共用)。
4
+ * 边框内嵌标题(Panel 同款顶线语言)+ 不可选的 dim 分组头 + ❯ 光标行。
5
+ *
6
+ * 键位:↑↓ 移动(自动跳过分组头)、Enter 选中、ESC 取消。
7
+ * 条目超过 maxVisible 时按光标位置开窗,不折行不撑破布局。
8
+ */
9
+ import { Box, Text, useInput } from 'ink';
10
+ import { FooterLine } from '../ui/FooterLine.js';
11
+ import { TOP_PREFIX, panelTopParts } from '../ui/Panel.js';
12
+ import { colors, styles } from '../ui/theme.js';
13
+ import { useKeyCapture } from '../ui/keyCapture.js';
14
+ import { displayWidth, padDisplay } from '../commands/output.js';
15
+ import { useRef, useState } from 'react';
16
+ /** 纯函数:从任意下标出发,找到下一个可选条目(跳过分组头);无则 null */
17
+ export function nextSelectable(items, from, step) {
18
+ let index = from + step;
19
+ while (index >= 0 && index < items.length) {
20
+ if (!items[index].section && items[index].value !== undefined)
21
+ return index;
22
+ index += step;
23
+ }
24
+ return null;
25
+ }
26
+ /** 纯函数:窗口起始下标,保证 active 落在 [start, start + maxVisible) 内 */
27
+ export function windowStart(active, items, maxVisible) {
28
+ if (items.length <= maxVisible)
29
+ return 0;
30
+ return Math.min(Math.max(0, active - Math.floor(maxVisible / 2)), items.length - maxVisible);
31
+ }
32
+ export function ListDialog({ borderTitle, items, width = 56, maxVisible = 12, onSubmit, onCancel, }) {
33
+ const first = nextSelectable(items, -1, 1) ?? -1;
34
+ const [active, setActive] = useState(first);
35
+ const activeRef = useRef(first);
36
+ const move = (step) => {
37
+ const next = nextSelectable(items, activeRef.current, step);
38
+ if (next === null)
39
+ return;
40
+ activeRef.current = next;
41
+ setActive(next);
42
+ };
43
+ // 对话框存活期间捕获全部按键:App 全局 handler(含 ESC 退出)一律让路
44
+ useKeyCapture(true);
45
+ useInput((_input, key) => {
46
+ if (key.escape) {
47
+ onCancel();
48
+ return;
49
+ }
50
+ if (key.upArrow) {
51
+ move(-1);
52
+ return;
53
+ }
54
+ if (key.downArrow) {
55
+ move(1);
56
+ return;
57
+ }
58
+ if (key.return) {
59
+ const item = items[activeRef.current];
60
+ if (item && !item.section && item.value !== undefined)
61
+ onSubmit(item.value);
62
+ }
63
+ });
64
+ const parts = panelTopParts(borderTitle, width);
65
+ const innerWidth = Math.max(10, width - 4);
66
+ const start = windowStart(Math.max(0, active), items, Math.max(1, maxVisible));
67
+ const visible = items.slice(start, start + Math.max(1, maxVisible));
68
+ return (_jsxs(Box, { flexDirection: "column", width: width, children: [_jsxs(Text, { children: [_jsx(Text, { color: colors.accent, children: TOP_PREFIX }), _jsx(Text, { ...styles.panelTitle, children: parts.title }), _jsx(Text, { color: colors.accent, children: parts.tail })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderTop: false, borderColor: colors.accent, paddingX: 1, children: [visible.map((item, offset) => {
69
+ const index = start + offset;
70
+ if (item.section) {
71
+ return (_jsx(Text, { dimColor: true, children: ` ${item.label}` }, `s-${item.label}`));
72
+ }
73
+ const focused = index === active;
74
+ const hint = item.hint;
75
+ const hintWidth = hint ? displayWidth(hint) : 0;
76
+ const labelShown = hint
77
+ ? padDisplay(item.label, Math.max(1, innerWidth - 2 - hintWidth - 1))
78
+ : item.label;
79
+ return (_jsxs(Text, { wrap: "truncate-end", children: [focused ? (_jsx(Text, { ...styles.rowFocus, bold: true, children: '❯ ' })) : (_jsx(Text, { children: ' ' })), _jsx(Text, { ...(focused ? styles.rowSelected : {}), children: labelShown }), hint ? _jsx(Text, { dimColor: true, children: ` ${hint}` }) : null] }, item.value ?? item.label));
80
+ }), _jsx(Box, { marginTop: 1, children: _jsx(FooterLine, { hints: [
81
+ { key: '↑↓', label: '选择' },
82
+ { key: 'Enter', label: '确认' },
83
+ { key: 'ESC', label: '取消' },
84
+ ], width: innerWidth }) })] })] }));
85
+ }
86
+ //# sourceMappingURL=ListDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListDialog.js","sourceRoot":"","sources":["../../src/components/ListDialog.tsx"],"names":[],"mappings":"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"}