@pushary/agent-hooks 1.9.7 → 1.9.9

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 (111) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +3 -3
  3. package/data/cursor-plugin/README.md +3 -7
  4. package/data/vscode-plugin/README.md +1 -1
  5. package/dist/bin/pushary-bell-hook.js +22 -24
  6. package/dist/bin/pushary-bell.js +13 -13
  7. package/dist/bin/pushary-claude.js +28 -30
  8. package/dist/bin/pushary-clean.js +113 -94
  9. package/dist/bin/pushary-codex-bridge.js +20 -20
  10. package/dist/bin/pushary-codex-hook.js +36 -38
  11. package/dist/bin/pushary-codex.js +13 -13
  12. package/dist/bin/pushary-connect.js +48 -22
  13. package/dist/bin/pushary-cowork.js +5 -5
  14. package/dist/bin/pushary-daemon.js +50 -40
  15. package/dist/bin/pushary-disconnect.js +188 -56
  16. package/dist/bin/pushary-doctor.js +105 -85
  17. package/dist/bin/pushary-elicitation-hook.js +25 -27
  18. package/dist/bin/pushary-gemini-bridge.js +13 -13
  19. package/dist/bin/pushary-gemini-hook.js +31 -33
  20. package/dist/bin/pushary-hook.js +36 -39
  21. package/dist/bin/pushary-login.js +12 -12
  22. package/dist/bin/pushary-logout.js +105 -42
  23. package/dist/bin/pushary-mcp.js +9 -9
  24. package/dist/bin/pushary-mode.js +28 -31
  25. package/dist/bin/pushary-notification-hook.js +29 -32
  26. package/dist/bin/pushary-opencode-hook.js +30 -32
  27. package/dist/bin/pushary-permission-denied-hook.js +30 -33
  28. package/dist/bin/pushary-permission-hook.js +33 -36
  29. package/dist/bin/pushary-post-hook.js +30 -33
  30. package/dist/bin/pushary-prompt-hook.js +29 -32
  31. package/dist/bin/pushary-session-end-hook.js +29 -32
  32. package/dist/bin/pushary-session-start-hook.js +33 -36
  33. package/dist/bin/pushary-setup.js +168 -160
  34. package/dist/bin/pushary-stats.js +5 -5
  35. package/dist/bin/pushary-status.js +65 -19
  36. package/dist/bin/pushary-stop-hook.js +29 -32
  37. package/dist/bin/pushary-stopfailure-hook.js +29 -32
  38. package/dist/bin/pushary-suggestions.js +19 -21
  39. package/dist/bin/pushary-transcript-register.js +18 -20
  40. package/dist/bin/pushary-transcripts.js +7 -7
  41. package/dist/bin/pushary-upgrade.js +50 -26
  42. package/dist/bin/pushary-wait.js +23 -19
  43. package/dist/bin/pushary.js +15 -14
  44. package/dist/{chunk-4FK6RZVJ.js → chunk-462EQA6K.js} +1 -1
  45. package/dist/{chunk-STQRUH3S.js → chunk-5DCDQ5VW.js} +59 -15
  46. package/dist/{chunk-JXISQ7DT.js → chunk-5N5L6DNN.js} +3 -3
  47. package/dist/{chunk-QR6VE5ME.js → chunk-5RGA636G.js} +79 -17
  48. package/dist/{chunk-L76HTPU6.js → chunk-6AYSKVLL.js} +3 -3
  49. package/dist/{chunk-NIBFSARF.js → chunk-6EBGOHDJ.js} +33 -13
  50. package/dist/{chunk-QQ4HBXZC.js → chunk-6W5M3MSE.js} +84 -673
  51. package/dist/{chunk-R3YW55MY.js → chunk-AI7RMFVV.js} +29 -26
  52. package/dist/{chunk-AUUXS44H.js → chunk-APP43AW7.js} +1 -1
  53. package/dist/{chunk-RQGODFQN.js → chunk-AZOKPWVI.js} +1 -1
  54. package/dist/{chunk-3GNUXXDZ.js → chunk-B5NMSP3V.js} +2 -2
  55. package/dist/{chunk-4D2AYNSE.js → chunk-BNSKVIAW.js} +2 -2
  56. package/dist/chunk-BYLKCZ2G.js +367 -0
  57. package/dist/{chunk-X5NXPCIC.js → chunk-BZLHTMT6.js} +89 -7
  58. package/dist/{chunk-BTQGAXZ3.js → chunk-COQ64C4F.js} +10 -10
  59. package/dist/{chunk-N4EUSDKX.js → chunk-DCCSULXK.js} +14 -14
  60. package/dist/{chunk-JWKBDSPF.js → chunk-DP3WX7FW.js} +2 -2
  61. package/dist/chunk-E5HOHIUV.js +52 -0
  62. package/dist/{chunk-GU3EJCVV.js → chunk-EA5NWDK7.js} +4 -0
  63. package/dist/chunk-EIAEUG7G.js +46 -0
  64. package/dist/{chunk-EB4XGVBG.js → chunk-EUW7JL2K.js} +0 -32
  65. package/dist/{chunk-T7Y5EADL.js → chunk-F7R3SZ4Q.js} +2 -2
  66. package/dist/{chunk-H37L7TT3.js → chunk-G7RIDXAT.js} +2 -2
  67. package/dist/{chunk-W2KI5KPD.js → chunk-H5T27W7M.js} +2 -2
  68. package/dist/chunk-HBWYMRR5.js +94 -0
  69. package/dist/{chunk-CBQACHKY.js → chunk-IIVZZMSO.js} +1 -1
  70. package/dist/{chunk-Z6HPS67T.js → chunk-IRHABAQT.js} +1 -1
  71. package/dist/{chunk-QTO6HEZD.js → chunk-K545B734.js} +2 -2
  72. package/dist/{chunk-KYO45G5L.js → chunk-KOWFRUIT.js} +1 -1
  73. package/dist/{chunk-QFEM7R6T.js → chunk-KQFTBQ66.js} +11 -11
  74. package/dist/chunk-LENBKYRB.js +50 -0
  75. package/dist/{chunk-JCWZ23MJ.js → chunk-M3STIAGU.js} +3 -3
  76. package/dist/{chunk-6DJTDHBI.js → chunk-MD4SVNT6.js} +1 -1
  77. package/dist/{chunk-7264S5HZ.js → chunk-MLGIVVSG.js} +1 -1
  78. package/dist/{chunk-H7MMU64M.js → chunk-NGKUXZID.js} +2 -2
  79. package/dist/{chunk-JWQZSYCK.js → chunk-NUVGDBZC.js} +1 -1
  80. package/dist/{chunk-AQ55ZSSS.js → chunk-OAYWO5NP.js} +1 -1
  81. package/dist/chunk-Q6C6ILUS.js +49 -0
  82. package/dist/{chunk-MBK7N46B.js → chunk-QIOIO7VN.js} +6 -6
  83. package/dist/{chunk-KFKL3FHS.js → chunk-QRXPWW3M.js} +4 -3
  84. package/dist/{chunk-7OIWWZAD.js → chunk-QTIUJZRX.js} +3 -3
  85. package/dist/{chunk-XWAYAO3V.js → chunk-R5RIVOPL.js} +2 -2
  86. package/dist/{chunk-ADSQDYYG.js → chunk-REU2VQPH.js} +54 -5
  87. package/dist/{chunk-GKI6LFAV.js → chunk-RQ32ADJP.js} +2 -2
  88. package/dist/{chunk-VXRXFU6Q.js → chunk-SZ4Q6ZVS.js} +14 -7
  89. package/dist/{chunk-KT5E2RLS.js → chunk-T6ZN4TEF.js} +1 -1
  90. package/dist/{chunk-UFVGSEWH.js → chunk-TO3PS646.js} +2 -2
  91. package/dist/chunk-UAP5DS6P.js +599 -0
  92. package/dist/{chunk-MZPXVH4A.js → chunk-UF6RBP5V.js} +204 -28
  93. package/dist/{chunk-AVNKVF7N.js → chunk-UPIZSCYD.js} +4 -4
  94. package/dist/{chunk-3PVDOCFI.js → chunk-VHPFNLRS.js} +5 -5
  95. package/dist/{chunk-HPRZJKRO.js → chunk-VIIHC42X.js} +1 -1
  96. package/dist/{chunk-D6S5EKXA.js → chunk-WRPYCIV2.js} +8 -12
  97. package/dist/{chunk-ZUTU43FT.js → chunk-Z23ZBYDW.js} +6 -4
  98. package/dist/{chunk-SBLPHUEB.js → chunk-ZGADIZDS.js} +8 -6
  99. package/dist/{global-upgrade-E2HUEB4B.js → global-upgrade-H272QOGD.js} +6 -6
  100. package/dist/{paths-QVTEGNZV.js → paths-HMVOTFUN.js} +2 -2
  101. package/dist/reapply-Q5NHDTVU.js +55 -0
  102. package/dist/src/index.d.ts +1 -0
  103. package/dist/src/index.js +19 -20
  104. package/dist/{upgrade-lock-JCIDZMHF.js → upgrade-lock-L3GHFIRW.js} +3 -3
  105. package/package.json +1 -1
  106. package/dist/chunk-4YO4T5FV.js +0 -149
  107. package/dist/chunk-ANEAA37E.js +0 -197
  108. package/dist/chunk-MNWRUGMH.js +0 -86
  109. package/dist/chunk-RQSOEB4S.js +0 -44
  110. package/dist/chunk-SD3272LS.js +0 -143
  111. package/dist/reapply-5QVKM6LA.js +0 -38
