@pushary/agent-hooks 1.4.2 → 1.5.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 (94) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +28 -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 +25 -25
  9. package/dist/bin/pushary-codex-bridge.js +16 -14
  10. package/dist/bin/pushary-codex-hook.js +32 -27
  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 +32 -28
  15. package/dist/bin/pushary-disconnect.js +16 -16
  16. package/dist/bin/pushary-doctor.js +111 -40
  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 +33 -27
  32. package/dist/bin/pushary-setup.js +94 -88
  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 +269 -45
  41. package/dist/bin/pushary-wait.js +7 -7
  42. package/dist/bin/pushary.js +8 -8
  43. package/dist/{chunk-LPYCPFBZ.js → chunk-2AUIEZYS.js} +3 -3
  44. package/dist/{chunk-4BROEAKH.js → chunk-2QT3GCU4.js} +1 -1
  45. package/dist/{chunk-55KW4FLG.js → chunk-3ZSGKLSO.js} +2 -2
  46. package/dist/{chunk-NY6XQ6CA.js → chunk-43LJSM4F.js} +2 -2
  47. package/dist/{chunk-LEAAERSQ.js → chunk-43ZDACBO.js} +1 -1
  48. package/dist/{chunk-II7PUMPB.js → chunk-4ERLRNOK.js} +3 -3
  49. package/dist/{chunk-M5CTUFF3.js → chunk-5HYNICS7.js} +1 -1
  50. package/dist/{chunk-MW6ZPC6R.js → chunk-5UQ5ATIE.js} +1 -1
  51. package/dist/{chunk-TYEO6T5J.js → chunk-5ZZG76S2.js} +2 -2
  52. package/dist/{chunk-EQRS3SGM.js → chunk-66H2QQAK.js} +1 -1
  53. package/dist/chunk-6EEANS74.js +300 -0
  54. package/dist/{chunk-TRLFZKVG.js → chunk-6IU45EHE.js} +49 -26
  55. package/dist/{chunk-JVTOML54.js → chunk-6QFEQIPM.js} +2 -2
  56. package/dist/chunk-BY2CRWBO.js +38 -0
  57. package/dist/{chunk-G653QPTR.js → chunk-D573TLP6.js} +7 -7
  58. package/dist/{chunk-25RTLTQD.js → chunk-DTQNDR7C.js} +1 -1
  59. package/dist/{chunk-FAH3D74E.js → chunk-EA3IELHP.js} +6 -0
  60. package/dist/{chunk-EYRGBYZG.js → chunk-HETOKNIL.js} +1 -1
  61. package/dist/{chunk-UM5J3J4V.js → chunk-HU5LSYL2.js} +2 -2
  62. package/dist/{chunk-PC6DU5C4.js → chunk-HUAOMX4U.js} +1 -1
  63. package/dist/{chunk-2V2IKOGJ.js → chunk-HVBF35GT.js} +2 -2
  64. package/dist/{chunk-DINDL2CF.js → chunk-HWJW3CPO.js} +25 -5
  65. package/dist/{chunk-VW66JEGU.js → chunk-IV3RHICU.js} +8 -8
  66. package/dist/{chunk-ACYIZ3KH.js → chunk-JKBDGZFL.js} +12 -6
  67. package/dist/{chunk-ZVY25BMK.js → chunk-K3QVDAZW.js} +1 -1
  68. package/dist/{chunk-MUVTZNJW.js → chunk-KHXVTWYS.js} +3 -3
  69. package/dist/{chunk-T5SZ4PML.js → chunk-KJRALILH.js} +7 -4
  70. package/dist/{chunk-VOMOZ4D5.js → chunk-M2LMXPJZ.js} +1 -1
  71. package/dist/{chunk-SUWRZYQG.js → chunk-MDJJW3LP.js} +3 -3
  72. package/dist/chunk-MU3WU2FO.js +166 -0
  73. package/dist/{chunk-2UMNXADU.js → chunk-OSJEMXSR.js} +5 -1
  74. package/dist/{chunk-TWWLVOPB.js → chunk-P4BNYJ5Q.js} +5 -5
  75. package/dist/{chunk-XDP3UYH5.js → chunk-PJ27EHCD.js} +8 -8
  76. package/dist/{chunk-LGXUGYUH.js → chunk-PYCQXCI5.js} +2 -2
  77. package/dist/{chunk-VIOL2DJS.js → chunk-R5KY3PBN.js} +5 -5
  78. package/dist/{chunk-SOUZBGYJ.js → chunk-T4QY64OR.js} +15 -14
  79. package/dist/{chunk-DY4ILT6L.js → chunk-TFKBFQCE.js} +1 -1
  80. package/dist/{chunk-GZ7E6VOB.js → chunk-TIWURSLS.js} +1 -1
  81. package/dist/{chunk-F4UWL4NY.js → chunk-TUXFIVOH.js} +1 -1
  82. package/dist/{chunk-UJBZIKSY.js → chunk-TZGCUNOX.js} +8 -8
  83. package/dist/{chunk-FU2DFEAZ.js → chunk-USQDVBEV.js} +2 -2
  84. package/dist/{chunk-YXP3WPAI.js → chunk-UYDTFCHW.js} +1 -1
  85. package/dist/{chunk-4ZDKSDVW.js → chunk-WNJSGZY7.js} +4 -4
  86. package/dist/{chunk-NHTAHAIS.js → chunk-WOLPADR6.js} +1 -1
  87. package/dist/{chunk-BZ4GDOJX.js → chunk-X7FESZTD.js} +7 -7
  88. package/dist/{chunk-NOWZUGZW.js → chunk-XWEONSLV.js} +1 -1
  89. package/dist/{chunk-Y3MM6PYN.js → chunk-YAWXKL2X.js} +1 -1
  90. package/dist/{chunk-GKIUEIDX.js → chunk-YQMFGWBD.js} +1 -1
  91. package/dist/{chunk-WPVHRUDT.js → chunk-Z4VGIBJ7.js} +3 -3
  92. package/dist/{reapply-J527BCJG.js → reapply-5CZSTJZI.js} +13 -8
  93. package/dist/src/index.js +18 -16
  94. package/package.json +1 -1
