@pushary/agent-hooks 0.92.0 → 0.93.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 (54) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/bin/pushary-bell.js +1 -1
  3. package/dist/bin/pushary-claude.js +59 -21
  4. package/dist/bin/pushary-clean.js +9 -9
  5. package/dist/bin/pushary-codex-bridge.js +5 -5
  6. package/dist/bin/pushary-codex-hook.js +44 -10
  7. package/dist/bin/pushary-codex.js +7 -6
  8. package/dist/bin/pushary-connect.js +2 -2
  9. package/dist/bin/pushary-daemon.js +10 -10
  10. package/dist/bin/pushary-disconnect.js +3 -3
  11. package/dist/bin/pushary-doctor.js +21 -14
  12. package/dist/bin/pushary-elicitation-hook.js +4 -4
  13. package/dist/bin/pushary-gemini-bridge.js +5 -5
  14. package/dist/bin/pushary-gemini-hook.js +7 -6
  15. package/dist/bin/pushary-hook.js +8 -8
  16. package/dist/bin/pushary-login.js +3 -3
  17. package/dist/bin/pushary-logout.js +1 -1
  18. package/dist/bin/pushary-notification-hook.js +7 -6
  19. package/dist/bin/pushary-opencode-hook.js +7 -6
  20. package/dist/bin/pushary-permission-denied-hook.js +8 -8
  21. package/dist/bin/pushary-permission-hook.js +8 -8
  22. package/dist/bin/pushary-post-hook.js +7 -6
  23. package/dist/bin/pushary-prompt-hook.js +7 -6
  24. package/dist/bin/pushary-session-end-hook.js +7 -6
  25. package/dist/bin/pushary-session-start-hook.js +11 -11
  26. package/dist/bin/pushary-setup.js +15 -15
  27. package/dist/bin/pushary-status.js +5 -5
  28. package/dist/bin/pushary-stop-hook.js +7 -6
  29. package/dist/bin/pushary-stopfailure-hook.js +7 -6
  30. package/dist/bin/pushary-upgrade.js +9 -9
  31. package/dist/{chunk-ZMKKK6DC.js → chunk-6Y4IKMQT.js} +2 -2
  32. package/dist/{chunk-2ACC5M7F.js → chunk-72FWXLW2.js} +1 -1
  33. package/dist/{chunk-QZCFVWA7.js → chunk-EQRS3SGM.js} +3 -1
  34. package/dist/{chunk-BSZYIAZL.js → chunk-EYRGBYZG.js} +2 -1
  35. package/dist/{chunk-YXDYKECP.js → chunk-G5L3WVFV.js} +117 -80
  36. package/dist/{chunk-4TFXV5MW.js → chunk-GKMQMSTB.js} +1 -1
  37. package/dist/{chunk-RQPQSJJH.js → chunk-HCLSTQ3N.js} +23 -8
  38. package/dist/{chunk-CNPAT3HL.js → chunk-KHTFHUL3.js} +1 -1
  39. package/dist/{chunk-CV2YD2JR.js → chunk-N3TF3RQ2.js} +42 -10
  40. package/dist/{chunk-3HS4YGHB.js → chunk-NXZYC3B3.js} +1 -1
  41. package/dist/{chunk-QCXKQJTG.js → chunk-NZQTIDXN.js} +2 -2
  42. package/dist/chunk-QQSQWLFR.js +53 -0
  43. package/dist/{chunk-F7OURW3C.js → chunk-RER3FRTD.js} +7 -7
  44. package/dist/{chunk-2XQSN66Q.js → chunk-T2PKGGDM.js} +1 -1
  45. package/dist/{chunk-I3ORVBTP.js → chunk-TFN7ZCTI.js} +4 -4
  46. package/dist/{chunk-SQYBP3QQ.js → chunk-TWVZHZM3.js} +2 -2
  47. package/dist/{chunk-L4E2BIJ2.js → chunk-UAFQC35P.js} +56 -3
  48. package/dist/{chunk-PYA4FLKI.js → chunk-UPCPR7QW.js} +1 -1
  49. package/dist/{chunk-HDORB7WD.js → chunk-WEDYCMHU.js} +1 -1
  50. package/dist/{chunk-I7W3UTDK.js → chunk-YUZYMAL7.js} +9 -7
  51. package/dist/src/index.d.ts +31 -3
  52. package/dist/src/index.js +9 -9
  53. package/package.json +2 -2
  54. package/dist/chunk-2LAHXHBR.js +0 -23
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.93.0
4
+
5
+ Requires Node.js 20.3.0 or newer for shared cancellation signals.
6
+
7
+ - Register the expanded Claude and Codex hook coverage from the September 4 changes; preserve child-agent identity during compaction.
8
+ - Share one deadline across mode lookup, question reconciliation, event reporting, and command acknowledgement. Retain unresolved question markers for retry.
9
+ - Deliver queued phone instructions on UserPromptSubmit and keep observational hooks from consuming them.
10
+ - Redact credentials in notification activity, phone pushes, and unrecognized failure messages.
11
+ - Diagnose modified Codex hook definitions against their installed trust hashes.
12
+
13
+ ## 0.92.1
14
+
15
+ ### A rejected key is an answer, not an empty poll
16
+
17
+ `pollAgent` returned `{ command: null, mode: null }` for every non-OK response,
18
+ so a 401 was indistinguishable from a healthy poll with nothing queued. That
19
+ landed on the success branch of `startCommandPoller`, which resets `errorStreak`
20
+ to zero, so the backoff never engaged and the wrapper polled a dead key at the
21
+ idle cadence forever. Because `mode` was null, `onModeState` never fired, and
22
+ `onModeState` is the only place `dualMode` sets `killed` and stops the active
23
+ leg. A wrapper whose key the server rejects therefore reported `kill=false` to
24
+ itself indefinitely: remote stop could not reach it, phone messages never
25
+ landed, and nothing was printed.
26
+
27
+ `PollResult` now carries `rejected`, set only for 401 and 403, which is the same
28
+ line `fetchModeState` already drew between an answer and a blip. A rejected poll
29
+ takes the error path, so the existing exponential backoff applies, and the
30
+ wrapper prints once that remote stop and phone messages are not active. A 500 or
31
+ a dropped connection is still a blip and still retried at the normal cadence.
32
+
33
+ A rejected response is also no longer trusted for its contents: neither the
34
+ command nor the mode state it carries is applied.
35
+
3
36
  ## 0.92.0
