@pushary/agent-hooks 0.97.0 → 0.98.0

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 (78) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/bin/pushary-bell-hook.js +19 -19
  3. package/dist/bin/pushary-bell.js +6 -6
  4. package/dist/bin/pushary-claude.js +20 -20
  5. package/dist/bin/pushary-clean.js +18 -18
  6. package/dist/bin/pushary-codex-bridge.js +10 -10
  7. package/dist/bin/pushary-codex-hook.js +23 -23
  8. package/dist/bin/pushary-codex.js +7 -7
  9. package/dist/bin/pushary-connect.js +6 -6
  10. package/dist/bin/pushary-cowork.js +3 -3
  11. package/dist/bin/pushary-daemon.js +23 -23
  12. package/dist/bin/pushary-disconnect.js +6 -6
  13. package/dist/bin/pushary-doctor.js +19 -19
  14. package/dist/bin/pushary-elicitation-hook.js +18 -18
  15. package/dist/bin/pushary-gemini-bridge.js +9 -9
  16. package/dist/bin/pushary-gemini-hook.js +21 -21
  17. package/dist/bin/pushary-hook.js +23 -23
  18. package/dist/bin/pushary-login.js +7 -7
  19. package/dist/bin/pushary-logout.js +4 -4
  20. package/dist/bin/pushary-mode.js +3 -3
  21. package/dist/bin/pushary-notification-hook.js +20 -20
  22. package/dist/bin/pushary-opencode-hook.js +21 -21
  23. package/dist/bin/pushary-permission-denied-hook.js +24 -24
  24. package/dist/bin/pushary-permission-hook.js +23 -23
  25. package/dist/bin/pushary-post-hook.js +20 -20
  26. package/dist/bin/pushary-prompt-hook.js +20 -20
  27. package/dist/bin/pushary-session-end-hook.js +20 -20
  28. package/dist/bin/pushary-session-start-hook.js +23 -23
  29. package/dist/bin/pushary-setup.js +37 -28
  30. package/dist/bin/pushary-stats.js +2 -2
  31. package/dist/bin/pushary-status.js +10 -10
  32. package/dist/bin/pushary-stop-hook.js +20 -20
  33. package/dist/bin/pushary-stopfailure-hook.js +20 -20
  34. package/dist/bin/pushary-transcript-register.js +17 -17
  35. package/dist/bin/pushary-transcripts.js +5 -5
  36. package/dist/bin/pushary-upgrade.js +14 -14
  37. package/dist/bin/pushary-wait.js +3 -3
  38. package/dist/{chunk-WIKEADOS.js → chunk-2GLOHBYB.js} +1 -1
  39. package/dist/{chunk-SW37HB27.js → chunk-3RVCQDC4.js} +1 -1
  40. package/dist/{chunk-XDMHLQMH.js → chunk-53QCTSWY.js} +4 -4
  41. package/dist/{chunk-6VXZKOBB.js → chunk-5B5QV3KC.js} +8 -8
  42. package/dist/{chunk-ROTIPRM4.js → chunk-5KLAETSU.js} +1 -1
  43. package/dist/{chunk-VDTC5DEM.js → chunk-6C6MS57P.js} +1 -1
  44. package/dist/{chunk-YX3U2CLP.js → chunk-6CYB77VD.js} +6 -6
  45. package/dist/{chunk-FU5SQKAY.js → chunk-6LRGZJFB.js} +9 -20
  46. package/dist/{chunk-VCKQ45QA.js → chunk-A76GNRIK.js} +1 -1
  47. package/dist/{chunk-3SNTEHOH.js → chunk-B35OCFXH.js} +4 -4
  48. package/dist/{chunk-ICUBJNFL.js → chunk-CP34FI4B.js} +2 -2
  49. package/dist/{chunk-LYWTLNMG.js → chunk-DOD3A6EU.js} +4 -4
  50. package/dist/{chunk-AXSDMDJI.js → chunk-FAJ4R7IB.js} +1 -1
  51. package/dist/{chunk-EHQC3GWL.js → chunk-HB2KB7QL.js} +1 -1
  52. package/dist/{chunk-IBRX7LRE.js → chunk-HFQ7WSHZ.js} +6 -7
  53. package/dist/{chunk-BYH75I7Y.js → chunk-IRLTW6KF.js} +1 -1
  54. package/dist/{chunk-KDPYXMUI.js → chunk-J44RPHUZ.js} +2 -2
  55. package/dist/{chunk-DOKFLZWL.js → chunk-JQU6PMH4.js} +14 -8
  56. package/dist/{chunk-YRXVC4HL.js → chunk-K6CH5NVW.js} +1 -1
  57. package/dist/{chunk-H4VNAOCG.js → chunk-LBNAGGLV.js} +1 -1
  58. package/dist/{chunk-B3557BDL.js → chunk-LX4NNYII.js} +2 -2
  59. package/dist/{chunk-5ODZEFP3.js → chunk-M4TVEMLH.js} +1 -1
  60. package/dist/{chunk-GGYH6LIE.js → chunk-NIXVMMJM.js} +1 -1
  61. package/dist/{chunk-C2FYSFTQ.js → chunk-NQGYPTJQ.js} +1 -1
  62. package/dist/{chunk-A4AIISZZ.js → chunk-OBYC6SN4.js} +1 -1
  63. package/dist/{chunk-QFAZ6QCT.js → chunk-OPR2BPD4.js} +1 -1
  64. package/dist/{chunk-HUZW6SEO.js → chunk-OUAE3GKO.js} +2 -2
  65. package/dist/{chunk-6WJKYD3Q.js → chunk-QXIF6R4P.js} +11 -8
  66. package/dist/{chunk-OYTOLQ3N.js → chunk-SI7GYBQP.js} +1 -1
  67. package/dist/{chunk-VF7YOT2W.js → chunk-SJLGOVC6.js} +1 -1
  68. package/dist/{chunk-DNLFSRCF.js → chunk-TZHDKRMG.js} +2 -2
  69. package/dist/{chunk-K7MLXXPY.js → chunk-V47GITZV.js} +3 -3
  70. package/dist/{chunk-VTUN7WSG.js → chunk-VZD2GEKB.js} +1 -1
  71. package/dist/{chunk-4AXWBCCO.js → chunk-W2MG2P46.js} +4 -4
  72. package/dist/{chunk-IZKCA35M.js → chunk-WU6LSXJ6.js} +2 -2
  73. package/dist/{chunk-67RNDRKL.js → chunk-XL3RKJYQ.js} +49 -4
  74. package/dist/{chunk-VOC55PQV.js → chunk-XOOWC62T.js} +1 -1
  75. package/dist/{chunk-CDSA3NTB.js → chunk-XPPXOKIG.js} +1 -1
  76. package/dist/{chunk-DGUMR5LZ.js → chunk-YJDRHQLG.js} +5 -5
  77. package/dist/src/index.js +10 -10
  78. package/package.json +1 -1
