just-bash 2.5.5 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/README.md +2 -2
  2. package/dist/AGENTS.md +2 -2
  3. package/dist/ast/types.d.ts +100 -11
  4. package/dist/bin/chunks/alias-EGIS5LUE.js +7 -0
  5. package/dist/bin/chunks/awk2-GFEJOWML.js +21 -0
  6. package/dist/bin/chunks/bash-PGDTHIM2.js +6 -0
  7. package/dist/bin/chunks/chmod-TYLTHXFR.js +9 -0
  8. package/dist/bin/chunks/chunk-D5WP4CKS.js +3 -0
  9. package/dist/bin/chunks/chunk-FSAGDARS.js +74 -0
  10. package/dist/bin/chunks/chunk-FSZWFMB4.js +16 -0
  11. package/dist/bin/chunks/chunk-IRUD2E3M.js +17 -0
  12. package/dist/bin/chunks/chunk-K5IXNHO5.js +8 -0
  13. package/dist/bin/chunks/chunk-KD3EODLB.js +6 -0
  14. package/dist/bin/{shell/chunks/echo-WSKTON6U.js → chunks/echo-7I42V66Q.js} +2 -2
  15. package/dist/bin/chunks/env-7A4MH7BJ.js +9 -0
  16. package/dist/bin/chunks/expansion-BOR3ELLC.js +2 -0
  17. package/dist/bin/{shell/chunks/find-CBEJ35BR.js → chunks/find-PHDZK64M.js} +1 -1
  18. package/dist/bin/{shell/chunks/grep-IIVQXFNI.js → chunks/grep-VX7MJMVN.js} +2 -2
  19. package/dist/bin/chunks/{head-DYK37Z24.js → head-TJHLLIMR.js} +1 -1
  20. package/dist/bin/{shell/chunks/jq-XXZPU5CA.js → chunks/jq-RGZHJNXC.js} +1 -1
  21. package/dist/bin/chunks/od-KRKGC2U3.js +5 -0
  22. package/dist/bin/chunks/printf-YPXD4CRE.js +15 -0
  23. package/dist/bin/chunks/pwd-L26WH2K4.js +3 -0
  24. package/dist/bin/{shell/chunks/rg-Q4OTJOEF.js → chunks/rg-RSDLLECO.js} +1 -1
  25. package/dist/bin/chunks/rmdir-GOODLY5W.js +14 -0
  26. package/dist/bin/chunks/sed-JPDTWF4W.js +100 -0
  27. package/dist/bin/{shell/chunks/tail-BES27CZT.js → chunks/tail-YAUIERGN.js} +1 -1
  28. package/dist/bin/{shell/chunks/tar-C27YYUAS.js → chunks/tar-LFENC54A.js} +7 -7
  29. package/dist/bin/chunks/time-37F5EBPK.js +14 -0
  30. package/dist/bin/chunks/touch-IBPHJBM3.js +7 -0
  31. package/dist/bin/chunks/wc-SAOHEZYP.js +6 -0
  32. package/dist/bin/chunks/{which-73KOOLC6.js → which-FCDFBOMN.js} +1 -1
  33. package/dist/bin/chunks/whoami-JVLUNKSG.js +3 -0
  34. package/dist/bin/{shell/chunks/xan-6K2NGTHM.js → chunks/xan-5HNHTFMB.js} +19 -19
  35. package/dist/bin/chunks/{yq-MF2SNFGL.js → yq-PFV4T2PV.js} +1 -1
  36. package/dist/bin/just-bash.js +659 -135
  37. package/dist/bin/shell/chunks/alias-EGIS5LUE.js +7 -0
  38. package/dist/bin/shell/chunks/awk2-GFEJOWML.js +21 -0
  39. package/dist/bin/shell/chunks/bash-PGDTHIM2.js +6 -0
  40. package/dist/bin/shell/chunks/chmod-TYLTHXFR.js +9 -0
  41. package/dist/bin/shell/chunks/chunk-D5WP4CKS.js +3 -0
  42. package/dist/bin/shell/chunks/chunk-FSAGDARS.js +74 -0
  43. package/dist/bin/shell/chunks/chunk-FSZWFMB4.js +16 -0
  44. package/dist/bin/shell/chunks/chunk-IRUD2E3M.js +17 -0
  45. package/dist/bin/shell/chunks/chunk-K5IXNHO5.js +8 -0
  46. package/dist/bin/shell/chunks/chunk-KD3EODLB.js +6 -0
  47. package/dist/bin/{chunks/echo-WSKTON6U.js → shell/chunks/echo-7I42V66Q.js} +2 -2
  48. package/dist/bin/shell/chunks/env-7A4MH7BJ.js +9 -0
  49. package/dist/bin/shell/chunks/expansion-BOR3ELLC.js +2 -0
  50. package/dist/bin/{chunks/find-CBEJ35BR.js → shell/chunks/find-PHDZK64M.js} +1 -1
  51. package/dist/bin/{chunks/grep-IIVQXFNI.js → shell/chunks/grep-VX7MJMVN.js} +2 -2
  52. package/dist/bin/shell/chunks/{head-DYK37Z24.js → head-TJHLLIMR.js} +1 -1
  53. package/dist/bin/{chunks/jq-XXZPU5CA.js → shell/chunks/jq-RGZHJNXC.js} +1 -1
  54. package/dist/bin/shell/chunks/od-KRKGC2U3.js +5 -0
  55. package/dist/bin/shell/chunks/printf-YPXD4CRE.js +15 -0
  56. package/dist/bin/shell/chunks/pwd-L26WH2K4.js +3 -0
  57. package/dist/bin/{chunks/rg-Q4OTJOEF.js → shell/chunks/rg-RSDLLECO.js} +1 -1
  58. package/dist/bin/shell/chunks/rmdir-GOODLY5W.js +14 -0
  59. package/dist/bin/shell/chunks/sed-JPDTWF4W.js +100 -0
  60. package/dist/bin/{chunks/tail-BES27CZT.js → shell/chunks/tail-YAUIERGN.js} +1 -1
  61. package/dist/bin/{chunks/tar-C27YYUAS.js → shell/chunks/tar-LFENC54A.js} +7 -7
  62. package/dist/bin/shell/chunks/time-37F5EBPK.js +14 -0
  63. package/dist/bin/shell/chunks/touch-IBPHJBM3.js +7 -0
  64. package/dist/bin/shell/chunks/wc-SAOHEZYP.js +6 -0
  65. package/dist/bin/shell/chunks/{which-73KOOLC6.js → which-FCDFBOMN.js} +1 -1
  66. package/dist/bin/shell/chunks/whoami-JVLUNKSG.js +3 -0
  67. package/dist/bin/{chunks/xan-6K2NGTHM.js → shell/chunks/xan-5HNHTFMB.js} +19 -19
  68. package/dist/bin/shell/chunks/{yq-MF2SNFGL.js → yq-PFV4T2PV.js} +1 -1
  69. package/dist/bin/shell/shell.js +664 -140
  70. package/dist/bundle/browser.js +1251 -606
  71. package/dist/bundle/chunks/alias-ATFBB6D2.js +6 -0
  72. package/dist/bundle/chunks/awk2-6FBZTP57.js +20 -0
  73. package/dist/bundle/chunks/bash-OLRNM52U.js +5 -0
  74. package/dist/bundle/chunks/chmod-ODWUR7E6.js +8 -0
  75. package/dist/bundle/chunks/chunk-3AWP5CWK.js +73 -0
  76. package/dist/bundle/chunks/chunk-CXEWLFNE.js +16 -0
  77. package/dist/bundle/chunks/chunk-CZPA5RBA.js +5 -0
  78. package/dist/bundle/chunks/chunk-EEXR5ZDP.js +2 -0
  79. package/dist/bundle/chunks/chunk-HDQ56CKY.js +15 -0
  80. package/dist/bundle/chunks/chunk-PSW6BMXW.js +7 -0
  81. package/dist/bundle/chunks/{echo-VUHWYV6L.js → echo-6S7WE7XB.js} +2 -2
  82. package/dist/bundle/chunks/env-2UI6XINU.js +8 -0
  83. package/dist/bundle/chunks/expansion-RIGCFEMA.js +1 -0
  84. package/dist/bundle/chunks/{find-ACOAWALE.js → find-YGMSVGUV.js} +1 -1
  85. package/dist/bundle/chunks/{grep-ACVE42JK.js → grep-NIC6JNLH.js} +2 -2
  86. package/dist/bundle/chunks/{head-FZ6IQHYW.js → head-SA7P5NJ7.js} +1 -1
  87. package/dist/bundle/chunks/{jq-3YU5HRKE.js → jq-RLRYRPOJ.js} +1 -1
  88. package/dist/bundle/chunks/od-3FPDPLWJ.js +4 -0
  89. package/dist/bundle/chunks/printf-66XGXFCD.js +14 -0
  90. package/dist/bundle/chunks/pwd-S4NVAMC4.js +2 -0
  91. package/dist/bundle/chunks/{rg-YLZJWCEJ.js → rg-SRMB7L6G.js} +1 -1
  92. package/dist/bundle/chunks/rmdir-XFQE4ZYV.js +13 -0
  93. package/dist/bundle/chunks/sed-IV6HLDXU.js +99 -0
  94. package/dist/bundle/chunks/{tail-PD4RZR6J.js → tail-52LRAWXT.js} +1 -1
  95. package/dist/bundle/chunks/{tar-QWBXMF7K.js → tar-LWIHPMT6.js} +7 -7
  96. package/dist/bundle/chunks/time-UWXBG6CS.js +13 -0
  97. package/dist/bundle/chunks/touch-TDTEBHHI.js +6 -0
  98. package/dist/bundle/chunks/wc-HE5XARI4.js +5 -0
  99. package/dist/bundle/chunks/{which-M5MQ6QXQ.js → which-UBLRBDHN.js} +1 -1
  100. package/dist/bundle/chunks/whoami-YUDAIS32.js +2 -0
  101. package/dist/bundle/chunks/{xan-2R2APJJ4.js → xan-A6VPI4HJ.js} +19 -19
  102. package/dist/bundle/chunks/{yq-KANM4MD2.js → yq-L665QPQU.js} +1 -1
  103. package/dist/bundle/index.js +657 -133
  104. package/dist/commands/awk/ast.d.ts +1 -0
  105. package/dist/commands/awk/interpreter/context.d.ts +14 -0
  106. package/dist/commands/awk/interpreter/interpreter.d.ts +2 -0
  107. package/dist/commands/awk/interpreter/{helpers.d.ts → type-coercion.d.ts} +4 -1
  108. package/dist/commands/awk/parser2-print.d.ts +35 -0
  109. package/dist/commands/awk/parser2.d.ts +42 -34
  110. package/dist/commands/printf/strftime.d.ts +9 -0
  111. package/dist/commands/query-engine/builtins/array-builtins.d.ts +20 -0
  112. package/dist/commands/query-engine/builtins/control-builtins.d.ts +18 -0
  113. package/dist/commands/query-engine/builtins/date-builtins.d.ts +15 -0
  114. package/dist/commands/query-engine/builtins/format-builtins.d.ts +11 -0
  115. package/dist/commands/query-engine/builtins/index-builtins.d.ts +16 -0
  116. package/dist/commands/query-engine/builtins/index.d.ts +17 -0
  117. package/dist/commands/query-engine/builtins/math-builtins.d.ts +15 -0
  118. package/dist/commands/query-engine/builtins/navigation-builtins.d.ts +18 -0
  119. package/dist/commands/query-engine/builtins/object-builtins.d.ts +15 -0
  120. package/dist/commands/query-engine/builtins/path-builtins.d.ts +20 -0
  121. package/dist/commands/query-engine/builtins/sql-builtins.d.ts +16 -0
  122. package/dist/commands/query-engine/builtins/string-builtins.d.ts +15 -0
  123. package/dist/commands/query-engine/builtins/type-builtins.d.ts +11 -0
  124. package/dist/commands/query-engine/evaluator.d.ts +10 -2
  125. package/dist/commands/query-engine/parser-types.d.ts +171 -0
  126. package/dist/commands/query-engine/parser.d.ts +2 -132
  127. package/dist/commands/query-engine/path-operations.d.ts +15 -0
  128. package/dist/commands/query-engine/value-operations.d.ts +39 -0
  129. package/dist/commands/registry.d.ts +1 -1
  130. package/dist/commands/rmdir/rmdir.d.ts +2 -0
  131. package/dist/commands/sed/lexer.d.ts +12 -0
  132. package/dist/commands/sed/parser.d.ts +9 -0
  133. package/dist/commands/sed/sed-regex.d.ts +23 -0
  134. package/dist/commands/sed/types.d.ts +13 -1
  135. package/dist/commands/tar/tar-options.d.ts +36 -0
  136. package/dist/commands/time/time.d.ts +25 -0
  137. package/dist/commands/whoami/whoami.d.ts +9 -0
  138. package/dist/commands/xan/moonblade-tokenizer.d.ts +25 -0
  139. package/dist/fs/in-memory-fs/in-memory-fs.d.ts +12 -0
  140. package/dist/fs/interface.d.ts +16 -0
  141. package/dist/fs/mountable-fs/mountable-fs.d.ts +12 -0
  142. package/dist/fs/overlay-fs/overlay-fs.d.ts +13 -1
  143. package/dist/fs/read-write-fs/read-write-fs.d.ts +13 -1
  144. package/dist/interpreter/alias-expansion.d.ts +23 -0
  145. package/dist/interpreter/arithmetic.d.ts +1 -6
  146. package/dist/interpreter/assignment-expansion.d.ts +24 -0
  147. package/dist/interpreter/builtin-dispatch.d.ts +39 -0
  148. package/dist/interpreter/builtins/compgen.d.ts +26 -0
  149. package/dist/interpreter/builtins/complete.d.ts +17 -0
  150. package/dist/interpreter/builtins/compopt.d.ts +28 -0
  151. package/dist/interpreter/builtins/declare-array-parsing.d.ts +14 -0
  152. package/dist/interpreter/builtins/declare-print.d.ts +39 -0
  153. package/dist/interpreter/builtins/declare.d.ts +10 -4
  154. package/dist/interpreter/builtins/dirs.d.ts +29 -0
  155. package/dist/interpreter/builtins/eval.d.ts +1 -1
  156. package/dist/interpreter/builtins/export.d.ts +1 -0
  157. package/dist/interpreter/builtins/getopts.d.ts +18 -0
  158. package/dist/interpreter/builtins/hash.d.ts +19 -0
  159. package/dist/interpreter/builtins/help.d.ts +12 -0
  160. package/dist/interpreter/builtins/index.d.ts +9 -1
  161. package/dist/interpreter/builtins/local.d.ts +1 -1
  162. package/dist/interpreter/builtins/read.d.ts +1 -1
  163. package/dist/interpreter/builtins/set.d.ts +3 -0
  164. package/dist/interpreter/builtins/shift.d.ts +3 -0
  165. package/dist/interpreter/builtins/shopt.d.ts +7 -0
  166. package/dist/interpreter/builtins/unset.d.ts +5 -1
  167. package/dist/interpreter/builtins/variable-assignment.d.ts +66 -0
  168. package/dist/interpreter/command-resolution.d.ts +43 -0
  169. package/dist/interpreter/conditionals.d.ts +1 -1
  170. package/dist/interpreter/errors.d.ts +36 -1
  171. package/dist/interpreter/expansion/analysis.d.ts +15 -17
  172. package/dist/interpreter/expansion/arith-text-expansion.d.ts +20 -0
  173. package/dist/interpreter/expansion/array-pattern-ops.d.ts +21 -0
  174. package/dist/interpreter/expansion/array-prefix-suffix.d.ts +46 -0
  175. package/dist/interpreter/expansion/array-slice-transform.d.ts +36 -0
  176. package/dist/interpreter/expansion/array-word-expansion.d.ts +39 -0
  177. package/dist/interpreter/expansion/command-substitution.d.ts +23 -0
  178. package/dist/interpreter/expansion/glob-escape.d.ts +32 -0
  179. package/dist/interpreter/expansion/indirect-expansion.d.ts +42 -0
  180. package/dist/interpreter/expansion/parameter-ops.d.ts +113 -0
  181. package/dist/interpreter/expansion/pattern-expansion.d.ts +23 -0
  182. package/dist/interpreter/expansion/pattern-removal.d.ts +18 -0
  183. package/dist/interpreter/expansion/pattern.d.ts +2 -1
  184. package/dist/interpreter/expansion/positional-params.d.ts +59 -0
  185. package/dist/interpreter/expansion/prompt.d.ts +39 -0
  186. package/dist/interpreter/expansion/quoting.d.ts +13 -0
  187. package/dist/interpreter/expansion/tilde.d.ts +12 -0
  188. package/dist/interpreter/expansion/unquoted-expansion.d.ts +76 -0
  189. package/dist/interpreter/expansion/variable-attrs.d.ts +19 -0
  190. package/dist/interpreter/expansion/variable.d.ts +10 -1
  191. package/dist/interpreter/expansion/word-glob-expansion.d.ts +33 -0
  192. package/dist/interpreter/expansion/word-split.d.ts +11 -6
  193. package/dist/interpreter/expansion.d.ts +30 -4
  194. package/dist/interpreter/functions.d.ts +1 -1
  195. package/dist/interpreter/helpers/array.d.ts +20 -0
  196. package/dist/interpreter/helpers/ifs.d.ts +66 -5
  197. package/dist/interpreter/helpers/nameref.d.ts +65 -0
  198. package/dist/interpreter/helpers/quoting.d.ts +24 -0
  199. package/dist/interpreter/helpers/readonly.d.ts +28 -4
  200. package/dist/interpreter/helpers/shell-constants.d.ts +25 -0
  201. package/dist/interpreter/helpers/shellopts.d.ts +28 -0
  202. package/dist/interpreter/helpers/string-compare.d.ts +3 -1
  203. package/dist/interpreter/helpers/tilde.d.ts +13 -0
  204. package/dist/interpreter/helpers/variable-tests.d.ts +1 -1
  205. package/dist/interpreter/helpers/word-matching.d.ts +26 -0
  206. package/dist/interpreter/helpers/xtrace.d.ts +18 -0
  207. package/dist/interpreter/interpreter.d.ts +13 -14
  208. package/dist/interpreter/pipeline-execution.d.ts +16 -0
  209. package/dist/interpreter/redirections.d.ts +38 -1
  210. package/dist/interpreter/simple-command-assignments.d.ts +29 -0
  211. package/dist/interpreter/subshell-group.d.ts +32 -0
  212. package/dist/interpreter/type-command.d.ts +37 -0
  213. package/dist/interpreter/types.d.ts +255 -21
  214. package/dist/parser/arithmetic-parser.d.ts +2 -4
  215. package/dist/parser/arithmetic-primaries.d.ts +45 -0
  216. package/dist/parser/compound-parser.d.ts +21 -7
  217. package/dist/parser/expansion-parser.d.ts +7 -1
  218. package/dist/parser/lexer.d.ts +57 -0
  219. package/dist/parser/parser-substitution.d.ts +62 -0
  220. package/dist/parser/parser.d.ts +39 -2
  221. package/dist/parser/types.d.ts +1 -0
  222. package/dist/types.d.ts +17 -0
  223. package/package.json +4 -1
  224. package/dist/bin/chunks/alias-PCMLRCRW.js +0 -7
  225. package/dist/bin/chunks/awk2-D2US2LMM.js +0 -20
  226. package/dist/bin/chunks/bash-UT3MT5UU.js +0 -7
  227. package/dist/bin/chunks/chmod-3DIKREF7.js +0 -9
  228. package/dist/bin/chunks/chunk-ACRTDIBO.js +0 -6
  229. package/dist/bin/chunks/chunk-DV5HL4K2.js +0 -17
  230. package/dist/bin/chunks/chunk-J7BCMQDI.js +0 -16
  231. package/dist/bin/chunks/chunk-NWWB2XRE.js +0 -6
  232. package/dist/bin/chunks/chunk-PM2DS2YW.js +0 -3
  233. package/dist/bin/chunks/env-YLLSNZZN.js +0 -9
  234. package/dist/bin/chunks/od-SLM7SRWU.js +0 -7
  235. package/dist/bin/chunks/printf-HWUQKYUM.js +0 -14
  236. package/dist/bin/chunks/pwd-53KG2MCJ.js +0 -3
  237. package/dist/bin/chunks/sed-5LQMJYRJ.js +0 -80
  238. package/dist/bin/chunks/touch-TSNAXMZ2.js +0 -4
  239. package/dist/bin/chunks/wc-QSBRKIF5.js +0 -6
  240. package/dist/bin/shell/chunks/alias-PCMLRCRW.js +0 -7
  241. package/dist/bin/shell/chunks/awk2-D2US2LMM.js +0 -20
  242. package/dist/bin/shell/chunks/bash-UT3MT5UU.js +0 -7
  243. package/dist/bin/shell/chunks/chmod-3DIKREF7.js +0 -9
  244. package/dist/bin/shell/chunks/chunk-ACRTDIBO.js +0 -6
  245. package/dist/bin/shell/chunks/chunk-DV5HL4K2.js +0 -17
  246. package/dist/bin/shell/chunks/chunk-J7BCMQDI.js +0 -16
  247. package/dist/bin/shell/chunks/chunk-NWWB2XRE.js +0 -6
  248. package/dist/bin/shell/chunks/chunk-PM2DS2YW.js +0 -3
  249. package/dist/bin/shell/chunks/env-YLLSNZZN.js +0 -9
  250. package/dist/bin/shell/chunks/od-SLM7SRWU.js +0 -7
  251. package/dist/bin/shell/chunks/printf-HWUQKYUM.js +0 -14
  252. package/dist/bin/shell/chunks/pwd-53KG2MCJ.js +0 -3
  253. package/dist/bin/shell/chunks/sed-5LQMJYRJ.js +0 -80
  254. package/dist/bin/shell/chunks/touch-TSNAXMZ2.js +0 -4
  255. package/dist/bin/shell/chunks/wc-QSBRKIF5.js +0 -6
  256. package/dist/bundle/chunks/alias-4UGRF4DM.js +0 -6
  257. package/dist/bundle/chunks/awk2-46RTIZKB.js +0 -19
  258. package/dist/bundle/chunks/bash-ZILV3VHA.js +0 -6
  259. package/dist/bundle/chunks/chmod-FBHLEIY6.js +0 -8
  260. package/dist/bundle/chunks/chunk-4JO5BKO4.js +0 -5
  261. package/dist/bundle/chunks/chunk-BOJ3OAZB.js +0 -16
  262. package/dist/bundle/chunks/chunk-CG2HXOFG.js +0 -5
  263. package/dist/bundle/chunks/chunk-NWEGHOXL.js +0 -2
  264. package/dist/bundle/chunks/chunk-W2EKKAIL.js +0 -15
  265. package/dist/bundle/chunks/env-EG5SQSAQ.js +0 -8
  266. package/dist/bundle/chunks/od-ECWXNUB4.js +0 -6
  267. package/dist/bundle/chunks/printf-VG2POOXB.js +0 -13
  268. package/dist/bundle/chunks/pwd-AC4P3JKI.js +0 -2
  269. package/dist/bundle/chunks/sed-ZKODWZ6F.js +0 -79
  270. package/dist/bundle/chunks/touch-MVQSKQKT.js +0 -3
  271. package/dist/bundle/chunks/wc-DFQKWSIZ.js +0 -5
  272. package/dist/interpreter/builtins/variable-helpers.d.ts +0 -30
  273. /package/dist/bin/chunks/{curl-LCMREE7R.js → curl-TH7YRBSA.js} +0 -0
  274. /package/dist/bin/chunks/{file-LNCFDPQZ.js → file-6PCTL3MH.js} +0 -0
  275. /package/dist/bin/shell/chunks/{curl-LCMREE7R.js → curl-TH7YRBSA.js} +0 -0
  276. /package/dist/bin/shell/chunks/{file-LNCFDPQZ.js → file-6PCTL3MH.js} +0 -0
  277. /package/dist/bundle/chunks/{curl-TVZH24MD.js → curl-XLP4VABU.js} +0 -0
  278. /package/dist/bundle/chunks/{file-XPA6O6H2.js → file-NQP3CKRV.js} +0 -0
  279. /package/dist/commands/curl/{utils.d.ts → response-formatting.d.ts} +0 -0
  280. /package/dist/commands/xan/{xan-utils.d.ts → column-selection.d.ts} +0 -0
  281. /package/dist/fs/{utils.d.ts → encoding.d.ts} +0 -0
