@pushary/agent-hooks 1.4.1 → 1.5.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 (92) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +27 -0
  3. package/data/vscode-plugin/README.md +1 -1
  4. package/data/vscode-plugin/scripts/pushary-gate.mjs +2 -2
  5. package/dist/bin/pushary-bell-hook.js +22 -21
  6. package/dist/bin/pushary-bell.js +10 -10
  7. package/dist/bin/pushary-claude.js +28 -24
  8. package/dist/bin/pushary-clean.js +30 -26
  9. package/dist/bin/pushary-codex-bridge.js +16 -14
  10. package/dist/bin/pushary-codex-hook.js +41 -31
  11. package/dist/bin/pushary-codex.js +15 -10
  12. package/dist/bin/pushary-connect.js +11 -11
  13. package/dist/bin/pushary-cowork.js +6 -6
  14. package/dist/bin/pushary-daemon.js +31 -28
  15. package/dist/bin/pushary-disconnect.js +16 -16
  16. package/dist/bin/pushary-doctor.js +81 -38
  17. package/dist/bin/pushary-elicitation-hook.js +23 -22
  18. package/dist/bin/pushary-gemini-bridge.js +13 -11
  19. package/dist/bin/pushary-gemini-hook.js +29 -24
  20. package/dist/bin/pushary-hook.js +30 -30
  21. package/dist/bin/pushary-login.js +14 -14
  22. package/dist/bin/pushary-logout.js +8 -8
  23. package/dist/bin/pushary-mode.js +7 -7
  24. package/dist/bin/pushary-notification-hook.js +26 -25
  25. package/dist/bin/pushary-opencode-hook.js +25 -24
  26. package/dist/bin/pushary-permission-denied-hook.js +30 -29
  27. package/dist/bin/pushary-permission-hook.js +29 -28
  28. package/dist/bin/pushary-post-hook.js +26 -25
  29. package/dist/bin/pushary-prompt-hook.js +26 -25
  30. package/dist/bin/pushary-session-end-hook.js +26 -25
  31. package/dist/bin/pushary-session-start-hook.js +32 -27
  32. package/dist/bin/pushary-setup.js +85 -59
  33. package/dist/bin/pushary-stats.js +6 -6
  34. package/dist/bin/pushary-status.js +15 -15
  35. package/dist/bin/pushary-stop-hook.js +26 -25
  36. package/dist/bin/pushary-stopfailure-hook.js +26 -25
  37. package/dist/bin/pushary-suggestions.js +4 -4
  38. package/dist/bin/pushary-transcript-register.js +20 -19
  39. package/dist/bin/pushary-transcripts.js +8 -8
  40. package/dist/bin/pushary-upgrade.js +231 -37
  41. package/dist/bin/pushary-wait.js +7 -7
  42. package/dist/bin/pushary.js +8 -8
  43. package/dist/{chunk-MN3XOVRK.js → chunk-2QT3GCU4.js} +1 -1
  44. package/dist/{chunk-LUT2EZLG.js → chunk-3NBODGQS.js} +1 -1
  45. package/dist/{chunk-43JKGLZZ.js → chunk-3ZSGKLSO.js} +2 -2
  46. package/dist/{chunk-QBS6LGEK.js → chunk-43LJSM4F.js} +2 -2
  47. package/dist/{chunk-SWFF5U2N.js → chunk-43ZDACBO.js} +1 -1
  48. package/dist/{chunk-HK3IXIQJ.js → chunk-5HYNICS7.js} +1 -1
  49. package/dist/{chunk-EQRS3SGM.js → chunk-66H2QQAK.js} +1 -1
  50. package/dist/{chunk-3BPB2HYZ.js → chunk-7XT76LWT.js} +7 -7
  51. package/dist/{chunk-ALFT7H5B.js → chunk-CQYHOHOK.js} +56 -5
  52. package/dist/{chunk-3UA6FPRC.js → chunk-DLJN5XEU.js} +3 -3
  53. package/dist/{chunk-BZBUPZC6.js → chunk-DTQNDR7C.js} +1 -1
  54. package/dist/{chunk-SAF6NNXY.js → chunk-DYHXOXUF.js} +43 -6
  55. package/dist/{chunk-FAH3D74E.js → chunk-EA3IELHP.js} +6 -0
  56. package/dist/{chunk-ED5TA2FJ.js → chunk-EADZPVYW.js} +3 -3
  57. package/dist/{chunk-I6HRQOMT.js → chunk-F57RGL7K.js} +8 -8
  58. package/dist/{chunk-LNGYW6G4.js → chunk-FDHMNT24.js} +20 -16
  59. package/dist/{chunk-37VLIYLI.js → chunk-H5LHTC5X.js} +1 -1
  60. package/dist/{chunk-EYRGBYZG.js → chunk-HETOKNIL.js} +1 -1
  61. package/dist/{chunk-K6I5M2ME.js → chunk-HU5LSYL2.js} +2 -2
  62. package/dist/{chunk-SKXLIVFM.js → chunk-HVBF35GT.js} +2 -2
  63. package/dist/{chunk-DINDL2CF.js → chunk-HWJW3CPO.js} +25 -5
  64. package/dist/{chunk-GOFDGTEI.js → chunk-IYTQ4B5I.js} +18 -45
  65. package/dist/{chunk-WIOXWUUH.js → chunk-J4J45VPZ.js} +3 -3
  66. package/dist/{chunk-HQLAZWJJ.js → chunk-JF736N4C.js} +5 -5
  67. package/dist/{chunk-LYXX5NSB.js → chunk-K3QVDAZW.js} +1 -1
  68. package/dist/{chunk-KI36MAT6.js → chunk-KEOLNHR3.js} +2 -2
  69. package/dist/{chunk-S3EP4B35.js → chunk-KJRALILH.js} +28 -11
  70. package/dist/{chunk-PHHGHHOW.js → chunk-MYP4UUFH.js} +1 -1
  71. package/dist/{chunk-TNS3YLFE.js → chunk-NFKVRMTM.js} +8 -8
  72. package/dist/{chunk-TF4IOINR.js → chunk-NTQSICPJ.js} +3 -3
  73. package/dist/{chunk-4FN6VV56.js → chunk-ORLJNJEO.js} +2 -2
  74. package/dist/{chunk-2UMNXADU.js → chunk-OSJEMXSR.js} +5 -1
  75. package/dist/chunk-OSSDK5RS.js +162 -0
  76. package/dist/{chunk-TWWLVOPB.js → chunk-P4BNYJ5Q.js} +5 -5
  77. package/dist/{chunk-KEMEBTCJ.js → chunk-PCGZXWGQ.js} +4 -4
  78. package/dist/{chunk-2GMI6JH6.js → chunk-PNNBMH4E.js} +5 -5
  79. package/dist/{chunk-LGXUGYUH.js → chunk-PYCQXCI5.js} +2 -2
  80. package/dist/{chunk-JOVWYVSR.js → chunk-SOCEY746.js} +1 -1
  81. package/dist/{chunk-FVKFDTN6.js → chunk-T4QY64OR.js} +19 -14
  82. package/dist/{chunk-R3AMKNIW.js → chunk-TFKBFQCE.js} +1 -1
  83. package/dist/{chunk-CRNAXFQ6.js → chunk-TIWURSLS.js} +1 -1
  84. package/dist/{chunk-VYUDGQM7.js → chunk-TUXFIVOH.js} +1 -1
  85. package/dist/{chunk-3T52B2OF.js → chunk-UQHUUZ5H.js} +1 -1
  86. package/dist/{chunk-TI3ZWXZG.js → chunk-USQDVBEV.js} +2 -2
  87. package/dist/{chunk-WEO5JCB4.js → chunk-UYDTFCHW.js} +1 -1
  88. package/dist/{chunk-D7ERHWYB.js → chunk-XWEONSLV.js} +1 -1
  89. package/dist/{chunk-GKIUEIDX.js → chunk-YQMFGWBD.js} +1 -1
  90. package/dist/{reapply-BAWDJTG7.js → reapply-D2TFN6XK.js} +9 -8
  91. package/dist/src/index.js +18 -16
  92. package/package.json +1 -1
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  CLAUDE_HOOK_EVENTS,
3
3
  supportedClaudeEvents
