@pushary/agent-hooks 1.9.34 → 1.9.35
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,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.35
|
|
4
|
+
|
|
5
|
+
- When you run setup yourself in a terminal and your phone cannot get notifications yet, it no longer stops with exit code 6. It asks you to open the Pushary app and allow notifications, waits up to 10 minutes for your phone, then sends a test notification. Press Enter to skip the wait. Runs with `--yes`, `--agents` or `--json`, and computers with the Pushary Mac app, keep the single check.
|
|
6
|
+
|
|
3
7
|
## 1.9.34
|
|
4
8
|
|
|
5
9
|
- Live questions keep waiting when a tool poll ends; agent instructions no longer cancel them after one retry.
|
|
@@ -129,8 +129,9 @@ import {
|
|
|
129
129
|
pairingEscapeApplies,
|
|
130
130
|
printConnectInstructions,
|
|
131
131
|
roundTripEvidence,
|
|
132
|
-
verifyRoundTrip
|
|
133
|
-
|
|
132
|
+
verifyRoundTrip,
|
|
133
|
+
waitForYourPhone
|
|
134
|
+
} from "../chunk-43H2FUNN.js";
|
|
134
135
|
import "../chunk-3EGEA4KH.js";
|
|
135
136
|
import {
|
|
136
137
|
setHumanStream
|
|
@@ -325,6 +326,20 @@ import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
|
|
|
325
326
|
// src/cli/exit.ts
|
|
326
327
|
var isExitPromptError = (err) => err instanceof Error && (err.name === "ExitPromptError" || err.message.includes("User force closed") || /force closed the prompt/i.test(err.message));
|
|
327
328
|
|
|
329
|
+
// src/cli/enter-key.ts
|
|
330
|
+
var enterKeyListener = (input2 = process.stdin) => {
|
|
331
|
+
if (input2.isTTY !== true) return null;
|
|
332
|
+
return (onEnter) => {
|
|
333
|
+
const onLine = () => onEnter();
|
|
334
|
+
input2.on("data", onLine);
|
|
335
|
+
input2.resume();
|
|
336
|
+
return () => {
|
|
337
|
+
input2.off("data", onLine);
|
|
338
|
+
input2.pause();
|
|
339
|
+
};
|
|
340
|
+
};
|
|
341
|
+
};
|
|
342
|
+
|
|
328
343
|
// ../contracts/src/billing.ts
|
|
329
344
|
var PARTNER_SELF_SERVE_PLANS = ["partner_launch", "partner_growth", "partner_scale"];
|
|
330
345
|
var PARTNER_PLAN_TYPES = ["partner", ...PARTNER_SELF_SERVE_PLANS];
|
|
@@ -602,7 +617,7 @@ var planPhoneCheck = (context) => {
|
|
|
602
617
|
if (context.verify === "none") return "verify-none";
|
|
603
618
|
if (!context.stdoutIsTty) return "instructions";
|
|
604
619
|
if (context.paired) return "confirm-pairing";
|
|
605
|
-
if (context.connectMode === "app") return "reuse-app";
|
|
620
|
+
if (context.connectMode === "app") return context.interactive && !context.macAppInstalled ? "wait-for-app" : "reuse-app";
|
|
606
621
|
return "connect";
|
|
607
622
|
};
|
|
608
623
|
|
|
@@ -2765,7 +2780,9 @@ var main = async () => {
|
|
|
2765
2780
|
verify: verifyMode,
|
|
2766
2781
|
stdoutIsTty: process.stdout.isTTY === true,
|
|
2767
2782
|
paired: keyFromPairing,
|
|
2768
|
-
connectMode
|
|
2783
|
+
connectMode,
|
|
2784
|
+
interactive: !options.nonInteractive,
|
|
2785
|
+
macAppInstalled: appBridgeAvailable
|
|
2769
2786
|
});
|
|
2770
2787
|
switch (phoneCheck) {
|
|
2771
2788
|
case "unverified":
|
|
@@ -2793,6 +2810,11 @@ var main = async () => {
|
|
|
2793
2810
|
case "reuse-app":
|
|
2794
2811
|
phone = await printConnectInstructions(trimmedKey);
|
|
2795
2812
|
break;
|
|
2813
|
+
case "wait-for-app": {
|
|
2814
|
+
const skip = enterKeyListener();
|
|
2815
|
+
phone = skip === null ? await printConnectInstructions(trimmedKey) : await waitForYourPhone(trimmedKey, { skip });
|
|
2816
|
+
break;
|
|
2817
|
+
}
|
|
2796
2818
|
case "connect":
|
|
2797
2819
|
phone = await connectDevice(trimmedKey, { showCapabilities: !options.connectExplicit });
|
|
2798
2820
|
break;
|
|
@@ -950,6 +950,80 @@ var connectViaAppPairing = async (options = {}) => {
|
|
|
950
950
|
process.off("SIGTERM", onTerminate);
|
|
951
951
|
}
|
|
952
952
|
};
|
|
953
|
+
var PHONE_WAIT_TIMEOUT_MS = 10 * 6e4;
|
|
954
|
+
var PHONE_WAIT_SKIP_LINE = "Press Enter to skip. Setup finishes without the phone check.";
|
|
955
|
+
var describePhoneWait = (skipOffered) => [
|
|
956
|
+
bold("Connect your phone"),
|
|
957
|
+
"Open the Pushary app on your phone and allow notifications.",
|
|
958
|
+
dim("Sign in with the same account you use here. No app yet? Get it at pushary.com/download"),
|
|
959
|
+
...skipOffered ? [dim(PHONE_WAIT_SKIP_LINE)] : []
|
|
960
|
+
];
|
|
961
|
+
var watchSkip = (listener) => {
|
|
962
|
+
let skipped = false;
|
|
963
|
+
let wake = () => {
|
|
964
|
+
};
|
|
965
|
+
const woken = new Promise((resolve) => {
|
|
966
|
+
wake = resolve;
|
|
967
|
+
});
|
|
968
|
+
const stop = listener?.(() => {
|
|
969
|
+
skipped = true;
|
|
970
|
+
wake();
|
|
971
|
+
}) ?? (() => {
|
|
972
|
+
});
|
|
973
|
+
return { skipped: () => skipped, woken, stop };
|
|
974
|
+
};
|
|
975
|
+
var PHONE_WAIT_REPAIR_LINE = `Open the Pushary app, sign in with the same account, and allow notifications. Then run ${NPX_LATEST_COMMAND} doctor.`;
|
|
976
|
+
var phoneWaitRepair = (verdict) => verdict.kind === "nobody" ? [PHONE_WAIT_REPAIR_LINE] : describeAppRepair(verdict) ?? [];
|
|
977
|
+
var pollForYourPhone = async (apiKey, firstSeen, options) => {
|
|
978
|
+
const clock = options.clock ?? SYSTEM_PAIR_CLOCK;
|
|
979
|
+
const deadline = clock.now() + PHONE_WAIT_TIMEOUT_MS;
|
|
980
|
+
const skip = watchSkip(options.skip);
|
|
981
|
+
const minutesLeft = () => Math.max(0, Math.ceil((deadline - clock.now()) / 6e4));
|
|
982
|
+
const stop = startSpinner(() => `Waiting for your phone ${dim(`(${minutesLeft()}m left)`)}`);
|
|
983
|
+
let lastSeen = firstSeen;
|
|
984
|
+
try {
|
|
985
|
+
while (clock.now() < deadline && !skip.skipped()) {
|
|
986
|
+
const probe = await fetchChannels(apiKey);
|
|
987
|
+
if (probe.kind === "unauthorized") {
|
|
988
|
+
stop(yellow("!"), "The server stopped accepting this key");
|
|
989
|
+
return { kind: "unauthorized" };
|
|
990
|
+
}
|
|
991
|
+
if (probe.kind === "locked") {
|
|
992
|
+
stop(yellow("!"), "This workspace has no active plan");
|
|
993
|
+
return { kind: "locked" };
|
|
994
|
+
}
|
|
995
|
+
if (probe.kind === "ok") {
|
|
996
|
+
lastSeen = probe.status;
|
|
997
|
+
if (reachesYou(probe.status)) {
|
|
998
|
+
stop(check, "Phone connected");
|
|
999
|
+
return { kind: "connected", channels: probe.status };
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
await Promise.race([clock.sleep(CONNECT_POLL_INTERVAL_MS), skip.woken]);
|
|
1003
|
+
}
|
|
1004
|
+
stop(yellow("!"), skip.skipped() ? "Skipped the phone check" : "No phone connected yet");
|
|
1005
|
+
return { kind: "not_yet", lastSeen };
|
|
1006
|
+
} finally {
|
|
1007
|
+
skip.stop();
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
var waitForYourPhone = async (apiKey, options = {}) => {
|
|
1011
|
+
const probe = await fetchChannels(apiKey);
|
|
1012
|
+
if (probe.kind !== "ok") return describeProbeFailure(probe);
|
|
1013
|
+
if (reachesYou(probe.status)) {
|
|
1014
|
+
console.log(` ${check} ${describeExistingConnection(probe.status)}`);
|
|
1015
|
+
return sendAndConfirm(apiKey, probe.status);
|
|
1016
|
+
}
|
|
1017
|
+
console.log();
|
|
1018
|
+
for (const line of describePhoneWait(options.skip !== void 0)) console.log(` ${line}`);
|
|
1019
|
+
console.log();
|
|
1020
|
+
const waited = await pollForYourPhone(apiKey, probe.status, options);
|
|
1021
|
+
if (waited.kind === "connected") return sendAndConfirm(apiKey, waited.channels);
|
|
1022
|
+
if (waited.kind === "unauthorized" || waited.kind === "locked") return describeProbeFailure(waited);
|
|
1023
|
+
const repair = phoneWaitRepair(reachVerdict(waited.lastSeen));
|
|
1024
|
+
for (const line of repair) console.log(` ${dim(line)}`);
|
|
1025
|
+
return phoneFailure("no_device", repair);
|
|
1026
|
+
};
|
|
953
1027
|
|
|
954
1028
|
export {
|
|
955
1029
|
reachVerdict,
|
|
@@ -965,5 +1039,6 @@ export {
|
|
|
965
1039
|
printConnectInstructions,
|
|
966
1040
|
BROWSER_CONNECT_COMMAND,
|
|
967
1041
|
pairingEscapeApplies,
|
|
968
|
-
connectViaAppPairing
|
|
1042
|
+
connectViaAppPairing,
|
|
1043
|
+
waitForYourPhone
|
|
969
1044
|
};
|