@pushary/agent-hooks 1.9.66 → 1.9.68

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 (127) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/data/SKILL.md +1 -1
  3. package/data/cursor-plugin/skills/pushary/SKILL.md +1 -1
  4. package/data/vscode-plugin/skills/pushary/SKILL.md +1 -1
  5. package/dist/{api-GDSVUTI2.js → api-6Q7XIB67.js} +10 -10
  6. package/dist/bin/pushary-bell-hook.js +25 -25
  7. package/dist/bin/pushary-bell.js +10 -10
  8. package/dist/bin/pushary-claude.js +26 -26
  9. package/dist/bin/pushary-clean.js +73 -74
  10. package/dist/bin/pushary-codex-bridge.js +21 -21
  11. package/dist/bin/pushary-codex-hook.js +30 -30
  12. package/dist/bin/pushary-codex-session.js +8 -8
  13. package/dist/bin/pushary-codex.js +13 -13
  14. package/dist/bin/pushary-connect.js +28 -27
  15. package/dist/bin/pushary-cowork.js +5 -5
  16. package/dist/bin/pushary-daemon.js +40 -39
  17. package/dist/bin/pushary-disconnect.js +25 -25
  18. package/dist/bin/pushary-doctor.js +126 -72
  19. package/dist/bin/pushary-elicitation-hook.js +25 -25
  20. package/dist/bin/pushary-gemini-bridge.js +15 -15
  21. package/dist/bin/pushary-gemini-hook.js +27 -27
  22. package/dist/bin/pushary-hook.js +29 -29
  23. package/dist/bin/pushary-login.js +20 -19
  24. package/dist/bin/pushary-logout.js +26 -27
  25. package/dist/bin/pushary-mcp.js +11 -11
  26. package/dist/bin/pushary-mode.js +16 -15
  27. package/dist/bin/pushary-notification-hook.js +24 -24
  28. package/dist/bin/pushary-opencode-hook.js +26 -26
  29. package/dist/bin/pushary-permission-denied-hook.js +29 -29
  30. package/dist/bin/pushary-permission-hook.js +29 -29
  31. package/dist/bin/pushary-post-hook.js +24 -24
  32. package/dist/bin/pushary-prompt-hook.js +24 -24
  33. package/dist/bin/pushary-session-end-hook.js +26 -26
  34. package/dist/bin/pushary-session-start-hook.js +34 -33
  35. package/dist/bin/pushary-setup.js +115 -98
  36. package/dist/bin/pushary-stats.js +5 -5
  37. package/dist/bin/pushary-status.js +37 -35
  38. package/dist/bin/pushary-stop-hook.js +24 -24
  39. package/dist/bin/pushary-stopfailure-hook.js +24 -24
  40. package/dist/bin/pushary-suggestions.js +15 -14
  41. package/dist/bin/pushary-transcript-register.js +16 -16
  42. package/dist/bin/pushary-transcripts.js +18 -17
  43. package/dist/bin/pushary-upgrade.js +66 -38
  44. package/dist/bin/pushary-wait.js +26 -20
  45. package/dist/bin/pushary.js +7 -7
  46. package/dist/{chunk-ZJV7SFIJ.js → chunk-2HMKZYF5.js} +1 -1
  47. package/dist/{chunk-IA5VWIHV.js → chunk-2VYQG2HG.js} +2 -2
  48. package/dist/{chunk-A47UKPC7.js → chunk-32OSSYGZ.js} +1 -1
  49. package/dist/{chunk-DBUHSUL7.js → chunk-4TIN3T2A.js} +1 -1
  50. package/dist/{chunk-JL3SZJJP.js → chunk-53Q4LRBU.js} +2 -2
  51. package/dist/{chunk-HUGVJBDN.js → chunk-53RH3ZIK.js} +2 -2
  52. package/dist/{chunk-2BL6KWN7.js → chunk-6IFEYELN.js} +9 -9
  53. package/dist/{chunk-DKMVVBXO.js → chunk-6VFZVL65.js} +55 -13
  54. package/dist/{chunk-YQDCTID4.js → chunk-73DHP3JX.js} +4 -4
  55. package/dist/{chunk-G6VJZ3RB.js → chunk-77L2TNJW.js} +1 -1
  56. package/dist/{chunk-IQ3GKPFM.js → chunk-77QP22FL.js} +1 -1
  57. package/dist/{chunk-VURDLVAQ.js → chunk-7S7NTMDJ.js} +3 -3
  58. package/dist/{chunk-4APD2DPI.js → chunk-7SKGS7QN.js} +53 -3
  59. package/dist/chunk-7V63A4AI.js +25 -0
  60. package/dist/{chunk-6BGVSV2Q.js → chunk-7YJSDXLM.js} +1 -1
  61. package/dist/{chunk-MNNQEUQC.js → chunk-AJIT4SCL.js} +27 -8
  62. package/dist/{chunk-QR2QWGQI.js → chunk-BSMHSN3Y.js} +3 -3
  63. package/dist/{chunk-R7C2FS33.js → chunk-C4EDAHXI.js} +1 -1
  64. package/dist/{chunk-7LK3Y6ET.js → chunk-CB4U6WRP.js} +6 -6
  65. package/dist/chunk-D6W7QDQE.js +2298 -0
  66. package/dist/{chunk-V4EOFOB2.js → chunk-E5PEOVUJ.js} +6 -6
  67. package/dist/{chunk-32ZT2ATY.js → chunk-EOWHEZHD.js} +8 -8
  68. package/dist/{chunk-57NTMVMI.js → chunk-EUU5PDUI.js} +6 -6
  69. package/dist/{chunk-XXIJBYNW.js → chunk-GMHQYX3D.js} +1 -1
  70. package/dist/{chunk-V3YBVOTZ.js → chunk-I5FFSOCV.js} +2 -2
  71. package/dist/{chunk-RJ6JEHCP.js → chunk-JAKWPQ2L.js} +1 -1
  72. package/dist/{chunk-XDDSURY3.js → chunk-JPVV27O2.js} +3 -3
  73. package/dist/{chunk-GWYCKTXS.js → chunk-K4TSXWVX.js} +5 -5
  74. package/dist/chunk-LF2NSOAQ.js +299 -0
  75. package/dist/{chunk-6RJZSBPD.js → chunk-LGCVAE52.js} +1 -1
  76. package/dist/{chunk-GDLT32I4.js → chunk-LQAAOXYJ.js} +21 -13
  77. package/dist/{chunk-3ELJIG2R.js → chunk-MCNHNIRC.js} +3 -3
  78. package/dist/{chunk-XIJTXRWB.js → chunk-METUT7V4.js} +2 -2
  79. package/dist/{chunk-MDIGG3Q7.js → chunk-MFWHANKG.js} +3 -3
  80. package/dist/{chunk-GECU7V44.js → chunk-MHC34X5A.js} +3 -3
  81. package/dist/{chunk-376TUN72.js → chunk-MMTA7UKA.js} +3 -3
  82. package/dist/{chunk-XGFFNERF.js → chunk-MUDUWF74.js} +1 -1
  83. package/dist/{chunk-KS3O6O7E.js → chunk-NAQCWM4U.js} +3 -3
  84. package/dist/{chunk-TQNFDNJA.js → chunk-NKPSJOHJ.js} +6 -6
  85. package/dist/{chunk-DPU6H4JY.js → chunk-NLDEC4Y7.js} +3 -3
  86. package/dist/{chunk-XEXF2OFZ.js → chunk-NWN6GGJL.js} +2 -2
  87. package/dist/{chunk-IGO3AGZK.js → chunk-O655YCOG.js} +4 -4
  88. package/dist/{chunk-5FJDODOA.js → chunk-ODAAK2RZ.js} +3 -3
  89. package/dist/{chunk-AVWECJSN.js → chunk-ORHVVRVL.js} +2 -2
  90. package/dist/{chunk-YB3HMDKE.js → chunk-P4XZX7CL.js} +2 -2
  91. package/dist/{chunk-CNJ7SI5V.js → chunk-PBEW5CJK.js} +4 -4
  92. package/dist/{chunk-CN6JFM62.js → chunk-PEPRUUGM.js} +15 -6
  93. package/dist/{chunk-QN25WBXL.js → chunk-PGOPIIOQ.js} +7 -7
  94. package/dist/{chunk-Q5RNYE2L.js → chunk-PZZKXX6Q.js} +4 -4
  95. package/dist/{chunk-SVKCYUYP.js → chunk-Q6JXE3PD.js} +9 -9
  96. package/dist/{chunk-ZAZUDYSF.js → chunk-QYTOYNV2.js} +5 -5
  97. package/dist/{chunk-3FQX74E4.js → chunk-REQO3WWO.js} +23 -8
  98. package/dist/{chunk-EJR5JXMV.js → chunk-RQOT6QL3.js} +43 -5
  99. package/dist/{chunk-AWGBL4P3.js → chunk-RWXDWOQQ.js} +89 -41
  100. package/dist/{chunk-6ZXCWK27.js → chunk-SL7CIZCL.js} +60 -6
  101. package/dist/{chunk-3EZP5ZPS.js → chunk-TVVJ6OYG.js} +4 -4
  102. package/dist/{chunk-B6JC676X.js → chunk-UC2J5RR4.js} +1 -1
  103. package/dist/{chunk-26W46E46.js → chunk-UETS2WEA.js} +27 -10
  104. package/dist/{chunk-EU2ZOZC3.js → chunk-UXN73YAE.js} +3 -3
  105. package/dist/{chunk-XFQAK35L.js → chunk-VHMZPN3N.js} +1 -1
  106. package/dist/{chunk-45KMS76L.js → chunk-VKZ3RJ5U.js} +1 -1
  107. package/dist/{chunk-T6YLXO6N.js → chunk-VRFFMTIG.js} +4 -4
  108. package/dist/{chunk-DIUTSF6I.js → chunk-WPOXZPEH.js} +4 -4
  109. package/dist/{chunk-GO7YKPT3.js → chunk-X2MTVD4W.js} +1 -1
  110. package/dist/{chunk-5J7OZBJ4.js → chunk-XQKB4LEK.js} +2 -2
  111. package/dist/{chunk-QOIPUYUD.js → chunk-XZKSUJ55.js} +1 -1
  112. package/dist/{chunk-RSZQEEEW.js → chunk-YZHJQG6W.js} +8 -6
  113. package/dist/{chunk-UTAARXYQ.js → chunk-ZK5WYAMI.js} +1 -1
  114. package/dist/{codex-app-cards-switch-W7OLKOMO.js → codex-app-cards-switch-VZ4XIDJO.js} +11 -11
  115. package/dist/{codex-desktop-launch-U6V3AXZF.js → codex-desktop-launch-CX2IE5BI.js} +1 -1
  116. package/dist/{codex-session-launch-EFU46WBL.js → codex-session-launch-WUIM6ZGA.js} +18 -18
  117. package/dist/{config-UC4LMCNX.js → config-OBGYURFX.js} +3 -3
  118. package/dist/{global-upgrade-ABF5O3HU.js → global-upgrade-XZ5L7LDB.js} +10 -10
  119. package/dist/{identity-3ZUZPHN6.js → identity-TGQPFIE4.js} +4 -4
  120. package/dist/{live-capabilities-BXWXJARK.js → live-capabilities-JHESROAP.js} +5 -5
  121. package/dist/{paths-FO76CFRQ.js → paths-EOMNC4QM.js} +7 -3
  122. package/dist/{reapply-3T3DFUAI.js → reapply-J5HHUUBE.js} +27 -26
  123. package/dist/src/index.js +28 -28
  124. package/dist/{upgrade-lock-EZ5JIPJE.js → upgrade-lock-VQORI6G5.js} +4 -4
  125. package/dist/{usage-Y6BL7RUD.js → usage-KX2HN47E.js} +3 -3
  126. package/package.json +1 -1
  127. package/dist/chunk-QBNICXMC.js +0 -615
