@pushary/agent-hooks 0.89.5 → 0.89.7

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 (42) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/bin/pushary-bell.js +1 -1
  3. package/dist/bin/pushary-claude.js +5 -5
  4. package/dist/bin/pushary-clean.js +128 -24
  5. package/dist/bin/pushary-codex-bridge.js +3 -3
  6. package/dist/bin/pushary-codex-hook.js +3 -3
  7. package/dist/bin/pushary-codex.js +3 -3
  8. package/dist/bin/pushary-daemon.js +47 -9
  9. package/dist/bin/pushary-disconnect.js +2 -2
  10. package/dist/bin/pushary-doctor.js +6 -6
  11. package/dist/bin/pushary-elicitation-hook.js +2 -2
  12. package/dist/bin/pushary-gemini-bridge.js +3 -3
  13. package/dist/bin/pushary-gemini-hook.js +3 -3
  14. package/dist/bin/pushary-hook.js +4 -4
  15. package/dist/bin/pushary-logout.js +1 -1
  16. package/dist/bin/pushary-notification-hook.js +3 -3
  17. package/dist/bin/pushary-opencode-hook.js +3 -3
  18. package/dist/bin/pushary-permission-denied-hook.js +4 -4
  19. package/dist/bin/pushary-permission-hook.js +4 -4
  20. package/dist/bin/pushary-post-hook.js +3 -3
  21. package/dist/bin/pushary-prompt-hook.js +3 -3
  22. package/dist/bin/pushary-session-end-hook.js +3 -3
  23. package/dist/bin/pushary-session-start-hook.js +3 -3
  24. package/dist/bin/pushary-setup.js +46 -16
  25. package/dist/bin/pushary-status.js +3 -3
  26. package/dist/bin/pushary-stop-hook.js +3 -3
  27. package/dist/bin/pushary-stopfailure-hook.js +3 -3
  28. package/dist/bin/pushary-upgrade.js +38 -198
  29. package/dist/{chunk-2HYPZLYY.js → chunk-2M66JVZM.js} +1 -1
  30. package/dist/chunk-2MEJBUOI.js +210 -0
  31. package/dist/{chunk-4ZHQNBDP.js → chunk-42TTFZLV.js} +1 -1
  32. package/dist/{chunk-MZBT2LXW.js → chunk-5YUVKPTS.js} +2 -2
  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-NFI2K2ZQ.js → chunk-BPKMGE7L.js} +1 -1
  36. package/dist/{chunk-V37ZXMH3.js → chunk-GMI5QZLG.js} +15 -9
  37. package/dist/{chunk-475T3XIO.js → chunk-J2JZJZKB.js} +1 -1
  38. package/dist/{chunk-VP7SDXYG.js → chunk-TESGYWEM.js} +1 -1
  39. package/dist/{chunk-7TS2G4QG.js → chunk-VA7VUNRD.js} +22 -14
  40. package/dist/{chunk-TRQ46MXR.js → chunk-ZH7TWAYK.js} +8 -5
  41. package/dist/src/index.js +4 -4
  42. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.89.7
4
+
5
+ ### clean no longer uninstalls the macOS app along with the CLI
6
+
7
+ `clean` removed `~/.pushary` whole. That directory is not only the CLI's: the Mac
8
+ app roots its entire runtime there, so the locator every hook execs, the socket
9
+ the app listens on, its gate state and its spool all went with it. It also
10
+ stripped the app's hook entries out of the agent configs. The app went on
11
+ running and went on reporting itself connected, while nothing reached it.
12
+
13
+ It now removes what the CLI owns and leaves `bin`, `run`, `spool` and `plugins`.
14
+ Hook entries are attributed by the command they name, so the app keeps its own.
15
+ `disconnect` is unchanged and still disconnects an agent whichever product
16
+ connected it.
17
+
18
+ The `mcpServers.pushary` entry and the VS Code plugin directory cannot be
19
+ attributed to either product, so they are kept when the app is installed and
20
+ removed when it is not. A CLI-only clean still leaves no API key on disk.
21
+
22
+ ### clean handles OpenCode
23
+
24
+ setup installs an OpenCode plugin and an MCP entry and `clean` walked past both,
25
+ so a command that says it removes all Pushary configuration left the sixth agent
26
+ wired. A `pushary.js` somebody else wrote, or one the Mac app wrote, is left
27
+ alone.
28
+
3
29
  ## 0.89.3
