@pushary/agent-hooks 1.9.75 → 1.9.76

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 (126) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/{api-L3BIISGS.js → api-YDCHRRA4.js} +10 -10
  3. package/dist/bin/pushary-bell-hook.js +26 -25
  4. package/dist/bin/pushary-bell.js +10 -10
  5. package/dist/bin/pushary-claude.js +27 -26
  6. package/dist/bin/pushary-clean.js +33 -33
  7. package/dist/bin/pushary-codex-bridge.js +21 -21
  8. package/dist/bin/pushary-codex-hook.js +31 -30
  9. package/dist/bin/pushary-codex-session.js +8 -8
  10. package/dist/bin/pushary-codex.js +13 -13
  11. package/dist/bin/pushary-connect.js +26 -26
  12. package/dist/bin/pushary-cowork.js +5 -5
  13. package/dist/bin/pushary-daemon.js +39 -38
  14. package/dist/bin/pushary-disconnect.js +25 -25
  15. package/dist/bin/pushary-display-hook.js +17 -16
  16. package/dist/bin/pushary-doctor.js +41 -41
  17. package/dist/bin/pushary-elicitation-hook.js +26 -25
  18. package/dist/bin/pushary-gemini-bridge.js +15 -15
  19. package/dist/bin/pushary-gemini-hook.js +28 -27
  20. package/dist/bin/pushary-hook.js +30 -29
  21. package/dist/bin/pushary-login.js +20 -20
  22. package/dist/bin/pushary-logout.js +24 -24
  23. package/dist/bin/pushary-mcp.js +11 -11
  24. package/dist/bin/pushary-mode.js +15 -15
  25. package/dist/bin/pushary-notification-hook.js +25 -24
  26. package/dist/bin/pushary-opencode-hook.js +27 -26
  27. package/dist/bin/pushary-permission-denied-hook.js +30 -29
  28. package/dist/bin/pushary-permission-hook.js +30 -29
  29. package/dist/bin/pushary-post-hook.js +25 -24
  30. package/dist/bin/pushary-prompt-hook.js +25 -24
  31. package/dist/bin/pushary-session-end-hook.js +27 -26
  32. package/dist/bin/pushary-session-start-hook.js +35 -34
  33. package/dist/bin/pushary-setup.js +50 -267
  34. package/dist/bin/pushary-stats.js +5 -5
  35. package/dist/bin/pushary-status.js +31 -31
  36. package/dist/bin/pushary-stop-hook.js +25 -24
  37. package/dist/bin/pushary-stopfailure-hook.js +25 -24
  38. package/dist/bin/pushary-suggestions.js +15 -15
  39. package/dist/bin/pushary-transcript-register.js +17 -16
  40. package/dist/bin/pushary-transcripts.js +19 -19
  41. package/dist/bin/pushary-upgrade.js +39 -39
  42. package/dist/bin/pushary-wait.js +15 -15
  43. package/dist/bin/pushary.js +7 -7
  44. package/dist/{chunk-CI6MDBQB.js → chunk-2BK2EQOB.js} +7 -7
  45. package/dist/{chunk-JCZWWBBA.js → chunk-2QFYEB3P.js} +5 -5
  46. package/dist/{chunk-3SAF4QXU.js → chunk-3YU6NIIL.js} +4 -4
  47. package/dist/{chunk-L2FQBHIR.js → chunk-47TIRGS5.js} +2 -2
  48. package/dist/{chunk-I73UQU7K.js → chunk-4LX5QUFV.js} +1 -1
  49. package/dist/{chunk-LRYZXY4V.js → chunk-57MQNSM5.js} +1 -1
  50. package/dist/{chunk-4DH54LS7.js → chunk-5FV472Q2.js} +1 -1
  51. package/dist/{chunk-HRRGIVIL.js → chunk-5KPMDLXB.js} +3 -3
  52. package/dist/{chunk-RPKFXNOJ.js → chunk-5M5F4IWR.js} +2 -2
  53. package/dist/{chunk-DARPCQPY.js → chunk-5NW7VM35.js} +2 -2
  54. package/dist/{chunk-KDUWFGY2.js → chunk-74ONBRPF.js} +4 -4
  55. package/dist/{chunk-2J4IVUEA.js → chunk-7KYQ24FI.js} +2 -2
  56. package/dist/{chunk-LIDUPDEY.js → chunk-7LLC4R66.js} +4 -4
  57. package/dist/{chunk-ZX3KEXO3.js → chunk-7SFP6Y5U.js} +45 -24
  58. package/dist/{chunk-EOGVWCLF.js → chunk-7ZOWQBHQ.js} +5 -5
  59. package/dist/{chunk-HXV2SY2V.js → chunk-B2PFCS72.js} +2 -2
  60. package/dist/{chunk-BGEUAJYL.js → chunk-BUR2LYQI.js} +2 -2
  61. package/dist/{chunk-UU3CDLIX.js → chunk-C2AR7QXU.js} +2 -2
  62. package/dist/{chunk-UBANQ4EZ.js → chunk-CHIOUBPB.js} +13 -13
  63. package/dist/{chunk-M7BXAWUC.js → chunk-CMNB4IZO.js} +3 -3
  64. package/dist/{chunk-BRG4XS2H.js → chunk-CUD6SYDG.js} +1 -1
  65. package/dist/{chunk-DCHZ5JOI.js → chunk-DB3NOEDW.js} +6 -6
  66. package/dist/{chunk-P4TWTQ6V.js → chunk-DZF2M3LM.js} +6 -6
  67. package/dist/{chunk-PV5XEBFI.js → chunk-E2VJ7B7D.js} +6 -6
  68. package/dist/{chunk-SIJHPGUW.js → chunk-E7U4YM4A.js} +3 -3
  69. package/dist/{chunk-PGLNE556.js → chunk-F7R7M5MG.js} +1 -1
  70. package/dist/{chunk-VGHWK5Z2.js → chunk-FAGQAR6I.js} +3 -3
  71. package/dist/{chunk-GAAN3Y7V.js → chunk-GII565PB.js} +1 -1
  72. package/dist/{chunk-6BFLDHPM.js → chunk-GJVV2EUC.js} +3 -3
  73. package/dist/{chunk-EH5OLIP2.js → chunk-IRLHN5UP.js} +236 -20
  74. package/dist/{chunk-7FNSQMQ2.js → chunk-IRN6JLSM.js} +4 -4
  75. package/dist/{chunk-SONZCJY5.js → chunk-ITLWEGLE.js} +11 -4
  76. package/dist/{chunk-32JJ5KV3.js → chunk-JNV5LOZH.js} +4 -4
  77. package/dist/{chunk-EM2RSWDA.js → chunk-JZ5KV2FK.js} +5 -5
  78. package/dist/{chunk-TPYZFYQ5.js → chunk-KGWLDNNT.js} +4 -4
  79. package/dist/{chunk-SOHJ37NA.js → chunk-KWGOKO4E.js} +3 -3
  80. package/dist/{chunk-DOG3BQFO.js → chunk-M5VJ3HXB.js} +6 -6
  81. package/dist/{chunk-53D6FFVE.js → chunk-M7JFGDGP.js} +1 -1
  82. package/dist/{chunk-4GWKKUQ5.js → chunk-MAWC4PJV.js} +5 -5
  83. package/dist/chunk-MHUKYYYR.js +239 -0
  84. package/dist/{chunk-SFJOGZQV.js → chunk-MMVIKXCP.js} +3 -3
  85. package/dist/{chunk-EVBG5YUO.js → chunk-MTRZQR2R.js} +3 -3
  86. package/dist/{chunk-QDUDXJAF.js → chunk-NFUV25JZ.js} +3 -3
  87. package/dist/{chunk-UEJTWQVF.js → chunk-NJTAUEW6.js} +1 -1
  88. package/dist/{chunk-WL3V2UV4.js → chunk-NQA56AMZ.js} +6 -6
  89. package/dist/{chunk-JFVLMWKY.js → chunk-NVLKH5FS.js} +9 -9
  90. package/dist/{chunk-NCTABQMC.js → chunk-PPD64MZW.js} +1 -1
  91. package/dist/{chunk-E5XYFIYL.js → chunk-QUGP76DQ.js} +6 -6
  92. package/dist/{chunk-UIS332AZ.js → chunk-R3HXGHRQ.js} +1 -1
  93. package/dist/{chunk-DX65IDBI.js → chunk-S7C5NY4R.js} +1 -1
  94. package/dist/{chunk-7O54GE5C.js → chunk-SWRNJ3BP.js} +3 -3
  95. package/dist/{chunk-AUDYAVNM.js → chunk-T2EJ3H6Y.js} +3 -3
  96. package/dist/{chunk-Z7ORL6SC.js → chunk-TFYFQM5C.js} +2 -2
  97. package/dist/{chunk-JOMG6J64.js → chunk-UEY4SHY2.js} +1 -1
  98. package/dist/{chunk-R7V6BPEV.js → chunk-UMBVIFP5.js} +1 -1
  99. package/dist/{chunk-2DB7TBA7.js → chunk-USMUW3LI.js} +2 -2
  100. package/dist/{chunk-SHW6KK2K.js → chunk-USZJJWZL.js} +2 -2
  101. package/dist/{chunk-4T25BBBO.js → chunk-VELPOV2F.js} +4 -4
  102. package/dist/{chunk-D4X4BQVQ.js → chunk-VZSSL6US.js} +10 -10
  103. package/dist/{chunk-MD4UJICD.js → chunk-W5AUTVVL.js} +5 -5
  104. package/dist/{chunk-XO7LP3JC.js → chunk-WK2L3XVQ.js} +1 -1
  105. package/dist/{chunk-3PPL64AG.js → chunk-WLHHDDVA.js} +9 -4
  106. package/dist/{chunk-5EQOUZYE.js → chunk-WRCM4XGY.js} +2 -2
  107. package/dist/{chunk-CLHRSK5L.js → chunk-XJ5DYPTM.js} +4 -4
  108. package/dist/{chunk-FEC3JUIH.js → chunk-XLGD5LDG.js} +3 -3
  109. package/dist/{chunk-SNUHX5GQ.js → chunk-Y2CYSVWU.js} +6 -6
  110. package/dist/{chunk-QRS7FQHE.js → chunk-Y4OBAK4I.js} +4 -0
  111. package/dist/{chunk-I6TIZMM3.js → chunk-YDPGBBV7.js} +5 -5
  112. package/dist/{chunk-T6RWREWU.js → chunk-YLB4AGZJ.js} +1 -1
  113. package/dist/{chunk-DUOBFECC.js → chunk-ZY25SNFQ.js} +1 -1
  114. package/dist/{codex-app-cards-switch-CN3G7GZW.js → codex-app-cards-switch-3OUTABVU.js} +11 -11
  115. package/dist/{codex-desktop-launch-GFZXCDSL.js → codex-desktop-launch-JH3E2CIA.js} +1 -1
  116. package/dist/{codex-session-launch-4F2UGQYE.js → codex-session-launch-GR363OQN.js} +18 -18
  117. package/dist/{config-BLHDUDCS.js → config-R43UFHX7.js} +3 -3
  118. package/dist/{global-upgrade-IZEC22BQ.js → global-upgrade-73GP4MZM.js} +10 -10
  119. package/dist/{identity-3HGTEP5Q.js → identity-CA7CZGDL.js} +4 -4
  120. package/dist/{live-capabilities-AZK664T7.js → live-capabilities-RCGMQIIZ.js} +5 -5
  121. package/dist/{paths-ROMZUSEX.js → paths-H7VNNB46.js} +3 -3
  122. package/dist/{reapply-IJYRR4YK.js → reapply-3UIA3CUO.js} +27 -27
  123. package/dist/src/index.js +29 -28
  124. package/dist/{upgrade-lock-FGEZPX56.js → upgrade-lock-ZTLX5PDF.js} +4 -4
  125. package/dist/{usage-HCURE44F.js → usage-C53NVWC2.js} +3 -3
  126. package/package.json +1 -1