4
37
 
5
38
  ### A Claude Code upgrade registers the events it just gained
@@ -15,7 +15,7 @@ import "../chunk-EZIEXHYM.js";
15
15
  import "../chunk-L4ZCFMWW.js";
16
16
  import {
17
17
  claudeSettings
18
- } from "../chunk-CV2YD2JR.js";
18
+ } from "../chunk-N3TF3RQ2.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-SQYBP3QQ.js";
10
+ } from "../chunk-TWVZHZM3.js";
11
11
  import {
12
12
  buildTranscriptRecords,
13
13
  decodePublicKey,
@@ -17,7 +17,7 @@ import {
17
17
  import {
18
18
  fetchTranscriptRecipients,
19
19
  uploadTranscriptRecords
20
- } from "../chunk-QZCFVWA7.js";
20
+ } from "../chunk-EQRS3SGM.js";
21
21
  import {
22
22
  transcriptsEnabled
23
23
  } from "../chunk-UZNKVRLE.js";
@@ -26,7 +26,7 @@ import {
26
26
  describeIdleWindow,
27
27
  startProcessOwnership,
28
28
  withSpawnProcessOwnership
29
- } from "../chunk-4TFXV5MW.js";
29
+ } from "../chunk-GKMQMSTB.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-YXDYKECP.js";
44
+ } from "../chunk-G5L3WVFV.js";
45
45
  import {
46
46
  DEFAULT_SESSION,
47
47
  askUser,
@@ -53,21 +53,22 @@ import {
53
53
  removePendingCommand,
54
54
  savePendingCommand,
55
55
  waitForAnswer
56
- } from "../chunk-F7OURW3C.js";
56
+ } from "../chunk-RER3FRTD.js";
57
57
  import {
58
58
  UNNAMED_ACTION,
59
59
  deriveToolTarget,
60
60
  describeToolCall,
61
61
  scopePathFor
62
- } from "../chunk-L4E2BIJ2.js";
62
+ } from "../chunk-UAFQC35P.js";
63
+ import "../chunk-QQSQWLFR.js";
63
64
  import {
64
65
  getMachineId
65
- } from "../chunk-2ACC5M7F.js";
66
- import "../chunk-CV2YD2JR.js";
66
+ } from "../chunk-72FWXLW2.js";
67
+ import "../chunk-N3TF3RQ2.js";
67
68
  import "../chunk-DINDL2CF.js";
