@pushary/agent-hooks 1.2.0 → 1.3.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 (85) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/data/SKILL.md +22 -10
  3. package/data/cursor-plugin/skills/pushary/SKILL.md +21 -9
  4. package/data/vscode-plugin/skills/pushary/SKILL.md +21 -9
  5. package/dist/bin/pushary-bell-hook.js +20 -20
  6. package/dist/bin/pushary-bell.js +7 -7
  7. package/dist/bin/pushary-claude.js +20 -20
  8. package/dist/bin/pushary-clean.js +21 -21
  9. package/dist/bin/pushary-codex-bridge.js +11 -11
  10. package/dist/bin/pushary-codex-hook.js +24 -24
  11. package/dist/bin/pushary-codex.js +7 -7
  12. package/dist/bin/pushary-connect.js +7 -7
  13. package/dist/bin/pushary-cowork.js +3 -3
  14. package/dist/bin/pushary-daemon.js +24 -24
  15. package/dist/bin/pushary-disconnect.js +11 -11
  16. package/dist/bin/pushary-doctor.js +35 -22
  17. package/dist/bin/pushary-elicitation-hook.js +19 -19
  18. package/dist/bin/pushary-gemini-bridge.js +10 -10
  19. package/dist/bin/pushary-gemini-hook.js +21 -21
  20. package/dist/bin/pushary-hook.js +30 -40
  21. package/dist/bin/pushary-login.js +8 -8
  22. package/dist/bin/pushary-logout.js +5 -5
  23. package/dist/bin/pushary-mode.js +3 -3
  24. package/dist/bin/pushary-notification-hook.js +22 -22
  25. package/dist/bin/pushary-opencode-hook.js +21 -21
  26. package/dist/bin/pushary-permission-denied-hook.js +26 -26
  27. package/dist/bin/pushary-permission-hook.js +30 -29
  28. package/dist/bin/pushary-post-hook.js +22 -22
  29. package/dist/bin/pushary-prompt-hook.js +22 -22
  30. package/dist/bin/pushary-session-end-hook.js +22 -22
  31. package/dist/bin/pushary-session-start-hook.js +24 -24
  32. package/dist/bin/pushary-setup.js +27 -27
  33. package/dist/bin/pushary-stats.js +2 -2
  34. package/dist/bin/pushary-status.js +11 -11
  35. package/dist/bin/pushary-stop-hook.js +22 -22
  36. package/dist/bin/pushary-stopfailure-hook.js +22 -22
  37. package/dist/bin/pushary-transcript-register.js +18 -18
  38. package/dist/bin/pushary-transcripts.js +6 -6
  39. package/dist/bin/pushary-upgrade.js +15 -15
  40. package/dist/bin/pushary-wait.js +3 -3
  41. package/dist/{chunk-PX53RT6Q.js → chunk-34NNTYK6.js} +1 -1
  42. package/dist/{chunk-7ERWAYVV.js → chunk-35RPUNYU.js} +1 -1
  43. package/dist/{chunk-KZPUARCU.js → chunk-465UENKO.js} +2 -2
  44. package/dist/{chunk-7TDQ7KDY.js → chunk-5SALHATY.js} +2 -2
  45. package/dist/{chunk-7DQVIIHX.js → chunk-5UWDYOZX.js} +33 -6
  46. package/dist/{chunk-ZFQPSGPO.js → chunk-5WLH2ENB.js} +1 -1
  47. package/dist/{chunk-YK3OU4E2.js → chunk-5XKMOZO6.js} +4 -4
  48. package/dist/{chunk-CVCSUAXI.js → chunk-6HH4IH4K.js} +4 -4
  49. package/dist/{chunk-JQJB7BZE.js → chunk-AFKOWCMQ.js} +1 -1
  50. package/dist/{chunk-JOTV75GX.js → chunk-AFOTOA24.js} +1 -1
  51. package/dist/{chunk-6QCN5XQE.js → chunk-CDSL3LLO.js} +1 -1
  52. package/dist/{chunk-4UT44NRP.js → chunk-CKLWJ6EL.js} +10 -2
  53. package/dist/{chunk-VDOKRCWM.js → chunk-EAGMQMRM.js} +1 -1
  54. package/dist/{chunk-WC5PYFDK.js → chunk-FGNABUPN.js} +1 -1
  55. package/dist/{chunk-BXLFUTSD.js → chunk-HCTSTMDD.js} +4 -4
  56. package/dist/{chunk-KODKICKJ.js → chunk-I2OLM3DM.js} +30 -21
  57. package/dist/{chunk-LGO7U23Z.js → chunk-JZA2JOGO.js} +1 -1
  58. package/dist/{chunk-ERP7FOFQ.js → chunk-KHGIM2BN.js} +3 -3
  59. package/dist/{chunk-U42ES5U3.js → chunk-KLZJEMSE.js} +1 -1
  60. package/dist/{chunk-YT6H7BB5.js → chunk-LWT34GSY.js} +20 -13
  61. package/dist/{chunk-VE2ZWUML.js → chunk-NDSOOJDX.js} +1 -1
  62. package/dist/{chunk-2DT7STR5.js → chunk-OMP3KDDU.js} +1 -1
  63. package/dist/{chunk-PCT2MYG5.js → chunk-P232YODQ.js} +8 -8
  64. package/dist/{chunk-7GH3D6YG.js → chunk-PEV6ULSM.js} +3 -3
  65. package/dist/{chunk-CG4ZUQ5O.js → chunk-PHXU4NOP.js} +2 -2
  66. package/dist/{chunk-LAXU5U75.js → chunk-QDYJQLXT.js} +2 -2
  67. package/dist/{chunk-C3WH44MH.js → chunk-QOCWB4Q6.js} +3 -3
  68. package/dist/{chunk-OGSRCIOD.js → chunk-R5CU7ED6.js} +1 -1
  69. package/dist/{chunk-W6XVHP4U.js → chunk-REIZ5GXG.js} +4 -4
  70. package/dist/{chunk-DRAATYTY.js → chunk-RERJ2ZDV.js} +6 -6
  71. package/dist/{chunk-PX54KULQ.js → chunk-SGZE2JBF.js} +3 -3
  72. package/dist/{chunk-YKLCWWEI.js → chunk-SGZJ5LYH.js} +1 -1
  73. package/dist/{chunk-4LL6LG5X.js → chunk-T7E75EKA.js} +4 -3
  74. package/dist/{chunk-VIQ7CCWW.js → chunk-TGG4FWWB.js} +2 -2
  75. package/dist/{chunk-RN6ZWIAC.js → chunk-TW7KA27C.js} +1 -1
  76. package/dist/{chunk-5AATCXJN.js → chunk-WOBHHXW5.js} +4 -4
  77. package/dist/{chunk-KEVJ2WW6.js → chunk-XOUQUZ43.js} +2 -2
  78. package/dist/{chunk-UWP66NDF.js → chunk-XP2KRTZD.js} +1 -1
  79. package/dist/{chunk-LWKVEMVK.js → chunk-XVE52YFZ.js} +1 -1
  80. package/dist/{chunk-KHTBSSY5.js → chunk-YXWM4TNX.js} +1 -1
  81. package/dist/{reapply-47AMVIXN.js → reapply-ADFRVH5N.js} +9 -9
  82. package/dist/src/index.d.ts +2 -2
  83. package/dist/src/index.js +13 -13
  84. package/package.json +1 -1
  85. /package/dist/{chunk-KBITFQST.js → chunk-P32LPT2L.js} +0 -0
