@pushary/agent-hooks 1.9.7 → 1.9.8

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.
Files changed (110) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +3 -3
  3. package/data/cursor-plugin/README.md +3 -7
  4. package/data/vscode-plugin/README.md +1 -1
  5. package/dist/bin/pushary-bell-hook.js +22 -23
  6. package/dist/bin/pushary-bell.js +9 -9
  7. package/dist/bin/pushary-claude.js +27 -28
  8. package/dist/bin/pushary-clean.js +101 -79
  9. package/dist/bin/pushary-codex-bridge.js +18 -18
  10. package/dist/bin/pushary-codex-hook.js +32 -33
  11. package/dist/bin/pushary-codex.js +13 -13
  12. package/dist/bin/pushary-connect.js +24 -21
  13. package/dist/bin/pushary-cowork.js +5 -5
  14. package/dist/bin/pushary-daemon.js +51 -39
  15. package/dist/bin/pushary-disconnect.js +189 -54
  16. package/dist/bin/pushary-doctor.js +67 -58
  17. package/dist/bin/pushary-elicitation-hook.js +24 -25
  18. package/dist/bin/pushary-gemini-bridge.js +13 -13
  19. package/dist/bin/pushary-gemini-hook.js +29 -30
  20. package/dist/bin/pushary-hook.js +30 -32
  21. package/dist/bin/pushary-login.js +12 -12
  22. package/dist/bin/pushary-logout.js +105 -42
  23. package/dist/bin/pushary-mcp.js +9 -9
  24. package/dist/bin/pushary-mode.js +28 -31
  25. package/dist/bin/pushary-notification-hook.js +26 -28
  26. package/dist/bin/pushary-opencode-hook.js +28 -29
  27. package/dist/bin/pushary-permission-denied-hook.js +30 -32
  28. package/dist/bin/pushary-permission-hook.js +29 -31
  29. package/dist/bin/pushary-post-hook.js +26 -28
  30. package/dist/bin/pushary-prompt-hook.js +26 -28
  31. package/dist/bin/pushary-session-end-hook.js +26 -28
  32. package/dist/bin/pushary-session-start-hook.js +31 -32
  33. package/dist/bin/pushary-setup.js +91 -101
  34. package/dist/bin/pushary-stats.js +5 -5
  35. package/dist/bin/pushary-status.js +34 -18
  36. package/dist/bin/pushary-stop-hook.js +26 -28
  37. package/dist/bin/pushary-stopfailure-hook.js +26 -28
  38. package/dist/bin/pushary-suggestions.js +19 -21
  39. package/dist/bin/pushary-transcript-register.js +18 -19
  40. package/dist/bin/pushary-transcripts.js +7 -7
  41. package/dist/bin/pushary-upgrade.js +55 -25
  42. package/dist/bin/pushary-wait.js +23 -19
  43. package/dist/bin/pushary.js +15 -14
  44. package/dist/{chunk-R3YW55MY.js → chunk-2A53H4S6.js} +17 -15
  45. package/dist/{chunk-4YO4T5FV.js → chunk-2QGYMY7A.js} +83 -3
  46. package/dist/{chunk-MBK7N46B.js → chunk-2QTO5YIT.js} +6 -6
  47. package/dist/{chunk-D6S5EKXA.js → chunk-2VZAALEJ.js} +5 -9
  48. package/dist/chunk-2WXF3QJR.js +49 -0
  49. package/dist/{chunk-JCWZ23MJ.js → chunk-3I6IVOZV.js} +3 -3
  50. package/dist/chunk-3Z3A37WD.js +77 -0
  51. package/dist/{chunk-Z6HPS67T.js → chunk-5QUPKDI5.js} +1 -1
  52. package/dist/{chunk-JWKBDSPF.js → chunk-6TE27XZR.js} +2 -2
  53. package/dist/{chunk-STQRUH3S.js → chunk-7DVNSQWF.js} +59 -15
  54. package/dist/{chunk-QTO6HEZD.js → chunk-7PT35RY2.js} +2 -2
  55. package/dist/{chunk-7OIWWZAD.js → chunk-B64KHETR.js} +3 -3
  56. package/dist/chunk-BEJRK4DF.js +94 -0
  57. package/dist/chunk-BXET3ALR.js +46 -0
  58. package/dist/{chunk-6DJTDHBI.js → chunk-CD47ZFFZ.js} +1 -1
  59. package/dist/{chunk-UFVGSEWH.js → chunk-CKV3UPMU.js} +2 -2
  60. package/dist/{chunk-4FK6RZVJ.js → chunk-CLOSJ4ES.js} +1 -1
  61. package/dist/{chunk-AVNKVF7N.js → chunk-DKMD6AWR.js} +4 -4
  62. package/dist/{chunk-SBLPHUEB.js → chunk-DL7XWKYV.js} +7 -5
  63. package/dist/{chunk-BTQGAXZ3.js → chunk-DPGSLWOS.js} +8 -8
  64. package/dist/{chunk-KYO45G5L.js → chunk-DUZVXBBU.js} +1 -1
  65. package/dist/{chunk-EB4XGVBG.js → chunk-EUW7JL2K.js} +0 -32
  66. package/dist/{chunk-4D2AYNSE.js → chunk-FQ2GORVG.js} +2 -2
  67. package/dist/{chunk-W2KI5KPD.js → chunk-HRULIYDU.js} +2 -2
  68. package/dist/{chunk-QR6VE5ME.js → chunk-I5IJRMNV.js} +58 -8
  69. package/dist/{chunk-T7Y5EADL.js → chunk-I6MJXLMY.js} +2 -2
  70. package/dist/{chunk-N4EUSDKX.js → chunk-IAD2RT4L.js} +14 -14
  71. package/dist/{chunk-H37L7TT3.js → chunk-IHFDPV7C.js} +2 -2
  72. package/dist/{chunk-3GNUXXDZ.js → chunk-IHO3YQAN.js} +2 -2
  73. package/dist/{chunk-JWQZSYCK.js → chunk-KF3UZLYI.js} +1 -1
  74. package/dist/chunk-KFF7G225.js +599 -0
  75. package/dist/{chunk-MZPXVH4A.js → chunk-KHNFLYJO.js} +204 -28
  76. package/dist/{chunk-QFEM7R6T.js → chunk-KRCR2CRQ.js} +9 -9
  77. package/dist/{chunk-VXRXFU6Q.js → chunk-LKLVTG3V.js} +14 -7
  78. package/dist/{chunk-KFKL3FHS.js → chunk-LWOO567I.js} +4 -3
  79. package/dist/{chunk-HPRZJKRO.js → chunk-M6BZZFVQ.js} +1 -1
  80. package/dist/{chunk-X5NXPCIC.js → chunk-MFF3ONG5.js} +16 -2
  81. package/dist/{chunk-H7MMU64M.js → chunk-MGRFDGWU.js} +2 -2
  82. package/dist/{chunk-L76HTPU6.js → chunk-MKTJEXZ3.js} +3 -3
  83. package/dist/{chunk-NIBFSARF.js → chunk-MXHTGVFZ.js} +33 -9
  84. package/dist/{chunk-ADSQDYYG.js → chunk-N4QSPI3B.js} +54 -5
  85. package/dist/{chunk-AQ55ZSSS.js → chunk-NWDG3MSW.js} +1 -1
  86. package/dist/chunk-OP7IHC2I.js +24 -0
  87. package/dist/{chunk-KT5E2RLS.js → chunk-QOLITCIP.js} +1 -1
  88. package/dist/{chunk-JXISQ7DT.js → chunk-TCQ43LSG.js} +3 -3
  89. package/dist/chunk-TCWKTUAE.js +50 -0
  90. package/dist/{chunk-RQGODFQN.js → chunk-V5HPPF3E.js} +1 -1
  91. package/dist/{chunk-7264S5HZ.js → chunk-WG3K4TCH.js} +1 -1
  92. package/dist/{chunk-GKI6LFAV.js → chunk-WS4H76EP.js} +2 -2
  93. package/dist/{chunk-XWAYAO3V.js → chunk-WWOHTTVP.js} +2 -2
  94. package/dist/{chunk-SD3272LS.js → chunk-YIG2R3BJ.js} +9 -7
  95. package/dist/{chunk-ZUTU43FT.js → chunk-ZBHUHJG6.js} +4 -4
  96. package/dist/{chunk-AUUXS44H.js → chunk-ZBK6E2OR.js} +1 -1
  97. package/dist/{chunk-QQ4HBXZC.js → chunk-ZN3C6GBG.js} +84 -673
  98. package/dist/{chunk-CBQACHKY.js → chunk-ZSTSEBG7.js} +1 -1
  99. package/dist/{chunk-3PVDOCFI.js → chunk-ZW3XZLJC.js} +5 -5
  100. package/dist/{global-upgrade-E2HUEB4B.js → global-upgrade-I56HNM23.js} +6 -6
  101. package/dist/{paths-QVTEGNZV.js → paths-AGY43CXS.js} +2 -2
  102. package/dist/reapply-IA5XUKWW.js +57 -0
  103. package/dist/src/index.d.ts +1 -0
  104. package/dist/src/index.js +19 -20
  105. package/dist/{upgrade-lock-JCIDZMHF.js → upgrade-lock-B34TAUKV.js} +3 -3
  106. package/package.json +1 -1
  107. package/dist/chunk-ANEAA37E.js +0 -197
  108. package/dist/chunk-MNWRUGMH.js +0 -86
  109. package/dist/chunk-RQSOEB4S.js +0 -44
  110. package/dist/reapply-5QVKM6LA.js +0 -38