4
- } from "./chunk-ED5TA2FJ.js";
4
+ } from "./chunk-EADZPVYW.js";
5
5
  import {
6
6
  guardBinary,
7
7
  holdBudgetOf,
8
8
  isProtectedByScope,
9
9
  registerHookEntry
10
- } from "./chunk-SAF6NNXY.js";
10
+ } from "./chunk-DYHXOXUF.js";
11
11
  import {
12
12
  HOOK_LOCATOR_BINARY,
13
13
  withHookHoldBudget
14
- } from "./chunk-FVKFDTN6.js";
14
+ } from "./chunk-T4QY64OR.js";
15
15
 
16
16
  // src/claude-config.ts
17
17
  import { join } from "path";
@@ -3,28 +3,28 @@ import {
3
3
  addPusharyToolPermissions,
4
4
  isPusharyHook,
5
5
  removeClaudeMcpServers
6
- } from "./chunk-WIOXWUUH.js";
6
+ } from "./chunk-J4J45VPZ.js";
7
7
  import {
8
8
  CLAUDE_HOOK_EVENTS,
9
9
  addGeminiMcpServer,
10
10
  removeGeminiMcpServer
11
- } from "./chunk-ED5TA2FJ.js";
11
+ } from "./chunk-EADZPVYW.js";
12
12
  import {
13
13
  CLAUDE_CODE_AGENT,
14
14
  parseApplyPatchFiles
15
- } from "./chunk-LNGYW6G4.js";
15
+ } from "./chunk-FDHMNT24.js";
16
16
  import {
17
17
  guardBinary,
18
18
  holdBudgetOf,
19
19
  registerHookEntry
20
- } from "./chunk-SAF6NNXY.js";
20
+ } from "./chunk-DYHXOXUF.js";
21
21
  import {
22
22
  PHONE_ANSWERED_TOOLS,
23
23
  hookCompatibleProfile,
24
24
  hookCompatibleProfileBySource,
25
25
  toToolLookup,
26
26
  withHookHoldBudget
27
- } from "./chunk-FVKFDTN6.js";
27
+ } from "./chunk-T4QY64OR.js";
28
28
 