@@ -1,31 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  registerTranscript
4
- } from "../chunk-PCT2MYG5.js";
5
- import "../chunk-YKLCWWEI.js";
6
- import "../chunk-W6XVHP4U.js";
7
- import "../chunk-WC5PYFDK.js";
8
- import "../chunk-U42ES5U3.js";
9
- import "../chunk-C3WH44MH.js";
10
- import "../chunk-CVCSUAXI.js";
11
- import "../chunk-ERP7FOFQ.js";
12
- import "../chunk-VDOKRCWM.js";
13
- import "../chunk-6QCN5XQE.js";
4
+ } from "../chunk-P232YODQ.js";
5
+ import "../chunk-SGZJ5LYH.js";
6
+ import "../chunk-REIZ5GXG.js";
7
+ import "../chunk-FGNABUPN.js";
8
+ import "../chunk-KLZJEMSE.js";
9
+ import "../chunk-QOCWB4Q6.js";
10
+ import "../chunk-6HH4IH4K.js";
11
+ import "../chunk-KHGIM2BN.js";
12
+ import "../chunk-EAGMQMRM.js";
13
+ import "../chunk-CDSL3LLO.js";
14
14
  import "../chunk-EQRS3SGM.js";
15
- import "../chunk-KHTBSSY5.js";
15
+ import "../chunk-YXWM4TNX.js";
16
16
  import "../chunk-XHKBHWLX.js";
17
- import "../chunk-UWP66NDF.js";
18
- import "../chunk-KZPUARCU.js";
19
- import "../chunk-PX53RT6Q.js";
17
+ import "../chunk-XP2KRTZD.js";
18
+ import "../chunk-465UENKO.js";
19
+ import "../chunk-34NNTYK6.js";
20
20
  import "../chunk-GMXKITVA.js";
21
21
  import "../chunk-DINDL2CF.js";
22
- import "../chunk-7TDQ7KDY.js";
22
+ import "../chunk-5SALHATY.js";
23
23
  import "../chunk-7QLSKOSU.js";
24
24
  import "../chunk-KZERVKTD.js";
