@pushary/agent-hooks 0.61.0 → 0.62.1

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 +76 -0
  2. package/dist/bin/pushary-claude.js +4 -4
  3. package/dist/bin/pushary-clean.js +82 -35
  4. package/dist/bin/pushary-codex-hook.js +4 -4
  5. package/dist/bin/pushary-codex.js +3 -3
  6. package/dist/bin/pushary-connect.js +7 -6
  7. package/dist/bin/pushary-daemon.js +37 -5
  8. package/dist/bin/pushary-doctor.js +114 -34
  9. package/dist/bin/pushary-gemini-hook.js +4 -4
  10. package/dist/bin/pushary-hook.js +5 -5
  11. package/dist/bin/pushary-login.js +5 -4
  12. package/dist/bin/pushary-logout.js +52 -9
  13. package/dist/bin/pushary-mode.js +4 -4
  14. package/dist/bin/pushary-notification-hook.js +2 -2
  15. package/dist/bin/pushary-permission-denied-hook.js +3 -3
  16. package/dist/bin/pushary-permission-hook.js +3 -3
  17. package/dist/bin/pushary-post-hook.js +2 -2
  18. package/dist/bin/pushary-prompt-hook.js +2 -2
  19. package/dist/bin/pushary-session-end-hook.js +2 -2
  20. package/dist/bin/pushary-session-start-hook.js +2 -2
  21. package/dist/bin/pushary-setup.js +97 -155
  22. package/dist/bin/pushary-stats.js +2 -2
  23. package/dist/bin/pushary-status.js +6 -5
  24. package/dist/bin/pushary-stop-hook.js +2 -2
  25. package/dist/bin/pushary-stopfailure-hook.js +2 -2
  26. package/dist/bin/pushary-suggestions.js +2 -2
  27. package/dist/bin/pushary-upgrade.js +189 -18
  28. package/dist/bin/pushary-wait.js +4 -4
  29. package/dist/bin/pushary.js +1 -1
  30. package/dist/{chunk-GX64YGU3.js → chunk-3O27ZSRE.js} +25 -0
  31. package/dist/{chunk-HI4AGGE6.js → chunk-5SO3CEGJ.js} +4 -4
  32. package/dist/chunk-6MTNS63X.js +55 -0
  33. package/dist/{chunk-B26DNXCA.js → chunk-COC6NPWG.js} +13 -59
  34. package/dist/chunk-E2U35RLD.js +108 -0
  35. package/dist/chunk-ER657KRJ.js +168 -0
  36. package/dist/{chunk-HUJQSP4F.js → chunk-IIZZYUWK.js} +1 -1
  37. package/dist/chunk-N7XJ4L2W.js +79 -0
  38. package/dist/{chunk-R6C4USIV.js → chunk-ONVEYEVR.js} +2 -2
  39. package/dist/{chunk-SML23YOT.js → chunk-SP7OZXCQ.js} +10 -2
  40. package/dist/chunk-UXXRRXUS.js +93 -0
  41. package/dist/{chunk-UKNAAVEE.js → chunk-YJ7YZRVV.js} +1 -1
  42. package/dist/src/index.js +3 -3
  43. package/package.json +1 -1
  44. package/dist/chunk-S4TFBJ5O.js +0 -339
  45. package/dist/{chunk-VFBYRR2N.js → chunk-HIIBSYFJ.js} +3 -3
@@ -2,34 +2,45 @@
2
2
  import {
3
3
  describeWaitLadder
4
4
  } from "../chunk-IIENZE2J.js";
