@pushary/agent-hooks 0.91.0 → 0.92.1

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 (44) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/bin/pushary-bell.js +1 -1
  3. package/dist/bin/pushary-claude.js +30 -8
  4. package/dist/bin/pushary-clean.js +7 -7
  5. package/dist/bin/pushary-codex-bridge.js +3 -3
  6. package/dist/bin/pushary-codex-hook.js +3 -3
  7. package/dist/bin/pushary-codex.js +3 -3
  8. package/dist/bin/pushary-daemon.js +9 -9
  9. package/dist/bin/pushary-disconnect.js +2 -2
  10. package/dist/bin/pushary-doctor.js +7 -7
  11. package/dist/bin/pushary-elicitation-hook.js +2 -2
  12. package/dist/bin/pushary-gemini-bridge.js +3 -3
  13. package/dist/bin/pushary-gemini-hook.js +3 -3
  14. package/dist/bin/pushary-hook.js +4 -4
  15. package/dist/bin/pushary-login.js +3 -3
  16. package/dist/bin/pushary-logout.js +1 -1
  17. package/dist/bin/pushary-notification-hook.js +3 -3
  18. package/dist/bin/pushary-opencode-hook.js +3 -3
  19. package/dist/bin/pushary-permission-denied-hook.js +4 -4
  20. package/dist/bin/pushary-permission-hook.js +4 -4
  21. package/dist/bin/pushary-post-hook.js +3 -3
  22. package/dist/bin/pushary-prompt-hook.js +3 -3
  23. package/dist/bin/pushary-session-end-hook.js +3 -3
  24. package/dist/bin/pushary-session-start-hook.js +18 -3
  25. package/dist/bin/pushary-setup.js +10 -10
  26. package/dist/bin/pushary-status.js +3 -3
  27. package/dist/bin/pushary-stop-hook.js +3 -3
  28. package/dist/bin/pushary-stopfailure-hook.js +3 -3
  29. package/dist/bin/pushary-upgrade.js +8 -8
  30. package/dist/{chunk-AWHCZOZO.js → chunk-2ACC5M7F.js} +1 -1
  31. package/dist/{chunk-YTD6PJM7.js → chunk-2XQSN66Q.js} +1 -1
  32. package/dist/{chunk-CRVJCKIN.js → chunk-3HS4YGHB.js} +1 -1
  33. package/dist/{chunk-GQ5ZC2QY.js → chunk-4TFXV5MW.js} +1 -1
  34. package/dist/{chunk-BVNYTQ5I.js → chunk-CV2YD2JR.js} +2 -0
  35. package/dist/{chunk-YTDH3XCE.js → chunk-HDORB7WD.js} +1 -1
  36. package/dist/{chunk-VAMBUKXH.js → chunk-I3ORVBTP.js} +106 -14
  37. package/dist/{chunk-ELHCIEMM.js → chunk-I7W3UTDK.js} +16 -1
  38. package/dist/{chunk-B65JGBIZ.js → chunk-QCXKQJTG.js} +2 -2
  39. package/dist/{chunk-4IEW4ZRF.js → chunk-RQPQSJJH.js} +2 -2
  40. package/dist/{chunk-Z4XCN2HH.js → chunk-SQYBP3QQ.js} +2 -2
  41. package/dist/{chunk-TVZQMPB7.js → chunk-YXDYKECP.js} +1 -1
  42. package/dist/{chunk-WGKC6PU2.js → chunk-ZMKKK6DC.js} +2 -2
  43. package/dist/src/index.js +4 -4
  44. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.92.1
4
+
5
+ ### A rejected key is an answer, not an empty poll
6
+
7
+ `pollAgent` returned `{ command: null, mode: null }` for every non-OK response,
8
+ so a 401 was indistinguishable from a healthy poll with nothing queued. That
9
+ landed on the success branch of `startCommandPoller`, which resets `errorStreak`
10
+ to zero, so the backoff never engaged and the wrapper polled a dead key at the
11
+ idle cadence forever. Because `mode` was null, `onModeState` never fired, and
12
+ `onModeState` is the only place `dualMode` sets `killed` and stops the active
13
+ leg. A wrapper whose key the server rejects therefore reported `kill=false` to
14
+ itself indefinitely: remote stop could not reach it, phone messages never
15
+ landed, and nothing was printed.
16
+
17
+ `PollResult` now carries `rejected`, set only for 401 and 403, which is the same
18
+ line `fetchModeState` already drew between an answer and a blip. A rejected poll
19
+ takes the error path, so the existing exponential backoff applies, and the
20
+ wrapper prints once that remote stop and phone messages are not active. A 500 or
21
+ a dropped connection is still a blip and still retried at the normal cadence.
22
+
23
+ A rejected response is also no longer trusted for its contents: neither the
24
+ command nor the mode state it carries is applied.
25
+
26
+ ## 0.92.0
27
+
28
+ ### A Claude Code upgrade registers the events it just gained
29
+
30
+ `CLAUDE_HOOK_EVENTS` gates each hook on the oldest Claude Code that understands
31
+ it, and the supported set was filtered by the version detected when the hooks
32
+ were written. Nothing re-ran that filter except `pushary upgrade`, so an event
33
+ your Claude Code gained reached you when Pushary next shipped rather than when
34
+ Claude did: the hook sat in the table, supported by your CLI, and unregistered.
35
+
36
+ SessionStart now asks the question, because that is the moment an upgrade becomes
37
+ observable. The answer costs about 5 ms of local reads and writes nothing unless
38
+ the event set actually moved. A machine wired against an older Claude picks up
39
+ the newer events on its next session.
40
+
41
+ It leaves three things alone. Hooks the macOS app wrote are never rewritten: the
42
+ app owns that wiring and the CLI's writer would replace its locator with the npm
43
+ bin. A patch bump that adds no events refreshes only the receipt, so settings.json
44
+ is not rewritten every time Claude Code ships. A machine with nothing wired is
45
+ left to `setup`.
46
+
47
+ The settings write is now atomic — temp file, fsync, rename — because several
48
+ sessions can start in the same moment and two plain writes interleaving is a torn
49
+ settings.json.
50
+
3
51
  ## 0.91.0
4
52
 
5
53
  ### Setup adopts the key the Mac app is already signed in with
@@ -15,7 +15,7 @@ import "../chunk-EZIEXHYM.js";
15
15
  import "../chunk-L4ZCFMWW.js";
16
16
  import {
17
17
  claudeSettings
18
- } from "../chunk-BVNYTQ5I.js";
18
+ } from "../chunk-CV2YD2JR.js";
19
19
  import {
20
20
  createIo
21
21
  } from "../chunk-5RUIFDTP.js";
@@ -7,7 +7,7 @@ import {
7
7
  } from "../chunk-YKLCWWEI.js";
8
8
  import {
9
9
  ensureDaemonRunning
10
- } from "../chunk-Z4XCN2HH.js";
10
+ } from "../chunk-SQYBP3QQ.js";
11
11
  import {
12
12
  buildTranscriptRecords,
13
13
  decodePublicKey,
@@ -26,7 +26,7 @@ import {
26
26
  describeIdleWindow,
27
27
  startProcessOwnership,
28
28
  withSpawnProcessOwnership
29
- } from "../chunk-GQ5ZC2QY.js";
29
+ } from "../chunk-4TFXV5MW.js";
30
30
  import {
31
31
  needsShell,
32
32
  spawnClaude
@@ -41,7 +41,7 @@ import {
41
41
  phoneDrivenEnv,
42
42
  repoKeyFor,
43
43
  reportEvent
44
- } from "../chunk-TVZQMPB7.js";
44
+ } from "../chunk-YXDYKECP.js";
45
45
  import {
46
46
  DEFAULT_SESSION,
47
47
  askUser,
@@ -62,8 +62,8 @@ import {
62
62
  } from "../chunk-L4E2BIJ2.js";
63
63
  import {
64
64
  getMachineId
65
- } from "../chunk-AWHCZOZO.js";
66
- import "../chunk-BVNYTQ5I.js";
65
+ } from "../chunk-2ACC5M7F.js";
66
+ import "../chunk-CV2YD2JR.js";
67
67
  import "../chunk-DINDL2CF.js";
