deskbuddy 0.2.0-beta.41 → 0.2.0-beta.43
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.
|
@@ -7,14 +7,49 @@ import { dirname as dirname19, join as join37 } from "path";
|
|
|
7
7
|
import { randomUUID } from "crypto";
|
|
8
8
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
9
9
|
import { homedir, hostname } from "os";
|
|
10
|
-
import { dirname, join } from "path";
|
|
11
|
-
function defaultRemoteCwd(home = homedir()
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
import { dirname, join, resolve } from "path";
|
|
11
|
+
function defaultRemoteCwd(home = homedir()) {
|
|
12
|
+
return process.env.DESKBUDDY_DEFAULT_REMOTE_CWD || join(home, "DeskBuddy");
|
|
13
|
+
}
|
|
14
|
+
function legacyRemoteCwds(home = homedir()) {
|
|
15
|
+
return [join(home, "Desktop"), join(home, "OneDrive", "Desktop")];
|
|
16
|
+
}
|
|
17
|
+
function samePath(a, b, platform) {
|
|
18
|
+
const n = (p) => {
|
|
19
|
+
const r = resolve(p).replace(/[\\/]+$/, "");
|
|
20
|
+
return platform === "win32" ? r.toLowerCase() : r;
|
|
21
|
+
};
|
|
22
|
+
return n(a) === n(b);
|
|
23
|
+
}
|
|
24
|
+
function ensureDefaultRemoteCwd(cwd) {
|
|
25
|
+
if (!cwd || !samePath(cwd, defaultRemoteCwd(), process.platform)) return;
|
|
26
|
+
try {
|
|
27
|
+
mkdirSync(cwd, { recursive: true });
|
|
28
|
+
} catch {
|
|
16
29
|
}
|
|
17
|
-
|
|
30
|
+
}
|
|
31
|
+
function remoteCwdReady() {
|
|
32
|
+
const cwd = loadConfig().remoteCwd || "";
|
|
33
|
+
ensureDefaultRemoteCwd(cwd);
|
|
34
|
+
return cwd;
|
|
35
|
+
}
|
|
36
|
+
function migrateRemoteCwd(home = homedir(), platform = process.platform) {
|
|
37
|
+
const cfg = loadConfig();
|
|
38
|
+
if (cfg.remoteCwdMigrated || !cfg.boundAt) return null;
|
|
39
|
+
const from = cfg.remoteCwd || "";
|
|
40
|
+
const hit = !!from && legacyRemoteCwds(home).some((p) => samePath(from, p, platform));
|
|
41
|
+
const to = defaultRemoteCwd(home);
|
|
42
|
+
if (hit) {
|
|
43
|
+
try {
|
|
44
|
+
mkdirSync(to, { recursive: true });
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
cfg.remoteCwd = to;
|
|
49
|
+
}
|
|
50
|
+
cfg.remoteCwdMigrated = true;
|
|
51
|
+
saveConfig(cfg);
|
|
52
|
+
return hit ? { from, to } : null;
|
|
18
53
|
}
|
|
19
54
|
var PROD_API_BASE = "https://api.shifengintelli.com";
|
|
20
55
|
var TEST_API_BASE = "https://test-api.shifengintelli.com";
|
|
@@ -144,6 +179,7 @@ function loadConfig() {
|
|
|
144
179
|
// 于是下一次保存还会把它抹掉),而且全程不报错
|
|
145
180
|
boundApiBase: parsed.boundApiBase,
|
|
146
181
|
remoteCwd: parsed.remoteCwd,
|
|
182
|
+
remoteCwdMigrated: parsed.remoteCwdMigrated === true ? true : void 0,
|
|
147
183
|
// 不认识的值一律回落默认,不能让一个手滑写错的配置变成"全放行"或"全拦"
|
|
148
184
|
approvalPolicy: parsed.approvalPolicy === "all" ? "all" : parsed.approvalPolicy === "commands" ? "commands" : void 0,
|
|
149
185
|
codexAppServer: typeof parsed.codexAppServer === "string" ? parsed.codexAppServer : void 0,
|
|
@@ -314,13 +350,13 @@ import { execFile, spawn } from "child_process";
|
|
|
314
350
|
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
315
351
|
import { homedir as homedir2 } from "os";
|
|
316
352
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
317
|
-
import { basename as basename2, dirname as dirname4, join as join4, resolve as
|
|
353
|
+
import { basename as basename2, dirname as dirname4, join as join4, resolve as resolve3 } from "path";
|
|
318
354
|
import { promisify } from "util";
|
|
319
355
|
|
|
320
356
|
// src/core/versions.ts
|
|
321
357
|
import { execFileSync } from "child_process";
|
|
322
358
|
import { cpSync, existsSync as existsSync3, mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync3, renameSync as renameSync3, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
323
|
-
import { basename, dirname as dirname3, join as join3, relative, resolve, sep } from "path";
|
|
359
|
+
import { basename, dirname as dirname3, join as join3, relative, resolve as resolve2, sep } from "path";
|
|
324
360
|
function versionsDir(home = deskbuddyHome()) {
|
|
325
361
|
return join3(home, "versions");
|
|
326
362
|
}
|
|
@@ -400,7 +436,7 @@ function markGood(version, home) {
|
|
|
400
436
|
return true;
|
|
401
437
|
}
|
|
402
438
|
function versionDirOf(cliPath, home) {
|
|
403
|
-
const rel = relative(versionsDir(home),
|
|
439
|
+
const rel = relative(versionsDir(home), resolve2(cliPath));
|
|
404
440
|
if (!rel || rel.startsWith("..") || rel.startsWith(sep) || /^[a-zA-Z]:/.test(rel)) return null;
|
|
405
441
|
const first = rel.split(/[\\/]/)[0];
|
|
406
442
|
return isValidVersion(first) ? first : null;
|
|
@@ -516,7 +552,7 @@ function registerRunningCli(running, deps = {}) {
|
|
|
516
552
|
if (!isValidVersion(running.version) || running.version.startsWith("0.0.0")) {
|
|
517
553
|
throw new Error(`\u5F00\u53D1\u7248\uFF08${running.version}\uFF09\u4E0D\u767B\u8BB0`);
|
|
518
554
|
}
|
|
519
|
-
let cliPath =
|
|
555
|
+
let cliPath = resolve2(running.cliPath);
|
|
520
556
|
if (!existsSync3(cliPath)) throw new Error(`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${cliPath}`);
|
|
521
557
|
let how = "already";
|
|
522
558
|
let note;
|
|
@@ -910,7 +946,7 @@ function autostartPointsTo(configText, home) {
|
|
|
910
946
|
});
|
|
911
947
|
}
|
|
912
948
|
function isCustomHome(home = deskbuddyHome(), defaultHome = join4(homedir2(), ".deskbuddy")) {
|
|
913
|
-
return
|
|
949
|
+
return resolve3(home) !== resolve3(defaultHome);
|
|
914
950
|
}
|
|
915
951
|
async function uninstallAutostart(platform = process.platform, deps = {}) {
|
|
916
952
|
const d = { ...defaultUninstallDeps(), ...deps };
|
|
@@ -2640,10 +2676,12 @@ function codexPermissionsCard(p) {
|
|
|
2640
2676
|
const summary = `\u7533\u8BF7${parts.join("\u3001")}${reason ? `\uFF1A${reason}` : ""}`;
|
|
2641
2677
|
const options = [
|
|
2642
2678
|
{ id: "allow", label: "Allow once", description: "\u8FD9\u4E00\u8F6E\u653E\u5F00\u7533\u8BF7\u7684\u6743\u9650", kind: "allow" },
|
|
2679
|
+
{ id: "session", label: "Allow this conversation", description: "\u8FD9\u4E2A\u5BF9\u8BDD\u91CC\u4E4B\u540E\u540C\u6837\u7684\u7533\u8BF7\u90FD\u653E\u5F00", kind: "allow_session" },
|
|
2643
2680
|
{ id: "deny", label: "Deny", kind: "deny" }
|
|
2644
2681
|
];
|
|
2645
2682
|
const actions = {
|
|
2646
2683
|
allow: { decision: "allow", native: { permissions: grant, scope: "turn" } },
|
|
2684
|
+
session: { decision: "allow", native: { permissions: grant, scope: "session" } },
|
|
2647
2685
|
deny: { decision: "deny", native: { permissions: {}, scope: "turn" } }
|
|
2648
2686
|
};
|
|
2649
2687
|
const set = checkOptions({ options, actions });
|
|
@@ -3182,7 +3220,7 @@ function traeNoticeSummary(toolName, toolInput, described, notice) {
|
|
|
3182
3220
|
// src/daemon/workbuddyApp/keeper.ts
|
|
3183
3221
|
import { execFile as execFile6, spawn as spawn2 } from "child_process";
|
|
3184
3222
|
import { existsSync as existsSync19, mkdirSync as mkdirSync21, readdirSync as readdirSync10, readFileSync as readFileSync24, renameSync as renameSync15, writeFileSync as writeFileSync21 } from "fs";
|
|
3185
|
-
import { delimiter as delimiter3, join as join22, resolve as
|
|
3223
|
+
import { delimiter as delimiter3, join as join22, resolve as resolve5 } from "path";
|
|
3186
3224
|
|
|
3187
3225
|
// src/core/process.ts
|
|
3188
3226
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
@@ -3710,7 +3748,7 @@ function resolveAlias(sessionId, now = Date.now()) {
|
|
|
3710
3748
|
import { execFile as execFile3, execFileSync as execFileSync7 } from "child_process";
|
|
3711
3749
|
import { chmodSync as chmodSync3, existsSync as existsSync14, mkdirSync as mkdirSync16, readdirSync as readdirSync6, readFileSync as readFileSync17, rmdirSync, rmSync as rmSync9, writeFileSync as writeFileSync16 } from "fs";
|
|
3712
3750
|
import { homedir as homedir3 } from "os";
|
|
3713
|
-
import { delimiter, join as join15, resolve as
|
|
3751
|
+
import { delimiter, join as join15, resolve as resolve4 } from "path";
|
|
3714
3752
|
var SHIM_FALLBACK_EXIT = 213;
|
|
3715
3753
|
var WIN_SHIM_ENABLED = true;
|
|
3716
3754
|
var SHIM_COMMANDS = { claude_code: "claude", codex: "codex" };
|
|
@@ -3823,7 +3861,7 @@ function cmdScript(tool, command, node, cli, bin) {
|
|
|
3823
3861
|
].join("\r\n");
|
|
3824
3862
|
}
|
|
3825
3863
|
function rcBlock(binDir, rcHome) {
|
|
3826
|
-
const std =
|
|
3864
|
+
const std = resolve4(rcHome, ".deskbuddy", "bin") === resolve4(binDir);
|
|
3827
3865
|
const dir2 = std ? "$HOME/.deskbuddy/bin" : binDir.replace(/(["\\$`])/g, "\\$1");
|
|
3828
3866
|
return [
|
|
3829
3867
|
RC_BEGIN,
|
|
@@ -4948,16 +4986,16 @@ var defaultProbe = createVersionProbe({
|
|
|
4948
4986
|
return classifySyncError(e);
|
|
4949
4987
|
}
|
|
4950
4988
|
},
|
|
4951
|
-
runAsync: (loc) => new Promise((
|
|
4989
|
+
runAsync: (loc) => new Promise((resolve7) => {
|
|
4952
4990
|
try {
|
|
4953
4991
|
execFile4(
|
|
4954
4992
|
loc.file,
|
|
4955
4993
|
[...loc.prefixArgs, "--version"],
|
|
4956
4994
|
{ encoding: "utf8", windowsHide: true, timeout: PROBE_TIMEOUT_MS, env: probeEnv(loc) },
|
|
4957
|
-
(err, stdout2, stderr) =>
|
|
4995
|
+
(err, stdout2, stderr) => resolve7(err ? classifyAsyncError(err, String(stdout2 ?? ""), String(stderr ?? "")) : { kind: "done", out: `${stdout2}${stderr}` })
|
|
4958
4996
|
);
|
|
4959
4997
|
} catch {
|
|
4960
|
-
|
|
4998
|
+
resolve7({ kind: "spawn_error" });
|
|
4961
4999
|
}
|
|
4962
5000
|
}),
|
|
4963
5001
|
now: () => Date.now()
|
|
@@ -5535,12 +5573,12 @@ function defaultWbElectron(d = defaultLocateDeps()) {
|
|
|
5535
5573
|
}
|
|
5536
5574
|
}
|
|
5537
5575
|
function defaultAppRunning(platform = process.platform) {
|
|
5538
|
-
return new Promise((
|
|
5576
|
+
return new Promise((resolve7) => {
|
|
5539
5577
|
try {
|
|
5540
5578
|
if (platform === "darwin") {
|
|
5541
5579
|
execFile5("pgrep", ["-f", "WorkBuddy.app/Contents/MacOS/"], { timeout: 5e3 }, (err) => {
|
|
5542
5580
|
const code = err?.code;
|
|
5543
|
-
|
|
5581
|
+
resolve7(!err ? true : code === 1 ? false : true);
|
|
5544
5582
|
});
|
|
5545
5583
|
return;
|
|
5546
5584
|
}
|
|
@@ -5549,13 +5587,13 @@ function defaultAppRunning(platform = process.platform) {
|
|
|
5549
5587
|
"tasklist",
|
|
5550
5588
|
["/FI", "IMAGENAME eq WorkBuddy.exe", "/FO", "CSV", "/NH"],
|
|
5551
5589
|
{ timeout: 1e4, windowsHide: true, encoding: "utf8" },
|
|
5552
|
-
(err, stdout2) =>
|
|
5590
|
+
(err, stdout2) => resolve7(err ? true : /"WorkBuddy\.exe"/i.test(String(stdout2)))
|
|
5553
5591
|
);
|
|
5554
5592
|
return;
|
|
5555
5593
|
}
|
|
5556
|
-
|
|
5594
|
+
resolve7(true);
|
|
5557
5595
|
} catch {
|
|
5558
|
-
|
|
5596
|
+
resolve7(true);
|
|
5559
5597
|
}
|
|
5560
5598
|
});
|
|
5561
5599
|
}
|
|
@@ -5590,13 +5628,13 @@ var defaultWbAppDbDeps = () => ({
|
|
|
5590
5628
|
configDir: () => dirname12(workbuddySettingsPath()),
|
|
5591
5629
|
loadSqlite: loadNodeSqlite,
|
|
5592
5630
|
electron: () => defaultWbElectron(),
|
|
5593
|
-
runElectron: (bin, script, input) => new Promise((
|
|
5631
|
+
runElectron: (bin, script, input) => new Promise((resolve7, reject) => {
|
|
5594
5632
|
const env = { ...process.env, ELECTRON_RUN_AS_NODE: "1" };
|
|
5595
5633
|
const c = execFile5(
|
|
5596
5634
|
bin,
|
|
5597
5635
|
["-e", script],
|
|
5598
5636
|
{ env, timeout: 15e3, windowsHide: true, maxBuffer: 1024 * 1024 },
|
|
5599
|
-
(err, stdout2) => err ? reject(err) :
|
|
5637
|
+
(err, stdout2) => err ? reject(err) : resolve7(String(stdout2))
|
|
5600
5638
|
);
|
|
5601
5639
|
c.stdin?.on("error", () => {
|
|
5602
5640
|
});
|
|
@@ -5741,12 +5779,12 @@ function openWs(target, port, d, info) {
|
|
|
5741
5779
|
const url = loopbackWsUrl(target.webSocketDebuggerUrl, port);
|
|
5742
5780
|
if (!url) return Promise.reject(new Error("\u4E3B\u7A97\u53E3\u7684\u8C03\u8BD5\u5730\u5740\u4E0D\u5BF9"));
|
|
5743
5781
|
const ws = (d.ws ?? ((u) => new WebSocket(u, { handshakeTimeout: 5e3 })))(url);
|
|
5744
|
-
return new Promise((
|
|
5782
|
+
return new Promise((resolve7, reject) => {
|
|
5745
5783
|
let opened = false;
|
|
5746
5784
|
const client = new WsCdpClient(ws, info);
|
|
5747
5785
|
ws.on("open", () => {
|
|
5748
5786
|
opened = true;
|
|
5749
|
-
|
|
5787
|
+
resolve7(client);
|
|
5750
5788
|
});
|
|
5751
5789
|
ws.on("error", (e) => {
|
|
5752
5790
|
if (!opened) reject(e instanceof Error ? e : new Error("CDP \u8FDE\u63A5\u5931\u8D25"));
|
|
@@ -5844,12 +5882,12 @@ var WsCdpClient = class {
|
|
|
5844
5882
|
#rpc(method, params, timeoutMs, raw) {
|
|
5845
5883
|
if (this.#closed) return Promise.reject(new Error("CDP \u8FDE\u63A5\u5DF2\u65AD\u5F00"));
|
|
5846
5884
|
const id = ++this.#id;
|
|
5847
|
-
return new Promise((
|
|
5885
|
+
return new Promise((resolve7, reject) => {
|
|
5848
5886
|
const timer = setTimeout(() => {
|
|
5849
5887
|
this.#waiting.delete(id);
|
|
5850
5888
|
reject(new Error("\u9875\u9762\u811A\u672C\u8D85\u65F6"));
|
|
5851
5889
|
}, timeoutMs);
|
|
5852
|
-
this.#waiting.set(id, { resolve:
|
|
5890
|
+
this.#waiting.set(id, { resolve: resolve7, reject, timer, ...raw ? { raw } : {} });
|
|
5853
5891
|
try {
|
|
5854
5892
|
this.#ws.send(JSON.stringify({ id, method, params }));
|
|
5855
5893
|
} catch (e) {
|
|
@@ -5909,7 +5947,7 @@ function cleanLaunchEnv(src = process.env, shim = shimDir()) {
|
|
|
5909
5947
|
const out = {};
|
|
5910
5948
|
const shimReal = (() => {
|
|
5911
5949
|
try {
|
|
5912
|
-
return
|
|
5950
|
+
return resolve5(shim);
|
|
5913
5951
|
} catch {
|
|
5914
5952
|
return shim;
|
|
5915
5953
|
}
|
|
@@ -5922,7 +5960,7 @@ function cleanLaunchEnv(src = process.env, shim = shimDir()) {
|
|
|
5922
5960
|
if (pathKey && typeof out[pathKey] === "string") {
|
|
5923
5961
|
out[pathKey] = out[pathKey].split(delimiter3).filter((p) => {
|
|
5924
5962
|
try {
|
|
5925
|
-
return
|
|
5963
|
+
return resolve5(p) !== shimReal;
|
|
5926
5964
|
} catch {
|
|
5927
5965
|
return p !== shim;
|
|
5928
5966
|
}
|
|
@@ -6722,7 +6760,7 @@ async function defaultWinProcs() {
|
|
|
6722
6760
|
// src/daemon/qoderApp/task.ts
|
|
6723
6761
|
import { createHash as createHash3 } from "crypto";
|
|
6724
6762
|
import { realpathSync as realpathSync3 } from "fs";
|
|
6725
|
-
import { resolve as
|
|
6763
|
+
import { resolve as resolve6 } from "path";
|
|
6726
6764
|
|
|
6727
6765
|
// src/daemon/command.ts
|
|
6728
6766
|
var SERVICE_COMMAND = "deskbuddy.command";
|
|
@@ -6994,7 +7032,7 @@ function normalizeCwd(p, platform = process.platform, real = (x) => realpathSync
|
|
|
6994
7032
|
r = r.replace(/\//g, "\\").replace(/\\+$/, "");
|
|
6995
7033
|
return (/^[a-z]:$/i.test(r) ? r + "\\" : r).toLowerCase().replace(/\\/g, "/");
|
|
6996
7034
|
}
|
|
6997
|
-
r =
|
|
7035
|
+
r = resolve6(r);
|
|
6998
7036
|
return r.length > 1 ? r.replace(/\/+$/, "") : r;
|
|
6999
7037
|
}
|
|
7000
7038
|
function appBusy(st) {
|
|
@@ -8468,7 +8506,7 @@ var DumateWatch = class {
|
|
|
8468
8506
|
}
|
|
8469
8507
|
};
|
|
8470
8508
|
function runHook(node, input, agentPid, tool = "dumate") {
|
|
8471
|
-
return new Promise((
|
|
8509
|
+
return new Promise((resolve7) => {
|
|
8472
8510
|
let child;
|
|
8473
8511
|
try {
|
|
8474
8512
|
child = spawn3(node, [installedHookPath(), tool], {
|
|
@@ -8476,18 +8514,18 @@ function runHook(node, input, agentPid, tool = "dumate") {
|
|
|
8476
8514
|
env: { ...process.env, DESKBUDDY_AGENT_PID: String(agentPid) }
|
|
8477
8515
|
});
|
|
8478
8516
|
} catch {
|
|
8479
|
-
|
|
8517
|
+
resolve7();
|
|
8480
8518
|
return;
|
|
8481
8519
|
}
|
|
8482
8520
|
const timer = setTimeout(() => child.kill("SIGKILL"), HOOK_KILL_MS);
|
|
8483
8521
|
timer.unref?.();
|
|
8484
8522
|
child.on("error", () => {
|
|
8485
8523
|
clearTimeout(timer);
|
|
8486
|
-
|
|
8524
|
+
resolve7();
|
|
8487
8525
|
});
|
|
8488
8526
|
child.on("close", () => {
|
|
8489
8527
|
clearTimeout(timer);
|
|
8490
|
-
|
|
8528
|
+
resolve7();
|
|
8491
8529
|
});
|
|
8492
8530
|
child.stdin.on("error", () => {
|
|
8493
8531
|
});
|
|
@@ -10538,7 +10576,7 @@ function startCommand(plan, tool, limitMs = EXEC_TIMEOUT_MS) {
|
|
|
10538
10576
|
}, Math.max(0, remaining));
|
|
10539
10577
|
};
|
|
10540
10578
|
let timedOut = false;
|
|
10541
|
-
const done = new Promise((
|
|
10579
|
+
const done = new Promise((resolve7) => {
|
|
10542
10580
|
child = execFile7(
|
|
10543
10581
|
plan.file,
|
|
10544
10582
|
plan.args,
|
|
@@ -10558,10 +10596,10 @@ function startCommand(plan, tool, limitMs = EXEC_TIMEOUT_MS) {
|
|
|
10558
10596
|
if (err || timedOut) {
|
|
10559
10597
|
const e = err;
|
|
10560
10598
|
const msg = timedOut ? `\u6267\u884C\u8D85\u8FC7 ${Math.round(limitMs / 1e3)} \u79D2\u6D3B\u52A8\u65F6\u95F4\uFF0C\u5DF2\u7EC8\u6B62` : e && typeof e.code === "number" ? `\u9000\u51FA\u7801 ${e.code}` : e && e.signal ? `\u88AB\u4FE1\u53F7 ${String(e.signal)} \u7ED3\u675F` : `\u8D77\u4E0D\u6765\uFF08${String(e?.code ?? "unknown")}\uFF09`;
|
|
10561
|
-
|
|
10599
|
+
resolve7({ ok: false, sessionId: parseSessionId(tool, out), stdout: out, stderr: errOut, error: msg });
|
|
10562
10600
|
return;
|
|
10563
10601
|
}
|
|
10564
|
-
|
|
10602
|
+
resolve7({ ok: true, sessionId: parseSessionId(tool, out), stdout: out, stderr: errOut });
|
|
10565
10603
|
}
|
|
10566
10604
|
);
|
|
10567
10605
|
child?.stdin?.end();
|
|
@@ -10700,8 +10738,8 @@ var defaultGuiDeps = () => ({
|
|
|
10700
10738
|
var defaultOpenerDeps = (findWt2) => ({
|
|
10701
10739
|
platform: process.platform,
|
|
10702
10740
|
findWt: findWt2,
|
|
10703
|
-
run: (file3, args) => new Promise((
|
|
10704
|
-
execFile8(file3, args, { windowsHide: true, timeout: 15e3 }, (err) => err ? reject(err) :
|
|
10741
|
+
run: (file3, args) => new Promise((resolve7, reject) => {
|
|
10742
|
+
execFile8(file3, args, { windowsHide: true, timeout: 15e3 }, (err) => err ? reject(err) : resolve7());
|
|
10705
10743
|
}),
|
|
10706
10744
|
spawnDetached: (file3, args) => {
|
|
10707
10745
|
const c = spawn4(file3, args, { detached: true, stdio: "ignore", shell: false, windowsHide: false });
|
|
@@ -10872,12 +10910,12 @@ async function checkLogin(tool, d) {
|
|
|
10872
10910
|
return { tool, state: "unknown", note: `\u68C0\u6D4B\u51FA\u9519\uFF1A${e?.message ?? e}` };
|
|
10873
10911
|
}
|
|
10874
10912
|
}
|
|
10875
|
-
var defaultProbeRun = (file3, args, env, timeoutMs) => new Promise((
|
|
10913
|
+
var defaultProbeRun = (file3, args, env, timeoutMs) => new Promise((resolve7) => {
|
|
10876
10914
|
let settled = false;
|
|
10877
10915
|
const done = (r) => {
|
|
10878
10916
|
if (settled) return;
|
|
10879
10917
|
settled = true;
|
|
10880
|
-
|
|
10918
|
+
resolve7(r);
|
|
10881
10919
|
};
|
|
10882
10920
|
const win = process.platform === "win32";
|
|
10883
10921
|
const opts = { env, windowsHide: true, maxBuffer: 8 * 1024 * 1024, detached: !win };
|
|
@@ -11074,7 +11112,7 @@ var defaultLoginOpenDeps = () => ({
|
|
|
11074
11112
|
});
|
|
11075
11113
|
async function installCodebuddyHooks(log) {
|
|
11076
11114
|
try {
|
|
11077
|
-
const { installTools: installTools2 } = await import("./enable-
|
|
11115
|
+
const { installTools: installTools2 } = await import("./enable-AF2A67ZD.js");
|
|
11078
11116
|
installTools2(["workbuddy"], () => {
|
|
11079
11117
|
}, null, { auto: true });
|
|
11080
11118
|
} catch (e) {
|
|
@@ -11277,7 +11315,7 @@ var DIALOG_TEXT = [
|
|
|
11277
11315
|
`\u73B0\u5728\u5B89\u88C5\u5417\uFF1F\uFF08\u4F1A\u6267\u884C npm i -g ${WORKBUDDY_STANDALONE_PKG}\uFF0C\u7EA6\u9700\u4E00\u4E24\u5206\u949F\uFF0C\u88C5\u5B8C\u4F1A\u6253\u5F00\u4E00\u4E2A\u7EC8\u7AEF\u7A97\u53E3\uFF0C\u6309\u63D0\u793A\u9009 Log in via Chinese Site\uFF08\u56FD\u5185\u7248\uFF09\u767B\u5F55\uFF1B\u7EC8\u7AEF\u7A97\u53E3\u5982\u679C\u662F\u9ED1\u7684\uFF0C\u6309\u4E00\u4E0B\u56DE\u8F66\u5C31\u4F1A\u663E\u793A\uFF09`
|
|
11278
11316
|
].join("\n");
|
|
11279
11317
|
var LIMITED_NOTE = "\u8BBE\u5907\u4E0A\u53EA\u80FD\u770B\u4EFB\u52A1\u72B6\u6001\u3001\u56DE\u7B54\u6388\u6743";
|
|
11280
|
-
var defaultRunner = (file3, args, opts) => new Promise((
|
|
11318
|
+
var defaultRunner = (file3, args, opts) => new Promise((resolve7) => {
|
|
11281
11319
|
try {
|
|
11282
11320
|
const child = execFile10(
|
|
11283
11321
|
file3,
|
|
@@ -11285,7 +11323,7 @@ var defaultRunner = (file3, args, opts) => new Promise((resolve6) => {
|
|
|
11285
11323
|
{ env: opts.env, timeout: opts.timeoutMs, windowsHide: true, maxBuffer: 8 * 1024 * 1024, encoding: "utf8" },
|
|
11286
11324
|
(err, stdout2, stderr) => {
|
|
11287
11325
|
const e = err;
|
|
11288
|
-
|
|
11326
|
+
resolve7({
|
|
11289
11327
|
code: e ? typeof e.code === "number" ? e.code : null : 0,
|
|
11290
11328
|
stdout: String(stdout2 ?? ""),
|
|
11291
11329
|
stderr: String(stderr ?? ""),
|
|
@@ -11296,7 +11334,7 @@ var defaultRunner = (file3, args, opts) => new Promise((resolve6) => {
|
|
|
11296
11334
|
);
|
|
11297
11335
|
child.stdin?.end();
|
|
11298
11336
|
} catch {
|
|
11299
|
-
|
|
11337
|
+
resolve7({ code: null, stdout: "", stderr: "", timedOut: false, spawnError: true });
|
|
11300
11338
|
}
|
|
11301
11339
|
});
|
|
11302
11340
|
function checkTimeout(s) {
|
|
@@ -11588,7 +11626,7 @@ function defaultOfferDeps(log) {
|
|
|
11588
11626
|
}),
|
|
11589
11627
|
openLogin: () => defaultOpenLogin(platform),
|
|
11590
11628
|
installHooks: async () => {
|
|
11591
|
-
const { installTools: installTools2 } = await import("./enable-
|
|
11629
|
+
const { installTools: installTools2 } = await import("./enable-AF2A67ZD.js");
|
|
11592
11630
|
installTools2(["workbuddy"], (l) => log(`[WorkBuddy \u72EC\u7ACB\u7248] ${l}`), null, { auto: true });
|
|
11593
11631
|
},
|
|
11594
11632
|
log: (l) => log(`[WorkBuddy \u72EC\u7ACB\u7248] ${l}`),
|
|
@@ -11829,6 +11867,9 @@ async function runEnable(tools, opts = {}) {
|
|
|
11829
11867
|
|
|
11830
11868
|
export {
|
|
11831
11869
|
defaultRemoteCwd,
|
|
11870
|
+
ensureDefaultRemoteCwd,
|
|
11871
|
+
remoteCwdReady,
|
|
11872
|
+
migrateRemoteCwd,
|
|
11832
11873
|
PROD_API_BASE,
|
|
11833
11874
|
TEST_API_BASE,
|
|
11834
11875
|
environmentLabel,
|
package/dist/cli.js
CHANGED
|
@@ -114,6 +114,7 @@ import {
|
|
|
114
114
|
detectTools,
|
|
115
115
|
dshOptions,
|
|
116
116
|
ensureClientId,
|
|
117
|
+
ensureDefaultRemoteCwd,
|
|
117
118
|
ensureDumateShortcuts,
|
|
118
119
|
ensureQoderShortcuts,
|
|
119
120
|
ensureQwenworkShortcuts,
|
|
@@ -173,6 +174,7 @@ import {
|
|
|
173
174
|
markWbAppSession,
|
|
174
175
|
materialize,
|
|
175
176
|
migrateLegacyQoder,
|
|
177
|
+
migrateRemoteCwd,
|
|
176
178
|
ocPluginModule,
|
|
177
179
|
openTerminal,
|
|
178
180
|
opencodeOptions,
|
|
@@ -210,6 +212,7 @@ import {
|
|
|
210
212
|
recordAttemptFailure,
|
|
211
213
|
refreshRegistry,
|
|
212
214
|
registerWorkbuddySession,
|
|
215
|
+
remoteCwdReady,
|
|
213
216
|
removeCommandFile,
|
|
214
217
|
removeWakeMark,
|
|
215
218
|
replyVerdict,
|
|
@@ -271,7 +274,7 @@ import {
|
|
|
271
274
|
writeState,
|
|
272
275
|
writeWakeMark,
|
|
273
276
|
writeWakeSecret
|
|
274
|
-
} from "./chunk-
|
|
277
|
+
} from "./chunk-ET52BEIS.js";
|
|
275
278
|
|
|
276
279
|
// src/commands/config.ts
|
|
277
280
|
function runConfig(args, out = (s2) => process.stdout.write(s2 + "\n")) {
|
|
@@ -16296,6 +16299,12 @@ var Daemon = class {
|
|
|
16296
16299
|
log(`\u6388\u6743\u7AEF\u70B9\u5DF2\u5C31\u7EEA 127.0.0.1:${port}`);
|
|
16297
16300
|
enableFatalReport(deskbuddyHome());
|
|
16298
16301
|
log(`${envLine()}\uFF1B${memLine()}`);
|
|
16302
|
+
try {
|
|
16303
|
+
const m = migrateRemoteCwd();
|
|
16304
|
+
if (m) log(`\u8FDC\u7A0B\u65B0\u5EFA\u4EFB\u52A1\u7684\u9ED8\u8BA4\u76EE\u5F55\u5DF2\u4ECE ${m.from} \u6539\u4E3A ${m.to}\uFF08\u684C\u9762\u53D7\u7CFB\u7EDF\u4FDD\u62A4\u3001\u4F1A\u88AB\u540C\u6B65\u4E0A\u4E91\uFF1B\u60F3\u6362\u56DE\u6765\u8DD1 deskbuddy setup\uFF09`);
|
|
16305
|
+
} catch (e) {
|
|
16306
|
+
log(`\u8FDC\u7A0B\u65B0\u5EFA\u4EFB\u52A1\u76EE\u5F55\u8FC1\u79FB\u51FA\u9519\uFF1A${e?.message ?? e}`);
|
|
16307
|
+
}
|
|
16299
16308
|
this.#memLog = setInterval(() => log(memLine()), MEM_LOG_MS);
|
|
16300
16309
|
this.#memLog.unref();
|
|
16301
16310
|
this.#windowScan = setInterval(() => this.#coord.scanWindows(), 1e3);
|
|
@@ -17033,7 +17042,7 @@ var Daemon = class {
|
|
|
17033
17042
|
this.#report(cmd, "", "rejected", "", "dir_gone");
|
|
17034
17043
|
return;
|
|
17035
17044
|
}
|
|
17036
|
-
} else cwd =
|
|
17045
|
+
} else cwd = remoteCwdReady();
|
|
17037
17046
|
this.#toDumateNew(cmd, cwd);
|
|
17038
17047
|
return;
|
|
17039
17048
|
}
|
|
@@ -17064,7 +17073,7 @@ var Daemon = class {
|
|
|
17064
17073
|
return;
|
|
17065
17074
|
}
|
|
17066
17075
|
} else {
|
|
17067
|
-
cwd =
|
|
17076
|
+
cwd = remoteCwdReady();
|
|
17068
17077
|
if (!cwd) {
|
|
17069
17078
|
this.#report(cmd, "", "rejected", "", "no_remote_cwd");
|
|
17070
17079
|
return;
|
|
@@ -17082,7 +17091,7 @@ var Daemon = class {
|
|
|
17082
17091
|
return;
|
|
17083
17092
|
}
|
|
17084
17093
|
} else {
|
|
17085
|
-
cwd =
|
|
17094
|
+
cwd = remoteCwdReady();
|
|
17086
17095
|
if (!cwd) {
|
|
17087
17096
|
this.#report(cmd, "", "rejected", "", "no_remote_cwd");
|
|
17088
17097
|
return;
|
|
@@ -17288,7 +17297,7 @@ var Daemon = class {
|
|
|
17288
17297
|
return;
|
|
17289
17298
|
}
|
|
17290
17299
|
} else {
|
|
17291
|
-
cwd =
|
|
17300
|
+
cwd = remoteCwdReady();
|
|
17292
17301
|
if (!cwd) {
|
|
17293
17302
|
this.#report(cmd, "", "rejected", "", "no_remote_cwd");
|
|
17294
17303
|
return;
|
|
@@ -18054,7 +18063,7 @@ var Daemon = class {
|
|
|
18054
18063
|
}
|
|
18055
18064
|
const target = resolveTarget(cmd, {
|
|
18056
18065
|
readState,
|
|
18057
|
-
remoteCwd: () =>
|
|
18066
|
+
remoteCwd: () => remoteCwdReady(),
|
|
18058
18067
|
alias: resolveAlias,
|
|
18059
18068
|
dirOf: (ref) => dirOf(ref),
|
|
18060
18069
|
windowOpen: (s2) => s2.interactive === true && !!s2.pid && isAlive(s2.pid, s2.pidName)
|
|
@@ -18794,6 +18803,8 @@ function verdictMessage(reason, path) {
|
|
|
18794
18803
|
var MAX_ATTEMPTS = 3;
|
|
18795
18804
|
async function askRemoteCwd(deps2) {
|
|
18796
18805
|
const defaultPath = deps2.defaultPath ?? defaultRemoteCwd();
|
|
18806
|
+
if (!deps2.defaultPath) ensureDefaultRemoteCwd(defaultPath);
|
|
18807
|
+
deps2.out(" \u8FDC\u7A0B\u4EFB\u52A1\u9ED8\u8BA4\u653E\u5728 DeskBuddy \u6587\u4EF6\u5939\u91CC\uFF08\u4E0D\u7528\u684C\u9762\uFF1A\u684C\u9762\u53D7\u7CFB\u7EDF\u4FDD\u62A4\u3001\u53EF\u80FD\u88AB\u540C\u6B65\u4E0A\u4E91\uFF09\uFF0C\u56DE\u8F66\u5373\u7528");
|
|
18797
18808
|
for (let i = 0; i < MAX_ATTEMPTS; i++) {
|
|
18798
18809
|
const raw = await deps2.ask(`\u8FDC\u7A0B\u300C\u65B0\u5EFA\u4EFB\u52A1\u300D\u7684\u5DE5\u4F5C\u76EE\u5F55 [${defaultPath}]\uFF1A`);
|
|
18799
18810
|
if (raw === null) {
|
|
@@ -18919,6 +18930,7 @@ async function runSetup(opts = {}) {
|
|
|
18919
18930
|
const remoteCwd = await askRemoteCwd({ out, ask: terminalAsk });
|
|
18920
18931
|
const bound = loadConfig();
|
|
18921
18932
|
bound.remoteCwd = remoteCwd;
|
|
18933
|
+
bound.remoteCwdMigrated = true;
|
|
18922
18934
|
saveConfig(bound);
|
|
18923
18935
|
out(` \u5DF2\u8BB0\u4E0B\uFF1A${remoteCwd}`);
|
|
18924
18936
|
out(" \u63D0\u793A\uFF1AClaude Code \u7B2C\u4E00\u6B21\u5728\u65B0\u76EE\u5F55\u91CC\u542F\u52A8\u4F1A\u95EE\u300C\u662F\u5426\u4FE1\u4EFB\u6B64\u6587\u4EF6\u5939\u300D\uFF0CDeskBuddy \u4E0D\u4F1A\u66FF\u4F60\u56DE\u7B54\u3002");
|
|
@@ -19093,8 +19105,10 @@ async function runInstall(opts, deps2 = defaultInstallDeps()) {
|
|
|
19093
19105
|
const bound = loadConfig();
|
|
19094
19106
|
if (!bound.remoteCwd) {
|
|
19095
19107
|
bound.remoteCwd = defaultRemoteCwd();
|
|
19108
|
+
bound.remoteCwdMigrated = true;
|
|
19096
19109
|
saveConfig(bound);
|
|
19097
19110
|
}
|
|
19111
|
+
ensureDefaultRemoteCwd(bound.remoteCwd);
|
|
19098
19112
|
const auto = await deps2.autostart();
|
|
19099
19113
|
let logins = [];
|
|
19100
19114
|
try {
|
|
@@ -19206,6 +19220,7 @@ function formatStatus(input) {
|
|
|
19206
19220
|
const account = cfg.boundAt ? `\u5DF2\u6388\u6743\uFF08clientId ${cfg.clientId.slice(0, 4)}\u2026\uFF0C\u7ED1\u5B9A\u4E8E ${fmtTime(cfg.boundAt)}\uFF09` : "\u672A\u6388\u6743 \u2014\u2014 \u8FD0\u884C deskbuddy setup \u626B\u7801\u6388\u6743";
|
|
19207
19221
|
lines3.push(` ${pad("\u8D26\u53F7", 10)}${account}`);
|
|
19208
19222
|
lines3.push(` ${pad("\u670D\u52A1\u7AEF", 10)}${cfg.apiBase}\uFF08${environmentLabel(cfg.apiBase)}\uFF09`);
|
|
19223
|
+
if (cfg.remoteCwd) lines3.push(` ${pad("\u65B0\u5EFA\u4EFB\u52A1\u76EE\u5F55", 10)}${cfg.remoteCwd}`);
|
|
19209
19224
|
if (cfg.boundAt && cfg.boundApiBase && cfg.boundApiBase !== cfg.apiBase) {
|
|
19210
19225
|
lines3.push(
|
|
19211
19226
|
` \u26A0\uFE0F \u6388\u6743\u65F6\u8FDE\u7684\u662F ${cfg.boundApiBase}\uFF08${environmentLabel(cfg.boundApiBase)}\uFF09\uFF0C\u4E0E\u5F53\u524D\u4E0D\u4E00\u81F4 \u2014\u2014 \u5F53\u524D\u73AF\u5883\u5E76\u4E0D\u8BA4\u8BC6\u8FD9\u53F0\u673A\u5668\uFF0C\u9700\u8981\u91CD\u65B0 deskbuddy setup`
|
package/dist/hook.cjs
CHANGED
|
@@ -2666,13 +2666,17 @@ async function main(argv) {
|
|
|
2666
2666
|
if (event === 'UserPromptSubmit') recordDir(payload.cwd, now)
|
|
2667
2667
|
// 窗口对话轮数(spec 2026-10-02 §2.1):一轮开始的事件加 1
|
|
2668
2668
|
const internal = event === 'UserPromptSubmit' && isInternalPrompt(payload.prompt)
|
|
2669
|
-
|
|
2669
|
+
// 子代理发的事件(带 agent_id):Codex 0.159 实测(10-13)子代理 thread 的 hook 带父会话的 session_id,
|
|
2670
|
+
// 但 turn_id / transcript_path 是子代理自己的,派它时那句话还会以 UserPromptSubmit 触发一次。
|
|
2671
|
+
// 归到父会话(状态、授权照常),但不算父会话的一轮、不当首句、不换掉父会话的 transcript
|
|
2672
|
+
const sub = typeof payload.agent_id === 'string' && payload.agent_id !== ''
|
|
2673
|
+
const isTurn = !internal && !sub && turnEvents(registry, tool).indexOf(event) >= 0
|
|
2670
2674
|
// 首条指令(标题来源 first-prompt):只记第一次
|
|
2671
2675
|
// 状态没了(会话结束后被续跑)就接已结束记录里的首句;DeskBuddy 注入的话不算首句
|
|
2672
2676
|
const firstPrompt =
|
|
2673
2677
|
(prev && prev.firstPrompt) ||
|
|
2674
2678
|
(prev ? undefined : endedFirstPrompt(sessionId)) ||
|
|
2675
|
-
(event === 'UserPromptSubmit' && !internal ? cleanPrompt(payload.prompt) : '') ||
|
|
2679
|
+
(event === 'UserPromptSubmit' && !internal && !sub ? cleanPrompt(payload.prompt) : '') ||
|
|
2676
2680
|
undefined
|
|
2677
2681
|
if (superseded(prev, eventAt)) {
|
|
2678
2682
|
// 被并发的更晚事件(多半是同一轮的 Stop)抢先写了:状态不覆盖,但首条指令要补上,不然标题就成了第二条指令
|
|
@@ -2754,7 +2758,7 @@ async function main(argv) {
|
|
|
2754
2758
|
firstPrompt: firstPrompt,
|
|
2755
2759
|
// transcript 路径(Claude Code 的 hook 输入带):daemon 据此认 Esc 打断(Bug 表 160)。🔴 只落本机、不上报
|
|
2756
2760
|
transcriptPath:
|
|
2757
|
-
typeof payload.transcript_path === 'string' && payload.transcript_path ? payload.transcript_path : (prev && prev.transcriptPath) || undefined,
|
|
2761
|
+
!sub && typeof payload.transcript_path === 'string' && payload.transcript_path ? payload.transcript_path : (prev && prev.transcriptPath) || undefined,
|
|
2758
2762
|
// WorkBuddy:会话在 ~/.workbuddy 还是 ~/.codebuddy(spec 2026-10-08 codebuddy-default-dir),续写按它选目录。🔴 只落本机、不上报
|
|
2759
2763
|
configDir: tool === 'workbuddy' ? workbuddyConfigDir(payload, process.env) || (prev && prev.configDir) || undefined : undefined,
|
|
2760
2764
|
// 进程号是按窗口登记先记下的、还没核对过祖先链(spec §3.5)。🔴 只落本机
|
|
@@ -2780,7 +2784,7 @@ async function main(argv) {
|
|
|
2780
2784
|
// cc-ai-title 要读 transcript,长任务期间 PreToolUse/PostToolUse 触发极频繁
|
|
2781
2785
|
next.title =
|
|
2782
2786
|
resolveTitle(titleSources(registry, tool), {
|
|
2783
|
-
transcriptPath: payload.transcript_path,
|
|
2787
|
+
transcriptPath: sub ? next.transcriptPath : payload.transcript_path,
|
|
2784
2788
|
cwd: next.project,
|
|
2785
2789
|
sessionId: sessionId,
|
|
2786
2790
|
tool: tool,
|
package/hook/hook-debug.log
CHANGED
|
@@ -482,3 +482,33 @@
|
|
|
482
482
|
2026-10-13T02:29:35.919Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
483
483
|
2026-10-13T02:29:35.919Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
484
484
|
2026-10-13T02:29:38.734Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
485
|
+
2026-10-13T03:30:01.372Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
486
|
+
2026-10-13T03:30:06.278Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
487
|
+
2026-10-13T03:30:06.278Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
488
|
+
2026-10-13T03:30:06.390Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
489
|
+
2026-10-13T03:30:06.390Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
490
|
+
2026-10-13T03:30:08.716Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
491
|
+
2026-10-13T03:32:18.623Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
492
|
+
2026-10-13T03:32:23.571Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
493
|
+
2026-10-13T03:32:23.571Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
494
|
+
2026-10-13T03:32:23.683Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
495
|
+
2026-10-13T03:32:23.683Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
496
|
+
2026-10-13T03:32:26.513Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
497
|
+
2026-10-13T03:35:16.340Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
498
|
+
2026-10-13T03:35:21.305Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
499
|
+
2026-10-13T03:35:21.305Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
500
|
+
2026-10-13T03:35:21.411Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
501
|
+
2026-10-13T03:35:21.411Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
502
|
+
2026-10-13T03:35:23.952Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
503
|
+
2026-10-13T06:01:27.324Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
504
|
+
2026-10-13T06:01:32.581Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
505
|
+
2026-10-13T06:01:32.581Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
506
|
+
2026-10-13T06:01:32.676Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
507
|
+
2026-10-13T06:01:32.676Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
508
|
+
2026-10-13T06:01:35.436Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
509
|
+
2026-10-13T06:06:34.568Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
510
|
+
2026-10-13T06:06:39.868Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
511
|
+
2026-10-13T06:06:39.869Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
512
|
+
2026-10-13T06:06:40.053Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
513
|
+
2026-10-13T06:06:40.053Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
514
|
+
2026-10-13T06:06:42.597Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
package/hook/hook.cjs
CHANGED
|
@@ -2666,13 +2666,17 @@ async function main(argv) {
|
|
|
2666
2666
|
if (event === 'UserPromptSubmit') recordDir(payload.cwd, now)
|
|
2667
2667
|
// 窗口对话轮数(spec 2026-10-02 §2.1):一轮开始的事件加 1
|
|
2668
2668
|
const internal = event === 'UserPromptSubmit' && isInternalPrompt(payload.prompt)
|
|
2669
|
-
|
|
2669
|
+
// 子代理发的事件(带 agent_id):Codex 0.159 实测(10-13)子代理 thread 的 hook 带父会话的 session_id,
|
|
2670
|
+
// 但 turn_id / transcript_path 是子代理自己的,派它时那句话还会以 UserPromptSubmit 触发一次。
|
|
2671
|
+
// 归到父会话(状态、授权照常),但不算父会话的一轮、不当首句、不换掉父会话的 transcript
|
|
2672
|
+
const sub = typeof payload.agent_id === 'string' && payload.agent_id !== ''
|
|
2673
|
+
const isTurn = !internal && !sub && turnEvents(registry, tool).indexOf(event) >= 0
|
|
2670
2674
|
// 首条指令(标题来源 first-prompt):只记第一次
|
|
2671
2675
|
// 状态没了(会话结束后被续跑)就接已结束记录里的首句;DeskBuddy 注入的话不算首句
|
|
2672
2676
|
const firstPrompt =
|
|
2673
2677
|
(prev && prev.firstPrompt) ||
|
|
2674
2678
|
(prev ? undefined : endedFirstPrompt(sessionId)) ||
|
|
2675
|
-
(event === 'UserPromptSubmit' && !internal ? cleanPrompt(payload.prompt) : '') ||
|
|
2679
|
+
(event === 'UserPromptSubmit' && !internal && !sub ? cleanPrompt(payload.prompt) : '') ||
|
|
2676
2680
|
undefined
|
|
2677
2681
|
if (superseded(prev, eventAt)) {
|
|
2678
2682
|
// 被并发的更晚事件(多半是同一轮的 Stop)抢先写了:状态不覆盖,但首条指令要补上,不然标题就成了第二条指令
|
|
@@ -2754,7 +2758,7 @@ async function main(argv) {
|
|
|
2754
2758
|
firstPrompt: firstPrompt,
|
|
2755
2759
|
// transcript 路径(Claude Code 的 hook 输入带):daemon 据此认 Esc 打断(Bug 表 160)。🔴 只落本机、不上报
|
|
2756
2760
|
transcriptPath:
|
|
2757
|
-
typeof payload.transcript_path === 'string' && payload.transcript_path ? payload.transcript_path : (prev && prev.transcriptPath) || undefined,
|
|
2761
|
+
!sub && typeof payload.transcript_path === 'string' && payload.transcript_path ? payload.transcript_path : (prev && prev.transcriptPath) || undefined,
|
|
2758
2762
|
// WorkBuddy:会话在 ~/.workbuddy 还是 ~/.codebuddy(spec 2026-10-08 codebuddy-default-dir),续写按它选目录。🔴 只落本机、不上报
|
|
2759
2763
|
configDir: tool === 'workbuddy' ? workbuddyConfigDir(payload, process.env) || (prev && prev.configDir) || undefined : undefined,
|
|
2760
2764
|
// 进程号是按窗口登记先记下的、还没核对过祖先链(spec §3.5)。🔴 只落本机
|
|
@@ -2780,7 +2784,7 @@ async function main(argv) {
|
|
|
2780
2784
|
// cc-ai-title 要读 transcript,长任务期间 PreToolUse/PostToolUse 触发极频繁
|
|
2781
2785
|
next.title =
|
|
2782
2786
|
resolveTitle(titleSources(registry, tool), {
|
|
2783
|
-
transcriptPath: payload.transcript_path,
|
|
2787
|
+
transcriptPath: sub ? next.transcriptPath : payload.transcript_path,
|
|
2784
2788
|
cwd: next.project,
|
|
2785
2789
|
sessionId: sessionId,
|
|
2786
2790
|
tool: tool,
|