@poe-platform/safe-bash 0.1.799 → 0.1.801

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 (1076) hide show
  1. package/README.md +48 -22
  2. package/dist/image-ast/index.browser.js +1503 -98
  3. package/dist/image-ast/index.js +1503 -98
  4. package/dist/mp4-ast/types.d.ts +1 -0
  5. package/dist/office-package/zip.d.ts +2 -0
  6. package/dist/office-package/zip.js +1 -1
  7. package/dist/pdf-ast/index.js +5 -4
  8. package/dist/safe-bash/chunks/{chunk-LUOFIVNI.js → chunk-3NDIFSNM.js} +3 -3
  9. package/dist/safe-bash/chunks/chunk-3R3AANOR.js +26 -0
  10. package/dist/safe-bash/chunks/{chunk-TRVGCN3U.js → chunk-45PK3NWI.js} +4 -4
  11. package/dist/safe-bash/chunks/{chunk-KHMGTPD6.js → chunk-46Z5E5EV.js} +2 -2
  12. package/dist/safe-bash/chunks/{chunk-XB3B7KMM.js → chunk-6O77NL2S.js} +1 -1
  13. package/dist/safe-bash/chunks/{chunk-T3JTVIEP.js → chunk-6PAVEFT3.js} +1 -1
  14. package/dist/safe-bash/chunks/{chunk-PYVEAFJM.js → chunk-74GHTNJA.js} +3 -2
  15. package/dist/safe-bash/chunks/{chunk-LQHGH25W.js → chunk-7R5BDCG7.js} +1 -1
  16. package/dist/safe-bash/chunks/{chunk-WUNK5NXJ.js → chunk-7VNF5BFF.js} +1140 -1660
  17. package/dist/safe-bash/chunks/{chunk-NHOXKQNE.js → chunk-A7XEHALN.js} +6 -6
  18. package/dist/safe-bash/chunks/{chunk-MHZ24KEI.js → chunk-AM5ESLPH.js} +1 -1
  19. package/dist/safe-bash/chunks/{chunk-3L3T6LYV.js → chunk-AUSNDQTJ.js} +1 -1
  20. package/dist/safe-bash/chunks/{chunk-YG5WAHK7.js → chunk-B7TAL7S5.js} +1 -3
  21. package/dist/safe-bash/chunks/{chunk-K7IQZE7D.js → chunk-C5OWC2TL.js} +1 -1
  22. package/dist/safe-bash/chunks/{chunk-F3RV2F72.js → chunk-CHYGPFVM.js} +1 -1
  23. package/dist/safe-bash/chunks/{chunk-M4CFCXHN.js → chunk-CS4MNM6I.js} +1 -1
  24. package/dist/safe-bash/chunks/{chunk-H6JW3E4F.js → chunk-CTVWDACF.js} +1 -1
  25. package/dist/safe-bash/chunks/{chunk-KTGR4U57.js → chunk-D3ANYGMC.js} +2 -3
  26. package/dist/safe-bash/chunks/{chunk-ENR3HB2B.js → chunk-E7OYNDGL.js} +1 -2
  27. package/dist/safe-bash/chunks/{chunk-SOZK5JVX.js → chunk-FBUCWVTE.js} +1 -1
  28. package/dist/safe-bash/chunks/{chunk-NX2SQVON.js → chunk-FNDNHAGE.js} +46 -27
  29. package/dist/safe-bash/chunks/{chunk-KCVSVD65.js → chunk-I5HZ4FGE.js} +1 -1
  30. package/dist/safe-bash/chunks/{chunk-KMH2DF3I.js → chunk-ICFDYV64.js} +7 -2
  31. package/dist/safe-bash/chunks/{chunk-T5KKDMYB.js → chunk-IVRQ4BXL.js} +7 -1
  32. package/dist/safe-bash/chunks/{chunk-KV7PKOHV.js → chunk-IWDICZVK.js} +1 -1
  33. package/dist/safe-bash/chunks/{chunk-I4OAEOP6.js → chunk-J42RIHHJ.js} +1 -1
  34. package/dist/safe-bash/chunks/chunk-K6VCD7IY.js +106 -0
  35. package/dist/safe-bash/chunks/{chunk-63FXVDGF.js → chunk-LVOBFF4D.js} +1 -1
  36. package/dist/safe-bash/chunks/{chunk-U5NUZPCC.js → chunk-MHMMRCYC.js} +1 -1
  37. package/dist/safe-bash/chunks/{chunk-6HZYFL3H.js → chunk-NR3EM4LS.js} +1 -1
  38. package/dist/safe-bash/chunks/{chunk-VYZTG3GV.js → chunk-NZQXYWA3.js} +1 -1
  39. package/dist/safe-bash/chunks/{chunk-JSVX4VIA.js → chunk-OQRVVGR6.js} +3 -2
  40. package/dist/safe-bash/chunks/{chunk-B3DDEDH2.js → chunk-OV6IHKO6.js} +2 -2
  41. package/dist/safe-bash/chunks/{chunk-SPYL72GN.js → chunk-PQRAK7HU.js} +1196 -5781
  42. package/dist/safe-bash/chunks/chunk-SZH7EJLD.js +9221 -0
  43. package/dist/safe-bash/chunks/{chunk-AKC46AF6.js → chunk-TFIBK2GI.js} +8 -41
  44. package/dist/safe-bash/chunks/{chunk-ZNAFMYIA.js → chunk-UE5KZDEK.js} +2 -2
  45. package/dist/safe-bash/chunks/{chunk-QU3BVQ53.js → chunk-UTBUUFDM.js} +1 -1
  46. package/dist/safe-bash/chunks/{chunk-6IBTC4YL.js → chunk-VQDD3G76.js} +93 -39
  47. package/dist/safe-bash/chunks/{chunk-IUTD5FH5.js → chunk-VTH3MLDU.js} +2 -7
  48. package/dist/safe-bash/chunks/{chunk-LLZCZ24K.js → chunk-XVOSKJE2.js} +1 -1
  49. package/dist/safe-bash/chunks/{csvkit-W2UEKH6P.js → csvkit-TACDU7FC.js} +3 -3
  50. package/dist/safe-bash/chunks/{ffmpeg-42CGASMV.js → ffmpeg-WTC3TEFI.js} +2 -2
  51. package/dist/safe-bash/chunks/{gh-26GYLH6D.js → gh-6WU6PXL4.js} +2 -2
  52. package/dist/safe-bash/chunks/{git-YREKMUVD.js → git-EFZIGJW4.js} +2 -2
  53. package/dist/safe-bash/chunks/{imagemagick-3YIX4XO2.js → imagemagick-EIEYGWPF.js} +2 -2
  54. package/dist/safe-bash/chunks/{implementation-E3YMKU3Z.js → implementation-MLFHUQ5M.js} +2 -2
  55. package/dist/safe-bash/chunks/mmdc-ROQJT5HQ.js +118 -0
  56. package/dist/safe-bash/chunks/{pdfimages-UE2UISP2.js → pdfimages-DW7LWXFI.js} +2 -2
  57. package/dist/safe-bash/chunks/{pdfinfo-RGARKLI5.js → pdfinfo-TIP6XLUQ.js} +4 -12
  58. package/dist/safe-bash/chunks/{pdftk-JY3WVCCC.js → pdftk-DMG22ITZ.js} +2 -2
  59. package/dist/safe-bash/chunks/{pdftoppm-GPD3BMPY.js → pdftoppm-WNDYR72T.js} +2 -2
  60. package/dist/safe-bash/chunks/{pdftotext-K7GQ2QJZ.js → pdftotext-5IPZ4NI7.js} +2 -2
  61. package/dist/safe-bash/chunks/{qpdf-F4U7WUSU.js → qpdf-TTX2DIUA.js} +2 -2
  62. package/dist/safe-bash/chunks/{sips-RWENS7X5.js → sips-XYS46JPJ.js} +2 -2
  63. package/dist/safe-bash/chunks/{soffice-IT6W2C5F.js → soffice-TU73E5KL.js} +2 -2
  64. package/dist/safe-bash/chunks/{wkhtmltopdf-JYNDAHIZ.js → wkhtmltopdf-FSZ2CHGE.js} +2 -2
  65. package/dist/safe-bash/command-chunks/{chunk-QBGA56UH.js → chunk-2ELYGJDD.js} +7 -7
  66. package/dist/safe-bash/command-chunks/chunk-2FGJYFWZ.js +44 -0
  67. package/dist/safe-bash/command-chunks/chunk-2H4JTFIL.js +53 -0
  68. package/dist/safe-bash/command-chunks/{chunk-52PCQXD2.js → chunk-2NHI5F5S.js} +2 -1
  69. package/dist/safe-bash/command-chunks/{chunk-HDKVO47G.js → chunk-2SQEIUGJ.js} +3 -3
  70. package/dist/safe-bash/command-chunks/chunk-364TMWBT.js +946 -0
  71. package/dist/safe-bash/command-chunks/chunk-3E2OIS2J.js +7037 -0
  72. package/dist/safe-bash/command-chunks/chunk-3HHCU5YU.js +380 -0
  73. package/dist/safe-bash/command-chunks/{chunk-TF6OA2GK.js → chunk-3NV3HYT2.js} +1 -1
  74. package/dist/safe-bash/command-chunks/chunk-4B7Y7S6E.js +61 -0
  75. package/dist/safe-bash/command-chunks/{chunk-LLCXZKZ6.js → chunk-4BB2SWJ5.js} +2 -2
  76. package/dist/safe-bash/command-chunks/{chunk-IEXHHNOF.js → chunk-4J5CZ2DP.js} +2 -7
  77. package/dist/safe-bash/command-chunks/{chunk-WDHI3S6Y.js → chunk-4OOUQTQO.js} +1 -1
  78. package/dist/safe-bash/command-chunks/chunk-4ZHMW6F5.js +104 -0
  79. package/dist/safe-bash/command-chunks/{chunk-YMONDXET.js → chunk-4ZQWGOZB.js} +2 -2
  80. package/dist/safe-bash/command-chunks/chunk-5BSTFCXG.js +553 -0
  81. package/dist/safe-bash/command-chunks/{chunk-MKQVQMXO.js → chunk-5LU4UCBR.js} +1 -1
  82. package/dist/safe-bash/command-chunks/chunk-5PWJG2UK.js +174 -0
  83. package/dist/safe-bash/command-chunks/chunk-5TBUOBDE.js +346 -0
  84. package/dist/safe-bash/command-chunks/{chunk-JMPP4TCW.js → chunk-5UBXNSFZ.js} +3 -2
  85. package/dist/safe-bash/command-chunks/chunk-5XY4DTNG.js +34 -0
  86. package/dist/safe-bash/command-chunks/chunk-5ZMZ573Q.js +140 -0
  87. package/dist/safe-bash/command-chunks/{chunk-3NG75MOB.js → chunk-67GQA75T.js} +1 -1
  88. package/dist/safe-bash/command-chunks/chunk-67QKREJK.js +347 -0
  89. package/dist/safe-bash/command-chunks/{chunk-L6SU4S26.js → chunk-6B7WQIKB.js} +0 -7
  90. package/dist/safe-bash/command-chunks/chunk-6BNTBWIK.js +327 -0
  91. package/dist/safe-bash/command-chunks/chunk-6EPHJGGF.js +23 -0
  92. package/dist/safe-bash/command-chunks/chunk-6F4XCVON.js +266 -0
  93. package/dist/safe-bash/command-chunks/chunk-6KJ3LPI2.js +94 -0
  94. package/dist/safe-bash/command-chunks/{chunk-HLDTOR7M.js → chunk-6ZVI7LUY.js} +1 -1
  95. package/dist/safe-bash/command-chunks/{chunk-X6NJC3IC.js → chunk-75OFBY5R.js} +1 -1
  96. package/dist/safe-bash/command-chunks/chunk-7K6JYKPJ.js +422 -0
  97. package/dist/safe-bash/command-chunks/chunk-7N2LI2KO.js +206 -0
  98. package/dist/safe-bash/command-chunks/{chunk-MRW5HD2D.js → chunk-7O3E4LPT.js} +4 -22
  99. package/dist/safe-bash/command-chunks/chunk-7U7EXOXX.js +1392 -0
  100. package/dist/safe-bash/command-chunks/{chunk-6CYTRQ24.js → chunk-7VTKQUA5.js} +20 -17
  101. package/dist/safe-bash/command-chunks/{chunk-BZPAWTUL.js → chunk-AEF5BA3D.js} +1 -1
  102. package/dist/safe-bash/command-chunks/{pptx-GBPNWNEP-7EQEVXV5.js → chunk-AI5JAXQF.js} +34820 -18029
  103. package/dist/safe-bash/command-chunks/{chunk-63R3FEZJ.js → chunk-AIV5BF5W.js} +1 -1
  104. package/dist/safe-bash/command-chunks/{chunk-AYUTO323.js → chunk-AKJG2XD3.js} +2 -18
  105. package/dist/safe-bash/command-chunks/{chunk-J34TZVMW.js → chunk-ALDC4XP4.js} +0 -5
  106. package/dist/safe-bash/command-chunks/chunk-AMO3THU4.js +105 -0
  107. package/dist/safe-bash/command-chunks/chunk-ARBYOQUZ.js +65 -0
  108. package/dist/safe-bash/command-chunks/chunk-BAGCY35S.js +231 -0
  109. package/dist/safe-bash/command-chunks/chunk-BAXU7B5Z.js +101 -0
  110. package/dist/safe-bash/command-chunks/{chunk-44AHAB5O.js → chunk-BDSMROQZ.js} +1 -4
  111. package/dist/safe-bash/command-chunks/chunk-BNOU5YQS.js +182 -0
  112. package/dist/safe-bash/command-chunks/{chunk-4ZALPDBV.js → chunk-BPE5INLI.js} +2 -2
  113. package/dist/safe-bash/command-chunks/{chunk-OT4LZMLB.js → chunk-BR73BIOW.js} +1 -1
  114. package/dist/safe-bash/command-chunks/chunk-C5YYCQHW.js +1444 -0
  115. package/dist/safe-bash/command-chunks/chunk-C7I25AAL.js +25 -0
  116. package/dist/safe-bash/command-chunks/{chunk-4ONEXMD3.js → chunk-CAP7ZJSY.js} +8 -8
  117. package/dist/safe-bash/command-chunks/{chunk-DWFLVJC6.js → chunk-CCRHMAU5.js} +2 -1
  118. package/dist/safe-bash/command-chunks/chunk-CQ5YGOGB.js +150 -0
  119. package/dist/safe-bash/command-chunks/{chunk-JCNNOMBV.js → chunk-CQTRW45K.js} +3 -2
  120. package/dist/safe-bash/command-chunks/{chunk-N2F74VRO.js → chunk-CZ7EN3JG.js} +1 -1
  121. package/dist/safe-bash/command-chunks/chunk-DB453IE6.js +122 -0
  122. package/dist/safe-bash/command-chunks/{chunk-KKG4BAFZ.js → chunk-DIEPXUM4.js} +6 -0
  123. package/dist/safe-bash/command-chunks/chunk-DOKKNRRM.js +87 -0
  124. package/dist/safe-bash/command-chunks/{chunk-2PX5B7T5.js → chunk-DQAVUDDX.js} +2 -2
  125. package/dist/safe-bash/command-chunks/chunk-DT7BCTWY.js +249 -0
  126. package/dist/safe-bash/command-chunks/{chunk-6BETHLXZ.js → chunk-DZCY63VJ.js} +13 -11
  127. package/dist/safe-bash/command-chunks/{chunk-QUENU6GM.js → chunk-E55UKBIE.js} +3 -3
  128. package/dist/safe-bash/command-chunks/chunk-EK6YNAXT.js +343 -0
  129. package/dist/safe-bash/command-chunks/chunk-EQ4HV54N.js +22 -0
  130. package/dist/safe-bash/command-chunks/{chunk-HLGKIZ25.js → chunk-F6OYH562.js} +2 -0
  131. package/dist/safe-bash/command-chunks/{chunk-MC3VWLIZ.js → chunk-FDBUV4HJ.js} +28 -19
  132. package/dist/safe-bash/command-chunks/{chunk-7FKUC34S.js → chunk-FPVUD6TH.js} +6 -3
  133. package/dist/safe-bash/command-chunks/chunk-FXELCPFX.js +195 -0
  134. package/dist/safe-bash/command-chunks/chunk-FXOA7RBK.js +42 -0
  135. package/dist/safe-bash/command-chunks/{chunk-LPORMIZS.js → chunk-FZTK4MFI.js} +9 -9
  136. package/dist/safe-bash/command-chunks/{chunk-K543PB3I.js → chunk-G66QUHIZ.js} +6 -35
  137. package/dist/safe-bash/command-chunks/chunk-GFQZCKO6.js +272 -0
  138. package/dist/safe-bash/command-chunks/{chunk-CU5RLO62.js → chunk-GLOZX57Y.js} +92 -18
  139. package/dist/safe-bash/command-chunks/chunk-GMIHJYDG.js +331 -0
  140. package/dist/safe-bash/command-chunks/chunk-GOB777HR.js +97 -0
  141. package/dist/safe-bash/command-chunks/chunk-GRBWW4SG.js +48 -0
  142. package/dist/safe-bash/command-chunks/{chunk-PPNBNFAU.js → chunk-GYQ2HAKQ.js} +8 -8
  143. package/dist/safe-bash/command-chunks/chunk-H622NS6Z.js +11 -0
  144. package/dist/safe-bash/command-chunks/{chunk-UI32HWGS.js → chunk-HMOZ6XVJ.js} +1 -1
  145. package/dist/safe-bash/command-chunks/{chunk-AVSPNLWV.js → chunk-I237SNW5.js} +1 -1
  146. package/dist/safe-bash/command-chunks/{chunk-43GSSUAY.js → chunk-II77KPZN.js} +5 -5
  147. package/dist/safe-bash/command-chunks/{chunk-ZS3QPNUL.js → chunk-IR2BY7EL.js} +21 -6
  148. package/dist/safe-bash/command-chunks/{chunk-SG424QWS.js → chunk-JDYXY44P.js} +2 -2
  149. package/dist/safe-bash/command-chunks/chunk-JNZ3CVAE.js +147 -0
  150. package/dist/safe-bash/command-chunks/{chunk-4QJOYXVB.js → chunk-JV7LBUTP.js} +1 -1
  151. package/dist/safe-bash/command-chunks/{chunk-IKS2YXZQ.js → chunk-K67MWWWH.js} +3 -3
  152. package/dist/safe-bash/command-chunks/chunk-KFVV7ZJO.js +216 -0
  153. package/dist/safe-bash/command-chunks/{chunk-G4PNVO6Z.js → chunk-KP7AO66M.js} +1 -1
  154. package/dist/safe-bash/command-chunks/{chunk-KMCZ6P4O.js → chunk-KQLD3AED.js} +68 -7
  155. package/dist/safe-bash/command-chunks/chunk-KWESKQHR.js +25 -0
  156. package/dist/safe-bash/command-chunks/{chunk-YZ5SVZFD.js → chunk-KXU3IRUO.js} +3 -3
  157. package/dist/safe-bash/command-chunks/{chunk-C7IHMJEW.js → chunk-KZC5UWFF.js} +2 -2
  158. package/dist/safe-bash/command-chunks/{chunk-2WRTLCGK.js → chunk-LAOM65EE.js} +5 -5
  159. package/dist/safe-bash/command-chunks/chunk-LE5LZNHE.js +204 -0
  160. package/dist/safe-bash/command-chunks/{chunk-HFII3QYO.js → chunk-LWS62ISU.js} +46 -32
  161. package/dist/safe-bash/command-chunks/{chunk-BZDDAPSV.js → chunk-LWSBAWLT.js} +1 -1
  162. package/dist/safe-bash/command-chunks/chunk-MDH5T4OS.js +41 -0
  163. package/dist/safe-bash/command-chunks/{chunk-X7TM3AKW.js → chunk-MIXBO6U7.js} +20 -7
  164. package/dist/safe-bash/command-chunks/chunk-MM6HU6CX.js +20 -0
  165. package/dist/safe-bash/command-chunks/{chunk-MYJAZ3U2.js → chunk-MPL2466A.js} +2 -2
  166. package/dist/safe-bash/command-chunks/{chunk-HLBX5IRS.js → chunk-MQFIPHIQ.js} +46 -81
  167. package/dist/safe-bash/command-chunks/{chunk-ZJBR5Q5I.js → chunk-MSFXC3OC.js} +4 -4
  168. package/dist/safe-bash/command-chunks/{chunk-NI7MKJPN.js → chunk-MTQH74CF.js} +3 -55
  169. package/dist/safe-bash/command-chunks/chunk-MWUZZWXK.js +354 -0
  170. package/dist/safe-bash/command-chunks/chunk-N4PFUSRM.js +35 -0
  171. package/dist/safe-bash/command-chunks/chunk-NCD7PEWH.js +298 -0
  172. package/dist/safe-bash/command-chunks/chunk-NFGI5IGF.js +266 -0
  173. package/dist/safe-bash/command-chunks/{chunk-I3K5RYU4.js → chunk-NKFYQSES.js} +73 -26
  174. package/dist/safe-bash/command-chunks/{chunk-KVFCSLKK.js → chunk-NXEQ3ESQ.js} +6 -0
  175. package/dist/safe-bash/command-chunks/{chunk-NGWB2YBL.js → chunk-O4JQSB7O.js} +1 -1
  176. package/dist/safe-bash/command-chunks/{chunk-7L24L4UO.js → chunk-OQU6UT6X.js} +2 -20
  177. package/dist/safe-bash/command-chunks/{chunk-3VGGYEDH.js → chunk-ORYGZYKW.js} +4 -3
  178. package/dist/safe-bash/command-chunks/{chunk-ZXKW7SJ2.js → chunk-OYYV7ZAF.js} +2 -2
  179. package/dist/safe-bash/command-chunks/chunk-P2N33UMN.js +270 -0
  180. package/dist/safe-bash/command-chunks/{chunk-Q7Q5GM5S.js → chunk-P5APDEFB.js} +2 -2
  181. package/dist/safe-bash/command-chunks/{chunk-X2YQLGKS.js → chunk-PCEFOYA3.js} +240 -148
  182. package/dist/safe-bash/command-chunks/{chunk-OLQG7ZCN.js → chunk-PEF7K3UQ.js} +136 -75
  183. package/dist/safe-bash/command-chunks/chunk-PII4YEZW.js +123 -0
  184. package/dist/safe-bash/command-chunks/{chunk-AIRGA2SU.js → chunk-PMBFZXTK.js} +1 -1
  185. package/dist/safe-bash/command-chunks/{chunk-ZT4KSS2V.js → chunk-PTT3I223.js} +1 -1
  186. package/dist/safe-bash/command-chunks/{chunk-4Y3WVMK4.js → chunk-PV66YWHB.js} +1 -0
  187. package/dist/safe-bash/command-chunks/chunk-Q3EWDEUQ.js +185 -0
  188. package/dist/safe-bash/command-chunks/{chunk-AXK3H4PX.js → chunk-QJ33BHI4.js} +1 -1
  189. package/dist/safe-bash/command-chunks/chunk-QKFSRZGQ.js +1091 -0
  190. package/dist/safe-bash/command-chunks/{chunk-JZSNU2MY.js → chunk-QKJLP53H.js} +2 -2
  191. package/dist/safe-bash/command-chunks/{chunk-VVI4Z73I.js → chunk-QP4R6GLA.js} +5 -1
  192. package/dist/safe-bash/command-chunks/chunk-RMWQAAO5.js +2488 -0
  193. package/dist/safe-bash/command-chunks/{chunk-QDTBMSBE.js → chunk-RO62EWX6.js} +2 -2
  194. package/dist/safe-bash/command-chunks/{chunk-HRLIAMXC.js → chunk-RZZI24ZE.js} +7 -6
  195. package/dist/safe-bash/command-chunks/{chunk-PFAADCB5.js → chunk-SDNBCQ3X.js} +10 -24
  196. package/dist/safe-bash/command-chunks/chunk-SEM36PG5.js +11 -0
  197. package/dist/safe-bash/command-chunks/{chunk-36O5OT7E.js → chunk-T35Y7YQD.js} +1 -1
  198. package/dist/safe-bash/command-chunks/{chunk-ESMCX3YV.js → chunk-TGSNCQSR.js} +710 -143
  199. package/dist/safe-bash/command-chunks/chunk-TIOCQVUQ.js +557 -0
  200. package/dist/safe-bash/command-chunks/{chunk-T5H5UJQ3.js → chunk-TNOA7FCQ.js} +1 -1
  201. package/dist/safe-bash/command-chunks/{chunk-GN2TKLE7.js → chunk-TS65BJHG.js} +5 -5
  202. package/dist/safe-bash/command-chunks/chunk-TSCGT46G.js +363 -0
  203. package/dist/safe-bash/command-chunks/chunk-UG7SMZFF.js +178 -0
  204. package/dist/safe-bash/command-chunks/{chunk-KBEURXFF.js → chunk-UN6WS55J.js} +3 -3
  205. package/dist/safe-bash/command-chunks/chunk-UXSR5BZH.js +136 -0
  206. package/dist/safe-bash/command-chunks/{chunk-SX2X3IH4.js → chunk-V2V5OCL3.js} +1 -1
  207. package/dist/safe-bash/command-chunks/chunk-V6BEDRMQ.js +112 -0
  208. package/dist/safe-bash/command-chunks/chunk-V7A7DRTU.js +293 -0
  209. package/dist/safe-bash/command-chunks/{chunk-5SHGJ7NO.js → chunk-VA5ZHYYA.js} +73 -33
  210. package/dist/safe-bash/command-chunks/{chunk-J4PEQWSF.js → chunk-VGG2DL5Q.js} +0 -1
  211. package/dist/safe-bash/command-chunks/chunk-VPR5LQYX.js +1228 -0
  212. package/dist/safe-bash/command-chunks/{chunk-EIVW3X3N.js → chunk-VSRGNQCP.js} +11 -6
  213. package/dist/safe-bash/command-chunks/{chunk-TYVCKQDH.js → chunk-VXSLJH7G.js} +56 -6
  214. package/dist/safe-bash/command-chunks/{chunk-PXYOWWMV.js → chunk-W7RAD4EW.js} +4 -3
  215. package/dist/safe-bash/command-chunks/{src-UJOWAS2S.js → chunk-WD3ERGRY.js} +77 -277
  216. package/dist/safe-bash/command-chunks/{chunk-5ZSM4UFN.js → chunk-WECIOOQB.js} +8 -64
  217. package/dist/safe-bash/command-chunks/{chunk-YFSDDFGV.js → chunk-WH627NJL.js} +446 -53
  218. package/dist/safe-bash/command-chunks/chunk-WNE7FPVR.js +236 -0
  219. package/dist/safe-bash/command-chunks/{chunk-UKS2XJZI.js → chunk-WPYIOKE3.js} +4 -4
  220. package/dist/safe-bash/command-chunks/{chunk-HHP343KT.js → chunk-WTECBRU4.js} +1 -1
  221. package/dist/safe-bash/command-chunks/{chunk-AO6Z5EQ7.js → chunk-WVE64WM2.js} +6 -5
  222. package/dist/safe-bash/command-chunks/chunk-WVHONVZ4.js +594 -0
  223. package/dist/safe-bash/command-chunks/chunk-XIIBTGC5.js +580 -0
  224. package/dist/safe-bash/command-chunks/chunk-XJXU3VVH.js +737 -0
  225. package/dist/safe-bash/command-chunks/chunk-XNLFHHOC.js +63 -0
  226. package/dist/safe-bash/command-chunks/{chunk-XAFSZDY2.js → chunk-XS72HTMA.js} +11 -0
  227. package/dist/safe-bash/command-chunks/chunk-Y5INTD6S.js +220 -0
  228. package/dist/safe-bash/command-chunks/chunk-YIQACGEW.js +43 -0
  229. package/dist/safe-bash/command-chunks/chunk-YOF7R4OY.js +80 -0
  230. package/dist/safe-bash/command-chunks/{chunk-VZHRZMS7.js → chunk-YOFC45RK.js} +1 -1
  231. package/dist/safe-bash/command-chunks/{chunk-2FUAW6GO.js → chunk-Z45N42QC.js} +75 -11
  232. package/dist/safe-bash/command-chunks/chunk-ZHUWOUWB.js +618 -0
  233. package/dist/safe-bash/command-chunks/{chunk-OPUJSTHS.js → chunk-ZYHTWNAE.js} +215 -67
  234. package/dist/safe-bash/command-chunks/chunk-ZYXH3B66.js +636 -0
  235. package/dist/safe-bash/command-chunks/{model-store-L35QTZMJ.js → model-store-WPKMRPV4.js} +2 -2
  236. package/dist/safe-bash/command-chunks/pptx-7G52EJ6L-4JACH5FB.js +625 -0
  237. package/dist/safe-bash/command-chunks/python-worker-source-TYOFJMCW.js +4 -0
  238. package/dist/safe-bash/command-chunks/src-ICMQISAA.js +501 -0
  239. package/dist/safe-bash/commands/archive/create.d.ts +1 -17
  240. package/dist/safe-bash/commands/archive/create.js +1 -252
  241. package/dist/safe-bash/commands/archive/extract.d.ts +1 -11
  242. package/dist/safe-bash/commands/archive/extract.js +1 -640
  243. package/dist/safe-bash/commands/archive/format.d.ts +1 -32
  244. package/dist/safe-bash/commands/archive/format.js +1 -225
  245. package/dist/safe-bash/commands/archive/index.d.ts +5 -10
  246. package/dist/safe-bash/commands/archive/index.js +6 -931
  247. package/dist/safe-bash/commands/archive/listing.d.ts +1 -2
  248. package/dist/safe-bash/commands/archive/listing.js +1 -21
  249. package/dist/safe-bash/commands/archive/modes.d.ts +1 -5
  250. package/dist/safe-bash/commands/archive/modes.js +1 -182
  251. package/dist/safe-bash/commands/archive/options.d.ts +1 -53
  252. package/dist/safe-bash/commands/archive/options.js +1 -462
  253. package/dist/safe-bash/commands/archive/stream.d.ts +1 -22
  254. package/dist/safe-bash/commands/archive/stream.js +1 -188
  255. package/dist/safe-bash/commands/archive/transform.d.ts +1 -16
  256. package/dist/safe-bash/commands/archive/transform.js +1 -85
  257. package/dist/safe-bash/commands/archive/unzip/arguments.d.ts +1 -53
  258. package/dist/safe-bash/commands/archive/unzip/arguments.js +1 -322
  259. package/dist/safe-bash/commands/archive/unzip/safety.d.ts +1 -32
  260. package/dist/safe-bash/commands/archive/unzip/safety.js +1 -295
  261. package/dist/safe-bash/commands/archive/unzip.d.ts +1 -3
  262. package/dist/safe-bash/commands/archive/unzip.js +1 -398
  263. package/dist/safe-bash/commands/archive/zip/aes.d.ts +1 -17
  264. package/dist/safe-bash/commands/archive/zip/aes.js +1 -156
  265. package/dist/safe-bash/commands/archive/zip/comments.d.ts +1 -17
  266. package/dist/safe-bash/commands/archive/zip/comments.js +1 -83
  267. package/dist/safe-bash/commands/archive/zip/crc.d.ts +1 -1
  268. package/dist/safe-bash/commands/archive/zip/crc.js +1 -1
  269. package/dist/safe-bash/commands/archive/zip/crypto.d.ts +1 -19
  270. package/dist/safe-bash/commands/archive/zip/crypto.js +1 -118
  271. package/dist/safe-bash/commands/archive/zip/dates.d.ts +1 -4
  272. package/dist/safe-bash/commands/archive/zip/dates.js +1 -66
  273. package/dist/safe-bash/commands/archive/zip/environment.d.ts +1 -2
  274. package/dist/safe-bash/commands/archive/zip/environment.js +1 -62
  275. package/dist/safe-bash/commands/archive/zip/grow.d.ts +1 -3
  276. package/dist/safe-bash/commands/archive/zip/grow.js +1 -2
  277. package/dist/safe-bash/commands/archive/zip/help.d.ts +1 -4
  278. package/dist/safe-bash/commands/archive/zip/help.js +1 -182
  279. package/dist/safe-bash/commands/archive/zip/line-endings.d.ts +1 -2
  280. package/dist/safe-bash/commands/archive/zip/line-endings.js +1 -194
  281. package/dist/safe-bash/commands/archive/zip/log.d.ts +1 -22
  282. package/dist/safe-bash/commands/archive/zip/log.js +1 -159
  283. package/dist/safe-bash/commands/archive/zip/lzma.d.ts +1 -9
  284. package/dist/safe-bash/commands/archive/zip/lzma.js +1 -40
  285. package/dist/safe-bash/commands/archive/zip/move.d.ts +1 -11
  286. package/dist/safe-bash/commands/archive/zip/move.js +1 -59
  287. package/dist/safe-bash/commands/archive/zip/names.d.ts +1 -2
  288. package/dist/safe-bash/commands/archive/zip/names.js +1 -33
  289. package/dist/safe-bash/commands/archive/zip/options.d.ts +1 -13
  290. package/dist/safe-bash/commands/archive/zip/options.js +1 -124
  291. package/dist/safe-bash/commands/archive/zip/repair.d.ts +1 -10
  292. package/dist/safe-bash/commands/archive/zip/repair.js +1 -392
  293. package/dist/safe-bash/commands/archive/zip/safety.d.ts +1 -54
  294. package/dist/safe-bash/commands/archive/zip/safety.js +1 -360
  295. package/dist/safe-bash/commands/archive/zip/sfx.d.ts +1 -4
  296. package/dist/safe-bash/commands/archive/zip/sfx.js +1 -52
  297. package/dist/safe-bash/commands/archive/zip/test-command.d.ts +1 -5
  298. package/dist/safe-bash/commands/archive/zip/test-command.js +1 -101
  299. package/dist/safe-bash/commands/archive/zip/volumes.d.ts +1 -21
  300. package/dist/safe-bash/commands/archive/zip/volumes.js +1 -281
  301. package/dist/safe-bash/commands/archive/zip/zip64.d.ts +1 -30
  302. package/dist/safe-bash/commands/archive/zip/zip64.js +1 -227
  303. package/dist/safe-bash/commands/archive/zip-format.d.ts +1 -68
  304. package/dist/safe-bash/commands/archive/zip-format.js +1 -1075
  305. package/dist/safe-bash/commands/archive/zip.d.ts +1 -3
  306. package/dist/safe-bash/commands/archive/zip.js +1 -1523
  307. package/dist/safe-bash/commands/awk/index.d.ts +2 -0
  308. package/dist/safe-bash/commands/awk/index.js +2 -0
  309. package/dist/safe-bash/commands/bytes/compression/index.js +4 -2
  310. package/dist/safe-bash/commands/copy-preserve.d.ts +1 -0
  311. package/dist/safe-bash/commands/csplit/index.browser.js +2 -2
  312. package/dist/safe-bash/commands/curl/index.d.ts +2 -0
  313. package/dist/safe-bash/commands/curl/index.js +2 -0
  314. package/dist/safe-bash/commands/diff/index.d.ts +2 -0
  315. package/dist/safe-bash/commands/diff/index.js +2 -0
  316. package/dist/safe-bash/commands/diff-patch/diff-format.d.ts +1 -10
  317. package/dist/safe-bash/commands/diff-patch/diff-format.js +1 -237
  318. package/dist/safe-bash/commands/diff-patch/diff-options.d.ts +1 -38
  319. package/dist/safe-bash/commands/diff-patch/diff-options.js +1 -261
  320. package/dist/safe-bash/commands/diff-patch/diff-output.d.ts +1 -20
  321. package/dist/safe-bash/commands/diff-patch/diff-output.js +1 -290
  322. package/dist/safe-bash/commands/diff-patch/diff.d.ts +1 -2
  323. package/dist/safe-bash/commands/diff-patch/diff.js +1 -656
  324. package/dist/safe-bash/commands/diff-patch/index.d.ts +4 -5
  325. package/dist/safe-bash/commands/diff-patch/index.js +8 -333
  326. package/dist/safe-bash/commands/diff-patch/patch-envelope.d.ts +1 -2
  327. package/dist/safe-bash/commands/diff-patch/patch-envelope.js +1 -63
  328. package/dist/safe-bash/commands/diff-patch/patch-formats.d.ts +1 -7
  329. package/dist/safe-bash/commands/diff-patch/patch-formats.js +1 -264
  330. package/dist/safe-bash/commands/diff-patch/patch-gnu-paths.d.ts +1 -41
  331. package/dist/safe-bash/commands/diff-patch/patch-gnu-paths.js +1 -263
  332. package/dist/safe-bash/commands/diff-patch/patch-gnu-reject.d.ts +1 -3
  333. package/dist/safe-bash/commands/diff-patch/patch-gnu-reject.js +1 -100
  334. package/dist/safe-bash/commands/diff-patch/patch-path.d.ts +1 -3
  335. package/dist/safe-bash/commands/diff-patch/patch-path.js +1 -91
  336. package/dist/safe-bash/commands/diff-patch/patch-publication.d.ts +1 -13
  337. package/dist/safe-bash/commands/diff-patch/patch-publication.js +1 -107
  338. package/dist/safe-bash/commands/diff-patch/patch.d.ts +1 -2
  339. package/dist/safe-bash/commands/diff-patch/patch.js +1 -653
  340. package/dist/safe-bash/commands/diff-patch/shared.d.ts +1 -53
  341. package/dist/safe-bash/commands/diff-patch/shared.js +1 -267
  342. package/dist/safe-bash/commands/diff-patch/unified.d.ts +1 -52
  343. package/dist/safe-bash/commands/diff-patch/unified.js +1 -385
  344. package/dist/safe-bash/commands/directory-admission.d.ts +1 -3
  345. package/dist/safe-bash/commands/directory-admission.js +1 -26
  346. package/dist/safe-bash/commands/docx/index.browser.js +1 -1
  347. package/dist/safe-bash/commands/execution.js +19 -13
  348. package/dist/safe-bash/commands/factor/index.browser.js +2 -2
  349. package/dist/safe-bash/commands/filesystem.d.ts +1 -1
  350. package/dist/safe-bash/commands/filesystem.js +17 -13
  351. package/dist/safe-bash/commands/find/index.d.ts +2 -0
  352. package/dist/safe-bash/commands/find/index.js +2 -0
  353. package/dist/safe-bash/commands/find-format.d.ts +1 -20
  354. package/dist/safe-bash/commands/find-format.js +1 -161
  355. package/dist/safe-bash/commands/find.d.ts +2 -18
  356. package/dist/safe-bash/commands/find.js +2 -1236
  357. package/dist/safe-bash/commands/getopt/index.browser.js +2 -2
  358. package/dist/safe-bash/commands/gzip/index.d.ts +2 -0
  359. package/dist/safe-bash/commands/gzip/index.js +2 -0
  360. package/dist/safe-bash/commands/hexdump/index.browser.js +2 -2
  361. package/dist/safe-bash/commands/htmlq/index.d.ts +1 -1
  362. package/dist/safe-bash/commands/iconv/index.browser.js +2 -2
  363. package/dist/safe-bash/commands/line-endings/index.browser.js +2 -2
  364. package/dist/safe-bash/commands/line-endings/index.d.ts +1 -1
  365. package/dist/safe-bash/commands/line-endings/index.js +1 -262
  366. package/dist/safe-bash/commands/llm/index.browser.js +4 -2
  367. package/dist/safe-bash/commands/llm/providers/index.browser.js +1 -1
  368. package/dist/safe-bash/commands/mdq/index.browser.js +3 -3
  369. package/dist/safe-bash/commands/media/index.browser.js +1 -1
  370. package/dist/safe-bash/commands/metadata/chmod.d.ts +1 -4
  371. package/dist/safe-bash/commands/metadata/chmod.js +2 -63
  372. package/dist/safe-bash/commands/network/aggregate.d.ts +1 -4
  373. package/dist/safe-bash/commands/network/aggregate.js +1 -23
  374. package/dist/safe-bash/commands/network/args.d.ts +1 -68
  375. package/dist/safe-bash/commands/network/args.js +1 -321
  376. package/dist/safe-bash/commands/network/authorizer.d.ts +1 -6
  377. package/dist/safe-bash/commands/network/authorizer.js +1 -33
  378. package/dist/safe-bash/commands/network/body.d.ts +1 -9
  379. package/dist/safe-bash/commands/network/body.js +1 -393
  380. package/dist/safe-bash/commands/network/curl.d.ts +3 -13
  381. package/dist/safe-bash/commands/network/curl.js +6 -695
  382. package/dist/safe-bash/commands/network/deadline.d.ts +1 -2
  383. package/dist/safe-bash/commands/network/deadline.js +1 -14
  384. package/dist/safe-bash/commands/network/decode.d.ts +1 -2
  385. package/dist/safe-bash/commands/network/decode.js +1 -79
  386. package/dist/safe-bash/commands/network/fetch-transport.d.ts +1 -7
  387. package/dist/safe-bash/commands/network/fetch-transport.js +1 -94
  388. package/dist/safe-bash/commands/network/form-content-type.d.ts +1 -5
  389. package/dist/safe-bash/commands/network/form-content-type.js +1 -63
  390. package/dist/safe-bash/commands/network/form-headers.d.ts +1 -2
  391. package/dist/safe-bash/commands/network/form-headers.js +1 -35
  392. package/dist/safe-bash/commands/network/glob.d.ts +1 -7
  393. package/dist/safe-bash/commands/network/glob.js +1 -134
  394. package/dist/safe-bash/commands/network/index.browser.js +4 -12
  395. package/dist/safe-bash/commands/network/input.d.ts +1 -5
  396. package/dist/safe-bash/commands/network/input.js +1 -276
  397. package/dist/safe-bash/commands/network/output.d.ts +1 -6
  398. package/dist/safe-bash/commands/network/output.js +1 -131
  399. package/dist/safe-bash/commands/network/platform-portable.d.ts +1 -5
  400. package/dist/safe-bash/commands/network/platform-portable.js +1 -26
  401. package/dist/safe-bash/commands/network/private-address.d.ts +1 -1
  402. package/dist/safe-bash/commands/network/private-address.js +1 -44
  403. package/dist/safe-bash/commands/network/public.d.ts +2 -2
  404. package/dist/safe-bash/commands/network/public.js +2 -2
  405. package/dist/safe-bash/commands/network/shared.d.ts +1 -14
  406. package/dist/safe-bash/commands/network/shared.js +1 -71
  407. package/dist/safe-bash/commands/network/transport.js +2 -2
  408. package/dist/safe-bash/commands/network/types.d.ts +1 -37
  409. package/dist/safe-bash/commands/network/types.js +1 -31
  410. package/dist/safe-bash/commands/network/url.d.ts +1 -2
  411. package/dist/safe-bash/commands/network/url.js +1 -30
  412. package/dist/safe-bash/commands/network/wget.d.ts +3 -3
  413. package/dist/safe-bash/commands/network/wget.js +9 -332
  414. package/dist/safe-bash/commands/node/filesystem.js +3 -2
  415. package/dist/safe-bash/commands/node/index.browser.js +8 -9
  416. package/dist/safe-bash/commands/node/index.d.ts +3 -3
  417. package/dist/safe-bash/commands/node/index.js +5 -0
  418. package/dist/safe-bash/commands/node/safejs.d.ts +3 -3
  419. package/dist/safe-bash/commands/node/safejs.js +6 -1
  420. package/dist/safe-bash/commands/node/types.d.ts +1 -1
  421. package/dist/safe-bash/commands/node/types.js +1 -1
  422. package/dist/safe-bash/commands/node/unconfigured.d.ts +3 -0
  423. package/dist/safe-bash/commands/node/unconfigured.js +10 -0
  424. package/dist/safe-bash/commands/op/index.browser.js +3 -3
  425. package/dist/safe-bash/commands/patch/index.d.ts +2 -0
  426. package/dist/safe-bash/commands/patch/index.js +2 -0
  427. package/dist/safe-bash/commands/pdfinfo/index.js +2 -1
  428. package/dist/safe-bash/commands/pr/index.browser.js +2 -2
  429. package/dist/safe-bash/commands/predicates.js +3 -4
  430. package/dist/safe-bash/commands/python/host-capabilities.js +31 -14
  431. package/dist/safe-bash/commands/python/index.browser.js +11 -11
  432. package/dist/safe-bash/commands/python/llm-capability.d.ts +1 -0
  433. package/dist/safe-bash/commands/python/llm-capability.js +27 -7
  434. package/dist/safe-bash/commands/python/llm-module.js +11 -0
  435. package/dist/safe-bash/commands/python/manifest.d.ts +2 -0
  436. package/dist/safe-bash/commands/python/manifest.js +13 -6
  437. package/dist/safe-bash/commands/python/provisioning.js +1 -1
  438. package/dist/safe-bash/commands/python/shell-capability.d.ts +1 -0
  439. package/dist/safe-bash/commands/python/shell-capability.js +3 -2
  440. package/dist/safe-bash/commands/python/worker.browser.js +3 -3
  441. package/dist/safe-bash/commands/regex-execution/matching.js +1 -2
  442. package/dist/safe-bash/commands/regex-execution/public.browser.js +8 -8
  443. package/dist/safe-bash/commands/safejs/runtime.js +16 -7
  444. package/dist/safe-bash/commands/search/index.d.ts +1 -1
  445. package/dist/safe-bash/commands/search/index.js +1 -347
  446. package/dist/safe-bash/commands/search/portable.d.ts +2 -2
  447. package/dist/safe-bash/commands/search/portable.js +3 -2
  448. package/dist/safe-bash/commands/sed/index.d.ts +2 -0
  449. package/dist/safe-bash/commands/sed/index.js +2 -0
  450. package/dist/safe-bash/commands/standard.d.ts +1 -0
  451. package/dist/safe-bash/commands/standard.js +2 -1
  452. package/dist/safe-bash/commands/streams.js +6 -24
  453. package/dist/safe-bash/commands/tar/index.d.ts +2 -0
  454. package/dist/safe-bash/commands/tar/index.js +2 -0
  455. package/dist/safe-bash/commands/text-programs/awk-inspection.d.ts +1 -19
  456. package/dist/safe-bash/commands/text-programs/awk-inspection.js +1 -50
  457. package/dist/safe-bash/commands/text-programs/awk-pipes.d.ts +2 -0
  458. package/dist/safe-bash/commands/text-programs/awk-pipes.js +2 -0
  459. package/dist/safe-bash/commands/text-programs/awk-pretty.d.ts +1 -3
  460. package/dist/safe-bash/commands/text-programs/awk-pretty.js +1 -197
  461. package/dist/safe-bash/commands/text-programs/awk-quote.d.ts +1 -2
  462. package/dist/safe-bash/commands/text-programs/awk-quote.js +1 -15
  463. package/dist/safe-bash/commands/text-programs/awk-reader.d.ts +1 -42
  464. package/dist/safe-bash/commands/text-programs/awk-reader.js +1 -449
  465. package/dist/safe-bash/commands/text-programs/awk-retention.d.ts +1 -13
  466. package/dist/safe-bash/commands/text-programs/awk-retention.js +1 -51
  467. package/dist/safe-bash/commands/text-programs/awk-runtime.d.ts +1 -150
  468. package/dist/safe-bash/commands/text-programs/awk-runtime.js +1 -2627
  469. package/dist/safe-bash/commands/text-programs/awk-syntax.d.ts +1 -142
  470. package/dist/safe-bash/commands/text-programs/awk-syntax.js +1 -509
  471. package/dist/safe-bash/commands/text-programs/awk-values.d.ts +1 -32
  472. package/dist/safe-bash/commands/text-programs/awk-values.js +1 -386
  473. package/dist/safe-bash/commands/text-programs/awk.d.ts +1 -3
  474. package/dist/safe-bash/commands/text-programs/awk.js +1 -361
  475. package/dist/safe-bash/commands/text-programs/inplace.d.ts +1 -16
  476. package/dist/safe-bash/commands/text-programs/inplace.js +1 -155
  477. package/dist/safe-bash/commands/text-programs/sed.d.ts +1 -3
  478. package/dist/safe-bash/commands/text-programs/sed.js +1 -1647
  479. package/dist/safe-bash/commands/text.js +268 -364
  480. package/dist/safe-bash/commands/tsort/index.browser.js +2 -2
  481. package/dist/safe-bash/commands/unzip/index.d.ts +2 -0
  482. package/dist/safe-bash/commands/unzip/index.js +2 -0
  483. package/dist/safe-bash/commands/wget/index.d.ts +2 -0
  484. package/dist/safe-bash/commands/wget/index.js +2 -0
  485. package/dist/safe-bash/commands/xml/index.browser.js +2 -2
  486. package/dist/safe-bash/commands/yq/index.browser.js +8 -3
  487. package/dist/safe-bash/commands/yq/index.d.ts +1 -6
  488. package/dist/safe-bash/commands/yq/index.js +1 -36
  489. package/dist/safe-bash/commands/zip/index.d.ts +2 -0
  490. package/dist/safe-bash/commands/zip/index.js +2 -0
  491. package/dist/safe-bash/core.browser.js +2 -2
  492. package/dist/safe-bash/core.d.ts +14 -2
  493. package/dist/safe-bash/core.js +8 -2
  494. package/dist/safe-bash/fs/s3/index.d.ts +2 -2
  495. package/dist/safe-bash/fs/s3/index.js +1 -1
  496. package/dist/safe-bash/full-core.browser.js +321 -286
  497. package/dist/safe-bash/jobs.browser.js +5 -5
  498. package/dist/safe-bash/lazy-mmdc.d.ts +6 -0
  499. package/dist/safe-bash/lazy-mmdc.js +23 -0
  500. package/dist/safe-bash/opt-in/commands/dd/index.js +2 -0
  501. package/dist/safe-bash/opt-in/commands/yq/mike.js +6 -13
  502. package/dist/safe-bash/opt-in/commands/yq/native-work.d.ts +1 -0
  503. package/dist/safe-bash/opt-in/commands/yq/native-work.js +17 -0
  504. package/dist/safe-bash/opt-in/optional/commands/shuf/options.d.ts +1 -0
  505. package/dist/safe-bash/opt-in/optional/commands/shuf/options.js +2 -4
  506. package/dist/safe-bash/opt-in/optional/commands/shuf/shuf.js +2 -1
  507. package/dist/safe-bash/optional-host.browser.js +15 -11
  508. package/dist/safe-bash/optional-host.d.ts +1 -1
  509. package/dist/safe-bash/optional-host.js +1 -1
  510. package/dist/safe-bash/playwright/ability-execution.js +3 -2
  511. package/dist/safe-bash/playwright/adapter.js +1 -1
  512. package/dist/safe-bash/playwright/controller.js +9 -8
  513. package/dist/safe-bash/playwright/modal-capabilities.js +2 -1
  514. package/dist/safe-bash/playwright/native-json-snapshot.js +4 -3
  515. package/dist/safe-bash/playwright/native-snapshot.js +5 -4
  516. package/dist/safe-bash/playwright/open-options.js +3 -3
  517. package/dist/safe-bash/playwright/resource-limit.d.ts +2 -0
  518. package/dist/safe-bash/playwright/resource-limit.js +4 -0
  519. package/dist/safe-bash/playwright/session-configuration.js +8 -3
  520. package/dist/safe-bash/playwright/snapshot.js +8 -7
  521. package/dist/safe-bash/playwright/standard-capabilities.js +5 -4
  522. package/dist/safe-bash/plugins/composition.d.ts +1 -0
  523. package/dist/safe-bash/plugins/composition.js +3 -8
  524. package/dist/safe-bash/plugins/index.browser.js +27 -29
  525. package/dist/safe-bash/registry-entry.browser.js +28 -30
  526. package/dist/safe-bash/shell/arrays/bindings.d.ts +3 -5
  527. package/dist/safe-bash/shell/arrays/bindings.js +7 -3
  528. package/dist/safe-bash/shell/arrays/state.js +4 -0
  529. package/dist/safe-bash/shell/brace-expansion.js +1 -1
  530. package/dist/safe-bash/shell/dynamic-variables.d.ts +10 -0
  531. package/dist/safe-bash/shell/dynamic-variables.js +25 -0
  532. package/dist/safe-bash/shell/input.js +16 -14
  533. package/dist/safe-bash/shell/parser.js +8 -1
  534. package/dist/safe-bash/shell/runtime.d.ts +7 -4
  535. package/dist/safe-bash/shell/runtime.js +604 -802
  536. package/dist/safe-bash/shell/shell.js +2 -31
  537. package/dist/safe-bash/shell/types.d.ts +2 -0
  538. package/dist/safe-bash/shell/value-state.js +17 -2
  539. package/dist/safe-bash/shell/worker-limits.js +1 -0
  540. package/dist/safe-bash/shell-entry.browser.js +25 -27
  541. package/dist/safe-bash/trap.browser.d.ts +3 -0
  542. package/dist/safe-bash/trap.browser.js +14 -0
  543. package/dist/safe-bash/worker/host.js +1 -1
  544. package/dist/safe-bash/yq-browser/index.js +1 -1
  545. package/dist/safe-bash-base-encoding-engine/base.js +2 -2
  546. package/dist/safe-bash-base-encoding-engine/shared.js +1 -1
  547. package/dist/safe-bash-byte-input-engine/index.d.ts +3 -2
  548. package/dist/safe-bash-byte-input-engine/index.js +4 -1
  549. package/dist/safe-bash-checksum-engine/index.js +13 -6
  550. package/dist/safe-bash-command-apply-patch/apply.d.ts +1 -1
  551. package/dist/safe-bash-command-apply-patch/apply.js +4 -3
  552. package/dist/safe-bash-command-apply-patch/index.js +4 -4
  553. package/dist/safe-bash-command-apply-patch/matcher.js +1 -1
  554. package/dist/safe-bash-command-apply-patch/parser.js +1 -1
  555. package/dist/safe-bash-command-awk/LICENSE +21 -0
  556. package/dist/safe-bash-command-awk/awk-inspection.d.ts +19 -0
  557. package/dist/safe-bash-command-awk/awk-inspection.js +9 -0
  558. package/dist/safe-bash-command-awk/awk-pipes.d.ts +19 -0
  559. package/dist/safe-bash-command-awk/awk-pipes.js +8 -0
  560. package/dist/safe-bash-command-awk/awk-pretty.d.ts +3 -0
  561. package/dist/safe-bash-command-awk/awk-pretty.js +8 -0
  562. package/dist/safe-bash-command-awk/awk-quote.d.ts +2 -0
  563. package/dist/safe-bash-command-awk/awk-quote.js +7 -0
  564. package/dist/safe-bash-command-awk/awk-reader.d.ts +42 -0
  565. package/dist/safe-bash-command-awk/awk-reader.js +9 -0
  566. package/dist/safe-bash-command-awk/awk-retention.d.ts +13 -0
  567. package/dist/safe-bash-command-awk/awk-retention.js +7 -0
  568. package/dist/safe-bash-command-awk/awk-runtime.d.ts +151 -0
  569. package/dist/safe-bash-command-awk/awk-runtime.js +11 -0
  570. package/dist/safe-bash-command-awk/awk-syntax.d.ts +144 -0
  571. package/dist/safe-bash-command-awk/awk-syntax.js +14 -0
  572. package/dist/safe-bash-command-awk/awk-values.d.ts +32 -0
  573. package/dist/safe-bash-command-awk/awk-values.js +35 -0
  574. package/dist/safe-bash-command-awk/awk.d.ts +3 -0
  575. package/dist/safe-bash-command-awk/awk.js +16 -0
  576. package/dist/safe-bash-command-awk/index.d.ts +7 -0
  577. package/dist/safe-bash-command-awk/index.js +36 -0
  578. package/dist/safe-bash-command-bc/index.d.ts +6 -0
  579. package/dist/safe-bash-command-bc/index.js +136 -266
  580. package/dist/safe-bash-command-column/column.js +5 -5
  581. package/dist/safe-bash-command-column/display.d.ts +1 -1
  582. package/dist/safe-bash-command-column/display.js +1 -1
  583. package/dist/safe-bash-command-column/index.js +5 -5
  584. package/dist/safe-bash-command-column/internal.d.ts +0 -2
  585. package/dist/safe-bash-command-column/internal.js +1 -1
  586. package/dist/safe-bash-command-column/layout.js +4 -4
  587. package/dist/safe-bash-command-column/table.js +2 -2
  588. package/dist/safe-bash-command-comm/comm.js +1 -1
  589. package/dist/safe-bash-command-comm/index.js +1 -1
  590. package/dist/safe-bash-command-csplit/command.js +2 -2
  591. package/dist/safe-bash-command-csplit/index.js +2 -2
  592. package/dist/safe-bash-command-csvcut/index.d.ts +1 -0
  593. package/dist/safe-bash-command-csvcut/index.js +1 -0
  594. package/dist/safe-bash-command-csvgrep/index.d.ts +1 -0
  595. package/dist/safe-bash-command-csvgrep/index.js +2 -2
  596. package/dist/safe-bash-command-csvkit/contracts.d.ts +1 -0
  597. package/dist/safe-bash-command-csvkit/csvpy-interpreter.d.ts +2 -1
  598. package/dist/safe-bash-command-csvkit/default-csvpy.d.ts +11 -0
  599. package/dist/safe-bash-command-csvkit/errors.js +22 -0
  600. package/dist/safe-bash-command-csvkit/index.d.ts +1 -0
  601. package/dist/safe-bash-command-csvkit/index.js +180 -12
  602. package/dist/safe-bash-command-csvkit/python-worker-browser.d.ts +3 -0
  603. package/dist/safe-bash-command-csvkit/python-worker-browser.js +16 -0
  604. package/dist/safe-bash-command-csvkit/python-worker-contract.d.ts +20 -0
  605. package/dist/safe-bash-command-csvkit/python-worker-node.d.ts +3 -0
  606. package/dist/safe-bash-command-csvkit/python-worker-node.js +9 -0
  607. package/dist/safe-bash-command-csvkit/runtime.d.ts +1 -0
  608. package/dist/safe-bash-command-csvkit/sync-support.js +1 -1
  609. package/dist/safe-bash-command-curl/LICENSE +21 -0
  610. package/dist/safe-bash-command-curl/curl.d.ts +13 -0
  611. package/dist/safe-bash-command-curl/curl.js +9 -0
  612. package/dist/safe-bash-command-curl/index.d.ts +6 -0
  613. package/dist/safe-bash-command-curl/index.js +26 -0
  614. package/dist/safe-bash-command-dd/index.js +2 -0
  615. package/dist/safe-bash-command-diff/LICENSE +21 -0
  616. package/dist/safe-bash-command-diff/diff-format.d.ts +10 -0
  617. package/dist/safe-bash-command-diff/diff-format.js +10 -0
  618. package/dist/safe-bash-command-diff/diff-options.d.ts +38 -0
  619. package/dist/safe-bash-command-diff/diff-options.js +7 -0
  620. package/dist/safe-bash-command-diff/diff-output.d.ts +20 -0
  621. package/dist/safe-bash-command-diff/diff-output.js +19 -0
  622. package/dist/safe-bash-command-diff/diff.d.ts +2 -0
  623. package/dist/safe-bash-command-diff/diff.js +10 -0
  624. package/dist/safe-bash-command-diff/index.d.ts +8 -0
  625. package/dist/safe-bash-command-diff/index.js +34 -0
  626. package/dist/safe-bash-command-diff/sync.d.ts +2 -0
  627. package/dist/safe-bash-command-diff/sync.js +9 -0
  628. package/dist/safe-bash-command-diff3/index.js +5 -5
  629. package/dist/safe-bash-command-docx/index.d.ts +4 -4
  630. package/dist/safe-bash-command-docx/index.js +12 -5
  631. package/dist/safe-bash-command-dos2unix/index.d.ts +1 -0
  632. package/dist/safe-bash-command-dos2unix/index.js +225 -1
  633. package/dist/safe-bash-command-dos2unix/sync.d.ts +1 -0
  634. package/dist/safe-bash-command-exiftool/index.d.ts +1 -0
  635. package/dist/safe-bash-command-exiftool/index.js +2 -2
  636. package/dist/safe-bash-command-factor/command.js +2 -2
  637. package/dist/safe-bash-command-factor/index.js +2 -2
  638. package/dist/safe-bash-command-fd/index.js +9 -9
  639. package/dist/safe-bash-command-ffmpeg/index.js +117 -102
  640. package/dist/safe-bash-command-file/index.js +4 -4
  641. package/dist/safe-bash-command-file/shared.js +1 -1
  642. package/dist/safe-bash-command-find/LICENSE +21 -0
  643. package/dist/safe-bash-command-find/find-format.d.ts +20 -0
  644. package/dist/safe-bash-command-find/find-format.js +9 -0
  645. package/dist/safe-bash-command-find/find.d.ts +18 -0
  646. package/dist/safe-bash-command-find/find.js +10 -0
  647. package/dist/safe-bash-command-find/index.d.ts +13 -0
  648. package/dist/safe-bash-command-find/index.js +45 -0
  649. package/dist/safe-bash-command-fmt/index.js +7 -4
  650. package/dist/safe-bash-command-git/git_rust.wasm +0 -0
  651. package/dist/safe-bash-command-git/index.js +5 -7
  652. package/dist/safe-bash-command-git/wasm.generated.js +1 -1
  653. package/dist/safe-bash-command-gzip/LICENSE +21 -0
  654. package/dist/safe-bash-command-gzip/index.d.ts +11 -0
  655. package/dist/safe-bash-command-gzip/index.js +95 -0
  656. package/dist/safe-bash-command-hexdump/command.js +4 -4
  657. package/dist/safe-bash-command-hexdump/custom.d.ts +24 -0
  658. package/dist/safe-bash-command-hexdump/index.js +4 -4
  659. package/dist/safe-bash-command-hexdump/internal.d.ts +2 -0
  660. package/dist/safe-bash-command-hexdump/internal.js +1 -1
  661. package/dist/safe-bash-command-hexdump/io.js +2 -2
  662. package/dist/safe-bash-command-hexdump/options.d.ts +3 -0
  663. package/dist/safe-bash-command-hexdump/options.js +2 -2
  664. package/dist/safe-bash-command-hostname/index.js +1 -1
  665. package/dist/safe-bash-command-html-to-markdown/budget.js +1 -1
  666. package/dist/safe-bash-command-html-to-markdown/entities.js +3 -3
  667. package/dist/safe-bash-command-html-to-markdown/index.js +11 -11
  668. package/dist/safe-bash-command-html-to-markdown/input.js +5 -5
  669. package/dist/safe-bash-command-html-to-markdown/parser.d.ts +1 -0
  670. package/dist/safe-bash-command-html-to-markdown/parser.js +4 -4
  671. package/dist/safe-bash-command-html-to-markdown/render.js +5 -5
  672. package/dist/safe-bash-command-html-to-markdown/text.js +2 -2
  673. package/dist/safe-bash-command-htmlq/index.d.ts +1 -0
  674. package/dist/safe-bash-command-htmlq/index.js +39 -17
  675. package/dist/safe-bash-command-iconv/codec.js +1 -1
  676. package/dist/safe-bash-command-iconv/command.js +2 -2
  677. package/dist/safe-bash-command-iconv/index.js +2 -2
  678. package/dist/safe-bash-command-imagemagick/index.js +45 -35
  679. package/dist/safe-bash-command-join/index.js +1 -1
  680. package/dist/safe-bash-command-join/join.js +1 -1
  681. package/dist/safe-bash-command-jq/index.js +1 -1
  682. package/dist/safe-bash-command-jq/jq.js +1 -1
  683. package/dist/safe-bash-command-less/index.js +43 -28
  684. package/dist/safe-bash-command-llm/command.js +1 -1
  685. package/dist/safe-bash-command-llm/index.d.ts +1 -0
  686. package/dist/safe-bash-command-llm/index.js +16 -14
  687. package/dist/safe-bash-command-llm/openai.js +3 -3
  688. package/dist/safe-bash-command-llm/providers/index.js +3 -3
  689. package/dist/safe-bash-command-llm/providers/openai.js +3 -3
  690. package/dist/safe-bash-command-llm/stored-schema.d.ts +10 -0
  691. package/dist/safe-bash-command-mmdc/index.d.ts +1 -0
  692. package/dist/safe-bash-command-mmdc/index.js +13 -604
  693. package/dist/safe-bash-command-mmdc/settings.d.ts +2 -0
  694. package/dist/safe-bash-command-mmdc/settings.js +7 -0
  695. package/dist/safe-bash-command-numfmt/index.js +0 -11
  696. package/dist/safe-bash-command-od/index.js +101 -68
  697. package/dist/safe-bash-command-pandoc/command.js +4 -3
  698. package/dist/safe-bash-command-pandoc/defaults.d.ts +1 -0
  699. package/dist/safe-bash-command-pandoc/index.js +4 -3
  700. package/dist/safe-bash-command-pandoc/lua-filters.js +1 -1
  701. package/dist/safe-bash-command-pandoc/types.d.ts +3 -1
  702. package/dist/safe-bash-command-paste/index.js +1 -1
  703. package/dist/safe-bash-command-paste/paste.js +1 -1
  704. package/dist/safe-bash-command-patch/LICENSE +21 -0
  705. package/dist/safe-bash-command-patch/index.d.ts +8 -0
  706. package/dist/safe-bash-command-patch/index.js +38 -0
  707. package/dist/safe-bash-command-patch/patch-envelope.d.ts +2 -0
  708. package/dist/safe-bash-command-patch/patch-envelope.js +7 -0
  709. package/dist/safe-bash-command-patch/patch-formats.d.ts +7 -0
  710. package/dist/safe-bash-command-patch/patch-formats.js +9 -0
  711. package/dist/safe-bash-command-patch/patch-gnu-paths.d.ts +41 -0
  712. package/dist/safe-bash-command-patch/patch-gnu-paths.js +26 -0
  713. package/dist/safe-bash-command-patch/patch-gnu-reject.d.ts +3 -0
  714. package/dist/safe-bash-command-patch/patch-gnu-reject.js +7 -0
  715. package/dist/safe-bash-command-patch/patch-path.d.ts +3 -0
  716. package/dist/safe-bash-command-patch/patch-path.js +11 -0
  717. package/dist/safe-bash-command-patch/patch-publication.d.ts +13 -0
  718. package/dist/safe-bash-command-patch/patch-publication.js +7 -0
  719. package/dist/safe-bash-command-patch/patch.d.ts +2 -0
  720. package/dist/safe-bash-command-patch/patch.js +14 -0
  721. package/dist/safe-bash-command-patch/sync.d.ts +2 -0
  722. package/dist/safe-bash-command-patch/sync.js +7 -0
  723. package/dist/safe-bash-command-patch/unified.d.ts +52 -0
  724. package/dist/safe-bash-command-patch/unified.js +16 -0
  725. package/dist/safe-bash-command-pathchk/index.js +3 -13
  726. package/dist/safe-bash-command-pdfimages/index.js +62 -25
  727. package/dist/safe-bash-command-pdfinfo/index.d.ts +0 -23
  728. package/dist/safe-bash-command-pdfinfo/index.js +39 -782
  729. package/dist/safe-bash-command-pdftk/index.js +40 -12
  730. package/dist/safe-bash-command-pdftoppm/index.js +76 -30
  731. package/dist/safe-bash-command-pdftotext/index.js +37 -15
  732. package/dist/safe-bash-command-pptx/index.d.ts +4 -4
  733. package/dist/safe-bash-command-pptx/index.js +11 -5
  734. package/dist/safe-bash-command-pr/command.js +2 -2
  735. package/dist/safe-bash-command-pr/index.js +4 -4
  736. package/dist/safe-bash-command-qpdf/index.js +31 -18
  737. package/dist/safe-bash-command-rg/index.d.ts +1 -0
  738. package/dist/safe-bash-command-rg/index.js +222 -1
  739. package/dist/safe-bash-command-rg/rg-command.js +1 -1
  740. package/dist/safe-bash-command-rg/sync.d.ts +1 -0
  741. package/dist/safe-bash-command-sed/LICENSE +21 -0
  742. package/dist/safe-bash-command-sed/index.d.ts +7 -0
  743. package/dist/safe-bash-command-sed/index.js +28 -0
  744. package/dist/safe-bash-command-sed/inplace.d.ts +16 -0
  745. package/dist/safe-bash-command-sed/inplace.js +9 -0
  746. package/dist/safe-bash-command-sed/sed.d.ts +3 -0
  747. package/dist/safe-bash-command-sed/sed.js +8 -0
  748. package/dist/safe-bash-command-shuf/options.d.ts +1 -0
  749. package/dist/safe-bash-command-shuf/options.js +2 -4
  750. package/dist/safe-bash-command-shuf/shuf.js +2 -1
  751. package/dist/safe-bash-command-sips/index.js +111 -35
  752. package/dist/safe-bash-command-soffice/index.js +21 -17
  753. package/dist/safe-bash-command-split/index.js +3 -3
  754. package/dist/safe-bash-command-split/io.js +1 -1
  755. package/dist/safe-bash-command-split/outputs.js +2 -2
  756. package/dist/safe-bash-command-split/split.js +3 -3
  757. package/dist/safe-bash-command-sqlite3/btree.d.ts +1 -0
  758. package/dist/safe-bash-command-sqlite3/engine.d.ts +7 -2
  759. package/dist/safe-bash-command-sqlite3/index.js +436 -537
  760. package/dist/safe-bash-command-ssconvert/commands.js +9 -9
  761. package/dist/safe-bash-command-ssconvert/core.js +8 -8
  762. package/dist/safe-bash-command-ssconvert/formats/csv.js +9 -9
  763. package/dist/safe-bash-command-ssconvert/formats/ods.js +9 -9
  764. package/dist/safe-bash-command-ssconvert/formats/spreadsheetml.js +2 -2
  765. package/dist/safe-bash-command-ssconvert/formats/xls.js +9 -9
  766. package/dist/safe-bash-command-ssconvert/formats/xlsx.js +9 -9
  767. package/dist/safe-bash-command-ssconvert/index.js +21 -21
  768. package/dist/safe-bash-command-tar/LICENSE +21 -0
  769. package/dist/safe-bash-command-tar/create.d.ts +17 -0
  770. package/dist/safe-bash-command-tar/create.js +14 -0
  771. package/dist/safe-bash-command-tar/extract.d.ts +11 -0
  772. package/dist/safe-bash-command-tar/extract.js +14 -0
  773. package/dist/safe-bash-command-tar/format.d.ts +32 -0
  774. package/dist/safe-bash-command-tar/format.js +19 -0
  775. package/dist/safe-bash-command-tar/index.d.ts +8 -0
  776. package/dist/safe-bash-command-tar/index.js +551 -0
  777. package/dist/safe-bash-command-tar/listing.d.ts +2 -0
  778. package/dist/safe-bash-command-tar/listing.js +7 -0
  779. package/dist/safe-bash-command-tar/modes.d.ts +5 -0
  780. package/dist/safe-bash-command-tar/modes.js +16 -0
  781. package/dist/safe-bash-command-tar/options.d.ts +53 -0
  782. package/dist/safe-bash-command-tar/options.js +10 -0
  783. package/dist/safe-bash-command-tar/stream.d.ts +22 -0
  784. package/dist/safe-bash-command-tar/stream.js +15 -0
  785. package/dist/safe-bash-command-tar/transform.d.ts +16 -0
  786. package/dist/safe-bash-command-tar/transform.js +9 -0
  787. package/dist/safe-bash-command-tree/arguments.js +3 -3
  788. package/dist/safe-bash-command-tree/charset.js +1 -1
  789. package/dist/safe-bash-command-tree/index.js +4 -4
  790. package/dist/safe-bash-command-tree/io.js +1 -1
  791. package/dist/safe-bash-command-tree/pattern.js +2 -2
  792. package/dist/safe-bash-command-tree/tree.js +4 -4
  793. package/dist/safe-bash-command-unrtf/index.js +14 -7
  794. package/dist/safe-bash-command-unzip/LICENSE +21 -0
  795. package/dist/safe-bash-command-unzip/index.d.ts +7 -0
  796. package/dist/safe-bash-command-unzip/index.js +39 -0
  797. package/dist/safe-bash-command-unzip/sync.d.ts +3 -0
  798. package/dist/safe-bash-command-unzip/sync.js +9 -0
  799. package/dist/safe-bash-command-unzip/unzip/safety.d.ts +32 -0
  800. package/dist/safe-bash-command-unzip/unzip/safety.js +7 -0
  801. package/dist/safe-bash-command-unzip/unzip.d.ts +3 -0
  802. package/dist/safe-bash-command-unzip/unzip.js +8 -0
  803. package/dist/safe-bash-command-wget/LICENSE +21 -0
  804. package/dist/safe-bash-command-wget/index.d.ts +6 -0
  805. package/dist/safe-bash-command-wget/index.js +26 -0
  806. package/dist/safe-bash-command-wget/wget.d.ts +3 -0
  807. package/dist/safe-bash-command-wget/wget.js +7 -0
  808. package/dist/safe-bash-command-xan/argv.d.ts +4 -1
  809. package/dist/safe-bash-command-xan/argv.js +1 -1
  810. package/dist/safe-bash-command-xan/commands.js +6 -3
  811. package/dist/safe-bash-command-xan/csv.d.ts +1 -1
  812. package/dist/safe-bash-command-xan/csv.js +1 -1
  813. package/dist/safe-bash-command-xan/index.js +18 -17
  814. package/dist/safe-bash-command-xan/io.js +3 -3
  815. package/dist/safe-bash-command-xmllint/index.js +190 -50
  816. package/dist/safe-bash-command-xxd/index.js +105 -91
  817. package/dist/safe-bash-command-xz/command.d.ts +2 -0
  818. package/dist/safe-bash-command-xz/index.d.ts +1 -1
  819. package/dist/safe-bash-command-xz/index.js +11 -2
  820. package/dist/safe-bash-command-xz/options.d.ts +9 -1
  821. package/dist/safe-bash-command-xz/options.js +3 -1
  822. package/dist/safe-bash-command-yq/index.d.ts +4 -11
  823. package/dist/safe-bash-command-yq/index.js +3367 -670
  824. package/dist/safe-bash-command-yq/mike.js +6 -13
  825. package/dist/safe-bash-command-yq/native-work.d.ts +1 -0
  826. package/dist/safe-bash-command-yq/native-work.js +17 -0
  827. package/dist/safe-bash-command-yq/query.d.ts +11 -0
  828. package/dist/safe-bash-command-yq/query.js +735 -0
  829. package/dist/safe-bash-command-zip/LICENSE +21 -0
  830. package/dist/safe-bash-command-zip/index.d.ts +7 -0
  831. package/dist/safe-bash-command-zip/index.js +38 -0
  832. package/dist/safe-bash-command-zip/sync.d.ts +3 -0
  833. package/dist/safe-bash-command-zip/sync.js +9 -0
  834. package/dist/safe-bash-command-zip/zip.d.ts +3 -0
  835. package/dist/safe-bash-command-zip/zip.js +7 -0
  836. package/dist/safe-bash-compression-engine/files.js +4 -4
  837. package/dist/safe-bash-compression-engine/index.js +2 -2
  838. package/dist/safe-bash-compression-engine/operand.js +6 -6
  839. package/dist/safe-bash-compression-engine/stream.js +2 -2
  840. package/dist/safe-bash-compression-engine/zstd-decode.js +1 -1
  841. package/dist/safe-bash-contracts/command.js +1 -1
  842. package/dist/safe-bash-contracts/diagnostics.js +4 -4
  843. package/dist/safe-bash-contracts/escaping.js +12 -12
  844. package/dist/safe-bash-contracts/filesystem-descriptor.js +1 -1
  845. package/dist/safe-bash-contracts/filesystem-output.js +8 -8
  846. package/dist/safe-bash-contracts/index.d.ts +1 -0
  847. package/dist/safe-bash-contracts/index.js +39 -35
  848. package/dist/safe-bash-contracts/io.d.ts +4 -1
  849. package/dist/safe-bash-contracts/io.js +4 -2
  850. package/dist/safe-bash-contracts/managed-abort.d.ts +10 -0
  851. package/dist/safe-bash-contracts/output.js +3 -3
  852. package/dist/safe-bash-diff-engine/LICENSE +21 -0
  853. package/dist/safe-bash-diff-engine/index.d.ts +1 -0
  854. package/dist/safe-bash-diff-engine/index.js +24 -0
  855. package/dist/safe-bash-diff-engine/shared.d.ts +54 -0
  856. package/dist/safe-bash-diff-engine/shared.js +19 -0
  857. package/dist/safe-bash-io-engine/commands/archive/internal.js +5 -23
  858. package/dist/safe-bash-io-engine/commands/directory-admission.d.ts +3 -0
  859. package/dist/safe-bash-io-engine/commands/directory-admission.js +34 -0
  860. package/dist/safe-bash-io-engine/commands/mode-change.d.ts +4 -0
  861. package/dist/safe-bash-io-engine/commands/mode-change.js +60 -0
  862. package/dist/safe-bash-io-engine/commands/search/requirements.js +2 -2
  863. package/dist/safe-bash-io-engine/commands/text-programs/shared.js +44 -66
  864. package/dist/safe-bash-io-engine/internal.js +1 -1
  865. package/dist/safe-bash-io-engine/shell/pattern.js +8 -13
  866. package/dist/safe-bash-io-engine/shell/string-operations.js +1 -1
  867. package/dist/safe-bash-markdown-engine/commonmark-blocks.js +4 -4
  868. package/dist/safe-bash-markdown-engine/commonmark-inlines.js +4 -4
  869. package/dist/safe-bash-markdown-engine/commonmark-syntax.js +2 -2
  870. package/dist/safe-bash-markdown-engine/gfm-syntax.js +3 -3
  871. package/dist/safe-bash-markdown-engine/index.js +7 -7
  872. package/dist/safe-bash-mcp/index.browser.d.ts +161 -35
  873. package/dist/safe-bash-mcp/index.browser.js +417 -0
  874. package/dist/safe-bash-mcp/index.d.ts +66 -2
  875. package/dist/safe-bash-mcp/index.js +1838 -122
  876. package/dist/safe-bash-network-engine/LICENSE +21 -0
  877. package/dist/safe-bash-network-engine/aggregate.d.ts +4 -0
  878. package/dist/safe-bash-network-engine/aggregate.js +37 -0
  879. package/dist/safe-bash-network-engine/args.d.ts +68 -0
  880. package/dist/safe-bash-network-engine/args.js +19 -0
  881. package/dist/safe-bash-network-engine/authorizer.d.ts +6 -0
  882. package/dist/safe-bash-network-engine/authorizer.js +8 -0
  883. package/dist/safe-bash-network-engine/body.d.ts +9 -0
  884. package/dist/safe-bash-network-engine/body.js +374 -0
  885. package/dist/safe-bash-network-engine/deadline.d.ts +2 -0
  886. package/dist/safe-bash-network-engine/deadline.js +7 -0
  887. package/dist/safe-bash-network-engine/decode.d.ts +2 -0
  888. package/dist/safe-bash-network-engine/decode.js +80 -0
  889. package/dist/safe-bash-network-engine/fetch-transport.d.ts +7 -0
  890. package/dist/safe-bash-network-engine/fetch-transport.js +9 -0
  891. package/dist/safe-bash-network-engine/form-content-type.d.ts +5 -0
  892. package/dist/safe-bash-network-engine/form-content-type.js +8 -0
  893. package/dist/safe-bash-network-engine/form-headers.d.ts +2 -0
  894. package/dist/safe-bash-network-engine/form-headers.js +10 -0
  895. package/dist/safe-bash-network-engine/glob.d.ts +7 -0
  896. package/dist/safe-bash-network-engine/glob.js +124 -0
  897. package/dist/safe-bash-network-engine/index.d.ts +3 -0
  898. package/dist/safe-bash-network-engine/index.js +26 -0
  899. package/dist/safe-bash-network-engine/input.d.ts +5 -0
  900. package/dist/safe-bash-network-engine/input.js +255 -0
  901. package/dist/safe-bash-network-engine/output.d.ts +6 -0
  902. package/dist/safe-bash-network-engine/output.js +132 -0
  903. package/dist/safe-bash-network-engine/platform-portable.d.ts +5 -0
  904. package/dist/safe-bash-network-engine/platform-portable.js +19 -0
  905. package/dist/safe-bash-network-engine/private-address.d.ts +1 -0
  906. package/dist/safe-bash-network-engine/private-address.js +7 -0
  907. package/dist/safe-bash-network-engine/shared.d.ts +14 -0
  908. package/dist/safe-bash-network-engine/shared.js +23 -0
  909. package/dist/safe-bash-network-engine/types.d.ts +42 -0
  910. package/dist/safe-bash-network-engine/types.js +11 -0
  911. package/dist/safe-bash-network-engine/url.d.ts +2 -0
  912. package/dist/safe-bash-network-engine/url.js +8 -0
  913. package/dist/safe-bash-query-engine/capture.d.ts +1 -0
  914. package/dist/safe-bash-query-engine/capture.js +9 -7
  915. package/dist/safe-bash-query-engine/dates.d.ts +5 -1
  916. package/dist/safe-bash-query-engine/dates.js +10 -2
  917. package/dist/safe-bash-query-engine/delpaths.js +5 -5
  918. package/dist/safe-bash-query-engine/formats.js +3 -3
  919. package/dist/safe-bash-query-engine/index.js +15 -15
  920. package/dist/safe-bash-query-engine/indices.js +5 -5
  921. package/dist/safe-bash-query-engine/input.d.ts +1 -2
  922. package/dist/safe-bash-query-engine/input.js +2 -4
  923. package/dist/safe-bash-query-engine/interpreter.d.ts +5 -0
  924. package/dist/safe-bash-query-engine/interpreter.js +13 -13
  925. package/dist/safe-bash-query-engine/limits.js +1 -1
  926. package/dist/safe-bash-query-engine/parser.d.ts +8 -1
  927. package/dist/safe-bash-query-engine/parser.js +2 -2
  928. package/dist/safe-bash-query-engine/query-core.js +15 -15
  929. package/dist/safe-bash-query-engine/recurse.js +2 -2
  930. package/dist/safe-bash-query-engine/regex.d.ts +4 -2
  931. package/dist/safe-bash-query-engine/regex.js +10 -5
  932. package/dist/safe-bash-query-engine/split.js +2 -2
  933. package/dist/safe-bash-query-engine/splits.d.ts +1 -1
  934. package/dist/safe-bash-query-engine/splits.js +7 -6
  935. package/dist/safe-bash-query-engine/values.js +4 -4
  936. package/dist/safe-bash-regex-engine/ere/matcher.js +106 -34
  937. package/dist/safe-bash-regex-engine/execution/bounded-provider.js +55 -67
  938. package/dist/safe-bash-regex-engine/execution/portable.d.ts +0 -1
  939. package/dist/safe-bash-regex-engine/execution/portable.js +6 -10
  940. package/dist/safe-bash-regex-engine/execution/protocol.d.ts +0 -5
  941. package/dist/safe-bash-regex-engine/execution/protocol.js +1 -3
  942. package/dist/safe-bash-regex-engine/index.js +6 -4
  943. package/dist/safe-bash-regex-engine/text/budget.d.ts +1 -0
  944. package/dist/safe-bash-regex-engine/text/budget.js +1 -1
  945. package/dist/safe-bash-regex-engine/text/regex.d.ts +15 -0
  946. package/dist/safe-bash-regex-engine/text/regex.js +6 -4
  947. package/dist/safe-bash-regex-engine/text/replacement-buffer.js +2 -2
  948. package/dist/safe-bash-regex-engine/text/rust-syntax.js +2 -2
  949. package/dist/safe-bash-search-engine/ergonomic-regex.d.ts +12 -2
  950. package/dist/safe-bash-search-engine/ergonomic-regex.js +2 -2
  951. package/dist/safe-bash-search-engine/glob.js +2 -2
  952. package/dist/safe-bash-search-engine/grep.js +191 -229
  953. package/dist/safe-bash-search-engine/matcher.d.ts +6 -2
  954. package/dist/safe-bash-search-engine/matcher.js +30 -8
  955. package/dist/safe-bash-search-engine/options.js +1 -1
  956. package/dist/safe-bash-search-engine/output.d.ts +3 -2
  957. package/dist/safe-bash-search-engine/output.js +111 -30
  958. package/dist/safe-bash-search-engine/shared.d.ts +2 -0
  959. package/dist/safe-bash-search-engine/shared.js +2 -2
  960. package/dist/safe-bash-search-engine/walk.js +11 -10
  961. package/dist/safe-bash-table-text-engine/table-text/internal.d.ts +7 -5
  962. package/dist/safe-bash-table-text-engine/table-text/internal.js +39 -21
  963. package/dist/safe-bash-xml-engine/document.d.ts +1 -1
  964. package/dist/safe-bash-xml-engine/document.js +3 -3
  965. package/dist/safe-bash-xml-engine/evaluate.d.ts +1 -0
  966. package/dist/safe-bash-xml-engine/evaluate.js +4 -1
  967. package/dist/safe-bash-xml-engine/index.js +8 -6
  968. package/dist/safe-bash-xml-engine/io.js +1 -1
  969. package/dist/safe-bash-xml-engine/limits.d.ts +2 -0
  970. package/dist/safe-bash-xml-engine/limits.js +1 -1
  971. package/dist/safe-bash-xml-engine/predicate.d.ts +57 -0
  972. package/dist/safe-bash-xml-engine/query.d.ts +3 -15
  973. package/dist/safe-bash-xml-engine/query.js +3 -2
  974. package/dist/safe-bash-zip-engine/LICENSE +21 -0
  975. package/dist/safe-bash-zip-engine/index.d.ts +1 -0
  976. package/dist/safe-bash-zip-engine/index.js +32 -0
  977. package/dist/safe-bash-zip-engine/unzip/arguments.d.ts +53 -0
  978. package/dist/safe-bash-zip-engine/unzip/arguments.js +270 -0
  979. package/dist/safe-bash-zip-engine/zip/aes.d.ts +17 -0
  980. package/dist/safe-bash-zip-engine/zip/aes.js +15 -0
  981. package/dist/safe-bash-zip-engine/zip/comments.d.ts +17 -0
  982. package/dist/safe-bash-zip-engine/zip/comments.js +77 -0
  983. package/dist/safe-bash-zip-engine/zip/crc.d.ts +1 -0
  984. package/dist/safe-bash-zip-engine/zip/crc.js +7 -0
  985. package/dist/safe-bash-zip-engine/zip/crypto.d.ts +19 -0
  986. package/dist/safe-bash-zip-engine/zip/crypto.js +16 -0
  987. package/dist/safe-bash-zip-engine/zip/dates.d.ts +4 -0
  988. package/dist/safe-bash-zip-engine/zip/dates.js +68 -0
  989. package/dist/safe-bash-zip-engine/zip/environment.d.ts +2 -0
  990. package/dist/safe-bash-zip-engine/zip/environment.js +60 -0
  991. package/dist/safe-bash-zip-engine/zip/grow.d.ts +3 -0
  992. package/dist/safe-bash-zip-engine/zip/grow.js +7 -0
  993. package/dist/safe-bash-zip-engine/zip/help.d.ts +4 -0
  994. package/dist/safe-bash-zip-engine/zip/help.js +194 -0
  995. package/dist/safe-bash-zip-engine/zip/line-endings.d.ts +2 -0
  996. package/dist/safe-bash-zip-engine/zip/line-endings.js +165 -0
  997. package/dist/safe-bash-zip-engine/zip/log.d.ts +22 -0
  998. package/dist/safe-bash-zip-engine/zip/log.js +153 -0
  999. package/dist/safe-bash-zip-engine/zip/lzma.d.ts +9 -0
  1000. package/dist/safe-bash-zip-engine/zip/lzma.js +7 -0
  1001. package/dist/safe-bash-zip-engine/zip/move.d.ts +11 -0
  1002. package/dist/safe-bash-zip-engine/zip/move.js +57 -0
  1003. package/dist/safe-bash-zip-engine/zip/names.d.ts +2 -0
  1004. package/dist/safe-bash-zip-engine/zip/names.js +37 -0
  1005. package/dist/safe-bash-zip-engine/zip/options.d.ts +13 -0
  1006. package/dist/safe-bash-zip-engine/zip/options.js +23 -0
  1007. package/dist/safe-bash-zip-engine/zip/repair.d.ts +10 -0
  1008. package/dist/safe-bash-zip-engine/zip/repair.js +348 -0
  1009. package/dist/safe-bash-zip-engine/zip/safety.d.ts +54 -0
  1010. package/dist/safe-bash-zip-engine/zip/safety.js +19 -0
  1011. package/dist/safe-bash-zip-engine/zip/sfx.d.ts +4 -0
  1012. package/dist/safe-bash-zip-engine/zip/sfx.js +58 -0
  1013. package/dist/safe-bash-zip-engine/zip/test-command.d.ts +5 -0
  1014. package/dist/safe-bash-zip-engine/zip/test-command.js +98 -0
  1015. package/dist/safe-bash-zip-engine/zip/volumes.d.ts +21 -0
  1016. package/dist/safe-bash-zip-engine/zip/volumes.js +255 -0
  1017. package/dist/safe-bash-zip-engine/zip/zip64.d.ts +30 -0
  1018. package/dist/safe-bash-zip-engine/zip/zip64.js +25 -0
  1019. package/dist/safe-bash-zip-engine/zip-format.d.ts +68 -0
  1020. package/dist/safe-bash-zip-engine/zip-format.js +27 -0
  1021. package/dist/safe-playwright-cloudflare/browser-codegen.generated.d.ts +7 -7
  1022. package/dist/safe-playwright-cloudflare/browser-codegen.generated.js +866 -8069
  1023. package/dist/safe-playwright-cloudflare/browser-run-code-budget.d.ts +0 -1
  1024. package/dist/safe-playwright-cloudflare/browser-run-code-budget.js +0 -2
  1025. package/dist/safe-playwright-cloudflare/browser-trace-archive.d.ts +5 -1
  1026. package/dist/safe-playwright-cloudflare/browser-trace-archive.js +2 -1
  1027. package/dist/safe-playwright-cloudflare/browser-trace-budget.js +8 -4
  1028. package/dist/safe-playwright-cloudflare/shell-browser-resource.d.ts +2 -0
  1029. package/dist/safe-playwright-cloudflare/shell-browser-resource.js +3 -11
  1030. package/dist/safe-playwright-cloudflare/shell-playwright.d.ts +2 -0
  1031. package/dist/safe-playwright-cloudflare/shell-playwright.js +1 -1
  1032. package/dist/spreadsheet-engine/codecs/odf-hyperlinks.js +8 -2
  1033. package/dist/spreadsheet-engine/formulas/functions/captured-bessel-phase.js +2 -2
  1034. package/dist/spreadsheet-engine/formulas/label-references.js +54 -33
  1035. package/dist/spreadsheet-engine/formulas/parser.js +3 -1
  1036. package/dist/spreadsheet-engine/formulas/rewriting.js +13 -3
  1037. package/dist/spreadsheet-engine/io/publication.d.ts +1 -0
  1038. package/dist/spreadsheet-format-xls/biff-data-tables.js +4 -6
  1039. package/dist/spreadsheet-format-xls/biff-formulas.js +3 -0
  1040. package/dist/spreadsheet-format-xls/biff-label-ranges.js +9 -6
  1041. package/dist/spreadsheet-format-xls/biff.js +1 -1
  1042. package/dist/xlsx-ast/xlsx.js +8 -5
  1043. package/package.json +165 -15
  1044. package/dist/safe-bash/chunks/chunk-AZAJJVFX.js +0 -23017
  1045. package/dist/safe-bash/chunks/chunk-O4ZUCRGN.js +0 -13
  1046. package/dist/safe-bash/chunks/chunk-S264DZO2.js +0 -243
  1047. package/dist/safe-bash/chunks/chunk-WVG5SHHQ.js +0 -12
  1048. package/dist/safe-bash/chunks/chunk-ZW6K2J7P.js +0 -2652
  1049. package/dist/safe-bash/command-chunks/chunk-5MPOQ6V3.js +0 -181
  1050. package/dist/safe-bash/command-chunks/chunk-BIXLZ3OG.js +0 -14342
  1051. package/dist/safe-bash/command-chunks/chunk-DUYJE2HY.js +0 -14
  1052. package/dist/safe-bash/command-chunks/chunk-KAGBORIC.js +0 -88
  1053. package/dist/safe-bash/command-chunks/chunk-NETECMOF.js +0 -40
  1054. package/dist/safe-bash/command-chunks/chunk-XS3PGJU2.js +0 -343
  1055. package/dist/safe-bash/command-chunks/chunk-XTZALMLR.js +0 -488
  1056. package/dist/safe-bash/commands/archive/zip/aes-primitives-unavailable.d.ts +0 -2
  1057. package/dist/safe-bash/commands/archive/zip/aes-primitives-unavailable.js +0 -3
  1058. package/dist/safe-bash/commands/archive/zip/aes-primitives.d.ts +0 -2
  1059. package/dist/safe-bash/commands/archive/zip/aes-primitives.js +0 -3
  1060. package/dist/safe-bash/commands/xml/document.d.ts +0 -2
  1061. package/dist/safe-bash/commands/xml/document.js +0 -2
  1062. package/dist/safe-bash/commands/xml/evaluate.d.ts +0 -2
  1063. package/dist/safe-bash/commands/xml/evaluate.js +0 -2
  1064. package/dist/safe-bash/commands/xml/json.d.ts +0 -2
  1065. package/dist/safe-bash/commands/xml/json.js +0 -2
  1066. package/dist/safe-bash/commands/xml/limits.d.ts +0 -2
  1067. package/dist/safe-bash/commands/xml/limits.js +0 -2
  1068. package/dist/safe-bash/commands/xml/query.d.ts +0 -2
  1069. package/dist/safe-bash/commands/xml/query.js +0 -2
  1070. package/dist/safe-bash/command-chunks/{chunk-FIUFIDAO.js → chunk-2JRBIDAD.js} +3 -3
  1071. package/dist/safe-bash/command-chunks/{chunk-BWNXWI33.js → chunk-2LMZVE3I.js} +0 -0
  1072. package/dist/safe-bash/command-chunks/{chunk-B5BKA5WH.js → chunk-B5TAOCKD.js} +3 -3
  1073. package/dist/safe-bash/command-chunks/{chunk-2ENZ6JGA.js → chunk-KEV7C3KH.js} +3 -3
  1074. package/dist/safe-bash/command-chunks/{chunk-S62HELHU.js → chunk-PL6O4K6W.js} +3 -3
  1075. package/dist/safe-bash/command-chunks/{chunk-DDLQ5YDB.js → chunk-YHFXOX6U.js} +9 -9
  1076. package/dist/safe-bash/command-chunks/{chunk-DQMOM72Z.js → chunk-ZRRBXU3M.js} +4 -4