@@ -154,6 +154,7 @@ var AGENTS = {
154
154
  fx: {
155
155
  ...defaults,
156
156
  label: "fx",
157
+ disconnectable: true,
157
158
  connectVia: "Local MCP bridge",
158
159
  setupCommand: PUSHARY_SETUP_COMMAND,
159
160
  capabilityNote: "fx has no hooks that other tools can register, so Pushary cannot answer fx's own approval prompts. Setup turns off fx's terminal question tool so fx's agent asks through Pushary. fx's full-access mode ignores that setting; there the agent is only instructed to ask through Pushary."
@@ -196,7 +197,7 @@ var AGENTS = {
196
197
  connectVia: "Native hooks + MCP",
197
198
  setupCommand: PUSHARY_SETUP_COMMAND,
198
199
  enforcementDetail: "Shell, writes and edits through native PreToolUse hooks, plus PermissionRequest, over Qoder's superset of the Claude Code event list.",
199
- capabilityNote: "Qoder documents no user-level instructions file, so the proactive-ask block is not installed. Hooks and MCP are unaffected. Like every agent in this family, the CLI wires it; the macOS app does not yet."
200
+ capabilityNote: "Qoder documents no user-level instructions file, so the proactive-ask block is not installed. Hooks and MCP are unaffected."
200
201
  },
201
202
  droid: {
202
203
  ...defaults,
@@ -262,10 +263,24 @@ var POLICY_AGENTS = [...Object.values(AGENTS).flatMap((agent) => agent.policyAge
262
263
  var AGENT_LABELS_BY_TYPE = Object.fromEntries(
263
264
  Object.entries(AGENTS).flatMap(([id, agent]) => agent.hasStoredIdentity ? [[id, agent.label]] : [])
264
265
  );
265
- var DISCONNECTABLE_AGENTS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.disconnectable ? [agent.hookSource] : []));
266
+ var DISCONNECTABLE_AGENTS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.disconnectable && agent.hookSource !== null ? [agent.hookSource] : []));
266
267
  var REPO_AWARE_AGENTS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.repoAware ? [agent.policyAgent] : []));