@@ -3,7 +3,7 @@ import {
3
3
  decodePublicKey,
4
4
  generateSessionKey,
5
5
  wrapSessionKey
6
- } from "./chunk-CDSA3NTB.js";
6
+ } from "./chunk-XPPXOKIG.js";
7
7
  import {
8
8
  fetchTranscriptRecipients,
9
9
  uploadTranscriptRecords
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  describeKeyCheck,
3
3
  keyCheckFromResponse
4
- } from "./chunk-SW37HB27.js";
4
+ } from "./chunk-3RVCQDC4.js";
5
5
  import {
6
6
  createIo
7
7
  } from "./chunk-5RUIFDTP.js";
@@ -4,11 +4,11 @@ import {
4
4
  forgetBlockedActionHint,
5
5
  hasBlockedActionHint,
6
6
  recordBlockedActionHint
7
- } from "./chunk-XDMHLQMH.js";
7
+ } from "./chunk-53QCTSWY.js";
8
8
  import {
9
9
  isGatingMoment,
10
10
  recordKeylessMoment
11
- } from "./chunk-VOC55PQV.js";
11
+ } from "./chunk-XOOWC62T.js";
12
12
  import {
13
13
  denyReasonFrom,
14
14
  isDeferAnswer
@@ -24,7 +24,7 @@ import {
24
24
  reportEvent,
25
25
  settleQuestionsForToolUse,
26
26
  throttlePass
27
- } from "./chunk-DGUMR5LZ.js";
27
+ } from "./chunk-YJDRHQLG.js";
28
28
  import {
29
29
  UNNAMED_ACTION,
30
30
  deriveAction,
@@ -34,7 +34,7 @@ import {
34
34
  describeToolCall,
35
35
  permissionDeniedAction,
36
36
  scopePathFor
37
- } from "./chunk-VCKQ45QA.js";
37
+ } from "./chunk-A76GNRIK.js";
38
38
  import {
39
39
  DECISION_STOP_REASON,
40
40
  askUser,
@@ -49,7 +49,7 @@ import {
49
49
  } from "./chunk-LGXUGYUH.js";
50
50
  import {
51
51
  getMachineId
52
- } from "./chunk-IZKCA35M.js";
52
+ } from "./chunk-WU6LSXJ6.js";
53
53
  import {
54
54
  getApiKey,
55
55
  getBaseUrl
@@ -73,7 +73,7 @@ import {
73
73
  parseAgentQuestions,
74
74
  resolveGate,
75
75
  stoppedOutput
76
- } from "./chunk-HUZW6SEO.js";
76
+ } from "./chunk-OUAE3GKO.js";
77
77
 
