@pushary/agent-hooks 1.9.75 → 1.9.77

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 +13 -0
  2. package/dist/{api-L3BIISGS.js → api-IGMCPM35.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 +123 -66
  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 +47 -18
  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-JCZWWBBA.js → chunk-2IOQHB3C.js} +5 -5
  45. package/dist/{chunk-UIS332AZ.js → chunk-2OWG667E.js} +1 -1
  46. package/dist/{chunk-UEJTWQVF.js → chunk-2YRNRYZW.js} +1 -1
  47. package/dist/{chunk-UU3CDLIX.js → chunk-3UYMJZXV.js} +2 -2
  48. package/dist/{chunk-HXV2SY2V.js → chunk-4ZXFOT44.js} +2 -2
  49. package/dist/{chunk-L2FQBHIR.js → chunk-6WOG2SCC.js} +3 -2
  50. package/dist/{chunk-6BFLDHPM.js → chunk-6XOEYBWJ.js} +3 -3
  51. package/dist/{chunk-SOHJ37NA.js → chunk-7AQEWD2J.js} +3 -3
  52. package/dist/{chunk-VGHWK5Z2.js → chunk-7CU7OGWP.js} +263 -5
  53. package/dist/{chunk-GAAN3Y7V.js → chunk-7HYNAA6B.js} +1 -1
  54. package/dist/{chunk-EVBG5YUO.js → chunk-A3BF7SGM.js} +3 -3
  55. package/dist/{chunk-AUDYAVNM.js → chunk-ABAWD6QM.js} +3 -3
  56. package/dist/{chunk-Z7ORL6SC.js → chunk-BUBC4R5J.js} +2 -2
  57. package/dist/{chunk-RPKFXNOJ.js → chunk-CIMFZIGP.js} +2 -2
  58. package/dist/{chunk-SIJHPGUW.js → chunk-CKUFXQUJ.js} +3 -3
  59. package/dist/{chunk-P4TWTQ6V.js → chunk-CS5PJXL7.js} +6 -6
  60. package/dist/{chunk-LRYZXY4V.js → chunk-CU65AFT4.js} +1 -1
  61. package/dist/{chunk-M7BXAWUC.js → chunk-D5NLXF72.js} +3 -3
  62. package/dist/{chunk-LIDUPDEY.js → chunk-DYDA77FS.js} +4 -4
  63. package/dist/{chunk-4DH54LS7.js → chunk-EFHCTIFT.js} +1 -1
  64. package/dist/{chunk-EOGVWCLF.js → chunk-ESHMWZXX.js} +5 -5
  65. package/dist/{chunk-T6RWREWU.js → chunk-EV47UGDK.js} +1 -1
  66. package/dist/{chunk-UBANQ4EZ.js → chunk-FBLVK2WR.js} +13 -13
  67. package/dist/{chunk-FEC3JUIH.js → chunk-FXQCSU4L.js} +3 -3
  68. package/dist/{chunk-I73UQU7K.js → chunk-GI3PX2JU.js} +1 -1
  69. package/dist/{chunk-SFJOGZQV.js → chunk-GL34UITI.js} +3 -3
  70. package/dist/{chunk-4T25BBBO.js → chunk-GOJO2OLP.js} +4 -4
  71. package/dist/{chunk-32JJ5KV3.js → chunk-GV7FB5L3.js} +4 -4
  72. package/dist/{chunk-3SAF4QXU.js → chunk-H4GOJIOK.js} +4 -4
  73. package/dist/{chunk-QDUDXJAF.js → chunk-HGVUTO67.js} +3 -3
  74. package/dist/{chunk-53D6FFVE.js → chunk-IHT33GZN.js} +1 -1
  75. package/dist/{chunk-QRS7FQHE.js → chunk-INBG473K.js} +8 -2
  76. package/dist/{chunk-E5XYFIYL.js → chunk-J2NPFRDI.js} +6 -6
  77. package/dist/{chunk-DCHZ5JOI.js → chunk-JJPBWBAF.js} +6 -6
  78. package/dist/{chunk-DX65IDBI.js → chunk-JLYVYHD2.js} +1 -1
  79. package/dist/{chunk-DARPCQPY.js → chunk-K2MW33DG.js} +2 -2
  80. package/dist/{chunk-JFVLMWKY.js → chunk-KUI2KGRZ.js} +9 -9
  81. package/dist/{chunk-BGEUAJYL.js → chunk-LD5LSJ2B.js} +2 -2
  82. package/dist/{chunk-JOMG6J64.js → chunk-LIEPMKTX.js} +1 -1
  83. package/dist/chunk-MHUKYYYR.js +239 -0
  84. package/dist/{chunk-I6TIZMM3.js → chunk-MQBQRXTN.js} +5 -5
  85. package/dist/{chunk-DOG3BQFO.js → chunk-MRTGCXG4.js} +6 -6
  86. package/dist/{chunk-EH5OLIP2.js → chunk-NHIEDRZR.js} +236 -20
  87. package/dist/{chunk-PV5XEBFI.js → chunk-NNV2XS3Y.js} +6 -6
  88. package/dist/{chunk-WL3V2UV4.js → chunk-OJ4EEE2B.js} +6 -6
  89. package/dist/{chunk-D4X4BQVQ.js → chunk-OXA2P5NJ.js} +10 -10
  90. package/dist/{chunk-BRG4XS2H.js → chunk-P4IFREOO.js} +1 -1
  91. package/dist/{chunk-MD4UJICD.js → chunk-P7CGVHH5.js} +5 -5
  92. package/dist/{chunk-ZX3KEXO3.js → chunk-PAPUUZOP.js} +626 -164
  93. package/dist/{chunk-PGLNE556.js → chunk-PGZFXNRJ.js} +1 -1
  94. package/dist/{chunk-3PPL64AG.js → chunk-PKHNZTHY.js} +9 -4
  95. package/dist/{chunk-NCTABQMC.js → chunk-PUF3BL6C.js} +1 -1
  96. package/dist/{chunk-EM2RSWDA.js → chunk-PZWC3JXW.js} +5 -5
  97. package/dist/{chunk-2J4IVUEA.js → chunk-PZXQUV3P.js} +4 -4
  98. package/dist/{chunk-7O54GE5C.js → chunk-QBCV27CM.js} +3 -3
  99. package/dist/{chunk-SNUHX5GQ.js → chunk-QGOY3HNV.js} +6 -6
  100. package/dist/{chunk-7FNSQMQ2.js → chunk-QS2IKPQW.js} +4 -4
  101. package/dist/{chunk-CI6MDBQB.js → chunk-QVP6F6BX.js} +7 -7
  102. package/dist/{chunk-CLHRSK5L.js → chunk-RYDT6Y32.js} +4 -4
  103. package/dist/{chunk-HRRGIVIL.js → chunk-S2UHLCF5.js} +3 -3
  104. package/dist/{chunk-R7V6BPEV.js → chunk-SNHAXVCJ.js} +1 -1
  105. package/dist/{chunk-4GWKKUQ5.js → chunk-SUOW4HJB.js} +5 -5
  106. package/dist/{chunk-TPYZFYQ5.js → chunk-TK3XMPG2.js} +4 -4
  107. package/dist/{chunk-XO7LP3JC.js → chunk-UBQ3TG3B.js} +1 -1
  108. package/dist/{chunk-SHW6KK2K.js → chunk-UU2CQFSJ.js} +2 -2
  109. package/dist/{chunk-5EQOUZYE.js → chunk-UUX6Q3CB.js} +2 -2
  110. package/dist/{chunk-SONZCJY5.js → chunk-WFSE7NRM.js} +23 -6
  111. package/dist/{chunk-DUOBFECC.js → chunk-XYNQA6YC.js} +1 -1
  112. package/dist/{chunk-KDUWFGY2.js → chunk-Y5YJLBML.js} +4 -4
  113. package/dist/{chunk-2DB7TBA7.js → chunk-ZZFYV26G.js} +2 -2
  114. package/dist/{codex-app-cards-switch-CN3G7GZW.js → codex-app-cards-switch-LTZCEFYB.js} +11 -11
  115. package/dist/{codex-desktop-launch-GFZXCDSL.js → codex-desktop-launch-DBJBV66U.js} +1 -1
  116. package/dist/{codex-session-launch-4F2UGQYE.js → codex-session-launch-6RTU73OP.js} +18 -18
  117. package/dist/{config-BLHDUDCS.js → config-YREUMA6Z.js} +3 -3
  118. package/dist/{global-upgrade-IZEC22BQ.js → global-upgrade-EYLSJXXN.js} +10 -10
  119. package/dist/{identity-3HGTEP5Q.js → identity-WIM6NVLP.js} +4 -4
  120. package/dist/{live-capabilities-AZK664T7.js → live-capabilities-SU3BEP2Z.js} +5 -5
  121. package/dist/{paths-ROMZUSEX.js → paths-XV3FXWOM.js} +3 -3
  122. package/dist/{reapply-IJYRR4YK.js → reapply-Q7QC3MWL.js} +27 -27
  123. package/dist/src/index.js +29 -28
  124. package/dist/{upgrade-lock-FGEZPX56.js → upgrade-lock-A2ALHHUG.js} +4 -4
  125. package/dist/{usage-HCURE44F.js → usage-UNEATRXG.js} +3 -3
  126. package/package.json +1 -1