@@ -6,12 +6,14 @@
6
6
  * - Array access (${arr[0]}, ${arr[@]}, ${arr[*]})
7
7
  * - Positional parameters ($1, $2, ...)
8
8
  * - Regular variables
9
+ * - Nameref resolution
9
10
  */
10
11
  import type { InterpreterContext } from "../types.js";
11
12
  /**
12
13
  * Get all elements of an array stored as arrayName_0, arrayName_1, etc.
13
14
  * Returns an array of [index/key, value] tuples, sorted by index/key.
14
15
  * For associative arrays, uses string keys.
16
+ * Special arrays FUNCNAME, BASH_LINENO, and BASH_SOURCE are handled dynamically from call stack.
15
17
  */
16
18
  export declare function getArrayElements(ctx: InterpreterContext, arrayName: string): Array<[number | string, string]>;
17
19
  /**
@@ -24,4 +26,11 @@ export declare function isArray(ctx: InterpreterContext, name: string): boolean;
24
26
  * @param name - The variable name
25
27
  * @param checkNounset - Whether to check for nounset (default true)
26
28
  */
27
- export declare function getVariable(ctx: InterpreterContext, name: string, checkNounset?: boolean, _insideDoubleQuotes?: boolean): string;
29
+ export declare function getVariable(ctx: InterpreterContext, name: string, checkNounset?: boolean, _insideDoubleQuotes?: boolean): Promise<string>;
30
+ /**
31
+ * Check if a variable is set (exists in the environment).
32
+ * Properly handles array subscripts (e.g., arr[0] -> arr_0).
33
+ * @param ctx - The interpreter context
34
+ * @param name - The variable name (possibly with array subscript)
35
+ */
36
+ export declare function isVariableSet(ctx: InterpreterContext, name: string): Promise<boolean>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Word Expansion with Glob Handling
3
+ *
4
+ * Handles the main word expansion flow including:
5
+ * - Brace expansion
6
+ * - Array and positional parameter expansion
7
+ * - Word splitting
8
+ * - Glob/pathname expansion
9
+ */
10
+ import type { ArithExpr, ParameterExpansionPart, WordNode, WordPart } from "../../ast/types.js";
11
+ import type { InterpreterContext } from "../types.js";
12
+ /**
13
+ * Dependencies injected to avoid circular imports
14
+ */
15
+ export interface WordGlobExpansionDeps {
16
+ expandWordAsync: (ctx: InterpreterContext, word: WordNode) => Promise<string>;
17
+ expandWordForGlobbing: (ctx: InterpreterContext, word: WordNode) => Promise<string>;
18
+ expandWordWithBracesAsync: (ctx: InterpreterContext, word: WordNode) => Promise<string[] | null>;
19
+ expandWordPartsAsync: (ctx: InterpreterContext, parts: WordPart[]) => Promise<string>;
20
+ expandPart: (ctx: InterpreterContext, part: WordPart, inDoubleQuotes?: boolean) => Promise<string>;
21
+ expandParameterAsync: (ctx: InterpreterContext, part: ParameterExpansionPart, inDoubleQuotes?: boolean) => Promise<string>;
22
+ hasBraceExpansion: (parts: WordPart[]) => boolean;
23
+ evaluateArithmetic: (ctx: InterpreterContext, expr: ArithExpr, isExpansionContext?: boolean) => Promise<number>;
24
+ buildIfsCharClassPattern: (ifsChars: string) => string;
25
+ smartWordSplit: (ctx: InterpreterContext, wordParts: WordPart[], ifsChars: string, ifsPattern: string, expandPart: (ctx: InterpreterContext, part: WordPart) => Promise<string>) => Promise<string[]>;
26
+ }
27
+ /**
28
+ * Main word expansion function that handles all expansion types and glob matching.
29
+ */
30
+ export declare function expandWordWithGlobImpl(ctx: InterpreterContext, word: WordNode, deps: WordGlobExpansionDeps): Promise<{
31
+ values: string[];
32
+ quoted: boolean;
33
+ }>;
@@ -10,15 +10,20 @@ import type { InterpreterContext } from "../types.js";
10
10
  */