68
68
  import "../chunk-OSALSIUF.js";
69
69
  import "../chunk-BC3VCZ3E.js";
@@ -744,6 +744,8 @@ var FAST_DECAY_TICKS = 3;
744
744
  var MAX_ERROR_BACKOFF_MS = 12e4;
745
745
  var MAX_ERROR_STREAK = 6;
746
746
  var REQUEST_TIMEOUT_MS = 1e4;
747
+ var PollRejectedError = class extends Error {
748
+ };
747
749
  var startCommandPoller = (opts) => {
748
750
  const drain = opts.drain ?? drainPendingCommand;
749
751
  const slow = opts.slowPollMs ?? SLOW_POLL_MS;
@@ -754,6 +756,16 @@ var startCommandPoller = (opts) => {
754
756
  let inflight;
755
757
  let idleTicks = 0;
756
758
  let errorStreak = 0;
759
+ let authRejectionReported = false;
760
+ const reportAuthRejection = () => {
761
+ if (authRejectionReported) return;
762
+ authRejectionReported = true;
763
+ try {
764
+ opts.onAuthRejected?.();
765
+ } catch {
766
+ return;
767
+ }
768
+ };
757
769
  const jitter = (ms) => {
758
770
  const r = opts.jitter ? opts.jitter() : Math.random();
759
771
  return Math.max(1, Math.round(ms * (0.85 + r * 0.3)));
@@ -789,6 +801,10 @@ var startCommandPoller = (opts) => {
789
801
  let command;
790
802
  if (opts.poll) {
791
803
  const result = await opts.poll(opts.apiKey, opts.getSessionId?.(), wantCommands, controller.signal);
804
+ if (result.rejected) {
805
+ reportAuthRejection();
806
+ throw new PollRejectedError();
807
+ }
792
808
  command = result.command;
793
809
  if (result.mode && opts.onModeState) {
794
810
  try {
@@ -845,6 +861,7 @@ var startCommandPoller = (opts) => {
845
861
 
846
862
  // src/wrapper/pollClient.ts
847
863
  var APPROVAL_MODES = /* @__PURE__ */ new Set(["push_only", "terminal_only", "push_first", "notify_only"]);
864
+ var isRejection = (status) => status === 401 || status === 403;
848
865
  var pollAgent = async (apiKey, sessionId, wantCommand, signal, baseUrl = getBaseUrl(), machineId) => {
849
866
  try {
850
867
  const sessionKey = sessionId || DEFAULT_SESSION;
@@ -894,7 +911,7 @@ var pollAgent = async (apiKey, sessionId, wantCommand, signal, baseUrl = getBase
894
911
  }),
895
912
  signal
896
913
  });
897
- if (!response.ok) return { command: null, mode: null };
914
+ if (!response.ok) return { command: null, mode: null, rejected: isRejection(response.status) };
898
915
  const data = await response.json();
899
916
  const claimedCommand = (id, text) => ({
900
917
  id,
@@ -923,9 +940,9 @@ var pollAgent = async (apiKey, sessionId, wantCommand, signal, baseUrl = getBase
923
940
  policyVersion: typeof data.policyVersion === "string" && data.policyVersion.length > 0 ? data.policyVersion : null,
924
941
  relayUrl: typeof data.relayUrl === "string" && data.relayUrl.length > 0 ? data.relayUrl : null
925
942
  };
926
- return { command, mode };
943
+ return { command, mode, rejected: false };
927
944
  } catch {
928
- return { command: null, mode: null };
945
+ return { command: null, mode: null, rejected: false };
929
946
  }
930
947
  };
931
948
 
@@ -1734,6 +1751,11 @@ var runDualMode = async (binary, args2, startingMode) => {
1734
1751
  // Relay-primary: idle the safety-net poll at 60s (see RELAY_FALLBACK_POLL_MS).
1735
1752
  // No relay advertised -> the poller IS the command path, so keep the default.
1736
1753
  slowPollMs: relayAdvertised ? RELAY_FALLBACK_POLL_MS : void 0,
1754
+ onAuthRejected: () => {
1755
+ process.stderr.write(
1756
+ "[pushary] this key was rejected \u2014 remote stop and phone messages are NOT active; run `pushary login` to reconnect\n"
1757
+ );
1758
+ },
1737
1759
  onModeState: (state) => {
1738
1760
  if (state.kill && !killed) {
1739
1761
  killed = true;
@@ -9,16 +9,16 @@ import {
9
9
  restoreHookTakeover,
10
10
  restoreMcpServer,
11
11
  runHermesPythonScript
12
- } from "../chunk-B65JGBIZ.js";
12
+ } from "../chunk-QCXKQJTG.js";
13
13
  import {
14
14
  removeInstructionBlock,
15
15
  shortenHome,
16
16
  unregisterPluginLocation,
17
17
  vscodeSettingsTargets
18
- } from "../chunk-CRVJCKIN.js";
18
+ } from "../chunk-3HS4YGHB.js";
19
19
  import {
20
20
  pusharyHookExecutable
21
- } from "../chunk-WGKC6PU2.js";
21
+ } from "../chunk-ZMKKK6DC.js";
22
22
  import {
23
23
  OPENCODE_PLUGIN_SIBLING,
24
24
  OPENCODE_PLUGIN_SIBLING_CONTENTS,
@@ -35,19 +35,19 @@ import {
35
35
  removeGeminiSettings,
36
36
  removePusharySettings,
37
37
  restoreClaudeMcpServer
38
- } from "../chunk-ELHCIEMM.js";
38
+ } from "../chunk-I7W3UTDK.js";
39
39
  import "../chunk-2LAHXHBR.js";
40
40
  import "../chunk-DSTLA2TC.js";
41
41
  import "../chunk-EZIEXHYM.js";
42
42
  import {
43
43
  disableDaemonService
44
- } from "../chunk-Z4XCN2HH.js";
44
+ } from "../chunk-SQYBP3QQ.js";
45
45
  import "../chunk-XHKBHWLX.js";
46
46
  import {
47
47
  execNpm
48
48
  } from "../chunk-L4ZCFMWW.js";
49
49
  import "../chunk-L4E2BIJ2.js";
50
- import "../chunk-AWHCZOZO.js";
50
+ import "../chunk-2ACC5M7F.js";
51
51
  import {
52
52
  claudeJson,
53
53
  claudeMcpReceipt,
@@ -73,7 +73,7 @@ import {
73
73
  restoreCodexHookTrust,
74
74
  vscodePluginDir,
75
75
  vscodePluginMcp
76
- } from "../chunk-BVNYTQ5I.js";
76
+ } from "../chunk-CV2YD2JR.js";
77
77
  import {
78
78
  rejectUnknownFlags
79
79
  } from "../chunk-GMXKITVA.js";
@@ -18,7 +18,7 @@ import {
18
18
  idleDeadlinePassed,
19
19
  startProcessOwnership,
20
20
  withSpawnProcessOwnership
21
- } from "../chunk-GQ5ZC2QY.js";
21
+ } from "../chunk-4TFXV5MW.js";
22
22
  import {
23
23
  spawnClaude
24
24
  } from "../chunk-XHKBHWLX.js";
@@ -27,8 +27,8 @@ import {
27
27
  } from "../chunk-L4ZCFMWW.js";
28
28
  import {
29
29
  getMachineId
30
- } from "../chunk-AWHCZOZO.js";
31
- import "../chunk-BVNYTQ5I.js";
30
+ } from "../chunk-2ACC5M7F.js";
31
+ import "../chunk-CV2YD2JR.js";
32
32
  import "../chunk-OSALSIUF.js";
33
33
  import "../chunk-BC3VCZ3E.js";
34
34
  import "../chunk-JW4KO5AF.js";
@@ -34,7 +34,7 @@ import {
34
34
  toCodexWire,
35
35
  toPolicyLookup,
36
36
  toPolicyLookups
37
- } from "../chunk-TVZQMPB7.js";
37
+ } from "../chunk-YXDYKECP.js";
38
38
  import {
39
39
  DEFAULT_SESSION,
40
40
  askUser,
@@ -53,10 +53,10 @@ import {
53
53
  } from "../chunk-L4E2BIJ2.js";
54
54
  import {
55
55
  getMachineId
56
- } from "../chunk-AWHCZOZO.js";
56
+ } from "../chunk-2ACC5M7F.js";
57
57
  import {
58
58
  canonicalJson
59
- } from "../chunk-BVNYTQ5I.js";
59
+ } from "../chunk-CV2YD2JR.js";
60
60
  import "../chunk-BSZYIAZL.js";
61
61
  import "../chunk-SAF6HGAA.js";
62
62
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  reportEvent
4
- } from "../chunk-TVZQMPB7.js";
4
+ } from "../chunk-YXDYKECP.js";
5
5
  import {
6
6
  askUser,
7
7
  waitForAnswer
@@ -9,8 +9,8 @@ import {
9
9
  import "../chunk-L4E2BIJ2.js";
10
10
  import {
11
11
  getMachineId
12
- } from "../chunk-AWHCZOZO.js";
13
- import "../chunk-BVNYTQ5I.js";
12
+ } from "../chunk-2ACC5M7F.js";
13
+ import "../chunk-CV2YD2JR.js";
14
14
  import "../chunk-BSZYIAZL.js";
15
15
  import "../chunk-SAF6HGAA.js";
16
16
  import "../chunk-7QLSKOSU.js";
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  inspectConfiguredManagedProviders
4
- } from "../chunk-VAMBUKXH.js";
5
- import "../chunk-YTDH3XCE.js";
4
+ } from "../chunk-I3ORVBTP.js";
5
+ import "../chunk-HDORB7WD.js";
6
6
  import {
7
7
  HEARTBEAT_INTERVAL_MS,
8
8
  sendHeartbeat
9
- } from "../chunk-YTD6PJM7.js";
10
- import "../chunk-WGKC6PU2.js";
11
- import "../chunk-ELHCIEMM.js";
9
+ } from "../chunk-2XQSN66Q.js";
10
+ import "../chunk-ZMKKK6DC.js";
11
+ import "../chunk-I7W3UTDK.js";
12
12
  import "../chunk-2LAHXHBR.js";
