pushary 1.9.117 → 1.9.119

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 (130) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/{api-OXKVQGTP.js → api-WWB7ZOLK.js} +11 -11
  3. package/dist/bin/pushary-audit.js +3 -3
  4. package/dist/bin/pushary-bell-hook.js +27 -27
  5. package/dist/bin/pushary-bell.js +10 -10
  6. package/dist/bin/pushary-claude.js +35 -40
  7. package/dist/bin/pushary-clean.js +43 -43
  8. package/dist/bin/pushary-codex-bridge.js +21 -21
  9. package/dist/bin/pushary-codex-hook.js +64 -75
  10. package/dist/bin/pushary-codex-session.js +8 -8
  11. package/dist/bin/pushary-codex.js +15 -15
  12. package/dist/bin/pushary-connect.js +28 -28
  13. package/dist/bin/pushary-cowork.js +5 -5
  14. package/dist/bin/pushary-daemon.js +44 -44
  15. package/dist/bin/pushary-disconnect.js +27 -27
  16. package/dist/bin/pushary-display-hook.js +17 -17
  17. package/dist/bin/pushary-doctor.js +47 -47
  18. package/dist/bin/pushary-elicitation-hook.js +27 -27
  19. package/dist/bin/pushary-gemini-bridge.js +15 -15
  20. package/dist/bin/pushary-gemini-hook.js +93 -90
  21. package/dist/bin/pushary-hook.js +33 -32
  22. package/dist/bin/pushary-login.js +22 -22
  23. package/dist/bin/pushary-logout.js +26 -26
  24. package/dist/bin/pushary-mcp.js +12 -12
  25. package/dist/bin/pushary-mode.js +15 -15
  26. package/dist/bin/pushary-notification-hook.js +26 -26
  27. package/dist/bin/pushary-opencode-hook.js +93 -75
  28. package/dist/bin/pushary-permission-denied-hook.js +33 -32
  29. package/dist/bin/pushary-permission-hook.js +33 -32
  30. package/dist/bin/pushary-post-hook.js +26 -26
  31. package/dist/bin/pushary-prompt-hook.js +26 -26
  32. package/dist/bin/pushary-session-end-hook.js +26 -26
  33. package/dist/bin/pushary-session-start-hook.js +35 -35
  34. package/dist/bin/pushary-setup.js +90 -90
  35. package/dist/bin/pushary-stats.js +5 -5
  36. package/dist/bin/pushary-status.js +32 -32
  37. package/dist/bin/pushary-stop-hook.js +26 -26
  38. package/dist/bin/pushary-stopfailure-hook.js +26 -26
  39. package/dist/bin/pushary-suggestions.js +15 -15
  40. package/dist/bin/pushary-transcript-register.js +17 -17
  41. package/dist/bin/pushary-transcripts.js +25 -25
  42. package/dist/bin/pushary-upgrade.js +43 -43
  43. package/dist/bin/pushary-wait.js +17 -17
  44. package/dist/bin/pushary.js +7 -7
  45. package/dist/{chunk-3ZQT5LQ3.js → chunk-2C45MJGK.js} +9 -6
  46. package/dist/{chunk-H5RGOO3B.js → chunk-2UE2NDCX.js} +1 -1
  47. package/dist/{chunk-NSCLVG7M.js → chunk-3B7S2H4R.js} +1 -1
  48. package/dist/{chunk-EXWJBUL5.js → chunk-3IESC326.js} +3 -3
  49. package/dist/{chunk-PHCZ26TZ.js → chunk-4D23TNCL.js} +4 -4
  50. package/dist/{chunk-DH23XX7X.js → chunk-4HDX77ND.js} +3 -3
  51. package/dist/{chunk-NI5KTEVM.js → chunk-4SZM2HRA.js} +6 -6
  52. package/dist/{chunk-XIJ4ADBX.js → chunk-5HKU4VUL.js} +3 -3
  53. package/dist/{chunk-EBL6XYOI.js → chunk-5T5T4YXM.js} +1 -1
  54. package/dist/{chunk-LN6LLUY7.js → chunk-67I7QRQB.js} +1 -1
  55. package/dist/{chunk-2NN5ODYJ.js → chunk-6KX2H4I5.js} +3 -3
  56. package/dist/{chunk-BSSD6UWJ.js → chunk-6YLVNFQZ.js} +3 -3
  57. package/dist/{chunk-U2AB2ZUZ.js → chunk-7CJ7W2RH.js} +4 -4
  58. package/dist/{chunk-MKTZZPWV.js → chunk-AGXOTZID.js} +5 -5
  59. package/dist/{chunk-MYSBGQU6.js → chunk-B7BOENW7.js} +1 -1
  60. package/dist/{chunk-SUMWA5VN.js → chunk-BQ673OOD.js} +2 -2
  61. package/dist/{chunk-ARRXCME5.js → chunk-CBLFIWPI.js} +2 -2
  62. package/dist/{chunk-7VPA5PXJ.js → chunk-COXNQUDP.js} +4 -4
  63. package/dist/{chunk-PHDPS5C7.js → chunk-CXIYGD33.js} +2 -2
  64. package/dist/{chunk-YEV6CIQZ.js → chunk-DXJUASTS.js} +2 -2
  65. package/dist/{chunk-X2JY437V.js → chunk-EFFH2FYG.js} +2 -2
  66. package/dist/{chunk-BJ7FGYF7.js → chunk-EISUEJDT.js} +6 -6
  67. package/dist/{chunk-4UGNMAQ2.js → chunk-EP6I3MQY.js} +4 -4
  68. package/dist/{chunk-IUPEFEBH.js → chunk-FPG7X2GS.js} +4 -4
  69. package/dist/{chunk-5TVOBKRE.js → chunk-G4OVFWU4.js} +20 -14
  70. package/dist/{chunk-4BV525QE.js → chunk-G5FQU2XF.js} +6 -6
  71. package/dist/{chunk-NZFYK75R.js → chunk-GAOUWLYN.js} +3 -3
  72. package/dist/{chunk-2KYPNVRC.js → chunk-GBVTVTDF.js} +1 -1
  73. package/dist/{chunk-BE6JIWTM.js → chunk-GW3PE52Q.js} +1 -1
  74. package/dist/{chunk-PPNJ3INA.js → chunk-HYTDNEXV.js} +1 -1
  75. package/dist/{chunk-K54Y2QFA.js → chunk-ISVHV2DP.js} +1 -1
  76. package/dist/{chunk-RVYREG7X.js → chunk-JJNF6QU4.js} +1 -1
  77. package/dist/{chunk-F3Z7UWM6.js → chunk-JKS4MN47.js} +6 -6
  78. package/dist/{chunk-S5MQA774.js → chunk-K5WTTEIQ.js} +5 -5
  79. package/dist/{chunk-FKH3KT4U.js → chunk-KILSIJTF.js} +31 -21
  80. package/dist/{chunk-XU4DUX7K.js → chunk-KOZBVXXC.js} +3 -3
  81. package/dist/{chunk-TKTNQORW.js → chunk-KVDN4U6W.js} +10 -10
  82. package/dist/{chunk-RYAWSPAR.js → chunk-L3MCQSES.js} +5 -5
  83. package/dist/{chunk-MHU7CW7T.js → chunk-MEPYLTWF.js} +10 -10
  84. package/dist/{chunk-FRIQ4LQ5.js → chunk-MYNLU6DV.js} +2 -2
  85. package/dist/{chunk-N74WJAL6.js → chunk-NASQPMXW.js} +9 -9
  86. package/dist/{chunk-XJC6PG7J.js → chunk-NVV3YUTX.js} +2 -2
  87. package/dist/{chunk-T3UOM443.js → chunk-PDAOZ2NF.js} +10 -10
  88. package/dist/{chunk-R5ZMI6BM.js → chunk-PJSFKKZ5.js} +1 -1
  89. package/dist/{chunk-4SI3CUWN.js → chunk-PNSIMPC7.js} +6 -6
  90. package/dist/{chunk-N4DQDFEP.js → chunk-R3RTISDD.js} +1 -1
  91. package/dist/{chunk-GJNWZWMA.js → chunk-R67NTMBY.js} +8 -8
  92. package/dist/{chunk-3OVRAD25.js → chunk-RGXFBS56.js} +3 -3
  93. package/dist/{chunk-UJGA7WL5.js → chunk-RIAELZYW.js} +2 -2
  94. package/dist/{chunk-74MC5LRW.js → chunk-SE7P5BBK.js} +1 -1
  95. package/dist/{chunk-2UYYX6VC.js → chunk-SNKC2IQZ.js} +2 -2
  96. package/dist/{chunk-DE6ZYZZZ.js → chunk-SQRS4IF2.js} +3 -3
  97. package/dist/{chunk-G5EB7GAR.js → chunk-SSBETUYZ.js} +3 -3
  98. package/dist/{chunk-C2NKILG3.js → chunk-TLCJCP5R.js} +1 -1
  99. package/dist/{chunk-KYWTX4R2.js → chunk-TRDHHF3A.js} +337 -37
  100. package/dist/{chunk-RCCISH7T.js → chunk-TZYVXTLN.js} +1 -1
  101. package/dist/{chunk-6ICAZ33G.js → chunk-U32N5JZO.js} +1 -1
  102. package/dist/{chunk-BL7ESWIQ.js → chunk-UHAUC7EO.js} +2 -2
  103. package/dist/{chunk-C32IT2TR.js → chunk-V52J2THT.js} +1 -1
  104. package/dist/chunk-VFZ2PE6U.js +60 -0
  105. package/dist/{chunk-DZI6MSR4.js → chunk-VMM6JCNQ.js} +2 -2
  106. package/dist/{chunk-MI56IIXG.js → chunk-VRZOUCIK.js} +2 -2
  107. package/dist/{chunk-2JQZFGIF.js → chunk-W5ZUDPKV.js} +5 -5
  108. package/dist/{chunk-ZJKH3CTN.js → chunk-W6LKC5YD.js} +5 -5
  109. package/dist/{chunk-J3PBLQUD.js → chunk-XBH6OKHD.js} +3 -3
  110. package/dist/{chunk-SE62HPB7.js → chunk-XNCKBVZX.js} +6 -61
  111. package/dist/{chunk-SQLXC4PM.js → chunk-YCCLWG7G.js} +6 -6
  112. package/dist/{chunk-YU3LDR5W.js → chunk-YZ7V2LVG.js} +3 -3
  113. package/dist/{chunk-MA4KQLCT.js → chunk-YZESBU7F.js} +5 -5
  114. package/dist/{chunk-FW2SOQ5J.js → chunk-Z3OG44Z4.js} +4 -4
  115. package/dist/chunk-ZLUAXGAA.js +121 -0
  116. package/dist/{chunk-6GZU4IYU.js → chunk-ZTVBM3EZ.js} +4 -4
  117. package/dist/{codex-app-cards-switch-ANBV6CA6.js → codex-app-cards-switch-J6EULXO5.js} +12 -12
  118. package/dist/{codex-card-routing-POEBILLG.js → codex-card-routing-XNJB6573.js} +2 -2
  119. package/dist/{codex-desktop-launch-Z4HXKBYP.js → codex-desktop-launch-46ELENBQ.js} +1 -1
  120. package/dist/{codex-session-launch-XA6BMIVU.js → codex-session-launch-R5FHFWAG.js} +18 -18
  121. package/dist/{config-ATKVK4QQ.js → config-RKWDMDRY.js} +3 -3
  122. package/dist/{global-upgrade-BJKCVYJU.js → global-upgrade-E65GJQS6.js} +9 -9
  123. package/dist/{identity-X3FI7ZYE.js → identity-JRGY2KS6.js} +4 -4
  124. package/dist/{live-capabilities-6OV363JK.js → live-capabilities-SOO6PD7Y.js} +4 -4
  125. package/dist/{paths-U67N2RPP.js → paths-G7NZODAY.js} +3 -3
  126. package/dist/{reapply-L3KVM3ZO.js → reapply-YKN5BKIP.js} +28 -28
  127. package/dist/src/index.js +32 -31
  128. package/dist/{upgrade-lock-ZIPY7I2T.js → upgrade-lock-YKAZI3BH.js} +4 -4
  129. package/dist/{usage-RAJPNVE5.js → usage-QWYNOIU6.js} +3 -3
  130. package/package.json +2 -2