@@ -3,6 +3,7 @@ import { readFileSync } from "fs";
3
3
  import { dirname, join, parse } from "path";
4
4
  import { fileURLToPath } from "url";
5
5
  var PACKAGE_NAME = "@pushary/agent-hooks";
6
+ var UNKNOWN_VERSION = "0.0.0";
6
7
  var findOwnPackageJson = (start) => {
7
8
  const { root } = parse(start);
8
9
  let dir = start;
@@ -20,13 +21,24 @@ var findOwnPackageJson = (start) => {
20
21
  }
21
22
  };
22
23
  var getPackageVersion = () => {
24
+ const root = ownPackageRoot();
25
+ return (root === void 0 ? void 0 : packageVersionAt(root)) ?? UNKNOWN_VERSION;
26
+ };
27
+ var ownPackageRoot = () => {
23
28
  try {
24
29
  const found = findOwnPackageJson(dirname(fileURLToPath(import.meta.url)));
25
- if (!found) return "0.0.0";
26
- const pkg = JSON.parse(readFileSync(found, "utf-8"));
27
- return pkg.version ?? "0.0.0";
30
+ return found ? dirname(found) : void 0;
31
+ } catch {
32
+ return void 0;
33
+ }
34
+ };
35
+ var packageVersionAt = (packageRoot) => {
36
+ try {
37
+ const manifest = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf-8"));
38
+ const version = manifest && typeof manifest === "object" && "version" in manifest ? manifest.version : void 0;
39
+ return typeof version === "string" ? version : void 0;
28
40
  } catch {
29
- return "0.0.0";
41
+ return void 0;
30
42
  }
31
43
  };
