@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
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CLAUDE_HOOK_EVENTS,
|
|
3
3
|
supportedClaudeEvents
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2PS3DTHQ.js";
|
|
5
5
|
import {
|
|
6
6
|
guardBinary,
|
|
7
7
|
holdBudgetOf,
|
|
8
8
|
isProtectedByScope,
|
|
9
9
|
registerHookEntry
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-LTPQKBJH.js";
|
|
11
11
|
import {
|
|
12
12
|
HOOK_LOCATOR_BINARY,
|
|
13
13
|
withHookHoldBudget
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-TTBRBWAK.js";
|
|
15
15
|
|
|
16
16
|
// src/claude-config.ts
|
|
17
17
|
import { join } from "path";
|
|
@@ -113,6 +113,16 @@ var removeClaudeMcpServers = (config) => {
|
|
|
113
113
|
}
|
|
114
114
|
return changed;
|
|
115
115
|
};
|
|
116
|
+
var removePusharyToolPermissions = (settings) => {
|
|
117
|
+
const permissions = asRecord(settings.permissions);
|
|
118
|
+
if (!permissions || !Array.isArray(permissions.allow)) return false;
|
|
119
|
+
const filtered = permissions.allow.filter((rule) => !isPusharyPermission(rule));
|
|
120
|
+
if (filtered.length === permissions.allow.length) return false;
|
|
121
|
+
if (filtered.length === 0) delete permissions.allow;
|
|
122
|
+
else permissions.allow = filtered;
|
|
123
|
+
if (Object.keys(permissions).length === 0) delete settings.permissions;
|
|
124
|
+
return true;
|
|
125
|
+
};
|
|
116
126
|
var addPusharyToolPermissions = (settings) => {
|
|
117
127
|
const permissions = ensureRecord(settings, "permissions");
|
|
118
128
|
const allow = Array.isArray(permissions.allow) ? permissions.allow : [];
|
|
@@ -151,19 +161,7 @@ var entry = (definition, resolve) => ({
|
|
|
151
161
|
});
|
|
152
162
|
var removePusharySettings = (settings, scope) => {
|
|
153
163
|
let changed = scope?.keepMcpServer === true ? false : removeClaudeMcpServers(settings);
|
|
154
|
-
|
|
155
|
-
if (permissions && Array.isArray(permissions.allow)) {
|
|
156
|
-
const filtered = permissions.allow.filter((rule) => !isPusharyPermission(rule));
|
|
157
|
-
if (filtered.length !== permissions.allow.length) {
|
|
158
|
-
if (filtered.length === 0) {
|
|
159
|
-
delete permissions.allow;
|
|
160
|
-
} else {
|
|
161
|
-
permissions.allow = filtered;
|
|
162
|
-
}
|
|
163
|
-
if (Object.keys(permissions).length === 0) delete settings.permissions;
|
|
164
|
-
changed = true;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
164
|
+
if (scope?.keepMcpServer !== true && removePusharyToolPermissions(settings)) changed = true;
|
|
167
165
|
const hooks = asRecord(settings.hooks);
|
|
168
166
|
if (hooks) {
|
|
169
167
|
for (const { event: key } of CLAUDE_HOOK_EVENTS) {
|
|
@@ -185,12 +183,14 @@ var removePusharySettings = (settings, scope) => {
|
|
|
185
183
|
};
|
|
186
184
|
|
|
187
185
|
export {
|
|
186
|
+
isPusharyHook,
|
|
188
187
|
addClaudeMcpServer,
|
|
189
188
|
isClaudeMcpSnapshot,
|
|
190
189
|
captureClaudeMcpServer,
|
|
191
190
|
updateClaudeMcpSnapshot,
|
|
192
191
|
restoreClaudeMcpServer,
|
|
193
192
|
removeClaudeMcpServers,
|
|
193
|
+
removePusharyToolPermissions,
|
|
194
194
|
addPusharyToolPermissions,
|
|
195
195
|
addPusharyHooks,
|
|
196
196
|
removePusharySettings
|
|
@@ -4,17 +4,17 @@ import {
|
|
|
4
4
|
} from "./chunk-XHKBHWLX.js";
|
|
5
5
|
import {
|
|
6
6
|
getMachineId
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7WMFPYR5.js";
|
|
8
8
|
import {
|
|
9
9
|
pusharyDir,
|
|
10
10
|
resolveGlobalBinary
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-LTPQKBJH.js";
|
|
12
12
|
import {
|
|
13
13
|
getPackageVersion
|
|
14
14
|
} from "./chunk-DINDL2CF.js";
|
|
15
15
|
import {
|
|
16
16
|
readControlMode
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-DOYARIYB.js";
|
|
18
18
|
import {
|
|
19
19
|
readJsonSafe,
|
|
20
20
|
writeFileAtomic,
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detectClaudeVersion
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Y55JNI2I.js";
|
|
4
4
|
import {
|
|
5
5
|
addClaudeMcpServer,
|
|
6
6
|
addPusharyHooks,
|
|
7
7
|
addPusharyToolPermissions
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MGI6MLFU.js";
|
|
9
9
|
import {
|
|
10
10
|
claudeUnprovenHolds,
|
|
11
11
|
claudeWired,
|
|
12
12
|
codexUnprovenHolds,
|
|
13
13
|
codexWired,
|
|
14
14
|
geminiWired
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-XK34HTMW.js";
|
|
16
16
|
import {
|
|
17
17
|
CLAUDE_HOOK_BINARY,
|
|
18
18
|
CLAUDE_HOOK_EVENTS,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
needsReregistration,
|
|
25
25
|
registrationSignatures,
|
|
26
26
|
supportedClaudeEvents
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-2PS3DTHQ.js";
|
|
28
28
|
import {
|
|
29
29
|
CODEX_HOOK_BINARY,
|
|
30
30
|
addCodexHookTrust,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
registrationHolderOf,
|
|
45
45
|
resolveGlobalBinary,
|
|
46
46
|
vscodePluginMcp
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-LTPQKBJH.js";
|
|
48
48
|
import {
|
|
49
49
|
readJsonSafe,
|
|
50
50
|
writeFileAtomic,
|
|
@@ -29,6 +29,7 @@ var defaults = {
|
|
|
29
29
|
repoAware: false,
|
|
30
30
|
disconnectable: false,
|
|
31
31
|
managedProvider: false,
|
|
32
|
+
bridged: false,
|
|
32
33
|
enforcement: "cooperative",
|
|
33
34
|
connectVia: "Plain MCP",
|
|
34
35
|
setupCommand: null,
|
|
@@ -45,6 +46,7 @@ var AGENTS = {
|
|
|
45
46
|
label: "Claude Code",
|
|
46
47
|
activationGuide: "/docs/agents/guides/claude-code#verify-a-real-approval",
|
|
47
48
|
hookSource: "claude",
|
|
49
|
+
bridged: true,
|
|
48
50
|
policyAgent: "claude_code",
|
|
49
51
|
repoAware: true,
|
|
50
52
|
disconnectable: true,
|
|
@@ -71,6 +73,7 @@ var AGENTS = {
|
|
|
71
73
|
...defaults,
|
|
72
74
|
label: "Codex",
|
|
73
75
|
hookSource: "codex",
|
|
76
|
+
bridged: true,
|
|
74
77
|
policyAgent: "codex",
|
|
75
78
|
repoAware: true,
|
|
76
79
|
disconnectable: true,
|
|
@@ -90,6 +93,7 @@ var AGENTS = {
|
|
|
90
93
|
...defaults,
|
|
91
94
|
label: "Gemini CLI",
|
|
92
95
|
hookSource: "gemini",
|
|
96
|
+
bridged: true,
|
|
93
97
|
policyAgent: "gemini_cli",
|
|
94
98
|
repoAware: true,
|
|
95
99
|
disconnectable: true,
|
|
@@ -113,6 +117,7 @@ var AGENTS = {
|
|
|
113
117
|
...defaults,
|
|
114
118
|
label: "Cursor",
|
|
115
119
|
hookSource: "cursor",
|
|
120
|
+
bridged: true,
|
|
116
121
|
policyAgent: "cursor",
|
|
117
122
|
disconnectable: true,
|
|
118
123
|
enforcement: "enforced",
|
|
@@ -124,6 +129,7 @@ var AGENTS = {
|
|
|
124
129
|
...defaults,
|
|
125
130
|
label: "VS Code",
|
|
126
131
|
hookSource: "vscode",
|
|
132
|
+
bridged: true,
|
|
127
133
|
policyAgent: "vscode",
|
|
128
134
|
enforcement: "enforced",
|
|
129
135
|
connectVia: "Agent plugin hooks + MCP",
|
|
@@ -135,6 +141,7 @@ var AGENTS = {
|
|
|
135
141
|
...defaults,
|
|
136
142
|
label: "OpenCode",
|
|
137
143
|
hookSource: "opencode",
|
|
144
|
+
bridged: true,
|
|
138
145
|
policyAgent: "opencode",
|
|
139
146
|
repoAware: true,
|
|
140
147
|
disconnectable: true,
|
|
@@ -143,6 +150,69 @@ var AGENTS = {
|
|
|
143
150
|
setupCommand: "npx @pushary/agent-hooks setup",
|
|
144
151
|
enforcementDetail: "Shell, writes, edits and web fetches when OpenCode itself asks for permission."
|
|
145
152
|
},
|
|
153
|
+
qwen_code: {
|
|
154
|
+
...defaults,
|
|
155
|
+
label: "Qwen Code",
|
|
156
|
+
hookSource: "qwen",
|
|
157
|
+
policyAgent: "qwen_code",
|
|
158
|
+
repoAware: true,
|
|
159
|
+
disconnectable: true,
|
|
160
|
+
enforcement: "enforced",
|
|
161
|
+
connectVia: "Native hooks + MCP",
|
|
162
|
+
setupCommand: "npx @pushary/agent-hooks setup",
|
|
163
|
+
enforcementDetail: "Shell, writes and edits through native PreToolUse hooks, matched on Qwen's own tool names and their Claude-shaped aliases."
|
|
164
|
+
},
|
|
165
|
+
codebuddy: {
|
|
166
|
+
...defaults,
|
|
167
|
+
label: "CodeBuddy",
|
|
168
|
+
hookSource: "codebuddy",
|
|
169
|
+
policyAgent: "codebuddy",
|
|
170
|
+
repoAware: true,
|
|
171
|
+
disconnectable: true,
|
|
172
|
+
enforcement: "enforced",
|
|
173
|
+
connectVia: "Native hooks + MCP",
|
|
174
|
+
setupCommand: "npx @pushary/agent-hooks setup",
|
|
175
|
+
enforcementDetail: "Shell, writes and edits through native PreToolUse hooks, plus PermissionRequest. CodeBuddy implements the Claude Code hook specification."
|
|
176
|
+
},
|
|
177
|
+
qoder: {
|
|
178
|
+
...defaults,
|
|
179
|
+
label: "Qoder",
|
|
180
|
+
hookSource: "qoder",
|
|
181
|
+
policyAgent: "qoder",
|
|
182
|
+
repoAware: true,
|
|
183
|
+
disconnectable: true,
|
|
184
|
+
enforcement: "enforced",
|
|
185
|
+
connectVia: "Native hooks + MCP",
|
|
186
|
+
setupCommand: "npx @pushary/agent-hooks setup",
|
|
187
|
+
enforcementDetail: "Shell, writes and edits through native PreToolUse hooks, plus PermissionRequest, over Qoder's superset of the Claude Code event list.",
|
|
188
|
+
capabilityNote: "Qoder documents no user-level instructions file, so the proactive-ask block is not installed. Hooks and MCP are unaffected. Like every agent in this family, the CLI wires it; the macOS app does not yet."
|
|
189
|
+
},
|
|
190
|
+
droid: {
|
|
191
|
+
...defaults,
|
|
192
|
+
label: "Droid",
|
|
193
|
+
hookSource: "droid",
|
|
194
|
+
policyAgent: "droid",
|
|
195
|
+
repoAware: true,
|
|
196
|
+
disconnectable: true,
|
|
197
|
+
enforcement: "enforced",
|
|
198
|
+
connectVia: "Native hooks",
|
|
199
|
+
setupCommand: "npx @pushary/agent-hooks setup",
|
|
200
|
+
enforcementDetail: "Execute, Create, Edit and ApplyPatch through native PreToolUse hooks in ~/.factory/hooks.json.",
|
|
201
|
+
capabilityNote: "Droid registers MCP servers through `droid mcp add` rather than a documented remote-server config shape, so setup writes hooks only. Add Pushary's MCP server yourself to let Droid send notifications and ask questions."
|
|
202
|
+
},
|
|
203
|
+
devin: {
|
|
204
|
+
...defaults,
|
|
205
|
+
label: "Devin CLI",
|
|
206
|
+
hookSource: "devin",
|
|
207
|
+
policyAgent: "devin",
|
|
208
|
+
repoAware: true,
|
|
209
|
+
disconnectable: true,
|
|
210
|
+
enforcement: "enforced",
|
|
211
|
+
connectVia: "Native hooks",
|
|
212
|
+
setupCommand: "npx @pushary/agent-hooks setup",
|
|
213
|
+
enforcementDetail: "exec, write and edit through native PreToolUse hooks, answered in Devin's own approve/block schema.",
|
|
214
|
+
capabilityNote: "Devin CLI answers PreToolUse with `{decision}` rather than a permission decision. That schema has no third value, so where another agent would be asked, Pushary stays silent and Devin's own prompt decides; and it cannot carry an updated tool input, so Devin's own question and plan dialogs are left alone rather than answered from the phone without the answer reaching it. It also fires no Notification event."
|
|
215
|
+
},
|
|
146
216
|
windsurf: {
|
|
147
217
|
...defaults,
|
|
148
218
|
label: "Windsurf",
|
|
@@ -182,6 +252,184 @@ var AGENT_LABELS_BY_TYPE = Object.fromEntries(
|
|
|
182
252
|
var DISCONNECTABLE_AGENTS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.disconnectable ? [agent.hookSource] : []));
|
|
183
253
|
var REPO_AWARE_AGENTS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.repoAware ? [agent.policyAgent] : []));
|
|
184
254
|
var MANAGED_PROVIDERS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.managedProvider ? [agent.hookSource] : []));
|
|
255
|
+
var BRIDGE_HOOK_SOURCES = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.bridged ? [agent.hookSource] : []));
|
|
256
|
+
|
|
257
|
+
// ../contracts/src/agent-wiring.ts
|
|
258
|
+
var COMPATIBLE_AGENT_TYPES = ["qwen_code", "codebuddy", "qoder", "droid", "devin"];
|
|
259
|
+
var CANONICAL_PATH_KEYS = ["file_path", "path"];
|
|
260
|
+
var SHELL_TOOLS = /* @__PURE__ */ new Set(["Bash", "PowerShell"]);
|
|
261
|
+
var PATH_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit", "NotebookEdit", "Read"]);
|
|
262
|
+
var PHONE_ANSWERED_TOOLS = /* @__PURE__ */ new Set(["AskUserQuestion", "ExitPlanMode"]);
|
|
263
|
+
var firstString = (record, keys) => {
|
|
264
|
+
for (const key of keys) {
|
|
265
|
+
const value = record[key];
|
|
266
|
+
if (typeof value === "string" && value.length > 0) return value;
|
|
267
|
+
}
|
|
268
|
+
return void 0;
|
|
269
|
+
};
|
|
270
|
+
var canonicalToolName = (profile, toolName) => profile.toolAliases[toolName] ?? toolName;
|
|
271
|
+
var toToolLookup = (profile, toolName, toolInput, resolvePath = (path) => path) => {
|
|
272
|
+
const tool = canonicalToolName(profile, toolName);
|
|
273
|
+
if (SHELL_TOOLS.has(tool)) {
|
|
274
|
+
const command = firstString(toolInput, ["command"]);
|
|
275
|
+
if (!command) return { tool, input: toolInput, pathless: false };
|
|
276
|
+
const context = Object.fromEntries(
|
|
277
|
+
profile.shellContextKeys.flatMap((key) => toolInput[key] === void 0 ? [] : [[key, toolInput[key]]])
|
|
278
|
+
);
|
|
279
|
+
return { tool, input: { command, ...context }, pathless: false };
|
|
280
|
+
}
|
|
281
|
+
if (!PATH_TOOLS.has(tool)) return { tool, input: toolInput, pathless: false };
|
|
282
|
+
const filePath = firstString(toolInput, [...profile.pathInputKeys, ...CANONICAL_PATH_KEYS]);
|
|
283
|
+
if (!filePath) return { tool, input: toolInput, pathless: true };
|
|
284
|
+
return { tool, input: { ...toolInput, file_path: resolvePath(filePath) }, pathless: false };
|
|
285
|
+
};
|
|
286
|
+
var renderPreToolUseVerdict = (profile, verdict) => {
|
|
287
|
+
if (profile.wire === "permission_decision") return verdict;
|
|
288
|
+
const { permissionDecision, permissionDecisionReason, updatedInput } = verdict.hookSpecificOutput;
|
|
289
|
+
if (permissionDecision === "ask" || updatedInput) return void 0;
|
|
290
|
+
const stop = verdict.continue === false ? { continue: false, ...verdict.stopReason ? { stopReason: verdict.stopReason } : {} } : {};
|
|
291
|
+
return {
|
|
292
|
+
decision: permissionDecision === "allow" ? "approve" : "block",
|
|
293
|
+
...permissionDecisionReason ? { reason: permissionDecisionReason } : {},
|
|
294
|
+
...stop
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
var CLAUDE_SHAPED_EVENTS = [
|
|
298
|
+
"PreToolUse",
|
|
299
|
+
"PostToolUse",
|
|
300
|
+
"Stop",
|
|
301
|
+
"UserPromptSubmit",
|
|
302
|
+
"Notification",
|
|
303
|
+
"SessionStart",
|
|
304
|
+
"SessionEnd",
|
|
305
|
+
"StopFailure",
|
|
306
|
+
"PermissionRequest",
|
|
307
|
+
"PermissionDenied",
|
|
308
|
+
"SubagentStart",
|
|
309
|
+
"SubagentStop",
|
|
310
|
+
"PreCompact",
|
|
311
|
+
"PostCompact",
|
|
312
|
+
"TeammateIdle",
|
|
313
|
+
"Elicitation"
|
|
314
|
+
];
|
|
315
|
+
var without = (...absent) => CLAUDE_SHAPED_EVENTS.filter((event) => !absent.includes(event));
|
|
316
|
+
var QWEN_CODE = {
|
|
317
|
+
agentType: "qwen_code",
|
|
318
|
+
source: "qwen",
|
|
319
|
+
label: "Qwen Code",
|
|
320
|
+
binary: "qwen",
|
|
321
|
+
configFile: [".qwen", "settings.json"],
|
|
322
|
+
hooksKeyPath: ["hooks"],
|
|
323
|
+
toolAliases: {
|
|
324
|
+
run_shell_command: "Bash",
|
|
325
|
+
write_file: "Write",
|
|
326
|
+
edit: "Edit",
|
|
327
|
+
replace: "Edit",
|
|
328
|
+
read_file: "Read",
|
|
329
|
+
WriteFile: "Write",
|
|
330
|
+
ReadFile: "Read"
|
|
331
|
+
},
|
|
332
|
+
extraMatchers: ["mcp__.*"],
|
|
333
|
+
pathInputKeys: ["absolute_path"],
|
|
334
|
+
shellContextKeys: ["directory"],
|
|
335
|
+
events: without("TeammateIdle", "Elicitation", "PermissionDenied"),
|
|
336
|
+
wire: "permission_decision",
|
|
337
|
+
mcp: { shape: "gemini_http", file: [".qwen", "settings.json"], trusted: true },
|
|
338
|
+
instructions: { file: [".qwen", "QWEN.md"], label: "Qwen Code" },
|
|
339
|
+
permissionRuleFile: null
|
|
340
|
+
};
|
|
341
|
+
var CODEBUDDY = {
|
|
342
|
+
agentType: "codebuddy",
|
|
343
|
+
source: "codebuddy",
|
|
344
|
+
label: "CodeBuddy",
|
|
345
|
+
binary: "codebuddy",
|
|
346
|
+
configFile: [".codebuddy", "settings.json"],
|
|
347
|
+
hooksKeyPath: ["hooks"],
|
|
348
|
+
toolAliases: {},
|
|
349
|
+
extraMatchers: ["mcp__.*"],
|
|
350
|
+
pathInputKeys: [],
|
|
351
|
+
shellContextKeys: [],
|
|
352
|
+
events: without("Elicitation", "PermissionDenied"),
|
|
353
|
+
wire: "permission_decision",
|
|
354
|
+
mcp: { shape: "claude_http", file: [".codebuddy", ".mcp.json"], trusted: false },
|
|
355
|
+
instructions: { file: [".codebuddy", "CODEBUDDY.md"], label: "CodeBuddy" },
|
|
356
|
+
permissionRuleFile: [".codebuddy", "settings.json"]
|
|
357
|
+
};
|
|
358
|
+
var QODER = {
|
|
359
|
+
agentType: "qoder",
|
|
360
|
+
source: "qoder",
|
|
361
|
+
label: "Qoder",
|
|
362
|
+
binary: "qoder",
|
|
363
|
+
configFile: [".qoder", "settings.json"],
|
|
364
|
+
hooksKeyPath: ["hooks"],
|
|
365
|
+
toolAliases: {},
|
|
366
|
+
extraMatchers: ["mcp__.*"],
|
|
367
|
+
pathInputKeys: [],
|
|
368
|
+
shellContextKeys: [],
|
|
369
|
+
events: without("Elicitation", "PermissionDenied"),
|
|
370
|
+
wire: "permission_decision",
|
|
371
|
+
mcp: { shape: "claude_http", file: [".qoder", "settings.json"], trusted: true },
|
|
372
|
+
instructions: null,
|
|
373
|
+
permissionRuleFile: null
|
|
374
|
+
};
|
|
375
|
+
var DROID = {
|
|
376
|
+
agentType: "droid",
|
|
377
|
+
source: "droid",
|
|
378
|
+
label: "Droid",
|
|
379
|
+
binary: "droid",
|
|
380
|
+
configFile: [".factory", "hooks.json"],
|
|
381
|
+
hooksKeyPath: [],
|
|
382
|
+
toolAliases: {
|
|
383
|
+
Execute: "Bash",
|
|
384
|
+
Create: "Write",
|
|
385
|
+
ApplyPatch: "Edit",
|
|
386
|
+
FetchUrl: "WebFetch"
|
|
387
|
+
},
|
|
388
|
+
extraMatchers: ["mcp__.*"],
|
|
389
|
+
pathInputKeys: [],
|
|
390
|
+
shellContextKeys: [],
|
|
391
|
+
events: ["PreToolUse", "PostToolUse", "UserPromptSubmit", "Notification", "Stop", "SubagentStop", "PreCompact", "SessionStart", "SessionEnd"],
|
|
392
|
+
wire: "permission_decision",
|
|
393
|
+
mcp: null,
|
|
394
|
+
instructions: null,
|
|
395
|
+
permissionRuleFile: null
|
|
396
|
+
};
|
|
397
|
+
var DEVIN = {
|
|
398
|
+
agentType: "devin",
|
|
399
|
+
source: "devin",
|
|
400
|
+
label: "Devin CLI",
|
|
401
|
+
binary: "devin",
|
|
402
|
+
configFile: [".config", "devin", "config.json"],
|
|
403
|
+
hooksKeyPath: ["hooks"],
|
|
404
|
+
toolAliases: {
|
|
405
|
+
exec: "Bash",
|
|
406
|
+
write: "Write",
|
|
407
|
+
edit: "Edit",
|
|
408
|
+
read: "Read",
|
|
409
|
+
webfetch: "WebFetch",
|
|
410
|
+
web_search: "WebSearch",
|
|
411
|
+
run_subagent: "Task"
|
|
412
|
+
},
|
|
413
|
+
extraMatchers: ["mcp__.*"],
|
|
414
|
+
pathInputKeys: [],
|
|
415
|
+
shellContextKeys: [],
|
|
416
|
+
events: ["PreToolUse", "PostToolUse", "UserPromptSubmit", "Stop", "SessionStart", "SessionEnd"],
|
|
417
|
+
wire: "legacy_decision",
|
|
418
|
+
mcp: null,
|
|
419
|
+
instructions: null,
|
|
420
|
+
permissionRuleFile: null
|
|
421
|
+
};
|
|
422
|
+
var HOOK_COMPATIBLE_PROFILES = Object.freeze([QWEN_CODE, CODEBUDDY, QODER, DROID, DEVIN]);
|
|
423
|
+
var hookCompatibleProfile = (agentType) => HOOK_COMPATIBLE_PROFILES.find((profile) => profile.agentType === agentType);
|
|
424
|
+
var hookCompatibleProfileBySource = (source) => HOOK_COMPATIBLE_PROFILES.find((profile) => profile.source === source);
|
|
425
|
+
var compatibleConfigDir = (profile) => profile.configFile.slice(0, -1);
|
|
426
|
+
var compatibleTargetFiles = (profile) => {
|
|
427
|
+
const seen = /* @__PURE__ */ new Map();
|
|
428
|
+
for (const file of [profile.configFile, profile.mcp?.file, profile.permissionRuleFile, profile.instructions?.file]) {
|
|
429
|
+
if (file) seen.set(file.join("/"), file);
|
|
430
|
+
}
|
|
431
|
+
return [...seen.values()];
|
|
432
|
+
};
|
|
185
433
|
|
|
186
434
|
// ../contracts/src/index.ts
|
|
187
435
|
var KEY_SCOPES = ["full_access", "agent", "connector", "bound"];
|
|
@@ -290,7 +538,15 @@ var HOOK_BUDGETS = {
|
|
|
290
538
|
// rather than one we are told. Chosen to match Claude Code, because what it
|
|
291
539
|
// bounds is how long the person's tool call sits unanswered before Pushary
|
|
292
540
|
// stops asking and hands it back to the terminal.
|
|
293
|
-
opencode: { budgetSeconds: 120, guardSeconds: 10 }
|
|
541
|
+
opencode: { budgetSeconds: 120, guardSeconds: 10 },
|
|
542
|
+
// The hook-compatible agents take a per-hook `timeout` in seconds exactly as
|
|
543
|
+
// Claude Code does, and `compatibleHookEvents` writes Claude's own numbers into
|
|
544
|
+
// their config, so what we may wait for is what we registered for.
|
|
545
|
+
qwen: { budgetSeconds: 600, guardSeconds: 10 },
|
|
546
|
+
codebuddy: { budgetSeconds: 600, guardSeconds: 10 },
|
|
547
|
+
qoder: { budgetSeconds: 600, guardSeconds: 10 },
|
|
548
|
+
droid: { budgetSeconds: 600, guardSeconds: 10 },
|
|
549
|
+
devin: { budgetSeconds: 600, guardSeconds: 10 }
|
|
294
550
|
};
|
|
295
551
|
var hookMaxWaitSeconds = (agent) => Math.max(HOOK_BUDGETS[agent].budgetSeconds - HOOK_BUDGETS[agent].guardSeconds, 1);
|
|
296
552
|
var HOOK_HOLD_BUDGET_FLAG = "--hold-budget";
|
|
@@ -1430,8 +1686,20 @@ var pendingCommandEvents = (source) => {
|
|
|
1430
1686
|
// so there is nothing for this to print.
|
|
1431
1687
|
case "opencode":
|
|
1432
1688
|
return [];
|
|
1689
|
+
case "qwen":
|
|
1690
|
+
case "codebuddy":
|
|
1691
|
+
case "qoder":
|
|
1692
|
+
case "droid":
|
|
1693
|
+
case "devin":
|
|
1694
|
+
return compatiblePendingCommandEvents(source);
|
|
1433
1695
|
}
|
|
1434
1696
|
};
|
|
1697
|
+
var COMPATIBLE_PENDING_COMMAND_EVENTS = ["PostToolUse", "UserPromptSubmit"];
|
|
1698
|
+
var compatiblePendingCommandEvents = (source) => {
|
|
1699
|
+
const profile = hookCompatibleProfileBySource(source);
|
|
1700
|
+
if (!profile || profile.wire !== "permission_decision") return [];
|
|
1701
|
+
return COMPATIBLE_PENDING_COMMAND_EVENTS.filter((event) => profile.events.includes(event));
|
|
1702
|
+
};
|
|
1435
1703
|
var claudePermissionRequestOutput = (decision, reason, updatedInput) => ({
|
|
1436
1704
|
hookSpecificOutput: {
|
|
1437
1705
|
hookEventName: "PermissionRequest",
|
|
@@ -1633,6 +1901,15 @@ export {
|
|
|
1633
1901
|
DISCONNECTABLE_AGENTS,
|
|
1634
1902
|
REPO_AWARE_AGENTS,
|
|
1635
1903
|
MANAGED_PROVIDERS,
|
|
1904
|
+
COMPATIBLE_AGENT_TYPES,
|
|
1905
|
+
PHONE_ANSWERED_TOOLS,
|
|
1906
|
+
toToolLookup,
|
|
1907
|
+
renderPreToolUseVerdict,
|
|
1908
|
+
HOOK_COMPATIBLE_PROFILES,
|
|
1909
|
+
hookCompatibleProfile,
|
|
1910
|
+
hookCompatibleProfileBySource,
|
|
1911
|
+
compatibleConfigDir,
|
|
1912
|
+
compatibleTargetFiles,
|
|
1636
1913
|
hookWritePath,
|
|
1637
1914
|
isHookActivationReport,
|
|
1638
1915
|
hookActivationResult,
|
|
@@ -2,17 +2,17 @@ import {
|
|
|
2
2
|
CLAUDE_HOOK_EVENTS,
|
|
3
3
|
GEMINI_HOOK_EVENTS,
|
|
4
4
|
hasGeminiHooks
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2PS3DTHQ.js";
|
|
6
6
|
import {
|
|
7
7
|
CODEX_HOOK_EVENTS,
|
|
8
8
|
hasCodexHooks,
|
|
9
9
|
holdBudgetOf
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-LTPQKBJH.js";
|
|
11
11
|
import {
|
|
12
12
|
CURSOR_GATE_EVENTS,
|
|
13
13
|
HOOK_LOCATOR_BINARY,
|
|
14
14
|
hookCommandHoldBudget
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-TTBRBWAK.js";
|
|
16
16
|
|
|
17
17
|
// src/diagnostics/wiring.ts
|
|
18
18
|
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -2,24 +2,24 @@ import {
|
|
|
2
2
|
detectProviderLiveCapabilities,
|
|
3
3
|
hasSpawnProvider,
|
|
4
4
|
resolveControlPolicy
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-IYA3NCZG.js";
|
|
6
6
|
import {
|
|
7
7
|
daemonHasRemoteProof,
|
|
8
8
|
daemonServiceManagerAvailable,
|
|
9
9
|
hasDaemonServiceDefinition,
|
|
10
10
|
readDaemonNeedsLogin,
|
|
11
11
|
readDaemonStatus
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MSOFZYI3.js";
|
|
13
13
|
import {
|
|
14
14
|
getMachineId
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-7WMFPYR5.js";
|
|
16
16
|
import {
|
|
17
17
|
getPackageVersion
|
|
18
18
|
} from "./chunk-DINDL2CF.js";
|
|
19
19
|
import {
|
|
20
20
|
readControlMode,
|
|
21
21
|
readKeySource
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-DOYARIYB.js";
|
|
23
23
|
import {
|
|
24
24
|
getBaseUrl
|
|
25
25
|
} from "./chunk-2UMNXADU.js";
|
|
@@ -8,15 +8,15 @@ import {
|
|
|
8
8
|
reapplyGeminiSettings,
|
|
9
9
|
reapplyVsCodePlugin,
|
|
10
10
|
repairCodexHolds
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-R744XA2M.js";
|
|
12
|
+
import "./chunk-Y55JNI2I.js";
|
|
13
|
+
import "./chunk-MGI6MLFU.js";
|
|
14
|
+
import "./chunk-XK34HTMW.js";
|
|
15
|
+
import "./chunk-2PS3DTHQ.js";
|
|
16
|
+
import "./chunk-EMCNSBF3.js";
|
|
17
|
+
import "./chunk-LTPQKBJH.js";
|
|
18
18
|
import "./chunk-4LL6LG5X.js";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-TTBRBWAK.js";
|
|
20
20
|
export {
|
|
21
21
|
inspectConfiguredManagedProviders,
|
|
22
22
|
reapplyAllAgents,
|