29
29
  // src/compatible-config.ts
30
30
  import { homedir } from "os";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HOOK_LOCATOR_BINARY
3
- } from "./chunk-FVKFDTN6.js";
3
+ } from "./chunk-T4QY64OR.js";
4
4
 
5
5
  // src/diagnostics/bridge.ts
6
6
  import { execFileSync } from "child_process";
@@ -2,10 +2,10 @@ import {
2
2
  resolveBinary,
3
3
  resolveGlobalPackageVersion,
4
4
  resolvePackageVersionFromBinary
5
- } from "./chunk-SAF6NNXY.js";
5
+ } from "./chunk-DYHXOXUF.js";
6
6
  import {
7
7
  MANAGED_PROVIDERS
8
- } from "./chunk-FVKFDTN6.js";
8
+ } from "./chunk-T4QY64OR.js";
9
9
 
10
10
  // src/live-capabilities.ts
11
11
  var CLAUDE_BRIDGE_CAPABILITY = "claude-bridge";
@@ -12,13 +12,17 @@ import {
12
12
  } from "./chunk-5RUIFDTP.js";
13
13
  import {
14
14
  callMcpTool
15
- } from "./chunk-EYRGBYZG.js";
15
+ } from "./chunk-HETOKNIL.js";
16
16
  import {
17
17
  reportedInstallSource
18
- } from "./chunk-K6I5M2ME.js";
18
+ } from "./chunk-HU5LSYL2.js";
19
19
  import {
20
+ PAIR_TTL_SECONDS,
20
21
  isAnswerSource
21
- } from "./chunk-FVKFDTN6.js";
22
+ } from "./chunk-T4QY64OR.js";
23
+ import {
24
+ NPX_LATEST_COMMAND
25
+ } from "./chunk-EA3IELHP.js";
22
26
 
23
27
  // src/reach.ts
