@pushary/agent-hooks 0.67.1 → 0.68.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.
@@ -6,7 +6,7 @@ import {
6
6
  confirmAppConnection,
7
7
  connectDevice,
8
8
  printConnectInstructions
9
- } from "../chunk-V6OA4VPU.js";
9
+ } from "../chunk-YMFZUXL5.js";
10
10
  import "../chunk-3EGEA4KH.js";
11
11
  import {
12
12
  readKeySource
@@ -35,7 +35,7 @@ import {
35
35
  describeReach,
36
36
  fetchChannels,
37
37
  reachVerdict
38
- } from "../chunk-V6OA4VPU.js";
38
+ } from "../chunk-YMFZUXL5.js";
39
39
  import "../chunk-3EGEA4KH.js";
40
40
  import {
41
41
  keyPrefix,
@@ -48,7 +48,7 @@ import {
48
48
  connectViaAppPairing,
49
49
  printConnectInstructions,
50
50
  setHumanStream
51
- } from "../chunk-V6OA4VPU.js";
51
+ } from "../chunk-YMFZUXL5.js";
52
52
  import "../chunk-3EGEA4KH.js";
53
53
  import {
54
54
  KEY_FILE_MODE,
@@ -7,7 +7,7 @@ import {
7
7
  describeReach,
8
8
  fetchChannels,
9
9
  reachVerdict
10
- } from "../chunk-V6OA4VPU.js";
10
+ } from "../chunk-YMFZUXL5.js";
11
11
  import "../chunk-3EGEA4KH.js";
12
12
  import {
13
13
  readKeySource
@@ -266,6 +266,29 @@ var writeStatusLine = (text) => {
266
266
  ` : ` ${text}
267
267
  `);
268
268
  };
269
+ var visibleLength = (text) => text.replace(/\x1b\[[0-9;]*m/g, "").length;
270
+ var clipToRow = (text, columns) => {
271
+ const budget = columns - 4;
272
+ if (budget <= 1 || visibleLength(text) <= budget) return text;
273
+ let visible = 0;
274
+ let out = "";
275
+ for (let i = 0; i < text.length; i += 1) {
276
+ const escape = /^\x1b\[[0-9;]*m/.exec(text.slice(i));
277
+ if (escape) {
278
+ out += escape[0];
279
+ i += escape[0].length - 1;
280
+ continue;
281
+ }
282
+ if (visible >= budget - 1) break;
283
+ out += text[i];
284
+ visible += 1;
285
+ }
286
+ return `${out}\u2026`;
287
+ };
288
+ var terminalColumns = () => {
289
+ const columns = process.stdout.columns;
290
+ return typeof columns === "number" && columns > 0 ? columns : 80;
291
+ };
269
292
  var startSpinner = (getLabel) => {
270
293
  if (!humanIsTty()) {
271
294
  writeHuman(` ${getLabel()}
@@ -283,7 +306,8 @@ var startSpinner = (getLabel) => {
283
306
  const frames = [" ", ". ", ".. ", "..."];
284
307
  let i = 0;
285
308
  const interval = setInterval(() => {
286
- writeHuman(`\r ${dim(frames[i++ % frames.length])} ${getLabel()}`);
309
+ const line = `${dim(frames[i++ % frames.length])} ${getLabel()}`;
310
+ writeHuman(`\r ${clipToRow(line, terminalColumns())}\x1B[K`);
287
311
  }, SPINNER_FRAME_MS);
288
312
  return (finalGlyph, finalLabel) => {
289
313
  clearInterval(interval);
@@ -338,6 +362,8 @@ var waitForDevice = async (apiKey, baseline) => {
338
362
  await sleep(CONNECT_POLL_INTERVAL_MS);
339
363
  }
340
364
  stop(yellow("!"), "Didn't detect a connection yet");
365
+ console.log(` ${dim("Signed in on the app already? Open it and allow notifications.")}`);
366
+ console.log(` ${dim("Signing in alone does not connect the phone. Then run")} ${cyan("pushary doctor")}${dim(".")}`);
341
367
  return { kind: "timeout" };
342
368
  } catch (err) {
343
369
  stop(yellow("!"), `Couldn't check connection ${dim(`(${err instanceof Error ? err.message : "network error"})`)}`);
@@ -484,6 +510,18 @@ var startPairing = async (cliPublicKey) => {
484
510
  return null;
485
511
  }
486
512
  };
513
+ var describePairFailure = (reason) => {
514
+ switch (reason) {
515
+ case "no_site":
516
+ return "Couldn't set up your workspace. Try again, or finish setup at pushary.com/dashboard";
517
+ case "blocked":
518
+ return "Finish setting up in the Pushary app, then run setup again";
519
+ case "authorize_failed":
520
+ return "The app could not authorize this terminal. Re-run setup to try again";
521
+ default:
522
+ return "Pairing failed. Re-run setup to try again";
523
+ }
524
+ };
487
525
  var cancelPairing = async (pairId) => {
488
526
  try {
489
527
  await fetch(`${apiBase()}/api/mobile/pair/start`, {
@@ -533,12 +571,19 @@ var connectViaAppPairing = async (options = {}) => {
533
571
  console.log();
534
572
  const startedAt = Date.now();
535
573
  const deadline = startedAt + PAIR_TIMEOUT_MS;
574
+ let hintShown = false;
536
575
  const stop = startSpinner(() => {
537
576
  const left = Math.max(0, Math.ceil((deadline - Date.now()) / 6e4));
538
577
  if (Date.now() - startedAt < PAIR_HINT_AFTER_MS) {
539
578
  return "Waiting for the app to authorize";
540
579
  }
541
- return `Waiting for the app ${dim(`(${left}m left. No app yet? Install it, sign in with this account, then scan. Ctrl-C to stop)`)}`;
580
+ if (!hintShown) {
581
+ hintShown = true;
582
+ writeStatusLine(
583
+ `${dim("No app yet? Install it, sign in with this account, then scan. Ctrl-C to stop.")}`
584
+ );
585
+ }
586
+ return `Waiting for the app ${dim(`(${left}m left)`)}`;
542
587
  });
543
588
  let cancelled = false;
544
589
  const onInterrupt = () => {
@@ -568,6 +613,10 @@ var connectViaAppPairing = async (options = {}) => {
568
613
  stop(yellow("!"), "Pairing expired \u2014 re-run setup to try again");
569
614
  return null;
570
615
  }
616
+ if (claim?.status === "failed") {
617
+ stop(yellow("!"), describePairFailure(claim.reason));
618
+ return null;
619
+ }
571
620
  await sleep(PAIR_POLL_INTERVAL_MS);
572
621
  }
573
622
  stop(yellow("!"), "Timed out waiting for the app");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "0.67.1",
3
+ "version": "0.68.0",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",