@pushary/agent-hooks 0.89.11 → 0.89.12

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 (77) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +3 -2
  3. package/dist/bin/pushary-bell-hook.js +5 -5
  4. package/dist/bin/pushary-bell.js +11 -11
  5. package/dist/bin/pushary-claude.js +104 -32
  6. package/dist/bin/pushary-clean.js +39 -28
  7. package/dist/bin/pushary-codex-bridge.js +17 -16
  8. package/dist/bin/pushary-codex-hook.js +11 -10
  9. package/dist/bin/pushary-codex.js +7 -7
  10. package/dist/bin/pushary-connect.js +12 -12
  11. package/dist/bin/pushary-daemon-supervisor.d.ts +1 -0
  12. package/dist/bin/pushary-daemon-supervisor.js +27 -0
  13. package/dist/bin/pushary-daemon.js +22 -22
  14. package/dist/bin/pushary-disconnect.js +9 -9
  15. package/dist/bin/pushary-doctor.js +59 -49
  16. package/dist/bin/pushary-elicitation-hook.js +4 -4
  17. package/dist/bin/pushary-gemini-bridge.js +16 -15
  18. package/dist/bin/pushary-gemini-hook.js +10 -9
  19. package/dist/bin/pushary-hook.js +13 -13
  20. package/dist/bin/pushary-login.js +11 -11
  21. package/dist/bin/pushary-logout.js +11 -11
  22. package/dist/bin/pushary-mode.js +5 -5
  23. package/dist/bin/pushary-notification-hook.js +7 -7
  24. package/dist/bin/pushary-opencode-hook.js +10 -9
  25. package/dist/bin/pushary-permission-denied-hook.js +11 -11
  26. package/dist/bin/pushary-permission-hook.js +11 -11
  27. package/dist/bin/pushary-post-hook.js +7 -7
  28. package/dist/bin/pushary-prompt-hook.js +7 -7
  29. package/dist/bin/pushary-session-end-hook.js +7 -7
  30. package/dist/bin/pushary-session-start-hook.js +7 -7
  31. package/dist/bin/pushary-setup.js +87 -59
  32. package/dist/bin/pushary-stats.js +4 -4
  33. package/dist/bin/pushary-status.js +14 -14
  34. package/dist/bin/pushary-stop-hook.js +7 -7
  35. package/dist/bin/pushary-stopfailure-hook.js +7 -7
  36. package/dist/bin/pushary-suggestions.js +2 -2
  37. package/dist/bin/pushary-upgrade.js +21 -21
  38. package/dist/bin/pushary-wait.js +5 -5
  39. package/dist/bin/pushary.js +1 -1
  40. package/dist/{chunk-253WC6O5.js → chunk-327YMKP5.js} +1 -1
  41. package/dist/{chunk-6XUABEX2.js → chunk-3OXHYPZG.js} +1 -1
  42. package/dist/{chunk-MZGWKIUZ.js → chunk-3XSP5SML.js} +7 -3
  43. package/dist/{chunk-XX2V4QS5.js → chunk-4LL6LG5X.js} +2 -2
  44. package/dist/{chunk-DKWM5T3P.js → chunk-5NDB3YOE.js} +2 -2
  45. package/dist/{chunk-TEZ2FZD6.js → chunk-6GU55AQQ.js} +2 -2
  46. package/dist/{chunk-Q223OM5J.js → chunk-6V7ZDH3A.js} +4 -4
  47. package/dist/{chunk-OLAGKKSR.js → chunk-6VXNA5JB.js} +16 -6
  48. package/dist/{chunk-34GN3IPX.js → chunk-7DK3ZH3N.js} +1 -1
  49. package/dist/{chunk-PZRWFWSR.js → chunk-7HYJPOGG.js} +7 -7
  50. package/dist/{chunk-TY5HVMXT.js → chunk-DHR4F2CR.js} +1 -1
  51. package/dist/{chunk-3HFK3UXM.js → chunk-FCUUVHTS.js} +1 -1
  52. package/dist/{chunk-NCVIWGVA.js → chunk-GKPURU7P.js} +1 -1
  53. package/dist/chunk-JJV5Q4KG.js +20 -0
  54. package/dist/{chunk-TG3T3M4K.js → chunk-JVZX5YRJ.js} +6 -2
  55. package/dist/{chunk-6EKQZA6R.js → chunk-KVHP5ZME.js} +1 -1
  56. package/dist/{chunk-X4ZUUFKV.js → chunk-L4ZCFMWW.js} +63 -1
  57. package/dist/{chunk-2LPEZYMC.js → chunk-MFNQ5IMW.js} +1 -1
  58. package/dist/{chunk-KVE5RCQL.js → chunk-NBRM3FMD.js} +1 -1
  59. package/dist/{chunk-FZ73G2RO.js → chunk-NESKLV6R.js} +25 -6
  60. package/dist/{chunk-FXIL7RCL.js → chunk-OADGBOP7.js} +4 -4
  61. package/dist/{chunk-J4K75V4D.js → chunk-OCMOTJTW.js} +10 -9
  62. package/dist/{chunk-LURY4WNF.js → chunk-OTPJ4FUR.js} +1 -1
  63. package/dist/{chunk-QA72MKIT.js → chunk-OVEGEQSB.js} +5 -5
  64. package/dist/{chunk-3SQYKLBW.js → chunk-PS7DQ2SU.js} +46 -18
  65. package/dist/{chunk-UDBJHQMG.js → chunk-QFJZHVVL.js} +1 -1
  66. package/dist/chunk-QZCFVWA7.js +58 -0
  67. package/dist/{chunk-3XTFX4CL.js → chunk-RLQWNEPM.js} +3 -2
  68. package/dist/{chunk-3CUDMTL4.js → chunk-RNKPLUWC.js} +10 -3
  69. package/dist/{chunk-SYUIXXQW.js → chunk-VF3RTVWY.js} +1 -1
  70. package/dist/{chunk-TRVIRETT.js → chunk-VPLQFXCH.js} +1 -1
  71. package/dist/{chunk-IUN6VOKV.js → chunk-WDVQ6O4C.js} +2 -42
  72. package/dist/{chunk-IUWRVTQK.js → chunk-XREW7RQ3.js} +1 -1
  73. package/dist/{chunk-BLODMQKJ.js → chunk-Y4WVZIEI.js} +1 -1
  74. package/dist/src/index.d.ts +3 -1
  75. package/dist/src/index.js +15 -11
  76. package/package.json +2 -1
  77. /package/dist/{chunk-X6RXX2NF.js → chunk-3MCEES6Z.js} +0 -0
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-QA72MKIT.js";
3
+ } from "./chunk-OVEGEQSB.js";
4
4
  import {
5
5
  writeFileAtomic
6
- } from "./chunk-XX2V4QS5.js";
6
+ } from "./chunk-4LL6LG5X.js";
7
7
 
