@pushary/agent-hooks 1.7.1 → 1.7.3

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 (106) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/data/cursor-plugin/CHANGELOG.md +1 -0
  3. package/data/cursor-plugin/scripts/pushary-gate.mjs +3 -3
  4. package/data/cursor-plugin/scripts/pushary-gate.test.mjs +23 -1
  5. package/data/vscode-plugin/CHANGELOG.md +1 -0
  6. package/data/vscode-plugin/scripts/pushary-gate.mjs +3 -3
  7. package/dist/bin/pushary-bell-hook.js +23 -23
  8. package/dist/bin/pushary-bell.js +10 -10
  9. package/dist/bin/pushary-claude.js +48 -37
  10. package/dist/bin/pushary-clean.js +107 -60
  11. package/dist/bin/pushary-codex-bridge.js +18 -17
  12. package/dist/bin/pushary-codex-hook.js +53 -39
  13. package/dist/bin/pushary-codex.js +14 -12
  14. package/dist/bin/pushary-connect.js +16 -16
  15. package/dist/bin/pushary-cowork.js +5 -5
  16. package/dist/bin/pushary-daemon.js +27 -27
  17. package/dist/bin/pushary-disconnect.js +19 -17
  18. package/dist/bin/pushary-doctor.js +63 -35
  19. package/dist/bin/pushary-elicitation-hook.js +35 -26
  20. package/dist/bin/pushary-gemini-bridge.js +12 -12
  21. package/dist/bin/pushary-gemini-hook.js +47 -32
  22. package/dist/bin/pushary-hook.js +34 -32
  23. package/dist/bin/pushary-login.js +16 -16
  24. package/dist/bin/pushary-logout.js +8 -8
  25. package/dist/bin/pushary-mcp.js +9 -8
  26. package/dist/bin/pushary-mode.js +10 -10
  27. package/dist/bin/pushary-notification-hook.js +29 -27
  28. package/dist/bin/pushary-opencode-hook.js +46 -32
  29. package/dist/bin/pushary-permission-denied-hook.js +34 -32
  30. package/dist/bin/pushary-permission-hook.js +33 -31
  31. package/dist/bin/pushary-post-hook.js +29 -27
  32. package/dist/bin/pushary-prompt-hook.js +29 -27
  33. package/dist/bin/pushary-session-end-hook.js +29 -27
  34. package/dist/bin/pushary-session-start-hook.js +33 -31
  35. package/dist/bin/pushary-setup.js +69 -56
  36. package/dist/bin/pushary-stats.js +5 -5
  37. package/dist/bin/pushary-status.js +19 -19
  38. package/dist/bin/pushary-stop-hook.js +29 -27
  39. package/dist/bin/pushary-stopfailure-hook.js +29 -27
  40. package/dist/bin/pushary-suggestions.js +5 -5
  41. package/dist/bin/pushary-transcript-register.js +19 -19
  42. package/dist/bin/pushary-transcripts.js +7 -7
  43. package/dist/bin/pushary-upgrade.js +20 -20
  44. package/dist/bin/pushary-wait.js +10 -10
  45. package/dist/bin/pushary.js +6 -6
  46. package/dist/{chunk-MWVCDP64.js → chunk-3EUBQARL.js} +1 -1
  47. package/dist/{chunk-3QORH5EJ.js → chunk-5GB22QYL.js} +6 -4
  48. package/dist/chunk-5OP5MQI7.js +45 -0
  49. package/dist/{chunk-6PV2JQ64.js → chunk-5S2VBSJI.js} +2 -2
  50. package/dist/{chunk-UPKP67TA.js → chunk-62CVUUNU.js} +2 -2
  51. package/dist/{chunk-42XR73I2.js → chunk-62VT3BPH.js} +35 -35
  52. package/dist/chunk-6JQFIHZC.js +99 -0
  53. package/dist/{chunk-2FU43B5Q.js → chunk-7OA34PNW.js} +2 -2
  54. package/dist/{chunk-7GI6QC3M.js → chunk-7RUJKCR4.js} +2 -2
  55. package/dist/{chunk-H6JV44TE.js → chunk-AWVNAYGD.js} +1 -1
  56. package/dist/{chunk-XMN37YJH.js → chunk-BGBLLHZ4.js} +1 -1
  57. package/dist/{chunk-VCMFKZON.js → chunk-BIH2Y2HP.js} +2 -2
  58. package/dist/{chunk-YZKS3ME3.js → chunk-D6OODZCM.js} +2 -2
  59. package/dist/{chunk-JTQDP4ZL.js → chunk-DUQO4C4I.js} +3 -3
  60. package/dist/{chunk-3QE3BHBW.js → chunk-EADXTSHE.js} +2 -2
  61. package/dist/{chunk-43SSQCWO.js → chunk-EEEJ2JIL.js} +3 -3
  62. package/dist/{chunk-4C4NRDIC.js → chunk-EUGNVLMG.js} +1 -1
  63. package/dist/{chunk-WSC53O7I.js → chunk-G3OMOTJ4.js} +3 -3
  64. package/dist/{chunk-XFNVG3OV.js → chunk-G4GLCLKK.js} +44 -9
  65. package/dist/{chunk-62TEPRWQ.js → chunk-G62JL2NT.js} +1 -1
  66. package/dist/{chunk-QPR33SHS.js → chunk-G6RRVJOG.js} +6 -6
  67. package/dist/{chunk-Y6GKOZBT.js → chunk-IPSRMLCJ.js} +1 -1
  68. package/dist/{chunk-MCNS4725.js → chunk-IRZG3HEU.js} +1 -1
  69. package/dist/{chunk-55RO62FV.js → chunk-IWJKSIB4.js} +1 -1
  70. package/dist/{chunk-NID4UZDN.js → chunk-KEL5MXRL.js} +1 -1
  71. package/dist/{chunk-BYVB3RX3.js → chunk-KJXUIPS4.js} +2 -2
  72. package/dist/{chunk-SNWNA3MQ.js → chunk-LHC45YUC.js} +1 -1
  73. package/dist/{chunk-XPTCPU6V.js → chunk-LPNJLKBQ.js} +1 -1
  74. package/dist/{chunk-WZWXBTRF.js → chunk-MIXWMA73.js} +3 -3
  75. package/dist/{chunk-454KMJHF.js → chunk-MZBRL5H5.js} +34 -1
  76. package/dist/{chunk-KSNAAMU5.js → chunk-N5MZH5A6.js} +4 -4
  77. package/dist/chunk-N6IOSZOE.js +185 -0
  78. package/dist/{chunk-XPMOCJHN.js → chunk-NOI3XTCY.js} +1 -1
  79. package/dist/{chunk-NAAZCNKI.js → chunk-O3JDWNLU.js} +351 -37
  80. package/dist/{chunk-7GYGVQBU.js → chunk-OTNOANMX.js} +8 -8
  81. package/dist/{chunk-P5CBNSYL.js → chunk-OVC5QXN5.js} +1 -1
  82. package/dist/{chunk-O5JD7UI5.js → chunk-P2VIBGXA.js} +3 -3
  83. package/dist/{chunk-3T35OE7C.js → chunk-PRNFSORD.js} +4 -4
  84. package/dist/{chunk-OAL44FM2.js → chunk-R6OYCUNK.js} +1 -1
  85. package/dist/{chunk-6SJQ442W.js → chunk-RLW3JWDY.js} +2 -2
  86. package/dist/{chunk-SVEMF2VO.js → chunk-TCVMK6GI.js} +4 -4
  87. package/dist/{chunk-O5PRIYFZ.js → chunk-U4TMAANR.js} +3 -0
  88. package/dist/{chunk-WM3U2RUK.js → chunk-U6RVDUJ5.js} +75 -232
  89. package/dist/{chunk-KBLIVEFJ.js → chunk-UOQRM7JQ.js} +5 -5
  90. package/dist/{chunk-NQFGVAT6.js → chunk-VE7TXLR4.js} +19 -2
  91. package/dist/{chunk-IGBDOZUO.js → chunk-VKVSRCBO.js} +1 -1
  92. package/dist/{chunk-ZEMSCGDD.js → chunk-VYPJHGG6.js} +8 -3
  93. package/dist/{chunk-YQN7S57T.js → chunk-WGMW7OXW.js} +6 -6
  94. package/dist/{chunk-OTZHT34O.js → chunk-WPX67AKT.js} +1 -1
  95. package/dist/{chunk-XDASEYRS.js → chunk-WTJM7PSL.js} +3 -3
  96. package/dist/{chunk-Q7QRR6YL.js → chunk-Y4ZH64UK.js} +2 -2
  97. package/dist/{chunk-ZIIYTQHC.js → chunk-YC27PROF.js} +12 -4
  98. package/dist/{chunk-AHWJHLG5.js → chunk-YPUBA2FL.js} +7 -5
  99. package/dist/{chunk-EIZW73P5.js → chunk-YYCTF4Q5.js} +1 -1
  100. package/dist/{chunk-AAGLDXH4.js → chunk-ZKJ34T2F.js} +5 -5
  101. package/dist/{reapply-66GQIBXN.js → reapply-PH5T4BGR.js} +9 -9
  102. package/dist/src/index.d.ts +1 -0
  103. package/dist/src/index.js +22 -20
  104. package/package.json +2 -1
  105. package/dist/chunk-JMBG47WV.js +0 -336
  106. package/dist/chunk-YHG74UFF.js +0 -12
