just-bash 2.11.5 → 2.11.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/Bash.d.ts +8 -1
  2. package/dist/bin/chunks/chunk-4QM2TCNV.js +2 -0
  3. package/dist/bin/chunks/{chunk-X4GRWTSZ.js → chunk-ISOXAKGQ.js} +58 -58
  4. package/dist/bin/{shell/chunks/expansion-LT2QL7LY.js → chunks/expansion-AMH5BAVV.js} +1 -1
  5. package/dist/bin/chunks/python3-UK6DVXEU.js +14 -0
  6. package/dist/bin/chunks/worker.js +226 -2
  7. package/dist/bin/just-bash.js +233 -233
  8. package/dist/bin/shell/chunks/chunk-4QM2TCNV.js +2 -0
  9. package/dist/bin/shell/chunks/{chunk-X4GRWTSZ.js → chunk-ISOXAKGQ.js} +58 -58
  10. package/dist/bin/{chunks/expansion-LT2QL7LY.js → shell/chunks/expansion-AMH5BAVV.js} +1 -1
  11. package/dist/bin/shell/chunks/python3-UK6DVXEU.js +14 -0
  12. package/dist/bin/shell/shell.js +267 -266
  13. package/dist/bundle/browser.js +554 -554
  14. package/dist/bundle/chunks/{chunk-YSCUI42G.js → chunk-V4CDPGZH.js} +58 -58
  15. package/dist/bundle/chunks/chunk-YYAPW4OA.js +1 -0
  16. package/dist/bundle/chunks/{expansion-HFUNFLDT.js → expansion-5HXXJ2SG.js} +1 -1
  17. package/dist/bundle/chunks/python3-W2D6SNQF.js +13 -0
  18. package/dist/bundle/chunks/worker.js +226 -2
  19. package/dist/bundle/index.js +181 -181
  20. package/dist/fs/real-fs-utils.d.ts +3 -1
  21. package/dist/fs/sanitize-error.d.ts +16 -0
  22. package/dist/index.d.ts +1 -1
  23. package/dist/limits.d.ts +2 -0
  24. package/dist/parser/lexer.d.ts +6 -1
  25. package/dist/parser/parser.d.ts +3 -3
  26. package/package.json +1 -1
  27. package/dist/bin/chunks/python3-ZWX5SFJ3.js +0 -14
  28. package/dist/bin/shell/chunks/python3-ZWX5SFJ3.js +0 -14
  29. package/dist/bundle/chunks/python3-SKZGHYDO.js +0 -13