78
78
  // src/decision-episode.ts
79
79
  var EPISODE_PATH = "/api/agent/decision-episode";
@@ -2,16 +2,16 @@ import {
2
2
  CLAUDE_HOOK_EVENTS,
3
3
  GEMINI_HOOK_EVENTS,
4
4
  hasGeminiHooks
5
- } from "./chunk-IBRX7LRE.js";
5
+ } from "./chunk-HFQ7WSHZ.js";
6
6
  import {
7
7
  CODEX_HOOK_EVENTS,
8
8
  hasCodexHooks
9
- } from "./chunk-67RNDRKL.js";
9
+ } from "./chunk-XL3RKJYQ.js";
10
10
  import {
11
11
  CURSOR_GATE_EVENTS,
12
12
  HOOK_LOCATOR_BINARY,
13
13
  hookCommandHoldBudget
14
- } from "./chunk-HUZW6SEO.js";
14
+ } from "./chunk-OUAE3GKO.js";
15
15
 
16
16
  // src/diagnostics/wiring.ts
17
17
  var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -73,31 +73,20 @@ var toSeconds = (timeout, unit) => {
73
73
  };
74
74
  var registeredHooks = (entries, shape, unit) => {
75
75
  if (!Array.isArray(entries)) return [];
76
- return entries.flatMap((entry, entryIndex) => {
76
+ return entries.flatMap((entry) => {
77
77
  const container = record(entry);
78
78
  if (!container) return [];
79
79
  const hooks = shape === "nested" ? Array.isArray(container.hooks) ? container.hooks : [] : [container];
80
- return hooks.flatMap((hook, hookIndex) => {
80
+ return hooks.flatMap((hook) => {
81
81
  const command = record(hook)?.command;
82
82
  if (typeof command !== "string" || command.trim() === "") return [];
83
- return [{
84
- command,
85
- timeoutSeconds: toSeconds(record(hook)?.timeout, unit),
86
- order: [entryIndex, hookIndex]
87
- }];
83
+ return [{ command, timeoutSeconds: toSeconds(record(hook)?.timeout, unit) }];
88
84
  });
89
85
  });
90
86
  };
91
- var runsBefore = (a, b) => a[0] < b[0] || a[0] === b[0] && a[1] < b[1];
92
87
  var holdersOnEvent = (event, hooks) => {
93
- const ours = hooks.find((hook) => pusharyHookExecutable(hook.command) !== null);
94
- if (!ours) return [];
95
- return hooks.filter((hook) => pusharyHookExecutable(hook.command) === null).map((hook) => ({
96
- event,
97
- command: hook.command,
98
- timeoutSeconds: hook.timeoutSeconds,
99
- position: runsBefore(hook.order, ours.order) ? "before" : "after"
100
- }));
88
+ if (!hooks.some((hook) => pusharyHookExecutable(hook.command) !== null)) return [];
89
+ return hooks.filter((hook) => pusharyHookExecutable(hook.command) === null).map((hook) => ({ event, command: hook.command, timeoutSeconds: hook.timeoutSeconds }));
101
90
  };
102
91
  var otherHolders = (hooks, events, shape, unit) => {
103
92
  const table = record(hooks);
@@ -134,7 +123,7 @@ var describeHoldTimeout = (holder) => {
134
123
  if (seconds >= 60 && seconds % 60 === 0) return `${seconds / 60}m timeout`;
135
124
  return `${seconds}s timeout`;
136
125
  };
137
- var describeOtherHolder = (holder) => `another hook on ${holder.event}: ${holderExecutable(holder.command)} (${describeHoldTimeout(holder)}, runs ${holder.position} ours)`;
126
+ var describeOtherHolder = (holder) => `another hook also registered on ${holder.event}: ${holderExecutable(holder.command)} (${describeHoldTimeout(holder)})`;
138
127
  var describeHoldSentence = (agentLabel) => `${agentLabel} waits for every hook on an event, so the terminal cannot move until that one returns, however fast your phone answered.`;
139
128
 
140
129
  export {
@@ -6,7 +6,7 @@ import {
6
6
  GATE_MAX_TOOL_INPUTS,
7
7
  redactSecrets,
8
8
  redactSecretsDeep
9
- } from "./chunk-HUZW6SEO.js";
9
+ } from "./chunk-OUAE3GKO.js";
10
10
 
11
11
  // ../hook-mapping/src/describe.ts
12
12
  import { isAbsolute, relative, resolve } from "path";
@@ -2,24 +2,24 @@ import {
2
2
  detectProviderLiveCapabilities,
3
3
  hasSpawnProvider,
4
4
  resolveControlPolicy
5
- } from "./chunk-DNLFSRCF.js";
5
+ } from "./chunk-TZHDKRMG.js";
6
6
  import {
7
7
  daemonHasRemoteProof,
8
8
  daemonServiceManagerAvailable,
9
9
  hasDaemonServiceDefinition,
10
10
  readDaemonNeedsLogin,
11
11
  readDaemonStatus
12
- } from "./chunk-LYWTLNMG.js";
12
+ } from "./chunk-DOD3A6EU.js";
13
13
  import {
14
14
  getMachineId
15
- } from "./chunk-IZKCA35M.js";
15
+ } from "./chunk-WU6LSXJ6.js";
16
16
  import {
17
17
  getPackageVersion
18
18
  } from "./chunk-DINDL2CF.js";
19
19
  import {
20
20
  readControlMode,
21
21
  readKeySource
22
- } from "./chunk-VF7YOT2W.js";
22
+ } from "./chunk-SJLGOVC6.js";
23
23
  import {
24
24
  getBaseUrl
25
25
  } from "./chunk-2UMNXADU.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SETUP_FLAGS
3
- } from "./chunk-H4VNAOCG.js";
3
+ } from "./chunk-LBNAGGLV.js";
4
4
  import {
5
5
  parseFlags
6
6
  } from "./chunk-GMXKITVA.js";