267
268
  var MANAGED_PROVIDERS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.managedProvider ? [agent.hookSource] : []));
268
269
  var BRIDGE_HOOK_SOURCES = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.bridged ? [agent.hookSource] : []));
270
+ var isAgentId = (value) => Object.keys(AGENTS).includes(value);
271
+ var isHooklessDisconnectableAgent = (value) => isAgentId(value) && AGENTS[value].disconnectable && AGENTS[value].hookSource === null;
272
+ var DISCONNECT_AGENT_IDS = Object.freeze([...DISCONNECTABLE_AGENTS, ...Object.keys(AGENTS).filter(isHooklessDisconnectableAgent)]);
273
+ var agentIdCalled = (name) => isAgentId(name) ? name : Object.keys(AGENTS).filter(isAgentId).find((id) => AGENTS[id].hookSource === name) ?? null;
274
+ var namesOfAgent = (id) => {
275
+ const source = AGENTS[id].hookSource;
276
+ return source === null ? [id] : [id, source];
277
+ };
278
+ var normalizeAgentId = (value, accepted) => {
279
+ const name = value.trim().toLowerCase();
280
+ const agent = agentIdCalled(name);
281
+ const names = agent === null ? [name] : namesOfAgent(agent);
282
+ return accepted.find((candidate) => names.includes(candidate)) ?? null;
283
+ };
269
284
 