@@ -1,33 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- HERMES_CONFIG_SCRIPT,
4
- HERMES_PIP_PACKAGE,
5
3
  PUSHARY_SKILL_NAME,
6
4
  PUSHARY_SKILL_SOURCE,
7
5
  createGuards,
8
- resolveHermesPython,
9
- runHermesPythonScript,
10
6
  withoutPusharyCursorHooks
11
- } from "../chunk-JMBG47WV.js";
7
+ } from "../chunk-6JQFIHZC.js";
12
8
  import {
13
9
  FX_PROFILE_REFUSALS,
14
10
  FX_QUESTION_TOOL,
15
11
  FX_SETTINGS_REFUSALS,
12
+ HERMES_PIP_PACKAGE,
16
13
  fxProfileText,
17
14
  fxSettingsText,
18
15
  isFxQuestionRuleReceipt,
19
16
  readFxFile,
20
17
  readFxProfile,
21
18
  readFxSettings,
19
+ readHermesStatus,
22
20
  removeInstructionBlock,
21
+ resolveHermesPython,
22
+ runHermesConfigScript,
23
23
  shortenHome,
24
24
  unregisterPluginLocation,
25
25
  vscodeSettingsTargets,
26
26
  withoutFxPusharyServer,
27
27
  withoutPusharyToolsAllowed,
28
28
  withoutQuestionsRoutedToPushary
29
- } from "../chunk-NAAZCNKI.js";
30
- import "../chunk-2FU43B5Q.js";
29
+ } from "../chunk-O3JDWNLU.js";
30
+ import "../chunk-7OA34PNW.js";
31
31
  import {
32
32
  OPENCODE_PLUGIN_SIBLING,
33
33
  OPENCODE_PLUGIN_SIBLING_CONTENTS,
@@ -39,7 +39,7 @@ import {
39
39
  openCodePluginDir,
40
40
  openCodePluginFile,
41
41
  removeOpenCodeMcpServer
42
- } from "../chunk-NID4UZDN.js";
42
+ } from "../chunk-KEL5MXRL.js";
43
43
  import {
44
44
  compatibleConfigFile,
45
45
  compatibleInstructionsFile,
@@ -47,42 +47,47 @@ import {
47
47
  compatiblePermissionRuleFile,
48
48
  removeCompatibleHooks,
49
49
  removeCompatibleMcpServer
50
- } from "../chunk-KBLIVEFJ.js";
50
+ } from "../chunk-UOQRM7JQ.js";
51
51
  import {
52
52
  isClaudeMcpSnapshot,
53
53
  removeClaudeMcpServers,
54
54
  removePusharySettings,
55
55
  removePusharyToolPermissions,
56
56
  restoreClaudeMcpServer
57
- } from "../chunk-WSC53O7I.js";
57
+ } from "../chunk-G3OMOTJ4.js";
58
58
  import {
59
59
  hookOwnerOf,
60
60
  isHookTakeoverReceipt,
61
61
  restoreHookTakeover,
62
62
  restoreMcpServer
63
- } from "../chunk-SVEMF2VO.js";
64
- import "../chunk-XMN37YJH.js";
63
+ } from "../chunk-TCVMK6GI.js";
64
+ import "../chunk-BGBLLHZ4.js";
65
65
  import {
66
66
  liveBridgeProbe,
67
67
  resolveBridgeStub
68
- } from "../chunk-MWVCDP64.js";
69
- import "../chunk-XDASEYRS.js";
68
+ } from "../chunk-3EUBQARL.js";
69
+ import "../chunk-WTJM7PSL.js";
70
70
  import {
71
71
  disableDaemonService
72
- } from "../chunk-AAGLDXH4.js";
72
+ } from "../chunk-ZKJ34T2F.js";
73
73
  import {
74
74
  removeGeminiSettings
75
- } from "../chunk-WZWXBTRF.js";
76
- import "../chunk-XPMOCJHN.js";
75
+ } from "../chunk-MIXWMA73.js";
76
+ import "../chunk-NOI3XTCY.js";
77
77
  import "../chunk-XHKBHWLX.js";
