@pushary/agent-hooks 1.9.65 → 1.9.66

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 (123) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/{api-32B3XLJR.js → api-GDSVUTI2.js} +12 -10
  3. package/dist/bin/pushary-bell-hook.js +25 -27
  4. package/dist/bin/pushary-bell.js +10 -10
  5. package/dist/bin/pushary-claude.js +26 -28
  6. package/dist/bin/pushary-clean.js +34 -36
  7. package/dist/bin/pushary-codex-bridge.js +21 -22
  8. package/dist/bin/pushary-codex-hook.js +30 -32
  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 +25 -26
  12. package/dist/bin/pushary-cowork.js +5 -5
  13. package/dist/bin/pushary-daemon.js +37 -39
  14. package/dist/bin/pushary-disconnect.js +25 -26
  15. package/dist/bin/pushary-doctor.js +42 -44
  16. package/dist/bin/pushary-elicitation-hook.js +25 -27
  17. package/dist/bin/pushary-gemini-bridge.js +15 -16
  18. package/dist/bin/pushary-gemini-hook.js +27 -29
  19. package/dist/bin/pushary-hook.js +29 -31
  20. package/dist/bin/pushary-login.js +19 -19
  21. package/dist/bin/pushary-logout.js +25 -26
  22. package/dist/bin/pushary-mcp.js +11 -11
  23. package/dist/bin/pushary-mode.js +14 -14
  24. package/dist/bin/pushary-notification-hook.js +24 -26
  25. package/dist/bin/pushary-opencode-hook.js +26 -28
  26. package/dist/bin/pushary-permission-denied-hook.js +29 -31
  27. package/dist/bin/pushary-permission-hook.js +32 -31
  28. package/dist/bin/pushary-post-hook.js +24 -26
  29. package/dist/bin/pushary-prompt-hook.js +24 -26
  30. package/dist/bin/pushary-session-end-hook.js +26 -28
  31. package/dist/bin/pushary-session-start-hook.js +33 -35
  32. package/dist/bin/pushary-setup.js +47 -49
  33. package/dist/bin/pushary-stats.js +5 -5
  34. package/dist/bin/pushary-status.js +30 -31
  35. package/dist/bin/pushary-stop-hook.js +24 -26
  36. package/dist/bin/pushary-stopfailure-hook.js +24 -26
  37. package/dist/bin/pushary-suggestions.js +14 -14
  38. package/dist/bin/pushary-transcript-register.js +16 -18
  39. package/dist/bin/pushary-transcripts.js +17 -17
  40. package/dist/bin/pushary-upgrade.js +37 -38
  41. package/dist/bin/pushary-wait.js +14 -14
  42. package/dist/bin/pushary.js +7 -7
  43. package/dist/{chunk-FFSIYBBU.js → chunk-26W46E46.js} +4 -4
  44. package/dist/{chunk-3UNAPXED.js → chunk-2BL6KWN7.js} +9 -9
  45. package/dist/{chunk-GA257T2E.js → chunk-32ZT2ATY.js} +5 -5
  46. package/dist/{chunk-CSKABVSH.js → chunk-376TUN72.js} +3 -3
  47. package/dist/{chunk-6CZX6YOE.js → chunk-3ELJIG2R.js} +3 -3
  48. package/dist/{chunk-WY6YAMZW.js → chunk-3EZP5ZPS.js} +5 -4
  49. package/dist/{chunk-4LUWNBGD.js → chunk-3FQX74E4.js} +3 -3
  50. package/dist/{chunk-HVOQUPSO.js → chunk-45KMS76L.js} +1 -1
  51. package/dist/{chunk-JCWHOB36.js → chunk-4APD2DPI.js} +2 -2
  52. package/dist/{chunk-ADXHPGBZ.js → chunk-57NTMVMI.js} +6 -6
  53. package/dist/{chunk-W5L2ZLHE.js → chunk-5FJDODOA.js} +3 -3
  54. package/dist/{chunk-CZ65D6Q5.js → chunk-5J7OZBJ4.js} +2 -2
  55. package/dist/{chunk-XJIIU36L.js → chunk-6BGVSV2Q.js} +1 -1
  56. package/dist/{chunk-I2UBF2SS.js → chunk-6RJZSBPD.js} +1 -1
  57. package/dist/{chunk-QNZ6G3LY.js → chunk-6ZXCWK27.js} +5 -5
  58. package/dist/{chunk-P5HZEGT7.js → chunk-7LK3Y6ET.js} +6 -6
  59. package/dist/{chunk-Y64JGYTB.js → chunk-A47UKPC7.js} +1 -1
  60. package/dist/{chunk-JFKMPLNF.js → chunk-AVWECJSN.js} +2 -2
  61. package/dist/{chunk-XZCJC3QO.js → chunk-AWGBL4P3.js} +211 -24
  62. package/dist/{chunk-LMC5UPL7.js → chunk-B6JC676X.js} +1 -1
  63. package/dist/{chunk-U2P2LQ5B.js → chunk-CN6JFM62.js} +5 -5
  64. package/dist/{chunk-ED2SWTPC.js → chunk-CNJ7SI5V.js} +4 -4
  65. package/dist/{chunk-SZBMTOUZ.js → chunk-DBUHSUL7.js} +1 -1
  66. package/dist/{chunk-EEVE7H5Z.js → chunk-DIUTSF6I.js} +4 -4
  67. package/dist/{chunk-UM2X7HL6.js → chunk-DKMVVBXO.js} +13 -15
  68. package/dist/{chunk-OA6EADFT.js → chunk-DPU6H4JY.js} +3 -3
  69. package/dist/{chunk-MNKIR2ZB.js → chunk-EJR5JXMV.js} +24 -1
  70. package/dist/{chunk-VHKK3US3.js → chunk-EU2ZOZC3.js} +3 -3
  71. package/dist/{chunk-AN7C3CHH.js → chunk-G6VJZ3RB.js} +1 -1
  72. package/dist/{chunk-ATPJGHUP.js → chunk-GDLT32I4.js} +3 -3
  73. package/dist/{chunk-7ILQX47W.js → chunk-GECU7V44.js} +3 -3
  74. package/dist/{chunk-BAGBCSXA.js → chunk-GO7YKPT3.js} +1 -1
  75. package/dist/{chunk-F56GTJFG.js → chunk-GWYCKTXS.js} +5 -5
  76. package/dist/{chunk-BEQ3MEE3.js → chunk-HUGVJBDN.js} +2 -2
  77. package/dist/{chunk-FWS2KLV2.js → chunk-IA5VWIHV.js} +2 -2
  78. package/dist/{chunk-CU2PXLZ6.js → chunk-IGO3AGZK.js} +4 -4
  79. package/dist/{chunk-Z3M627TQ.js → chunk-IQ3GKPFM.js} +1 -1
  80. package/dist/{chunk-HDGB6SQ4.js → chunk-JL3SZJJP.js} +2 -2
  81. package/dist/{chunk-SCMEVDAR.js → chunk-KS3O6O7E.js} +3 -3
  82. package/dist/{chunk-HIYLAC3C.js → chunk-MDIGG3Q7.js} +3 -3
  83. package/dist/{chunk-ICFHMJTW.js → chunk-MNNQEUQC.js} +3 -3
  84. package/dist/{chunk-BKCI53W6.js → chunk-Q5RNYE2L.js} +4 -4
  85. package/dist/{chunk-ONBL2GCU.js → chunk-QBNICXMC.js} +6 -6
  86. package/dist/{chunk-PP7FC3Y7.js → chunk-QN25WBXL.js} +9 -7
  87. package/dist/{chunk-NUEPJ5W6.js → chunk-QOIPUYUD.js} +3 -5
  88. package/dist/{chunk-UHS5MMAI.js → chunk-QR2QWGQI.js} +3 -3
  89. package/dist/{chunk-NOH3EJFH.js → chunk-R7C2FS33.js} +1 -1
  90. package/dist/{chunk-RABLE5R6.js → chunk-RJ6JEHCP.js} +1 -1
  91. package/dist/{chunk-WOHP7EL6.js → chunk-RSZQEEEW.js} +6 -6
  92. package/dist/{chunk-Q2BD4IBX.js → chunk-SVKCYUYP.js} +11 -13
  93. package/dist/{chunk-R4FL5JHK.js → chunk-T6YLXO6N.js} +4 -4
  94. package/dist/{chunk-3LF7T3NW.js → chunk-TQNFDNJA.js} +6 -6
  95. package/dist/{chunk-SROWUG5W.js → chunk-UTAARXYQ.js} +1 -1
  96. package/dist/{chunk-DXMUJTYF.js → chunk-V3YBVOTZ.js} +2 -2
  97. package/dist/{chunk-RRHHWYPX.js → chunk-V4EOFOB2.js} +6 -6
  98. package/dist/{chunk-DM24VZOI.js → chunk-VURDLVAQ.js} +3 -3
  99. package/dist/{chunk-IZVEBBDH.js → chunk-XDDSURY3.js} +3 -3
  100. package/dist/{chunk-QSW3HAKI.js → chunk-XEXF2OFZ.js} +61 -2
  101. package/dist/{chunk-2Z7I7DHT.js → chunk-XFQAK35L.js} +1 -1
  102. package/dist/{chunk-TK4JU2F7.js → chunk-XGFFNERF.js} +1 -1
  103. package/dist/{chunk-2VADJ6JH.js → chunk-XIJTXRWB.js} +2 -2
  104. package/dist/{chunk-3KXBRSL3.js → chunk-XXIJBYNW.js} +1 -1
  105. package/dist/{chunk-ITYKN2K3.js → chunk-YB3HMDKE.js} +2 -2
  106. package/dist/{chunk-GTBWWCCM.js → chunk-YQDCTID4.js} +115 -9
  107. package/dist/{chunk-DTVHZDYM.js → chunk-ZAZUDYSF.js} +26 -12
  108. package/dist/{chunk-UMTMFDL2.js → chunk-ZJV7SFIJ.js} +1 -1
  109. package/dist/{codex-app-cards-switch-HK4RMOBI.js → codex-app-cards-switch-W7OLKOMO.js} +11 -11
  110. package/dist/{codex-desktop-launch-OCO6N7SA.js → codex-desktop-launch-U6V3AXZF.js} +1 -1
  111. package/dist/{codex-session-launch-ETZQTVFS.js → codex-session-launch-EFU46WBL.js} +18 -19
  112. package/dist/{config-YY54G3CC.js → config-UC4LMCNX.js} +3 -3
  113. package/dist/{global-upgrade-5DN5G3ZQ.js → global-upgrade-ABF5O3HU.js} +10 -10
  114. package/dist/{identity-EGL6HAWG.js → identity-3ZUZPHN6.js} +4 -4
  115. package/dist/{live-capabilities-WU3FYJJG.js → live-capabilities-BXWXJARK.js} +5 -5
  116. package/dist/{paths-ZG6KDM6Y.js → paths-FO76CFRQ.js} +3 -3
  117. package/dist/{reapply-AQLNCCTE.js → reapply-3T3DFUAI.js} +26 -27
  118. package/dist/src/index.js +30 -20
  119. package/dist/{upgrade-lock-BIRXIKHJ.js → upgrade-lock-EZ5JIPJE.js} +4 -4
  120. package/dist/{usage-43C2DHDU.js → usage-Y6BL7RUD.js} +3 -3
  121. package/package.json +1 -1
  122. package/dist/chunk-ANP3DIST.js +0 -118
  123. package/dist/chunk-TJUJAK5L.js +0 -62
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-ATPJGHUP.js";
3
+ } from "./chunk-GDLT32I4.js";
4
4
  import {
5
5
  readJsonSafe,
6
6
  writeFileAtomic
7
- } from "./chunk-SCMEVDAR.js";
7
+ } from "./chunk-KS3O6O7E.js";
8
8
  import {
9
9
  DECLINED_AGENTS_FILE,
10
10
  DISCONNECT_AGENT_IDS,
@@ -13,7 +13,7 @@ import {
13
13
  serializeDeclinedAgents,
14
14
  withDeclinedAgent,
15
15
  withoutDeclinedAgent
16
- } from "./chunk-MNKIR2ZB.js";
16
+ } from "./chunk-EJR5JXMV.js";
17
17
 
