@pushary/agent-hooks 0.63.2 → 0.64.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 CHANGED
@@ -1,5 +1,49 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.64.0
4
+
5
+ ### A typo on `--dry-run` ran a real clean
6
+
7
+ `pushary clean --yes --dryrun`, one missing hyphen, silently dropped the flag it
8
+ did not recognise and performed a full destructive clean: the stored key, the
9
+ Cursor plugin, every agent config, and the global package itself. It printed
10
+ "Clean complete." with the past tense throughout and exited `0`. The typo most
11
+ worth catching was the one on the flag that means "change nothing", sitting next
12
+ to the flag that means "do not ask me".
13
+
14
+ `clean` now rejects a flag it does not know and exits `2` before removing
15
+ anything. `--dry-run`, `--yes` and `-y` are unchanged.
16
+
17
+ ### Setup reuses the key this machine already has
18
+
19
+ `setup` read `PUSHARY_API_KEY` and never `~/.pushary/config.json`, so the key
20
+ `pushary login` had just written was invisible to it. `login` followed by `setup`
21
+ in the same shell ran a second browser login and minted a second key, and a
22
+ machine with no terminal that had been set up by `login` exited "no API key" with
23
+ a working key sitting on disk. The shell export made it work in a *new* shell,
24
+ which is what hid it.
25
+
26
+ Setup now reads the stored key, verifies it, and uses it. A key the server no
27
+ longer recognises falls through to a fresh sign-in rather than dead-ending, and a
28
+ server it cannot reach keeps the key rather than discarding it.
29
+
30
+ ### The Pushary app is the default connect path
31
+
32
+ An unflagged `setup` now pairs the app instead of sending you to the browser
33
+ subscribe page. `--connect browser` is the fallback for a machine with no app,
34
+ `--connect web` is the legacy page and keeps working exactly as before, and
35
+ `--connect none` skips the phone step like `--skip-phone`. `auto` and `pwa` are
36
+ accepted as input spellings.
37
+
38
+ Pairing only happens when there is a terminal to show the QR to and no usable key
39
+ already on the machine, so re-running setup to add an agent no longer asks you to
40
+ scan anything, and no longer mints a key you did not ask for. Typing
41
+ `--connect app` explicitly still pairs every time.
42
+
43
+ When pairing does not complete, setup now names the two ways to finish without
44
+ the app rather than only inviting you to try the QR again.
45
+
46
+
3
47
  ## 0.63.2
4
48
 
5
49
  ### Setup reports what happened, not only that it worked
@@ -29,15 +29,21 @@ import {
29
29
  import {
30
30
  removeClaudeAlias
31
31
  } from "../chunk-BC3VCZ3E.js";
32
+ import {
33
+ rejectUnknownFlags
34
+ } from "../chunk-GMXKITVA.js";
32
35
  import {
33
36
  execNpm
34
37
  } from "../chunk-MUEW424A.js";
35
38
  import {
36
39
  exitOnHelpFlag
37
- } from "../chunk-VYD27DKZ.js";
38
- import "../chunk-PPTC2QDB.js";
40
+ } from "../chunk-ATP6UQPH.js";
41
+ import "../chunk-JGH37QRB.js";
42
+ import "../chunk-7QLSKOSU.js";
39
43
  import "../chunk-DQAN3JQP.js";
40
- import "../chunk-KZERVKTD.js";
44
+ import {
45
+ EXIT
46
+ } from "../chunk-KZERVKTD.js";
41
47
 
42
48
  // bin/pushary-clean.ts
43
49
  import { existsSync, readFileSync, copyFileSync, readdirSync } from "fs";