25
- import "../chunk-ZFQPSGPO.js";
26
- import "../chunk-4LL6LG5X.js";
25
+ import "../chunk-5WLH2ENB.js";
26
+ import "../chunk-T7E75EKA.js";
27
27
  import "../chunk-2UMNXADU.js";
28
- import "../chunk-7DQVIIHX.js";
28
+ import "../chunk-5UWDYOZX.js";
29
29
 
30
30
  // bin/pushary-transcript-register.ts
31
31
  var raw = "";
@@ -3,21 +3,21 @@ import {
3
3
  clearPin,
4
4
  fingerprint,
5
5
  loadPin
6
- } from "../chunk-YKLCWWEI.js";
6
+ } from "../chunk-SGZJ5LYH.js";
7
7
  import {
8
8
  transcriptsEnabled
9
- } from "../chunk-KHTBSSY5.js";
9
+ } from "../chunk-YXWM4TNX.js";
10
10
  import {
11
11
  exitOnHelpFlag
12
12
  } from "../chunk-GOQHN2UH.js";
13
13
  import "../chunk-LZQVAEWP.js";
14
14
  import "../chunk-DINDL2CF.js";
15
- import "../chunk-7TDQ7KDY.js";
15
+ import "../chunk-5SALHATY.js";
16
16
  import "../chunk-KZERVKTD.js";
17
- import "../chunk-ZFQPSGPO.js";
18
- import "../chunk-4LL6LG5X.js";
17
+ import "../chunk-5WLH2ENB.js";
18
+ import "../chunk-T7E75EKA.js";
19
19
  import "../chunk-2UMNXADU.js";
20
- import "../chunk-7DQVIIHX.js";
20
+ import "../chunk-5UWDYOZX.js";
21
21
 
22
22
  // bin/pushary-transcripts.ts
23
23
  exitOnHelpFlag("transcripts");
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  reapplyAllAgents
4
- } from "../chunk-DRAATYTY.js";
5
- import "../chunk-JQJB7BZE.js";
4
+ } from "../chunk-RERJ2ZDV.js";
5
+ import "../chunk-AFKOWCMQ.js";
6
6
  import {
7
7
  waitForMachineReadiness
8
- } from "../chunk-YK3OU4E2.js";
9
- import "../chunk-PX54KULQ.js";
8
+ } from "../chunk-5XKMOZO6.js";
9
+ import "../chunk-SGZE2JBF.js";
10
10
  import {
11
11
  detectProviderLiveCapabilities,
12
12
  hasSpawnProvider,
13
13
  resolveControlPolicy
14
- } from "../chunk-CG4ZUQ5O.js";
15
- import "../chunk-C3WH44MH.js";
14
+ } from "../chunk-PHXU4NOP.js";
15
+ import "../chunk-QOCWB4Q6.js";
16
16
  import {
17
17
  daemonHasRemoteProof,
18
18
  daemonServiceManagerAvailable,
@@ -23,13 +23,13 @@ import {
23
23
  replaceDaemonService,
24
24
  stopDaemonService,
25
25
  waitForDaemonRemoteProof
26
- } from "../chunk-CVCSUAXI.js";
27
- import "../chunk-ERP7FOFQ.js";
26
+ } from "../chunk-6HH4IH4K.js";
27
+ import "../chunk-KHGIM2BN.js";
28
28
  import {
29
29
  needsShell
30
30
  } from "../chunk-XHKBHWLX.js";
31
- import "../chunk-UWP66NDF.js";
32
- import "../chunk-KZPUARCU.js";
31
+ import "../chunk-XP2KRTZD.js";
32
+ import "../chunk-465UENKO.js";
33
33
  import {
34
34
  claudeJson,
35
35
  codexConfigToml,
@@ -39,7 +39,7 @@ import {
39
39
  npmErrorMessage,
40
40
  resolveGlobalBinary,
41
41
  vscodePluginDir
42
- } from "../chunk-PX53RT6Q.js";
42
+ } from "../chunk-34NNTYK6.js";
43
43
  import {
44
44
  exitOnHelpFlag
45
45
  } from "../chunk-GOQHN2UH.js";
@@ -49,14 +49,14 @@ import {
49
49
  } from "../chunk-DINDL2CF.js";
50
50
  import {
51
51
  readControlMode
52
- } from "../chunk-7TDQ7KDY.js";
52
+ } from "../chunk-5SALHATY.js";
53
53
  import "../chunk-KZERVKTD.js";
54
- import "../chunk-ZFQPSGPO.js";
55
- import "../chunk-4LL6LG5X.js";
54
+ import "../chunk-5WLH2ENB.js";
55
+ import "../chunk-T7E75EKA.js";
56
56
  import {
57
57
  getApiKey
58
58
  } from "../chunk-2UMNXADU.js";
59
- import "../chunk-7DQVIIHX.js";
59
+ import "../chunk-5UWDYOZX.js";
60
60
 
61
61
  // bin/pushary-upgrade.ts
62
62
  import { existsSync } from "fs";