78
- import "../chunk-WM3U2RUK.js";
79
- import "../chunk-4C4NRDIC.js";
80
- import "../chunk-ZIIYTQHC.js";
81
- import "../chunk-KSNAAMU5.js";
78
+ import "../chunk-U6RVDUJ5.js";
79
+ import "../chunk-N6IOSZOE.js";
80
+ import "../chunk-EUGNVLMG.js";
81
+ import "../chunk-YC27PROF.js";
82
+ import "../chunk-N5MZH5A6.js";
82
83
  import "../chunk-POFBE6ZY.js";
84
+ import {
85
+ ansiPainter,
86
+ useColor
87
+ } from "../chunk-U4TMAANR.js";
83
88
  import {
84
89
  exitOnHelpFlag
85
- } from "../chunk-6PV2JQ64.js";
90
+ } from "../chunk-5S2VBSJI.js";
86
91
  import {
87
92
  rejectUnknownFlags
88
93
  } from "../chunk-GMXKITVA.js";
@@ -90,16 +95,18 @@ import {
90
95
  CANDIDATE_RCS,
91
96
  isDisabledExport,
92
97
  removeClaudeAlias
93
- } from "../chunk-YZKS3ME3.js";
94
- import "../chunk-NQFGVAT6.js";
95
- import "../chunk-JTQDP4ZL.js";
96
- import "../chunk-P5CBNSYL.js";
98
+ } from "../chunk-D6OODZCM.js";
99
+ import "../chunk-VE7TXLR4.js";
100
+ import "../chunk-EEEJ2JIL.js";
101
+ import "../chunk-DUQO4C4I.js";
102
+ import "../chunk-OVC5QXN5.js";
97
103
  import "../chunk-7QLSKOSU.js";
98
104
  import {
99
105
  EXIT
100
106
  } from "../chunk-KZERVKTD.js";