@@ -3,10 +3,10 @@ import {
3
3
  forkFinishWithUpgradeLock,
4
4
  installWithUpgradeLock,
5
5
  releaseAutoUpdateLock
6
- } from "./chunk-Z7ORL6SC.js";
6
+ } from "./chunk-TFYFQM5C.js";
7
7
  import {
8
8
  phoneStartIsRequired
9
- } from "./chunk-KDUWFGY2.js";
9
+ } from "./chunk-74ONBRPF.js";
10
10
  import {
11
11
  describeAutoUpdateCheck,
12
12
  globalInstallLocation,
@@ -18,25 +18,25 @@ import {
18
18
  readAutoUpdateState,
19
19
  updateAutoUpdateState,
20
20
  upgradeEntryFor
21
- } from "./chunk-M7BXAWUC.js";
21
+ } from "./chunk-CMNB4IZO.js";
22
22
  import {
23
23
  autoUpdateLock,
24
24
  autoUpdateLog,
25
25
  autoUpdateState
26
- } from "./chunk-2J4IVUEA.js";
26
+ } from "./chunk-7KYQ24FI.js";
27
27
  import {
28
28
  execNpm,
29
29
  fetchLatestPublishedVersion,
30
30
  npmErrorMessage,
31
31
  readGlobalCliInstallAt,
32
32
  readGlobalPrefix
33
- } from "./chunk-AUDYAVNM.js";
33
+ } from "./chunk-T2EJ3H6Y.js";
34
34
  import {
35
35
  EXIT
36
36
  } from "./chunk-KZERVKTD.js";
