@pushary/agent-hooks 1.6.4 → 1.7.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 (102) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +3 -2
  3. package/dist/bin/pushary-bell-hook.js +23 -24
  4. package/dist/bin/pushary-bell.js +10 -11
  5. package/dist/bin/pushary-claude.js +27 -28
  6. package/dist/bin/pushary-clean.js +173 -71
  7. package/dist/bin/pushary-codex-bridge.js +17 -18
  8. package/dist/bin/pushary-codex-hook.js +30 -31
  9. package/dist/bin/pushary-codex.js +12 -13
  10. package/dist/bin/pushary-connect.js +14 -15
  11. package/dist/bin/pushary-cowork.js +5 -6
  12. package/dist/bin/pushary-daemon.js +27 -28
  13. package/dist/bin/pushary-disconnect.js +17 -18
  14. package/dist/bin/pushary-doctor.js +104 -41
  15. package/dist/bin/pushary-elicitation-hook.js +24 -25
  16. package/dist/bin/pushary-gemini-bridge.js +12 -13
  17. package/dist/bin/pushary-gemini-hook.js +27 -28
  18. package/dist/bin/pushary-hook.js +31 -32
  19. package/dist/bin/pushary-login.js +14 -16
  20. package/dist/bin/pushary-logout.js +8 -9
  21. package/dist/bin/pushary-mcp.d.ts +1 -0
  22. package/dist/bin/pushary-mcp.js +56 -0
  23. package/dist/bin/pushary-mode.js +10 -11
  24. package/dist/bin/pushary-notification-hook.js +27 -28
  25. package/dist/bin/pushary-opencode-hook.js +26 -27
  26. package/dist/bin/pushary-permission-denied-hook.js +31 -32
  27. package/dist/bin/pushary-permission-hook.js +30 -31
  28. package/dist/bin/pushary-post-hook.js +27 -28
  29. package/dist/bin/pushary-prompt-hook.js +27 -28
  30. package/dist/bin/pushary-session-end-hook.js +27 -28
  31. package/dist/bin/pushary-session-start-hook.js +31 -32
  32. package/dist/bin/pushary-setup.js +235 -100
  33. package/dist/bin/pushary-stats.js +5 -6
  34. package/dist/bin/pushary-status.js +16 -17
  35. package/dist/bin/pushary-stop-hook.js +27 -28
  36. package/dist/bin/pushary-stopfailure-hook.js +27 -28
  37. package/dist/bin/pushary-suggestions.js +5 -5
  38. package/dist/bin/pushary-transcript-register.js +19 -20
  39. package/dist/bin/pushary-transcripts.js +7 -8
  40. package/dist/bin/pushary-upgrade.js +20 -21
  41. package/dist/bin/pushary-wait.js +10 -11
  42. package/dist/bin/pushary.js +6 -7
  43. package/dist/chunk-2FU43B5Q.js +120 -0
  44. package/dist/{chunk-6NLWK6ZV.js → chunk-3QE3BHBW.js} +2 -2
  45. package/dist/{chunk-NYMPLNV3.js → chunk-3QORH5EJ.js} +3 -3
  46. package/dist/{chunk-LFMOYHPY.js → chunk-3T35OE7C.js} +2 -2
  47. package/dist/{chunk-5U3FJ6YF.js → chunk-42XR73I2.js} +8 -8
  48. package/dist/{chunk-UGKDBJJX.js → chunk-43SSQCWO.js} +3 -3
  49. package/dist/{chunk-K32C2RGK.js → chunk-454KMJHF.js} +17 -9
  50. package/dist/{chunk-YUGGNZSF.js → chunk-4C4NRDIC.js} +1 -1
  51. package/dist/{chunk-HUB4Q35G.js → chunk-55RO62FV.js} +1 -1
  52. package/dist/{chunk-YQMFGWBD.js → chunk-62TEPRWQ.js} +1 -1
  53. package/dist/{chunk-P4BNYJ5Q.js → chunk-6PV2JQ64.js} +2 -2
  54. package/dist/{chunk-53DN77WB.js → chunk-6SJQ442W.js} +2 -2
  55. package/dist/{chunk-UAP556WK.js → chunk-7GI6QC3M.js} +2 -2
  56. package/dist/{chunk-D3K2FPPJ.js → chunk-7GYGVQBU.js} +8 -8
  57. package/dist/{chunk-OZE2TQX5.js → chunk-AAGLDXH4.js} +5 -5
  58. package/dist/{chunk-XJG2FUWS.js → chunk-AHWJHLG5.js} +9 -30
  59. package/dist/{chunk-P4UYILQK.js → chunk-BYVB3RX3.js} +2 -2
  60. package/dist/{chunk-EA3IELHP.js → chunk-EIZW73P5.js} +6 -2
  61. package/dist/{chunk-BY2CRWBO.js → chunk-H6JV44TE.js} +1 -1
  62. package/dist/{chunk-3LU74H52.js → chunk-IGBDOZUO.js} +1 -1
  63. package/dist/{chunk-N62KAMMY.js → chunk-JMBG47WV.js} +30 -1
  64. package/dist/{chunk-DESAUCH2.js → chunk-JTQDP4ZL.js} +4 -6
  65. package/dist/{chunk-LJEL7IB5.js → chunk-KBLIVEFJ.js} +5 -5
  66. package/dist/{chunk-VOCZHOXV.js → chunk-KSNAAMU5.js} +4 -4
  67. package/dist/{chunk-5UWV5GHM.js → chunk-MCNS4725.js} +1 -1
  68. package/dist/{chunk-I3XJATMR.js → chunk-MWVCDP64.js} +1 -1
  69. package/dist/chunk-NAAZCNKI.js +757 -0
  70. package/dist/{chunk-3VZX4NSP.js → chunk-NID4UZDN.js} +1 -1
  71. package/dist/{chunk-BJENQBMH.js → chunk-NQFGVAT6.js} +8 -4
  72. package/dist/{chunk-XOMH53NB.js → chunk-O5JD7UI5.js} +1 -1
  73. package/dist/{chunk-5RUIFDTP.js → chunk-O5PRIYFZ.js} +30 -2
  74. package/dist/{chunk-OSJEMXSR.js → chunk-OAL44FM2.js} +1 -1
  75. package/dist/{chunk-66H2QQAK.js → chunk-OTZHT34O.js} +1 -1
  76. package/dist/{chunk-DZTKLE7Q.js → chunk-P5CBNSYL.js} +1 -1
  77. package/dist/{chunk-GBL4BTG3.js → chunk-Q7QRR6YL.js} +2 -2
  78. package/dist/{chunk-YPONELWS.js → chunk-QPR33SHS.js} +6 -6
  79. package/dist/{chunk-LDRGVXLR.js → chunk-SNWNA3MQ.js} +1 -1
  80. package/dist/{chunk-5SWQZ6HY.js → chunk-SVEMF2VO.js} +4 -4
  81. package/dist/{chunk-VHNDE3ZD.js → chunk-UPKP67TA.js} +2 -2
  82. package/dist/{chunk-PJF7L7AA.js → chunk-VCMFKZON.js} +2 -2
  83. package/dist/{chunk-H6XU22TN.js → chunk-WM3U2RUK.js} +8 -8
  84. package/dist/{chunk-ZA5UXRNE.js → chunk-WSC53O7I.js} +3 -3
  85. package/dist/{chunk-7CLTSZOL.js → chunk-WZWXBTRF.js} +3 -3
  86. package/dist/{chunk-YXPGFRRW.js → chunk-XDASEYRS.js} +3 -3
  87. package/dist/{chunk-CAS7GFWI.js → chunk-XFNVG3OV.js} +75 -5
  88. package/dist/{chunk-I2YUMZLE.js → chunk-XMN37YJH.js} +1 -1
  89. package/dist/{chunk-LQI7W4RG.js → chunk-XPMOCJHN.js} +1 -1
  90. package/dist/{chunk-VA2R64I7.js → chunk-XPTCPU6V.js} +1 -1
  91. package/dist/{chunk-PBKEYMAO.js → chunk-Y6GKOZBT.js} +1 -1
  92. package/dist/{chunk-JOGA3TL2.js → chunk-YQN7S57T.js} +6 -6
  93. package/dist/{chunk-R4HVHTNA.js → chunk-YZKS3ME3.js} +2 -2
  94. package/dist/chunk-ZEMSCGDD.js +87 -0
  95. package/dist/{chunk-EREBZHN2.js → chunk-ZIIYTQHC.js} +4 -4
  96. package/dist/{reapply-4DAJKNVP.js → reapply-66GQIBXN.js} +9 -10
  97. package/dist/src/index.js +19 -20
  98. package/package.json +2 -1
  99. package/dist/chunk-GU3EJCVV.js +0 -43
  100. package/dist/chunk-HWJW3CPO.js +0 -65
  101. package/dist/chunk-NFH73H5B.js +0 -360
  102. package/dist/chunk-P32LPT2L.js +0 -6
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_BUDGETS,
3
3
  OPENCODE_APPROVAL_EVENT