270
285
  // ../contracts/src/agent-wiring.ts
271
286
  var COMPATIBLE_AGENT_TYPES = ["qwen_code", "codebuddy", "qoder", "droid", "devin"];
@@ -718,6 +733,25 @@ var AUTH_REJECTION_REASONS = [
718
733
  ...AGENT_SITE_REJECTION_REASONS
719
734
  ];
720
735
 
736
+ // ../contracts/src/declined-agents.ts
737
+ var DECLINED_AGENTS_FILE = "declined-agents.json";
738
+ var DECLINED_AGENTS_VERSION = 1;
739
+ var isDeclinableAgent = (value) => typeof value === "string" && HOOK_SOURCES.includes(value);
740
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
741
+ var canonicalAgents = (agents) => [...new Set(agents)].sort();
742
+ var parseDeclinedAgents = (value) => {
743
+ if (!isRecord(value) || value.version !== DECLINED_AGENTS_VERSION || !Array.isArray(value.agents)) return [];
744
+ return canonicalAgents(value.agents.filter(isDeclinableAgent));
745
+ };
746
+ var declinedAgentsDocument = (agents) => ({
747
+ version: DECLINED_AGENTS_VERSION,
748
+ agents: canonicalAgents(agents)
749
+ });
750
+ var serializeDeclinedAgents = (agents) => `${JSON.stringify(declinedAgentsDocument(agents), null, 2)}
751
+ `;
752
+ var withDeclinedAgent = (agents, agent) => canonicalAgents([...agents, agent]);
753
+ var withoutDeclinedAgent = (agents, agent) => agents.filter((candidate) => candidate !== agent);
754
+
721
755
  // ../contracts/src/index.ts
722
756
  var KEY_SCOPES = ["full_access", "agent", "connector", "bound"];
723
757
  var normalizeKeyScope = (value) => typeof value === "string" && KEY_SCOPES.includes(value) ? value : null;
@@ -874,7 +908,7 @@ var CURSOR_GATE_EVENTS = ["beforeShellExecution", "beforeMCPExecution", "preTool
874
908
  var SUPPORT_EMAIL = "business@pushary.com";
875
909
  var SUPPORT_DISCORD = "https://discord.gg/9v3VvUByrr";
876
910
  var HOOK_LOCATOR_BINARY = "pushary-bridge";
877
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
911
+ var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
878
912
  var HOOK_BATCH_MAX_BYTES = 4 * 1024 * 1024;
879
913
  var REPO_KEY_MAX_LENGTH = 200;
880
914
  var WILDCARD_TOOL_PATTERN = "*";
@@ -2242,7 +2276,7 @@ var settingsPermissionList = (permissions, kind) => {
2242
2276
  };
2243
2277
  var boundedUnion = (lists) => [...new Set(lists.flat())].slice(0, MAX_AGENT_PERMISSION_RULES_PER_KIND);
2244
2278
  var claudePermissionRulesFromSettings = (documents) => {
2245
- const permissionBlocks = documents.flatMap((document) => isRecord(document) && isRecord(document.permissions) ? [document.permissions] : []);
2279
+ const permissionBlocks = documents.flatMap((document) => isRecord2(document) && isRecord2(document.permissions) ? [document.permissions] : []);
2246
2280
  const collect = (kind) => boundedUnion(permissionBlocks.map((permissions) => settingsPermissionList(permissions, kind)));
2247
2281
  return { allow: collect("allow"), ask: collect("ask"), deny: collect("deny") };
2248
2282
  };
@@ -2463,6 +2497,10 @@ var claudeElicitationOutput = (event, action, content) => ({
2463
2497
  }
2464
2498
  });
2465
2499
  var renderElicitationOutput = (event, action, content) => ELICITATION_EVENTS.includes(event) ? JSON.stringify(claudeElicitationOutput(event, action, content)) : void 0;