37
37
  import {
38
38
  NPX_LATEST_COMMAND
39
- } from "./chunk-UIS332AZ.js";
39
+ } from "./chunk-R3HXGHRQ.js";
40
40
  import {
41
41
  commandsPackage,
42
42
  globalUpgradeEntry,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pusharyFetch
3
- } from "./chunk-SOHJ37NA.js";
3
+ } from "./chunk-KWGOKO4E.js";
4
4
  import {
5
5
  getBaseUrl
6
- } from "./chunk-53D6FFVE.js";
6
+ } from "./chunk-M7JFGDGP.js";
7
7
  import {
8
8
  NetworkError
9
9
  } from "./chunk-PPY5N2E6.js";
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  isValidApiKey,
15
15
  normalizeKeyScope
16
- } from "./chunk-QRS7FQHE.js";
16
+ } from "./chunk-Y4OBAK4I.js";
17
17
 
18
18
  // src/session.ts
19
19
  var samePusharyAccount = (left, right) => left.kind === "ok" && right.kind === "ok" && left.identity.workspaceId !== "" && left.identity.workspaceId === right.identity.workspaceId && left.identity.siteId === right.identity.siteId;
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-3EGEA4KH.js";
10
10
  import {
11
11
  getBaseUrl
12
- } from "./chunk-53D6FFVE.js";
12
+ } from "./chunk-M7JFGDGP.js";
13
13
 
14
14
  // src/cli/login-ui.ts
15
15
  import { hostname } from "os";
@@ -5,19 +5,19 @@ import {
5
5
  hermesAppWiringRecord,
6
6
  hermesConfigReceipt,
7
7
  hermesSetupReceipt
8
- } from "./chunk-2J4IVUEA.js";
8
+ } from "./chunk-7KYQ24FI.js";
9
9
  import {
10
10
  readJsonSafe,
11
11
  resolvePathBinary,
12
12
  writeJsonAtomic
13
- } from "./chunk-AUDYAVNM.js";
13
+ } from "./chunk-T2EJ3H6Y.js";
14
14
  import {
15
15
  isNewerVersion,
16
16
  isReleaseVersion
17
17
  } from "./chunk-QTOLNRET.js";
18
18
  import {
19
19
  isRecord
20
- } from "./chunk-QRS7FQHE.js";
20
+ } from "./chunk-Y4OBAK4I.js";
21
21
 
22
22
  // src/hermes/plugin-payload.ts
23
23
  import { createHash } from "crypto";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isSafeReadOnlyCommand
3
- } from "./chunk-QRS7FQHE.js";
3
+ } from "./chunk-Y4OBAK4I.js";
4
4
 
5
5
  // src/ledger.ts
6
6
  import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync } from "fs";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  CODEX_HOOK_STATUS
3
- } from "./chunk-SHW6KK2K.js";
3
+ } from "./chunk-USZJJWZL.js";
4
4
  import {
5
5
  retryAgentCommand
6
- } from "./chunk-7O54GE5C.js";
6
+ } from "./chunk-SWRNJ3BP.js";
7
7
  import {
8
8
  NPX_LATEST_COMMAND
9
- } from "./chunk-UIS332AZ.js";
9
+ } from "./chunk-R3HXGHRQ.js";
10
10
 
11
11
  // src/setup/codex-trust.ts