18
18
  // src/declined-agents-file.ts
19
19
  import { join } from "path";
@@ -1,7 +1,63 @@
1
+ import {
2
+ getBaseUrl
3
+ } from "./chunk-A47UKPC7.js";
1
4
  import {
2
5
  compressTranscriptRecord,
3
6
  redactSecretsFromContent
4
- } from "./chunk-MNKIR2ZB.js";
7
+ } from "./chunk-EJR5JXMV.js";
8
+
9
+ // src/transcript-api.ts
10
+ var fetchTranscriptRecipients = async (apiKey, baseUrl = getBaseUrl()) => {
11
+ try {
12
+ const res = await fetch(`${baseUrl}/api/agent/encryption-account`, {
13
+ headers: { Authorization: `Bearer ${apiKey}` },
14
+ signal: AbortSignal.timeout(5e3)
15
+ });
16
+ if (!res.ok) return null;
17
+ const data = await res.json();
18
+ if (typeof data.publicKey !== "string" || data.publicKey.length === 0) return null;
19
+ const phoneReadsCompressedRecords = data.readsCompressedRecords === true;
20
+ if (data.providerRecovery === void 0 || data.providerRecovery === null) {
21
+ return { phonePublicKey: data.publicKey, phoneReadsCompressedRecords, provider: null };
22
+ }
23
+ if (typeof data.providerRecovery !== "object") return null;
24
+ const provider = data.providerRecovery;
25
+ if (typeof provider.required !== "boolean" || typeof provider.keyId !== "string" || provider.keyId.length === 0 || typeof provider.publicKey !== "string" || provider.publicKey.length === 0) return null;
26
+ return {
27
+ phonePublicKey: data.publicKey,
28
+ phoneReadsCompressedRecords,
29
+ provider: { required: provider.required, keyId: provider.keyId, publicKey: provider.publicKey }
30
+ };
31
+ } catch {
32
+ return null;
33
+ }
34
+ };
35
+ var fetchAccountPublicKey = async (apiKey, baseUrl = getBaseUrl()) => (await fetchTranscriptRecipients(apiKey, baseUrl))?.phonePublicKey ?? null;
36
+ var uploadTranscriptRecords = async (apiKey, params, baseUrl = getBaseUrl()) => {
37
+ try {
38
+ const res = await fetch(`${baseUrl}/api/agent/transcript`, {
39
+ method: "POST",
40
+ headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
41
+ body: JSON.stringify(params),
42
+ signal: AbortSignal.timeout(15e3)
43
+ });
44
+ const body = await res.json().catch(() => null);
45
+ const keyRegistered = body?.keyRegistered === true;
46
+ const keyConflict = body?.keyConflict === true;
47
+ const keyUnavailable = res.status === 503;
48
+ const ids = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
49
+ return {
50
+ ok: res.ok && !keyConflict && (params.dataEncryptionKey === void 0 || keyRegistered),
51
+ keyRegistered,
52
+ keyConflict,
53
+ keyUnavailable,
54
+ settledIds: Array.isArray(body?.settledIds) ? ids(body.settledIds) : null,
55
+ rejectedIds: ids(body?.rejectedIds)
56
+ };
57
+ } catch {
58
+ return { ok: false, keyRegistered: false, keyConflict: false, keyUnavailable: false, settledIds: null, rejectedIds: [] };
59
+ }
60
+ };
5
61
 