24
28
  var reachVerdict = (channels) => {
@@ -747,8 +751,13 @@ var printConnectInstructions = async (apiKey) => {
747
751
  return phoneFailure("no_device");
748
752
  };
749
753
  var PAIR_POLL_INTERVAL_MS = 2e3;
750
- var PAIR_TIMEOUT_MS = 9e5;
754
+ var PAIR_STOP_BEFORE_EXPIRY_MS = 1e4;
755
+ var PAIR_TIMEOUT_MS = PAIR_TTL_SECONDS * 1e3 - PAIR_STOP_BEFORE_EXPIRY_MS;
751
756
  var PAIR_HINT_AFTER_MS = 45e3;
757
+ var PAIR_BROWSER_FALLBACK_AFTER_MS = 6e4;
758
+ var BROWSER_CONNECT_COMMAND = `${NPX_LATEST_COMMAND} setup --connect browser`;
759
+ var PAIR_BROWSER_FALLBACK_LINE = `Still waiting? Sign in with a browser instead: Ctrl-C, then ${BROWSER_CONNECT_COMMAND}`;
760
+ var SYSTEM_PAIR_CLOCK = { now: () => Date.now(), sleep };
752
761
  var startPairing = async (cliPublicKey) => {
753
762
  try {
754
763
  const res = await fetch(`${apiBase()}/api/mobile/pair/start`, {
@@ -837,7 +846,9 @@ var buildPairLinks = (pairId, publicKeyB64, baseUrl = apiBase(), code = null) =>
837
846
  };
838
847
  };
839
848
  var connectViaAppPairing = async (options = {}) => {
849
+ const clock = options.clock ?? SYSTEM_PAIR_CLOCK;
840
850
  const keypair = generateKeypair();
851
+ const requestedAt = clock.now();
841
852
  const started = await startPairing(keypair.publicKeyB64);
842
853
  if (!started) {
843
854
  console.log(` ${yellow("!")} Couldn't start pairing. Check your connection and try again.`);
@@ -854,12 +865,13 @@ var connectViaAppPairing = async (options = {}) => {
854
865
  console.log(` ${dim("Confirm the app shows fingerprint")} ${cyan(publicKeyFingerprint(keypair.publicKeyB64))}`);
855
866
  console.log(` ${dim("Already have the app and it opened a browser? Use")} ${cyan(deepLink)}`);
856
867
  console.log();
857
- const startedAt = Date.now();
858
- const deadline = startedAt + PAIR_TIMEOUT_MS;
868
+ const startedAt = clock.now();
869
+ const deadline = requestedAt + PAIR_TIMEOUT_MS;
859
870
  let hintShown = false;
871
+ let browserFallbackShown = false;
860
872
  const stop = startSpinner(() => {
861
- const left = Math.max(0, Math.ceil((deadline - Date.now()) / 6e4));
862
- if (Date.now() - startedAt < PAIR_HINT_AFTER_MS) {
873
+ const left = Math.max(0, Math.ceil((deadline - clock.now()) / 6e4));
874
+ if (clock.now() - startedAt < PAIR_HINT_AFTER_MS) {
863
875
  return "Waiting for the app to authorize";
864
876
  }
865
877
  if (!hintShown) {
@@ -880,8 +892,12 @@ var connectViaAppPairing = async (options = {}) => {
880
892
  process.once("SIGINT", onInterrupt);
881
893
  let consecutiveFailures = 0;
882
894
  try {
883
- while (Date.now() < deadline) {
895
+ while (clock.now() < deadline) {
884
896
  if (cancelled) return pairFailed("cancelled");
897
+ if (!browserFallbackShown && clock.now() - startedAt >= PAIR_BROWSER_FALLBACK_AFTER_MS) {
898
+ browserFallbackShown = true;
899
+ writeStatusLine(dim(PAIR_BROWSER_FALLBACK_LINE));
900
+ }
885
901
  const claim = await claimPairing(pairId);
886
902
  if (claim === null) {
887
903
  consecutiveFailures += 1;
@@ -890,7 +906,7 @@ var connectViaAppPairing = async (options = {}) => {
890
906
  await cancelPairing(pairId);
891
907
  return pairFailed("unreachable");
892
908
  }
893
- await sleep(PAIR_POLL_INTERVAL_MS);
909
+ await clock.sleep(PAIR_POLL_INTERVAL_MS);
894
910
  continue;
895
911
  }
896
912
  consecutiveFailures = 0;
@@ -915,7 +931,7 @@ var connectViaAppPairing = async (options = {}) => {
915
931
  stop(yellow("!"), describePairFailure(claim.reason));
916
932
  return pairFailed("rejected");
917
933
  }
918
- await sleep(PAIR_POLL_INTERVAL_MS);
934
+ await clock.sleep(PAIR_POLL_INTERVAL_MS);
919
935
  }
920
936
  stop(yellow("!"), "Timed out waiting for the app");
921
937
  await cancelPairing(pairId);
@@ -940,6 +956,7 @@ export {
940
956
  confirmAppConnection,
941
957
  connectExistingApp,
942
958
  printConnectInstructions,
959
+ BROWSER_CONNECT_COMMAND,
943
960
  pairingEscapeApplies,
944
961
  connectViaAppPairing
945
962
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-SAF6NNXY.js";
3
+ } from "./chunk-DYHXOXUF.js";
4
4
  import {
5
5
  readJsonSafe
6
6
  } from "./chunk-T7E75EKA.js";
@@ -6,38 +6,38 @@ import {
6
6
  } from "./chunk-SGZJ5LYH.js";
7
7
  import {
8
8
  hookOwnerOf
9
- } from "./chunk-KEMEBTCJ.js";
9
+ } from "./chunk-PCGZXWGQ.js";
10
10
  import {
11
11
  ensureDaemonRunning
12
- } from "./chunk-3BPB2HYZ.js";
12
+ } from "./chunk-7XT76LWT.js";
13
13
  import {
14
14
  buildTranscriptRecords,
15
15
  decodePublicKey,
16
16
  generateSessionKey,
17
17
  wrapSessionKey
18
- } from "./chunk-CRNAXFQ6.js";
18
+ } from "./chunk-TIWURSLS.js";
19
19
  import {
20
20
  fetchTranscriptRecipients,
21
21
  uploadTranscriptRecords
22
- } from "./chunk-EQRS3SGM.js";
22
+ } from "./chunk-66H2QQAK.js";
23
23
  import {
24
24
  transcriptEnvironmentPreference,
25
25
  transcriptsEnabled
26
- } from "./chunk-MN3XOVRK.js";
26
+ } from "./chunk-2QT3GCU4.js";
27
27
  import {
28
28
  codexHome,
29
29
  pusharyDir
30
- } from "./chunk-SAF6NNXY.js";
30
+ } from "./chunk-DYHXOXUF.js";
31
31
  import {
32
32
  readTranscriptPreference
33
- } from "./chunk-TI3ZWXZG.js";
33
+ } from "./chunk-USQDVBEV.js";
34
34
  import {
35
35
  writeJsonAtomic
36
36
  } from "./chunk-T7E75EKA.js";
37
37
  import {
38
38
  getApiKey,
39
39
  getBaseUrl
40
- } from "./chunk-2UMNXADU.js";
40
+ } from "./chunk-OSJEMXSR.js";
41
41
 
42
42
  // src/transcript-registration.ts
43
43
  import { createHash } from "crypto";
@@ -2,17 +2,17 @@ import {
2
2
  CLAUDE_HOOK_EVENTS,
3
3
  GEMINI_HOOK_EVENTS,
4
4
  hasGeminiHooks
5
- } from "./chunk-ED5TA2FJ.js";
5
+ } from "./chunk-EADZPVYW.js";
6
6
  import {
7
7
  CODEX_HOOK_EVENTS,
8
8
  hasCodexHooks,
9
9
  holdBudgetOf
10
- } from "./chunk-SAF6NNXY.js";
10
+ } from "./chunk-DYHXOXUF.js";
11
11
  import {
12
12
  CURSOR_GATE_EVENTS,
13
13
  HOOK_LOCATOR_BINARY,
14
14
  hookCommandHoldBudget
15
- } from "./chunk-FVKFDTN6.js";
15
+ } from "./chunk-T4QY64OR.js";
16
16
 
17
17
  // src/diagnostics/wiring.ts
18
18
  var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  registerTranscript
3
- } from "./chunk-TNS3YLFE.js";
3
+ } from "./chunk-NFKVRMTM.js";
4
4
  import {
5
5
  degradedLine
6
- } from "./chunk-FVKFDTN6.js";
6
+ } from "./chunk-T4QY64OR.js";
7
7
 
