@poe-platform/safe-bash 0.1.802 → 0.1.804
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.
- package/README.md +60 -33
- package/dist/image-ast/ast.d.ts +1 -0
- package/dist/image-ast/browser/ast.d.ts +1 -0
- package/dist/image-ast/browser/codecs/jpeg.d.ts +2 -2
- package/dist/image-ast/codecs/jpeg.d.ts +2 -2
- package/dist/image-ast/index.browser.js +692 -8355
- package/dist/image-ast/index.js +692 -8355
- package/dist/mp4-ast/codecs.d.ts +7 -2
- package/dist/safe-bash/chunks/{chunk-CHYGPFVM.js → chunk-22SX3F2R.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-FBUCWVTE.js → chunk-2IVBJTBD.js} +1 -1
- package/dist/safe-bash/chunks/chunk-2POETUMB.js +190 -0
- package/dist/safe-bash/chunks/{chunk-XVOSKJE2.js → chunk-47D7WBJK.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-VKNVHEX3.js → chunk-4ESI236Y.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-74GHTNJA.js → chunk-4KTMKD5W.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-55YJASTN.js → chunk-4T53AERN.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-DQP3VHSB.js → chunk-5XIFJVOO.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-NZQXYWA3.js → chunk-62BOHHJT.js} +1 -2
- package/dist/safe-bash/chunks/{chunk-HZAMGT5I.js → chunk-67WIFM3N.js} +17 -6
- package/dist/safe-bash/chunks/{chunk-4D4N7IU2.js → chunk-6LNFRPW5.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-6O77NL2S.js → chunk-6SMICPI3.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-4BSJLKNM.js → chunk-7O76UFQD.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-44ALJ4QG.js → chunk-AW5KIT6V.js} +3549 -84
- package/dist/safe-bash/chunks/{chunk-RSTHLAF3.js → chunk-B2Z73HTZ.js} +52 -28
- package/dist/safe-bash/chunks/chunk-B3ZMOJVM.js +319 -0
- package/dist/safe-bash/chunks/{chunk-7ZBU7KYV.js → chunk-CFAWS3O4.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-I5HZ4FGE.js → chunk-CL2FCTTO.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-KDNSPLII.js → chunk-CTXNARJH.js} +2 -1
- package/dist/safe-bash/chunks/{chunk-TFIBK2GI.js → chunk-D5Q7NFWI.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-OQRVVGR6.js → chunk-DSOOVZ6Q.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-VTH3MLDU.js → chunk-DUTAG6ZD.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-XAQMU6OY.js → chunk-EE5YGFIZ.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-FZE4HW6G.js → chunk-EJOYT2ME.js} +1 -1
- package/dist/safe-bash/chunks/chunk-FAAIR6EJ.js +887 -0
- package/dist/safe-bash/chunks/{chunk-OV6IHKO6.js → chunk-FOB2FZR4.js} +2 -2
- package/dist/safe-bash/chunks/chunk-G6V4RRSQ.js +14 -0
- package/dist/safe-bash/chunks/{chunk-UTBUUFDM.js → chunk-GGQAGQXQ.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-K6VCD7IY.js → chunk-HIIYIJ5G.js} +2 -4
- package/dist/safe-bash/chunks/chunk-IOHH2GTI.js +56 -0
- package/dist/safe-bash/chunks/{chunk-CTVWDACF.js → chunk-IQW34XQT.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-HZ7BWKQ3.js → chunk-IS572AAT.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-AUSNDQTJ.js → chunk-JPSUHHOA.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-ZVD5IS4V.js → chunk-KBZ4UB2O.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-AM5ESLPH.js → chunk-KU5CVWKA.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-NQCM3TYR.js → chunk-LPOVNKNB.js} +225 -176
- package/dist/safe-bash/chunks/{chunk-46Z5E5EV.js → chunk-MBOC3LZ4.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-6PAVEFT3.js → chunk-N4BQFD3P.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-CS4MNM6I.js → chunk-NGKCVNWS.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-7R5BDCG7.js → chunk-OHML2BEU.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-C5OWC2TL.js → chunk-OQ3AGYCZ.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-B7TAL7S5.js → chunk-PTAEWLSE.js} +0 -2
- package/dist/safe-bash/chunks/{chunk-LVOBFF4D.js → chunk-Q4FNLOTI.js} +1 -1
- package/dist/safe-bash/chunks/chunk-Q5XO3NAS.js +1036 -0
- package/dist/safe-bash/chunks/{chunk-GEG3BWGE.js → chunk-RHFRJIWQ.js} +1 -1
- package/dist/safe-bash/chunks/chunk-RUR6J33T.js +11 -0
- package/dist/safe-bash/chunks/{chunk-WDLGKIHD.js → chunk-S4RFUUXO.js} +841 -26
- package/dist/safe-bash/chunks/{chunk-RRR7AQ24.js → chunk-SD2ISU5L.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-3NDIFSNM.js → chunk-SUJ3NTMH.js} +3 -3
- package/dist/safe-bash/chunks/{chunk-R3NAKOED.js → chunk-SZRUU5HS.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-PH63PLPZ.js → chunk-TC3F4UFF.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-3R3AANOR.js → chunk-TCKYOLUE.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-D3ANYGMC.js → chunk-UV4X32QU.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-E7OYNDGL.js → chunk-V7QT2RWC.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-SHEMU2Z7.js → chunk-W2IYOVHK.js} +839 -1211
- package/dist/safe-bash/chunks/{chunk-3HQU4OJO.js → chunk-XNGVOSGI.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-J42RIHHJ.js → chunk-XQWCQSRN.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-BJA5XNP6.js → chunk-Y7FW6GLT.js} +6 -6
- package/dist/safe-bash/chunks/{chunk-QGUV42T5.js → chunk-YL3GBUG4.js} +1 -1
- package/dist/safe-bash/chunks/chunk-YOXUCJER.js +389 -0
- package/dist/safe-bash/chunks/{chunk-HBCN24ZA.js → chunk-Z2AAYYJN.js} +2 -2
- package/dist/safe-bash/chunks/chunk-ZKYKJCZZ.js +30 -0
- package/dist/safe-bash/chunks/core-IE3AFIDX.js +85806 -0
- package/dist/safe-bash/chunks/{ffmpeg-WTC3TEFI.js → ffmpeg-YANDK6HU.js} +2 -2
- package/dist/safe-bash/chunks/{gh-6WU6PXL4.js → gh-4MBJ2S5V.js} +2 -2
- package/dist/safe-bash/chunks/{git-EFZIGJW4.js → git-2QONJNRQ.js} +2 -2
- package/dist/safe-bash/chunks/{imagemagick-EIEYGWPF.js → imagemagick-JLEHGYSN.js} +2 -2
- package/dist/safe-bash/chunks/{mmdc-ROQJT5HQ.js → mmdc-6LD7A6ND.js} +2 -2
- package/dist/safe-bash/chunks/{pdfimages-DW7LWXFI.js → pdfimages-RSHL7LOP.js} +2 -2
- package/dist/safe-bash/chunks/{pdfinfo-TIP6XLUQ.js → pdfinfo-L3SGWPNG.js} +2 -2
- package/dist/safe-bash/chunks/{pdftk-DMG22ITZ.js → pdftk-LFBJNU5A.js} +2 -2
- package/dist/safe-bash/chunks/{pdftoppm-WNDYR72T.js → pdftoppm-NXXFUIHG.js} +2 -2
- package/dist/safe-bash/chunks/{pdftotext-5IPZ4NI7.js → pdftotext-4IHNWT6F.js} +2 -2
- package/dist/safe-bash/chunks/{qpdf-TTX2DIUA.js → qpdf-ZEIREV63.js} +2 -2
- package/dist/safe-bash/chunks/read-builtin-A4QKAT45.js +9 -0
- package/dist/safe-bash/chunks/{sips-XYS46JPJ.js → sips-D5YBG2V3.js} +2 -2
- package/dist/safe-bash/chunks/{soffice-TU73E5KL.js → soffice-RAJU3JUT.js} +2 -2
- package/dist/safe-bash/chunks/source-files-3XWRRHFA.js +7 -0
- package/dist/safe-bash/chunks/{wkhtmltopdf-FSZ2CHGE.js → wkhtmltopdf-7UE4FORZ.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-7KWZXKY6.js → chunk-26RTBV2I.js} +1 -0
- package/dist/safe-bash/command-chunks/{chunk-AQJ2ROJO.js → chunk-2WYNMZR2.js} +10 -8
- package/dist/safe-bash/command-chunks/{chunk-BDSMROQZ.js → chunk-36GFRF2N.js} +2 -1
- package/dist/safe-bash/command-chunks/{chunk-GC5TJZOF.js → chunk-3VIA2IA7.js} +114 -31
- package/dist/safe-bash/command-chunks/{chunk-NKFYQSES.js → chunk-4CTI3ZTX.js} +1 -0
- package/dist/safe-bash/command-chunks/{chunk-WH627NJL.js → chunk-4MYP2FX4.js} +2 -1
- package/dist/safe-bash/command-chunks/chunk-4R5ADJM5.js +178 -0
- package/dist/safe-bash/command-chunks/{chunk-P2N33UMN.js → chunk-5MIKM54M.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-DB453IE6.js → chunk-6FZQUOSJ.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-WPYIOKE3.js → chunk-6GKYHPJG.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-7K6JYKPJ.js → chunk-6M2ELGEN.js} +17 -15
- package/dist/safe-bash/command-chunks/{chunk-PXEIT2O4.js → chunk-6UR7V3ET.js} +8 -1
- package/dist/safe-bash/command-chunks/{chunk-6KJ3LPI2.js → chunk-6XBS5B46.js} +26 -3
- package/dist/safe-bash/command-chunks/{chunk-5PWJG2UK.js → chunk-6YXLZX7L.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-EK6YNAXT.js → chunk-753YOR54.js} +31 -5
- package/dist/safe-bash/command-chunks/{chunk-RMWQAAO5.js → chunk-7IR4NRNE.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-FZTK4MFI.js → chunk-7NM73SVK.js} +8 -8
- package/dist/safe-bash/command-chunks/{chunk-NXEQ3ESQ.js → chunk-7QD5YY4F.js} +6 -11
- package/dist/safe-bash/command-chunks/{chunk-EMPU65ZK.js → chunk-A5LBSJGH.js} +1 -0
- package/dist/safe-bash/command-chunks/chunk-A7MU7762.js +200 -0
- package/dist/safe-bash/command-chunks/{chunk-ORYGZYKW.js → chunk-ARZMP2L2.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-OQKC5ZU2.js → chunk-BAKFZ477.js} +62 -20
- package/dist/safe-bash/command-chunks/{chunk-QRRYN2KO.js → chunk-BC7BK6R6.js} +0 -2424
- package/dist/safe-bash/command-chunks/{chunk-F4TEEZTL.js → chunk-BOEOJS2Q.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-XS72HTMA.js → chunk-BWGGLYEB.js} +5 -22
- package/dist/safe-bash/command-chunks/{chunk-PMBFZXTK.js → chunk-C5ZZKP7V.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-LHIOAFWW.js → chunk-C7SEB6WU.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-XPT2UGBF.js → chunk-CHJKFRT7.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-TIOCQVUQ.js → chunk-CON26Q2O.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-E55UKBIE.js → chunk-DBAT3IK2.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-Z45N42QC.js → chunk-DPAYAVMS.js} +15 -1
- package/dist/safe-bash/command-chunks/chunk-DS3NXVUM.js +368 -0
- package/dist/safe-bash/command-chunks/{chunk-5ZMZ573Q.js → chunk-DSJ3VRL3.js} +16 -4
- package/dist/safe-bash/command-chunks/{chunk-K2GDEMEU.js → chunk-EFRCFWVR.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-DZCY63VJ.js → chunk-EV6HIJ5H.js} +6 -5
- package/dist/safe-bash/command-chunks/{chunk-JDYXY44P.js → chunk-FJURV46Y.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-TZZ4WUKH.js → chunk-FZAWGKSE.js} +6 -4
- package/dist/safe-bash/command-chunks/{chunk-YHFXOX6U.js → chunk-GOCFQ6XV.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-YOFC45RK.js → chunk-HH5O7DJI.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-3HHCU5YU.js → chunk-HK7F5SDC.js} +13 -0
- package/dist/safe-bash/command-chunks/{chunk-JNZ3CVAE.js → chunk-HQBXIZC7.js} +8 -3
- package/dist/safe-bash/command-chunks/{chunk-2JRBIDAD.js → chunk-I63DBZXZ.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-WNE7FPVR.js → chunk-I64TLTIW.js} +24 -16
- package/dist/safe-bash/command-chunks/{chunk-QKFSRZGQ.js → chunk-ICANWOXH.js} +7 -31
- package/dist/safe-bash/command-chunks/{chunk-SQRQW3CT.js → chunk-IJ6LGLXM.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-5E4WAO4O.js → chunk-JD5QNRNO.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-KJIMDLBB.js → chunk-JNANXVJV.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-TGSNCQSR.js → chunk-JT4RYCA6.js} +1771 -1663
- package/dist/safe-bash/command-chunks/{chunk-II77KPZN.js → chunk-JWW6FYBN.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-ZYXH3B66.js → chunk-LCJWKTCJ.js} +250 -203
- package/dist/safe-bash/command-chunks/{chunk-I237SNW5.js → chunk-LFJJQQND.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-LU4HBPP2.js +97 -0
- package/dist/safe-bash/command-chunks/{chunk-XJXU3VVH.js → chunk-LWOE65OE.js} +20 -5
- package/dist/safe-bash/command-chunks/{chunk-GMIHJYDG.js → chunk-M32HFSX7.js} +22 -6
- package/dist/safe-bash/command-chunks/{chunk-YG4EPFWC.js → chunk-M3NINRDU.js} +2880 -172
- package/dist/safe-bash/command-chunks/chunk-MQREDAL6.js +164 -0
- package/dist/safe-bash/command-chunks/{chunk-LWS62ISU.js → chunk-N6DIASO2.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-NGL7YK7O.js +188 -0
- package/dist/safe-bash/command-chunks/{chunk-PEF7K3UQ.js → chunk-NJYHWKIL.js} +40 -10
- package/dist/safe-bash/command-chunks/{chunk-VXSLJH7G.js → chunk-OJQRSCBP.js} +27 -7
- package/dist/safe-bash/command-chunks/{chunk-OQU6UT6X.js → chunk-OV3XREFN.js} +11 -0
- package/dist/safe-bash/command-chunks/{chunk-MIXBO6U7.js → chunk-PTZLF456.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-ALDC4XP4.js → chunk-QILLRNES.js} +34 -10
- package/dist/safe-bash/command-chunks/{chunk-L22T3H7L.js → chunk-QR25JLKO.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-7U7EXOXX.js → chunk-R7C4MGZ5.js} +17 -223
- package/dist/safe-bash/command-chunks/{chunk-LCF3OB7P.js → chunk-RBME3JEH.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-2KG2QLJE.js → chunk-RFWGYT7G.js} +3 -0
- package/dist/safe-bash/command-chunks/{chunk-5TBUOBDE.js → chunk-RZMVRT26.js} +27 -13
- package/dist/safe-bash/command-chunks/chunk-TFR6B3WB.js +44 -0
- package/dist/safe-bash/command-chunks/chunk-TOH3OF3O.js +179 -0
- package/dist/safe-bash/command-chunks/{chunk-VGG2DL5Q.js → chunk-TRR4MYWF.js} +4 -0
- package/dist/safe-bash/command-chunks/chunk-TT4DAFBT.js +13621 -0
- package/dist/safe-bash/command-chunks/{chunk-LWSBAWLT.js → chunk-TXI64OAG.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-TZRI7BJZ.js +496 -0
- package/dist/safe-bash/command-chunks/{chunk-QOKBZFFD.js → chunk-U3MMODA5.js} +2 -7
- package/dist/safe-bash/command-chunks/{chunk-ZYHTWNAE.js → chunk-UAW423ZL.js} +11 -11
- package/dist/safe-bash/command-chunks/{chunk-C5YYCQHW.js → chunk-UXEEUGOV.js} +222 -12
- package/dist/safe-bash/command-chunks/{chunk-GY3BWK7K.js → chunk-VOZPMJRX.js} +87 -80
- package/dist/safe-bash/command-chunks/{chunk-MQFIPHIQ.js → chunk-WPANOB4A.js} +38 -35
- package/dist/safe-bash/command-chunks/{chunk-Y2WBSJG6.js → chunk-X4QZQI5Q.js} +65 -64
- package/dist/safe-bash/command-chunks/{chunk-FPVUD6TH.js → chunk-XGI57GCN.js} +10 -8
- package/dist/safe-bash/command-chunks/{chunk-5UBXNSFZ.js → chunk-XUCU7QQT.js} +1281 -1278
- package/dist/safe-bash/command-chunks/chunk-Y22VXJBD.js +296 -0
- package/dist/safe-bash/command-chunks/{chunk-WVHONVZ4.js → chunk-YMFUUPDX.js} +5 -3
- package/dist/safe-bash/command-chunks/{chunk-IR2BY7EL.js → chunk-YYGIBXFZ.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-MSFXC3OC.js → chunk-Z4FO6OHE.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-6GWJUQAV.js → chunk-Z5ZZVDUD.js} +181 -133
- package/dist/safe-bash/command-chunks/{chunk-W5DNF4JH.js → chunk-ZHN3QDCI.js} +1 -1
- package/dist/safe-bash/commands/alias/index.d.ts +2 -0
- package/dist/safe-bash/commands/alias/index.js +2 -0
- package/dist/safe-bash/commands/apply-patch/index.browser.js +2 -3
- package/dist/safe-bash/commands/apply-patch/index.d.ts +0 -1
- package/dist/safe-bash/commands/apply-patch/index.js +0 -1
- package/dist/safe-bash/commands/archive/index.browser.js +2 -3
- package/dist/safe-bash/commands/archive/index.d.ts +0 -1
- package/dist/safe-bash/commands/archive/index.js +0 -1
- package/dist/safe-bash/commands/bytes/compression/index.js +54 -51
- package/dist/safe-bash/commands/bytes/index.js +2 -1
- package/dist/safe-bash/commands/chmod/index.browser.js +14 -0
- package/dist/safe-bash/commands/chmod/index.d.ts +2 -0
- package/dist/safe-bash/commands/chmod/index.js +2 -0
- package/dist/safe-bash/commands/column/index.browser.js +2 -3
- package/dist/safe-bash/commands/column/index.d.ts +0 -1
- package/dist/safe-bash/commands/column/index.js +0 -1
- package/dist/safe-bash/commands/copy-source.js +1 -0
- package/dist/safe-bash/commands/csplit/index.browser.js +2 -2
- package/dist/safe-bash/commands/csvkit/index.browser.js +72 -0
- package/dist/safe-bash/commands/csvkit/index.d.ts +0 -5
- package/dist/safe-bash/commands/csvkit/index.js +0 -50
- package/dist/safe-bash/commands/docx/index.browser.js +5 -7
- package/dist/safe-bash/commands/du/index.browser.js +2 -3
- package/dist/safe-bash/commands/du/index.d.ts +0 -1
- package/dist/safe-bash/commands/du/index.js +0 -1
- package/dist/safe-bash/commands/expr/index.browser.js +2 -3
- package/dist/safe-bash/commands/expr/index.d.ts +0 -1
- package/dist/safe-bash/commands/expr/index.js +0 -1
- package/dist/safe-bash/commands/factor/index.browser.js +2 -2
- package/dist/safe-bash/commands/file/index.browser.js +2 -3
- package/dist/safe-bash/commands/file/index.d.ts +0 -1
- package/dist/safe-bash/commands/file/index.js +0 -1
- package/dist/safe-bash/commands/filesystem.js +1 -1
- package/dist/safe-bash/commands/getopt/index.browser.js +2 -2
- package/dist/safe-bash/commands/grep-aliases/index.browser.js +3 -3
- package/dist/safe-bash/commands/hexdump/index.browser.js +2 -2
- package/dist/safe-bash/commands/html-to-markdown/index.browser.js +2 -3
- package/dist/safe-bash/commands/html-to-markdown/index.d.ts +0 -1
- package/dist/safe-bash/commands/html-to-markdown/index.js +0 -1
- package/dist/safe-bash/commands/htmlq/index.d.ts +1 -5
- package/dist/safe-bash/commands/htmlq/index.js +1 -143
- package/dist/safe-bash/commands/iconv/index.browser.js +2 -2
- package/dist/safe-bash/commands/line-endings/index.browser.js +2 -2
- package/dist/safe-bash/commands/llm/index.browser.js +2 -2
- package/dist/safe-bash/commands/llm/providers/index.browser.js +1 -1
- package/dist/safe-bash/commands/mdq/index.browser.js +3 -3
- package/dist/safe-bash/commands/media/index.browser.js +4 -16314
- package/dist/safe-bash/commands/media/index.d.ts +1 -5
- package/dist/safe-bash/commands/media/index.js +1 -3
- package/dist/safe-bash/commands/media/plugin.d.ts +1 -18
- package/dist/safe-bash/commands/media/plugin.js +1 -90
- package/dist/safe-bash/commands/media/remote.d.ts +1 -63
- package/dist/safe-bash/commands/media/remote.js +1 -405
- package/dist/safe-bash/commands/media/settings.d.ts +1 -4
- package/dist/safe-bash/commands/media/settings.js +1 -26
- package/dist/safe-bash/commands/metadata/chmod.d.ts +1 -7
- package/dist/safe-bash/commands/metadata/chmod.js +1 -204
- package/dist/safe-bash/commands/metadata/index.browser.js +3 -8
- package/dist/safe-bash/commands/metadata/index.d.ts +0 -1
- package/dist/safe-bash/commands/metadata/index.js +2 -2
- package/dist/safe-bash/commands/metadata/internal.d.ts +1 -30
- package/dist/safe-bash/commands/metadata/internal.js +1 -76
- package/dist/safe-bash/commands/metadata/mktemp.d.ts +1 -3
- package/dist/safe-bash/commands/metadata/mktemp.js +1 -202
- package/dist/safe-bash/commands/metadata/stat.d.ts +1 -7
- package/dist/safe-bash/commands/metadata/stat.js +1 -530
- package/dist/safe-bash/commands/mktemp/index.browser.js +13 -0
- package/dist/safe-bash/commands/mktemp/index.d.ts +2 -0
- package/dist/safe-bash/commands/mktemp/index.js +2 -0
- package/dist/safe-bash/commands/network/curl.js +1 -3
- package/dist/safe-bash/commands/network/index.browser.js +3 -4
- package/dist/safe-bash/commands/network/public.d.ts +0 -1
- package/dist/safe-bash/commands/network/public.js +0 -1
- package/dist/safe-bash/commands/network/transport.js +2 -1
- package/dist/safe-bash/commands/network/wget.js +1 -3
- package/dist/safe-bash/commands/node/browser.d.ts +0 -1
- package/dist/safe-bash/commands/node/browser.js +0 -1
- package/dist/safe-bash/commands/node/default-runtime.d.ts +3 -0
- package/dist/safe-bash/commands/node/default-runtime.js +15 -0
- package/dist/safe-bash/commands/node/index.browser.js +7 -8
- package/dist/safe-bash/commands/node/index.js +3 -3
- package/dist/safe-bash/commands/node/path.js +1 -1
- package/dist/safe-bash/commands/node/preload.d.ts +1 -1
- package/dist/safe-bash/commands/node/preload.js +4 -1
- package/dist/safe-bash/commands/node/quickjs.d.ts +2 -0
- package/dist/safe-bash/commands/node/quickjs.js +2 -0
- package/dist/safe-bash/commands/node/safejs.js +26 -12
- package/dist/safe-bash/commands/op/index.browser.js +2 -3
- package/dist/safe-bash/commands/op/index.d.ts +0 -11
- package/dist/safe-bash/commands/op/index.js +0 -84
- package/dist/safe-bash/commands/pandoc/index.browser.js +44 -0
- package/dist/safe-bash/commands/pandoc/index.d.ts +0 -1
- package/dist/safe-bash/commands/pandoc/index.js +0 -1
- package/dist/safe-bash/commands/portable-random.d.ts +1 -1
- package/dist/safe-bash/commands/portable-random.js +1 -12
- package/dist/safe-bash/commands/pr/index.browser.js +2 -2
- package/dist/safe-bash/commands/python/docker-runner.js +4 -3
- package/dist/safe-bash/commands/python/docker.d.ts +1 -0
- package/dist/safe-bash/commands/python/docker.js +5 -2
- package/dist/safe-bash/commands/python/index.browser.js +17 -13
- package/dist/safe-bash/commands/python/index.d.ts +2 -1
- package/dist/safe-bash/commands/python/index.js +10 -8
- package/dist/safe-bash/commands/python/llm-capability.js +65 -2
- package/dist/safe-bash/commands/python/llm-dependencies.d.ts +27 -0
- package/dist/safe-bash/commands/python/llm-dependencies.js +66 -0
- package/dist/safe-bash/commands/python/llm-module.js +6 -4
- package/dist/safe-bash/commands/python/llm-reference-module.d.ts +3 -0
- package/dist/safe-bash/commands/python/llm-reference-module.js +690 -0
- package/dist/safe-bash/commands/python/worker.browser.js +2 -3
- package/dist/safe-bash/commands/python/worker.d.ts +0 -1
- package/dist/safe-bash/commands/python/worker.js +0 -1
- package/dist/safe-bash/commands/regex-execution/ere/transport/wire-engine.d.ts +1 -1
- package/dist/safe-bash/commands/regex-execution/ere/transport/wire-engine.js +3 -3
- package/dist/safe-bash/commands/regex-execution/public.browser.js +7 -7
- package/dist/safe-bash/commands/safejs/options.js +5 -1
- package/dist/safe-bash/commands/safejs/runtime.d.ts +1 -0
- package/dist/safe-bash/commands/safejs/runtime.js +1 -1
- package/dist/safe-bash/commands/split/index.browser.js +2 -3
- package/dist/safe-bash/commands/split/index.d.ts +0 -1
- package/dist/safe-bash/commands/split/index.js +0 -1
- package/dist/safe-bash/commands/ssconvert/index.browser.js +98 -0
- package/dist/safe-bash/commands/stat/index.browser.js +13 -0
- package/dist/safe-bash/commands/stat/index.d.ts +2 -0
- package/dist/safe-bash/commands/stat/index.js +2 -0
- package/dist/safe-bash/commands/stream-format/index.browser.js +3 -4
- package/dist/safe-bash/commands/stream-format/index.d.ts +0 -1
- package/dist/safe-bash/commands/stream-format/index.js +0 -1
- package/dist/safe-bash/commands/stream-inspection/index.browser.js +3 -4
- package/dist/safe-bash/commands/stream-inspection/index.d.ts +0 -1
- package/dist/safe-bash/commands/stream-inspection/index.js +0 -1
- package/dist/safe-bash/commands/streams.js +2 -1
- package/dist/safe-bash/commands/table-text/index.browser.js +3 -4
- package/dist/safe-bash/commands/table-text/index.d.ts +0 -1
- package/dist/safe-bash/commands/table-text/index.js +0 -1
- package/dist/safe-bash/commands/text.js +74 -34
- package/dist/safe-bash/commands/time-env/index.browser.js +3 -4
- package/dist/safe-bash/commands/time-env/index.d.ts +0 -1
- package/dist/safe-bash/commands/time-env/index.js +0 -1
- package/dist/safe-bash/commands/tree/index.browser.js +2 -3
- package/dist/safe-bash/commands/tree/index.d.ts +0 -1
- package/dist/safe-bash/commands/tree/index.js +0 -1
- package/dist/safe-bash/commands/tsort/index.browser.js +2 -2
- package/dist/safe-bash/commands/unalias/index.d.ts +2 -0
- package/dist/safe-bash/commands/unalias/index.js +2 -0
- package/dist/safe-bash/commands/xml/index.browser.js +2 -2
- package/dist/safe-bash/commands/yq/index.browser.js +2 -2
- package/dist/safe-bash/core.browser.js +2 -2
- package/dist/safe-bash/core.d.ts +7 -1
- package/dist/safe-bash/core.js +7 -1
- package/dist/safe-bash/execution-runtime.js +2 -1
- package/dist/safe-bash/fs/s3/http/index.d.ts +2 -2
- package/dist/safe-bash/fs/s3/http/index.js +1 -1
- package/dist/safe-bash/full-core.browser.js +254 -916
- package/dist/safe-bash/internal/op/types.d.ts +1 -0
- package/dist/safe-bash/jobs.browser.js +5 -5
- package/dist/safe-bash/lazy-optional.d.ts +3 -3
- package/dist/safe-bash/lazy-optional.js +1 -1
- package/dist/safe-bash/opt-in/commands/cmp/index.js +7 -6
- package/dist/safe-bash/opt-in/commands/dd/index.js +1 -1
- package/dist/safe-bash/opt-in/commands/dd/io.js +51 -5
- package/dist/safe-bash/opt-in/commands/truncate/index.js +2 -2
- package/dist/safe-bash/opt-in/commands/yq/native-work.js +3 -0
- package/dist/safe-bash/opt-in/optional/commands/shuf/input.js +2 -1
- package/dist/safe-bash/opt-in/optional/commands/shuf/shuf.js +4 -2
- package/dist/safe-bash/opt-in/optional.d.ts +1 -1
- package/dist/safe-bash/opt-in/optional.js +1 -1
- package/dist/safe-bash/opt-in/shell/extensions/read/index.js +2 -344
- package/dist/safe-bash/optional-host.browser.js +19 -14
- package/dist/safe-bash/optional-host.d.ts +1 -0
- package/dist/safe-bash/optional-host.js +1 -0
- package/dist/safe-bash/playwright/controller.js +41 -3
- package/dist/safe-bash/playwright/native-storage-targets.js +4 -2
- package/dist/safe-bash/plugins/base.d.ts +1 -1
- package/dist/safe-bash/plugins/base.js +3 -3
- package/dist/safe-bash/plugins/composition.d.ts +5 -2
- package/dist/safe-bash/plugins/composition.js +10 -7
- package/dist/safe-bash/plugins/index.browser.js +44 -41
- package/dist/safe-bash/plugins/index.js +3 -2
- package/dist/safe-bash/plugins/portable-commands.d.ts +3 -0
- package/dist/safe-bash/plugins/portable-commands.js +31 -0
- package/dist/safe-bash/registry-entry.browser.js +41 -42
- package/dist/safe-bash/search.browser.js +32 -33
- package/dist/safe-bash/shell/arithmetic.js +19 -6
- package/dist/safe-bash/shell/arrays/state.js +1 -1
- package/dist/safe-bash/shell/arrays/syntax.js +4 -3
- package/dist/safe-bash/shell/index.d.ts +0 -1
- package/dist/safe-bash/shell/index.js +0 -1
- package/dist/safe-bash/shell/parser.d.ts +2 -2
- package/dist/safe-bash/shell/parser.js +268 -64
- package/dist/safe-bash/shell/read-builtin.d.ts +3 -0
- package/dist/safe-bash/shell/read-builtin.js +344 -0
- package/dist/safe-bash/shell/runtime.d.ts +24 -4
- package/dist/safe-bash/shell/runtime.js +392 -414
- package/dist/safe-bash/shell/session-state.js +25 -0
- package/dist/safe-bash/shell/shell.js +76 -154
- package/dist/safe-bash/shell/tilde-expansion.d.ts +1 -1
- package/dist/safe-bash/shell/tilde-expansion.js +2 -2
- package/dist/safe-bash/shell/types.d.ts +7 -0
- package/dist/safe-bash/shell/value-state.js +1 -1
- package/dist/safe-bash/shell/worker-limits.js +1 -0
- package/dist/safe-bash/shell-entry.browser.js +32 -33
- package/dist/safe-bash/trap.browser.js +4 -4
- package/dist/safe-bash/worker/host.js +1 -1
- package/dist/safe-bash/yq-browser/index.js +1 -1
- package/dist/safe-bash-calendar-engine/time-env/calendar.d.ts +1 -1
- package/dist/safe-bash-calendar-engine/time-env/calendar.js +1 -1
- package/dist/safe-bash-calendar-engine/time-env/format.js +1 -1
- package/dist/safe-bash-command-alias/index.d.ts +13 -0
- package/dist/safe-bash-command-alias/index.js +88 -0
- package/dist/safe-bash-command-apply-patch/apply.js +3 -3
- package/dist/safe-bash-command-apply-patch/index.js +3 -3
- package/dist/safe-bash-command-apply-patch/matcher.js +1 -1
- package/dist/safe-bash-command-apply-patch/parser.js +1 -1
- package/dist/safe-bash-command-awk/awk-pipes.js +2 -2
- package/dist/safe-bash-command-awk/awk-reader.js +1 -1
- package/dist/safe-bash-command-awk/awk-runtime.js +3 -3
- package/dist/safe-bash-command-awk/awk.js +5 -5
- package/dist/safe-bash-command-awk/index.js +5 -5
- package/dist/safe-bash-command-bc/index.js +218 -65
- package/dist/safe-bash-command-bzip2/index.js +4 -3
- package/dist/safe-bash-command-chmod/LICENSE +21 -0
- package/dist/safe-bash-command-chmod/command.d.ts +7 -0
- package/dist/safe-bash-command-chmod/command.js +11 -0
- package/dist/safe-bash-command-chmod/index.d.ts +6 -0
- package/dist/safe-bash-command-chmod/index.js +27 -0
- package/dist/safe-bash-command-cmp/index.js +7 -6
- package/dist/safe-bash-command-column/column.js +3 -3
- package/dist/safe-bash-command-column/index.js +3 -3
- package/dist/safe-bash-command-column/layout.js +2 -2
- package/dist/safe-bash-command-csvkit/index.d.ts +1 -0
- package/dist/safe-bash-command-csvkit/index.js +1505 -7
- package/dist/safe-bash-command-csvkit/sync-support.js +2 -7
- package/dist/safe-bash-command-curl/curl.js +1 -1
- package/dist/safe-bash-command-curl/index.js +1 -1
- package/dist/safe-bash-command-date/date.js +1 -1
- package/dist/safe-bash-command-date/index.js +1 -1
- package/dist/safe-bash-command-dd/index.js +1 -1
- package/dist/safe-bash-command-dd/io.js +51 -5
- package/dist/safe-bash-command-diff/diff.js +1 -1
- package/dist/safe-bash-command-diff/index.js +1 -1
- package/dist/safe-bash-command-diff3/index.js +10 -13
- package/dist/safe-bash-command-exiftool/index.js +283 -55
- package/dist/safe-bash-command-exiftool/registry.d.ts +4 -2
- package/dist/safe-bash-command-factor/command.js +2 -2
- package/dist/safe-bash-command-factor/index.js +2 -2
- package/dist/safe-bash-command-fd/arguments.d.ts +2 -0
- package/dist/safe-bash-command-fd/index.js +42 -12
- package/dist/safe-bash-command-ffmpeg/index.js +356 -66
- package/dist/safe-bash-command-find/find-format.d.ts +3 -0
- package/dist/safe-bash-command-find/find-format.js +1 -1
- package/dist/safe-bash-command-find/find.js +2 -2
- package/dist/safe-bash-command-find/index.js +2 -2
- package/dist/safe-bash-command-fmt/index.js +10 -6
- package/dist/safe-bash-command-fold/engine.d.ts +1 -1
- package/dist/safe-bash-command-fold/family.js +2 -2
- package/dist/safe-bash-command-fold/index.js +1 -1
- package/dist/safe-bash-command-gzip/index.js +45 -42
- package/dist/safe-bash-command-hexdump/command.js +2 -2
- package/dist/safe-bash-command-hexdump/index.js +2 -2
- package/dist/safe-bash-command-html-to-markdown/entities.js +1 -1
- package/dist/safe-bash-command-html-to-markdown/index.js +4 -4
- package/dist/safe-bash-command-html-to-markdown/input.js +3 -3
- package/dist/safe-bash-command-html-to-markdown/parser.js +2 -2
- package/dist/safe-bash-command-html-to-markdown/render.js +3 -3
- package/dist/safe-bash-command-htmlq/contracts.d.ts +5 -2
- package/dist/safe-bash-command-htmlq/index.d.ts +2 -1
- package/dist/safe-bash-command-htmlq/index.js +175 -49
- package/dist/safe-bash-command-htmlq/sync.d.ts +1 -0
- package/dist/safe-bash-command-imagemagick/index.js +59 -7
- package/dist/safe-bash-command-install/arguments.d.ts +27 -0
- package/dist/safe-bash-command-install/arguments.js +224 -0
- package/dist/safe-bash-command-install/index.d.ts +7 -0
- package/dist/safe-bash-command-install/index.js +942 -0
- package/dist/safe-bash-command-install/mode.d.ts +6 -0
- package/dist/safe-bash-command-install/mode.js +71 -0
- package/dist/safe-bash-command-install/options.d.ts +40 -0
- package/dist/safe-bash-command-install/options.js +27 -0
- package/dist/safe-bash-command-jq/index.js +1 -1
- package/dist/safe-bash-command-jq/jq.js +1 -1
- package/dist/safe-bash-command-less/index.js +42 -57
- package/dist/safe-bash-command-llm/command.js +1 -1
- package/dist/safe-bash-command-llm/elevenlabs.js +2 -2
- package/dist/safe-bash-command-llm/index.js +4 -4
- package/dist/safe-bash-command-llm/openai.js +2 -2
- package/dist/safe-bash-command-llm/providers/elevenlabs.js +2 -2
- package/dist/safe-bash-command-llm/providers/index.js +3 -3
- package/dist/safe-bash-command-llm/providers/openai.js +2 -2
- package/dist/safe-bash-command-llm/providers/shared.js +1 -1
- package/dist/{safe-bash-mcp → safe-bash-command-mcp}/index.browser.d.ts +463 -46
- package/dist/safe-bash-command-mcp/index.browser.js +19308 -0
- package/dist/{safe-bash-mcp → safe-bash-command-mcp}/index.d.ts +15 -6
- package/dist/{safe-bash-mcp → safe-bash-command-mcp}/index.js +2835 -2783
- package/dist/safe-bash-command-media/LICENSE +21 -0
- package/dist/safe-bash-command-media/index.d.ts +6 -0
- package/dist/safe-bash-command-media/index.js +30 -0
- package/dist/safe-bash-command-media/plugin.d.ts +18 -0
- package/dist/safe-bash-command-media/plugin.js +11 -0
- package/dist/safe-bash-command-media/remote.d.ts +63 -0
- package/dist/safe-bash-command-media/remote.js +11 -0
- package/dist/safe-bash-command-media/settings.d.ts +4 -0
- package/dist/safe-bash-command-media/settings.js +41 -0
- package/dist/safe-bash-command-mktemp/LICENSE +21 -0
- package/dist/safe-bash-command-mktemp/command.d.ts +3 -0
- package/dist/safe-bash-command-mktemp/command.js +9 -0
- package/dist/safe-bash-command-mktemp/index.d.ts +6 -0
- package/dist/safe-bash-command-mktemp/index.js +25 -0
- package/dist/safe-bash-command-mmdc/arguments.d.ts +1 -0
- package/dist/safe-bash-command-mmdc/command.d.ts +2 -0
- package/dist/safe-bash-command-mmdc/contracts.d.ts +8 -1
- package/dist/safe-bash-command-mmdc/index.js +359 -7
- package/dist/safe-bash-command-nl/index.js +1 -1
- package/dist/safe-bash-command-nl/nl.js +1 -1
- package/dist/safe-bash-command-node/LICENSE +21 -0
- package/dist/safe-bash-command-node/index.d.ts +17 -0
- package/dist/safe-bash-command-node/index.js +328 -0
- package/dist/safe-bash-command-numfmt/index.js +1 -0
- package/dist/safe-bash-command-od/index.js +16 -8
- package/dist/safe-bash-command-op/index.js +62 -36
- package/dist/safe-bash-command-op/types.d.ts +1 -0
- package/dist/safe-bash-command-pandoc/command.js +3 -3
- package/dist/safe-bash-command-pandoc/index.d.ts +1 -0
- package/dist/safe-bash-command-pandoc/index.js +5 -3
- package/dist/safe-bash-command-pandoc/sync.d.ts +1 -0
- package/dist/safe-bash-command-patch/index.js +4 -4
- package/dist/safe-bash-command-patch/patch.js +4 -4
- package/dist/safe-bash-command-pdfimages/index.js +1 -1
- package/dist/safe-bash-command-pdfinfo/index.js +30 -5
- package/dist/safe-bash-command-pdftk/index.js +21 -23
- package/dist/safe-bash-command-pdftoppm/index.js +17 -4
- package/dist/safe-bash-command-pdftotext/index.js +11 -14
- package/dist/safe-bash-command-qpdf/index.d.ts +1 -0
- package/dist/safe-bash-command-qpdf/index.js +9 -6
- package/dist/safe-bash-command-rg/index.js +1 -1
- package/dist/safe-bash-command-rg/rg-command.js +1 -1
- package/dist/safe-bash-command-sed/index.js +1 -1
- package/dist/safe-bash-command-sed/sed.js +1 -1
- package/dist/safe-bash-command-shuf/input.d.ts +2 -2
- package/dist/safe-bash-command-shuf/input.js +2 -1
- package/dist/safe-bash-command-shuf/shuf.js +4 -2
- package/dist/safe-bash-command-sips/index.js +15 -7
- package/dist/safe-bash-command-soffice/index.js +97 -12
- package/dist/safe-bash-command-sponge/index.js +13 -3
- package/dist/safe-bash-command-sqlite3/engine.d.ts +1 -0
- package/dist/safe-bash-command-sqlite3/index.js +510 -70
- package/dist/safe-bash-command-ssconvert/formats/xlsx.js +2 -2
- package/dist/safe-bash-command-ssconvert/index.js +44 -22
- package/dist/safe-bash-command-stat/LICENSE +21 -0
- package/dist/safe-bash-command-stat/command.d.ts +7 -0
- package/dist/safe-bash-command-stat/command.js +9 -0
- package/dist/safe-bash-command-stat/index.d.ts +6 -0
- package/dist/safe-bash-command-stat/index.js +25 -0
- package/dist/safe-bash-command-tar/create.d.ts +1 -0
- package/dist/safe-bash-command-tar/create.js +2 -2
- package/dist/safe-bash-command-tar/extract.js +2 -2
- package/dist/safe-bash-command-tar/index.js +4 -4
- package/dist/safe-bash-command-tar/modes.js +4 -4
- package/dist/safe-bash-command-tar/options.js +1 -1
- package/dist/safe-bash-command-truncate/index.js +2 -2
- package/dist/safe-bash-command-tsort/command.js +2 -2
- package/dist/safe-bash-command-tsort/index.js +2 -2
- package/dist/safe-bash-command-unalias/index.d.ts +12 -0
- package/dist/safe-bash-command-unalias/index.js +67 -0
- package/dist/safe-bash-command-unrtf/index.js +37 -5
- package/dist/safe-bash-command-xan/argv.d.ts +1 -1
- package/dist/safe-bash-command-xan/argv.js +2 -2
- package/dist/safe-bash-command-xan/budget.d.ts +0 -1
- package/dist/safe-bash-command-xan/budget.js +1 -1
- package/dist/safe-bash-command-xan/commands.js +6 -6
- package/dist/safe-bash-command-xan/csv.js +2 -2
- package/dist/safe-bash-command-xan/index.js +8 -9
- package/dist/safe-bash-command-xan/io.js +4 -4
- package/dist/safe-bash-command-xan/options.js +1 -1
- package/dist/safe-bash-command-xan/selector.js +2 -2
- package/dist/safe-bash-command-xmllint/index.js +45 -23
- package/dist/safe-bash-command-xxd/index.js +47 -12
- package/dist/safe-bash-command-xz/command.d.ts +1 -1
- package/dist/safe-bash-command-xz/index.js +3 -2
- package/dist/safe-bash-command-yq/accounting.js +1 -1
- package/dist/safe-bash-command-yq/index.js +4 -2
- package/dist/safe-bash-command-yq/native-work.js +3 -0
- package/dist/safe-bash-command-yq/parser.js +2 -2
- package/dist/safe-bash-command-yq/query.js +8 -5
- package/dist/safe-bash-command-yq/toml.js +2 -2
- package/dist/safe-bash-command-zip/index.js +3 -3
- package/dist/safe-bash-compression-engine/bounded-codec.js +3 -3
- package/dist/safe-bash-compression-engine/codec-loader.js +2 -2
- package/dist/safe-bash-compression-engine/files.js +6 -6
- package/dist/safe-bash-compression-engine/index.js +5 -5
- package/dist/safe-bash-compression-engine/operand.js +6 -6
- package/dist/safe-bash-compression-engine/options.js +1 -1
- package/dist/safe-bash-compression-engine/stream.js +5 -5
- package/dist/safe-bash-compression-engine/zstd-decode.js +4 -4
- package/dist/safe-bash-contracts/command.js +3 -3
- package/dist/safe-bash-contracts/default-executor.js +2 -2
- package/dist/safe-bash-contracts/diagnostics.js +3 -3
- package/dist/safe-bash-contracts/escaping.js +6 -6
- package/dist/safe-bash-contracts/filesystem-descriptor.js +3 -3
- package/dist/safe-bash-contracts/filesystem-output.js +5 -5
- package/dist/safe-bash-contracts/http.d.ts +7 -0
- package/dist/safe-bash-contracts/index.js +8 -8
- package/dist/safe-bash-contracts/io.d.ts +2 -0
- package/dist/safe-bash-contracts/io.js +2 -2
- package/dist/safe-bash-contracts/output.js +3 -3
- package/dist/safe-bash-contracts/runtime-control.d.ts +2 -2
- package/dist/safe-bash-contracts/runtime-control.js +4 -2
- package/dist/safe-bash-contracts/signals.d.ts +2 -0
- package/dist/safe-bash-contracts/signals.js +3 -1
- package/dist/safe-bash-contracts/yield.js +1 -1
- package/dist/safe-bash-csv-engine/index.d.ts +2 -1
- package/dist/safe-bash-csv-engine/index.js +21 -15
- package/dist/safe-bash-io-engine/commands/search/requirements.js +2 -2
- package/dist/safe-bash-io-engine/commands/text-programs/shared.js +6 -6
- package/dist/safe-bash-io-engine/internal.js +1 -1
- package/dist/safe-bash-io-engine/shell/pattern.js +38 -18
- package/dist/safe-bash-line-ending-engine/convert.js +9 -204
- package/dist/safe-bash-line-ending-engine/encoding.js +9 -42
- package/dist/safe-bash-line-ending-engine/index.js +48 -0
- package/dist/safe-bash-line-ending-engine/info.js +9 -90
- package/dist/safe-bash-line-ending-engine/internal.js +15 -160
- package/dist/safe-bash-line-ending-engine/io.js +12 -289
- package/dist/safe-bash-line-ending-engine/stage.js +10 -160
- package/dist/safe-bash-markdown-engine/index.js +3 -3
- package/dist/safe-bash-metadata-engine/LICENSE +21 -0
- package/dist/safe-bash-metadata-engine/index.d.ts +30 -0
- package/dist/safe-bash-metadata-engine/index.js +82 -0
- package/dist/safe-bash-metadata-engine/random.d.ts +1 -0
- package/dist/safe-bash-metadata-engine/random.js +21 -0
- package/dist/safe-bash-network-engine/args.d.ts +6 -0
- package/dist/safe-bash-network-engine/args.js +4 -2
- package/dist/safe-bash-network-engine/body.js +1 -1
- package/dist/safe-bash-network-engine/fetch-transport.js +3 -1
- package/dist/safe-bash-network-engine/index.js +3 -1
- package/dist/safe-bash-network-engine/input.js +2 -2
- package/dist/safe-bash-network-engine/platform-portable.js +3 -1
- package/dist/safe-bash-query-engine/dates.d.ts +1 -1
- package/dist/safe-bash-query-engine/dates.js +1 -1
- package/dist/safe-bash-query-engine/index.js +6 -6
- package/dist/safe-bash-query-engine/interpreter.js +4 -4
- package/dist/safe-bash-query-engine/parser.js +1 -1
- package/dist/safe-bash-query-engine/query-core.js +6 -6
- package/dist/safe-bash-regex-engine/execution/bounded-provider.js +10 -0
- package/dist/safe-bash-regex-engine/index.js +1 -1
- package/dist/safe-bash-regex-engine/text/regex.d.ts +1 -1
- package/dist/safe-bash-regex-engine/text/regex.js +1 -1
- package/dist/safe-bash-search-engine/ergonomic-regex.d.ts +1 -0
- package/dist/safe-bash-search-engine/ergonomic-regex.js +2 -2
- package/dist/safe-bash-search-engine/glob.js +2 -2
- package/dist/safe-bash-search-engine/grep.js +17 -10
- package/dist/safe-bash-search-engine/matcher.d.ts +2 -2
- package/dist/safe-bash-search-engine/matcher.js +13 -9
- package/dist/safe-bash-search-engine/options.d.ts +2 -0
- package/dist/safe-bash-search-engine/options.js +1 -1
- package/dist/safe-bash-search-engine/output.js +1 -1
- package/dist/safe-bash-search-engine/shared.js +2 -2
- package/dist/safe-bash-search-engine/walk.js +15 -3
- package/dist/safe-bash-text-stream-engine/stream-format/shared.d.ts +1 -1
- package/dist/safe-bash-text-stream-engine/stream-format/shared.js +2 -1
- package/dist/safe-bash-xml-engine/document.js +3 -3
- package/dist/safe-bash-xml-engine/evaluate.js +2 -2
- package/dist/safe-bash-xml-engine/index.js +4 -4
- package/dist/safe-bash-xml-engine/io.js +7 -2
- package/dist/safe-bash-xml-engine/limits.d.ts +0 -2
- package/dist/safe-bash-xml-engine/limits.js +1 -1
- package/dist/safe-bash-xml-engine/query.js +3 -3
- package/dist/safe-bash-zip-engine/index.js +3 -3
- package/dist/safe-bash-zip-engine/zip/repair.js +3 -3
- package/dist/safe-bash-zip-engine/zip/safety.js +1 -1
- package/dist/safe-bash-zip-engine/zip/sfx.js +3 -3
- package/dist/safe-bash-zip-engine/zip/volumes.js +1 -1
- package/dist/safe-bash-zip-engine/zip-format.js +3 -3
- package/dist/safe-playwright-cloudflare/browser-snapshot-json.js +2 -2
- package/dist/safe-playwright-cloudflare/browser-snapshot-references.js +1 -1
- package/dist/safe-playwright-cloudflare/browser-socket-closure.js +18 -3
- package/dist/safe-playwright-cloudflare/shell-browser-resource.js +1 -1
- package/dist/xlsx-ast/xlsx.js +6 -5
- package/package.json +112 -98
- package/dist/media-cli/bytes.d.ts +0 -8
- package/dist/media-cli/bytes.js +0 -40
- package/dist/media-cli/concat.d.ts +0 -30
- package/dist/media-cli/concat.js +0 -197
- package/dist/media-cli/content.js +0 -66
- package/dist/media-cli/dependency-grammars.d.ts +0 -12
- package/dist/media-cli/dependency-grammars.js +0 -557
- package/dist/media-cli/discover.js +0 -286
- package/dist/media-cli/engine.js +0 -190
- package/dist/media-cli/filename-expression.js +0 -147
- package/dist/media-cli/filesystem.js +0 -35
- package/dist/media-cli/frontend-contract.js +0 -8
- package/dist/media-cli/frontend-issues.d.ts +0 -6
- package/dist/media-cli/frontend-issues.js +0 -9
- package/dist/media-cli/imagemagick-operand.d.ts +0 -42
- package/dist/media-cli/imagemagick-operand.js +0 -229
- package/dist/media-cli/imagemagick-references.d.ts +0 -7
- package/dist/media-cli/imagemagick-references.js +0 -42
- package/dist/media-cli/imagemagick.generated.js +0 -3254
- package/dist/media-cli/imagemagick.js +0 -615
- package/dist/media-cli/index.js +0 -12
- package/dist/media-cli/mvg.d.ts +0 -10
- package/dist/media-cli/mvg.js +0 -102
- package/dist/media-cli/network.js +0 -78
- package/dist/media-cli/options.generated.js +0 -3312
- package/dist/media-cli/preset.d.ts +0 -11
- package/dist/media-cli/preset.js +0 -57
- package/dist/media-cli/resolution-path.d.ts +0 -23
- package/dist/media-cli/resolution-path.js +0 -217
- package/dist/media-cli/resolver.js +0 -494
- package/dist/media-cli/resources.d.ts +0 -16
- package/dist/media-cli/resources.js +0 -187
- package/dist/media-cli/shim.js +0 -52
- package/dist/media-cli/tee.d.ts +0 -6
- package/dist/media-cli/tee.js +0 -38
- package/dist/office-package/zip-sync.js +0 -111
- package/dist/remote-execution/binary.js +0 -178
- package/dist/remote-execution/callback-result.js +0 -26
- package/dist/remote-execution/canonical-capabilities.d.ts +0 -5
- package/dist/remote-execution/canonical-capabilities.js +0 -45
- package/dist/remote-execution/canonical-metadata.d.ts +0 -4
- package/dist/remote-execution/canonical-metadata.js +0 -32
- package/dist/remote-execution/client.js +0 -824
- package/dist/remote-execution/deployment.js +0 -131
- package/dist/remote-execution/descriptors.js +0 -267
- package/dist/remote-execution/effects.js +0 -357
- package/dist/remote-execution/endpoint.js +0 -224
- package/dist/remote-execution/files.js +0 -291
- package/dist/remote-execution/hosting-operation.js +0 -26
- package/dist/remote-execution/hosting-request.d.ts +0 -4
- package/dist/remote-execution/hosting-request.js +0 -12
- package/dist/remote-execution/hosting-stream.d.ts +0 -8
- package/dist/remote-execution/hosting-stream.js +0 -64
- package/dist/remote-execution/index.js +0 -18
- package/dist/remote-execution/invocation-admission.d.ts +0 -3
- package/dist/remote-execution/invocation-admission.js +0 -17
- package/dist/remote-execution/job-binding.js +0 -1269
- package/dist/remote-execution/materializations.js +0 -284
- package/dist/remote-execution/modal-driver.js +0 -90
- package/dist/remote-execution/native-result.d.ts +0 -3
- package/dist/remote-execution/native-result.js +0 -16
- package/dist/remote-execution/output-freshness.d.ts +0 -4
- package/dist/remote-execution/output-freshness.js +0 -19
- package/dist/remote-execution/output-retrieval.js +0 -474
- package/dist/remote-execution/process-http.js +0 -607
- package/dist/remote-execution/process.js +0 -577
- package/dist/remote-execution/protocol.js +0 -208
- package/dist/remote-execution/relay.js +0 -91
- package/dist/remote-execution/rest-driver.js +0 -93
- package/dist/remote-execution/upload-descriptor.js +0 -201
- package/dist/remote-execution/upload-protocol.js +0 -62
- package/dist/remote-execution/uploads.js +0 -324
- package/dist/remote-execution/wire-json.d.ts +0 -4
- package/dist/remote-execution/wire-json.js +0 -44
- package/dist/remote-execution/wire-validation.js +0 -131
- package/dist/remote-execution/wire.generated.js +0 -4224
- package/dist/safe-bash/chunks/chunk-GETUOD5D.js +0 -161
- package/dist/safe-bash/chunks/chunk-IWDICZVK.js +0 -20
- package/dist/safe-bash/chunks/chunk-MHMMRCYC.js +0 -3464
- package/dist/safe-bash/chunks/chunk-UE5KZDEK.js +0 -77
- package/dist/safe-bash/chunks/chunk-VSAJ4OTM.js +0 -962
- package/dist/safe-bash/chunks/csvkit-TACDU7FC.js +0 -1618
- package/dist/safe-bash/chunks/implementation-MLFHUQ5M.js +0 -133
- package/dist/safe-bash/commands/csvkit/sync.js +0 -1639
- package/dist/safe-bash/commands/node/unconfigured.d.ts +0 -3
- package/dist/safe-bash/commands/node/unconfigured.js +0 -10
- package/dist/safe-bash/commands/pandoc/implementation.d.ts +0 -8
- package/dist/safe-bash/commands/pandoc/implementation.js +0 -94
- package/dist/safe-bash-mcp/index.browser.js +0 -9157
- package/dist/safe-bash/command-chunks/{chunk-ZRRBXU3M.js → chunk-GIN5GUDP.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-LAOM65EE.js → chunk-IEO4XVN6.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-364TMWBT.js → chunk-MWREVL44.js} +6 -6
- package/dist/safe-bash/command-chunks/{chunk-464RVBGB.js → chunk-Q5TDKFHK.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-AJR3AQYA.js → chunk-UKX3LZHR.js} +0 -0
- package/dist/safe-bash/command-chunks/{chunk-XIIBTGC5.js → chunk-XPXEQKRW.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-FDBUV4HJ.js → chunk-Y4HGTG3E.js} +3 -3
- /package/dist/{safe-bash/commands/csvkit → safe-bash-command-csvkit}/sync.d.ts +0 -0
|
@@ -1,1269 +0,0 @@
|
|
|
1
|
-
import { EndpointCapabilityGap } from './endpoint.js';
|
|
2
|
-
import { BytePath, decodeFileOffset, decodeObjectMetadata } from "@poe-platform/safe-fs/contracts/object";
|
|
3
|
-
import { FsError } from "@poe-platform/safe-fs/contracts/errors";
|
|
4
|
-
import { encodeFileMetadata } from './files.js';
|
|
5
|
-
import { assertLogicalCwd } from './invocation-admission.js';
|
|
6
|
-
import { createDescriptorMaterialization } from './descriptors.js';
|
|
7
|
-
import { admitCanonicalMetadata } from './canonical-metadata.js';
|
|
8
|
-
import { admitCanonicalCapabilities } from './canonical-capabilities.js';
|
|
9
|
-
export class JobEffectsError extends Error {
|
|
10
|
-
effects;
|
|
11
|
-
constructor(cause, effects) {
|
|
12
|
-
super(cause instanceof Error ? cause.message : String(cause), { cause });
|
|
13
|
-
this.effects = effects;
|
|
14
|
-
this.name = 'JobEffectsError';
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
export class JobCallbackRecoveryError extends Error {
|
|
18
|
-
sessionId;
|
|
19
|
-
epoch;
|
|
20
|
-
jobId;
|
|
21
|
-
outcome = 'unknown';
|
|
22
|
-
constructor(sessionId, epoch, jobId) {
|
|
23
|
-
super('Job callback retention ended; inspect the job before recovery');
|
|
24
|
-
this.sessionId = sessionId;
|
|
25
|
-
this.epoch = epoch;
|
|
26
|
-
this.jobId = jobId;
|
|
27
|
-
this.name = 'JobCallbackRecoveryError';
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/** Replacing an observed data field with a getter cannot hide revoked work.
|
|
31
|
-
* Existing metadata getters remain supported without a second invocation. */
|
|
32
|
-
function unchangedMetadata(record, key, before, value) {
|
|
33
|
-
const current = Object.getOwnPropertyDescriptor(record, key);
|
|
34
|
-
if (!before || !current)
|
|
35
|
-
return before === current;
|
|
36
|
-
if ('value' in before)
|
|
37
|
-
return 'value' in current && current.value === value;
|
|
38
|
-
return !('value' in current) && current.get === before.get && current.set === before.set;
|
|
39
|
-
}
|
|
40
|
-
/** Own only admission metadata. Advisory acquisition/error payloads remain lazy;
|
|
41
|
-
* neither an iterator nor an inherited slot can supply readiness evidence. */
|
|
42
|
-
export function snapshotReadiness(work) {
|
|
43
|
-
if (!Array.isArray(work))
|
|
44
|
-
throw new Error('Incomplete required readiness');
|
|
45
|
-
const length = work.length;
|
|
46
|
-
const records = [];
|
|
47
|
-
const descriptors = [];
|
|
48
|
-
const slots = [];
|
|
49
|
-
const snapshot = Array.from({ length }, (_, index) => {
|
|
50
|
-
if (!Object.hasOwn(work, index))
|
|
51
|
-
throw new Error('Incomplete required readiness');
|
|
52
|
-
slots.push(Object.getOwnPropertyDescriptor(work, index));
|
|
53
|
-
const item = work[index];
|
|
54
|
-
if (!item)
|
|
55
|
-
throw new Error('Incomplete required readiness');
|
|
56
|
-
records.push(item);
|
|
57
|
-
descriptors.push(Object.fromEntries(['kind', 'identity', 'state']
|
|
58
|
-
.map(key => [key, Object.getOwnPropertyDescriptor(item, key)])));
|
|
59
|
-
return { kind: item.kind, identity: item.identity, state: item.state };
|
|
60
|
-
});
|
|
61
|
-
if (work.length !== length)
|
|
62
|
-
throw new Error('Incomplete required readiness');
|
|
63
|
-
// Later metadata accessors can revoke an earlier obligation without changing
|
|
64
|
-
// ledger length. Check descriptors and data values without invoking getters again
|
|
65
|
-
// or touching advisory acquisition/error payloads.
|
|
66
|
-
for (let index = 0; index < length; index++) {
|
|
67
|
-
if (!unchangedMetadata(work, String(index), slots[index], records[index]))
|
|
68
|
-
throw new Error('Incomplete required readiness');
|
|
69
|
-
for (const key of ['kind', 'identity', 'state']) {
|
|
70
|
-
if (!unchangedMetadata(records[index], key, descriptors[index][key], snapshot[index][key]))
|
|
71
|
-
throw new Error('Incomplete required readiness');
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return snapshot;
|
|
75
|
-
}
|
|
76
|
-
export function assertRequiredReadiness(work, admitted) {
|
|
77
|
-
work = snapshotReadiness(work);
|
|
78
|
-
if (admitted !== undefined)
|
|
79
|
-
admitted = snapshotReadiness(admitted);
|
|
80
|
-
const identities = new Set();
|
|
81
|
-
if (!work.some(item => item.kind === 'required')
|
|
82
|
-
|| work.some(item => {
|
|
83
|
-
if (!item || typeof item.identity !== 'string' || !item.identity.length
|
|
84
|
-
|| identities.has(item.identity) || !['metadata-only', 'speculative', 'required'].includes(item.kind)
|
|
85
|
-
|| !['pending', 'complete', 'failed'].includes(item.state)
|
|
86
|
-
|| (item.kind === 'required' && item.state !== 'complete'))
|
|
87
|
-
return true;
|
|
88
|
-
identities.add(item.identity);
|
|
89
|
-
return false;
|
|
90
|
-
}))
|
|
91
|
-
throw new Error('Incomplete required readiness');
|
|
92
|
-
if (admitted !== undefined) {
|
|
93
|
-
// Ledger order is bookkeeping, not authority. Keep the exact admitted set
|
|
94
|
-
// of required identities while advisory records evolve independently.
|
|
95
|
-
const required = new Set(work.filter(item => item.kind === 'required').map(item => item.identity));
|
|
96
|
-
const expected = admitted.filter(item => item.kind === 'required');
|
|
97
|
-
if (required.size !== expected.length || expected.some(item => !required.has(item.identity)))
|
|
98
|
-
throw new Error('Incomplete or stale job materialization readiness');
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
function completeStartingEntries(entries) {
|
|
102
|
-
const indexes = new Set();
|
|
103
|
-
return Array.isArray(entries) && Array.from(entries).every(entry => {
|
|
104
|
-
if (!entry || !['pending', 'applied', 'failed', 'unknown'].includes(entry.state)
|
|
105
|
-
|| entry.kind !== undefined && !['metadata-only', 'speculative', 'required'].includes(entry.kind))
|
|
106
|
-
return false;
|
|
107
|
-
if (entry.kind !== undefined && entry.kind !== 'required')
|
|
108
|
-
return true;
|
|
109
|
-
if (entry.state !== 'applied')
|
|
110
|
-
return false;
|
|
111
|
-
if (entry.index === undefined)
|
|
112
|
-
return true;
|
|
113
|
-
if (!Number.isSafeInteger(entry.index) || entry.index < 0 || indexes.has(entry.index))
|
|
114
|
-
return false;
|
|
115
|
-
indexes.add(entry.index);
|
|
116
|
-
return true;
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
function requiredEntryIdentity(entries) {
|
|
120
|
-
const required = entries.filter(entry => entry.kind === undefined || entry.kind === 'required');
|
|
121
|
-
// Indexed manifest records name obligations independently of observation
|
|
122
|
-
// order. Unindexed namespace work retains its ordered admission evidence.
|
|
123
|
-
const indexed = required.filter(entry => entry.index !== undefined).sort((a, b) => a.index - b.index);
|
|
124
|
-
const unindexed = required.filter(entry => entry.index === undefined);
|
|
125
|
-
return JSON.stringify({ indexed, unindexed });
|
|
126
|
-
}
|
|
127
|
-
/** In-process source admission evidence. Capture methods and their receivers,
|
|
128
|
-
* never dependency bytes, before asynchronous session/materialization binding.
|
|
129
|
-
* Mutable filesystem containers cannot authorize a replacement scratch facet. */
|
|
130
|
-
export function captureJobSource(fs) {
|
|
131
|
-
const objects = fs.objects;
|
|
132
|
-
return Object.freeze({ fs, objects, capabilities: fs.capabilities,
|
|
133
|
-
objectMethods: Object.freeze({
|
|
134
|
-
open: objects?.open, create: objects?.create, rename: objects?.rename,
|
|
135
|
-
unlink: objects?.unlink, readdir: objects?.readdir,
|
|
136
|
-
}),
|
|
137
|
-
pathMethods: Object.freeze({
|
|
138
|
-
access: fs.access, realpath: fs.realpath, stat: fs.stat, lstat: fs.lstat,
|
|
139
|
-
mkdir: fs.mkdir, rmdir: fs.rmdir, readlink: fs.readlink,
|
|
140
|
-
symlink: fs.symlink, capabilitiesFor: fs.capabilitiesFor,
|
|
141
|
-
}),
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
const fields = ['sessionId', 'epoch', 'buildId', 'sourceAuthorityId', 'bindingId', 'materializationId', 'manifestId', 'manifestRevision', 'directoryRevision'];
|
|
145
|
-
function octets(value, empty = false) {
|
|
146
|
-
if (!Array.isArray(value) || (!empty && !value.length) || value.length > 1048576)
|
|
147
|
-
throw new TypeError('Invalid native octets');
|
|
148
|
-
for (let index = 0; index < value.length; index++) {
|
|
149
|
-
if (!Object.hasOwn(value, index))
|
|
150
|
-
throw new TypeError('Invalid native octets');
|
|
151
|
-
const n = value[index];
|
|
152
|
-
if (!Number.isInteger(n) || n < 1 || n > 255)
|
|
153
|
-
throw new TypeError('Invalid native octets');
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
/** Includes one native NUL terminator per argument, including empty arguments. */
|
|
157
|
-
export const nativeArgvByteLimit = 1048576;
|
|
158
|
-
/** Validate the literal job description before handing it to a host adapter. */
|
|
159
|
-
export function assertJobInvocation(input) {
|
|
160
|
-
for (const field of fields)
|
|
161
|
-
if (typeof input[field] !== 'string' || !input[field].length || input[field].length > 256)
|
|
162
|
-
throw new TypeError('Incomplete job binding');
|
|
163
|
-
assertNativeProcessView(input.cwd, input.originalArgv);
|
|
164
|
-
}
|
|
165
|
-
/** Admit literal process names independently of resource acquisition and session
|
|
166
|
-
* binding. Dependency discovery must not run for an inadmissible process view. */
|
|
167
|
-
export function assertNativeProcessView(cwd, originalArgv) {
|
|
168
|
-
octets(cwd);
|
|
169
|
-
assertLogicalCwd(cwd);
|
|
170
|
-
if (!Array.isArray(originalArgv))
|
|
171
|
-
throw new TypeError('Original argv required');
|
|
172
|
-
if (originalArgv.length > nativeArgvByteLimit)
|
|
173
|
-
throw new TypeError('Native argv limit');
|
|
174
|
-
let remaining = nativeArgvByteLimit;
|
|
175
|
-
for (let index = 0; index < originalArgv.length; index++) {
|
|
176
|
-
if (!Object.hasOwn(originalArgv, index))
|
|
177
|
-
throw new TypeError('Invalid native octets');
|
|
178
|
-
const arg = originalArgv[index];
|
|
179
|
-
octets(arg, true);
|
|
180
|
-
if (arg.length >= remaining)
|
|
181
|
-
throw new TypeError('Native argv limit');
|
|
182
|
-
remaining -= arg.length + 1;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
/** Own the native indexed names, never advisory properties on their carriers.
|
|
186
|
-
* Validate before allocation and again after observing caller-owned slots. */
|
|
187
|
-
function ownNativeProcessView(cwd, originalArgv) {
|
|
188
|
-
assertNativeProcessView(cwd, originalArgv);
|
|
189
|
-
const argumentCount = originalArgv.length;
|
|
190
|
-
const indexed = (bytes) => {
|
|
191
|
-
const length = bytes.length;
|
|
192
|
-
const owned = Array.from({ length }, (_, index) => {
|
|
193
|
-
if (!Object.hasOwn(bytes, index))
|
|
194
|
-
throw new TypeError('Invalid native octets');
|
|
195
|
-
return bytes[index];
|
|
196
|
-
});
|
|
197
|
-
if (bytes.length !== length)
|
|
198
|
-
throw new TypeError('Invalid native octets');
|
|
199
|
-
return owned;
|
|
200
|
-
};
|
|
201
|
-
const owned = {
|
|
202
|
-
cwd: indexed(cwd),
|
|
203
|
-
originalArgv: Array.from({ length: argumentCount }, (_, index) => {
|
|
204
|
-
if (!Object.hasOwn(originalArgv, index))
|
|
205
|
-
throw new TypeError('Invalid native octets');
|
|
206
|
-
return indexed(originalArgv[index]);
|
|
207
|
-
}),
|
|
208
|
-
};
|
|
209
|
-
// Indexed accessors can append a late operand during copying. A prefix is
|
|
210
|
-
// neither the original argv nor a complete process binding.
|
|
211
|
-
if (originalArgv.length !== argumentCount)
|
|
212
|
-
throw new TypeError('Invalid native octets');
|
|
213
|
-
assertNativeProcessView(owned.cwd, owned.originalArgv);
|
|
214
|
-
return owned;
|
|
215
|
-
}
|
|
216
|
-
/** Invocation-local live authority. No staged pathname is ever a fallback.
|
|
217
|
-
* Callback replay is process-local; a lost ledger requires unknown-outcome
|
|
218
|
-
* recovery, never retransmission against a new binding instance. */
|
|
219
|
-
export function createJobBinding(options) {
|
|
220
|
-
options = Object.freeze({ ...options });
|
|
221
|
-
if (!options.credential || (typeof options.credential !== 'object' && typeof options.credential !== 'function'))
|
|
222
|
-
throw new TypeError('Callback credential capability required');
|
|
223
|
-
const endpointBuild = options.endpoints?.buildDigest;
|
|
224
|
-
const endpointOpen = options.endpoints?.access.open.bind(options.endpoints.access);
|
|
225
|
-
const maxIo = options.maxIoBytes ?? 1048576;
|
|
226
|
-
const maxEntries = options.maxDirectoryEntries ?? 4096;
|
|
227
|
-
for (const n of [options.maxCallbacks, options.maxHandles, maxIo, maxEntries])
|
|
228
|
-
if (!Number.isSafeInteger(n) || n < 1)
|
|
229
|
-
throw new TypeError('Invalid job bound');
|
|
230
|
-
// Retain the canonical object facet when the host issues this capability,
|
|
231
|
-
// before asynchronous engine binding can replace facets with scratch storage.
|
|
232
|
-
// This retains authority, not bytes: each operation still observes live data.
|
|
233
|
-
const sourceAdmission = captureJobSource(options.fs);
|
|
234
|
-
const objects = sourceAdmission.objects;
|
|
235
|
-
// Pin the mandatory acquisition capability as well as its receiver. A host
|
|
236
|
-
// can mutate the facet during asynchronous engine binding; looking up open
|
|
237
|
-
// again at execute would silently authorize its replacement scratch store.
|
|
238
|
-
const open = sourceAdmission.objectMethods.open?.bind(objects);
|
|
239
|
-
const source = {
|
|
240
|
-
open,
|
|
241
|
-
create: sourceAdmission.objectMethods.create?.bind(objects),
|
|
242
|
-
rename: sourceAdmission.objectMethods.rename?.bind(objects),
|
|
243
|
-
unlink: sourceAdmission.objectMethods.unlink?.bind(objects),
|
|
244
|
-
readdir: sourceAdmission.objectMethods.readdir?.bind(objects),
|
|
245
|
-
};
|
|
246
|
-
const canonical = {
|
|
247
|
-
access: sourceAdmission.pathMethods.access?.bind(options.fs),
|
|
248
|
-
realpath: sourceAdmission.pathMethods.realpath?.bind(options.fs),
|
|
249
|
-
stat: sourceAdmission.pathMethods.stat?.bind(options.fs),
|
|
250
|
-
lstat: sourceAdmission.pathMethods.lstat?.bind(options.fs),
|
|
251
|
-
mkdir: sourceAdmission.pathMethods.mkdir?.bind(options.fs),
|
|
252
|
-
rmdir: sourceAdmission.pathMethods.rmdir?.bind(options.fs),
|
|
253
|
-
readlink: sourceAdmission.pathMethods.readlink?.bind(options.fs),
|
|
254
|
-
symlink: sourceAdmission.pathMethods.symlink?.bind(options.fs),
|
|
255
|
-
capabilitiesFor: sourceAdmission.pathMethods.capabilitiesFor?.bind(options.fs),
|
|
256
|
-
};
|
|
257
|
-
const descriptorHandles = options.handles ? { acquire: options.handles.acquire.bind(options.handles) } : undefined;
|
|
258
|
-
return {
|
|
259
|
-
effects: options.effects,
|
|
260
|
-
/** Engines pass their original scoped source capability to prevent reuse of
|
|
261
|
-
* another invocation's binding. Direct callers use this binding's source. */
|
|
262
|
-
async execute(input, signal, sourceCapability, admittedSource) {
|
|
263
|
-
// The engine supplies its invocation's actual scoped capability. Serialized
|
|
264
|
-
// authority IDs alone cannot detect a job borrowed from another invocation.
|
|
265
|
-
if (sourceCapability !== undefined && sourceCapability !== options.fs)
|
|
266
|
-
throw new Error('Job source capability mismatch');
|
|
267
|
-
if (admittedSource && (admittedSource.fs !== sourceAdmission.fs
|
|
268
|
-
|| admittedSource.objects !== sourceAdmission.objects
|
|
269
|
-
// Policy participates in canonical authority just like method facets.
|
|
270
|
-
// Compare the issued facet, without freezing its live access guarantees.
|
|
271
|
-
|| admittedSource.capabilities !== sourceAdmission.capabilities
|
|
272
|
-
|| Object.keys(sourceAdmission.objectMethods).some(key => Reflect.get(admittedSource.objectMethods, key) !== Reflect.get(sourceAdmission.objectMethods, key))
|
|
273
|
-
|| Object.keys(sourceAdmission.pathMethods).some(key => Reflect.get(admittedSource.pathMethods, key) !== Reflect.get(sourceAdmission.pathMethods, key))))
|
|
274
|
-
throw new Error('Job source capability mismatch');
|
|
275
|
-
// Capture top-level observations once, then admit octets before retaining
|
|
276
|
-
// their copy. Validate again after copying any caller-owned nested arrays.
|
|
277
|
-
// Private staging and advisory discovery are not job admission fields.
|
|
278
|
-
// Observing their getters could eagerly acquire dependencies or surface a
|
|
279
|
-
// speculative failure before the process reaches its native access stage.
|
|
280
|
-
const description = Object.fromEntries([...fields, 'cwd', 'originalArgv']
|
|
281
|
-
.map(field => [field, Reflect.get(input, field)]));
|
|
282
|
-
assertJobInvocation(description);
|
|
283
|
-
const invocation = { ...description, ...ownNativeProcessView(description.cwd, description.originalArgv) };
|
|
284
|
-
// Validate exactly the owned description passed to preparation and launch.
|
|
285
|
-
// Local structural callers can expose getters; checking the caller and
|
|
286
|
-
// copying it later would authorize a different session or source binding.
|
|
287
|
-
assertJobInvocation(invocation);
|
|
288
|
-
for (const field of ['sessionId', 'epoch', 'buildId', 'sourceAuthorityId', 'bindingId'])
|
|
289
|
-
if (invocation[field] !== options[field])
|
|
290
|
-
throw new Error('Job authority mismatch');
|
|
291
|
-
signal.throwIfAborted();
|
|
292
|
-
const jobId = crypto.randomUUID();
|
|
293
|
-
const handles = new Map();
|
|
294
|
-
const reads = new AbortController();
|
|
295
|
-
const descriptors = descriptorHandles ? createDescriptorMaterialization({ handles: descriptorHandles, maxHandles: options.maxHandles, maxIoBytes: maxIo }) : undefined;
|
|
296
|
-
const descriptorOwners = new Map();
|
|
297
|
-
// Retiring handles still consume canonical retains until close settles.
|
|
298
|
-
let closingHandles = 0;
|
|
299
|
-
let acquiringHandles = 0;
|
|
300
|
-
const namespaceChanges = [];
|
|
301
|
-
options.effects?.settle({ state: 'running' });
|
|
302
|
-
const outputIdentities = new Set();
|
|
303
|
-
const identities = new Map();
|
|
304
|
-
const callbacks = new Map();
|
|
305
|
-
const queues = new Map();
|
|
306
|
-
const pending = new Set();
|
|
307
|
-
const endpointLeases = new Set();
|
|
308
|
-
let endpointAcquisitions = 0;
|
|
309
|
-
let endpointCallbacks = 0;
|
|
310
|
-
let closed = false;
|
|
311
|
-
const openEndpoint = async (credential, native) => {
|
|
312
|
-
if (credential !== options.credential)
|
|
313
|
-
throw new Error('Unauthorized endpoint callback');
|
|
314
|
-
if (closed)
|
|
315
|
-
throw new JobCallbackRecoveryError(invocation.sessionId, invocation.epoch, jobId);
|
|
316
|
-
signal.throwIfAborted();
|
|
317
|
-
if (!endpointOpen)
|
|
318
|
-
throw new EndpointCapabilityGap();
|
|
319
|
-
native = { ...native };
|
|
320
|
-
const callerSignal = native.signal;
|
|
321
|
-
native = { ...structuredClone({ ...native, signal: undefined }), signal: callerSignal };
|
|
322
|
-
if (!endpointBuild || native.buildDigest !== endpointBuild)
|
|
323
|
-
throw new Error('Endpoint build mismatch');
|
|
324
|
-
if (endpointCallbacks >= options.maxCallbacks)
|
|
325
|
-
throw new Error('Endpoint callback bound');
|
|
326
|
-
if (endpointAcquisitions + endpointLeases.size >= options.maxHandles)
|
|
327
|
-
throw new Error('Endpoint handle bound');
|
|
328
|
-
endpointCallbacks++;
|
|
329
|
-
endpointAcquisitions++;
|
|
330
|
-
const acquisition = Promise.resolve().then(async () => {
|
|
331
|
-
const lease = await endpointOpen({ ...native, signal: native.signal
|
|
332
|
-
? AbortSignal.any([signal, native.signal]) : signal });
|
|
333
|
-
if (!lease || typeof lease.close !== 'function')
|
|
334
|
-
throw new TypeError('Endpoint provider must return a retireable transport lease');
|
|
335
|
-
const retire = lease.close.bind(lease);
|
|
336
|
-
let closing;
|
|
337
|
-
const owned = { close() {
|
|
338
|
-
return closing ??= Promise.resolve().then(retire).then(() => { endpointLeases.delete(owned); });
|
|
339
|
-
} };
|
|
340
|
-
endpointLeases.add(owned);
|
|
341
|
-
if (closed || signal.aborted) {
|
|
342
|
-
await owned.close();
|
|
343
|
-
signal.throwIfAborted();
|
|
344
|
-
throw new JobCallbackRecoveryError(invocation.sessionId, invocation.epoch, jobId);
|
|
345
|
-
}
|
|
346
|
-
return owned;
|
|
347
|
-
});
|
|
348
|
-
// Drain unawaited acquisitions without replacing the primary outcome.
|
|
349
|
-
const drained = acquisition.then(() => { }, () => { });
|
|
350
|
-
pending.add(drained);
|
|
351
|
-
try {
|
|
352
|
-
return await acquisition;
|
|
353
|
-
}
|
|
354
|
-
finally {
|
|
355
|
-
endpointAcquisitions--;
|
|
356
|
-
pending.delete(drained);
|
|
357
|
-
}
|
|
358
|
-
};
|
|
359
|
-
let workspace;
|
|
360
|
-
let acquiredWorkspace;
|
|
361
|
-
function path(value) {
|
|
362
|
-
octets(value);
|
|
363
|
-
return new BytePath(Uint8Array.from(value[0] === 47 ? value : [...invocation.cwd, ...(invocation.cwd.at(-1) === 47 ? [] : [47]), ...value]));
|
|
364
|
-
}
|
|
365
|
-
async function retainOutput(object, identity) {
|
|
366
|
-
if (!options.effects || !options.retainOutput || outputIdentities.has(identity))
|
|
367
|
-
return;
|
|
368
|
-
// Reserve identity admission before yielding: links and independent
|
|
369
|
-
// handles may settle concurrently against the same canonical object.
|
|
370
|
-
outputIdentities.add(identity);
|
|
371
|
-
let output;
|
|
372
|
-
let closeOutput;
|
|
373
|
-
try {
|
|
374
|
-
output = await options.retainOutput(object);
|
|
375
|
-
closeOutput = output.close.bind(output);
|
|
376
|
-
const outputIdentity = output.identity;
|
|
377
|
-
// Unqualified live retrieval cannot establish cache/resume authority.
|
|
378
|
-
// An explicit identity must designate this exact canonical object;
|
|
379
|
-
// accepting another retain would expose unrelated storage as output.
|
|
380
|
-
if (outputIdentity !== undefined && outputIdentity !== object.identity)
|
|
381
|
-
throw new Error('Output retain identity does not match canonical object');
|
|
382
|
-
output = Object.freeze({ identity: outputIdentity, freshness: output.freshness?.bind(output),
|
|
383
|
-
stat: output.stat.bind(output), read: output.read.bind(output), close: closeOutput });
|
|
384
|
-
options.effects.retain(identity, output);
|
|
385
|
-
identities.get(object.identity).retainedOutput = true;
|
|
386
|
-
}
|
|
387
|
-
catch (error) {
|
|
388
|
-
const cleanup = await Promise.allSettled([Promise.resolve().then(() => closeOutput?.())]);
|
|
389
|
-
options.effects.failRetrieval(identity, cleanup[0].status === 'rejected' ? new AggregateError([error, cleanup[0].reason], 'Output retain failed') : error);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
const access = async (credential, raw) => {
|
|
393
|
-
function admit(raw) {
|
|
394
|
-
if (credential !== options.credential || raw.sessionId !== invocation.sessionId || raw.epoch !== invocation.epoch || raw.jobId !== jobId)
|
|
395
|
-
throw new Error('Unauthorized file callback');
|
|
396
|
-
for (const value of [raw.callbackId, raw.fileId, raw.stage])
|
|
397
|
-
if (typeof value !== 'string' || !value.length || value.length > 256)
|
|
398
|
-
throw new TypeError('Incomplete file callback');
|
|
399
|
-
if ('path' in raw)
|
|
400
|
-
octets(raw.path);
|
|
401
|
-
if ('destination' in raw)
|
|
402
|
-
octets(raw.destination);
|
|
403
|
-
if (raw.operation === 'descriptor-acquire') {
|
|
404
|
-
if (!Array.isArray(raw.rights) || raw.rights.length > 4)
|
|
405
|
-
throw new FsError('EINVAL');
|
|
406
|
-
for (let index = 0; index < raw.rights.length; index++) {
|
|
407
|
-
if (!Object.hasOwn(raw.rights, index) || !['read', 'write', 'seek', 'stat'].includes(raw.rights[index]))
|
|
408
|
-
throw new FsError('EINVAL');
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
if (raw.operation === 'symlink') {
|
|
412
|
-
octets(raw.target);
|
|
413
|
-
if (raw.target.length > maxIo)
|
|
414
|
-
throw new FsError('EFBIG', { syscall: 'symlink' });
|
|
415
|
-
}
|
|
416
|
-
if (raw.operation === 'create' && raw.flag !== undefined && !['w', 'wx', 'a', 'ax'].includes(raw.flag))
|
|
417
|
-
throw new FsError('EINVAL', { syscall: 'create' });
|
|
418
|
-
if (raw.operation === 'create' || raw.operation === 'mkdir') {
|
|
419
|
-
if (raw.mode !== undefined && (!Number.isSafeInteger(raw.mode) || raw.mode < 0 || raw.mode > 0o7777))
|
|
420
|
-
throw new FsError('EINVAL', { syscall: raw.operation });
|
|
421
|
-
}
|
|
422
|
-
if (raw.operation === 'path-access' && raw.mode !== undefined
|
|
423
|
-
&& (!Number.isSafeInteger(raw.mode) || raw.mode < 0 || raw.mode > 7))
|
|
424
|
-
throw new FsError('EINVAL', { syscall: 'access' });
|
|
425
|
-
if (raw.operation === 'capabilities') {
|
|
426
|
-
for (const value of [raw.create, raw.allowDirectory])
|
|
427
|
-
if (value !== undefined && typeof value !== 'boolean')
|
|
428
|
-
throw new FsError('EINVAL', { syscall: 'capabilities' });
|
|
429
|
-
}
|
|
430
|
-
// Enforce transfer admission before retaining/copying the caller's frame.
|
|
431
|
-
// The authenticated transport still owns aggregate queue/wire budgets.
|
|
432
|
-
if (raw.operation === 'write' || raw.operation === 'append' || raw.operation === 'descriptor-write') {
|
|
433
|
-
if (!(raw.bytes instanceof Uint8Array) && (!Array.isArray(raw.bytes) || raw.operation === 'descriptor-write'))
|
|
434
|
-
throw new FsError('EINVAL');
|
|
435
|
-
const span = raw.bytes instanceof Uint8Array
|
|
436
|
-
? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Uint8Array.prototype), 'byteLength').get.call(raw.bytes)
|
|
437
|
-
: raw.bytes.length;
|
|
438
|
-
if (span > maxIo)
|
|
439
|
-
throw new FsError('EINVAL');
|
|
440
|
-
if (!(raw.bytes instanceof Uint8Array))
|
|
441
|
-
for (let index = 0; index < span; index++) {
|
|
442
|
-
if (!Object.hasOwn(raw.bytes, index))
|
|
443
|
-
throw new FsError('EINVAL');
|
|
444
|
-
const byte = raw.bytes[index];
|
|
445
|
-
if (!Number.isInteger(byte) || byte < 0 || byte > 255)
|
|
446
|
-
throw new FsError('EINVAL');
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
if (raw.operation === 'read' || raw.operation === 'descriptor-read') {
|
|
450
|
-
if (!Number.isSafeInteger(raw.maxBytes) || raw.maxBytes < 0 || raw.maxBytes > maxIo)
|
|
451
|
-
throw new FsError('EINVAL');
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
admit(raw);
|
|
455
|
-
if (closed)
|
|
456
|
-
throw new JobCallbackRecoveryError(invocation.sessionId, invocation.epoch, jobId);
|
|
457
|
-
// Only callback contract fields participate in admission and replay.
|
|
458
|
-
// Private driver extensions may lazily acquire scratch storage; copying
|
|
459
|
-
// them would turn staging into authority or expose speculative failures.
|
|
460
|
-
const callbackFields = ['sessionId', 'epoch', 'jobId', 'callbackId', 'fileId', 'stage',
|
|
461
|
-
'operation', 'fd', 'rights', 'handle', 'maxBytes', 'bytes', 'position', 'path',
|
|
462
|
-
'access', 'flag', 'mode', 'length', 'destination', 'create', 'allowDirectory', 'changes', 'target'];
|
|
463
|
-
const request = structuredClone(Object.fromEntries(callbackFields
|
|
464
|
-
.filter(field => Object.hasOwn(raw, field))
|
|
465
|
-
.map(field => {
|
|
466
|
-
const value = Reflect.get(raw, field);
|
|
467
|
-
// Path/rights/payload carriers authorize only their own indexed
|
|
468
|
-
// values. Private enumerable getters can acquire live dependencies;
|
|
469
|
-
// structuredClone must never evaluate them at this access stage.
|
|
470
|
-
if (['path', 'destination', 'target', 'rights', 'bytes'].includes(field) && Array.isArray(value)) {
|
|
471
|
-
const length = value.length;
|
|
472
|
-
const limit = field === 'rights' ? 4 : field === 'bytes' ? maxIo : 1048576;
|
|
473
|
-
if (length > limit)
|
|
474
|
-
throw new FsError('EINVAL');
|
|
475
|
-
const owned = Array.from({ length }, (_, index) => {
|
|
476
|
-
if (!Object.hasOwn(value, index))
|
|
477
|
-
throw new FsError('EINVAL');
|
|
478
|
-
return value[index];
|
|
479
|
-
});
|
|
480
|
-
// A late dependency or payload appended during indexed copying
|
|
481
|
-
// cannot authorize its truncated prefix or enter the replay ledger.
|
|
482
|
-
if (value.length !== length)
|
|
483
|
-
throw new FsError('EINVAL');
|
|
484
|
-
return [field, owned];
|
|
485
|
-
}
|
|
486
|
-
return [field, value];
|
|
487
|
-
})));
|
|
488
|
-
// Copying may observe accessor-backed structural host inputs again.
|
|
489
|
-
// Only the owned, reauthorized frame may enter replay storage or queues.
|
|
490
|
-
admit(request);
|
|
491
|
-
// Binary payload identity is its octets, not the host carrier chosen by
|
|
492
|
-
// a transport on replay. Keep all access metadata in the replay key.
|
|
493
|
-
// Transport object-member order is not file/job identity. Normalize
|
|
494
|
-
// records, including metadata changes, while preserving octet order.
|
|
495
|
-
const body = JSON.stringify('bytes' in request
|
|
496
|
-
? { ...request, bytes: Array.from(request.bytes) } : request, (_key, value) => value && typeof value === 'object' && !Array.isArray(value)
|
|
497
|
-
? Object.fromEntries(Object.keys(value).sort().map(key => [key, value[key]])) : value);
|
|
498
|
-
const previous = callbacks.get(request.callbackId);
|
|
499
|
-
if (previous) {
|
|
500
|
-
if (previous.body !== body)
|
|
501
|
-
throw new Error('Callback identity conflict');
|
|
502
|
-
return structuredClone(await previous.result);
|
|
503
|
-
}
|
|
504
|
-
if (callbacks.size >= options.maxCallbacks)
|
|
505
|
-
throw new Error('Callback limit');
|
|
506
|
-
// Independent open descriptions must be able to unblock each other.
|
|
507
|
-
// Live observations and acquisitions must not block a writer that can
|
|
508
|
-
// settle their upstream work. Serialize namespace changes and each handle;
|
|
509
|
-
// descriptor duplicates additionally share their canonical cursor queue.
|
|
510
|
-
const queue = 'handle' in request ? request.handle
|
|
511
|
-
: ['open', 'create', 'descriptor-acquire', 'path-stat', 'path-lstat', 'path-access', 'realpath', 'readlink', 'readdir', 'capabilities'].includes(request.operation)
|
|
512
|
-
? `observation:${request.callbackId}` : 'namespace';
|
|
513
|
-
const result = (queues.get(queue) ?? Promise.resolve()).then(async () => {
|
|
514
|
-
let releaseEffect;
|
|
515
|
-
let acquisitionReserved = false;
|
|
516
|
-
const namespaceObservation = namespaceChanges.length;
|
|
517
|
-
try {
|
|
518
|
-
signal.throwIfAborted();
|
|
519
|
-
if (request.operation === 'open' || request.operation === 'create' || request.operation === 'descriptor-acquire') {
|
|
520
|
-
if (handles.size + descriptorOwners.size + closingHandles + acquiringHandles >= options.maxHandles)
|
|
521
|
-
throw new FsError('EMFILE', { syscall: request.operation });
|
|
522
|
-
acquiringHandles++;
|
|
523
|
-
acquisitionReserved = true;
|
|
524
|
-
}
|
|
525
|
-
if (request.operation === 'descriptor-acquire') {
|
|
526
|
-
if (!descriptors)
|
|
527
|
-
throw new FsError('ENOTSUP');
|
|
528
|
-
const opened = await descriptors.acquire(request.fd, request.rights, signal);
|
|
529
|
-
descriptorOwners.set(opened.handle, request.fileId);
|
|
530
|
-
acquiringHandles--;
|
|
531
|
-
acquisitionReserved = false;
|
|
532
|
-
return opened;
|
|
533
|
-
}
|
|
534
|
-
if (request.operation === 'descriptor-read' || request.operation === 'descriptor-write'
|
|
535
|
-
|| request.operation === 'descriptor-seek' || request.operation === 'descriptor-stat' || request.operation === 'descriptor-close') {
|
|
536
|
-
if (!descriptors || descriptorOwners.get(request.handle) !== request.fileId)
|
|
537
|
-
throw new FsError('EBADF');
|
|
538
|
-
if (request.operation === 'descriptor-read')
|
|
539
|
-
return descriptors.read(request.handle, request.maxBytes, signal);
|
|
540
|
-
if (request.operation === 'descriptor-write')
|
|
541
|
-
return descriptors.write(request.handle, request.bytes, signal);
|
|
542
|
-
if (request.operation === 'descriptor-seek')
|
|
543
|
-
return descriptors.seek(request.handle, request.position, signal);
|
|
544
|
-
if (request.operation === 'descriptor-stat')
|
|
545
|
-
return descriptors.stat(request.handle, signal);
|
|
546
|
-
descriptorOwners.delete(request.handle);
|
|
547
|
-
closingHandles++;
|
|
548
|
-
try {
|
|
549
|
-
return await descriptors.close(request.handle, signal);
|
|
550
|
-
}
|
|
551
|
-
finally {
|
|
552
|
-
closingHandles--;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
const fs = source;
|
|
556
|
-
const effect = (value) => options.effects?.record({ ...value, callbackId: request.callbackId, stage: request.stage });
|
|
557
|
-
// Opens also publish identity observations. Reserve their receipt
|
|
558
|
-
// before acquisition so concurrent observations cannot consume the
|
|
559
|
-
// slot promised to an already admitted canonical mutation.
|
|
560
|
-
if (['open', 'create', 'mkdir', 'rmdir', 'write', 'append', 'truncate', 'metadata', 'rename', 'unlink', 'link', 'symlink'].includes(request.operation)) {
|
|
561
|
-
releaseEffect = options.effects?.reserve(request.operation === 'write' || request.operation === 'append' ? request.bytes.length : 0);
|
|
562
|
-
}
|
|
563
|
-
if (request.operation === 'rmdir') {
|
|
564
|
-
if (!canonical.rmdir)
|
|
565
|
-
throw new FsError('ENOTSUP', { syscall: 'rmdir' });
|
|
566
|
-
const removedPath = Array.from(path(request.path).bytes());
|
|
567
|
-
let logical;
|
|
568
|
-
try {
|
|
569
|
-
logical = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(Uint8Array.from(removedPath));
|
|
570
|
-
}
|
|
571
|
-
catch {
|
|
572
|
-
throw new FsError('EILSEQ', { syscall: 'rmdir' });
|
|
573
|
-
}
|
|
574
|
-
const capabilities = canonical.capabilitiesFor
|
|
575
|
-
? await canonical.capabilitiesFor(logical, { signal, allowDirectory: true })
|
|
576
|
-
: sourceAdmission.capabilities;
|
|
577
|
-
let observed;
|
|
578
|
-
// Retain the issued policy facet, but observe its live values at
|
|
579
|
-
// access time. Invalid selected-mount responses must never fall
|
|
580
|
-
// through to a weaker global profile or authorize removal.
|
|
581
|
-
if (capabilities !== undefined || canonical.capabilitiesFor) {
|
|
582
|
-
observed = admitCanonicalCapabilities(capabilities, 'rmdir', logical);
|
|
583
|
-
}
|
|
584
|
-
// Snapshot-marker removal cannot reproduce native empty-only rmdir.
|
|
585
|
-
// A mount query selects the actual path's profile, not the summary.
|
|
586
|
-
if (observed?.snapshotRmdir === true)
|
|
587
|
-
throw new FsError('ENOTSUP', { syscall: 'rmdir', path: logical });
|
|
588
|
-
signal.throwIfAborted();
|
|
589
|
-
await canonical.rmdir(logical, { signal });
|
|
590
|
-
namespaceChanges.push({ callbackId: request.callbackId, path: removedPath });
|
|
591
|
-
effect({ operation: 'rmdir', path: removedPath });
|
|
592
|
-
for (const value of handles.values())
|
|
593
|
-
if (JSON.stringify(value.path) === JSON.stringify(removedPath))
|
|
594
|
-
value.path = undefined;
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
if (request.operation === 'symlink') {
|
|
598
|
-
if (!canonical.symlink)
|
|
599
|
-
throw new FsError('ENOTSUP', { syscall: 'symlink' });
|
|
600
|
-
const destination = path(request.path).bytes();
|
|
601
|
-
let logical;
|
|
602
|
-
let target;
|
|
603
|
-
try {
|
|
604
|
-
const decoder = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
|
|
605
|
-
logical = decoder.decode(destination);
|
|
606
|
-
target = decoder.decode(Uint8Array.from(request.target));
|
|
607
|
-
}
|
|
608
|
-
catch {
|
|
609
|
-
throw new FsError('EILSEQ', { syscall: 'symlink' });
|
|
610
|
-
}
|
|
611
|
-
await canonical.symlink(target, logical, { signal });
|
|
612
|
-
const linkedPath = Array.from(destination);
|
|
613
|
-
namespaceChanges.push({ callbackId: request.callbackId, path: linkedPath });
|
|
614
|
-
for (const value of handles.values())
|
|
615
|
-
if (JSON.stringify(value.path) === JSON.stringify(linkedPath))
|
|
616
|
-
value.path = undefined;
|
|
617
|
-
effect({ operation: 'symlink', path: linkedPath, target: request.target });
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
if (request.operation === 'mkdir') {
|
|
621
|
-
if (!canonical.mkdir)
|
|
622
|
-
throw new FsError('ENOTSUP', { syscall: 'mkdir' });
|
|
623
|
-
let logical;
|
|
624
|
-
try {
|
|
625
|
-
logical = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(path(request.path).bytes());
|
|
626
|
-
}
|
|
627
|
-
catch {
|
|
628
|
-
throw new FsError('EILSEQ', { syscall: 'mkdir' });
|
|
629
|
-
}
|
|
630
|
-
await canonical.mkdir(logical, { signal, ...(request.mode === undefined ? {} : { mode: request.mode }) });
|
|
631
|
-
namespaceChanges.push({ callbackId: request.callbackId, path: Array.from(path(request.path).bytes()) });
|
|
632
|
-
effect({ operation: 'mkdir', path: Array.from(path(request.path).bytes()), ...(request.mode === undefined ? {} : { mode: request.mode }) });
|
|
633
|
-
return;
|
|
634
|
-
}
|
|
635
|
-
if (request.operation === 'open' || request.operation === 'create') {
|
|
636
|
-
if (request.access !== undefined && !['read', 'write', 'readwrite'].includes(request.access))
|
|
637
|
-
throw new TypeError('Invalid file access');
|
|
638
|
-
let object;
|
|
639
|
-
let creation;
|
|
640
|
-
if (request.operation === 'open') {
|
|
641
|
-
if (!open)
|
|
642
|
-
throw new FsError('ENOTSUP', { syscall: 'open' });
|
|
643
|
-
object = await open(path(request.path), { access: request.access ?? 'read', signal });
|
|
644
|
-
}
|
|
645
|
-
else if (fs.create) {
|
|
646
|
-
const acquired = await fs.create(path(request.path), { flag: request.flag ?? 'w', access: request.access ?? 'read', ...(request.mode === undefined ? {} : { mode: request.mode }), signal });
|
|
647
|
-
object = acquired;
|
|
648
|
-
}
|
|
649
|
-
else {
|
|
650
|
-
// Native acquisition always requires the canonical flag/disposition
|
|
651
|
-
// primitive, including the default truncating flag. A legacy hook
|
|
652
|
-
// cannot prove creation, preserve exclusivity or acknowledge truncate.
|
|
653
|
-
throw new FsError('ENOTSUP', { syscall: 'create' });
|
|
654
|
-
}
|
|
655
|
-
// Own cleanup before inspecting any backend admission properties.
|
|
656
|
-
// A receipt/identity getter can fail after canonical truncation or
|
|
657
|
-
// creation; neither that failure nor a changed method table may
|
|
658
|
-
// abandon the acquired retain or redirect its cleanup.
|
|
659
|
-
const close = object.close.bind(object);
|
|
660
|
-
try {
|
|
661
|
-
if (request.operation === 'create') {
|
|
662
|
-
creation = object.creation;
|
|
663
|
-
if (creation === 'created')
|
|
664
|
-
namespaceChanges.push({ callbackId: request.callbackId, path: Array.from(path(request.path).bytes()) });
|
|
665
|
-
// A disposition receipt must qualify this exact native flag.
|
|
666
|
-
// Do not infer exclusivity or truncation from a later stat.
|
|
667
|
-
// Rejected receipts still report completed canonical effects
|
|
668
|
-
// through the acquisition cleanup below; nothing rolls back.
|
|
669
|
-
const flag = request.flag ?? 'w';
|
|
670
|
-
if (creation !== 'created' && !(flag === 'w' && creation === 'truncated')
|
|
671
|
-
&& !(flag === 'a' && creation === 'opened'))
|
|
672
|
-
throw new FsError('EIO', { syscall: 'create' });
|
|
673
|
-
}
|
|
674
|
-
// Retain the acquired capability, not its mutable public method table.
|
|
675
|
-
// Bound receivers keep live backend state; no content is snapshotted.
|
|
676
|
-
const admittedAccess = request.access ?? 'read';
|
|
677
|
-
object = Object.freeze({
|
|
678
|
-
identity: object.identity, type: object.type,
|
|
679
|
-
stat: object.stat?.bind(object), close,
|
|
680
|
-
read: admittedAccess !== 'write' ? object.read?.bind(object) : undefined,
|
|
681
|
-
write: admittedAccess !== 'read' ? object.write?.bind(object) : undefined,
|
|
682
|
-
append: admittedAccess !== 'read' ? object.append?.bind(object) : undefined,
|
|
683
|
-
truncate: admittedAccess !== 'read' ? object.truncate?.bind(object) : undefined,
|
|
684
|
-
metadata: object.metadata?.bind(object), link: object.link?.bind(object),
|
|
685
|
-
});
|
|
686
|
-
if (object.identity === null || !['object', 'symbol'].includes(typeof object.identity)
|
|
687
|
-
|| !['file', 'directory', 'symlink'].includes(object.type))
|
|
688
|
-
throw new FsError('ENOTSUP');
|
|
689
|
-
}
|
|
690
|
-
catch (error) {
|
|
691
|
-
// Canonical acquisition can already have created or truncated the
|
|
692
|
-
// entry. Refusing its returned retain does not undo that effect.
|
|
693
|
-
// No admitted identity exists here; report only the native receipt.
|
|
694
|
-
if (creation === 'truncated')
|
|
695
|
-
effect({ operation: 'truncate', path: Array.from(path(request.path).bytes()), length: '0' });
|
|
696
|
-
else if (creation === 'created')
|
|
697
|
-
effect({ operation: 'created', path: Array.from(path(request.path).bytes()) });
|
|
698
|
-
try {
|
|
699
|
-
await close();
|
|
700
|
-
}
|
|
701
|
-
catch (cleanup) {
|
|
702
|
-
throw new AggregateError([error, cleanup], 'Rejected object cleanup failed', { cause: error });
|
|
703
|
-
}
|
|
704
|
-
throw error;
|
|
705
|
-
}
|
|
706
|
-
const handle = crypto.randomUUID();
|
|
707
|
-
let correlation = identities.get(object.identity);
|
|
708
|
-
if (!correlation) {
|
|
709
|
-
correlation = { id: crypto.randomUUID(), references: 0, retainedOutput: false };
|
|
710
|
-
identities.set(object.identity, correlation);
|
|
711
|
-
}
|
|
712
|
-
correlation.references++;
|
|
713
|
-
const identity = correlation.id;
|
|
714
|
-
const openedPath = Array.from(path(request.path).bytes());
|
|
715
|
-
// A delayed open retains its object even if the namespace changes
|
|
716
|
-
// before it returns. Its former spelling cannot locate later writes.
|
|
717
|
-
const changedDuringOpen = namespaceChanges.slice(namespaceObservation).some(change => change.callbackId !== request.callbackId && (change.path === undefined
|
|
718
|
-
|| change.path.every((byte, i) => openedPath[i] === byte)
|
|
719
|
-
&& (openedPath.length === change.path.length || openedPath[change.path.length] === 47)));
|
|
720
|
-
// A fresh canonical open can prove that a prior retained object no
|
|
721
|
-
// longer occupies this spelling. Its IO remains on the old identity.
|
|
722
|
-
if (!changedDuringOpen)
|
|
723
|
-
for (const value of handles.values())
|
|
724
|
-
if (value.identity !== identity && JSON.stringify(value.path) === JSON.stringify(openedPath))
|
|
725
|
-
value.path = undefined;
|
|
726
|
-
handles.set(handle, { fileId: request.fileId, object, identity, access: request.access ?? 'read', path: changedDuringOpen ? undefined : openedPath, reads: new AbortController() });
|
|
727
|
-
acquiringHandles--;
|
|
728
|
-
acquisitionReserved = false;
|
|
729
|
-
// Overlapping namespace callbacks retire the acquisition spelling;
|
|
730
|
-
// the retain still proves the created/truncated/opened identity.
|
|
731
|
-
const effectPath = changedDuringOpen ? undefined : openedPath;
|
|
732
|
-
if (creation === 'truncated')
|
|
733
|
-
effect({ operation: 'truncate', path: effectPath, object: identity, length: '0' });
|
|
734
|
-
else if (creation === 'created')
|
|
735
|
-
effect({ operation: 'created', path: effectPath, object: identity });
|
|
736
|
-
// Preserve the initial namespace observation even before this
|
|
737
|
-
// identity becomes an output. A later rename can retire the handle
|
|
738
|
-
// spelling before its first write. Projection promotes only
|
|
739
|
-
// identities with settled mutations, so untouched inputs stay out.
|
|
740
|
-
else
|
|
741
|
-
effect({ operation: 'open', path: effectPath, object: identity });
|
|
742
|
-
if (request.operation === 'create' || (request.access && request.access !== 'read'))
|
|
743
|
-
await retainOutput(object, identity);
|
|
744
|
-
signal.throwIfAborted();
|
|
745
|
-
return { handle, object: identity };
|
|
746
|
-
}
|
|
747
|
-
if (request.operation === 'rename') {
|
|
748
|
-
if (!fs.rename)
|
|
749
|
-
throw new FsError('ENOTSUP', { syscall: 'rename' });
|
|
750
|
-
const receipt = await fs.rename(path(request.path), path(request.destination), { signal });
|
|
751
|
-
// One canonical observation governs namespace retirement, effect
|
|
752
|
-
// publication and the replayed acknowledgment. Backend accessors
|
|
753
|
-
// cannot substitute another outcome between these stages.
|
|
754
|
-
const moved = receipt?.moved;
|
|
755
|
-
const source = Array.from(path(request.path).bytes());
|
|
756
|
-
const destination = Array.from(path(request.destination).bytes());
|
|
757
|
-
const samePath = JSON.stringify(source) === JSON.stringify(destination);
|
|
758
|
-
if (!samePath && moved !== false)
|
|
759
|
-
namespaceChanges.push({ callbackId: request.callbackId });
|
|
760
|
-
// Namespace settlement does not identify the former pathname's
|
|
761
|
-
// occupant. An external writer may have replaced it since our open.
|
|
762
|
-
effect({ operation: 'rename', path: source, destination, ...(samePath ? { moved: false } : typeof moved === 'boolean' ? { moved } : {}) });
|
|
763
|
-
// Literal paths cannot prove which aliases traverse a moved parent
|
|
764
|
-
// or displaced entry. Keep every retain and its live methods, but
|
|
765
|
-
// retire unverified path hints, including delayed acquisitions.
|
|
766
|
-
if (!samePath && moved !== false)
|
|
767
|
-
for (const value of handles.values())
|
|
768
|
-
value.path = undefined;
|
|
769
|
-
return typeof moved === 'boolean' ? { moved } : undefined;
|
|
770
|
-
}
|
|
771
|
-
if (request.operation === 'unlink') {
|
|
772
|
-
if (!fs.unlink)
|
|
773
|
-
throw new FsError('ENOTSUP', { syscall: 'unlink' });
|
|
774
|
-
await fs.unlink(path(request.path), { signal });
|
|
775
|
-
const source = Array.from(path(request.path).bytes());
|
|
776
|
-
namespaceChanges.push({ callbackId: request.callbackId });
|
|
777
|
-
effect({ operation: 'unlink', path: source });
|
|
778
|
-
for (const value of handles.values())
|
|
779
|
-
value.path = undefined;
|
|
780
|
-
return;
|
|
781
|
-
}
|
|
782
|
-
if (request.operation === 'readdir') {
|
|
783
|
-
if (!fs.readdir)
|
|
784
|
-
throw new FsError('ENOTSUP', { syscall: 'readdir' });
|
|
785
|
-
const entries = await fs.readdir(path(request.path), { signal, maxEntries });
|
|
786
|
-
if (!Array.isArray(entries))
|
|
787
|
-
throw new FsError('EIO', { syscall: 'readdir' });
|
|
788
|
-
const length = entries.length;
|
|
789
|
-
if (length > maxEntries)
|
|
790
|
-
throw new FsError('EFBIG', { syscall: 'readdir' });
|
|
791
|
-
let bytes = 0;
|
|
792
|
-
const listing = Array.from({ length }, (_, index) => {
|
|
793
|
-
if (!Object.hasOwn(entries, index))
|
|
794
|
-
throw new FsError('EIO', { syscall: 'readdir' });
|
|
795
|
-
const entry = entries[index];
|
|
796
|
-
if (!entry)
|
|
797
|
-
throw new FsError('EIO', { syscall: 'readdir' });
|
|
798
|
-
const { name: component, type } = entry;
|
|
799
|
-
if (!['file', 'directory', 'symlink', 'character', 'fifo', 'socket'].includes(type))
|
|
800
|
-
throw new FsError('EIO', { syscall: 'readdir' });
|
|
801
|
-
// Read the genuine owned carrier, not a public override that can
|
|
802
|
-
// replace an authoritative byte name with another spelling.
|
|
803
|
-
let carrier;
|
|
804
|
-
try {
|
|
805
|
-
carrier = BytePath.prototype.bytes.call(component);
|
|
806
|
-
}
|
|
807
|
-
catch {
|
|
808
|
-
throw new FsError('EIO', { syscall: 'readdir' });
|
|
809
|
-
}
|
|
810
|
-
if (!(carrier instanceof Uint8Array))
|
|
811
|
-
throw new FsError('EIO', { syscall: 'readdir' });
|
|
812
|
-
// Admit against the remaining aggregate transfer budget before
|
|
813
|
-
// retaining a backend-owned fragment in execution memory.
|
|
814
|
-
const span = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Uint8Array.prototype), 'byteLength').get.call(carrier);
|
|
815
|
-
if (span > maxIo - bytes)
|
|
816
|
-
throw new FsError('EFBIG', { syscall: 'readdir' });
|
|
817
|
-
const name = new Uint8Array(carrier);
|
|
818
|
-
bytes += name.length;
|
|
819
|
-
if (!name.length || name.includes(0) || name.includes(47)
|
|
820
|
-
|| (name.length <= 2 && name.every(byte => byte === 46)))
|
|
821
|
-
throw new FsError('EIO', { syscall: 'readdir' });
|
|
822
|
-
if (bytes > maxIo)
|
|
823
|
-
throw new FsError('EFBIG', { syscall: 'readdir' });
|
|
824
|
-
return { name: Array.from(name), type };
|
|
825
|
-
});
|
|
826
|
-
// Never acknowledge a prefix after backend metadata access changed
|
|
827
|
-
// the admitted listing. This is carrier validation, not a promise
|
|
828
|
-
// of an atomic directory snapshot against external writers.
|
|
829
|
-
if (entries.length !== length)
|
|
830
|
-
throw new FsError('EIO', { syscall: 'readdir' });
|
|
831
|
-
return listing;
|
|
832
|
-
}
|
|
833
|
-
if (request.operation === 'capabilities' || request.operation === 'readlink'
|
|
834
|
-
|| request.operation === 'path-access' || request.operation === 'realpath'
|
|
835
|
-
|| request.operation === 'path-stat' || request.operation === 'path-lstat') {
|
|
836
|
-
const bytes = path(request.path).bytes();
|
|
837
|
-
let logical;
|
|
838
|
-
try {
|
|
839
|
-
logical = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
840
|
-
}
|
|
841
|
-
catch {
|
|
842
|
-
throw new FsError('EILSEQ', { syscall: request.operation === 'path-access' ? 'access' : request.operation });
|
|
843
|
-
}
|
|
844
|
-
if (request.operation === 'path-access') {
|
|
845
|
-
if (!canonical.access)
|
|
846
|
-
throw new FsError('ENOTSUP', { syscall: 'access' });
|
|
847
|
-
return canonical.access(logical, request.mode ?? 0, { signal });
|
|
848
|
-
}
|
|
849
|
-
if (request.operation === 'realpath') {
|
|
850
|
-
if (!canonical.realpath)
|
|
851
|
-
throw new FsError('ENOTSUP', { syscall: 'realpath' });
|
|
852
|
-
const resolved = await canonical.realpath(logical, { signal });
|
|
853
|
-
if (typeof resolved !== 'string' || !resolved.startsWith('/') || resolved.includes('\0'))
|
|
854
|
-
throw new FsError('EIO', { syscall: 'realpath' });
|
|
855
|
-
if (resolved.length > maxIo)
|
|
856
|
-
throw new FsError('EFBIG', { syscall: 'realpath' });
|
|
857
|
-
const encoded = new TextEncoder().encode(resolved);
|
|
858
|
-
if (encoded.length > maxIo)
|
|
859
|
-
throw new FsError('EFBIG', { syscall: 'realpath' });
|
|
860
|
-
if (new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(encoded) !== resolved)
|
|
861
|
-
throw new FsError('EILSEQ', { syscall: 'realpath' });
|
|
862
|
-
return Array.from(encoded);
|
|
863
|
-
}
|
|
864
|
-
if (request.operation === 'path-stat' || request.operation === 'path-lstat') {
|
|
865
|
-
const method = request.operation === 'path-stat' ? 'stat' : 'lstat';
|
|
866
|
-
if (!canonical[method])
|
|
867
|
-
throw new FsError('ENOTSUP', { syscall: method });
|
|
868
|
-
// Path metadata is an observation, never retained wire identity.
|
|
869
|
-
return admitCanonicalMetadata(await canonical[method](logical, { signal }), method);
|
|
870
|
-
}
|
|
871
|
-
if (request.operation === 'capabilities') {
|
|
872
|
-
if (!canonical.capabilitiesFor && sourceAdmission.capabilities === undefined)
|
|
873
|
-
throw new FsError('ENOTSUP', { syscall: 'capabilities' });
|
|
874
|
-
const capabilities = canonical.capabilitiesFor ? await canonical.capabilitiesFor(logical, { signal,
|
|
875
|
-
...(request.create === undefined ? {} : { create: request.create }),
|
|
876
|
-
...(request.allowDirectory === undefined ? {} : { allowDirectory: request.allowDirectory }) }) : sourceAdmission.capabilities;
|
|
877
|
-
const observed = admitCanonicalCapabilities(capabilities, 'capabilities', logical, maxIo);
|
|
878
|
-
// A legacy backend guarantee alone cannot admit an operation on
|
|
879
|
-
// this retained-object route. Method presence is necessary, never
|
|
880
|
-
// sufficient: keep unknown/false guarantees and only narrow true.
|
|
881
|
-
// Do not acquire a file merely to probe its optional handle methods.
|
|
882
|
-
const namespaceSupport = {
|
|
883
|
-
// Descriptor-only jobs need no pathname acquisition. Legacy
|
|
884
|
-
// read/resize guarantees cannot qualify a missing object route;
|
|
885
|
-
// refuse at the actual access without consulting scratch files.
|
|
886
|
-
read: !!fs.open,
|
|
887
|
-
streamingRead: !!fs.open,
|
|
888
|
-
retainedRead: !!fs.open,
|
|
889
|
-
truncate: !!fs.open,
|
|
890
|
-
retainedResize: !!fs.open,
|
|
891
|
-
readdir: !!fs.readdir,
|
|
892
|
-
// Ordinary writes and append streams may create a missing
|
|
893
|
-
// file. Writable existing retains alone cannot supply those
|
|
894
|
-
// routes, even if legacy pathname methods advertise them.
|
|
895
|
-
write: !!fs.create,
|
|
896
|
-
append: !!fs.create,
|
|
897
|
-
streamingWrite: !!fs.create,
|
|
898
|
-
streamingAppend: !!fs.create,
|
|
899
|
-
descriptorWriteStream: !!fs.create,
|
|
900
|
-
// safe-fs defines this legacy flag as eligibility for the
|
|
901
|
-
// shell's bounded whole-file offset replacement strategy.
|
|
902
|
-
// It cannot qualify retained positional writes, large offsets
|
|
903
|
-
// or sparse allocation. Actual writes use the admitted object
|
|
904
|
-
// operation and preserve its ENOTSUP/EFBIG/partial receipts.
|
|
905
|
-
randomAccessWrite: false,
|
|
906
|
-
exclusiveCreate: !!fs.create,
|
|
907
|
-
rename: !!fs.rename,
|
|
908
|
-
atomicRename: !!fs.rename,
|
|
909
|
-
mkdir: !!canonical.mkdir,
|
|
910
|
-
remove: !!fs.unlink,
|
|
911
|
-
removeDirectory: !!canonical.rmdir && observed.snapshotRmdir !== true,
|
|
912
|
-
readlink: !!canonical.readlink,
|
|
913
|
-
symlinks: !!canonical.symlink,
|
|
914
|
-
stat: !!canonical.stat && !!canonical.lstat,
|
|
915
|
-
access: !!canonical.access,
|
|
916
|
-
realpath: !!canonical.realpath,
|
|
917
|
-
// The byte rename contract has no no-replace precondition.
|
|
918
|
-
atomicRenameNoReplace: false,
|
|
919
|
-
// These require canonical primitives absent from this route.
|
|
920
|
-
// A sequence of retained writes or namespace callbacks cannot
|
|
921
|
-
// inherit a legacy backend's compound/atomic guarantee.
|
|
922
|
-
copy: false,
|
|
923
|
-
exclusiveCopy: false,
|
|
924
|
-
recursiveMkdir: false,
|
|
925
|
-
recursiveRemove: false,
|
|
926
|
-
atomicFileStaging: false,
|
|
927
|
-
atomicFileMutation: false,
|
|
928
|
-
atomicDirectoryMetadata: false,
|
|
929
|
-
atomicResize: false,
|
|
930
|
-
};
|
|
931
|
-
for (const [capability, supported] of Object.entries(namespaceSupport)) {
|
|
932
|
-
if (observed[capability] === true && !supported)
|
|
933
|
-
observed[capability] = false;
|
|
934
|
-
}
|
|
935
|
-
if (observed.readOnly === true) {
|
|
936
|
-
for (const capability of ['write', 'append', 'truncate', 'streamingWrite', 'streamingAppend', 'descriptorWriteStream', 'randomAccessWrite', 'exclusiveCreate', 'mkdir', 'recursiveMkdir', 'remove', 'removeDirectory', 'recursiveRemove', 'rename', 'copy', 'exclusiveCopy', 'symlinks', 'hardlinks', 'permissions', 'timestamps', 'atomicRename', 'atomicRenameNoReplace', 'atomicFileStaging', 'atomicFileMutation', 'atomicDirectoryMetadata', 'atomicResize', 'retainedResize']) {
|
|
937
|
-
if (observed[capability] === true)
|
|
938
|
-
observed[capability] = false;
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
// Narrowing true guarantees to false adds one JSON octet per
|
|
942
|
-
// member. Bound the final reply as well as backend admission.
|
|
943
|
-
if (new TextEncoder().encode(JSON.stringify(observed)).length > maxIo)
|
|
944
|
-
throw new FsError('EFBIG', { syscall: 'capabilities', path: logical });
|
|
945
|
-
return observed;
|
|
946
|
-
}
|
|
947
|
-
if (!canonical.readlink)
|
|
948
|
-
throw new FsError('ENOTSUP', { syscall: 'readlink' });
|
|
949
|
-
const spelling = await canonical.readlink(logical, { signal });
|
|
950
|
-
if (typeof spelling !== 'string' || !spelling.length || spelling.includes('\0'))
|
|
951
|
-
throw new FsError('EIO', { syscall: 'readlink' });
|
|
952
|
-
// UTF-8 encoding replaces unpaired UTF-16 surrogates. A legacy
|
|
953
|
-
// string backend cannot authorize those manufactured target bytes.
|
|
954
|
-
// Bound the string before allocating its binary representation.
|
|
955
|
-
if (spelling.length > maxIo)
|
|
956
|
-
throw new FsError('EFBIG', { syscall: 'readlink' });
|
|
957
|
-
const target = new TextEncoder().encode(spelling);
|
|
958
|
-
if (target.length > maxIo)
|
|
959
|
-
throw new FsError('EFBIG', { syscall: 'readlink' });
|
|
960
|
-
if (new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(target) !== spelling)
|
|
961
|
-
throw new FsError('EILSEQ', { syscall: 'readlink' });
|
|
962
|
-
return Array.from(target);
|
|
963
|
-
}
|
|
964
|
-
const retained = handles.get(request.handle);
|
|
965
|
-
if (!retained || retained.fileId !== request.fileId)
|
|
966
|
-
throw new FsError('EBADF');
|
|
967
|
-
const object = retained.object;
|
|
968
|
-
if (request.operation === 'close') {
|
|
969
|
-
handles.delete(request.handle);
|
|
970
|
-
closingHandles++;
|
|
971
|
-
try {
|
|
972
|
-
return await object.close();
|
|
973
|
-
}
|
|
974
|
-
finally {
|
|
975
|
-
closingHandles--;
|
|
976
|
-
const correlation = identities.get(object.identity);
|
|
977
|
-
if (--correlation.references === 0 && !correlation.retainedOutput)
|
|
978
|
-
identities.delete(object.identity);
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
if (request.operation === 'stat') {
|
|
982
|
-
if (!object.stat)
|
|
983
|
-
throw new FsError('ENOTSUP', { syscall: 'stat' });
|
|
984
|
-
// ExactFileStat is structural: native backends may return prototype
|
|
985
|
-
// accessors. Observe only contract fields, once, at this fstat stage;
|
|
986
|
-
// enumerable private state is neither metadata nor wire authority.
|
|
987
|
-
const { type, size, allocatedBytes, nlink, mode, uid, gid, atimeNs, mtimeNs, ctimeNs } = await object.stat({ signal });
|
|
988
|
-
const observed = { type, size, allocatedBytes, nlink, mode, uid, gid, atimeNs, mtimeNs, ctimeNs };
|
|
989
|
-
if (observed.type !== object.type)
|
|
990
|
-
throw new FsError('EIO', { syscall: 'stat' });
|
|
991
|
-
try {
|
|
992
|
-
encodeFileMetadata(observed);
|
|
993
|
-
}
|
|
994
|
-
catch {
|
|
995
|
-
throw new FsError('EIO', { syscall: 'stat' });
|
|
996
|
-
}
|
|
997
|
-
// Object correlation comes from the admitted retain. Backend identity
|
|
998
|
-
// scopes and device/inode pairs cannot grant wire authority.
|
|
999
|
-
return observed;
|
|
1000
|
-
}
|
|
1001
|
-
if (request.operation === 'read') {
|
|
1002
|
-
if (retained.access === 'write')
|
|
1003
|
-
throw new FsError('EBADF');
|
|
1004
|
-
if (!Number.isSafeInteger(request.maxBytes) || request.maxBytes < 0 || request.maxBytes > maxIo)
|
|
1005
|
-
throw new FsError('EINVAL');
|
|
1006
|
-
if (!object.read)
|
|
1007
|
-
throw new FsError('ENOTSUP', { syscall: 'read' });
|
|
1008
|
-
const readSignal = AbortSignal.any([signal, reads.signal, retained.reads.signal]);
|
|
1009
|
-
readSignal.throwIfAborted();
|
|
1010
|
-
const bytes = await object.read(decodeFileOffset(request.position), request.maxBytes, { signal: readSignal });
|
|
1011
|
-
if (!(bytes instanceof Uint8Array))
|
|
1012
|
-
throw new FsError('EIO', { syscall: 'read' });
|
|
1013
|
-
const span = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Uint8Array.prototype), 'byteLength').get.call(bytes);
|
|
1014
|
-
if (span > request.maxBytes)
|
|
1015
|
-
throw new FsError('EIO', { syscall: 'read' });
|
|
1016
|
-
return new Uint8Array(bytes);
|
|
1017
|
-
}
|
|
1018
|
-
if (request.operation === 'write' || request.operation === 'append') {
|
|
1019
|
-
if (retained.access === 'read')
|
|
1020
|
-
throw new FsError('EBADF');
|
|
1021
|
-
if (!(request.bytes instanceof Uint8Array) && !Array.isArray(request.bytes))
|
|
1022
|
-
throw new FsError('EINVAL');
|
|
1023
|
-
if (request.bytes.length > maxIo)
|
|
1024
|
-
throw new FsError('EINVAL');
|
|
1025
|
-
if (!(request.bytes instanceof Uint8Array))
|
|
1026
|
-
for (const n of request.bytes)
|
|
1027
|
-
if (!Number.isInteger(n) || n < 0 || n > 255)
|
|
1028
|
-
throw new FsError('EINVAL');
|
|
1029
|
-
const owned = Uint8Array.from(request.bytes);
|
|
1030
|
-
let count;
|
|
1031
|
-
if (request.operation === 'append') {
|
|
1032
|
-
if (!object.append)
|
|
1033
|
-
throw new FsError('ENOTSUP', { syscall: 'append' });
|
|
1034
|
-
count = await object.append(owned, { signal });
|
|
1035
|
-
}
|
|
1036
|
-
else {
|
|
1037
|
-
if (!object.write)
|
|
1038
|
-
throw new FsError('ENOTSUP', { syscall: 'write' });
|
|
1039
|
-
count = await object.write(decodeFileOffset(request.position), owned, { signal });
|
|
1040
|
-
}
|
|
1041
|
-
if (!Number.isSafeInteger(count) || count < 0 || count > request.bytes.length)
|
|
1042
|
-
throw new FsError('EIO', { syscall: request.operation });
|
|
1043
|
-
effect({ operation: request.operation, object: retained.identity, path: retained.path, ...(request.operation === 'write' ? { position: request.position } : {}), bytes: Array.from(request.bytes).slice(0, count), count });
|
|
1044
|
-
return count;
|
|
1045
|
-
}
|
|
1046
|
-
if (request.operation === 'truncate') {
|
|
1047
|
-
if (retained.access === 'read')
|
|
1048
|
-
throw new FsError('EBADF');
|
|
1049
|
-
if (!object.truncate)
|
|
1050
|
-
throw new FsError('ENOTSUP', { syscall: 'truncate' });
|
|
1051
|
-
await object.truncate(decodeFileOffset(request.length), { signal });
|
|
1052
|
-
effect({ operation: 'truncate', object: retained.identity, path: retained.path, length: request.length });
|
|
1053
|
-
return;
|
|
1054
|
-
}
|
|
1055
|
-
if (request.operation === 'metadata') {
|
|
1056
|
-
if (!object.metadata)
|
|
1057
|
-
throw new FsError('ENOTSUP');
|
|
1058
|
-
await object.metadata(decodeObjectMetadata(request.changes), { signal });
|
|
1059
|
-
effect({ operation: 'metadata', object: retained.identity, path: retained.path, changes: request.changes });
|
|
1060
|
-
await retainOutput(object, retained.identity);
|
|
1061
|
-
return;
|
|
1062
|
-
}
|
|
1063
|
-
if (request.operation === 'link') {
|
|
1064
|
-
if (!object.link)
|
|
1065
|
-
throw new FsError('ENOTSUP', { syscall: 'link' });
|
|
1066
|
-
const destination = path(request.destination);
|
|
1067
|
-
await object.link(destination, { signal });
|
|
1068
|
-
const linkedPath = Array.from(destination.bytes());
|
|
1069
|
-
namespaceChanges.push({ callbackId: request.callbackId, path: linkedPath });
|
|
1070
|
-
// A settled link proves which object occupies this new spelling.
|
|
1071
|
-
// Other retained identities still live, but their old path hint may
|
|
1072
|
-
// have become stale through an external namespace operation.
|
|
1073
|
-
for (const value of handles.values())
|
|
1074
|
-
if (value.identity !== retained.identity && JSON.stringify(value.path) === JSON.stringify(linkedPath))
|
|
1075
|
-
value.path = undefined;
|
|
1076
|
-
effect({ operation: 'link', object: retained.identity, destination: linkedPath });
|
|
1077
|
-
await retainOutput(object, retained.identity);
|
|
1078
|
-
return;
|
|
1079
|
-
}
|
|
1080
|
-
throw new FsError('ENOTSUP');
|
|
1081
|
-
}
|
|
1082
|
-
finally {
|
|
1083
|
-
if (acquisitionReserved)
|
|
1084
|
-
acquiringHandles--;
|
|
1085
|
-
releaseEffect?.();
|
|
1086
|
-
}
|
|
1087
|
-
}).then(value => structuredClone(value));
|
|
1088
|
-
callbacks.set(request.callbackId, { body, result });
|
|
1089
|
-
const settled = result.catch(() => { });
|
|
1090
|
-
queues.set(queue, settled);
|
|
1091
|
-
pending.add(settled);
|
|
1092
|
-
void settled.then(() => {
|
|
1093
|
-
pending.delete(settled);
|
|
1094
|
-
if (queues.get(queue) === settled)
|
|
1095
|
-
queues.delete(queue);
|
|
1096
|
-
});
|
|
1097
|
-
// Publish replay and cursor barriers before abort listeners can reenter.
|
|
1098
|
-
// Waiting to cancel inside the queued close deadlocks behind an idle
|
|
1099
|
-
// upstream read. Only the authenticated owner can retire this consumer.
|
|
1100
|
-
if (request.operation === 'descriptor-close' && descriptorOwners.get(request.handle) === request.fileId)
|
|
1101
|
-
descriptors?.retireReads(request.handle);
|
|
1102
|
-
if (request.operation === 'close') {
|
|
1103
|
-
const retained = handles.get(request.handle);
|
|
1104
|
-
if (retained?.fileId === request.fileId)
|
|
1105
|
-
retained.reads.abort(new FsError('EBADF'));
|
|
1106
|
-
}
|
|
1107
|
-
return structuredClone(await result);
|
|
1108
|
-
};
|
|
1109
|
-
let primary;
|
|
1110
|
-
const dispose = async () => {
|
|
1111
|
-
closed = true;
|
|
1112
|
-
reads.abort(new FsError('EBADF'));
|
|
1113
|
-
descriptors?.retireReads();
|
|
1114
|
-
await Promise.all([...pending]);
|
|
1115
|
-
const cleanup = await Promise.allSettled([...handles.values()].map(({ object }) => Promise.resolve().then(() => object.close())));
|
|
1116
|
-
cleanup.push(...await Promise.allSettled([...endpointLeases].map(lease => lease.close())));
|
|
1117
|
-
cleanup.push(...await Promise.allSettled([descriptors?.dispose()]));
|
|
1118
|
-
descriptorOwners.clear();
|
|
1119
|
-
handles.clear();
|
|
1120
|
-
callbacks.clear();
|
|
1121
|
-
identities.clear();
|
|
1122
|
-
queues.clear();
|
|
1123
|
-
if (acquiredWorkspace)
|
|
1124
|
-
cleanup.push(...await Promise.allSettled([Promise.resolve().then(() => options.release?.(workspace ?? acquiredWorkspace, acquiredWorkspace))]));
|
|
1125
|
-
const failures = cleanup.filter(result => result.status === 'rejected');
|
|
1126
|
-
if (failures.length) {
|
|
1127
|
-
const error = new AggregateError([...(primary ? [primary.cause] : []), ...failures.map(result => result.reason)], 'Job handle cleanup failed', primary);
|
|
1128
|
-
throw options.effects ? new JobEffectsError(error, options.effects.inspect()) : error;
|
|
1129
|
-
}
|
|
1130
|
-
};
|
|
1131
|
-
try {
|
|
1132
|
-
// Own the acquisition before snapshot admission can fail. Cancellation
|
|
1133
|
-
// during preparation still retires the late workspace and keeps its cause.
|
|
1134
|
-
acquiredWorkspace = await options.prepare(structuredClone(invocation), signal);
|
|
1135
|
-
signal.throwIfAborted();
|
|
1136
|
-
const acquired = acquiredWorkspace;
|
|
1137
|
-
// Snapshot the public binding, not private driver capabilities. Retain
|
|
1138
|
-
// those capabilities for release without letting mutable IDs redirect it.
|
|
1139
|
-
const snapshot = () => {
|
|
1140
|
-
// Observe each public field once. Reading it again after admission
|
|
1141
|
-
// could replace a stale revision or incomplete tree with a ready one.
|
|
1142
|
-
const publicFields = [...fields, 'cwd', 'originalArgv', 'state', 'entries', 'readiness'];
|
|
1143
|
-
const publicDescriptors = Object.fromEntries(publicFields
|
|
1144
|
-
.map(key => [key, Object.getOwnPropertyDescriptor(acquired, key)]));
|
|
1145
|
-
const observed = Object.fromEntries(publicFields.map(key => [key, Reflect.get(acquired, key)]));
|
|
1146
|
-
const entryCount = observed.entries?.length;
|
|
1147
|
-
const entryRecords = [];
|
|
1148
|
-
const entryDescriptors = [];
|
|
1149
|
-
const entrySlots = [];
|
|
1150
|
-
// Private driver accessors may acquire scratch storage or do advisory
|
|
1151
|
-
// work. They are not admission evidence and must never run as part of
|
|
1152
|
-
// startup or revalidation. Preserve inert extension values for cleanup;
|
|
1153
|
-
// the exact acquired capability remains the second release argument.
|
|
1154
|
-
const extensions = Object.fromEntries(Object.entries(Object.getOwnPropertyDescriptors(acquired))
|
|
1155
|
-
.filter(([key, descriptor]) => !publicFields.includes(key) && descriptor.enumerable && 'value' in descriptor)
|
|
1156
|
-
.map(([key, descriptor]) => [key, descriptor.value]));
|
|
1157
|
-
const captured = { ...extensions, ...observed, ...structuredClone({
|
|
1158
|
-
...Object.fromEntries(fields.map(field => [field, observed[field]])),
|
|
1159
|
-
...ownNativeProcessView(observed.cwd, observed.originalArgv),
|
|
1160
|
-
state: observed.state,
|
|
1161
|
-
// Records may also contain lazy acquisition/failure capabilities.
|
|
1162
|
-
// Read only the metadata used to admit the starting tree, both now
|
|
1163
|
-
// and after live validation; speculative payloads are not evidence.
|
|
1164
|
-
// Driver iterators and inherited slots cannot replace the records
|
|
1165
|
-
// belonging to the acquired starting tree.
|
|
1166
|
-
entries: Array.isArray(observed.entries) ? Array.from({ length: observed.entries.length }, (_, index) => {
|
|
1167
|
-
if (!Object.hasOwn(observed.entries, index))
|
|
1168
|
-
throw new Error('Incomplete or stale job materialization');
|
|
1169
|
-
entrySlots.push(Object.getOwnPropertyDescriptor(observed.entries, index));
|
|
1170
|
-
const entry = observed.entries[index];
|
|
1171
|
-
entryRecords.push(entry);
|
|
1172
|
-
if (!entry)
|
|
1173
|
-
return entry;
|
|
1174
|
-
entryDescriptors[index] = Object.fromEntries(['state', 'kind', 'index']
|
|
1175
|
-
.map(key => [key, Object.getOwnPropertyDescriptor(entry, key)]));
|
|
1176
|
-
const { state, kind } = entry;
|
|
1177
|
-
// Manifest indexes are required-work identity, not advisory
|
|
1178
|
-
// acquisition payload. Never inspect speculative index accessors.
|
|
1179
|
-
const manifestIndex = kind === undefined || kind === 'required' ? entry.index : undefined;
|
|
1180
|
-
return { state, ...(kind === undefined ? {} : { kind }), ...(manifestIndex === undefined ? {} : { index: manifestIndex }) };
|
|
1181
|
-
}) : observed.entries,
|
|
1182
|
-
readiness: snapshotReadiness(observed.readiness),
|
|
1183
|
-
}) };
|
|
1184
|
-
// Later metadata observations must not replace an earlier binding
|
|
1185
|
-
// field or either ledger. Inspect property descriptors without invoking
|
|
1186
|
-
// driver getters again: a second getter result is not fresh authority.
|
|
1187
|
-
for (const key of publicFields) {
|
|
1188
|
-
if (!unchangedMetadata(acquired, key, publicDescriptors[key], Reflect.get(observed, key)))
|
|
1189
|
-
throw new Error('Incomplete or stale job materialization');
|
|
1190
|
-
}
|
|
1191
|
-
// A metadata accessor can add required work while either ledger is
|
|
1192
|
-
// copied. Never admit a prefix as the complete installed tree.
|
|
1193
|
-
if (observed.entries?.length !== entryCount)
|
|
1194
|
-
throw new Error('Incomplete or stale job materialization');
|
|
1195
|
-
for (let index = 0; index < entryRecords.length; index++) {
|
|
1196
|
-
const record = entryRecords[index];
|
|
1197
|
-
if (!unchangedMetadata(observed.entries, String(index), entrySlots[index], record))
|
|
1198
|
-
throw new Error('Incomplete or stale job materialization');
|
|
1199
|
-
if (!record)
|
|
1200
|
-
continue;
|
|
1201
|
-
const entry = captured.entries[index];
|
|
1202
|
-
// Advisory indexes are acquisition payloads, not startup evidence.
|
|
1203
|
-
const keys = entry.kind === undefined || entry.kind === 'required'
|
|
1204
|
-
? ['state', 'kind', 'index'] : ['state', 'kind'];
|
|
1205
|
-
for (const key of keys) {
|
|
1206
|
-
if (!unchangedMetadata(record, key, entryDescriptors[index][key], entry[key]))
|
|
1207
|
-
throw new Error('Incomplete or stale job materialization');
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
return captured;
|
|
1211
|
-
};
|
|
1212
|
-
workspace = snapshot();
|
|
1213
|
-
signal.throwIfAborted();
|
|
1214
|
-
assertRequiredReadiness(workspace.readiness);
|
|
1215
|
-
if (fields.some(field => workspace[field] !== invocation[field]) || workspace.state !== 'ready'
|
|
1216
|
-
|| !completeStartingEntries(workspace.entries)
|
|
1217
|
-
|| JSON.stringify(workspace.cwd) !== JSON.stringify(invocation.cwd)
|
|
1218
|
-
|| JSON.stringify(workspace.originalArgv) !== JSON.stringify(invocation.originalArgv))
|
|
1219
|
-
throw new Error('Incomplete or stale job materialization');
|
|
1220
|
-
if (options.validate) {
|
|
1221
|
-
await options.validate({ workspace: acquired, invocation: structuredClone(invocation), signal });
|
|
1222
|
-
signal.throwIfAborted();
|
|
1223
|
-
const current = snapshot();
|
|
1224
|
-
assertRequiredReadiness(current.readiness, workspace.readiness);
|
|
1225
|
-
// Revalidation may observe drift, but cannot replace the pinned binding
|
|
1226
|
-
// or remove required entries to manufacture a complete starting tree.
|
|
1227
|
-
if (fields.some(field => current[field] !== workspace[field])
|
|
1228
|
-
|| current.state !== 'ready'
|
|
1229
|
-
|| !completeStartingEntries(current.entries)
|
|
1230
|
-
|| JSON.stringify(current.cwd) !== JSON.stringify(workspace.cwd)
|
|
1231
|
-
|| JSON.stringify(current.originalArgv) !== JSON.stringify(workspace.originalArgv)
|
|
1232
|
-
|| requiredEntryIdentity(current.entries) !== requiredEntryIdentity(workspace.entries))
|
|
1233
|
-
throw new Error('Incomplete or stale job materialization');
|
|
1234
|
-
workspace = current;
|
|
1235
|
-
}
|
|
1236
|
-
// Reading the driver's live readiness can itself observe lease loss.
|
|
1237
|
-
// Finish that admission work before checking cancellation at launch.
|
|
1238
|
-
signal.throwIfAborted();
|
|
1239
|
-
const result = await options.run({ jobId, invocation: structuredClone(invocation), readiness: structuredClone(workspace.readiness), signal, access, openEndpoint });
|
|
1240
|
-
const exitCode = result?.exitCode;
|
|
1241
|
-
if (!Number.isInteger(exitCode) || exitCode < 0 || exitCode > 255)
|
|
1242
|
-
throw new TypeError('Invalid native exit status');
|
|
1243
|
-
// Completion is also the effect barrier: stop admitting callbacks before
|
|
1244
|
-
// draining those already accepted. Their canonical effects remain live
|
|
1245
|
-
// and acknowledged individually, regardless of the native exit code.
|
|
1246
|
-
closed = true;
|
|
1247
|
-
reads.abort(new FsError('EBADF'));
|
|
1248
|
-
descriptors?.retireReads();
|
|
1249
|
-
await Promise.all([...pending]);
|
|
1250
|
-
options.effects?.settle({ state: 'exited', exitCode });
|
|
1251
|
-
signal.throwIfAborted();
|
|
1252
|
-
return { exitCode };
|
|
1253
|
-
}
|
|
1254
|
-
catch (cause) {
|
|
1255
|
-
primary = { cause };
|
|
1256
|
-
closed = true;
|
|
1257
|
-
reads.abort(new FsError('EBADF'));
|
|
1258
|
-
descriptors?.retireReads();
|
|
1259
|
-
await Promise.all([...pending]);
|
|
1260
|
-
if (options.effects?.inspect().native.state === 'running')
|
|
1261
|
-
options.effects.settle({ state: signal.aborted ? 'cancelled' : 'failed', error: cause instanceof Error ? cause.message : String(cause) });
|
|
1262
|
-
throw options.effects ? new JobEffectsError(cause, options.effects.inspect()) : cause;
|
|
1263
|
-
}
|
|
1264
|
-
finally {
|
|
1265
|
-
await dispose();
|
|
1266
|
-
}
|
|
1267
|
-
},
|
|
1268
|
-
};
|
|
1269
|
-
}
|