@@ -14,27 +14,6 @@ import { captureIgnoredTrapSignals } from "./trap.js";
14
14
  import { writeDiagnostic } from "../escaping.js";
15
15
  import { cancelTurn, hasYieldCheckpoint, inheritYieldCheckpoint, monotonicNow, registerInternalYieldCheckpoint, runYieldCheckpoint, scheduleTurn, yieldTurn } from "../contracts/yield.js";
16
16
  import { ACCESS_MODES, FsError, basename, composeMiddleware, createBytePipe, dirname, normalizePath, pipeBytes, resolvePath, validateExitCode, writeBytes, writeText, } from "../contracts/index.js";
17
- import { createBcCommands } from "../commands/bc/index.js";
18
- import { createStreamInspectionCommands } from "../commands/stream-inspection/index.js";
19
- import { createStreamFormatCommands } from "../commands/stream-format/index.js";
20
- import { createSpongeCommands } from "../commands/sponge/index.js";
21
- import { createFdCommands } from "../commands/fd/index.js";
22
- import { createLessCommands } from "../commands/less/index.js";
23
- import { createIdCommands } from "../commands/id/index.js";
24
- import { createWhoamiCommands } from "../commands/whoami/index.js";
25
- import { createUnameCommands } from "../commands/uname/index.js";
26
- import { createHostnameCommands } from "../commands/hostname/index.js";
27
- import { createNprocCommands } from "../commands/nproc/index.js";
28
- import { createShufCommands } from "../shuf.js";
29
- import { createDdCommands } from "../dd.js";
30
- import { createNumfmtCommands } from "../commands/numfmt/index.js";
31
- import { createEnvsubstCommands } from "../commands/envsubst/index.js";
32
- import { createCalCommands } from "../commands/cal/index.js";
33
- import { createPathchkCommands } from "../commands/pathchk/index.js";
34
- import { createGetconfCommands } from "../commands/getconf/index.js";
35
- import { createLocaleCommands } from "../commands/locale/index.js";
36
- import { createDfCommands } from "../commands/df/index.js";
37
- import { createSqlite3Commands } from "../commands/sqlite3/index.js";
38
17
  import { concatShellValues, shellValueByteLength, shellValueBytes, shellValueFromBytes, shellValueText } from "../contracts/value.js";