@@ -4,24 +4,24 @@ import {
4
4
  outcomeOfFailedAsk,
5
5
  reportMachineDenial,
6
6
  storedWaitDeadline
7
- } from "./chunk-V4EOFOB2.js";
7
+ } from "./chunk-E5PEOVUJ.js";
8
8
  import {
9
9
  isGatingMoment,
10
10
  recordKeylessMoment
11
- } from "./chunk-6BGVSV2Q.js";
11
+ } from "./chunk-7YJSDXLM.js";
12
12
  import {
13
13
  isAdmitted,
14
14
  readAdmissionRules
15
- } from "./chunk-QN25WBXL.js";
15
+ } from "./chunk-PGOPIIOQ.js";
16
16
  import {
17
17
  isDeferAnswer,
18
18
  oncePerSession
19
- } from "./chunk-ZJV7SFIJ.js";
19
+ } from "./chunk-2HMKZYF5.js";
20
20
  import {
21
21
  activeHookSource,
22
22
  activeIdentity,
23
23
  namedSource
24
- } from "./chunk-3EZP5ZPS.js";
24
+ } from "./chunk-TVVJ6OYG.js";
25
25
  import {
26
26
  DEFAULT_SESSION,
27
27
  UNNAMED_ACTION,
@@ -45,10 +45,10 @@ import {
45
45
  reportEvent,
46
46
  scopePathFor,
47
47
  settleQuestionsForToolUse
48
- } from "./chunk-2BL6KWN7.js";
48
+ } from "./chunk-6IFEYELN.js";
49
49
  import {
50
50
  repoKeyFor
51
- } from "./chunk-XXIJBYNW.js";
51
+ } from "./chunk-GMHQYX3D.js";
52
52
  import {
53
53
  askUser,
54
54
  cancelQuestion,
@@ -65,20 +65,20 @@ import {
65
65
  waitForQuestion,
66
66
  waitsForThePhone,
67
67
  withdrawQuestion
68
- } from "./chunk-ZAZUDYSF.js";
68
+ } from "./chunk-QYTOYNV2.js";
69
69
  import {
70
70
  getMachineId
71
- } from "./chunk-IA5VWIHV.js";
71
+ } from "./chunk-2VYQG2HG.js";
72
72
  import {
73
73
  claudeConfigDir
74
- } from "./chunk-GDLT32I4.js";
74
+ } from "./chunk-LQAAOXYJ.js";
75
75
  import {
76
76
  getApiKey,
77
77
  getBaseUrl
78
- } from "./chunk-A47UKPC7.js";
78
+ } from "./chunk-32OSSYGZ.js";
79
79
  import {
80
80
  NPX_LATEST_COMMAND
81
- } from "./chunk-GO7YKPT3.js";
81
+ } from "./chunk-X2MTVD4W.js";
82
82
  import {
83
83
  AGENT_QUESTION_STRATEGY,
84
84
  AGENT_QUESTION_TOOL,
@@ -133,7 +133,7 @@ import {
133
133
  terminalStaysLiveForTheCall,
134
134
  timeoutActionWithoutLocalPrompt,
135
135
  unansweredRefusalReason
136
- } from "./chunk-EJR5JXMV.js";
136
+ } from "./chunk-RQOT6QL3.js";
137
137
 