@@ -149,6 +155,16 @@ var main = async () => {
149
155
  console.log(` ${bold("Pushary Clean")}`);
150
156
  console.log(` ${dim("Removes all Pushary configuration")}`);
151
157
  console.log();
158
+ try {
159
+ rejectUnknownFlags(
160
+ process.argv.slice(2).filter((a) => a !== "clean"),
161
+ ["--dry-run", "--yes", "-y", "--help", "-h"]
162
+ );
163
+ } catch (err) {
164
+ process.stderr.write(` ! ${err instanceof Error ? err.message : String(err)}
165
+ `);
166
+ process.exit(EXIT.USAGE);
167
+ }
152
168
  dryRun = process.argv.includes("--dry-run");
153
169
  if (dryRun) {
154
170
  console.log(` ${bold("Dry run")} ${dim("- nothing will be changed")}`);
@@ -10,7 +10,7 @@ import {
10
10
  import "../chunk-3EGEA4KH.js";
11
11
  import {
12
12
  readKeySource
13
- } from "../chunk-COC6NPWG.js";
13
+ } from "../chunk-NHKWU7MN.js";
14
14
  import "../chunk-6MTNS63X.js";
15
15
  import {
16
16
  checkApiKey
@@ -18,14 +18,14 @@ import {
18
18
  import {
19
19
  createIo
20
20
  } from "../chunk-TX7KBKT7.js";
21
+ import "../chunk-BC3VCZ3E.js";
21
22
  import {
22
23
  parseFlags
23
24
  } from "../chunk-GMXKITVA.js";
24
- import "../chunk-BC3VCZ3E.js";
25
25
  import {
26
26
  exitOnHelpFlag
27
- } from "../chunk-VYD27DKZ.js";
28
- import "../chunk-PPTC2QDB.js";
27
+ } from "../chunk-ATP6UQPH.js";
28
+ import "../chunk-JGH37QRB.js";
29
29
  import "../chunk-BSZYIAZL.js";
30
30
  import "../chunk-SAF6HGAA.js";
31
31
  import {
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  HEARTBEAT_INTERVAL_MS,
4
4
  sendHeartbeat
5
- } from "../chunk-R22IAMSS.js";
5
+ } from "../chunk-YZT2CBC3.js";
6
6
  import {
7
7
  spawnClaude
8
8
  } from "../chunk-XHKBHWLX.js";
@@ -11,8 +11,8 @@ import {
11
11
  } from "../chunk-MUEW424A.js";
12
12
  import {
13
13
  exitOnHelpFlag
14
- } from "../chunk-VYD27DKZ.js";
15
- import "../chunk-PPTC2QDB.js";
14
+ } from "../chunk-ATP6UQPH.js";
15
+ import "../chunk-JGH37QRB.js";
16
16
  import {
17
17
  getMachineId
18
18
  } from "../chunk-RN3NOEJF.js";
@@ -39,7 +39,7 @@ import "../chunk-3EGEA4KH.js";
39
39
  import {
40
40
  keyPrefix,
41
41
  readKeySource
42
- } from "../chunk-COC6NPWG.js";
42
+ } from "../chunk-NHKWU7MN.js";
43
43
  import "../chunk-6MTNS63X.js";
44
44
  import {
45
45
  checkApiKey,
@@ -48,19 +48,19 @@ import {
48
48
  import {
49
49
  createIo
50
50
  } from "../chunk-TX7KBKT7.js";
51
+ import "../chunk-BC3VCZ3E.js";
51
52
  import {
52
53
  parseFlags
53
54
  } from "../chunk-GMXKITVA.js";
54
- import "../chunk-BC3VCZ3E.js";
55
55
  import {
56
56
  execNpm
57
57
  } from "../chunk-MUEW424A.js";
58
58
  import {
59
59
  exitOnHelpFlag
60
- } from "../chunk-VYD27DKZ.js";
60
+ } from "../chunk-ATP6UQPH.js";
61
61
  import {
62
62
  getPackageVersion
63
- } from "../chunk-PPTC2QDB.js";
63
+ } from "../chunk-JGH37QRB.js";
64
64
  import {
65
65
  readLedgerSummary
66
66
  } from "../chunk-WLGEY4UX.js";
@@ -5,8 +5,8 @@ import {
5
5
  import "../chunk-CAJZAFVS.js";
6
6
  import {
7
7
  exitOnHelpFlag
8
- } from "../chunk-VYD27DKZ.js";
9
- import "../chunk-PPTC2QDB.js";
8
+ } from "../chunk-ATP6UQPH.js";
9
+ import "../chunk-JGH37QRB.js";
10
10
  import "../chunk-YHG74UFF.js";
