@pushary/agent-hooks 1.9.6 → 1.9.8

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.
Files changed (111) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +3 -3
  3. package/data/cursor-plugin/README.md +3 -7
  4. package/data/vscode-plugin/README.md +1 -1
  5. package/dist/bin/pushary-bell-hook.js +22 -23
  6. package/dist/bin/pushary-bell.js +9 -9
  7. package/dist/bin/pushary-claude.js +27 -28
  8. package/dist/bin/pushary-clean.js +98 -76
  9. package/dist/bin/pushary-codex-bridge.js +18 -18
  10. package/dist/bin/pushary-codex-hook.js +32 -33
  11. package/dist/bin/pushary-codex.js +13 -13
  12. package/dist/bin/pushary-connect.js +24 -21
  13. package/dist/bin/pushary-cowork.js +5 -5
  14. package/dist/bin/pushary-daemon.js +51 -38
  15. package/dist/bin/pushary-disconnect.js +187 -52
  16. package/dist/bin/pushary-doctor.js +68 -56
  17. package/dist/bin/pushary-elicitation-hook.js +24 -25
  18. package/dist/bin/pushary-gemini-bridge.js +13 -13
  19. package/dist/bin/pushary-gemini-hook.js +29 -30
  20. package/dist/bin/pushary-hook.js +30 -32
  21. package/dist/bin/pushary-login.js +12 -12
  22. package/dist/bin/pushary-logout.js +105 -42
  23. package/dist/bin/pushary-mcp.js +9 -9
  24. package/dist/bin/pushary-mode.js +28 -31
  25. package/dist/bin/pushary-notification-hook.js +26 -28
  26. package/dist/bin/pushary-opencode-hook.js +28 -29
  27. package/dist/bin/pushary-permission-denied-hook.js +30 -32
  28. package/dist/bin/pushary-permission-hook.js +29 -31
  29. package/dist/bin/pushary-post-hook.js +26 -28
  30. package/dist/bin/pushary-prompt-hook.js +26 -28
  31. package/dist/bin/pushary-session-end-hook.js +26 -28
  32. package/dist/bin/pushary-session-start-hook.js +31 -31
  33. package/dist/bin/pushary-setup.js +98 -106
  34. package/dist/bin/pushary-stats.js +5 -5
  35. package/dist/bin/pushary-status.js +34 -18
  36. package/dist/bin/pushary-stop-hook.js +26 -28
  37. package/dist/bin/pushary-stopfailure-hook.js +26 -28
  38. package/dist/bin/pushary-suggestions.js +19 -21
  39. package/dist/bin/pushary-transcript-register.js +18 -19
  40. package/dist/bin/pushary-transcripts.js +7 -7
  41. package/dist/bin/pushary-upgrade.js +67 -31
  42. package/dist/bin/pushary-wait.js +23 -19
  43. package/dist/bin/pushary.js +15 -14
  44. package/dist/{chunk-BSZ7VBVT.js → chunk-2A53H4S6.js} +17 -15
  45. package/dist/{chunk-D7SOOVHX.js → chunk-2QGYMY7A.js} +83 -3
  46. package/dist/{chunk-SVTHEMM3.js → chunk-2QTO5YIT.js} +6 -6
  47. package/dist/{chunk-WN6WYUCV.js → chunk-2VZAALEJ.js} +5 -9
  48. package/dist/chunk-2WXF3QJR.js +49 -0
  49. package/dist/{chunk-UKNKYTTY.js → chunk-3I6IVOZV.js} +3 -3
  50. package/dist/chunk-3Z3A37WD.js +77 -0
  51. package/dist/{chunk-2QRE6QH2.js → chunk-5QUPKDI5.js} +1 -1
  52. package/dist/chunk-6TE27XZR.js +69 -0
  53. package/dist/{chunk-L6USMDTW.js → chunk-7DVNSQWF.js} +59 -15
  54. package/dist/{chunk-SNJ3BOCP.js → chunk-7PT35RY2.js} +27 -8
  55. package/dist/{chunk-CBVDW2N6.js → chunk-B64KHETR.js} +3 -3
  56. package/dist/chunk-BEJRK4DF.js +94 -0
  57. package/dist/chunk-BXET3ALR.js +46 -0
  58. package/dist/{chunk-DJ4BB264.js → chunk-CD47ZFFZ.js} +1 -1
  59. package/dist/{chunk-FBD3QGVJ.js → chunk-CKV3UPMU.js} +2 -2
  60. package/dist/{chunk-7JTVYR5B.js → chunk-CLOSJ4ES.js} +1 -1
  61. package/dist/{chunk-DA4FTGTK.js → chunk-DKMD6AWR.js} +4 -4
  62. package/dist/{chunk-SPXBXN23.js → chunk-DL7XWKYV.js} +7 -5
  63. package/dist/{chunk-VRT3EEZN.js → chunk-DPGSLWOS.js} +8 -8
  64. package/dist/{chunk-3BUAEQCY.js → chunk-DUZVXBBU.js} +1 -1
  65. package/dist/{chunk-6GERGJHF.js → chunk-EUW7JL2K.js} +0 -32
  66. package/dist/{chunk-75CA37FZ.js → chunk-FQ2GORVG.js} +2 -2
  67. package/dist/{chunk-WUKUXICK.js → chunk-HRULIYDU.js} +2 -2
  68. package/dist/{chunk-Q4E56K4X.js → chunk-I5IJRMNV.js} +78 -8
  69. package/dist/{chunk-MKJ3RTUS.js → chunk-I6MJXLMY.js} +2 -2
  70. package/dist/{chunk-YPXUD6DW.js → chunk-IAD2RT4L.js} +14 -14
  71. package/dist/{chunk-LBLCFD5K.js → chunk-IHFDPV7C.js} +2 -2
  72. package/dist/{chunk-BVCHY4OY.js → chunk-IHO3YQAN.js} +2 -2
  73. package/dist/{chunk-RDK7FX5F.js → chunk-KF3UZLYI.js} +1 -1
  74. package/dist/chunk-KFF7G225.js +599 -0
  75. package/dist/{chunk-TE5M6GGK.js → chunk-KHNFLYJO.js} +204 -28
  76. package/dist/{chunk-CCDVL63C.js → chunk-KRCR2CRQ.js} +9 -9
  77. package/dist/{chunk-ZC3TF4LR.js → chunk-LKLVTG3V.js} +18 -9
  78. package/dist/{chunk-4QKM44N6.js → chunk-LWOO567I.js} +4 -3
  79. package/dist/{chunk-KK54WQ74.js → chunk-M6BZZFVQ.js} +1 -1
  80. package/dist/{chunk-RIC6OOJX.js → chunk-MFF3ONG5.js} +21 -1
  81. package/dist/{chunk-IMGJYFCX.js → chunk-MGRFDGWU.js} +3 -2
  82. package/dist/{chunk-ZPW4MJOV.js → chunk-MKTJEXZ3.js} +3 -3
  83. package/dist/{chunk-2I23NFVT.js → chunk-MXHTGVFZ.js} +52 -9
  84. package/dist/{chunk-5BHROGRB.js → chunk-N4QSPI3B.js} +54 -5
  85. package/dist/{chunk-DGQTJDSJ.js → chunk-NWDG3MSW.js} +1 -1
  86. package/dist/chunk-OP7IHC2I.js +24 -0
  87. package/dist/{chunk-EVFY3VE6.js → chunk-QOLITCIP.js} +1 -1
  88. package/dist/{chunk-W4Q7NFXU.js → chunk-TCQ43LSG.js} +3 -3
  89. package/dist/chunk-TCWKTUAE.js +50 -0
  90. package/dist/{chunk-EZAFBC2C.js → chunk-V5HPPF3E.js} +8 -4
  91. package/dist/{chunk-Q23MMVTD.js → chunk-WG3K4TCH.js} +1 -1
  92. package/dist/{chunk-F56SB65Y.js → chunk-WS4H76EP.js} +2 -2
  93. package/dist/{chunk-HWQNQVY6.js → chunk-WWOHTTVP.js} +2 -2
  94. package/dist/{chunk-NVGDMTX3.js → chunk-YIG2R3BJ.js} +9 -7
  95. package/dist/{chunk-HJXZJF6O.js → chunk-ZBHUHJG6.js} +4 -4
  96. package/dist/{chunk-5AXCOTIT.js → chunk-ZBK6E2OR.js} +1 -1
  97. package/dist/{chunk-5PMTC2CB.js → chunk-ZN3C6GBG.js} +84 -673
  98. package/dist/{chunk-GQHZIBAZ.js → chunk-ZSTSEBG7.js} +1 -1
  99. package/dist/{chunk-PYZC54KA.js → chunk-ZW3XZLJC.js} +61 -17
  100. package/dist/{global-upgrade-7F5RP45B.js → global-upgrade-I56HNM23.js} +6 -6
  101. package/dist/{paths-MELXIVBO.js → paths-AGY43CXS.js} +2 -2
  102. package/dist/reapply-IA5XUKWW.js +57 -0
  103. package/dist/src/index.d.ts +1 -0
  104. package/dist/src/index.js +19 -20
  105. package/dist/{upgrade-lock-AHRBA66K.js → upgrade-lock-B34TAUKV.js} +5 -3
  106. package/package.json +1 -1
  107. package/dist/chunk-HT3WMM6Q.js +0 -44
  108. package/dist/chunk-IR5FRUPQ.js +0 -197
  109. package/dist/chunk-JUFKJCZG.js +0 -38
  110. package/dist/chunk-SJN22ADZ.js +0 -86
  111. package/dist/reapply-NOB2Q6C4.js +0 -35
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.8
4
+
5
+ - `pushary upgrade` and automatic updates no longer take over agents the Pushary Mac app connected. They used to replace the app's hooks with the CLI's and overwrite its MCP key for Claude Code, Codex, Gemini CLI, VS Code and OpenCode. An agent the app owns is now left exactly as the app wrote it and listed as kept for the Mac app, using the same rule setup uses. Pass `--take-over-hooks` to setup if you want the CLI to own it.
6
+ - `pushary clean` keeps the Mac app's wiring for Qwen Code, CodeBuddy, Qoder, Droid and Devin while the app is installed, as it already did for the other agents. `clean --everything` still removes it.
7
+ - `pushary disconnect cursor` removes the Cursor plugin setup installed in `~/.cursor/plugins/local/pushary`, including the `mcp.json` that held your API key, and setup's leftover copies of it. The plugin is kept, and the output says so, when the gate in `~/.cursor/hooks.json` that points into it could not be removed.
8
+ - `pushary disconnect` removes the Pushary block it wrote to `AGENTS.md` (Codex, OpenCode), `GEMINI.md`, `QWEN.md` and `CODEBUDDY.md`. Only the text between the Pushary markers is removed. Skills are left in place.
9
+ - `pushary disconnect <agent>` is no longer undone by the Mac app. It records the agent in `~/.pushary/declined-agents.json`, and Pushary.app versions that read that file leave the agent off until you connect it again from the app or with `pushary setup`.
10
+ - `pushary mode`, `mode clear`, `wait <seconds>` and `suggestions` no longer say "This key was rejected" when the key is fine. Keys from `pushary login`, phone pairing and the Mac app cannot change approval settings, and these commands now say so, point you to the Pushary app, your phone or the dashboard, and exit with code 2.
11
+ - `pushary sign-out --revoke` revokes those keys too, and then checks with pushary.com and tells you whether the key still works. Before, it could not revoke them and always said the key was still valid. `--json` adds `keyStillValid`.
12
+ - When the Mac app signs out of the key setup borrowed from it, the background service stops once instead of restarting every 10 seconds, and `pushary doctor`, `pushary status` and commands that report a rejected key say the key was signed out on this Mac, tell you to run `pushary login`, and name the shell profile line that still exports the old key. Pushary does not edit that line. A background service with no key at all also stops instead of restarting.
13
+
14
+ ## 1.9.7
15
+
16
+ - `pushary claude` and the `pushary daemon` commands wait at most 5 seconds for the background service again. Only setup and upgrade allow the 30 seconds a cold Windows start can need, so launching Claude no longer sits silent while the service starts.
17
+ - An automatic update whose configuration refresh fails now retries after 5 minutes, then after an hour, then once a day, instead of every 5 minutes. On a Mac with phone-start on, each retry restarted the background service.
18
+ - A refresh that cannot succeed until you change something (a legacy phone-start service, phone-start turned on without a usable agent, or a config file Pushary cannot rewrite) is no longer retried automatically. `pushary doctor` shows it, and running `pushary upgrade` after the fix finishes it.
19
+ - When a Codex approval hook is turned off in Codex, setup and upgrade tell you to enable it in `/hooks` instead of asking you to trust it. A missing or background (asynchronous) approval hook points you to setup again, as doctor does.
20
+ - Upgrades, including automatic ones, regenerate the OpenCode plugin Pushary installed, so the active directory fix from 1.9.4 reaches existing installs without running setup again. A `pushary.js` you wrote yourself is never touched, and no plugin is added where there was none.
21
+
3
22
  ## 1.9.6