68
69
  import "../chunk-OSALSIUF.js";
69
70
  import "../chunk-BC3VCZ3E.js";
70
- import "../chunk-BSZYIAZL.js";
71
+ import "../chunk-EYRGBYZG.js";
71
72
  import "../chunk-SAF6HGAA.js";
72
73
  import "../chunk-7QLSKOSU.js";
73
74
  import "../chunk-KZERVKTD.js";
@@ -240,7 +241,8 @@ var createSyncState = () => ({
240
241
  providerKeyId: null,
241
242
  seen: /* @__PURE__ */ new Set(),
242
243
  keyUploaded: false,
243
- keyRejected: false
244
+ keyRejected: false,
245
+ keyUnavailable: false
244
246
  });
245
247
  var syncTick = async (lines, state, uploader, sessionId, machineId) => {
246
248
  if (state.keyRejected) return state;
@@ -265,6 +267,7 @@ var syncTick = async (lines, state, uploader, sessionId, machineId) => {
265
267
  const seen = new Set(state.seen);
266
268
  let keyUploaded = state.keyUploaded;
267
269
  let keyRejected = false;
270
+ let keyUnavailable = false;
268
271
  let rejected = 0;
269
272
  for (const chunk of chunkRecords(built.records)) {
270
273
  const result = await uploader.uploadRecords({
@@ -280,6 +283,10 @@ var syncTick = async (lines, state, uploader, sessionId, machineId) => {
280
283
  keyRejected = true;
281
284
  break;
282
285
  }
286
+ if (result.keyUnavailable) {
287
+ keyUnavailable = true;
288
+ break;
289
+ }
283
290
  if (!result.ok) break;
284
291
  for (const id of result.settledIds ?? chunk.map((r) => r.localId)) seen.add(id);
285
292
  rejected += result.rejectedIds.length;
@@ -295,7 +302,8 @@ var syncTick = async (lines, state, uploader, sessionId, machineId) => {
295
302
  providerKeyId,
296
303
  seen,
297
304
  keyUploaded,
298
- keyRejected
305
+ keyRejected,
306
+ keyUnavailable
299
307
  };
300
308
  };
301
309
  var MAX_RECORDS_PER_BATCH = 200;
@@ -384,7 +392,7 @@ var startTranscriptSync = (opts) => {
384
392
  void (async () => {
385
393
  const before = state.sessionKey;
386
394
  await tick();
387
- const idle = state.sessionKey === null && before === null;
395
+ const idle = state.sessionKey === null && before === null || state.keyUnavailable;
388
396
  schedule(nextInterval(delayMs, idle, baseIntervalMs, maxIntervalMs));
389
397
  })();
390
398
  }, delayMs);
@@ -717,6 +725,9 @@ var createRemoteApprover = (deps) => {
717
725
  };
718
726
  };
719
727
 
728
+ // src/wrapper/authRejection.ts
729
+ var isAuthRejection = (status) => status === 401 || status === 403;
730
+
720
731
  // src/wrapper/drainClient.ts
721
732
  var drainPendingCommand = async (apiKey, sessionId, signal, baseUrl = getBaseUrl()) => {
722
733
  try {
@@ -729,11 +740,12 @@ var drainPendingCommand = async (apiKey, sessionId, signal, baseUrl = getBaseUrl
729
740
  body: JSON.stringify(sessionId ? { sessionId } : {}),
730
741
  signal
731
742
  });
732
- if (!response.ok) return null;
743
+ if (!response.ok) return { command: null, rejected: isAuthRejection(response.status) };
733
744
  const data = await response.json();
734
- return typeof data.command === "string" && data.command.length > 0 ? data.command : null;
745
+ const command = typeof data.command === "string" && data.command.length > 0 ? data.command : null;
746
+ return { command, rejected: false };
735
747
  } catch {
736
- return null;
748
+ return { command: null, rejected: false };
737
749
  }
738
750
  };
739
751
 
@@ -744,6 +756,9 @@ var FAST_DECAY_TICKS = 3;
744
756
  var MAX_ERROR_BACKOFF_MS = 12e4;
745
757
  var MAX_ERROR_STREAK = 6;
746
758
  var REQUEST_TIMEOUT_MS = 1e4;
759
+ var PollRejectedError = class extends Error {
760
+ };
761
+ var EMPTY_DRAIN = { command: null, rejected: false };
747
762
  var startCommandPoller = (opts) => {
748
763
  const drain = opts.drain ?? drainPendingCommand;
749
764
  const slow = opts.slowPollMs ?? SLOW_POLL_MS;
@@ -754,6 +769,16 @@ var startCommandPoller = (opts) => {
754
769
  let inflight;
755
770
  let idleTicks = 0;
756
771
  let errorStreak = 0;
772
+ let authRejectionReported = false;
773
+ const reportAuthRejection = () => {
774
+ if (authRejectionReported) return;
775
+ authRejectionReported = true;
776
+ try {
777
+ opts.onAuthRejected?.();
778
+ } catch {
779
+ return;
780
+ }
781
+ };
757
782
  const jitter = (ms) => {
758
783
  const r = opts.jitter ? opts.jitter() : Math.random();
759
784
  return Math.max(1, Math.round(ms * (0.85 + r * 0.3)));
@@ -789,6 +814,10 @@ var startCommandPoller = (opts) => {
789
814
  let command;
790
815
  if (opts.poll) {
791
816
  const result = await opts.poll(opts.apiKey, opts.getSessionId?.(), wantCommands, controller.signal);
817
+ if (result.rejected) {
818
+ reportAuthRejection();
819
+ throw new PollRejectedError();
820
+ }
792
821
  command = result.command;
793
822
  if (result.mode && opts.onModeState) {
794
823
  try {
@@ -797,11 +826,15 @@ var startCommandPoller = (opts) => {
797
826
  }
798
827
  }
799
828
  } else {
800
- ;
801
- [command] = await Promise.all([
802
- wantCommands ? drain(opts.apiKey, opts.getSessionId?.(), controller.signal) : Promise.resolve(null),
829
+ const [drained] = await Promise.all([
830
+ wantCommands ? drain(opts.apiKey, opts.getSessionId?.(), controller.signal) : Promise.resolve(EMPTY_DRAIN),
803
831
  fetchMode()
804
832
  ]);
833
+ if (drained.rejected) {
834
+ reportAuthRejection();
835
+ throw new PollRejectedError();
836
+ }
837
+ command = drained.command;
805
838
  }
806
839
  errorStreak = 0;
807
840
  if (command) {
@@ -894,7 +927,7 @@ var pollAgent = async (apiKey, sessionId, wantCommand, signal, baseUrl = getBase
894
927
  }),
895
928
  signal
896
929
  });
897
- if (!response.ok) return { command: null, mode: null };
930
+ if (!response.ok) return { command: null, mode: null, rejected: isAuthRejection(response.status) };
898
931
  const data = await response.json();
899
932
  const claimedCommand = (id, text) => ({
900
933
  id,
@@ -923,9 +956,9 @@ var pollAgent = async (apiKey, sessionId, wantCommand, signal, baseUrl = getBase
923
956
  policyVersion: typeof data.policyVersion === "string" && data.policyVersion.length > 0 ? data.policyVersion : null,
924
957
  relayUrl: typeof data.relayUrl === "string" && data.relayUrl.length > 0 ? data.relayUrl : null
925
958
  };
926
- return { command, mode };
959
+ return { command, mode, rejected: false };
927
960
  } catch {
928
- return { command: null, mode: null };
961
+ return { command: null, mode: null, rejected: false };
929
962
  }
930
963
  };
931
964
 
@@ -1734,6 +1767,11 @@ var runDualMode = async (binary, args2, startingMode) => {
1734
1767
  // Relay-primary: idle the safety-net poll at 60s (see RELAY_FALLBACK_POLL_MS).
1735
1768
  // No relay advertised -> the poller IS the command path, so keep the default.
1736
1769
  slowPollMs: relayAdvertised ? RELAY_FALLBACK_POLL_MS : void 0,
1770
+ onAuthRejected: () => {
1771
+ process.stderr.write(
1772
+ "[pushary] this key was rejected \u2014 remote stop and phone messages are NOT active; run `pushary login` to reconnect\n"
1773
+ );
1774
+ },
1737
1775
  onModeState: (state) => {
1738
1776
  if (state.kill && !killed) {
1739
1777
  killed = true;
@@ -9,16 +9,16 @@ import {
9
9
  restoreHookTakeover,
10
10
  restoreMcpServer,
11
11
  runHermesPythonScript
12
- } from "../chunk-QCXKQJTG.js";
12
+ } from "../chunk-NZQTIDXN.js";
13
13
  import {
14
14
  removeInstructionBlock,
15
15
  shortenHome,
16
16
  unregisterPluginLocation,
17
17
  vscodeSettingsTargets
18
- } from "../chunk-3HS4YGHB.js";
18
+ } from "../chunk-NXZYC3B3.js";
19
19
  import {
20
20
  pusharyHookExecutable
21
- } from "../chunk-ZMKKK6DC.js";
21
+ } from "../chunk-6Y4IKMQT.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-I7W3UTDK.js";
39
- import "../chunk-2LAHXHBR.js";
38
+ } from "../chunk-YUZYMAL7.js";
40
39
  import "../chunk-DSTLA2TC.js";
41
40
  import "../chunk-EZIEXHYM.js";
42
41
  import {
43
42
  disableDaemonService
44
- } from "../chunk-SQYBP3QQ.js";
43
+ } from "../chunk-TWVZHZM3.js";
45
44
  import "../chunk-XHKBHWLX.js";
46
45
  import {
47
46
  execNpm
48
47
  } from "../chunk-L4ZCFMWW.js";
49
- import "../chunk-L4E2BIJ2.js";
50
- import "../chunk-2ACC5M7F.js";
48
+ import "../chunk-UAFQC35P.js";
49
+ import "../chunk-QQSQWLFR.js";
50
+ import "../chunk-72FWXLW2.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-CV2YD2JR.js";
76
+ } from "../chunk-N3TF3RQ2.js";
77
77
  import {
78
78
  rejectUnknownFlags
79
79
  } from "../chunk-GMXKITVA.js";
@@ -6,9 +6,9 @@ import {
6
6
  postLiveSession,
7
7
  postLiveSessionUntilAccepted,
8
8
  startLiveSessionHeartbeat
9
- } from "../chunk-CNPAT3HL.js";
9
+ } from "../chunk-KHTFHUL3.js";
10
10
  import "../chunk-7FE2KABY.js";
11
- import "../chunk-QZCFVWA7.js";
11
+ import "../chunk-EQRS3SGM.js";
12
12
  import {
13
13
  transcriptsEnabled
14
14
  } from "../chunk-UZNKVRLE.js";
@@ -18,7 +18,7 @@ import {
18
18
  idleDeadlinePassed,
19
19
  startProcessOwnership,
20
20
  withSpawnProcessOwnership
21
- } from "../chunk-4TFXV5MW.js";
21
+ } from "../chunk-GKMQMSTB.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-2ACC5M7F.js";
31
- import "../chunk-CV2YD2JR.js";
30
+ } from "../chunk-72FWXLW2.js";
31
+ import "../chunk-N3TF3RQ2.js";
32
32
  import "../chunk-OSALSIUF.js";