13
13
  import "../chunk-EZIEXHYM.js";
14
14
  import {
@@ -27,7 +27,7 @@ import {
27
27
  requestDaemonHandoff,
28
28
  stopDaemonRunning,
29
29
  writeDaemonNeedsLogin
30
- } from "../chunk-Z4XCN2HH.js";
30
+ } from "../chunk-SQYBP3QQ.js";
31
31
  import {
32
32
  detectProviderLiveCapabilities,
33
33
  hasSpawnProvider,
@@ -40,7 +40,7 @@ import {
40
40
  listProcessProofs,
41
41
  ownsLiveProcess,
42
42
  silentSpawnedProofs
43
- } from "../chunk-GQ5ZC2QY.js";
43
+ } from "../chunk-4TFXV5MW.js";
44
44
  import {
45
45
  spawnClaude
46
46
  } from "../chunk-XHKBHWLX.js";
@@ -49,8 +49,8 @@ import {
49
49
  } from "../chunk-L4ZCFMWW.js";
50
50
  import {
51
51
  getMachineId
52
- } from "../chunk-AWHCZOZO.js";
53
- import "../chunk-BVNYTQ5I.js";
52
+ } from "../chunk-2ACC5M7F.js";
53
+ import "../chunk-CV2YD2JR.js";
54
54
  import {
55
55
  writeHuman
56
56
  } from "../chunk-QCGNGEGE.js";
@@ -15,7 +15,7 @@ import {
15
15
  removeGeminiSettings,
16
16
  removePusharySettings,
17
17
  restoreClaudeMcpServer
18
- } from "../chunk-ELHCIEMM.js";
18
+ } from "../chunk-I7W3UTDK.js";
19
19
  import "../chunk-2LAHXHBR.js";
20
20
  import "../chunk-EZIEXHYM.js";
21
21
  import "../chunk-L4ZCFMWW.js";
@@ -32,7 +32,7 @@ import {
32
32
  geminiSettings,
33
33
  removeCodexHooks,
34
34
  removeCodexSettings
35
- } from "../chunk-BVNYTQ5I.js";
35
+ } from "../chunk-CV2YD2JR.js";
36
36
  import {
37
37
  exitOnHelpFlag
38
38
  } from "../chunk-BVBEURWJ.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "../chunk-GU3EJCVV.js";
9
9
  import {
10
10
  readMachineReadiness
11
- } from "../chunk-YTD6PJM7.js";
11
+ } from "../chunk-2XQSN66Q.js";
12
12
  import {
13
13
  CURSOR_GATE_SCRIPT,
14
14
  agentProbes,
@@ -22,7 +22,7 @@ import {
22
22
  liveBridgeProbe,
23
23
  resolveBridgeStub,
24
24
  vscodeSettingsTargets
25
- } from "../chunk-CRVJCKIN.js";
25
+ } from "../chunk-3HS4YGHB.js";
26
26
  import {
27
27
  claudeOtherHolders,
28
28
  claudeWired,
@@ -37,7 +37,7 @@ import {
37
37
  geminiWired,
38
38
  holdsLong,
39
39
  pusharyHookExecutable
40
- } from "../chunk-WGKC6PU2.js";
40
+ } from "../chunk-ZMKKK6DC.js";
41
41
  import {
42
42
  OPENCODE_PLUGIN_PLACEHOLDER,
43
43
  openCodePluginDir,
@@ -48,7 +48,7 @@ import {
48
48
  GEMINI_HOOK_BINARY,
49
49
  hasGeminiHooks,
50
50
  missingGeminiHookEvents
51
- } from "../chunk-ELHCIEMM.js";
51
+ } from "../chunk-I7W3UTDK.js";
52
52
  import "../chunk-2LAHXHBR.js";
53
53
  import "../chunk-EZIEXHYM.js";