5
+ import {
6
+ detectAllAgents
7
+ } from "../chunk-UXXRRXUS.js";
8
+ import {
9
+ hasInstructionBlock
10
+ } from "../chunk-N7XJ4L2W.js";
5
11
  import {
6
12
  GEMINI_HOOK_BINARY,
13
+ hasGeminiHooks,
14
+ missingGeminiHookEvents
15
+ } from "../chunk-E2U35RLD.js";
16
+ import {
17
+ codexAgentsMd,
7
18
  codexConfigToml,
8
19
  codexHooksJson,
20
+ codexSkillDir,
9
21
  hasCodexHooks,
10
- hasGeminiHooks,
11
- hasInstructionBlock,
12
22
  missingCodexHookEvents,
13
- missingGeminiHookEvents,
14
23
  readCodexMcpAuth,
15
24
  untrustedCodexHookEvents
16
- } from "../chunk-S4TFBJ5O.js";
25
+ } from "../chunk-ER657KRJ.js";
17
26
  import {
18
27
  describeReach,
19
28
  fetchChannels,
20
29
  reachVerdict
21
- } from "../chunk-GX64YGU3.js";
30
+ } from "../chunk-3O27ZSRE.js";
22
31
  import "../chunk-3EGEA4KH.js";
23
32
  import {
24
33
  parseFlags
25
34
  } from "../chunk-N4DA4CJB.js";
26
35
  import {
36
+ keyPrefix,
27
37
  readKeySource
28
- } from "../chunk-B26DNXCA.js";
38
+ } from "../chunk-COC6NPWG.js";
39
+ import "../chunk-6MTNS63X.js";
29
40
  import {
30
41
  checkApiKey,
31
42
  describeKeyCheck
32
- } from "../chunk-UKNAAVEE.js";
43
+ } from "../chunk-YJ7YZRVV.js";
33
44
  import {
34
45
  createIo
35
46
  } from "../chunk-TX7KBKT7.js";
@@ -42,10 +53,11 @@ import {
42
53
  } from "../chunk-MUEW424A.js";
43
54
  import {
44
55
  exitOnHelpFlag
45
- } from "../chunk-HUJQSP4F.js";
56
+ } from "../chunk-IIZZYUWK.js";
46
57
  import {
47
- EXIT
48
- } from "../chunk-SML23YOT.js";
58
+ EXIT,
59
+ getPackageVersion
60
+ } from "../chunk-SP7OZXCQ.js";
49
61
  import {
50
62
  readLedgerSummary
51
63
  } from "../chunk-WLGEY4UX.js";
@@ -54,20 +66,67 @@ import {
54
66
  sendMcpRequest
55
67
  } from "../chunk-HNTKTK5B.js";
56
68
  import "../chunk-DQAN3JQP.js";
69
+ import {
70
+ getMachineId
71
+ } from "../chunk-RN3NOEJF.js";
57
72
  import {
58
73
  getBaseUrl
59
74
  } from "../chunk-2UMNXADU.js";
60
75
 
61
76
  // bin/pushary-doctor.ts
62
- import { existsSync, readFileSync } from "fs";
77
+ import { existsSync, readFileSync, writeFileSync } from "fs";
63
78
  import { join } from "path";
64
- import { homedir } from "os";
79
+ import { homedir as homedir2 } from "os";
65
80
  import { execSync } from "child_process";
66
81
  import { confirm } from "@inquirer/prompts";
67
82
  import { parse as parseTOML } from "smol-toml";