12
12
  var CODEX_TRUST_TELEMETRY = {
@@ -15,16 +15,20 @@ import {
15
15
  } from "./chunk-E46NE7FB.js";
16
16
 
17
17
  // src/codex-desktop-launch.ts
18
- import { spawn as spawn2, execFileSync } from "child_process";
18
+ import { spawn as spawn2, execFileSync as execFileSync2 } from "child_process";
19
19
  import { existsSync } from "fs";
20
20
  import { mkdtemp, readFile, rm, writeFile, access } from "fs/promises";
21
21
  import { constants } from "fs";
22
22
  import { tmpdir } from "os";
23
- import { join, resolve } from "path";
23
+ import { join as join2, resolve } from "path";
24
24
 
25
- // src/codex-desktop-proxy.ts
26
- import { spawn } from "child_process";
27
- import { Transform } from "stream";
25
+ // src/codex-app-runtime.ts
26
+ import { execFileSync } from "child_process";
27
+ import { createHash, randomUUID } from "crypto";
28
+ import { chmodSync, lstatSync, mkdirSync, readdirSync, rmdirSync, unlinkSync } from "fs";
29
+ import { createConnection, createServer } from "net";
30
+ import { homedir } from "os";
31
+ import { join } from "path";
28
32
 
29
33
  // src/codex-permission-form.ts
30
34
  var CODEX_APP_CARD_METHOD = "mcpServer/elicitation/request";
@@ -51,6 +55,163 @@ var codexPermissionFormOf = (message) => {
51
55
  };
52
56
  var codexFormCameFrom = (message, servers) => isRecord(message) && message.method === CODEX_APP_CARD_METHOD && isRecord(message.params) && typeof message.params.serverName === "string" && servers.includes(message.params.serverName);
53
57
 
58
+ // src/codex-app-runtime.ts
59
+ var PROBE_TIMEOUT_MS = 400;
60
+ var MAX_PROBE_BYTES = 1024;
61
+ var MAX_PROXIES = 64;
62
+ var SOCKET_SUFFIX = ".sock";
63
+ var codexRuntimeDirectory = (home = homedir()) => join("/tmp", `pushary-codex-${process.getuid?.() ?? "unknown"}-${createHash("sha256").update(home).digest("hex").slice(0, 16)}`);
64
+ var privateDirectory = (directory) => {
65
+ try {
66
+ const stat = lstatSync(directory);
67
+ return stat.isDirectory() && !stat.isSymbolicLink() && stat.uid === process.getuid?.() && (stat.mode & 63) === 0;
68
+ } catch {
69
+ return false;
70
+ }
71
+ };
72
+ var serveCodexRuntime = (enginePid, forwarding, report, directory = codexRuntimeDirectory()) => {
73
+ let close = () => {
74
+ };
75
+ try {
76
+ mkdirSync(directory, { recursive: true, mode: 448 });
77
+ if (!privateDirectory(directory)) throw new Error("runtime directory is not private");
78
+ const path = join(directory, `${process.pid}-${randomUUID().slice(0, 8)}${SOCKET_SUFFIX}`);
79
+ const server = createServer((socket) => {
80
+ socket.setTimeout(PROBE_TIMEOUT_MS, () => socket.destroy());
81
+ socket.on("error", () => socket.destroy());
82
+ let input = "";
83
+ socket.on("data", (chunk) => {
84
+ input += chunk.toString();
85
+ if (input.length > MAX_PROBE_BYTES) {
86
+ socket.destroy();
87
+ return;
88
+ }
89
+ if (!input.endsWith("\n")) return;
90
+ const nonce = input.trim();
91
+ if (!/^[a-f0-9-]{36}$/.test(nonce)) {
92
+ socket.destroy();
93
+ return;
94
+ }
95
+ socket.end(JSON.stringify({ nonce, pid: process.pid, enginePid, forwarding: forwarding() }) + "\n");
96
+ });
97
+ });
98
+ server.on("error", () => report("Codex connection status is unavailable; permission forwarding is unchanged."));
99
+ server.listen(path, () => {
100
+ try {
101
+ chmodSync(path, 384);
102
+ } catch {
103
+ server.close();
104
+ }
105
+ });
106
+ server.unref();
107
+ close = () => {
108
+ server.close();
109
+ try {
110
+ unlinkSync(path);
111
+ } catch {
112
+ }
113
+ try {
114
+ rmdirSync(directory);
115
+ } catch {
116
+ }
117
+ };
118
+ } catch {
119
+ report("Codex connection status is unavailable; permission forwarding is unchanged.");
120
+ }
121
+ return close;
122
+ };
123
+ var probeCodexRuntime = (path) => new Promise((resolve2) => {
124
+ const nonce = randomUUID();
125
+ const socket = createConnection(path);
126
+ let output = "";
127
+ let finished = false;
128
+ const finish = (reply) => {
129
+ if (finished) return;
130
+ finished = true;
131
+ socket.destroy();
132
+ resolve2(reply);
133
+ };
134
+ socket.setTimeout(PROBE_TIMEOUT_MS, () => finish(null));
135
+ socket.on("error", () => finish(null));
136
+ socket.on("connect", () => socket.write(nonce + "\n"));
137
+ socket.on("data", (chunk) => {
138
+ output += chunk.toString();
139
+ if (output.length > MAX_PROBE_BYTES) {
140
+ finish(null);
141
+ return;
142
+ }
143
+ if (!output.endsWith("\n")) return;
144
+ try {
145
+ const reply = JSON.parse(output);
146
+ if (!isRecord(reply) || reply.nonce !== nonce || !Number.isSafeInteger(reply.pid) || !Number.isSafeInteger(reply.enginePid) || typeof reply.pid !== "number" || reply.pid <= 0 || typeof reply.enginePid !== "number" || reply.enginePid <= 0 || typeof reply.forwarding !== "boolean") {
147
+ finish(null);
148
+ return;
149
+ }
150
+ finish({ pid: reply.pid, enginePid: reply.enginePid, forwarding: reply.forwarding });
151
+ } catch {
152
+ finish(null);
153
+ }
154
+ });
155
+ socket.on("close", () => finish(null));
156
+ });
157
+ var codexRuntimeProcesses = (output) => {
158
+ const processes = [];
159
+ for (const line of output.trim().split("\n")) {
160
+ const match = /^\s*(\d+)\s+(\d+)\s+(.+)$/.exec(line);
161
+ if (!match) return null;
162
+ const pid = Number(match[1]), parent = Number(match[2]);
163
+ if (!Number.isSafeInteger(pid) || pid <= 0 || !Number.isSafeInteger(parent) || parent < 0 || processes.some((process2) => process2.pid === pid)) return null;
164
+ processes.push({ pid, parent, executable: match[3] });
165
+ }
166
+ return processes;
167
+ };
168
+ var codexRuntimeStatus = (app, processes, replies) => {
169
+ const byPid = new Map(processes.map((process2) => [process2.pid, process2]));
170
+ const desktops = new Set(processes.filter((process2) => process2.executable.startsWith(`${app}/Contents/MacOS/`)).map((process2) => process2.pid));
171
+ if (desktops.size === 0) return "closed";
172
+ const isEngine = (process2) => process2.executable.startsWith(`${app}/Contents/Resources/codex-cli/`) && process2.executable.endsWith("/codex");
173
+ const owningDesktop = (engine) => {
174
+ const visited = /* @__PURE__ */ new Set([engine.pid]);
175
+ let parent = byPid.get(engine.parent);
176
+ while (parent && !visited.has(parent.pid)) {
177
+ if (desktops.has(parent.pid)) return parent.pid;
178
+ if (isEngine(parent)) return null;
179
+ visited.add(parent.pid);
180
+ parent = byPid.get(parent.parent);
181
+ }
182
+ return null;
183
+ };
184
+ const engines = processes.filter((process2) => isEngine(process2) && owningDesktop(process2) !== null);
185
+ const owners = new Set(engines.map(owningDesktop));
186
+ if ([...desktops].some((pid) => !owners.has(pid))) return "unknown";
187
+ const observed = engines.map((engine) => replies.find((reply) => reply.enginePid === engine.pid && reply.pid === engine.parent));
188
+ if (observed.some((reply) => reply === void 0)) return "restart_required";
189
+ return observed.every((reply) => reply?.forwarding) ? "connected" : "unsupported";
190
+ };
191
+ var readCodexAppRuntime = async (app, directory = codexRuntimeDirectory()) => {
192
+ const uid = process.getuid?.();
193
+ if (app === null || process.platform !== "darwin" || uid === void 0) return "unknown";
194
+ try {
195
+ const snapshot = execFileSync("/bin/ps", ["-U", String(uid), "-o", "pid=,ppid=,comm="], { encoding: "utf8", timeout: 1e3, maxBuffer: 2 * 1024 * 1024 });
196
+ const processes = codexRuntimeProcesses(snapshot);
197
+ if (processes === null) return "unknown";
198
+ const livePids = new Set(processes.map((process2) => process2.pid));
199
+ const names = privateDirectory(directory) ? readdirSync(directory).filter((name) => {
200
+ const match = /^(\d+)-[a-f0-9]{8}\.sock$/.exec(name);
201
+ return match !== null && livePids.has(Number(match[1]));
202
+ }) : [];
203
+ if (names.length > MAX_PROXIES) return "unknown";
204
+ const replies = await Promise.all(names.map((name) => probeCodexRuntime(join(directory, name))));
205
+ return codexRuntimeStatus(app, processes, replies.filter((reply) => reply !== null));
206
+ } catch {
207
+ return "unknown";
208
+ }
209
+ };
210
+
211
+ // src/codex-desktop-proxy.ts
212
+ import { spawn } from "child_process";
213
+ import { Transform } from "stream";
214
+
54
215
  // src/codex-app-card.ts
55
216
  var CODEX_REQUEST_RESOLVED_METHOD = "serverRequest/resolved";
56
217
  var COMPUTER_USE_CONNECTOR = "computer-use";
@@ -176,6 +337,17 @@ var CodexAppCardLedger = class {
176
337
  }
177
338
  };
