@pushary/agent-hooks 0.87.3 → 0.88.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 +9 -0
- package/data/cursor-plugin/scripts/pushary-gate.test.mjs +39 -0
- package/dist/bin/pushary-bell-hook.js +4 -4
- package/dist/bin/pushary-bell.js +5 -5
- package/dist/bin/pushary-claude.js +8 -8
- package/dist/bin/pushary-clean.js +9 -8
- package/dist/bin/pushary-codex-bridge.js +5 -5
- package/dist/bin/pushary-codex-hook.js +15 -9
- package/dist/bin/pushary-codex.js +4 -4
- package/dist/bin/pushary-connect.js +6 -6
- package/dist/bin/pushary-daemon.js +4 -4
- package/dist/bin/pushary-disconnect.js +5 -5
- package/dist/bin/pushary-doctor.js +15 -14
- package/dist/bin/pushary-elicitation-hook.js +1 -1
- package/dist/bin/pushary-gemini-bridge.js +5 -5
- package/dist/bin/pushary-gemini-hook.js +15 -9
- package/dist/bin/pushary-hook.js +6 -6
- package/dist/bin/pushary-login.js +4 -4
- package/dist/bin/pushary-logout.js +4 -4
- package/dist/bin/pushary-mode.js +3 -3
- package/dist/bin/pushary-notification-hook.js +4 -4
- package/dist/bin/pushary-opencode-hook.js +5 -5
- package/dist/bin/pushary-permission-denied-hook.js +6 -6
- package/dist/bin/pushary-permission-hook.js +6 -6
- package/dist/bin/pushary-post-hook.js +4 -4
- package/dist/bin/pushary-prompt-hook.js +4 -4
- package/dist/bin/pushary-session-end-hook.js +4 -4
- package/dist/bin/pushary-session-start-hook.js +4 -4
- package/dist/bin/pushary-setup.js +16 -16
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +5 -5
- package/dist/bin/pushary-stop-hook.js +4 -4
- package/dist/bin/pushary-stopfailure-hook.js +4 -4
- package/dist/bin/pushary-upgrade.js +5 -5
- package/dist/bin/pushary-wait.js +3 -3
- package/dist/{chunk-LGVHYFIB.js → chunk-3B3PYTKH.js} +1 -1
- package/dist/{chunk-DMW54VWK.js → chunk-3JL64GVE.js} +93 -3
- package/dist/{chunk-TD3M232T.js → chunk-3PSEZOC4.js} +1 -1
- package/dist/{chunk-VIHRP25S.js → chunk-4VYELDAH.js} +1 -1
- package/dist/{chunk-YX6ZKCC5.js → chunk-67TNJVJW.js} +1 -1
- package/dist/{chunk-KFAH6KRE.js → chunk-6BOE5NJZ.js} +1 -1
- package/dist/{chunk-ZGC3W23N.js → chunk-DSTZ2RBU.js} +1 -1
- package/dist/{chunk-ICERLAE2.js → chunk-DXBUFXPL.js} +1 -1
- package/dist/{chunk-EJL3PJU7.js → chunk-ESARAYRI.js} +1 -1
- package/dist/{chunk-7J67NYK4.js → chunk-F5W3AY6L.js} +2 -1
- package/dist/{chunk-QLMX5LLV.js → chunk-LEYXXXRN.js} +1 -1
- package/dist/{chunk-VOE4SYPR.js → chunk-MNXG6IIM.js} +23 -7
- package/dist/{chunk-K42RXJPG.js → chunk-MY5A4EPQ.js} +1 -1
- package/dist/{chunk-KCAFCGGY.js → chunk-OULRSHFB.js} +1 -1
- package/dist/{chunk-TAYHEJFF.js → chunk-RSUBLTMP.js} +2 -2
- package/dist/{chunk-DPUOW6NS.js → chunk-T2XZH7D5.js} +3 -7
- package/dist/{chunk-2JYQAW4B.js → chunk-U6HRYNHC.js} +2 -2
- package/dist/{chunk-OMA2OZRE.js → chunk-UTQCV46U.js} +27 -62
- package/dist/{chunk-VL5ZNK6V.js → chunk-VHHVGVFQ.js} +12 -2
- package/dist/{chunk-KBS53WOE.js → chunk-VSCSZ2LI.js} +1 -1
- package/dist/{chunk-YYTLTEGU.js → chunk-WXCHB6BO.js} +1 -1
- package/dist/{chunk-TV3UFGT7.js → chunk-XFHMGVMX.js} +1 -1
- package/dist/src/index.js +6 -6
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
isGatingMoment,
|
|
7
7
|
recordKeylessMoment
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4VYELDAH.js";
|
|
9
9
|
import {
|
|
10
10
|
denyReasonFrom,
|
|
11
11
|
isDeferAnswer
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
readLastUserPrompt,
|
|
18
18
|
repoKeyFor,
|
|
19
19
|
throttlePass
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-MNXG6IIM.js";
|
|
21
21
|
import {
|
|
22
22
|
DEFAULT_SESSION,
|
|
23
23
|
askUser,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
deriveToolTarget,
|
|
34
34
|
describeToolCall,
|
|
35
35
|
scopePathFor
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-F5W3AY6L.js";
|
|
37
37
|
import {
|
|
38
38
|
getMachineId
|
|
39
39
|
} from "./chunk-RN3NOEJF.js";
|
|
@@ -49,8 +49,10 @@ import {
|
|
|
49
49
|
hookWaitClamped,
|
|
50
50
|
hookWaitDeadline,
|
|
51
51
|
parseAgentQuestionAnswers,
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
parseAgentQuestions,
|
|
53
|
+
resolveGate,
|
|
54
|
+
shouldDeferToNativeMode
|
|
55
|
+
} from "./chunk-3JL64GVE.js";
|
|
54
56
|
|
|
55
57
|
// src/decision-episode.ts
|
|
56
58
|
var EPISODE_PATH = "/api/agent/decision-episode";
|
|
@@ -107,10 +109,10 @@ var handlePushOnly = async (apiKey, description, projectName, timeoutSeconds, ti
|
|
|
107
109
|
return void 0;
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
|
-
if (result.suppressed) {
|
|
112
|
+
if (result.suppressed || result.status === "terminal") {
|
|
111
113
|
await cancelQuestion(apiKey, result.correlationId).catch(() => {
|
|
112
114
|
});
|
|
113
|
-
return ask("You are at the keyboard, approve here.");
|
|
115
|
+
return ask(result.suppressed ? "You are at the keyboard, approve here." : "Delivery mode is Terminal, approve here.");
|
|
114
116
|
}
|
|
115
117
|
if (result.noDevices) {
|
|
116
118
|
switch (timeoutAction) {
|
|
@@ -300,58 +302,21 @@ var keylessNoticeOnce = (sessionId) => {
|
|
|
300
302
|
} catch {
|
|
301
303
|
}
|
|
302
304
|
};
|
|
303
|
-
var
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
const flag = process.env.PUSHARY_RESPECT_PERMISSION_MODE;
|
|
307
|
-
return flag === "0" || flag === "false";
|
|
308
|
-
};
|
|
309
|
-
var shouldDeferToNativeMode = (permissionMode, toolName) => {
|
|
310
|
-
if (nativeModeGatingDisabled()) return false;
|
|
311
|
-
if (typeof permissionMode !== "string") return false;
|
|
312
|
-
if (FULL_DEFER_MODES.has(permissionMode)) return true;
|
|
313
|
-
if (permissionMode === "acceptEdits" && ACCEPT_EDITS_DEFER_TOOLS.has(toolName)) return true;
|
|
314
|
-
if (permissionMode === "bypassPermissions") {
|
|
315
|
-
const flag = process.env.PUSHARY_DEFER_BYPASS;
|
|
316
|
-
return flag === "1" || flag === "true";
|
|
317
|
-
}
|
|
318
|
-
return false;
|
|
319
|
-
};
|
|
320
|
-
var MAX_PHONE_QUESTIONS = 4;
|
|
321
|
-
var parseQuestion = (raw) => {
|
|
322
|
-
const q = raw;
|
|
323
|
-
if (!q || typeof q.question !== "string") return void 0;
|
|
324
|
-
const options = Array.isArray(q.options) ? q.options.flatMap((option) => {
|
|
325
|
-
if (!option || typeof option !== "object") return [];
|
|
326
|
-
const value = option;
|
|
327
|
-
if (typeof value.label !== "string" || value.label.length === 0) return [];
|
|
328
|
-
return [{
|
|
329
|
-
label: value.label,
|
|
330
|
-
...typeof value.description === "string" ? { description: value.description } : {}
|
|
331
|
-
}];
|
|
332
|
-
}) : [];
|
|
333
|
-
const labels = options.map((option) => option.label);
|
|
334
|
-
if (labels.length < 2) return void 0;
|
|
305
|
+
var nativeDeferOptions = () => {
|
|
306
|
+
const respect = process.env.PUSHARY_RESPECT_PERMISSION_MODE;
|
|
307
|
+
const bypass = process.env.PUSHARY_DEFER_BYPASS;
|
|
335
308
|
return {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
multiSelect: q.multiSelect === true,
|
|
339
|
-
options,
|
|
340
|
-
labels
|
|
309
|
+
respectPermissionMode: !(respect === "0" || respect === "false"),
|
|
310
|
+
deferBypass: bypass === "1" || bypass === "true"
|
|
341
311
|
};
|
|
342
312
|
};
|
|
343
|
-
var
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
if (!one || parsed.some((question) => question.question === one.question)) return void 0;
|
|
351
|
-
parsed.push(one);
|
|
352
|
-
}
|
|
353
|
-
return parsed;
|
|
354
|
-
};
|
|
313
|
+
var shouldDeferToNativeMode2 = (permissionMode, toolName) => shouldDeferToNativeMode(permissionMode, toolName, nativeDeferOptions());
|
|
314
|
+
var handedToTerminal = (result) => result.suppressed === true || result.noDevices === true || result.status === "terminal";
|
|
315
|
+
var withLabels = (question) => ({
|
|
316
|
+
...question,
|
|
317
|
+
labels: question.options.map((option) => option.label)
|
|
318
|
+
});
|
|
319
|
+
var parseQuestions = (toolInput) => parseAgentQuestions(toolInput)?.map(withLabels);
|
|
355
320
|
var questionContext = (question, index, total, project) => {
|
|
356
321
|
const subject = question.header ? `${question.header}: your agent is asking in ${project}` : `Your agent is asking in ${project}`;
|
|
357
322
|
return total > 1 ? `${subject} (${index + 1} of ${total})` : subject;
|
|
@@ -376,7 +341,7 @@ var askAsOneCard = async (apiKey, input, parsed, projectName, deadline) => {
|
|
|
376
341
|
} catch {
|
|
377
342
|
return void 0;
|
|
378
343
|
}
|
|
379
|
-
if (result
|
|
344
|
+
if (handedToTerminal(result)) {
|
|
380
345
|
await cancelQuestion(apiKey, result.correlationId).catch(() => {
|
|
381
346
|
});
|
|
382
347
|
return void 0;
|
|
@@ -411,7 +376,7 @@ var askQuestionByQuestion = async (apiKey, input, parsed, projectName, deadline)
|
|
|
411
376
|
} catch {
|
|
412
377
|
return void 0;
|
|
413
378
|
}
|
|
414
|
-
if (result
|
|
379
|
+
if (handedToTerminal(result)) {
|
|
415
380
|
await cancelQuestion(apiKey, result.correlationId).catch(() => {
|
|
416
381
|
});
|
|
417
382
|
return void 0;
|
|
@@ -461,7 +426,7 @@ var handleExitPlanMode = async (apiKey, input) => {
|
|
|
461
426
|
} catch {
|
|
462
427
|
return void 0;
|
|
463
428
|
}
|
|
464
|
-
if (result
|
|
429
|
+
if (handedToTerminal(result)) {
|
|
465
430
|
await cancelQuestion(apiKey, result.correlationId).catch(() => {
|
|
466
431
|
});
|
|
467
432
|
return void 0;
|
|
@@ -524,7 +489,7 @@ var handlePreToolUse = async (input) => {
|
|
|
524
489
|
if (input.tool_name === "ExitPlanMode") {
|
|
525
490
|
return handleExitPlanMode(apiKey, input);
|
|
526
491
|
}
|
|
527
|
-
if (
|
|
492
|
+
if (shouldDeferToNativeMode2(input.permission_mode, input.tool_name)) {
|
|
528
493
|
return void 0;
|
|
529
494
|
}
|
|
530
495
|
switch (verdict.kind) {
|
|
@@ -555,7 +520,7 @@ var toPermissionRequestOutput = (hookOutput) => {
|
|
|
555
520
|
};
|
|
556
521
|
var handlePermissionRequest = async (input) => {
|
|
557
522
|
if (PRETOOLUSE_HANDLED_TOOLS.has(input.tool_name)) {
|
|
558
|
-
const reclaimDeferredExec = !PRETOOLUSE_PHONE_ANSWERED_TOOLS.includes(input.tool_name) &&
|
|
523
|
+
const reclaimDeferredExec = !PRETOOLUSE_PHONE_ANSWERED_TOOLS.includes(input.tool_name) && shouldDeferToNativeMode2(input.permission_mode, input.tool_name);
|
|
559
524
|
if (!reclaimDeferredExec) return void 0;
|
|
560
525
|
}
|
|
561
526
|
if (input.tool_name.startsWith("mcp__pushary__")) return void 0;
|
|
@@ -636,7 +601,7 @@ var handlePermissionDenied = async (input) => {
|
|
|
636
601
|
} catch {
|
|
637
602
|
return void 0;
|
|
638
603
|
}
|
|
639
|
-
if (result
|
|
604
|
+
if (handedToTerminal(result)) {
|
|
640
605
|
await cancelQuestion(apiKey, result.correlationId).catch(() => {
|
|
641
606
|
});
|
|
642
607
|
return void 0;
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
HOOK_BUDGETS,
|
|
6
6
|
HOOK_LOCATOR_BINARY
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3JL64GVE.js";
|
|
8
8
|
|
|
9
9
|
// src/codex-config.ts
|
|
10
10
|
import { createHash } from "crypto";
|
|
@@ -228,10 +228,20 @@ var addCodexHookTrust = (config, hooksJsonPath, command, positions) => {
|
|
|
228
228
|
const position = positions[definition.event];
|
|
229
229
|
if (!position) continue;
|
|
230
230
|
const key = codexHookStateKey(hooksJsonPath, definition.event, position);
|
|
231
|
+
const ours = codexHookTrustHash(definition, command);
|
|
231
232
|
const existing = asRecord(state[key]) ?? {};
|
|
232
|
-
state[key] = { ...existing, trusted_hash:
|
|
233
|
+
state[key] = { ...existing, trusted_hash: ours };
|
|
234
|
+
for (const stale of staleTrustKeys(state, hooksJsonPath, definition.event, key, ours)) {
|
|
235
|
+
delete state[stale];
|
|
236
|
+
}
|
|
233
237
|
}
|
|
234
238
|
};
|
|
239
|
+
var staleTrustKeys = (state, hooksJsonPath, event, currentKey, ourHash) => {
|
|
240
|
+
const prefix = `${hooksJsonPath}:${CODEX_EVENT_KEY[event]}:`;
|
|
241
|
+
return Object.keys(state).filter(
|
|
242
|
+
(key) => key !== currentKey && key.startsWith(prefix) && asRecord(state[key])?.trusted_hash === ourHash
|
|
243
|
+
);
|
|
244
|
+
};
|
|
235
245
|
|
|
236
246
|
// src/setup/paths.ts
|
|
237
247
|
import { homedir as homedir2 } from "os";
|
package/dist/src/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handlePreToolUse
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-UTQCV46U.js";
|
|
4
4
|
import "../chunk-ATBKJNWS.js";
|
|
5
|
-
import "../chunk-
|
|
5
|
+
import "../chunk-4VYELDAH.js";
|
|
6
6
|
import "../chunk-YHG74UFF.js";
|
|
7
7
|
import {
|
|
8
8
|
fetchModeOverride,
|
|
@@ -12,17 +12,17 @@ import {
|
|
|
12
12
|
handlePostToolUse,
|
|
13
13
|
handleStop,
|
|
14
14
|
reportEvent
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-MNXG6IIM.js";
|
|
16
16
|
import {
|
|
17
17
|
askUser,
|
|
18
18
|
cancelQuestion,
|
|
19
19
|
waitForAnswer
|
|
20
20
|
} from "../chunk-J3YDT4HM.js";
|
|
21
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-F5W3AY6L.js";
|
|
22
22
|
import "../chunk-RN3NOEJF.js";
|
|
23
23
|
import "../chunk-BSZYIAZL.js";
|
|
24
24
|
import "../chunk-SAF6HGAA.js";
|
|
25
|
-
import "../chunk-
|
|
25
|
+
import "../chunk-VSCSZ2LI.js";
|
|
26
26
|
import "../chunk-7QLSKOSU.js";
|
|
27
27
|
import "../chunk-KZERVKTD.js";
|
|
28
28
|
import {
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
} from "../chunk-2UMNXADU.js";
|
|
32
32
|
import {
|
|
33
33
|
resolvePolicy
|
|
34
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-3JL64GVE.js";
|
|
35
35
|
export {
|
|
36
36
|
askUser,
|
|
37
37
|
cancelQuestion,
|