deskbuddy 0.2.0-beta.46 → 0.2.0-beta.48

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.
@@ -8,6 +8,8 @@ import { randomUUID } from "crypto";
8
8
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
9
9
  import { homedir, hostname } from "os";
10
10
  import { dirname, join, resolve } from "path";
11
+ var DEFAULT_FOCUS_IDLE_SECONDS = 5;
12
+ var MAX_FOCUS_IDLE_SECONDS = 600;
11
13
  function defaultRemoteCwd(home = homedir()) {
12
14
  return process.env.DESKBUDDY_DEFAULT_REMOTE_CWD || join(home, "DeskBuddy");
13
15
  }
@@ -203,7 +205,11 @@ function loadConfig() {
203
205
  cozeApp: typeof parsed.cozeApp === "boolean" ? parsed.cozeApp : void 0,
204
206
  cozeCdpPort: portOrUndefined(parsed.cozeCdpPort),
205
207
  chatgptAppPort: typeof parsed.chatgptAppPort === "boolean" ? parsed.chatgptAppPort : void 0,
206
- chatgptCdpPort: portOrUndefined(parsed.chatgptCdpPort)
208
+ chatgptCdpPort: portOrUndefined(parsed.chatgptCdpPort),
209
+ focusSessionOnRemote: typeof parsed.focusSessionOnRemote === "boolean" ? parsed.focusSessionOnRemote : void 0,
210
+ focusSessionOnRemoteWindows: typeof parsed.focusSessionOnRemoteWindows === "boolean" ? parsed.focusSessionOnRemoteWindows : void 0,
211
+ focusSessionInApp: typeof parsed.focusSessionInApp === "boolean" ? parsed.focusSessionInApp : void 0,
212
+ focusIdleSeconds: typeof parsed.focusIdleSeconds === "number" && Number.isInteger(parsed.focusIdleSeconds) && parsed.focusIdleSeconds >= 0 && parsed.focusIdleSeconds <= MAX_FOCUS_IDLE_SECONDS ? parsed.focusIdleSeconds : void 0
207
213
  };
