fix: file路由readFile改promise版 + 终端客户端自动聚焦(实机pwd已验证服务端通)

This commit is contained in:
Aisland
2026-08-17 20:45:29 +08:00
parent 825730c54c
commit f83aa1d589
5 changed files with 43 additions and 2 deletions
+4
View File
@@ -982,6 +982,9 @@ function TerminalPane() {
return
}
term.open(el)
const focusTerm = () => { try { term.focus() } catch {} }
focusTerm()
el.addEventListener('pointerdown', focusTerm)
const scope = splitEnv?.getScope?.()
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:'
const url = proto + '//' + location.host + '/api/worktable/term?sessionId=' + encodeURIComponent(scope?.sessionId ?? '') + '&cwd=' + encodeURIComponent(scope?.cwd ?? '') + '&cols=80&rows=24'
@@ -992,6 +995,7 @@ function TerminalPane() {
setFailed(T('pane.termFail'))
return
}
ws.onopen = () => { focusTerm() }
ws.onmessage = (ev) => { try { term.write(String(ev.data)) } catch {} }
ws.onclose = () => { if (!disposed) { try { term.write('\r\n[连接已关闭]') } catch {} } }
ws.onerror = () => { if (!disposed) setFailed(T('pane.termFail')) }
+2 -2
View File
@@ -1,7 +1,7 @@
import { Context } from '@deepseek-ai/cordis'
import { execFile } from 'node:child_process'
import { readdirSync, readFile, realpathSync } from 'node:fs'
import { readdir } from 'node:fs/promises'
import { readdirSync, realpathSync } from 'node:fs'
import { readdir, readFile } from 'node:fs/promises'
import { dirname, resolve as pathResolve, sep } from 'node:path'
import { createRequire } from 'node:module'
import { homedir } from 'node:os'
@@ -443,3 +443,15 @@
(better-sidebar 同款生命周期)。
- 验证(04_test/term-e2e.cjs 扩展):fs handler 直调 200 + 真实条目;终端 E2E
RESULT: PASS(真实 cmd.exe shell,pwd 回显正常)。**需再重启一次 dsh web 生效。**
## 补记(浏览器 file 路由 readFile 坑 + 终端实机验证 + 客户端焦点)
- 用户反馈:① 浏览器打不开(错误 JSON = file 路由抛
ERR_INVALID_ARG_TYPE cb must be function——readFile 用了 node:fs 回调版,
与 readdir 同一类坑);② 终端仍无法敲命令。
- 处理:
① readFile 改 node:fs/promises(file 路由本地直调 200 + README 内容,已验证);
② 终端**实机验证**:直接对用户运行中的服务器(20:40:44 启动)跑 ws + pwd →
RESULT: PASS(cmd.exe 真实回显 E:\AI_Workspace)——服务端已通!用户侧「敲不了」
定位为客户端焦点问题:TerminalPane 增加 open 后自动 focus + 点击聚焦 + ws.onopen 聚焦;
③ 客户端焦点修复实时下发(F5 生效);file 路由修复需再重启一次。
+18
View File
@@ -0,0 +1,18 @@
const WebSocket = require('ws');
const ws = new WebSocket('ws://127.0.0.1:3080/api/worktable/term?cwd=' + encodeURIComponent('E:/AI_Workspace') + '&cols=80&rows=24');
const received = [];
const timer = setTimeout(() => { console.log('RESULT: FAIL 15s 无任何输出'); process.exit(1); }, 15000);
ws.on('open', () => { console.log('WS_OPEN'); setTimeout(() => { console.log('SEND pwd'); ws.send('pwd\r'); }, 1500); });
ws.on('message', (d) => {
const t = String(d);
received.push(t);
console.log('FRAME[' + received.length + ']:', JSON.stringify(t.slice(0, 100)));
if (t.includes('E:\\AI_Workspace') || /[A-Za-z]:[\\/]/.test(t)) {
clearTimeout(timer);
console.log('RESULT: PASS pwd 真实回显 OK');
ws.close(); process.exit(0);
}
});
ws.on('close', (code) => { console.log('WS_CLOSE code=' + code); clearTimeout(timer); process.exit(0); });
ws.on('error', (e) => { console.log('WS_ERROR:', String(e)); clearTimeout(timer); process.exit(1); });
+7
View File
@@ -22,6 +22,13 @@ const WebSocket = require('ws');
const fakeReq = { [Symbol.asyncIterator]() { let done = false; return { next: () => (done ? Promise.resolve({ done: true }) : (done = true, Promise.resolve({ done: false, value: Buffer.from('{"path":"E:/AI_Workspace"}') }))) }; } };
await fsRoute.handler(fakeReq, fakeRes);
console.log('fs direct:', captured && captured.status, captured && captured.body ? captured.body.slice(0, 160) : '');
// file 路由直调(真实 README.md)
const fileRoute = routes.find((r) => r.path === '/api/worktable/file');
let fc = null;
const fRes = { writeHead: (s) => { fc = { status: s }; }, end: (b) => { fc.body = String(b); } };
const fReq = { url: '/api/worktable/file?path=' + encodeURIComponent('E:/AI_Workspace/DeepseekHarness/Projects/dsh-worktable/README.md') };
await fileRoute.handler(fReq, fRes);
console.log('file direct:', fc && fc.status, fc && fc.body ? fc.body.slice(0, 60) : '');
if (upgrades.length === 0) { console.log('RESULT: NO_TERMINAL_ROUTE'); process.exit(1); }
const server = http.createServer((req, res) => { res.writeHead(404); res.end(); });
server.on('upgrade', (req, socket, head) => {