@pushary/agent-hooks 0.68.0 → 0.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/README.md +3 -2
  3. package/data/cursor-plugin/scripts/pushary-gate.mjs +70 -15
  4. package/data/vscode-plugin/scripts/pushary-gate.mjs +59 -11
  5. package/dist/bin/pushary-claude.js +21 -11
  6. package/dist/bin/pushary-clean.js +60 -22
  7. package/dist/bin/pushary-codex-hook.js +38 -23
  8. package/dist/bin/pushary-codex.js +1 -1
  9. package/dist/bin/pushary-connect.js +6 -4
  10. package/dist/bin/pushary-daemon.js +3 -3
  11. package/dist/bin/pushary-doctor.js +120 -28
  12. package/dist/bin/pushary-gemini-hook.js +32 -16
  13. package/dist/bin/pushary-hook.js +5 -5
  14. package/dist/bin/pushary-login.js +2 -2
  15. package/dist/bin/pushary-logout.js +2 -2
  16. package/dist/bin/pushary-mode.js +2 -2
  17. package/dist/bin/pushary-notification-hook.js +1 -1
  18. package/dist/bin/pushary-permission-denied-hook.js +3 -3
  19. package/dist/bin/pushary-permission-hook.js +3 -3
  20. package/dist/bin/pushary-post-hook.js +1 -1
  21. package/dist/bin/pushary-prompt-hook.js +1 -1
  22. package/dist/bin/pushary-session-end-hook.js +1 -1
  23. package/dist/bin/pushary-session-start-hook.js +1 -1
  24. package/dist/bin/pushary-setup.js +90 -13
  25. package/dist/bin/pushary-stats.js +2 -2
  26. package/dist/bin/pushary-status.js +4 -4
  27. package/dist/bin/pushary-stop-hook.js +1 -1
  28. package/dist/bin/pushary-stopfailure-hook.js +1 -1
  29. package/dist/bin/pushary-suggestions.js +2 -2
  30. package/dist/bin/pushary-upgrade.js +2 -2
  31. package/dist/bin/pushary-wait.js +2 -2
  32. package/dist/bin/pushary.js +1 -1
  33. package/dist/{chunk-JGH37QRB.js → chunk-7OYGFJYZ.js} +1 -1
  34. package/dist/chunk-B7R4YSAB.js +38 -0
  35. package/dist/{chunk-ATP6UQPH.js → chunk-BBK3TTU2.js} +1 -1
  36. package/dist/{chunk-XOUYM27W.js → chunk-FZIQSDTQ.js} +207 -113
  37. package/dist/chunk-GD275GEX.js +66 -0
  38. package/dist/{chunk-SONXGCZY.js → chunk-HU43EZ5Q.js} +45 -27
  39. package/dist/{chunk-KB4ODLGB.js → chunk-I4BYZIX4.js} +2 -0
  40. package/dist/{chunk-YMFZUXL5.js → chunk-MGFZXUUR.js} +57 -4
  41. package/dist/{chunk-YZT2CBC3.js → chunk-NQTRA7H5.js} +1 -1
  42. package/dist/src/index.d.ts +1 -0
  43. package/dist/src/index.js +3 -3
  44. package/package.json +1 -1
  45. package/dist/chunk-YHG74UFF.js +0 -12
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePermissionRequest
4
- } from "../chunk-SONXGCZY.js";
4
+ } from "../chunk-HU43EZ5Q.js";
5
5
  import "../chunk-CAJZAFVS.js";
6
- import "../chunk-YHG74UFF.js";
7
- import "../chunk-XOUYM27W.js";
6
+ import "../chunk-GD275GEX.js";
7
+ import "../chunk-FZIQSDTQ.js";
8
8
  import "../chunk-WLGEY4UX.js";
9
9
  import "../chunk-BSZYIAZL.js";
10
10
  import "../chunk-SAF6HGAA.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePostToolUse
4
- } from "../chunk-XOUYM27W.js";
4
+ } from "../chunk-FZIQSDTQ.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleUserPrompt
4
- } from "../chunk-XOUYM27W.js";
4
+ } from "../chunk-FZIQSDTQ.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionEnd
4
- } from "../chunk-XOUYM27W.js";
4
+ } from "../chunk-FZIQSDTQ.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionStart
4
- } from "../chunk-XOUYM27W.js";
4
+ } from "../chunk-FZIQSDTQ.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -7,6 +7,11 @@ import {
7
7
  addPusharyHooks,
8
8
  addPusharyToolPermissions
9
9
  } from "../chunk-CAJZAFVS.js";
10
+ import {
11
+ claudeWired,
12
+ codexWired,
13
+ geminiWired
14
+ } from "../chunk-B7R4YSAB.js";
10
15
  import {
11
16
  describeDetection,
12
17
  detectAllAgents,
@@ -18,7 +23,7 @@ import {
18
23
  shortenHome,
19
24
  vscodeSettingsTargets,
20
25
  writeInstructionBlock
21
- } from "../chunk-KB4ODLGB.js";
26
+ } from "../chunk-I4BYZIX4.js";
22
27
  import {
23
28
  GEMINI_HOOK_BINARY,
24
29
  addGeminiHooks,
@@ -48,7 +53,7 @@ import {
48
53
  connectViaAppPairing,
49
54
  printConnectInstructions,
50
55
  setHumanStream
51
- } from "../chunk-YMFZUXL5.js";
56
+ } from "../chunk-MGFZXUUR.js";
52
57
  import "../chunk-3EGEA4KH.js";
53
58
  import {
54
59
  KEY_FILE_MODE,
@@ -86,10 +91,10 @@ import {
86
91
  getPackageVersion,
87
92
  isNewerVersion,
88
93
  renderCommandHelp
89
- } from "../chunk-JGH37QRB.js";
94
+ } from "../chunk-7OYGFJYZ.js";
90
95
  import {
91
96
  reportEvent
92
- } from "../chunk-XOUYM27W.js";
97
+ } from "../chunk-FZIQSDTQ.js";
93
98
  import "../chunk-BSZYIAZL.js";
94
99
  import "../chunk-SAF6HGAA.js";
