@pushary/agent-hooks 0.89.6 → 0.89.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 (48) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/bin/pushary-bell-hook.js +3 -3
  3. package/dist/bin/pushary-bell.js +4 -4
  4. package/dist/bin/pushary-claude.js +6 -6
  5. package/dist/bin/pushary-clean.js +138 -31
  6. package/dist/bin/pushary-codex-bridge.js +4 -4
  7. package/dist/bin/pushary-codex-hook.js +4 -4
  8. package/dist/bin/pushary-codex.js +4 -4
  9. package/dist/bin/pushary-connect.js +2 -2
  10. package/dist/bin/pushary-daemon.js +11 -11
  11. package/dist/bin/pushary-disconnect.js +2 -2
  12. package/dist/bin/pushary-doctor.js +8 -8
  13. package/dist/bin/pushary-elicitation-hook.js +3 -3
  14. package/dist/bin/pushary-gemini-bridge.js +4 -4
  15. package/dist/bin/pushary-gemini-hook.js +4 -4
  16. package/dist/bin/pushary-hook.js +5 -5
  17. package/dist/bin/pushary-login.js +2 -2
  18. package/dist/bin/pushary-logout.js +3 -3
  19. package/dist/bin/pushary-notification-hook.js +4 -4
  20. package/dist/bin/pushary-opencode-hook.js +4 -4
  21. package/dist/bin/pushary-permission-denied-hook.js +5 -5
  22. package/dist/bin/pushary-permission-hook.js +5 -5
  23. package/dist/bin/pushary-post-hook.js +4 -4
  24. package/dist/bin/pushary-prompt-hook.js +4 -4
  25. package/dist/bin/pushary-session-end-hook.js +4 -4
  26. package/dist/bin/pushary-session-start-hook.js +4 -4
  27. package/dist/bin/pushary-setup.js +10 -10
  28. package/dist/bin/pushary-status.js +5 -5
  29. package/dist/bin/pushary-stop-hook.js +4 -4
  30. package/dist/bin/pushary-stopfailure-hook.js +4 -4
  31. package/dist/bin/pushary-upgrade.js +9 -9
  32. package/dist/{chunk-NFI2K2ZQ.js → chunk-4XZCDSNG.js} +1 -1
  33. package/dist/{chunk-QH4AA7QV.js → chunk-A4O5ROZK.js} +1 -1
  34. package/dist/{chunk-OBI4YMCT.js → chunk-BAE45YLP.js} +2 -2
  35. package/dist/{chunk-2HYPZLYY.js → chunk-DKDDLF5P.js} +2 -2
  36. package/dist/{chunk-5TASNKRX.js → chunk-EA3E74P2.js} +5 -5
  37. package/dist/{chunk-MZBT2LXW.js → chunk-EJT2ER6G.js} +2 -2
  38. package/dist/{chunk-WQGMUIDW.js → chunk-FX5QSMPY.js} +1 -1
  39. package/dist/{chunk-V37ZXMH3.js → chunk-GMI5QZLG.js} +15 -9
  40. package/dist/{chunk-475T3XIO.js → chunk-J2JZJZKB.js} +1 -1
  41. package/dist/{chunk-NQNCSPEH.js → chunk-R2AGKCXL.js} +350 -27
  42. package/dist/{chunk-4ZHQNBDP.js → chunk-TF247BET.js} +2 -2
  43. package/dist/{chunk-L3YUHEB6.js → chunk-V6N4Q223.js} +1 -1
  44. package/dist/{chunk-7TS2G4QG.js → chunk-VA7VUNRD.js} +22 -14
  45. package/dist/{chunk-6MTNS63X.js → chunk-XX2V4QS5.js} +12 -1
  46. package/dist/{chunk-VP7SDXYG.js → chunk-ZL7HEF2T.js} +1 -1
  47. package/dist/src/index.js +5 -5
  48. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.89.8
