pushary 1.9.83 → 1.9.85

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 (127) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/{api-EKLKVJQG.js → api-4WEMR2G3.js} +10 -10
  3. package/dist/bin/pushary-bell-hook.js +26 -26
  4. package/dist/bin/pushary-bell.js +10 -10
  5. package/dist/bin/pushary-claude.js +32 -31
  6. package/dist/bin/pushary-clean.js +35 -33
  7. package/dist/bin/pushary-codex-bridge.js +21 -21
  8. package/dist/bin/pushary-codex-hook.js +44 -43
  9. package/dist/bin/pushary-codex-session.js +8 -8
  10. package/dist/bin/pushary-codex.js +14 -13
  11. package/dist/bin/pushary-connect.js +27 -26
  12. package/dist/bin/pushary-cowork.js +5 -5
  13. package/dist/bin/pushary-daemon.js +70 -43
  14. package/dist/bin/pushary-disconnect.js +26 -25
  15. package/dist/bin/pushary-display-hook.js +17 -17
  16. package/dist/bin/pushary-doctor.js +42 -41
  17. package/dist/bin/pushary-elicitation-hook.js +26 -26
  18. package/dist/bin/pushary-gemini-bridge.js +15 -15
  19. package/dist/bin/pushary-gemini-hook.js +35 -34
  20. package/dist/bin/pushary-hook.js +30 -30
  21. package/dist/bin/pushary-login.js +20 -20
  22. package/dist/bin/pushary-logout.js +25 -24
  23. package/dist/bin/pushary-mcp.js +11 -11
  24. package/dist/bin/pushary-mode.js +15 -15
  25. package/dist/bin/pushary-notification-hook.js +25 -25
  26. package/dist/bin/pushary-opencode-hook.js +35 -34
  27. package/dist/bin/pushary-permission-denied-hook.js +30 -30
  28. package/dist/bin/pushary-permission-hook.js +30 -30
  29. package/dist/bin/pushary-post-hook.js +25 -25
  30. package/dist/bin/pushary-prompt-hook.js +25 -25
  31. package/dist/bin/pushary-session-end-hook.js +27 -27
  32. package/dist/bin/pushary-session-start-hook.js +35 -35
  33. package/dist/bin/pushary-setup.js +48 -47
  34. package/dist/bin/pushary-stats.js +5 -5
  35. package/dist/bin/pushary-status.js +32 -31
  36. package/dist/bin/pushary-stop-hook.js +25 -25
  37. package/dist/bin/pushary-stopfailure-hook.js +25 -25
  38. package/dist/bin/pushary-suggestions.js +15 -15
  39. package/dist/bin/pushary-transcript-register.js +21 -20
  40. package/dist/bin/pushary-transcripts.js +30 -20
  41. package/dist/bin/pushary-upgrade.js +40 -39
  42. package/dist/bin/pushary-wait.js +15 -15
  43. package/dist/bin/pushary.js +7 -7
  44. package/dist/{chunk-BLM6O2QL.js → chunk-254B34JU.js} +1 -1
  45. package/dist/{chunk-XYEGVQST.js → chunk-2VZY5XQ5.js} +7 -7
  46. package/dist/chunk-3MWQZKIO.js +843 -0
  47. package/dist/{chunk-46P53RBT.js → chunk-42DNYOC4.js} +23 -21
  48. package/dist/{chunk-7YYJASRF.js → chunk-4J3NGYHG.js} +2 -2
  49. package/dist/{chunk-ZGZ2L3QN.js → chunk-4OP5GWHQ.js} +5 -5
  50. package/dist/{chunk-5UPZR3C3.js → chunk-4QGV3II7.js} +4 -4
  51. package/dist/{chunk-MHUKYYYR.js → chunk-4TMKTLQX.js} +44 -1
  52. package/dist/{chunk-2B7YU4EK.js → chunk-5Z43EFX2.js} +2 -2
  53. package/dist/{chunk-YIAJOV2X.js → chunk-64XK7DLE.js} +3 -3
  54. package/dist/{chunk-VRHVOMH2.js → chunk-6HBWJXU6.js} +3 -3
  55. package/dist/{chunk-IUZCERPQ.js → chunk-7GYDMVHV.js} +2 -2
  56. package/dist/{chunk-BG4YJEFE.js → chunk-7ZYVX2KN.js} +1 -1
  57. package/dist/{chunk-KR3KVDXD.js → chunk-BGMYSRMY.js} +1 -1
  58. package/dist/{chunk-OUYFUUWB.js → chunk-BS5MTP34.js} +2 -2
  59. package/dist/{chunk-VCMDY6YL.js → chunk-BUS7MXEE.js} +3 -3
  60. package/dist/{chunk-EMT7I74E.js → chunk-CIICMXVH.js} +3 -3
  61. package/dist/{chunk-4P256ZAU.js → chunk-CSOVOAX5.js} +6 -6
  62. package/dist/{chunk-VBY2AHSX.js → chunk-CZ7C5AJT.js} +1 -1
  63. package/dist/{chunk-HCLP2QBX.js → chunk-DNBBWBYA.js} +5 -5
  64. package/dist/{chunk-BJN7LMMK.js → chunk-EKWDNEPN.js} +3 -3
  65. package/dist/{chunk-TNWQ6SKS.js → chunk-EX33ZFJ6.js} +3 -3
  66. package/dist/{chunk-TMBLBDPB.js → chunk-FNC4SPOD.js} +2 -2
  67. package/dist/{chunk-IBULUTHA.js → chunk-FRPR4OTH.js} +4 -4
  68. package/dist/{chunk-ACM4OINM.js → chunk-FSSA76HW.js} +1 -1
  69. package/dist/{chunk-J2PAQ3HF.js → chunk-G2GOVKBU.js} +6 -6
  70. package/dist/{chunk-2KVELJZX.js → chunk-GGGOFJBL.js} +1 -1
  71. package/dist/{chunk-GKWPIE6R.js → chunk-GWHZUHIK.js} +1 -1
  72. package/dist/{chunk-BUXMFD5C.js → chunk-H6IJOGDH.js} +4 -4
  73. package/dist/{chunk-SN22OXY3.js → chunk-HARHFDZM.js} +1 -1
  74. package/dist/{chunk-44R5ATBR.js → chunk-HLAW7HUT.js} +2 -2
  75. package/dist/{chunk-G4HTRKCP.js → chunk-HVZJ2EEI.js} +6 -6
  76. package/dist/{chunk-6BD5ZZLL.js → chunk-HWT42Z4O.js} +5 -5
  77. package/dist/{chunk-L4THAI7Q.js → chunk-JHWOM55B.js} +2 -0
  78. package/dist/{chunk-NDLOWIYO.js → chunk-JJCMQRBF.js} +3 -3
  79. package/dist/{chunk-7MRX5JYA.js → chunk-JLJWVKMJ.js} +54 -835
  80. package/dist/{chunk-TBU4WXA4.js → chunk-JSZT4Q23.js} +1 -1
  81. package/dist/{chunk-MA6FJ7U3.js → chunk-LUSWC2MV.js} +3 -3
  82. package/dist/{chunk-C5EWCNJF.js → chunk-OGTZ7JR7.js} +1 -1
  83. package/dist/{chunk-FGWRVOBP.js → chunk-OKWHHDV5.js} +5 -5
  84. package/dist/{chunk-XHHX63PY.js → chunk-OSEGZLCO.js} +3 -3
  85. package/dist/{chunk-B2RDWRKR.js → chunk-PHBZK4SC.js} +2 -2
  86. package/dist/{chunk-S55CXRFD.js → chunk-POKCUYIQ.js} +1 -1
  87. package/dist/{chunk-YZVAAY6B.js → chunk-QF6OJUWQ.js} +1 -1
  88. package/dist/{chunk-5FM4BQOM.js → chunk-QG5Y5A36.js} +10 -10
  89. package/dist/{chunk-UNEJNC6X.js → chunk-QSDZE2B7.js} +5 -5
  90. package/dist/{chunk-Y32CL7XZ.js → chunk-RPNT4D3K.js} +1 -1
  91. package/dist/{chunk-6CJ4MSZU.js → chunk-SAPRO7FI.js} +6 -6
  92. package/dist/{chunk-LLQBPDFQ.js → chunk-SBK7WGSE.js} +2 -2
  93. package/dist/{chunk-GMZTABMV.js → chunk-TD5PW2VI.js} +6 -6
  94. package/dist/{chunk-VUI4HK5O.js → chunk-TFJQAPIA.js} +2 -2
  95. package/dist/{chunk-OKZC4FHN.js → chunk-TNPKYKXU.js} +166 -24
  96. package/dist/{chunk-2BDGGE2G.js → chunk-TSCFJJIB.js} +6 -6
  97. package/dist/{chunk-MND7HQ4P.js → chunk-TZDEHPYZ.js} +1 -1
  98. package/dist/{chunk-FEF3ILT6.js → chunk-UGELL4RB.js} +2 -2
  99. package/dist/{chunk-6WOG2SCC.js → chunk-UIDWJ24H.js} +6 -13
  100. package/dist/{chunk-ZS27XXDA.js → chunk-UWL6VVE3.js} +4 -4
  101. package/dist/{chunk-JIC5PGNI.js → chunk-V4JZHAOY.js} +2 -2
  102. package/dist/{chunk-35ABA2JQ.js → chunk-VD24OIWR.js} +1 -1
  103. package/dist/{chunk-GGI6GTBL.js → chunk-VJZGR4N3.js} +7 -5
  104. package/dist/{chunk-CVPVP4KP.js → chunk-VVWL6AB4.js} +5 -5
  105. package/dist/{chunk-A3TMREYJ.js → chunk-W2IRYDG5.js} +4 -4
  106. package/dist/{chunk-SSNLMIFR.js → chunk-WRKRZJCW.js} +10 -8
  107. package/dist/{chunk-ASEHRBD4.js → chunk-YQCCJ6U5.js} +3 -3
  108. package/dist/{chunk-42RQG2VG.js → chunk-YU5ACKJP.js} +4 -4
  109. package/dist/{chunk-HIMEVTA5.js → chunk-Z75D2NJN.js} +3 -3
  110. package/dist/{chunk-6PWU2LBT.js → chunk-ZHL6F2KC.js} +3 -3
  111. package/dist/{chunk-SVAGMJOH.js → chunk-ZNFAF74M.js} +1 -1
  112. package/dist/{chunk-ELYJNNXG.js → chunk-ZUZ7NTWO.js} +181 -75
  113. package/dist/{chunk-QPJQAE2L.js → chunk-ZWKF7WE4.js} +4 -4
  114. package/dist/{codex-app-cards-switch-CTAOTOCH.js → codex-app-cards-switch-26N5XSSZ.js} +11 -11
  115. package/dist/{codex-desktop-launch-2DZVA5C7.js → codex-desktop-launch-UU6CPB2I.js} +1 -1
  116. package/dist/{codex-session-launch-TMOSTWEH.js → codex-session-launch-66LBR4MG.js} +18 -18
  117. package/dist/{config-OV6WLZXO.js → config-ESAAVJWO.js} +3 -3
  118. package/dist/{global-upgrade-FI42NJNL.js → global-upgrade-QJONTWQI.js} +10 -10
  119. package/dist/{identity-PCA25OI5.js → identity-IZVPSC7B.js} +4 -4
  120. package/dist/{live-capabilities-CYFXHTOI.js → live-capabilities-OEUPZX67.js} +5 -5
  121. package/dist/{paths-4YFDMUK6.js → paths-GDWS3B46.js} +3 -3
  122. package/dist/{reapply-PBQ46BPS.js → reapply-P2VOZGWQ.js} +28 -27
  123. package/dist/src/index.js +29 -29
  124. package/dist/{upgrade-lock-22J2AMVY.js → upgrade-lock-3QABNXBZ.js} +4 -4
  125. package/dist/{usage-7KTINNRK.js → usage-KDRZPUZS.js} +3 -3
  126. package/package.json +1 -1
  127. package/dist/chunk-7EIMASAA.js +0 -74