2500
+ var UNVERIFIABLE_APPROVAL_REASON = "Pushary could not create a verifiable approval. Retry the action.";
2501
+ var DECISION_STOP_REASON = "Approval was cancelled or became unavailable. Retry only after resolving it.";
2502
+ var WITHDRAWN_APPROVAL_REASON = "The phone question was withdrawn. Approve in the current client.";
2503
+ var claudeStoppedPreToolUseOutput = (reason) => stoppedOutput(claudePreToolUseOutput("deny", reason), reason);
2466
2504
  var ELICITATION_ANSWERABLE_MODE = "form";
2467
2505
  var ELICITATION_MIN_OPTIONS = 2;
2468
2506
  var ELICITATION_MAX_MULTI_QUESTIONS = 4;
@@ -2655,16 +2693,16 @@ var globalInstallTarget = (owner, ownName) => {
2655
2693
  return LEGACY_PACKAGE;
2656
2694
  }
2657
2695
  };
2658
- var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
2659
- var declaresOwnershipProbe = (bin) => isRecord2(bin) && typeof bin[OWNERSHIP_PROBE_COMMAND] === "string";
2696
+ var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
2697
+ var declaresOwnershipProbe = (bin) => isRecord3(bin) && typeof bin[OWNERSHIP_PROBE_COMMAND] === "string";
2660
2698
  var cliManifestName = (manifest) => {
2661
- if (!isRecord2(manifest) || !isCliPackageName(manifest.name) || !declaresOwnershipProbe(manifest.bin)) return void 0;
2699
+ if (!isRecord3(manifest) || !isCliPackageName(manifest.name) || !declaresOwnershipProbe(manifest.bin)) return void 0;
2662
2700
  return manifest.name;
2663
2701
  };
2664
2702
  var classifyGlobalFolder = (name, read) => {
2665
2703
  if (read.kind === "unreadable") return { kind: "unseen" };
2666
2704
  const { manifest } = read;
2667
- if (!isRecord2(manifest) || cliManifestName(manifest) !== name) return { kind: "foreign" };
2705
+ if (!isRecord3(manifest) || cliManifestName(manifest) !== name) return { kind: "foreign" };
2668
2706
  return { kind: "ours", installed: { name, version: typeof manifest.version === "string" ? manifest.version : void 0 } };
2669
2707
  };
2670
2708
  var classifyGlobalInstall = (installed, owner) => {
@@ -2755,6 +2793,8 @@ export {
2755
2793
  DISCONNECTABLE_AGENTS,
2756
2794
  REPO_AWARE_AGENTS,
2757
2795
  MANAGED_PROVIDERS,
2796
+ DISCONNECT_AGENT_IDS,
2797
+ normalizeAgentId,
2758
2798
  PHONE_ANSWERED_TOOLS,
2759
2799
  canonicalToolName,
2760
2800
  toToolLookup,
@@ -2780,7 +2820,13 @@ export {
2780
2820
  isSetupConnectMode,
2781
2821
  CLIENT_REPORT_PATH,
2782
2822
  clientContextHeaders,
2823
+ DECLINED_AGENTS_FILE,
2824
+ parseDeclinedAgents,
2825
+ serializeDeclinedAgents,
2826
+ withDeclinedAgent,
2827
+ withoutDeclinedAgent,
2783
2828
  normalizeKeyScope,
2829
+ isApprovalMode,
2784
2830
  parseAgentQuestion,
2785
2831
  parseAgentQuestions,
2786
2832
  parseAgentQuestionAnswers,
@@ -2849,6 +2895,10 @@ export {
2849
2895
  claudePermissionRequestOutput,
2850
2896
  gateOutputFor,
2851
2897
  renderElicitationOutput,
2898
+ UNVERIFIABLE_APPROVAL_REASON,
2899
+ DECISION_STOP_REASON,
2900
+ WITHDRAWN_APPROVAL_REASON,
2901
+ claudeStoppedPreToolUseOutput,
2852
2902
  ELICITATION_ANSWERABLE_MODE,
2853
2903
  readElicitationFields,
2854
2904
  planElicitationAsk,
@@ -10,10 +10,10 @@ import {
10
10
  resolvePackageVersionFromBinary,
11
11
  resolvePathBinary,
12
12
  resolvePathBinaryAsync
13
- } from "./chunk-ZUTU43FT.js";
13
+ } from "./chunk-ZBHUHJG6.js";
14
14
  import {
15
15
  MANAGED_PROVIDERS
16
- } from "./chunk-QR6VE5ME.js";
16
+ } from "./chunk-I5IJRMNV.js";
17
17
 
18
18
  // src/setup/codex-install.ts
19
19
  var NATIVE_BINARY_MIN_BYTES = 20 * 1024 * 1024;
@@ -14,19 +14,19 @@ import {
14
14
  } from "./chunk-U4TMAANR.js";
15
15
  import {
16
16
  callMcpTool
17
- } from "./chunk-L76HTPU6.js";
17
+ } from "./chunk-MKTJEXZ3.js";
18
18
  import {
19
19
  reportedInstallSource
20
- } from "./chunk-4D2AYNSE.js";
20
+ } from "./chunk-FQ2GORVG.js";
21
21
  import {
22
22
  NPX_LATEST_COMMAND
23
- } from "./chunk-STQRUH3S.js";
23
+ } from "./chunk-7DVNSQWF.js";
24
24
  import {
25
25
  NO_PAIRING_COMPUTER,
26
26
  PAIR_TTL_SECONDS,
27
27
  classifyConfirmResponse,
28
28
  isAnswerSource
29
- } from "./chunk-QR6VE5ME.js";
29
+ } from "./chunk-I5IJRMNV.js";
30
30
 