32
44
  var isNewerVersion = (candidate, current) => {
@@ -38,8 +50,16 @@ var isNewerVersion = (candidate, current) => {
38
50
  }
39
51
  return false;
40
52
  };
53
+ var RELEASE_VERSION = /^\d+\.\d+\.\d+$/;
54
+ var isReleaseVersion = (value) => RELEASE_VERSION.test(value);
55
+ var majorOf = (version) => parseInt(version.split(".")[0] ?? "", 10) || 0;
56
+ var isSameMajorVersion = (candidate, current) => majorOf(candidate) === majorOf(current);
41
57
 
42
58
  export {
43
59
  getPackageVersion,
44
- isNewerVersion
60
+ ownPackageRoot,
61
+ packageVersionAt,
62
+ isNewerVersion,
63
+ isReleaseVersion,
64
+ isSameMajorVersion
45
65
  };
@@ -2,27 +2,27 @@ import {
2
2
  detectProviderLiveCapabilities,
3
3
  hasSpawnProvider,
4
4
  resolveControlPolicy
5
- } from "./chunk-TYEO6T5J.js";
5
+ } from "./chunk-5ZZG76S2.js";
6
6
  import {
7
7
  daemonHasRemoteProof,
8
8
  daemonServiceManagerAvailable,
9
9
  hasDaemonServiceDefinition,
10
10
  readDaemonNeedsLogin,
11
11
  readDaemonStatus
12
- } from "./chunk-BZ4GDOJX.js";
12
+ } from "./chunk-X7FESZTD.js";
13
13
  import {
14
14
  getMachineId
15
- } from "./chunk-NHTAHAIS.js";
16
- import {
17
- getPackageVersion
18
- } from "./chunk-DINDL2CF.js";
15
+ } from "./chunk-WOLPADR6.js";
19
16
  import {
20
17
  readControlMode,
21
18
  readKeySource
22
- } from "./chunk-FU2DFEAZ.js";
19
+ } from "./chunk-USQDVBEV.js";
23
20
  import {
24
21
  getBaseUrl
25
- } from "./chunk-2UMNXADU.js";
22
+ } from "./chunk-OSJEMXSR.js";
23
+ import {
24
+ getPackageVersion
25
+ } from "./chunk-HWJW3CPO.js";
26
26
 
27
27
  // src/machines.ts
28
28
  import { hostname } from "os";
@@ -1,18 +1,21 @@
1
1
  import {
2
2
  detectClaudeVersion
3
- } from "./chunk-PC6DU5C4.js";
3
+ } from "./chunk-HUAOMX4U.js";
4
+ import {
5
+ ensureCodexTrustsPusharyHooks
6
+ } from "./chunk-6EEANS74.js";
4
7
  import {
5
8
  addClaudeMcpServer,
6
9
  addPusharyHooks,
7
10
  addPusharyToolPermissions
8
- } from "./chunk-II7PUMPB.js";
11
+ } from "./chunk-4ERLRNOK.js";
9
12
  import {
10
13
  claudeUnprovenHolds,
11
14
  claudeWired,
12
15
  codexUnprovenHolds,
13
16
  codexWired,
14
17
  geminiWired
15
- } from "./chunk-WPVHRUDT.js";
18
+ } from "./chunk-Z4VGIBJ7.js";
16
19
  import {
17
20
  CLAUDE_HOOK_BINARY,
18
21
  CLAUDE_HOOK_EVENTS,
@@ -24,7 +27,7 @@ import {
24
27
  needsReregistration,
25
28
  registrationSignatures,
26
29
  supportedClaudeEvents
27
- } from "./chunk-LPYCPFBZ.js";
30
+ } from "./chunk-2AUIEZYS.js";
28
31
  import {
29
32
  CODEX_HOOK_BINARY,
30
33
  addCodexHookTrust,
@@ -44,7 +47,7 @@ import {
44
47
  registrationHolderOf,
45
48
  resolveGlobalBinary,
46
49
  vscodePluginMcp
47
- } from "./chunk-TRLFZKVG.js";
50
+ } from "./chunk-6IU45EHE.js";
48
51
  import {
49
52
  readJsonSafe,
50
53
  writeFileAtomic,
@@ -309,6 +312,8 @@ var reapplyAllAgents = (apiKey) => {
309
312
  }
310
313
  return done;
311
314
  };
