@pushary/agent-hooks 0.49.0 → 0.50.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.
- package/dist/bin/pushary-claude.js +15 -10
- package/dist/bin/pushary-clean.js +11 -4
- package/dist/bin/pushary-codex-hook.js +5 -5
- package/dist/bin/pushary-codex.js +2 -2
- package/dist/bin/pushary-daemon.js +19 -21
- package/dist/bin/pushary-doctor.js +42 -3
- package/dist/bin/pushary-gemini-hook.js +4 -4
- package/dist/bin/pushary-hook.js +5 -5
- package/dist/bin/pushary-notification-hook.js +2 -2
- package/dist/bin/pushary-permission-denied-hook.js +5 -5
- package/dist/bin/pushary-permission-hook.js +5 -5
- package/dist/bin/pushary-post-hook.js +2 -2
- package/dist/bin/pushary-prompt-hook.js +2 -2
- package/dist/bin/pushary-session-end-hook.js +2 -2
- package/dist/bin/pushary-session-start-hook.js +2 -2
- package/dist/bin/pushary-setup.js +5 -5
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-stop-hook.js +2 -2
- package/dist/bin/pushary-stopfailure-hook.js +2 -2
- package/dist/bin/pushary-upgrade.js +2 -2
- package/dist/{chunk-OW2AJ74U.js → chunk-BC3VCZ3E.js} +3 -1
- package/dist/{chunk-SVVEC4QV.js → chunk-FDRSMTJS.js} +1 -1
- package/dist/{chunk-OQMEGREX.js → chunk-M24KUFLW.js} +6 -6
- package/dist/{chunk-7EW3USQF.js → chunk-PUT2N5VA.js} +1 -1
- package/dist/{chunk-O5MFSRWV.js → chunk-SCXPHMAS.js} +20 -8
- package/dist/{chunk-R5AJNXZS.js → chunk-V42K3XQI.js} +1 -1
- package/dist/{chunk-Z5PL3K7C.js → chunk-WI3F6XNZ.js} +34 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +5 -5
- package/package.json +4 -3
|
@@ -16,12 +16,12 @@ import {
|
|
|
16
16
|
reportEvent,
|
|
17
17
|
resolvePolicy,
|
|
18
18
|
waitForAnswer
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-SCXPHMAS.js";
|
|
20
20
|
import {
|
|
21
21
|
getMachineId
|
|
22
22
|
} from "../chunk-RN3NOEJF.js";
|
|
23
23
|
import "../chunk-DWED7BS3.js";
|
|
24
|
-
import "../chunk-
|
|
24
|
+
import "../chunk-WI3F6XNZ.js";
|
|
25
25
|
import {
|
|
26
26
|
getApiKey,
|
|
27
27
|
getBaseUrl
|
|
@@ -343,7 +343,7 @@ var createRemoteApprover = (deps) => {
|
|
|
343
343
|
const sessionId = deps.getSessionId?.();
|
|
344
344
|
const modeState = await fetchModeState2(deps.apiKey, sessionId);
|
|
345
345
|
if (modeState.kill) return deny("Stopped by user \u2014 this agent was halted from Pushary");
|
|
346
|
-
const policyConfig = await getPolicy2(deps.apiKey, modeState.policyVersion);
|
|
346
|
+
const policyConfig = await getPolicy2(deps.apiKey, modeState.policyVersion, "claude_code");
|
|
347
347
|
const policy = resolvePolicy2(policyConfig, toolName, modeState.mode, input);
|
|
348
348
|
if (policy.timeoutSeconds === 0 && policy.timeoutAction === "approve") return allow(input);
|
|
349
349
|
if (policy.timeoutSeconds === 0 && policy.timeoutAction === "deny") {
|
|
@@ -509,7 +509,7 @@ var startCommandPoller = (opts) => {
|
|
|
509
509
|
schedule(nextDelay());
|
|
510
510
|
};
|
|
511
511
|
schedule(fast);
|
|
512
|
-
opts.log?.("[pushary]
|
|
512
|
+
opts.log?.("[pushary] command poller active");
|
|
513
513
|
return {
|
|
514
514
|
stop() {
|
|
515
515
|
stopped = true;
|
|
@@ -1130,6 +1130,11 @@ var runDualMode = async (binary, args2, startingMode) => {
|
|
|
1130
1130
|
const agentName = `Claude Code - ${projectName}`;
|
|
1131
1131
|
const machineId = getMachineId();
|
|
1132
1132
|
const stdin = createStdinHandoff();
|
|
1133
|
+
const verbose = process.env.PUSHARY_VERBOSE === "1";
|
|
1134
|
+
const verboseLog = (message) => {
|
|
1135
|
+
if (verbose) process.stderr.write(`${message}
|
|
1136
|
+
`);
|
|
1137
|
+
};
|
|
1133
1138
|
const { initialPrompt, resume, permissionMode } = parseRemoteArgs(args2);
|
|
1134
1139
|
const userManagesSession = args2.some((a) => SESSION_FLAG_RE.test(a));
|
|
1135
1140
|
let sessionId = resume;
|
|
@@ -1164,10 +1169,8 @@ var runDualMode = async (binary, args2, startingMode) => {
|
|
|
1164
1169
|
agentType: "claude_code",
|
|
1165
1170
|
getSessionId: () => sessionId,
|
|
1166
1171
|
onCommand: (command) => onPhoneCommand(command),
|
|
1167
|
-
onFatal: (message) =>
|
|
1168
|
-
|
|
1169
|
-
log: (message) => process.stderr.write(`${message}
|
|
1170
|
-
`)
|
|
1172
|
+
onFatal: (message) => verboseLog(`[pushary] relay unavailable (${message}); using polling`),
|
|
1173
|
+
log: verboseLog
|
|
1171
1174
|
});
|
|
1172
1175
|
relay.start();
|
|
1173
1176
|
}
|
|
@@ -1228,8 +1231,7 @@ var runDualMode = async (binary, args2, startingMode) => {
|
|
|
1228
1231
|
activeLeg?.stop("kill");
|
|
1229
1232
|
}
|
|
1230
1233
|
},
|
|
1231
|
-
log:
|
|
1232
|
-
`)
|
|
1234
|
+
log: verboseLog
|
|
1233
1235
|
});
|
|
1234
1236
|
const signals = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
1235
1237
|
const onSignal = () => {
|
|
@@ -1265,6 +1267,9 @@ var runDualMode = async (binary, args2, startingMode) => {
|
|
|
1265
1267
|
};
|
|
1266
1268
|
try {
|
|
1267
1269
|
if (sessionId && startingMode === "local") {
|
|
1270
|
+
process.stderr.write(
|
|
1271
|
+
"[pushary] reachable from your phone \u2014 send an instruction from the app when this goes idle (Ctrl-] keeps the terminal).\n"
|
|
1272
|
+
);
|
|
1268
1273
|
void announcePresence("session_start", "Session ready \u2014 reachable from your phone");
|
|
1269
1274
|
}
|
|
1270
1275
|
if (startingMode === "remote" && initialPrompt) input.push(userMessage(initialPrompt));
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
removeClaudeAlias
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-BC3VCZ3E.js";
|
|
5
5
|
import {
|
|
6
6
|
removeCodexHooks,
|
|
7
7
|
removeGeminiSettings,
|
|
8
8
|
removeInstructionBlock
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-FDRSMTJS.js";
|
|
10
10
|
import {
|
|
11
11
|
execNpm
|
|
12
12
|
} from "../chunk-J7JWI3KU.js";
|
|
13
13
|
import {
|
|
14
14
|
removeClaudeMcpServers,
|
|
15
15
|
removePusharySettings
|
|
16
|
-
} from "../chunk-
|
|
17
|
-
import "../chunk-
|
|
16
|
+
} from "../chunk-PUT2N5VA.js";
|
|
17
|
+
import "../chunk-WI3F6XNZ.js";
|
|
18
18
|
|
|
19
19
|
// bin/pushary-clean.ts
|
|
20
20
|
import { existsSync, readFileSync, writeFileSync, rmSync, readdirSync } from "fs";
|
|
@@ -277,6 +277,13 @@ var main = async () => {
|
|
|
277
277
|
console.log();
|
|
278
278
|
console.log(` ${green(bold("Clean complete."))}`);
|
|
279
279
|
console.log(` ${dim("Run")} npx @pushary/agent-hooks@latest setup ${dim("to reinstall.")}`);
|
|
280
|
+
if (aliasRemovedFrom.length > 0) {
|
|
281
|
+
console.log();
|
|
282
|
+
console.log(` ${yellow("!")} ${bold("One thing left in your current terminal.")}`);
|
|
283
|
+
console.log(` ${dim("It still has the")} ${bold("claude")} ${dim("alias loaded from before. Run")} ${bold("unalias claude")}`);
|
|
284
|
+
console.log(` ${dim("(or open a new terminal) so")} ${bold("claude")} ${dim("runs Claude Code again.")}`);
|
|
285
|
+
}
|
|
286
|
+
console.log(` ${dim("If a")} ${bold("pushary claude")} ${dim("or")} ${bold("pushary daemon")} ${dim("is still running anywhere, stop it (Ctrl-C).")}`);
|
|
280
287
|
console.log();
|
|
281
288
|
};
|
|
282
289
|
main();
|
|
@@ -31,21 +31,21 @@ import {
|
|
|
31
31
|
toCodexWire,
|
|
32
32
|
toPolicyLookup,
|
|
33
33
|
waitForAnswer
|
|
34
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-SCXPHMAS.js";
|
|
35
35
|
import {
|
|
36
36
|
getMachineId
|
|
37
37
|
} from "../chunk-RN3NOEJF.js";
|
|
38
38
|
import {
|
|
39
39
|
isGatingMoment,
|
|
40
40
|
recordKeylessMoment
|
|
41
|
-
} from "../chunk-
|
|
41
|
+
} from "../chunk-V42K3XQI.js";
|
|
42
42
|
import "../chunk-DWED7BS3.js";
|
|
43
43
|
import {
|
|
44
44
|
DECISION_LINE_MAX,
|
|
45
45
|
effectiveWaitSeconds,
|
|
46
46
|
hookWaitClamped,
|
|
47
47
|
hookWaitDeadline
|
|
48
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-WI3F6XNZ.js";
|
|
49
49
|
import {
|
|
50
50
|
getApiKey
|
|
51
51
|
} from "../chunk-NKXSILEW.js";
|
|
@@ -170,7 +170,7 @@ var decidePermissionRequest = async (input) => {
|
|
|
170
170
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
171
171
|
if (modeState.kill) return codexDeny(KILL_REASON);
|
|
172
172
|
const lookup = toPolicyLookup(input.tool_name ?? "", input.tool_input ?? {}, input.cwd);
|
|
173
|
-
const policy = await getPolicy(apiKey, modeState.policyVersion);
|
|
173
|
+
const policy = await getPolicy(apiKey, modeState.policyVersion, "codex");
|
|
174
174
|
const toolPolicy = resolvePolicy(policy, lookup.tool, modeState.mode, lookup.input);
|
|
175
175
|
if (toolPolicy.timeoutSeconds === 0 && toolPolicy.timeoutAction === "approve") return codexAllow();
|
|
176
176
|
if (toolPolicy.timeoutSeconds === 0 && toolPolicy.timeoutAction === "deny") {
|
|
@@ -229,7 +229,7 @@ var decidePreToolUse = async (input) => {
|
|
|
229
229
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
230
230
|
if (modeState.kill) return codexDeny(KILL_REASON);
|
|
231
231
|
const lookup = toPolicyLookup(input.tool_name ?? "", input.tool_input ?? {}, input.cwd);
|
|
232
|
-
const policy = await getPolicy(apiKey, modeState.policyVersion);
|
|
232
|
+
const policy = await getPolicy(apiKey, modeState.policyVersion, "codex");
|
|
233
233
|
const toolPolicy = resolvePolicy(policy, lookup.tool, modeState.mode, lookup.input);
|
|
234
234
|
if (toolPolicy.timeoutSeconds === 0 && toolPolicy.timeoutAction === "approve") return codexPass();
|
|
235
235
|
if (toolPolicy.timeoutSeconds === 0 && toolPolicy.timeoutAction === "deny") {
|
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
askUser,
|
|
4
4
|
reportEvent,
|
|
5
5
|
waitForAnswer
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-SCXPHMAS.js";
|
|
7
7
|
import {
|
|
8
8
|
getMachineId
|
|
9
9
|
} from "../chunk-RN3NOEJF.js";
|
|
10
10
|
import "../chunk-DWED7BS3.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-WI3F6XNZ.js";
|
|
12
12
|
import {
|
|
13
13
|
getApiKey
|
|
14
14
|
} from "../chunk-NKXSILEW.js";
|
|
@@ -14,8 +14,9 @@ import {
|
|
|
14
14
|
} from "../chunk-NKXSILEW.js";
|
|
15
15
|
|
|
16
16
|
// src/spawn-daemon.ts
|
|
17
|
+
import { spawn } from "child_process";
|
|
17
18
|
import { existsSync } from "fs";
|
|
18
|
-
import { basename } from "path";
|
|
19
|
+
import { basename, dirname, join } from "path";
|
|
19
20
|
var DRAIN_PATH = "/api/agent/spawn/drain";
|
|
20
21
|
var FAST_POLL_MS = 3e3;
|
|
21
22
|
var SLOW_POLL_MS = 3e4;
|
|
@@ -43,6 +44,8 @@ var runSpawnDaemon = async () => {
|
|
|
43
44
|
const machineId = getMachineId();
|
|
44
45
|
const baseUrl = getBaseUrl();
|
|
45
46
|
const pusharyBin = resolveGlobalBinary("pushary") ?? "pushary";
|
|
47
|
+
const siblingEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary.js") : "";
|
|
48
|
+
const spawnDirect = siblingEntry.length > 0 && existsSync(siblingEntry);
|
|
46
49
|
let stopped = false;
|
|
47
50
|
let idleTicks = 0;
|
|
48
51
|
let errorStreak = 0;
|
|
@@ -50,20 +53,11 @@ var runSpawnDaemon = async () => {
|
|
|
50
53
|
let timer;
|
|
51
54
|
let inflight;
|
|
52
55
|
const launch = (req) => {
|
|
53
|
-
if (!spawnRateAllows(spawnTimestamps, Date.now())) {
|
|
54
|
-
stderr(`[pushary] spawn rate limit reached; skipping a queued session
|
|
55
|
-
`);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
56
|
spawnTimestamps.push(Date.now());
|
|
59
57
|
const cwd = req.cwd && existsSync(req.cwd) ? req.cwd : process.cwd();
|
|
58
|
+
const args = ["claude", "--remote", "-p", req.prompt];
|
|
60
59
|
try {
|
|
61
|
-
const child =
|
|
62
|
-
cwd,
|
|
63
|
-
detached: true,
|
|
64
|
-
stdio: "ignore",
|
|
65
|
-
env: process.env
|
|
66
|
-
});
|
|
60
|
+
const child = spawnDirect ? spawn(process.execPath, [siblingEntry, ...args], { cwd, detached: true, stdio: "ignore", env: process.env }) : spawnClaude(pusharyBin, args, { cwd, detached: true, stdio: "ignore", env: process.env });
|
|
67
61
|
child.on("error", (err) => stderr(`[pushary] could not launch session: ${err.message}
|
|
68
62
|
`));
|
|
69
63
|
child.unref();
|
|
@@ -83,8 +77,8 @@ var runSpawnDaemon = async () => {
|
|
|
83
77
|
});
|
|
84
78
|
if (!res.ok) throw new Error(`drain ${res.status}`);
|
|
85
79
|
const data = await res.json();
|
|
86
|
-
const
|
|
87
|
-
return
|
|
80
|
+
const spawn2 = data.spawn;
|
|
81
|
+
return spawn2 && typeof spawn2.prompt === "string" && typeof spawn2.id === "string" ? spawn2 : null;
|
|
88
82
|
};
|
|
89
83
|
const nextDelay = () => {
|
|
90
84
|
if (errorStreak > 0) return Math.min(SLOW_POLL_MS * 2 ** (errorStreak - 1), MAX_ERROR_BACKOFF_MS);
|
|
@@ -93,6 +87,10 @@ var runSpawnDaemon = async () => {
|
|
|
93
87
|
const jitter = (ms) => Math.max(1, Math.round(ms * (0.85 + Math.random() * 0.3)));
|
|
94
88
|
const tick = async () => {
|
|
95
89
|
if (stopped) return;
|
|
90
|
+
if (!spawnRateAllows(spawnTimestamps, Date.now())) {
|
|
91
|
+
timer = setTimeout(tick, jitter(nextDelay()));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
96
94
|
const controller = new AbortController();
|
|
97
95
|
inflight = controller;
|
|
98
96
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
@@ -119,18 +117,18 @@ var runSpawnDaemon = async () => {
|
|
|
119
117
|
if (timer) clearTimeout(timer);
|
|
120
118
|
inflight?.abort();
|
|
121
119
|
};
|
|
122
|
-
const signals = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
123
|
-
const onSignal = () => {
|
|
124
|
-
teardown();
|
|
125
|
-
process.exit(0);
|
|
126
|
-
};
|
|
127
|
-
for (const signal of signals) process.on(signal, onSignal);
|
|
128
120
|
stderr(
|
|
129
121
|
`[pushary] daemon online \u2014 this machine (${machineId}) can now be sent a new session from your phone. Ctrl-C to stop.
|
|
130
122
|
`
|
|
131
123
|
);
|
|
132
124
|
timer = setTimeout(tick, FAST_POLL_MS);
|
|
133
|
-
|
|
125
|
+
const signals = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
126
|
+
await new Promise((resolve) => {
|
|
127
|
+
const onSignal = () => {
|
|
128
|
+
teardown();
|
|
129
|
+
resolve();
|
|
130
|
+
};
|
|
131
|
+
for (const signal of signals) process.on(signal, onSignal);
|
|
134
132
|
});
|
|
135
133
|
return 0;
|
|
136
134
|
};
|
|
@@ -11,18 +11,18 @@ import {
|
|
|
11
11
|
missingGeminiHookEvents,
|
|
12
12
|
readCodexMcpAuth,
|
|
13
13
|
untrustedCodexHookEvents
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-FDRSMTJS.js";
|
|
15
15
|
import {
|
|
16
16
|
execNpm
|
|
17
17
|
} from "../chunk-J7JWI3KU.js";
|
|
18
18
|
import {
|
|
19
19
|
readLedgerSummary
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-V42K3XQI.js";
|
|
21
21
|
import {
|
|
22
22
|
callMcpTool,
|
|
23
23
|
sendMcpRequest
|
|
24
24
|
} from "../chunk-DWED7BS3.js";
|
|
25
|
-
import "../chunk-
|
|
25
|
+
import "../chunk-WI3F6XNZ.js";
|
|
26
26
|
import {
|
|
27
27
|
getBaseUrl
|
|
28
28
|
} from "../chunk-NKXSILEW.js";
|
|
@@ -342,6 +342,45 @@ var main = async () => {
|
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
console.log();
|
|
345
|
+
console.log(` ${dim("Remote control")}`);
|
|
346
|
+
const aliasRc = SHELL_FILES.find((f) => {
|
|
347
|
+
try {
|
|
348
|
+
return /alias\s+claude=['"]?pushary claude/.test(readFileSync(f, "utf-8"));
|
|
349
|
+
} catch {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
if (aliasRc) {
|
|
354
|
+
if (globalVersion) {
|
|
355
|
+
check(true, "claude alias \u2192 pushary claude", `set in ${aliasRc.split("/").pop()}`);
|
|
356
|
+
} else {
|
|
357
|
+
check(false, "claude alias \u2192 pushary claude", "alias is set but pushary is not installed \u2014 run `unalias claude` (this shell) or reinstall");
|
|
358
|
+
}
|
|
359
|
+
} else {
|
|
360
|
+
console.log(` ${dim("\u2013")} claude alias not set ${dim("(optional \u2014 run `pushary claude` directly, or re-run setup to add it)")}`);
|
|
361
|
+
}
|
|
362
|
+
if (apiKey) {
|
|
363
|
+
try {
|
|
364
|
+
const modeRes = await fetch(`${getBaseUrl()}/api/mcp/mode`, {
|
|
365
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
366
|
+
signal: AbortSignal.timeout(8e3)
|
|
367
|
+
});
|
|
368
|
+
const relayUrl = modeRes.ok ? (await modeRes.json()).relayUrl : void 0;
|
|
369
|
+
if (typeof relayUrl === "string" && relayUrl.length > 0) {
|
|
370
|
+
const healthUrl = relayUrl.replace(/^wss:/, "https:").replace(/\/relay$/, "/health/ready");
|
|
371
|
+
try {
|
|
372
|
+
const h = await fetch(healthUrl, { signal: AbortSignal.timeout(6e3) });
|
|
373
|
+
console.log(h.ok ? ` ${pass} Relay reachable ${dim("(sub-second phone commands)")}` : ` ${dim("\u2013")} Relay advertised but returned ${h.status} ${dim("(commands still delivered via polling)")}`);
|
|
374
|
+
} catch {
|
|
375
|
+
console.log(` ${dim("\u2013")} Relay advertised but unreachable ${dim("(commands still delivered via polling)")}`);
|
|
376
|
+
}
|
|
377
|
+
} else {
|
|
378
|
+
console.log(` ${dim("\u2013")} Relay not enabled ${dim("(phone commands delivered via polling)")}`);
|
|
379
|
+
}
|
|
380
|
+
} catch {
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
console.log();
|
|
345
384
|
console.log(` ${dim("Connectivity")}`);
|
|
346
385
|
if (!apiKey) {
|
|
347
386
|
check(false, "MCP server reachable", "skipped \u2014 no API key");
|
|
@@ -23,21 +23,21 @@ import {
|
|
|
23
23
|
savePendingQuestion,
|
|
24
24
|
sendNotification,
|
|
25
25
|
waitForAnswer
|
|
26
|
-
} from "../chunk-
|
|
26
|
+
} from "../chunk-SCXPHMAS.js";
|
|
27
27
|
import {
|
|
28
28
|
getMachineId
|
|
29
29
|
} from "../chunk-RN3NOEJF.js";
|
|
30
30
|
import {
|
|
31
31
|
isGatingMoment,
|
|
32
32
|
recordKeylessMoment
|
|
33
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-V42K3XQI.js";
|
|
34
34
|
import "../chunk-DWED7BS3.js";
|
|
35
35
|
import {
|
|
36
36
|
DECISION_LINE_MAX,
|
|
37
37
|
effectiveWaitSeconds,
|
|
38
38
|
hookWaitClamped,
|
|
39
39
|
hookWaitDeadline
|
|
40
|
-
} from "../chunk-
|
|
40
|
+
} from "../chunk-WI3F6XNZ.js";
|
|
41
41
|
import {
|
|
42
42
|
getApiKey
|
|
43
43
|
} from "../chunk-NKXSILEW.js";
|
|
@@ -209,7 +209,7 @@ var decideBeforeTool = async (input) => {
|
|
|
209
209
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
210
210
|
if (modeState.kill) return geminiDeny(KILL_REASON);
|
|
211
211
|
const lookup = toGeminiPolicyLookup(input.tool_name ?? "", input.tool_input ?? {});
|
|
212
|
-
const policy = await getPolicy(apiKey, modeState.policyVersion);
|
|
212
|
+
const policy = await getPolicy(apiKey, modeState.policyVersion, "gemini_cli");
|
|
213
213
|
const toolPolicy = resolvePolicy(policy, lookup.tool, modeState.mode, lookup.input);
|
|
214
214
|
if (toolPolicy.timeoutSeconds === 0 && toolPolicy.timeoutAction === "approve") return geminiAllow();
|
|
215
215
|
if (toolPolicy.timeoutSeconds === 0 && toolPolicy.timeoutAction === "deny") {
|
package/dist/bin/pushary-hook.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePreToolUse
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-M24KUFLW.js";
|
|
5
|
+
import "../chunk-PUT2N5VA.js";
|
|
6
6
|
import "../chunk-KQYIHZ5E.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-SCXPHMAS.js";
|
|
8
8
|
import "../chunk-RN3NOEJF.js";
|
|
9
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-V42K3XQI.js";
|
|
10
10
|
import "../chunk-DWED7BS3.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-WI3F6XNZ.js";
|
|
12
12
|
import "../chunk-NKXSILEW.js";
|
|
13
13
|
|
|
14
14
|
// bin/pushary-hook.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleNotification
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-SCXPHMAS.js";
|
|
5
5
|
import "../chunk-RN3NOEJF.js";
|
|
6
6
|
import "../chunk-DWED7BS3.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-WI3F6XNZ.js";
|
|
8
8
|
import "../chunk-NKXSILEW.js";
|
|
9
9
|
|
|
10
10
|
// bin/pushary-notification-hook.ts
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePermissionDenied
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-M24KUFLW.js";
|
|
5
|
+
import "../chunk-PUT2N5VA.js";
|
|
6
6
|
import "../chunk-KQYIHZ5E.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-SCXPHMAS.js";
|
|
8
8
|
import "../chunk-RN3NOEJF.js";
|
|
9
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-V42K3XQI.js";
|
|
10
10
|
import "../chunk-DWED7BS3.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-WI3F6XNZ.js";
|
|
12
12
|
import "../chunk-NKXSILEW.js";
|
|
13
13
|
|
|
14
14
|
// bin/pushary-permission-denied-hook.ts
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePermissionRequest
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-M24KUFLW.js";
|
|
5
|
+
import "../chunk-PUT2N5VA.js";
|
|
6
6
|
import "../chunk-KQYIHZ5E.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-SCXPHMAS.js";
|
|
8
8
|
import "../chunk-RN3NOEJF.js";
|
|
9
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-V42K3XQI.js";
|
|
10
10
|
import "../chunk-DWED7BS3.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-WI3F6XNZ.js";
|
|
12
12
|
import "../chunk-NKXSILEW.js";
|
|
13
13
|
|
|
14
14
|
// bin/pushary-permission-hook.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePostToolUse
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-SCXPHMAS.js";
|
|
5
5
|
import "../chunk-RN3NOEJF.js";
|
|
6
6
|
import "../chunk-DWED7BS3.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-WI3F6XNZ.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-
|
|
4
|
+
} from "../chunk-SCXPHMAS.js";
|
|
5
5
|
import "../chunk-RN3NOEJF.js";
|
|
6
6
|
import "../chunk-DWED7BS3.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-WI3F6XNZ.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-
|
|
4
|
+
} from "../chunk-SCXPHMAS.js";
|
|
5
5
|
import "../chunk-RN3NOEJF.js";
|
|
6
6
|
import "../chunk-DWED7BS3.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-WI3F6XNZ.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-
|
|
4
|
+
} from "../chunk-SCXPHMAS.js";
|
|
5
5
|
import "../chunk-RN3NOEJF.js";
|
|
6
6
|
import "../chunk-DWED7BS3.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-WI3F6XNZ.js";
|
|
8
8
|
import "../chunk-NKXSILEW.js";
|
|
9
9
|
|
|
10
10
|
// bin/pushary-session-start-hook.ts
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
installClaudeAlias,
|
|
4
4
|
resolveShellRc
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-BC3VCZ3E.js";
|
|
6
6
|
import {
|
|
7
7
|
GEMINI_HOOK_BINARY,
|
|
8
8
|
addCodexHookTrust,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
renderAgentInstructions,
|
|
14
14
|
renderProjectAgentInstructions,
|
|
15
15
|
writeInstructionBlock
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-FDRSMTJS.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-
|
|
28
|
+
} from "../chunk-PUT2N5VA.js";
|
|
29
29
|
import {
|
|
30
30
|
reportEvent
|
|
31
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-SCXPHMAS.js";
|
|
32
32
|
import "../chunk-RN3NOEJF.js";
|
|
33
33
|
import "../chunk-DWED7BS3.js";
|
|
34
34
|
import {
|
|
35
35
|
isValidApiKey
|
|
36
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-WI3F6XNZ.js";
|
|
37
37
|
import "../chunk-NKXSILEW.js";
|
|
38
38
|
|
|
39
39
|
// bin/pushary-setup.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleStop
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-SCXPHMAS.js";
|
|
5
5
|
import "../chunk-RN3NOEJF.js";
|
|
6
6
|
import "../chunk-DWED7BS3.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-WI3F6XNZ.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-
|
|
4
|
+
} from "../chunk-SCXPHMAS.js";
|
|
5
5
|
import "../chunk-RN3NOEJF.js";
|
|
6
6
|
import "../chunk-DWED7BS3.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-WI3F6XNZ.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-
|
|
12
|
-
import "../chunk-
|
|
11
|
+
} from "../chunk-PUT2N5VA.js";
|
|
12
|
+
import "../chunk-WI3F6XNZ.js";
|
|
13
13
|
import {
|
|
14
14
|
getApiKey
|
|
15
15
|
} from "../chunk-NKXSILEW.js";
|
|
@@ -37,7 +37,9 @@ var resolveShellRc = () => {
|
|
|
37
37
|
if (shell === "zsh") return { path: join(home, ".zshrc"), shell };
|
|
38
38
|
if (shell === "bash") {
|
|
39
39
|
const bashrc = join(home, ".bashrc");
|
|
40
|
-
|
|
40
|
+
const profile = join(home, ".bash_profile");
|
|
41
|
+
if (process.platform === "darwin") return { path: profile, shell };
|
|
42
|
+
return { path: existsSync(bashrc) ? bashrc : profile, shell };
|
|
41
43
|
}
|
|
42
44
|
return null;
|
|
43
45
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PRETOOLUSE_HANDLED_TOOLS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PUT2N5VA.js";
|
|
4
4
|
import {
|
|
5
5
|
denyReasonFrom,
|
|
6
6
|
isDeferAnswer
|
|
@@ -23,19 +23,19 @@ import {
|
|
|
23
23
|
sendNotification,
|
|
24
24
|
throttlePass,
|
|
25
25
|
waitForAnswer
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-SCXPHMAS.js";
|
|
27
27
|
import {
|
|
28
28
|
getMachineId
|
|
29
29
|
} from "./chunk-RN3NOEJF.js";
|
|
30
30
|
import {
|
|
31
31
|
isGatingMoment,
|
|
32
32
|
recordKeylessMoment
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-V42K3XQI.js";
|
|
34
34
|
import {
|
|
35
35
|
effectiveWaitSeconds,
|
|
36
36
|
hookWaitClamped,
|
|
37
37
|
hookWaitDeadline
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-WI3F6XNZ.js";
|
|
39
39
|
import {
|
|
40
40
|
getApiKey
|
|
41
41
|
} from "./chunk-NKXSILEW.js";
|
|
@@ -322,7 +322,7 @@ var handlePreToolUse = async (input) => {
|
|
|
322
322
|
}
|
|
323
323
|
try {
|
|
324
324
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
325
|
-
const policy = await getPolicy(apiKey, modeState.policyVersion);
|
|
325
|
+
const policy = await getPolicy(apiKey, modeState.policyVersion, "claude_code");
|
|
326
326
|
if (modeState.kill) {
|
|
327
327
|
return deny("Stopped by user \u2014 this agent was halted from Pushary");
|
|
328
328
|
}
|
|
@@ -374,7 +374,7 @@ var handlePermissionRequest = async (input) => {
|
|
|
374
374
|
}
|
|
375
375
|
try {
|
|
376
376
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
377
|
-
const policy = await getPolicy(apiKey, modeState.policyVersion);
|
|
377
|
+
const policy = await getPolicy(apiKey, modeState.policyVersion, "claude_code");
|
|
378
378
|
if (modeState.kill) return permReqDeny("Stopped by user \u2014 this agent was halted from Pushary");
|
|
379
379
|
const toolPolicy = resolvePolicy(policy, input.tool_name, modeState.mode, input.tool_input);
|
|
380
380
|
if (toolPolicy.timeoutSeconds === 0 && toolPolicy.timeoutAction === "approve") return permReqAllow();
|
|
@@ -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-
|
|
19
|
+
} from "./chunk-WI3F6XNZ.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
|
|
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 };
|
|
@@ -279,6 +279,31 @@ var API_KEY_PATTERN = /^pk_[a-f0-9]+\.[a-f0-9]+$/;
|
|
|
279
279
|
var isValidApiKey = (value) => API_KEY_PATTERN.test(value);
|
|
280
280
|
var ACTION_BODY_MAX = 4e3;
|
|
281
281
|
var DECISION_LINE_MAX = 500;
|
|
282
|
+
var APPROVAL_FATIGUE_FLAG_PATTERNS = [
|
|
283
|
+
/\brm\s+-[a-z]*r/i,
|
|
284
|
+
/\brmdir\b/i,
|
|
285
|
+
/git\s+push[^\n]*(--force|--force-with-lease|\s-f\b)/i,
|
|
286
|
+
/git\s+reset\s+--hard/i,
|
|
287
|
+
/git\s+clean\s+-[a-z]*f/i,
|
|
288
|
+
/\bdrop\s+(table|database|schema)\b/i,
|
|
289
|
+
/\bdelete\s+from\b/i,
|
|
290
|
+
/\btruncate\b/i,
|
|
291
|
+
/\b(deploy|publish|release)\b/i,
|
|
292
|
+
/\bnpm\s+publish\b/i,
|
|
293
|
+
/\bsudo\b/i,
|
|
294
|
+
/chmod\s+-?R?\s*777/i,
|
|
295
|
+
/\bkubectl\s+delete\b/i,
|
|
296
|
+
/\bterraform\s+(apply|destroy)\b/i,
|
|
297
|
+
/\bdocker\s+system\s+prune\b/i
|
|
298
|
+
];
|
|
299
|
+
var HIGH_CONSEQUENCE_PATTERNS = [
|
|
300
|
+
/(^|[\\/])\.env(\.|$|[\\/])/i,
|
|
301
|
+
/secrets?/i,
|
|
302
|
+
/credentials?/i,
|
|
303
|
+
/(^|[\\/])deploy/i,
|
|
304
|
+
/\.github[\\/]workflows/i,
|
|
305
|
+
/package\.json/i
|
|
306
|
+
];
|
|
282
307
|
var SECRET_REDACTION_RULES = [
|
|
283
308
|
{ pattern: /-----BEGIN[A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END[A-Z0-9 ]*PRIVATE KEY-----/g, replacement: "[redacted key]" },
|
|
284
309
|
{ pattern: /\bsk-[A-Za-z0-9_-]{16,}\b/g, replacement: "[redacted]" },
|
|
@@ -303,6 +328,13 @@ var SECRET_REDACTION_RULES = [
|
|
|
303
328
|
var HIGH_ENTROPY_RULE = { pattern: /[A-Za-z0-9+/]{40,}={0,2}/g, replacement: "[redacted]" };
|
|
304
329
|
var redactSecrets = (text) => SECRET_REDACTION_RULES.reduce((acc, rule) => acc.replace(rule.pattern, rule.replacement), text);
|
|
305
330
|
var redactSecretsDeep = (text) => redactSecrets(text).replace(HIGH_ENTROPY_RULE.pattern, HIGH_ENTROPY_RULE.replacement);
|
|
331
|
+
var classifyDecisionRisk = (toolName, toolTarget) => {
|
|
332
|
+
const parts = [toolName, toolTarget ?? ""];
|
|
333
|
+
const matchesAny = (patterns) => parts.some((part) => patterns.some((re) => re.test(part)));
|
|
334
|
+
if (matchesAny(APPROVAL_FATIGUE_FLAG_PATTERNS)) return "destructive";
|
|
335
|
+
if (matchesAny(HIGH_CONSEQUENCE_PATTERNS)) return "elevated";
|
|
336
|
+
return "standard";
|
|
337
|
+
};
|
|
306
338
|
|
|
307
339
|
export {
|
|
308
340
|
isApprovalMode,
|
|
@@ -318,5 +350,6 @@ export {
|
|
|
318
350
|
ACTION_BODY_MAX,
|
|
319
351
|
DECISION_LINE_MAX,
|
|
320
352
|
redactSecrets,
|
|
321
|
-
redactSecretsDeep
|
|
353
|
+
redactSecretsDeep,
|
|
354
|
+
classifyDecisionRisk
|
|
322
355
|
};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ interface ReceiptMeta {
|
|
|
26
26
|
ok: boolean;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
declare const getPolicy: (apiKey: string, expectedVersion?: string | null) => Promise<PolicyConfig>;
|
|
29
|
+
declare const getPolicy: (apiKey: string, expectedVersion?: string | null, agent?: string) => Promise<PolicyConfig>;
|
|
30
30
|
type AutoResolveOrigin = 'safe_readonly' | 'policy_timeout';
|
|
31
31
|
declare const resolvePolicy: (config: PolicyConfig, toolName: string, modeOverride?: ApprovalMode | null, toolInput?: Record<string, unknown>) => ToolPolicy;
|
|
32
32
|
interface ModeState {
|
package/dist/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handlePreToolUse
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-M24KUFLW.js";
|
|
4
|
+
import "../chunk-PUT2N5VA.js";
|
|
5
5
|
import "../chunk-KQYIHZ5E.js";
|
|
6
6
|
import {
|
|
7
7
|
askUser,
|
|
@@ -15,11 +15,11 @@ import {
|
|
|
15
15
|
reportEvent,
|
|
16
16
|
resolvePolicy,
|
|
17
17
|
waitForAnswer
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-SCXPHMAS.js";
|
|
19
19
|
import "../chunk-RN3NOEJF.js";
|
|
20
|
-
import "../chunk-
|
|
20
|
+
import "../chunk-V42K3XQI.js";
|
|
21
21
|
import "../chunk-DWED7BS3.js";
|
|
22
|
-
import "../chunk-
|
|
22
|
+
import "../chunk-WI3F6XNZ.js";
|
|
23
23
|
import {
|
|
24
24
|
getApiKey,
|
|
25
25
|
getBaseUrl
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pushary/agent-hooks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.0",
|
|
4
4
|
"description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pushary",
|
|
@@ -73,12 +73,13 @@
|
|
|
73
73
|
"scripts": {
|
|
74
74
|
"build": "node scripts/bundle-plugin.mjs && tsup",
|
|
75
75
|
"dev": "tsup --watch",
|
|
76
|
-
"test": "bun test src/api.test.ts && bun test src/claude-config.test.ts && bun test src/config.test.ts && bun test src/mcp-http.test.ts && bun test src/retry.test.ts && bun test src/usage.test.ts && bun test src/validate.test.ts && bun test src/policy.test.ts && bun test src/npm.test.ts && bun test src/identity.test.ts && bun test src/pending.test.ts && bun test src/events.test.ts && bun test src/describe.test.ts && bun test src/reapply.test.ts && bun test src/suggestions.test.ts && bun test src/safe-commands.test.ts && bun test src/hook.test.ts && bun test src/codex-adapter.test.ts && bun test src/codex-config.test.ts && bun test src/gemini-adapter.test.ts && bun test src/gemini-config.test.ts && bun test src/instruction-file.test.ts && bun test src/pairing.test.ts && bun test src/wait-ladder.test.ts && bun test src/ledger.test.ts && bun test src/wrapper/wrapper.test.ts && bun test src/wrapper/messageQueue.test.ts && bun test src/wrapper/approver.test.ts && bun test src/wrapper/remoteLoop.test.ts && bun test src/wrapper/spawnClaude.test.ts && bun test src/wrapper/wsProtocol.test.ts && bun test src/wrapper/relayClient.test.ts && bun test src/wrapper/modeLoop.test.ts && bun test src/wrapper/stdinHandoff.test.ts && bun test src/wrapper/localLeg.test.ts"
|
|
76
|
+
"test": "bun test src/api.test.ts && bun test src/claude-config.test.ts && bun test src/config.test.ts && bun test src/mcp-http.test.ts && bun test src/retry.test.ts && bun test src/usage.test.ts && bun test src/validate.test.ts && bun test src/policy.test.ts && bun test src/npm.test.ts && bun test src/identity.test.ts && bun test src/pending.test.ts && bun test src/events.test.ts && bun test src/describe.test.ts && bun test src/reapply.test.ts && bun test src/suggestions.test.ts && bun test src/safe-commands.test.ts && bun test src/hook.test.ts && bun test src/codex-adapter.test.ts && bun test src/codex-config.test.ts && bun test src/gemini-adapter.test.ts && bun test src/gemini-config.test.ts && bun test src/instruction-file.test.ts && bun test src/pairing.test.ts && bun test src/wait-ladder.test.ts && bun test src/ledger.test.ts && bun test src/wrapper/wrapper.test.ts && bun test src/wrapper/messageQueue.test.ts && bun test src/wrapper/approver.test.ts && bun test src/wrapper/remoteLoop.test.ts && bun test src/wrapper/spawnClaude.test.ts && bun test src/wrapper/wsProtocol.test.ts && bun test src/wrapper/relayClient.test.ts && bun test src/wrapper/modeLoop.test.ts && bun test src/wrapper/stdinHandoff.test.ts && bun test src/wrapper/localLeg.test.ts && bun test src/crypto.test.ts && bun test src/transcript-capture.test.ts"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@inquirer/prompts": "^8.4.2",
|
|
80
80
|
"qrcode-terminal": "^0.12.0",
|
|
81
|
-
"smol-toml": "^1.6.1"
|
|
81
|
+
"smol-toml": "^1.6.1",
|
|
82
|
+
"tweetnacl": "^1.0.3"
|
|
82
83
|
},
|
|
83
84
|
"devDependencies": {
|
|
84
85
|
"@pushary/contracts": "workspace:*",
|