6
62
  // src/crypto.ts
7
63
  import nacl from "tweetnacl";
@@ -164,5 +220,8 @@ export {
164
220
  wrapSessionKey,
165
221
  encryptRecord,
166
222
  recordSealerFor,
167
- buildTranscriptRecords
223
+ buildTranscriptRecords,
224
+ fetchTranscriptRecipients,
225
+ fetchAccountPublicKey,
226
+ uploadTranscriptRecords
168
227
  };
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-KZERVKTD.js";
8
8
  import {
9
9
  redactSecretsFromContent
10
- } from "./chunk-MNKIR2ZB.js";
10
+ } from "./chunk-EJR5JXMV.js";
11
11
 
12
12
  // src/cli/json.ts
13
13
  var writeStdoutFully = (text) => new Promise((resolve, reject) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readTranscriptPreference
3
- } from "./chunk-ED2SWTPC.js";
3
+ } from "./chunk-CNJ7SI5V.js";
4
4
 
5
5
  // src/transcript-setting.ts
6
6
  var transcriptEnvironmentPreference = () => {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  configFilePath
3
- } from "./chunk-Y64JGYTB.js";
3
+ } from "./chunk-A47UKPC7.js";
4
4
  import {
5
5
  normalizeInstallSource
6
- } from "./chunk-MNKIR2ZB.js";
6
+ } from "./chunk-EJR5JXMV.js";
7
7
 
