@very_aq/codex-cli-web 0.0.16 → 0.0.18
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/package.json +1 -1
- package/server/dist/app.js +80 -7
- package/server/dist/app.js.map +1 -1
- package/server/dist/history/http/historyRoutes.js +55 -17
- package/server/dist/history/http/historyRoutes.js.map +1 -1
- package/server/dist/history/worker/historyWorkerClient.js +13 -3
- package/server/dist/history/worker/historyWorkerClient.js.map +1 -1
- package/server/dist/history/worker/historyWorkerPool.d.ts +0 -4
- package/server/dist/history/worker/historyWorkerPool.js +95 -9
- package/server/dist/history/worker/historyWorkerPool.js.map +1 -1
- package/server/dist/tools/cwdSuggest.js +6 -1
- package/server/dist/tools/cwdSuggest.js.map +1 -1
- package/server/dist/workspace/accessControl.js +10 -3
- package/server/dist/workspace/accessControl.js.map +1 -1
- package/server/dist/workspace/threadListVisibility.js +9 -4
- package/server/dist/workspace/threadListVisibility.js.map +1 -1
- package/server/dist/workspace/threadSanitize.d.ts +8 -0
- package/server/dist/workspace/threadSanitize.js +27 -0
- package/server/dist/workspace/threadSanitize.js.map +1 -0
- package/server/dist/workspace/userWorkspaceRoutes.js +7 -2
- package/server/dist/workspace/userWorkspaceRoutes.js.map +1 -1
- package/server/dist/workspace/windowsVerbatimPath.d.ts +23 -0
- package/server/dist/workspace/windowsVerbatimPath.js +80 -0
- package/server/dist/workspace/windowsVerbatimPath.js.map +1 -0
- package/server/dist/ws/wsHub.js +18 -7
- package/server/dist/ws/wsHub.js.map +1 -1
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createHistoryWorkerPool = createHistoryWorkerPool;
|
|
4
4
|
const historyWorkerClient_1 = require("./historyWorkerClient");
|
|
5
|
+
/**
|
|
6
|
+
* HistoryWorkerPool:对外提供与现有 history runtime 对齐的 ingest/query 接口,
|
|
7
|
+
* 内部通过 worker_threads 执行 SQLite 读写,避免阻塞主线程。
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* 判断错误是否属于“worker 已关闭/退出”这类可恢复场景。
|
|
11
|
+
*
|
|
12
|
+
* 说明:
|
|
13
|
+
* - worker client 的实现/构建产物可能存在差异(例如旧版本仅抛出 `history worker is closed`);
|
|
14
|
+
* - 这里用 message 关键字做兼容匹配,避免因错误文本差异导致无法恢复。
|
|
15
|
+
*/
|
|
16
|
+
function isHistoryWorkerClosedError(err) {
|
|
17
|
+
const message = String(err?.message ?? err ?? "");
|
|
18
|
+
if (!message)
|
|
19
|
+
return false;
|
|
20
|
+
if (!message.toLowerCase().includes("history worker"))
|
|
21
|
+
return false;
|
|
22
|
+
return message.includes("closed") || message.includes("exited");
|
|
23
|
+
}
|
|
5
24
|
/**
|
|
6
25
|
* 归一化 worker 数量,避免 NaN/负数导致异常。
|
|
7
26
|
*/
|
|
@@ -16,18 +35,59 @@ function normalizeWorkerCount(raw) {
|
|
|
16
35
|
*/
|
|
17
36
|
function createHistoryWorkerPool(options) {
|
|
18
37
|
const normalizedWorkerCount = normalizeWorkerCount(options.workerCount);
|
|
38
|
+
// writerName:writer 实例名称(用于日志定位)。
|
|
39
|
+
const writerName = "history-writer";
|
|
40
|
+
// readerNames:reader 实例名称列表(用于日志定位与重建)。
|
|
41
|
+
const readerNames = Array.from({ length: Math.max(0, normalizedWorkerCount - 1) }, (_, index) => `history-reader-${index + 1}`);
|
|
19
42
|
// writer:负责 history ingest(保证写入顺序,避免多写者锁争用)。
|
|
20
|
-
|
|
43
|
+
let writer = (0, historyWorkerClient_1.createHistoryWorkerClient)({ dbPath: options.dbPath, name: writerName });
|
|
21
44
|
// readers:可选的只读 worker,用于分摊查询负载;为空时查询也走 writer。
|
|
22
|
-
const readers =
|
|
45
|
+
const readers = readerNames.map((name) => (0, historyWorkerClient_1.createHistoryWorkerClient)({ dbPath: options.dbPath, name }));
|
|
23
46
|
// nextReaderIndex:round-robin 指针,避免热点落在同一个 reader。
|
|
24
47
|
let nextReaderIndex = 0;
|
|
25
|
-
|
|
48
|
+
/**
|
|
49
|
+
* 替换 writer:
|
|
50
|
+
* - 先同步创建新 worker 并切换引用;
|
|
51
|
+
* - 再异步 best-effort 关闭旧 worker(避免阻塞当前请求)。
|
|
52
|
+
*/
|
|
53
|
+
const replaceWriter = (expected) => {
|
|
54
|
+
const current = writer;
|
|
55
|
+
if (current !== expected) {
|
|
56
|
+
void expected.close().catch(() => { });
|
|
57
|
+
return current;
|
|
58
|
+
}
|
|
59
|
+
const previous = current;
|
|
60
|
+
writer = (0, historyWorkerClient_1.createHistoryWorkerClient)({ dbPath: options.dbPath, name: writerName });
|
|
61
|
+
void previous.close().catch(() => { });
|
|
62
|
+
return writer;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* 替换某个 reader(按下标)。
|
|
66
|
+
*/
|
|
67
|
+
const replaceReader = (index, expected) => {
|
|
68
|
+
const current = readers[index];
|
|
69
|
+
if (current !== expected) {
|
|
70
|
+
void expected.close().catch(() => { });
|
|
71
|
+
return current ?? writer;
|
|
72
|
+
}
|
|
73
|
+
const name = readerNames[index] ?? `history-reader-${index + 1}`;
|
|
74
|
+
const next = (0, historyWorkerClient_1.createHistoryWorkerClient)({ dbPath: options.dbPath, name });
|
|
75
|
+
readers[index] = next;
|
|
76
|
+
void expected.close().catch(() => { });
|
|
77
|
+
return next;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* pickQueryTarget:为一次 query 选择目标 worker:
|
|
81
|
+
* - 优先 reader(round-robin);
|
|
82
|
+
* - 无 reader 时回退 writer。
|
|
83
|
+
*/
|
|
84
|
+
const pickQueryTarget = () => {
|
|
26
85
|
if (!readers.length)
|
|
27
|
-
return writer;
|
|
28
|
-
const
|
|
86
|
+
return { kind: "writer", client: writer };
|
|
87
|
+
const index = nextReaderIndex % readers.length;
|
|
29
88
|
nextReaderIndex += 1;
|
|
30
|
-
|
|
89
|
+
const picked = readers[index] ?? writer;
|
|
90
|
+
return picked === writer ? { kind: "writer", client: writer } : { kind: "reader", index, client: picked };
|
|
31
91
|
};
|
|
32
92
|
let closed = false;
|
|
33
93
|
const close = async () => {
|
|
@@ -40,7 +100,15 @@ function createHistoryWorkerPool(options) {
|
|
|
40
100
|
};
|
|
41
101
|
const ingest = {
|
|
42
102
|
async recordCodexEvent(input) {
|
|
43
|
-
|
|
103
|
+
const currentWriter = writer;
|
|
104
|
+
try {
|
|
105
|
+
await currentWriter.recordEvent(input);
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
if (closed || !isHistoryWorkerClosedError(err))
|
|
109
|
+
throw err;
|
|
110
|
+
await replaceWriter(currentWriter).recordEvent(input);
|
|
111
|
+
}
|
|
44
112
|
},
|
|
45
113
|
async flushAndClose() {
|
|
46
114
|
await close();
|
|
@@ -48,10 +116,28 @@ function createHistoryWorkerPool(options) {
|
|
|
48
116
|
};
|
|
49
117
|
const query = {
|
|
50
118
|
async listMessages(input) {
|
|
51
|
-
|
|
119
|
+
const target = pickQueryTarget();
|
|
120
|
+
try {
|
|
121
|
+
return await target.client.listMessages(input);
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
if (closed || !isHistoryWorkerClosedError(err))
|
|
125
|
+
throw err;
|
|
126
|
+
const nextClient = target.kind === "writer" ? replaceWriter(target.client) : replaceReader(target.index, target.client);
|
|
127
|
+
return nextClient.listMessages(input);
|
|
128
|
+
}
|
|
52
129
|
},
|
|
53
130
|
async getMessageDiff(input) {
|
|
54
|
-
|
|
131
|
+
const target = pickQueryTarget();
|
|
132
|
+
try {
|
|
133
|
+
return await target.client.getMessageDiff(input);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (closed || !isHistoryWorkerClosedError(err))
|
|
137
|
+
throw err;
|
|
138
|
+
const nextClient = target.kind === "writer" ? replaceWriter(target.client) : replaceReader(target.index, target.client);
|
|
139
|
+
return nextClient.getMessageDiff(input);
|
|
140
|
+
}
|
|
55
141
|
},
|
|
56
142
|
};
|
|
57
143
|
return { ingest, query, close };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"historyWorkerPool.js","sourceRoot":"","sources":["../../../src/history/worker/historyWorkerPool.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"historyWorkerPool.js","sourceRoot":"","sources":["../../../src/history/worker/historyWorkerPool.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ exports.suggestCwds = suggestCwds;
|
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const env_1 = require("../env");
|
|
11
|
+
const windowsVerbatimPath_1 = require("../workspace/windowsVerbatimPath");
|
|
11
12
|
// 目录建议接口的可预期错误类型(客户端可据此展示更友好的提示)。
|
|
12
13
|
class CwdSuggestError extends Error {
|
|
13
14
|
code;
|
|
@@ -50,7 +51,11 @@ function parseQuery(query) {
|
|
|
50
51
|
}
|
|
51
52
|
// 在可能存在权限/平台差异时,realpath 失败则回退到 resolve,以确保逻辑可继续执行。
|
|
52
53
|
async function resolveRealpathOrFallback(candidate) {
|
|
53
|
-
|
|
54
|
+
const rawCandidate = String(candidate ?? "");
|
|
55
|
+
return fs_1.default.promises
|
|
56
|
+
.realpath(rawCandidate)
|
|
57
|
+
.then((realpathValue) => (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(realpathValue))
|
|
58
|
+
.catch(() => (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(path_1.default.resolve(rawCandidate)));
|
|
54
59
|
}
|
|
55
60
|
// 校验 listDir 真实路径是否位于允许范围内:
|
|
56
61
|
// - allowAnyRoot=true:admin 不限制;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cwdSuggest.js","sourceRoot":"","sources":["../../src/tools/cwdSuggest.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"cwdSuggest.js","sourceRoot":"","sources":["../../src/tools/cwdSuggest.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ const promises_1 = __importDefault(require("node:fs/promises"));
|
|
|
10
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
11
11
|
const env_1 = require("../env");
|
|
12
12
|
const roles_1 = require("../auth/roles");
|
|
13
|
+
const windowsVerbatimPath_1 = require("./windowsVerbatimPath");
|
|
13
14
|
// 判断 candidate 是否位于 root 目录之下(含 root 本身)。
|
|
14
15
|
function isPathWithinRoot(root, candidate) {
|
|
15
16
|
const rel = node_path_1.default.relative(root, candidate);
|
|
@@ -25,7 +26,9 @@ function normalizeRoots(roots) {
|
|
|
25
26
|
const seen = new Set();
|
|
26
27
|
const out = [];
|
|
27
28
|
for (const r of roots) {
|
|
28
|
-
const
|
|
29
|
+
const trimmedRoot = String(r ?? "").trim();
|
|
30
|
+
const sanitizedRoot = (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(trimmedRoot);
|
|
31
|
+
const resolved = node_path_1.default.resolve(sanitizedRoot);
|
|
29
32
|
if (!resolved)
|
|
30
33
|
continue;
|
|
31
34
|
if (seen.has(resolved))
|
|
@@ -47,12 +50,16 @@ function resolveAllowedRootsForUser(user) {
|
|
|
47
50
|
return { allowAnyRoot: false, roots: assigned };
|
|
48
51
|
}
|
|
49
52
|
async function resolveRealpathOrFallback(candidate) {
|
|
50
|
-
|
|
53
|
+
const rawCandidate = String(candidate ?? "");
|
|
54
|
+
return promises_1.default
|
|
55
|
+
.realpath(rawCandidate)
|
|
56
|
+
.then((realpathValue) => (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(realpathValue))
|
|
57
|
+
.catch(() => (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(node_path_1.default.resolve(rawCandidate)));
|
|
51
58
|
}
|
|
52
59
|
// 校验 cwd 是否在用户允许范围内;返回 canonical(尽力 realpath)后的 cwd。
|
|
53
60
|
async function assertCwdAllowedForUser(opts) {
|
|
54
61
|
const base = node_path_1.default.resolve((0, env_1.getCodexCwd)());
|
|
55
|
-
const raw = typeof opts.cwd === "string" ? opts.cwd.trim() : "";
|
|
62
|
+
const raw = typeof opts.cwd === "string" ? (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(opts.cwd.trim()) : "";
|
|
56
63
|
if (raw.includes("\0"))
|
|
57
64
|
throw new Error("invalid cwd");
|
|
58
65
|
// 空 cwd 等价于使用默认 CODEX_CWD,保持与历史行为一致。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessControl.js","sourceRoot":"","sources":["../../src/workspace/accessControl.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"accessControl.js","sourceRoot":"","sources":["../../src/workspace/accessControl.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@ exports.shouldIncludeThreadForList = shouldIncludeThreadForList;
|
|
|
13
13
|
const node_path_1 = __importDefault(require("node:path"));
|
|
14
14
|
const accessControl_1 = require("./accessControl");
|
|
15
15
|
const pathCompare_1 = require("./pathCompare");
|
|
16
|
+
const windowsVerbatimPath_1 = require("./windowsVerbatimPath");
|
|
16
17
|
// WS/HTTP 统一使用绝对路径 + 去重后的 workspace 列表,避免路径比较歧义。
|
|
17
18
|
function normalizeWorkspacePaths(workspaces) {
|
|
18
19
|
const seen = new Set();
|
|
@@ -21,7 +22,8 @@ function normalizeWorkspacePaths(workspaces) {
|
|
|
21
22
|
const trimmedWorkspace = String(workspace ?? "").trim();
|
|
22
23
|
if (!trimmedWorkspace)
|
|
23
24
|
continue;
|
|
24
|
-
const
|
|
25
|
+
const sanitizedWorkspace = (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(trimmedWorkspace);
|
|
26
|
+
const resolvedWorkspace = node_path_1.default.resolve(sanitizedWorkspace);
|
|
25
27
|
if (seen.has(resolvedWorkspace))
|
|
26
28
|
continue;
|
|
27
29
|
seen.add(resolvedWorkspace);
|
|
@@ -39,7 +41,8 @@ function buildWorkspaceRoutingSnapshot(users) {
|
|
|
39
41
|
const trimmedWorkspace = String(workspace ?? "").trim();
|
|
40
42
|
if (!trimmedWorkspace)
|
|
41
43
|
continue;
|
|
42
|
-
|
|
44
|
+
const sanitizedWorkspace = (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(trimmedWorkspace);
|
|
45
|
+
roots.add(node_path_1.default.resolve(sanitizedWorkspace));
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
const rootsDesc = Array.from(roots.values()).sort((leftRoot, rightRoot) => rightRoot.length - leftRoot.length);
|
|
@@ -50,7 +53,8 @@ function resolveWorkspaceRootForCwd(snapshot, cwd) {
|
|
|
50
53
|
const trimmedCwd = String(cwd ?? "").trim();
|
|
51
54
|
if (!trimmedCwd)
|
|
52
55
|
return null;
|
|
53
|
-
const
|
|
56
|
+
const sanitizedCwd = (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(trimmedCwd);
|
|
57
|
+
const resolvedCwd = node_path_1.default.resolve(sanitizedCwd);
|
|
54
58
|
for (const root of snapshot.rootsDesc) {
|
|
55
59
|
if ((0, accessControl_1.isPathWithinRoot)(root, resolvedCwd))
|
|
56
60
|
return root;
|
|
@@ -69,7 +73,8 @@ function normalizeThreadCwd(rawThreadCwd) {
|
|
|
69
73
|
const threadCwd = typeof rawThreadCwd === "string" ? rawThreadCwd.trim() : "";
|
|
70
74
|
if (!threadCwd)
|
|
71
75
|
return "";
|
|
72
|
-
|
|
76
|
+
const sanitizedCwd = (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(threadCwd);
|
|
77
|
+
return node_path_1.default.resolve(sanitizedCwd);
|
|
73
78
|
}
|
|
74
79
|
// 判断线程 cwd 是否对指定用户可见(admin 全可见,member 按分配工作区可见)。
|
|
75
80
|
function isThreadCwdVisibleToUser(input) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threadListVisibility.js","sourceRoot":"","sources":["../../src/workspace/threadListVisibility.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"threadListVisibility.js","sourceRoot":"","sources":["../../src/workspace/threadListVisibility.ts"],"names":[],"mappings":";;;;;AAeA,0DAaC;AAGD,sEAaC;AAGD,gEASC;AAGD,4EAOC;AAGD,gDAKC;AAGD,4DAeC;AAGD,gEAmBC;AAlHD,0DAA6B;AAG7B,mDAAwG;AACxG,+CAAiD;AACjD,+DAAuE;AASvE,iDAAiD;AACjD,SAAgB,uBAAuB,CAAC,UAAoB;IAC1D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,SAAS,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QACzC,MAAM,gBAAgB,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACxD,IAAI,CAAC,gBAAgB;YAAE,SAAS;QAChC,MAAM,kBAAkB,GAAG,IAAA,oDAA8B,EAAC,gBAAgB,CAAC,CAAC;QAC5E,MAAM,iBAAiB,GAAG,mBAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC3D,IAAI,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC;YAAE,SAAS;QAC1C,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC5B,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,+CAA+C;AAC/C,SAAgB,6BAA6B,CAAC,KAAqD;IACjG,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,SAAS;QACrC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YAC9C,MAAM,gBAAgB,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACxD,IAAI,CAAC,gBAAgB;gBAAE,SAAS;YAChC,MAAM,kBAAkB,GAAG,IAAA,oDAA8B,EAAC,gBAAgB,CAAC,CAAC;YAC5E,KAAK,CAAC,GAAG,CAAC,mBAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/G,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC;AAChD,CAAC;AAED,wCAAwC;AACxC,SAAgB,0BAA0B,CAAC,QAAkC,EAAE,GAAW;IACxF,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,YAAY,GAAG,IAAA,oDAA8B,EAAC,UAAU,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,mBAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACtC,IAAI,IAAA,gCAAgB,EAAC,IAAI,EAAE,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iCAAiC;AAC1B,KAAK,UAAU,gCAAgC,CACpD,YAAqB,EACrB,IAA8B;IAE9B,MAAM,eAAe,GAAG,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,IAAI,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,IAAA,uCAAuB,EAAC,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,iCAAiC;AACjC,SAAgB,kBAAkB,CAAC,YAAqB;IACtD,MAAM,SAAS,GAAG,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAC1B,MAAM,YAAY,GAAG,IAAA,oDAA8B,EAAC,SAAS,CAAC,CAAC;IAC/D,OAAO,mBAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;AACpC,CAAC;AAED,iDAAiD;AACjD,SAAgB,wBAAwB,CAAC,KAIxC;IACC,MAAM,YAAY,GAAG,IAAA,0CAA0B,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,YAAY,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE7C,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,MAAM,aAAa,GAAG,0BAA0B,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACnF,IAAI,aAAa;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,gCAAgB,EAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,4CAA4C;AAC5C,SAAgB,0BAA0B,CAAC,KAK1C;IACC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,IAAI,CAAC,mBAAmB;QAAE,OAAO,KAAK,CAAC;IAEvC,MAAM,OAAO,GAAG,wBAAwB,CAAC;QACvC,GAAG,EAAE,mBAAmB;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,eAAe,EAAE,KAAK,CAAC,eAAe;KACvC,CAAC,CAAC;IACH,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,IAAI,CAAC,KAAK,CAAC,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAC3C,gDAAgD;IAChD,OAAO,IAAA,8BAAgB,EAAC,mBAAmB,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitizeThreadForClient = sanitizeThreadForClient;
|
|
4
|
+
const windowsVerbatimPath_1 = require("./windowsVerbatimPath");
|
|
5
|
+
/**
|
|
6
|
+
* 仅用于“对外返回给前端的 thread payload”净化:剥离 Windows `\\?\` 前缀。
|
|
7
|
+
*
|
|
8
|
+
* 说明:
|
|
9
|
+
* - 该函数是 best-effort:只处理 `cwd` 字段,不做深拷贝/深层 normalize;
|
|
10
|
+
* - 主要用于兼容历史线程中已持久化的 `\\?\C:\...`,避免继续污染 UI 展示。
|
|
11
|
+
*/
|
|
12
|
+
function sanitizeThreadForClient(thread) {
|
|
13
|
+
// thread 原始值(允许是 null/非对象)。
|
|
14
|
+
const rawThread = thread;
|
|
15
|
+
if (!rawThread || typeof rawThread !== "object")
|
|
16
|
+
return thread;
|
|
17
|
+
// thread.cwd 原始值(仅处理 string)。
|
|
18
|
+
const rawCwd = typeof rawThread.cwd === "string" ? String(rawThread.cwd) : "";
|
|
19
|
+
if (!rawCwd)
|
|
20
|
+
return thread;
|
|
21
|
+
// 去除 verbatim 前缀后的 cwd。
|
|
22
|
+
const sanitizedCwd = (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(rawCwd);
|
|
23
|
+
if (sanitizedCwd === rawCwd)
|
|
24
|
+
return thread;
|
|
25
|
+
return { ...rawThread, cwd: sanitizedCwd };
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=threadSanitize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threadSanitize.js","sourceRoot":"","sources":["../../src/workspace/threadSanitize.ts"],"names":[],"mappings":";;AASA,0DAcC;AAvBD,+DAAuE;AAEvE;;;;;;GAMG;AACH,SAAgB,uBAAuB,CAAC,MAAe;IACrD,4BAA4B;IAC5B,MAAM,SAAS,GAAG,MAAa,CAAC;IAChC,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAE/D,8BAA8B;IAC9B,MAAM,MAAM,GAAG,OAAO,SAAS,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC;IAE3B,wBAAwB;IACxB,MAAM,YAAY,GAAG,IAAA,oDAA8B,EAAC,MAAM,CAAC,CAAC;IAC5D,IAAI,YAAY,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IAE3C,OAAO,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;AAC7C,CAAC"}
|
|
@@ -11,6 +11,7 @@ const env_1 = require("../env");
|
|
|
11
11
|
const accessControl_1 = require("./accessControl");
|
|
12
12
|
const cwdSwitchLogger_1 = require("./cwdSwitchLogger");
|
|
13
13
|
const fsSafeMkdir_1 = require("./fsSafeMkdir");
|
|
14
|
+
const windowsVerbatimPath_1 = require("./windowsVerbatimPath");
|
|
14
15
|
function normalizeWorkspaceDirInputs(rawWorkspaceDirs) {
|
|
15
16
|
const input = Array.isArray(rawWorkspaceDirs) ? rawWorkspaceDirs : [];
|
|
16
17
|
return input.map((dir) => String(dir ?? "").trim()).filter(Boolean);
|
|
@@ -26,12 +27,16 @@ function mapWorkspaceValidationError(error) {
|
|
|
26
27
|
return { status: 400, code: "invalid_input", details };
|
|
27
28
|
}
|
|
28
29
|
async function resolveRealpathOrFallback(candidatePath) {
|
|
29
|
-
|
|
30
|
+
const rawCandidatePath = String(candidatePath ?? "");
|
|
31
|
+
return promises_1.default
|
|
32
|
+
.realpath(rawCandidatePath)
|
|
33
|
+
.then((realpathValue) => (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(realpathValue))
|
|
34
|
+
.catch(() => (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(node_path_1.default.resolve(rawCandidatePath)));
|
|
30
35
|
}
|
|
31
36
|
function resolveRequestedWorkspaceDir(workspaceDir) {
|
|
32
37
|
// 与 accessControl 的 cwd 解析口径保持一致:相对路径基于 CODEX_CWD。
|
|
33
38
|
const baseCwd = node_path_1.default.resolve((0, env_1.getCodexCwd)());
|
|
34
|
-
const rawWorkspaceDir = String(workspaceDir ?? "").trim();
|
|
39
|
+
const rawWorkspaceDir = (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(String(workspaceDir ?? "").trim());
|
|
35
40
|
if (rawWorkspaceDir.includes("\0"))
|
|
36
41
|
throw new Error("invalid cwd");
|
|
37
42
|
if (!rawWorkspaceDir)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userWorkspaceRoutes.js","sourceRoot":"","sources":["../../src/workspace/userWorkspaceRoutes.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"userWorkspaceRoutes.js","sourceRoot":"","sources":["../../src/workspace/userWorkspaceRoutes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 将 Windows 的 verbatim/extended-length 路径前缀转换为普通路径形式。
|
|
3
|
+
*
|
|
4
|
+
* 背景:在 Windows 原生 Node 环境中,`fs.realpath()` 可能返回 `\\?\C:\...` 或 `\\?\UNC\...`,
|
|
5
|
+
* 这会污染会话的 `cwd` 展示与路径比较。此函数只做“前缀剥离”,避免引入额外的语义变化。
|
|
6
|
+
*/
|
|
7
|
+
export declare function stripWindowsVerbatimPathPrefix(rawPath: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* 将 Windows 绝对路径转换为 verbatim/extended-length 形式(`\\?\` / `\\?\UNC\`)。
|
|
10
|
+
*
|
|
11
|
+
* 用途:`codex` CLI 在 Windows 下可能以 verbatim 形式持久化 cwd/历史记录;
|
|
12
|
+
* 为了稳定命中同一历史存储,本项目在与 codex 交互时需要确保 cwd 带上该前缀。
|
|
13
|
+
*
|
|
14
|
+
* 注意:该函数只负责“加前缀”,不保证路径存在,也不做 realpath。
|
|
15
|
+
*/
|
|
16
|
+
export declare function ensureWindowsVerbatimPathPrefix(rawPath: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* 将 “权限校验通过后的 cwd” 转换为 “传给 codex 的 cwd”。
|
|
19
|
+
*
|
|
20
|
+
* - Windows:返回 verbatim 路径(确保命中 codex 历史存储)。
|
|
21
|
+
* - 非 Windows:原样返回。
|
|
22
|
+
*/
|
|
23
|
+
export declare function coerceCwdForCodex(cwd: string, platform?: string): string;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.stripWindowsVerbatimPathPrefix = stripWindowsVerbatimPathPrefix;
|
|
7
|
+
exports.ensureWindowsVerbatimPathPrefix = ensureWindowsVerbatimPathPrefix;
|
|
8
|
+
exports.coerceCwdForCodex = coerceCwdForCodex;
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
/**
|
|
11
|
+
* 将 Windows 的 verbatim/extended-length 路径前缀转换为普通路径形式。
|
|
12
|
+
*
|
|
13
|
+
* 背景:在 Windows 原生 Node 环境中,`fs.realpath()` 可能返回 `\\?\C:\...` 或 `\\?\UNC\...`,
|
|
14
|
+
* 这会污染会话的 `cwd` 展示与路径比较。此函数只做“前缀剥离”,避免引入额外的语义变化。
|
|
15
|
+
*/
|
|
16
|
+
function stripWindowsVerbatimPathPrefix(rawPath) {
|
|
17
|
+
// 输入字符串(保持 best-effort,不抛异常)。
|
|
18
|
+
const inputPath = String(rawPath ?? "");
|
|
19
|
+
// Windows verbatim 前缀:`\\?\`
|
|
20
|
+
const verbatimPrefix = "\\\\?\\";
|
|
21
|
+
// Windows verbatim UNC 前缀:`\\?\UNC\server\share\...`
|
|
22
|
+
const verbatimUncPrefix = "\\\\?\\UNC\\";
|
|
23
|
+
if (inputPath.startsWith(verbatimUncPrefix)) {
|
|
24
|
+
// `\\?\UNC\server\share\dir` -> `\\server\share\dir`
|
|
25
|
+
const uncTail = inputPath.slice(verbatimUncPrefix.length);
|
|
26
|
+
return `\\\\${uncTail}`;
|
|
27
|
+
}
|
|
28
|
+
if (inputPath.startsWith(verbatimPrefix)) {
|
|
29
|
+
// `\\?\C:\dir` -> `C:\dir`
|
|
30
|
+
return inputPath.slice(verbatimPrefix.length);
|
|
31
|
+
}
|
|
32
|
+
return inputPath;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 将 Windows 绝对路径转换为 verbatim/extended-length 形式(`\\?\` / `\\?\UNC\`)。
|
|
36
|
+
*
|
|
37
|
+
* 用途:`codex` CLI 在 Windows 下可能以 verbatim 形式持久化 cwd/历史记录;
|
|
38
|
+
* 为了稳定命中同一历史存储,本项目在与 codex 交互时需要确保 cwd 带上该前缀。
|
|
39
|
+
*
|
|
40
|
+
* 注意:该函数只负责“加前缀”,不保证路径存在,也不做 realpath。
|
|
41
|
+
*/
|
|
42
|
+
function ensureWindowsVerbatimPathPrefix(rawPath) {
|
|
43
|
+
// 输入路径(best-effort)。
|
|
44
|
+
const inputPath = String(rawPath ?? "");
|
|
45
|
+
if (!inputPath)
|
|
46
|
+
return inputPath;
|
|
47
|
+
// 已经是 verbatim 形式时直接返回。
|
|
48
|
+
const verbatimPrefix = "\\\\?\\";
|
|
49
|
+
if (inputPath.startsWith(verbatimPrefix))
|
|
50
|
+
return inputPath;
|
|
51
|
+
// 将 `/` 统一为 `\`,避免 `toNamespacedPath` 对分隔符差异处理不一致。
|
|
52
|
+
const withBackslashes = inputPath.replace(/\//g, "\\");
|
|
53
|
+
// UNC 路径(`\\server\share`)与盘符路径(`C:\dir`)才需要 verbatim 前缀;相对路径保持不变。
|
|
54
|
+
const isUncPath = withBackslashes.startsWith("\\\\");
|
|
55
|
+
const isDriveAbsolutePath = /^[a-zA-Z]:\\/.test(withBackslashes);
|
|
56
|
+
if (!isUncPath && !isDriveAbsolutePath)
|
|
57
|
+
return inputPath;
|
|
58
|
+
// `path.win32.toNamespacedPath` 会按语义生成 `\\?\` 或 `\\?\UNC\` 前缀。
|
|
59
|
+
// 这里不做 normalize,以避免改变 caller 的大小写/分隔符偏好。
|
|
60
|
+
const namespaced = node_path_1.default.win32.toNamespacedPath(withBackslashes);
|
|
61
|
+
return String(namespaced ?? withBackslashes);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 将 “权限校验通过后的 cwd” 转换为 “传给 codex 的 cwd”。
|
|
65
|
+
*
|
|
66
|
+
* - Windows:返回 verbatim 路径(确保命中 codex 历史存储)。
|
|
67
|
+
* - 非 Windows:原样返回。
|
|
68
|
+
*/
|
|
69
|
+
function coerceCwdForCodex(cwd, platform = process.platform) {
|
|
70
|
+
// 输入 cwd(best-effort)。
|
|
71
|
+
const rawCwd = String(cwd ?? "");
|
|
72
|
+
if (!rawCwd)
|
|
73
|
+
return rawCwd;
|
|
74
|
+
// 平台名(允许测试注入)。
|
|
75
|
+
const normalizedPlatform = String(platform ?? "").trim().toLowerCase();
|
|
76
|
+
if (normalizedPlatform !== "win32")
|
|
77
|
+
return rawCwd;
|
|
78
|
+
return ensureWindowsVerbatimPathPrefix(rawCwd);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=windowsVerbatimPath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"windowsVerbatimPath.js","sourceRoot":"","sources":["../../src/workspace/windowsVerbatimPath.ts"],"names":[],"mappings":";;;;;AAQA,wEAqBC;AAUD,0EAqBC;AAQD,8CAUC;AA9ED,0DAA6B;AAE7B;;;;;GAKG;AACH,SAAgB,8BAA8B,CAAC,OAAe;IAC5D,8BAA8B;IAC9B,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAExC,6BAA6B;IAC7B,MAAM,cAAc,GAAG,SAAS,CAAC;IACjC,qDAAqD;IACrD,MAAM,iBAAiB,GAAG,cAAc,CAAC;IAEzC,IAAI,SAAS,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC5C,qDAAqD;QACrD,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC1D,OAAO,OAAO,OAAO,EAAE,CAAC;IAC1B,CAAC;IAED,IAAI,SAAS,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACzC,2BAA2B;QAC3B,OAAO,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,+BAA+B,CAAC,OAAe;IAC7D,qBAAqB;IACrB,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACxC,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IAEjC,wBAAwB;IACxB,MAAM,cAAc,GAAG,SAAS,CAAC;IACjC,IAAI,SAAS,CAAC,UAAU,CAAC,cAAc,CAAC;QAAE,OAAO,SAAS,CAAC;IAE3D,mDAAmD;IACnD,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEvD,mEAAmE;IACnE,MAAM,SAAS,GAAG,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,mBAAmB,GAAG,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjE,IAAI,CAAC,SAAS,IAAI,CAAC,mBAAmB;QAAE,OAAO,SAAS,CAAC;IAEzD,+DAA+D;IAC/D,0CAA0C;IAC1C,MAAM,UAAU,GAAG,mBAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC,UAAU,IAAI,eAAe,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,GAAW,EAAE,WAAmB,OAAO,CAAC,QAAQ;IAChF,uBAAuB;IACvB,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC;IAE3B,eAAe;IACf,MAAM,kBAAkB,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACvE,IAAI,kBAAkB,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC;IAElD,OAAO,+BAA+B,CAAC,MAAM,CAAC,CAAC;AACjD,CAAC"}
|
package/server/dist/ws/wsHub.js
CHANGED
|
@@ -13,6 +13,8 @@ const threadContextUsage_1 = require("../status/threadContextUsage");
|
|
|
13
13
|
const accessControl_1 = require("../workspace/accessControl");
|
|
14
14
|
const cwdSwitchLogger_1 = require("../workspace/cwdSwitchLogger");
|
|
15
15
|
const threadListVisibility_1 = require("../workspace/threadListVisibility");
|
|
16
|
+
const threadSanitize_1 = require("../workspace/threadSanitize");
|
|
17
|
+
const windowsVerbatimPath_1 = require("../workspace/windowsVerbatimPath");
|
|
16
18
|
const executionPolicy_1 = require("../security/executionPolicy");
|
|
17
19
|
const codexEventProjector_1 = require("../chat/codexEventProjector");
|
|
18
20
|
const fileChangeExtractor_1 = require("../chat/fileChangeExtractor");
|
|
@@ -362,16 +364,18 @@ class WsHub {
|
|
|
362
364
|
});
|
|
363
365
|
const requestedCwd = typeof msg.cwd === "string" ? msg.cwd : "";
|
|
364
366
|
const cwd = await resolveCwdForNewThread(requestedCwd, user);
|
|
367
|
+
const codexCwd = (0, windowsVerbatimPath_1.coerceCwdForCodex)(cwd);
|
|
365
368
|
(0, cwdSwitchLogger_1.logCwdSwitch)({
|
|
366
369
|
event: "ws_open_thread_new",
|
|
367
370
|
username,
|
|
368
371
|
role: user.role,
|
|
369
372
|
requestedCwd,
|
|
370
373
|
canonicalCwd: cwd,
|
|
374
|
+
codexCwd,
|
|
371
375
|
workspacesCount: user.workspaces.length,
|
|
372
376
|
});
|
|
373
377
|
return this.codex.startThread({
|
|
374
|
-
cwd,
|
|
378
|
+
cwd: codexCwd,
|
|
375
379
|
approvalPolicy,
|
|
376
380
|
sandbox,
|
|
377
381
|
model: typeof msg.model === "string" ? msg.model : undefined,
|
|
@@ -382,7 +386,7 @@ class WsHub {
|
|
|
382
386
|
this.setThreadOwner(threadId, ws, username);
|
|
383
387
|
const threadCwd = String(thread?.cwd ?? "");
|
|
384
388
|
if (threadId && threadCwd)
|
|
385
|
-
this.threadCwdById.set(threadId, threadCwd);
|
|
389
|
+
this.threadCwdById.set(threadId, (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(threadCwd));
|
|
386
390
|
const { threadForClient, turns } = this.trimThreadTurnsForClient(thread, this.initialThreadTurnLimit);
|
|
387
391
|
if (username && threadId && turns.length)
|
|
388
392
|
this.cacheThreadTurns(username, threadId, turns);
|
|
@@ -572,8 +576,9 @@ class WsHub {
|
|
|
572
576
|
workspaceFilterCwd,
|
|
573
577
|
routingSnapshot,
|
|
574
578
|
}));
|
|
579
|
+
const sanitizedThreads = visibleThreads.map((thread) => (0, threadSanitize_1.sanitizeThreadForClient)(thread));
|
|
575
580
|
return {
|
|
576
|
-
threads:
|
|
581
|
+
threads: sanitizedThreads,
|
|
577
582
|
workspaceFilterCwd,
|
|
578
583
|
};
|
|
579
584
|
}
|
|
@@ -612,10 +617,15 @@ class WsHub {
|
|
|
612
617
|
// 获取 thread cwd,并缓存到 threadCwdById;用于 WS 事件与审批路由等场景。
|
|
613
618
|
async getOrFetchThreadCwd(threadId) {
|
|
614
619
|
const cached = this.threadCwdById.get(threadId);
|
|
615
|
-
if (cached)
|
|
616
|
-
|
|
620
|
+
if (cached) {
|
|
621
|
+
const sanitizedCachedCwd = (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(String(cached));
|
|
622
|
+
if (sanitizedCachedCwd !== cached)
|
|
623
|
+
this.threadCwdById.set(threadId, sanitizedCachedCwd);
|
|
624
|
+
return sanitizedCachedCwd;
|
|
625
|
+
}
|
|
617
626
|
const thread = await this.codex.readThread(threadId, false);
|
|
618
|
-
const
|
|
627
|
+
const rawCwd = String(thread?.cwd ?? "").trim();
|
|
628
|
+
const cwd = (0, windowsVerbatimPath_1.stripWindowsVerbatimPathPrefix)(rawCwd);
|
|
619
629
|
if (!cwd)
|
|
620
630
|
return null;
|
|
621
631
|
this.threadCwdById.set(threadId, cwd);
|
|
@@ -733,12 +743,13 @@ class WsHub {
|
|
|
733
743
|
const safeLimit = Number.isFinite(limit) ? Math.max(0, Math.floor(limit)) : 0;
|
|
734
744
|
const start = Math.max(0, allTurns.length - safeLimit);
|
|
735
745
|
const sliced = safeLimit > 0 ? allTurns.slice(start) : [];
|
|
736
|
-
const
|
|
746
|
+
const rawThreadForClient = {
|
|
737
747
|
...t,
|
|
738
748
|
turns: sliced,
|
|
739
749
|
turnsStart: start,
|
|
740
750
|
turnsTotal: allTurns.length,
|
|
741
751
|
};
|
|
752
|
+
const threadForClient = (0, threadSanitize_1.sanitizeThreadForClient)(rawThreadForClient);
|
|
742
753
|
return { threadForClient, turns: allTurns };
|
|
743
754
|
}
|
|
744
755
|
/**
|