8
8
  // src/identity.ts
9
9
  import { randomUUID } from "crypto";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-QA72MKIT.js";
3
+ } from "./chunk-OVEGEQSB.js";
4
4
  import {
5
5
  readJsonSafe
6
- } from "./chunk-XX2V4QS5.js";
6
+ } from "./chunk-4LL6LG5X.js";
7
7
 
8
8
  // src/process-ownership.ts
9
9
  import { createHash, randomUUID } from "crypto";
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  PRETOOLUSE_GATED_TOOLS,
3
3
  PRETOOLUSE_PHONE_ANSWERED_TOOLS
4
- } from "./chunk-6EKQZA6R.js";
4
+ } from "./chunk-KVHP5ZME.js";
5
5
  import {
6
6
  guardBinary
7
- } from "./chunk-SYUIXXQW.js";
7
+ } from "./chunk-VF3RTVWY.js";
8
8
  import {
9
9
  isProtectedByScope
10
- } from "./chunk-QA72MKIT.js";
10
+ } from "./chunk-OVEGEQSB.js";
11
11
  import {
12
12
  HOOK_BUDGETS,
13
13
  HOOK_LOCATOR_BINARY
14
- } from "./chunk-X6RXX2NF.js";
14
+ } from "./chunk-3MCEES6Z.js";
15
15
 
