@pushary/agent-hooks 0.64.0 → 0.64.2
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 +52 -0
- package/dist/bin/pushary-claude.js +1 -1
- package/dist/bin/pushary-codex-hook.js +1 -1
- package/dist/bin/pushary-codex.js +1 -1
- package/dist/bin/pushary-connect.js +1 -1
- package/dist/bin/pushary-doctor.js +3 -2
- package/dist/bin/pushary-gemini-hook.js +1 -1
- package/dist/bin/pushary-hook.js +2 -2
- package/dist/bin/pushary-notification-hook.js +1 -1
- package/dist/bin/pushary-permission-denied-hook.js +2 -2
- package/dist/bin/pushary-permission-hook.js +2 -2
- package/dist/bin/pushary-post-hook.js +1 -1
- package/dist/bin/pushary-prompt-hook.js +1 -1
- package/dist/bin/pushary-session-end-hook.js +1 -1
- package/dist/bin/pushary-session-start-hook.js +1 -1
- package/dist/bin/pushary-setup.js +105 -40
- package/dist/bin/pushary-status.js +1 -1
- package/dist/bin/pushary-stop-hook.js +1 -1
- package/dist/bin/pushary-stopfailure-hook.js +1 -1
- package/dist/{chunk-NGZMVCXN.js → chunk-GFHQ26ST.js} +3 -2
- package/dist/{chunk-SDXF5I46.js → chunk-SONXGCZY.js} +1 -1
- package/dist/{chunk-5ZDYDU2Q.js → chunk-XOUYM27W.js} +1 -1
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.64.2
|
|
4
|
+
|
|
5
|
+
### A run that gave up reported nothing, and said it stopped at the start
|
|
6
|
+
|
|
7
|
+
`agent_setup_completed` was wired to one of setup's fifteen exits: the last line
|
|
8
|
+
of a run that finished. Every other way out returned before it. A key the server
|
|
9
|
+
refused, a cancelled pairing, no terminal to sign in from, an installer that
|
|
10
|
+
threw, a Ctrl-C at the agent checkbox: all silent. The beacon was added so failed
|
|
11
|
+
and abandoned runs would stop being invisible, and the runs it could see were
|
|
12
|
+
still only the ones that already worked.
|
|
13
|
+
|
|
14
|
+
Every early exit reports now, and each says why it stopped: `key-refused`,
|
|
15
|
+
`pairing-cancelled`, `no-key`, `login-rejected`, `no-agents-detected`,
|
|
16
|
+
`invalid-key`, `interrupted`, `crashed`.
|
|
17
|
+
|
|
18
|
+
Argv-time exits stay silent, along with `--help` and `--dry-run`. A flag typo is
|
|
19
|
+
not an abandoned run: nothing was attempted and nothing was written. It is also
|
|
20
|
+
the fastest-failing path there is, and waiting on a beacon took `setup --bogus`
|
|
21
|
+
from 60ms to two seconds against an unreachable server. A dry run stays silent
|
|
22
|
+
for the other reason: counting it as a completed setup would be its own lie.
|
|
23
|
+
|
|
24
|
+
`abandonedAt` said where. It was always `start`, because `markStep` had no call
|
|
25
|
+
site outside its own test, so the field that was supposed to locate a failure was
|
|
26
|
+
a constant. It now moves through the run, per agent inside the configure loop, so
|
|
27
|
+
an installer that hangs is named rather than grouped.
|
|
28
|
+
|
|
29
|
+
Ctrl-C at the pairing QR reports before the process leaves. The cancel and the
|
|
30
|
+
beacon run concurrently and the exit waits for both, so this adds nothing to the
|
|
31
|
+
worst case a cancel already had.
|
|
32
|
+
|
|
33
|
+
The beacon authenticates with the key the run resolved rather than the one
|
|
34
|
+
already installed. Most of these exits happen before the key is written to disk,
|
|
35
|
+
so without that they posted as nobody, which meant the window holding the
|
|
36
|
+
interesting failures was exactly the window that could not report.
|
|
37
|
+
|
|
38
|
+
## 0.64.1
|
|
39
|
+
|
|
40
|
+
### Ctrl-C at the pairing QR printed nothing
|
|
41
|
+
|
|
42
|
+
The QR screen said "No app? Press Ctrl-C for the ways to finish without one", and
|
|
43
|
+
pressing it printed nothing at all. `connectViaAppPairing` handles SIGINT by
|
|
44
|
+
exiting the process itself, so control never returned to setup and the lines it
|
|
45
|
+
meant to show were unreachable on the one path that advertised them.
|
|
46
|
+
|
|
47
|
+
Setup now hands the escape to the pairing wait, which prints it inside the
|
|
48
|
+
handler before exiting, and the line on screen names the command directly instead
|
|
49
|
+
of telling you to interrupt the program to find out what it is.
|
|
50
|
+
|
|
51
|
+
The same two commands are printed when a pairing simply never completes, so both
|
|
52
|
+
ways out of the QR screen say the same thing.
|
|
53
|
+
|
|
54
|
+
|
|
3
55
|
## 0.64.0
|
|
4
56
|
|
|
5
57
|
### A typo on `--dry-run` ran a real clean
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
describeReach,
|
|
35
35
|
fetchChannels,
|
|
36
36
|
reachVerdict
|
|
37
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-GFHQ26ST.js";
|
|
38
38
|
import "../chunk-3EGEA4KH.js";
|
|
39
39
|
import {
|
|
40
40
|
keyPrefix,
|
|
@@ -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
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePreToolUse
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-SONXGCZY.js";
|
|
5
5
|
import "../chunk-CAJZAFVS.js";
|
|
6
6
|
import {
|
|
7
7
|
exitOnHelpFlag
|
|
8
8
|
} from "../chunk-ATP6UQPH.js";
|
|
9
9
|
import "../chunk-JGH37QRB.js";
|
|
10
10
|
import "../chunk-YHG74UFF.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-XOUYM27W.js";
|
|
12
12
|
import "../chunk-WLGEY4UX.js";
|
|
13
13
|
import "../chunk-BSZYIAZL.js";
|
|
14
14
|
import "../chunk-SAF6HGAA.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePermissionDenied
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-SONXGCZY.js";
|
|
5
5
|
import "../chunk-CAJZAFVS.js";
|
|
6
6
|
import "../chunk-YHG74UFF.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-XOUYM27W.js";
|
|
8
8
|
import "../chunk-WLGEY4UX.js";
|
|
9
9
|
import "../chunk-BSZYIAZL.js";
|
|
10
10
|
import "../chunk-SAF6HGAA.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
handlePermissionRequest
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-SONXGCZY.js";
|
|
5
5
|
import "../chunk-CAJZAFVS.js";
|
|
6
6
|
import "../chunk-YHG74UFF.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-XOUYM27W.js";
|
|
8
8
|
import "../chunk-WLGEY4UX.js";
|
|
9
9
|
import "../chunk-BSZYIAZL.js";
|
|
10
10
|
import "../chunk-SAF6HGAA.js";
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
connectViaAppPairing,
|
|
46
46
|
printConnectInstructions,
|
|
47
47
|
setHumanStream
|
|
48
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-GFHQ26ST.js";
|
|
49
49
|
import "../chunk-3EGEA4KH.js";
|
|
50
50
|
import {
|
|
51
51
|
KEY_FILE_MODE,
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
} from "../chunk-JGH37QRB.js";
|
|
87
87
|
import {
|
|
88
88
|
reportEvent
|
|
89
|
-
} from "../chunk-
|
|
89
|
+
} from "../chunk-XOUYM27W.js";
|
|
90
90
|
import "../chunk-BSZYIAZL.js";
|
|
91
91
|
import "../chunk-SAF6HGAA.js";
|
|
92
92
|
import {
|
|
@@ -206,32 +206,60 @@ var installSkillViaSkillsCli = (agent) => {
|
|
|
206
206
|
|
|
207
207
|
// src/setup/telemetry.ts
|
|
208
208
|
var currentStep = "start";
|
|
209
|
+
var markStep = (step) => {
|
|
210
|
+
currentStep = step;
|
|
211
|
+
};
|
|
212
|
+
var recordedOptions = null;
|
|
213
|
+
var recordSetupOptions = (options) => {
|
|
214
|
+
recordedOptions = options;
|
|
215
|
+
};
|
|
216
|
+
var recordedKey = null;
|
|
217
|
+
var recordSetupKey = (apiKey) => {
|
|
218
|
+
recordedKey = apiKey;
|
|
219
|
+
};
|
|
209
220
|
var emitted = false;
|
|
210
|
-
var
|
|
221
|
+
var defaultDeps = { report: reportEvent };
|
|
222
|
+
var emit = async (deps, props) => {
|
|
211
223
|
if (emitted) return;
|
|
212
224
|
emitted = true;
|
|
213
225
|
try {
|
|
214
|
-
await
|
|
215
|
-
{
|
|
216
|
-
|
|
217
|
-
agentType: "setup",
|
|
218
|
-
agents: outcome.completed,
|
|
219
|
-
connectMode: outcome.options.connectMode,
|
|
220
|
-
connectOutcome: outcome.connectOutcome,
|
|
221
|
-
failedAgents: outcome.failed.length,
|
|
222
|
-
skippedAgents: outcome.skipped,
|
|
223
|
-
nonInteractive: outcome.options.nonInteractive,
|
|
224
|
-
keyCheck: outcome.keyCheck,
|
|
225
|
-
exitCode: outcome.exitCode,
|
|
226
|
-
// Where the run stopped. On a completed run this is the closing step, so
|
|
227
|
-
// the interesting values are the ones that are not.
|
|
228
|
-
abandonedAt: outcome.exitCode === 0 ? null : currentStep
|
|
229
|
-
},
|
|
230
|
-
{ maxAttempts: 1, timeoutMs: 2e3 }
|
|
226
|
+
await deps.report(
|
|
227
|
+
{ event: "agent_setup_completed", agentType: "setup", ...props },
|
|
228
|
+
{ maxAttempts: 1, timeoutMs: 2e3, ...recordedKey ? { apiKey: recordedKey } : {} }
|
|
231
229
|
);
|
|
232
230
|
} catch {
|
|
233
231
|
}
|
|
234
232
|
};
|
|
233
|
+
var reportSetupOutcomeWith = async (deps, outcome) => emit(deps, {
|
|
234
|
+
agents: outcome.completed,
|
|
235
|
+
connectMode: outcome.options.connectMode,
|
|
236
|
+
connectOutcome: outcome.connectOutcome,
|
|
237
|
+
failedAgents: outcome.failed.length,
|
|
238
|
+
skippedAgents: outcome.skipped,
|
|
239
|
+
nonInteractive: outcome.options.nonInteractive,
|
|
240
|
+
keyCheck: outcome.keyCheck,
|
|
241
|
+
exitCode: outcome.exitCode,
|
|
242
|
+
// Where the run stopped. On a completed run this is the closing step, so the
|
|
243
|
+
// interesting values are the ones that are not.
|
|
244
|
+
abandonedAt: outcome.exitCode === 0 ? null : currentStep,
|
|
245
|
+
// Always present, so a query can separate "ended" from "gave up" on the
|
|
246
|
+
// property rather than on the absence of one.
|
|
247
|
+
abortReason: null
|
|
248
|
+
});
|
|
249
|
+
var reportSetupOutcome = (outcome) => reportSetupOutcomeWith(defaultDeps, outcome);
|
|
250
|
+
var reportSetupAbortWith = async (deps, reason, exitCode, keyCheck = "unknown") => emit(deps, {
|
|
251
|
+
agents: [],
|
|
252
|
+
connectMode: recordedOptions?.connectMode ?? null,
|
|
253
|
+
connectOutcome: "skipped",
|
|
254
|
+
failedAgents: 0,
|
|
255
|
+
skippedAgents: [],
|
|
256
|
+
nonInteractive: recordedOptions?.nonInteractive ?? null,
|
|
257
|
+
keyCheck,
|
|
258
|
+
exitCode,
|
|
259
|
+
abandonedAt: currentStep,
|
|
260
|
+
abortReason: reason
|
|
261
|
+
});
|
|
262
|
+
var reportSetupAbort = (reason, exitCode, keyCheck) => reportSetupAbortWith(defaultDeps, reason, exitCode, keyCheck);
|
|
235
263
|
|
|
236
264
|
// src/setup/options.ts
|
|
237
265
|
var AGENT_CHOICES = ["claude_code", "codex", "gemini_cli", "hermes", "cursor", "custom"];
|
|
@@ -333,6 +361,10 @@ var green = (s) => `\x1B[32m${s}\x1B[0m`;
|
|
|
333
361
|
var cyan = (s) => `\x1B[36m${s}\x1B[0m`;
|
|
334
362
|
var yellow = (s) => `\x1B[33m${s}\x1B[0m`;
|
|
335
363
|
var check = green("\u2713");
|
|
364
|
+
var abortWith = async (reason, code, keyCheck) => {
|
|
365
|
+
await reportSetupAbort(reason, code, keyCheck);
|
|
366
|
+
return code;
|
|
367
|
+
};
|
|
336
368
|
var readKeyFromStdin = async (options) => {
|
|
337
369
|
if (!options.keyStdin) return void 0;
|
|
338
370
|
const chunks = [];
|
|
@@ -341,14 +373,14 @@ var readKeyFromStdin = async (options) => {
|
|
|
341
373
|
if (!first) {
|
|
342
374
|
console.log(`
|
|
343
375
|
${yellow("!")} --key-stdin was passed but stdin was empty.`);
|
|
344
|
-
process.exit(
|
|
376
|
+
process.exit(EXIT.USAGE);
|
|
345
377
|
}
|
|
346
378
|
if (!isValidApiKey(first)) {
|
|
347
379
|
console.log(`
|
|
348
380
|
${yellow("!")} The key on stdin is not a valid Pushary key. Expected: ${dim("pk_xxx.xxx")}`);
|
|
349
381
|
console.log(` ${dim("Copy your key from")} ${cyan("https://pushary.com/dashboard/agent/settings")}
|
|
350
382
|
`);
|
|
351
|
-
process.exit(
|
|
383
|
+
process.exit(EXIT.USAGE);
|
|
352
384
|
}
|
|
353
385
|
return first;
|
|
354
386
|
};
|
|
@@ -971,7 +1003,7 @@ var verifyKeyOrExit = async (apiKey, options, precomputed) => {
|
|
|
971
1003
|
console.log(` ${yellow("!")} ${report.message}`);
|
|
972
1004
|
for (const line of report.next) console.log(` ${dim(line)}`);
|
|
973
1005
|
console.log();
|
|
974
|
-
process.exit(report.exitCode);
|
|
1006
|
+
process.exit(await abortWith("key-refused", report.exitCode, result.kind));
|
|
975
1007
|
}
|
|
976
1008
|
if (result.kind === "ok") {
|
|
977
1009
|
const { siteSlug, siteName, plan } = result.identity;
|
|
@@ -982,6 +1014,19 @@ var verifyKeyOrExit = async (apiKey, options, precomputed) => {
|
|
|
982
1014
|
}
|
|
983
1015
|
return result;
|
|
984
1016
|
};
|
|
1017
|
+
var printPairingEscape = () => {
|
|
1018
|
+
console.log();
|
|
1019
|
+
console.log(` ${yellow("!")} No app? Two ways to finish without one:`);
|
|
1020
|
+
console.log();
|
|
1021
|
+
console.log(` ${cyan("npx @pushary/agent-hooks setup --connect browser")}`);
|
|
1022
|
+
console.log(` ${dim("Approve in a browser tab. No phone needed.")}`);
|
|
1023
|
+
console.log();
|
|
1024
|
+
console.log(` ${cyan("npx @pushary/agent-hooks setup --key pk_...")}`);
|
|
1025
|
+
console.log(` ${dim("Paste a key from")} ${cyan("pushary.com/dashboard/agent/settings")}`);
|
|
1026
|
+
console.log();
|
|
1027
|
+
console.log(` ${dim("Or get the app at")} ${cyan("https://pushary.com/download")} ${dim("and re-run setup.")}`);
|
|
1028
|
+
console.log();
|
|
1029
|
+
};
|
|
985
1030
|
var usableStoredKey = async (apiKey) => {
|
|
986
1031
|
let result;
|
|
987
1032
|
try {
|
|
@@ -1041,7 +1086,7 @@ var resolveAgents = async (options) => {
|
|
|
1041
1086
|
console.log(` ${yellow("!")} No agents detected, so nothing was configured. Your key is saved.`);
|
|
1042
1087
|
console.log(` ${dim("Install an agent and re-run, name one with --agents <id>, or pass --agents none to accept this.")}`);
|
|
1043
1088
|
console.log();
|
|
1044
|
-
process.exit(EXIT.PROBLEMS_FOUND);
|
|
1089
|
+
process.exit(await abortWith("no-agents-detected", EXIT.PROBLEMS_FOUND));
|
|
1045
1090
|
}
|
|
1046
1091
|
console.log(` ${check} Selected automatically: ${picked.map((a) => AGENT_NAMES[a]).join(", ")} ${dim("(--agents to choose)")}`);
|
|
1047
1092
|
return picked;
|
|
@@ -1112,6 +1157,7 @@ var main = async () => {
|
|
|
1112
1157
|
`);
|
|
1113
1158
|
process.exit(EXIT.OK);
|
|
1114
1159
|
}
|
|
1160
|
+
recordSetupOptions(options);
|
|
1115
1161
|
if (options.json) {
|
|
1116
1162
|
humanStream = process.stderr;
|
|
1117
1163
|
setHumanStream(process.stderr);
|
|
@@ -1126,6 +1172,7 @@ var main = async () => {
|
|
|
1126
1172
|
console.log(` ${dim("Push notifications for AI agents")}`);
|
|
1127
1173
|
console.log();
|
|
1128
1174
|
await checkForUpdates(version);
|
|
1175
|
+
markStep("resolve-key");
|
|
1129
1176
|
const connectMode = options.connectMode;
|
|
1130
1177
|
const flagKey = await readKeyFromStdin(options) ?? options.key ?? void 0;
|
|
1131
1178
|
const envKey = process.env.PUSHARY_API_KEY?.trim();
|
|
@@ -1160,18 +1207,18 @@ var main = async () => {
|
|
|
1160
1207
|
}
|
|
1161
1208
|
} else if (connectMode === "app" && canRunBrowserLogin() && !options.skipPhone) {
|
|
1162
1209
|
console.log(` ${dim("Pairing with your Pushary app.")}`);
|
|
1163
|
-
console.log(` ${dim("No app?
|
|
1210
|
+
console.log(` ${dim("No app? Ctrl-C, then:")} ${cyan("npx @pushary/agent-hooks setup --connect browser")}`);
|
|
1211
|
+
markStep("pair");
|
|
1164
1212
|
const previous = readKeySource();
|
|
1165
|
-
const paired = await connectViaAppPairing(
|
|
1213
|
+
const paired = await connectViaAppPairing({
|
|
1214
|
+
onCancelled: async () => {
|
|
1215
|
+
printPairingEscape();
|
|
1216
|
+
await reportSetupAbort("pairing-cancelled", 130);
|
|
1217
|
+
}
|
|
1218
|
+
});
|
|
1166
1219
|
if (!paired) {
|
|
1167
|
-
|
|
1168
|
-
|
|
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);
|
|
1220
|
+
printPairingEscape();
|
|
1221
|
+
process.exit(await abortWith("pairing-cancelled", EXIT.NOT_CONFIGURED));
|
|
1175
1222
|
}
|
|
1176
1223
|
trimmedKey = paired.apiKey;
|
|
1177
1224
|
keyFromPairing = true;
|
|
@@ -1188,8 +1235,9 @@ var main = async () => {
|
|
|
1188
1235
|
console.log(` ${dim("Pass --key <pk_xxx.xxx>, or --key-stdin, or export PUSHARY_API_KEY.")}`);
|
|
1189
1236
|
console.log(` ${dim("On a machine with a terminal, run")} ${cyan("pushary login")} ${dim("once and re-run this.")}`);
|
|
1190
1237
|
console.log();
|
|
1191
|
-
process.exit(EXIT.NOT_CONFIGURED);
|
|
1238
|
+
process.exit(await abortWith("no-key", EXIT.NOT_CONFIGURED));
|
|
1192
1239
|
} else {
|
|
1240
|
+
markStep("browser-login");
|
|
1193
1241
|
const outcome = await runBrowserLogin(
|
|
1194
1242
|
{ say: (line) => console.log(line), bold, dim, cyan, yellow },
|
|
1195
1243
|
{ cliVersion: version }
|
|
@@ -1203,7 +1251,7 @@ var main = async () => {
|
|
|
1203
1251
|
console.log();
|
|
1204
1252
|
console.log(` ${yellow("!")} That request was rejected in the browser. Nothing was written.`);
|
|
1205
1253
|
console.log();
|
|
1206
|
-
process.exit(EXIT.NOT_CONFIGURED);
|
|
1254
|
+
process.exit(await abortWith("login-rejected", EXIT.NOT_CONFIGURED));
|
|
1207
1255
|
} else {
|
|
1208
1256
|
console.log();
|
|
1209
1257
|
if (outcome.kind === "unavailable") {
|
|
@@ -1224,15 +1272,19 @@ var main = async () => {
|
|
|
1224
1272
|
console.log(` ${dim("Copy your key from")} ${cyan("https://pushary.com/dashboard/agent/settings")}`);
|
|
1225
1273
|
console.log(` ${dim("Or sign up at")} ${cyan("https://pushary.com/sign-up?from=ai-coding")}
|
|
1226
1274
|
`);
|
|
1227
|
-
process.exit(EXIT.USAGE);
|
|
1275
|
+
process.exit(await abortWith("invalid-key", EXIT.USAGE));
|
|
1228
1276
|
}
|
|
1277
|
+
recordSetupKey(trimmedKey);
|
|
1278
|
+
markStep("verify-key");
|
|
1229
1279
|
const keyCheck = keyFromPairing ? null : await verifyKeyOrExit(trimmedKey, options, storedKeyCheck ?? void 0);
|
|
1280
|
+
markStep("resolve-agents");
|
|
1230
1281
|
const agents = await resolveAgents(options);
|
|
1231
1282
|
if (options.dryRun) {
|
|
1232
1283
|
reportDryRun(trimmedKey, agents, keyCheck);
|
|
1233
1284
|
emitJson(options, { ok: true, dryRun: true, agents, keyCheck: keyCheck?.kind ?? "skipped" });
|
|
1234
1285
|
process.exit(EXIT.OK);
|
|
1235
1286
|
}
|
|
1287
|
+
markStep("save-key");
|
|
1236
1288
|
const rc = await saveApiKey(trimmedKey);
|
|
1237
1289
|
const context = { rc };
|
|
1238
1290
|
const failed = [];
|
|
@@ -1244,6 +1296,7 @@ var main = async () => {
|
|
|
1244
1296
|
console.log(` ${dim("Run setup again with --agents <id> when you want one wired up.")}`);
|
|
1245
1297
|
} else {
|
|
1246
1298
|
for (const agent of agents) {
|
|
1299
|
+
markStep(`configure:${agent}`);
|
|
1247
1300
|
try {
|
|
1248
1301
|
const outcome = await AGENT_SETUP[agent](trimmedKey, context);
|
|
1249
1302
|
if (outcome === "skipped") skipped.push(agent);
|
|
@@ -1262,11 +1315,13 @@ var main = async () => {
|
|
|
1262
1315
|
console.log();
|
|
1263
1316
|
console.log(` ${yellow("!")} Failed: ${failed.join(", ")} ${dim("(others completed successfully)")}`);
|
|
1264
1317
|
}
|
|
1318
|
+
markStep("project-instructions");
|
|
1265
1319
|
await offerProjectInstructions(agents, options);
|
|
1266
1320
|
if (completed.includes("claude_code")) {
|
|
1267
1321
|
await offerClaudeAlias(options);
|
|
1268
1322
|
}
|
|
1269
1323
|
}
|
|
1324
|
+
markStep("connect-phone");
|
|
1270
1325
|
const skipPhone = options.skipPhone;
|
|
1271
1326
|
let phone = null;
|
|
1272
1327
|
if (keyCheck?.kind === "locked") {
|
|
@@ -1304,6 +1359,15 @@ var main = async () => {
|
|
|
1304
1359
|
rc: rc.kind,
|
|
1305
1360
|
exitCode: report.exitCode
|
|
1306
1361
|
});
|
|
1362
|
+
await reportSetupOutcome({
|
|
1363
|
+
options,
|
|
1364
|
+
completed,
|
|
1365
|
+
skipped,
|
|
1366
|
+
failed,
|
|
1367
|
+
connectOutcome: "skipped",
|
|
1368
|
+
keyCheck: "locked",
|
|
1369
|
+
exitCode: report.exitCode
|
|
1370
|
+
});
|
|
1307
1371
|
process.exit(report.exitCode);
|
|
1308
1372
|
}
|
|
1309
1373
|
printManualSteps();
|
|
@@ -1311,6 +1375,7 @@ var main = async () => {
|
|
|
1311
1375
|
const agentsOk = failed.length === 0 && !configuredNothing;
|
|
1312
1376
|
const reachChecked = phone !== null;
|
|
1313
1377
|
const reachesYou = phone?.reachesYou ?? true;
|
|
1378
|
+
markStep("closing");
|
|
1314
1379
|
const closing = describeClosing({
|
|
1315
1380
|
agentsOk,
|
|
1316
1381
|
configuredNothing,
|
|
@@ -1365,7 +1430,7 @@ var main = async () => {
|
|
|
1365
1430
|
process.exit(exitCode);
|
|
1366
1431
|
}
|
|
1367
1432
|
};
|
|
1368
|
-
main().catch((err) => {
|
|
1433
|
+
main().catch(async (err) => {
|
|
1369
1434
|
if (err instanceof UsageError) {
|
|
1370
1435
|
console.log();
|
|
1371
1436
|
console.log(` ${yellow("!")} ${err.message}`);
|
|
@@ -1377,11 +1442,11 @@ main().catch((err) => {
|
|
|
1377
1442
|
console.log();
|
|
1378
1443
|
console.log(` ${dim("Cancelled. Nothing further was changed.")}`);
|
|
1379
1444
|
console.log();
|
|
1380
|
-
process.exit(130);
|
|
1445
|
+
process.exit(await abortWith("interrupted", 130));
|
|
1381
1446
|
}
|
|
1382
1447
|
console.log();
|
|
1383
1448
|
console.log(` ${yellow("!")} Setup failed: ${formatError(err)}`);
|
|
1384
1449
|
console.log(` ${dim("Run")} ${cyan("npx @pushary/agent-hooks doctor")} ${dim("after fixing the issue, then rerun setup.")}`);
|
|
1385
1450
|
console.log();
|
|
1386
|
-
process.exit(
|
|
1451
|
+
process.exit(await abortWith("crashed", EXIT.FAILED));
|
|
1387
1452
|
});
|
|
@@ -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,7 +520,8 @@ var connectViaAppPairing = async () => {
|
|
|
520
520
|
const onInterrupt = () => {
|
|
521
521
|
cancelled = true;
|
|
522
522
|
stop(yellow("!"), "Cancelled");
|
|
523
|
-
|
|
523
|
+
const flushed = options.onCancelled?.();
|
|
524
|
+
void Promise.allSettled([Promise.resolve(flushed), cancelPairing(pairId)]).finally(() => process.exit(EXIT_ABORTED));
|
|
524
525
|
};
|
|
525
526
|
process.once("SIGINT", onInterrupt);
|
|
526
527
|
try {
|
|
@@ -928,7 +928,7 @@ ${injected}` : injected;
|
|
|
928
928
|
};
|
|
929
929
|
var detectInstallMode = () => (process.argv[1] ?? "").includes("_npx") ? "npx" : "cli";
|
|
930
930
|
var reportEvent = async (event, options = {}) => {
|
|
931
|
-
const apiKey = getApiKey();
|
|
931
|
+
const apiKey = options.apiKey ?? getApiKey();
|
|
932
932
|
const baseUrl = getBaseUrl();
|
|
933
933
|
return withRetry(async () => {
|
|
934
934
|
const res = await fetch(`${baseUrl}/api/agent/event`, {
|
package/dist/src/index.d.ts
CHANGED
|
@@ -73,6 +73,16 @@ interface AgentEvent {
|
|
|
73
73
|
interface ReportEventOptions {
|
|
74
74
|
maxAttempts?: number;
|
|
75
75
|
timeoutMs?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Authenticate with this key instead of the ambient one.
|
|
78
|
+
*
|
|
79
|
+
* getApiKey() reads the environment and ~/.pushary/config.json, so it can only
|
|
80
|
+
* ever speak for a key that is already installed. setup resolves a key minutes
|
|
81
|
+
* before it writes one, and its abort beacons run inside that window: without
|
|
82
|
+
* an override they post as nobody, so the runs that fail before saveApiKey are
|
|
83
|
+
* exactly the runs that cannot report failing.
|
|
84
|
+
*/
|
|
85
|
+
apiKey?: string;
|
|
76
86
|
}
|
|
77
87
|
interface EventResponse {
|
|
78
88
|
readonly ok?: boolean;
|
package/dist/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handlePreToolUse
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-SONXGCZY.js";
|
|
4
4
|
import "../chunk-CAJZAFVS.js";
|
|
5
5
|
import "../chunk-YHG74UFF.js";
|
|
6
6
|
import {
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
reportEvent,
|
|
16
16
|
resolvePolicy,
|
|
17
17
|
waitForAnswer
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-XOUYM27W.js";
|
|
19
19
|
import "../chunk-WLGEY4UX.js";
|
|
20
20
|
import "../chunk-BSZYIAZL.js";
|
|
21
21
|
import "../chunk-SAF6HGAA.js";
|