@@ -4,8 +4,8 @@ import {
4
4
  } from "../chunk-CVWG2N3Y.js";
5
5
  import {
6
6
  exitOnFailedResponse
7
- } from "../chunk-VE2ZWUML.js";
8
- import "../chunk-RN6ZWIAC.js";
7
+ } from "../chunk-NDSOOJDX.js";
8
+ import "../chunk-TW7KA27C.js";
9
9
  import {
10
10
  createIo
11
11
  } from "../chunk-5RUIFDTP.js";
@@ -28,7 +28,7 @@ import {
28
28
  getApiKey,
29
29
  getBaseUrl
30
30
  } from "../chunk-2UMNXADU.js";
31
- import "../chunk-7DQVIIHX.js";
31
+ import "../chunk-5UWDYOZX.js";
32
32
 
33
33
  // bin/pushary-wait.ts
34
34
  exitOnHelpFlag("wait");
@@ -2,7 +2,7 @@ import {
2
2
  HOOK_BUDGETS,
3
3
  HOOK_LOCATOR_BINARY,
4
4
  withHookHoldBudget
5
- } from "./chunk-7DQVIIHX.js";
5
+ } from "./chunk-5UWDYOZX.js";
6
6
 
7
7
  // src/npm.ts
8
8
  import { execFileSync, execSync } from "child_process";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readConfigFileKey
3
- } from "./chunk-7TDQ7KDY.js";
3
+ } from "./chunk-5SALHATY.js";
4
4
 
5
5
  // src/bell/fleet.ts
6
6
  import { closeSync, constants, futimesSync, lstatSync, mkdirSync, openSync, readdirSync, unlinkSync } from "fs";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-PX53RT6Q.js";
3
+ } from "./chunk-34NNTYK6.js";
4
4
  import {
5
5
  writeFileAtomic
6
- } from "./chunk-4LL6LG5X.js";
6
+ } from "./chunk-T7E75EKA.js";
7
7
 
8
8
  // src/identity.ts
9
9
  import { randomUUID } from "crypto";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  resolveInstallSourceFor
3
- } from "./chunk-ZFQPSGPO.js";
3
+ } from "./chunk-5WLH2ENB.js";
4
4
  import {
5
5
  backupFile,
6
6
  readJsonSafe,
7
7
  writeFileAtomic,
8
8
  writeJsonAtomic
9
- } from "./chunk-4LL6LG5X.js";
9
+ } from "./chunk-T7E75EKA.js";
10
10
  import {
11
11
  configFilePath
12
12
  } from "./chunk-2UMNXADU.js";
