@pushary/agent-hooks 0.94.0 → 0.95.1
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/data/SKILL.md +31 -24
- package/data/cursor-plugin/.cursor-plugin/plugin.json +1 -1
- package/data/cursor-plugin/CONTRIBUTING.md +31 -19
- package/data/cursor-plugin/skills/pushary/SKILL.md +30 -23
- package/data/vscode-plugin/.claude-plugin/plugin.json +1 -1
- package/data/vscode-plugin/CONTRIBUTING.md +31 -19
- package/data/vscode-plugin/skills/pushary/SKILL.md +30 -23
- package/dist/bin/pushary-bell-hook.js +26 -5
- package/dist/bin/pushary-bell.js +8 -8
- package/dist/bin/pushary-claude.js +343 -365
- package/dist/bin/pushary-clean.js +28 -23
- package/dist/bin/pushary-codex-bridge.js +12 -12
- package/dist/bin/pushary-codex-hook.js +28 -10
- package/dist/bin/pushary-codex.js +7 -7
- package/dist/bin/pushary-connect.js +9 -9
- package/dist/bin/pushary-daemon.js +41 -26
- package/dist/bin/pushary-disconnect.js +8 -6
- package/dist/bin/pushary-doctor.js +42 -39
- package/dist/bin/pushary-elicitation-hook.js +24 -4
- package/dist/bin/pushary-gemini-bridge.js +12 -12
- package/dist/bin/pushary-gemini-hook.js +27 -9
- package/dist/bin/pushary-hook.js +28 -11
- package/dist/bin/pushary-login.js +10 -10
- package/dist/bin/pushary-logout.js +7 -7
- package/dist/bin/pushary-mode.js +6 -6
- package/dist/bin/pushary-notification-hook.js +26 -8
- package/dist/bin/pushary-opencode-hook.js +27 -9
- package/dist/bin/pushary-permission-denied-hook.js +29 -11
- package/dist/bin/pushary-permission-hook.js +29 -11
- package/dist/bin/pushary-post-hook.js +26 -8
- package/dist/bin/pushary-prompt-hook.js +26 -8
- package/dist/bin/pushary-session-end-hook.js +30 -9
- package/dist/bin/pushary-session-start-hook.js +29 -14
- package/dist/bin/pushary-setup.js +59 -53
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +11 -11
- package/dist/bin/pushary-stop-hook.js +26 -8
- package/dist/bin/pushary-stopfailure-hook.js +26 -8
- package/dist/bin/pushary-suggestions.js +3 -3
- package/dist/bin/pushary-transcript-register.d.ts +1 -0
- package/dist/bin/pushary-transcript-register.js +42 -0
- package/dist/bin/pushary-transcripts.js +4 -4
- package/dist/bin/pushary-upgrade.js +19 -18
- package/dist/bin/pushary-wait.js +6 -6
- package/dist/{chunk-Y6XXFXVB.js → chunk-3F4VV5TS.js} +1 -1
- package/dist/chunk-77U3ZVV6.js +86 -0
- package/dist/{chunk-RH3TM7TO.js → chunk-7MGF5Q7G.js} +1 -1
- package/dist/{chunk-WY4ALDYN.js → chunk-AQ5OAYOH.js} +1 -1
- package/dist/chunk-BWNU4MX4.js +185 -0
- package/dist/{chunk-OYNPLEXP.js → chunk-C2MV4G4A.js} +1 -1
- package/dist/chunk-CC625NRG.js +503 -0
- package/dist/{chunk-ZTJF6ANY.js → chunk-CU5KI425.js} +2 -2
- package/dist/{chunk-HSAVPZ46.js → chunk-IFCS6LXB.js} +3 -3
- package/dist/{chunk-36LR2LOT.js → chunk-IP63LMZM.js} +10 -8
- package/dist/{chunk-BSEAOCCQ.js → chunk-IZRI4M3C.js} +1 -1
- package/dist/{chunk-5HGLZGI4.js → chunk-J55K6YS4.js} +6 -5
- package/dist/{chunk-6BIMJIRG.js → chunk-JSASMV3H.js} +1 -1
- package/dist/{chunk-6CUUA7HO.js → chunk-K7ZZGI2Y.js} +7 -1
- package/dist/{chunk-TDUTNYAQ.js → chunk-M64I4T7J.js} +1 -1
- package/dist/{chunk-ZO2XG3CX.js → chunk-MF64S7WO.js} +1 -1
- package/dist/chunk-N6FAXQDD.js +276 -0
- package/dist/{chunk-UZFVNEEU.js → chunk-PDFVIRPB.js} +1 -1
- package/dist/chunk-PQ4K74WL.js +30 -0
- package/dist/{chunk-ROHFVGXM.js → chunk-R7NPGCSD.js} +1 -1
- package/dist/{chunk-QGA2ZB4I.js → chunk-RNH2AE52.js} +1 -1
- package/dist/{chunk-NVPYRDCT.js → chunk-SSQ5X6SA.js} +1 -1
- package/dist/{chunk-OB4RF2TF.js → chunk-T23EGPRI.js} +1 -1
- package/dist/{chunk-ODL52O5V.js → chunk-T5B3LRYF.js} +1 -1
- package/dist/{chunk-Y3UGCQQC.js → chunk-TTO76NZJ.js} +1 -1
- package/dist/{chunk-46P3VES5.js → chunk-UFGDCMUD.js} +2 -1
- package/dist/{chunk-2ORRI66J.js → chunk-UQSKCQBO.js} +1 -1
- package/dist/{chunk-4PE2SQVM.js → chunk-VLKEAYJ4.js} +1 -1
- package/dist/chunk-WJZUTMMU.js +194 -0
- package/dist/{chunk-QKNLW7H6.js → chunk-Y24D5ZWS.js} +7 -7
- package/dist/{chunk-YANV5TGK.js → chunk-YPYPI6BG.js} +8 -90
- package/dist/{chunk-6WYL3XIP.js → chunk-ZOR5OJZJ.js} +4 -3
- package/dist/chunk-ZW3KAWTM.js +266 -0
- package/dist/src/index.js +11 -11
- package/package.json +3 -2
- package/dist/chunk-FYOIW5RV.js +0 -539
- package/dist/chunk-RX75MRGC.js +0 -368
- /package/dist/{chunk-Z6CP5ZZD.js → chunk-VOWZ5VOO.js} +0 -0
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
reapplyAllAgents
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-IP63LMZM.js";
|
|
5
|
+
import "../chunk-MF64S7WO.js";
|
|
6
6
|
import {
|
|
7
7
|
waitForMachineReadiness
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import
|
|
11
|
-
|
|
8
|
+
} from "../chunk-RNH2AE52.js";
|
|
9
|
+
import "../chunk-WJZUTMMU.js";
|
|
10
|
+
import {
|
|
11
|
+
detectProviderLiveCapabilities,
|
|
12
|
+
hasSpawnProvider,
|
|
13
|
+
resolveControlPolicy
|
|
14
|
+
} from "../chunk-3OXHYPZG.js";
|
|
15
|
+
import "../chunk-IFCS6LXB.js";
|
|
12
16
|
import {
|
|
13
17
|
daemonHasRemoteProof,
|
|
14
18
|
daemonServiceManagerAvailable,
|
|
@@ -19,12 +23,9 @@ import {
|
|
|
19
23
|
replaceDaemonService,
|
|
20
24
|
stopDaemonService,
|
|
21
25
|
waitForDaemonRemoteProof
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import
|
|
24
|
-
|
|
25
|
-
hasSpawnProvider,
|
|
26
|
-
resolveControlPolicy
|
|
27
|
-
} from "../chunk-3OXHYPZG.js";
|
|
26
|
+
} from "../chunk-CU5KI425.js";
|
|
27
|
+
import "../chunk-BWNU4MX4.js";
|
|
28
|
+
import "../chunk-EZIEXHYM.js";
|
|
28
29
|
import {
|
|
29
30
|
needsShell
|
|
30
31
|
} from "../chunk-XHKBHWLX.js";
|
|
@@ -33,15 +34,15 @@ import {
|
|
|
33
34
|
npmErrorMessage,
|
|
34
35
|
resolveGlobalBinary
|
|
35
36
|
} from "../chunk-L4ZCFMWW.js";
|
|
36
|
-
import "../chunk-
|
|
37
|
-
import "../chunk-
|
|
37
|
+
import "../chunk-TTO76NZJ.js";
|
|
38
|
+
import "../chunk-SSQ5X6SA.js";
|
|
38
39
|
import {
|
|
39
40
|
claudeJson,
|
|
40
41
|
codexConfigToml,
|
|
41
42
|
cursorPluginDir,
|
|
42
43
|
geminiSettings,
|
|
43
44
|
vscodePluginDir
|
|
44
|
-
} from "../chunk-
|
|
45
|
+
} from "../chunk-3F4VV5TS.js";
|
|
45
46
|
import {
|
|
46
47
|
exitOnHelpFlag
|
|
47
48
|
} from "../chunk-BVBEURWJ.js";
|
|
@@ -51,15 +52,15 @@ import {
|
|
|
51
52
|
} from "../chunk-DINDL2CF.js";
|
|
52
53
|
import {
|
|
53
54
|
readControlMode
|
|
54
|
-
} from "../chunk-
|
|
55
|
+
} from "../chunk-JSASMV3H.js";
|
|
55
56
|
import "../chunk-BC3VCZ3E.js";
|
|
56
57
|
import "../chunk-KZERVKTD.js";
|
|
57
|
-
import "../chunk-
|
|
58
|
+
import "../chunk-T5B3LRYF.js";
|
|
58
59
|
import "../chunk-4LL6LG5X.js";
|
|
59
60
|
import {
|
|
60
61
|
getApiKey
|
|
61
62
|
} from "../chunk-2UMNXADU.js";
|
|
62
|
-
import "../chunk-
|
|
63
|
+
import "../chunk-VOWZ5VOO.js";
|
|
63
64
|
|
|
64
65
|
// bin/pushary-upgrade.ts
|
|
65
66
|
import { existsSync } from "fs";
|
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -4,18 +4,18 @@ import {
|
|
|
4
4
|
} from "../chunk-IIENZE2J.js";
|
|
5
5
|
import {
|
|
6
6
|
exitOnFailedResponse
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-AQ5OAYOH.js";
|
|
8
|
+
import "../chunk-PDFVIRPB.js";
|
|
9
9
|
import {
|
|
10
10
|
createIo
|
|
11
11
|
} from "../chunk-5RUIFDTP.js";
|
|
12
|
-
import {
|
|
13
|
-
rejectUnknownFlags
|
|
14
|
-
} from "../chunk-GMXKITVA.js";
|
|
15
12
|
import {
|
|
16
13
|
exitOnHelpFlag
|
|
17
14
|
} from "../chunk-BVBEURWJ.js";
|
|
18
15
|
import "../chunk-43GMYSS4.js";
|
|
16
|
+
import {
|
|
17
|
+
rejectUnknownFlags
|
|
18
|
+
} from "../chunk-GMXKITVA.js";
|
|
19
19
|
import "../chunk-DINDL2CF.js";
|
|
20
20
|
import "../chunk-SAF6HGAA.js";
|
|
21
21
|
import {
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
getApiKey,
|
|
29
29
|
getBaseUrl
|
|
30
30
|
} from "../chunk-2UMNXADU.js";
|
|
31
|
-
import "../chunk-
|
|
31
|
+
import "../chunk-VOWZ5VOO.js";
|
|
32
32
|
|
|
33
33
|
// bin/pushary-wait.ts
|
|
34
34
|
exitOnHelpFlag("wait");
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HOOK_LOCATOR_BINARY
|
|
3
|
+
} from "./chunk-VOWZ5VOO.js";
|
|
4
|
+
|
|
5
|
+
// src/diagnostics/bridge.ts
|
|
6
|
+
import { execFileSync } from "child_process";
|
|
7
|
+
import { existsSync, readFileSync } from "fs";
|
|
8
|
+
import { homedir } from "os";
|
|
9
|
+
import { dirname, join } from "path";
|
|
10
|
+
var BRIDGE_BUNDLE_IDENTIFIER = "com.pushary.app";
|
|
11
|
+
var BRIDGE_HELPER_SUFFIX = "/Contents/Helpers/pushary-bridge";
|
|
12
|
+
var BRIDGE_BUNDLE_ROOTS = ["/Applications/Pushary.app", "$HOME/Applications/Pushary.app"];
|
|
13
|
+
var expandHome = (path, home) => path.replaceAll("$HOME", home);
|
|
14
|
+
var parseBridgeStub = (contents, stubPath) => {
|
|
15
|
+
const helperSuffix = contents.match(/^H=(\S+)$/m)?.[1] ?? BRIDGE_HELPER_SUFFIX;
|
|
16
|
+
const cachePath = contents.match(/^C="([^"\n]+)"$/m)?.[1] ?? join(dirname(stubPath), ".bridge-cache");
|
|
17
|
+
const rootsLine = contents.match(/^for P in ((?:"[^"\n]*"\s*)+); do$/m)?.[1];
|
|
18
|
+
const bundleRoots = rootsLine ? [...rootsLine.matchAll(/"([^"]*)"/g)].map((match) => match[1]) : BRIDGE_BUNDLE_ROOTS;
|
|
19
|
+
const bundleIdentifier = contents.match(/kMDItemCFBundleIdentifier == "([^"]+)"/)?.[1] ?? BRIDGE_BUNDLE_IDENTIFIER;
|
|
20
|
+
return { helperSuffix, cachePath, bundleRoots, bundleIdentifier };
|
|
21
|
+
};
|
|
22
|
+
var resolveBridgeStub = (stubPath, probe) => {
|
|
23
|
+
const contents = probe.readFile(stubPath);
|
|
24
|
+
if (contents === null) return { kind: "no-stub", stub: stubPath };
|
|
25
|
+
const shape = parseBridgeStub(contents, stubPath);
|
|
26
|
+
const helperIn = (bundle) => `${bundle}${shape.helperSuffix}`;
|
|
27
|
+
const looked = [];
|
|
28
|
+
for (const root of shape.bundleRoots.map((root2) => expandHome(root2, probe.home))) {
|
|
29
|
+
looked.push(root);
|
|
30
|
+
if (probe.exists(helperIn(root))) return { kind: "bundle", helper: helperIn(root), via: "root" };
|
|
31
|
+
}
|
|
32
|
+
const cached = shape.cachePath ? probe.readFile(shape.cachePath)?.split("\n")[0]?.trim() : void 0;
|
|
33
|
+
if (cached) {
|
|
34
|
+
looked.push(cached);
|
|
35
|
+
if (probe.exists(helperIn(cached))) return { kind: "bundle", helper: helperIn(cached), via: "cache" };
|
|
36
|
+
}
|
|
37
|
+
for (const found of probe.mdfind(shape.bundleIdentifier)) {
|
|
38
|
+
looked.push(found);
|
|
39
|
+
if (probe.exists(helperIn(found))) return { kind: "bundle", helper: helperIn(found), via: "spotlight" };
|
|
40
|
+
}
|
|
41
|
+
return { kind: "missing", stub: stubPath, looked };
|
|
42
|
+
};
|
|
43
|
+
var BRIDGE_GONE_MESSAGE = "the Mac app is gone but its hooks remain; run pushary setup or reinstall the app";
|
|
44
|
+
var describeBridgeResolution = (resolution) => {
|
|
45
|
+
switch (resolution.kind) {
|
|
46
|
+
case "bundle":
|
|
47
|
+
return `${resolution.helper} (${resolution.via === "root" ? "installed" : resolution.via === "cache" ? "cached path" : "found by Spotlight"})`;
|
|
48
|
+
case "missing":
|
|
49
|
+
return BRIDGE_GONE_MESSAGE;
|
|
50
|
+
case "no-stub":
|
|
51
|
+
return `${resolution.stub} is not there; ${BRIDGE_GONE_MESSAGE}`;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var isBridgeLocator = (executable) => executable !== null && executable.split(/[/\\]/).pop() === HOOK_LOCATOR_BINARY;
|
|
55
|
+
var spotlight = (bundleIdentifier) => {
|
|
56
|
+
if (process.platform !== "darwin") return [];
|
|
57
|
+
try {
|
|
58
|
+
return execFileSync("/usr/bin/mdfind", [`kMDItemCFBundleIdentifier == "${bundleIdentifier}"`], {
|
|
59
|
+
encoding: "utf-8",
|
|
60
|
+
timeout: 5e3,
|
|
61
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
62
|
+
}).split("\n").map((line) => line.trim()).filter((line) => line !== "");
|
|
63
|
+
} catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var readOrNull = (path) => {
|
|
68
|
+
try {
|
|
69
|
+
return readFileSync(path, "utf-8");
|
|
70
|
+
} catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
var liveBridgeProbe = () => ({
|
|
75
|
+
exists: existsSync,
|
|
76
|
+
readFile: readOrNull,
|
|
77
|
+
mdfind: spotlight,
|
|
78
|
+
home: homedir()
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
export {
|
|
82
|
+
resolveBridgeStub,
|
|
83
|
+
describeBridgeResolution,
|
|
84
|
+
isBridgeLocator,
|
|
85
|
+
liveBridgeProbe
|
|
86
|
+
};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NOTIFICATION_MATCHED_TYPES,
|
|
3
|
+
POSTTOOLUSE_MIRRORED_TOOLS,
|
|
4
|
+
PRETOOLUSE_GATED_TOOLS,
|
|
5
|
+
PRETOOLUSE_PHONE_ANSWERED_TOOLS
|
|
6
|
+
} from "./chunk-TTO76NZJ.js";
|
|
7
|
+
import {
|
|
8
|
+
isProtectedByScope
|
|
9
|
+
} from "./chunk-3F4VV5TS.js";
|
|
10
|
+
import {
|
|
11
|
+
HOOK_BUDGETS,
|
|
12
|
+
HOOK_LOCATOR_BINARY
|
|
13
|
+
} from "./chunk-VOWZ5VOO.js";
|
|
14
|
+
|
|
15
|
+
// src/gemini-config.ts
|
|
16
|
+
var GEMINI_HOOK_BINARY = "pushary-gemini-hook";
|
|
17
|
+
var GEMINI_MCP_URL = "https://pushary.com/api/mcp/mcp";
|
|
18
|
+
var GEMINI_HOOK_EVENTS = [
|
|
19
|
+
{ event: "BeforeTool", matcher: "run_shell_command|write_file|replace", delivery: "approval", timeoutMs: HOOK_BUDGETS.gemini.budgetSeconds * 1e3 },
|
|
20
|
+
{ event: "AfterTool", matcher: "run_shell_command|write_file|replace", delivery: "telemetry", timeoutMs: 1e4 },
|
|
21
|
+
{ event: "BeforeAgent", delivery: "telemetry", timeoutMs: 1e4 },
|
|
22
|
+
{ event: "AfterAgent", delivery: "telemetry", timeoutMs: 1e4 },
|
|
23
|
+
{ event: "SessionStart", delivery: "telemetry", timeoutMs: 1e4 },
|
|
24
|
+
{ event: "SessionEnd", delivery: "telemetry", timeoutMs: 1e4 }
|
|
25
|
+
];
|
|
26
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
27
|
+
var ensureRecord = (target, key) => {
|
|
28
|
+
const existing = asRecord(target[key]);
|
|
29
|
+
if (existing) return existing;
|
|
30
|
+
const created = {};
|
|
31
|
+
target[key] = created;
|
|
32
|
+
return created;
|
|
33
|
+
};
|
|
34
|
+
var isPusharyGeminiHook = (entry, scope) => {
|
|
35
|
+
const hooks = asRecord(entry)?.hooks;
|
|
36
|
+
if (!Array.isArray(hooks)) return false;
|
|
37
|
+
return hooks.some((hook) => {
|
|
38
|
+
const command = String(asRecord(hook)?.command ?? "");
|
|
39
|
+
if (isProtectedByScope(command, scope)) return false;
|
|
40
|
+
return command.includes(GEMINI_HOOK_BINARY) || command.includes(HOOK_LOCATOR_BINARY);
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
var addGeminiMcpServer = (settings, apiKey) => {
|
|
44
|
+
const mcpServers = ensureRecord(settings, "mcpServers");
|
|
45
|
+
mcpServers.pushary = {
|
|
46
|
+
httpUrl: GEMINI_MCP_URL,
|
|
47
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
48
|
+
trust: true
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
var addGeminiHooks = (settings, command) => {
|
|
52
|
+
const hooks = ensureRecord(settings, "hooks");
|
|
53
|
+
for (const definition of GEMINI_HOOK_EVENTS) {
|
|
54
|
+
const existing = Array.isArray(hooks[definition.event]) ? hooks[definition.event] : [];
|
|
55
|
+
const entries = existing.filter((entry) => !isPusharyGeminiHook(entry));
|
|
56
|
+
entries.push({
|
|
57
|
+
...definition.matcher ? { matcher: definition.matcher } : {},
|
|
58
|
+
hooks: [{
|
|
59
|
+
name: "pushary",
|
|
60
|
+
type: "command",
|
|
61
|
+
command,
|
|
62
|
+
timeout: definition.timeoutMs
|
|
63
|
+
}]
|
|
64
|
+
});
|
|
65
|
+
hooks[definition.event] = entries;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var removeGeminiHooks = (settings, scope) => {
|
|
69
|
+
const hooks = asRecord(settings.hooks);
|
|
70
|
+
if (!hooks) return false;
|
|
71
|
+
let changed = false;
|
|
72
|
+
for (const definition of GEMINI_HOOK_EVENTS) {
|
|
73
|
+
const entries = hooks[definition.event];
|
|
74
|
+
if (!Array.isArray(entries)) continue;
|
|
75
|
+
const filtered = entries.filter((entry) => !isPusharyGeminiHook(entry, scope));
|
|
76
|
+
if (filtered.length !== entries.length) {
|
|
77
|
+
if (filtered.length === 0) {
|
|
78
|
+
delete hooks[definition.event];
|
|
79
|
+
} else {
|
|
80
|
+
hooks[definition.event] = filtered;
|
|
81
|
+
}
|
|
82
|
+
changed = true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (Object.keys(hooks).length === 0) delete settings.hooks;
|
|
86
|
+
return changed;
|
|
87
|
+
};
|
|
88
|
+
var removeGeminiMcpServer = (settings) => {
|
|
89
|
+
const mcpServers = asRecord(settings.mcpServers);
|
|
90
|
+
if (!mcpServers?.pushary) return false;
|
|
91
|
+
delete mcpServers.pushary;
|
|
92
|
+
if (Object.keys(mcpServers).length === 0) delete settings.mcpServers;
|
|
93
|
+
return true;
|
|
94
|
+
};
|
|
95
|
+
var removeGeminiSettings = (settings, scope) => {
|
|
96
|
+
const mcpRemoved = scope?.keepMcpServer === true ? false : removeGeminiMcpServer(settings);
|
|
97
|
+
const hooksRemoved = removeGeminiHooks(settings, scope);
|
|
98
|
+
return mcpRemoved || hooksRemoved;
|
|
99
|
+
};
|
|
100
|
+
var hasGeminiHooks = (settings) => {
|
|
101
|
+
const hooks = asRecord(settings.hooks);
|
|
102
|
+
if (!hooks) return false;
|
|
103
|
+
return GEMINI_HOOK_EVENTS.some((definition) => {
|
|
104
|
+
const entries = hooks[definition.event];
|
|
105
|
+
return Array.isArray(entries) && entries.some((entry) => isPusharyGeminiHook(entry));
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
var missingGeminiHookEvents = (settings) => {
|
|
109
|
+
const hooks = asRecord(settings.hooks);
|
|
110
|
+
return GEMINI_HOOK_EVENTS.filter((definition) => {
|
|
111
|
+
const entries = hooks?.[definition.event];
|
|
112
|
+
return !Array.isArray(entries) || !entries.some((entry) => isPusharyGeminiHook(entry));
|
|
113
|
+
}).map((definition) => definition.event);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/agent-version.ts
|
|
117
|
+
var parseVersion = (raw) => {
|
|
118
|
+
const match = raw.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
119
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
120
|
+
};
|
|
121
|
+
var compareVersion = (a, b) => {
|
|
122
|
+
for (let index = 0; index < 3; index++) {
|
|
123
|
+
if (a[index] !== b[index]) return a[index] < b[index] ? -1 : 1;
|
|
124
|
+
}
|
|
125
|
+
return 0;
|
|
126
|
+
};
|
|
127
|
+
var atLeast = (version, floor) => compareVersion(version, floor) >= 0;
|
|
128
|
+
var formatVersion = (version) => version.join(".");
|
|
129
|
+
|
|
130
|
+
// src/claude-events.ts
|
|
131
|
+
var GATED_TOOLS = [...PRETOOLUSE_GATED_TOOLS, ...PRETOOLUSE_PHONE_ANSWERED_TOOLS].join("|");
|
|
132
|
+
var MIRRORED_TOOLS = POSTTOOLUSE_MIRRORED_TOOLS.join("|");
|
|
133
|
+
var ESTABLISHED = [1, 0, 0];
|
|
134
|
+
var OBSERVED = [2, 0, 0];
|
|
135
|
+
var CLAUDE_HOOK_EVENTS = [
|
|
136
|
+
{ event: "PreToolUse", binary: "pushary-hook", matcher: GATED_TOOLS, timeout: HOOK_BUDGETS.claude.budgetSeconds, delivery: "approval", since: ESTABLISHED },
|
|
137
|
+
{ event: "PostToolUse", binary: "pushary-post-hook", matcher: MIRRORED_TOOLS, timeout: 10, delivery: "telemetry", since: ESTABLISHED },
|
|
138
|
+
{ event: "Stop", binary: "pushary-stop-hook", timeout: 10, delivery: "telemetry", since: ESTABLISHED },
|
|
139
|
+
{ event: "UserPromptSubmit", binary: "pushary-prompt-hook", timeout: 10, delivery: "telemetry", since: ESTABLISHED },
|
|
140
|
+
{ event: "Notification", binary: "pushary-notification-hook", matcher: NOTIFICATION_MATCHED_TYPES.join("|"), timeout: 10, delivery: "telemetry", since: ESTABLISHED },
|
|
141
|
+
{ event: "SessionStart", binary: "pushary-session-start-hook", matcher: "startup|resume|clear", timeout: 10, delivery: "telemetry", since: ESTABLISHED },
|
|
142
|
+
{ event: "SessionEnd", binary: "pushary-session-end-hook", timeout: 10, delivery: "telemetry", since: ESTABLISHED },
|
|
143
|
+
{ event: "StopFailure", binary: "pushary-stopfailure-hook", timeout: 10, delivery: "telemetry", since: ESTABLISHED },
|
|
144
|
+
{ event: "PermissionRequest", binary: "pushary-permission-hook", timeout: HOOK_BUDGETS.claude.budgetSeconds, delivery: "approval", since: ESTABLISHED },
|
|
145
|
+
{ event: "PermissionDenied", binary: "pushary-permission-denied-hook", timeout: 60, delivery: "telemetry", since: ESTABLISHED },
|
|
146
|
+
// Observability only. Each carries session shape the island cannot get any other
|
|
147
|
+
// way, and none of them decides anything.
|
|
148
|
+
{ event: "SubagentStart", binary: "pushary-session-start-hook", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
149
|
+
{ event: "SubagentStop", binary: "pushary-stop-hook", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
150
|
+
{ event: "PreCompact", binary: "pushary-post-hook", matcher: "manual|auto", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
151
|
+
{ event: "PostCompact", binary: "pushary-post-hook", matcher: "manual|auto", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
152
|
+
{ event: "TeammateIdle", binary: "pushary-notification-hook", timeout: 10, delivery: "telemetry", since: OBSERVED },
|
|
153
|
+
// An MCP server asking the person for a value, answered from the phone rather
|
|
154
|
+
// than the terminal. No matcher: Claude Code matches this event on the MCP
|
|
155
|
+
// server's name, and we have no business preferring one server over another.
|
|
156
|
+
{ event: "Elicitation", binary: "pushary-elicitation-hook", timeout: HOOK_BUDGETS.claude.budgetSeconds, delivery: "approval", since: OBSERVED }
|
|
157
|
+
];
|
|
158
|
+
var supportedClaudeEvents = (version) => CLAUDE_HOOK_EVENTS.filter((hook) => version ? atLeast(version, hook.since) : hook.since === ESTABLISHED);
|
|
159
|
+
var registrationSignatures = (events, version) => Object.fromEntries(
|
|
160
|
+
events.map((hook) => [hook.event, `registered|${version ? formatVersion(version) : "unknown"}`])
|
|
161
|
+
);
|
|
162
|
+
var needsReregistration = (stored, version) => {
|
|
163
|
+
const expected = registrationSignatures(supportedClaudeEvents(version), version);
|
|
164
|
+
const keys = Object.keys(expected);
|
|
165
|
+
if (!stored) return true;
|
|
166
|
+
if (keys.length !== Object.keys(stored).length) return true;
|
|
167
|
+
return keys.some((event) => stored[event] !== expected[event]);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export {
|
|
171
|
+
GEMINI_HOOK_BINARY,
|
|
172
|
+
GEMINI_HOOK_EVENTS,
|
|
173
|
+
addGeminiMcpServer,
|
|
174
|
+
addGeminiHooks,
|
|
175
|
+
removeGeminiSettings,
|
|
176
|
+
hasGeminiHooks,
|
|
177
|
+
missingGeminiHookEvents,
|
|
178
|
+
parseVersion,
|
|
179
|
+
compareVersion,
|
|
180
|
+
formatVersion,
|
|
181
|
+
CLAUDE_HOOK_EVENTS,
|
|
182
|
+
supportedClaudeEvents,
|
|
183
|
+
registrationSignatures,
|
|
184
|
+
needsReregistration
|
|
185
|
+
};
|