54
54
  import {
@@ -59,7 +59,7 @@ import {
59
59
  readDaemonNeedsLogin,
60
60
  readDaemonStatus,
61
61
  readInstalledDaemonService
62
- } from "../chunk-Z4XCN2HH.js";
62
+ } from "../chunk-SQYBP3QQ.js";
63
63
  import {
64
64
  detectProviderLiveCapabilities,
65
65
  hasSpawnProvider,
@@ -75,7 +75,7 @@ import {
75
75
  import "../chunk-L4E2BIJ2.js";
76
76
  import {
77
77
  getMachineId
78
- } from "../chunk-AWHCZOZO.js";
78
+ } from "../chunk-2ACC5M7F.js";
79
79
  import {
80
80
  claudeJson,
81
81
  claudeSettings,
@@ -96,7 +96,7 @@ import {
96
96
  readCodexMcpAuth,
97
97
  untrustedCodexHookEvents,
98
98
  vscodePluginDir
99
- } from "../chunk-BVNYTQ5I.js";
99
+ } from "../chunk-CV2YD2JR.js";
100
100
  import {
101
101
  describeReach,
102
102
  describeRoundTrip,
@@ -14,8 +14,8 @@ import {
14
14
  } from "../chunk-F7OURW3C.js";
15
15
  import {
16
16
  getMachineId
17
- } from "../chunk-AWHCZOZO.js";
18
- import "../chunk-BVNYTQ5I.js";
17
+ } from "../chunk-2ACC5M7F.js";
18
+ import "../chunk-CV2YD2JR.js";
19
19
  import "../chunk-BSZYIAZL.js";
20
20
  import "../chunk-SAF6HGAA.js";
21
21
  import "../chunk-7QLSKOSU.js";
@@ -17,7 +17,7 @@ import {
17
17
  idleDeadlinePassed,
18
18
  startProcessOwnership,
19
19
  withSpawnProcessOwnership
20
- } from "../chunk-GQ5ZC2QY.js";
20
+ } from "../chunk-4TFXV5MW.js";
21
21
  import {
22
22
  spawnClaude
23
23
  } from "../chunk-XHKBHWLX.js";
@@ -26,8 +26,8 @@ import {
26
26
  } from "../chunk-L4ZCFMWW.js";
27
27
  import {
28
28
  getMachineId
29
- } from "../chunk-AWHCZOZO.js";
30
- import "../chunk-BVNYTQ5I.js";
29
+ } from "../chunk-2ACC5M7F.js";
30
+ import "../chunk-CV2YD2JR.js";
31
31
  import "../chunk-OSALSIUF.js";
32
32
  import "../chunk-BC3VCZ3E.js";
33
33
  import "../chunk-JW4KO5AF.js";
@@ -22,7 +22,7 @@ import {
22
22
  readLastUserPrompt,
23
23
  repoKeyFor,
24
24
  reportEvent
25
- } from "../chunk-TVZQMPB7.js";
25
+ } from "../chunk-YXDYKECP.js";
26
26
  import {
27
27
  DEFAULT_SESSION,
28
28
  askUser,
@@ -41,8 +41,8 @@ import {
41
41
  } from "../chunk-L4E2BIJ2.js";
42
42
  import {
43
43
  getMachineId
44
- } from "../chunk-AWHCZOZO.js";
45
- import "../chunk-BVNYTQ5I.js";
44
+ } from "../chunk-2ACC5M7F.js";
45
+ import "../chunk-CV2YD2JR.js";
46
46
  import "../chunk-BSZYIAZL.js";
47
47
  import "../chunk-SAF6HGAA.js";
48
48
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePreToolUse
4
- } from "../chunk-4IEW4ZRF.js";
4
+ } from "../chunk-RQPQSJJH.js";
5
5
  import "../chunk-2LAHXHBR.js";
6
6
  import "../chunk-I463AEG3.js";
7
7
  import "../chunk-VHWCVD42.js";
@@ -9,11 +9,11 @@ import {
9
9
  readHookInput
10
10
  } from "../chunk-6CUUA7HO.js";
11
11
  import "../chunk-YHG74UFF.js";
12
- import "../chunk-TVZQMPB7.js";
12
+ import "../chunk-YXDYKECP.js";
13
13
  import "../chunk-F7OURW3C.js";
14
14
  import "../chunk-L4E2BIJ2.js";
15
- import "../chunk-AWHCZOZO.js";
16
- import "../chunk-BVNYTQ5I.js";
15
+ import "../chunk-2ACC5M7F.js";
16
+ import "../chunk-CV2YD2JR.js";
17
17
  import {
18
18
  exitOnHelpFlag
19
19
  } from "../chunk-BVBEURWJ.js";
@@ -4,11 +4,11 @@ import {
4
4
  } from "../chunk-Z3Z4VK5F.js";
5
5
  import {
6
6
  recoverDaemonAfterLogin
7
- } from "../chunk-Z4XCN2HH.js";
7
+ } from "../chunk-SQYBP3QQ.js";
8
8
  import "../chunk-XHKBHWLX.js";
9
9
  import "../chunk-L4ZCFMWW.js";
10
- import "../chunk-AWHCZOZO.js";
11
- import "../chunk-BVNYTQ5I.js";
10
+ import "../chunk-2ACC5M7F.js";
11
+ import "../chunk-CV2YD2JR.js";
12
12
  import "../chunk-3EGEA4KH.js";
13
13
  import {
14
14
  checkApiKey,
@@ -4,7 +4,7 @@ import {
4
4
  codexConfigToml,
5
5
  cursorUserMcp,
6
6
  geminiSettings
7
- } from "../chunk-BVNYTQ5I.js";
7
+ } from "../chunk-CV2YD2JR.js";
8
8
  import {
9
9
  createIo
10
10
  } from "../chunk-5RUIFDTP.js";
@@ -4,11 +4,11 @@ import {
4
4
  } from "../chunk-6CUUA7HO.js";
5
5
  import {
6
6
  handleNotification
7
- } from "../chunk-TVZQMPB7.js";
7
+ } from "../chunk-YXDYKECP.js";
8
8
  import "../chunk-F7OURW3C.js";
9
9
  import "../chunk-L4E2BIJ2.js";
10
- import "../chunk-AWHCZOZO.js";
11
- import "../chunk-BVNYTQ5I.js";
10
+ import "../chunk-2ACC5M7F.js";
11
+ import "../chunk-CV2YD2JR.js";
12
12
  import "../chunk-BSZYIAZL.js";
13
13
  import "../chunk-SAF6HGAA.js";
14
14
  import "../chunk-7QLSKOSU.js";
@@ -19,7 +19,7 @@ import {
19
19
  policyRequestFor,
20
20
  readLastPrompt,
21
21
  repoKeyFor
22
- } from "../chunk-TVZQMPB7.js";
22
+ } from "../chunk-YXDYKECP.js";
23
23
  import {
24
24
  DEFAULT_SESSION,
25
25
  askUser,
@@ -40,8 +40,8 @@ import {
40
40
  } from "../chunk-L4E2BIJ2.js";
41
41
  import {
42
42
  getMachineId
43
- } from "../chunk-AWHCZOZO.js";
44
- import "../chunk-BVNYTQ5I.js";
43
+ } from "../chunk-2ACC5M7F.js";
44
+ import "../chunk-CV2YD2JR.js";
45
45
  import "../chunk-BSZYIAZL.js";
46
46
  import "../chunk-SAF6HGAA.js";
47
47
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePermissionDenied
4
- } from "../chunk-4IEW4ZRF.js";
4
+ } from "../chunk-RQPQSJJH.js";
5
5
  import "../chunk-2LAHXHBR.js";
6
6
  import "../chunk-I463AEG3.js";
7
7
  import "../chunk-VHWCVD42.js";
@@ -9,11 +9,11 @@ import {
9
9
  readHookInput
10
10
  } from "../chunk-6CUUA7HO.js";
11
11
  import "../chunk-YHG74UFF.js";
12
- import "../chunk-TVZQMPB7.js";
12
+ import "../chunk-YXDYKECP.js";
13
13
  import "../chunk-F7OURW3C.js";
14
14
  import "../chunk-L4E2BIJ2.js";
15
- import "../chunk-AWHCZOZO.js";
16
- import "../chunk-BVNYTQ5I.js";
15
+ import "../chunk-2ACC5M7F.js";
16
+ import "../chunk-CV2YD2JR.js";
17
17
  import "../chunk-BSZYIAZL.js";
18
18
  import "../chunk-SAF6HGAA.js";