@@ -0,0 +1,239 @@
1
+ // ../contracts/src/billing.ts
2
+ var PARTNER_SELF_SERVE_PLANS = ["partner_launch", "partner_growth", "partner_scale"];
3
+ var PARTNER_PLAN_TYPES = ["partner", ...PARTNER_SELF_SERVE_PLANS];
4
+ var PLAN_TYPES = ["free", "agent", "agent_pro", "team", "partner", "starter", "growth", "pro", "enterprise", ...PARTNER_SELF_SERVE_PLANS];
5
+ var PAID_PLAN_TYPES = ["agent", "agent_pro", "team", "partner", "starter", "growth", "pro", ...PARTNER_SELF_SERVE_PLANS];
6
+ var SESSION_HISTORY_RETENTION_DAYS = { standard: 14, pro: 30 };
7
+ var PLAN_CONFIGS = {
8
+ free: {
9
+ name: "Free",
10
+ price: 0,
11
+ priceId: null,
12
+ limits: {
13
+ subscribers: 100,
14
+ notifications: 500,
15
+ sites: 1,
16
+ members: 1,
17
+ campaigns: 25,
18
+ dataRetentionDays: 7,
19
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.standard
20
+ },
21
+ features: {
22
+ abTesting: false,
23
+ apiAccess: false,
24
+ prioritySupport: false
25
+ }
26
+ },
27
+ agent: {
28
+ name: "Agent",
29
+ price: 9.99,
30
+ priceId: null,
31
+ limits: {
32
+ subscribers: 3,
33
+ notifications: 5e3,
34
+ sites: 1,
35
+ members: 1,
36
+ campaigns: 0,
37
+ dataRetentionDays: 30,
38
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.standard
39
+ },
40
+ features: {
41
+ abTesting: false,
42
+ apiAccess: true,
43
+ prioritySupport: false
44
+ }
45
+ },
46
+ agent_pro: {
47
+ name: "Agent Pro",
48
+ price: 19.99,
49
+ priceId: null,
50
+ limits: {
51
+ subscribers: 5,
52
+ notifications: Infinity,
53
+ sites: 1,
54
+ members: 5,
55
+ campaigns: 0,
56
+ dataRetentionDays: 90,
57
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.pro
58
+ },
59
+ features: {
60
+ abTesting: false,
61
+ apiAccess: true,
62
+ prioritySupport: true
63
+ }
64
+ },
65
+ team: {
66
+ name: "Team",
67
+ price: 59.99,
68
+ priceId: null,
69
+ limits: {
70
+ subscribers: 25,
71
+ notifications: Infinity,
72
+ sites: 1,
73
+ members: 10,
74
+ campaigns: 0,
75
+ dataRetentionDays: 365,
76
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.pro
77
+ },
78
+ features: {
79
+ abTesting: false,
80
+ apiAccess: true,
81
+ prioritySupport: true
82
+ }
83
+ },
84
+ partner: {
85
+ name: "Partner",
86
+ price: 99,
87
+ priceId: null,
88
+ limits: {
89
+ subscribers: 25e3,
90
+ notifications: 1e5,
91
+ sites: 1,
92
+ members: 10,
93
+ campaigns: 0,
94
+ dataRetentionDays: 365,
95
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.pro
96
+ },
97
+ features: {
98
+ abTesting: false,
99
+ apiAccess: true,
100
+ prioritySupport: true
101
+ }
102
+ },
103
+ partner_launch: {
104
+ name: "Partner Launch",
105
+ price: 99,
106
+ priceId: null,
107
+ limits: {
108
+ subscribers: 5e3,
109
+ // Closed until request admission and fan-out accounting ship. Never sell
110
+ // human requests against the legacy notification-delivery counter.
111
+ notifications: 0,
112
+ humanDecisionRequests: 25e3,
113
+ sites: 1,
114
+ members: 3,
115
+ campaigns: 0,
116
+ dataRetentionDays: 90,
117
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.pro
118
+ },
119
+ features: { abTesting: false, apiAccess: true, prioritySupport: false }
120
+ },
121
+ partner_growth: {
122
+ name: "Partner Growth",
123
+ price: 299,
124
+ priceId: null,
125
+ limits: {
126
+ subscribers: 25e3,
127
+ // Closed until request admission and fan-out accounting ship. Never sell
128
+ // human requests against the legacy notification-delivery counter.
129
+ notifications: 0,
130
+ humanDecisionRequests: 1e5,
131
+ sites: 1,
132
+ members: 10,
133
+ campaigns: 0,
134
+ dataRetentionDays: 365,
135
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.pro
136
+ },
137
+ features: { abTesting: false, apiAccess: true, prioritySupport: true }
138
+ },
139
+ partner_scale: {
140
+ name: "Partner Scale",
141
+ price: 799,
142
+ priceId: null,
143
+ limits: {
144
+ subscribers: 1e5,
145
+ // Closed until request admission and fan-out accounting ship. Never sell
146
+ // human requests against the legacy notification-delivery counter.
147
+ notifications: 0,
148
+ humanDecisionRequests: 5e5,
149
+ sites: 1,
150
+ members: 25,
151
+ campaigns: 0,
152
+ dataRetentionDays: 730,
153
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.pro
154
+ },
155
+ features: { abTesting: false, apiAccess: true, prioritySupport: true }
156
+ },
157
+ starter: {
158
+ name: "Starter",
159
+ price: 29,
160
+ priceId: null,
161
+ limits: {
162
+ subscribers: 5e3,
163
+ notifications: 25e3,
164
+ sites: 3,
165
+ members: 5,
166
+ campaigns: 250,
167
+ dataRetentionDays: 30,
168
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.standard
169
+ },
170
+ features: {
171
+ abTesting: true,
172
+ apiAccess: true,
173
+ prioritySupport: false
174
+ }
175
+ },
176
+ growth: {
177
+ name: "Growth",
178
+ price: 99,
179
+ priceId: null,
180
+ limits: {
181
+ subscribers: 25e3,
182
+ notifications: 1e5,
183
+ sites: 10,
184
+ members: 15,
185
+ campaigns: Infinity,
186
+ dataRetentionDays: 90,
187
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.standard
188
+ },
189
+ features: {
190
+ abTesting: true,
191
+ apiAccess: true,
192
+ prioritySupport: true
193
+ }
194
+ },
195
+ pro: {
196
+ name: "Pro",
197
+ price: 149,
198
+ priceId: null,
199
+ limits: {
200
+ subscribers: 1e5,
201
+ notifications: 5e5,
202
+ sites: 25,
203
+ members: 50,
204
+ campaigns: Infinity,
205
+ dataRetentionDays: 180,
206
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.standard
207
+ },
208
+ features: {
209
+ abTesting: true,
210
+ apiAccess: true,
211
+ prioritySupport: true
212
+ }
213
+ },
214
+ enterprise: {
215
+ name: "Enterprise",
216
+ price: -1,
217
+ priceId: null,
218
+ limits: {
219
+ subscribers: Infinity,
220
+ notifications: Infinity,
221
+ sites: Infinity,
222
+ members: Infinity,
223
+ campaigns: Infinity,
224
+ dataRetentionDays: Infinity,
225
+ sessionHistoryRetentionDays: SESSION_HISTORY_RETENTION_DAYS.pro
226
+ },
227
+ features: {
228
+ abTesting: true,
229
+ apiAccess: true,
230
+ prioritySupport: true
231
+ }
232
+ }
233
+ };
234
+
235
+ export {
236
+ PLAN_TYPES,
237
+ SESSION_HISTORY_RETENTION_DAYS,
238
+ PLAN_CONFIGS
239
+ };
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  macAppBridgeAvailable
3
- } from "./chunk-E5XYFIYL.js";
3
+ } from "./chunk-J2NPFRDI.js";
4
4
  import {
5
5
  keyPrefix
6
- } from "./chunk-LIDUPDEY.js";
6
+ } from "./chunk-DYDA77FS.js";
7
7
  import {
8
8
  bridgeAgentKey
9
- } from "./chunk-2J4IVUEA.js";
9
+ } from "./chunk-PZXQUV3P.js";
10
10
  import {
11
11
  readJsonSafe
12
- } from "./chunk-AUDYAVNM.js";
12
+ } from "./chunk-ABAWD6QM.js";
13
13
  import {
14
14
  isRecord,
15
15
  isValidApiKey
16
- } from "./chunk-QRS7FQHE.js";
16
+ } from "./chunk-INBG473K.js";
17
17
 