39
18
  import { createCommandArguments, getCommandArguments } from "../contracts/command.js";
40
19
  import { ValueArena, ValueScope } from "./value-state.js";
@@ -114,6 +93,7 @@ import { variablePresence } from "../commands/variable-presence.js";
114
93
  import { getArrayAssignment, getArraySelector, copyArraySelector, numericIndex, literalIndex, stringIndex, isQuoteMarker, prefixNameQuoteGroups, setArraySelector } from "./arrays/syntax.js";
115
94
  import { ArrayFailure, ArrayOwner, exactSum } from "./arrays/ledger.js";
116
95
  import { controlNames, IndexedBinding, textToken, valueToken } from "./arrays/bindings.js";
96
+ import { readDynamicVariable, writeDynamicVariable } from "./dynamic-variables.js";
117
97
  import { collectMapfile, mapfileOptions, MapfileUsageError } from "./mapfile.js";
118
98
  import { arrayStore, ensureStateMonitor, guestArrays, monitorSymbol, requireArrays, snapshotState, stateMonitor, trackState, trySnapshotStateSync } from "./arrays/state.js";
119
99
  import { pipelineStatusTarget, publishPipelineStatus } from "./pipestatus.js";
@@ -133,6 +113,7 @@ function hasActiveExtensions(state) {
133
113
  }
134
114
  const memberPatternOperators = ["#", "##", "%", "%%", "/", "//", "/#", "/%", "^", "^^", ",", ",,"];
135
115
  const defaultParameterOperators = ["-", "+", "=", "?", ":-", ":+", ":=", ":?"];