11
11
  export type ExpandPartFn = (ctx: InterpreterContext, part: WordPart) => Promise<string>;
12
12
  /**
13
- * Smart word splitting that respects expansion boundaries.
13
+ * Smart word splitting for words containing expansions.
14
14
  *
15
- * E.g., with IFS=x: ${v:-AxBxC}x should give "A B Cx" (literal x attaches to last field)
16
- * E.g., with IFS=x: y${v:-AxBxC}z should give "yA B Cz" (literals attach to first/last fields)
15
+ * In bash, word splitting respects quoted parts. When you have:
16
+ * - $a"$b" where a="1 2" and b="3 4"
17
+ * - The unquoted $a gets split by IFS: "1 2" -> ["1", "2"]
18
+ * - The quoted "$b" does NOT get split, it joins with the last field from $a
19
+ * - Result: ["1", "23 4"] (the "2" joins with "3 4")
20
+ *
21
+ * This differs from pure literal words which are never IFS-split.
17
22
  *
18
23
  * @param ctx - Interpreter context
19
24
  * @param wordParts - Word parts to expand and split
20
- * @param _ifsChars - IFS characters (unused, kept for API compatibility)
21
- * @param ifsPattern - Regex-escaped IFS pattern for splitting
25
+ * @param ifsChars - IFS characters for proper whitespace/non-whitespace handling
26
+ * @param ifsPattern - Regex-escaped IFS pattern for checking if splitting is needed
22
27
  * @param expandPartFn - Function to expand individual parts (injected to avoid circular deps)
23
28
  */