178
339
 
340
+ // src/codex-audio-card.ts
341
+ var codexAudioCardOf = (message) => {
342
+ const form = codexPermissionFormOf(message);
343
+ if (!form || form.serverName !== CODEX_COMPUTER_USE_SERVER || !["form", "openai/form", "openaiForm"].includes(form.mode)) return null;
344
+ const meta = form.meta;
345
+ if (meta.connector_id !== "computer-use" || meta.tool_name !== "start_audio_recording" || form.sentence !== "Allow Computer Use to record computer audio?" || !Array.isArray(meta.persist) || !meta.persist.includes("session") || !isRecord(meta.tool_params) || Object.keys(meta.tool_params).length !== 0) return null;
346
+ return { kind: "audio", requestId: form.requestId, threadId: form.threadId };
347
+ };
348
+ var CODEX_AUDIO_QUESTION = "Allow Codex to record computer audio for this conversation?";
349
+ var CODEX_AUDIO_CONTEXT = `${CODEX_SHOWS_THE_SAME_QUESTION} Yes permits computer audio recording for this conversation. Audio may include other apps and calls. No declines recording.`;
350
+
179
351
  // src/codex-browser-use-card.ts
180
352
  var BROWSER_USE_SERVERS = [CODEX_COMPUTER_USE_SERVER, CODEX_BROWSER_SERVER];
181
353
  var BROWSER_USE_CONNECTOR = "browser-use";
