kcode-pi 0.1.30 → 0.1.31
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/extensions/kingdee-header.ts +93 -9
- package/package.json +1 -1
|
@@ -4,6 +4,96 @@ import { readActiveRun } from "../src/harness/state.ts";
|
|
|
4
4
|
import type { ActiveRun, GateResult } from "../src/harness/types.ts";
|
|
5
5
|
import { formatProductProfile } from "../src/product/profile.ts";
|
|
6
6
|
|
|
7
|
+
/** ANSI escape sequence pattern: CSI, OSC, APC. */
|
|
8
|
+
const ANSI_RE = /\x1b\[[0-9;]*[A-Za-z]|\x1b\][^\x07]*\x07|\x1b_[^\x1b]*\x1b\\/g;
|
|
9
|
+
|
|
10
|
+
/** Visible width of a string (strips ANSI codes; CJK/wide chars = 2 columns). */
|
|
11
|
+
function visibleWidth(str: string): number {
|
|
12
|
+
let width = 0;
|
|
13
|
+
const clean = str.replace(ANSI_RE, "");
|
|
14
|
+
for (const ch of clean) {
|
|
15
|
+
const code = ch.codePointAt(0)!;
|
|
16
|
+
width +=
|
|
17
|
+
code >= 0x1100 &&
|
|
18
|
+
!(code >= 0x00a0 && code <= 0x00ff) &&
|
|
19
|
+
((code >= 0x1100 && code <= 0x115f) ||
|
|
20
|
+
(code >= 0x2329 && code <= 0x232a) ||
|
|
21
|
+
(code >= 0x2e80 && code <= 0x303e) ||
|
|
22
|
+
(code >= 0x3040 && code <= 0x3247) ||
|
|
23
|
+
(code >= 0x3250 && code <= 0x4dbf) ||
|
|
24
|
+
(code >= 0x4e00 && code <= 0xa4c6) ||
|
|
25
|
+
(code >= 0xa960 && code <= 0xa97c) ||
|
|
26
|
+
(code >= 0xac00 && code <= 0xd7a3) ||
|
|
27
|
+
(code >= 0xf900 && code <= 0xfaff) ||
|
|
28
|
+
(code >= 0xfe10 && code <= 0xfe19) ||
|
|
29
|
+
(code >= 0xfe30 && code <= 0xfe6b) ||
|
|
30
|
+
(code >= 0xff01 && code <= 0xff60) ||
|
|
31
|
+
(code >= 0xffe0 && code <= 0xffe6) ||
|
|
32
|
+
(code >= 0x1f300 && code <= 0x1f9ff) ||
|
|
33
|
+
(code >= 0x20000 && code <= 0x2fffd))
|
|
34
|
+
? 2
|
|
35
|
+
: 1;
|
|
36
|
+
}
|
|
37
|
+
return width;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* If the line's visible width exceeds `maxWidth`, truncate visible characters
|
|
42
|
+
* and append `>` so the result fits. Preserves ANSI codes in the kept portion
|
|
43
|
+
* and appends SGR reset before the `>`. No padding — pi-tui only requires
|
|
44
|
+
* visibleWidth <= width.
|
|
45
|
+
*/
|
|
46
|
+
function clipLine(text: string, maxWidth: number): string {
|
|
47
|
+
if (maxWidth <= 0) return "";
|
|
48
|
+
const vw = visibleWidth(text);
|
|
49
|
+
if (vw <= maxWidth) return text;
|
|
50
|
+
|
|
51
|
+
const targetW = maxWidth - 1; // reserve 1 col for ">"
|
|
52
|
+
let result = "";
|
|
53
|
+
let visibleSoFar = 0;
|
|
54
|
+
let i = 0;
|
|
55
|
+
|
|
56
|
+
while (i < text.length && visibleSoFar < targetW) {
|
|
57
|
+
// Preserve ANSI escape sequences
|
|
58
|
+
if (text[i] === "\x1b") {
|
|
59
|
+
const m = text.slice(i).match(/^(?:\[[0-9;]*[A-Za-z]|\][^\x07]*\x07|_[^\x1b]*\x1b\\)/);
|
|
60
|
+
if (m) {
|
|
61
|
+
result += m[0];
|
|
62
|
+
i += m[0].length;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const ch = text[i];
|
|
68
|
+
const code = ch.codePointAt(0)!;
|
|
69
|
+
const wide =
|
|
70
|
+
(code >= 0x1100 && code <= 0x115f) ||
|
|
71
|
+
(code >= 0x2329 && code <= 0x232a) ||
|
|
72
|
+
(code >= 0x2e80 && code <= 0x303e) ||
|
|
73
|
+
(code >= 0x3040 && code <= 0x3247) ||
|
|
74
|
+
(code >= 0x3250 && code <= 0x4dbf) ||
|
|
75
|
+
(code >= 0x4e00 && code <= 0xa4c6) ||
|
|
76
|
+
(code >= 0xa960 && code <= 0xa97c) ||
|
|
77
|
+
(code >= 0xac00 && code <= 0xd7a3) ||
|
|
78
|
+
(code >= 0xf900 && code <= 0xfaff) ||
|
|
79
|
+
(code >= 0xfe10 && code <= 0xfe19) ||
|
|
80
|
+
(code >= 0xfe30 && code <= 0xfe6b) ||
|
|
81
|
+
(code >= 0xff01 && code <= 0xff60) ||
|
|
82
|
+
(code >= 0xffe0 && code <= 0xffe6) ||
|
|
83
|
+
(code >= 0x1f300 && code <= 0x1f9ff) ||
|
|
84
|
+
(code >= 0x20000 && code <= 0x2fffd);
|
|
85
|
+
const charW = wide ? 2 : 1;
|
|
86
|
+
|
|
87
|
+
if (visibleSoFar + charW > targetW) break;
|
|
88
|
+
|
|
89
|
+
result += ch;
|
|
90
|
+
visibleSoFar += charW;
|
|
91
|
+
i++;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return result + "\x1b[0m>";
|
|
95
|
+
}
|
|
96
|
+
|
|
7
97
|
function formatProduct(run: ActiveRun | undefined): string {
|
|
8
98
|
if (!run) return "未选择";
|
|
9
99
|
if (run.profile?.product === "unknown") return "未确认";
|
|
@@ -43,12 +133,6 @@ function riskColor(risk: string): "error" | "warning" | "muted" | "success" {
|
|
|
43
133
|
return "success";
|
|
44
134
|
}
|
|
45
135
|
|
|
46
|
-
function padOrTrim(text: string, width: number): string {
|
|
47
|
-
if (width <= 0) return "";
|
|
48
|
-
if (text.length > width) return text.slice(0, Math.max(0, width - 1)) + ">";
|
|
49
|
-
return text + " ".repeat(width - text.length);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
136
|
function logoLines(theme: Theme): string[] {
|
|
53
137
|
const accent = (text: string) => theme.fg("accent", text);
|
|
54
138
|
const muted = (text: string) => theme.fg("muted", text);
|
|
@@ -87,9 +171,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
87
171
|
|
|
88
172
|
return [
|
|
89
173
|
"",
|
|
90
|
-
...logoLines(theme).map((line) =>
|
|
91
|
-
|
|
92
|
-
|
|
174
|
+
...logoLines(theme).map((line) => clipLine(line, width)),
|
|
175
|
+
clipLine(status, width),
|
|
176
|
+
clipLine(theme.fg("dim", `run:${runId}`), width),
|
|
93
177
|
"",
|
|
94
178
|
];
|
|
95
179
|
},
|