24
- export declare function smartWordSplit(ctx: InterpreterContext, wordParts: WordPart[], _ifsChars: string, ifsPattern: string, expandPartFn: ExpandPartFn): Promise<string[]>;
29
+ export declare function smartWordSplit(ctx: InterpreterContext, wordParts: WordPart[], ifsChars: string, _ifsPattern: string, expandPartFn: ExpandPartFn): Promise<string[]>;
@@ -11,17 +11,43 @@
11
11
  */
12
12
  import type { WordNode } from "../ast/types.js";
13
13
  import type { InterpreterContext } from "./types.js";
14
- export { getArrayElements, getVariable } from "./expansion/variable.js";
14
+ export { escapeGlobChars, escapeRegexChars } from "./expansion/glob-escape.js";
15
+ export { getArrayElements, getVariable, isArray, } from "./expansion/variable.js";
15
16
  /**
16
17
  * Check if an entire word is fully quoted
17
18
  */
18
19
  export declare function isWordFullyQuoted(word: WordNode): boolean;
20
+ export declare function expandWord(ctx: InterpreterContext, word: WordNode): Promise<string>;
19
21
  /**
20
- * Escape glob metacharacters in a string for literal matching
22
+ * Expand a word for use as a regex pattern (in [[ =~ ]]).
23
+ * Preserves backslash escapes so they're passed to the regex engine.
24
+ * For example, \[\] becomes \[\] in the regex (matching literal [ and ]).
21
25
  */
