@pushary/agent-hooks 1.7.0 → 1.7.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 +11 -0
- package/dist/bin/pushary-bell-hook.js +23 -23
- package/dist/bin/pushary-bell.js +10 -10
- package/dist/bin/pushary-claude.js +25 -25
- package/dist/bin/pushary-clean.js +116 -71
- package/dist/bin/pushary-codex-bridge.js +17 -17
- package/dist/bin/pushary-codex-hook.js +30 -30
- package/dist/bin/pushary-codex.js +12 -12
- package/dist/bin/pushary-connect.js +14 -14
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +27 -27
- package/dist/bin/pushary-disconnect.js +17 -17
- package/dist/bin/pushary-doctor.js +68 -40
- package/dist/bin/pushary-elicitation-hook.js +24 -24
- package/dist/bin/pushary-gemini-bridge.js +12 -12
- package/dist/bin/pushary-gemini-hook.js +27 -27
- package/dist/bin/pushary-hook.js +31 -31
- package/dist/bin/pushary-login.js +13 -13
- package/dist/bin/pushary-logout.js +8 -8
- package/dist/bin/pushary-mcp.js +8 -8
- package/dist/bin/pushary-mode.js +10 -10
- package/dist/bin/pushary-notification-hook.js +27 -27
- package/dist/bin/pushary-opencode-hook.js +26 -26
- package/dist/bin/pushary-permission-denied-hook.js +31 -31
- package/dist/bin/pushary-permission-hook.js +30 -30
- package/dist/bin/pushary-post-hook.js +27 -27
- package/dist/bin/pushary-prompt-hook.js +27 -27
- package/dist/bin/pushary-session-end-hook.js +27 -27
- package/dist/bin/pushary-session-start-hook.js +31 -31
- package/dist/bin/pushary-setup.js +114 -89
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +16 -16
- package/dist/bin/pushary-stop-hook.js +27 -27
- package/dist/bin/pushary-stopfailure-hook.js +27 -27
- package/dist/bin/pushary-suggestions.js +5 -5
- package/dist/bin/pushary-transcript-register.js +19 -19
- package/dist/bin/pushary-transcripts.js +7 -7
- package/dist/bin/pushary-upgrade.js +20 -20
- package/dist/bin/pushary-wait.js +10 -10
- package/dist/bin/pushary.js +6 -6
- package/dist/{chunk-YYINL576.js → chunk-2FU43B5Q.js} +2 -2
- package/dist/{chunk-D6BULEJW.js → chunk-3QE3BHBW.js} +2 -2
- package/dist/{chunk-52NVBNJT.js → chunk-3QORH5EJ.js} +3 -3
- package/dist/{chunk-PUDBG3GM.js → chunk-3T35OE7C.js} +2 -2
- package/dist/{chunk-DVQDPI3T.js → chunk-42XR73I2.js} +8 -8
- package/dist/{chunk-X6KDKOV5.js → chunk-43SSQCWO.js} +3 -3
- package/dist/{chunk-DNJUSFBL.js → chunk-454KMJHF.js} +7 -5
- package/dist/{chunk-DZURML2D.js → chunk-4C4NRDIC.js} +1 -1
- package/dist/{chunk-6ADZQFVW.js → chunk-55RO62FV.js} +1 -1
- package/dist/{chunk-QXAK5RFU.js → chunk-62TEPRWQ.js} +1 -1
- package/dist/{chunk-2PS6QWDW.js → chunk-6PV2JQ64.js} +2 -2
- package/dist/{chunk-7OS4IHGI.js → chunk-6SJQ442W.js} +2 -2
- package/dist/{chunk-UC65FJJT.js → chunk-7GI6QC3M.js} +2 -2
- package/dist/{chunk-EAQMWJPG.js → chunk-7GYGVQBU.js} +8 -8
- package/dist/{chunk-73T6MSU5.js → chunk-AAGLDXH4.js} +5 -5
- package/dist/{chunk-HDRNWNVP.js → chunk-AHWJHLG5.js} +7 -28
- package/dist/{chunk-BWYJ6AAF.js → chunk-BYVB3RX3.js} +2 -2
- package/dist/{chunk-B3UXMSMW.js → chunk-EIZW73P5.js} +1 -1
- package/dist/{chunk-B234346F.js → chunk-H6JV44TE.js} +1 -1
- package/dist/{chunk-J2355HR7.js → chunk-IGBDOZUO.js} +1 -1
- package/dist/{chunk-DANOZVZK.js → chunk-JMBG47WV.js} +30 -1
- package/dist/{chunk-KW2RRR7D.js → chunk-JTQDP4ZL.js} +3 -3
- package/dist/{chunk-WUNZAE7I.js → chunk-KBLIVEFJ.js} +5 -5
- package/dist/{chunk-V6QRSU2G.js → chunk-KSNAAMU5.js} +4 -4
- package/dist/{chunk-2C7CCWVX.js → chunk-MCNS4725.js} +1 -1
- package/dist/{chunk-5HLTWFJ6.js → chunk-MWVCDP64.js} +1 -1
- package/dist/{chunk-L4H2Q2S4.js → chunk-NAAZCNKI.js} +153 -13
- package/dist/{chunk-B3YQANFN.js → chunk-NID4UZDN.js} +1 -1
- package/dist/{chunk-JNXVOU6Y.js → chunk-NQFGVAT6.js} +2 -2
- package/dist/{chunk-BH2SKSSK.js → chunk-O5JD7UI5.js} +1 -1
- package/dist/{chunk-5RUIFDTP.js → chunk-O5PRIYFZ.js} +30 -2
- package/dist/{chunk-V4AQBAVG.js → chunk-OAL44FM2.js} +1 -1
- package/dist/{chunk-KXMZMZD3.js → chunk-OTZHT34O.js} +1 -1
- package/dist/{chunk-XNCMT7YY.js → chunk-P5CBNSYL.js} +1 -1
- package/dist/{chunk-JXUAXO74.js → chunk-Q7QRR6YL.js} +2 -2
- package/dist/{chunk-BBKNJJVX.js → chunk-QPR33SHS.js} +6 -6
- package/dist/{chunk-LEZFOTMI.js → chunk-SNWNA3MQ.js} +1 -1
- package/dist/{chunk-R2XCLT6I.js → chunk-SVEMF2VO.js} +4 -4
- package/dist/{chunk-ROQK7IN3.js → chunk-UPKP67TA.js} +2 -2
- package/dist/{chunk-SQRWHALT.js → chunk-VCMFKZON.js} +2 -2
- package/dist/{chunk-IJ6ECPA6.js → chunk-WM3U2RUK.js} +8 -8
- package/dist/{chunk-KYQXUGH7.js → chunk-WSC53O7I.js} +3 -3
- package/dist/{chunk-ZQ7IDOKY.js → chunk-WZWXBTRF.js} +3 -3
- package/dist/{chunk-PQ4F64M2.js → chunk-XDASEYRS.js} +3 -3
- package/dist/{chunk-YROGUPOZ.js → chunk-XFNVG3OV.js} +1 -1
- package/dist/{chunk-CVALVGA7.js → chunk-XMN37YJH.js} +1 -1
- package/dist/{chunk-VKVIAZQO.js → chunk-XPMOCJHN.js} +1 -1
- package/dist/{chunk-B76WVEDX.js → chunk-XPTCPU6V.js} +1 -1
- package/dist/{chunk-O2LEPIU6.js → chunk-Y6GKOZBT.js} +1 -1
- package/dist/{chunk-4F46VIEE.js → chunk-YQN7S57T.js} +6 -6
- package/dist/{chunk-UOAQ6QMP.js → chunk-YZKS3ME3.js} +2 -2
- package/dist/{chunk-S3UD4V6W.js → chunk-ZEMSCGDD.js} +6 -1
- package/dist/{chunk-EGKXSQCY.js → chunk-ZIIYTQHC.js} +4 -4
- package/dist/{reapply-6PH3FMPX.js → reapply-66GQIBXN.js} +9 -9
- package/dist/src/index.js +19 -19
- package/package.json +1 -1
- package/dist/chunk-P32LPT2L.js +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.7.1
|
|
4
|
+
|
|
5
|
+
- **fx asks through Pushary.** Setup now adds `"ask_user_question": "deny"` as the last rule in `~/.fx/settings.json`, which removes fx's own terminal question tool from what its agent can call, so every question goes through `mcp_pushary_ask_user`: to the Mac notch at the Mac, to the phone away from it. fx cannot forward its own prompt, so a question asked there used to wait unseen once you walked away. A rule you already set for `ask_user_question` is kept, and setup names it. The instructions in `~/.fx/AGENTS.md` now tell fx's agent to load `mcp_pushary_ask_user` with `mcp_select_tool` by exact name and to ask there even while you are at the terminal, and to ask in its reply only when Pushary hands the question back or cannot be reached.
|
|
6
|
+
- fx's full-access mode (`yolo`, `full-access` or `full access`, from settings, a workspace, or `FX_PERMISSION_MODE`) ignores permission rules, so the terminal question tool stays on there; setup and `pushary doctor` say so instead of claiming questions are routed, and the instructions still steer the agent to Pushary. fx workspaces with their own permission rules replace the global ones, and setup and doctor name how many keep the question tool on. Setup reads the rules the way fx does (globs, last match wins, per-target maps) and leaves a `settings.json` fx would reject, such as one with an unknown action or permission mode, untouched and says fx ignores it.
|
|
7
|
+
- `pushary clean` removes the question rule only when setup recorded adding it and it is still `deny`, so a rule of your own survives.
|
|
8
|
+
- `pushary clean` now removes Pushary entries from every event in `~/.cursor/hooks.json`, not only the events the permission gate uses. The Mac app registers its bridge on session, compaction and stop events too, and those eight entries were left behind under "Clean complete". Other tools' hooks are untouched.
|
|
9
|
+
- `pushary clean` now removes the Pushary block from OpenCode's `~/.config/opencode/AGENTS.md`, as it already did for Codex and Gemini. Setup wrote it and clean left it.
|
|
10
|
+
- `pushary clean` removes temp files that an interrupted config write left next to an agent's config (`.<file>.pushary-<id>` and `.<pid>-<time>.pushary-tmp`), only next to the agent configs clean rewrites (your home folder, Claude Code, Codex, Gemini, Cursor, OpenCode, fx and VS Code settings), never through a symlink, and only once they are over a minute old.
|
|
11
|
+
- Setup's summary no longer says "(others completed successfully)" or "Other agents will continue" when the failed agent was the only one; it names the agents that were configured.
|
|
12
|
+
- Setup's progress lines no longer leave the tail of the previous frame behind ("with Codexex", "tap the notificationon"): setup uses the shared spinner, which clears the line, keeps each frame to one terminal row, and does not animate into a log when colour is forced on.
|
|
13
|
+
|
|
3
14
|
## 1.7.0
|
|
4
15
|
|
|
5
16
|
- **fx.** `npx @pushary/agent-hooks@latest setup --agents fx`, or ticking fx in the picker, connects Vercel Labs' fx coding agent. Setup adds a `pushary` server to `~/.fx/mcp.json` that runs the new `pushary-mcp` command, a local bridge that signs in with the key setup saved in `~/.pushary`. No key is written to fx's files, and a rotated key is used without running setup again. fx has no hooks other tools can register, so Pushary cannot answer fx's own approval prompts; fx's agent asks through Pushary's tools when it chooses to, guided by a managed block setup writes to `~/.fx/AGENTS.md`.
|
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleBell
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-55RO62FV.js";
|
|
5
5
|
import {
|
|
6
6
|
readHookInput
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-7GI6QC3M.js";
|
|
8
|
+
import "../chunk-7GYGVQBU.js";
|
|
9
9
|
import "../chunk-SGZJ5LYH.js";
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
18
|
-
import "../chunk-
|
|
19
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-SVEMF2VO.js";
|
|
11
|
+
import "../chunk-XMN37YJH.js";
|
|
12
|
+
import "../chunk-MWVCDP64.js";
|
|
13
|
+
import "../chunk-XDASEYRS.js";
|
|
14
|
+
import "../chunk-AAGLDXH4.js";
|
|
15
|
+
import "../chunk-WZWXBTRF.js";
|
|
16
|
+
import "../chunk-XPMOCJHN.js";
|
|
17
|
+
import "../chunk-O5JD7UI5.js";
|
|
18
|
+
import "../chunk-OTZHT34O.js";
|
|
19
|
+
import "../chunk-XPTCPU6V.js";
|
|
20
20
|
import "../chunk-XHKBHWLX.js";
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-4C4NRDIC.js";
|
|
22
|
+
import "../chunk-KSNAAMU5.js";
|
|
23
23
|
import "../chunk-POFBE6ZY.js";
|
|
24
24
|
import "../chunk-GMXKITVA.js";
|
|
25
|
-
import "../chunk-
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
25
|
+
import "../chunk-YZKS3ME3.js";
|
|
26
|
+
import "../chunk-JTQDP4ZL.js";
|
|
27
|
+
import "../chunk-P5CBNSYL.js";
|
|
28
28
|
import "../chunk-7QLSKOSU.js";
|
|
29
29
|
import "../chunk-KZERVKTD.js";
|
|
30
|
-
import "../chunk-
|
|
31
|
-
import "../chunk-
|
|
30
|
+
import "../chunk-UPKP67TA.js";
|
|
31
|
+
import "../chunk-454KMJHF.js";
|
|
32
32
|
import "../chunk-T7E75EKA.js";
|
|
33
|
-
import "../chunk-
|
|
34
|
-
import "../chunk-
|
|
35
|
-
import "../chunk-
|
|
33
|
+
import "../chunk-OAL44FM2.js";
|
|
34
|
+
import "../chunk-EIZW73P5.js";
|
|
35
|
+
import "../chunk-XFNVG3OV.js";
|
|
36
36
|
|
|
37
37
|
// bin/pushary-bell-hook.ts
|
|
38
38
|
var main = async () => {
|
package/dist/bin/pushary-bell.js
CHANGED
|
@@ -5,37 +5,37 @@ import {
|
|
|
5
5
|
liveAgentCount,
|
|
6
6
|
ring,
|
|
7
7
|
upgradeThreshold
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-55RO62FV.js";
|
|
9
9
|
import {
|
|
10
10
|
addBellHooks,
|
|
11
11
|
bellInstalled,
|
|
12
12
|
removeBellHooks
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-XPMOCJHN.js";
|
|
14
14
|
import {
|
|
15
15
|
createIo
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-O5PRIYFZ.js";
|
|
17
17
|
import {
|
|
18
18
|
exitOnHelpFlag
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-6PV2JQ64.js";
|
|
20
20
|
import {
|
|
21
21
|
parseFlags
|
|
22
22
|
} from "../chunk-GMXKITVA.js";
|
|
23
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-YZKS3ME3.js";
|
|
24
24
|
import "../chunk-7QLSKOSU.js";
|
|
25
25
|
import {
|
|
26
26
|
EXIT
|
|
27
27
|
} from "../chunk-KZERVKTD.js";
|
|
28
|
-
import "../chunk-
|
|
28
|
+
import "../chunk-UPKP67TA.js";
|
|
29
29
|
import {
|
|
30
30
|
claudeSettings
|
|
31
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-454KMJHF.js";
|
|
32
32
|
import {
|
|
33
33
|
readJsonSafe,
|
|
34
34
|
writeJsonAtomic
|
|
35
35
|
} from "../chunk-T7E75EKA.js";
|
|
36
|
-
import "../chunk-
|
|
37
|
-
import "../chunk-
|
|
38
|
-
import "../chunk-
|
|
36
|
+
import "../chunk-OAL44FM2.js";
|
|
37
|
+
import "../chunk-EIZW73P5.js";
|
|
38
|
+
import "../chunk-XFNVG3OV.js";
|
|
39
39
|
|
|
40
40
|
// bin/pushary-bell.ts
|
|
41
41
|
exitOnHelpFlag("bell");
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
describeIdleWindow,
|
|
9
9
|
startProcessOwnership,
|
|
10
10
|
withSpawnProcessOwnership
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-SNWNA3MQ.js";
|
|
12
12
|
import {
|
|
13
13
|
isDeferAnswer
|
|
14
14
|
} from "../chunk-YHG74UFF.js";
|
|
@@ -17,24 +17,24 @@ import {
|
|
|
17
17
|
loadSessionKey,
|
|
18
18
|
registerTranscript,
|
|
19
19
|
registeredTranscriptEnabled
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-7GYGVQBU.js";
|
|
21
21
|
import "../chunk-SGZJ5LYH.js";
|
|
22
|
-
import "../chunk-
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
25
|
-
import "../chunk-
|
|
22
|
+
import "../chunk-SVEMF2VO.js";
|
|
23
|
+
import "../chunk-XMN37YJH.js";
|
|
24
|
+
import "../chunk-MWVCDP64.js";
|
|
25
|
+
import "../chunk-XDASEYRS.js";
|
|
26
26
|
import {
|
|
27
27
|
ensureDaemonRunning
|
|
28
|
-
} from "../chunk-
|
|
29
|
-
import "../chunk-
|
|
30
|
-
import "../chunk-
|
|
28
|
+
} from "../chunk-AAGLDXH4.js";
|
|
29
|
+
import "../chunk-WZWXBTRF.js";
|
|
30
|
+
import "../chunk-XPMOCJHN.js";
|
|
31
31
|
import {
|
|
32
32
|
encryptRecord
|
|
33
|
-
} from "../chunk-
|
|
34
|
-
import "../chunk-
|
|
33
|
+
} from "../chunk-O5JD7UI5.js";
|
|
34
|
+
import "../chunk-OTZHT34O.js";
|
|
35
35
|
import {
|
|
36
36
|
transcriptsEnabled
|
|
37
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-XPTCPU6V.js";
|
|
38
38
|
import {
|
|
39
39
|
needsShell,
|
|
40
40
|
spawnClaude
|
|
@@ -56,8 +56,8 @@ import {
|
|
|
56
56
|
reportEvent,
|
|
57
57
|
savePendingCommand,
|
|
58
58
|
scopePathFor
|
|
59
|
-
} from "../chunk-
|
|
60
|
-
import "../chunk-
|
|
59
|
+
} from "../chunk-WM3U2RUK.js";
|
|
60
|
+
import "../chunk-4C4NRDIC.js";
|
|
61
61
|
import {
|
|
62
62
|
DECISION_STOP_REASON,
|
|
63
63
|
askUser,
|
|
@@ -67,33 +67,33 @@ import {
|
|
|
67
67
|
nextLongPollMs,
|
|
68
68
|
waitForAnswer,
|
|
69
69
|
withdrawQuestion
|
|
70
|
-
} from "../chunk-
|
|
71
|
-
import "../chunk-
|
|
70
|
+
} from "../chunk-ZIIYTQHC.js";
|
|
71
|
+
import "../chunk-KSNAAMU5.js";
|
|
72
72
|
import "../chunk-POFBE6ZY.js";
|
|
73
73
|
import "../chunk-GMXKITVA.js";
|
|
74
|
-
import "../chunk-
|
|
75
|
-
import "../chunk-
|
|
76
|
-
import "../chunk-
|
|
74
|
+
import "../chunk-YZKS3ME3.js";
|
|
75
|
+
import "../chunk-NQFGVAT6.js";
|
|
76
|
+
import "../chunk-JTQDP4ZL.js";
|
|
77
77
|
import {
|
|
78
78
|
getMachineId
|
|
79
|
-
} from "../chunk-
|
|
79
|
+
} from "../chunk-P5CBNSYL.js";
|
|
80
80
|
import "../chunk-7QLSKOSU.js";
|
|
81
81
|
import "../chunk-KZERVKTD.js";
|
|
82
|
-
import "../chunk-
|
|
83
|
-
import "../chunk-
|
|
82
|
+
import "../chunk-UPKP67TA.js";
|
|
83
|
+
import "../chunk-454KMJHF.js";
|
|
84
84
|
import "../chunk-T7E75EKA.js";
|
|
85
85
|
import {
|
|
86
86
|
getApiKey,
|
|
87
87
|
getBaseUrl
|
|
88
|
-
} from "../chunk-
|
|
88
|
+
} from "../chunk-OAL44FM2.js";
|
|
89
89
|
import {
|
|
90
90
|
NPX_LATEST_COMMAND
|
|
91
|
-
} from "../chunk-
|
|
91
|
+
} from "../chunk-EIZW73P5.js";
|
|
92
92
|
import {
|
|
93
93
|
KILL_REASON,
|
|
94
94
|
redactSecrets,
|
|
95
95
|
resolveGate
|
|
96
|
-
} from "../chunk-
|
|
96
|
+
} from "../chunk-XFNVG3OV.js";
|
|
97
97
|
|
|
98
98
|
// src/wrapper/localPassthrough.ts
|
|
99
99
|
var SIGNAL_NUMBERS = {
|
|
@@ -6,14 +6,16 @@ import {
|
|
|
6
6
|
PUSHARY_SKILL_SOURCE,
|
|
7
7
|
createGuards,
|
|
8
8
|
resolveHermesPython,
|
|
9
|
-
runHermesPythonScript
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
runHermesPythonScript,
|
|
10
|
+
withoutPusharyCursorHooks
|
|
11
|
+
} from "../chunk-JMBG47WV.js";
|
|
12
12
|
import {
|
|
13
13
|
FX_PROFILE_REFUSALS,
|
|
14
|
+
FX_QUESTION_TOOL,
|
|
14
15
|
FX_SETTINGS_REFUSALS,
|
|
15
16
|
fxProfileText,
|
|
16
17
|
fxSettingsText,
|
|
18
|
+
isFxQuestionRuleReceipt,
|
|
17
19
|
readFxFile,
|
|
18
20
|
readFxProfile,
|
|
19
21
|
readFxSettings,
|
|
@@ -22,19 +24,22 @@ import {
|
|
|
22
24
|
unregisterPluginLocation,
|
|
23
25
|
vscodeSettingsTargets,
|
|
24
26
|
withoutFxPusharyServer,
|
|
25
|
-
withoutPusharyToolsAllowed
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
withoutPusharyToolsAllowed,
|
|
28
|
+
withoutQuestionsRoutedToPushary
|
|
29
|
+
} from "../chunk-NAAZCNKI.js";
|
|
30
|
+
import "../chunk-2FU43B5Q.js";
|
|
28
31
|
import {
|
|
29
32
|
OPENCODE_PLUGIN_SIBLING,
|
|
30
33
|
OPENCODE_PLUGIN_SIBLING_CONTENTS,
|
|
31
34
|
hasForeignPlugins,
|
|
32
35
|
isOpenCodePluginOurs,
|
|
36
|
+
openCodeConfigDir,
|
|
33
37
|
openCodeConfigFile,
|
|
38
|
+
openCodeInstructionsFile,
|
|
34
39
|
openCodePluginDir,
|
|
35
40
|
openCodePluginFile,
|
|
36
41
|
removeOpenCodeMcpServer
|
|
37
|
-
} from "../chunk-
|
|
42
|
+
} from "../chunk-NID4UZDN.js";
|
|
38
43
|
import {
|
|
39
44
|
compatibleConfigFile,
|
|
40
45
|
compatibleInstructionsFile,
|
|
@@ -42,44 +47,42 @@ import {
|
|
|
42
47
|
compatiblePermissionRuleFile,
|
|
43
48
|
removeCompatibleHooks,
|
|
44
49
|
removeCompatibleMcpServer
|
|
45
|
-
} from "../chunk-
|
|
50
|
+
} from "../chunk-KBLIVEFJ.js";
|
|
46
51
|
import {
|
|
47
52
|
isClaudeMcpSnapshot,
|
|
48
53
|
removeClaudeMcpServers,
|
|
49
54
|
removePusharySettings,
|
|
50
55
|
removePusharyToolPermissions,
|
|
51
56
|
restoreClaudeMcpServer
|
|
52
|
-
} from "../chunk-
|
|
57
|
+
} from "../chunk-WSC53O7I.js";
|
|
53
58
|
import {
|
|
54
59
|
hookOwnerOf,
|
|
55
60
|
isHookTakeoverReceipt,
|
|
56
61
|
restoreHookTakeover,
|
|
57
62
|
restoreMcpServer
|
|
58
|
-
} from "../chunk-
|
|
59
|
-
import "../chunk-
|
|
63
|
+
} from "../chunk-SVEMF2VO.js";
|
|
64
|
+
import "../chunk-XMN37YJH.js";
|
|
60
65
|
import {
|
|
61
66
|
liveBridgeProbe,
|
|
62
67
|
resolveBridgeStub
|
|
63
|
-
} from "../chunk-
|
|
64
|
-
import
|
|
65
|
-
pusharyHookExecutable
|
|
66
|
-
} from "../chunk-PQ4F64M2.js";
|
|
68
|
+
} from "../chunk-MWVCDP64.js";
|
|
69
|
+
import "../chunk-XDASEYRS.js";
|
|
67
70
|
import {
|
|
68
71
|
disableDaemonService
|
|
69
|
-
} from "../chunk-
|
|
72
|
+
} from "../chunk-AAGLDXH4.js";
|
|
70
73
|
import {
|
|
71
74
|
removeGeminiSettings
|
|
72
|
-
} from "../chunk-
|
|
73
|
-
import "../chunk-
|
|
75
|
+
} from "../chunk-WZWXBTRF.js";
|
|
76
|
+
import "../chunk-XPMOCJHN.js";
|
|
74
77
|
import "../chunk-XHKBHWLX.js";
|
|
75
|
-
import "../chunk-
|
|
76
|
-
import "../chunk-
|
|
77
|
-
import "../chunk-
|
|
78
|
-
import "../chunk-
|
|
78
|
+
import "../chunk-WM3U2RUK.js";
|
|
79
|
+
import "../chunk-4C4NRDIC.js";
|
|
80
|
+
import "../chunk-ZIIYTQHC.js";
|
|
81
|
+
import "../chunk-KSNAAMU5.js";
|
|
79
82
|
import "../chunk-POFBE6ZY.js";
|
|
80
83
|
import {
|
|
81
84
|
exitOnHelpFlag
|
|
82
|
-
} from "../chunk-
|
|
85
|
+
} from "../chunk-6PV2JQ64.js";
|
|
83
86
|
import {
|
|
84
87
|
rejectUnknownFlags
|
|
85
88
|
} from "../chunk-GMXKITVA.js";
|
|
@@ -87,15 +90,15 @@ import {
|
|
|
87
90
|
CANDIDATE_RCS,
|
|
88
91
|
isDisabledExport,
|
|
89
92
|
removeClaudeAlias
|
|
90
|
-
} from "../chunk-
|
|
91
|
-
import "../chunk-
|
|
92
|
-
import "../chunk-
|
|
93
|
-
import "../chunk-
|
|
93
|
+
} from "../chunk-YZKS3ME3.js";
|
|
94
|
+
import "../chunk-NQFGVAT6.js";
|
|
95
|
+
import "../chunk-JTQDP4ZL.js";
|
|
96
|
+
import "../chunk-P5CBNSYL.js";
|
|
94
97
|
import "../chunk-7QLSKOSU.js";
|
|
95
98
|
import {
|
|
96
99
|
EXIT
|
|
97
100
|
} from "../chunk-KZERVKTD.js";
|
|
98
|
-
import "../chunk-
|
|
101
|
+
import "../chunk-UPKP67TA.js";
|
|
99
102
|
import {
|
|
100
103
|
bridgeAgentKey,
|
|
101
104
|
claudeJson,
|
|
@@ -113,13 +116,14 @@ import {
|
|
|
113
116
|
cursorUserMcp,
|
|
114
117
|
execNpm,
|
|
115
118
|
fxAgentsMd,
|
|
119
|
+
fxConfigDir,
|
|
116
120
|
fxMcpProfile,
|
|
121
|
+
fxQuestionRuleReceipt,
|
|
117
122
|
fxSettings,
|
|
118
123
|
geminiMd,
|
|
119
124
|
geminiSettings,
|
|
120
125
|
hermesConfigReceipt,
|
|
121
126
|
hookTakeoverReceipt,
|
|
122
|
-
isProtectedByScope,
|
|
123
127
|
pusharyDir,
|
|
124
128
|
readCodexMcpAuth,
|
|
125
129
|
removeCodexHookTrust,
|
|
@@ -127,23 +131,22 @@ import {
|
|
|
127
131
|
restoreCodexHookTrust,
|
|
128
132
|
vscodePluginDir,
|
|
129
133
|
vscodePluginMcp
|
|
130
|
-
} from "../chunk-
|
|
134
|
+
} from "../chunk-454KMJHF.js";
|
|
131
135
|
import "../chunk-T7E75EKA.js";
|
|
132
|
-
import "../chunk-
|
|
133
|
-
import "../chunk-
|
|
136
|
+
import "../chunk-OAL44FM2.js";
|
|
137
|
+
import "../chunk-EIZW73P5.js";
|
|
134
138
|
import {
|
|
135
|
-
CURSOR_GATE_EVENTS,
|
|
136
139
|
HOOK_COMPATIBLE_PROFILES,
|
|
137
140
|
HOOK_LOCATOR_BINARY,
|
|
138
141
|
SUPPORT_DISCORD,
|
|
139
142
|
SUPPORT_EMAIL,
|
|
140
143
|
isValidApiKey,
|
|
141
144
|
redactSecrets
|
|
142
|
-
} from "../chunk-
|
|
145
|
+
} from "../chunk-XFNVG3OV.js";
|
|
143
146
|
|
|
144
147
|
// bin/pushary-clean.ts
|
|
145
|
-
import { existsSync as existsSync6, readFileSync as readFileSync4, copyFileSync, readdirSync as
|
|
146
|
-
import { dirname, join as
|
|
148
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, copyFileSync, readdirSync as readdirSync4 } from "fs";
|
|
149
|
+
import { dirname, join as join6 } from "path";
|
|
147
150
|
import { homedir as homedir5, tmpdir } from "os";
|
|
148
151
|
import { confirm } from "@inquirer/prompts";
|
|
149
152
|
import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
|
|
@@ -425,6 +428,26 @@ var claudeBackupRewrites = (receipt, home = homedir4()) => claudeJsonBackups(hom
|
|
|
425
428
|
` }] : [];
|
|
426
429
|
});
|
|
427
430
|
|
|
431
|
+
// src/cli/config-temp-leftovers.ts
|
|
432
|
+
import { lstatSync, readdirSync as readdirSync3 } from "fs";
|
|
433
|
+
import { join as join5 } from "path";
|
|
434
|
+
var MAC_APP_WRITE_TEMP = /^\..+\.pushary-[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/;
|
|
435
|
+
var PID_STAMPED_WRITE_TEMP = /^\.\d+-[^/]+\.pushary-tmp$/;
|
|
436
|
+
var CONFIG_TEMP_MIN_AGE_MS = 6e4;
|
|
437
|
+
var isLeakedConfigTempName = (name) => MAC_APP_WRITE_TEMP.test(name) || PID_STAMPED_WRITE_TEMP.test(name);
|
|
438
|
+
var leakedConfigTemps = (entries, nowMs) => entries.filter((entry) => entry.isFile && isLeakedConfigTempName(entry.name) && nowMs - entry.modifiedAtMs >= CONFIG_TEMP_MIN_AGE_MS).map((entry) => entry.name);
|
|
439
|
+
var directoryEntries = (directory) => {
|
|
440
|
+
try {
|
|
441
|
+
return readdirSync3(directory).flatMap((name) => {
|
|
442
|
+
const stats = lstatSync(join5(directory, name), { throwIfNoEntry: false });
|
|
443
|
+
return stats ? [{ name, isFile: stats.isFile(), modifiedAtMs: stats.mtimeMs }] : [];
|
|
444
|
+
});
|
|
445
|
+
} catch {
|
|
446
|
+
return [];
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
var configTempLeftovers = (directories, nowMs) => [...new Set(directories)].flatMap((directory) => leakedConfigTemps(directoryEntries(directory), nowMs).map((name) => join5(directory, name)));
|
|
450
|
+
|
|
428
451
|
// src/app-owned-paths.ts
|
|
429
452
|
var APP_OWNED_ENTRIES = [
|
|
430
453
|
// PusharyPaths.bin: bridgeStub, bridgeCache
|
|
@@ -477,13 +500,13 @@ var CURSOR_PLUGIN_DIR = cursorPluginDir();
|
|
|
477
500
|
var CURSOR_USER_HOOKS = cursorUserHooks();
|
|
478
501
|
var VSCODE_PLUGIN_DIR = vscodePluginDir();
|
|
479
502
|
var PUSHARY_DIR = pusharyDir();
|
|
480
|
-
var SHELL_FILES = [".zshrc", ".zprofile", ".bashrc", ".bash_profile"].map((f) =>
|
|
503
|
+
var SHELL_FILES = [".zshrc", ".zprofile", ".bashrc", ".bash_profile"].map((f) => join6(homedir5(), f));
|
|
481
504
|
var PRESENCE_BY_RESOLUTION = {
|
|
482
505
|
bundle: "present",
|
|
483
506
|
missing: "gone",
|
|
484
507
|
"no-stub": "absent"
|
|
485
508
|
};
|
|
486
|
-
var macAppPresence = () => PRESENCE_BY_RESOLUTION[resolveBridgeStub(
|
|
509
|
+
var macAppPresence = () => PRESENCE_BY_RESOLUTION[resolveBridgeStub(join6(PUSHARY_DIR, "bin", HOOK_LOCATOR_BINARY), liveBridgeProbe()).kind];
|
|
487
510
|
var removalScope = (keepMcpServer, keepAppWiring) => ({
|
|
488
511
|
keepAppWiring,
|
|
489
512
|
keepMcpServer
|
|
@@ -512,7 +535,7 @@ var cursorPluginLeftovers = () => {
|
|
|
512
535
|
const parent = dirname(CURSOR_PLUGIN_DIR);
|
|
513
536
|
const backupPrefix = `${CURSOR_PLUGIN_DIR.split("/").pop()}.pushary-backup-`;
|
|
514
537
|
try {
|
|
515
|
-
return
|
|
538
|
+
return readdirSync4(parent).filter((name) => name.startsWith(backupPrefix) || name.startsWith(CURSOR_PLUGIN_STAGING)).map((name) => join6(parent, name));
|
|
516
539
|
} catch {
|
|
517
540
|
return [];
|
|
518
541
|
}
|
|
@@ -533,7 +556,7 @@ var guardedInstructionBlockRemoval = (path) => {
|
|
|
533
556
|
};
|
|
534
557
|
var guardedAliasRemoval = () => {
|
|
535
558
|
if (!dryRun) return removeClaudeAlias();
|
|
536
|
-
const shells = CANDIDATE_RCS.map((name) =>
|
|
559
|
+
const shells = CANDIDATE_RCS.map((name) => join6(homedir5(), name)).filter((path) => existsSync6(path) && readFileSync4(path, "utf-8").includes("pushary claude"));
|
|
537
560
|
for (const path of shells) wouldNote("rewrite", path);
|
|
538
561
|
return shells;
|
|
539
562
|
};
|
|
@@ -577,6 +600,25 @@ var removeFxToolsRule = () => {
|
|
|
577
600
|
const { settings, removed } = withoutPusharyToolsAllowed(read.settings);
|
|
578
601
|
if (removed) writeFxText(path, fxSettingsText(settings), "fx auto-allowed Pushary tools");
|
|
579
602
|
};
|
|
603
|
+
var FX_QUESTION_RULE_KEPT = {
|
|
604
|
+
"not-ours": "no setup record says Pushary added it, so it may be yours; left as it is",
|
|
605
|
+
"changed-after-setup": "changed after setup; left as it is"
|
|
606
|
+
};
|
|
607
|
+
var readFxQuestionRuleReceipt = () => {
|
|
608
|
+
const receipt = readJson(fxQuestionRuleReceipt());
|
|
609
|
+
return isFxQuestionRuleReceipt(receipt) ? receipt : null;
|
|
610
|
+
};
|
|
611
|
+
var removeFxQuestionRule = () => {
|
|
612
|
+
const path = fxSettings();
|
|
613
|
+
const read = readFxFile(path, readFxSettings);
|
|
614
|
+
if (read.kind === "refused" || read.kind === "unreadable") return;
|
|
615
|
+
if (read.kind === "settings") {
|
|
616
|
+
const { settings, outcome } = withoutQuestionsRoutedToPushary(read.settings, readFxQuestionRuleReceipt());
|
|
617
|
+
if (outcome === "removed") writeFxText(path, fxSettingsText(settings), "fx question rule");
|
|
618
|
+
else if (outcome !== "absent") console.log(` ${skip} fx question rule ${dim(`(${FX_QUESTION_TOOL} in ${path}: ${FX_QUESTION_RULE_KEPT[outcome]})`)}`);
|
|
619
|
+
}
|
|
620
|
+
guardedRemove(fxQuestionRuleReceipt(), { force: true });
|
|
621
|
+
};
|
|
580
622
|
var removeFxInstructions = () => {
|
|
581
623
|
if (guardedInstructionBlockRemoval(fxAgentsMd())) {
|
|
582
624
|
console.log(` ${check} fx instructions ${dim(did("removed"))}`);
|
|
@@ -591,21 +633,9 @@ var removeCursorUserHook = (scope) => {
|
|
|
591
633
|
return "failed";
|
|
592
634
|
}
|
|
593
635
|
if (!parsed2 || typeof parsed2 !== "object") return "failed";
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const existing = Array.isArray(hooks[event]) ? hooks[event] : [];
|
|
598
|
-
const others = existing.filter((h) => {
|
|
599
|
-
const command = String(h.command ?? "");
|
|
600
|
-
return pusharyHookExecutable(command) === null || isProtectedByScope(command, scope);
|
|
601
|
-
});
|
|
602
|
-
if (others.length === existing.length) continue;
|
|
603
|
-
removedAny = true;
|
|
604
|
-
if (others.length === 0) delete hooks[event];
|
|
605
|
-
else hooks[event] = others;
|
|
606
|
-
}
|
|
607
|
-
if (!removedAny) return "absent";
|
|
608
|
-
parsed2.hooks = hooks;
|
|
636
|
+
const removal = withoutPusharyCursorHooks(parsed2.hooks ?? {}, scope);
|
|
637
|
+
if (removal.removed === 0) return "absent";
|
|
638
|
+
parsed2.hooks = removal.hooks;
|
|
609
639
|
try {
|
|
610
640
|
writeJson(CURSOR_USER_HOOKS, parsed2);
|
|
611
641
|
} catch {
|
|
@@ -614,15 +644,7 @@ var removeCursorUserHook = (scope) => {
|
|
|
614
644
|
if (dryRun) return "removed";
|
|
615
645
|
try {
|
|
616
646
|
const after = JSON.parse(readFileSync4(CURSOR_USER_HOOKS, "utf-8"));
|
|
617
|
-
|
|
618
|
-
const stillThere = CURSOR_GATE_EVENTS.some((event) => {
|
|
619
|
-
const entries = afterHooks[event];
|
|
620
|
-
return Array.isArray(entries) && entries.some((h) => {
|
|
621
|
-
const command = String(h?.command ?? "");
|
|
622
|
-
return pusharyHookExecutable(command) !== null && !isProtectedByScope(command, scope);
|
|
623
|
-
});
|
|
624
|
-
});
|
|
625
|
-
if (stillThere) return "failed";
|
|
647
|
+
if (withoutPusharyCursorHooks(after?.hooks ?? {}, scope).removed > 0) return "failed";
|
|
626
648
|
} catch {
|
|
627
649
|
return "failed";
|
|
628
650
|
}
|
|
@@ -647,13 +669,23 @@ var cleanSettingsFile = (path, label, scope) => {
|
|
|
647
669
|
` ${skip} ${label} ${dim(wouldHaveChanged ? "(kept: written by the Mac app)" : "(no pushary entries)")}`
|
|
648
670
|
);
|
|
649
671
|
};
|
|
672
|
+
var agentConfigDirectories = () => [
|
|
673
|
+
homedir5(),
|
|
674
|
+
dirname(CLAUDE_SETTINGS),
|
|
675
|
+
dirname(codexConfigToml()),
|
|
676
|
+
dirname(geminiSettings()),
|
|
677
|
+
dirname(CURSOR_USER_HOOKS),
|
|
678
|
+
openCodeConfigDir(),
|
|
679
|
+
fxConfigDir(),
|
|
680
|
+
...vscodeSettingsTargets(existsSync6).map((settings) => dirname(settings))
|
|
681
|
+
];
|
|
650
682
|
var restoreTakeoverReceipts = () => {
|
|
651
683
|
const targets = [
|
|
652
684
|
["claude_code", CLAUDE_SETTINGS, CLAUDE_JSON, "mcpServers", "json"],
|
|
653
685
|
["codex", codexHooksJson(), codexConfigToml(), "mcp_servers", "toml"],
|
|
654
686
|
["gemini_cli", geminiSettings(), geminiSettings(), "mcpServers", "json"],
|
|
655
687
|
["cursor", CURSOR_USER_HOOKS, null, null, null],
|
|
656
|
-
["vscode",
|
|
688
|
+
["vscode", join6(VSCODE_PLUGIN_DIR, "hooks", "hooks.json"), vscodePluginMcp(), "mcpServers", "json"]
|
|
657
689
|
];
|
|
658
690
|
for (const [agent, hookFile, mcpFile, mcpKey, mcpFormat] of targets) {
|
|
659
691
|
const receiptPath = hookTakeoverReceipt(agent);
|
|
@@ -1027,10 +1059,10 @@ var main = async () => {
|
|
|
1027
1059
|
} else {
|
|
1028
1060
|
guardedRemove(openCodePlugin, { force: true });
|
|
1029
1061
|
console.log(` ${check} OpenCode plugin ${dim(did("removed"))}`);
|
|
1030
|
-
const sibling =
|
|
1062
|
+
const sibling = join6(openCodePluginDir(), OPENCODE_PLUGIN_SIBLING);
|
|
1031
1063
|
const remaining = (() => {
|
|
1032
1064
|
try {
|
|
1033
|
-
return
|
|
1065
|
+
return readdirSync4(openCodePluginDir()).filter((name) => name !== OPENCODE_PLUGIN_SIBLING);
|
|
1034
1066
|
} catch {
|
|
1035
1067
|
return [];
|
|
1036
1068
|
}
|
|
@@ -1054,8 +1086,16 @@ var main = async () => {
|
|
|
1054
1086
|
} else {
|
|
1055
1087
|
console.log(` ${skip} OpenCode MCP ${dim("(not found)")}`);
|
|
1056
1088
|
}
|
|
1089
|
+
if (keepShared) {
|
|
1090
|
+
console.log(` ${skip} OpenCode AGENTS.md ${dim("(kept: the Mac app uses it)")}`);
|
|
1091
|
+
} else if (guardedInstructionBlockRemoval(openCodeInstructionsFile())) {
|
|
1092
|
+
console.log(` ${check} OpenCode AGENTS.md ${dim("(removed Pushary block)")}`);
|
|
1093
|
+
} else {
|
|
1094
|
+
console.log(` ${skip} OpenCode AGENTS.md ${dim("(no pushary block)")}`);
|
|
1095
|
+
}
|
|
1057
1096
|
removeFxMcpServer();
|
|
1058
1097
|
removeFxToolsRule();
|
|
1098
|
+
removeFxQuestionRule();
|
|
1059
1099
|
removeFxInstructions();
|
|
1060
1100
|
const hermesPython = resolveHermesPython();
|
|
1061
1101
|
if (hermesPython) {
|
|
@@ -1117,15 +1157,20 @@ var main = async () => {
|
|
|
1117
1157
|
} else {
|
|
1118
1158
|
console.log(` ${skip} claude alias ${dim("(not set)")}`);
|
|
1119
1159
|
}
|
|
1160
|
+
const leakedTemps = configTempLeftovers(agentConfigDirectories(), Date.now());
|
|
1161
|
+
for (const temp of leakedTemps) guardedRemove(temp, { force: true });
|
|
1162
|
+
if (leakedTemps.length > 0) {
|
|
1163
|
+
console.log(` ${check} Leftover temp files ${dim(`(${dryRun ? "would remove" : "removed"} ${leakedTemps.length} left by an interrupted config write)`)}`);
|
|
1164
|
+
}
|
|
1120
1165
|
if (existsSync6(PUSHARY_DIR)) {
|
|
1121
1166
|
let removed = 0;
|
|
1122
1167
|
const kept = [];
|
|
1123
|
-
for (const entry of
|
|
1168
|
+
for (const entry of readdirSync4(PUSHARY_DIR)) {
|
|
1124
1169
|
if (keepShared && isAppOwned(entry) || entry === "setup" && (keepShared || incompleteClean)) {
|
|
1125
1170
|
kept.push(entry);
|
|
1126
1171
|
continue;
|
|
1127
1172
|
}
|
|
1128
|
-
guardedRemove(
|
|
1173
|
+
guardedRemove(join6(PUSHARY_DIR, entry), { force: true });
|
|
1129
1174
|
removed++;
|
|
1130
1175
|
}
|
|
1131
1176
|
if (removed > 0) {
|
|
@@ -1142,10 +1187,10 @@ var main = async () => {
|
|
|
1142
1187
|
}
|
|
1143
1188
|
try {
|
|
1144
1189
|
let swept = 0;
|
|
1145
|
-
for (const f of
|
|
1190
|
+
for (const f of readdirSync4(tmpdir())) {
|
|
1146
1191
|
if (!f.startsWith("pushary-")) continue;
|
|
1147
1192
|
try {
|
|
1148
|
-
guardedRemove(
|
|
1193
|
+
guardedRemove(join6(tmpdir(), f), { force: true });
|
|
1149
1194
|
swept++;
|
|
1150
1195
|
} catch {
|
|
1151
1196
|
}
|