pushary 1.8.1 → 1.8.2

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/bin/pushary-bell-hook.js +6 -5
  3. package/dist/bin/pushary-claude.js +5 -4
  4. package/dist/bin/pushary-clean.js +7 -6
  5. package/dist/bin/pushary-codex-bridge.js +7 -5
  6. package/dist/bin/pushary-codex-hook.js +7 -6
  7. package/dist/bin/pushary-daemon.js +82 -18
  8. package/dist/bin/pushary-disconnect.js +4 -3
  9. package/dist/bin/pushary-doctor.js +10 -7
  10. package/dist/bin/pushary-elicitation-hook.js +6 -5
  11. package/dist/bin/pushary-gemini-bridge.js +7 -4
  12. package/dist/bin/pushary-gemini-hook.js +6 -5
  13. package/dist/bin/pushary-hook.js +9 -8
  14. package/dist/bin/pushary-notification-hook.js +8 -7
  15. package/dist/bin/pushary-opencode-hook.js +6 -5
  16. package/dist/bin/pushary-permission-denied-hook.js +9 -8
  17. package/dist/bin/pushary-permission-hook.js +9 -8
  18. package/dist/bin/pushary-post-hook.js +8 -7
  19. package/dist/bin/pushary-prompt-hook.js +8 -7
  20. package/dist/bin/pushary-session-end-hook.js +8 -7
  21. package/dist/bin/pushary-session-start-hook.js +10 -9
  22. package/dist/bin/pushary-setup.js +22 -78
  23. package/dist/bin/pushary-status.js +4 -2
  24. package/dist/bin/pushary-stop-hook.js +8 -7
  25. package/dist/bin/pushary-stopfailure-hook.js +8 -7
  26. package/dist/bin/pushary-transcript-register.js +5 -4
  27. package/dist/bin/pushary-upgrade.js +10 -8
  28. package/dist/{chunk-JRQRNNGA.js → chunk-644AEX4T.js} +1 -1
  29. package/dist/chunk-6ICPEJY5.js +20 -0
  30. package/dist/{chunk-GH6KGWMC.js → chunk-B3UVRGYP.js} +9 -7
  31. package/dist/{chunk-HBWC3JVZ.js → chunk-BDMC5H5L.js} +1 -1
  32. package/dist/{chunk-6TK4IY3A.js → chunk-DUA5O6X5.js} +1 -1
  33. package/dist/{chunk-FLQPM2GQ.js → chunk-EESPY5DG.js} +1 -1
  34. package/dist/{chunk-TKQ6LZQZ.js → chunk-I3XLHSOC.js} +3 -2
  35. package/dist/{chunk-QB6QYZ6B.js → chunk-MOTNSXC3.js} +2 -2
  36. package/dist/{chunk-HQRCVEI2.js → chunk-NNWQ5VDB.js} +1 -1
  37. package/dist/{chunk-ASWRMBOM.js → chunk-RIVNNBEK.js} +2 -1
  38. package/dist/{chunk-HTEGMMT3.js → chunk-S2UNQQQS.js} +4 -17
  39. package/dist/{chunk-OCVVSRDA.js → chunk-XEGVVU5H.js} +1 -1
  40. package/dist/chunk-XQZEIWAV.js +150 -0
  41. package/dist/{chunk-GBNQXYN4.js → chunk-YNCGXHM4.js} +1 -1
  42. package/dist/{reapply-ICGTBHVE.js → reapply-3UERAKQN.js} +6 -5
  43. package/dist/src/index.js +5 -4
  44. package/package.json +1 -1
  45. package/dist/chunk-VZMIHERK.js +0 -59
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.8.2
4
+
5
+ - **Starting Codex from your phone no longer picks an old, broken Codex over the one you use.** The daemon looked for agents in npm's global folder before the ones your shell runs, so a broken npm copy of Codex won over a working one elsewhere on your PATH, and the session died at once with `spawn ... ENOENT`. On macOS and Linux the daemon and both session bridges now start the agent your shell finds first. Windows keeps npm's `.cmd` launcher first, because the first match on PATH there can be a script Windows cannot run.
6
+ - A Codex install with no native program left in its package, as XProtect left some npm installs, is no longer offered to your phone, and a request for it fails with the path it found and "Reinstall Codex". This is read from the disk; Pushary never runs the agent to check it. Setup, `pushary doctor` and `pushary upgrade` still treat that Codex as installed, as before, so they never stop the background service because of it, and they check the service against the agents it can actually start, so a broken Codex does not make them report that the service failed.
7
+ - The daemon checks every minute which agents it can start, so installing or repairing an agent shows on your phone without restarting the daemon. The daemon log says when that list changes.
8
+ - The daemon log now records how each session started from your phone ended: finished, stopped from Pushary, interrupted, stopped by a signal, or exited with its code, and after how long. Only an exit with an error code is recorded as the daemon's last error, which `pushary daemon status` and `pushary doctor` show. Stopping a session from your phone, or the kill switch halting it, is not an error.
9
+ - The Codex install check that setup also uses no longer judges a standalone Codex by an unrelated npm copy in a folder above it.
10
+
3
11
  ## 1.8.1
