@pushary/agent-hooks 0.21.0 → 0.22.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/data/cursor-plugin/scripts/pushary-gate.mjs +28 -2
- package/dist/bin/pushary-codex-hook.js +49 -33
- package/dist/bin/pushary-codex.js +3 -5
- package/dist/bin/pushary-gemini-hook.js +30 -15
- package/dist/bin/pushary-hook.js +4 -4
- package/dist/bin/pushary-post-hook.js +2 -3
- package/dist/bin/pushary-prompt-hook.js +2 -3
- package/dist/bin/pushary-setup.js +1 -1
- package/dist/bin/pushary-stop-hook.js +2 -3
- package/dist/chunk-2Q6XPZ4Q.js +395 -0
- package/dist/chunk-3LC4YUMA.js +194 -0
- package/dist/chunk-5LTQNC7R.js +824 -0
- package/dist/chunk-6A3WCJO2.js +416 -0
- package/dist/chunk-6QWFMVCD.js +328 -0
- package/dist/chunk-BYNYYZWW.js +412 -0
- package/dist/chunk-FGZZRCOG.js +194 -0
- package/dist/chunk-GTJGZBTQ.js +328 -0
- package/dist/chunk-KQYIHZ5E.js +8 -0
- package/dist/chunk-M4GDBGXF.js +824 -0
- package/dist/chunk-M5F2L4KF.js +177 -0
- package/dist/chunk-PSSHNBEL.js +177 -0
- package/dist/chunk-WPVL6VIT.js +160 -0
- package/dist/src/index.d.ts +5 -1
- package/dist/src/index.js +8 -10
- package/package.json +1 -1
|
@@ -231,6 +231,25 @@ const fetchModeState = async (apiKey, sessionId) => {
|
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
// ── action body capture + redaction (inlined mirror of describe.ts, since this
|
|
235
|
+
// dependency-free hook cannot import the workspace) ──────────────────────────────
|
|
236
|
+
const ACTION_BODY_MAX = 4000
|
|
237
|
+
const ACTION_BODY_TRUNCATION_MARKER = '\n… [truncated]'
|
|
238
|
+
const REDACTION_RULES = [
|
|
239
|
+
[/\bsk-[A-Za-z0-9]{20,}\b/g, '[redacted]'],
|
|
240
|
+
[/\bpk_(?:live|test)_[A-Za-z0-9]+\b/g, '[redacted]'],
|
|
241
|
+
[/\brk_[A-Za-z0-9]+\b/g, '[redacted]'],
|
|
242
|
+
[/\bAKIA[0-9A-Z]{16}\b/g, '[redacted]'],
|
|
243
|
+
[/\bbearer\s+[A-Za-z0-9._-]+/gi, 'bearer [redacted]'],
|
|
244
|
+
[/\bauthorization:\s*\S+/gi, 'authorization: [redacted]'],
|
|
245
|
+
[/((?:secret|token|password|passwd|api[_-]?key|private[_-]?key)\s*[=:]\s*)(\S+)/gi, '$1[redacted]'],
|
|
246
|
+
[/[A-Za-z0-9+/]{40,}={0,2}/g, '[redacted]'],
|
|
247
|
+
]
|
|
248
|
+
const redactSecrets = (text) => REDACTION_RULES.reduce((acc, [pattern, replacement]) => acc.replace(pattern, replacement), text)
|
|
249
|
+
const capActionBody = (text) =>
|
|
250
|
+
text.length <= ACTION_BODY_MAX ? text : `${text.slice(0, ACTION_BODY_MAX - ACTION_BODY_TRUNCATION_MARKER.length)}${ACTION_BODY_TRUNCATION_MARKER}`
|
|
251
|
+
const deriveActionBody = (command) => capActionBody(redactSecrets(command))
|
|
252
|
+
|
|
234
253
|
// ── ask / wait ───────────────────────────────────────────────────────────────
|
|
235
254
|
const askArgs = (command, project, ident) => ({
|
|
236
255
|
question: `Allow this command?\n\n${command}`,
|
|
@@ -240,6 +259,7 @@ const askArgs = (command, project, ident) => ({
|
|
|
240
259
|
sessionId: ident.sessionId,
|
|
241
260
|
machineId: ident.machineId,
|
|
242
261
|
toolName: 'Bash',
|
|
262
|
+
actionBody: deriveActionBody(command),
|
|
243
263
|
wait: false,
|
|
244
264
|
})
|
|
245
265
|
|
|
@@ -278,7 +298,10 @@ const handlePushOnly = async (apiKey, command, project, ident, timeoutSeconds, t
|
|
|
278
298
|
const realMs = Math.max(timeoutSeconds, 1) * 1000
|
|
279
299
|
const cap = Math.min(realMs, MAX_BLOCK_MS)
|
|
280
300
|
const answer = await pollForAnswer(apiKey, asked.correlationId, Date.now() + cap)
|
|
281
|
-
if (answer.answered)
|
|
301
|
+
if (answer.answered) {
|
|
302
|
+
if (answer.value === 'defer') return ask()
|
|
303
|
+
return answer.value === 'yes' ? ALLOW : deny(DENIED)
|
|
304
|
+
}
|
|
282
305
|
|
|
283
306
|
// If Cursor's hook limit cut us off before the configured timeout, hand off to
|
|
284
307
|
// Cursor's own prompt rather than misapplying the policy's timeout action.
|
|
@@ -298,7 +321,10 @@ const handlePushFirst = async (apiKey, command, project, ident, pushFirstSeconds
|
|
|
298
321
|
|
|
299
322
|
const cap = Math.min(Math.max(pushFirstSeconds, 1) * 1000, MAX_BLOCK_MS)
|
|
300
323
|
const answer = await pollForAnswer(apiKey, asked.correlationId, Date.now() + cap)
|
|
301
|
-
if (answer.answered)
|
|
324
|
+
if (answer.answered) {
|
|
325
|
+
if (answer.value === 'defer') return ask()
|
|
326
|
+
return answer.value === 'yes' ? ALLOW : deny(DENIED)
|
|
327
|
+
}
|
|
302
328
|
return ask('Sent to your phone via Pushary — you can also approve here.')
|
|
303
329
|
}
|
|
304
330
|
|
|
@@ -1,35 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
denyReasonFrom
|
|
4
|
-
|
|
3
|
+
denyReasonFrom,
|
|
4
|
+
isDeferAnswer
|
|
5
|
+
} from "../chunk-KQYIHZ5E.js";
|
|
5
6
|
import {
|
|
6
7
|
CODEX_AGENT,
|
|
8
|
+
DEFAULT_SESSION,
|
|
9
|
+
askUser,
|
|
7
10
|
codexAllow,
|
|
8
11
|
codexDeny,
|
|
9
12
|
codexPass,
|
|
13
|
+
deriveActionBody,
|
|
14
|
+
deriveBlocker,
|
|
15
|
+
deriveToolTarget,
|
|
16
|
+
describeApplyPatch,
|
|
17
|
+
describeToolCall,
|
|
18
|
+
fetchModeState,
|
|
19
|
+
getMachineId,
|
|
20
|
+
getPolicy,
|
|
10
21
|
handlePostToolUse,
|
|
11
22
|
handleStop,
|
|
12
23
|
handleUserPrompt,
|
|
13
24
|
permissionTimeoutDecision,
|
|
14
25
|
preToolUseTimeoutDecision,
|
|
26
|
+
readLastPrompt,
|
|
15
27
|
reportEvent,
|
|
16
|
-
toCodexWire,
|
|
17
|
-
toPolicyLookup
|
|
18
|
-
} from "../chunk-QY4L6XHN.js";
|
|
19
|
-
import {
|
|
20
|
-
DEFAULT_SESSION,
|
|
21
|
-
askUser,
|
|
22
|
-
deriveToolTarget,
|
|
23
|
-
describeToolCall,
|
|
24
|
-
fetchModeState,
|
|
25
|
-
getMachineId,
|
|
26
|
-
getPolicy,
|
|
27
28
|
resolvePolicy,
|
|
28
29
|
savePendingQuestion,
|
|
29
30
|
sendNotification,
|
|
31
|
+
toCodexWire,
|
|
32
|
+
toPolicyLookup,
|
|
30
33
|
waitForAnswer
|
|
31
|
-
} from "../chunk-
|
|
32
|
-
import
|
|
34
|
+
} from "../chunk-M4GDBGXF.js";
|
|
35
|
+
import {
|
|
36
|
+
DECISION_LINE_MAX
|
|
37
|
+
} from "../chunk-WPVL6VIT.js";
|
|
33
38
|
import "../chunk-DWED7BS3.js";
|
|
34
39
|
import {
|
|
35
40
|
getApiKey
|
|
@@ -41,6 +46,7 @@ import { tmpdir, userInfo } from "os";
|
|
|
41
46
|
import { existsSync, mkdirSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
42
47
|
var KILL_REASON = "Stopped by user: this agent was halted from Pushary";
|
|
43
48
|
var MAX_WAIT_SECONDS = 170;
|
|
49
|
+
var START_MS = Date.now();
|
|
44
50
|
var APPROVAL_TTL_MS = 10 * 60 * 1e3;
|
|
45
51
|
var sanitizeId = (value) => value.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 128);
|
|
46
52
|
var userScope = () => {
|
|
@@ -104,11 +110,10 @@ var pollForAnswer = async (apiKey, correlationId, deadlineMs, pollInterval = 2e3
|
|
|
104
110
|
return { answered: false };
|
|
105
111
|
};
|
|
106
112
|
var agentNameFor = (input) => `Codex - ${basename(input.cwd ?? process.cwd())}`;
|
|
107
|
-
var
|
|
108
|
-
|
|
109
|
-
const toolInput = input.tool_input ?? {};
|
|
113
|
+
var describeFor = (input, lookup) => input.tool_name === "apply_patch" ? describeApplyPatch(input.tool_input?.command) ?? describeToolCall(lookup.tool, lookup.input, "hook") : describeToolCall(lookup.tool, lookup.input, "hook");
|
|
114
|
+
var pushQuestion = async (apiKey, input, lookup, waitSeconds, mode) => {
|
|
110
115
|
const projectName = basename(input.cwd ?? process.cwd());
|
|
111
|
-
const description =
|
|
116
|
+
const description = describeFor(input, lookup);
|
|
112
117
|
const result = await askUser(apiKey, {
|
|
113
118
|
question: `Allow ${description}?`,
|
|
114
119
|
type: "confirm",
|
|
@@ -116,18 +121,25 @@ var pushQuestion = async (apiKey, input, waitSeconds) => {
|
|
|
116
121
|
agentName: agentNameFor(input),
|
|
117
122
|
sessionId: input.session_id,
|
|
118
123
|
machineId: getMachineId(),
|
|
119
|
-
toolName,
|
|
120
|
-
toolTarget: deriveToolTarget(
|
|
124
|
+
toolName: lookup.tool,
|
|
125
|
+
toolTarget: deriveToolTarget(lookup.tool, lookup.input),
|
|
126
|
+
intent: readLastPrompt(input.session_id || DEFAULT_SESSION),
|
|
127
|
+
action: description.slice(0, DECISION_LINE_MAX),
|
|
128
|
+
blocker: deriveBlocker(mode),
|
|
129
|
+
actionBody: deriveActionBody(input.tool_name ?? "", input.tool_input ?? {})
|
|
121
130
|
});
|
|
122
|
-
const deadline =
|
|
131
|
+
const deadline = Math.min(
|
|
132
|
+
Date.now() + Math.min(waitSeconds, MAX_WAIT_SECONDS) * 1e3,
|
|
133
|
+
START_MS + MAX_WAIT_SECONDS * 1e3
|
|
134
|
+
);
|
|
123
135
|
const answer = await pollForAnswer(apiKey, result.correlationId, deadline);
|
|
124
136
|
return { answer, correlationId: result.correlationId };
|
|
125
137
|
};
|
|
126
|
-
var notifyApprovalNeeded = async (apiKey, input) => {
|
|
138
|
+
var notifyApprovalNeeded = async (apiKey, input, lookup) => {
|
|
127
139
|
try {
|
|
128
140
|
await sendNotification(apiKey, {
|
|
129
141
|
title: "Agent needs approval",
|
|
130
|
-
body:
|
|
142
|
+
body: describeFor(input, lookup),
|
|
131
143
|
agentName: agentNameFor(input),
|
|
132
144
|
sessionId: input.session_id,
|
|
133
145
|
machineId: getMachineId()
|
|
@@ -140,7 +152,7 @@ var decidePermissionRequest = async (input) => {
|
|
|
140
152
|
const apiKey = getApiKey();
|
|
141
153
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
142
154
|
if (modeState.kill) return codexDeny(KILL_REASON);
|
|
143
|
-
const lookup = toPolicyLookup(input.tool_name ?? "", input.tool_input ?? {});
|
|
155
|
+
const lookup = toPolicyLookup(input.tool_name ?? "", input.tool_input ?? {}, input.cwd);
|
|
144
156
|
const policy = await getPolicy(apiKey, modeState.policyVersion);
|
|
145
157
|
const toolPolicy = resolvePolicy(policy, lookup.tool, modeState.mode, lookup.input);
|
|
146
158
|
if (toolPolicy.timeoutSeconds === 0 && toolPolicy.timeoutAction === "approve") return codexAllow();
|
|
@@ -149,12 +161,13 @@ var decidePermissionRequest = async (input) => {
|
|
|
149
161
|
}
|
|
150
162
|
if (toolPolicy.mode === "terminal_only") return codexPass();
|
|
151
163
|
if (toolPolicy.mode === "notify_only") {
|
|
152
|
-
if (claimNotify(input.tool_use_id)) await notifyApprovalNeeded(apiKey, input);
|
|
164
|
+
if (claimNotify(input.tool_use_id)) await notifyApprovalNeeded(apiKey, input, lookup);
|
|
153
165
|
return codexPass();
|
|
154
166
|
}
|
|
155
167
|
const waitSeconds = toolPolicy.mode === "push_first" ? toolPolicy.pushFirstSeconds : toolPolicy.timeoutSeconds;
|
|
156
|
-
const { answer, correlationId } = await pushQuestion(apiKey, input, waitSeconds);
|
|
168
|
+
const { answer, correlationId } = await pushQuestion(apiKey, input, lookup, waitSeconds, toolPolicy.mode);
|
|
157
169
|
if (answer.answered) {
|
|
170
|
+
if (isDeferAnswer(answer.value)) return codexPass();
|
|
158
171
|
if (answer.value === "yes") {
|
|
159
172
|
if (toolPolicy.mode === "push_only") markApproved(input.tool_use_id);
|
|
160
173
|
return codexAllow();
|
|
@@ -175,7 +188,7 @@ var decidePreToolUse = async (input) => {
|
|
|
175
188
|
const apiKey = getApiKey();
|
|
176
189
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
177
190
|
if (modeState.kill) return codexDeny(KILL_REASON);
|
|
178
|
-
const lookup = toPolicyLookup(input.tool_name ?? "", input.tool_input ?? {});
|
|
191
|
+
const lookup = toPolicyLookup(input.tool_name ?? "", input.tool_input ?? {}, input.cwd);
|
|
179
192
|
const policy = await getPolicy(apiKey, modeState.policyVersion);
|
|
180
193
|
const toolPolicy = resolvePolicy(policy, lookup.tool, modeState.mode, lookup.input);
|
|
181
194
|
if (toolPolicy.timeoutSeconds === 0 && toolPolicy.timeoutAction === "approve") return codexPass();
|
|
@@ -186,19 +199,20 @@ var decidePreToolUse = async (input) => {
|
|
|
186
199
|
if (consumeApproval(input.tool_use_id)) return codexPass();
|
|
187
200
|
let pushed;
|
|
188
201
|
try {
|
|
189
|
-
pushed = await pushQuestion(apiKey, input, toolPolicy.timeoutSeconds);
|
|
202
|
+
pushed = await pushQuestion(apiKey, input, lookup, toolPolicy.timeoutSeconds, "push_only");
|
|
190
203
|
} catch {
|
|
191
204
|
return preToolUseTimeoutDecision(toolPolicy.timeoutAction, "Push notification failed, denying per policy");
|
|
192
205
|
}
|
|
193
206
|
const { answer, correlationId } = pushed;
|
|
194
207
|
if (answer.answered) {
|
|
208
|
+
if (isDeferAnswer(answer.value)) return codexPass();
|
|
195
209
|
return answer.value === "yes" ? codexPass() : codexDeny(denyReasonFrom(answer.value));
|
|
196
210
|
}
|
|
197
211
|
savePendingQuestion(input.session_id || DEFAULT_SESSION, correlationId);
|
|
198
212
|
return preToolUseTimeoutDecision(toolPolicy.timeoutAction);
|
|
199
213
|
}
|
|
200
214
|
if (toolPolicy.mode === "notify_only") {
|
|
201
|
-
if (claimNotify(input.tool_use_id)) await notifyApprovalNeeded(apiKey, input);
|
|
215
|
+
if (claimNotify(input.tool_use_id)) await notifyApprovalNeeded(apiKey, input, lookup);
|
|
202
216
|
return codexPass();
|
|
203
217
|
}
|
|
204
218
|
return codexPass();
|
|
@@ -244,15 +258,17 @@ var main = async () => {
|
|
|
244
258
|
case "PreToolUse":
|
|
245
259
|
emit(toCodexWire("PreToolUse", await decidePreToolUse(input)));
|
|
246
260
|
break;
|
|
247
|
-
case "PostToolUse":
|
|
261
|
+
case "PostToolUse": {
|
|
262
|
+
const lookup = toPolicyLookup(input.tool_name ?? "", input.tool_input ?? {}, input.cwd);
|
|
248
263
|
await handlePostToolUse({
|
|
249
|
-
tool_name:
|
|
250
|
-
tool_input: input
|
|
264
|
+
tool_name: lookup.tool,
|
|
265
|
+
tool_input: lookup.input,
|
|
251
266
|
tool_result: asToolResult(input.tool_response),
|
|
252
267
|
cwd: input.cwd,
|
|
253
268
|
session_id: input.session_id
|
|
254
269
|
}, CODEX_AGENT);
|
|
255
270
|
break;
|
|
271
|
+
}
|
|
256
272
|
case "UserPromptSubmit":
|
|
257
273
|
await handleUserPrompt({
|
|
258
274
|
prompt: input.prompt,
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
reportEvent
|
|
4
|
-
} from "../chunk-QY4L6XHN.js";
|
|
5
2
|
import {
|
|
6
3
|
askUser,
|
|
7
4
|
getMachineId,
|
|
5
|
+
reportEvent,
|
|
8
6
|
waitForAnswer
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-M4GDBGXF.js";
|
|
8
|
+
import "../chunk-WPVL6VIT.js";
|
|
11
9
|
import "../chunk-DWED7BS3.js";
|
|
12
10
|
import {
|
|
13
11
|
getApiKey
|
|
@@ -1,27 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
denyReasonFrom
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
handlePostToolUse,
|
|
7
|
-
handleStop,
|
|
8
|
-
handleUserPrompt,
|
|
9
|
-
reportEvent
|
|
10
|
-
} from "../chunk-QY4L6XHN.js";
|
|
3
|
+
denyReasonFrom,
|
|
4
|
+
isDeferAnswer
|
|
5
|
+
} from "../chunk-KQYIHZ5E.js";
|
|
11
6
|
import {
|
|
12
7
|
DEFAULT_SESSION,
|
|
13
8
|
askUser,
|
|
9
|
+
deriveActionBody,
|
|
10
|
+
deriveBlocker,
|
|
14
11
|
deriveToolTarget,
|
|
15
12
|
describeToolCall,
|
|
16
13
|
fetchModeState,
|
|
17
14
|
getMachineId,
|
|
18
15
|
getPolicy,
|
|
16
|
+
handlePostToolUse,
|
|
17
|
+
handleStop,
|
|
18
|
+
handleUserPrompt,
|
|
19
|
+
readLastPrompt,
|
|
20
|
+
readLastUserPrompt,
|
|
21
|
+
reportEvent,
|
|
19
22
|
resolvePolicy,
|
|
20
23
|
savePendingQuestion,
|
|
21
24
|
sendNotification,
|
|
22
25
|
waitForAnswer
|
|
23
|
-
} from "../chunk-
|
|
24
|
-
import
|
|
26
|
+
} from "../chunk-M4GDBGXF.js";
|
|
27
|
+
import {
|
|
28
|
+
DECISION_LINE_MAX
|
|
29
|
+
} from "../chunk-WPVL6VIT.js";
|
|
25
30
|
import "../chunk-DWED7BS3.js";
|
|
26
31
|
import {
|
|
27
32
|
getApiKey
|
|
@@ -66,6 +71,7 @@ var geminiTimeoutDecision = (timeoutAction, denyReason = "No response within tim
|
|
|
66
71
|
// bin/pushary-gemini-hook.ts
|
|
67
72
|
var KILL_REASON = "Stopped by user: this agent was halted from Pushary";
|
|
68
73
|
var MAX_WAIT_SECONDS = 170;
|
|
74
|
+
var START_MS = Date.now();
|
|
69
75
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
70
76
|
var pollForAnswer = async (apiKey, correlationId, deadlineMs, pollInterval = 2e3) => {
|
|
71
77
|
while (Date.now() < deadlineMs) {
|
|
@@ -85,7 +91,7 @@ var pollForAnswer = async (apiKey, correlationId, deadlineMs, pollInterval = 2e3
|
|
|
85
91
|
return { answered: false };
|
|
86
92
|
};
|
|
87
93
|
var agentNameFor = (input) => `${GEMINI_AGENT.label} - ${basename(input.cwd ?? process.cwd())}`;
|
|
88
|
-
var pushQuestion = async (apiKey, input, lookup, waitSeconds, pollInterval = 2e3) => {
|
|
94
|
+
var pushQuestion = async (apiKey, input, lookup, waitSeconds, mode, pollInterval = 2e3) => {
|
|
89
95
|
const projectName = basename(input.cwd ?? process.cwd());
|
|
90
96
|
const description = describeToolCall(lookup.tool, lookup.input, "hook");
|
|
91
97
|
const result = await askUser(apiKey, {
|
|
@@ -96,9 +102,16 @@ var pushQuestion = async (apiKey, input, lookup, waitSeconds, pollInterval = 2e3
|
|
|
96
102
|
sessionId: input.session_id,
|
|
97
103
|
machineId: getMachineId(),
|
|
98
104
|
toolName: lookup.tool,
|
|
99
|
-
toolTarget: deriveToolTarget(lookup.tool, lookup.input)
|
|
105
|
+
toolTarget: deriveToolTarget(lookup.tool, lookup.input),
|
|
106
|
+
intent: readLastPrompt(input.session_id || DEFAULT_SESSION) ?? (input.transcript_path ? readLastUserPrompt(input.transcript_path) : void 0),
|
|
107
|
+
action: description.slice(0, DECISION_LINE_MAX),
|
|
108
|
+
blocker: deriveBlocker(mode),
|
|
109
|
+
actionBody: deriveActionBody(input.tool_name ?? "", input.tool_input ?? {})
|
|
100
110
|
});
|
|
101
|
-
const deadline =
|
|
111
|
+
const deadline = Math.min(
|
|
112
|
+
Date.now() + Math.min(waitSeconds, MAX_WAIT_SECONDS) * 1e3,
|
|
113
|
+
START_MS + MAX_WAIT_SECONDS * 1e3
|
|
114
|
+
);
|
|
102
115
|
const answer = await pollForAnswer(apiKey, result.correlationId, deadline, pollInterval);
|
|
103
116
|
return { answer, correlationId: result.correlationId };
|
|
104
117
|
};
|
|
@@ -117,12 +130,13 @@ var notifyApprovalNeeded = async (apiKey, input, lookup) => {
|
|
|
117
130
|
var handlePushOnly = async (apiKey, input, lookup, timeoutSeconds, timeoutAction) => {
|
|
118
131
|
let pushed;
|
|
119
132
|
try {
|
|
120
|
-
pushed = await pushQuestion(apiKey, input, lookup, timeoutSeconds);
|
|
133
|
+
pushed = await pushQuestion(apiKey, input, lookup, timeoutSeconds, "push_only");
|
|
121
134
|
} catch {
|
|
122
135
|
return geminiTimeoutDecision(timeoutAction, "Push notification failed, denying per policy");
|
|
123
136
|
}
|
|
124
137
|
const { answer, correlationId } = pushed;
|
|
125
138
|
if (answer.answered) {
|
|
139
|
+
if (isDeferAnswer(answer.value)) return geminiPass();
|
|
126
140
|
return answer.value === "yes" ? geminiAllow() : geminiDeny(denyReasonFrom(answer.value));
|
|
127
141
|
}
|
|
128
142
|
savePendingQuestion(input.session_id || DEFAULT_SESSION, correlationId);
|
|
@@ -131,12 +145,13 @@ var handlePushOnly = async (apiKey, input, lookup, timeoutSeconds, timeoutAction
|
|
|
131
145
|
var handlePushFirst = async (apiKey, input, lookup, pushFirstSeconds) => {
|
|
132
146
|
let pushed;
|
|
133
147
|
try {
|
|
134
|
-
pushed = await pushQuestion(apiKey, input, lookup, pushFirstSeconds, 1500);
|
|
148
|
+
pushed = await pushQuestion(apiKey, input, lookup, pushFirstSeconds, "push_first", 1500);
|
|
135
149
|
} catch {
|
|
136
150
|
return geminiPass();
|
|
137
151
|
}
|
|
138
152
|
const { answer, correlationId } = pushed;
|
|
139
153
|
if (answer.answered) {
|
|
154
|
+
if (isDeferAnswer(answer.value)) return geminiPass();
|
|
140
155
|
return answer.value === "yes" ? geminiAllow() : geminiDeny(denyReasonFrom(answer.value));
|
|
141
156
|
}
|
|
142
157
|
savePendingQuestion(input.session_id || DEFAULT_SESSION, correlationId);
|
package/dist/bin/pushary-hook.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePreToolUse
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-FGZZRCOG.js";
|
|
5
|
+
import "../chunk-KQYIHZ5E.js";
|
|
6
|
+
import "../chunk-M4GDBGXF.js";
|
|
7
|
+
import "../chunk-WPVL6VIT.js";
|
|
8
8
|
import "../chunk-DWED7BS3.js";
|
|
9
9
|
import "../chunk-NKXSILEW.js";
|
|
10
10
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePostToolUse
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-USUCPCUC.js";
|
|
4
|
+
} from "../chunk-M4GDBGXF.js";
|
|
5
|
+
import "../chunk-WPVL6VIT.js";
|
|
7
6
|
import "../chunk-DWED7BS3.js";
|
|
8
7
|
import "../chunk-NKXSILEW.js";
|
|
9
8
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleUserPrompt
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-USUCPCUC.js";
|
|
4
|
+
} from "../chunk-M4GDBGXF.js";
|
|
5
|
+
import "../chunk-WPVL6VIT.js";
|
|
7
6
|
import "../chunk-DWED7BS3.js";
|
|
8
7
|
import "../chunk-NKXSILEW.js";
|
|
9
8
|
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from "../chunk-BHAMEPOP.js";
|
|
18
18
|
import {
|
|
19
19
|
isValidApiKey
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-WPVL6VIT.js";
|
|
21
21
|
|
|
22
22
|
// bin/pushary-setup.ts
|
|
23
23
|
import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync, cpSync, rmSync, chmodSync } from "fs";
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleStop
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-USUCPCUC.js";
|
|
4
|
+
} from "../chunk-M4GDBGXF.js";
|
|
5
|
+
import "../chunk-WPVL6VIT.js";
|
|
7
6
|
import "../chunk-DWED7BS3.js";
|
|
8
7
|
import "../chunk-NKXSILEW.js";
|
|
9
8
|
|