@@ -1,18 +1,13 @@
1
1
  import {
2
- changedRecipientsMessage,
3
- loadPin,
4
- savePin,
5
- verifyRecipients
6
- } from "./chunk-7EIMASAA.js";
7
- import {
8
- SESSION_HISTORY_RETENTION_DAYS
9
- } from "./chunk-MHUKYYYR.js";
2
+ SESSION_HISTORY_RETENTION_DAYS,
3
+ savedTranscriptReadPositions
4
+ } from "./chunk-4TMKTLQX.js";
10
5
  import {
11
6
  ensureDaemonRunning
12
- } from "./chunk-6CJ4MSZU.js";
7
+ } from "./chunk-SAPRO7FI.js";
13
8
  import {
14
9
  hookOwnerOf
15
- } from "./chunk-42RQG2VG.js";
10
+ } from "./chunk-YU5ACKJP.js";
16
11
  import {
17
12
  buildTranscriptRecords,
18
13
  decodePublicKey,
@@ -23,46 +18,112 @@ import {
23
18
  recordSealerFor,
24
19
  uploadTranscriptRecords,
25
20
  wrapSessionKey
26
- } from "./chunk-IUZCERPQ.js";
21
+ } from "./chunk-7GYDMVHV.js";
27
22
  import {
28
23
  external_exports
29
24
  } from "./chunk-XMSDA5WA.js";