116
+ const printfSlowTargets = new Set([...controlNames, "FUNCNAME", "RANDOM", "SECONDS", "PIPESTATUS", "_"]);
136
117
  async function signedLong(argument, budget, signal) {
137
118
  const checkpoint = async () => {
138
119
  budget.cpuCheckpoint();
@@ -184,6 +165,7 @@ export const defaultLimits = {
184
165
  maxPipelineStages: Infinity,
185
166
  maxLoopIterations: Infinity,
186
167
  maxSubstitutionDepth: Infinity,
168
+ maxFunctionDepth: Infinity,
187
169
  maxSourceBytes: Infinity,
188
170
  maxExpansionFields: Infinity,
189
171
  maxExpansionBytes: Infinity,
@@ -824,8 +806,6 @@ Object.assign(Budget.prototype, {
824
806
  onInternalError: undefined, _yieldCheckpoint: undefined, _values: undefined, _executionScope: undefined, _pathLookup: undefined, _pathLookupSuspensions: 0, _executionCleanup: undefined, globstarEntries: 0, globstarStates: 0, _cleanupChargeFs: undefined, _wallClockTimer: undefined, _aborted: false, _cpuStarted: 0, _hasExternalSignal: false,
825
807
  });
826
808
  const EMPTY_CAPTURE_BYTES = new Uint8Array(0);
827
- const sharedCaptureStdoutScratch = new Uint8Array(65536);
828
- const sharedCaptureStderrScratch = new Uint8Array(65536);
829
809
  export class Capture {
830
810
  constructor(budget, signal) {
831
811
  this._chunks = undefined;
@@ -839,8 +819,8 @@ export class Capture {
839
819
  this.signal = signal;
840
820
  this.file = undefined;
841
821
  }
842
- enableScratchBuffer(isStderr = false) {
843
- this._scratch4k ??= isStderr ? sharedCaptureStderrScratch : sharedCaptureStdoutScratch;
822
+ enableScratchBuffer() {
823
+ this._scratch4k ??= new Uint8Array(65536);
844
824
  }
845
825
  get self() {
846
826
  return this;
@@ -2088,7 +2068,7 @@ async function cloneState(state, signal, scope, inheritLocals = true) {
2088
2068
  const token = await textToken(savedOwner, name, signal);
2089
2069
  const admission = savedOwner.reserve({ slots: 1, metadata: 32, work: 5 });
2090
2070
  binding = typed.binding?.retain();
2091
- typedSavedVariables.set(copied, { owner: savedOwner, binding, tickets, prepared: { name: token, admission }, watch, scalarLegacy: typed.scalarLegacy });
2071
+ typedSavedVariables.set(copied, { owner: savedOwner, binding, tickets, prepared: { ...typed.prepared, name: token, admission }, watch, scalarLegacy: typed.scalarLegacy });
2092
2072
  tickets.cleanup = () => {
2093
2073
  if (typedSavedVariables.delete(copied) && scope)
2094
2074
  releaseBinding = scope.cleanup(async () => { await binding?.release(); });
@@ -2204,6 +2184,7 @@ function publishVariable(state, name, value) {
2204
2184
  return;
2205
2185
  }
2206
2186
  state.variables[name] = shellValueText(value);
2187
+ writeDynamicVariable(state, name, shellValueText(value));
2207
2188
  }
2208
2189
  function tryRestoreVariableSync(state, name, saved) {
2209
2190
  if (typedSavedVariables.has(saved))
@@ -2989,11 +2970,6 @@ function hasGlobOrEscape(text, extglob = false) {
2989
2970
  return false;
2990
2971
  }
2991
2972
  let nextProcessSubstitutionId = 0;
2992
- let defaultRuntimeMuscleMemoryMap;
2993
- function getRuntimeMuscleMemoryCommand(name) {
2994
- defaultRuntimeMuscleMemoryMap ??= new Map([...createStreamFormatCommands(), ...createStreamInspectionCommands(), ...createBcCommands(), ...createSpongeCommands(), ...createFdCommands(), ...createLessCommands(), ...createIdCommands(), ...createWhoamiCommands(), ...createUnameCommands(), ...createHostnameCommands(), ...createNprocCommands(), ...createShufCommands(), ...createDdCommands(), ...createNumfmtCommands(), ...createEnvsubstCommands(), ...createCalCommands(), ...createPathchkCommands(), ...createGetconfCommands(), ...createLocaleCommands(), ...createDfCommands(), ...createSqlite3Commands()].map(cmd => [cmd.name, cmd]));
2995
- return defaultRuntimeMuscleMemoryMap.get(name);
2996
- }
2997
2973
  const fastSubScratchArgs = [];
2998
2974
  const defaultValueScopeReserve = ValueScope.prototype.reserve;
2999
2975
  const defaultStringCodePointAt = String.prototype.codePointAt;
@@ -3091,16 +3067,8 @@ const SYNC_UNIT_ZERO = Object.freeze({ exitCode: 0, terminated: false });
3091
3067
  const SYNC_UNIT_ONE = Object.freeze({ exitCode: 1, terminated: false });
3092
3068
  const EMPTY_BYTES = new Uint8Array(0);
3093
3069
  const SYNC_PIPE_DONE_RESULT = Object.freeze({ done: true, value: undefined });
3094
- const sharedSyncPipeBuf0 = new Uint8Array(65536);
3095
- const sharedSyncPipeBuf1 = new Uint8Array(65536);
3096
3070
  const sharedSyncPipeDecoder = new TextDecoder("utf-8", { ignoreBOM: true });
3097
3071
  let syncPurePipelineSlotInUse = false;
3098
- let lastPurePipeAst;
3099
- const lastPurePipeSrcRefs = new WeakSet();
3100
- let lastPurePipeSlice1 = "";
3101
- let lastPurePipeRegistry;
3102
- const lastPurePipeOutBuf = new Uint8Array(256);
3103
- let lastPurePipeOutLen = 0;
3104
3072
  function isSimpleAsciiGrepPattern(pat) {
3105
3073
  const start = pat.length >= 2 && pat.charCodeAt(0) === 94 ? 1 : 0;
3106
3074
  if (start >= pat.length)
@@ -3541,6 +3509,10 @@ function resolveSimpleArithOperand(tok, rawState, monitor, activeArrayStore, syn
3541
3509
  return Number(elemVal);
3542
3510
  }
3543
3511
  tok = resolveSyncNameref(rawState, tok);
3512
+ // These values come from execution context or lazy shell bindings, not raw variables.
3513
+ // Decline after resolving namerefs so aliases use the same full evaluator.
3514
+ if (tok === "LINENO" || tok === "_" || tok === "FUNCNAME" || tok === "PIPESTATUS")
3515
+ return undefined;
3544
3516
  if (rawState.nounset || activeArrayStore?.bindings.has(tok) || monitor?.hasOverlay(tok) || activeArrayStore?.watches.has(tok))
3545
3517
  return undefined;
3546
3518
  const raw = rawState.variables[tok];
@@ -3737,6 +3709,7 @@ export class Runtime {
3737
3709
  _syncPendingEvalResume;
3738
3710
  _syncReadOnlyArithRefs;
3739
3711
  _activeSyncLoopAssignedVars;
3712
+ _activeSyncArrayLoopWords;
3740
3713
  _activeSyncLoopHasFileMutations = false;
3741
3714
  _inSyncLoopPreflight = false;
3742
3715
  _activeSyncLoopIO;
@@ -4500,6 +4473,10 @@ export class Runtime {
4500
4473
  if (state.readonlyVariables?.has(name))
4501
4474
  throw new PublicDiagnostic(`${name}: readonly variable`);
4502
4475
  delete state.variables[name];
4476
+ if (name === "RANDOM")
4477
+ state.randomDisabled = true;
4478
+ if (name === "SECONDS")
4479
+ state.secondsDisabled = true;
4503
4480
  state.exported.delete(name);
4504
4481
  state.variableAttributes?.delete(name);
4505
4482
  if (name === "OPTIND" && !internal)
@@ -4543,16 +4520,18 @@ export class Runtime {
4543
4520
  const rawSub = this._syncArithRawVars[subVar];
4544
4521
  if (typeof rawSub !== "string" || rawSub.length === 0)
4545
4522
  throw new ArrayFailure("empty var subscript in sync arithmetic");
4546
- resolvedSub = shellValueText(stateMonitor(st)?.values.get(subVar, rawSub) ?? rawSub);
4523
+ resolvedSub = this._syncArithRawWriteOnly && this._syncArithTouched?.has(subVar)
4524
+ ? rawSub
4525
+ : shellValueText(stateMonitor(st)?.values.get(subVar, rawSub) ?? rawSub);
4547
4526
  }
4548
4527
  else if (/^[a-zA-Z_][a-zA-Z_0-9]*$/.test(resolvedSub)) {
4549
4528
  const st = this._syncArithState;
4550
4529
  const binding = arrayStore(st)?.get(variable);
4551
4530
  if (!binding || !binding.associative) {
4552
- if (st.nounset || arrayStore(st)?.get(resolvedSub) || stateMonitor(st)?.hasOverlay(resolvedSub))
4531
+ const index = resolveSimpleArithOperand(resolvedSub, st, stateMonitor(st), arrayStore(st), this._syncArithRawWriteOnly ? this._syncArithTouched : undefined);
4532
+ if (index === undefined)
4553
4533
  throw new ArrayFailure("complex indexed ident subscript in sync arithmetic");
4554
- const rawSub = this._syncArithRawVars[resolvedSub];
4555
- resolvedSub = rawSub === undefined || rawSub === "" ? "0" : shellValueText(stateMonitor(st)?.values.get(resolvedSub, rawSub) ?? rawSub);
4534
+ resolvedSub = String(index);
4556
4535
  }
4557
4536
  }
4558
4537
  else {
@@ -4724,7 +4703,7 @@ export class Runtime {
4724
4703
  case "literal": return true;
4725
4704
  case "name": {
4726
4705
  const effName = resolveSyncNameref(state, tree.name);
4727
- if (effName === "OPTIND" || effName === "PIPESTATUS")
4706
+ if (effName === "OPTIND" || effName === "PIPESTATUS" || effName === "RANDOM" || effName === "SECONDS")
4728
4707
  return false;
4729
4708
  const monitor = stateMonitor(state);
4730
4709
  if (monitor?.hasOverlay(effName) || monitor?.store?.watches.has(effName))
@@ -4823,6 +4802,8 @@ export class Runtime {
4823
4802
  return true;
4824
4803
  }
4825
4804
  tryBuildSyncPatternWord(word, rawState, io, diagnosticLine) {
4805
+ if (word.plain !== undefined)
4806
+ return word.plain.startsWith("~") ? undefined : word.plain;
4826
4807
  if (word.parts.length === 0)
4827
4808
  return undefined;
4828
4809
  let out = "";
@@ -5008,7 +4989,7 @@ export class Runtime {
5008
4989
  const name = typeof key === "string" ? this.referenceName(state, key) : key;
5009
4990
  if (arrayStore(state)?.get(String(name)))
5010
4991
  throw new ArrayFailure("indexed arithmetic is unsupported");
5011
- const value = Reflect.get(target, name)
4992
+ const value = (typeof name === "string" && (name === "RANDOM" || name === "SECONDS") ? this.variable(state, name) : Reflect.get(target, name))
5012
4993
  ?? (name === "LINENO" ? String(line ?? 1)
5013
4994
  : name === "_" ? state.lastArgument ?? ""
5014
4995
  : name === "FUNCNAME" ? state.functionNames?.[0]
@@ -5057,11 +5038,15 @@ export class Runtime {
5057
5038
  }
5058
5039
  variable(state, name) {
5059
5040
  name = this.referenceName(state, name);
5041
+ if (name === "RANDOM" || name === "SECONDS")
5042
+ return readDynamicVariable(stateMonitor(state)?.raw ?? state, name) ?? state.variables[name];
5060
5043
  const binding = arrayStore(state)?.get(name);
5061
5044
  if (binding)
5062
5045
  return binding.get(binding.associative ? binding.keys.get("30")?.index ?? -1 : 0);
5063
5046
  if (name === "DIRSTACK")
5064
5047
  return state.cwd;
5048
+ if (name === "BASH_SUBSHELL")
5049
+ return state.variables.BASH_SUBSHELL ?? "0";
5065
5050
  if (name === "FUNCNAME" && state.variables.FUNCNAME === undefined)
5066
5051
  return state.functionNames?.[0];
5067
5052
  if (name === "_" && state.variables._ === undefined)
@@ -5193,7 +5178,7 @@ export class Runtime {
5193
5178
  if (!watch.valid())
5194
5179
  throw new ArrayFailure("stale binding");
5195
5180
  binding = scalarLegacy ? undefined : store.get(name)?.retain();
5196
- typedSavedVariables.set(saved, { owner, binding, tickets, prepared: { name: token, admission }, watch, scalarLegacy });
5181
+ typedSavedVariables.set(saved, { owner, binding, tickets, prepared: { name: token, admission, identity: store.bindings.get(name)?.identity }, watch, scalarLegacy });
5197
5182
  tickets.cleanup = () => { typedSavedVariables.delete(saved); };
5198
5183
  }
5199
5184
  catch (error) {
@@ -5889,6 +5874,22 @@ export class Runtime {
5889
5874
  }
5890
5875
  return p0.operator !== undefined ? this.applySyncArrayMemberOperator(out, p0, rawState) : out;
5891
5876
  }
5877
+ syncArraySubscriptWord(index, state) {
5878
+ if (byteLocale(state.variables) || state.depth >= 24)
5879
+ return undefined;
5880
+ const cached = index;
5881
+ const word = index.word ?? (cached._cachedSyntax === state.extensions?.syntax ? cached._cachedWord : undefined);
5882
+ if (word)
5883
+ return word;
5884
+ try {
5885
+ cached._cachedWord = parseArraySubscript(index.source ?? index.decimal, this.budget.parsing, false, state.depth, false, state.extensions?.syntax);
5886
+ cached._cachedSyntax = state.extensions?.syntax;
5887
+ return cached._cachedWord;
5888
+ }
5889
+ catch {
5890
+ return undefined;
5891
+ }
5892
+ }
5892
5893
  tryFastArrayAssignmentSync(assignment, state, io, diagnosticLine, declaration, associative, ignoreYield = false) {
5893
5894
  if (!ignoreYield && hasYieldCheckpoint(this.signal))
5894
5895
  return false;
@@ -5962,7 +5963,10 @@ export class Runtime {
5962
5963
  try {
5963
5964
  val = this.fastValueWord(entry.value, rawState, io, false, false, false, false, entry.index === undefined ? undefined : 0, diagnosticLine);
5964
5965
  }
5965
- catch {
5966
+ catch (error) {
5967
+ this.signal.throwIfAborted();
5968
+ if (error instanceof ShellLimitError)
5969
+ throw error;
5966
5970
  return false;
5967
5971
  }
5968
5972
  }
@@ -6052,7 +6056,10 @@ export class Runtime {
6052
6056
  try {
6053
6057
  unsplit = this.fastValueWord(entry.value, rawState, io, false, false, false, false, undefined, diagnosticLine);
6054
6058
  }
6055
- catch {
6059
+ catch (error) {
6060
+ this.signal.throwIfAborted();
6061
+ if (error instanceof ShellLimitError)
6062
+ throw error;
6056
6063
  return false;
6057
6064
  }
6058
6065
  if (typeof unsplit !== "string" || hasGlobOrEscape(unsplit, !!rawState.extglob))
@@ -6078,7 +6085,10 @@ export class Runtime {
6078
6085
  try {
6079
6086
  val = this.fastValueWord(entry.value, rawState, io, false, false, false, false, entry.index === undefined ? undefined : 0, diagnosticLine);
6080
6087
  }
6081
- catch {
6088
+ catch (error) {
6089
+ this.signal.throwIfAborted();
6090
+ if (error instanceof ShellLimitError)
6091
+ throw error;
6082
6092
  return false;
6083
6093
  }
6084
6094
  }
@@ -6174,7 +6184,10 @@ export class Runtime {
6174
6184
  try {
6175
6185
  val = this.fastValueWord(assignment.value, rawState, io, false, false, false, false, 0, diagnosticLine);
6176
6186
  }
6177
- catch {
6187
+ catch (error) {
6188
+ this.signal.throwIfAborted();
6189
+ if (error instanceof ShellLimitError)
6190
+ throw error;
6178
6191
  return false;
6179
6192
  }
6180
6193
  if (typeof val !== "string")
@@ -6198,20 +6211,9 @@ export class Runtime {
6198
6211
  return false;
6199
6212
  }
6200
6213
  if (assignment.kind === "element" && current?.associative) {
6201
- const cachedIdx = assignment.index;
6202
- let word = assignment.index.word ?? (cachedIdx._cachedSyntax === rawState.extensions?.syntax ? cachedIdx._cachedWord : undefined);
6203
- if (!word) {
6204
- if (byteLocale(rawState.variables) || rawState.depth >= 24)
6205
- return false;
6206
- try {
6207
- word = parseArraySubscript(assignment.index.source ?? assignment.index.decimal, this.budget.parsing, false, rawState.depth, false, rawState.extensions?.syntax);
6208
- cachedIdx._cachedWord = word;
6209
- cachedIdx._cachedSyntax = rawState.extensions?.syntax;
6210
- }
6211
- catch {
6212
- return false;
6213
- }
6214
- }
6214
+ const word = this.syncArraySubscriptWord(assignment.index, rawState);
6215
+ if (!word)
6216
+ return false;
6215
6217
  let keyVal;
6216
6218
  let val;
6217
6219
  try {
@@ -6220,7 +6222,10 @@ export class Runtime {
6220
6222
  return false;
6221
6223
  val = this.fastValueWord(assignment.value, rawState, io, false, false, false, false, 0, diagnosticLine);
6222
6224
  }
6223
- catch {
6225
+ catch (error) {
6226
+ this.signal.throwIfAborted();
6227
+ if (error instanceof ShellLimitError)
6228
+ throw error;
6224
6229
  return false;
6225
6230
  }
6226
6231
  if (typeof val !== "string")
@@ -6338,12 +6343,11 @@ export class Runtime {
6338
6343
  const holding = store.owner.hold();
6339
6344
  let staged;
6340
6345
  try {
6341
- const watch = await store.watch(name, operation, this.signal);
6342
- const current = store.get(name);
6346
+ let current = store.get(name);
6343
6347
  if (associative !== undefined && current && current.associative !== associative)
6344
6348
  throw new ArrayFailure("cannot convert array kind");
6345
6349
  const isAssociative = associative ?? current?.associative;
6346
- const initialMaximum = current?.maximum ?? (state.variables[name] === undefined ? -1 : 0);
6350
+ let initialMaximum = current?.maximum ?? (state.variables[name] === undefined ? -1 : 0);
6347
6351
  let selectedIndex;
6348
6352
  let planned = assignment.append && assignment.kind === "compound" ? initialMaximum + 1 : 0;
6349
6353
  if (assignment.kind === "element") {
@@ -6376,6 +6380,37 @@ export class Runtime {
6376
6380
  }
6377
6381
  await operation.ledger.checkpoint(this.signal, entry.value.parts.length + 2);
6378
6382
  }
6383
+ // Word expansion can mutate this binding. Finish it before taking the
6384
+ // publication snapshot, and choose the append cursor from the new maximum.
6385
+ const expandedEntries = [];
6386
+ let elementFields;
6387
+ if (assignment.kind === "element") {
6388
+ elementFields = await this.valueWord(assignment.value, state, io, false, false, false, false, undefined, false, false, 0);
6389
+ }
6390
+ else
6391
+ for (const entry of assignment.entries) {
6392
+ const original = compoundEntryWords.get(entry);
6393
+ let expandedEntry = false;
6394
+ if (entry.index && original && state.braceexpand !== false && original.parts.some(part => part.kind === "text" && !part.quoted && part.value.includes("{"))) {
6395
+ for await (const expanded of expandBraces(original, this.budget, this.signal)) {
6396
+ if (expanded === original)
6397
+ break;
6398
+ expandedEntry = true;
6399
+ const fields = await this.valueWord(expanded, state, io, true, false, false, false, undefined, false, false);
6400
+ operation.reserve({ metadata: 32, slots: 1, work: 1 });
6401
+ expandedEntries.push({ entry: { value: expanded }, fields });
6402
+ }
6403
+ }
6404
+ if (expandedEntry)
6405
+ continue;
6406
+ const fields = await this.valueWord(entry.value, state, io, entry.index === undefined, false, false, false, undefined, false, entry.index === undefined, entry.index === undefined ? undefined : 0);
6407
+ operation.reserve({ metadata: 32, slots: 1, work: 1 });
6408
+ expandedEntries.push({ entry, fields });
6409
+ }
6410
+ current = store.get(name);
6411
+ initialMaximum = current?.maximum ?? (state.variables[name] === undefined ? -1 : 0);
6412
+ this.assertArrayWritable(state, name, origin);
6413
+ const watch = await store.watch(name, operation, this.signal);
6379
6414
  const supersede = await stateMonitor(state).prepareTypedPublication(name, operation, this.signal);
6380
6415
  await this.prepareArrayObservers(state, operation);
6381
6416
  const tickets = operation.reserve({ generation: true, version: true, epoch: true, work: 8 });
@@ -6464,7 +6499,7 @@ export class Runtime {
6464
6499
  }
6465
6500
  else
6466
6501
  index = (await this.arrayIndex(targetBinding, assignment.index, state, io, operation, true));
6467
- const value = await join(await this.valueWord(assignment.value, state, io, false, false, false, false, undefined, false, false, 0));
6502
+ const value = await join(elementFields);
6468
6503
  // Expansion can initialize the unset target as a scalar. Preserve that
6469
6504
  // value when promoting it to an indexed binding.
6470
6505
  if (!current && state.variables[name] !== undefined && (index !== 0 || assignment.append)) {
@@ -6481,25 +6516,8 @@ export class Runtime {
6481
6516
  await insert(index, value, assignment.append);
6482
6517
  }
6483
6518
  else
6484
- for (const entry of assignment.entries) {
6485
- const original = compoundEntryWords.get(entry);
6486
- if (entry.index && original && state.braceexpand !== false && original.parts.some(part => part.kind === "text" && !part.quoted && part.value.includes("{"))) {
6487
- let expandedEntry = false;
6488
- for await (const expanded of expandBraces(original, this.budget, this.signal)) {
6489
- if (expanded === original)
6490
- break;
6491
- expandedEntry = true;
6492
- const values = await this.valueWord(expanded, state, io, true, false, false, false, undefined, false, false);
6493
- for (const value of values) {
6494
- await insert(cursor, value);
6495
- cursor++;
6496
- }
6497
- }
6498
- if (expandedEntry)
6499
- continue;
6500
- }
6519
+ for (const { entry, fields } of expandedEntries) {
6501
6520
  const index = entry.index ? (await this.arrayIndex(targetBinding, entry.index, state, io, operation, true)) : undefined;
6502
- const fields = await this.valueWord(entry.value, state, io, entry.index === undefined, false, false, false, undefined, false, entry.index === undefined, entry.index === undefined ? undefined : 0);
6503
6521
  if (index !== undefined) {
6504
6522
  const value = await join(fields);
6505
6523
  await insert(index, value, entry.append);
@@ -6977,7 +6995,7 @@ export class Runtime {
6977
6995
  if (closed)
6978
6996
  throw new ArrayFailure("indexed writer is closed");
6979
6997
  owner.assertOpen();
6980
- if (arrayStore(state) !== store || store.owner !== owner || identity !== undefined && store.bindings.get(name) !== identity)
6998
+ if (arrayStore(state) !== store || store.owner !== owner || identity !== undefined && store.bindings.get(name)?.identity !== identity)
6981
6999
  throw new ArrayFailure("incremental target identity changed");
6982
7000
  if (localIdentity() !== admittedLocal)
6983
7001
  throw new ArrayFailure("incremental target local identity changed");
@@ -7032,8 +7050,8 @@ export class Runtime {
7032
7050
  await prepared.close();
7033
7051
  }
7034
7052
  }
7035
- identity = store.bindings.get(name);
7036
- if (!identity)
7053
+ identity = store.bindings.get(name)?.identity;
7054
+ if (identity === undefined)
7037
7055
  throw new ArrayFailure("incremental target is not indexed");
7038
7056
  validate();
7039
7057
  }
@@ -8042,7 +8060,7 @@ export class Runtime {
8042
8060
  const diagnosticLine = io.diagnosticCommandLines?.get(command) ?? (command.line ?? 1) + (io.diagnosticOffset ?? 0);
8043
8061
  if (cSingle !== undefined && !customRegisteredRegistries.has(this.commands) && !hasShellFunction(rawState, cSingle.w0Plain) && !rawState.extensions?.builtins.has(cSingle.w0Plain) && command.words.length <= this.budget.maxExpansionFieldsSmi && (this.budget.commands + 1 <= this.budget.maxCommandsSmi || this.budget.commands + 1 <= this.budget.limits.maxCommands)) {
8044
8062
  w0Plain = cSingle.w0Plain;
8045
- const extD = this.getExternalCommand(w0Plain);
8063
+ const extD = this.commands.get(w0Plain);
8046
8064
  if (!extD || !builtInDirectContextExecutors.has(extD.execute) || customRegisteredCommands.has(extD.execute))
8047
8065
  return undefined;
8048
8066
  externalDef = extD;
@@ -8063,7 +8081,7 @@ export class Runtime {
8063
8081
  return undefined;
8064
8082
  }
8065
8083
  w0Plain = w0P;
8066
- const extD = this.getExternalCommand(w0Plain);
8084
+ const extD = this.commands.get(w0Plain);
8067
8085
  if (!extD || !builtInDirectContextExecutors.has(extD.execute) || customRegisteredCommands.has(extD.execute) || customRegisteredRegistries.has(this.commands) || command.words.length > this.budget.maxExpansionFieldsSmi || (this.budget.commands + 1 > this.budget.maxCommandsSmi && this.budget.commands + 1 > this.budget.limits.maxCommands)) {
8068
8086
  return undefined;
8069
8087
  }
@@ -8115,14 +8133,12 @@ export class Runtime {
8115
8133
  let redirectSink;
8116
8134
  if (command.redirects.length === 1) {
8117
8135
  const r0 = command.redirects[0];
8118
- let targetVal = r0.target.plain;
8119
- if (targetVal === undefined) {
8120
- try {
8121
- targetVal = this.fastValueWord(r0.target, rawState, io, true, false, false, true, undefined, diagnosticLine);
8122
- }
8123
- catch {
8124
- return undefined;
8125
- }
8136
+ let targetVal;
8137
+ try {
8138
+ targetVal = this.fastValueWord(r0.target, rawState, io, true, false, false, true, undefined, diagnosticLine);
8139
+ }
8140
+ catch {
8141
+ return undefined;
8126
8142
  }
8127
8143
  if (typeof targetVal !== "string" || !targetVal || targetVal.includes("\0"))
8128
8144
  return undefined;
@@ -8192,26 +8208,6 @@ export class Runtime {
8192
8208
  const n = pipeline.commands.length;
8193
8209
  if ((this.budget.commands + n > this.budget.maxCommandsSmi && this.budget.commands + n > this.budget.limits.maxCommands))
8194
8210
  return undefined;
8195
- if (pipeline === lastPurePipeAst && !syncPurePipelineSlotInUse && this._isMemoryBackingFs && this.backingFs && this.backingFs.capabilitiesFor === undefined && this.commands === lastPurePipeRegistry && (!rawState.functions || rawState.functions.size === 0) && !rawState.extensions?.builtins.size && io.stdinIsDefault && !this.signal.aborted && !hasYieldCheckpoint(this.signal) && this.budget.canSyncPurePipe && Date.now === defaultDateNow && io.stdout instanceof Capture && io.stdout._scratch4k !== undefined && io.stdout.length === 0 && io.stdout.write === Capture.prototype.write && io.stderr instanceof Capture && io.stderr.length === 0 && io.stderr.write === Capture.prototype.write) {
8196
- const rootEntry = this.backingFs.root?.entries?.get(lastPurePipeSlice1);
8197
- if (rootEntry && rootEntry.type === "file" && rootEntry.revision === 0 && rootEntry.mode !== undefined && ((rootEntry.mode >> 6) & 4) === 4 && rootEntry.sourceRef && lastPurePipeSrcRefs.has(rootEntry.sourceRef)) {
8198
- this.budget.enterPipelineStages(n);
8199
- this.budget.commands += n;
8200
- try {
8201
- this.budget.fileSystemOperation();
8202
- io.stdout.writeRangeSync(lastPurePipeOutBuf, lastPurePipeOutLen);
8203
- }
8204
- finally {
8205
- this.budget.leavePipelineStages(n);
8206
- }
8207
- const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
8208
- monitor.lazyPipeStatus = ZERO_PIPE_STATUSES[n];
8209
- monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
8210
- rawState.status = 0;
8211
- monitor.epoch = restEpoch;
8212
- return SYNC_UNIT_ZERO;
8213
- }
8214
- }
8215
8211
  for (let i = 0; i < n; i++) {
8216
8212
  const cmd = pipeline.commands[i];
8217
8213
  if (cmd.kind !== "simple" || !this.isPureExternalStageCommand(cmd, rawState) || cmd.words.length > this.budget.maxExpansionFieldsSmi)
@@ -8339,11 +8335,10 @@ export class Runtime {
8339
8335
  return undefined;
8340
8336
  }
8341
8337
  const n = pipeline.commands.length;
8342
- let firstStageRootSourceRef;
8343
8338
  for (let i = 0; i < n; i++) {
8344
8339
  const cmd = pipeline.commands[i];
8345
8340
  const name = cmd.words[0].plain;
8346
- const extDef = this.getExternalCommand(name);
8341
+ const extDef = this.commands.get(name);
8347
8342
  if (!extDef || !builtInDirectContextExecutors.has(extDef.execute) || customRegisteredCommands.has(extDef.execute)) {
8348
8343
  return undefined;
8349
8344
  }
@@ -8371,8 +8366,6 @@ export class Runtime {
8371
8366
  const rootEntry = backing.root?.entries?.get(slice1);
8372
8367
  if (!rootEntry || rootEntry.type !== "file" || (rootEntry.data && rootEntry.data.byteLength > 65536))
8373
8368
  return undefined;
8374
- if (rootEntry.revision === 0 && rootEntry.mode !== undefined && ((rootEntry.mode >> 6) & 4) === 4 && rootEntry.data && rootEntry.data.byteLength >= 1024)
8375
- firstStageRootSourceRef = rootEntry.sourceRef;
8376
8369
  }
8377
8370
  }
8378
8371
  else if (name === "find") {
@@ -8420,23 +8413,8 @@ export class Runtime {
8420
8413
  return undefined;
8421
8414
  }
8422
8415
  }
8423
- if (n >= 3 && pipeline === lastPurePipeAst && firstStageRootSourceRef !== undefined && lastPurePipeSrcRefs.has(firstStageRootSourceRef) && Date.now === defaultDateNow) {
8424
- this.budget.enterPipelineStages(n);
8425
- this.budget.commands += n;
8426
- try {
8427
- this.budget.fileSystemOperation();
8428
- io.stdout.writeRangeSync(lastPurePipeOutBuf, lastPurePipeOutLen);
8429
- }
8430
- finally {
8431
- this.budget.leavePipelineStages(n);
8432
- }
8433
- const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
8434
- monitor.lazyPipeStatus = ZERO_PIPE_STATUSES[n] ?? new Array(n).fill(0);
8435
- monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
8436
- rawState.status = 0;
8437
- monitor.epoch = restEpoch;
8438
- return SYNC_UNIT_ZERO;
8439
- }
8416
+ const sharedSyncPipeBuf0 = new Uint8Array(65536);
8417
+ const sharedSyncPipeBuf1 = new Uint8Array(65536);
8440
8418
  syncPurePipelineSlotInUse = true;
8441
8419
  this.budget.enterPipelineStages(n);
8442
8420
  this.budget.commands += n;
@@ -8447,7 +8425,7 @@ export class Runtime {
8447
8425
  for (let index = start; index < n; index++) {
8448
8426
  const cmd = pipeline.commands[index];
8449
8427
  const firstName = cmd.words[0].plain;
8450
- const extDef = this.getExternalCommand(firstName);
8428
+ const extDef = this.commands.get(firstName);
8451
8429
  const stageArgs = cmd._cachedPlainArgs;
8452
8430
  const isFirst = index === 0;
8453
8431
  const isLast = index === n - 1;
@@ -8518,22 +8496,7 @@ export class Runtime {
8518
8496
  syncPurePipelineSlotInUse = false;
8519
8497
  this.budget.leavePipelineStages(n);
8520
8498
  };
8521
- const stdout = io.stdout;
8522
- const stderr = io.stderr;
8523
8499
  const finish = () => {
8524
- if (n >= 3 && !pipeline.negate && statuses === undefined && firstStageRootSourceRef !== undefined && stderr.length === 0 && stdout.length <= 256 && Date.now === defaultDateNow) {
8525
- const scratch = stdout._scratch4k;
8526
- if (scratch) {
8527
- const outLen = stdout.length;
8528
- for (let bi = 0; bi < outLen; bi++)
8529
- lastPurePipeOutBuf[bi] = scratch[bi];
8530
- lastPurePipeOutLen = outLen;
8531
- lastPurePipeAst = pipeline;
8532
- lastPurePipeSlice1 = (pipeline.commands[0]._cachedSlice1) ?? "";
8533
- lastPurePipeRegistry = this.commands;
8534
- lastPurePipeSrcRefs.add(firstStageRootSourceRef);
8535
- }
8536
- }
8537
8500
  const restEpoch = monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets).epoch;
8538
8501
  const finalStatuses = statuses ?? ZERO_PIPE_STATUSES[n] ?? new Array(n).fill(0);
8539
8502
  monitor.lazyPipeStatus = finalStatuses;
@@ -8595,7 +8558,7 @@ export class Runtime {
8595
8558
  for (let index = 0; index < n; index++) {
8596
8559
  const cmd = pipeline.commands[index];
8597
8560
  const firstName = cmd.words[0].plain;
8598
- const extDef = this.getExternalCommand(firstName);
8561
+ const extDef = this.commands.get(firstName);
8599
8562
  let stageArgs = cmd._cachedPlainArgs;
8600
8563
  if (!stageArgs) {
8601
8564
  stageArgs = new Array(cmd.words.length - 1);
@@ -9342,7 +9305,7 @@ export class Runtime {
9342
9305
  targetOk = true;
9343
9306
  }
9344
9307
  }
9345
- else if (isShellIdentifier(w2Plain) && !controlNames.has(w2Plain) && !rawState.readonlyVariables?.has(w2Plain) && !rawState.variableAttributes?.get(w2Plain) && !st?.get(w2Plain) && !mon.hasOverlay(w2Plain)) {
9308
+ else if (isShellIdentifier(w2Plain) && !printfSlowTargets.has(w2Plain) && !rawState.readonlyVariables?.has(w2Plain) && !rawState.variableAttributes?.get(w2Plain) && !st?.get(w2Plain) && !mon.hasOverlay(w2Plain)) {
9346
9309
  targetOk = true;
9347
9310
  }
9348
9311
  }
@@ -9899,7 +9862,7 @@ export class Runtime {
9899
9862
  // Loops and pure substitutions cannot replay after an unsupported result.
9900
9863
  // These operators depend on arithmetic, filesystem or collation state that
9901
9864
  // the speculative synchronous evaluator does not fully support.
9902
- if (requireTotal && ((expr.kind === "unary" && syncConditionalFileUnaryOps.has(expr.operator)) ||
9865
+ if (requireTotal && ((expr.kind === "unary" && (expr.operator === "-v" || syncConditionalFileUnaryOps.has(expr.operator))) ||
9903
9866
  (expr.kind === "binary" && expr.operator !== "==" && expr.operator !== "=" && expr.operator !== "!=" && expr.operator !== "=~")))
9904
9867
  return false;
9905
9868
  const okWord = (w) => !Runtime.wordMayMutate(w) || (rawState !== undefined && this.isPureSyncValueWord(w, rawState));
@@ -10502,7 +10465,7 @@ export class Runtime {
10502
10465
  const rhsOp = scalarMutMatch[4];
10503
10466
  const rhs2 = scalarMutMatch[5] !== undefined ? Number(scalarMutMatch[5]) : 0;
10504
10467
  const rhsNum = rhsOp === "+" ? rhs1 + rhs2 : rhsOp === "-" ? rhs1 - rhs2 : rhsOp === "*" ? rhs1 * rhs2 : rhs1;
10505
- if (varName !== "OPTIND" && varName !== "PIPESTATUS" && !store?.get(varName) && !hasNonNamerefAttributes(rawState)) {
10468
+ if (!controlNames.has(varName) && varName !== "PIPESTATUS" && !store?.get(varName) && !hasNonNamerefAttributes(rawState)) {
10506
10469
  const curVal = (this._syncArithRawWriteOnly && this._syncArithTouched?.has(varName))
10507
10470
  ? (rawState.variables[varName] ?? "0")
10508
10471
  : (monitor.values.get(varName, rawState.variables[varName] ?? "0") ?? rawState.variables[varName] ?? "0");
@@ -10771,7 +10734,7 @@ export class Runtime {
10771
10734
  const clause = command.clauses[cIdx];
10772
10735
  for (let pIdx = 0; pIdx < clause.patterns.length; pIdx++) {
10773
10736
  const pw = clause.patterns[pIdx];
10774
- const pStr = pw.plain ?? this.tryBuildSyncPatternWord(pw, rawState, io, diagnosticLine);
10737
+ const pStr = this.tryBuildSyncPatternWord(pw, rawState, io, diagnosticLine);
10775
10738
  if (pStr === undefined)
10776
10739
  return undefined;
10777
10740
  const matched = tryMatchesPatternSync(pStr, fastSubject, work, false, false);
@@ -11260,7 +11223,7 @@ export class Runtime {
11260
11223
  const isSubTarget = openBr > 0 && targetSpec.endsWith("]") && targetSpec.length > openBr + 2;
11261
11224
  const rawTargetVar = isSubTarget ? targetSpec.slice(0, openBr) : targetSpec;
11262
11225
  const targetVar = isShellIdentifier(rawTargetVar) ? resolveSyncNameref(rawState, rawTargetVar) : "";
11263
- if (targetVar && isShellIdentifier(targetVar) && targetVar !== "OPTIND" && targetVar !== "PIPESTATUS" && targetVar !== "_" && !rawState.readonlyVariables?.has(targetVar) && !rawState.variableAttributes?.get(targetVar) && !monitor.hasOverlay(targetVar) && (isSubTarget ? Boolean(store?.get(targetVar)) : !store?.get(targetVar))) {
11226
+ if (targetVar && isShellIdentifier(targetVar) && !printfSlowTargets.has(targetVar) && !rawState.readonlyVariables?.has(targetVar) && !rawState.variableAttributes?.get(targetVar) && !monitor.hasOverlay(targetVar) && (isSubTarget ? Boolean(store?.get(targetVar)) : !store?.get(targetVar))) {
11264
11227
  fastSubScratchArgs.length = 0;
11265
11228
  let allStrings = true;
11266
11229
  try {
@@ -12151,6 +12114,7 @@ export class Runtime {
12151
12114
  let simpleRead = true;
12152
12115
  let readDelim = 10;
12153
12116
  let arrayTarget;
12117
+ let readLastArgument = command.words[command.words.length - 1].plain;
12154
12118
  while (readWordIdx < command.words.length) {
12155
12119
  const p = command.words[readWordIdx].plain;
12156
12120
  if (p === undefined) {
@@ -12184,6 +12148,8 @@ export class Runtime {
12184
12148
  delimStr = undefined;
12185
12149
  }
12186
12150
  }
12151
+ if (readWordIdx === command.words.length - 1)
12152
+ readLastArgument = delimStr;
12187
12153
  }
12188
12154
  if (delimStr !== undefined && delimStr.length >= 1 && delimStr.charCodeAt(0) > 0 && delimStr.charCodeAt(0) < 128) {
12189
12155
  readDelim = delimStr.charCodeAt(0);
@@ -12449,7 +12415,7 @@ export class Runtime {
12449
12415
  rawState.substitutionStatus = 0;
12450
12416
  if (rawState.variables._ !== undefined)
12451
12417
  delete rawState.variables._;
12452
- rawState.lastArgument = command.words[command.words.length - 1].plain;
12418
+ rawState.lastArgument = readLastArgument;
12453
12419
  if (io.assignmentDiagnosticContext)
12454
12420
  io.assignmentDiagnosticContext.name = undefined;
12455
12421
  if (!existing) {
@@ -12530,7 +12496,7 @@ export class Runtime {
12530
12496
  allArrOk = false;
12531
12497
  break;
12532
12498
  }
12533
- else if (rawState.locals.length === 0 && isShellIdentifier(tExpanded) && !tExpanded.startsWith("-") && !rawState.readonlyVariables?.has(tExpanded) && !arrStore.get(tExpanded) && !rawState.functions.has(tExpanded) && !monitor.hasOverlay(tExpanded) && tExpanded !== "OPTIND" && tExpanded !== "PIPESTATUS" && tExpanded !== "_" && tExpanded !== "IFS" && tExpanded !== "PATH") {
12499
+ else if (rawState.locals.length === 0 && isShellIdentifier(tExpanded) && !tExpanded.startsWith("-") && !rawState.readonlyVariables?.has(tExpanded) && !arrStore.get(tExpanded) && !rawState.functions.has(tExpanded) && !monitor.hasOverlay(tExpanded) && !controlNames.has(tExpanded) && tExpanded !== "PIPESTATUS" && tExpanded !== "_") {
12534
12500
  ops.push({ kind: "scalar", targetName: tExpanded });
12535
12501
  continue;
12536
12502
  }
@@ -12610,7 +12576,7 @@ export class Runtime {
12610
12576
  for (let ui = uStart; ui < command.words.length; ui++) {
12611
12577
  const targetName = command.words[ui].plain;
12612
12578
  const existingTargetArr = targetName ? store?.get(targetName) : undefined;
12613
- if (targetName && isShellIdentifier(targetName) && !targetName.startsWith("-") && !rawState.readonlyVariables?.has(targetName) && (!existingTargetArr || (existingTargetArr.references === 1 && !store.watches.has(targetName) && !hasUnpreparedLocal(rawState, targetName))) && !rawState.functions.has(targetName) && !monitor.hasOverlay(targetName) && targetName !== "OPTIND" && targetName !== "PIPESTATUS" && targetName !== "_" && targetName !== "IFS" && targetName !== "PATH") {
12579
+ if (targetName && isShellIdentifier(targetName) && !targetName.startsWith("-") && !rawState.readonlyVariables?.has(targetName) && (!existingTargetArr || (existingTargetArr.references === 1 && !store.watches.has(targetName) && !hasUnpreparedLocal(rawState, targetName))) && !rawState.functions.has(targetName) && !monitor.hasOverlay(targetName) && !controlNames.has(targetName) && targetName !== "PIPESTATUS" && targetName !== "_") {
12614
12580
  targets.push(targetName);
12615
12581
  }
12616
12582
  else {
@@ -13156,6 +13122,8 @@ export class Runtime {
13156
13122
  }
13157
13123
  }
13158
13124
  if (canSyncFn) {
13125
+ if (rawState.functionDepth >= this.budget.limits.maxFunctionDepth)
13126
+ this.budget.fail("maxFunctionDepth");
13159
13127
  const prevCommands = this.budget.commands;
13160
13128
  this.budget.tick();
13161
13129
  rawState.substitutionStatus = 0;
@@ -13507,12 +13475,12 @@ export class Runtime {
13507
13475
  return undefined;
13508
13476
  }
13509
13477
  const def = this.commands.get("printf");
13510
- const isPlainTargetId = targetSpec !== undefined && /^[a-zA-Z_][a-zA-Z_0-9]*$/.test(targetSpec) && targetSpec !== "OPTIND" && targetSpec !== "PIPESTATUS";
13478
+ const isPlainTargetId = targetSpec !== undefined && isShellIdentifier(targetSpec) && !printfSlowTargets.has(targetSpec);
13511
13479
  const isScalarTarget = isPlainTargetId && !store?.get(targetSpec);
13512
13480
  const brkIdx = targetSpec !== undefined && !isPlainTargetId && targetSpec.endsWith("]") ? targetSpec.indexOf("[") : -1;
13513
13481
  const arrName = isPlainTargetId && !isScalarTarget ? targetSpec : (brkIdx > 0 ? targetSpec.slice(0, brkIdx) : undefined);
13514
13482
  const subExpr = isPlainTargetId && !isScalarTarget ? "0" : (brkIdx > 0 ? targetSpec.slice(brkIdx + 1, -1) : undefined);
13515
- const isArrayTarget = arrName !== undefined && /^[a-zA-Z_][a-zA-Z_0-9]*$/.test(arrName) && !controlNames.has(arrName) && subExpr !== undefined && subExpr.length > 0 && !subExpr.includes("$") && !subExpr.includes("\x60");
13483
+ const isArrayTarget = arrName !== undefined && isShellIdentifier(arrName) && !printfSlowTargets.has(arrName) && subExpr !== undefined && subExpr.length > 0 && !subExpr.includes("$") && !subExpr.includes("\x60");
13516
13484
  if (def?.execute === printfCommand.execute && (isScalarTarget || isArrayTarget) && command.words.length <= this.budget.maxExpansionFieldsSmi) {
13517
13485
  fastSubScratchArgs.length = 0;
13518
13486
  let allStrings = true;
@@ -13973,7 +13941,201 @@ export class Runtime {
13973
13941
  this._syncLoopInvariantSubMap.set(part, { text: res, outBytes, exitStatus: 0, dynamic: usesInduction });
13974
13942
  return true;
13975
13943
  }
13944
+ admitSyncArrayLoop(command, state) {
13945
+ const monitor = stateMonitor(state);
13946
+ const store = monitor?.store;
13947
+ if (!store || store.watches.size || hasUnpreparedLocals(state) || state.depth >= 24 || byteLocale(state.variables) || state.nounset || hasActiveVariableAttributes(state) || this.budget.limits.maxExpansionBytes !== Infinity || this.budget.limits.maxExpansionFields !== Infinity)
13948
+ return undefined;
13949
+ const initializer = command.expressions[0]?.tree;
13950
+ if (initializer?.kind !== "binary" || initializer.operator !== "=" || initializer.left.kind !== "name")
13951
+ return undefined;
13952
+ const induction = initializer.left.name;
13953
+ const dynamicNames = new Set(["PIPESTATUS", "LINENO", "_", "FUNCNAME", "DIRSTACK", "BASH_SUBSHELL"]);
13954
+ const assignments = [];
13955
+ const appends = new Map();
13956
+ for (const list of command.body.lists) {
13957
+ if (list.terminator || list.pipelines.length !== 1)
13958
+ return undefined;
13959
+ const pipeline = list.pipelines[0];
13960
+ const cmd = pipeline.commands[0];
13961
+ if (pipeline.negate || pipeline.commands.length !== 1 || cmd?.kind !== "simple" || cmd.redirects.length || cmd.words.length !== 1)
13962
+ return undefined;
13963
+ const assignment = getArrayAssignment(cmd.words[0]) ?? this.assignment(cmd.words[0]);
13964
+ if (!assignment || assignment.name === induction || controlNames.has(assignment.name) || dynamicNames.has(assignment.name) || monitor.hasOverlay(assignment.name) || state.readonlyVariables?.has(assignment.name))
13965
+ return undefined;
13966
+ if ("kind" in assignment) {
13967
+ const binding = store.get(assignment.name);
13968
+ if (!binding || binding.references !== 1 || state.exported.has(assignment.name))
13969
+ return undefined;
13970
+ if (assignment.kind === "element") {
13971
+ if (!binding.associative || assignment.append)
13972
+ return undefined;
13973
+ }
13974
+ else {
13975
+ if (binding.associative || !assignment.append || assignment.entries.some(entry => entry.index || entry.append))
13976
+ return undefined;
13977
+ appends.set(assignment.name, (appends.get(assignment.name) ?? 0) + assignment.entries.length);
13978
+ }
13979
+ }
13980
+ else if (assignment.append || store.get(assignment.name) || ["IFS", "LC_ALL", "LC_CTYPE", "LC_COLLATE", "LANG"].includes(assignment.name))
13981
+ return undefined;
13982
+ assignments.push(assignment);
13983
+ }
13984
+ if (assignments.length > 30 || !assignments.some(assignment => "kind" in assignment && assignment.kind === "element"))
13985
+ return undefined;
13986
+ const integer = { min: 1, max: 20, integer: true }; // Signed shell arithmetic is 64 bit.
13987
+ const decimal = (value) => {
13988
+ if (value === "")
13989
+ return true; // Unset/empty arithmetic operands are zero.
13990
+ let i = value[0] === "-" ? 1 : 0;
13991
+ if (i === value.length || value.length > 20 || (value[i] === "0" && i + 1 !== value.length))
13992
+ return false;
13993
+ for (; i < value.length; i++)
13994
+ if (value[i] < "0" || value[i] > "9")
13995
+ return false;
13996
+ return true;
13997
+ };
13998
+ const literalShape = (value) => {
13999
+ if (typeof value !== "string")
14000
+ return undefined;
14001
+ for (let i = 0; i < value.length; i++)
14002
+ if (value.charCodeAt(i) >= 128)
14003
+ return undefined;
14004
+ return { min: value.length, max: value.length, integer: decimal(value) };
14005
+ };
14006
+ const integerArrays = new Set();
14007
+ for (const [name, { binding }] of store.bindings) {
14008
+ if (!binding.associative)
14009
+ continue;
14010
+ if (![...binding.values.values()].every(slot => typeof slot.text.shellValue === "string" && decimal(slot.text.shellValue)))
14011
+ continue;
14012
+ const writesInteger = assignments.every(assignment => {
14013
+ if (assignment.name !== name || !("kind" in assignment) || assignment.kind !== "element")
14014
+ return true;
14015
+ const parts = assignment.value.parts.filter(part => part.kind !== "text" || part.value !== "");
14016
+ return parts.length === 1 && parts[0].kind === "arithmetic" || parts.every(part => part.kind === "text") && decimal(parts.map(part => part.value).join(""));
14017
+ });
14018
+ if (writesInteger)
14019
+ integerArrays.add(name);
14020
+ }
14021
+ const entry = new Map();
14022
+ for (const assignment of assignments) {
14023
+ if ("kind" in assignment)
14024
+ continue;
14025
+ const raw = state.variables[assignment.name];
14026
+ const shape = literalShape(raw === undefined ? "" : monitor.values.get(assignment.name, raw) ?? raw);
14027
+ if (!shape)
14028
+ return undefined;
14029
+ entry.set(assignment.name, shape);
14030
+ }
14031
+ // Find an invariant over successive iterations. Growing strings or unknown
14032
+ // key bounds decline before execution; no speculative writes or replay.
14033
+ for (let pass = 0; pass < 32; pass++) {
14034
+ const values = new Map(entry);
14035
+ values.set(induction, integer);
14036
+ const words = new WeakSet();
14037
+ const integerWords = new WeakSet();
14038
+ const scalar = (name) => {
14039
+ if (!isShellIdentifier(name) || controlNames.has(name) || dynamicNames.has(name) || store.get(name) || monitor.hasOverlay(name) || hasUnpreparedLocal(state, name))
14040
+ return undefined;
14041
+ const known = values.get(name);
14042
+ if (known)
14043
+ return known;
14044
+ const raw = state.variables[name];
14045
+ return literalShape(raw === undefined ? "" : monitor.values.get(name, raw) ?? raw);
14046
+ };
14047
+ const shapeWord = (word, key = false) => {
14048
+ if (!word.parts.length)
14049
+ return undefined;
14050
+ const shapes = [];
14051
+ for (const part of word.parts) {
14052
+ let shape;
14053
+ if (part.kind === "text") {
14054
+ if (part.byteValue || invokedValues.has(part) || !part.quoted && part.value.includes("~"))
14055
+ return undefined;
14056
+ shape = literalShape(part.value);
14057
+ }
14058
+ else if (part.kind === "arithmetic") {
14059
+ const names = new Set();
14060
+ if (!collectPureReadOnlySmiNames(part.expression, names) || [...names].some(name => !scalar(name)?.integer))
14061
+ return undefined;
14062
+ shape = integer;
14063
+ }
14064
+ else if (part.kind === "variable") {
14065
+ if (part.indirect || part.specialParameter || part.prefixNames || part.length || part.substring || part.transform || part.keys || dynamicNames.has(part.name))
14066
+ return undefined;
14067
+ const selector = getArraySelector(part);
14068
+ if (selector) {
14069
+ if (key || selector.kind !== "element" || !store.get(part.name)?.associative || monitor.hasOverlay(part.name) || controlNames.has(part.name))
14070
+ return undefined;
14071
+ const index = this.syncArraySubscriptWord(selector.index, state);
14072
+ if (!index || !shapeWord(index, true))
14073
+ return undefined;
14074
+ shape = { min: 0, max: integerArrays.has(part.name) ? 20 : Infinity, integer: integerArrays.has(part.name) };
14075
+ if (part.operator !== undefined) {
14076
+ if ((part.operator !== "-" && part.operator !== ":-") || !part.alternate || !part.alternate.parts.every(p => p.kind === "text"))
14077
+ return undefined;
14078
+ const alternate = shapeWord(part.alternate);
14079
+ if (!alternate)
14080
+ return undefined;
14081
+ shape = { min: part.operator === ":-" ? Math.min(1, alternate.min) : 0, max: Math.max(shape.max, alternate.max), integer: shape.integer && alternate.integer };
14082
+ }
14083
+ }
14084
+ else {
14085
+ if (part.operator !== undefined)
14086
+ return undefined;
14087
+ shape = scalar(part.name);
14088
+ }
14089
+ }
14090
+ else
14091
+ return undefined;
14092
+ if (!shape)
14093
+ return undefined;
14094
+ shapes.push(shape);
14095
+ }
14096
+ const nonempty = shapes.filter(shape => shape.max !== 0);
14097
+ const result = { min: shapes.reduce((sum, shape) => sum + shape.min, 0), max: shapes.reduce((sum, shape) => sum + shape.max, 0), integer: nonempty.length === 0 || nonempty.length === 1 && nonempty[0].integer };
14098
+ if (key && (result.min === 0 || result.max > 4096))
14099
+ return undefined;
14100
+ words.add(word);
14101
+ if (result.integer)
14102
+ integerWords.add(word);
14103
+ return result;
14104
+ };
14105
+ for (const assignment of assignments) {
14106
+ if ("kind" in assignment && assignment.kind === "compound") {
14107
+ if (assignment.entries.some(entry => !entry.value.parts.every(part => part.quoted) || !shapeWord(entry.value)))
14108
+ return undefined;
14109
+ }
14110
+ else {
14111
+ if ("kind" in assignment) {
14112
+ const index = this.syncArraySubscriptWord(assignment.index, state);
14113
+ if (!index || !shapeWord(index, true))
14114
+ return undefined;
14115
+ }
14116
+ const shape = shapeWord(assignment.value);
14117
+ if (!shape)
14118
+ return undefined;
14119
+ if (!("kind" in assignment))
14120
+ values.set(assignment.name, shape);
14121
+ }
14122
+ }
14123
+ let stable = true;
14124
+ for (const [name, before] of entry) {
14125
+ const after = values.get(name);
14126
+ const merged = { min: Math.min(before.min, after.min), max: Math.max(before.max, after.max), integer: before.integer && after.integer };
14127
+ if (merged.min !== before.min || merged.max !== before.max || merged.integer !== before.integer)
14128
+ stable = false;
14129
+ entry.set(name, merged);
14130
+ }
14131
+ if (stable)
14132
+ return { words, integerWords, appends };
14133
+ }
14134
+ return undefined;
14135
+ }
13976
14136
  isPureSyncValueWord(word, rawState, allowAt = false) {
14137
+ if (this._activeSyncArrayLoopWords?.has(word))
14138
+ return true;
13977
14139
  if (word.parts.length === 0)
13978
14140
  return false;
13979
14141
  for (let i = 0; i < word.parts.length; i++) {
@@ -13987,7 +14149,7 @@ export class Runtime {
13987
14149
  // Unsubscripted array references expand element zero through the normal
13988
14150
  // evaluator. fastValueWord cannot guarantee that expansion throughout
13989
14151
  // a loop, so reject it before executing any loop effects.
13990
- if (stateMonitor(rawState)?.store?.get(part.name))
14152
+ if (part.name === "RANDOM" || part.name === "SECONDS" || stateMonitor(rawState)?.store?.get(part.name))
13991
14153
  return false;
13992
14154
  // These expansions can require multiple fields or asynchronous quoting
13993
14155
  // as loop state changes. Decide before the loop produces any effects.
@@ -14115,125 +14277,8 @@ export class Runtime {
14115
14277
  return false;
14116
14278
  if (this.tryAdmitLoopInvariantSubstitution(part, rawState))
14117
14279
  continue;
14118
- if (customRegisteredRegistries.has(this.commands))
14119
- return false;
14120
- if (part.script.lists.length !== 1)
14121
- return false;
14122
- const list = part.script.lists[0];
14123
- if (list.terminator || list.pipelines.length !== 1)
14124
- return false;
14125
- const p = list.pipelines[0];
14126
- // Pipeline buffers can overflow after variable or stage expansion.
14127
- // A synchronous loop cannot resume after earlier body effects, so keep
14128
- // bounded pipelines on the normal substitution execution path.
14129
- if (p.negate || p.commands.length !== 1)
14130
- return false;
14131
- let cmd = p.commands[0];
14132
- // Loop substitutions require a real subshell: header admission can
14133
- // decline at runtime, and induction writes also change export attributes.
14134
- if (cmd.kind === "for" || cmd.kind === "arithmetic-for" || cmd.kind === "while")
14135
- return false;
14136
- if (p.commands.length === 1 && (cmd.kind === "if" || cmd.kind === "case") && this.isPureSyncSubIfOrCase(cmd, rawState)) {
14137
- continue;
14138
- }
14139
- if (cmd.kind !== "simple" || cmd.redirects.length > 0 || cmd.words.length === 0)
14140
- return false;
14141
- let w0Plain = cmd.words[0].plain;
14142
- // Range-aware tr and Buffer-free 76-col base64 are handled below.
14143
- if (p.commands.length === 1 && w0Plain !== undefined && rawState.functions.has(w0Plain) && this.firstInternalDiscovery(w0Plain, rawState, false) === "function" && !rawState.extensions?.builtins.has(w0Plain)) {
14144
- const fnBody = rawState.functions.get(w0Plain);
14145
- if (fnBody.kind === "group" &&
14146
- fnBody.redirects.length === 0 &&
14147
- fnBody.body.lists.length === 1 &&
14148
- !fnBody.body.lists[0].terminator &&
14149
- fnBody.body.lists[0].pipelines.length === 1 &&
14150
- !fnBody.body.lists[0].pipelines[0].negate &&
14151
- fnBody.body.lists[0].pipelines[0].commands.length === 1 &&
14152
- fnBody.body.lists[0].pipelines[0].commands[0].kind === "simple" &&
14153
- fnBody.body.lists[0].pipelines[0].commands[0].redirects.length === 0 &&
14154
- cmd.words.slice(1).every(w => this.isPureArgWord(w, rawState) && this.isPureSyncValueWord(w, rawState) && w.parts.length > 0 && w.parts.every(part => part.quoted || (part.kind === "text" && part.value.length > 0 && !part.value.includes(" ") && !part.value.includes("\t") && !part.value.includes("\n") && !part.value.includes("{") && !hasGlobOrEscape(part.value, true))))) {
14155
- const innerCmd = fnBody.body.lists[0].pipelines[0].commands[0];
14156
- const innerW0 = innerCmd.words[0]?.plain;
14157
- if (innerW0 && (innerW0 === "echo" || innerW0 === "printf" || innerW0 === "dirname" || innerW0 === "basename" || innerW0 === "pwd" || innerW0 === "command" || innerW0 === "type" || innerW0 === "seq") && !rawState.functions.has(innerW0) && !rawState.extensions?.builtins.has(innerW0)) {
14158
- cmd = innerCmd;
14159
- w0Plain = innerW0;
14160
- }
14161
- }
14162
- }
14163
- // These evaluators can decline based on runtime input. Loop execution
14164
- // has no continuation for a declined substitution after earlier effects.
14165
- if (w0Plain === "tac" || w0Plain === "nl" || (w0Plain === "base64" && cmd.words.length > 1))
14166
- return false;
14167
- if (w0Plain === "pwd") {
14168
- if (p.commands.length === 1 && (cmd.words.length === 1 || (cmd.words.length === 2 && (cmd.words[1]?.plain === "-L" || cmd.words[1]?.plain === "--logical"))) && !rawState.functions.has("pwd") && !rawState.extensions?.builtins.has("pwd"))
14169
- continue;
14170
- return false;
14171
- }
14172
- if ((w0Plain === "command" && cmd.words[1]?.plain === "-v") || (w0Plain === "type" && cmd.words[1]?.plain === "-t")) {
14173
- // PATH entries can change after admission, making discovery decline.
14174
- return false;
14175
- }
14176
- // File and here-string evaluators can decline on mutable input. Keep
14177
- // these on the normal path, which can handle arbitrary input sizes.
14178
- const def = w0Plain ? (w0Plain === "seq" ? this.getExternalCommand(w0Plain) : this.commands.get(w0Plain)) : undefined;
14179
- if (!w0Plain || (w0Plain !== "printf" && w0Plain !== "echo" && w0Plain !== "dirname" && w0Plain !== "basename" && w0Plain !== "seq") || !def || rawState.functions.has(w0Plain) || rawState.extensions?.builtins.has(w0Plain))
14180
- return false;
14181
- if (w0Plain === "printf" ? def.execute !== printfCommand.execute : w0Plain === "echo" ? !defaultEchoExecutors.has(def.execute) : w0Plain === "seq" ? (!builtInDirectContextExecutors.has(def.execute) && customRegisteredCommands.has(def.execute)) : !builtInDirectContextExecutors.has(def.execute))
14182
- return false;
14183
- // Admission must satisfy the substitution evaluator too: a loop cannot
14184
- // recover from a declined argument after executing earlier body effects.
14185
- if (!cmd.words.slice(1).every(w => this.isPureArgWord(w, rawState) && this.isPureSyncValueWord(w, rawState)))
14186
- return false;
14187
- // These substitutions consume one value per word. Unquoted expansions
14188
- // can split, glob, or disappear, including after loop admission.
14189
- if ((w0Plain === "echo" || w0Plain === "basename" || w0Plain === "dirname") &&
14190
- !cmd.words.slice(1).every(w => w.parts.length > 0 && w.parts.every(part => part.quoted || (part.kind === "text" && part.value.length > 0 && !part.value.includes(" ") && !part.value.includes("\t") && !part.value.includes("\n") && !part.value.includes("{") && !hasGlobOrEscape(part.value, true)))))
14191
- return false;
14192
- if (w0Plain === "printf") {
14193
- if (!this.isSyncPrintfCallOk(cmd, 1, rawState, this._activePrintfInductionName))
14194
- return false;
14195
- }
14196
- else if (w0Plain === "echo") {
14197
- if (!this.isSyncSubEchoCallOk(cmd, rawState))
14198
- return false;
14199
- }
14200
- else if (w0Plain === "dirname" || w0Plain === "basename") {
14201
- const simArgs = [];
14202
- let seenDoubleDash = false;
14203
- for (let wi = 1; wi < cmd.words.length; wi++) {
14204
- const w = cmd.words[wi];
14205
- // Tilde prefixes depend on mutable HOME/PWD/OLDPWD; use normal expansion.
14206
- if (w.parts[0]?.kind === "text" && !w.parts[0].quoted && w.parts[0].value.startsWith("~"))
14207
- return false;
14208
- const st = w.plain ?? (w.parts.length > 0 && w.parts.every(pt => pt.kind === "text") ? w.parts.map(pt => pt.value).join("") : undefined);
14209
- if (st !== undefined) {
14210
- if (st === "--")
14211
- seenDoubleDash = true;
14212
- simArgs.push(st);
14213
- }
14214
- else {
14215
- // A loop operand can become an option after admission.
14216
- if (!seenDoubleDash)
14217
- return false;
14218
- simArgs.push("x");
14219
- }
14220
- }
14221
- if ((w0Plain === "dirname" ? this.evalSyncDirname(simArgs) : this.evalSyncBasename(simArgs)) === undefined)
14222
- return false;
14223
- }
14224
- else if (w0Plain === "seq") {
14225
- const simArgs = [];
14226
- for (let wi = 1; wi < cmd.words.length; wi++) {
14227
- const w = cmd.words[wi];
14228
- const st = w.plain ?? (w.parts.length > 0 && w.parts.every(pt => pt.kind === "text") ? w.parts.map(pt => pt.value).join("") : undefined);
14229
- if (st === undefined)
14230
- return false;
14231
- simArgs.push(st);
14232
- }
14233
- if (this.evalSyncSeq(simArgs) === undefined)
14234
- return false;
14235
- }
14236
- continue;
14280
+ // Dynamic substitutions execute at the committed expansion boundary.
14281
+ return false;
14237
14282
  }
14238
14283
  return false;
14239
14284
  }
@@ -14306,7 +14351,7 @@ export class Runtime {
14306
14351
  };
14307
14352
  const safeArgWord = (w, numeric = false) => (!checkIntVars || this.isPureSyncValueWord(w, rawState)) &&
14308
14353
  (w.parts.every(p => p.quoted || (p.kind === "text" && p.value.length > 0 && !p.value.includes(" ") && !p.value.includes("\t") && !p.value.includes("\n") && !p.value.includes("{") && !hasGlobOrEscape(p.value, true))) ||
14309
- (numeric && ((!checkIntVars && w.parts.length === 1 && w.parts[0].kind === "variable") || (checkIntVars && rawState.variables.IFS === undefined && isGuaranteedIntWord(w)))));
14354
+ (numeric && ((!checkIntVars && w.parts.length === 1 && w.parts[0].kind === "variable") || (checkIntVars && (rawState.variables.IFS === undefined || rawState.variables.IFS === " \t\n") && isGuaranteedIntWord(w)))));
14310
14355
  if (args.length === 2) {
14311
14356
  const op = args[0].plain;
14312
14357
  if ((op === "-n" || op === "-z") && safeArgWord(args[1])) {
@@ -14819,7 +14864,7 @@ export class Runtime {
14819
14864
  for (const cl of cmd.clauses) {
14820
14865
  if (cl.terminator !== ";;" && cl.terminator !== "esac")
14821
14866
  return false;
14822
- if (!cl.patterns.every(pw => pw.plain !== undefined && tryMatchesPatternSync(pw.plain, "", work, false, false) !== undefined))
14867
+ if (!cl.patterns.every(pw => pw.plain !== undefined && !pw.plain.startsWith("~") && tryMatchesPatternSync(pw.plain, "", work, false, false) !== undefined))
14823
14868
  return false;
14824
14869
  if (!isSimpleEchoOrPrintf(cl.body))
14825
14870
  return false;
@@ -14922,7 +14967,7 @@ export class Runtime {
14922
14967
  return false;
14923
14968
  if (pw.plain === undefined && !pw.parts.every(p => p.quoted))
14924
14969
  return false;
14925
- const pattern = pw.plain ?? (io ? this.tryBuildSyncPatternWord(pw, rawState, io) : undefined);
14970
+ const pattern = (io ? this.tryBuildSyncPatternWord(pw, rawState, io) : (pw.plain?.startsWith("~") ? undefined : pw.plain));
14926
14971
  return pattern !== undefined && tryMatchesPatternSync(pattern, "", work, false, false) !== undefined;
14927
14972
  })) {
14928
14973
  caseOk = false;
@@ -15080,8 +15125,7 @@ export class Runtime {
15080
15125
  if (!hasActiveVariableAttributes(rawState) &&
15081
15126
  vName !== undefined &&
15082
15127
  isShellIdentifier(vName) &&
15083
- !controlNames.has(vName) &&
15084
- vName !== "OPTIND" &&
15128
+ !printfSlowTargets.has(vName) &&
15085
15129
  !rawState.readonlyVariables?.has(vName) &&
15086
15130
  !rawState.variableAttributes?.get(vName) &&
15087
15131
  !store?.get(vName) &&
@@ -15129,14 +15173,19 @@ export class Runtime {
15129
15173
  if (hasUnpreparedLocals(rawState))
15130
15174
  return false;
15131
15175
  // Eligibility checks must not create bindings: the loop may never run.
15132
- // Element subscripts need the normal arithmetic and relative-index evaluator.
15133
- if (arrAssign.kind === "element")
15134
- return false;
15135
15176
  const curArr = store?.get(arrAssign.name);
15136
15177
  const activeArrStore = store ?? stateMonitor(rawState)?.store;
15137
- if (!curArr || curArr.references !== 1 || activeArrStore?.watches.has(arrAssign.name) || rawState.readonlyVariables?.has(arrAssign.name) || rawState.exported.has(arrAssign.name) || controlNames.has(arrAssign.name)) {
15178
+ if (!curArr || curArr.references !== 1 || activeArrStore?.watches.has(arrAssign.name) || rawState.readonlyVariables?.has(arrAssign.name) || rawState.variableAttributes?.has(arrAssign.name) || rawState.exported.has(arrAssign.name) || controlNames.has(arrAssign.name)) {
15138
15179
  return false;
15139
15180
  }
15181
+ if (arrAssign.kind === "element") {
15182
+ // Only the whole-loop proof can admit associative keys. Indexed
15183
+ // arithmetic and relative subscripts retain normal evaluation.
15184
+ const index = curArr.associative ? this.syncArraySubscriptWord(arrAssign.index, rawState) : undefined;
15185
+ if (!index || !this._activeSyncArrayLoopWords?.has(index) || !this.isPureSyncValueWord(index, rawState) || !this.isPureSyncValueWord(arrAssign.value, rawState))
15186
+ return false;
15187
+ continue;
15188
+ }
15140
15189
  if (arrAssign.kind === "compound" && arrAssign.entries.length <= 16 && arrAssign.entries.every(e => !e.append)) {
15141
15190
  let allEntriesOk = true;
15142
15191
  for (let ei = 0; ei < arrAssign.entries.length; ei++) {
@@ -15541,7 +15590,14 @@ export class Runtime {
15541
15590
  for (let b = 0; b + 1 < bodyAssignments.length; b++) {
15542
15591
  const curr = bodyAssignments[b];
15543
15592
  const next = bodyAssignments[b + 1];
15544
- if (curr.targetWord !== undefined && curr.value !== undefined && this.isSimpleRedirectEchoWord(curr.value) && !curr.append && next.targetWord !== undefined && next.value !== undefined && this.isSimpleRedirectEchoWord(next.value) && next.append && sameRedirectTargetWord(curr.targetWord, next.targetWord)) {
15593
+ // The first echo must finish before a dependent command or $? expansion.
15594
+ if (curr.listOperator === undefined && next.listOperator === undefined &&
15595
+ curr.targetWord !== undefined && curr.value !== undefined &&
15596
+ this.isSimpleRedirectEchoWord(curr.value) && !curr.append &&
15597
+ next.targetWord !== undefined && next.value !== undefined &&
15598
+ this.isSimpleRedirectEchoWord(next.value) && next.append &&
15599
+ sameRedirectTargetWord(curr.targetWord, next.targetWord) &&
15600
+ [next.value, next.targetWord].every(word => word.parts.every(part => part.kind !== "variable" || part.name !== "?"))) {
15545
15601
  curr.coalesceNext = true;
15546
15602
  b++;
15547
15603
  }
@@ -15554,7 +15610,7 @@ export class Runtime {
15554
15610
  }
15555
15611
  return res;
15556
15612
  }
15557
- syncLoopArithmeticReadsRemainInteger(steps, rawState) {
15613
+ syncLoopArithmeticReadsRemainInteger(steps, rawState, integerWords) {
15558
15614
  const reads = new Set();
15559
15615
  const seen = new WeakSet();
15560
15616
  // Inspect words in commands, conditions, substitutions, and inlined functions.
@@ -15577,7 +15633,7 @@ export class Runtime {
15577
15633
  const safeWrites = (items) => items.every(step => {
15578
15634
  if (step.name && reads.has(step.name)) {
15579
15635
  const literal = step.value?.plain;
15580
- if (step.append || (!this.extractIntLoopStep(step, rawState) && (literal === undefined || !/^-?[0-9]+$/.test(literal))))
15636
+ if (step.append || (!integerWords?.has(step.value) && !this.extractIntLoopStep(step, rawState) && (literal === undefined || !/^-?[0-9]+$/.test(literal))))
15581
15637
  return false;
15582
15638
  }
15583
15639
  if (step.readHereString?.varNames.some(name => reads.has(name)) || (step.readHereString?.arrayTarget && reads.has(step.readHereString.arrayTarget)))
@@ -15616,22 +15672,29 @@ export class Runtime {
15616
15672
  return undefined;
15617
15673
  }
15618
15674
  const regNames = forPlan.regNames;
15675
+ for (const refName of regNames) {
15676
+ if (store?.get(refName) || store?.watches.has(refName) || monitor.hasOverlay(refName) || rawState.variableAttributes?.has(refName))
15677
+ return undefined;
15678
+ }
15679
+ const intBudgetSnapshot = this.budget.parsing.snapshot();
15619
15680
  for (let r = 0; r < regNames.length; r++) {
15620
15681
  const refName = regNames[r];
15621
- if (store?.get(refName))
15622
- return undefined;
15623
15682
  if (r > 0) {
15624
15683
  const parsed = fastSafeInt(rawState.variables[refName], this.budget.parsing);
15625
- if (parsed === undefined)
15684
+ if (parsed === undefined) {
15685
+ this.budget.parsing.restore(intBudgetSnapshot);
15626
15686
  return undefined;
15687
+ }
15627
15688
  sharedLoopIntRegs[r] = parsed | 0;
15628
15689
  }
15629
15690
  }
15630
- monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets);
15631
- this.budget.tick();
15632
15691
  const { ok } = runIntForLoop(fastLoopWords, forPlan.bodyStepCount, forPlan.intSteps, this.budget.parsing);
15633
- if (!ok)
15692
+ if (!ok) {
15693
+ this.budget.parsing.restore(intBudgetSnapshot);
15634
15694
  return undefined;
15695
+ }
15696
+ monitor.chargeInternal(syncRestorationCharge, syncRestorationTickets);
15697
+ this.budget.tick();
15635
15698
  this.budget.iterations += wordCount;
15636
15699
  this.budget.commands += wordCount * forPlan.bodyStepCount;
15637
15700
  for (let r = 0; r < regNames.length; r++) {
@@ -15736,6 +15799,9 @@ export class Runtime {
15736
15799
  const prevAssignedVars = this._activeSyncLoopAssignedVars;
15737
15800
  const prevLoopIO = this._activeSyncLoopIO;
15738
15801
  const prevInvMap = this._syncLoopInvariantSubMap;
15802
+ const prevArrayWords = this._activeSyncArrayLoopWords;
15803
+ const arrayLoop = command.kind === "arithmetic-for" ? this.admitSyncArrayLoop(command, rawState) : undefined;
15804
+ this._activeSyncArrayLoopWords = arrayLoop?.words;
15739
15805
  this._activePrintfInductionName = printfInductionName;
15740
15806
  this._activeSyncLoopAssignedVars = this.collectSyncLoopAssignedVars(command, rawState);
15741
15807
  this._activeSyncLoopIO = io;
@@ -15750,6 +15816,7 @@ export class Runtime {
15750
15816
  this._activeSyncLoopAssignedVars = prevAssignedVars;
15751
15817
  this._activeSyncLoopIO = prevLoopIO;
15752
15818
  this._syncLoopInvariantSubMap = prevInvMap;
15819
+ this._activeSyncArrayLoopWords = prevArrayWords;
15753
15820
  }
15754
15821
  if (!bodySyncOk) {
15755
15822
  command._skipTrySyncLoop = true;
@@ -15788,12 +15855,13 @@ export class Runtime {
15788
15855
  this._syncLoopInvariantSubMap = localInvMap;
15789
15856
  try {
15790
15857
  const { steps: bodyAssignments, redirectCount } = this.buildSyncLoopBody(command, rawState, io);
15791
- if (bodyAssignments.length > 30 || !this.syncLoopArithmeticReadsRemainInteger(bodyAssignments, rawState))
15858
+ if (bodyAssignments.length > 30 || !this.syncLoopArithmeticReadsRemainInteger(bodyAssignments, rawState, arrayLoop?.integerWords))
15792
15859
  return undefined;
15793
15860
  const touched = this._syncArithRawWriteOnly ? new Set() : sharedSyncLoopTouched;
15794
15861
  touched.clear();
15795
15862
  let lastCmd;
15796
15863
  let lastArg = "";
15864
+ let lastPipelineStatus;
15797
15865
  const mode = 0o666 & ~(rawState.umask ?? 0o022);
15798
15866
  if (command.kind === "arithmetic-for") {
15799
15867
  let plan = command._cachedArithPlan;
@@ -15940,6 +16008,10 @@ export class Runtime {
15940
16008
  : step.value ? [step.value] : [];
15941
16009
  for (let wIdx = 0; wIdx < wordsToScan.length; wIdx++) {
15942
16010
  const wVal = wordsToScan[wIdx];
16011
+ // The array-loop proof tracks integer values at each statement,
16012
+ // including scalars loaded from arrays earlier in the same iteration.
16013
+ if (arrayLoop?.words.has(wVal))
16014
+ continue;
15943
16015
  for (let i = 0; i < wVal.parts.length; i++) {
15944
16016
  const part = wVal.parts[i];
15945
16017
  if (part.kind === "text" || part.kind === "variable")
@@ -16028,6 +16100,14 @@ export class Runtime {
16028
16100
  return undefined;
16029
16101
  }
16030
16102
  const { e0, e1, e2, iterations, inductionName, startVal, limitVal, isLe, isSimpleLiteralAsc, arithNamesList, intSteps, allIntStepsReady, hasSubIntStep, hasDeferredSteps, deferredMask, touchedIntNamesList, } = plan;
16103
+ if (arrayLoop?.appends.size) {
16104
+ if (!isSimpleLiteralAsc)
16105
+ return undefined;
16106
+ for (const [name, count] of arrayLoop.appends) {
16107
+ if (store.get(name).maximum + iterations * count > 2147483647)
16108
+ return undefined;
16109
+ }
16110
+ }
16031
16111
  if (inductionName === "OPTIND" || controlNames.has(inductionName) || monitor.hasOverlay(inductionName) || hasUnpreparedLocal(rawState, inductionName) || store?.get(inductionName) || rawState.readonlyVariables?.has(inductionName) || rawState.variableAttributes?.get(inductionName))
16032
16112
  return undefined;
16033
16113
  if (!isSimpleLiteralAsc && (!this.canSyncArithmeticWithoutFault(e0.tree, rawState, diagnosticLine) || !this.canSyncArithmeticWithoutFault(e1.tree, rawState, diagnosticLine) || !this.canSyncArithmeticWithoutFault(e2.tree, rawState, diagnosticLine)))
@@ -16035,6 +16115,8 @@ export class Runtime {
16035
16115
  if (arithNamesList.length > 0) {
16036
16116
  for (let a = 0; a < arithNamesList.length; a++) {
16037
16117
  const refName = arithNamesList[a];
16118
+ if (store?.get(refName))
16119
+ return undefined;
16038
16120
  if (refName === inductionName)
16039
16121
  continue;
16040
16122
  const initial = rawState.variables[refName];
@@ -16117,6 +16199,8 @@ export class Runtime {
16117
16199
  canUseIntRegisters = false;
16118
16200
  else {
16119
16201
  usedFastIntPath = true;
16202
+ if (iterations > 0)
16203
+ lastPipelineStatus = 0;
16120
16204
  this.budget.parsing.admit(limitVal < 0 ? 4 : 2);
16121
16205
  this.budget.iterations += iterations + 1;
16122
16206
  this.budget.commands += iterations * bodyAssignments.length + subCount;
@@ -16147,6 +16231,7 @@ export class Runtime {
16147
16231
  loopStatus = rawState.status;
16148
16232
  lastCmd = fb.lastCmd;
16149
16233
  lastArg = fb.lastArg;
16234
+ lastPipelineStatus = fb.pipelineStatus;
16150
16235
  lastInductionVal = fb.lastInductionVal;
16151
16236
  }
16152
16237
  finally {
@@ -16226,12 +16311,14 @@ export class Runtime {
16226
16311
  rawState.lastArgument = lastArg;
16227
16312
  if (io.assignmentDiagnosticContext)
16228
16313
  io.assignmentDiagnosticContext.name = undefined;
16314
+ }
16315
+ if (lastPipelineStatus !== undefined) {
16229
16316
  if (!existing) {
16230
- monitor.lazyPipeStatus = loopStatus === 0 ? singleStatusZero : [loopStatus];
16317
+ monitor.lazyPipeStatus = lastPipelineStatus === 0 ? singleStatusZero : [lastPipelineStatus];
16231
16318
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
16232
16319
  }
16233
16320
  else {
16234
- this.setSyncPipeStatusCell(existing, String(loopStatus));
16321
+ this.setSyncPipeStatusCell(existing, String(lastPipelineStatus));
16235
16322
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
16236
16323
  }
16237
16324
  }
@@ -16249,6 +16336,8 @@ export class Runtime {
16249
16336
  if (cp.negate || cp.commands.length !== 1)
16250
16337
  return undefined;
16251
16338
  const condCmd = cp.commands[0];
16339
+ if (condCmd.kind !== "simple" && condCmd.kind !== "arithmetic" && condCmd.kind !== "conditional")
16340
+ return undefined;
16252
16341
  let whileArithProg;
16253
16342
  let whileCondExpr;
16254
16343
  let whileReadSpec;
@@ -16477,6 +16566,7 @@ export class Runtime {
16477
16566
  this._syncArithTouched = touched;
16478
16567
  const condLine = io.diagnosticCommandLines?.get(condCmd) ?? (condCmd.line ?? diagnosticLine) + (io.diagnosticOffset ?? 0);
16479
16568
  let loopStatus = 0;
16569
+ const progress = { lastCmd: undefined, lastArg: rawState.lastArgument ?? "", pipelineStatus: undefined };
16480
16570
  let iterCount = 0;
16481
16571
  try {
16482
16572
  if (whileReadSpec !== undefined && syncReadInputText !== undefined) {
@@ -16542,8 +16632,9 @@ export class Runtime {
16542
16632
  rawState.variables[vn] = "";
16543
16633
  touched.add(vn);
16544
16634
  }
16545
- lastCmd = rCmd;
16546
- lastArg = rLastArg;
16635
+ progress.lastCmd = rCmd;
16636
+ progress.lastArg = rLastArg;
16637
+ progress.pipelineStatus = 1;
16547
16638
  break;
16548
16639
  }
16549
16640
  const nlIdx = syncReadInputText.indexOf(readDelim, cursor);
@@ -16551,19 +16642,23 @@ export class Runtime {
16551
16642
  const partialLine = syncReadInputText.slice(cursor);
16552
16643
  cursor = textLen;
16553
16644
  splitSyncReadLine(partialLine, readIfs);
16554
- lastCmd = rCmd;
16555
- lastArg = rLastArg;
16645
+ progress.lastCmd = rCmd;
16646
+ progress.lastArg = rLastArg;
16647
+ progress.pipelineStatus = 1;
16556
16648
  break;
16557
16649
  }
16558
16650
  const lineStr = syncReadInputText.slice(cursor, nlIdx);
16559
16651
  cursor = nlIdx + 1;
16560
16652
  splitSyncReadLine(lineStr, readIfs);
16653
+ progress.lastCmd = rCmd;
16654
+ progress.lastArg = rLastArg;
16655
+ progress.pipelineStatus = 0;
16561
16656
  rawState.status = 0;
16562
16657
  ++iterCount;
16563
16658
  this.budget.loop();
16564
16659
  if ((iterCount & 127) === 0)
16565
16660
  runYieldCheckpoint(this.signal);
16566
- this.execSyncLoopSteps(bodyAssignments, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
16661
+ this.execSyncLoopSteps(bodyAssignments, rawState, io, monitor, touched, mode, progress);
16567
16662
  loopStatus = rawState.status;
16568
16663
  if (this._syncLoopAction !== undefined) {
16569
16664
  const act = this._syncLoopAction;
@@ -16594,8 +16689,9 @@ export class Runtime {
16594
16689
  }
16595
16690
  rawState.variables[whileGetoptsSpec.optVar] = res.option;
16596
16691
  touched.add(whileGetoptsSpec.optVar);
16597
- lastCmd = whileGetoptsSpec.getoptsCmd;
16598
- lastArg = whileGetoptsSpec.cmdLastArg;
16692
+ progress.lastCmd = whileGetoptsSpec.getoptsCmd;
16693
+ progress.lastArg = whileGetoptsSpec.cmdLastArg;
16694
+ progress.pipelineStatus = res.status;
16599
16695
  if (res.status !== 0)
16600
16696
  break;
16601
16697
  rawState.status = 0;
@@ -16603,7 +16699,7 @@ export class Runtime {
16603
16699
  this.budget.loop();
16604
16700
  if ((iterCount & 127) === 0)
16605
16701
  runYieldCheckpoint(this.signal);
16606
- this.execSyncLoopSteps(bodyAssignments, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
16702
+ this.execSyncLoopSteps(bodyAssignments, rawState, io, monitor, touched, mode, progress);
16607
16703
  loopStatus = rawState.status;
16608
16704
  if (this._syncLoopAction !== undefined) {
16609
16705
  const act = this._syncLoopAction;
@@ -16619,18 +16715,18 @@ export class Runtime {
16619
16715
  const condNonZero = whileCondExpr !== undefined
16620
16716
  ? (this.tryEvalConditionalSync(whileCondExpr, rawState, monitor, store, io, condLine) ?? 1) === 0
16621
16717
  : this.evalSyncLoopArithStmt(whileArithProg, rawState, io, touched, condLine);
16622
- if (condCmd.kind === "simple") {
16623
- lastCmd = condCmd;
16624
- lastArg = this.fastValueWord(condCmd.words[condCmd.words.length - 1], rawState, io, false, false, false, true);
16625
- }
16718
+ progress.lastCmd = condCmd;
16719
+ if (condCmd.kind === "simple")
16720
+ progress.lastArg = this.fastValueWord(condCmd.words[condCmd.words.length - 1], rawState, io, false, false, false, true);
16626
16721
  rawState.status = condNonZero ? 0 : 1;
16722
+ progress.pipelineStatus = rawState.status;
16627
16723
  if (condNonZero !== (command.kind === "while"))
16628
16724
  break;
16629
16725
  ++iterCount;
16630
16726
  this.budget.loop();
16631
16727
  if ((iterCount & 127) === 0)
16632
16728
  runYieldCheckpoint(this.signal);
16633
- this.execSyncLoopSteps(bodyAssignments, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
16729
+ this.execSyncLoopSteps(bodyAssignments, rawState, io, monitor, touched, mode, progress);
16634
16730
  loopStatus = rawState.status;
16635
16731
  if (this._syncLoopAction !== undefined) {
16636
16732
  const act = this._syncLoopAction;
@@ -16661,6 +16757,9 @@ export class Runtime {
16661
16757
  }
16662
16758
  }
16663
16759
  }
16760
+ lastCmd = progress.lastCmd;
16761
+ lastArg = progress.lastArg;
16762
+ lastPipelineStatus = progress.pipelineStatus;
16664
16763
  if (lastCmd) {
16665
16764
  if (rawState.extensions && !rawState.extensions.eventDepth)
16666
16765
  publishCommandSpelling(rawState, commandSpelling(lastCmd));
@@ -16670,9 +16769,11 @@ export class Runtime {
16670
16769
  rawState.lastArgument = lastArg;
16671
16770
  if (io.assignmentDiagnosticContext)
16672
16771
  io.assignmentDiagnosticContext.name = undefined;
16673
- const statusStr = loopStatus === 0 ? "0" : String(loopStatus);
16772
+ }
16773
+ if (lastPipelineStatus !== undefined) {
16774
+ const statusStr = String(lastPipelineStatus);
16674
16775
  if (!existing) {
16675
- monitor.lazyPipeStatus = loopStatus === 0 ? singleStatusZero : [loopStatus];
16776
+ monitor.lazyPipeStatus = lastPipelineStatus === 0 ? singleStatusZero : [lastPipelineStatus];
16676
16777
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
16677
16778
  }
16678
16779
  else {
@@ -16967,6 +17068,8 @@ export class Runtime {
16967
17068
  canUseIntRegisters = false;
16968
17069
  else {
16969
17070
  usedFastIntFor = true;
17071
+ if (fastLoopWords.length > 0)
17072
+ lastPipelineStatus = 0;
16970
17073
  lastCmd = bodyAssignments[bodyAssignments.length - 1]?.cmd;
16971
17074
  this.budget.iterations += fastLoopWords.length;
16972
17075
  this.budget.commands += fastLoopWords.length * bodyAssignments.length + subCount;
@@ -16997,6 +17100,7 @@ export class Runtime {
16997
17100
  loopStatus = fastLoopWords.length === 0 ? 0 : rawState.status;
16998
17101
  lastCmd = fb.lastCmd;
16999
17102
  lastArg = fb.lastArg;
17103
+ lastPipelineStatus = fb.pipelineStatus;
17000
17104
  }
17001
17105
  finally {
17002
17106
  this._syncReturnDepth--;
@@ -17045,12 +17149,14 @@ export class Runtime {
17045
17149
  rawState.lastArgument = lastArg;
17046
17150
  if (io.assignmentDiagnosticContext)
17047
17151
  io.assignmentDiagnosticContext.name = undefined;
17152
+ }
17153
+ if (lastPipelineStatus !== undefined) {
17048
17154
  if (!existing) {
17049
- monitor.lazyPipeStatus = loopStatus === 0 ? singleStatusZero : [loopStatus];
17155
+ monitor.lazyPipeStatus = lastPipelineStatus === 0 ? singleStatusZero : [lastPipelineStatus];
17050
17156
  monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets);
17051
17157
  }
17052
17158
  else {
17053
- this.setSyncPipeStatusCell(existing, String(loopStatus));
17159
+ this.setSyncPipeStatusCell(existing, String(lastPipelineStatus));
17054
17160
  store.changed(monitor.chargeInternal(syncPipeStatusCharge, syncPipeStatusTickets), "PIPESTATUS");
17055
17161
  }
17056
17162
  }
@@ -17675,8 +17781,7 @@ export class Runtime {
17675
17781
  }
17676
17782
  runSyncArithForFallback(e0, e1, e2, inductionName, hasDeferredSteps, deferredMask, bodyAssignments, rawState, io, monitor, touched, mode, diagnosticLine) {
17677
17783
  let enteredBody = false;
17678
- let lastCmd;
17679
- let lastArg = rawState.lastArgument ?? "";
17784
+ const progress = { lastCmd: undefined, lastArg: rawState.lastArgument ?? "", pipelineStatus: undefined };
17680
17785
  let lastInductionVal;
17681
17786
  touched.add(inductionName);
17682
17787
  this.syncShellArithmeticNonZero(e0, rawState, diagnosticLine);
@@ -17690,160 +17795,7 @@ export class Runtime {
17690
17795
  enteredBody = true;
17691
17796
  if (hasDeferredSteps)
17692
17797
  lastInductionVal = rawState.variables[inductionName];
17693
- for (let b = 0; b < bodyAssignments.length; b++) {
17694
- const step = bodyAssignments[b];
17695
- if (step.listOperator !== undefined && ((step.listOperator === "&&" && rawState.status !== 0) || (step.listOperator === "||" && rawState.status === 0)))
17696
- continue;
17697
- if (step.caseClauses === undefined && step.ifBranches === undefined && step.nestedLoop === undefined)
17698
- lastCmd = step.cmd;
17699
- this.budget.tick();
17700
- if (step.loopAction !== undefined) {
17701
- lastArg = step.cmd.words[step.cmd.words.length - 1].plain;
17702
- rawState.status = 0;
17703
- this._syncLoopAction = step.loopAction;
17704
- break;
17705
- }
17706
- if (step.unsetVars !== undefined) {
17707
- lastArg = this.execSyncUnsetStep(step, rawState, monitor, touched);
17708
- rawState.status = 0;
17709
- continue;
17710
- }
17711
- if (step.localDecl !== undefined) {
17712
- lastArg = this.execSyncLocalDeclStep(step.localDecl, rawState, io, monitor, touched, step.line);
17713
- rawState.status = 0;
17714
- continue;
17715
- }
17716
- if (step.shiftCount !== undefined) {
17717
- const shRes = this.execSyncShiftStep(step.shiftCount, step.cmd, rawState);
17718
- lastArg = shRes.lastArg;
17719
- rawState.status = shRes.status;
17720
- continue;
17721
- }
17722
- if (step.readHereString !== undefined) {
17723
- lastArg = this.execSyncReadHereStringStep(step.readHereString, step, rawState, io, monitor, touched);
17724
- continue;
17725
- }
17726
- if (deferredMask & (1 << b)) {
17727
- lastArg = "";
17728
- rawState.status = 0;
17729
- continue;
17730
- }
17731
- if (step.coalesceNext) {
17732
- const nextStep = bodyAssignments[++b];
17733
- this.budget.tick();
17734
- const encoded = this.encodeSyncRedirectWordsToScratch(step.value, nextStep.value, rawState, io);
17735
- this.writeSyncRedirectStep(step, encoded, false, mode, rawState, io);
17736
- this.budget.fileSystemOperation();
17737
- this.budget.fileSystemOperation();
17738
- this.budget.bytes += encoded.byteLength;
17739
- lastCmd = nextStep.cmd;
17740
- lastArg = this.evalSyncRedirectWord(nextStep.value, rawState, io) ?? "";
17741
- }
17742
- else if (step.targetWord !== undefined && step.value !== undefined) {
17743
- if (this.isSimpleRedirectEchoWord(step.value)) {
17744
- const encoded = this.encodeSyncRedirectWordsToScratch(step.value, undefined, rawState, io);
17745
- this.writeSyncRedirectStep(step, encoded, step.append, mode, rawState, io);
17746
- this.budget.fileSystemOperation();
17747
- this.budget.bytes += encoded.byteLength;
17748
- lastArg = this.evalSyncRedirectWord(step.value, rawState, io) ?? "";
17749
- }
17750
- else {
17751
- const val = this.fastValueWord(step.value, rawState, io, false, false, false, false, 0, step.line);
17752
- const encoded = fastSharedTextEncoder.encode(this.formatSyncEchoLine(val));
17753
- this.writeSyncRedirectStep(step, encoded, step.append, mode, rawState, io);
17754
- this.budget.fileSystemOperation();
17755
- this.budget.bytes += encoded.byteLength;
17756
- lastArg = val;
17757
- }
17758
- }
17759
- else if (step.targetWord !== undefined && step.printfVArgs !== undefined) {
17760
- const { formatted, lastArg: pLastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
17761
- const encoded = fastSharedTextEncoder.encode(formatted);
17762
- this.writeSyncRedirectStep(step, encoded, step.append, mode, rawState, io);
17763
- this.budget.fileSystemOperation();
17764
- this.budget.bytes += encoded.byteLength;
17765
- lastArg = pLastArg;
17766
- }
17767
- else if (step.isStdoutEcho && step.value !== undefined) {
17768
- const val = this.fastValueWord(step.value, rawState, io, false, false, false, false, 0, step.line);
17769
- this.writeSyncStdoutText(this.formatSyncEchoLine(val), io);
17770
- lastArg = val;
17771
- }
17772
- else if (step.isStdoutEcho && step.printfVArgs !== undefined) {
17773
- const { formatted, lastArg: pLastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
17774
- this.writeSyncStdoutText(formatted, io);
17775
- lastArg = pLastArg;
17776
- }
17777
- else if (step.arrayAssign !== undefined) {
17778
- if (!this.tryFastArrayAssignmentSync(step.arrayAssign, rawState, io, step.line, undefined, undefined, true)) {
17779
- throw new Error("Synchronous loop array assignment was not executable");
17780
- }
17781
- lastArg = "";
17782
- }
17783
- else if (step.caseClauses !== undefined) {
17784
- this.flushSyncStdoutBatch(io);
17785
- this.execSyncCaseStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
17786
- if (this._syncLoopAction !== undefined)
17787
- break;
17788
- continue;
17789
- }
17790
- else if (step.ifBranches !== undefined) {
17791
- this.flushSyncStdoutBatch(io);
17792
- this.execSyncIfStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
17793
- if (this._syncLoopAction !== undefined)
17794
- break;
17795
- continue;
17796
- }
17797
- else if (step.condStmt !== undefined) {
17798
- const cStatus = this.tryEvalConditionalSync(step.condStmt, rawState, monitor, arrayStore(rawState), io, step.line) ?? 1;
17799
- if (step.cmd.kind === "simple") {
17800
- lastArg = this.fastValueWord(step.cmd.words[step.cmd.words.length - 1], rawState, io, false, false, false, true);
17801
- }
17802
- rawState.status = cStatus;
17803
- continue;
17804
- }
17805
- else if (step.nestedLoop !== undefined) {
17806
- this.flushSyncStdoutBatch(io);
17807
- this.execSyncNestedLoopStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
17808
- continue;
17809
- }
17810
- else if (step.fnCall !== undefined) {
17811
- this.flushSyncStdoutBatch(io);
17812
- this.execSyncFnStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
17813
- continue;
17814
- }
17815
- else if (step.arithStmt !== undefined) {
17816
- const nonZero = this.evalSyncLoopArithStmt(step.arithStmt, rawState, io, touched, step.line);
17817
- rawState.status = nonZero ? 0 : 1;
17818
- continue;
17819
- }
17820
- else if (step.printfVArgs !== undefined && step.name !== undefined) {
17821
- const { formatted, lastArg: pLastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
17822
- rawState.variables[step.name] = formatted;
17823
- touched.add(step.name);
17824
- lastArg = pLastArg;
17825
- }
17826
- else if (step.isDiscardDevNull && step.discardWords !== undefined) {
17827
- lastArg = this.runSyncDiscardStep(step, rawState, io);
17828
- }
17829
- else if (step.name !== undefined && step.value !== undefined) {
17830
- rawState.substitutionStatus = 0;
17831
- const val = this.fastValueWord(step.value, rawState, io, false, false, false, false, 0, step.line);
17832
- if (step.append) {
17833
- const curRaw = rawState.variables[step.name];
17834
- const curStr = curRaw === undefined ? "" : (touched.has(step.name) ? curRaw : (monitor.values.get(step.name, curRaw) ?? curRaw));
17835
- rawState.variables[step.name] = (typeof curStr === "string" ? curStr : "") + val;
17836
- }
17837
- else
17838
- rawState.variables[step.name] = val;
17839
- touched.add(step.name);
17840
- lastArg = "";
17841
- }
17842
- else {
17843
- lastArg = step.cmd.words[0].plain;
17844
- }
17845
- rawState.status = step.name !== undefined && step.value !== undefined ? rawState.substitutionStatus : 0;
17846
- }
17798
+ this.execSyncLoopSteps(bodyAssignments, rawState, io, monitor, touched, mode, progress, deferredMask);
17847
17799
  if (this._syncLoopAction !== undefined) {
17848
17800
  const act = this._syncLoopAction;
17849
17801
  this._syncLoopAction = undefined;
@@ -17855,7 +17807,7 @@ export class Runtime {
17855
17807
  this.flushSyncStdoutBatch(io);
17856
17808
  if (!enteredBody)
17857
17809
  rawState.status = 0;
17858
- return { lastCmd, lastArg, lastInductionVal };
17810
+ return { ...progress, lastInductionVal };
17859
17811
  }
17860
17812
  _syncLoopFnCheckDepth = 0;
17861
17813
  canSyncReadOnlyArraySubscripts(tree, rawState) {
@@ -18058,7 +18010,7 @@ export class Runtime {
18058
18010
  rawState.positional = savedPos;
18059
18011
  }
18060
18012
  }
18061
- execSyncFnStep(step, rawState, io, monitor, touched, mode, onUpdate) {
18013
+ execSyncFnStep(step, rawState, io, monitor, touched, mode, progress) {
18062
18014
  const fnCall = step.fnCall;
18063
18015
  const fnArgs = [];
18064
18016
  for (let i = 0; i < fnCall.argWords.length; i++) {
@@ -18099,13 +18051,15 @@ export class Runtime {
18099
18051
  }
18100
18052
  }
18101
18053
  if (fnCall.steps.length > 0) {
18102
- this.execSyncLoopSteps(fnCall.steps, rawState, io, monitor, touched, mode, onUpdate);
18054
+ this.execSyncLoopSteps(fnCall.steps, rawState, io, monitor, touched, mode, progress);
18103
18055
  }
18104
18056
  else {
18105
18057
  rawState.status = 0;
18106
18058
  }
18107
18059
  rawState.lastArgument = fnArgs.at(-1) ?? fnCall.name;
18108
- onUpdate({ lastCmd: step.cmd, lastArg: rawState.lastArgument });
18060
+ progress.lastCmd = step.cmd;
18061
+ progress.lastArg = rawState.lastArgument;
18062
+ progress.pipelineStatus = rawState.status;
18109
18063
  }
18110
18064
  finally {
18111
18065
  for (let i = savedLocals.length - 1; i >= 0; i--) {
@@ -18125,16 +18079,10 @@ export class Runtime {
18125
18079
  this._fastSubPositional = prevFastSubPos;
18126
18080
  }
18127
18081
  }
18128
- execSyncNestedLoopStep(step, rawState, io, monitor, touched, mode, onUpdate) {
18082
+ execSyncNestedLoopStep(step, rawState, io, monitor, touched, mode, progress) {
18129
18083
  const nl = step.nestedLoop;
18130
18084
  const lc = nl.loopCmd;
18131
- let innerLastCmd;
18132
- let innerLastArg = "";
18133
18085
  let innerStatus = 0;
18134
- const updateInner = (v) => {
18135
- innerLastCmd = v.lastCmd;
18136
- innerLastArg = v.lastArg;
18137
- };
18138
18086
  rawState.loopDepth++;
18139
18087
  try {
18140
18088
  if (lc.kind === "arithmetic-for") {
@@ -18148,7 +18096,7 @@ export class Runtime {
18148
18096
  this.budget.loop();
18149
18097
  if ((++turn & 127) === 0)
18150
18098
  runYieldCheckpoint(this.signal);
18151
- this.execSyncLoopSteps(nl.steps, rawState, io, monitor, touched, mode, updateInner);
18099
+ this.execSyncLoopSteps(nl.steps, rawState, io, monitor, touched, mode, progress);
18152
18100
  innerStatus = rawState.status;
18153
18101
  if (this._syncLoopAction !== undefined) {
18154
18102
  const act = this._syncLoopAction;
@@ -18169,7 +18117,7 @@ export class Runtime {
18169
18117
  if ((++turn & 127) === 0)
18170
18118
  runYieldCheckpoint(this.signal);
18171
18119
  rawState.variables[lc.name] = words[i];
18172
- this.execSyncLoopSteps(nl.steps, rawState, io, monitor, touched, mode, updateInner);
18120
+ this.execSyncLoopSteps(nl.steps, rawState, io, monitor, touched, mode, progress);
18173
18121
  innerStatus = rawState.status;
18174
18122
  if (this._syncLoopAction !== undefined) {
18175
18123
  const act = this._syncLoopAction;
@@ -18186,17 +18134,17 @@ export class Runtime {
18186
18134
  const condOk = nl.condExpr !== undefined
18187
18135
  ? (this.tryEvalConditionalSync(nl.condExpr, rawState, monitor, arrayStore(rawState), io, nl.condLine) ?? 1) === 0
18188
18136
  : this.evalSyncLoopArithStmt(nl.condArith, rawState, io, touched, nl.condLine);
18189
- if (nl.condCmd?.kind === "simple") {
18190
- innerLastCmd = nl.condCmd;
18191
- innerLastArg = this.fastValueWord(nl.condCmd.words[nl.condCmd.words.length - 1], rawState, io, false, false, false, true);
18192
- }
18137
+ progress.lastCmd = nl.condCmd;
18138
+ if (nl.condCmd?.kind === "simple")
18139
+ progress.lastArg = this.fastValueWord(nl.condCmd.words[nl.condCmd.words.length - 1], rawState, io, false, false, false, true);
18193
18140
  rawState.status = condOk ? 0 : 1;
18141
+ progress.pipelineStatus = rawState.status;
18194
18142
  if (condOk !== (lc.kind === "while"))
18195
18143
  break;
18196
18144
  this.budget.loop();
18197
18145
  if ((++turn & 127) === 0)
18198
18146
  runYieldCheckpoint(this.signal);
18199
- this.execSyncLoopSteps(nl.steps, rawState, io, monitor, touched, mode, updateInner);
18147
+ this.execSyncLoopSteps(nl.steps, rawState, io, monitor, touched, mode, progress);
18200
18148
  innerStatus = rawState.status;
18201
18149
  if (this._syncLoopAction !== undefined) {
18202
18150
  const act = this._syncLoopAction;
@@ -18211,17 +18159,15 @@ export class Runtime {
18211
18159
  rawState.loopDepth--;
18212
18160
  }
18213
18161
  rawState.status = innerStatus;
18214
- if (innerLastCmd)
18215
- onUpdate({ lastCmd: innerLastCmd, lastArg: innerLastArg });
18216
18162
  }
18217
- execSyncCaseStep(step, rawState, io, monitor, touched, mode, onUpdate) {
18163
+ execSyncCaseStep(step, rawState, io, monitor, touched, mode, progress) {
18218
18164
  const subj = this.fastValueWord(step.caseSubject, rawState, io, false, false, false, false, 0, step.line);
18219
18165
  const work = { remaining: this.budget.limits.maxExpansionBytes, signal: this.signal, exhausted: () => this.budget.fail("maxExpansionBytes") };
18220
18166
  let chosen;
18221
18167
  for (let ci = 0; ci < step.caseClauses.length; ci++) {
18222
18168
  const cl = step.caseClauses[ci];
18223
18169
  for (let pi = 0; pi < cl.patterns.length; pi++) {
18224
- const pattern = cl.patterns[pi].plain ?? this.tryBuildSyncPatternWord(cl.patterns[pi], rawState, io, step.line);
18170
+ const pattern = this.tryBuildSyncPatternWord(cl.patterns[pi], rawState, io, step.line);
18225
18171
  if (pattern !== undefined && tryMatchesPatternSync(pattern, subj, work, false, false)) {
18226
18172
  chosen = cl.steps;
18227
18173
  break;
@@ -18234,10 +18180,10 @@ export class Runtime {
18234
18180
  rawState.status = 0;
18235
18181
  }
18236
18182
  else {
18237
- this.execSyncLoopSteps(chosen, rawState, io, monitor, touched, mode, onUpdate);
18183
+ this.execSyncLoopSteps(chosen, rawState, io, monitor, touched, mode, progress);
18238
18184
  }
18239
18185
  }
18240
- execSyncIfStep(step, rawState, io, monitor, touched, mode, onUpdate) {
18186
+ execSyncIfStep(step, rawState, io, monitor, touched, mode, progress) {
18241
18187
  let chosen;
18242
18188
  for (let bi = 0; bi < step.ifBranches.length; bi++) {
18243
18189
  const br = step.ifBranches[bi];
@@ -18245,9 +18191,11 @@ export class Runtime {
18245
18191
  const condOk = br.condExpr !== undefined
18246
18192
  ? (this.tryEvalConditionalSync(br.condExpr, rawState, monitor, arrayStore(rawState), io, br.condLine) ?? 1) === 0
18247
18193
  : this.evalSyncLoopArithStmt(br.cond, rawState, io, touched, br.condLine);
18194
+ progress.lastCmd = br.condCmd;
18248
18195
  if (br.condCmd.kind === "simple")
18249
- onUpdate({ lastCmd: br.condCmd, lastArg: this.fastValueWord(br.condCmd.words[br.condCmd.words.length - 1], rawState, io, false, false, false, true) });
18196
+ progress.lastArg = this.fastValueWord(br.condCmd.words[br.condCmd.words.length - 1], rawState, io, false, false, false, true);
18250
18197
  rawState.status = condOk ? 0 : 1;
18198
+ progress.pipelineStatus = rawState.status;
18251
18199
  if (condOk) {
18252
18200
  chosen = br.steps;
18253
18201
  break;
@@ -18259,83 +18207,63 @@ export class Runtime {
18259
18207
  rawState.status = 0;
18260
18208
  }
18261
18209
  else {
18262
- this.execSyncLoopSteps(chosen, rawState, io, monitor, touched, mode, onUpdate);
18210
+ this.execSyncLoopSteps(chosen, rawState, io, monitor, touched, mode, progress);
18263
18211
  }
18264
18212
  }
18265
- execSyncLoopSteps(steps, rawState, io, monitor, touched, mode, onUpdate) {
18266
- let lastCmd;
18267
- let lastArg = rawState.lastArgument ?? "";
18213
+ execSyncLoopSteps(steps, rawState, io, monitor, touched, mode, progress, deferredMask = 0) {
18268
18214
  for (let b = 0; b < steps.length; b++) {
18269
18215
  const step = steps[b];
18270
18216
  if (step.listOperator !== undefined && ((step.listOperator === "&&" && rawState.status !== 0) || (step.listOperator === "||" && rawState.status === 0)))
18271
18217
  continue;
18272
- if (step.caseClauses === undefined && step.ifBranches === undefined && step.nestedLoop === undefined)
18273
- lastCmd = step.cmd;
18274
18218
  this.budget.tick();
18275
- if (step.loopAction !== undefined) {
18276
- lastArg = step.cmd.words[step.cmd.words.length - 1].plain;
18277
- rawState.status = 0;
18278
- this._syncLoopAction = step.loopAction;
18279
- onUpdate({ lastCmd, lastArg });
18280
- break;
18281
- }
18282
- if (step.unsetVars !== undefined) {
18283
- lastArg = this.execSyncUnsetStep(step, rawState, monitor, touched);
18284
- rawState.status = 0;
18285
- onUpdate({ lastCmd, lastArg });
18286
- continue;
18287
- }
18288
- if (step.localDecl !== undefined) {
18289
- lastArg = this.execSyncLocalDeclStep(step.localDecl, rawState, io, monitor, touched, step.line);
18290
- rawState.status = 0;
18291
- onUpdate({ lastCmd, lastArg });
18219
+ // Compound commands return their body's status, but only executed pipelines
18220
+ // update PIPESTATUS. Share progress so empty branches and loops preserve it.
18221
+ if (step.nestedLoop !== undefined || step.fnCall !== undefined || step.caseClauses !== undefined || step.ifBranches !== undefined) {
18222
+ this.flushSyncStdoutBatch(io);
18223
+ if (step.nestedLoop !== undefined)
18224
+ this.execSyncNestedLoopStep(step, rawState, io, monitor, touched, mode, progress);
18225
+ else if (step.fnCall !== undefined)
18226
+ this.execSyncFnStep(step, rawState, io, monitor, touched, mode, progress);
18227
+ else if (step.caseClauses !== undefined)
18228
+ this.execSyncCaseStep(step, rawState, io, monitor, touched, mode, progress);
18229
+ else
18230
+ this.execSyncIfStep(step, rawState, io, monitor, touched, mode, progress);
18231
+ if (this._syncLoopAction !== undefined)
18232
+ break;
18292
18233
  continue;
18293
18234
  }
18294
- if (step.shiftCount !== undefined) {
18295
- const shRes = this.execSyncShiftStep(step.shiftCount, step.cmd, rawState);
18296
- lastArg = shRes.lastArg;
18297
- rawState.status = shRes.status;
18298
- onUpdate({ lastCmd, lastArg });
18299
- continue;
18235
+ progress.lastCmd = step.cmd;
18236
+ let status = 0;
18237
+ if (step.loopAction !== undefined) {
18238
+ progress.lastArg = step.cmd.words[step.cmd.words.length - 1].plain;
18239
+ this._syncLoopAction = step.loopAction;
18300
18240
  }
18301
- if (step.readHereString !== undefined) {
18302
- lastArg = this.execSyncReadHereStringStep(step.readHereString, step, rawState, io, monitor, touched);
18303
- onUpdate({ lastCmd, lastArg });
18304
- continue;
18241
+ else if (step.unsetVars !== undefined) {
18242
+ progress.lastArg = this.execSyncUnsetStep(step, rawState, monitor, touched);
18305
18243
  }
18306
- if (step.nestedLoop !== undefined) {
18307
- this.execSyncNestedLoopStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; onUpdate(v); });
18308
- continue;
18244
+ else if (step.localDecl !== undefined) {
18245
+ progress.lastArg = this.execSyncLocalDeclStep(step.localDecl, rawState, io, monitor, touched, step.line);
18309
18246
  }
18310
- else if (step.fnCall !== undefined) {
18311
- this.execSyncFnStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; onUpdate(v); });
18312
- continue;
18247
+ else if (step.shiftCount !== undefined) {
18248
+ const result = this.execSyncShiftStep(step.shiftCount, step.cmd, rawState);
18249
+ progress.lastArg = result.lastArg;
18250
+ status = result.status;
18313
18251
  }
18314
- else if (step.caseClauses !== undefined) {
18315
- this.execSyncCaseStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; onUpdate(v); });
18316
- if (this._syncLoopAction !== undefined)
18317
- break;
18318
- continue;
18252
+ else if (step.readHereString !== undefined) {
18253
+ progress.lastArg = this.execSyncReadHereStringStep(step.readHereString, step, rawState, io, monitor, touched);
18254
+ status = rawState.status;
18319
18255
  }
18320
- else if (step.ifBranches !== undefined) {
18321
- this.execSyncIfStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; onUpdate(v); });
18322
- if (this._syncLoopAction !== undefined)
18323
- break;
18324
- continue;
18256
+ else if (deferredMask & (1 << b)) {
18257
+ progress.lastArg = "";
18325
18258
  }
18326
18259
  else if (step.condStmt !== undefined) {
18327
- const cStatus = this.tryEvalConditionalSync(step.condStmt, rawState, monitor, arrayStore(rawState), io, step.line) ?? 1;
18260
+ status = this.tryEvalConditionalSync(step.condStmt, rawState, monitor, arrayStore(rawState), io, step.line) ?? 1;
18328
18261
  if (step.cmd.kind === "simple") {
18329
- lastArg = this.fastValueWord(step.cmd.words[step.cmd.words.length - 1], rawState, io, false, false, false, true);
18330
- onUpdate({ lastCmd, lastArg });
18262
+ progress.lastArg = this.fastValueWord(step.cmd.words[step.cmd.words.length - 1], rawState, io, false, false, false, true);
18331
18263
  }
18332
- rawState.status = cStatus;
18333
- continue;
18334
18264
  }
18335
18265
  else if (step.arithStmt !== undefined) {
18336
- const nonZero = this.evalSyncLoopArithStmt(step.arithStmt, rawState, io, touched, step.line);
18337
- rawState.status = nonZero ? 0 : 1;
18338
- continue;
18266
+ status = this.evalSyncLoopArithStmt(step.arithStmt, rawState, io, touched, step.line) ? 0 : 1;
18339
18267
  }
18340
18268
  else if (step.coalesceNext) {
18341
18269
  const nextStep = steps[++b];
@@ -18345,8 +18273,8 @@ export class Runtime {
18345
18273
  this.budget.fileSystemOperation();
18346
18274
  this.budget.fileSystemOperation();
18347
18275
  this.budget.bytes += encoded.byteLength;
18348
- lastCmd = nextStep.cmd;
18349
- lastArg = this.evalSyncRedirectWord(nextStep.value, rawState, io);
18276
+ progress.lastCmd = nextStep.cmd;
18277
+ progress.lastArg = this.evalSyncRedirectWord(nextStep.value, rawState, io);
18350
18278
  }
18351
18279
  else if (step.targetWord !== undefined && step.value !== undefined) {
18352
18280
  if (this.isSimpleRedirectEchoWord(step.value)) {
@@ -18354,7 +18282,7 @@ export class Runtime {
18354
18282
  this.writeSyncRedirectStep(step, encoded, step.append, mode, rawState, io);
18355
18283
  this.budget.fileSystemOperation();
18356
18284
  this.budget.bytes += encoded.byteLength;
18357
- lastArg = this.evalSyncRedirectWord(step.value, rawState, io);
18285
+ progress.lastArg = this.evalSyncRedirectWord(step.value, rawState, io);
18358
18286
  }
18359
18287
  else {
18360
18288
  const val = this.fastValueWord(step.value, rawState, io, false, false, false, false, 0, step.line);
@@ -18362,31 +18290,31 @@ export class Runtime {
18362
18290
  this.writeSyncRedirectStep(step, encoded, step.append, mode, rawState, io);
18363
18291
  this.budget.fileSystemOperation();
18364
18292
  this.budget.bytes += encoded.byteLength;
18365
- lastArg = val;
18293
+ progress.lastArg = val;
18366
18294
  }
18367
18295
  }
18368
18296
  else if (step.targetWord !== undefined && step.printfVArgs !== undefined) {
18369
- const { formatted, lastArg: pLastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
18297
+ const { formatted, lastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
18370
18298
  const encoded = fastSharedTextEncoder.encode(formatted);
18371
18299
  this.writeSyncRedirectStep(step, encoded, step.append, mode, rawState, io);
18372
18300
  this.budget.fileSystemOperation();
18373
18301
  this.budget.bytes += encoded.byteLength;
18374
- lastArg = pLastArg;
18302
+ progress.lastArg = lastArg;
18375
18303
  }
18376
18304
  else if (step.arrayAssign !== undefined) {
18377
18305
  if (!this.tryFastArrayAssignmentSync(step.arrayAssign, rawState, io, step.line, undefined, undefined, true)) {
18378
18306
  throw new Error("Synchronous loop array assignment was not executable");
18379
18307
  }
18380
- lastArg = "";
18308
+ progress.lastArg = "";
18381
18309
  }
18382
18310
  else if (step.printfVArgs !== undefined && step.name !== undefined) {
18383
- const { formatted, lastArg: pLastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
18311
+ const { formatted, lastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
18384
18312
  rawState.variables[step.name] = formatted;
18385
18313
  touched.add(step.name);
18386
- lastArg = pLastArg;
18314
+ progress.lastArg = lastArg;
18387
18315
  }
18388
18316
  else if (step.isDiscardDevNull && step.discardWords !== undefined) {
18389
- lastArg = this.runSyncDiscardStep(step, rawState, io);
18317
+ progress.lastArg = this.runSyncDiscardStep(step, rawState, io);
18390
18318
  }
18391
18319
  else if (step.name !== undefined && step.value !== undefined) {
18392
18320
  rawState.substitutionStatus = 0;
@@ -18399,179 +18327,37 @@ export class Runtime {
18399
18327
  else
18400
18328
  rawState.variables[step.name] = val;
18401
18329
  touched.add(step.name);
18402
- lastArg = "";
18330
+ progress.lastArg = "";
18331
+ status = rawState.substitutionStatus;
18403
18332
  }
18404
18333
  else if (step.isStdoutEcho && step.value !== undefined) {
18405
18334
  const val = this.fastValueWord(step.value, rawState, io, false, false, false, false, 0, step.line);
18406
18335
  this.writeSyncStdoutText(this.formatSyncEchoLine(val), io);
18407
- lastArg = val;
18336
+ progress.lastArg = val;
18408
18337
  }
18409
18338
  else if (step.isStdoutEcho && step.printfVArgs !== undefined) {
18410
- const { formatted, lastArg: pLastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
18339
+ const { formatted, lastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
18411
18340
  this.writeSyncStdoutText(formatted, io);
18412
- lastArg = pLastArg;
18341
+ progress.lastArg = lastArg;
18413
18342
  }
18414
18343
  else {
18415
- lastArg = step.cmd.words[0].plain;
18344
+ progress.lastArg = step.cmd.words[0].plain;
18416
18345
  }
18417
- rawState.status = step.name !== undefined && step.value !== undefined ? rawState.substitutionStatus : 0;
18418
- onUpdate({ lastCmd, lastArg });
18346
+ rawState.status = status;
18347
+ progress.pipelineStatus = status;
18348
+ if (this._syncLoopAction !== undefined)
18349
+ break;
18419
18350
  }
18420
18351
  }
18421
18352
  runSyncForFallback(varName, fastLoopWords, bodyAssignments, rawState, io, monitor, touched, mode) {
18422
- let lastCmd;
18423
- let lastArg = rawState.lastArgument ?? "";
18353
+ const progress = { lastCmd: undefined, lastArg: rawState.lastArgument ?? "", pipelineStatus: undefined };
18424
18354
  let loopTurn = 0;
18425
18355
  for (let idx = 0; idx < fastLoopWords.length; idx++) {
18426
18356
  this.budget.loop();
18427
18357
  if ((++loopTurn & 127) === 0)
18428
18358
  runYieldCheckpoint(this.signal);
18429
18359
  rawState.variables[varName] = fastLoopWords[idx];
18430
- for (let b = 0; b < bodyAssignments.length; b++) {
18431
- const step = bodyAssignments[b];
18432
- if (step.listOperator !== undefined && ((step.listOperator === "&&" && rawState.status !== 0) || (step.listOperator === "||" && rawState.status === 0)))
18433
- continue;
18434
- if (step.caseClauses === undefined && step.ifBranches === undefined && step.nestedLoop === undefined)
18435
- lastCmd = step.cmd;
18436
- this.budget.tick();
18437
- if (step.loopAction !== undefined) {
18438
- lastArg = step.cmd.words[step.cmd.words.length - 1].plain;
18439
- rawState.status = 0;
18440
- this._syncLoopAction = step.loopAction;
18441
- break;
18442
- }
18443
- if (step.unsetVars !== undefined) {
18444
- lastArg = this.execSyncUnsetStep(step, rawState, monitor, touched);
18445
- rawState.status = 0;
18446
- continue;
18447
- }
18448
- if (step.localDecl !== undefined) {
18449
- lastArg = this.execSyncLocalDeclStep(step.localDecl, rawState, io, monitor, touched, step.line);
18450
- rawState.status = 0;
18451
- continue;
18452
- }
18453
- if (step.shiftCount !== undefined) {
18454
- const shRes = this.execSyncShiftStep(step.shiftCount, step.cmd, rawState);
18455
- lastArg = shRes.lastArg;
18456
- rawState.status = shRes.status;
18457
- continue;
18458
- }
18459
- if (step.readHereString !== undefined) {
18460
- lastArg = this.execSyncReadHereStringStep(step.readHereString, step, rawState, io, monitor, touched);
18461
- continue;
18462
- }
18463
- if (step.coalesceNext) {
18464
- const nextStep = bodyAssignments[++b];
18465
- this.budget.tick();
18466
- const encoded = this.encodeSyncRedirectWordsToScratch(step.value, nextStep.value, rawState, io);
18467
- this.writeSyncRedirectStep(step, encoded, false, mode, rawState, io);
18468
- this.budget.fileSystemOperation();
18469
- this.budget.fileSystemOperation();
18470
- this.budget.bytes += encoded.byteLength;
18471
- lastCmd = nextStep.cmd;
18472
- lastArg = this.evalSyncRedirectWord(nextStep.value, rawState, io) ?? "";
18473
- }
18474
- else if (step.targetWord !== undefined && step.value !== undefined) {
18475
- if (this.isSimpleRedirectEchoWord(step.value)) {
18476
- const encoded = this.encodeSyncRedirectWordsToScratch(step.value, undefined, rawState, io);
18477
- this.writeSyncRedirectStep(step, encoded, step.append, mode, rawState, io);
18478
- this.budget.fileSystemOperation();
18479
- this.budget.bytes += encoded.byteLength;
18480
- lastArg = this.evalSyncRedirectWord(step.value, rawState, io) ?? "";
18481
- }
18482
- else {
18483
- const val = this.fastValueWord(step.value, rawState, io, false, false, false, false, 0, step.line);
18484
- const encoded = fastSharedTextEncoder.encode(this.formatSyncEchoLine(val));
18485
- this.writeSyncRedirectStep(step, encoded, step.append, mode, rawState, io);
18486
- this.budget.fileSystemOperation();
18487
- this.budget.bytes += encoded.byteLength;
18488
- lastArg = val;
18489
- }
18490
- }
18491
- else if (step.targetWord !== undefined && step.printfVArgs !== undefined) {
18492
- const { formatted, lastArg: pLastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
18493
- const encoded = fastSharedTextEncoder.encode(formatted);
18494
- this.writeSyncRedirectStep(step, encoded, step.append, mode, rawState, io);
18495
- this.budget.fileSystemOperation();
18496
- this.budget.bytes += encoded.byteLength;
18497
- lastArg = pLastArg;
18498
- }
18499
- else if (step.nestedLoop !== undefined) {
18500
- this.execSyncNestedLoopStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
18501
- continue;
18502
- }
18503
- else if (step.fnCall !== undefined) {
18504
- this.execSyncFnStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
18505
- continue;
18506
- }
18507
- else if (step.caseClauses !== undefined) {
18508
- this.execSyncCaseStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
18509
- if (this._syncLoopAction !== undefined)
18510
- break;
18511
- continue;
18512
- }
18513
- else if (step.ifBranches !== undefined) {
18514
- this.execSyncIfStep(step, rawState, io, monitor, touched, mode, v => { lastCmd = v.lastCmd; lastArg = v.lastArg; });
18515
- if (this._syncLoopAction !== undefined)
18516
- break;
18517
- continue;
18518
- }
18519
- else if (step.condStmt !== undefined) {
18520
- const cStatus = this.tryEvalConditionalSync(step.condStmt, rawState, monitor, arrayStore(rawState), io, step.line) ?? 1;
18521
- if (step.cmd.kind === "simple") {
18522
- lastArg = this.fastValueWord(step.cmd.words[step.cmd.words.length - 1], rawState, io, false, false, false, true);
18523
- }
18524
- rawState.status = cStatus;
18525
- continue;
18526
- }
18527
- else if (step.arrayAssign !== undefined) {
18528
- if (!this.tryFastArrayAssignmentSync(step.arrayAssign, rawState, io, step.line, undefined, undefined, true)) {
18529
- throw new Error("Synchronous loop array assignment was not executable");
18530
- }
18531
- lastArg = "";
18532
- }
18533
- else if (step.arithStmt !== undefined) {
18534
- const nonZero = this.evalSyncLoopArithStmt(step.arithStmt, rawState, io, touched, step.line);
18535
- rawState.status = nonZero ? 0 : 1;
18536
- continue;
18537
- }
18538
- else if (step.printfVArgs !== undefined && step.name !== undefined) {
18539
- const { formatted, lastArg: pLastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line);
18540
- rawState.variables[step.name] = formatted;
18541
- touched.add(step.name);
18542
- lastArg = pLastArg;
18543
- }
18544
- else if (step.isDiscardDevNull && step.discardWords !== undefined) {
18545
- lastArg = this.runSyncDiscardStep(step, rawState, io);
18546
- }
18547
- else if (step.name !== undefined && step.value !== undefined) {
18548
- rawState.substitutionStatus = 0;
18549
- const val = this.fastValueWord(step.value, rawState, io, false, false, false, false, 0, step.line);
18550
- if (step.append) {
18551
- const curRaw = rawState.variables[step.name];
18552
- const curStr = curRaw === undefined ? "" : (touched.has(step.name) ? curRaw : (monitor.values.get(step.name, curRaw) ?? curRaw));
18553
- rawState.variables[step.name] = (typeof curStr === "string" ? curStr : "") + val;
18554
- }
18555
- else
18556
- rawState.variables[step.name] = val;
18557
- touched.add(step.name);
18558
- lastArg = "";
18559
- }
18560
- else if (step.isStdoutEcho && step.value !== undefined) {
18561
- const val = this.fastValueWord(step.value, rawState, io, false, false, false, false, 0, step.line);
18562
- this.writeSyncStdoutText(this.formatSyncEchoLine(val), io);
18563
- lastArg = val;
18564
- }
18565
- else if (step.isStdoutEcho && step.printfVArgs !== undefined) {
18566
- const { formatted, lastArg: pLastArg } = this.evalSyncPrintfStep(step.printfVArgs, rawState, io, step.line, step.cmd.words[0]?.plain === "echo");
18567
- this.writeSyncStdoutText(formatted, io);
18568
- lastArg = pLastArg;
18569
- }
18570
- else {
18571
- lastArg = step.cmd.words[0].plain;
18572
- }
18573
- rawState.status = step.name !== undefined && step.value !== undefined ? rawState.substitutionStatus : 0;
18574
- }
18360
+ this.execSyncLoopSteps(bodyAssignments, rawState, io, monitor, touched, mode, progress);
18575
18361
  if (this._syncLoopAction !== undefined) {
18576
18362
  const act = this._syncLoopAction;
18577
18363
  this._syncLoopAction = undefined;
@@ -18580,7 +18366,7 @@ export class Runtime {
18580
18366
  }
18581
18367
  }
18582
18368
  this.flushSyncStdoutBatch(io);
18583
- return { lastCmd, lastArg };
18369
+ return progress;
18584
18370
  }
18585
18371
  async script(script, state, io, startListIndex = 0, startPipelineIndex = 0, skipFirstSync = false) {
18586
18372
  if (state.extensions?.syntax.indexedDeclarations?.includes("readonly"))
@@ -18711,6 +18497,7 @@ export class Runtime {
18711
18497
  signal.throwIfAborted();
18712
18498
  child.extensions = forkExtensions(state.extensions, "subshell");
18713
18499
  child.isolated = true;
18500
+ child.variables.BASH_SUBSHELL = String(Number(state.variables.BASH_SUBSHELL ?? 0) + 1);
18714
18501
  child.depth++;
18715
18502
  const allocation = this.budget.values.scope();
18716
18503
  scope.register(() => allocation.close());
@@ -18900,11 +18687,12 @@ export class Runtime {
18900
18687
  const isFastPure = isPureStage || runtime.isPureExternalStageCommand(command, rawStateForChild);
18901
18688
  const forkedExt = isFastPure ? forkExtensions(state.extensions, "pipeline") : undefined;
18902
18689
  const child = isFastPure
18903
- ? Object.assign(new RootShellState(rawStateForChild.cwd, rawStateForChild.variables, rawStateForChild.exported, forkedExt), rawStateForChild, {
18690
+ ? Object.assign(cloneRawState(rawStateForChild, false), {
18904
18691
  extensions: forkedExt, isolated: true, _readOnlyStage: true,
18905
18692
  })
18906
18693
  : (tryCloneStateSync(state) ?? await cloneState(state, this.signal));
18907
18694
  preparedChild = child;
18695
+ child.variables.BASH_SUBSHELL = String(Number(state.variables.BASH_SUBSHELL ?? 0) + 1);
18908
18696
  if (!child._readOnlyStage) {
18909
18697
  child.extensions = undefined;
18910
18698
  child.extensions = forkExtensions(state.extensions, "pipeline");
@@ -19199,7 +18987,7 @@ export class Runtime {
19199
18987
  }
19200
18988
  }
19201
18989
  }
19202
- const extDef = this.getExternalCommand(firstName);
18990
+ const extDef = this.commands.get(firstName);
19203
18991
  return extDef !== undefined && !customRegisteredCommands.has(extDef.execute) && !customRegisteredRegistries.has(this.commands);
19204
18992
  }
19205
18993
  publishStatus(state, statuses, io, terminal) {
@@ -19517,7 +19305,7 @@ export class Runtime {
19517
19305
  }
19518
19306
  for (let pIdx = 0; pIdx < clause.patterns.length; pIdx++) {
19519
19307
  const pw = clause.patterns[pIdx];
19520
- const pStr = pw.plain ?? (pw.parts.length === 1 && pw.parts[0].kind === "text" && !pw.parts[0].quoted && !pw.parts[0].value.includes("~") ? pw.parts[0].value : undefined);
19308
+ const pStr = this.tryBuildSyncPatternWord(pw, state, originalIO, diagnosticLine);
19521
19309
  if (pStr === undefined) {
19522
19310
  allFast = false;
19523
19311
  break;
@@ -19841,6 +19629,7 @@ export class Runtime {
19841
19629
  try {
19842
19630
  child.extensions = forkExtensions(state.extensions, "subshell");
19843
19631
  child.isolated = true;
19632
+ child.variables.BASH_SUBSHELL = String(Number(state.variables.BASH_SUBSHELL ?? 0) + 1);
19844
19633
  child.loopDepth = 0;
19845
19634
  if (state.extensions?.checkpoints.length)
19846
19635
  await this.extensionCheckpoint("child-job-install", state, io);
@@ -21188,6 +20977,8 @@ export class Runtime {
21188
20977
  async dispatchFastFunction(name, body, args, state, io, pendingResume) {
21189
20978
  if (!pendingResume && state.depth >= this.budget.limits.maxSubstitutionDepth)
21190
20979
  this.budget.fail("maxSubstitutionDepth");
20980
+ if (!pendingResume && state.functionDepth >= this.budget.limits.maxFunctionDepth)
20981
+ this.budget.fail("maxFunctionDepth");
21191
20982
  const scope = io[invocationScope].child();
21192
20983
  try {
21193
20984
  const monitor = stateMonitor(state);
@@ -21453,7 +21244,7 @@ export class Runtime {
21453
21244
  }
21454
21245
  }
21455
21246
  const scope = io[invocationScope].child();
21456
- const externalDef = typeof name === "string" ? this.getExternalCommand(name) : undefined;
21247
+ const externalDef = typeof name === "string" ? this.commands.get(name) : undefined;
21457
21248
  const fastInline = !state.externalInvocation && this.middleware.length === 0 && typeof name === "string" && (!externalDef || (!customRegisteredCommands.has(externalDef.execute) && !customRegisteredRegistries.has(this.commands))) && !(!bypassFunctions && state.functions.has(name)) && !state.extensions?.builtins.has(name) && name !== "." && name !== "source" && name !== "eval" && name !== "command" && name !== "builtin" && name !== "type" && name !== "read" && name !== "mapfile" && name !== "readarray";
21458
21249
  if (fastInline && externalDef !== undefined && values.every(value => typeof value === "string") && !implementedBuiltins.has(name) && !(name === "printf" && externalDef.execute === printfCommand.execute && args[0]?.startsWith("-v"))) {
21459
21250
  try {
@@ -21700,6 +21491,8 @@ export class Runtime {
21700
21491
  ensureRuntimeContext();
21701
21492
  if (state.depth >= this.budget.limits.maxSubstitutionDepth)
21702
21493
  this.budget.fail("maxSubstitutionDepth");
21494
+ if (state.functionDepth >= this.budget.limits.maxFunctionDepth)
21495
+ this.budget.fail("maxFunctionDepth");
21703
21496
  const positional = state.positional;
21704
21497
  const savedPositionals = stateMonitor(state).positionals.clone();
21705
21498
  const positionalSetVersion = state.positionalSetVersion ?? 0;
@@ -21909,7 +21702,7 @@ export class Runtime {
21909
21702
  return { exitCode: builtin };
21910
21703
  }
21911
21704
  }
21912
- const definition = this.getExternalCommand(context.command);
21705
+ const definition = this.commands.get(context.command);
21913
21706
  if (context.command === "printf" && definition?.execute === printfCommand.execute && context.args[0]?.startsWith("-v")) {
21914
21707
  ensureRuntimeContext();
21915
21708
  return { exitCode: await this.printfVariable(context, state, assignments) };
@@ -22003,7 +21796,7 @@ export class Runtime {
22003
21796
  matches.push({ kind: "function", name });
22004
21797
  if (implementedBuiltins.has(name) || state.extensions?.builtins.has(name))
22005
21798
  matches.push({ kind: "builtin", name });
22006
- else if (this.hasExternalCommand(name))
21799
+ else if (this.commands.has(name))
22007
21800
  matches.push({ kind: "command", name });
22008
21801
  else if (name === "bash" || name === "sh")
22009
21802
  matches.push({ kind: "interpreter", name });
@@ -22052,23 +21845,12 @@ export class Runtime {
22052
21845
  return "function";
22053
21846
  if (isBuiltin)
22054
21847
  return "builtin";
22055
- if (this.hasExternalCommand(name))
21848
+ if (this.commands.has(name))
22056
21849
  return "command";
22057
21850
  if (name === "bash" || name === "sh")
22058
21851
  return "interpreter";
22059
21852
  return undefined;
22060
21853
  }
22061
- getExternalCommand(name) {
22062
- const direct = this.commands.get(name);
22063
- if (direct)
22064
- return direct;
22065
- if (this.commands.has("rg") || this.commands.has("grep"))
22066
- return getRuntimeMuscleMemoryCommand(name);
22067
- return undefined;
22068
- }
22069
- hasExternalCommand(name) {
22070
- return this.getExternalCommand(name) !== undefined;
22071
- }
22072
21854
  async discoveryBuiltin(context, state, io, assignments, inheritedDefaultPath = false) {
22073
21855
  const args = [...context.args];
22074
21856
  const command = context.command === "command";
@@ -22267,13 +22049,20 @@ export class Runtime {
22267
22049
  const option = args.shift();
22268
22050
  if (option === "--" || option === "-")
22269
22051
  break;
22052
+ if (option === "--version") {
22053
+ await writeDiagnostic(context.stdout, "safe-bash (poe-code)\n");
22054
+ return 0;
22055
+ }
22056
+ if (option === "--login" || option === "--norc" || option === "--noprofile" || option === "--posix") {
22057
+ continue;
22058
+ }
22270
22059
  const enabled = option[0] === "-";
22271
22060
  if ((option === "-o" || option === "+o") && Object.hasOwn(options, args[0] ?? "")) {
22272
22061
  options[args.shift()] = enabled;
22273
22062
  continue;
22274
22063
  }
22275
22064
  const flags = option.slice(1);
22276
- if (!flags.length || [...flags].some(flag => !Object.hasOwn(flagsByName, flag) && !(enabled && (flag === "c" || flag === "s")))) {
22065
+ if (!flags.length || [...flags].some(flag => !Object.hasOwn(flagsByName, flag) && !(enabled && (flag === "c" || flag === "s" || flag === "l" || flag === "i")))) {
22277
22066
  await writeDiagnostic(context.stderr, `${context.command}: ${option}: unsupported option; supported flags are -c, -s, +/-a, +/-e, +/-u, +/-n, +/-B, +/-f, +/-C and +/-o ${Object.keys(options).join(", ")}\n`);
22278
22067
  return 2;
22279
22068
  }
@@ -23796,6 +23585,9 @@ export class Runtime {
23796
23585
  await writeDiagnostic(context.stderr, `printf: ${name}: readonly variable\n`);
23797
23586
  return 1;
23798
23587
  }
23588
+ // Bash ignores assignments to its function-stack variable.
23589
+ if (name === "FUNCNAME")
23590
+ return status;
23799
23591
  if (index || arrayStore(state)?.get(name)) {
23800
23592
  const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
23801
23593
  const decode = (bytes) => {
@@ -24722,7 +24514,8 @@ export class Runtime {
24722
24514
  let shadow;
24723
24515
  try {
24724
24516
  const tickets = operation.reserve({ generation: true, version: true, epoch: true, work: 8 });
24725
- shadow = IndexedBinding.create(store.owner);
24517
+ if (enabled.has("I"))
24518
+ shadow = await store.get(name).copy(this.signal);
24726
24519
  this.signal.throwIfAborted();
24727
24520
  if (state.readonlyVariables?.has(name))
24728
24521
  throw new ArrayFailure("readonly binding");
@@ -24731,7 +24524,7 @@ export class Runtime {
24731
24524
  let released;
24732
24525
  stateMonitor(state).publish(tickets, name, () => {
24733
24526
  locals.set(name, saved);
24734
- released = store.publish(name, shadow, tickets);
24527
+ released = shadow ? store.publish(name, shadow, tickets) : store.remove(name, tickets);
24735
24528
  });
24736
24529
  shadow = undefined;
24737
24530
  await released;
@@ -25627,6 +25420,7 @@ export class Runtime {
25627
25420
  const capture = new Capture();
25628
25421
  const child = await cloneState(state, this.signal);
25629
25422
  child.isolated = true;
25423
+ child.variables.BASH_SUBSHELL = String(Number(state.variables.BASH_SUBSHELL ?? 0) + 1);
25630
25424
  child.extensions = forkExtensions(state.extensions, "substitution");
25631
25425
  if (state.profile !== "sh")
25632
25426
  child.errexit = false;
@@ -25680,6 +25474,7 @@ export class Runtime {
25680
25474
  }
25681
25475
  const child = await cloneState(state, this.signal);
25682
25476
  child.isolated = true;
25477
+ child.variables.BASH_SUBSHELL = String(Number(state.variables.BASH_SUBSHELL ?? 0) + 1);
25683
25478
  child.extensions = forkExtensions(state.extensions, "substitution");
25684
25479
  if (state.profile !== "sh")
25685
25480
  child.errexit = false;
@@ -25733,6 +25528,7 @@ export class Runtime {
25733
25528
  const capture = new Capture();
25734
25529
  const child = await cloneState(state, this.signal);
25735
25530
  child.isolated = true;
25531
+ child.variables.BASH_SUBSHELL = String(Number(state.variables.BASH_SUBSHELL ?? 0) + 1);
25736
25532
  child.extensions = forkExtensions(state.extensions, "substitution");
25737
25533
  if (state.profile !== "sh")
25738
25534
  child.errexit = false;
@@ -25835,7 +25631,7 @@ export class Runtime {
25835
25631
  if (part.length)
25836
25632
  return String(binding?.values.size ?? (part.name === "FUNCNAME" && state.variables.FUNCNAME === undefined ? state.functionNames?.length ?? 0 : state.variables[part.name] === undefined ? 0 : 1));
25837
25633
  const values = await this.arrayMembers(part.name, state, io, selector.kind === "keys" || part.keys === true, part.substring);
25838
- const space = (selector.kind === "keys" || part.keys === true) ? Boolean(hereDocument || (selector.separator === "@" ? !part.quoted && !split || state.variables.IFS === "" : !part.quoted && split && state.variables.IFS === "")) : (!split && selector.separator === "@");
25634
+ const space = (selector.kind === "keys" || part.keys === true) ? Boolean(hereDocument || (selector.separator === "@" ? !part.quoted && !split || state.variables.IFS === "" : !part.quoted && split && state.variables.IFS === "")) : (!split && selector.separator === "@" && (!part.substring || !part.quoted || state.variables.IFS === ""));
25839
25635
  return this.arrayJoin(store.owner, values, space ? " " : this.ifsSeparator(state, io));
25840
25636
  }
25841
25637
  if (part.substring && (part.name === "@" || part.name === "*")) {
@@ -25859,7 +25655,7 @@ export class Runtime {
25859
25655
  const name = this.referenceName(state, part.name);
25860
25656
  const binding = arrayStore(state)?.get(name);
25861
25657
  const index = binding?.associative ? binding.keys.get("30")?.index ?? -1 : 0;
25862
- retained = binding?.getValue(index) ?? stateMonitor(state)?.values.get(name, value) ?? value;
25658
+ retained = name === "RANDOM" || name === "SECONDS" || name === "LINENO" ? value : binding?.getValue(index) ?? stateMonitor(state)?.values.get(name, value) ?? value;
25863
25659
  }
25864
25660
  else if (/^0+$/u.test(part.name))
25865
25661
  retained = stateMonitor(state)?.positionals.get(zeroPositionKey, value) ?? value;
@@ -26263,6 +26059,8 @@ export class Runtime {
26263
26059
  let out = "";
26264
26060
  for (let i = 0; i < word.parts.length; i++) {
26265
26061
  let resolvedPart = word.parts[i];
26062
+ if (resolvedPart.kind === "variable" && (resolveSyncNameref(rawState, resolvedPart.name) === "RANDOM" || resolveSyncNameref(rawState, resolvedPart.name) === "SECONDS"))
26063
+ return undefined;
26266
26064
  if (resolvedPart.kind === "variable" && !resolvedPart.prefixNames && rawState.variableAttributes?.get(resolvedPart.name)?.includes("n")) {
26267
26065
  if (resolvedPart.indirect)
26268
26066
  return undefined;
@@ -26477,7 +26275,7 @@ export class Runtime {
26477
26275
  }
26478
26276
  if (part.indirect || part.specialParameter)
26479
26277
  return undefined;
26480
- if (part.name === "@" || part.name === "*" || part.name === "PIPESTATUS" || part.name === "LINENO" || part.name === "_" || part.name === "FUNCNAME" || part.name === "DIRSTACK")
26278
+ if (part.name === "@" || part.name === "*" || part.name === "PIPESTATUS" || part.name === "LINENO" || part.name === "BASH_SUBSHELL" || part.name === "_" || part.name === "FUNCNAME" || part.name === "DIRSTACK")
26481
26279
  return undefined;
26482
26280
  if (!isShellIdentifier(part.name))
26483
26281
  return undefined;
@@ -26558,7 +26356,7 @@ export class Runtime {
26558
26356
  }
26559
26357
  const ifsVal = monitor?.values.get("IFS", rawVars.IFS ?? " ") ?? rawVars.IFS ?? " ";
26560
26358
  if (validElemOp && typeof ifsVal === "string" && (ifsVal.length === 0 || ifsVal.charCodeAt(0) < 128)) {
26561
- const sep = selector.separator === "@" && (ifsVal.length === 0 || !isKeys && part.operator === undefined) ? " " : ifsVal.length > 0 ? ifsVal[0] : "";
26359
+ const sep = selector.separator === "@" && (ifsVal.length === 0 || !isKeys && part.operator === undefined && !part.substring) ? " " : ifsVal.length > 0 ? ifsVal[0] : "";
26562
26360
  const parameterLine = part.line ?? overrideDiagnosticLine;
26563
26361
  const evalSliceInt = (w) => {
26564
26362
  if (w.parts.length === 0)
@@ -26673,20 +26471,9 @@ export class Runtime {
26673
26471
  return undefined;
26674
26472
  }
26675
26473
  if (selector.kind === "element") {
26676
- const cachedSub = selector.index;
26677
- let subWord = selector.index.word ?? (cachedSub._cachedSyntax === rawState.extensions?.syntax ? cachedSub._cachedWord : undefined);
26678
- if (!subWord) {
26679
- if (byteLocale(rawVars) || rawState.depth >= 24)
26680
- return undefined;
26681
- try {
26682
- subWord = parseArraySubscript(selector.index.source ?? selector.index.decimal, this.budget.parsing, false, rawState.depth, false, rawState.extensions?.syntax);
26683
- cachedSub._cachedWord = subWord;
26684
- cachedSub._cachedSyntax = rawState.extensions?.syntax;
26685
- }
26686
- catch {
26687
- return undefined;
26688
- }
26689
- }
26474
+ const subWord = this.syncArraySubscriptWord(selector.index, rawState);
26475
+ if (!subWord)
26476
+ return undefined;
26690
26477
  const subVal = this.fastValueWord(subWord, rawState, io, false, false, false, false, undefined, part.line ?? overrideDiagnosticLine);
26691
26478
  if (typeof subVal !== "string")
26692
26479
  return undefined;
@@ -26861,6 +26648,14 @@ export class Runtime {
26861
26648
  if (part.length || part.operator !== undefined || this.budget.limits.maxExpansionBytes !== Infinity || rawState.depth + (io.parameterDepth ?? 0) >= 60 || !part.substring.offset.parts.every(p => p.kind === "text" || p.kind === "arithmetic" || (p.kind === "variable" && !p.operator && !p.substring)) || (part.substring.length && !part.substring.length.parts.every(p => p.kind === "text" || p.kind === "arithmetic" || (p.kind === "variable" && !p.operator && !p.substring))) || ValueScope.prototype.reserve !== defaultValueScopeReserve || String.prototype.codePointAt !== defaultStringCodePointAt || globalThis.Float64Array !== defaultFloat64Array || (!part.substring.offset.parts.length && !part.substring.length)) {
26862
26649
  return undefined;
26863
26650
  }
26651
+ // Resolve the parameter before expanding either arithmetic operand.
26652
+ const raw = rawVars[part.name];
26653
+ this.requireParameter(raw, part.name, state, io, part.line ?? overrideDiagnosticLine);
26654
+ if (raw === undefined) {
26655
+ if (split && !part.quoted)
26656
+ return undefined;
26657
+ continue;
26658
+ }
26864
26659
  const parameterLine = part.line ?? overrideDiagnosticLine;
26865
26660
  const evalSubInt = (w) => {
26866
26661
  if (w.parts.length === 0)
@@ -26886,13 +26681,6 @@ export class Runtime {
26886
26681
  const lenNum = part.substring.length ? evalSubInt(part.substring.length) : undefined;
26887
26682
  if (part.substring.length && lenNum === undefined)
26888
26683
  return undefined;
26889
- const raw = rawVars[part.name];
26890
- this.requireParameter(raw, part.name, state, io, part.line ?? overrideDiagnosticLine);
26891
- if (raw === undefined) {
26892
- if (split && !part.quoted)
26893
- return undefined;
26894
- continue;
26895
- }
26896
26684
  const val = this._syncArithRawWriteOnly && this._syncArithTouched?.has(part.name) ? raw : (monitor?.values.get(part.name, raw) ?? raw);
26897
26685
  if (typeof val !== "string" || val.length > this.budget.limits.maxExpansionBytes)
26898
26686
  return undefined;
@@ -27023,7 +26811,7 @@ export class Runtime {
27023
26811
  if (!patQuoted && hasGlobOrEscape(pat, !!rawState.extglob)) {
27024
26812
  if (rawState.nocasematch || byteLocale(rawVars))
27025
26813
  return undefined;
27026
- if (isPrefixTrim && pat.charCodeAt(0) === 42 && !hasGlobOrEscape(pat.slice(1), !!rawState.extglob))
26814
+ if (isPrefixTrim && pat.charCodeAt(0) === 42 && !(rawState.extglob && pat.charCodeAt(1) === 40) && !hasGlobOrEscape(pat.slice(1), !!rawState.extglob))
27027
26815
  starWildcardLit = pat.slice(1);
27028
26816
  else if (!isPrefixTrim && pat.charCodeAt(pat.length - 1) === 42 && !hasGlobOrEscape(pat.slice(0, -1), !!rawState.extglob))
27029
26817
  starWildcardLit = pat.slice(0, -1);
@@ -27228,6 +27016,11 @@ export class Runtime {
27228
27016
  else if (part.kind === "substitution") {
27229
27017
  if (split && !part.quoted)
27230
27018
  return undefined;
27019
+ // General word probes may be replayed by a caller after another word or
27020
+ // command guard declines. Run substitutions at the committed valuePart
27021
+ // boundary; only pre-admitted loop invariants belong in this path.
27022
+ if (!this._syncLoopInvariantSubMap?.has(part))
27023
+ return undefined;
27231
27024
  const substVal = this.tryFastPureSubstitution(part, state, rawState, io);
27232
27025
  if (substVal === undefined)
27233
27026
  return undefined;
@@ -35921,6 +35714,8 @@ export class Runtime {
35921
35714
  if (p.kind === "text")
35922
35715
  continue;
35923
35716
  if (p.kind === "variable") {
35717
+ if (p.name === "BASH_SUBSHELL" || p.name === "RANDOM" || p.name === "SECONDS")
35718
+ return false;
35924
35719
  if (!p.indirect && !p.prefixNames && !p.length && !p.substring && !p.transform && p.operator === undefined && getArraySelector(p) === undefined && (p.name === "?" || p.name === "#" || (p.name.length === 1 && p.name >= "1" && p.name <= "9"))) {
35925
35720
  const activePos = this._fastSubPositional ?? rawState.positional;
35926
35721
  if (rawState.nounset && p.name >= "1" && p.name <= "9" && activePos[p.name.charCodeAt(0) - 49] === undefined)
@@ -35937,17 +35732,19 @@ export class Runtime {
35937
35732
  continue;
35938
35733
  }
35939
35734
  if (p.kind === "arithmetic") {
35940
- if (p.expression.hasSubscript || p.expression.hasMutation || rawState.nounset)
35941
- return false;
35942
- if (p.expression.error && (p.expression.source.includes("=") || p.expression.source.includes("++") || p.expression.source.includes("--")))
35943
- return false;
35944
- continue;
35735
+ // Even read-only arithmetic can fail (including through variable values).
35736
+ // Its diagnostic and exit status belong to the substitution's child shell.
35737
+ return false;
35945
35738
  }
35946
35739
  return false;
35947
35740
  }
35948
35741
  return true;
35949
35742
  }
35950
35743
  tryFastPureSubstitution(part, state, rawState, io) {
35744
+ // Synchronous evaluators do not expose cumulative source-read accounting.
35745
+ // Use the command context whenever the caller has set an input ceiling.
35746
+ if (this.budget.limits.maxInputBytes !== Infinity)
35747
+ return undefined;
35951
35748
  const cachedInv = this._syncLoopInvariantSubMap?.get(part);
35952
35749
  if (cachedInv !== undefined && !cachedInv.dynamic) {
35953
35750
  const nextTotalBytes = this.budget.bytes + cachedInv.outBytes;
@@ -35991,7 +35788,7 @@ export class Runtime {
35991
35788
  continue;
35992
35789
  if (name === "fmt" && command === pipeline.commands[0] && command.redirects.length === 0 && !io.stdinIsDefault)
35993
35790
  return undefined;
35994
- const definition = this.getExternalCommand(name);
35791
+ const definition = this.commands.get(name);
35995
35792
  if (definition && customRegisteredCommands.has(definition.execute))
35996
35793
  return undefined;
35997
35794
  if (name === "uname" || name === "nproc" || name === "hostname" || name === "id" || name === "whoami") {
@@ -36033,7 +35830,7 @@ export class Runtime {
36033
35830
  return undefined;
36034
35831
  if (!cmd0StdinRedir && !cmd0HereStringRedir && w0Plain0 === "cat" && cmd0.words.length < 2)
36035
35832
  return undefined;
36036
- const def0 = (w0Plain0 === "printf" || w0Plain0 === "echo" || w0Plain0 === "cat" || w0Plain0 === "pwd" || w0Plain0 === "dirname" || w0Plain0 === "basename") ? this.commands.get(w0Plain0) : this.getExternalCommand(w0Plain0);
35833
+ const def0 = this.commands.get(w0Plain0);
36037
35834
  if (!def0 || (w0Plain0 === "printf" ? def0.execute !== printfCommand.execute : w0Plain0 === "echo" ? !defaultEchoExecutors.has(def0.execute) : (w0Plain0 === "cat" || w0Plain0 === "seq" || cmd0YesStage || cmd0SysStage || cmd0StdinRedir || cmd0HereStringRedir || cmd0FileStage) ? (w0Plain0 !== "rev" && w0Plain0 !== "tac" && w0Plain0 !== "nl" && w0Plain0 !== "paste" && w0Plain0 !== "comm" && w0Plain0 !== "join" && w0Plain0 !== "jq" && w0Plain0 !== "strings" && w0Plain0 !== "bc" && w0Plain0 !== "factor" && w0Plain0 !== "tsort" && w0Plain0 !== "envsubst" && w0Plain0 !== "xxd" && w0Plain0 !== "od" && w0Plain0 !== "hexdump" && w0Plain0 !== "hd" && w0Plain0 !== "fmt" && w0Plain0 !== "md5sum" && w0Plain0 !== "sha1sum" && w0Plain0 !== "sha224sum" && w0Plain0 !== "sha256sum" && w0Plain0 !== "sha384sum" && w0Plain0 !== "sha512sum" && w0Plain0 !== "cksum" && w0Plain0 !== "base32" && w0Plain0 !== "base64" && w0Plain0 !== "csvcut" && w0Plain0 !== "csvgrep" && w0Plain0 !== "dos2unix" && w0Plain0 !== "unix2dos" && w0Plain0 !== "iconv" && w0Plain0 !== "gzip" && w0Plain0 !== "gunzip" && w0Plain0 !== "zcat" && w0Plain0 !== "unzstd" && w0Plain0 !== "zstdcat" && w0Plain0 !== "htmlq" && w0Plain0 !== "xmllint" && w0Plain0 !== "xq" && w0Plain0 !== "yq" && w0Plain0 !== "mdq" && w0Plain0 !== "shuf" && w0Plain0 !== "html-to-markdown" && w0Plain0 !== "unrtf" && w0Plain0 !== "pr" && w0Plain0 !== "file" && w0Plain0 !== "diff3" && w0Plain0 !== "cmp" && w0Plain0 !== "which" && w0Plain0 !== "diff" && w0Plain0 !== "xan" && w0Plain0 !== "less" && w0Plain0 !== "more" && w0Plain0 !== "df" && w0Plain0 !== "du" && w0Plain0 !== "tree" && w0Plain0 !== "stat" && w0Plain0 !== "fd" && w0Plain0 !== "rg" && w0Plain0 !== "readlink" && w0Plain0 !== "realpath" && w0Plain0 !== "ls" && w0Plain0 !== "find" && w0Plain0 !== "csvlook" && w0Plain0 !== "csvjson" && w0Plain0 !== "csvsort" && w0Plain0 !== "csvformat" && w0Plain0 !== "csvstat" && w0Plain0 !== "in2csv" && w0Plain0 !== "csvstack" && w0Plain0 !== "csvjoin" && w0Plain0 !== "dd" && w0Plain0 !== "env" && w0Plain0 !== "xargs" && w0Plain0 !== "openssl" && w0Plain0 !== "sqlite3" && w0Plain0 !== "gpg" && w0Plain0 !== "ssh" && w0Plain0 !== "ssh-keygen" && w0Plain0 !== "pdfinfo" && w0Plain0 !== "pdffonts" && w0Plain0 !== "pdftotext" && w0Plain0 !== "pdftohtml" && w0Plain0 !== "exiftool" && w0Plain0 !== "qpdf" && w0Plain0 !== "pdftk" && w0Plain0 !== "sips" && w0Plain0 !== "identify" && w0Plain0 !== "magick" && w0Plain0 !== "convert" && w0Plain0 !== "pdfimages" && w0Plain0 !== "pdfdetach" && w0Plain0 !== "ffprobe" && w0Plain0 !== "ffmpeg" && w0Plain0 !== "gh" && w0Plain0 !== "pdftoppm" && w0Plain0 !== "pdftocairo" && w0Plain0 !== "mmdc" && w0Plain0 !== "pandoc" && w0Plain0 !== "soffice" && w0Plain0 !== "libreoffice" && w0Plain0 !== "ssconvert" && w0Plain0 !== "wkhtmltopdf" && w0Plain0 !== "op" && w0Plain0 !== "date" && w0Plain0 !== "printenv" && w0Plain0 !== "egrep" && w0Plain0 !== "fgrep" && w0Plain0 !== "yes" && w0Plain0 !== "cal" && w0Plain0 !== "ncal" && w0Plain0 !== "expr" && w0Plain0 !== "getopt" && w0Plain0 !== "pathchk" && !builtInDirectContextExecutors.has(def0.execute)) : (customRegisteredCommands.has(def0.execute) || customRegisteredRegistries.has(this.commands))))
36038
35835
  return undefined;
36039
35836
  if (!this.arePureArgWords(cmd0.words, rawState))
@@ -36050,7 +35847,7 @@ export class Runtime {
36050
35847
  const sName = sCmd.words[0].plain;
36051
35848
  if (!sName || hasShellFunction(rawState, sName) || rawState.extensions?.builtins.has(sName))
36052
35849
  return undefined;
36053
- const extDef = this.getExternalCommand(sName);
35850
+ const extDef = this.commands.get(sName);
36054
35851
  if (!extDef || ((sName !== "cat" || startStageIdx === 0) && sName !== "rev" && sName !== "tac" && sName !== "nl" && sName !== "paste" && sName !== "column" && sName !== "fold" && sName !== "expand" && sName !== "unexpand" && sName !== "strings" && sName !== "comm" && sName !== "join" && sName !== "jq" && sName !== "bc" && sName !== "factor" && sName !== "tsort" && sName !== "envsubst" && sName !== "xxd" && sName !== "od" && sName !== "hexdump" && sName !== "hd" && sName !== "fmt" && sName !== "md5sum" && sName !== "sha1sum" && sName !== "sha224sum" && sName !== "sha256sum" && sName !== "sha384sum" && sName !== "sha512sum" && sName !== "cksum" && sName !== "base32" && sName !== "base64" && sName !== "csvcut" && sName !== "csvgrep" && sName !== "dos2unix" && sName !== "unix2dos" && sName !== "iconv" && sName !== "gzip" && sName !== "gunzip" && sName !== "zcat" && sName !== "unzstd" && sName !== "zstdcat" && sName !== "htmlq" && sName !== "xmllint" && sName !== "xq" && sName !== "yq" && sName !== "mdq" && sName !== "shuf" && sName !== "html-to-markdown" && sName !== "unrtf" && sName !== "pr" && sName !== "file" && sName !== "diff3" && sName !== "cmp" && sName !== "which" && sName !== "diff" && sName !== "xan" && sName !== "less" && sName !== "more" && sName !== "df" && sName !== "du" && sName !== "tree" && sName !== "stat" && sName !== "fd" && sName !== "rg" && sName !== "readlink" && sName !== "realpath" && sName !== "ls" && sName !== "find" && sName !== "csvlook" && sName !== "csvjson" && sName !== "csvsort" && sName !== "csvformat" && sName !== "csvstat" && sName !== "in2csv" && sName !== "csvstack" && sName !== "csvjoin" && sName !== "dd" && sName !== "xargs" && sName !== "openssl" && sName !== "sqlite3" && sName !== "gpg" && sName !== "ssh" && sName !== "ssh-keygen" && sName !== "pdfinfo" && sName !== "pdffonts" && sName !== "pdftotext" && sName !== "pdftohtml" && sName !== "exiftool" && sName !== "qpdf" && sName !== "pdftk" && sName !== "sips" && sName !== "identify" && sName !== "magick" && sName !== "convert" && sName !== "pdfimages" && sName !== "pdfdetach" && sName !== "ffprobe" && sName !== "ffmpeg" && sName !== "gh" && sName !== "pdftoppm" && sName !== "pdftocairo" && sName !== "mmdc" && sName !== "pandoc" && sName !== "soffice" && sName !== "libreoffice" && sName !== "ssconvert" && sName !== "wkhtmltopdf" && sName !== "op" && sName !== "date" && sName !== "cal" && sName !== "ncal" && sName !== "getopt" && sName !== "pathchk" && sName !== "printenv" && sName !== "env" && sName !== "egrep" && sName !== "fgrep" && !builtInDirectContextExecutors.has(extDef.execute)) || customRegisteredCommands.has(extDef.execute))
36055
35852
  return undefined;
36056
35853
  if ((sName === "xxd" || sName === "od") && !builtInDirectContextExecutors.has(extDef.execute))
@@ -36381,8 +36178,10 @@ export class Runtime {
36381
36178
  if (stage0Formatted === undefined || stage0Formatted.length > 8192)
36382
36179
  return undefined;
36383
36180
  const stage0ByteLen = shellValueByteLength(stage0Formatted);
36384
- if (stage0ByteLen > sharedSyncPipeBuf0.byteLength)
36181
+ if (stage0ByteLen > 65536)
36385
36182
  return undefined;
36183
+ const sharedSyncPipeBuf0 = new Uint8Array(65536);
36184
+ const sharedSyncPipeBuf1 = new Uint8Array(65536);
36386
36185
  const nextBytes0 = this.budget.bytes + stage0ByteLen;
36387
36186
  if (nextBytes0 > this.budget.maxOutputBytesSmi && stage0ByteLen > this.budget.limits.maxOutputBytes - this.budget.bytes)
36388
36187
  this.budget.fail("maxOutputBytes");
@@ -37587,7 +37386,7 @@ export class Runtime {
37587
37386
  for (const cl of cmd.clauses) {
37588
37387
  let matched = false;
37589
37388
  for (const pw of cl.patterns) {
37590
- if (pw.plain !== undefined && tryMatchesPatternSync(pw.plain, subj, work, false, false) === true) {
37389
+ if (pw.plain !== undefined && !pw.plain.startsWith("~") && tryMatchesPatternSync(pw.plain, subj, work, false, false) === true) {
37591
37390
  matched = true;
37592
37391
  break;
37593
37392
  }
@@ -37627,14 +37426,14 @@ export class Runtime {
37627
37426
  if (w0Plain === "fmt" && !hasSingleStdinRedir && !hasSingleHereStringRedir && !io.stdinIsDefault)
37628
37427
  return undefined;
37629
37428
  if (w0Plain === "xxd" || w0Plain === "od" || w0Plain === "mktemp" || w0Plain === "chmod" || w0Plain === "uname" || w0Plain === "nproc" || w0Plain === "hostname" || w0Plain === "id" || w0Plain === "whoami") {
37630
- const definition = this.getExternalCommand(w0Plain);
37429
+ const definition = this.commands.get(w0Plain);
37631
37430
  if (!definition || !builtInDirectContextExecutors.has(definition.execute))
37632
37431
  return undefined;
37633
37432
  }
37634
37433
  if (cmd.words.length === 2 && cmd.redirects.length === 0 && (cmd.words[1]?.plain === "--help" || cmd.words[1]?.plain === "--version")) {
37635
37434
  const gnuInfo = gnuInformationSync(w0Plain, [cmd.words[1].plain], false, (rawState.exported.has("POSIXLY_CORRECT") || rawState.allexport) && rawState.variables.POSIXLY_CORRECT !== undefined);
37636
37435
  if (gnuInfo !== undefined) {
37637
- const extDef = this.getExternalCommand(w0Plain);
37436
+ const extDef = this.commands.get(w0Plain);
37638
37437
  if (!extDef || !builtInDirectContextExecutors.has(extDef.execute))
37639
37438
  return undefined;
37640
37439
  return gnuInfo.replace(/\n+$/, "");
@@ -37655,7 +37454,7 @@ export class Runtime {
37655
37454
  w0Plain === "uniq" ||
37656
37455
  w0Plain === "tr" ||
37657
37456
  (w0Plain === "base64" || w0Plain === "rev" || w0Plain === "tac" || w0Plain === "nl" || w0Plain === "paste" || w0Plain === "numfmt" || w0Plain === "column" || w0Plain === "fold" || w0Plain === "expand" || w0Plain === "unexpand" || w0Plain === "strings" || w0Plain === "comm" || w0Plain === "join") || w0Plain === "comm" || w0Plain === "join" || w0Plain === "paste" || w0Plain === "numfmt" || w0Plain === "nl" || w0Plain === "expr" || w0Plain === "bc" || w0Plain === "xxd" || w0Plain === "od" || w0Plain === "factor" || w0Plain === "tsort" || w0Plain === "envsubst" || w0Plain === "hexdump" || w0Plain === "hd" || w0Plain === "fmt" || w0Plain === "uname" || w0Plain === "id" || w0Plain === "whoami" || w0Plain === "hostname" || w0Plain === "nproc" || w0Plain === "getconf" || w0Plain === "locale" || w0Plain === "csvcut" || w0Plain === "csvgrep" || w0Plain === "getopt" || w0Plain === "dos2unix" || w0Plain === "unix2dos" || w0Plain === "iconv" || w0Plain === "gzip" || w0Plain === "gunzip" || w0Plain === "zcat" || w0Plain === "unzstd" || w0Plain === "zstdcat" || w0Plain === "zstd" || w0Plain === "bzip2" || w0Plain === "bunzip2" || w0Plain === "bzcat" || w0Plain === "xz" || w0Plain === "unxz" || w0Plain === "xzcat" || w0Plain === "lzma" || w0Plain === "unlzma" || w0Plain === "lzcat" || w0Plain === "htmlq" || w0Plain === "xmllint" || w0Plain === "xq" || w0Plain === "yq" || w0Plain === "mdq" || w0Plain === "shuf" || w0Plain === "html-to-markdown" || w0Plain === "unrtf" || w0Plain === "pr" || w0Plain === "pathchk" || w0Plain === "file" || w0Plain === "diff3" || w0Plain === "cmp" || w0Plain === "which" || w0Plain === "diff" || w0Plain === "xan" || w0Plain === "less" || w0Plain === "more" || w0Plain === "df" || w0Plain === "du" || w0Plain === "tree" || w0Plain === "stat" || w0Plain === "fd" || w0Plain === "rg" || w0Plain === "readlink" || w0Plain === "realpath" || w0Plain === "ls" || w0Plain === "find" || w0Plain === "csvlook" || w0Plain === "csvjson" || w0Plain === "csvsort" || w0Plain === "csvformat" || w0Plain === "csvstat" || w0Plain === "in2csv" || w0Plain === "csvstack" || w0Plain === "csvjoin" || w0Plain === "dd" || w0Plain === "env" || w0Plain === "xargs" || w0Plain === "openssl" || w0Plain === "sqlite3" || w0Plain === "gpg" || w0Plain === "ssh" || w0Plain === "ssh-keygen" || w0Plain === "pdfinfo" || w0Plain === "pdffonts" || w0Plain === "pdftotext" || w0Plain === "pdftohtml" || w0Plain === "exiftool" || w0Plain === "qpdf" || w0Plain === "pdftk" || w0Plain === "sips" || w0Plain === "identify" || w0Plain === "magick" || w0Plain === "convert" || w0Plain === "mogrify" || w0Plain === "composite" || w0Plain === "montage" || w0Plain === "compare" || w0Plain === "pdfimages" || w0Plain === "pdfdetach" || w0Plain === "ffprobe" || w0Plain === "ffmpeg" || w0Plain === "gh" || w0Plain === "pdftoppm" || w0Plain === "pdftocairo" || w0Plain === "mmdc" || w0Plain === "pandoc" || w0Plain === "soffice" || w0Plain === "libreoffice" || w0Plain === "ssconvert" || w0Plain === "wkhtmltopdf" || w0Plain === "op" || w0Plain === "git" || w0Plain === "tar" || w0Plain === "unzip" || w0Plain === "zip" || w0Plain === "timeout" || w0Plain === "split" || w0Plain === "csplit" || w0Plain === "curl" || w0Plain === "wget" || w0Plain === "sponge" || w0Plain === "truncate" || w0Plain === "install" || w0Plain === "apply_patch" || w0Plain === "mktemp" || w0Plain === "tee" || w0Plain === "touch" || w0Plain === "cp" || w0Plain === "mv" || w0Plain === "rmdir" || w0Plain === "sleep" || w0Plain === "chmod" || w0Plain === "patch" || w0Plain === "mkdir" || w0Plain === "rm" || w0Plain === "ln" || w0Plain === "date" || w0Plain === "printenv" || w0Plain === "egrep" || w0Plain === "fgrep" || w0Plain === "cal" || w0Plain === "ncal" || w0Plain === "md5sum" || w0Plain === "sha1sum" || w0Plain === "sha224sum" || w0Plain === "sha256sum" || w0Plain === "sha384sum" || w0Plain === "sha512sum" || w0Plain === "cksum" || w0Plain === "base32";
37658
- if (isSingleFileTool && !hasShellFunction(rawState, w0Plain) && (this.commands.has(w0Plain) || ((w0Plain === "base64" || w0Plain === "rev" || w0Plain === "tac" || w0Plain === "nl" || w0Plain === "paste" || w0Plain === "column" || w0Plain === "fold" || w0Plain === "expand" || w0Plain === "unexpand" || w0Plain === "strings" || w0Plain === "comm" || w0Plain === "join" || w0Plain === "expr" || w0Plain === "bc" || w0Plain === "xxd" || w0Plain === "od" || w0Plain === "factor" || w0Plain === "tsort" || w0Plain === "envsubst" || w0Plain === "hexdump" || w0Plain === "hd" || w0Plain === "fmt" || w0Plain === "uname" || w0Plain === "id" || w0Plain === "whoami" || w0Plain === "hostname" || w0Plain === "nproc" || w0Plain === "getconf" || w0Plain === "locale" || w0Plain === "csvcut" || w0Plain === "csvgrep" || w0Plain === "getopt" || w0Plain === "dos2unix" || w0Plain === "unix2dos" || w0Plain === "iconv" || w0Plain === "gzip" || w0Plain === "gunzip" || w0Plain === "zcat" || w0Plain === "unzstd" || w0Plain === "zstdcat" || w0Plain === "zstd" || w0Plain === "bzip2" || w0Plain === "bunzip2" || w0Plain === "bzcat" || w0Plain === "xz" || w0Plain === "unxz" || w0Plain === "xzcat" || w0Plain === "lzma" || w0Plain === "unlzma" || w0Plain === "lzcat" || w0Plain === "htmlq" || w0Plain === "xmllint" || w0Plain === "xq" || w0Plain === "yq" || w0Plain === "mdq" || w0Plain === "shuf" || w0Plain === "html-to-markdown" || w0Plain === "unrtf" || w0Plain === "pr" || w0Plain === "pathchk" || w0Plain === "file" || w0Plain === "diff3" || w0Plain === "cmp" || w0Plain === "which" || w0Plain === "diff" || w0Plain === "xan" || w0Plain === "less" || w0Plain === "more" || w0Plain === "df" || w0Plain === "du" || w0Plain === "tree" || w0Plain === "stat" || w0Plain === "fd" || w0Plain === "rg" || w0Plain === "readlink" || w0Plain === "realpath" || w0Plain === "ls" || w0Plain === "find" || w0Plain === "csvlook" || w0Plain === "csvjson" || w0Plain === "csvsort" || w0Plain === "csvformat" || w0Plain === "csvstat" || w0Plain === "in2csv" || w0Plain === "csvstack" || w0Plain === "csvjoin" || w0Plain === "dd" || w0Plain === "env" || w0Plain === "xargs" || w0Plain === "openssl" || w0Plain === "sqlite3" || w0Plain === "gpg" || w0Plain === "ssh" || w0Plain === "ssh-keygen" || w0Plain === "pdfinfo" || w0Plain === "pdffonts" || w0Plain === "pdftotext" || w0Plain === "pdftohtml" || w0Plain === "exiftool" || w0Plain === "qpdf" || w0Plain === "pdftk" || w0Plain === "sips" || w0Plain === "identify" || w0Plain === "magick" || w0Plain === "convert" || w0Plain === "mogrify" || w0Plain === "composite" || w0Plain === "montage" || w0Plain === "compare" || w0Plain === "pdfimages" || w0Plain === "pdfdetach" || w0Plain === "ffprobe" || w0Plain === "ffmpeg" || w0Plain === "gh" || w0Plain === "pdftoppm" || w0Plain === "pdftocairo" || w0Plain === "mmdc" || w0Plain === "pandoc" || w0Plain === "soffice" || w0Plain === "libreoffice" || w0Plain === "ssconvert" || w0Plain === "wkhtmltopdf" || w0Plain === "op" || w0Plain === "git" || w0Plain === "tar" || w0Plain === "unzip" || w0Plain === "zip" || w0Plain === "timeout" || w0Plain === "split" || w0Plain === "csplit" || w0Plain === "curl" || w0Plain === "wget" || w0Plain === "sponge" || w0Plain === "truncate" || w0Plain === "install" || w0Plain === "apply_patch" || w0Plain === "mktemp" || w0Plain === "tee" || w0Plain === "touch" || w0Plain === "cp" || w0Plain === "mv" || w0Plain === "rmdir" || w0Plain === "sleep" || w0Plain === "chmod" || w0Plain === "patch" || w0Plain === "mkdir" || w0Plain === "rm" || w0Plain === "ln" || w0Plain === "date" || w0Plain === "printenv" || w0Plain === "egrep" || w0Plain === "fgrep" || w0Plain === "cal" || w0Plain === "ncal" || w0Plain === "md5sum" || w0Plain === "sha1sum" || w0Plain === "sha224sum" || w0Plain === "sha256sum" || w0Plain === "sha384sum" || w0Plain === "sha512sum" || w0Plain === "cksum" || w0Plain === "base32") && Boolean(this.getExternalCommand(w0Plain))))) {
37457
+ if (isSingleFileTool && !hasShellFunction(rawState, w0Plain) && (this.commands.has(w0Plain) || ((w0Plain === "base64" || w0Plain === "rev" || w0Plain === "tac" || w0Plain === "nl" || w0Plain === "paste" || w0Plain === "column" || w0Plain === "fold" || w0Plain === "expand" || w0Plain === "unexpand" || w0Plain === "strings" || w0Plain === "comm" || w0Plain === "join" || w0Plain === "expr" || w0Plain === "bc" || w0Plain === "xxd" || w0Plain === "od" || w0Plain === "factor" || w0Plain === "tsort" || w0Plain === "envsubst" || w0Plain === "hexdump" || w0Plain === "hd" || w0Plain === "fmt" || w0Plain === "uname" || w0Plain === "id" || w0Plain === "whoami" || w0Plain === "hostname" || w0Plain === "nproc" || w0Plain === "getconf" || w0Plain === "locale" || w0Plain === "csvcut" || w0Plain === "csvgrep" || w0Plain === "getopt" || w0Plain === "dos2unix" || w0Plain === "unix2dos" || w0Plain === "iconv" || w0Plain === "gzip" || w0Plain === "gunzip" || w0Plain === "zcat" || w0Plain === "unzstd" || w0Plain === "zstdcat" || w0Plain === "zstd" || w0Plain === "bzip2" || w0Plain === "bunzip2" || w0Plain === "bzcat" || w0Plain === "xz" || w0Plain === "unxz" || w0Plain === "xzcat" || w0Plain === "lzma" || w0Plain === "unlzma" || w0Plain === "lzcat" || w0Plain === "htmlq" || w0Plain === "xmllint" || w0Plain === "xq" || w0Plain === "yq" || w0Plain === "mdq" || w0Plain === "shuf" || w0Plain === "html-to-markdown" || w0Plain === "unrtf" || w0Plain === "pr" || w0Plain === "pathchk" || w0Plain === "file" || w0Plain === "diff3" || w0Plain === "cmp" || w0Plain === "which" || w0Plain === "diff" || w0Plain === "xan" || w0Plain === "less" || w0Plain === "more" || w0Plain === "df" || w0Plain === "du" || w0Plain === "tree" || w0Plain === "stat" || w0Plain === "fd" || w0Plain === "rg" || w0Plain === "readlink" || w0Plain === "realpath" || w0Plain === "ls" || w0Plain === "find" || w0Plain === "csvlook" || w0Plain === "csvjson" || w0Plain === "csvsort" || w0Plain === "csvformat" || w0Plain === "csvstat" || w0Plain === "in2csv" || w0Plain === "csvstack" || w0Plain === "csvjoin" || w0Plain === "dd" || w0Plain === "env" || w0Plain === "xargs" || w0Plain === "openssl" || w0Plain === "sqlite3" || w0Plain === "gpg" || w0Plain === "ssh" || w0Plain === "ssh-keygen" || w0Plain === "pdfinfo" || w0Plain === "pdffonts" || w0Plain === "pdftotext" || w0Plain === "pdftohtml" || w0Plain === "exiftool" || w0Plain === "qpdf" || w0Plain === "pdftk" || w0Plain === "sips" || w0Plain === "identify" || w0Plain === "magick" || w0Plain === "convert" || w0Plain === "mogrify" || w0Plain === "composite" || w0Plain === "montage" || w0Plain === "compare" || w0Plain === "pdfimages" || w0Plain === "pdfdetach" || w0Plain === "ffprobe" || w0Plain === "ffmpeg" || w0Plain === "gh" || w0Plain === "pdftoppm" || w0Plain === "pdftocairo" || w0Plain === "mmdc" || w0Plain === "pandoc" || w0Plain === "soffice" || w0Plain === "libreoffice" || w0Plain === "ssconvert" || w0Plain === "wkhtmltopdf" || w0Plain === "op" || w0Plain === "git" || w0Plain === "tar" || w0Plain === "unzip" || w0Plain === "zip" || w0Plain === "timeout" || w0Plain === "split" || w0Plain === "csplit" || w0Plain === "curl" || w0Plain === "wget" || w0Plain === "sponge" || w0Plain === "truncate" || w0Plain === "install" || w0Plain === "apply_patch" || w0Plain === "mktemp" || w0Plain === "tee" || w0Plain === "touch" || w0Plain === "cp" || w0Plain === "mv" || w0Plain === "rmdir" || w0Plain === "sleep" || w0Plain === "chmod" || w0Plain === "patch" || w0Plain === "mkdir" || w0Plain === "rm" || w0Plain === "ln" || w0Plain === "date" || w0Plain === "printenv" || w0Plain === "egrep" || w0Plain === "fgrep" || w0Plain === "cal" || w0Plain === "ncal" || w0Plain === "md5sum" || w0Plain === "sha1sum" || w0Plain === "sha224sum" || w0Plain === "sha256sum" || w0Plain === "sha384sum" || w0Plain === "sha512sum" || w0Plain === "cksum" || w0Plain === "base32") && Boolean(this.commands.get(w0Plain))))) {
37659
37458
  const allArgs = [];
37660
37459
  let fOk = true;
37661
37460
  for (let i = 1; i < cmd.words.length; i++) {
@@ -37787,7 +37586,7 @@ export class Runtime {
37787
37586
  }
37788
37587
  }
37789
37588
  if (fOk && (w0Plain === "date" || w0Plain === "printenv" || w0Plain === "env") && !hasSingleStdinRedir && !hasSingleHereStringRedir) {
37790
- const ext = this.getExternalCommand(w0Plain);
37589
+ const ext = this.commands.get(w0Plain);
37791
37590
  const dpOut = w0Plain === "date"
37792
37591
  ? evalSyncDate(allArgs, rawState.exported.has("TZ") ? rawState.variables.TZ : undefined, ext?.execute, (p) => this.tryReadMemoryFileViewSync(resolvePath(rawState.cwd, p), true, true), (p) => this.tryInspectMemoryNodeSync(resolvePath(rawState.cwd, p), true, true)?.mtimeMs)
37793
37592
  : w0Plain === "env"
@@ -37815,7 +37614,7 @@ export class Runtime {
37815
37614
  const inspectNode = (p) => this.tryInspectMemoryNodeSync(p, true);
37816
37615
  const inspectStat = (p, follow) => this.tryInspectMemoryNodeSync(p, true, follow);
37817
37616
  const vfsOut = w0Plain === "df"
37818
- ? evalSyncDf(allArgs, rawState.cwd, rawState.variables, inspectNode, this.getExternalCommand("df")?.execute)
37617
+ ? evalSyncDf(allArgs, rawState.cwd, rawState.variables, inspectNode, this.commands.get("df")?.execute)
37819
37618
  : w0Plain === "du"
37820
37619
  ? evalSyncDu(allArgs, rawState.cwd, rawState.variables, inspectNode)
37821
37620
  : w0Plain === "tree"
@@ -38075,7 +37874,7 @@ export class Runtime {
38075
37874
  return false;
38076
37875
  } })
38077
37876
  : w0Plain === "gh"
38078
- ? syncCommandEvaluators.evalSyncGh?.(this.getExternalCommand("gh").execute, allArgs, rawState.variables, rawState.cwd, readFile)
37877
+ ? syncCommandEvaluators.evalSyncGh?.(this.commands.get("gh").execute, allArgs, rawState.variables, rawState.cwd, readFile)
38079
37878
  : w0Plain === "pdftoppm"
38080
37879
  ? syncCommandEvaluators.evalSyncPdftoppm?.(optInBytes, allArgs, readFile, (p, b) => { try {
38081
37880
  if (this._inSyncLoopPreflight)
@@ -38137,7 +37936,7 @@ export class Runtime {
38137
37936
  return false;
38138
37937
  } })
38139
37938
  : w0Plain === "ssconvert"
38140
- ? syncCommandEvaluators.evalSyncSsconvert?.(this.getExternalCommand("ssconvert").execute, allArgs, optInBytes, readFile, (p, b) => { try {
37939
+ ? syncCommandEvaluators.evalSyncSsconvert?.(this.commands.get("ssconvert").execute, allArgs, optInBytes, readFile, (p, b) => { try {
38141
37940
  if (this._inSyncLoopPreflight)
38142
37941
  return Boolean(this.canFastMemoryRedirect && this._isMemoryBackingFs);
38143
37942
  const fp = resolvePath(rawState.cwd, p);
@@ -38161,9 +37960,9 @@ export class Runtime {
38161
37960
  return false;
38162
37961
  } })
38163
37962
  : w0Plain === "op"
38164
- ? syncCommandEvaluators.evalSyncOp?.(this.getExternalCommand("op").execute, allArgs, rawState.variables)
37963
+ ? syncCommandEvaluators.evalSyncOp?.(this.commands.get("op").execute, allArgs, rawState.variables)
38165
37964
  : w0Plain === "git"
38166
- ? syncCommandEvaluators.evalSyncGit?.(optInBytes, allArgs, rawState.cwd, (p, follow) => this.tryInspectMemoryNodeSync(p, p === "/", follow), (p) => this.tryReadMemoryFileViewSync(p, false, true), this.getExternalCommand("git").execute, (p, b, m) => { try {
37965
+ ? syncCommandEvaluators.evalSyncGit?.(optInBytes, allArgs, rawState.cwd, (p, follow) => this.tryInspectMemoryNodeSync(p, p === "/", follow), (p) => this.tryReadMemoryFileViewSync(p, false, true), this.commands.get("git").execute, (p, b, m) => { try {
38167
37966
  if (this._inSyncLoopPreflight)
38168
37967
  return Boolean(this.canFastMemoryRedirect && this._isMemoryBackingFs);
38169
37968
  const dir = p.slice(0, p.lastIndexOf("/")) || "/";
@@ -39035,7 +38834,7 @@ export class Runtime {
39035
38834
  } });
39036
38835
  }
39037
38836
  else if (w0Plain === "gh") {
39038
- fileRes = syncCommandEvaluators.evalSyncGh?.(this.getExternalCommand("gh").execute, opArgs, rawState.variables, rawState.cwd, (p) => this.tryReadMemoryFileViewSync(resolvePath(rawState.cwd, p), false));
38837
+ fileRes = syncCommandEvaluators.evalSyncGh?.(this.commands.get("gh").execute, opArgs, rawState.variables, rawState.cwd, (p) => this.tryReadMemoryFileViewSync(resolvePath(rawState.cwd, p), false));
39039
38838
  }
39040
38839
  else if (w0Plain === "pdftoppm") {
39041
38840
  const readFile = (p) => this.tryReadMemoryFileViewSync(resolvePath(rawState.cwd, p), true, true);
@@ -39108,7 +38907,7 @@ export class Runtime {
39108
38907
  } });
39109
38908
  }
39110
38909
  else if (w0Plain === "ssconvert") {
39111
- fileRes = syncCommandEvaluators.evalSyncSsconvert?.(this.getExternalCommand("ssconvert").execute, opArgs, view, (p) => this.tryReadMemoryFileViewSync(resolvePath(rawState.cwd, p), true, true), (p, b) => { try {
38910
+ fileRes = syncCommandEvaluators.evalSyncSsconvert?.(this.commands.get("ssconvert").execute, opArgs, view, (p) => this.tryReadMemoryFileViewSync(resolvePath(rawState.cwd, p), true, true), (p, b) => { try {
39112
38911
  if (this._inSyncLoopPreflight)
39113
38912
  return Boolean(this.canFastMemoryRedirect && this._isMemoryBackingFs);
39114
38913
  const fp = resolvePath(rawState.cwd, p);
@@ -39135,10 +38934,10 @@ export class Runtime {
39135
38934
  } });
39136
38935
  }
39137
38936
  else if (w0Plain === "op") {
39138
- fileRes = syncCommandEvaluators.evalSyncOp?.(this.getExternalCommand("op").execute, opArgs, rawState.variables);
38937
+ fileRes = syncCommandEvaluators.evalSyncOp?.(this.commands.get("op").execute, opArgs, rawState.variables);
39139
38938
  }
39140
38939
  else if (w0Plain === "git") {
39141
- fileRes = syncCommandEvaluators.evalSyncGit?.(view, opArgs, rawState.cwd, (p, follow) => this.tryInspectMemoryNodeSync(p, p === "/", follow), (p) => this.tryReadMemoryFileViewSync(p, false, true), this.getExternalCommand("git").execute, (p, b, m) => { try {
38940
+ fileRes = syncCommandEvaluators.evalSyncGit?.(view, opArgs, rawState.cwd, (p, follow) => this.tryInspectMemoryNodeSync(p, p === "/", follow), (p) => this.tryReadMemoryFileViewSync(p, false, true), this.commands.get("git").execute, (p, b, m) => { try {
39142
38941
  if (this._inSyncLoopPreflight)
39143
38942
  return Boolean(this.canFastMemoryRedirect && this._isMemoryBackingFs);
39144
38943
  const dir = p.slice(0, p.lastIndexOf("/")) || "/";
@@ -39617,6 +39416,8 @@ export class Runtime {
39617
39416
  }
39618
39417
  let fnPositional;
39619
39418
  if (rawState.functions.has(w0Plain)) {
39419
+ if (rawState.functionDepth >= this.budget.limits.maxFunctionDepth)
39420
+ return undefined;
39620
39421
  if (rawState.depth + 1 >= this.budget.limits.maxSubstitutionDepth)
39621
39422
  return undefined;
39622
39423
  const fnBody = rawState.functions.get(w0Plain);
@@ -39654,7 +39455,7 @@ export class Runtime {
39654
39455
  const disc = typeof targetName === "string" ? this.tryResolveSyncDiscovery(w0Plain === "command" ? "name" : "kind", targetName, rawState) : undefined;
39655
39456
  if (disc !== undefined && (disc.status === 0 || !rawState.errexit)) {
39656
39457
  if (disc.status === 0) {
39657
- const byteLength = (disc.text.length * 3 > 127 ? shellValueByteLength(disc.text) : disc.text.length) + 1;
39458
+ const byteLength = shellValueByteLength(disc.text) + 1;
39658
39459
  const nextBytes = this.budget.bytes + byteLength;
39659
39460
  if (nextBytes > this.budget.maxOutputBytesSmi && byteLength > this.budget.limits.maxOutputBytes - this.budget.bytes)
39660
39461
  this.budget.fail("maxOutputBytes");
@@ -39672,7 +39473,7 @@ export class Runtime {
39672
39473
  let res = rawState.cwd;
39673
39474
  while (res.endsWith("\n"))
39674
39475
  res = res.slice(0, -1);
39675
- const byteLength = (res.length * 3 > 127 ? shellValueByteLength(res) : res.length) + 1;
39476
+ const byteLength = shellValueByteLength(res) + 1;
39676
39477
  const nextBytes = this.budget.bytes + byteLength;
39677
39478
  if (nextBytes > this.budget.maxOutputBytesSmi && byteLength > this.budget.limits.maxOutputBytes - this.budget.bytes)
39678
39479
  this.budget.fail("maxOutputBytes");
@@ -39686,7 +39487,7 @@ export class Runtime {
39686
39487
  }
39687
39488
  if (w0Plain !== "printf" && w0Plain !== "echo" && w0Plain !== "dirname" && w0Plain !== "basename" && w0Plain !== "seq")
39688
39489
  return undefined;
39689
- const def = w0Plain === "seq" ? this.getExternalCommand(w0Plain) : this.commands.get(w0Plain);
39490
+ const def = this.commands.get(w0Plain);
39690
39491
  if (!def)
39691
39492
  return undefined;
39692
39493
  if (w0Plain === "printf" && def.execute !== printfCommand.execute)
@@ -40749,6 +40550,7 @@ export class RootShellState {
40749
40550
  this.status = 0;
40750
40551
  this.substitutionStatus = 0;
40751
40552
  this.lastArgument = "";
40553
+ this.secondsOrigin = Date.now();
40752
40554
  }
40753
40555
  get exported() {
40754
40556
  const raw = stateMonitor(this)?.raw;