4
12
 
5
13
  - The CLI is now also published as `pushary`, from the same build as `@pushary/agent-hooks`, and the commands it prints now show `npx pushary@latest`. `npx @pushary/agent-hooks@latest` keeps working.
@@ -4,20 +4,21 @@ import {
4
4
  } from "../chunk-HMNR7B2F.js";
5
5
  import {
6
6
  readHookInput
7
- } from "../chunk-FLQPM2GQ.js";
8
- import "../chunk-6TK4IY3A.js";
7
+ } from "../chunk-EESPY5DG.js";
8
+ import "../chunk-DUA5O6X5.js";
9
9
  import "../chunk-SGZJ5LYH.js";
10
- import "../chunk-GBNQXYN4.js";
10
+ import "../chunk-YNCGXHM4.js";
11
11
  import "../chunk-DLEKCAQL.js";
12
12
  import "../chunk-MYHG7PX2.js";
13
- import "../chunk-OCVVSRDA.js";
13
+ import "../chunk-XEGVVU5H.js";
14
14
  import "../chunk-EIGJYCOE.js";
15
- import "../chunk-HTEGMMT3.js";
15
+ import "../chunk-S2UNQQQS.js";
16
16
  import "../chunk-HOEB6AKG.js";
17
17
  import "../chunk-URNXU3FO.js";
18
18
  import "../chunk-UMMCHS6P.js";
19
19
  import "../chunk-72WOCX22.js";
20
20
  import "../chunk-XHKBHWLX.js";
21
+ import "../chunk-6ICPEJY5.js";
21
22
  import "../chunk-VFFHQC7W.js";
22
23
  import "../chunk-KB2FTO4O.js";
23
24
  import "../chunk-POFBE6ZY.js";
@@ -18,16 +18,16 @@ import {
18
18
  loadSessionKey,
19
19
  registerTranscript,
20
20
  registeredTranscriptEnabled
21
- } from "../chunk-6TK4IY3A.js";
21
+ } from "../chunk-DUA5O6X5.js";
22
22
  import "../chunk-SGZJ5LYH.js";
23
- import "../chunk-GBNQXYN4.js";
23
+ import "../chunk-YNCGXHM4.js";
24
24
  import "../chunk-DLEKCAQL.js";
25
25
  import "../chunk-MYHG7PX2.js";
26
- import "../chunk-OCVVSRDA.js";
26
+ import "../chunk-XEGVVU5H.js";
27
27
  import {
28
28
  ensureDaemonRunning
29
29
  } from "../chunk-EIGJYCOE.js";
30
- import "../chunk-HTEGMMT3.js";
30
+ import "../chunk-S2UNQQQS.js";
31
31
  import "../chunk-HOEB6AKG.js";
32
32
  import {
33
33
  encryptRecord
@@ -40,6 +40,7 @@ import {
40
40
  needsShell,
41
41
  spawnClaude
42
42
  } from "../chunk-XHKBHWLX.js";
43
+ import "../chunk-6ICPEJY5.js";
43
44
  import {
44
45
  UNNAMED_ACTION,
45
46
  deriveToolTarget,
@@ -4,7 +4,7 @@ import {
4
4
  PUSHARY_SKILL_SOURCE,
5
5
  createGuards,
6
6
  withoutPusharyCursorHooks
7
- } from "../chunk-HBWC3JVZ.js";
7
+ } from "../chunk-BDMC5H5L.js";
8
8
  import {
9
9
  HERMES_PIP_PACKAGE,
10
10
  planFxRemoval,
@@ -36,34 +36,35 @@ import {
36
36
  compatiblePermissionRuleFile,
37
37
  removeCompatibleHooks,
38
38
  removeCompatibleMcpServer
39
- } from "../chunk-QB6QYZ6B.js";
39
+ } from "../chunk-MOTNSXC3.js";
40
40
  import {
41
41
  isClaudeMcpSnapshot,
42
42
  removeClaudeMcpServers,
43
43
  removePusharySettings,
44
44
  removePusharyToolPermissions,
45
45
  restoreClaudeMcpServer
46
- } from "../chunk-JRQRNNGA.js";
46
+ } from "../chunk-644AEX4T.js";
47
47
  import {
48
48
  hookOwnerOf,
49
49
  isHookTakeoverReceipt,
50
50
  restoreHookTakeover,
51
51
  restoreMcpServer
52
- } from "../chunk-GBNQXYN4.js";
52
+ } from "../chunk-YNCGXHM4.js";
53
53
  import "../chunk-DLEKCAQL.js";