33
33
  import "../chunk-BC3VCZ3E.js";
34
34
  import "../chunk-JW4KO5AF.js";
@@ -21,9 +21,11 @@ import {
21
21
  describeApplyPatch,
22
22
  fetchModeState,
23
23
  getPolicy,
24
+ handleCompaction,
24
25
  handlePostToolUse,
25
26
  handleSessionEnd,
26
27
  handleStop,
28
+ handleSubagentStop,
27
29
  handleUserPrompt,
28
30
  permissionTimeoutDecision,
29
31
  policyRequestFor,
@@ -34,7 +36,7 @@ import {
34
36
  toCodexWire,
35
37
  toPolicyLookup,
36
38
  toPolicyLookups
37
- } from "../chunk-YXDYKECP.js";
39
+ } from "../chunk-G5L3WVFV.js";
38
40
  import {
39
41
  DEFAULT_SESSION,
40
42
  askUser,
@@ -42,22 +44,24 @@ import {
42
44
  pollForAnswer,
43
45
  savePendingQuestion,
44
46
  sendNotification
45
- } from "../chunk-F7OURW3C.js";
47
+ } from "../chunk-RER3FRTD.js";
46
48
  import {
47
49
  UNNAMED_ACTION,
48
50
  deriveActionBody,
49
51
  deriveBlocker,
50
52
  deriveToolTarget,
51
53
  describeToolCall,
52
- scopePathFor
53
- } from "../chunk-L4E2BIJ2.js";
54
+ scopePathFor,
55
+ sessionIdentityOf
56
+ } from "../chunk-UAFQC35P.js";
57
+ import "../chunk-QQSQWLFR.js";
54
58
  import {
55
59
  getMachineId
56
- } from "../chunk-2ACC5M7F.js";
60
+ } from "../chunk-72FWXLW2.js";
57
61
  import {
58
62
  canonicalJson
59
- } from "../chunk-CV2YD2JR.js";
60
- import "../chunk-BSZYIAZL.js";
63
+ } from "../chunk-N3TF3RQ2.js";
64
+ import "../chunk-EYRGBYZG.js";
61
65
  import "../chunk-SAF6HGAA.js";