208
214
  } catch {
209
215
  return fallback;
@@ -1711,10 +1717,19 @@ var CODEX_EVENTS = [
1711
1717
  "SessionEnd",
1712
1718
  "PermissionRequest"
1713
1719
  ];
1714
- var CODEX_TRUST_NOTICE = "\u26A0\uFE0F \u4E0B\u6B21\u542F\u52A8 Codex \u65F6\u4F1A\u8981\u6C42\u4F60\u786E\u8BA4\u4FE1\u4EFB\u8FD9\u4E2A hook\uFF0C\u8BF7\u9009\u62E9\u540C\u610F\u2014\u2014\u4E0D\u786E\u8BA4\u7684\u8BDD Codex \u4E0D\u4F1A\u6267\u884C\u5B83\u3002\n DeskBuddy \u5347\u7EA7\uFF08\u542B\u81EA\u52A8\u5347\u7EA7\uFF09\u65B0\u589E hook \u6761\u76EE\u65F6\uFF0CCodex \u53EA\u4F1A\u5C31\u65B0\u6761\u76EE\u518D\u95EE\u4E00\u6B21\uFF0C\u540C\u6837\u9009\u540C\u610F\uFF1B\u539F\u6709\u6761\u76EE\u4E0D\u53D7\u5F71\u54CD\u3001\u72B6\u6001\u7167\u5E38\u4E0A\u62A5\u3002\n Codex \u7ECF `--remote` \u8FDE\u5E38\u9A7B app-server \u4F7F\u7528\u65F6\uFF0C\u7A97\u53E3\u91CC\u7684\u6388\u6743\u6846\u4E5F\u80FD\u5728\u8BBE\u5907\u4E0A\u786E\u8BA4\uFF08\u5B88\u62A4\u8FDB\u7A0B\u5728\u8DD1\u65F6\u751F\u6548\uFF09";
1720
+ var CODEX_TRUST_NOTICE = "\u26A0\uFE0F \u4E0B\u6B21\u542F\u52A8 Codex \u65F6\u4F1A\u8981\u6C42\u4F60\u786E\u8BA4\u4FE1\u4EFB\u8FD9\u4E2A hook\uFF0C\u8BF7\u9009\u62E9\u540C\u610F\u2014\u2014\u4E0D\u786E\u8BA4\u7684\u8BDD Codex \u4E0D\u4F1A\u6267\u884C\u5B83\u3002\n \u6BCF\u6761 hook \u90FD\u5E26\u300CDeskBuddy\uFF1A\u2026\u300D\u540D\u5B57\uFF0C\u5BA1\u67E5\u6846\u91CC\u80FD\u770B\u5230\u5B83\u662F\u505A\u4EC0\u4E48\u7684\u3002\n DeskBuddy \u5347\u7EA7\uFF08\u542B\u81EA\u52A8\u5347\u7EA7\uFF09\u65B0\u589E\u6216\u6539\u52A8 hook \u6761\u76EE\u65F6\uFF0CCodex \u4F1A\u5C31\u8FD9\u4E9B\u6761\u76EE\u518D\u95EE\u4E00\u6B21\uFF0C\u540C\u6837\u9009\u540C\u610F\uFF1B\u786E\u8BA4\u524D\u8FD9\u4E9B\u6761\u76EE\u4E0D\u6267\u884C\u3002\n Codex \u7ECF `--remote` \u8FDE\u5E38\u9A7B app-server \u4F7F\u7528\u65F6\uFF0C\u7A97\u53E3\u91CC\u7684\u6388\u6743\u6846\u4E5F\u80FD\u5728\u8BBE\u5907\u4E0A\u786E\u8BA4\uFF08\u5B88\u62A4\u8FDB\u7A0B\u5728\u8DD1\u65F6\u751F\u6548\uFF09";
1715
1721
  function codexConfigPath() {
1716
1722
  return join7(codexHome(), "config.toml");
1717
1723
  }
1724
+ var CODEX_HOOK_LABELS = {
1725
+ UserPromptSubmit: "DeskBuddy\uFF1A\u628A\u4F60\u53D1\u7684\u6D88\u606F\u540C\u6B65\u5230\u684C\u9762\u8BBE\u5907",
1726
+ PreToolUse: "DeskBuddy\uFF1A\u628A\u6B63\u5728\u6267\u884C\u7684\u64CD\u4F5C\u540C\u6B65\u5230\u684C\u9762\u8BBE\u5907",
1727
+ PostToolUse: "DeskBuddy\uFF1A\u628A\u64CD\u4F5C\u7ED3\u679C\u540C\u6B65\u5230\u684C\u9762\u8BBE\u5907",
1728
+ Stop: "DeskBuddy\uFF1A\u4EFB\u52A1\u5B8C\u6210\u65F6\u901A\u77E5\u684C\u9762\u8BBE\u5907",
1729
+ SessionEnd: "DeskBuddy\uFF1A\u4F1A\u8BDD\u7ED3\u675F\u65F6\u901A\u77E5\u684C\u9762\u8BBE\u5907",
1730
+ PermissionRequest: "DeskBuddy\uFF1A\u628A\u6388\u6743\u8BF7\u6C42\u540C\u6B65\u5230\u684C\u9762\u8BBE\u5907"
1731
+ };
1732
+ var CODEX_APPENDED_LABEL = "DeskBuddy\uFF1A\u8BFB\u53D6\u4F60\u5728\u684C\u9762\u8BBE\u5907\u4E0A\u8FFD\u52A0\u7684\u6307\u4EE4";
1718
1733
  var CODEX_APPENDED_TIMEOUT_S = 3;
1719
1734
  function renderBlock(hookPath, events, tool, platform) {
1720
1735
  const script = platform === "win32" ? winPsPath(hookPath) : hookPath;
@@ -1722,9 +1737,10 @@ function renderBlock(hookPath, events, tool, platform) {
1722
1737
  const appended = JSON.stringify(`node ${script} ${tool} --appended`);
1723
1738
  const lines = [CODEX_MARKER_BEGIN];
1724
1739
  for (const event of events) {
1725
- lines.push(`[[hooks.${event}]]`, 'matcher = ""', "hooks = [", ` { type = "command", command = ${command}, async = true, timeoutSec = 5 }`);
1740
+ const label2 = JSON.stringify(CODEX_HOOK_LABELS[event] ?? `DeskBuddy\uFF1A${event} \u65F6\u540C\u6B65\u5230\u684C\u9762\u8BBE\u5907`);
1741
+ lines.push(`[[hooks.${event}]]`, 'matcher = ""', "hooks = [", ` { type = "command", command = ${command}, async = true, timeoutSec = 5, statusMessage = ${label2} }`);
1726
1742
  if (event === "UserPromptSubmit") {
1727
- lines.push(` , { type = "command", command = ${appended}, async = false, timeout = ${CODEX_APPENDED_TIMEOUT_S} }`);
1743
+ lines.push(` , { type = "command", command = ${appended}, async = false, timeout = ${CODEX_APPENDED_TIMEOUT_S}, statusMessage = ${JSON.stringify(CODEX_APPENDED_LABEL)} }`);
1728
1744
  }
1729
1745
  lines.push("]", "");
1730
1746
  }
@@ -6338,6 +6354,52 @@ var WsCdpClient = class {
6338
6354
 
6339
6355
  // src/daemon/workbuddyApp/keeper.ts
6340
6356
  import { posix as posix2, win32 as win326 } from "path";
6357
+
6358
+ // src/daemon/userIdle.ts
6359
+ function parseHidIdleMs(out) {
6360
+ const m = /"HIDIdleTime"\s*=\s*(\d+)/.exec(out);
6361
+ return m ? Math.floor(Number(m[1]) / 1e6) : null;
6362
+ }
6363
+ var WIN_PRESENCE_PS = String.raw`Add-Type @"
6364
+ using System; using System.Runtime.InteropServices;
6365
+ public class DbUserIdle {
6366
+ [StructLayout(LayoutKind.Sequential)] public struct LII { public uint cbSize; public uint dwTime; }
6367
+ [DllImport("user32.dll")] public static extern bool GetLastInputInfo(ref LII p);
6368
+ [DllImport("kernel32.dll")] public static extern uint GetTickCount();
6369
+ [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
6370
+ [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr h, out uint pid);
6371
+ }
6372
+ "@
6373
+ $l = New-Object DbUserIdle+LII; $l.cbSize = 8
6374
+ if (-not [DbUserIdle]::GetLastInputInfo([ref]$l)) { exit 1 }
6375
+ $idle = (([uint64][DbUserIdle]::GetTickCount()) - [uint64]$l.dwTime + 4294967296) % 4294967296
6376
+ $fp = [uint32]0; [void][DbUserIdle]::GetWindowThreadProcessId([DbUserIdle]::GetForegroundWindow(), [ref]$fp)
6377
+ $n = ''; try { $n = (Get-Process -Id $fp -ErrorAction Stop).ProcessName } catch {}
6378
+ Write-Output ("{0}|{1}" -f $idle, $n)`;
6379
+ function parseWinPresence(code, stdout2) {
6380
+ const m = /^(\d+)\|(.*)$/m.exec(stdout2.trim());
6381
+ if (code !== 0 || !m) return null;
6382
+ return { idleMs: Number(m[1]), front: m[2].trim() };
6383
+ }
6384
+ async function macIdleMs(exec) {
6385
+ const r = await exec("ioreg", ["-c", "IOHIDSystem", "-d", "4"]);
6386
+ return r.code === 0 ? parseHidIdleMs(r.stdout) : null;
6387
+ }
6388
+ async function winPresence(exec) {
6389
+ const r = await exec("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", WIN_PRESENCE_PS], 15e3);
6390
+ return parseWinPresence(r.code, r.stdout);
6391
+ }
6392
+ async function userIdleMs(exec, platform = process.platform) {
6393
+ try {
6394
+ if (platform === "darwin") return await macIdleMs(exec);
6395
+ if (platform === "win32") return (await winPresence(exec))?.idleMs ?? null;
6396
+ } catch {
6397
+ return null;
6398
+ }
6399
+ return null;
6400
+ }
6401
+
6402
+ // src/daemon/workbuddyApp/keeper.ts
6341
6403
  var DEFAULT_CDP_PORT = 39217;
6342
6404
  var ENV_NAME = "WORKBUDDY_REMOTE_DEBUGGING_PORT";
6343
6405
  var RESTART_GAP_MS = 30 * 60 * 1e3;
@@ -6418,26 +6480,6 @@ var filePersist = {
6418
6480
  }
6419
6481
  }
6420
6482
  };
6421
- function parseHidIdleMs(out) {
6422
- const m = /"HIDIdleTime"\s*=\s*(\d+)/.exec(out);
6423
- return m ? Math.floor(Number(m[1]) / 1e6) : null;
6424
- }
6425
- var WIN_PRESENCE_PS = String.raw`Add-Type @"
6426
- using System; using System.Runtime.InteropServices;
6427
- public class DbUserIdle {
6428
- [StructLayout(LayoutKind.Sequential)] public struct LII { public uint cbSize; public uint dwTime; }
6429
- [DllImport("user32.dll")] public static extern bool GetLastInputInfo(ref LII p);
6430
- [DllImport("kernel32.dll")] public static extern uint GetTickCount();
6431
- [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
6432
- [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr h, out uint pid);
6433
- }
6434
- "@
6435
- $l = New-Object DbUserIdle+LII; $l.cbSize = 8
6436
- if (-not [DbUserIdle]::GetLastInputInfo([ref]$l)) { exit 1 }
6437
- $idle = (([uint64][DbUserIdle]::GetTickCount()) - [uint64]$l.dwTime + 4294967296) % 4294967296
6438
- $fp = [uint32]0; [void][DbUserIdle]::GetWindowThreadProcessId([DbUserIdle]::GetForegroundWindow(), [ref]$fp)
6439
- $n = ''; try { $n = (Get-Process -Id $fp -ErrorAction Stop).ProcessName } catch {}
6440
- Write-Output ("{0}|{1}" -f $idle, $n)`;
6441
6483
  var WAKE_LAUNCH_GAP_MS = 60 * 1e3;
6442
6484
  var APP_PATH_TTL_MS = 5 * 60 * 1e3;
6443
6485
  function defaultWorkbuddyAppPath() {
@@ -6692,7 +6734,7 @@ var CdpKeeper = class {
6692
6734
  if (this.#d.userAway) return await this.#d.userAway();
6693
6735
  const exec = this.#exec();
6694
6736
  if (this.#platform() === "darwin") {
6695
- const idle = parseHidIdleMs((await exec("ioreg", ["-c", "IOHIDSystem", "-d", "4"])).stdout);
6737
+ const idle = await macIdleMs(exec);
6696
6738
  if (idle === null || idle < AWAY_IDLE_MS) return false;
6697
6739
  const asn = (await exec("lsappinfo", ["front"])).stdout.trim();
6698
6740
  if (!asn) return false;
@@ -6700,10 +6742,9 @@ var CdpKeeper = class {
6700
6742
  return !!name.trim() && !/WorkBuddy/i.test(name);
6701
6743
  }
6702
6744
  if (this.#platform() === "win32") {
6703
- const r = await exec("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", WIN_PRESENCE_PS], 15e3);
6704
- const m = /^(\d+)\|(.*)$/m.exec(r.stdout.trim());
6705
- if (r.code !== 0 || !m) return false;
6706
- return Number(m[1]) >= AWAY_IDLE_MS && !/^WorkBuddy$/i.test(m[2].trim());
6745
+ const p = await winPresence(exec);
6746
+ if (!p) return false;
6747
+ return p.idleMs >= AWAY_IDLE_MS && !/^WorkBuddy$/i.test(p.front);
6707
6748
  }
6708
6749
  } catch {
6709
6750
  return false;
@@ -7197,6 +7238,16 @@ var TYPE_TEXT = "text";
7197
7238
  var TYPE_SUMMARY = "summary";
7198
7239
  var MAX_TEXT_LENGTH = 2e3;
7199
7240
  var MAX_ID_LENGTH = 64;
7241
+ function parseFocusOverride(d) {
7242
+ const o = {};
7243
+ const e = typeof d.focusEnabled === "string" ? d.focusEnabled.trim() : d.focusEnabled;
7244
+ if (e === true || e === "true") o.enabled = true;
7245
+ else if (e === false || e === "false") o.enabled = false;
7246
+ const raw = d.focusIdleSec;
7247
+ const sec = typeof raw === "number" ? raw : typeof raw === "string" && /^\d{1,3}$/.test(raw.trim()) ? Number(raw.trim()) : NaN;
7248
+ if (Number.isInteger(sec) && sec >= 0 && sec <= 600) o.idleMs = sec * 1e3;
7249
+ return o.enabled === void 0 && o.idleMs === void 0 ? void 0 : o;
7250
+ }
7200
7251
  function str2(v) {
7201
7252
  return typeof v === "string" ? v : "";
7202
7253
  }
@@ -7233,6 +7284,10 @@ function parseCommand(frame) {
7233
7284
  const dirRef = !sessionId && /^[0-9a-f]{16}$/.test(rawDir) ? rawDir : "";
7234
7285
  const cmd = { instructionId, type, sessionId, tool, text, expireAt: parseMillis(d.expireAt), dirRef };
7235
7286
  if (type === TYPE_SUMMARY) cmd.kind = "summary";
7287
+ else {
7288
+ const focus = parseFocusOverride(d);
7289
+ if (focus) cmd.focus = focus;
7290
+ }
7236
7291
  return cmd;
7237
7292
  }
7238
7293
  var TYPE_APPROVAL = "approval";
@@ -9023,10 +9078,6 @@ function hasMainProc(psOut, brand) {
9023
9078
  }
9024
9079
  return false;
9025
9080
  }
9026
- function parseHidIdleMs2(out) {
9027
- const m = /"HIDIdleTime"\s*=\s*(\d+)/.exec(out);
9028
- return m ? Math.floor(Number(m[1]) / 1e6) : null;
9029
- }
9030
9081
  function parseLsappBundle(out) {
9031
9082
  const m = /"CFBundleIdentifier"\s*=\s*"([^"]+)"/.exec(out);
9032
9083
  return m ? m[1] : null;
@@ -9307,10 +9358,9 @@ var QoderCdpKeeper = class {
9307
9358
  async userAway() {
9308
9359
  if (this.#isWin() && !this.#d.frontBundle && !this.#d.idleMs) {
9309
9360
  try {
9310
- const r = await this.#exec()("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", WIN_PRESENCE_PS], 15e3);
9311
- const m = /^(\d+)\|(.*)$/m.exec(r.stdout.trim());
9312
- if (r.code !== 0 || !m) return false;
9313
- return Number(m[1]) >= USER_IDLE_MS && !!m[2].trim() && !this.#d.brand.win.fgName.test(m[2].trim());
9361
+ const p = await winPresence(this.#exec());
9362
+ if (!p) return false;
9363
+ return p.idleMs >= USER_IDLE_MS && !!p.front && !this.#d.brand.win.fgName.test(p.front);
9314
9364
  } catch {
9315
9365
  return false;
9316
9366
  }
@@ -9333,8 +9383,7 @@ var QoderCdpKeeper = class {
9333
9383
  return parseLsappBundle((await exec("lsappinfo", ["info", "-only", "bundleid", asn])).stdout);
9334
9384
  }
9335
9385
  async #defaultIdle() {
9336
- const r = await this.#exec()("ioreg", ["-c", "IOHIDSystem", "-d", "4"]);
9337
- return r.code === 0 ? parseHidIdleMs2(r.stdout) : null;
9386
+ return macIdleMs(this.#exec());
9338
9387
  }
9339
9388
  /** 主进程(macOS;只认唯一一个;没有 / 认不出 / 多个 → null) */
9340
9389
  async #brandMain() {
@@ -11541,7 +11590,7 @@ var defaultLoginOpenDeps = () => ({
11541
11590
  });
11542
11591
  async function installCodebuddyHooks(log) {
11543
11592
  try {
11544
- const { installTools: installTools2 } = await import("./enable-XTCQ6IFF.js");
11593
+ const { installTools: installTools2 } = await import("./enable-W4R6MJGE.js");
11545
11594
  installTools2(["workbuddy"], () => {
11546
11595
  }, null, { auto: true });
11547
11596
  } catch (e) {
@@ -12055,7 +12104,7 @@ function defaultOfferDeps(log) {
12055
12104
  }),
12056
12105
  openLogin: () => defaultOpenLogin(platform),
12057
12106
  installHooks: async () => {
12058
- const { installTools: installTools2 } = await import("./enable-XTCQ6IFF.js");
12107
+ const { installTools: installTools2 } = await import("./enable-W4R6MJGE.js");
12059
12108
  installTools2(["workbuddy"], (l) => log(`[WorkBuddy \u72EC\u7ACB\u7248] ${l}`), null, { auto: true });
12060
12109
  },
12061
12110
  log: (l) => log(`[WorkBuddy \u72EC\u7ACB\u7248] ${l}`),
@@ -12295,6 +12344,8 @@ async function runEnable(tools, opts = {}) {
12295
12344
  }
12296
12345
 
12297
12346
  export {
12347
+ DEFAULT_FOCUS_IDLE_SECONDS,
12348
+ MAX_FOCUS_IDLE_SECONDS,
12298
12349
  defaultRemoteCwd,
12299
12350
  ensureDefaultRemoteCwd,
12300
12351
  remoteCwdReady,
@@ -12483,6 +12534,7 @@ export {
12483
12534
  registerWorkbuddySession,
12484
12535
  flushPendingWorkbuddy,
12485
12536
  connectCdp,
12537
+ userIdleMs,
12486
12538
  DEFAULT_CDP_PORT,
12487
12539
  defaultExec,
12488
12540
  APP_PORT_HUNG_REASON,