@pushary/agent-hooks 0.49.1 → 0.51.0

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.
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePostToolUse
4
- } from "../chunk-O5MFSRWV.js";
4
+ } from "../chunk-BEK4SJNX.js";
5
5
  import "../chunk-RN3NOEJF.js";
6
6
  import "../chunk-DWED7BS3.js";
7
- import "../chunk-Z5PL3K7C.js";
7
+ import "../chunk-CJBVT33U.js";
8
8
  import "../chunk-NKXSILEW.js";
9
9
 
10
10
  // bin/pushary-post-hook.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleUserPrompt
4
- } from "../chunk-O5MFSRWV.js";
4
+ } from "../chunk-BEK4SJNX.js";
5
5
  import "../chunk-RN3NOEJF.js";
6
6
  import "../chunk-DWED7BS3.js";
7
- import "../chunk-Z5PL3K7C.js";
7
+ import "../chunk-CJBVT33U.js";
8
8
  import "../chunk-NKXSILEW.js";
9
9
 
10
10
  // bin/pushary-prompt-hook.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionEnd
4
- } from "../chunk-O5MFSRWV.js";
4
+ } from "../chunk-BEK4SJNX.js";
5
5
  import "../chunk-RN3NOEJF.js";
6
6
  import "../chunk-DWED7BS3.js";
7
- import "../chunk-Z5PL3K7C.js";
7
+ import "../chunk-CJBVT33U.js";
8
8
  import "../chunk-NKXSILEW.js";
9
9
 
10
10
  // bin/pushary-session-end-hook.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionStart
4
- } from "../chunk-O5MFSRWV.js";
4
+ } from "../chunk-BEK4SJNX.js";
5
5
  import "../chunk-RN3NOEJF.js";
6
6
  import "../chunk-DWED7BS3.js";
7
- import "../chunk-Z5PL3K7C.js";
7
+ import "../chunk-CJBVT33U.js";
8
8
  import "../chunk-NKXSILEW.js";
9
9
 
10
10
  // bin/pushary-session-start-hook.ts
@@ -13,7 +13,7 @@ import {
13
13
  renderAgentInstructions,
14
14
  renderProjectAgentInstructions,
15
15
  writeInstructionBlock
16
- } from "../chunk-SVVEC4QV.js";
16
+ } from "../chunk-ORKNGSJI.js";
17
17
  import {
18
18
  execNpm,
19
19
  npmErrorMessage,
@@ -25,15 +25,15 @@ import {
25
25
  addClaudeMcpServer,
26
26
  addPusharyHooks,
27
27
  addPusharyToolPermissions
28
- } from "../chunk-7EW3USQF.js";
28
+ } from "../chunk-K74PMS6N.js";
29
29
  import {
30
30
  reportEvent
31
- } from "../chunk-O5MFSRWV.js";
31
+ } from "../chunk-BEK4SJNX.js";
32
32
  import "../chunk-RN3NOEJF.js";
33
33
  import "../chunk-DWED7BS3.js";
34
34
  import {
35
35
  isValidApiKey
36
- } from "../chunk-Z5PL3K7C.js";
36
+ } from "../chunk-CJBVT33U.js";
37
37
  import "../chunk-NKXSILEW.js";
38
38
 
39
39
  // bin/pushary-setup.ts
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  readLedgerSummary
4
- } from "../chunk-R5AJNXZS.js";
5
- import "../chunk-Z5PL3K7C.js";
4
+ } from "../chunk-LRGSMQH2.js";
5
+ import "../chunk-CJBVT33U.js";
6
6
  import {
7
7
  getApiKey
8
8
  } from "../chunk-NKXSILEW.js";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleStop
4
- } from "../chunk-O5MFSRWV.js";
4
+ } from "../chunk-BEK4SJNX.js";
5
5
  import "../chunk-RN3NOEJF.js";
6
6
  import "../chunk-DWED7BS3.js";
7
- import "../chunk-Z5PL3K7C.js";
7
+ import "../chunk-CJBVT33U.js";
8
8
  import "../chunk-NKXSILEW.js";
9
9
 
10
10
  // bin/pushary-stop-hook.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleStopFailure
4
- } from "../chunk-O5MFSRWV.js";
4
+ } from "../chunk-BEK4SJNX.js";
5
5
  import "../chunk-RN3NOEJF.js";
6
6
  import "../chunk-DWED7BS3.js";
7
- import "../chunk-Z5PL3K7C.js";
7
+ import "../chunk-CJBVT33U.js";
8
8
  import "../chunk-NKXSILEW.js";
9
9
 
10
10
  // bin/pushary-stopfailure-hook.ts
@@ -8,8 +8,8 @@ import {
8
8
  addClaudeMcpServer,
9
9
  addPusharyHooks,
10
10
  addPusharyToolPermissions
11
- } from "../chunk-7EW3USQF.js";
12
- import "../chunk-Z5PL3K7C.js";
11
+ } from "../chunk-K74PMS6N.js";
12
+ import "../chunk-CJBVT33U.js";
13
13
  import {
14
14
  getApiKey
15
15
  } from "../chunk-NKXSILEW.js";