8
8
  // src/install-source.ts
9
9
  import { readFileSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  localRepoKey,
3
3
  normalizeRepoRemote
4
- } from "./chunk-MNKIR2ZB.js";
4
+ } from "./chunk-EJR5JXMV.js";
5
5
 
6
6
  // src/repo.ts
7
7
  import { existsSync, readFileSync, statSync } from "fs";
@@ -4,10 +4,10 @@ import {
4
4
  keyPrefix,
5
5
  readConfigFileKey,
6
6
  readMacAppKeyPrefix
7
- } from "./chunk-ED2SWTPC.js";
7
+ } from "./chunk-CNJ7SI5V.js";
8
8
  import {
9
9
  NPX_LATEST_COMMAND
10
- } from "./chunk-BAGBCSXA.js";
10
+ } from "./chunk-GO7YKPT3.js";
11
11
 
12
12
  // src/key-signed-out.ts
13
13
  var VERDICT_BY_CHECK = {
@@ -1,25 +1,24 @@
1
- import {
2
- GEMINI_HOOK_EVENTS,
3
- hasGeminiHooks
4
- } from "./chunk-ANP3DIST.js";
5
1
  import {
6
2
  AGENT_CHOICES
7
- } from "./chunk-SROWUG5W.js";
3
+ } from "./chunk-UTAARXYQ.js";
8
4
  import {
9
5
  BELL_HOOK_BINARY
10
- } from "./chunk-Z3M627TQ.js";
6
+ } from "./chunk-IQ3GKPFM.js";
11
7
  import {
12
8
  CLAUDE_HOOK_EVENTS,
13
9
  CODEX_HOOK_EVENTS,
14
10
  HOOK_SHELL,
15
11
  hasCodexHooks,
16
- holdBudgetOf
17
- } from "./chunk-ATPJGHUP.js";
12
+ holdBudgetOf,
13
+ isProtectedByScope,
14
+ registerHookEntry
15
+ } from "./chunk-GDLT32I4.js";
18
16
  import {
19
17
  CURSOR_GATE_EVENTS,
18
+ HOOK_BUDGETS,
20
19
  HOOK_LOCATOR_BINARY,
21
20
  hookCommandHoldBudget
22
- } from "./chunk-MNKIR2ZB.js";
21
+ } from "./chunk-EJR5JXMV.js";
23
22
 
24
23
  // src/diagnostics/bridge.ts
25
24
  import { execFileSync } from "child_process";
@@ -97,6 +96,105 @@ var liveBridgeProbe = () => ({
97
96
  home: homedir()
98
97
  });
99
98
 
