@pushary/agent-hooks 1.7.3 → 1.8.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 (108) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +39 -19
  3. package/data/SKILL.md +8 -8
  4. package/data/cowork/SKILL.md +2 -2
  5. package/data/cursor-plugin/README.md +2 -2
  6. package/data/cursor-plugin/scripts/pushary-gate.mjs +2 -21
  7. package/data/cursor-plugin/scripts/redaction.mjs +53 -0
  8. package/data/cursor-plugin/skills/pushary/SKILL.md +7 -7
  9. package/data/vscode-plugin/README.md +4 -4
  10. package/data/vscode-plugin/scripts/pushary-gate.mjs +3 -23
  11. package/data/vscode-plugin/scripts/redaction.mjs +53 -0
  12. package/data/vscode-plugin/skills/pushary/SKILL.md +7 -7
  13. package/dist/bin/pushary-bell-hook.js +23 -23
  14. package/dist/bin/pushary-bell.js +9 -9
  15. package/dist/bin/pushary-claude.js +26 -26
  16. package/dist/bin/pushary-clean.js +97 -111
  17. package/dist/bin/pushary-codex-bridge.js +18 -18
  18. package/dist/bin/pushary-codex-hook.js +42 -43
  19. package/dist/bin/pushary-codex.js +13 -13
  20. package/dist/bin/pushary-connect.js +13 -13
  21. package/dist/bin/pushary-cowork.js +5 -5
  22. package/dist/bin/pushary-daemon.js +27 -27
  23. package/dist/bin/pushary-disconnect.js +18 -18
  24. package/dist/bin/pushary-doctor.js +92 -86
  25. package/dist/bin/pushary-elicitation-hook.js +25 -25
  26. package/dist/bin/pushary-gemini-bridge.js +12 -12
  27. package/dist/bin/pushary-gemini-hook.js +29 -30
  28. package/dist/bin/pushary-hook.js +32 -32
  29. package/dist/bin/pushary-login.js +12 -12
  30. package/dist/bin/pushary-logout.js +7 -7
  31. package/dist/bin/pushary-mcp.js +85 -28
  32. package/dist/bin/pushary-mode.js +9 -9
  33. package/dist/bin/pushary-notification-hook.js +28 -28
  34. package/dist/bin/pushary-opencode-hook.js +28 -29
  35. package/dist/bin/pushary-permission-denied-hook.js +32 -32
  36. package/dist/bin/pushary-permission-hook.js +31 -31
  37. package/dist/bin/pushary-post-hook.js +28 -28
  38. package/dist/bin/pushary-prompt-hook.js +28 -28
  39. package/dist/bin/pushary-session-end-hook.js +28 -28
  40. package/dist/bin/pushary-session-start-hook.js +32 -32
  41. package/dist/bin/pushary-setup.js +62 -129
  42. package/dist/bin/pushary-stats.js +5 -5
  43. package/dist/bin/pushary-status.js +15 -15
  44. package/dist/bin/pushary-stop-hook.js +28 -28
  45. package/dist/bin/pushary-stopfailure-hook.js +28 -28
  46. package/dist/bin/pushary-suggestions.js +4 -4
  47. package/dist/bin/pushary-transcript-register.js +19 -19
  48. package/dist/bin/pushary-transcripts.js +7 -7
  49. package/dist/bin/pushary-upgrade.js +236 -110
  50. package/dist/bin/pushary-wait.js +9 -9
  51. package/dist/bin/pushary.js +6 -6
  52. package/dist/{chunk-DUQO4C4I.js → chunk-2SLCHCVN.js} +3 -3
  53. package/dist/{chunk-YYCTF4Q5.js → chunk-35X5UDML.js} +7 -7
  54. package/dist/{chunk-OVC5QXN5.js → chunk-4A3UQERT.js} +1 -1
  55. package/dist/chunk-5DGNEUXK.js +73 -0
  56. package/dist/{chunk-62CVUUNU.js → chunk-5Y2DY6X4.js} +2 -2
  57. package/dist/{chunk-G4GLCLKK.js → chunk-5YY3IJT4.js} +159 -36
  58. package/dist/{chunk-KJXUIPS4.js → chunk-64H5IZZD.js} +28 -16
  59. package/dist/{chunk-OTNOANMX.js → chunk-6TK4IY3A.js} +8 -8
  60. package/dist/{chunk-LPNJLKBQ.js → chunk-72WOCX22.js} +1 -1
  61. package/dist/{chunk-IRZG3HEU.js → chunk-7ITOAMCD.js} +1 -1
  62. package/dist/{chunk-G62JL2NT.js → chunk-7U7ZWUTR.js} +1 -1
  63. package/dist/{chunk-IPSRMLCJ.js → chunk-ASWRMBOM.js} +1 -1
  64. package/dist/{chunk-5S2VBSJI.js → chunk-CB23AO4D.js} +2 -2
  65. package/dist/{chunk-VKVSRCBO.js → chunk-CHMOVJ2M.js} +1 -1
  66. package/dist/{chunk-BGBLLHZ4.js → chunk-DLEKCAQL.js} +1 -1
  67. package/dist/{chunk-EEEJ2JIL.js → chunk-DVW2MYCM.js} +3 -3
  68. package/dist/{chunk-AWVNAYGD.js → chunk-DXBS2EL7.js} +1 -1
  69. package/dist/{chunk-ZKJ34T2F.js → chunk-EIGJYCOE.js} +31 -17
  70. package/dist/{chunk-U6RVDUJ5.js → chunk-F6NTWZZC.js} +283 -41
  71. package/dist/{chunk-7RUJKCR4.js → chunk-FLQPM2GQ.js} +2 -2
  72. package/dist/{chunk-TCVMK6GI.js → chunk-GBNQXYN4.js} +4 -4
  73. package/dist/{chunk-G6RRVJOG.js → chunk-GH6KGWMC.js} +6 -6
  74. package/dist/chunk-GU3EJCVV.js +43 -0
  75. package/dist/{chunk-6JQFIHZC.js → chunk-HBWC3JVZ.js} +3 -3
  76. package/dist/{chunk-IWJKSIB4.js → chunk-HMNR7B2F.js} +1 -1
  77. package/dist/{chunk-NOI3XTCY.js → chunk-HOEB6AKG.js} +1 -1
  78. package/dist/{chunk-62VT3BPH.js → chunk-HQRCVEI2.js} +32 -17
  79. package/dist/{chunk-MIXWMA73.js → chunk-HTEGMMT3.js} +3 -3
  80. package/dist/{chunk-BIH2Y2HP.js → chunk-HVDMGDYV.js} +2 -2
  81. package/dist/{chunk-VE7TXLR4.js → chunk-I4HKMUZQ.js} +3 -3
  82. package/dist/{chunk-YPUBA2FL.js → chunk-INSMZNS7.js} +5 -5
  83. package/dist/{chunk-G3OMOTJ4.js → chunk-JRQRNNGA.js} +3 -3
  84. package/dist/{chunk-N5MZH5A6.js → chunk-KB2FTO4O.js} +4 -4
  85. package/dist/{chunk-O3JDWNLU.js → chunk-LK2S5XIV.js} +183 -28
  86. package/dist/{chunk-YC27PROF.js → chunk-MMVCI6DT.js} +20 -5
  87. package/dist/{chunk-3EUBQARL.js → chunk-MYHG7PX2.js} +1 -1
  88. package/dist/{chunk-EADXTSHE.js → chunk-N6JJJTPH.js} +6 -3
  89. package/dist/{chunk-PRNFSORD.js → chunk-NHCUXTEM.js} +1 -1
  90. package/dist/{chunk-KEL5MXRL.js → chunk-NOLPURUI.js} +1 -1
  91. package/dist/{chunk-WTJM7PSL.js → chunk-OCVVSRDA.js} +3 -3
  92. package/dist/{chunk-R6OYCUNK.js → chunk-ON5JW2HP.js} +1 -1
  93. package/dist/{chunk-UOQRM7JQ.js → chunk-QB6QYZ6B.js} +5 -5
  94. package/dist/{chunk-7OA34PNW.js → chunk-T55H6YEP.js} +40 -10
  95. package/dist/{chunk-D6OODZCM.js → chunk-TJMAXQ5Q.js} +2 -2
  96. package/dist/{chunk-WGMW7OXW.js → chunk-TKQ6LZQZ.js} +6 -6
  97. package/dist/{chunk-WPX67AKT.js → chunk-UMMCHS6P.js} +1 -1
  98. package/dist/{chunk-MZBRL5H5.js → chunk-UPLV5AJF.js} +108 -25
  99. package/dist/{chunk-P2VIBGXA.js → chunk-URNXU3FO.js} +1 -1
  100. package/dist/{chunk-EUGNVLMG.js → chunk-VFFHQC7W.js} +3 -1
  101. package/dist/{chunk-Y4ZH64UK.js → chunk-VZMIHERK.js} +2 -2
  102. package/dist/{chunk-RLW3JWDY.js → chunk-W2LJ4O3A.js} +2 -2
  103. package/dist/{chunk-LHC45YUC.js → chunk-ZJYJAD52.js} +1 -1
  104. package/dist/{reapply-PH5T4BGR.js → reapply-ICGTBHVE.js} +9 -9
  105. package/dist/src/index.js +20 -20
  106. package/package.json +1 -1
  107. package/dist/chunk-5GB22QYL.js +0 -255
  108. package/dist/chunk-VYPJHGG6.js +0 -92