315
+ var isRewrittenCodex = (agent) => agent.id === "codex" && agent.result.hooks;
316
+ var ensureCodexTrustAfterReapply = async (agents, options = {}) => agents.some(isRewrittenCodex) ? ensureCodexTrustsPusharyHooks(options) : null;
312
317
 
313
318
  export {
314
319
  reapplyClaudeSettings,
@@ -319,5 +324,6 @@ export {
319
324
  reapplyGeminiSettings,
320
325
  reapplyCursorPlugin,
321
326
  reapplyVsCodePlugin,
322
- reapplyAllAgents
327
+ reapplyAllAgents,
328
+ ensureCodexTrustAfterReapply
323
329
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HOOK_LOCATOR_BINARY
3
- } from "./chunk-SOUZBGYJ.js";
3
+ } from "./chunk-T4QY64OR.js";
4
4
 
5
5
  // src/diagnostics/bridge.ts
6
6
  import { execFileSync } from "child_process";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  openCodeConfigDirFrom
3
- } from "./chunk-F4UWL4NY.js";
3
+ } from "./chunk-TUXFIVOH.js";
4
4
  import {
5
5
  codexHomeFrom
6
- } from "./chunk-TRLFZKVG.js";
6
+ } from "./chunk-6IU45EHE.js";
7
7
  import {
8
8
  HOOK_COMPATIBLE_PROFILES
9
- } from "./chunk-SOUZBGYJ.js";
9
+ } from "./chunk-T4QY64OR.js";
10
10
 
11
11
  // src/vscode-config.ts
12
12
  import { homedir } from "os";
@@ -12,14 +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-UM5J3J4V.js";
18
+ } from "./chunk-HU5LSYL2.js";
19
19
  import {
20
20
  PAIR_TTL_SECONDS,
21
21
  isAnswerSource
22
- } from "./chunk-SOUZBGYJ.js";
22
+ } from "./chunk-T4QY64OR.js";
23
+ import {
24
+ NPX_LATEST_COMMAND
25
+ } from "./chunk-EA3IELHP.js";
23
26
 
24
27
  // src/reach.ts
25
28
  var reachVerdict = (channels) => {
@@ -752,7 +755,7 @@ var PAIR_STOP_BEFORE_EXPIRY_MS = 1e4;
752
755
  var PAIR_TIMEOUT_MS = PAIR_TTL_SECONDS * 1e3 - PAIR_STOP_BEFORE_EXPIRY_MS;
753
756
  var PAIR_HINT_AFTER_MS = 45e3;
754
757
  var PAIR_BROWSER_FALLBACK_AFTER_MS = 6e4;
755
- var BROWSER_CONNECT_COMMAND = "npx @pushary/agent-hooks setup --connect browser";
758
+ var BROWSER_CONNECT_COMMAND = `${NPX_LATEST_COMMAND} setup --connect browser`;
756
759
  var PAIR_BROWSER_FALLBACK_LINE = `Still waiting? Sign in with a browser instead: Ctrl-C, then ${BROWSER_CONNECT_COMMAND}`;
757
760
  var SYSTEM_PAIR_CLOCK = { now: () => Date.now(), sleep };
758
761
  var startPairing = async (cliPublicKey) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-TRLFZKVG.js";
3
+ } from "./chunk-6IU45EHE.js";
4
4
  import {
5
5
  readJsonSafe
6
6
  } from "./chunk-T7E75EKA.js";