16
16
  // src/claude-config.ts
17
17
  import { join } from "path";
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  buildTranscriptRecords,
3
3
  decodePublicKey,
4
- fetchAccountPublicKey,
5
4
  generateSessionKey,
6
- uploadTranscriptRecords,
7
5
  wrapSessionKey
8
- } from "./chunk-IUN6VOKV.js";
6
+ } from "./chunk-WDVQ6O4C.js";
7
+ import {
8
+ fetchTranscriptRecipients,
9
+ uploadTranscriptRecords
10
+ } from "./chunk-QZCFVWA7.js";
9
11
 
10
12
  // src/live-session.ts
11
13
  var MAX_TRANSCRIPT_QUEUE = 100;
@@ -71,6 +73,8 @@ var LiveTranscriptRelay = class {
71
73
  queue = [];
72
74
  sessionKey = null;
73
75
  wrappedKey = null;
76
+ providerWrappedKey = null;
77
+ providerKeyId = null;
74
78
  keyUploaded = false;
75
79
  keyRejected = false;
76
80
  flushing = null;
@@ -97,10 +101,14 @@ var LiveTranscriptRelay = class {
97
101
  async flushBatch() {
98
102
  try {
99
103
  if (!this.sessionKey) {
100
- const publicKey = await fetchAccountPublicKey(this.options.apiKey, this.options.baseUrl);
101
- if (!publicKey) return false;
104
+ const recipients = await fetchTranscriptRecipients(this.options.apiKey, this.options.baseUrl);
105
+ if (!recipients) return false;
102
106
  this.sessionKey = generateSessionKey();
103
- this.wrappedKey = wrapSessionKey(this.sessionKey, decodePublicKey(publicKey));
107
+ this.wrappedKey = wrapSessionKey(this.sessionKey, decodePublicKey(recipients.phonePublicKey));
108
+ if (recipients.provider) {
109
+ this.providerWrappedKey = wrapSessionKey(this.sessionKey, decodePublicKey(recipients.provider.publicKey));
110
+ this.providerKeyId = recipients.provider.keyId;
111
+ }
104
112
  }
105
113
  const count = Math.min(this.queue.length, 50);
106
114
  const records = buildTranscriptRecords(this.queue.slice(0, count), this.sessionKey).records;
@@ -112,6 +120,8 @@ var LiveTranscriptRelay = class {
112
120
  sessionId: this.sessionId,
113
121
  machineId: this.options.machineId,
114
122
  dataEncryptionKey: this.keyUploaded ? void 0 : this.wrappedKey ?? void 0,
123
+ providerWrappedSessionKey: this.keyUploaded ? void 0 : this.providerWrappedKey ?? void 0,
124
+ providerKeyId: this.keyUploaded ? void 0 : this.providerKeyId ?? void 0,
115
125
  records
116
126
  }, this.options.baseUrl);
117
127
  if (result.keyConflict) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_BUDGETS,
3
3
  OPENCODE_APPROVAL_EVENT
4
- } from "./chunk-X6RXX2NF.js";
4
+ } from "./chunk-3MCEES6Z.js";
5
5
 
6
6
  // src/opencode-plugin.ts
7
7
  var OPENCODE_PLUGIN_MARKER = "pushary-opencode-plugin w1";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  detectClaudeVersion
3
- } from "./chunk-KVE5RCQL.js";
3
+ } from "./chunk-NBRM3FMD.js";
4
4
  import {
5
5
  claudeWired,
6
6
  codexWired,
7
7
  geminiWired
8
- } from "./chunk-FZ73G2RO.js";
8
+ } from "./chunk-NESKLV6R.js";
9
9
  import {
10
10
  GEMINI_HOOK_BINARY,
11
11
  addClaudeMcpServer,
@@ -14,14 +14,14 @@ import {
14
14
  addPusharyHooks,
15
15
  addPusharyToolPermissions,
16
16
  hasGeminiHooks
17
- } from "./chunk-Q223OM5J.js";
17
+ } from "./chunk-6V7ZDH3A.js";
18
18
  import {
19
19
  guardBinary
20
- } from "./chunk-SYUIXXQW.js";
20
+ } from "./chunk-VF3RTVWY.js";
21
21
  import {
22
22
  resolveGlobalBinDir,
23
23
  resolveGlobalBinary
24
- } from "./chunk-X4ZUUFKV.js";
24
+ } from "./chunk-L4ZCFMWW.js";
25
25
  import {
26
26
  CODEX_HOOK_BINARY,
27
27
  addCodexHookTrust,
@@ -32,10 +32,10 @@ import {
32
32
  codexHooksJson,
33
33
  hasCodexHooks,
34
34
  vscodePluginMcp
35
- } from "./chunk-QA72MKIT.js";
35
+ } from "./chunk-OVEGEQSB.js";
36
36
  import {
37
37
  readJsonSafe
38
- } from "./chunk-XX2V4QS5.js";
38
+ } from "./chunk-4LL6LG5X.js";
39
39
 