@@ -154,6 +154,7 @@ var AGENTS = {
154
154
  ...defaults,
155
155
  label: "Qwen Code",
156
156
  hookSource: "qwen",
157
+ bridged: true,
157
158
  policyAgent: "qwen_code",
158
159
  repoAware: true,
159
160
  disconnectable: true,
@@ -166,6 +167,7 @@ var AGENTS = {
166
167
  ...defaults,
167
168
  label: "CodeBuddy",
168
169
  hookSource: "codebuddy",
170
+ bridged: true,
169
171
  policyAgent: "codebuddy",
170
172
  repoAware: true,
171
173
  disconnectable: true,
@@ -178,6 +180,7 @@ var AGENTS = {
178
180
  ...defaults,
179
181
  label: "Qoder",
180
182
  hookSource: "qoder",
183
+ bridged: true,
181
184
  policyAgent: "qoder",
182
185
  repoAware: true,
183
186
  disconnectable: true,
@@ -191,6 +194,7 @@ var AGENTS = {
191
194
  ...defaults,
192
195
  label: "Droid",
193
196
  hookSource: "droid",
197
+ bridged: true,
194
198
  policyAgent: "droid",
195
199
  repoAware: true,
196
200
  disconnectable: true,
@@ -204,6 +208,7 @@ var AGENTS = {
204
208
  ...defaults,
205
209
  label: "Devin CLI",
206
210
  hookSource: "devin",
211
+ bridged: true,
207
212
  policyAgent: "devin",
208
213
  repoAware: true,
209
214
  disconnectable: true,
@@ -436,6 +441,18 @@ var compatibleTargetFiles = (profile) => {
436
441
  return [...seen.values()];
437
442
  };
438
443
 
444
+ // ../contracts/src/degraded.ts
445
+ var DEGRADED_PREFIX = "[degraded]";
446
+ var degradedPayload = (subsystem, report) => ({
447
+ subsystem,
448
+ reason: report.reason,
449
+ fallback: report.fallback,
450
+ ...report.siteId ? { siteId: report.siteId } : {},
451
+ ...report.sessionId ? { sessionId: report.sessionId } : {},
452
+ ...report.event ? { event: report.event } : {}
453
+ });
454
+ var degradedLine = (subsystem, report) => `${DEGRADED_PREFIX} ${JSON.stringify(degradedPayload(subsystem, report))}`;
455
+
439
456
  // ../contracts/src/index.ts
440
457
  var KEY_SCOPES = ["full_access", "agent", "connector", "bound"];
441
458
  var normalizeKeyScope = (value) => typeof value === "string" && KEY_SCOPES.includes(value) ? value : null;
@@ -718,6 +735,7 @@ var shellCommandSegments = (command) => {
718
735
  index += 1;
719
736
  continue;
720
737
  }
738
+ if (quote === SHELL_DOUBLE_QUOTE && (char === "`" || char === SHELL_SUBSTITUTION_SIGIL && next === SHELL_GROUP_OPEN)) return null;
721
739
  if (char === quote) quote = null;
722
740
  current += char;
723
741
  continue;
@@ -1066,7 +1084,7 @@ var verdictForPolicy = (policy) => {
1066
1084
  if (isAutoApprove(policy)) return "allow";
1067
1085
  return "requires_human";
1068
1086
  };
1069
- var policyIntent = (policy) => policy.timeoutAction === "deny" ? PATTERN_INTENT.restrict : PATTERN_INTENT.grant;
1087
+ var policyIntent = (policy) => isAutoApprove(policy) ? PATTERN_INTENT.grant : PATTERN_INTENT.restrict;
1070
1088
  var selectGoverningRule = (policies, toolName, args, repoKey, sessionId) => {
1071
1089
  let best;
1072
1090
  let bestWeight = 0;
@@ -1325,6 +1343,8 @@ var ANSWER_SOURCES = [
1325
1343
  "sandbox"
1326
1344
  ];
1327
1345
  var isAnswerSource = (value) => typeof value === "string" && ANSWER_SOURCES.includes(value);
1346
+ var SETTLED_OUTCOMES = ["approve", "deny"];
1347
+ var isSettledOutcome = (value) => typeof value === "string" && SETTLED_OUTCOMES.includes(value);
1328
1348
  var classifyDecisionRisk = (toolName, toolTarget) => {
1329
1349
  const parts = [toolName, toolTarget ?? ""];
1330
1350
  const matchesAny = (patterns) => parts.some((part) => patterns.some((re) => re.test(part)));
@@ -1372,6 +1392,13 @@ var CAPABILITY_PATTERNS = {
1372
1392
  };
1373
1393
  var DECISION_EPISODE_SCHEMA_VERSION = 1;
1374
1394
  var DECISION_FEATURE_EXTRACTOR = `pushary-hooks/schema-${DECISION_EPISODE_SCHEMA_VERSION}`;
1395
+ var DECISION_ORIGIN = {
1396
+ human: "human",
1397
+ autopilot: "autopilot",
1398
+ safeReadonly: "safe_readonly",
1399
+ policyTimeout: "policy_timeout",
1400
+ killSwitch: "kill_switch"
1401
+ };
1375
1402
  var EPISODE_CAPABILITIES = [...POLICY_CAPABILITIES, "other"];
1376
1403
  var NETWORK_COMMAND_PATTERNS = [
1377
1404
  /\bcurl\b/i,
@@ -1445,9 +1472,8 @@ var deriveBlastRadius = (capability, riskClass, targetClass) => {
1445
1472
  return "low";
1446
1473
  };
1447
1474
  var deriveLabelTier = (origin, decision) => {
1448
- if (origin === "autopilot") return "none";
1449
- if (origin === "human" && (decision === "approve" || decision === "deny")) return "bronze";
1450
- return "bronze";
1475
+ if (origin !== DECISION_ORIGIN.human) return "none";
1476
+ return isSettledOutcome(decision) ? "bronze" : "none";
1451
1477
  };
1452
1478
  var buildDecisionEpisodeFeatures = (input) => {
1453
1479
  const isCommand = isCommandTool(input.toolName);
@@ -1539,9 +1565,9 @@ var resolveAutoResolveOrigin = (config, toolName, toolInput, cwd, repoKey, sessi
1539
1565
  const match = selectGoverningRule(config.policies, toolName, args, repoKey, sessionId);
1540
1566
  const governedBySpecificRule = match?.rank === "exact" || match?.rank === "prefix";
1541
1567
  if (!governedBySpecificRule && toolName === "Bash" && typeof arg === "string" && isSafeReadOnlyCommand(arg)) {
1542
- return "safe_readonly";
1568
+ return DECISION_ORIGIN.safeReadonly;
1543
1569
  }
1544
- return "policy_timeout";
1570
+ return DECISION_ORIGIN.autopilot;
1545
1571
  };
1546
1572
  var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, sessionId) => {
1547
1573
  const args = toolInput ? policyArgForms(toolName, toolInput, cwd) : [];
@@ -1991,6 +2017,7 @@ export {
1991
2017
  hookCompatibleProfile,
1992
2018
  hookCompatibleProfileBySource,
1993
2019
  compatibleTargetFiles,
2020
+ degradedLine,
1994
2021
  hookWritePath,
1995
2022
  isHookActivationReport,
1996
2023
  hookActivationResult,
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2UMNXADU.js";
4
4
  import {
5
5
  normalizeInstallSource
6
- } from "./chunk-7DQVIIHX.js";
6
+ } from "./chunk-5UWDYOZX.js";
7
7
 
8
8
  // src/install-source.ts
9
9
  import { readFileSync } from "fs";
@@ -2,24 +2,24 @@ import {
2
2
  detectProviderLiveCapabilities,
3
3
  hasSpawnProvider,
4
4
  resolveControlPolicy
5
- } from "./chunk-CG4ZUQ5O.js";
5
+ } from "./chunk-PHXU4NOP.js";
6
6
  import {
7
7
  daemonHasRemoteProof,
8
8
  daemonServiceManagerAvailable,
9
9
  hasDaemonServiceDefinition,
10
10
  readDaemonNeedsLogin,
11
11
  readDaemonStatus
12
- } from "./chunk-CVCSUAXI.js";
12
+ } from "./chunk-6HH4IH4K.js";
13
13
  import {
14
14
  getMachineId
15
- } from "./chunk-KZPUARCU.js";
15
+ } from "./chunk-465UENKO.js";
16
16
  import {
17
17
  getPackageVersion
18
18
  } from "./chunk-DINDL2CF.js";
19
19
  import {
20
20
  readControlMode,
21
21
  readKeySource
22
- } from "./chunk-7TDQ7KDY.js";
22
+ } from "./chunk-5SALHATY.js";
23
23
  import {
24
24
  getBaseUrl
25
25
  } from "./chunk-2UMNXADU.js";
@@ -4,23 +4,23 @@ import {
4
4
  } from "./chunk-XHKBHWLX.js";
5
5
  import {
6
6
  getMachineId
7
- } from "./chunk-KZPUARCU.js";
7
+ } from "./chunk-465UENKO.js";
8
8
  import {
9
9
  pusharyDir,
10
10
  resolveGlobalBinary
11
- } from "./chunk-PX53RT6Q.js";
11
+ } from "./chunk-34NNTYK6.js";
12
12
  import {
13
13
  getPackageVersion
14
14
  } from "./chunk-DINDL2CF.js";
15
15
  import {
16
16
  readControlMode
17
- } from "./chunk-7TDQ7KDY.js";
17
+ } from "./chunk-5SALHATY.js";
18
18
  import {
19
19
  readJsonSafe,
20
20
  writeFileAtomic,
21
21
  writeJsonAtomic,
22
22
  writeJsonAtomicDurable
23
- } from "./chunk-4LL6LG5X.js";
23
+ } from "./chunk-T7E75EKA.js";
24
24
  import {
25
25
  getApiKey
26
26
  } from "./chunk-2UMNXADU.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseVersion
3
- } from "./chunk-ERP7FOFQ.js";
3
+ } from "./chunk-KHGIM2BN.js";
4
4
 