8
8
  // src/tool-hook-input.ts
9
9
  var OPTIONAL_TEXT_FIELDS = ["hook_event_name", "session_id", "cwd", "transcript_path", "tool_use_id", "permission_mode"];
@@ -1,3 +1,7 @@
1
+ import {
2
+ NPX_LATEST_COMMAND
3
+ } from "./chunk-EA3IELHP.js";
4
+
1
5
  // src/config.ts
2
6
  import { readFileSync } from "fs";
3
7
  import { join } from "path";
@@ -33,7 +37,7 @@ var getApiKey = () => {
33
37
  const fileKey = readKeyFromConfigFile();
34
38
  if (fileKey) return fileKey;
35
39
  throw new Error(
36
- "PUSHARY_API_KEY is not set and no key was found in ~/.pushary/config.json. Run `npx @pushary/agent-hooks setup`, or get your API key at https://pushary.com/sign-up?from=ai-coding"
40
+ `PUSHARY_API_KEY is not set and no key was found in ~/.pushary/config.json. Run \`${NPX_LATEST_COMMAND} setup\`, or get your API key at https://pushary.com/sign-up?from=ai-coding`
37
41
  );
38
42
  };
39
43
  var getBaseUrl = () => process.env.PUSHARY_BASE_URL?.trim() || process.env.PUSHARY_API_URL?.trim() || "https://pushary.com";
