@pushary/agent-hooks 1.9.57 → 1.9.59

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 (119) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/{api-RQAY3A5V.js → api-UVJGNZIF.js} +10 -10
  3. package/dist/bin/pushary-bell-hook.js +27 -27
  4. package/dist/bin/pushary-bell.js +10 -10
  5. package/dist/bin/pushary-claude.js +26 -26
  6. package/dist/bin/pushary-clean.js +49 -46
  7. package/dist/bin/pushary-codex-bridge.js +21 -21
  8. package/dist/bin/pushary-codex-hook.js +32 -32
  9. package/dist/bin/pushary-codex-session.js +10 -8
  10. package/dist/bin/pushary-codex.js +14 -14
  11. package/dist/bin/pushary-connect.js +27 -26
  12. package/dist/bin/pushary-cowork.js +5 -5
  13. package/dist/bin/pushary-daemon.js +37 -37
  14. package/dist/bin/pushary-disconnect.js +26 -26
  15. package/dist/bin/pushary-doctor.js +41 -39
  16. package/dist/bin/pushary-elicitation-hook.js +27 -27
  17. package/dist/bin/pushary-gemini-bridge.js +15 -15
  18. package/dist/bin/pushary-gemini-hook.js +29 -29
  19. package/dist/bin/pushary-hook.js +31 -31
  20. package/dist/bin/pushary-login.js +13 -13
  21. package/dist/bin/pushary-logout.js +26 -26
  22. package/dist/bin/pushary-mcp.js +11 -11
  23. package/dist/bin/pushary-mode.js +13 -13
  24. package/dist/bin/pushary-notification-hook.js +26 -26
  25. package/dist/bin/pushary-opencode-hook.js +28 -28
  26. package/dist/bin/pushary-permission-denied-hook.js +31 -31
  27. package/dist/bin/pushary-permission-hook.js +30 -30
  28. package/dist/bin/pushary-post-hook.js +26 -26
  29. package/dist/bin/pushary-prompt-hook.js +26 -26
  30. package/dist/bin/pushary-session-end-hook.js +26 -26
  31. package/dist/bin/pushary-session-start-hook.js +33 -33
  32. package/dist/bin/pushary-setup.js +65 -268
  33. package/dist/bin/pushary-stats.js +5 -5
  34. package/dist/bin/pushary-status.js +32 -30
  35. package/dist/bin/pushary-stop-hook.js +26 -26
  36. package/dist/bin/pushary-stopfailure-hook.js +26 -26
  37. package/dist/bin/pushary-suggestions.js +13 -13
  38. package/dist/bin/pushary-transcript-register.js +18 -18
  39. package/dist/bin/pushary-transcripts.js +7 -7
  40. package/dist/bin/pushary-upgrade.js +107 -58
  41. package/dist/bin/pushary-wait.js +13 -13
  42. package/dist/bin/pushary.js +7 -7
  43. package/dist/chunk-2FVP7WRP.js +378 -0
  44. package/dist/{chunk-W6363YYZ.js → chunk-2WMZDKPM.js} +8 -8
  45. package/dist/{chunk-N3NSWWNU.js → chunk-3N2ZTHZZ.js} +1 -1
  46. package/dist/{chunk-JCMSISCC.js → chunk-3NROUNIS.js} +2 -2
  47. package/dist/{chunk-7RZO6VWD.js → chunk-3RKIJM26.js} +2 -2
  48. package/dist/{chunk-Z7Q36I4K.js → chunk-4QF2YLYK.js} +11 -7
  49. package/dist/{chunk-LVDC3RUE.js → chunk-4XXZUFWN.js} +1 -1
  50. package/dist/{chunk-BAJ3A3BU.js → chunk-5BNXJTOZ.js} +5 -2
  51. package/dist/{chunk-A54W5A74.js → chunk-5EFNBL6V.js} +3 -3
  52. package/dist/{chunk-4YTFYILS.js → chunk-5JWCWALO.js} +9 -9
  53. package/dist/{chunk-3IBUZQKM.js → chunk-5O6D4J2K.js} +2 -2
  54. package/dist/{chunk-DDQRYX2L.js → chunk-5PP4455M.js} +3 -3
  55. package/dist/{chunk-NQDEMRAS.js → chunk-6ONSTCDJ.js} +5 -5
  56. package/dist/{chunk-ECJJKDP7.js → chunk-75UYYIFJ.js} +1 -1
  57. package/dist/{chunk-GZL3KEPC.js → chunk-762CDAJJ.js} +140 -136
  58. package/dist/{chunk-YKYVDHIY.js → chunk-AS4Z6KS4.js} +1 -1
  59. package/dist/{chunk-4YNNAF53.js → chunk-AY32RSUC.js} +2 -2
  60. package/dist/{chunk-I43PY5G3.js → chunk-BKVX53QR.js} +1 -1
  61. package/dist/{chunk-5SFM6XB4.js → chunk-BMPZ5HVJ.js} +2 -2
  62. package/dist/{chunk-7OQ4AJC7.js → chunk-BRUHVTFB.js} +2 -7
  63. package/dist/{chunk-OZSP4RIQ.js → chunk-CPRA7IEK.js} +174 -41
  64. package/dist/{chunk-C3IWX6KU.js → chunk-D6CXQIXO.js} +1 -1
  65. package/dist/{chunk-T45PAPOG.js → chunk-DK35M4TH.js} +5 -5
  66. package/dist/{chunk-K45CFSYV.js → chunk-DS7X36Z3.js} +4 -4
  67. package/dist/{chunk-IBSRULIY.js → chunk-EBQTWH5O.js} +10 -10
  68. package/dist/{chunk-OLNBYAPI.js → chunk-EHCIQA5D.js} +4 -4
  69. package/dist/{chunk-2NIRYGTK.js → chunk-IBXHVYN2.js} +2 -2
  70. package/dist/{chunk-HCIB4YNB.js → chunk-JAKBCKEB.js} +3 -3
  71. package/dist/{chunk-PZDMZ7LM.js → chunk-JBCMXSBO.js} +5 -5
  72. package/dist/{chunk-IRZ5FVWG.js → chunk-KAJDKYUM.js} +3 -3
  73. package/dist/{chunk-AN6TVB2H.js → chunk-KHDD74MK.js} +5 -5
  74. package/dist/{chunk-ZZB4J6CX.js → chunk-KQHY6L3X.js} +4 -4
  75. package/dist/{chunk-UPFFO4F6.js → chunk-KQWN7C5C.js} +4 -4
  76. package/dist/{chunk-D2EETYAL.js → chunk-KW3DED2A.js} +14 -369
  77. package/dist/{chunk-TWLWDIFB.js → chunk-KZCYHWDF.js} +4 -2
  78. package/dist/{chunk-RFAF3TOX.js → chunk-L3NVHPBU.js} +94 -15
  79. package/dist/{chunk-LVZYIUSR.js → chunk-LAEW5QQD.js} +1 -1
  80. package/dist/{chunk-SQ5G6A6K.js → chunk-M46WDK64.js} +1 -1
  81. package/dist/{chunk-LVWXRXT7.js → chunk-M6MOQBR5.js} +1 -1
  82. package/dist/{chunk-FBKVCODG.js → chunk-MA37WNVS.js} +3 -3
  83. package/dist/{chunk-XTZHUIGJ.js → chunk-MMLIQDTG.js} +1 -1
  84. package/dist/{chunk-CB565EVO.js → chunk-MSU3VKGJ.js} +2 -2
  85. package/dist/{chunk-ZU6L34DQ.js → chunk-MYU5D5VH.js} +4 -4
  86. package/dist/{chunk-WXZN5CS3.js → chunk-OZIXBN3O.js} +2 -2
  87. package/dist/{chunk-JSQOHMNJ.js → chunk-PVANKDWM.js} +1 -1
  88. package/dist/{chunk-JYXIARGW.js → chunk-RAMQBSVZ.js} +1 -1
  89. package/dist/{chunk-S5LX25XE.js → chunk-RQDP2SJY.js} +1 -1
  90. package/dist/{chunk-DS6OR5OS.js → chunk-SIU6OWA6.js} +6 -6
  91. package/dist/{chunk-QLDTBZBP.js → chunk-T65RIQK2.js} +6 -6
  92. package/dist/{chunk-2PJENKRJ.js → chunk-TCH5UCPR.js} +77 -30
  93. package/dist/{chunk-QQYUWTYS.js → chunk-TDOKDCFH.js} +3 -3
  94. package/dist/chunk-UFJS4RR7.js +266 -0
  95. package/dist/{chunk-AEXACKDR.js → chunk-US3IT6ZC.js} +3 -3
  96. package/dist/{chunk-4QD7VE4E.js → chunk-UTJ5465F.js} +2 -2
  97. package/dist/{chunk-M7NX25ZA.js → chunk-UVZK5LIK.js} +1 -1
  98. package/dist/{chunk-IUOUNRLH.js → chunk-V3PDUDPB.js} +2 -2
  99. package/dist/{chunk-K5SDLOFS.js → chunk-VAJHDTJX.js} +11 -11
  100. package/dist/{chunk-QTCFEKLJ.js → chunk-W47WL6JY.js} +1 -1
  101. package/dist/{chunk-6QM54CSJ.js → chunk-WW24SG27.js} +5 -5
  102. package/dist/{chunk-3TJLPABQ.js → chunk-WWAVHLGS.js} +3 -3
  103. package/dist/{chunk-CUEUANIU.js → chunk-X4ES7QBT.js} +5 -5
  104. package/dist/{chunk-XXNT4FGA.js → chunk-XGP5VSQG.js} +1 -1
  105. package/dist/{chunk-LW7IWGSV.js → chunk-YQVKG5MC.js} +5 -5
  106. package/dist/{codex-app-cards-switch-SVGTZ2UN.js → codex-app-cards-switch-N77RWKCO.js} +21 -19
  107. package/dist/{codex-desktop-launch-SH7OUEEC.js → codex-desktop-launch-KIX7OMTL.js} +3 -1
  108. package/dist/{codex-session-launch-IQ57OL3N.js → codex-session-launch-XV7SIIWP.js} +18 -18
  109. package/dist/{config-SYLUYZQE.js → config-HH4DYYNX.js} +3 -3
  110. package/dist/global-upgrade-YWIVJIUR.js +34 -0
  111. package/dist/{identity-6KRUO2YO.js → identity-4J7Y2MW3.js} +4 -4
  112. package/dist/{live-capabilities-RKUHAWT6.js → live-capabilities-LHZBCI5U.js} +4 -4
  113. package/dist/{paths-MUPQZNLG.js → paths-ES3V7BWQ.js} +5 -3
  114. package/dist/{reapply-YZXZCWCI.js → reapply-KA5SIYWX.js} +26 -26
  115. package/dist/src/index.js +21 -21
  116. package/dist/{upgrade-lock-JXP27UKI.js → upgrade-lock-TJPKU5HL.js} +4 -6
  117. package/dist/{usage-OUV76AIY.js → usage-7ALXBJVJ.js} +3 -3
  118. package/package.json +1 -1
  119. package/dist/global-upgrade-SRCWQE7N.js +0 -26