@@ -1378,14 +1378,29 @@ function parseCommitId(value) {
1378
1378
  // ../contracts/src/conversation-text.ts
1379
1379
  var INTERNAL_ENVELOPE = /(^|\n) {0,3}(?:<(total_tokens|task-notification)>[\s\S]*?(?:<\/\2>|$)[\t ]*)+/g;
1380
1380
  var INCOMPLETE_ENVELOPE = /(^|\n) {0,3}<(?:total_tokens|task-notification)$/g;
1381
+ var AGENT_MESSAGE_OPENING = /^ {0,3}<agent-message from=/;
1382
+ var AGENT_MESSAGE_CLOSING = "</agent-message>";
1381
1383
  var SUGGESTION_REQUEST = /^This is an app-generated request for a suggested next user(?: message| prompt)/;
1382
1384
  var visibleProse = (text3) => text3.replace(INTERNAL_ENVELOPE, "$1").replace(INCOMPLETE_ENVELOPE, "$1");
1385
+ var textAfterAgentMessage = (line) => {
1386
+ const closing = line.indexOf(AGENT_MESSAGE_CLOSING);
1387
+ return closing === -1 ? null : line.slice(closing + AGENT_MESSAGE_CLOSING.length);
1388
+ };
1383
1389
  function conversationText(text3) {
1384
1390
  if (SUGGESTION_REQUEST.test(text3.trimStart())) return "";
1385
1391
  const output = [];
1386
1392
  let prose = [];
1387
1393
  let fence = null;
1388
- for (const line of text3.split("\n")) {
1394
+ let insideAgentMessage = false;
1395
+ const lines = text3.split("\n").reverse();
1396
+ while (lines.length > 0) {
1397
+ const line = lines.pop() ?? "";
1398
+ if (insideAgentMessage || !fence && AGENT_MESSAGE_OPENING.test(line)) {
1399
+ const after = textAfterAgentMessage(line);
1400
+ insideAgentMessage = after === null;
1401
+ if (after?.trim()) lines.push(after);
1402
+ continue;
1403
+ }
1389
1404
  const marker = /^ {0,3}(`{3,}|~{3,})/.exec(line)?.[1];
1390
1405
  if (fence) {
1391
1406
  output.push(line);
@@ -1599,6 +1614,65 @@ var SEGMENT_SEPARATORS = /* @__PURE__ */ new Set([";", "\n", "&", "|"]);
1599
1614
  var DOUBLED_SEPARATORS = /* @__PURE__ */ new Set(["&", "|"]);
1600
1615
  var UNDECOMPOSABLE = /* @__PURE__ */ new Set(["`", "<", ">"]);
1601
1616
  var LITERAL_IN_DOUBLE_QUOTES = /* @__PURE__ */ new Set([";", "|", "&", "<", ">", "*", "?", "[", "\\"]);
1617
+ var OPENS_A_WORD_AFTER = /[ \t\n;&|()`]/;
1618
+ var COMMENT_OR_ANSI_C_QUOTE = /#|\$'/;
1619
+ var INERT_ANSI_C_ESCAPE = "__";
1620
+ var runLengthBefore = (text3, index, char) => {
1621
+ let length = 0;
1622
+ while (text3.charAt(index - 1 - length) === char) length += 1;
1623
+ return length;
1624
+ };
1625
+ var opensAnsiCQuote = (text3, index) => {
1626
+ const dollars = runLengthBefore(text3, index, "$");
1627
+ const backslashes = runLengthBefore(text3, index - dollars, "\\");
1628
+ return text3.charAt(index) === "'" && (dollars - backslashes % 2) % 2 === 1;
1629
+ };
1630
+ var readingWithoutCommentsOrAnsiEscapes = (text3) => {
1631
+ if (!COMMENT_OR_ANSI_C_QUOTE.test(text3)) return null;
1632
+ let reading = "";
1633
+ let changed = false;
1634
+ let quote = null;
1635
+ let ansiC = false;
1636
+ let inComment = false;
1637
+ let atWordStart = true;
1638
+ for (let index = 0; index < text3.length; index += 1) {
1639
+ const char = text3.charAt(index);
1640
+ const next = text3.charAt(index + 1);
1641
+ if (inComment && char !== "\n") continue;
1642
+ inComment = false;
1643
+ if (ansiC && char === "\\" && next) {
1644
+ reading += INERT_ANSI_C_ESCAPE;
1645
+ changed = true;
1646
+ index += 1;
1647
+ } else if (char === "\\" && quote !== "'") {
1648
+ reading += char + next;
1649
+ atWordStart = next === "\n" ? atWordStart : false;
1650
+ index += 1;
1651
+ } else if (quote === "'") {
1652
+ reading += char;
1653
+ if (char === quote) {
1654
+ quote = null;
1655
+ ansiC = false;
1656
+ }
1657
+ atWordStart = false;
1658
+ } else if (char === "'" || char === '"') {
1659
+ reading += char;
1660
+ if (quote === char) quote = null;
1661
+ else if (quote === null) {
1662
+ ansiC = opensAnsiCQuote(text3, index);
1663
+ quote = char;
1664
+ }
1665
+ atWordStart = false;
1666
+ } else if (quote === null && atWordStart && char === COMMENT_START) {
1667
+ inComment = true;
1668
+ changed = true;
1669
+ } else {
1670
+ reading += char;
1671
+ atWordStart = quote === null && OPENS_A_WORD_AFTER.test(char);
1672
+ }
1673
+ }
1674
+ return changed ? reading : null;
1675
+ };
1602
1676
  var scanShell = (command) => {
1603
1677
  const lexemes = [];
1604
1678
  let quote = null;
@@ -1642,6 +1716,112 @@ var splitShellSegments = (command) => {
1642
1716
  const present = segments.filter((segment) => segment.text.length > 0);
1643
1717
  return present.length > 0 ? present : null;
1644
1718
  };
1719
+ var COMMAND_POSITION = String.raw`(^[ \t]*|[;&|(` + "`" + String.raw`\n][ \t]*|\b(?:then|do|else|elif|if|while|until)[ \t]+|[{!][ \t]+)`;
1720
+ var COMMAND_PREFIXES = String.raw`(?:[A-Za-z_]\w*=\S*[ \t]+|(?:sudo|env|exec|command|builtin|nohup|time|nice(?:[ \t]+-n[ \t]+\S+)?|timeout[ \t]+\S+)(?:[ \t]+-[^\s<]*){0,4}[ \t]+){0,8}`;
1721
+ var A_SHELL_RUNNING_A_SUBSTITUTION = new RegExp(
1722
+ String.raw`${COMMAND_POSITION}${COMMAND_PREFIXES}(?:[^\s;&|()<>` + "`" + String.raw`]*/)?(?:sh|bash|zsh|dash|ksh|source|\.)(?:[ \t]+-[^\s<]*){0,8}[ \t]+(?:<[ \t]*)?[<=](?=\()`,
1723
+ "g"
1724
+ );
1725
+ var AN_EVAL_THAT_RUNS = new RegExp(String.raw`${COMMAND_POSITION}${COMMAND_PREFIXES}eval[ \t]+`, "g");
1726
+ var CASE_HEAD = /(^|[\s;&|(])case[ \t]+(?:"[^"\n]*"|'[^'\n]*'|\S+)[ \t\n]+in(?=[\s;])/g;
1727
+ var CASE_ARM_OPENING = /;[;&]{0,2}[ \t\n]*\(?[^()\s;][^()\n;]*\)[ \t\n]*/g;
1728
+ var CASE_ARM_ENDING = /;;&?|;&/g;
1729
+ var CASE_WORD = /\bcase\b/;
1730
+ var ESAC_WORD = /\besac\b/g;
1731
+ var COPROC_PREFIX = /(^|[\s;&|(])coproc[ \t]+(?:[A-Za-z_]\w*[ \t]+(?=[{(]))?/g;
1732
+ var A_FUNCTION_WITH_A_SUBSHELL_BODY = /(^|[\s;&|])(?:function[ \t]+[\w.:-]+(?:[ \t]*\(\))?|[\w.:-]+[ \t]*\(\))[ \t\n]*(?=\()/g;
1733
+ var NPX_GIVEN_A_COMMAND_STRING = /(^|[\s;&|(])npx(?:[ \t]+(?:(?:-p|--package)[ \t]+[^\s;&|]+|(?!-c\b|--call\b)-[^\s;&|]+)){0,8}?[ \t]+(?:-c|--call)(?:[ \t]+|=)/g;
1734
+ var SU_GIVEN_A_COMMAND_STRING = /(^|[\s;&|(])su(?:[ \t]+(?!-c\b|--command\b)[^\s;&|]+){0,8}?[ \t]+(?:-c|--command)(?:[ \t]+|=)/g;
1735
+ var PARALLEL_PREFIX = /(^|[\s;&|(])parallel[ \t]+(?=[^-\s])/g;
1736
+ var closingParenthesisOf = (text3, open) => {
1737
+ let depth = 0;
1738
+ let quote = null;
1739
+ for (let index = open; index < text3.length; index += 1) {
1740
+ const char = text3.charAt(index);
1741
+ if (quote === "'") {
1742
+ if (char === "'") quote = null;
1743
+ } else if (char === "\\") {
1744
+ index += 1;
1745
+ } else if (quote === '"') {
1746
+ if (char === '"') quote = null;
1747
+ } else if (char === "'" || char === '"') {
1748
+ quote = char;
1749
+ } else if (char === "(") {
1750
+ depth += 1;
1751
+ } else if (char === ")") {
1752
+ depth -= 1;
1753
+ if (depth === 0) return index;
1754
+ }
1755
+ }
1756
+ return null;
1757
+ };
1758
+ var withSubstitutionsPipedIntoAShell = (text3) => {
1759
+ let reading = "";
1760
+ let from = 0;
1761
+ for (const match of text3.matchAll(A_SHELL_RUNNING_A_SUBSTITUTION)) {
1762
+ const open = match.index + match[0].length;
1763
+ const close = match.index < from ? null : closingParenthesisOf(text3, open);
1764
+ if (close !== null) {
1765
+ reading += `${text3.slice(from, match.index)}${match[1]}${text3.slice(open + 1, close)} | sh`;
1766
+ from = close + 1;
1767
+ }
1768
+ }
1769
+ return reading + text3.slice(from);
1770
+ };
1771
+ var withCaseArmsAsCommands = (text3) => CASE_WORD.test(text3) && text3.search(ESAC_WORD) !== -1 ? text3.replace(CASE_HEAD, "$1true;").replace(CASE_ARM_OPENING, ";").replace(CASE_ARM_ENDING, ";").replace(ESAC_WORD, "true") : text3;
1772
+ var withoutCoprocPrefix = (text3) => text3.replace(COPROC_PREFIX, "$1");
1773
+ var withFunctionSubshellBodiesExposed = (text3) => text3.replace(A_FUNCTION_WITH_A_SUBSHELL_BODY, "$1");
1774
+ var withCommandStringsRunByAShell = (text3) => text3.replace(NPX_GIVEN_A_COMMAND_STRING, "$1sh -c ").replace(SU_GIVEN_A_COMMAND_STRING, "$1sh -c ");
1775
+ var withoutParallelPrefix = (text3) => text3.replace(PARALLEL_PREFIX, "$1");
1776
+ var SHELL_FORM_REWRITES = [
1777
+ withSubstitutionsPipedIntoAShell,
1778
+ withCaseArmsAsCommands,
1779
+ withoutCoprocPrefix,
1780
+ withFunctionSubshellBodiesExposed,
1781
+ withCommandStringsRunByAShell,
1782
+ withoutParallelPrefix
1783
+ ];
1784
+ var readingWithShellFormsSpelledOut = (text3) => {
1785
+ const reading = SHELL_FORM_REWRITES.reduce((current, rewrite) => rewrite(current), text3);
1786
+ return reading === text3 ? null : reading;
1787
+ };
1788
+ var SHELLS_THAT_RUN_A_SCRIPT_ARGUMENT = /* @__PURE__ */ new Set(["sh", "bash", "zsh", "dash", "ksh"]);
1789
+ var SHORT_FLAGS_WITH_THE_COMMAND_FLAG = /^-[A-Za-z]*c[A-Za-z]*$/;
1790
+ var SHELL_LONG_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Set(["--rcfile", "--init-file"]);
1791
+ var SHELL_SHORT_FLAGS_ENDING_IN_AN_OPTION_NAME = /^[-+][A-Za-z]*[oO]$/;
1792
+ var SHELL_OPTION_WORD = /^[-+]/;
1793
+ var COMMAND_SEPARATOR_INSIDE_A_WORD = /[;&|()`]/;
1794
+ var DEEPEST_NESTED_SCRIPT_READ = 3;
1795
+ var MOST_SCRIPTS_READ_FROM_ONE_COMMAND = 16;
1796
+ var programNamedBy = (word) => basenameOf(word.split(COMMAND_SEPARATOR_INSIDE_A_WORD).filter((piece) => piece !== "").pop() ?? "");
1797
+ var scriptArgumentOfAShellAt = (words, index) => {
1798
+ if (!SHELLS_THAT_RUN_A_SCRIPT_ARGUMENT.has(programNamedBy(words[index]?.text ?? ""))) return void 0;
1799
+ for (let next = index + 1; SHELL_OPTION_WORD.test(words[next]?.text ?? ""); next += 1) {
1800
+ const option = words[next]?.text ?? "";
1801
+ if (SHORT_FLAGS_WITH_THE_COMMAND_FLAG.test(option)) return words[next + 1]?.text;
1802
+ if (SHELL_LONG_OPTIONS_WITH_A_VALUE.has(option) || SHELL_SHORT_FLAGS_ENDING_IN_AN_OPTION_NAME.test(option)) next += 1;
1803
+ }
1804
+ return void 0;
1805
+ };
1806
+ var scriptsOfShellsIn = (text3) => {
1807
+ const words = shellWordsOf(text3);
1808
+ return words === null ? [] : words.flatMap((_, index) => scriptArgumentOfAShellAt(words, index) ?? []);
1809
+ };
1810
+ var scriptOfAnEvalEndingAt = (text3, end) => {
1811
+ const words = shellWordsOf(text3.slice(end));
1812
+ return words === null ? [] : [words.map((word) => word.text).join(" ")];
1813
+ };
1814
+ var scriptsOfEvalsIn = (text3) => [...text3.matchAll(AN_EVAL_THAT_RUNS)].slice(0, MOST_SCRIPTS_READ_FROM_ONE_COMMAND).flatMap((match) => scriptOfAnEvalEndingAt(text3, match.index + match[0].length));
1815
+ var scriptsDirectlyInside = (text3) => [...scriptsOfEvalsIn(text3), ...scriptsOfShellsIn(text3)];
1816
+ var scriptsPassedToAShell = (text3) => {
1817
+ const found = [];
1818
+ let level = [text3];
1819
+ for (let depth = 0; depth < DEEPEST_NESTED_SCRIPT_READ && level.length > 0 && found.length < MOST_SCRIPTS_READ_FROM_ONE_COMMAND; depth += 1) {
1820
+ level = level.flatMap(scriptsDirectlyInside).slice(0, MOST_SCRIPTS_READ_FROM_ONE_COMMAND - found.length);
1821
+ found.push(...level);
1822
+ }
1823
+ return found;
1824
+ };
1645
1825
  var shellCommandSegments = (command) => splitShellSegments(command)?.map((segment) => segment.text) ?? null;
1646
1826
  var shellSegmentsReadingAPipe = (command) => splitShellSegments(command)?.filter((segment) => segment.readsPipe).map((segment) => segment.text) ?? null;
1647
1827
  var SUBSTITUTION_OPEN = "$(";
@@ -3488,10 +3668,14 @@ var readSetupOutcomeProperties = (body) => {
3488
3668
  // ../contracts/src/policy-capabilities.ts
3489
3669
  var POLICY_REQUEST_CAPABILITIES_HEADER = "x-pushary-policy-capabilities";
3490
3670
  var POLICY_REQUEST_CAPABILITY = {
3491
- readsCommandRunnersAndAVersionedCache: "command-runners-1"
3671
+ readsCommandRunnersAndAVersionedCache: "command-runners-1",
3672
+ readsWhereAPushLands: "push-destinations-1"
3492
3673
  };
3493
3674
  var KNOWN_POLICY_REQUEST_CAPABILITIES = Object.values(POLICY_REQUEST_CAPABILITY);
3494
- var CLI_POLICY_REQUEST_CAPABILITIES = [POLICY_REQUEST_CAPABILITY.readsCommandRunnersAndAVersionedCache];
3675
+ var CLI_POLICY_REQUEST_CAPABILITIES = [
3676
+ POLICY_REQUEST_CAPABILITY.readsCommandRunnersAndAVersionedCache,
3677
+ POLICY_REQUEST_CAPABILITY.readsWhereAPushLands
3678
+ ];
3495
3679
  var POLICY_REQUEST_CAPABILITY_SEPARATOR = ",";
3496
3680
  var policyRequestCapabilitiesHeaderValue = (capabilities) => capabilities.join(POLICY_REQUEST_CAPABILITY_SEPARATOR);
3497
3681
 
@@ -7939,8 +8123,10 @@ var denyReasonFrom = (value, note) => {
7939
8123
  if (trimmed) return `${PHONE_DENIAL_PREFIX}${trimmed}`;
7940
8124
  return value && value !== DENY_ANSWER && value !== APPROVE_ANSWER ? `${PHONE_DENIAL_PREFIX}${value}` : PHONE_DENIAL_REASON;
7941
8125
  };
7942
- var APPROVE_RESPONSES = /* @__PURE__ */ new Set([APPROVE_ANSWER, "approve", "approved"]);
7943
- var DENY_RESPONSES = /* @__PURE__ */ new Set([DENY_ANSWER, "deny", "denied", "reject", "rejected"]);
8126
+ var APPROVE_RESPONSE_WORDS = [APPROVE_ANSWER, "approve", "approved"];
8127
+ var DENY_RESPONSE_WORDS = [DENY_ANSWER, "deny", "denied", "reject", "rejected"];
8128
+ var APPROVE_RESPONSES = new Set(APPROVE_RESPONSE_WORDS);
8129
+ var DENY_RESPONSES = new Set(DENY_RESPONSE_WORDS);
7944
8130
  var DEFER_RESPONSES = /* @__PURE__ */ new Set([DEFER_ANSWER]);
7945
8131
  var classifyConfirmResponse = (response) => {
7946
8132
  const normalized = (response ?? "").trim().toLowerCase();
@@ -8473,13 +8659,24 @@ var bypassModeApplies = (input) => isBypassPermissionMode(input.permissionMode)
8473
8659
  var bypassModeAllows = (input) => bypassModeApplies(input) && (bypassStopsOf(input.config) === "nothing" ? !aChosenRuleGovernsInEitherRepository(input, ruleAsksOrRefuses) : bypassModeCoversEveryInput(input));
8474
8660
  var PERMISSIONS_OFF_ASK_REASON = "Permissions are off in your agent, so Pushary only stops for risky steps like this one. You can change this in Settings on pushary.com.";
8475
8661
  var permissionsOffLineAppliesTo = (agentType) => agentType === CLAUDE_CODE_AGENT_TYPE;
8476
- var askAtTheRouteOfAPushOfTheCurrentBranch = (input, repoKey) => {
8662
+ var PATTERN_PREFIX_WILDCARD = /(?::\*|\*)?\)$/;
8663
+ var CONTINUES_A_COMMAND_WORD = /^[ :]/;
8664
+ var ruleNarrowsThePattern = (ruleTool, pattern) => {
8665
+ if (ruleTool === pattern) return false;
8666
+ if (!pattern.includes("(")) return ruleTool.includes("(");
8667
+ const prefix = pattern.replace(PATTERN_PREFIX_WILDCARD, "");
8668
+ return ruleTool.startsWith(prefix) && CONTINUES_A_COMMAND_WORD.test(ruleTool.slice(prefix.length));
8669
+ };
8670
+ var askAtTheRouteOfAPush = (input, repoKey, allowedBy) => {
8477
8671
  const routes = approvalRoutesOf(input.config);
8478
- if (routes === null || input.currentBranch === void 0) return void 0;
8672
+ if (routes === null) return void 0;
8673
+ const askRows = input.config.policies.filter((policy) => restricts(policy) && !isAutoDeny(policy) && appliesToThisCall(policy, repoKey, input.sessionId));
8674
+ const routesWithAnAsk = routes.filter((route) => askRows.some((policy) => policy.tool === route.toolPattern));
8675
+ const routesTheAllowDoesNotNarrow = routesWithAnAsk.filter((route) => !ruleNarrowsThePattern(allowedBy.tool, route.toolPattern));
8676
+ const bestOf = (candidates, spellings) => spellings.length === 0 ? void 0 : findBestRoute(candidates, input.toolName, spellings, repoKey);
8479
8677
  for (const toolInput of input.toolInputs) {
8480
- const pushes = pushesOfTheCurrentBranchIn(input, toolInput);
8481
- const route = pushes.length === 0 ? void 0 : findBestRoute(routes, input.toolName, pushes, repoKey);
8482
- const ask = route && input.config.policies.find((policy) => policy.tool === route.toolPattern && restricts(policy) && !isAutoDeny(policy) && appliesToThisCall(policy, repoKey, input.sessionId));
8678
+ const route = bestOf(routesWithAnAsk, pushesOfTheCurrentBranchIn(input, toolInput)) ?? bestOf(routesTheAllowDoesNotNarrow, pushSpellingsBeyondTheWrittenOnesIn(input, toolInput));
8679
+ const ask = route && askRows.find((policy) => policy.tool === route.toolPattern);
8483
8680
  if (ask) {
8484
8681
  const mode = input.modeState.mode ?? input.config.modeOverride ?? ask.mode;
8485
8682
  return { ...ask, mode };
@@ -8488,7 +8685,37 @@ var askAtTheRouteOfAPushOfTheCurrentBranch = (input, repoKey) => {
8488
8685
  return void 0;
8489
8686
  };
8490
8687
  var permissionsOffAskReason = (input, verdict) => verdict.kind === "gate" && !verdict.scopeReason && !isAskedInEveryMode(input.toolName) && bypassModeApplies(input) && bypassStopsOf(input.config) === "consequences" && !aChosenRuleGovernsInEitherRepository(input) ? PERMISSIONS_OFF_ASK_REASON : void 0;
8491
- var resolveGate = (input) => {
8688
+ var SCOPE_QUESTION_FIRST_WAIT_SECONDS = 30;
8689
+ var policyForScopeQuestion = (policy) => policy.timeoutAction === "approve" ? {
8690
+ ...policy,
8691
+ mode: policy.mode === "push_only" ? "push_first" : policy.mode,
8692
+ timeoutAction: "wait",
8693
+ pushFirstSeconds: policy.pushFirstSeconds > 0 ? policy.pushFirstSeconds : SCOPE_QUESTION_FIRST_WAIT_SECONDS
8694
+ } : policy;
8695
+ var isAReading = (reading) => reading !== null && reading.trim() !== "";
8696
+ var extraReadingsOf = (toolInput) => {
8697
+ const { command } = toolInput;
8698
+ if (typeof command !== "string" || command.length > LONGEST_COMMAND_READ_FOR_A_PUSH) return [];
8699
+ const commentFree = readingWithoutCommentsOrAnsiEscapes(command);
8700
+ const spelledOut = [command, commentFree].filter(isAReading).map(readingWithShellFormsSpelledOut);
8701
+ const readings = [
8702
+ commentFree,
8703
+ ...spelledOut,
8704
+ ...[command, commentFree, ...spelledOut].filter(isAReading).flatMap((text3) => scriptsPassedToAShell(text3)).map(readingWithoutCommentsOrAnsiEscapes)
8705
+ ];
8706
+ return readings.filter(isAReading).map((reading) => ({ ...toolInput, command: reading }));
8707
+ };
8708
+ var readingsNotYetJudged = (toolInputs) => {
8709
+ const judged = new Set(toolInputs.map((toolInput) => toolInput.command));
8710
+ return toolInputs.flatMap(extraReadingsOf).filter((reading) => {
8711
+ const isNew = !judged.has(reading.command);
8712
+ judged.add(reading.command);
8713
+ return isNew;
8714
+ });
8715
+ };
8716
+ var withExtraReadings = (input) => shellDialectOf(input.toolName) !== void 0 ? { ...input, toolInputs: [...input.toolInputs, ...readingsNotYetJudged(input.toolInputs)] } : input;
8717
+ var resolveGate = (rawInput) => {
8718
+ const input = withExtraReadings(rawInput);
8492
8719
  const { modeState, config, toolName, toolInputs, cwd, sessionId } = input;
8493
8720
  const repoKey = input.sharedRepoKey ?? input.repoKey;
8494
8721
  if (isPusharyOwnTool(toolName)) {
@@ -8503,35 +8730,41 @@ var resolveGate = (input) => {
8503
8730
  const legacyPolicy = (toolInputs.length ? toolInputs : [void 0]).map((toolInput) => resolvePolicy(config, toolName, modeState.mode, toolInput, cwd, input.repoKey, sessionId)).find((policy2) => policy2.repoKey === input.repoKey && verdictForPolicy(policy2) === "deny");
8504
8731
  if (legacyPolicy) return { kind: "deny", policy: legacyPolicy, reason: `Denied by policy for ${legacyPolicy.tool}` };
8505
8732
  }
8506
- const policy = resolvePolicyAcross(config, toolName, modeState.mode, toolInputs, cwd, repoKey, sessionId);
8733
+ const policy = toolInputs.slice(rawInput.toolInputs.length).map((reading) => resolvePolicy(config, toolName, modeState.mode, reading, cwd, repoKey, sessionId)).reduce(
8734
+ (strictest, reading) => strictestReadingOf(reading, strictest),
8735
+ resolvePolicyAcross(config, toolName, modeState.mode, rawInput.toolInputs, cwd, repoKey, sessionId)
8736
+ );
8507
8737
  const verdict = verdictForPolicy(policy);
8508
8738
  const autoDenies = verdict === "deny";
8509
8739
  const allowedByBypassMode = !autoDenies && verdict !== "allow" && bypassModeAllows(input);
8510
- const askBesideARoutedPush = verdict === "allow" ? askAtTheRouteOfAPushOfTheCurrentBranch(input, repoKey) : void 0;
8740
+ const askBesideARoutedPush = verdict === "allow" ? askAtTheRouteOfAPush(input, repoKey, policy) : void 0;
8511
8741
  const autoApproves = (verdict === "allow" || allowedByBypassMode) && askBesideARoutedPush === void 0;
8512
8742
  const askedPolicy = askBesideARoutedPush ?? policy;
8513
8743
  if (autoDenies) return { kind: "deny", policy, reason: `Denied by policy for ${policy.tool}` };
8514
8744
  if (isAskedInEveryMode(toolName)) return { kind: "gate", policy };
8515
8745
  if (isModeStateDegraded(modeState)) {
8516
8746
  if (autoApproves) {
8517
- return survivesDegraded(config, toolName, toolInputs, cwd, repoKey, sessionId) ? { kind: "allow", policy, source: "allowlist" } : { kind: "defer", policy };
8747
+ return survivesDegraded(config, toolName, rawInput.toolInputs, cwd, repoKey, sessionId) ? { kind: "allow", policy, source: "allowlist" } : { kind: "defer", policy };
8518
8748
  }
8519
8749
  return { kind: "gate", policy: askedPolicy };
8520
8750
  }
8521
8751
  const scopeVerdict = modeState.scope ? strictestScopeVerdict(modeState.scope, input.scopePaths ?? []) : { outcome: "no_contract" };
8522
8752
  if (autoApproves) {
8523
8753
  if (!scopeRequiresHuman(scopeVerdict)) {
8754
+ if (config.knownSuperseded === true && !survivesDegraded(config, toolName, rawInput.toolInputs, cwd, repoKey, sessionId)) {
8755
+ return { kind: "defer", policy };
8756
+ }
8524
8757
  return {
8525
8758
  kind: "allow",
8526
8759
  policy: allowedByBypassMode ? autoApprove(policy.tool) : policy,
8527
- source: toolInputs.length === 1 && resolveAutoResolveOrigin(config, toolName, toolInputs[0], cwd, repoKey, sessionId) === "safe_readonly" ? "allowlist" : "policy"
8760
+ source: rawInput.toolInputs.length === 1 && resolveAutoResolveOrigin(config, toolName, rawInput.toolInputs[0], cwd, repoKey, sessionId) === "safe_readonly" ? "allowlist" : "policy"
8528
8761
  };
8529
8762
  }
8530
8763
  }
8531
8764
  const scopeReason = scopeChangeReason(scopeVerdict);
8532
8765
  return {
8533
8766
  kind: "gate",
8534
- policy: askedPolicy,
8767
+ policy: scopeReason ? policyForScopeQuestion(askedPolicy) : askedPolicy,
8535
8768
  scopeReason,
8536
8769
  scopePath: scopeReason && "path" in scopeVerdict ? widenablePath(scopeVerdict.path) : void 0
8537
8770
  };
@@ -8645,13 +8878,17 @@ var approvalRoutesOf = (config) => {
8645
8878
  const routes = config.approvalRoutes ?? [];
8646
8879
  return Array.isArray(routes) && routes.every(isApprovalRoutePattern) ? routes : null;
8647
8880
  };
8648
- var GIT_PUSH_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Set(["-o", "--push-option", "--repo", "--receive-pack", "--exec"]);
8649
- var GIT_PUSH_FLAGS_THAT_PUSH_NO_BRANCH = /* @__PURE__ */ new Set(["--dry-run", "--tags"]);
8650
- var GIT_PUSH_SHORT_FLAGS_WITH_A_DRY_RUN = /^-[A-Za-z]*n[A-Za-z]*$/;
8881
+ var GIT_PUSH_OPTIONS_WITH_A_VALUE = /* @__PURE__ */ new Set(["--push-option", "--repo", "--receive-pack", "--exec", "--recurse-submodules"]);
8882
+ var GIT_PUSH_OPTION_WITH_ITS_VALUE_ATTACHED = /^--(?:push-option|repo|receive-pack|exec|recurse-submodules)=/;
8883
+ var GIT_PUSH_SHORT_FLAGS_ENDING_IN_THE_OPTION_FLAG = /^-[A-Za-np-z]*o$/;
8884
+ var GIT_PUSH_DRY_RUN_FLAG = "--dry-run";
8885
+ var GIT_PUSH_TAGS_FLAG = "--tags";
8886
+ var GIT_PUSH_SHORT_FLAGS_WITH_A_DRY_RUN = /^-[A-Za-mp-z]*n[A-Za-z]*$/;
8651
8887
  var HEAD_REFSPECS = /* @__PURE__ */ new Set(["HEAD", "@"]);
8652
8888
  var MOVES_BEFORE_A_PUSH = /^(?:(?:if|elif|while|until)\s+)?(?:(?:cd|pushd|popd)(?:\s|$)|git\s+(?:checkout|switch)(?:\s|$))/;
8653
8889
  var LONGEST_COMMAND_READ_FOR_A_PUSH = 16 * 1024;
8654
- var pushesNoBranchItself = (word) => GIT_PUSH_FLAGS_THAT_PUSH_NO_BRANCH.has(word) || GIT_PUSH_SHORT_FLAGS_WITH_A_DRY_RUN.test(word);
8890
+ var isADryRunFlag = (word) => word === GIT_PUSH_DRY_RUN_FLAG || GIT_PUSH_SHORT_FLAGS_WITH_A_DRY_RUN.test(word);
8891
+ var takesTheNextWordAsItsValue = (word) => GIT_PUSH_OPTIONS_WITH_A_VALUE.has(word) || GIT_PUSH_SHORT_FLAGS_ENDING_IN_THE_OPTION_FLAG.test(word);
8655
8892
  var pointsGitAtAnotherRepository = (form) => {
8656
8893
  const [program, ...words] = form.split(" ");
8657
8894
  if (program !== "git") return false;
@@ -8662,44 +8899,86 @@ var pointsGitAtAnotherRepository = (form) => {
8662
8899
  }
8663
8900
  return false;
8664
8901
  };
8902
+ var wordsBeforeAComment = (form) => {
8903
+ const words = shellWordsOf(form);
8904
+ if (words === null) return form.split(" ");
8905
+ const firstComment = words.findIndex((word) => word.comment);
8906
+ return (firstComment === -1 ? words : words.slice(0, firstComment)).map((word) => word.text);
8907
+ };
8665
8908
  var gitPushWordsOf = (form) => {
8666
- const [program, subcommand, ...words] = form.split(" ");
8909
+ const [program, subcommand, ...words] = wordsBeforeAComment(form);
8667
8910
  if (program !== "git" || subcommand !== "push") return null;
8668
8911
  const flags = [];
8669
8912
  const operands = [];
8670
8913
  for (let index = 0; index < words.length; index += 1) {
8671
8914
  const word = words[index] ?? "";
8672
- if (pushesNoBranchItself(word)) return null;
8673
- if (GIT_PUSH_OPTIONS_WITH_A_VALUE.has(word)) index += 1;
8674
- else if (word.startsWith("-")) flags.push(word);
8675
- else operands.push(word);
8915
+ if (isADryRunFlag(word)) return null;
8916
+ if (takesTheNextWordAsItsValue(word)) {
8917
+ if (GIT_PUSH_FORCING_FLAG.test(word)) flags.push(word);
8918
+ index += 1;
8919
+ } else if (word.startsWith("-")) {
8920
+ if (!GIT_PUSH_OPTION_WITH_ITS_VALUE_ATTACHED.test(word)) flags.push(word);
8921
+ } else {
8922
+ operands.push(word);
8923
+ }
8676
8924
  }
8677
8925
  return { flags, operands };
8678
8926
  };
8679
8927
  var pushNamesNoBranch = ({ operands }) => operands.length <= 1 || operands.length === 2 && HEAD_REFSPECS.has(operands[1] ?? "");
8928
+ var GIT_PUSH_FORCING_FLAG = /^(?:--force(?:-with-lease|-if-includes)?(?:=.*)?|-[A-Za-z]*f[A-Za-z]*)$/;
8929
+ var GIT_PUSH_FORCE_SPELLINGS = ["--force", "-f"];
8930
+ var FORCED_REFSPEC_MARK = "+";
8931
+ var REFSPEC_SEPARATOR = ":";
8932
+ var BRANCH_REF_PREFIXES = ["refs/heads/", "heads/"];
8933
+ var DEFAULT_PUSH_REMOTE = "origin";
8934
+ var destinationOfRefspec = (refspec) => {
8935
+ const forced = refspec.startsWith(FORCED_REFSPEC_MARK);
8936
+ const spec = forced ? refspec.slice(FORCED_REFSPEC_MARK.length) : refspec;
8937
+ const destination = spec.slice(spec.lastIndexOf(REFSPEC_SEPARATOR) + 1);
8938
+ const prefix = BRANCH_REF_PREFIXES.find((candidate) => destination.startsWith(candidate));
8939
+ return { branch: prefix === void 0 ? destination : destination.slice(prefix.length), forced };
8940
+ };
8941
+ var spellingsOfAPushToADestination = (remote, { branch, forced }, flagsForce) => [
8942
+ `git push ${remote} ${branch}`,
8943
+ ...forced || flagsForce ? GIT_PUSH_FORCE_SPELLINGS.map((flag) => `git push ${flag} ${remote} ${branch}`) : []
8944
+ ];
8945
+ var flagsForceThePush = ({ flags }) => flags.some((flag) => GIT_PUSH_FORCING_FLAG.test(flag));
8946
+ var spellingsOfAPushToItsDestinations = (form) => {
8947
+ const push = gitPushWordsOf(form);
8948
+ if (push === null) return [];
8949
+ const forced = flagsForceThePush(push) ? GIT_PUSH_FORCE_SPELLINGS.map((flag) => `git push ${flag}`) : [];
8950
+ if (pushNamesNoBranch(push)) return forced;
8951
+ const [remote = DEFAULT_PUSH_REMOTE, ...refspecs] = push.operands;
8952
+ return [...forced, ...refspecs.map(destinationOfRefspec).flatMap((destination) => spellingsOfAPushToADestination(remote, destination, flagsForceThePush(push)))];
8953
+ };
8680
8954
  var spellingsOfAPushOfTheBranch = (form, branch) => {
8681
8955
  const push = gitPushWordsOf(form);
8682
- if (push === null || !pushNamesNoBranch(push)) return [];
8683
- const remote = push.operands[0] ?? "origin";
8956
+ if (push === null || push.flags.includes(GIT_PUSH_TAGS_FLAG) || !pushNamesNoBranch(push)) return [];
8957
+ const remote = push.operands[0] ?? DEFAULT_PUSH_REMOTE;
8684
8958
  return [.../* @__PURE__ */ new Set([`git push ${remote} ${branch}`, ["git push", ...push.flags, remote, branch].join(" ")])];
8685
8959
  };
8960
+ var forcedSpellingsOfAPushOfTheBranch = (form, branch) => {
8961
+ const push = gitPushWordsOf(form);
8962
+ if (push === null || !flagsForceThePush(push)) return [];
8963
+ return spellingsOfAPushOfTheBranch(form, branch).length === 0 ? [] : GIT_PUSH_FORCE_SPELLINGS.map((flag) => `git push ${flag} ${push.operands[0] ?? DEFAULT_PUSH_REMOTE} ${branch}`);
8964
+ };
8686
8965
  var commandReadForAPush = (input, toolInput) => {
8687
8966
  const command = POSIX_SHELL_TOOLS.has(input.toolName) ? extractPolicyArg(input.toolName, toolInput) : void 0;
8688
8967
  return command !== void 0 && command.length <= LONGEST_COMMAND_READ_FOR_A_PUSH ? command : void 0;
8689
8968
  };
8690
- var pushesInSegmentsBeforeAMove = (command, branch) => {
8969
+ var pushesInSegmentsBeforeAMove = (command, branch, spellingsOf) => {
8691
8970
  const pushes = [];
8692
8971
  for (const segment of spelledSegmentsOf(command)) {
8693
8972
  const { forms } = commandSpellings(segment.text, SPELLS_COMMAND_RUNNERS_TOO);
8694
8973
  if (forms.some((form) => MOVES_BEFORE_A_PUSH.test(form))) break;
8695
- if (!forms.some(pointsGitAtAnotherRepository)) pushes.push(...forms.flatMap((form) => spellingsOfAPushOfTheBranch(form, branch)));
8974
+ if (!forms.some(pointsGitAtAnotherRepository)) pushes.push(...forms.flatMap((form) => spellingsOf(form, branch)));
8696
8975
  }
8697
8976
  return [...new Set(pushes)];
8698
8977
  };
8699
- var pushesOfTheCurrentBranchIn = (input, toolInput) => {
8978
+ var pushesOfTheCurrentBranchIn = (input, toolInput, spellingsOf = spellingsOfAPushOfTheBranch) => {
8700
8979
  const branch = input.currentBranch;
8701
8980
  const command = branch !== void 0 && isGitBranch(branch) ? commandReadForAPush(input, toolInput) : void 0;
8702
- return branch === void 0 || command === void 0 ? [] : pushesInSegmentsBeforeAMove(command, branch);
8981
+ return branch === void 0 || command === void 0 ? [] : pushesInSegmentsBeforeAMove(command, branch, spellingsOf);
8703
8982
  };
8704
8983
  var MENTIONS_A_GIT_PUSH = /\bgit\b[\s\S]*\bpush\b/;
8705
8984
  var toolInputMayPushTheCurrentBranch = (toolName, toolInput) => {
@@ -8707,13 +8986,20 @@ var toolInputMayPushTheCurrentBranch = (toolName, toolInput) => {
8707
8986
  return command !== void 0 && command.length <= LONGEST_COMMAND_READ_FOR_A_PUSH && MENTIONS_A_GIT_PUSH.test(command);
8708
8987
  };
8709
8988
  var callMayPushTheCurrentBranch = (toolName, toolInputs) => POSIX_SHELL_TOOLS.has(toolName) && toolInputs.some((toolInput) => toolInputMayPushTheCurrentBranch(toolName, toolInput));
8710
- var routeArgumentsOf = (input, toolInput) => [...policyArgForms(input.toolName, toolInput, input.cwd), ...pushesOfTheCurrentBranchIn(input, toolInput)];
8989
+ var pushDestinationSpellingsIn = (input, toolInput) => {
8990
+ const command = commandReadForAPush(input, toolInput);
8991
+ if (command === void 0 || !MENTIONS_A_GIT_PUSH.test(command)) return [];
8992
+ return [...new Set(spelledSegmentsOf(command).flatMap((segment) => commandSpellings(segment.text, SPELLS_COMMAND_RUNNERS_TOO).forms.flatMap(spellingsOfAPushToItsDestinations)))];
8993
+ };
8994
+ var pushSpellingsBeyondTheWrittenOnesIn = (input, toolInput) => [...pushesOfTheCurrentBranchIn(input, toolInput, forcedSpellingsOfAPushOfTheBranch), ...pushDestinationSpellingsIn(input, toolInput)];
8995
+ var writtenRouteArgumentsOf = (input, toolInput) => [...policyArgForms(input.toolName, toolInput, input.cwd), ...pushesOfTheCurrentBranchIn(input, toolInput)];
8996
+ var routeArgumentsOf = (input, toolInput) => [...writtenRouteArgumentsOf(input, toolInput), ...pushSpellingsBeyondTheWrittenOnesIn(input, toolInput)];
8711
8997
  var everyRule = () => true;
8712
8998
  var aChosenRuleGoverns = (input, counts = everyRule) => {
8713
8999
  const chosen = input.config.policies.filter((policy) => !isDefaultRule(policy));
8714
9000
  const routes = approvalRoutesOf(input.config);
8715
9001
  if (routes === null) return true;
8716
- return input.toolInputs.some((toolInput) => {
9002
+ return withExtraReadings(input).toolInputs.some((toolInput) => {
8717
9003
  const args = policyArgForms(input.toolName, toolInput, input.cwd);
8718
9004
  const reading = policyReadingOf(chosen, input.toolName, args, SPELLS_COMMAND_RUNNERS_TOO);
8719
9005
  const governing = governingRuleForReading(chosen, input.toolName, args, reading, input.repoKey, input.sessionId);
@@ -8721,16 +9007,27 @@ var aChosenRuleGoverns = (input, counts = everyRule) => {
8721
9007
  });
8722
9008
  };
8723
9009
  var AUTO_PERMISSION_MODE = "auto";
8724
- var routeDeliveredFor = (input, routes, toolInput) => findBestRoute(routes, input.toolName, routeArgumentsOf(input, toolInput), input.sharedRepoKey ?? input.repoKey);
9010
+ var routeWaitsForSomeoneElse = (route) => route.answeredBySomeoneElse === true;
9011
+ var routeDeliveredFor = (input, routes, toolInput) => {
9012
+ const repoKey = input.sharedRepoKey ?? input.repoKey;
9013
+ const written = writtenRouteArgumentsOf(input, toolInput);
9014
+ const writtenRoute = findBestRoute(routes, input.toolName, written, repoKey);
9015
+ if (writtenRoute?.answeredBySomeoneElse === true) return writtenRoute;
9016
+ const spelled = pushSpellingsBeyondTheWrittenOnesIn(input, toolInput).filter((spelling) => !written.includes(spelling));
9017
+ if (spelled.length === 0) return writtenRoute;
9018
+ const heldSpelledRoute = findBestRoute(routes.filter(routeWaitsForSomeoneElse), input.toolName, spelled, repoKey);
9019
+ if (heldSpelledRoute !== void 0 && heldSpelledRoute.toolPattern.length > (writtenRoute?.toolPattern.length ?? -1)) return heldSpelledRoute;
9020
+ return writtenRoute ?? findBestRoute(routes, input.toolName, spelled, repoKey);
9021
+ };
8725
9022
  var callWaitsForSomeoneElse = (input) => {
8726
9023
  const routes = approvalRoutesOf(input.config);
8727
9024
  if (routes === null) return false;
8728
- return input.toolInputs.some((toolInput) => routeDeliveredFor(input, routes, toolInput)?.answeredBySomeoneElse === true);
9025
+ return withExtraReadings(input).toolInputs.some((toolInput) => routeDeliveredFor(input, routes, toolInput)?.answeredBySomeoneElse === true);
8729
9026
  };
8730
9027
  var namedRouteWaitsForSomeoneElse = (input) => {
8731
9028
  const routes = approvalRoutesOf(input.config);
8732
9029
  if (routes === null) return false;
8733
- return input.toolInputs.some((toolInput) => {
9030
+ return withExtraReadings(input).toolInputs.some((toolInput) => {
8734
9031
  const route = routeDeliveredFor(input, routes, toolInput);
8735
9032
  return route?.answeredBySomeoneElse === true && patternToolName(route.toolPattern) === input.toolName;
8736
9033
  });
@@ -8738,7 +9035,7 @@ var namedRouteWaitsForSomeoneElse = (input) => {
8738
9035
  var matchedRouteOf = (input) => {
8739
9036
  const routes = approvalRoutesOf(input.config);
8740
9037
  if (routes === null) return void 0;
8741
- const matched = input.toolInputs.flatMap((toolInput) => routeDeliveredFor(input, routes, toolInput) ?? []);
9038
+ const matched = withExtraReadings(input).toolInputs.flatMap((toolInput) => routeDeliveredFor(input, routes, toolInput) ?? []);
8742
9039
  const route = matched.find((candidate) => candidate.answeredBySomeoneElse === true) ?? matched[0];
8743
9040
  if (route === void 0) return void 0;
8744
9041
  return route.repoKey ? { toolPattern: route.toolPattern, repoKey: route.repoKey } : { toolPattern: route.toolPattern };
@@ -8749,6 +9046,7 @@ var mcpCallCouldBeHeldForSomeoneElse = (toolName, permissionMode) => permissionM
8749
9046
  var approvalRouteHoldsMcpCall = (input, verdict, permissionMode) => mcpCallCouldBeHeldForSomeoneElse(input.toolName, permissionMode) && verdictCanHoldTheCall(verdict) && namedRouteWaitsForSomeoneElse(input);
8750
9047
  var claudeAllowlistOwnsCall = (input, verdict, permissionMode, rules) => rules !== null && verdict.kind === "gate" && !verdict.scopeReason && !aChosenRuleGoverns(input) && !isAskedInEveryMode(input.toolName) && claudeConsultsItsAllowlist(permissionMode) && agentRulesAllowEveryInput(rules, input.toolName, input.toolInputs, input.cwd);
8751
9048
  var claudePromptTakesTheCall = (facts, input, verdict) => verdict.kind === "gate" && !verdict.scopeReason && terminalStaysLiveForTheCall(facts) && noModeOverrideIsActive(input) && !aChosenRuleGoverns(input) && !editGoesToTheAgentsPrompt({ source: facts.source, event: "PreToolUse", permissionMode: facts.permissionMode }, input, verdict);
9049
+ var isProvenModeResponse = (value) => isRecord(value) && typeof value.kill === "boolean";
8752
9050
  var toPolicyVersion = (value) => typeof value === "string" || typeof value === "number" ? String(value) : null;
8753
9051
  var modeStateFromResponse = (data) => {
8754
9052
  const mode = data.override?.mode;
@@ -9247,6 +9545,7 @@ export {
9247
9545
  answersToQuestionsAsAsked,
9248
9546
  normalizeInstallSource,
9249
9547
  HOOK_BUDGETS,
9548
+ hookMaxWaitSeconds,
9250
9549
  HOOK_HOLD_BUDGET_ENV,
9251
9550
  withHookHoldBudget,
9252
9551
  hookCommandHoldBudget,
@@ -9337,6 +9636,7 @@ export {
9337
9636
  approvalRouteHoldsMcpCall,
9338
9637
  claudeAllowlistOwnsCall,
9339
9638
  claudePromptTakesTheCall,
9639
+ isProvenModeResponse,
9340
9640
  modeStateFromResponse,
9341
9641
  GATE_WIRE,
9342
9642
  GATE_MAX_TOOL_INPUTS,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pusharyDir
3
- } from "./chunk-ARRXCME5.js";
3
+ } from "./chunk-CBLFIWPI.js";
4
4
  import {
5
5
  writeFileAtomic
6
6
  } from "./chunk-T5I4PKOQ.js";
@@ -5,7 +5,7 @@ import {
5
5
  MCP_CREDENTIAL_REJECTION_BODY,
6
6
  isRecord,
7
7
  responseRejectsCredential
8
- } from "./chunk-KYWTX4R2.js";
8
+ } from "./chunk-TRDHHF3A.js";
9
9
 
10
10
  // src/credential-rejection.ts
11
11
  import { createHash, randomUUID } from "crypto";
@@ -4,10 +4,10 @@ import {
4
4
  keyPrefix,
5
5
  readConfigFileKey,
6
6
  readMacAppKeyPrefix
7
- } from "./chunk-YU3LDR5W.js";
7
+ } from "./chunk-YZ7V2LVG.js";
8
8
  import {
9
9
  NPX_LATEST_COMMAND
10
- } from "./chunk-R5ZMI6BM.js";
10
+ } from "./chunk-PJSFKKZ5.js";
11
11
 
12
12
  // src/key-signed-out.ts
13
13
  var VERDICT_BY_CHECK = {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  guardBinary
3
- } from "./chunk-ARRXCME5.js";
3
+ } from "./chunk-CBLFIWPI.js";
4
4
 
5
5
  // src/bell/install.ts
6
6
  import { join } from "path";