18
18
  // src/shared-mcp-key.ts
19
19
  var asRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
@@ -4,7 +4,7 @@ import {
4
4
  postLiveSession,
5
5
  postLiveSessionUntilAccepted,
6
6
  startLiveSessionHeartbeat
7
- } from "./chunk-JOMG6J64.js";
7
+ } from "./chunk-LIEPMKTX.js";
8
8
  import {
9
9
  CommandReceipts,
10
10
  controllerCommandSchema
@@ -14,24 +14,24 @@ import {
14
14
  describeIdleWindow,
15
15
  idleDeadlinePassed,
16
16
  startProcessOwnership
17
- } from "./chunk-FEC3JUIH.js";
17
+ } from "./chunk-FXQCSU4L.js";
18
18
  import {
19
19
  spawnClaude
20
20
  } from "./chunk-XHKBHWLX.js";
21
21
  import {
22
22
  repoKeyFor
23
- } from "./chunk-DUOBFECC.js";
23
+ } from "./chunk-XYNQA6YC.js";
24
24
  import {
25
25
  isAskUserResponse,
26
26
  isDecisionStopped,
27
27
  isWaitForAnswerResponse,
28
28
  withdrawQuestion,
29
29
  writeDegraded
30
- } from "./chunk-EOGVWCLF.js";
30
+ } from "./chunk-ESHMWZXX.js";
31
31
  import {
32
32
  callMcpTool,
33
33
  isRetryable
34
- } from "./chunk-32JJ5KV3.js";
34
+ } from "./chunk-GV7FB5L3.js";
35
35
  import {
36
36
  AGENT_QUESTION_DESCRIPTION_MAX,
37
37
  AGENT_QUESTION_HEADER_MAX,
@@ -52,7 +52,7 @@ import {
52
52
  parseCodexQuestions,
53
53
  planElicitationAsk,
54
54
  readElicitationFields
55
- } from "./chunk-QRS7FQHE.js";
55
+ } from "./chunk-INBG473K.js";
56
56
 
57
57
  // src/codex-question-owner.ts
58
58
  import { createHash } from "crypto";
@@ -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-IGMCPM35.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-LTZCEFYB.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,