@pushary/agent-hooks 0.99.0 → 1.0.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/CHANGELOG.md +14 -0
- package/dist/bin/pushary-bell-hook.js +18 -18
- package/dist/bin/pushary-bell.js +6 -6
- package/dist/bin/pushary-claude.js +22 -24
- package/dist/bin/pushary-clean.js +60 -18
- package/dist/bin/pushary-codex-bridge.js +10 -10
- package/dist/bin/pushary-codex-hook.js +33 -35
- package/dist/bin/pushary-codex.js +6 -7
- package/dist/bin/pushary-connect.js +6 -6
- package/dist/bin/pushary-cowork.js +3 -3
- package/dist/bin/pushary-daemon.js +22 -22
- package/dist/bin/pushary-disconnect.js +48 -7
- package/dist/bin/pushary-doctor.js +58 -19
- package/dist/bin/pushary-elicitation-hook.js +17 -17
- package/dist/bin/pushary-gemini-bridge.js +9 -9
- package/dist/bin/pushary-gemini-hook.js +25 -27
- package/dist/bin/pushary-hook.js +61 -33
- package/dist/bin/pushary-login.js +7 -7
- package/dist/bin/pushary-logout.js +4 -4
- package/dist/bin/pushary-mode.js +3 -3
- package/dist/bin/pushary-notification-hook.js +26 -21
- package/dist/bin/pushary-opencode-hook.js +27 -29
- package/dist/bin/pushary-permission-denied-hook.js +24 -23
- package/dist/bin/pushary-permission-hook.js +32 -24
- package/dist/bin/pushary-post-hook.js +30 -22
- package/dist/bin/pushary-prompt-hook.js +26 -21
- package/dist/bin/pushary-session-end-hook.js +26 -21
- package/dist/bin/pushary-session-start-hook.js +30 -25
- package/dist/bin/pushary-setup.js +145 -37
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +10 -10
- package/dist/bin/pushary-stop-hook.js +27 -22
- package/dist/bin/pushary-stopfailure-hook.js +26 -21
- package/dist/bin/pushary-transcript-register.js +16 -16
- package/dist/bin/pushary-transcripts.js +4 -4
- package/dist/bin/pushary-upgrade.js +14 -14
- package/dist/bin/pushary-wait.js +3 -3
- package/dist/{chunk-PD6JY33P.js → chunk-2PS3DTHQ.js} +4 -3
- package/dist/{chunk-RALVI7OF.js → chunk-2SL5X7UB.js} +9 -6
- package/dist/{chunk-6KLCP7VF.js → chunk-3C4ERARU.js} +3 -3
- package/dist/{chunk-LBNAGGLV.js → chunk-3UUAK2AK.js} +3 -2
- package/dist/{chunk-V262ATS5.js → chunk-447SBIC7.js} +15 -2
- package/dist/{chunk-562UJ2DA.js → chunk-7WMFPYR5.js} +1 -1
- package/dist/{chunk-XPPXOKIG.js → chunk-7ZDFVWRR.js} +1 -1
- package/dist/{chunk-GCD3SQSV.js → chunk-A3D43VXO.js} +1 -1
- package/dist/{chunk-3RVCQDC4.js → chunk-BOZETFXB.js} +1 -1
- package/dist/{chunk-4C4XFAGJ.js → chunk-BPD4P3NN.js} +2 -2
- package/dist/{chunk-IRLTW6KF.js → chunk-CDTGL7TT.js} +1 -1
- package/dist/{chunk-CP34FI4B.js → chunk-D2N2EJH2.js} +2 -2
- package/dist/{chunk-6IFUXNFX.js → chunk-DMJTWULU.js} +1 -1
- package/dist/{chunk-4PBCNVI3.js → chunk-DOYARIYB.js} +1 -1
- package/dist/{chunk-XOOWC62T.js → chunk-DUOG74E7.js} +1 -1
- package/dist/{chunk-OPR2BPD4.js → chunk-EMCNSBF3.js} +1 -1
- package/dist/{chunk-5KLAETSU.js → chunk-GTR72MIU.js} +1 -1
- package/dist/{chunk-NSFNEDCT.js → chunk-HGEI7SVM.js} +6 -6
- package/dist/chunk-HS2KEAFD.js +224 -0
- package/dist/{chunk-T3JZZUAR.js → chunk-I3TWY7GH.js} +30 -29
- package/dist/{chunk-ID5FDKDZ.js → chunk-IBU7UU3R.js} +1 -1
- package/dist/{chunk-O3LZQEQP.js → chunk-IWZG2Y4Z.js} +1 -1
- package/dist/{chunk-WGV3VY7O.js → chunk-IYA3NCZG.js} +2 -2
- package/dist/{chunk-JBJBVERL.js → chunk-LTPQKBJH.js} +1 -1
- package/dist/{chunk-64WARXGV.js → chunk-MDV7ZRAT.js} +698 -43
- package/dist/{chunk-QS55LDX4.js → chunk-MGI6MLFU.js} +16 -16
- package/dist/{chunk-CRFLU455.js → chunk-MSOFZYI3.js} +3 -3
- package/dist/{chunk-LWKPMSBB.js → chunk-R744XA2M.js} +5 -5
- package/dist/{chunk-3ZAEUPM4.js → chunk-RFNMSC6N.js} +1 -1
- package/dist/{chunk-K6BASBQJ.js → chunk-S2W4ZSHE.js} +1 -1
- package/dist/{chunk-OUAE3GKO.js → chunk-TTBRBWAK.js} +278 -1
- package/dist/{chunk-6C6MS57P.js → chunk-TVY7AT6O.js} +1 -1
- package/dist/{chunk-EXHXR2X5.js → chunk-UWQVODHT.js} +1 -1
- package/dist/{chunk-JXELRCU5.js → chunk-XK34HTMW.js} +3 -3
- package/dist/{chunk-SI7GYBQP.js → chunk-XKDKUFMP.js} +1 -1
- package/dist/{chunk-HB2KB7QL.js → chunk-XNXIMIFY.js} +1 -1
- package/dist/{chunk-K4XFCEVI.js → chunk-Y55JNI2I.js} +1 -1
- package/dist/{chunk-JL33EDN7.js → chunk-ZZIUQVAN.js} +4 -4
- package/dist/{reapply-HQ264ZTR.js → reapply-I4NB5SSM.js} +8 -8
- package/dist/src/index.js +12 -10
- package/package.json +1 -1
- package/dist/chunk-A76GNRIK.js +0 -608
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
} from "./chunk-YKLCWWEI.js";
|
|
7
7
|
import {
|
|
8
8
|
hookOwnerOf
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2SL5X7UB.js";
|
|
10
10
|
import {
|
|
11
11
|
ensureDaemonRunning
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MSOFZYI3.js";
|
|
13
13
|
import {
|
|
14
14
|
buildTranscriptRecords,
|
|
15
15
|
decodePublicKey,
|
|
16
16
|
generateSessionKey,
|
|
17
17
|
wrapSessionKey
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-7ZDFVWRR.js";
|
|
19
19
|
import {
|
|
20
20
|
fetchTranscriptRecipients,
|
|
21
21
|
uploadTranscriptRecords
|
|
@@ -23,14 +23,14 @@ import {
|
|
|
23
23
|
import {
|
|
24
24
|
transcriptEnvironmentPreference,
|
|
25
25
|
transcriptsEnabled
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-IBU7UU3R.js";
|
|
27
27
|
import {
|
|
28
28
|
codexHome,
|
|
29
29
|
pusharyDir
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-LTPQKBJH.js";
|
|
31
31
|
import {
|
|
32
32
|
readTranscriptPreference
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-DOYARIYB.js";
|
|
34
34
|
import {
|
|
35
35
|
writeJsonAtomic
|
|
36
36
|
} from "./chunk-4LL6LG5X.js";
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addClaudeMcpServer,
|
|
3
|
+
addPusharyToolPermissions,
|
|
4
|
+
isPusharyHook,
|
|
5
|
+
removeClaudeMcpServers
|
|
6
|
+
} from "./chunk-MGI6MLFU.js";
|
|
7
|
+
import {
|
|
8
|
+
CLAUDE_HOOK_EVENTS,
|
|
9
|
+
addGeminiMcpServer,
|
|
10
|
+
removeGeminiMcpServer
|
|
11
|
+
} from "./chunk-2PS3DTHQ.js";
|
|
12
|
+
import {
|
|
13
|
+
CLAUDE_CODE_AGENT,
|
|
14
|
+
parseApplyPatchFiles
|
|
15
|
+
} from "./chunk-MDV7ZRAT.js";
|
|
16
|
+
import {
|
|
17
|
+
guardBinary,
|
|
18
|
+
holdBudgetOf,
|
|
19
|
+
registerHookEntry
|
|
20
|
+
} from "./chunk-LTPQKBJH.js";
|
|
21
|
+
import {
|
|
22
|
+
PHONE_ANSWERED_TOOLS,
|
|
23
|
+
hookCompatibleProfile,
|
|
24
|
+
toToolLookup,
|
|
25
|
+
withHookHoldBudget
|
|
26
|
+
} from "./chunk-TTBRBWAK.js";
|
|
27
|
+
|
|
28
|
+
// src/compatible-config.ts
|
|
29
|
+
import { homedir } from "os";
|
|
30
|
+
import { isAbsolute, join, resolve } from "path";
|
|
31
|
+
var AGENT_FLAG = "--agent";
|
|
32
|
+
var agentArgument = (profile) => `${AGENT_FLAG}=${profile.agentType}`;
|
|
33
|
+
var profileFromArgv = (argv) => {
|
|
34
|
+
const prefix = `${AGENT_FLAG}=`;
|
|
35
|
+
const named = argv.find((argument) => argument.startsWith(prefix));
|
|
36
|
+
return named ? hookCompatibleProfile(named.slice(prefix.length)) : void 0;
|
|
37
|
+
};
|
|
38
|
+
var activeIdentity = (argv) => {
|
|
39
|
+
const profile = profileFromArgv(argv);
|
|
40
|
+
return profile ? { type: profile.agentType, label: profile.label } : CLAUDE_CODE_AGENT;
|
|
41
|
+
};
|
|
42
|
+
var activeHookSource = (argv) => profileFromArgv(argv)?.source ?? "claude";
|
|
43
|
+
var PATCH_INPUT_KEYS = ["command", "patch", "input"];
|
|
44
|
+
var patchedFiles = (toolInput) => [...new Set(PATCH_INPUT_KEYS.flatMap((key) => parseApplyPatchFiles(toolInput[key])))];
|
|
45
|
+
var lookupFor = (profile, input) => {
|
|
46
|
+
const absolute = (path) => input.cwd && !isAbsolute(path) ? resolve(input.cwd, path) : path;
|
|
47
|
+
const toolInput = input.tool_input ?? {};
|
|
48
|
+
const lookup = toToolLookup(profile, input.tool_name ?? "", toolInput, absolute);
|
|
49
|
+
if (!lookup.pathless) return lookup;
|
|
50
|
+
const files = patchedFiles(toolInput);
|
|
51
|
+
return files.length === 1 ? { ...lookup, input: { ...lookup.input, file_path: absolute(files[0]) }, pathless: false } : lookup;
|
|
52
|
+
};
|
|
53
|
+
var normalizeToolCall = (profile, input) => {
|
|
54
|
+
if (!profile || !input.tool_name) return input;
|
|
55
|
+
const lookup = lookupFor(profile, input);
|
|
56
|
+
return { ...input, tool_name: lookup.tool, tool_input: lookup.input };
|
|
57
|
+
};
|
|
58
|
+
var unreadablePathTool = (profile, input) => {
|
|
59
|
+
if (!profile || !input.tool_name) return void 0;
|
|
60
|
+
return lookupFor(profile, input).pathless ? input.tool_name : void 0;
|
|
61
|
+
};
|
|
62
|
+
var underHome = (segments, home = homedir()) => join(home, ...segments);
|
|
63
|
+
var compatibleConfigFile = (profile, home) => underHome(profile.configFile, home);
|
|
64
|
+
var compatibleMcpFile = (profile, home) => profile.mcp ? underHome(profile.mcp.file, home) : null;
|
|
65
|
+
var compatibleInstructionsFile = (profile, home) => profile.instructions ? underHome(profile.instructions.file, home) : null;
|
|
66
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
67
|
+
var ensureRecord = (target, key) => {
|
|
68
|
+
const existing = asRecord(target[key]);
|
|
69
|
+
if (existing) return existing;
|
|
70
|
+
const created = {};
|
|
71
|
+
target[key] = created;
|
|
72
|
+
return created;
|
|
73
|
+
};
|
|
74
|
+
var descend = (config, keyPath) => keyPath.reduce(ensureRecord, config);
|
|
75
|
+
var findMap = (config, keyPath) => keyPath.reduce((node, key) => node && asRecord(node[key]), config);
|
|
76
|
+
var pruneEmptyMap = (config, keyPath) => {
|
|
77
|
+
if (keyPath.length === 0) return false;
|
|
78
|
+
const parent = findMap(config, keyPath.slice(0, -1));
|
|
79
|
+
const key = keyPath[keyPath.length - 1];
|
|
80
|
+
const map = asRecord(parent?.[key]);
|
|
81
|
+
if (!parent || !map || Object.keys(map).length > 0) return false;
|
|
82
|
+
delete parent[key];
|
|
83
|
+
return true;
|
|
84
|
+
};
|
|
85
|
+
var aliasesFor = (profile, canonical) => Object.entries(profile.toolAliases).flatMap(([agentName, target]) => target === canonical ? [agentName] : []);
|
|
86
|
+
var carriesPhoneAnswer = (profile, canonical) => profile.wire === "legacy_decision" && PHONE_ANSWERED_TOOLS.has(canonical);
|
|
87
|
+
var translateMatcher = (profile, matcher) => {
|
|
88
|
+
const spellings = matcher.split("|").filter((canonical) => !carriesPhoneAnswer(profile, canonical)).flatMap((canonical) => [canonical, ...aliasesFor(profile, canonical)]);
|
|
89
|
+
return [.../* @__PURE__ */ new Set([...spellings, ...profile.extraMatchers])].join("|");
|
|
90
|
+
};
|
|
91
|
+
var TOOL_MATCHED_EVENTS = /* @__PURE__ */ new Set(["PreToolUse", "PostToolUse"]);
|
|
92
|
+
var withoutMatcher = ({ matcher, ...hook }) => hook;
|
|
93
|
+
var compatibleHookEvents = (profile) => CLAUDE_HOOK_EVENTS.filter((hook) => profile.events.includes(hook.event)).map((hook) => {
|
|
94
|
+
if (!hook.matcher) return hook;
|
|
95
|
+
if (!TOOL_MATCHED_EVENTS.has(hook.event)) return withoutMatcher(hook);
|
|
96
|
+
return { ...hook, matcher: translateMatcher(profile, hook.matcher) };
|
|
97
|
+
});
|
|
98
|
+
var WRITTEN = { ok: true };
|
|
99
|
+
var ROOT_KEY = "(root)";
|
|
100
|
+
var dotted = (segments) => segments.join(".") || ROOT_KEY;
|
|
101
|
+
var hooksShapeConflict = (config, profile) => {
|
|
102
|
+
if (!asRecord(config)) return ROOT_KEY;
|
|
103
|
+
const walked = [];
|
|
104
|
+
let node = config;
|
|
105
|
+
for (const key of profile.hooksKeyPath) {
|
|
106
|
+
if (node[key] === void 0) return void 0;
|
|
107
|
+
const nested = asRecord(node[key]);
|
|
108
|
+
if (!nested) return dotted([...walked, key]);
|
|
109
|
+
walked.push(key);
|
|
110
|
+
node = nested;
|
|
111
|
+
}
|
|
112
|
+
const clash = CLAUDE_HOOK_EVENTS.find(({ event }) => node[event] !== void 0 && !Array.isArray(node[event]));
|
|
113
|
+
return clash ? dotted([...walked, clash.event]) : void 0;
|
|
114
|
+
};
|
|
115
|
+
var permissionsShapeConflict = (config) => {
|
|
116
|
+
if (!asRecord(config)) return ROOT_KEY;
|
|
117
|
+
if (config.permissions === void 0) return void 0;
|
|
118
|
+
const permissions = asRecord(config.permissions);
|
|
119
|
+
if (!permissions) return "permissions";
|
|
120
|
+
return permissions.allow !== void 0 && !Array.isArray(permissions.allow) ? "permissions.allow" : void 0;
|
|
121
|
+
};
|
|
122
|
+
var addCompatibleToolPermissions = (config) => {
|
|
123
|
+
const conflictAt = permissionsShapeConflict(config);
|
|
124
|
+
if (conflictAt) return { ok: false, conflictAt };
|
|
125
|
+
addPusharyToolPermissions(config);
|
|
126
|
+
return WRITTEN;
|
|
127
|
+
};
|
|
128
|
+
var entryFor = (profile, definition, resolve2) => ({
|
|
129
|
+
...definition.matcher ? { matcher: definition.matcher } : {},
|
|
130
|
+
hooks: [{
|
|
131
|
+
type: "command",
|
|
132
|
+
command: withHookHoldBudget(
|
|
133
|
+
`${resolve2(definition.binary)} ${agentArgument(profile)}`,
|
|
134
|
+
holdBudgetOf(definition)
|
|
135
|
+
),
|
|
136
|
+
timeout: definition.timeout
|
|
137
|
+
}]
|
|
138
|
+
});
|
|
139
|
+
var addCompatibleHooks = (config, profile, binDir) => {
|
|
140
|
+
const conflictAt = hooksShapeConflict(config, profile);
|
|
141
|
+
if (conflictAt) return { ok: false, conflictAt };
|
|
142
|
+
const resolve2 = (name) => guardBinary(binDir ? join(binDir, name) : name);
|
|
143
|
+
const hooks = descend(config, profile.hooksKeyPath);
|
|
144
|
+
const supported = new Map(compatibleHookEvents(profile).map((hook) => [hook.event, hook]));
|
|
145
|
+
for (const known of CLAUDE_HOOK_EVENTS) {
|
|
146
|
+
const current = Array.isArray(hooks[known.event]) ? hooks[known.event] : [];
|
|
147
|
+
const definition = supported.get(known.event);
|
|
148
|
+
if (definition) {
|
|
149
|
+
hooks[known.event] = registerHookEntry(current, isPusharyHook, entryFor(profile, definition, resolve2));
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const others = current.filter((item) => !isPusharyHook(item));
|
|
153
|
+
if (others.length > 0) hooks[known.event] = others;
|
|
154
|
+
else delete hooks[known.event];
|
|
155
|
+
}
|
|
156
|
+
return WRITTEN;
|
|
157
|
+
};
|
|
158
|
+
var removeCompatibleHooks = (config, profile, scope) => {
|
|
159
|
+
const hooks = findMap(config, profile.hooksKeyPath);
|
|
160
|
+
if (!hooks) return false;
|
|
161
|
+
let changed = false;
|
|
162
|
+
for (const { event } of CLAUDE_HOOK_EVENTS) {
|
|
163
|
+
const entries = hooks[event];
|
|
164
|
+
if (!Array.isArray(entries)) continue;
|
|
165
|
+
const kept = entries.filter((entry) => !isPusharyHook(entry, scope));
|
|
166
|
+
if (kept.length === entries.length) continue;
|
|
167
|
+
if (kept.length === 0) delete hooks[event];
|
|
168
|
+
else hooks[event] = kept;
|
|
169
|
+
changed = true;
|
|
170
|
+
}
|
|
171
|
+
const pruned = pruneEmptyMap(config, profile.hooksKeyPath);
|
|
172
|
+
return changed || pruned;
|
|
173
|
+
};
|
|
174
|
+
var hasCompatibleHooks = (config, profile) => {
|
|
175
|
+
const hooks = findMap(config, profile.hooksKeyPath);
|
|
176
|
+
if (!hooks) return false;
|
|
177
|
+
return compatibleHookEvents(profile).some(({ event }) => {
|
|
178
|
+
const entries = hooks[event];
|
|
179
|
+
return Array.isArray(entries) && entries.some((entry) => isPusharyHook(entry));
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
var missingCompatibleHookEvents = (config, profile) => {
|
|
183
|
+
const hooks = findMap(config, profile.hooksKeyPath);
|
|
184
|
+
return compatibleHookEvents(profile).filter(({ event }) => {
|
|
185
|
+
const entries = hooks?.[event];
|
|
186
|
+
return !Array.isArray(entries) || !entries.some((entry) => isPusharyHook(entry));
|
|
187
|
+
}).map(({ event }) => event);
|
|
188
|
+
};
|
|
189
|
+
var compatiblePermissionRuleFile = (profile, home) => profile.permissionRuleFile ? underHome(profile.permissionRuleFile, home) : null;
|
|
190
|
+
var addCompatibleMcpServer = (config, profile, apiKey) => {
|
|
191
|
+
if (!profile.mcp) return;
|
|
192
|
+
if (profile.mcp.shape === "gemini_http") {
|
|
193
|
+
addGeminiMcpServer(config, apiKey);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
addClaudeMcpServer(config, apiKey);
|
|
197
|
+
if (!profile.mcp.trusted) return;
|
|
198
|
+
const server = asRecord(asRecord(config.mcpServers)?.pushary);
|
|
199
|
+
if (server) server.trust = true;
|
|
200
|
+
};
|
|
201
|
+
var removeCompatibleMcpServer = (config, profile) => {
|
|
202
|
+
if (!profile.mcp) return false;
|
|
203
|
+
return profile.mcp.shape === "gemini_http" ? removeGeminiMcpServer(config) : removeClaudeMcpServers(config);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export {
|
|
207
|
+
profileFromArgv,
|
|
208
|
+
activeIdentity,
|
|
209
|
+
activeHookSource,
|
|
210
|
+
normalizeToolCall,
|
|
211
|
+
unreadablePathTool,
|
|
212
|
+
compatibleConfigFile,
|
|
213
|
+
compatibleMcpFile,
|
|
214
|
+
compatibleInstructionsFile,
|
|
215
|
+
compatibleHookEvents,
|
|
216
|
+
addCompatibleToolPermissions,
|
|
217
|
+
addCompatibleHooks,
|
|
218
|
+
removeCompatibleHooks,
|
|
219
|
+
hasCompatibleHooks,
|
|
220
|
+
missingCompatibleHookEvents,
|
|
221
|
+
compatiblePermissionRuleFile,
|
|
222
|
+
addCompatibleMcpServer,
|
|
223
|
+
removeCompatibleMcpServer
|
|
224
|
+
};
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
activeIdentity
|
|
3
|
+
} from "./chunk-HS2KEAFD.js";
|
|
1
4
|
import {
|
|
2
5
|
blockedActionFingerprint,
|
|
3
6
|
defersToNativeMode,
|
|
4
7
|
forgetBlockedActionHint,
|
|
5
8
|
hasBlockedActionHint,
|
|
6
9
|
recordBlockedActionHint
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3C4ERARU.js";
|
|
8
11
|
import {
|
|
9
12
|
isGatingMoment,
|
|
10
13
|
recordKeylessMoment
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-DUOG74E7.js";
|
|
12
15
|
import {
|
|
13
16
|
denyReasonFrom,
|
|
14
17
|
isDeferAnswer
|
|
15
18
|
} from "./chunk-YHG74UFF.js";
|
|
16
19
|
import {
|
|
17
|
-
CLAUDE_CODE_AGENT,
|
|
18
20
|
DEFAULT_SESSION,
|
|
21
|
+
UNNAMED_ACTION,
|
|
22
|
+
deriveAction,
|
|
23
|
+
deriveActionBody,
|
|
24
|
+
deriveBlocker,
|
|
25
|
+
deriveToolTarget,
|
|
26
|
+
describeToolCall,
|
|
19
27
|
fetchModeState,
|
|
20
28
|
getPolicy,
|
|
29
|
+
permissionDeniedAction,
|
|
21
30
|
readLastPrompt,
|
|
22
31
|
readLastUserPrompt,
|
|
23
32
|
repoKeyFor,
|
|
24
33
|
reportEvent,
|
|
34
|
+
scopePathFor,
|
|
25
35
|
settleQuestionsForToolUse,
|
|
26
36
|
throttlePass
|
|
27
|
-
} from "./chunk-
|
|
28
|
-
import {
|
|
29
|
-
UNNAMED_ACTION,
|
|
30
|
-
deriveAction,
|
|
31
|
-
deriveActionBody,
|
|
32
|
-
deriveBlocker,
|
|
33
|
-
deriveToolTarget,
|
|
34
|
-
describeToolCall,
|
|
35
|
-
permissionDeniedAction,
|
|
36
|
-
scopePathFor
|
|
37
|
-
} from "./chunk-A76GNRIK.js";
|
|
37
|
+
} from "./chunk-MDV7ZRAT.js";
|
|
38
38
|
import {
|
|
39
39
|
DECISION_STOP_REASON,
|
|
40
40
|
askUser,
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
} from "./chunk-LGXUGYUH.js";
|
|
50
50
|
import {
|
|
51
51
|
getMachineId
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-7WMFPYR5.js";
|
|
53
53
|
import {
|
|
54
54
|
getApiKey,
|
|
55
55
|
getBaseUrl
|
|
@@ -73,7 +73,7 @@ import {
|
|
|
73
73
|
parseAgentQuestions,
|
|
74
74
|
resolveGate,
|
|
75
75
|
stoppedOutput
|
|
76
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-TTBRBWAK.js";
|
|
77
77
|
|
|
78
78
|
// src/decision-episode.ts
|
|
79
79
|
var EPISODE_PATH = "/api/agent/decision-episode";
|
|
@@ -102,6 +102,8 @@ import { basename, join } from "path";
|
|
|
102
102
|
import { tmpdir } from "os";
|
|
103
103
|
import { existsSync, writeFileSync } from "fs";
|
|
104
104
|
var START_MS = Date.now();
|
|
105
|
+
var ACTIVE_AGENT = activeIdentity(process.argv);
|
|
106
|
+
var agentNameIn = (projectName) => `${ACTIVE_AGENT.label} - ${projectName}`;
|
|
105
107
|
var allow = (reason) => claudePreToolUseOutput("allow", reason);
|
|
106
108
|
var deny = (reason) => claudePreToolUseOutput("deny", reason);
|
|
107
109
|
var allowWithInput = (updatedInput) => claudePreToolUseOutput("allow", void 0, updatedInput);
|
|
@@ -122,7 +124,7 @@ var handlePushOnly = async (apiKey, description, projectName, timeoutSeconds, ti
|
|
|
122
124
|
question: `Allow ${description || UNNAMED_ACTION}?`,
|
|
123
125
|
type: "confirm",
|
|
124
126
|
context: `Agent wants to run this in ${projectName}`,
|
|
125
|
-
agentName:
|
|
127
|
+
agentName: agentNameIn(projectName),
|
|
126
128
|
sessionId,
|
|
127
129
|
machineId,
|
|
128
130
|
toolName,
|
|
@@ -167,7 +169,7 @@ var handlePushFirst = async (apiKey, description, projectName, pushFirstSeconds,
|
|
|
167
169
|
question: `Allow ${description || UNNAMED_ACTION}?`,
|
|
168
170
|
type: "confirm",
|
|
169
171
|
context: `Agent wants to run this in ${projectName}`,
|
|
170
|
-
agentName:
|
|
172
|
+
agentName: agentNameIn(projectName),
|
|
171
173
|
sessionId,
|
|
172
174
|
machineId,
|
|
173
175
|
toolName,
|
|
@@ -195,7 +197,7 @@ var handleNotifyOnly = async (apiKey, description, projectName, sessionId, machi
|
|
|
195
197
|
await sendNotification(apiKey, {
|
|
196
198
|
title: "Agent needs approval",
|
|
197
199
|
body: description,
|
|
198
|
-
agentName:
|
|
200
|
+
agentName: agentNameIn(projectName),
|
|
199
201
|
sessionId,
|
|
200
202
|
machineId
|
|
201
203
|
});
|
|
@@ -203,7 +205,6 @@ var handleNotifyOnly = async (apiKey, description, projectName, sessionId, machi
|
|
|
203
205
|
}
|
|
204
206
|
return ask();
|
|
205
207
|
};
|
|
206
|
-
var CLAUDE_AGENT_TYPE = "claude_code";
|
|
207
208
|
var emitDecisionEpisode = (apiKey, input, toolPolicy, machineId, toolTarget, decision, result) => {
|
|
208
209
|
const verdict = result?.hookSpecificOutput?.permissionDecision;
|
|
209
210
|
const outcome = verdict === "allow" ? "approve" : verdict === "deny" ? "deny" : null;
|
|
@@ -215,7 +216,7 @@ var emitDecisionEpisode = (apiKey, input, toolPolicy, machineId, toolTarget, dec
|
|
|
215
216
|
commandOrPath,
|
|
216
217
|
intent: decision.intent,
|
|
217
218
|
toolTarget,
|
|
218
|
-
agentType:
|
|
219
|
+
agentType: ACTIVE_AGENT.type,
|
|
219
220
|
matchedPattern: toolPolicy.tool,
|
|
220
221
|
policyMode: toolPolicy.mode,
|
|
221
222
|
timeoutSeconds: toolPolicy.timeoutSeconds,
|
|
@@ -327,7 +328,7 @@ var askAsOneCard = async (apiKey, input, parsed, projectName, deadline) => {
|
|
|
327
328
|
options: [...only.labels],
|
|
328
329
|
questions: parsed.map(withoutLabels),
|
|
329
330
|
context: questionContext(only, 0, 1, projectName),
|
|
330
|
-
agentName:
|
|
331
|
+
agentName: agentNameIn(projectName),
|
|
331
332
|
sessionId: input.session_id,
|
|
332
333
|
machineId: getMachineId(),
|
|
333
334
|
toolName: "AskUserQuestion",
|
|
@@ -357,7 +358,7 @@ var askQuestionByQuestion = async (apiKey, input, parsed, projectName, deadline)
|
|
|
357
358
|
options: [...question.labels],
|
|
358
359
|
questions: [withoutLabels(question)],
|
|
359
360
|
context: questionContext(question, index, parsed.length, projectName),
|
|
360
|
-
agentName:
|
|
361
|
+
agentName: agentNameIn(projectName),
|
|
361
362
|
sessionId: input.session_id,
|
|
362
363
|
machineId: getMachineId(),
|
|
363
364
|
toolName: "AskUserQuestion",
|
|
@@ -409,7 +410,7 @@ var handleExitPlanMode = async (apiKey, input) => {
|
|
|
409
410
|
type: "select",
|
|
410
411
|
options: [PLAN_APPROVE, PLAN_KEEP_PLANNING],
|
|
411
412
|
context: `Your agent finished planning in ${projectName} and is waiting to start.`,
|
|
412
|
-
agentName:
|
|
413
|
+
agentName: agentNameIn(projectName),
|
|
413
414
|
sessionId: input.session_id,
|
|
414
415
|
machineId: getMachineId(),
|
|
415
416
|
toolName: "ExitPlanMode",
|
|
@@ -511,7 +512,7 @@ var handlePreToolUse = async (input) => {
|
|
|
511
512
|
}
|
|
512
513
|
try {
|
|
513
514
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
514
|
-
const policy = await getPolicy(apiKey, modeState.policyVersion,
|
|
515
|
+
const policy = await getPolicy(apiKey, modeState.policyVersion, ACTIVE_AGENT.type, true, input.session_id);
|
|
515
516
|
const verdict = resolveGate(claudeGateInput(modeState, policy, input));
|
|
516
517
|
if (verdict.kind === "kill") return halted(verdict.reason);
|
|
517
518
|
if (verdict.kind === "deny") return deny(verdict.reason);
|
|
@@ -563,7 +564,7 @@ var handlePermissionRequest = async (input) => {
|
|
|
563
564
|
}
|
|
564
565
|
try {
|
|
565
566
|
const modeState = await fetchModeState(apiKey, input.session_id);
|
|
566
|
-
const policy = await getPolicy(apiKey, modeState.policyVersion,
|
|
567
|
+
const policy = await getPolicy(apiKey, modeState.policyVersion, ACTIVE_AGENT.type, true, input.session_id);
|
|
567
568
|
const verdict = resolveGate(claudeGateInput(modeState, policy, input));
|
|
568
569
|
switch (verdict.kind) {
|
|
569
570
|
case "kill":
|
|
@@ -588,8 +589,8 @@ var reportPermissionDenied = (input) => reportEvent({
|
|
|
588
589
|
event: "permission_denied",
|
|
589
590
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
590
591
|
toolUseId: input.tool_use_id,
|
|
591
|
-
agentType:
|
|
592
|
-
agentName:
|
|
592
|
+
agentType: ACTIVE_AGENT.type,
|
|
593
|
+
agentName: agentNameIn(basename(input.cwd ?? process.cwd())),
|
|
593
594
|
action: permissionDeniedAction(input.tool_name),
|
|
594
595
|
sessionId: input.session_id
|
|
595
596
|
// Side report, not a command carrier. Without timeoutMs this takes the phone's
|
|
@@ -609,7 +610,7 @@ var notifyPermissionDenied = async (apiKey, input) => {
|
|
|
609
610
|
await sendNotification(apiKey, {
|
|
610
611
|
title: `Auto mode blocked ${input.tool_name}`,
|
|
611
612
|
body: `Your agent was denied ${input.tool_name} in ${projectName}.`,
|
|
612
|
-
agentName:
|
|
613
|
+
agentName: agentNameIn(projectName),
|
|
613
614
|
sessionId: input.session_id
|
|
614
615
|
}, 4e3).catch(() => void 0);
|
|
615
616
|
};
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
resolveBinary,
|
|
3
3
|
resolveGlobalPackageVersion,
|
|
4
4
|
resolvePackageVersionFromBinary
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-LTPQKBJH.js";
|
|
6
6
|
import {
|
|
7
7
|
MANAGED_PROVIDERS
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TTBRBWAK.js";
|
|
9
9
|
|
|
10
10
|
// src/live-capabilities.ts
|
|
11
11
|
var CLAUDE_BRIDGE_CAPABILITY = "claude-bridge";
|