4
- } from "./chunk-CAS7GFWI.js";
4
+ } from "./chunk-XFNVG3OV.js";
5
5
 
6
6
  // src/opencode-plugin.ts
7
7
  var OPENCODE_PLUGIN_MARKER = "pushary-opencode-plugin w1";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  installNetworkDefaults
3
- } from "./chunk-DESAUCH2.js";
3
+ } from "./chunk-JTQDP4ZL.js";
4
4
  import {
5
5
  getBaseUrl
6
- } from "./chunk-OSJEMXSR.js";
6
+ } from "./chunk-OAL44FM2.js";
7
7
 
8
8
  // src/retry.ts
9
9
  var isRetryable = (err) => {
@@ -35,7 +35,7 @@ var withRetry = async (fn, options = {}) => {
35
35
 
36
36
  // src/mcp-http.ts
37
37
  installNetworkDefaults();
38
- var parseSseJson = (body) => {
38
+ var parseSseMessages = (body) => {
39
39
  const messages = [];
40
40
  for (const event of body.split(/\r?\n\r?\n/)) {
41
41
  const data = event.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n").trim();
@@ -45,7 +45,10 @@ var parseSseJson = (body) => {
45
45
  } catch {
46
46
  }
47
47
  }
48
- const message = messages.at(-1);
48
+ return messages;
49
+ };
50
+ var parseSseJson = (body) => {
51
+ const message = parseSseMessages(body).at(-1);
49
52
  if (!message) throw new Error("Empty response from Pushary");
50
53
  return message;
51
54
  };
@@ -112,6 +115,7 @@ var callMcpTool = async (apiKey, toolName, params, options = {}) => {
112
115
 
113
116
  export {
114
117
  withRetry,
118
+ parseSseMessages,
115
119
  sendMcpRequest,
116
120
  callMcpTool
117
121
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  redactSecrets
3
- } from "./chunk-CAS7GFWI.js";
3
+ } from "./chunk-XFNVG3OV.js";
4
4
 
5
5
  // src/crypto.ts
6
6
  import nacl from "tweetnacl";
@@ -1,3 +1,28 @@
1
+ // src/cli/terminal-row.ts
2
+ var visibleLength = (text) => text.replace(/\x1b\[[0-9;]*m/g, "").length;
3
+ var clipToRow = (text, columns) => {
4
+ const budget = columns - 4;
5
+ if (budget <= 1 || visibleLength(text) <= budget) return text;
6
+ let visible = 0;
7
+ let out = "";
8
+ for (let i = 0; i < text.length; i += 1) {
9
+ const escape = /^\x1b\[[0-9;]*m/.exec(text.slice(i));
10
+ if (escape) {
11
+ out += escape[0];
12
+ i += escape[0].length - 1;
13
+ continue;
14
+ }
15
+ if (visible >= budget - 1) break;
16
+ out += text[i];
17
+ visible += 1;
18
+ }
19
+ return `${out}\u2026`;
20
+ };
21
+ var terminalColumns = (stream = process.stdout) => {
22
+ const columns = stream.columns;
23
+ return typeof columns === "number" && columns > 0 ? columns : 80;
24
+ };
25
+
1
26
  // src/cli/io.ts
2
27
  var truthyLevel = (value) => {
3
28
  if (value === void 0) return void 0;
@@ -15,6 +40,7 @@ var useColor = (context = {}, stream = process.stdout) => {
15
40
  return stream.isTTY === true;
16
41
  };
17
42
  var SPINNER_FRAMES = [" ", ". ", ".. ", "..."];
43
+ var SPINNER_FRAME_WIDTH = SPINNER_FRAMES[0].length + 1;
18
44
  var SPINNER_INTERVAL_MS = 200;
19
45
  var describeError = (err) => {
20
46
  if (err instanceof Error) {
@@ -45,7 +71,7 @@ var createIo = (stream = process.stdout, context = {}) => {
45
71
  `);
46
72
  };
47
73
  const spinner = async (label, fn, options = {}) => {
48
- if (!color) {
74
+ if (stream.isTTY !== true) {
49
75
  try {
50
76
  await fn();
51
77
  line(` ${check()} ${label}`);
@@ -57,7 +83,7 @@ var createIo = (stream = process.stdout, context = {}) => {
57
83
  }
58
84
  let frame = 0;
59
85
  const timer = setInterval(() => {
60
- stream.write(`\r ${dim(SPINNER_FRAMES[frame++ % SPINNER_FRAMES.length])} ${label}`);
86
+ stream.write(`\r ${dim(SPINNER_FRAMES[frame++ % SPINNER_FRAMES.length])} ${clipToRow(label, terminalColumns(stream) - SPINNER_FRAME_WIDTH)}\x1B[K`);
61
87
  }, SPINNER_INTERVAL_MS);
62
88
  try {
63
89
  await fn();
@@ -75,6 +101,8 @@ var createIo = (stream = process.stdout, context = {}) => {
75
101
  };
76
102
 
77
103
  export {
104
+ clipToRow,
105
+ terminalColumns,
78
106
  useColor,
79
107
  createIo
80
108
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NPX_LATEST_COMMAND
3
- } from "./chunk-EA3IELHP.js";
3
+ } from "./chunk-EIZW73P5.js";
4
4
 
5
5
  // src/config.ts
6
6
  import { readFileSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getBaseUrl
3
- } from "./chunk-OSJEMXSR.js";
3
+ } from "./chunk-OAL44FM2.js";
4
4
 
5
5
  // src/transcript-api.ts
6
6
  var fetchTranscriptRecipients = async (apiKey, baseUrl = getBaseUrl()) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-K32C2RGK.js";
3
+ } from "./chunk-454KMJHF.js";
4
4
  import {
5
5
  writeFileAtomic
6
6
  } from "./chunk-T7E75EKA.js";
@@ -2,10 +2,10 @@ import {
2
2
  resolveBinary,
3
3
  resolveGlobalPackageVersion,
4
4
  resolvePackageVersionFromBinary
5
- } from "./chunk-K32C2RGK.js";
5
+ } from "./chunk-454KMJHF.js";
6
6
  import {
7
7
  MANAGED_PROVIDERS
8
- } from "./chunk-CAS7GFWI.js";
8
+ } from "./chunk-XFNVG3OV.js";
9
9
 
10
10
  // src/live-capabilities.ts
11
11
  var CLAUDE_BRIDGE_CAPABILITY = "claude-bridge";
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  detectClaudeVersion
3
- } from "./chunk-PBKEYMAO.js";
3
+ } from "./chunk-Y6GKOZBT.js";
4
4
  import {
5
5
  ensureCodexTrustsPusharyHooks
6
- } from "./chunk-53DN77WB.js";
6
+ } from "./chunk-6SJQ442W.js";
7
7
  import {
8
8
  addClaudeMcpServer,
9
9
  addPusharyHooks,
10
10
  addPusharyToolPermissions
11
- } from "./chunk-ZA5UXRNE.js";
11
+ } from "./chunk-WSC53O7I.js";
12
12
  import {
13
13
  claudeUnprovenHolds,
14
14
  claudeWired,
15
15
  codexUnprovenHolds,
16
16
  codexWired,
17
17
  geminiWired
18
- } from "./chunk-YXPGFRRW.js";
18
+ } from "./chunk-XDASEYRS.js";
19
19
  import {
20
20
  CLAUDE_HOOK_BINARY,
21
21
  CLAUDE_HOOK_EVENTS,
@@ -27,7 +27,7 @@ import {
27
27
  needsReregistration,
28
28
  registrationSignatures,
29
29
  supportedClaudeEvents
30
- } from "./chunk-7CLTSZOL.js";
30
+ } from "./chunk-WZWXBTRF.js";
31
31
  import {
32
32
  CODEX_HOOK_BINARY,
33
33
  addCodexHookTrust,
@@ -47,7 +47,7 @@ import {
47
47
  registrationHolderOf,
48
48
  resolveGlobalBinary,
49
49
  vscodePluginMcp
50
- } from "./chunk-K32C2RGK.js";
50
+ } from "./chunk-454KMJHF.js";
51
51
  import {
52
52
  readJsonSafe,
53
53
  writeFileAtomic,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-K32C2RGK.js";
3
+ } from "./chunk-454KMJHF.js";
4
4
  import {
5
5
  readJsonSafe
6
6
  } from "./chunk-T7E75EKA.js";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  AGENT_CHOICES
3
- } from "./chunk-I2YUMZLE.js";
3
+ } from "./chunk-XMN37YJH.js";
4
4
  import {
5
5
  isBridgeLocator
6
- } from "./chunk-I3XJATMR.js";
6
+ } from "./chunk-MWVCDP64.js";
7
7
  import {
8
8
  pusharyHookExecutable
9
- } from "./chunk-YXPGFRRW.js";
9
+ } from "./chunk-XDASEYRS.js";
10
10
  import {
11
11
  BELL_HOOK_BINARY
12
- } from "./chunk-LQI7W4RG.js";
12
+ } from "./chunk-XPMOCJHN.js";
13
13
 
14
14
  // src/setup/hook-ownership.ts
15
15
  var commandsIn = (value) => {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  configFilePath
3
- } from "./chunk-OSJEMXSR.js";
3
+ } from "./chunk-OAL44FM2.js";
4
4
  import {
5
5
  normalizeInstallSource
6
- } from "./chunk-CAS7GFWI.js";
6
+ } from "./chunk-XFNVG3OV.js";
7
7
 
8
8
  // src/install-source.ts
9
9
  import { readFileSync } from "fs";
@@ -3,11 +3,11 @@ import {
3
3
  decodePublicKey,
4
4
  generateSessionKey,
5
5
  wrapSessionKey
6
- } from "./chunk-XOMH53NB.js";
6
+ } from "./chunk-O5JD7UI5.js";
7
7
  import {
8
8
  fetchTranscriptRecipients,
9
9
  uploadTranscriptRecords
10
- } from "./chunk-66H2QQAK.js";
10
+ } from "./chunk-OTZHT34O.js";
11
11
 
12
12
  // src/live-session.ts
13
13
  var MAX_TRANSCRIPT_QUEUE = 100;
@@ -1,30 +1,30 @@
1
1
  import {
2
2
  NOTIFICATION_PUSH_TYPES,
3
3
  POSTTOOLUSE_MIRROR_ONLY_TOOLS
4
- } from "./chunk-YUGGNZSF.js";
4
+ } from "./chunk-4C4NRDIC.js";
5
5
  import {
6
6
  cancelQuestion,
7
7
  isPolicyConfig,
8
8
  sendNotification,
9
9
  waitForAnswer
10
- } from "./chunk-EREBZHN2.js";
10
+ } from "./chunk-ZIIYTQHC.js";
11
11
  import {
12
12
  clientErrorKindOf,
13
13
  reportClientError
14
- } from "./chunk-VOCZHOXV.js";
14
+ } from "./chunk-KSNAAMU5.js";
15
15
  import {
16
16
  withRetry
17
- } from "./chunk-BJENQBMH.js";
17
+ } from "./chunk-NQFGVAT6.js";
18
18
  import {
19
19
  getMachineId
20
- } from "./chunk-DZTKLE7Q.js";
20
+ } from "./chunk-P5CBNSYL.js";
21
21
  import {
22
22
  reportedInstallSource
23
- } from "./chunk-VHNDE3ZD.js";
23
+ } from "./chunk-UPKP67TA.js";
24
24
  import {
25
25
  getApiKey,
26
26
  getBaseUrl
27
- } from "./chunk-OSJEMXSR.js";
27
+ } from "./chunk-OAL44FM2.js";
28
28
  import {
29
29
  ACTION_BODY_MAX,
30
30
  AGENT_LABELS_BY_TYPE,
@@ -48,7 +48,7 @@ import {
48
48
  resolveAutoResolveOrigin,
49
49
  resolvePolicy,
50
50
  toToolLookup
51
- } from "./chunk-CAS7GFWI.js";
51
+ } from "./chunk-XFNVG3OV.js";
52
52
 
53
53
  // src/policy.ts
54
54
  import { createHash } from "crypto";
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  CLAUDE_HOOK_EVENTS,
3
3
  supportedClaudeEvents
4
- } from "./chunk-7CLTSZOL.js";
4
+ } from "./chunk-WZWXBTRF.js";
5
5
  import {
6
6
  guardBinary,
7
7
  holdBudgetOf,
8
8
  isProtectedByScope,
9
9
  registerHookEntry
10
- } from "./chunk-K32C2RGK.js";
10
+ } from "./chunk-454KMJHF.js";
11
11
  import {
12
12
  HOOK_LOCATOR_BINARY,
13
13
  withHookHoldBudget
14
- } from "./chunk-CAS7GFWI.js";
14
+ } from "./chunk-XFNVG3OV.js";
15
15
 
16
16
  // src/claude-config.ts
17
17
  import { join } from "path";
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  NOTIFICATION_MATCHED_TYPES,
3
3
  POSTTOOLUSE_MIRRORED_TOOLS
4
- } from "./chunk-YUGGNZSF.js";
4
+ } from "./chunk-4C4NRDIC.js";
5
5
  import {
6
6
  isProtectedByScope,
7
7
  registerHookEntry
8
- } from "./chunk-K32C2RGK.js";
8
+ } from "./chunk-454KMJHF.js";
9
9
  import {
10
10
  CLAUDE_PRETOOLUSE_MATCHER,
11
11
  HOOK_BUDGETS,
12
12
  HOOK_LOCATOR_BINARY
13
- } from "./chunk-CAS7GFWI.js";
13
+ } from "./chunk-XFNVG3OV.js";
14
14
 
15
15
  // src/gemini-config.ts
16
16
  var GEMINI_HOOK_BINARY = "pushary-gemini-hook";
@@ -2,17 +2,17 @@ import {
2
2
  CLAUDE_HOOK_EVENTS,
3
3
  GEMINI_HOOK_EVENTS,
4
4
  hasGeminiHooks
5
- } from "./chunk-7CLTSZOL.js";
5
+ } from "./chunk-WZWXBTRF.js";
6
6
  import {
7
7
  CODEX_HOOK_EVENTS,
8
8
  hasCodexHooks,
9
9
  holdBudgetOf
10
- } from "./chunk-K32C2RGK.js";
10
+ } from "./chunk-454KMJHF.js";
11
11
  import {
12
12
  CURSOR_GATE_EVENTS,
13
13
  HOOK_LOCATOR_BINARY,
14
14
  hookCommandHoldBudget
15
- } from "./chunk-CAS7GFWI.js";
15
+ } from "./chunk-XFNVG3OV.js";
16
16
 
17
17
  // src/diagnostics/wiring.ts
18
18
  var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -151,6 +151,13 @@ var AGENTS = {
151
151
  setupCommand: AGENT_HOOKS_SETUP_COMMAND,
152
152
  enforcementDetail: "Shell, writes, edits and web fetches when OpenCode itself asks for permission."
153
153
  },
154
+ fx: {
155
+ ...defaults,
156
+ label: "fx",
157
+ connectVia: "Local MCP bridge",
158
+ setupCommand: AGENT_HOOKS_SETUP_COMMAND,
159
+ capabilityNote: "fx has no hooks that other tools can register, so Pushary cannot answer fx's own approval prompts. Setup turns off fx's terminal question tool so fx's agent asks through Pushary. fx's full-access mode ignores that setting; there the agent is only instructed to ask through Pushary."
160
+ },
154
161
  qwen_code: {
155
162
  ...defaults,
156
163
  label: "Qwen Code",
@@ -467,8 +474,8 @@ var SECRET_REDACTION_RULES = [
467
474
  { pattern: /\bbearer\s+[A-Za-z0-9._~+/=-]+/gi, replacement: "bearer [redacted]" },
468
475
  { pattern: /\bauthorization:\s*\S+/gi, replacement: "authorization: [redacted]" },
469
476
  {
470
- pattern: /((?:secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)\s*[=:]\s*)("[^"]*"|'[^']*'|\S+)/gi,
471
- replacement: "$1[redacted]"
477
+ pattern: /((?:secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)["']?\s*[=:]\s*)(?:(")(?:\\[\s\S]|[^"\\])*(?:"|\\?$)|(')[^']*(?:'|$)|\S+)/gi,
478
+ replacement: "$1$2$3[redacted]$2$3"
472
479
  }
473
480
  ];
474
481
  var HIGH_ENTROPY_RULE = { pattern: /[A-Za-z0-9+/]{40,}={0,2}/g, replacement: "[redacted]" };
@@ -497,6 +504,7 @@ var SETUP_AGENT_CHOICES = [
497
504
  "cursor",
498
505
  "vscode",
499
506
  "opencode",
507
+ "fx",
500
508
  ...COMPATIBLE_AGENT_TYPES,
501
509
  "custom"
502
510
  ];
@@ -1324,8 +1332,7 @@ var DESTRUCTIVE_SUBCOMMANDS = /* @__PURE__ */ new Set([
1324
1332
  var DATA_LOSS_COMMAND_PATTERNS = [
1325
1333
  "Bash(git branch -D:*)",
1326
1334
  "Bash(git branch --delete:*)",
1327
- "Bash(git checkout --:*)",
1328
- "Bash(git checkout .:*)",
1335
+ "Bash(git checkout:*)",
1329
1336
  "Bash(git restore:*)",
1330
1337
  "Bash(git stash drop:*)",
1331
1338
  "Bash(git stash clear:*)",
@@ -2498,6 +2505,63 @@ var hookActivationResult = (report) => {
2498
2505
  return report && !report.truncated && report.evidence.length === 1 ? report.evidence[0].result : "unverified";
2499
2506
  };
2500
2507
 
2508
+ // src/cli/version.ts
2509
+ import { readFileSync } from "fs";
2510
+ import { dirname, join, parse } from "path";
2511
+ import { fileURLToPath } from "url";
2512
+ var PACKAGE_NAME = "@pushary/agent-hooks";
2513
+ var UNKNOWN_VERSION = "0.0.0";
2514
+ var findOwnPackageJson = (start) => {
2515
+ const { root } = parse(start);
2516
+ let dir = start;
2517
+ while (true) {
2518
+ const candidate = join(dir, "package.json");
2519
+ try {
2520
+ const pkg = JSON.parse(readFileSync(candidate, "utf-8"));
2521
+ if (pkg.name === PACKAGE_NAME) return candidate;
2522
+ } catch {
2523
+ }
2524
+ if (dir === root) return void 0;
2525
+ const parent = dirname(dir);
2526
+ if (parent === dir) return void 0;
2527
+ dir = parent;
2528
+ }
2529
+ };
2530
+ var getPackageVersion = () => {
2531
+ const root = ownPackageRoot();
2532
+ return (root === void 0 ? void 0 : packageVersionAt(root)) ?? UNKNOWN_VERSION;
2533
+ };
2534
+ var ownPackageRoot = () => {
2535
+ try {
2536
+ const found = findOwnPackageJson(dirname(fileURLToPath(import.meta.url)));
2537
+ return found ? dirname(found) : void 0;
2538
+ } catch {
2539
+ return void 0;
2540
+ }
2541
+ };
2542
+ var packageVersionAt = (packageRoot) => {
2543
+ try {
2544
+ const manifest = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf-8"));
2545
+ const version = manifest && typeof manifest === "object" && "version" in manifest ? manifest.version : void 0;
2546
+ return typeof version === "string" ? version : void 0;
2547
+ } catch {
2548
+ return void 0;
2549
+ }
2550
+ };
2551
+ var isNewerVersion = (candidate, current) => {
2552
+ const a = candidate.split(".").map((part) => parseInt(part, 10) || 0);
2553
+ const b = current.split(".").map((part) => parseInt(part, 10) || 0);
2554
+ for (let i = 0; i < 3; i++) {
2555
+ if ((a[i] ?? 0) > (b[i] ?? 0)) return true;
2556
+ if ((a[i] ?? 0) < (b[i] ?? 0)) return false;
2557
+ }
2558
+ return false;
2559
+ };
2560
+ var RELEASE_VERSION = /^\d+\.\d+\.\d+$/;
2561
+ var isReleaseVersion = (value) => RELEASE_VERSION.test(value);
2562
+ var majorOf = (version) => parseInt(version.split(".")[0] ?? "", 10) || 0;
2563
+ var isSameMajorVersion = (candidate, current) => majorOf(candidate) === majorOf(current);
2564
+
2501
2565
  export {
2502
2566
  CLAUDE_CONNECTOR_URL,
2503
2567
  CLAUDE_CONNECTOR_GUIDE,
@@ -2600,5 +2664,11 @@ export {
2600
2664
  readElicitationFields,
2601
2665
  planElicitationAsk,
2602
2666
  elicitationContent,
2603
- elicitationContentFromAnswers
2667
+ elicitationContentFromAnswers,
2668
+ getPackageVersion,
2669
+ ownPackageRoot,
2670
+ packageVersionAt,
2671
+ isNewerVersion,
2672
+ isReleaseVersion,
2673
+ isSameMajorVersion
2604
2674
  };
@@ -9,7 +9,7 @@ import {
9
9
  SETUP_CONNECT_MODES,
10
10
  isSetupConnectMode,
11
11
  isValidApiKey
12
- } from "./chunk-CAS7GFWI.js";
12
+ } from "./chunk-XFNVG3OV.js";
13
13
 
14
14
  // src/setup/options.ts
15
15
  var AGENT_CHOICES = SETUP_AGENT_CHOICES;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  guardBinary
3
- } from "./chunk-K32C2RGK.js";
3
+ } from "./chunk-454KMJHF.js";
4
4
 
5
5
  // src/bell/install.ts
6
6
  import { join } from "path";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readTranscriptPreference
3
- } from "./chunk-R4HVHTNA.js";
3
+ } from "./chunk-YZKS3ME3.js";
4
4
 
5
5
  // src/transcript-setting.ts
6
6
  var transcriptEnvironmentPreference = () => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseVersion
3
- } from "./chunk-7CLTSZOL.js";
3
+ } from "./chunk-WZWXBTRF.js";
4
4
 
5
5
  // src/setup/agent-probe.ts
6
6
  import { execSync } from "child_process";
@@ -2,27 +2,27 @@ import {
2
2
  detectProviderLiveCapabilities,
3
3
  hasSpawnProvider,
4
4
  resolveControlPolicy
5
- } from "./chunk-GBL4BTG3.js";
5
+ } from "./chunk-Q7QRR6YL.js";
6
6
  import {
7
7
  daemonHasRemoteProof,
8
8
  daemonServiceManagerAvailable,
9
9
  hasDaemonServiceDefinition,
10
10
  readDaemonNeedsLogin,
11
11
  readDaemonStatus
12
- } from "./chunk-OZE2TQX5.js";
12
+ } from "./chunk-AAGLDXH4.js";
13
13
  import {
14
14
  readControlMode,
15
15
  readKeySource
16
- } from "./chunk-R4HVHTNA.js";
16
+ } from "./chunk-YZKS3ME3.js";
17
17
  import {
18
18
  getMachineId
19
- } from "./chunk-DZTKLE7Q.js";
19
+ } from "./chunk-P5CBNSYL.js";
20
20
  import {
21
21
  getBaseUrl
22
- } from "./chunk-OSJEMXSR.js";
22
+ } from "./chunk-OAL44FM2.js";
23
23
  import {
24
24
  getPackageVersion
25
- } from "./chunk-HWJW3CPO.js";
25
+ } from "./chunk-XFNVG3OV.js";
26
26
 
27
27
  // src/machines.ts
28
28
  import { hostname } from "os";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveInstallSourceFor
3
- } from "./chunk-VHNDE3ZD.js";
3
+ } from "./chunk-UPKP67TA.js";
4
4
  import {
5
5
  backupFile,
6
6
  readJsonSafe,
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-T7E75EKA.js";
10
10
  import {
11
11
  configFilePath
12
- } from "./chunk-OSJEMXSR.js";
12
+ } from "./chunk-OAL44FM2.js";
13
13
 
14
14
  // src/shell-alias.ts
15
15
  import { homedir } from "os";
@@ -0,0 +1,87 @@
1
+ import {
2
+ NPX_LATEST_COMMAND
3
+ } from "./chunk-EIZW73P5.js";
4
+
5
+ // src/setup/agent-failure.ts
6
+ var AgentConfigError = class extends Error {
7
+ kind;
8
+ filePath;
9
+ constructor(kind, filePath, message) {
10
+ super(message);
11
+ this.name = "AgentConfigError";
12
+ this.kind = kind;
13
+ this.filePath = filePath;
14
+ }
15
+ };
16
+ var configFailureKind = (readFailure) => readFailure === "unparseable" ? "config-unparseable" : "config-unreadable";
17
+ var AGENT_FAILURE_DETAILS = {
18
+ "not-wired": "reported success but its config is not there.",
19
+ "app-account-mismatch": "Mac app hooks kept, but their Pushary account could not be matched to this setup."
20
+ };
21
+ var describedAgentFailure = (agent, kind) => ({
22
+ agent,
23
+ kind,
24
+ detail: AGENT_FAILURE_DETAILS[kind]
25
+ });
26
+ var agentFailureFromError = (agent, error, describeError) => ({
27
+ agent,
28
+ kind: error instanceof AgentConfigError ? error.kind : "installer-error",
29
+ detail: describeError(error)
30
+ });
31
+ var retryAgentCommand = (agent) => `${NPX_LATEST_COMMAND} setup --agents ${agent}`;
32
+ var REMAINING_AGENTS_CONTINUE = "Other agents will continue. Re-run setup to retry.";
33
+ var afterAgentFailureNote = (agentsStillToSetUp) => agentsStillToSetUp > 0 ? REMAINING_AGENTS_CONTINUE : null;
34
+ var failedAgentsContext = (configuredAgentNames) => configuredAgentNames.length > 0 ? `(configured: ${configuredAgentNames.join(", ")})` : null;
35
+ var agentFailureWire = (failures) => failures.map(({ agent, kind }) => ({ agent, kind }));
36
+
37
+ // src/diagnostics/service-runtime.ts
38
+ var unescapeXml = (value) => value.replaceAll("&quot;", '"').replaceAll("&apos;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
39
+ var unquoteSystemd = (value) => value.replaceAll('\\"', '"').replaceAll("\\\\", "\\").replaceAll("%%", "%");
40
+ var readServiceExecPath = (contents, platform) => {
41
+ if (platform === "darwin") {
42
+ const program = contents.match(/<key>ProgramArguments<\/key>\s*<array>\s*<string>([^<]*)<\/string>/)?.[1];
43
+ return program ? unescapeXml(program) : null;
44
+ }
45
+ if (platform === "linux") {
46
+ const exec = contents.match(/^ExecStart="((?:[^"\\]|\\.)*)"/m)?.[1];
47
+ return exec ? unquoteSystemd(exec) : null;
48
+ }
49
+ if (platform === "win32") {
50
+ const command = contents.match(/<Command>([^<]*)<\/Command>/)?.[1];
51
+ return command ? unescapeXml(command) : null;
52
+ }
53
+ return null;
54
+ };
55
+ var MANAGER_SEGMENTS = [
56
+ [".nvm", "nvm"],
57
+ ["nvm", "nvm"],
58
+ ["fnm", "fnm"],
59
+ [".fnm", "fnm"],
60
+ [".volta", "volta"],
61
+ ["volta", "volta"],
62
+ [".asdf", "asdf"],
63
+ ["asdf", "asdf"]
64
+ ];
65
+ var versionManagerOf = (execPath) => {
66
+ const segments = execPath.split(/[/\\]/);
67
+ for (const segment of segments) {
68
+ const hit = MANAGER_SEGMENTS.find(([name]) => name === segment);
69
+ if (hit) return hit[1];
70
+ }
71
+ return null;
72
+ };
73
+ var describeVersionManagerPin = (execPath, manager) => `The background service is pinned to ${execPath}, which ${manager} manages. Switching Node versions strands it; run pushary daemon install afterwards.`;
74
+
75
+ export {
76
+ AgentConfigError,
77
+ configFailureKind,
78
+ describedAgentFailure,
79
+ agentFailureFromError,
80
+ retryAgentCommand,
81
+ afterAgentFailureNote,
82
+ failedAgentsContext,
83
+ agentFailureWire,
84
+ readServiceExecPath,
85
+ versionManagerOf,
86
+ describeVersionManagerPin
87
+ };