22
- export declare function escapeGlobChars(str: string): string;
23
- export declare function expandWord(ctx: InterpreterContext, word: WordNode): Promise<string>;
26
+ export declare function expandWordForRegex(ctx: InterpreterContext, word: WordNode): Promise<string>;
27
+ /**
28
+ * Expand a word for use as a pattern (e.g., in [[ == ]] or case).
29
+ * Preserves backslash escapes for pattern metacharacters so they're treated literally.
30
+ * This prevents `*\(\)` from being interpreted as an extglob pattern.
31
+ */
32
+ export declare function expandWordForPattern(ctx: InterpreterContext, word: WordNode): Promise<string>;
24
33
  export declare function expandWordWithGlob(ctx: InterpreterContext, word: WordNode): Promise<{
25
34
  values: string[];
26
35
  quoted: boolean;
27
36
  }>;
37
+ export declare function hasQuotedMultiValueAt(ctx: InterpreterContext, word: WordNode): boolean;
38
+ /**
39
+ * Expand a redirect target with glob handling.
40
+ *
41
+ * For redirects:
42
+ * - If glob matches 0 files with failglob → error (returns { error: ... })
43
+ * - If glob matches 0 files without failglob → use literal pattern
44
+ * - If glob matches 1 file → use that file
45
+ * - If glob matches 2+ files → "ambiguous redirect" error
46
+ *
47
+ * Returns { target: string } on success or { error: string } on failure.
48
+ */
49
+ export declare function expandRedirectTarget(ctx: InterpreterContext, word: WordNode): Promise<{
50
+ target: string;
51
+ } | {
52
+ error: string;
53
+ }>;
@@ -9,4 +9,4 @@ import type { FunctionDefNode } from "../ast/types.js";
9
9
  import type { ExecResult } from "../types.js";
10
10
  import type { InterpreterContext } from "./types.js";
11
11
  export declare function executeFunctionDef(ctx: InterpreterContext, node: FunctionDefNode): ExecResult;
12
- export declare function callFunction(ctx: InterpreterContext, func: FunctionDefNode, args: string[]): Promise<ExecResult>;
12
+ export declare function callFunction(ctx: InterpreterContext, func: FunctionDefNode, args: string[], stdin?: string, callLine?: number): Promise<ExecResult>;
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Array helper functions for the interpreter.
3
3
  */
4
+ import type { WordNode } from "../../ast/types.js";
4
5
  import type { InterpreterContext } from "../types.js";
5
6
  /**
6
7
  * Get all indices of an array, sorted in ascending order.
@@ -21,3 +22,22 @@ export declare function getAssocArrayKeys(ctx: InterpreterContext, arrayName: st
21
22
  * Handles 'key' and "key" → key
22
23
  */
23
24
  export declare function unquoteKey(key: string): string;
25
+ /**
26
+ * Parse a keyed array element from an AST WordNode like [key]=value or [key]+=value.
27
+ * Returns { key, valueParts, append } where valueParts are the AST parts for the value.
28
+ * Returns null if not a keyed element pattern.
29
+ *
30
+ * This is used to properly expand variables in the value part of keyed elements.
31
+ */
32
+ export interface ParsedKeyedElement {
33
+ key: string;
34
+ valueParts: WordNode["parts"];
35
+ append: boolean;
36
+ }
37
+ export declare function parseKeyedElementFromWord(word: WordNode): ParsedKeyedElement | null;
38
+ /**
39
+ * Extract literal string content from a Word node (without expansion).
40
+ * This is used for parsing associative array element syntax like [key]=value
41
+ * where the [key] part may be parsed as a Glob.
42
+ */
43
+ export declare function wordToLiteralString(word: WordNode): string;
@@ -15,6 +15,13 @@ export declare function getIfs(env: Record<string, string>): string;
15
15
  * Check if IFS is set to empty string (disables word splitting).
16
16
  */
17
17
  export declare function isIfsEmpty(env: Record<string, string>): boolean;
18
+ /**
19
+ * Check if IFS contains only whitespace characters (space, tab, newline).
20
+ * This affects how empty fields are handled in $@ and $* expansion.
21
+ * When IFS has non-whitespace chars, empty params are preserved.
22
+ * When IFS has only whitespace, empty params are dropped.
23
+ */
24
+ export declare function isIfsWhitespaceOnly(env: Record<string, string>): boolean;
18
25
  /**
19
26
  * Build a regex-safe pattern from IFS characters for use in character classes.
20
27
  * E.g., for IFS=" \t\n", returns " \\t\\n" (escaped for [pattern] use)
@@ -26,18 +33,72 @@ export declare function buildIfsCharClassPattern(ifs: string): string;
26
33
  */