30
25
  import {
31
26
  transcriptEnvironmentPreference,
32
27
  transcriptsEnabled
33
- } from "./chunk-GKWPIE6R.js";
28
+ } from "./chunk-GWHZUHIK.js";
34
29
  import {
35
30
  readTranscriptPreference
36
- } from "./chunk-IBULUTHA.js";
31
+ } from "./chunk-FRPR4OTH.js";
32
+ import {
33
+ hookMeaning
34
+ } from "./chunk-3MWQZKIO.js";
37
35
  import {
38
36
  claudeConfigDir,
39
37
  codexHome,
40
38
  pusharyDir
41
- } from "./chunk-B2RDWRKR.js";
39
+ } from "./chunk-PHBZK4SC.js";
42
40
  import {
43
41
  writeJsonAtomic,
44
42
  writeJsonAtomicDurable
45
- } from "./chunk-YIAJOV2X.js";
43
+ } from "./chunk-64XK7DLE.js";
46
44
  import {
47
45
  getApiKey,
48
46
  getBaseUrl
49
- } from "./chunk-TBU4WXA4.js";
47
+ } from "./chunk-JSZT4Q23.js";
50
48
  import {
51
49
  PENDING_COMMAND_PREFIX,
52
50
  SESSION_HISTORY_BACKFILL_LIMIT_BYTES,
53
51
  canonicalJsonText,
52
+ isHookSource,
54
53
  isRecord,
55
54
  redactSecretsFromContent
56
- } from "./chunk-L4THAI7Q.js";
55
+ } from "./chunk-JHWOM55B.js";
56
+
57
+ // src/transcript-recipient-pin.ts
58
+ import { existsSync, mkdirSync, readFileSync, rmSync } from "fs";
59
+ import { homedir } from "os";
60
+ import { dirname, join } from "path";
61
+ var pinFile = () => process.env.PUSHARY_RECIPIENT_PIN_FILE?.trim() || join(homedir(), ".pushary", "recipients.json");
62
+ var asPin = (offer) => ({
63
+ phonePublicKey: offer.phonePublicKey,
64
+ providerKeyId: offer.provider?.keyId ?? null,
65
+ providerPublicKey: offer.provider?.publicKey ?? null
66
+ });
67
+ var loadPin = (path = pinFile()) => {
68
+ if (!existsSync(path)) return null;
69
+ try {
70
+ const raw = JSON.parse(readFileSync(path, "utf-8"));
71
+ if (typeof raw.phonePublicKey !== "string" || raw.phonePublicKey.length === 0) return null;
72
+ return {
73
+ phonePublicKey: raw.phonePublicKey,
74
+ providerKeyId: typeof raw.providerKeyId === "string" ? raw.providerKeyId : null,
75
+ providerPublicKey: typeof raw.providerPublicKey === "string" ? raw.providerPublicKey : null
76
+ };
77
+ } catch {
78
+ return null;
79
+ }
80
+ };
81
+ var savePin = (pin, path = pinFile()) => {
82
+ try {
83
+ mkdirSync(dirname(path), { recursive: true, mode: 448 });
84
+ writeJsonAtomicDurable(path, pin, 384);
85
+ return true;
86
+ } catch {
87
+ return false;
88
+ }
89
+ };
90
+ var clearPin = () => {
91
+ try {
92
+ rmSync(pinFile(), { force: true });
93
+ } catch {
94
+ }
95
+ };
96
+ var verifyRecipients = (offer, pinned) => {
97
+ if (!pinned) return { kind: "first-use", pin: asPin(offer) };
98
+ const next = asPin(offer);
99
+ const changed = [];
100
+ if (next.phonePublicKey !== pinned.phonePublicKey) changed.push("the phone key this machine seals to");
101
+ if (next.providerKeyId !== pinned.providerKeyId) changed.push("the compliance recovery key id");
102
+ if (next.providerPublicKey !== pinned.providerPublicKey) changed.push("the compliance recovery key");
103
+ return changed.length === 0 ? { kind: "match" } : { kind: "changed", changed };
104
+ };
105
+ var fingerprint = (publicKey) => {
106
+ const hex = Buffer.from(publicKey, "base64").toString("hex").toUpperCase();
107
+ return (hex.slice(0, 8).match(/.{2}/g) ?? []).join(" ");
108
+ };
109
+ var changedRecipientsMessage = (verdict, offer) => [
110
+ "[pushary] Transcript sync stopped: the keys this machine seals transcripts to have changed.",
111
+ ...verdict.changed.map((what) => `[pushary] changed: ${what}`),
112
+ `[pushary] now offered: phone ${fingerprint(offer.phonePublicKey)}${offer.provider ? `, recovery ${offer.provider.keyId.slice(0, 8)}` : ", no recovery key"}`,
113
+ "[pushary] If you reinstalled the app or rotated a key, this is expected. Compare the",
114
+ "[pushary] fingerprint above with the one in the app under Settings, then run:",
115
+ "[pushary] pushary transcripts trust --rotate",
116
+ "[pushary] Until then nothing is uploaded, so no turn is sealed to a key you have not seen."
117
+ ].join("\n");
57
118
 
58
119
  // src/transcript-registration.ts
59
120
  import { createHash as createHash4 } from "crypto";
60
- import { readFileSync as readFileSync6, readdirSync as readdirSync2, realpathSync, statSync as statSync3, unlinkSync as unlinkSync2 } from "fs";
61
- import { basename, dirname as dirname2, isAbsolute, join as join5, relative, resolve as resolve2, sep } from "path";
121
+ import { lstatSync as lstatSync3, readFileSync as readFileSync7, readdirSync as readdirSync2, realpathSync, statSync as statSync3, unlinkSync as unlinkSync2 } from "fs";
122
+ import { basename, dirname as dirname3, isAbsolute, join as join6, relative, resolve as resolve2, sep } from "path";
62
123
 
63
124
  // src/claude-display-draft.ts
64
- import { closeSync, fstatSync, lstatSync, openSync, readFileSync, readSync, unlinkSync } from "fs";
65
- import { join } from "path";
125
+ import { closeSync, fstatSync, lstatSync, openSync, readFileSync as readFileSync2, readSync, unlinkSync } from "fs";
126
+ import { join as join2 } from "path";
66
127
 
67
128
  // src/transcript-redaction.ts