62
66
  import "../chunk-7QLSKOSU.js";
63
67
  import "../chunk-KZERVKTD.js";
@@ -388,14 +392,17 @@ var decidePreToolUse = async (input) => {
388
392
  return codexPass();
389
393
  }
390
394
  };
391
- var reportSessionStart = async (input) => {
395
+ var reportSessionStart = async (input, action = "Session started") => {
392
396
  try {
393
397
  await reportEvent({
394
398
  event: "session_begin",
395
399
  agentType: CODEX_AGENT.type,
396
400
  agentName: agentNameFor(input),
397
- action: "Session started",
398
- sessionId: input.session_id
401
+ action,
402
+ // Not `sessionId: input.session_id`. On SubagentStart that would announce
403
+ // the parent session a second time under the same id; this gives the
404
+ // subagent its own row and names the parent beside it.
405
+ ...sessionIdentityOf(input)
399
406
  }, { maxAttempts: 1, timeoutMs: 5e3 });
400
407
  } catch {
401
408
  }
@@ -458,6 +465,33 @@ var main = async () => {
458
465
  reason: input.reason
459
466
  }, CODEX_AGENT, { reconcile: false, reportAttempts: 1, reportTimeoutMs: 1200 });
460
467
  break;
468
+ // Observability only, and none of them carries context back, so none uses
469
+ // emitContext. Each goes through the same handler Claude Code's own hook
470
+ // does, rather than a Codex-shaped copy of it, so the two agents cannot
471
+ // drift into reporting the same moment differently.
472
+ case "SubagentStart":
473
+ await reportSessionStart(input, "Subagent started");
474
+ break;
475
+ case "SubagentStop":
476
+ await handleSubagentStop({
477
+ hook_event_name: input.hook_event_name,
478
+ cwd: input.cwd,
479
+ session_id: input.session_id,
480
+ agent_id: input.agent_id,
481
+ agent_type: input.agent_type,
482
+ last_assistant_message: input.last_assistant_message
483
+ }, CODEX_AGENT);
484
+ break;
485
+ case "PreCompact":
486
+ case "PostCompact":
487
+ await handleCompaction({
488
+ hook_event_name: input.hook_event_name,
489
+ trigger: input.trigger,
490
+ cwd: input.cwd,
491
+ session_id: input.session_id,
492
+ agent_id: input.agent_id
493
+ }, CODEX_AGENT);
494
+ break;
461
495
  default:
462
496
  break;
463
497
  }