19
19
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePermissionRequest
4
- } from "../chunk-4IEW4ZRF.js";
4
+ } from "../chunk-RQPQSJJH.js";
5
5
  import "../chunk-2LAHXHBR.js";
6
6
  import "../chunk-I463AEG3.js";
7
7
  import "../chunk-VHWCVD42.js";
@@ -9,11 +9,11 @@ import {
9
9
  readHookInput
10
10
  } from "../chunk-6CUUA7HO.js";
11
11
  import "../chunk-YHG74UFF.js";
12
- import "../chunk-TVZQMPB7.js";
12
+ import "../chunk-YXDYKECP.js";
13
13
  import "../chunk-F7OURW3C.js";
14
14
  import "../chunk-L4E2BIJ2.js";
15
- import "../chunk-AWHCZOZO.js";
16
- import "../chunk-BVNYTQ5I.js";
15
+ import "../chunk-2ACC5M7F.js";
16
+ import "../chunk-CV2YD2JR.js";
17
17
  import "../chunk-BSZYIAZL.js";
18
18
  import "../chunk-SAF6HGAA.js";
19
19
  import "../chunk-7QLSKOSU.js";
@@ -6,11 +6,11 @@ import {
6
6
  handleCompaction,
7
7
  handlePostToolUse,
8
8
  isCompactionEvent
9
- } from "../chunk-TVZQMPB7.js";
9
+ } from "../chunk-YXDYKECP.js";
10
10
  import "../chunk-F7OURW3C.js";
11
11
  import "../chunk-L4E2BIJ2.js";
12
- import "../chunk-AWHCZOZO.js";
13
- import "../chunk-BVNYTQ5I.js";
12
+ import "../chunk-2ACC5M7F.js";
13
+ import "../chunk-CV2YD2JR.js";
14
14
  import "../chunk-BSZYIAZL.js";
15
15
  import "../chunk-SAF6HGAA.js";
16
16
  import "../chunk-7QLSKOSU.js";
@@ -4,11 +4,11 @@ import {
4
4
  } from "../chunk-6CUUA7HO.js";
5
5
  import {
6
6
  handleUserPrompt
7
- } from "../chunk-TVZQMPB7.js";
7
+ } from "../chunk-YXDYKECP.js";
8
8
  import "../chunk-F7OURW3C.js";
9
9
  import "../chunk-L4E2BIJ2.js";
10
- import "../chunk-AWHCZOZO.js";
11
- import "../chunk-BVNYTQ5I.js";
10
+ import "../chunk-2ACC5M7F.js";
11
+ import "../chunk-CV2YD2JR.js";
12
12
  import "../chunk-BSZYIAZL.js";
13
13
  import "../chunk-SAF6HGAA.js";
14
14
  import "../chunk-7QLSKOSU.js";
@@ -4,11 +4,11 @@ import {
4
4
  } from "../chunk-6CUUA7HO.js";
5
5
  import {
6
6
  handleSessionEnd
7
- } from "../chunk-TVZQMPB7.js";
7
+ } from "../chunk-YXDYKECP.js";
8
8
  import "../chunk-F7OURW3C.js";
9
9
  import "../chunk-L4E2BIJ2.js";
10
- import "../chunk-AWHCZOZO.js";
11
- import "../chunk-BVNYTQ5I.js";
10
+ import "../chunk-2ACC5M7F.js";
11
+ import "../chunk-CV2YD2JR.js";
12
12
  import "../chunk-BSZYIAZL.js";
13
13
  import "../chunk-SAF6HGAA.js";
14
14
  import "../chunk-7QLSKOSU.js";
@@ -1,14 +1,23 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ reapplyClaudeForVersion
4
+ } from "../chunk-I3ORVBTP.js";
5
+ import "../chunk-HDORB7WD.js";
6
+ import "../chunk-ZMKKK6DC.js";
7
+ import "../chunk-I7W3UTDK.js";
8
+ import "../chunk-2LAHXHBR.js";
9
+ import "../chunk-EZIEXHYM.js";
10
+ import "../chunk-L4ZCFMWW.js";
2
11
  import {
3
12
  readHookInput
4
13
  } from "../chunk-6CUUA7HO.js";
5
14
  import {
6
15
  handleSessionStart
7
- } from "../chunk-TVZQMPB7.js";
16
+ } from "../chunk-YXDYKECP.js";
8
17
  import "../chunk-F7OURW3C.js";
9
18
  import "../chunk-L4E2BIJ2.js";
10
- import "../chunk-AWHCZOZO.js";
11
- import "../chunk-BVNYTQ5I.js";
19
+ import "../chunk-2ACC5M7F.js";
20
+ import "../chunk-CV2YD2JR.js";
12
21
  import "../chunk-BSZYIAZL.js";
13
22
  import "../chunk-SAF6HGAA.js";
14
23
  import "../chunk-7QLSKOSU.js";
@@ -22,6 +31,12 @@ import "../chunk-VNMKIJZB.js";
22
31
  var main = async () => {
23
32
  const input = await readHookInput("claude", "SessionStart");
24
33
  if (!input) return;
34
+ if (!input.agent_id) {
35
+ try {
36
+ reapplyClaudeForVersion();
37
+ } catch {
38
+ }
39
+ }
25
40
  try {
26
41
  await handleSessionStart(input);
27
42
  } catch {
@@ -4,14 +4,14 @@ import {
4
4
  } from "../chunk-Z3Z4VK5F.js";
5
5
  import {
6
6
  detectClaudeVersion
7
- } from "../chunk-YTDH3XCE.js";
7
+ } from "../chunk-HDORB7WD.js";
8
8
  import {
9
9
  describeVersionManagerPin,
10
10
  versionManagerOf
11
11
  } from "../chunk-GU3EJCVV.js";
12
12
  import {
13
13
  waitForMachineReadiness
14
- } from "../chunk-YTD6PJM7.js";
14
+ } from "../chunk-2XQSN66Q.js";
15
15
  import {
16
16
  AGENT_CHOICES,
17
17
  HERMES_CONFIG_SCRIPT,
@@ -31,7 +31,7 @@ import {
31
31
  planHooks,
32
32
  resolveHermesPython,
33
33
  runHermesPythonScript
34
- } from "../chunk-B65JGBIZ.js";
34
+ } from "../chunk-QCXKQJTG.js";
35
35
  import {
36
36
  describeDetection,
37
37
  detectAllAgents,
@@ -45,13 +45,13 @@ import {
45
45
  shortenHome,
46
46
  vscodeSettingsTargets,
47
47
  writeInstructionBlock
48
- } from "../chunk-CRVJCKIN.js";
48
+ } from "../chunk-3HS4YGHB.js";
49
49
  import {
50
50
  claudeWired,
51
51
  codexWired,
52
52
  geminiWired,
53
53
  pusharyHookExecutable
54
- } from "../chunk-WGKC6PU2.js";
54
+ } from "../chunk-ZMKKK6DC.js";
55
55
  import {
56
56
  OPENCODE_HOOK_BINARY,
57
57
  addOpenCodeMcpServer,
@@ -75,7 +75,7 @@ import {
75
75
  isClaudeMcpSnapshot,
76
76
  parseVersion,
77
77
  updateClaudeMcpSnapshot
78
- } from "../chunk-ELHCIEMM.js";
78
+ } from "../chunk-I7W3UTDK.js";
79
79
  import "../chunk-2LAHXHBR.js";
80
80
  import "../chunk-DSTLA2TC.js";
