@pushary/agent-hooks 0.95.8 → 0.97.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 +19 -21
- package/dist/bin/pushary-bell.js +6 -8
- package/dist/bin/pushary-claude.js +21 -23
- package/dist/bin/pushary-clean.js +19 -22
- package/dist/bin/pushary-codex-bridge.js +13 -14
- package/dist/bin/pushary-codex-hook.js +452 -104
- package/dist/bin/pushary-codex.js +8 -8
- package/dist/bin/pushary-connect.js +6 -6
- package/dist/bin/pushary-cowork.js +3 -3
- package/dist/bin/pushary-daemon.js +25 -27
- package/dist/bin/pushary-disconnect.js +6 -8
- package/dist/bin/pushary-doctor.js +28 -23
- package/dist/bin/pushary-elicitation-hook.js +19 -21
- package/dist/bin/pushary-gemini-bridge.js +11 -12
- package/dist/bin/pushary-gemini-hook.js +22 -24
- package/dist/bin/pushary-hook.js +24 -26
- package/dist/bin/pushary-login.js +7 -8
- package/dist/bin/pushary-logout.js +4 -4
- package/dist/bin/pushary-mode.js +3 -3
- package/dist/bin/pushary-notification-hook.js +21 -23
- package/dist/bin/pushary-opencode-hook.js +22 -24
- package/dist/bin/pushary-permission-denied-hook.js +28 -27
- package/dist/bin/pushary-permission-hook.js +24 -26
- package/dist/bin/pushary-post-hook.js +21 -23
- package/dist/bin/pushary-prompt-hook.js +21 -23
- package/dist/bin/pushary-session-end-hook.js +21 -23
- package/dist/bin/pushary-session-start-hook.js +24 -26
- package/dist/bin/pushary-setup.js +34 -38
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +10 -11
- package/dist/bin/pushary-stop-hook.js +21 -23
- package/dist/bin/pushary-stopfailure-hook.js +21 -23
- package/dist/bin/pushary-transcript-register.js +17 -19
- package/dist/bin/pushary-transcripts.js +5 -5
- package/dist/bin/pushary-upgrade.js +17 -20
- package/dist/bin/pushary-wait.js +3 -3
- package/dist/{chunk-RE25RJ5A.js → chunk-3SNTEHOH.js} +4 -4
- package/dist/{chunk-R3OZ5ISU.js → chunk-4AXWBCCO.js} +4 -4
- package/dist/{chunk-XEVOPOKT.js → chunk-5ODZEFP3.js} +1 -1
- package/dist/{chunk-NOVA7KZ2.js → chunk-67RNDRKL.js} +260 -32
- package/dist/{chunk-3YFJGKJQ.js → chunk-6VXZKOBB.js} +8 -8
- package/dist/{chunk-ATKGKAP6.js → chunk-6WJKYD3Q.js} +8 -8
- package/dist/{chunk-EMGGUO2Q.js → chunk-A4AIISZZ.js} +1 -1
- package/dist/{chunk-N6FAXQDD.js → chunk-AXSDMDJI.js} +1 -1
- package/dist/{chunk-XO3JR3OP.js → chunk-B3557BDL.js} +2 -2
- package/dist/{chunk-QJPYJVL3.js → chunk-BYH75I7Y.js} +1 -1
- package/dist/{chunk-VERXHIQF.js → chunk-C2FYSFTQ.js} +1 -1
- package/dist/{chunk-SKPXQRKN.js → chunk-CDSA3NTB.js} +1 -1
- package/dist/{chunk-HUGIKB5O.js → chunk-DGUMR5LZ.js} +6 -6
- package/dist/{chunk-54W7ELDQ.js → chunk-DNLFSRCF.js} +2 -2
- package/dist/{chunk-R6LBGKWQ.js → chunk-DOKFLZWL.js} +10 -14
- package/dist/{chunk-U5RIXR7I.js → chunk-EHQC3GWL.js} +1 -1
- package/dist/{chunk-QD73WATQ.js → chunk-FU5SQKAY.js} +15 -4
- package/dist/{chunk-TY6IJY6I.js → chunk-GGYH6LIE.js} +1 -1
- package/dist/{chunk-XZWUOCJZ.js → chunk-H4VNAOCG.js} +1 -1
- package/dist/{chunk-MC5WUOJJ.js → chunk-HUZW6SEO.js} +75 -1
- package/dist/{chunk-QV266EGS.js → chunk-IBRX7LRE.js} +8 -10
- package/dist/{chunk-UKMLSQXA.js → chunk-ICUBJNFL.js} +2 -2
- package/dist/{chunk-E47WV7BJ.js → chunk-IZKCA35M.js} +2 -2
- package/dist/{chunk-F4TMY6XI.js → chunk-K7MLXXPY.js} +2 -2
- package/dist/{chunk-Y6SCMXR6.js → chunk-KDPYXMUI.js} +2 -2
- package/dist/{chunk-XS33QBJA.js → chunk-LGXUGYUH.js} +50 -1
- package/dist/{chunk-I7LKI4WO.js → chunk-LYWTLNMG.js} +6 -8
- package/dist/chunk-OYTOLQ3N.js +15 -0
- package/dist/{chunk-XUTSZYYJ.js → chunk-QFAZ6QCT.js} +1 -4
- package/dist/{chunk-FRXZMCVA.js → chunk-ROTIPRM4.js} +1 -1
- package/dist/{chunk-BQL7UDIB.js → chunk-SW37HB27.js} +1 -1
- package/dist/{chunk-Z4JVEL7R.js → chunk-VCKQ45QA.js} +191 -2
- package/dist/{chunk-SDNTRS76.js → chunk-VDTC5DEM.js} +1 -1
- package/dist/{chunk-VMQU7YEJ.js → chunk-VF7YOT2W.js} +1 -1
- package/dist/{chunk-5GKNAQTG.js → chunk-VOC55PQV.js} +1 -1
- package/dist/{chunk-L7NOG547.js → chunk-VTUN7WSG.js} +1 -1
- package/dist/{chunk-GOPIMNVC.js → chunk-WIKEADOS.js} +1 -1
- package/dist/chunk-XDMHLQMH.js +202 -0
- package/dist/{chunk-4DUEIUUO.js → chunk-YRXVC4HL.js} +1 -1
- package/dist/{chunk-A22VQ5ZL.js → chunk-YX3U2CLP.js} +111 -55
- package/dist/src/index.js +11 -11
- package/package.json +1 -1
- package/dist/chunk-3AJIK5AO.js +0 -57
- package/dist/chunk-L4ZCFMWW.js +0 -177
- package/dist/chunk-VDI645ZX.js +0 -18
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
reapplyAllAgents
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-DOKFLZWL.js";
|
|
5
|
+
import "../chunk-YRXVC4HL.js";
|
|
6
6
|
import {
|
|
7
7
|
waitForMachineReadiness
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-3SNTEHOH.js";
|
|
9
|
+
import "../chunk-6WJKYD3Q.js";
|
|
10
10
|
import {
|
|
11
11
|
detectProviderLiveCapabilities,
|
|
12
12
|
hasSpawnProvider,
|
|
13
13
|
resolveControlPolicy
|
|
14
|
-
} from "../chunk-
|
|
15
|
-
import "../chunk-
|
|
14
|
+
} from "../chunk-DNLFSRCF.js";
|
|
15
|
+
import "../chunk-FU5SQKAY.js";
|
|
16
16
|
import {
|
|
17
17
|
daemonHasRemoteProof,
|
|
18
18
|
daemonServiceManagerAvailable,
|
|
@@ -23,26 +23,23 @@ import {
|
|
|
23
23
|
replaceDaemonService,
|
|
24
24
|
stopDaemonService,
|
|
25
25
|
waitForDaemonRemoteProof
|
|
26
|
-
} from "../chunk-
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-3AJIK5AO.js";
|
|
26
|
+
} from "../chunk-LYWTLNMG.js";
|
|
27
|
+
import "../chunk-IBRX7LRE.js";
|
|
29
28
|
import {
|
|
30
29
|
needsShell
|
|
31
30
|
} from "../chunk-XHKBHWLX.js";
|
|
32
|
-
import
|
|
33
|
-
|
|
34
|
-
npmErrorMessage,
|
|
35
|
-
resolveGlobalBinary
|
|
36
|
-
} from "../chunk-L4ZCFMWW.js";
|
|
37
|
-
import "../chunk-XUTSZYYJ.js";
|
|
38
|
-
import "../chunk-E47WV7BJ.js";
|
|
31
|
+
import "../chunk-QFAZ6QCT.js";
|
|
32
|
+
import "../chunk-IZKCA35M.js";
|
|
39
33
|
import {
|
|
40
34
|
claudeJson,
|
|
41
35
|
codexConfigToml,
|
|
42
36
|
cursorPluginDir,
|
|
37
|
+
execNpm,
|
|
43
38
|
geminiSettings,
|
|
39
|
+
npmErrorMessage,
|
|
40
|
+
resolveGlobalBinary,
|
|
44
41
|
vscodePluginDir
|
|
45
|
-
} from "../chunk-
|
|
42
|
+
} from "../chunk-67RNDRKL.js";
|
|
46
43
|
import {
|
|
47
44
|
exitOnHelpFlag
|
|
48
45
|
} from "../chunk-GOQHN2UH.js";
|
|
@@ -52,13 +49,13 @@ import {
|
|
|
52
49
|
} from "../chunk-DINDL2CF.js";
|
|
53
50
|
import {
|
|
54
51
|
readControlMode
|
|
55
|
-
} from "../chunk-
|
|
52
|
+
} from "../chunk-VF7YOT2W.js";
|
|
56
53
|
import "../chunk-KZERVKTD.js";
|
|
57
|
-
import "../chunk-
|
|
54
|
+
import "../chunk-VTUN7WSG.js";
|
|
58
55
|
import {
|
|
59
56
|
getApiKey
|
|
60
57
|
} from "../chunk-2UMNXADU.js";
|
|
61
|
-
import "../chunk-
|
|
58
|
+
import "../chunk-HUZW6SEO.js";
|
|
62
59
|
|
|
63
60
|
// bin/pushary-upgrade.ts
|
|
64
61
|
import { existsSync } from "fs";
|
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "../chunk-CVWG2N3Y.js";
|
|
5
5
|
import {
|
|
6
6
|
exitOnFailedResponse
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-VDTC5DEM.js";
|
|
8
|
+
import "../chunk-SW37HB27.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-HUZW6SEO.js";
|
|
32
32
|
|
|
33
33
|
// bin/pushary-wait.ts
|
|
34
34
|
exitOnHelpFlag("wait");
|
|
@@ -2,24 +2,24 @@ import {
|
|
|
2
2
|
detectProviderLiveCapabilities,
|
|
3
3
|
hasSpawnProvider,
|
|
4
4
|
resolveControlPolicy
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DNLFSRCF.js";
|
|
6
6
|
import {
|
|
7
7
|
daemonHasRemoteProof,
|
|
8
8
|
daemonServiceManagerAvailable,
|
|
9
9
|
hasDaemonServiceDefinition,
|
|
10
10
|
readDaemonNeedsLogin,
|
|
11
11
|
readDaemonStatus
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-LYWTLNMG.js";
|
|
13
13
|
import {
|
|
14
14
|
getMachineId
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-IZKCA35M.js";
|
|
16
16
|
import {
|
|
17
17
|
getPackageVersion
|
|
18
18
|
} from "./chunk-DINDL2CF.js";
|
|
19
19
|
import {
|
|
20
20
|
readControlMode,
|
|
21
21
|
readKeySource
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-VF7YOT2W.js";
|
|
23
23
|
import {
|
|
24
24
|
getBaseUrl
|
|
25
25
|
} from "./chunk-2UMNXADU.js";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AGENT_CHOICES
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-H4VNAOCG.js";
|
|
4
4
|
import {
|
|
5
5
|
isBridgeLocator
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BYH75I7Y.js";
|
|
7
7
|
import {
|
|
8
8
|
pusharyHookExecutable
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FU5SQKAY.js";
|
|
10
10
|
import {
|
|
11
11
|
BELL_HOOK_BINARY
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WIKEADOS.js";
|
|
13
13
|
|
|
14
14
|
// src/setup/hook-ownership.ts
|
|
15
15
|
var commandsIn = (value) => {
|
|
@@ -1,7 +1,222 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HOOK_BUDGETS,
|
|
3
|
-
HOOK_LOCATOR_BINARY
|
|
4
|
-
|
|
3
|
+
HOOK_LOCATOR_BINARY,
|
|
4
|
+
withHookHoldBudget
|
|
5
|
+
} from "./chunk-HUZW6SEO.js";
|
|
6
|
+
|
|
7
|
+
// src/npm.ts
|
|
8
|
+
import { execFileSync, execSync } from "child_process";
|
|
9
|
+
import { existsSync, readFileSync, realpathSync } from "fs";
|
|
10
|
+
import { dirname, isAbsolute, join, relative, resolve } from "path";
|
|
11
|
+
var cleanNpmEnv = () => {
|
|
12
|
+
const env = {};
|
|
13
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
14
|
+
if (key.toLowerCase().startsWith("npm_config_workspace")) continue;
|
|
15
|
+
env[key] = value;
|
|
16
|
+
}
|
|
17
|
+
return env;
|
|
18
|
+
};
|
|
19
|
+
var npmErrorMessage = (err) => {
|
|
20
|
+
const e = err;
|
|
21
|
+
const text = [e?.stderr, e?.stdout].map((part) => part ? part.toString() : "").join("\n");
|
|
22
|
+
const line = text.split("\n").map((l) => l.replace(/^npm error\s*/i, "").trim()).find((l) => l && !l.startsWith("A complete log") && !/^code\s/i.test(l));
|
|
23
|
+
return line || e?.message || String(err);
|
|
24
|
+
};
|
|
25
|
+
var execNpm = (args, options = {}) => {
|
|
26
|
+
return execSync(`npm ${args}`, {
|
|
27
|
+
timeout: 12e4,
|
|
28
|
+
stdio: "pipe",
|
|
29
|
+
...options,
|
|
30
|
+
env: { ...cleanNpmEnv(), ...options.env ?? {} }
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
var resolveGlobalBinary = (name) => {
|
|
34
|
+
try {
|
|
35
|
+
const prefix = execNpm("prefix -g --no-workspaces", { timeout: 5e3 }).toString().trim();
|
|
36
|
+
const candidates = process.platform === "win32" ? [join(prefix, `${name}.cmd`), join(prefix, name)] : [join(prefix, "bin", name)];
|
|
37
|
+
return candidates.find(existsSync);
|
|
38
|
+
} catch {
|
|
39
|
+
return void 0;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var resolvePathBinary = (name, platform = process.platform) => {
|
|
43
|
+
try {
|
|
44
|
+
return execFileSync(platform === "win32" ? "where" : "which", [name], {
|
|
45
|
+
encoding: "utf8",
|
|
46
|
+
stdio: "pipe",
|
|
47
|
+
timeout: 5e3
|
|
48
|
+
}).split(/\r?\n/, 1)[0]?.trim() || void 0;
|
|
49
|
+
} catch {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var resolveBinary = (name) => resolveGlobalBinary(name) ?? resolvePathBinary(name);
|
|
54
|
+
var resolvePackageVersionFromBinary = (binary, packageName) => {
|
|
55
|
+
try {
|
|
56
|
+
let dir = dirname(realpathSync(binary));
|
|
57
|
+
const packagePath = packageName.split("/");
|
|
58
|
+
for (let depth = 0; depth < 8; depth++) {
|
|
59
|
+
for (const manifest of [
|
|
60
|
+
join(dir, "package.json"),
|
|
61
|
+
join(dir, "node_modules", ...packagePath, "package.json")
|
|
62
|
+
]) {
|
|
63
|
+
try {
|
|
64
|
+
const value = JSON.parse(readFileSync(manifest, "utf8"));
|
|
65
|
+
if (value.name === packageName && typeof value.version === "string") return value.version;
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const parent = dirname(dir);
|
|
70
|
+
if (parent === dir) break;
|
|
71
|
+
dir = parent;
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
return void 0;
|
|
76
|
+
};
|
|
77
|
+
var resolveGlobalPackageVersion = (name) => {
|
|
78
|
+
try {
|
|
79
|
+
const result = JSON.parse(execNpm("list -g --depth=0 --json --no-workspaces", { timeout: 5e3 }).toString());
|
|
80
|
+
const value = result.dependencies?.[name]?.version;
|
|
81
|
+
return typeof value === "string" ? value : void 0;
|
|
82
|
+
} catch {
|
|
83
|
+
return void 0;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var localImportsPresent = (entry, packageDir, seen = /* @__PURE__ */ new Set()) => {
|
|
87
|
+
if (seen.has(entry)) return true;
|
|
88
|
+
seen.add(entry);
|
|
89
|
+
try {
|
|
90
|
+
const source = readFileSync(entry, "utf8");
|
|
91
|
+
for (const match of source.matchAll(/\b(?:import|export)\s+(?:[^"'()]*?\s+from\s+)?["'](\.{1,2}\/[^"']+)["']|\bimport\s*\(\s*["'](\.{1,2}\/[^"']+)["']/g)) {
|
|
92
|
+
const dependency = resolve(dirname(entry), match[1] ?? match[2]);
|
|
93
|
+
const localPath = relative(packageDir, dependency);
|
|
94
|
+
if (localPath.startsWith("..") || isAbsolute(localPath) || !existsSync(dependency)) return false;
|
|
95
|
+
if (/\.[cm]?js$/.test(dependency) && !localImportsPresent(dependency, packageDir, seen)) return false;
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
var packageBinsPresent = (packageDir, prefix, platform = process.platform, requiredFiles = []) => {
|
|
103
|
+
try {
|
|
104
|
+
const manifest = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
|
|
105
|
+
if (!manifest.bin || typeof manifest.bin !== "object" || Array.isArray(manifest.bin)) return false;
|
|
106
|
+
const bins = Object.entries(manifest.bin);
|
|
107
|
+
if (bins.length === 0) return false;
|
|
108
|
+
if (!requiredFiles.every((path) => existsSync(join(packageDir, path)))) return false;
|
|
109
|
+
const seen = /* @__PURE__ */ new Set();
|
|
110
|
+
return bins.every(([name, target]) => {
|
|
111
|
+
if (typeof target !== "string") return false;
|
|
112
|
+
const shims = platform === "win32" ? [join(prefix, `${name}.cmd`), join(prefix, name)] : [join(prefix, "bin", name)];
|
|
113
|
+
const entry = join(packageDir, target);
|
|
114
|
+
return existsSync(entry) && shims.some(existsSync) && localImportsPresent(entry, packageDir, seen);
|
|
115
|
+
});
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
var AGENT_HOOKS_RUNTIME_FILES = [
|
|
121
|
+
"data/SKILL.md",
|
|
122
|
+
"data/cursor-plugin/.cursor-plugin/plugin.json",
|
|
123
|
+
"data/cursor-plugin/hooks/hooks.json",
|
|
124
|
+
"data/cursor-plugin/mcp.json",
|
|
125
|
+
"data/cursor-plugin/scripts/pushary-gate.mjs",
|
|
126
|
+
"data/vscode-plugin/.claude-plugin/plugin.json",
|
|
127
|
+
"data/vscode-plugin/hooks/hooks.json",
|
|
128
|
+
"data/vscode-plugin/.mcp.json",
|
|
129
|
+
"data/vscode-plugin/scripts/pushary-gate.mjs"
|
|
130
|
+
];
|
|
131
|
+
var globalPackageBinsPresent = (name) => {
|
|
132
|
+
try {
|
|
133
|
+
const root = execNpm("root -g --no-workspaces", { timeout: 5e3 }).toString().trim();
|
|
134
|
+
const prefix = execNpm("prefix -g --no-workspaces", { timeout: 5e3 }).toString().trim();
|
|
135
|
+
return packageBinsPresent(join(root, ...name.split("/")), prefix, process.platform, AGENT_HOOKS_RUNTIME_FILES);
|
|
136
|
+
} catch {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
var resolveGlobalBinDir = (probe) => {
|
|
141
|
+
if (process.platform === "win32") return void 0;
|
|
142
|
+
const resolved = resolveGlobalBinary(probe);
|
|
143
|
+
return resolved ? resolved.slice(0, resolved.length - probe.length - 1) : void 0;
|
|
144
|
+
};
|
|
145
|
+
var quoteIfNeeded = (path) => /\s/.test(path) ? `"${path}"` : path;
|
|
146
|
+
var needsGlobalInstall = (requested, installed, binaryPresent) => requested !== installed || !binaryPresent;
|
|
147
|
+
var installState;
|
|
148
|
+
var installGlobally = (options) => {
|
|
149
|
+
if (installState) {
|
|
150
|
+
return installState.then((result) => result === "installed" ? "cached" : result);
|
|
151
|
+
}
|
|
152
|
+
const started = (async () => {
|
|
153
|
+
const pinned = process.env.PUSHARY_PIN_GLOBAL_VERSION !== "0";
|
|
154
|
+
if (pinned && !needsGlobalInstall(
|
|
155
|
+
options.version,
|
|
156
|
+
resolveGlobalPackageVersion("@pushary/agent-hooks"),
|
|
157
|
+
globalPackageBinsPresent("@pushary/agent-hooks")
|
|
158
|
+
)) {
|
|
159
|
+
return "skipped";
|
|
160
|
+
}
|
|
161
|
+
const spec = pinned && options.version && options.version !== "0.0.0" ? `@pushary/agent-hooks@${options.version}` : "@pushary/agent-hooks@latest";
|
|
162
|
+
execNpm(`install -g --no-workspaces ${spec}`, { timeout: options.timeoutMs ?? 12e4 });
|
|
163
|
+
return "installed";
|
|
164
|
+
})();
|
|
165
|
+
installState = started;
|
|
166
|
+
started.catch(() => {
|
|
167
|
+
if (installState === started) installState = void 0;
|
|
168
|
+
});
|
|
169
|
+
return started;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// src/hook-command.ts
|
|
173
|
+
var HOOK_SHELL = "/bin/sh -c";
|
|
174
|
+
var holdBudgetOf = (hook) => hook.holds ? hook.timeout : void 0;
|
|
175
|
+
var LOCATE = 'B=$(command -v "$0") || exit 0; [ -f "$B" ] || exit 0; [ -x "$B" ] || exit 0';
|
|
176
|
+
var NODE_PRESENT = "command -v node >/dev/null 2>&1 || exit 0";
|
|
177
|
+
var CURSOR_NO_OPINION = { permission: "deny", user_message: "Command denied via Pushary.", agent_message: "Pushary hook is unavailable. Repair the integration before retrying." };
|
|
178
|
+
var shellDoubleQuoted = (text) => `"${text.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
179
|
+
var CURSOR_NATIVE_PROMPT = { permission: "ask" };
|
|
180
|
+
var CURSOR_NATIVE_PROMPT_EVENTS = ["beforeShellExecution", "beforeMCPExecution"];
|
|
181
|
+
var hookEventIsOneOf = (events) => events.flatMap((event) => [`*\\"hook_event_name\\":\\"${event}\\"*`, `*\\"hook_event_name\\":\\ \\"${event}\\"*`]).join("|");
|
|
182
|
+
var CURSOR_MISS = `{ E=$(cat); case "$E" in ${hookEventIsOneOf(CURSOR_NATIVE_PROMPT_EVENTS)}) printf %s ${shellDoubleQuoted(JSON.stringify(CURSOR_NATIVE_PROMPT))} ;; *) printf %s ${shellDoubleQuoted(JSON.stringify(CURSOR_NO_OPINION))} ;; esac; exit 0; }`;
|
|
183
|
+
var HOOK_GUARD_SCRIPTS = {
|
|
184
|
+
native_binary: `${LOCATE}; exec "$B" "$@"`,
|
|
185
|
+
node_binary: `${LOCATE}; ${NODE_PRESENT}; exec "$B" "$@"`,
|
|
186
|
+
node_script: `[ -f "$0" ] || exit 0; ${NODE_PRESENT}; exec node "$0" "$@"`,
|
|
187
|
+
cursor_gate_script: `[ -f "$0" ] || ${CURSOR_MISS}; command -v node >/dev/null 2>&1 || ${CURSOR_MISS}; exec node "$0" "$@"`
|
|
188
|
+
};
|
|
189
|
+
var BINARY_GUARDS = {
|
|
190
|
+
native: "native_binary",
|
|
191
|
+
node: "node_binary"
|
|
192
|
+
};
|
|
193
|
+
var guardKindOf = (target) => {
|
|
194
|
+
switch (target.kind) {
|
|
195
|
+
case "node":
|
|
196
|
+
return "node_script";
|
|
197
|
+
case "cursor_gate":
|
|
198
|
+
return "cursor_gate_script";
|
|
199
|
+
case "binary":
|
|
200
|
+
return BINARY_GUARDS[target.runtime];
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
var targetPath = (target) => target.kind === "binary" ? target.path : target.script;
|
|
204
|
+
var runsThroughNode = (target) => target.kind !== "binary";
|
|
205
|
+
var guardHookCommand = (target, platform = process.platform) => {
|
|
206
|
+
const path = quoteIfNeeded(targetPath(target));
|
|
207
|
+
if (platform === "win32") return runsThroughNode(target) ? `node ${path}` : path;
|
|
208
|
+
return `${HOOK_SHELL} '${HOOK_GUARD_SCRIPTS[guardKindOf(target)]}' ${path}`;
|
|
209
|
+
};
|
|
210
|
+
var guardBinary = (path, platform) => guardHookCommand({ kind: "binary", path, runtime: "node" }, platform);
|
|
211
|
+
var guardCursorGate = (script, platform) => guardHookCommand({ kind: "cursor_gate", script }, platform);
|
|
212
|
+
var guardedArgv = (target, args = [], platform = process.platform) => {
|
|
213
|
+
const path = targetPath(target);
|
|
214
|
+
if (platform === "win32") {
|
|
215
|
+
return runsThroughNode(target) ? ["node", path, ...args] : [path, ...args];
|
|
216
|
+
}
|
|
217
|
+
const [shell, ...shellArgs] = HOOK_SHELL.split(/\s+/);
|
|
218
|
+
return [shell, ...shellArgs, HOOK_GUARD_SCRIPTS[guardKindOf(target)], path, ...args];
|
|
219
|
+
};
|
|
5
220
|
|
|
6
221
|
// src/removal-scope.ts
|
|
7
222
|
var namesAppLocator = (command) => command.includes(HOOK_LOCATOR_BINARY);
|
|
@@ -10,7 +225,7 @@ var isProtectedByScope = (command, scope) => scope?.keepAppWiring === true && na
|
|
|
10
225
|
// src/codex-config.ts
|
|
11
226
|
import { createHash } from "crypto";
|
|
12
227
|
import { homedir } from "os";
|
|
13
|
-
import { join } from "path";
|
|
228
|
+
import { join as join2 } from "path";
|
|
14
229
|
|
|
15
230
|
// src/canonical-json.ts
|
|
16
231
|
var canonicalJson = (value) => {
|
|
@@ -23,17 +238,17 @@ var canonicalJson = (value) => {
|
|
|
23
238
|
// src/codex-config.ts
|
|
24
239
|
var CODEX_HOOK_BINARY = "pushary-codex-hook";
|
|
25
240
|
var codexHome = () => codexHomeFrom(homedir());
|
|
26
|
-
var codexHomeFrom = (home) => process.env.CODEX_HOME?.trim() ||
|
|
27
|
-
var codexConfigToml = () =>
|
|
28
|
-
var codexHooksJson = () =>
|
|
29
|
-
var codexAgentsMd = () =>
|
|
30
|
-
var codexSkillDir = () =>
|
|
241
|
+
var codexHomeFrom = (home) => process.env.CODEX_HOME?.trim() || join2(home, ".codex");
|
|
242
|
+
var codexConfigToml = () => join2(codexHome(), "config.toml");
|
|
243
|
+
var codexHooksJson = () => join2(codexHome(), "hooks.json");
|
|
244
|
+
var codexAgentsMd = () => join2(codexHome(), "AGENTS.md");
|
|
245
|
+
var codexSkillDir = () => join2(codexHome(), "skills", "pushary");
|
|
31
246
|
var CODEX_HOOK_EVENTS = [
|
|
32
247
|
{ event: "PermissionRequest", delivery: "approval", timeout: HOOK_BUDGETS.codex.budgetSeconds, statusMessage: "Waiting for your phone" },
|
|
33
248
|
{ event: "PreToolUse", matcher: "Bash|apply_patch|mcp__.*", delivery: "approval", timeout: HOOK_BUDGETS.codex.budgetSeconds, statusMessage: "Checking Pushary policy" },
|
|
34
249
|
{ event: "PostToolUse", matcher: "Bash|apply_patch|mcp__.*", delivery: "telemetry", timeout: 10 },
|
|
35
250
|
{ event: "UserPromptSubmit", delivery: "telemetry", timeout: 10 },
|
|
36
|
-
{ event: "Stop", delivery: "
|
|
251
|
+
{ event: "Stop", delivery: "rescue", timeout: HOOK_BUDGETS.codex.budgetSeconds, holds: true },
|
|
37
252
|
// `clear` alongside startup and resume, matching what we already do on Claude
|
|
38
253
|
// Code. Codex names all three in its own SessionStart sources, and without it a
|
|
39
254
|
// session the person started by clearing is one we never see begin.
|
|
@@ -115,7 +330,7 @@ var addCodexHooks = (config, command) => {
|
|
|
115
330
|
...definition.matcher ? { matcher: definition.matcher } : {},
|
|
116
331
|
hooks: [{
|
|
117
332
|
type: "command",
|
|
118
|
-
command,
|
|
333
|
+
command: withHookHoldBudget(command, holdBudgetOf(definition)),
|
|
119
334
|
timeout: definition.timeout,
|
|
120
335
|
...definition.statusMessage ? { statusMessage: definition.statusMessage } : {}
|
|
121
336
|
}]
|
|
@@ -159,7 +374,7 @@ var missingCodexHookEvents = (config) => {
|
|
|
159
374
|
}).map((definition) => definition.event);
|
|
160
375
|
};
|
|
161
376
|
var codexHookTrustHash = (definition, command) => {
|
|
162
|
-
const hook = { command, timeout: definition.timeout, type: "command" };
|
|
377
|
+
const hook = { command: withHookHoldBudget(command, holdBudgetOf(definition)), timeout: definition.timeout, type: "command" };
|
|
163
378
|
if (definition.statusMessage) hook.statusMessage = definition.statusMessage;
|
|
164
379
|
const entry = { hooks: [hook] };
|
|
165
380
|
if (definition.matcher) entry.matcher = definition.matcher;
|
|
@@ -308,29 +523,42 @@ var staleTrustKeys = (state, hooksJsonPath, event, currentKey, ourHash) => {
|
|
|
308
523
|
|
|
309
524
|
// src/setup/paths.ts
|
|
310
525
|
import { homedir as homedir2 } from "os";
|
|
311
|
-
import { join as
|
|
312
|
-
var claudeSettings = () =>
|
|
313
|
-
var claudeJson = () =>
|
|
314
|
-
var claudeSkillDir = () =>
|
|
315
|
-
var cursorPluginDir = () =>
|
|
316
|
-
var cursorUserHooks = () =>
|
|
317
|
-
var cursorUserMcp = () =>
|
|
318
|
-
var vscodePluginDir = () =>
|
|
319
|
-
var vscodePluginMcp = () =>
|
|
320
|
-
var claudeSettingsLocal = () =>
|
|
321
|
-
var pusharyDir = () =>
|
|
322
|
-
var claudeMcpReceipt = () =>
|
|
323
|
-
var bridgeAgentKey = () =>
|
|
324
|
-
var claudeRegistrationReceipt = () =>
|
|
325
|
-
var hermesConfigReceipt = () =>
|
|
326
|
-
var hookTakeoverReceipt = (agent) =>
|
|
327
|
-
var codexSkillDir2 = () =>
|
|
328
|
-
var codexAgentsMd2 = () =>
|
|
329
|
-
var geminiSettings = () =>
|
|
330
|
-
var geminiMd = () =>
|
|
331
|
-
var pusharyConfigFile = () =>
|
|
526
|
+
import { join as join3 } from "path";
|
|
527
|
+
var claudeSettings = () => join3(homedir2(), ".claude", "settings.json");
|
|
528
|
+
var claudeJson = () => join3(homedir2(), ".claude.json");
|
|
529
|
+
var claudeSkillDir = () => join3(homedir2(), ".claude", "skills", "pushary");
|
|
530
|
+
var cursorPluginDir = () => join3(homedir2(), ".cursor", "plugins", "local", "pushary");
|
|
531
|
+
var cursorUserHooks = () => join3(homedir2(), ".cursor", "hooks.json");
|
|
532
|
+
var cursorUserMcp = () => join3(homedir2(), ".cursor", "mcp.json");
|
|
533
|
+
var vscodePluginDir = () => join3(homedir2(), ".pushary", "plugins", "vscode");
|
|
534
|
+
var vscodePluginMcp = () => join3(vscodePluginDir(), ".mcp.json");
|
|
535
|
+
var claudeSettingsLocal = () => join3(homedir2(), ".claude", "settings.local.json");
|
|
536
|
+
var pusharyDir = () => join3(homedir2(), ".pushary");
|
|
537
|
+
var claudeMcpReceipt = () => join3(pusharyDir(), "setup", "claude-mcp.json");
|
|
538
|
+
var bridgeAgentKey = () => join3(pusharyDir(), "bridge-auth", "agent-key.json");
|
|
539
|
+
var claudeRegistrationReceipt = () => join3(pusharyDir(), "setup", "claude-registration.json");
|
|
540
|
+
var hermesConfigReceipt = () => join3(pusharyDir(), "setup", "hermes-config.json");
|
|
541
|
+
var hookTakeoverReceipt = (agent) => join3(pusharyDir(), "setup", `hook-takeover-${agent}.json`);
|
|
542
|
+
var codexSkillDir2 = () => join3(codexHome(), "skills", "pushary");
|
|
543
|
+
var codexAgentsMd2 = () => join3(codexHome(), "AGENTS.md");
|
|
544
|
+
var geminiSettings = () => join3(homedir2(), ".gemini", "settings.json");
|
|
545
|
+
var geminiMd = () => join3(homedir2(), ".gemini", "GEMINI.md");
|
|
546
|
+
var pusharyConfigFile = () => join3(homedir2(), ".pushary", "config.json");
|
|
332
547
|
|
|
333
548
|
export {
|
|
549
|
+
npmErrorMessage,
|
|
550
|
+
execNpm,
|
|
551
|
+
resolveGlobalBinary,
|
|
552
|
+
resolvePathBinary,
|
|
553
|
+
resolveBinary,
|
|
554
|
+
resolvePackageVersionFromBinary,
|
|
555
|
+
resolveGlobalPackageVersion,
|
|
556
|
+
resolveGlobalBinDir,
|
|
557
|
+
installGlobally,
|
|
558
|
+
holdBudgetOf,
|
|
559
|
+
guardBinary,
|
|
560
|
+
guardCursorGate,
|
|
561
|
+
guardedArgv,
|
|
334
562
|
isProtectedByScope,
|
|
335
563
|
canonicalJson,
|
|
336
564
|
CODEX_HOOK_BINARY,
|
|
@@ -3,19 +3,19 @@ import {
|
|
|
3
3
|
loadPin,
|
|
4
4
|
savePin,
|
|
5
5
|
verifyRecipients
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-A4AIISZZ.js";
|
|
7
7
|
import {
|
|
8
8
|
hookOwnerOf
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-4AXWBCCO.js";
|
|
10
10
|
import {
|
|
11
11
|
ensureDaemonRunning
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-LYWTLNMG.js";
|
|
13
13
|
import {
|
|
14
14
|
buildTranscriptRecords,
|
|
15
15
|
decodePublicKey,
|
|
16
16
|
generateSessionKey,
|
|
17
17
|
wrapSessionKey
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-CDSA3NTB.js";
|
|
19
19
|
import {
|
|
20
20
|
fetchTranscriptRecipients,
|
|
21
21
|
uploadTranscriptRecords
|
|
@@ -23,17 +23,17 @@ import {
|
|
|
23
23
|
import {
|
|
24
24
|
transcriptEnvironmentPreference,
|
|
25
25
|
transcriptsEnabled
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-C2FYSFTQ.js";
|
|
27
27
|
import {
|
|
28
28
|
codexHome,
|
|
29
29
|
pusharyDir
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-67RNDRKL.js";
|
|
31
31
|
import {
|
|
32
32
|
readTranscriptPreference
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-VF7YOT2W.js";
|
|
34
34
|
import {
|
|
35
35
|
writeJsonAtomic
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-VTUN7WSG.js";
|
|
37
37
|
import {
|
|
38
38
|
getApiKey,
|
|
39
39
|
getBaseUrl
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CLAUDE_HOOK_EVENTS,
|
|
3
3
|
supportedClaudeEvents
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
guardBinary
|
|
7
|
-
} from "./chunk-3AJIK5AO.js";
|
|
4
|
+
} from "./chunk-IBRX7LRE.js";
|
|
8
5
|
import {
|
|
6
|
+
guardBinary,
|
|
7
|
+
holdBudgetOf,
|
|
9
8
|
isProtectedByScope
|
|
10
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-67RNDRKL.js";
|
|
11
10
|
import {
|
|
12
|
-
HOOK_LOCATOR_BINARY
|
|
13
|
-
|
|
11
|
+
HOOK_LOCATOR_BINARY,
|
|
12
|
+
withHookHoldBudget
|
|
13
|
+
} from "./chunk-HUZW6SEO.js";
|
|
14
14
|
|
|
15
15
|
// src/claude-config.ts
|
|
16
16
|
import { join } from "path";
|
|
@@ -142,7 +142,7 @@ var entry = (definition, resolve) => ({
|
|
|
142
142
|
...definition.matcher ? { matcher: definition.matcher } : {},
|
|
143
143
|
hooks: [{
|
|
144
144
|
type: "command",
|
|
145
|
-
command: resolve(definition.binary),
|
|
145
|
+
command: withHookHoldBudget(resolve(definition.binary), holdBudgetOf(definition)),
|
|
146
146
|
timeout: definition.timeout
|
|
147
147
|
}]
|
|
148
148
|
});
|
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
} from "./chunk-EYRGBYZG.js";
|
|
16
16
|
import {
|
|
17
17
|
reportedInstallSource
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-VTUN7WSG.js";
|
|
19
19
|
import {
|
|
20
20
|
isAnswerSource
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-HUZW6SEO.js";
|
|
22
22
|
|
|
23
23
|
// src/reach.ts
|
|
24
24
|
var reachVerdict = (channels) => {
|