@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.
- package/CHANGELOG.md +138 -0
- package/README.md +3 -2
- package/data/cursor-plugin/scripts/pushary-gate.mjs +70 -15
- package/data/vscode-plugin/scripts/pushary-gate.mjs +59 -11
- package/dist/bin/pushary-claude.js +21 -11
- package/dist/bin/pushary-clean.js +60 -22
- package/dist/bin/pushary-codex-hook.js +38 -23
- package/dist/bin/pushary-codex.js +1 -1
- package/dist/bin/pushary-connect.js +6 -4
- package/dist/bin/pushary-daemon.js +3 -3
- package/dist/bin/pushary-doctor.js +120 -28
- package/dist/bin/pushary-gemini-hook.js +32 -16
- package/dist/bin/pushary-hook.js +5 -5
- package/dist/bin/pushary-login.js +2 -2
- package/dist/bin/pushary-logout.js +2 -2
- package/dist/bin/pushary-mode.js +2 -2
- package/dist/bin/pushary-notification-hook.js +1 -1
- package/dist/bin/pushary-permission-denied-hook.js +3 -3
- package/dist/bin/pushary-permission-hook.js +3 -3
- package/dist/bin/pushary-post-hook.js +1 -1
- package/dist/bin/pushary-prompt-hook.js +1 -1
- package/dist/bin/pushary-session-end-hook.js +1 -1
- package/dist/bin/pushary-session-start-hook.js +1 -1
- package/dist/bin/pushary-setup.js +90 -13
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +4 -4
- package/dist/bin/pushary-stop-hook.js +1 -1
- package/dist/bin/pushary-stopfailure-hook.js +1 -1
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-upgrade.js +2 -2
- package/dist/bin/pushary-wait.js +2 -2
- package/dist/bin/pushary.js +1 -1
- package/dist/{chunk-JGH37QRB.js → chunk-7OYGFJYZ.js} +1 -1
- package/dist/chunk-B7R4YSAB.js +38 -0
- package/dist/{chunk-ATP6UQPH.js → chunk-BBK3TTU2.js} +1 -1
- package/dist/{chunk-XOUYM27W.js → chunk-FZIQSDTQ.js} +207 -113
- package/dist/chunk-GD275GEX.js +66 -0
- package/dist/{chunk-SONXGCZY.js → chunk-HU43EZ5Q.js} +45 -27
- package/dist/{chunk-KB4ODLGB.js → chunk-I4BYZIX4.js} +2 -0
- package/dist/{chunk-YMFZUXL5.js → chunk-MGFZXUUR.js} +57 -4
- package/dist/{chunk-YZT2CBC3.js → chunk-NQTRA7H5.js} +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +3 -3
- package/package.json +1 -1
- 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-
|
|
4
|
+
} from "../chunk-HU43EZ5Q.js";
|
|
5
5
|
import "../chunk-CAJZAFVS.js";
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
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";
|
|
@@ -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-
|
|
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-
|
|
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-
|
|
94
|
+
} from "../chunk-7OYGFJYZ.js";
|
|
90
95
|
import {
|
|
91
96
|
reportEvent
|
|
92
|
-
} from "../chunk-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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 =
|
|
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
|
|
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")
|
|
1439
|
-
|
|
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)}`);
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import {
|
|
3
3
|
describeLastSeen,
|
|
4
4
|
listMachines
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-NQTRA7H5.js";
|
|
6
6
|
import {
|
|
7
7
|
describeReach,
|
|
8
8
|
fetchChannels,
|
|
9
9
|
reachVerdict
|
|
10
|
-
} from "../chunk-
|
|
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-
|
|
30
|
-
import "../chunk-
|
|
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 {
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
} from "../chunk-GMXKITVA.js";
|
|
8
8
|
import {
|
|
9
9
|
exitOnHelpFlag
|
|
10
|
-
} from "../chunk-
|
|
11
|
-
import "../chunk-
|
|
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-
|
|
39
|
+
} from "../chunk-BBK3TTU2.js";
|
|
40
40
|
import {
|
|
41
41
|
isNewerVersion
|
|
42
|
-
} from "../chunk-
|
|
42
|
+
} from "../chunk-7OYGFJYZ.js";
|
|
43
43
|
import "../chunk-DQAN3JQP.js";
|
|
44
44
|
import {
|
|
45
45
|
getApiKey
|
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
} from "../chunk-GMXKITVA.js";
|
|
15
15
|
import {
|
|
16
16
|
exitOnHelpFlag
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-BBK3TTU2.js";
|
|
18
|
+
import "../chunk-7OYGFJYZ.js";
|
|
19
19
|
import "../chunk-SAF6HGAA.js";
|
|
20
20
|
import {
|
|
21
21
|
UsageError
|
package/dist/bin/pushary.js
CHANGED
|
@@ -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
|
|
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
|
+
};
|