99
+ // src/gemini-config.ts
100
+ var GEMINI_HOOK_BINARY = "pushary-gemini-hook";
101
+ var GEMINI_MCP_URL = "https://pushary.com/api/mcp/mcp";
102
+ var GEMINI_HOOK_EVENTS = [
103
+ { event: "BeforeTool", matcher: "run_shell_command|write_file|replace|mcp_.*", delivery: "approval", timeoutMs: HOOK_BUDGETS.gemini.budgetSeconds * 1e3 },
104
+ { event: "AfterTool", matcher: "run_shell_command|write_file|replace|mcp_.*", delivery: "telemetry", timeoutMs: 1e4 },
105
+ { event: "BeforeAgent", delivery: "telemetry", timeoutMs: 1e4 },
106
+ { event: "AfterAgent", delivery: "telemetry", timeoutMs: 1e4 },
107
+ { event: "SessionStart", delivery: "telemetry", timeoutMs: 1e4 },
108
+ { event: "SessionEnd", delivery: "telemetry", timeoutMs: 1e4 }
109
+ ];
110
+ var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
111
+ var ensureRecord = (target, key) => {
112
+ const existing = asRecord(target[key]);
113
+ if (existing) return existing;
114
+ const created = {};
115
+ target[key] = created;
116
+ return created;
117
+ };
118
+ var isPusharyGeminiHook = (entry, scope) => {
119
+ const hooks = asRecord(entry)?.hooks;
120
+ if (!Array.isArray(hooks)) return false;
121
+ return hooks.some((hook) => {
122
+ const command = String(asRecord(hook)?.command ?? "");
123
+ if (isProtectedByScope(command, scope)) return false;
124
+ return command.includes(GEMINI_HOOK_BINARY) || command.includes(HOOK_LOCATOR_BINARY);
125
+ });
126
+ };
127
+ var addGeminiMcpServer = (settings, apiKey) => {
128
+ const mcpServers = ensureRecord(settings, "mcpServers");
129
+ mcpServers.pushary = {
130
+ httpUrl: GEMINI_MCP_URL,
131
+ headers: { Authorization: `Bearer ${apiKey}` },
132
+ trust: true
133
+ };
134
+ };
135
+ var addGeminiHooks = (settings, command) => {
136
+ const hooks = ensureRecord(settings, "hooks");
137
+ for (const definition of GEMINI_HOOK_EVENTS) {
138
+ const existing = Array.isArray(hooks[definition.event]) ? hooks[definition.event] : [];
139
+ hooks[definition.event] = registerHookEntry(existing, isPusharyGeminiHook, {
140
+ ...definition.matcher ? { matcher: definition.matcher } : {},
141
+ hooks: [{
142
+ name: "pushary",
143
+ type: "command",
144
+ command,
145
+ timeout: definition.timeoutMs
146
+ }]
147
+ });
148
+ }
149
+ };
150
+ var removeGeminiHooks = (settings, scope) => {
151
+ const hooks = asRecord(settings.hooks);
152
+ if (!hooks) return false;
153
+ let changed = false;
154
+ for (const definition of GEMINI_HOOK_EVENTS) {
155
+ const entries = hooks[definition.event];
156
+ if (!Array.isArray(entries)) continue;
157
+ const filtered = entries.filter((entry) => !isPusharyGeminiHook(entry, scope));
158
+ if (filtered.length !== entries.length) {
159
+ if (filtered.length === 0) {
160
+ delete hooks[definition.event];
161
+ } else {
162
+ hooks[definition.event] = filtered;
163
+ }
164
+ changed = true;
165
+ }
166
+ }
167
+ if (Object.keys(hooks).length === 0) delete settings.hooks;
168
+ return changed;
169
+ };
170
+ var removeGeminiMcpServer = (settings) => {
171
+ const mcpServers = asRecord(settings.mcpServers);
172
+ if (!mcpServers?.pushary) return false;
173
+ delete mcpServers.pushary;
174
+ if (Object.keys(mcpServers).length === 0) delete settings.mcpServers;
175
+ return true;
176
+ };
177
+ var removeGeminiSettings = (settings, scope) => {
178
+ const mcpRemoved = scope?.keepMcpServer === true ? false : removeGeminiMcpServer(settings);
179
+ const hooksRemoved = removeGeminiHooks(settings, scope);
180
+ return mcpRemoved || hooksRemoved;
181
+ };
182
+ var hasGeminiHooks = (settings) => {
183
+ const hooks = asRecord(settings.hooks);
184
+ if (!hooks) return false;
185
+ return GEMINI_HOOK_EVENTS.some((definition) => {
186
+ const entries = hooks[definition.event];
187
+ return Array.isArray(entries) && entries.some((entry) => isPusharyGeminiHook(entry));
188
+ });
189
+ };
190
+ var missingGeminiHookEvents = (settings) => {
191
+ const hooks = asRecord(settings.hooks);
192
+ return GEMINI_HOOK_EVENTS.filter((definition) => {
193
+ const entries = hooks?.[definition.event];
194
+ return !Array.isArray(entries) || !entries.some((entry) => isPusharyGeminiHook(entry));
195
+ }).map((definition) => definition.event);
196
+ };
197
+
100
198
  // src/diagnostics/wiring.ts
101
199
  var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
102
200
  var CLAUDE_HOOK_BINARY = /pushary-[a-z-]*hook/;
