@pushary/agent-hooks 1.9.6 → 1.9.8

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 (111) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +3 -3
  3. package/data/cursor-plugin/README.md +3 -7
  4. package/data/vscode-plugin/README.md +1 -1
  5. package/dist/bin/pushary-bell-hook.js +22 -23
  6. package/dist/bin/pushary-bell.js +9 -9
  7. package/dist/bin/pushary-claude.js +27 -28
  8. package/dist/bin/pushary-clean.js +98 -76
  9. package/dist/bin/pushary-codex-bridge.js +18 -18
  10. package/dist/bin/pushary-codex-hook.js +32 -33
  11. package/dist/bin/pushary-codex.js +13 -13
  12. package/dist/bin/pushary-connect.js +24 -21
  13. package/dist/bin/pushary-cowork.js +5 -5
  14. package/dist/bin/pushary-daemon.js +51 -38
  15. package/dist/bin/pushary-disconnect.js +187 -52
  16. package/dist/bin/pushary-doctor.js +68 -56
  17. package/dist/bin/pushary-elicitation-hook.js +24 -25
  18. package/dist/bin/pushary-gemini-bridge.js +13 -13
  19. package/dist/bin/pushary-gemini-hook.js +29 -30
  20. package/dist/bin/pushary-hook.js +30 -32
  21. package/dist/bin/pushary-login.js +12 -12
  22. package/dist/bin/pushary-logout.js +105 -42
  23. package/dist/bin/pushary-mcp.js +9 -9
  24. package/dist/bin/pushary-mode.js +28 -31
  25. package/dist/bin/pushary-notification-hook.js +26 -28
  26. package/dist/bin/pushary-opencode-hook.js +28 -29
  27. package/dist/bin/pushary-permission-denied-hook.js +30 -32
  28. package/dist/bin/pushary-permission-hook.js +29 -31
  29. package/dist/bin/pushary-post-hook.js +26 -28
  30. package/dist/bin/pushary-prompt-hook.js +26 -28
  31. package/dist/bin/pushary-session-end-hook.js +26 -28
  32. package/dist/bin/pushary-session-start-hook.js +31 -31
  33. package/dist/bin/pushary-setup.js +98 -106
  34. package/dist/bin/pushary-stats.js +5 -5
  35. package/dist/bin/pushary-status.js +34 -18
  36. package/dist/bin/pushary-stop-hook.js +26 -28
  37. package/dist/bin/pushary-stopfailure-hook.js +26 -28
  38. package/dist/bin/pushary-suggestions.js +19 -21
  39. package/dist/bin/pushary-transcript-register.js +18 -19
  40. package/dist/bin/pushary-transcripts.js +7 -7
  41. package/dist/bin/pushary-upgrade.js +67 -31
  42. package/dist/bin/pushary-wait.js +23 -19
  43. package/dist/bin/pushary.js +15 -14
  44. package/dist/{chunk-BSZ7VBVT.js → chunk-2A53H4S6.js} +17 -15
  45. package/dist/{chunk-D7SOOVHX.js → chunk-2QGYMY7A.js} +83 -3
  46. package/dist/{chunk-SVTHEMM3.js → chunk-2QTO5YIT.js} +6 -6
  47. package/dist/{chunk-WN6WYUCV.js → chunk-2VZAALEJ.js} +5 -9
  48. package/dist/chunk-2WXF3QJR.js +49 -0
  49. package/dist/{chunk-UKNKYTTY.js → chunk-3I6IVOZV.js} +3 -3
  50. package/dist/chunk-3Z3A37WD.js +77 -0
  51. package/dist/{chunk-2QRE6QH2.js → chunk-5QUPKDI5.js} +1 -1
  52. package/dist/chunk-6TE27XZR.js +69 -0
  53. package/dist/{chunk-L6USMDTW.js → chunk-7DVNSQWF.js} +59 -15
  54. package/dist/{chunk-SNJ3BOCP.js → chunk-7PT35RY2.js} +27 -8
  55. package/dist/{chunk-CBVDW2N6.js → chunk-B64KHETR.js} +3 -3
  56. package/dist/chunk-BEJRK4DF.js +94 -0
  57. package/dist/chunk-BXET3ALR.js +46 -0
  58. package/dist/{chunk-DJ4BB264.js → chunk-CD47ZFFZ.js} +1 -1
  59. package/dist/{chunk-FBD3QGVJ.js → chunk-CKV3UPMU.js} +2 -2
  60. package/dist/{chunk-7JTVYR5B.js → chunk-CLOSJ4ES.js} +1 -1
  61. package/dist/{chunk-DA4FTGTK.js → chunk-DKMD6AWR.js} +4 -4
  62. package/dist/{chunk-SPXBXN23.js → chunk-DL7XWKYV.js} +7 -5
  63. package/dist/{chunk-VRT3EEZN.js → chunk-DPGSLWOS.js} +8 -8
  64. package/dist/{chunk-3BUAEQCY.js → chunk-DUZVXBBU.js} +1 -1
  65. package/dist/{chunk-6GERGJHF.js → chunk-EUW7JL2K.js} +0 -32
  66. package/dist/{chunk-75CA37FZ.js → chunk-FQ2GORVG.js} +2 -2
  67. package/dist/{chunk-WUKUXICK.js → chunk-HRULIYDU.js} +2 -2
  68. package/dist/{chunk-Q4E56K4X.js → chunk-I5IJRMNV.js} +78 -8
  69. package/dist/{chunk-MKJ3RTUS.js → chunk-I6MJXLMY.js} +2 -2
  70. package/dist/{chunk-YPXUD6DW.js → chunk-IAD2RT4L.js} +14 -14
  71. package/dist/{chunk-LBLCFD5K.js → chunk-IHFDPV7C.js} +2 -2
  72. package/dist/{chunk-BVCHY4OY.js → chunk-IHO3YQAN.js} +2 -2
  73. package/dist/{chunk-RDK7FX5F.js → chunk-KF3UZLYI.js} +1 -1
  74. package/dist/chunk-KFF7G225.js +599 -0
  75. package/dist/{chunk-TE5M6GGK.js → chunk-KHNFLYJO.js} +204 -28
  76. package/dist/{chunk-CCDVL63C.js → chunk-KRCR2CRQ.js} +9 -9
  77. package/dist/{chunk-ZC3TF4LR.js → chunk-LKLVTG3V.js} +18 -9
  78. package/dist/{chunk-4QKM44N6.js → chunk-LWOO567I.js} +4 -3
  79. package/dist/{chunk-KK54WQ74.js → chunk-M6BZZFVQ.js} +1 -1
  80. package/dist/{chunk-RIC6OOJX.js → chunk-MFF3ONG5.js} +21 -1
  81. package/dist/{chunk-IMGJYFCX.js → chunk-MGRFDGWU.js} +3 -2
  82. package/dist/{chunk-ZPW4MJOV.js → chunk-MKTJEXZ3.js} +3 -3
  83. package/dist/{chunk-2I23NFVT.js → chunk-MXHTGVFZ.js} +52 -9
  84. package/dist/{chunk-5BHROGRB.js → chunk-N4QSPI3B.js} +54 -5
  85. package/dist/{chunk-DGQTJDSJ.js → chunk-NWDG3MSW.js} +1 -1
  86. package/dist/chunk-OP7IHC2I.js +24 -0
  87. package/dist/{chunk-EVFY3VE6.js → chunk-QOLITCIP.js} +1 -1
  88. package/dist/{chunk-W4Q7NFXU.js → chunk-TCQ43LSG.js} +3 -3
  89. package/dist/chunk-TCWKTUAE.js +50 -0
  90. package/dist/{chunk-EZAFBC2C.js → chunk-V5HPPF3E.js} +8 -4
  91. package/dist/{chunk-Q23MMVTD.js → chunk-WG3K4TCH.js} +1 -1
  92. package/dist/{chunk-F56SB65Y.js → chunk-WS4H76EP.js} +2 -2
  93. package/dist/{chunk-HWQNQVY6.js → chunk-WWOHTTVP.js} +2 -2
  94. package/dist/{chunk-NVGDMTX3.js → chunk-YIG2R3BJ.js} +9 -7
  95. package/dist/{chunk-HJXZJF6O.js → chunk-ZBHUHJG6.js} +4 -4
  96. package/dist/{chunk-5AXCOTIT.js → chunk-ZBK6E2OR.js} +1 -1
  97. package/dist/{chunk-5PMTC2CB.js → chunk-ZN3C6GBG.js} +84 -673
  98. package/dist/{chunk-GQHZIBAZ.js → chunk-ZSTSEBG7.js} +1 -1
  99. package/dist/{chunk-PYZC54KA.js → chunk-ZW3XZLJC.js} +61 -17
  100. package/dist/{global-upgrade-7F5RP45B.js → global-upgrade-I56HNM23.js} +6 -6
  101. package/dist/{paths-MELXIVBO.js → paths-AGY43CXS.js} +2 -2
  102. package/dist/reapply-IA5XUKWW.js +57 -0
  103. package/dist/src/index.d.ts +1 -0
  104. package/dist/src/index.js +19 -20
  105. package/dist/{upgrade-lock-AHRBA66K.js → upgrade-lock-B34TAUKV.js} +5 -3
  106. package/package.json +1 -1
  107. package/dist/chunk-HT3WMM6Q.js +0 -44
  108. package/dist/chunk-IR5FRUPQ.js +0 -197
  109. package/dist/chunk-JUFKJCZG.js +0 -38
  110. package/dist/chunk-SJN22ADZ.js +0 -86
  111. package/dist/reapply-NOB2Q6C4.js +0 -35