68
129
  var redactDraft = (text, complete = false) => {
@@ -115,14 +176,14 @@ var stateSchema = external_exports.object({
115
176
  startedAt: external_exports.number().int().positive(),
116
177
  updatedAt: external_exports.number().int().positive()
117
178
  });
118
- var fileFor = (id, directory) => join(directory, `${id}.display`);
179
+ var fileFor = (id, directory) => join2(directory, `${id}.display`);
119
180
  var readState = (sessionId, runtime) => {
120
181
  if (!identifier.safeParse(sessionId).success) return null;
121
182
  try {
122
183
  const path = fileFor(sessionId, runtime.directory);
123
184
  const info = lstatSync(path);
124
185
  if (!info.isFile() || info.nlink !== 1 || info.size > MAX_TAIL || (info.mode & 511) !== 384) return null;
125
- const envelope = external_exports.object({ content: external_exports.string() }).parse(JSON.parse(readFileSync(path, "utf8")));
186
+ const envelope = external_exports.object({ content: external_exports.string() }).parse(JSON.parse(readFileSync2(path, "utf8")));
126
187
  const plain = decryptRecord(envelope.content, runtime.sessionKey);
127
188
  if (!plain) return null;
128
189
  const state = stateSchema.parse(JSON.parse(plain));
@@ -205,18 +266,18 @@ var readDisplayDraft = (sessionId, runtime) => {
205
266
  };
206
267
 
207
268
  // src/transcript-session-key.ts
208
- import { existsSync, mkdirSync, readFileSync as readFileSync2, readdirSync, rmSync, statSync } from "fs";
209
- import { homedir } from "os";
210
- import { join as join2 } from "path";
211
- var sessionKeyDirectory = () => process.env.PUSHARY_SESSION_KEY_DIR?.trim() || join2(homedir(), ".pushary", "sessions");
269
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync, rmSync as rmSync2, statSync } from "fs";
270
+ import { homedir as homedir2 } from "os";
271
+ import { join as join3 } from "path";
272
+ var sessionKeyDirectory = () => process.env.PUSHARY_SESSION_KEY_DIR?.trim() || join3(homedir2(), ".pushary", "sessions");
212
273
  var SESSION_DISPLAY_TTL_MS = 48 * 60 * 60 * 1e3;
213
274
  var SAFE_SESSION_ID = /^[A-Za-z0-9._-]{1,128}$/;
214
- var fileFor2 = (sessionId, directory) => SAFE_SESSION_ID.test(sessionId) ? join2(directory, `${sessionId}.json`) : null;
275
+ var fileFor2 = (sessionId, directory) => SAFE_SESSION_ID.test(sessionId) ? join3(directory, `${sessionId}.json`) : null;
215
276
  var loadSessionKey = (sessionId, directory = sessionKeyDirectory()) => {
216
277
  const path = fileFor2(sessionId, directory);
217
- if (!path || !existsSync(path)) return null;
278
+ if (!path || !existsSync2(path)) return null;
218
279
  try {
219
- const raw = JSON.parse(readFileSync2(path, "utf-8"));
280
+ const raw = JSON.parse(readFileSync3(path, "utf-8"));
220
281
  const key = typeof raw.sessionKey === "string" ? Buffer.from(raw.sessionKey, "base64") : null;
221
282
  if (!key || key.length !== 32) return null;
222
283
  return {
@@ -235,7 +296,7 @@ var saveSessionKey = (sessionId, value, directory = sessionKeyDirectory()) => {
235
296
  const path = fileFor2(sessionId, directory);
236
297
  if (!path) return false;
237
298
  try {
238
- mkdirSync(directory, { recursive: true, mode: 448 });
299
+ mkdirSync2(directory, { recursive: true, mode: 448 });
239
300
  writeJsonAtomicDurable(path, {
240
301
  sessionKey: Buffer.from(value.sessionKey).toString("base64"),
241
302
  wrappedKey: value.wrappedKey,
@@ -250,15 +311,15 @@ var saveSessionKey = (sessionId, value, directory = sessionKeyDirectory()) => {
250
311
  }
251
312
  };
252
313
  var sweepStaleSessionDisplays = (now = Date.now(), dir = sessionKeyDirectory()) => {
253
- if (!existsSync(dir)) return 0;
314
+ if (!existsSync2(dir)) return 0;
254
315
  let removed = 0;
255
316
  try {
256
317
  for (const name of readdirSync(dir)) {
257
318
  if (!name.endsWith(".display")) continue;
258
- const path = join2(dir, name);
319
+ const path = join3(dir, name);
259
320
  try {
260
321
  if (now - statSync(path).mtimeMs <= SESSION_DISPLAY_TTL_MS) continue;
261
- rmSync(path, { force: true });
322
+ rmSync2(path, { force: true });
262
323
  removed += 1;
263
324
  } catch {
264
325
  }
@@ -366,8 +427,8 @@ var startDisplayPublisher = (options) => {
366
427
 
367
428
  // src/transcript-reader.ts
368
429
  import { createHash as createHash3 } from "crypto";
369
- import { join as join3 } from "path";
370
- import { closeSync as closeSync3, fstatSync as fstatSync3, openSync as openSync3, readFileSync as readFileSync5, readSync as readSync2, statSync as statSync2 } from "fs";
430
+ import { join as join4 } from "path";
431
+ import { closeSync as closeSync3, fstatSync as fstatSync3, openSync as openSync3, readFileSync as readFileSync6, readSync as readSync2, statSync as statSync2 } from "fs";
371
432
 
372
433
  // src/transcript-source.ts
373
434
  var normalizeTranscriptLines = (lines, source) => {
@@ -422,7 +483,7 @@ var transcriptLinesSince = (lines, oldestLineMs, dropCompactionSummaries) => lin
422
483
  });
423
484
 
424
485
  // src/transcript-snapshot-file.ts
425
- import { closeSync as closeSync2, fstatSync as fstatSync2, openSync as openSync2, readFileSync as readFileSync3 } from "fs";
486
+ import { closeSync as closeSync2, fstatSync as fstatSync2, openSync as openSync2, readFileSync as readFileSync4 } from "fs";
426
487
 
427
488
  // src/transcript-snapshot-source.ts
428
489
  import { createHash } from "crypto";
@@ -551,10 +612,10 @@ var parseCursorSnapshot = (text) => {
551
612
  const record = JSON.parse(line);
552
613
  if (isRecord(record) && (record.type === "metadata" || record.type === "turn_ended")) continue;
553
614
  const message = cursorMessage.parse(record);
554
- const fingerprint = createHash("sha256").update(canonicalJsonText(message)).digest("hex");
555
- const occurrence = occurrences.get(fingerprint) ?? 0;
556
- occurrences.set(fingerprint, occurrence + 1);
557
- messages.push({ id: `cursor:${fingerprint}:${occurrence}`, role: message.role, content: message.message.content });
615
+ const fingerprint2 = createHash("sha256").update(canonicalJsonText(message)).digest("hex");
616
+ const occurrence = occurrences.get(fingerprint2) ?? 0;
617
+ occurrences.set(fingerprint2, occurrence + 1);
618
+ messages.push({ id: `cursor:${fingerprint2}:${occurrence}`, role: message.role, content: message.message.content });
558
619
  }
559
620
  return messages;
560
621
  };
@@ -587,7 +648,7 @@ var readTranscriptSnapshot = (path, source, sessionId) => {
587
648
  try {
588
649
  const before = fstatSync2(descriptor);
589
650
  if (!before.isFile() || before.size === 0 || before.size > SESSION_HISTORY_BACKFILL_LIMIT_BYTES) throw new Error("History snapshot is empty or exceeds its size limit");
590
- const text = readFileSync3(descriptor, "utf8");
651
+ const text = readFileSync4(descriptor, "utf8");
591
652
  const after = fstatSync2(descriptor);
592
653
  if (before.size !== after.size || before.mtimeMs !== after.mtimeMs) throw new Error("History snapshot changed while reading");
593
654
  let messages;
@@ -610,8 +671,8 @@ var readTranscriptSnapshot = (path, source, sessionId) => {
610
671
  };
611
672
 
612
673
  // src/transcript-snapshot-journal.ts
613
- import { lstatSync as lstatSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync4 } from "fs";
614
- import { dirname } from "path";
674
+ import { lstatSync as lstatSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "fs";
675
+ import { dirname as dirname2 } from "path";
615
676
 
616
677
  // src/transcript-projection.ts
617
678
  import { createHash as createHash2 } from "crypto";
@@ -619,7 +680,8 @@ var projectTranscriptSnapshot = (previous, messages) => {
619
680
  const revision = (previous?.revision ?? 0) + 1;
620
681
  const entries = /* @__PURE__ */ Object.create(null);
621
682
  const lines = [];
622
- for (const [order, message] of messages.entries()) {
683
+ for (const message of messages) {
684
+ const order = message.sourcePosition;
623
685
  if (!message.id || message.id.length > 256 || Object.hasOwn(entries, message.id)) throw new Error("Invalid or duplicate history message identity");
624
686
  const record = { timestamp: message.timestamp, observedAtMs: message.observedAtMs, historyMessage: { role: message.role, content: message.content } };
625
687
  const digest = createHash2("sha256").update(JSON.stringify(record)).digest("hex");
@@ -660,7 +722,7 @@ var TranscriptSnapshotJournal = class {
660
722
  return;
661
723
  }
662
724
  if (!info.isFile() || info.nlink !== 1 || info.size > MAXIMUM_JOURNAL_BYTES || process.getuid && (info.uid !== process.getuid() || (info.mode & 511) !== 384)) throw new Error("Unsafe history checkpoint");
663
- const saved = journalSchema.parse(JSON.parse(readFileSync4(path, "utf8")));
725
+ const saved = journalSchema.parse(JSON.parse(readFileSync5(path, "utf8")));
664
726
  if (saved.binding !== binding) throw new Error("History checkpoint belongs to another source");
665
727
  this.current = saved.epochStartedAtMs === epochStartedAtMs ? saved : { ...saved, epochStartedAtMs, initialized: false, observedAtMs: {}, pending: null, excludedIds: [], projection: { revision: Math.max(saved.projection?.revision ?? 0, saved.pending?.next.revision ?? 0), entries: {} } };
666
728
  }
@@ -677,7 +739,7 @@ var TranscriptSnapshotJournal = class {
677
739
  for (const message of messages) {
678
740
  if (!message.timestamp && !excluded.has(message.id) && !Object.hasOwn(observedAtMs, message.id)) observedAtMs[message.id] = nowMs;
679
741
  }
680
- const allowed = messages.filter((message) => !excluded.has(message.id) && (message.timestamp ? Date.parse(message.timestamp) : observedAtMs[message.id] ?? 0) >= oldestMessageMs).map((message) => message.timestamp ? message : { ...message, observedAtMs: observedAtMs[message.id] });
742
+ const allowed = messages.flatMap((message, sourcePosition) => !excluded.has(message.id) && (message.timestamp ? Date.parse(message.timestamp) : observedAtMs[message.id] ?? 0) >= oldestMessageMs ? [{ ...message.timestamp ? message : { ...message, observedAtMs: observedAtMs[message.id] }, sourcePosition }] : []);
681
743
  const projected = projectTranscriptSnapshot(this.current.projection, allowed);
682
744
  if (projected.lines.length === 0) {
683
745
  const metadataChanged = excluded.size !== this.current.excludedIds.length || Object.keys(observedAtMs).length !== Object.keys(this.current.observedAtMs).length;
@@ -705,7 +767,7 @@ var TranscriptSnapshotJournal = class {
705
767
  }
706
768
  store(next) {
707
769
  if (Buffer.byteLength(JSON.stringify(next)) > MAXIMUM_JOURNAL_BYTES) throw new Error("History checkpoint exceeds its size limit");
708
- mkdirSync2(dirname(this.path), { recursive: true, mode: 448 });
770
+ mkdirSync3(dirname2(this.path), { recursive: true, mode: 448 });
709
771
  writeJsonAtomicDurable(this.path, next, 384);
710
772
  this.current = journalSchema.parse(next);
711
773
  }
@@ -801,7 +863,7 @@ var appendOnlyReader = (path, source, epoch) => ({
801
863
  read(retentionDays, nowMs) {
802
864
  const version = sourceVersion(path);
803
865
  const read2 = epoch ? linesSeenDuringEpoch(epoch, path, source, nowMs, retentionDays) : null;
804
- const lines = read2?.lines ?? normalizeTranscriptLines(readFileSync5(path, "utf8").split("\n"), source);
866
+ const lines = read2?.lines ?? normalizeTranscriptLines(readFileSync6(path, "utf8").split("\n"), source);
805
867
  return {
806
868
  lines,
807
869
  acknowledge() {
@@ -815,7 +877,7 @@ var appendOnlyReader = (path, source, epoch) => ({
815
877
  var snapshotReader = (options, source) => {
816
878
  const { path, epoch } = options;
817
879
  const binding = createHash3("sha256").update(JSON.stringify([options.baseUrl, options.apiKey, options.machineId, options.sessionId, source, path])).digest("hex");
818
- const journalPath = join3(options.keyDirectory, "snapshots", binding + ".json");
880
+ const journalPath = join4(options.keyDirectory, "snapshots", binding + ".json");
819
881
  const epochStart = epoch?.startedAtMs ?? 0;
820
882
  const backfill = epoch ? epoch.backfill : SESSION_HISTORY_BACKFILL;
821
883
  let journal;
@@ -866,11 +928,11 @@ var transcriptHealthReporter = (target) => {
866
928
  };
867
929
 
868
930
  // src/transcript-sync.ts
869
- import { join as join4, resolve } from "path";
931
+ import { join as join5, resolve } from "path";
870
932
  var claudeTranscriptPath = (cwd, sessionId) => {
871
933
  const projectId = resolve(cwd).replace(/[^a-zA-Z0-9-]/g, "-");
872
934
  const configDir = claudeConfigDir();
873
- return join4(configDir, "projects", projectId, `${sessionId}.jsonl`);
935
+ return join5(configDir, "projects", projectId, `${sessionId}.jsonl`);
874
936
  };
875
937
  var createSyncState = () => ({
876
938
  sessionKey: null,
@@ -977,6 +1039,8 @@ var chunkRecords = (records) => {
977
1039
  };
978
1040
  var IDLE_CEILING_MS = 6e4;
979
1041
  var RECIPIENT_REFRESH_MS = 6e4;
1042
+ var MAXIMUM_READS_PASSED_OVER_PER_TICK = 16;
1043
+ var LONGEST_SESSION_HISTORY_RETENTION_DAYS = Math.max(...Object.values(SESSION_HISTORY_RETENTION_DAYS));
980
1044
  var CATCH_UP_DELAY_MS = 50;
981
1045
  var STALLED_BACKOFF_FACTOR = 4;
982
1046
  var nothingLeftToUpload = (state) => state.sessionKey !== null && !state.keyRejected && state.unsettled === 0;
@@ -1039,6 +1103,15 @@ var startTranscriptSync = (opts) => {
1039
1103
  persistedKey = state.sessionKey;
1040
1104
  persistedUploaded = state.keyUploaded;
1041
1105
  };
1106
+ const passOverConversationWhileHistoryIsOff = () => {
1107
+ try {
1108
+ for (let read2 = 0; read2 < MAXIMUM_READS_PASSED_OVER_PER_TICK; read2++) {
1109
+ if (reader.read(LONGEST_SESSION_HISTORY_RETENTION_DAYS, Date.now()).acknowledge() !== "more") return;
1110
+ }
1111
+ } catch {
1112
+ return;
1113
+ }
1114
+ };
1042
1115
  let running = true;
1043
1116
  let inFlight = false;
1044
1117
  let stalled = false;
@@ -1059,6 +1132,7 @@ var startTranscriptSync = (opts) => {
1059
1132
  const recipients = await fetchPinnedRecipients();
1060
1133
  if (!recipients) {
1061
1134
  waitingForRecipients = true;
1135
+ if (recipientFailure === "off_for_workspace") passOverConversationWhileHistoryIsOff();
1062
1136
  await reportHealth(recipientFailure);
1063
1137
  return;
1064
1138
  }
@@ -1125,7 +1199,7 @@ var startTranscriptSync = (opts) => {
1125
1199
  };
1126
1200
 
1127
1201
  // src/transcript-registration.ts
1128
- import { homedir as homedir2 } from "os";
1202
+ import { homedir as homedir3 } from "os";
1129
1203
  var storedRegistrationSchema = external_exports.object({
1130
1204
  sessionId: external_exports.string().min(1).max(128),
1131
1205
  cwd: external_exports.string(),
@@ -1140,18 +1214,41 @@ var storedRegistrationSchema = external_exports.object({
1140
1214
  endedAt: external_exports.number().positive().optional(),
1141
1215
  drained: external_exports.boolean().optional()
1142
1216
  });
1143
- var defaultRegistryDirectory = () => process.env.PUSHARY_TRANSCRIPT_REGISTRY_DIR || join5(pusharyDir(), "transcript-capture");
1217
+ var defaultRegistryDirectory = () => process.env.PUSHARY_TRANSCRIPT_REGISTRY_DIR || join6(pusharyDir(), "transcript-capture");
1144
1218
  var cliRegistry = (apiKey = getApiKey()) => ({ apiKey, baseUrl: getBaseUrl(), directory: defaultRegistryDirectory() });
1145
1219
  var accountFor = (registry) => createHash4("sha256").update(`${registry.baseUrl}\0${registry.apiKey}`).digest("hex");
1146
1220
  var TTL = 48 * 60 * 60 * 1e3;
1221
+ var registeredReadPositionsFile = (registry) => join6(registry.directory, "read-positions", `${accountFor(registry)}.json`);
1222
+ var SNAPSHOT_KEYS_DIRECTORY_NAME = "snapshot-keys";
1223
+ var SNAPSHOT_RECIPIENT_PIN_FILE_NAME = "recipients.json";
1224
+ var snapshotKeyDirectory = (registry) => join6(registry.directory, SNAPSHOT_KEYS_DIRECTORY_NAME, accountFor(registry));
1225
+ var snapshotRecipientPinFile = (registry) => join6(snapshotKeyDirectory(registry), SNAPSHOT_RECIPIENT_PIN_FILE_NAME);
1226
+ var entryAt = (path) => {
1227
+ try {
1228
+ return lstatSync3(path);
1229
+ } catch {
1230
+ return null;
1231
+ }
1232
+ };
1233
+ var removedPinFile = (path) => {
1234
+ const entry = entryAt(path);
1235
+ if (!entry || !(entry.isFile() || entry.isSymbolicLink())) return false;
1236
+ unlinkSync2(path);
1237
+ return true;
1238
+ };
1239
+ var clearSnapshotRecipientPins = (registryDirectory = defaultRegistryDirectory()) => {
1240
+ const accounts = join6(registryDirectory, SNAPSHOT_KEYS_DIRECTORY_NAME);
1241
+ if (!entryAt(accounts)?.isDirectory()) return false;
1242
+ return readdirSync2(accounts, { withFileTypes: true }).filter((account) => account.isDirectory()).map((account) => removedPinFile(join6(accounts, account.name, SNAPSHOT_RECIPIENT_PIN_FILE_NAME))).includes(true);
1243
+ };
1147
1244
  var read = (path) => {
1148
1245
  if (statSync3(path).size > 16384) throw new Error("History registration exceeds its size limit");
1149
- return storedRegistrationSchema.parse(JSON.parse(readFileSync6(path, "utf8")));
1246
+ return storedRegistrationSchema.parse(JSON.parse(readFileSync7(path, "utf8")));
1150
1247
  };
1151
1248
  var consent = (record) => record.consentOverride ?? readTranscriptPreference() ?? true;
1152
1249
  var withoutTrailingSlash = (url) => url.replace(/\/+$/, "");
1153
1250
  var sameServer = (url, registry) => withoutTrailingSlash(url) === withoutTrailingSlash(registry.baseUrl);
1154
- var fileFor3 = (registry, sessionId) => join5(registry.directory, `${createHash4("sha256").update(accountFor(registry) + sessionId).digest("hex")}.json`);
1251
+ var fileFor3 = (registry, sessionId) => join6(registry.directory, `${createHash4("sha256").update(accountFor(registry) + sessionId).digest("hex")}.json`);
1155
1252
  var permitted = (registry, raw) => raw.account === accountFor(registry) && consent(raw) && !raw.drained && (raw.source !== "claude" || !!raw.expectedSiteId || !macOwnsClaudeHooks(raw.cwd)) && (!raw.expectedSiteId || raw.expectedSiteId === raw.verifiedSiteId && !!raw.expectedBaseUrl && sameServer(raw.expectedBaseUrl, registry));
1156
1253
  var registeredTranscriptEnabled = (apiKey, sessionId, registry = cliRegistry(apiKey)) => {
1157
1254
  try {
@@ -1161,25 +1258,25 @@ var registeredTranscriptEnabled = (apiKey, sessionId, registry = cliRegistry(api
1161
1258
  }
1162
1259
  };
1163
1260
  var macOwnsClaudeHooks = (cwd) => [
1164
- join5(claudeConfigDir(), "settings.json"),
1165
- join5(cwd, ".claude", "settings.json"),
1166
- join5(cwd, ".claude", "settings.local.json")
1261
+ join6(claudeConfigDir(), "settings.json"),
1262
+ join6(cwd, ".claude", "settings.json"),
1263
+ join6(cwd, ".claude", "settings.local.json")
1167
1264
  ].some((path) => {
1168
1265
  try {
1169
- return hookOwnerOf(JSON.parse(readFileSync6(path, "utf8"))) === "app";
1266
+ return hookOwnerOf(JSON.parse(readFileSync7(path, "utf8"))) === "app";
1170
1267
  } catch {
1171
1268
  return false;
1172
1269
  }
1173
1270
  });
1174
1271
  var TRANSCRIPT_ROOT_NAME = { claude: "projects", codex: "sessions", gemini: "tmp", cursor: "projects", hermes: "hermes-history" };
1175
1272
  var transcriptRoots = (source) => {
1176
- const home = homedir2();
1177
- if (source === "codex") return [join5(codexHome(), TRANSCRIPT_ROOT_NAME.codex)];
1178
- if (source === "cursor") return [join5(home, ".cursor", TRANSCRIPT_ROOT_NAME.cursor)];
1179
- if (source === "hermes") return [join5(home, ".pushary", TRANSCRIPT_ROOT_NAME.hermes)];
1180
- if (source === "gemini") return [join5(process.env.GEMINI_CLI_HOME || home, ".gemini", "tmp"), join5(home, ".cache", ".gemini", "tmp")];
1273
+ const home = homedir3();
1274
+ if (source === "codex") return [join6(codexHome(), TRANSCRIPT_ROOT_NAME.codex)];
1275
+ if (source === "cursor") return [join6(home, ".cursor", TRANSCRIPT_ROOT_NAME.cursor)];
1276
+ if (source === "hermes") return [join6(home, ".pushary", TRANSCRIPT_ROOT_NAME.hermes)];
1277
+ if (source === "gemini") return [join6(process.env.GEMINI_CLI_HOME || home, ".gemini", "tmp"), join6(home, ".cache", ".gemini", "tmp")];
1181
1278
  const configured = process.env.CLAUDE_CONFIG_DIR;
1182
- return [join5(configured || join5(home, ".claude"), TRANSCRIPT_ROOT_NAME.claude), join5(home, ".claude", TRANSCRIPT_ROOT_NAME.claude)];
1279
+ return [join6(configured || join6(home, ".claude"), TRANSCRIPT_ROOT_NAME.claude), join6(home, ".claude", TRANSCRIPT_ROOT_NAME.claude)];
1183
1280
  };
1184
1281
  var isAgentTranscriptRoot = (root, source) => isAbsolute(root) && resolve2(root) === root && basename(root) === TRANSCRIPT_ROOT_NAME[source];
1185
1282
  var acceptedTranscriptRoots = (source, registeredRoot) => typeof registeredRoot === "string" && isAgentTranscriptRoot(registeredRoot, source) ? [...transcriptRoots(source), registeredRoot] : transcriptRoots(source);
@@ -1188,8 +1285,8 @@ var resolvedSourcePath = (path) => {
1188
1285
  try {
1189
1286
  return realpathSync(absolute);
1190
1287
  } catch {
1191
- const parent = dirname2(absolute);
1192
- return parent === absolute ? absolute : join5(resolvedSourcePath(parent), basename(absolute));
1288
+ const parent = dirname3(absolute);
1289
+ return parent === absolute ? absolute : join6(resolvedSourcePath(parent), basename(absolute));
1193
1290
  }
1194
1291
  };
1195
1292
  var transcriptRootContaining = (candidate, roots) => {
@@ -1209,9 +1306,15 @@ var captureRegistration = (source, value, registeredRoot) => {
1209
1306
  const segments = relative(root, path).split(sep);
1210
1307
  if (source === "hermes" && (segments.length !== 2 || !/^[a-f0-9]{64}$/.test(segments[0] ?? "") || basename(path) !== `${sessionId}.json`)) return null;
1211
1308
  if (source === "gemini" && (segments.length !== 3 || segments[1] !== "chats" || !basename(path).startsWith("session-"))) return null;
1212
- if (source === "cursor" && (segments[1] !== "agent-transcripts" || basename(path) !== `${sessionId}.jsonl` || !(segments.length === 3 || segments.length === 4 && basename(dirname2(path)) === sessionId))) return null;
1309
+ if (source === "cursor" && (segments[1] !== "agent-transcripts" || basename(path) !== `${sessionId}.jsonl` || !(segments.length === 3 || segments.length === 4 && basename(dirname3(path)) === sessionId))) return null;
1213
1310
  return { sessionId, cwd: input.cwd, path, source, root };
1214
1311
  };
1312
+ var SESSION_END_EVENT = "SessionEnd";
1313
+ var closesSession = (source, input) => {
1314
+ const event = input.hook_event_name;
1315
+ if (typeof event !== "string") return false;
1316
+ return event === SESSION_END_EVENT || isHookSource(source) && hookMeaning(source, event)?.kind === "session_closed";
1317
+ };
1215
1318
  var registerTranscript = (source, input, startDaemon = () => {
1216
1319
  void ensureDaemonRunning({ waitTimeoutMs: 0 }).catch(() => {
1217
1320
  });
@@ -1232,7 +1335,7 @@ var registerTranscript = (source, input, startDaemon = () => {
1232
1335
  return;
1233
1336
  }
1234
1337
  if (source === "claude" && !options.siteId && !previous?.expectedSiteId && macOwnsClaudeHooks(registration.cwd)) return;
1235
- const ending = options.ended || input.hook_event_name === "SessionEnd" && process.env.PUSHARY_WRAPPER_ACTIVE !== "1";
1338
+ const ending = options.ended || closesSession(source, input) && process.env.PUSHARY_WRAPPER_ACTIVE !== "1";
1236
1339
  const stored = {
1237
1340
  ...registration,
1238
1341
  path: previous?.account === account ? previous.path : registration.path,
@@ -1263,8 +1366,8 @@ var sightRegisteredTranscripts = (epoch, registry, listing) => {
1263
1366
  };
1264
1367
  var startRegisteredTranscripts = (apiKey, machineId, options = {}) => {
1265
1368
  const { intervalMs = 3e3, enabled = () => true, storage } = options;
1266
- const epoch = options.epoch ?? startTranscriptCaptureEpoch(Date.now(), void 0, SESSION_HISTORY_BACKFILL);
1267
1369
  const registry = { apiKey, baseUrl: options.baseUrl ?? getBaseUrl(), directory: options.registryDirectory ?? defaultRegistryDirectory() };
1370
+ const epoch = options.epoch ?? startTranscriptCaptureEpoch(Date.now(), savedTranscriptReadPositions(registeredReadPositionsFile(registry)), SESSION_HISTORY_BACKFILL);
1268
1371
  const active = /* @__PURE__ */ new Map();
1269
1372
  let stopped = false;
1270
1373
  let scanning = false;
@@ -1277,7 +1380,7 @@ var startRegisteredTranscripts = (apiKey, machineId, options = {}) => {
1277
1380
  try {
1278
1381
  let unreadable = 0;
1279
1382
  const files = readdirSync2(registry.directory).filter((name) => name.endsWith(".json")).flatMap((name) => {
1280
- const path = join5(registry.directory, name);
1383
+ const path = join6(registry.directory, name);
1281
1384
  try {
1282
1385
  const time = statSync3(path).mtimeMs;
1283
1386
  if (Date.now() - time > TTL) {
@@ -1326,10 +1429,9 @@ var startRegisteredTranscripts = (apiKey, machineId, options = {}) => {
1326
1429
  for (const [id, registration] of wanted) {
1327
1430
  if (active.has(id)) continue;
1328
1431
  const current = () => read(registration.registrationPath);
1329
- const snapshotKeys = join5(registry.directory, "snapshot-keys", accountFor(registry));
1330
1432
  const keyStorage = storage ?? (registration.source === "claude" || registration.source === "codex" ? void 0 : {
1331
- sessionKeyDirectory: snapshotKeys,
1332
- recipientPinFile: join5(snapshotKeys, "recipients.json")
1433
+ sessionKeyDirectory: snapshotKeyDirectory(registry),
1434
+ recipientPinFile: snapshotRecipientPinFile(registry)
1333
1435
  });
1334
1436
  active.set(id, { path: registration.path, stop: startTranscriptSync({
1335
1437
  apiKey,
@@ -1381,7 +1483,11 @@ export {
1381
1483
  sessionKeyDirectory,
1382
1484
  loadSessionKey,
1383
1485
  startDraftPublisher,
1486
+ loadPin,
1487
+ clearPin,
1488
+ fingerprint,
1384
1489
  claudeTranscriptPath,
1490
+ clearSnapshotRecipientPins,
1385
1491
  registeredTranscriptEnabled,
1386
1492
  captureRegistration,
1387
1493
  registerTranscript,
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  keyCheckFromResponse
3
- } from "./chunk-VCMDY6YL.js";
3
+ } from "./chunk-BUS7MXEE.js";
4
4
  import {
5
5
  installNetworkDefaults
6
- } from "./chunk-NDLOWIYO.js";
6
+ } from "./chunk-JJCMQRBF.js";
7
7
  import {
8
8
  getBaseUrl
9
- } from "./chunk-TBU4WXA4.js";
9
+ } from "./chunk-JSZT4Q23.js";
10
10
  import {
11
11
  isRecord,
12
12
  isToolErrorResult,
13
13
  toolFailureCodeOfResult
14
- } from "./chunk-L4THAI7Q.js";
14
+ } from "./chunk-JHWOM55B.js";
15
15
 
16
16
  // src/retry.ts
17
17
  var isRetryable = (err) => {
@@ -22,22 +22,22 @@ import {
22
22
  turnCodexAppCardsOff,
23
23
  turnCodexAppCardsOn,
24
24
  whyLaunchctlFailed
25
- } from "./chunk-XHHX63PY.js";
26
- import "./chunk-TMBLBDPB.js";
25
+ } from "./chunk-OSEGZLCO.js";
26
+ import "./chunk-FNC4SPOD.js";
27
27
  import "./chunk-XCEN33UP.js";
28
28
  import "./chunk-QCGNGEGE.js";
29
- import "./chunk-6CJ4MSZU.js";
29
+ import "./chunk-SAPRO7FI.js";
30
30
  import "./chunk-XHKBHWLX.js";
31
- import "./chunk-IBULUTHA.js";
31
+ import "./chunk-FRPR4OTH.js";
32
32
  import "./chunk-E46NE7FB.js";
33
- import "./chunk-JIC5PGNI.js";
34
- import "./chunk-FEF3ILT6.js";
35
- import "./chunk-B2RDWRKR.js";
36
- import "./chunk-YIAJOV2X.js";
37
- import "./chunk-TBU4WXA4.js";
38
- import "./chunk-2KVELJZX.js";
33
+ import "./chunk-V4JZHAOY.js";
34
+ import "./chunk-UGELL4RB.js";
35
+ import "./chunk-PHBZK4SC.js";
36
+ import "./chunk-64XK7DLE.js";
37
+ import "./chunk-JSZT4Q23.js";
38
+ import "./chunk-GGGOFJBL.js";
39
39
  import "./chunk-ZVU6WMMU.js";
40
- import "./chunk-L4THAI7Q.js";
40
+ import "./chunk-JHWOM55B.js";
41
41
  import "./chunk-MLKGABMK.js";
42
42
  export {
43
43
  CODEX_APP_CARDS_DIRECTORY,
@@ -11,7 +11,7 @@ import {
11
11
  installedCodexApp,
12
12
  shellQuoted,
13
13
  writeDesktopProxy
14
- } from "./chunk-TMBLBDPB.js";
14
+ } from "./chunk-FNC4SPOD.js";
15
15
  import "./chunk-XCEN33UP.js";
16
16
  import {
17
17
  CODEX_APP_LAUNCH_VARIABLE