81
81
  import {
@@ -95,7 +95,7 @@ import {
95
95
  replaceDaemonService,
96
96
  stopDaemonService,
97
97
  waitForDaemonRemoteProof
98
- } from "../chunk-Z4XCN2HH.js";
98
+ } from "../chunk-SQYBP3QQ.js";
99
99
  import {
100
100
  detectProviderLiveCapabilities,
101
101
  hasSpawnProvider,
@@ -113,10 +113,10 @@ import {
113
113
  } from "../chunk-L4ZCFMWW.js";
114
114
  import {
115
115
  reportEvent
116
- } from "../chunk-TVZQMPB7.js";
116
+ } from "../chunk-YXDYKECP.js";
117
117
  import "../chunk-F7OURW3C.js";
118
118
  import "../chunk-L4E2BIJ2.js";
119
- import "../chunk-AWHCZOZO.js";
119
+ import "../chunk-2ACC5M7F.js";
120
120
  import {
121
121
  addCodexHookTrust,
122
122
  addCodexHooks,
@@ -144,7 +144,7 @@ import {
144
144
  readCodexMcpAuth,
145
145
  vscodePluginDir,
146
146
  vscodePluginMcp
147
- } from "../chunk-BVNYTQ5I.js";
147
+ } from "../chunk-CV2YD2JR.js";
148
148
  import {
149
149
  confirmAppConnection,
150
150
  connectDevice,
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  describeLastSeen,
4
4
  listMachines
5
- } from "../chunk-YTD6PJM7.js";
6
- import "../chunk-AWHCZOZO.js";
7
- import "../chunk-BVNYTQ5I.js";
5
+ } from "../chunk-2XQSN66Q.js";
6
+ import "../chunk-2ACC5M7F.js";
7
+ import "../chunk-CV2YD2JR.js";
8
8
  import {
9
9
  describeReach,
10
10
  fetchChannels,
@@ -6,11 +6,11 @@ import {
6
6
  handleStop,
7
7
  handleSubagentStop,
8
8
  isSubagentStop
9
- } from "../chunk-TVZQMPB7.js";
9
+ } from "../chunk-YXDYKECP.js";
10
10
  import "../chunk-F7OURW3C.js";
11
11
  import "../chunk-L4E2BIJ2.js";
12
- import "../chunk-AWHCZOZO.js";
13
- import "../chunk-BVNYTQ5I.js";
12
+ import "../chunk-2ACC5M7F.js";
13
+ import "../chunk-CV2YD2JR.js";
14
14
  import "../chunk-BSZYIAZL.js";
15
15
  import "../chunk-SAF6HGAA.js";
16
16
  import "../chunk-7QLSKOSU.js";
@@ -4,11 +4,11 @@ import {
4
4
  } from "../chunk-6CUUA7HO.js";
5
5
  import {
6
6
  handleStopFailure
7
- } from "../chunk-TVZQMPB7.js";
7
+ } from "../chunk-YXDYKECP.js";
8
8
  import "../chunk-F7OURW3C.js";
9
9
  import "../chunk-L4E2BIJ2.js";
10
- import "../chunk-AWHCZOZO.js";
11
- import "../chunk-BVNYTQ5I.js";
10
+ import "../chunk-2ACC5M7F.js";
11
+ import "../chunk-CV2YD2JR.js";
12
12
  import "../chunk-BSZYIAZL.js";
13
13
  import "../chunk-SAF6HGAA.js";
14
14
  import "../chunk-7QLSKOSU.js";
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  reapplyAllAgents
4
- } from "../chunk-VAMBUKXH.js";
5
- import "../chunk-YTDH3XCE.js";
4
+ } from "../chunk-I3ORVBTP.js";
5
+ import "../chunk-HDORB7WD.js";
6
6
  import {
7
7
  waitForMachineReadiness
8
- } from "../chunk-YTD6PJM7.js";
9
- import "../chunk-WGKC6PU2.js";
10
- import "../chunk-ELHCIEMM.js";
8
+ } from "../chunk-2XQSN66Q.js";
9
+ import "../chunk-ZMKKK6DC.js";
10
+ import "../chunk-I7W3UTDK.js";
11
11
  import "../chunk-2LAHXHBR.js";
12
12
  import "../chunk-EZIEXHYM.js";
13
13
  import {
@@ -20,7 +20,7 @@ import {
20
20
  replaceDaemonService,
21
21
  stopDaemonService,
22
22
  waitForDaemonRemoteProof
23
- } from "../chunk-Z4XCN2HH.js";
23
+ } from "../chunk-SQYBP3QQ.js";
24
24
  import {
25
25
  detectProviderLiveCapabilities,
26
26
  hasSpawnProvider,
@@ -34,14 +34,14 @@ import {
34
34
  npmErrorMessage,
35
35
  resolveGlobalBinary
36
36
  } from "../chunk-L4ZCFMWW.js";
37
- import "../chunk-AWHCZOZO.js";
37
+ import "../chunk-2ACC5M7F.js";
38
38
  import {
39
39
  claudeJson,
40
40
  codexConfigToml,
41
41
  cursorPluginDir,
42
42
  geminiSettings,
43
43
  vscodePluginDir
44
- } from "../chunk-BVNYTQ5I.js";
44
+ } from "../chunk-CV2YD2JR.js";
45
45
  import {
46
46
  exitOnHelpFlag
47
47
  } from "../chunk-BVBEURWJ.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-BVNYTQ5I.js";
3
+ } from "./chunk-CV2YD2JR.js";
4
4
  import {
5
5
  writeFileAtomic
6
6
  } from "./chunk-4LL6LG5X.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getMachineId
3
- } from "./chunk-AWHCZOZO.js";
3
+ } from "./chunk-2ACC5M7F.js";
4
4
  import {
5
5
  getPackageVersion
6
6
  } from "./chunk-DINDL2CF.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-CELX75MW.js";
4
4
  import {
5
5
  codexHomeFrom
6
- } from "./chunk-BVNYTQ5I.js";
6
+ } from "./chunk-CV2YD2JR.js";
7
7
  import {
8
8
  HOOK_LOCATOR_BINARY
9
9
  } from "./chunk-VNMKIJZB.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-BVNYTQ5I.js";
3
+ } from "./chunk-CV2YD2JR.js";
4
4
  import {
5
5
  readJsonSafe
6
6
  } from "./chunk-4LL6LG5X.js";
@@ -288,6 +288,7 @@ var vscodePluginMcp = () => join2(vscodePluginDir(), ".mcp.json");
288
288
  var claudeSettingsLocal = () => join2(homedir2(), ".claude", "settings.local.json");
289
289
  var pusharyDir = () => join2(homedir2(), ".pushary");
290
290
  var claudeMcpReceipt = () => join2(pusharyDir(), "setup", "claude-mcp.json");
291
+ var claudeRegistrationReceipt = () => join2(pusharyDir(), "setup", "claude-registration.json");
291
292
  var hermesConfigReceipt = () => join2(pusharyDir(), "setup", "hermes-config.json");
292
293
  var hookTakeoverReceipt = (agent) => join2(pusharyDir(), "setup", `hook-takeover-${agent}.json`);
293
294
  var codexSkillDir2 = () => join2(codexHome(), "skills", "pushary");
@@ -332,6 +333,7 @@ export {
332
333
  claudeSettingsLocal,
333
334
  pusharyDir,
334
335
  claudeMcpReceipt,
336
+ claudeRegistrationReceipt,
335
337
  hermesConfigReceipt,
336
338
  hookTakeoverReceipt,
337
339
  codexSkillDir2,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseVersion
3
- } from "./chunk-ELHCIEMM.js";
3
+ } from "./chunk-I7W3UTDK.js";
4
4
 
5
5
  // src/setup/agent-probe.ts
6
6
  import { execSync } from "child_process";