4
+
5
+ ### Daemon upgrades keep a recoverable service
6
+
7
+ Background-service replacement now records the previous definition and native
8
+ running state in an owner-only transaction receipt before changing launchd,
9
+ systemd or Task Scheduler. A failed or interrupted replacement restores that
10
+ service before another upgrade is attempted, and verifies whether it should be
11
+ running or stopped.
12
+
13
+ Native probe errors are not treated as proof that a service disappeared, and
14
+ rollback preserves an administratively disabled service instead of enabling it.
15
+
16
+ `pushary clean` now proves the background service was removed before changing
17
+ agent configuration or local state. If removal cannot be proven, clean stops
18
+ with the existing installation intact so it can be repaired and retried.
19
+
20
+ ## 0.89.7
21
+
22
+ ### clean no longer uninstalls the macOS app along with the CLI
23
+
24
+ `clean` removed `~/.pushary` whole. That directory is not only the CLI's: the Mac
25
+ app roots its entire runtime there, so the locator every hook execs, the socket
26
+ the app listens on, its gate state and its spool all went with it. It also
27
+ stripped the app's hook entries out of the agent configs. The app went on
28
+ running and went on reporting itself connected, while nothing reached it.
29
+
30
+ It now removes what the CLI owns and leaves `bin`, `run`, `spool` and `plugins`.
31
+ Hook entries are attributed by the command they name, so the app keeps its own.
32
+ `disconnect` is unchanged and still disconnects an agent whichever product
33
+ connected it.
34
+
35
+ The `mcpServers.pushary` entry and the VS Code plugin directory cannot be
36
+ attributed to either product, so they are kept when the app is installed and
37
+ removed when it is not. A CLI-only clean still leaves no API key on disk.
38
+
39
+ ### clean handles OpenCode
40
+
41
+ setup installs an OpenCode plugin and an MCP entry and `clean` walked past both,
42
+ so a command that says it removes all Pushary configuration left the sixth agent
43
+ wired. A `pushary.js` somebody else wrote, or one the Mac app wrote, is left
44
+ alone.
45
+
3
46
  ## 0.89.3
4
47
 
5
48
  ### Doctor recognizes hooks installed by the macOS app
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleBell
4
- } from "../chunk-WQGMUIDW.js";
4
+ } from "../chunk-FX5QSMPY.js";
5
5
  import {
6
6
  readHookInput
7
7
  } from "../chunk-6CUUA7HO.js";
8
- import "../chunk-L3YUHEB6.js";
8
+ import "../chunk-V6N4Q223.js";
9
9
  import "../chunk-BC3VCZ3E.js";
10
10
  import "../chunk-OFRNZWC4.js";
11
- import "../chunk-6MTNS63X.js";
11
+ import "../chunk-XX2V4QS5.js";
12
12
  import "../chunk-2UMNXADU.js";
13
13
  import "../chunk-L4C2JXJS.js";
14
14
 
@@ -5,18 +5,18 @@ import {
5
5
  liveAgentCount,
6
6
  ring,
7
7
  upgradeThreshold
8
- } from "../chunk-WQGMUIDW.js";
8
+ } from "../chunk-FX5QSMPY.js";
9
9
  import {
10
10
  guardBinary
11
11
  } from "../chunk-AIGDBRIJ.js";
12
12
  import "../chunk-PZA7G4CN.js";
13
13
  import {
14
14
  claudeSettings
15
- } from "../chunk-V37ZXMH3.js";
15
+ } from "../chunk-GMI5QZLG.js";
16
16
  import {
17
17
  createIo
18
18
  } from "../chunk-5RUIFDTP.js";
19
- import "../chunk-L3YUHEB6.js";
19
+ import "../chunk-V6N4Q223.js";
20
20
  import {
21
21
  parseFlags
22
22
  } from "../chunk-GMXKITVA.js";
@@ -34,7 +34,7 @@ import {
34
34
  import {
35
35
  readJsonSafe,
36
36
  writeJsonAtomic
37
- } from "../chunk-6MTNS63X.js";
37
+ } from "../chunk-XX2V4QS5.js";
38
38
  import "../chunk-2UMNXADU.js";
39
39
  import "../chunk-L4C2JXJS.js";
40
40
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ensureDaemonRunning
4
- } from "../chunk-NQNCSPEH.js";
4
+ } from "../chunk-R2AGKCXL.js";
5
5
  import {
6
6
  buildTranscriptRecords,
7
7
  decodePublicKey,
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  startProcessOwnership,
15
15
  withSpawnProcessOwnership
16
- } from "../chunk-4ZHQNBDP.js";
16
+ } from "../chunk-TF247BET.js";
17
17
  import {
18
18
  needsShell,
19
19
  spawnClaude
@@ -27,7 +27,7 @@ import {
27
27
  getPolicy,
28
28
  repoKeyFor,
29
29
  reportEvent
30
- } from "../chunk-NFI2K2ZQ.js";
30
+ } from "../chunk-4XZCDSNG.js";
31
31
  import {
32
32
  DEFAULT_SESSION,
33
33
  askUser,
@@ -46,15 +46,15 @@ import {
46
46
  } from "../chunk-KOPUTJQC.js";
47
47
  import {
48
48
  getMachineId
49
- } from "../chunk-2HYPZLYY.js";
50
- import "../chunk-V37ZXMH3.js";
49
+ } from "../chunk-DKDDLF5P.js";
50
+ import "../chunk-GMI5QZLG.js";
51
51
  import "../chunk-DINDL2CF.js";
52
52
  import "../chunk-BSZYIAZL.js";