@@ -1,17 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  reportEvent
4
- } from "../chunk-YXDYKECP.js";
4
+ } from "../chunk-G5L3WVFV.js";
5
5
  import {
6
6
  askUser,
7
7
  waitForAnswer
8
- } from "../chunk-F7OURW3C.js";
9
- import "../chunk-L4E2BIJ2.js";
8
+ } from "../chunk-RER3FRTD.js";
9
+ import "../chunk-UAFQC35P.js";
10
+ import "../chunk-QQSQWLFR.js";
10
11
  import {
11
12
  getMachineId
12
- } from "../chunk-2ACC5M7F.js";
13
- import "../chunk-CV2YD2JR.js";
14
- import "../chunk-BSZYIAZL.js";
13
+ } from "../chunk-72FWXLW2.js";
14
+ import "../chunk-N3TF3RQ2.js";
15
+ import "../chunk-EYRGBYZG.js";
15
16
  import "../chunk-SAF6HGAA.js";
16
17
  import "../chunk-7QLSKOSU.js";
17
18
  import "../chunk-KZERVKTD.js";
@@ -6,7 +6,7 @@ import {
6
6
  connectDevice,
7
7
  connectExistingApp,
8
8
  printConnectInstructions
9
- } from "../chunk-PYA4FLKI.js";
9
+ } from "../chunk-UPCPR7QW.js";
10
10
  import "../chunk-3EGEA4KH.js";