95
100
  import {
@@ -318,6 +323,9 @@ var parseSetupOptions = (input2) => {
318
323
  if (key && keyStdin) {
319
324
  throw new UsageError("Pass either --key or --key-stdin, not both");
320
325
  }
326
+ if (key && !isValidApiKey(key)) {
327
+ throw new UsageError("--key is not a valid API key. Expected the pk_xxx.xxx shape from pushary.com/dashboard/agent/settings");
328
+ }
321
329
  return {
322
330
  connectMode,
323
331
  connectExplicit: connectRaw !== void 0,
@@ -328,7 +336,14 @@ var parseSetupOptions = (input2) => {
328
336
  // Anything that means "there is nobody to answer a prompt". A non-TTY stdin
329
337
  // is included because that is the case that used to hang: it is better to
330
338
  // take the defaults and say so than to wait forever for a keypress.
331
- nonInteractive: yes || agentsFlag !== void 0 || !input2.stdinIsTty,
339
+ //
340
+ // --json counts. Under it stdout carries exactly one object and every human
341
+ // line is redirected to stderr, so a prompt has nowhere to render: the
342
+ // question goes to stderr while the run blocks on a keypress the caller
343
+ // cannot see it is waiting for, and whatever is reading stdout waits forever
344
+ // for an object that never arrives. Asking for machine-readable output is
345
+ // itself a statement that no human is watching.
346
+ nonInteractive: yes || agentsFlag !== void 0 || flags.bools.has("json") || !input2.stdinIsTty,
332
347
  json: flags.bools.has("json"),
333
348
  dryRun: flags.bools.has("dry-run"),
334
349
  help,
@@ -359,6 +374,7 @@ var humanStream = process.stdout;
359
374
  var writeHuman = (text) => {
360
375
  humanStream.write(text);
361
376
  };
377
+ var jsonMode = false;
362
378
  var dim = (s) => `\x1B[2m${s}\x1B[0m`;
363
379
  var bold = (s) => `\x1B[1m${s}\x1B[0m`;
364
380
  var green = (s) => `\x1B[32m${s}\x1B[0m`;
@@ -367,6 +383,10 @@ var yellow = (s) => `\x1B[33m${s}\x1B[0m`;
367
383
  var check = green("\u2713");
368
384
  var abortWith = async (reason, code, keyCheck) => {
369
385
  await reportSetupAbort(reason, code, keyCheck);
386
+ if (jsonMode) {
387
+ process.stdout.write(`${JSON.stringify({ ok: false, reason, exitCode: code, ...keyCheck ? { keyCheck } : {} }, null, 2)}
388
+ `);
389
+ }
370
390
  return code;
371
391
  };
372
392
  var readKeyFromStdin = async (options) => {
@@ -1053,6 +1073,44 @@ var setupGemini = async (apiKey) => {
1053
1073
  console.log(` ${dim("Restart Gemini CLI to load the new config.")}`);
1054
1074
  noteManual("Restart Gemini CLI to load the new config.");
1055
1075
  };
1076
+ var agentIsWired = (agent) => {
1077
+ const readJson2 = (path) => {
1078
+ try {
1079
+ return JSON.parse(readFileSync(path, "utf-8"));
1080
+ } catch {
1081
+ return null;
1082
+ }
1083
+ };
1084
+ switch (agent) {
1085
+ case "claude_code":
1086
+ return claudeWired({
1087
+ claudeJson: readJson2(CLAUDE_JSON),
1088
+ settings: readJson2(CLAUDE_SETTINGS),
1089
+ skillExists: existsSync(join(CLAUDE_SKILL_DIR, "SKILL.md"))
1090
+ });
1091
+ case "codex": {
1092
+ let config = null;
1093
+ try {
1094
+ config = parseTOML(readFileSync(join(CODEX_HOME, "config.toml"), "utf-8"));
1095
+ } catch {
1096
+ config = null;
1097
+ }
1098
+ return codexWired({
1099
+ config,
1100
+ hooks: readJson2(CODEX_HOOKS_JSON),
1101
+ skillExists: existsSync(join(CODEX_SKILL_DIR, "SKILL.md"))
1102
+ });
1103
+ }
1104
+ case "gemini_cli":
1105
+ return geminiWired({ settings: readJson2(GEMINI_SETTINGS) });
1106
+ case "cursor":
1107
+ return existsSync(join(CURSOR_PLUGIN_DIR, "mcp.json"));
1108
+ case "vscode":
1109
+ return existsSync(join(VSCODE_PLUGIN_DIR, ".mcp.json"));
1110
+ default:
1111
+ return true;
1112
+ }
1113
+ };
1056
1114
  var AGENT_SETUP = {
1057
1115
  claude_code: setupClaudeCode,
1058
1116
  codex: setupCodex,
@@ -1201,7 +1259,8 @@ var resolveAgents = async (options) => {
1201
1259
  return options.agents.agents;
1202
1260
  }
1203
1261
  const detected = detectAgents();
1204
- if (options.agents.kind === "auto") {
1262
+ const wantsAuto = options.agents.kind === "auto" || options.nonInteractive;
1263
+ if (wantsAuto) {
1205
1264
  const picked = Object.keys(detected).filter((agent) => detected[agent].found);
1206
1265
  if (picked.length === 0) {
1207
1266
  console.log(` ${yellow("!")} No agents detected, so nothing was configured. Your key is saved.`);
@@ -1239,7 +1298,9 @@ var reportDryRun = (apiKey, agents, keyCheck) => {
1239
1298
  console.log();
1240
1299
  console.log(` ${bold("Dry run")} ${dim("\u2014 nothing below has been written")}`);
1241
1300
  console.log();
1242
- console.log(` ${dim("Key:")} ${dim(`${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`)} ${dim(`(${keyCheck?.kind ?? "not verified"})`)}`);
1301
+ console.log(
1302
+ apiKey ? ` ${dim("Key:")} ${dim(`${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`)} ${dim(`(${keyCheck?.kind ?? "not verified"})`)}` : ` ${dim("Key:")} ${dim("none on this machine \u2014 a real run would acquire one")}`
1303
+ );
1243
1304
  console.log(` ${dim("Key store:")} ${PUSHARY_CONFIG_FILE}`);
1244
1305
  const rc = resolveShellRc();
1245
1306
  console.log(` ${dim("Shell rc:")} ${rc ? rc.path : dim("none for this shell; the export line would be printed instead")}`);
@@ -1281,6 +1342,7 @@ var main = async () => {
1281
1342
  }
1282
1343
  recordSetupOptions(options);
1283
1344
  if (options.json) {
1345
+ jsonMode = true;
1284
1346
  humanStream = process.stderr;
1285
1347
  setHumanStream(process.stderr);
1286
1348
  console.log = (...args) => {
@@ -1302,12 +1364,12 @@ var main = async () => {
1302
1364
  let keyFromPairing = false;
1303
1365
  const storedKey = readConfigFileKey();
1304
1366
  const pairingRequested = connectMode === "app" && options.connectExplicit && !options.skipPhone;
1305
- const ambientEligible = !(flagKey && isValidApiKey(flagKey)) && !pairingRequested;
1367
+ const ambientEligible = flagKey === void 0 && !pairingRequested;
1306
1368
  const envCheck = ambientEligible && envKey && isValidApiKey(envKey) ? await usableStoredKey(envKey) : null;
1307
1369
  const storedCheck = ambientEligible && envCheck === null && storedKey !== null && isValidApiKey(storedKey) && // login writes both, so without this the same key is probed twice.
1308
1370
  storedKey !== envKey ? await usableStoredKey(storedKey) : null;
1309
1371
  let storedKeyCheck = null;
1310
- if (flagKey && isValidApiKey(flagKey)) {
1372
+ if (flagKey) {
1311
1373
  const masked = `${flagKey.slice(0, 8)}...${flagKey.slice(-4)}`;
1312
1374
  console.log(` ${check} Using API key: ${dim(masked)}`);
1313
1375
  console.log();
@@ -1323,7 +1385,7 @@ var main = async () => {
1323
1385
  const masked = `${envKey.slice(0, 8)}...${envKey.slice(-4)}`;
1324
1386
  console.log(` ${check} Found API key in environment: ${dim(masked)}`);
1325
1387
  console.log();
1326
- const useExisting = options.nonInteractive ? true : await confirm({ message: "Use this key?", default: true });
1388
+ const useExisting = options.nonInteractive || options.dryRun ? true : await confirm({ message: "Use this key?", default: true });
1327
1389
  if (useExisting) {
1328
1390
  trimmedKey = envKey;
1329
1391
  storedKeyCheck = envCheck;
@@ -1331,6 +1393,14 @@ var main = async () => {
1331
1393
  const apiKey = await input({ message: "API key:" });
1332
1394
  trimmedKey = apiKey.trim();
1333
1395
  }
1396
+ } else if (options.dryRun) {
1397
+ console.log(` ${dim("No key on this machine. A real run would connect one first.")}`);
1398
+ console.log();
1399
+ markStep("resolve-agents");
1400
+ const plannedAgents = await resolveAgents(options);
1401
+ reportDryRun(null, plannedAgents, null);
1402
+ emitJson(options, { ok: true, dryRun: true, agents: plannedAgents, keyCheck: "skipped", key: "none" });
1403
+ process.exit(EXIT.OK);
1334
1404
  } else if (connectMode === "app" && canRunBrowserLogin() && !options.skipPhone) {
1335
1405
  console.log(` ${dim("Pairing with your Pushary app.")}`);
1336
1406
  console.log(` ${dim("No app? Ctrl-C, then:")} ${cyan("npx @pushary/agent-hooks setup --connect browser")}`);
@@ -1405,7 +1475,7 @@ var main = async () => {
1405
1475
  `);
1406
1476
  process.exit(await abortWith("invalid-key", EXIT.USAGE));
1407
1477
  }
1408
- recordSetupKey(trimmedKey);
1478
+ if (!options.dryRun) recordSetupKey(trimmedKey);
1409
1479
  markStep("verify-key");
1410
1480
  const keyCheck = keyFromPairing ? null : await verifyKeyOrExit(trimmedKey, options, storedKeyCheck ?? void 0);
1411
1481
  markStep("resolve-agents");
@@ -1435,8 +1505,15 @@ var main = async () => {
1435
1505
  markStep(`configure:${agent}`);
1436
1506
  try {
1437
1507
  const outcome = await AGENT_SETUP[agent](trimmedKey, context);
1438
- if (outcome === "skipped") skipped.push(agent);
1439
- else completed.push(agent);
1508
+ if (outcome === "skipped") {
1509
+ skipped.push(agent);
1510
+ } else if (agentIsWired(agent)) {
1511
+ completed.push(agent);
1512
+ } else {
1513
+ failed.push(agent.replace("_", " "));
1514
+ console.log(` ${yellow("!")} ${agent.replace("_", " ")} reported success but its config is not there.`);
1515
+ console.log(` ${dim("Re-run setup, then")} ${cyan("npx @pushary/agent-hooks@latest doctor")} ${dim("to see what is missing.")}`);
1516
+ }
1440
1517
  } catch (err) {
1441
1518
  failed.push(agent.replace("_", " "));
1442
1519
  console.log(` ${yellow("!")} ${agent.replace("_", " ")} setup failed: ${formatError(err)}`);
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  exitOnHelpFlag
4
- } from "../chunk-ATP6UQPH.js";
5
- import "../chunk-JGH37QRB.js";
4
+ } from "../chunk-BBK3TTU2.js";
5
+ import "../chunk-7OYGFJYZ.js";
6
6
  import {
7
7
  readLedgerSummary
8
8
  } from "../chunk-WLGEY4UX.js";
@@ -2,12 +2,12 @@
2
2
  import {
3
3
  describeLastSeen,
4
4
  listMachines
5
- } from "../chunk-YZT2CBC3.js";
5
+ } from "../chunk-NQTRA7H5.js";
6
6
  import {
7
7
  describeReach,
8
8
  fetchChannels,
9
9
  reachVerdict
10
- } from "../chunk-YMFZUXL5.js";
10
+ } from "../chunk-MGFZXUUR.js";
11
11
  import "../chunk-3EGEA4KH.js";
12
12
  import {
13
13
  readKeySource
@@ -26,8 +26,8 @@ import {
26
26
  } from "../chunk-GMXKITVA.js";
27
27
  import {
28
28
  exitOnHelpFlag
29
- } from "../chunk-ATP6UQPH.js";
30
- import "../chunk-JGH37QRB.js";
29
+ } from "../chunk-BBK3TTU2.js";
30
+ import "../chunk-7OYGFJYZ.js";
31
31
  import "../chunk-BSZYIAZL.js";
32
32
  import "../chunk-SAF6HGAA.js";
33
33
  import {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleStop
4
- } from "../chunk-XOUYM27W.js";
4
+ } from "../chunk-FZIQSDTQ.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleStopFailure
4
- } from "../chunk-XOUYM27W.js";
4
+ } from "../chunk-FZIQSDTQ.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -7,8 +7,8 @@ import {
7
7
  } from "../chunk-GMXKITVA.js";
8
8
  import {
9
9
  exitOnHelpFlag
10
- } from "../chunk-ATP6UQPH.js";
11
- import "../chunk-JGH37QRB.js";
10
+ } from "../chunk-BBK3TTU2.js";
11
+ import "../chunk-7OYGFJYZ.js";
12
12
  import {
13
13
  UsageError
14
14
  } from "../chunk-7QLSKOSU.js";
@@ -36,10 +36,10 @@ import {
36
36
  } from "../chunk-MUEW424A.js";
37
37
  import {
38
38
  exitOnHelpFlag
39
- } from "../chunk-ATP6UQPH.js";
39
+ } from "../chunk-BBK3TTU2.js";
40
40
  import {
41
41
  isNewerVersion
42
- } from "../chunk-JGH37QRB.js";
42
+ } from "../chunk-7OYGFJYZ.js";
43
43
  import "../chunk-DQAN3JQP.js";
44
44
  import {
45
45
  getApiKey
@@ -14,8 +14,8 @@ import {
14
14
  } from "../chunk-GMXKITVA.js";
15
15
  import {
16
16
  exitOnHelpFlag
17
- } from "../chunk-ATP6UQPH.js";
18
- import "../chunk-JGH37QRB.js";
17
+ } from "../chunk-BBK3TTU2.js";
18
+ import "../chunk-7OYGFJYZ.js";
19
19
  import "../chunk-SAF6HGAA.js";
20
20
  import {
21
21
  UsageError
@@ -4,7 +4,7 @@ import {
4
4
  getPackageVersion,
5
5
  isCommandName,
6
6
  renderHelp
7
- } from "../chunk-JGH37QRB.js";
7
+ } from "../chunk-7OYGFJYZ.js";
8
8
  import {
9
9
  installProxyDispatcher
10
10
  } from "../chunk-SAF6HGAA.js";
@@ -3,7 +3,7 @@ var COMMAND_LIST = [
3
3
  {
4
4
  name: "setup",
5
5
  module: "pushary-setup",
6
- summary: "Configure Claude Code, Codex, Gemini CLI, Hermes, or Cursor with Pushary"
6
+ summary: "Configure Claude Code, Codex, Gemini CLI, Hermes, Cursor, or VS Code with Pushary"
7
7
  },
8
8
  {
9
9
  name: "claude",
@@ -0,0 +1,38 @@
1
+ import {
2
+ hasGeminiHooks
3
+ } from "./chunk-E2U35RLD.js";
4
+ import {
5
+ hasCodexHooks
6
+ } from "./chunk-7HG4WUIE.js";
7
+
8
+ // src/diagnostics/wiring.ts
9
+ var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
10
+ var CLAUDE_HOOK_BINARY = /pushary-[a-z-]*hook/;
11
+ var claudeWired = ({ claudeJson, settings, skillExists }) => {
12
+ if (record(record(claudeJson)?.mcpServers)?.pushary) return true;
13
+ const s = record(settings);
14
+ if (s) {
15
+ if (CLAUDE_HOOK_BINARY.test(JSON.stringify(s.hooks ?? {}))) return true;
16
+ const allow = record(s.permissions)?.allow;
17
+ if (Array.isArray(allow) && allow.some((rule) => String(rule).includes("mcp__pushary__"))) return true;
18
+ }
19
+ return skillExists;
20
+ };
21
+ var codexWired = ({ config, hooks, skillExists }) => {
22
+ if (record(record(config)?.mcp_servers)?.pushary) return true;
23
+ const h = record(hooks);
24
+ if (h && hasCodexHooks(h)) return true;
25
+ return skillExists;
26
+ };
27
+ var geminiWired = ({ settings }) => {
28
+ const s = record(settings);
29
+ if (!s) return false;
30
+ if (record(s.mcpServers)?.pushary) return true;
31
+ return hasGeminiHooks(s);
32
+ };
33
+
34
+ export {
35
+ claudeWired,
36
+ codexWired,
37
+ geminiWired
38
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getPackageVersion,
3
3
  renderCommandHelp
4
- } from "./chunk-JGH37QRB.js";
4
+ } from "./chunk-7OYGFJYZ.js";
5
5
  import {
6
6
  EXIT
7
7
  } from "./chunk-KZERVKTD.js";