4
23
 
5
24
  - Read-only shell approval no longer covers commands that make the shell evaluate quoted text again: arithmetic expansion (`$[ ]`), subscripted parameters (`$name[ ]`, including zsh flag prefixes) and `printf -v`. These ran a quoted command substitution in bash or zsh while being approved without asking. They now go to your normal approval.
package/README.md CHANGED
@@ -210,11 +210,11 @@ claude Run Claude Code through Pushary, reachable from your phone even whe
210
210
  daemon Keep this machine reachable so your phone can START a new session
211
211
  status One screen: which key is in force, whether the server accepts it, what can receive an approval
212
212
  login Sign in from this terminal, no key to copy (--with-token to pipe one in)
213
- logout Remove the key this machine stores, and say what it does not remove
214
- connect Connect a phone without re-running setup (--app for the Pushary app)
213
+ sign-out Sign out: remove the key this machine stores, and say what it does not remove (also: logout)
214
+ pair Pair a phone without re-running setup (--app for the Pushary app; also: connect)
215
215
  bell Free local bell when an agent finishes or needs you. No account, no key, no network
216
216
  doctor Verify your Pushary installation is working
217
- disconnect Turn off one agent (claude|codex|gemini|cursor)
217
+ disconnect Turn off one agent (claude|codex|gemini|cursor|opencode|qwen|codebuddy|qoder|droid|devin|fx)
218
218
  clean Remove Pushary from this machine (--everything: the Mac app's setup too, --dry-run: preview)
219
219
  mode Choose where approval requests appear
220
220
  wait Show or set the "wait for your phone" ladder (pushary wait 45)
@@ -26,11 +26,7 @@ There are three things.
26
26
 
27
27
  You need two things: the plugin, and an API key.
28
28
 
29
- ### Option 1: Cursor Marketplace (recommended)
30
-
31
- Open the Marketplace panel in Cursor, search for Pushary, and click install. Then set your API key (see below).
32
-
33
- ### Option 2: CLI
29
+ ### Option 1: CLI (recommended)
34
30
 
35
31
  This also sets up Claude Code, Codex, and Hermes if you use them.
36
32
 
@@ -38,7 +34,7 @@ This also sets up Claude Code, Codex, and Hermes if you use them.
38
34
  npx pushary@latest setup
39
35
  ```
40
36
 
41
- ### Option 3: Manual MCP
37
+ ### Option 2: Manual MCP
42
38
 
43
39
  Add this to `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` for every project:
44
40
 
@@ -106,7 +102,7 @@ Then reload Cursor with Developer: Reload Window.
106
102
 
107
103
  ## Security
108
104
 
109
- This repository has no secrets. Your key is read at runtime from `PUSHARY_API_KEY`. The gate script has no dependencies and only talks to pushary.com. Read `scripts/pushary-gate.mjs` to see exactly what it sends. See `SECURITY.md` for details.
105
+ Your key is read at runtime from `PUSHARY_API_KEY`. The gate script has no dependencies. It sends approval and activity data to pushary.com by default; `PUSHARY_BASE_URL` can change that endpoint. Read `scripts/pushary-gate.mjs` to see exactly what it sends. See `SECURITY.md` for details.
110
106
 
111
107
  ## License
112
108
 
@@ -121,7 +121,7 @@ echo '{"hook_event_name":"PreToolUse","tool_name":"runTerminalCommand","tool_inp
121
121
 
122
122
  ## Security
123
123
 
124
- This repository has no secrets. Your key is read at runtime from `PUSHARY_API_KEY`, the plugin `.mcp.json`, or `~/.pushary/config.json`. The gate script has no dependencies and only talks to pushary.com. Command text is redacted for common secret shapes before it is sent. Read `scripts/pushary-gate.mjs` to see exactly what it sends. See `SECURITY.md` for details.
124
+ Your key is read at runtime from `PUSHARY_API_KEY`, the plugin `.mcp.json`, or `~/.pushary/config.json`. The gate script has no dependencies. It sends approval and activity data to pushary.com by default; `PUSHARY_BASE_URL` and `PUSHARY_API_URL` can change its API endpoints. Command text is redacted for common secret shapes before it is sent. Read `scripts/pushary-gate.mjs` to see exactly what it sends. See `SECURITY.md` for details.
125
125
 
126
126
  ## License
127
127
 
@@ -1,39 +1,38 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleBell
4
- } from "../chunk-LBLCFD5K.js";
4
+ } from "../chunk-IHFDPV7C.js";
5
5
  import {
6
6
  readHookInput
7
- } from "../chunk-HWQNQVY6.js";
8
- import "../chunk-VRT3EEZN.js";
7
+ } from "../chunk-WWOHTTVP.js";
8
+ import "../chunk-DPGSLWOS.js";
9
9
  import "../chunk-SGZJ5LYH.js";
10
- import "../chunk-NVGDMTX3.js";
11
- import "../chunk-SPXBXN23.js";
12
- import "../chunk-SJN22ADZ.js";
13
- import "../chunk-D7SOOVHX.js";
14
- import "../chunk-ZC3TF4LR.js";
15
- import "../chunk-UKNKYTTY.js";
16
- import "../chunk-Q23MMVTD.js";
17
- import "../chunk-5AXCOTIT.js";
18
- import "../chunk-7JTVYR5B.js";
19
- import "../chunk-KK54WQ74.js";
10
+ import "../chunk-YIG2R3BJ.js";
11
+ import "../chunk-DL7XWKYV.js";
12
+ import "../chunk-LKLVTG3V.js";
13
+ import "../chunk-2QGYMY7A.js";
14
+ import "../chunk-3I6IVOZV.js";
15
+ import "../chunk-WG3K4TCH.js";
16
+ import "../chunk-ZBK6E2OR.js";
17
+ import "../chunk-CLOSJ4ES.js";
18
+ import "../chunk-M6BZZFVQ.js";
20
19
  import "../chunk-XHKBHWLX.js";
21
20
  import "../chunk-6ICPEJY5.js";
22
- import "../chunk-DJ4BB264.js";
23
- import "../chunk-DA4FTGTK.js";
21
+ import "../chunk-CD47ZFFZ.js";
22
+ import "../chunk-DKMD6AWR.js";
24
23
  import "../chunk-POFBE6ZY.js";
25
24
  import "../chunk-GMXKITVA.js";
26
- import "../chunk-5BHROGRB.js";
27
- import "../chunk-W4Q7NFXU.js";
28
- import "../chunk-3BUAEQCY.js";
25
+ import "../chunk-N4QSPI3B.js";
26
+ import "../chunk-TCQ43LSG.js";
27
+ import "../chunk-DUZVXBBU.js";
29
28
  import "../chunk-7QLSKOSU.js";
30
29
  import "../chunk-KZERVKTD.js";
31
- import "../chunk-75CA37FZ.js";
32
- import "../chunk-HJXZJF6O.js";
30
+ import "../chunk-FQ2GORVG.js";
31
+ import "../chunk-ZBHUHJG6.js";
33
32
  import "../chunk-T7E75EKA.js";
34
- import "../chunk-2QRE6QH2.js";
35
- import "../chunk-L6USMDTW.js";
36
- import "../chunk-Q4E56K4X.js";
33
+ import "../chunk-5QUPKDI5.js";
34
+ import "../chunk-7DVNSQWF.js";
35
+ import "../chunk-I5IJRMNV.js";
37
36
 
38
37
  // bin/pushary-bell-hook.ts
39
38
  var main = async () => {
@@ -5,37 +5,37 @@ import {
5
5
  liveAgentCount,
6
6
  ring,
7
7
  upgradeThreshold
8
- } from "../chunk-LBLCFD5K.js";
8
+ } from "../chunk-IHFDPV7C.js";
9
9
  import {
10
10
  addBellHooks,
11
11
  bellInstalled,
12
12
  removeBellHooks
13
- } from "../chunk-Q23MMVTD.js";
13
+ } from "../chunk-WG3K4TCH.js";
14
14
  import {
15
15
  createIo
16
16
  } from "../chunk-U4TMAANR.js";
17
17
  import {
18
18
  exitOnHelpFlag
19
- } from "../chunk-FBD3QGVJ.js";
19
+ } from "../chunk-CKV3UPMU.js";
20
20
  import {
21
21
  parseFlags
22
22
  } from "../chunk-GMXKITVA.js";
23
- import "../chunk-5BHROGRB.js";
23
+ import "../chunk-N4QSPI3B.js";
24
24
  import "../chunk-7QLSKOSU.js";
25
25
  import {
26
26
  EXIT
27
27
  } from "../chunk-KZERVKTD.js";
28
- import "../chunk-75CA37FZ.js";
28
+ import "../chunk-FQ2GORVG.js";
29
29
  import {
30
30
  claudeSettings
31
- } from "../chunk-HJXZJF6O.js";
31
+ } from "../chunk-ZBHUHJG6.js";
32
32
  import {
33
33
  readJsonSafe,
34
34
  writeJsonAtomic
35
35
  } from "../chunk-T7E75EKA.js";
36
- import "../chunk-2QRE6QH2.js";
37
- import "../chunk-L6USMDTW.js";
38
- import "../chunk-Q4E56K4X.js";
36
+ import "../chunk-5QUPKDI5.js";
37
+ import "../chunk-7DVNSQWF.js";
38
+ import "../chunk-I5IJRMNV.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-RDK7FX5F.js";
11
+ } from "../chunk-KF3UZLYI.js";
12
12
  import {
13
13
  announceSubscriptionRequired,
14
14
  isDeferAnswer
@@ -18,24 +18,23 @@ import {
18
18
  loadSessionKey,
19
19
  registerTranscript,
20
20
  registeredTranscriptEnabled
21
- } from "../chunk-VRT3EEZN.js";
21
+ } from "../chunk-DPGSLWOS.js";
22
22
  import "../chunk-SGZJ5LYH.js";
23
- import "../chunk-NVGDMTX3.js";
24
- import "../chunk-SPXBXN23.js";
25
- import "../chunk-SJN22ADZ.js";
26
- import "../chunk-D7SOOVHX.js";
23
+ import "../chunk-YIG2R3BJ.js";
24
+ import "../chunk-DL7XWKYV.js";
27
25
  import {
28
26
  ensureDaemonRunning
29
- } from "../chunk-ZC3TF4LR.js";
30
- import "../chunk-UKNKYTTY.js";
31
- import "../chunk-Q23MMVTD.js";
27
+ } from "../chunk-LKLVTG3V.js";
28
+ import "../chunk-2QGYMY7A.js";
29
+ import "../chunk-3I6IVOZV.js";
30
+ import "../chunk-WG3K4TCH.js";
32
31
  import {
33
32
  encryptRecord
34
- } from "../chunk-5AXCOTIT.js";
35
- import "../chunk-7JTVYR5B.js";
33
+ } from "../chunk-ZBK6E2OR.js";
34
+ import "../chunk-CLOSJ4ES.js";
36
35
  import {
37
36
  transcriptsEnabled
38
- } from "../chunk-KK54WQ74.js";
37
+ } from "../chunk-M6BZZFVQ.js";
39
38
  import {
40
39
  needsShell,
41
40
  spawnClaude
@@ -51,7 +50,7 @@ import {
51
50
  repoKeyFor,
52
51
  reportEvent,
53
52
  scopePathFor
54
- } from "../chunk-CCDVL63C.js";
53
+ } from "../chunk-KRCR2CRQ.js";
55
54
  import {
56
55
  DEFAULT_SESSION,
57
56
  markPendingCommandDelivered,
@@ -61,10 +60,8 @@ import {
61
60
  removePendingCommand,
62
61
  savePendingCommand
63
62
  } from "../chunk-N6IOSZOE.js";
64
- import "../chunk-DJ4BB264.js";
63
+ import "../chunk-CD47ZFFZ.js";
65
64
  import {
66
- DECISION_STOP_REASON,
67
- UNVERIFIABLE_APPROVAL_REASON,
68
65
  askUser,
69
66
  cancelQuestion,
70
67
  isDecisionStopped,
@@ -72,36 +69,38 @@ import {
72
69
  nextLongPollMs,
73
70
  waitForAnswer,
74
71
  withdrawQuestion
75
- } from "../chunk-WN6WYUCV.js";
76
- import "../chunk-DA4FTGTK.js";
72
+ } from "../chunk-2VZAALEJ.js";
73
+ import "../chunk-DKMD6AWR.js";
77
74
  import "../chunk-POFBE6ZY.js";
78
75
  import "../chunk-GMXKITVA.js";
79
- import "../chunk-5BHROGRB.js";
76
+ import "../chunk-N4QSPI3B.js";
80
77
  import {
81
78
  SubscriptionRequiredError
82
- } from "../chunk-ZPW4MJOV.js";
83
- import "../chunk-4QKM44N6.js";
84
- import "../chunk-W4Q7NFXU.js";
79
+ } from "../chunk-MKTJEXZ3.js";
80
+ import "../chunk-LWOO567I.js";
81
+ import "../chunk-TCQ43LSG.js";
85
82
  import {
86
83
  getMachineId
87
- } from "../chunk-3BUAEQCY.js";
84
+ } from "../chunk-DUZVXBBU.js";
88
85
  import "../chunk-7QLSKOSU.js";
89
86
  import "../chunk-KZERVKTD.js";
90
- import "../chunk-75CA37FZ.js";
91
- import "../chunk-HJXZJF6O.js";
87
+ import "../chunk-FQ2GORVG.js";
88
+ import "../chunk-ZBHUHJG6.js";
92
89
  import "../chunk-T7E75EKA.js";
93
90
  import {
94
91
  getApiKey,
95
92
  getBaseUrl
96
- } from "../chunk-2QRE6QH2.js";
93
+ } from "../chunk-5QUPKDI5.js";
97
94
  import {
98
95
  NPX_LATEST_COMMAND
99
- } from "../chunk-L6USMDTW.js";
96
+ } from "../chunk-7DVNSQWF.js";
100
97
  import {
98
+ DECISION_STOP_REASON,
101
99
  KILL_REASON,
100
+ UNVERIFIABLE_APPROVAL_REASON,
102
101
  redactSecretsFromContent,
103
102
  resolveGate
104
- } from "../chunk-Q4E56K4X.js";
103
+ } from "../chunk-I5IJRMNV.js";
105
104
 
106
105
  // src/wrapper/localPassthrough.ts
107
106
  var SIGNAL_NUMBERS = {
@@ -1,22 +1,34 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ appAgentKey,
4
+ macAppKeepsMcpEntry,
5
+ mcpServerBearer,
6
+ pusharyKey,
7
+ setupReceiptKey
8
+ } from "../chunk-OP7IHC2I.js";
2
9
  import {
3
10
  PUSHARY_SKILL_NAME,
4
11
  PUSHARY_SKILL_SOURCE,
5
- createGuards,
12
+ createGuards
13
+ } from "../chunk-EUW7JL2K.js";
14
+ import {
15
+ isCursorPluginLeftover,
6
16
  withoutPusharyCursorHooks
7
- } from "../chunk-6GERGJHF.js";
17
+ } from "../chunk-TCWKTUAE.js";
8
18
  import {
9
19
  HERMES_PIP_PACKAGE,
10
- planFxRemoval,
11
20
  readHermesStatus,
12
- removeInstructionBlock,
13
21
  resolveHermesPython,
14
22
  runHermesConfigScript,
15
23
  shortenHome,
16
24
  unregisterPluginLocation,
17
25
  vscodeSettingsTargets
18
- } from "../chunk-5PMTC2CB.js";
19
- import "../chunk-WUKUXICK.js";
26
+ } from "../chunk-KFF7G225.js";
27
+ import {
28
+ planFxRemoval,
29
+ removeInstructionBlock
30
+ } from "../chunk-ZN3C6GBG.js";
31
+ import "../chunk-HRULIYDU.js";
20
32
  import {
21
33
  OPENCODE_PLUGIN_SIBLING,
22
34
  OPENCODE_PLUGIN_SIBLING_CONTENTS,
@@ -28,48 +40,45 @@ import {
28
40
  openCodePluginDir,
29
41
  openCodePluginFile,
30
42
  removeOpenCodeMcpServer
31
- } from "../chunk-RIC6OOJX.js";
43
+ } from "../chunk-MFF3ONG5.js";
32
44
  import {
33
45
  compatibleConfigFile,
34
46
  compatibleInstructionsFile,
35
47
  compatibleMcpFile,
36
48
  compatiblePermissionRuleFile,
37
- removeCompatibleHooks,
38
- removeCompatibleMcpServer
39
- } from "../chunk-TE5M6GGK.js";
40
- import {
41
49
  isClaudeMcpSnapshot,
42
50
  removeClaudeMcpServers,
51
+ removeCompatibleHooks,
52
+ removeCompatibleMcpServer,
43
53
  removePusharySettings,
44
54
  removePusharyToolPermissions,
45
55
  restoreClaudeMcpServer
46
- } from "../chunk-IR5FRUPQ.js";
56
+ } from "../chunk-KHNFLYJO.js";
47
57
  import {
48
58
  hookOwnerOf,
49
59
  isHookTakeoverReceipt,
50
60
  restoreHookTakeover,
51
61
  restoreMcpServer
52
- } from "../chunk-NVGDMTX3.js";
53
- import "../chunk-SPXBXN23.js";
62
+ } from "../chunk-YIG2R3BJ.js";
63
+ import "../chunk-DL7XWKYV.js";
64
+ import {
65
+ disableDaemonService
66
+ } from "../chunk-LKLVTG3V.js";
54
67
  import {
55
68
  liveBridgeProbe,
56
69
  resolveBridgeStub
57
- } from "../chunk-SJN22ADZ.js";
58
- import "../chunk-D7SOOVHX.js";
59
- import {
60
- disableDaemonService
61
- } from "../chunk-ZC3TF4LR.js";
70
+ } from "../chunk-2QGYMY7A.js";
62
71
  import {
63
72
  removeGeminiSettings
64
- } from "../chunk-UKNKYTTY.js";
65
- import "../chunk-Q23MMVTD.js";
73
+ } from "../chunk-3I6IVOZV.js";
74
+ import "../chunk-WG3K4TCH.js";
66
75
  import "../chunk-XHKBHWLX.js";
67
76
  import "../chunk-6ICPEJY5.js";
68
- import "../chunk-CCDVL63C.js";
77
+ import "../chunk-KRCR2CRQ.js";
69
78
  import "../chunk-N6IOSZOE.js";
70
- import "../chunk-DJ4BB264.js";
71
- import "../chunk-WN6WYUCV.js";
72
- import "../chunk-DA4FTGTK.js";
79
+ import "../chunk-CD47ZFFZ.js";
80
+ import "../chunk-2VZAALEJ.js";
81
+ import "../chunk-DKMD6AWR.js";
73
82
  import "../chunk-POFBE6ZY.js";
74
83
  import {
75
84
  ansiPainter,
@@ -77,7 +86,7 @@ import {
77
86
  } from "../chunk-U4TMAANR.js";
78
87
  import {
79
88
  exitOnHelpFlag
80
- } from "../chunk-FBD3QGVJ.js";
89
+ } from "../chunk-CKV3UPMU.js";
81
90
  import {
82
91
  rejectUnknownFlags
83
92
  } from "../chunk-GMXKITVA.js";
@@ -85,16 +94,16 @@ import {
85
94
  CANDIDATE_RCS,
86
95
  isDisabledExport,
87
96
  removeClaudeAlias
88
- } from "../chunk-5BHROGRB.js";
89
- import "../chunk-ZPW4MJOV.js";
90
- import "../chunk-4QKM44N6.js";
91
- import "../chunk-W4Q7NFXU.js";
92
- import "../chunk-3BUAEQCY.js";
97
+ } from "../chunk-N4QSPI3B.js";
98
+ import "../chunk-MKTJEXZ3.js";
99
+ import "../chunk-LWOO567I.js";
100
+ import "../chunk-TCQ43LSG.js";
101
+ import "../chunk-DUZVXBBU.js";
93
102
  import "../chunk-7QLSKOSU.js";
94
103
  import {
95
104
  EXIT
96
105
  } from "../chunk-KZERVKTD.js";
97
- import "../chunk-75CA37FZ.js";
106
+ import "../chunk-FQ2GORVG.js";
98
107
  import {
99
108
  bridgeAgentKey,
100
109
  claudeJson,
@@ -132,12 +141,12 @@ import {
132
141
  restoreCodexHookTrust,
133
142
  vscodePluginDir,
134
143
  vscodePluginMcp
135
- } from "../chunk-HJXZJF6O.js";
144
+ } from "../chunk-ZBHUHJG6.js";
136
145
  import "../chunk-T7E75EKA.js";
137
- import "../chunk-2QRE6QH2.js";
146
+ import "../chunk-5QUPKDI5.js";
138
147
  import {
139
148
  NPX_LATEST_COMMAND
140
- } from "../chunk-L6USMDTW.js";
149
+ } from "../chunk-7DVNSQWF.js";
141
150
  import {
142
151
  CLI_PACKAGE_NAMES,
143
152
  HOOK_COMPATIBLE_PROFILES,
@@ -149,7 +158,7 @@ import {
149
158
  globalRootFor,
150
159
  isValidApiKey,
151
160
  redactSecrets
152
- } from "../chunk-Q4E56K4X.js";
161
+ } from "../chunk-I5IJRMNV.js";
153
162
 
154
163
  // bin/pushary-clean.ts
155
164
  import { existsSync as existsSync6, readFileSync as readFileSync4, copyFileSync, readdirSync as readdirSync4 } from "fs";
@@ -526,21 +535,47 @@ var APP_OWNED_ENTRIES = [
526
535
  // does the CLI. Not attributable, so it is kept whenever the app is installed
527
536
  // rather than removed and left registered against a path that is gone.
528
537
  "plugins",
529
- "bridge-auth"
538
+ "bridge-auth",
539
+ "declined-agents.json"
530
540
  ];
531
541
  var isAppOwned = (name) => APP_OWNED_ENTRIES.includes(name);
532
542
 
533
- // src/shared-mcp-key.ts
534
- var asRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
535
- var pusharyKey = (value) => typeof value === "string" && isValidApiKey(value.trim()) ? value.trim() : null;
536
- var bearerKey = (authorization) => typeof authorization === "string" && authorization.startsWith("Bearer ") ? pusharyKey(authorization.slice("Bearer ".length)) : null;
537
- var mcpServerBearer = (mcpServers) => bearerKey(asRecord(asRecord(asRecord(mcpServers)?.pushary)?.headers)?.Authorization);
538
- var appAgentKey = (bridgeAgentKey2) => pusharyKey(asRecord(bridgeAgentKey2)?.key);
539
- var setupReceiptKey = (claudeMcpReceipt2) => bearerKey(asRecord(asRecord(asRecord(claudeMcpReceipt2)?.installedPushary)?.headers)?.Authorization);
540
- var macAppKeepsMcpEntry = (entryKey, keys) => {
541
- if (!entryKey) return true;
542
- if (keys.appKey) return entryKey === keys.appKey;
543
- return entryKey !== keys.setupKey;
543
+ // src/compatible-clean.ts
544
+ var keepsMcpServer = (profile, scope, io, home) => {
545
+ const mcpPath = compatibleMcpFile(profile, home);
546
+ if (!mcpPath) return false;
547
+ const mcp = io.readJson(mcpPath);
548
+ return mcp !== null && scope.keepsMcpEntry(profile.agentType, mcpServerBearer(mcp.mcpServers));
549
+ };
550
+ var removalsByPath = (profile, removalScope2, home) => {
551
+ const removals = /* @__PURE__ */ new Map();
552
+ const add = (path, removal) => {
553
+ if (path) removals.set(path, [...removals.get(path) ?? [], removal]);
554
+ };
555
+ add(compatibleConfigFile(profile, home), (config) => removeCompatibleHooks(config, profile, removalScope2));
556
+ if (removalScope2.keepMcpServer !== true) {
557
+ add(compatibleMcpFile(profile, home), (config) => removeCompatibleMcpServer(config, profile));
558
+ add(compatiblePermissionRuleFile(profile, home), removePusharyToolPermissions);
559
+ }
560
+ return removals;
561
+ };
562
+ var cleanInstructions = (profile, scope, io, home) => {
563
+ const path = compatibleInstructionsFile(profile, home);
564
+ if (!path) return null;
565
+ if (scope.keepAppWiring) return { path, outcome: "kept_for_app" };
566
+ return { path, outcome: io.removeInstructionBlock(path) ? "removed" : "absent" };
567
+ };
568
+ var cleanCompatibleAgent = (profile, scope, io, home) => {
569
+ const mcpKeptForApp = keepsMcpServer(profile, scope, io, home);
570
+ const removalScope2 = { keepAppWiring: scope.keepAppWiring, keepMcpServer: mcpKeptForApp };
571
+ const files = [...removalsByPath(profile, removalScope2, home)].map(([path, removals]) => {
572
+ const config = io.readJson(path);
573
+ if (!config) return { path, outcome: "not_found" };
574
+ if (!removals.reduce((changed, remove) => remove(config) || changed, false)) return { path, outcome: "unchanged" };
575
+ io.writeJson(path, config);
576
+ return { path, outcome: "cleaned" };
577
+ });
578
+ return { profile, files, mcpKeptForApp, instructions: cleanInstructions(profile, scope, io, home) };
544
579
  };
545
580
 
546
581
  // bin/pushary-clean.ts
@@ -598,12 +633,10 @@ var wouldNote = (action, path) => {
598
633
  var guards = createGuards(() => dryRun, wouldNote);
599
634
  var guardedWrite = (path, contents) => guards.write(path, contents);
600
635
  var guardedRemove = (path, options) => guards.remove(path, options);
601
- var CURSOR_PLUGIN_STAGING = ".pushary-staging-";
602
636
  var cursorPluginLeftovers = () => {
603
637
  const parent = dirname(CURSOR_PLUGIN_DIR);
604
- const backupPrefix = `${CURSOR_PLUGIN_DIR.split("/").pop()}.pushary-backup-`;
605
638
  try {
606
- return readdirSync4(parent).filter((name) => name.startsWith(backupPrefix) || name.startsWith(CURSOR_PLUGIN_STAGING)).map((name) => join6(parent, name));
639
+ return readdirSync4(parent).filter(isCursorPluginLeftover).map((name) => join6(parent, name));
607
640
  } catch {
608
641
  return [];
609
642
  }
@@ -1023,34 +1056,23 @@ var main = async () => {
1023
1056
  } else {
1024
1057
  console.log(` ${skip} Codex skill directory ${dim("(not found)")}`);
1025
1058
  }
1059
+ const compatibleScope = { keepAppWiring: keepShared, keepsMcpEntry: macAppKeeps };
1060
+ const compatibleIo = { readJson, writeJson, removeInstructionBlock: guardedInstructionBlockRemoval };
1026
1061
  for (const profile of HOOK_COMPATIBLE_PROFILES) {
1027
- const edits = [
1028
- [compatibleConfigFile(profile), (config) => removeCompatibleHooks(config, profile)],
1029
- ...compatibleMcpFile(profile) ? [[compatibleMcpFile(profile), (config) => removeCompatibleMcpServer(config, profile)]] : [],
1030
- ...compatiblePermissionRuleFile(profile) ? [[compatiblePermissionRuleFile(profile), removePusharyToolPermissions]] : []
1031
- ];
1032
- const byPath = /* @__PURE__ */ new Map();
1033
- for (const [path, edit] of edits) byPath.set(path, [...byPath.get(path) ?? [], edit]);
1034
- for (const [path, removals] of byPath) {
1035
- const config = readJson(path);
1036
- if (!config) {
1037
- console.log(` ${skip} ${profile.label} ${shortenHome(path)} ${dim("(not found)")}`);
1038
- continue;
1039
- }
1040
- if (removals.reduce((changed, remove) => remove(config) || changed, false)) {
1041
- writeJson(path, config);
1042
- console.log(` ${check} ${profile.label} ${shortenHome(path)} ${dim(did("cleaned"))}`);
1043
- } else {
1044
- console.log(` ${skip} ${profile.label} ${shortenHome(path)} ${dim("(no pushary entries)")}`);
1045
- }
1062
+ const report = cleanCompatibleAgent(profile, compatibleScope, compatibleIo);
1063
+ for (const file of report.files) {
1064
+ const label2 = `${profile.label} ${shortenHome(file.path)}`;
1065
+ if (file.outcome === "not_found") console.log(` ${skip} ${label2} ${dim("(not found)")}`);
1066
+ else if (file.outcome === "cleaned") console.log(` ${check} ${label2} ${dim(did("cleaned"))}`);
1067
+ else console.log(` ${skip} ${label2} ${dim(keepShared ? "(nothing the CLI wrote)" : "(no pushary entries)")}`);
1046
1068
  }
1047
- const instructions = compatibleInstructionsFile(profile);
1069
+ if (report.mcpKeptForApp) console.log(` ${skip} ${profile.label} MCP server ${dim("(kept: the Mac app uses it)")}`);
1070
+ const instructions = report.instructions;
1048
1071
  if (!instructions) continue;
1049
- if (guardedInstructionBlockRemoval(instructions)) {
1050
- console.log(` ${check} ${profile.label} ${shortenHome(instructions)} ${dim("(removed Pushary block)")}`);
1051
- } else {
1052
- console.log(` ${skip} ${profile.label} ${shortenHome(instructions)} ${dim("(no pushary block)")}`);
1053
- }
1072
+ const label = `${profile.label} ${shortenHome(instructions.path)}`;
1073
+ if (instructions.outcome === "kept_for_app") console.log(` ${skip} ${label} ${dim("(kept: the Mac app uses it)")}`);
1074
+ else if (instructions.outcome === "removed") console.log(` ${check} ${label} ${dim("(removed Pushary block)")}`);
1075
+ else console.log(` ${skip} ${label} ${dim("(no pushary block)")}`);
1054
1076
  }
1055
1077
  const geminiSettingsPath = geminiSettings();
1056
1078
  const geminiSettings2 = readJson(geminiSettingsPath);