@@ -26,30 +26,46 @@ import { join, resolve } from "path";
26
26
  import { spawn } from "child_process";
27
27
  import { Transform } from "stream";
28
28
 
29
- // src/codex-app-card.ts
29
+ // src/codex-permission-form.ts
30
30
  var CODEX_APP_CARD_METHOD = "mcpServer/elicitation/request";
31
+ var TOOL_CALL_APPROVAL = "mcp_tool_call";
32
+ var MAX_IDENTIFIER_LENGTH = 200;
33
+ var CODEX_COMPUTER_USE_SERVER = "cua_repl";
34
+ var CODEX_BROWSER_SERVER = "node_repl";
35
+ var CODEX_SHOWS_THE_SAME_QUESTION = "Codex is showing the same question on your Mac.";
36
+ var ONE_PRINTABLE_LINE = /^[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}]+$/u;
37
+ var CODEX_FORM_DECLINED = { action: "decline", content: null, _meta: null };
38
+ var isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
39
+ var isRequestId = (value) => typeof value === "string" && value.length > 0 && value.length <= MAX_IDENTIFIER_LENGTH || typeof value === "number" && Number.isSafeInteger(value);
40
+ var isIdentifier = (value) => typeof value === "string" && value.length > 0 && value.length <= MAX_IDENTIFIER_LENGTH;
41
+ var asksForNothingToFillIn = (schema) => isRecord(schema) && isRecord(schema.properties) && Object.keys(schema.properties).length === 0;
42
+ var codexPermissionFormOf = (message) => {
43
+ if (!isRecord(message) || message.method !== CODEX_APP_CARD_METHOD || !isRequestId(message.id)) return null;
44
+ const params = message.params;
45
+ if (!isRecord(params) || !isIdentifier(params.threadId)) return null;
46
+ if (typeof params.serverName !== "string" || typeof params.mode !== "string" || typeof params.message !== "string") return null;
47
+ if (!asksForNothingToFillIn(params.requestedSchema)) return null;
48
+ const meta = params._meta;
49
+ if (!isRecord(meta) || meta.codex_approval_kind !== TOOL_CALL_APPROVAL) return null;
50
+ return { requestId: message.id, threadId: params.threadId, serverName: params.serverName, mode: params.mode, sentence: params.message, meta };
51
+ };
52
+ 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
+
54
+ // src/codex-app-card.ts
31
55
  var CODEX_REQUEST_RESOLVED_METHOD = "serverRequest/resolved";