@@ -271,14 +443,49 @@ var codexBrowserUseCardReply = (requestId, decision) => ({
271
443
  // src/codex-card.ts
272
444
  var codexCardOf = (message) => {
273
445
  const app = codexAppCardOf(message);
274
- return app ? { kind: "app", ...app } : codexBrowserUseCardOf(message);
446
+ return app ? { kind: "app", ...app } : codexBrowserUseCardOf(message) ?? codexAudioCardOf(message);
275
447
  };
276
448
  var comesFromCodexOwnTools = (message) => comesFromComputerUse(message) || comesFromBrowserUse(message);
277
449
  var codexAppMayAnswerItself = (card) => card.kind === "site_access";
278
- var codexCardQuestion = (card) => card.kind === "app" ? codexAppCardQuestion(card) : codexBrowserUseCardQuestion(card);
279
- var codexCardContext = (card) => card.kind === "app" ? codexAppCardContext(card) : codexBrowserUseCardContext(card);
280
- var codexCardSubject = (card) => card.kind === "app" ? card.appName : codexBrowserUseCardSubject(card);
281
- var codexCardReply = (card, decision) => card.kind === "app" ? codexAppCardReply(card.requestId, decision) : codexBrowserUseCardReply(card.requestId, decision);
450
+ var codexCardQuestion = (card) => {
451
+ switch (card.kind) {
452
+ case "app":
453
+ return codexAppCardQuestion(card);
454
+ case "audio":
455
+ return CODEX_AUDIO_QUESTION;
456
+ default:
457
+ return codexBrowserUseCardQuestion(card);
458
+ }
459
+ };
460
+ var codexCardContext = (card) => {
461
+ switch (card.kind) {
462
+ case "app":
463
+ return codexAppCardContext(card);
464
+ case "audio":
465
+ return CODEX_AUDIO_CONTEXT;
466
+ default:
467
+ return codexBrowserUseCardContext(card);
468
+ }
469
+ };
470
+ var codexCardSubject = (card) => {
471
+ switch (card.kind) {
472
+ case "app":
473
+ return card.appName;
474
+ case "audio":
475
+ return "computer audio";
476
+ default:
477
+ return codexBrowserUseCardSubject(card);
478
+ }
479
+ };
480
+ var codexCardReply = (card, decision) => {
481
+ switch (card.kind) {
482
+ case "app":
483
+ case "audio":
484
+ return codexAppCardReply(card.requestId, decision);
485
+ default:
486
+ return codexBrowserUseCardReply(card.requestId, decision);
487
+ }
488
+ };
282
489
 
283
490
  // src/load-once.ts
284
491
  var loadedOnce = (load) => {
@@ -294,7 +501,7 @@ var loadedOnce = (load) => {
294
501
  };
295
502
 
296
503
  // src/codex-desktop-proxy.ts
297
- var loadThePhone = () => import("./api-L3BIISGS.js");
504
+ var loadThePhone = () => import("./api-YDCHRRA4.js");
298
505
  var theFirstCardLoadsAgain = () => {
299
506
  };
300
507
  var APP_SERVER_COMMAND = "app-server";
@@ -645,6 +852,12 @@ var runCodexDesktopProxy = async (binary, args, readAccount, options = { watches
645
852
  env: codexEngineEnvironment(binary)
646
853
  });
647
854
  child.once("spawn", tellTheLauncherTheEngineStarted);
855
+ let forwarding = watches;
856
+ let closeRuntime = () => {
857
+ };
858
+ child.once("spawn", () => {
859
+ if (child.pid && args[subcommandIndexOf(args)] === APP_SERVER_COMMAND) closeRuntime = serveCodexRuntime(child.pid, () => forwarding, reportOnStderr);
860
+ });
648
861
  const abort = new AbortController();
649
862
  let killTimer;
650
863
  let lingerTimer;
@@ -673,6 +886,7 @@ var runCodexDesktopProxy = async (binary, args, readAccount, options = { watches
673
886
  let cards;
674
887
  const streams = [];
675
888
  const keepCopyingWithoutCards = (error) => {
889
+ forwarding = false;
676
890
  cards?.standDown();
677
891
  reportOnStderr(`Codex app cards stopped for this session after an unexpected error; Codex keeps working. ${error instanceof Error ? error.message.split("\n")[0] : ""}`.trim());
678
892
  };
@@ -701,6 +915,7 @@ var runCodexDesktopProxy = async (binary, args, readAccount, options = { watches
701
915
  child.once("close", (code) => resolve2(code ?? 1));
702
916
  });
703
917
  } finally {
918
+ closeRuntime();
704
919
  abort.abort();
705
920
  clearTimeout(killTimer);
706
921
  clearTimeout(lingerTimer);
@@ -783,12 +998,12 @@ var codexEngineBehindLauncher = (script) => {
783
998
  return shellUnquoted(assignment.slice(ENGINE_ASSIGNMENT.length));
784
999
  };
785
1000
  var writeDesktopProxy = async (entry, app, engine, directory) => {
786
- const shim = join(directory, "codex");
1001
+ const shim = join2(directory, "codex");
787
1002
  await writeFile(shim, desktopProxyScript(entry, app, engine), { mode: 448, flag: "wx" });
788
1003
  return shim;
789
1004
  };
790
1005
  var desktopEngine = async (app) => {
791
- const manifest = JSON.parse(await readFile(join(app, CODEX_ENGINE_DIRECTORY, CODEX_ENGINE_MANIFEST), "utf8"));
1006
+ const manifest = JSON.parse(await readFile(join2(app, CODEX_ENGINE_DIRECTORY, CODEX_ENGINE_MANIFEST), "utf8"));
792
1007
  const engine = desktopEngineFromManifest(app, manifest);
793
1008
  await access(engine, constants.X_OK);
794
1009
  return engine;
@@ -802,18 +1017,18 @@ var engineWhateverTheLayout = async (app) => {
802
1017
  return { engine, layoutIsKnown: false };
803
1018
  }
804
1019
  };
805
- var codexAppOnThisMac = () => INSTALLED_CODEX_APPS.find((candidate) => existsSync(join(candidate, CODEX_ENGINE_DIRECTORY, CODEX_ENGINE_MANIFEST))) ?? null;
1020
+ var codexAppOnThisMac = () => INSTALLED_CODEX_APPS.find((candidate) => existsSync(join2(candidate, CODEX_ENGINE_DIRECTORY, CODEX_ENGINE_MANIFEST))) ?? null;
806
1021
  var installedCodexApp = (chosen) => resolve(chosen ?? codexAppOnThisMac() ?? INSTALLED_CODEX_APPS[1]);
807
1022
  var desktopExecutable = (app) => {
808
- const plist = join(app, "Contents/Info.plist");
809
- const read = (key) => execFileSync("/usr/bin/plutil", ["-extract", key, "raw", plist], { encoding: "utf8" }).trim();
1023
+ const plist = join2(app, "Contents/Info.plist");
1024
+ const read = (key) => execFileSync2("/usr/bin/plutil", ["-extract", key, "raw", plist], { encoding: "utf8" }).trim();
810
1025
  if (read("CFBundleIdentifier") !== "com.openai.codex") throw new Error("Choose the Codex Desktop application");
811
1026
  const name = read("CFBundleExecutable");
812
1027
  if (!name || name.includes("/") || name === "." || name === "..") throw new Error("Invalid Desktop executable");
813
1028
  try {
814
- execFileSync("/usr/bin/pgrep", ["-x", name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")], { stdio: "ignore" });
1029
+ execFileSync2("/usr/bin/pgrep", ["-x", name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")], { stdio: "ignore" });
815
1030
  } catch (error) {
816
- if (record(error) && error.status === 1) return join(app, "Contents/MacOS", name);
1031
+ if (record(error) && error.status === 1) return join2(app, "Contents/MacOS", name);
817
1032
  throw error;
818
1033
  }
819
1034
  throw new Error("Codex Desktop is already running. Finish active work and quit it yourself, then retry. Pushary will not restart it.");
@@ -827,7 +1042,7 @@ var codexDesktopCommand = async (args, entry, readAccount) => {
827
1042
  return runCodexDesktopProxy(engine2, args.slice(3), readAccount, { watchesForCards: layoutIsKnown });
828
1043
  }
829
1044
  if (args[0] === APP_CARDS_FLAG) {
830
- const { codexAppCardsCommandOnThisMac } = await import("./codex-app-cards-switch-CN3G7GZW.js");
1045
+ const { codexAppCardsCommandOnThisMac } = await import("./codex-app-cards-switch-3OUTABVU.js");
831
1046
  return codexAppCardsCommandOnThisMac(args.slice(1), entry, readAccount);
832
1047
  }
833
1048
  if (args.length > 2) throw new Error("Usage: pushary codex --desktop [path/to/Codex.app]");
@@ -835,7 +1050,7 @@ var codexDesktopCommand = async (args, entry, readAccount) => {
835
1050
  const app = installedCodexApp(args[1]);
836
1051
  const engine = await desktopEngine(app);
837
1052
  const executable = desktopExecutable(app);
838
- const directory = await mkdtemp(join(tmpdir(), "pushary-codex-desktop-"));
1053
+ const directory = await mkdtemp(join2(tmpdir(), "pushary-codex-desktop-"));
839
1054
  try {
840
1055
  const shim = await writeDesktopProxy(entry, app, engine, directory);
841
1056
  process.stderr.write("[pushary] Experimental Codex app launch. When Codex asks to use an app on this Mac, or its browser asks to open a site, download or upload, the question also reaches Pushary; every other prompt stays as it is. Quit and open Codex normally to turn this off.\n");
@@ -850,6 +1065,7 @@ var codexDesktopCommand = async (args, entry, readAccount) => {
850
1065
  };
851
1066
 
852
1067
  export {
1068
+ readCodexAppRuntime,
853
1069
  shellQuoted,
854
1070
  LAUNCHCTL,
855
1071
  desktopEngineFromManifest,
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  notificationAnswerStep
3
- } from "./chunk-SNUHX5GQ.js";
3
+ } from "./chunk-Y2CYSVWU.js";
4
4
  import {
5
5
  canChangeApprovalSettings
6
- } from "./chunk-2DB7TBA7.js";
6
+ } from "./chunk-USMUW3LI.js";
7
7
  import {
8
8
  matchMacAccountStep,
9
9
  retryAgentCommand
10
- } from "./chunk-7O54GE5C.js";
10
+ } from "./chunk-SWRNJ3BP.js";
11
11
  import {
12
12
  EXIT
13
13
  } from "./chunk-KZERVKTD.js";
14
14
  import {
15
15
  NPX_LATEST_COMMAND
16
- } from "./chunk-UIS332AZ.js";
16
+ } from "./chunk-R3HXGHRQ.js";
17
17
 
18
18
  // src/setup/closing.ts
19
19
  var ACTIVITY_URL = "pushary.com/dashboard/agent/activity";
@@ -1,13 +1,18 @@
1
1
  import {
2
2
  getBaseUrl
3
- } from "./chunk-53D6FFVE.js";
3
+ } from "./chunk-M7JFGDGP.js";
4
4
  import {
5
5
  compressTranscriptRecord,
6
6
  redactSecretsFromContent,
7
7
  transcriptRecordPlaintext
8
- } from "./chunk-QRS7FQHE.js";
8
+ } from "./chunk-Y4OBAK4I.js";
9
9
 
10
10
  // src/transcript-api.ts
11
+ var retentionDaysOf = (sessionHistory) => {
12
+ if (sessionHistory === null || typeof sessionHistory !== "object") return null;
13
+ const days = sessionHistory.retentionDays;
14
+ return typeof days === "number" && Number.isInteger(days) && days > 0 ? days : null;
15
+ };
11
16
  var fetchTranscriptRecipients = async (apiKey, baseUrl = getBaseUrl()) => {
12
17
  try {
13
18
  const res = await fetch(`${baseUrl}/api/agent/encryption-account`, {
@@ -18,8 +23,9 @@ var fetchTranscriptRecipients = async (apiKey, baseUrl = getBaseUrl()) => {
18
23
  const data = await res.json();
19
24
  if (typeof data.publicKey !== "string" || data.publicKey.length === 0) return null;
20
25
  const phoneReadsCompressedRecords = data.readsCompressedRecords === true;
26
+ const retentionDays = retentionDaysOf(data.sessionHistory);
21
27
  if (data.providerRecovery === void 0 || data.providerRecovery === null) {
22
- return { phonePublicKey: data.publicKey, phoneReadsCompressedRecords, provider: null };
28
+ return { phonePublicKey: data.publicKey, phoneReadsCompressedRecords, provider: null, retentionDays };
23
29
  }
24
30
  if (typeof data.providerRecovery !== "object") return null;
25
31
  const provider = data.providerRecovery;
@@ -27,7 +33,8 @@ var fetchTranscriptRecipients = async (apiKey, baseUrl = getBaseUrl()) => {
27
33
  return {
28
34
  phonePublicKey: data.publicKey,
29
35
  phoneReadsCompressedRecords,
30
- provider: { required: provider.required, keyId: provider.keyId, publicKey: provider.publicKey }
36
+ provider: { required: provider.required, keyId: provider.keyId, publicKey: provider.publicKey },
37
+ retentionDays
31
38
  };
32
39
  } catch {
33
40
  return null;
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  keyCheckFromResponse
3
- } from "./chunk-SIJHPGUW.js";
3
+ } from "./chunk-E7U4YM4A.js";
4
4
  import {
5
5
  installNetworkDefaults
6
- } from "./chunk-SOHJ37NA.js";
6
+ } from "./chunk-KWGOKO4E.js";
7
7
  import {
8
8
  getBaseUrl
9
- } from "./chunk-53D6FFVE.js";
9
+ } from "./chunk-M7JFGDGP.js";
10
10
  import {
11
11
  isRecord,
12
12
  isToolErrorResult,
13
13
  toolFailureCodeOfResult
14
- } from "./chunk-QRS7FQHE.js";
14
+ } from "./chunk-Y4OBAK4I.js";
15
15
 
16
16
  // src/retry.ts
17
17
  var isRetryable = (err) => {
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  openCodeConfigDirFrom
3
- } from "./chunk-E5XYFIYL.js";
3
+ } from "./chunk-QUGP76DQ.js";
4
4
  import {
5
5
  nativeClaudeInstallPath
6
- } from "./chunk-R7V6BPEV.js";
6
+ } from "./chunk-UMBVIFP5.js";
7
7
  import {
8
8
  grokHome
9
- } from "./chunk-3SAF4QXU.js";
9
+ } from "./chunk-3YU6NIIL.js";
10
10
  import {
11
11
  claudeConfigDir,
12
12
  clineDataDirectory,
13
13
  codexHomeFrom
14
- } from "./chunk-2J4IVUEA.js";
14
+ } from "./chunk-7KYQ24FI.js";
15
15
  import {
16
16
  HOOK_COMPATIBLE_PROFILES
17
- } from "./chunk-QRS7FQHE.js";
17
+ } from "./chunk-Y4OBAK4I.js";
18
18
 
19
19
  // src/vscode-config.ts
20
20
  import { homedir } from "os";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  AGENT_CHOICES
3
- } from "./chunk-NCTABQMC.js";
3
+ } from "./chunk-PPD64MZW.js";
4
4
  import {
5
5
  BELL_HOOK_BINARY
6
- } from "./chunk-4DH54LS7.js";
6
+ } from "./chunk-5FV472Q2.js";
7
7
  import {
8
8
  CLAUDE_HOOK_EVENTS,
9
9
  CODEX_HOOK_EVENTS,
@@ -12,13 +12,13 @@ import {
12
12
  holdBudgetOf,
13
13
  isProtectedByScope,
14
14
  registerHookEntry
15
- } from "./chunk-2J4IVUEA.js";
15
+ } from "./chunk-7KYQ24FI.js";
16
16
  import {
17
17
  CURSOR_GATE_EVENTS,
18
18
  HOOK_BUDGETS,
19
19
  HOOK_LOCATOR_BINARY,
20
20
  hookCommandHoldBudget
21
- } from "./chunk-QRS7FQHE.js";
21
+ } from "./chunk-Y4OBAK4I.js";
22
22
 
23
23
  // src/diagnostics/bridge.ts
24
24
  import { execFileSync } from "child_process";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  readExistingMachineId
3
- } from "./chunk-BGEUAJYL.js";
3
+ } from "./chunk-BUR2LYQI.js";
4
4
  import {
5
5
  getBaseUrl
6
- } from "./chunk-53D6FFVE.js";
6
+ } from "./chunk-M7JFGDGP.js";
7
7
  import {
8
8
  NetworkError
9
9
  } from "./chunk-PPY5N2E6.js";
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  clientContextHeaders,
15
15
  redactSecretsFromContent
16
- } from "./chunk-QRS7FQHE.js";
16
+ } from "./chunk-Y4OBAK4I.js";
17
17
 
18
18
  // src/cli/net.ts
19
19
  import { createRequire } from "module";