11
11
  import "../chunk-5ZDYDU2Q.js";
12
12
  import "../chunk-WLGEY4UX.js";
@@ -6,7 +6,7 @@ import "../chunk-3EGEA4KH.js";
6
6
  import {
7
7
  readKeySource,
8
8
  writeKey
9
- } from "../chunk-COC6NPWG.js";
9
+ } from "../chunk-NHKWU7MN.js";
10
10
  import "../chunk-6MTNS63X.js";
11
11
  import {
12
12
  checkApiKey,
@@ -15,16 +15,16 @@ import {
15
15
  import {
16
16
  createIo
17
17
  } from "../chunk-TX7KBKT7.js";
18
+ import "../chunk-BC3VCZ3E.js";
18
19
  import {
19
20
  parseFlags
20
21
  } from "../chunk-GMXKITVA.js";
21
- import "../chunk-BC3VCZ3E.js";
22
22
  import {
23
23
  exitOnHelpFlag
24
- } from "../chunk-VYD27DKZ.js";
24
+ } from "../chunk-ATP6UQPH.js";
25
25
  import {
26
26
  getPackageVersion
27
- } from "../chunk-PPTC2QDB.js";
27
+ } from "../chunk-JGH37QRB.js";
28
28
  import "../chunk-SAF6HGAA.js";
29
29
  import {
30
30
  UsageError
@@ -8,19 +8,19 @@ import {
8
8
  import {
9
9
  clearKey,
10
10
  readKeySource
11
- } from "../chunk-COC6NPWG.js";
11
+ } from "../chunk-NHKWU7MN.js";
12
12
  import "../chunk-6MTNS63X.js";
13
13
  import {
14
14
  createIo
15
15
  } from "../chunk-TX7KBKT7.js";
16
+ import "../chunk-BC3VCZ3E.js";
16
17
  import {
17
18
  parseFlags
18
19
  } from "../chunk-GMXKITVA.js";
19
- import "../chunk-BC3VCZ3E.js";
20
20
  import {
21
21
  exitOnHelpFlag
22
- } from "../chunk-VYD27DKZ.js";
23
- import "../chunk-PPTC2QDB.js";
22
+ } from "../chunk-ATP6UQPH.js";
23
+ import "../chunk-JGH37QRB.js";
24
24
  import {
25
25
  UsageError
26
26
  } from "../chunk-7QLSKOSU.js";
@@ -11,8 +11,8 @@ import {
11
11
  } from "../chunk-GMXKITVA.js";
12
12
  import {
13
13
  exitOnHelpFlag
14
- } from "../chunk-VYD27DKZ.js";
15
- import "../chunk-PPTC2QDB.js";
14
+ } from "../chunk-ATP6UQPH.js";
15
+ import "../chunk-JGH37QRB.js";
16
16
  import "../chunk-SAF6HGAA.js";
