@pushary/agent-hooks 0.90.2 → 0.92.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 +39 -0
- package/dist/bin/pushary-bell.js +1 -1
- package/dist/bin/pushary-claude.js +5 -5
- package/dist/bin/pushary-clean.js +9 -8
- package/dist/bin/pushary-codex-bridge.js +3 -3
- package/dist/bin/pushary-codex-hook.js +3 -3
- package/dist/bin/pushary-codex.js +3 -3
- package/dist/bin/pushary-daemon.js +9 -9
- package/dist/bin/pushary-disconnect.js +2 -2
- package/dist/bin/pushary-doctor.js +7 -7
- package/dist/bin/pushary-elicitation-hook.js +2 -2
- package/dist/bin/pushary-gemini-bridge.js +3 -3
- package/dist/bin/pushary-gemini-hook.js +3 -3
- package/dist/bin/pushary-hook.js +4 -4
- package/dist/bin/pushary-login.js +3 -3
- package/dist/bin/pushary-logout.js +1 -1
- package/dist/bin/pushary-notification-hook.js +3 -3
- package/dist/bin/pushary-opencode-hook.js +3 -3
- package/dist/bin/pushary-permission-denied-hook.js +4 -4
- package/dist/bin/pushary-permission-hook.js +4 -4
- package/dist/bin/pushary-post-hook.js +3 -3
- package/dist/bin/pushary-prompt-hook.js +3 -3
- package/dist/bin/pushary-session-end-hook.js +3 -3
- package/dist/bin/pushary-session-start-hook.js +18 -3
- package/dist/bin/pushary-setup.js +39 -17
- package/dist/bin/pushary-status.js +3 -3
- package/dist/bin/pushary-stop-hook.js +3 -3
- package/dist/bin/pushary-stopfailure-hook.js +3 -3
- package/dist/bin/pushary-upgrade.js +8 -8
- package/dist/{chunk-AWHCZOZO.js → chunk-2ACC5M7F.js} +1 -1
- package/dist/{chunk-YTD6PJM7.js → chunk-2XQSN66Q.js} +1 -1
- package/dist/{chunk-CRVJCKIN.js → chunk-3HS4YGHB.js} +1 -1
- package/dist/{chunk-GQ5ZC2QY.js → chunk-4TFXV5MW.js} +1 -1
- package/dist/{chunk-BVNYTQ5I.js → chunk-CV2YD2JR.js} +2 -0
- package/dist/{chunk-YTDH3XCE.js → chunk-HDORB7WD.js} +1 -1
- package/dist/{chunk-VAMBUKXH.js → chunk-I3ORVBTP.js} +106 -14
- package/dist/{chunk-ELHCIEMM.js → chunk-I7W3UTDK.js} +16 -1
- package/dist/{chunk-ATUUQFDH.js → chunk-QCXKQJTG.js} +5 -2
- package/dist/{chunk-4IEW4ZRF.js → chunk-RQPQSJJH.js} +2 -2
- package/dist/{chunk-Z4XCN2HH.js → chunk-SQYBP3QQ.js} +2 -2
- package/dist/{chunk-TVZQMPB7.js → chunk-YXDYKECP.js} +1 -1
- package/dist/{chunk-WGKC6PU2.js → chunk-ZMKKK6DC.js} +2 -2
- package/dist/src/index.js +4 -4
- package/package.json +1 -1
|
@@ -4,16 +4,18 @@ import {
|
|
|
4
4
|
} from "../chunk-Z3Z4VK5F.js";
|
|
5
5
|
import {
|
|
6
6
|
detectClaudeVersion
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-HDORB7WD.js";
|
|
8
8
|
import {
|
|
9
9
|
describeVersionManagerPin,
|
|
10
10
|
versionManagerOf
|
|
11
11
|
} from "../chunk-GU3EJCVV.js";
|
|
12
12
|
import {
|
|
13
13
|
waitForMachineReadiness
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-2XQSN66Q.js";
|
|
15
15
|
import {
|
|
16
|
+
AGENT_CHOICES,
|
|
16
17
|
HERMES_CONFIG_SCRIPT,
|
|
18
|
+
HERMES_PIP_PACKAGE,
|
|
17
19
|
KEEP_HINT,
|
|
18
20
|
captureHookTakeover,
|
|
19
21
|
captureMcpServer,
|
|
@@ -29,7 +31,7 @@ import {
|
|
|
29
31
|
planHooks,
|
|
30
32
|
resolveHermesPython,
|
|
31
33
|
runHermesPythonScript
|
|
32
|
-
} from "../chunk-
|
|
34
|
+
} from "../chunk-QCXKQJTG.js";
|
|
33
35
|
import {
|
|
34
36
|
describeDetection,
|
|
35
37
|
detectAllAgents,
|
|
@@ -43,13 +45,13 @@ import {
|
|
|
43
45
|
shortenHome,
|
|
44
46
|
vscodeSettingsTargets,
|
|
45
47
|
writeInstructionBlock
|
|
46
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-3HS4YGHB.js";
|
|
47
49
|
import {
|
|
48
50
|
claudeWired,
|
|
49
51
|
codexWired,
|
|
50
52
|
geminiWired,
|
|
51
53
|
pusharyHookExecutable
|
|
52
|
-
} from "../chunk-
|
|
54
|
+
} from "../chunk-ZMKKK6DC.js";
|
|
53
55
|
import {
|
|
54
56
|
OPENCODE_HOOK_BINARY,
|
|
55
57
|
addOpenCodeMcpServer,
|
|
@@ -73,7 +75,7 @@ import {
|
|
|
73
75
|
isClaudeMcpSnapshot,
|
|
74
76
|
parseVersion,
|
|
75
77
|
updateClaudeMcpSnapshot
|
|
76
|
-
} from "../chunk-
|
|
78
|
+
} from "../chunk-I7W3UTDK.js";
|
|
77
79
|
import "../chunk-2LAHXHBR.js";
|
|
78
80
|
import "../chunk-DSTLA2TC.js";
|
|
79
81
|
import {
|
|
@@ -93,7 +95,7 @@ import {
|
|
|
93
95
|
replaceDaemonService,
|
|
94
96
|
stopDaemonService,
|
|
95
97
|
waitForDaemonRemoteProof
|
|
96
|
-
} from "../chunk-
|
|
98
|
+
} from "../chunk-SQYBP3QQ.js";
|
|
97
99
|
import {
|
|
98
100
|
detectProviderLiveCapabilities,
|
|
99
101
|
hasSpawnProvider,
|
|
@@ -111,10 +113,10 @@ import {
|
|
|
111
113
|
} from "../chunk-L4ZCFMWW.js";
|
|
112
114
|
import {
|
|
113
115
|
reportEvent
|
|
114
|
-
} from "../chunk-
|
|
116
|
+
} from "../chunk-YXDYKECP.js";
|
|
115
117
|
import "../chunk-F7OURW3C.js";
|
|
116
118
|
import "../chunk-L4E2BIJ2.js";
|
|
117
|
-
import "../chunk-
|
|
119
|
+
import "../chunk-2ACC5M7F.js";
|
|
118
120
|
import {
|
|
119
121
|
addCodexHookTrust,
|
|
120
122
|
addCodexHooks,
|
|
@@ -142,7 +144,7 @@ import {
|
|
|
142
144
|
readCodexMcpAuth,
|
|
143
145
|
vscodePluginDir,
|
|
144
146
|
vscodePluginMcp
|
|
145
|
-
} from "../chunk-
|
|
147
|
+
} from "../chunk-CV2YD2JR.js";
|
|
146
148
|
import {
|
|
147
149
|
confirmAppConnection,
|
|
148
150
|
connectDevice,
|
|
@@ -553,6 +555,11 @@ var reportSetupAbortWith = async (deps, reason, exitCode, keyCheck = "unknown")
|
|
|
553
555
|
});
|
|
554
556
|
var reportSetupAbort = (reason, exitCode, keyCheck) => reportSetupAbortWith(defaultDeps, reason, exitCode, keyCheck);
|
|
555
557
|
|
|
558
|
+
// src/setup/app-key.ts
|
|
559
|
+
var pickAppKey = (candidates) => candidates.fromAgents.find(
|
|
560
|
+
(candidate) => typeof candidate === "string" && candidate !== candidates.storedKey && candidate !== candidates.envKey && isValidApiKey(candidate)
|
|
561
|
+
) ?? null;
|
|
562
|
+
|
|
556
563
|
// bin/pushary-setup.ts
|
|
557
564
|
var CLAUDE_SETTINGS = claudeSettings();
|
|
558
565
|
var CLAUDE_JSON = claudeJson();
|
|
@@ -819,16 +826,16 @@ var setupHermes = async (_apiKey) => {
|
|
|
819
826
|
const python = resolveHermesPython();
|
|
820
827
|
if (!python) {
|
|
821
828
|
console.log(` ${yellow("!")} Could not locate the Python that Hermes runs in. Skipping.`);
|
|
822
|
-
noteManual(
|
|
829
|
+
noteManual(`Install the Hermes plugin by hand: <hermes-python> -m pip install ${HERMES_PIP_PACKAGE}`);
|
|
823
830
|
return "skipped";
|
|
824
831
|
}
|
|
825
832
|
const existingReceipt = readJsonSafe(HERMES_CONFIG_RECEIPT);
|
|
826
833
|
if (existingReceipt.kind !== "missing" && (existingReceipt.kind !== "ok" || !isHermesConfigReceipt(existingReceipt.value))) {
|
|
827
834
|
throw new Error(`Cannot safely configure Hermes: ${HERMES_CONFIG_RECEIPT} is unreadable or invalid.`);
|
|
828
835
|
}
|
|
829
|
-
await spinner(
|
|
836
|
+
await spinner(`Installing ${HERMES_PIP_PACKAGE} into Hermes\u2019 environment`, async () => {
|
|
830
837
|
ensurePip(python);
|
|
831
|
-
execSync2(`"${python}" -m pip install --upgrade
|
|
838
|
+
execSync2(`"${python}" -m pip install --upgrade ${HERMES_PIP_PACKAGE}`, { stdio: "pipe", timeout: 18e4 });
|
|
832
839
|
});
|
|
833
840
|
let pluginEnabled = false;
|
|
834
841
|
await spinner("Enabling plugin + routing questions to push", async () => {
|
|
@@ -1471,6 +1478,13 @@ var appMcpKeyFor = (agent) => {
|
|
|
1471
1478
|
const file = agent === "claude_code" ? CLAUDE_JSON : agent === "gemini_cli" ? GEMINI_SETTINGS : agent === "cursor" ? cursorUserMcp() : agent === "vscode" ? VSCODE_PLUGIN_MCP : null;
|
|
1472
1479
|
return file ? mcpBearerKey(readAgentJson(file), "mcpServers", "headers") : null;
|
|
1473
1480
|
};
|
|
1481
|
+
var appMcpKeyIfReadable = (agent) => {
|
|
1482
|
+
try {
|
|
1483
|
+
return appMcpKeyFor(agent);
|
|
1484
|
+
} catch {
|
|
1485
|
+
return null;
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1474
1488
|
var captureTakeoverReceipt = (agent) => {
|
|
1475
1489
|
const hookFile = HOOK_FILES[agent]?.();
|
|
1476
1490
|
if (!hookFile) return;
|
|
@@ -1806,6 +1820,8 @@ var main = async () => {
|
|
|
1806
1820
|
const envCheck = ambientEligible && envKey && isValidApiKey(envKey) ? await usableStoredKey(envKey) : null;
|
|
1807
1821
|
const storedCheck = ambientEligible && envCheck === null && storedKey !== null && isValidApiKey(storedKey) && // login writes both, so without this the same key is probed twice.
|
|
1808
1822
|
storedKey !== envKey ? await usableStoredKey(storedKey) : null;
|
|
1823
|
+
const appKey = ambientEligible && envCheck === null && storedCheck === null ? pickAppKey({ fromAgents: AGENT_CHOICES.map(appMcpKeyIfReadable), storedKey, envKey }) : null;
|
|
1824
|
+
const appKeyCheck = appKey === null ? null : await usableStoredKey(appKey);
|
|
1809
1825
|
let storedKeyCheck = null;
|
|
1810
1826
|
if (flagKey) {
|
|
1811
1827
|
const masked = `${flagKey.slice(0, 8)}...${flagKey.slice(-4)}`;
|
|
@@ -1831,6 +1847,12 @@ var main = async () => {
|
|
|
1831
1847
|
const apiKey = await input({ message: "API key:" });
|
|
1832
1848
|
trimmedKey = apiKey.trim();
|
|
1833
1849
|
}
|
|
1850
|
+
} else if (appKey !== null && appKeyCheck !== null) {
|
|
1851
|
+
const masked = `${appKey.slice(0, 8)}...${appKey.slice(-4)}`;
|
|
1852
|
+
console.log(` ${check} Using the key the Pushary Mac app is signed in with: ${dim(masked)}`);
|
|
1853
|
+
console.log();
|
|
1854
|
+
trimmedKey = appKey;
|
|
1855
|
+
storedKeyCheck = appKeyCheck;
|
|
1834
1856
|
} else if (options.dryRun) {
|
|
1835
1857
|
console.log(` ${dim("No key on this machine. A real run would connect one first.")}`);
|
|
1836
1858
|
console.log();
|
|
@@ -1950,12 +1972,12 @@ var main = async () => {
|
|
|
1950
1972
|
return pending;
|
|
1951
1973
|
};
|
|
1952
1974
|
const appAccountMatches = async (agent) => {
|
|
1953
|
-
const
|
|
1954
|
-
if (!
|
|
1955
|
-
if (
|
|
1975
|
+
const appKey2 = appMcpKeyFor(agent);
|
|
1976
|
+
if (!appKey2) return false;
|
|
1977
|
+
if (appKey2 === trimmedKey) return true;
|
|
1956
1978
|
const [cliAccount, appAccount] = await Promise.all([
|
|
1957
1979
|
accountCheckFor(trimmedKey),
|
|
1958
|
-
accountCheckFor(
|
|
1980
|
+
accountCheckFor(appKey2)
|
|
1959
1981
|
]);
|
|
1960
1982
|
return samePusharyAccount(cliAccount, appAccount);
|
|
1961
1983
|
};
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
describeLastSeen,
|
|
4
4
|
listMachines
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-2XQSN66Q.js";
|
|
6
|
+
import "../chunk-2ACC5M7F.js";
|
|
7
|
+
import "../chunk-CV2YD2JR.js";
|
|
8
8
|
import {
|
|
9
9
|
describeReach,
|
|
10
10
|
fetchChannels,
|
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
handleStop,
|
|
7
7
|
handleSubagentStop,
|
|
8
8
|
isSubagentStop
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-YXDYKECP.js";
|
|
10
10
|
import "../chunk-F7OURW3C.js";
|
|
11
11
|
import "../chunk-L4E2BIJ2.js";
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-2ACC5M7F.js";
|
|
13
|
+
import "../chunk-CV2YD2JR.js";
|
|
14
14
|
import "../chunk-BSZYIAZL.js";
|
|
15
15
|
import "../chunk-SAF6HGAA.js";
|
|
16
16
|
import "../chunk-7QLSKOSU.js";
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
} from "../chunk-6CUUA7HO.js";
|
|
5
5
|
import {
|
|
6
6
|
handleStopFailure
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-YXDYKECP.js";
|
|
8
8
|
import "../chunk-F7OURW3C.js";
|
|
9
9
|
import "../chunk-L4E2BIJ2.js";
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-2ACC5M7F.js";
|
|
11
|
+
import "../chunk-CV2YD2JR.js";
|
|
12
12
|
import "../chunk-BSZYIAZL.js";
|
|
13
13
|
import "../chunk-SAF6HGAA.js";
|
|
14
14
|
import "../chunk-7QLSKOSU.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
reapplyAllAgents
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-I3ORVBTP.js";
|
|
5
|
+
import "../chunk-HDORB7WD.js";
|
|
6
6
|
import {
|
|
7
7
|
waitForMachineReadiness
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
8
|
+
} from "../chunk-2XQSN66Q.js";
|
|
9
|
+
import "../chunk-ZMKKK6DC.js";
|
|
10
|
+
import "../chunk-I7W3UTDK.js";
|
|
11
11
|
import "../chunk-2LAHXHBR.js";
|
|
12
12
|
import "../chunk-EZIEXHYM.js";
|
|
13
13
|
import {
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
replaceDaemonService,
|
|
21
21
|
stopDaemonService,
|
|
22
22
|
waitForDaemonRemoteProof
|
|
23
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-SQYBP3QQ.js";
|
|
24
24
|
import {
|
|
25
25
|
detectProviderLiveCapabilities,
|
|
26
26
|
hasSpawnProvider,
|
|
@@ -34,14 +34,14 @@ import {
|
|
|
34
34
|
npmErrorMessage,
|
|
35
35
|
resolveGlobalBinary
|
|
36
36
|
} from "../chunk-L4ZCFMWW.js";
|
|
37
|
-
import "../chunk-
|
|
37
|
+
import "../chunk-2ACC5M7F.js";
|
|
38
38
|
import {
|
|
39
39
|
claudeJson,
|
|
40
40
|
codexConfigToml,
|
|
41
41
|
cursorPluginDir,
|
|
42
42
|
geminiSettings,
|
|
43
43
|
vscodePluginDir
|
|
44
|
-
} from "../chunk-
|
|
44
|
+
} from "../chunk-CV2YD2JR.js";
|
|
45
45
|
import {
|
|
46
46
|
exitOnHelpFlag
|
|
47
47
|
} from "../chunk-BVBEURWJ.js";
|
|
@@ -288,6 +288,7 @@ var vscodePluginMcp = () => join2(vscodePluginDir(), ".mcp.json");
|
|
|
288
288
|
var claudeSettingsLocal = () => join2(homedir2(), ".claude", "settings.local.json");
|
|
289
289
|
var pusharyDir = () => join2(homedir2(), ".pushary");
|
|
290
290
|
var claudeMcpReceipt = () => join2(pusharyDir(), "setup", "claude-mcp.json");
|
|
291
|
+
var claudeRegistrationReceipt = () => join2(pusharyDir(), "setup", "claude-registration.json");
|
|
291
292
|
var hermesConfigReceipt = () => join2(pusharyDir(), "setup", "hermes-config.json");
|
|
292
293
|
var hookTakeoverReceipt = (agent) => join2(pusharyDir(), "setup", `hook-takeover-${agent}.json`);
|
|
293
294
|
var codexSkillDir2 = () => join2(codexHome(), "skills", "pushary");
|
|
@@ -332,6 +333,7 @@ export {
|
|
|
332
333
|
claudeSettingsLocal,
|
|
333
334
|
pusharyDir,
|
|
334
335
|
claudeMcpReceipt,
|
|
336
|
+
claudeRegistrationReceipt,
|
|
335
337
|
hermesConfigReceipt,
|
|
336
338
|
hookTakeoverReceipt,
|
|
337
339
|
codexSkillDir2,
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detectClaudeVersion
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HDORB7WD.js";
|
|
4
4
|
import {
|
|
5
5
|
claudeWired,
|
|
6
6
|
codexWired,
|
|
7
7
|
geminiWired
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ZMKKK6DC.js";
|
|
9
9
|
import {
|
|
10
|
+
CLAUDE_HOOK_EVENTS,
|
|
10
11
|
GEMINI_HOOK_BINARY,
|
|
11
12
|
addClaudeMcpServer,
|
|
12
13
|
addGeminiHooks,
|
|
13
14
|
addGeminiMcpServer,
|
|
14
15
|
addPusharyHooks,
|
|
15
16
|
addPusharyToolPermissions,
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
formatVersion,
|
|
18
|
+
hasGeminiHooks,
|
|
19
|
+
needsReregistration,
|
|
20
|
+
registrationSignatures,
|
|
21
|
+
supportedClaudeEvents
|
|
22
|
+
} from "./chunk-I7W3UTDK.js";
|
|
18
23
|
import {
|
|
19
24
|
guardBinary
|
|
20
25
|
} from "./chunk-EZIEXHYM.js";
|
|
@@ -27,21 +32,84 @@ import {
|
|
|
27
32
|
addCodexHookTrust,
|
|
28
33
|
addCodexHooks,
|
|
29
34
|
addCodexMcpServer,
|
|
35
|
+
claudeRegistrationReceipt,
|
|
30
36
|
codexConfigToml,
|
|
31
37
|
codexHookPositions,
|
|
32
38
|
codexHooksJson,
|
|
33
39
|
hasCodexHooks,
|
|
34
40
|
vscodePluginMcp
|
|
35
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-CV2YD2JR.js";
|
|
36
42
|
import {
|
|
37
|
-
readJsonSafe
|
|
43
|
+
readJsonSafe,
|
|
44
|
+
writeJsonAtomic
|
|
38
45
|
} from "./chunk-4LL6LG5X.js";
|
|
46
|
+
import {
|
|
47
|
+
HOOK_LOCATOR_BINARY
|
|
48
|
+
} from "./chunk-VNMKIJZB.js";
|
|
39
49
|
|
|
40
50
|
// src/reapply.ts
|
|
41
|
-
import { join
|
|
51
|
+
import { join } from "path";
|
|
42
52
|
import { homedir } from "os";
|
|
43
|
-
import {
|
|
53
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
44
54
|
import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
|
|
55
|
+
|
|
56
|
+
// src/reregister.ts
|
|
57
|
+
var asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
58
|
+
var commandsUnder = (settings) => {
|
|
59
|
+
const hooks = asRecord(settings?.hooks);
|
|
60
|
+
if (!hooks) return [];
|
|
61
|
+
const found = [];
|
|
62
|
+
for (const [event, value] of Object.entries(hooks)) {
|
|
63
|
+
if (!Array.isArray(value)) continue;
|
|
64
|
+
for (const item of value) {
|
|
65
|
+
const inner = asRecord(item)?.hooks;
|
|
66
|
+
if (!Array.isArray(inner)) continue;
|
|
67
|
+
for (const hook of inner) {
|
|
68
|
+
const command = asRecord(hook)?.command;
|
|
69
|
+
if (typeof command === "string") found.push({ event, command });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return found;
|
|
74
|
+
};
|
|
75
|
+
var segments = (command) => command.split(/[\s/\\"']+/).map((segment) => segment.replace(/\.(cmd|exe)$/i, ""));
|
|
76
|
+
var CLI_BINARIES = new Set(CLAUDE_HOOK_EVENTS.map((hook) => hook.binary));
|
|
77
|
+
var namesLocator = (command) => segments(command).includes(HOOK_LOCATOR_BINARY);
|
|
78
|
+
var namesCliBinary = (command) => segments(command).some((segment) => CLI_BINARIES.has(segment));
|
|
79
|
+
var registrationHolder = (settings) => {
|
|
80
|
+
const commands = commandsUnder(settings);
|
|
81
|
+
if (commands.some(({ command }) => namesLocator(command))) return "app";
|
|
82
|
+
return commands.some(({ command }) => namesCliBinary(command)) ? "cli" : "none";
|
|
83
|
+
};
|
|
84
|
+
var registeredPusharyEvents = (settings) => new Set(
|
|
85
|
+
commandsUnder(settings).filter(({ command }) => namesLocator(command) || namesCliBinary(command)).map(({ event }) => event)
|
|
86
|
+
);
|
|
87
|
+
var reregisterVerdict = ({ settings, stored, version }) => {
|
|
88
|
+
const holder = registrationHolder(settings);
|
|
89
|
+
if (holder === "none") return { kind: "not_wired" };
|
|
90
|
+
if (holder === "app") return { kind: "app_owned" };
|
|
91
|
+
if (!needsReregistration(stored, version)) return { kind: "current" };
|
|
92
|
+
const supported = new Set(supportedClaudeEvents(version).map((hook) => hook.event));
|
|
93
|
+
const present = registeredPusharyEvents(settings);
|
|
94
|
+
const missing = [...supported].filter((event) => !present.has(event));
|
|
95
|
+
const extra = [...present].filter((event) => !supported.has(event));
|
|
96
|
+
return missing.length > 0 || extra.length > 0 ? { kind: "stale", version, missing, extra } : { kind: "record_only", version };
|
|
97
|
+
};
|
|
98
|
+
var receiptFor = (version, now = /* @__PURE__ */ new Date()) => ({
|
|
99
|
+
signatures: registrationSignatures(supportedClaudeEvents(version), version),
|
|
100
|
+
version: version ? formatVersion(version) : null,
|
|
101
|
+
recordedAt: now.toISOString()
|
|
102
|
+
});
|
|
103
|
+
var storedSignatures = (raw) => {
|
|
104
|
+
const signatures = asRecord(asRecord(raw)?.signatures);
|
|
105
|
+
if (!signatures) return void 0;
|
|
106
|
+
const entries = Object.entries(signatures).filter(
|
|
107
|
+
(pair) => typeof pair[1] === "string"
|
|
108
|
+
);
|
|
109
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// src/reapply.ts
|
|
45
113
|
var CLAUDE_SETTINGS = join(homedir(), ".claude", "settings.json");
|
|
46
114
|
var CLAUDE_JSON = join(homedir(), ".claude.json");
|
|
47
115
|
var readJson = (filePath) => {
|
|
@@ -50,11 +118,7 @@ var readJson = (filePath) => {
|
|
|
50
118
|
if (result.kind === "missing") return {};
|
|
51
119
|
return null;
|
|
52
120
|
};
|
|
53
|
-
var writeJson = (filePath, data) =>
|
|
54
|
-
const dir = dirname(filePath);
|
|
55
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
56
|
-
writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
57
|
-
};
|
|
121
|
+
var writeJson = (filePath, data) => writeJsonAtomic(filePath, data);
|
|
58
122
|
var hasPusharyClaudeHooks = (settings) => JSON.stringify(settings.hooks ?? {}).includes("pushary-hook");
|
|
59
123
|
var hasPusharyMcp = (claudeJson) => !!claudeJson.mcpServers?.pushary;
|
|
60
124
|
var reapplyClaudeSettings = (apiKey, paths = {}) => {
|
|
@@ -72,7 +136,7 @@ var reapplyClaudeSettings = (apiKey, paths = {}) => {
|
|
|
72
136
|
if (!settingsWritable) throw new Error("settings.json could not be parsed");
|
|
73
137
|
const s = settings;
|
|
74
138
|
addPusharyToolPermissions(s);
|
|
75
|
-
addPusharyHooks(s, resolveGlobalBinDir("pushary-hook"), detectClaudeVersion());
|
|
139
|
+
addPusharyHooks(s, resolveGlobalBinDir("pushary-hook"), (paths.detectVersion ?? detectClaudeVersion)());
|
|
76
140
|
writeJson(settingsPath, s);
|
|
77
141
|
hooks = true;
|
|
78
142
|
} catch {
|
|
@@ -89,6 +153,33 @@ var reapplyClaudeSettings = (apiKey, paths = {}) => {
|
|
|
89
153
|
}
|
|
90
154
|
return { configured: true, reapplied: hooks || mcp, hooks, mcp };
|
|
91
155
|
};
|
|
156
|
+
var reapplyClaudeForVersion = (apiKey, paths = {}) => {
|
|
157
|
+
const idle = { verdict: "current", rewrote: false, missing: [] };
|
|
158
|
+
try {
|
|
159
|
+
const settingsPath = paths.settingsPath ?? CLAUDE_SETTINGS;
|
|
160
|
+
const receiptPath = paths.receiptPath ?? claudeRegistrationReceipt();
|
|
161
|
+
const version = (paths.detectVersion ?? detectClaudeVersion)();
|
|
162
|
+
const receipt = readJsonSafe(receiptPath);
|
|
163
|
+
const verdict = reregisterVerdict({
|
|
164
|
+
settings: readJson(settingsPath),
|
|
165
|
+
stored: storedSignatures(receipt.kind === "ok" ? receipt.value : void 0),
|
|
166
|
+
version
|
|
167
|
+
});
|
|
168
|
+
if (verdict.kind === "not_wired" || verdict.kind === "app_owned" || verdict.kind === "current") {
|
|
169
|
+
return { verdict: verdict.kind, rewrote: false, missing: [] };
|
|
170
|
+
}
|
|
171
|
+
const rewrote = verdict.kind === "stale" ? reapplyClaudeSettings(apiKey, { ...paths, settingsPath }).hooks : false;
|
|
172
|
+
if (verdict.kind === "stale" && !rewrote) return { verdict: "stale", rewrote: false, missing: verdict.missing };
|
|
173
|
+
writeJsonAtomic(receiptPath, receiptFor(version));
|
|
174
|
+
return {
|
|
175
|
+
verdict: verdict.kind,
|
|
176
|
+
rewrote,
|
|
177
|
+
missing: verdict.kind === "stale" ? verdict.missing : []
|
|
178
|
+
};
|
|
179
|
+
} catch {
|
|
180
|
+
return idle;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
92
183
|
var readToml = (filePath) => {
|
|
93
184
|
try {
|
|
94
185
|
const raw = readFileSync(filePath, "utf-8");
|
|
@@ -205,6 +296,7 @@ var reapplyAllAgents = (apiKey) => {
|
|
|
205
296
|
};
|
|
206
297
|
|
|
207
298
|
export {
|
|
299
|
+
reapplyClaudeForVersion,
|
|
208
300
|
inspectConfiguredManagedProviders,
|
|
209
301
|
reapplyAllAgents
|
|
210
302
|
};
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-EZIEXHYM.js";
|
|
8
8
|
import {
|
|
9
9
|
isProtectedByScope
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-CV2YD2JR.js";
|
|
11
11
|
import {
|
|
12
12
|
HOOK_BUDGETS,
|
|
13
13
|
HOOK_LOCATOR_BINARY
|
|
@@ -28,6 +28,7 @@ var compareVersion = (a, b) => {
|
|
|
28
28
|
return 0;
|
|
29
29
|
};
|
|
30
30
|
var atLeast = (version, floor) => compareVersion(version, floor) >= 0;
|
|
31
|
+
var formatVersion = (version) => version.join(".");
|
|
31
32
|
|
|
32
33
|
// src/claude-events.ts
|
|
33
34
|
var GATED_TOOLS = [...PRETOOLUSE_GATED_TOOLS, ...PRETOOLUSE_PHONE_ANSWERED_TOOLS].join("|");
|
|
@@ -58,6 +59,16 @@ var CLAUDE_HOOK_EVENTS = [
|
|
|
58
59
|
{ event: "Elicitation", binary: "pushary-elicitation-hook", timeout: HOOK_BUDGETS.claude.budgetSeconds, delivery: "approval", since: OBSERVED }
|
|
59
60
|
];
|
|
60
61
|
var supportedClaudeEvents = (version) => CLAUDE_HOOK_EVENTS.filter((hook) => version ? atLeast(version, hook.since) : hook.since === ESTABLISHED);
|
|
62
|
+
var registrationSignatures = (events, version) => Object.fromEntries(
|
|
63
|
+
events.map((hook) => [hook.event, `registered|${version ? formatVersion(version) : "unknown"}`])
|
|
64
|
+
);
|
|
65
|
+
var needsReregistration = (stored, version) => {
|
|
66
|
+
const expected = registrationSignatures(supportedClaudeEvents(version), version);
|
|
67
|
+
const keys = Object.keys(expected);
|
|
68
|
+
if (!stored) return true;
|
|
69
|
+
if (keys.length !== Object.keys(stored).length) return true;
|
|
70
|
+
return keys.some((event) => stored[event] !== expected[event]);
|
|
71
|
+
};
|
|
61
72
|
|
|
62
73
|
// src/claude-config.ts
|
|
63
74
|
import { isDeepStrictEqual } from "util";
|
|
@@ -331,7 +342,11 @@ var missingGeminiHookEvents = (settings) => {
|
|
|
331
342
|
export {
|
|
332
343
|
parseVersion,
|
|
333
344
|
compareVersion,
|
|
345
|
+
formatVersion,
|
|
334
346
|
CLAUDE_HOOK_EVENTS,
|
|
347
|
+
supportedClaudeEvents,
|
|
348
|
+
registrationSignatures,
|
|
349
|
+
needsReregistration,
|
|
335
350
|
addClaudeMcpServer,
|
|
336
351
|
isClaudeMcpSnapshot,
|
|
337
352
|
captureClaudeMcpServer,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isBridgeLocator
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3HS4YGHB.js";
|
|
4
4
|
import {
|
|
5
5
|
pusharyHookExecutable
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZMKKK6DC.js";
|
|
7
7
|
import {
|
|
8
8
|
BELL_HOOK_BINARY
|
|
9
9
|
} from "./chunk-DSTLA2TC.js";
|
|
@@ -31,6 +31,7 @@ var isHermesConfigReceipt = (value) => {
|
|
|
31
31
|
if (!isRecord(value)) return false;
|
|
32
32
|
return ["security", "approval", "transport", "fallback", "plugins", "enabled", "agent", "disabled"].every((key) => isSnapshot(value[key])) && typeof value.pushary_enabled === "boolean" && typeof value.clarify_disabled === "boolean";
|
|
33
33
|
};
|
|
34
|
+
var HERMES_PIP_PACKAGE = "hermes-plugin-pushary";
|
|
34
35
|
var HERMES_CONFIG_SCRIPT = String.raw`
|
|
35
36
|
import json, os, sys
|
|
36
37
|
from hermes_cli.config import load_config, save_config
|
|
@@ -514,11 +515,13 @@ var describeHookOwnership = (entries, names) => {
|
|
|
514
515
|
|
|
515
516
|
export {
|
|
516
517
|
isHermesConfigReceipt,
|
|
518
|
+
HERMES_PIP_PACKAGE,
|
|
517
519
|
HERMES_CONFIG_SCRIPT,
|
|
518
520
|
resolveHermesPython,
|
|
519
521
|
runHermesPythonScript,
|
|
520
522
|
createGuards,
|
|
521
523
|
describeSetupSideEffects,
|
|
524
|
+
AGENT_CHOICES,
|
|
522
525
|
effectiveVerify,
|
|
523
526
|
effectiveControlMode,
|
|
524
527
|
parseSetupOptions,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
repoKeyFor,
|
|
22
22
|
settleQuestionsForToolUse,
|
|
23
23
|
throttlePass
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-YXDYKECP.js";
|
|
25
25
|
import {
|
|
26
26
|
DEFAULT_SESSION,
|
|
27
27
|
askUser,
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
} from "./chunk-L4E2BIJ2.js";
|
|
42
42
|
import {
|
|
43
43
|
getMachineId
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-2ACC5M7F.js";
|
|
45
45
|
import {
|
|
46
46
|
getApiKey,
|
|
47
47
|
getBaseUrl
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
} from "./chunk-L4ZCFMWW.js";
|
|
8
8
|
import {
|
|
9
9
|
getMachineId
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2ACC5M7F.js";
|
|
11
11
|
import {
|
|
12
12
|
pusharyDir
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-CV2YD2JR.js";
|
|
14
14
|
import {
|
|
15
15
|
getPackageVersion
|
|
16
16
|
} from "./chunk-DINDL2CF.js";
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
CLAUDE_HOOK_EVENTS,
|
|
3
3
|
GEMINI_HOOK_EVENTS,
|
|
4
4
|
hasGeminiHooks
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-I7W3UTDK.js";
|
|
6
6
|
import {
|
|
7
7
|
CODEX_HOOK_EVENTS,
|
|
8
8
|
hasCodexHooks
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-CV2YD2JR.js";
|
|
10
10
|
import {
|
|
11
11
|
CURSOR_GATE_EVENTS,
|
|
12
12
|
HOOK_LOCATOR_BINARY
|
package/dist/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handlePreToolUse
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-RQPQSJJH.js";
|
|
4
4
|
import "../chunk-2LAHXHBR.js";
|
|
5
5
|
import {
|
|
6
6
|
fetchAccountPublicKey
|
|
@@ -16,15 +16,15 @@ import {
|
|
|
16
16
|
handlePostToolUse,
|
|
17
17
|
handleStop,
|
|
18
18
|
reportEvent
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-YXDYKECP.js";
|
|
20
20
|
import {
|
|
21
21
|
askUser,
|
|
22
22
|
cancelQuestion,
|
|
23
23
|
waitForAnswer
|
|
24
24
|
} from "../chunk-F7OURW3C.js";
|
|
25
25
|
import "../chunk-L4E2BIJ2.js";
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
26
|
+
import "../chunk-2ACC5M7F.js";
|
|
27
|
+
import "../chunk-CV2YD2JR.js";
|
|
28
28
|
import "../chunk-BSZYIAZL.js";
|
|
29
29
|
import "../chunk-SAF6HGAA.js";
|
|
30
30
|
import "../chunk-7QLSKOSU.js";
|