40
40
  // src/reapply.ts
41
41
  import { join, dirname } from "path";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getMachineId
3
- } from "./chunk-DKWM5T3P.js";
3
+ } from "./chunk-5NDB3YOE.js";
4
4
  import {
5
5
  getPackageVersion
6
6
  } from "./chunk-DINDL2CF.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isSafeReadOnlyCommand
3
- } from "./chunk-X6RXX2NF.js";
3
+ } from "./chunk-3MCEES6Z.js";
4
4
 
5
5
  // src/ledger.ts
6
6
  import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  shouldDeferToNativeMode
3
- } from "./chunk-X6RXX2NF.js";
3
+ } from "./chunk-3MCEES6Z.js";
4
4
 
5
5
  // src/native-defer.ts
6
6
  var nativeDeferOptions = () => {
@@ -0,0 +1,20 @@
1
+ import {
2
+ readTranscriptPreference
3
+ } from "./chunk-RNKPLUWC.js";
4
+
5
+ // src/transcript-setting.ts
6
+ var fromEnv = () => {
7
+ const value = process.env.PUSHARY_TRANSCRIPTS?.trim().toLowerCase();
8
+ if (!value) return null;
9
+ if (["0", "false", "off"].includes(value)) return false;
10
+ if (["1", "true", "on"].includes(value)) return true;
11
+ return null;
12
+ };
13
+ var configuredPreference = () => fromEnv() ?? readTranscriptPreference();
14
+ var transcriptsEnabled = () => configuredPreference() ?? false;
15
+ var transcriptPreferenceForSetup = (explicit = null) => explicit ?? configuredPreference() ?? true;
16
+
17
+ export {
18
+ transcriptsEnabled,
19
+ transcriptPreferenceForSetup
20
+ };
@@ -5,7 +5,7 @@ import {
5
5
  FILE_TARGET_TOOLS,
6
6
  redactSecrets,
7
7
  redactSecretsDeep
8
- } from "./chunk-X6RXX2NF.js";
8
+ } from "./chunk-3MCEES6Z.js";
9
9
 
10
10
  // ../hook-mapping/src/describe.ts
11
11
  import { isAbsolute, relative, resolve } from "path";
@@ -46,10 +46,13 @@ var eventPrefixes = {
46
46
  };
47
47
  var EVENT_ACTION_MAX = 120;
48
48
  var HOOK_FALLBACK_MAX = 200;
