@pushary/agent-hooks 0.64.2 → 0.64.3

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,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.64.3
4
+
5
+ ### A stale shell export hid the working key on disk
6
+
7
+ `PUSHARY_API_KEY` wins over `~/.pushary/config.json`, which is right and
8
+ unchanged. But the environment used to win on the key's *shape* alone, so a
9
+ well-formed key the server had since revoked shadowed a working one in the config
10
+ file and setup exited "This key was rejected by pushary.com" with a perfectly
11
+ good key sitting on the machine.
12
+
13
+ That is the state any shell left open across a key rotation is in: the export is
14
+ the old key, the file is the new one, and the terminal you happen to be typing in
15
+ decides whether setup works.
16
+
17
+ The environment key is checked with the server before it is chosen now, and a
18
+ rejected one falls through to the stored key rather than ending the run. It costs
19
+ no extra call: the verdict is handed to the verification step that was already
20
+ making it.
21
+
22
+ ### `--connect app` on a machine with no terminal named the wrong problem
23
+
24
+ A headless run that asked to pair said "No API key, and no terminal to sign in
25
+ from" even with a key in the config file, because asking to pair deliberately
26
+ takes the stored key off the table. It now says the flag needs a terminal for the
27
+ QR, and that dropping it uses the key already there.
28
+
3
29
  ## 0.64.2
4
30
 
5
31
  ### A run that gave up reported nothing, and said it stopped at the start
@@ -1180,7 +1180,10 @@ var main = async () => {
1180
1180
  let keyFromPairing = false;
1181
1181
  const storedKey = readConfigFileKey();
1182
1182
  const pairingRequested = connectMode === "app" && options.connectExplicit && !options.skipPhone;
1183
- const storedCheck = !(flagKey && isValidApiKey(flagKey)) && !pairingRequested && !(envKey && isValidApiKey(envKey)) && storedKey !== null && isValidApiKey(storedKey) ? await usableStoredKey(storedKey) : null;
1183
+ const ambientEligible = !(flagKey && isValidApiKey(flagKey)) && !pairingRequested;
1184
+ const envCheck = ambientEligible && envKey && isValidApiKey(envKey) ? await usableStoredKey(envKey) : null;
1185
+ const storedCheck = ambientEligible && envCheck === null && storedKey !== null && isValidApiKey(storedKey) && // login writes both, so without this the same key is probed twice.
1186
+ storedKey !== envKey ? await usableStoredKey(storedKey) : null;
1184
1187
  let storedKeyCheck = null;
1185
1188
  if (flagKey && isValidApiKey(flagKey)) {
1186
1189
  const masked = `${flagKey.slice(0, 8)}...${flagKey.slice(-4)}`;
@@ -1194,13 +1197,14 @@ var main = async () => {
1194
1197
  console.log();
1195
1198
  trimmedKey = storedKey;
1196
1199
  storedKeyCheck = storedCheck;
1197
- } else if (!pairingRequested && envKey && isValidApiKey(envKey)) {
1200
+ } else if (envKey && envCheck !== null) {
1198
1201
  const masked = `${envKey.slice(0, 8)}...${envKey.slice(-4)}`;
1199
1202
  console.log(` ${check} Found API key in environment: ${dim(masked)}`);
1200
1203
  console.log();
1201
1204
  const useExisting = options.nonInteractive ? true : await confirm({ message: "Use this key?", default: true });
1202
1205
  if (useExisting) {
1203
1206
  trimmedKey = envKey;
1207
+ storedKeyCheck = envCheck;
1204
1208
  } else {
1205
1209
  const apiKey = await input({ message: "API key:" });
1206
1210
  trimmedKey = apiKey.trim();
@@ -1231,9 +1235,14 @@ var main = async () => {
1231
1235
  }
1232
1236
  console.log();
1233
1237
  } else if (!canRunBrowserLogin()) {
1234
- console.log(` ${yellow("!")} No API key, and no terminal to sign in from.`);
1235
- console.log(` ${dim("Pass --key <pk_xxx.xxx>, or --key-stdin, or export PUSHARY_API_KEY.")}`);
1236
- console.log(` ${dim("On a machine with a terminal, run")} ${cyan("pushary login")} ${dim("once and re-run this.")}`);
1238
+ if (pairingRequested) {
1239
+ console.log(` ${yellow("!")} ${cyan("--connect app")} needs a terminal to show the pairing QR in.`);
1240
+ console.log(` ${dim("Drop the flag to use the key this machine already has, or pass --key <pk_xxx.xxx>.")}`);
1241
+ } else {
1242
+ console.log(` ${yellow("!")} No API key, and no terminal to sign in from.`);
1243
+ console.log(` ${dim("Pass --key <pk_xxx.xxx>, or --key-stdin, or export PUSHARY_API_KEY.")}`);
1244
+ console.log(` ${dim("On a machine with a terminal, run")} ${cyan("pushary login")} ${dim("once and re-run this.")}`);
1245
+ }
1237
1246
  console.log();
1238
1247
  process.exit(await abortWith("no-key", EXIT.NOT_CONFIGURED));
1239
1248
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "0.64.2",
3
+ "version": "0.64.3",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",