@@ -52,9 +52,11 @@ export declare function resolveCanonicalPathNoSymlinks(realPath: string, root: s
52
52
  /**
53
53
  * Validate that a root directory exists and is actually a directory.
54
54
  * Throws with a descriptive message including `fsName` (e.g. "OverlayFs",
55
- * "ReadWriteFs") on failure.
55
+ * "ReadWriteFs") on failure. Does NOT include the real root path in the
56
+ * error message to prevent information leakage.
56
57
  */
57
58
  export declare function validateRootDirectory(root: string, fsName: string): void;
59
+ export { sanitizeErrorMessage } from "./sanitize-error.js";
58
60
  /**
59
61
  * Validate that a path does not contain null bytes.
60
62
  * Null bytes in paths can be used to truncate filenames or bypass security
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Error message sanitization utility.
3
+ *
4
+ * This module has NO Node.js dependencies (no `node:fs`, etc.) so it can
5
+ * safely be imported in browser bundles.
6
+ */
7
+ /**
8
+ * Sanitize an error message to strip real OS filesystem paths and stack traces.
9
+ *
10
+ * - Replaces common OS path prefixes (/Users/, /home/, /private/, C:\, etc.)
11
+ * with `<path>` to prevent information leakage about the host filesystem.
12
+ * - Strips stack trace lines (`\n at ...`).
13
+ * - Preserves error codes (ENOENT, EACCES, etc.) and virtual paths that don't
14
+ * match known OS prefixes.
15
+ */
16
+ export declare function sanitizeErrorMessage(message: string): string;
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export type { BufferEncoding, CpOptions, DirectoryEntry, FileContent, FileEntry,
10
10
  export { MountableFs, type MountableFsOptions, type MountConfig, } from "./fs/mountable-fs/index.js";
11
11
  export { OverlayFs, type OverlayFsOptions } from "./fs/overlay-fs/index.js";
12
12
  export { ReadWriteFs, type ReadWriteFsOptions, } from "./fs/read-write-fs/index.js";
13
- export type { NetworkConfig } from "./network/index.js";
13
+ export type { NetworkConfig, SecureFetch } from "./network/index.js";
14
14
  export { NetworkAccessDeniedError, RedirectNotAllowedError, TooManyRedirectsError, } from "./network/index.js";
15
15
  export { parse } from "./parser/parser.js";
16
16
  export type { CommandFinished as SandboxCommandFinished, OutputMessage, SandboxOptions, WriteFilesInput, } from "./sandbox/index.js";
package/dist/limits.d.ts CHANGED
@@ -35,6 +35,8 @@ export interface ExecutionLimits {
35
35
  maxHeredocSize?: number;
36
36
  /** Maximum command substitution nesting depth (default: 50) */
37
37
  maxSubstitutionDepth?: number;
38
+ /** Maximum brace expansion results (default: 10000) */
39
+ maxBraceExpansionResults?: number;
38
40
  }
39
41
  /**
40
42
  * Resolve execution limits by merging user-provided limits with defaults.
@@ -9,6 +9,10 @@
9
9
  * - Here-documents
10
10
  * - Escape sequences
11
11
  */
12
+ export interface LexerOptions {
13
+ /** Maximum heredoc size in bytes (default: 10MB) */
14
+ maxHeredocSize?: number;
15
+ }
12
16
  export declare enum TokenType {
13
17
  EOF = "EOF",
14
18
  NEWLINE = "NEWLINE",
@@ -98,7 +102,8 @@ export declare class Lexer {
98
102
  private tokens;
99
103
  private pendingHeredocs;
100
104
  private dparenDepth;
101
- constructor(input: string);
105
+ private maxHeredocSize;
106
+ constructor(input: string, options?: LexerOptions);
102
107
  /**
103
108
  * Tokenize the entire input
104
109
  */
@@ -13,7 +13,7 @@
13
13
  * compound_cmd ::= if | for | while | until | case | subshell | group | (( | [[
14
14
  */
15
15
  import { type ArithmeticExpansionPart, type ArithmeticExpressionNode, type CommandSubstitutionPart, type RedirectionNode, type ScriptNode, type StatementNode, type WordNode } from "../ast/types.js";
16
- import { type Token, TokenType } from "./lexer.js";
16
+ import { type LexerOptions, type Token, TokenType } from "./lexer.js";
17
17
  export type { ParseError } from "./types.js";
18
18
  export { ParseException } from "./types.js";
19
19
  /**
@@ -43,7 +43,7 @@ export declare class Parser {
43
43
  /**
44
44
  * Parse a bash script string
45
45
  */
46
- parse(input: string): ScriptNode;
46
+ parse(input: string, options?: LexerOptions): ScriptNode;
47
47
  /**
48
48
  * Parse from pre-tokenized input
49
49
  */
@@ -132,4 +132,4 @@ export declare class Parser {
132
132
  /**
133
133
  * Convenience function to parse a bash script
134
134
  */
135
- export declare function parse(input: string): ScriptNode;
135
+ export declare function parse(input: string, options?: LexerOptions): ScriptNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "just-bash",
3
- "version": "2.11.5",
3
+ "version": "2.11.7",
4
4
  "description": "A simulated bash environment with virtual filesystem",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- import{a as C}from"./chunk-4PRVMER6.js";import{a as y,b as D}from"./chunk-GTNBSMZR.js";import"./chunk-KGOUQS5A.js";import{fileURLToPath as L}from"node:url";import{Worker as N}from"node:worker_threads";var a={NOOP:0,READ_FILE:1,WRITE_FILE:2,STAT:3,READDIR:4,MKDIR:5,RM:6,EXISTS:7,APPEND_FILE:8,SYMLINK:9,READLINK:10,LSTAT:11,CHMOD:12,REALPATH:13,WRITE_STDOUT:100,WRITE_STDERR:101,EXIT:102,HTTP_REQUEST:200},n={PENDING:0,READY:1,SUCCESS:2,ERROR:3},u={NONE:0,NOT_FOUND:1,IS_DIRECTORY:2,NOT_DIRECTORY:3,EXISTS:4,PERMISSION_DENIED:5,INVALID_PATH:6,IO_ERROR:7,TIMEOUT:8,NETWORK_ERROR:9,NETWORK_NOT_CONFIGURED:10},i={OP_CODE:0,STATUS:4,PATH_LENGTH:8,DATA_LENGTH:12,RESULT_LENGTH:16,ERROR_CODE:20,FLAGS:24,MODE:28,PATH_BUFFER:32,DATA_BUFFER:4128},p={CONTROL_REGION:32,PATH_BUFFER:4096,DATA_BUFFER:1048576,TOTAL:1052704},R={NONE:0,RECURSIVE:1,FORCE:2,MKDIR_RECURSIVE:1},h={IS_FILE:0,IS_DIRECTORY:1,IS_SYMLINK:2,MODE:4,SIZE:8,MTIME:16,TOTAL:24};function O(){return new SharedArrayBuffer(p.TOTAL)}var w=class{int32View;uint8View;dataView;constructor(t){this.int32View=new Int32Array(t),this.uint8View=new Uint8Array(t),this.dataView=new DataView(t)}getOpCode(){return Atomics.load(this.int32View,i.OP_CODE/4)}setOpCode(t){Atomics.store(this.int32View,i.OP_CODE/4,t)}getStatus(){return Atomics.load(this.int32View,i.STATUS/4)}setStatus(t){Atomics.store(this.int32View,i.STATUS/4,t)}getPathLength(){return Atomics.load(this.int32View,i.PATH_LENGTH/4)}setPathLength(t){Atomics.store(this.int32View,i.PATH_LENGTH/4,t)}getDataLength(){return Atomics.load(this.int32View,i.DATA_LENGTH/4)}setDataLength(t){Atomics.store(this.int32View,i.DATA_LENGTH/4,t)}getResultLength(){return Atomics.load(this.int32View,i.RESULT_LENGTH/4)}setResultLength(t){Atomics.store(this.int32View,i.RESULT_LENGTH/4,t)}getErrorCode(){return Atomics.load(this.int32View,i.ERROR_CODE/4)}setErrorCode(t){Atomics.store(this.int32View,i.ERROR_CODE/4,t)}getFlags(){return Atomics.load(this.int32View,i.FLAGS/4)}setFlags(t){Atomics.store(this.int32View,i.FLAGS/4,t)}getMode(){return Atomics.load(this.int32View,i.MODE/4)}setMode(t){Atomics.store(this.int32View,i.MODE/4,t)}getPath(){let t=this.getPathLength(),e=this.uint8View.slice(i.PATH_BUFFER,i.PATH_BUFFER+t);return new TextDecoder().decode(e)}setPath(t){let e=new TextEncoder().encode(t);if(e.length>p.PATH_BUFFER)throw new Error(`Path too long: ${e.length} > ${p.PATH_BUFFER}`);this.uint8View.set(e,i.PATH_BUFFER),this.setPathLength(e.length)}getData(){let t=this.getDataLength();return this.uint8View.slice(i.DATA_BUFFER,i.DATA_BUFFER+t)}setData(t){if(t.length>p.DATA_BUFFER)throw new Error(`Data too large: ${t.length} > ${p.DATA_BUFFER}`);this.uint8View.set(t,i.DATA_BUFFER),this.setDataLength(t.length)}getDataAsString(){let t=this.getData();return new TextDecoder().decode(t)}setDataFromString(t){let e=new TextEncoder().encode(t);this.setData(e)}getResult(){let t=this.getResultLength();return this.uint8View.slice(i.DATA_BUFFER,i.DATA_BUFFER+t)}setResult(t){if(t.length>p.DATA_BUFFER)throw new Error(`Result too large: ${t.length} > ${p.DATA_BUFFER}`);this.uint8View.set(t,i.DATA_BUFFER),this.setResultLength(t.length)}getResultAsString(){let t=this.getResult();return new TextDecoder().decode(t)}setResultFromString(t){let e=new TextEncoder().encode(t);this.setResult(e)}encodeStat(t){this.uint8View[i.DATA_BUFFER+h.IS_FILE]=t.isFile?1:0,this.uint8View[i.DATA_BUFFER+h.IS_DIRECTORY]=t.isDirectory?1:0,this.uint8View[i.DATA_BUFFER+h.IS_SYMLINK]=t.isSymbolicLink?1:0,this.dataView.setInt32(i.DATA_BUFFER+h.MODE,t.mode,!0);let e=Math.min(t.size,Number.MAX_SAFE_INTEGER);this.dataView.setFloat64(i.DATA_BUFFER+h.SIZE,e,!0),this.dataView.setFloat64(i.DATA_BUFFER+h.MTIME,t.mtime.getTime(),!0),this.setResultLength(h.TOTAL)}decodeStat(){return{isFile:this.uint8View[i.DATA_BUFFER+h.IS_FILE]===1,isDirectory:this.uint8View[i.DATA_BUFFER+h.IS_DIRECTORY]===1,isSymbolicLink:this.uint8View[i.DATA_BUFFER+h.IS_SYMLINK]===1,mode:this.dataView.getInt32(i.DATA_BUFFER+h.MODE,!0),size:this.dataView.getFloat64(i.DATA_BUFFER+h.SIZE,!0),mtime:new Date(this.dataView.getFloat64(i.DATA_BUFFER+h.MTIME,!0))}}waitForReady(t){return Atomics.wait(this.int32View,i.STATUS/4,n.PENDING,t)}waitForReadyAsync(t){return Atomics.waitAsync(this.int32View,i.STATUS/4,n.PENDING,t)}async waitUntilReady(t){let e=Date.now();for(;;){let s=this.getStatus();if(s===n.READY)return!0;let o=Date.now()-e;if(o>=t)return!1;let l=t-o,d=Atomics.waitAsync(this.int32View,i.STATUS/4,s,l);if(d.async&&await d.value==="timed-out")return!1}}waitForResult(t){return Atomics.wait(this.int32View,i.STATUS/4,n.READY,t)}notify(){return Atomics.notify(this.int32View,i.STATUS/4)}reset(){this.setOpCode(a.NOOP),this.setStatus(n.PENDING),this.setPathLength(0),this.setDataLength(0),this.setResultLength(0),this.setErrorCode(u.NONE),this.setFlags(R.NONE),this.setMode(0)}};var A=class{fs;cwd;secureFetch;protocol;running=!1;output={stdout:"",stderr:"",exitCode:0};constructor(t,e,s,o=void 0){this.fs=e,this.cwd=s,this.secureFetch=o,this.protocol=new w(t)}async run(t){this.running=!0;let e=Date.now();for(;this.running;){let s=Date.now()-e;if(s>=t){this.output.stderr+=`
3
- python3: execution timeout exceeded
4
- `,this.output.exitCode=124;break}let o=t-s;if(!await this.protocol.waitUntilReady(o)){this.output.stderr+=`
5
- python3: execution timeout exceeded
6
- `,this.output.exitCode=124;break}let d=this.protocol.getOpCode();await this.handleOperation(d),this.protocol.notify()}return this.output}stop(){this.running=!1}async handleOperation(t){try{switch(t){case a.READ_FILE:await this.handleReadFile();break;case a.WRITE_FILE:await this.handleWriteFile();break;case a.STAT:await this.handleStat();break;case a.LSTAT:await this.handleLstat();break;case a.READDIR:await this.handleReaddir();break;case a.MKDIR:await this.handleMkdir();break;case a.RM:await this.handleRm();break;case a.EXISTS:await this.handleExists();break;case a.APPEND_FILE:await this.handleAppendFile();break;case a.SYMLINK:await this.handleSymlink();break;case a.READLINK:await this.handleReadlink();break;case a.CHMOD:await this.handleChmod();break;case a.REALPATH:await this.handleRealpath();break;case a.WRITE_STDOUT:this.handleWriteStdout();break;case a.WRITE_STDERR:this.handleWriteStderr();break;case a.EXIT:this.handleExit();break;case a.HTTP_REQUEST:await this.handleHttpRequest();break;default:this.protocol.setErrorCode(u.IO_ERROR),this.protocol.setStatus(n.ERROR)}}catch(e){this.setErrorFromException(e)}}resolvePath(t){return t.startsWith("/mnt/host/")?t.slice(9):t.startsWith("/mnt/host")?t.slice(9)||"/":this.fs.resolvePath(this.cwd,t)}async handleReadFile(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readFileBuffer(t);this.protocol.setResult(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleWriteFile(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getData();try{await this.fs.writeFile(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleStat(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.stat(t);this.protocol.encodeStat(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleLstat(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.lstat(t);this.protocol.encodeStat(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleReaddir(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readdir(t);this.protocol.setResultFromString(JSON.stringify(e)),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleMkdir(){let t=this.resolvePath(this.protocol.getPath()),s=(this.protocol.getFlags()&R.MKDIR_RECURSIVE)!==0;try{await this.fs.mkdir(t,{recursive:s}),this.protocol.setStatus(n.SUCCESS)}catch(o){this.setErrorFromException(o)}}async handleRm(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getFlags(),s=(e&R.RECURSIVE)!==0,o=(e&R.FORCE)!==0;try{await this.fs.rm(t,{recursive:s,force:o}),this.protocol.setStatus(n.SUCCESS)}catch(l){this.setErrorFromException(l)}}async handleExists(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.exists(t);this.protocol.setResult(new Uint8Array([e?1:0])),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleAppendFile(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getData();try{await this.fs.appendFile(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleSymlink(){let t=this.protocol.getPath(),e=this.protocol.getDataAsString(),s=this.resolvePath(t);try{await this.fs.symlink(e,s),this.protocol.setStatus(n.SUCCESS)}catch(o){this.setErrorFromException(o)}}async handleReadlink(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readlink(t);this.protocol.setResultFromString(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleChmod(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getMode();try{await this.fs.chmod(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleRealpath(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.realpath(t);this.protocol.setResultFromString(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}handleWriteStdout(){let t=this.protocol.getDataAsString();this.output.stdout+=t,this.protocol.setStatus(n.SUCCESS)}handleWriteStderr(){let t=this.protocol.getDataAsString();this.output.stderr+=t,this.protocol.setStatus(n.SUCCESS)}handleExit(){let t=this.protocol.getFlags();this.output.exitCode=t,this.protocol.setStatus(n.SUCCESS),this.running=!1}async handleHttpRequest(){if(!this.secureFetch){this.protocol.setErrorCode(u.NETWORK_NOT_CONFIGURED),this.protocol.setResultFromString("Network access not configured. Enable network in Bash options."),this.protocol.setStatus(n.ERROR);return}let t=this.protocol.getPath(),e=this.protocol.getDataAsString();try{let s=e?JSON.parse(e):{},o=await this.secureFetch(t,{method:s.method,headers:s.headers,body:s.body}),l=JSON.stringify({status:o.status,statusText:o.statusText,headers:o.headers,body:o.body,url:o.url});this.protocol.setResultFromString(l),this.protocol.setStatus(n.SUCCESS)}catch(s){let o=s instanceof Error?s.message:String(s);this.protocol.setErrorCode(u.NETWORK_ERROR),this.protocol.setResultFromString(o),this.protocol.setStatus(n.ERROR)}}setErrorFromException(t){let e=t instanceof Error?t.message:String(t),s=u.IO_ERROR,o=e.toLowerCase();o.includes("no such file")||o.includes("not found")||o.includes("enoent")?s=u.NOT_FOUND:o.includes("is a directory")||o.includes("eisdir")?s=u.IS_DIRECTORY:o.includes("not a directory")||o.includes("enotdir")?s=u.NOT_DIRECTORY:o.includes("already exists")||o.includes("eexist")?s=u.EXISTS:(o.includes("permission")||o.includes("eperm")||o.includes("eacces"))&&(s=u.PERMISSION_DENIED),this.protocol.setErrorCode(s),this.protocol.setResultFromString(e),this.protocol.setStatus(n.ERROR)}};var V=3e4,k={name:"python3",summary:"Execute Python code via Pyodide",usage:"python3 [OPTIONS] [-c CODE | -m MODULE | FILE] [ARGS...]",description:["Execute Python code using Pyodide (Python compiled to WebAssembly).","","This command runs Python in a sandboxed environment with access to","the virtual filesystem. Only Pyodide-bundled packages are available."],options:["-c CODE Execute CODE as Python script","-m MODULE Run library module as a script","--version Show Python version","--help Show this help"],examples:['python3 -c "print(1 + 2)"','python3 -c "import sys; print(sys.version)"',"python3 script.py","python3 script.py arg1 arg2",`echo 'print("hello")' | python3`],notes:["Pyodide runs in WebAssembly, so execution may be slower than native Python.","Only packages bundled with Pyodide are available (no pip install).","First execution loads Pyodide (~30MB), subsequent calls are faster.","Maximum execution time is 30 seconds by default."]};function M(r){let t={code:null,module:null,scriptFile:null,showVersion:!1,scriptArgs:[]};if(r.length===0)return t;let e=r.findIndex(s=>!s.startsWith("-")||s==="-"||s==="--");for(let s=0;s<(e===-1?r.length:e);s++){let o=r[s];if(o==="-c")return s+1>=r.length?{stdout:"",stderr:`python3: option requires an argument -- 'c'
7
- `,exitCode:2}:(t.code=r[s+1],t.scriptArgs=r.slice(s+2),t);if(o==="-m")return s+1>=r.length?{stdout:"",stderr:`python3: option requires an argument -- 'm'
8
- `,exitCode:2}:(t.module=r[s+1],t.scriptArgs=r.slice(s+2),t);if(o==="--version"||o==="-V")return t.showVersion=!0,t;if(o.startsWith("-")&&o!=="-")return{stdout:"",stderr:`python3: unrecognized option '${o}'
9
- `,exitCode:2}}if(e!==-1){let s=r[e];s==="--"?e+1<r.length&&(t.scriptFile=r[e+1],t.scriptArgs=r.slice(e+2)):(t.scriptFile=s,t.scriptArgs=r.slice(e+1))}return t}var c=null,F=null,S=[],E=null,b=L(new URL("./worker.js",import.meta.url));function _(){if(E||S.length===0)return;let r=S.shift();if(!r)return;E=r,B().postMessage(E.input)}function B(){return F&&(clearTimeout(F),F=null),c||(c=new N(b),c.on("message",r=>{E&&(E.resolve(r),E=null),S.length>0?_():v()}),c.on("error",r=>{E&&(E.resolve({success:!1,error:r.message}),E=null);for(let t of S)t.resolve({success:!1,error:"Worker crashed"});S.length=0,c=null}),c.on("exit",()=>{c=null}),c)}function v(){F=setTimeout(()=>{c&&!E&&S.length===0&&(c.terminate(),c=null)},5e3)}async function H(r,t,e,s=[]){let o=O(),l=new A(o,t.fs,t.cwd,t.fetch),d=t.limits?.maxPythonTimeoutMs??V,f={sharedBuffer:o,pythonCode:r,cwd:t.cwd,env:C(t.env),args:s,scriptPath:e},P=new Promise(T=>{let I=setTimeout(()=>{T({success:!1,error:`Execution timeout: exceeded ${d}ms limit`})},d),U=x=>{clearTimeout(I),T(x)};S.push({input:f,resolve:U}),_()}),[m,g]=await Promise.all([l.run(d),P.catch(T=>({success:!1,error:T.message}))]);return!g.success&&g.error?{stdout:m.stdout,stderr:`${m.stderr}python3: ${g.error}
10
- `,exitCode:m.exitCode||1}:m}var W={name:"python3",async execute(r,t){if(D(r))return y(k);let e=M(r);if("exitCode"in e)return e;if(e.showVersion)return{stdout:`Python 3.12.1 (Pyodide)
11
- `,stderr:"",exitCode:0};let s,o;if(e.code!==null)s=e.code,o="-c";else if(e.module!==null)s=`import runpy; runpy.run_module('${e.module}', run_name='__main__')`,o=e.module;else if(e.scriptFile!==null){let l=t.fs.resolvePath(t.cwd,e.scriptFile);if(!await t.fs.exists(l))return{stdout:"",stderr:`python3: can't open file '${e.scriptFile}': [Errno 2] No such file or directory
12
- `,exitCode:2};try{s=await t.fs.readFile(l),o=e.scriptFile}catch(d){return{stdout:"",stderr:`python3: can't open file '${e.scriptFile}': ${d.message}
13
- `,exitCode:2}}}else if(t.stdin.trim())s=t.stdin,o="<stdin>";else return{stdout:"",stderr:`python3: no input provided (use -c CODE, -m MODULE, or provide a script file)
14
- `,exitCode:2};return H(s,t,o,e.scriptArgs)}},Z={name:"python",async execute(r,t){return W.execute(r,t)}};export{W as python3Command,Z as pythonCommand};
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- import{a as C}from"./chunk-4PRVMER6.js";import{a as y,b as D}from"./chunk-GTNBSMZR.js";import"./chunk-KGOUQS5A.js";import{fileURLToPath as L}from"node:url";import{Worker as N}from"node:worker_threads";var a={NOOP:0,READ_FILE:1,WRITE_FILE:2,STAT:3,READDIR:4,MKDIR:5,RM:6,EXISTS:7,APPEND_FILE:8,SYMLINK:9,READLINK:10,LSTAT:11,CHMOD:12,REALPATH:13,WRITE_STDOUT:100,WRITE_STDERR:101,EXIT:102,HTTP_REQUEST:200},n={PENDING:0,READY:1,SUCCESS:2,ERROR:3},u={NONE:0,NOT_FOUND:1,IS_DIRECTORY:2,NOT_DIRECTORY:3,EXISTS:4,PERMISSION_DENIED:5,INVALID_PATH:6,IO_ERROR:7,TIMEOUT:8,NETWORK_ERROR:9,NETWORK_NOT_CONFIGURED:10},i={OP_CODE:0,STATUS:4,PATH_LENGTH:8,DATA_LENGTH:12,RESULT_LENGTH:16,ERROR_CODE:20,FLAGS:24,MODE:28,PATH_BUFFER:32,DATA_BUFFER:4128},p={CONTROL_REGION:32,PATH_BUFFER:4096,DATA_BUFFER:1048576,TOTAL:1052704},R={NONE:0,RECURSIVE:1,FORCE:2,MKDIR_RECURSIVE:1},h={IS_FILE:0,IS_DIRECTORY:1,IS_SYMLINK:2,MODE:4,SIZE:8,MTIME:16,TOTAL:24};function O(){return new SharedArrayBuffer(p.TOTAL)}var w=class{int32View;uint8View;dataView;constructor(t){this.int32View=new Int32Array(t),this.uint8View=new Uint8Array(t),this.dataView=new DataView(t)}getOpCode(){return Atomics.load(this.int32View,i.OP_CODE/4)}setOpCode(t){Atomics.store(this.int32View,i.OP_CODE/4,t)}getStatus(){return Atomics.load(this.int32View,i.STATUS/4)}setStatus(t){Atomics.store(this.int32View,i.STATUS/4,t)}getPathLength(){return Atomics.load(this.int32View,i.PATH_LENGTH/4)}setPathLength(t){Atomics.store(this.int32View,i.PATH_LENGTH/4,t)}getDataLength(){return Atomics.load(this.int32View,i.DATA_LENGTH/4)}setDataLength(t){Atomics.store(this.int32View,i.DATA_LENGTH/4,t)}getResultLength(){return Atomics.load(this.int32View,i.RESULT_LENGTH/4)}setResultLength(t){Atomics.store(this.int32View,i.RESULT_LENGTH/4,t)}getErrorCode(){return Atomics.load(this.int32View,i.ERROR_CODE/4)}setErrorCode(t){Atomics.store(this.int32View,i.ERROR_CODE/4,t)}getFlags(){return Atomics.load(this.int32View,i.FLAGS/4)}setFlags(t){Atomics.store(this.int32View,i.FLAGS/4,t)}getMode(){return Atomics.load(this.int32View,i.MODE/4)}setMode(t){Atomics.store(this.int32View,i.MODE/4,t)}getPath(){let t=this.getPathLength(),e=this.uint8View.slice(i.PATH_BUFFER,i.PATH_BUFFER+t);return new TextDecoder().decode(e)}setPath(t){let e=new TextEncoder().encode(t);if(e.length>p.PATH_BUFFER)throw new Error(`Path too long: ${e.length} > ${p.PATH_BUFFER}`);this.uint8View.set(e,i.PATH_BUFFER),this.setPathLength(e.length)}getData(){let t=this.getDataLength();return this.uint8View.slice(i.DATA_BUFFER,i.DATA_BUFFER+t)}setData(t){if(t.length>p.DATA_BUFFER)throw new Error(`Data too large: ${t.length} > ${p.DATA_BUFFER}`);this.uint8View.set(t,i.DATA_BUFFER),this.setDataLength(t.length)}getDataAsString(){let t=this.getData();return new TextDecoder().decode(t)}setDataFromString(t){let e=new TextEncoder().encode(t);this.setData(e)}getResult(){let t=this.getResultLength();return this.uint8View.slice(i.DATA_BUFFER,i.DATA_BUFFER+t)}setResult(t){if(t.length>p.DATA_BUFFER)throw new Error(`Result too large: ${t.length} > ${p.DATA_BUFFER}`);this.uint8View.set(t,i.DATA_BUFFER),this.setResultLength(t.length)}getResultAsString(){let t=this.getResult();return new TextDecoder().decode(t)}setResultFromString(t){let e=new TextEncoder().encode(t);this.setResult(e)}encodeStat(t){this.uint8View[i.DATA_BUFFER+h.IS_FILE]=t.isFile?1:0,this.uint8View[i.DATA_BUFFER+h.IS_DIRECTORY]=t.isDirectory?1:0,this.uint8View[i.DATA_BUFFER+h.IS_SYMLINK]=t.isSymbolicLink?1:0,this.dataView.setInt32(i.DATA_BUFFER+h.MODE,t.mode,!0);let e=Math.min(t.size,Number.MAX_SAFE_INTEGER);this.dataView.setFloat64(i.DATA_BUFFER+h.SIZE,e,!0),this.dataView.setFloat64(i.DATA_BUFFER+h.MTIME,t.mtime.getTime(),!0),this.setResultLength(h.TOTAL)}decodeStat(){return{isFile:this.uint8View[i.DATA_BUFFER+h.IS_FILE]===1,isDirectory:this.uint8View[i.DATA_BUFFER+h.IS_DIRECTORY]===1,isSymbolicLink:this.uint8View[i.DATA_BUFFER+h.IS_SYMLINK]===1,mode:this.dataView.getInt32(i.DATA_BUFFER+h.MODE,!0),size:this.dataView.getFloat64(i.DATA_BUFFER+h.SIZE,!0),mtime:new Date(this.dataView.getFloat64(i.DATA_BUFFER+h.MTIME,!0))}}waitForReady(t){return Atomics.wait(this.int32View,i.STATUS/4,n.PENDING,t)}waitForReadyAsync(t){return Atomics.waitAsync(this.int32View,i.STATUS/4,n.PENDING,t)}async waitUntilReady(t){let e=Date.now();for(;;){let s=this.getStatus();if(s===n.READY)return!0;let o=Date.now()-e;if(o>=t)return!1;let l=t-o,d=Atomics.waitAsync(this.int32View,i.STATUS/4,s,l);if(d.async&&await d.value==="timed-out")return!1}}waitForResult(t){return Atomics.wait(this.int32View,i.STATUS/4,n.READY,t)}notify(){return Atomics.notify(this.int32View,i.STATUS/4)}reset(){this.setOpCode(a.NOOP),this.setStatus(n.PENDING),this.setPathLength(0),this.setDataLength(0),this.setResultLength(0),this.setErrorCode(u.NONE),this.setFlags(R.NONE),this.setMode(0)}};var A=class{fs;cwd;secureFetch;protocol;running=!1;output={stdout:"",stderr:"",exitCode:0};constructor(t,e,s,o=void 0){this.fs=e,this.cwd=s,this.secureFetch=o,this.protocol=new w(t)}async run(t){this.running=!0;let e=Date.now();for(;this.running;){let s=Date.now()-e;if(s>=t){this.output.stderr+=`
3
- python3: execution timeout exceeded
4
- `,this.output.exitCode=124;break}let o=t-s;if(!await this.protocol.waitUntilReady(o)){this.output.stderr+=`
5
- python3: execution timeout exceeded
6
- `,this.output.exitCode=124;break}let d=this.protocol.getOpCode();await this.handleOperation(d),this.protocol.notify()}return this.output}stop(){this.running=!1}async handleOperation(t){try{switch(t){case a.READ_FILE:await this.handleReadFile();break;case a.WRITE_FILE:await this.handleWriteFile();break;case a.STAT:await this.handleStat();break;case a.LSTAT:await this.handleLstat();break;case a.READDIR:await this.handleReaddir();break;case a.MKDIR:await this.handleMkdir();break;case a.RM:await this.handleRm();break;case a.EXISTS:await this.handleExists();break;case a.APPEND_FILE:await this.handleAppendFile();break;case a.SYMLINK:await this.handleSymlink();break;case a.READLINK:await this.handleReadlink();break;case a.CHMOD:await this.handleChmod();break;case a.REALPATH:await this.handleRealpath();break;case a.WRITE_STDOUT:this.handleWriteStdout();break;case a.WRITE_STDERR:this.handleWriteStderr();break;case a.EXIT:this.handleExit();break;case a.HTTP_REQUEST:await this.handleHttpRequest();break;default:this.protocol.setErrorCode(u.IO_ERROR),this.protocol.setStatus(n.ERROR)}}catch(e){this.setErrorFromException(e)}}resolvePath(t){return t.startsWith("/mnt/host/")?t.slice(9):t.startsWith("/mnt/host")?t.slice(9)||"/":this.fs.resolvePath(this.cwd,t)}async handleReadFile(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readFileBuffer(t);this.protocol.setResult(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleWriteFile(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getData();try{await this.fs.writeFile(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleStat(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.stat(t);this.protocol.encodeStat(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleLstat(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.lstat(t);this.protocol.encodeStat(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleReaddir(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readdir(t);this.protocol.setResultFromString(JSON.stringify(e)),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleMkdir(){let t=this.resolvePath(this.protocol.getPath()),s=(this.protocol.getFlags()&R.MKDIR_RECURSIVE)!==0;try{await this.fs.mkdir(t,{recursive:s}),this.protocol.setStatus(n.SUCCESS)}catch(o){this.setErrorFromException(o)}}async handleRm(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getFlags(),s=(e&R.RECURSIVE)!==0,o=(e&R.FORCE)!==0;try{await this.fs.rm(t,{recursive:s,force:o}),this.protocol.setStatus(n.SUCCESS)}catch(l){this.setErrorFromException(l)}}async handleExists(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.exists(t);this.protocol.setResult(new Uint8Array([e?1:0])),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleAppendFile(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getData();try{await this.fs.appendFile(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleSymlink(){let t=this.protocol.getPath(),e=this.protocol.getDataAsString(),s=this.resolvePath(t);try{await this.fs.symlink(e,s),this.protocol.setStatus(n.SUCCESS)}catch(o){this.setErrorFromException(o)}}async handleReadlink(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readlink(t);this.protocol.setResultFromString(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleChmod(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getMode();try{await this.fs.chmod(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleRealpath(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.realpath(t);this.protocol.setResultFromString(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}handleWriteStdout(){let t=this.protocol.getDataAsString();this.output.stdout+=t,this.protocol.setStatus(n.SUCCESS)}handleWriteStderr(){let t=this.protocol.getDataAsString();this.output.stderr+=t,this.protocol.setStatus(n.SUCCESS)}handleExit(){let t=this.protocol.getFlags();this.output.exitCode=t,this.protocol.setStatus(n.SUCCESS),this.running=!1}async handleHttpRequest(){if(!this.secureFetch){this.protocol.setErrorCode(u.NETWORK_NOT_CONFIGURED),this.protocol.setResultFromString("Network access not configured. Enable network in Bash options."),this.protocol.setStatus(n.ERROR);return}let t=this.protocol.getPath(),e=this.protocol.getDataAsString();try{let s=e?JSON.parse(e):{},o=await this.secureFetch(t,{method:s.method,headers:s.headers,body:s.body}),l=JSON.stringify({status:o.status,statusText:o.statusText,headers:o.headers,body:o.body,url:o.url});this.protocol.setResultFromString(l),this.protocol.setStatus(n.SUCCESS)}catch(s){let o=s instanceof Error?s.message:String(s);this.protocol.setErrorCode(u.NETWORK_ERROR),this.protocol.setResultFromString(o),this.protocol.setStatus(n.ERROR)}}setErrorFromException(t){let e=t instanceof Error?t.message:String(t),s=u.IO_ERROR,o=e.toLowerCase();o.includes("no such file")||o.includes("not found")||o.includes("enoent")?s=u.NOT_FOUND:o.includes("is a directory")||o.includes("eisdir")?s=u.IS_DIRECTORY:o.includes("not a directory")||o.includes("enotdir")?s=u.NOT_DIRECTORY:o.includes("already exists")||o.includes("eexist")?s=u.EXISTS:(o.includes("permission")||o.includes("eperm")||o.includes("eacces"))&&(s=u.PERMISSION_DENIED),this.protocol.setErrorCode(s),this.protocol.setResultFromString(e),this.protocol.setStatus(n.ERROR)}};var V=3e4,k={name:"python3",summary:"Execute Python code via Pyodide",usage:"python3 [OPTIONS] [-c CODE | -m MODULE | FILE] [ARGS...]",description:["Execute Python code using Pyodide (Python compiled to WebAssembly).","","This command runs Python in a sandboxed environment with access to","the virtual filesystem. Only Pyodide-bundled packages are available."],options:["-c CODE Execute CODE as Python script","-m MODULE Run library module as a script","--version Show Python version","--help Show this help"],examples:['python3 -c "print(1 + 2)"','python3 -c "import sys; print(sys.version)"',"python3 script.py","python3 script.py arg1 arg2",`echo 'print("hello")' | python3`],notes:["Pyodide runs in WebAssembly, so execution may be slower than native Python.","Only packages bundled with Pyodide are available (no pip install).","First execution loads Pyodide (~30MB), subsequent calls are faster.","Maximum execution time is 30 seconds by default."]};function M(r){let t={code:null,module:null,scriptFile:null,showVersion:!1,scriptArgs:[]};if(r.length===0)return t;let e=r.findIndex(s=>!s.startsWith("-")||s==="-"||s==="--");for(let s=0;s<(e===-1?r.length:e);s++){let o=r[s];if(o==="-c")return s+1>=r.length?{stdout:"",stderr:`python3: option requires an argument -- 'c'
7
- `,exitCode:2}:(t.code=r[s+1],t.scriptArgs=r.slice(s+2),t);if(o==="-m")return s+1>=r.length?{stdout:"",stderr:`python3: option requires an argument -- 'm'
8
- `,exitCode:2}:(t.module=r[s+1],t.scriptArgs=r.slice(s+2),t);if(o==="--version"||o==="-V")return t.showVersion=!0,t;if(o.startsWith("-")&&o!=="-")return{stdout:"",stderr:`python3: unrecognized option '${o}'
9
- `,exitCode:2}}if(e!==-1){let s=r[e];s==="--"?e+1<r.length&&(t.scriptFile=r[e+1],t.scriptArgs=r.slice(e+2)):(t.scriptFile=s,t.scriptArgs=r.slice(e+1))}return t}var c=null,F=null,S=[],E=null,b=L(new URL("./worker.js",import.meta.url));function _(){if(E||S.length===0)return;let r=S.shift();if(!r)return;E=r,B().postMessage(E.input)}function B(){return F&&(clearTimeout(F),F=null),c||(c=new N(b),c.on("message",r=>{E&&(E.resolve(r),E=null),S.length>0?_():v()}),c.on("error",r=>{E&&(E.resolve({success:!1,error:r.message}),E=null);for(let t of S)t.resolve({success:!1,error:"Worker crashed"});S.length=0,c=null}),c.on("exit",()=>{c=null}),c)}function v(){F=setTimeout(()=>{c&&!E&&S.length===0&&(c.terminate(),c=null)},5e3)}async function H(r,t,e,s=[]){let o=O(),l=new A(o,t.fs,t.cwd,t.fetch),d=t.limits?.maxPythonTimeoutMs??V,f={sharedBuffer:o,pythonCode:r,cwd:t.cwd,env:C(t.env),args:s,scriptPath:e},P=new Promise(T=>{let I=setTimeout(()=>{T({success:!1,error:`Execution timeout: exceeded ${d}ms limit`})},d),U=x=>{clearTimeout(I),T(x)};S.push({input:f,resolve:U}),_()}),[m,g]=await Promise.all([l.run(d),P.catch(T=>({success:!1,error:T.message}))]);return!g.success&&g.error?{stdout:m.stdout,stderr:`${m.stderr}python3: ${g.error}
10
- `,exitCode:m.exitCode||1}:m}var W={name:"python3",async execute(r,t){if(D(r))return y(k);let e=M(r);if("exitCode"in e)return e;if(e.showVersion)return{stdout:`Python 3.12.1 (Pyodide)
11
- `,stderr:"",exitCode:0};let s,o;if(e.code!==null)s=e.code,o="-c";else if(e.module!==null)s=`import runpy; runpy.run_module('${e.module}', run_name='__main__')`,o=e.module;else if(e.scriptFile!==null){let l=t.fs.resolvePath(t.cwd,e.scriptFile);if(!await t.fs.exists(l))return{stdout:"",stderr:`python3: can't open file '${e.scriptFile}': [Errno 2] No such file or directory
12
- `,exitCode:2};try{s=await t.fs.readFile(l),o=e.scriptFile}catch(d){return{stdout:"",stderr:`python3: can't open file '${e.scriptFile}': ${d.message}
13
- `,exitCode:2}}}else if(t.stdin.trim())s=t.stdin,o="<stdin>";else return{stdout:"",stderr:`python3: no input provided (use -c CODE, -m MODULE, or provide a script file)
14
- `,exitCode:2};return H(s,t,o,e.scriptArgs)}},Z={name:"python",async execute(r,t){return W.execute(r,t)}};export{W as python3Command,Z as pythonCommand};
@@ -1,13 +0,0 @@
1
- import{a as C}from"./chunk-OJDRYQWQ.js";import{a as y,b as D}from"./chunk-74CEPOFO.js";import"./chunk-DXB73IDG.js";import{fileURLToPath as L}from"node:url";import{Worker as N}from"node:worker_threads";var a={NOOP:0,READ_FILE:1,WRITE_FILE:2,STAT:3,READDIR:4,MKDIR:5,RM:6,EXISTS:7,APPEND_FILE:8,SYMLINK:9,READLINK:10,LSTAT:11,CHMOD:12,REALPATH:13,WRITE_STDOUT:100,WRITE_STDERR:101,EXIT:102,HTTP_REQUEST:200},n={PENDING:0,READY:1,SUCCESS:2,ERROR:3},u={NONE:0,NOT_FOUND:1,IS_DIRECTORY:2,NOT_DIRECTORY:3,EXISTS:4,PERMISSION_DENIED:5,INVALID_PATH:6,IO_ERROR:7,TIMEOUT:8,NETWORK_ERROR:9,NETWORK_NOT_CONFIGURED:10},i={OP_CODE:0,STATUS:4,PATH_LENGTH:8,DATA_LENGTH:12,RESULT_LENGTH:16,ERROR_CODE:20,FLAGS:24,MODE:28,PATH_BUFFER:32,DATA_BUFFER:4128},p={CONTROL_REGION:32,PATH_BUFFER:4096,DATA_BUFFER:1048576,TOTAL:1052704},R={NONE:0,RECURSIVE:1,FORCE:2,MKDIR_RECURSIVE:1},h={IS_FILE:0,IS_DIRECTORY:1,IS_SYMLINK:2,MODE:4,SIZE:8,MTIME:16,TOTAL:24};function O(){return new SharedArrayBuffer(p.TOTAL)}var w=class{int32View;uint8View;dataView;constructor(t){this.int32View=new Int32Array(t),this.uint8View=new Uint8Array(t),this.dataView=new DataView(t)}getOpCode(){return Atomics.load(this.int32View,i.OP_CODE/4)}setOpCode(t){Atomics.store(this.int32View,i.OP_CODE/4,t)}getStatus(){return Atomics.load(this.int32View,i.STATUS/4)}setStatus(t){Atomics.store(this.int32View,i.STATUS/4,t)}getPathLength(){return Atomics.load(this.int32View,i.PATH_LENGTH/4)}setPathLength(t){Atomics.store(this.int32View,i.PATH_LENGTH/4,t)}getDataLength(){return Atomics.load(this.int32View,i.DATA_LENGTH/4)}setDataLength(t){Atomics.store(this.int32View,i.DATA_LENGTH/4,t)}getResultLength(){return Atomics.load(this.int32View,i.RESULT_LENGTH/4)}setResultLength(t){Atomics.store(this.int32View,i.RESULT_LENGTH/4,t)}getErrorCode(){return Atomics.load(this.int32View,i.ERROR_CODE/4)}setErrorCode(t){Atomics.store(this.int32View,i.ERROR_CODE/4,t)}getFlags(){return Atomics.load(this.int32View,i.FLAGS/4)}setFlags(t){Atomics.store(this.int32View,i.FLAGS/4,t)}getMode(){return Atomics.load(this.int32View,i.MODE/4)}setMode(t){Atomics.store(this.int32View,i.MODE/4,t)}getPath(){let t=this.getPathLength(),e=this.uint8View.slice(i.PATH_BUFFER,i.PATH_BUFFER+t);return new TextDecoder().decode(e)}setPath(t){let e=new TextEncoder().encode(t);if(e.length>p.PATH_BUFFER)throw new Error(`Path too long: ${e.length} > ${p.PATH_BUFFER}`);this.uint8View.set(e,i.PATH_BUFFER),this.setPathLength(e.length)}getData(){let t=this.getDataLength();return this.uint8View.slice(i.DATA_BUFFER,i.DATA_BUFFER+t)}setData(t){if(t.length>p.DATA_BUFFER)throw new Error(`Data too large: ${t.length} > ${p.DATA_BUFFER}`);this.uint8View.set(t,i.DATA_BUFFER),this.setDataLength(t.length)}getDataAsString(){let t=this.getData();return new TextDecoder().decode(t)}setDataFromString(t){let e=new TextEncoder().encode(t);this.setData(e)}getResult(){let t=this.getResultLength();return this.uint8View.slice(i.DATA_BUFFER,i.DATA_BUFFER+t)}setResult(t){if(t.length>p.DATA_BUFFER)throw new Error(`Result too large: ${t.length} > ${p.DATA_BUFFER}`);this.uint8View.set(t,i.DATA_BUFFER),this.setResultLength(t.length)}getResultAsString(){let t=this.getResult();return new TextDecoder().decode(t)}setResultFromString(t){let e=new TextEncoder().encode(t);this.setResult(e)}encodeStat(t){this.uint8View[i.DATA_BUFFER+h.IS_FILE]=t.isFile?1:0,this.uint8View[i.DATA_BUFFER+h.IS_DIRECTORY]=t.isDirectory?1:0,this.uint8View[i.DATA_BUFFER+h.IS_SYMLINK]=t.isSymbolicLink?1:0,this.dataView.setInt32(i.DATA_BUFFER+h.MODE,t.mode,!0);let e=Math.min(t.size,Number.MAX_SAFE_INTEGER);this.dataView.setFloat64(i.DATA_BUFFER+h.SIZE,e,!0),this.dataView.setFloat64(i.DATA_BUFFER+h.MTIME,t.mtime.getTime(),!0),this.setResultLength(h.TOTAL)}decodeStat(){return{isFile:this.uint8View[i.DATA_BUFFER+h.IS_FILE]===1,isDirectory:this.uint8View[i.DATA_BUFFER+h.IS_DIRECTORY]===1,isSymbolicLink:this.uint8View[i.DATA_BUFFER+h.IS_SYMLINK]===1,mode:this.dataView.getInt32(i.DATA_BUFFER+h.MODE,!0),size:this.dataView.getFloat64(i.DATA_BUFFER+h.SIZE,!0),mtime:new Date(this.dataView.getFloat64(i.DATA_BUFFER+h.MTIME,!0))}}waitForReady(t){return Atomics.wait(this.int32View,i.STATUS/4,n.PENDING,t)}waitForReadyAsync(t){return Atomics.waitAsync(this.int32View,i.STATUS/4,n.PENDING,t)}async waitUntilReady(t){let e=Date.now();for(;;){let s=this.getStatus();if(s===n.READY)return!0;let o=Date.now()-e;if(o>=t)return!1;let l=t-o,d=Atomics.waitAsync(this.int32View,i.STATUS/4,s,l);if(d.async&&await d.value==="timed-out")return!1}}waitForResult(t){return Atomics.wait(this.int32View,i.STATUS/4,n.READY,t)}notify(){return Atomics.notify(this.int32View,i.STATUS/4)}reset(){this.setOpCode(a.NOOP),this.setStatus(n.PENDING),this.setPathLength(0),this.setDataLength(0),this.setResultLength(0),this.setErrorCode(u.NONE),this.setFlags(R.NONE),this.setMode(0)}};var A=class{fs;cwd;secureFetch;protocol;running=!1;output={stdout:"",stderr:"",exitCode:0};constructor(t,e,s,o=void 0){this.fs=e,this.cwd=s,this.secureFetch=o,this.protocol=new w(t)}async run(t){this.running=!0;let e=Date.now();for(;this.running;){let s=Date.now()-e;if(s>=t){this.output.stderr+=`
2
- python3: execution timeout exceeded
3
- `,this.output.exitCode=124;break}let o=t-s;if(!await this.protocol.waitUntilReady(o)){this.output.stderr+=`
4
- python3: execution timeout exceeded
5
- `,this.output.exitCode=124;break}let d=this.protocol.getOpCode();await this.handleOperation(d),this.protocol.notify()}return this.output}stop(){this.running=!1}async handleOperation(t){try{switch(t){case a.READ_FILE:await this.handleReadFile();break;case a.WRITE_FILE:await this.handleWriteFile();break;case a.STAT:await this.handleStat();break;case a.LSTAT:await this.handleLstat();break;case a.READDIR:await this.handleReaddir();break;case a.MKDIR:await this.handleMkdir();break;case a.RM:await this.handleRm();break;case a.EXISTS:await this.handleExists();break;case a.APPEND_FILE:await this.handleAppendFile();break;case a.SYMLINK:await this.handleSymlink();break;case a.READLINK:await this.handleReadlink();break;case a.CHMOD:await this.handleChmod();break;case a.REALPATH:await this.handleRealpath();break;case a.WRITE_STDOUT:this.handleWriteStdout();break;case a.WRITE_STDERR:this.handleWriteStderr();break;case a.EXIT:this.handleExit();break;case a.HTTP_REQUEST:await this.handleHttpRequest();break;default:this.protocol.setErrorCode(u.IO_ERROR),this.protocol.setStatus(n.ERROR)}}catch(e){this.setErrorFromException(e)}}resolvePath(t){return t.startsWith("/mnt/host/")?t.slice(9):t.startsWith("/mnt/host")?t.slice(9)||"/":this.fs.resolvePath(this.cwd,t)}async handleReadFile(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readFileBuffer(t);this.protocol.setResult(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleWriteFile(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getData();try{await this.fs.writeFile(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleStat(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.stat(t);this.protocol.encodeStat(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleLstat(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.lstat(t);this.protocol.encodeStat(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleReaddir(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readdir(t);this.protocol.setResultFromString(JSON.stringify(e)),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleMkdir(){let t=this.resolvePath(this.protocol.getPath()),s=(this.protocol.getFlags()&R.MKDIR_RECURSIVE)!==0;try{await this.fs.mkdir(t,{recursive:s}),this.protocol.setStatus(n.SUCCESS)}catch(o){this.setErrorFromException(o)}}async handleRm(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getFlags(),s=(e&R.RECURSIVE)!==0,o=(e&R.FORCE)!==0;try{await this.fs.rm(t,{recursive:s,force:o}),this.protocol.setStatus(n.SUCCESS)}catch(l){this.setErrorFromException(l)}}async handleExists(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.exists(t);this.protocol.setResult(new Uint8Array([e?1:0])),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleAppendFile(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getData();try{await this.fs.appendFile(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleSymlink(){let t=this.protocol.getPath(),e=this.protocol.getDataAsString(),s=this.resolvePath(t);try{await this.fs.symlink(e,s),this.protocol.setStatus(n.SUCCESS)}catch(o){this.setErrorFromException(o)}}async handleReadlink(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readlink(t);this.protocol.setResultFromString(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleChmod(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getMode();try{await this.fs.chmod(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleRealpath(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.realpath(t);this.protocol.setResultFromString(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}handleWriteStdout(){let t=this.protocol.getDataAsString();this.output.stdout+=t,this.protocol.setStatus(n.SUCCESS)}handleWriteStderr(){let t=this.protocol.getDataAsString();this.output.stderr+=t,this.protocol.setStatus(n.SUCCESS)}handleExit(){let t=this.protocol.getFlags();this.output.exitCode=t,this.protocol.setStatus(n.SUCCESS),this.running=!1}async handleHttpRequest(){if(!this.secureFetch){this.protocol.setErrorCode(u.NETWORK_NOT_CONFIGURED),this.protocol.setResultFromString("Network access not configured. Enable network in Bash options."),this.protocol.setStatus(n.ERROR);return}let t=this.protocol.getPath(),e=this.protocol.getDataAsString();try{let s=e?JSON.parse(e):{},o=await this.secureFetch(t,{method:s.method,headers:s.headers,body:s.body}),l=JSON.stringify({status:o.status,statusText:o.statusText,headers:o.headers,body:o.body,url:o.url});this.protocol.setResultFromString(l),this.protocol.setStatus(n.SUCCESS)}catch(s){let o=s instanceof Error?s.message:String(s);this.protocol.setErrorCode(u.NETWORK_ERROR),this.protocol.setResultFromString(o),this.protocol.setStatus(n.ERROR)}}setErrorFromException(t){let e=t instanceof Error?t.message:String(t),s=u.IO_ERROR,o=e.toLowerCase();o.includes("no such file")||o.includes("not found")||o.includes("enoent")?s=u.NOT_FOUND:o.includes("is a directory")||o.includes("eisdir")?s=u.IS_DIRECTORY:o.includes("not a directory")||o.includes("enotdir")?s=u.NOT_DIRECTORY:o.includes("already exists")||o.includes("eexist")?s=u.EXISTS:(o.includes("permission")||o.includes("eperm")||o.includes("eacces"))&&(s=u.PERMISSION_DENIED),this.protocol.setErrorCode(s),this.protocol.setResultFromString(e),this.protocol.setStatus(n.ERROR)}};var V=3e4,k={name:"python3",summary:"Execute Python code via Pyodide",usage:"python3 [OPTIONS] [-c CODE | -m MODULE | FILE] [ARGS...]",description:["Execute Python code using Pyodide (Python compiled to WebAssembly).","","This command runs Python in a sandboxed environment with access to","the virtual filesystem. Only Pyodide-bundled packages are available."],options:["-c CODE Execute CODE as Python script","-m MODULE Run library module as a script","--version Show Python version","--help Show this help"],examples:['python3 -c "print(1 + 2)"','python3 -c "import sys; print(sys.version)"',"python3 script.py","python3 script.py arg1 arg2",`echo 'print("hello")' | python3`],notes:["Pyodide runs in WebAssembly, so execution may be slower than native Python.","Only packages bundled with Pyodide are available (no pip install).","First execution loads Pyodide (~30MB), subsequent calls are faster.","Maximum execution time is 30 seconds by default."]};function M(r){let t={code:null,module:null,scriptFile:null,showVersion:!1,scriptArgs:[]};if(r.length===0)return t;let e=r.findIndex(s=>!s.startsWith("-")||s==="-"||s==="--");for(let s=0;s<(e===-1?r.length:e);s++){let o=r[s];if(o==="-c")return s+1>=r.length?{stdout:"",stderr:`python3: option requires an argument -- 'c'
6
- `,exitCode:2}:(t.code=r[s+1],t.scriptArgs=r.slice(s+2),t);if(o==="-m")return s+1>=r.length?{stdout:"",stderr:`python3: option requires an argument -- 'm'
7
- `,exitCode:2}:(t.module=r[s+1],t.scriptArgs=r.slice(s+2),t);if(o==="--version"||o==="-V")return t.showVersion=!0,t;if(o.startsWith("-")&&o!=="-")return{stdout:"",stderr:`python3: unrecognized option '${o}'
8
- `,exitCode:2}}if(e!==-1){let s=r[e];s==="--"?e+1<r.length&&(t.scriptFile=r[e+1],t.scriptArgs=r.slice(e+2)):(t.scriptFile=s,t.scriptArgs=r.slice(e+1))}return t}var c=null,F=null,S=[],E=null,b=L(new URL("./worker.js",import.meta.url));function _(){if(E||S.length===0)return;let r=S.shift();if(!r)return;E=r,B().postMessage(E.input)}function B(){return F&&(clearTimeout(F),F=null),c||(c=new N(b),c.on("message",r=>{E&&(E.resolve(r),E=null),S.length>0?_():v()}),c.on("error",r=>{E&&(E.resolve({success:!1,error:r.message}),E=null);for(let t of S)t.resolve({success:!1,error:"Worker crashed"});S.length=0,c=null}),c.on("exit",()=>{c=null}),c)}function v(){F=setTimeout(()=>{c&&!E&&S.length===0&&(c.terminate(),c=null)},5e3)}async function H(r,t,e,s=[]){let o=O(),l=new A(o,t.fs,t.cwd,t.fetch),d=t.limits?.maxPythonTimeoutMs??V,f={sharedBuffer:o,pythonCode:r,cwd:t.cwd,env:C(t.env),args:s,scriptPath:e},P=new Promise(T=>{let I=setTimeout(()=>{T({success:!1,error:`Execution timeout: exceeded ${d}ms limit`})},d),U=x=>{clearTimeout(I),T(x)};S.push({input:f,resolve:U}),_()}),[m,g]=await Promise.all([l.run(d),P.catch(T=>({success:!1,error:T.message}))]);return!g.success&&g.error?{stdout:m.stdout,stderr:`${m.stderr}python3: ${g.error}
9
- `,exitCode:m.exitCode||1}:m}var W={name:"python3",async execute(r,t){if(D(r))return y(k);let e=M(r);if("exitCode"in e)return e;if(e.showVersion)return{stdout:`Python 3.12.1 (Pyodide)
10
- `,stderr:"",exitCode:0};let s,o;if(e.code!==null)s=e.code,o="-c";else if(e.module!==null)s=`import runpy; runpy.run_module('${e.module}', run_name='__main__')`,o=e.module;else if(e.scriptFile!==null){let l=t.fs.resolvePath(t.cwd,e.scriptFile);if(!await t.fs.exists(l))return{stdout:"",stderr:`python3: can't open file '${e.scriptFile}': [Errno 2] No such file or directory
11
- `,exitCode:2};try{s=await t.fs.readFile(l),o=e.scriptFile}catch(d){return{stdout:"",stderr:`python3: can't open file '${e.scriptFile}': ${d.message}
12
- `,exitCode:2}}}else if(t.stdin.trim())s=t.stdin,o="<stdin>";else return{stdout:"",stderr:`python3: no input provided (use -c CODE, -m MODULE, or provide a script file)
13
- `,exitCode:2};return H(s,t,o,e.scriptArgs)}},Z={name:"python",async execute(r,t){return W.execute(r,t)}};export{W as python3Command,Z as pythonCommand};