53
53
  import "../chunk-SAF6HGAA.js";
54
54
  import "../chunk-OFRNZWC4.js";
55
55
  import "../chunk-7QLSKOSU.js";
56
56
  import "../chunk-KZERVKTD.js";
57
- import "../chunk-6MTNS63X.js";
57
+ import "../chunk-XX2V4QS5.js";
58
58
  import {
59
59
  getApiKey,
60
60
  getBaseUrl
@@ -4,24 +4,33 @@ import {
4
4
  shortenHome,
5
5
  unregisterPluginLocation,
6
6
  vscodeSettingsTargets
7
- } from "../chunk-QH4AA7QV.js";
8
- import "../chunk-O5B7EK5U.js";
7
+ } from "../chunk-A4O5ROZK.js";
8
+ import {
9
+ OPENCODE_PLUGIN_SIBLING,
10
+ OPENCODE_PLUGIN_SIBLING_CONTENTS,
11
+ hasForeignPlugins,
12
+ isOpenCodePluginOurs,
13
+ openCodeConfigFile,
14
+ openCodePluginDir,
15
+ openCodePluginFile,
16
+ removeOpenCodeMcpServer
17
+ } from "../chunk-O5B7EK5U.js";
9
18
  import {
10
19
  removeClaudeMcpServers,
11
20
  removeGeminiSettings,
12
21
  removePusharySettings
13
- } from "../chunk-7TS2G4QG.js";
22
+ } from "../chunk-VA7VUNRD.js";
14
23
  import "../chunk-ATBKJNWS.js";
15
24
  import "../chunk-AIGDBRIJ.js";
16
25
  import {
17
26
  disableDaemonService
18
- } from "../chunk-NQNCSPEH.js";
27
+ } from "../chunk-R2AGKCXL.js";
19
28
  import "../chunk-XHKBHWLX.js";
20
29
  import {
21
30
  execNpm
22
31
  } from "../chunk-PZA7G4CN.js";
23
32
  import "../chunk-KOPUTJQC.js";
24
- import "../chunk-2HYPZLYY.js";
33
+ import "../chunk-DKDDLF5P.js";
25
34
  import {
26
35
  claudeJson,
27
36
  claudeSettings,
@@ -41,7 +50,7 @@ import {
41
50
  removeCodexHookTrust,
42
51
  removeCodexHooks,
43
52
  vscodePluginDir
44
- } from "../chunk-V37ZXMH3.js";
53
+ } from "../chunk-GMI5QZLG.js";
45
54
  import {
46
55
  rejectUnknownFlags
47
56
  } from "../chunk-GMXKITVA.js";
@@ -57,10 +66,11 @@ import "../chunk-7QLSKOSU.js";
57
66
  import {
58
67
  EXIT
59
68
  } from "../chunk-KZERVKTD.js";
60
- import "../chunk-6MTNS63X.js";
69
+ import "../chunk-XX2V4QS5.js";
61
70
  import "../chunk-2UMNXADU.js";
62
71
  import {
63
- CURSOR_GATE_EVENTS
72
+ CURSOR_GATE_EVENTS,
73
+ HOOK_LOCATOR_BINARY
64
74
  } from "../chunk-L4C2JXJS.js";
65
75
 
66
76
  // bin/pushary-clean.ts
@@ -89,6 +99,21 @@ var createGuards = (isDryRun, note) => ({
89
99
  }
90
100
  });
91
101
 
102
+ // src/app-owned-paths.ts
103
+ var APP_OWNED_ENTRIES = [
104
+ // PusharyPaths.bin: bridgeStub, bridgeCache
105
+ "bin",
106
+ // PusharyPaths.run: pushary.sock, pushary.lastrun, gate-state.json, pending-commands.json
107
+ "run",
108
+ // PusharyPaths.spool
109
+ "spool",
110
+ // Shared: AgentInstaller.vscodePlugin writes .pushary/plugins/vscode, and so
111
+ // does the CLI. Not attributable, so it is kept whenever the app is installed
112
+ // rather than removed and left registered against a path that is gone.
113
+ "plugins"
114
+ ];
115
+ var isAppOwned = (name) => APP_OWNED_ENTRIES.includes(name);
116
+
92
117
  // bin/pushary-clean.ts
93
118
  exitOnHelpFlag("clean");
94
119
  var dim = (s) => `\x1B[2m${s}\x1B[0m`;
@@ -110,6 +135,11 @@ var CURSOR_USER_HOOKS = cursorUserHooks();
110
135
  var VSCODE_PLUGIN_DIR = vscodePluginDir();
111
136
  var PUSHARY_DIR = pusharyDir();
112
137
  var SHELL_FILES = [".zshrc", ".zprofile", ".bashrc", ".bash_profile"].map((f) => join(homedir(), f));
