@wukonglabs/wukong 0.1.1 → 0.1.3
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/README.md +17 -8
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +4 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/index.js +171 -54
- package/dist/index.js.map +1 -1
- package/dist/tui/app.d.ts +15 -1
- package/dist/tui/app.d.ts.map +1 -1
- package/dist/tui/app.js +51 -11
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/hint-bar.js +1 -1
- package/dist/tui/hint-bar.js.map +1 -1
- package/dist/tui/history-entry.d.ts +3 -1
- package/dist/tui/history-entry.d.ts.map +1 -1
- package/dist/tui/history-entry.js +23 -4
- package/dist/tui/history-entry.js.map +1 -1
- package/dist/tui/history-item.d.ts +14 -8
- package/dist/tui/history-item.d.ts.map +1 -1
- package/dist/tui/live-block.js +1 -1
- package/dist/tui/live-block.js.map +1 -1
- package/dist/tui/permission-card.d.ts.map +1 -1
- package/dist/tui/permission-card.js +3 -1
- package/dist/tui/permission-card.js.map +1 -1
- package/dist/tui/plan-panel.d.ts.map +1 -1
- package/dist/tui/plan-panel.js +3 -1
- package/dist/tui/plan-panel.js.map +1 -1
- package/dist/tui/response-panel.d.ts +6 -1
- package/dist/tui/response-panel.d.ts.map +1 -1
- package/dist/tui/response-panel.js +10 -1
- package/dist/tui/response-panel.js.map +1 -1
- package/dist/tui/run-ink.d.ts +18 -0
- package/dist/tui/run-ink.d.ts.map +1 -1
- package/dist/tui/run-ink.js +74 -2
- package/dist/tui/run-ink.js.map +1 -1
- package/dist/tui/slash/menu.d.ts.map +1 -1
- package/dist/tui/slash/menu.js +4 -2
- package/dist/tui/slash/menu.js.map +1 -1
- package/dist/tui/slash/registry.js +1 -1
- package/dist/tui/slash/registry.js.map +1 -1
- package/dist/tui/text-input.d.ts +16 -1
- package/dist/tui/text-input.d.ts.map +1 -1
- package/dist/tui/text-input.js +96 -42
- package/dist/tui/text-input.js.map +1 -1
- package/dist/tui/theme/theme.d.ts +4 -0
- package/dist/tui/theme/theme.d.ts.map +1 -1
- package/dist/tui/theme/theme.js +14 -10
- package/dist/tui/theme/theme.js.map +1 -1
- package/dist/tui/thinking-panel.d.ts.map +1 -1
- package/dist/tui/thinking-panel.js +7 -5
- package/dist/tui/thinking-panel.js.map +1 -1
- package/dist/tui/welcome.js +1 -1
- package/dist/tui/welcome.js.map +1 -1
- package/package.json +2 -2
- package/wukong.json +12 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history-item.d.ts","sourceRoot":"","sources":["../../src/tui/history-item.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"history-item.d.ts","sourceRoot":"","sources":["../../src/tui/history-item.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,QAAQ;IACvB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,4CAA4C;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4BAA4B;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACtG,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,8CAA8C;IAC9C,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,uDAAuD;IACvD,IAAI,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC;IAC1F,6CAA6C;IAC7C,SAAS,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;CAChC"}
|
package/dist/tui/live-block.js
CHANGED
|
@@ -67,6 +67,6 @@ export function LiveBlock({ thinkingText, thinkingStreaming, activeTools, stream
|
|
|
67
67
|
}
|
|
68
68
|
const statsSuffix = statsParts.length > 0 ? ` (${statsParts.join(' · ')})` : '';
|
|
69
69
|
const activityLine = `${icon} ${verb}…${statsSuffix}`;
|
|
70
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { paddingX: 1, children: _jsx(Text, { color: theme.status, bold: true, children: activityLine }) }), hasThinking && (_jsx(Box, { paddingX: 1, children: _jsx(ThinkingPanel, { thinking: thinkingText, streaming: thinkingStreaming, tailLines: thinkingStreaming ? thinkingRows : 0 }) })), hasTools && _jsx(ToolCards, { tools: activeTools, maxVisible: toolsVisible }), hasResponse && (_jsx(Box, { flexDirection: "column", paddingX: 1, children: tailLines.length === 0 ? (_jsx(Text, { color:
|
|
70
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { paddingX: 1, children: _jsx(Text, { color: theme.status, bold: true, children: activityLine }) }), hasThinking && (_jsx(Box, { paddingX: 1, children: _jsx(ThinkingPanel, { thinking: thinkingText, streaming: thinkingStreaming, tailLines: thinkingStreaming ? thinkingRows : 0 }) })), hasTools && _jsx(ToolCards, { tools: activeTools, maxVisible: toolsVisible }), hasResponse && (_jsx(Box, { flexDirection: "column", paddingX: 1, children: tailLines.length === 0 ? (_jsx(Text, { color: theme.assistant, dimColor: true, children: "\u231B \u6B63\u5728\u751F\u6210\u54CD\u5E94\u2026" })) : (tailLines.map((line, i) => (_jsxs(Text, { color: theme.assistant, dimColor: true, children: [line, i === tailLines.length - 1 ? '▍' : ''] }, i)))) })), (streaming || awaitingLlm) && (_jsx(Box, { paddingX: 1, children: _jsx(Text, { dimColor: true, children: `Tip: /clear 重置会话 · esc 取消当前 run` }) }))] }));
|
|
71
71
|
}
|
|
72
72
|
//# sourceMappingURL=live-block.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-block.js","sourceRoot":"","sources":["../../src/tui/live-block.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"live-block.js","sourceRoot":"","sources":["../../src/tui/live-block.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-card.d.ts","sourceRoot":"","sources":["../../src/tui/permission-card.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAyB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"permission-card.d.ts","sourceRoot":"","sources":["../../src/tui/permission-card.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAyB,MAAM,8BAA8B,CAAC;AAGrH,MAAM,WAAW,mBAAmB;IAClC,WAAW;IACX,OAAO,EAAE,oBAAoB,CAAC;IAC9B,aAAa;IACb,QAAQ,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACjD;AAED,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,mBAAmB,GAAG,KAAK,CAAC,YAAY,CAgF7F"}
|
|
@@ -18,8 +18,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
18
18
|
*/
|
|
19
19
|
import { useState } from 'react';
|
|
20
20
|
import { Box, Text, useInput } from 'ink';
|
|
21
|
+
import { useTheme } from './theme/context.js';
|
|
21
22
|
export function PermissionCard({ request, onSubmit }) {
|
|
22
23
|
const [showFullArgs, setShowFullArgs] = useState(false);
|
|
24
|
+
const { theme } = useTheme();
|
|
23
25
|
useInput((input, key) => {
|
|
24
26
|
const c = input.toLowerCase();
|
|
25
27
|
let result = null;
|
|
@@ -55,7 +57,7 @@ export function PermissionCard({ request, onSubmit }) {
|
|
|
55
57
|
}
|
|
56
58
|
});
|
|
57
59
|
const argsPreview = formatArgsPreview(request.argumentsJson, showFullArgs ? undefined : 200);
|
|
58
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "yellow", bold: true, children: "\uD83D\uDD12 \u6388\u6743\u8BF7\u6C42" }), _jsxs(Text, { dimColor: true, children: [" (step ", request.step, ")"] })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "\u5DE5\u5177: " }), _jsx(Text, { color:
|
|
60
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "yellow", bold: true, children: "\uD83D\uDD12 \u6388\u6743\u8BF7\u6C42" }), _jsxs(Text, { dimColor: true, children: [" (step ", request.step, ")"] })] }), _jsxs(Box, { children: [_jsx(Text, { bold: true, children: "\u5DE5\u5177: " }), _jsx(Text, { color: theme.status, children: request.toolName })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "\u53C2\u6570:" }), _jsx(Text, { dimColor: true, children: argsPreview }), !showFullArgs && request.argumentsJson.length > 200 && (_jsx(Text, { dimColor: true, color: "gray", children: "(\u6309 v \u67E5\u770B\u5B8C\u6574\u53C2\u6570)" }))] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, children: "\u9009\u62E9: " }) }), _jsxs(Box, { children: [_jsx(Text, { color: "green", children: "[y]" }), _jsx(Text, { children: " \u4EC5\u672C\u6B21 " }), _jsx(Text, { color: "green", children: "[s]" }), _jsx(Text, { children: " \u672C\u6B21session " }), _jsx(Text, { color: "green", children: "[l]" }), _jsx(Text, { children: " \u672C\u9879\u76EE\u6C38\u4E45 " }), _jsx(Text, { color: "green", children: "[g]" }), _jsx(Text, { children: " \u5168\u5C40\u6C38\u4E45" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "red", children: "[n]" }), _jsx(Text, { children: " \u62D2\u7EDD " }), _jsx(Text, { color: "red", children: "[x]" }), _jsx(Text, { children: " \u6C38\u4E45\u62D2\u7EDD " }), _jsx(Text, { dimColor: true, children: "[v] \u67E5\u770B\u53C2\u6570" })] })] }));
|
|
59
61
|
}
|
|
60
62
|
/** 格式化参数预览(截断到 maxLen) */
|
|
61
63
|
function formatArgsPreview(argsJson, maxLen) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-card.js","sourceRoot":"","sources":["../../src/tui/permission-card.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"permission-card.js","sourceRoot":"","sources":["../../src/tui/permission-card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan-panel.d.ts","sourceRoot":"","sources":["../../src/tui/plan-panel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"plan-panel.d.ts","sourceRoot":"","sources":["../../src/tui/plan-panel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC;CAC/D;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,yBAAyB;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,UAAe,EAAE,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CAyB/F"}
|
package/dist/tui/plan-panel.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
+
import { useTheme } from './theme/context.js';
|
|
3
4
|
export function PlanPanel({ todos, maxVisible = 10 }) {
|
|
5
|
+
const { theme } = useTheme();
|
|
4
6
|
if (todos.length === 0)
|
|
5
7
|
return null;
|
|
6
8
|
const completed = todos.filter((t) => t.status === 'completed').length;
|
|
@@ -9,7 +11,7 @@ export function PlanPanel({ todos, maxVisible = 10 }) {
|
|
|
9
11
|
// 策略:已完成的折叠到头部和尾部,进行中的可见(用户最关心的状态)
|
|
10
12
|
const visible = todos.slice(0, maxVisible);
|
|
11
13
|
const hidden = total - visible.length;
|
|
12
|
-
return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsxs(Text, { color:
|
|
14
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsxs(Text, { color: theme.status, bold: true, children: ["\u25B6 Plan (", completed, "/", total, ")"] }), visible.map((t, i) => (_jsx(TodoRow, { index: i + 1, todo: t }, t.id))), hidden > 0 && (_jsxs(Text, { dimColor: true, children: [" \u2026 \u8FD8\u6709 ", hidden, " \u4E2A todo(\u5DF2\u6298\u53E0)"] }))] }));
|
|
13
15
|
}
|
|
14
16
|
function TodoRow({ index, todo }) {
|
|
15
17
|
const { icon, color } = statusIcon(todo.status);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan-panel.js","sourceRoot":"","sources":["../../src/tui/plan-panel.tsx"],"names":[],"mappings":";AAmBA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"plan-panel.js","sourceRoot":"","sources":["../../src/tui/plan-panel.tsx"],"names":[],"mappings":";AAmBA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAc9C,MAAM,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,EAAE,EAAkB;IAClE,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAE3B,2CAA2C;IAC3C,mCAAmC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;IAEtC,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aACpC,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,oCACpB,SAAS,OAAG,KAAK,SACrB,EACN,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CACrB,KAAC,OAAO,IAAY,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,IAA3B,CAAC,CAAC,EAAE,CAA2B,CAC9C,CAAC,EACD,MAAM,GAAG,CAAC,IAAI,CACb,MAAC,IAAI,IAAC,QAAQ,6CAAS,MAAM,wCAAoB,CAClD,IACG,CACP,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAqC;IACjE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChD,OAAO,CACL,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,IAAI,GAAQ,EACjC,MAAC,IAAI,IAAC,QAAQ,wBAAG,KAAK,UAAU,EAChC,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,aAC9C,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IACxC,IACH,CACP,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,MAA0B;IAC5C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QACvC,KAAK,aAAa;YAChB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QACxC,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACrC;YACE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACxC,CAAC;AACH,CAAC"}
|
|
@@ -24,11 +24,16 @@ export interface ToolCallState {
|
|
|
24
24
|
}
|
|
25
25
|
export interface CompletedRun {
|
|
26
26
|
response: string;
|
|
27
|
-
|
|
27
|
+
/** 单次 Agent run 发起的 Provider 方法调用数,包含外层重试和 mid-run compaction */
|
|
28
|
+
requestCount: number;
|
|
28
29
|
totalTokens: {
|
|
29
30
|
prompt: number;
|
|
30
31
|
completion: number;
|
|
31
32
|
};
|
|
33
|
+
/** Provider 上报的累计 prompt cache 命中 tokens */
|
|
34
|
+
cachedPromptTokens?: number;
|
|
35
|
+
/** Provider 归一化后的缓存命中率分母 */
|
|
36
|
+
cacheInputTokens?: number;
|
|
32
37
|
durationMs: number;
|
|
33
38
|
}
|
|
34
39
|
export interface ResponsePanelProps {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-panel.d.ts","sourceRoot":"","sources":["../../src/tui/response-panel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"response-panel.d.ts","sourceRoot":"","sources":["../../src/tui/response-panel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,4CAA4C;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4BAA4B;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,sBAAsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,aAAkB,EAClB,SAAS,EACT,aAAa,EACb,QAAY,GACb,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CA2CzC"}
|
|
@@ -2,10 +2,19 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Text, Box } from 'ink';
|
|
3
3
|
import { useTerminalWidth } from './use-terminal-width.js';
|
|
4
4
|
import { tailVisualLines } from './tail-visual.js';
|
|
5
|
+
import { useTheme } from './theme/context.js';
|
|
5
6
|
export function ResponsePanel({ streamingText = '', streaming, lastCompleted, maxLines = 6, }) {
|
|
6
7
|
const cols = useTerminalWidth();
|
|
8
|
+
const { theme } = useTheme();
|
|
7
9
|
const tail = tailVisualLines(streamingText, maxLines, cols);
|
|
8
10
|
const tailLines = tail.length > 0 ? tail.split('\n') : [];
|
|
9
|
-
|
|
11
|
+
const completedCacheRate = lastCompleted?.cachedPromptTokens !== undefined &&
|
|
12
|
+
lastCompleted.cacheInputTokens !== undefined &&
|
|
13
|
+
lastCompleted.cacheInputTokens > 0
|
|
14
|
+
? (lastCompleted.cachedPromptTokens / lastCompleted.cacheInputTokens) * 100
|
|
15
|
+
: undefined;
|
|
16
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [streaming && (_jsx(Box, { flexDirection: "column", children: tailLines.length === 0 ? (_jsx(Text, { color: theme.assistant, dimColor: true, children: "\u231B \u6B63\u5728\u751F\u6210\u54CD\u5E94\u2026" })) : (tailLines.map((line, i) => (_jsxs(Text, { color: theme.assistant, dimColor: true, children: [line, i === tailLines.length - 1 ? '▍' : ''] }, i)))) })), !streaming && lastCompleted && (_jsxs(Box, { children: [_jsx(Text, { color: "green", children: "\u2713 " }), _jsxs(Text, { dimColor: true, children: ["\u672C\u8F6E\u54CD\u5E94\u5DF2\u5B8C\u6210(\u6B63\u6587\u89C1\u4E0A\u65B9,\u5171 ", lastCompleted.response.length, " \u5B57\u7B26, Request Count:", ' ', lastCompleted.requestCount, completedCacheRate !== undefined
|
|
17
|
+
? `, Cached Tokens(%): ${completedCacheRate.toFixed(1)}%`
|
|
18
|
+
: '', `, Duration: ${(lastCompleted.durationMs / 1000).toFixed(1)}s)`] })] }))] }));
|
|
10
19
|
}
|
|
11
20
|
//# sourceMappingURL=response-panel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-panel.js","sourceRoot":"","sources":["../../src/tui/response-panel.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"response-panel.js","sourceRoot":"","sources":["../../src/tui/response-panel.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAqC9C,MAAM,UAAU,aAAa,CAAC,EAC5B,aAAa,GAAG,EAAE,EAClB,SAAS,EACT,aAAa,EACb,QAAQ,GAAG,CAAC,GACO;IACnB,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,eAAe,CAAC,aAAa,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,MAAM,kBAAkB,GAAG,aAAa,EAAE,kBAAkB,KAAK,SAAS;QACxE,aAAa,CAAC,gBAAgB,KAAK,SAAS;QAC5C,aAAa,CAAC,gBAAgB,GAAG,CAAC;QAClC,CAAC,CAAC,CAAC,aAAa,CAAC,kBAAkB,GAAG,aAAa,CAAC,gBAAgB,CAAC,GAAG,GAAG;QAC3E,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACpC,SAAS,IAAI,CACZ,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACxB,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,wEAAiB,CACxD,CAAC,CAAC,CAAC,CACF,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACzB,MAAC,IAAI,IAAS,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,mBAC3C,IAAI,EACJ,CAAC,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAF7B,CAAC,CAGL,CACR,CAAC,CACH,GACG,CACP,EAEA,CAAC,SAAS,IAAI,aAAa,IAAI,CAC9B,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,wBAAU,EAC7B,MAAC,IAAI,IAAC,QAAQ,wGACK,aAAa,CAAC,QAAQ,CAAC,MAAM,mCAAqB,GAAG,EACrE,aAAa,CAAC,YAAY,EAC1B,kBAAkB,KAAK,SAAS;gCAC/B,CAAC,CAAC,uBAAuB,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;gCACzD,CAAC,CAAC,EAAE,EACL,eAAe,CAAC,aAAa,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAC3D,IACH,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
|
package/dist/tui/run-ink.d.ts
CHANGED
|
@@ -27,8 +27,26 @@ export interface InkRunHandle {
|
|
|
27
27
|
/** 卸载 Ink 实例(退出时调用) */
|
|
28
28
|
unmount: () => void;
|
|
29
29
|
}
|
|
30
|
+
interface CursorAnchorRef {
|
|
31
|
+
current: string;
|
|
32
|
+
}
|
|
33
|
+
interface FullRenderRef {
|
|
34
|
+
current: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 返回光标锚点的逆向移动。Ink 的清屏逻辑只要求回到帧末尾所在行,
|
|
38
|
+
* 后续 eraseLines 会自行把列归零,因此不依赖终端对 save/restore cursor 的支持。
|
|
39
|
+
*/
|
|
40
|
+
export declare function getCursorAnchorRestoreSequence(anchor: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Ink 的 log-update 假设每次更新都从上一帧末尾开始。为了让 IME 跟随输入位置,
|
|
43
|
+
* 每帧写完后移动到输入光标;下一次 Ink 写入前按相同行数移回帧末尾,
|
|
44
|
+
* 否则 eraseLines 会从输入行开始清屏,造成输入框和 HintBar 逐次重复。
|
|
45
|
+
*/
|
|
46
|
+
export declare function createCursorAnchoredStdout(stdout: NodeJS.WriteStream, cursorAnchorRef: CursorAnchorRef, fullRenderRef?: FullRenderRef): NodeJS.WriteStream;
|
|
30
47
|
/**
|
|
31
48
|
* 启动 Ink TUI。onStream 由调用方通过 streamSinkRef 桥接,不再由此处返回。
|
|
32
49
|
*/
|
|
33
50
|
export declare function runInk(opts: InkRunOptions): InkRunHandle;
|
|
51
|
+
export {};
|
|
34
52
|
//# sourceMappingURL=run-ink.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-ink.d.ts","sourceRoot":"","sources":["../../src/tui/run-ink.tsx"],"names":[],"mappings":"AASA,OAAO,EAAO,WAAW,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGrD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,WAAW,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,qBAAqB;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"run-ink.d.ts","sourceRoot":"","sources":["../../src/tui/run-ink.tsx"],"names":[],"mappings":"AASA,OAAO,EAAO,WAAW,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGrD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,WAAW,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,qBAAqB;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,CAAC,WAAW,EAC1B,eAAe,EAAE,eAAe,EAChC,aAAa,GAAE,aAAkC,GAChD,MAAM,CAAC,WAAW,CAsCpB;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,YAAY,CA8CxD"}
|
package/dist/tui/run-ink.js
CHANGED
|
@@ -10,13 +10,85 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
10
10
|
import { render } from 'ink';
|
|
11
11
|
import { App } from './app.js';
|
|
12
12
|
import { ThemeProvider } from './theme/context.js';
|
|
13
|
+
/**
|
|
14
|
+
* 返回光标锚点的逆向移动。Ink 的清屏逻辑只要求回到帧末尾所在行,
|
|
15
|
+
* 后续 eraseLines 会自行把列归零,因此不依赖终端对 save/restore cursor 的支持。
|
|
16
|
+
*/
|
|
17
|
+
export function getCursorAnchorRestoreSequence(anchor) {
|
|
18
|
+
const match = /^\x1b\[(\d+)A/.exec(anchor);
|
|
19
|
+
return match ? `\x1b[${match[1]}B` : '';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Ink 的 log-update 假设每次更新都从上一帧末尾开始。为了让 IME 跟随输入位置,
|
|
23
|
+
* 每帧写完后移动到输入光标;下一次 Ink 写入前按相同行数移回帧末尾,
|
|
24
|
+
* 否则 eraseLines 会从输入行开始清屏,造成输入框和 HintBar 逐次重复。
|
|
25
|
+
*/
|
|
26
|
+
export function createCursorAnchoredStdout(stdout, cursorAnchorRef, fullRenderRef = { current: false }) {
|
|
27
|
+
const originalWrite = stdout.write.bind(stdout);
|
|
28
|
+
let anchorScheduled = false;
|
|
29
|
+
let restoreFrameEnd = '';
|
|
30
|
+
const scheduleAnchor = () => {
|
|
31
|
+
if (anchorScheduled)
|
|
32
|
+
return;
|
|
33
|
+
anchorScheduled = true;
|
|
34
|
+
queueMicrotask(() => {
|
|
35
|
+
anchorScheduled = false;
|
|
36
|
+
const anchor = cursorAnchorRef.current;
|
|
37
|
+
if (anchor) {
|
|
38
|
+
originalWrite(anchor);
|
|
39
|
+
restoreFrameEnd = getCursorAnchorRestoreSequence(anchor);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
const anchoredWrite = ((...args) => {
|
|
44
|
+
if (restoreFrameEnd) {
|
|
45
|
+
originalWrite(restoreFrameEnd);
|
|
46
|
+
restoreFrameEnd = '';
|
|
47
|
+
}
|
|
48
|
+
const result = originalWrite(...args);
|
|
49
|
+
scheduleAnchor();
|
|
50
|
+
return result;
|
|
51
|
+
});
|
|
52
|
+
return new Proxy(stdout, {
|
|
53
|
+
get(target, property) {
|
|
54
|
+
if (property === 'write')
|
|
55
|
+
return anchoredWrite;
|
|
56
|
+
// Ink 在 outputHeight >= stdout.rows 时会使用 clearTerminal + 完整帧输出。
|
|
57
|
+
// resize 的同步处理期间临时返回 1,避免旧行被终端 reflow 后按失效行数增量擦除。
|
|
58
|
+
if (property === 'rows' && fullRenderRef.current)
|
|
59
|
+
return 1;
|
|
60
|
+
const value = Reflect.get(target, property, target);
|
|
61
|
+
return typeof value === 'function' ? value.bind(target) : value;
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
13
65
|
/**
|
|
14
66
|
* 启动 Ink TUI。onStream 由调用方通过 streamSinkRef 桥接,不再由此处返回。
|
|
15
67
|
*/
|
|
16
68
|
export function runInk(opts) {
|
|
17
|
-
const
|
|
69
|
+
const cursorAnchorRef = { current: '' };
|
|
70
|
+
const fullRenderRef = { current: false };
|
|
71
|
+
const stdout = createCursorAnchoredStdout(process.stdout, cursorAnchorRef, fullRenderRef);
|
|
72
|
+
const inkInstance = render(_jsx(ThemeProvider, { children: _jsx(App, { model: opts.model, sessionUuidShort: opts.sessionUuidShort, workspaceRoot: opts.workspaceRoot, handlers: opts.handlers, initialHistory: opts.initialHistory, streamSinkRef: opts.streamSinkRef, appVersion: opts.appVersion, configPath: opts.configPath, sessionRecordCount: opts.sessionRecordCount, sessionCreated: opts.sessionCreated, toolsCount: opts.toolsCount, skillsLoaded: opts.skillsLoaded, cursorAnchorRef: cursorAnchorRef }) }), { stdout });
|
|
73
|
+
/*
|
|
74
|
+
* 终端 resize 会按新列宽重排旧帧,Ink 的 previousLineCount 不再可信。
|
|
75
|
+
* 监听器排在 Ink 自带 resize 监听器之前:本次同步 resize 周期内让 stdout.rows=1,
|
|
76
|
+
* 使 Ink 走内置 clearTerminal + 完整帧输出;事件结束后立即恢复真实 rows。
|
|
77
|
+
* 不手动 clear、不 rerender,也不 remount App。
|
|
78
|
+
*/
|
|
79
|
+
const handleResize = () => {
|
|
80
|
+
fullRenderRef.current = true;
|
|
81
|
+
queueMicrotask(() => {
|
|
82
|
+
fullRenderRef.current = false;
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
process.stdout.prependListener('resize', handleResize);
|
|
18
86
|
return {
|
|
19
|
-
unmount: () =>
|
|
87
|
+
unmount: () => {
|
|
88
|
+
process.stdout.off('resize', handleResize);
|
|
89
|
+
cursorAnchorRef.current = '';
|
|
90
|
+
inkInstance.unmount();
|
|
91
|
+
},
|
|
20
92
|
};
|
|
21
93
|
}
|
|
22
94
|
//# sourceMappingURL=run-ink.js.map
|
package/dist/tui/run-ink.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-ink.js","sourceRoot":"","sources":["../../src/tui/run-ink.tsx"],"names":[],"mappings":";AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAwB,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"run-ink.js","sourceRoot":"","sources":["../../src/tui/run-ink.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../src/tui/slash/menu.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../src/tui/slash/menu.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CAkB5F"}
|
package/dist/tui/slash/menu.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
+
import { useTheme } from '../theme/context.js';
|
|
3
4
|
export function SlashMenu({ commands, highlight }) {
|
|
5
|
+
const { theme } = useTheme();
|
|
4
6
|
if (commands.length === 0)
|
|
5
7
|
return null;
|
|
6
|
-
return (_jsx(Box, { flexDirection: "column", borderStyle: "round", borderColor:
|
|
8
|
+
return (_jsx(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.border, paddingX: 1, children: commands.map((c, i) => {
|
|
7
9
|
const active = i === highlight;
|
|
8
|
-
return (_jsx(Box, { children: _jsxs(Text, { inverse: active, children: [_jsxs(Text, { color: active ?
|
|
10
|
+
return (_jsx(Box, { children: _jsxs(Text, { inverse: active, children: [_jsxs(Text, { color: active ? theme.status : undefined, children: ["/", c.name] }), _jsxs(Text, { children: [" \u2014 ", c.description] })] }) }, c.name));
|
|
9
11
|
}) }));
|
|
10
12
|
}
|
|
11
13
|
//# sourceMappingURL=menu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../../src/tui/slash/menu.tsx"],"names":[],"mappings":";AAQA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../../src/tui/slash/menu.tsx"],"names":[],"mappings":";AAQA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAQ/C,MAAM,UAAU,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAkB;IAC/D,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAC,OAAO,EAAC,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,YACnF,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACrB,MAAM,MAAM,GAAG,CAAC,KAAK,SAAS,CAAC;YAC/B,OAAO,CACL,KAAC,GAAG,cACF,MAAC,IAAI,IAAC,OAAO,EAAE,MAAM,aACnB,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,kBAAI,CAAC,CAAC,IAAI,IAAQ,EAChE,MAAC,IAAI,2BAAK,CAAC,CAAC,WAAW,IAAQ,IAC1B,IAJC,CAAC,CAAC,IAAI,CAKV,CACP,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -11,7 +11,7 @@ export const SLASH_COMMANDS = [
|
|
|
11
11
|
{ name: 'clear', description: '清空对话历史' },
|
|
12
12
|
{ name: 'quit', description: '优雅退出' },
|
|
13
13
|
{ name: 'exit', description: '优雅退出' },
|
|
14
|
-
{ name: 'model', description: '
|
|
14
|
+
{ name: 'model', description: '列出或切换模型', takesArgument: true },
|
|
15
15
|
{ name: 'session', description: '显示 session 信息' },
|
|
16
16
|
{ name: 'theme', description: '切换主题(dark/light/mono)', takesArgument: true },
|
|
17
17
|
{ name: 'compact', description: '手动触发压缩', notEnabledHint: '压缩功能未启用' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/tui/slash/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAwBH,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE;IACvC,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;IAC/D,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE;IACxC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/tui/slash/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAwBH,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE;IACvC,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;IAC/D,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE;IACxC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE;IAC9D,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE;IACjD,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,aAAa,EAAE,IAAI,EAAE;IAC5E,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE;IACrE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,gBAAgB,EAAE;IACrF,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE;CAC1C,CAAC;AAEF,+BAA+B;AAC/B,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC,CAAC;QAAE,OAAO,cAAc,CAAC;IAC9B,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC"}
|
package/dist/tui/text-input.d.ts
CHANGED
|
@@ -41,6 +41,12 @@ export interface TextInputProps {
|
|
|
41
41
|
placeholder?: string;
|
|
42
42
|
/** 是否禁用(等待 agent 响应时) */
|
|
43
43
|
disabled?: boolean;
|
|
44
|
+
/** Ink 输出层使用的真实终端光标锚点 */
|
|
45
|
+
cursorAnchorRef?: {
|
|
46
|
+
current: string;
|
|
47
|
+
};
|
|
48
|
+
/** 终端列数,用于计算输入文本自动换行后的光标位置 */
|
|
49
|
+
terminalColumns?: number;
|
|
44
50
|
/**
|
|
45
51
|
* Ctrl+C 回调(§3.3 M3):由 App 层实现两次 Ctrl+C 语义。
|
|
46
52
|
* Ink raw mode 拦截 Ctrl+C,不走 process SIGINT,故需显式回调。
|
|
@@ -51,7 +57,16 @@ export interface TextInputProps {
|
|
|
51
57
|
/** 选中某个 slash 命令时回调(name + 可选参数) */
|
|
52
58
|
onSlash?: (name: string, arg?: string) => void;
|
|
53
59
|
}
|
|
54
|
-
export declare function TextInput({ value, onChange, onSubmit, multiline, history, prompt, placeholder, disabled, onAbort, onExit, onSlash, }: TextInputProps): React.ReactElement;
|
|
60
|
+
export declare function TextInput({ value, onChange, onSubmit, multiline, history, prompt, placeholder, disabled, cursorAnchorRef, terminalColumns, onAbort, onExit, onSlash, }: TextInputProps): React.ReactElement;
|
|
61
|
+
/**
|
|
62
|
+
* 生成 Ink 完成一帧输出后,将真实终端光标移回输入位置的 ANSI 序列。
|
|
63
|
+
*
|
|
64
|
+
* 只使用相对上移 + 绝对列定位,不假设输入框贴着终端底部。输入框靠近底部时,
|
|
65
|
+
* 候选窗显示在光标上方还是下方交给终端和操作系统决定。
|
|
66
|
+
*/
|
|
67
|
+
export declare function getCursorAnchorSequence(value: string, cursor: number, prompt: string, terminalColumns: number): string;
|
|
68
|
+
/** 计算终端单元格宽度(CJK / 全角字符和 emoji 通常占两列)。 */
|
|
69
|
+
export declare function terminalCellWidth(text: string): number;
|
|
55
70
|
/** 找 pos 之前最近的 word 边界(跳过连续 whitespace + 非 word 字符) */
|
|
56
71
|
export declare function prevWordBoundary(value: string, pos: number): number;
|
|
57
72
|
/** 找 pos 之后最近的 word 边界 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-input.d.ts","sourceRoot":"","sources":["../../src/tui/text-input.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,EACL,eAAe,EAGhB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"text-input.d.ts","sourceRoot":"","sources":["../../src/tui/text-input.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,EACL,eAAe,EAGhB,MAAM,wBAAwB,CAAC;AAShC,MAAM,WAAW,cAAc;IAC7B,cAAc;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY;IACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kBAAkB;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB;IACpB,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IAC7C,qBAAqB;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,eAAe,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,8BAA8B;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAeD,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAgB,EAChB,OAAO,EACP,MAAa,EACb,WAAgB,EAChB,QAAgB,EAChB,eAAe,EACf,eAAoB,EACpB,OAAO,EACP,MAAM,EACN,OAAO,GACR,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CAmXrC;AASD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GACtB,MAAM,CA0BR;AAgCD,0CAA0C;AAC1C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQtD;AAiED,uDAAuD;AACvD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMnE;AAED,0BAA0B;AAC1B,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMnE"}
|
package/dist/tui/text-input.js
CHANGED
|
@@ -24,11 +24,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
24
24
|
* 所有可打印字符(单/多)统一走 insertText,彻底消除闭包陷阱,IME 候选可见、可退格改字。
|
|
25
25
|
*/
|
|
26
26
|
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
27
|
-
import { Text, useInput, useStdin
|
|
27
|
+
import { Text, useInput, useStdin } from 'ink';
|
|
28
28
|
import { reverseSearch, reverseSearchNext, } from './use-input-history.js';
|
|
29
29
|
import { parseSlashCommand } from './slash/parse.js';
|
|
30
30
|
import { filterSlashCommands } from './slash/registry.js';
|
|
31
31
|
import { SlashMenu } from './slash/menu.js';
|
|
32
|
+
import { useTheme } from './theme/context.js';
|
|
32
33
|
/** 输入长度硬上限(M11c):粘贴大文件也够,防止异常灌入撑爆 Ink */
|
|
33
34
|
const MAX_INPUT_LENGTH = 100_000;
|
|
34
35
|
const INITIAL_RS = {
|
|
@@ -36,13 +37,13 @@ const INITIAL_RS = {
|
|
|
36
37
|
query: '',
|
|
37
38
|
matchIndex: -1,
|
|
38
39
|
};
|
|
39
|
-
export function TextInput({ value, onChange, onSubmit, multiline = true, history, prompt = '> ', placeholder = '', disabled = false, onAbort, onExit, onSlash, }) {
|
|
40
|
+
export function TextInput({ value, onChange, onSubmit, multiline = true, history, prompt = '> ', placeholder = '', disabled = false, cursorAnchorRef, terminalColumns = 80, onAbort, onExit, onSlash, }) {
|
|
40
41
|
const [cursor, setCursor] = useState(value.length);
|
|
41
42
|
const [rs, setRs] = useState(INITIAL_RS);
|
|
42
43
|
const [slashDismissed, setSlashDismissed] = useState(false);
|
|
43
44
|
const [slashHighlight, setSlashHighlight] = useState(0);
|
|
44
45
|
const { stdin, setRawMode } = useStdin();
|
|
45
|
-
const {
|
|
46
|
+
const { theme } = useTheme();
|
|
46
47
|
// stdin 原始模式(捕获 Ctrl+C / Ctrl+R 等控制字符)
|
|
47
48
|
useEffect(() => {
|
|
48
49
|
if (stdin && typeof setRawMode === 'function') {
|
|
@@ -342,57 +343,110 @@ export function TextInput({ value, onChange, onSubmit, multiline = true, history
|
|
|
342
343
|
return;
|
|
343
344
|
}
|
|
344
345
|
});
|
|
345
|
-
// ──
|
|
346
|
-
// Ink
|
|
347
|
-
//
|
|
348
|
-
//
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
return;
|
|
355
|
-
const writeFn = s.write;
|
|
356
|
-
const termRows = s.rows;
|
|
357
|
-
const timer = setTimeout(() => {
|
|
358
|
-
try {
|
|
359
|
-
const lineStart = value.lastIndexOf('\n', cursor - 1) + 1;
|
|
360
|
-
const colInLine = cursor - lineStart;
|
|
361
|
-
let cursorLineIndex = 0;
|
|
362
|
-
for (let i = 0; i < cursor; i++) {
|
|
363
|
-
if (value[i] === '\n')
|
|
364
|
-
cursorLineIndex++;
|
|
365
|
-
}
|
|
366
|
-
/*
|
|
367
|
-
* footer 钉底结构(从屏幕底向上):
|
|
368
|
-
* row termRows : HintBar
|
|
369
|
-
* row termRows - 1 : 输入框下边框 ─
|
|
370
|
-
* row termRows - 2 : 输入框内容行(光标所在)
|
|
371
|
-
* row termRows - 3 : 输入框上边框 ─
|
|
372
|
-
*/
|
|
373
|
-
const row = Math.max(1, termRows - 2 - cursorLineIndex);
|
|
374
|
-
const col = Math.max(1, 2 + prompt.length + colInLine); // │ + space + prompt + 行内列
|
|
375
|
-
writeFn(`\x1b[${row};${col}H`);
|
|
376
|
-
}
|
|
377
|
-
catch { /* 非TTY 或流已关闭时静默失败 */ }
|
|
378
|
-
}, 0);
|
|
379
|
-
return () => clearTimeout(timer);
|
|
380
|
-
}, [value, cursor, disabled, prompt, stdout]);
|
|
346
|
+
// ── 物理光标锚点(IME 候选窗跟随)──
|
|
347
|
+
// OS 输入法读取的是终端真实光标,而 Ink 每次刷帧后会把它留在 HintBar 末尾。
|
|
348
|
+
// 这里同步计算锚点;run-ink 的 stdout 包装器会在每次真实写帧后的 microtask 恢复它,
|
|
349
|
+
// 不再用 setTimeout 与 Ink 的节流输出抢时序。
|
|
350
|
+
if (cursorAnchorRef) {
|
|
351
|
+
cursorAnchorRef.current = disabled || slashActive || rs.active
|
|
352
|
+
? ''
|
|
353
|
+
: getCursorAnchorSequence(value, cursor, prompt, terminalColumns);
|
|
354
|
+
}
|
|
381
355
|
// ── 渲染 ──
|
|
382
356
|
if (slashActive) {
|
|
383
357
|
return _jsx(SlashMenu, { commands: slashCmds, highlight: Math.min(slashHighlight, Math.max(slashCmds.length - 1, 0)) });
|
|
384
358
|
}
|
|
385
359
|
if (rs.active) {
|
|
386
360
|
const matchText = rs.matchIndex >= 0 && history ? history.entries[rs.matchIndex] : '';
|
|
387
|
-
return (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "(reverse-i-search)`" }), _jsx(Text, { children: rs.query }), _jsx(Text, { inverse: true, children: " " }), _jsx(Text, { dimColor: true, children: "`: " }), _jsx(Text, { color: matchText ?
|
|
361
|
+
return (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "(reverse-i-search)`" }), _jsx(Text, { children: rs.query }), _jsx(Text, { inverse: true, children: " " }), _jsx(Text, { dimColor: true, children: "`: " }), _jsx(Text, { color: matchText ? theme.status : 'red', children: matchText || '(无匹配 · Esc/Ctrl+G 取消)' })] }));
|
|
388
362
|
}
|
|
389
363
|
if (!value && placeholder) {
|
|
390
|
-
return (_jsxs(Text, { children: [_jsx(Text, { color:
|
|
364
|
+
return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: theme.userPrompt, children: prompt }), _jsx(Text, { inverse: true, children: " " }), _jsx(Text, { dimColor: true, children: placeholder })] }));
|
|
391
365
|
}
|
|
392
366
|
const before = value.slice(0, cursor);
|
|
393
367
|
const at = value.slice(cursor, cursor + 1);
|
|
394
368
|
const after = value.slice(cursor + 1);
|
|
395
|
-
return (_jsxs(Text, { children: [_jsx(Text, { color:
|
|
369
|
+
return (_jsxs(Text, { children: [_jsx(Text, { color: theme.userPrompt, children: prompt }), before, _jsx(Text, { inverse: true, children: at || ' ' }), after] }));
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* 生成 Ink 完成一帧输出后,将真实终端光标移回输入位置的 ANSI 序列。
|
|
373
|
+
*
|
|
374
|
+
* 只使用相对上移 + 绝对列定位,不假设输入框贴着终端底部。输入框靠近底部时,
|
|
375
|
+
* 候选窗显示在光标上方还是下方交给终端和操作系统决定。
|
|
376
|
+
*/
|
|
377
|
+
export function getCursorAnchorSequence(value, cursor, prompt, terminalColumns) {
|
|
378
|
+
const safeCursor = Math.max(0, Math.min(cursor, value.length));
|
|
379
|
+
// round 边框左右各 1 列,paddingX 左右各 1 列。
|
|
380
|
+
const contentColumns = Math.max(1, terminalColumns - 4);
|
|
381
|
+
const prefixPosition = measureVisualPosition(prompt + value.slice(0, safeCursor), contentColumns);
|
|
382
|
+
const cursorCell = value.slice(safeCursor)[0] ?? ' ';
|
|
383
|
+
const cursorPosition = normalizeCursorPosition(prefixPosition, terminalCellWidth(cursorCell), contentColumns);
|
|
384
|
+
// 光标在末尾时 TextInput 会额外绘制一个反色空格,它也参与自动换行和高度计算。
|
|
385
|
+
const renderedText = prompt + value + (safeCursor === value.length ? ' ' : '');
|
|
386
|
+
const endPosition = measureVisualPosition(renderedText, contentColumns);
|
|
387
|
+
const totalContentRows = endPosition.row + 1;
|
|
388
|
+
// Ink 的 log-update 会在整帧后追加换行,真实光标最终位于 HintBar 的下一行。
|
|
389
|
+
// 因此需要越过:追加换行后的空行 + HintBar + 输入框下边框 + 剩余内容行。
|
|
390
|
+
const rowsUp = 2 + totalContentRows - cursorPosition.row;
|
|
391
|
+
// 内容区从终端第 3 列开始:左边框 1 列 + 左 padding 1 列。
|
|
392
|
+
const absoluteColumn = 3 + cursorPosition.col;
|
|
393
|
+
return `\x1b[${rowsUp}A\x1b[${absoluteColumn}G`;
|
|
394
|
+
}
|
|
395
|
+
function measureVisualPosition(text, columns) {
|
|
396
|
+
const position = { row: 0, col: 0 };
|
|
397
|
+
for (const char of text) {
|
|
398
|
+
if (char === '\n') {
|
|
399
|
+
position.row++;
|
|
400
|
+
position.col = 0;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
const charWidth = terminalCellWidth(char);
|
|
404
|
+
if (charWidth === 0)
|
|
405
|
+
continue;
|
|
406
|
+
if (position.col > 0 && position.col + charWidth > columns) {
|
|
407
|
+
position.row++;
|
|
408
|
+
position.col = 0;
|
|
409
|
+
}
|
|
410
|
+
position.col += charWidth;
|
|
411
|
+
}
|
|
412
|
+
return position;
|
|
413
|
+
}
|
|
414
|
+
function normalizeCursorPosition(position, cursorCellWidth, columns) {
|
|
415
|
+
if (position.col >= columns || position.col + cursorCellWidth > columns) {
|
|
416
|
+
return { row: position.row + 1, col: 0 };
|
|
417
|
+
}
|
|
418
|
+
return position;
|
|
419
|
+
}
|
|
420
|
+
/** 计算终端单元格宽度(CJK / 全角字符和 emoji 通常占两列)。 */
|
|
421
|
+
export function terminalCellWidth(text) {
|
|
422
|
+
let width = 0;
|
|
423
|
+
for (const char of text) {
|
|
424
|
+
const code = char.codePointAt(0) ?? 0;
|
|
425
|
+
if (isCombiningMark(code) || code === 0x200d)
|
|
426
|
+
continue;
|
|
427
|
+
width += isWideCodePoint(code) ? 2 : 1;
|
|
428
|
+
}
|
|
429
|
+
return width;
|
|
430
|
+
}
|
|
431
|
+
function isCombiningMark(code) {
|
|
432
|
+
return ((code >= 0x0300 && code <= 0x036f) ||
|
|
433
|
+
(code >= 0x1ab0 && code <= 0x1aff) ||
|
|
434
|
+
(code >= 0x1dc0 && code <= 0x1dff) ||
|
|
435
|
+
(code >= 0x20d0 && code <= 0x20ff) ||
|
|
436
|
+
(code >= 0xfe20 && code <= 0xfe2f));
|
|
437
|
+
}
|
|
438
|
+
function isWideCodePoint(code) {
|
|
439
|
+
return ((code >= 0x1100 && code <= 0x115f) ||
|
|
440
|
+
(code >= 0x2329 && code <= 0x232a) ||
|
|
441
|
+
(code >= 0x2e80 && code <= 0xa4cf) ||
|
|
442
|
+
(code >= 0xac00 && code <= 0xd7a3) ||
|
|
443
|
+
(code >= 0xf900 && code <= 0xfaff) ||
|
|
444
|
+
(code >= 0xfe10 && code <= 0xfe19) ||
|
|
445
|
+
(code >= 0xfe30 && code <= 0xfe6f) ||
|
|
446
|
+
(code >= 0xff00 && code <= 0xff60) ||
|
|
447
|
+
(code >= 0xffe0 && code <= 0xffe6) ||
|
|
448
|
+
(code >= 0x1f300 && code <= 0x1faff) ||
|
|
449
|
+
(code >= 0x20000 && code <= 0x3fffd));
|
|
396
450
|
}
|
|
397
451
|
function getLineInfo(value, cursor) {
|
|
398
452
|
let lineStart = 0;
|