@pushary/agent-hooks 0.32.1 → 0.33.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-claude.d.ts +1 -0
- package/dist/bin/pushary-claude.js +175 -0
- package/dist/bin/pushary-clean.js +1 -1
- package/dist/bin/pushary-codex-hook.js +5 -5
- package/dist/bin/pushary-codex.js +1 -1
- package/dist/bin/pushary-gemini-hook.js +5 -5
- package/dist/bin/pushary-hook.js +2 -2
- package/dist/bin/pushary-notification-hook.js +1 -1
- package/dist/bin/pushary-post-hook.js +1 -1
- package/dist/bin/pushary-prompt-hook.js +1 -1
- package/dist/bin/pushary-session-start-hook.d.ts +1 -0
- package/dist/bin/pushary-session-start-hook.js +21 -0
- package/dist/bin/pushary-setup.js +2 -2
- package/dist/bin/pushary-stop-hook.js +1 -1
- package/dist/bin/pushary.js +3 -0
- package/dist/{chunk-M6YUEVRV.js → chunk-AV2F2ZTZ.js} +13 -3
- package/dist/{chunk-USRIQPWI.js → chunk-OCPDWNG2.js} +37 -2
- package/dist/{chunk-FD4NV6BO.js → chunk-UU3ETDK4.js} +5 -5
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +3 -3
- package/package.json +4 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getApiKey
|
|
4
|
+
} from "../chunk-NKXSILEW.js";
|
|
5
|
+
|
|
6
|
+
// src/wrapper/claudeBinary.ts
|
|
7
|
+
import { statSync } from "fs";
|
|
8
|
+
import { join, delimiter } from "path";
|
|
9
|
+
var WRAPPER_ACTIVE_ENV = "PUSHARY_WRAPPER_ACTIVE";
|
|
10
|
+
var isFile = (path) => {
|
|
11
|
+
try {
|
|
12
|
+
return statSync(path).isFile();
|
|
13
|
+
} catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var findClaudeBinary = () => {
|
|
18
|
+
const override = process.env.PUSHARY_CLAUDE_BIN?.trim();
|
|
19
|
+
if (override) return isFile(override) ? override : null;
|
|
20
|
+
const pathVar = process.env.PATH ?? "";
|
|
21
|
+
const exts = process.platform === "win32" ? [".cmd", ".exe", ".bat", ""] : [""];
|
|
22
|
+
for (const dir of pathVar.split(delimiter)) {
|
|
23
|
+
if (!dir) continue;
|
|
24
|
+
for (const ext of exts) {
|
|
25
|
+
const candidate = join(dir, `claude${ext}`);
|
|
26
|
+
if (isFile(candidate)) return candidate;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// src/wrapper/localPassthrough.ts
|
|
33
|
+
import { spawn } from "child_process";
|
|
34
|
+
var SIGNAL_NUMBERS = {
|
|
35
|
+
SIGHUP: 1,
|
|
36
|
+
SIGINT: 2,
|
|
37
|
+
SIGQUIT: 3,
|
|
38
|
+
SIGKILL: 9,
|
|
39
|
+
SIGTERM: 15
|
|
40
|
+
};
|
|
41
|
+
var FORWARDED_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
42
|
+
var runLocalPassthrough = (binary, args2) => {
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
let child;
|
|
45
|
+
try {
|
|
46
|
+
child = spawn(binary, args2, {
|
|
47
|
+
stdio: "inherit",
|
|
48
|
+
env: { ...process.env, [WRAPPER_ACTIVE_ENV]: "1" }
|
|
49
|
+
});
|
|
50
|
+
} catch {
|
|
51
|
+
resolve(127);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const forward = (signal) => {
|
|
55
|
+
try {
|
|
56
|
+
child.kill(signal);
|
|
57
|
+
} catch {
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
for (const signal of FORWARDED_SIGNALS) process.on(signal, forward);
|
|
61
|
+
const cleanup = () => {
|
|
62
|
+
for (const signal of FORWARDED_SIGNALS) process.off(signal, forward);
|
|
63
|
+
};
|
|
64
|
+
child.on("error", () => {
|
|
65
|
+
cleanup();
|
|
66
|
+
resolve(127);
|
|
67
|
+
});
|
|
68
|
+
child.on("exit", (code, signal) => {
|
|
69
|
+
cleanup();
|
|
70
|
+
if (typeof code === "number") resolve(code);
|
|
71
|
+
else if (signal) resolve(128 + (SIGNAL_NUMBERS[signal] ?? 0));
|
|
72
|
+
else resolve(0);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// src/wrapper/commandPoller.ts
|
|
78
|
+
var FAST_POLL_MS = 2e3;
|
|
79
|
+
var SLOW_POLL_MS = 3e4;
|
|
80
|
+
var isEnabled = () => {
|
|
81
|
+
const flag = process.env.PUSHARY_WRAPPER_POLL;
|
|
82
|
+
return flag === "1" || flag === "true";
|
|
83
|
+
};
|
|
84
|
+
var startCommandPoller = (opts) => {
|
|
85
|
+
let stopped = false;
|
|
86
|
+
let timer;
|
|
87
|
+
if (!isEnabled()) return { stop() {
|
|
88
|
+
} };
|
|
89
|
+
try {
|
|
90
|
+
getApiKey();
|
|
91
|
+
} catch {
|
|
92
|
+
return { stop() {
|
|
93
|
+
} };
|
|
94
|
+
}
|
|
95
|
+
const schedule = (delayMs) => {
|
|
96
|
+
if (stopped) return;
|
|
97
|
+
timer = setTimeout(tick, delayMs);
|
|
98
|
+
};
|
|
99
|
+
const tick = async () => {
|
|
100
|
+
if (stopped) return;
|
|
101
|
+
let next = SLOW_POLL_MS;
|
|
102
|
+
try {
|
|
103
|
+
const command = await drainPendingCommand(opts.sessionId);
|
|
104
|
+
if (command) {
|
|
105
|
+
next = FAST_POLL_MS;
|
|
106
|
+
opts.onCommand(command);
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
110
|
+
schedule(next);
|
|
111
|
+
};
|
|
112
|
+
opts.log?.("[pushary] wrapper command poller enabled (experimental)");
|
|
113
|
+
schedule(SLOW_POLL_MS);
|
|
114
|
+
return {
|
|
115
|
+
stop() {
|
|
116
|
+
stopped = true;
|
|
117
|
+
if (timer) clearTimeout(timer);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
var drainPendingCommand = async (_sessionId) => {
|
|
122
|
+
return null;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// src/wrapper/remoteMode.ts
|
|
126
|
+
var runRemoteMode = async (_binary, _args) => {
|
|
127
|
+
return { implemented: false };
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/wrapper/runClaudeWrapper.ts
|
|
131
|
+
var runClaudeWrapper = async (args2) => {
|
|
132
|
+
const binary = findClaudeBinary();
|
|
133
|
+
if (!binary) {
|
|
134
|
+
process.stderr.write(
|
|
135
|
+
"[pushary] Could not find the `claude` binary on your PATH. Install Claude Code, or set PUSHARY_CLAUDE_BIN to its full path.\n"
|
|
136
|
+
);
|
|
137
|
+
return 127;
|
|
138
|
+
}
|
|
139
|
+
const nested = process.env[WRAPPER_ACTIVE_ENV] === "1";
|
|
140
|
+
if (!nested && process.env.PUSHARY_WRAPPER_REMOTE === "1") {
|
|
141
|
+
try {
|
|
142
|
+
const remote = await runRemoteMode(binary, args2);
|
|
143
|
+
if (remote.implemented) return remote.exitCode ?? 0;
|
|
144
|
+
} catch {
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const poller = nested ? { stop() {
|
|
148
|
+
} } : startCommandPoller({
|
|
149
|
+
onCommand: () => {
|
|
150
|
+
},
|
|
151
|
+
log: (m) => process.stderr.write(`${m}
|
|
152
|
+
`)
|
|
153
|
+
});
|
|
154
|
+
try {
|
|
155
|
+
return await runLocalPassthrough(binary, args2);
|
|
156
|
+
} finally {
|
|
157
|
+
poller.stop();
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// src/wrapper/args.ts
|
|
162
|
+
var resolveClaudeArgs = (argv) => {
|
|
163
|
+
const rest = argv.slice(2);
|
|
164
|
+
return rest[0] === "claude" ? rest.slice(1) : rest;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// bin/pushary-claude.ts
|
|
168
|
+
var args = resolveClaudeArgs(process.argv);
|
|
169
|
+
runClaudeWrapper(args).then((code) => process.exit(code)).catch((err) => {
|
|
170
|
+
process.stderr.write(
|
|
171
|
+
`[pushary] wrapper error: ${err instanceof Error ? err.message : String(err)}
|
|
172
|
+
`
|
|
173
|
+
);
|
|
174
|
+
process.exit(1);
|
|
175
|
+
});
|
|
@@ -3,10 +3,6 @@ import {
|
|
|
3
3
|
denyReasonFrom,
|
|
4
4
|
isDeferAnswer
|
|
5
5
|
} from "../chunk-KQYIHZ5E.js";
|
|
6
|
-
import {
|
|
7
|
-
isGatingMoment,
|
|
8
|
-
recordKeylessMoment
|
|
9
|
-
} from "../chunk-R5AJNXZS.js";
|
|
10
6
|
import {
|
|
11
7
|
CODEX_AGENT,
|
|
12
8
|
DEFAULT_SESSION,
|
|
@@ -36,7 +32,11 @@ import {
|
|
|
36
32
|
toCodexWire,
|
|
37
33
|
toPolicyLookup,
|
|
38
34
|
waitForAnswer
|
|
39
|
-
} from "../chunk-
|
|
35
|
+
} from "../chunk-OCPDWNG2.js";
|
|
36
|
+
import {
|
|
37
|
+
isGatingMoment,
|
|
38
|
+
recordKeylessMoment
|
|
39
|
+
} from "../chunk-R5AJNXZS.js";
|
|
40
40
|
import "../chunk-DWED7BS3.js";
|
|
41
41
|
import {
|
|
42
42
|
DECISION_LINE_MAX,
|
|
@@ -3,10 +3,6 @@ import {
|
|
|
3
3
|
denyReasonFrom,
|
|
4
4
|
isDeferAnswer
|
|
5
5
|
} from "../chunk-KQYIHZ5E.js";
|
|
6
|
-
import {
|
|
7
|
-
isGatingMoment,
|
|
8
|
-
recordKeylessMoment
|
|
9
|
-
} from "../chunk-R5AJNXZS.js";
|
|
10
6
|
import {
|
|
11
7
|
DEFAULT_SESSION,
|
|
12
8
|
askUser,
|
|
@@ -28,7 +24,11 @@ import {
|
|
|
28
24
|
savePendingQuestion,
|
|
29
25
|
sendNotification,
|
|
30
26
|
waitForAnswer
|
|
31
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-OCPDWNG2.js";
|
|
28
|
+
import {
|
|
29
|
+
isGatingMoment,
|
|
30
|
+
recordKeylessMoment
|
|
31
|
+
} from "../chunk-R5AJNXZS.js";
|
|
32
32
|
import "../chunk-DWED7BS3.js";
|
|
33
33
|
import {
|
|
34
34
|
DECISION_LINE_MAX,
|
package/dist/bin/pushary-hook.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePreToolUse
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-UU3ETDK4.js";
|
|
5
5
|
import "../chunk-KQYIHZ5E.js";
|
|
6
|
+
import "../chunk-OCPDWNG2.js";
|
|
6
7
|
import "../chunk-R5AJNXZS.js";
|
|
7
|
-
import "../chunk-USRIQPWI.js";
|
|
8
8
|
import "../chunk-DWED7BS3.js";
|
|
9
9
|
import "../chunk-Z5PL3K7C.js";
|
|
10
10
|
import "../chunk-NKXSILEW.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
handleSessionStart
|
|
4
|
+
} from "../chunk-OCPDWNG2.js";
|
|
5
|
+
import "../chunk-DWED7BS3.js";
|
|
6
|
+
import "../chunk-Z5PL3K7C.js";
|
|
7
|
+
import "../chunk-NKXSILEW.js";
|
|
8
|
+
|
|
9
|
+
// bin/pushary-session-start-hook.ts
|
|
10
|
+
var main = async () => {
|
|
11
|
+
let rawInput = "";
|
|
12
|
+
for await (const chunk of process.stdin) {
|
|
13
|
+
rawInput += chunk;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const input = rawInput.trim() ? JSON.parse(rawInput) : {};
|
|
17
|
+
await handleSessionStart(input);
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
main();
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
addClaudeMcpServer,
|
|
4
4
|
addPusharyHooks,
|
|
5
5
|
addPusharyToolPermissions
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-AV2F2ZTZ.js";
|
|
7
7
|
import {
|
|
8
8
|
GEMINI_HOOK_BINARY,
|
|
9
9
|
addCodexHookTrust,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "../chunk-J7JWI3KU.js";
|
|
25
25
|
import {
|
|
26
26
|
reportEvent
|
|
27
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-OCPDWNG2.js";
|
|
28
28
|
import "../chunk-DWED7BS3.js";
|
|
29
29
|
import {
|
|
30
30
|
isValidApiKey
|
package/dist/bin/pushary.js
CHANGED
|
@@ -18,12 +18,15 @@ if (command === "setup") {
|
|
|
18
18
|
await import("./pushary-stats.js");
|
|
19
19
|
} else if (command === "upgrade") {
|
|
20
20
|
await import("./pushary-upgrade.js");
|
|
21
|
+
} else if (command === "claude") {
|
|
22
|
+
await import("./pushary-claude.js");
|
|
21
23
|
} else {
|
|
22
24
|
console.log(`
|
|
23
25
|
Pushary Agent Hooks
|
|
24
26
|
|
|
25
27
|
Commands:
|
|
26
28
|
setup Configure Claude Code, Codex, Gemini CLI, Hermes, or Cursor with Pushary
|
|
29
|
+
claude Run Claude Code through Pushary (experimental wrapper; today a transparent passthrough)
|
|
27
30
|
doctor Verify your Pushary installation is working
|
|
28
31
|
clean Remove all Pushary configuration (--yes for non-interactive)
|
|
29
32
|
mode Switch approval mode (push_only, push_first, terminal_only)
|
|
@@ -20,7 +20,7 @@ var isPusharyHook = (entry) => {
|
|
|
20
20
|
if (!Array.isArray(hooks)) return false;
|
|
21
21
|
return hooks.some((hook) => {
|
|
22
22
|
const command = String(asRecord(hook)?.command ?? "");
|
|
23
|
-
return command.includes("pushary-hook") || command.includes("pushary-post-hook") || command.includes("pushary-stop-hook") || command.includes("pushary-prompt-hook") || command.includes("pushary-notification-hook");
|
|
23
|
+
return command.includes("pushary-hook") || command.includes("pushary-post-hook") || command.includes("pushary-stop-hook") || command.includes("pushary-prompt-hook") || command.includes("pushary-notification-hook") || command.includes("pushary-session-start-hook");
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
26
|
var addClaudeMcpServer = (config, apiKey) => {
|
|
@@ -77,7 +77,7 @@ var addPusharyHooks = (settings, binDir) => {
|
|
|
77
77
|
hooks.PreToolUse = preToolUse;
|
|
78
78
|
const postToolUse = (Array.isArray(hooks.PostToolUse) ? hooks.PostToolUse : []).filter((entry) => !isPusharyHook(entry));
|
|
79
79
|
postToolUse.push({
|
|
80
|
-
matcher: "Bash|Write|Edit|NotebookEdit",
|
|
80
|
+
matcher: "Bash|Write|Edit|NotebookEdit|TodoWrite",
|
|
81
81
|
hooks: [{
|
|
82
82
|
type: "command",
|
|
83
83
|
command: resolve("pushary-post-hook"),
|
|
@@ -113,6 +113,16 @@ var addPusharyHooks = (settings, binDir) => {
|
|
|
113
113
|
}]
|
|
114
114
|
});
|
|
115
115
|
hooks.Notification = notification;
|
|
116
|
+
const sessionStart = (Array.isArray(hooks.SessionStart) ? hooks.SessionStart : []).filter((entry) => !isPusharyHook(entry));
|
|
117
|
+
sessionStart.push({
|
|
118
|
+
matcher: "startup|resume|clear",
|
|
119
|
+
hooks: [{
|
|
120
|
+
type: "command",
|
|
121
|
+
command: resolve("pushary-session-start-hook"),
|
|
122
|
+
timeout: 10
|
|
123
|
+
}]
|
|
124
|
+
});
|
|
125
|
+
hooks.SessionStart = sessionStart;
|
|
116
126
|
};
|
|
117
127
|
var removePusharySettings = (settings) => {
|
|
118
128
|
let changed = removeClaudeMcpServers(settings);
|
|
@@ -131,7 +141,7 @@ var removePusharySettings = (settings) => {
|
|
|
131
141
|
}
|
|
132
142
|
const hooks = asRecord(settings.hooks);
|
|
133
143
|
if (hooks) {
|
|
134
|
-
for (const key of ["PreToolUse", "PostToolUse", "Stop", "UserPromptSubmit", "Notification"]) {
|
|
144
|
+
for (const key of ["PreToolUse", "PostToolUse", "Stop", "UserPromptSubmit", "Notification", "SessionStart"]) {
|
|
135
145
|
const entries = hooks[key];
|
|
136
146
|
if (!Array.isArray(entries)) continue;
|
|
137
147
|
const filtered = entries.filter((entry) => !isPusharyHook(entry));
|
|
@@ -194,11 +194,24 @@ var hookPrefixes = {
|
|
|
194
194
|
Edit: (input) => `edit file: ${input.file_path ?? "(unknown path)"}`,
|
|
195
195
|
Read: (input) => `read file: ${input.file_path ?? "(unknown path)"}`
|
|
196
196
|
};
|
|
197
|
+
var describeTodoProgress = (todos) => {
|
|
198
|
+
if (!Array.isArray(todos)) return "updated the plan";
|
|
199
|
+
const items = todos.filter((t) => !!t && typeof t === "object");
|
|
200
|
+
const total = items.length;
|
|
201
|
+
if (total === 0) return "updated the plan";
|
|
202
|
+
const done = items.filter((t) => t.status === "completed").length;
|
|
203
|
+
const current = items.find((t) => t.status === "in_progress");
|
|
204
|
+
const label = current ? [current.activeForm, current.content].find((v) => typeof v === "string" && v.trim().length > 0) : void 0;
|
|
205
|
+
if (done >= total) return `finished all ${total} tasks`;
|
|
206
|
+
if (label) return `${label.trim()} (${done}/${total} done)`;
|
|
207
|
+
return `${done}/${total} tasks done`;
|
|
208
|
+
};
|
|
197
209
|
var eventPrefixes = {
|
|
198
210
|
Bash: (input) => `ran: ${String(input.command ?? "")}`,
|
|
199
211
|
Write: (input) => `wrote: ${input.file_path ?? "unknown"}`,
|
|
200
212
|
Edit: (input) => `edited: ${input.file_path ?? "unknown"}`,
|
|
201
|
-
Read: (input) => `read: ${input.file_path ?? "unknown"}
|
|
213
|
+
Read: (input) => `read: ${input.file_path ?? "unknown"}`,
|
|
214
|
+
TodoWrite: (input) => describeTodoProgress(input.todos)
|
|
202
215
|
};
|
|
203
216
|
var EVENT_ACTION_MAX = 120;
|
|
204
217
|
var HOOK_FALLBACK_MAX = 200;
|
|
@@ -876,6 +889,13 @@ var handleUserPrompt = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
876
889
|
return void 0;
|
|
877
890
|
}
|
|
878
891
|
};
|
|
892
|
+
var STOP_SUMMARY_MAX_LENGTH = 200;
|
|
893
|
+
var summarizeFinalMessage = (message) => {
|
|
894
|
+
if (typeof message !== "string") return "Session ended";
|
|
895
|
+
const collapsed = message.replace(/\s+/g, " ").trim();
|
|
896
|
+
if (!collapsed) return "Session ended";
|
|
897
|
+
return collapsed.slice(0, STOP_SUMMARY_MAX_LENGTH);
|
|
898
|
+
};
|
|
879
899
|
var handleStop = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
880
900
|
try {
|
|
881
901
|
const projectName = basename(input.cwd ?? process.cwd());
|
|
@@ -889,7 +909,7 @@ var handleStop = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
889
909
|
event: "session_end",
|
|
890
910
|
agentType: agent.type,
|
|
891
911
|
agentName: `${agent.label} - ${projectName}`,
|
|
892
|
-
action:
|
|
912
|
+
action: summarizeFinalMessage(input.last_assistant_message),
|
|
893
913
|
sessionId: input.session_id,
|
|
894
914
|
usage: deriveUsage(input.transcript_path, input.session_id)
|
|
895
915
|
}, { maxAttempts: 1 })
|
|
@@ -912,6 +932,20 @@ var handleStop = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
|
912
932
|
return void 0;
|
|
913
933
|
}
|
|
914
934
|
};
|
|
935
|
+
var handleSessionStart = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
936
|
+
try {
|
|
937
|
+
const projectName = basename(input.cwd ?? process.cwd());
|
|
938
|
+
const action = input.source === "resume" ? "Session resumed" : "Session started";
|
|
939
|
+
await reportEvent({
|
|
940
|
+
event: "session_start",
|
|
941
|
+
agentType: agent.type,
|
|
942
|
+
agentName: `${agent.label} - ${projectName}`,
|
|
943
|
+
action,
|
|
944
|
+
sessionId: input.session_id
|
|
945
|
+
}, { maxAttempts: 1, timeoutMs: 800 });
|
|
946
|
+
} catch {
|
|
947
|
+
}
|
|
948
|
+
};
|
|
915
949
|
var NOTIFICATION_PUSH_TYPES = /* @__PURE__ */ new Set(["idle_prompt", "agent_needs_input"]);
|
|
916
950
|
var NOTIFICATION_THROTTLE_MS = 60 * 1e3;
|
|
917
951
|
var handleNotification = async (input, agent = CLAUDE_CODE_AGENT) => {
|
|
@@ -983,5 +1017,6 @@ export {
|
|
|
983
1017
|
handlePostToolUse,
|
|
984
1018
|
handleUserPrompt,
|
|
985
1019
|
handleStop,
|
|
1020
|
+
handleSessionStart,
|
|
986
1021
|
handleNotification
|
|
987
1022
|
};
|
|
@@ -2,10 +2,6 @@ import {
|
|
|
2
2
|
denyReasonFrom,
|
|
3
3
|
isDeferAnswer
|
|
4
4
|
} from "./chunk-KQYIHZ5E.js";
|
|
5
|
-
import {
|
|
6
|
-
isGatingMoment,
|
|
7
|
-
recordKeylessMoment
|
|
8
|
-
} from "./chunk-R5AJNXZS.js";
|
|
9
5
|
import {
|
|
10
6
|
DEFAULT_SESSION,
|
|
11
7
|
askUser,
|
|
@@ -24,7 +20,11 @@ import {
|
|
|
24
20
|
savePendingQuestion,
|
|
25
21
|
sendNotification,
|
|
26
22
|
waitForAnswer
|
|
27
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-OCPDWNG2.js";
|
|
24
|
+
import {
|
|
25
|
+
isGatingMoment,
|
|
26
|
+
recordKeylessMoment
|
|
27
|
+
} from "./chunk-R5AJNXZS.js";
|
|
28
28
|
import {
|
|
29
29
|
effectiveWaitSeconds,
|
|
30
30
|
hookWaitClamped,
|
package/dist/src/index.d.ts
CHANGED
|
@@ -91,6 +91,7 @@ declare const handleStop: (input: {
|
|
|
91
91
|
session_id?: string;
|
|
92
92
|
stop_hook_active?: boolean;
|
|
93
93
|
transcript_path?: string;
|
|
94
|
+
last_assistant_message?: string;
|
|
94
95
|
}, agent?: AgentIdentity) => Promise<StopHookOutput | undefined>;
|
|
95
96
|
declare const handleNotification: (input: {
|
|
96
97
|
message?: string;
|
package/dist/src/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handlePreToolUse
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-UU3ETDK4.js";
|
|
4
4
|
import "../chunk-KQYIHZ5E.js";
|
|
5
|
-
import "../chunk-R5AJNXZS.js";
|
|
6
5
|
import {
|
|
7
6
|
askUser,
|
|
8
7
|
cancelQuestion,
|
|
@@ -15,7 +14,8 @@ import {
|
|
|
15
14
|
reportEvent,
|
|
16
15
|
resolvePolicy,
|
|
17
16
|
waitForAnswer
|
|
18
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-OCPDWNG2.js";
|
|
18
|
+
import "../chunk-R5AJNXZS.js";
|
|
19
19
|
import "../chunk-DWED7BS3.js";
|
|
20
20
|
import "../chunk-Z5PL3K7C.js";
|
|
21
21
|
import {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pushary/agent-hooks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pushary",
|
|
@@ -48,6 +48,8 @@
|
|
|
48
48
|
"pushary-stop-hook": "./dist/bin/pushary-stop-hook.js",
|
|
49
49
|
"pushary-prompt-hook": "./dist/bin/pushary-prompt-hook.js",
|
|
50
50
|
"pushary-notification-hook": "./dist/bin/pushary-notification-hook.js",
|
|
51
|
+
"pushary-session-start-hook": "./dist/bin/pushary-session-start-hook.js",
|
|
52
|
+
"pushary-claude": "./dist/bin/pushary-claude.js",
|
|
51
53
|
"pushary-codex": "./dist/bin/pushary-codex.js",
|
|
52
54
|
"pushary-codex-hook": "./dist/bin/pushary-codex-hook.js",
|
|
53
55
|
"pushary-gemini-hook": "./dist/bin/pushary-gemini-hook.js",
|
|
@@ -66,7 +68,7 @@
|
|
|
66
68
|
"scripts": {
|
|
67
69
|
"build": "node scripts/bundle-plugin.mjs && tsup",
|
|
68
70
|
"dev": "tsup --watch",
|
|
69
|
-
"test": "bun test src/api.test.ts && bun test src/claude-config.test.ts && bun test src/config.test.ts && bun test src/mcp-http.test.ts && bun test src/retry.test.ts && bun test src/usage.test.ts && bun test src/validate.test.ts && bun test src/policy.test.ts && bun test src/npm.test.ts && bun test src/identity.test.ts && bun test src/pending.test.ts && bun test src/events.test.ts && bun test src/describe.test.ts && bun test src/suggestions.test.ts && bun test src/safe-commands.test.ts && bun test src/hook.test.ts && bun test src/codex-adapter.test.ts && bun test src/codex-config.test.ts && bun test src/gemini-adapter.test.ts && bun test src/gemini-config.test.ts && bun test src/instruction-file.test.ts && bun test src/pairing.test.ts && bun test src/wait-ladder.test.ts && bun test src/ledger.test.ts"
|
|
71
|
+
"test": "bun test src/api.test.ts && bun test src/claude-config.test.ts && bun test src/config.test.ts && bun test src/mcp-http.test.ts && bun test src/retry.test.ts && bun test src/usage.test.ts && bun test src/validate.test.ts && bun test src/policy.test.ts && bun test src/npm.test.ts && bun test src/identity.test.ts && bun test src/pending.test.ts && bun test src/events.test.ts && bun test src/describe.test.ts && bun test src/suggestions.test.ts && bun test src/safe-commands.test.ts && bun test src/hook.test.ts && bun test src/codex-adapter.test.ts && bun test src/codex-config.test.ts && bun test src/gemini-adapter.test.ts && bun test src/gemini-config.test.ts && bun test src/instruction-file.test.ts && bun test src/pairing.test.ts && bun test src/wait-ladder.test.ts && bun test src/ledger.test.ts && bun test src/wrapper/wrapper.test.ts"
|
|
70
72
|
},
|
|
71
73
|
"dependencies": {
|
|
72
74
|
"@inquirer/prompts": "^8.4.2",
|