49
+ var UNNAMED_ACTION = "this request";
49
50
  var describeToolCall = (toolName, toolInput, format = "hook") => {
51
+ if (!toolName) return "";
50
52
  const prefixes = format === "hook" ? hookPrefixes : eventPrefixes;
51
53
  const builder = prefixes[toolName];
52
- const raw = builder ? builder(toolInput) : format === "hook" ? `${toolName}: ${JSON.stringify(toolInput)}` : `${toolName}: done`;
54
+ const detail = JSON.stringify(toolInput ?? {});
55
+ const raw = builder ? builder(toolInput) : format === "hook" ? detail === "{}" || detail === void 0 ? toolName : `${toolName}: ${detail}` : `${toolName}: done`;
53
56
  const redacted = redactSecrets(raw);
54
57
  if (format === "event") return redacted.slice(0, EVENT_ACTION_MAX);
55
58
  return builder ? redacted : redacted.slice(0, HOOK_FALLBACK_MAX);
@@ -269,6 +272,7 @@ var taskTitleFrom = (prompt) => typeof prompt === "string" ? prompt.replace(/\s+
269
272
 
270
273
  export {
271
274
  HOOK_FALLBACK_MAX,
275
+ UNNAMED_ACTION,
272
276
  describeToolCall,
273
277
  deriveToolTarget,
274
278
  parseApplyPatchOps,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ASKED_IN_EVERY_MODE_TOOLS
3
- } from "./chunk-X6RXX2NF.js";
3
+ } from "./chunk-3MCEES6Z.js";
4
4
 
5
5
  // src/claude-tools.ts
6
6
  var PRETOOLUSE_GATED_TOOLS = [
@@ -1,7 +1,7 @@
1
1
  // src/npm.ts
2
2
  import { execFileSync, execSync } from "child_process";
3
3
  import { existsSync, readFileSync, realpathSync } from "fs";
4
- import { dirname, join } from "path";
4
+ import { dirname, isAbsolute, join, relative, resolve } from "path";
5
5
  var cleanNpmEnv = () => {
6
6
  const env = {};
7
7
  for (const [key, value] of Object.entries(process.env)) {
@@ -77,12 +77,67 @@ var resolveGlobalPackageVersion = (name) => {
77
77
  return void 0;
78
78
  }
79
79
  };
80
+ var localImportsPresent = (entry, packageDir, seen = /* @__PURE__ */ new Set()) => {
81
+ if (seen.has(entry)) return true;
82
+ seen.add(entry);
83
+ try {
84
+ const source = readFileSync(entry, "utf8");
85
+ for (const match of source.matchAll(/\b(?:import|export)\s+(?:[^"'()]*?\s+from\s+)?["'](\.{1,2}\/[^"']+)["']|\bimport\s*\(\s*["'](\.{1,2}\/[^"']+)["']/g)) {
86
+ const dependency = resolve(dirname(entry), match[1] ?? match[2]);
87
+ const localPath = relative(packageDir, dependency);
88
+ if (localPath.startsWith("..") || isAbsolute(localPath) || !existsSync(dependency)) return false;
89
+ if (/\.[cm]?js$/.test(dependency) && !localImportsPresent(dependency, packageDir, seen)) return false;
90
+ }
91
+ return true;
92
+ } catch {
93
+ return false;
94
+ }
95
+ };
96
+ var packageBinsPresent = (packageDir, prefix, platform = process.platform, requiredFiles = []) => {
97
+ try {
98
+ const manifest = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
99
+ if (!manifest.bin || typeof manifest.bin !== "object" || Array.isArray(manifest.bin)) return false;
100
+ const bins = Object.entries(manifest.bin);
101
+ if (bins.length === 0) return false;
102
+ if (!requiredFiles.every((path) => existsSync(join(packageDir, path)))) return false;
103
+ const seen = /* @__PURE__ */ new Set();
104
+ return bins.every(([name, target]) => {
105
+ if (typeof target !== "string") return false;
106
+ const shims = platform === "win32" ? [join(prefix, `${name}.cmd`), join(prefix, name)] : [join(prefix, "bin", name)];
107
+ const entry = join(packageDir, target);
108
+ return existsSync(entry) && shims.some(existsSync) && localImportsPresent(entry, packageDir, seen);
109
+ });
110
+ } catch {
111
+ return false;
112
+ }
113
+ };
114
+ var AGENT_HOOKS_RUNTIME_FILES = [
115
+ "data/SKILL.md",
116
+ "data/cursor-plugin/.cursor-plugin/plugin.json",
117
+ "data/cursor-plugin/hooks/hooks.json",
118
+ "data/cursor-plugin/mcp.json",
119
+ "data/cursor-plugin/scripts/pushary-gate.mjs",
120
+ "data/vscode-plugin/.claude-plugin/plugin.json",
121
+ "data/vscode-plugin/hooks/hooks.json",
122
+ "data/vscode-plugin/.mcp.json",
123
+ "data/vscode-plugin/scripts/pushary-gate.mjs"
124
+ ];
125
+ var globalPackageBinsPresent = (name) => {
126
+ try {
127
+ const root = execNpm("root -g --no-workspaces", { timeout: 5e3 }).toString().trim();
128
+ const prefix = execNpm("prefix -g --no-workspaces", { timeout: 5e3 }).toString().trim();
129
+ return packageBinsPresent(join(root, ...name.split("/")), prefix, process.platform, AGENT_HOOKS_RUNTIME_FILES);
130
+ } catch {
131
+ return false;
132
+ }
133
+ };
80
134
  var resolveGlobalBinDir = (probe) => {
81
135
  if (process.platform === "win32") return void 0;
82
136
  const resolved = resolveGlobalBinary(probe);
83
137
  return resolved ? resolved.slice(0, resolved.length - probe.length - 1) : void 0;
84
138
  };
85
139
  var quoteIfNeeded = (path) => /\s/.test(path) ? `"${path}"` : path;
140
+ var needsGlobalInstall = (requested, installed, binaryPresent) => requested !== installed || !binaryPresent;
86
141
  var installState;
87
142
  var installGlobally = (options) => {
88
143
  if (installState) {
@@ -90,6 +145,13 @@ var installGlobally = (options) => {
90
145
  }
91
146
  const started = (async () => {
92
147
  const pinned = process.env.PUSHARY_PIN_GLOBAL_VERSION !== "0";
148
+ if (pinned && !needsGlobalInstall(
149
+ options.version,
150
+ resolveGlobalPackageVersion("@pushary/agent-hooks"),
151
+ globalPackageBinsPresent("@pushary/agent-hooks")
152
+ )) {
153
+ return "skipped";
154
+ }
93
155
  const spec = pinned && options.version && options.version !== "0.0.0" ? `@pushary/agent-hooks@${options.version}` : "@pushary/agent-hooks@latest";
94
156
  execNpm(`install -g --no-workspaces ${spec}`, { timeout: options.timeoutMs ?? 12e4 });
95
157
  return "installed";
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-BSZYIAZL.js";
12
12
  import {
13
13
  reportedInstallSource
14
- } from "./chunk-IUWRVTQK.js";
14
+ } from "./chunk-XREW7RQ3.js";
15
15
 
16
16
  // src/reach.ts
17
17
  var reachVerdict = (channels) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseVersion
3
- } from "./chunk-Q223OM5J.js";
3
+ } from "./chunk-6V7ZDH3A.js";
4
4
 
5
5
  // src/setup/agent-probe.ts
6
6
  import { execSync } from "child_process";
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  hasGeminiHooks
3
- } from "./chunk-Q223OM5J.js";
3
+ } from "./chunk-6V7ZDH3A.js";
4
4
  import {
5
5
  hasCodexHooks
6
- } from "./chunk-QA72MKIT.js";
6
+ } from "./chunk-OVEGEQSB.js";
7
7
  import {
8
8
  HOOK_LOCATOR_BINARY
9
- } from "./chunk-X6RXX2NF.js";
9
+ } from "./chunk-3MCEES6Z.js";
10
10
 
11
11
  // src/diagnostics/wiring.ts
12
12
  var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
13
13
  var CLAUDE_HOOK_BINARY = /pushary-[a-z-]*hook/;
14
- var EXACT_HOOK_BINARY = /^pushary-[a-z-]*hook$/;
14
+ var EXACT_HOOK_BINARY = /^pushary-[a-z-]*(hook|gate)$/;
15
15
  var pusharyHookExecutable = (command) => {
16
16
  const tokens = command.match(/"[^"]*"|'[^']*'|\S+/g) ?? [];
17
17
  for (const raw of tokens.reverse()) {
18
18
  const token = raw[0] === '"' && raw.at(-1) === '"' || raw[0] === "'" && raw.at(-1) === "'" ? raw.slice(1, -1) : raw;
19
- const name = token.split(/[/\\]/).pop()?.replace(/\.(cmd|exe)$/i, "") ?? "";
19
+ const name = token.split(/[/\\]/).pop()?.replace(/\.(cmd|exe|mjs)$/i, "") ?? "";
20
20
  if (name === HOOK_LOCATOR_BINARY || EXACT_HOOK_BINARY.test(name)) return token;
21
21
  }
22
22
  return null;
@@ -44,10 +44,29 @@ var geminiWired = ({ settings }) => {
44
44
  if (record(s.mcpServers)?.pushary) return true;
45
45
  return hasGeminiHooks(s);
46
46
  };
47
+ var cursorWired = ({ userHooks, mcp, pluginDirExists }) => {
48
+ if (pluginDirExists) return true;
49
+ if (record(record(mcp)?.mcpServers)?.pushary) return true;
50
+ const hooks = record(record(userHooks)?.hooks);
51
+ if (!hooks) return false;
52
+ return Object.values(hooks).some((entries) => Array.isArray(entries) && entries.some((entry) => pusharyHookExecutable(String(record(entry)?.command ?? "")) !== null));
53
+ };
54
+ var cursorMcpAuthorization = (pluginMcp, userMcp) => {
55
+ const pluginServers = record(record(pluginMcp)?.mcpServers);
56
+ const usePlugin = pluginServers !== null && Object.hasOwn(pluginServers, "pushary");
57
+ const servers = usePlugin ? pluginServers : record(record(userMcp)?.mcpServers);
58
+ const headers = record(record(servers?.pushary)?.headers);
59
+ return {
60
+ authorization: typeof headers?.Authorization === "string" ? headers.Authorization : null,
61
+ source: usePlugin ? "plugin mcp.json" : "~/.cursor/mcp.json"
62
+ };
63
+ };
47
64
 
48
65
  export {
49
66
  pusharyHookExecutable,
50
67
  claudeWired,
51
68
  codexWired,
52
- geminiWired
69
+ geminiWired,
70
+ cursorWired,
71
+ cursorMcpAuthorization
53
72
  };
@@ -26,16 +26,16 @@ import {
26
26
  summarizeStop,
27
27
  taskTitleFrom,
28
28
  toolResultErrorText
29
- } from "./chunk-TG3T3M4K.js";
29
+ } from "./chunk-JVZX5YRJ.js";
30
30
  import {
31
31
  getMachineId
32
- } from "./chunk-DKWM5T3P.js";
32
+ } from "./chunk-5NDB3YOE.js";
33
33
  import {
34
34
  withRetry
35
35
  } from "./chunk-BSZYIAZL.js";