17
17
  import {
18
18
  UsageError
@@ -51,9 +51,10 @@ import {
51
51
  KEY_FILE_MODE,
52
52
  exportLine,
53
53
  keyPrefix,
54
+ readConfigFileKey,
54
55
  readKeySource,
55
56
  writeKey
56
- } from "../chunk-COC6NPWG.js";
57
+ } from "../chunk-NHKWU7MN.js";
57
58
  import {
58
59
  backupFile,
59
60
  readJsonSafe,
@@ -64,13 +65,13 @@ import {
64
65
  checkApiKey,
65
66
  describeKeyCheck
66
67
  } from "../chunk-G4TARJAY.js";
67
- import {
68
- parseFlags
69
- } from "../chunk-GMXKITVA.js";
70
68
  import {
71
69
  installClaudeAlias,
72
70
  resolveShellRc
73
71
  } from "../chunk-BC3VCZ3E.js";
72
+ import {
73
+ parseFlags
74
+ } from "../chunk-GMXKITVA.js";
74
75
  import {
75
76
  installGlobally,
76
77
  npmErrorMessage,
@@ -82,7 +83,7 @@ import {
82
83
  getPackageVersion,
83
84
  isNewerVersion,
84
85
  renderCommandHelp
85
- } from "../chunk-PPTC2QDB.js";
86
+ } from "../chunk-JGH37QRB.js";
86
87
  import {
87
88
  reportEvent
88
89
  } from "../chunk-5ZDYDU2Q.js";
@@ -234,6 +235,14 @@ var reportSetupOutcome = async (outcome) => {
234
235
 
235
236
  // src/setup/options.ts
236
237
  var AGENT_CHOICES = ["claude_code", "codex", "gemini_cli", "hermes", "cursor", "custom"];
238
+ var CONNECT_MODES = ["app", "browser", "web", "none"];
239
+ var CONNECT_ALIASES = { auto: "app", pwa: "web" };
240
+ var parseConnectMode = (raw) => {
241
+ const value = raw.trim().toLowerCase();
242
+ if (Object.hasOwn(CONNECT_ALIASES, value)) return CONNECT_ALIASES[value];
243
+ if (CONNECT_MODES.includes(value)) return value;
244
+ throw new UsageError(`--connect must be one of: ${CONNECT_MODES.join(", ")} (got ${raw})`);
245
+ };
237
246
  var SETUP_FLAGS = {
238
247
  bools: ["key-stdin", "skip-phone", "yes", "y", "json", "dry-run", "help", "h"],
239
248
  values: ["key", "connect", "agents"]
@@ -272,18 +281,19 @@ var parseSetupOptions = (input2) => {
272
281
  const agentsFlag = flags.values.get("agents");
273
282
  const agents = parseAgentSelection(agentsFlag, yes);
274
283
  const connectRaw = flags.values.get("connect");
275
- if (connectRaw !== void 0 && connectRaw !== "web" && connectRaw !== "app") {
276
- throw new UsageError(`--connect must be one of: web, app (got ${connectRaw})`);
277
- }
284
+ const connectMode = connectRaw === void 0 ? "app" : parseConnectMode(connectRaw);
278
285
  const key = flags.values.get("key")?.trim() || null;
279
286
  const keyStdin = flags.bools.has("key-stdin");
280
287
  if (key && keyStdin) {
281
288
  throw new UsageError("Pass either --key or --key-stdin, not both");
282
289
  }
283
290
  return {
284
- connectMode: connectRaw === "app" ? "app" : "web",
291
+ connectMode,
285
292
  connectExplicit: connectRaw !== void 0,
286
- skipPhone: flags.bools.has("skip-phone"),
293
+ // `--connect none` and `--skip-phone` are the same instruction, so they
294
+ // resolve to the same field rather than being checked separately at the two
295
+ // call sites that would inevitably drift apart.
296
+ skipPhone: flags.bools.has("skip-phone") || connectMode === "none",
287
297
  // Anything that means "there is nobody to answer a prompt". A non-TTY stdin
288
298
  // is included because that is the case that used to hang: it is better to
289
299
  // take the defaults and say so than to wait forever for a keypress.
@@ -942,14 +952,18 @@ var offerClaudeAlias = async (options) => {
942
952
  console.log(` ${check} ${dim("The")} ${cyan("claude")} ${dim("alias is already set.")}`);
943
953
  }
944
954
  };
945
- var verifyKeyOrExit = async (apiKey, options) => {
946
- const live = process.stdout.isTTY === true && !options.json;
955
+ var verifyKeyOrExit = async (apiKey, options, precomputed) => {
956
+ const live = process.stdout.isTTY === true && !options.json && precomputed === void 0;
947
957
  if (live) writeHuman(` ${dim("...")} Verifying your key with pushary.com`);
948
958
  let result;
949
- try {
950
- result = await checkApiKey(apiKey);
951
- } catch (err) {
952
- result = { kind: "unreachable", detail: formatError(err) };
959
+ if (precomputed !== void 0) {
960
+ result = precomputed;
961
+ } else {
962
+ try {
963
+ result = await checkApiKey(apiKey);
964
+ } catch (err) {
965
+ result = { kind: "unreachable", detail: formatError(err) };
966
+ }
953
967
  }
954
968
  if (live) writeHuman("\r\x1B[2K");
955
969
  const report = describeKeyCheck(result);
@@ -968,6 +982,15 @@ var verifyKeyOrExit = async (apiKey, options) => {
968
982
  }
969
983
  return result;
970
984
  };
985
+ var usableStoredKey = async (apiKey) => {
986
+ let result;
987
+ try {
988
+ result = await checkApiKey(apiKey);
989
+ } catch (err) {
990
+ result = { kind: "unreachable", detail: formatError(err) };
991
+ }
992
+ return result.kind === "rejected" || result.kind === "malformed" ? null : result;
993
+ };
971
994
  var AGENT_NAMES = {
972
995
  claude_code: "Claude Code",
973
996
  codex: "Codex",
@@ -1108,20 +1131,47 @@ var main = async () => {
1108
1131
  const envKey = process.env.PUSHARY_API_KEY?.trim();
1109
1132
  let trimmedKey;
1110
1133
  let keyFromPairing = false;
1134
+ const storedKey = readConfigFileKey();
1135
+ const pairingRequested = connectMode === "app" && options.connectExplicit && !options.skipPhone;
1136
+ const storedCheck = !(flagKey && isValidApiKey(flagKey)) && !pairingRequested && !(envKey && isValidApiKey(envKey)) && storedKey !== null && isValidApiKey(storedKey) ? await usableStoredKey(storedKey) : null;
1137
+ let storedKeyCheck = null;
1111
1138
  if (flagKey && isValidApiKey(flagKey)) {
1112
1139
  const masked = `${flagKey.slice(0, 8)}...${flagKey.slice(-4)}`;
1113
1140
  console.log(` ${check} Using API key: ${dim(masked)}`);
1114
1141
  console.log();
1115
1142
  trimmedKey = flagKey;
1116
- } else if (connectMode === "app") {
1143
+ } else if (storedKey !== null && storedCheck !== null) {
1144
+ const masked = `${storedKey.slice(0, 8)}...${storedKey.slice(-4)}`;
1145
+ console.log(` ${check} Using the key already on this machine: ${dim(masked)}`);
1146
+ console.log(` ${dim(PUSHARY_CONFIG_FILE)}`);
1147
+ console.log();
1148
+ trimmedKey = storedKey;
1149
+ storedKeyCheck = storedCheck;
1150
+ } else if (!pairingRequested && envKey && isValidApiKey(envKey)) {
1151
+ const masked = `${envKey.slice(0, 8)}...${envKey.slice(-4)}`;
1152
+ console.log(` ${check} Found API key in environment: ${dim(masked)}`);
1153
+ console.log();
1154
+ const useExisting = options.nonInteractive ? true : await confirm({ message: "Use this key?", default: true });
1155
+ if (useExisting) {
1156
+ trimmedKey = envKey;
1157
+ } else {
1158
+ const apiKey = await input({ message: "API key:" });
1159
+ trimmedKey = apiKey.trim();
1160
+ }
1161
+ } else if (connectMode === "app" && canRunBrowserLogin() && !options.skipPhone) {
1117
1162
  console.log(` ${dim("Pairing with your Pushary app.")}`);
1163
+ console.log(` ${dim("No app? Press Ctrl-C for the ways to finish without one.")}`);
1118
1164
  const previous = readKeySource();
1119
1165
  const paired = await connectViaAppPairing();
1120
1166
  if (!paired) {
1121
1167
  console.log();
1122
- console.log(` ${yellow("!")} Pairing didn't complete. Re-run setup when you're ready to scan.`);
1123
- console.log(` ${dim("No app yet? Get it at")} ${cyan("https://pushary.com/download")}`);
1124
- process.exit(1);
1168
+ console.log(` ${yellow("!")} Pairing didn't complete. Two ways to finish without the app:`);
1169
+ console.log();
1170
+ console.log(` ${cyan("setup --connect browser")} ${dim("Approve in a browser tab")}`);
1171
+ console.log(` ${cyan("setup --key pk_...")} ${dim("Paste a key you already have")}`);
1172
+ console.log();
1173
+ console.log(` ${dim("Or get the app at")} ${cyan("https://pushary.com/download")} ${dim("and re-run setup.")}`);
1174
+ process.exit(EXIT.NOT_CONFIGURED);
1125
1175
  }
1126
1176
  trimmedKey = paired.apiKey;
1127
1177
  keyFromPairing = true;
@@ -1133,17 +1183,6 @@ var main = async () => {
1133
1183
  console.log(` ${dim("Revoke it at")} ${cyan("pushary.com/dashboard/agent/settings")} ${dim("if nothing else uses it.")}`);
1134
1184
  }
1135
1185
  console.log();
1136
- } else if (envKey && isValidApiKey(envKey)) {
1137
- const masked = `${envKey.slice(0, 8)}...${envKey.slice(-4)}`;
1138
- console.log(` ${check} Found API key in environment: ${dim(masked)}`);
1139
- console.log();
1140
- const useExisting = options.nonInteractive ? true : await confirm({ message: "Use this key?", default: true });
1141
- if (useExisting) {
1142
- trimmedKey = envKey;
1143
- } else {
1144
- const apiKey = await input({ message: "API key:" });
1145
- trimmedKey = apiKey.trim();
1146
- }
1147
1186
  } else if (!canRunBrowserLogin()) {
1148
1187
  console.log(` ${yellow("!")} No API key, and no terminal to sign in from.`);
1149
1188
  console.log(` ${dim("Pass --key <pk_xxx.xxx>, or --key-stdin, or export PUSHARY_API_KEY.")}`);
@@ -1187,7 +1226,7 @@ var main = async () => {
1187
1226
  `);
1188
1227
  process.exit(EXIT.USAGE);
1189
1228
  }
1190
- const keyCheck = keyFromPairing ? null : await verifyKeyOrExit(trimmedKey, options);
1229
+ const keyCheck = keyFromPairing ? null : await verifyKeyOrExit(trimmedKey, options, storedKeyCheck ?? void 0);
1191
1230
  const agents = await resolveAgents(options);
1192
1231
  if (options.dryRun) {
1193
1232
  reportDryRun(trimmedKey, agents, keyCheck);
@@ -1238,8 +1277,10 @@ var main = async () => {
1238
1277
  console.log(` ${dim("Skipping the phone check (--skip-phone).")}`);
1239
1278
  } else if (!process.stdout.isTTY) {
1240
1279
  phone = await printConnectInstructions(trimmedKey);
1241
- } else if (connectMode === "app") {
1280
+ } else if (keyFromPairing) {
1242
1281
  phone = await confirmAppConnection(trimmedKey);
1282
+ } else if (connectMode === "app") {
1283
+ phone = await printConnectInstructions(trimmedKey);
1243
1284
  } else {
1244
1285
  phone = await connectDevice(trimmedKey, { showCapabilities: !options.connectExplicit });
1245
1286
  }
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  exitOnHelpFlag
4
- } from "../chunk-VYD27DKZ.js";
5
- import "../chunk-PPTC2QDB.js";
4
+ } from "../chunk-ATP6UQPH.js";
5
+ import "../chunk-JGH37QRB.js";
6
6
  import {
7
7
  readLedgerSummary
8
8
  } from "../chunk-WLGEY4UX.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  describeLastSeen,
4
4
  listMachines
5
- } from "../chunk-R22IAMSS.js";
5
+ } from "../chunk-YZT2CBC3.js";
6
6
  import {
7
7
  describeReach,
8
8
  fetchChannels,
@@ -11,7 +11,7 @@ import {
11
11
  import "../chunk-3EGEA4KH.js";
12
12
  import {
13
13
  readKeySource
14
- } from "../chunk-COC6NPWG.js";
14
+ } from "../chunk-NHKWU7MN.js";
15
15
  import "../chunk-6MTNS63X.js";
16
16
  import {
17
17
  checkApiKey,
@@ -20,14 +20,14 @@ import {
20
20
  import {
21
21
  createIo
22
22
  } from "../chunk-TX7KBKT7.js";
23
+ import "../chunk-BC3VCZ3E.js";
23
24
  import {
24
25
  rejectUnknownFlags
25
26
  } from "../chunk-GMXKITVA.js";
26
- import "../chunk-BC3VCZ3E.js";
27
27
  import {
28
28
  exitOnHelpFlag
29
- } from "../chunk-VYD27DKZ.js";
30
- import "../chunk-PPTC2QDB.js";
29
+ } from "../chunk-ATP6UQPH.js";
30
+ import "../chunk-JGH37QRB.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-VYD27DKZ.js";
11
- import "../chunk-PPTC2QDB.js";
10
+ } from "../chunk-ATP6UQPH.js";
11
+ import "../chunk-JGH37QRB.js";
12
12
  import {
13
13
  UsageError
14
14
  } from "../chunk-7QLSKOSU.js";
@@ -34,10 +34,10 @@ import {
34
34
  } from "../chunk-MUEW424A.js";
35
35
  import {
36
36
  exitOnHelpFlag
37
- } from "../chunk-VYD27DKZ.js";
37
+ } from "../chunk-ATP6UQPH.js";
38
38
  import {
39
39
  isNewerVersion
40
- } from "../chunk-PPTC2QDB.js";
40
+ } from "../chunk-JGH37QRB.js";
41
41
  import "../chunk-DQAN3JQP.js";
42
42
  import {
43
43
  getApiKey
@@ -14,8 +14,8 @@ import {
14
14
  } from "../chunk-GMXKITVA.js";
15
15
  import {
16
16
  exitOnHelpFlag
17
- } from "../chunk-VYD27DKZ.js";
18
- import "../chunk-PPTC2QDB.js";
17
+ } from "../chunk-ATP6UQPH.js";
18
+ import "../chunk-JGH37QRB.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-PPTC2QDB.js";
7
+ } from "../chunk-JGH37QRB.js";
8
8
  import {
9
9
  installProxyDispatcher
10
10
  } from "../chunk-SAF6HGAA.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getPackageVersion,
3
3
  renderCommandHelp
4
- } from "./chunk-PPTC2QDB.js";
4
+ } from "./chunk-JGH37QRB.js";
5
5
  import {
6
6
  EXIT
7
7
  } from "./chunk-KZERVKTD.js";
@@ -105,8 +105,10 @@ var SETUP_OPTIONS = [
105
105
  ["--key-stdin", "Read the API key from the first line of stdin, so it never appears in argv or shell history"],
106
106
  ["--agents <list>", 'Comma-separated agent ids, or "auto" for everything detected, or "none" to save the key only'],
107
107
  ["--yes, -y", "Accept every default and ask nothing. Implies --agents auto unless --agents is given"],
108
- ["--connect app", "Pair the native Pushary app, no key to paste"],
109
- ["--connect web", "Connect your phone via the browser subscribe page (default)"],
108
+ ["--connect app", "Pair the native Pushary app, no key to paste (default)"],
109
+ ["--connect browser", "Approve in a browser tab instead. For a machine with no app"],
110
+ ["--connect web", "Legacy browser subscribe page"],
111
+ ["--connect none", "Skip the phone connect step, same as --skip-phone"],
110
112
  ["--skip-phone", "Skip the phone connect step"],
111
113
  ["--dry-run", "Print what would be written and change nothing"],
112
114
  ["--json", "Emit one machine-readable object instead of the human report"]
@@ -169,6 +169,7 @@ var readConfigKey = (configPath) => {
169
169
  const key = typeof result.value.apiKey === "string" ? result.value.apiKey.trim() : "";
170
170
  return key || null;
171
171
  };
172
+ var readConfigFileKey = () => readConfigKey(configFilePath());
172
173
  var readKeySource = () => {
173
174
  const configPath = configFilePath();
174
175
  const envKey = process.env.PUSHARY_API_KEY?.trim() || null;
@@ -185,5 +186,6 @@ export {
185
186
  keyPrefix,
186
187
  writeKey,
187
188
  clearKey,
189
+ readConfigFileKey,
188
190
  readKeySource
189
191
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getPackageVersion
3
- } from "./chunk-PPTC2QDB.js";
3
+ } from "./chunk-JGH37QRB.js";
4
4
  import {
5
5
  getMachineId
6
6
  } from "./chunk-RN3NOEJF.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "0.63.2",
3
+ "version": "0.64.0",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",