@pushary/agent-hooks 0.85.2 → 0.87.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 +17 -0
- package/dist/bin/pushary-bell-hook.js +4 -4
- package/dist/bin/pushary-bell.js +6 -6
- package/dist/bin/pushary-claude.js +12 -10
- package/dist/bin/pushary-clean.js +10 -9
- package/dist/bin/pushary-codex-bridge.js +5 -5
- package/dist/bin/pushary-codex-hook.js +13 -29
- package/dist/bin/pushary-codex.js +6 -4
- package/dist/bin/pushary-connect.js +6 -6
- package/dist/bin/pushary-daemon.js +4 -4
- package/dist/bin/pushary-disconnect.js +25 -10
- package/dist/bin/pushary-doctor.js +21 -15
- package/dist/bin/pushary-elicitation-hook.d.ts +1 -0
- package/dist/bin/pushary-elicitation-hook.js +210 -0
- package/dist/bin/pushary-gemini-bridge.js +5 -5
- package/dist/bin/pushary-gemini-hook.js +10 -8
- package/dist/bin/pushary-hook.js +7 -8
- 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 -3
- package/dist/bin/pushary-permission-denied-hook.js +7 -8
- package/dist/bin/pushary-permission-hook.js +7 -8
- package/dist/bin/pushary-post-hook.js +4 -3
- package/dist/bin/pushary-prompt-hook.js +4 -3
- package/dist/bin/pushary-session-end-hook.js +4 -3
- package/dist/bin/pushary-session-start-hook.js +4 -3
- package/dist/bin/pushary-setup.js +26 -21
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +5 -5
- package/dist/bin/pushary-stop-hook.js +4 -3
- package/dist/bin/pushary-stopfailure-hook.js +4 -3
- package/dist/bin/pushary-upgrade.js +13 -11
- package/dist/bin/pushary-wait.js +3 -3
- package/dist/{chunk-GM74DUMS.js → chunk-2T3GX7WG.js} +1 -1
- package/dist/{chunk-XJDL3MUE.js → chunk-5646VKR4.js} +18 -20
- package/dist/{chunk-PKUNB3SN.js → chunk-7MBDFNUC.js} +1 -1
- package/dist/{chunk-K337LIBD.js → chunk-7YJS2VTG.js} +36 -4
- package/dist/{chunk-LCA2EQTK.js → chunk-A3PFIWWN.js} +1 -1
- package/dist/{chunk-LSB6PFLN.js → chunk-A4I5JGCW.js} +1 -1
- package/dist/chunk-ATBKJNWS.js +19 -0
- package/dist/{chunk-KJW6NKF7.js → chunk-B3V2H6SA.js} +39 -15
- package/dist/{chunk-T54OT7IY.js → chunk-ECEUMWBH.js} +1 -1
- package/dist/{chunk-Q4URN3E7.js → chunk-HAUTLCMA.js} +1 -1
- package/dist/{chunk-Y7E2MC3G.js → chunk-HJ44HIUW.js} +60 -31
- package/dist/{chunk-4U2YRHNF.js → chunk-IWL5LWIE.js} +2 -2
- package/dist/chunk-J3YDT4HM.js +128 -0
- package/dist/{chunk-NTIUQB3E.js → chunk-JAICP7BA.js} +1 -1
- package/dist/{chunk-HSGEEBBL.js → chunk-M7RYIZX6.js} +3 -3
- package/dist/{chunk-KZIGJLOX.js → chunk-OT4YD54Q.js} +1 -1
- package/dist/{chunk-LXWISFF3.js → chunk-QBWYNVKY.js} +1 -1
- package/dist/{chunk-4YMWLMAP.js → chunk-SJVLFIYP.js} +1 -1
- package/dist/{chunk-DPDUB4XF.js → chunk-V2XPF77V.js} +104 -163
- package/dist/{chunk-JBLRZGTT.js → chunk-WLLBFDVY.js} +1 -1
- package/dist/{chunk-JT5NQQCE.js → chunk-XW5CHAQX.js} +2 -2
- package/dist/{chunk-CWV4CMB6.js → chunk-Y3UTTFTZ.js} +1 -1
- package/dist/{chunk-GY3I353G.js → chunk-ZZE6FN7T.js} +7 -3
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +11 -11
- package/package.json +3 -1
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
detectClaudeVersion
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-HAUTLCMA.js";
|
|
5
5
|
import {
|
|
6
6
|
claudeWired,
|
|
7
7
|
codexWired,
|
|
8
8
|
geminiWired
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-XW5CHAQX.js";
|
|
10
10
|
import {
|
|
11
11
|
runBrowserLogin
|
|
12
12
|
} from "../chunk-Z3Z4VK5F.js";
|
|
13
13
|
import {
|
|
14
14
|
ensureDaemonRunning
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-SJVLFIYP.js";
|
|
16
|
+
import {
|
|
17
|
+
addClaudeMcpServer,
|
|
18
|
+
addPusharyHooks,
|
|
19
|
+
addPusharyToolPermissions,
|
|
20
|
+
compareVersion,
|
|
21
|
+
parseVersion
|
|
22
|
+
} from "../chunk-5646VKR4.js";
|
|
16
23
|
import {
|
|
17
24
|
describeDetection,
|
|
18
25
|
detectAllAgents,
|
|
@@ -24,23 +31,17 @@ import {
|
|
|
24
31
|
shortenHome,
|
|
25
32
|
vscodeSettingsTargets,
|
|
26
33
|
writeInstructionBlock
|
|
27
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-IWL5LWIE.js";
|
|
28
35
|
import {
|
|
29
36
|
GEMINI_HOOK_BINARY,
|
|
30
37
|
addGeminiHooks,
|
|
31
38
|
addGeminiMcpServer
|
|
32
|
-
} from "../chunk-
|
|
33
|
-
import
|
|
34
|
-
addClaudeMcpServer,
|
|
35
|
-
addPusharyHooks,
|
|
36
|
-
addPusharyToolPermissions,
|
|
37
|
-
compareVersion,
|
|
38
|
-
parseVersion
|
|
39
|
-
} from "../chunk-XJDL3MUE.js";
|
|
39
|
+
} from "../chunk-ZZE6FN7T.js";
|
|
40
|
+
import "../chunk-ATBKJNWS.js";
|
|
40
41
|
import {
|
|
41
42
|
guardBinary,
|
|
42
43
|
guardNodeScript
|
|
43
|
-
} from "../chunk-
|
|
44
|
+
} from "../chunk-M7RYIZX6.js";
|
|
44
45
|
import "../chunk-XHKBHWLX.js";
|
|
45
46
|
import {
|
|
46
47
|
installGlobally,
|
|
@@ -58,6 +59,7 @@ import {
|
|
|
58
59
|
codexAgentsMd2 as codexAgentsMd,
|
|
59
60
|
codexConfigToml,
|
|
60
61
|
codexHome,
|
|
62
|
+
codexHookPositions,
|
|
61
63
|
codexSkillDir2 as codexSkillDir,
|
|
62
64
|
cursorPluginDir,
|
|
63
65
|
cursorUserHooks,
|
|
@@ -65,10 +67,11 @@ import {
|
|
|
65
67
|
geminiSettings,
|
|
66
68
|
pusharyConfigFile,
|
|
67
69
|
vscodePluginDir
|
|
68
|
-
} from "../chunk-
|
|
70
|
+
} from "../chunk-B3V2H6SA.js";
|
|
69
71
|
import {
|
|
70
72
|
reportEvent
|
|
71
|
-
} from "../chunk-
|
|
73
|
+
} from "../chunk-V2XPF77V.js";
|
|
74
|
+
import "../chunk-J3YDT4HM.js";
|
|
72
75
|
import "../chunk-RN3NOEJF.js";
|
|
73
76
|
import {
|
|
74
77
|
confirmAppConnection,
|
|
@@ -78,12 +81,12 @@ import {
|
|
|
78
81
|
printConnectInstructions,
|
|
79
82
|
setHumanStream,
|
|
80
83
|
verifyRoundTrip
|
|
81
|
-
} from "../chunk-
|
|
84
|
+
} from "../chunk-A3PFIWWN.js";
|
|
82
85
|
import "../chunk-3EGEA4KH.js";
|
|
83
86
|
import {
|
|
84
87
|
checkApiKey,
|
|
85
88
|
describeKeyCheck
|
|
86
|
-
} from "../chunk-
|
|
89
|
+
} from "../chunk-A4I5JGCW.js";
|
|
87
90
|
import {
|
|
88
91
|
useColor
|
|
89
92
|
} from "../chunk-5RUIFDTP.js";
|
|
@@ -94,7 +97,7 @@ import {
|
|
|
94
97
|
readConfigFileKey,
|
|
95
98
|
readKeySource,
|
|
96
99
|
writeKey
|
|
97
|
-
} from "../chunk-
|
|
100
|
+
} from "../chunk-OT4YD54Q.js";
|
|
98
101
|
import {
|
|
99
102
|
parseFlags
|
|
100
103
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -117,7 +120,7 @@ import {
|
|
|
117
120
|
} from "../chunk-6MTNS63X.js";
|
|
118
121
|
import "../chunk-BSZYIAZL.js";
|
|
119
122
|
import "../chunk-SAF6HGAA.js";
|
|
120
|
-
import "../chunk-
|
|
123
|
+
import "../chunk-Y3UTTFTZ.js";
|
|
121
124
|
import {
|
|
122
125
|
UsageError
|
|
123
126
|
} from "../chunk-7QLSKOSU.js";
|
|
@@ -127,7 +130,7 @@ import {
|
|
|
127
130
|
import "../chunk-2UMNXADU.js";
|
|
128
131
|
import {
|
|
129
132
|
isValidApiKey
|
|
130
|
-
} from "../chunk-
|
|
133
|
+
} from "../chunk-7YJS2VTG.js";
|
|
131
134
|
|
|
132
135
|
// bin/pushary-setup.ts
|
|
133
136
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, rmSync, renameSync, realpathSync, readdirSync, statSync } from "fs";
|
|
@@ -940,10 +943,12 @@ var setupCodex = async (apiKey) => {
|
|
|
940
943
|
let trusted = false;
|
|
941
944
|
if (hooksSupported) {
|
|
942
945
|
const hookCommand = guardBinary(resolveGlobalBinary("pushary-codex-hook") ?? "pushary-codex-hook");
|
|
946
|
+
let hookPositions = {};
|
|
943
947
|
await spinner("Adding native hooks (~/.codex/hooks.json)", async () => {
|
|
944
948
|
const hooksConfig = readAgentJson(CODEX_HOOKS_JSON);
|
|
945
949
|
addCodexHooks(hooksConfig, hookCommand);
|
|
946
950
|
writeJson(CODEX_HOOKS_JSON, hooksConfig);
|
|
951
|
+
hookPositions = codexHookPositions(hooksConfig);
|
|
947
952
|
});
|
|
948
953
|
if (trustAuto) {
|
|
949
954
|
await spinner("Trusting the Pushary hook (skips the /hooks step)", async () => {
|
|
@@ -953,7 +958,7 @@ var setupCodex = async (apiKey) => {
|
|
|
953
958
|
} catch {
|
|
954
959
|
}
|
|
955
960
|
const config = raw ? parseTOML(raw) : {};
|
|
956
|
-
addCodexHookTrust(config, CODEX_HOOKS_JSON, hookCommand);
|
|
961
|
+
addCodexHookTrust(config, CODEX_HOOKS_JSON, hookCommand, hookPositions);
|
|
957
962
|
writeFileSync(codexConfig, stringifyTOML(config), "utf-8");
|
|
958
963
|
trusted = true;
|
|
959
964
|
}, { optional: true });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
readLedgerSummary
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-7MBDFNUC.js";
|
|
5
5
|
import {
|
|
6
6
|
exitOnHelpFlag
|
|
7
7
|
} from "../chunk-SQOFGPNX.js";
|
|
@@ -11,7 +11,7 @@ import "../chunk-KZERVKTD.js";
|
|
|
11
11
|
import {
|
|
12
12
|
getApiKey
|
|
13
13
|
} from "../chunk-2UMNXADU.js";
|
|
14
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-7YJS2VTG.js";
|
|
15
15
|
|
|
16
16
|
// bin/pushary-stats.ts
|
|
17
17
|
exitOnHelpFlag("stats");
|
|
@@ -8,18 +8,18 @@ import {
|
|
|
8
8
|
describeReach,
|
|
9
9
|
fetchChannels,
|
|
10
10
|
reachVerdict
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-A3PFIWWN.js";
|
|
12
12
|
import "../chunk-3EGEA4KH.js";
|
|
13
13
|
import {
|
|
14
14
|
checkApiKey,
|
|
15
15
|
describeKeyCheck
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-A4I5JGCW.js";
|
|
17
17
|
import {
|
|
18
18
|
createIo
|
|
19
19
|
} from "../chunk-5RUIFDTP.js";
|
|
20
20
|
import {
|
|
21
21
|
readKeySource
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-OT4YD54Q.js";
|
|
23
23
|
import {
|
|
24
24
|
rejectUnknownFlags
|
|
25
25
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -32,7 +32,7 @@ import "../chunk-DINDL2CF.js";
|
|
|
32
32
|
import "../chunk-6MTNS63X.js";
|
|
33
33
|
import "../chunk-BSZYIAZL.js";
|
|
34
34
|
import "../chunk-SAF6HGAA.js";
|
|
35
|
-
import "../chunk-
|
|
35
|
+
import "../chunk-Y3UTTFTZ.js";
|
|
36
36
|
import {
|
|
37
37
|
UsageError
|
|
38
38
|
} from "../chunk-7QLSKOSU.js";
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
EXIT
|
|
41
41
|
} from "../chunk-KZERVKTD.js";
|
|
42
42
|
import "../chunk-2UMNXADU.js";
|
|
43
|
-
import "../chunk-
|
|
43
|
+
import "../chunk-7YJS2VTG.js";
|
|
44
44
|
|
|
45
45
|
// src/status.ts
|
|
46
46
|
var keySourceLine = (source) => {
|
|
@@ -4,15 +4,16 @@ import {
|
|
|
4
4
|
} from "../chunk-6CUUA7HO.js";
|
|
5
5
|
import {
|
|
6
6
|
handleStop
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-V2XPF77V.js";
|
|
8
|
+
import "../chunk-J3YDT4HM.js";
|
|
8
9
|
import "../chunk-RN3NOEJF.js";
|
|
9
10
|
import "../chunk-BSZYIAZL.js";
|
|
10
11
|
import "../chunk-SAF6HGAA.js";
|
|
11
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-Y3UTTFTZ.js";
|
|
12
13
|
import "../chunk-7QLSKOSU.js";
|
|
13
14
|
import "../chunk-KZERVKTD.js";
|
|
14
15
|
import "../chunk-2UMNXADU.js";
|
|
15
|
-
import "../chunk-
|
|
16
|
+
import "../chunk-7YJS2VTG.js";
|
|
16
17
|
|
|
17
18
|
// bin/pushary-stop-hook.ts
|
|
18
19
|
var main = async () => {
|
|
@@ -4,15 +4,16 @@ import {
|
|
|
4
4
|
} from "../chunk-6CUUA7HO.js";
|
|
5
5
|
import {
|
|
6
6
|
handleStopFailure
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-V2XPF77V.js";
|
|
8
|
+
import "../chunk-J3YDT4HM.js";
|
|
8
9
|
import "../chunk-RN3NOEJF.js";
|
|
9
10
|
import "../chunk-BSZYIAZL.js";
|
|
10
11
|
import "../chunk-SAF6HGAA.js";
|
|
11
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-Y3UTTFTZ.js";
|
|
12
13
|
import "../chunk-7QLSKOSU.js";
|
|
13
14
|
import "../chunk-KZERVKTD.js";
|
|
14
15
|
import "../chunk-2UMNXADU.js";
|
|
15
|
-
import "../chunk-
|
|
16
|
+
import "../chunk-7YJS2VTG.js";
|
|
16
17
|
|
|
17
18
|
// bin/pushary-stopfailure-hook.ts
|
|
18
19
|
var main = async () => {
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
detectClaudeVersion
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-HAUTLCMA.js";
|
|
5
|
+
import {
|
|
6
|
+
addClaudeMcpServer,
|
|
7
|
+
addPusharyHooks,
|
|
8
|
+
addPusharyToolPermissions
|
|
9
|
+
} from "../chunk-5646VKR4.js";
|
|
5
10
|
import {
|
|
6
11
|
GEMINI_HOOK_BINARY,
|
|
7
12
|
addGeminiHooks,
|
|
8
13
|
addGeminiMcpServer,
|
|
9
14
|
hasGeminiHooks
|
|
10
|
-
} from "../chunk-
|
|
11
|
-
import
|
|
12
|
-
addClaudeMcpServer,
|
|
13
|
-
addPusharyHooks,
|
|
14
|
-
addPusharyToolPermissions
|
|
15
|
-
} from "../chunk-XJDL3MUE.js";
|
|
15
|
+
} from "../chunk-ZZE6FN7T.js";
|
|
16
|
+
import "../chunk-ATBKJNWS.js";
|
|
16
17
|
import {
|
|
17
18
|
guardBinary
|
|
18
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-M7RYIZX6.js";
|
|
19
20
|
import {
|
|
20
21
|
execNpm,
|
|
21
22
|
npmErrorMessage,
|
|
@@ -29,13 +30,14 @@ import {
|
|
|
29
30
|
addCodexMcpServer,
|
|
30
31
|
claudeJson,
|
|
31
32
|
codexConfigToml,
|
|
33
|
+
codexHookPositions,
|
|
32
34
|
codexHooksJson,
|
|
33
35
|
cursorPluginDir,
|
|
34
36
|
geminiSettings,
|
|
35
37
|
hasCodexHooks,
|
|
36
38
|
vscodePluginDir,
|
|
37
39
|
vscodePluginMcp
|
|
38
|
-
} from "../chunk-
|
|
40
|
+
} from "../chunk-B3V2H6SA.js";
|
|
39
41
|
import {
|
|
40
42
|
exitOnHelpFlag
|
|
41
43
|
} from "../chunk-SQOFGPNX.js";
|
|
@@ -50,7 +52,7 @@ import "../chunk-KZERVKTD.js";
|
|
|
50
52
|
import {
|
|
51
53
|
getApiKey
|
|
52
54
|
} from "../chunk-2UMNXADU.js";
|
|
53
|
-
import "../chunk-
|
|
55
|
+
import "../chunk-7YJS2VTG.js";
|
|
54
56
|
|
|
55
57
|
// bin/pushary-upgrade.ts
|
|
56
58
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -137,7 +139,7 @@ var reapplyCodexSettings = (apiKey, paths = {}) => {
|
|
|
137
139
|
}
|
|
138
140
|
if (config != null) {
|
|
139
141
|
try {
|
|
140
|
-
if (hooks) addCodexHookTrust(config, hooksPath, command);
|
|
142
|
+
if (hooks) addCodexHookTrust(config, hooksPath, command, codexHookPositions(hooksConfig ?? void 0));
|
|
141
143
|
if (apiKey) {
|
|
142
144
|
addCodexMcpServer(config, apiKey);
|
|
143
145
|
mcp = true;
|
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "../chunk-IIENZE2J.js";
|
|
5
5
|
import {
|
|
6
6
|
exitOnFailedResponse
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-JAICP7BA.js";
|
|
8
|
+
import "../chunk-A4I5JGCW.js";
|
|
9
9
|
import {
|
|
10
10
|
createIo
|
|
11
11
|
} from "../chunk-5RUIFDTP.js";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
getApiKey,
|
|
29
29
|
getBaseUrl
|
|
30
30
|
} from "../chunk-2UMNXADU.js";
|
|
31
|
-
import "../chunk-
|
|
31
|
+
import "../chunk-7YJS2VTG.js";
|
|
32
32
|
|
|
33
33
|
// bin/pushary-wait.ts
|
|
34
34
|
exitOnHelpFlag("wait");
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PRETOOLUSE_GATED_TOOLS,
|
|
3
|
+
PRETOOLUSE_PHONE_ANSWERED_TOOLS
|
|
4
|
+
} from "./chunk-ATBKJNWS.js";
|
|
1
5
|
import {
|
|
2
6
|
guardBinary
|
|
3
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-M7RYIZX6.js";
|
|
4
8
|
import {
|
|
5
|
-
HOOK_BUDGETS
|
|
6
|
-
|
|
9
|
+
HOOK_BUDGETS,
|
|
10
|
+
HOOK_LOCATOR_BINARY
|
|
11
|
+
} from "./chunk-7YJS2VTG.js";
|
|
7
12
|
|
|
8
13
|
// src/claude-config.ts
|
|
9
14
|
import { join } from "path";
|
|
@@ -21,21 +26,8 @@ var compareVersion = (a, b) => {
|
|
|
21
26
|
};
|
|
22
27
|
var atLeast = (version, floor) => compareVersion(version, floor) >= 0;
|
|
23
28
|
|
|
24
|
-
// src/claude-tools.ts
|
|
25
|
-
var PRETOOLUSE_GATED_TOOLS = [
|
|
26
|
-
"Bash",
|
|
27
|
-
"Write",
|
|
28
|
-
"Edit",
|
|
29
|
-
"MultiEdit",
|
|
30
|
-
"NotebookEdit",
|
|
31
|
-
"PowerShell",
|
|
32
|
-
"Monitor"
|
|
33
|
-
];
|
|
34
|
-
var POSTTOOLUSE_MIRRORED_TOOLS = [...PRETOOLUSE_GATED_TOOLS, "TodoWrite"];
|
|
35
|
-
var PRETOOLUSE_HANDLED_TOOLS = /* @__PURE__ */ new Set([...PRETOOLUSE_GATED_TOOLS, "AskUserQuestion"]);
|
|
36
|
-
|
|
37
29
|
// src/claude-events.ts
|
|
38
|
-
var GATED_TOOLS = [...PRETOOLUSE_GATED_TOOLS,
|
|
30
|
+
var GATED_TOOLS = [...PRETOOLUSE_GATED_TOOLS, ...PRETOOLUSE_PHONE_ANSWERED_TOOLS].join("|");
|
|
39
31
|
var MIRRORED_TOOLS = [...PRETOOLUSE_GATED_TOOLS, "TodoWrite"].join("|");
|
|
40
32
|
var ESTABLISHED = [1, 0, 0];
|
|
41
33
|
var OBSERVED = [2, 0, 0];
|
|
@@ -56,7 +48,11 @@ var CLAUDE_HOOK_EVENTS = [
|
|
|
56
48
|
{ event: "SubagentStop", binary: "pushary-stop-hook", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
57
49
|
{ event: "PreCompact", binary: "pushary-post-hook", matcher: "manual|auto", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
58
50
|
{ event: "PostCompact", binary: "pushary-post-hook", matcher: "manual|auto", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
59
|
-
{ event: "TeammateIdle", binary: "pushary-notification-hook", timeout: 10, delivery: "telemetry", since: OBSERVED }
|
|
51
|
+
{ event: "TeammateIdle", binary: "pushary-notification-hook", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
52
|
+
// An MCP server asking the person for a value, answered from the phone rather
|
|
53
|
+
// than the terminal. No matcher: Claude Code matches this event on the MCP
|
|
54
|
+
// server's name, and we have no business preferring one server over another.
|
|
55
|
+
{ event: "Elicitation", binary: "pushary-elicitation-hook", timeout: HOOK_BUDGETS.claude.budgetSeconds, delivery: "approval", since: OBSERVED, cliOnly: true }
|
|
60
56
|
];
|
|
61
57
|
var supportedClaudeEvents = (version) => CLAUDE_HOOK_EVENTS.filter((hook) => version ? atLeast(version, hook.since) : hook.since === ESTABLISHED);
|
|
62
58
|
|
|
@@ -72,7 +68,10 @@ var ensureRecord = (target, key) => {
|
|
|
72
68
|
return created;
|
|
73
69
|
};
|
|
74
70
|
var isPusharyPermission = (rule) => typeof rule === "string" && (rule.includes("pushary") || rule.includes("MCP(pushary"));
|
|
75
|
-
var HOOK_BINARIES = new Set(
|
|
71
|
+
var HOOK_BINARIES = /* @__PURE__ */ new Set([
|
|
72
|
+
...CLAUDE_HOOK_EVENTS.map((hook) => hook.binary),
|
|
73
|
+
HOOK_LOCATOR_BINARY
|
|
74
|
+
]);
|
|
76
75
|
var namesPusharyBinary = (command) => command.split(/[\s/\\"']+/).some((segment) => HOOK_BINARIES.has(segment.replace(/\.(cmd|exe)$/i, "")));
|
|
77
76
|
var isPusharyHook = (entry2) => {
|
|
78
77
|
const hooks = asRecord(entry2)?.hooks;
|
|
@@ -178,7 +177,6 @@ var removePusharySettings = (settings) => {
|
|
|
178
177
|
export {
|
|
179
178
|
parseVersion,
|
|
180
179
|
compareVersion,
|
|
181
|
-
PRETOOLUSE_HANDLED_TOOLS,
|
|
182
180
|
addClaudeMcpServer,
|
|
183
181
|
removeClaudeMcpServers,
|
|
184
182
|
addPusharyToolPermissions,
|
|
@@ -53,7 +53,8 @@ var HOOK_BUDGETS = {
|
|
|
53
53
|
gemini: { budgetSeconds: 180, guardSeconds: 10 },
|
|
54
54
|
// The Cursor gate is a dependency-free .mjs that cannot import this module; it
|
|
55
55
|
// mirrors these as MAX_BLOCK_MS (45s) inside its 60s failClosed budget.
|
|
56
|
-
cursor: { budgetSeconds: 60, guardSeconds: 15 }
|
|
56
|
+
cursor: { budgetSeconds: 60, guardSeconds: 15 },
|
|
57
|
+
vscode: { budgetSeconds: 60, guardSeconds: 15 }
|
|
57
58
|
};
|
|
58
59
|
var hookMaxWaitSeconds = (agent) => Math.max(HOOK_BUDGETS[agent].budgetSeconds - HOOK_BUDGETS[agent].guardSeconds, 1);
|
|
59
60
|
var hookWaitDeadline = (startMs, policyWaitSeconds, agent, nowMs) => {
|
|
@@ -65,6 +66,19 @@ var hookWaitDeadline = (startMs, policyWaitSeconds, agent, nowMs) => {
|
|
|
65
66
|
};
|
|
66
67
|
var hookWaitClamped = (startMs, policyWaitSeconds, agent, nowMs) => startMs + hookMaxWaitSeconds(agent) * 1e3 < nowMs + Math.max(policyWaitSeconds, 0) * 1e3;
|
|
67
68
|
var effectiveWaitSeconds = (timeoutAction, policySeconds, agent) => timeoutAction === "wait" ? hookMaxWaitSeconds(agent) : policySeconds;
|
|
69
|
+
var AGENT_LABELS_BY_TYPE = {
|
|
70
|
+
claude_code: "Claude Code",
|
|
71
|
+
claude_cowork: "Claude Cowork",
|
|
72
|
+
codex: "Codex",
|
|
73
|
+
chatgpt: "ChatGPT",
|
|
74
|
+
gemini_cli: "Gemini CLI",
|
|
75
|
+
hermes: "Hermes",
|
|
76
|
+
cursor: "Cursor",
|
|
77
|
+
vscode: "VS Code",
|
|
78
|
+
windsurf: "Windsurf",
|
|
79
|
+
unknown: "Agent"
|
|
80
|
+
};
|
|
81
|
+
var HOOK_LOCATOR_BINARY = "pushary-bridge";
|
|
68
82
|
var HOOK_BATCH_MAX_BYTES = 4 * 1024 * 1024;
|
|
69
83
|
var REPO_KEY_MAX_LENGTH = 200;
|
|
70
84
|
var isRepoKeyMatch = (ruleRepoKey, currentRepoKey) => {
|
|
@@ -502,6 +516,8 @@ var selectGoverningRule = (policies, toolName, args, repoKey, sessionId) => {
|
|
|
502
516
|
}
|
|
503
517
|
return best;
|
|
504
518
|
};
|
|
519
|
+
var ARG_PREFIX_TARGET_TOOLS = Object.keys(POLICY_COMMAND_KEYS);
|
|
520
|
+
var FILE_TARGET_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit"]);
|
|
505
521
|
var API_KEY_PATTERN = /^pk_[a-f0-9]+\.[a-f0-9]+$/;
|
|
506
522
|
var isValidApiKey = (value) => API_KEY_PATTERN.test(value);
|
|
507
523
|
var ACTION_BODY_MAX = 4e3;
|
|
@@ -945,6 +961,7 @@ var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, se
|
|
|
945
961
|
pushFirstSeconds: config.defaultPushFirstSeconds ?? 20
|
|
946
962
|
};
|
|
947
963
|
const governedBySpecificRule = match?.rank === "exact" || match?.rank === "prefix";
|
|
964
|
+
const governingMode = base.mode;
|
|
948
965
|
if (!governedBySpecificRule && toolName === "Bash" && typeof arg === "string" && isSafeReadOnlyCommand(arg)) {
|
|
949
966
|
base = autoApprove(base.tool);
|
|
950
967
|
}
|
|
@@ -954,7 +971,7 @@ var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, se
|
|
|
954
971
|
tool: base.tool,
|
|
955
972
|
timeoutSeconds: config.defaultTimeoutSeconds,
|
|
956
973
|
timeoutAction: "wait",
|
|
957
|
-
mode:
|
|
974
|
+
mode: governingMode,
|
|
958
975
|
pushFirstSeconds: config.defaultPushFirstSeconds ?? 20
|
|
959
976
|
};
|
|
960
977
|
}
|
|
@@ -1051,7 +1068,7 @@ var claudePermissionRequestOutput = (decision, reason, updatedInput) => ({
|
|
|
1051
1068
|
});
|
|
1052
1069
|
var gateOutputFor = (source, event, decision, reason) => {
|
|
1053
1070
|
let output;
|
|
1054
|
-
if (source === "claude") {
|
|
1071
|
+
if (source === "claude" || source === "vscode") {
|
|
1055
1072
|
if (event === "PreToolUse") {
|
|
1056
1073
|
output = claudePreToolUseOutput(decision, reason);
|
|
1057
1074
|
} else if (event === "PermissionRequest" && decision !== "ask") {
|
|
@@ -1085,6 +1102,17 @@ var gateOutputFor = (source, event, decision, reason) => {
|
|
|
1085
1102
|
}
|
|
1086
1103
|
return output;
|
|
1087
1104
|
};
|
|
1105
|
+
var ELICITATION_EVENTS = ["Elicitation", "ElicitationResult"];
|
|
1106
|
+
var claudeElicitationOutput = (event, action, content) => ({
|
|
1107
|
+
hookSpecificOutput: {
|
|
1108
|
+
hookEventName: event,
|
|
1109
|
+
action,
|
|
1110
|
+
// Only ever alongside an accept. A declined elicitation has nothing to carry,
|
|
1111
|
+
// and content beside a decline reads as an answer the person did not give.
|
|
1112
|
+
...action === "accept" && content ? { content } : {}
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
var renderElicitationOutput = (event, action, content) => ELICITATION_EVENTS.includes(event) ? JSON.stringify(claudeElicitationOutput(event, action, content)) : void 0;
|
|
1088
1116
|
|
|
1089
1117
|
export {
|
|
1090
1118
|
parseAgentQuestionAnswers,
|
|
@@ -1093,10 +1121,13 @@ export {
|
|
|
1093
1121
|
hookWaitDeadline,
|
|
1094
1122
|
hookWaitClamped,
|
|
1095
1123
|
effectiveWaitSeconds,
|
|
1124
|
+
AGENT_LABELS_BY_TYPE,
|
|
1125
|
+
HOOK_LOCATOR_BINARY,
|
|
1096
1126
|
normalizeRepoRemote,
|
|
1097
1127
|
localRepoKey,
|
|
1098
1128
|
isSafeReadOnlyCommand,
|
|
1099
1129
|
isAutoApprove,
|
|
1130
|
+
FILE_TARGET_TOOLS,
|
|
1100
1131
|
isValidApiKey,
|
|
1101
1132
|
ACTION_BODY_MAX,
|
|
1102
1133
|
DECISION_LINE_MAX,
|
|
@@ -1110,5 +1141,6 @@ export {
|
|
|
1110
1141
|
modeStateFromResponse,
|
|
1111
1142
|
claudePreToolUseOutput,
|
|
1112
1143
|
claudePermissionRequestOutput,
|
|
1113
|
-
gateOutputFor
|
|
1144
|
+
gateOutputFor,
|
|
1145
|
+
renderElicitationOutput
|
|
1114
1146
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/claude-tools.ts
|
|
2
|
+
var PRETOOLUSE_GATED_TOOLS = [
|
|
3
|
+
"Bash",
|
|
4
|
+
"Write",
|
|
5
|
+
"Edit",
|
|
6
|
+
"MultiEdit",
|
|
7
|
+
"NotebookEdit",
|
|
8
|
+
"PowerShell",
|
|
9
|
+
"Monitor"
|
|
10
|
+
];
|
|
11
|
+
var PRETOOLUSE_PHONE_ANSWERED_TOOLS = ["AskUserQuestion", "ExitPlanMode"];
|
|
12
|
+
var POSTTOOLUSE_MIRRORED_TOOLS = [...PRETOOLUSE_GATED_TOOLS, "TodoWrite"];
|
|
13
|
+
var PRETOOLUSE_HANDLED_TOOLS = /* @__PURE__ */ new Set([...PRETOOLUSE_GATED_TOOLS, ...PRETOOLUSE_PHONE_ANSWERED_TOOLS]);
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
PRETOOLUSE_GATED_TOOLS,
|
|
17
|
+
PRETOOLUSE_PHONE_ANSWERED_TOOLS,
|
|
18
|
+
PRETOOLUSE_HANDLED_TOOLS
|
|
19
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
HOOK_BUDGETS
|
|
3
|
-
|
|
2
|
+
HOOK_BUDGETS,
|
|
3
|
+
HOOK_LOCATOR_BINARY
|
|
4
|
+
} from "./chunk-7YJS2VTG.js";
|
|
4
5
|
|
|
5
6
|
// src/codex-config.ts
|
|
6
7
|
import { createHash } from "crypto";
|
|
@@ -60,10 +61,13 @@ var readCodexMcpAuth = (config) => {
|
|
|
60
61
|
if (typeof pushary.bearer_token === "string") return { method: "legacy-bearer" };
|
|
61
62
|
return void 0;
|
|
62
63
|
};
|
|
64
|
+
var isPusharyCommand = (hook) => {
|
|
65
|
+
const command = String(asRecord(hook)?.command ?? "");
|
|
66
|
+
return command.includes(CODEX_HOOK_BINARY) || command.includes(HOOK_LOCATOR_BINARY);
|
|
67
|
+
};
|
|
63
68
|
var isPusharyCodexHook = (entry) => {
|
|
64
69
|
const hooks = asRecord(entry)?.hooks;
|
|
65
|
-
|
|
66
|
-
return hooks.some((hook) => String(asRecord(hook)?.command ?? "").includes(CODEX_HOOK_BINARY));
|
|
70
|
+
return Array.isArray(hooks) && hooks.some(isPusharyCommand);
|
|
67
71
|
};
|
|
68
72
|
var addCodexHooks = (config, command) => {
|
|
69
73
|
const hooks = ensureRecord(config, "hooks");
|
|
@@ -130,13 +134,28 @@ var codexHookTrustHash = (definition, command) => {
|
|
|
130
134
|
if (definition.matcher) identity.matcher = definition.matcher;
|
|
131
135
|
return "sha256:" + createHash("sha256").update(canonicalJson(identity), "utf8").digest("hex");
|
|
132
136
|
};
|
|
133
|
-
var
|
|
134
|
-
|
|
137
|
+
var codexHookPositions = (hooksConfig) => {
|
|
138
|
+
const hooks = asRecord(hooksConfig?.hooks);
|
|
139
|
+
const positions = {};
|
|
140
|
+
for (const definition of CODEX_HOOK_EVENTS) {
|
|
141
|
+
const entries = hooks?.[definition.event];
|
|
142
|
+
if (!Array.isArray(entries)) continue;
|
|
143
|
+
const entryIndex = entries.findIndex(isPusharyCodexHook);
|
|
144
|
+
if (entryIndex < 0) continue;
|
|
145
|
+
const inner = asRecord(entries[entryIndex])?.hooks;
|
|
146
|
+
const hookIndex = Array.isArray(inner) ? inner.findIndex(isPusharyCommand) : -1;
|
|
147
|
+
positions[definition.event] = [entryIndex, Math.max(hookIndex, 0)];
|
|
148
|
+
}
|
|
149
|
+
return positions;
|
|
150
|
+
};
|
|
151
|
+
var codexHookStateKey = (hooksJsonPath, event, position) => `${hooksJsonPath}:${CODEX_EVENT_KEY[event]}:${position[0]}:${position[1]}`;
|
|
152
|
+
var untrustedCodexHookEvents = (config, hooksJsonPath, command, positions) => {
|
|
135
153
|
const state = asRecord(asRecord(config.hooks)?.state);
|
|
136
154
|
return CODEX_HOOK_EVENTS.filter((definition) => {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
155
|
+
const position = positions[definition.event];
|
|
156
|
+
if (!position) return false;
|
|
157
|
+
const entry = asRecord(state?.[codexHookStateKey(hooksJsonPath, definition.event, position)]);
|
|
158
|
+
return entry?.trusted_hash !== codexHookTrustHash(definition, command);
|
|
140
159
|
}).map((definition) => definition.event);
|
|
141
160
|
};
|
|
142
161
|
var removeCodexMcpServer = (config) => {
|
|
@@ -146,12 +165,14 @@ var removeCodexMcpServer = (config) => {
|
|
|
146
165
|
if (Object.keys(servers).length === 0) delete config.mcp_servers;
|
|
147
166
|
return true;
|
|
148
167
|
};
|
|
149
|
-
var removeCodexHookTrust = (config, hooksJsonPath) => {
|
|
168
|
+
var removeCodexHookTrust = (config, hooksJsonPath, positions) => {
|
|
150
169
|
const state = asRecord(asRecord(config.hooks)?.state);
|
|
151
170
|
if (!state) return false;
|
|
152
171
|
let changed = false;
|
|
153
172
|
for (const definition of CODEX_HOOK_EVENTS) {
|
|
154
|
-
const
|
|
173
|
+
const position = positions[definition.event];
|
|
174
|
+
if (!position) continue;
|
|
175
|
+
const key = codexHookStateKey(hooksJsonPath, definition.event, position);
|
|
155
176
|
if (key in state) {
|
|
156
177
|
delete state[key];
|
|
157
178
|
changed = true;
|
|
@@ -166,16 +187,18 @@ var removeCodexHookTrust = (config, hooksJsonPath) => {
|
|
|
166
187
|
}
|
|
167
188
|
return changed;
|
|
168
189
|
};
|
|
169
|
-
var removeCodexSettings = (config, hooksJsonPath) => {
|
|
190
|
+
var removeCodexSettings = (config, hooksJsonPath, positions) => {
|
|
170
191
|
const mcp = removeCodexMcpServer(config);
|
|
171
|
-
const trust = removeCodexHookTrust(config, hooksJsonPath);
|
|
192
|
+
const trust = removeCodexHookTrust(config, hooksJsonPath, positions);
|
|
172
193
|
return mcp || trust;
|
|
173
194
|
};
|
|
174
|
-
var addCodexHookTrust = (config, hooksJsonPath, command) => {
|
|
195
|
+
var addCodexHookTrust = (config, hooksJsonPath, command, positions) => {
|
|
175
196
|
const hooks = ensureRecord(config, "hooks");
|
|
176
197
|
const state = ensureRecord(hooks, "state");
|
|
177
198
|
for (const definition of CODEX_HOOK_EVENTS) {
|
|
178
|
-
const
|
|
199
|
+
const position = positions[definition.event];
|
|
200
|
+
if (!position) continue;
|
|
201
|
+
const key = codexHookStateKey(hooksJsonPath, definition.event, position);
|
|
179
202
|
const existing = asRecord(state[key]) ?? {};
|
|
180
203
|
state[key] = { ...existing, trusted_hash: codexHookTrustHash(definition, command) };
|
|
181
204
|
}
|
|
@@ -214,6 +237,7 @@ export {
|
|
|
214
237
|
removeCodexHooks,
|
|
215
238
|
hasCodexHooks,
|
|
216
239
|
missingCodexHookEvents,
|
|
240
|
+
codexHookPositions,
|
|
217
241
|
untrustedCodexHookEvents,
|
|
218
242
|
removeCodexSettings,
|
|
219
243
|
addCodexHookTrust,
|