@@ -14,7 +14,7 @@ import {
14
14
  CLAUDE_CONNECTOR_URL,
15
15
  COWORK_CONNECTOR_LIMIT,
16
16
  COWORK_STANDING_INSTRUCTIONS
17
- } from "./chunk-HUZW6SEO.js";
17
+ } from "./chunk-OUAE3GKO.js";
18
18
 
19
19
  // src/cli/cowork.ts
20
20
  import { readFileSync } from "fs";
@@ -4,23 +4,23 @@ import {
4
4
  } from "./chunk-XHKBHWLX.js";
5
5
  import {
6
6
  getMachineId
7
- } from "./chunk-IZKCA35M.js";
7
+ } from "./chunk-WU6LSXJ6.js";
8
8
  import {
9
9
  pusharyDir,
10
10
  resolveGlobalBinary
11
- } from "./chunk-67RNDRKL.js";
11
+ } from "./chunk-XL3RKJYQ.js";
12
12
  import {
13
13
  getPackageVersion
14
14
  } from "./chunk-DINDL2CF.js";
15
15
  import {
16
16
  readControlMode
17
- } from "./chunk-VF7YOT2W.js";
17
+ } from "./chunk-SJLGOVC6.js";
18
18
  import {
19
19
  readJsonSafe,
20
20
  writeFileAtomic,
21
21
  writeJsonAtomic,
22
22
  writeJsonAtomicDurable
23
- } from "./chunk-VTUN7WSG.js";
23
+ } from "./chunk-VZD2GEKB.js";
24
24
  import {
25
25
  getApiKey
26
26
  } from "./chunk-2UMNXADU.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolvePathBinary
3
- } from "./chunk-67RNDRKL.js";
3
+ } from "./chunk-XL3RKJYQ.js";
4
4
 
5
5
  // src/hermes-config.ts
6
6
  import { execFileSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_BUDGETS,
3
3
  OPENCODE_APPROVAL_EVENT
4
- } from "./chunk-HUZW6SEO.js";
4
+ } from "./chunk-OUAE3GKO.js";
5
5
 
6
6
  // src/opencode-plugin.ts
7
7
  var OPENCODE_PLUGIN_MARKER = "pushary-opencode-plugin w1";
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  NOTIFICATION_MATCHED_TYPES,
3
3
  POSTTOOLUSE_MIRRORED_TOOLS