@@ -326,6 +424,14 @@ export {
326
424
  describeBridgeResolution,
327
425
  isBridgeLocator,
328
426
  liveBridgeProbe,
427
+ GEMINI_HOOK_BINARY,
428
+ GEMINI_HOOK_EVENTS,
429
+ addGeminiMcpServer,
430
+ addGeminiHooks,
431
+ removeGeminiMcpServer,
432
+ removeGeminiSettings,
433
+ hasGeminiHooks,
434
+ missingGeminiHookEvents,
329
435
  pusharyHookExecutable,
330
436
  claudeWired,
331
437
  codexWired,
@@ -6,18 +6,18 @@ import {
6
6
  McpToolError,
7
7
  SubscriptionRequiredError,
8
8
  callMcpTool
9
- } from "./chunk-BKCI53W6.js";
9
+ } from "./chunk-Q5RNYE2L.js";
10
10
  import {
11
11
  installNetworkDefaults,
12
12
  isNetworkFailure
13
- } from "./chunk-7ILQX47W.js";
13
+ } from "./chunk-GECU7V44.js";
14
14
  import {
15
15
  clientReportClaims
16
- } from "./chunk-ATPJGHUP.js";
16
+ } from "./chunk-GDLT32I4.js";
17
17
  import {
18
18
  getApiKey,
19
19
  getBaseUrl
20
- } from "./chunk-Y64JGYTB.js";
20
+ } from "./chunk-A47UKPC7.js";
21
21
  import {
22
22
  ASK_AGENT_NAME_MAX,
23
23
  CLIENT_REPORT_PATH,
@@ -26,7 +26,7 @@ import {
26
26
  TOOL_FAILURE_CODES,
27
27
  degradedLine,
28
28
  truncateLine
29
- } from "./chunk-MNKIR2ZB.js";
29
+ } from "./chunk-EJR5JXMV.js";
30
30
 
31
31
  // src/api.ts
32
32
  import { randomUUID } from "crypto";
@@ -235,25 +235,38 @@ var nextLongPollMs = (deadlineMs, nowMs) => {
235
235
  const hold = Math.min(deadlineMs - nowMs - WAIT_RESPONSE_GRACE_MS, MAX_LONG_POLL_MS);
236
236
  return hold >= MIN_LONG_POLL_MS ? hold : null;
237
237
  };