@@ -7,10 +7,10 @@ import {
7
7
  permissionDeniedAction,
8
8
  releaseThrottle,
9
9
  reportEvent
10
- } from "./chunk-G653QPTR.js";
10
+ } from "./chunk-D573TLP6.js";
11
11
  import {
12
12
  canonicalJson
13
- } from "./chunk-TRLFZKVG.js";
13
+ } from "./chunk-6IU45EHE.js";
14
14
  import {
15
15
  writeFileAtomic
16
16
  } from "./chunk-T7E75EKA.js";
@@ -20,7 +20,7 @@ import {
20
20
  machineDecisionFor,
21
21
  shouldDeferToNativeMode,
22
22
  wireVerdictFor
23
- } from "./chunk-SOUZBGYJ.js";
23
+ } from "./chunk-T4QY64OR.js";
24
24
 
25
25
  // src/machine-decision-audit.ts
26
26
  import { basename } from "path";
@@ -0,0 +1,166 @@
1
+ import {
2
+ autoUpdateState
3
+ } from "./chunk-6IU45EHE.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", "finish_pending"];
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
+ if (input.platform === "linux") return "linux";
57
+ return null;
58
+ };
59
+ var globalInstallPrefix = (packageRoot) => {
60
+ const root = packageRoot.replace(/\/+$/, "");
61
+ if (!root.endsWith(GLOBAL_PACKAGE_SUBPATH)) return null;
62
+ if (NON_GLOBAL_INSTALL_SEGMENTS.some((segment) => root.includes(segment))) return null;
63
+ const prefix = root.slice(0, -GLOBAL_PACKAGE_SUBPATH.length);
64
+ return prefix.startsWith("/") ? prefix : null;
65
+ };
66
+ var upgradeEntryFor = (prefix) => join(prefix, GLOBAL_PACKAGE_SUBPATH, ...UPGRADE_ENTRY_SUBPATH);
67
+ var checkedWithinInterval = (lastCheckAt, now) => {
68
+ const last = lastCheckAt === void 0 ? Number.NaN : Date.parse(lastCheckAt);
69
+ if (Number.isNaN(last)) return false;
70
+ const elapsed = now - last;
71
+ return elapsed >= 0 && elapsed < AUTO_UPDATE_INTERVAL_MS;
72
+ };
73
+ var autoUpdateDecision = (input) => {
74
+ if (input.isSubagentStart) return { kind: "skip", reason: "subagent_start" };
75
+ const offReason = autoUpdateOffReason(input);
76
+ if (offReason !== null) return { kind: "skip", reason: offReason };
77
+ const prefix = input.packageRoot === void 0 ? null : globalInstallPrefix(input.packageRoot);
78
+ if (prefix === null) return { kind: "skip", reason: "not_global_install" };
79
+ if (checkedWithinInterval(input.state.lastCheckAt, input.now)) return { kind: "skip", reason: "checked_recently" };
80
+ return { kind: "check", prefix };
81
+ };
82
+ var parseAutoUpdateFlag = (args) => {
83
+ const token = args.find((arg) => arg === AUTO_UPDATE_FLAG || arg.startsWith(`${AUTO_UPDATE_FLAG}=`));
84
+ if (token === void 0) return { kind: "absent" };
85
+ if (token === AUTO_UPDATE_FLAG) return { kind: "run" };
86
+ const value = token.slice(AUTO_UPDATE_FLAG.length + 1);
87
+ if (value === "on") return { kind: "set", enabled: true };
88
+ if (value === "off") return { kind: "set", enabled: false };
89
+ return { kind: "invalid", value };
90
+ };
91
+ var AUTO_UPDATE_RESULT_LABELS = {
92
+ updated: "updated",
93
+ finish_pending: "installed; configuration refresh pending",
94
+ current: "up to date",
95
+ needs_manual: "needs a manual upgrade",
96
+ failed: "failed"
97
+ };
98
+ var versionsOf = (state) => state.from && state.to ? `${state.from} to ${state.to}` : state.from;
99
+ var describeAutoUpdateCheck = (state) => {
100
+ const label = state.lastResult ? AUTO_UPDATE_RESULT_LABELS[state.lastResult] : "no result recorded";
101
+ return [label, versionsOf(state), state.detail].filter(Boolean).join(", ");
102
+ };
103
+ var hasPendingUpgradeFinish = (state, installed) => state.to === installed && (state.lastResult === "finish_pending" || state.lastResult === "updated" && Boolean(state.detail));
104
+ var pendingAutoUpdateAnnouncement = (state) => state.lastResult === "updated" && state.announced !== true && state.from && state.to ? { from: state.from, to: state.to } : null;
105
+ var describeAutoUpdateAnnouncement = (announcement) => `Pushary updated itself from ${announcement.from} to ${announcement.to}.`;
106
+ var takeAutoUpdateAnnouncement = (statePath, markAnnounced) => {
107
+ try {
108
+ const announcement = pendingAutoUpdateAnnouncement(readAutoUpdateState(statePath));
109
+ if (announcement && markAnnounced) updateAutoUpdateState(statePath, { announced: true });
110
+ return announcement;
111
+ } catch {
112
+ return null;
113
+ }
114
+ };
115
+ var readAutoUpdateState = (statePath) => {
116
+ const read = readJsonSafe(statePath);
117
+ return read.kind === "ok" ? parseAutoUpdateState(read.value) : {};
118
+ };
119
+ var updateAutoUpdateState = (statePath, patch) => {
120
+ const next = { ...readAutoUpdateState(statePath), ...patch };
121
+ writeJsonAtomic(statePath, next);
122
+ return next;
123
+ };
124
+ var ignoreSpawnFailure = () => void 0;
125
+ var spawnDetached = (command, args, cwd) => {
126
+ const child = spawn(command, [...args], { cwd, detached: true, stdio: "ignore" });
127
+ child.on("error", ignoreSpawnFailure);
128
+ child.unref();
129
+ };
130
+ var triggerAutoUpdate = (trigger) => {
131
+ try {
132
+ const statePath = trigger.statePath ?? autoUpdateState();
133
+ const now = trigger.now ?? Date.now();
134
+ const decision = autoUpdateDecision({
135
+ env: trigger.env ?? process.env,
136
+ state: readAutoUpdateState(statePath),
137
+ now,
138
+ platform: trigger.platform ?? process.platform,
139
+ packageRoot: trigger.packageRoot ?? ownPackageRoot(),
140
+ isSubagentStart: trigger.isSubagentStart
141
+ });
142
+ if (decision.kind === "skip") return decision;
143
+ updateAutoUpdateState(statePath, { lastCheckAt: new Date(now).toISOString() });
144
+ const spawnUpgrade = trigger.spawn ?? spawnDetached;
145
+ spawnUpgrade(trigger.execPath ?? process.execPath, [upgradeEntryFor(decision.prefix), AUTO_UPDATE_FLAG], dirname(statePath));
146
+ return decision;
147
+ } catch {
148
+ return null;
149
+ }
150
+ };
151
+
152
+ export {
153
+ AUTO_UPDATE_DISABLE_ENV,
154
+ isAutoUpdateDisabledByEnv,
155
+ autoUpdateOffReason,
156
+ globalInstallPrefix,
157
+ upgradeEntryFor,
158
+ parseAutoUpdateFlag,
159
+ describeAutoUpdateCheck,
160
+ hasPendingUpgradeFinish,
161
+ describeAutoUpdateAnnouncement,
162
+ takeAutoUpdateAnnouncement,
163
+ readAutoUpdateState,
164
+ updateAutoUpdateState,
165
+ triggerAutoUpdate
166
+ };
@@ -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";
@@ -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,7 +1,7 @@
1
1
  import {
2
2
  activeHookSource,
3
3
  activeIdentity
4
- } from "./chunk-VIOL2DJS.js";
4
+ } from "./chunk-R5KY3PBN.js";
5
5
  import {
6
6
  blockedActionFingerprint,
7
7
  defersToNativeMode,
@@ -9,11 +9,11 @@ import {
9
9
  hasBlockedActionHint,
10
10
  recordBlockedActionHint,
11
11
  reportMachineDenial
12
- } from "./chunk-SUWRZYQG.js";
12
+ } from "./chunk-MDJJW3LP.js";
13
13
  import {
14
14
  isGatingMoment,
15
15
  recordKeylessMoment
16
- } from "./chunk-LEAAERSQ.js";
16
+ } from "./chunk-43ZDACBO.js";
17
17
  import {
18
18
  denyReasonFrom,
19
19
  isDeferAnswer
@@ -36,7 +36,7 @@ import {
36
36
  reportEvent,
37
37
  scopePathFor,
38
38
  settleQuestionsForToolUse
39
- } from "./chunk-G653QPTR.js";
39
+ } from "./chunk-D573TLP6.js";
40
40
  import {
41
41
  DECISION_STOP_REASON,
42
42
  askUser,
@@ -48,14 +48,14 @@ import {
48
48
  requestGate,
49
49
  sendNotification,
50
50
  waitForQuestion
51
- } from "./chunk-LGXUGYUH.js";
51
+ } from "./chunk-PYCQXCI5.js";
52
52
  import {
53
53
  getMachineId
54
- } from "./chunk-NHTAHAIS.js";
54
+ } from "./chunk-WOLPADR6.js";
55
55
  import {
56
56
  getApiKey,
57
57
  getBaseUrl
58
- } from "./chunk-2UMNXADU.js";
58
+ } from "./chunk-OSJEMXSR.js";
59
59
  import {
60
60
  AGENT_QUESTION_STRATEGY,
61
61
  GATE_BLOCK_REASON_MAX_LENGTH,
@@ -79,7 +79,7 @@ import {
79
79
  parseAgentQuestions,
80
80
  resolveGate,
81
81
  stoppedOutput
82
- } from "./chunk-SOUZBGYJ.js";
82
+ } from "./chunk-T4QY64OR.js";
83
83
 