@@ -0,0 +1,162 @@
1
+ import {
2
+ autoUpdateState
3
+ } from "./chunk-DYHXOXUF.js";
4
+ import {
5
+ readJsonSafe,
6
+ writeJsonAtomic
7
+ } from "./chunk-T7E75EKA.js";
8
+ import {
9
+ ownPackageRoot
10
+ } from "./chunk-HWJW3CPO.js";
11
+
12
+ // src/auto-update.ts
13
+ import { spawn } from "child_process";
14
+ import { dirname, join } from "path";
15
+ var AUTO_UPDATE_DISABLE_ENV = "PUSHARY_DISABLE_AUTOUPDATE";
16
+ var AUTO_UPDATE_INTERVAL_MS = 24 * 60 * 60 * 1e3;
17
+ var AUTO_UPDATE_FLAG = "--auto";
18
+ var GLOBAL_PACKAGE_SUBPATH = "/lib/node_modules/@pushary/agent-hooks";
19
+ var UPGRADE_ENTRY_SUBPATH = ["dist", "bin", "pushary-upgrade.js"];
20
+ var NON_GLOBAL_INSTALL_SEGMENTS = ["/_npx/", "/.volta/"];
21
+ var NOT_DISABLED_VALUES = /* @__PURE__ */ new Set(["", "0"]);
22
+ var AUTO_UPDATE_RESULTS = ["updated", "current", "needs_manual", "failed"];
23
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24
+ var isAutoUpdateResult = (value) => typeof value === "string" && AUTO_UPDATE_RESULTS.some((result) => result === value);
25
+ var stringField = (record, key) => {
26
+ const value = record[key];
27
+ return typeof value === "string" ? value : void 0;
28
+ };
29
+ var booleanField = (record, key) => {
30
+ const value = record[key];
31
+ return typeof value === "boolean" ? value : void 0;
32
+ };
33
+ var parseAutoUpdateState = (value) => {
34
+ if (!isRecord(value)) return {};
35
+ return {
36
+ disabled: booleanField(value, "disabled"),
37
+ lastCheckAt: stringField(value, "lastCheckAt"),
38
+ lastResult: isAutoUpdateResult(value.lastResult) ? value.lastResult : void 0,
39
+ from: stringField(value, "from"),
40
+ to: stringField(value, "to"),
41
+ at: stringField(value, "at"),
42
+ detail: stringField(value, "detail"),
43
+ announced: booleanField(value, "announced")
44
+ };
45
+ };
46
+ var isAutoUpdateDisabledByEnv = (env) => {
47
+ const value = env[AUTO_UPDATE_DISABLE_ENV];
48
+ return value !== void 0 && !NOT_DISABLED_VALUES.has(value.trim());
49
+ };
50
+ var isContinuousIntegration = (env) => Boolean(env.CI);
51
+ var autoUpdateOffReason = (input) => {
52
+ if (isAutoUpdateDisabledByEnv(input.env)) return "disabled_by_env";
53
+ if (input.state.disabled === true) return "disabled_by_user";
54
+ if (isContinuousIntegration(input.env)) return "ci";
55
+ if (input.platform === "win32") return "windows";
56
+ return null;
57
+ };
58
+ var globalInstallPrefix = (packageRoot) => {
59
+ const root = packageRoot.replace(/\/+$/, "");
60
+ if (!root.endsWith(GLOBAL_PACKAGE_SUBPATH)) return null;
61
+ if (NON_GLOBAL_INSTALL_SEGMENTS.some((segment) => root.includes(segment))) return null;
62
+ const prefix = root.slice(0, -GLOBAL_PACKAGE_SUBPATH.length);
63
+ return prefix.startsWith("/") ? prefix : null;
64
+ };
65
+ var upgradeEntryFor = (prefix) => join(prefix, GLOBAL_PACKAGE_SUBPATH, ...UPGRADE_ENTRY_SUBPATH);
66
+ var checkedWithinInterval = (lastCheckAt, now) => {
67
+ const last = lastCheckAt === void 0 ? Number.NaN : Date.parse(lastCheckAt);
68
+ if (Number.isNaN(last)) return false;
69
+ const elapsed = now - last;
70
+ return elapsed >= 0 && elapsed < AUTO_UPDATE_INTERVAL_MS;
71
+ };
72
+ var autoUpdateDecision = (input) => {
73
+ if (input.isSubagentStart) return { kind: "skip", reason: "subagent_start" };
74
+ const offReason = autoUpdateOffReason(input);
75
+ if (offReason !== null) return { kind: "skip", reason: offReason };
76
+ const prefix = input.packageRoot === void 0 ? null : globalInstallPrefix(input.packageRoot);
77
+ if (prefix === null) return { kind: "skip", reason: "not_global_install" };
78
+ if (checkedWithinInterval(input.state.lastCheckAt, input.now)) return { kind: "skip", reason: "checked_recently" };
79
+ return { kind: "check", prefix };
80
+ };
81
+ var parseAutoUpdateFlag = (args) => {
82
+ const token = args.find((arg) => arg === AUTO_UPDATE_FLAG || arg.startsWith(`${AUTO_UPDATE_FLAG}=`));
83
+ if (token === void 0) return { kind: "absent" };
84
+ if (token === AUTO_UPDATE_FLAG) return { kind: "run" };
85
+ const value = token.slice(AUTO_UPDATE_FLAG.length + 1);
86
+ if (value === "on") return { kind: "set", enabled: true };
87
+ if (value === "off") return { kind: "set", enabled: false };
88
+ return { kind: "invalid", value };
89
+ };
90
+ var AUTO_UPDATE_RESULT_LABELS = {
91
+ updated: "updated",
92
+ current: "up to date",
93
+ needs_manual: "needs a manual upgrade",
94
+ failed: "failed"
95
+ };
96
+ var versionsOf = (state) => state.from && state.to ? `${state.from} to ${state.to}` : state.from;
97
+ var describeAutoUpdateCheck = (state) => {
98
+ const label = state.lastResult ? AUTO_UPDATE_RESULT_LABELS[state.lastResult] : "no result recorded";
99
+ return [label, versionsOf(state), state.detail].filter(Boolean).join(", ");
100
+ };
101
+ var pendingAutoUpdateAnnouncement = (state) => state.lastResult === "updated" && state.announced !== true && state.from && state.to ? { from: state.from, to: state.to } : null;
102
+ var describeAutoUpdateAnnouncement = (announcement) => `Pushary updated itself from ${announcement.from} to ${announcement.to}.`;
103
+ var takeAutoUpdateAnnouncement = (statePath, markAnnounced) => {
104
+ try {
105
+ const announcement = pendingAutoUpdateAnnouncement(readAutoUpdateState(statePath));
106
+ if (announcement && markAnnounced) updateAutoUpdateState(statePath, { announced: true });
107
+ return announcement;
108
+ } catch {
109
+ return null;
110
+ }
111
+ };
112
+ var readAutoUpdateState = (statePath) => {
113
+ const read = readJsonSafe(statePath);
114
+ return read.kind === "ok" ? parseAutoUpdateState(read.value) : {};
115
+ };
116
+ var updateAutoUpdateState = (statePath, patch) => {
117
+ const next = { ...readAutoUpdateState(statePath), ...patch };
118
+ writeJsonAtomic(statePath, next);
119
+ return next;
120
+ };
121
+ var ignoreSpawnFailure = () => void 0;
122
+ var spawnDetached = (command, args, cwd) => {
123
+ const child = spawn(command, [...args], { cwd, detached: true, stdio: "ignore" });
124
+ child.on("error", ignoreSpawnFailure);
125
+ child.unref();
126
+ };
127
+ var triggerAutoUpdate = (trigger) => {
128
+ try {
129
+ const statePath = trigger.statePath ?? autoUpdateState();
130
+ const now = trigger.now ?? Date.now();
131
+ const decision = autoUpdateDecision({
132
+ env: trigger.env ?? process.env,
133
+ state: readAutoUpdateState(statePath),
134
+ now,
135
+ platform: trigger.platform ?? process.platform,
136
+ packageRoot: trigger.packageRoot ?? ownPackageRoot(),
137
+ isSubagentStart: trigger.isSubagentStart
138
+ });
139
+ if (decision.kind === "skip") return decision;
140
+ updateAutoUpdateState(statePath, { lastCheckAt: new Date(now).toISOString() });
141
+ const spawnUpgrade = trigger.spawn ?? spawnDetached;
142
+ spawnUpgrade(trigger.execPath ?? process.execPath, [upgradeEntryFor(decision.prefix), AUTO_UPDATE_FLAG], dirname(statePath));
143
+ return decision;
144
+ } catch {
145
+ return null;
146
+ }
147
+ };
148
+
149
+ export {
150
+ AUTO_UPDATE_DISABLE_ENV,
151
+ isAutoUpdateDisabledByEnv,
152
+ autoUpdateOffReason,
153
+ globalInstallPrefix,
154
+ upgradeEntryFor,
155
+ parseAutoUpdateFlag,
156
+ describeAutoUpdateCheck,
157
+ describeAutoUpdateAnnouncement,
158
+ takeAutoUpdateAnnouncement,
159
+ readAutoUpdateState,
160
+ updateAutoUpdateState,
161
+ triggerAutoUpdate
162
+ };
@@ -1,12 +1,12 @@
1
+ import {
2
+ EXIT
3
+ } from "./chunk-KZERVKTD.js";
1
4
  import {
2
5
  renderCommandHelp
3
- } from "./chunk-FAH3D74E.js";
6
+ } from "./chunk-EA3IELHP.js";
4
7
  import {
5
8
  getPackageVersion
6
- } from "./chunk-DINDL2CF.js";
7
- import {
8
- EXIT
9
- } from "./chunk-KZERVKTD.js";
9
+ } from "./chunk-HWJW3CPO.js";
10
10
 
