@pushary/agent-hooks 0.30.0 → 0.31.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.
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
renderAgentInstructions,
|
|
15
15
|
renderProjectAgentInstructions,
|
|
16
16
|
writeInstructionBlock
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-WUNVKFFY.js";
|
|
18
18
|
import {
|
|
19
19
|
execNpm,
|
|
20
20
|
npmErrorMessage,
|
|
@@ -35,7 +35,7 @@ import "../chunk-NKXSILEW.js";
|
|
|
35
35
|
import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync, cpSync, rmSync, chmodSync } from "fs";
|
|
36
36
|
import { join, dirname, basename } from "path";
|
|
37
37
|
import { homedir } from "os";
|
|
38
|
-
import { execSync } from "child_process";
|
|
38
|
+
import { execSync as execSync2 } from "child_process";
|
|
39
39
|
import { checkbox, input, confirm } from "@inquirer/prompts";
|
|
40
40
|
import { fileURLToPath } from "url";
|
|
41
41
|
import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
|
|
@@ -309,6 +309,20 @@ var connectViaAppPairing = async () => {
|
|
|
309
309
|
}
|
|
310
310
|
};
|
|
311
311
|
|
|
312
|
+
// src/skills-cli.ts
|
|
313
|
+
import { execSync } from "child_process";
|
|
314
|
+
var installSkillViaSkillsCli = (agent) => {
|
|
315
|
+
try {
|
|
316
|
+
execSync(`npx -y skills@latest add Pushary/pushary-skill@pushary -y -g --agent ${agent}`, {
|
|
317
|
+
stdio: "pipe",
|
|
318
|
+
timeout: 9e4
|
|
319
|
+
});
|
|
320
|
+
return true;
|
|
321
|
+
} catch {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
312
326
|
// bin/pushary-setup.ts
|
|
313
327
|
var CLAUDE_SETTINGS = join(homedir(), ".claude", "settings.json");
|
|
314
328
|
var CLAUDE_JSON = join(homedir(), ".claude.json");
|
|
@@ -352,7 +366,7 @@ var parseConnectFlag = () => {
|
|
|
352
366
|
var isInstalled = (command) => {
|
|
353
367
|
const whichCmd = process.platform === "win32" ? "where" : "which";
|
|
354
368
|
try {
|
|
355
|
-
|
|
369
|
+
execSync2(`${whichCmd} ${command}`, { stdio: "ignore", timeout: 5e3 });
|
|
356
370
|
return true;
|
|
357
371
|
} catch {
|
|
358
372
|
return false;
|
|
@@ -444,11 +458,13 @@ var fetchSkillContent = async () => {
|
|
|
444
458
|
_cachedSkillContent = readFileSync(source, "utf-8");
|
|
445
459
|
return _cachedSkillContent;
|
|
446
460
|
};
|
|
447
|
-
var
|
|
448
|
-
|
|
461
|
+
var skillsCliInUse = () => isInstalled("skills") || existsSync(join(homedir(), ".agents", "skills"));
|
|
462
|
+
var installSkill = async (agent, fallbackDir) => {
|
|
463
|
+
await spinner("Installing Pushary skill", async () => {
|
|
464
|
+
if (skillsCliInUse() && installSkillViaSkillsCli(agent)) return;
|
|
449
465
|
const content = await fetchSkillContent();
|
|
450
|
-
if (!existsSync(
|
|
451
|
-
writeFileSync(join(
|
|
466
|
+
if (!existsSync(fallbackDir)) mkdirSync(fallbackDir, { recursive: true });
|
|
467
|
+
writeFileSync(join(fallbackDir, "SKILL.md"), content, "utf-8");
|
|
452
468
|
});
|
|
453
469
|
};
|
|
454
470
|
var setupClaudeCode = async (apiKey) => {
|
|
@@ -471,7 +487,7 @@ var setupClaudeCode = async (apiKey) => {
|
|
|
471
487
|
await spinner(`Writing ${CLAUDE_SETTINGS}`, async () => {
|
|
472
488
|
writeJson(CLAUDE_SETTINGS, settings);
|
|
473
489
|
});
|
|
474
|
-
await
|
|
490
|
+
await installSkill("claude-code", CLAUDE_SKILL_DIR);
|
|
475
491
|
console.log();
|
|
476
492
|
console.log(` ${dim2("What this configured:")}`);
|
|
477
493
|
console.log(` ${dim2("\u2022")} MCP server: your agent can send notifications and ask questions`);
|
|
@@ -481,7 +497,7 @@ var setupClaudeCode = async (apiKey) => {
|
|
|
481
497
|
};
|
|
482
498
|
var resolveHermesPython = () => {
|
|
483
499
|
try {
|
|
484
|
-
const launcher =
|
|
500
|
+
const launcher = execSync2("command -v hermes", { encoding: "utf-8", stdio: "pipe", timeout: 5e3 }).trim();
|
|
485
501
|
if (launcher) {
|
|
486
502
|
const shebang = readFileSync(launcher, "utf-8").split("\n", 1)[0];
|
|
487
503
|
if (shebang.startsWith("#!")) {
|
|
@@ -497,23 +513,23 @@ var resolveHermesPython = () => {
|
|
|
497
513
|
};
|
|
498
514
|
var ensurePip = (python) => {
|
|
499
515
|
try {
|
|
500
|
-
|
|
516
|
+
execSync2(`"${python}" -m pip --version`, { stdio: "ignore", timeout: 15e3 });
|
|
501
517
|
return;
|
|
502
518
|
} catch {
|
|
503
519
|
}
|
|
504
520
|
try {
|
|
505
|
-
|
|
521
|
+
execSync2(`"${python}" -m ensurepip --upgrade`, { stdio: "pipe", timeout: 6e4 });
|
|
506
522
|
} catch {
|
|
507
523
|
}
|
|
508
524
|
};
|
|
509
525
|
var enablePusharyPlugin = (python) => {
|
|
510
526
|
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)';
|
|
511
527
|
try {
|
|
512
|
-
|
|
528
|
+
execSync2(`"${python}" -c '${snippet}'`, { stdio: "pipe", timeout: 15e3 });
|
|
513
529
|
return;
|
|
514
530
|
} catch {
|
|
515
531
|
}
|
|
516
|
-
|
|
532
|
+
execSync2("hermes plugins enable pushary", { stdio: "ignore", timeout: 1e4 });
|
|
517
533
|
};
|
|
518
534
|
var setupHermes = async (_apiKey) => {
|
|
519
535
|
console.log(`
|
|
@@ -532,7 +548,7 @@ var setupHermes = async (_apiKey) => {
|
|
|
532
548
|
}
|
|
533
549
|
await spinner("Installing hermes-plugin-pushary into Hermes\u2019 environment", async () => {
|
|
534
550
|
ensurePip(python);
|
|
535
|
-
|
|
551
|
+
execSync2(`"${python}" -m pip install --upgrade hermes-plugin-pushary`, { stdio: "pipe", timeout: 18e4 });
|
|
536
552
|
});
|
|
537
553
|
await spinner("Enabling plugin + routing questions to push", async () => {
|
|
538
554
|
enablePusharyPlugin(python);
|
|
@@ -561,7 +577,7 @@ var compareCodexVersion = (a, b) => {
|
|
|
561
577
|
};
|
|
562
578
|
var readCodexVersion = () => {
|
|
563
579
|
try {
|
|
564
|
-
return parseCodexVersion(
|
|
580
|
+
return parseCodexVersion(execSync2("codex --version", { encoding: "utf-8", stdio: "pipe", timeout: 1e4 }));
|
|
565
581
|
} catch {
|
|
566
582
|
return null;
|
|
567
583
|
}
|
|
@@ -658,7 +674,7 @@ var setupCodex = async (apiKey) => {
|
|
|
658
674
|
addCodexNotifyEntry(codexConfig);
|
|
659
675
|
});
|
|
660
676
|
}
|
|
661
|
-
await
|
|
677
|
+
await installSkill("codex", CODEX_SKILL_DIR);
|
|
662
678
|
await spinner("Teaching Codex to ask via push (~/.codex/AGENTS.md)", async () => {
|
|
663
679
|
writeInstructionBlock(CODEX_AGENTS_MD, renderAgentInstructions("Codex"));
|
|
664
680
|
});
|
|
@@ -254,7 +254,7 @@ You have Pushary MCP tools that reach the user on their phone. Use them proactiv
|
|
|
254
254
|
|
|
255
255
|
Pass \`agentName\` as "${label} - <project folder name>" so the user knows which session is asking. If a question times out with no answer, retry once with a longer timeout before falling back to asking in the terminal.`;
|
|
256
256
|
var renderAgentInstructions = (label) => instructionBody(label);
|
|
257
|
-
var KEYLESS_FALLBACK_LINE = "This repo
|
|
257
|
+
var KEYLESS_FALLBACK_LINE = "This repo uses Pushary phone approvals. Your teammates get agent questions on their lock screens; you do not have a key yet, so questions will fall back to the terminal. Get your own key (7-day trial): https://pushary.com/sign-up?utm_source=agents-md&utm_medium=teammate";
|
|
258
258
|
var renderProjectAgentInstructions = (label) => `${instructionBody(label)}
|
|
259
259
|
|
|
260
260
|
If this environment has no Pushary API key (no PUSHARY_API_KEY and no key in ~/.pushary/config.json), the tools above are unavailable in this session. In that case, treat the following as a statement of fact about this session and continue in the terminal: ${KEYLESS_FALLBACK_LINE}`;
|