4
- } from "./chunk-QFAZ6QCT.js";
4
+ } from "./chunk-OPR2BPD4.js";
5
5
  import {
6
- isProtectedByScope
7
- } from "./chunk-67RNDRKL.js";
6
+ isProtectedByScope,
7
+ registerHookEntry
8
+ } from "./chunk-XL3RKJYQ.js";
8
9
  import {
9
10
  CLAUDE_PRETOOLUSE_MATCHER,
10
11
  HOOK_BUDGETS,
11
12
  HOOK_LOCATOR_BINARY
12
- } from "./chunk-HUZW6SEO.js";
13
+ } from "./chunk-OUAE3GKO.js";
13
14
 
14
15
  // src/gemini-config.ts
15
16
  var GEMINI_HOOK_BINARY = "pushary-gemini-hook";
@@ -51,8 +52,7 @@ var addGeminiHooks = (settings, command) => {
51
52
  const hooks = ensureRecord(settings, "hooks");
52
53
  for (const definition of GEMINI_HOOK_EVENTS) {
53
54
  const existing = Array.isArray(hooks[definition.event]) ? hooks[definition.event] : [];
54
- const entries = existing.filter((entry) => !isPusharyGeminiHook(entry));
55
- entries.push({
55
+ hooks[definition.event] = registerHookEntry(existing, isPusharyGeminiHook, {
56
56
  ...definition.matcher ? { matcher: definition.matcher } : {},
57
57
  hooks: [{
58
58
  name: "pushary",
@@ -61,7 +61,6 @@ var addGeminiHooks = (settings, command) => {
61
61
  timeout: definition.timeoutMs
62
62
  }]
63
63
  });
64
- hooks[definition.event] = entries;
65
64
  }
66
65
  };
67
66
  var removeGeminiHooks = (settings, scope) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HOOK_LOCATOR_BINARY
3
- } from "./chunk-HUZW6SEO.js";
3
+ } from "./chunk-OUAE3GKO.js";
4
4
 
5
5
  // src/diagnostics/bridge.ts
6
6
  import { execFileSync } from "child_process";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-67RNDRKL.js";
3
+ } from "./chunk-XL3RKJYQ.js";
4
4
  import {
5
5
  readJsonSafe
6
- } from "./chunk-VTUN7WSG.js";
6
+ } from "./chunk-VZD2GEKB.js";
7
7
 
8
8
  // src/process-ownership.ts
9
9
  import { createHash, randomUUID } from "crypto";
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  detectClaudeVersion
3
- } from "./chunk-YRXVC4HL.js";
3
+ } from "./chunk-K6CH5NVW.js";
4
4
  import {
5
5
  addClaudeMcpServer,
6
6
  addPusharyHooks,
7
7
  addPusharyToolPermissions
8
- } from "./chunk-6WJKYD3Q.js";
8
+ } from "./chunk-QXIF6R4P.js";
9
9
  import {
10
10
  claudeWired,
11
11
  codexWired,
12
12
  geminiWired
13
- } from "./chunk-FU5SQKAY.js";
13
+ } from "./chunk-6LRGZJFB.js";
14
14
  import {
15
15
  CLAUDE_HOOK_EVENTS,
16
16
  GEMINI_HOOK_BINARY,
@@ -21,7 +21,7 @@ import {
21
21
  needsReregistration,
22
22
  registrationSignatures,
23
23
  supportedClaudeEvents
24
- } from "./chunk-IBRX7LRE.js";
24
+ } from "./chunk-HFQ7WSHZ.js";
25
25
  import {
26
26
  CODEX_HOOK_BINARY,
27
27
  addCodexHookTrust,
@@ -31,19 +31,21 @@ import {
31
31
  codexConfigToml,
32
32
  codexHookPositions,
33
33
  codexHooksJson,
34
+ codexVacatedIndexes,
35
+ dropVacatedCodexHookTrust,
34
36
  guardBinary,
35
37
  hasCodexHooks,
36
38
  resolveGlobalBinDir,
37
39
  resolveGlobalBinary,
38
40
  vscodePluginMcp
39
- } from "./chunk-67RNDRKL.js";
41
+ } from "./chunk-XL3RKJYQ.js";
40
42
  import {
41
43
  readJsonSafe,
42
44
  writeJsonAtomic
43
- } from "./chunk-VTUN7WSG.js";
45
+ } from "./chunk-VZD2GEKB.js";
44
46
  import {
45
47
  HOOK_LOCATOR_BINARY
46
- } from "./chunk-HUZW6SEO.js";
48
+ } from "./chunk-OUAE3GKO.js";
47
49
 