84
84
  // src/decision-episode.ts
85
85
  var EPISODE_PATH = "/api/agent/decision-episode";
@@ -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";
@@ -3,28 +3,28 @@ import {
3
3
  addPusharyToolPermissions,
4
4
  isPusharyHook,
5
5
  removeClaudeMcpServers
6
- } from "./chunk-II7PUMPB.js";
6
+ } from "./chunk-4ERLRNOK.js";
7
7
  import {
8
8
  CLAUDE_HOOK_EVENTS,
9
9
  addGeminiMcpServer,
10
10
  removeGeminiMcpServer
11
- } from "./chunk-LPYCPFBZ.js";
11
+ } from "./chunk-2AUIEZYS.js";
12
12
  import {
13
13
  CLAUDE_CODE_AGENT,
14
14
  parseApplyPatchFiles
15
- } from "./chunk-G653QPTR.js";
15
+ } from "./chunk-D573TLP6.js";
16
16
  import {
17
17
  guardBinary,
18
18
  holdBudgetOf,
19
19
  registerHookEntry
20
- } from "./chunk-TRLFZKVG.js";
20
+ } from "./chunk-6IU45EHE.js";
21
21
  import {
22
22
  PHONE_ANSWERED_TOOLS,
23
23
  hookCompatibleProfile,
24
24
  hookCompatibleProfileBySource,
25
25
  toToolLookup,
26
26
  withHookHoldBudget
27
- } from "./chunk-SOUZBGYJ.js";
27
+ } from "./chunk-T4QY64OR.js";
28
28
 
29
29
  // src/compatible-config.ts
30
30
  import { homedir } from "os";