@@ -1,20 +1,25 @@
1
1
  import {
2
2
  detectClaudeVersion
3
- } from "./chunk-YTDH3XCE.js";
3
+ } from "./chunk-HDORB7WD.js";
4
4
  import {
5
5
  claudeWired,
6
6
  codexWired,
7
7
  geminiWired
8
- } from "./chunk-WGKC6PU2.js";
8
+ } from "./chunk-ZMKKK6DC.js";
9
9
  import {
10
+ CLAUDE_HOOK_EVENTS,
10
11
  GEMINI_HOOK_BINARY,
11
12
  addClaudeMcpServer,
12
13
  addGeminiHooks,
13
14
  addGeminiMcpServer,
14
15
  addPusharyHooks,
15
16
  addPusharyToolPermissions,
16
- hasGeminiHooks
17
- } from "./chunk-ELHCIEMM.js";
17
+ formatVersion,
18
+ hasGeminiHooks,
19
+ needsReregistration,
20
+ registrationSignatures,
21
+ supportedClaudeEvents
22
+ } from "./chunk-I7W3UTDK.js";
18
23
  import {
19
24
  guardBinary
20
25
  } from "./chunk-EZIEXHYM.js";
@@ -27,21 +32,84 @@ import {
27
32
  addCodexHookTrust,
28
33
  addCodexHooks,
29
34
  addCodexMcpServer,
35
+ claudeRegistrationReceipt,
30
36
  codexConfigToml,
31
37
  codexHookPositions,
32
38
  codexHooksJson,
33
39
  hasCodexHooks,
34
40
  vscodePluginMcp
35
- } from "./chunk-BVNYTQ5I.js";
41
+ } from "./chunk-CV2YD2JR.js";
36
42
  import {
37
- readJsonSafe
43
+ readJsonSafe,
44
+ writeJsonAtomic
38
45
  } from "./chunk-4LL6LG5X.js";
46
+ import {
47
+ HOOK_LOCATOR_BINARY
48
+ } from "./chunk-VNMKIJZB.js";
39
49
 
40
50
  // src/reapply.ts
41
- import { join, dirname } from "path";
51
+ import { join } from "path";
42
52
  import { homedir } from "os";
43
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
53
+ import { readFileSync, writeFileSync } from "fs";
44
54
  import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