138
138
  // src/terminal-answer-watch.ts
139
139
  import { closeSync, openSync, readSync, statSync } from "fs";
@@ -296,36 +296,45 @@ var reportDecisionEpisode = async (apiKey, input) => {
296
296
 
297
297
  // src/hook.ts
298
298
  import { basename } from "path";
299
- var START_MS = Date.now();
300
- var ACTIVE_AGENT = activeIdentity(process.argv);
301
- var ACTIVE_SOURCE = activeHookSource(process.argv);
302
- var HANDED_DOWN_BY_THE_MAC_BRIDGE = namedSource(process.argv) !== void 0;
303
- var CLAUDE_SESSION_ATTENDED_ENV = "CLAUDE_CODE_SESSION_ATTENDED";
304
- var PUSHARY_IS_SOLE_GATE = ACTIVE_SOURCE !== null && hookCompatibleProfileBySource(ACTIVE_SOURCE)?.soleGate != null;
305
- var agentNameIn = (projectName) => `${ACTIVE_AGENT.label} - ${projectName}`;
299
+
300
+ // src/pre-tool-use-output.ts
306
301
  var allow = (reason) => claudePreToolUseOutput("allow", reason);
307
302
  var deny = (reason) => claudePreToolUseOutput("deny", reason);
308
- var allowWithInput = (updatedInput) => claudePreToolUseOutput("allow", void 0, updatedInput);
309
303
  var ask = (reason) => claudePreToolUseOutput("ask", reason);
310
304
  var halted = (reason) => claudeStoppedPreToolUseOutput(reason);
311
- var undecidedCall = (reason) => PUSHARY_IS_SOLE_GATE ? deny(reason) : void 0;
305
+
306
+ // src/permission-ask-outcome.ts
312
307
  var questionLimitOutput = (handBack) => handBack.kind === "refuse" ? deny(handBack.reason) : ask(QUESTION_LIMIT_PROMPT_REASON);
313
- var outcomeOfFailedPermissionAsk = (error, sessionId, questionLimitFacts) => {
308
+ var outcomeOfFailedPermissionAsk = (error, sessionId, questionLimitFacts, subscriptionRequiredOutput) => {
314
309
  if (isQuestionLimitRefusal(error)) return questionLimitOutput(questionLimitHandBack(questionLimitFacts));
315
- return outcomeOfFailedAsk(error, sessionId, halted(UNVERIFIABLE_APPROVAL_REASON)) ?? undecidedCall(SOLE_GATE_SUBSCRIPTION_REASON);
310
+ return outcomeOfFailedAsk(error, sessionId, halted(UNVERIFIABLE_APPROVAL_REASON)) ?? subscriptionRequiredOutput;
316
311
  };
317
- var handlePushOnly = async (apiKey, description, projectName, timeoutSeconds, timeoutAction, sessionId, machineId, toolName, toolTarget, decision, signals, agentPromptFollows) => {
312
+ var handlePushOnly = async (apiKey, call, timeoutSeconds, timeoutAction, signals) => {
313
+ const {
314
+ description,
315
+ projectName,
316
+ agentName,
317
+ sessionId,
318
+ machineId,
319
+ toolName,
320
+ toolTarget,
321
+ decision,
322
+ agentPromptFollows,
323
+ startMs,
324
+ subscriptionRequiredOutput,
325
+ announceWait: announceWait2
326
+ } = call;
318
327
  const effectiveWait = effectiveWaitSeconds(timeoutAction, timeoutSeconds, "claude");
319
328
  const now = Date.now();
320
- const requestedDeadline = hookWaitDeadline(START_MS, effectiveWait, "claude", now);
321
- const clampCut = hookWaitClamped(START_MS, effectiveWait, "claude", now);
329
+ const requestedDeadline = hookWaitDeadline(startMs, effectiveWait, "claude", now);
330
+ const clampCut = hookWaitClamped(startMs, effectiveWait, "claude", now);
322
331
  let result;
323
332
  try {
324
333
  result = await askUser(apiKey, {
325
334
  question: `Allow ${description || UNNAMED_ACTION}?`,
326
335
  type: "confirm",
327
336
  context: `Agent wants to run this in ${projectName}`,
328
- agentName: agentNameIn(projectName),
337
+ agentName,
329
338
  sessionId,
330
339
  machineId,
331
340
  toolName,
@@ -337,11 +346,11 @@ var handlePushOnly = async (apiKey, description, projectName, timeoutSeconds, ti
337
346
  return outcomeOfFailedPermissionAsk(error, sessionId, {
338
347
  refusesUnanswered: refusesWhenUnanswered({ mode: "push_only", timeoutAction }),
339
348
  agentPromptFollows
340
- });
349
+ }, subscriptionRequiredOutput);
341
350
  }
342
351
  if (isDecisionStopped(result)) return halted(DECISION_STOP_REASON);
343
352
  const deadline = storedWaitDeadline(result, requestedDeadline);
344
- if (waitsForThePhone(result)) announceWait(effectiveWait, result.answerUrl, sessionId);
353
+ if (waitsForThePhone(result)) announceWait2(effectiveWait, result.answerUrl, sessionId);
345
354
  const answer = await waitForQuestion(apiKey, result, deadline);
346
355
  if (isDecisionStopped(answer)) return halted(DECISION_STOP_REASON);
347
356
  if (!answer.answered && isLocalQuestionHandoff(result)) return ask("Approve in the current client.");
@@ -362,18 +371,29 @@ var handlePushOnly = async (apiKey, description, projectName, timeoutSeconds, ti
362
371
  return ask("No push response, asking in terminal");
363
372
  }
364
373
  };
365
- var handleTerminalOnly = () => {
366
- return ask();
367
- };
368
- var handlePushFirst = async (apiKey, description, projectName, pushFirstSeconds, sessionId, machineId, toolName, toolTarget, decision, signals, agentPromptFollows) => {
369
- const requestedDeadline = hookWaitDeadline(START_MS, pushFirstSeconds, "claude", Date.now());
374
+ var handlePushFirst = async (apiKey, call, pushFirstSeconds, signals) => {
375
+ const {
376
+ description,
377
+ projectName,
378
+ agentName,
379
+ sessionId,
380
+ machineId,
381
+ toolName,
382
+ toolTarget,
383
+ decision,
384
+ agentPromptFollows,
385
+ startMs,
386
+ subscriptionRequiredOutput,
387
+ announceWait: announceWait2
388
+ } = call;
389
+ const requestedDeadline = hookWaitDeadline(startMs, pushFirstSeconds, "claude", Date.now());
370
390
  let result;
371
391
  try {
372
392
  result = await askUser(apiKey, {
373
393
  question: `Allow ${description || UNNAMED_ACTION}?`,
374
394
  type: "confirm",
375
395
  context: `Agent wants to run this in ${projectName}`,
376
- agentName: agentNameIn(projectName),
396
+ agentName,
377
397
  sessionId,
378
398
  machineId,
379
399
  toolName,
@@ -382,10 +402,10 @@ var handlePushFirst = async (apiKey, description, projectName, pushFirstSeconds,
382
402
  ...decision
383
403
  });
384
404
  } catch (error) {
385
- return outcomeOfFailedPermissionAsk(error, sessionId, { refusesUnanswered: false, agentPromptFollows });
405
+ return outcomeOfFailedPermissionAsk(error, sessionId, { refusesUnanswered: false, agentPromptFollows }, subscriptionRequiredOutput);
386
406
  }
387
407
  if (isDecisionStopped(result)) return halted(DECISION_STOP_REASON);
388
- if (waitsForThePhone(result)) announceWait(pushFirstSeconds, result.answerUrl, sessionId);
408
+ if (waitsForThePhone(result)) announceWait2(pushFirstSeconds, result.answerUrl, sessionId);
389
409
  const deadline = storedWaitDeadline(result, requestedDeadline);
390
410
  const answer = await waitForQuestion(apiKey, result, deadline, 1500);
391
411
  if (isDecisionStopped(answer)) return halted(DECISION_STOP_REASON);
@@ -396,6 +416,20 @@ var handlePushFirst = async (apiKey, description, projectName, pushFirstSeconds,
396
416
  }
397
417
  return ask(WITHDRAWN_APPROVAL_REASON);
398
418
  };
419
+
420
+ // src/hook.ts
421
+ var START_MS = Date.now();
422
+ var ACTIVE_AGENT = activeIdentity(process.argv);
423
+ var ACTIVE_SOURCE = activeHookSource(process.argv);
424
+ var HANDED_DOWN_BY_THE_MAC_BRIDGE = namedSource(process.argv) !== void 0;
425
+ var CLAUDE_SESSION_ATTENDED_ENV = "CLAUDE_CODE_SESSION_ATTENDED";
426
+ var PUSHARY_IS_SOLE_GATE = ACTIVE_SOURCE !== null && hookCompatibleProfileBySource(ACTIVE_SOURCE)?.soleGate != null;
427
+ var agentNameIn = (projectName) => `${ACTIVE_AGENT.label} - ${projectName}`;
428
+ var allowWithInput = (updatedInput) => claudePreToolUseOutput("allow", void 0, updatedInput);
429
+ var undecidedCall = (reason) => PUSHARY_IS_SOLE_GATE ? deny(reason) : void 0;
430
+ var handleTerminalOnly = () => {
431
+ return ask();
432
+ };
399
433
  var handleNotifyOnly = async (apiKey, description, projectName, sessionId, machineId) => {
400
434
  try {
401
435
  await sendNotification(apiKey, {
@@ -522,6 +556,20 @@ var dispatchModeHandler = async (apiKey, input, toolPolicy, machineId, trainingC
522
556
  permissionMode: input.permission_mode
523
557
  };
524
558
  const signals = {};
559
+ const permissionAsk = {
560
+ description,
561
+ projectName,
562
+ agentName: agentNameIn(projectName),
563
+ sessionId,
564
+ machineId,
565
+ toolName: input.tool_name,
566
+ toolTarget,
567
+ decision,
568
+ agentPromptFollows,
569
+ startMs: START_MS,
570
+ subscriptionRequiredOutput: undecidedCall(SOLE_GATE_SUBSCRIPTION_REASON),
571
+ announceWait
572
+ };
525
573
  const runHandler = () => {
526
574
  const mode = ownPrompt ? toolPolicy.mode : approvalModeWithoutLocalPrompt(toolPolicy.mode);
527
575
  if (terminalLive && pushesToThePhone(mode)) {
@@ -529,15 +577,15 @@ var dispatchModeHandler = async (apiKey, input, toolPolicy, machineId, trainingC
529
577
  }
530
578
  switch (mode) {
531
579
  case "push_only":
532
- return handlePushOnly(apiKey, description, projectName, toolPolicy.timeoutSeconds, ownPrompt ? toolPolicy.timeoutAction : timeoutActionWithoutLocalPrompt(toolPolicy), sessionId, machineId, input.tool_name, toolTarget, decision, signals, agentPromptFollows);
580
+ return handlePushOnly(apiKey, permissionAsk, toolPolicy.timeoutSeconds, ownPrompt ? toolPolicy.timeoutAction : timeoutActionWithoutLocalPrompt(toolPolicy), signals);
533
581
  case "terminal_only":
534
582
  return Promise.resolve(handleTerminalOnly());
535
583
  case "push_first":
536
- return handlePushFirst(apiKey, description, projectName, toolPolicy.pushFirstSeconds, sessionId, machineId, input.tool_name, toolTarget, decision, signals, agentPromptFollows);
584
+ return handlePushFirst(apiKey, permissionAsk, toolPolicy.pushFirstSeconds, signals);
537
585
  case "notify_only":
538
586
  return handleNotifyOnly(apiKey, description, projectName, sessionId, machineId);
539
587
  default:
540
- return handlePushFirst(apiKey, description, projectName, toolPolicy.pushFirstSeconds, sessionId, machineId, input.tool_name, toolTarget, decision, signals, agentPromptFollows);
588
+ return handlePushFirst(apiKey, permissionAsk, toolPolicy.pushFirstSeconds, signals);
541
589
  }
542
590
  };
543
591
  const result = await runHandler();
@@ -4,13 +4,13 @@ import {
4
4
  configFailureKind,
5
5
  retryAgentCommand,
6
6
  writeSetupConfigFile
7
- } from "./chunk-5FJDODOA.js";
7
+ } from "./chunk-ODAAK2RZ.js";
8
8
  import {
9
9
  MCP_BRIDGE_BINARY
10
- } from "./chunk-HUGVJBDN.js";
10
+ } from "./chunk-53RH3ZIK.js";
11
11
  import {
12
12
  KEY_FILE_MODE
13
- } from "./chunk-CNJ7SI5V.js";
13
+ } from "./chunk-PBEW5CJK.js";
14
14
  import {
15
15
  CLINE_SERVER_NAME_TAKEN,
16
16
  CLINE_SETTINGS_REFUSALS,
@@ -23,19 +23,22 @@ import {
23
23
  clinePusharyEntryOf,
24
24
  clineServerNameTakenElsewhere,
25
25
  clineSettingsText,
26
+ guardedArgv,
26
27
  isClinePusharyEntry,
28
+ isPusharyMcpUrl,
27
29
  otherPusharyServerNames,
28
30
  readClineSettings,
29
31
  renderAgentInstructions,
30
32
  withClinePusharyServer,
31
33
  withRefreshedClineKey,
32
34
  withoutClinePusharyServer
33
- } from "./chunk-GDLT32I4.js";
35
+ } from "./chunk-LQAAOXYJ.js";
34
36
  import {
35
37
  readJsonSafe,
38
+ resolveGlobalBinary,
36
39
  writeFileAtomic,
37
40
  writeJsonAtomic
38
- } from "./chunk-KS3O6O7E.js";
41
+ } from "./chunk-NAQCWM4U.js";
39
42
 
40
43
  // src/fx-config.ts
41
44
  var FX_SERVER_NAME = "pushary";
@@ -57,6 +60,9 @@ var ALIAS_SERVERS_KEY = "mcpServers";
57
60
  var LOCAL_TRANSPORT = "local";
58
61
  var SERVER_TRANSPORTS = /* @__PURE__ */ new Set(["local", "stdio", "http", "sse"]);
59
62
  var STDIO_TRANSPORTS = /* @__PURE__ */ new Set(["local", "stdio"]);
63
+ var REMOTE_TRANSPORTS = /* @__PURE__ */ new Set(["http", "sse"]);
64
+ var FX_HTTP_CALLS_CAN_DROP = "fx's MCP-v2 engine (FX_MCP_ENGINE=v2) reuses an HTTP connection the server has already closed, so the first Pushary call after a few idle minutes can fail without reaching Pushary";
65
+ var FX_RELOAD_AFTER_BRIDGE = "Restart fx, or run /mcp reload in each running fx session, so it reaches Pushary through the local bridge.";
60
66
  var AMBIGUOUS_SERVER_KEYS = /* @__PURE__ */ new Set([
61
67
  "mcpserver",
62
68
  "mcpservers",
@@ -200,6 +206,22 @@ var isFxPusharyEntry = (value) => {
200
206
  return STDIO_TRANSPORTS.has(transport) && (commandNamesBridge(entry.command) || commandNamesBridge(entry.args));
201
207
  };
202
208
  var fxPusharyEntryOf = (profile) => asRecord(profile[fxServersKeyOf(profile)])?.[FX_SERVER_NAME];
209
+ var connectsOverHttp = (entry) => entry.type === void 0 || typeof entry.type === "string" && REMOTE_TRANSPORTS.has(entry.type);
210
+ var isFxPusharyHttpEntry = (value) => {
211
+ const entry = asRecord(value);
212
+ return entry !== void 0 && entry.enabled !== false && connectsOverHttp(entry) && isPusharyMcpUrl(entry.url);
213
+ };
214
+ var isOtherPusharyHttpServer = ([name, entry]) => name !== FX_SERVER_NAME && isFxPusharyHttpEntry(entry);
215
+ var serverNameOf = ([name]) => name;
216
+ var fxOtherPusharyHttpServers = (profile) => Object.entries(asRecord(profile[fxServersKeyOf(profile)]) ?? {}).filter(isOtherPusharyHttpServer).map(serverNameOf);
217
+ var quotedServerNames = (names) => names.map((name) => `"${name}"`).join(", ");
218
+ var fxOtherHttpServersNote = (names, profilePath, retryCommand) => `fx also reaches Pushary over HTTP through ${quotedServerNames(names)} in ${profilePath}. ${FX_HTTP_CALLS_CAN_DROP}. Remove ${names.length === 1 ? "it" : "them"}, then run ${retryCommand}.`;
219
+ var FX_HTTP_ENTRY_KEPT_BECAUSE = {
220
+ "no-key": "this machine has no saved Pushary key for the local bridge",
221
+ "no-bridge": "the Pushary bridge is not installed globally on this machine"
222
+ };
223
+ var fxHttpEntryKeptNote = (reason, profilePath, retryCommand) => `fx still reaches Pushary over HTTP ("${FX_SERVER_NAME}" in ${profilePath}), because ${FX_HTTP_ENTRY_KEPT_BECAUSE[reason]}. ${FX_HTTP_CALLS_CAN_DROP}. Run ${retryCommand} to switch it.`;
224
+ var fxHttpEntryDoctorNote = (profilePath, upgradeCommand) => `${profilePath} points "${FX_SERVER_NAME}" straight at Pushary over HTTP. ${FX_HTTP_CALLS_CAN_DROP}. Run ${upgradeCommand} to switch it to the local bridge.`;
203
225
  var isBridgeTarget = (part) => namesBridge(part);
204
226
  var fxBridgeTargetOf = (value) => {
205
227
  const entry = asRecord(value);
@@ -435,6 +457,31 @@ var fxServerHolder = (profilePath, appBridge) => {
435
457
  if (!isFxPusharyEntry(entry)) return "none";
436
458
  return fxBridgeTargetOf(entry) === appBridge ? "app" : "cli";
437
459
  };
460
+ var fxBridgeEntryAt = (bridgePath) => fxPusharyEntry(guardedArgv({ kind: "binary", path: bridgePath, runtime: "node" }));
461
+ var cliFxBridgeEntry = () => fxBridgeEntryAt(resolveGlobalBinary(MCP_BRIDGE_BINARY) ?? MCP_BRIDGE_BINARY);
462
+ var installedCliFxBridgeEntry = () => {
463
+ const installed = resolveGlobalBinary(MCP_BRIDGE_BINARY);
464
+ return installed === void 0 ? void 0 : fxBridgeEntryAt(installed);
465
+ };
466
+ var NO_FX_PUSHARY_HTTP_WIRING = { pusharyOverHttp: false, otherHttpServers: [] };
467
+ var inspectFxPusharyHttpWiring = (profilePath) => {
468
+ const read = readFxFile(profilePath, readFxProfile);
469
+ if (read.kind !== "profile") return NO_FX_PUSHARY_HTTP_WIRING;
470
+ return {
471
+ pusharyOverHttp: isFxPusharyHttpEntry(fxPusharyEntryOf(read.profile)),
472
+ otherHttpServers: fxOtherPusharyHttpServers(read.profile)
473
+ };
474
+ };
475
+ var switchFxHttpEntryToBridge = (profilePath, bridgeEntry) => {
476
+ const read = readFxFile(profilePath, readFxProfile);
477
+ if (read.kind !== "profile" || !isFxPusharyHttpEntry(fxPusharyEntryOf(read.profile))) return "not-http";
478
+ try {
479
+ writeFxProfile(profilePath, withFxPusharyServer(read.profile, bridgeEntry));
480
+ return "switched";
481
+ } catch {
482
+ return "failed";
483
+ }
484
+ };
438
485
  var fxSettingsReadRefusal = (filePath, read) => {
439
486
  if (read.kind === "unreadable") return `${filePath} could not be read`;
440
487
  if (read.kind === "refused") return `${filePath} ${FX_SETTINGS_REFUSALS[read.reason]}`;
@@ -701,15 +748,22 @@ var removeClineServer = (settingsPath) => {
701
748
  export {
702
749
  FX_PUSHARY_TOOLS_RULE,
703
750
  fxInstructionsBody,
751
+ FX_RELOAD_AFTER_BRIDGE,
704
752
  FX_PROFILE_REFUSALS,
705
- fxPusharyEntry,
706
753
  withFxPusharyServer,
754
+ fxOtherHttpServersNote,
755
+ fxHttpEntryKeptNote,
756
+ fxHttpEntryDoctorNote,
707
757
  FX_QUESTION_TOOL,
708
758
  fxIgnoresInstructionsFile,
709
759
  readFxProfileForSetup,
710
760
  writeFxProfile,
711
761
  macAppFxBridge,
712
762
  fxServerHolder,
763
+ cliFxBridgeEntry,
764
+ installedCliFxBridgeEntry,
765
+ inspectFxPusharyHttpWiring,
766
+ switchFxHttpEntryToBridge,
713
767
  configureFxSettings,
714
768
  inspectFxInstallation,
715
769
  planFxRemoval,
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  addGeminiMcpServer,
3
3
  removeGeminiMcpServer
4
- } from "./chunk-YQDCTID4.js";
4
+ } from "./chunk-73DHP3JX.js";
5
5
  import {
6
6
  CLAUDE_CODE_AGENT,
7
7
  compatibleToolLookup
8
- } from "./chunk-2BL6KWN7.js";
8
+ } from "./chunk-6IFEYELN.js";
9
9
  import {
10
10
  CLAUDE_HOOK_EVENTS,
11
11
  PUSHARY_MCP_URL,
@@ -17,7 +17,7 @@ import {
17
17
  isPusharyHook,
18
18
  registerHookEntry,
19
19
  removeClaudeMcpServers
20
- } from "./chunk-GDLT32I4.js";
20
+ } from "./chunk-LQAAOXYJ.js";
21
21
  import {
22
22
  HOOK_COMPATIBLE_PROFILES,
23
23
  PHONE_ANSWERED_TOOLS,
@@ -28,7 +28,7 @@ import {
28
28
  pusharyMissingReason,
29
29
  refusalOutput,
30
30
  withHookHoldBudget
31
- } from "./chunk-EJR5JXMV.js";
31
+ } from "./chunk-RQOT6QL3.js";
32
32
 
33
33
  // src/config-document.ts
34
34
  import { parse, stringify } from "smol-toml";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_HOLD_BUDGET_ENV,
3
3
  hookHoldBudgetProof
4
- } from "./chunk-EJR5JXMV.js";
4
+ } from "./chunk-RQOT6QL3.js";
5
5
 
6
6
  // src/hold-budget.ts
7
7
  var takeHookHoldBudget = (args = process.argv.slice(2), env = process.env) => {
@@ -2,25 +2,31 @@ import {
2
2
  SIGNED_OUT_ON_MAC_MESSAGE,
3
3
  describeSignedOutKey,
4
4
  readSignedOutDiagnosis
5
- } from "./chunk-YB3HMDKE.js";
5
+ } from "./chunk-P4XZX7CL.js";
6
+ import {
7
+ APPROVAL_RULES_PATH
8
+ } from "./chunk-7V63A4AI.js";
6
9
  import {
7
10
  createIo
8
11
  } from "./chunk-FO3MDD26.js";
9
12
  import {
10
13
  readKeySource
11
- } from "./chunk-CNJ7SI5V.js";
14
+ } from "./chunk-PBEW5CJK.js";
12
15
  import {
13
16
  absoluteUrl,
14
17
  checkApiKey,
15
18
  describeKeyCheck,
16
19
  keyCheckFromResponse
17
- } from "./chunk-QR2QWGQI.js";
20
+ } from "./chunk-BSMHSN3Y.js";
18
21
  import {
19
22
  EXIT
20
23
  } from "./chunk-KZERVKTD.js";
21
24
  import {
22
25
  getBaseUrl
23
- } from "./chunk-A47UKPC7.js";
26
+ } from "./chunk-32OSSYGZ.js";
27
+ import {
28
+ KEY_SCOPE
29
+ } from "./chunk-RQOT6QL3.js";
24
30
 
25
31
  // src/cli/report-key.ts
26
32
  var { dim, yellow } = createIo();
@@ -61,16 +67,28 @@ var exitOnFailedResponse = async (response, baseUrl) => {
61
67
  };
62
68
  var REFUSED_SETTINGS_ACTION = {
63
69
  mode: "change the approval mode",
70
+ mode_clear: "end a temporary approval mode",
64
71
  wait: "change how long approvals wait for you",
65
72
  suggestions: "read or accept rule suggestions"
66
73
  };
67
- var APPROVAL_SETTINGS_PATH = "/dashboard/agent/settings";
68
- var AGENT_KEY_SCOPE = "agent";
69
- var isAgentKeyRefusal = (status, check) => status === 401 && check.kind === "ok" && check.identity.keyScope === AGENT_KEY_SCOPE;
74
+ var settingsChangeStep = (request, baseUrl) => {
75
+ const approvalRules = absoluteUrl(baseUrl, APPROVAL_RULES_PATH);
76
+ switch (request) {
77
+ case "mode":
78
+ return `Change it in the Pushary app, or on the dashboard: ${approvalRules}`;
79
+ case "mode_clear":
80
+ return "A temporary mode ends on its own. To end it now, pick a mode in the Pushary app.";
81
+ case "wait":
82
+ return `Change it on the dashboard: ${approvalRules}`;
83
+ case "suggestions":
84
+ return `Review them on the dashboard: ${approvalRules}`;
85
+ }
86
+ };
87
+ var isAgentKeyRefusal = (status, check) => status === 401 && check.kind === "ok" && check.identity.keyScope === KEY_SCOPE.agent;
70
88
  var describeAgentKeyRefusal = (request, baseUrl = getBaseUrl()) => ({
71
- message: `This computer's key cannot ${REFUSED_SETTINGS_ACTION[request]}. Keys from pushary login, phone pairing and the Mac app run approvals and notifications, not account settings.`,
89
+ message: `This computer's key cannot ${REFUSED_SETTINGS_ACTION[request]}. It runs approvals and notifications, not account settings.`,
72
90
  next: [
73
- `Change it from the Pushary app, your phone, or the dashboard: ${absoluteUrl(baseUrl, APPROVAL_SETTINGS_PATH)}`,
91
+ settingsChangeStep(request, baseUrl),
74
92
  "The key itself is valid. Nothing on this computer needs fixing."
75
93
  ],
76
94
  exitCode: EXIT.USAGE,
@@ -90,6 +108,5 @@ var exitOnFailedSettingsRequest = async (response, settings) => {
90
108
 
91
109
  export {
92
110
  printKeyCheck,
93
- APPROVAL_SETTINGS_PATH,
94
111
  exitOnFailedSettingsRequest
95
112
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SETUP_FLAGS
3
- } from "./chunk-UTAARXYQ.js";
3
+ } from "./chunk-ZK5WYAMI.js";
4
4
  import {
5
5
  parseFlags
6
6
  } from "./chunk-NMUI3ZWG.js";
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-PPY5N2E6.js";
10
10
  import {
11
11
  NPX_LATEST_COMMAND
12
- } from "./chunk-GO7YKPT3.js";
12
+ } from "./chunk-X2MTVD4W.js";
13
13
  import {
14
14
  CLAUDE_CONNECTOR_GUIDE,
15
15
  CLAUDE_CONNECTOR_STEPS,
@@ -17,7 +17,7 @@ import {
17
17
  CLAUDE_CONNECTOR_URL,
18
18
  COWORK_CONNECTOR_LIMIT,
19
19
  COWORK_STANDING_INSTRUCTIONS
20
- } from "./chunk-EJR5JXMV.js";
20
+ } from "./chunk-RQOT6QL3.js";
21
21
 
22
22
  // src/cli/cowork.ts
23
23
  import { readFileSync } from "fs";
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-KZERVKTD.js";
8
8
  import {
9
9
  redactSecretsFromContent
10
- } from "./chunk-EJR5JXMV.js";
10
+ } from "./chunk-RQOT6QL3.js";
11
11
 
12
12
  // src/cli/json.ts
13
13
  var writeStdoutFully = (text) => new Promise((resolve, reject) => {
@@ -2,7 +2,7 @@ import {
2
2
  isApprovalMode,
3
3
  isRecord,
4
4
  isTimeoutAction
5
- } from "./chunk-EJR5JXMV.js";
5
+ } from "./chunk-RQOT6QL3.js";
6
6
 
7
7
  // src/cli/settings-response.ts
8
8
  var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  realpath
3
- } from "./chunk-MDIGG3Q7.js";
3
+ } from "./chunk-MFWHANKG.js";
4
4
  import {
5
5
  findNativeClaudeInstall
6
- } from "./chunk-RJ6JEHCP.js";
6
+ } from "./chunk-JAKWPQ2L.js";
7
7
  import {
8
8
  readGlobalPrefixAsync,
9
9
  resolveGlobalBinary,
@@ -13,10 +13,10 @@ import {
13
13
  resolvePackageVersionFromBinary,
14
14
  resolvePathBinary,
15
15
  resolvePathBinaryAsync
16
- } from "./chunk-KS3O6O7E.js";
16
+ } from "./chunk-NAQCWM4U.js";
17
17
  import {
18
18
  MANAGED_PROVIDERS
19
- } from "./chunk-EJR5JXMV.js";
19
+ } from "./chunk-RQOT6QL3.js";
20
20
 
21
21
  // src/live-capabilities.ts
22
22
  import { homedir } from "os";
@@ -12,7 +12,7 @@ import {
12
12
  reachVerdict,
13
13
  reachesYou,
14
14
  verifyDelivery
15
- } from "./chunk-MNNQEUQC.js";
15
+ } from "./chunk-AJIT4SCL.js";
16
16
  import {
17
17
  humanIsTty,
18
18
  writeHuman
@@ -24,14 +24,14 @@ import {
24
24
  } from "./chunk-FO3MDD26.js";
25
25
  import {
26
26
  reportedInstallSource
27
- } from "./chunk-XIJTXRWB.js";
27
+ } from "./chunk-METUT7V4.js";
28
28
  import {
29
29
  NPX_LATEST_COMMAND
30
- } from "./chunk-GO7YKPT3.js";
30
+ } from "./chunk-X2MTVD4W.js";
31
31
  import {
32
32
  NO_PAIRING_COMPUTER,
33
33
  PAIR_TTL_SECONDS
34
- } from "./chunk-EJR5JXMV.js";
34
+ } from "./chunk-RQOT6QL3.js";
35
35
 