83
+
84
+ // src/diagnostics/bundle.ts
85
+ import { homedir, hostname } from "os";
86
+ var globalVersion = () => {
87
+ try {
88
+ return execNpm("list -g --no-workspaces @pushary/agent-hooks --depth=0", { timeout: 1e4 }).toString().match(/@pushary\/agent-hooks@([\d.]+)/)?.[1] ?? null;
89
+ } catch {
90
+ return null;
91
+ }
92
+ };
93
+ var collectBundle = async (options2 = {}) => {
94
+ const now = options2.now ?? (() => /* @__PURE__ */ new Date());
95
+ const source = readKeySource();
96
+ const identity = options2.identity ?? null;
97
+ return {
98
+ generatedAt: now().toISOString(),
99
+ cliVersion: getPackageVersion(),
100
+ globalVersion: globalVersion(),
101
+ node: process.version,
102
+ platform: process.platform,
103
+ arch: process.arch,
104
+ shell: process.env.SHELL ?? null,
105
+ machineId: getMachineId(),
106
+ keySource: source.kind,
107
+ keyPrefix: source.key ? keyPrefix(source.key) : null,
108
+ // The value of the drift, not the keys: knowing two places disagree is the
109
+ // whole diagnostic, and the keys themselves are what must not travel.
110
+ keyDrift: source.drift !== null,
111
+ identity: identity ? stripWorkspace(identity) : null,
112
+ agents: detectAllAgents().map((entry) => ({ id: entry.agent, detected: entry.result })),
113
+ checks: options2.checks ?? []
114
+ };
115
+ };
116
+ var stripWorkspace = (identity) => {
117
+ const { workspaceId: _workspaceId, ...rest } = identity;
118
+ return rest;
119
+ };
120
+ var KEY_PATTERN = /pk_[A-Za-z0-9_]+\.[A-Za-z0-9_]+/g;
121
+ var homePattern = () => new RegExp(homedir().replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g");
122
+ var redactText = (text) => text.replace(KEY_PATTERN, (match) => `${match.split(".")[0]}.REDACTED`).replace(homePattern(), "~").replace(new RegExp(hostname().replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), "HOST");
123
+ var redact = (bundle) => JSON.parse(redactText(JSON.stringify(bundle)));
124
+ var bundleFileName = (bundle) => `pushary-diagnostics-${bundle.generatedAt.replace(/[:.]/g, "-")}.json`;
125
+
126
+ // bin/pushary-doctor.ts
68
127
  exitOnHelpFlag("doctor");
69
128
  var parseDoctorOptions = (argv) => {
70
- const flags = parseFlags(argv, { bools: ["json", "roundtrip", "no-push", "help", "h"], values: [] });
129
+ const flags = parseFlags(argv, { bools: ["json", "roundtrip", "no-push", "bundle", "help", "h"], values: [] });
71
130
  if (flags.command !== void 0 && flags.command !== "doctor") {
72
131
  throw new UsageError(`doctor takes no positional arguments (got ${flags.command})`);
73
132
  }
@@ -76,7 +135,7 @@ var parseDoctorOptions = (argv) => {
76
135
  if (roundtrip && noPush) {
77
136
  throw new UsageError("--roundtrip needs to send a push, so it cannot be combined with --no-push");
78
137
  }
79
- return { json: flags.bools.has("json"), roundtrip, noPush };
138
+ return { json: flags.bools.has("json"), roundtrip, noPush, bundle: flags.bools.has("bundle") };
80
139
  };
81
140
  var options;
82
141
  try {
@@ -97,9 +156,9 @@ var { bold, dim, green, yellow, red, cyan } = createIo();
97
156
  var pass = green("\u2713");
98
157
  var fail = red("\u2717");
99
158
  var warn = yellow("!");
100
- var CLAUDE_SETTINGS = join(homedir(), ".claude", "settings.json");
101
- var SKILL_PATH = join(homedir(), ".claude", "skills", "pushary", "SKILL.md");
102
- var SHELL_FILES = [".zshrc", ".zprofile", ".bashrc", ".bash_profile"].map((f) => join(homedir(), f));
159
+ var CLAUDE_SETTINGS = join(homedir2(), ".claude", "settings.json");
160
+ var SKILL_PATH = join(homedir2(), ".claude", "skills", "pushary", "SKILL.md");
161
+ var SHELL_FILES = [".zshrc", ".zprofile", ".bashrc", ".bash_profile"].map((f) => join(homedir2(), f));
103
162
  var readJson = (path) => {
104
163
  try {
105
164
  return JSON.parse(readFileSync(path, "utf-8"));
@@ -215,7 +274,7 @@ var main = async () => {
215
274
  break;
216
275
  }
217
276
  }
218
- const CLAUDE_JSON = join(homedir(), ".claude.json");
277
+ const CLAUDE_JSON = join(homedir2(), ".claude.json");
219
278
  const claudeJson = readJson(CLAUDE_JSON);
220
279
  const mcpServers = claudeJson?.mcpServers ?? {};
221
280
  const pusharyServer = mcpServers?.pushary;
@@ -325,13 +384,13 @@ var main = async () => {
325
384
  check(resolves, "Codex: notify handler resolves", resolves ? codexNotifyPath : `not found: ${codexNotifyPath}`);
326
385
  }
327
386
  }
328
- const codexSkillPath = join(homedir(), ".codex", "skills", "pushary", "SKILL.md");
387
+ const codexSkillPath = join(codexSkillDir(), "SKILL.md");
329
388
  check(existsSync(codexSkillPath), "Codex: skill installed");
330
- const codexAgentsMd = join(homedir(), ".codex", "AGENTS.md");
331
- const hasCodexInstructions = hasInstructionBlock(codexAgentsMd);
332
- check(hasCodexInstructions, "Codex: proactive instructions (AGENTS.md)", hasCodexInstructions ? codexAgentsMd : "missing \u2014 re-run setup so Codex asks via push, not the terminal");
389
+ const codexAgentsMd2 = codexAgentsMd();
390
+ const hasCodexInstructions = hasInstructionBlock(codexAgentsMd2);
391
+ check(hasCodexInstructions, "Codex: proactive instructions (AGENTS.md)", hasCodexInstructions ? codexAgentsMd2 : "missing \u2014 re-run setup so Codex asks via push, not the terminal");
333
392
  }
334
- const geminiSettingsPath = join(homedir(), ".gemini", "settings.json");
393
+ const geminiSettingsPath = join(homedir2(), ".gemini", "settings.json");
335
394
  const geminiSettings = readJson(geminiSettingsPath);
336
395
  if (geminiSettings) {
337
396
  const geminiServers = geminiSettings.mcpServers ?? {};
@@ -369,13 +428,13 @@ var main = async () => {
369
428
  } else {
370
429
  check(false, "Gemini CLI: native hooks installed", "no Pushary hooks in ~/.gemini/settings.json \u2014 re-run setup");
371
430
  }
372
- const geminiMd = join(homedir(), ".gemini", "GEMINI.md");
431
+ const geminiMd = join(homedir2(), ".gemini", "GEMINI.md");
373
432
  const hasGeminiInstructions = hasInstructionBlock(geminiMd);
374
433
  check(hasGeminiInstructions, "Gemini CLI: proactive instructions (GEMINI.md)", hasGeminiInstructions ? geminiMd : "missing \u2014 re-run setup so Gemini asks via push, not the terminal");
375
434
  }
376
- const cursorPluginDir = join(homedir(), ".cursor", "plugins", "local", "pushary");
435
+ const cursorPluginDir = join(homedir2(), ".cursor", "plugins", "local", "pushary");
377
436
  if (existsSync(cursorPluginDir)) {
378
- const cursorUserHooks = join(homedir(), ".cursor", "hooks.json");
437
+ const cursorUserHooks = join(homedir2(), ".cursor", "hooks.json");
379
438
  const userHooks = readJson(cursorUserHooks);
380
439
  const gateEntry = userHooks.hooks?.beforeShellExecution?.find(
381
440
  (h) => String(h.command ?? "").includes("pushary-gate")
@@ -399,22 +458,22 @@ var main = async () => {
399
458
  }
400
459
  }
401
460
  check(existsSync(SKILL_PATH), "Skill installed", existsSync(SKILL_PATH) ? SKILL_PATH : "not found");
402
- let globalVersion = "";
461
+ let globalVersion2 = "";
403
462
  try {
404
- globalVersion = execNpm("list -g --no-workspaces @pushary/agent-hooks --depth=0", { timeout: 1e4 }).toString().match(/@pushary\/agent-hooks@([\d.]+)/)?.[1] ?? "";
463
+ globalVersion2 = execNpm("list -g --no-workspaces @pushary/agent-hooks --depth=0", { timeout: 1e4 }).toString().match(/@pushary\/agent-hooks@([\d.]+)/)?.[1] ?? "";
405
464
  } catch {
406
- globalVersion = "";
465
+ globalVersion2 = "";
407
466
  }
408
- check(!!globalVersion, "Global package installed", globalVersion || "not found");
409
- if (globalVersion) {
467
+ check(!!globalVersion2, "Global package installed", globalVersion2 || "not found");
468
+ if (globalVersion2) {
410
469
  try {
411
470
  const res = await fetch("https://registry.npmjs.org/@pushary/agent-hooks/latest", {
412
471
  signal: AbortSignal.timeout(5e3)
413
472
  });
414
473
  const latest = res.ok ? (await res.json()).version ?? "" : "";
415
474
  if (latest) {
416
- const upToDate = latest === globalVersion;
417
- check(upToDate, "Global package up to date", upToDate ? globalVersion : `${globalVersion} installed, ${latest} available \u2014 run npx @pushary/agent-hooks@latest upgrade`);
475
+ const upToDate = latest === globalVersion2;
476
+ check(upToDate, "Global package up to date", upToDate ? globalVersion2 : `${globalVersion2} installed, ${latest} available \u2014 run npx @pushary/agent-hooks@latest upgrade`);
418
477
  }
419
478
  } catch {
420
479
  }
@@ -429,7 +488,7 @@ var main = async () => {
429
488
  }
430
489
  });
431
490
  if (aliasRc) {
432
- if (globalVersion) {
491
+ if (globalVersion2) {
433
492
  check(true, "claude alias \u2192 pushary claude", `set in ${aliasRc.split("/").pop()}`);
434
493
  } else {
435
494
  check(false, "claude alias \u2192 pushary claude", "alias is set but pushary is not installed \u2014 run `unalias claude` (this shell) or reinstall");
@@ -604,6 +663,27 @@ var main = async () => {
604
663
  console.log();
605
664
  const keyExit = keyVerdict && (keyVerdict.kind === "rejected" || keyVerdict.kind === "locked" || keyVerdict.kind === "malformed") ? describeKeyCheck(keyVerdict).exitCode : null;
606
665
  const exitCode = keyExit ?? (failed.length > 0 ? EXIT.PROBLEMS_FOUND : EXIT.OK);
666
+ if (options.bundle) {
667
+ try {
668
+ const bundle = redact(
669
+ await collectBundle({
670
+ identity: keyVerdict?.kind === "ok" ? keyVerdict.identity : null,
671
+ checks: results.map((r) => ({ id: r.label, ok: r.passed, detail: r.detail ?? "" }))
672
+ })
673
+ );
674
+ const target = join(process.cwd(), bundleFileName(bundle));
675
+ writeFileSync(target, `${JSON.stringify(bundle, null, 2)}
676
+ `, "utf-8");
677
+ const say = options.json ? process.stderr : process.stdout;
678
+ say.write(`
679
+ Diagnostics written to ${target}
680
+ `);
681
+ say.write(" Keys, your home directory and this machine name are redacted. Read it before sharing.\n\n");
682
+ } catch (err) {
683
+ process.stderr.write(` ! could not write the diagnostics file: ${err instanceof Error ? err.message : String(err)}
684
+ `);
685
+ }
686
+ }
607
687
  if (options.json) {
608
688
  process.stdout.write(`${JSON.stringify({
609
689
  ok: exitCode === EXIT.OK,
@@ -23,10 +23,7 @@ import {
23
23
  savePendingQuestion,
24
24
  sendNotification,
25
25
  waitForAnswer
26
- } from "../chunk-VFBYRR2N.js";
27
- import {
28
- getMachineId
29
- } from "../chunk-RN3NOEJF.js";
26
+ } from "../chunk-HIIBSYFJ.js";
30
27
  import {
31
28
  isGatingMoment,
32
29
  recordKeylessMoment
@@ -38,6 +35,9 @@ import {
38
35
  hookWaitClamped,
39
36
  hookWaitDeadline
40
37
  } from "../chunk-DQAN3JQP.js";
38
+ import {
39
+ getMachineId
40
+ } from "../chunk-RN3NOEJF.js";
41
41
  import {
42
42
  getApiKey
43
43
  } from "../chunk-2UMNXADU.js";
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePreToolUse
4
- } from "../chunk-HI4AGGE6.js";
4
+ } from "../chunk-5SO3CEGJ.js";
5
5
  import "../chunk-CAJZAFVS.js";
6
6
  import {
7
7
  exitOnHelpFlag
8
- } from "../chunk-HUJQSP4F.js";
9
- import "../chunk-SML23YOT.js";
8
+ } from "../chunk-IIZZYUWK.js";
9
+ import "../chunk-SP7OZXCQ.js";
10
10
  import "../chunk-YHG74UFF.js";
11
- import "../chunk-VFBYRR2N.js";
12
- import "../chunk-RN3NOEJF.js";
11
+ import "../chunk-HIIBSYFJ.js";
13
12
  import "../chunk-WLGEY4UX.js";
14
13
  import "../chunk-HNTKTK5B.js";
15
14
  import "../chunk-DQAN3JQP.js";
15
+ import "../chunk-RN3NOEJF.js";
16
16
  import "../chunk-2UMNXADU.js";
17
17
 
18
18
  // bin/pushary-hook.ts
@@ -9,11 +9,12 @@ import {
9
9
  import {
10
10
  readKeySource,
11
11
  writeKey
12
- } from "../chunk-B26DNXCA.js";
12
+ } from "../chunk-COC6NPWG.js";
13
+ import "../chunk-6MTNS63X.js";
13
14
  import {
14
15
  checkApiKey,
15
16
  describeKeyCheck
16
- } from "../chunk-UKNAAVEE.js";
17
+ } from "../chunk-YJ7YZRVV.js";
17
18
  import {
18
19
  createIo
19
20
  } from "../chunk-TX7KBKT7.js";
@@ -23,11 +24,11 @@ import {
23
24
  import "../chunk-BC3VCZ3E.js";
24
25
  import {
25
26
  exitOnHelpFlag
26
- } from "../chunk-HUJQSP4F.js";
27
+ } from "../chunk-IIZZYUWK.js";
27
28
  import {
28
29
  EXIT,
29
30
  getPackageVersion
30
- } from "../chunk-SML23YOT.js";
31
+ } from "../chunk-SP7OZXCQ.js";
31
32
  import {
32
33
  isValidApiKey
33
34
  } from "../chunk-DQAN3JQP.js";
@@ -1,11 +1,15 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ codexConfigToml
4
+ } from "../chunk-ER657KRJ.js";
2
5
  import {
3
6
  parseFlags
4
7
  } from "../chunk-N4DA4CJB.js";
5
8
  import {
6
9
  clearKey,
7
10
  readKeySource
8
- } from "../chunk-B26DNXCA.js";
11
+ } from "../chunk-COC6NPWG.js";
12
+ import "../chunk-6MTNS63X.js";
9
13
  import {
10
14
  createIo
11
15
  } from "../chunk-TX7KBKT7.js";
@@ -15,11 +19,14 @@ import {
15
19
  import "../chunk-BC3VCZ3E.js";
16
20
  import {
17
21
  exitOnHelpFlag
18
- } from "../chunk-HUJQSP4F.js";
22
+ } from "../chunk-IIZZYUWK.js";
19
23
  import {
20
24
  EXIT
21
- } from "../chunk-SML23YOT.js";
22
- import "../chunk-2UMNXADU.js";
25
+ } from "../chunk-SP7OZXCQ.js";
26
+ import "../chunk-DQAN3JQP.js";
27
+ import {
28
+ getBaseUrl
29
+ } from "../chunk-2UMNXADU.js";
23
30
 
24
31
  // bin/pushary-logout.ts
25
32
  import { existsSync } from "fs";
@@ -27,11 +34,11 @@ import { homedir } from "os";
27
34
  import { join } from "path";
28
35
  exitOnHelpFlag("logout");
29
36
  var parseLogoutOptions = (argv) => {
30
- const flags = parseFlags(argv, { bools: ["json", "help", "h"], values: [] });
37
+ const flags = parseFlags(argv, { bools: ["json", "revoke", "help", "h"], values: [] });
31
38
  if (flags.command !== void 0 && flags.command !== "logout") {
32
39
  throw new UsageError(`logout takes no positional arguments (got ${flags.command})`);
33
40
  }
34
- return { json: flags.bools.has("json") };
41
+ return { json: flags.bools.has("json"), revoke: flags.bools.has("revoke") };
35
42
  };
36
43
  var options;
37
44
  try {
@@ -47,12 +54,34 @@ var say = options.json ? (line) => process.stderr.write(`${line}
47
54
  `);
48
55
  var AGENT_CONFIGS = [
49
56
  { label: "Claude Code", path: join(homedir(), ".claude.json") },
50
- { label: "Codex", path: join(process.env.CODEX_HOME ?? join(homedir(), ".codex"), "config.toml") },
57
+ { label: "Codex", path: codexConfigToml() },
51
58
  { label: "Gemini CLI", path: join(homedir(), ".gemini", "settings.json") },
52
59
  { label: "Cursor", path: join(homedir(), ".cursor", "mcp.json") }
53
60
  ];
54
- var main = () => {
61
+ var revokeRemotely = async (apiKey) => {
62
+ try {
63
+ const res = await fetch(`${getBaseUrl()}/api/v1/server/keys/self/revoke`, {
64
+ method: "POST",
65
+ headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
66
+ signal: AbortSignal.timeout(1e4)
67
+ });
68
+ if (res.status === 401) return { ok: true, detail: "the server had already stopped accepting it" };
69
+ if (!res.ok) return { ok: false, detail: `the server answered ${res.status}` };
70
+ return { ok: true, detail: "revoked server-side" };
71
+ } catch (err) {
72
+ return { ok: false, detail: err instanceof Error ? err.message : "network error" };
73
+ }
74
+ };
75
+ var main = async () => {
55
76
  const before = readKeySource();
77
+ let revoked = null;
78
+ if (options.revoke) {
79
+ if (before.key) {
80
+ revoked = await revokeRemotely(before.key);
81
+ } else {
82
+ revoked = { ok: false, detail: "no key was stored here, so there was nothing to revoke" };
83
+ }
84
+ }
56
85
  const result = clearKey();
57
86
  const remaining = AGENT_CONFIGS.filter((entry) => existsSync(entry.path));
58
87
  say("");
@@ -65,6 +94,15 @@ var main = () => {
65
94
  say(` ${dim(`Commented out ${result.rcLinesDisabled} export line in ${result.rcPath}`)}`);
66
95
  }
67
96
  }
97
+ if (revoked) {
98
+ say("");
99
+ if (revoked.ok) {
100
+ say(` ${green("\u2713")} Key ${revoked.detail}. It will not work anywhere else either.`);
101
+ } else {
102
+ say(` ${yellow("!")} Could not revoke the key server-side: ${revoked.detail}`);
103
+ say(` ${dim("It is still valid. Revoke it at")} ${cyan("pushary.com/dashboard/agent/settings")}`);
104
+ }
105
+ }
68
106
  if (before.kind === "env") {
69
107
  say("");
70
108
  say(` ${yellow("!")} PUSHARY_API_KEY is set in this shell, and a child process cannot unset it.`);
@@ -89,6 +127,7 @@ var main = () => {
89
127
  rcPath: result.rcPath,
90
128
  rcLinesDisabled: result.rcLinesDisabled,
91
129
  envStillSet: before.kind === "env",
130
+ revoked: revoked === null ? null : revoked.ok,
92
131
  agentConfigsRetainingKey: remaining.map((entry) => entry.path)
93
132
  },
94
133
  null,
@@ -99,4 +138,8 @@ var main = () => {
99
138
  }
100
139
  process.exit(EXIT.OK);
101
140
  };
102
- main();
141
+ main().catch((err) => {
142
+ process.stderr.write(` ! logout failed: ${err instanceof Error ? err.message : String(err)}
143
+ `);
144
+ process.exit(EXIT.FAILED);
145
+ });
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  exitOnFailedResponse
4
- } from "../chunk-R6C4USIV.js";
5
- import "../chunk-UKNAAVEE.js";
4
+ } from "../chunk-ONVEYEVR.js";
5
+ import "../chunk-YJ7YZRVV.js";
6
6
  import {
7
7
  createIo
8
8
  } from "../chunk-TX7KBKT7.js";
9
9
  import "../chunk-7QLSKOSU.js";
10
10
  import {
11
11
  exitOnHelpFlag
12
- } from "../chunk-HUJQSP4F.js";
12
+ } from "../chunk-IIZZYUWK.js";
13
13
  import {
14
14
  EXIT
15
- } from "../chunk-SML23YOT.js";
15
+ } from "../chunk-SP7OZXCQ.js";
16
16
  import "../chunk-DQAN3JQP.js";
17
17
  import {
18
18
  getApiKey,
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleNotification
4
- } from "../chunk-VFBYRR2N.js";
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-notification-hook.ts
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePermissionDenied
4
- } from "../chunk-HI4AGGE6.js";
4
+ } from "../chunk-5SO3CEGJ.js";
5
5
  import "../chunk-CAJZAFVS.js";
6
6
  import "../chunk-YHG74UFF.js";
7
- import "../chunk-VFBYRR2N.js";
8
- import "../chunk-RN3NOEJF.js";
7
+ import "../chunk-HIIBSYFJ.js";
9
8
  import "../chunk-WLGEY4UX.js";
10
9
  import "../chunk-HNTKTK5B.js";
11
10
  import "../chunk-DQAN3JQP.js";
11
+ import "../chunk-RN3NOEJF.js";
12
12
  import "../chunk-2UMNXADU.js";
13
13
 
14
14
  // bin/pushary-permission-denied-hook.ts
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePermissionRequest
4
- } from "../chunk-HI4AGGE6.js";
4
+ } from "../chunk-5SO3CEGJ.js";
5
5
  import "../chunk-CAJZAFVS.js";
6
6
  import "../chunk-YHG74UFF.js";
7
- import "../chunk-VFBYRR2N.js";
8
- import "../chunk-RN3NOEJF.js";
7
+ import "../chunk-HIIBSYFJ.js";
9
8
  import "../chunk-WLGEY4UX.js";
10
9
  import "../chunk-HNTKTK5B.js";
11
10
  import "../chunk-DQAN3JQP.js";
11
+ import "../chunk-RN3NOEJF.js";
12
12
  import "../chunk-2UMNXADU.js";
13
13
 
14
14
  // bin/pushary-permission-hook.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePostToolUse
4
- } from "../chunk-VFBYRR2N.js";
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-post-hook.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleUserPrompt
4
- } from "../chunk-VFBYRR2N.js";
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-prompt-hook.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionEnd
4
- } from "../chunk-VFBYRR2N.js";
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-session-end-hook.ts
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionStart
4
- } from "../chunk-VFBYRR2N.js";
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-session-start-hook.ts