@pushary/agent-hooks 0.63.2 → 0.64.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.
- package/CHANGELOG.md +61 -0
- package/dist/bin/pushary-clean.js +19 -3
- package/dist/bin/pushary-connect.js +5 -5
- package/dist/bin/pushary-daemon.js +3 -3
- package/dist/bin/pushary-doctor.js +7 -6
- package/dist/bin/pushary-hook.js +2 -2
- package/dist/bin/pushary-login.js +4 -4
- package/dist/bin/pushary-logout.js +4 -4
- package/dist/bin/pushary-mode.js +2 -2
- package/dist/bin/pushary-setup.js +84 -36
- package/dist/bin/pushary-stats.js +2 -2
- package/dist/bin/pushary-status.js +6 -6
- package/dist/bin/pushary-suggestions.js +2 -2
- package/dist/bin/pushary-upgrade.js +2 -2
- package/dist/bin/pushary-wait.js +2 -2
- package/dist/bin/pushary.js +1 -1
- package/dist/{chunk-VYD27DKZ.js → chunk-ATP6UQPH.js} +1 -1
- package/dist/{chunk-PPTC2QDB.js → chunk-JGH37QRB.js} +4 -2
- package/dist/{chunk-COC6NPWG.js → chunk-NHKWU7MN.js} +2 -0
- package/dist/{chunk-NGZMVCXN.js → chunk-RASBS2CC.js} +2 -1
- package/dist/{chunk-R22IAMSS.js → chunk-YZT2CBC3.js} +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.64.1
|
|
4
|
+
|
|
5
|
+
### Ctrl-C at the pairing QR printed nothing
|
|
6
|
+
|
|
7
|
+
The QR screen said "No app? Press Ctrl-C for the ways to finish without one", and
|
|
8
|
+
pressing it printed nothing at all. `connectViaAppPairing` handles SIGINT by
|
|
9
|
+
exiting the process itself, so control never returned to setup and the lines it
|
|
10
|
+
meant to show were unreachable on the one path that advertised them.
|
|
11
|
+
|
|
12
|
+
Setup now hands the escape to the pairing wait, which prints it inside the
|
|
13
|
+
handler before exiting, and the line on screen names the command directly instead
|
|
14
|
+
of telling you to interrupt the program to find out what it is.
|
|
15
|
+
|
|
16
|
+
The same two commands are printed when a pairing simply never completes, so both
|
|
17
|
+
ways out of the QR screen say the same thing.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## 0.64.0
|
|
21
|
+
|
|
22
|
+
### A typo on `--dry-run` ran a real clean
|
|
23
|
+
|
|
24
|
+
`pushary clean --yes --dryrun`, one missing hyphen, silently dropped the flag it
|
|
25
|
+
did not recognise and performed a full destructive clean: the stored key, the
|
|
26
|
+
Cursor plugin, every agent config, and the global package itself. It printed
|
|
27
|
+
"Clean complete." with the past tense throughout and exited `0`. The typo most
|
|
28
|
+
worth catching was the one on the flag that means "change nothing", sitting next
|
|
29
|
+
to the flag that means "do not ask me".
|
|
30
|
+
|
|
31
|
+
`clean` now rejects a flag it does not know and exits `2` before removing
|
|
32
|
+
anything. `--dry-run`, `--yes` and `-y` are unchanged.
|
|
33
|
+
|
|
34
|
+
### Setup reuses the key this machine already has
|
|
35
|
+
|
|
36
|
+
`setup` read `PUSHARY_API_KEY` and never `~/.pushary/config.json`, so the key
|
|
37
|
+
`pushary login` had just written was invisible to it. `login` followed by `setup`
|
|
38
|
+
in the same shell ran a second browser login and minted a second key, and a
|
|
39
|
+
machine with no terminal that had been set up by `login` exited "no API key" with
|
|
40
|
+
a working key sitting on disk. The shell export made it work in a *new* shell,
|
|
41
|
+
which is what hid it.
|
|
42
|
+
|
|
43
|
+
Setup now reads the stored key, verifies it, and uses it. A key the server no
|
|
44
|
+
longer recognises falls through to a fresh sign-in rather than dead-ending, and a
|
|
45
|
+
server it cannot reach keeps the key rather than discarding it.
|
|
46
|
+
|
|
47
|
+
### The Pushary app is the default connect path
|
|
48
|
+
|
|
49
|
+
An unflagged `setup` now pairs the app instead of sending you to the browser
|
|
50
|
+
subscribe page. `--connect browser` is the fallback for a machine with no app,
|
|
51
|
+
`--connect web` is the legacy page and keeps working exactly as before, and
|
|
52
|
+
`--connect none` skips the phone step like `--skip-phone`. `auto` and `pwa` are
|
|
53
|
+
accepted as input spellings.
|
|
54
|
+
|
|
55
|
+
Pairing only happens when there is a terminal to show the QR to and no usable key
|
|
56
|
+
already on the machine, so re-running setup to add an agent no longer asks you to
|
|
57
|
+
scan anything, and no longer mints a key you did not ask for. Typing
|
|
58
|
+
`--connect app` explicitly still pairs every time.
|
|
59
|
+
|
|
60
|
+
When pairing does not complete, setup now names the two ways to finish without
|
|
61
|
+
the app rather than only inviting you to try the QR again.
|
|
62
|
+
|
|
63
|
+
|
|
3
64
|
## 0.63.2
|
|
4
65
|
|
|
5
66
|
### 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-
|
|
38
|
-
import "../chunk-
|
|
40
|
+
} from "../chunk-ATP6UQPH.js";
|
|
41
|
+
import "../chunk-JGH37QRB.js";
|
|
42
|
+
import "../chunk-7QLSKOSU.js";
|
|
39
43
|
import "../chunk-DQAN3JQP.js";
|
|
40
|
-
import
|
|
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")}`);
|
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
confirmAppConnection,
|
|
7
7
|
connectDevice,
|
|
8
8
|
printConnectInstructions
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-RASBS2CC.js";
|
|
10
10
|
import "../chunk-3EGEA4KH.js";
|
|
11
11
|
import {
|
|
12
12
|
readKeySource
|
|
13
|
-
} from "../chunk-
|
|
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-
|
|
28
|
-
import "../chunk-
|
|
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-
|
|
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-
|
|
15
|
-
import "../chunk-
|
|
14
|
+
} from "../chunk-ATP6UQPH.js";
|
|
15
|
+
import "../chunk-JGH37QRB.js";
|
|
16
16
|
import {
|
|
17
17
|
getMachineId
|
|
18
18
|
} from "../chunk-RN3NOEJF.js";
|
|
@@ -34,12 +34,12 @@ import {
|
|
|
34
34
|
describeReach,
|
|
35
35
|
fetchChannels,
|
|
36
36
|
reachVerdict
|
|
37
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-RASBS2CC.js";
|
|
38
38
|
import "../chunk-3EGEA4KH.js";
|
|
39
39
|
import {
|
|
40
40
|
keyPrefix,
|
|
41
41
|
readKeySource
|
|
42
|
-
} from "../chunk-
|
|
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-
|
|
60
|
+
} from "../chunk-ATP6UQPH.js";
|
|
61
61
|
import {
|
|
62
62
|
getPackageVersion
|
|
63
|
-
} from "../chunk-
|
|
63
|
+
} from "../chunk-JGH37QRB.js";
|
|
64
64
|
import {
|
|
65
65
|
readLedgerSummary
|
|
66
66
|
} from "../chunk-WLGEY4UX.js";
|
|
@@ -102,12 +102,13 @@ var globalVersion = () => {
|
|
|
102
102
|
};
|
|
103
103
|
var collectBundle = async (options2 = {}) => {
|
|
104
104
|
const now = options2.now ?? (() => /* @__PURE__ */ new Date());
|
|
105
|
+
const readGlobalVersion = options2.readGlobalVersion ?? globalVersion;
|
|
105
106
|
const source = readKeySource();
|
|
106
107
|
const identity = options2.identity ?? null;
|
|
107
108
|
return {
|
|
108
109
|
generatedAt: now().toISOString(),
|
|
109
110
|
cliVersion: getPackageVersion(),
|
|
110
|
-
globalVersion:
|
|
111
|
+
globalVersion: readGlobalVersion(),
|
|
111
112
|
node: process.version,
|
|
112
113
|
platform: process.platform,
|
|
113
114
|
arch: process.arch,
|
package/dist/bin/pushary-hook.js
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
import "../chunk-CAJZAFVS.js";
|
|
6
6
|
import {
|
|
7
7
|
exitOnHelpFlag
|
|
8
|
-
} from "../chunk-
|
|
9
|
-
import "../chunk-
|
|
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-
|
|
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-
|
|
24
|
+
} from "../chunk-ATP6UQPH.js";
|
|
25
25
|
import {
|
|
26
26
|
getPackageVersion
|
|
27
|
-
} from "../chunk-
|
|
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-
|
|
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-
|
|
23
|
-
import "../chunk-
|
|
22
|
+
} from "../chunk-ATP6UQPH.js";
|
|
23
|
+
import "../chunk-JGH37QRB.js";
|
|
24
24
|
import {
|
|
25
25
|
UsageError
|
|
26
26
|
} from "../chunk-7QLSKOSU.js";
|
package/dist/bin/pushary-mode.js
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
} from "../chunk-GMXKITVA.js";
|
|
12
12
|
import {
|
|
13
13
|
exitOnHelpFlag
|
|
14
|
-
} from "../chunk-
|
|
15
|
-
import "../chunk-
|
|
14
|
+
} from "../chunk-ATP6UQPH.js";
|
|
15
|
+
import "../chunk-JGH37QRB.js";
|
|
16
16
|
import "../chunk-SAF6HGAA.js";
|
|
17
17
|
import {
|
|
18
18
|
UsageError
|
|
@@ -45,15 +45,16 @@ import {
|
|
|
45
45
|
connectViaAppPairing,
|
|
46
46
|
printConnectInstructions,
|
|
47
47
|
setHumanStream
|
|
48
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-RASBS2CC.js";
|
|
49
49
|
import "../chunk-3EGEA4KH.js";
|
|
50
50
|
import {
|
|
51
51
|
KEY_FILE_MODE,
|
|
52
52
|
exportLine,
|
|
53
53
|
keyPrefix,
|
|
54
|
+
readConfigFileKey,
|
|
54
55
|
readKeySource,
|
|
55
56
|
writeKey
|
|
56
|
-
} from "../chunk-
|
|
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-
|
|
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
|
-
|
|
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
|
|
291
|
+
connectMode,
|
|
285
292
|
connectExplicit: connectRaw !== void 0,
|
|
286
|
-
|
|
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
|
-
|
|
950
|
-
result =
|
|
951
|
-
}
|
|
952
|
-
|
|
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,28 @@ var verifyKeyOrExit = async (apiKey, options) => {
|
|
|
968
982
|
}
|
|
969
983
|
return result;
|
|
970
984
|
};
|
|
985
|
+
var printPairingEscape = () => {
|
|
986
|
+
console.log();
|
|
987
|
+
console.log(` ${yellow("!")} No app? Two ways to finish without one:`);
|
|
988
|
+
console.log();
|
|
989
|
+
console.log(` ${cyan("npx @pushary/agent-hooks setup --connect browser")}`);
|
|
990
|
+
console.log(` ${dim("Approve in a browser tab. No phone needed.")}`);
|
|
991
|
+
console.log();
|
|
992
|
+
console.log(` ${cyan("npx @pushary/agent-hooks setup --key pk_...")}`);
|
|
993
|
+
console.log(` ${dim("Paste a key from")} ${cyan("pushary.com/dashboard/agent/settings")}`);
|
|
994
|
+
console.log();
|
|
995
|
+
console.log(` ${dim("Or get the app at")} ${cyan("https://pushary.com/download")} ${dim("and re-run setup.")}`);
|
|
996
|
+
console.log();
|
|
997
|
+
};
|
|
998
|
+
var usableStoredKey = async (apiKey) => {
|
|
999
|
+
let result;
|
|
1000
|
+
try {
|
|
1001
|
+
result = await checkApiKey(apiKey);
|
|
1002
|
+
} catch (err) {
|
|
1003
|
+
result = { kind: "unreachable", detail: formatError(err) };
|
|
1004
|
+
}
|
|
1005
|
+
return result.kind === "rejected" || result.kind === "malformed" ? null : result;
|
|
1006
|
+
};
|
|
971
1007
|
var AGENT_NAMES = {
|
|
972
1008
|
claude_code: "Claude Code",
|
|
973
1009
|
codex: "Codex",
|
|
@@ -1108,20 +1144,41 @@ var main = async () => {
|
|
|
1108
1144
|
const envKey = process.env.PUSHARY_API_KEY?.trim();
|
|
1109
1145
|
let trimmedKey;
|
|
1110
1146
|
let keyFromPairing = false;
|
|
1147
|
+
const storedKey = readConfigFileKey();
|
|
1148
|
+
const pairingRequested = connectMode === "app" && options.connectExplicit && !options.skipPhone;
|
|
1149
|
+
const storedCheck = !(flagKey && isValidApiKey(flagKey)) && !pairingRequested && !(envKey && isValidApiKey(envKey)) && storedKey !== null && isValidApiKey(storedKey) ? await usableStoredKey(storedKey) : null;
|
|
1150
|
+
let storedKeyCheck = null;
|
|
1111
1151
|
if (flagKey && isValidApiKey(flagKey)) {
|
|
1112
1152
|
const masked = `${flagKey.slice(0, 8)}...${flagKey.slice(-4)}`;
|
|
1113
1153
|
console.log(` ${check} Using API key: ${dim(masked)}`);
|
|
1114
1154
|
console.log();
|
|
1115
1155
|
trimmedKey = flagKey;
|
|
1116
|
-
} else if (
|
|
1156
|
+
} else if (storedKey !== null && storedCheck !== null) {
|
|
1157
|
+
const masked = `${storedKey.slice(0, 8)}...${storedKey.slice(-4)}`;
|
|
1158
|
+
console.log(` ${check} Using the key already on this machine: ${dim(masked)}`);
|
|
1159
|
+
console.log(` ${dim(PUSHARY_CONFIG_FILE)}`);
|
|
1160
|
+
console.log();
|
|
1161
|
+
trimmedKey = storedKey;
|
|
1162
|
+
storedKeyCheck = storedCheck;
|
|
1163
|
+
} else if (!pairingRequested && envKey && isValidApiKey(envKey)) {
|
|
1164
|
+
const masked = `${envKey.slice(0, 8)}...${envKey.slice(-4)}`;
|
|
1165
|
+
console.log(` ${check} Found API key in environment: ${dim(masked)}`);
|
|
1166
|
+
console.log();
|
|
1167
|
+
const useExisting = options.nonInteractive ? true : await confirm({ message: "Use this key?", default: true });
|
|
1168
|
+
if (useExisting) {
|
|
1169
|
+
trimmedKey = envKey;
|
|
1170
|
+
} else {
|
|
1171
|
+
const apiKey = await input({ message: "API key:" });
|
|
1172
|
+
trimmedKey = apiKey.trim();
|
|
1173
|
+
}
|
|
1174
|
+
} else if (connectMode === "app" && canRunBrowserLogin() && !options.skipPhone) {
|
|
1117
1175
|
console.log(` ${dim("Pairing with your Pushary app.")}`);
|
|
1176
|
+
console.log(` ${dim("No app? Ctrl-C, then:")} ${cyan("npx @pushary/agent-hooks setup --connect browser")}`);
|
|
1118
1177
|
const previous = readKeySource();
|
|
1119
|
-
const paired = await connectViaAppPairing();
|
|
1178
|
+
const paired = await connectViaAppPairing({ onCancelled: printPairingEscape });
|
|
1120
1179
|
if (!paired) {
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
console.log(` ${dim("No app yet? Get it at")} ${cyan("https://pushary.com/download")}`);
|
|
1124
|
-
process.exit(1);
|
|
1180
|
+
printPairingEscape();
|
|
1181
|
+
process.exit(EXIT.NOT_CONFIGURED);
|
|
1125
1182
|
}
|
|
1126
1183
|
trimmedKey = paired.apiKey;
|
|
1127
1184
|
keyFromPairing = true;
|
|
@@ -1133,17 +1190,6 @@ var main = async () => {
|
|
|
1133
1190
|
console.log(` ${dim("Revoke it at")} ${cyan("pushary.com/dashboard/agent/settings")} ${dim("if nothing else uses it.")}`);
|
|
1134
1191
|
}
|
|
1135
1192
|
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
1193
|
} else if (!canRunBrowserLogin()) {
|
|
1148
1194
|
console.log(` ${yellow("!")} No API key, and no terminal to sign in from.`);
|
|
1149
1195
|
console.log(` ${dim("Pass --key <pk_xxx.xxx>, or --key-stdin, or export PUSHARY_API_KEY.")}`);
|
|
@@ -1187,7 +1233,7 @@ var main = async () => {
|
|
|
1187
1233
|
`);
|
|
1188
1234
|
process.exit(EXIT.USAGE);
|
|
1189
1235
|
}
|
|
1190
|
-
const keyCheck = keyFromPairing ? null : await verifyKeyOrExit(trimmedKey, options);
|
|
1236
|
+
const keyCheck = keyFromPairing ? null : await verifyKeyOrExit(trimmedKey, options, storedKeyCheck ?? void 0);
|
|
1191
1237
|
const agents = await resolveAgents(options);
|
|
1192
1238
|
if (options.dryRun) {
|
|
1193
1239
|
reportDryRun(trimmedKey, agents, keyCheck);
|
|
@@ -1238,8 +1284,10 @@ var main = async () => {
|
|
|
1238
1284
|
console.log(` ${dim("Skipping the phone check (--skip-phone).")}`);
|
|
1239
1285
|
} else if (!process.stdout.isTTY) {
|
|
1240
1286
|
phone = await printConnectInstructions(trimmedKey);
|
|
1241
|
-
} else if (
|
|
1287
|
+
} else if (keyFromPairing) {
|
|
1242
1288
|
phone = await confirmAppConnection(trimmedKey);
|
|
1289
|
+
} else if (connectMode === "app") {
|
|
1290
|
+
phone = await printConnectInstructions(trimmedKey);
|
|
1243
1291
|
} else {
|
|
1244
1292
|
phone = await connectDevice(trimmedKey, { showCapabilities: !options.connectExplicit });
|
|
1245
1293
|
}
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
import {
|
|
3
3
|
describeLastSeen,
|
|
4
4
|
listMachines
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-YZT2CBC3.js";
|
|
6
6
|
import {
|
|
7
7
|
describeReach,
|
|
8
8
|
fetchChannels,
|
|
9
9
|
reachVerdict
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-RASBS2CC.js";
|
|
11
11
|
import "../chunk-3EGEA4KH.js";
|
|
12
12
|
import {
|
|
13
13
|
readKeySource
|
|
14
|
-
} from "../chunk-
|
|
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-
|
|
30
|
-
import "../chunk-
|
|
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-
|
|
11
|
-
import "../chunk-
|
|
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-
|
|
37
|
+
} from "../chunk-ATP6UQPH.js";
|
|
38
38
|
import {
|
|
39
39
|
isNewerVersion
|
|
40
|
-
} from "../chunk-
|
|
40
|
+
} from "../chunk-JGH37QRB.js";
|
|
41
41
|
import "../chunk-DQAN3JQP.js";
|
|
42
42
|
import {
|
|
43
43
|
getApiKey
|
package/dist/bin/pushary-wait.js
CHANGED
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
} from "../chunk-GMXKITVA.js";
|
|
15
15
|
import {
|
|
16
16
|
exitOnHelpFlag
|
|
17
|
-
} from "../chunk-
|
|
18
|
-
import "../chunk-
|
|
17
|
+
} from "../chunk-ATP6UQPH.js";
|
|
18
|
+
import "../chunk-JGH37QRB.js";
|
|
19
19
|
import "../chunk-SAF6HGAA.js";
|
|
20
20
|
import {
|
|
21
21
|
UsageError
|
package/dist/bin/pushary.js
CHANGED
|
@@ -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
|
|
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
|
};
|
|
@@ -494,7 +494,7 @@ var buildPairLinks = (pairId, publicKeyB64, baseUrl = apiBase()) => {
|
|
|
494
494
|
deepLink: `pushary://pair?pk=${pk}&id=${id}`
|
|
495
495
|
};
|
|
496
496
|
};
|
|
497
|
-
var connectViaAppPairing = async () => {
|
|
497
|
+
var connectViaAppPairing = async (options = {}) => {
|
|
498
498
|
const keypair = generateKeypair();
|
|
499
499
|
const pairId = await startPairing(keypair.publicKeyB64);
|
|
500
500
|
if (!pairId) {
|
|
@@ -520,6 +520,7 @@ var connectViaAppPairing = async () => {
|
|
|
520
520
|
const onInterrupt = () => {
|
|
521
521
|
cancelled = true;
|
|
522
522
|
stop(yellow("!"), "Cancelled");
|
|
523
|
+
options.onCancelled?.();
|
|
523
524
|
void cancelPairing(pairId).finally(() => process.exit(EXIT_ABORTED));
|
|
524
525
|
};
|
|
525
526
|
process.once("SIGINT", onInterrupt);
|