36
36
  // src/onboarding.ts
37
37
  import qrcodeTerminal from "qrcode-terminal";
@@ -2,7 +2,7 @@ import {
2
2
  DISCONNECT_AGENT_IDS,
3
3
  SETUP_AGENT_CHOICES,
4
4
  isApprovalMode
5
- } from "./chunk-EJR5JXMV.js";
5
+ } from "./chunk-RQOT6QL3.js";
6
6
 
7
7
  // src/cli/mode-request.ts
8
8
  var parseDuration = (value) => {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  findNativeClaudeInstall
3
- } from "./chunk-RJ6JEHCP.js";
3
+ } from "./chunk-JAKWPQ2L.js";
4
4
  import {
5
5
  isFile
6
- } from "./chunk-KS3O6O7E.js";
6
+ } from "./chunk-NAQCWM4U.js";
7
7
 
8
8
  // src/wrapper/claudeBinary.ts
9
9
  import { homedir } from "os";
@@ -7,7 +7,7 @@ import {
7
7
  recordSealerFor,
8
8
  uploadTranscriptRecords,
9
9
  wrapSessionKey
10
- } from "./chunk-XEXF2OFZ.js";
10
+ } from "./chunk-NWN6GGJL.js";
11
11
 
12
12
  // src/live-session.ts
13
13
  var MAX_TRANSCRIPT_QUEUE = 100;