@@ -4,65 +4,56 @@ import {
4
4
  } from "../chunk-CVWG2N3Y.js";
5
5
  import {
6
6
  readServiceExecPath,
7
- retryAgentCommand,
8
7
  versionManagerOf
9
- } from "../chunk-VYPJHGG6.js";
8
+ } from "../chunk-GU3EJCVV.js";
10
9
  import {
11
10
  assessCodexHookTrust,
12
11
  readCodexTrustForPusharyHooks
13
- } from "../chunk-RLW3JWDY.js";
12
+ } from "../chunk-W2LJ4O3A.js";
14
13
  import {
15
14
  readMachineReadiness,
16
15
  readManagedControlEvidence
17
- } from "../chunk-WGMW7OXW.js";
16
+ } from "../chunk-TKQ6LZQZ.js";
18
17
  import {
19
18
  FX_PROFILE_REFUSALS,
20
19
  FX_PUSHARY_TOOLS_RULE,
21
20
  FX_QUESTION_TOOL,
22
- FX_SETTINGS_REFUSALS,
23
21
  HERMES_PIP_PACKAGE,
24
22
  HERMES_PLUGIN_NAME,
25
23
  agentProbes,
26
24
  detectAgent,
27
25
  detectAllAgents,
28
- fxBridgeTargetOf,
29
- fxPusharyEntryOf,
30
- fxQuestionRouting,
31
26
  hasInstructionBlock,
32
27
  hermesWiredByPushary,
28
+ inspectFxInstallation,
33
29
  isDetected,
34
- isFxPusharyEntry,
35
30
  isPluginRegistered,
36
- pusharyToolsAllowed,
37
- readFxFile,
38
- readFxProfile,
39
- readFxSettings,
40
31
  readHermesStatus,
41
32
  resolveHermesPython,
33
+ retryAgentCommand,
42
34
  shortenHome,
43
- vscodeSettingsTargets,
44
- workspacesShowingQuestionTool
45
- } from "../chunk-O3JDWNLU.js";
46
- import "../chunk-7OA34PNW.js";
35
+ vscodeSettingsTargets
36
+ } from "../chunk-LK2S5XIV.js";
37
+ import "../chunk-T55H6YEP.js";
47
38
  import {
48
39
  OPENCODE_PLUGIN_PLACEHOLDER,
49
40
  openCodePluginDir,
50
41
  openCodePluginFile,
51
42
  openCodeWired
52
- } from "../chunk-KEL5MXRL.js";
43
+ } from "../chunk-NOLPURUI.js";
53
44
  import {
54
45
  compatibleConfigFile,
55
46
  compatibleInstructionsFile,
56
47
  compatibleMcpFile,
57
48
  hasCompatibleHooks,
58
49
  missingCompatibleHookEvents
59
- } from "../chunk-UOQRM7JQ.js";
60
- import "../chunk-G3OMOTJ4.js";
50
+ } from "../chunk-QB6QYZ6B.js";
51
+ import "../chunk-JRQRNNGA.js";
61
52
  import {
62
53
  detectProviderLiveCapabilities,
63
54
  hasSpawnProvider,
64
55
  resolveControlPolicy
65
- } from "../chunk-Y4ZH64UK.js";
56
+ } from "../chunk-VZMIHERK.js";
66
57
  import {
67
58
  AUTO_UPDATE_DISABLE_ENV,
68
59
  autoUpdateOffReason,
@@ -70,16 +61,16 @@ import {
70
61
  describeAutoUpdateCheck,
71
62
  readAutoUpdateState,
72
63
  takeAutoUpdateAnnouncement
73
- } from "../chunk-KJXUIPS4.js";
64
+ } from "../chunk-64H5IZZD.js";
74
65
  import {
75
66
  readLedgerSummary
76
- } from "../chunk-IRZG3HEU.js";
67
+ } from "../chunk-7ITOAMCD.js";
77
68
  import {
78
69
  describeBridgeResolution,
79
70
  isBridgeLocator,
80
71
  liveBridgeProbe,
81
72
  resolveBridgeStub
82
- } from "../chunk-3EUBQARL.js";
73
+ } from "../chunk-MYHG7PX2.js";
83
74
  import {
84
75
  claudeOtherHolders,
85
76
  claudeUnprovenHolds,
@@ -96,7 +87,7 @@ import {
96
87
  geminiWired,
97
88
  holdsLong,
98
89
  pusharyHookExecutable
99
- } from "../chunk-WTJM7PSL.js";
90
+ } from "../chunk-OCVVSRDA.js";
100
91
  import {
101
92
  daemonHasRemoteProof,
102
93
  daemonServiceManagerAvailable,
@@ -105,18 +96,18 @@ import {
105
96
  readDaemonNeedsLogin,
106
97
  readDaemonStatus,
107
98
  readInstalledDaemonService
108
- } from "../chunk-ZKJ34T2F.js";
99
+ } from "../chunk-EIGJYCOE.js";
109
100
  import {
110
101
  GEMINI_HOOK_BINARY,
111
102
  hasGeminiHooks,
112
103
  missingGeminiHookEvents
113
- } from "../chunk-MIXWMA73.js";
104
+ } from "../chunk-HTEGMMT3.js";
114
105
  import "../chunk-XHKBHWLX.js";
