@pushary/agent-hooks 1.3.1 → 1.4.1
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 +23 -0
- package/README.md +1 -1
- package/dist/bin/pushary-bell-hook.js +18 -18
- package/dist/bin/pushary-bell.js +8 -8
- package/dist/bin/pushary-claude.js +18 -18
- package/dist/bin/pushary-clean.js +490 -95
- package/dist/bin/pushary-codex-bridge.js +10 -10
- package/dist/bin/pushary-codex-hook.js +28 -26
- package/dist/bin/pushary-codex.js +6 -6
- package/dist/bin/pushary-connect.js +8 -8
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +24 -24
- package/dist/bin/pushary-disconnect.js +12 -12
- package/dist/bin/pushary-doctor.js +75 -26
- 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 +19 -19
- package/dist/bin/pushary-hook.js +27 -27
- package/dist/bin/pushary-login.js +9 -9
- package/dist/bin/pushary-logout.js +6 -6
- package/dist/bin/pushary-mode.js +5 -5
- package/dist/bin/pushary-notification-hook.js +20 -20
- package/dist/bin/pushary-opencode-hook.js +19 -19
- package/dist/bin/pushary-permission-denied-hook.js +24 -24
- package/dist/bin/pushary-permission-hook.js +25 -25
- package/dist/bin/pushary-post-hook.js +20 -20
- package/dist/bin/pushary-prompt-hook.js +20 -20
- package/dist/bin/pushary-session-end-hook.js +20 -20
- package/dist/bin/pushary-session-start-hook.js +22 -22
- package/dist/bin/pushary-setup.js +38 -59
- package/dist/bin/pushary-stats.js +4 -4
- package/dist/bin/pushary-status.js +12 -12
- package/dist/bin/pushary-stop-hook.js +20 -20
- package/dist/bin/pushary-stopfailure-hook.js +20 -20
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-transcript-register.js +16 -16
- package/dist/bin/pushary-transcripts.js +6 -6
- package/dist/bin/pushary-upgrade.js +16 -16
- package/dist/bin/pushary-wait.js +5 -5
- package/dist/bin/pushary.js +1 -1
- package/dist/{chunk-RERJ2ZDV.js → chunk-2GMI6JH6.js} +5 -5
- package/dist/{chunk-AFOTOA24.js → chunk-37VLIYLI.js} +35 -4
- package/dist/{chunk-6HH4IH4K.js → chunk-3BPB2HYZ.js} +3 -3
- package/dist/{chunk-465UENKO.js → chunk-3T52B2OF.js} +1 -1
- package/dist/{chunk-PEV6ULSM.js → chunk-3UA6FPRC.js} +3 -3
- package/dist/{chunk-QDYJQLXT.js → chunk-43JKGLZZ.js} +2 -2
- package/dist/{chunk-CKLWJ6EL.js → chunk-4FN6VV56.js} +33 -7
- package/dist/{chunk-HCTSTMDD.js → chunk-ALFT7H5B.js} +3 -3
- package/dist/{chunk-35RPUNYU.js → chunk-BZBUPZC6.js} +1 -1
- package/dist/{chunk-CDSL3LLO.js → chunk-CRNAXFQ6.js} +1 -1
- package/dist/{chunk-NDSOOJDX.js → chunk-D7ERHWYB.js} +1 -1
- package/dist/{chunk-KHGIM2BN.js → chunk-ED5TA2FJ.js} +3 -3
- package/dist/{chunk-LZQVAEWP.js → chunk-FAH3D74E.js} +2 -1
- package/dist/{chunk-5UWDYOZX.js → chunk-FVKFDTN6.js} +81 -8
- package/dist/{chunk-I2OLM3DM.js → chunk-GOFDGTEI.js} +62 -12
- package/dist/{chunk-JZA2JOGO.js → chunk-HK3IXIQJ.js} +1 -1
- package/dist/{chunk-LWT34GSY.js → chunk-HQLAZWJJ.js} +7 -7
- package/dist/{chunk-5XKMOZO6.js → chunk-I6HRQOMT.js} +4 -4
- package/dist/{chunk-EAGMQMRM.js → chunk-JOVWYVSR.js} +1 -1
- package/dist/{chunk-5WLH2ENB.js → chunk-K6I5M2ME.js} +1 -1
- package/dist/{chunk-REIZ5GXG.js → chunk-KEMEBTCJ.js} +4 -4
- package/dist/{chunk-PHXU4NOP.js → chunk-KI36MAT6.js} +2 -2
- package/dist/{chunk-WOBHHXW5.js → chunk-LNGYW6G4.js} +5 -4
- package/dist/{chunk-AFKOWCMQ.js → chunk-LUT2EZLG.js} +1 -1
- package/dist/{chunk-KLZJEMSE.js → chunk-LYXX5NSB.js} +1 -1
- package/dist/{chunk-YXWM4TNX.js → chunk-MN3XOVRK.js} +1 -1
- package/dist/{chunk-XOUQUZ43.js → chunk-PHHGHHOW.js} +1 -1
- package/dist/{chunk-TW7KA27C.js → chunk-QBS6LGEK.js} +1 -1
- package/dist/{chunk-FGNABUPN.js → chunk-R3AMKNIW.js} +1 -1
- package/dist/{chunk-TGG4FWWB.js → chunk-S3EP4B35.js} +2 -2
- package/dist/{chunk-34NNTYK6.js → chunk-SAF6NNXY.js} +1 -1
- package/dist/{chunk-R5CU7ED6.js → chunk-SKXLIVFM.js} +1 -1
- package/dist/{chunk-OMP3KDDU.js → chunk-SWFF5U2N.js} +1 -1
- package/dist/{chunk-QOCWB4Q6.js → chunk-TF4IOINR.js} +3 -3
- package/dist/{chunk-5SALHATY.js → chunk-TI3ZWXZG.js} +11 -2
- package/dist/{chunk-P232YODQ.js → chunk-TNS3YLFE.js} +6 -6
- package/dist/{chunk-GOQHN2UH.js → chunk-TWWLVOPB.js} +1 -1
- package/dist/{chunk-XVE52YFZ.js → chunk-VYUDGQM7.js} +1 -1
- package/dist/{chunk-XP2KRTZD.js → chunk-WEO5JCB4.js} +1 -1
- package/dist/{chunk-SGZE2JBF.js → chunk-WIOXWUUH.js} +3 -3
- package/dist/{reapply-ADFRVH5N.js → reapply-BAWDJTG7.js} +8 -8
- package/dist/src/index.d.ts +19 -16
- package/dist/src/index.js +12 -12
- package/package.json +1 -1
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -4,15 +4,15 @@ import {
|
|
|
4
4
|
} from "../chunk-CVWG2N3Y.js";
|
|
5
5
|
import {
|
|
6
6
|
exitOnFailedResponse
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-D7ERHWYB.js";
|
|
8
|
+
import "../chunk-QBS6LGEK.js";
|
|
9
9
|
import {
|
|
10
10
|
createIo
|
|
11
11
|
} from "../chunk-5RUIFDTP.js";
|
|
12
12
|
import {
|
|
13
13
|
exitOnHelpFlag
|
|
14
|
-
} from "../chunk-
|
|
15
|
-
import "../chunk-
|
|
14
|
+
} from "../chunk-TWWLVOPB.js";
|
|
15
|
+
import "../chunk-FAH3D74E.js";
|
|
16
16
|
import {
|
|
17
17
|
rejectUnknownFlags
|
|
18
18
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
getApiKey,
|
|
29
29
|
getBaseUrl
|
|
30
30
|
} from "../chunk-2UMNXADU.js";
|
|
31
|
-
import "../chunk-
|
|
31
|
+
import "../chunk-FVKFDTN6.js";
|
|
32
32
|
|
|
33
33
|
// bin/pushary-wait.ts
|
|
34
34
|
exitOnHelpFlag("wait");
|
package/dist/bin/pushary.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detectClaudeVersion
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LUT2EZLG.js";
|
|
4
4
|
import {
|
|
5
5
|
addClaudeMcpServer,
|
|
6
6
|
addPusharyHooks,
|
|
7
7
|
addPusharyToolPermissions
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WIOXWUUH.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-TF4IOINR.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-ED5TA2FJ.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-SAF6NNXY.js";
|
|
48
48
|
import {
|
|
49
49
|
readJsonSafe,
|
|
50
50
|
writeFileAtomic,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolvePathBinary
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SAF6NNXY.js";
|
|
4
4
|
|
|
5
5
|
// src/hermes-config.ts
|
|
6
6
|
import { execFileSync } from "child_process";
|
|
@@ -233,8 +233,35 @@ var runHermesPythonScript = (python, script, ...args) => {
|
|
|
233
233
|
}
|
|
234
234
|
};
|
|
235
235
|
|
|
236
|
-
// src/cli
|
|
236
|
+
// src/skills-cli.ts
|
|
237
237
|
import { execSync } from "child_process";
|
|
238
|
+
var PUSHARY_SKILL_SOURCE = "Pushary/pushary-skill";
|
|
239
|
+
var PUSHARY_SKILL_NAME = "pushary";
|
|
240
|
+
var installSkillViaSkillsCli = (agent) => {
|
|
241
|
+
try {
|
|
242
|
+
execSync(`npx -y skills@latest add ${PUSHARY_SKILL_SOURCE}@${PUSHARY_SKILL_NAME} -y -g --agent ${agent}`, {
|
|
243
|
+
stdio: "pipe",
|
|
244
|
+
timeout: 9e4
|
|
245
|
+
});
|
|
246
|
+
return true;
|
|
247
|
+
} catch {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
var installAgentSkill = async (request, effects) => {
|
|
252
|
+
if (request.skillsCliInUse) {
|
|
253
|
+
const startedAt = effects.now();
|
|
254
|
+
if (effects.runSkillsCli(request.agent)) {
|
|
255
|
+
const modifiedAt = effects.skillModifiedAt(request.agentSkillDir);
|
|
256
|
+
if (modifiedAt !== null && modifiedAt >= startedAt) return "skills-cli";
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
await effects.writePackagedSkill(request.agentSkillDir);
|
|
260
|
+
return "packaged-copy";
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// src/cli/dry-run.ts
|
|
264
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
238
265
|
import { rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
239
266
|
var createGuards = (isDryRun, note) => ({
|
|
240
267
|
write: (path, contents) => {
|
|
@@ -245,9 +272,9 @@ var createGuards = (isDryRun, note) => ({
|
|
|
245
272
|
if (isDryRun()) return note("remove ", path);
|
|
246
273
|
rmSync2(path, { recursive: true, force: options.force ?? false });
|
|
247
274
|
},
|
|
248
|
-
|
|
275
|
+
execFile: (file, args, options, describe) => {
|
|
249
276
|
if (isDryRun()) return note("run ", describe);
|
|
250
|
-
|
|
277
|
+
execFileSync2(file, args, options);
|
|
251
278
|
}
|
|
252
279
|
});
|
|
253
280
|
var describeService = (effects) => {
|
|
@@ -271,6 +298,10 @@ export {
|
|
|
271
298
|
HERMES_CONFIG_SCRIPT,
|
|
272
299
|
resolveHermesPython,
|
|
273
300
|
runHermesPythonScript,
|
|
301
|
+
PUSHARY_SKILL_SOURCE,
|
|
302
|
+
PUSHARY_SKILL_NAME,
|
|
303
|
+
installSkillViaSkillsCli,
|
|
304
|
+
installAgentSkill,
|
|
274
305
|
createGuards,
|
|
275
306
|
describeSetupSideEffects
|
|
276
307
|
};
|
|
@@ -4,17 +4,17 @@ import {
|
|
|
4
4
|
} from "./chunk-XHKBHWLX.js";
|
|
5
5
|
import {
|
|
6
6
|
getMachineId
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3T52B2OF.js";
|
|
8
8
|
import {
|
|
9
9
|
pusharyDir,
|
|
10
10
|
resolveGlobalBinary
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-SAF6NNXY.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-TI3ZWXZG.js";
|
|
18
18
|
import {
|
|
19
19
|
readJsonSafe,
|
|
20
20
|
writeFileAtomic,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
openCodeConfigDirFrom
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VYUDGQM7.js";
|
|
4
4
|
import {
|
|
5
5
|
codexHomeFrom
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SAF6NNXY.js";
|
|
7
7
|
import {
|
|
8
8
|
HOOK_COMPATIBLE_PROFILES
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FVKFDTN6.js";
|
|
10
10
|
|
|
11
11
|
// src/vscode-config.ts
|
|
12
12
|
import { homedir } from "os";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SETUP_FLAGS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-R3AMKNIW.js";
|
|
4
4
|
import {
|
|
5
5
|
parseFlags
|
|
6
6
|
} from "./chunk-GMXKITVA.js";
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
CLAUDE_CONNECTOR_URL,
|
|
15
15
|
COWORK_CONNECTOR_LIMIT,
|
|
16
16
|
COWORK_STANDING_INSTRUCTIONS
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-FVKFDTN6.js";
|
|
18
18
|
|
|
19
19
|
// src/cli/cowork.ts
|
|
20
20
|
import { readFileSync } from "fs";
|
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
2
|
registerTranscript
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TNS3YLFE.js";
|
|
4
4
|
import {
|
|
5
5
|
degradedLine
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FVKFDTN6.js";
|
|
7
|
+
|
|
8
|
+
// src/tool-hook-input.ts
|
|
9
|
+
var OPTIONAL_TEXT_FIELDS = ["hook_event_name", "session_id", "cwd", "transcript_path", "tool_use_id", "permission_mode"];
|
|
10
|
+
function isInputRecord(value) {
|
|
11
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
function isToolHookInput(value) {
|
|
14
|
+
if (!isInputRecord(value)) return false;
|
|
15
|
+
if (typeof value.tool_name !== "string" || value.tool_name.length === 0) return false;
|
|
16
|
+
if (!isInputRecord(value.tool_input)) return false;
|
|
17
|
+
for (const field of OPTIONAL_TEXT_FIELDS) {
|
|
18
|
+
if (value[field] !== void 0 && typeof value[field] !== "string") return false;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
function parseToolHookInput(value) {
|
|
23
|
+
if (!isInputRecord(value)) return null;
|
|
24
|
+
const input = { ...value, tool_input: value.tool_input === void 0 ? {} : value.tool_input };
|
|
25
|
+
return isToolHookInput(input) ? input : null;
|
|
26
|
+
}
|
|
7
27
|
|
|
8
28
|
// src/admission.ts
|
|
9
29
|
import { readFileSync } from "fs";
|
|
@@ -41,7 +61,7 @@ var matches = (rule, source, event) => {
|
|
|
41
61
|
return (ruleSource === "*" || ruleSource === source) && (ruleEvent === "*" || ruleEvent === event);
|
|
42
62
|
};
|
|
43
63
|
var isAdmitted = (rules, source, event) => !rules.disabled.some((rule) => matches(rule, source, event));
|
|
44
|
-
var readHookInput = async (source, fallbackEvent = "", stdin = process.stdin) => {
|
|
64
|
+
var readHookInput = async (source, fallbackEvent = "", stdin = process.stdin, parseInput) => {
|
|
45
65
|
if (source === null) {
|
|
46
66
|
process.stderr.write(`${degradedLine("hook", {
|
|
47
67
|
reason: "unknown_agent",
|
|
@@ -61,17 +81,23 @@ var readHookInput = async (source, fallbackEvent = "", stdin = process.stdin) =>
|
|
|
61
81
|
return null;
|
|
62
82
|
}
|
|
63
83
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
64
|
-
const
|
|
84
|
+
const input = parseInput ? parseInput(parsed) : parsed;
|
|
85
|
+
if (input === null) return null;
|
|
86
|
+
const event = eventNameOf(input) ?? fallbackEvent;
|
|
65
87
|
if (!isAdmitted(readAdmissionRules(), source, event)) return null;
|
|
66
|
-
if (stdin === process.stdin) registerTranscript(source,
|
|
67
|
-
return
|
|
88
|
+
if (stdin === process.stdin) registerTranscript(source, input);
|
|
89
|
+
return input;
|
|
68
90
|
};
|
|
69
91
|
var eventNameOf = (input) => {
|
|
70
92
|
if (!("hook_event_name" in input)) return void 0;
|
|
71
93
|
const name = input.hook_event_name;
|
|
72
94
|
return typeof name === "string" && name.length > 0 ? name : void 0;
|
|
73
95
|
};
|
|
96
|
+
function readToolHookInput(source, event, stdin = process.stdin) {
|
|
97
|
+
return readHookInput(source, event, stdin, parseToolHookInput);
|
|
98
|
+
}
|
|
74
99
|
|
|
75
100
|
export {
|
|
76
|
-
readHookInput
|
|
101
|
+
readHookInput,
|
|
102
|
+
readToolHookInput
|
|
77
103
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
canonicalGateInputs
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LNGYW6G4.js";
|
|
4
4
|
import {
|
|
5
5
|
canonicalJson
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SAF6NNXY.js";
|
|
7
7
|
import {
|
|
8
8
|
writeFileAtomic
|
|
9
9
|
} from "./chunk-T7E75EKA.js";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
BLOCKED_ACTION_GRANT_TTL_SECONDS,
|
|
12
12
|
blockedActionIdentity,
|
|
13
13
|
shouldDeferToNativeMode
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-FVKFDTN6.js";
|
|
15
15
|
|
|
16
16
|
// src/native-defer.ts
|
|
17
17
|
var nativeDeferOptions = () => {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NOTIFICATION_MATCHED_TYPES,
|
|
3
3
|
POSTTOOLUSE_MIRRORED_TOOLS
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WEO5JCB4.js";
|
|
5
5
|
import {
|
|
6
6
|
isProtectedByScope,
|
|
7
7
|
registerHookEntry
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SAF6NNXY.js";
|
|
9
9
|
import {
|
|
10
10
|
CLAUDE_PRETOOLUSE_MATCHER,
|
|
11
11
|
HOOK_BUDGETS,
|
|
12
12
|
HOOK_LOCATOR_BINARY
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-FVKFDTN6.js";
|
|
14
14
|
|
|
15
15
|
// src/gemini-config.ts
|
|
16
16
|
var GEMINI_HOOK_BINARY = "pushary-gemini-hook";
|
|
@@ -59,7 +59,7 @@ var COMMAND_LIST = [
|
|
|
59
59
|
},
|
|
60
60
|
{ name: "doctor", module: "pushary-doctor", summary: "Verify your Pushary installation is working" },
|
|
61
61
|
{ name: "disconnect", module: "pushary-disconnect", summary: "Turn off one agent (claude|codex|gemini|cursor)" },
|
|
62
|
-
{ name: "clean", module: "pushary-clean", summary: "Remove
|
|
62
|
+
{ name: "clean", module: "pushary-clean", summary: "Remove Pushary from this machine (--everything: the Mac app's setup too, --dry-run: preview)" },
|
|
63
63
|
{ name: "mode", module: "pushary-mode", summary: "Choose where approval requests appear" },
|
|
64
64
|
{ name: "wait", module: "pushary-wait", summary: 'Show or set the "wait for your phone" ladder (pushary wait 45)' },
|
|
65
65
|
{ name: "stats", module: "pushary-stats", summary: "Show the approval moments your agents hit while not connected" },
|
|
@@ -98,6 +98,7 @@ var COMMAND_OPTIONS = {
|
|
|
98
98
|
],
|
|
99
99
|
clean: [
|
|
100
100
|
["--dry-run", "List everything it would remove and change nothing"],
|
|
101
|
+
["--everything", "Also remove what the Mac app set up: quits it, then its keychain items, local state and editor extension"],
|
|
101
102
|
["--yes", "Remove everything without asking"]
|
|
102
103
|
],
|
|
103
104
|
transcripts: [
|
|
@@ -216,7 +216,7 @@ var AGENTS = {
|
|
|
216
216
|
connectVia: "Native hooks",
|
|
217
217
|
setupCommand: "npx @pushary/agent-hooks setup",
|
|
218
218
|
enforcementDetail: "exec, write and edit through native PreToolUse hooks, answered in Devin's own approve/block schema.",
|
|
219
|
-
capabilityNote: "Devin CLI answers PreToolUse with `{decision}` rather than a permission decision.
|
|
219
|
+
capabilityNote: "Devin CLI answers PreToolUse with `{decision}` rather than a permission decision. Pushary blocks an unanswered approval because this adapter cannot request a native prompt reliably. Question and plan dialogs remain with Devin; this adapter does not render their answers. It also fires no Notification event."
|
|
220
220
|
},
|
|
221
221
|
windsurf: {
|
|
222
222
|
...defaults,
|
|
@@ -292,7 +292,8 @@ var toToolLookup = (profile, toolName, toolInput, resolvePath = (path) => path)
|
|
|
292
292
|
var renderPreToolUseVerdict = (profile, verdict) => {
|
|
293
293
|
if (profile.wire === "permission_decision") return verdict;
|
|
294
294
|
const { permissionDecision, permissionDecisionReason, updatedInput } = verdict.hookSpecificOutput;
|
|
295
|
-
if (permissionDecision === "ask"
|
|
295
|
+
if (permissionDecision === "ask") return { decision: "block", reason: permissionDecisionReason ?? "Pushary requires an explicit approval before this tool can run." };
|
|
296
|
+
if (updatedInput) return void 0;
|
|
296
297
|
const stop = verdict.continue === false ? { continue: false, ...verdict.stopReason ? { stopReason: verdict.stopReason } : {} } : {};
|
|
297
298
|
return {
|
|
298
299
|
decision: permissionDecision === "allow" ? "approve" : "block",
|
|
@@ -333,7 +334,9 @@ var QWEN_CODE = {
|
|
|
333
334
|
replace: "Edit",
|
|
334
335
|
read_file: "Read",
|
|
335
336
|
WriteFile: "Write",
|
|
336
|
-
ReadFile: "Read"
|
|
337
|
+
ReadFile: "Read",
|
|
338
|
+
ask_user_question: "AskUserQuestion",
|
|
339
|
+
exit_plan_mode: "ExitPlanMode"
|
|
337
340
|
},
|
|
338
341
|
extraMatchers: ["mcp__.*"],
|
|
339
342
|
pathInputKeys: ["absolute_path"],
|
|
@@ -415,12 +418,14 @@ var DEVIN = {
|
|
|
415
418
|
exec: "Bash",
|
|
416
419
|
write: "Write",
|
|
417
420
|
edit: "Edit",
|
|
421
|
+
apply_patch: "Edit",
|
|
422
|
+
notebook_edit: "NotebookEdit",
|
|
418
423
|
read: "Read",
|
|
419
424
|
webfetch: "WebFetch",
|
|
420
425
|
web_search: "WebSearch",
|
|
421
426
|
run_subagent: "Task"
|
|
422
427
|
},
|
|
423
|
-
extraMatchers: ["mcp__.*"],
|
|
428
|
+
extraMatchers: ["mcp__.*", "mcp_call_tool", "write_to_process"],
|
|
424
429
|
pathInputKeys: [],
|
|
425
430
|
shellCommandKeys: [],
|
|
426
431
|
shellContextKeys: [],
|
|
@@ -602,6 +607,8 @@ var hookWaitClamped = (startMs, policyWaitSeconds, agent, nowMs) => startMs + ho
|
|
|
602
607
|
var effectiveWaitSeconds = (timeoutAction, policySeconds, agent) => timeoutAction === "wait" ? hookMaxWaitSeconds(agent) : policySeconds;
|
|
603
608
|
var OPENCODE_APPROVAL_EVENT = "permission.ask";
|
|
604
609
|
var CURSOR_GATE_EVENTS = ["beforeShellExecution", "beforeMCPExecution", "preToolUse"];
|
|
610
|
+
var SUPPORT_EMAIL = "business@pushary.com";
|
|
611
|
+
var SUPPORT_DISCORD = "https://discord.gg/9v3VvUByrr";
|
|
605
612
|
var HOOK_LOCATOR_BINARY = "pushary-bridge";
|
|
606
613
|
var HOOK_BATCH_MAX_BYTES = 4 * 1024 * 1024;
|
|
607
614
|
var REPO_KEY_MAX_LENGTH = 200;
|
|
@@ -1221,6 +1228,7 @@ var computeDeltaSignal = (input) => {
|
|
|
1221
1228
|
return { deltaSignal: "match", deltaScore: 0, remoteApprove: !destructive };
|
|
1222
1229
|
};
|
|
1223
1230
|
var SECRET_REDACTION_RULES = [
|
|
1231
|
+
{ pattern: /\bpk_[A-Za-z0-9_]+\.[A-Za-z0-9_]+/g, replacement: "[redacted]" },
|
|
1224
1232
|
{ pattern: /-----BEGIN[A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END[A-Z0-9 ]*PRIVATE KEY-----/g, replacement: "[redacted key]" },
|
|
1225
1233
|
{ pattern: /\bsk-[A-Za-z0-9_-]{16,}\b/g, replacement: "[redacted]" },
|
|
1226
1234
|
{ pattern: /\b[spr]k_(?:live|test)_[A-Za-z0-9]{8,}\b/g, replacement: "[redacted]" },
|
|
@@ -1344,6 +1352,10 @@ var ANSWER_SOURCES = [
|
|
|
1344
1352
|
];
|
|
1345
1353
|
var isAnswerSource = (value) => typeof value === "string" && ANSWER_SOURCES.includes(value);
|
|
1346
1354
|
var SETTLED_OUTCOMES = ["approve", "deny"];
|
|
1355
|
+
var SETTLED_OUTCOME = {
|
|
1356
|
+
approve: "approve",
|
|
1357
|
+
deny: "deny"
|
|
1358
|
+
};
|
|
1347
1359
|
var isSettledOutcome = (value) => typeof value === "string" && SETTLED_OUTCOMES.includes(value);
|
|
1348
1360
|
var classifyDecisionRisk = (toolName, toolTarget) => {
|
|
1349
1361
|
const parts = [toolName, toolTarget ?? ""];
|
|
@@ -1621,6 +1633,10 @@ var resolvePolicyAcross = (config, toolName, modeOverride, toolInputs, cwd, repo
|
|
|
1621
1633
|
};
|
|
1622
1634
|
var isModeStateDegraded = (state) => state?.degraded === true;
|
|
1623
1635
|
var KILL_REASON = "Stopped by user, this agent was halted from Pushary";
|
|
1636
|
+
var GATE_ALLOW_SOURCE = {
|
|
1637
|
+
allowlist: "allowlist",
|
|
1638
|
+
policy: "policy"
|
|
1639
|
+
};
|
|
1624
1640
|
var PUSHARY_TOOL_PREFIX = "mcp__pushary__";
|
|
1625
1641
|
var isPusharyOwnTool = (toolName) => toolName.startsWith(PUSHARY_TOOL_PREFIX);
|
|
1626
1642
|
var strictestScopeVerdict = (scope, paths) => {
|
|
@@ -1649,7 +1665,15 @@ var shouldDeferToNativeMode = (permissionMode, toolName, options = {}) => {
|
|
|
1649
1665
|
if (permissionMode === "bypassPermissions") return options.deferBypass === true;
|
|
1650
1666
|
return false;
|
|
1651
1667
|
};
|
|
1652
|
-
var
|
|
1668
|
+
var AGENT_QUESTION_TOOL = "AskUserQuestion";
|
|
1669
|
+
var AGENT_QUESTION_STRATEGY = { native: "native_dialog", updatedInput: "updated_input", none: "not_a_question" };
|
|
1670
|
+
var UPDATED_INPUT_QUESTION_SOURCES = /* @__PURE__ */ new Set(["claude", "qoder", "codebuddy", "droid"]);
|
|
1671
|
+
function agentQuestionStrategy(source, event, toolName) {
|
|
1672
|
+
if (toolName !== AGENT_QUESTION_TOOL) return AGENT_QUESTION_STRATEGY.none;
|
|
1673
|
+
if (source !== null && event === "PreToolUse" && UPDATED_INPUT_QUESTION_SOURCES.has(source)) return AGENT_QUESTION_STRATEGY.updatedInput;
|
|
1674
|
+
return AGENT_QUESTION_STRATEGY.native;
|
|
1675
|
+
}
|
|
1676
|
+
var ASKED_IN_EVERY_MODE_TOOLS = [AGENT_QUESTION_TOOL, "ExitPlanMode"];
|
|
1653
1677
|
var ASKED_IN_EVERY_MODE = new Set(ASKED_IN_EVERY_MODE_TOOLS);
|
|
1654
1678
|
var isAskedInEveryMode = (toolName) => ASKED_IN_EVERY_MODE.has(toolName);
|
|
1655
1679
|
var NATIVE_BLOCK_EVENTS = /* @__PURE__ */ new Set(["PermissionDenied"]);
|
|
@@ -1728,6 +1752,8 @@ var resolveGate = (input) => {
|
|
|
1728
1752
|
scopePath: scopeReason && "path" in scopeVerdict ? widenablePath(scopeVerdict.path) : void 0
|
|
1729
1753
|
};
|
|
1730
1754
|
};
|
|
1755
|
+
var editAsksAtTheAgentsPrompt = (input, verdict) => verdict.kind === "gate" && !verdict.scopeReason && (input.modeState.mode ?? input.config.modeOverride ?? null) === null && verdict.policy.origin === "builtin" && verdict.policy.mode === "push_first" && ACCEPT_EDITS_DEFER_TOOLS.has(input.toolName);
|
|
1756
|
+
var claudePromptsBeforeAnEdit = (permissionMode) => permissionMode === "default";
|
|
1731
1757
|
var toPolicyVersion = (value) => typeof value === "string" || typeof value === "number" ? String(value) : null;
|
|
1732
1758
|
var modeStateFromResponse = (data) => {
|
|
1733
1759
|
const mode = data.override?.mode;
|
|
@@ -1747,6 +1773,42 @@ var modeStateFromResponse = (data) => {
|
|
|
1747
1773
|
var GATE_WIRE = 1;
|
|
1748
1774
|
var GATE_MAX_TOOL_INPUTS = 32;
|
|
1749
1775
|
var GATE_BLOCK_REASON_MAX_LENGTH = 200;
|
|
1776
|
+
var wireVerdictFor = (verdict, deadlineSeconds) => {
|
|
1777
|
+
switch (verdict.kind) {
|
|
1778
|
+
case "kill":
|
|
1779
|
+
return { kind: "kill", reason: verdict.reason };
|
|
1780
|
+
case "allow":
|
|
1781
|
+
return { kind: "allow", source: verdict.source, policy: verdict.policy };
|
|
1782
|
+
case "deny":
|
|
1783
|
+
return { kind: "deny", reason: verdict.reason, policy: verdict.policy };
|
|
1784
|
+
case "defer":
|
|
1785
|
+
return { kind: "no_opinion", reason: verdict.reason === "own_tool" ? "not_gated" : "degraded" };
|
|
1786
|
+
case "gate":
|
|
1787
|
+
return {
|
|
1788
|
+
kind: "ask",
|
|
1789
|
+
policy: verdict.policy,
|
|
1790
|
+
deadlineSeconds,
|
|
1791
|
+
...verdict.scopeReason ? { scopeReason: verdict.scopeReason } : {},
|
|
1792
|
+
...verdict.scopePath ? { scopePath: verdict.scopePath } : {}
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
};
|
|
1796
|
+
var machineDecisionFor = (verdict) => {
|
|
1797
|
+
switch (verdict.kind) {
|
|
1798
|
+
case "kill":
|
|
1799
|
+
return { origin: DECISION_ORIGIN.killSwitch, outcome: SETTLED_OUTCOME.deny };
|
|
1800
|
+
case "allow":
|
|
1801
|
+
return {
|
|
1802
|
+
origin: verdict.source === GATE_ALLOW_SOURCE.allowlist ? DECISION_ORIGIN.safeReadonly : DECISION_ORIGIN.autopilot,
|
|
1803
|
+
outcome: SETTLED_OUTCOME.approve
|
|
1804
|
+
};
|
|
1805
|
+
case "deny":
|
|
1806
|
+
return { origin: DECISION_ORIGIN.autopilot, outcome: SETTLED_OUTCOME.deny };
|
|
1807
|
+
case "ask":
|
|
1808
|
+
case "no_opinion":
|
|
1809
|
+
return null;
|
|
1810
|
+
}
|
|
1811
|
+
};
|
|
1750
1812
|
var claudePermissionDeniedOutput = (decision) => ({
|
|
1751
1813
|
hookSpecificOutput: {
|
|
1752
1814
|
hookEventName: "PermissionDenied",
|
|
@@ -1807,7 +1869,6 @@ var claudePermissionRequestOutput = (decision, reason, updatedInput) => ({
|
|
|
1807
1869
|
decision: decision === "allow" ? { behavior: "allow", ...updatedInput ? { updatedInput } : {} } : { behavior: "deny", ...reason ? { message: reason } : {} }
|
|
1808
1870
|
}
|
|
1809
1871
|
});
|
|
1810
|
-
var COMPATIBLE_GATE_EVENT = "PreToolUse";
|
|
1811
1872
|
var gateOutputFor = (source, event, decision, reason) => {
|
|
1812
1873
|
let output;
|
|
1813
1874
|
if (source === "claude" || source === "vscode") {
|
|
@@ -1847,8 +1908,12 @@ var gateOutputFor = (source, event, decision, reason) => {
|
|
|
1847
1908
|
};
|
|
1848
1909
|
} else {
|
|
1849
1910
|
const profile = hookCompatibleProfileBySource(source);
|
|
1850
|
-
if (profile
|
|
1851
|
-
|
|
1911
|
+
if (profile?.events.includes(event)) {
|
|
1912
|
+
if (event === "PreToolUse") {
|
|
1913
|
+
output = renderPreToolUseVerdict(profile, claudePreToolUseOutput(decision, reason));
|
|
1914
|
+
} else if (event === "PermissionRequest" && decision !== "ask") {
|
|
1915
|
+
output = claudePermissionRequestOutput(decision, reason);
|
|
1916
|
+
}
|
|
1852
1917
|
}
|
|
1853
1918
|
}
|
|
1854
1919
|
return output;
|
|
@@ -2037,6 +2102,8 @@ export {
|
|
|
2037
2102
|
effectiveWaitSeconds,
|
|
2038
2103
|
OPENCODE_APPROVAL_EVENT,
|
|
2039
2104
|
CURSOR_GATE_EVENTS,
|
|
2105
|
+
SUPPORT_EMAIL,
|
|
2106
|
+
SUPPORT_DISCORD,
|
|
2040
2107
|
HOOK_LOCATOR_BINARY,
|
|
2041
2108
|
normalizeRepoRemote,
|
|
2042
2109
|
localRepoKey,
|
|
@@ -2055,6 +2122,8 @@ export {
|
|
|
2055
2122
|
KILL_REASON,
|
|
2056
2123
|
isPusharyOwnTool,
|
|
2057
2124
|
shouldDeferToNativeMode,
|
|
2125
|
+
AGENT_QUESTION_STRATEGY,
|
|
2126
|
+
agentQuestionStrategy,
|
|
2058
2127
|
CODEX_RESCUE_TOOL_NAME,
|
|
2059
2128
|
isBlockedActionRequest,
|
|
2060
2129
|
BLOCKED_ACTION_GRANT_TTL_SECONDS,
|
|
@@ -2063,10 +2132,14 @@ export {
|
|
|
2063
2132
|
isPermissionRequestOwnedByPreToolUse,
|
|
2064
2133
|
CLAUDE_PRETOOLUSE_MATCHER,
|
|
2065
2134
|
resolveGate,
|
|
2135
|
+
editAsksAtTheAgentsPrompt,
|
|
2136
|
+
claudePromptsBeforeAnEdit,
|
|
2066
2137
|
modeStateFromResponse,
|
|
2067
2138
|
GATE_WIRE,
|
|
2068
2139
|
GATE_MAX_TOOL_INPUTS,
|
|
2069
2140
|
GATE_BLOCK_REASON_MAX_LENGTH,
|
|
2141
|
+
wireVerdictFor,
|
|
2142
|
+
machineDecisionFor,
|
|
2070
2143
|
claudePermissionDeniedOutput,
|
|
2071
2144
|
codexStopRescueOutput,
|
|
2072
2145
|
stoppedOutput,
|