11
11
  import {
12
12
  checkApiKey
@@ -27,7 +27,7 @@ import {
27
27
  readKeySource
28
28
  } from "../chunk-OSALSIUF.js";
29
29
  import "../chunk-BC3VCZ3E.js";
30
- import "../chunk-BSZYIAZL.js";
30
+ import "../chunk-EYRGBYZG.js";
31
31
  import "../chunk-SAF6HGAA.js";
32
32
  import {
33
33
  UsageError
@@ -1,15 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  inspectConfiguredManagedProviders
4
- } from "../chunk-I3ORVBTP.js";
5
- import "../chunk-HDORB7WD.js";
4
+ } from "../chunk-TFN7ZCTI.js";
5
+ import "../chunk-WEDYCMHU.js";
6
6
  import {
7
7
  HEARTBEAT_INTERVAL_MS,
8
8
  sendHeartbeat
9
- } from "../chunk-2XQSN66Q.js";
10
- import "../chunk-ZMKKK6DC.js";
11
- import "../chunk-I7W3UTDK.js";
12
- import "../chunk-2LAHXHBR.js";
9
+ } from "../chunk-T2PKGGDM.js";
10
+ import "../chunk-6Y4IKMQT.js";
11
+ import "../chunk-YUZYMAL7.js";
13
12
  import "../chunk-EZIEXHYM.js";
14
13
  import {
15
14
  DAEMON_LEASE_RENEW_INTERVAL_MS,
@@ -27,7 +26,7 @@ import {
27
26
  requestDaemonHandoff,
28
27
  stopDaemonRunning,
29
28
  writeDaemonNeedsLogin
30
- } from "../chunk-SQYBP3QQ.js";
29
+ } from "../chunk-TWVZHZM3.js";
31
30
  import {
32
31
  detectProviderLiveCapabilities,
33
32
  hasSpawnProvider,
@@ -40,17 +39,18 @@ import {
40
39
  listProcessProofs,
41
40
  ownsLiveProcess,
42
41
  silentSpawnedProofs
43
- } from "../chunk-4TFXV5MW.js";
42
+ } from "../chunk-GKMQMSTB.js";
44
43
  import {
45
44
  spawnClaude
46
45
  } from "../chunk-XHKBHWLX.js";
47
46
  import {
48
47
  resolveBinary
49
48
  } from "../chunk-L4ZCFMWW.js";
49
+ import "../chunk-QQSQWLFR.js";
50
50
  import {
51
51
  getMachineId
52
- } from "../chunk-2ACC5M7F.js";
53
- import "../chunk-CV2YD2JR.js";
52
+ } from "../chunk-72FWXLW2.js";
53
+ import "../chunk-N3TF3RQ2.js";
54
54
  import {
55
55
  writeHuman
56
56
  } from "../chunk-QCGNGEGE.js";
@@ -15,10 +15,10 @@ import {
15
15
  removeGeminiSettings,
16
16
  removePusharySettings,
17
17
  restoreClaudeMcpServer
18
- } from "../chunk-I7W3UTDK.js";
19
- import "../chunk-2LAHXHBR.js";
18
+ } from "../chunk-YUZYMAL7.js";
20
19
  import "../chunk-EZIEXHYM.js";
21
20
  import "../chunk-L4ZCFMWW.js";
21
+ import "../chunk-QQSQWLFR.js";
22
22
  import {
23
23
  claudeJson,
24
24
  claudeMcpReceipt,
@@ -32,7 +32,7 @@ import {
32
32
  geminiSettings,
33
33
  removeCodexHooks,
34
34
  removeCodexSettings
35
- } from "../chunk-CV2YD2JR.js";
35
+ } from "../chunk-N3TF3RQ2.js";
36
36
  import {
37
37
  exitOnHelpFlag
38
38
  } from "../chunk-BVBEURWJ.js";