32
- var COMPUTER_USE_SERVER = "cua_repl";
33
56
  var COMPUTER_USE_CONNECTOR = "computer-use";
34
- var TOOL_CALL_APPROVAL = "mcp_tool_call";
35
57
  var CONVERSATION_GRANT = "session";
36
58
  var FORM_MODES = ["form", "openai/form", "openaiForm"];
37
59
  var APP_PARAMETER = "app";
38
- var MAX_IDENTIFIER_LENGTH = 200;
39
60
  var MAX_APP_NAME_LENGTH = 100;
40
61
  var MAX_CARDS_ANSWERED_ON_THE_PHONE = 64;
41
62
  var APP_LINES_A_LATE_REPLY_CAN_FOLLOW = 256;
42
- var ONE_PRINTABLE_LINE = /^[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}]+$/u;
43
63
  var APP_IDENTIFIER = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
44
64
  var RISK_LEVELS = ["low", "medium", "high"];
45
65
  var PHONE_ANSWER_YES = "yes";
46
66
  var PHONE_ANSWER_NO = "no";
47
67
  var ALLOW_THIS_CONVERSATION = { action: "accept", content: {}, _meta: { persist: CONVERSATION_GRANT } };
48
- var DENY = { action: "decline", content: null, _meta: null };
49
- var isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
50
- var isRequestId = (value) => typeof value === "string" && value.length > 0 && value.length <= MAX_IDENTIFIER_LENGTH || typeof value === "number" && Number.isSafeInteger(value);
51
- var isIdentifier = (value) => typeof value === "string" && value.length > 0 && value.length <= MAX_IDENTIFIER_LENGTH;
52
- var asksForNothingToFillIn = (schema) => isRecord(schema) && isRecord(schema.properties) && Object.keys(schema.properties).length === 0;
68
+ var DENY = CODEX_FORM_DECLINED;
53
69
  var offersAConversationGrant = (persist) => Array.isArray(persist) && persist.includes(CONVERSATION_GRANT);
54
70
  var isTheAppParameter = (entry) => isRecord(entry) && entry.name === APP_PARAMETER;