31
31
  // src/reach.ts
32
32
  var reachVerdict = (channels) => {
@@ -155,7 +155,7 @@ var describeVerifyOutcome = (outcome) => {
155
155
  ok: false,
156
156
  message: "Nothing to deliver to. Agents are configured; approvals will fall back to the terminal.",
157
157
  next: [
158
- "Run pushary connect to add your phone.",
158
+ "Run pushary pair to pair your phone.",
159
159
  "Then pushary doctor --roundtrip to test a synthetic question and answer."
160
160
  ]
161
161
  };
@@ -165,7 +165,7 @@ var describeVerifyOutcome = (outcome) => {
165
165
  message: `Delivered to ${plural2(outcome.recipients, "device")} on this site, none of them yours.`,
166
166
  next: [
167
167
  `Approvals for your agent would wake one of your ${plural2(outcome.otherMembers, "teammate")}.`,
168
- "Run pushary connect to add your own phone."
168
+ "Run pushary pair to pair your own phone."
169
169
  ]
170
170
  };
171
171
  case "unattributable":
@@ -174,7 +174,7 @@ var describeVerifyOutcome = (outcome) => {
174
174
  message: `Delivered to ${plural2(outcome.recipients, "device")} on this site, and no way to tell whose.`,
175
175
  next: [
176
176
  "Browser subscriptions carry no owner, and this site has other members.",
177
- "Install the Pushary app with pushary connect, or run pushary doctor --roundtrip to prove it reaches you."
177
+ "Install the Pushary app and pair it with pushary pair, or run pushary doctor --roundtrip to prove it reaches you."
178
178
  ]
179
179
  };
180
180
  case "error":
@@ -319,8 +319,8 @@ var describeRoundTripOutcome = (outcome) => {
319
319
  ok: false,
320
320
  message: "Nothing to ask. No phone or browser is connected to this site.",
321
321
  next: [
322
- "Run pushary connect to add your phone.",
323
- "Or pushary connect --app if you already have the Pushary app."
322
+ "Run pushary pair to pair your phone.",
323
+ "Or pushary pair --app if you already have the Pushary app."
324
324
  ]
325
325
  };
326
326
  case "error":
@@ -538,14 +538,14 @@ var waitForDevice = async (apiKey, baseline) => {
538
538
  consecutiveFailures = 0;
539
539
  const channels = probe.status;
540
540
  if (reachesYou(channels) || channels.webActive > baseline.webActive) {
541
- stop(check, "Phone connected");
541
+ stop(check, "Phone paired");
542
542
  return { kind: "connected", channels };
543
543
  }
544
544
  await sleep(CONNECT_POLL_INTERVAL_MS);
545
545
  }
546
546
  stop(yellow("!"), "Didn't detect a connection yet");
547
547
  console.log(` ${dim("Signed in on the app already? Open it and allow notifications.")}`);
548
- console.log(` ${dim("Signing in alone does not connect the phone. Then run")} ${cyan("pushary doctor")}${dim(".")}`);
548
+ console.log(` ${dim("Signing in alone does not pair the phone. Then run")} ${cyan("pushary doctor")}${dim(".")}`);
549
549
  return { kind: "timeout" };
550
550
  } catch (err) {
551
551
  stop(yellow("!"), `Couldn't check connection ${dim(`(${err instanceof Error ? err.message : "network error"})`)}`);
@@ -588,14 +588,14 @@ var connectDevice = async (apiKey, options = {}) => {
588
588
  }
589
589
  const site = await fetchSite(apiKey);
590
590
  if (!site) {
591
- console.log(` ${yellow("!")} Couldn't load your subscribe link. Connect your phone later at ${cyan("pushary.com/download")}.`);
591
+ console.log(` ${yellow("!")} Couldn't load your subscribe link. Pair your phone later at ${cyan("pushary.com/download")}.`);
592
592
  return phoneFailure("no_subscribe_link");
593
593
  }
594
594
  console.log();
595
595
  if (channels.site !== null && channels.site.otherMembers > 0 && channels.phoneReachable) {
596
596
  printSiteOnlyWarning(channels);
597
597
  } else {
598
- console.log(` ${bold("Connect your phone")}`);
598
+ console.log(` ${bold("Pair your phone")}`);
599
599
  if (channels.webDesktop > 0) {
600
600
  console.log(` ${dim("A browser on this computer is subscribed, but no phone is connected yet.")}`);
601
601
  }
@@ -727,7 +727,7 @@ var printConnectInstructions = async (apiKey) => {
727
727
  }
728
728
  const site = await fetchSite(apiKey);
729
729
  const target = site?.subscribeUrl ?? "https://pushary.com/download";
730
- console.log(` ${dim("Connect your phone for push notifications at")} ${cyan(target)}`);
730
+ console.log(` ${dim("Pair your phone for push notifications at")} ${cyan(target)}`);
731
731
  console.log(` ${dim("or get the Pushary app at")} ${cyan("https://pushary.com/download")}`);
732
732
  return phoneFailure("no_device");
733
733
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  readConfigFileKey
3
- } from "./chunk-ADSQDYYG.js";
3
+ } from "./chunk-N4QSPI3B.js";
4
4
 