36
36
  import {
37
37
  reportedInstallSource
38
- } from "./chunk-IUWRVTQK.js";
38
+ } from "./chunk-XREW7RQ3.js";
39
39
  import {
40
40
  getApiKey,
41
41
  getBaseUrl
@@ -51,7 +51,7 @@ import {
51
51
  pendingCommandEvents,
52
52
  resolveAutoResolveOrigin,
53
53
  resolvePolicy
54
- } from "./chunk-X6RXX2NF.js";
54
+ } from "./chunk-3MCEES6Z.js";
55
55
 
56
56
  // src/policy.ts
57
57
  import { createHash } from "crypto";
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  PRETOOLUSE_HANDLED_TOOLS,
3
3
  PRETOOLUSE_PHONE_ANSWERED_TOOLS
4
- } from "./chunk-6EKQZA6R.js";
4
+ } from "./chunk-KVHP5ZME.js";
5
5
  import {
6
6
  defersToNativeMode
7
- } from "./chunk-NCVIWGVA.js";
7
+ } from "./chunk-GKPURU7P.js";
8
8
  import {
9
9
  isGatingMoment,
10
10
  recordKeylessMoment
11
- } from "./chunk-3HFK3UXM.js";
11
+ } from "./chunk-FCUUVHTS.js";
12
12
  import {
13
13
  denyReasonFrom,
14
14
  isDeferAnswer
@@ -20,7 +20,7 @@ import {
20
20
  readLastUserPrompt,
21
21
  repoKeyFor,
22
22
  throttlePass
23
- } from "./chunk-FXIL7RCL.js";
23
+ } from "./chunk-OADGBOP7.js";
24
24
  import {
25
25
  DEFAULT_SESSION,
26
26
  askUser,
@@ -30,16 +30,17 @@ import {
30
30
  sendNotification
31
31
  } from "./chunk-JHJHCMAF.js";
32
32
  import {
33
+ UNNAMED_ACTION,
33
34
  deriveAction,
34
35
  deriveActionBody,
35
36
  deriveBlocker,
36
37
  deriveToolTarget,
37
38
  describeToolCall,
38
39
  scopePathFor
39
- } from "./chunk-TG3T3M4K.js";
40
+ } from "./chunk-JVZX5YRJ.js";
40
41
  import {
41
42
  getMachineId
42
- } from "./chunk-DKWM5T3P.js";
43
+ } from "./chunk-5NDB3YOE.js";
43
44
  import {
44
45
  getApiKey,
45
46
  getBaseUrl
@@ -54,7 +55,7 @@ import {
54
55
  parseAgentQuestionAnswers,
55
56
  parseAgentQuestions,
56
57
  resolveGate
57
- } from "./chunk-X6RXX2NF.js";
58
+ } from "./chunk-3MCEES6Z.js";
58
59
 
