From d376e70c25ebbb38e696d845b8c37990f7ccc3ed Mon Sep 17 00:00:00 2001 From: Codebuddy Date: Thu, 13 Aug 2026 16:37:34 +0800 Subject: [PATCH] =?utf8?q?fix(frontend):=20=E4=BF=AE=E5=A4=8D=20reattach/?= =?utf8?q?=E8=BF=9E=E6=8E=A5=E6=8F=90=E7=A4=BA=E4=B8=AD=E7=9A=84=20ANSI=20?= =?utf8?q?=E8=BD=AC=E4=B9=89=E8=A2=AB=E5=86=99=E6=88=90=E5=AD=97=E9=9D=A2?= =?utf8?q?=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit - renderReattach 与 connectWS 的状态提示误用双反斜杠 \\x1b,导致 xterm 把转义序列当纯文本打印 - 统一改为单反斜杠 \x1b,连接成功/重新连接/任务状态等提示恢复正常彩色 - 仅前端改动,刷新浏览器即生效 --- frontend/index.html | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 0b16c3c..e84124f 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -613,7 +613,7 @@ body { position: fixed; top: 0; left: 0; right: 0; bottom: 0; height: 100%; over } const data = await res.json(); currentTask.model = (data.task && data.task.model) || ''; - term.writeln('\\x1b[33m⏳ 切换模型为 "' + (currentTask.model || '默认·最新GLM') + '",正在重启会话...\\x1b[0m'); + term.writeln('\x1b[33m⏳ 切换模型为 "' + (currentTask.model || '默认·最新GLM') + '",正在重启会话...\x1b[0m'); // 重启以应用新模型(resume 同样会采用新 --model) killCurrent(); if (term) term.clear(); @@ -863,13 +863,13 @@ body { position: fixed; top: 0; left: 0; right: 0; bottom: 0; height: 100%; over const m = Math.floor(sec / 60), s = sec % 60; term.writeln(''); if (msg.running) { - term.writeln('\\x1b[36m🔗 已重新连接 · 任务运行中 · 已运行 ' + m + '分' + s + '秒\\x1b[0m'); + term.writeln('\x1b[36m🔗 已重新连接 · 任务运行中 · 已运行 ' + m + '分' + s + '秒\x1b[0m'); } else { - term.writeln('\\x1b[33mⓘ 任务已结束(退出码 ' + (msg.exit_code == null ? '?' : msg.exit_code) + ')\\x1b[0m'); + term.writeln('\x1b[33mⓘ 任务已结束(退出码 ' + (msg.exit_code == null ? '?' : msg.exit_code) + ')\x1b[0m'); } - if (msg.current_task) term.writeln('\\x1b[90m当前/最近任务:' + msg.current_task + '\\x1b[0m'); + if (msg.current_task) term.writeln('\x1b[90m当前/最近任务:' + msg.current_task + '\x1b[0m'); if (msg.replay) { - term.writeln('\\x1b[90m──── 以下为断开期间 / 上次的输出 ────\\x1b[0m'); + term.writeln('\x1b[90m──── 以下为断开期间 / 上次的输出 ────\x1b[0m'); term.write(msg.replay); } try { term.focus(); } catch (e) {} @@ -880,25 +880,25 @@ body { position: fixed; top: 0; left: 0; right: 0; bottom: 0; height: 100%; over if (!authToken || !TASK_ID) return; const proto = location.protocol === 'https:' ? 'wss:' : 'ws:'; const url = proto + '//' + location.host + '/ws?token=' + encodeURIComponent(authToken) + '&task=' + encodeURIComponent(TASK_ID); - term.writeln('\\x1b[33m⏳ 正在连接任务 [' + (currentTask ? currentTask.name : TASK_ID) + ']...\\x1b[0m'); + term.writeln('\x1b[33m⏳ 正在连接任务 [' + (currentTask ? currentTask.name : TASK_ID) + ']...\x1b[0m'); setConnected(false); ws = new WebSocket(url); ws.binaryType = 'arraybuffer'; - ws.onopen = () => { setConnected(true); term.writeln('\\x1b[32m✓ 连接成功\\x1b[0m'); }; + ws.onopen = () => { setConnected(true); term.writeln('\x1b[32m✓ 连接成功\x1b[0m'); }; ws.onmessage = (event) => { try { const msg = JSON.parse(event.data); if (msg.type === 'output' && msg.data) term.write(msg.data); else if (msg.type === 'pid') pid = msg.pid; else if (msg.type === 'reattach') { pid = msg.pid || pid; renderReattach(msg); } - else if (msg.type === 'error') { term.writeln('\\x1b[31m✗ ' + msg.data + '\\x1b[0m'); } - else if (msg.type === 'exit') { term.writeln('\\x1b[33m⚠ 进程已退出 (code: ' + msg.code + ')\\x1b[0m'); setConnected(false); } + else if (msg.type === 'error') { term.writeln('\x1b[31m✗ ' + msg.data + '\x1b[0m'); } + else if (msg.type === 'exit') { term.writeln('\x1b[33m⚠ 进程已退出 (code: ' + msg.code + ')\x1b[0m'); setConnected(false); } } catch(e) { term.write(event.data); } }; - ws.onclose = () => { setConnected(false); term.writeln('\\x1b[31m✗ 连接已断开\\x1b[0m'); }; - ws.onerror = () => { setConnected(false); term.writeln('\\x1b[31m✗ 连接错误\\x1b[0m'); }; + ws.onclose = () => { setConnected(false); term.writeln('\x1b[31m✗ 连接已断开\x1b[0m'); }; + ws.onerror = () => { setConnected(false); term.writeln('\x1b[31m✗ 连接错误\x1b[0m'); }; } function killCurrent() { @@ -908,7 +908,7 @@ body { position: fixed; top: 0; left: 0; right: 0; bottom: 0; height: 100%; over document.getElementById('btn-restart').onclick = () => { killCurrent(); if (term) term.clear(); - term.writeln('\\x1b[33m⏳ 重启会话中...\\x1b[0m'); + term.writeln('\x1b[33m⏳ 重启会话中...\x1b[0m'); connectWS(); }; document.getElementById('btn-list').onclick = () => { window.open('/', 'cb_picker'); }; -- 2.43.0