5
5
  // src/setup/agent-probe.ts
6
6
  import { execSync } from "child_process";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolvePathBinary
3
- } from "./chunk-PX53RT6Q.js";
3
+ } from "./chunk-34NNTYK6.js";
4
4
 
5
5
  // src/hermes-config.ts
6
6
  import { execFileSync } from "child_process";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  redactSecrets
3
- } from "./chunk-7DQVIIHX.js";
3
+ } from "./chunk-5UWDYOZX.js";
4
4
 
5
5
  // src/crypto.ts
6
6
  import nacl from "tweetnacl";
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  registerTranscript
3
- } from "./chunk-PCT2MYG5.js";
3
+ } from "./chunk-P232YODQ.js";
4
+ import {
5
+ degradedLine
6
+ } from "./chunk-5UWDYOZX.js";
4
7
 
5
8
  // src/admission.ts
6
9
  import { readFileSync } from "fs";
@@ -40,7 +43,12 @@ var matches = (rule, source, event) => {
40
43
  var isAdmitted = (rules, source, event) => !rules.disabled.some((rule) => matches(rule, source, event));
41
44
  var readHookInput = async (source, fallbackEvent = "", stdin = process.stdin) => {
42
45
  if (source === null) {
43
- process.stderr.write("[pushary] unrecognised --agent, standing aside rather than acting as another agent\n");
46
+ process.stderr.write(`${degradedLine("hook", {
47
+ reason: "unknown_agent",
48
+ fallback: "stood aside, so nothing is gated or reported for this call",
49
+ event: fallbackEvent
50
+ })}
51
+ `);
44
52
  return null;
45
53
  }
46
54
  let raw = "";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  guardBinary
3
- } from "./chunk-PX53RT6Q.js";
3
+ } from "./chunk-34NNTYK6.js";
4
4
 
5
5
  // src/bell/install.ts