59
60
  // src/decision-episode.ts
60
61
  var EPISODE_PATH = "/api/agent/decision-episode";
@@ -100,7 +101,7 @@ var handlePushOnly = async (apiKey, description, projectName, timeoutSeconds, ti
100
101
  let result;
101
102
  try {
102
103
  result = await askUser(apiKey, {
103
- question: `Allow ${description}?`,
104
+ question: `Allow ${description || UNNAMED_ACTION}?`,
104
105
  type: "confirm",
105
106
  context: `Agent wants to run this in ${projectName}`,
106
107
  agentName: `Claude Code - ${projectName}`,
@@ -168,7 +169,7 @@ var handlePushFirst = async (apiKey, description, projectName, pushFirstSeconds,
168
169
  let result;
169
170
  try {
170
171
  result = await askUser(apiKey, {
171
- question: `Allow ${description}?`,
172
+ question: `Allow ${description || UNNAMED_ACTION}?`,
172
173
  type: "confirm",
173
174
  context: `Agent wants to run this in ${projectName}`,
174
175
  agentName: `Claude Code - ${projectName}`,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  renderCommandHelp
3
- } from "./chunk-3XTFX4CL.js";
3
+ } from "./chunk-RLQWNEPM.js";
4
4
  import {
5
5
  getPackageVersion
6
6
  } from "./chunk-DINDL2CF.js";
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  HOOK_BUDGETS,
3
3
  HOOK_LOCATOR_BINARY
4
- } from "./chunk-X6RXX2NF.js";
4
+ } from "./chunk-3MCEES6Z.js";
5
+
6
+ // src/removal-scope.ts
7
+ var namesAppLocator = (command) => command.includes(HOOK_LOCATOR_BINARY);
8
+ var isProtectedByScope = (command, scope) => scope?.keepAppWiring === true && namesAppLocator(command);
5
9
 
6
10
  // src/codex-config.ts
7
11
  import { createHash } from "crypto";
8
12
  import { homedir } from "os";
9
13
  import { join } from "path";
10
14
 
11
- // src/removal-scope.ts
12
- var namesAppLocator = (command) => command.includes(HOOK_LOCATOR_BINARY);
13
- var isProtectedByScope = (command, scope) => scope?.keepAppWiring === true && namesAppLocator(command);
14
-
15
15
  // src/canonical-json.ts
16
16
  var canonicalJson = (value) => {
17
17
  if (value === null || typeof value !== "object") return JSON.stringify(value);