238
- var pollForAnswer = async (apiKey, correlationId, deadlineMs, pollInterval = 2e3) => {
239
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
238
+ var ABANDONED_WAIT = { answered: false, status: "abandoned" };
239
+ var sleepUnlessAborted = (ms, signal) => new Promise((resolve) => {
240
+ const wake = () => {
241
+ clearTimeout(timer);
242
+ signal?.removeEventListener("abort", wake);
243
+ resolve();
244
+ };
245
+ const timer = setTimeout(wake, ms);
246
+ signal?.addEventListener("abort", wake, { once: true });
247
+ });
248
+ var boundedBy = (timeoutMs, signal) => signal ? AbortSignal.any([AbortSignal.timeout(timeoutMs), signal]) : AbortSignal.timeout(timeoutMs);
249
+ var pollForAnswer = async (apiKey, correlationId, deadlineMs, pollInterval = 2e3, signal) => {
240
250
  while (Date.now() < deadlineMs) {
251
+ if (signal?.aborted) return ABANDONED_WAIT;
241
252
  const hold = nextLongPollMs(deadlineMs, Date.now());
242
253
  if (hold === null) {
243
- await sleep(Math.max(0, deadlineMs - Date.now()));
254
+ await sleepUnlessAborted(Math.max(0, deadlineMs - Date.now()), signal);
244
255
  continue;
245
256
  }
246
257
  let answer;
247
258
  try {
248
- answer = await waitForAnswer(apiKey, correlationId, hold, AbortSignal.timeout(Math.max(1, deadlineMs - Date.now())));
259
+ answer = await waitForAnswer(apiKey, correlationId, hold, boundedBy(Math.max(1, deadlineMs - Date.now()), signal));
249
260
  } catch {
261
+ if (signal?.aborted) return ABANDONED_WAIT;
250
262
  const late = await withdrawQuestion(apiKey, correlationId);
251
263
  return late.answered ? late : STOPPED;
252
264
  }
253
265
  if (isDecisionStopped(answer) || answer.answered) return answer;
254
266
  if (answer.status === "expired") return STOPPED;
255
- await sleep(Math.min(pollInterval, Math.max(0, deadlineMs - Date.now())));
267
+ await sleepUnlessAborted(Math.min(pollInterval, Math.max(0, deadlineMs - Date.now())), signal);
256
268
  }
269
+ if (signal?.aborted) return ABANDONED_WAIT;
257
270
  return withdrawQuestion(apiKey, correlationId);
258
271
  };
259
272
  var cancelQuestion = async (apiKey, correlationId, signal, baseUrl) => {
@@ -271,10 +284,10 @@ var withdrawQuestion = async (apiKey, correlationId, transport = { cancelQuestio
271
284
  return STOPPED;
272
285
  }
273
286
  };
274
- var waitForQuestion = async (apiKey, question, deadlineMs, pollInterval = 2e3) => {
287
+ var waitForQuestion = async (apiKey, question, deadlineMs, pollInterval = 2e3, signal) => {
275
288
  if (isDecisionStopped(question) || question.answered) return { ...question, answered: !!question.answered };
276
289
  if (question.status === "expired") return STOPPED;
277
- return isAwayPaused(question) || isLocalQuestionHandoff(question) ? withdrawQuestion(apiKey, question.correlationId) : pollForAnswer(apiKey, question.correlationId, deadlineMs, pollInterval);
290
+ return isAwayPaused(question) || isLocalQuestionHandoff(question) ? withdrawQuestion(apiKey, question.correlationId) : pollForAnswer(apiKey, question.correlationId, deadlineMs, pollInterval, signal);
278
291
  };
279
292
  var sendNotification = async (apiKey, params, timeoutMs = 15e3, signal) => {
280
293
  await callMcpTool(apiKey, "send_notification", { ...params }, { maxRetries: signal ? 1 : 3, timeoutMs, signal });
@@ -328,6 +341,7 @@ export {
328
341
  waitForAnswer,
329
342
  WAIT_RESPONSE_GRACE_MS,
330
343
  nextLongPollMs,
344
+ ABANDONED_WAIT,
331
345
  pollForAnswer,
332
346
  cancelQuestion,
333
347
  withdrawQuestion,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DEFAULT_SESSION
3
- } from "./chunk-3UNAPXED.js";
3
+ } from "./chunk-2BL6KWN7.js";
4
4
 
5
5
  // src/answer.ts
6
6
  var isDeferAnswer = (value) => value === "defer";
@@ -22,22 +22,22 @@ import {
22
22
  turnCodexAppCardsOff,
23
23
  turnCodexAppCardsOn,
24
24
  whyLaunchctlFailed
25
- } from "./chunk-OA6EADFT.js";
26
- import "./chunk-JFKMPLNF.js";
25
+ } from "./chunk-DPU6H4JY.js";
26
+ import "./chunk-AVWECJSN.js";
27
27
  import "./chunk-XCEN33UP.js";
28
28
  import "./chunk-QCGNGEGE.js";
29
- import "./chunk-ADXHPGBZ.js";
29
+ import "./chunk-57NTMVMI.js";
30
30
  import "./chunk-XHKBHWLX.js";
31
- import "./chunk-ED2SWTPC.js";
31
+ import "./chunk-CNJ7SI5V.js";
32
32
  import "./chunk-E46NE7FB.js";
33
- import "./chunk-FWS2KLV2.js";
34
- import "./chunk-2VADJ6JH.js";
35
- import "./chunk-ATPJGHUP.js";
36
- import "./chunk-SCMEVDAR.js";
37
- import "./chunk-Y64JGYTB.js";
38
- import "./chunk-BAGBCSXA.js";
33
+ import "./chunk-IA5VWIHV.js";
34
+ import "./chunk-XIJTXRWB.js";
35
+ import "./chunk-GDLT32I4.js";
36
+ import "./chunk-KS3O6O7E.js";
37
+ import "./chunk-A47UKPC7.js";
38
+ import "./chunk-GO7YKPT3.js";
39
39
  import "./chunk-QTOLNRET.js";
40
- import "./chunk-MNKIR2ZB.js";
40
+ import "./chunk-EJR5JXMV.js";
41
41
  import "./chunk-MLKGABMK.js";
42
42
  export {
43
43
  CODEX_APP_CARDS_DIRECTORY,
@@ -11,7 +11,7 @@ import {
11
11
  installedCodexApp,
12
12
  shellQuoted,
13
13
  writeDesktopProxy
14
- } from "./chunk-JFKMPLNF.js";
14
+ } from "./chunk-AVWECJSN.js";
15
15
  import "./chunk-XCEN33UP.js";
16
16
  import {
17
17
  CODEX_APP_LAUNCH_VARIABLE
@@ -11,34 +11,33 @@ import {
11
11
  isCodexQuestionLeftWithTheLocalClient,
12
12
  planCodexElicitation,
13
13
  reportOwnedQuestion
14
- } from "./chunk-3LF7T3NW.js";
15
- import "./chunk-NUEPJ5W6.js";
16
- import "./chunk-R4FL5JHK.js";
17
- import "./chunk-HIYLAC3C.js";
18
- import "./chunk-6CZX6YOE.js";
19
- import "./chunk-RABLE5R6.js";
20
- import "./chunk-QSW3HAKI.js";
21
- import "./chunk-TJUJAK5L.js";
14
+ } from "./chunk-TQNFDNJA.js";
15
+ import "./chunk-QOIPUYUD.js";
16
+ import "./chunk-T6YLXO6N.js";
17
+ import "./chunk-MDIGG3Q7.js";
18
+ import "./chunk-3ELJIG2R.js";
19
+ import "./chunk-RJ6JEHCP.js";
20
+ import "./chunk-XEXF2OFZ.js";
22
21
  import "./chunk-XHKBHWLX.js";
23
- import "./chunk-3KXBRSL3.js";
22
+ import "./chunk-XXIJBYNW.js";
24
23
  import {
25
24
  writeDegraded
26
- } from "./chunk-DTVHZDYM.js";
25
+ } from "./chunk-ZAZUDYSF.js";
27
26
  import "./chunk-POFBE6ZY.js";
28
- import "./chunk-BKCI53W6.js";
29
- import "./chunk-UHS5MMAI.js";
30
- import "./chunk-7ILQX47W.js";
31
- import "./chunk-FWS2KLV2.js";
27
+ import "./chunk-Q5RNYE2L.js";
28
+ import "./chunk-QR2QWGQI.js";
29
+ import "./chunk-GECU7V44.js";
30
+ import "./chunk-IA5VWIHV.js";
32
31
  import "./chunk-PPY5N2E6.js";
33
32
  import "./chunk-KZERVKTD.js";
34
- import "./chunk-ATPJGHUP.js";
35
- import "./chunk-SCMEVDAR.js";
36
- import "./chunk-Y64JGYTB.js";
37
- import "./chunk-BAGBCSXA.js";
33
+ import "./chunk-GDLT32I4.js";
34
+ import "./chunk-KS3O6O7E.js";
35
+ import "./chunk-A47UKPC7.js";
36
+ import "./chunk-GO7YKPT3.js";
38
37
  import "./chunk-QTOLNRET.js";
39
38
  import {
40
39
  canonicalJsonText
41
- } from "./chunk-MNKIR2ZB.js";
40
+ } from "./chunk-EJR5JXMV.js";
42
41
  import "./chunk-MLKGABMK.js";
