@pushary/agent-hooks 0.61.0 → 0.62.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 +48 -0
- package/dist/bin/pushary-claude.js +4 -4
- package/dist/bin/pushary-clean.js +62 -32
- package/dist/bin/pushary-codex-hook.js +4 -4
- package/dist/bin/pushary-codex.js +3 -3
- package/dist/bin/pushary-connect.js +6 -6
- package/dist/bin/pushary-daemon.js +37 -5
- package/dist/bin/pushary-doctor.js +113 -34
- package/dist/bin/pushary-gemini-hook.js +4 -4
- package/dist/bin/pushary-hook.js +5 -5
- package/dist/bin/pushary-login.js +4 -4
- package/dist/bin/pushary-logout.js +51 -9
- package/dist/bin/pushary-mode.js +4 -4
- package/dist/bin/pushary-notification-hook.js +2 -2
- 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 +2 -2
- package/dist/bin/pushary-prompt-hook.js +2 -2
- package/dist/bin/pushary-session-end-hook.js +2 -2
- package/dist/bin/pushary-session-start-hook.js +2 -2
- package/dist/bin/pushary-setup.js +92 -152
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +5 -5
- package/dist/bin/pushary-stop-hook.js +2 -2
- package/dist/bin/pushary-stopfailure-hook.js +2 -2
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-upgrade.js +176 -11
- package/dist/bin/pushary-wait.js +4 -4
- package/dist/bin/pushary.js +1 -1
- package/dist/{chunk-B26DNXCA.js → chunk-247C4RE5.js} +1 -0
- package/dist/{chunk-GX64YGU3.js → chunk-3O27ZSRE.js} +25 -0
- package/dist/{chunk-HI4AGGE6.js → chunk-5SO3CEGJ.js} +4 -4
- package/dist/chunk-E2U35RLD.js +108 -0
- package/dist/chunk-ER657KRJ.js +168 -0
- package/dist/{chunk-HUJQSP4F.js → chunk-IIZZYUWK.js} +1 -1
- package/dist/chunk-N7XJ4L2W.js +79 -0
- package/dist/{chunk-R6C4USIV.js → chunk-ONVEYEVR.js} +2 -2
- package/dist/{chunk-SML23YOT.js → chunk-SP7OZXCQ.js} +10 -2
- package/dist/chunk-UXXRRXUS.js +93 -0
- package/dist/{chunk-UKNAAVEE.js → chunk-YJ7YZRVV.js} +1 -1
- package/dist/src/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-S4TFBJ5O.js +0 -339
- package/dist/{chunk-VFBYRR2N.js → chunk-HIIBSYFJ.js} +3 -3
|
@@ -7,24 +7,35 @@ import {
|
|
|
7
7
|
addPusharyHooks,
|
|
8
8
|
addPusharyToolPermissions
|
|
9
9
|
} from "../chunk-CAJZAFVS.js";
|
|
10
|
+
import {
|
|
11
|
+
describeDetection,
|
|
12
|
+
detectAllAgents,
|
|
13
|
+
isDetected
|
|
14
|
+
} from "../chunk-UXXRRXUS.js";
|
|
15
|
+
import {
|
|
16
|
+
renderAgentInstructions,
|
|
17
|
+
renderProjectAgentInstructions,
|
|
18
|
+
writeInstructionBlock
|
|
19
|
+
} from "../chunk-N7XJ4L2W.js";
|
|
10
20
|
import {
|
|
11
21
|
GEMINI_HOOK_BINARY,
|
|
22
|
+
addGeminiHooks,
|
|
23
|
+
addGeminiMcpServer
|
|
24
|
+
} from "../chunk-E2U35RLD.js";
|
|
25
|
+
import {
|
|
12
26
|
addCodexHookTrust,
|
|
13
27
|
addCodexHooks,
|
|
14
28
|
addCodexMcpServer,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
renderProjectAgentInstructions,
|
|
19
|
-
writeInstructionBlock
|
|
20
|
-
} from "../chunk-S4TFBJ5O.js";
|
|
29
|
+
codexConfigToml,
|
|
30
|
+
codexHome
|
|
31
|
+
} from "../chunk-ER657KRJ.js";
|
|
21
32
|
import {
|
|
22
33
|
confirmAppConnection,
|
|
23
34
|
connectDevice,
|
|
24
35
|
connectViaAppPairing,
|
|
25
36
|
printConnectInstructions,
|
|
26
37
|
setHumanStream
|
|
27
|
-
} from "../chunk-
|
|
38
|
+
} from "../chunk-3O27ZSRE.js";
|
|
28
39
|
import "../chunk-3EGEA4KH.js";
|
|
29
40
|
import {
|
|
30
41
|
parseFlags
|
|
@@ -37,11 +48,11 @@ import {
|
|
|
37
48
|
writeFileAtomic,
|
|
38
49
|
writeJsonAtomic,
|
|
39
50
|
writeKey
|
|
40
|
-
} from "../chunk-
|
|
51
|
+
} from "../chunk-247C4RE5.js";
|
|
41
52
|
import {
|
|
42
53
|
checkApiKey,
|
|
43
54
|
describeKeyCheck
|
|
44
|
-
} from "../chunk-
|
|
55
|
+
} from "../chunk-YJ7YZRVV.js";
|
|
45
56
|
import {
|
|
46
57
|
UsageError
|
|
47
58
|
} from "../chunk-7QLSKOSU.js";
|
|
@@ -60,28 +71,38 @@ import {
|
|
|
60
71
|
EXIT,
|
|
61
72
|
getPackageVersion,
|
|
62
73
|
renderCommandHelp
|
|
63
|
-
} from "../chunk-
|
|
74
|
+
} from "../chunk-SP7OZXCQ.js";
|
|
64
75
|
import {
|
|
65
76
|
reportEvent
|
|
66
|
-
} from "../chunk-
|
|
67
|
-
import "../chunk-RN3NOEJF.js";
|
|
77
|
+
} from "../chunk-HIIBSYFJ.js";
|
|
68
78
|
import "../chunk-HNTKTK5B.js";
|
|
69
79
|
import {
|
|
70
80
|
isValidApiKey
|
|
71
81
|
} from "../chunk-DQAN3JQP.js";
|
|
82
|
+
import "../chunk-RN3NOEJF.js";
|
|
72
83
|
import "../chunk-2UMNXADU.js";
|
|
73
84
|
|
|
74
85
|
// bin/pushary-setup.ts
|
|
75
|
-
import { existsSync
|
|
76
|
-
import { join
|
|
77
|
-
import { homedir
|
|
78
|
-
import { execSync as
|
|
86
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, rmSync, renameSync } from "fs";
|
|
87
|
+
import { join, dirname, basename } from "path";
|
|
88
|
+
import { homedir, tmpdir } from "os";
|
|
89
|
+
import { execSync as execSync2 } from "child_process";
|
|
79
90
|
import { checkbox, input, confirm } from "@inquirer/prompts";
|
|
80
91
|
import { fileURLToPath } from "url";
|
|
81
92
|
import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
|
|
82
93
|
|
|
83
94
|
// src/setup/closing.ts
|
|
84
95
|
var ACTIVITY_URL = "pushary.com/dashboard/agent/activity";
|
|
96
|
+
var COMMAND_SURFACE = [
|
|
97
|
+
{ command: "pushary status", summary: "what this machine is connected to" },
|
|
98
|
+
{ command: "pushary mode", summary: "switch between ask, auto and notify-only" },
|
|
99
|
+
{ command: "pushary wait", summary: "block until a pending question is answered" },
|
|
100
|
+
{ command: "pushary stats", summary: "what your agents have been asking" },
|
|
101
|
+
{ command: "pushary claude", summary: "run Claude Code with the Pushary wrapper" },
|
|
102
|
+
{ command: "pushary doctor", summary: "check the install" }
|
|
103
|
+
];
|
|
104
|
+
var SURFACE_COLUMN = Math.max(...COMMAND_SURFACE.map((entry) => entry.command.length)) + 2;
|
|
105
|
+
var renderCommandSurface = () => COMMAND_SURFACE.map((entry) => `${entry.command.padEnd(SURFACE_COLUMN)}${entry.summary}`);
|
|
85
106
|
var nextSteps = (facts, reachable) => {
|
|
86
107
|
const lines = [];
|
|
87
108
|
if (facts.completed.includes("claude_code")) {
|
|
@@ -229,102 +250,18 @@ var parseSetupOptions = (input2) => {
|
|
|
229
250
|
};
|
|
230
251
|
};
|
|
231
252
|
|
|
232
|
-
// src/setup/detect.ts
|
|
233
|
-
import { execSync as execSync2 } from "child_process";
|
|
234
|
-
import { existsSync } from "fs";
|
|
235
|
-
import { homedir } from "os";
|
|
236
|
-
import { join } from "path";
|
|
237
|
-
var whichCommand = () => process.platform === "win32" ? "where" : "which";
|
|
238
|
-
var binaryOnPath = (binary) => {
|
|
239
|
-
try {
|
|
240
|
-
execSync2(`${whichCommand()} ${binary}`, { stdio: "ignore", timeout: 5e3 });
|
|
241
|
-
return true;
|
|
242
|
-
} catch {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
var defaultDeps = { onPath: binaryOnPath, exists: existsSync };
|
|
247
|
-
var detectAgent = (probe, deps = defaultDeps) => {
|
|
248
|
-
const checked = [];
|
|
249
|
-
if (probe.binary) {
|
|
250
|
-
checked.push(`${whichCommand()} ${probe.binary}`);
|
|
251
|
-
if (deps.onPath(probe.binary)) {
|
|
252
|
-
return { kind: "installed", evidence: `${probe.binary} on PATH`, strong: true };
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
for (const path of probe.paths) {
|
|
256
|
-
checked.push(path);
|
|
257
|
-
if (deps.exists(path)) return { kind: "installed", evidence: path, strong: true };
|
|
258
|
-
}
|
|
259
|
-
for (const marker of probe.configMarkers) {
|
|
260
|
-
checked.push(marker);
|
|
261
|
-
if (deps.exists(marker)) return { kind: "installed", evidence: marker, strong: false };
|
|
262
|
-
}
|
|
263
|
-
if (probe.binary === null && probe.paths.length === 0 && probe.configMarkers.length === 0) {
|
|
264
|
-
return { kind: "unknown" };
|
|
265
|
-
}
|
|
266
|
-
return { kind: "not-found", checked };
|
|
267
|
-
};
|
|
268
|
-
var agentProbes = (home = homedir()) => ({
|
|
269
|
-
claude_code: {
|
|
270
|
-
binary: "claude",
|
|
271
|
-
// The native installer puts it here, outside a default non-login PATH.
|
|
272
|
-
paths: [join(home, ".local", "bin", "claude")],
|
|
273
|
-
configMarkers: [join(home, ".claude")]
|
|
274
|
-
},
|
|
275
|
-
codex: {
|
|
276
|
-
binary: "codex",
|
|
277
|
-
paths: [],
|
|
278
|
-
configMarkers: [process.env.CODEX_HOME?.trim() || join(home, ".codex")]
|
|
279
|
-
},
|
|
280
|
-
gemini_cli: {
|
|
281
|
-
binary: "gemini",
|
|
282
|
-
paths: [],
|
|
283
|
-
configMarkers: [join(home, ".gemini")]
|
|
284
|
-
},
|
|
285
|
-
hermes: {
|
|
286
|
-
binary: "hermes",
|
|
287
|
-
paths: [],
|
|
288
|
-
configMarkers: [join(home, ".hermes")]
|
|
289
|
-
},
|
|
290
|
-
cursor: {
|
|
291
|
-
// GUI editor. `cursor` on PATH only exists if the user ran "Install 'cursor'
|
|
292
|
-
// command in PATH" from the command palette, which most never do.
|
|
293
|
-
binary: "cursor",
|
|
294
|
-
paths: process.platform === "darwin" ? ["/Applications/Cursor.app"] : process.platform === "win32" ? [join(process.env.LOCALAPPDATA ?? join(home, "AppData", "Local"), "Programs", "cursor")] : ["/usr/share/cursor", join(home, ".local", "share", "cursor")],
|
|
295
|
-
configMarkers: [join(home, ".cursor")]
|
|
296
|
-
},
|
|
297
|
-
// "Other" is a set of printed instructions for any MCP or HTTP client. There is
|
|
298
|
-
// nothing to detect, and it must never be auto-selected.
|
|
299
|
-
custom: { binary: null, paths: [], configMarkers: [] }
|
|
300
|
-
});
|
|
301
|
-
var detectAllAgents = (deps = defaultDeps, home) => {
|
|
302
|
-
const probes = agentProbes(home);
|
|
303
|
-
return Object.keys(probes).map((agent) => ({
|
|
304
|
-
agent,
|
|
305
|
-
result: detectAgent(probes[agent], deps)
|
|
306
|
-
}));
|
|
307
|
-
};
|
|
308
|
-
var isDetected = (result) => result.kind === "installed";
|
|
309
|
-
var shortenHome = (path, home = homedir()) => home && path.startsWith(home) ? `~${path.slice(home.length)}` : path;
|
|
310
|
-
var describeDetection = (result, home) => {
|
|
311
|
-
if (result.kind !== "installed") return null;
|
|
312
|
-
const evidence = shortenHome(result.evidence, home);
|
|
313
|
-
return result.strong ? evidence : `${evidence}, config only`;
|
|
314
|
-
};
|
|
315
|
-
|
|
316
253
|
// bin/pushary-setup.ts
|
|
317
|
-
var CLAUDE_SETTINGS =
|
|
318
|
-
var CLAUDE_JSON =
|
|
319
|
-
var CURSOR_PLUGIN_DIR =
|
|
320
|
-
var CURSOR_USER_HOOKS =
|
|
321
|
-
var CLAUDE_SKILL_DIR =
|
|
322
|
-
var CODEX_HOME =
|
|
323
|
-
var CODEX_SKILL_DIR =
|
|
324
|
-
var CODEX_AGENTS_MD =
|
|
325
|
-
var GEMINI_SETTINGS =
|
|
326
|
-
var GEMINI_MD =
|
|
327
|
-
var PUSHARY_CONFIG_FILE =
|
|
254
|
+
var CLAUDE_SETTINGS = join(homedir(), ".claude", "settings.json");
|
|
255
|
+
var CLAUDE_JSON = join(homedir(), ".claude.json");
|
|
256
|
+
var CURSOR_PLUGIN_DIR = join(homedir(), ".cursor", "plugins", "local", "pushary");
|
|
257
|
+
var CURSOR_USER_HOOKS = join(homedir(), ".cursor", "hooks.json");
|
|
258
|
+
var CLAUDE_SKILL_DIR = join(homedir(), ".claude", "skills", "pushary");
|
|
259
|
+
var CODEX_HOME = codexHome();
|
|
260
|
+
var CODEX_SKILL_DIR = join(CODEX_HOME, "skills", "pushary");
|
|
261
|
+
var CODEX_AGENTS_MD = join(CODEX_HOME, "AGENTS.md");
|
|
262
|
+
var GEMINI_SETTINGS = join(homedir(), ".gemini", "settings.json");
|
|
263
|
+
var GEMINI_MD = join(homedir(), ".gemini", "GEMINI.md");
|
|
264
|
+
var PUSHARY_CONFIG_FILE = join(homedir(), ".pushary", "config.json");
|
|
328
265
|
var manualSteps = [];
|
|
329
266
|
var noteManual = (step) => {
|
|
330
267
|
manualSteps.push(step);
|
|
@@ -361,7 +298,7 @@ var readKeyFromStdin = async (options) => {
|
|
|
361
298
|
var isInstalled = (command) => {
|
|
362
299
|
const whichCmd = process.platform === "win32" ? "where" : "which";
|
|
363
300
|
try {
|
|
364
|
-
|
|
301
|
+
execSync2(`${whichCmd} ${command}`, { stdio: "ignore", timeout: 5e3 });
|
|
365
302
|
return true;
|
|
366
303
|
} catch {
|
|
367
304
|
return false;
|
|
@@ -386,7 +323,7 @@ var readAgentJson = (filePath) => {
|
|
|
386
323
|
};
|
|
387
324
|
var writeJson = (filePath, data) => {
|
|
388
325
|
const dir = dirname(filePath);
|
|
389
|
-
if (!
|
|
326
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
390
327
|
writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
391
328
|
};
|
|
392
329
|
var readAgentToml = (filePath) => {
|
|
@@ -466,21 +403,21 @@ var fetchSkillContent = async () => {
|
|
|
466
403
|
if (_cachedSkillContent) return _cachedSkillContent;
|
|
467
404
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
468
405
|
const candidates = [
|
|
469
|
-
|
|
470
|
-
|
|
406
|
+
join(__dirname, "..", "..", "data", "SKILL.md"),
|
|
407
|
+
join(__dirname, "..", "data", "SKILL.md")
|
|
471
408
|
];
|
|
472
|
-
const source = candidates.find((path) =>
|
|
409
|
+
const source = candidates.find((path) => existsSync(path));
|
|
473
410
|
if (!source) throw new Error("packaged skill not found");
|
|
474
411
|
_cachedSkillContent = readFileSync(source, "utf-8");
|
|
475
412
|
return _cachedSkillContent;
|
|
476
413
|
};
|
|
477
|
-
var skillsCliInUse = () => isInstalled("skills") ||
|
|
414
|
+
var skillsCliInUse = () => isInstalled("skills") || existsSync(join(homedir(), ".agents", "skills"));
|
|
478
415
|
var installSkill = async (agent, fallbackDir) => {
|
|
479
416
|
await spinner("Installing Pushary skill", async () => {
|
|
480
417
|
if (skillsCliInUse() && installSkillViaSkillsCli(agent)) return;
|
|
481
418
|
const content = await fetchSkillContent();
|
|
482
|
-
if (!
|
|
483
|
-
writeFileSync(
|
|
419
|
+
if (!existsSync(fallbackDir)) mkdirSync(fallbackDir, { recursive: true });
|
|
420
|
+
writeFileSync(join(fallbackDir, "SKILL.md"), content, "utf-8");
|
|
484
421
|
});
|
|
485
422
|
};
|
|
486
423
|
var setupClaudeCode = async (apiKey) => {
|
|
@@ -517,40 +454,40 @@ var IS_WINDOWS = process.platform === "win32";
|
|
|
517
454
|
var resolveHermesPython = () => {
|
|
518
455
|
try {
|
|
519
456
|
const probe = IS_WINDOWS ? "where hermes" : "command -v hermes";
|
|
520
|
-
const launcher =
|
|
457
|
+
const launcher = execSync2(probe, { encoding: "utf-8", stdio: "pipe", timeout: 5e3 }).split("\n")[0].trim();
|
|
521
458
|
if (launcher && !IS_WINDOWS) {
|
|
522
459
|
const shebang = readFileSync(launcher, "utf-8").split("\n", 1)[0];
|
|
523
460
|
if (shebang.startsWith("#!")) {
|
|
524
461
|
const interpreter = shebang.slice(2).trim().split(/\s+/)[0];
|
|
525
|
-
if (interpreter && /python/i.test(interpreter) &&
|
|
462
|
+
if (interpreter && /python/i.test(interpreter) && existsSync(interpreter)) return interpreter;
|
|
526
463
|
}
|
|
527
464
|
}
|
|
528
465
|
} catch {
|
|
529
466
|
}
|
|
530
|
-
const venvRoot =
|
|
531
|
-
const candidates = IS_WINDOWS ? [
|
|
532
|
-
return candidates.find(
|
|
467
|
+
const venvRoot = join(homedir(), ".hermes", "hermes-agent", "venv");
|
|
468
|
+
const candidates = IS_WINDOWS ? [join(venvRoot, "Scripts", "python.exe"), join(venvRoot, "Scripts", "python3.exe")] : [join(venvRoot, "bin", "python3"), join(venvRoot, "bin", "python")];
|
|
469
|
+
return candidates.find(existsSync) ?? null;
|
|
533
470
|
};
|
|
534
471
|
var ensurePip = (python) => {
|
|
535
472
|
try {
|
|
536
|
-
|
|
473
|
+
execSync2(`"${python}" -m pip --version`, { stdio: "ignore", timeout: 15e3 });
|
|
537
474
|
return;
|
|
538
475
|
} catch {
|
|
539
476
|
}
|
|
540
477
|
try {
|
|
541
|
-
|
|
478
|
+
execSync2(`"${python}" -m ensurepip --upgrade`, { stdio: "pipe", timeout: 6e4 });
|
|
542
479
|
} catch {
|
|
543
480
|
}
|
|
544
481
|
};
|
|
545
482
|
var enablePusharyPlugin = (python) => {
|
|
546
483
|
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"] = (e + ["pushary"]) if "pushary" not in e else e; 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"] = (d + ["clarify"]) if "clarify" not in d else d; c["agent"] = a; save_config(c)';
|
|
547
|
-
const scriptPath =
|
|
484
|
+
const scriptPath = join(tmpdir(), `pushary-hermes-${process.pid}.py`);
|
|
548
485
|
try {
|
|
549
486
|
writeFileSync(scriptPath, snippet.split("; ").join("\n"), "utf-8");
|
|
550
|
-
|
|
487
|
+
execSync2(`"${python}" "${scriptPath}"`, { stdio: "pipe", timeout: 15e3 });
|
|
551
488
|
return;
|
|
552
489
|
} catch {
|
|
553
|
-
|
|
490
|
+
execSync2("hermes plugins enable pushary", { stdio: "ignore", timeout: 1e4 });
|
|
554
491
|
} finally {
|
|
555
492
|
try {
|
|
556
493
|
rmSync(scriptPath, { force: true });
|
|
@@ -575,7 +512,7 @@ var setupHermes = async (_apiKey) => {
|
|
|
575
512
|
}
|
|
576
513
|
await spinner("Installing hermes-plugin-pushary into Hermes\u2019 environment", async () => {
|
|
577
514
|
ensurePip(python);
|
|
578
|
-
|
|
515
|
+
execSync2(`"${python}" -m pip install --upgrade hermes-plugin-pushary`, { stdio: "pipe", timeout: 18e4 });
|
|
579
516
|
});
|
|
580
517
|
await spinner("Enabling plugin + routing questions to push", async () => {
|
|
581
518
|
enablePusharyPlugin(python);
|
|
@@ -588,7 +525,7 @@ var setupHermes = async (_apiKey) => {
|
|
|
588
525
|
console.log(` ${dim("\u2022")} Permission gating: set ${bold("PUSHARY_GATE_TOOLS")} to require lock-screen approval for risky tools`);
|
|
589
526
|
console.log(` ${dim("To re-enable terminal prompts:")} remove ${bold("clarify")} from ${dim("agent.disabled_toolsets")} in ~/.hermes/config.yaml`);
|
|
590
527
|
};
|
|
591
|
-
var CODEX_HOOKS_JSON =
|
|
528
|
+
var CODEX_HOOKS_JSON = join(CODEX_HOME, "hooks.json");
|
|
592
529
|
var CODEX_HOOKS_MIN_VERSION = [0, 122, 0];
|
|
593
530
|
var CODEX_TRUST_VERIFIED_MAX = [0, 142, 2];
|
|
594
531
|
var parseCodexVersion = (raw) => {
|
|
@@ -604,7 +541,7 @@ var compareCodexVersion = (a, b) => {
|
|
|
604
541
|
};
|
|
605
542
|
var readCodexVersion = () => {
|
|
606
543
|
try {
|
|
607
|
-
return parseCodexVersion(
|
|
544
|
+
return parseCodexVersion(execSync2("codex --version", { encoding: "utf-8", stdio: "pipe", timeout: 1e4 }));
|
|
608
545
|
} catch {
|
|
609
546
|
return null;
|
|
610
547
|
}
|
|
@@ -655,7 +592,7 @@ var setupCodex = async (apiKey) => {
|
|
|
655
592
|
return "skipped";
|
|
656
593
|
}
|
|
657
594
|
await installGlobally2();
|
|
658
|
-
const codexConfig =
|
|
595
|
+
const codexConfig = codexConfigToml();
|
|
659
596
|
await spinner("Adding Pushary MCP server (key embedded, auto-allowed)", async () => {
|
|
660
597
|
const config = readAgentToml(codexConfig);
|
|
661
598
|
addCodexMcpServer(config, apiKey);
|
|
@@ -731,19 +668,19 @@ var setupCodex = async (apiKey) => {
|
|
|
731
668
|
var resolveBundledPlugin = () => {
|
|
732
669
|
const dir = dirname(fileURLToPath(import.meta.url));
|
|
733
670
|
const candidates = [
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
671
|
+
join(dir, "..", "..", "data", "cursor-plugin"),
|
|
672
|
+
join(dir, "..", "data", "cursor-plugin"),
|
|
673
|
+
join(dir, "..", "..", "..", "cursor-plugin"),
|
|
674
|
+
join(dir, "..", "..", "cursor-plugin")
|
|
738
675
|
];
|
|
739
|
-
return candidates.find((p) =>
|
|
676
|
+
return candidates.find((p) => existsSync(join(p, ".cursor-plugin", "plugin.json"))) ?? null;
|
|
740
677
|
};
|
|
741
678
|
var installCursorUserHooks = (gateScript) => {
|
|
742
|
-
const template = readJson(
|
|
679
|
+
const template = readJson(join(CURSOR_PLUGIN_DIR, "hooks", "hooks.json")).hooks?.beforeShellExecution?.[0];
|
|
743
680
|
if (!template) throw new Error("bundled Cursor hooks.json missing a beforeShellExecution entry");
|
|
744
681
|
const entry = { ...template, command: `node "${gateScript}"` };
|
|
745
682
|
let userHooks = {};
|
|
746
|
-
if (
|
|
683
|
+
if (existsSync(CURSOR_USER_HOOKS)) {
|
|
747
684
|
try {
|
|
748
685
|
userHooks = JSON.parse(readFileSync(CURSOR_USER_HOOKS, "utf-8"));
|
|
749
686
|
} catch {
|
|
@@ -761,8 +698,8 @@ var installCursorUserHooks = (gateScript) => {
|
|
|
761
698
|
writeJson(CURSOR_USER_HOOKS, { ...userHooks, version: userHooks.version ?? 1, hooks });
|
|
762
699
|
};
|
|
763
700
|
var neutralizePluginGate = () => {
|
|
764
|
-
const path =
|
|
765
|
-
if (!
|
|
701
|
+
const path = join(CURSOR_PLUGIN_DIR, "hooks", "hooks.json");
|
|
702
|
+
if (!existsSync(path)) return;
|
|
766
703
|
const data = readJson(path);
|
|
767
704
|
if (data.hooks && "beforeShellExecution" in data.hooks) {
|
|
768
705
|
delete data.hooks.beforeShellExecution;
|
|
@@ -776,7 +713,7 @@ var setupCursor = async (apiKey) => {
|
|
|
776
713
|
const source = resolveBundledPlugin();
|
|
777
714
|
if (!source) throw new Error("bundled Cursor plugin not found in this package");
|
|
778
715
|
await spinner("Installing Pushary plugin", async () => {
|
|
779
|
-
const staging =
|
|
716
|
+
const staging = join(dirname(CURSOR_PLUGIN_DIR), `.pushary-staging-${process.pid}`);
|
|
780
717
|
const backup = `${CURSOR_PLUGIN_DIR}.pushary-backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
|
|
781
718
|
rmSync(staging, { recursive: true, force: true });
|
|
782
719
|
try {
|
|
@@ -784,11 +721,11 @@ var setupCursor = async (apiKey) => {
|
|
|
784
721
|
recursive: true,
|
|
785
722
|
filter: (p) => !["tools", "node_modules", ".git", ".DS_Store"].includes(basename(p))
|
|
786
723
|
});
|
|
787
|
-
const staged = readJsonSafe(
|
|
724
|
+
const staged = readJsonSafe(join(staging, ".cursor-plugin", "plugin.json"));
|
|
788
725
|
if (staged.kind !== "ok") {
|
|
789
726
|
throw new Error("staged Cursor plugin is missing or has an unreadable plugin.json");
|
|
790
727
|
}
|
|
791
|
-
const hadExisting =
|
|
728
|
+
const hadExisting = existsSync(CURSOR_PLUGIN_DIR);
|
|
792
729
|
if (hadExisting) renameSync(CURSOR_PLUGIN_DIR, backup);
|
|
793
730
|
try {
|
|
794
731
|
renameSync(staging, CURSOR_PLUGIN_DIR);
|
|
@@ -802,7 +739,7 @@ var setupCursor = async (apiKey) => {
|
|
|
802
739
|
}
|
|
803
740
|
});
|
|
804
741
|
await spinner("Linking your API key", async () => {
|
|
805
|
-
const mcpPath =
|
|
742
|
+
const mcpPath = join(CURSOR_PLUGIN_DIR, "mcp.json");
|
|
806
743
|
const mcp = readAgentJson(mcpPath);
|
|
807
744
|
const servers = mcp.mcpServers ?? {};
|
|
808
745
|
if (servers.pushary) {
|
|
@@ -812,7 +749,7 @@ var setupCursor = async (apiKey) => {
|
|
|
812
749
|
}
|
|
813
750
|
});
|
|
814
751
|
await spinner("Registering permission gate (~/.cursor/hooks.json)", async () => {
|
|
815
|
-
installCursorUserHooks(
|
|
752
|
+
installCursorUserHooks(join(CURSOR_PLUGIN_DIR, "scripts", "pushary-gate.mjs"));
|
|
816
753
|
neutralizePluginGate();
|
|
817
754
|
});
|
|
818
755
|
console.log();
|
|
@@ -931,8 +868,8 @@ var offerProjectInstructions = async (agents, options) => {
|
|
|
931
868
|
});
|
|
932
869
|
if (!wanted) return;
|
|
933
870
|
for (const target of targets) {
|
|
934
|
-
await spinner(`Writing managed block to ${
|
|
935
|
-
writeInstructionBlock(
|
|
871
|
+
await spinner(`Writing managed block to ${join(process.cwd(), target.file)}`, async () => {
|
|
872
|
+
writeInstructionBlock(join(process.cwd(), target.file), renderProjectAgentInstructions(target.label));
|
|
936
873
|
}, { optional: true });
|
|
937
874
|
}
|
|
938
875
|
console.log(` ${dim("Commit the file to share it. Teammates without a key fall back to the terminal.")}`);
|
|
@@ -1054,11 +991,11 @@ var resolveAgents = async (options) => {
|
|
|
1054
991
|
});
|
|
1055
992
|
};
|
|
1056
993
|
var AGENT_TARGETS = {
|
|
1057
|
-
claude_code: [CLAUDE_JSON, CLAUDE_SETTINGS,
|
|
1058
|
-
codex: [
|
|
994
|
+
claude_code: [CLAUDE_JSON, CLAUDE_SETTINGS, join(CLAUDE_SKILL_DIR, "SKILL.md")],
|
|
995
|
+
codex: [join(CODEX_HOME, "config.toml"), CODEX_HOOKS_JSON, join(CODEX_SKILL_DIR, "SKILL.md"), CODEX_AGENTS_MD],
|
|
1059
996
|
gemini_cli: [GEMINI_SETTINGS, GEMINI_MD],
|
|
1060
997
|
hermes: ["the Hermes virtualenv (pip install pushary-hermes)"],
|
|
1061
|
-
cursor: [
|
|
998
|
+
cursor: [join(CURSOR_PLUGIN_DIR, "mcp.json"), CURSOR_USER_HOOKS],
|
|
1062
999
|
custom: ["nothing (prints connection details only)"]
|
|
1063
1000
|
};
|
|
1064
1001
|
var reportDryRun = (apiKey, agents, keyCheck) => {
|
|
@@ -1305,6 +1242,9 @@ var main = async () => {
|
|
|
1305
1242
|
console.log();
|
|
1306
1243
|
for (const line of closing.next) console.log(` ${line}`);
|
|
1307
1244
|
console.log();
|
|
1245
|
+
console.log(` ${dim("Useful:")}`);
|
|
1246
|
+
for (const line of renderCommandSurface()) console.log(` ${dim(line)}`);
|
|
1247
|
+
console.log();
|
|
1308
1248
|
const exitCode = closing.exitCode;
|
|
1309
1249
|
emitJson(options, {
|
|
1310
1250
|
ok: closing.ok,
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
describeReach,
|
|
4
4
|
fetchChannels,
|
|
5
5
|
reachVerdict
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-3O27ZSRE.js";
|
|
7
7
|
import "../chunk-3EGEA4KH.js";
|
|
8
8
|
import {
|
|
9
9
|
readKeySource
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-247C4RE5.js";
|
|
11
11
|
import {
|
|
12
12
|
checkApiKey,
|
|
13
13
|
describeKeyCheck
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-YJ7YZRVV.js";
|
|
15
15
|
import {
|
|
16
16
|
createIo
|
|
17
17
|
} from "../chunk-TX7KBKT7.js";
|
|
@@ -19,10 +19,10 @@ import "../chunk-7QLSKOSU.js";
|
|
|
19
19
|
import "../chunk-BC3VCZ3E.js";
|
|
20
20
|
import {
|
|
21
21
|
exitOnHelpFlag
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-IIZZYUWK.js";
|
|
23
23
|
import {
|
|
24
24
|
EXIT
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-SP7OZXCQ.js";
|
|
26
26
|
import "../chunk-HNTKTK5B.js";
|
|
27
27
|
import "../chunk-DQAN3JQP.js";
|
|
28
28
|
import "../chunk-2UMNXADU.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleStop
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-RN3NOEJF.js";
|
|
4
|
+
} from "../chunk-HIIBSYFJ.js";
|
|
6
5
|
import "../chunk-HNTKTK5B.js";
|
|
7
6
|
import "../chunk-DQAN3JQP.js";
|
|
7
|
+
import "../chunk-RN3NOEJF.js";
|
|
8
8
|
import "../chunk-2UMNXADU.js";
|
|
9
9
|
|
|
10
10
|
// bin/pushary-stop-hook.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handleStopFailure
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-RN3NOEJF.js";
|
|
4
|
+
} from "../chunk-HIIBSYFJ.js";
|
|
6
5
|
import "../chunk-HNTKTK5B.js";
|
|
7
6
|
import "../chunk-DQAN3JQP.js";
|
|
7
|
+
import "../chunk-RN3NOEJF.js";
|
|
8
8
|
import "../chunk-2UMNXADU.js";
|
|
9
9
|
|
|
10
10
|
// bin/pushary-stopfailure-hook.ts
|