48
50
  // src/reapply.ts
49
51
  import { join } from "path";
@@ -214,6 +216,7 @@ var reapplyCodexSettings = (apiKey, paths = {}) => {
214
216
  const command = guardBinary(resolveGlobalBinary(CODEX_HOOK_BINARY) ?? CODEX_HOOK_BINARY);
215
217
  let hooks = false;
216
218
  let mcp = false;
219
+ const vacated = codexVacatedIndexes(hooksConfig ?? void 0);
217
220
  if (hooksConfig != null) {
218
221
  try {
219
222
  addCodexHooks(hooksConfig, command);
@@ -224,7 +227,10 @@ var reapplyCodexSettings = (apiKey, paths = {}) => {
224
227
  }
225
228
  if (config != null) {
226
229
  try {
227
- if (hooks) addCodexHookTrust(config, hooksPath, command, codexHookPositions(hooksConfig ?? void 0));
230
+ if (hooks) {
231
+ dropVacatedCodexHookTrust(config, hooksPath, vacated);
232
+ addCodexHookTrust(config, hooksPath, command, codexHookPositions(hooksConfig ?? void 0));
233
+ }
228
234
  if (apiKey) {
229
235
  addCodexMcpServer(config, apiKey);
230
236
  mcp = true;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseVersion
3
- } from "./chunk-IBRX7LRE.js";
3
+ } from "./chunk-HFQ7WSHZ.js";
4
4
 
5
5
  // src/setup/agent-probe.ts
6
6
  import { execSync } from "child_process";
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-7QLSKOSU.js";
7
7
  import {
8
8
  isValidApiKey
9
- } from "./chunk-HUZW6SEO.js";
9
+ } from "./chunk-OUAE3GKO.js";
10
10
 
11
11
  // src/setup/options.ts
12
12
  var AGENT_CHOICES = ["claude_code", "codex", "gemini_cli", "hermes", "cursor", "vscode", "opencode", "custom"];
@@ -15,10 +15,10 @@ import {
15
15
  } from "./chunk-EYRGBYZG.js";
16
16
  import {
17
17
  reportedInstallSource
18
- } from "./chunk-VTUN7WSG.js";
18
+ } from "./chunk-VZD2GEKB.js";
19
19
  import {
20
20
  isAnswerSource
21
- } from "./chunk-HUZW6SEO.js";
21
+ } from "./chunk-OUAE3GKO.js";
22
22
 
23
23
  // src/reach.ts
24
24
  var reachVerdict = (channels) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  registerTranscript
3
- } from "./chunk-6VXZKOBB.js";
3
+ } from "./chunk-5B5QV3KC.js";
4
4
 
5
5
  // src/admission.ts
6
6
  import { readFileSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readConfigFileKey
3
- } from "./chunk-VF7YOT2W.js";
3
+ } from "./chunk-SJLGOVC6.js";
4
4
 
5
5
  // src/bell/fleet.ts
6
6
  import { closeSync, constants, futimesSync, lstatSync, mkdirSync, openSync, readdirSync, unlinkSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readTranscriptPreference
3
- } from "./chunk-VF7YOT2W.js";
3
+ } from "./chunk-SJLGOVC6.js";
4
4
 
5
5
  // src/transcript-setting.ts
6
6
  var transcriptEnvironmentPreference = () => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  writeJsonAtomicDurable
3
- } from "./chunk-VTUN7WSG.js";
3
+ } from "./chunk-VZD2GEKB.js";
4
4
 
5
5
  // src/transcript-recipient-pin.ts
6
6
  import { existsSync, mkdirSync, readFileSync, rmSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  PRETOOLUSE_GATED_TOOLS
3
- } from "./chunk-HUZW6SEO.js";
3
+ } from "./chunk-OUAE3GKO.js";
4
4
 
5
5
  // src/claude-tools.ts
6
6
  var POSTTOOLUSE_MIRROR_ONLY_TOOLS = ["TodoWrite", "Task", "WebFetch", "WebSearch"];
@@ -1397,8 +1397,8 @@ var claudePermissionDeniedOutput = (decision) => ({
1397
1397
  }
1398
1398
  });
1399
1399
  var CODEX_RESCUE_COMMAND_MAX_LENGTH = 2e3;
