@pushary/agent-hooks 0.84.1 → 0.85.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 +44 -0
- package/README.md +24 -0
- package/dist/bin/pushary-bell-hook.js +5 -3
- package/dist/bin/pushary-bell.js +8 -7
- package/dist/bin/pushary-claude.js +5 -5
- package/dist/bin/pushary-clean.js +6 -5
- package/dist/bin/pushary-codex-bridge.js +2 -2
- package/dist/bin/pushary-codex-hook.js +7 -13
- package/dist/bin/pushary-codex.js +1 -1
- package/dist/bin/pushary-connect.js +5 -5
- package/dist/bin/pushary-daemon.js +5 -5
- package/dist/bin/pushary-disconnect.d.ts +1 -0
- package/dist/bin/pushary-disconnect.js +125 -0
- package/dist/bin/pushary-doctor.js +9 -9
- package/dist/bin/pushary-gemini-bridge.js +2 -2
- package/dist/bin/pushary-gemini-hook.js +7 -13
- package/dist/bin/pushary-hook.js +13 -20
- package/dist/bin/pushary-login.js +2 -2
- package/dist/bin/pushary-logout.js +3 -3
- package/dist/bin/pushary-mode.js +2 -2
- package/dist/bin/pushary-notification-hook.js +6 -9
- package/dist/bin/pushary-permission-denied-hook.js +11 -9
- package/dist/bin/pushary-permission-hook.js +11 -9
- package/dist/bin/pushary-post-hook.js +6 -9
- package/dist/bin/pushary-prompt-hook.js +6 -9
- package/dist/bin/pushary-session-end-hook.js +6 -6
- package/dist/bin/pushary-session-start-hook.js +6 -6
- package/dist/bin/pushary-setup.js +23 -24
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +2 -2
- package/dist/bin/pushary-stop-hook.js +6 -6
- package/dist/bin/pushary-stopfailure-hook.js +6 -6
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-upgrade.js +13 -8
- package/dist/bin/pushary-wait.js +2 -2
- package/dist/bin/pushary.js +2 -1
- package/dist/{chunk-HZNOAJGB.js → chunk-4QPOMJUB.js} +1 -1
- package/dist/chunk-64PXDATC.js +187 -0
- package/dist/chunk-6CUUA7HO.js +59 -0
- package/dist/{chunk-UXWEE3QI.js → chunk-ADISVXZL.js} +1 -1
- package/dist/chunk-AXRATIS6.js +70 -0
- package/dist/{chunk-CCCJ6BPW.js → chunk-EXMUM226.js} +19 -7
- package/dist/{chunk-YR5TSPXB.js → chunk-GFM3STWO.js} +3 -3
- package/dist/{chunk-MGJBC6DD.js → chunk-GOEXZ5QJ.js} +1 -0
- package/dist/{chunk-BLDDXHHA.js → chunk-GXIFADGD.js} +1 -1
- package/dist/{chunk-SEAHGHCE.js → chunk-HVZIHTOO.js} +33 -0
- package/dist/chunk-PWTKKQQI.js +27 -0
- package/dist/{chunk-J4KFVOCQ.js → chunk-SQOFGPNX.js} +1 -1
- package/dist/{chunk-CCH775Y6.js → chunk-WEAQQSHQ.js} +1 -1
- package/dist/{chunk-ILB6UOAF.js → chunk-YKW6JCWI.js} +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +6 -4
- package/package.json +3 -2
- package/dist/chunk-UKSQWTBH.js +0 -208
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.85.0
|
|
4
|
+
|
|
5
|
+
### A hook command that cannot outlive what it points at
|
|
6
|
+
|
|
7
|
+
Every hook command written into `~/.claude/settings.json`, `~/.codex/hooks.json`
|
|
8
|
+
and `~/.gemini/settings.json`, the free bell included, is now wrapped so that a missing binary, a removed
|
|
9
|
+
`node`, a changed npm prefix or a moved home directory exits 0 and the agent reads
|
|
10
|
+
"no opinion". Before, any of those turned every tool call into a failing hook.
|
|
11
|
+
The guard is tested on every shell that can be `/bin/sh`, including dash, and with
|
|
12
|
+
`node` off PATH, which used to exit 127 and print on every tool call.
|
|
13
|
+
|
|
14
|
+
Codex hashes the exact command string to trust a hook, so `pushary upgrade` rewrites
|
|
15
|
+
the trust entry when it re-applies the hooks.
|
|
16
|
+
|
|
17
|
+
### Hooks registered for the CLI you have
|
|
18
|
+
|
|
19
|
+
Claude Code events are registered from a table with a version floor per event.
|
|
20
|
+
`SubagentStart`, `SubagentStop`, `PreCompact`, `PostCompact` and `TeammateIdle`
|
|
21
|
+
are added on a CLI that understands them, and `pushary upgrade` re-registers
|
|
22
|
+
against the CLI you have now. Disconnect removes every event in the table; a
|
|
23
|
+
hand-typed list used to leave the five observability events behind.
|
|
24
|
+
|
|
25
|
+
### `pushary disconnect <agent>`
|
|
26
|
+
|
|
27
|
+
Removes the MCP server, the hooks, the skill and, for Codex, the trust entries and
|
|
28
|
+
the API key from `config.toml`, for one agent, leaving the others alone. The bin
|
|
29
|
+
map entry was written in a shape the build silently dropped, and the command read
|
|
30
|
+
the dispatcher's own token as the agent name; both are fixed before this, its
|
|
31
|
+
first release, and a test now holds every bin entry to the one shape tsup builds.
|
|
32
|
+
|
|
33
|
+
### A kill switch per hook path
|
|
34
|
+
|
|
35
|
+
`~/.pushary/admission-rules.json` (`{"version":1,"disabled":["claude:PostToolUse"]}`)
|
|
36
|
+
silences one event on one agent, or one agent entirely, without a release. Every
|
|
37
|
+
hook binary reads its input through this check, from the same file the macOS
|
|
38
|
+
helper reads, so one file governs both transports. Deny-only: nothing in the file
|
|
39
|
+
can enable a hook.
|
|
40
|
+
|
|
41
|
+
### `PostToolUse` no longer pays two round trips per tool call
|
|
42
|
+
|
|
43
|
+
The telemetry hooks reuse the mode state the gate fetched for the same session
|
|
44
|
+
within the last 60 seconds. The gate itself still reads it live, so a remote stop
|
|
45
|
+
and a scope contract are never served stale where they decide anything.
|
|
46
|
+
|
|
3
47
|
## 0.84.1
|
|
4
48
|
|
|
5
49
|
### Remote starts survive lost acknowledgements without double-launching
|
package/README.md
CHANGED
|
@@ -108,6 +108,29 @@ npx @pushary/agent-hooks@latest doctor
|
|
|
108
108
|
|
|
109
109
|
Any other MCP client can use notify and ask by pointing at the Pushary MCP endpoint directly.
|
|
110
110
|
|
|
111
|
+
## Hook events, gated by version
|
|
112
|
+
|
|
113
|
+
Claude Code 2.1.239 names thirty-one hook events and the set grows release by release,
|
|
114
|
+
so the ones we register are gated on the version actually installed. The version is
|
|
115
|
+
read from disk and never by running the binary: `codex --version` once submitted the
|
|
116
|
+
Codex CLI to XProtect, which killed it and moved the 181 MB binary to the Trash, so
|
|
117
|
+
setup deleted the user's installation as a side effect of asking its version.
|
|
118
|
+
|
|
119
|
+
An unreadable version registers only the events that predate gating. Each registration
|
|
120
|
+
records `registered|<version>`, which is what lets an upgrade pick up newer events
|
|
121
|
+
without anyone re-running setup.
|
|
122
|
+
|
|
123
|
+
## Admission rules
|
|
124
|
+
|
|
125
|
+
Publishing this package is a version bump merged to main, and a hook change is not
|
|
126
|
+
live until that happens, so a hook that floods on one event would otherwise need a
|
|
127
|
+
release to stop. `~/.pushary/admission-rules.json` can disable an `(agent, event)`
|
|
128
|
+
pair as data.
|
|
129
|
+
|
|
130
|
+
Deny-only by construction: a rule can silence a hook we ship, and no shape of the file
|
|
131
|
+
can enable one we do not. A file that cannot be read admits everything, because
|
|
132
|
+
failing closed would let one malformed download silence every hook on the machine.
|
|
133
|
+
|
|
111
134
|
## Commands
|
|
112
135
|
|
|
113
136
|
<!-- Managed: every command below is declared in src/cli/commands.ts, and a test
|
|
@@ -123,6 +146,7 @@ logout Remove the key this machine stores, and say what it does not remove
|
|
|
123
146
|
connect Connect a phone without re-running setup (--app for the Pushary app)
|
|
124
147
|
bell Free local bell when an agent finishes or needs you. No account, no key, no network
|
|
125
148
|
doctor Verify your Pushary installation is working
|
|
149
|
+
disconnect Turn off one agent (claude|codex|gemini|cursor)
|
|
126
150
|
clean Remove all Pushary configuration (--yes for non-interactive)
|
|
127
151
|
mode Switch approval mode (push_only, push_first, terminal_only)
|
|
128
152
|
wait Show or set the "wait for your phone" ladder (pushary wait 45)
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
handleBell
|
|
4
4
|
} from "../chunk-7PZPJSWI.js";
|
|
5
|
+
import {
|
|
6
|
+
readHookInput
|
|
7
|
+
} from "../chunk-6CUUA7HO.js";
|
|
5
8
|
import "../chunk-K7CSRGKZ.js";
|
|
6
9
|
import "../chunk-BC3VCZ3E.js";
|
|
7
10
|
import "../chunk-6MTNS63X.js";
|
|
@@ -11,10 +14,9 @@ import "../chunk-MQMPG5X4.js";
|
|
|
11
14
|
|
|
12
15
|
// bin/pushary-bell-hook.ts
|
|
13
16
|
var main = async () => {
|
|
14
|
-
let rawInput = "";
|
|
15
17
|
try {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
const input = await readHookInput("claude");
|
|
19
|
+
if (input) handleBell(input);
|
|
18
20
|
} catch {
|
|
19
21
|
}
|
|
20
22
|
process.stdout.write("{}");
|
package/dist/bin/pushary-bell.js
CHANGED
|
@@ -6,9 +6,13 @@ import {
|
|
|
6
6
|
ring,
|
|
7
7
|
upgradeThreshold
|
|
8
8
|
} from "../chunk-7PZPJSWI.js";
|
|
9
|
+
import {
|
|
10
|
+
guardBinary
|
|
11
|
+
} from "../chunk-PWTKKQQI.js";
|
|
12
|
+
import "../chunk-VT4IVERX.js";
|
|
9
13
|
import {
|
|
10
14
|
claudeSettings
|
|
11
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-HVZIHTOO.js";
|
|
12
16
|
import {
|
|
13
17
|
createIo
|
|
14
18
|
} from "../chunk-5RUIFDTP.js";
|
|
@@ -18,8 +22,8 @@ import {
|
|
|
18
22
|
} from "../chunk-GMXKITVA.js";
|
|
19
23
|
import {
|
|
20
24
|
exitOnHelpFlag
|
|
21
|
-
} from "../chunk-
|
|
22
|
-
import "../chunk-
|
|
25
|
+
} from "../chunk-SQOFGPNX.js";
|
|
26
|
+
import "../chunk-GOEXZ5QJ.js";
|
|
23
27
|
import "../chunk-BC3VCZ3E.js";
|
|
24
28
|
import "../chunk-DINDL2CF.js";
|
|
25
29
|
import {
|
|
@@ -53,10 +57,7 @@ var isBellHook = (entry) => {
|
|
|
53
57
|
var BELL_TIMEOUT_SECONDS = 5;
|
|
54
58
|
var BELL_NOTIFICATION_MATCHER = "idle_prompt|agent_needs_input|agent_completed";
|
|
55
59
|
var addBellHooks = (settings, binDir) => {
|
|
56
|
-
const resolve = (name) =>
|
|
57
|
-
const path = binDir ? join(binDir, name) : name;
|
|
58
|
-
return /\s/.test(path) ? `"${path}"` : path;
|
|
59
|
-
};
|
|
60
|
+
const resolve = (name) => guardBinary(binDir ? join(binDir, name) : name);
|
|
60
61
|
const hooks = ensureRecord(settings, "hooks");
|
|
61
62
|
const notification = (Array.isArray(hooks.Notification) ? hooks.Notification : []).filter((entry) => !isBellHook(entry));
|
|
62
63
|
notification.push({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ensureDaemonRunning
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-WEAQQSHQ.js";
|
|
5
5
|
import {
|
|
6
6
|
buildTranscriptRecords,
|
|
7
7
|
decodePublicKey,
|
|
@@ -13,18 +13,18 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
startProcessOwnership,
|
|
15
15
|
withSpawnProcessOwnership
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-YKW6JCWI.js";
|
|
17
17
|
import {
|
|
18
18
|
needsShell,
|
|
19
19
|
spawnClaude
|
|
20
20
|
} from "../chunk-XHKBHWLX.js";
|
|
21
21
|
import "../chunk-VT4IVERX.js";
|
|
22
|
-
import "../chunk-
|
|
22
|
+
import "../chunk-HVZIHTOO.js";
|
|
23
23
|
import {
|
|
24
24
|
KILL_REASON,
|
|
25
25
|
isDeferAnswer,
|
|
26
26
|
resolveGate
|
|
27
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-GXIFADGD.js";
|
|
28
28
|
import {
|
|
29
29
|
askUser,
|
|
30
30
|
cancelQuestion,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
reportEvent,
|
|
37
37
|
scopePathFor,
|
|
38
38
|
waitForAnswer
|
|
39
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-EXMUM226.js";
|
|
40
40
|
import {
|
|
41
41
|
getMachineId
|
|
42
42
|
} from "../chunk-RN3NOEJF.js";
|
|
@@ -4,14 +4,15 @@ import {
|
|
|
4
4
|
shortenHome,
|
|
5
5
|
unregisterPluginLocation,
|
|
6
6
|
vscodeSettingsTargets
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-ADISVXZL.js";
|
|
8
8
|
import {
|
|
9
9
|
removeGeminiSettings
|
|
10
10
|
} from "../chunk-DOXSWT4Q.js";
|
|
11
11
|
import {
|
|
12
12
|
removeClaudeMcpServers,
|
|
13
13
|
removePusharySettings
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-64PXDATC.js";
|
|
15
|
+
import "../chunk-PWTKKQQI.js";
|
|
15
16
|
import {
|
|
16
17
|
execNpm
|
|
17
18
|
} from "../chunk-VT4IVERX.js";
|
|
@@ -32,14 +33,14 @@ import {
|
|
|
32
33
|
pusharyDir,
|
|
33
34
|
removeCodexHooks,
|
|
34
35
|
vscodePluginDir
|
|
35
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-HVZIHTOO.js";
|
|
36
37
|
import {
|
|
37
38
|
rejectUnknownFlags
|
|
38
39
|
} from "../chunk-GMXKITVA.js";
|
|
39
40
|
import {
|
|
40
41
|
exitOnHelpFlag
|
|
41
|
-
} from "../chunk-
|
|
42
|
-
import "../chunk-
|
|
42
|
+
} from "../chunk-SQOFGPNX.js";
|
|
43
|
+
import "../chunk-GOEXZ5QJ.js";
|
|
43
44
|
import {
|
|
44
45
|
removeClaudeAlias
|
|
45
46
|
} from "../chunk-BC3VCZ3E.js";
|
|
@@ -11,14 +11,14 @@ import "../chunk-GCKAWHFP.js";
|
|
|
11
11
|
import {
|
|
12
12
|
startProcessOwnership,
|
|
13
13
|
withSpawnProcessOwnership
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-YKW6JCWI.js";
|
|
15
15
|
import {
|
|
16
16
|
spawnClaude
|
|
17
17
|
} from "../chunk-XHKBHWLX.js";
|
|
18
18
|
import {
|
|
19
19
|
resolveBinary
|
|
20
20
|
} from "../chunk-VT4IVERX.js";
|
|
21
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-HVZIHTOO.js";
|
|
22
22
|
import {
|
|
23
23
|
getMachineId
|
|
24
24
|
} from "../chunk-RN3NOEJF.js";
|
|
@@ -3,12 +3,15 @@ import {
|
|
|
3
3
|
isGatingMoment,
|
|
4
4
|
recordKeylessMoment
|
|
5
5
|
} from "../chunk-NJ7JT26G.js";
|
|
6
|
+
import {
|
|
7
|
+
readHookInput
|
|
8
|
+
} from "../chunk-6CUUA7HO.js";
|
|
6
9
|
import {
|
|
7
10
|
KILL_REASON,
|
|
8
11
|
denyReasonFrom,
|
|
9
12
|
isDeferAnswer,
|
|
10
13
|
resolveGate
|
|
11
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-GXIFADGD.js";
|
|
12
15
|
import {
|
|
13
16
|
CODEX_AGENT,
|
|
14
17
|
DEFAULT_SESSION,
|
|
@@ -40,7 +43,7 @@ import {
|
|
|
40
43
|
toPolicyLookup,
|
|
41
44
|
toPolicyLookups,
|
|
42
45
|
waitForAnswer
|
|
43
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-EXMUM226.js";
|
|
44
47
|
import {
|
|
45
48
|
getMachineId
|
|
46
49
|
} from "../chunk-RN3NOEJF.js";
|
|
@@ -310,17 +313,8 @@ var emit = (wire) => {
|
|
|
310
313
|
if (wire) process.stdout.write(JSON.stringify(wire));
|
|
311
314
|
};
|
|
312
315
|
var main = async () => {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
rawInput += chunk;
|
|
316
|
-
}
|
|
317
|
-
if (!rawInput.trim()) {
|
|
318
|
-
process.exit(0);
|
|
319
|
-
}
|
|
320
|
-
let input;
|
|
321
|
-
try {
|
|
322
|
-
input = JSON.parse(rawInput);
|
|
323
|
-
} catch {
|
|
316
|
+
const input = await readHookInput("codex");
|
|
317
|
+
if (!input) {
|
|
324
318
|
process.exit(0);
|
|
325
319
|
}
|
|
326
320
|
try {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
printKeyCheck
|
|
4
|
+
} from "../chunk-FBGBJXVC.js";
|
|
2
5
|
import {
|
|
3
6
|
confirmAppConnection,
|
|
4
7
|
connectDevice,
|
|
5
8
|
printConnectInstructions
|
|
6
9
|
} from "../chunk-6LC4WSCL.js";
|
|
7
10
|
import "../chunk-3EGEA4KH.js";
|
|
8
|
-
import {
|
|
9
|
-
printKeyCheck
|
|
10
|
-
} from "../chunk-FBGBJXVC.js";
|
|
11
11
|
import {
|
|
12
12
|
checkApiKey
|
|
13
13
|
} from "../chunk-F52SIIDG.js";
|
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
} from "../chunk-GMXKITVA.js";
|
|
23
23
|
import {
|
|
24
24
|
exitOnHelpFlag
|
|
25
|
-
} from "../chunk-
|
|
26
|
-
import "../chunk-
|
|
25
|
+
} from "../chunk-SQOFGPNX.js";
|
|
26
|
+
import "../chunk-GOEXZ5QJ.js";
|
|
27
27
|
import "../chunk-BC3VCZ3E.js";
|
|
28
28
|
import "../chunk-DINDL2CF.js";
|
|
29
29
|
import "../chunk-6MTNS63X.js";
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
acquireDaemonLease,
|
|
9
9
|
readDaemonStatus,
|
|
10
10
|
requestDaemonHandoff
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-WEAQQSHQ.js";
|
|
12
12
|
import {
|
|
13
13
|
CODEX_BRIDGE_CAPABILITY,
|
|
14
14
|
CODEX_RESUME_CAPABILITY,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
findLiveProcessBySpawnId,
|
|
19
19
|
ownsLiveProcess
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-YKW6JCWI.js";
|
|
21
21
|
import {
|
|
22
22
|
spawnClaude
|
|
23
23
|
} from "../chunk-XHKBHWLX.js";
|
|
@@ -26,14 +26,14 @@ import {
|
|
|
26
26
|
resolveGlobalPackageVersion,
|
|
27
27
|
resolvePackageVersionFromBinary
|
|
28
28
|
} from "../chunk-VT4IVERX.js";
|
|
29
|
-
import "../chunk-
|
|
29
|
+
import "../chunk-HVZIHTOO.js";
|
|
30
30
|
import {
|
|
31
31
|
getMachineId
|
|
32
32
|
} from "../chunk-RN3NOEJF.js";
|
|
33
33
|
import {
|
|
34
34
|
exitOnHelpFlag
|
|
35
|
-
} from "../chunk-
|
|
36
|
-
import "../chunk-
|
|
35
|
+
} from "../chunk-SQOFGPNX.js";
|
|
36
|
+
import "../chunk-GOEXZ5QJ.js";
|
|
37
37
|
import "../chunk-DINDL2CF.js";
|
|
38
38
|
import "../chunk-6MTNS63X.js";
|
|
39
39
|
import {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
removeGeminiSettings
|
|
4
|
+
} from "../chunk-DOXSWT4Q.js";
|
|
5
|
+
import {
|
|
6
|
+
removeClaudeMcpServers,
|
|
7
|
+
removePusharySettings
|
|
8
|
+
} from "../chunk-64PXDATC.js";
|
|
9
|
+
import "../chunk-PWTKKQQI.js";
|
|
10
|
+
import "../chunk-VT4IVERX.js";
|
|
11
|
+
import {
|
|
12
|
+
claudeJson,
|
|
13
|
+
claudeSettings,
|
|
14
|
+
claudeSettingsLocal,
|
|
15
|
+
codexConfigToml,
|
|
16
|
+
codexHooksJson,
|
|
17
|
+
cursorUserHooks,
|
|
18
|
+
cursorUserMcp,
|
|
19
|
+
geminiSettings,
|
|
20
|
+
removeCodexHooks,
|
|
21
|
+
removeCodexSettings
|
|
22
|
+
} from "../chunk-HVZIHTOO.js";
|
|
23
|
+
import {
|
|
24
|
+
exitOnHelpFlag
|
|
25
|
+
} from "../chunk-SQOFGPNX.js";
|
|
26
|
+
import "../chunk-GOEXZ5QJ.js";
|
|
27
|
+
import "../chunk-DINDL2CF.js";
|
|
28
|
+
import "../chunk-KZERVKTD.js";
|
|
29
|
+
import "../chunk-MQMPG5X4.js";
|
|
30
|
+
|
|
31
|
+
// bin/pushary-disconnect.ts
|
|
32
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
33
|
+
import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
|
|
34
|
+
|
|
35
|
+
// src/disconnect.ts
|
|
36
|
+
var DISCONNECTABLE_AGENTS = ["claude", "codex", "gemini", "cursor"];
|
|
37
|
+
var isDisconnectableAgent = (value) => DISCONNECTABLE_AGENTS.includes(value);
|
|
38
|
+
var removeCursorHooks = (config) => {
|
|
39
|
+
const hooks = config.hooks;
|
|
40
|
+
if (!hooks) return false;
|
|
41
|
+
let changed = false;
|
|
42
|
+
for (const [event, entries] of Object.entries(hooks)) {
|
|
43
|
+
if (!Array.isArray(entries)) continue;
|
|
44
|
+
const kept = entries.filter((entry) => !String(entry?.command ?? "").includes("pushary"));
|
|
45
|
+
if (kept.length === entries.length) continue;
|
|
46
|
+
changed = true;
|
|
47
|
+
if (kept.length === 0) delete hooks[event];
|
|
48
|
+
else hooks[event] = kept;
|
|
49
|
+
}
|
|
50
|
+
if (changed && Object.keys(hooks).length === 0) delete config.hooks;
|
|
51
|
+
return changed;
|
|
52
|
+
};
|
|
53
|
+
var disconnectPlan = (agent) => {
|
|
54
|
+
switch (agent) {
|
|
55
|
+
case "claude":
|
|
56
|
+
return [
|
|
57
|
+
{ path: claudeSettings(), format: "json", remove: removePusharySettings },
|
|
58
|
+
{ path: claudeSettingsLocal(), format: "json", remove: removePusharySettings },
|
|
59
|
+
{ path: claudeJson(), format: "json", remove: removeClaudeMcpServers }
|
|
60
|
+
];
|
|
61
|
+
case "codex":
|
|
62
|
+
return [
|
|
63
|
+
{ path: codexHooksJson(), format: "json", remove: removeCodexHooks },
|
|
64
|
+
{ path: codexConfigToml(), format: "toml", remove: (config) => removeCodexSettings(config, codexHooksJson()) }
|
|
65
|
+
];
|
|
66
|
+
case "gemini":
|
|
67
|
+
return [{ path: geminiSettings(), format: "json", remove: removeGeminiSettings }];
|
|
68
|
+
case "cursor":
|
|
69
|
+
return [
|
|
70
|
+
{ path: cursorUserHooks(), format: "json", remove: removeCursorHooks },
|
|
71
|
+
{ path: cursorUserMcp(), format: "json", remove: removeClaudeMcpServers }
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var disconnectAgent = (agent, io) => {
|
|
76
|
+
const changed = [];
|
|
77
|
+
const untouched = [];
|
|
78
|
+
for (const edit of disconnectPlan(agent)) {
|
|
79
|
+
const raw = io.read(edit.path);
|
|
80
|
+
if (raw === null) continue;
|
|
81
|
+
try {
|
|
82
|
+
const config = edit.format === "toml" ? io.parseToml(raw) : JSON.parse(raw);
|
|
83
|
+
if (!edit.remove(config)) {
|
|
84
|
+
untouched.push(edit.path);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
io.write(
|
|
88
|
+
edit.path,
|
|
89
|
+
edit.format === "toml" ? io.stringifyToml(config) : `${JSON.stringify(config, null, 2)}
|
|
90
|
+
`
|
|
91
|
+
);
|
|
92
|
+
changed.push(edit.path);
|
|
93
|
+
} catch {
|
|
94
|
+
untouched.push(edit.path);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return { agent, changed, untouched };
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// bin/pushary-disconnect.ts
|
|
101
|
+
exitOnHelpFlag("disconnect");
|
|
102
|
+
var rest = process.argv.slice(2);
|
|
103
|
+
var requested = rest[0] === "disconnect" ? rest[1] : rest[0];
|
|
104
|
+
if (!requested || !isDisconnectableAgent(requested)) {
|
|
105
|
+
console.error(`Usage: pushary disconnect <${DISCONNECTABLE_AGENTS.join("|")}>`);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
var result = disconnectAgent(requested, {
|
|
109
|
+
read: (path) => {
|
|
110
|
+
try {
|
|
111
|
+
return readFileSync(path, "utf-8");
|
|
112
|
+
} catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
write: (path, contents) => writeFileSync(path, contents, "utf-8"),
|
|
117
|
+
parseToml: (raw) => parseTOML(raw),
|
|
118
|
+
stringifyToml: (config) => stringifyTOML(config)
|
|
119
|
+
});
|
|
120
|
+
if (result.changed.length === 0) {
|
|
121
|
+
console.log(`${requested} was not connected.`);
|
|
122
|
+
} else {
|
|
123
|
+
console.log(`Disconnected ${requested}:`);
|
|
124
|
+
for (const path of result.changed) console.log(` ${path}`);
|
|
125
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
describeWaitLadder
|
|
4
|
-
} from "../chunk-IIENZE2J.js";
|
|
5
2
|
import {
|
|
6
3
|
claudeWired,
|
|
7
4
|
codexWired,
|
|
8
5
|
geminiWired
|
|
9
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-4QPOMJUB.js";
|
|
7
|
+
import {
|
|
8
|
+
describeWaitLadder
|
|
9
|
+
} from "../chunk-IIENZE2J.js";
|
|
10
10
|
import {
|
|
11
11
|
readDaemonStatus
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-WEAQQSHQ.js";
|
|
13
13
|
import {
|
|
14
14
|
agentProbes,
|
|
15
15
|
detectAgent,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
isDetected,
|
|
19
19
|
isPluginRegistered,
|
|
20
20
|
vscodeSettingsTargets
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-ADISVXZL.js";
|
|
22
22
|
import {
|
|
23
23
|
GEMINI_HOOK_BINARY,
|
|
24
24
|
hasGeminiHooks,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
readCodexMcpAuth,
|
|
47
47
|
untrustedCodexHookEvents,
|
|
48
48
|
vscodePluginDir
|
|
49
|
-
} from "../chunk-
|
|
49
|
+
} from "../chunk-HVZIHTOO.js";
|
|
50
50
|
import {
|
|
51
51
|
readLedgerSummary
|
|
52
52
|
} from "../chunk-NJ7JT26G.js";
|
|
@@ -77,8 +77,8 @@ import {
|
|
|
77
77
|
} from "../chunk-GMXKITVA.js";
|
|
78
78
|
import {
|
|
79
79
|
exitOnHelpFlag
|
|
80
|
-
} from "../chunk-
|
|
81
|
-
import "../chunk-
|
|
80
|
+
} from "../chunk-SQOFGPNX.js";
|
|
81
|
+
import "../chunk-GOEXZ5QJ.js";
|
|
82
82
|
import "../chunk-BC3VCZ3E.js";
|
|
83
83
|
import {
|
|
84
84
|
getPackageVersion
|
|
@@ -10,14 +10,14 @@ import "../chunk-GCKAWHFP.js";
|
|
|
10
10
|
import {
|
|
11
11
|
startProcessOwnership,
|
|
12
12
|
withSpawnProcessOwnership
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-YKW6JCWI.js";
|
|
14
14
|
import {
|
|
15
15
|
spawnClaude
|
|
16
16
|
} from "../chunk-XHKBHWLX.js";
|
|
17
17
|
import {
|
|
18
18
|
resolveBinary
|
|
19
19
|
} from "../chunk-VT4IVERX.js";
|
|
20
|
-
import "../chunk-
|
|
20
|
+
import "../chunk-HVZIHTOO.js";
|
|
21
21
|
import {
|
|
22
22
|
getMachineId
|
|
23
23
|
} from "../chunk-RN3NOEJF.js";
|
|
@@ -3,12 +3,15 @@ import {
|
|
|
3
3
|
isGatingMoment,
|
|
4
4
|
recordKeylessMoment
|
|
5
5
|
} from "../chunk-NJ7JT26G.js";
|
|
6
|
+
import {
|
|
7
|
+
readHookInput
|
|
8
|
+
} from "../chunk-6CUUA7HO.js";
|
|
6
9
|
import {
|
|
7
10
|
KILL_REASON,
|
|
8
11
|
denyReasonFrom,
|
|
9
12
|
isDeferAnswer,
|
|
10
13
|
resolveGate
|
|
11
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-GXIFADGD.js";
|
|
12
15
|
import {
|
|
13
16
|
DEFAULT_SESSION,
|
|
14
17
|
askUser,
|
|
@@ -31,7 +34,7 @@ import {
|
|
|
31
34
|
scopePathFor,
|
|
32
35
|
sendNotification,
|
|
33
36
|
waitForAnswer
|
|
34
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-EXMUM226.js";
|
|
35
38
|
import {
|
|
36
39
|
getMachineId
|
|
37
40
|
} from "../chunk-RN3NOEJF.js";
|
|
@@ -278,17 +281,8 @@ var emit = (wire) => {
|
|
|
278
281
|
if (wire) process.stdout.write(JSON.stringify(wire));
|
|
279
282
|
};
|
|
280
283
|
var main = async () => {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
rawInput += chunk;
|
|
284
|
-
}
|
|
285
|
-
if (!rawInput.trim()) {
|
|
286
|
-
process.exit(0);
|
|
287
|
-
}
|
|
288
|
-
let input;
|
|
289
|
-
try {
|
|
290
|
-
input = JSON.parse(rawInput);
|
|
291
|
-
} catch {
|
|
284
|
+
const input = await readHookInput("gemini");
|
|
285
|
+
if (!input) {
|
|
292
286
|
process.exit(0);
|
|
293
287
|
}
|
|
294
288
|
try {
|
package/dist/bin/pushary-hook.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePreToolUse
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-GFM3STWO.js";
|
|
5
|
+
import "../chunk-64PXDATC.js";
|
|
6
|
+
import "../chunk-PWTKKQQI.js";
|
|
7
|
+
import "../chunk-VT4IVERX.js";
|
|
6
8
|
import "../chunk-NJ7JT26G.js";
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
+
import {
|
|
10
|
+
readHookInput
|
|
11
|
+
} from "../chunk-6CUUA7HO.js";
|
|
12
|
+
import "../chunk-GXIFADGD.js";
|
|
13
|
+
import "../chunk-EXMUM226.js";
|
|
9
14
|
import "../chunk-RN3NOEJF.js";
|
|
10
15
|
import {
|
|
11
16
|
exitOnHelpFlag
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-SQOFGPNX.js";
|
|
18
|
+
import "../chunk-GOEXZ5QJ.js";
|
|
14
19
|
import "../chunk-DINDL2CF.js";
|
|
15
20
|
import "../chunk-BSZYIAZL.js";
|
|
16
21
|
import "../chunk-SAF6HGAA.js";
|
|
@@ -23,20 +28,8 @@ import "../chunk-MQMPG5X4.js";
|
|
|
23
28
|
// bin/pushary-hook.ts
|
|
24
29
|
exitOnHelpFlag("hook");
|
|
25
30
|
var main = async () => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
rawInput += chunk;
|
|
29
|
-
}
|
|
30
|
-
if (!rawInput.trim()) {
|
|
31
|
-
process.exit(0);
|
|
32
|
-
}
|
|
33
|
-
let input;
|
|
34
|
-
try {
|
|
35
|
-
input = JSON.parse(rawInput);
|
|
36
|
-
} catch {
|
|
37
|
-
process.exit(0);
|
|
38
|
-
}
|
|
39
|
-
if (!input.tool_name) {
|
|
31
|
+
const input = await readHookInput("claude", "PreToolUse");
|
|
32
|
+
if (!input?.tool_name) {
|
|
40
33
|
process.exit(0);
|
|
41
34
|
}
|
|
42
35
|
try {
|
|
@@ -19,8 +19,8 @@ import {
|
|
|
19
19
|
} from "../chunk-GMXKITVA.js";
|
|
20
20
|
import {
|
|
21
21
|
exitOnHelpFlag
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import "../chunk-
|
|
22
|
+
} from "../chunk-SQOFGPNX.js";
|
|
23
|
+
import "../chunk-GOEXZ5QJ.js";
|
|
24
24
|
import "../chunk-BC3VCZ3E.js";
|
|
25
25
|
import {
|
|
26
26
|
getPackageVersion
|