4
30
 
5
31
  ### Doctor recognizes hooks installed by the macOS app
@@ -12,7 +12,7 @@ import {
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";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ensureDaemonRunning
4
- } from "../chunk-TRQ46MXR.js";
4
+ } from "../chunk-ZH7TWAYK.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-42TTFZLV.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-BPKMGE7L.js";
31
31
  import {
32
32
  DEFAULT_SESSION,
33
33
  askUser,
@@ -46,8 +46,8 @@ 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-2M66JVZM.js";
50
+ import "../chunk-GMI5QZLG.js";
51
51
  import "../chunk-DINDL2CF.js";
52
52
  import "../chunk-BSZYIAZL.js";
53
53
  import "../chunk-SAF6HGAA.js";
@@ -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-TRQ46MXR.js";
27
+ } from "../chunk-ZH7TWAYK.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-2M66JVZM.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";
@@ -60,7 +69,8 @@ import {
60
69
  import "../chunk-6MTNS63X.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,17 @@ 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
+ }
253
293
  cleanSettingsFile(CLAUDE_SETTINGS, "Claude Code settings");
254
294
  cleanSettingsFile(CLAUDE_SETTINGS_LOCAL, "Claude Code settings.local");
255
- const claudeJson2 = readJson(CLAUDE_JSON);
256
- if (claudeJson2) {
295
+ const claudeJson2 = keepShared ? null : readJson(CLAUDE_JSON);
296
+ if (keepShared) {
297
+ console.log(` ${skip} Claude Code MCP servers ${dim("(kept: the Mac app uses it)")}`);
298
+ } else if (claudeJson2) {
257
299
  if (removeClaudeMcpServers(claudeJson2)) {
258
300
  writeJson(CLAUDE_JSON, claudeJson2);
259
301
  console.log(` ${check} Claude Code MCP servers ${dim("(removed from ~/.claude.json)")}`);
@@ -263,8 +305,10 @@ var main = async () => {
263
305
  } else {
264
306
  console.log(` ${skip} Claude Code MCP servers ${dim("(not found)")}`);
265
307
  }
266
- const cursorData = readJson(CURSOR_MCP);
267
- if (cursorData) {
308
+ const cursorData = keepShared ? null : readJson(CURSOR_MCP);
309
+ if (keepShared) {
310
+ console.log(` ${skip} Cursor MCP config ${dim("(kept: the Mac app uses it)")}`);
311
+ } else if (cursorData) {
268
312
  const mcpServers = cursorData.mcpServers;
269
313
  if (mcpServers?.pushary) {
270
314
  delete mcpServers.pushary;
@@ -295,7 +339,10 @@ var main = async () => {
295
339
  } else {
296
340
  console.log(` ${skip} Cursor plugin ${dim("(not installed)")}`);
297
341
  }
298
- for (const settingsPath of vscodeSettingsTargets(existsSync)) {
342
+ if (keepShared) {
343
+ console.log(` ${skip} VS Code plugin ${dim("(kept: the Mac app writes the same plugin directory)")}`);
344
+ }
345
+ for (const settingsPath of keepShared ? [] : vscodeSettingsTargets(existsSync)) {
299
346
  const label = `VS Code plugin ${dim(`(${shortenHome(settingsPath)})`)}`;
300
347
  if (!existsSync(settingsPath)) {
301
348
  console.log(` ${skip} ${label} ${dim("(no settings.json)")}`);
@@ -311,7 +358,7 @@ var main = async () => {
311
358
  console.log(` ${skip} ${label} ${dim("(no pushary entry)")}`);
312
359
  }
313
360
  }
314
- if (existsSync(VSCODE_PLUGIN_DIR)) {
361
+ if (!keepShared && existsSync(VSCODE_PLUGIN_DIR)) {
315
362
  guardedRemove(VSCODE_PLUGIN_DIR);
316
363
  console.log(` ${check} VS Code plugin files ${dim(did("removed"))}`);
317
364
  }
@@ -331,10 +378,12 @@ var main = async () => {
331
378
  const trustRemoved = removeCodexHookTrust(parsed, codexHooksJson2, codexPositions);
332
379
  const hadPushary = config.includes("pushary");
333
380
  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;
381
+ if (!keepShared) {
382
+ const mcpServers = parsed.mcp_servers ?? {};
383
+ delete mcpServers.pushary;
384
+ if (Object.keys(mcpServers).length === 0) delete parsed.mcp_servers;
385
+ else parsed.mcp_servers = mcpServers;
386
+ }
338
387
  if (Array.isArray(parsed.notify)) {
339
388
  parsed.notify = parsed.notify.filter((n) => typeof n !== "string" || !n.includes("pushary-codex"));
340
389
  if (parsed.notify.length === 0) delete parsed.notify;
@@ -349,7 +398,7 @@ var main = async () => {
349
398
  console.log(` ${skip} Codex config ${dim("(not found)")}`);
350
399
  }
351
400
  if (codexHooksData) {
352
- if (removeCodexHooks(codexHooksData)) {
401
+ if (removeCodexHooks(codexHooksData, removalScope())) {
353
402
  writeJson(codexHooksJson2, codexHooksData);
354
403
  console.log(` ${check} Codex hooks ${dim("(removed from ~/.codex/hooks.json)")}`);
355
404
  } else {
@@ -374,7 +423,7 @@ var main = async () => {
374
423
  const geminiSettingsPath = geminiSettings();
375
424
  const geminiSettings2 = readJson(geminiSettingsPath);
376
425
  if (geminiSettings2) {
377
- if (removeGeminiSettings(geminiSettings2)) {
426
+ if (removeGeminiSettings(geminiSettings2, removalScope())) {
378
427
  writeJson(geminiSettingsPath, geminiSettings2);
379
428
  console.log(` ${check} Gemini CLI settings ${dim(did("cleaned"))}`);
380
429
  } else {
@@ -389,6 +438,44 @@ var main = async () => {
389
438
  } else {
390
439
  console.log(` ${skip} Gemini GEMINI.md ${dim("(no pushary block)")}`);
391
440
  }
441
+ const openCodePlugin = openCodePluginFile();
442
+ const openCodePluginContents = existsSync(openCodePlugin) ? readFileSync(openCodePlugin, "utf-8") : null;
443
+ if (openCodePluginContents === null) {
444
+ console.log(` ${skip} OpenCode plugin ${dim("(not installed)")}`);
445
+ } else if (!isOpenCodePluginOurs(openCodePluginContents)) {
446
+ console.log(` ${skip} OpenCode plugin ${dim("(a pushary.js we did not write)")}`);
447
+ } else if (openCodePluginContents.includes(HOOK_LOCATOR_BINARY)) {
448
+ console.log(` ${skip} OpenCode plugin ${dim("(kept: written by the Mac app)")}`);
449
+ } else {
450
+ guardedRemove(openCodePlugin, { force: true });
451
+ console.log(` ${check} OpenCode plugin ${dim(did("removed"))}`);
452
+ const sibling = join(openCodePluginDir(), OPENCODE_PLUGIN_SIBLING);
453
+ const remaining = (() => {
454
+ try {
455
+ return readdirSync(openCodePluginDir()).filter((name) => name !== OPENCODE_PLUGIN_SIBLING);
456
+ } catch {
457
+ return [];
458
+ }
459
+ })();
460
+ const siblingIsOurs = existsSync(sibling) && readFileSync(sibling, "utf-8") === OPENCODE_PLUGIN_SIBLING_CONTENTS;
461
+ if (siblingIsOurs && !hasForeignPlugins(remaining)) {
462
+ guardedRemove(sibling, { force: true });
463
+ console.log(` ${check} OpenCode plugin sibling ${dim(did("removed"))}`);
464
+ }
465
+ }
466
+ const openCodeConfig = keepShared ? null : readJson(openCodeConfigFile());
467
+ if (keepShared) {
468
+ console.log(` ${skip} OpenCode MCP ${dim("(kept: the Mac app uses it)")}`);
469
+ } else if (openCodeConfig) {
470
+ if (removeOpenCodeMcpServer(openCodeConfig)) {
471
+ writeJson(openCodeConfigFile(), openCodeConfig);
472
+ console.log(` ${check} OpenCode MCP ${dim(did("removed"))}`);
473
+ } else {
474
+ console.log(` ${skip} OpenCode MCP ${dim("(no pushary entries)")}`);
475
+ }
476
+ } else {
477
+ console.log(` ${skip} OpenCode MCP ${dim("(not found)")}`);
478
+ }
392
479
  const hermesPython = resolveHermesPython();
393
480
  if (hermesPython) {
394
481
  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)';
@@ -441,8 +528,25 @@ var main = async () => {
441
528
  console.log(` ${cross} Background service ${dim("(could not stop or uninstall)")}`);
442
529
  }
443
530
  if (existsSync(PUSHARY_DIR)) {
444
- guardedRemove(PUSHARY_DIR);
445
- console.log(` ${check} Local state ${dim("(~/.pushary removed: stored API key, ledger)")}`);
531
+ let removed = 0;
532
+ const kept = [];
533
+ for (const entry of readdirSync(PUSHARY_DIR)) {
534
+ if (keepShared && isAppOwned(entry)) {
535
+ kept.push(entry);
536
+ continue;
537
+ }
538
+ guardedRemove(join(PUSHARY_DIR, entry), { force: true });
539
+ removed++;
540
+ }
541
+ if (removed > 0) {
542
+ const what = `${removed} entr${removed === 1 ? "y" : "ies"} from ~/.pushary: stored API key, ledger`;
543
+ console.log(` ${check} Local state ${dim(dryRun ? `(would remove ${what})` : `(removed ${what})`)}`);
544
+ } else {
545
+ console.log(` ${skip} Local state ${dim("(nothing of ours in ~/.pushary)")}`);
546
+ }
547
+ if (kept.length > 0) {
548
+ console.log(` ${dim(`left ${kept.sort().join(", ")} for the Mac app`)}`);
549
+ }
446
550
  } else {
447
551
  console.log(` ${skip} Local state ${dim("(~/.pushary not found)")}`);
448
552
  }
@@ -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-42TTFZLV.js";
15
15
  import {
16
16
  spawnClaude
17
17
  } from "../chunk-XHKBHWLX.js";
@@ -20,8 +20,8 @@ import {
20
20
  } from "../chunk-PZA7G4CN.js";
21
21
  import {
22
22
  getMachineId
23
- } from "../chunk-2HYPZLYY.js";
24
- import "../chunk-V37ZXMH3.js";
23
+ } from "../chunk-2M66JVZM.js";
24
+ import "../chunk-GMI5QZLG.js";
25
25
  import "../chunk-6MTNS63X.js";
26
26
  import {
27
27
  getApiKey,
@@ -31,7 +31,7 @@ import {
31
31
  toCodexWire,
32
32
  toPolicyLookup,
33
33
  toPolicyLookups
34
- } from "../chunk-NFI2K2ZQ.js";
34
+ } from "../chunk-BPKMGE7L.js";
35
35
  import {
36
36
  DEFAULT_SESSION,
37
37
  askUser,
@@ -49,10 +49,10 @@ import {
49
49
  } from "../chunk-KOPUTJQC.js";
50
50
  import {
51
51
  getMachineId
52
- } from "../chunk-2HYPZLYY.js";
52
+ } from "../chunk-2M66JVZM.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";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  reportEvent
4
- } from "../chunk-NFI2K2ZQ.js";
4
+ } from "../chunk-BPKMGE7L.js";
5
5
  import {
6
6
  askUser,
7
7
  waitForAnswer
@@ -9,8 +9,8 @@ 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-2M66JVZM.js";
13
+ import "../chunk-GMI5QZLG.js";
14
14
  import "../chunk-BSZYIAZL.js";
15
15
  import "../chunk-SAF6HGAA.js";
16
16
  import "../chunk-OFRNZWC4.js";
@@ -1,27 +1,38 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ inspectConfiguredManagedProviders
4
+ } from "../chunk-2MEJBUOI.js";
5
+ import "../chunk-J2JZJZKB.js";
2
6
  import {
3
7
  HEARTBEAT_INTERVAL_MS,
4
8
  sendHeartbeat
5
- } from "../chunk-VP7SDXYG.js";
9
+ } from "../chunk-TESGYWEM.js";
10
+ import "../chunk-BAE45YLP.js";
11
+ import "../chunk-VA7VUNRD.js";
12
+ import "../chunk-ATBKJNWS.js";
13
+ import "../chunk-AIGDBRIJ.js";
6
14
  import {
7
15
  DAEMON_LEASE_RENEW_INTERVAL_MS,
8
16
  acquireDaemonLease,
17
+ daemonServiceManagerAvailable,
9
18
  ensureDaemonRunning,
19
+ hasDaemonServiceDefinition,
10
20
  manageDaemonService,
11
21
  parseDaemonAction,
12
22
  readDaemonStatus,
13
23
  replaceDaemonService,
14
24
  requestDaemonHandoff,
15
25
  stopDaemonRunning
16
- } from "../chunk-TRQ46MXR.js";
26
+ } from "../chunk-ZH7TWAYK.js";
17
27
  import {
18
28
  detectProviderLiveCapabilities,
19
- hasSpawnProvider
29
+ hasSpawnProvider,
30
+ resolveControlPolicy
20
31
  } from "../chunk-NKHEHEUM.js";
21
32
  import {
22
33
  findLiveProcessBySpawnId,
23
34
  ownsLiveProcess
24
- } from "../chunk-4ZHQNBDP.js";
35
+ } from "../chunk-42TTFZLV.js";
25
36
  import {
26
37
  spawnClaude
27
38
  } from "../chunk-XHKBHWLX.js";
@@ -30,13 +41,18 @@ import {
30
41
  } from "../chunk-PZA7G4CN.js";
31
42
  import {
32
43
  getMachineId
33
- } from "../chunk-2HYPZLYY.js";
34
- import "../chunk-V37ZXMH3.js";
44
+ } from "../chunk-2M66JVZM.js";
45
+ import "../chunk-GMI5QZLG.js";
46
+ import {
47
+ readControlMode
48
+ } from "../chunk-L3YUHEB6.js";
35
49
  import {
36
50
  exitOnHelpFlag
37
51
  } from "../chunk-LURY4WNF.js";
38
52
  import "../chunk-3XTFX4CL.js";
53
+ import "../chunk-BC3VCZ3E.js";
39
54
  import "../chunk-DINDL2CF.js";
55
+ import "../chunk-OFRNZWC4.js";
40
56
  import {
41
57
  EXIT
42
58
  } from "../chunk-KZERVKTD.js";
@@ -174,9 +190,12 @@ var normalizeLaunchAgent = (requestedAgent) => {
174
190
  if (requestedAgent === "codex" || requestedAgent === "gemini") return requestedAgent;
175
191
  return null;
176
192
  };
177
- var providerLaunchError = (requestedAgent, binaries) => {
193
+ var providerLaunchError = (requestedAgent, binaries, configuredProviders) => {
178
194
  const agent = normalizeLaunchAgent(requestedAgent);
179
195
  if (!agent) return `Unsupported agent provider: ${requestedAgent}`;
196
+ if (configuredProviders && !configuredProviders.includes(agent)) {
197
+ return `${agent === "claude" ? "Claude Code" : agent === "codex" ? "Codex" : "Gemini"} is not configured for Pushary on this machine`;
198
+ }
180
199
  if (binaries[agent]) return null;
181
200
  return agent === "claude" ? "Claude Code is not installed on this machine" : `${agent === "codex" ? "Codex" : "Gemini"} CLI is not installed on this machine`;
182
201
  };
@@ -241,7 +260,8 @@ var runSpawnDaemon = async () => {
241
260
  const machineId = getMachineId();
242
261
  const baseUrl = getBaseUrl();
243
262
  const pusharyBin = resolveBinary("pushary") ?? "pushary";
244
- const providerCapabilities = detectProviderLiveCapabilities();
263
+ const configuredProviders = inspectConfiguredManagedProviders();
264
+ const providerCapabilities = detectProviderLiveCapabilities(configuredProviders);
245
265
  const siblingEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary.js") : "";
246
266
  const codexBridgeEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary-codex-bridge.js") : "pushary-codex-bridge";
247
267
  const geminiBridgeEntry = process.argv[1] ? join(dirname(process.argv[1]), "pushary-gemini-bridge.js") : "pushary-gemini-bridge";
@@ -298,7 +318,7 @@ var runSpawnDaemon = async () => {
298
318
  claude: agent === "claude" ? providerBin ?? null : null,
299
319
  codex: agent === "codex" ? providerBin ?? null : null,
300
320
  gemini: agent === "gemini" ? providerBin ?? null : null
301
- });
321
+ }, configuredProviders);
302
322
  if (unavailable) return Promise.reject(new Error(unavailable));
303
323
  spawnTimestamps.push(Date.now());
304
324
  const cwd = directory.cwd;
@@ -598,6 +618,24 @@ var main = async () => {
598
618
  `);
599
619
  return status.kind === "running" ? EXIT.OK : EXIT.UNREACHABLE;
600
620
  }
621
+ if (action === "install" || action === "start" || action === "restart") {
622
+ if (!getApiKey()) {
623
+ process.stderr.write("[pushary] daemon service has no readable API key; re-run setup.\n");
624
+ return EXIT.FAILED;
625
+ }
626
+ const status = readDaemonStatus();
627
+ const controlPolicy = resolveControlPolicy({
628
+ mode: readControlMode() ?? (action === "install" ? "on" : null),
629
+ providerAvailable: hasSpawnProvider(detectProviderLiveCapabilities(inspectConfiguredManagedProviders())),
630
+ managerAvailable: daemonServiceManagerAvailable(),
631
+ servicePresent: status.kind !== "absent" || hasDaemonServiceDefinition()
632
+ });
633
+ if (controlPolicy !== "enabled") {
634
+ process.stderr.write(`[pushary] daemon service is ${controlPolicy}; run setup with --control on to configure phone-start safely.
635
+ `);
636
+ return EXIT.FAILED;
637
+ }
638
+ }
601
639
  if (action === "install") {
602
640
  const installed = await replaceDaemonService();
603
641
  if (installed.kind !== "ok") {
@@ -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-TRQ46MXR.js";
37
+ } from "../chunk-ZH7TWAYK.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-2M66JVZM.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,
@@ -14,8 +14,8 @@ import {
14
14
  } from "../chunk-GKAKAOKC.js";
15
15
  import {
16
16
  getMachineId
17
- } from "../chunk-2HYPZLYY.js";
18
- import "../chunk-V37ZXMH3.js";
17
+ } from "../chunk-2M66JVZM.js";
18
+ import "../chunk-GMI5QZLG.js";
19
19
  import "../chunk-BSZYIAZL.js";
20
20
  import "../chunk-SAF6HGAA.js";
21
21
  import "../chunk-7QLSKOSU.js";
@@ -10,7 +10,7 @@ import "../chunk-PMHTCDEO.js";
10
10
  import {
11
11
  startProcessOwnership,
12
12
  withSpawnProcessOwnership
13
- } from "../chunk-4ZHQNBDP.js";
13
+ } from "../chunk-42TTFZLV.js";
14
14
  import {
15
15
  spawnClaude
16
16
  } from "../chunk-XHKBHWLX.js";
@@ -19,8 +19,8 @@ import {
19
19
  } from "../chunk-PZA7G4CN.js";
20
20
  import {
21
21
  getMachineId
22
- } from "../chunk-2HYPZLYY.js";
23
- import "../chunk-V37ZXMH3.js";
22
+ } from "../chunk-2M66JVZM.js";
23
+ import "../chunk-GMI5QZLG.js";
24
24
  import "../chunk-6MTNS63X.js";
25
25
  import {
26
26
  getApiKey,
@@ -21,7 +21,7 @@ import {
21
21
  readLastUserPrompt,
22
22
  repoKeyFor,
23
23
  reportEvent
24
- } from "../chunk-NFI2K2ZQ.js";
24
+ } from "../chunk-BPKMGE7L.js";
25
25
  import {
26
26
  DEFAULT_SESSION,
27
27
  askUser,
@@ -39,8 +39,8 @@ import {
39
39
  } from "../chunk-KOPUTJQC.js";
40
40
  import {
41
41
  getMachineId
42
- } from "../chunk-2HYPZLYY.js";
43
- import "../chunk-V37ZXMH3.js";
42
+ } from "../chunk-2M66JVZM.js";
43
+ import "../chunk-GMI5QZLG.js";
44
44
  import "../chunk-BSZYIAZL.js";
45
45
  import "../chunk-SAF6HGAA.js";
46
46
  import "../chunk-OFRNZWC4.js";