115
- import "../chunk-U6RVDUJ5.js";
106
+ import "../chunk-F6NTWZZC.js";
116
107
  import "../chunk-N6IOSZOE.js";
117
- import "../chunk-EUGNVLMG.js";
118
- import "../chunk-YC27PROF.js";
119
- import "../chunk-N5MZH5A6.js";
108
+ import "../chunk-VFFHQC7W.js";
109
+ import "../chunk-MMVCI6DT.js";
110
+ import "../chunk-KB2FTO4O.js";
120
111
  import "../chunk-POFBE6ZY.js";
121
112
  import {
122
113
  describeReach,
@@ -125,7 +116,7 @@ import {
125
116
  reachVerdict,
126
117
  roundTripEvidence,
127
118
  verifyRoundTrip
128
- } from "../chunk-YPUBA2FL.js";
119
+ } from "../chunk-INSMZNS7.js";
129
120
  import "../chunk-3EGEA4KH.js";
130
121
  import "../chunk-QCGNGEGE.js";
131
122
  import {
@@ -133,7 +124,7 @@ import {
133
124
  } from "../chunk-U4TMAANR.js";
134
125
  import {
135
126
  exitOnHelpFlag
136
- } from "../chunk-5S2VBSJI.js";
127
+ } from "../chunk-CB23AO4D.js";
137
128
  import {
138
129
  parseFlags
139
130
  } from "../chunk-GMXKITVA.js";