@@ -1,21 +1,36 @@
1
+ import {
2
+ agentHookOwner,
3
+ macAppBridgeAvailable,
4
+ openCodePluginOwner
5
+ } from "./chunk-3Z3A37WD.js";
1
6
  import {
2
7
  ensureCodexTrustsPusharyHooks
3
- } from "./chunk-IMGJYFCX.js";
8
+ } from "./chunk-MGRFDGWU.js";
9
+ import {
10
+ OPENCODE_HOOK_BINARY,
11
+ installOpenCodePlugin,
12
+ openCodeHookArgv,
13
+ openCodePluginDir,
14
+ openCodeWired
15
+ } from "./chunk-MFF3ONG5.js";
4
16
  import {
5
17
  addClaudeMcpServer,
6
18
  addPusharyHooks,
7
19
  addPusharyToolPermissions
8
- } from "./chunk-IR5FRUPQ.js";
20
+ } from "./chunk-KHNFLYJO.js";
9
21
  import {
10
22
  detectClaudeVersion
11
23
  } from "./chunk-RIVNNBEK.js";
24
+ import {
25
+ planHooks
26
+ } from "./chunk-YIG2R3BJ.js";
12
27
  import {
13
28
  claudeUnprovenHolds,
14
29
  claudeWired,
15
30
  codexUnprovenHolds,
16
31
  codexWired,
17
32
  geminiWired
18
- } from "./chunk-D7SOOVHX.js";
33
+ } from "./chunk-2QGYMY7A.js";
19
34
  import {
20
35
  CLAUDE_HOOK_BINARY,
21
36
  CLAUDE_HOOK_EVENTS,
@@ -26,7 +41,7 @@ import {
26
41
  needsReregistration,
27
42
  registrationSignatures,
28
43
  supportedClaudeEvents
29
- } from "./chunk-UKNKYTTY.js";
44
+ } from "./chunk-3I6IVOZV.js";
30
45
  import {
31
46
  formatVersion
32
47
  } from "./chunk-6ICPEJY5.js";