@@ -8,6 +8,7 @@ import {
8
8
  import {
9
9
  ACTION_BODY_MAX,
10
10
  DECISION_LINE_MAX,
11
+ classifyDecisionRisk,
11
12
  extractPolicyArg,
12
13
  isApprovalMode,
13
14
  isSafeReadOnlyCommand,
@@ -15,7 +16,7 @@ import {
15
16
  matchToolPattern,
16
17
  redactSecrets,
17
18
  redactSecretsDeep
18
- } from "./chunk-Z5PL3K7C.js";
19
+ } from "./chunk-CJBVT33U.js";
19
20
  import {
20
21
  getApiKey,
21
22
  getBaseUrl
@@ -46,14 +47,15 @@ var isWaitForAnswerResponse = (data) => {
46
47
 
47
48
  // src/policy.ts
48
49
  var CACHE_TTL_MS = 60 * 1e3;
49
- var cacheFile = (apiKey) => {
50
- const hash = createHash("sha256").update(apiKey).digest("hex").slice(0, 12);
50
+ var cacheFile = (apiKey, agent) => {
51
+ const hash = createHash("sha256").update(agent ? `${apiKey}:${agent}` : apiKey).digest("hex").slice(0, 12);
51
52
  return join(tmpdir(), `pushary-policy-${hash}.json`);
52
53
  };
53
- var fetchPolicy = async (apiKey) => {
54
+ var fetchPolicy = async (apiKey, agent) => {
54
55
  return withRetry(async () => {
55
56
  const baseUrl = getBaseUrl();
56
- const response = await fetch(`${baseUrl}/api/mcp/policy`, {
57
+ const url = agent ? `${baseUrl}/api/mcp/policy?agent=${encodeURIComponent(agent)}` : `${baseUrl}/api/mcp/policy`;
58
+ const response = await fetch(url, {
57
59
  headers: { "Authorization": `Bearer ${apiKey}` },
58
60
  signal: AbortSignal.timeout(1e4)
59
61
  });
@@ -65,8 +67,8 @@ var fetchPolicy = async (apiKey) => {
65
67
  return raw;
66
68
  }, { maxAttempts: 2 });
67
69
  };
68
- var getPolicy = async (apiKey, expectedVersion) => {
69
- const path = cacheFile(apiKey);
70
+ var getPolicy = async (apiKey, expectedVersion, agent) => {
71
+ const path = cacheFile(apiKey, agent);
70
72
  let staleCache = null;
71
73
  if (existsSync(path)) {
72
74
  try {
@@ -83,7 +85,7 @@ var getPolicy = async (apiKey, expectedVersion) => {
83
85
  }
84
86
  }
85
87
  try {
86
- const policy = await fetchPolicy(apiKey);
88
+ const policy = await fetchPolicy(apiKey, agent);
87
89
  try {
88
90
  writeFileSync(path, JSON.stringify({ ...policy, _cachedAt: Date.now(), _policyVersion: expectedVersion ?? null }), "utf-8");
89
91
  } catch {
@@ -141,6 +143,16 @@ var resolvePolicy = (config, toolName, modeOverride, toolInput) => {
141
143
  if (!governedBySpecificRule && toolName === "Bash" && typeof arg === "string" && isSafeReadOnlyCommand(arg)) {
142
144
  base = autoApprove(base.tool);
143
145
  }
146
+ const wouldAutoApprove = base.timeoutSeconds === 0 && base.timeoutAction === "approve";
147
+ if (!governedBySpecificRule && wouldAutoApprove && toolName === "Bash" && typeof arg === "string" && classifyDecisionRisk(toolName, arg) === "destructive") {
148
+ base = {
149
+ tool: base.tool,
150
+ timeoutSeconds: config.defaultTimeoutSeconds,
151
+ timeoutAction: "wait",
152
+ mode: "push_first",
153
+ pushFirstSeconds: config.defaultPushFirstSeconds ?? 20
154
+ };
155
+ }
144
156
  const effectiveOverride = modeOverride ?? config.modeOverride;
145
157
  if (effectiveOverride) {
146
158
  return { ...base, mode: effectiveOverride };
@@ -156,17 +168,18 @@ var fetchModeState = async (apiKey, sessionId) => {
156
168
  headers: { "Authorization": `Bearer ${apiKey}` },
157
169
  signal: AbortSignal.timeout(3e3)
158
170
  });
159
- if (!response.ok) return { mode: null, kill: false, policyVersion: null, relayUrl: null };
171
+ if (!response.ok) return { mode: null, kill: false, policyVersion: null, relayUrl: null, trainingConsent: false };
160
172
  const data = await response.json();
161
173
  const mode = data.override?.mode;
162
174
  return {
163
175
  mode: isApprovalMode(mode) ? mode : null,
164
176
  kill: data.kill === true,
165
177
  policyVersion: toPolicyVersion(data.policyVersion),
166
- relayUrl: typeof data.relayUrl === "string" && data.relayUrl.length > 0 ? data.relayUrl : null
178
+ relayUrl: typeof data.relayUrl === "string" && data.relayUrl.length > 0 ? data.relayUrl : null,
179
+ trainingConsent: data.trainingConsent === true
167
180
  };
168
181
  } catch {
169
- return { mode: null, kill: false, policyVersion: null, relayUrl: null };
182
+ return { mode: null, kill: false, policyVersion: null, relayUrl: null, trainingConsent: false };
170
183
  }
171
184
  };
172
185
  var fetchModeOverride = async (apiKey) => (await fetchModeState(apiKey)).mode;
@@ -795,6 +808,9 @@ var reportEvent = async (event, options = {}) => {
795
808
  ...event,
796
809
  machineId: event.machineId ?? getMachineId(),
797
810
  installMode: detectInstallMode(),
811
+ // Link-back for a phone-spawned session: forward the spawn id the daemon
812
+ // set in the environment so the server can map spawnId -> sessionId.
813
+ ...process.env.PUSHARY_SPAWN_ID ? { spawnId: process.env.PUSHARY_SPAWN_ID } : {},
798
814
  // Advertise that this client reads `pendingCommand` back off the
799
815
  // response, so the server may drain the phone-queued instruction on
800
816
  // activity events (tool_complete/tool_error/user_prompt), not only Stop.