5
5
  // src/bell/fleet.ts
6
6
  import { closeSync, constants, futimesSync, lstatSync, mkdirSync, openSync, readdirSync, unlinkSync } from "fs";
@@ -141,7 +141,7 @@ var writeLastShown = (at) => {
141
141
  }
142
142
  };
143
143
  var upgradeLine = (context) => ` ${context.liveAgents} agents running. A bell can't tell you which one needs you, and it can't reach your pocket.
144
- pushary connect`;
144
+ pushary pair`;
145
145
  var upgradeNotice = (context, deps = {}) => {
146
146
  const env = deps.env ?? process.env;
147
147
  if (env.PUSHARY_BELL_QUIET === "1" || env.PUSHARY_BELL_QUIET === "true") return null;
@@ -5,7 +5,7 @@ import {
5
5
  permissionDeniedAction,
6
6
  releaseThrottle,
7
7
  reportEvent
8
- } from "./chunk-QFEM7R6T.js";
8
+ } from "./chunk-KRCR2CRQ.js";
9
9
  import {
10
10
  DEFAULT_SESSION
11
11
  } from "./chunk-N6IOSZOE.js";
@@ -13,7 +13,7 @@ import {
13
13
  machineDecisionFor,
14
14
  shouldDeferToNativeMode,
15
15
  wireVerdictFor
16
- } from "./chunk-QR6VE5ME.js";
16
+ } from "./chunk-I5IJRMNV.js";
17
17
 
18
18
  // src/machine-decision-audit.ts
19
19
  import { basename } from "path";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-ZUTU43FT.js";
3
+ } from "./chunk-ZBHUHJG6.js";
4
4
  import {
5
5
  readJsonSafe
6
6
  } from "./chunk-T7E75EKA.js";