1400
- var CODEX_RESCUE_APPROVED = "The user approved this command from Pushary after the auto-reviewer denied it.";
1401
- var codexRescueRetryInstruction = (command) => command.length <= CODEX_RESCUE_COMMAND_MAX_LENGTH ? `Run it again exactly as before, unchanged: ${command}` : `Run it again exactly as before, unchanged. It is too long to repeat in full here and begins: ${command.slice(0, CODEX_RESCUE_COMMAND_MAX_LENGTH)}`;
1400
+ var CODEX_RESCUE_APPROVED = "I approved this command in Pushary after the auto-reviewer denied it. If it is denied again, stop and tell me.";
1401
+ var codexRescueRetryInstruction = (command) => command.length <= CODEX_RESCUE_COMMAND_MAX_LENGTH ? `Run it again now, exactly as before: ${command}` : `Run it again now, exactly as before. It is too long to repeat in full here and begins: ${command.slice(0, CODEX_RESCUE_COMMAND_MAX_LENGTH)}`;
1402
1402
  var codexStopRescueOutput = (decision, command) => decision === "allow" ? { decision: "block", reason: `${CODEX_RESCUE_APPROVED} ${codexRescueRetryInstruction(command)}` } : { continue: true };
1403
1403
  var stoppedOutput = (output, stopReason) => ({ ...output, continue: false, stopReason });
1404
1404
  var claudePreToolUseOutput = (decision, reason, updatedInput) => ({
@@ -1,16 +1,17 @@
1
1
  import {
2
2
  CLAUDE_HOOK_EVENTS,
3
3
  supportedClaudeEvents
4
- } from "./chunk-IBRX7LRE.js";
4
+ } from "./chunk-HFQ7WSHZ.js";
5
5
  import {
6
6
  guardBinary,
7
7
  holdBudgetOf,
8
- isProtectedByScope
9
- } from "./chunk-67RNDRKL.js";
8
+ isProtectedByScope,
9
+ registerHookEntry
10
+ } from "./chunk-XL3RKJYQ.js";
10
11
  import {
11
12
  HOOK_LOCATOR_BINARY,
12
13
  withHookHoldBudget
13
- } from "./chunk-HUZW6SEO.js";
14
+ } from "./chunk-OUAE3GKO.js";
14
15
 
15
16
  // src/claude-config.ts
16
17
  import { join } from "path";
@@ -126,12 +127,14 @@ var addPusharyHooks = (settings, binDir, version = null) => {
126
127
  const hooks = ensureRecord(settings, "hooks");
127
128
  const supported = new Map(supportedClaudeEvents(version).map((hook) => [hook.event, hook]));
128
129
  for (const known of CLAUDE_HOOK_EVENTS) {
129
- const current = hooks[known.event];
130
- const others = (Array.isArray(current) ? current : []).filter((item) => !isPusharyHook(item));
130
+ const current = Array.isArray(hooks[known.event]) ? hooks[known.event] : [];
131
131
  const definition = supported.get(known.event);
132
132
  if (definition) {
133
- hooks[known.event] = [...others, entry(definition, resolve)];
134
- } else if (others.length > 0) {
133
+ hooks[known.event] = registerHookEntry(current, isPusharyHook, entry(definition, resolve));
134
+ continue;
135
+ }
136
+ const others = current.filter((item) => !isPusharyHook(item));
137
+ if (others.length > 0) {
135
138
  hooks[known.event] = others;
136
139
  } else {
137
140
  delete hooks[known.event];
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_HOLD_BUDGET_ENV,
3
3
  hookHoldBudgetProof
4
- } from "./chunk-HUZW6SEO.js";
4
+ } from "./chunk-OUAE3GKO.js";
5
5
 
6
6
  // src/hold-budget.ts
7
7
  var takeHookHoldBudget = (args = process.argv.slice(2), env = process.env) => {
@@ -4,7 +4,7 @@ import {
4
4
  resolveInstallSourceFor,
5
5
  writeFileAtomic,
6
6
  writeJsonAtomic
7
- } from "./chunk-VTUN7WSG.js";
7
+ } from "./chunk-VZD2GEKB.js";
8
8
  import {
9
9
  configFilePath
10
10
  } from "./chunk-2UMNXADU.js";
@@ -2,10 +2,10 @@ import {
2
2
  resolveBinary,
3
3
  resolveGlobalPackageVersion,
4
4
  resolvePackageVersionFromBinary
5
- } from "./chunk-67RNDRKL.js";
5
+ } from "./chunk-XL3RKJYQ.js";
6
6
  import {
7
7
  MANAGED_PROVIDERS
8
- } from "./chunk-HUZW6SEO.js";
8
+ } from "./chunk-OUAE3GKO.js";
9
9
 