43
42
 
44
43
  // src/codex-session-launch.ts
@@ -3,9 +3,9 @@ import {
3
3
  getApiKey,
4
4
  getBaseUrl,
5
5
  resetKeyDriftWarning
6
- } from "./chunk-Y64JGYTB.js";
7
- import "./chunk-BAGBCSXA.js";
8
- import "./chunk-MNKIR2ZB.js";
6
+ } from "./chunk-A47UKPC7.js";
7
+ import "./chunk-GO7YKPT3.js";
8
+ import "./chunk-EJR5JXMV.js";
9
9
  import "./chunk-MLKGABMK.js";
10
10
  export {
11
11
  configFilePath,
@@ -7,19 +7,19 @@ import {
7
7
  recordUnfinishedUpgrade,
8
8
  upgradeInstalledPackage,
9
9
  withUpgradeLock
10
- } from "./chunk-WOHP7EL6.js";
11
- import "./chunk-DXMUJTYF.js";
12
- import "./chunk-R4FL5JHK.js";
13
- import "./chunk-HIYLAC3C.js";
14
- import "./chunk-RABLE5R6.js";
15
- import "./chunk-DM24VZOI.js";
10
+ } from "./chunk-RSZQEEEW.js";
11
+ import "./chunk-V3YBVOTZ.js";
12
+ import "./chunk-T6YLXO6N.js";
13
+ import "./chunk-MDIGG3Q7.js";
14
+ import "./chunk-RJ6JEHCP.js";
15
+ import "./chunk-VURDLVAQ.js";
16
16
  import "./chunk-POFBE6ZY.js";
17
17
  import "./chunk-KZERVKTD.js";
18
- import "./chunk-ATPJGHUP.js";
19
- import "./chunk-SCMEVDAR.js";
20
- import "./chunk-BAGBCSXA.js";
18
+ import "./chunk-GDLT32I4.js";
19
+ import "./chunk-KS3O6O7E.js";
20
+ import "./chunk-GO7YKPT3.js";
21
21
  import "./chunk-QTOLNRET.js";
22
- import "./chunk-MNKIR2ZB.js";
22
+ import "./chunk-EJR5JXMV.js";
23
23
  import "./chunk-MLKGABMK.js";
24
24
  export {
25
25
  finishGlobalUpgrade,
@@ -2,11 +2,11 @@ import {
2
2
  getMachineId,
3
3
  getOrCreateMachineId,
4
4
  readExistingMachineId
5
- } from "./chunk-FWS2KLV2.js";
6
- import "./chunk-ATPJGHUP.js";
7
- import "./chunk-SCMEVDAR.js";
5
+ } from "./chunk-IA5VWIHV.js";
6
+ import "./chunk-GDLT32I4.js";
7
+ import "./chunk-KS3O6O7E.js";
8
8
  import "./chunk-QTOLNRET.js";
9
- import "./chunk-MNKIR2ZB.js";
9
+ import "./chunk-EJR5JXMV.js";
10
10
  import "./chunk-MLKGABMK.js";
11
11
  export {
12
12
  getMachineId,
@@ -22,12 +22,12 @@ import {
22
22
  resolveControlPolicy,
23
23
  resolveProviderBinary,
24
24
  trackProviderInventory
25
- } from "./chunk-R4FL5JHK.js";
26
- import "./chunk-HIYLAC3C.js";
27
- import "./chunk-RABLE5R6.js";
28
- import "./chunk-SCMEVDAR.js";
25
+ } from "./chunk-T6YLXO6N.js";
26
+ import "./chunk-MDIGG3Q7.js";
27
+ import "./chunk-RJ6JEHCP.js";
28
+ import "./chunk-KS3O6O7E.js";
29
29
  import "./chunk-QTOLNRET.js";
30
- import "./chunk-MNKIR2ZB.js";
30
+ import "./chunk-EJR5JXMV.js";
31
31
  import "./chunk-MLKGABMK.js";
32
32
  export {
33
33
  CLAUDE_BRIDGE_CAPABILITY,
@@ -35,10 +35,10 @@ import {
35
35
  serviceOwedBackMark,
36
36
  vscodePluginDir,
37
37
  vscodePluginMcp
38
- } from "./chunk-ATPJGHUP.js";
39
- import "./chunk-SCMEVDAR.js";
38
+ } from "./chunk-GDLT32I4.js";
39
+ import "./chunk-KS3O6O7E.js";
40
40
  import "./chunk-QTOLNRET.js";
41
- import "./chunk-MNKIR2ZB.js";
41
+ import "./chunk-EJR5JXMV.js";
42
42
  import "./chunk-MLKGABMK.js";
43
43
  export {
44
44
  autoUpdateLock,