deskbuddy 0.2.0-beta.34 → 0.2.0-beta.35
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.
|
@@ -5608,10 +5608,13 @@ var defaultFetchJson = async (url, timeoutMs) => {
|
|
|
5608
5608
|
clearTimeout(t);
|
|
5609
5609
|
}
|
|
5610
5610
|
};
|
|
5611
|
-
function
|
|
5612
|
-
if (!Array.isArray(list)) return
|
|
5611
|
+
function mainTargets(list) {
|
|
5612
|
+
if (!Array.isArray(list)) return [];
|
|
5613
5613
|
const pages = list.filter((t) => t && t.type === "page" && typeof t.webSocketDebuggerUrl === "string" && !/^devtools:/.test(t.url ?? ""));
|
|
5614
|
-
return pages.
|
|
5614
|
+
return pages.filter((t) => /renderer\/index\.html/.test(t.url ?? ""));
|
|
5615
|
+
}
|
|
5616
|
+
function pickMainTarget(list) {
|
|
5617
|
+
return mainTargets(list)[0] ?? null;
|
|
5615
5618
|
}
|
|
5616
5619
|
function loopbackWsUrl(wsUrl, port) {
|
|
5617
5620
|
try {
|
|
@@ -5624,16 +5627,18 @@ function loopbackWsUrl(wsUrl, port) {
|
|
|
5624
5627
|
return null;
|
|
5625
5628
|
}
|
|
5626
5629
|
}
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5630
|
+
var HAS_SDK_EXPR = "!!(globalThis.wb && globalThis.wb.conversations)";
|
|
5631
|
+
function pageName(url) {
|
|
5632
|
+
return String(url || "").split(/[?#]/)[0].split(/[\\/]/).slice(-2).join("/");
|
|
5633
|
+
}
|
|
5634
|
+
function openWs(target, port, d, info) {
|
|
5635
|
+
if (!target.webSocketDebuggerUrl) return Promise.reject(new Error("\u627E\u4E0D\u5230 App \u4E3B\u7A97\u53E3"));
|
|
5631
5636
|
const url = loopbackWsUrl(target.webSocketDebuggerUrl, port);
|
|
5632
|
-
if (!url)
|
|
5637
|
+
if (!url) return Promise.reject(new Error("\u4E3B\u7A97\u53E3\u7684\u8C03\u8BD5\u5730\u5740\u4E0D\u5BF9"));
|
|
5633
5638
|
const ws = (d.ws ?? ((u) => new WebSocket(u, { handshakeTimeout: 5e3 })))(url);
|
|
5634
|
-
return
|
|
5639
|
+
return new Promise((resolve6, reject) => {
|
|
5635
5640
|
let opened = false;
|
|
5636
|
-
const client = new WsCdpClient(ws);
|
|
5641
|
+
const client = new WsCdpClient(ws, info);
|
|
5637
5642
|
ws.on("open", () => {
|
|
5638
5643
|
opened = true;
|
|
5639
5644
|
resolve6(client);
|
|
@@ -5648,13 +5653,53 @@ async function connectCdp(port, d = {}) {
|
|
|
5648
5653
|
ws.on("message", (data) => client.onMessage(data));
|
|
5649
5654
|
});
|
|
5650
5655
|
}
|
|
5656
|
+
async function connectCdp(port, d = {}) {
|
|
5657
|
+
const fetchJson = d.fetchJson ?? defaultFetchJson;
|
|
5658
|
+
const list = await fetchJson(`http://127.0.0.1:${port}/json/list`, 3e3);
|
|
5659
|
+
if (!d.pickSdk) {
|
|
5660
|
+
const target = (d.pick ?? pickMainTarget)(list);
|
|
5661
|
+
if (!target?.webSocketDebuggerUrl) throw new Error("\u627E\u4E0D\u5230 App \u4E3B\u7A97\u53E3");
|
|
5662
|
+
return openWs(target, port, d);
|
|
5663
|
+
}
|
|
5664
|
+
const all = mainTargets(list);
|
|
5665
|
+
if (all.length === 0) throw new Error("\u627E\u4E0D\u5230 App \u4E3B\u7A97\u53E3");
|
|
5666
|
+
let ua = "";
|
|
5667
|
+
try {
|
|
5668
|
+
const v = await fetchJson(`http://127.0.0.1:${port}/json/version`, 2e3);
|
|
5669
|
+
const m = typeof v?.["User-Agent"] === "string" ? /\bWorkBuddy\/[\w.-]+/.exec(v["User-Agent"]) : null;
|
|
5670
|
+
ua = [m?.[0], typeof v?.Browser === "string" ? v.Browser : ""].filter(Boolean).join(" ");
|
|
5671
|
+
} catch {
|
|
5672
|
+
ua = "";
|
|
5673
|
+
}
|
|
5674
|
+
const infoOf = (i, sdk) => ({ url: pageName(String(all[i].url ?? "")), title: "", candidates: all.length, index: i, sdk, ...ua ? { ua } : {} });
|
|
5675
|
+
if (all.length === 1) return openWs(all[0], port, d, infoOf(0, null));
|
|
5676
|
+
for (let i = 0; i < all.length; i++) {
|
|
5677
|
+
let c;
|
|
5678
|
+
try {
|
|
5679
|
+
c = await openWs(all[i], port, d, infoOf(i, true));
|
|
5680
|
+
} catch {
|
|
5681
|
+
continue;
|
|
5682
|
+
}
|
|
5683
|
+
let has = false;
|
|
5684
|
+
try {
|
|
5685
|
+
has = await c.evaluate(HAS_SDK_EXPR, 2e3) === true;
|
|
5686
|
+
} catch {
|
|
5687
|
+
has = false;
|
|
5688
|
+
}
|
|
5689
|
+
if (has) return c;
|
|
5690
|
+
c.close();
|
|
5691
|
+
}
|
|
5692
|
+
return openWs(all[0], port, d, infoOf(0, false));
|
|
5693
|
+
}
|
|
5651
5694
|
var WsCdpClient = class {
|
|
5652
5695
|
#ws;
|
|
5696
|
+
target;
|
|
5653
5697
|
#id = 0;
|
|
5654
5698
|
#closed = false;
|
|
5655
5699
|
#waiting = /* @__PURE__ */ new Map();
|
|
5656
|
-
constructor(ws) {
|
|
5700
|
+
constructor(ws, target) {
|
|
5657
5701
|
this.#ws = ws;
|
|
5702
|
+
if (target) this.target = target;
|
|
5658
5703
|
}
|
|
5659
5704
|
get closed() {
|
|
5660
5705
|
return this.#closed;
|
|
@@ -5858,6 +5903,7 @@ var HungTracker = class {
|
|
|
5858
5903
|
}
|
|
5859
5904
|
};
|
|
5860
5905
|
var APP_PORT_HUNG_REASON = "app_port_unresponsive";
|
|
5906
|
+
var STARTUP_GRACE_MS = 90 * 1e3;
|
|
5861
5907
|
var FORCE_QUIT_WAIT_MS = 10 * 1e3;
|
|
5862
5908
|
function isTimeoutError(e) {
|
|
5863
5909
|
const err = e;
|
|
@@ -6005,6 +6051,12 @@ var CdpKeeper = class {
|
|
|
6005
6051
|
#hung = new HungTracker();
|
|
6006
6052
|
/** 这一段卡死里「暂不重启」的原因记过哪条(同一条只记一次) */
|
|
6007
6053
|
#hungNote = "";
|
|
6054
|
+
/** 启动宽限期到什么时候(0 = 不在宽限期) */
|
|
6055
|
+
#graceUntil = 0;
|
|
6056
|
+
/** 宽限期内超时记过一行没有(每段宽限只记一次) */
|
|
6057
|
+
#graceNoted = false;
|
|
6058
|
+
/** 上一轮端口检查的结果(判「刚从不通变成通」) */
|
|
6059
|
+
#lastPort = null;
|
|
6008
6060
|
/** 这一段端口不通里「不重启」的原因记过哪条(同一条只记一次;端口通了 / 转成卡死时清掉。258:原先这些分支一行不记) */
|
|
6009
6061
|
#downNote = "";
|
|
6010
6062
|
/** 最近一轮端口不通的细分(日志 / 设备任务的等待原因用):fail = 没在监听或回包不是 WorkBuddy;timeout = 超时且监听者不是本机回环的 WorkBuddy */
|
|
@@ -6149,6 +6201,20 @@ var CdpKeeper = class {
|
|
|
6149
6201
|
this.#hung.clear();
|
|
6150
6202
|
this.#hungNote = "";
|
|
6151
6203
|
}
|
|
6204
|
+
/** 进入启动宽限期(拉起 / 重启 / 端口刚从不通变成通) */
|
|
6205
|
+
#startGrace(now) {
|
|
6206
|
+
this.#graceUntil = now + STARTUP_GRACE_MS;
|
|
6207
|
+
this.#graceNoted = false;
|
|
6208
|
+
}
|
|
6209
|
+
#inGrace(now) {
|
|
6210
|
+
return this.#graceUntil > 0 && now < this.#graceUntil;
|
|
6211
|
+
}
|
|
6212
|
+
/** 宽限期内超时:记一行(每段一次) */
|
|
6213
|
+
#noteGrace() {
|
|
6214
|
+
if (this.#graceNoted) return;
|
|
6215
|
+
this.#graceNoted = true;
|
|
6216
|
+
this.#d.log(`WorkBuddy \u8C03\u8BD5\u7AEF\u53E3 ${this.#d.port()} \u8D85\u65F6\uFF0C\u4F46 App \u521A\u542F\u52A8 / \u521A\u6062\u590D\uFF08${STARTUP_GRACE_MS / 1e3} \u79D2\u5BBD\u9650\u671F\u5185\uFF09\uFF0C\u5148\u4E0D\u5224\u65E0\u54CD\u5E94`);
|
|
6217
|
+
}
|
|
6152
6218
|
/** 最近一轮端口不通的细分(没不通过返回 '') */
|
|
6153
6219
|
get downWhy() {
|
|
6154
6220
|
return this.#downWhy;
|
|
@@ -6200,7 +6266,13 @@ var CdpKeeper = class {
|
|
|
6200
6266
|
await this.ensureEnv().catch(() => {
|
|
6201
6267
|
});
|
|
6202
6268
|
const pr = await this.#probe();
|
|
6269
|
+
const st = await this.#tickInner(pr);
|
|
6270
|
+
this.#lastPort = st;
|
|
6271
|
+
return st;
|
|
6272
|
+
}
|
|
6273
|
+
async #tickInner(pr) {
|
|
6203
6274
|
if (pr === "ok") {
|
|
6275
|
+
if (this.#lastPort === "down") this.#startGrace(this.#now());
|
|
6204
6276
|
if (this.#hung.since) this.#d.log(`WorkBuddy \u8C03\u8BD5\u7AEF\u53E3 ${this.#d.port()} \u6062\u590D\u54CD\u5E94`);
|
|
6205
6277
|
this.#markHung(false, 0);
|
|
6206
6278
|
this.#downRounds = 0;
|
|
@@ -6211,6 +6283,11 @@ var CdpKeeper = class {
|
|
|
6211
6283
|
});
|
|
6212
6284
|
return ok ? "up" : "untrusted";
|
|
6213
6285
|
}
|
|
6286
|
+
if (pr === "timeout" && this.#inGrace(this.#now()) && await this.ownerOk().catch(() => false)) {
|
|
6287
|
+
this.#noteGrace();
|
|
6288
|
+
this.#downRounds = 0;
|
|
6289
|
+
return this.#lastPort === "up" ? "up" : "down";
|
|
6290
|
+
}
|
|
6214
6291
|
if (await this.#isHung(pr)) {
|
|
6215
6292
|
const now = this.#now();
|
|
6216
6293
|
this.#markHung(true, now);
|
|
@@ -6277,6 +6354,7 @@ var CdpKeeper = class {
|
|
|
6277
6354
|
async #doRestart(verify, hung = false) {
|
|
6278
6355
|
this.#restarting = true;
|
|
6279
6356
|
this.#lastRestart = this.#now();
|
|
6357
|
+
this.#startGrace(this.#lastRestart);
|
|
6280
6358
|
this.#restarts++;
|
|
6281
6359
|
this.#saveThrottle();
|
|
6282
6360
|
try {
|
|
@@ -6368,6 +6446,10 @@ var CdpKeeper = class {
|
|
|
6368
6446
|
this.#d.log(`\u5524\u8D77 WorkBuddy\uFF1A${Math.round((now - this.#lastWakeLaunch) / 1e3)} \u79D2\u524D\u521A\u62C9\u8D77\u8FC7\uFF08\u8282\u6D41 60 \u79D2\uFF09\uFF0C\u4E0D\u518D\u62C9\u8D77\uFF0C\u7B49\u5B83\u8D77\u6765`);
|
|
6369
6447
|
return "launched";
|
|
6370
6448
|
}
|
|
6449
|
+
if (pr === "timeout" && this.#inGrace(now) && await this.ownerOk().catch(() => false)) {
|
|
6450
|
+
this.#noteGrace();
|
|
6451
|
+
return "running";
|
|
6452
|
+
}
|
|
6371
6453
|
if (await this.#isHung(pr)) return this.#wakeHung(now);
|
|
6372
6454
|
if (this.#lastRestart && now - this.#lastRestart < RESTART_GAP_MS) {
|
|
6373
6455
|
this.#d.log(`\u5524\u8D77 WorkBuddy\uFF1A${Math.round((now - this.#lastRestart) / 6e4)} \u5206\u949F\u524D\u521A\u91CD\u542F\u8FC7\uFF08\u8282\u6D41 30 \u5206\u949F\uFF09\uFF0C\u4E0D\u518D\u91CD\u542F\uFF0C\u7B49\u7AEF\u53E3\u8D77\u6765`);
|
|
@@ -6384,6 +6466,7 @@ var CdpKeeper = class {
|
|
|
6384
6466
|
return "not_installed";
|
|
6385
6467
|
}
|
|
6386
6468
|
this.#lastWakeLaunch = now;
|
|
6469
|
+
this.#startGrace(now);
|
|
6387
6470
|
this.#saveThrottle();
|
|
6388
6471
|
await this.ensureEnv().catch(() => {
|
|
6389
6472
|
});
|
|
@@ -10648,7 +10731,7 @@ var defaultLoginOpenDeps = () => ({
|
|
|
10648
10731
|
});
|
|
10649
10732
|
async function installCodebuddyHooks(log) {
|
|
10650
10733
|
try {
|
|
10651
|
-
const { installTools: installTools2 } = await import("./enable-
|
|
10734
|
+
const { installTools: installTools2 } = await import("./enable-UNMUBPWP.js");
|
|
10652
10735
|
installTools2(["workbuddy"], () => {
|
|
10653
10736
|
}, null, { auto: true });
|
|
10654
10737
|
} catch (e) {
|
|
@@ -11162,7 +11245,7 @@ function defaultOfferDeps(log) {
|
|
|
11162
11245
|
}),
|
|
11163
11246
|
openLogin: () => defaultOpenLogin(platform),
|
|
11164
11247
|
installHooks: async () => {
|
|
11165
|
-
const { installTools: installTools2 } = await import("./enable-
|
|
11248
|
+
const { installTools: installTools2 } = await import("./enable-UNMUBPWP.js");
|
|
11166
11249
|
installTools2(["workbuddy"], (l) => log(`[WorkBuddy \u72EC\u7ACB\u7248] ${l}`), null, { auto: true });
|
|
11167
11250
|
},
|
|
11168
11251
|
log: (l) => log(`[WorkBuddy \u72EC\u7ACB\u7248] ${l}`),
|
package/dist/cli.js
CHANGED
|
@@ -262,7 +262,7 @@ import {
|
|
|
262
262
|
writeState,
|
|
263
263
|
writeWakeMark,
|
|
264
264
|
writeWakeSecret
|
|
265
|
-
} from "./chunk-
|
|
265
|
+
} from "./chunk-37YGRQ4H.js";
|
|
266
266
|
|
|
267
267
|
// src/commands/config.ts
|
|
268
268
|
function runConfig(args, out = (s2) => process.stdout.write(s2 + "\n")) {
|
|
@@ -795,9 +795,9 @@ var AutoEnabler = class {
|
|
|
795
795
|
|
|
796
796
|
// src/daemon/index.ts
|
|
797
797
|
import { randomBytes as randomBytes7 } from "crypto";
|
|
798
|
-
import { existsSync as existsSync7, readdirSync as readdirSync11, readFileSync as
|
|
798
|
+
import { existsSync as existsSync7, readdirSync as readdirSync11, readFileSync as readFileSync14, statSync as statSync13 } from "fs";
|
|
799
799
|
import { homedir as homedir8 } from "os";
|
|
800
|
-
import { basename as basename9, dirname as
|
|
800
|
+
import { basename as basename9, dirname as dirname9, join as join27 } from "path";
|
|
801
801
|
import WebSocket2 from "ws";
|
|
802
802
|
|
|
803
803
|
// src/core/transcript/locate.ts
|
|
@@ -2735,6 +2735,23 @@ function basename5(p) {
|
|
|
2735
2735
|
const parts = p.split(/[\\/]+/).filter(Boolean);
|
|
2736
2736
|
return parts[parts.length - 1] ?? "";
|
|
2737
2737
|
}
|
|
2738
|
+
function addedTail(toolName, a) {
|
|
2739
|
+
const str6 = (v) => typeof v === "string" ? v : "";
|
|
2740
|
+
let oldS = "";
|
|
2741
|
+
let newS = "";
|
|
2742
|
+
if (toolName === "MultiEdit" && Array.isArray(a.edits) && a.edits.length > 0) {
|
|
2743
|
+
const last = a.edits[a.edits.length - 1];
|
|
2744
|
+
oldS = str6(last?.old_string);
|
|
2745
|
+
newS = str6(last?.new_string);
|
|
2746
|
+
} else if (toolName === "NotebookEdit") newS = str6(a.new_source);
|
|
2747
|
+
else {
|
|
2748
|
+
oldS = str6(a.old_string);
|
|
2749
|
+
newS = str6(a.new_string);
|
|
2750
|
+
}
|
|
2751
|
+
const old = new Set(oldS.split(/\r?\n/).map((l) => squash(l)));
|
|
2752
|
+
const added = newS.split(/\r?\n/).map((l) => squash(l)).filter((l) => l && !old.has(l));
|
|
2753
|
+
return (added[added.length - 1] ?? "").slice(0, 20);
|
|
2754
|
+
}
|
|
2738
2755
|
function displayFingerprint(toolName, input) {
|
|
2739
2756
|
const a = input && typeof input === "object" ? input : {};
|
|
2740
2757
|
const s2 = (v) => typeof v === "string" ? v : "";
|
|
@@ -2748,7 +2765,14 @@ function displayFingerprint(toolName, input) {
|
|
|
2748
2765
|
const body = squash(s2(a.content)).slice(0, 20);
|
|
2749
2766
|
return name ? body ? name + FP_SEP + body : name : "";
|
|
2750
2767
|
}
|
|
2751
|
-
if (["Edit", "MultiEdit", "
|
|
2768
|
+
if (["Edit", "MultiEdit", "NotebookEdit"].includes(toolName)) {
|
|
2769
|
+
const name = squash(basename5(s2(a.file_path) || s2(a.notebook_path)));
|
|
2770
|
+
if (!name) return "";
|
|
2771
|
+
if (toolName === "NotebookEdit") return name;
|
|
2772
|
+
const tail4 = addedTail(toolName, a);
|
|
2773
|
+
return tail4 ? name + FP_SEP + tail4 : name;
|
|
2774
|
+
}
|
|
2775
|
+
if (toolName === "Read") return squash(basename5(s2(a.file_path)));
|
|
2752
2776
|
return headTail(Object.values(a).find((v) => typeof v === "string" && v.trim() !== "") ?? "").slice(0, 200);
|
|
2753
2777
|
}
|
|
2754
2778
|
var SETTLE_MS = 800;
|
|
@@ -2792,10 +2816,33 @@ function permissionRegion(lines3, toolName) {
|
|
|
2792
2816
|
function isPermissionDialog(lines3, toolName, fingerprint2) {
|
|
2793
2817
|
if (!fingerprint2) return false;
|
|
2794
2818
|
const region = permissionRegion(lines3, toolName);
|
|
2795
|
-
if (!region) return
|
|
2819
|
+
if (!region) return scrolledFileDialog(lines3, toolName, fingerprint2);
|
|
2796
2820
|
const text = squash(joined(region));
|
|
2797
2821
|
return fingerprint2.split(FP_SEP).every((part) => !!part && text.includes(squash(part)));
|
|
2798
2822
|
}
|
|
2823
|
+
var SCROLL_TOOLS = /* @__PURE__ */ new Set(["Edit", "MultiEdit", "NotebookEdit"]);
|
|
2824
|
+
var EDIT_QUESTION_RE = /^\s*Do you want to make this edit to (.+)\?\s*$/;
|
|
2825
|
+
function scrolledFileDialog(lines3, toolName, fingerprint2) {
|
|
2826
|
+
if (!SCROLL_TOOLS.has(toolName)) return false;
|
|
2827
|
+
const [name, ...content] = fingerprint2.split(FP_SEP);
|
|
2828
|
+
if (!name || content.length === 0 || content.some((c) => !c)) return false;
|
|
2829
|
+
let q = -1;
|
|
2830
|
+
for (let i = lines3.length - 1; i >= 0; i--) {
|
|
2831
|
+
if (/^\s*Do you want to .+\?\s*$/.test(lines3[i])) {
|
|
2832
|
+
q = i;
|
|
2833
|
+
break;
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
if (q < 0) return false;
|
|
2837
|
+
const m = EDIT_QUESTION_RE.exec(lines3[q]);
|
|
2838
|
+
if (!m || squash(basename5(m[1].trim())) !== name) return false;
|
|
2839
|
+
if (lines3.slice(0, q).some((l) => /^\s*●/.test(l))) return false;
|
|
2840
|
+
const after = joined(lines3.slice(q + 1, q + 6));
|
|
2841
|
+
if (!new RegExp(`^\\s*(?:${CURSOR}\\s*)?1\\.\\s+Yes\\s*$`, "m").test(after)) return false;
|
|
2842
|
+
if (!/^\s*(?:[❯>›]\s*)?3\.\s+No\b/m.test(after)) return false;
|
|
2843
|
+
const body = squash(joined(lines3.slice(0, q)));
|
|
2844
|
+
return content.every((c) => body.includes(c));
|
|
2845
|
+
}
|
|
2799
2846
|
async function answerPermission(io, toolName, fingerprint2, decision) {
|
|
2800
2847
|
const ok = (l) => isPermissionDialog(l, toolName, fingerprint2);
|
|
2801
2848
|
if (!await settled(io, ok)) return "not_waiting";
|
|
@@ -7909,6 +7956,8 @@ ${PRELUDE3}
|
|
|
7909
7956
|
|
|
7910
7957
|
// src/daemon/workbuddyApp/watch.ts
|
|
7911
7958
|
var KEEPER_EVERY_MS3 = 15 * 1e3;
|
|
7959
|
+
var NON_SDK_KEEP_MS = 60 * 1e3;
|
|
7960
|
+
var NO_SDK_REPROBE_MS = 90 * 1e3;
|
|
7912
7961
|
var PROBE_EVERY_MS3 = 60 * 1e3;
|
|
7913
7962
|
var SEEN_TTL_MS4 = 60 * 60 * 1e3;
|
|
7914
7963
|
var CONNECT_BACKOFF_MIN_MS3 = 15 * 1e3;
|
|
@@ -7956,6 +8005,10 @@ var WorkbuddyAppWatch = class {
|
|
|
7956
8005
|
#modeProbed = false;
|
|
7957
8006
|
#connectedAt = 0;
|
|
7958
8007
|
#nonSdkSince = 0;
|
|
8008
|
+
/** 断开时还是非 sdk:记下原起点和断开时刻,短暂断线(< NON_SDK_KEEP_MS)重连后仍非 sdk 就沿用(258 退回:断线清零让快速回落永远攒不够) */
|
|
8009
|
+
#nonSdkKept = null;
|
|
8010
|
+
/** 上次因为「页面里没有 SDK」重连重探候选页的时刻 */
|
|
8011
|
+
#reprobeAt = 0;
|
|
7959
8012
|
#connectError = "";
|
|
7960
8013
|
/** 端口检查过没有(第一轮不通也记一行) */
|
|
7961
8014
|
#portChecked = false;
|
|
@@ -8146,7 +8199,7 @@ var WorkbuddyAppWatch = class {
|
|
|
8146
8199
|
}
|
|
8147
8200
|
if (now < this.#connectRetryAt) return;
|
|
8148
8201
|
try {
|
|
8149
|
-
const client = await (this.#d.connect ?? ((p) => connectCdp(p)))(this.#d.port());
|
|
8202
|
+
const client = await (this.#d.connect ?? ((p) => connectCdp(p, { pickSdk: true })))(this.#d.port());
|
|
8150
8203
|
if (this.#stopped) {
|
|
8151
8204
|
try {
|
|
8152
8205
|
client.close();
|
|
@@ -8163,7 +8216,8 @@ var WorkbuddyAppWatch = class {
|
|
|
8163
8216
|
this.#connectBackoffMs = CONNECT_BACKOFF_MIN_MS3;
|
|
8164
8217
|
this.#connectRetryAt = 0;
|
|
8165
8218
|
this.#connectFailLogged = false;
|
|
8166
|
-
|
|
8219
|
+
const ti = client.target;
|
|
8220
|
+
this.#d.log(`WorkBuddy App \u6388\u6743\u6865\u5DF2\u8FDE\u4E0A${ti ? `\uFF08\u9875\u9762 ${ti.url}\uFF0C\u5019\u9009 ${ti.index + 1}/${ti.candidates}${ti.sdk === false ? "\uFF0C\u5404\u5019\u9009\u9875\u90FD\u6CA1\u6709 SDK" : ""}${ti.ua ? `\uFF0C${ti.ua}` : ""}\uFF09` : ""}`);
|
|
8167
8221
|
} catch (e) {
|
|
8168
8222
|
this.#client = null;
|
|
8169
8223
|
this.#connectError = String(e?.message ?? e).slice(0, 120);
|
|
@@ -8187,9 +8241,23 @@ var WorkbuddyAppWatch = class {
|
|
|
8187
8241
|
this.#mode = r?.mode === "sdk" ? "sdk" : r?.mode === "dom" ? "dom" : "none";
|
|
8188
8242
|
this.#modeWhy = this.#mode === "sdk" ? "" : !r ? "no_result" : typeof r.why === "string" ? r.why.slice(0, 120) : "";
|
|
8189
8243
|
this.#modeProbed = true;
|
|
8190
|
-
if (this.#mode === "sdk")
|
|
8191
|
-
|
|
8244
|
+
if (this.#mode === "sdk") {
|
|
8245
|
+
this.#nonSdkSince = 0;
|
|
8246
|
+
this.#nonSdkKept = null;
|
|
8247
|
+
} else if (first || prev === "sdk" || !this.#nonSdkSince) {
|
|
8248
|
+
const kept = this.#nonSdkKept;
|
|
8249
|
+
this.#nonSdkSince = first && kept && now - kept.at < NON_SDK_KEEP_MS ? kept.since : now;
|
|
8250
|
+
this.#nonSdkKept = null;
|
|
8251
|
+
}
|
|
8192
8252
|
if (first || prev !== this.#mode || prevWhy !== this.#modeWhy) this.#d.log(`WorkBuddy App \u6388\u6743\u6865\u6A21\u5F0F\uFF1A${this.#mode}${this.#modeWhy ? `\uFF08${modeWhyText(this.#modeWhy)}\uFF09` : ""}`);
|
|
8253
|
+
const cands = this.#client?.target?.candidates ?? 1;
|
|
8254
|
+
if (this.#mode !== "sdk" && this.#modeWhy === "no_wb" && cands > 1 && this.#nonSdkSince && now - this.#nonSdkSince >= NO_SDK_REPROBE_MS && now - this.#reprobeAt >= NO_SDK_REPROBE_MS) {
|
|
8255
|
+
this.#reprobeAt = now;
|
|
8256
|
+
this.#d.log(`WorkBuddy App \u5404\u5019\u9009\u9875\u90FD\u6CA1\u6709 SDK \u5DF2\u8D85\u8FC7 ${NO_SDK_REPROBE_MS / 1e3} \u79D2\uFF0C\u91CD\u8FDE\u518D\u9010\u9875\u63A2\u4E00\u6B21`);
|
|
8257
|
+
this.#disconnect(REASON_APP_EXITED);
|
|
8258
|
+
this.#connectRetryAt = 0;
|
|
8259
|
+
return;
|
|
8260
|
+
}
|
|
8193
8261
|
}
|
|
8194
8262
|
if (!this.#client) return;
|
|
8195
8263
|
if (this.#mode === "sdk") await this.#sdkRound();
|
|
@@ -8208,6 +8276,7 @@ var WorkbuddyAppWatch = class {
|
|
|
8208
8276
|
}
|
|
8209
8277
|
}
|
|
8210
8278
|
#disconnect(reason) {
|
|
8279
|
+
if (this.#nonSdkSince) this.#nonSdkKept = { since: this.#nonSdkSince, at: this.#now() };
|
|
8211
8280
|
this.#mode = "none";
|
|
8212
8281
|
this.#modeWhy = "";
|
|
8213
8282
|
this.#modeProbed = false;
|
|
@@ -8810,6 +8879,7 @@ var REASON_TAKEOVER = "\u5DF2\u6539\u63A8\u9009\u62E9\u9898\u5361";
|
|
|
8810
8879
|
var FALLBACK_GRACE_MS = 3e3;
|
|
8811
8880
|
var FALLBACK_GRACE_APP_MS = 8e3;
|
|
8812
8881
|
var FALLBACK_BUTTON = "\u53BB\u7535\u8111\u4E0A\u4F5C\u7B54";
|
|
8882
|
+
var NOPORT_STAT = "[stat:qoder_noport_question]";
|
|
8813
8883
|
var REASON_APP_GONE = REASON_APP_EXITED;
|
|
8814
8884
|
var REASON_STOPPED = "Qoder App \u5DF2\u65AD\u5F00";
|
|
8815
8885
|
var RECOMMENDED_RE2 = /\s*\(Recommended\)\s*$/i;
|
|
@@ -9025,7 +9095,7 @@ var QoderAppQuestions = class {
|
|
|
9025
9095
|
card.markedAt = this.#mark(sid);
|
|
9026
9096
|
if (noPort && !this.#noPortLogged.has(sid)) {
|
|
9027
9097
|
this.#noPortLogged.add(sid);
|
|
9028
|
-
this.#d.log(`${this.#d.label} App \u6CA1\u5E26\u8C03\u8BD5\u7AEF\u53E3\uFF0CApp \u91CC\u7684\u9009\u62E9\u9898\u63A8\u4E0D\u5230\u8BBE\u5907\uFF0C\u5DF2\u63A8\u63D0\u793A\u5361\uFF08\u4F1A\u8BDD ${sid.slice(0, 8)}\uFF09`);
|
|
9098
|
+
this.#d.log(`${this.#d.label} App \u6CA1\u5E26\u8C03\u8BD5\u7AEF\u53E3\uFF0CApp \u91CC\u7684\u9009\u62E9\u9898\u63A8\u4E0D\u5230\u8BBE\u5907\uFF0C\u5DF2\u63A8\u63D0\u793A\u5361\uFF08\u4F1A\u8BDD ${sid.slice(0, 8)}\uFF09 ${NOPORT_STAT} tool=${this.#d.tool} scene=notice`);
|
|
9029
9099
|
}
|
|
9030
9100
|
const req = {
|
|
9031
9101
|
window: true,
|
|
@@ -9307,7 +9377,7 @@ var QoderHookQuestionGate = class {
|
|
|
9307
9377
|
const questions = hookQuestions(hook.tool_input);
|
|
9308
9378
|
if (!questions || hasDuplicateQuestion(questions)) return none;
|
|
9309
9379
|
if (!await this.#d.userAway(tool)) {
|
|
9310
|
-
this.#d.log(`${tag}\uFF1AApp \u6CA1\u8FDE\u4E0A\u8C03\u8BD5\u7AEF\u53E3\uFF0C\u7528\u6237\u5728\u7535\u8111\u524D\uFF0C\u9009\u62E9\u9898\u7167\u5E38\u5728\u7535\u8111\u4E0A\u51FA`);
|
|
9380
|
+
this.#d.log(`${tag}\uFF1AApp \u6CA1\u8FDE\u4E0A\u8C03\u8BD5\u7AEF\u53E3\uFF0C\u7528\u6237\u5728\u7535\u8111\u524D\uFF0C\u9009\u62E9\u9898\u7167\u5E38\u5728\u7535\u8111\u4E0A\u51FA ${NOPORT_STAT} tool=${tool} scene=present`);
|
|
9311
9381
|
return none;
|
|
9312
9382
|
}
|
|
9313
9383
|
if (signal.aborted) return none;
|
|
@@ -9319,7 +9389,7 @@ var QoderHookQuestionGate = class {
|
|
|
9319
9389
|
const onAbort = () => ac.abort(typeof signal.reason === "string" && signal.reason ? signal.reason : REASON_PC_CANCELLED);
|
|
9320
9390
|
if (signal.aborted) onAbort();
|
|
9321
9391
|
else signal.addEventListener("abort", onAbort, { once: true });
|
|
9322
|
-
this.#d.log(`${tag}\uFF1AApp \u6CA1\u8FDE\u4E0A\u8C03\u8BD5\u7AEF\u53E3\u3001\u7528\u6237\u4E0D\u5728\u7535\u8111\u524D\uFF0C\u9009\u62E9\u9898\u6302\u8D77\u5E76\u63A8\u8BBE\u5907`);
|
|
9392
|
+
this.#d.log(`${tag}\uFF1AApp \u6CA1\u8FDE\u4E0A\u8C03\u8BD5\u7AEF\u53E3\u3001\u7528\u6237\u4E0D\u5728\u7535\u8111\u524D\uFF0C\u9009\u62E9\u9898\u6302\u8D77\u5E76\u63A8\u8BBE\u5907 ${NOPORT_STAT} tool=${tool} scene=away`);
|
|
9323
9393
|
const cwd = typeof hook.cwd === "string" ? hook.cwd : "";
|
|
9324
9394
|
const card = this.#d.gate(
|
|
9325
9395
|
{
|
|
@@ -9601,6 +9671,7 @@ import { resolve as resolve4 } from "path";
|
|
|
9601
9671
|
var WB_APP_WAKE_WAIT_MS = 60 * 1e3;
|
|
9602
9672
|
var WB_APP_WAKE_WAIT_WIN_MS = 120 * 1e3;
|
|
9603
9673
|
var WB_APP_STUCK_MS = 120 * 1e3;
|
|
9674
|
+
var WB_APP_NO_SDK_MS = 15 * 1e3;
|
|
9604
9675
|
var WB_APP_CONFIRM_MS = 60 * 1e3;
|
|
9605
9676
|
var WB_APP_CONFIRM_POLL_MS = 5 * 1e3;
|
|
9606
9677
|
var WB_APP_LOCATE_WAIT_MS = 20 * 1e3;
|
|
@@ -9715,7 +9786,7 @@ var WbAppTasks = class {
|
|
|
9715
9786
|
* 计时起点是「模式最近一次变成非 sdk 的时刻」(长期 sdk 时偶尔掉一下不算);页面脚本没结果(no_result,多半是一次超时)
|
|
9716
9787
|
* 不算:催一次重探,照常等。返回原因;不是这种情况返回 ''
|
|
9717
9788
|
*/
|
|
9718
|
-
#stuckWhy(max) {
|
|
9789
|
+
#stuckWhy(max, justWoke = false) {
|
|
9719
9790
|
const r = this.#readiness();
|
|
9720
9791
|
if (!r || !r.connected || !r.probed || r.mode === "sdk" || !r.nonSdkSince) return "";
|
|
9721
9792
|
if (r.modeWhy === "no_result") {
|
|
@@ -9723,7 +9794,7 @@ var WbAppTasks = class {
|
|
|
9723
9794
|
return "";
|
|
9724
9795
|
}
|
|
9725
9796
|
const secs = Math.round((this.#d.now() - r.nonSdkSince) / 1e3);
|
|
9726
|
-
if (this.#d.now() - r.nonSdkSince < max) return "";
|
|
9797
|
+
if (this.#d.now() - r.nonSdkSince < (r.modeWhy === "no_wb" && !justWoke ? Math.min(max, WB_APP_NO_SDK_MS) : max)) return "";
|
|
9727
9798
|
return `\u6388\u6743\u6865\u6A21\u5F0F\u662F ${r.mode} \u5DF2 ${secs} \u79D2${r.modeWhy ? `\uFF08${modeWhyText(r.modeWhy)}\uFF09` : ""}\uFF0CApp \u4E0D\u662F\u521A\u6253\u5F00\uFF0C\u518D\u7B49\u4E5F\u4E0D\u4F1A\u597D`;
|
|
9728
9799
|
}
|
|
9729
9800
|
async #ensureReady(cmd, sid, q, report, mayWake) {
|
|
@@ -9780,6 +9851,11 @@ var WbAppTasks = class {
|
|
|
9780
9851
|
await this.#sleep(Math.max(1, Math.min(this.#d.pollMs ?? WB_APP_POLL_MS, deadline - this.#d.now())));
|
|
9781
9852
|
const now = await this.#notReady();
|
|
9782
9853
|
if (!now) return true;
|
|
9854
|
+
const stuckNow = sid ? "" : this.#stuckWhy(WB_APP_STUCK_MS, w === "launched" || w === "restarted");
|
|
9855
|
+
if (stuckNow) {
|
|
9856
|
+
this.#d.log(`\u6307\u4EE4 ${cmd.instructionId} WorkBuddy App \u7528\u4E0D\u4E86\uFF1A${stuckNow}\uFF0C\u8D70\u547D\u4EE4\u884C`);
|
|
9857
|
+
return false;
|
|
9858
|
+
}
|
|
9783
9859
|
if (now !== why) this.#d.log(`\u6307\u4EE4 ${cmd.instructionId} \u7B49 WorkBuddy App\uFF1A${now}`);
|
|
9784
9860
|
why = now;
|
|
9785
9861
|
}
|
|
@@ -12665,10 +12741,50 @@ function unwrapShell(command) {
|
|
|
12665
12741
|
const w = command.match(/^"?(?:[^"]*[\\/])?(?:powershell|pwsh)(?:\.exe)?"?(?: -NoLogo| -NoProfile| -NonInteractive)* -Command ([\s\S]+)$/i);
|
|
12666
12742
|
if (!w) return command;
|
|
12667
12743
|
const body = w[1].trim();
|
|
12744
|
+
const posix4 = posixWord(body);
|
|
12745
|
+
if (posix4 !== null && /^'[^']*'["']/.test(body)) return posix4;
|
|
12668
12746
|
if (body.length >= 2 && body.startsWith('"') && body.endsWith('"')) return body.slice(1, -1).replace(/\\"/g, '"');
|
|
12669
12747
|
if (body.length >= 2 && body.startsWith("'") && body.endsWith("'")) return body.slice(1, -1).replace(/''/g, "'");
|
|
12670
12748
|
return body;
|
|
12671
12749
|
}
|
|
12750
|
+
function posixWord(s2) {
|
|
12751
|
+
let out = "";
|
|
12752
|
+
let i = 0;
|
|
12753
|
+
while (i < s2.length) {
|
|
12754
|
+
const c = s2[i];
|
|
12755
|
+
if (c === "'") {
|
|
12756
|
+
const j = s2.indexOf("'", i + 1);
|
|
12757
|
+
if (j < 0) return null;
|
|
12758
|
+
out += s2.slice(i + 1, j);
|
|
12759
|
+
i = j + 1;
|
|
12760
|
+
} else if (c === '"') {
|
|
12761
|
+
i++;
|
|
12762
|
+
let closed = false;
|
|
12763
|
+
while (i < s2.length) {
|
|
12764
|
+
const d = s2[i];
|
|
12765
|
+
if (d === '"') {
|
|
12766
|
+
closed = true;
|
|
12767
|
+
i++;
|
|
12768
|
+
break;
|
|
12769
|
+
}
|
|
12770
|
+
if (d === "\\" && i + 1 < s2.length && '\\"$`\n'.includes(s2[i + 1])) {
|
|
12771
|
+
out += s2[i + 1];
|
|
12772
|
+
i += 2;
|
|
12773
|
+
continue;
|
|
12774
|
+
}
|
|
12775
|
+
out += d;
|
|
12776
|
+
i++;
|
|
12777
|
+
}
|
|
12778
|
+
if (!closed) return null;
|
|
12779
|
+
} else if (/\s/.test(c)) {
|
|
12780
|
+
return null;
|
|
12781
|
+
} else {
|
|
12782
|
+
out += c;
|
|
12783
|
+
i++;
|
|
12784
|
+
}
|
|
12785
|
+
}
|
|
12786
|
+
return out;
|
|
12787
|
+
}
|
|
12672
12788
|
var CodexWatch = class {
|
|
12673
12789
|
#d;
|
|
12674
12790
|
#ws = null;
|
|
@@ -14046,6 +14162,68 @@ function describe2(r) {
|
|
|
14046
14162
|
return [r.status, r.n !== void 0 ? `n=${r.n}` : "", r.detail ?? ""].filter(Boolean).join(" ");
|
|
14047
14163
|
}
|
|
14048
14164
|
|
|
14165
|
+
// src/daemon/dshVersion.ts
|
|
14166
|
+
import { readFileSync as readFileSync11, realpathSync as realpathSync5 } from "fs";
|
|
14167
|
+
import { dirname as dirname8, join as join24 } from "path";
|
|
14168
|
+
var DSH_HEADLESS_MIN_VERSION = "0.0.1-rc.1";
|
|
14169
|
+
var DSH_PKG = "@deepseek-ai/dsh";
|
|
14170
|
+
var DSH_VERSION_UNSUPPORTED = "tool_version_unsupported";
|
|
14171
|
+
var defaultDeps2 = {
|
|
14172
|
+
locate: () => locate("deepseek_harness"),
|
|
14173
|
+
realpath: (p) => realpathSync5.native(p),
|
|
14174
|
+
readFile: (p) => {
|
|
14175
|
+
try {
|
|
14176
|
+
return readFileSync11(p, "utf8");
|
|
14177
|
+
} catch {
|
|
14178
|
+
return null;
|
|
14179
|
+
}
|
|
14180
|
+
}
|
|
14181
|
+
};
|
|
14182
|
+
function dshSupport(d = defaultDeps2) {
|
|
14183
|
+
let loc = null;
|
|
14184
|
+
try {
|
|
14185
|
+
loc = d.locate();
|
|
14186
|
+
} catch {
|
|
14187
|
+
loc = null;
|
|
14188
|
+
}
|
|
14189
|
+
if (!loc) return { ok: true };
|
|
14190
|
+
const script = loc.prefixArgs.find((a) => /\.(?:c|m)?js$/i.test(a)) ?? loc.file;
|
|
14191
|
+
let real2 = script;
|
|
14192
|
+
try {
|
|
14193
|
+
real2 = d.realpath(script);
|
|
14194
|
+
} catch {
|
|
14195
|
+
real2 = script;
|
|
14196
|
+
}
|
|
14197
|
+
let dir2 = dirname8(real2);
|
|
14198
|
+
for (let i = 0; i < 4; i++) {
|
|
14199
|
+
const raw = d.readFile(join24(dir2, "package.json"));
|
|
14200
|
+
if (raw !== null) {
|
|
14201
|
+
let pkg = {};
|
|
14202
|
+
try {
|
|
14203
|
+
pkg = JSON.parse(raw);
|
|
14204
|
+
} catch {
|
|
14205
|
+
pkg = {};
|
|
14206
|
+
}
|
|
14207
|
+
const name = typeof pkg.name === "string" ? pkg.name : "";
|
|
14208
|
+
const version = typeof pkg.version === "string" ? pkg.version : "";
|
|
14209
|
+
if (!name) {
|
|
14210
|
+
dir2 = dirname8(dir2);
|
|
14211
|
+
continue;
|
|
14212
|
+
}
|
|
14213
|
+
if (name !== DSH_PKG) return { ok: true };
|
|
14214
|
+
if (!isValidVersion(version) || semverLt(version, DSH_HEADLESS_MIN_VERSION)) return { ok: false, why: `${DSH_PKG} ${version || "\u7248\u672C\u8BFB\u4E0D\u51FA"} \u4F4E\u4E8E ${DSH_HEADLESS_MIN_VERSION}` };
|
|
14215
|
+
return { ok: true, version };
|
|
14216
|
+
}
|
|
14217
|
+
const up = dirname8(dir2);
|
|
14218
|
+
if (up === dir2) break;
|
|
14219
|
+
dir2 = up;
|
|
14220
|
+
}
|
|
14221
|
+
return { ok: true };
|
|
14222
|
+
}
|
|
14223
|
+
function dshOutputUnsupported(out) {
|
|
14224
|
+
return /unknown (?:command|option|argument)[^\n]*(?:headless|profile)|(?:invalid|no such) (?:command|choice)[^\n]*(?:headless|profile)|unrecognized arguments?:[^\n]*(?:--profile|headless)/i.test(out);
|
|
14225
|
+
}
|
|
14226
|
+
|
|
14049
14227
|
// src/daemon/opencodeVersion.ts
|
|
14050
14228
|
import { execFile as execFile5 } from "child_process";
|
|
14051
14229
|
import { statSync as statSync12 } from "fs";
|
|
@@ -14535,24 +14713,24 @@ function startWakeServer(path, hub, secret, platform = process.platform) {
|
|
|
14535
14713
|
}
|
|
14536
14714
|
|
|
14537
14715
|
// src/core/appended.ts
|
|
14538
|
-
import { chmodSync as chmodSync4, mkdirSync as mkdirSync11, readFileSync as
|
|
14539
|
-
import { join as
|
|
14716
|
+
import { chmodSync as chmodSync4, mkdirSync as mkdirSync11, readFileSync as readFileSync12, renameSync as renameSync8, rmSync as rmSync9, writeFileSync as writeFileSync10 } from "fs";
|
|
14717
|
+
import { join as join25 } from "path";
|
|
14540
14718
|
var APPENDED_MAX_ITEMS = 5;
|
|
14541
14719
|
var APPENDED_TEXT_MAX = 500;
|
|
14542
14720
|
var APPENDED_RESULT_MAX = 800;
|
|
14543
14721
|
var APPENDED_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
14544
14722
|
function appendedDir() {
|
|
14545
|
-
return
|
|
14723
|
+
return join25(deskbuddyHome(), "appended");
|
|
14546
14724
|
}
|
|
14547
14725
|
function appendedPath(sessionId) {
|
|
14548
14726
|
const safe2 = sessionId.replace(/[^A-Za-z0-9_-]/g, "");
|
|
14549
|
-
return safe2 ?
|
|
14727
|
+
return safe2 ? join25(appendedDir(), `${safe2}.json`) : null;
|
|
14550
14728
|
}
|
|
14551
14729
|
function readAppended(sessionId) {
|
|
14552
14730
|
const file = appendedPath(sessionId);
|
|
14553
14731
|
if (!file) return [];
|
|
14554
14732
|
try {
|
|
14555
|
-
const d = JSON.parse(
|
|
14733
|
+
const d = JSON.parse(readFileSync12(file, "utf8"));
|
|
14556
14734
|
return Array.isArray(d.items) ? d.items : [];
|
|
14557
14735
|
} catch {
|
|
14558
14736
|
return [];
|
|
@@ -14576,13 +14754,13 @@ function writeAppended(sessionId, item) {
|
|
|
14576
14754
|
var RUNNING_TTL_MS = 60 * 60 * 1e3;
|
|
14577
14755
|
function runningPath(sessionId) {
|
|
14578
14756
|
const safe2 = sessionId.replace(/[^A-Za-z0-9_-]/g, "");
|
|
14579
|
-
return safe2 ?
|
|
14757
|
+
return safe2 ? join25(deskbuddyHome(), "running", `${safe2}.json`) : null;
|
|
14580
14758
|
}
|
|
14581
14759
|
function writeRunning(sessionId, now = Date.now()) {
|
|
14582
14760
|
const file = runningPath(sessionId);
|
|
14583
14761
|
if (!file) return;
|
|
14584
14762
|
try {
|
|
14585
|
-
mkdirSync11(
|
|
14763
|
+
mkdirSync11(join25(deskbuddyHome(), "running"), { recursive: true, mode: 448 });
|
|
14586
14764
|
writeFileSync10(`${file}.tmp`, JSON.stringify({ at: now, pid: process.pid }), { encoding: "utf8", mode: 384 });
|
|
14587
14765
|
renameSync8(`${file}.tmp`, file);
|
|
14588
14766
|
} catch {
|
|
@@ -14629,8 +14807,8 @@ function resultSummary(tool, stdout6) {
|
|
|
14629
14807
|
}
|
|
14630
14808
|
|
|
14631
14809
|
// src/core/dshMailbox.ts
|
|
14632
|
-
import { chmodSync as chmodSync5, existsSync as existsSync6, mkdirSync as mkdirSync12, readdirSync as readdirSync10, readFileSync as
|
|
14633
|
-
import { join as
|
|
14810
|
+
import { chmodSync as chmodSync5, existsSync as existsSync6, mkdirSync as mkdirSync12, readdirSync as readdirSync10, readFileSync as readFileSync13, renameSync as renameSync9, rmSync as rmSync10, writeFileSync as writeFileSync11 } from "fs";
|
|
14811
|
+
import { join as join26 } from "path";
|
|
14634
14812
|
var DSH_HEARTBEAT_FRESH_MS = 5 * 1e3;
|
|
14635
14813
|
var DSH_ACK_TIMEOUT_MS = 8 * 1e3;
|
|
14636
14814
|
var ACK_POLL_MS = 200;
|
|
@@ -14641,10 +14819,10 @@ var REVOKE_RETRY_MS = 50;
|
|
|
14641
14819
|
var SID_RE2 = /^[A-Za-z0-9_-]{1,128}$/;
|
|
14642
14820
|
var IID_RE = /^[A-Za-z0-9_-]{1,128}$/;
|
|
14643
14821
|
function dshMailboxDir(home = deskbuddyHome(), channel = "dsh") {
|
|
14644
|
-
return
|
|
14822
|
+
return join26(home, channel);
|
|
14645
14823
|
}
|
|
14646
14824
|
function sub(home, name, channel = "dsh") {
|
|
14647
|
-
return
|
|
14825
|
+
return join26(dshMailboxDir(home, channel), name);
|
|
14648
14826
|
}
|
|
14649
14827
|
function ensureDir2(p) {
|
|
14650
14828
|
mkdirSync12(p, { recursive: true, mode: 448 });
|
|
@@ -14684,7 +14862,7 @@ function liveHeartbeats(sessionId, d0 = {}) {
|
|
|
14684
14862
|
if (!/^\d+\.json$/.test(n)) continue;
|
|
14685
14863
|
let hb;
|
|
14686
14864
|
try {
|
|
14687
|
-
hb = JSON.parse(
|
|
14865
|
+
hb = JSON.parse(readFileSync13(join26(dir2, n), "utf8"));
|
|
14688
14866
|
} catch {
|
|
14689
14867
|
continue;
|
|
14690
14868
|
}
|
|
@@ -14708,8 +14886,8 @@ async function dshDeliver(sessionId, msg, d0 = {}) {
|
|
|
14708
14886
|
const ackDir = sub(d.home, "ack", d.channel);
|
|
14709
14887
|
ensureDir2(inbox);
|
|
14710
14888
|
ensureDir2(ackDir);
|
|
14711
|
-
const letter =
|
|
14712
|
-
const ackPath =
|
|
14889
|
+
const letter = join26(inbox, `${sessionId}.${msg.instructionId}.json`);
|
|
14890
|
+
const ackPath = join26(ackDir, `${msg.instructionId}.json`);
|
|
14713
14891
|
if (existsSync6(letter)) return { ok: false, reason: "inbox_busy" };
|
|
14714
14892
|
const writtenAt = d.now();
|
|
14715
14893
|
writeJson(letter, {
|
|
@@ -14727,7 +14905,7 @@ async function dshDeliver(sessionId, msg, d0 = {}) {
|
|
|
14727
14905
|
if (existsSync6(ackPath)) {
|
|
14728
14906
|
let ack = { ok: false, reason: "bad_ack" };
|
|
14729
14907
|
try {
|
|
14730
|
-
const v = JSON.parse(
|
|
14908
|
+
const v = JSON.parse(readFileSync13(ackPath, "utf8"));
|
|
14731
14909
|
if (v && typeof v.ok === "boolean") ack = v;
|
|
14732
14910
|
} catch {
|
|
14733
14911
|
}
|
|
@@ -14778,10 +14956,10 @@ function dshClearInbox(home = deskbuddyHome(), channel = "dsh") {
|
|
|
14778
14956
|
var DSH_REPLY_WAIT_MS = 4 * 60 * 1e3;
|
|
14779
14957
|
function takeMailboxReply(instructionId, home = deskbuddyHome(), channel = "dsh") {
|
|
14780
14958
|
if (!IID_RE.test(instructionId)) return null;
|
|
14781
|
-
const p =
|
|
14959
|
+
const p = join26(sub(home, "reply", channel), `${instructionId}.json`);
|
|
14782
14960
|
let v = null;
|
|
14783
14961
|
try {
|
|
14784
|
-
v = JSON.parse(
|
|
14962
|
+
v = JSON.parse(readFileSync13(p, "utf8"));
|
|
14785
14963
|
} catch {
|
|
14786
14964
|
return null;
|
|
14787
14965
|
}
|
|
@@ -14807,7 +14985,7 @@ function clearDir(inbox) {
|
|
|
14807
14985
|
let n = 0;
|
|
14808
14986
|
for (const f of names) {
|
|
14809
14987
|
try {
|
|
14810
|
-
rmSync10(
|
|
14988
|
+
rmSync10(join26(inbox, f), { force: true });
|
|
14811
14989
|
n++;
|
|
14812
14990
|
} catch {
|
|
14813
14991
|
}
|
|
@@ -14882,7 +15060,7 @@ function defaultCodexAppServers() {
|
|
|
14882
15060
|
}
|
|
14883
15061
|
function opencodeReady() {
|
|
14884
15062
|
const mod = ocPluginModule(installedHookPath());
|
|
14885
|
-
return isOcPluginInstalled(opencodePluginPath()) && existsSync7(mod) && existsSync7(
|
|
15063
|
+
return isOcPluginInstalled(opencodePluginPath()) && existsSync7(mod) && existsSync7(join27(dirname9(mod), "ocTranslate.mjs"));
|
|
14886
15064
|
}
|
|
14887
15065
|
var INTERNAL_PROMPT_MARK = "[DeskBuddy]";
|
|
14888
15066
|
function orphanResumeText(summary2) {
|
|
@@ -15039,6 +15217,7 @@ var Daemon = class {
|
|
|
15039
15217
|
materialize: deps2.materialize ?? ((plan, tool) => materialize(plan, tool)),
|
|
15040
15218
|
opencodeReady: deps2.opencodeReady ?? opencodeReady,
|
|
15041
15219
|
opencodeVersion: deps2.opencodeVersion ?? defaultOpencodeVersion,
|
|
15220
|
+
dshSupport: deps2.dshSupport ?? (() => dshSupport()),
|
|
15042
15221
|
codexAppServers: deps2.codexAppServers ?? defaultCodexAppServers,
|
|
15043
15222
|
codexRoute: deps2.codexRoute ?? ((tid) => this.#codexRouteFor(tid)),
|
|
15044
15223
|
report: deps2.report ?? ((p, t) => api.commandResult(p, t)),
|
|
@@ -16741,7 +16920,7 @@ var Daemon = class {
|
|
|
16741
16920
|
for (const n of names) {
|
|
16742
16921
|
if (!n.endsWith(".json")) continue;
|
|
16743
16922
|
try {
|
|
16744
|
-
const s2 = JSON.parse(
|
|
16923
|
+
const s2 = JSON.parse(readFileSync14(join27(stateDir(), n), "utf8"));
|
|
16745
16924
|
if (typeof s2.sessionId === "string" && typeof s2.tool === "string" && enabled.has(s2.tool)) out.push({ tool: s2.tool, sessionId: s2.sessionId, state: typeof s2.state === "string" ? s2.state : "", cwd: typeof s2.cwd === "string" ? s2.cwd : "" });
|
|
16746
16925
|
} catch {
|
|
16747
16926
|
}
|
|
@@ -16775,12 +16954,12 @@ var Daemon = class {
|
|
|
16775
16954
|
}
|
|
16776
16955
|
case "deepseek_harness": {
|
|
16777
16956
|
if (!TRANSCRIPT_SID_RE.test(s2.sessionId)) return null;
|
|
16778
|
-
const p =
|
|
16957
|
+
const p = join27(deskbuddyHome(), "dsh", "transcript", `${s2.sessionId}.jsonl`);
|
|
16779
16958
|
return existsSync7(p) ? { kind: "file", path: p, format: "dsh" } : null;
|
|
16780
16959
|
}
|
|
16781
16960
|
case "opencode": {
|
|
16782
16961
|
if (!TRANSCRIPT_SID_RE.test(s2.sessionId)) return null;
|
|
16783
|
-
return snapshotSource(`opencode-snap:${s2.sessionId}`,
|
|
16962
|
+
return snapshotSource(`opencode-snap:${s2.sessionId}`, join27(deskbuddyHome(), "opencode", "transcript", `${s2.sessionId}.json`));
|
|
16784
16963
|
}
|
|
16785
16964
|
case "dumate":
|
|
16786
16965
|
return { kind: "http", key: "dumate", fetch: () => this.#dumate.transcriptMessages(s2.sessionId) };
|
|
@@ -16811,7 +16990,7 @@ var Daemon = class {
|
|
|
16811
16990
|
#summaryTranscriptOf(st) {
|
|
16812
16991
|
const f = this.#transcriptOf(st, this.#deps.now());
|
|
16813
16992
|
if (f) return f;
|
|
16814
|
-
const homes = st.tool === "workbuddy" ? [st.configDir,
|
|
16993
|
+
const homes = st.tool === "workbuddy" ? [st.configDir, dirname9(workbuddySettingsPath()), codebuddyConfigDir()] : st.tool === "qwenwork" ? [qwenworkDataHome()] : [];
|
|
16815
16994
|
for (const h of homes) {
|
|
16816
16995
|
if (!h) continue;
|
|
16817
16996
|
const p = claudeTranscriptFile(st.sessionId, st.cwd, h);
|
|
@@ -17131,6 +17310,19 @@ var Daemon = class {
|
|
|
17131
17310
|
return;
|
|
17132
17311
|
}
|
|
17133
17312
|
}
|
|
17313
|
+
if (cmd.tool === "deepseek_harness" && !sessionId) {
|
|
17314
|
+
let sup = { ok: true };
|
|
17315
|
+
try {
|
|
17316
|
+
sup = this.#deps.dshSupport();
|
|
17317
|
+
} catch {
|
|
17318
|
+
sup = { ok: true };
|
|
17319
|
+
}
|
|
17320
|
+
if (!sup.ok) {
|
|
17321
|
+
log(`\u6307\u4EE4 ${cmd.instructionId} \u4E0D\u6267\u884C\uFF1A\u7535\u8111\u4E0A\u7684 DeepSeek Harness \u7248\u672C\u592A\u65E7\uFF0C\u4E0D\u652F\u6301\u8BBE\u5907\u65B0\u5EFA\u4EFB\u52A1\uFF08${sup.why}\uFF1B\u9700\u8981 ${DSH_PKG} \u2265 ${DSH_HEADLESS_MIN_VERSION}\uFF09`);
|
|
17322
|
+
this.#report(cmd, "", "rejected", "", DSH_VERSION_UNSUPPORTED);
|
|
17323
|
+
return;
|
|
17324
|
+
}
|
|
17325
|
+
}
|
|
17134
17326
|
const runId = newRunId();
|
|
17135
17327
|
const text = isSummary(cmd) ? withSummaryMark(cmd.text, cmd.instructionId) : cmd.text;
|
|
17136
17328
|
const plan = buildSpawnPlan({ ...cmd, sessionId, text }, cwd, this.#gateTarget(runId), void 0, sessionId ? readState(sessionId)?.configDir : void 0);
|
|
@@ -17167,12 +17359,15 @@ var Daemon = class {
|
|
|
17167
17359
|
);
|
|
17168
17360
|
const writerBusy = cmd.tool === "codex" && isCodexWriterBusy(result, cmd.text);
|
|
17169
17361
|
if (writerBusy) log(`\u6307\u4EE4 ${cmd.instructionId} Codex \u4F1A\u8BDD\u6B63\u5F00\u5728\u7535\u8111\u7A97\u53E3\u91CC\uFF08\u5360\u7740\u5199\uFF09\uFF0C\u540E\u53F0\u7EED\u4E0D\u4E86`);
|
|
17362
|
+
const dshOld = cmd.tool === "deepseek_harness" && !sessionId && dshOutputUnsupported(`${result.stderr ?? ""}
|
|
17363
|
+
${result.stdout}`);
|
|
17364
|
+
if (dshOld) log(`\u6307\u4EE4 ${cmd.instructionId} \u7535\u8111\u4E0A\u7684 DeepSeek Harness \u7248\u672C\u592A\u65E7\uFF0C\u4E0D\u652F\u6301\u8BBE\u5907\u65B0\u5EFA\u4EFB\u52A1\uFF08\u4E0D\u8BA4 --profile headless\uFF09`);
|
|
17170
17365
|
this.#report(
|
|
17171
17366
|
cmd,
|
|
17172
17367
|
sessionId || result.sessionId || "",
|
|
17173
17368
|
"failed",
|
|
17174
17369
|
"headless",
|
|
17175
|
-
notLoggedIn ? AGENT_NOT_LOGGED_IN : writerBusy ? "window_open" : "exec_failed"
|
|
17370
|
+
notLoggedIn ? AGENT_NOT_LOGGED_IN : writerBusy ? "window_open" : dshOld ? DSH_VERSION_UNSUPPORTED : "exec_failed"
|
|
17176
17371
|
);
|
|
17177
17372
|
if (notLoggedIn) this.#guideLogin(cmd.tool);
|
|
17178
17373
|
}
|
|
@@ -17407,7 +17602,7 @@ async function runDaemon(deps2 = {}) {
|
|
|
17407
17602
|
}
|
|
17408
17603
|
|
|
17409
17604
|
// src/daemon/shimCheck.ts
|
|
17410
|
-
import { readFileSync as
|
|
17605
|
+
import { readFileSync as readFileSync15 } from "fs";
|
|
17411
17606
|
var SHIM_CHECK_FIRST_DELAY_MS = 60 * 1e3;
|
|
17412
17607
|
var SHIM_CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
17413
17608
|
var TOOL = "claude_code";
|
|
@@ -17503,7 +17698,7 @@ function defaultShimCheckDeps(log2, idle, inj = {}) {
|
|
|
17503
17698
|
idle,
|
|
17504
17699
|
shimInstalled: () => {
|
|
17505
17700
|
try {
|
|
17506
|
-
return
|
|
17701
|
+
return readFileSync15(shimFile(probe.binDir, command, "win32"), "utf8").includes(SHIM_MARKER);
|
|
17507
17702
|
} catch {
|
|
17508
17703
|
return false;
|
|
17509
17704
|
}
|
|
@@ -17712,7 +17907,7 @@ async function runDisable(tools, opts = {}) {
|
|
|
17712
17907
|
|
|
17713
17908
|
// src/commands/install.ts
|
|
17714
17909
|
import { mkdirSync as mkdirSync13, rmSync as rmSync12, writeFileSync as writeFileSync13 } from "fs";
|
|
17715
|
-
import { join as
|
|
17910
|
+
import { join as join28 } from "path";
|
|
17716
17911
|
|
|
17717
17912
|
// src/commands/setup.ts
|
|
17718
17913
|
import qrcode from "qrcode-terminal";
|
|
@@ -17929,7 +18124,7 @@ function inSandbox(env) {
|
|
|
17929
18124
|
}
|
|
17930
18125
|
function precheckWritable(dirs) {
|
|
17931
18126
|
for (const dir2 of dirs) {
|
|
17932
|
-
const probe =
|
|
18127
|
+
const probe = join28(dir2, `.deskbuddy-probe-${process.pid}`);
|
|
17933
18128
|
try {
|
|
17934
18129
|
mkdirSync13(dir2, { recursive: true });
|
|
17935
18130
|
writeFileSync13(probe, "");
|
|
@@ -18339,11 +18534,12 @@ async function runAutoSwitch(opts) {
|
|
|
18339
18534
|
// src/wrap/run.ts
|
|
18340
18535
|
import { randomBytes as randomBytes10 } from "crypto";
|
|
18341
18536
|
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync15, statSync as statSync16, truncateSync as truncateSync3 } from "fs";
|
|
18342
|
-
import { join as
|
|
18537
|
+
import { join as join31 } from "path";
|
|
18343
18538
|
import { StringDecoder as StringDecoder2 } from "string_decoder";
|
|
18344
18539
|
|
|
18345
18540
|
// src/wrap/injector.ts
|
|
18346
18541
|
var SEEN_MAX = 200;
|
|
18542
|
+
var PERMISSION_PENDING = "permission_pending";
|
|
18347
18543
|
var WINDOW_UNRECOGNIZED = "window_unrecognized";
|
|
18348
18544
|
var QUIET_MS = 1500;
|
|
18349
18545
|
var STARTUP_QUIET_MS = 3e3;
|
|
@@ -18509,7 +18705,8 @@ var Injector = class {
|
|
|
18509
18705
|
return;
|
|
18510
18706
|
}
|
|
18511
18707
|
if (job.expireAt > 0 && this.#d.now() > job.expireAt) {
|
|
18512
|
-
this.#
|
|
18708
|
+
const perm = this.#lastWhy.split(",").includes("permission");
|
|
18709
|
+
this.#final(job, { status: "rejected", mode: "window", reason: perm ? PERMISSION_PENDING : "expired" });
|
|
18513
18710
|
return;
|
|
18514
18711
|
}
|
|
18515
18712
|
if (!this.#owns(job.sessionId)) {
|
|
@@ -18684,9 +18881,9 @@ var WithdrawWatch = class {
|
|
|
18684
18881
|
|
|
18685
18882
|
// src/wrap/passthrough.ts
|
|
18686
18883
|
import { spawn as spawn3 } from "child_process";
|
|
18687
|
-
import { realpathSync as
|
|
18884
|
+
import { realpathSync as realpathSync6 } from "fs";
|
|
18688
18885
|
import { constants } from "os";
|
|
18689
|
-
import { dirname as
|
|
18886
|
+
import { dirname as dirname10, resolve as resolve7 } from "path";
|
|
18690
18887
|
var CLAUDE_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
18691
18888
|
"agents",
|
|
18692
18889
|
"attach",
|
|
@@ -18742,7 +18939,7 @@ function norm(p, win) {
|
|
|
18742
18939
|
}
|
|
18743
18940
|
function real(p) {
|
|
18744
18941
|
try {
|
|
18745
|
-
return
|
|
18942
|
+
return realpathSync6(p);
|
|
18746
18943
|
} catch {
|
|
18747
18944
|
return p;
|
|
18748
18945
|
}
|
|
@@ -18750,7 +18947,7 @@ function real(p) {
|
|
|
18750
18947
|
function findReal(tool, d = defaultLocateDeps(), skip = shimDir()) {
|
|
18751
18948
|
const win = (d.platform ?? process.platform) === "win32";
|
|
18752
18949
|
const skipKeys = /* @__PURE__ */ new Set([norm(skip, win), norm(real(skip), win)]);
|
|
18753
|
-
const inSkip = (file) => skipKeys.has(norm(
|
|
18950
|
+
const inSkip = (file) => skipKeys.has(norm(dirname10(file), win)) || skipKeys.has(norm(dirname10(real(file)), win));
|
|
18754
18951
|
const dd = { ...d, skipDirs: [...d.skipDirs ?? [], skip] };
|
|
18755
18952
|
const name = SHIM_COMMANDS[tool];
|
|
18756
18953
|
if (!name) {
|
|
@@ -18834,10 +19031,10 @@ function runDirect(real2, args, env = process.env) {
|
|
|
18834
19031
|
|
|
18835
19032
|
// src/wrap/codexLaunch.ts
|
|
18836
19033
|
import { execFileSync as execFileSync4, spawn as spawn4 } from "child_process";
|
|
18837
|
-
import { closeSync as closeSync9, mkdirSync as mkdirSync14, openSync as openSync9, readdirSync as readdirSync12, readFileSync as
|
|
19034
|
+
import { closeSync as closeSync9, mkdirSync as mkdirSync14, openSync as openSync9, readdirSync as readdirSync12, readFileSync as readFileSync16, rmSync as rmSync14, statSync as statSync15, truncateSync as truncateSync2, writeFileSync as writeFileSync14, renameSync as renameSync10 } from "fs";
|
|
18838
19035
|
import { request as request2 } from "http";
|
|
18839
19036
|
import { createServer as createServer5 } from "net";
|
|
18840
|
-
import { join as
|
|
19037
|
+
import { join as join29 } from "path";
|
|
18841
19038
|
var TAKEOVER_VALUE_OPTS = /* @__PURE__ */ new Set(["-c", "--config", "-m", "--model", "-s", "--sandbox", "-a", "--ask-for-approval", "-C", "--cd", "--enable", "--disable"]);
|
|
18842
19039
|
var SHORT_VALUE_OPTS = /* @__PURE__ */ new Set(["-c", "-m", "-s", "-a", "-C"]);
|
|
18843
19040
|
var TAKEOVER_FLAGS = /* @__PURE__ */ new Set(["--search", "--no-alt-screen", "--dangerously-bypass-approvals-and-sandbox"]);
|
|
@@ -19006,10 +19203,10 @@ async function runCodexWindow(real2, args, d) {
|
|
|
19006
19203
|
}
|
|
19007
19204
|
var MAX_LOG_BYTES2 = 1024 * 1024;
|
|
19008
19205
|
function appServerLogPath() {
|
|
19009
|
-
return
|
|
19206
|
+
return join29(deskbuddyHome(), "codex-app-server.log");
|
|
19010
19207
|
}
|
|
19011
19208
|
function windowsDir2() {
|
|
19012
|
-
return
|
|
19209
|
+
return join29(deskbuddyHome(), "codex-windows");
|
|
19013
19210
|
}
|
|
19014
19211
|
function pidAlive5(pid) {
|
|
19015
19212
|
try {
|
|
@@ -19022,7 +19219,7 @@ function pidAlive5(pid) {
|
|
|
19022
19219
|
function daemonAlive(pidFile = pidFilePath(), args = processArgs) {
|
|
19023
19220
|
let pid = 0;
|
|
19024
19221
|
try {
|
|
19025
|
-
pid = Number(
|
|
19222
|
+
pid = Number(readFileSync16(pidFile, "utf8").trim());
|
|
19026
19223
|
} catch {
|
|
19027
19224
|
return false;
|
|
19028
19225
|
}
|
|
@@ -19099,7 +19296,7 @@ function killOwnServer(pid, url, args = freshArgs, kill = (p) => killServer(p))
|
|
|
19099
19296
|
if (a && isAppServerArgs(a, url)) kill(pid);
|
|
19100
19297
|
}
|
|
19101
19298
|
function recordPath(rec) {
|
|
19102
|
-
return
|
|
19299
|
+
return join29(windowsDir2(), `${rec.server}.json`);
|
|
19103
19300
|
}
|
|
19104
19301
|
function writeRecord(rec) {
|
|
19105
19302
|
try {
|
|
@@ -19124,10 +19321,10 @@ function reapWindows(dir2 = windowsDir2(), alive = pidAlive5, args = freshArgs,
|
|
|
19124
19321
|
return;
|
|
19125
19322
|
}
|
|
19126
19323
|
for (const n of names) {
|
|
19127
|
-
const p =
|
|
19324
|
+
const p = join29(dir2, n);
|
|
19128
19325
|
let rec;
|
|
19129
19326
|
try {
|
|
19130
|
-
rec = JSON.parse(
|
|
19327
|
+
rec = JSON.parse(readFileSync16(p, "utf8"));
|
|
19131
19328
|
} catch {
|
|
19132
19329
|
rmSync14(p, { force: true });
|
|
19133
19330
|
continue;
|
|
@@ -19147,7 +19344,7 @@ function reapWindows(dir2 = windowsDir2(), alive = pidAlive5, args = freshArgs,
|
|
|
19147
19344
|
function launchLog(line) {
|
|
19148
19345
|
try {
|
|
19149
19346
|
mkdirSync14(deskbuddyHome(), { recursive: true });
|
|
19150
|
-
writeFileSync14(
|
|
19347
|
+
writeFileSync14(join29(deskbuddyHome(), "wrap.log"), `${(/* @__PURE__ */ new Date()).toISOString()} [codex ${process.pid}] ${line}
|
|
19151
19348
|
`, { flag: "a" });
|
|
19152
19349
|
} catch {
|
|
19153
19350
|
}
|
|
@@ -19172,7 +19369,7 @@ function defaultCodexWindowDeps(base) {
|
|
|
19172
19369
|
// src/wrap/promptLaunch.ts
|
|
19173
19370
|
import { randomBytes as randomBytes8, randomUUID as randomUUID3 } from "crypto";
|
|
19174
19371
|
import { homedir as homedir10 } from "os";
|
|
19175
|
-
import { join as
|
|
19372
|
+
import { join as join30 } from "path";
|
|
19176
19373
|
var FIRST_LINE_WAIT_MS2 = 2 * 60 * 1e3;
|
|
19177
19374
|
function promptArgs(text, tool = "") {
|
|
19178
19375
|
if (!text) return [];
|
|
@@ -19182,7 +19379,7 @@ function promptArgs(text, tool = "") {
|
|
|
19182
19379
|
function promptEnv(tool, env, launcherPid = process.pid, answerWindowId = "") {
|
|
19183
19380
|
const out = { ...env };
|
|
19184
19381
|
if (tool === "workbuddy") {
|
|
19185
|
-
if (!out.CODEBUDDY_CONFIG_DIR) out.CODEBUDDY_CONFIG_DIR =
|
|
19382
|
+
if (!out.CODEBUDDY_CONFIG_DIR) out.CODEBUDDY_CONFIG_DIR = join30(homedir10(), ".workbuddy");
|
|
19186
19383
|
out.DESKBUDDY_LAUNCHER_PID = String(launcherPid);
|
|
19187
19384
|
out.DESKBUDDY_LAUNCHED_TOOL = tool;
|
|
19188
19385
|
if (answerWindowId) out.DESKBUDDY_LAUNCHED_WINDOW = answerWindowId;
|
|
@@ -19721,7 +19918,7 @@ async function runAnswerWindow(tool, real2, args, env, windowId, d) {
|
|
|
19721
19918
|
}
|
|
19722
19919
|
|
|
19723
19920
|
// src/wrap/launchRegister.ts
|
|
19724
|
-
import { dirname as
|
|
19921
|
+
import { dirname as dirname11 } from "path";
|
|
19725
19922
|
async function launchTranscriptReady(tool, sessionId) {
|
|
19726
19923
|
try {
|
|
19727
19924
|
if (tool === "qoder_cn") {
|
|
@@ -19729,7 +19926,7 @@ async function launchTranscriptReady(tool, sessionId) {
|
|
|
19729
19926
|
return !!p && (await transcriptInfo(p)).title !== "";
|
|
19730
19927
|
}
|
|
19731
19928
|
if (tool === "workbuddy") {
|
|
19732
|
-
const p = findWbTranscript(
|
|
19929
|
+
const p = findWbTranscript(dirname11(workbuddySettingsPath()), sessionId);
|
|
19733
19930
|
return !!p && wbTranscriptInfo(p).title !== "";
|
|
19734
19931
|
}
|
|
19735
19932
|
return false;
|
|
@@ -19737,8 +19934,8 @@ async function launchTranscriptReady(tool, sessionId) {
|
|
|
19737
19934
|
return false;
|
|
19738
19935
|
}
|
|
19739
19936
|
}
|
|
19740
|
-
var
|
|
19741
|
-
async function launchRegister(tool, sessionId, cwd, firstLine, final, d =
|
|
19937
|
+
var defaultDeps3 = { qoder: (j) => syncQoderApp(j), workbuddy: (j) => registerWorkbuddySession(j) };
|
|
19938
|
+
async function launchRegister(tool, sessionId, cwd, firstLine, final, d = defaultDeps3) {
|
|
19742
19939
|
if (tool === "workbuddy") return d.workbuddy({ sessionId, cwd, fallbackTitle: firstLine ?? "" });
|
|
19743
19940
|
if (tool !== "qoder_cn") return "skip tool";
|
|
19744
19941
|
const r = await d.qoder({ tool, kind: "register", sessionId, cwd, fallbackTitle: firstLine ?? "" });
|
|
@@ -19766,7 +19963,7 @@ function childEnv(src, windowId, takeover = true) {
|
|
|
19766
19963
|
}
|
|
19767
19964
|
function wrapLog(line) {
|
|
19768
19965
|
try {
|
|
19769
|
-
const p =
|
|
19966
|
+
const p = join31(deskbuddyHome(), "wrap.log");
|
|
19770
19967
|
mkdirSync15(deskbuddyHome(), { recursive: true });
|
|
19771
19968
|
try {
|
|
19772
19969
|
if (statSync16(p).size > MAX_LOG_BYTES3) truncateSync3(p, 0);
|
package/hook/hook-debug.log
CHANGED
|
@@ -308,3 +308,33 @@
|
|
|
308
308
|
2026-10-12T06:14:16.558Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
309
309
|
2026-10-12T06:14:16.558Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
310
310
|
2026-10-12T06:14:19.410Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
311
|
+
2026-10-12T07:00:56.655Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
312
|
+
2026-10-12T07:01:01.581Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
313
|
+
2026-10-12T07:01:01.581Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
314
|
+
2026-10-12T07:01:01.681Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
315
|
+
2026-10-12T07:01:01.681Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
316
|
+
2026-10-12T07:01:04.078Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
317
|
+
2026-10-12T07:36:12.685Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
318
|
+
2026-10-12T07:36:17.637Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
319
|
+
2026-10-12T07:36:17.637Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
320
|
+
2026-10-12T07:36:17.734Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
321
|
+
2026-10-12T07:36:17.734Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
322
|
+
2026-10-12T07:36:20.164Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
323
|
+
2026-10-12T07:38:26.140Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
324
|
+
2026-10-12T07:38:31.306Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
325
|
+
2026-10-12T07:38:31.306Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
326
|
+
2026-10-12T07:38:31.422Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
327
|
+
2026-10-12T07:38:31.422Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
328
|
+
2026-10-12T07:38:34.204Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
329
|
+
2026-10-12T07:45:21.768Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
330
|
+
2026-10-12T07:45:26.698Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
331
|
+
2026-10-12T07:45:26.699Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
332
|
+
2026-10-12T07:45:26.806Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
333
|
+
2026-10-12T07:45:26.806Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
334
|
+
2026-10-12T07:45:29.059Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|
|
335
|
+
2026-10-12T07:48:52.563Z [opencode] 回填选择题失败:/question/{requestID}/reply status=404
|
|
336
|
+
2026-10-12T07:48:57.566Z [opencode] opencode 版本 1.4.3:带说明的拒绝不走新路由
|
|
337
|
+
2026-10-12T07:48:57.566Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
338
|
+
2026-10-12T07:48:57.673Z [opencode] opencode 版本 读不出:带说明的拒绝不走新路由
|
|
339
|
+
2026-10-12T07:48:57.673Z [opencode] opencode 版本不确定支持带说明的拒绝,设备上的反馈没有带给模型
|
|
340
|
+
2026-10-12T07:49:00.208Z [opencode] 后台任务里的提问 que_r2 没法在设备上回答(后台任务不能提问,请在电脑上继续),已拒绝
|