11
11
  // src/cli/usage.ts
12
12
  var exitOnHelpFlag = (command) => {
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  AGENT_CHOICES
3
- } from "./chunk-R3AMKNIW.js";
3
+ } from "./chunk-TFKBFQCE.js";
4
4
  import {
5
5
  isBridgeLocator
6
- } from "./chunk-LYXX5NSB.js";
6
+ } from "./chunk-K3QVDAZW.js";
7
7
  import {
8
8
  pusharyHookExecutable
9
- } from "./chunk-TF4IOINR.js";
9
+ } from "./chunk-NTQSICPJ.js";
10
10
  import {
11
11
  BELL_HOOK_BINARY
12
- } from "./chunk-JOVWYVSR.js";
12
+ } from "./chunk-SOCEY746.js";
13
13
 
14
14
  // src/setup/hook-ownership.ts
15
15
  var commandsIn = (value) => {
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  detectClaudeVersion
3
- } from "./chunk-LUT2EZLG.js";
3
+ } from "./chunk-3NBODGQS.js";
4
4
  import {
5
5
  addClaudeMcpServer,
6
6
  addPusharyHooks,
7
7
  addPusharyToolPermissions
8
- } from "./chunk-WIOXWUUH.js";
8
+ } from "./chunk-J4J45VPZ.js";
9
9
  import {
10
10
  claudeUnprovenHolds,
11
11
  claudeWired,
12
12
  codexUnprovenHolds,
13
13
  codexWired,
14
14
  geminiWired
15
- } from "./chunk-TF4IOINR.js";
15
+ } from "./chunk-NTQSICPJ.js";
16
16
  import {
17
17
  CLAUDE_HOOK_BINARY,
18
18
  CLAUDE_HOOK_EVENTS,
@@ -24,7 +24,7 @@ import {
24
24
  needsReregistration,
25
25
  registrationSignatures,
26
26
  supportedClaudeEvents
27
- } from "./chunk-ED5TA2FJ.js";
27
+ } from "./chunk-EADZPVYW.js";
28
28
  import {
29
29
  CODEX_HOOK_BINARY,
30
30
  addCodexHookTrust,
@@ -44,7 +44,7 @@ import {
44
44
  registrationHolderOf,
45
45
  resolveGlobalBinary,
46
46
  vscodePluginMcp
47
- } from "./chunk-SAF6NNXY.js";
47
+ } from "./chunk-DYHXOXUF.js";
48
48
  import {
49
49
  readJsonSafe,
50
50
  writeFileAtomic,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  callMcpTool
3
- } from "./chunk-EYRGBYZG.js";
3
+ } from "./chunk-HETOKNIL.js";
4
4
  import {
5
5
  installProxyDispatcher
6
6
  } from "./chunk-SAF6HGAA.js";
7
7
  import {
8
8
  getBaseUrl
9
- } from "./chunk-2UMNXADU.js";
9
+ } from "./chunk-OSJEMXSR.js";
10
10
 
11
11
  // src/api.ts
12
12
  import { randomUUID } from "crypto";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  guardBinary
3
- } from "./chunk-SAF6NNXY.js";
3
+ } from "./chunk-DYHXOXUF.js";
4
4
 
5
5
  // src/bell/install.ts
6
6
  import { join } from "path";