@@ -141,26 +132,26 @@ import {
141
132
  keyPrefix,
142
133
  readControlMode,
143
134
  readKeySource
144
- } from "../chunk-D6OODZCM.js";
135
+ } from "../chunk-TJMAXQ5Q.js";
145
136
  import {
146
137
  callMcpTool,
147
138
  sendMcpRequest
148
- } from "../chunk-VE7TXLR4.js";
139
+ } from "../chunk-I4HKMUZQ.js";
149
140
  import {
150
141
  checkApiKey,
151
142
  describeKeyCheck
152
- } from "../chunk-EEEJ2JIL.js";
153
- import "../chunk-DUQO4C4I.js";
143
+ } from "../chunk-DVW2MYCM.js";
144
+ import "../chunk-2SLCHCVN.js";
154
145
  import {
155
146
  getMachineId
156
- } from "../chunk-OVC5QXN5.js";
147
+ } from "../chunk-4A3UQERT.js";
157
148
  import {
158
149
  UsageError
159
150
  } from "../chunk-7QLSKOSU.js";
160
151
  import {
161
152
  EXIT
162
153
  } from "../chunk-KZERVKTD.js";
163
- import "../chunk-62CVUUNU.js";
154
+ import "../chunk-5Y2DY6X4.js";
164
155
  import {
165
156
  CODEX_HOOK_EVENTS,
166
157
  autoUpdateState,
@@ -176,7 +167,6 @@ import {
176
167
  cursorPluginDir,
177
168
  cursorUserHooks,
178
169
  cursorUserMcp,
179
- execNpm,
180
170
  fetchLatestPublishedVersion,
181
171
  fxMcpProfile,
182
172
  fxSettings,
@@ -188,16 +178,17 @@ import {
188
178
  missingCodexHookEvents,
189
179
  pusharyConfigFile,
190
180
  readCodexMcpAuth,
181
+ readGlobalCliInstall,
191
182
  resolvePathBinary,
192
183
  vscodePluginDir
193
- } from "../chunk-MZBRL5H5.js";
184
+ } from "../chunk-UPLV5AJF.js";
194
185
  import "../chunk-T7E75EKA.js";
195
186
  import {
196
187
  getBaseUrl
197
- } from "../chunk-R6OYCUNK.js";
188
+ } from "../chunk-ON5JW2HP.js";
198
189
  import {
199
190
  NPX_LATEST_COMMAND
200
- } from "../chunk-YYCTF4Q5.js";
191
+ } from "../chunk-35X5UDML.js";
201
192
  import {
202
193
  AGENTS,
203
194
  CURSOR_GATE_EVENTS,
@@ -206,12 +197,13 @@ import {
206
197
  HOOK_SOURCES,
207
198
  SUPPORT_DISCORD,
208
199
  SUPPORT_EMAIL,
200
+ commandsPackage,
209
201
  getPackageVersion,
210
202
  hookActivationResult,
211
203
  hookCompatibleProfile,
212
204
  isHookActivationReport,
213
205
  isNewerVersion
214
- } from "../chunk-G4GLCLKK.js";
206
+ } from "../chunk-5YY3IJT4.js";
215
207
 
216
208
  // bin/pushary-doctor.ts
217
209
  import { existsSync, readFileSync, writeFileSync } from "fs";
@@ -221,6 +213,33 @@ import { execFileSync } from "child_process";
221
213
  import { confirm } from "@inquirer/prompts";
222
214
  import { parse as parseTOML } from "smol-toml";
223
215
 
216
+ // src/diagnostics/global-package.ts
217
+ var NOT_FOUND = "not found";
218
+ var NPM_PREFIX_UNREADABLE = "not found (npm could not report its global prefix)";
219
+ var BOTH_INSTALLED_WARNING = "npm uninstall -g of either name removes every Pushary command";
220
+ var describeInstalledPackage = (installed2) => installed2.version === void 0 ? `${installed2.name}, version unreadable` : `${installed2.name} ${installed2.version}`;
221
+ var describeCommandOwner = (owner) => owner.kind === "owned" ? `the commands run from ${owner.name}` : "which one owns the commands could not be read";
222
+ var globalPackageCheck = (install) => {
223
+ switch (install.kind) {
224
+ case "unavailable":
225
+ return { ok: false, detail: NPM_PREFIX_UNREADABLE, commands: void 0 };
226
+ case "absent":
227
+ return { ok: false, detail: NOT_FOUND, commands: void 0 };
228
+ case "single":
229
+ return {
230
+ ok: install.installed.version !== void 0,
231
+ detail: describeInstalledPackage(install.installed),
232
+ commands: install.installed
233
+ };
234
+ case "both":
235
+ return {
236
+ ok: false,
237
+ detail: `both installed: ${install.installed.map(describeInstalledPackage).join(" and ")}; ${describeCommandOwner(install.owner)}; ${BOTH_INSTALLED_WARNING}`,
238
+ commands: commandsPackage(install)
239
+ };
240
+ }
241
+ };
242
+
224
243
  // src/diagnostics/auto-update.ts
