@xiaoqiong0v0/opencode-ssh-tool 0.3.0 → 0.5.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.
- package/README.md +30 -24
- package/dist/base-session.d.ts +128 -0
- package/dist/base-session.d.ts.map +1 -0
- package/dist/base-session.js +414 -0
- package/dist/base-session.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +27 -3
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +28 -3
- package/dist/constants.js.map +1 -1
- package/dist/history.d.ts +14 -5
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +25 -9
- package/dist/history.js.map +1 -1
- package/dist/i18n.d.ts +249 -196
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +171 -180
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +320 -332
- package/dist/index.js.map +1 -1
- package/dist/last-match.d.ts +17 -0
- package/dist/last-match.d.ts.map +1 -0
- package/dist/last-match.js +63 -0
- package/dist/last-match.js.map +1 -0
- package/dist/local-session.d.ts +9 -91
- package/dist/local-session.d.ts.map +1 -1
- package/dist/local-session.js +46 -308
- package/dist/local-session.js.map +1 -1
- package/dist/log.d.ts +3 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +5 -0
- package/dist/log.js.map +1 -0
- package/dist/server-manager.d.ts +3 -1
- package/dist/server-manager.d.ts.map +1 -1
- package/dist/server-manager.js +3 -2
- package/dist/server-manager.js.map +1 -1
- package/dist/server.d.ts +35 -6
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +362 -305
- package/dist/server.js.map +1 -1
- package/dist/session-store.d.ts +2 -0
- package/dist/session-store.d.ts.map +1 -1
- package/dist/session-store.js +15 -0
- package/dist/session-store.js.map +1 -1
- package/dist/session.d.ts +15 -108
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +69 -361
- package/dist/session.js.map +1 -1
- package/dist/shell-adapter.d.ts +20 -0
- package/dist/shell-adapter.d.ts.map +1 -0
- package/dist/shell-adapter.js +70 -0
- package/dist/shell-adapter.js.map +1 -0
- package/dist/ssh-auth.d.ts.map +1 -1
- package/dist/ssh-auth.js +1 -2
- package/dist/ssh-auth.js.map +1 -1
- package/dist/utils.d.ts +25 -24
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +277 -45
- package/dist/utils.js.map +1 -1
- package/dist/web/app.css +35 -0
- package/dist/web/app.js +2 -0
- package/dist/web/fonts/CaskaydiaCoveNerdFontMono-Regular.ttf +0 -0
- package/dist/web/index.html +24 -0
- package/package.json +8 -4
package/dist/utils.d.ts
CHANGED
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* 定位命令回显行在原始流中的结束位置(供流式增量定位使用):
|
|
3
|
+
* 丢弃窗口开头到"命令回显行结束"之前的一切内容(提示符、PS1 填充、光标定位噪音均在内)。
|
|
4
|
+
* 命令回显行 = 命令文本首次出现所在行(命令本身可能含 \033 等转义)。
|
|
5
|
+
* @param raw 原始终端流(含 ANSI)
|
|
6
|
+
* @param command 本次执行的命令文本
|
|
7
|
+
* @returns 命令回显结束后的字节偏移;未命中命令文本返回 0(此时应视作输出尚未开始)
|
|
4
8
|
*/
|
|
5
|
-
export declare function
|
|
9
|
+
export declare function extractOutputStart(raw: string, command: string): number;
|
|
6
10
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* 剥离"提示符 + 命令回显",只保留程序纯输出:
|
|
12
|
+
* shell 提示符(含背景填充、zle 重绘序列)依赖其自身终端屏幕状态,字节流脱离该状态无法忠实还原,
|
|
13
|
+
* 故丢弃窗口开头到"命令回显行结束"之前的一切内容(提示符、PS1 填充、光标定位噪音均在内)。
|
|
14
|
+
* 命令回显行 = 命令文本首次出现所在行(命令本身可能含 \033 等转义)。
|
|
15
|
+
* 命中后切到"命令文本结束处":zsh 下程序输出可能直接粘连在回显尾(无换行),不能按换行截断。
|
|
16
|
+
* @param raw 原始终端流(含 ANSI)
|
|
17
|
+
* @param command 本次执行的命令文本
|
|
18
|
+
* @returns 纯程序输出原始流(保留程序自身的 ANSI 颜色/进度条,供 web TermScreen 与模型 toModelText)
|
|
12
19
|
*/
|
|
13
|
-
export declare function
|
|
20
|
+
export declare function extractOutput(raw: string, command: string): string;
|
|
14
21
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
22
|
+
* 把原始终端流转为给模型看的干净文本:模拟终端屏幕(处理光标移动/清行/覆盖/退格/SGR/OSC),
|
|
23
|
+
* 输出最终屏幕各行文本,再逐行去尾空白并剔除空行。比纯文本正则更鲁棒地处理 PSReadLine
|
|
24
|
+
* 行内重绘、进度条 \r 覆盖等场景。
|
|
25
|
+
* @param raw 原始终端流(含 ANSI)
|
|
26
|
+
* @returns 纯文本输出(供模型消费 / exec 返回值 / read 命令)
|
|
18
27
|
*/
|
|
19
|
-
export declare function
|
|
28
|
+
export declare function toModelText(raw: string): string;
|
|
20
29
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @param s 原始输出(含 ANSI 或已清洗均可)
|
|
25
|
-
* @returns 合并覆盖后的文本(\r\n 正常换行保留)
|
|
26
|
-
*/
|
|
27
|
-
export declare function collapseCarriage(s: string): string;
|
|
28
|
-
/**
|
|
29
|
-
* 剥离尾部 shell 提示符残留(如 "5cb08b77db01:~$ "、"user@host:~/dir$ "、"root@server:/etc#")
|
|
30
|
-
* @param s 清洗后文本
|
|
31
|
-
* @returns 剥离尾部提示符后的文本
|
|
30
|
+
* 末尾空白清理(原为提示符剥离,现仅做清理,不依赖正则匹配具体提示符形状)
|
|
31
|
+
* @param s 文本
|
|
32
|
+
* @returns 清理后文本
|
|
32
33
|
*/
|
|
33
34
|
export declare function stripPrompt(s: string): string;
|
|
34
35
|
/**
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAWA;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAWvE;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIlE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO/C;AAgJD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAI1C"}
|
package/dist/utils.js
CHANGED
|
@@ -1,63 +1,295 @@
|
|
|
1
|
-
//
|
|
2
|
-
import {
|
|
1
|
+
// 工具函数:命令回显定位、模型文本清理、ANSI 清洗、CR 覆盖合并、完成标记剥离
|
|
2
|
+
import { stripMarkers } from "./shell-adapter.js";
|
|
3
|
+
import { findLastEndOf } from "./last-match.js";
|
|
4
|
+
/** 正则转义文本 */
|
|
5
|
+
const escRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6
|
+
/** 命令回显匹配的宽松字符间隙(ANSI 序列或普通空白/换行,可插在命令字符之间;容忍终端列宽自动换行) */
|
|
7
|
+
const ECHO_WIDE = "(?:\\x1b\\[[0-9;?]*[a-zA-Z]|\\x1b\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)|\\x1b[^\\x1b]|[ \\t\\r\\n])*";
|
|
3
8
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
9
|
+
* 定位命令回显行在原始流中的结束位置(供流式增量定位使用):
|
|
10
|
+
* 丢弃窗口开头到"命令回显行结束"之前的一切内容(提示符、PS1 填充、光标定位噪音均在内)。
|
|
11
|
+
* 命令回显行 = 命令文本首次出现所在行(命令本身可能含 \033 等转义)。
|
|
12
|
+
* @param raw 原始终端流(含 ANSI)
|
|
13
|
+
* @param command 本次执行的命令文本
|
|
14
|
+
* @returns 命令回显结束后的字节偏移;未命中命令文本返回 0(此时应视作输出尚未开始)
|
|
6
15
|
*/
|
|
7
|
-
export function
|
|
8
|
-
|
|
16
|
+
export function extractOutputStart(raw, command) {
|
|
17
|
+
const cmd = command.trim();
|
|
18
|
+
if (!cmd)
|
|
19
|
+
return 0;
|
|
20
|
+
// 单条宽松正则一次性匹配命令回显(命令文本 + 字符间 ANSI 间隙):
|
|
21
|
+
// 1) 字符间容忍 ANSI 间隙(WIDE)2) 命令字面 \033 回显可能变真实 ESC(二选一)
|
|
22
|
+
const norm = cmd.replace(/\\033/gi, "\x1b");
|
|
23
|
+
const frags = [...norm].map((c) => (c === "\x1b" ? "(?:\\x1b|\\\\033)" : escRe(c)));
|
|
24
|
+
const re = new RegExp(frags.join(ECHO_WIDE), "g");
|
|
25
|
+
// 取最后一次匹配:备屏退出(如 cmatrix)会重放主屏历史,其中含旧命令回显,
|
|
26
|
+
// 只有最后一次出现的回显之后才是本次命令的真实输出
|
|
27
|
+
return findLastEndOf(re, raw);
|
|
9
28
|
}
|
|
10
29
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
30
|
+
* 剥离"提示符 + 命令回显",只保留程序纯输出:
|
|
31
|
+
* shell 提示符(含背景填充、zle 重绘序列)依赖其自身终端屏幕状态,字节流脱离该状态无法忠实还原,
|
|
32
|
+
* 故丢弃窗口开头到"命令回显行结束"之前的一切内容(提示符、PS1 填充、光标定位噪音均在内)。
|
|
33
|
+
* 命令回显行 = 命令文本首次出现所在行(命令本身可能含 \033 等转义)。
|
|
34
|
+
* 命中后切到"命令文本结束处":zsh 下程序输出可能直接粘连在回显尾(无换行),不能按换行截断。
|
|
35
|
+
* @param raw 原始终端流(含 ANSI)
|
|
36
|
+
* @param command 本次执行的命令文本
|
|
37
|
+
* @returns 纯程序输出原始流(保留程序自身的 ANSI 颜色/进度条,供 web TermScreen 与模型 toModelText)
|
|
16
38
|
*/
|
|
17
|
-
export function
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
39
|
+
export function extractOutput(raw, command) {
|
|
40
|
+
const end = extractOutputStart(raw, command);
|
|
41
|
+
if (end <= 0)
|
|
42
|
+
return raw;
|
|
43
|
+
return raw.slice(end).replace(/^[\r\n]+/, "");
|
|
21
44
|
}
|
|
22
45
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
46
|
+
* 把原始终端流转为给模型看的干净文本:模拟终端屏幕(处理光标移动/清行/覆盖/退格/SGR/OSC),
|
|
47
|
+
* 输出最终屏幕各行文本,再逐行去尾空白并剔除空行。比纯文本正则更鲁棒地处理 PSReadLine
|
|
48
|
+
* 行内重绘、进度条 \r 覆盖等场景。
|
|
49
|
+
* @param raw 原始终端流(含 ANSI)
|
|
50
|
+
* @returns 纯文本输出(供模型消费 / exec 返回值 / read 命令)
|
|
26
51
|
*/
|
|
27
|
-
export function
|
|
28
|
-
|
|
29
|
-
return
|
|
52
|
+
export function toModelText(raw) {
|
|
53
|
+
const screen = simulateScreen(stripMarkers(raw));
|
|
54
|
+
return screen
|
|
55
|
+
.split(/\r?\n/)
|
|
56
|
+
.map((l) => l.replace(/\r/g, "").trimEnd())
|
|
57
|
+
.filter((l) => l !== "")
|
|
58
|
+
.join("\n");
|
|
30
59
|
}
|
|
31
60
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* @
|
|
36
|
-
* @returns 合并覆盖后的文本(\r\n 正常换行保留)
|
|
61
|
+
* 模拟终端屏幕渲染:处理 ANSI 光标/清行/清屏/退格/覆盖,输出最终各行的文本。
|
|
62
|
+
* 不保留颜色/SGR,仅提取各行已写字符的最右列,确保最终屏幕文本与真实终端显示一致。
|
|
63
|
+
* @param s 原始字节流(含 ANSI、\b、\r 等)
|
|
64
|
+
* @returns 按行拼接的纯文本(行间 \n 分隔,行内保留空格)
|
|
37
65
|
*/
|
|
38
|
-
|
|
39
|
-
//
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
function simulateScreen(s) {
|
|
67
|
+
// 网格:每行 { maxCol: 已写最右列, cols: Map<col, char> }
|
|
68
|
+
const rows = [];
|
|
69
|
+
let r = 0; // 当前行
|
|
70
|
+
let c = 0; // 当前列
|
|
71
|
+
let sr = 0; // 保存的光标行(ESC 7 / CSI s)
|
|
72
|
+
let sc = 0; // 保存的光标列
|
|
73
|
+
let altRows = null; // 备屏保存(CSI ?1049h/l)
|
|
74
|
+
const COLS = 240; // 足够宽
|
|
75
|
+
const row = (i) => {
|
|
76
|
+
while (rows.length <= i)
|
|
77
|
+
rows.push({ maxCol: 0, cols: new Map() });
|
|
78
|
+
return rows[i];
|
|
79
|
+
};
|
|
80
|
+
const put = (ch) => {
|
|
81
|
+
const cur = row(r);
|
|
82
|
+
if (c < COLS) {
|
|
83
|
+
cur.cols.set(c, ch);
|
|
84
|
+
if (c >= cur.maxCol)
|
|
85
|
+
cur.maxCol = c + 1;
|
|
86
|
+
}
|
|
87
|
+
c++;
|
|
88
|
+
};
|
|
89
|
+
let i = 0;
|
|
90
|
+
const n = s.length;
|
|
91
|
+
while (i < n) {
|
|
92
|
+
const ch = s[i];
|
|
93
|
+
if (ch === "\x1b") {
|
|
94
|
+
// OSC: ESC ] ... BEL/ESC\ — 整段丢弃
|
|
95
|
+
if (i + 1 < n && s[i + 1] === "]") {
|
|
96
|
+
let j = i + 2;
|
|
97
|
+
while (j < n && s[j] !== "\x07" && !(s[j] === "\x1b" && j + 1 < n && s[j + 1] === "\\"))
|
|
98
|
+
j++;
|
|
99
|
+
if (j >= n)
|
|
100
|
+
break;
|
|
101
|
+
i = s[j] === "\x07" ? j + 1 : j + 2;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// CSI: ESC [ params... final
|
|
105
|
+
if (i + 1 < n && s[i + 1] === "[") {
|
|
106
|
+
let j = i + 2;
|
|
107
|
+
const start = j;
|
|
108
|
+
while (j < n && !/[A-Za-z@]/.test(s[j]))
|
|
109
|
+
j++;
|
|
110
|
+
if (j >= n)
|
|
111
|
+
break;
|
|
112
|
+
const body = s.slice(start, j);
|
|
113
|
+
const final = s[j];
|
|
114
|
+
const p = (d) => { const v = parseInt(d, 10); return Number.isFinite(v) && v > 0 ? v : 1; };
|
|
115
|
+
const va = (d) => { const v = parseInt(d, 10); return Number.isFinite(v) && v >= 0 ? v : 0; };
|
|
116
|
+
if (final === "m") {
|
|
117
|
+
// SGR:忽略颜色
|
|
118
|
+
}
|
|
119
|
+
else if (final === "A") {
|
|
120
|
+
r = Math.max(0, r - p(body));
|
|
121
|
+
}
|
|
122
|
+
else if (final === "B") {
|
|
123
|
+
r += p(body);
|
|
124
|
+
}
|
|
125
|
+
else if (final === "C") {
|
|
126
|
+
c = Math.min(COLS - 1, c + p(body));
|
|
127
|
+
}
|
|
128
|
+
else if (final === "D") {
|
|
129
|
+
c = Math.max(0, c - p(body));
|
|
130
|
+
}
|
|
131
|
+
else if (final === "H" || final === "f") {
|
|
132
|
+
const m = body.split(";");
|
|
133
|
+
r = Math.max(0, (p(m[0]) - 1));
|
|
134
|
+
c = Math.max(0, (p(m[1]) - 1));
|
|
135
|
+
}
|
|
136
|
+
else if (final === "G" || final.charCodeAt(0) === 96) {
|
|
137
|
+
c = Math.max(0, p(body) - 1);
|
|
138
|
+
}
|
|
139
|
+
else if (final === "d") {
|
|
140
|
+
r = Math.max(0, p(body) - 1);
|
|
141
|
+
}
|
|
142
|
+
else if (final === "s") {
|
|
143
|
+
sr = r;
|
|
144
|
+
sc = c;
|
|
145
|
+
}
|
|
146
|
+
else if (final === "u") {
|
|
147
|
+
r = Math.min(sr, rows.length - 1);
|
|
148
|
+
c = sc;
|
|
149
|
+
}
|
|
150
|
+
else if (final === "h" && body.startsWith("?")) {
|
|
151
|
+
// 私有模式 set:?1049h 进入备屏(保存主屏+光标,清屏)
|
|
152
|
+
if (va(body.slice(1)) === 1049) {
|
|
153
|
+
altRows = rows.map((x) => ({ maxCol: x.maxCol, cols: new Map(x.cols) }));
|
|
154
|
+
sr = r;
|
|
155
|
+
sc = c;
|
|
156
|
+
rows.length = 0;
|
|
157
|
+
r = 0;
|
|
158
|
+
c = 0;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else if (final === "l" && body.startsWith("?")) {
|
|
162
|
+
// 私有模式 reset:?1049l 退出备屏(恢复主屏+光标)
|
|
163
|
+
if (va(body.slice(1)) === 1049 && altRows) {
|
|
164
|
+
rows.length = 0;
|
|
165
|
+
rows.push(...altRows);
|
|
166
|
+
altRows = null;
|
|
167
|
+
r = Math.min(sr, rows.length - 1);
|
|
168
|
+
c = sc;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (final === "K") {
|
|
172
|
+
const mode = va(body);
|
|
173
|
+
const curRow = row(r);
|
|
174
|
+
if (mode === 2) {
|
|
175
|
+
curRow.cols.clear();
|
|
176
|
+
curRow.maxCol = 0;
|
|
177
|
+
}
|
|
178
|
+
else if (mode === 1) {
|
|
179
|
+
for (let ci = 0; ci <= c; ci++) {
|
|
180
|
+
curRow.cols.delete(ci);
|
|
181
|
+
}
|
|
182
|
+
;
|
|
183
|
+
curRow.maxCol = 0;
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
for (let ci = c; ci < COLS; ci++) {
|
|
187
|
+
curRow.cols.delete(ci);
|
|
188
|
+
}
|
|
189
|
+
;
|
|
190
|
+
curRow.maxCol = Math.min(curRow.maxCol, c);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else if (final === "J") {
|
|
194
|
+
const mode = va(body);
|
|
195
|
+
if (mode === 2 || mode === 3) {
|
|
196
|
+
rows.length = 0;
|
|
197
|
+
r = 0;
|
|
198
|
+
c = 0;
|
|
199
|
+
}
|
|
200
|
+
else if (mode === 1) {
|
|
201
|
+
rows.length = 0;
|
|
202
|
+
r = 0;
|
|
203
|
+
c = 0;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
const cur = row(r);
|
|
207
|
+
for (let ci = c; ci < COLS; ci++)
|
|
208
|
+
cur.cols.delete(ci);
|
|
209
|
+
cur.maxCol = Math.min(cur.maxCol, c);
|
|
210
|
+
rows.length = r + 1;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// 其余 CSI(滚动/插入/删除等)忽略
|
|
214
|
+
i = j + 1;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// ESC 7 保存光标 / ESC 8 恢复光标
|
|
218
|
+
if (s[i + 1] === "7") {
|
|
219
|
+
sr = r;
|
|
220
|
+
sc = c;
|
|
221
|
+
i += 2;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (s[i + 1] === "8") {
|
|
225
|
+
r = Math.min(sr, rows.length - 1);
|
|
226
|
+
c = sc;
|
|
227
|
+
i += 2;
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
// 其他 ESC 序列忽略
|
|
231
|
+
i += 2;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (ch === "\r") {
|
|
235
|
+
c = 0;
|
|
236
|
+
i++;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (ch === "\n") {
|
|
240
|
+
r++;
|
|
241
|
+
c = 0;
|
|
242
|
+
i++;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (ch === "\b") {
|
|
246
|
+
if (c > 0)
|
|
247
|
+
c--;
|
|
248
|
+
i++;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (ch === "\t") {
|
|
252
|
+
const next = (Math.floor(c / 8) + 1) * 8;
|
|
253
|
+
if (next >= COLS) {
|
|
254
|
+
r++;
|
|
255
|
+
c = 0;
|
|
256
|
+
}
|
|
257
|
+
else
|
|
258
|
+
c = next;
|
|
259
|
+
i++;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
// 其他控制字符(\x07 BEL 等)跳过
|
|
263
|
+
if (ch.charCodeAt(0) < 32) {
|
|
264
|
+
i++;
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
put(ch);
|
|
268
|
+
i++;
|
|
269
|
+
}
|
|
270
|
+
// 构建输出行
|
|
271
|
+
const lines = [];
|
|
272
|
+
for (let ri = 0; ri < rows.length; ri++) {
|
|
273
|
+
const cur = rows[ri];
|
|
274
|
+
if (cur.maxCol === 0) {
|
|
275
|
+
lines.push("");
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
let line = "";
|
|
279
|
+
for (let ci = 0; ci < cur.maxCol; ci++) {
|
|
280
|
+
line += cur.cols.get(ci) ?? " ";
|
|
281
|
+
}
|
|
282
|
+
lines.push(line);
|
|
283
|
+
}
|
|
284
|
+
return lines.join("\n");
|
|
51
285
|
}
|
|
52
286
|
/**
|
|
53
|
-
*
|
|
54
|
-
* @param s
|
|
55
|
-
* @returns
|
|
287
|
+
* 末尾空白清理(原为提示符剥离,现仅做清理,不依赖正则匹配具体提示符形状)
|
|
288
|
+
* @param s 文本
|
|
289
|
+
* @returns 清理后文本
|
|
56
290
|
*/
|
|
57
291
|
export function stripPrompt(s) {
|
|
58
|
-
return s
|
|
59
|
-
.replace(/(?:^|[\r\n])\s*(?:[\w.-]+@)?[\w.-]+:[^\r\n]*[$#%] ?(?=[\r\n]|$)/g, "")
|
|
60
|
-
.trim();
|
|
292
|
+
return s.trimEnd();
|
|
61
293
|
}
|
|
62
294
|
/**
|
|
63
295
|
* 时间戳格式化为 yyyy-MM-dd HH:mm:ss
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AAEvC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,cAAc,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAA;AACzD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,GAAW;IAChD,MAAM,aAAa,GAAG,wBAAwB,CAAA;IAC9C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IACjF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC3G,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,4CAA4C;IAC5C,OAAO,CAAC,CAAC,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAA;AACvF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAS;IACxC,kDAAkD;IAClD,MAAM,SAAS,GAAG,qBAAqB,CAAA;IACvC,2CAA2C;IAC3C,OAAO,CAAC;SACL,KAAK,CAAC,MAAM,CAAC;SACb,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAA;QAC9D,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC9B,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,CAAC;SACL,OAAO,CAAC,kEAAkE,EAAE,EAAE,CAAC;SAC/E,IAAI,EAAE,CAAA;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,EAAU;IAChC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAA;IACtB,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACnD,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,CAAA;AACnI,CAAC"}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/dist/web/app.css
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@font-face {
|
|
2
|
+
font-family: "CaskaydiaCove Nerd Font Mono";
|
|
3
|
+
src: url("/web/fonts/CaskaydiaCoveNerdFontMono-Regular.ttf") format("truetype");
|
|
4
|
+
font-display: swap;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
html, body { margin: 0; height: 100%; background: #0d1117; color: #c9d1d9; font-family: system-ui, sans-serif; }
|
|
8
|
+
header { position: sticky; top: 0; display: flex; align-items: center; gap: 12px; padding: 10px 16px; background: #161b22; border-bottom: 1px solid #30363d; }
|
|
9
|
+
header h1 { margin: 0; font-size: 14px; color: #e6edf3; font-weight: 600; }
|
|
10
|
+
select { background: #21262d; color: #c9d1d9; border: 1px solid #30363d; padding: 4px 8px; border-radius: 6px; }
|
|
11
|
+
pre { margin: 0; padding: 16px; font-family: "CaskaydiaCove Nerd Font Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", "Noto Sans Mono", "Hack", Consolas, "Courier New", monospace; font-size: 13px; line-height: 1.5; white-space: pre-wrap; overflow: auto; height: calc(100% - 52px); box-sizing: border-box; color: #c9d1d9; }
|
|
12
|
+
.row { display: flex; align-items: stretch; }
|
|
13
|
+
.row .t { box-sizing: border-box; flex: 0 0 172px; color: #8b949e; padding: 0 10px 0 6px; border-right: 1px solid #30363d; white-space: pre; }
|
|
14
|
+
.row .c { flex: 1; padding-left: 12px; white-space: pre; }
|
|
15
|
+
body:not(.show-time) .row .t { display: none; }
|
|
16
|
+
.row.cmdline { background: #161b22; box-shadow: inset 3px 0 0 #58a6ff; font-weight: 600; }
|
|
17
|
+
.tgl { font-size: 12px; color: #8b949e; display: flex; align-items: center; gap: 4px; white-space: nowrap; }
|
|
18
|
+
#meta { font-size: 12px; color: #8b949e; }
|
|
19
|
+
::-webkit-scrollbar { width: 10px; height: 10px; }
|
|
20
|
+
::-webkit-scrollbar-track { background: #161b22; }
|
|
21
|
+
::-webkit-scrollbar-thumb { background: #30363d; border-radius: 5px; border: 2px solid #161b22; }
|
|
22
|
+
::-webkit-scrollbar-thumb:hover { background: #484f58; }
|
|
23
|
+
::-webkit-scrollbar-corner { background: #161b22; }
|
|
24
|
+
* { scrollbar-width: thin; scrollbar-color: #30363d #161b22; }
|
|
25
|
+
.to-bottom-btn {
|
|
26
|
+
position: fixed; right: 24px; bottom: 24px; display: none;
|
|
27
|
+
background: #238636; color: #fff; border: none; border-radius: 20px;
|
|
28
|
+
padding: 8px 16px; font-size: 13px; cursor: pointer; z-index: 10;
|
|
29
|
+
box-shadow: 0 4px 12px rgba(0,0,0,.4);
|
|
30
|
+
}
|
|
31
|
+
.to-bottom-btn:hover { background: #2ea043; }
|
|
32
|
+
.sep hr { border: none; border-top: 1px dashed #30363d; margin: 8px 0; }
|
|
33
|
+
.del-btn { background: none; border: 1px solid #30363d; color: #f85149; border-radius: 4px; cursor: pointer; padding: 2px 8px; font-size: 14px; line-height: 1; display: none; }
|
|
34
|
+
.del-btn:hover { background: #f85149; color: #fff; }
|
|
35
|
+
.del-btn.show { display: inline-block; }
|
package/dist/web/app.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";(()=>{var x=Object.defineProperty;var G=(n,e,t)=>e in n?x(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var m=(n,e,t)=>G(n,typeof e!="symbol"?e+"":e,t);function j(n){let e=n.match(H);if(e&&e.length>0){let t=parseInt(e[e.length-1].replace(/<SSH_DONE:|>/g,""),10);return{text:n.replace(H,""),exitCode:isNaN(t)?void 0:t}}return{text:n}}var E=window.__I18N__,v=window.__PTY_COLS__||120,k=["#010101","#de382b","#39b54a","#ffc005","#006fb8","#762671","#2cb3e9","#c9d1d9"],_=["#666666","#ff7b72","#3fb950","#d29922","#58a6ff","#bc8cff","#39c5cf","#f0f6fc"],w=class{constructor(e){m(this,"cols");m(this,"grid",[]);m(this,"r",0);m(this,"c",0);m(this,"fg",null);m(this,"bg",null);m(this,"bold",!1);m(this,"sr",0);m(this,"sc",0);m(this,"altGrid",null);this.cols=e}_row(e){for(;this.grid.length<=e;){let t=[];for(let i=0;i<this.cols;i++)t.push({ch:" ",fg:null,bg:null,bold:!1});this.grid.push(t)}return this.grid[e]}_put(e){let t=this._row(this.r);t[this.c]={ch:e,fg:this.fg,bg:this.bg,bold:this.bold},this.c++,this.c>=this.cols&&(this.c=0,this.r++)}write(e){let t=0,i=e.length;for(;t<i;){let r=e[t];if(r==="\x1B"){if(t+1<i&&e[t+1]==="]"){let l=t+2;for(;l<i&&e[l]!=="\x07"&&!(e[l]==="\x1B"&&e[l+1]==="\\");)l++;if(l>=i)break;t=e[l]==="\x07"?l+1:l+2;continue}if(t+1<i&&e[t+1]==="["){let l=t+2,o=l;for(;l<i&&!/[A-Za-z@]/.test(e[l]);)l++;if(l>=i)break;this._csi(e.slice(o,l),e[l]),t=l+1;continue}if(e[t+1]==="7"){this.sr=this.r,this.sc=this.c,t+=2;continue}if(e[t+1]==="8"){this.r=Math.min(this.sr,this.grid.length-1),this.c=this.sc,t+=2;continue}t+=2;continue}if(r==="\r"){this.c=0,t++;continue}if(r===`
|
|
2
|
+
`){this.r++,this.c=0,t++;continue}if(r==="\b"){this.c>0&&this.c--,t++;continue}if(r===" "){this.c=(Math.floor(this.c/8)+1)*8,this.c>=this.cols&&(this.c=0,this.r++),t++;continue}if(r.charCodeAt(0)<32){t++;continue}this._put(r),t++}}_csi(e,t){let i=e.replace(/^[?]/,"");if(t==="m"){let o=i?i.split(";").map(s=>parseInt(s,10)):[0];(!i||o.indexOf(0)>=0)&&(this.fg=null,this.bg=null,this.bold=!1);for(let s of o)s===1?this.bold=!0:s===22?this.bold=!1:s>=30&&s<=37?this.fg=k[s-30]:s===39?this.fg=null:s>=90&&s<=97?this.fg=_[s-90]:s>=40&&s<=47?this.bg=k[s-40]:s===49?this.bg=null:s>=100&&s<=107&&(this.bg=_[s-100]);return}let r=o=>{let s=parseInt(o,10);return Number.isFinite(s)&&s>0?s:1},l=o=>{let s=parseInt(o,10);return Number.isFinite(s)&&s>=0?s:0};if(t==="A")this.r=Math.max(0,this.r-r(i));else if(t==="B")this.r+=r(i);else if(t==="C")this.c=Math.min(this.cols-1,this.c+r(i));else if(t==="D")this.c=Math.max(0,this.c-r(i));else if(t==="H"||t==="f"){let o=i.split(";");this.r=r(o[0])-1,this.c=r(o[1])-1}else if(t==="G"||t.charCodeAt(0)===96)this.c=Math.max(0,r(i)-1);else if(t==="d")this.r=Math.max(0,r(i)-1);else if(t==="J"){let o=l(i);if(o===2||o===3){for(let s=0;s<this.grid.length;s++){let c=this._row(s);for(let a=0;a<this.cols;a++)c[a]={ch:" ",fg:null,bg:null,bold:!1}}this.r=0,this.c=0}else if(o===1)for(let s=0;s<=this.r;s++){let c=this._row(s),a=s===this.r?this.c:this.cols;for(let d=0;d<a;d++)c[d]={ch:" ",fg:null,bg:null,bold:!1}}else for(let s=this.r;s<this.grid.length;s++){let c=this._row(s),a=s===this.r?this.c:0;for(let d=a;d<this.cols;d++)c[d]={ch:" ",fg:null,bg:null,bold:!1}}}else if(t==="K"){let o=l(i),s=this._row(this.r);if(o===2)for(let c=0;c<this.cols;c++)s[c]={ch:" ",fg:null,bg:null,bold:!1};else if(o===1)for(let c=0;c<=this.c;c++)s[c]={ch:" ",fg:null,bg:null,bold:!1};else for(let c=this.c;c<this.cols;c++)s[c]={ch:" ",fg:null,bg:null,bold:!1}}else t==="s"?(this.sr=this.r,this.sc=this.c):t==="u"?(this.r=Math.min(this.sr,this.grid.length-1),this.c=this.sc):(t==="h"||t==="l")&&e.startsWith("?")&&l(e.slice(1).split(";")[0])===1049&&(t==="h"?(this.altGrid=this.grid.map(s=>s.slice()),this.sr=this.r,this.sc=this.c,this.grid=[],this.r=0,this.c=0):this.altGrid&&(this.grid=this.altGrid,this.altGrid=null,this.r=Math.min(this.sr,this.grid.length-1),this.c=this.sc))}render(){let e=i=>i.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),t=[];for(let i=0;i<this.grid.length;i++){let r=this.grid[i],l=this.cols;for(;l>0&&r[l-1].ch===" ";)l--;if(l===0)continue;let o="",s=null;for(let c=0;c<l;c++){let a=r[c],d=[];a.bold&&d.push("font-weight:bold"),a.fg&&d.push("color:"+a.fg),a.bg&&d.push("background-color:"+a.bg);let p=d.join(";");p!==s&&(s&&(o+="</span>"),s=p,p&&(o+='<span style="'+p+'">')),o+=e(a.ch)}s&&(o+="</span>"),t.push(o)}return t}},h=null,u=[],T=!0,g=null,f=!1;function A(){h=new WebSocket("ws://"+window.location.host+"/ws"),h.onopen=()=>{h.send(JSON.stringify({type:"list"})),L()},h.onmessage=n=>{let e;try{e=JSON.parse(n.data)}catch{return}switch(e.type){case"sessions":F(e);break;case"snapshot":R(e);break;case"run":W(e);break;case"runEnd":break;case"cmdStart":Y(e);break;case"raw":J(e);break}},h.onclose=()=>{let n=document.getElementById("term");n.textContent="WebSocket disconnected"}}function F(n){let e=n.sessions||[],t=document.getElementById("session"),i=e.map(o=>o.sessionID+"|"+o.terminals.length).join(","),r=t.value,l=document.getElementById("terminal").value;u=e,t.innerHTML="";for(let o of u){let s=document.createElement("option");s.value=o.sessionID,s.textContent=N(o)+" ("+o.terminals.length+" "+E.terminals+")",t.appendChild(s)}r&&[...t.options].some(o=>o.value===r)?t.value=r:t.selectedIndex=u.length?0:-1,B(l)}function B(n){let e=document.getElementById("session"),t=document.getElementById("terminal"),i=document.getElementById("delTerm"),r=e.value,l=u.find(s=>s.sessionID===r);t.innerHTML="";for(let s of l?l.terminals:[]){let c=document.createElement("option");c.value=s.name||"default",c.textContent=(s.name||"default")+(s.kind==="local"?" ["+E.local+"]":"")+" "+(s.connected?"\u25CF":"\u25CB")+(s.busy?" \u23F3":""),t.appendChild(c)}n&&[...t.options].some(s=>s.value===n)?t.value=n:t.selectedIndex=t.options.length?0:-1;let o=l?.terminals.find(s=>(s.name||"default")===t.value);i.classList.toggle("show",!!(o&&!o.connected)),L()}var S="",M="",I=!1;function L(){let n=document.getElementById("session").value,e=document.getElementById("terminal").value;!n||!e||!h||h.readyState!==WebSocket.OPEN||n===S&&e===M||(S=n,M=e,g=null,I=!1,h.send(JSON.stringify({type:"subscribe",sessionID:n,name:e,raw:f})))}function R(n){let e=document.getElementById("term"),t=document.getElementById("toBottom");if(n.notFound){e.innerHTML='<div class="row"><span class="t"></span><span class="c">'+E.sessionGone+"</span></div>",document.getElementById("meta").textContent="",K(n.sessionID,n.name);return}let i=n.pairs||[],r=!f&&document.getElementById("showTime").checked;document.body.classList.toggle("show-time",r);let l=i.filter(o=>o.type==="cmd").length;document.getElementById("meta").textContent=n.sessionID+"/"+n.name+" \xB7 "+l+" "+E.commands,!(f&&I)&&(g=null,e.innerHTML=q(i,r),T?(e.scrollTop=e.scrollHeight,t.style.display="none"):t.style.display=e.scrollHeight>e.clientHeight?"block":"none")}function W(n){if(!n.data||f)return;let e=document.getElementById("term"),t=document.getElementById("toBottom"),i=document.getElementById("runBlock");g||(g=new w(v),i=document.createElement("div"),i.id="runBlock",e.appendChild(i)),g.write(C(n.data));let r=g.render().map(l=>'<div class="row"><span class="t"></span><span class="c">'+l+"</span></div>").join("");i.innerHTML=r,T?(e.scrollTop=e.scrollHeight,t.style.display="none"):t.style.display="block"}var b=null;function J(n){if(!f)return;let e=document.getElementById("term"),t=document.getElementById("toBottom");if(I||(I=!0,e.innerHTML="",b=null),n.reset?(b=new w(v),b.write(n.data||"")):n.data&&(b||(b=new w(v)),b.write(n.data)),b){let i=b.render().map(r=>'<div class="row"><span class="c">'+r+"</span></div>").join("");e.innerHTML=i}T?(e.scrollTop=e.scrollHeight,t.style.display="none"):t.style.display=e.scrollHeight>e.clientHeight?"block":"none"}function Y(n){if(f||!n.command)return;let e=document.getElementById("term"),t=document.getElementById("toBottom"),i=document.getElementById("runBlock");i&&i.remove(),g=null;let l=document.getElementById("showTime").checked?P(Date.now()):"",o=document.createElement("div");o.className="row cmdline",o.innerHTML='<span class="t">'+l+'</span><span class="c">'+D(n.command)+"</span>",e.appendChild(o),T&&(e.scrollTop=e.scrollHeight,t.style.display="none")}function D(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var H=/<SSH_DONE:(-?\d+)>/g;function C(n){return n.replace(H,"")}function q(n,e){let t=[],i=null;for(let r of n){if(r.type==="sep"){t.push('<div class="sep"><hr></div>');continue}if(r.type==="cmd"){i={ts:r.ts,endTs:r.endTs};let l=r.ts?P(r.ts):"";t.push('<div class="row cmdline"><span class="t">'+l+'</span><span class="c">'+D(r.text)+"</span></div>")}else if(r.type==="run"){g=new w(v),g.write(C(r.text));let l=g.render().map(o=>'<div class="row"><span class="t"></span><span class="c">'+o+"</span></div>").join("");t.push('<div id="runBlock">'+l+"</div>")}else{let l=j(r.text),o=new w(v);o.write(l.text);let s=o.render(),c=e?z(i,l.exitCode):"",a=(d,p)=>'<div class="row"><span class="t">'+d+'</span><span class="c">'+p+"</span></div>";s.length===0?t.push(a(c," ")):s.forEach((d,p)=>t.push(a(p===s.length-1?c:"",d))),i=null}}return t.join("")}function z(n,e){let t=[];if(n&&n.ts&&n.endTs&&t.push("+"+((n.endTs-n.ts)/1e3).toFixed(3)+"s"),e!==void 0){let i=e===0?"#3fb950":"#ff7b72";t.push('<span style="color:'+i+'">'+(e===0?"\u2713":"\u2717 "+e)+"</span>")}return t.join(" ")}function N(n){if(n.title&&n.title.trim())return n.title;let e=n.terminals&&n.terminals[0];return e&&e.host?(e.user?e.user+"@":"")+e.host:n.sessionID.slice(0,8)+"\u2026"}function P(n){let e=new Date(n),t=i=>String(i).padStart(2,"0");return e.getFullYear()+"-"+t(e.getMonth()+1)+"-"+t(e.getDate())+" "+t(e.getHours())+":"+t(e.getMinutes())+":"+t(e.getSeconds())}function K(n,e){let t=u.find(o=>o.sessionID===n);t&&(t.terminals=t.terminals.filter(o=>(o.name||"default")!==e),t.terminals.length===0&&(u=u.filter(o=>o.sessionID!==n)));let i=document.getElementById("session"),r=i.value;i.innerHTML="";for(let o of u){let s=document.createElement("option");s.value=o.sessionID,s.textContent=N(o)+" ("+o.terminals.length+" "+E.terminals+")",i.appendChild(s)}r&&[...i.options].some(o=>o.value===r)?i.value=r:i.selectedIndex=u.length?0:-1;let l=document.getElementById("terminal").value;B(l)}function Z(n){n&&(T=!0);let e=document.getElementById("terminal").value;B(e)}function Q(){let n=document.getElementById("showTime");localStorage.setItem("showTime",n.checked?"1":"0"),document.body.classList.toggle("show-time",n.checked)}function U(){let n=document.getElementById("debugMode");f=n.checked,localStorage.setItem("debugMode",n.checked?"1":"0"),document.body.classList.toggle("debug",n.checked),S="",M="",L()}function V(){let n=document.getElementById("session").value,e=document.getElementById("terminal").value;if(!e||!h||h.readyState!==WebSocket.OPEN)return;let t=u.find(l=>l.sessionID===n),i=t?.terminals.find(l=>(l.name||"default")===e);if(!i||i.connected)return;h.send(JSON.stringify({type:"deleteTerminal",sessionID:n,name:e})),t&&(t.terminals=t.terminals.filter(l=>(l.name||"default")!==e),t.terminals.length===0&&(u=u.filter(l=>l.sessionID!==n)));let r=document.getElementById("terminal").value;B(r!==e?r:void 0)}function X(){let n=document.getElementById("term"),e=document.getElementById("toBottom");n.scrollTop=n.scrollHeight,T=!0,e.style.display="none"}var O=document.getElementById("showTime");O.checked=localStorage.getItem("showTime")==="1";document.body.classList.toggle("show-time",O.checked);var $=document.getElementById("debugMode");f=localStorage.getItem("debugMode")==="1";$.checked=f;document.body.classList.toggle("debug",f);var y=document.getElementById("term"),ee=document.getElementById("toBottom");y.addEventListener("scroll",()=>{y.scrollTop+y.clientHeight>=y.scrollHeight-30?(T=!0,ee.style.display="none"):T=!1});Object.assign(window,{onSessionChange:Z,onShowTimeChange:Q,onDebugModeChange:U,deleteTerminal:V,scrollToNewest:X});A();})();
|
|
Binary file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="{{lang}}">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>{{web_title}}</title>
|
|
6
|
+
<link rel="stylesheet" href="/web/app.css">
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<header>
|
|
10
|
+
<h1>{{web_title}}</h1>
|
|
11
|
+
<select id="session" onchange="onSessionChange(true)"></select>
|
|
12
|
+
<select id="terminal" onchange="onSessionChange(true)"></select>
|
|
13
|
+
<button id="delTerm" class="del-btn" onclick="deleteTerminal()" title="{{web_delete_terminal}}">×</button>
|
|
14
|
+
<label class="tgl"><input type="checkbox" id="showTime" onchange="onShowTimeChange()"> {{web_time}}</label>
|
|
15
|
+
<label class="tgl"><input type="checkbox" id="debugMode" onchange="onDebugModeChange()"> Raw</label>
|
|
16
|
+
<span id="meta"></span>
|
|
17
|
+
</header>
|
|
18
|
+
<pre id="term">{{web_loading}}</pre>
|
|
19
|
+
<button id="toBottom" class="to-bottom-btn" onclick="scrollToNewest()">{{web_new_messages}}</button>
|
|
20
|
+
<script>window.__I18N__ = __I18N_JSON__;</script>
|
|
21
|
+
<script>window.__PTY_COLS__ = __PTY_COLS_VAL__;</script>
|
|
22
|
+
<script src="/web/app.js"></script>
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xiaoqiong0v0/opencode-ssh-tool",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "长驻交互式 SSH 会话工具插件,远程命令受 opencode 权限管控",
|
|
6
6
|
"files": [
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
".": "./dist/index.js"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "tsc",
|
|
16
|
+
"build": "tsc && node web/build.mjs",
|
|
17
17
|
"prepublishOnly": "npm run build"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
@@ -36,8 +36,10 @@
|
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@xiaoqiong0v0/opencode-plugin-logger": "^1.0.
|
|
40
|
-
"ssh2": "^1.16.0"
|
|
39
|
+
"@xiaoqiong0v0/opencode-plugin-logger": "^1.0.4",
|
|
40
|
+
"ssh2": "^1.16.0",
|
|
41
|
+
"string-argv": "^0.3.2",
|
|
42
|
+
"ws": "^8.21.3"
|
|
41
43
|
},
|
|
42
44
|
"peerDependencies": {
|
|
43
45
|
"@opencode-ai/plugin": "^1.18.4"
|
|
@@ -45,6 +47,8 @@
|
|
|
45
47
|
"devDependencies": {
|
|
46
48
|
"@types/node": "^26.1.1",
|
|
47
49
|
"@types/ssh2": "^1.15.4",
|
|
50
|
+
"@types/ws": "^8.18.1",
|
|
51
|
+
"esbuild": "^0.28.2",
|
|
48
52
|
"typescript": "^7.0.2"
|
|
49
53
|
}
|
|
50
54
|
}
|