6
6
  import { join } from "path";
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  COMPATIBLE_AGENT_TYPES,
9
9
  isValidApiKey
10
- } from "./chunk-7DQVIIHX.js";
10
+ } from "./chunk-5UWDYOZX.js";
11
11
 
12
12
  // src/setup/options.ts
13
13
  var AGENT_CHOICES = ["claude_code", "codex", "gemini_cli", "hermes", "cursor", "vscode", "opencode", ...COMPATIBLE_AGENT_TYPES, "custom"];
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  canonicalGateInputs
3
- } from "./chunk-5AATCXJN.js";
3
+ } from "./chunk-WOBHHXW5.js";
4
4
  import {
5
5
  canonicalJson
6
- } from "./chunk-PX53RT6Q.js";
6
+ } from "./chunk-34NNTYK6.js";
7
7
  import {
8
8
  writeFileAtomic
9
- } from "./chunk-4LL6LG5X.js";
9
+ } from "./chunk-T7E75EKA.js";
10
10
  import {
11
11
  BLOCKED_ACTION_GRANT_TTL_SECONDS,
12
12
  blockedActionIdentity,
13
13
  shouldDeferToNativeMode
14
- } from "./chunk-7DQVIIHX.js";
14
+ } from "./chunk-5UWDYOZX.js";
15
15
 
16
16
  // src/native-defer.ts
17
17
  var nativeDeferOptions = () => {
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  activeIdentity
3
- } from "./chunk-YT6H7BB5.js";
3
+ } from "./chunk-LWT34GSY.js";
4
4
  import {
5
5
  blockedActionFingerprint,
6
6
  defersToNativeMode,
7
7
  forgetBlockedActionHint,
8
8
  hasBlockedActionHint,
9
9
  recordBlockedActionHint
10
- } from "./chunk-BXLFUTSD.js";
10
+ } from "./chunk-HCTSTMDD.js";
11
11
  import {
12
12
  isGatingMoment,
13
13
  recordKeylessMoment
14
- } from "./chunk-2DT7STR5.js";
14
+ } from "./chunk-OMP3KDDU.js";
15
15
  import {
16
16
  denyReasonFrom,
17
17
  isDeferAnswer
@@ -34,7 +34,7 @@ import {
34
34
  scopePathFor,
35
35
  settleQuestionsForToolUse,
36
36
  throttlePass
37
- } from "./chunk-5AATCXJN.js";
37
+ } from "./chunk-WOBHHXW5.js";
38
38
  import {
39
39
  DECISION_STOP_REASON,
40
40
  askUser,
@@ -49,7 +49,7 @@ import {
49
49
  } from "./chunk-LGXUGYUH.js";
50
50
  import {
51
51
  getMachineId
52
- } from "./chunk-KZPUARCU.js";
52
+ } from "./chunk-465UENKO.js";
53
53
  import {
54
54
  getApiKey,
55
55
  getBaseUrl
@@ -73,7 +73,7 @@ import {
73
73
  parseAgentQuestions,
74
74
  resolveGate,
75
75
  stoppedOutput
76
- } from "./chunk-7DQVIIHX.js";
76
+ } from "./chunk-5UWDYOZX.js";
77
77
 
78
78
  // src/decision-episode.ts
79
79
  var EPISODE_PATH = "/api/agent/decision-episode";
@@ -450,19 +450,25 @@ var handleKeyless = (input) => {
450
450
  }
451
451
  return void 0;
452
452
  };
453
- var claudeGateInput = (modeState, config, input) => {
454
- const scopePath = modeState.scope ? scopePathFor(input.tool_name, input.tool_input, input.cwd) : void 0;
453
+ var claudeGateInput = (modeState, config, input, canonical) => {
454
+ const toolName = canonical?.toolName ?? input.tool_name;
455
+ const toolInputs = canonical?.toolInputs ?? [input.tool_input ?? {}];
455
456
  return {
456
457
  modeState,
457
458
  config,
458
- toolName: input.tool_name,
459
- toolInputs: [input.tool_input ?? {}],
460
- scopePaths: scopePath ? [scopePath] : [],
459
+ toolName,
460
+ toolInputs,
461
+ scopePaths: modeState.scope ? toolInputs.flatMap((args) => {
462
+ const path = scopePathFor(toolName, args, input.cwd);
463
+ return path ? [path] : [];
464
+ }) : [],
461
465
  cwd: input.cwd,
462
466
  repoKey: repoKeyFor(input.cwd),
463
467
  sessionId: input.session_id
464
468
  };
465
469
  };
470
+ var unreadableReason = "Pushary could not read every target of this call. Use a supported command or a single-file edit.";
471
+ var batchScopeReason = "This patch exceeds the agreed scope. Split it into single-file edits so each additional path can be approved.";
466
472
  var BLOCKED_ACTION_GATE_TIMEOUT_MS = 15e3;
467
473
  var BLOCKED_ACTION_CLAIM_TIMEOUT_MS = 4e3;
468
474
  var BLOCKED_ACTION_ALLOW_REASON = "Approved from Pushary after auto mode blocked it";
@@ -502,7 +508,7 @@ var claimedBlockedActionRetry = async (apiKey, input) => {
502
508
  return false;
503
509
  }
504
510
  };