225
244
  var globalPackageFreshness = (installed2, latest) => isNewerVersion(latest, installed2) ? { upToDate: false, detail: `${installed2} installed, ${latest} available \u2014 run ${NPX_LATEST_COMMAND} upgrade` } : { upToDate: true, detail: installed2 };
226
245
  var AUTO_UPDATE_ON = "on: once a day at session start, within the same major version";
@@ -254,22 +273,21 @@ var describeAutoUpdateStatus = (input) => {
254
273
 
255
274
  // src/diagnostics/bundle.ts
256
275
  import { homedir, hostname } from "os";
257
- var globalVersion = () => {
258
- try {
259
- return execNpm("list -g --no-workspaces @pushary/agent-hooks --depth=0", { timeout: 1e4 }).toString().match(/@pushary\/agent-hooks@([\d.]+)/)?.[1] ?? null;
260
- } catch {
261
- return null;
262
- }
276
+ var installedGlobalPackages = (install) => {
277
+ if (install.kind === "single") return [install.installed];
278
+ if (install.kind === "both") return install.installed;
279
+ return [];
263
280
  };
264
281
  var collectBundle = async (options2 = {}) => {
265
282
  const now = options2.now ?? (() => /* @__PURE__ */ new Date());
266
- const readGlobalVersion = options2.readGlobalVersion ?? globalVersion;
283
+ const globalInstall = (options2.readGlobalInstall ?? readGlobalCliInstall)();
267
284
  const source = readKeySource();
268
285
  const identity = options2.identity ?? null;
269
286
  return {
270
287
  generatedAt: now().toISOString(),
271
288
  cliVersion: getPackageVersion(),
272
- globalVersion: readGlobalVersion(),
289
+ globalVersion: commandsPackage(globalInstall)?.version ?? null,
290
+ globalPackages: installedGlobalPackages(globalInstall),
273
291
  node: process.version,
274
292
  platform: process.platform,
275
293
  arch: process.arch,
@@ -374,7 +392,7 @@ function inertRegistrations(configs, resolves) {
374
392
  return findings;
375
393
  }
376
394
  var describeInertRegistration = ({ named }) => `hooks here are registered for "${named}", which this CLI has no profile for, so every one of them stands aside`;
377
- var inertRegistrationRemedy = () => "Upgrade with npx @pushary/agent-hooks@latest upgrade, or re-run setup to rewrite them for an agent this version knows";
395
+ var inertRegistrationRemedy = () => `Upgrade with ${NPX_LATEST_COMMAND} upgrade, or re-run setup to rewrite them for an agent this version knows`;
378
396
 
379
397
  // src/hooks-spec.ts
380
398
  var CURSOR_GATE_SCRIPT = "pushary-gate.mjs";
@@ -483,12 +501,6 @@ var reportHermesStatus = (status) => {
483
501
  if (status.questionsRouted) check(true, "Hermes: questions go through Pushary", `clarify is off in ${config}`);
484
502
  else console.log(` ${warn} Hermes: questions can stop in the terminal ${dim(`(clarify is not in agent.disabled_toolsets in ${config})`)}`);
485
503
  };
486
- var fxSettingsProblem = (read) => {
487
- if (read.kind === "missing") return `${fxSettings()} is missing, so fx runs with no Pushary rules; re-run ${retryAgentCommand("fx")}`;
488
- if (read.kind === "unreadable") return `${fxSettings()} could not be read`;
489
- if (read.kind === "refused") return `${fxSettings()} ${FX_SETTINGS_REFUSALS[read.reason]}`;
490
- return null;
491
- };
492
504
  var FX_QUESTION_ROUTING_WARNINGS = {
493
505
  "full-access": "full-access mode ignores permission rules, so fx's terminal question tool stays on; its instructions ask it to use Pushary instead",
494
506
  overridden: `a rule in ${fxSettings()} keeps ${FX_QUESTION_TOOL} on; make "${FX_QUESTION_TOOL}": "deny" the last rule that matches it`
@@ -698,10 +710,10 @@ var main = async () => {
698
710
  const configured = JSON.stringify(hooks?.[event] ?? []);
699
711
  const present = configured.includes(needle) || configured.includes(HOOK_LOCATOR_BINARY);
700
712
  if (!present) claudeHooksMissing += 1;
701
- check(present, `Claude Code: ${label}`, present ? void 0 : "missing \u2014 run npx @pushary/agent-hooks@latest upgrade");
713
+ check(present, `Claude Code: ${label}`, present ? void 0 : `missing: run ${NPX_LATEST_COMMAND} upgrade`);
702
714
  }
703
715
  for (const event of claudeUnprovenHolds(settings)) {
704
- console.log(` ${warn} Claude Code: ${event} hook carries no current hold budget ${dim("(an auto-mode block only notifies; run npx @pushary/agent-hooks@latest upgrade)")}`);
716
+ console.log(` ${warn} Claude Code: ${event} hook carries no current hold budget ${dim(`(an auto-mode block only notifies; run ${NPX_LATEST_COMMAND} upgrade)`)}`);
705
717
  }
706
718
  const preHookCommand = extractAgentHookCommand(hooks?.PreToolUse, "pushary-hook");
707
719
  if (preHookCommand) {
@@ -818,7 +830,7 @@ var main = async () => {
818
830
  }
819
831
  }
820
832
  for (const event of codexUnprovenHolds(codexHooksConfig)) {
821
- console.log(` ${warn} Codex: ${event} hook carries no current hold budget ${dim("(an auto-reviewer denial is not asked about; run npx @pushary/agent-hooks@latest upgrade)")}`);
833
+ console.log(` ${warn} Codex: ${event} hook carries no current hold budget ${dim(`(an auto-reviewer denial is not asked about; run ${NPX_LATEST_COMMAND} upgrade)`)}`);
822
834
  }
823
835
  } else {
824
836
  check(!!codexNotifyPath, "Codex: notify handler configured (deprecated)", codexNotifyPath ? "upgrade Codex and re-run setup for native hooks" : "missing, re-run setup");
@@ -1112,27 +1124,25 @@ var main = async () => {
1112
1124
  } else {
1113
1125
  skipped("OpenCode", installed("opencode") ? "installed, but Pushary is not set up for it" : "not installed");
1114
1126
  }
1115
- const fxProfile = readFxFile(fxMcpProfile(), readFxProfile);
1116
- const fxEntry = fxProfile.kind === "profile" ? fxPusharyEntryOf(fxProfile.profile) : void 0;
1117
- if (isFxPusharyEntry(fxEntry)) {
1127
+ const fx = inspectFxInstallation(fxMcpProfile(), fxSettings(), process.env);
1128
+ const fxProfile = fx.profile;
1129
+ if (fx.configured) {
1118
1130
  checking("fx");
1119
1131
  check(true, "fx: Pushary MCP server configured", fxMcpProfile());
1120
- const bridge = fxBridgeTargetOf(fxEntry);
1132
+ const bridge = fx.bridge;
1121
1133
  if (bridge) {
1122
1134
  const found = fxBridgeFound(bridge);
1123
1135
  check(found, "fx: bridge binary resolves", found ? bridge : `${bridge} is not installed or not on PATH \u2014 re-run ${retryAgentCommand("fx")}`);
1124
1136
  }
1125
- const fxSettingsRead = readFxFile(fxSettings(), readFxSettings);
1126
- const settingsProblem = fxSettingsProblem(fxSettingsRead);
1127
- const fxSettings2 = fxSettingsRead.kind === "settings" ? fxSettingsRead.settings : {};
1137
+ const settingsProblem = fx.settingsProblem;
1128
1138
  if (settingsProblem) {
1129
1139
  console.log(` ${warn} fx: Pushary tools are not auto-allowed and questions can still stop in the terminal ${dim(`(${settingsProblem})`)}`);
1130
- } else if (!pusharyToolsAllowed(fxSettings2)) {
1140
+ } else if (!fx.toolsAllowed) {
1131
1141
  console.log(` ${warn} fx: Pushary tools are not auto-allowed ${dim(`(fx will review or prompt for each call; add "${FX_PUSHARY_TOOLS_RULE}": "allow" to permission in ${fxSettings()})`)}`);
1132
1142
  }
1133
- const questionRouting = fxQuestionRouting(fxSettings2, process.env);
1143
+ const questionRouting = fx.questionRouting;
1134
1144
  if (settingsProblem === null) reportFxQuestionRouting(questionRouting);
1135
- const workspacesShowingQuestions = workspacesShowingQuestionTool(fxSettings2);
1145
+ const workspacesShowingQuestions = fx.workspacesShowingQuestions;
1136
1146
  if (workspacesShowingQuestions.length > 0) {
1137
1147
  console.log(` ${warn} fx: ${workspacesShowingQuestions.length} workspace(s) replace the global rules and keep ${FX_QUESTION_TOOL} on ${dim(`(add "${FX_QUESTION_TOOL}": "deny" to their permission rules in ${fxSettings()})`)}`);
1138
1148
  }
@@ -1159,22 +1169,18 @@ var main = async () => {
1159
1169
  check(
1160
1170
  agentsChecked.length > 0,
1161
1171
  "Wired to at least one agent",
1162
- agentsChecked.length > 0 ? agentsChecked.join(", ") : "Pushary is installed but configured for no agent \u2014 run npx @pushary/agent-hooks@latest setup"
1172
+ agentsChecked.length > 0 ? agentsChecked.join(", ") : `Pushary is installed but configured for no agent. Run ${NPX_LATEST_COMMAND} setup`
1163
1173
  );
1164
1174
  if (claudeInPlay) {
1165
1175
  check(existsSync(SKILL_PATH), "Skill installed", existsSync(SKILL_PATH) ? SKILL_PATH : "not found");
1166
1176
  }
1167
- let globalVersion2 = "";
1168
- try {
1169
- globalVersion2 = execNpm("list -g --no-workspaces @pushary/agent-hooks --depth=0", { timeout: 1e4 }).toString().match(/@pushary\/agent-hooks@([\d.]+)/)?.[1] ?? "";
1170
- } catch {
1171
- globalVersion2 = "";
1172
- }
1173
- check(!!globalVersion2, "Global package installed", globalVersion2 || "not found");
1174
- if (globalVersion2) {
1175
- const latest = await fetchLatestPublishedVersion();
1177
+ const globalPackage = globalPackageCheck(readGlobalCliInstall());
1178
+ const globalVersion = globalPackage.commands?.version ?? "";
1179
+ check(globalPackage.ok, "Global package installed", globalPackage.detail);
1180
+ if (globalPackage.commands && globalVersion) {
1181
+ const latest = await fetchLatestPublishedVersion({ packageName: globalPackage.commands.name });
1176
1182
  if (latest) {
1177
- const freshness = globalPackageFreshness(globalVersion2, latest);
1183
+ const freshness = globalPackageFreshness(globalVersion, latest);
1178
1184
  check(freshness.upToDate, "Global package up to date", freshness.detail);
1179
1185
  }
1180
1186
  }
@@ -1194,7 +1200,7 @@ var main = async () => {
1194
1200
  }
1195
1201
  });
1196
1202
  if (aliasRc) {
1197
- if (globalVersion2) {
1203
+ if (globalVersion) {
1198
1204
  check(true, "claude alias \u2192 pushary claude", `set in ${aliasRc.split("/").pop()}`);
1199
1205
  } else {
1200
1206
  check(false, "claude alias \u2192 pushary claude", "alias is set but pushary is not installed \u2014 run `unalias claude` (this shell) or reinstall");
@@ -1231,7 +1237,7 @@ var main = async () => {
1231
1237
  check(false, "MCP handshake", "skipped");
1232
1238
  const keylessSummary = readLedgerSummary(7);
1233
1239
  if (keylessSummary.count > 0) {
1234
- check(false, "Keyless approval moments (7d)", `${keylessSummary.count} counted locally \u2014 npx @pushary/agent-hooks@latest stats`);
1240
+ check(false, "Keyless approval moments (7d)", `${keylessSummary.count} counted locally. See them with ${NPX_LATEST_COMMAND} stats`);
1235
1241
  }
1236
1242
  } else {
1237
1243
  let sessionId = "";
@@ -1374,7 +1380,7 @@ var main = async () => {
1374
1380
  console.log(` ${fail} ${f.label}${f.detail ? ` \u2014 ${f.detail}` : ""}`);
1375
1381
  }
1376
1382
  console.log();
1377
- console.log(` ${dim("Run")} ${cyan("npx @pushary/agent-hooks@latest clean")} ${dim("then")} ${cyan("setup")} ${dim("to fix.")}`);
1383
+ console.log(` ${dim("Run")} ${cyan(`${NPX_LATEST_COMMAND} clean`)} ${dim("then")} ${cyan("setup")} ${dim("to fix.")}`);
1378
1384
  console.log(` ${dim("Still failing after that? Send this report to")} ${cyan(SUPPORT_EMAIL)} ${dim("or ask on")} ${cyan(SUPPORT_DISCORD)}`);
1379
1385
  }
1380
1386
  console.log();
@@ -1,52 +1,52 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  readHookInput
4
- } from "../chunk-7RUJKCR4.js";
4
+ } from "../chunk-FLQPM2GQ.js";
5
5
  import {
6
6
  announceSubscriptionRequired,
7
7
  isDeferAnswer
8
8
  } from "../chunk-5OP5MQI7.js";
9
- import "../chunk-OTNOANMX.js";
9
+ import "../chunk-6TK4IY3A.js";
10
10
  import "../chunk-SGZJ5LYH.js";
11
- import "../chunk-TCVMK6GI.js";
12
- import "../chunk-BGBLLHZ4.js";
13
- import "../chunk-3EUBQARL.js";
14
- import "../chunk-WTJM7PSL.js";
15
- import "../chunk-ZKJ34T2F.js";
16
- import "../chunk-MIXWMA73.js";
17
- import "../chunk-NOI3XTCY.js";
18
- import "../chunk-P2VIBGXA.js";
19
- import "../chunk-WPX67AKT.js";
20
- import "../chunk-LPNJLKBQ.js";
11
+ import "../chunk-GBNQXYN4.js";
12
+ import "../chunk-DLEKCAQL.js";
13
+ import "../chunk-MYHG7PX2.js";
14
+ import "../chunk-OCVVSRDA.js";
15
+ import "../chunk-EIGJYCOE.js";
16
+ import "../chunk-HTEGMMT3.js";
17
+ import "../chunk-HOEB6AKG.js";
18
+ import "../chunk-URNXU3FO.js";
19
+ import "../chunk-UMMCHS6P.js";
20
+ import "../chunk-72WOCX22.js";
21
21
  import "../chunk-XHKBHWLX.js";
22
22
  import "../chunk-N6IOSZOE.js";
23
- import "../chunk-EUGNVLMG.js";
23
+ import "../chunk-VFFHQC7W.js";
24
24
  import {
25
25
  askUser,
26
26
  isDecisionStopped,
27
27
  waitForQuestion
28
- } from "../chunk-YC27PROF.js";
29
- import "../chunk-N5MZH5A6.js";
28
+ } from "../chunk-MMVCI6DT.js";
29
+ import "../chunk-KB2FTO4O.js";
30
30
  import "../chunk-POFBE6ZY.js";
31
31
  import "../chunk-GMXKITVA.js";
32
- import "../chunk-D6OODZCM.js";
32
+ import "../chunk-TJMAXQ5Q.js";
33
33
  import {
34
34
  SubscriptionRequiredError
35
- } from "../chunk-VE7TXLR4.js";
36
- import "../chunk-EEEJ2JIL.js";
37
- import "../chunk-DUQO4C4I.js";
35
+ } from "../chunk-I4HKMUZQ.js";
36
+ import "../chunk-DVW2MYCM.js";
37
+ import "../chunk-2SLCHCVN.js";
38
38
  import {
39
39
  getMachineId
40
- } from "../chunk-OVC5QXN5.js";
40
+ } from "../chunk-4A3UQERT.js";
41
41
  import "../chunk-7QLSKOSU.js";
42
42
  import "../chunk-KZERVKTD.js";
43
- import "../chunk-62CVUUNU.js";
44
- import "../chunk-MZBRL5H5.js";
43
+ import "../chunk-5Y2DY6X4.js";
44
+ import "../chunk-UPLV5AJF.js";
45
45
  import "../chunk-T7E75EKA.js";
46
46
  import {
47
47
  getApiKey
48
- } from "../chunk-R6OYCUNK.js";
49
- import "../chunk-YYCTF4Q5.js";
48
+ } from "../chunk-ON5JW2HP.js";
49
+ import "../chunk-35X5UDML.js";
50
50
  import {
51
51
  ELICITATION_ANSWERABLE_MODE,
52
52
  effectiveWaitSeconds,
@@ -57,7 +57,7 @@ import {
57
57
  planElicitationAsk,
58
58
  readElicitationFields,
59
59
  renderElicitationOutput
60
- } from "../chunk-G4GLCLKK.js";
60
+ } from "../chunk-5YY3IJT4.js";
61
61
 
62
62
  // bin/pushary-elicitation-hook.ts
63
63
  import { basename } from "path";
@@ -5,37 +5,37 @@ import {
5
5
  postLiveSession,
6
6
  postLiveSessionUntilAccepted,
7
7
  startLiveSessionHeartbeat
8
- } from "../chunk-BIH2Y2HP.js";
8
+ } from "../chunk-HVDMGDYV.js";
9
9
  import {
10
10
  SESSION_IDLE_TIMEOUT_MS,
11
11
  describeIdleWindow,
12
12
  idleDeadlinePassed,
13
13
  startProcessOwnership,
14
14
  withSpawnProcessOwnership
15
- } from "../chunk-LHC45YUC.js";
16
- import "../chunk-P2VIBGXA.js";
17
- import "../chunk-WPX67AKT.js";
15
+ } from "../chunk-ZJYJAD52.js";
16
+ import "../chunk-URNXU3FO.js";
17
+ import "../chunk-UMMCHS6P.js";
18
18
  import {
19
19
  transcriptsEnabled
20
- } from "../chunk-LPNJLKBQ.js";
20
+ } from "../chunk-72WOCX22.js";
21
21
  import {
22
22
  spawnClaude
23
23
  } from "../chunk-XHKBHWLX.js";
24
- import "../chunk-D6OODZCM.js";
24
+ import "../chunk-TJMAXQ5Q.js";
25
25
  import {
26
26
  getMachineId
27
- } from "../chunk-OVC5QXN5.js";
28
- import "../chunk-62CVUUNU.js";
27
+ } from "../chunk-4A3UQERT.js";
28
+ import "../chunk-5Y2DY6X4.js";
29
29
  import {
30
30
  resolveBinary
31
- } from "../chunk-MZBRL5H5.js";
31
+ } from "../chunk-UPLV5AJF.js";
32
32
  import "../chunk-T7E75EKA.js";
33
33
  import {
34
34
  getApiKey,
35
35
  getBaseUrl
36
- } from "../chunk-R6OYCUNK.js";
37
- import "../chunk-YYCTF4Q5.js";
38
- import "../chunk-G4GLCLKK.js";
36
+ } from "../chunk-ON5JW2HP.js";
37
+ import "../chunk-35X5UDML.js";
38
+ import "../chunk-5YY3IJT4.js";
39
39
 
40
40
  // bin/pushary-gemini-bridge.ts
41
41
  import { existsSync } from "fs";