101
- import "../chunk-UPKP67TA.js";
107
+ import "../chunk-62CVUUNU.js";
102
108
  import {
109
+ AGENT_HOOKS_PACKAGE,
103
110
  bridgeAgentKey,
104
111
  claudeJson,
105
112
  claudeMcpReceipt,
@@ -122,8 +129,11 @@ import {
122
129
  fxSettings,
123
130
  geminiMd,
124
131
  geminiSettings,
132
+ globalPackageState,
133
+ hermesConfig,
125
134
  hermesConfigReceipt,
126
135
  hookTakeoverReceipt,
136
+ npmIsOnPath,
127
137
  pusharyDir,
128
138
  readCodexMcpAuth,
129
139
  removeCodexHookTrust,
@@ -131,10 +141,10 @@ import {
131
141
  restoreCodexHookTrust,
132
142
  vscodePluginDir,
133
143
  vscodePluginMcp
134
- } from "../chunk-454KMJHF.js";
144
+ } from "../chunk-MZBRL5H5.js";
135
145
  import "../chunk-T7E75EKA.js";
136
- import "../chunk-OAL44FM2.js";
137
- import "../chunk-EIZW73P5.js";
146
+ import "../chunk-R6OYCUNK.js";
147
+ import "../chunk-YYCTF4Q5.js";
138
148
  import {
139
149
  HOOK_COMPATIBLE_PROFILES,
140
150
  HOOK_LOCATOR_BINARY,
@@ -142,7 +152,7 @@ import {
142
152
  SUPPORT_EMAIL,
143
153
  isValidApiKey,
144
154
  redactSecrets
145
- } from "../chunk-XFNVG3OV.js";
155
+ } from "../chunk-G4GLCLKK.js";
146
156
 
147
157
  // bin/pushary-clean.ts
148
158
  import { existsSync as existsSync6, readFileSync as readFileSync4, copyFileSync, readdirSync as readdirSync4 } from "fs";
@@ -169,7 +179,7 @@ var TEST_DEFAULTS_PREFIXES = [
169
179
  var isTestDefaultsDomain = (domain) => TEST_DEFAULTS_PREFIXES.some((prefix) => domain.startsWith(prefix));
170
180
  var leakedTestDefaultsDomains = () => {
171
181
  try {
172
- return execSync("defaults domains", { encoding: "utf-8", timeout: 2e4 }).split(",").map((entry) => entry.trim()).filter(isTestDefaultsDomain);
182
+ return execSync("defaults domains", { encoding: "utf-8", timeout: 2e4 }).split(",").map((entry) => entry.trim()).filter(isTestDefaultsDomain).filter(liveMacStatePresence.defaultsDomain);
173
183
  } catch {
174
184
  return [];
175
185
  }
@@ -211,6 +221,28 @@ var MAC_KEYCHAIN_ACCOUNTS = [
211
221
  "cachedEnvironment"
212
222
  ];
213
223
  var MAC_DEFAULTS_DOMAINS = ["com.pushary.app", "pushary-bridge", "pushary.render"];
224
+ var PRESENCE_PROBE_TIMEOUT_MS = 1e4;
225
+ var commandSucceeds = (file, args) => {
226
+ try {
227
+ execFileSync(file, args, { stdio: "ignore", timeout: PRESENCE_PROBE_TIMEOUT_MS });
228
+ return true;
229
+ } catch {
230
+ return false;
231
+ }
232
+ };
233
+ var KEYCHAIN_ITEM_NOT_FOUND = 44;
234
+ var keychainItemMayExist = (service, account) => {
235
+ try {
236
+ execFileSync("security", ["find-generic-password", "-s", service, "-a", account], { stdio: "ignore" });
237
+ return true;
238
+ } catch (error) {
239
+ return !(error instanceof Error && "status" in error && error.status === KEYCHAIN_ITEM_NOT_FOUND);
240
+ }
241
+ };
242
+ var liveMacStatePresence = {
243
+ keychainItem: keychainItemMayExist,
244
+ defaultsDomain: (domain) => commandSucceeds("defaults", ["read", domain])
245
+ };
214
246
  var macLibraryState = (home = homedir()) => [
215
247
  join(home, "Library", "Application Support", "Pushary"),
216
248
  join(home, "Library", "Caches", "com.pushary.app"),
@@ -284,7 +316,7 @@ var removeDeveloperLeftovers = (guards2, domains, bundles) => {
284
316
  }
285
317
  return removed;
286
318
  };
287
- var removeMacAppState = (guards2, readServices, home) => {
319
+ var removeMacAppState = (guards2, readServices, home, present) => {
288
320
  let removed = 0;
289
321
  let failed = 0;
290
322
  let services;
@@ -294,7 +326,7 @@ var removeMacAppState = (guards2, readServices, home) => {
294
326
  return { removed, failed: 1 };
295
327
  }
296
328
  for (const service of services) {
297
- for (const account of MAC_KEYCHAIN_ACCOUNTS) {
329
+ for (const account of MAC_KEYCHAIN_ACCOUNTS.filter((account2) => present.keychainItem(service, account2))) {
298
330
  try {
299
331
  guards2.execFile(
300
332
  "security",
@@ -308,7 +340,7 @@ var removeMacAppState = (guards2, readServices, home) => {
308
340
  }
309
341
  }
310
342
  }
311
- for (const domain of MAC_DEFAULTS_DOMAINS) {
343
+ for (const domain of MAC_DEFAULTS_DOMAINS.filter(present.defaultsDomain)) {
312
344
  try {
313
345
  guards2.execFile("defaults", ["delete", domain], { stdio: "ignore", timeout: 1e4 }, `delete preferences ${domain}`);
314
346
  removed++;
@@ -479,11 +511,12 @@ var macAppKeepsMcpEntry = (entryKey, keys) => {
479
511
 
480
512
  // bin/pushary-clean.ts
481
513
  exitOnHelpFlag("clean");
482
- var dim = (s) => `\x1B[2m${s}\x1B[0m`;
483
- var bold = (s) => `\x1B[1m${s}\x1B[0m`;
484
- var green = (s) => `\x1B[32m${s}\x1B[0m`;
485
- var yellow = (s) => `\x1B[33m${s}\x1B[0m`;
486
- var red = (s) => `\x1B[31m${s}\x1B[0m`;
514
+ var paint = ansiPainter(() => useColor());
515
+ var dim = paint("\x1B[2m");
516
+ var bold = paint("\x1B[1m");
517
+ var green = paint("\x1B[32m");
518
+ var yellow = paint("\x1B[33m");
519
+ var red = paint("\x1B[31m");
487
520
  var check = green("\u2713");
488
521
  var skip = yellow("\u2013");
489
522
  var cross = red("\u2717");
@@ -494,6 +527,7 @@ var CLAUDE_SETTINGS_LOCAL = claudeSettingsLocal();
494
527
  var CLAUDE_JSON = claudeJson();
495
528
  var CLAUDE_MCP_RECEIPT = claudeMcpReceipt();
496
529
  var HERMES_CONFIG_RECEIPT = hermesConfigReceipt();
530
+ var HERMES_CONFIG_FILE = hermesConfig();
497
531
  var SKILL_DIR = claudeSkillDir();
498
532
  var CURSOR_MCP = cursorUserMcp();
499
533
  var CURSOR_PLUGIN_DIR = cursorPluginDir();
@@ -617,7 +651,7 @@ var removeFxQuestionRule = () => {
617
651
  if (outcome === "removed") writeFxText(path, fxSettingsText(settings), "fx question rule");
618
652
  else if (outcome !== "absent") console.log(` ${skip} fx question rule ${dim(`(${FX_QUESTION_TOOL} in ${path}: ${FX_QUESTION_RULE_KEPT[outcome]})`)}`);
619
653
  }
620
- guardedRemove(fxQuestionRuleReceipt(), { force: true });
654
+ if (existsSync6(fxQuestionRuleReceipt())) guardedRemove(fxQuestionRuleReceipt(), { force: true });
621
655
  };
622
656
  var removeFxInstructions = () => {
623
657
  if (guardedInstructionBlockRemoval(fxAgentsMd())) {
@@ -1099,18 +1133,27 @@ var main = async () => {
1099
1133
  removeFxInstructions();
1100
1134
  const hermesPython = resolveHermesPython();
1101
1135
  if (hermesPython) {
1102
- const configUpdated = dryRun ? (wouldNote("run ", "hermes plugin config restore"), true) : runHermesPythonScript(hermesPython, HERMES_CONFIG_SCRIPT, "clean", HERMES_CONFIG_RECEIPT);
1103
- if (!configUpdated) {
1136
+ const configRun = runHermesConfigScript(hermesPython, dryRun ? "clean-preview" : "clean", HERMES_CONFIG_RECEIPT);
1137
+ if (configRun === "failed") {
1104
1138
  incompleteClean = true;
1105
1139
  console.log(` ${skip} Hermes config ${dim("(could not update config.yaml)")}`);
1106
1140
  } else {
1107
- console.log(` ${check} Hermes config ${dim("(setup-owned changes restored)")}`);
1108
- try {
1109
- guards.execFile(hermesPython, ["-m", "pip", "uninstall", "-y", HERMES_PIP_PACKAGE], { stdio: "pipe", timeout: 6e4 }, `pip uninstall ${HERMES_PIP_PACKAGE}`);
1110
- console.log(` ${check} Hermes plugin ${dim("(pip uninstalled)")}`);
1111
- } catch {
1112
- incompleteClean = true;
1113
- console.log(` ${skip} Hermes plugin ${dim("(could not uninstall; setup receipt kept for retry)")}`);
1141
+ if (configRun === "changed") {
1142
+ if (dryRun) wouldNote("rewrite", HERMES_CONFIG_FILE);
1143
+ console.log(` ${check} Hermes config ${dim(did("removed"))} ${dim("(Pushary settings)")}`);
1144
+ } else {
1145
+ console.log(` ${skip} Hermes config ${dim("(no Pushary settings)")}`);
1146
+ }
1147
+ if (readHermesStatus(hermesPython)?.pluginInstalled === false) {
1148
+ console.log(` ${skip} Hermes plugin ${dim("(not installed)")}`);
1149
+ } else {
1150
+ try {
1151
+ guards.execFile(hermesPython, ["-m", "pip", "uninstall", "-y", HERMES_PIP_PACKAGE], { stdio: "pipe", timeout: 6e4 }, `pip uninstall ${HERMES_PIP_PACKAGE}`);
1152
+ console.log(` ${check} Hermes plugin ${dim(did("uninstalled"))}`);
1153
+ } catch {
1154
+ incompleteClean = true;
1155
+ console.log(` ${skip} Hermes plugin ${dim("(could not uninstall; setup receipt kept for retry)")}`);
1156
+ }
1114
1157
  }
1115
1158
  }
1116
1159
  } else if (existsSync6(HERMES_CONFIG_RECEIPT)) {
@@ -1209,26 +1252,30 @@ var main = async () => {
1209
1252
  if (leftovers > 0) {
1210
1253
  console.log(` ${check} Developer leftovers ${dim(did("removed"))} ${dim(`(${leftovers} leaked test preferences and stale app registrations)`)}`);
1211
1254
  }
1212
- const { removed, failed } = process.platform === "darwin" ? removeMacAppState(guards, storedPusharyKeychainServices, homedir5()) : { removed: 0, failed: 0 };
1255
+ const { removed, failed } = process.platform === "darwin" ? removeMacAppState(guards, storedPusharyKeychainServices, homedir5(), liveMacStatePresence) : { removed: 0, failed: 0 };
1213
1256
  if (failed > 0) {
1214
1257
  incompleteClean = true;
1215
1258
  console.log(` ${cross} Mac keychain ${dim(`(${failed} operations failed; unlock your keychain and re-run)`)}`);
1216
1259
  }
1217
1260
  if (removed > 0) {
1218
- console.log(` ${check} Mac app state ${dim(did("removed"))} ${dim(`(${removed} keychain items, preferences and caches)`)}`);
1261
+ console.log(` ${check} Mac app state ${dim(did("removed"))} ${dim(`(${removed} across the keychain, preferences and caches)`)}`);
1219
1262
  } else if (failed === 0) {
1220
1263
  console.log(` ${skip} Mac app state ${dim("(nothing of ours in the keychain, preferences or caches)")}`);
1221
1264
  }
1222
1265
  }
1223
- try {
1224
- if (dryRun) {
1225
- wouldNote("run ", "npm uninstall -g @pushary/agent-hooks");
1226
- } else {
1227
- execNpm("uninstall -g --no-workspaces @pushary/agent-hooks", { stdio: "ignore", timeout: 3e4 });
1228
- }
1229
- console.log(` ${check} Global package ${dim(did("uninstalled"))}`);
1230
- } catch {
1266
+ if (!npmIsOnPath()) {
1267
+ console.log(` ${skip} Global package ${dim(`(npm not found; remove ${AGENT_HOOKS_PACKAGE} with the tool that installed it)`)}`);
1268
+ } else if (globalPackageState(AGENT_HOOKS_PACKAGE) === "absent") {
1231
1269
  console.log(` ${skip} Global package ${dim("(not installed)")}`);
1270
+ } else {
1271
+ try {
1272
+ if (dryRun) wouldNote("run ", `npm uninstall -g ${AGENT_HOOKS_PACKAGE}`);
1273
+ else execNpm(`uninstall -g --no-workspaces ${AGENT_HOOKS_PACKAGE}`, { stdio: "ignore", timeout: 3e4 });
1274
+ console.log(` ${check} Global package ${dim(did("uninstalled"))}`);
1275
+ } catch {
1276
+ incompleteClean = true;
1277
+ console.log(` ${cross} Global package ${dim(`(npm uninstall failed; run npm uninstall -g ${AGENT_HOOKS_PACKAGE})`)}`);
1278
+ }
1232
1279
  }
1233
1280
  console.log();
1234
1281
  if (incompleteClean) {
@@ -1,24 +1,24 @@
1
1
  #!/usr/bin/env node
2
- import "../chunk-Q7QRR6YL.js";
2
+ import "../chunk-Y4ZH64UK.js";
3
3
  import {
4
4
  LiveTranscriptRelay,
5
5
  liveSessionSleep,
6
6
  postLiveSession,
7
7
  postLiveSessionUntilAccepted,
8
8
  startLiveSessionHeartbeat
9
- } from "../chunk-VCMFKZON.js";
9
+ } from "../chunk-BIH2Y2HP.js";
10
10
  import {
11
11
  SESSION_IDLE_TIMEOUT_MS,
12
12
  describeIdleWindow,
13
13
  idleDeadlinePassed,
14
14
  startProcessOwnership,
15
15
  withSpawnProcessOwnership
16
- } from "../chunk-SNWNA3MQ.js";
17
- import "../chunk-O5JD7UI5.js";
18
- import "../chunk-OTZHT34O.js";
16
+ } from "../chunk-LHC45YUC.js";
17
+ import "../chunk-P2VIBGXA.js";
18
+ import "../chunk-WPX67AKT.js";
19
19
  import {
20
20
  transcriptsEnabled
21
- } from "../chunk-XPTCPU6V.js";
21
+ } from "../chunk-LPNJLKBQ.js";
22
22
  import {
23
23
  spawnClaude
24
24
  } from "../chunk-XHKBHWLX.js";
@@ -27,38 +27,39 @@ import {
27
27
  isDecisionStopped,
28
28
  isWaitForAnswerResponse,
29
29
  withdrawQuestion
30
- } from "../chunk-ZIIYTQHC.js";
30
+ } from "../chunk-YC27PROF.js";
31
31
  import {
32
32
  writeDegraded
33
- } from "../chunk-KSNAAMU5.js";
33
+ } from "../chunk-N5MZH5A6.js";
34
34
  import "../chunk-POFBE6ZY.js";
35
- import "../chunk-YZKS3ME3.js";
35
+ import "../chunk-D6OODZCM.js";
36
36
  import {
37
37
  callMcpTool
38
- } from "../chunk-NQFGVAT6.js";
39
- import "../chunk-JTQDP4ZL.js";
38
+ } from "../chunk-VE7TXLR4.js";
39
+ import "../chunk-EEEJ2JIL.js";
40
+ import "../chunk-DUQO4C4I.js";
40
41
  import {
41
42
  getMachineId
42
- } from "../chunk-P5CBNSYL.js";
43
+ } from "../chunk-OVC5QXN5.js";
43
44
  import "../chunk-7QLSKOSU.js";
44
45
  import "../chunk-KZERVKTD.js";
45
- import "../chunk-UPKP67TA.js";
46
+ import "../chunk-62CVUUNU.js";
46
47
  import {
47
48
  resolveBinary
48
- } from "../chunk-454KMJHF.js";
49
+ } from "../chunk-MZBRL5H5.js";
49
50
  import "../chunk-T7E75EKA.js";
50
51
  import {
51
52
  getApiKey,
52
53
  getBaseUrl
53
- } from "../chunk-OAL44FM2.js";
54
- import "../chunk-EIZW73P5.js";
54
+ } from "../chunk-R6OYCUNK.js";
55
+ import "../chunk-YYCTF4Q5.js";
55
56
  import {
56
57
  elicitationContent,
57
58
  parseAgentQuestion,
58
59
  parseAgentQuestionAnswers,
59
60
  planElicitationAsk,
60
61
  readElicitationFields
61
- } from "../chunk-XFNVG3OV.js";
62
+ } from "../chunk-G4GLCLKK.js";
62
63
 
63
64
  // bin/pushary-codex-bridge.ts
64
65
  import { existsSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  takeHookHoldBudget
4
- } from "../chunk-IGBDOZUO.js";
4
+ } from "../chunk-VKVSRCBO.js";
5
5
  import {
6
6
  blockedActionFingerprint,
7
7
  codexCallKey,
@@ -13,37 +13,37 @@ import {
13
13
  recordCodexCallDecision,
14
14
  reportMachineDenial,
15
15
  userScope
16
- } from "../chunk-3QORH5EJ.js";
16
+ } from "../chunk-5GB22QYL.js";
17
17
  import {
18
18
  triggerAutoUpdate
19
- } from "../chunk-BYVB3RX3.js";
19
+ } from "../chunk-KJXUIPS4.js";
20
20
  import {
21
21
  isGatingMoment,
22
22
  recordKeylessMoment
23
- } from "../chunk-MCNS4725.js";
23
+ } from "../chunk-IRZG3HEU.js";
24
24
  import {
25
25
  readHookInput
26
- } from "../chunk-7GI6QC3M.js";
26
+ } from "../chunk-7RUJKCR4.js";
27
27
  import {
28
+ announceSubscriptionRequired,
28
29
  denyReasonFrom,
29
30
  isDeferAnswer
30
- } from "../chunk-YHG74UFF.js";
31
- import "../chunk-7GYGVQBU.js";
31
+ } from "../chunk-5OP5MQI7.js";
32
+ import "../chunk-OTNOANMX.js";
32
33
  import "../chunk-SGZJ5LYH.js";
33
- import "../chunk-SVEMF2VO.js";
34
- import "../chunk-XMN37YJH.js";
35
- import "../chunk-MWVCDP64.js";
36
- import "../chunk-XDASEYRS.js";
37
- import "../chunk-AAGLDXH4.js";
38
- import "../chunk-WZWXBTRF.js";
39
- import "../chunk-XPMOCJHN.js";
40
- import "../chunk-O5JD7UI5.js";
41
- import "../chunk-OTZHT34O.js";
42
- import "../chunk-XPTCPU6V.js";
34
+ import "../chunk-TCVMK6GI.js";
35
+ import "../chunk-BGBLLHZ4.js";
36
+ import "../chunk-3EUBQARL.js";
37
+ import "../chunk-WTJM7PSL.js";
38
+ import "../chunk-ZKJ34T2F.js";
39
+ import "../chunk-MIXWMA73.js";
40
+ import "../chunk-NOI3XTCY.js";
41
+ import "../chunk-P2VIBGXA.js";
42
+ import "../chunk-WPX67AKT.js";
43
+ import "../chunk-LPNJLKBQ.js";
43
44
  import "../chunk-XHKBHWLX.js";
44
45
  import {
45
46
  CODEX_AGENT,
46
- DEFAULT_SESSION,
47
47
  UNNAMED_ACTION,
48
48
  codexAllow,
49
49
  codexDeny,
@@ -76,10 +76,14 @@ import {
76
76
  toCodexWire,
77
77
  toPolicyLookup,
78
78
  toPolicyLookups
79
- } from "../chunk-WM3U2RUK.js";
80
- import "../chunk-4C4NRDIC.js";
79
+ } from "../chunk-U6RVDUJ5.js";
80
+ import {
81
+ DEFAULT_SESSION
82
+ } from "../chunk-N6IOSZOE.js";
83
+ import "../chunk-EUGNVLMG.js";
81
84
  import {
82
85
  DECISION_STOP_REASON,
86
+ UNVERIFIABLE_APPROVAL_REASON,
83
87
  askUser,
84
88
  cancelQuestion,
85
89
  claimBlockedAction,
@@ -88,34 +92,38 @@ import {
88
92
  pollForAnswer,
89
93
  requestGate,
90
94
  sendNotification,
95
+ unavailableQuestionUnlessSubscriptionRequired,
91
96
  waitForQuestion
92
- } from "../chunk-ZIIYTQHC.js";
97
+ } from "../chunk-YC27PROF.js";
93
98
  import {
94
99
  exitAfterClientReports
95
- } from "../chunk-KSNAAMU5.js";
100
+ } from "../chunk-N5MZH5A6.js";
96
101
  import "../chunk-POFBE6ZY.js";
97
102
  import "../chunk-GMXKITVA.js";
98
- import "../chunk-YZKS3ME3.js";
99
- import "../chunk-NQFGVAT6.js";
100
- import "../chunk-JTQDP4ZL.js";
103
+ import "../chunk-D6OODZCM.js";
104
+ import {
105
+ SubscriptionRequiredError
106
+ } from "../chunk-VE7TXLR4.js";
107
+ import "../chunk-EEEJ2JIL.js";
108
+ import "../chunk-DUQO4C4I.js";
101
109
  import {
102
110
  getMachineId
103
- } from "../chunk-P5CBNSYL.js";
111
+ } from "../chunk-OVC5QXN5.js";
104
112
  import "../chunk-7QLSKOSU.js";
105
113
  import {
106
114
  EXIT
107
115
  } from "../chunk-KZERVKTD.js";
108
- import "../chunk-UPKP67TA.js";
116
+ import "../chunk-62CVUUNU.js";
109
117
  import {
110
118
  canonicalJson
111
- } from "../chunk-454KMJHF.js";
119
+ } from "../chunk-MZBRL5H5.js";
112
120
  import {
113
121
  writeFileAtomic
114
122
  } from "../chunk-T7E75EKA.js";
115
123
  import {
116
124
  getApiKey
117
- } from "../chunk-OAL44FM2.js";
118
- import "../chunk-EIZW73P5.js";
125
+ } from "../chunk-R6OYCUNK.js";
126
+ import "../chunk-YYCTF4Q5.js";
119
127
  import {
120
128
  CODEX_RESCUE_TOOL_NAME,
121
129
  DECISION_LINE_MAX,
@@ -129,7 +137,7 @@ import {
129
137
  hookWaitClamped,
130
138
  hookWaitDeadline,
131
139
  resolveGate
132
- } from "../chunk-XFNVG3OV.js";
140
+ } from "../chunk-G4GLCLKK.js";
133
141
 