55
+
56
+ // src/reregister.ts
57
+ var asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
58
+ var commandsUnder = (settings) => {
59
+ const hooks = asRecord(settings?.hooks);
60
+ if (!hooks) return [];
61
+ const found = [];
62
+ for (const [event, value] of Object.entries(hooks)) {
63
+ if (!Array.isArray(value)) continue;
64
+ for (const item of value) {
65
+ const inner = asRecord(item)?.hooks;
66
+ if (!Array.isArray(inner)) continue;
67
+ for (const hook of inner) {
68
+ const command = asRecord(hook)?.command;
69
+ if (typeof command === "string") found.push({ event, command });
70
+ }
71
+ }
72
+ }
73
+ return found;
74
+ };
75
+ var segments = (command) => command.split(/[\s/\\"']+/).map((segment) => segment.replace(/\.(cmd|exe)$/i, ""));
76
+ var CLI_BINARIES = new Set(CLAUDE_HOOK_EVENTS.map((hook) => hook.binary));
77
+ var namesLocator = (command) => segments(command).includes(HOOK_LOCATOR_BINARY);
78
+ var namesCliBinary = (command) => segments(command).some((segment) => CLI_BINARIES.has(segment));
79
+ var registrationHolder = (settings) => {
80
+ const commands = commandsUnder(settings);
81
+ if (commands.some(({ command }) => namesLocator(command))) return "app";
82
+ return commands.some(({ command }) => namesCliBinary(command)) ? "cli" : "none";
83
+ };
84
+ var registeredPusharyEvents = (settings) => new Set(
85
+ commandsUnder(settings).filter(({ command }) => namesLocator(command) || namesCliBinary(command)).map(({ event }) => event)
86
+ );
87
+ var reregisterVerdict = ({ settings, stored, version }) => {
88
+ const holder = registrationHolder(settings);
89
+ if (holder === "none") return { kind: "not_wired" };
90
+ if (holder === "app") return { kind: "app_owned" };
91
+ if (!needsReregistration(stored, version)) return { kind: "current" };
92
+ const supported = new Set(supportedClaudeEvents(version).map((hook) => hook.event));
93
+ const present = registeredPusharyEvents(settings);
94
+ const missing = [...supported].filter((event) => !present.has(event));
95
+ const extra = [...present].filter((event) => !supported.has(event));
96
+ return missing.length > 0 || extra.length > 0 ? { kind: "stale", version, missing, extra } : { kind: "record_only", version };
97
+ };
98
+ var receiptFor = (version, now = /* @__PURE__ */ new Date()) => ({
99
+ signatures: registrationSignatures(supportedClaudeEvents(version), version),
100
+ version: version ? formatVersion(version) : null,
101
+ recordedAt: now.toISOString()
102
+ });
103
+ var storedSignatures = (raw) => {
104
+ const signatures = asRecord(asRecord(raw)?.signatures);
105
+ if (!signatures) return void 0;
106
+ const entries = Object.entries(signatures).filter(
107
+ (pair) => typeof pair[1] === "string"
108
+ );
109
+ return entries.length > 0 ? Object.fromEntries(entries) : void 0;
110
+ };
111
+
112
+ // src/reapply.ts
45
113
  var CLAUDE_SETTINGS = join(homedir(), ".claude", "settings.json");
46
114
  var CLAUDE_JSON = join(homedir(), ".claude.json");
47
115
  var readJson = (filePath) => {
@@ -50,11 +118,7 @@ var readJson = (filePath) => {
50
118
  if (result.kind === "missing") return {};
51
119
  return null;
52
120
  };
53
- var writeJson = (filePath, data) => {
54
- const dir = dirname(filePath);
55
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
56
- writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
57
- };
121
+ var writeJson = (filePath, data) => writeJsonAtomic(filePath, data);
58
122
  var hasPusharyClaudeHooks = (settings) => JSON.stringify(settings.hooks ?? {}).includes("pushary-hook");
59
123
  var hasPusharyMcp = (claudeJson) => !!claudeJson.mcpServers?.pushary;
60
124
  var reapplyClaudeSettings = (apiKey, paths = {}) => {
@@ -72,7 +136,7 @@ var reapplyClaudeSettings = (apiKey, paths = {}) => {
72
136
  if (!settingsWritable) throw new Error("settings.json could not be parsed");
73
137
  const s = settings;
74
138
  addPusharyToolPermissions(s);
75
- addPusharyHooks(s, resolveGlobalBinDir("pushary-hook"), detectClaudeVersion());
139
+ addPusharyHooks(s, resolveGlobalBinDir("pushary-hook"), (paths.detectVersion ?? detectClaudeVersion)());
76
140
  writeJson(settingsPath, s);
77
141
  hooks = true;
78
142
  } catch {
@@ -89,6 +153,33 @@ var reapplyClaudeSettings = (apiKey, paths = {}) => {
89
153
  }
90
154
  return { configured: true, reapplied: hooks || mcp, hooks, mcp };
91
155
  };
156
+ var reapplyClaudeForVersion = (apiKey, paths = {}) => {
157
+ const idle = { verdict: "current", rewrote: false, missing: [] };
158
+ try {
159
+ const settingsPath = paths.settingsPath ?? CLAUDE_SETTINGS;
160
+ const receiptPath = paths.receiptPath ?? claudeRegistrationReceipt();
161
+ const version = (paths.detectVersion ?? detectClaudeVersion)();
162
+ const receipt = readJsonSafe(receiptPath);
163
+ const verdict = reregisterVerdict({
164
+ settings: readJson(settingsPath),
165
+ stored: storedSignatures(receipt.kind === "ok" ? receipt.value : void 0),
166
+ version
167
+ });
168
+ if (verdict.kind === "not_wired" || verdict.kind === "app_owned" || verdict.kind === "current") {
169
+ return { verdict: verdict.kind, rewrote: false, missing: [] };
170
+ }
171
+ const rewrote = verdict.kind === "stale" ? reapplyClaudeSettings(apiKey, { ...paths, settingsPath }).hooks : false;
172
+ if (verdict.kind === "stale" && !rewrote) return { verdict: "stale", rewrote: false, missing: verdict.missing };
173
+ writeJsonAtomic(receiptPath, receiptFor(version));
174
+ return {
175
+ verdict: verdict.kind,
176
+ rewrote,
177
+ missing: verdict.kind === "stale" ? verdict.missing : []
178
+ };
179
+ } catch {
180
+ return idle;
181
+ }
182
+ };
92
183
  var readToml = (filePath) => {
93
184
  try {
94
185
  const raw = readFileSync(filePath, "utf-8");
@@ -205,6 +296,7 @@ var reapplyAllAgents = (apiKey) => {
205
296
  };
206
297
 
207
298
  export {
299
+ reapplyClaudeForVersion,
208
300
  inspectConfiguredManagedProviders,
209
301
  reapplyAllAgents
210
302
  };
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-EZIEXHYM.js";
8
8
  import {
9
9
  isProtectedByScope
10
- } from "./chunk-BVNYTQ5I.js";
10
+ } from "./chunk-CV2YD2JR.js";
11
11
  import {
12
12
  HOOK_BUDGETS,
13
13
  HOOK_LOCATOR_BINARY
@@ -28,6 +28,7 @@ var compareVersion = (a, b) => {
28
28
  return 0;
29
29
  };
30
30
  var atLeast = (version, floor) => compareVersion(version, floor) >= 0;
31
+ var formatVersion = (version) => version.join(".");
31
32
 
32
33
  // src/claude-events.ts
33
34
  var GATED_TOOLS = [...PRETOOLUSE_GATED_TOOLS, ...PRETOOLUSE_PHONE_ANSWERED_TOOLS].join("|");
@@ -58,6 +59,16 @@ var CLAUDE_HOOK_EVENTS = [
58
59
  { event: "Elicitation", binary: "pushary-elicitation-hook", timeout: HOOK_BUDGETS.claude.budgetSeconds, delivery: "approval", since: OBSERVED }
59
60
  ];
60
61
  var supportedClaudeEvents = (version) => CLAUDE_HOOK_EVENTS.filter((hook) => version ? atLeast(version, hook.since) : hook.since === ESTABLISHED);
62
+ var registrationSignatures = (events, version) => Object.fromEntries(
63
+ events.map((hook) => [hook.event, `registered|${version ? formatVersion(version) : "unknown"}`])
64
+ );
65
+ var needsReregistration = (stored, version) => {
66
+ const expected = registrationSignatures(supportedClaudeEvents(version), version);
67
+ const keys = Object.keys(expected);
68
+ if (!stored) return true;
69
+ if (keys.length !== Object.keys(stored).length) return true;
70
+ return keys.some((event) => stored[event] !== expected[event]);
71
+ };
61
72
 
62
73
  // src/claude-config.ts
63
74
  import { isDeepStrictEqual } from "util";
@@ -331,7 +342,11 @@ var missingGeminiHookEvents = (settings) => {
331
342
  export {
332
343
  parseVersion,
333
344
  compareVersion,
345
+ formatVersion,
334
346
  CLAUDE_HOOK_EVENTS,
347
+ supportedClaudeEvents,
348
+ registrationSignatures,
349
+ needsReregistration,
335
350
  addClaudeMcpServer,
336
351
  isClaudeMcpSnapshot,
337
352
  captureClaudeMcpServer,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  isBridgeLocator
3
- } from "./chunk-CRVJCKIN.js";
3
+ } from "./chunk-3HS4YGHB.js";
4
4
  import {
5
5
  pusharyHookExecutable
6
- } from "./chunk-WGKC6PU2.js";
6
+ } from "./chunk-ZMKKK6DC.js";
7
7
  import {
8
8
  BELL_HOOK_BINARY
9
9
  } from "./chunk-DSTLA2TC.js";
@@ -21,7 +21,7 @@ import {
21
21
  repoKeyFor,
22
22
  settleQuestionsForToolUse,
23
23
  throttlePass
24
- } from "./chunk-TVZQMPB7.js";
24
+ } from "./chunk-YXDYKECP.js";
25
25
  import {
26
26
  DEFAULT_SESSION,
27
27
  askUser,
@@ -41,7 +41,7 @@ import {
41
41
  } from "./chunk-L4E2BIJ2.js";
42
42
  import {
43
43
  getMachineId
44
- } from "./chunk-AWHCZOZO.js";
44
+ } from "./chunk-2ACC5M7F.js";
45
45
  import {
46
46
  getApiKey,
47
47
  getBaseUrl
@@ -7,10 +7,10 @@ import {
7
7
  } from "./chunk-L4ZCFMWW.js";
8
8
  import {
9
9
  getMachineId
10
- } from "./chunk-AWHCZOZO.js";
10
+ } from "./chunk-2ACC5M7F.js";
11
11
  import {
12
12
  pusharyDir
13
- } from "./chunk-BVNYTQ5I.js";
13
+ } from "./chunk-CV2YD2JR.js";
14
14
  import {
15
15
  getPackageVersion
16
16
  } from "./chunk-DINDL2CF.js";
@@ -33,7 +33,7 @@ import {
33
33
  } from "./chunk-L4E2BIJ2.js";
34
34
  import {
35
35
  getMachineId
36
- } from "./chunk-AWHCZOZO.js";
36
+ } from "./chunk-2ACC5M7F.js";
37
37
  import {
38
38
  withRetry
39
39
  } from "./chunk-BSZYIAZL.js";
@@ -2,11 +2,11 @@ import {
2
2
  CLAUDE_HOOK_EVENTS,
3
3
  GEMINI_HOOK_EVENTS,
4
4
  hasGeminiHooks
5
- } from "./chunk-ELHCIEMM.js";
5
+ } from "./chunk-I7W3UTDK.js";
6
6
  import {
7
7
  CODEX_HOOK_EVENTS,
8
8
  hasCodexHooks
9
- } from "./chunk-BVNYTQ5I.js";
9
+ } from "./chunk-CV2YD2JR.js";
10
10
  import {
11
11
  CURSOR_GATE_EVENTS,
12
12
  HOOK_LOCATOR_BINARY
package/dist/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  handlePreToolUse
3
- } from "../chunk-4IEW4ZRF.js";
3
+ } from "../chunk-RQPQSJJH.js";
4
4
  import "../chunk-2LAHXHBR.js";
5
5
  import {
6
6
  fetchAccountPublicKey
@@ -16,15 +16,15 @@ import {
16
16
  handlePostToolUse,
17
17
  handleStop,
18
18
  reportEvent
19
- } from "../chunk-TVZQMPB7.js";
19
+ } from "../chunk-YXDYKECP.js";
20
20
  import {
21
21
  askUser,
22
22
  cancelQuestion,
23
23
  waitForAnswer
24
24
  } from "../chunk-F7OURW3C.js";
25
25
  import "../chunk-L4E2BIJ2.js";
26
- import "../chunk-AWHCZOZO.js";
27
- import "../chunk-BVNYTQ5I.js";
26
+ import "../chunk-2ACC5M7F.js";
27
+ import "../chunk-CV2YD2JR.js";
28
28
  import "../chunk-BSZYIAZL.js";
29
29
  import "../chunk-SAF6HGAA.js";
30
30
  import "../chunk-7QLSKOSU.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "0.91.0",
3
+ "version": "0.92.1",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",