@@ -1,34 +1,200 @@
1
- import {
2
- addClaudeMcpServer,
3
- addPusharyToolPermissions,
4
- isPusharyHook,
5
- removeClaudeMcpServers
6
- } from "./chunk-ANEAA37E.js";
7
1
  import {
8
2
  CLAUDE_HOOK_EVENTS,
9
3
  addGeminiMcpServer,
10
- removeGeminiMcpServer
11
- } from "./chunk-JCWZ23MJ.js";
4
+ removeGeminiMcpServer,
5
+ supportedClaudeEvents
6
+ } from "./chunk-M3STIAGU.js";
12
7
  import {
13
8
  CLAUDE_CODE_AGENT,
14
9
  parseApplyPatchFiles
15
- } from "./chunk-QFEM7R6T.js";
10
+ } from "./chunk-KQFTBQ66.js";
16
11
  import {
17
12
  guardBinary,
18
13
  holdBudgetOf,
14
+ isProtectedByScope,
19
15
  registerHookEntry
20
- } from "./chunk-ZUTU43FT.js";
16
+ } from "./chunk-Z23ZBYDW.js";
21
17
  import {
18
+ HOOK_LOCATOR_BINARY,
22
19
  PHONE_ANSWERED_TOOLS,
23
20
  hookCompatibleProfile,
24
21
  hookCompatibleProfileBySource,
25
22
  toToolLookup,
26
23
  withHookHoldBudget
27
- } from "./chunk-QR6VE5ME.js";
24
+ } from "./chunk-5RGA636G.js";
25
+
26
+ // src/claude-config.ts
27
+ import { join } from "path";
28
+ import { isDeepStrictEqual } from "util";
29
+ var PUSHARY_MCP_URL = "https://pushary.com/api/mcp/mcp";
30
+ var PUSHARY_PERMISSION_RULE = "mcp__pushary__*";
31
+ var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
32
+ var ensureRecord = (target, key) => {
33
+ const existing = asRecord(target[key]);
34
+ if (existing) return existing;
35
+ const created = {};
36
+ target[key] = created;
37
+ return created;
38
+ };
39
+ var isPusharyPermission = (rule) => typeof rule === "string" && (rule.includes("pushary") || rule.includes("MCP(pushary"));
40
+ var HOOK_BINARIES = /* @__PURE__ */ new Set([
41
+ ...CLAUDE_HOOK_EVENTS.map((hook) => hook.binary),
42
+ HOOK_LOCATOR_BINARY
43
+ ]);
44
+ var namesPusharyBinary = (command) => command.split(/[\s/\\"']+/).some((segment) => HOOK_BINARIES.has(segment.replace(/\.(cmd|exe)$/i, "")));
45
+ var isPusharyHook = (entry2, scope) => {
46
+ const hooks = asRecord(entry2)?.hooks;
47
+ if (!Array.isArray(hooks)) return false;
48
+ return hooks.some((hook) => {
49
+ const command = String(asRecord(hook)?.command ?? "");
50
+ if (isProtectedByScope(command, scope)) return false;
51
+ return namesPusharyBinary(command);
52
+ });
53
+ };
54
+ var pusharyMcpServer = (apiKey) => ({
55
+ type: "http",
56
+ url: PUSHARY_MCP_URL,
57
+ headers: { Authorization: `Bearer ${apiKey}` }
58
+ });
59
+ var addClaudeMcpServer = (config, apiKey) => {
60
+ const mcpServers = ensureRecord(config, "mcpServers");
61
+ mcpServers.pushary = pusharyMcpServer(apiKey);
62
+ };
63
+ var isClaudeMcpSnapshot = (value) => {
64
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
65
+ const snapshot = value;
66
+ return typeof snapshot.hadMcpServers === "boolean" && typeof snapshot.mcpServersWasRecord === "boolean" && (!snapshot.hadMcpServers || snapshot.mcpServersWasRecord || Object.hasOwn(snapshot, "mcpServers")) && typeof snapshot.hadPushary === "boolean" && (!snapshot.hadPushary || Object.hasOwn(snapshot, "pushary")) && (!Object.hasOwn(snapshot, "installedPushary") || asRecord(snapshot.installedPushary)?.type === "http" && asRecord(snapshot.installedPushary)?.url === PUSHARY_MCP_URL);
67
+ };
68
+ var captureClaudeMcpServer = (config, apiKey) => {
69
+ const mcpServers = asRecord(config.mcpServers);
70
+ const hadMcpServers = Object.hasOwn(config, "mcpServers");
71
+ return {
72
+ hadMcpServers,
73
+ mcpServersWasRecord: Boolean(mcpServers),
74
+ ...hadMcpServers && !mcpServers ? { mcpServers: structuredClone(config.mcpServers) } : {},
75
+ hadPushary: Boolean(mcpServers && Object.hasOwn(mcpServers, "pushary")),
76
+ ...mcpServers && Object.hasOwn(mcpServers, "pushary") ? { pushary: structuredClone(mcpServers.pushary) } : {},
77
+ ...apiKey ? { installedPushary: pusharyMcpServer(apiKey) } : {}
78
+ };
79
+ };
80
+ var updateClaudeMcpSnapshot = (snapshot, apiKey) => ({
81
+ ...snapshot,
82
+ installedPushary: pusharyMcpServer(apiKey)
83
+ });
84
+ var restoreClaudeMcpServer = (config, snapshot) => {
85
+ const mcpServers = asRecord(config.mcpServers);
86
+ const current = asRecord(mcpServers?.pushary);
87
+ if (Object.hasOwn(snapshot, "installedPushary")) {
88
+ if (!isDeepStrictEqual(mcpServers?.pushary, snapshot.installedPushary)) return false;
89
+ } else if (current?.type !== "http" || current.url !== PUSHARY_MCP_URL) {
90
+ return false;
91
+ }
92
+ if (!snapshot.mcpServersWasRecord) {
93
+ if (Object.keys(mcpServers).length === 1) {
94
+ if (snapshot.hadMcpServers) config.mcpServers = structuredClone(snapshot.mcpServers);
95
+ else delete config.mcpServers;
96
+ } else {
97
+ delete mcpServers.pushary;
98
+ }
99
+ } else if (snapshot.hadPushary) {
100
+ mcpServers.pushary = structuredClone(snapshot.pushary);
101
+ } else {
102
+ delete mcpServers.pushary;
103
+ if (!snapshot.hadMcpServers && Object.keys(mcpServers).length === 0) delete config.mcpServers;
104
+ }
105
+ return true;
106
+ };
107
+ var removeClaudeMcpServers = (config) => {
108
+ let changed = false;
109
+ const removeFrom = (target) => {
110
+ const mcpServers = asRecord(target.mcpServers);
111
+ if (!mcpServers?.pushary) return;
112
+ delete mcpServers.pushary;
113
+ if (Object.keys(mcpServers).length === 0) delete target.mcpServers;
114
+ changed = true;
115
+ };
116
+ removeFrom(config);
117
+ const projects = asRecord(config.projects);
118
+ if (projects) {
119
+ for (const project of Object.values(projects)) {
120
+ const projectConfig = asRecord(project);
121
+ if (projectConfig) removeFrom(projectConfig);
122
+ }
123
+ }
124
+ return changed;
125
+ };
126
+ var removePusharyToolPermissions = (settings) => {
127
+ const permissions = asRecord(settings.permissions);
128
+ if (!permissions || !Array.isArray(permissions.allow)) return false;
129
+ const filtered = permissions.allow.filter((rule) => !isPusharyPermission(rule));
130
+ if (filtered.length === permissions.allow.length) return false;
131
+ if (filtered.length === 0) delete permissions.allow;
132
+ else permissions.allow = filtered;
133
+ if (Object.keys(permissions).length === 0) delete settings.permissions;
134
+ return true;
135
+ };
136
+ var addPusharyToolPermissions = (settings) => {
137
+ const permissions = ensureRecord(settings, "permissions");
138
+ const allow = Array.isArray(permissions.allow) ? permissions.allow : [];
139
+ const filtered = allow.filter((rule) => !isPusharyPermission(rule));
140
+ if (!filtered.includes(PUSHARY_PERMISSION_RULE)) {
141
+ filtered.push(PUSHARY_PERMISSION_RULE);
142
+ }
143
+ permissions.allow = filtered;
144
+ };
145
+ var addPusharyHooks = (settings, binDir, version = null) => {
146
+ const resolve2 = (name) => guardBinary(binDir ? join(binDir, name) : name);
147
+ const hooks = ensureRecord(settings, "hooks");
148
+ const supported = new Map(supportedClaudeEvents(version).map((hook) => [hook.event, hook]));
149
+ for (const known of CLAUDE_HOOK_EVENTS) {
150
+ const current = Array.isArray(hooks[known.event]) ? hooks[known.event] : [];
151
+ const definition = supported.get(known.event);
152
+ if (definition) {
153
+ hooks[known.event] = registerHookEntry(current, isPusharyHook, entry(definition, resolve2));
154
+ continue;
155
+ }
156
+ const others = current.filter((item) => !isPusharyHook(item));
157
+ if (others.length > 0) {
158
+ hooks[known.event] = others;
159
+ } else {
160
+ delete hooks[known.event];
161
+ }
162
+ }
163
+ };
164
+ var entry = (definition, resolve2) => ({
165
+ ...definition.matcher ? { matcher: definition.matcher } : {},
166
+ hooks: [{
167
+ type: "command",
168
+ command: withHookHoldBudget(resolve2(definition.binary), holdBudgetOf(definition)),
169
+ timeout: definition.timeout
170
+ }]
171
+ });
172
+ var removePusharySettings = (settings, scope) => {
173
+ let changed = scope?.keepMcpServer === true ? false : removeClaudeMcpServers(settings);
174
+ if (scope?.keepMcpServer !== true && removePusharyToolPermissions(settings)) changed = true;
175
+ const hooks = asRecord(settings.hooks);
176
+ if (hooks) {
177
+ for (const { event: key } of CLAUDE_HOOK_EVENTS) {
178
+ const entries = hooks[key];
179
+ if (!Array.isArray(entries)) continue;
180
+ const filtered = entries.filter((entry2) => !isPusharyHook(entry2, scope));
181
+ if (filtered.length !== entries.length) {
182
+ if (filtered.length === 0) {
183
+ delete hooks[key];
184
+ } else {
185
+ hooks[key] = filtered;
186
+ }
187
+ changed = true;
188
+ }
189
+ }
190
+ if (Object.keys(hooks).length === 0) delete settings.hooks;
191
+ }
192
+ return changed;
193
+ };
28
194
 
29
195
  // src/compatible-config.ts
30
196
  import { homedir } from "os";
31
- import { isAbsolute, join, resolve } from "path";
197
+ import { isAbsolute, join as join2, resolve } from "path";
32
198
  var AGENT_FLAG = "--agent";
33
199
  var SOURCE_FLAG = "--source";
34
200
  var agentArgument = (profile) => `${AGENT_FLAG}=${profile.agentType}`;
@@ -74,25 +240,25 @@ var normalizeToolCall = (profile, input) => {
74
240
  const lookup = lookupFor(profile, input);
75
241
  return { ...input, tool_name: lookup.tool, tool_input: lookup.input };
76
242
  };
77
- var underHome = (segments, home = homedir()) => join(home, ...segments);
243
+ var underHome = (segments, home = homedir()) => join2(home, ...segments);
78
244
  var compatibleConfigFile = (profile, home) => underHome(profile.configFile, home);
79
245
  var compatibleMcpFile = (profile, home) => profile.mcp ? underHome(profile.mcp.file, home) : null;
80
246
  var compatibleInstructionsFile = (profile, home) => profile.instructions ? underHome(profile.instructions.file, home) : null;
81
- var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
82
- var ensureRecord = (target, key) => {
83
- const existing = asRecord(target[key]);
247
+ var asRecord2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
248
+ var ensureRecord2 = (target, key) => {
249
+ const existing = asRecord2(target[key]);
84
250
  if (existing) return existing;
85
251
  const created = {};
86
252
  target[key] = created;
87
253
  return created;
88
254
  };
89
- var descend = (config, keyPath) => keyPath.reduce(ensureRecord, config);
90
- var findMap = (config, keyPath) => keyPath.reduce((node, key) => node && asRecord(node[key]), config);
255
+ var descend = (config, keyPath) => keyPath.reduce(ensureRecord2, config);
256
+ var findMap = (config, keyPath) => keyPath.reduce((node, key) => node && asRecord2(node[key]), config);
91
257
  var pruneEmptyMap = (config, keyPath) => {
92
258
  if (keyPath.length === 0) return false;
93
259
  const parent = findMap(config, keyPath.slice(0, -1));
94
260
  const key = keyPath[keyPath.length - 1];
95
- const map = asRecord(parent?.[key]);
261
+ const map = asRecord2(parent?.[key]);
96
262
  if (!parent || !map || Object.keys(map).length > 0) return false;
97
263
  delete parent[key];
98
264
  return true;
@@ -114,12 +280,12 @@ var WRITTEN = { ok: true };
114
280
  var ROOT_KEY = "(root)";
115
281
  var dotted = (segments) => segments.join(".") || ROOT_KEY;
116
282
  var hooksShapeConflict = (config, profile) => {
117
- if (!asRecord(config)) return ROOT_KEY;
283
+ if (!asRecord2(config)) return ROOT_KEY;
118
284
  const walked = [];
119
285
  let node = config;
120
286
  for (const key of profile.hooksKeyPath) {
121
287
  if (node[key] === void 0) return void 0;
122
- const nested = asRecord(node[key]);
288
+ const nested = asRecord2(node[key]);
123
289
  if (!nested) return dotted([...walked, key]);
124
290
  walked.push(key);
125
291
  node = nested;
@@ -128,9 +294,9 @@ var hooksShapeConflict = (config, profile) => {
128
294
  return clash ? dotted([...walked, clash.event]) : void 0;
129
295
  };
130
296
  var permissionsShapeConflict = (config) => {
131
- if (!asRecord(config)) return ROOT_KEY;
297
+ if (!asRecord2(config)) return ROOT_KEY;
132
298
  if (config.permissions === void 0) return void 0;
133
- const permissions = asRecord(config.permissions);
299
+ const permissions = asRecord2(config.permissions);
134
300
  if (!permissions) return "permissions";
135
301
  return permissions.allow !== void 0 && !Array.isArray(permissions.allow) ? "permissions.allow" : void 0;
136
302
  };
@@ -154,7 +320,7 @@ var entryFor = (profile, definition, resolve2) => ({
154
320
  var addCompatibleHooks = (config, profile, binDir) => {
155
321
  const conflictAt = hooksShapeConflict(config, profile);
156
322
  if (conflictAt) return { ok: false, conflictAt };
157
- const resolve2 = (name) => guardBinary(binDir ? join(binDir, name) : name);
323
+ const resolve2 = (name) => guardBinary(binDir ? join2(binDir, name) : name);
158
324
  const hooks = descend(config, profile.hooksKeyPath);
159
325
  const supported = new Map(compatibleHookEvents(profile).map((hook) => [hook.event, hook]));
160
326
  for (const known of CLAUDE_HOOK_EVENTS) {
@@ -177,7 +343,7 @@ var removeCompatibleHooks = (config, profile, scope) => {
177
343
  for (const { event } of CLAUDE_HOOK_EVENTS) {
178
344
  const entries = hooks[event];
179
345
  if (!Array.isArray(entries)) continue;
180
- const kept = entries.filter((entry) => !isPusharyHook(entry, scope));
346
+ const kept = entries.filter((entry2) => !isPusharyHook(entry2, scope));
181
347
  if (kept.length === entries.length) continue;
182
348
  if (kept.length === 0) delete hooks[event];
183
349
  else hooks[event] = kept;
@@ -191,14 +357,14 @@ var hasCompatibleHooks = (config, profile) => {
191
357
  if (!hooks) return false;
192
358
  return compatibleHookEvents(profile).some(({ event }) => {
193
359
  const entries = hooks[event];
194
- return Array.isArray(entries) && entries.some((entry) => isPusharyHook(entry));
360
+ return Array.isArray(entries) && entries.some((entry2) => isPusharyHook(entry2));
195
361
  });
196
362
  };
197
363
  var missingCompatibleHookEvents = (config, profile) => {
198
364
  const hooks = findMap(config, profile.hooksKeyPath);
199
365
  return compatibleHookEvents(profile).filter(({ event }) => {
200
366
  const entries = hooks?.[event];
201
- return !Array.isArray(entries) || !entries.some((entry) => isPusharyHook(entry));
367
+ return !Array.isArray(entries) || !entries.some((entry2) => isPusharyHook(entry2));
202
368
  }).map(({ event }) => event);
203
369
  };
204
370
  var compatiblePermissionRuleFile = (profile, home) => profile.permissionRuleFile ? underHome(profile.permissionRuleFile, home) : null;
@@ -210,7 +376,7 @@ var addCompatibleMcpServer = (config, profile, apiKey) => {
210
376
  }
211
377
  addClaudeMcpServer(config, apiKey);
212
378
  if (!profile.mcp.trusted) return;
213
- const server = asRecord(asRecord(config.mcpServers)?.pushary);
379
+ const server = asRecord2(asRecord2(config.mcpServers)?.pushary);
214
380
  if (server) server.trust = true;
215
381
  };
216
382
  var removeCompatibleMcpServer = (config, profile) => {
@@ -219,6 +385,16 @@ var removeCompatibleMcpServer = (config, profile) => {
219
385
  };
220
386
 
221
387
  export {
388
+ addClaudeMcpServer,
389
+ isClaudeMcpSnapshot,
390
+ captureClaudeMcpServer,
391
+ updateClaudeMcpSnapshot,
392
+ restoreClaudeMcpServer,
393
+ removeClaudeMcpServers,
394
+ removePusharyToolPermissions,
395
+ addPusharyToolPermissions,
396
+ addPusharyHooks,
397
+ removePusharySettings,
222
398
  profileFromArgv,
223
399
  activeIdentity,
224
400
  activeHookSource,
@@ -4,18 +4,18 @@ import {
4
4
  } from "./chunk-POFBE6ZY.js";
5
5
  import {
6
6
  isNetworkFailure
7
- } from "./chunk-JXISQ7DT.js";
7
+ } from "./chunk-5N5L6DNN.js";
8
8
  import {
9
9
  clientReportClaims
10
- } from "./chunk-ZUTU43FT.js";
10
+ } from "./chunk-Z23ZBYDW.js";
11
11
  import {
12
12
  getApiKey,
13
13
  getBaseUrl
14
- } from "./chunk-Z6HPS67T.js";
14
+ } from "./chunk-IRHABAQT.js";
15
15
  import {
16
16
  CLIENT_REPORT_PATH,
17
17
  degradedLine
18
- } from "./chunk-QR6VE5ME.js";
18
+ } from "./chunk-5RGA636G.js";
19
19
 
20
20
  // src/client-report-claim.ts
21
21
  import { createHash } from "crypto";
@@ -4,7 +4,7 @@ import {
4
4
  forkFinishWithUpgradeLock,
5
5
  installWithUpgradeLock,
6
6
  releaseAutoUpdateLock
7
- } from "./chunk-RQGODFQN.js";
7
+ } from "./chunk-AZOKPWVI.js";
8
8
  import {
9
9
  describeAutoUpdateCheck,
10
10
  globalInstallLocation,
@@ -14,7 +14,7 @@ import {
14
14
  readAutoUpdateState,
15
15
  updateAutoUpdateState,
16
16
  upgradeEntryFor
17
- } from "./chunk-QTO6HEZD.js";
17
+ } from "./chunk-K545B734.js";
18
18
  import {
19
19
  EXIT
20
20
  } from "./chunk-KZERVKTD.js";
@@ -27,10 +27,10 @@ import {
27
27
  npmErrorMessage,
28
28
  readGlobalCliInstallAt,
29
29
  readGlobalPrefix
30
- } from "./chunk-ZUTU43FT.js";
30
+ } from "./chunk-Z23ZBYDW.js";
31
31
  import {
32
32
  NPX_LATEST_COMMAND
33
- } from "./chunk-STQRUH3S.js";
33
+ } from "./chunk-5DCDQ5VW.js";
34
34
  import {
35
35
  commandsPackage,
36
36
  globalUpgradeEntry,
@@ -39,7 +39,7 @@ import {
39
39
  isSameMajorVersion,
40
40
  ownPackageRoot,
41
41
  packageVersionAt
42
- } from "./chunk-QR6VE5ME.js";
42
+ } from "./chunk-5RGA636G.js";
43
43
 
44
44
  // src/global-upgrade.ts
45
45
  import { existsSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readTranscriptPreference
3
- } from "./chunk-ADSQDYYG.js";
3
+ } from "./chunk-REU2VQPH.js";
4
4
 
5
5
  // src/transcript-setting.ts
6
6
  var transcriptEnvironmentPreference = () => {
@@ -1,23 +1,23 @@
1
- import {
2
- clientErrorKindOf,
3
- reportClientError
4
- } from "./chunk-AVNKVF7N.js";
5
1
  import {
6
2
  SubscriptionRequiredError,
7
3
  callMcpTool
8
- } from "./chunk-L76HTPU6.js";
4
+ } from "./chunk-6AYSKVLL.js";
5
+ import {
6
+ clientErrorKindOf,
7
+ reportClientError
8
+ } from "./chunk-UPIZSCYD.js";
9
9
  import {
10
10
  installNetworkDefaults
11
- } from "./chunk-JXISQ7DT.js";
11
+ } from "./chunk-5N5L6DNN.js";
12
12
  import {
13
13
  getBaseUrl
14
- } from "./chunk-Z6HPS67T.js";
14
+ } from "./chunk-IRHABAQT.js";
15
15
  import {
16
16
  ASK_AGENT_NAME_MAX,
17
17
  ASK_QUESTION_MAX,
18
18
  DECISION_LINE_MAX,
19
19
  truncateLine
20
- } from "./chunk-QR6VE5ME.js";
20
+ } from "./chunk-5RGA636G.js";
21
21
 
22
22
  // src/api.ts
23
23
  import { randomUUID } from "crypto";
@@ -56,11 +56,9 @@ var isBlockedActionClaim = (data) => {
56
56
 
57
57
  // src/api.ts
58
58
  installNetworkDefaults();
59
- var DECISION_STOP_REASON = "Approval was cancelled or became unavailable. Retry only after resolving it.";
60
59
  var isDecisionStopped = (result) => result.handoffAction === "stop" || ["cancelled", "unavailable", "stopped", "missing"].includes(result.status ?? "");
61
60
  var isLocalQuestionHandoff = (result) => result.suppressed === true || result.noDevices === true || result.status === "terminal" || result.status === "notified";
62
61
  var STOPPED = { answered: false, handoffAction: "stop" };
63
- var UNVERIFIABLE_APPROVAL_REASON = "Pushary could not create a verifiable approval. Retry the action.";
64
62
  var unavailableQuestionUnlessSubscriptionRequired = (error) => {
65
63
  if (error instanceof SubscriptionRequiredError) throw error;
66
64
  return { correlationId: "", status: "unavailable" };
@@ -174,10 +172,8 @@ export {
174
172
  isPolicyConfig,
175
173
  isAskUserResponse,
176
174
  isWaitForAnswerResponse,
177
- DECISION_STOP_REASON,
178
175
  isDecisionStopped,
179
176
  isLocalQuestionHandoff,
180
- UNVERIFIABLE_APPROVAL_REASON,
181
177
  unavailableQuestionUnlessSubscriptionRequired,
182
178
  askUser,
183
179
  waitForAnswer,
@@ -13,7 +13,7 @@ import {
13
13
  isReleaseVersion,
14
14
  ownPackageName,
15
15
  withHookHoldBudget
16
- } from "./chunk-QR6VE5ME.js";
16
+ } from "./chunk-5RGA636G.js";
17
17
 
18
18
  // src/setup/paths.ts
19
19
  import { homedir as homedir2 } from "os";
@@ -365,9 +365,9 @@ var installGlobally = (options) => {
365
365
  }
366
366
  const started = (async () => {
367
367
  if (!npmIsOnPath()) throw new NpmMissingError();
368
- const { withUpgradeLock } = await import("./global-upgrade-E2HUEB4B.js");
369
- const { installWithUpgradeLock, ownsUpgradeLock } = await import("./upgrade-lock-JCIDZMHF.js");
370
- const { autoUpdateLock: autoUpdateLock2 } = await import("./paths-QVTEGNZV.js");
368
+ const { withUpgradeLock } = await import("./global-upgrade-H272QOGD.js");
369
+ const { installWithUpgradeLock, ownsUpgradeLock } = await import("./upgrade-lock-L3GHFIRW.js");
370
+ const { autoUpdateLock: autoUpdateLock2 } = await import("./paths-HMVOTFUN.js");
371
371
  let result = "skipped";
372
372
  const install = async () => {
373
373
  const platform = process.platform;
@@ -438,6 +438,7 @@ var guardHookCommand = (target, platform = process.platform) => {
438
438
  return `${HOOK_SHELL} '${HOOK_GUARD_SCRIPTS[guardKindOf(target)]}' ${path}`;
439
439
  };
440
440
  var guardBinary = (path, platform) => guardHookCommand({ kind: "binary", path, runtime: "node" }, platform);
441
+ var guardNodeScript = (script, platform) => guardHookCommand({ kind: "node", script }, platform);
441
442
  var guardCursorGate = (script, platform) => guardHookCommand({ kind: "cursor_gate", script }, platform);
442
443
  var guardedArgv = (target, args = [], platform = process.platform) => {
443
444
  const path = targetPath(target);
@@ -853,6 +854,7 @@ export {
853
854
  installGlobally,
854
855
  holdBudgetOf,
855
856
  guardBinary,
857
+ guardNodeScript,
856
858
  guardCursorGate,
857
859
  guardedArgv,
858
860
  registerHookEntry,
@@ -8,8 +8,9 @@ import {
8
8
  SETUP_AGENT_CHOICES,
9
9
  SETUP_CONNECT_MODES,
10
10
  isSetupConnectMode,
11
- isValidApiKey
12
- } from "./chunk-QR6VE5ME.js";
11
+ isValidApiKey,
12
+ normalizeAgentId
13
+ } from "./chunk-5RGA636G.js";
13
14
 
14
15
  // src/setup/options.ts
15
16
  var AGENT_CHOICES = SETUP_AGENT_CHOICES;
@@ -41,8 +42,7 @@ var SETUP_FLAGS = {
41
42
  bools: ["key-stdin", "skip-phone", "yes", "y", "json", "dry-run", "take-over-hooks", "help", "h"],
42
43
  values: ["key", "connect", "agents", "verify", "control", "transcripts"]
43
44
  };
44
- var effectiveControlMode = (options, stored, configPresent) => options.controlExplicit ? options.control : stored ?? (configPresent ? null : options.control);
45
- var isAgentChoice = (value) => AGENT_CHOICES.includes(value);
45
+ var effectiveControlMode = (options, stored) => options.controlExplicit ? options.control : stored ?? options.control;
46
46
  var parseAgentSelection = (raw, yes) => {
47
47
  if (raw === void 0) {
48
48
  return yes ? { kind: "auto" } : { kind: "ask" };
@@ -52,13 +52,15 @@ var parseAgentSelection = (raw, yes) => {
52
52
  if (value === "none") return { kind: "none" };
53
53
  const parts = value.split(",").map((part) => part.trim()).filter((part) => part !== "");
54
54
  if (parts.length === 0) throw new UsageError("--agents needs a value");
55
- const unknown = parts.filter((part) => !isAgentChoice(part));
55
+ const resolved = parts.map((part) => ({ part, agent: normalizeAgentId(part, AGENT_CHOICES) }));
56
+ const unknown = resolved.flatMap(({ part, agent }) => agent === null ? [part] : []);
56
57
  if (unknown.length > 0) {
57
58
  throw new UsageError(
58
59
  `--agents does not know: ${unknown.join(", ")}. Use auto, none, or any of: ${AGENT_CHOICES.join(", ")}`
59
60
  );
60
61
  }
61
- return { kind: "explicit", agents: [...new Set(parts)] };
62
+ const agents = resolved.flatMap(({ agent }) => agent === null ? [] : [agent]);
63
+ return { kind: "explicit", agents: [...new Set(agents)] };
62
64
  };
63
65
  var parseSetupOptions = (input) => {
64
66
  const flags = parseFlags(input.argv, SETUP_FLAGS);
@@ -5,15 +5,15 @@ import {
5
5
  readGlobalUpgradeSubject,
6
6
  upgradeInstalledPackage,
7
7
  withUpgradeLock
8
- } from "./chunk-3PVDOCFI.js";
9
- import "./chunk-RQGODFQN.js";
10
- import "./chunk-QTO6HEZD.js";
8
+ } from "./chunk-VHPFNLRS.js";
9
+ import "./chunk-AZOKPWVI.js";
10
+ import "./chunk-K545B734.js";
11
11
  import "./chunk-POFBE6ZY.js";
12
12
  import "./chunk-KZERVKTD.js";
13
- import "./chunk-ZUTU43FT.js";
13
+ import "./chunk-Z23ZBYDW.js";
14
14
  import "./chunk-T7E75EKA.js";
15
- import "./chunk-STQRUH3S.js";
16
- import "./chunk-QR6VE5ME.js";
15
+ import "./chunk-5DCDQ5VW.js";
16
+ import "./chunk-5RGA636G.js";
17
17
  export {
18
18
  finishGlobalUpgrade,
19
19
  finishUpgradeWithLock,
@@ -32,8 +32,8 @@ import {
32
32
  pusharyDir,
33
33
  vscodePluginDir,
34
34
  vscodePluginMcp
35
- } from "./chunk-ZUTU43FT.js";
36
- import "./chunk-QR6VE5ME.js";
35
+ } from "./chunk-Z23ZBYDW.js";
36
+ import "./chunk-5RGA636G.js";
37
37
  export {
38
38
  autoUpdateLock,
39
39
  autoUpdateLog,
@@ -0,0 +1,55 @@
1
+ import {
2
+ ensureCodexTrustAfterReapply,
3
+ inspectConfiguredManagedProviders,
4
+ reapplyAllAgents,
5
+ reapplyClaudeForVersion,
6
+ reapplyClaudeSettings,
7
+ reapplyCodexSettings,
8
+ reapplyCursorPlugin,
9
+ reapplyGeminiSettings,
10
+ reapplyOpenCodePlugin,
11
+ reapplyVsCodePlugin,
12
+ repairCodexHolds
13
+ } from "./chunk-6EBGOHDJ.js";
14
+ import "./chunk-NGKUXZID.js";
15
+ import "./chunk-RIVNNBEK.js";
16
+ import "./chunk-XHKBHWLX.js";
17
+ import "./chunk-BZLHTMT6.js";
18
+ import "./chunk-UF6RBP5V.js";
19
+ import "./chunk-BYLKCZ2G.js";
20
+ import "./chunk-M3STIAGU.js";
21
+ import "./chunk-ZGADIZDS.js";
22
+ import "./chunk-MLGIVVSG.js";
23
+ import "./chunk-GMXKITVA.js";
24
+ import "./chunk-6ICPEJY5.js";
25
+ import "./chunk-KQFTBQ66.js";
26
+ import "./chunk-N6IOSZOE.js";
27
+ import "./chunk-MD4SVNT6.js";
28
+ import "./chunk-WRPYCIV2.js";
29
+ import "./chunk-6AYSKVLL.js";
30
+ import "./chunk-QRXPWW3M.js";
31
+ import "./chunk-UPIZSCYD.js";
32
+ import "./chunk-POFBE6ZY.js";
33
+ import "./chunk-5N5L6DNN.js";
34
+ import "./chunk-KOWFRUIT.js";
35
+ import "./chunk-7QLSKOSU.js";
36
+ import "./chunk-KZERVKTD.js";
37
+ import "./chunk-BNSKVIAW.js";
38
+ import "./chunk-Z23ZBYDW.js";
39
+ import "./chunk-T7E75EKA.js";
40
+ import "./chunk-IRHABAQT.js";
41
+ import "./chunk-5DCDQ5VW.js";
42
+ import "./chunk-5RGA636G.js";
43
+ export {
44
+ ensureCodexTrustAfterReapply,
45
+ inspectConfiguredManagedProviders,
46
+ reapplyAllAgents,
47
+ reapplyClaudeForVersion,
48
+ reapplyClaudeSettings,
49
+ reapplyCodexSettings,
50
+ reapplyCursorPlugin,
51
+ reapplyGeminiSettings,
52
+ reapplyOpenCodePlugin,
53
+ reapplyVsCodePlugin,
54
+ repairCodexHolds
55
+ };
@@ -183,6 +183,7 @@ interface AnswerResult {
183
183
  value?: string;
184
184
  note?: string;
185
185
  }
186
+
186
187
  declare const askUser: (apiKey: string, params: AskUserParams, timeoutMs?: number) => Promise<AskUserResponse>;
187
188
  declare const waitForAnswer: (apiKey: string, correlationId: string, timeoutMs?: number, signal?: AbortSignal) => Promise<AnswerResult>;
188
189
  declare const cancelQuestion: (apiKey: string, correlationId: string, signal?: AbortSignal) => Promise<{