134
142
  // bin/pushary-codex-hook.ts
135
143
  import { basename } from "path";
@@ -573,13 +581,18 @@ var pushQuestion = async (apiKey, input, lookup, waitSeconds, mode) => {
573
581
  // key on locally. Passing it through lets the server collapse a retried create
574
582
  // the same way, instead of putting the same approval on the phone twice.
575
583
  toolUseId: input.tool_use_id
576
- }).catch(() => ({ correlationId: "", status: "unavailable" }));
584
+ }).catch(unavailableQuestionUnlessSubscriptionRequired);
577
585
  const now = Date.now();
578
586
  const deadline = hookWaitDeadline(START_MS2, waitSeconds, "codex", now);
579
587
  const clampCut = hookWaitClamped(START_MS2, waitSeconds, "codex", now);
580
588
  const answer = await waitForQuestion(apiKey, result, deadline);
581
589
  return { answer, localHandoff: !answer.answered && isLocalQuestionHandoff(result), clampCut };
582
590
  };
591
+ var codexStepsAside = (error, input) => {
592
+ announceSubscriptionRequired(error.upgradeUrl, input.session_id);
593
+ return codexPass();
594
+ };
595
+ var passAfterFailure = (error, input) => error instanceof SubscriptionRequiredError ? codexStepsAside(error, input) : codexPass();
583
596
  var notifyApprovalNeeded = async (apiKey, input, lookup) => {
584
597
  try {
585
598
  await sendNotification(apiKey, {
@@ -650,8 +663,8 @@ var decidePermissionRequest = async (input) => {
650
663
  if (toolPolicy.mode === "push_first") return codexPass();
651
664
  if (clampCut) return codexPass();
652
665
  return permissionTimeoutDecision(toolPolicy.timeoutAction);
653
- } catch {
654
- return codexPass();
666
+ } catch (error) {
667
+ return passAfterFailure(error, input);
655
668
  }
656
669
  };
657
670
  var recordPreToolUse = (key, outcome) => {
@@ -670,8 +683,8 @@ var decidePushFirstBeforeTheTool = async (apiKey, input, lookup, pushFirstSecond
670
683
  let pushed;
671
684
  try {
672
685
  pushed = await pushQuestion(apiKey, input, lookup, pushFirstSeconds, "push_first");
673
- } catch {
674
- return recordPreToolUse(callKey, codexPass());
686
+ } catch (error) {
687
+ return recordPreToolUse(callKey, passAfterFailure(error, input));
675
688
  }
676
689
  const { answer, localHandoff } = pushed;
677
690
  if (isDecisionStopped(answer)) return codexDeny(DECISION_STOP_REASON);
@@ -721,8 +734,9 @@ var decidePreToolUse = async (input) => {
721
734
  let pushed;
722
735
  try {
723
736
  pushed = await pushQuestion(apiKey, input, lookup, effectiveWaitSeconds(toolPolicy.timeoutAction, toolPolicy.timeoutSeconds, "codex"), "push_only");
724
- } catch {
725
- return recordPreToolUse(callKey, codexDeny("Pushary could not create a verifiable approval. Retry the action."));
737
+ } catch (error) {
738
+ if (error instanceof SubscriptionRequiredError) return recordPreToolUse(callKey, codexStepsAside(error, input));
739
+ return recordPreToolUse(callKey, codexDeny(UNVERIFIABLE_APPROVAL_REASON));
726
740
  }
727
741
  const { answer, localHandoff, clampCut } = pushed;
728
742
  if (isDecisionStopped(answer)) return codexDeny(DECISION_STOP_REASON);
@@ -750,7 +764,7 @@ var decidePreToolUse = async (input) => {
750
764
  };
751
765
  var repairCodexHoldsQuietly = async () => {
752
766
  try {
753
- const { repairCodexHolds } = await import("../reapply-66GQIBXN.js");
767
+ const { repairCodexHolds } = await import("../reapply-PH5T4BGR.js");
754
768
  repairCodexHolds();
755
769
  } catch {
756
770
  return;
@@ -1,32 +1,34 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  reportEvent
4
- } from "../chunk-WM3U2RUK.js";
5
- import "../chunk-4C4NRDIC.js";
4
+ } from "../chunk-U6RVDUJ5.js";
5
+ import "../chunk-N6IOSZOE.js";
6
+ import "../chunk-EUGNVLMG.js";
6
7
  import {
7
8
  askUser,
8
9
  isDecisionStopped,
9
10
  waitForAnswer
10
- } from "../chunk-ZIIYTQHC.js";
11
- import "../chunk-KSNAAMU5.js";
11
+ } from "../chunk-YC27PROF.js";
12
+ import "../chunk-N5MZH5A6.js";
12
13
  import "../chunk-POFBE6ZY.js";
13
- import "../chunk-NQFGVAT6.js";
14
- import "../chunk-JTQDP4ZL.js";
14
+ import "../chunk-VE7TXLR4.js";
15
+ import "../chunk-EEEJ2JIL.js";
16
+ import "../chunk-DUQO4C4I.js";
15
17
  import {
16
18
  getMachineId
17
- } from "../chunk-P5CBNSYL.js";
19
+ } from "../chunk-OVC5QXN5.js";
18
20
  import "../chunk-7QLSKOSU.js";
19
21
  import "../chunk-KZERVKTD.js";
20
- import "../chunk-UPKP67TA.js";
21
- import "../chunk-454KMJHF.js";
22
+ import "../chunk-62CVUUNU.js";
23
+ import "../chunk-MZBRL5H5.js";
22
24
  import "../chunk-T7E75EKA.js";
23
25
  import {
24
26
  getApiKey
25
- } from "../chunk-OAL44FM2.js";
27
+ } from "../chunk-R6OYCUNK.js";
26
28
  import {
27
29
  NPX_LATEST_COMMAND
28
- } from "../chunk-EIZW73P5.js";
29
- import "../chunk-XFNVG3OV.js";
30
+ } from "../chunk-YYCTF4Q5.js";
31
+ import "../chunk-G4GLCLKK.js";
30
32
 
31
33
  // bin/pushary-codex.ts
32
34
  import { basename } from "path";