138
+ var macAppInstalled = () => existsSync(join(PUSHARY_DIR, "bin", HOOK_LOCATOR_BINARY));
139
+ var removalScope = () => ({
140
+ keepAppWiring: true,
141
+ keepMcpServer: macAppInstalled()
142
+ });
113
143
  var resolveHermesPython = () => {
114
144
  try {
115
145
  const launcher = execSync2("command -v hermes", { encoding: "utf-8", stdio: "pipe", timeout: 5e3 }).trim();
@@ -211,13 +241,18 @@ var cleanSettingsFile = (path, label) => {
211
241
  console.log(` ${skip} ${label} ${dim("(not found)")}`);
212
242
  return;
213
243
  }
214
- const changed = removePusharySettings(data);
244
+ const changed = removePusharySettings(data, removalScope());
215
245
  if (changed) {
216
246
  writeJson(path, data);
217
247
  console.log(` ${check} ${label} ${dim(did("cleaned"))}`);
218
- } else {
219
- console.log(` ${skip} ${label} ${dim("(no pushary entries)")}`);
248
+ return;
220
249
  }
250
+ const wouldHaveChanged = removePusharySettings(
251
+ JSON.parse(JSON.stringify(data))
252
+ );
253
+ console.log(
254
+ ` ${skip} ${label} ${dim(wouldHaveChanged ? "(kept: written by the Mac app)" : "(no pushary entries)")}`
255
+ );
221
256
  };
222
257
  var main = async () => {
223
258
  console.log();
@@ -250,10 +285,26 @@ var main = async () => {
250
285
  process.exit(0);
251
286
  }
252
287
  console.log();
288
+ const keepShared = macAppInstalled();
289
+ if (keepShared) {
290
+ console.log(` ${dim("The Mac app is installed, so its wiring and the state it owns are left alone.")}`);
291
+ console.log();
292
+ }
293
+ const daemonRemoved = await guardedDaemonRemoval();
294
+ if (!daemonRemoved) {
295
+ console.log(` ${cross} Background service ${dim("(could not stop or uninstall)")}`);
296
+ console.log(` ${yellow(bold("Clean stopped before changing provider configuration or local state."))}`);
297
+ console.log(` ${dim("Fix the background service, then re-run")} npx @pushary/agent-hooks@latest clean`);
298
+ console.log();
299
+ process.exit(EXIT.FAILED);
300
+ }
301
+ console.log(` ${check} Background service ${dim(did("uninstalled"))}`);
253
302
  cleanSettingsFile(CLAUDE_SETTINGS, "Claude Code settings");
254
303
  cleanSettingsFile(CLAUDE_SETTINGS_LOCAL, "Claude Code settings.local");
255
- const claudeJson2 = readJson(CLAUDE_JSON);
256
- if (claudeJson2) {
304
+ const claudeJson2 = keepShared ? null : readJson(CLAUDE_JSON);
305
+ if (keepShared) {
306
+ console.log(` ${skip} Claude Code MCP servers ${dim("(kept: the Mac app uses it)")}`);
307
+ } else if (claudeJson2) {
257
308
  if (removeClaudeMcpServers(claudeJson2)) {
258
309
  writeJson(CLAUDE_JSON, claudeJson2);
259
310
  console.log(` ${check} Claude Code MCP servers ${dim("(removed from ~/.claude.json)")}`);
@@ -263,8 +314,10 @@ var main = async () => {
263
314
  } else {
264
315
  console.log(` ${skip} Claude Code MCP servers ${dim("(not found)")}`);
265
316
  }
266
- const cursorData = readJson(CURSOR_MCP);
267
- if (cursorData) {
317
+ const cursorData = keepShared ? null : readJson(CURSOR_MCP);
318
+ if (keepShared) {
319
+ console.log(` ${skip} Cursor MCP config ${dim("(kept: the Mac app uses it)")}`);
320
+ } else if (cursorData) {
268
321
  const mcpServers = cursorData.mcpServers;
269
322
  if (mcpServers?.pushary) {
270
323
  delete mcpServers.pushary;
@@ -295,7 +348,10 @@ var main = async () => {
295
348
  } else {
296
349
  console.log(` ${skip} Cursor plugin ${dim("(not installed)")}`);
297
350
  }
298
- for (const settingsPath of vscodeSettingsTargets(existsSync)) {
351
+ if (keepShared) {
352
+ console.log(` ${skip} VS Code plugin ${dim("(kept: the Mac app writes the same plugin directory)")}`);
353
+ }
354
+ for (const settingsPath of keepShared ? [] : vscodeSettingsTargets(existsSync)) {
299
355
  const label = `VS Code plugin ${dim(`(${shortenHome(settingsPath)})`)}`;
300
356
  if (!existsSync(settingsPath)) {
301
357
  console.log(` ${skip} ${label} ${dim("(no settings.json)")}`);
@@ -311,7 +367,7 @@ var main = async () => {
311
367
  console.log(` ${skip} ${label} ${dim("(no pushary entry)")}`);
312
368
  }
313
369
  }
314
- if (existsSync(VSCODE_PLUGIN_DIR)) {
370
+ if (!keepShared && existsSync(VSCODE_PLUGIN_DIR)) {
315
371
  guardedRemove(VSCODE_PLUGIN_DIR);
316
372
  console.log(` ${check} VS Code plugin files ${dim(did("removed"))}`);
317
373
  }
@@ -331,10 +387,12 @@ var main = async () => {
331
387
  const trustRemoved = removeCodexHookTrust(parsed, codexHooksJson2, codexPositions);
332
388
  const hadPushary = config.includes("pushary");
333
389
  if (hadPushary || trustRemoved) {
334
- const mcpServers = parsed.mcp_servers ?? {};
335
- delete mcpServers.pushary;
336
- if (Object.keys(mcpServers).length === 0) delete parsed.mcp_servers;
337
- else parsed.mcp_servers = mcpServers;
390
+ if (!keepShared) {
391
+ const mcpServers = parsed.mcp_servers ?? {};
392
+ delete mcpServers.pushary;
393
+ if (Object.keys(mcpServers).length === 0) delete parsed.mcp_servers;
394
+ else parsed.mcp_servers = mcpServers;
395
+ }
338
396
  if (Array.isArray(parsed.notify)) {
339
397
  parsed.notify = parsed.notify.filter((n) => typeof n !== "string" || !n.includes("pushary-codex"));
340
398
  if (parsed.notify.length === 0) delete parsed.notify;
@@ -349,7 +407,7 @@ var main = async () => {
349
407
  console.log(` ${skip} Codex config ${dim("(not found)")}`);
350
408
  }
351
409
  if (codexHooksData) {
352
- if (removeCodexHooks(codexHooksData)) {
410
+ if (removeCodexHooks(codexHooksData, removalScope())) {
353
411
  writeJson(codexHooksJson2, codexHooksData);
354
412
  console.log(` ${check} Codex hooks ${dim("(removed from ~/.codex/hooks.json)")}`);
355
413
  } else {
@@ -374,7 +432,7 @@ var main = async () => {
374
432
  const geminiSettingsPath = geminiSettings();
375
433
  const geminiSettings2 = readJson(geminiSettingsPath);
376
434
  if (geminiSettings2) {
377
- if (removeGeminiSettings(geminiSettings2)) {
435
+ if (removeGeminiSettings(geminiSettings2, removalScope())) {
378
436
  writeJson(geminiSettingsPath, geminiSettings2);
379
437
  console.log(` ${check} Gemini CLI settings ${dim(did("cleaned"))}`);
380
438
  } else {
@@ -389,6 +447,44 @@ var main = async () => {
389
447
  } else {
390
448
  console.log(` ${skip} Gemini GEMINI.md ${dim("(no pushary block)")}`);
391
449
  }
450
+ const openCodePlugin = openCodePluginFile();
451
+ const openCodePluginContents = existsSync(openCodePlugin) ? readFileSync(openCodePlugin, "utf-8") : null;
452
+ if (openCodePluginContents === null) {
453
+ console.log(` ${skip} OpenCode plugin ${dim("(not installed)")}`);
454
+ } else if (!isOpenCodePluginOurs(openCodePluginContents)) {
455
+ console.log(` ${skip} OpenCode plugin ${dim("(a pushary.js we did not write)")}`);
456
+ } else if (openCodePluginContents.includes(HOOK_LOCATOR_BINARY)) {
457
+ console.log(` ${skip} OpenCode plugin ${dim("(kept: written by the Mac app)")}`);
458
+ } else {
459
+ guardedRemove(openCodePlugin, { force: true });
460
+ console.log(` ${check} OpenCode plugin ${dim(did("removed"))}`);
461
+ const sibling = join(openCodePluginDir(), OPENCODE_PLUGIN_SIBLING);
462
+ const remaining = (() => {
463
+ try {
464
+ return readdirSync(openCodePluginDir()).filter((name) => name !== OPENCODE_PLUGIN_SIBLING);
465
+ } catch {
466
+ return [];
467
+ }
468
+ })();
469
+ const siblingIsOurs = existsSync(sibling) && readFileSync(sibling, "utf-8") === OPENCODE_PLUGIN_SIBLING_CONTENTS;
470
+ if (siblingIsOurs && !hasForeignPlugins(remaining)) {
471
+ guardedRemove(sibling, { force: true });
472
+ console.log(` ${check} OpenCode plugin sibling ${dim(did("removed"))}`);
473
+ }
474
+ }
475
+ const openCodeConfig = keepShared ? null : readJson(openCodeConfigFile());
476
+ if (keepShared) {
477
+ console.log(` ${skip} OpenCode MCP ${dim("(kept: the Mac app uses it)")}`);
478
+ } else if (openCodeConfig) {
479
+ if (removeOpenCodeMcpServer(openCodeConfig)) {
480
+ writeJson(openCodeConfigFile(), openCodeConfig);
481
+ console.log(` ${check} OpenCode MCP ${dim(did("removed"))}`);
482
+ } else {
483
+ console.log(` ${skip} OpenCode MCP ${dim("(no pushary entries)")}`);
484
+ }
485
+ } else {
486
+ console.log(` ${skip} OpenCode MCP ${dim("(not found)")}`);
487
+ }
392
488
  const hermesPython = resolveHermesPython();
393
489
  if (hermesPython) {
394
490
  const snippet = 'from hermes_cli.config import load_config, save_config; c = load_config(); p = c.get("plugins") if isinstance(c.get("plugins"), dict) else {}; e = p.get("enabled") if isinstance(p.get("enabled"), list) else []; p["enabled"] = [x for x in e if x != "pushary"]; c["plugins"] = p; a = c.get("agent") if isinstance(c.get("agent"), dict) else {}; d = a.get("disabled_toolsets") if isinstance(a.get("disabled_toolsets"), list) else []; a["disabled_toolsets"] = [x for x in d if x != "clarify"]; c["agent"] = a; save_config(c)';
@@ -434,15 +530,26 @@ var main = async () => {
434
530
  } else {
435
531
  console.log(` ${skip} claude alias ${dim("(not set)")}`);
436
532
  }
437
- if (await guardedDaemonRemoval()) {
438
- console.log(` ${check} Background service ${dim(did("uninstalled"))}`);
439
- } else {
440
- incompleteClean = true;
441
- console.log(` ${cross} Background service ${dim("(could not stop or uninstall)")}`);
442
- }
443
533
  if (existsSync(PUSHARY_DIR)) {
444
- guardedRemove(PUSHARY_DIR);
445
- console.log(` ${check} Local state ${dim("(~/.pushary removed: stored API key, ledger)")}`);
534
+ let removed = 0;
535
+ const kept = [];
536
+ for (const entry of readdirSync(PUSHARY_DIR)) {
537
+ if (keepShared && isAppOwned(entry)) {
538
+ kept.push(entry);
539
+ continue;
540
+ }
541
+ guardedRemove(join(PUSHARY_DIR, entry), { force: true });
542
+ removed++;
543
+ }
544
+ if (removed > 0) {
545
+ const what = `${removed} entr${removed === 1 ? "y" : "ies"} from ~/.pushary: stored API key, ledger`;
546
+ console.log(` ${check} Local state ${dim(dryRun ? `(would remove ${what})` : `(removed ${what})`)}`);
547
+ } else {
548
+ console.log(` ${skip} Local state ${dim("(nothing of ours in ~/.pushary)")}`);
549
+ }
550
+ if (kept.length > 0) {
551
+ console.log(` ${dim(`left ${kept.sort().join(", ")} for the Mac app`)}`);
552
+ }
446
553
  } else {
447
554
  console.log(` ${skip} Local state ${dim("(~/.pushary not found)")}`);
448
555
  }
@@ -11,7 +11,7 @@ import "../chunk-PMHTCDEO.js";
11
11
  import {
12
12
  startProcessOwnership,
13
13
  withSpawnProcessOwnership
14
- } from "../chunk-4ZHQNBDP.js";
14
+ } from "../chunk-TF247BET.js";
15
15
  import {
16
16
  spawnClaude
17
17
  } from "../chunk-XHKBHWLX.js";
@@ -20,9 +20,9 @@ import {
20
20
  } from "../chunk-PZA7G4CN.js";
21
21
  import {
22
22
  getMachineId
23
- } from "../chunk-2HYPZLYY.js";
24
- import "../chunk-V37ZXMH3.js";
25
- import "../chunk-6MTNS63X.js";
23
+ } from "../chunk-DKDDLF5P.js";
24
+ import "../chunk-GMI5QZLG.js";
25
+ import "../chunk-XX2V4QS5.js";
26
26
  import {
27
27
  getApiKey,
28
28
  getBaseUrl
@@ -31,7 +31,7 @@ import {
31
31
  toCodexWire,
32
32
  toPolicyLookup,
33
33
  toPolicyLookups
34
- } from "../chunk-NFI2K2ZQ.js";
34
+ } from "../chunk-4XZCDSNG.js";
35
35
  import {
36
36
  DEFAULT_SESSION,
37
37
  askUser,
@@ -49,16 +49,16 @@ import {
49
49
  } from "../chunk-KOPUTJQC.js";
50
50
  import {
51
51
  getMachineId
52
- } from "../chunk-2HYPZLYY.js";
52
+ } from "../chunk-DKDDLF5P.js";
53
53
  import {
54
54
  canonicalJson
55
- } from "../chunk-V37ZXMH3.js";
55
+ } from "../chunk-GMI5QZLG.js";
56
56
  import "../chunk-BSZYIAZL.js";
57
57
  import "../chunk-SAF6HGAA.js";
58
58
  import "../chunk-OFRNZWC4.js";
59
59
  import "../chunk-7QLSKOSU.js";
60
60
  import "../chunk-KZERVKTD.js";
61
- import "../chunk-6MTNS63X.js";
61
+ import "../chunk-XX2V4QS5.js";
62
62
  import {
63
63
  getApiKey
64
64
  } from "../chunk-2UMNXADU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  reportEvent
4
- } from "../chunk-NFI2K2ZQ.js";
4
+ } from "../chunk-4XZCDSNG.js";
5
5
  import {
6
6
  askUser,
7
7
  waitForAnswer
@@ -9,14 +9,14 @@ import {
9
9
  import "../chunk-KOPUTJQC.js";
10
10
  import {
11
11
  getMachineId
12
- } from "../chunk-2HYPZLYY.js";
13
- import "../chunk-V37ZXMH3.js";
12
+ } from "../chunk-DKDDLF5P.js";
13
+ import "../chunk-GMI5QZLG.js";
14
14
  import "../chunk-BSZYIAZL.js";
15
15
  import "../chunk-SAF6HGAA.js";
16
16
  import "../chunk-OFRNZWC4.js";
17
17
  import "../chunk-7QLSKOSU.js";
18
18
  import "../chunk-KZERVKTD.js";
19
- import "../chunk-6MTNS63X.js";
19
+ import "../chunk-XX2V4QS5.js";
20
20
  import {
21
21
  getApiKey
22
22
  } from "../chunk-2UMNXADU.js";
@@ -16,7 +16,7 @@ import {
16
16
  } from "../chunk-5RUIFDTP.js";
17
17
  import {
18
18
  readKeySource
19
- } from "../chunk-L3YUHEB6.js";
19
+ } from "../chunk-V6N4Q223.js";
20
20
  import {
21
21
  parseFlags
22
22
  } from "../chunk-GMXKITVA.js";
@@ -35,7 +35,7 @@ import {
35
35
  import {
36
36
  EXIT
37
37
  } from "../chunk-KZERVKTD.js";
38
- import "../chunk-6MTNS63X.js";
38
+ import "../chunk-XX2V4QS5.js";
39
39
  import "../chunk-2UMNXADU.js";
40
40
  import "../chunk-L4C2JXJS.js";
41
41
 
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  inspectConfiguredManagedProviders
4
- } from "../chunk-5TASNKRX.js";
5
- import "../chunk-475T3XIO.js";
4
+ } from "../chunk-EA3E74P2.js";
5
+ import "../chunk-J2JZJZKB.js";
6
6
  import {
7
7
  HEARTBEAT_INTERVAL_MS,
8
8
  sendHeartbeat
9
- } from "../chunk-VP7SDXYG.js";
10
- import "../chunk-OBI4YMCT.js";
11
- import "../chunk-7TS2G4QG.js";
9
+ } from "../chunk-ZL7HEF2T.js";
10
+ import "../chunk-BAE45YLP.js";
11
+ import "../chunk-VA7VUNRD.js";
12
12
  import "../chunk-ATBKJNWS.js";
13
13
  import "../chunk-AIGDBRIJ.js";
14
14
  import {
@@ -23,7 +23,7 @@ import {
23
23
  replaceDaemonService,
24
24
  requestDaemonHandoff,
25
25
  stopDaemonRunning
26
- } from "../chunk-NQNCSPEH.js";
26
+ } from "../chunk-R2AGKCXL.js";
27
27
  import {
28
28
  detectProviderLiveCapabilities,
29
29
  hasSpawnProvider,
@@ -32,7 +32,7 @@ import {
32
32
  import {
33
33
  findLiveProcessBySpawnId,
34
34
  ownsLiveProcess
35
- } from "../chunk-4ZHQNBDP.js";
35
+ } from "../chunk-TF247BET.js";
36
36
  import {
37
37
  spawnClaude
38
38
  } from "../chunk-XHKBHWLX.js";
@@ -41,11 +41,11 @@ import {
41
41
  } from "../chunk-PZA7G4CN.js";
42
42
  import {
43
43
  getMachineId
44
- } from "../chunk-2HYPZLYY.js";
45
- import "../chunk-V37ZXMH3.js";
44
+ } from "../chunk-DKDDLF5P.js";
45
+ import "../chunk-GMI5QZLG.js";
46
46
  import {
47
47
  readControlMode
48
- } from "../chunk-L3YUHEB6.js";
48
+ } from "../chunk-V6N4Q223.js";
49
49
  import {
50
50
  exitOnHelpFlag
51
51
  } from "../chunk-LURY4WNF.js";
@@ -56,7 +56,7 @@ import "../chunk-OFRNZWC4.js";
56
56
  import {
57
57
  EXIT
58
58
  } from "../chunk-KZERVKTD.js";
59
- import "../chunk-6MTNS63X.js";
59
+ import "../chunk-XX2V4QS5.js";
60
60
  import {
61
61
  getApiKey,
62
62
  getBaseUrl
@@ -13,7 +13,7 @@ import {
13
13
  removeClaudeMcpServers,
14
14
  removeGeminiSettings,
15
15
  removePusharySettings
16
- } from "../chunk-7TS2G4QG.js";
16
+ } from "../chunk-VA7VUNRD.js";
17
17
  import "../chunk-ATBKJNWS.js";
18
18
  import "../chunk-AIGDBRIJ.js";
19
19
  import "../chunk-PZA7G4CN.js";
@@ -29,7 +29,7 @@ import {
29
29
  geminiSettings,
30
30
  removeCodexHooks,
31
31
  removeCodexSettings
32
- } from "../chunk-V37ZXMH3.js";
32
+ } from "../chunk-GMI5QZLG.js";
33
33
  import {
34
34
  exitOnHelpFlag
35
35
  } from "../chunk-LURY4WNF.js";
@@ -7,7 +7,7 @@ import {
7
7
  codexWired,
8
8
  geminiWired,
9
9
  pusharyHookExecutable
10
- } from "../chunk-OBI4YMCT.js";
10
+ } from "../chunk-BAE45YLP.js";
11
11
  import {
12
12
  agentProbes,
13
13
  detectAgent,
@@ -16,7 +16,7 @@ import {
16
16
  isDetected,
17
17
  isPluginRegistered,
18
18
  vscodeSettingsTargets
19
- } from "../chunk-QH4AA7QV.js";
19
+ } from "../chunk-A4O5ROZK.js";
20
20
  import {
21
21
  OPENCODE_PLUGIN_PLACEHOLDER,
22
22
  openCodePluginDir,
@@ -27,14 +27,14 @@ import {
27
27
  GEMINI_HOOK_BINARY,
28
28
  hasGeminiHooks,
29
29
  missingGeminiHookEvents
30
- } from "../chunk-7TS2G4QG.js";
30
+ } from "../chunk-VA7VUNRD.js";
31
31
  import "../chunk-ATBKJNWS.js";
32
32
  import "../chunk-AIGDBRIJ.js";
33
33
  import {
34
34
  daemonServiceManagerAvailable,
35
35
  hasDaemonServiceDefinition,
36
36
  readDaemonStatus
37
- } from "../chunk-NQNCSPEH.js";
37
+ } from "../chunk-R2AGKCXL.js";
38
38
  import {
39
39
  detectProviderLiveCapabilities,
40
40
  hasSpawnProvider,
@@ -50,7 +50,7 @@ import {
50
50
  import "../chunk-KOPUTJQC.js";
51
51
  import {
52
52
  getMachineId
53
- } from "../chunk-2HYPZLYY.js";
53
+ } from "../chunk-DKDDLF5P.js";
54
54
  import {
55
55
  claudeJson,
56
56
  claudeSettings,
@@ -70,7 +70,7 @@ import {
70
70
  readCodexMcpAuth,
71
71
  untrustedCodexHookEvents,
72
72
  vscodePluginDir
73
- } from "../chunk-V37ZXMH3.js";
73
+ } from "../chunk-GMI5QZLG.js";
74
74
  import {
75
75
  describeReach,
76
76
  describeRoundTrip,
@@ -90,7 +90,7 @@ import {
90
90
  keyPrefix,
91
91
  readControlMode,
92
92
  readKeySource
93
- } from "../chunk-L3YUHEB6.js";
93
+ } from "../chunk-V6N4Q223.js";
94
94
  import {
95
95
  parseFlags
96
96
  } from "../chunk-GMXKITVA.js";
@@ -114,7 +114,7 @@ import {
114
114
  import {
115
115
  EXIT
116
116
  } from "../chunk-KZERVKTD.js";
117
- import "../chunk-6MTNS63X.js";
117
+ import "../chunk-XX2V4QS5.js";
118
118
  import {
119
119
  getBaseUrl
120
120
  } from "../chunk-2UMNXADU.js";