54
54
  import {
55
55
  liveBridgeProbe,
56
56
  resolveBridgeStub
57
57
  } from "../chunk-MYHG7PX2.js";
58
- import "../chunk-OCVVSRDA.js";
58
+ import "../chunk-XEGVVU5H.js";
59
59
  import {
60
60
  disableDaemonService
61
61
  } from "../chunk-EIGJYCOE.js";
62
62
  import {
63
63
  removeGeminiSettings
64
- } from "../chunk-HTEGMMT3.js";
64
+ } from "../chunk-S2UNQQQS.js";
65
65
  import "../chunk-HOEB6AKG.js";
66
66
  import "../chunk-XHKBHWLX.js";
67
+ import "../chunk-6ICPEJY5.js";
67
68
  import "../chunk-F6NTWZZC.js";
68
69
  import "../chunk-N6IOSZOE.js";
69
70
  import "../chunk-VFFHQC7W.js";
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import "../chunk-VZMIHERK.js";
3
2
  import {
4
3
  LiveTranscriptRelay,
5
4
  liveSessionSleep,
@@ -7,6 +6,10 @@ import {
7
6
  postLiveSessionUntilAccepted,
8
7
  startLiveSessionHeartbeat
9
8
  } from "../chunk-HVDMGDYV.js";
9
+ import {
10
+ resolveProviderBinary
11
+ } from "../chunk-XQZEIWAV.js";
12
+ import "../chunk-RIVNNBEK.js";
10
13
  import {
11
14
  SESSION_IDLE_TIMEOUT_MS,
12
15
  describeIdleWindow,
@@ -22,6 +25,7 @@ import {
22
25
  import {
23
26
  spawnClaude
24
27
  } from "../chunk-XHKBHWLX.js";
28
+ import "../chunk-6ICPEJY5.js";
25
29
  import {
26
30
  isAskUserResponse,
27
31
  isDecisionStopped,
@@ -44,9 +48,7 @@ import {
44
48
  import "../chunk-7QLSKOSU.js";
45
49
  import "../chunk-KZERVKTD.js";
46
50
  import "../chunk-5Y2DY6X4.js";
47
- import {
48
- resolveBinary
49
- } from "../chunk-UPLV5AJF.js";
51
+ import "../chunk-UPLV5AJF.js";
50
52
  import "../chunk-T7E75EKA.js";
51
53
  import {
52
54
  getApiKey,
@@ -589,7 +591,7 @@ var outcome = await withSpawnProcessOwnership(spawnId, () => runCodexBridge({
589
591
  model: process.env.PUSHARY_BRIDGE_MODEL?.trim() || void 0,
590
592
  resumeThreadId: process.env.PUSHARY_BRIDGE_RESUME_SESSION_ID?.trim() || void 0,
591
593
  appServer: {
592
- command: process.env.PUSHARY_CODEX_COMMAND?.trim() || resolveBinary("codex") || "codex",
594
+ command: process.env.PUSHARY_CODEX_COMMAND?.trim() || resolveProviderBinary("codex") || "codex",
593
595
  args: ["app-server", "--stdio"]
594
596
  },
595
597
  signal: abort.signal,
@@ -15,25 +15,26 @@ import {
15
15
  } from "../chunk-7ITOAMCD.js";
16
16
  import {
17
17
  readHookInput
18
- } from "../chunk-FLQPM2GQ.js";
18
+ } from "../chunk-EESPY5DG.js";
19
19
  import {
20
20
  announceSubscriptionRequired,
21
21
  denyReasonFrom,
22
22
  isDeferAnswer
23
23
  } from "../chunk-5OP5MQI7.js";
24
- import "../chunk-6TK4IY3A.js";
24
+ import "../chunk-DUA5O6X5.js";
25
25
  import "../chunk-SGZJ5LYH.js";
26
- import "../chunk-GBNQXYN4.js";
26
+ import "../chunk-YNCGXHM4.js";
27
27
  import "../chunk-DLEKCAQL.js";
28
28
  import "../chunk-MYHG7PX2.js";
29
- import "../chunk-OCVVSRDA.js";
29
+ import "../chunk-XEGVVU5H.js";
30
30
  import "../chunk-EIGJYCOE.js";
31
- import "../chunk-HTEGMMT3.js";
31
+ import "../chunk-S2UNQQQS.js";
32
32
  import "../chunk-HOEB6AKG.js";
33
33
  import "../chunk-URNXU3FO.js";
34
34
  import "../chunk-UMMCHS6P.js";
35
35
  import "../chunk-72WOCX22.js";
36
36
  import "../chunk-XHKBHWLX.js";
37
+ import "../chunk-6ICPEJY5.js";
37
38
  import {
38
39
  CODEX_AGENT,
39
40
  UNNAMED_ACTION,
@@ -763,7 +764,7 @@ var decidePreToolUse = async (input) => {
763
764
  };
764
765
  var repairCodexHoldsQuietly = async () => {
765
766
  try {
766
- const { repairCodexHolds } = await import("../reapply-ICGTBHVE.js");
767
+ const { repairCodexHolds } = await import("../reapply-3UERAKQN.js");
767
768
  repairCodexHolds();
768
769
  } catch {
769
770
  return;
@@ -1,19 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  inspectConfiguredManagedProviders
4
- } from "../chunk-GH6KGWMC.js";
5
- import "../chunk-ASWRMBOM.js";
4
+ } from "../chunk-B3UVRGYP.js";
6
5
  import "../chunk-W2LJ4O3A.js";
7
6
  import {
8
7
  HEARTBEAT_INTERVAL_MS,
9
8
  sendHeartbeat
10
- } from "../chunk-TKQ6LZQZ.js";
11
- import "../chunk-JRQRNNGA.js";
9
+ } from "../chunk-I3XLHSOC.js";
10
+ import "../chunk-644AEX4T.js";
12
11
  import {
12
+ codexBinaryIsBroken,
13
+ detectLaunchableProviderCapabilities,
13
14
  detectProviderLiveCapabilities,
14
15
  hasSpawnProvider,
15
- resolveControlPolicy
16
- } from "../chunk-VZMIHERK.js";
16
+ launchAdvertisement,
17
+ launchableProviders,
18
+ resolveControlPolicy,
19
+ resolveProviderBinary
20
+ } from "../chunk-XQZEIWAV.js";
21
+ import "../chunk-RIVNNBEK.js";
17
22
  import {
18
23
  SESSION_REAP_SILENCE_MS,
19
24
  describeIdleWindow,
@@ -24,12 +29,12 @@ import {
24
29
  } from "../chunk-ZJYJAD52.js";
25
30
  import {
26
31
  startRegisteredTranscripts
27
- } from "../chunk-6TK4IY3A.js";
32
+ } from "../chunk-DUA5O6X5.js";
28
33
  import "../chunk-SGZJ5LYH.js";
29
- import "../chunk-GBNQXYN4.js";
34
+ import "../chunk-YNCGXHM4.js";
30
35
  import "../chunk-DLEKCAQL.js";
31
36
  import "../chunk-MYHG7PX2.js";
32
- import "../chunk-OCVVSRDA.js";
37
+ import "../chunk-XEGVVU5H.js";
33
38
  import {
34
39
  DAEMON_LEASE_RENEW_INTERVAL_MS,
35
40
  acquireDaemonLease,
@@ -47,7 +52,7 @@ import {
47
52
  stopDaemonRunning,
48
53
  writeDaemonNeedsLogin
49
54
  } from "../chunk-EIGJYCOE.js";
50
- import "../chunk-HTEGMMT3.js";
55
+ import "../chunk-S2UNQQQS.js";
51
56
  import "../chunk-HOEB6AKG.js";
52
57
  import "../chunk-URNXU3FO.js";
53
58
  import "../chunk-UMMCHS6P.js";
@@ -55,6 +60,7 @@ import "../chunk-72WOCX22.js";
55
60
  import {
56
61
  spawnClaude
57
62
  } from "../chunk-XHKBHWLX.js";
63
+ import "../chunk-6ICPEJY5.js";
58
64
  import "../chunk-VFFHQC7W.js";
59
65
  import {
60
66
  writeHuman
@@ -231,6 +237,37 @@ var providerLaunchError = (requestedAgent, binaries, configuredProviders) => {
231
237
  if (binaries[agent]) return null;
232
238
  return agent === "claude" ? "Claude Code is not installed on this machine" : `${agent === "codex" ? "Codex" : "Gemini"} CLI is not installed on this machine`;
233
239
  };
240
+ var brokenCodexMessage = (binary) => `Codex at ${binary} cannot start: the program it launches is missing. Reinstall Codex on this machine, then try again.`;
241
+ var plural = (count, unit) => `${count} ${unit}${count === 1 ? "" : "s"}`;
242
+ var describeRunTime = (ms) => {
243
+ const seconds = Math.max(0, Math.floor(ms / 1e3));
244
+ if (seconds < 60) return `${seconds}s`;
245
+ const minutes = Math.floor(seconds / 60);
246
+ return minutes < 60 ? plural(minutes, "minute") : plural(Math.floor(minutes / 60), "hour");
247
+ };
248
+ var INTERRUPTED_EXIT_CODES = /* @__PURE__ */ new Set([130, 143]);
249
+ var exitedInterrupted = (code) => code !== null && INTERRUPTED_EXIT_CODES.has(code);
250
+ var describeSessionExit = (agent, exit) => {
251
+ const ranFor = describeRunTime(exit.ranForMs);
252
+ if (exit.stoppedByPushary) return `${agent} session was stopped from Pushary after ${ranFor}`;
253
+ if (exit.signal) return `${agent} session was stopped by ${exit.signal} after ${ranFor}`;
254
+ if (exitedInterrupted(exit.code)) return `${agent} session was interrupted (exit code ${exit.code}) after ${ranFor}`;
255
+ return exit.code === 0 ? `${agent} session finished after ${ranFor}` : `${agent} session exited with code ${exit.code} after ${ranFor}`;
256
+ };
257
+ var sessionExitFailed = (exit) => !exit.stoppedByPushary && exit.signal === null && exit.code !== 0 && !exitedInterrupted(exit.code);
258
+ var reportSessionExit = (child, report) => {
259
+ const launchedAt = report.now();
260
+ child.once("exit", (code, signal) => {
261
+ const exit = { code, signal, ranForMs: report.now() - launchedAt, stoppedByPushary: report.stoppedByPushary() };
262
+ const line = `spawn ${report.spawnId}: ${describeSessionExit(report.agent, exit)}`;
263
+ report.log(line);
264
+ if (sessionExitFailed(exit)) report.recordError(line);
265
+ });
266
+ };
267
+ var describeLaunchableProviders = (capabilities) => {
268
+ const providers = launchableProviders(capabilities);
269
+ return providers.length > 0 ? `the phone can start: ${providers.join(", ")}` : "the phone cannot start any agent on this machine";
270
+ };
234
271
  var resolveSpawnDirectory = (requested, options = {}) => {
235
272
  const fallbackDir = options.fallbackDir ?? process.cwd();
236
273
  const value = requested?.trim();
@@ -323,7 +360,7 @@ var runSpawnDaemon = async () => {
323
360
  const baseUrl = getBaseUrl();
324
361
  const pusharyBin = resolveBinary("pushary") ?? "pushary";
325
362
  const configuredProviders = inspectConfiguredManagedProviders();
326
- const providerCapabilities = detectProviderLiveCapabilities(configuredProviders);
363
+ let providerCapabilities = detectLaunchableProviderCapabilities(configuredProviders);
327
364
  const siblingEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary.js") : "";
328
365
  const codexBridgeEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary-codex-bridge.js") : "pushary-codex-bridge";
329
366
  const geminiBridgeEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary-gemini-bridge.js") : "pushary-gemini-bridge";
@@ -362,6 +399,7 @@ var runSpawnDaemon = async () => {
362
399
  let lastControlProbeAt = 0;
363
400
  const spawnTimestamps = [];
364
401
  const launchedProcesses = /* @__PURE__ */ new Map();
402
+ const stoppedByPushary = /* @__PURE__ */ new Set();
365
403
  const completedStops = /* @__PURE__ */ new Map();
366
404
  let timer;
367
405
  let inflight;
@@ -381,13 +419,16 @@ var runSpawnDaemon = async () => {
381
419
  if (!directory.ok) return Promise.reject(new Error(directory.message));
382
420
  const agent = normalizeLaunchAgent(req.agent);
383
421
  if (!agent) return Promise.reject(new Error(`Unsupported agent provider: ${req.agent}`));
384
- const providerBin = resolveBinary(agent);
422
+ const providerBin = resolveProviderBinary(agent);
385
423
  const unavailable = providerLaunchError(req.agent, {
386
424
  claude: agent === "claude" ? providerBin ?? null : null,
387
425
  codex: agent === "codex" ? providerBin ?? null : null,
388
426
  gemini: agent === "gemini" ? providerBin ?? null : null
389
427
  }, configuredProviders);
390
428
  if (unavailable) return Promise.reject(new Error(unavailable));
429
+ if (agent === "codex" && providerBin && codexBinaryIsBroken(providerBin)) {
430
+ return Promise.reject(new Error(brokenCodexMessage(providerBin)));
431
+ }
391
432
  spawnTimestamps.push(Date.now());
392
433
  const cwd = directory.cwd;
393
434
  const env = {
@@ -431,9 +472,20 @@ var runSpawnDaemon = async () => {
431
472
  });
432
473
  child.once("spawn", () => {
433
474
  started = true;
475
+ reportSessionExit(child, {
476
+ spawnId: req.id,
477
+ agent: plan.agent,
478
+ now: Date.now,
479
+ stoppedByPushary: () => typeof child.pid === "number" && stoppedByPushary.has(child.pid),
480
+ log,
481
+ recordError: (line) => daemonLease.recordError(line)
482
+ });
434
483
  if (typeof child.pid === "number") {
435
484
  launchedProcesses.set(child.pid, req.id);
436
- child.once("close", () => launchedProcesses.delete(child.pid));
485
+ child.once("close", () => {
486
+ launchedProcesses.delete(child.pid);
487
+ stoppedByPushary.delete(child.pid);
488
+ });
437
489
  }
438
490
  child.unref();
439
491
  log(`spawn ${req.id}: launched a phone-requested ${plan.agent} session in ${basename(cwd)} (pid ${child.pid ?? "unknown"})`);
@@ -448,7 +500,10 @@ var runSpawnDaemon = async () => {
448
500
  execFileSync("taskkill", windowsTaskkillArgs(pid), { stdio: "ignore" });
449
501
  } : process.kill.bind(process);
450
502
  const stopDeps = {
451
- kill,
503
+ kill: (pid, signal) => {
504
+ if (launchedProcesses.has(pid)) stoppedByPushary.add(pid);
505
+ kill(pid, signal);
506
+ },
452
507
  ownsProcess: (request) => {
453
508
  const launched = request.spawnId ? launchedProcesses.get(request.pid) === request.spawnId : !request.id && launchedProcesses.has(request.pid);
454
509
  return launched || ownsLiveProcess(request);
@@ -674,6 +729,13 @@ var runSpawnDaemon = async () => {
674
729
  log(`daemon could not release its local lease: ${errMsg(err)}`);
675
730
  }
676
731
  };
732
+ const refreshProviderCapabilities = () => {
733
+ const detected = detectLaunchableProviderCapabilities(configuredProviders);
734
+ const before = describeLaunchableProviders(providerCapabilities);
735
+ const after = describeLaunchableProviders(detected);
736
+ providerCapabilities = detected;
737
+ if (after !== before) log(`agents changed: ${after}`);
738
+ };
677
739
  const beat = async () => {
678
740
  if (stopped) return;
679
741
  if (!daemonLease.isOwner()) {
@@ -683,10 +745,9 @@ var runSpawnDaemon = async () => {
683
745
  const result = await sendHeartbeat(apiKey, {
684
746
  repoKey: basename(process.cwd()),
685
747
  capabilities: [
686
- ...hasSpawnProvider(providerCapabilities) ? ["spawn"] : [],
748
+ ...launchAdvertisement(providerCapabilities),
687
749
  STOP_CAPABILITY,
688
- STOP_ACK_CAPABILITY,
689
- ...providerCapabilities
750
+ STOP_ACK_CAPABILITY
690
751
  ]
691
752
  });
692
753
  if (result.kind === "ok") {
@@ -701,7 +762,10 @@ var runSpawnDaemon = async () => {
701
762
  }
702
763
  };
703
764
  void beat();
704
- heartbeat = setInterval(() => void beat(), HEARTBEAT_INTERVAL_MS);
765
+ heartbeat = setInterval(() => {
766
+ refreshProviderCapabilities();
767
+ void beat();
768
+ }, HEARTBEAT_INTERVAL_MS);
705
769
  leaseRenewal = setInterval(() => daemonLease.renew(), DAEMON_LEASE_RENEW_INTERVAL_MS);
706
770
  versionWatch = setInterval(() => {
707
771
  if (daemonLease.shouldYield()) finish();
@@ -15,17 +15,18 @@ import {
15
15
  compatiblePermissionRuleFile,
16
16
  removeCompatibleHooks,
17
17
  removeCompatibleMcpServer
18
- } from "../chunk-QB6QYZ6B.js";
18
+ } from "../chunk-MOTNSXC3.js";
19
19
  import {
20
20
  isClaudeMcpSnapshot,
21
21
  removeClaudeMcpServers,
22
22
  removePusharySettings,
23
23
  removePusharyToolPermissions,
24
24
  restoreClaudeMcpServer
25
- } from "../chunk-JRQRNNGA.js";
25
+ } from "../chunk-644AEX4T.js";
26
26
  import {
27
27
  removeGeminiSettings
28
- } from "../chunk-HTEGMMT3.js";
28
+ } from "../chunk-S2UNQQQS.js";
29
+ import "../chunk-6ICPEJY5.js";
29
30
  import "../chunk-F6NTWZZC.js";
30
31
  import "../chunk-N6IOSZOE.js";
31
32
  import "../chunk-VFFHQC7W.js";
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  readMachineReadiness,
15
15
  readManagedControlEvidence
16
- } from "../chunk-TKQ6LZQZ.js";
16
+ } from "../chunk-I3XLHSOC.js";
17
17
  import {
18
18
  FX_PROFILE_REFUSALS,
19
19
  FX_PUSHARY_TOOLS_RULE,
@@ -47,13 +47,15 @@ import {
47
47
  compatibleMcpFile,
48
48
  hasCompatibleHooks,
49
49
  missingCompatibleHookEvents
50
- } from "../chunk-QB6QYZ6B.js";
51
- import "../chunk-JRQRNNGA.js";
50
+ } from "../chunk-MOTNSXC3.js";
51
+ import "../chunk-644AEX4T.js";
52
52
  import {
53
53
  detectProviderLiveCapabilities,
54
+ expectedLaunchCapabilities,
54
55
  hasSpawnProvider,
55
56
  resolveControlPolicy
56
- } from "../chunk-VZMIHERK.js";
57
+ } from "../chunk-XQZEIWAV.js";
58
+ import "../chunk-RIVNNBEK.js";
57
59
  import {
58
60
  AUTO_UPDATE_DISABLE_ENV,
59
61
  autoUpdateOffReason,
@@ -87,7 +89,7 @@ import {
87
89
  geminiWired,
88
90
  holdsLong,
89
91
  pusharyHookExecutable
90
- } from "../chunk-OCVVSRDA.js";
92
+ } from "../chunk-XEGVVU5H.js";
91
93
  import {
92
94
  daemonHasRemoteProof,
93
95
  daemonServiceManagerAvailable,
@@ -101,8 +103,9 @@ import {
101
103
  GEMINI_HOOK_BINARY,
102
104
  hasGeminiHooks,
103
105
  missingGeminiHookEvents
104
- } from "../chunk-HTEGMMT3.js";
106
+ } from "../chunk-S2UNQQQS.js";
105
107
  import "../chunk-XHKBHWLX.js";
108
+ import "../chunk-6ICPEJY5.js";
106
109
  import "../chunk-F6NTWZZC.js";
107
110
  import "../chunk-N6IOSZOE.js";
108
111
  import "../chunk-VFFHQC7W.js";
@@ -982,7 +985,7 @@ var main = async () => {
982
985
  }
983
986
  let serverProof = null;
984
987
  if (controlPolicy === "enabled" && apiKey && daemon.machineId) {
985
- serverProof = await readMachineReadiness(apiKey, ["spawn", ...controlCapabilities], {
988
+ serverProof = await readMachineReadiness(apiKey, expectedLaunchCapabilities(configuredManagedProviders), {
986
989
  machineId: daemon.machineId
987
990
  });
988
991
  if (serverProof.kind === "unsupported") {
@@ -1,24 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  readHookInput
4
- } from "../chunk-FLQPM2GQ.js";
4
+ } from "../chunk-EESPY5DG.js";
5
5
  import {
6
6
  announceSubscriptionRequired,
7
7
  isDeferAnswer
8
8
  } from "../chunk-5OP5MQI7.js";
9
- import "../chunk-6TK4IY3A.js";
9
+ import "../chunk-DUA5O6X5.js";
10
10
  import "../chunk-SGZJ5LYH.js";
11
- import "../chunk-GBNQXYN4.js";
11
+ import "../chunk-YNCGXHM4.js";
12
12
  import "../chunk-DLEKCAQL.js";
13
13
  import "../chunk-MYHG7PX2.js";
14
- import "../chunk-OCVVSRDA.js";
14
+ import "../chunk-XEGVVU5H.js";
15
15
  import "../chunk-EIGJYCOE.js";
16
- import "../chunk-HTEGMMT3.js";
16
+ import "../chunk-S2UNQQQS.js";
17
17
  import "../chunk-HOEB6AKG.js";
18
18
  import "../chunk-URNXU3FO.js";
19
19
  import "../chunk-UMMCHS6P.js";
20
20
  import "../chunk-72WOCX22.js";
21
21
  import "../chunk-XHKBHWLX.js";
22
+ import "../chunk-6ICPEJY5.js";
22
23
  import "../chunk-N6IOSZOE.js";
23
24
  import "../chunk-VFFHQC7W.js";
24
25
  import {
@@ -6,6 +6,10 @@ import {
6
6
  postLiveSessionUntilAccepted,
7
7
  startLiveSessionHeartbeat
8
8
  } from "../chunk-HVDMGDYV.js";
9
+ import {
10
+ resolveProviderBinary
11
+ } from "../chunk-XQZEIWAV.js";
12
+ import "../chunk-RIVNNBEK.js";
9
13
  import {
10
14
  SESSION_IDLE_TIMEOUT_MS,
11
15
  describeIdleWindow,
@@ -21,14 +25,13 @@ import {
21
25
  import {
22
26
  spawnClaude
23
27
  } from "../chunk-XHKBHWLX.js";
28
+ import "../chunk-6ICPEJY5.js";
24
29
  import "../chunk-TJMAXQ5Q.js";
25
30
  import {
26
31
  getMachineId
27
32
  } from "../chunk-4A3UQERT.js";
28
33
  import "../chunk-5Y2DY6X4.js";
29
- import {
30
- resolveBinary
31
- } from "../chunk-UPLV5AJF.js";
34
+ import "../chunk-UPLV5AJF.js";
32
35
  import "../chunk-T7E75EKA.js";
33
36
  import {
34
37
  getApiKey,
@@ -331,7 +334,7 @@ var outcome = await withSpawnProcessOwnership(spawnId, () => runGeminiBridge({
331
334
  prompt: process.env.PUSHARY_BRIDGE_PROMPT?.trim() || void 0,
332
335
  model: process.env.PUSHARY_BRIDGE_MODEL?.trim() || void 0,
333
336
  resumeSessionId: process.env.PUSHARY_BRIDGE_RESUME_SESSION_ID?.trim() || void 0,
334
- command: { command: process.env.PUSHARY_GEMINI_COMMAND?.trim() || resolveBinary("gemini") || "gemini" },
337
+ command: { command: process.env.PUSHARY_GEMINI_COMMAND?.trim() || resolveProviderBinary("gemini") || "gemini" },
335
338
  signal: abort.signal,
336
339
  transcripts: transcriptsEnabled()
337
340
  }));
@@ -8,25 +8,26 @@ import {
8
8
  } from "../chunk-7ITOAMCD.js";
9
9
  import {
10
10
  readHookInput
11
- } from "../chunk-FLQPM2GQ.js";
11
+ } from "../chunk-EESPY5DG.js";
12
12
  import {
13
13
  announceSubscriptionRequired,
14
14
  denyReasonFrom,
15
15
  isDeferAnswer
16
16
  } from "../chunk-5OP5MQI7.js";
17
- import "../chunk-6TK4IY3A.js";
17
+ import "../chunk-DUA5O6X5.js";
18
18
  import "../chunk-SGZJ5LYH.js";
19
- import "../chunk-GBNQXYN4.js";
19
+ import "../chunk-YNCGXHM4.js";
20
20
  import "../chunk-DLEKCAQL.js";
21
21
  import "../chunk-MYHG7PX2.js";
22
- import "../chunk-OCVVSRDA.js";
22
+ import "../chunk-XEGVVU5H.js";
23
23
  import "../chunk-EIGJYCOE.js";
24
- import "../chunk-HTEGMMT3.js";
24
+ import "../chunk-S2UNQQQS.js";
25
25
  import "../chunk-HOEB6AKG.js";
26
26
  import "../chunk-URNXU3FO.js";
27
27
  import "../chunk-UMMCHS6P.js";
28
28
  import "../chunk-72WOCX22.js";
29
29
  import "../chunk-XHKBHWLX.js";
30
+ import "../chunk-6ICPEJY5.js";
30
31
  import {
31
32
  UNNAMED_ACTION,
32
33
  deriveActionBody,
@@ -1,32 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePreToolUse
4
- } from "../chunk-HQRCVEI2.js";
4
+ } from "../chunk-NNWQ5VDB.js";
5
5
  import {
6
6
  activeHookSource,
7
7
  normalizeToolCall,
8
8
  profileFromArgv
9
- } from "../chunk-QB6QYZ6B.js";
10
- import "../chunk-JRQRNNGA.js";
9
+ } from "../chunk-MOTNSXC3.js";
10
+ import "../chunk-644AEX4T.js";
11
11
  import "../chunk-5DGNEUXK.js";
12
12
  import "../chunk-7ITOAMCD.js";
13
13
  import {
14
14
  readToolHookInput
15
- } from "../chunk-FLQPM2GQ.js";
15
+ } from "../chunk-EESPY5DG.js";
16
16
  import "../chunk-5OP5MQI7.js";
17
- import "../chunk-6TK4IY3A.js";
17
+ import "../chunk-DUA5O6X5.js";
18
18
  import "../chunk-SGZJ5LYH.js";
19
- import "../chunk-GBNQXYN4.js";
19
+ import "../chunk-YNCGXHM4.js";
20
20
  import "../chunk-DLEKCAQL.js";
21
21
  import "../chunk-MYHG7PX2.js";
22
- import "../chunk-OCVVSRDA.js";
22
+ import "../chunk-XEGVVU5H.js";
23
23
  import "../chunk-EIGJYCOE.js";
24
- import "../chunk-HTEGMMT3.js";
24
+ import "../chunk-S2UNQQQS.js";
25
25
  import "../chunk-HOEB6AKG.js";
26
26
  import "../chunk-URNXU3FO.js";
27
27
  import "../chunk-UMMCHS6P.js";
28
28
  import "../chunk-72WOCX22.js";
29
29
  import "../chunk-XHKBHWLX.js";
30
+ import "../chunk-6ICPEJY5.js";
30
31
  import {
31
32
  canonicalGateInputs
32
33
  } from "../chunk-F6NTWZZC.js";