@@ -49,7 +64,7 @@ import {
49
64
  registrationHolderOf,
50
65
  resolveGlobalBinary,
51
66
  vscodePluginMcp
52
- } from "./chunk-HJXZJF6O.js";
67
+ } from "./chunk-ZBHUHJG6.js";
53
68
  import {
54
69
  readJsonSafe,
55
70
  writeFileAtomic,
@@ -305,21 +320,48 @@ var reapplyCursorPlugin = (apiKey, paths = {}) => reapplyPluginMcp(
305
320
  apiKey
306
321
  );
307
322
  var reapplyVsCodePlugin = (apiKey, paths = {}) => reapplyPluginMcp(paths.pluginMcpPath ?? vscodePluginMcp(), apiKey);
308
- var reapplyAllAgents = (apiKey) => {
323
+ var reapplyOpenCodePlugin = (paths = {}) => {
324
+ const pluginDir = paths.pluginDir ?? openCodePluginDir();
325
+ if (!openCodeWired(pluginDir)) return { configured: false, reapplied: false, hooks: false, mcp: false };
326
+ try {
327
+ installOpenCodePlugin(openCodeHookArgv((paths.resolveBinary ?? resolveGlobalBinary)(OPENCODE_HOOK_BINARY)), pluginDir);
328
+ return { configured: true, reapplied: true, hooks: true, mcp: false };
329
+ } catch {
330
+ return { configured: true, reapplied: false, hooks: false, mcp: false, failed: true };
331
+ }
332
+ };
333
+ var SETUP_CHOICE_BY_REAPPLY_ID = {
334
+ claude: "claude_code",
335
+ codex: "codex",
336
+ gemini: "gemini_cli",
337
+ cursor: "cursor",
338
+ vscode: "vscode"
339
+ };
340
+ var reapplyHookOwner = (id, appAvailable) => id === "opencode" ? openCodePluginOwner(appAvailable) : agentHookOwner(SETUP_CHOICE_BY_REAPPLY_ID[id], appAvailable);
341
+ var reapplyHolder = (id, appAvailable) => planHooks({ owner: reapplyHookOwner(id, appAvailable), takeOverHooks: false, nonInteractive: true }) === "keep" ? "app" : "cli";
342
+ var KEPT_FOR_APP = { configured: true, reapplied: false, hooks: false, mcp: false };
343
+ var FAILED_REAPPLY = { configured: false, reapplied: false, hooks: false, mcp: false, failed: true };
344
+ var reapplyAllAgents = (apiKey, options = {}) => {
309
345
  const runners = [
310
346
  { id: "claude", label: "Claude Code", run: () => reapplyClaudeSettings(apiKey) },
311
347
  { id: "codex", label: "Codex", run: () => reapplyCodexSettings(apiKey) },
312
348
  { id: "gemini", label: "Gemini CLI", run: () => reapplyGeminiSettings(apiKey) },
313
349
  { id: "cursor", label: "Cursor", run: () => reapplyCursorPlugin(apiKey) },
314
- { id: "vscode", label: "VS Code", run: () => reapplyVsCodePlugin(apiKey) }
350
+ { id: "vscode", label: "VS Code", run: () => reapplyVsCodePlugin(apiKey) },
351
+ { id: "opencode", label: "OpenCode", run: () => reapplyOpenCodePlugin() }
315
352
  ];
353
+ const appAvailable = (options.appAvailable ?? macAppBridgeAvailable)();
316
354
  const done = [];
317
355
  for (const runner of runners) {
318
356
  try {
357
+ if (reapplyHolder(runner.id, appAvailable) === "app") {
358
+ done.push({ id: runner.id, label: runner.label, heldBy: "app", result: KEPT_FOR_APP });
359
+ continue;
360
+ }
319
361
  const result = runner.run();
320
- if (result.configured) done.push({ id: runner.id, label: runner.label, result });
362
+ if (result.configured) done.push({ id: runner.id, label: runner.label, heldBy: "cli", result });
321
363
  } catch {
322
- done.push({ id: runner.id, label: runner.label, result: { configured: false, reapplied: false, hooks: false, mcp: false, failed: true } });
364
+ done.push({ id: runner.id, label: runner.label, heldBy: "cli", result: FAILED_REAPPLY });
323
365
  }
324
366
  }
325
367
  return done;
@@ -336,6 +378,7 @@ export {
336
378
  reapplyGeminiSettings,
337
379
  reapplyCursorPlugin,
338
380
  reapplyVsCodePlugin,
381
+ reapplyOpenCodePlugin,
339
382
  reapplyAllAgents,
340
383
  ensureCodexTrustAfterReapply
341
384
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveInstallSourceFor
3
- } from "./chunk-75CA37FZ.js";
3
+ } from "./chunk-FQ2GORVG.js";
4
4
  import {
5
5
  backupFile,
6
6
  readJsonSafe,
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-T7E75EKA.js";
10
10
  import {
11
11
  configFilePath
12
- } from "./chunk-2QRE6QH2.js";
12
+ } from "./chunk-5QUPKDI5.js";
13
13
 
14
14
  // src/shell-alias.ts
15
15
  import { homedir } from "os";
@@ -110,6 +110,20 @@ var isDisabledExport = (line) => {
110
110
  return OUR_EXPORT.test(trimmed.slice(1, -LOGOUT_MARK.length).trim());
111
111
  };
112
112
  var keyPrefix = (key) => key.split(".")[0] ?? key;
113
+ var MAC_APP_KEY_PREFIX_FIELD = "macAppKeyPrefix";
114
+ var KEY_PREFIX_SHAPE = /^pk_[a-f0-9]+$/;
115
+ var findKeyExport = (contents) => {
116
+ const lines = contents.split("\n");
117
+ for (const [index, line] of lines.entries()) {
118
+ const key = line.match(OUR_EXPORT)?.[2];
119
+ if (key) return { line: index + 1, key };
120
+ }
121
+ return null;
122
+ };
123
+ var keepMacAppKeyPrefix = (current, apiKey) => {
124
+ const { [MAC_APP_KEY_PREFIX_FIELD]: recorded, ...rest } = current;
125
+ return recorded === keyPrefix(apiKey) ? { ...rest, [MAC_APP_KEY_PREFIX_FIELD]: recorded } : rest;
126
+ };
113
127
  var manualKeyStepFor = (kind, platform) => kind === "no-rc" || platform === "win32" ? "config-only" : "paste-export";
114
128
  var rcResult = (kind, over = {}) => ({
115
129
  kind,
@@ -208,7 +222,7 @@ var writeKey = (apiKey, options = {}) => {
208
222
  writeJsonAtomic(
209
223
  configPath,
210
224
  {
211
- ...current,
225
+ ...keepMacAppKeyPrefix(current, apiKey),
212
226
  apiKey,
213
227
  installSource: resolveInstallSourceFor(current),
214
228
  ...options.controlMode ? { controlMode: options.controlMode } : {},
@@ -227,7 +241,7 @@ var clearKey = (options = {}) => {
227
241
  const existing = readJsonSafe(configPath);
228
242
  let removedFromConfig = false;
229
243
  if (existing.kind === "ok" && typeof existing.value.apiKey === "string") {
230
- const { apiKey: _dropped, ...rest } = existing.value;
244
+ const { apiKey: _dropped, [MAC_APP_KEY_PREFIX_FIELD]: _adopted, ...rest } = existing.value;
231
245
  writeJsonAtomic(configPath, rest, KEY_FILE_MODE);
232
246
  restrictFile(configPath);
233
247
  removedFromConfig = true;
@@ -289,6 +303,38 @@ var readKeySource = () => {
289
303
  if (fileKey) return { kind: "config", key: fileKey, origin: configPath, drift: null };
290
304
  return { kind: "none", key: null, origin: null, drift: null };
291
305
  };
306
+ var readMacAppKeyPrefix = (configPath = configFilePath()) => {
307
+ const result = readJsonSafe(configPath);
308
+ if (result.kind !== "ok") return null;
309
+ const recorded = result.value[MAC_APP_KEY_PREFIX_FIELD];
310
+ return typeof recorded === "string" && KEY_PREFIX_SHAPE.test(recorded) ? recorded : null;
311
+ };
312
+ var recordMacAppKeyPrefix = (apiKey, configPath = configFilePath()) => {
313
+ const result = readJsonSafe(configPath);
314
+ if (result.kind !== "ok" || result.value.apiKey !== apiKey) return false;
315
+ if (result.value[MAC_APP_KEY_PREFIX_FIELD] === keyPrefix(apiKey)) return false;
316
+ writeJsonAtomic(configPath, { ...result.value, [MAC_APP_KEY_PREFIX_FIELD]: keyPrefix(apiKey) }, KEY_FILE_MODE);
317
+ restrictFile(configPath);
318
+ return true;
319
+ };
320
+ var shellProfileCandidates = () => {
321
+ const resolved = resolveShellRc();
322
+ const fallbacks = FALLBACK_RCS.map((name) => join2(homedir2(), name));
323
+ return resolved ? [resolved.path, ...fallbacks.filter((path) => path !== resolved.path)] : fallbacks;
324
+ };
325
+ var findExportedKeyLine = (profiles = shellProfileCandidates()) => {
326
+ for (const path of profiles) {
327
+ let contents;
328
+ try {
329
+ contents = readFileSync2(path, "utf8");
330
+ } catch {
331
+ continue;
332
+ }
333
+ const found = findKeyExport(contents);
334
+ if (found) return { path, ...found };
335
+ }
336
+ return null;
337
+ };
292
338
 
293
339
  export {
294
340
  CANDIDATE_RCS,
@@ -305,5 +351,8 @@ export {
305
351
  readConfigFileKey,
306
352
  readControlMode,
307
353
  readTranscriptPreference,
308
- readKeySource
354
+ readKeySource,
355
+ readMacAppKeyPrefix,
356
+ recordMacAppKeyPrefix,
357
+ findExportedKeyLine
309
358
  };
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-3EGEA4KH.js";
10
10
  import {
11
11
  getBaseUrl
12
- } from "./chunk-2QRE6QH2.js";
12
+ } from "./chunk-5QUPKDI5.js";
13
13
 
14
14
  // src/cli/login-ui.ts
15
15
  import { hostname } from "os";
@@ -0,0 +1,24 @@
1
+ import {
2
+ isValidApiKey
3
+ } from "./chunk-I5IJRMNV.js";
4
+
5
+ // src/shared-mcp-key.ts
6
+ var asRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
7
+ var pusharyKey = (value) => typeof value === "string" && isValidApiKey(value.trim()) ? value.trim() : null;
8
+ var bearerKey = (authorization) => typeof authorization === "string" && authorization.startsWith("Bearer ") ? pusharyKey(authorization.slice("Bearer ".length)) : null;
9
+ var mcpServerBearer = (mcpServers) => bearerKey(asRecord(asRecord(asRecord(mcpServers)?.pushary)?.headers)?.Authorization);
10
+ var appAgentKey = (bridgeAgentKey) => pusharyKey(asRecord(bridgeAgentKey)?.key);
11
+ var setupReceiptKey = (claudeMcpReceipt) => bearerKey(asRecord(asRecord(asRecord(claudeMcpReceipt)?.installedPushary)?.headers)?.Authorization);
12
+ var macAppKeepsMcpEntry = (entryKey, keys) => {
13
+ if (!entryKey) return true;
14
+ if (keys.appKey) return entryKey === keys.appKey;
15
+ return entryKey !== keys.setupKey;
16
+ };
17
+
18
+ export {
19
+ pusharyKey,
20
+ mcpServerBearer,
21
+ appAgentKey,
22
+ setupReceiptKey,
23
+ macAppKeepsMcpEntry
24
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_HOLD_BUDGET_ENV,
3
3
  hookHoldBudgetProof
4
- } from "./chunk-Q4E56K4X.js";
4
+ } from "./chunk-I5IJRMNV.js";
5
5
 
6
6
  // src/hold-budget.ts
7
7
  var takeHookHoldBudget = (args = process.argv.slice(2), env = process.env) => {
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  readExistingMachineId
3
- } from "./chunk-3BUAEQCY.js";
3
+ } from "./chunk-DUZVXBBU.js";
4
4
  import {
5
5
  NetworkError
6
6
  } from "./chunk-7QLSKOSU.js";
7
7
  import {
8
8
  getBaseUrl
9
- } from "./chunk-2QRE6QH2.js";
9
+ } from "./chunk-5QUPKDI5.js";
10
10
  import {
11
11
  clientContextHeaders,
12
12
  getPackageVersion
13
- } from "./chunk-Q4E56K4X.js";
13
+ } from "./chunk-I5IJRMNV.js";
14
14
 
15
15
  // src/cli/net.ts
16
16
  import { createRequire } from "module";
@@ -0,0 +1,50 @@
1
+ import {
2
+ pusharyHookExecutable
3
+ } from "./chunk-2QGYMY7A.js";
4
+ import {
5
+ isProtectedByScope,
6
+ registerHookEntry
7
+ } from "./chunk-ZBHUHJG6.js";
8
+
9
+ // src/cursor-config.ts
10
+ var hookCommandOf = (entry) => {
11
+ const command = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.command : void 0;
12
+ return typeof command === "string" ? command : "";
13
+ };
14
+ var isPusharyCursorEntry = (entry) => pusharyHookExecutable(hookCommandOf(entry)) !== null;
15
+ var registerCursorGate = (existing, entry) => registerHookEntry(existing, isPusharyCursorEntry, entry);
16
+ var withoutPusharyCursorHooks = (hooks, scope) => {
17
+ let removed = 0;
18
+ const kept = {};
19
+ for (const [event, entries] of Object.entries(hooks)) {
20
+ if (!Array.isArray(entries)) {
21
+ kept[event] = entries;
22
+ continue;
23
+ }
24
+ const others = entries.filter((entry) => !isPusharyCursorEntry(entry) || isProtectedByScope(hookCommandOf(entry), scope));
25
+ removed += entries.length - others.length;
26
+ if (others.length > 0 || entries.length === 0) kept[event] = others;
27
+ }
28
+ return { hooks: kept, removed };
29
+ };
30
+ var CURSOR_PLUGIN_NAME = "pushary";
31
+ var CURSOR_PLUGIN_STAGING_PREFIX = ".pushary-staging-";
32
+ var CURSOR_PLUGIN_BACKUP_INFIX = ".pushary-backup-";
33
+ var isCursorPluginLeftover = (name) => name.startsWith(`${CURSOR_PLUGIN_NAME}${CURSOR_PLUGIN_BACKUP_INFIX}`) || name.startsWith(CURSOR_PLUGIN_STAGING_PREFIX);
34
+ var isPusharyCursorPluginManifest = (contents) => {
35
+ try {
36
+ const manifest = JSON.parse(contents);
37
+ return typeof manifest === "object" && manifest !== null && !Array.isArray(manifest) && manifest.name === CURSOR_PLUGIN_NAME;
38
+ } catch {
39
+ return false;
40
+ }
41
+ };
42
+
43
+ export {
44
+ registerCursorGate,
45
+ withoutPusharyCursorHooks,
46
+ CURSOR_PLUGIN_STAGING_PREFIX,
47
+ CURSOR_PLUGIN_BACKUP_INFIX,
48
+ isCursorPluginLeftover,
49
+ isPusharyCursorPluginManifest
50
+ };
@@ -2,7 +2,7 @@ import {
2
2
  autoUpdateLock,
3
3
  installPackageGlobally,
4
4
  npmErrorMessage
5
- } from "./chunk-HJXZJF6O.js";
5
+ } from "./chunk-ZBHUHJG6.js";
6
6
  import {
7
7
  writeJsonAtomic
8
8
  } from "./chunk-T7E75EKA.js";
@@ -133,7 +133,7 @@ var releaseAutoUpdateLock = (lockPath) => {
133
133
  server.close();
134
134
  }
135
135
  };
136
- var finishWithUpgradeLock = (request) => new Promise((resolve, reject) => {
136
+ var forkFinishWithUpgradeLock = (request) => new Promise((resolve, reject) => {
137
137
  const path = canonicalLockPath(request.lockPath ?? autoUpdateLock());
138
138
  const server = heldLocks.get(path);
139
139
  if (!server) return reject(new Error("Cannot finish an upgrade without its lock"));
@@ -154,10 +154,13 @@ var finishWithUpgradeLock = (request) => new Promise((resolve, reject) => {
154
154
  });
155
155
  child.once("exit", (code, signal) => {
156
156
  clearTimeout(timer);
157
- if (code === 0) resolve();
158
- else reject(new Error(`Upgrade finish exited with ${signal ?? code}`));
157
+ resolve({ code, signal });
159
158
  });
160
159
  });
160
+ var finishWithUpgradeLock = async (request) => {
161
+ const exit = await forkFinishWithUpgradeLock(request);
162
+ if (exit.code !== 0) throw new Error(`Upgrade finish exited with ${exit.signal ?? exit.code}`);
163
+ };
161
164
  var installWithUpgradeLock = (request, lockPath = autoUpdateLock(), runNpm) => {
162
165
  const path = canonicalLockPath(lockPath);
163
166
  if (!heldLocks.has(path)) throw new Error("Cannot install an upgrade without its lock");
@@ -170,6 +173,7 @@ export {
170
173
  claimUpgradeLock,
171
174
  ownsUpgradeLock,
172
175
  releaseAutoUpdateLock,
176
+ forkFinishWithUpgradeLock,
173
177
  finishWithUpgradeLock,
174
178
  installWithUpgradeLock
175
179
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  guardBinary
3
- } from "./chunk-HJXZJF6O.js";
3
+ } from "./chunk-ZBHUHJG6.js";
4
4
 
5
5
  // src/bell/install.ts
6
6
  import { join } from "path";
@@ -3,11 +3,11 @@ import {
3
3
  decodePublicKey,
4
4
  generateSessionKey,
5
5
  wrapSessionKey
6
- } from "./chunk-5AXCOTIT.js";
6
+ } from "./chunk-ZBK6E2OR.js";
7
7
  import {
8
8
  fetchTranscriptRecipients,
9
9
  uploadTranscriptRecords
10
- } from "./chunk-7JTVYR5B.js";
10
+ } from "./chunk-CLOSJ4ES.js";
11
11
 
12
12
  // src/live-session.ts
13
13
  var MAX_TRANSCRIPT_QUEUE = 100;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  registerTranscript
3
- } from "./chunk-VRT3EEZN.js";
3
+ } from "./chunk-DPGSLWOS.js";
4
4
  import {
5
5
  writeDegraded
6
- } from "./chunk-DA4FTGTK.js";
6
+ } from "./chunk-DKMD6AWR.js";
7
7
 
