@pushary/agent-hooks 0.89.2 → 0.89.4
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 +9 -0
- package/README.md +40 -0
- package/dist/bin/pushary-bell-hook.js +3 -3
- package/dist/bin/pushary-bell.js +9 -10
- package/dist/bin/pushary-claude.js +106 -24
- package/dist/bin/pushary-clean.js +28 -7
- package/dist/bin/pushary-codex-bridge.js +17 -7
- package/dist/bin/pushary-codex-hook.js +8 -7
- package/dist/bin/pushary-codex.js +6 -4
- package/dist/bin/pushary-connect.js +4 -4
- package/dist/bin/pushary-daemon.js +141 -21
- package/dist/bin/pushary-disconnect.js +3 -4
- package/dist/bin/pushary-doctor.js +45 -29
- package/dist/bin/pushary-elicitation-hook.js +4 -2
- package/dist/bin/pushary-gemini-bridge.js +16 -6
- package/dist/bin/pushary-gemini-hook.js +6 -4
- package/dist/bin/pushary-hook.js +9 -7
- package/dist/bin/pushary-login.js +4 -4
- package/dist/bin/pushary-logout.js +5 -6
- package/dist/bin/pushary-mode.js +2 -2
- package/dist/bin/pushary-notification-hook.js +6 -4
- package/dist/bin/pushary-opencode-hook.js +14 -6
- package/dist/bin/pushary-permission-denied-hook.js +7 -5
- package/dist/bin/pushary-permission-hook.js +7 -5
- package/dist/bin/pushary-post-hook.js +6 -4
- package/dist/bin/pushary-prompt-hook.js +6 -4
- package/dist/bin/pushary-session-end-hook.js +6 -4
- package/dist/bin/pushary-session-start-hook.js +6 -4
- package/dist/bin/pushary-setup.js +49 -28
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +7 -6
- package/dist/bin/pushary-stop-hook.js +6 -4
- package/dist/bin/pushary-stopfailure-hook.js +6 -4
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-upgrade.js +63 -28
- package/dist/bin/pushary-wait.js +2 -2
- package/dist/bin/pushary.js +1 -1
- package/dist/chunk-2HYPZLYY.js +45 -0
- package/dist/{chunk-ZYPS2XMT.js → chunk-4ZHQNBDP.js} +1 -1
- package/dist/{chunk-B7JE4XHD.js → chunk-7IJYOBHL.js} +1 -1
- package/dist/{chunk-NRGRUOAR.js → chunk-FWUEYXSD.js} +4 -0
- package/dist/{chunk-J3YDT4HM.js → chunk-GKAKAOKC.js} +68 -2
- package/dist/{chunk-GOEXZ5QJ.js → chunk-GPNOHKFO.js} +9 -2
- package/dist/{chunk-SQOFGPNX.js → chunk-KJ57OPCC.js} +1 -1
- package/dist/{chunk-LGXTBUT4.js → chunk-KOPUTJQC.js} +1 -0
- package/dist/{chunk-HEQVIIBN.js → chunk-MZBT2LXW.js} +4 -4
- package/dist/{chunk-6XSC6Z2K.js → chunk-NFI2K2ZQ.js} +80 -23
- package/dist/{chunk-K42SZKYF.js → chunk-NLMSSKES.js} +251 -6
- package/dist/{chunk-4VYUMYWD.js → chunk-OBI4YMCT.js} +17 -2
- package/dist/{chunk-LUCFN47K.js → chunk-QH4AA7QV.js} +1 -1
- package/dist/{chunk-VKVHY5HD.js → chunk-V37ZXMH3.js} +11 -3
- package/dist/{chunk-MHBC2XUP.js → chunk-VP7SDXYG.js} +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +7 -5
- package/package.json +1 -1
- package/dist/chunk-GIRT7677.js +0 -11
- package/dist/chunk-RN3NOEJF.js +0 -9
- package/dist/{chunk-LALHWDWL.js → chunk-W6NPWHBJ.js} +3 -3
|
@@ -5,17 +5,18 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
resolveGlobalBinary
|
|
7
7
|
} from "./chunk-PZA7G4CN.js";
|
|
8
|
-
import {
|
|
9
|
-
pusharyDir
|
|
10
|
-
} from "./chunk-VKVHY5HD.js";
|
|
11
8
|
import {
|
|
12
9
|
getMachineId
|
|
13
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2HYPZLYY.js";
|
|
11
|
+
import {
|
|
12
|
+
pusharyDir
|
|
13
|
+
} from "./chunk-V37ZXMH3.js";
|
|
14
14
|
import {
|
|
15
15
|
getPackageVersion
|
|
16
16
|
} from "./chunk-DINDL2CF.js";
|
|
17
17
|
import {
|
|
18
18
|
readJsonSafe,
|
|
19
|
+
writeFileAtomic,
|
|
19
20
|
writeJsonAtomic
|
|
20
21
|
} from "./chunk-6MTNS63X.js";
|
|
21
22
|
import {
|
|
@@ -23,9 +24,11 @@ import {
|
|
|
23
24
|
} from "./chunk-2UMNXADU.js";
|
|
24
25
|
|
|
25
26
|
// src/daemon-lifecycle.ts
|
|
26
|
-
import { dirname, join } from "path";
|
|
27
|
-
import { existsSync, mkdirSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
27
|
+
import { dirname, join, win32 as win32Path } from "path";
|
|
28
|
+
import { existsSync, mkdirSync, realpathSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
28
29
|
import { createHash, randomUUID } from "crypto";
|
|
30
|
+
import { homedir } from "os";
|
|
31
|
+
import { execFileSync } from "child_process";
|
|
29
32
|
var daemonNeedsHandoff = (status) => status.kind === "version-mismatch" || status.kind === "configuration-mismatch" || status.kind === "unresponsive" && status.processAlive === true;
|
|
30
33
|
var statePath = (dir) => join(dir, "daemon-state.json");
|
|
31
34
|
var lockPath = (dir) => join(dir, "daemon.lock");
|
|
@@ -37,6 +40,219 @@ var buildDaemonLaunch = (input) => input.siblingEntry ? { command: input.execPat
|
|
|
37
40
|
args: [],
|
|
38
41
|
shell: needsShell(input.daemonBinary, input.platform ?? process.platform)
|
|
39
42
|
};
|
|
43
|
+
var xml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
44
|
+
var systemdQuote = (value) => `"${value.replaceAll("%", "%%").replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
|
|
45
|
+
var buildDaemonService = (input) => {
|
|
46
|
+
if (input.platform === "darwin") {
|
|
47
|
+
if (!Number.isInteger(input.uid) || input.uid < 0) return null;
|
|
48
|
+
const label = "com.pushary.daemon";
|
|
49
|
+
const domain = `gui/${input.uid}`;
|
|
50
|
+
const target = `${domain}/${label}`;
|
|
51
|
+
const definitionPath = join(input.homeDir, "Library", "LaunchAgents", `${label}.plist`);
|
|
52
|
+
const contents = `<?xml version="1.0" encoding="UTF-8"?>
|
|
53
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
54
|
+
<plist version="1.0">
|
|
55
|
+
<dict>
|
|
56
|
+
<key>Label</key><string>${label}</string>
|
|
57
|
+
<key>ProgramArguments</key>
|
|
58
|
+
<array><string>${xml(input.execPath)}</string><string>${xml(input.daemonEntry)}</string></array>
|
|
59
|
+
<key>WorkingDirectory</key><string>${xml(input.homeDir)}</string>
|
|
60
|
+
<key>EnvironmentVariables</key><dict><key>PATH</key><string>${xml(input.pathEnv)}</string></dict>
|
|
61
|
+
<key>RunAtLoad</key><true/>
|
|
62
|
+
<key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>
|
|
63
|
+
<key>ThrottleInterval</key><integer>10</integer>
|
|
64
|
+
<key>StandardOutPath</key><string>${xml(join(input.stateDir, "daemon.log"))}</string>
|
|
65
|
+
<key>StandardErrorPath</key><string>${xml(join(input.stateDir, "daemon-error.log"))}</string>
|
|
66
|
+
</dict>
|
|
67
|
+
</plist>
|
|
68
|
+
`;
|
|
69
|
+
const bootstrap = { command: "launchctl", args: ["bootstrap", domain, definitionPath] };
|
|
70
|
+
return {
|
|
71
|
+
definitionPath,
|
|
72
|
+
contents,
|
|
73
|
+
install: [
|
|
74
|
+
{ command: "launchctl", args: ["bootout", domain, definitionPath], ignoreFailure: true },
|
|
75
|
+
bootstrap,
|
|
76
|
+
{ command: "launchctl", args: ["enable", target] },
|
|
77
|
+
{ command: "launchctl", args: ["kickstart", "-k", target] }
|
|
78
|
+
],
|
|
79
|
+
start: [{ command: "launchctl", args: ["kickstart", "-k", target] }],
|
|
80
|
+
stop: [{ command: "launchctl", args: ["kill", "SIGTERM", target], ignoreFailure: true }],
|
|
81
|
+
uninstall: [{ command: "launchctl", args: ["bootout", domain, definitionPath], ignoreFailure: true }]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (input.platform === "linux") {
|
|
85
|
+
const unit = "pushary-daemon.service";
|
|
86
|
+
const definitionPath = join(input.homeDir, ".config", "systemd", "user", unit);
|
|
87
|
+
const contents = `[Unit]
|
|
88
|
+
Description=Pushary phone-to-agent daemon
|
|
89
|
+
After=network-online.target
|
|
90
|
+
|
|
91
|
+
[Service]
|
|
92
|
+
Type=simple
|
|
93
|
+
ExecStart=${systemdQuote(input.execPath)} ${systemdQuote(input.daemonEntry)}
|
|
94
|
+
WorkingDirectory=${systemdQuote(input.homeDir)}
|
|
95
|
+
Environment=${systemdQuote(`PATH=${input.pathEnv}`)}
|
|
96
|
+
Restart=on-failure
|
|
97
|
+
RestartSec=10
|
|
98
|
+
|
|
99
|
+
[Install]
|
|
100
|
+
WantedBy=default.target
|
|
101
|
+
`;
|
|
102
|
+
return {
|
|
103
|
+
definitionPath,
|
|
104
|
+
contents,
|
|
105
|
+
install: [
|
|
106
|
+
{ command: "systemctl", args: ["--user", "daemon-reload"] },
|
|
107
|
+
{ command: "systemctl", args: ["--user", "enable", "--now", unit] }
|
|
108
|
+
],
|
|
109
|
+
start: [{ command: "systemctl", args: ["--user", "start", unit] }],
|
|
110
|
+
stop: [{ command: "systemctl", args: ["--user", "stop", unit], ignoreFailure: true }],
|
|
111
|
+
uninstall: [
|
|
112
|
+
{ command: "systemctl", args: ["--user", "disable", "--now", unit], ignoreFailure: true }
|
|
113
|
+
],
|
|
114
|
+
reloadAfterUninstall: { command: "systemctl", args: ["--user", "daemon-reload"] }
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (input.platform === "win32") {
|
|
118
|
+
const taskName = "Pushary Daemon";
|
|
119
|
+
const definitionPath = win32Path.join(input.stateDir, "pushary-daemon-task.xml");
|
|
120
|
+
const contents = `<?xml version="1.0" encoding="UTF-8"?>
|
|
121
|
+
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
|
122
|
+
<RegistrationInfo><Description>Pushary phone-to-agent daemon</Description></RegistrationInfo>
|
|
123
|
+
<Triggers><LogonTrigger><Enabled>true</Enabled></LogonTrigger></Triggers>
|
|
124
|
+
<Principals><Principal id="Author"><LogonType>InteractiveToken</LogonType><RunLevel>LeastPrivilege</RunLevel></Principal></Principals>
|
|
125
|
+
<Settings>
|
|
126
|
+
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
|
127
|
+
<StartWhenAvailable>true</StartWhenAvailable>
|
|
128
|
+
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
|
129
|
+
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
|
|
130
|
+
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
|
|
131
|
+
<RestartOnFailure><Interval>PT1M</Interval><Count>999</Count></RestartOnFailure>
|
|
132
|
+
</Settings>
|
|
133
|
+
<Actions Context="Author">
|
|
134
|
+
<Exec>
|
|
135
|
+
<Command>${xml(input.execPath)}</Command>
|
|
136
|
+
<Arguments>"${xml(input.daemonEntry)}"</Arguments>
|
|
137
|
+
<WorkingDirectory>${xml(input.homeDir)}</WorkingDirectory>
|
|
138
|
+
</Exec>
|
|
139
|
+
</Actions>
|
|
140
|
+
</Task>
|
|
141
|
+
`;
|
|
142
|
+
return {
|
|
143
|
+
definitionPath,
|
|
144
|
+
contents,
|
|
145
|
+
install: [
|
|
146
|
+
{ command: "schtasks.exe", args: ["/Create", "/TN", taskName, "/XML", definitionPath, "/F"] },
|
|
147
|
+
{ command: "schtasks.exe", args: ["/Run", "/TN", taskName] }
|
|
148
|
+
],
|
|
149
|
+
start: [{ command: "schtasks.exe", args: ["/Run", "/TN", taskName] }],
|
|
150
|
+
stop: [{ command: "schtasks.exe", args: ["/End", "/TN", taskName], ignoreFailure: true }],
|
|
151
|
+
uninstall: [{ command: "schtasks.exe", args: ["/Delete", "/TN", taskName, "/F"], ignoreFailure: true }]
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
};
|
|
156
|
+
var resolveDaemonServiceDefinition = (options = {}) => {
|
|
157
|
+
const platform = options.platform ?? process.platform;
|
|
158
|
+
const exists = options.entryExists ?? existsSync;
|
|
159
|
+
const globalBinary = options.globalBinary ?? resolveGlobalBinary("pushary-daemon");
|
|
160
|
+
let daemonEntry = options.daemonEntry;
|
|
161
|
+
if (!daemonEntry && globalBinary) {
|
|
162
|
+
if (platform === "win32") {
|
|
163
|
+
const globalRoot = win32Path.dirname(globalBinary);
|
|
164
|
+
const candidate = win32Path.join(
|
|
165
|
+
globalRoot,
|
|
166
|
+
"node_modules",
|
|
167
|
+
"@pushary",
|
|
168
|
+
"agent-hooks",
|
|
169
|
+
"dist",
|
|
170
|
+
"bin",
|
|
171
|
+
"pushary-daemon.js"
|
|
172
|
+
);
|
|
173
|
+
if (exists(candidate)) daemonEntry = candidate;
|
|
174
|
+
} else {
|
|
175
|
+
try {
|
|
176
|
+
const candidate = (options.realpath ?? realpathSync)(globalBinary);
|
|
177
|
+
if (exists(candidate)) daemonEntry = candidate;
|
|
178
|
+
} catch {
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const argvEntry = options.argvEntry ?? process.argv[1];
|
|
183
|
+
if (!daemonEntry && argvEntry) {
|
|
184
|
+
const path = platform === "win32" ? win32Path : { dirname, join };
|
|
185
|
+
const candidate = path.join(path.dirname(argvEntry), "pushary-daemon.js");
|
|
186
|
+
if (exists(candidate)) daemonEntry = candidate;
|
|
187
|
+
}
|
|
188
|
+
if (!daemonEntry || !exists(daemonEntry)) return null;
|
|
189
|
+
const homeDir = options.homeDir ?? homedir();
|
|
190
|
+
return buildDaemonService({
|
|
191
|
+
platform,
|
|
192
|
+
homeDir,
|
|
193
|
+
stateDir: options.stateDir ?? pusharyDir(),
|
|
194
|
+
execPath: options.execPath ?? process.execPath,
|
|
195
|
+
daemonEntry,
|
|
196
|
+
pathEnv: options.pathEnv ?? process.env.PATH ?? "",
|
|
197
|
+
uid: options.uid ?? process.getuid?.()
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
var applyDaemonService = (action, definition, options = {}) => {
|
|
201
|
+
const run = options.run ?? ((command, args) => {
|
|
202
|
+
execFileSync(command, [...args], { stdio: "ignore", windowsHide: true });
|
|
203
|
+
});
|
|
204
|
+
try {
|
|
205
|
+
if (action === "install") writeFileAtomic(definition.definitionPath, definition.contents, 384);
|
|
206
|
+
const steps = action === "uninstall" ? [...definition.stop, ...definition.uninstall] : definition[action];
|
|
207
|
+
for (const step of steps) {
|
|
208
|
+
try {
|
|
209
|
+
run(step.command, step.args);
|
|
210
|
+
} catch (err) {
|
|
211
|
+
if (!step.ignoreFailure) throw err;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (action === "uninstall") {
|
|
215
|
+
safeUnlink(definition.definitionPath);
|
|
216
|
+
const reload = definition.reloadAfterUninstall;
|
|
217
|
+
if (reload) run(reload.command, reload.args);
|
|
218
|
+
}
|
|
219
|
+
return { kind: "ok" };
|
|
220
|
+
} catch (err) {
|
|
221
|
+
return { kind: "failed", detail: err instanceof Error ? err.message : String(err) };
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
var DAEMON_ACTIONS = /* @__PURE__ */ new Set([
|
|
225
|
+
"install",
|
|
226
|
+
"start",
|
|
227
|
+
"stop",
|
|
228
|
+
"restart",
|
|
229
|
+
"status",
|
|
230
|
+
"uninstall",
|
|
231
|
+
"foreground"
|
|
232
|
+
]);
|
|
233
|
+
var parseDaemonAction = (argv) => {
|
|
234
|
+
const args = argv[0] === "daemon" ? argv.slice(1) : argv;
|
|
235
|
+
const action = args[0] ?? "foreground";
|
|
236
|
+
return DAEMON_ACTIONS.has(action) ? action : null;
|
|
237
|
+
};
|
|
238
|
+
var manageDaemonService = (action, options = {}) => {
|
|
239
|
+
const definition = action === "uninstall" ? buildDaemonService({
|
|
240
|
+
platform: options.platform ?? process.platform,
|
|
241
|
+
homeDir: options.homeDir ?? homedir(),
|
|
242
|
+
stateDir: options.stateDir ?? pusharyDir(),
|
|
243
|
+
execPath: options.execPath ?? process.execPath,
|
|
244
|
+
daemonEntry: options.daemonEntry ?? process.execPath,
|
|
245
|
+
pathEnv: options.pathEnv ?? process.env.PATH ?? "",
|
|
246
|
+
uid: options.uid ?? process.getuid?.()
|
|
247
|
+
}) : resolveDaemonServiceDefinition(options);
|
|
248
|
+
if (!definition) {
|
|
249
|
+
return {
|
|
250
|
+
kind: "unavailable",
|
|
251
|
+
detail: "Could not find the globally installed daemon entry. Run Pushary setup again."
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return applyDaemonService(action, definition, { run: options.run });
|
|
255
|
+
};
|
|
40
256
|
var spawnDetachedDaemon = (plan, options = {}) => {
|
|
41
257
|
const spawnImpl = options.spawnImpl ?? spawnClaude;
|
|
42
258
|
const child = spawnImpl(plan.command, plan.args, {
|
|
@@ -278,6 +494,31 @@ var requestDaemonHandoff = async (initial, options = {}) => {
|
|
|
278
494
|
}
|
|
279
495
|
return status;
|
|
280
496
|
};
|
|
497
|
+
var stopDaemonRunning = async (options = {}) => {
|
|
498
|
+
const dir = options.dir ?? pusharyDir();
|
|
499
|
+
const initial = readDaemonStatus(options);
|
|
500
|
+
if (initial.pid === null || initial.processAlive !== true) {
|
|
501
|
+
safeUnlink(statePath(dir));
|
|
502
|
+
safeUnlink(lockPath(dir));
|
|
503
|
+
return { kind: "absent" };
|
|
504
|
+
}
|
|
505
|
+
let status;
|
|
506
|
+
try {
|
|
507
|
+
status = await requestDaemonHandoff(initial, options);
|
|
508
|
+
} catch (err) {
|
|
509
|
+
return { kind: "unavailable", detail: err instanceof Error ? err.message : String(err) };
|
|
510
|
+
}
|
|
511
|
+
if (status.pid === initial.pid && status.processAlive === true) {
|
|
512
|
+
return { kind: "unavailable", detail: "daemon did not stop" };
|
|
513
|
+
}
|
|
514
|
+
safeUnlink(statePath(dir));
|
|
515
|
+
safeUnlink(lockPath(dir));
|
|
516
|
+
return { kind: "stopped" };
|
|
517
|
+
};
|
|
518
|
+
var replaceDaemonService = async (options = {}) => {
|
|
519
|
+
const stopped = await stopDaemonRunning(options);
|
|
520
|
+
return stopped.kind === "unavailable" ? stopped : manageDaemonService("install", options);
|
|
521
|
+
};
|
|
281
522
|
var launchInstalledDaemon = (options) => {
|
|
282
523
|
const entryExists = options.entryExists ?? existsSync;
|
|
283
524
|
const argvEntry = process.argv[1];
|
|
@@ -336,8 +577,12 @@ var ensureDaemonRunning = async (options = {}) => {
|
|
|
336
577
|
|
|
337
578
|
export {
|
|
338
579
|
DAEMON_LEASE_RENEW_INTERVAL_MS,
|
|
580
|
+
parseDaemonAction,
|
|
581
|
+
manageDaemonService,
|
|
339
582
|
readDaemonStatus,
|
|
340
583
|
acquireDaemonLease,
|
|
341
584
|
requestDaemonHandoff,
|
|
585
|
+
stopDaemonRunning,
|
|
586
|
+
replaceDaemonService,
|
|
342
587
|
ensureDaemonRunning
|
|
343
588
|
};
|
|
@@ -3,16 +3,30 @@ import {
|
|
|
3
3
|
} from "./chunk-7TS2G4QG.js";
|
|
4
4
|
import {
|
|
5
5
|
hasCodexHooks
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-V37ZXMH3.js";
|
|
7
|
+
import {
|
|
8
|
+
HOOK_LOCATOR_BINARY
|
|
9
|
+
} from "./chunk-L4C2JXJS.js";
|
|
7
10
|
|
|
8
11
|
// src/diagnostics/wiring.ts
|
|
9
12
|
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
10
13
|
var CLAUDE_HOOK_BINARY = /pushary-[a-z-]*hook/;
|
|
14
|
+
var EXACT_HOOK_BINARY = /^pushary-[a-z-]*hook$/;
|
|
15
|
+
var pusharyHookExecutable = (command) => {
|
|
16
|
+
const tokens = command.match(/"[^"]*"|'[^']*'|\S+/g) ?? [];
|
|
17
|
+
for (const raw of tokens.reverse()) {
|
|
18
|
+
const token = raw[0] === '"' && raw.at(-1) === '"' || raw[0] === "'" && raw.at(-1) === "'" ? raw.slice(1, -1) : raw;
|
|
19
|
+
const name = token.split(/[/\\]/).pop()?.replace(/\.(cmd|exe)$/i, "") ?? "";
|
|
20
|
+
if (name === HOOK_LOCATOR_BINARY || EXACT_HOOK_BINARY.test(name)) return token;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
11
24
|
var claudeWired = ({ claudeJson, settings, skillExists }) => {
|
|
12
25
|
if (record(record(claudeJson)?.mcpServers)?.pushary) return true;
|
|
13
26
|
const s = record(settings);
|
|
14
27
|
if (s) {
|
|
15
|
-
|
|
28
|
+
const hooks = JSON.stringify(s.hooks ?? {});
|
|
29
|
+
if (CLAUDE_HOOK_BINARY.test(hooks) || hooks.includes(HOOK_LOCATOR_BINARY)) return true;
|
|
16
30
|
const allow = record(s.permissions)?.allow;
|
|
17
31
|
if (Array.isArray(allow) && allow.some((rule) => String(rule).includes("mcp__pushary__"))) return true;
|
|
18
32
|
}
|
|
@@ -32,6 +46,7 @@ var geminiWired = ({ settings }) => {
|
|
|
32
46
|
};
|
|
33
47
|
|
|
34
48
|
export {
|
|
49
|
+
pusharyHookExecutable,
|
|
35
50
|
claudeWired,
|
|
36
51
|
codexWired,
|
|
37
52
|
geminiWired
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
canonicalJson
|
|
3
|
-
} from "./chunk-GIRT7677.js";
|
|
4
1
|
import {
|
|
5
2
|
HOOK_BUDGETS,
|
|
6
3
|
HOOK_LOCATOR_BINARY
|
|
@@ -10,6 +7,16 @@ import {
|
|
|
10
7
|
import { createHash } from "crypto";
|
|
11
8
|
import { homedir } from "os";
|
|
12
9
|
import { join } from "path";
|
|
10
|
+
|
|
11
|
+
// src/canonical-json.ts
|
|
12
|
+
var canonicalJson = (value) => {
|
|
13
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
14
|
+
if (Array.isArray(value)) return "[" + value.map(canonicalJson).join(",") + "]";
|
|
15
|
+
const record = value;
|
|
16
|
+
return "{" + Object.keys(record).sort().map((key) => JSON.stringify(key) + ":" + canonicalJson(record[key])).join(",") + "}";
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// src/codex-config.ts
|
|
13
20
|
var CODEX_HOOK_BINARY = "pushary-codex-hook";
|
|
14
21
|
var codexHome = () => codexHomeFrom(homedir());
|
|
15
22
|
var codexHomeFrom = (home) => process.env.CODEX_HOME?.trim() || join(home, ".codex");
|
|
@@ -263,6 +270,7 @@ var geminiMd = () => join2(homedir2(), ".gemini", "GEMINI.md");
|
|
|
263
270
|
var pusharyConfigFile = () => join2(homedir2(), ".pushary", "config.json");
|
|
264
271
|
|
|
265
272
|
export {
|
|
273
|
+
canonicalJson,
|
|
266
274
|
CODEX_HOOK_BINARY,
|
|
267
275
|
codexHome,
|
|
268
276
|
codexHomeFrom,
|
package/dist/src/index.d.ts
CHANGED
|
@@ -68,6 +68,8 @@ interface ReportEventOptions {
|
|
|
68
68
|
interface EventResponse {
|
|
69
69
|
readonly ok?: boolean;
|
|
70
70
|
readonly pendingCommand?: string;
|
|
71
|
+
readonly pendingCommandId?: string;
|
|
72
|
+
readonly pendingCommandExpiresAtMs?: number;
|
|
71
73
|
}
|
|
72
74
|
declare const reportEvent: (event: AgentEvent, options?: ReportEventOptions) => Promise<EventResponse | null>;
|
|
73
75
|
declare const handlePostToolUse: (input: {
|
package/dist/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handlePreToolUse
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-MZBT2LXW.js";
|
|
4
4
|
import "../chunk-ATBKJNWS.js";
|
|
5
5
|
import "../chunk-VZKXBFUA.js";
|
|
6
6
|
import "../chunk-YHG74UFF.js";
|
|
@@ -12,19 +12,21 @@ import {
|
|
|
12
12
|
handlePostToolUse,
|
|
13
13
|
handleStop,
|
|
14
14
|
reportEvent
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-NFI2K2ZQ.js";
|
|
16
16
|
import {
|
|
17
17
|
askUser,
|
|
18
18
|
cancelQuestion,
|
|
19
19
|
waitForAnswer
|
|
20
|
-
} from "../chunk-
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-
|
|
20
|
+
} from "../chunk-GKAKAOKC.js";
|
|
21
|
+
import "../chunk-KOPUTJQC.js";
|
|
22
|
+
import "../chunk-2HYPZLYY.js";
|
|
23
|
+
import "../chunk-V37ZXMH3.js";
|
|
23
24
|
import "../chunk-BSZYIAZL.js";
|
|
24
25
|
import "../chunk-SAF6HGAA.js";
|
|
25
26
|
import "../chunk-OFRNZWC4.js";
|
|
26
27
|
import "../chunk-7QLSKOSU.js";
|
|
27
28
|
import "../chunk-KZERVKTD.js";
|
|
29
|
+
import "../chunk-6MTNS63X.js";
|
|
28
30
|
import {
|
|
29
31
|
getApiKey,
|
|
30
32
|
getBaseUrl
|
package/package.json
CHANGED
package/dist/chunk-GIRT7677.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// src/canonical-json.ts
|
|
2
|
-
var canonicalJson = (value) => {
|
|
3
|
-
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
4
|
-
if (Array.isArray(value)) return "[" + value.map(canonicalJson).join(",") + "]";
|
|
5
|
-
const record = value;
|
|
6
|
-
return "{" + Object.keys(record).sort().map((key) => JSON.stringify(key) + ":" + canonicalJson(record[key])).join(",") + "}";
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
canonicalJson
|
|
11
|
-
};
|
package/dist/chunk-RN3NOEJF.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
// src/identity.ts
|
|
2
|
-
import { createHash } from "crypto";
|
|
3
|
-
import { hostname } from "os";
|
|
4
|
-
var deriveMachineId = (host) => createHash("sha256").update(host).digest("hex").slice(0, 8);
|
|
5
|
-
var getMachineId = () => deriveMachineId(hostname());
|
|
6
|
-
|
|
7
|
-
export {
|
|
8
|
-
getMachineId
|
|
9
|
-
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveShellRc
|
|
3
3
|
} from "./chunk-BC3VCZ3E.js";
|
|
4
|
+
import {
|
|
5
|
+
resolveInstallSourceFor
|
|
6
|
+
} from "./chunk-OFRNZWC4.js";
|
|
4
7
|
import {
|
|
5
8
|
backupFile,
|
|
6
9
|
readJsonSafe,
|
|
7
10
|
writeFileAtomic,
|
|
8
11
|
writeJsonAtomic
|
|
9
12
|
} from "./chunk-6MTNS63X.js";
|
|
10
|
-
import {
|
|
11
|
-
resolveInstallSourceFor
|
|
12
|
-
} from "./chunk-OFRNZWC4.js";
|
|
13
13
|
import {
|
|
14
14
|
configFilePath
|
|
15
15
|
} from "./chunk-2UMNXADU.js";
|