27
34
  export declare function getIfsSeparator(env: Record<string, string>): string;
28
35
  /**
29
- * Split a string by IFS, handling leading/trailing IFS properly.
30
- * Returns words and their start positions in the original string.
36
+ * Advanced IFS splitting for the read builtin with proper whitespace/non-whitespace handling.
37
+ *
38
+ * IFS has two types of characters:
39
+ * - Whitespace (space, tab, newline): Multiple consecutive ones are collapsed,
40
+ * leading/trailing are stripped
41
+ * - Non-whitespace (like 'x', ':'): Create empty fields when consecutive,
42
+ * trailing ones preserved (except the final delimiter)
31
43
  *
32
44
  * @param value - String to split
33
45
  * @param ifs - IFS characters to split on
46
+ * @param maxSplit - Maximum number of splits (for read with multiple vars, the last gets the rest)
47
+ * @param raw - If true, backslash escaping is disabled (like read -r)
34
48
  * @returns Object with words array and wordStarts array
35
49
  */
36
- export declare function splitByIfs(value: string, ifs: string): {
50
+ export declare function splitByIfsForRead(value: string, ifs: string, maxSplit?: number, raw?: boolean): {
37
51
  words: string[];
38
52
  wordStarts: number[];
39
53
  };
40
54
  /**
41
- * Strip trailing IFS characters from a string.
55
+ * IFS splitting for word expansion (unquoted $VAR, $*, etc.).
56
+ *
57
+ * Key differences from splitByIfsForRead:
58
+ * - Trailing non-whitespace delimiter does NOT create an empty field
59
+ * - No maxSplit concept (always splits fully)
60
+ * - No backslash escape handling
61
+ *
62
+ * @param value - String to split
63
+ * @param ifs - IFS characters to split on
64
+ * @returns Array of words after splitting
65
+ */
66
+ /**
67
+ * Result of splitByIfsForExpansionEx with leading/trailing delimiter info.
68
+ */
69
+ export interface IfsExpansionSplitResult {
70
+ words: string[];
71
+ /** True if the value started with an IFS whitespace delimiter (affects joining with preceding text) */
72
+ hadLeadingDelimiter: boolean;
73
+ /** True if the value ended with an IFS delimiter (affects joining with subsequent text) */
74
+ hadTrailingDelimiter: boolean;
75
+ }
76
+ /**
77
+ * Extended IFS splitting that tracks trailing delimiters.
78
+ * This is needed for proper word boundary handling when literal text follows an expansion.
79
+ * For example, in `-$x-` where `x='a b c '`, the trailing space means the final `-`
80
+ * should become a separate word, not join with `c`.
81
+ */
82
+ export declare function splitByIfsForExpansionEx(value: string, ifs: string): IfsExpansionSplitResult;
83
+ export declare function splitByIfsForExpansion(value: string, ifs: string): string[];
84
+ /**
85
+ * Strip trailing IFS from the last variable in read builtin.
86
+ *
87
+ * Bash behavior:
88
+ * 1. Strip trailing IFS whitespace characters (but NOT if they're escaped by backslash)
89
+ * 2. If there's a single trailing IFS non-whitespace character, strip it ONLY IF
90
+ * there are no other non-ws IFS chars in the content (excluding the trailing one)
91
+ *
92
+ * Examples with IFS="x ":
93
+ * - "ax " -> "a" (trailing spaces stripped, then trailing single x stripped because no other x)
94
+ * - "ax" -> "a" (trailing single x stripped because no other x in remaining content)
95
+ * - "axx" -> "axx" (two trailing x's, so don't strip - there's another x)
96
+ * - "ax x" -> "ax x" (trailing x NOT stripped because there's an x earlier)
97
+ * - "bx" -> "b" (trailing x stripped, no other x)
98
+ * - "a\ " -> "a " (backslash-escaped space is NOT stripped)
99
+ *
100
+ * @param value - String to strip (raw, before backslash processing)
101
+ * @param ifs - IFS characters
102
+ * @param raw - If true, backslash escaping is disabled
42
103
  */
43
- export declare function stripTrailingIfs(value: string, ifs: string): string;
104
+ export declare function stripTrailingIfsWhitespace(value: string, ifs: string, raw?: boolean): string;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Nameref (declare -n) support
3
+ *
4
+ * Namerefs are variables that reference other variables by name.
5
+ * When a nameref is accessed, it transparently dereferences to the target variable.
6
+ */
7
+ import type { InterpreterContext } from "../types.js";
8
+ /**
9
+ * Check if a variable is a nameref
10
+ */
11
+ export declare function isNameref(ctx: InterpreterContext, name: string): boolean;
12
+ /**
13
+ * Mark a variable as a nameref
14
+ */
15
+ export declare function markNameref(ctx: InterpreterContext, name: string): void;
16
+ /**
17
+ * Remove the nameref attribute from a variable
18
+ */
19
+ export declare function unmarkNameref(ctx: InterpreterContext, name: string): void;
20
+ /**
21
+ * Mark a nameref as having an "invalid" target at creation time.
22
+ * Invalid namerefs always read/write their value directly, never resolving.
23
+ */
24
+ export declare function markNamerefInvalid(ctx: InterpreterContext, name: string): void;
25
+ /**
26
+ * Mark a nameref as "bound" - meaning its target existed at creation time.
27
+ * This is kept for tracking purposes but is currently not used in resolution.
28
+ */
29
+ export declare function markNamerefBound(ctx: InterpreterContext, name: string): void;
30
+ /**
31
+ * Check if a name refers to a valid, existing variable or array element.
32
+ * Used to determine if a nameref target is "real" or just a stored value.
33
+ */
34
+ export declare function targetExists(ctx: InterpreterContext, target: string): boolean;
35
+ /**
36
+ * Resolve a nameref chain to the final variable name.
37
+ * Returns the original name if it's not a nameref.
38
+ * Detects circular references and returns undefined.
39
+ *
40
+ * @param ctx - The interpreter context
41
+ * @param name - The variable name to resolve
42
+ * @param maxDepth - Maximum chain depth to prevent infinite loops (default 100)
43
+ * @returns The resolved variable name, or undefined if circular reference detected
44
+ */
45
+ export declare function resolveNameref(ctx: InterpreterContext, name: string, maxDepth?: number): string | undefined;
46
+ /**
47
+ * Get the target name of a nameref (what it points to).
48
+ * Returns the variable's value if it's a nameref, undefined otherwise.
49
+ */
50
+ export declare function getNamerefTarget(ctx: InterpreterContext, name: string): string | undefined;
51
+ /**
52
+ * Resolve a nameref for assignment purposes.
53
+ * Unlike resolveNameref, this will resolve to the target variable name
54
+ * even if the target doesn't exist yet (allowing creation).
55
+ *
56
+ * @param ctx - The interpreter context
57
+ * @param name - The variable name to resolve
58
+ * @param valueBeingAssigned - The value being assigned (needed for empty nameref handling)
59
+ * @param maxDepth - Maximum chain depth to prevent infinite loops
60
+ * @returns
61
+ * - undefined if circular reference detected
62
+ * - null if the nameref is empty and value is not an existing variable (skip assignment)
63
+ * - The resolved target name otherwise (may be the nameref itself if target is invalid)
64
+ */
65
+ export declare function resolveNamerefForAssignment(ctx: InterpreterContext, name: string, valueBeingAssigned?: string, maxDepth?: number): string | null | undefined;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Shell value quoting utilities
3
+ *
4
+ * Provides functions for quoting values in shell output format,
5
+ * used by both `set` and `declare/typeset` builtins.
6
+ */
7
+ /**
8
+ * Quote a value for shell output (used by 'set' and 'typeset' with no args)
9
+ * Matches bash's output format:
10
+ * - No quotes for simple alphanumeric values
11
+ * - Single quotes for values with spaces or shell metacharacters
12
+ * - $'...' quoting for values with control characters
13
+ */
14
+ export declare function quoteValue(value: string): string;
15
+ /**
16
+ * Quote a value for array element output
17
+ * Uses $'...' for control characters, double quotes otherwise
18
+ */
19
+ export declare function quoteArrayValue(value: string): string;
20
+ /**
21
+ * Quote a value for declare -p output
22
+ * Uses $'...' for control characters, double quotes otherwise
23
+ */
24
+ export declare function quoteDeclareValue(value: string): string;
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Readonly variable helpers.
2
+ * Readonly and export variable helpers.
3
3
  *
4
- * Consolidates readonly variable logic used in declare, export, local, etc.
4
+ * Consolidates readonly and export variable logic used in declare, export, local, etc.
5
5
  */
6
6
  import type { ExecResult } from "../../types.js";
7
7
  import type { InterpreterContext } from "../types.js";
@@ -10,12 +10,36 @@ import type { InterpreterContext } from "../types.js";
10
10
  */
11
11
  export declare function markReadonly(ctx: InterpreterContext, name: string): void;
12
12
  /**
13
- * Check if a variable is readonly and return an error if so.
13
+ * Check if a variable is readonly.
14
+ */
15
+ export declare function isReadonly(ctx: InterpreterContext, name: string): boolean;
16
+ /**
17
+ * Check if a variable is readonly and throw an error if so.
14
18
  * Returns null if the variable is not readonly (can be modified).
15
19
  *
20
+ * Assigning to a readonly variable is a fatal error that stops script execution.
21
+ * This matches the behavior of dash, mksh, ash, and bash in POSIX mode.
22
+ * (Note: bash in non-POSIX mode has a bug where multi-line readonly assignment
23
+ * continues execution, but one-line still stops. We always stop.)
24
+ *
16
25
  * @param ctx - Interpreter context
17
26
  * @param name - Variable name
18
27
  * @param command - Command name for error message (default: "bash")
19
- * @returns Error result if readonly, null otherwise
28
+ * @returns null if variable is not readonly (can be modified)
29
+ * @throws ExitError if variable is readonly
20
30
  */
21
31
  export declare function checkReadonlyError(ctx: InterpreterContext, name: string, command?: string): ExecResult | null;
32
+ /**
33
+ * Mark a variable as exported.
34
+ *
35
+ * If we're inside a local scope and the variable is local (exists in the
36
+ * current scope), track it as a locally-exported variable. When the scope
37
+ * is popped, the export attribute will be removed if it wasn't exported
38
+ * before entering the function.
39
+ */
40
+ export declare function markExported(ctx: InterpreterContext, name: string): void;
41
+ /**
42
+ * Remove the export attribute from a variable.
43
+ * The variable value is preserved, just no longer exported to child processes.
44
+ */
45
+ export declare function unmarkExported(ctx: InterpreterContext, name: string): void;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shell Constants
3
+ *
4
+ * Constants for shell builtins, keywords, and POSIX special builtins.
5
+ */
6
+ /**
7
+ * POSIX special built-in commands.
8
+ * In POSIX mode, these have special behaviors:
9
+ * - Prefix assignments persist after the command
10
+ * - Cannot be redefined as functions
11
+ * - Errors may be fatal
12
+ */
13
+ export declare const POSIX_SPECIAL_BUILTINS: Set<string>;
14
+ /**
15
+ * Check if a command name is a POSIX special built-in
16
+ */
17
+ export declare function isPosixSpecialBuiltin(name: string): boolean;
18
+ /**
19
+ * Shell keywords (for type, command -v, etc.)
20
+ */
21
+ export declare const SHELL_KEYWORDS: Set<string>;
22
+ /**
23
+ * Shell builtins (for type, command -v, builtin, etc.)
24
+ */
25
+ export declare const SHELL_BUILTINS: Set<string>;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * SHELLOPTS and BASHOPTS variable helpers.
3
+ *
4
+ * SHELLOPTS is a colon-separated list of enabled shell options from `set -o`.
5
+ * BASHOPTS is a colon-separated list of enabled bash-specific options from `shopt`.
6
+ */
7
+ import type { InterpreterContext, ShellOptions, ShoptOptions } from "../types.js";
8
+ /**
9
+ * Build the SHELLOPTS string from current shell options.
10
+ * Returns a colon-separated list of enabled options (alphabetically sorted).
11
+ * Includes always-on options like braceexpand, hashall, interactive-comments.
12
+ */
13
+ export declare function buildShellopts(options: ShellOptions): string;
14
+ /**
15
+ * Update the SHELLOPTS environment variable to reflect current shell options.
16
+ * Should be called whenever shell options change (via set -o or shopt -o).
17
+ */
18
+ export declare function updateShellopts(ctx: InterpreterContext): void;
19
+ /**
20
+ * Build the BASHOPTS string from current shopt options.
21
+ * Returns a colon-separated list of enabled options (alphabetically sorted).
22
+ */
23
+ export declare function buildBashopts(shoptOptions: ShoptOptions): string;
24
+ /**
25
+ * Update the BASHOPTS environment variable to reflect current shopt options.
26
+ * Should be called whenever shopt options change.
27
+ */
28
+ export declare function updateBashopts(ctx: InterpreterContext): void;
@@ -17,6 +17,8 @@ export declare function isStringCompareOp(op: string): op is StringCompareOp;
17
17
  * @param left - Left operand
18
18
  * @param right - Right operand
19
19
  * @param usePattern - If true, use glob pattern matching for equality (default: false)
20
+ * @param nocasematch - If true, use case-insensitive comparison (default: false)
21
+ * @param extglob - If true, enable extended glob patterns @(), *(), +(), ?(), !() (default: false)
20
22
  * @returns True if the comparison succeeds
21
23
  */
22
- export declare function compareStrings(op: StringCompareOp, left: string, right: string, usePattern?: boolean): boolean;
24
+ export declare function compareStrings(op: StringCompareOp, left: string, right: string, usePattern?: boolean, nocasematch?: boolean, extglob?: boolean): boolean;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Tilde expansion helper functions.
3
+ *
4
+ * Handles ~ expansion in assignment contexts.
5
+ */
6
+ import type { InterpreterContext } from "../types.js";
7
+ /**
8
+ * Expand tildes in assignment values (PATH-like expansion)
9
+ * - ~ at start expands to HOME
10
+ * - ~ after : expands to HOME (for PATH-like values)
11
+ * - ~username expands to user's home (only root supported)
12
+ */
13
+ export declare function expandTildesInValue(ctx: InterpreterContext, value: string): string;
@@ -6,4 +6,4 @@ import type { InterpreterContext } from "../types.js";
6
6
  * @param ctx - Interpreter context with environment variables
7
7
  * @param operand - The variable name to test, may include array subscript (e.g., "arr[0]", "arr[-1]")
8
8
  */
9
- export declare function evaluateVariableTest(ctx: InterpreterContext, operand: string): boolean;
9
+ export declare function evaluateVariableTest(ctx: InterpreterContext, operand: string): Promise<boolean>;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Interpreter Utility Functions
3
+ *
4
+ * Standalone helper functions used by the interpreter.
5
+ */
6
+ import type { WordNode } from "../../ast/types.js";
7
+ /**
8
+ * Check if a WordNode is a literal match for any of the given strings.
9
+ * Returns true only if the word is a single literal (no expansions, no quoting)
10
+ * that matches one of the target strings.
11
+ *
12
+ * This is used to detect assignment builtins at "parse time" - bash determines
13
+ * whether a command is export/declare/etc based on the literal token, not the
14
+ * runtime value after expansion.
15
+ */
16
+ export declare function isWordLiteralMatch(word: WordNode, targets: string[]): boolean;
17
+ /**
18
+ * Parse the content of a read-write file descriptor.
19
+ * Format: __rw__:pathLength:path:position:content
20
+ * @returns The parsed components, or null if format is invalid
21
+ */
22
+ export declare function parseRwFdContent(fdContent: string): {
23
+ path: string;
24
+ position: number;
25
+ content: string;
26
+ } | null;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * xtrace (set -x) helper functions
3
+ *
4
+ * Handles trace output generation when xtrace option is enabled.
5
+ * PS4 variable controls the prefix (default "+ ").
6
+ * PS4 is expanded (variable substitution) before each trace line.
7
+ */
8
+ import type { InterpreterContext } from "../types.js";
9
+ /**
10
+ * Generate xtrace output for a simple command.
11
+ * Returns the trace line to be added to stderr.
12
+ */
13
+ export declare function traceSimpleCommand(ctx: InterpreterContext, commandName: string, args: string[]): Promise<string>;
14
+ /**
15
+ * Generate xtrace output for an assignment.
16
+ * Returns the trace line to be added to stderr.
17
+ */
18
+ export declare function traceAssignment(ctx: InterpreterContext, name: string, value: string): Promise<string>;
@@ -34,28 +34,27 @@ export interface InterpreterOptions {
34
34
  export declare class Interpreter {
35
35
  private ctx;
36
36
  constructor(options: InterpreterOptions, state: InterpreterState);
37
+ /**
38
+ * Build environment record containing only exported variables.
39
+ * In bash, only exported variables are passed to child processes.
40
+ * This includes both permanently exported variables (via export/declare -x)
41
+ * and temporarily exported variables (prefix assignments like FOO=bar cmd).
42
+ */
43
+ private buildExportedEnv;
37
44
  executeScript(node: ScriptNode): Promise<ExecResult>;
45
+ /**
46
+ * Execute a user script file found in PATH.
47
+ */
48
+ private executeUserScript;
38
49
  private executeStatement;
39
50
  private executePipeline;
40
51
  private executeCommand;
41
52
  private executeSimpleCommand;
42
53
  private executeSimpleCommandInner;
43
54
  private runCommand;
44
- /**
45
- * Resolve a command name to its implementation via PATH lookup.
46
- * Returns the command and its resolved path, or null if not found.
47
- *
48
- * Resolution order:
49
- * 1. If command contains "/", resolve as a path
50
- * 2. Search PATH directories for the command file
51
- * 3. Fall back to registry lookup (for non-InMemoryFs filesystems like OverlayFs)
52
- */
53
- private resolveCommand;
54
- /**
55
- * Find all paths for a command in PATH (for `which -a`).
56
- */
55
+ private aliasExpansionStack;
56
+ private expandAlias;
57
57
  findCommandInPath(commandName: string): Promise<string[]>;
58
- private handleType;
59
58
  private executeSubshell;
60
59
  private executeGroup;
61
60
  private executeArithmeticCommand;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Pipeline Execution
3
+ *
4
+ * Handles execution of command pipelines (cmd1 | cmd2 | cmd3).
5
+ */
6
+ import type { CommandNode, PipelineNode } from "../ast/types.js";
7
+ import type { ExecResult } from "../types.js";
8
+ import type { InterpreterContext } from "./types.js";
9
+ /**
10
+ * Type for executeCommand callback
11
+ */
12
+ export type ExecuteCommandFn = (node: CommandNode, stdin: string) => Promise<ExecResult>;
13
+ /**
14
+ * Execute a pipeline node (command or sequence of piped commands).
15
+ */
16
+ export declare function executePipeline(ctx: InterpreterContext, node: PipelineNode, executeCommand: ExecuteCommandFn): Promise<ExecResult>;
@@ -7,8 +7,45 @@
7
7
  * - 2> : Write stderr to file
8
8
  * - &> : Write both stdout and stderr to file
9
9
  * - >& : Redirect fd to another fd
10
+ * - {fd}>file : Allocate FD and store in variable
10
11
  */
11
12
  import type { RedirectionNode } from "../ast/types.js";
12
13
  import type { ExecResult } from "../types.js";
13
14
  import type { InterpreterContext } from "./types.js";
14
- export declare function applyRedirections(ctx: InterpreterContext, result: ExecResult, redirections: RedirectionNode[]): Promise<ExecResult>;
15
+ /**
16
+ * Pre-expanded redirect targets, keyed by index into the redirections array.
17
+ * This allows us to expand redirect targets (including side effects) before
18
+ * executing a function body, then apply the redirections after.
19
+ */
20
+ export type ExpandedRedirectTargets = Map<number, string>;
21
+ /**
22
+ * Pre-expand redirect targets for function definitions.
23
+ * This is needed because redirections on function definitions are evaluated
24
+ * each time the function is called, and any side effects (like $((i++)))
25
+ * must occur BEFORE the function body executes.
26
+ */
27
+ export declare function preExpandRedirectTargets(ctx: InterpreterContext, redirections: RedirectionNode[]): Promise<{
28
+ targets: ExpandedRedirectTargets;
29
+ error?: string;
30
+ }>;
31
+ /**
32
+ * Process FD variable redirections ({varname}>file syntax).
33
+ * This allocates FDs and sets variables before command execution.
34
+ * Returns an error result if there's an issue, or null if successful.
35
+ */
36
+ export declare function processFdVariableRedirections(ctx: InterpreterContext, redirections: RedirectionNode[]): Promise<ExecResult | null>;
37
+ /**
38
+ * Pre-open (truncate) output redirect files before command execution.
39
+ * This is needed for compound commands (subshell, for, case, [[) where
40
+ * bash opens/truncates the redirect file BEFORE evaluating any words in
41
+ * the command body (including command substitutions).
42
+ *
43
+ * Example: `(echo \`cat FILE\`) > FILE`
44
+ * - Bash first truncates FILE (making it empty)
45
+ * - Then executes the subshell, where `cat FILE` returns empty string
46
+ *
47
+ * Returns an error result if there's an issue (like directory or noclobber),
48
+ * or null if pre-opening succeeded.
49
+ */
50
+ export declare function preOpenOutputRedirects(ctx: InterpreterContext, redirections: RedirectionNode[]): Promise<ExecResult | null>;
51
+ export declare function applyRedirections(ctx: InterpreterContext, result: ExecResult, redirections: RedirectionNode[], preExpandedTargets?: ExpandedRedirectTargets): Promise<ExecResult>;