55
71
  var appNameShownBy = (meta) => {
@@ -64,25 +80,20 @@ var appIdentifierIn = (meta) => {
64
80
  var riskIn = (meta) => RISK_LEVELS.find((level) => level === meta.riskLevel) ?? null;
65
81
  var wordingCodexShowsFor = (appName) => `Allow Computer Use to use "${appName}"?`;
66
82
  var codexAppCardOf = (message) => {
67
- if (!isRecord(message) || message.method !== CODEX_APP_CARD_METHOD || !isRequestId(message.id)) return null;
68
- const params = message.params;
69
- if (!isRecord(params) || !isIdentifier(params.threadId) || params.serverName !== COMPUTER_USE_SERVER) return null;
70
- if (typeof params.mode !== "string" || !FORM_MODES.includes(params.mode)) return null;
71
- if (!asksForNothingToFillIn(params.requestedSchema)) return null;
72
- const meta = params._meta;
73
- if (!isRecord(meta) || meta.connector_id !== COMPUTER_USE_CONNECTOR || meta.codex_approval_kind !== TOOL_CALL_APPROVAL) return null;
74
- if (!offersAConversationGrant(meta.persist)) return null;
75
- const appName = appNameShownBy(meta);
76
- if (appName === null || params.message !== wordingCodexShowsFor(appName)) return null;
83
+ const form = codexPermissionFormOf(message);
84
+ if (!form || form.serverName !== CODEX_COMPUTER_USE_SERVER || !FORM_MODES.includes(form.mode)) return null;
85
+ if (form.meta.connector_id !== COMPUTER_USE_CONNECTOR || !offersAConversationGrant(form.meta.persist)) return null;
86
+ const appName = appNameShownBy(form.meta);
87
+ if (appName === null || form.sentence !== wordingCodexShowsFor(appName)) return null;
77
88
  return {
78
- requestId: message.id,
79
- threadId: params.threadId,
89
+ requestId: form.requestId,
90
+ threadId: form.threadId,
80
91
  appName,
81
- appIdentifier: appIdentifierIn(meta),
82
- risk: riskIn(meta)
92
+ appIdentifier: appIdentifierIn(form.meta),
93
+ risk: riskIn(form.meta)
83
94
  };
84
95
  };
85
- var comesFromComputerUse = (message) => isRecord(message) && message.method === CODEX_APP_CARD_METHOD && isRecord(message.params) && message.params.serverName === COMPUTER_USE_SERVER;
96
+ var comesFromComputerUse = (message) => codexFormCameFrom(message, [CODEX_COMPUTER_USE_SERVER]);
86
97
  var codexRequestResolvedBy = (message) => {
87
98
  if (!isRecord(message) || message.method !== CODEX_REQUEST_RESOLVED_METHOD || !isRecord(message.params)) return null;
88
99
  return isRequestId(message.params.requestId) ? message.params.requestId : null;
@@ -92,7 +103,7 @@ var codexAppCardQuestion = (card) => `Allow Codex to use ${card.appName} for thi
92
103
  var codexAppCardContext = (card) => [
93
104
  card.appIdentifier ? `App: ${card.appName} (${card.appIdentifier})` : `App: ${card.appName}`,
94
105
  ...card.risk ? [`Risk Codex reports: ${card.risk}`] : [],
95
- "Codex is showing the same question on your Mac. Yes allows this app for this conversation only."
106
+ `${CODEX_SHOWS_THE_SAME_QUESTION} Yes allows this app for this conversation only.`
96
107
  ].join("\n");
97
108
  var codexAppCardDecisionOf = (phoneAnswer) => {
98
109
  if (phoneAnswer === PHONE_ANSWER_YES) return "allow";
@@ -165,7 +176,127 @@ var CodexAppCardLedger = class {
165
176
  }
166
177
  };
167
178
 
179
+ // src/codex-browser-use-card.ts
180
+ var BROWSER_USE_SERVERS = [CODEX_COMPUTER_USE_SERVER, CODEX_BROWSER_SERVER];
181
+ var BROWSER_USE_CONNECTOR = "browser-use";
182
+ var PLAIN_FORM = "form";
183
+ var SITE_ACCESS_TOOL = "access_browser_origin";
184
+ var TRANSFER_TOOLS = { download: "download_browser_files", upload: "upload_browser_files" };
185
+ var TRANSFER_WORDING = {
186
+ download: { before: "Allow download from ", after: "?" },
187
+ upload: { before: "Allow upload to ", after: "?" }
188
+ };
189
+ var WEB_PROTOCOLS = ["http:", "https:"];
190
+ var BROWSER_NAMES = ["Browser use", "Cloud browser"];
191
+ var MAX_ORIGIN_LENGTH = 100;
192
+ var MAX_PAGE_LENGTH = 2e3;
193
+ var MAX_ADDRESS_SHOWN = 240;
194
+ var CUT_SHORT = "\u2026";
195
+ var WHAT_AN_ANSWER_DOES = {
196
+ site_access: `${CODEX_SHOWS_THE_SAME_QUESTION} Yes allows this site for the rest of this conversation, or only this turn if Codex is set to ask each turn. No blocks it for this conversation.`,
197
+ file_transfer: `${CODEX_SHOWS_THE_SAME_QUESTION} It shows the whole address. Yes allows it once and saves nothing.`
198
+ };
199
+ var ACCEPTED_WITH_NO_SAVED_CHOICE = { action: "accept", content: {}, _meta: null };
200
+ var webAddressOf = (text, longest) => {
201
+ if (text.length === 0 || text.length > longest || !ONE_PRINTABLE_LINE.test(text) || !URL.canParse(text)) return null;
202
+ const address = new URL(text);
203
+ return WEB_PROTOCOLS.includes(address.protocol) ? address : null;
204
+ };
205
+ var isOneWebOrigin = (value) => typeof value === "string" && webAddressOf(value, MAX_ORIGIN_LENGTH)?.origin === value;
206
+ var originAskedAbout = (meta) => {
207
+ const origin = meta.origin;
208
+ if (!isOneWebOrigin(origin)) return null;
209
+ return isRecord(meta.tool_params) && meta.tool_params.origin === origin ? origin : null;
210
+ };
211
+ var cleanAddressOn = (origin, page) => {
212
+ const address = webAddressOf(page, MAX_PAGE_LENGTH);
213
+ if (address === null || address.origin !== origin || address.username !== "" || address.password !== "") return null;
214
+ return address.href === page || address.origin === page ? address : null;
215
+ };
216
+ var addressToShow = (address) => {
217
+ const upToThePath = `${address.origin}${address.pathname}`;
218
+ const isWhole = address.href === upToThePath && upToThePath.length <= MAX_ADDRESS_SHOWN;
219
+ return isWhole ? upToThePath : `${upToThePath.slice(0, MAX_ADDRESS_SHOWN - CUT_SHORT.length)}${CUT_SHORT}`;
220
+ };
221
+ var isAKnownBrowserName = (value) => typeof value === "string" && BROWSER_NAMES.includes(value);
222
+ var siteAccessSentence = (browserName, origin) => `Allow ${browserName} to access ${origin}?`;
223
+ var siteAccessCardOf = (form, browserName, origin) => {
224
+ if (form.meta.tool_name !== SITE_ACCESS_TOOL || form.sentence !== siteAccessSentence(browserName, origin)) return null;
225
+ return { kind: "site_access", requestId: form.requestId, threadId: form.threadId, origin };
226
+ };
227
+ var isAFileTransfer = (value) => typeof value === "string" && Object.hasOwn(TRANSFER_TOOLS, value);
228
+ var pageNamedIn = (sentence, transfer) => {
229
+ const { before, after } = TRANSFER_WORDING[transfer];
230
+ if (!sentence.startsWith(before) || !sentence.endsWith(after)) return null;
231
+ return sentence.slice(before.length, sentence.length - after.length);
232
+ };
233
+ var fileTransferCardOf = (form, origin) => {
234
+ const transfer = form.meta.file_transfer;
235
+ if (!isAFileTransfer(transfer) || form.meta.tool_name !== TRANSFER_TOOLS[transfer]) return null;
236
+ const page = pageNamedIn(form.sentence, transfer);
237
+ const address = page === null ? null : cleanAddressOn(origin, page);
238
+ if (address === null) return null;
239
+ return { kind: "file_transfer", requestId: form.requestId, threadId: form.threadId, transfer, origin, addressShown: addressToShow(address) };
240
+ };
241
+ var codexBrowserUseCardOf = (message) => {
242
+ const form = codexPermissionFormOf(message);
243
+ if (!form || !BROWSER_USE_SERVERS.includes(form.serverName) || form.mode !== PLAIN_FORM) return null;
244
+ if (form.meta.connector_id !== BROWSER_USE_CONNECTOR) return null;
245
+ const browserName = form.meta.connector_name;
246
+ const origin = originAskedAbout(form.meta);
247
+ if (!isAKnownBrowserName(browserName) || origin === null) return null;
248
+ return siteAccessCardOf(form, browserName, origin) ?? fileTransferCardOf(form, origin);
249
+ };
250
+ var comesFromBrowserUse = (message) => codexFormCameFrom(message, BROWSER_USE_SERVERS);
251
+ var siteNameOf = (origin) => new URL(origin).host;
252
+ var TRANSFER_QUESTIONS = {
253
+ download: (site) => `Allow Codex to download from ${site}?`,
254
+ upload: (site) => `Allow Codex to upload files to ${site}?`
255
+ };
256
+ var codexBrowserUseCardQuestion = (card) => {
257
+ const site = siteNameOf(card.origin);
258
+ if (card.kind === "site_access") return `Allow Codex to access ${site} for this conversation?`;
259
+ return TRANSFER_QUESTIONS[card.transfer](site);
260
+ };
261
+ var codexBrowserUseCardContext = (card) => [
262
+ card.kind === "file_transfer" ? `Address: ${card.addressShown}` : `Site: ${card.origin}`,
263
+ WHAT_AN_ANSWER_DOES[card.kind]
264
+ ].join("\n");
265
+ var codexBrowserUseCardSubject = (card) => siteNameOf(card.origin);
266
+ var codexBrowserUseCardReply = (requestId, decision) => ({
267
+ id: requestId,
268
+ result: decision === "allow" ? ACCEPTED_WITH_NO_SAVED_CHOICE : CODEX_FORM_DECLINED
269
+ });
270
+
271
+ // src/codex-card.ts
272
+ var codexCardOf = (message) => {
273
+ const app = codexAppCardOf(message);
274
+ return app ? { kind: "app", ...app } : codexBrowserUseCardOf(message);
275
+ };
276
+ var comesFromCodexOwnTools = (message) => comesFromComputerUse(message) || comesFromBrowserUse(message);
277
+ 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);
282
+
283
+ // src/load-once.ts
284
+ var loadedOnce = (load) => {
285
+ let loading;
286
+ const forgetAFailedLoad = (error) => {
287
+ loading = void 0;
288
+ throw error;
289
+ };
290
+ return () => {
291
+ loading ??= load().catch(forgetAFailedLoad);
292
+ return loading;
293
+ };
294
+ };
295
+
168
296
  // src/codex-desktop-proxy.ts
297
+ var loadThePhone = () => import("./api-UVJGNZIF.js");
298
+ var theFirstCardLoadsAgain = () => {
299
+ };
169
300
  var APP_SERVER_COMMAND = "app-server";
170
301
  var CONFIG_FLAGS = ["-c", "--config"];
171
302
  var CONFIG_FLAG_PREFIXES = ["-c=", "--config="];
@@ -184,9 +315,10 @@ var WITHDRAW_TIMEOUT_MS = 4e3;
184
315
  var CLOSE_GRACE_MS = 1500;
185
316
  var ENGINE_KILL_GRACE_MS = 2e3;
186
317
  var ENGINE_EXIT_GRACE_MS = 5e3;
187
- var QUESTION_IN_AN_UNKNOWN_SHAPE = "Codex asked about Computer Use in a way this version of Pushary does not know, so the question stays in Codex.";
318
+ var QUESTION_IN_AN_UNKNOWN_SHAPE = "Codex asked for a permission in a way this version of Pushary does not know, so the question stays in Codex.";
188
319
  var LAUNCHER_CHECK_MS = 2e3;
189
- var USUAL_TIMING = { answerWindowMs: 10 * 6e4, longPollMs: 25e3, pauseBetweenPollsMs: 2e3 };
320
+ var WAIT_FOR_CODEX_TO_ANSWER_SITE_ACCESS_ITSELF_MS = 500;
321
+ var USUAL_TIMING = { answerWindowMs: 10 * 6e4, longPollMs: 25e3, pauseBetweenPollsMs: 2e3, letCodexAnswerFirstMs: WAIT_FOR_CODEX_TO_ANSWER_SITE_ACCESS_ITSELF_MS };
190
322
  var subcommandIndexOf = (args) => {
191
323
  let index = 0;
192
324
  while (index < args.length) {
@@ -332,10 +464,12 @@ var CodexAppCards = class {
332
464
  constructor(options) {
333
465
  this.options = options;
334
466
  this.timing = options.timing ?? USUAL_TIMING;
467
+ this.thePhone = loadedOnce(options.loadPhone ?? loadThePhone);
468
+ void this.thePhone().catch(theFirstCardLoadsAgain);
335
469
  }
336
470
  ledger = new CodexAppCardLedger();
337
471
  questions = /* @__PURE__ */ new Map();
338
- phone;
472
+ thePhone;
339
473
  stoodDown = false;
340
474
  saidAQuestionWasUnknown = false;
341
475
  timing;
@@ -376,17 +510,13 @@ var CodexAppCards = class {
376
510
  for (const question of outstanding) question.waiting.abort();
377
511
  await Promise.allSettled(outstanding.map((question) => this.cancel(question)));
378
512
  }
379
- thePhone() {
380
- this.phone ??= import("./api-RQAY3A5V.js");
381
- return this.phone;
382
- }
383
513
  questionShown(message) {
384
- const card = codexAppCardOf(message);
514
+ const card = codexCardOf(message);
385
515
  if (card) {
386
516
  if (this.ledger.open(card.requestId)) void this.askThePhone(card);
387
517
  return;
388
518
  }
389
- if (this.saidAQuestionWasUnknown || !comesFromComputerUse(message)) return;
519
+ if (this.saidAQuestionWasUnknown || !comesFromCodexOwnTools(message)) return;
390
520
  this.saidAQuestionWasUnknown = true;
391
521
  this.options.report(QUESTION_IN_AN_UNKNOWN_SHAPE);
392
522
  }
@@ -395,6 +525,8 @@ var CodexAppCards = class {
395
525
  }
396
526
  async askThePhone(card) {
397
527
  try {
528
+ if (codexAppMayAnswerItself(card)) await pauseUnlessStopped(this.timing.letCodexAnswerFirstMs, this.options.signal);
529
+ if (this.options.signal.aborted || !this.ledger.isWaiting(card.requestId)) return;
398
530
  const account = await this.options.readAccount();
399
531
  if (!account) {
400
532
  this.ledger.leaveWithTheApp(card.requestId);
@@ -404,9 +536,9 @@ var CodexAppCards = class {
404
536
  if (!this.ledger.isWaiting(card.requestId)) return;
405
537
  const answerableUntil = Date.now() + this.timing.answerWindowMs;
406
538
  const asked = await phone.askUser(account.apiKey, {
407
- question: codexAppCardQuestion(card),
539
+ question: codexCardQuestion(card),
408
540
  type: "confirm",
409
- context: codexAppCardContext(card),
541
+ context: codexCardContext(card),
410
542
  agentName: CODEX_APP_AGENT_NAME,
411
543
  sessionId: card.threadId,
412
544
  machineId: account.machineId,
@@ -430,7 +562,7 @@ var CodexAppCards = class {
430
562
  await this.waitForThePhone(phone, card, question);
431
563
  } catch (error) {
432
564
  if (this.ledger.leaveWithTheApp(card.requestId)) {
433
- this.options.report(`Could not ask about ${card.appName} through Pushary; answer in Codex. ${error instanceof Error ? error.message.split("\n")[0] : ""}`.trim());
565
+ this.options.report(`Could not ask about ${codexCardSubject(card)} through Pushary; answer in Codex. ${error instanceof Error ? error.message.split("\n")[0] : ""}`.trim());
434
566
  }
435
567
  }
436
568
  }
@@ -472,7 +604,7 @@ var CodexAppCards = class {
472
604
  this.ledger.leaveWithTheApp(card.requestId);
473
605
  return;
474
606
  }
475
- if (this.ledger.settleOnThePhone(card.requestId)) this.options.reply(codexAppCardReply(card.requestId, decision));
607
+ if (this.ledger.settleOnThePhone(card.requestId)) this.options.reply(codexCardReply(card, decision));
476
608
  }
477
609
  withdraw(requestId) {
478
610
  const key = codexRequestKey(requestId);
@@ -695,7 +827,7 @@ var codexDesktopCommand = async (args, entry, readAccount) => {
695
827
  return runCodexDesktopProxy(engine2, args.slice(3), readAccount, { watchesForCards: layoutIsKnown });
696
828
  }
697
829
  if (args[0] === APP_CARDS_FLAG) {
698
- const { codexAppCardsCommandOnThisMac } = await import("./codex-app-cards-switch-SVGTZ2UN.js");
830
+ const { codexAppCardsCommandOnThisMac } = await import("./codex-app-cards-switch-N77RWKCO.js");
699
831
  return codexAppCardsCommandOnThisMac(args.slice(1), entry, readAccount);
700
832
  }
701
833
  if (args.length > 2) throw new Error("Usage: pushary codex --desktop [path/to/Codex.app]");
@@ -706,7 +838,7 @@ var codexDesktopCommand = async (args, entry, readAccount) => {
706
838
  const directory = await mkdtemp(join(tmpdir(), "pushary-codex-desktop-"));
707
839
  try {
708
840
  const shim = await writeDesktopProxy(entry, app, engine, directory);
709
- process.stderr.write("[pushary] Experimental Codex app launch. When Codex asks to use an app on this Mac, the question also reaches Pushary; every other prompt stays as it is. Quit and open Codex normally to turn this off.\n");
841
+ 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");
710
842
  const child = spawn2(executable, [], { stdio: "ignore", detached: true, env: { ...process.env, [CODEX_APP_LAUNCH_VARIABLE]: shim } });
711
843
  return await new Promise((resolve2, reject) => {
712
844
  child.once("error", reject);
@@ -719,6 +851,7 @@ var codexDesktopCommand = async (args, entry, readAccount) => {
719
851
 
720
852
  export {
721
853
  shellQuoted,
854
+ LAUNCHCTL,
722
855
  desktopEngineFromManifest,
723
856
  everyProgramFileIsThere,
724
857
  desktopProxyScript,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readTranscriptPreference
3
- } from "./chunk-IRZ5FVWG.js";
3
+ } from "./chunk-KAJDKYUM.js";
4
4
 
5
5
  // src/transcript-setting.ts
6
6
  var transcriptEnvironmentPreference = () => {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  APPROVAL_SETTINGS_PATH
3
- } from "./chunk-K45CFSYV.js";
3
+ } from "./chunk-DS7X36Z3.js";
4
4
  import {
5
5
  readMacAppAgentKey
6
- } from "./chunk-OLNBYAPI.js";
6
+ } from "./chunk-EHCIQA5D.js";
7
7
  import {
8
8
  findExportedKeyLines,
9
9
  isAdoptedMacAppKey,
@@ -13,13 +13,13 @@ import {
13
13
  readConfigFileKey,
14
14
  readKeySource,
15
15
  readMacAppKeyPrefix
16
- } from "./chunk-IRZ5FVWG.js";
16
+ } from "./chunk-KAJDKYUM.js";
17
17
  import {
18
18
  absoluteUrl
19
- } from "./chunk-FBKVCODG.js";
19
+ } from "./chunk-MA37WNVS.js";
20
20
  import {
21
21
  isValidApiKey
22
- } from "./chunk-GZL3KEPC.js";
22
+ } from "./chunk-762CDAJJ.js";
23
23
 
24
24
  // src/key-revocation.ts
25
25
  var SELF_REVOKE_PATH = "/api/v1/server/keys/self/revoke";
@@ -2,25 +2,25 @@ import {
2
2
  SIGNED_OUT_ON_MAC_MESSAGE,
3
3
  describeSignedOutKey,
4
4
  readSignedOutDiagnosis
5
- } from "./chunk-4YNNAF53.js";
5
+ } from "./chunk-AY32RSUC.js";
6
6
  import {
7
7
  createIo
8
8
  } from "./chunk-FO3MDD26.js";
9
9
  import {
10
10
  readKeySource
11
- } from "./chunk-IRZ5FVWG.js";
11
+ } from "./chunk-KAJDKYUM.js";
12
12
  import {
13
13
  absoluteUrl,
14
14
  checkApiKey,
15
15
  describeKeyCheck,
16
16
  keyCheckFromResponse
17
- } from "./chunk-FBKVCODG.js";
17
+ } from "./chunk-MA37WNVS.js";
18
18
  import {
19
19
  EXIT
20
20
  } from "./chunk-KZERVKTD.js";
21
21
  import {
22
22
  getBaseUrl
23
- } from "./chunk-LVDC3RUE.js";
23
+ } from "./chunk-4XXZUFWN.js";
24
24
 
25
25
  // src/cli/report-key.ts
26
26
  var { dim, yellow } = createIo();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ensureCodexTrustsPusharyHooks
3
- } from "./chunk-2NIRYGTK.js";
3
+ } from "./chunk-IBXHVYN2.js";
4
4
  import {
5
5
  CODEX_INSTRUCTIONS_LABEL,
6
6
  GEMINI_INSTRUCTIONS_LABEL,
@@ -11,7 +11,7 @@ import {
11
11
  macAppFxBridge,
12
12
  refreshInstructionBlock,
13
13
  renderAgentInstructions
14
- } from "./chunk-NQDEMRAS.js";
14
+ } from "./chunk-6ONSTCDJ.js";
15
15
  import {
16
16
  OPENCODE_HOOK_BINARY,
17
17
  agentHookOwner,
@@ -21,10 +21,10 @@ import {
21
21
  openCodeInstructionsFile,
22
22
  openCodePluginDir,
23
23
  openCodeWired
24
- } from "./chunk-PZDMZ7LM.js";
24
+ } from "./chunk-JBCMXSBO.js";
25
25
  import {
26
26
  detectClaudeVersion
27
- } from "./chunk-LVWXRXT7.js";
27
+ } from "./chunk-M6MOQBR5.js";
28
28
  import {
29
29
  addClaudeMcpServer,
30
30
  addCompatibleHooks,
@@ -33,7 +33,7 @@ import {
33
33
  compatibleConfigFile,
34
34
  compatibleInstructionsFile,
35
35
  hasCompatibleHooks
36
- } from "./chunk-UPFFO4F6.js";
36
+ } from "./chunk-KQWN7C5C.js";
37
37
  import {
38
38
  claudeUnprovenHolds,
39
39
  claudeWired,
@@ -41,7 +41,7 @@ import {
41
41
  codexWired,
42
42
  geminiWired,
43
43
  planHooks
44
- } from "./chunk-CUEUANIU.js";
44
+ } from "./chunk-X4ES7QBT.js";
45
45
  import {
46
46
  CLAUDE_HOOK_BINARY,
47
47
  CLAUDE_HOOK_EVENTS,
@@ -52,7 +52,7 @@ import {
52
52
  needsReregistration,
53
53
  registrationSignatures,
54
54
  supportedClaudeEvents
55
- } from "./chunk-QQYUWTYS.js";
55
+ } from "./chunk-TDOKDCFH.js";
56
56
  import {
57
57
  formatVersion
58
58
  } from "./chunk-6ICPEJY5.js";
@@ -80,11 +80,11 @@ import {
80
80
  registeredCommands,
81
81
  registrationHolderOf,
82
82
  vscodePluginMcp
83
- } from "./chunk-TWLWDIFB.js";
83
+ } from "./chunk-KZCYHWDF.js";
84
84
  import {
85
85
  resolveGlobalBinDir,
86
86
  resolveGlobalBinary
87
- } from "./chunk-AEXACKDR.js";
87
+ } from "./chunk-US3IT6ZC.js";
88
88
  import {
89
89
  readJsonSafe,
90
90
  writeFileAtomic,
@@ -94,7 +94,7 @@ import {
94
94
  HOOK_COMPATIBLE_PROFILES,
95
95
  isCompatibleAgentType,
96
96
  isRecord
97
- } from "./chunk-GZL3KEPC.js";
97
+ } from "./chunk-762CDAJJ.js";
98
98
 
99
99
  // src/reapply.ts
100
100
  import { dirname, join } from "path";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  macAppBridgeAvailable
3
- } from "./chunk-PZDMZ7LM.js";
3
+ } from "./chunk-JBCMXSBO.js";
4
4
  import {
5
5
  keyPrefix
6
- } from "./chunk-IRZ5FVWG.js";
6
+ } from "./chunk-KAJDKYUM.js";
7
7
  import {
8
8
  bridgeAgentKey
9
- } from "./chunk-TWLWDIFB.js";
9
+ } from "./chunk-KZCYHWDF.js";
10
10
  import {
11
11
  readJsonSafe
12
12
  } from "./chunk-QENTGE75.js";
13
13
  import {
14
14
  isValidApiKey
15
- } from "./chunk-GZL3KEPC.js";
15
+ } from "./chunk-762CDAJJ.js";
16
16
 
17
17
  // src/shared-mcp-key.ts
18
18
  var asRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
@@ -7,10 +7,10 @@ import {
7
7
  codexHome,
8
8
  codexHooksJsonIn,
9
9
  isPusharyCodexCommand
10
- } from "./chunk-TWLWDIFB.js";
10
+ } from "./chunk-KZCYHWDF.js";
11
11
  import {
12
12
  resolvePathBinary
13
- } from "./chunk-AEXACKDR.js";
13
+ } from "./chunk-US3IT6ZC.js";
14
14
  import {
15
15
  getPackageVersion
16
16
  } from "./chunk-QTOLNRET.js";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  readExistingMachineId
3
- } from "./chunk-SQ5G6A6K.js";
3
+ } from "./chunk-M46WDK64.js";
4
4
  import {
5
5
  NetworkError
6
6
  } from "./chunk-7QLSKOSU.js";
7
7
  import {
8
8
  getBaseUrl
9
- } from "./chunk-LVDC3RUE.js";
9
+ } from "./chunk-4XXZUFWN.js";
10
10
  import {
11
11
  getPackageVersion
12
12
  } from "./chunk-QTOLNRET.js";
13
13
  import {
14
14
  clientContextHeaders
15
- } from "./chunk-GZL3KEPC.js";
15
+ } from "./chunk-762CDAJJ.js";
16
16
 
17
17
  // src/cli/net.ts
18
18
  import { createRequire } from "module";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  compatibleConfigFile
3
- } from "./chunk-UPFFO4F6.js";
3
+ } from "./chunk-KQWN7C5C.js";
4
4
  import {
5
5
  hookOwnerOf,
6
6
  hookOwnerOfCommands,
7
7
  liveBridgeProbe,
8
8
  resolveBridgeStub
9
- } from "./chunk-CUEUANIU.js";
9
+ } from "./chunk-X4ES7QBT.js";
10
10
  import {
11
11
  AGENT_CHOICES
12
- } from "./chunk-ECJJKDP7.js";
12
+ } from "./chunk-75UYYIFJ.js";
13
13
  import {
14
14
  claudeSettings,
15
15
  codexHooksJson,
@@ -18,7 +18,7 @@ import {
18
18
  guardedArgv,
19
19
  pusharyDir,
20
20
  vscodePluginDir
21
- } from "./chunk-TWLWDIFB.js";
21
+ } from "./chunk-KZCYHWDF.js";
22
22
  import {
23
23
  readJsonSafe
24
24
  } from "./chunk-QENTGE75.js";
@@ -29,7 +29,7 @@ import {
29
29
  OPENCODE_APPROVAL_EVENT,
30
30
  hookCompatibleProfile,
31
31
  isRecord
32
- } from "./chunk-GZL3KEPC.js";
32
+ } from "./chunk-762CDAJJ.js";
33
33
 
34
34
  // src/opencode-plugin.ts
35
35
  var OPENCODE_PLUGIN_MARKER = "pushary-opencode-plugin w1";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveInstallSourceFor
3
- } from "./chunk-7RZO6VWD.js";
3
+ } from "./chunk-3RKIJM26.js";
4
4
  import {
5
5
  backupFile,
6
6
  readJsonSafe,
@@ -9,11 +9,11 @@ import {
9
9
  } from "./chunk-QENTGE75.js";
10
10
  import {
11
11
  configFilePath
12
- } from "./chunk-LVDC3RUE.js";
12
+ } from "./chunk-4XXZUFWN.js";
13
13
  import {
14
14
  API_KEY_PREFIX_PATTERN,
15
15
  isRecord
16
- } from "./chunk-GZL3KEPC.js";
16
+ } from "./chunk-762CDAJJ.js";
17
17
 
18
18
  // src/shell-alias.ts
19
19
  import { homedir } from "os";
@@ -3,24 +3,24 @@ import {
3
3
  expectedLaunchCapabilities,
4
4
  hasSpawnProvider,
5
5
  resolveControlPolicy
6
- } from "./chunk-DDQRYX2L.js";
6
+ } from "./chunk-5PP4455M.js";
7
7
  import {
8
8
  daemonHasRemoteProof,
9
9
  daemonServiceManagerAvailable,
10
10
  hasDaemonServiceDefinition,
11
11
  readDaemonNeedsLogin,
12
12
  readDaemonStatus
13
- } from "./chunk-Z7Q36I4K.js";
13
+ } from "./chunk-4QF2YLYK.js";
14
14
  import {
15
15
  readControlMode,
16
16
  readKeySource
17
- } from "./chunk-IRZ5FVWG.js";
17
+ } from "./chunk-KAJDKYUM.js";
18
18
  import {
19
19
  getMachineId
20
- } from "./chunk-SQ5G6A6K.js";
20
+ } from "./chunk-M46WDK64.js";
21
21
  import {
22
22
  getBaseUrl
23
- } from "./chunk-LVDC3RUE.js";
23
+ } from "./chunk-4XXZUFWN.js";
24
24
  import {
25
25
  getPackageVersion
26
26
  } from "./chunk-QTOLNRET.js";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  registerTranscript
3
- } from "./chunk-W6363YYZ.js";
3
+ } from "./chunk-2WMZDKPM.js";
4
4
  import {
5
5
  namedEvent
6
- } from "./chunk-UPFFO4F6.js";
6
+ } from "./chunk-KQWN7C5C.js";
7
7
  import {
8
8
  writeDegraded
9
- } from "./chunk-6QM54CSJ.js";
9
+ } from "./chunk-WW24SG27.js";
10
10
  import {
11
11
  claudeShapedHookInput,
12
12
  hookCompatibleProfileBySource,
13
13
  isGrokHookPayload,
14
14
  isGrokSessionEndStop
15
- } from "./chunk-GZL3KEPC.js";
15
+ } from "./chunk-762CDAJJ.js";
16
16
 
17
17
  // src/tool-hook-input.ts
18
18
  var OPTIONAL_TEXT_FIELDS = ["hook_event_name", "session_id", "cwd", "transcript_path", "tool_use_id", "permission_mode"];