@pushary/agent-hooks 0.86.0 → 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/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 +6 -6
- 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 +22 -8
- 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 +6 -5
- 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 +6 -5
- package/dist/bin/pushary-permission-hook.js +6 -5
- 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 +19 -15
- 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 +8 -7
- package/dist/bin/pushary-wait.js +3 -3
- package/dist/{chunk-5EUZYWID.js → chunk-2T3GX7WG.js} +1 -1
- package/dist/{chunk-GK4CED6Z.js → chunk-5646VKR4.js} +7 -3
- package/dist/{chunk-MNQI6ZZU.js → chunk-7MBDFNUC.js} +1 -1
- package/dist/{chunk-CY4TZK5O.js → chunk-7YJS2VTG.js} +31 -4
- package/dist/{chunk-PZR4XMFU.js → chunk-A3PFIWWN.js} +1 -1
- package/dist/{chunk-2TZCZ7CL.js → chunk-A4I5JGCW.js} +1 -1
- package/dist/{chunk-VPJAAGD4.js → chunk-B3V2H6SA.js} +37 -17
- package/dist/{chunk-XPAGN3SC.js → chunk-ECEUMWBH.js} +1 -1
- package/dist/{chunk-2255DZ74.js → chunk-HAUTLCMA.js} +1 -1
- package/dist/{chunk-S3UD7O35.js → chunk-HJ44HIUW.js} +12 -28
- package/dist/{chunk-QW27ZFA4.js → chunk-IWL5LWIE.js} +1 -1
- package/dist/chunk-J3YDT4HM.js +128 -0
- package/dist/{chunk-N52CIK47.js → chunk-JAICP7BA.js} +1 -1
- package/dist/{chunk-HSGEEBBL.js → chunk-M7RYIZX6.js} +3 -3
- package/dist/{chunk-7G5VO76N.js → chunk-OT4YD54Q.js} +1 -1
- package/dist/{chunk-VZNDR3Z7.js → chunk-QBWYNVKY.js} +1 -1
- package/dist/{chunk-MTKR4YLW.js → chunk-SJVLFIYP.js} +1 -1
- package/dist/{chunk-33T5OOKP.js → chunk-V2XPF77V.js} +96 -161
- package/dist/{chunk-FOY5FISQ.js → chunk-WLLBFDVY.js} +1 -1
- package/dist/{chunk-Q7N3XGWM.js → chunk-XW5CHAQX.js} +2 -2
- package/dist/{chunk-7C5CJC3H.js → chunk-Y3UTTFTZ.js} +1 -1
- package/dist/{chunk-2C6B6V2U.js → chunk-ZZE6FN7T.js} +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +10 -8
- package/package.json +3 -1
|
@@ -1,25 +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
16
|
import {
|
|
17
17
|
addClaudeMcpServer,
|
|
18
18
|
addPusharyHooks,
|
|
19
19
|
addPusharyToolPermissions,
|
|
20
20
|
compareVersion,
|
|
21
21
|
parseVersion
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-5646VKR4.js";
|
|
23
23
|
import {
|
|
24
24
|
describeDetection,
|
|
25
25
|
detectAllAgents,
|
|
@@ -31,17 +31,17 @@ import {
|
|
|
31
31
|
shortenHome,
|
|
32
32
|
vscodeSettingsTargets,
|
|
33
33
|
writeInstructionBlock
|
|
34
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-IWL5LWIE.js";
|
|
35
35
|
import {
|
|
36
36
|
GEMINI_HOOK_BINARY,
|
|
37
37
|
addGeminiHooks,
|
|
38
38
|
addGeminiMcpServer
|
|
39
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-ZZE6FN7T.js";
|
|
40
40
|
import "../chunk-ATBKJNWS.js";
|
|
41
41
|
import {
|
|
42
42
|
guardBinary,
|
|
43
43
|
guardNodeScript
|
|
44
|
-
} from "../chunk-
|
|
44
|
+
} from "../chunk-M7RYIZX6.js";
|
|
45
45
|
import "../chunk-XHKBHWLX.js";
|
|
46
46
|
import {
|
|
47
47
|
installGlobally,
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
codexAgentsMd2 as codexAgentsMd,
|
|
60
60
|
codexConfigToml,
|
|
61
61
|
codexHome,
|
|
62
|
+
codexHookPositions,
|
|
62
63
|
codexSkillDir2 as codexSkillDir,
|
|
63
64
|
cursorPluginDir,
|
|
64
65
|
cursorUserHooks,
|
|
@@ -66,10 +67,11 @@ import {
|
|
|
66
67
|
geminiSettings,
|
|
67
68
|
pusharyConfigFile,
|
|
68
69
|
vscodePluginDir
|
|
69
|
-
} from "../chunk-
|
|
70
|
+
} from "../chunk-B3V2H6SA.js";
|
|
70
71
|
import {
|
|
71
72
|
reportEvent
|
|
72
|
-
} from "../chunk-
|
|
73
|
+
} from "../chunk-V2XPF77V.js";
|
|
74
|
+
import "../chunk-J3YDT4HM.js";
|
|
73
75
|
import "../chunk-RN3NOEJF.js";
|
|
74
76
|
import {
|
|
75
77
|
confirmAppConnection,
|
|
@@ -79,12 +81,12 @@ import {
|
|
|
79
81
|
printConnectInstructions,
|
|
80
82
|
setHumanStream,
|
|
81
83
|
verifyRoundTrip
|
|
82
|
-
} from "../chunk-
|
|
84
|
+
} from "../chunk-A3PFIWWN.js";
|
|
83
85
|
import "../chunk-3EGEA4KH.js";
|
|
84
86
|
import {
|
|
85
87
|
checkApiKey,
|
|
86
88
|
describeKeyCheck
|
|
87
|
-
} from "../chunk-
|
|
89
|
+
} from "../chunk-A4I5JGCW.js";
|
|
88
90
|
import {
|
|
89
91
|
useColor
|
|
90
92
|
} from "../chunk-5RUIFDTP.js";
|
|
@@ -95,7 +97,7 @@ import {
|
|
|
95
97
|
readConfigFileKey,
|
|
96
98
|
readKeySource,
|
|
97
99
|
writeKey
|
|
98
|
-
} from "../chunk-
|
|
100
|
+
} from "../chunk-OT4YD54Q.js";
|
|
99
101
|
import {
|
|
100
102
|
parseFlags
|
|
101
103
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -118,7 +120,7 @@ import {
|
|
|
118
120
|
} from "../chunk-6MTNS63X.js";
|
|
119
121
|
import "../chunk-BSZYIAZL.js";
|
|
120
122
|
import "../chunk-SAF6HGAA.js";
|
|
121
|
-
import "../chunk-
|
|
123
|
+
import "../chunk-Y3UTTFTZ.js";
|
|
122
124
|
import {
|
|
123
125
|
UsageError
|
|
124
126
|
} from "../chunk-7QLSKOSU.js";
|
|
@@ -128,7 +130,7 @@ import {
|
|
|
128
130
|
import "../chunk-2UMNXADU.js";
|
|
129
131
|
import {
|
|
130
132
|
isValidApiKey
|
|
131
|
-
} from "../chunk-
|
|
133
|
+
} from "../chunk-7YJS2VTG.js";
|
|
132
134
|
|
|
133
135
|
// bin/pushary-setup.ts
|
|
134
136
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, rmSync, renameSync, realpathSync, readdirSync, statSync } from "fs";
|
|
@@ -941,10 +943,12 @@ var setupCodex = async (apiKey) => {
|
|
|
941
943
|
let trusted = false;
|
|
942
944
|
if (hooksSupported) {
|
|
943
945
|
const hookCommand = guardBinary(resolveGlobalBinary("pushary-codex-hook") ?? "pushary-codex-hook");
|
|
946
|
+
let hookPositions = {};
|
|
944
947
|
await spinner("Adding native hooks (~/.codex/hooks.json)", async () => {
|
|
945
948
|
const hooksConfig = readAgentJson(CODEX_HOOKS_JSON);
|
|
946
949
|
addCodexHooks(hooksConfig, hookCommand);
|
|
947
950
|
writeJson(CODEX_HOOKS_JSON, hooksConfig);
|
|
951
|
+
hookPositions = codexHookPositions(hooksConfig);
|
|
948
952
|
});
|
|
949
953
|
if (trustAuto) {
|
|
950
954
|
await spinner("Trusting the Pushary hook (skips the /hooks step)", async () => {
|
|
@@ -954,7 +958,7 @@ var setupCodex = async (apiKey) => {
|
|
|
954
958
|
} catch {
|
|
955
959
|
}
|
|
956
960
|
const config = raw ? parseTOML(raw) : {};
|
|
957
|
-
addCodexHookTrust(config, CODEX_HOOKS_JSON, hookCommand);
|
|
961
|
+
addCodexHookTrust(config, CODEX_HOOKS_JSON, hookCommand, hookPositions);
|
|
958
962
|
writeFileSync(codexConfig, stringifyTOML(config), "utf-8");
|
|
959
963
|
trusted = true;
|
|
960
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,22 +1,22 @@
|
|
|
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
|
addClaudeMcpServer,
|
|
7
7
|
addPusharyHooks,
|
|
8
8
|
addPusharyToolPermissions
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-5646VKR4.js";
|
|
10
10
|
import {
|
|
11
11
|
GEMINI_HOOK_BINARY,
|
|
12
12
|
addGeminiHooks,
|
|
13
13
|
addGeminiMcpServer,
|
|
14
14
|
hasGeminiHooks
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-ZZE6FN7T.js";
|
|
16
16
|
import "../chunk-ATBKJNWS.js";
|
|
17
17
|
import {
|
|
18
18
|
guardBinary
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-M7RYIZX6.js";
|
|
20
20
|
import {
|
|
21
21
|
execNpm,
|
|
22
22
|
npmErrorMessage,
|
|
@@ -30,13 +30,14 @@ import {
|
|
|
30
30
|
addCodexMcpServer,
|
|
31
31
|
claudeJson,
|
|
32
32
|
codexConfigToml,
|
|
33
|
+
codexHookPositions,
|
|
33
34
|
codexHooksJson,
|
|
34
35
|
cursorPluginDir,
|
|
35
36
|
geminiSettings,
|
|
36
37
|
hasCodexHooks,
|
|
37
38
|
vscodePluginDir,
|
|
38
39
|
vscodePluginMcp
|
|
39
|
-
} from "../chunk-
|
|
40
|
+
} from "../chunk-B3V2H6SA.js";
|
|
40
41
|
import {
|
|
41
42
|
exitOnHelpFlag
|
|
42
43
|
} from "../chunk-SQOFGPNX.js";
|
|
@@ -51,7 +52,7 @@ import "../chunk-KZERVKTD.js";
|
|
|
51
52
|
import {
|
|
52
53
|
getApiKey
|
|
53
54
|
} from "../chunk-2UMNXADU.js";
|
|
54
|
-
import "../chunk-
|
|
55
|
+
import "../chunk-7YJS2VTG.js";
|
|
55
56
|
|
|
56
57
|
// bin/pushary-upgrade.ts
|
|
57
58
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -138,7 +139,7 @@ var reapplyCodexSettings = (apiKey, paths = {}) => {
|
|
|
138
139
|
}
|
|
139
140
|
if (config != null) {
|
|
140
141
|
try {
|
|
141
|
-
if (hooks) addCodexHookTrust(config, hooksPath, command);
|
|
142
|
+
if (hooks) addCodexHookTrust(config, hooksPath, command, codexHookPositions(hooksConfig ?? void 0));
|
|
142
143
|
if (apiKey) {
|
|
143
144
|
addCodexMcpServer(config, apiKey);
|
|
144
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");
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
} from "./chunk-ATBKJNWS.js";
|
|
5
5
|
import {
|
|
6
6
|
guardBinary
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-M7RYIZX6.js";
|
|
8
8
|
import {
|
|
9
9
|
HOOK_BUDGETS,
|
|
10
10
|
HOOK_LOCATOR_BINARY
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-7YJS2VTG.js";
|
|
12
12
|
|
|
13
13
|
// src/claude-config.ts
|
|
14
14
|
import { join } from "path";
|
|
@@ -48,7 +48,11 @@ var CLAUDE_HOOK_EVENTS = [
|
|
|
48
48
|
{ event: "SubagentStop", binary: "pushary-stop-hook", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
49
49
|
{ event: "PreCompact", binary: "pushary-post-hook", matcher: "manual|auto", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
50
50
|
{ event: "PostCompact", binary: "pushary-post-hook", matcher: "manual|auto", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
51
|
-
{ 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 }
|
|
52
56
|
];
|
|
53
57
|
var supportedClaudeEvents = (version) => CLAUDE_HOOK_EVENTS.filter((hook) => version ? atLeast(version, hook.since) : hook.since === ESTABLISHED);
|
|
54
58
|
|
|
@@ -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,18 @@ 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
|
+
};
|
|
68
81
|
var HOOK_LOCATOR_BINARY = "pushary-bridge";
|
|
69
82
|
var HOOK_BATCH_MAX_BYTES = 4 * 1024 * 1024;
|
|
70
83
|
var REPO_KEY_MAX_LENGTH = 200;
|
|
@@ -948,6 +961,7 @@ var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, se
|
|
|
948
961
|
pushFirstSeconds: config.defaultPushFirstSeconds ?? 20
|
|
949
962
|
};
|
|
950
963
|
const governedBySpecificRule = match?.rank === "exact" || match?.rank === "prefix";
|
|
964
|
+
const governingMode = base.mode;
|
|
951
965
|
if (!governedBySpecificRule && toolName === "Bash" && typeof arg === "string" && isSafeReadOnlyCommand(arg)) {
|
|
952
966
|
base = autoApprove(base.tool);
|
|
953
967
|
}
|
|
@@ -957,7 +971,7 @@ var resolvePolicy = (config, toolName, modeOverride, toolInput, cwd, repoKey, se
|
|
|
957
971
|
tool: base.tool,
|
|
958
972
|
timeoutSeconds: config.defaultTimeoutSeconds,
|
|
959
973
|
timeoutAction: "wait",
|
|
960
|
-
mode:
|
|
974
|
+
mode: governingMode,
|
|
961
975
|
pushFirstSeconds: config.defaultPushFirstSeconds ?? 20
|
|
962
976
|
};
|
|
963
977
|
}
|
|
@@ -1054,7 +1068,7 @@ var claudePermissionRequestOutput = (decision, reason, updatedInput) => ({
|
|
|
1054
1068
|
});
|
|
1055
1069
|
var gateOutputFor = (source, event, decision, reason) => {
|
|
1056
1070
|
let output;
|
|
1057
|
-
if (source === "claude") {
|
|
1071
|
+
if (source === "claude" || source === "vscode") {
|
|
1058
1072
|
if (event === "PreToolUse") {
|
|
1059
1073
|
output = claudePreToolUseOutput(decision, reason);
|
|
1060
1074
|
} else if (event === "PermissionRequest" && decision !== "ask") {
|
|
@@ -1088,6 +1102,17 @@ var gateOutputFor = (source, event, decision, reason) => {
|
|
|
1088
1102
|
}
|
|
1089
1103
|
return output;
|
|
1090
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;
|
|
1091
1116
|
|
|
1092
1117
|
export {
|
|
1093
1118
|
parseAgentQuestionAnswers,
|
|
@@ -1096,6 +1121,7 @@ export {
|
|
|
1096
1121
|
hookWaitDeadline,
|
|
1097
1122
|
hookWaitClamped,
|
|
1098
1123
|
effectiveWaitSeconds,
|
|
1124
|
+
AGENT_LABELS_BY_TYPE,
|
|
1099
1125
|
HOOK_LOCATOR_BINARY,
|
|
1100
1126
|
normalizeRepoRemote,
|
|
1101
1127
|
localRepoKey,
|
|
@@ -1115,5 +1141,6 @@ export {
|
|
|
1115
1141
|
modeStateFromResponse,
|
|
1116
1142
|
claudePreToolUseOutput,
|
|
1117
1143
|
claudePermissionRequestOutput,
|
|
1118
|
-
gateOutputFor
|
|
1144
|
+
gateOutputFor,
|
|
1145
|
+
renderElicitationOutput
|
|
1119
1146
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HOOK_BUDGETS,
|
|
3
3
|
HOOK_LOCATOR_BINARY
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7YJS2VTG.js";
|
|
5
5
|
|
|
6
6
|
// src/codex-config.ts
|
|
7
7
|
import { createHash } from "crypto";
|
|
@@ -61,13 +61,13 @@ var readCodexMcpAuth = (config) => {
|
|
|
61
61
|
if (typeof pushary.bearer_token === "string") return { method: "legacy-bearer" };
|
|
62
62
|
return void 0;
|
|
63
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
|
+
};
|
|
64
68
|
var isPusharyCodexHook = (entry) => {
|
|
65
69
|
const hooks = asRecord(entry)?.hooks;
|
|
66
|
-
|
|
67
|
-
return hooks.some((hook) => {
|
|
68
|
-
const command = String(asRecord(hook)?.command ?? "");
|
|
69
|
-
return command.includes(CODEX_HOOK_BINARY) || command.includes(HOOK_LOCATOR_BINARY);
|
|
70
|
-
});
|
|
70
|
+
return Array.isArray(hooks) && hooks.some(isPusharyCommand);
|
|
71
71
|
};
|
|
72
72
|
var addCodexHooks = (config, command) => {
|
|
73
73
|
const hooks = ensureRecord(config, "hooks");
|
|
@@ -134,13 +134,28 @@ var codexHookTrustHash = (definition, command) => {
|
|
|
134
134
|
if (definition.matcher) identity.matcher = definition.matcher;
|
|
135
135
|
return "sha256:" + createHash("sha256").update(canonicalJson(identity), "utf8").digest("hex");
|
|
136
136
|
};
|
|
137
|
-
var
|
|
138
|
-
|
|
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) => {
|
|
139
153
|
const state = asRecord(asRecord(config.hooks)?.state);
|
|
140
154
|
return CODEX_HOOK_EVENTS.filter((definition) => {
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
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);
|
|
144
159
|
}).map((definition) => definition.event);
|
|
145
160
|
};
|
|
146
161
|
var removeCodexMcpServer = (config) => {
|
|
@@ -150,12 +165,14 @@ var removeCodexMcpServer = (config) => {
|
|
|
150
165
|
if (Object.keys(servers).length === 0) delete config.mcp_servers;
|
|
151
166
|
return true;
|
|
152
167
|
};
|
|
153
|
-
var removeCodexHookTrust = (config, hooksJsonPath) => {
|
|
168
|
+
var removeCodexHookTrust = (config, hooksJsonPath, positions) => {
|
|
154
169
|
const state = asRecord(asRecord(config.hooks)?.state);
|
|
155
170
|
if (!state) return false;
|
|
156
171
|
let changed = false;
|
|
157
172
|
for (const definition of CODEX_HOOK_EVENTS) {
|
|
158
|
-
const
|
|
173
|
+
const position = positions[definition.event];
|
|
174
|
+
if (!position) continue;
|
|
175
|
+
const key = codexHookStateKey(hooksJsonPath, definition.event, position);
|
|
159
176
|
if (key in state) {
|
|
160
177
|
delete state[key];
|
|
161
178
|
changed = true;
|
|
@@ -170,16 +187,18 @@ var removeCodexHookTrust = (config, hooksJsonPath) => {
|
|
|
170
187
|
}
|
|
171
188
|
return changed;
|
|
172
189
|
};
|
|
173
|
-
var removeCodexSettings = (config, hooksJsonPath) => {
|
|
190
|
+
var removeCodexSettings = (config, hooksJsonPath, positions) => {
|
|
174
191
|
const mcp = removeCodexMcpServer(config);
|
|
175
|
-
const trust = removeCodexHookTrust(config, hooksJsonPath);
|
|
192
|
+
const trust = removeCodexHookTrust(config, hooksJsonPath, positions);
|
|
176
193
|
return mcp || trust;
|
|
177
194
|
};
|
|
178
|
-
var addCodexHookTrust = (config, hooksJsonPath, command) => {
|
|
195
|
+
var addCodexHookTrust = (config, hooksJsonPath, command, positions) => {
|
|
179
196
|
const hooks = ensureRecord(config, "hooks");
|
|
180
197
|
const state = ensureRecord(hooks, "state");
|
|
181
198
|
for (const definition of CODEX_HOOK_EVENTS) {
|
|
182
|
-
const
|
|
199
|
+
const position = positions[definition.event];
|
|
200
|
+
if (!position) continue;
|
|
201
|
+
const key = codexHookStateKey(hooksJsonPath, definition.event, position);
|
|
183
202
|
const existing = asRecord(state[key]) ?? {};
|
|
184
203
|
state[key] = { ...existing, trusted_hash: codexHookTrustHash(definition, command) };
|
|
185
204
|
}
|
|
@@ -218,6 +237,7 @@ export {
|
|
|
218
237
|
removeCodexHooks,
|
|
219
238
|
hasCodexHooks,
|
|
220
239
|
missingCodexHookEvents,
|
|
240
|
+
codexHookPositions,
|
|
221
241
|
untrustedCodexHookEvents,
|
|
222
242
|
removeCodexSettings,
|
|
223
243
|
addCodexHookTrust,
|
|
@@ -5,15 +5,12 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
isGatingMoment,
|
|
7
7
|
recordKeylessMoment
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-7MBDFNUC.js";
|
|
9
9
|
import {
|
|
10
10
|
denyReasonFrom,
|
|
11
11
|
isDeferAnswer
|
|
12
12
|
} from "./chunk-YHG74UFF.js";
|
|
13
13
|
import {
|
|
14
|
-
DEFAULT_SESSION,
|
|
15
|
-
askUser,
|
|
16
|
-
cancelQuestion,
|
|
17
14
|
deriveAction,
|
|
18
15
|
deriveActionBody,
|
|
19
16
|
deriveBlocker,
|
|
@@ -24,12 +21,17 @@ import {
|
|
|
24
21
|
readLastPrompt,
|
|
25
22
|
readLastUserPrompt,
|
|
26
23
|
repoKeyFor,
|
|
27
|
-
savePendingQuestion,
|
|
28
24
|
scopePathFor,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
throttlePass
|
|
26
|
+
} from "./chunk-V2XPF77V.js";
|
|
27
|
+
import {
|
|
28
|
+
DEFAULT_SESSION,
|
|
29
|
+
askUser,
|
|
30
|
+
cancelQuestion,
|
|
31
|
+
pollForAnswer,
|
|
32
|
+
savePendingQuestion,
|
|
33
|
+
sendNotification
|
|
34
|
+
} from "./chunk-J3YDT4HM.js";
|
|
33
35
|
import {
|
|
34
36
|
getMachineId
|
|
35
37
|
} from "./chunk-RN3NOEJF.js";
|
|
@@ -46,7 +48,7 @@ import {
|
|
|
46
48
|
hookWaitDeadline,
|
|
47
49
|
parseAgentQuestionAnswers,
|
|
48
50
|
resolveGate
|
|
49
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-7YJS2VTG.js";
|
|
50
52
|
|
|
51
53
|
// src/decision-episode.ts
|
|
52
54
|
var EPISODE_PATH = "/api/agent/decision-episode";
|
|
@@ -74,29 +76,11 @@ var reportDecisionEpisode = async (apiKey, input) => {
|
|
|
74
76
|
import { basename, join } from "path";
|
|
75
77
|
import { tmpdir } from "os";
|
|
76
78
|
import { existsSync, writeFileSync } from "fs";
|
|
77
|
-
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
78
79
|
var START_MS = Date.now();
|
|
79
80
|
var allow = () => claudePreToolUseOutput("allow");
|
|
80
81
|
var deny = (reason) => claudePreToolUseOutput("deny", reason);
|
|
81
82
|
var allowWithInput = (updatedInput) => claudePreToolUseOutput("allow", void 0, updatedInput);
|
|
82
83
|
var ask = (reason) => claudePreToolUseOutput("ask", reason);
|
|
83
|
-
var pollForAnswer = async (apiKey, correlationId, deadlineMs, pollInterval = 2e3) => {
|
|
84
|
-
while (Date.now() < deadlineMs) {
|
|
85
|
-
const remaining = Math.min(Math.max(deadlineMs - Date.now(), 1e3), 3e4);
|
|
86
|
-
let answer;
|
|
87
|
-
try {
|
|
88
|
-
answer = await waitForAnswer(apiKey, correlationId, remaining);
|
|
89
|
-
} catch {
|
|
90
|
-
if (Date.now() + pollInterval >= deadlineMs) break;
|
|
91
|
-
await sleep(pollInterval);
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
if (answer.answered) return answer;
|
|
95
|
-
if (Date.now() + pollInterval >= deadlineMs) break;
|
|
96
|
-
await sleep(pollInterval);
|
|
97
|
-
}
|
|
98
|
-
return { answered: false };
|
|
99
|
-
};
|
|
100
84
|
var handlePushOnly = async (apiKey, description, projectName, timeoutSeconds, timeoutAction, sessionId, machineId, toolName, toolTarget, decision, signals) => {
|
|
101
85
|
let result;
|
|
102
86
|
try {
|