505
- var handlePreToolUse = async (input) => {
511
+ var handlePreToolUse = async (input, canonical) => {
506
512
  if (isPusharyOwnTool(input.tool_name)) return void 0;
507
513
  let apiKey;
508
514
  try {
@@ -513,9 +519,11 @@ var handlePreToolUse = async (input) => {
513
519
  try {
514
520
  const modeState = await fetchModeState(apiKey, input.session_id);
515
521
  const policy = await getPolicy(apiKey, modeState.policyVersion, ACTIVE_AGENT.type, true, input.session_id);
516
- const verdict = resolveGate(claudeGateInput(modeState, policy, input));
522
+ const verdict = resolveGate(claudeGateInput(modeState, policy, input, canonical));
517
523
  if (verdict.kind === "kill") return halted(verdict.reason);
518
524
  if (verdict.kind === "deny") return deny(verdict.reason);
525
+ if (canonical === null) return deny(unreadableReason);
526
+ if (verdict.kind === "gate" && verdict.scopeReason && (canonical?.toolInputs.length ?? 0) > 1) return deny(batchScopeReason);
519
527
  if (input.tool_name === "AskUserQuestion") {
520
528
  return handleAskUserQuestion(apiKey, input, modeState);
521
529
  }
@@ -523,7 +531,7 @@ var handlePreToolUse = async (input) => {
523
531
  return handleExitPlanMode(apiKey, input);
524
532
  }
525
533
  if (await claimedBlockedActionRetry(apiKey, input)) return allow(BLOCKED_ACTION_ALLOW_REASON);
526
- if (shouldDeferToNativeMode(input.permission_mode, input.tool_name)) {
534
+ if (!(verdict.kind === "gate" && verdict.scopeReason) && shouldDeferToNativeMode(input.permission_mode, input.tool_name)) {
527
535
  return void 0;
528
536
  }
529
537
  switch (verdict.kind) {
@@ -553,8 +561,8 @@ var toPermissionRequestOutput = (hookOutput) => {
553
561
  if (d.permissionDecision === "deny") return permReqDeny(d.permissionDecisionReason);
554
562
  return void 0;
555
563
  };
556
- var handlePermissionRequest = async (input) => {
557
- if (isPermissionRequestOwnedByPreToolUse(input.tool_name, input.permission_mode, shouldDeferToNativeMode)) return void 0;
564
+ var handlePermissionRequest = async (input, canonical) => {
565
+ if (canonical === void 0 && isPermissionRequestOwnedByPreToolUse(input.tool_name, input.permission_mode, shouldDeferToNativeMode)) return void 0;
558
566
  if (isPusharyOwnTool(input.tool_name)) return void 0;
559
567
  let apiKey;
560
568
  try {
@@ -565,14 +573,15 @@ var handlePermissionRequest = async (input) => {
565
573
  try {
566
574
  const modeState = await fetchModeState(apiKey, input.session_id);
567
575
  const policy = await getPolicy(apiKey, modeState.policyVersion, ACTIVE_AGENT.type, true, input.session_id);
568
- const verdict = resolveGate(claudeGateInput(modeState, policy, input));
576
+ const verdict = resolveGate(claudeGateInput(modeState, policy, input, canonical));
577
+ if (verdict.kind === "kill") return permReqHalted(verdict.reason);
578
+ if (verdict.kind === "deny") return permReqDeny(verdict.reason);
579
+ if (canonical === null) return permReqDeny(unreadableReason);
580
+ if (verdict.kind === "gate" && verdict.scopeReason && (canonical?.toolInputs.length ?? 0) > 1) return permReqDeny(batchScopeReason);
581
+ if (!(verdict.kind === "gate" && verdict.scopeReason) && isPermissionRequestOwnedByPreToolUse(input.tool_name, input.permission_mode, shouldDeferToNativeMode)) return void 0;
569
582
  switch (verdict.kind) {
570
- case "kill":
571
- return permReqHalted(verdict.reason);
572
583
  case "allow":
573
584
  return permReqAllow();
574
- case "deny":
575
- return permReqDeny(verdict.reason);
576
585
  // No opinion, so Claude Code's own dialog shows.
577
586
  case "defer":
578
587
  return void 0;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_HOLD_BUDGET_ENV,
3
3
  hookHoldBudgetProof
4
- } from "./chunk-7DQVIIHX.js";
4
+ } from "./chunk-5UWDYOZX.js";
5
5
 
6
6
  // src/hold-budget.ts
7
7
  var takeHookHoldBudget = (args = process.argv.slice(2), env = process.env) => {