8
8
  // src/tool-hook-input.ts
9
9
  var OPTIONAL_TEXT_FIELDS = ["hook_event_name", "session_id", "cwd", "transcript_path", "tool_use_id", "permission_mode"];
@@ -1,15 +1,13 @@
1
1
  import {
2
2
  AGENT_CHOICES
3
- } from "./chunk-SPXBXN23.js";
4
- import {
5
- isBridgeLocator
6
- } from "./chunk-SJN22ADZ.js";
3
+ } from "./chunk-DL7XWKYV.js";
7
4
  import {
5
+ isBridgeLocator,
8
6
  pusharyHookExecutable
9
- } from "./chunk-D7SOOVHX.js";
7
+ } from "./chunk-2QGYMY7A.js";
10
8
  import {
11
9
  BELL_HOOK_BINARY
12
- } from "./chunk-Q23MMVTD.js";
10
+ } from "./chunk-WG3K4TCH.js";
13
11
 
14
12
  // src/setup/hook-ownership.ts
15
13
  var commandsIn = (value) => {
@@ -105,7 +103,10 @@ var hookOwnerOf = (document, appAvailable = true, hooksKeyPath = ["hooks"]) => {
105
103
  (node, key) => node && typeof node === "object" ? node[key] : void 0,
106
104
  document
107
105
  );
108
- const executables = commandsIn(hooks).map(pusharyHookExecutable).filter((executable) => executable !== null);
106
+ return hookOwnerOfCommands(commandsIn(hooks), appAvailable);
107
+ };
108
+ var hookOwnerOfCommands = (commands, appAvailable = true) => {
109
+ const executables = commands.map(pusharyHookExecutable).filter((executable) => executable !== null);
109
110
  if (appAvailable && executables.some(isBridgeLocator)) return "app";
110
111
  if (executables.some((executable) => !isBridgeLocator(executable))) return "cli";
111
112
  return "none";
@@ -136,6 +137,7 @@ export {
136
137
  isHookTakeoverReceipt,
137
138
  restoreHookTakeover,
138
139
  hookOwnerOf,
140
+ hookOwnerOfCommands,
139
141
  planHooks,
140
142
  describeAppOwnership,
141
143
  KEEP_HINT,
@@ -13,7 +13,7 @@ import {
13
13
  isReleaseVersion,
14
14
  ownPackageName,
15
15
  withHookHoldBudget
16
- } from "./chunk-Q4E56K4X.js";
16
+ } from "./chunk-I5IJRMNV.js";
17
17
 
18
18
  // src/setup/paths.ts
19
19
  import { homedir as homedir2 } from "os";
@@ -365,9 +365,9 @@ var installGlobally = (options) => {
365
365
  }
366
366
  const started = (async () => {
367
367
  if (!npmIsOnPath()) throw new NpmMissingError();
368
- const { withUpgradeLock } = await import("./global-upgrade-7F5RP45B.js");
369
- const { installWithUpgradeLock, ownsUpgradeLock } = await import("./upgrade-lock-AHRBA66K.js");
370
- const { autoUpdateLock: autoUpdateLock2 } = await import("./paths-MELXIVBO.js");
368
+ const { withUpgradeLock } = await import("./global-upgrade-I56HNM23.js");
369
+ const { installWithUpgradeLock, ownsUpgradeLock } = await import("./upgrade-lock-B34TAUKV.js");
370
+ const { autoUpdateLock: autoUpdateLock2 } = await import("./paths-AGY43CXS.js");
371
371
  let result = "skipped";
372
372
  const install = async () => {
373
373
  const platform = process.platform;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  redactSecretsFromContent
3
- } from "./chunk-Q4E56K4X.js";
3
+ } from "./chunk-I5IJRMNV.js";
4
4
 
5
5
  // src/crypto.ts
6
6
  import nacl from "tweetnacl";