10
10
  // src/live-capabilities.ts
11
11
  var CLAUDE_BRIDGE_CAPABILITY = "claude-bridge";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  openCodeConfigDirFrom
3
- } from "./chunk-EHQC3GWL.js";
3
+ } from "./chunk-HB2KB7QL.js";
4
4
  import {
5
5
  codexHomeFrom
6
- } from "./chunk-67RNDRKL.js";
6
+ } from "./chunk-XL3RKJYQ.js";
7
7
 
8
8
  // src/vscode-config.ts
9
9
  import { homedir } from "os";
@@ -264,7 +264,7 @@ You have Pushary MCP tools that reach the user on their phone. Use them proactiv
264
264
 
265
265
  - When you need the user to make a decision or answer a clarifying question, call \`ask_user\` instead of guessing or stalling. Use type "confirm" for yes/no, "select" for a fixed set of options, and "input" for free text. Read \`answered\`, \`status\` and the returned handoff instead of assuming the tool blocked. Silence is not consent; choice/text answers do not authorize a separate action.
266
266
  - Ask once, on one channel. If you also have a built-in way to prompt the user, use that or \`ask_user\` for a given question, never both. \`ask_user\` is the one that reaches the user when they are away from this machine, so prefer it. Raising both strands the user in whichever prompt you are not waiting on.
267
- - Honor authorization already granted in this session. Ask before a risky or irreversible action outside that authorization, or when an enforced host policy requires it. Do not ask again for an already authorized step, and never bypass an enforced gate.
267
+ - Honor authorization already granted in this session. Ask before a risky or irreversible action outside that authorization, or when an enforced host policy requires it. Do not ask again for an already authorized step, and never bypass an enforced gate. When a Pushary hook result says the user approved a specific command after a denial, rerunning that exact command is the approved path and not a bypass of that gate.
268
268
  - Call \`propose_scope\` only for an unresolved or requested file boundary. A ratified scope narrows what may proceed; it does not bypass other approval rules. Do not add a plan approval merely because work spans several files, and do not propose a new scope mid-run just to widen it. Let the installed gate request any scope expansion before the edit executes.
269
269
  - When you are blocked, stuck, or hit an error you cannot resolve on your own, call \`send_notification\` so the user knows, and call \`ask_user\` if you need a decision to continue.
270
270
  - When meaningful work finishes while the user is away, or they requested an alert, call \`send_notification\` so the user knows it is done. Skip trivial completions and duplicate reports to someone already reading. Always pass \`context\` with a \`type\` of "task_complete", "error" or "info": it is what tells Pushary this is a task update, so the user's own setting for where updates land can route it.
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2UMNXADU.js";
4
4
  import {
5
5
  normalizeInstallSource
6
- } from "./chunk-HUZW6SEO.js";
6
+ } from "./chunk-OUAE3GKO.js";
7
7
 
8
8
  // src/cli/fsx.ts
9
9
  import { copyFileSync, existsSync, fsyncSync, mkdirSync, openSync, closeSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "fs";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  AGENT_CHOICES
3
- } from "./chunk-H4VNAOCG.js";
3
+ } from "./chunk-LBNAGGLV.js";
4
4
  import {
5
5
  isBridgeLocator
6
- } from "./chunk-BYH75I7Y.js";
6
+ } from "./chunk-IRLTW6KF.js";
7
7
  import {
8
8
  pusharyHookExecutable
9
- } from "./chunk-FU5SQKAY.js";
9
+ } from "./chunk-6LRGZJFB.js";
10
10
  import {
11
11
  BELL_HOOK_BINARY
12
- } from "./chunk-WIKEADOS.js";
12
+ } from "./chunk-2GLOHBYB.js";
13
13
 
14
14
  // src/setup/hook-ownership.ts
15
15
  var commandsIn = (value) => {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-67RNDRKL.js";
3
+ } from "./chunk-XL3RKJYQ.js";
4
4
  import {
5
5
  writeFileAtomic
6
- } from "./chunk-VTUN7WSG.js";
6
+ } from "./chunk-VZD2GEKB.js";
7
7
 
8
8
  // src/identity.ts
9
9
  import { randomUUID } from "crypto";