@pushary/agent-hooks 0.87.4 → 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/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-BFBAHOGR.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-H5PIPIKQ.js → chunk-OULRSHFB.js} +1 -1
- package/dist/{chunk-QXZ2CKRK.js → chunk-RSUBLTMP.js} +2 -2
- package/dist/{chunk-KULUNLRO.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-NAPRGHZ3.js → chunk-VHHVGVFQ.js} +1 -1
- 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
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
// ../contracts/src/index.ts
|
|
2
2
|
var APPROVAL_MODES = ["push_only", "terminal_only", "push_first", "notify_only"];
|
|
3
3
|
var isApprovalMode = (value) => typeof value === "string" && APPROVAL_MODES.includes(value);
|
|
4
|
+
var MAX_AGENT_QUESTIONS = 4;
|
|
5
|
+
var parseAgentQuestion = (raw) => {
|
|
6
|
+
const q = raw;
|
|
7
|
+
if (!q || typeof q.question !== "string") return void 0;
|
|
8
|
+
const options = Array.isArray(q.options) ? q.options.flatMap((option) => {
|
|
9
|
+
if (!option || typeof option !== "object") return [];
|
|
10
|
+
const value = option;
|
|
11
|
+
if (typeof value.label !== "string" || value.label.length === 0) return [];
|
|
12
|
+
return [{
|
|
13
|
+
label: value.label,
|
|
14
|
+
...typeof value.description === "string" ? { description: value.description } : {}
|
|
15
|
+
}];
|
|
16
|
+
}) : [];
|
|
17
|
+
if (options.length < 2) return void 0;
|
|
18
|
+
return {
|
|
19
|
+
question: q.question,
|
|
20
|
+
...typeof q.header === "string" ? { header: q.header } : {},
|
|
21
|
+
multiSelect: q.multiSelect === true,
|
|
22
|
+
options
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
var parseAgentQuestions = (toolInput) => {
|
|
26
|
+
const questions = toolInput.questions;
|
|
27
|
+
if (!Array.isArray(questions) || questions.length === 0) return void 0;
|
|
28
|
+
if (questions.length > MAX_AGENT_QUESTIONS) return void 0;
|
|
29
|
+
const parsed = [];
|
|
30
|
+
for (const raw of questions) {
|
|
31
|
+
const one = parseAgentQuestion(raw);
|
|
32
|
+
if (!one || parsed.some((question) => question.question === one.question)) return void 0;
|
|
33
|
+
parsed.push(one);
|
|
34
|
+
}
|
|
35
|
+
return parsed;
|
|
36
|
+
};
|
|
4
37
|
var parseAgentQuestionAnswers = (questions, value) => {
|
|
5
38
|
let parsed;
|
|
6
39
|
try {
|
|
@@ -72,6 +105,7 @@ var hookWaitDeadline = (startMs, policyWaitSeconds, agent, nowMs) => {
|
|
|
72
105
|
};
|
|
73
106
|
var hookWaitClamped = (startMs, policyWaitSeconds, agent, nowMs) => startMs + hookMaxWaitSeconds(agent) * 1e3 < nowMs + Math.max(policyWaitSeconds, 0) * 1e3;
|
|
74
107
|
var effectiveWaitSeconds = (timeoutAction, policySeconds, agent) => timeoutAction === "wait" ? hookMaxWaitSeconds(agent) : policySeconds;
|
|
108
|
+
var HOOK_SOURCES = ["claude", "codex", "gemini", "cursor", "vscode", "opencode"];
|
|
75
109
|
var AGENT_LABELS_BY_TYPE = {
|
|
76
110
|
claude_code: "Claude Code",
|
|
77
111
|
claude_cowork: "Claude Cowork",
|
|
@@ -86,6 +120,7 @@ var AGENT_LABELS_BY_TYPE = {
|
|
|
86
120
|
unknown: "Agent"
|
|
87
121
|
};
|
|
88
122
|
var OPENCODE_APPROVAL_EVENT = "permission.ask";
|
|
123
|
+
var CURSOR_GATE_EVENTS = ["beforeShellExecution", "beforeMCPExecution"];
|
|
89
124
|
var HOOK_LOCATOR_BINARY = "pushary-bridge";
|
|
90
125
|
var HOOK_BATCH_MAX_BYTES = 4 * 1024 * 1024;
|
|
91
126
|
var REPO_KEY_MAX_LENGTH = 200;
|
|
@@ -960,8 +995,15 @@ var resolveAutoResolveOrigin = (config, toolName, toolInput, cwd, repoKey, sessi
|
|
|
960
995
|
var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, sessionId) => {
|
|
961
996
|
const args = toolInput ? policyArgForms(toolName, toolInput, cwd) : [];
|
|
962
997
|
const arg = args[0];
|
|
963
|
-
const
|
|
964
|
-
|
|
998
|
+
const governing = (pool) => {
|
|
999
|
+
if (pool.length === 0) return void 0;
|
|
1000
|
+
const rule = selectGoverningRule(pool, toolName, args, repoKey, sessionId);
|
|
1001
|
+
if (rule) return rule;
|
|
1002
|
+
const wildcard = pool.find((p) => p.tool === "*");
|
|
1003
|
+
return wildcard ? { policy: wildcard, rank: "wildcard" } : void 0;
|
|
1004
|
+
};
|
|
1005
|
+
const match = governing(config.policies.filter((p) => !p.origin)) ?? governing(config.policies.filter((p) => p.origin === "preset")) ?? governing(config.policies.filter((p) => p.origin === "builtin"));
|
|
1006
|
+
let base = match?.policy ?? {
|
|
965
1007
|
tool: toolName,
|
|
966
1008
|
timeoutSeconds: config.defaultTimeoutSeconds,
|
|
967
1009
|
timeoutAction: config.defaultTimeoutAction,
|
|
@@ -1013,6 +1055,21 @@ var strictestScopeVerdict = (scope, paths) => {
|
|
|
1013
1055
|
return worst;
|
|
1014
1056
|
};
|
|
1015
1057
|
var survivesDegraded = (config, toolName, toolInputs, cwd, repoKey, sessionId) => toolInputs.length === 1 && resolveAutoResolveOrigin(config, toolName, toolInputs[0], cwd, repoKey, sessionId) === "safe_readonly";
|
|
1058
|
+
var FULL_DEFER_MODES = /* @__PURE__ */ new Set(["plan", "auto", "dontAsk"]);
|
|
1059
|
+
var ACCEPT_EDITS_DEFER_TOOLS = /* @__PURE__ */ new Set([
|
|
1060
|
+
"Write",
|
|
1061
|
+
"Edit",
|
|
1062
|
+
"MultiEdit",
|
|
1063
|
+
"NotebookEdit"
|
|
1064
|
+
]);
|
|
1065
|
+
var shouldDeferToNativeMode = (permissionMode, toolName, options = {}) => {
|
|
1066
|
+
if (options.respectPermissionMode === false) return false;
|
|
1067
|
+
if (typeof permissionMode !== "string") return false;
|
|
1068
|
+
if (FULL_DEFER_MODES.has(permissionMode)) return true;
|
|
1069
|
+
if (permissionMode === "acceptEdits" && ACCEPT_EDITS_DEFER_TOOLS.has(toolName)) return true;
|
|
1070
|
+
if (permissionMode === "bypassPermissions") return options.deferBypass === true;
|
|
1071
|
+
return false;
|
|
1072
|
+
};
|
|
1016
1073
|
var resolveGate = (input) => {
|
|
1017
1074
|
const { modeState, config, toolName, toolInputs, cwd, repoKey, sessionId } = input;
|
|
1018
1075
|
if (modeState.kill) return { kind: "kill", reason: KILL_REASON };
|
|
@@ -1068,6 +1125,33 @@ var claudePreToolUseOutput = (decision, reason, updatedInput) => ({
|
|
|
1068
1125
|
...updatedInput ? { updatedInput } : {}
|
|
1069
1126
|
}
|
|
1070
1127
|
});
|
|
1128
|
+
var PENDING_COMMAND_PREFIX = "The user sent a new instruction from their phone via Pushary:";
|
|
1129
|
+
var pendingCommandEvents = (source) => {
|
|
1130
|
+
switch (source) {
|
|
1131
|
+
case "claude":
|
|
1132
|
+
return ["PostToolUse", "UserPromptSubmit", "Stop"];
|
|
1133
|
+
// Codex carries context on its activity events and NOT on Stop, whose output
|
|
1134
|
+
// schema has no context field at all. Draining for it at the turn boundary
|
|
1135
|
+
// was therefore right to render nothing, and wrong to conclude that Codex
|
|
1136
|
+
// could not be sent a message.
|
|
1137
|
+
case "codex":
|
|
1138
|
+
return ["PostToolUse", "PreToolUse", "UserPromptSubmit"];
|
|
1139
|
+
case "gemini":
|
|
1140
|
+
return ["AfterTool", "BeforeTool", "BeforeAgent"];
|
|
1141
|
+
// Registered events only. Cursor's carriers are `postToolUse` and `stop`,
|
|
1142
|
+
// which this build does not write into the config; the ones it does write
|
|
1143
|
+
// (`afterShellExecution`, `afterFileEdit`, `afterAgentResponse`) are
|
|
1144
|
+
// observational and discard whatever they print.
|
|
1145
|
+
case "cursor":
|
|
1146
|
+
return [];
|
|
1147
|
+
case "vscode":
|
|
1148
|
+
return [];
|
|
1149
|
+
// The prompt is appended through the TUI rather than through a hook return,
|
|
1150
|
+
// so there is nothing for this to print.
|
|
1151
|
+
case "opencode":
|
|
1152
|
+
return [];
|
|
1153
|
+
}
|
|
1154
|
+
};
|
|
1071
1155
|
var claudePermissionRequestOutput = (decision, reason, updatedInput) => ({
|
|
1072
1156
|
hookSpecificOutput: {
|
|
1073
1157
|
hookEventName: "PermissionRequest",
|
|
@@ -1103,7 +1187,7 @@ var gateOutputFor = (source, event, decision, reason) => {
|
|
|
1103
1187
|
output = decision === "allow" ? { decision: "allow" } : { decision: "deny", reason: reason ?? "Denied from Pushary" };
|
|
1104
1188
|
} else if (source === "opencode" && event === OPENCODE_APPROVAL_EVENT) {
|
|
1105
1189
|
output = decision === "deny" ? { status: "deny", reason: reason ?? "Denied from Pushary" } : { status: decision };
|
|
1106
|
-
} else if (source === "cursor" && event
|
|
1190
|
+
} else if (source === "cursor" && CURSOR_GATE_EVENTS.includes(event)) {
|
|
1107
1191
|
output = decision === "allow" ? { permission: "allow" } : decision === "ask" ? { permission: "ask" } : {
|
|
1108
1192
|
permission: "deny",
|
|
1109
1193
|
user_message: "Command denied via Pushary.",
|
|
@@ -1125,14 +1209,17 @@ var claudeElicitationOutput = (event, action, content) => ({
|
|
|
1125
1209
|
var renderElicitationOutput = (event, action, content) => ELICITATION_EVENTS.includes(event) ? JSON.stringify(claudeElicitationOutput(event, action, content)) : void 0;
|
|
1126
1210
|
|
|
1127
1211
|
export {
|
|
1212
|
+
parseAgentQuestions,
|
|
1128
1213
|
parseAgentQuestionAnswers,
|
|
1129
1214
|
normalizeInstallSource,
|
|
1130
1215
|
HOOK_BUDGETS,
|
|
1131
1216
|
hookWaitDeadline,
|
|
1132
1217
|
hookWaitClamped,
|
|
1133
1218
|
effectiveWaitSeconds,
|
|
1219
|
+
HOOK_SOURCES,
|
|
1134
1220
|
AGENT_LABELS_BY_TYPE,
|
|
1135
1221
|
OPENCODE_APPROVAL_EVENT,
|
|
1222
|
+
CURSOR_GATE_EVENTS,
|
|
1136
1223
|
HOOK_LOCATOR_BINARY,
|
|
1137
1224
|
normalizeRepoRemote,
|
|
1138
1225
|
localRepoKey,
|
|
@@ -1148,9 +1235,12 @@ export {
|
|
|
1148
1235
|
resolveAutoResolveOrigin,
|
|
1149
1236
|
resolvePolicy,
|
|
1150
1237
|
KILL_REASON,
|
|
1238
|
+
shouldDeferToNativeMode,
|
|
1151
1239
|
resolveGate,
|
|
1152
1240
|
modeStateFromResponse,
|
|
1153
1241
|
claudePreToolUseOutput,
|
|
1242
|
+
PENDING_COMMAND_PREFIX,
|
|
1243
|
+
pendingCommandEvents,
|
|
1154
1244
|
claudePermissionRequestOutput,
|
|
1155
1245
|
gateOutputFor,
|
|
1156
1246
|
renderElicitationOutput
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
FILE_TARGET_TOOLS,
|
|
6
6
|
redactSecrets,
|
|
7
7
|
redactSecretsDeep
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3JL64GVE.js";
|
|
9
9
|
|
|
10
10
|
// ../hook-mapping/src/describe.ts
|
|
11
11
|
import { isAbsolute, relative, resolve } from "path";
|
|
@@ -280,6 +280,7 @@ export {
|
|
|
280
280
|
deriveActionBody,
|
|
281
281
|
deriveAction,
|
|
282
282
|
deriveBlocker,
|
|
283
|
+
AGENT_IDENTITIES,
|
|
283
284
|
summarizeStop,
|
|
284
285
|
sessionStartAction,
|
|
285
286
|
sessionEndAction,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
waitForAnswer
|
|
11
11
|
} from "./chunk-J3YDT4HM.js";
|
|
12
12
|
import {
|
|
13
|
+
AGENT_IDENTITIES,
|
|
13
14
|
deriveReceiptMeta,
|
|
14
15
|
deriveToolTarget,
|
|
15
16
|
describeToolCall,
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
summarizeStop,
|
|
22
23
|
taskTitleFrom,
|
|
23
24
|
toolResultErrorText
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-F5W3AY6L.js";
|
|
25
26
|
import {
|
|
26
27
|
getMachineId
|
|
27
28
|
} from "./chunk-RN3NOEJF.js";
|
|
@@ -30,20 +31,23 @@ import {
|
|
|
30
31
|
} from "./chunk-BSZYIAZL.js";
|
|
31
32
|
import {
|
|
32
33
|
reportedInstallSource
|
|
33
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-VSCSZ2LI.js";
|
|
34
35
|
import {
|
|
35
36
|
getApiKey,
|
|
36
37
|
getBaseUrl
|
|
37
38
|
} from "./chunk-2UMNXADU.js";
|
|
38
39
|
import {
|
|
40
|
+
HOOK_SOURCES,
|
|
41
|
+
PENDING_COMMAND_PREFIX,
|
|
39
42
|
gateOutputFor,
|
|
40
43
|
isAutoApprove,
|
|
41
44
|
localRepoKey,
|
|
42
45
|
modeStateFromResponse,
|
|
43
46
|
normalizeRepoRemote,
|
|
47
|
+
pendingCommandEvents,
|
|
44
48
|
resolveAutoResolveOrigin,
|
|
45
49
|
resolvePolicy
|
|
46
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-3JL64GVE.js";
|
|
47
51
|
|
|
48
52
|
// src/policy.ts
|
|
49
53
|
import { createHash } from "crypto";
|
|
@@ -648,7 +652,6 @@ var deriveUsage = (transcriptPath, sessionId) => {
|
|
|
648
652
|
return void 0;
|
|
649
653
|
}
|
|
650
654
|
};
|
|
651
|
-
var PENDING_COMMAND_PREFIX = "The user sent a new instruction from their phone via Pushary:";
|
|
652
655
|
var mergeAdditionalContext = (existing, reported) => {
|
|
653
656
|
const pendingCommand = reported.status === "fulfilled" ? reported.value?.pendingCommand : void 0;
|
|
654
657
|
if (typeof pendingCommand !== "string" || pendingCommand.trim().length === 0) return existing;
|
|
@@ -657,6 +660,11 @@ var mergeAdditionalContext = (existing, reported) => {
|
|
|
657
660
|
|
|
658
661
|
${injected}` : injected;
|
|
659
662
|
};
|
|
663
|
+
var consumesActivityContext = (agentType) => {
|
|
664
|
+
const source = HOOK_SOURCES.find((candidate) => AGENT_IDENTITIES[candidate].type === agentType);
|
|
665
|
+
if (!source) return false;
|
|
666
|
+
return pendingCommandEvents(source).some((event) => event !== "Stop");
|
|
667
|
+
};
|
|
660
668
|
var detectInstallMode = () => (process.argv[1] ?? "").includes("_npx") ? "npx" : "cli";
|
|
661
669
|
var reportEvent = async (event, options = {}) => {
|
|
662
670
|
const apiKey = options.apiKey ?? getApiKey();
|
|
@@ -691,7 +699,15 @@ var reportEvent = async (event, options = {}) => {
|
|
|
691
699
|
// Only Claude Code consumes additionalContext from these hooks; Codex and
|
|
692
700
|
// Gemini keep their existing session_end-only drain, so they must NOT
|
|
693
701
|
// advertise it or the server would pop-and-drop their queued command.
|
|
694
|
-
|
|
702
|
+
//
|
|
703
|
+
// And only when this caller kept the full budget. The pop is a destructive
|
|
704
|
+
// LPOP that happens before the response is written, so a caller that
|
|
705
|
+
// abandons the request destroys the message: `user_prompt` runs on a human
|
|
706
|
+
// keystroke and gave it 800ms, which a cold function misses routinely.
|
|
707
|
+
// Asking the server to consume something we may not wait to receive is the
|
|
708
|
+
// one shape that loses it outright, and the instruction reaches the agent
|
|
709
|
+
// on its next tool call instead.
|
|
710
|
+
canDrainCommand: consumesActivityContext(event.agentType) && options.timeoutMs === void 0
|
|
695
711
|
}),
|
|
696
712
|
signal: AbortSignal.timeout(options.timeoutMs ?? 1e4)
|
|
697
713
|
});
|
|
@@ -750,7 +766,7 @@ var handlePostToolUse = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
750
766
|
);
|
|
751
767
|
}
|
|
752
768
|
const [reported] = await Promise.allSettled([toolReport, ...extraReports]);
|
|
753
|
-
if (agent.type
|
|
769
|
+
if (consumesActivityContext(agent.type)) {
|
|
754
770
|
additionalContext = mergeAdditionalContext(additionalContext, reported);
|
|
755
771
|
}
|
|
756
772
|
return additionalContext;
|
|
@@ -780,7 +796,7 @@ var handleUserPrompt = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
780
796
|
taskTitle
|
|
781
797
|
}, { maxAttempts: 1, timeoutMs: 800 })
|
|
782
798
|
]);
|
|
783
|
-
if (agent.type
|
|
799
|
+
if (consumesActivityContext(agent.type)) {
|
|
784
800
|
additionalContext = mergeAdditionalContext(additionalContext, reported);
|
|
785
801
|
}
|
|
786
802
|
return additionalContext;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hasGeminiHooks
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MY5A4EPQ.js";
|
|
4
4
|
import {
|
|
5
5
|
hasCodexHooks
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VHHVGVFQ.js";
|
|
7
7
|
|
|
8
8
|
// src/diagnostics/wiring.ts
|
|
9
9
|
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
openCodeConfigDirFrom
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DSTZ2RBU.js";
|
|
4
4
|
import {
|
|
5
5
|
codexHomeFrom
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VHHVGVFQ.js";
|
|
7
7
|
|
|
8
8
|
// src/vscode-config.ts
|
|
9
9
|
import { homedir } from "os";
|
|
@@ -326,9 +326,6 @@ var hasInstructionBlock = (filePath) => {
|
|
|
326
326
|
}
|
|
327
327
|
};
|
|
328
328
|
|
|
329
|
-
// src/hooks-spec.ts
|
|
330
|
-
var CURSOR_GATE_EVENTS = ["beforeShellExecution", "beforeMCPExecution"];
|
|
331
|
-
|
|
332
329
|
export {
|
|
333
330
|
registerPluginLocation,
|
|
334
331
|
unregisterPluginLocation,
|
|
@@ -345,6 +342,5 @@ export {
|
|
|
345
342
|
renderProjectAgentInstructions,
|
|
346
343
|
writeInstructionBlock,
|
|
347
344
|
removeInstructionBlock,
|
|
348
|
-
hasInstructionBlock
|
|
349
|
-
CURSOR_GATE_EVENTS
|
|
345
|
+
hasInstructionBlock
|
|
350
346
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CLAUDE_HOOK_EVENTS,
|
|
3
3
|
supportedClaudeEvents
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MY5A4EPQ.js";
|
|
5
5
|
import {
|
|
6
6
|
guardBinary
|
|
7
7
|
} from "./chunk-B7ZBHWOW.js";
|
|
8
8
|
import {
|
|
9
9
|
HOOK_LOCATOR_BINARY
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3JL64GVE.js";
|
|
11
11
|
|
|
12
12
|
// src/claude-config.ts
|
|
13
13
|
import { join } from "path";
|
|
@@ -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;
|