typescript-virtual-container 1.3.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +0 -1
- package/README.md +674 -1504
- package/benchmark-results.txt +21 -21
- package/builds/self-standalone.js +274 -208
- package/builds/self-standalone.js.map +4 -4
- package/builds/standalone-wo-sftp.js +201 -149
- package/builds/standalone-wo-sftp.js.map +4 -4
- package/builds/standalone.js +263 -211
- package/builds/standalone.js.map +4 -4
- package/builds/web-full-api.min.js +3 -3
- package/builds/web-full-api.min.js.map +4 -4
- package/builds/web.min.js +2 -2
- package/builds/web.min.js.map +4 -4
- package/bun.lock +14 -12
- package/dist/SSHClient/index.d.ts.map +1 -1
- package/dist/SSHClient/index.js +5 -3
- package/dist/SSHMimic/executor.d.ts +1 -3
- package/dist/SSHMimic/executor.d.ts.map +1 -1
- package/dist/SSHMimic/executor.js +20 -22
- package/dist/SSHMimic/index.d.ts.map +1 -1
- package/dist/SSHMimic/index.js +5 -3
- package/dist/SSHMimic/sftp.d.ts.map +1 -1
- package/dist/SSHMimic/sftp.js +26 -21
- package/dist/VirtualShell/shell.d.ts.map +1 -1
- package/dist/VirtualShell/shell.js +25 -3
- package/dist/VirtualShell/shellParser.d.ts +1 -8
- package/dist/VirtualShell/shellParser.d.ts.map +1 -1
- package/dist/VirtualShell/shellParser.js +2 -81
- package/dist/VirtualUserManager/index.d.ts +7 -1
- package/dist/VirtualUserManager/index.d.ts.map +1 -1
- package/dist/VirtualUserManager/index.js +47 -19
- package/dist/commands/adduser.d.ts +10 -4
- package/dist/commands/adduser.d.ts.map +1 -1
- package/dist/commands/adduser.js +75 -12
- package/dist/commands/alias.d.ts +5 -0
- package/dist/commands/alias.d.ts.map +1 -1
- package/dist/commands/alias.js +5 -0
- package/dist/commands/apt.d.ts +5 -0
- package/dist/commands/apt.d.ts.map +1 -1
- package/dist/commands/apt.js +5 -0
- package/dist/commands/awk.d.ts +10 -8
- package/dist/commands/awk.d.ts.map +1 -1
- package/dist/commands/awk.js +156 -28
- package/dist/commands/cd.d.ts.map +1 -1
- package/dist/commands/cd.js +0 -3
- package/dist/commands/clear.d.ts +5 -0
- package/dist/commands/clear.d.ts.map +1 -1
- package/dist/commands/clear.js +5 -0
- package/dist/commands/command-helpers.d.ts.map +1 -1
- package/dist/commands/command-helpers.js +8 -0
- package/dist/commands/declare.d.ts +5 -0
- package/dist/commands/declare.d.ts.map +1 -1
- package/dist/commands/declare.js +5 -0
- package/dist/commands/deluser.d.ts +12 -0
- package/dist/commands/deluser.d.ts.map +1 -1
- package/dist/commands/deluser.js +72 -6
- package/dist/commands/df.d.ts +5 -0
- package/dist/commands/df.d.ts.map +1 -1
- package/dist/commands/df.js +5 -0
- package/dist/commands/du.d.ts +5 -0
- package/dist/commands/du.d.ts.map +1 -1
- package/dist/commands/du.js +5 -0
- package/dist/commands/export.d.ts +5 -0
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +5 -0
- package/dist/commands/grep.d.ts.map +1 -1
- package/dist/commands/grep.js +22 -4
- package/dist/commands/groups.d.ts +5 -0
- package/dist/commands/groups.d.ts.map +1 -1
- package/dist/commands/groups.js +5 -0
- package/dist/commands/gzip.d.ts +5 -2
- package/dist/commands/gzip.d.ts.map +1 -1
- package/dist/commands/gzip.js +48 -28
- package/dist/commands/head.d.ts.map +1 -1
- package/dist/commands/head.js +12 -3
- package/dist/commands/htop.d.ts +5 -0
- package/dist/commands/htop.d.ts.map +1 -1
- package/dist/commands/htop.js +5 -0
- package/dist/commands/kill.d.ts +5 -0
- package/dist/commands/kill.d.ts.map +1 -1
- package/dist/commands/kill.js +5 -0
- package/dist/commands/ln.d.ts +2 -0
- package/dist/commands/ln.d.ts.map +1 -1
- package/dist/commands/ln.js +22 -0
- package/dist/commands/ls.d.ts.map +1 -1
- package/dist/commands/ls.js +15 -0
- package/dist/commands/lsb-release.d.ts +5 -0
- package/dist/commands/lsb-release.d.ts.map +1 -1
- package/dist/commands/lsb-release.js +5 -0
- package/dist/commands/mkdir.d.ts +5 -0
- package/dist/commands/mkdir.d.ts.map +1 -1
- package/dist/commands/mkdir.js +5 -0
- package/dist/commands/mv.d.ts +5 -0
- package/dist/commands/mv.d.ts.map +1 -1
- package/dist/commands/mv.js +5 -0
- package/dist/commands/nano.d.ts +5 -0
- package/dist/commands/nano.d.ts.map +1 -1
- package/dist/commands/nano.js +5 -0
- package/dist/commands/neofetch.d.ts +5 -0
- package/dist/commands/neofetch.d.ts.map +1 -1
- package/dist/commands/neofetch.js +8 -5
- package/dist/commands/passwd.d.ts +8 -0
- package/dist/commands/passwd.d.ts.map +1 -1
- package/dist/commands/passwd.js +32 -11
- package/dist/commands/ping.d.ts +5 -0
- package/dist/commands/ping.d.ts.map +1 -1
- package/dist/commands/ping.js +5 -0
- package/dist/commands/printf.d.ts +5 -0
- package/dist/commands/printf.d.ts.map +1 -1
- package/dist/commands/printf.js +43 -12
- package/dist/commands/ps.d.ts +5 -0
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +5 -0
- package/dist/commands/read.d.ts +5 -0
- package/dist/commands/read.d.ts.map +1 -1
- package/dist/commands/read.js +5 -0
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +4 -1
- package/dist/commands/rm.d.ts +5 -0
- package/dist/commands/rm.d.ts.map +1 -1
- package/dist/commands/rm.js +5 -0
- package/dist/commands/runtime.d.ts.map +1 -1
- package/dist/commands/runtime.js +1 -57
- package/dist/commands/sed.d.ts +5 -0
- package/dist/commands/sed.d.ts.map +1 -1
- package/dist/commands/sed.js +5 -0
- package/dist/commands/set.d.ts +5 -6
- package/dist/commands/set.d.ts.map +1 -1
- package/dist/commands/set.js +5 -22
- package/dist/commands/sh.d.ts +6 -0
- package/dist/commands/sh.d.ts.map +1 -1
- package/dist/commands/sh.js +6 -0
- package/dist/commands/shift.d.ts +10 -0
- package/dist/commands/shift.d.ts.map +1 -1
- package/dist/commands/shift.js +10 -0
- package/dist/commands/sleep.d.ts +5 -0
- package/dist/commands/sleep.d.ts.map +1 -1
- package/dist/commands/sleep.js +5 -0
- package/dist/commands/sort.d.ts +5 -0
- package/dist/commands/sort.d.ts.map +1 -1
- package/dist/commands/sort.js +5 -0
- package/dist/commands/source.d.ts +5 -0
- package/dist/commands/source.d.ts.map +1 -1
- package/dist/commands/source.js +5 -0
- package/dist/commands/stat.d.ts +7 -0
- package/dist/commands/stat.d.ts.map +1 -0
- package/dist/commands/stat.js +56 -0
- package/dist/commands/su.d.ts +13 -0
- package/dist/commands/su.d.ts.map +1 -1
- package/dist/commands/su.js +45 -14
- package/dist/commands/sudo.d.ts.map +1 -1
- package/dist/commands/sudo.js +5 -0
- package/dist/commands/tail.d.ts +5 -0
- package/dist/commands/tail.d.ts.map +1 -1
- package/dist/commands/tail.js +15 -3
- package/dist/commands/tar.d.ts +5 -0
- package/dist/commands/tar.d.ts.map +1 -1
- package/dist/commands/tar.js +40 -10
- package/dist/commands/tee.d.ts +5 -0
- package/dist/commands/tee.d.ts.map +1 -1
- package/dist/commands/tee.js +5 -0
- package/dist/commands/touch.d.ts +5 -0
- package/dist/commands/touch.d.ts.map +1 -1
- package/dist/commands/touch.js +5 -0
- package/dist/commands/tr.d.ts.map +1 -1
- package/dist/commands/tr.js +45 -10
- package/dist/commands/tree.d.ts +5 -0
- package/dist/commands/tree.d.ts.map +1 -1
- package/dist/commands/tree.js +5 -0
- package/dist/commands/true.d.ts +10 -0
- package/dist/commands/true.d.ts.map +1 -1
- package/dist/commands/true.js +10 -0
- package/dist/commands/type.d.ts +5 -0
- package/dist/commands/type.d.ts.map +1 -1
- package/dist/commands/type.js +5 -0
- package/dist/commands/uname.d.ts +5 -0
- package/dist/commands/uname.d.ts.map +1 -1
- package/dist/commands/uname.js +5 -0
- package/dist/commands/uniq.d.ts +5 -0
- package/dist/commands/uniq.d.ts.map +1 -1
- package/dist/commands/uniq.js +5 -0
- package/dist/commands/unset.d.ts +5 -0
- package/dist/commands/unset.d.ts.map +1 -1
- package/dist/commands/unset.js +5 -0
- package/dist/commands/uptime.d.ts +5 -0
- package/dist/commands/uptime.d.ts.map +1 -1
- package/dist/commands/uptime.js +5 -0
- package/dist/commands/wc.d.ts +5 -0
- package/dist/commands/wc.d.ts.map +1 -1
- package/dist/commands/wc.js +5 -0
- package/dist/commands/wget.d.ts +5 -0
- package/dist/commands/wget.d.ts.map +1 -1
- package/dist/commands/wget.js +5 -0
- package/dist/commands/who.d.ts +5 -0
- package/dist/commands/who.d.ts.map +1 -1
- package/dist/commands/who.js +5 -0
- package/dist/commands/whoami.d.ts +5 -0
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +5 -0
- package/dist/commands/xargs.d.ts +5 -0
- package/dist/commands/xargs.d.ts.map +1 -1
- package/dist/commands/xargs.js +5 -0
- package/dist/self-standalone.js +254 -30
- package/dist/types/commands.d.ts +36 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/utils/tokenize.d.ts +20 -0
- package/dist/utils/tokenize.d.ts.map +1 -0
- package/dist/utils/tokenize.js +74 -0
- package/examples/web.min.js +2 -2
- package/package.json +1 -1
- package/src/SSHClient/index.ts +6 -3
- package/src/SSHMimic/executor.ts +21 -44
- package/src/SSHMimic/index.ts +7 -5
- package/src/SSHMimic/sftp.ts +28 -21
- package/src/VirtualShell/shell.ts +34 -4
- package/src/VirtualShell/shellParser.ts +2 -103
- package/src/VirtualUserManager/index.ts +44 -20
- package/src/commands/adduser.ts +86 -13
- package/src/commands/alias.ts +5 -0
- package/src/commands/apt.ts +5 -0
- package/src/commands/awk.ts +154 -29
- package/src/commands/cd.ts +0 -4
- package/src/commands/clear.ts +5 -0
- package/src/commands/command-helpers.ts +9 -0
- package/src/commands/declare.ts +5 -0
- package/src/commands/deluser.ts +84 -7
- package/src/commands/df.ts +5 -0
- package/src/commands/du.ts +5 -0
- package/src/commands/export.ts +5 -0
- package/src/commands/grep.ts +21 -8
- package/src/commands/groups.ts +5 -0
- package/src/commands/gzip.ts +54 -28
- package/src/commands/head.ts +14 -4
- package/src/commands/htop.ts +5 -0
- package/src/commands/kill.ts +5 -0
- package/src/commands/ln.ts +22 -0
- package/src/commands/ls.ts +17 -0
- package/src/commands/lsb-release.ts +5 -0
- package/src/commands/mkdir.ts +5 -0
- package/src/commands/mv.ts +5 -0
- package/src/commands/nano.ts +5 -0
- package/src/commands/neofetch.ts +8 -6
- package/src/commands/passwd.ts +35 -12
- package/src/commands/ping.ts +5 -0
- package/src/commands/printf.ts +30 -13
- package/src/commands/ps.ts +5 -0
- package/src/commands/read.ts +5 -0
- package/src/commands/registry.ts +4 -1
- package/src/commands/rm.ts +5 -0
- package/src/commands/runtime.ts +1 -61
- package/src/commands/sed.ts +5 -0
- package/src/commands/set.ts +5 -24
- package/src/commands/sh.ts +9 -3
- package/src/commands/shift.ts +10 -0
- package/src/commands/sleep.ts +5 -0
- package/src/commands/sort.ts +5 -0
- package/src/commands/source.ts +5 -0
- package/src/commands/stat.ts +61 -0
- package/src/commands/su.ts +54 -16
- package/src/commands/sudo.ts +5 -0
- package/src/commands/tail.ts +17 -3
- package/src/commands/tar.ts +38 -15
- package/src/commands/tee.ts +5 -0
- package/src/commands/touch.ts +5 -0
- package/src/commands/tr.ts +54 -10
- package/src/commands/tree.ts +5 -0
- package/src/commands/true.ts +10 -0
- package/src/commands/type.ts +5 -0
- package/src/commands/uname.ts +5 -0
- package/src/commands/uniq.ts +5 -0
- package/src/commands/unset.ts +5 -0
- package/src/commands/uptime.ts +5 -0
- package/src/commands/wc.ts +5 -0
- package/src/commands/wget.ts +5 -0
- package/src/commands/who.ts +5 -0
- package/src/commands/whoami.ts +5 -0
- package/src/commands/xargs.ts +5 -0
- package/src/self-standalone.ts +316 -33
- package/src/types/commands.ts +37 -0
- package/src/utils/tokenize.ts +78 -0
- package/builds/web-iife.min.js +0 -13
- package/builds/web-iife.min.js.map +0 -7
|
@@ -1,67 +1,107 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{basename as
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import{readFile as Wi,unlink as ji,writeFile as Hi}from"node:fs/promises";import{basename as qi}from"node:path";import{stdin as it,stdout as rt}from"node:process";import{createInterface as Ki}from"node:readline";var Ve={name:"adduser",description:"Add a new user",category:"users",params:["<username>"],run:({authUser:e,shell:t,args:r})=>{if(e!=="root")return{stderr:`adduser: permission denied
|
|
3
|
+
`,exitCode:1};let n=r[0];if(!n)return{stderr:`Usage: adduser <username>
|
|
4
|
+
`,exitCode:1};if(t.users.listUsers().includes(n))return{stderr:`adduser: user '${n}' already exists
|
|
5
|
+
`,exitCode:1};let i="",s="new";return{sudoChallenge:{username:n,targetUser:n,commandLine:null,loginShell:!1,prompt:"New password: ",mode:"passwd",onPassword:async(a,l)=>s==="new"?a.length<1?{result:{stderr:`adduser: password cannot be empty
|
|
6
|
+
`,exitCode:1}}:(i=a,s="retype",{result:null,nextPrompt:"Retype new password: "}):a!==i?{result:{stderr:`adduser: passwords do not match \u2014 user not created
|
|
7
|
+
`,exitCode:1}}:(await l.users.addUser(n,i),{result:{stdout:`${[`Adding user '${n}' ...`,`Adding new group '${n}' (1001) ...`,`Adding new user '${n}' (1001) with group '${n}' ...`,`Creating home directory '/home/${n}' ...`,`passwd: password set for '${n}'`,"adduser: done."].join(`
|
|
8
|
+
`)}
|
|
9
|
+
`,exitCode:0}})},exitCode:0}}};function De(e){return Array.isArray(e)?e:[e]}function jt(e,t){if(e===t)return{matched:!0,inlineValue:null};let r=`${t}=`;return e.startsWith(r)?{matched:!0,inlineValue:e.slice(r.length)}:t.length===2&&t.startsWith("-")&&!t.startsWith("--")&&e.startsWith(t)&&e.length>t.length?{matched:!0,inlineValue:e.slice(t.length)}:{matched:!1,inlineValue:null}}function Ss(e,t={}){let r=new Set(t.flags??[]),n=new Set(t.flagsWithValue??[]),i=[],s=!1;for(let o=0;o<e.length;o+=1){let a=e[o];if(s){i.push(a);continue}if(a==="--"){s=!0;continue}let l=!1;for(let c of r){let{matched:u}=jt(a,c);if(u){l=!0;break}}if(!l){for(let c of n){let u=jt(a,c);if(u.matched){l=!0,u.inlineValue===null&&o+1<e.length&&(o+=1);break}}l||i.push(a)}}return i}function y(e,t){let r=De(t);for(let n of e)for(let i of r)if(jt(n,i).matched)return!0;return!1}function st(e,t){let r=De(t);for(let n=0;n<e.length;n+=1){let i=e[n];for(let s of r){let o=jt(i,s);if(!o.matched)continue;if(o.inlineValue!==null)return o.inlineValue;let a=e[n+1];return a!==void 0&&a!=="--"?a:!0}}}function wt(e,t,r={}){return Ss(e,r)[t]}function nt(e,t={}){let r=new Set,n=new Map,i=[],s=new Set(t.flags??[]),o=new Set(t.flagsWithValue??[]),a=!1;for(let l=0;l<e.length;l+=1){let c=e[l];if(a){i.push(c);continue}if(c==="--"){a=!0;continue}if(s.has(c)){r.add(c);continue}if(o.has(c)){let d=e[l+1];d&&!d.startsWith("-")?(n.set(c,d),l+=1):n.set(c,"");continue}let u=Array.from(o).find(d=>c.startsWith(`${d}=`));if(u){n.set(u,c.slice(u.length+1));continue}i.push(c)}return{flags:r,flagsWithValues:n,positionals:i}}var _e={name:"alias",description:"Define or display aliases",category:"shell",params:["[name[=value] ...]"],run:({args:e,env:t})=>{if(!t)return{exitCode:0};if(e.length===0)return{stdout:Object.entries(t.vars).filter(([i])=>i.startsWith("__alias_")).map(([i,s])=>`alias ${i.slice(8)}='${s}'`).join(`
|
|
10
|
+
`)||"",exitCode:0};let r=[];for(let n of e){let i=n.indexOf("=");if(i===-1){let s=t.vars[`__alias_${n}`];if(s)r.push(`alias ${n}='${s}'`);else return{stderr:`alias: ${n}: not found`,exitCode:1}}else{let s=n.slice(0,i),o=n.slice(i+1).replace(/^['"]|['"]$/g,"");t.vars[`__alias_${s}`]=o}}return{stdout:r.join(`
|
|
11
|
+
`)||void 0,exitCode:0}}},Le={name:"unalias",description:"Remove alias definitions",category:"shell",params:["<name...> | -a"],run:({args:e,env:t})=>{if(!t)return{exitCode:0};if(y(e,["-a"])){for(let r of Object.keys(t.vars))r.startsWith("__alias_")&&delete t.vars[r];return{exitCode:0}}for(let r of e)delete t.vars[`__alias_${r}`];return{exitCode:0}}};import*as ut from"node:path";var ws=["/virtual-env-js/.auth"];function x(e,t){return!t||t.trim()===""?e:t.startsWith("/")?ut.posix.normalize(t):ut.posix.normalize(ut.posix.join(e,t))}function xs(e){let t=e.startsWith("/")?ut.posix.normalize(e):ut.posix.normalize(`/${e}`);return ws.some(r=>t===r||t.startsWith(`${r}/`))}function L(e,t,r){if(e!=="root"&&xs(t))throw new Error(`${r}: permission denied: ${t}`)}function Te(e){let r=(e.split("?")[0]?.split("#")[0]??e).split("/").filter(Boolean).pop();return r&&r.length>0?r:"index.html"}function bs(e,t){let r=Array.from({length:e.length+1},()=>Array(t.length+1).fill(0));for(let n=0;n<=e.length;n+=1)r[n][0]=n;for(let n=0;n<=t.length;n+=1)r[0][n]=n;for(let n=1;n<=e.length;n+=1)for(let i=1;i<=t.length;i+=1){let s=e[n-1]===t[i-1]?0:1;r[n][i]=Math.min(r[n-1][i]+1,r[n][i-1]+1,r[n-1][i-1]+s)}return r[e.length][t.length]}function ze(e,t,r){let n=x(t,r);if(e.exists(n))return n;let i=ut.posix.dirname(n),s=ut.posix.basename(n),o=e.list(i),a=o.filter(c=>c.toLowerCase()===s.toLowerCase());if(a.length===1)return ut.posix.join(i,a[0]);let l=o.filter(c=>bs(c.toLowerCase(),s.toLowerCase())<=1);return l.length===1?ut.posix.join(i,l[0]):n}function Oe(e,t,r){return t.map(n=>{let i=x(e,n);return r(i).type==="directory"?`${n}/`:n}).join(" ")}function Pt(e){return e.packageManager}var Ue={name:"apt",aliases:["apt-get"],description:"Package manager",category:"package",params:["<install|remove|update|upgrade|search|show|list> [pkg...]"],run:({args:e,shell:t,authUser:r})=>{let n=Pt(t);if(!n)return{stderr:"apt: package manager not initialised",exitCode:1};let i=e[0]?.toLowerCase(),s=e.slice(1),o=y(s,["-q","--quiet","-qq"]),a=y(s,["--purge"]),l=s.filter(u=>!u.startsWith("-"));if(["install","remove","purge","upgrade","update"].includes(i??"")&&r!=="root")return{stderr:`E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
|
|
5
12
|
E: Unable to acquire the dpkg frontend lock, are you root?`,exitCode:100};switch(i){case"install":{if(l.length===0)return{stderr:"apt: no packages specified",exitCode:1};let{output:u,exitCode:d}=n.install(l,{quiet:o});return{stdout:u||void 0,exitCode:d}}case"remove":case"purge":{if(l.length===0)return{stderr:"apt: no packages specified",exitCode:1};let{output:u,exitCode:d}=n.remove(l,{purge:i==="purge"||a,quiet:o});return{stdout:u||void 0,exitCode:d}}case"update":return{stdout:["Hit:1 fortune://packages.fortune.local aurora InRelease","Hit:2 fortune://security.fortune.local aurora-security InRelease","Reading package lists... Done","Building dependency tree... Done","Reading state information... Done","All packages are up to date."].join(`
|
|
6
13
|
`),exitCode:0};case"upgrade":return{stdout:["Reading package lists... Done","Building dependency tree... Done","Reading state information... Done","Calculating upgrade... Done","0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded."].join(`
|
|
7
14
|
`),exitCode:0};case"search":{let u=l[0];if(!u)return{stderr:"apt: search requires a term",exitCode:1};let d=n.search(u);return d.length===0?{stdout:`Sorting... Done
|
|
8
15
|
Full Text Search... Done
|
|
9
16
|
(no results)`,exitCode:0}:{stdout:`Sorting... Done
|
|
10
17
|
Full Text Search... Done
|
|
11
|
-
${d.map(
|
|
12
|
-
${
|
|
13
|
-
`)}`,exitCode:0}}case"show":{let u=l[0];if(!u)return{stderr:"apt: show requires a package name",exitCode:1};let d=n.show(u);return d?{stdout:d,exitCode:0}:{stderr:`N: Unable to locate package ${u}`,exitCode:100}}case"list":{if(
|
|
18
|
+
${d.map(p=>`${p.name}/${p.section??"misc"} ${p.version} amd64
|
|
19
|
+
${p.shortDesc??p.description}`).join(`
|
|
20
|
+
`)}`,exitCode:0}}case"show":{let u=l[0];if(!u)return{stderr:"apt: show requires a package name",exitCode:1};let d=n.show(u);return d?{stdout:d,exitCode:0}:{stderr:`N: Unable to locate package ${u}`,exitCode:100}}case"list":{if(y(s,["--installed"])){let p=n.listInstalled();return p.length===0?{stdout:`Listing... Done
|
|
14
21
|
(no packages installed)`,exitCode:0}:{stdout:`Listing... Done
|
|
15
|
-
${
|
|
22
|
+
${p.map(g=>`${g.name}/${g.section} ${g.version} ${g.architecture} [installed]`).join(`
|
|
16
23
|
`)}`,exitCode:0}}return{stdout:`Listing... Done
|
|
17
|
-
${n.listAvailable().map(
|
|
24
|
+
${n.listAvailable().map(p=>`${p.name}/${p.section??"misc"} ${p.version} amd64`).join(`
|
|
18
25
|
`)}`,exitCode:0}}default:return{stdout:["Usage: apt [options] command","","Commands:"," install <pkg...> Install packages"," remove <pkg...> Remove packages"," purge <pkg...> Remove packages and config files"," update Refresh package index"," upgrade Upgrade all packages"," search <term> Search in package descriptions"," show <pkg> Show package details"," list [--installed] List packages"].join(`
|
|
19
|
-
`),exitCode:0}}}},
|
|
20
|
-
`)||"(no results)",exitCode:0}:{stderr:"Need a search term",exitCode:1};case"show":{if(!i)return{stderr:"Need a package name",exitCode:1};let s=
|
|
21
|
-
`),exitCode:0}}default:return{stderr:`apt-cache: unknown command '${n??""}'`,exitCode:1}}}};var
|
|
22
|
-
`).
|
|
23
|
-
`)
|
|
26
|
+
`),exitCode:0}}}},Be={name:"apt-cache",description:"Query the package cache",category:"package",params:["<search|show|policy> [pkg]"],run:({args:e,shell:t})=>{let r=Pt(t);if(!r)return{stderr:"apt-cache: package manager not initialised",exitCode:1};let n=e[0]?.toLowerCase(),i=e[1];switch(n){case"search":return i?{stdout:r.search(i).map(o=>`${o.name} - ${o.shortDesc??o.description}`).join(`
|
|
27
|
+
`)||"(no results)",exitCode:0}:{stderr:"Need a search term",exitCode:1};case"show":{if(!i)return{stderr:"Need a package name",exitCode:1};let s=r.show(i);return s?{stdout:s,exitCode:0}:{stderr:`N: Unable to locate package ${i}`,exitCode:100}}case"policy":{if(!i)return{stderr:"Need a package name",exitCode:1};let s=r.findInRegistry(i);if(!s)return{stderr:`N: Unable to locate package ${i}`,exitCode:100};let o=r.isInstalled(i);return{stdout:[`${i}:`,` Installed: ${o?s.version:"(none)"}`,` Candidate: ${s.version}`," Version table:",` ${s.version} 500`," 500 fortune://packages.fortune.local aurora/main amd64 Packages"].join(`
|
|
28
|
+
`),exitCode:0}}default:return{stderr:`apt-cache: unknown command '${n??""}'`,exitCode:1}}}};var We={name:"awk",description:"Pattern scanning and processing language",category:"text",params:["[-F <sep>] '<program>' [file]"],run:({authUser:e,args:t,stdin:r,cwd:n,shell:i})=>{let s=st(t,["-F"])??" ",o=t.filter(w=>!w.startsWith("-")&&w!==s),a=o[0],l=o[1];if(!a)return{stderr:"awk: no program",exitCode:1};let c=r??"";if(l){let w=x(n,l);try{L(e,w,"awk"),c=i.vfs.readFile(w)}catch{return{stderr:`awk: ${l}: No such file or directory`,exitCode:1}}}let u=c.split(`
|
|
29
|
+
`);u[u.length-1]===""&&u.pop();let d=[],m=a.trim();if(!m.startsWith("{")&&!m.includes("{"))d.push({pattern:m,action:"print $0"});else{let w=/([^{]*)\{([^}]*)\}/g,k=w.exec(m);for(;k!==null;)d.push({pattern:k[1].trim(),action:k[2].trim()}),k=w.exec(m);d.length===0&&d.push({pattern:"",action:m.replace(/[{}]/g,"").trim()})}let p=[],S=d.find(w=>w.pattern==="BEGIN"),g=d.find(w=>w.pattern==="END"),f=d.filter(w=>w.pattern!=="BEGIN"&&w.pattern!=="END");function $(w){return s===" "?w.trim().split(/\s+/).filter(Boolean):w.split(s)}function F(w,k,R){let b=$(k),P=b.length,V=v=>{if(v=v.trim(),v==="NR")return String(R);if(v==="NF")return String(P);if(v==="$0")return k;if(v==="$NF")return b[P-1]??"";if(/^\$\d+$/.test(v))return b[parseInt(v.slice(1),10)-1]??"";let N=v.replace(/\bNR\b/g,String(R)).replace(/\bNF\b/g,String(P));if(/^[\d\s+\-*/()]+$/.test(N))try{return String(Function(`"use strict"; return (${N});`)())}catch{}return v.replace(/"/g,"")},C=w.split(";").map(v=>v.trim()).filter(Boolean);for(let v of C)if(v==="print"||v==="print $0")p.push(k);else if(v.startsWith("print ")){let N=v.slice(6).split(/\s*,\s*/);p.push(N.map(V).join(" "))}}function M(w,k,R){if(!w||w==="1")return!0;let b=w.match(/^NR\s*([=!<>]=?|==)\s*(\d+)$/);if(b){let C=b[1],v=parseInt(b[2],10);switch(C){case"==":return R===v;case"!=":return R!==v;case">":return R>v;case">=":return R>=v;case"<":return R<v;case"<=":return R<=v}}let P=w.match(/^NR%(\d+)==(\d+)$/);if(P)return R%parseInt(P[1],10)===parseInt(P[2],10);if(w.startsWith("/")&&w.endsWith("/"))try{return new RegExp(w.slice(1,-1)).test(k)}catch{return!1}let V=w.match(/^\$(\d+)~\/(.*)\/$/);if(V){let v=$(k)[parseInt(V[1],10)-1]??"";try{return new RegExp(V[2]).test(v)}catch{return!1}}return!1}S&&F(S.action,"",0);for(let w=1;w<=u.length;w++){let k=u[w-1];for(let R of f)M(R.pattern,k,w)&&F(R.action,k,w)}return g&&F(g.action,"",u.length+1),{stdout:p.join(`
|
|
30
|
+
`)+(p.length>0?`
|
|
31
|
+
`:""),exitCode:0}}};var je={name:"base64",description:"Encode/decode base64",category:"text",params:["[-d] [file]"],run:({args:e,stdin:t})=>{let r=y(e,["-d","--decode"]),n=t??"";if(r)try{return{stdout:Buffer.from(n.trim(),"base64").toString("utf8"),exitCode:0}}catch{return{stderr:"base64: invalid input",exitCode:1}}return{stdout:Buffer.from(n).toString("base64"),exitCode:0}}};var He={name:"cat",description:"Concatenate and print files",category:"files",params:["[-n] [-b] <file...>"],run:({authUser:e,shell:t,cwd:r,args:n,stdin:i})=>{let s=y(n,["-n","--number"]),o=y(n,["-b","--number-nonblank"]),a=n.filter(m=>!m.startsWith("-"));if(a.length===0&&i!==void 0)return{stdout:i,exitCode:0};if(a.length===0)return{stderr:"cat: missing file operand",exitCode:1};let l=[];for(let m of a){let p=ze(t.vfs,r,m);L(e,p,"cat"),l.push(t.vfs.readFile(p))}let c=l.join("");if(!s&&!o)return{stdout:c,exitCode:0};let u=1;return{stdout:c.split(`
|
|
24
32
|
`).map(m=>o&&m.trim()===""?m:`${String(u++).padStart(6)} ${m}`).join(`
|
|
25
|
-
`),exitCode:0}}};var
|
|
26
|
-
`),exitCode:0};let o=s[0];if(!o)return{stderr:"curl: no URL specified",exitCode:1};let a=i.get("-o")??i.get("--output")??null,l=(i.get("-X")??i.get("--request")??"GET").toUpperCase(),c=i.get("-d")??i.get("--data")??null,u=i.get("-H")??i.get("--header")??null,d=
|
|
33
|
+
`),exitCode:0}}};var qe={name:"cd",description:"Change directory",category:"navigation",params:["[path]"],run:({authUser:e,shell:t,cwd:r,args:n,mode:i})=>{let s=x(r,n[0]??"/virtual-env-js");return L(e,s,"cd"),t.vfs.stat(s).type!=="directory"?{stderr:`cd: not a directory: ${s}`,exitCode:1}:{nextCwd:s,exitCode:0}}};function vs(e,t){let r=/^([ugoa]*)([+\-=])([rwx]*)$/,n=t.split(","),i=e;for(let s of n){let o=s.trim().match(r);if(!o)return null;let[,a="a",l,c=""]=o,u=a===""||a==="a"?["u","g","o"]:a.split(""),d={u:{r:256,w:128,x:64},g:{r:32,w:16,x:8},o:{r:4,w:2,x:1}};for(let m of u)for(let p of c.split("")){let S=d[m]?.[p];if(S!==void 0){if(l==="+")i|=S;else if(l==="-")i&=~S;else if(l==="="){let g=Object.values(d[m]??{}).reduce((f,$)=>f|$,0);i=i&~g|S}}}}return i}var Ke={name:"chmod",description:"Change file permissions",category:"files",params:["<mode> <file>"],run:({authUser:e,shell:t,cwd:r,args:n})=>{let[i,s]=n;if(!i||!s)return{stderr:"chmod: missing operand",exitCode:1};let o=x(r,s);try{if(L(e,o,"chmod"),!t.vfs.exists(o))return{stderr:`chmod: ${s}: No such file or directory`,exitCode:1};let a,l=parseInt(i,8);if(!Number.isNaN(l)&&/^[0-7]+$/.test(i))a=l;else{let c=t.vfs.stat(o).mode,u=vs(c,i);if(u===null)return{stderr:`chmod: invalid mode: ${i}`,exitCode:1};a=u}return t.vfs.chmod(o,a),{exitCode:0}}catch(a){return{stderr:`chmod: ${a instanceof Error?a.message:String(a)}`,exitCode:1}}}};var Ge={name:"clear",description:"Clear the terminal screen",category:"shell",params:[],run:()=>({clearScreen:!0,stdout:"",exitCode:0})};var Ze={name:"cp",description:"Copy files or directories",category:"files",params:["[-r] <source> <dest>"],run:({authUser:e,shell:t,cwd:r,args:n})=>{let i=y(n,["-r","-R","--recursive"]),s=n.filter(u=>!u.startsWith("-")),[o,a]=s;if(!o||!a)return{stderr:"cp: missing operand",exitCode:1};let l=x(r,o),c=x(r,a);try{if(L(e,l,"cp"),L(e,c,"cp"),!t.vfs.exists(l))return{stderr:`cp: ${o}: No such file or directory`,exitCode:1};if(t.vfs.stat(l).type==="directory"){if(!i)return{stderr:`cp: ${o}: is a directory (use -r)`,exitCode:1};let d=(p,S)=>{t.vfs.mkdir(S,493);for(let g of t.vfs.list(p)){let f=`${p}/${g}`,$=`${S}/${g}`;if(t.vfs.stat(f).type==="directory")d(f,$);else{let M=t.vfs.readFileRaw(f);t.writeFileAsUser(e,$,M)}}},m=t.vfs.exists(c)&&t.vfs.stat(c).type==="directory"?`${c}/${o.split("/").pop()}`:c;d(l,m)}else{let d=t.vfs.exists(c)&&t.vfs.stat(c).type==="directory"?`${c}/${o.split("/").pop()}`:c,m=t.vfs.readFileRaw(l);t.writeFileAsUser(e,d,m)}return{exitCode:0}}catch(u){return{stderr:`cp: ${u instanceof Error?u.message:String(u)}`,exitCode:1}}}};var Je={name:"curl",description:"Transfer data from or to a server (pure fetch)",category:"network",params:["[options] <url>"],run:async({authUser:e,cwd:t,args:r,shell:n})=>{let{flagsWithValues:i,positionals:s}=nt(r,{flagsWithValue:["-o","--output","-X","--request","-d","--data","-H","--header","-u","--user"]});if(y(r,["--help","-h"]))return{stdout:["Usage: curl [options] <url>"," -o, --output <file> Write to file"," -X, --request <method> HTTP method"," -d, --data <data> POST data"," -H, --header <hdr> Extra header"," -s, --silent Silent mode"," -I, --head Fetch headers only"," -L, --location Follow redirects"," -v, --verbose Verbose"].join(`
|
|
34
|
+
`),exitCode:0};let o=s[0];if(!o)return{stderr:"curl: no URL specified",exitCode:1};let a=i.get("-o")??i.get("--output")??null,l=(i.get("-X")??i.get("--request")??"GET").toUpperCase(),c=i.get("-d")??i.get("--data")??null,u=i.get("-H")??i.get("--header")??null,d=y(r,["-s","--silent"]),m=y(r,["-I","--head"]),p=y(r,["-L","--location"]),S=y(r,["-v","--verbose"]),g={"User-Agent":"curl/7.88.1"};if(u){let k=u.indexOf(":");k!==-1&&(g[u.slice(0,k).trim()]=u.slice(k+1).trim())}let f=c&&l==="GET"?"POST":l,$={method:f,headers:g,redirect:p?"follow":"manual"};c&&(g["Content-Type"]??="application/x-www-form-urlencoded",$.body=c);let F=[];S&&(F.push(`* Trying ${o}...`,"* Connected"),F.push(`> ${f} / HTTP/1.1`,`> Host: ${new URL(o).host}`));let M;try{M=await fetch(o,$)}catch(k){return{stderr:`curl: (6) Could not resolve host: ${k instanceof Error?k.message:String(k)}`,exitCode:6}}if(S&&F.push(`< HTTP/1.1 ${M.status} ${M.statusText}`),m){let k=[`HTTP/1.1 ${M.status} ${M.statusText}`];for(let[R,b]of M.headers.entries())k.push(`${R}: ${b}`);return{stdout:`${k.join(`\r
|
|
27
35
|
`)}\r
|
|
28
|
-
`,exitCode:0}}let
|
|
29
|
-
100 ${
|
|
30
|
-
`)||void 0,exitCode:
|
|
31
|
-
`):void 0,exitCode:
|
|
32
|
-
`).map(a=>{let l=a.split(
|
|
33
|
-
`),exitCode:0}}};var
|
|
34
|
-
`),exitCode:0};let o=
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
`,exitCode:0}}let w;try{w=await M.text()}catch{return{stderr:"curl: failed to read response body",exitCode:1}}if(a){let k=x(t,a);return L(e,k,"curl"),n.writeFileAsUser(e,k,w),d||F.push(` % Total % Received
|
|
37
|
+
100 ${w.length} 100 ${w.length}`),{stderr:F.join(`
|
|
38
|
+
`)||void 0,exitCode:M.ok?0:22}}return{stdout:w,stderr:F.length>0?F.join(`
|
|
39
|
+
`):void 0,exitCode:M.ok?0:22}}};var Ye={name:"cut",description:"Remove sections from lines",category:"text",params:["-d <delim> -f <fields> [file]"],run:({args:e,stdin:t})=>{let r=st(e,["-d"])??" ",i=(st(e,["-f"])??"1").split(",").map(a=>{let[l,c]=a.split("-").map(Number);return c!==void 0?{from:(l??1)-1,to:c-1}:{from:(l??1)-1,to:(l??1)-1}});return{stdout:(t??"").split(`
|
|
40
|
+
`).map(a=>{let l=a.split(r),c=[];for(let u of i)for(let d=u.from;d<=Math.min(u.to,l.length-1);d++)c.push(l[d]??"");return c.join(r)}).join(`
|
|
41
|
+
`),exitCode:0}}};var Qe={name:"date",description:"Print current date and time",category:"system",params:["[+format]"],run:({args:e})=>{let t=new Date,r=e[0];return r?.startsWith("+")?{stdout:r.slice(1).replace("%Y",String(t.getFullYear())).replace("%m",String(t.getMonth()+1).padStart(2,"0")).replace("%d",String(t.getDate()).padStart(2,"0")).replace("%H",String(t.getHours()).padStart(2,"0")).replace("%M",String(t.getMinutes()).padStart(2,"0")).replace("%S",String(t.getSeconds()).padStart(2,"0")).replace("%s",String(Math.floor(t.getTime()/1e3))),exitCode:0}:{stdout:t.toString(),exitCode:0}}};var Xe={name:"declare",aliases:["local","typeset"],description:"Declare variables and give them attributes",category:"shell",params:["[-i] [-r] [-x] [-a] [name[=value]...]"],run:({args:e,env:t})=>{if(!t)return{exitCode:0};let r=y(e,["-i"]),n=y(e,["-r"]),i=y(e,["-x"]);if(e.filter(a=>!a.startsWith("-")).length===0)return{stdout:Object.entries(t.vars).map(([l,c])=>`declare -- ${l}="${c}"`).join(`
|
|
42
|
+
`),exitCode:0};let o=e.filter(a=>!a.startsWith("-"));for(let a of o){let l=a.indexOf("=");if(l===-1)a in t.vars||(t.vars[a]="");else{let c=a.slice(0,l),u=a.slice(l+1);if(r){let d=parseInt(u,10);u=Number.isNaN(d)?"0":String(d)}t.vars[c]=u}}return{exitCode:0}}};var tr={name:"deluser",description:"Delete a user",category:"users",params:["[-f] <username>"],run:async({authUser:e,args:t,shell:r})=>{if(e!=="root")return{stderr:`deluser: permission denied
|
|
43
|
+
`,exitCode:1};let n=t.includes("-f")||t.includes("--force")||t.includes("-y"),i=t.find(o=>!o.startsWith("-"));if(!i)return{stderr:`Usage: deluser [-f] <username>
|
|
44
|
+
`,exitCode:1};if(!r.users.listUsers().includes(i))return{stderr:`deluser: user '${i}' does not exist
|
|
45
|
+
`,exitCode:1};if(i==="root")return{stderr:`deluser: cannot remove the root account
|
|
46
|
+
`,exitCode:1};if(n)return await r.users.deleteUser(i),{stdout:`Removing user '${i}' ...
|
|
47
|
+
deluser: done.
|
|
48
|
+
`,exitCode:0};let s=async(o,a)=>o.trim()!==i?{result:{stderr:`deluser: confirmation did not match \u2014 user not deleted
|
|
49
|
+
`,exitCode:1}}:(await a.users.deleteUser(i),{result:{stdout:`Removing user '${i}' ...
|
|
50
|
+
deluser: done.
|
|
51
|
+
`,exitCode:0}});return{sudoChallenge:{username:i,targetUser:i,commandLine:null,loginShell:!1,prompt:`Warning: deleting user '${i}'.
|
|
52
|
+
Type the username to confirm: `,mode:"confirm",onPassword:s},exitCode:0}}};var er={name:"df",description:"Report filesystem disk space usage",category:"system",params:["[-h]"],run:({shell:e})=>{let r=(e.vfs.getUsageBytes()/1024).toFixed(0),n="1048576",i=String(Number(n)-Number(r)),s=Math.round(Number(r)/Number(n)*100),o="Filesystem 1K-blocks Used Available Use% Mounted on",a=`virtual-fs ${n.padStart(9)} ${r.padStart(7)} ${i.padStart(9)} ${s}% /`;return{stdout:`${o}
|
|
53
|
+
${a}`,exitCode:0}}};var rr={name:"diff",description:"Compare files line by line",category:"text",params:["<file1> <file2>"],run:({shell:e,cwd:t,args:r})=>{let[n,i]=r;if(!n||!i)return{stderr:"diff: missing operand",exitCode:1};let s=x(t,n),o=x(t,i),a,l;try{a=e.vfs.readFile(s).split(`
|
|
54
|
+
`)}catch{return{stderr:`diff: ${n}: No such file or directory`,exitCode:2}}try{l=e.vfs.readFile(o).split(`
|
|
55
|
+
`)}catch{return{stderr:`diff: ${i}: No such file or directory`,exitCode:2}}let c=[],u=Math.max(a.length,l.length);for(let d=0;d<u;d++){let m=a[d],p=l[d];m!==p&&(m!==void 0&&c.push(`< ${m}`),p!==void 0&&c.push(`> ${p}`))}return{stdout:c.join(`
|
|
56
|
+
`),exitCode:c.length>0?1:0}}};var nr={name:"dpkg",description:"Debian package manager low-level tool",category:"package",params:["[-l] [-s pkg] [-L pkg] [-i pkg] [--remove pkg]"],run:({args:e,authUser:t,shell:r})=>{let n=Pt(r);if(!n)return{stderr:"dpkg: package manager not initialised",exitCode:1};let i=y(e,["-l","--list"]),s=y(e,["-s","--status"]),o=y(e,["-L","--listfiles"]),a=y(e,["-r","--remove"]),l=y(e,["-P","--purge"]),{positionals:c}=nt(e,{flags:["-l","--list","-s","--status","-L","--listfiles","-r","--remove","-P","--purge"]});if(i){let u=n.listInstalled();if(u.length===0)return{stdout:["Desired=Unknown/Install/Remove/Purge/Hold","|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend","|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)","||/ Name Version Architecture Description","+++-==============-===============-============-========================================","(no packages installed)"].join(`
|
|
57
|
+
`),exitCode:0};let d=["Desired=Unknown/Install/Remove/Purge/Hold","|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend","|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)","||/ Name Version Architecture Description","+++-==============-===============-============-========================================"],m=u.map(p=>{let S=p.name.padEnd(14).slice(0,14),g=p.version.padEnd(15).slice(0,15),f=p.architecture.padEnd(12).slice(0,12),$=(p.description||"").slice(0,40);return`ii ${S} ${g} ${f} ${$}`});return{stdout:[...d,...m].join(`
|
|
40
58
|
`),exitCode:0}}if(s){let u=c[0];if(!u)return{stderr:"dpkg: -s needs a package name",exitCode:1};let d=n.show(u);return d?{stdout:d,exitCode:0}:{stderr:`dpkg-query: package '${u}' is not installed and no information is available`,exitCode:1}}if(o){let u=c[0];if(!u)return{stderr:"dpkg: -L needs a package name",exitCode:1};let d=n.listInstalled().find(m=>m.name===u);return d?d.files.length===0?{stdout:"/.keep",exitCode:0}:{stdout:d.files.join(`
|
|
41
59
|
`),exitCode:0}:{stderr:`dpkg-query: package '${u}' is not installed`,exitCode:1}}if(a||l){if(t!=="root")return{stderr:"dpkg: error: requested operation requires superuser privilege",exitCode:2};if(c.length===0)return{stderr:"dpkg: error: need an action option",exitCode:2};let{output:u,exitCode:d}=n.remove(c,{purge:l});return{stdout:u||void 0,exitCode:d}}return{stdout:["Usage: dpkg [<option>...] <command>","","Commands:"," -l, --list List packages matching given pattern"," -s, --status <pkg>... Report status of specified package"," -L, --listfiles <pkg>... List files owned by package"," -r, --remove <pkg>... Remove <pkg> but leave its configuration"," -P, --purge <pkg>... Remove <pkg> and its configuration"].join(`
|
|
42
|
-
`),exitCode:0}}},
|
|
60
|
+
`),exitCode:0}}},sr={name:"dpkg-query",description:"Show information about installed packages",category:"package",params:["-W [pkg] | -l [pattern]"],run:({args:e,shell:t})=>{let r=Pt(t);if(!r)return{stderr:"dpkg-query: package manager not initialised",exitCode:1};let n=y(e,["-l"]),i=y(e,["-W","--show"]),{positionals:s}=nt(e,{flags:["-l","-W","--show"]});if(n||i){let o=r.listInstalled(),a=s[0],l=a?o.filter(u=>u.name.includes(a)):o;return i?{stdout:l.map(u=>`${u.name} ${u.version}`).join(`
|
|
43
61
|
`),exitCode:0}:{stdout:l.map(u=>{let d=u.name.padEnd(14).slice(0,14),m=u.version.padEnd(15).slice(0,15);return`ii ${d} ${m} amd64 ${(u.description||"").slice(0,40)}`}).join(`
|
|
44
|
-
`)||"(no packages match)",exitCode:0}}return{stderr:"dpkg-query: need a flag (-l, -W)",exitCode:1}}};var
|
|
45
|
-
`),exitCode:0}}};function
|
|
46
|
-
`).replace(/\\t/g," ").replace(/\\r/g,"\r").replace(/\\\\/g,"\\").replace(/\\a/g,"\x07").replace(/\\b/g,"\b").replace(/\\f/g,"\f").replace(/\\v/g,"\v").replace(/\\0(\d{1,3})/g,(t,
|
|
47
|
-
`,exitCode:0}}};var
|
|
48
|
-
`),exitCode:0}}};var
|
|
49
|
-
`),exitCode:0};for(let
|
|
50
|
-
`),exitCode:0}}};import*as
|
|
51
|
-
`),exitCode:0}}};var
|
|
52
|
-
`),
|
|
53
|
-
|
|
54
|
-
`)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
`),
|
|
62
|
+
`)||"(no packages match)",exitCode:0}}return{stderr:"dpkg-query: need a flag (-l, -W)",exitCode:1}}};var ir={name:"du",description:"Estimate file space usage",category:"system",params:["[-h] [-s] [path]"],run:({shell:e,cwd:t,args:r})=>{let n=y(r,["-h"]),i=y(r,["-s"]),s=r.find(u=>!u.startsWith("-"))??".",o=x(t,s),a=u=>n?`${(u/1024).toFixed(1)}K`:String(Math.ceil(u/1024));if(!e.vfs.exists(o))return{stderr:`du: ${s}: No such file or directory`,exitCode:1};if(i||e.vfs.stat(o).type==="file")return{stdout:`${a(e.vfs.getUsageBytes(o))} ${s}`,exitCode:0};let l=[],c=(u,d)=>{let m=0;for(let p of e.vfs.list(u)){let S=`${u}/${p}`,g=`${d}/${p}`,f=e.vfs.stat(S);f.type==="directory"?m+=c(S,g):(m+=f.size,i||l.push(`${a(f.size)} ${g}`))}return l.push(`${a(m)} ${d}`),m};return c(o,s),{stdout:l.join(`
|
|
63
|
+
`),exitCode:0}}};function Cs(e,t){let r=e.replace(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g,(n,i)=>{let s=t[i];return s!==void 0&&s!==""?s:"0"});if(!/^[\d\s+\-*/%()^!&|<>=,. ]+$/.test(r))return NaN;try{let n=Function(`"use strict"; return (${r.replace(/\*\*/g,"**")});`)();return typeof n=="number"?Math.trunc(n):NaN}catch{return NaN}}function $s(e,t){let r=[],n=0;for(;n<e.length;){let i=e.indexOf("'",n);if(i===-1){r.push(t(e.slice(n)));break}r.push(t(e.slice(n,i)));let s=e.indexOf("'",i+1);if(s===-1){r.push(e.slice(i));break}r.push(e.slice(i,s+1)),n=s+1}return r.join("")}function me(e,t,r=0,n){let i=n??t.HOME??"/home/user";return $s(e,s=>{let o=s;return o=o.replace(/(^|[\s:])~(\/|$)/g,(a,l,c)=>`${l}${i}${c}`),o=o.replace(/\$\?/g,String(r)),o=o.replace(/\$\$/g,"1"),o=o.replace(/\$#/g,"0"),o=o.replace(/\$\(\(([^)]+(?:\([^)]*\)[^)]*)*)\)\)/g,(a,l)=>{let c=Cs(l,t);return Number.isNaN(c)?"0":String(c)}),o=o.replace(/\$\{#([A-Za-z_][A-Za-z0-9_]*)\}/g,(a,l)=>String((t[l]??"").length)),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*):-([^}]*)\}/g,(a,l,c)=>t[l]!==void 0&&t[l]!==""?t[l]:c),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*):=([^}]*)\}/g,(a,l,c)=>((t[l]===void 0||t[l]==="")&&(t[l]=c),t[l])),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*):\+([^}]*)\}/g,(a,l,c)=>t[l]!==void 0&&t[l]!==""?c:""),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(a,l)=>t[l]??""),o=o.replace(/\$([A-Za-z_][A-Za-z0-9_]*)/g,(a,l)=>t[l]??""),o})}async function Ht(e,t,r,n){if(e.includes("$(")){let i="",s=!1,o=0;for(;o<e.length;){let a=e[o];if(a==="'"&&!s){s=!0,i+=a,o++;continue}if(a==="'"&&s){s=!1,i+=a,o++;continue}if(!s&&a==="$"&&e[o+1]==="("){if(e[o+2]==="("){i+=a,o++;continue}let l=0,c=o+1;for(;c<e.length;){if(e[c]==="(")l++;else if(e[c]===")"&&(l--,l===0))break;c++}let u=e.slice(o+2,c).trim(),d=(await n(u)).replace(/\n$/,"");i+=d,o=c+1;continue}i+=a,o++}e=i}return me(e,t,r)}function Ps(e){return e.replace(/\\n/g,`
|
|
64
|
+
`).replace(/\\t/g," ").replace(/\\r/g,"\r").replace(/\\\\/g,"\\").replace(/\\a/g,"\x07").replace(/\\b/g,"\b").replace(/\\f/g,"\f").replace(/\\v/g,"\v").replace(/\\0(\d{1,3})/g,(t,r)=>String.fromCharCode(parseInt(r,8)))}var or={name:"echo",description:"Display text",category:"shell",params:["[-n] [-e] [text...]"],run:({args:e,stdin:t,env:r})=>{let{flags:n,positionals:i}=nt(e,{flags:["-n","-e","-E"]}),s=n.has("-n"),o=n.has("-e"),a=i.length>0?i.join(" "):t??"",l=me(a,r?.vars??{},r?.lastExitCode??0),c=o?Ps(l):l;return{stdout:s?c:`${c}
|
|
65
|
+
`,exitCode:0}}};var ar={name:"env",description:"Print environment variables",category:"shell",params:[],run:({env:e,authUser:t})=>{let r={...e.vars,USER:t,HOME:`/home/${t}`};return{stdout:Object.entries(r).map(([n,i])=>`${n}=${i}`).join(`
|
|
66
|
+
`),exitCode:0}}};var lr={name:"exit",aliases:["bye"],description:"Exit the shell session",category:"shell",params:["[code]"],run:({args:e})=>({closeSession:!0,exitCode:parseInt(e[0]??"0",10)||0})};var cr={name:"export",description:"Set shell environment variable",category:"shell",params:["[VAR=value]"],run:({args:e,env:t})=>{if(e.length===0)return{stdout:Object.entries(t.vars).map(([n,i])=>`declare -x ${n}="${i}"`).join(`
|
|
67
|
+
`),exitCode:0};for(let r of e)if(r.includes("=")){let n=r.indexOf("="),i=r.slice(0,n),s=r.slice(n+1);t.vars[i]=s}return{exitCode:0}}};var ur={name:"find",description:"Search for files",category:"files",params:["[path] [-name <pattern>] [-type f|d]"],run:({authUser:e,shell:t,cwd:r,args:n})=>{let i=st(n,["-name"]),s=st(n,["-type"]),a=n.filter(m=>!m.startsWith("-")&&m!==i&&m!==s)[0]??".",l=x(r,a);try{if(L(e,l,"find"),!t.vfs.exists(l))return{stderr:`find: ${a}: No such file or directory`,exitCode:1}}catch(m){return{stderr:`find: ${m instanceof Error?m.message:String(m)}`,exitCode:1}}let c=i?new RegExp(`^${i.replace(/\./g,"\\.").replace(/\*/g,".*").replace(/\?/g,".")}$`):null,u=[],d=(m,p)=>{let S=t.vfs.stat(m),g=!s||s==="f"&&S.type==="file"||s==="d"&&S.type==="directory",f=!c||c.test(m.split("/").pop()??"");if(g&&f&&u.push(p),S.type==="directory")for(let $ of t.vfs.list(m)){let F=`${m}/${$}`,M=`${p}/${$}`;d(F,M)}};return d(l,a),{stdout:u.join(`
|
|
68
|
+
`),exitCode:0}}};import*as qt from"node:os";var dr={name:"free",description:"Display amount of free and used memory",category:"system",params:["[-h] [-m] [-g]"],run:({args:e})=>{let t=y(e,["-h","--human"]),r=y(e,["-m"]),n=y(e,["-g"]),i=qt.totalmem(),s=qt.freemem(),o=i-s,a=Math.floor(i*.02),l=Math.floor(i*.05),c=Math.floor(s*.95),u=Math.floor(i*.5),d=g=>t?g>=1024*1024*1024?`${(g/(1024*1024*1024)).toFixed(1)}G`:g>=1024*1024?`${(g/(1024*1024)).toFixed(1)}M`:`${(g/1024).toFixed(1)}K`:String(Math.floor(n?g/(1024*1024*1024):r?g/(1024*1024):g/1024)),m=" total used free shared buff/cache available",p=`Mem: ${d(i).padStart(12)} ${d(o).padStart(11)} ${d(s).padStart(11)} ${d(a).padStart(11)} ${d(l).padStart(11)} ${d(c).padStart(11)}`,S=`Swap: ${d(u).padStart(12)} ${d(0).padStart(11)} ${d(u).padStart(11)}`;return{stdout:[m,p,S].join(`
|
|
69
|
+
`),exitCode:0}}};var mr={name:"grep",description:"Search text patterns",category:"text",params:["[-i] [-v] [-n] [-r] <pattern> [file...]"],run:({authUser:e,shell:t,cwd:r,args:n,stdin:i})=>{let{flags:s,positionals:o}=nt(n,{flags:["-i","-v","-n","-r","-c","-l","-L","-q","--quiet","--silent"]}),a=s.has("-i"),l=s.has("-v"),c=s.has("-n"),u=s.has("-r"),d=s.has("-c"),m=s.has("-l"),p=s.has("-q")||s.has("--quiet")||s.has("--silent"),S=o[0],g=o.slice(1);if(!S)return{stderr:"grep: no pattern specified",exitCode:1};let f;try{let w=a?"mi":"m";f=new RegExp(S,w)}catch{return{stderr:`grep: invalid regex: ${S}`,exitCode:1}}let $=(w,k="")=>{let R=w.split(`
|
|
70
|
+
`),b=[];for(let P=0;P<R.length;P++){let V=R[P]??"",C=f.test(V);if(l?!C:C){let N=c?`${P+1}:`:"";b.push(`${k}${N}${V}`)}}return b},F=w=>{if(!t.vfs.exists(w))return[];if(t.vfs.stat(w).type==="file")return[w];if(!u)return[];let R=[],b=P=>{for(let V of t.vfs.list(P)){let C=`${P}/${V}`;t.vfs.stat(C).type==="file"?R.push(C):b(C)}};return b(w),R},M=[];if(g.length===0){if(!i)return{stdout:"",exitCode:1};let w=$(i);if(d)return{stdout:`${w.length}
|
|
71
|
+
`,exitCode:w.length>0?0:1};if(p)return{exitCode:w.length>0?0:1};M.push(...w)}else{let w=g.flatMap(k=>{let R=x(r,k);return F(R).map(b=>({file:k,path:b}))});for(let{file:k,path:R}of w)try{L(e,R,"grep");let b=t.vfs.readFile(R),P=w.length>1?`${k}:`:"",V=$(b,P);d?M.push(w.length>1?`${k}:${V.length}`:String(V.length)):m?V.length>0&&M.push(k):M.push(...V)}catch{return{stderr:`grep: ${k}: No such file or directory`,exitCode:1}}}return{stdout:M.length>0?`${M.join(`
|
|
72
|
+
`)}
|
|
73
|
+
`:"",exitCode:M.length>0?0:1}}};var pr={name:"groups",description:"Print group memberships",category:"system",params:["[user]"],run:({authUser:e,shell:t,args:r})=>{let n=r[0]??e;return{stdout:t.users.isSudoer(n)?`${n} sudo root`:n,exitCode:0}}};var fr={name:"gzip",description:"Compress files",category:"archive",params:["[-k] [-d] <file>"],run:({shell:e,cwd:t,args:r})=>{let n=r.includes("-k")||r.includes("--keep"),i=r.includes("-d"),s=r.find(c=>!c.startsWith("-"));if(!s)return{stderr:`gzip: no file specified
|
|
74
|
+
`,exitCode:1};let o=x(t,s);if(i){if(!s.endsWith(".gz"))return{stderr:`gzip: ${s}: unknown suffix -- ignored
|
|
75
|
+
`,exitCode:1};if(!e.vfs.exists(o))return{stderr:`gzip: ${s}: No such file or directory
|
|
76
|
+
`,exitCode:1};let c=e.vfs.readFile(o),u=o.slice(0,-3);return e.vfs.writeFile(u,c),n||e.vfs.remove(o),{exitCode:0}}if(!e.vfs.exists(o))return{stderr:`gzip: ${s}: No such file or directory
|
|
77
|
+
`,exitCode:1};if(s.endsWith(".gz"))return{stderr:`gzip: ${s}: already has .gz suffix -- unchanged
|
|
78
|
+
`,exitCode:1};let a=e.vfs.readFileRaw(o),l=`${o}.gz`;return e.vfs.writeFile(l,a,{compress:!0}),n||e.vfs.remove(o),{exitCode:0}}},hr={name:"gunzip",description:"Decompress files",category:"archive",aliases:["zcat"],params:["[-k] <file>"],run:({shell:e,cwd:t,args:r})=>{let n=r.includes("-k")||r.includes("--keep"),i=r.find(l=>!l.startsWith("-"));if(!i)return{stderr:`gunzip: no file specified
|
|
79
|
+
`,exitCode:1};let s=x(t,i);if(!e.vfs.exists(s))return{stderr:`gunzip: ${i}: No such file or directory
|
|
80
|
+
`,exitCode:1};if(!i.endsWith(".gz"))return{stderr:`gunzip: ${i}: unknown suffix -- ignored
|
|
81
|
+
`,exitCode:1};let o=e.vfs.readFile(s),a=s.slice(0,-3);return e.vfs.writeFile(a,o),n||e.vfs.remove(s),{exitCode:0}}};var gr={name:"head",description:"Output first lines",category:"text",params:["[-n <lines>] [file...]"],run:({authUser:e,shell:t,cwd:r,args:n,stdin:i})=>{let s=st(n,["-n"]),o=n.find(d=>/^-\d+$/.test(d)),a=typeof s=="string"?parseInt(s,10):o?parseInt(o.slice(1),10):10,l=n.filter(d=>!d.startsWith("-")&&d!==s&&d!==String(a)),c=d=>{let m=d.split(`
|
|
82
|
+
`),p=m.slice(0,a);return p.join(`
|
|
83
|
+
`)+(d.endsWith(`
|
|
84
|
+
`)&&p.length===m.slice(0,a).length?`
|
|
85
|
+
`:"")};if(l.length===0)return{stdout:c(i??""),exitCode:0};let u=[];for(let d of l){let m=x(r,d);try{L(e,m,"head"),u.push(c(t.vfs.readFile(m)))}catch{return{stderr:`head: ${d}: No such file or directory`,exitCode:1}}}return{stdout:u.join(`
|
|
86
|
+
`),exitCode:0}}};var yr=["navigation","files","text","archive","system","package","network","shell","users","misc"],wr={navigation:"Navigation",files:"Files & Filesystem",text:"Text Processing",archive:"Archive & Compression",system:"System",package:"Package Management",network:"Network",shell:"Shell & Scripting",users:"Users & Permissions",misc:"Miscellaneous"},xr="\x1B[1m",dt="\x1B[0m",ks="\x1B[36m",Ms="\x1B[33m",Rt="\x1B[2m",Es="\x1B[32m";function Sr(e,t){return e.length>=t?e:e+" ".repeat(t-e.length)}function As(e){let t=e.aliases?.length?` ${Rt}(${e.aliases.join(", ")})${dt}`:"";return` ${ks}${Sr(e.name,16)}${dt}${t}${Sr("",(e.aliases?.length,0))} ${e.description??""}`}function Fs(e){let t={};for(let s of e){let o=s.category??"misc";t[o]||(t[o]=[]),t[o].push(s)}let r=[`${xr}Available commands${dt}`,`${Rt}Type 'help <command>' for detailed usage.${dt}`,""],n=[...yr.filter(s=>t[s]),...Object.keys(t).filter(s=>!yr.includes(s)).sort()];for(let s of n){let o=t[s];if(!o?.length)continue;r.push(`${Ms}${wr[s]??s}${dt}`);let a=[...o].sort((l,c)=>l.name.localeCompare(c.name));for(let l of a)r.push(As(l));r.push("")}let i=e.length;return r.push(`${Rt}${i} commands available.${dt}`),r.join(`
|
|
87
|
+
`)}function Ns(e){let t=[];if(t.push(`${xr}${e.name}${dt} \u2014 ${e.description??"no description"}`),e.aliases?.length&&t.push(`${Rt}Aliases: ${e.aliases.join(", ")}${dt}`),t.push(""),t.push(`${Es}Usage:${dt}`),e.params.length)for(let n of e.params)t.push(` ${e.name} ${n}`);else t.push(` ${e.name}`);let r=wr[e.category??"misc"]??e.category??"misc";return t.push(""),t.push(`${Rt}Category: ${r}${dt}`),t.join(`
|
|
88
|
+
`)}function br(e){return{name:"help",description:"List all commands, or show usage for a specific command",category:"shell",params:["[command]"],run:({args:t})=>{let r=pe();if(t[0]){let n=t[0].toLowerCase(),i=r.find(s=>s.name===n||s.aliases?.includes(n));return i?{stdout:Ns(i),exitCode:0}:{stderr:`help: no help entry for '${t[0]}'`,exitCode:1}}return{stdout:Fs(r),exitCode:0}}}}var vr={name:"history",description:"Display command history",category:"shell",params:["[n]"],run:({args:e,shell:t})=>{let r="/virtual-env-js/.bash_history";if(!t.vfs.exists(r))return{stdout:"",exitCode:0};let i=t.vfs.readFile(r).split(`
|
|
89
|
+
`).filter(Boolean),s=e[0],o=s?parseInt(s,10):null,a=o&&!Number.isNaN(o)?i.slice(-o):i,l=i.length-a.length+1;return{stdout:a.map((u,d)=>`${String(l+d).padStart(5)} ${u}`).join(`
|
|
90
|
+
`),exitCode:0}}};var Cr={name:"hostname",description:"Print hostname",category:"system",params:[],run:({hostname:e})=>({stdout:e,exitCode:0})};var $r={name:"htop",description:"System monitor",category:"system",params:[],run:({mode:e})=>e==="exec"?{stderr:"htop: interactive terminal required",exitCode:1}:{openHtop:!0,exitCode:0}};var Pr={name:"id",description:"Print user identity",category:"system",params:["[user]"],run:({authUser:e,shell:t,args:r})=>{let n=r[0]??e,i=n==="root"?0:1e3,s=i,a=t.users.isSudoer(n)?`${s}(${n}),0(root)`:`${s}(${n})`;return{stdout:`uid=${i}(${n}) gid=${s}(${n}) groups=${a}`,exitCode:0}}};var kr={name:"kill",description:"Send signal to process",category:"system",params:["[-9] <pid>"],run:({args:e})=>e.find(r=>!r.startsWith("-"))?{stdout:"",exitCode:0}:{stderr:"kill: no pid specified",exitCode:1}};var Mr={name:"ln",description:"Create links",category:"files",params:["[-s] <target> <link_name>"],run:({authUser:e,shell:t,cwd:r,args:n})=>{let i=y(n,["-s","--symbolic"]),s=n.filter(u=>!u.startsWith("-")),[o,a]=s;if(!o||!a)return{stderr:"ln: missing operand",exitCode:1};let l=x(r,a),c=i?o:x(r,o);try{if(L(e,l,"ln"),i)t.vfs.symlink(c,l);else{let u=x(r,o);if(L(e,u,"ln"),!t.vfs.exists(u))return{stderr:`ln: ${o}: No such file or directory`,exitCode:1};let d=t.vfs.readFile(u);t.writeFileAsUser(e,l,d)}return{exitCode:0}}catch(u){return{stderr:`ln: ${u instanceof Error?u.message:String(u)}`,exitCode:1}}}},Er={name:"readlink",description:"Print resolved path of symbolic link",category:"files",params:["[-f] <path>"],run:({shell:e,cwd:t,args:r})=>{let n=r.includes("-f")||r.includes("-e"),i=r.find(a=>!a.startsWith("-"));if(!i)return{stderr:`readlink: missing operand
|
|
91
|
+
`,exitCode:1};let s=x(t,i);return e.vfs.exists(s)?e.vfs.isSymlink(s)?{stdout:`${e.vfs.resolveSymlink(s)}
|
|
92
|
+
`,exitCode:0}:{stderr:`readlink: ${i}: not a symbolic link
|
|
93
|
+
`,exitCode:1}:{stderr:`readlink: ${i}: No such file or directory
|
|
94
|
+
`,exitCode:1}}};var Ar={name:"stat",description:"Display file status",category:"files",params:["[-c <format>] <file>"],run:({shell:e,cwd:t,args:r})=>{let n=r.findIndex($=>$==="-c"||$==="--format"),i=n!==-1?r[n+1]:void 0,s=r.find($=>!$.startsWith("-")&&$!==i);if(!s)return{stderr:`stat: missing operand
|
|
95
|
+
`,exitCode:1};let o=x(t,s);if(!e.vfs.exists(o))return{stderr:`stat: cannot stat '${s}': No such file or directory
|
|
96
|
+
`,exitCode:1};let a=e.vfs.stat(o),l=a.type==="directory",c=e.vfs.isSymlink(o),u=e.vfs.isSymlink(o),d=$=>{let F=[256,128,64,32,16,8,4,2,1],M=["r","w","x","r","w","x","r","w","x"];return(l?"d":u?"l":"-")+F.map((w,k)=>$&w?M[k]:"-").join("")},m=a.mode.toString(8).padStart(4,"0"),p=d(a.mode),S="size"in a?a.size:0,g=$=>$.toISOString().replace("T"," ").replace(/\.\d+Z$/," +0000");return i?{stdout:`${i.replace("%n",s).replace("%s",String(S)).replace("%a",m.slice(1)).replace("%A",p).replace("%F",u?"symbolic link":l?"directory":"regular file").replace("%y",g(a.updatedAt)).replace("%z",g(a.updatedAt))}
|
|
97
|
+
`,exitCode:0}:{stdout:`${[` File: ${s}${u?` -> ${e.vfs.resolveSymlink(o)}`:""}`,` Size: ${S}${" ".repeat(3)}${u?"symbolic link":l?"directory":"regular file"}`,`Access: (${m}/${p}) Uid: ( 0/ root) Gid: ( 0/ root)`,`Modify: ${g(a.updatedAt)}`,`Change: ${g(a.updatedAt)}`].join(`
|
|
98
|
+
`)}
|
|
99
|
+
`,exitCode:0}}};function Fr(e,t){let r=t?"d":"-",i=[[256,"r"],[128,"w"],[64,"x"],[32,"r"],[16,"w"],[8,"x"],[4,"r"],[2,"w"],[1,"x"]].map(([s,o])=>e&s?o:"-").join("");return`${r}${i}`}function Nr(e){return e.toISOString().replace("T"," ").slice(0,16)}var Ir={name:"ls",description:"List directory contents",category:"navigation",params:["[-la] [path]"],run:({authUser:e,shell:t,cwd:r,args:n})=>{let i=y(n,["-l","--long"]),s=y(n,["-a","--all"]),o=wt(n,0,{flags:["-l","--long","-a","--all","-la","-al"]}),a=x(r,o??r);if(L(e,a,"ls"),t.vfs.exists(a)){let u=t.vfs.stat(a);if(u.type==="file"||t.vfs.isSymlink(a)){if(i){let d=a.split("/").pop()??a,m=u.type==="file"?u.size:0;return{stdout:`${Fr(u.mode,!1)} 1 root root ${m} ${Nr(u.updatedAt)} ${d}
|
|
100
|
+
`,exitCode:0}}return{stdout:a.split("/").pop()??a,exitCode:0}}}let l=t.vfs.list(a).filter(u=>s||!u.startsWith("."));return{stdout:i?l.map(u=>{let d=x(a,u),m=t.vfs.stat(d),p=m.type==="file"?m.size:m.childrenCount;return`${Fr(m.mode,m.type==="directory")} 1 ${p} ${Nr(m.updatedAt)} ${u}${m.type==="directory"?"/":""}`}).join(`
|
|
101
|
+
`):Oe(a,l,u=>t.vfs.stat(u)),exitCode:0}}};var Rr={name:"lsb_release",description:"Print distribution-specific information",category:"system",params:["[-a] [-i] [-d] [-r] [-c]"],run:({args:e,shell:t})=>{let r=t.properties?.os??"Fortune GNU/Linux x64",n="aurora",i="1.0";try{let d=t.vfs.readFile("/etc/os-release");for(let m of d.split(`
|
|
102
|
+
`))m.startsWith("PRETTY_NAME=")&&(r=m.slice(12).replace(/^"|"$/g,"").trim()),m.startsWith("VERSION_CODENAME=")&&(n=m.slice(17).trim()),m.startsWith("VERSION_ID=")&&(i=m.slice(11).replace(/^"|"$/g,"").trim())}catch{}let s=y(e,["-a","--all"]),o=y(e,["-i","--id"]),a=y(e,["-d","--description"]),l=y(e,["-r","--release"]),c=y(e,["-c","--codename"]);if(s||e.length===0)return{stdout:["Distributor ID: Fortune",`Description: ${r}`,`Release: ${i}`,`Codename: ${n}`].join(`
|
|
103
|
+
`),exitCode:0};let u=[];return o&&u.push("Distributor ID: Fortune"),a&&u.push(`Description: ${r}`),l&&u.push(`Release: ${i}`),c&&u.push(`Codename: ${n}`),{stdout:u.join(`
|
|
104
|
+
`),exitCode:0}}};var Is={ls:`LS(1) User Commands LS(1)
|
|
65
105
|
|
|
66
106
|
NAME
|
|
67
107
|
ls - list directory contents
|
|
@@ -186,157 +226,169 @@ OPTIONS
|
|
|
186
226
|
-z, --gzip filter the archive through gzip
|
|
187
227
|
-f, --file=ARCHIVE use archive file or device ARCHIVE
|
|
188
228
|
-v, --verbose verbosely list files processed
|
|
189
|
-
-t, --list list the contents of an archive`},
|
|
190
|
-
`)){if(!t.startsWith("PRETTY_NAME="))continue;return t.slice(12).trim().replace(/^"|"$/g,"")}}catch{return}}function
|
|
191
|
-
`)[0]?.trim();return!t||t.length===0?void 0:t}catch{return}}function
|
|
192
|
-
`)}var
|
|
193
|
-
`
|
|
194
|
-
`};case"util":return{format:(...o)=>o.map(ut).join(" "),inspect:o=>ut(o)};case"fs":case"fs/promises":throw new Error(`Cannot require '${s}': filesystem access not available in virtual runtime`);case"child_process":case"net":case"http":case"https":throw new Error(`Cannot require '${s}': not available in virtual runtime`);default:throw new Error(`Cannot find module '${s}'`)}};return i.resolve=s=>{throw new Error(`Cannot resolve '${s}'`)},i.cache={},i.extensions={},jr.createContext({console:n,process:e,require:i,Math,JSON,Object,Array,String,Number,Boolean,Symbol,Date,RegExp,Error,TypeError,RangeError,SyntaxError,Promise,Map,Set,WeakMap,WeakSet,parseInt,parseFloat,isNaN,isFinite,encodeURIComponent,decodeURIComponent,encodeURI,decodeURI,setTimeout:()=>{},clearTimeout:()=>{},setInterval:()=>{},clearInterval:()=>{},queueMicrotask:()=>{},globalThis:void 0,undefined:void 0,Infinity:1/0,NaN:NaN})}var Wt=class{constructor(t){this.code=t}code};function ut(r){if(r===null)return"null";if(r===void 0)return"undefined";if(typeof r=="string")return r;if(typeof r=="function")return`[Function: ${r.name||"(anonymous)"}]`;if(Array.isArray(r))return`[ ${r.map(ut).join(", ")} ]`;if(r instanceof Error)return`${r.name}: ${r.message}`;if(typeof r=="object")try{return`{ ${Object.entries(r).map(([e,n])=>`${e}: ${ut(n)}`).join(", ")} }`}catch{return"[Object]"}return String(r)}function Ht(r){let t=[],e=[],n=Os(t,e),i=0;try{let s=jr.runInContext(r,n,{timeout:5e3});s!==void 0&&t.length===0&&t.push(ut(s))}catch(s){s instanceof Wt?i=s.code:s instanceof Error?(e.push(`${s.name}: ${s.message}`),i=1):(e.push(String(s)),i=1)}return{stdout:t.length?`${t.join(`
|
|
229
|
+
-t, --list list the contents of an archive`},Vr={name:"man",description:"Interface to the system reference manuals",category:"shell",params:["<command>"],run:({args:e,shell:t})=>{let r=e[0];if(!r)return{stderr:"What manual page do you want?",exitCode:1};let n=`/usr/share/man/man1/${r}.1`;if(t.vfs.exists(n))return{stdout:t.vfs.readFile(n),exitCode:0};let i=Is[r.toLowerCase()];return i?{stdout:i,exitCode:0}:{stderr:`No manual entry for ${r}`,exitCode:16}}};var Dr={name:"mkdir",description:"Make directories",category:"files",params:["<dir>"],run:({authUser:e,shell:t,cwd:r,args:n})=>{if(n.length===0)return{stderr:"mkdir: missing operand",exitCode:1};for(let i=0;i<n.length;i++){let s=wt(n,i);if(!s)return{stderr:"mkdir: missing operand",exitCode:1};let o=x(r,s);L(e,o,"mkdir"),t.vfs.mkdir(o)}return{exitCode:0}}};var _r={name:"mv",description:"Move or rename files",category:"files",params:["<source> <dest>"],run:({authUser:e,shell:t,cwd:r,args:n})=>{let i=n.filter(c=>!c.startsWith("-")),[s,o]=i;if(!s||!o)return{stderr:"mv: missing operand",exitCode:1};let a=x(r,s),l=x(r,o);try{if(L(e,a,"mv"),L(e,l,"mv"),!t.vfs.exists(a))return{stderr:`mv: ${s}: No such file or directory`,exitCode:1};let c=t.vfs.exists(l)&&t.vfs.stat(l).type==="directory"?`${l}/${s.split("/").pop()}`:l;return t.vfs.move(a,c),{exitCode:0}}catch(c){return{stderr:`mv: ${c instanceof Error?c.message:String(c)}`,exitCode:1}}}};import*as Lr from"node:path";var Tr={name:"nano",description:"Text editor",category:"files",params:["<file>"],run:({authUser:e,shell:t,cwd:r,args:n})=>{let i=n[0];if(!i)return{stderr:"nano: missing file operand",exitCode:1};let s=x(r,i);L(e,s,"nano");let o=t.vfs.exists(s)?t.vfs.readFile(s):"",a=Lr.posix.basename(s)||"buffer",l=`/tmp/sshmimic-nano-${Date.now()}-${a}.tmp`;return{openEditor:{targetPath:s,tempPath:l,initialContent:o},exitCode:0}}};import{existsSync as Hr,readdirSync as Rs,readFileSync as fe}from"node:fs";import*as tt from"node:os";import*as qr from"node:path";function Vs(e){let t=Math.max(1,Math.floor(e/60)),r=Math.floor(t/1440),n=Math.floor(t%1440/60),i=t%60,s=[];return r>0&&s.push(`${r} day${r>1?"s":""}`),n>0&&s.push(`${n} hour${n>1?"s":""}`),(i>0||s.length===0)&&s.push(`${i} min${i>1?"s":""}`),s.join(", ")}function zr(e){return`\x1B[${e}m \x1B[0m`}function Ds(){let e=[40,41,42,43,44,45,46,47].map(zr).join(""),t=[100,101,102,103,104,105,106,107].map(zr).join("");return[e,t]}function Or(e,t,r){if(e.trim().length===0)return e;let n={r:255,g:255,b:255},i={r:168,g:85,b:247},s=r<=1?0:t/(r-1),o=Math.round(n.r+(i.r-n.r)*s),a=Math.round(n.g+(i.g-n.g)*s),l=Math.round(n.b+(i.b-n.b)*s);return`\x1B[38;2;${o};${a};${l}m${e}\x1B[0m`}function _s(e){if(e.trim().length===0)return e;let t=e.indexOf(":");if(t===-1)return e.includes("@")?Ur(e):e;let r=e.substring(0,t+1),n=e.substring(t+1);return Ur(r)+n}function Ur(e){let t=new RegExp("\x1B\\[[\\d;]*m","g"),r=e.replace(t,"");if(r.trim().length===0)return e;let n={r:255,g:255,b:255},i={r:168,g:85,b:247},s="";for(let o=0;o<r.length;o+=1){let a=r.length<=1?0:o/(r.length-1),l=Math.round(n.r+(i.r-n.r)*a),c=Math.round(n.g+(i.g-n.g)*a),u=Math.round(n.b+(i.b-n.b)*a);s+=`\x1B[38;2;${l};${c};${u}m${r[o]}\x1B[0m`}return s}function Br(e){return Math.max(0,Math.round(e/(1024*1024)))}function Wr(){try{let e=fe("/etc/os-release","utf8");for(let t of e.split(`
|
|
230
|
+
`)){if(!t.startsWith("PRETTY_NAME="))continue;return t.slice(12).trim().replace(/^"|"$/g,"")}}catch{return}}function jr(e){try{let t=fe(e,"utf8").split(`
|
|
231
|
+
`)[0]?.trim();return!t||t.length===0?void 0:t}catch{return}}function Ls(e){let t=jr("/sys/devices/virtual/dmi/id/sys_vendor"),r=jr("/sys/devices/virtual/dmi/id/product_name");return t&&r?`${t} ${r}`:r||e}function Ts(){let e=["/var/lib/dpkg/status","/usr/local/var/lib/dpkg/status"];for(let t of e)if(Hr(t))try{return fe(t,"utf8").match(/^Package:\s+/gm)?.length??0}catch{}}function zs(){let e=["/snap","/var/lib/snapd/snaps"];for(let t of e)if(Hr(t))try{return Rs(t,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}}function Os(){let e=Ts(),t=zs();return e!==void 0&&t!==void 0?`${e} (dpkg), ${t} (snap)`:e!==void 0?`${e} (dpkg)`:t!==void 0?`${t} (snap)`:"n/a"}function Us(){let e=tt.cpus();if(e.length===0)return"unknown";let t=e[0];if(!t)return"unknown";let r=(t.speed/1e3).toFixed(2);return`${t.model} (${e.length}) @ ${r}GHz`}function Bs(e){return!e||e.trim().length===0?"unknown":qr.posix.basename(e.trim())}function Ws(e){let t=tt.totalmem(),r=tt.freemem(),n=Math.max(0,t-r),i=e.shellProps,s=process.uptime();return e.uptimeSeconds===void 0&&(e.uptimeSeconds=Math.round(s)),{user:e.user,host:e.host,osName:i?.os??e.osName??`${Wr()??tt.type()} ${tt.arch()}`,kernel:i?.kernel??e.kernel??tt.release(),uptimeSeconds:e.uptimeSeconds??tt.uptime(),packages:e.packages??Os(),shell:Bs(e.shell),shellProps:e.shellProps??{kernel:e.kernel??tt.release(),os:e.osName??`${Wr()??tt.type()} ${tt.arch()}`,arch:tt.arch()},resolution:e.resolution??"n/a (ssh)",terminal:e.terminal??"unknown",cpu:e.cpu??Us(),gpu:e.gpu??"n/a",memoryUsedMiB:e.memoryUsedMiB??Br(n),memoryTotalMiB:e.memoryTotalMiB??Br(t)}}function Kr(e){let t=Ws(e),r=Vs(t.uptimeSeconds),n=Ds(),i=[" .. .:. "," .::.. .. .. ",". .... ... .. ",": .... .:. .. ",": .:.:........:. .. ",": .. ",". : ",". : ",".. : "," :. .. "," .. .. "," :-. :: "," .:. :. "," ..: ... "," ..: :.. "," :... :...."," .. ...."," . .. "," .:. .: "," :. .. "," ::. .. ","..... ..:... ","...:. .. ",".:...:. ::. .. "," ... ..:::::.. ..:::::::.. "],s=[`${t.user}@${t.host}`,"-------------------------",`OS: ${t.osName}`,`Host: ${Ls(t.host)}`,`Kernel: ${t.kernel}`,`Uptime: ${r}`,`Packages: ${t.packages}`,`Shell: ${t.shell}`,`Resolution: ${t.resolution}`,`Terminal: ${t.terminal}`,`CPU: ${t.cpu}`,`GPU: ${t.gpu}`,`Memory: ${t.memoryUsedMiB}MiB / ${t.memoryTotalMiB}MiB`,"",n[0],n[1]],o=Math.max(i.length,s.length),a=[];for(let l=0;l<o;l+=1){let c=i[l]??"",u=s[l]??"";if(u.length>0){let d=Or(c.padEnd(31," "),l,i.length),m=_s(u);a.push(`${d} ${m}`);continue}a.push(Or(c,l,i.length))}return a.join(`
|
|
232
|
+
`)}var Gr={name:"neofetch",description:"System info display",category:"system",params:["[--off]"],run:({args:e,authUser:t,hostname:r,shell:n,env:i})=>y(e,"--help")?{stdout:"Usage: neofetch [--off]",exitCode:0}:y(e,"--off")?{stdout:`${t}@${r}`,exitCode:0}:{stdout:Kr({user:t,host:r,shell:i.vars.SHELL,shellProps:n.properties,terminal:i.vars.TERM,uptimeSeconds:Math.floor((Date.now()-n.startTime)/1e3),packages:`${n.packageManager?.installedCount()??0} (dpkg)`}),exitCode:0}};import Zr from"node:vm";var Kt="v18.19.0",Jr={node:Kt,npm:"9.2.0",v8:"10.2.154.26-node.22"};function js(e,t){let r={version:Kt,versions:Jr,platform:"linux",arch:"x64",env:{NODE_ENV:"production",HOME:"/root",PATH:"/usr/local/bin:/usr/bin:/bin"},argv:["node"],stdout:{write:s=>(e.push(s),!0)},stderr:{write:s=>(t.push(s),!0)},exit:(s=0)=>{throw new Gt(s)},cwd:()=>"/root",hrtime:()=>[0,0]},n={log:(...s)=>e.push(s.map(mt).join(" ")),error:(...s)=>t.push(s.map(mt).join(" ")),warn:(...s)=>t.push(s.map(mt).join(" ")),info:(...s)=>e.push(s.map(mt).join(" ")),dir:s=>e.push(mt(s))},i=s=>{switch(s){case"path":return{join:(...o)=>o.join("/").replace(/\/+/g,"/"),resolve:(...o)=>`/${o.join("/").replace(/^\/+/,"")}`,dirname:o=>o.split("/").slice(0,-1).join("/")||"/",basename:o=>o.split("/").pop()??"",extname:o=>{let a=o.split("/").pop()??"",l=a.lastIndexOf(".");return l>0?a.slice(l):""},sep:"/",delimiter:":"};case"os":return{platform:()=>"linux",arch:()=>"x64",type:()=>"Linux",hostname:()=>"fortune-vm",homedir:()=>"/root",tmpdir:()=>"/tmp",EOL:`
|
|
233
|
+
`};case"util":return{format:(...o)=>o.map(mt).join(" "),inspect:o=>mt(o)};case"fs":case"fs/promises":throw new Error(`Cannot require '${s}': filesystem access not available in virtual runtime`);case"child_process":case"net":case"http":case"https":throw new Error(`Cannot require '${s}': not available in virtual runtime`);default:throw new Error(`Cannot find module '${s}'`)}};return i.resolve=s=>{throw new Error(`Cannot resolve '${s}'`)},i.cache={},i.extensions={},Zr.createContext({console:n,process:r,require:i,Math,JSON,Object,Array,String,Number,Boolean,Symbol,Date,RegExp,Error,TypeError,RangeError,SyntaxError,Promise,Map,Set,WeakMap,WeakSet,parseInt,parseFloat,isNaN,isFinite,encodeURIComponent,decodeURIComponent,encodeURI,decodeURI,setTimeout:()=>{},clearTimeout:()=>{},setInterval:()=>{},clearInterval:()=>{},queueMicrotask:()=>{},globalThis:void 0,undefined:void 0,Infinity:1/0,NaN:NaN})}var Gt=class{constructor(t){this.code=t}code};function mt(e){if(e===null)return"null";if(e===void 0)return"undefined";if(typeof e=="string")return e;if(typeof e=="function")return`[Function: ${e.name||"(anonymous)"}]`;if(Array.isArray(e))return`[ ${e.map(mt).join(", ")} ]`;if(e instanceof Error)return`${e.name}: ${e.message}`;if(typeof e=="object")try{return`{ ${Object.entries(e).map(([r,n])=>`${r}: ${mt(n)}`).join(", ")} }`}catch{return"[Object]"}return String(e)}function Zt(e){let t=[],r=[],n=js(t,r),i=0;try{let s=Zr.runInContext(e,n,{timeout:5e3});s!==void 0&&t.length===0&&t.push(mt(s))}catch(s){s instanceof Gt?i=s.code:s instanceof Error?(r.push(`${s.name}: ${s.message}`),i=1):(r.push(String(s)),i=1)}return{stdout:t.length?`${t.join(`
|
|
195
234
|
`)}
|
|
196
|
-
`:"",stderr:
|
|
235
|
+
`:"",stderr:r.length?`${r.join(`
|
|
197
236
|
`)}
|
|
198
|
-
`:"",exitCode:i}}function
|
|
199
|
-
`)&&!t.startsWith("const ")&&!t.startsWith("let ")&&!t.startsWith("var ")&&!t.startsWith("function ")&&!t.startsWith("class ")&&!t.startsWith("if ")&&!t.startsWith("for ")&&!t.startsWith("while ")&&!t.startsWith("import ")&&!t.startsWith("//")?
|
|
237
|
+
`:"",exitCode:i}}function Hs(e){let t=e.trim();return!t.includes(`
|
|
238
|
+
`)&&!t.startsWith("const ")&&!t.startsWith("let ")&&!t.startsWith("var ")&&!t.startsWith("function ")&&!t.startsWith("class ")&&!t.startsWith("if ")&&!t.startsWith("for ")&&!t.startsWith("while ")&&!t.startsWith("import ")&&!t.startsWith("//")?Zt(t):Zt(`(async () => { ${e} })()`)}var Yr={name:"node",description:"JavaScript runtime (virtual)",category:"system",params:["[--version] [-e <expr>] [-p <expr>] [file]"],run:({args:e,shell:t,cwd:r})=>{if(!t.packageManager.isInstalled("nodejs"))return{stderr:`bash: node: command not found
|
|
200
239
|
Hint: install it with: apt install nodejs
|
|
201
|
-
`,exitCode:127};if(
|
|
202
|
-
`,exitCode:0};if(
|
|
203
|
-
`,exitCode:0};let n=
|
|
204
|
-
`,exitCode:1};let{stdout:a,stderr:l,exitCode:c}=
|
|
205
|
-
`,exitCode:1};let{stdout:a,stderr:l,exitCode:c}=
|
|
206
|
-
`:void 0),stderr:l||void 0,exitCode:c}}let s=
|
|
207
|
-
`,exitCode:1};let a=t.vfs.readFile(o),{stdout:l,stderr:c,exitCode:u}=
|
|
208
|
-
`),exitCode:0}}};var
|
|
240
|
+
`,exitCode:127};if(y(e,["--version","-v"]))return{stdout:`${Kt}
|
|
241
|
+
`,exitCode:0};if(y(e,["--versions"]))return{stdout:`${JSON.stringify(Jr,null,2)}
|
|
242
|
+
`,exitCode:0};let n=e.findIndex(o=>o==="-e"||o==="--eval");if(n!==-1){let o=e[n+1];if(!o)return{stderr:`node: -e requires an argument
|
|
243
|
+
`,exitCode:1};let{stdout:a,stderr:l,exitCode:c}=Zt(o);return{stdout:a||void 0,stderr:l||void 0,exitCode:c}}let i=e.findIndex(o=>o==="-p"||o==="--print");if(i!==-1){let o=e[i+1];if(!o)return{stderr:`node: -p requires an argument
|
|
244
|
+
`,exitCode:1};let{stdout:a,stderr:l,exitCode:c}=Zt(o);return{stdout:a||(c===0?`
|
|
245
|
+
`:void 0),stderr:l||void 0,exitCode:c}}let s=e.find(o=>!o.startsWith("-"));if(s){let o=x(r,s);if(!t.vfs.exists(o))return{stderr:`node: cannot open file '${s}': No such file or directory
|
|
246
|
+
`,exitCode:1};let a=t.vfs.readFile(o),{stdout:l,stderr:c,exitCode:u}=Hs(a);return{stdout:l||void 0,stderr:c||void 0,exitCode:u}}return{stdout:[`Welcome to Node.js ${Kt}.`,'Type ".exit" to exit the REPL.',"> "].join(`
|
|
247
|
+
`),exitCode:0}}};var Jt="9.2.0",qs="18.19.0",Qr={name:"npm",description:"Node.js package manager (virtual)",category:"system",params:["<command> [args]"],run:({args:e,shell:t})=>{if(!t.packageManager.isInstalled("npm"))return{stderr:`bash: npm: command not found
|
|
209
248
|
Hint: install it with: apt install npm
|
|
210
|
-
`,exitCode:127};if(
|
|
211
|
-
`,exitCode:0};let e
|
|
249
|
+
`,exitCode:127};if(y(e,["--version","-v"]))return{stdout:`${Jt}
|
|
250
|
+
`,exitCode:0};let r=e[0]?.toLowerCase();switch(r){case"version":case"-version":return{stdout:`{ npm: '${Jt}', node: '${qs}', v8: '10.2.154.26' }
|
|
212
251
|
`,exitCode:0};case"install":case"i":case"add":return{stderr:`npm warn: package installation is not available in the virtual runtime.
|
|
213
252
|
npm warn: This environment simulates npm CLI behaviour only.
|
|
214
253
|
`,exitCode:1};case"run":case"exec":case"x":return{stderr:`npm error: script execution is not available in the virtual runtime.
|
|
215
254
|
`,exitCode:1};case"init":return{stdout:`Wrote to /home/user/package.json
|
|
216
|
-
`,exitCode:0};case"list":case"ls":return{stdout:`${
|
|
255
|
+
`,exitCode:0};case"list":case"ls":return{stdout:`${r==="ls"||r==="list"?"virtual-env@1.0.0":""}
|
|
217
256
|
\u2514\u2500\u2500 (empty)
|
|
218
|
-
`,exitCode:0};case"help":case void 0:return{stdout:`${[`npm ${
|
|
257
|
+
`,exitCode:0};case"help":case void 0:return{stdout:`${[`npm ${Jt}`,"","Usage: npm <command>","","Commands:"," install (not available in virtual runtime)"," run (not available in virtual runtime)"," exec (not available in virtual runtime)"," list List installed packages"," version Print versions"," --version Print npm version"].join(`
|
|
219
258
|
`)}
|
|
220
|
-
`,exitCode:0};default:return{stderr:`npm error: unknown command: ${
|
|
221
|
-
`,exitCode:1}}}},
|
|
259
|
+
`,exitCode:0};default:return{stderr:`npm error: unknown command: ${r}
|
|
260
|
+
`,exitCode:1}}}},Xr={name:"npx",description:"Node.js package runner (virtual)",category:"system",params:["<package> [args]"],run:({args:e,shell:t})=>t.packageManager.isInstalled("npm")?y(e,["--version"])?{stdout:`${Jt}
|
|
222
261
|
`,exitCode:0}:{stderr:`npx: package execution is not available in the virtual runtime.
|
|
223
262
|
`,exitCode:1}:{stderr:`bash: npx: command not found
|
|
224
263
|
Hint: install it with: apt install npm
|
|
225
|
-
`,exitCode:127}};var
|
|
226
|
-
`)
|
|
227
|
-
`,
|
|
228
|
-
`),exitCode:0}}let
|
|
229
|
-
|
|
230
|
-
`
|
|
231
|
-
`
|
|
264
|
+
`,exitCode:127}};var tn={name:"passwd",description:"Change user password",category:"users",params:["[username]"],run:async({authUser:e,args:t,shell:r,stdin:n})=>{let i=t[0]??e;if(e!=="root"&&e!==i)return{stderr:"passwd: permission denied",exitCode:1};if(!r.users.listUsers().includes(i))return{stderr:`passwd: user '${i}' does not exist`,exitCode:1};if(n!==void 0&&n.trim().length>0){let s=n.trim().split(`
|
|
265
|
+
`)[0];return await r.users.setPassword(i,s),{stdout:`passwd: password updated successfully
|
|
266
|
+
`,exitCode:0}}return{passwordChallenge:{prompt:"New password: ",confirmPrompt:"Retype new password: ",action:"passwd",targetUsername:i},exitCode:0}}};var en={name:"ping",description:"Send ICMP ECHO_REQUEST (mock)",category:"network",params:["[-c <count>] <host>"],run:({args:e})=>{let{flagsWithValues:t,positionals:r}=nt(e,{flagsWithValue:["-c","-i","-W"]}),n=r[0]??"localhost",i=t.get("-c"),s=i?Math.max(1,parseInt(i,10)||4):4,o=[`PING ${n}: 56 data bytes`];for(let a=0;a<s;a++){let l=(Math.random()*10+1).toFixed(3);o.push(`64 bytes from ${n}: icmp_seq=${a} ttl=64 time=${l} ms`)}return o.push(`--- ${n} ping statistics ---`),o.push(`${s} packets transmitted, ${s} received, 0% packet loss`),{stdout:o.join(`
|
|
267
|
+
`),exitCode:0}}};function Ks(e,t){let r=0,n="",i=0;for(;i<e.length;){if(e[i]==="\\"&&i+1<e.length)switch(e[i+1]){case"n":n+=`
|
|
268
|
+
`,i+=2;continue;case"t":n+=" ",i+=2;continue;case"r":n+="\r",i+=2;continue;case"\\":n+="\\",i+=2;continue;case"a":n+="\x07",i+=2;continue;case"b":n+="\b",i+=2;continue;case"f":n+="\f",i+=2;continue;case"v":n+="\v",i+=2;continue;default:n+=e[i],i++;continue}if(e[i]==="%"&&i+1<e.length){let s=i+1,o=!1;e[s]==="-"&&(o=!0,s++);let a=!1;e[s]==="0"&&(a=!0,s++);let l=0;for(;s<e.length&&/\d/.test(e[s]);)l=l*10+parseInt(e[s],10),s++;let c=-1;if(e[s]===".")for(s++,c=0;s<e.length&&/\d/.test(e[s]);)c=c*10+parseInt(e[s],10),s++;let u=e[s],d=t[r++]??"",m=(p,S=" ")=>{if(l<=0||p.length>=l)return p;let g=S.repeat(l-p.length);return o?p+g:g+p};switch(u){case"s":{let p=String(d);c>=0&&(p=p.slice(0,c)),n+=m(p);break}case"d":case"i":n+=m(String(parseInt(d,10)||0),a?"0":" ");break;case"f":{let p=c>=0?c:6;n+=m((parseFloat(d)||0).toFixed(p));break}case"o":n+=m((parseInt(d,10)||0).toString(8),a?"0":" ");break;case"x":n+=m((parseInt(d,10)||0).toString(16),a?"0":" ");break;case"X":n+=m((parseInt(d,10)||0).toString(16).toUpperCase(),a?"0":" ");break;case"%":n+="%",r--;break;default:n+=e[i],i++;continue}i=s+1;continue}n+=e[i],i++}return n}var rn={name:"printf",description:"Format and print data",category:"shell",params:["<format> [args...]"],run:({args:e})=>{let t=e[0];return t?{stdout:Ks(t,e.slice(1)),exitCode:0}:{stderr:"printf: missing format string",exitCode:1}}};var nn={name:"ps",description:"Report process status",category:"system",params:["[-a] [-u] [-x] [aux]"],run:({authUser:e,shell:t,args:r})=>{let n=t.users.listActiveSessions(),i=y(r,["-u"])||r.includes("u")||r.includes("aux")||r.includes("au"),s=y(r,["-a","-x"])||r.includes("a")||r.includes("aux");if(i){let u=["USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND"],d=1e3;for(let m of n){let p=m.username.padEnd(10).slice(0,10),S=(Math.random()*.5).toFixed(1),g=Math.floor(Math.random()*2e4+5e3),f=Math.floor(Math.random()*5e3+1e3);u.push(`${p} ${String(d).padStart(6)} 0.0 ${S.padStart(4)} ${String(g).padStart(6)} ${String(f).padStart(5)} ${m.tty.padEnd(8)} Ss 00:00 0:00 bash`),d++}return u.push(`root ${String(d).padStart(6)} 0.0 0.0 0 0 ? S 00:00 0:00 ps`),{stdout:u.join(`
|
|
269
|
+
`),exitCode:0}}let a=[" PID TTY TIME CMD"],l=1e3;for(let c of n)!s&&c.username!==e||(a.push(`${String(l).padStart(5)} ${c.tty.padEnd(12)} 00:00:00 ${c.username===e?"bash":`bash (${c.username})`}`),l++);return a.push(`${String(l).padStart(5)} pts/0 00:00:00 ps`),{stdout:a.join(`
|
|
270
|
+
`),exitCode:0}}};var sn={name:"pwd",description:"Print working directory",category:"navigation",params:[],run:({cwd:e})=>({stdout:e,exitCode:0})};var Gs="Python 3.11.2";var Yt="3.11.2 (default, Mar 13 2023, 12:18:29) [GCC 12.2.0]",h={__pytype__:"none"};function j(e=[]){return{__pytype__:"dict",data:new Map(e)}}function he(e,t,r=1){return{__pytype__:"range",start:e,stop:t,step:r}}function B(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.__pytype__==="dict"}function Mt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.__pytype__==="range"}function pt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.__pytype__==="func"}function ge(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.__pytype__==="class"}function Vt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.__pytype__==="instance"}function St(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.__pytype__==="none"}function Y(e){return e===null||St(e)?"None":e===!0?"True":e===!1?"False":typeof e=="number"?Number.isInteger(e)?String(e):e.toPrecision(12).replace(/\.?0+$/,""):typeof e=="string"?`'${e.replace(/'/g,"\\'")}'`:Array.isArray(e)?`[${e.map(Y).join(", ")}]`:B(e)?`{${[...e.data.entries()].map(([t,r])=>`'${t}': ${Y(r)}`).join(", ")}}`:Mt(e)?`range(${e.start}, ${e.stop}${e.step!==1?`, ${e.step}`:""})`:pt(e)?`<function ${e.name} at 0x...>`:ge(e)?`<class '${e.name}'>`:Vt(e)?`<${e.cls.name} object at 0x...>`:String(e)}function I(e){return e===null||St(e)?"None":e===!0?"True":e===!1?"False":typeof e=="number"?Number.isInteger(e)?String(e):e.toPrecision(12).replace(/\.?0+$/,""):typeof e=="string"?e:Array.isArray(e)?`[${e.map(Y).join(", ")}]`:B(e)?`{${[...e.data.entries()].map(([t,r])=>`'${t}': ${Y(r)}`).join(", ")}}`:Mt(e)?`range(${e.start}, ${e.stop}${e.step!==1?`, ${e.step}`:""})`:Y(e)}function ot(e){return e===null||St(e)?!1:typeof e=="boolean"?e:typeof e=="number"?e!==0:typeof e=="string"||Array.isArray(e)?e.length>0:B(e)?e.data.size>0:Mt(e)?an(e)>0:!0}function an(e){if(e.step===0)return 0;let t=Math.ceil((e.stop-e.start)/e.step);return Math.max(0,t)}function Zs(e){let t=[];for(let r=e.start;(e.step>0?r<e.stop:r>e.stop)&&(t.push(r),!(t.length>1e4));r+=e.step);return t}function J(e){if(Array.isArray(e))return e;if(typeof e=="string")return[...e];if(Mt(e))return Zs(e);if(B(e))return[...e.data.keys()];throw new W("TypeError",`'${vt(e)}' object is not iterable`)}function vt(e){return e===null||St(e)?"NoneType":typeof e=="boolean"?"bool":typeof e=="number"?Number.isInteger(e)?"int":"float":typeof e=="string"?"str":Array.isArray(e)?"list":B(e)?"dict":Mt(e)?"range":pt(e)?"function":ge(e)?"type":Vt(e)?e.cls.name:"object"}var W=class{constructor(t,r){this.type=t;this.message=r}type;message;toString(){return`${this.type}: ${this.message}`}},kt=class{constructor(t){this.value=t}value},Dt=class{},_t=class{},Lt=class{constructor(t){this.code=t}code};function Js(e){let t=new Map,r=j([["sep","/"],["linesep",`
|
|
271
|
+
`],["curdir","."],["pardir",".."]]);return r.__methods__={getcwd:()=>e,getenv:n=>typeof n=="string"?process.env[n]??h:h,path:j([["join",h],["exists",h],["dirname",h],["basename",h]]),listdir:()=>[]},t.set("__builtins__",h),t.set("__name__","__main__"),t.set("__cwd__",e),t}function Ys(e){let t=j([["sep","/"],["curdir","."]]),r=j([["sep","/"],["linesep",`
|
|
272
|
+
`],["name","posix"]]);return r._cwd=e,t._cwd=e,r.path=t,r}function Qs(){return j([["version",Yt],["version_info",j([["major",3],["minor",11],["micro",2]].map(([e,t])=>[e,t]))],["platform","linux"],["executable","/usr/bin/python3"],["prefix","/usr"],["path",["/usr/lib/python3.11","/usr/lib/python3.11/lib-dynload"]],["argv",[""]],["maxsize",9007199254740991]])}function Xs(){return j([["pi",Math.PI],["e",Math.E],["tau",Math.PI*2],["inf",1/0],["nan",NaN],["sqrt",h],["floor",h],["ceil",h],["log",h],["pow",h],["sin",h],["cos",h],["tan",h],["fabs",h],["factorial",h]])}function ti(){return j([["dumps",h],["loads",h]])}function ei(){return j([["match",h],["search",h],["findall",h],["sub",h],["split",h],["compile",h]])}var on={os:Ys,sys:()=>Qs(),math:()=>Xs(),json:()=>ti(),re:()=>ei(),random:()=>j([["random",h],["randint",h],["choice",h],["shuffle",h]]),time:()=>j([["time",h],["sleep",h],["ctime",h]]),datetime:()=>j([["datetime",h],["date",h],["timedelta",h]]),collections:()=>j([["Counter",h],["defaultdict",h],["OrderedDict",h]]),itertools:()=>j([["chain",h],["product",h],["combinations",h],["permutations",h]]),functools:()=>j([["reduce",h],["partial",h],["lru_cache",h]]),string:()=>j([["ascii_letters","abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"],["digits","0123456789"],["punctuation","!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"]])},Qt=class{constructor(t){this.cwd=t}cwd;output=[];stderr=[];modules=new Map;getOutput(){return this.output.join(`
|
|
232
273
|
`)+(this.output.length?`
|
|
233
274
|
`:"")}getStderr(){return this.stderr.join(`
|
|
234
275
|
`)+(this.stderr.length?`
|
|
235
|
-
`:"")}splitArgs(t){let
|
|
236
|
-
`).replace(/\\t/g," ").replace(/\\r/g,"\r").replace(/\\\\/g,"\\").replace(/\\'/g,"'").replace(/\\"/g,'"');let n=t.match(/^f(['"])([\s\S]*)\1$/);if(n){let c=n[2];return c=c.replace(/\{([^{}]+)\}/g,(u,d)=>{try{return
|
|
237
|
-
`);case"join":return
|
|
238
|
-
`.replace(/\\n/g,"")),
|
|
239
|
-
`);this.execLines(n,0,
|
|
276
|
+
`:"")}splitArgs(t){let r=[],n=0,i="",s=!1,o="";for(let a=0;a<t.length;a++){let l=t[a];s?(i+=l,l===o&&t[a-1]!=="\\"&&(s=!1)):l==='"'||l==="'"?(s=!0,o=l,i+=l):"([{".includes(l)?(n++,i+=l):")]}".includes(l)?(n--,i+=l):l===","&&n===0?(r.push(i.trim()),i=""):i+=l}return i.trim()&&r.push(i.trim()),r}pyEval(t,r){if(t=t.trim(),!t||t==="None")return h;if(t==="True")return!0;if(t==="False")return!1;if(t==="...")return h;if(/^-?\d+$/.test(t))return parseInt(t,10);if(/^-?\d+\.\d*$/.test(t))return parseFloat(t);if(/^0x[0-9a-fA-F]+$/.test(t))return parseInt(t,16);if(/^0o[0-7]+$/.test(t))return parseInt(t.slice(2),8);if(/^('''[\s\S]*'''|"""[\s\S]*""")$/.test(t))return t.slice(3,-3);if(/^(['"])(.*)\1$/s.test(t))return t.slice(1,-1).replace(/\\n/g,`
|
|
277
|
+
`).replace(/\\t/g," ").replace(/\\r/g,"\r").replace(/\\\\/g,"\\").replace(/\\'/g,"'").replace(/\\"/g,'"');let n=t.match(/^f(['"])([\s\S]*)\1$/);if(n){let c=n[2];return c=c.replace(/\{([^{}]+)\}/g,(u,d)=>{try{return I(this.pyEval(d.trim(),r))}catch{return`{${d}}`}}),c}let i=t.match(/^b(['"])(.*)\1$/s);if(i)return i[2];if(t.startsWith("[")&&t.endsWith("]")){let c=t.slice(1,-1).trim();if(!c)return[];let u=c.match(/^(.+?)\s+for\s+(\w+)\s+in\s+(.+?)(?:\s+if\s+(.+))?$/);if(u){let[,d,m,p,S]=u,g=J(this.pyEval(p.trim(),r)),f=[];for(let $ of g){let F=new Map(r);F.set(m,$),!(S&&!ot(this.pyEval(S,F)))&&f.push(this.pyEval(d.trim(),F))}return f}return this.splitArgs(c).map(d=>this.pyEval(d,r))}if(t.startsWith("(")&&t.endsWith(")")){let c=t.slice(1,-1).trim();if(!c)return[];let u=this.splitArgs(c);return u.length===1&&!c.endsWith(",")?this.pyEval(u[0],r):u.map(d=>this.pyEval(d,r))}if(t.startsWith("{")&&t.endsWith("}")){let c=t.slice(1,-1).trim();if(!c)return j();let u=j();for(let d of this.splitArgs(c)){let m=d.indexOf(":");if(m===-1)continue;let p=I(this.pyEval(d.slice(0,m).trim(),r)),S=this.pyEval(d.slice(m+1).trim(),r);u.data.set(p,S)}return u}let s=t.match(/^not\s+(.+)$/);if(s)return!ot(this.pyEval(s[1],r));let o=[["or"],["and"],["in","not in","is not","is","==","!=","<=",">=","<",">"],["+","-"],["**"],["*","//","/","%"]];for(let c of o){let u=this.tryBinaryOp(t,c,r);if(u!==void 0)return u}if(t.startsWith("-")){let c=this.pyEval(t.slice(1),r);if(typeof c=="number")return-c}if(process.env.PY_DEBUG&&console.error("eval:",JSON.stringify(t)),t.endsWith("]")&&!t.startsWith("[")){let c=this.findMatchingBracket(t,"[");if(c!==-1){let u=this.pyEval(t.slice(0,c),r),d=t.slice(c+1,-1);return this.subscript(u,d,r)}}let a=t.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*\(([\s\S]*)\)$/);if(a){let[,c,u]=a,d=(u?.trim()?this.splitArgs(u):[]).map(m=>this.pyEval(m,r));return this.callBuiltin(c,d,r)}let l=this.findDotAccess(t);if(l){let{objExpr:c,attr:u,callPart:d}=l,m=this.pyEval(c,r);if(d!==void 0){let p=d.slice(1,-1),S=p.trim()?this.splitArgs(p).map(g=>this.pyEval(g,r)):[];return this.callMethod(m,u,S,r)}return this.getAttr(m,u,r)}if(/^[A-Za-z_][A-Za-z0-9_]*$/.test(t)){if(r.has(t))return r.get(t);throw new W("NameError",`name '${t}' is not defined`)}if(/^[A-Za-z_][A-Za-z0-9_.]+$/.test(t)){let c=t.split("."),u=r.get(c[0])??(()=>{throw new W("NameError",`name '${c[0]}' is not defined`)})();for(let d of c.slice(1))u=this.getAttr(u,d,r);return u}return h}findMatchingBracket(t,r){let n=r==="["?"]":r==="("?")":"}",i=0;for(let s=t.length-1;s>=0;s--)if(t[s]===n&&i++,t[s]===r&&(i--,i===0))return s;return-1}findDotAccess(t){let r=0,n=!1,i="";for(let s=t.length-1;s>0;s--){let o=t[s];if(n){o===i&&t[s-1]!=="\\"&&(n=!1);continue}if(o==='"'||o==="'"){n=!0,i=o;continue}if(")]}".includes(o)){r++;continue}if("([{".includes(o)){r--;continue}if(r!==0||o!==".")continue;let a=t.slice(0,s).trim(),c=t.slice(s+1).match(/^(\w+)(\([\s\S]*\))?$/);if(c&&!/^-?\d+$/.test(a))return{objExpr:a,attr:c[1],callPart:c[2]}}return null}tryBinaryOp(t,r,n){let i=0,s=!1,o="";for(let a=t.length-1;a>=0;a--){let l=t[a];if(s){l===o&&t[a-1]!=="\\"&&(s=!1);continue}if(l==='"'||l==="'"){s=!0,o=l;continue}if(")]}".includes(l)){i++;continue}if("([{".includes(l)){i--;continue}if(i===0){for(let c of r)if(t.slice(a,a+c.length)===c){if(c==="*"&&(t[a+1]==="*"||t[a-1]==="*"))continue;let u=t[a-1],d=t[a+c.length];if(/^[a-z]/.test(c)&&(u&&/\w/.test(u)||d&&/\w/.test(d)))continue;let p=t.slice(0,a).trim(),S=t.slice(a+c.length).trim();if(!p||!S)continue;return this.applyBinaryOp(c,p,S,n)}}}}applyBinaryOp(t,r,n,i){if(t==="and"){let a=this.pyEval(r,i);return ot(a)?this.pyEval(n,i):a}if(t==="or"){let a=this.pyEval(r,i);return ot(a)?a:this.pyEval(n,i)}let s=this.pyEval(r,i),o=this.pyEval(n,i);switch(t){case"+":return typeof s=="string"&&typeof o=="string"?s+o:Array.isArray(s)&&Array.isArray(o)?[...s,...o]:s+o;case"-":return s-o;case"*":if(typeof s=="string"&&typeof o=="number")return s.repeat(o);if(Array.isArray(s)&&typeof o=="number"){let a=[];for(let l=0;l<o;l++)a.push(...s);return a}return s*o;case"/":{if(o===0)throw new W("ZeroDivisionError","division by zero");return s/o}case"//":{if(o===0)throw new W("ZeroDivisionError","integer division or modulo by zero");return Math.floor(s/o)}case"%":{if(typeof s=="string")return this.pyStringFormat(s,Array.isArray(o)?o:[o]);if(o===0)throw new W("ZeroDivisionError","integer division or modulo by zero");return s%o}case"**":return s**o;case"==":return Y(s)===Y(o)||s===o;case"!=":return Y(s)!==Y(o)&&s!==o;case"<":return s<o;case"<=":return s<=o;case">":return s>o;case">=":return s>=o;case"in":return this.pyIn(o,s);case"not in":return!this.pyIn(o,s);case"is":return s===o||St(s)&&St(o);case"is not":return!(s===o||St(s)&&St(o))}return h}pyIn(t,r){return typeof t=="string"?typeof r=="string"&&t.includes(r):Array.isArray(t)?t.some(n=>Y(n)===Y(r)):B(t)?t.data.has(I(r)):!1}subscript(t,r,n){if(r.includes(":")){let s=r.split(":").map(l=>l.trim()),o=s[0]?this.pyEval(s[0],n):void 0,a=s[1]?this.pyEval(s[1],n):void 0;return typeof t=="string"||Array.isArray(t)?t.slice(o,a):h}let i=this.pyEval(r,n);if(Array.isArray(t)){let s=i;return s<0&&(s=t.length+s),t[s]??h}if(typeof t=="string"){let s=i;return s<0&&(s=t.length+s),t[s]??h}if(B(t))return t.data.get(I(i))??h;throw new W("TypeError",`'${vt(t)}' is not subscriptable`)}getAttr(t,r,n){return B(t)?t.data.has(r)?t.data.get(r):r==="path"&&t.path?t.path:h:Vt(t)?t.attrs.get(r)??h:typeof t=="string"?{__class__:{__pytype__:"class",name:"str"}}[r]??h:h}callMethod(t,r,n,i){if(typeof t=="string")switch(r){case"upper":return t.toUpperCase();case"lower":return t.toLowerCase();case"strip":return(n[0]?t.replace(new RegExp(`[${n[0]}]+`,"g"),""):t).trim();case"lstrip":return t.trimStart();case"rstrip":return t.trimEnd();case"split":return t.split(typeof n[0]=="string"?n[0]:/\s+/).filter((s,o)=>o>0||s!=="");case"splitlines":return t.split(`
|
|
278
|
+
`);case"join":return J(n[0]??[]).map(I).join(t);case"replace":return t.replaceAll(I(n[0]??""),I(n[1]??""));case"startswith":return t.startsWith(I(n[0]??""));case"endswith":return t.endsWith(I(n[0]??""));case"find":return t.indexOf(I(n[0]??""));case"index":{let s=t.indexOf(I(n[0]??""));if(s===-1)throw new W("ValueError","substring not found");return s}case"count":return t.split(I(n[0]??"")).length-1;case"format":return this.pyStringFormat(t,n);case"encode":return t;case"decode":return t;case"isdigit":return/^\d+$/.test(t);case"isalpha":return/^[a-zA-Z]+$/.test(t);case"isalnum":return/^[a-zA-Z0-9]+$/.test(t);case"isspace":return/^\s+$/.test(t);case"isupper":return t===t.toUpperCase()&&t!==t.toLowerCase();case"islower":return t===t.toLowerCase()&&t!==t.toUpperCase();case"center":{let s=n[0]??0,o=I(n[1]??" ");return t.padStart(Math.floor((s+t.length)/2),o).padEnd(s,o)}case"ljust":return t.padEnd(n[0]??0,I(n[1]??" "));case"rjust":return t.padStart(n[0]??0,I(n[1]??" "));case"zfill":return t.padStart(n[0]??0,"0");case"title":return t.replace(/\b\w/g,s=>s.toUpperCase());case"capitalize":return t[0]?.toUpperCase()+t.slice(1).toLowerCase();case"swapcase":return[...t].map(s=>s===s.toUpperCase()?s.toLowerCase():s.toUpperCase()).join("")}if(Array.isArray(t))switch(r){case"append":return t.push(n[0]??h),h;case"extend":for(let s of J(n[0]??[]))t.push(s);return h;case"insert":return t.splice(n[0]??0,0,n[1]??h),h;case"pop":{let s=n[0]!==void 0?n[0]:-1,o=s<0?t.length+s:s;return t.splice(o,1)[0]??h}case"remove":{let s=t.findIndex(o=>Y(o)===Y(n[0]??h));return s!==-1&&t.splice(s,1),h}case"index":{let s=t.findIndex(o=>Y(o)===Y(n[0]??h));if(s===-1)throw new W("ValueError","is not in list");return s}case"count":return t.filter(s=>Y(s)===Y(n[0]??h)).length;case"sort":return t.sort((s,o)=>typeof s=="number"&&typeof o=="number"?s-o:I(s).localeCompare(I(o))),h;case"reverse":return t.reverse(),h;case"copy":return[...t];case"clear":return t.splice(0),h}if(B(t))switch(r){case"keys":return[...t.data.keys()];case"values":return[...t.data.values()];case"items":return[...t.data.entries()].map(([s,o])=>[s,o]);case"get":return t.data.get(I(n[0]??""))??n[1]??h;case"update":{if(B(n[0]??h))for(let[s,o]of n[0].data)t.data.set(s,o);return h}case"pop":{let s=I(n[0]??""),o=t.data.get(s)??n[1]??h;return t.data.delete(s),o}case"clear":return t.data.clear(),h;case"copy":return j([...t.data.entries()]);case"setdefault":{let s=I(n[0]??"");return t.data.has(s)||t.data.set(s,n[1]??h),t.data.get(s)??h}}if(B(t)&&t.data.has("name")&&t.data.get("name")==="posix")switch(r){case"getcwd":return this.cwd;case"getenv":return typeof n[0]=="string"?process.env[n[0]]??n[1]??h:h;case"listdir":return[];case"path":return t}if(B(t))switch(r){case"join":return n.map(I).join("/").replace(/\/+/g,"/");case"exists":return!1;case"dirname":return I(n[0]??"").split("/").slice(0,-1).join("/")||"/";case"basename":return I(n[0]??"").split("/").pop()??"";case"abspath":return I(n[0]??"");case"splitext":{let s=I(n[0]??""),o=s.lastIndexOf(".");return o>0?[s.slice(0,o),s.slice(o)]:[s,""]}case"isfile":return!1;case"isdir":return!1}if(B(t)&&t.data.has("version")&&t.data.get("version")===Yt&&r==="exit")throw new Lt(n[0]??0);if(B(t)){let s={sqrt:Math.sqrt,floor:Math.floor,ceil:Math.ceil,fabs:Math.abs,log:Math.log,log2:Math.log2,log10:Math.log10,sin:Math.sin,cos:Math.cos,tan:Math.tan,asin:Math.asin,acos:Math.acos,atan:Math.atan,atan2:Math.atan2,pow:Math.pow,exp:Math.exp,hypot:Math.hypot};if(r in s){let o=s[r];return o(...n.map(a=>a))}if(r==="factorial"){let o=n[0]??0,a=1;for(;o>1;)a*=o--;return a}if(r==="gcd"){let o=Math.abs(n[0]??0),a=Math.abs(n[1]??0);for(;a;)[o,a]=[a,o%a];return o}}if(B(t)){if(r==="dumps"){let s=B(n[1]??h)?n[1]:void 0,o=s?s.data.get("indent"):void 0;return JSON.stringify(this.pyToJs(n[0]??h),null,o)}if(r==="loads")return this.jsToPy(JSON.parse(I(n[0]??"")))}if(Vt(t)){let s=t.attrs.get(r)??t.cls.methods.get(r)??h;if(pt(s)){let o=new Map(s.closure);return o.set("self",t),s.params.slice(1).forEach((a,l)=>o.set(a,n[l]??h)),this.execBlock(s.body,o)}}throw new W("AttributeError",`'${vt(t)}' object has no attribute '${r}'`)}pyStringFormat(t,r){let n=0;return t.replace(/%([diouxXeEfFgGcrs%])/g,(i,s)=>{if(s==="%")return"%";let o=r[n++];switch(s){case"d":case"i":return String(Math.trunc(o));case"f":return o.toFixed(6);case"s":return I(o??h);case"r":return Y(o??h);default:return String(o)}})}pyToJs(t){return St(t)?null:B(t)?Object.fromEntries([...t.data.entries()].map(([r,n])=>[r,this.pyToJs(n)])):Array.isArray(t)?t.map(r=>this.pyToJs(r)):t}jsToPy(t){return t==null?h:typeof t=="boolean"||typeof t=="number"||typeof t=="string"?t:Array.isArray(t)?t.map(r=>this.jsToPy(r)):typeof t=="object"?j(Object.entries(t).map(([r,n])=>[r,this.jsToPy(n)])):h}callBuiltin(t,r,n){if(n.has(t)){let i=n.get(t)??h;return pt(i)?this.callFunc(i,r,n):ge(i)?this.instantiate(i,r,n):i}switch(t){case"print":return this.output.push(r.map(I).join(" ")+`
|
|
279
|
+
`.replace(/\\n/g,"")),h;case"input":return this.output.push(I(r[0]??"")),"";case"int":{if(r.length===0)return 0;let i=r[1]??10,s=parseInt(I(r[0]??0),i);return Number.isNaN(s)?(()=>{throw new W("ValueError","invalid literal for int()")})():s}case"float":{if(r.length===0)return 0;let i=parseFloat(I(r[0]??0));return Number.isNaN(i)?(()=>{throw new W("ValueError","could not convert to float")})():i}case"str":return r.length===0?"":I(r[0]??h);case"bool":return r.length===0?!1:ot(r[0]??h);case"list":return r.length===0?[]:J(r[0]??[]);case"tuple":return r.length===0?[]:J(r[0]??[]);case"set":return r.length===0?[]:[...new Set(J(r[0]??[]).map(Y))].map(i=>J(r[0]??[]).find(o=>Y(o)===i)??h);case"dict":return r.length===0?j():B(r[0]??h)?r[0]:j();case"bytes":return typeof r[0]=="string"?r[0]:I(r[0]??"");case"bytearray":return r.length===0?"":I(r[0]??"");case"type":return r.length===1?`<class '${vt(r[0]??h)}'>`:h;case"isinstance":return vt(r[0]??h)===I(r[1]??"");case"issubclass":return!1;case"callable":return pt(r[0]??h);case"hasattr":return B(r[0]??h)?r[0].data.has(I(r[1]??"")):!1;case"getattr":return B(r[0]??h)?r[0].data.get(I(r[1]??""))??r[2]??h:r[2]??h;case"setattr":return B(r[0]??h)&&r[0].data.set(I(r[1]??""),r[2]??h),h;case"len":{let i=r[0]??h;if(typeof i=="string"||Array.isArray(i))return i.length;if(B(i))return i.data.size;if(Mt(i))return an(i);throw new W("TypeError",`object of type '${vt(i)}' has no len()`)}case"range":return r.length===1?he(0,r[0]):r.length===2?he(r[0],r[1]):he(r[0],r[1],r[2]);case"enumerate":{let i=r[1]??0;return J(r[0]??[]).map((s,o)=>[o+i,s])}case"zip":{let i=r.map(J),s=Math.min(...i.map(o=>o.length));return Array.from({length:s},(o,a)=>i.map(l=>l[a]??h))}case"map":{let i=r[0]??h;return J(r[1]??[]).map(s=>pt(i)?this.callFunc(i,[s],n):h)}case"filter":{let i=r[0]??h;return J(r[1]??[]).filter(s=>pt(i)?ot(this.callFunc(i,[s],n)):ot(s))}case"reduce":{let i=r[0]??h,s=J(r[1]??[]);if(s.length===0)return r[2]??h;let o=r[2]!==void 0?r[2]:s[0];for(let a of r[2]!==void 0?s:s.slice(1))o=pt(i)?this.callFunc(i,[o,a],n):h;return o}case"sorted":{let i=[...J(r[0]??[])],s=r[1]??h,o=B(s)?s.data.get("key")??h:s;return i.sort((a,l)=>{let c=pt(o)?this.callFunc(o,[a],n):a,u=pt(o)?this.callFunc(o,[l],n):l;return typeof c=="number"&&typeof u=="number"?c-u:I(c).localeCompare(I(u))}),i}case"reversed":return[...J(r[0]??[])].reverse();case"any":return J(r[0]??[]).some(ot);case"all":return J(r[0]??[]).every(ot);case"sum":return J(r[0]??[]).reduce((i,s)=>i+s,r[1]??0);case"max":return(r.length===1?J(r[0]??[]):r).reduce((s,o)=>s>=o?s:o);case"min":return(r.length===1?J(r[0]??[]):r).reduce((s,o)=>s<=o?s:o);case"abs":return Math.abs(r[0]??0);case"round":return r[1]!==void 0?parseFloat(r[0].toFixed(r[1])):Math.round(r[0]??0);case"divmod":{let i=r[0],s=r[1];return[Math.floor(i/s),i%s]}case"pow":return r[0]**r[1];case"hex":return`0x${r[0].toString(16)}`;case"oct":return`0o${r[0].toString(8)}`;case"bin":return`0b${r[0].toString(2)}`;case"ord":return I(r[0]??"").charCodeAt(0);case"chr":return String.fromCharCode(r[0]??0);case"id":return Math.floor(Math.random()*4294967295);case"hash":return typeof r[0]=="number"?r[0]:I(r[0]??"").split("").reduce((i,s)=>i*31+s.charCodeAt(0)|0,0);case"open":throw new W("PermissionError","open() not available in virtual runtime");case"repr":return Y(r[0]??h);case"iter":return r[0]??h;case"next":return Array.isArray(r[0])&&r[0].length>0?r[0].shift():r[1]??(()=>{throw new W("StopIteration","")})();case"vars":return j([...n.entries()].map(([i,s])=>[i,s]));case"globals":return j([...n.entries()].map(([i,s])=>[i,s]));case"locals":return j([...n.entries()].map(([i,s])=>[i,s]));case"dir":{if(r.length===0)return[...n.keys()];let i=r[0]??h;return typeof i=="string"?["upper","lower","strip","split","join","replace","find","format","encode","startswith","endswith","count","isdigit","isalpha","title","capitalize"]:Array.isArray(i)?["append","extend","insert","pop","remove","index","count","sort","reverse","copy","clear"]:B(i)?["keys","values","items","get","update","pop","clear","copy","setdefault"]:[]}case"Exception":case"ValueError":case"TypeError":case"KeyError":case"IndexError":case"AttributeError":case"NameError":case"RuntimeError":case"StopIteration":case"NotImplementedError":case"OSError":case"IOError":throw new W(t,I(r[0]??""));case"exec":return this.execScript(I(r[0]??""),n),h;case"eval":return this.pyEval(I(r[0]??""),n);default:throw new W("NameError",`name '${t}' is not defined`)}}callFunc(t,r,n){let i=new Map(t.closure);t.params.forEach((s,o)=>{if(s.startsWith("*")){i.set(s.slice(1),r.slice(o));return}i.set(s,r[o]??h)});try{return this.execBlock(t.body,i)}catch(s){if(s instanceof kt)return s.value;throw s}}instantiate(t,r,n){let i={__pytype__:"instance",cls:t,attrs:new Map};return t.methods.get("__init__")&&this.callMethod(i,"__init__",r,n),i}execScript(t,r){let n=t.split(`
|
|
280
|
+
`);this.execLines(n,0,r)}execLines(t,r,n){let i=r;for(;i<t.length;){let s=t[i];if(!s.trim()||s.trim().startsWith("#")){i++;continue}i=this.execStatement(t,i,n)}return i}execBlock(t,r){try{this.execLines(t,0,r)}catch(n){if(n instanceof kt)return n.value;throw n}return h}getIndent(t){let r=0;for(let n of t)if(n===" ")r++;else if(n===" ")r+=4;else break;return r}collectBlock(t,r,n){let i=[];for(let s=r;s<t.length;s++){let o=t[s];if(!o.trim()){i.push("");continue}if(this.getIndent(o)<=n)break;i.push(o.slice(n+4))}return i}execStatement(t,r,n){let i=t[r],s=i.trim(),o=this.getIndent(i);if(s==="pass")return r+1;if(s==="break")throw new Dt;if(s==="continue")throw new _t;let a=s.match(/^return(?:\s+(.+))?$/);if(a)throw new kt(a[1]?this.pyEval(a[1],n):h);let l=s.match(/^raise(?:\s+(.+))?$/);if(l){if(l[1]){let b=this.pyEval(l[1],n);throw new W(typeof b=="string"?b:vt(b),I(b))}throw new W("RuntimeError","")}let c=s.match(/^assert\s+(.+?)(?:,\s*(.+))?$/);if(c){if(!ot(this.pyEval(c[1],n)))throw new W("AssertionError",c[2]?I(this.pyEval(c[2],n)):"");return r+1}let u=s.match(/^del\s+(.+)$/);if(u)return n.delete(u[1].trim()),r+1;let d=s.match(/^import\s+(\w+)(?:\s+as\s+(\w+))?$/);if(d){let[,b,P]=d,V=on[b];if(V){let C=V(this.cwd);this.modules.set(b,C),n.set(P??b,C)}return r+1}let m=s.match(/^from\s+(\w+)\s+import\s+(.+)$/);if(m){let[,b,P]=m,V=on[b];if(V){let C=V(this.cwd);if(P?.trim()==="*")for(let[v,N]of C.data)n.set(v,N);else for(let v of P.split(",").map(N=>N.trim()))n.set(v,C.data.get(v)??h)}return r+1}let p=s.match(/^def\s+(\w+)\s*\(([^)]*)\)\s*:$/);if(p){let[,b,P]=p,V=P.split(",").map(N=>N.trim()).filter(Boolean),C=this.collectBlock(t,r+1,o),v={__pytype__:"func",name:b,params:V,body:C,closure:new Map(n)};return n.set(b,v),r+1+C.length}let S=s.match(/^class\s+(\w+)(?:\(([^)]*)\))?\s*:$/);if(S){let[,b,P]=S,V=P?P.split(",").map(G=>G.trim()):[],C=this.collectBlock(t,r+1,o),v={__pytype__:"class",name:b,methods:new Map,bases:V},N=0;for(;N<C.length;){let U=C[N].trim().match(/^def\s+(\w+)\s*\(([^)]*)\)\s*:$/);if(U){let[,Z,gt]=U,lt=gt.split(",").map(A=>A.trim()).filter(Boolean),yt=this.collectBlock(C,N+1,0);v.methods.set(Z,{__pytype__:"func",name:Z,params:lt,body:yt,closure:new Map(n)}),N+=1+yt.length}else N++}return n.set(b,v),r+1+C.length}if(s.startsWith("if ")&&s.endsWith(":")){let b=s.slice(3,-1).trim(),P=this.collectBlock(t,r+1,o),V=P.length+1;if(ot(this.pyEval(b,n))){this.execBlock(P,new Map(n).also?.(N=>{for(let[G,U]of n)N.set(G,U)})??n),this.runBlockInScope(P,n);let v=r+1+P.length;for(;v<t.length;){let N=t[v].trim();if(this.getIndent(t[v])<o||!N.startsWith("elif")&&!N.startsWith("else"))break;let G=this.collectBlock(t,v+1,o);v+=1+G.length}return v}let C=r+1+P.length;for(;C<t.length;){let v=t[C],N=v.trim();if(this.getIndent(v)!==o)break;let G=N.match(/^elif\s+(.+):$/);if(G){let U=this.collectBlock(t,C+1,o);if(ot(this.pyEval(G[1],n))){for(this.runBlockInScope(U,n),C+=1+U.length;C<t.length;){let Z=t[C].trim();if(this.getIndent(t[C])!==o||!Z.startsWith("elif")&&!Z.startsWith("else"))break;let gt=this.collectBlock(t,C+1,o);C+=1+gt.length}return C}C+=1+U.length;continue}if(N==="else:"){let U=this.collectBlock(t,C+1,o);return this.runBlockInScope(U,n),C+1+U.length}break}return C}let g=s.match(/^for\s+(.+?)\s+in\s+(.+?)\s*:$/);if(g){let[,b,P]=g,V=J(this.pyEval(P.trim(),n)),C=this.collectBlock(t,r+1,o),v=[],N=r+1+C.length;N<t.length&&t[N]?.trim()==="else:"&&(v=this.collectBlock(t,N+1,o),N+=1+v.length);let G=!1;for(let U of V){if(b.includes(",")){let Z=b.split(",").map(lt=>lt.trim()),gt=Array.isArray(U)?U:[U];Z.forEach((lt,yt)=>n.set(lt,gt[yt]??h))}else n.set(b.trim(),U);try{this.runBlockInScope(C,n)}catch(Z){if(Z instanceof Dt){G=!0;break}if(Z instanceof _t)continue;throw Z}}return!G&&v.length&&this.runBlockInScope(v,n),N}let f=s.match(/^while\s+(.+?)\s*:$/);if(f){let b=f[1],P=this.collectBlock(t,r+1,o),V=0;for(;ot(this.pyEval(b,n))&&V++<1e5;)try{this.runBlockInScope(P,n)}catch(C){if(C instanceof Dt)break;if(C instanceof _t)continue;throw C}return r+1+P.length}if(s==="try:"){let b=this.collectBlock(t,r+1,o),P=r+1+b.length,V=[],C=[],v=[];for(;P<t.length;){let G=t[P],U=G.trim();if(this.getIndent(G)!==o)break;if(U.startsWith("except")){let Z=U.match(/^except(?:\s+(\w+)(?:\s+as\s+(\w+))?)?\s*:$/),gt=Z?.[1]??null,lt=Z?.[2],yt=this.collectBlock(t,P+1,o);V.push({exc:gt,body:yt}),lt&&n.set(lt,""),P+=1+yt.length}else if(U==="else:")v=this.collectBlock(t,P+1,o),P+=1+v.length;else if(U==="finally:")C=this.collectBlock(t,P+1,o),P+=1+C.length;else break}let N=null;try{this.runBlockInScope(b,n),v.length&&this.runBlockInScope(v,n)}catch(G){if(G instanceof W){N=G;let U=!1;for(let Z of V)if(Z.exc===null||Z.exc===G.type||Z.exc==="Exception"){this.runBlockInScope(Z.body,n),U=!0;break}if(!U)throw G}else throw G}finally{C.length&&this.runBlockInScope(C,n)}return P}let $=s.match(/^with\s+(.+?)\s+as\s+(\w+)\s*:$/);if($){let b=this.collectBlock(t,r+1,o);return n.set($[2],h),this.runBlockInScope(b,n),r+1+b.length}let F=s.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*(\+=|-=|\*=|\/\/=|\/=|%=|\*\*=|&=|\|=)\s*(.+)$/);if(F){let[,b,P,V]=F,C=n.get(b)??0,v=this.pyEval(V,n),N;switch(P){case"+=":N=typeof C=="string"?C+I(v):C+v;break;case"-=":N=C-v;break;case"*=":N=C*v;break;case"/=":N=C/v;break;case"//=":N=Math.floor(C/v);break;case"%=":N=C%v;break;case"**=":N=C**v;break;default:N=v}return n.set(b,N),r+1}let M=s.match(/^([A-Za-z_][A-Za-z0-9_]*)\[(.+)\]\s*=\s*(.+)$/);if(M){let[,b,P,V]=M,C=n.get(b)??h,v=this.pyEval(V,n)??h,N=this.pyEval(P,n)??h;return Array.isArray(C)?C[N]=v:B(C)&&C.data.set(I(N),v),r+1}let w=s.match(/^([A-Za-z_][A-Za-z0-9_.]+)\s*=\s*(.+)$/);if(w){let b=w[1].lastIndexOf(".");if(b!==-1){let P=w[1].slice(0,b),V=w[1].slice(b+1),C=this.pyEval(w[2],n),v=this.pyEval(P,n);return B(v)?v.data.set(V,C):Vt(v)&&v.attrs.set(V,C),r+1}}let k=s.match(/^([A-Za-z_][A-Za-z0-9_,\s]*),\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.+)$/);if(k){let b=this.pyEval(k[3],n),P=s.split("=")[0].split(",").map(C=>C.trim()),V=J(b);return P.forEach((C,v)=>n.set(C,V[v]??h)),r+1}let R=s.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*(?::[^=]+)?\s*=\s*(.+)$/);if(R){let[,b,P]=R;return n.set(b,this.pyEval(P,n)),r+1}try{this.pyEval(s,n)}catch(b){if(b instanceof W||b instanceof Lt)throw b}return r+1}runBlockInScope(t,r){this.execLines(t,0,r)}run(t){let r=Js(this.cwd);try{this.execScript(t,r)}catch(n){return n instanceof Lt?{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:n.code}:n instanceof W?(this.stderr.push(n.toString()),{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:1}):n instanceof kt?{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:0}:(this.stderr.push(`RuntimeError: ${n}`),{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:1})}return{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:0}}},ln={name:"python3",aliases:["python"],description:"Python 3 interpreter (virtual)",category:"system",params:["[--version] [-c <code>] [-V] [file]"],run:({args:e,shell:t,cwd:r})=>{if(!t.packageManager.isInstalled("python3"))return{stderr:`bash: python3: command not found
|
|
240
281
|
Hint: install it with: apt install python3
|
|
241
|
-
`,exitCode:127};if(
|
|
242
|
-
`,exitCode:0};if(
|
|
243
|
-
`,exitCode:0};let n=
|
|
282
|
+
`,exitCode:127};if(y(e,["--version","-V"]))return{stdout:`${Gs}
|
|
283
|
+
`,exitCode:0};if(y(e,["--version-full"]))return{stdout:`${Yt}
|
|
284
|
+
`,exitCode:0};let n=e.indexOf("-c");if(n!==-1){let s=e[n+1];if(!s)return{stderr:`python3: -c requires a code argument
|
|
244
285
|
`,exitCode:1};let o=s.replace(/\\n/g,`
|
|
245
|
-
`).replace(/\\t/g," "),a=new
|
|
246
|
-
`,exitCode:2};let o=t.vfs.readFile(s),a=new
|
|
286
|
+
`).replace(/\\t/g," "),a=new Qt(r),{stdout:l,stderr:c,exitCode:u}=a.run(o);return{stdout:l||void 0,stderr:c||void 0,exitCode:u}}let i=e.find(s=>!s.startsWith("-"));if(i){let s=x(r,i);if(!t.vfs.exists(s))return{stderr:`python3: can't open file '${i}': [Errno 2] No such file or directory
|
|
287
|
+
`,exitCode:2};let o=t.vfs.readFile(s),a=new Qt(r),{stdout:l,stderr:c,exitCode:u}=a.run(o);return{stdout:l||void 0,stderr:c||void 0,exitCode:u}}return{stdout:`${Yt}
|
|
247
288
|
Type "help", "copyright", "credits" or "license" for more information.
|
|
248
|
-
>>> `,exitCode:0}}};var
|
|
249
|
-
`)[0]??"",o=
|
|
250
|
-
`||a[1]==="\r"?"":a[1]);if(!
|
|
251
|
-
`),
|
|
252
|
-
`),
|
|
253
|
-
`),s=!0
|
|
254
|
-
`)}
|
|
255
|
-
`)
|
|
256
|
-
`),
|
|
257
|
-
`).
|
|
289
|
+
>>> `,exitCode:0}}};var cn={name:"read",description:"Read a line from stdin into variables",category:"shell",params:["[-r] [-p prompt] <var...>"],run:({args:e,stdin:t,env:r})=>{let n=e.indexOf("-p"),i=e.filter((a,l)=>a!=="-r"&&a!=="-p"&&e[l-1]!=="-p"),s=(t??"").split(`
|
|
290
|
+
`)[0]??"",o=y(e,["-r"])?s:s.replace(/\\(?:\r?\n|.)/g,a=>a[1]===`
|
|
291
|
+
`||a[1]==="\r"?"":a[1]);if(!r)return{exitCode:0};if(i.length===0)r.vars.REPLY=o;else if(i.length===1)r.vars[i[0]]=o;else{let a=o.split(/\s+/);for(let l=0;l<i.length;l++)r.vars[i[l]]=l<i.length-1?a[l]??"":a.slice(l).join(" ")}return{exitCode:0}}};var un={name:"rm",description:"Remove files or directories",category:"files",params:["[-r|-rf] <path>"],run:({authUser:e,shell:t,cwd:r,args:n})=>{if(n.length===0)return{stderr:"rm: missing operand",exitCode:1};let i=y(n,["-r","-rf","-fr"]),s=[];for(let o=0;;o+=1){let a=wt(n,o,{flags:["-r","-rf","-fr"]});if(!a)break;s.push(a)}if(s.length===0)return{stderr:"rm: missing operand",exitCode:1};for(let o of s){let a=x(r,o);L(e,a,"rm"),t.vfs.remove(a,{recursive:i})}return{exitCode:0}}};var dn={name:"sed",description:"Stream editor for filtering and transforming text",category:"text",params:["-e <expr> [file]","s/pattern/replace/[g]"],run:({authUser:e,shell:t,cwd:r,args:n,stdin:i})=>{let s=y(n,["-i"]),o=st(n,["-e"])??n.find(f=>!f.startsWith("-")),a=n.filter(f=>!f.startsWith("-")&&f!==o).pop();if(!o)return{stderr:"sed: no expression",exitCode:1};let l=i??"";if(a){let f=x(r,a);try{l=t.vfs.readFile(f)}catch{return{stderr:`sed: ${a}: No such file or directory`,exitCode:1}}}let c=o.match(/^s([^a-zA-Z0-9])(.+?)\1(.*?)\1([gi]*)$/);if(!c)return{stderr:`sed: unrecognized command: ${o}`,exitCode:1};let[,,u,d,m]=c,p=(m??"").includes("i")?"gi":(m??"").includes("g")?"g":"",S;try{S=new RegExp(u,p||"")}catch{return{stderr:`sed: invalid regex: ${u}`,exitCode:1}}let g=((m??"").includes("g")||p.includes("g"),l.replace(S,d??""));if(s&&a){let f=x(r,a);return t.writeFileAsUser(e,f,g),{exitCode:0}}return{stdout:g,exitCode:0}}};var mn={name:"set",description:"Display or set shell variables",category:"shell",params:["[VAR=value]"],run:({args:e,env:t})=>{if(e.length===0)return{stdout:Object.entries(t.vars).map(([n,i])=>`${n}=${i}`).join(`
|
|
292
|
+
`),exitCode:0};for(let r of e)if(r.includes("=")){let n=r.indexOf("=");t.vars[r.slice(0,n)]=r.slice(n+1)}return{exitCode:0}}};async function Se(e,t,r,n){return Ht(e,t,r,i=>q(i,n.authUser,n.hostname,n.mode,n.cwd,n.shell,void 0,n.env).then(s=>s.stdout??""))}function Ct(e){let t=[],r=0;for(;r<e.length;){let n=e[r].trim();if(!n||n.startsWith("#")){r++;continue}if(n.startsWith("if ")||n==="if"){let i=n.replace(/^if\s+/,"").replace(/;\s*then\s*$/,"").trim(),s=[],o=[],a=[],l="then",c="";for(r++;r<e.length&&e[r]?.trim()!=="fi";){let u=e[r].trim();u.startsWith("elif ")?(l="elif",c=u.replace(/^elif\s+/,"").replace(/;\s*then\s*$/,"").trim(),o.push({cond:c,body:[]})):u==="else"?l="else":u!=="then"&&(l==="then"?s.push(u):l==="elif"&&o.length>0?o[o.length-1].body.push(u):a.push(u)),r++}t.push({type:"if",cond:i,then_:s,elif:o,else_:a})}else if(n.startsWith("for ")){let i=n.match(/^for\s+(\w+)\s+in\s+(.+?)(?:\s*;\s*do)?$/);if(i){let s=[];for(r++;r<e.length&&e[r]?.trim()!=="done";){let o=e[r].trim().replace(/^do\s+/,"");o&&o!=="do"&&s.push(o),r++}t.push({type:"for",var:i[1],list:i[2],body:s})}else t.push({type:"cmd",line:n})}else if(n.startsWith("while ")){let i=n.replace(/^while\s+/,"").replace(/;\s*do\s*$/,"").trim(),s=[];for(r++;r<e.length&&e[r]?.trim()!=="done";){let o=e[r].trim().replace(/^do\s+/,"");o&&o!=="do"&&s.push(o),r++}t.push({type:"while",cond:i,body:s})}else t.push({type:"cmd",line:n});r++}return t}async function ye(e,t){let r=await Se(e,t.env.vars,t.env.lastExitCode,t),n=r.match(/^\[?\s*(.+?)\s*\]?$/);if(n){let s=n[1],o=s.match(/^-([fdeznr])\s+(.+)$/);if(o){let[,c,u]=o,d=x(t.cwd,u);if(c==="f")return t.shell.vfs.exists(d)&&t.shell.vfs.stat(d).type==="file";if(c==="d")return t.shell.vfs.exists(d)&&t.shell.vfs.stat(d).type==="directory";if(c==="e")return t.shell.vfs.exists(d);if(c==="z")return(u??"").length===0;if(c==="n")return(u??"").length>0}let a=s.match(/^"?([^"]*)"?\s*(==|!=|=|<|>)\s*"?([^"]*)"?$/);if(a){let[,c,u,d]=a;if(u==="=="||u==="=")return c===d;if(u==="!=")return c!==d}let l=s.match(/^(\S+)\s+(-eq|-ne|-lt|-le|-gt|-ge)\s+(\S+)$/);if(l){let[,c,u,d]=l,m=Number(c),p=Number(d);if(u==="-eq")return m===p;if(u==="-ne")return m!==p;if(u==="-lt")return m<p;if(u==="-le")return m<=p;if(u==="-gt")return m>p;if(u==="-ge")return m>=p}}return((await q(r,t.authUser,t.hostname,t.mode,t.cwd,t.shell,void 0,t.env)).exitCode??0)===0}async function $t(e,t){let r={exitCode:0},n="";for(let i of e)if(i.type==="cmd"){let s=await Se(i.line,t.env.vars,t.env.lastExitCode,t),o=/^([A-Za-z_][A-Za-z0-9_]*)=(.*)/,a=s.trim().split(/\s+/);if(a.length>0&&o.test(a[0])&&a.every(u=>o.test(u))){for(let u of a){let d=u.match(o);t.env.vars[d[1]]=d[2]}t.env.lastExitCode=0;continue}let l=await q(s,t.authUser,t.hostname,t.mode,t.cwd,t.shell,void 0,t.env);if(t.env.lastExitCode=l.exitCode??0,l.stdout&&(n+=`${l.stdout}
|
|
293
|
+
`),l.stderr)return{...l,stdout:n.trim()};r=l}else if(i.type==="if"){let s=!1;if(await ye(i.cond,t)){let o=await $t(Ct(i.then_),t);o.stdout&&(n+=`${o.stdout}
|
|
294
|
+
`),s=!0}else{for(let o of i.elif)if(await ye(o.cond,t)){let a=await $t(Ct(o.body),t);a.stdout&&(n+=`${a.stdout}
|
|
295
|
+
`),s=!0;break}if(!s&&i.else_.length>0){let o=await $t(Ct(i.else_),t);o.stdout&&(n+=`${o.stdout}
|
|
296
|
+
`)}}}else if(i.type==="for"){let o=(await Se(i.list,t.env.vars,t.env.lastExitCode,t)).trim().split(/\s+/);for(let a of o){t.env.vars[i.var]=a;let l=await $t(Ct(i.body),t);if(l.stdout&&(n+=`${l.stdout}
|
|
297
|
+
`),l.closeSession)return l}}else if(i.type==="while"){let s=0;for(;s<1e3&&await ye(i.cond,t);){let o=await $t(Ct(i.body),t);if(o.stdout&&(n+=`${o.stdout}
|
|
298
|
+
`),o.closeSession)return o;s++}}return{...r,stdout:n.trim()||r.stdout}}var pn={name:"sh",aliases:["bash"],description:"Execute shell script or command",category:"shell",params:["-c <script>","[<file>]"],run:async e=>{let{args:t,shell:r,cwd:n}=e;if(y(t,"-c")){let s=t[t.indexOf("-c")+1]??"";if(!s)return{stderr:"sh: -c requires a script",exitCode:1};let o=s.split(/[;\n]/).map(l=>l.trim()).filter(l=>l&&!l.startsWith("#")),a=Ct(o);return $t(a,e)}let i=t[0];if(i){let s=x(n,i);if(!r.vfs.exists(s))return{stderr:`sh: ${i}: No such file or directory`,exitCode:1};let a=r.vfs.readFile(s).split(`
|
|
299
|
+
`).map(c=>c.trim()).filter(c=>c&&!c.startsWith("#")),l=Ct(a);return $t(l,e)}return{stderr:"sh: invalid usage. Use: sh -c 'cmd' or sh <file>",exitCode:1}}};var fn={name:"shift",description:"Shift positional parameters",category:"shell",params:["[n]"],run:({args:e,env:t})=>{if(!t)return{exitCode:0};let r=parseInt(e[0]??"1",10)||1,n=t.vars.__argv?.split("\0").filter(Boolean)??[];t.vars.__argv=n.slice(r).join("\0");let i=n.slice(r);for(let s=1;s<=9;s++)t.vars[String(s)]=i[s-1]??"";return{exitCode:0}}},hn={name:"trap",description:"Trap signals and events",category:"shell",params:["[action] [signal...]"],run:({args:e,env:t})=>{if(!t||e.length===0)return{exitCode:0};let r=e[0]??"",n=e.slice(1);for(let i of n)t.vars[`__trap_${i.toUpperCase()}`]=r;return{exitCode:0}}},gn={name:"return",description:"Return from a shell function",category:"shell",params:["[n]"],run:({args:e,env:t})=>{let r=parseInt(e[0]??"0",10);return t&&(t.lastExitCode=r),{exitCode:r}}};var yn={name:"sleep",description:"Delay execution",category:"system",params:["<seconds>"],run:async({args:e})=>{let t=parseFloat(e[0]??"1");return Number.isNaN(t)||t<0?{stderr:"sleep: invalid time",exitCode:1}:(await new Promise(r=>setTimeout(r,t*1e3)),{exitCode:0})}};var Sn={name:"sort",description:"Sort lines of text",category:"text",params:["[-r] [-n] [-u] [-k <col>] [file...]"],run:({authUser:e,shell:t,cwd:r,args:n,stdin:i})=>{let s=y(n,["-r"]),o=y(n,["-n"]),a=y(n,["-u"]),l=n.filter(S=>!S.startsWith("-")),d=[...(l.length>0?l.map(S=>{try{return L(e,x(r,S),"sort"),t.vfs.readFile(x(r,S))}catch{return""}}).join(`
|
|
258
300
|
`):i??"").split(`
|
|
259
|
-
`).filter(Boolean)].sort((
|
|
260
|
-
`),exitCode:0}}};var
|
|
261
|
-
`)){let d=u.trim();if(!d||d.startsWith("#"))continue;let m=await
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
`),
|
|
265
|
-
`),
|
|
266
|
-
`)
|
|
267
|
-
|
|
268
|
-
`),exitCode:0}}};var
|
|
301
|
+
`).filter(Boolean)].sort((S,g)=>o?Number(S)-Number(g):S.localeCompare(g)),m=s?d.reverse():d;return{stdout:(a?[...new Set(m)]:m).join(`
|
|
302
|
+
`),exitCode:0}}};var wn={name:"source",aliases:["."],description:"Execute commands from a file in the current shell environment",category:"shell",params:["<file> [args...]"],run:async({args:e,authUser:t,hostname:r,cwd:n,shell:i,env:s})=>{let o=e[0];if(!o)return{stderr:"source: missing filename",exitCode:1};let a=x(n,o);if(!i.vfs.exists(a))return{stderr:`source: ${o}: No such file or directory`,exitCode:1};let l=i.vfs.readFile(a),c=0;for(let u of l.split(`
|
|
303
|
+
`)){let d=u.trim();if(!d||d.startsWith("#"))continue;let m=await q(d,t,r,"shell",n,i,void 0,s);if(c=m.exitCode??0,m.closeSession||m.switchUser)return m}return{exitCode:c}}};var xn={name:"su",description:"Switch user",category:"users",params:["[-] [-c <cmd>] [username]"],run:async({authUser:e,shell:t,args:r,hostname:n,mode:i,cwd:s})=>{let o=r.includes("-")||r.includes("-l")||r.includes("--login"),a=r.indexOf("-c"),l=a!==-1?r[a+1]:void 0,u=r.filter((d,m)=>m!==a&&m!==a+1).filter(d=>d!=="-"&&d!=="-l"&&d!=="--login").find(d=>!d.startsWith("-"))??"root";return t.users.listUsers().includes(u)?e==="root"?l?q(l,u,n,i,o?`/home/${u}`:s,t):{switchUser:u,nextCwd:o?`/home/${u}`:void 0,exitCode:0}:t.users.isSudoer(e)?{sudoChallenge:{username:u,targetUser:u,commandLine:l??null,loginShell:o,prompt:"Password: "},exitCode:0}:{stderr:`su: permission denied
|
|
304
|
+
`,exitCode:1}:{stderr:`su: user '${u}' does not exist
|
|
305
|
+
`,exitCode:1}}};function ri(e){let{flags:t,flagsWithValues:r,positionals:n}=nt(e,{flags:["-i","-S"],flagsWithValue:["-u","--user"]}),i=t.has("-i"),s=r.get("-u")||r.get("--user")||"root",o=n.length>0?n.join(" "):null;return{targetUser:s,loginShell:i,commandLine:o}}var bn={name:"sudo",description:"Execute as superuser",category:"users",params:["<command...>"],run:async({authUser:e,hostname:t,mode:r,cwd:n,shell:i,args:s})=>{let{targetUser:o,loginShell:a,commandLine:l}=ri(s);if(e!=="root"&&!i.users.isSudoer(e))return{stderr:"sudo: permission denied",exitCode:1};let c=o||"root",u=`[sudo] password for ${e}: `;return e==="root"?!l&&a?{switchUser:c,nextCwd:`/home/${c}`,exitCode:0}:l?q(l,c,t,r,a?`/home/${c}`:n,i):{stderr:"sudo: missing command",exitCode:1}:{sudoChallenge:{username:e,targetUser:c,commandLine:l,loginShell:a,prompt:u},exitCode:0}}};var vn={name:"tail",description:"Output last lines",category:"text",params:["[-n <lines>] [file...]"],run:({authUser:e,shell:t,cwd:r,args:n,stdin:i})=>{let s=st(n,["-n"]),o=n.find(d=>/^-\d+$/.test(d)),a=typeof s=="string"?parseInt(s,10):o?parseInt(o.slice(1),10):10,l=n.filter(d=>!d.startsWith("-")&&d!==s&&d!==String(a)),c=d=>{let m=d.split(`
|
|
306
|
+
`),p=d.endsWith(`
|
|
307
|
+
`),S=p?m.slice(0,-1):m;return S.slice(Math.max(0,S.length-a)).join(`
|
|
308
|
+
`)+(p?`
|
|
309
|
+
`:"")};if(l.length===0)return{stdout:c(i??""),exitCode:0};let u=[];for(let d of l){let m=x(r,d);try{L(e,m,"tail"),u.push(c(t.vfs.readFile(m)))}catch{return{stderr:`tail: ${d}: No such file or directory`,exitCode:1}}}return{stdout:u.join(`
|
|
310
|
+
`),exitCode:0}}};var Cn={name:"tar",description:"Archive utility",category:"archive",params:["[-czf|-xzf|-tf] <archive> [files...]"],run:({authUser:e,shell:t,cwd:r,args:n})=>{let i=[],s=!1;for(let m of n)if(/^-[a-zA-Z]{2,}$/.test(m))for(let p of m.slice(1))i.push(`-${p}`);else if(!s&&/^[cxtdru]{1,}[a-zA-Z]*$/.test(m)&&!m.includes("/")&&!m.startsWith("-")){s=!0;for(let p of m)i.push(`-${p}`)}else i.push(m);let o=i.includes("-c"),a=i.includes("-x"),l=i.includes("-t"),c=i.indexOf("-f"),u=c!==-1?i[c+1]:i.find(m=>m.endsWith(".tar")||m.endsWith(".tar.gz")||m.endsWith(".tgz"));if(!o&&!a&&!l)return{stderr:`tar: must specify -c, -x, or -t
|
|
311
|
+
`,exitCode:1};if(!u)return{stderr:`tar: no archive specified
|
|
312
|
+
`,exitCode:1};let d=x(r,u);if(o){let m=new Set;c!==-1&&m.add(c+1);let p=i.filter((g,f)=>!g.startsWith("-")&&g!==u&&!m.has(f)),S={};for(let g of p){let f=x(r,g);try{if(t.vfs.stat(f).type==="file")S[g]=t.vfs.readFile(f);else{let F=(M,w)=>{for(let k of t.vfs.list(M)){let R=`${M}/${k}`,b=`${w}/${k}`;t.vfs.stat(R).type==="file"?S[b]=t.vfs.readFile(R):F(R,b)}};F(f,g)}}catch{return{stderr:`tar: ${g}: No such file or directory`,exitCode:1}}}return t.writeFileAsUser(e,d,JSON.stringify(S)),{exitCode:0}}if(l||a){let m;try{m=JSON.parse(t.vfs.readFile(d))}catch{return{stderr:`tar: ${u}: cannot open archive`,exitCode:1}}if(l)return{stdout:Object.keys(m).join(`
|
|
313
|
+
`),exitCode:0};for(let[p,S]of Object.entries(m))t.writeFileAsUser(e,x(r,p),S);return{exitCode:0}}return{stderr:"tar: must specify -c, -x, or -t",exitCode:1}}};var $n={name:"tee",description:"Read stdin, write to stdout and files",category:"text",params:["[-a] <file...>"],run:({authUser:e,shell:t,cwd:r,args:n,stdin:i})=>{let s=y(n,["-a"]),o=n.filter(l=>!l.startsWith("-")),a=i??"";for(let l of o){let c=x(r,l);if(s){let u=(()=>{try{return t.vfs.readFile(c)}catch{return""}})();t.writeFileAsUser(e,c,u+a)}else t.writeFileAsUser(e,c,a)}return{stdout:a,exitCode:0}}};function Et(e,t,r){if(e[e.length-1]==="]"&&(e=e.slice(0,-1)),e[0]==="["&&(e=e.slice(1)),e.length===0)return!1;if(e[0]==="!")return!Et(e.slice(1),t,r);let n=e.indexOf("-a");if(n!==-1)return Et(e.slice(0,n),t,r)&&Et(e.slice(n+1),t,r);let i=e.indexOf("-o");if(i!==-1)return Et(e.slice(0,i),t,r)||Et(e.slice(i+1),t,r);if(e.length===2){let[s,o=""]=e,l=(c=>c.startsWith("/")?c:`${r}/${c}`.replace(/\/+/g,"/"))(o);switch(s){case"-e":return t.vfs.exists(l);case"-f":return t.vfs.exists(l)&&t.vfs.stat(l).type==="file";case"-d":return t.vfs.exists(l)&&t.vfs.stat(l).type==="directory";case"-r":return t.vfs.exists(l);case"-w":return t.vfs.exists(l);case"-x":return t.vfs.exists(l)&&!!(t.vfs.stat(l).mode&73);case"-s":return t.vfs.exists(l)&&t.vfs.stat(l).type==="file"&&t.vfs.stat(l).size>0;case"-z":return o.length===0;case"-n":return o.length>0;case"-L":return t.vfs.isSymlink(l)}}if(e.length===3){let[s="",o,a=""]=e,l=Number(s),c=Number(a);switch(o){case"=":case"==":return s===a;case"!=":return s!==a;case"<":return s<a;case">":return s>a;case"-eq":return l===c;case"-ne":return l!==c;case"-lt":return l<c;case"-le":return l<=c;case"-gt":return l>c;case"-ge":return l>=c}}return e.length===1?(e[0]??"").length>0:!1}var Pn={name:"test",aliases:["["],description:"Evaluate conditional expression",category:"shell",params:["<expression>"],run:({args:e,shell:t,cwd:r})=>{try{return{exitCode:Et([...e],t,r)?0:1}}catch{return{stderr:"test: malformed expression",exitCode:2}}}};var kn={name:"touch",description:"Create or update files",category:"files",params:["<file>"],run:({authUser:e,shell:t,cwd:r,args:n})=>{if(n.length===0)return{stderr:"touch: missing file operand",exitCode:1};for(let i of n){let s=x(r,i);L(e,s,"touch"),t.vfs.exists(s)||t.writeFileAsUser(e,s,"")}return{exitCode:0}}};function ni(e){return e.replace(/\\n/g,`
|
|
314
|
+
`).replace(/\\t/g," ").replace(/\\r/g,"\r").replace(/\\\\/g,"\\")}function Mn(e){let t=[],r=ni(e),n=0;for(;n<r.length;){if(n+2<r.length&&r[n+1]==="-"){let i=r.charCodeAt(n),s=r.charCodeAt(n+2);if(i<=s){for(let o=i;o<=s;o++)t.push(String.fromCharCode(o));n+=3;continue}}t.push(r[n]),n++}return t}var En={name:"tr",description:"Translate or delete characters",category:"text",params:["[-d] [-s] <set1> [set2]"],run:({args:e,stdin:t})=>{let r=y(e,["-d"]),n=y(e,["-s"]),i=e.filter(l=>!l.startsWith("-")),s=Mn(i[0]??""),o=Mn(i[1]??""),a=t??"";if(r){let l=new Set(s);a=[...a].filter(c=>!l.has(c)).join("")}else if(o.length>0){let l=new Map;for(let c=0;c<s.length;c++)l.set(s[c],o[c]??o[o.length-1]??"");a=[...a].map(c=>l.get(c)??c).join("")}if(n&&o.length>0){let l=new Set(o);a=a.replace(/(.)\1+/g,(c,u)=>l.has(u)?u:c)}return{stdout:a,exitCode:0}}};var An={name:"tree",description:"Display directory tree",category:"navigation",params:["[path]"],run:({authUser:e,shell:t,cwd:r,args:n})=>{let i=x(r,wt(n,0)??r);return L(e,i,"tree"),{stdout:t.vfs.tree(i),exitCode:0}}};var Fn={name:"true",description:"Return success exit code",category:"shell",params:[],run:()=>({exitCode:0})},Nn={name:"false",description:"Return failure exit code",category:"shell",params:[],run:()=>({exitCode:1})};var In={name:"type",description:"Describe how a command would be interpreted",category:"shell",params:["<command...>"],run:({args:e,shell:t,env:r})=>{if(e.length===0)return{stderr:"type: missing argument",exitCode:1};let n=(r?.vars?.PATH??"/usr/local/bin:/usr/bin:/bin").split(":"),i=[],s=0;for(let o of e){if(ft(o)){i.push(`${o} is a shell builtin`);continue}let a=!1;for(let l of n){let c=`${l}/${o}`;if(t.vfs.exists(c)){i.push(`${o} is ${c}`),a=!0;break}}a||(i.push(`${o}: not found`),s=1)}return{stdout:i.join(`
|
|
315
|
+
`),exitCode:s}}};var Rn={name:"uname",description:"Print system information",category:"system",params:["[-a] [-s] [-r] [-m]"],run:({shell:e,args:t})=>{let r=y(t,["-a"]),n="Linux",i=e.properties?.kernel??"5.15.0",s=e.properties?.arch??"x86_64",o=e.hostname;return r?{stdout:`${n} ${o} ${i} #1 SMP ${s} GNU/Linux`,exitCode:0}:y(t,["-r"])?{stdout:i,exitCode:0}:y(t,["-m"])?{stdout:s,exitCode:0}:{stdout:n,exitCode:0}}};var Vn={name:"uniq",description:"Report or filter out repeated lines",category:"text",params:["[-c] [-d] [-u] [file]"],run:({args:e,stdin:t})=>{let r=y(e,["-c"]),n=y(e,["-d"]),i=y(e,["-u"]),s=(t??"").split(`
|
|
316
|
+
`),o=[],a=0;for(;a<s.length;){let l=a;for(;l<s.length&&s[l]===s[a];)l++;let c=l-a,u=s[a];if(n&&c===1){a=l;continue}if(i&&c>1){a=l;continue}o.push(r?`${String(c).padStart(4)} ${u}`:u),a=l}return{stdout:o.join(`
|
|
317
|
+
`),exitCode:0}}};var Dn={name:"unset",description:"Remove shell variable",category:"shell",params:["<VAR>"],run:({args:e,env:t})=>{for(let r of e)delete t.vars[r];return{exitCode:0}}};var _n={name:"uptime",description:"Tell how long the system has been running",category:"system",params:["[-p] [-s]"],run:({args:e,shell:t})=>{let r=y(e,["-p"]),n=y(e,["-s"]),i=Math.floor((Date.now()-t.startTime)/1e3),s=Math.floor(i/86400),o=Math.floor(i%86400/3600),a=Math.floor(i%3600/60);if(n)return{stdout:new Date(t.startTime).toISOString().slice(0,19).replace("T"," "),exitCode:0};if(r){let m=[];return s>0&&m.push(`${s} day${s>1?"s":""}`),o>0&&m.push(`${o} hour${o>1?"s":""}`),m.push(`${a} minute${a!==1?"s":""}`),{stdout:`up ${m.join(", ")}`,exitCode:0}}let l=new Date().toTimeString().slice(0,8),c=s>0?`${s} day${s>1?"s":""}, ${String(o).padStart(2)}:${String(a).padStart(2,"0")}`:`${String(o).padStart(2)}:${String(a).padStart(2,"0")}`,u=t.users.listActiveSessions().length,d=(Math.random()*.5).toFixed(2);return{stdout:` ${l} up ${c}, ${u} user${u!==1?"s":""}, load average: ${d}, ${d}, ${d}`,exitCode:0}}};var Ln={name:"wc",description:"Count words/lines/bytes",category:"text",params:["[-l] [-w] [-c] [file...]"],run:({authUser:e,shell:t,cwd:r,args:n,stdin:i})=>{let s=y(n,["-l"]),o=y(n,["-w"]),a=y(n,["-c"]),l=!s&&!o&&!a,c=n.filter(m=>!m.startsWith("-")),u=(m,p)=>{let S=m.split(`
|
|
269
318
|
`).length-(m.endsWith(`
|
|
270
|
-
`)?1:0),g=m.trim().split(/\s+/).filter(Boolean).length,
|
|
271
|
-
`),exitCode:0}}};var
|
|
272
|
-
`),exitCode:0};if(
|
|
273
|
-
Usage: wget [OPTION]... [URL]...`,exitCode:1};let a=i.get("-O")??i.get("--output-document")??null,l=i.get("-P")??i.get("--directory-prefix")??null,c=
|
|
274
|
-
`),exitCode:4}}if(!
|
|
275
|
-
`),exitCode:8};let
|
|
276
|
-
`)||void 0,exitCode:0}:d?(n.writeFileAsUser(
|
|
277
|
-
${d} 100%[==================>] ${
|
|
278
|
-
`)||void 0,exitCode:0}):{stdout:
|
|
279
|
-
`),exitCode:s?1:0}}};function
|
|
280
|
-
`),exitCode:0})};var
|
|
281
|
-
`).
|
|
319
|
+
`)?1:0),g=m.trim().split(/\s+/).filter(Boolean).length,f=Buffer.byteLength(m,"utf8"),$=[];return(l||s)&&$.push(String(S).padStart(7)),(l||o)&&$.push(String(g).padStart(7)),(l||a)&&$.push(String(f).padStart(7)),p&&$.push(` ${p}`),$.join("")};if(c.length===0)return{stdout:u(i??"",""),exitCode:0};let d=[];for(let m of c){let p=x(r,m);try{L(e,p,"wc");let S=t.vfs.readFile(p);d.push(u(S,m))}catch{return{stderr:`wc: ${m}: No such file or directory`,exitCode:1}}}return{stdout:d.join(`
|
|
320
|
+
`),exitCode:0}}};var Tn={name:"wget",description:"File downloader (pure fetch)",category:"network",params:["[options] <url>"],run:async({authUser:e,cwd:t,args:r,shell:n})=>{let{flagsWithValues:i,positionals:s}=nt(r,{flagsWithValue:["-O","--output-document","-o","--output-file","-P","--directory-prefix","--tries","--timeout"]});if(y(r,["-h","--help"]))return{stdout:["Usage: wget [option]... [URL]..."," -O, --output-document=FILE Write to FILE ('-' for stdout)"," -P, --directory-prefix=DIR Save files in DIR"," -q, --quiet Quiet mode"," -v, --verbose Verbose output (default)"," -c, --continue Continue partial download"," --tries=N Retry N times"," --timeout=N Timeout in seconds"].join(`
|
|
321
|
+
`),exitCode:0};if(y(r,["-V","--version"]))return{stdout:"GNU Wget 1.21.3 (virtual) built on Fortune GNU/Linux.",exitCode:0};let o=s[0];if(!o)return{stderr:`wget: missing URL
|
|
322
|
+
Usage: wget [OPTION]... [URL]...`,exitCode:1};let a=i.get("-O")??i.get("--output-document")??null,l=i.get("-P")??i.get("--directory-prefix")??null,c=y(r,["-q","--quiet"]),u=a==="-"?null:a??Te(o),d=u?x(t,l?`${l}/${u}`:u):null;d&&L(e,d,"wget");let m=[];c||(m.push(`--${new Date().toISOString()}-- ${o}`),m.push(`Resolving ${new URL(o).host}...`),m.push(`Connecting to ${new URL(o).host}...`));let p;try{p=await fetch(o,{headers:{"User-Agent":"Wget/1.21.3 (Fortune GNU/Linux)"}})}catch(g){let f=g instanceof Error?g.message:String(g);return m.push(`wget: unable to resolve host: ${f}`),{stderr:m.join(`
|
|
323
|
+
`),exitCode:4}}if(!p.ok)return m.push(`ERROR ${p.status}: ${p.statusText}`),{stderr:m.join(`
|
|
324
|
+
`),exitCode:8};let S;try{S=await p.text()}catch{return{stderr:"wget: failed to read response",exitCode:1}}if(!c){let g=p.headers.get("content-type")??"application/octet-stream";m.push(`HTTP request sent, awaiting response... ${p.status} ${p.statusText}`),m.push(`Length: ${S.length} [${g}]`)}return a==="-"?{stdout:S,stderr:m.join(`
|
|
325
|
+
`)||void 0,exitCode:0}:d?(n.writeFileAsUser(e,d,S),c||m.push(`Saving to: '${d}'
|
|
326
|
+
${d} 100%[==================>] ${S.length} B`),{stderr:m.join(`
|
|
327
|
+
`)||void 0,exitCode:0}):{stdout:S,exitCode:0}}};var zn={name:"which",description:"Locate a command in PATH",category:"shell",params:["<command...>"],run:({args:e,shell:t,env:r})=>{if(e.length===0)return{stderr:"which: missing argument",exitCode:1};let n=(r?.vars?.PATH??"/usr/local/bin:/usr/bin:/bin").split(":"),i=[],s=!1;for(let o of e){let a=!1;for(let l of n){let c=`${l}/${o}`;if(t.vfs.exists(c)&&t.vfs.stat(c).type==="file"){i.push(c),a=!0;break}}a||(s=!0)}return i.length===0?{exitCode:1}:{stdout:i.join(`
|
|
328
|
+
`),exitCode:s?1:0}}};function Xt(e){let t=e.toLocaleString("en-US",{weekday:"short"}),r=e.toLocaleString("en-US",{month:"short"}),n=e.getDate().toString().padStart(2,"0"),i=e.getHours().toString().padStart(2,"0"),s=e.getMinutes().toString().padStart(2,"0"),o=e.getSeconds().toString().padStart(2,"0"),a=e.getFullYear();return`${t} ${r} ${n} ${i}:${s}:${o} ${a}`}var On={name:"who",description:"Show active sessions",category:"system",params:[],run:({shell:e})=>({stdout:e.users.listActiveSessions().map(r=>{let n=new Date(r.startedAt),i=Number.isNaN(n.getTime())?r.startedAt:Xt(n);return`${r.username} ${r.tty} ${i} (${r.remoteAddress||"unknown"})`}).join(`
|
|
329
|
+
`),exitCode:0})};var Un={name:"whoami",description:"Print current user",category:"system",params:[],run:({authUser:e})=>({stdout:e,exitCode:0})};var Bn={name:"xargs",description:"Build and execute command lines from stdin",category:"text",params:["[command] [args...]"],run:async({authUser:e,hostname:t,mode:r,cwd:n,args:i,stdin:s,shell:o,env:a})=>{let l=i[0]??"echo",c=i.slice(1),u=(s??"").trim().split(/\s+/).filter(Boolean);if(u.length===0)return{exitCode:0};let d=[l,...c,...u].join(" ");return q(d,e,t,r,n,o,void 0,a)}};var si=[sn,qe,Ir,An,He,kn,un,Dr,Ze,_r,Mr,Er,Ke,Ar,ur,mr,dn,We,Sn,Vn,Ln,gr,vn,Ye,En,$n,Bn,rr,Cn,fr,hr,je,Un,On,Cr,Pr,pr,Rn,nn,kr,er,ir,Qe,yn,en,or,ar,cr,mn,Dn,pn,Ge,lr,Tr,$r,Je,Tn,Ve,tn,tr,bn,xn,Gr,Ue,Be,nr,sr,zn,In,Vr,_e,Le,Pn,wn,vr,rn,cn,Xe,fn,hn,gn,Fn,Nn,Qr,Xr,Yr,ln,_n,dr,Rr],Wn=[],Tt=new Map,te=null,ii=br(()=>xe().map(e=>e.name));function we(){Tt.clear();for(let e of xe()){Tt.set(e.name,e);for(let t of e.aliases??[])Tt.set(t,e)}te=Array.from(Tt.keys()).sort()}function xe(){return[...si,...Wn,ii]}function be(e){let t={...e,name:e.name.trim().toLowerCase(),aliases:e.aliases?.map(n=>n.trim().toLowerCase())};if([t.name,...t.aliases??[]].some(n=>n.length===0||/\s/.test(n)))throw new Error("Command names must be non-empty and contain no spaces");Wn.push(t),we()}function ve(e,t,r){return{name:e,params:t,run:r}}function Ce(){return te||we(),te}function pe(){return xe()}function ft(e){return te||we(),Tt.get(e.toLowerCase())}async function jn(e,t,r,n,i,s,o){let a={exitCode:0},l=[],c=i,u=0;for(;u<e.length;){let m=e[u];if(a=await oi(m.pipeline,t,r,n,c,s,o),o.lastExitCode=a.exitCode??0,a.nextCwd&&(a.exitCode??0)===0&&(c=a.nextCwd),a.stdout&&l.push(a.stdout),a.closeSession||a.switchUser)return{...a,stdout:l.join("")||a.stdout};let p=m.op;if(!(!p||p===";")){if(p==="&&"){if((a.exitCode??0)!==0)for(;u<e.length&&e[u]?.op==="&&";)u++}else if(p==="||"&&(a.exitCode??0)===0)for(;u<e.length&&e[u]?.op==="||";)u++}u++}let d=l.join("");return{...a,stdout:d||a.stdout,nextCwd:c!==i?c:void 0}}async function oi(e,t,r,n,i,s,o){if(!e.isValid)return{stderr:e.error||"Syntax error",exitCode:1};if(e.commands.length===0)return{exitCode:0};let a=o??{vars:{},lastExitCode:0};return e.commands.length===1?ai(e.commands[0],t,r,n,i,s,a):li(e.commands,t,r,n,i,s,a)}async function ai(e,t,r,n,i,s,o){let a;if(e.inputFile){let c=x(i,e.inputFile);try{a=s.vfs.readFile(c)}catch{return{stderr:`${e.inputFile}: No such file or directory`,exitCode:1}}}let l=await ee(e.name,e.args,t,r,n,i,s,a,o);if(e.outputFile){let c=x(i,e.outputFile),u=l.stdout||"";try{if(e.appendOutput){let d=(()=>{try{return s.vfs.readFile(c)}catch{return""}})();s.writeFileAsUser(t,c,d+u)}else s.writeFileAsUser(t,c,u);return{...l,stdout:""}}catch{return{...l,stderr:`Failed to write to ${e.outputFile}`,exitCode:1}}}return l}async function li(e,t,r,n,i,s,o){let a="",l=0;for(let c=0;c<e.length;c++){let u=e[c];if(c===0&&u.inputFile){let m=x(i,u.inputFile);try{a=s.vfs.readFile(m)}catch{return{stderr:`${u.inputFile}: No such file or directory`,exitCode:1}}}let d=await ee(u.name,u.args,t,r,n,i,s,a,o);if(l=d.exitCode??0,c===e.length-1&&u.outputFile){let m=x(i,u.outputFile),p=d.stdout||"";try{if(u.appendOutput){let S=(()=>{try{return s.vfs.readFile(m)}catch{return""}})();s.writeFileAsUser(t,m,S+p)}else s.writeFileAsUser(t,m,p);a=""}catch{return{stderr:`Failed to write to ${u.outputFile}`,exitCode:1}}}else a=d.stdout||"";if(d.stderr&&l!==0)return{stderr:d.stderr,exitCode:l};if(d.closeSession||d.switchUser)return d}return{stdout:a,exitCode:l}}function zt(e){let t=[],r="",n=!1,i="",s=0;for(;s<e.length;){let o=e[s],a=e[s+1];if((o==='"'||o==="'")&&!n){n=!0,i=o,s++;continue}if(n&&o===i){n=!1,i="",s++;continue}if(n){r+=o,s++;continue}if(o===" "){r&&(t.push(r),r=""),s++;continue}if((o===">"||o==="<")&&!n){r&&(t.push(r),r=""),o===">"&&a===">"?(t.push(">>"),s+=2):(t.push(o),s++);continue}r+=o,s++}return r&&t.push(r),t}function Hn(e){let t=e.trim();if(!t)return{statements:[],isValid:!0};try{return{statements:ci(t),isValid:!0}}catch(r){return{statements:[],isValid:!1,error:r.message}}}function ci(e){let t=ui(e),r=[];for(let n of t){let s={pipeline:{commands:di(n.text.trim()),isValid:!0}};n.op&&(s.op=n.op),r.push(s)}return r}function ui(e){let t=[],r="",n=0,i=!1,s="",o=0,a=l=>{r.trim()&&t.push({text:r,op:l}),r=""};for(;o<e.length;){let l=e[o],c=e.slice(o,o+2);if((l==='"'||l==="'")&&!i){i=!0,s=l,r+=l,o++;continue}if(i&&l===s){i=!1,r+=l,o++;continue}if(i){r+=l,o++;continue}if(l==="("){n++,r+=l,o++;continue}if(l===")"){n--,r+=l,o++;continue}if(n>0){r+=l,o++;continue}if(c==="&&"){a("&&"),o+=2;continue}if(c==="||"){a("||"),o+=2;continue}if(l===";"){a(";"),o++;continue}r+=l,o++}return a(),t}function di(e){return mi(e).map(pi)}function mi(e){let t=[],r="",n=!1,i="";for(let o=0;o<e.length;o++){let a=e[o];if((a==='"'||a==="'")&&!n){n=!0,i=a,r+=a;continue}if(n&&a===i){n=!1,r+=a;continue}if(n){r+=a;continue}if(a==="|"&&e[o+1]!=="|"){if(!r.trim())throw new Error("Syntax error near unexpected token '|'");t.push(r.trim()),r=""}else r+=a}let s=r.trim();if(!s&&t.length>0)throw new Error("Syntax error near unexpected token '|'");return s&&t.push(s),t}function pi(e){let t=zt(e);if(t.length===0)return{name:"",args:[]};let r=[],n,i,s=!1,o=0;for(;o<t.length;){let l=t[o];if(l==="<"){if(o++,o>=t.length)throw new Error("Syntax error: expected filename after <");n=t[o],o++}else if(l===">>"){if(o++,o>=t.length)throw new Error("Syntax error: expected filename after >>");i=t[o],s=!0,o++}else if(l===">"){if(o++,o>=t.length)throw new Error("Syntax error: expected filename after >");i=t[o],s=!1,o++}else r.push(l),o++}return{name:(r[0]??"").toLowerCase(),args:r.slice(1),inputFile:n,outputFile:i,appendOutput:s}}function At(e,t){return{vars:{PATH:"/usr/local/bin:/usr/bin:/bin",HOME:`/home/${e}`,USER:e,LOGNAME:e,SHELL:"/bin/sh",TERM:"xterm-256color",HOSTNAME:t,PS1:"\\u@\\h:\\w\\$ "},lastExitCode:0}}function qn(e,t,r,n){if(e.startsWith("/")){if(!r.vfs.exists(e))return null;try{let s=r.vfs.stat(e);return s.type!=="file"||!(s.mode&73)||(e.startsWith("/sbin/")||e.startsWith("/usr/sbin/"))&&n!=="root"?null:e}catch{return null}}let i=(t.vars.PATH??"/usr/local/bin:/usr/bin:/bin").split(":");for(let s of i){if((s==="/sbin"||s==="/usr/sbin")&&n!=="root")continue;let o=`${s}/${e}`;if(r.vfs.exists(o))try{let a=r.vfs.stat(o);if(a.type!=="file"||!(a.mode&73))continue;return o}catch{}}return null}async function ee(e,t,r,n,i,s,o,a,l){let c=l.vars[`__alias_${e}`];if(c)return q(`${c} ${t.join(" ")}`,r,n,i,s,o,a,l);let u=ft(e);if(!u){let d=qn(e,l,o,r);if(d){let m=o.vfs.readFile(d),p=m.match(/exec\s+builtin\s+(\S+)/);if(p){let g=ft(p[1]);if(g)return await g.run({authUser:r,hostname:n,activeSessions:o.users.listActiveSessions(),rawInput:[e,...t].join(" "),mode:i,args:t,stdin:a,cwd:s,shell:o,env:l})}let S=ft("sh");if(S)return await S.run({authUser:r,hostname:n,activeSessions:o.users.listActiveSessions(),rawInput:`sh -c ${JSON.stringify(m)}`,mode:i,args:["-c",m,"--",...t],stdin:a,cwd:s,shell:o,env:l})}return{stderr:`${e}: command not found`,exitCode:127}}try{return await u.run({authUser:r,hostname:n,activeSessions:o.users.listActiveSessions(),rawInput:[e,...t].join(" "),mode:i,args:t,stdin:a,cwd:s,shell:o,env:l})}catch(d){return{stderr:d instanceof Error?d.message:"Command failed",exitCode:1}}}async function q(e,t,r,n,i,s,o,a){let l=e.trim();if(l.length===0)return{exitCode:0};let c=a??At(t,r),d=zt(l)[0]?.toLowerCase()??"",m=c.vars[`__alias_${d}`],p=m?l.replace(d,m):l;if(/(?<![|&])[|](?![|])/.test(p)||p.includes(">")||p.includes("<")||p.includes("&&")||p.includes("||")||p.includes(";")){let w=Hn(p);if(!w.isValid)return{stderr:w.error||"Syntax error",exitCode:1};try{return await jn(w.statements,t,r,n,i,s,c)}catch(k){return{stderr:k instanceof Error?k.message:"Execution failed",exitCode:1}}}let g=await Ht(p,c.vars,c.lastExitCode,w=>q(w,t,r,n,i,s,void 0,c).then(k=>k.stdout??"")),f=zt(g.trim()),$=f[0]?.toLowerCase()??"",F=f.slice(1),M=ft($);if(!M){let w=qn($,c,s,t);if(w){let k=s.vfs.readFile(w),R=k.match(/exec\s+builtin\s+(\S+)/);if(R){let P=R[1],V=ft(P);if(V)return await V.run({authUser:t,hostname:r,activeSessions:s.users.listActiveSessions(),rawInput:[$,...F].join(" "),mode:n,args:F,stdin:o,cwd:i,shell:s,env:c})}let b=ft("sh");if(b)return await b.run({authUser:t,hostname:r,activeSessions:s.users.listActiveSessions(),rawInput:`sh -c ${JSON.stringify(k)}`,mode:n,args:["-c",k,"--",...F],stdin:o,cwd:i,shell:s,env:c})}return{stderr:`${$}: command not found`,exitCode:127}}try{return await M.run({authUser:t,hostname:r,activeSessions:s.users.listActiveSessions(),rawInput:g,mode:n,args:F,stdin:o,cwd:i,shell:s,env:c})}catch(w){return{stderr:w instanceof Error?w.message:"Command failed",exitCode:1}}}import{spawn as hi}from"node:child_process";import{readFile as fi}from"node:fs/promises";import*as re from"node:path";function $e(e){return`'${e.replace(/'/g,"'\\''")}'`}function Ot(e){return e.replace(/\r\n/g,`
|
|
330
|
+
`).replace(/\r/g,`
|
|
331
|
+
`).replace(/\n/g,`\r
|
|
332
|
+
`)}function Kn(e,t){let r=Number.isFinite(t.cols)&&t.cols>0?Math.floor(t.cols):80,n=Number.isFinite(t.rows)&&t.rows>0?Math.floor(t.rows):24;return`stty cols ${r} rows ${n} 2>/dev/null; ${e}`}function Gn(e,t){return!t||t.trim()===""||t==="."?e:t.startsWith("/")?re.posix.normalize(t):re.posix.normalize(re.posix.join(e,t))}async function Zn(e){try{let r=(await fi(`/proc/${e}/task/${e}/children`,"utf8")).trim().split(/\s+/).filter(Boolean).map(i=>Number.parseInt(i,10)).filter(i=>Number.isInteger(i)&&i>0),n=await Promise.all(r.map(i=>Zn(i)));return[...r,...n.flat()]}catch{return[]}}async function Jn(e=process.pid){let t=await Zn(e),r=Array.from(new Set(t)).sort((n,i)=>n-i);return r.length===0?null:r.join(",")}function Yn(e,t,r){let n=Kn(e,t),i=hi("script",["-qfec",n,"/dev/null"],{stdio:["pipe","pipe","pipe"],env:{...process.env,TERM:process.env.TERM??"xterm-256color"}});return i.stdout.on("data",s=>{r.write(s.toString("utf8"))}),i.stderr.on("data",s=>{r.write(s.toString("utf8"))}),i}function ne(e,t,r){return Yn(`nano -- ${$e(e)}`,t,r)}function Qn(e,t,r){return Yn(`htop -p ${$e(e)}`,t,r)}function se(e,t,r){let n=[`Linux ${e} ${t.kernel} ${t.arch}`,"","The programs included with the Fortune GNU/Linux system are free software;","the exact distribution terms for each program are described in the","individual files in /usr/share/doc/*/copyright.","","Fortune GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent","permitted by applicable law."];if(r){let i=new Date(r.at),s=Number.isNaN(i.getTime())?r.at:Xt(i);n.push(`Last login: ${s} from ${r.from||"unknown"}`)}return n.push(""),`${n.map(i=>`${i}\r
|
|
333
|
+
`).join("")}`}function ie(e,t,r){let n=e==="root",i=n?"\x1B[31;1m":"\x1B[35;1m",s="\x1B[37;1m",o="\x1B[34;1m",a="\x1B[0m";return`${s}[${i}${e}${s}@${o}${t}${a} ${r}${s}]${a}${n?"#":"$"} `}import{EventEmitter as zi}from"node:events";import*as Ft from"node:os";function E(e,t,r=493){e.exists(t)||e.mkdir(t,r)}function O(e,t,r,n=420){e.exists(t)||e.writeFile(t,r,{mode:n})}function gi(e,t,r){E(e,"/etc"),O(e,"/etc/os-release",`${['NAME="Fortune GNU/Linux"',`PRETTY_NAME="${r.os}"`,"ID=fortune","ID_LIKE=debian",'HOME_URL="https://github.com/itsrealfortune/typescript-virtual-container"',"VERSION_CODENAME=aurora",'VERSION_ID="1.0"'].join(`
|
|
282
334
|
`)}
|
|
283
|
-
`),O(
|
|
284
|
-
`),O(
|
|
285
|
-
`),O(
|
|
335
|
+
`),O(e,"/etc/debian_version",`12.0
|
|
336
|
+
`),O(e,"/etc/hostname",`${t}
|
|
337
|
+
`),O(e,"/etc/shells",`/bin/sh
|
|
286
338
|
/bin/bash
|
|
287
339
|
/usr/bin/bash
|
|
288
|
-
`),O(
|
|
340
|
+
`),O(e,"/etc/profile",`${["export PATH=/usr/local/bin:/usr/bin:/bin","export PS1='\\u@\\h:\\w\\$ '"].join(`
|
|
289
341
|
`)}
|
|
290
|
-
`),O(
|
|
291
|
-
`),O(
|
|
292
|
-
`)),
|
|
342
|
+
`),O(e,"/etc/issue",`Fortune GNU/Linux 1.0 \\n \\l
|
|
343
|
+
`),O(e,"/etc/motd",["",`Welcome to ${r.os}`,`Kernel: ${r.kernel}`,""].join(`
|
|
344
|
+
`)),E(e,"/etc/apt"),E(e,"/etc/apt/sources.list.d"),O(e,"/etc/apt/sources.list",`${["# Fortune GNU/Linux package sources","deb [virtual] fortune://packages.fortune.local aurora main contrib","deb [virtual] fortune://security.fortune.local aurora-security main"].join(`
|
|
293
345
|
`)}
|
|
294
|
-
`),
|
|
346
|
+
`),E(e,"/etc/network"),O(e,"/etc/network/interfaces",`${["auto lo","iface lo inet loopback","","auto eth0","iface eth0 inet dhcp"].join(`
|
|
295
347
|
`)}
|
|
296
|
-
`),O(
|
|
348
|
+
`),O(e,"/etc/resolv.conf",`nameserver 1.1.1.1
|
|
297
349
|
nameserver 8.8.8.8
|
|
298
|
-
`),O(
|
|
350
|
+
`),O(e,"/etc/hosts",`${["127.0.0.1 localhost",`127.0.1.1 ${t}`,"::1 localhost ip6-localhost ip6-loopback"].join(`
|
|
299
351
|
`)}
|
|
300
|
-
`),
|
|
352
|
+
`),E(e,"/etc/cron.d"),E(e,"/etc/init.d"),E(e,"/etc/systemd"),E(e,"/etc/systemd/system")}function Pe(e,t){let r=t.listUsers(),n=["root:x:0:0:root:/root:/bin/bash","daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin","www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin","nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin"],i=1e3;for(let a of r)a!=="root"&&(n.push(`${a}:x:${i}:${i}::/home/${a}:/bin/bash`),i++);e.writeFile("/etc/passwd",`${n.join(`
|
|
301
353
|
`)}
|
|
302
|
-
`);let s=["root:x:0:","daemon:x:1:",`sudo:x:27:${
|
|
354
|
+
`);let s=["root:x:0:","daemon:x:1:",`sudo:x:27:${r.filter(a=>t.isSudoer(a)).join(",")}`,`users:x:100:${r.filter(a=>a!=="root").join(",")}`,"nogroup:x:65534:"];e.writeFile("/etc/group",`${s.join(`
|
|
303
355
|
`)}
|
|
304
|
-
`);let o=["root:*:19000:0:99999:7:::","daemon:*:19000:0:99999:7:::"];for(let a of
|
|
356
|
+
`);let o=["root:*:19000:0:99999:7:::","daemon:*:19000:0:99999:7:::"];for(let a of r)a!=="root"&&o.push(`${a}:!:19000:0:99999:7:::`);e.writeFile("/etc/shadow",`${o.join(`
|
|
305
357
|
`)}
|
|
306
|
-
`,{mode:416})}function
|
|
358
|
+
`,{mode:416})}function Xn(e){let t=e.match(/(\d+)$/);return 1e3+(t?.[1]?parseInt(t[1],10):0)}function ts(e,t,r,n,i,s,o){let a=`/proc/${t}`;E(e,a),E(e,`${a}/fd`),E(e,`${a}/fdinfo`);let l=Math.floor((Date.now()-new Date(s).getTime())/1e3);e.writeFile(`${a}/cmdline`,`${i.replace(/\s+/g,"\0")}\0`),e.writeFile(`${a}/comm`,i.split(/\s+/)[0]??"bash"),e.writeFile(`${a}/status`,`${[`Name: ${i.split(/\s+/)[0]??"bash"}`,"State: S (sleeping)",`Pid: ${t}`,"PPid: 1","Uid: 0 0 0 0","Gid: 0 0 0 0","VmRSS: 4096 kB","VmSize: 16384 kB","Threads: 1"].join(`
|
|
307
359
|
`)}
|
|
308
|
-
`),
|
|
309
|
-
`),
|
|
310
|
-
`);let o=Math.floor(
|
|
360
|
+
`),e.writeFile(`${a}/stat`,`${t} (${i.split(/\s+/)[0]??"bash"}) S 1 ${t} ${t} 0 -1 4194304 0 0 0 0 ${l} 0 0 0 20 0 1 0 0 16384 4096 0
|
|
361
|
+
`),e.writeFile(`${a}/environ`,`${Object.entries(o).map(([c,u])=>`${c}=${u}`).join("\0")}\0`),e.writeFile(`${a}/cwd`,`/home/${r}\0`),e.writeFile(`${a}/exe`,"/bin/bash\0"),e.writeFile(`${a}/fd/0`,""),e.writeFile(`${a}/fd/1`,""),e.writeFile(`${a}/fd/2`,"")}function oe(e,t,r,n,i){E(e,"/proc");let s=Math.floor((Date.now()-n)/1e3);e.writeFile("/proc/uptime",`${s}.00 ${Math.floor(s*.9)}.00
|
|
362
|
+
`);let o=Math.floor(Ft.totalmem()/1024),a=Math.floor(Ft.freemem()/1024),l=Math.floor(a*.95);e.writeFile("/proc/meminfo",`${[`MemTotal: ${String(o).padStart(10)} kB`,`MemFree: ${String(a).padStart(10)} kB`,`MemAvailable: ${String(l).padStart(10)} kB`,`Buffers: ${String(Math.floor(o*.02)).padStart(10)} kB`,`Cached: ${String(Math.floor(o*.15)).padStart(10)} kB`,`SwapTotal: ${String(Math.floor(o*.5)).padStart(10)} kB`,`SwapFree: ${String(Math.floor(o*.5)).padStart(10)} kB`].join(`
|
|
311
363
|
`)}
|
|
312
|
-
`);let c=
|
|
364
|
+
`);let c=Ft.cpus(),u=[];for(let f=0;f<c.length;f++){let $=c[f];if(!$)continue;let F=$.speed.toFixed(3);u.push(`processor : ${f}`,`model name : ${$.model}`,`cpu MHz : ${F}`,"cache size : 8192 KB","")}e.writeFile("/proc/cpuinfo",`${u.join(`
|
|
313
365
|
`)}
|
|
314
|
-
`),
|
|
315
|
-
`),
|
|
316
|
-
`);let d=(Math.random()*.5).toFixed(2),m=1+(i?.length??0);
|
|
317
|
-
`),
|
|
366
|
+
`),e.writeFile("/proc/version",`Linux version ${t.kernel} (fortune@build) (gcc version 12.2.0) #1 SMP
|
|
367
|
+
`),e.writeFile("/proc/hostname",`${r}
|
|
368
|
+
`);let d=(Math.random()*.5).toFixed(2),m=1+(i?.length??0);e.writeFile("/proc/loadavg",`${d} ${d} ${d} ${m}/${m} 1
|
|
369
|
+
`),E(e,"/proc/net"),O(e,"/proc/net/dev",`${["Inter-| Receive | Transmit"," face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed"," lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"," eth0: 131072 1024 0 0 0 0 0 0 65536 512 0 0 0 0 0 0"].join(`
|
|
318
370
|
`)}
|
|
319
|
-
`),
|
|
371
|
+
`),ts(e,1,"root","pts/0","/sbin/init",new Date(n).toISOString(),{});let p=i??[];for(let f of p){let $=Xn(f.tty);ts(e,$,f.username,f.tty,"bash",f.startedAt,{USER:f.username,HOME:`/home/${f.username}`,TERM:"xterm-256color",SHELL:"/bin/bash"})}let S=p.length>0?Xn(p[p.length-1].tty):1;if(e.exists("/proc/self"))try{e.remove("/proc/self")}catch{}let g=`/proc/${S}`;if(e.exists(g)){E(e,"/proc/self"),E(e,"/proc/self/fd");for(let f of e.list(g)){let $=`${g}/${f}`,F=`/proc/self/${f}`;try{e.stat($).type==="file"&&e.writeFile(F,e.readFile($))}catch{}}e.writeFile("/proc/self/status",e.exists(`${g}/status`)?e.readFile(`${g}/status`):"")}else E(e,"/proc/self"),e.writeFile("/proc/self/cmdline","bash\0"),e.writeFile("/proc/self/comm","bash"),e.writeFile("/proc/self/status",`Name: bash
|
|
320
372
|
State: S (sleeping)
|
|
321
373
|
Pid: 1
|
|
322
374
|
PPid: 0
|
|
323
|
-
`),
|
|
324
|
-
`),O(
|
|
325
|
-
`),O(
|
|
326
|
-
`),
|
|
327
|
-
`),O(
|
|
328
|
-
`),O(
|
|
329
|
-
`)}function
|
|
330
|
-
exec builtin ${
|
|
331
|
-
`,493);O(
|
|
375
|
+
`),e.writeFile("/proc/self/environ",""),e.writeFile("/proc/self/cwd","/root\0"),e.writeFile("/proc/self/exe","/bin/bash\0")}function yi(e,t){E(e,"/sys"),E(e,"/sys/devices"),E(e,"/sys/devices/virtual"),E(e,"/sys/devices/virtual/dmi"),E(e,"/sys/devices/virtual/dmi/id"),O(e,"/sys/devices/virtual/dmi/id/sys_vendor",`Fortune Systems
|
|
376
|
+
`),O(e,"/sys/devices/virtual/dmi/id/product_name",`VirtualContainer v1
|
|
377
|
+
`),O(e,"/sys/devices/virtual/dmi/id/board_name",`fortune-board
|
|
378
|
+
`),E(e,"/sys/class"),E(e,"/sys/class/net"),E(e,"/sys/kernel"),O(e,"/sys/kernel/hostname",`fortune-vm
|
|
379
|
+
`),O(e,"/sys/kernel/osrelease",`${t.kernel}
|
|
380
|
+
`),O(e,"/sys/kernel/ostype",`Linux
|
|
381
|
+
`)}function Si(e){E(e,"/dev"),O(e,"/dev/null","",438),O(e,"/dev/zero","",438),O(e,"/dev/random","",292),O(e,"/dev/urandom","",292),E(e,"/dev/pts"),E(e,"/dev/shm")}function wi(e){E(e,"/usr"),E(e,"/usr/bin"),E(e,"/usr/sbin"),E(e,"/usr/local"),E(e,"/usr/local/bin"),E(e,"/usr/local/lib"),E(e,"/usr/local/share"),E(e,"/usr/share"),E(e,"/usr/share/doc"),E(e,"/usr/share/man"),E(e,"/usr/share/man/man1"),E(e,"/usr/lib");let t=["sh","bash","ls","cat","echo","grep","find","sort","head","tail","cut","tr","sed","awk","wc","tee","tar","gzip","gunzip","touch","mkdir","rm","mv","cp","chmod","ln","pwd","env","date","sleep","id","whoami","hostname","uname","ps","kill","df","du","curl","wget","nano","diff","uniq","xargs","base64"];for(let r of t)O(e,`/usr/bin/${r}`,`#!/bin/sh
|
|
382
|
+
exec builtin ${r} "$@"
|
|
383
|
+
`,493);O(e,"/usr/bin/lsb_release",`#!/bin/sh
|
|
332
384
|
exec lsb_release "$@"
|
|
333
|
-
`,493)}function
|
|
334
|
-
`),O(
|
|
385
|
+
`,493)}function xi(e){E(e,"/var"),E(e,"/var/log"),E(e,"/var/tmp"),E(e,"/var/run"),E(e,"/var/cache"),E(e,"/var/cache/apt"),E(e,"/var/cache/apt/archives"),E(e,"/var/lib"),E(e,"/var/lib/apt"),E(e,"/var/lib/apt/lists"),E(e,"/var/lib/dpkg"),E(e,"/var/lib/dpkg/info"),O(e,"/var/lib/dpkg/status",""),O(e,"/var/lib/dpkg/available",""),O(e,"/var/log/syslog",`${new Date().toUTCString()} fortune kernel: Virtual container started
|
|
386
|
+
`),O(e,"/var/log/auth.log",""),O(e,"/var/log/dpkg.log",""),O(e,"/var/log/apt/history.log",""),O(e,"/var/log/apt/term.log","")}function bi(e){e.exists("/bin")||e.symlink("/usr/bin","/bin"),e.exists("/sbin")||e.symlink("/usr/sbin","/sbin"),e.exists("/lib")||E(e,"/lib"),e.exists("/lib64")||E(e,"/lib64")}function vi(e){E(e,"/tmp",1023)}function Ci(e){E(e,"/root",448),O(e,"/root/.bashrc",`${["# root .bashrc","export PS1='\\[\\033[0;31m\\]\\u@\\h\\[\\033[0m\\]:\\[\\033[0;34m\\]\\w\\[\\033[0m\\]# '","export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","alias ll='ls -la'","alias la='ls -A'"].join(`
|
|
335
387
|
`)}
|
|
336
|
-
`),O(
|
|
337
|
-
`),
|
|
388
|
+
`),O(e,"/root/.profile",`[ -f ~/.bashrc ] && . ~/.bashrc
|
|
389
|
+
`),e.exists("/home/root")||e.symlink("/root","/home/root")}function $i(e){E(e,"/opt"),E(e,"/srv"),E(e,"/mnt"),E(e,"/media")}function es(e,t,r,n,i){gi(e,r,n),yi(e,n),Si(e),wi(e),xi(e),bi(e),vi(e),Ci(e),$i(e),oe(e,n,r,i,[]),Pe(e,t)}function rs(e){return e==="1"||e==="true"}function ns(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function Pi(){return rs(process.env.DEV_MODE)||rs(process.env.RENDER_PERF)}function ae(e){let t=Pi();if(!t)return{enabled:t,mark:()=>{},done:()=>{}};let r=ns(),n=s=>{let o=ns()-r;console.log(`[perf][${e}] ${s}: ${o.toFixed(1)}ms`)};return{enabled:t,mark:n,done:(s="done")=>{n(s)}}}import{EventEmitter as Ei}from"node:events";import*as xt from"node:fs";import*as ht from"node:path";import{gunzipSync as Ae,gzipSync as ds}from"node:zlib";var Ee=Buffer.from([86,70,83,33]),ki=1,ss=1,is=2,ke=class{chunks=[];write(t){this.chunks.push(t)}writeUint8(t){let r=Buffer.allocUnsafe(1);r.writeUInt8(t,0),this.chunks.push(r)}writeUint16(t){let r=Buffer.allocUnsafe(2);r.writeUInt16LE(t,0),this.chunks.push(r)}writeUint32(t){let r=Buffer.allocUnsafe(4);r.writeUInt32LE(t,0),this.chunks.push(r)}writeFloat64(t){let r=Buffer.allocUnsafe(8);r.writeDoubleBE(t,0),this.chunks.push(r)}writeString(t){let r=Buffer.from(t,"utf8");this.writeUint16(r.length),this.chunks.push(r)}writeBytes(t){this.writeUint32(t.length),this.chunks.push(t)}toBuffer(){return Buffer.concat(this.chunks)}};function os(e,t){if(t.type==="file"){let r=t;e.writeUint8(ss),e.writeString(r.name),e.writeUint32(r.mode),e.writeFloat64(r.createdAt.getTime()),e.writeFloat64(r.updatedAt.getTime()),e.writeUint8(r.compressed?1:0),e.writeBytes(r.content)}else{let r=t;e.writeUint8(is),e.writeString(r.name),e.writeUint32(r.mode),e.writeFloat64(r.createdAt.getTime()),e.writeFloat64(r.updatedAt.getTime());let n=Array.from(r.children.values());e.writeUint32(n.length);for(let i of n)os(e,i)}}function as(e){let t=new ke;return t.write(Ee),t.writeUint8(ki),os(t,e),t.toBuffer()}var Me=class{constructor(t){this.buf=t}buf;pos=0;readUint8(){return this.buf.readUInt8(this.pos++)}readUint16(){let t=this.buf.readUInt16LE(this.pos);return this.pos+=2,t}readUint32(){let t=this.buf.readUInt32LE(this.pos);return this.pos+=4,t}readFloat64(){let t=this.buf.readDoubleBE(this.pos);return this.pos+=8,t}readString(){let t=this.readUint16(),r=this.buf.toString("utf8",this.pos,this.pos+t);return this.pos+=t,r}readBytes(){let t=this.readUint32(),r=this.buf.slice(this.pos,this.pos+t);return this.pos+=t,r}remaining(){return this.buf.length-this.pos}};function ls(e){let t=e.readUint8(),r=e.readString(),n=e.readUint32(),i=new Date(e.readFloat64()),s=new Date(e.readFloat64());if(t===ss){let o=e.readUint8()===1,a=e.readBytes();return{type:"file",name:r,mode:n,createdAt:i,updatedAt:s,compressed:o,content:a}}if(t===is){let o=e.readUint32(),a=new Map;for(let l=0;l<o;l++){let c=ls(e);a.set(c.name,c)}return{type:"directory",name:r,mode:n,createdAt:i,updatedAt:s,children:a}}throw new Error(`[VFS binary] Unknown node type: 0x${t.toString(16)}`)}function cs(e){if(e.length<5)throw new Error("[VFS binary] Buffer too short");if(!e.slice(0,4).equals(Ee))throw new Error("[VFS binary] Invalid magic \u2014 not a VFS binary snapshot");let r=new Me(e);for(let i=0;i<5;i++)r.readUint8();let n=ls(r);if(n.type!=="directory")throw new Error("[VFS binary] Root node must be a directory");return n}function us(e){return e.length>=4&&e.slice(0,4).equals(Ee)}import*as le from"node:path";function K(e){if(!e||e.trim()==="")return"/";let t=le.posix.normalize(e.startsWith("/")?e:`/${e}`);return t===""?"/":t}function Mi(e){return e.split("/").filter(Boolean)}function et(e,t){let r=K(t);if(r==="/")return e;let n=Mi(r),i=e;for(let s of n){if(i.type!=="directory")throw new Error(`Path '${r}' does not exist.`);let o=i.children.get(s);if(!o)throw new Error(`Path '${r}' does not exist.`);i=o}return i}function Nt(e,t,r,n){let i=K(t);if(i==="/")throw new Error("Root path has no parent directory.");let s=le.posix.dirname(i),o=le.posix.basename(i);if(!o)throw new Error(`Invalid path '${t}'.`);r&&n(s);let a=et(e,s);if(a.type!=="directory")throw new Error(`Parent path '${s}' is not a directory.`);return{parent:a,name:o}}var Fe=class e extends Ei{root;mode;snapshotFile;constructor(t={}){if(super(),this.mode=t.mode??"memory",this.mode==="fs"){if(!t.snapshotPath)throw new Error('VirtualFileSystem: "snapshotPath" is required when mode is "fs".');this.snapshotFile=ht.resolve(t.snapshotPath,"vfs-snapshot.vfsb")}else this.snapshotFile=null;this.root=this.makeDir("",493)}makeDir(t,r){let n=new Date;return{type:"directory",name:t,mode:r,createdAt:n,updatedAt:n,children:new Map}}makeFile(t,r,n,i){let s=new Date;return{type:"file",name:t,content:r,mode:n,compressed:i,createdAt:s,updatedAt:s}}mkdirRecursive(t,r){let n=K(t);if(n==="/")return;let i=n.split("/").filter(Boolean),s=this.root,o="";for(let a of i){o+=`/${a}`;let l=s.children.get(a);if(!l)l=this.makeDir(a,r),s.children.set(a,l),this.emit("dir:create",{path:o,mode:r});else if(l.type!=="directory")throw new Error(`Cannot create directory '${o}': path is a file.`);s=l}}async restoreMirror(){if(!(this.mode!=="fs"||!this.snapshotFile)&&xt.existsSync(this.snapshotFile))try{let t=xt.readFileSync(this.snapshotFile);if(us(t))this.root=cs(t);else{let r=JSON.parse(t.toString("utf8"));this.root=this.deserializeDir(r.root,""),console.info("[VirtualFileSystem] Migrating legacy JSON snapshot to binary format.")}this.emit("snapshot:restore",{path:this.snapshotFile})}catch(t){console.warn(`[VirtualFileSystem] Could not restore snapshot from ${this.snapshotFile}:`,t instanceof Error?t.message:String(t))}}async flushMirror(){if(this.mode!=="fs"||!this.snapshotFile){this.emit("mirror:flush");return}let t=ht.dirname(this.snapshotFile);xt.mkdirSync(t,{recursive:!0});let r=as(this.root);xt.writeFileSync(this.snapshotFile,r),this.emit("mirror:flush",{path:this.snapshotFile})}getMode(){return this.mode}getSnapshotPath(){return this.snapshotFile}mkdir(t,r=493){let n=K(t),i=(()=>{try{return et(this.root,n)}catch{return null}})();if(i&&i.type!=="directory")throw new Error(`Cannot create directory '${n}': path is a file.`);this.mkdirRecursive(n,r)}writeFile(t,r,n={}){let i=K(t),{parent:s,name:o}=Nt(this.root,i,!0,m=>this.mkdirRecursive(m,493)),a=s.children.get(o);if(a?.type==="directory")throw new Error(`Cannot write file '${i}': path is a directory.`);let l=Buffer.isBuffer(r)?r:Buffer.from(r,"utf8"),c=n.compress??!1,u=c?ds(l):l,d=n.mode??420;if(a){let m=a;m.content=u,m.compressed=c,m.mode=d,m.updatedAt=new Date}else s.children.set(o,this.makeFile(o,u,d,c));this.emit("file:write",{path:i,size:u.length})}readFile(t){let r=K(t),n=et(this.root,r);if(n.type!=="file")throw new Error(`Cannot read '${t}': not a file.`);let i=n,s=i.compressed?Ae(i.content):i.content;return this.emit("file:read",{path:r,size:s.length}),s.toString("utf8")}readFileRaw(t){let r=K(t),n=et(this.root,r);if(n.type!=="file")throw new Error(`Cannot read '${t}': not a file.`);let i=n,s=i.compressed?Ae(i.content):i.content;return this.emit("file:read",{path:r,size:s.length}),s}exists(t){try{return et(this.root,K(t)),!0}catch{return!1}}chmod(t,r){et(this.root,K(t)).mode=r}stat(t){let r=K(t),n=et(this.root,r),i=r==="/"?"":ht.posix.basename(r);if(n.type==="file"){let o=n;return{type:"file",name:i,path:r,mode:o.mode,createdAt:o.createdAt,updatedAt:o.updatedAt,compressed:o.compressed,size:o.content.length}}let s=n;return{type:"directory",name:i,path:r,mode:s.mode,createdAt:s.createdAt,updatedAt:s.updatedAt,childrenCount:s.children.size}}list(t="/"){let r=K(t),n=et(this.root,r);if(n.type!=="directory")throw new Error(`Cannot list '${t}': not a directory.`);return Array.from(n.children.keys()).sort()}tree(t="/"){let r=K(t),n=et(this.root,r);if(n.type!=="directory")throw new Error(`Cannot render tree for '${t}': not a directory.`);let i=t==="/"?"/":ht.posix.basename(r);return this.renderTreeLines(n,i)}renderTreeLines(t,r){let n=[r],i=Array.from(t.children.keys()).sort();for(let s=0;s<i.length;s++){let o=i[s],a=t.children.get(o),l=s===i.length-1,c=l?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",u=l?" ":"\u2502 ";if(n.push(`${c}${o}`),a.type==="directory"){let d=this.renderTreeLines(a,"").split(`
|
|
338
390
|
`).slice(1).map(m=>`${u}${m}`);n.push(...d)}}return n.join(`
|
|
339
|
-
`)}getUsageBytes(t="/"){return this.computeUsage(
|
|
391
|
+
`)}getUsageBytes(t="/"){return this.computeUsage(et(this.root,K(t)))}computeUsage(t){if(t.type==="file")return t.content.length;let r=0;for(let n of t.children.values())r+=this.computeUsage(n);return r}compressFile(t){let r=et(this.root,K(t));if(r.type!=="file")throw new Error(`Cannot compress '${t}': not a file.`);let n=r;n.compressed||(n.content=ds(n.content),n.compressed=!0,n.updatedAt=new Date)}decompressFile(t){let r=et(this.root,K(t));if(r.type!=="file")throw new Error(`Cannot decompress '${t}': not a file.`);let n=r;n.compressed&&(n.content=Ae(n.content),n.compressed=!1,n.updatedAt=new Date)}symlink(t,r){let n=K(r),i=t.startsWith("/")?K(t):t,{parent:s,name:o}=Nt(this.root,n,!0,l=>this.mkdirRecursive(l,493)),a={type:"file",name:o,content:Buffer.from(i,"utf8"),mode:41471,compressed:!1,createdAt:new Date,updatedAt:new Date};s.children.set(o,a),this.emit("symlink:create",{link:n,target:i})}isSymlink(t){try{let r=et(this.root,K(t));return r.type==="file"&&r.mode===41471}catch{return!1}}resolveSymlink(t,r=8){let n=K(t);for(let i=0;i<r;i++){try{let s=et(this.root,n);if(s.type==="file"&&s.mode===41471){let o=s.content.toString("utf8");n=o.startsWith("/")?o:K(ht.posix.join(ht.posix.dirname(n),o));continue}}catch{break}return n}throw new Error(`Too many levels of symbolic links: ${t}`)}remove(t,r={}){let n=K(t);if(n==="/")throw new Error("Cannot remove root directory.");let i=et(this.root,n);if(i.type==="directory"){let a=i;if(!r.recursive&&a.children.size>0)throw new Error(`Directory '${n}' is not empty. Use recursive option.`)}let{parent:s,name:o}=Nt(this.root,n,!1,()=>{});s.children.delete(o),this.emit("node:remove",{path:n})}move(t,r){let n=K(t),i=K(r);if(n==="/"||i==="/")throw new Error("Cannot move root directory.");let s=et(this.root,n);if(this.exists(i))throw new Error(`Destination '${i}' already exists.`);this.mkdirRecursive(ht.posix.dirname(i),493);let{parent:o,name:a}=Nt(this.root,i,!1,()=>{}),{parent:l,name:c}=Nt(this.root,n,!1,()=>{});l.children.delete(c),s.name=a,o.children.set(a,s)}toSnapshot(){return{root:this.serializeDir(this.root)}}serializeDir(t){let r=[];for(let n of t.children.values())r.push(n.type==="file"?this.serializeFile(n):this.serializeDir(n));return{type:"directory",name:t.name,mode:t.mode,createdAt:t.createdAt.toISOString(),updatedAt:t.updatedAt.toISOString(),children:r}}serializeFile(t){return{type:"file",name:t.name,mode:t.mode,createdAt:t.createdAt.toISOString(),updatedAt:t.updatedAt.toISOString(),compressed:t.compressed,contentBase64:t.content.toString("base64")}}static fromSnapshot(t){let r=new e;return r.root=r.deserializeDir(t.root,""),r}importSnapshot(t){this.root=this.deserializeDir(t.root,""),this.emit("snapshot:import")}deserializeDir(t,r){let n={type:"directory",name:r,mode:t.mode,createdAt:new Date(t.createdAt),updatedAt:new Date(t.updatedAt),children:new Map};for(let i of t.children)if(i.type==="file"){let s=i;n.children.set(s.name,{type:"file",name:s.name,mode:s.mode,createdAt:new Date(s.createdAt),updatedAt:new Date(s.updatedAt),compressed:s.compressed,content:Buffer.from(s.contentBase64,"base64")})}else{let s=this.deserializeDir(i,i.name);n.children.set(i.name,s)}return n}},ms=Fe;var Ne=[{name:"vim",version:"2:9.0.1378-2",section:"editors",description:"Vi IMproved - enhanced vi editor",shortDesc:"Vi IMproved",installedSizeKb:3812,files:[{path:"/usr/bin/vim",content:`#!/bin/sh
|
|
340
392
|
echo 'vim: use nano for editing in this environment'
|
|
341
393
|
`,mode:493},{path:"/usr/bin/vi",content:`#!/bin/sh
|
|
342
394
|
exec vim "$@"
|
|
@@ -409,7 +461,7 @@ echo 'rsync: virtual stub'
|
|
|
409
461
|
echo 'tmux: terminal multiplexer (virtual stub)'
|
|
410
462
|
`,mode:493}]},{name:"tree",version:"2.1.0-1",section:"utils",description:"Displays an indented directory tree, in color",shortDesc:"list files in tree format",installedSizeKb:108,files:[{path:"/usr/bin/tree",content:`#!/bin/sh
|
|
411
463
|
exec builtin tree "$@"
|
|
412
|
-
`,mode:493}]},{name:"ca-certificates",version:"20230311",section:"misc",description:"Common CA certificates",shortDesc:"common CA certificates",installedSizeKb:388,files:[{path:"/etc/ssl/certs/.keep",content:""},{path:"/etc/ssl/private/.keep",content:""},{path:"/usr/share/ca-certificates/.keep",content:""}],onInstall:
|
|
464
|
+
`,mode:493}]},{name:"ca-certificates",version:"20230311",section:"misc",description:"Common CA certificates",shortDesc:"common CA certificates",installedSizeKb:388,files:[{path:"/etc/ssl/certs/.keep",content:""},{path:"/etc/ssl/private/.keep",content:""},{path:"/usr/share/ca-certificates/.keep",content:""}],onInstall:e=>{e.exists("/etc/ssl")||e.mkdir("/etc/ssl",493),e.exists("/etc/ssl/certs")||e.mkdir("/etc/ssl/certs",493)}},{name:"locales",version:"2.36-9+deb12u3",section:"localization",description:"GNU C Library: National Language (locale) data",shortDesc:"locale data",installedSizeKb:16484,files:[{path:"/etc/locale.gen",content:`en_US.UTF-8 UTF-8
|
|
413
465
|
`},{path:"/etc/default/locale",content:`LANG=en_US.UTF-8
|
|
414
466
|
LANGUAGE=en_US:en
|
|
415
467
|
`}]},{name:"sudo",version:"1.9.13p3-1+deb12u1",section:"admin",description:"Provide limited super user privileges to specific users",shortDesc:"super user privilege execution",installedSizeKb:2304,files:[{path:"/usr/bin/sudo",content:`#!/bin/sh
|
|
@@ -421,62 +473,76 @@ echo 'systemd is not running in this virtual container.'
|
|
|
421
473
|
exit 1
|
|
422
474
|
`,mode:493},{path:"/usr/bin/journalctl",content:`#!/bin/sh
|
|
423
475
|
echo 'journalctl: virtual stub'
|
|
424
|
-
`,mode:493}]}],
|
|
476
|
+
`,mode:493}]}],ce=class{constructor(t,r){this.vfs=t;this.users=r}vfs;users;installed=new Map;registryPath="/var/lib/dpkg/status";logPath="/var/log/dpkg.log";aptLogPath="/var/log/apt/history.log";load(){if(!this.vfs.exists(this.registryPath))return;let t=this.vfs.readFile(this.registryPath);if(!t.trim())return;let r=t.split(/\n\n+/);for(let n of r){if(!n.trim())continue;let i=this.parseFields(n),s=i.Package;s&&this.installed.set(s,{name:s,version:i.Version??"unknown",architecture:i.Architecture??"amd64",maintainer:i.Maintainer??"Fortune Maintainers",description:i.Description??"",section:i.Section??"misc",installedSizeKb:Number(i["Installed-Size"]??0),installedAt:i["X-Installed-At"]??new Date().toISOString(),files:(i["X-Files"]??"").split("|").filter(Boolean)})}}persist(){let t=[];for(let r of this.installed.values())t.push([`Package: ${r.name}`,"Status: install ok installed","Priority: optional",`Section: ${r.section}`,`Installed-Size: ${r.installedSizeKb}`,`Maintainer: ${r.maintainer}`,`Architecture: ${r.architecture}`,`Version: ${r.version}`,`Description: ${r.description}`,`X-Installed-At: ${r.installedAt}`,`X-Files: ${r.files.join("|")}`].join(`
|
|
425
477
|
`));this.vfs.writeFile(this.registryPath,`${t.join(`
|
|
426
478
|
|
|
427
479
|
`)}
|
|
428
|
-
`)}parseFields(t){let
|
|
429
|
-
`)){let i=n.indexOf(": ");i!==-1&&(
|
|
430
|
-
`,i=this.vfs.exists(this.logPath)?this.vfs.readFile(this.logPath):"";this.vfs.writeFile(this.logPath,i+n)}aptLog(t,
|
|
431
|
-
`);this.vfs.writeFile(this.aptLogPath,i+s)}findInRegistry(t){return
|
|
432
|
-
`),exitCode:0};let a=i.reduce((l,c)=>l+(c.installedSizeKb??0),0);
|
|
433
|
-
`),exitCode:0}}remove(t,
|
|
434
|
-
`)||"Nothing to remove.",exitCode:0};
|
|
435
|
-
`),exitCode:0}}search(t){let
|
|
436
|
-
`)}};import{createHash as
|
|
437
|
-
`)){let i=n.trim();if(i.length===0)continue;let s=i.split(":");if(s.length<3)continue;let[o,a,l]=s;!o||!a||!l||this.users.set(o,{username:o,salt:a,passwordHash:l})}}loadSudoersFromVfs(){if(this.sudoers.clear(),!this.vfs.exists(this.sudoersPath))return;let
|
|
438
|
-
`)){let i=n.trim();i.length>0&&this.sudoers.add(i)}}loadQuotasFromVfs(){if(this.quotas.clear(),!this.vfs.exists(this.quotasPath))return;let
|
|
439
|
-
`)){let i=n.trim();if(i.length===0)continue;let[s,o]=i.split(":"),a=Number.parseInt(o??"",10);!s||!Number.isFinite(a)||a<0||this.quotas.set(s,a)}}async persist(){this.vfs.exists(this.authDirPath)||this.vfs.mkdir(this.authDirPath,448);let
|
|
480
|
+
`)}parseFields(t){let r={};for(let n of t.split(`
|
|
481
|
+
`)){let i=n.indexOf(": ");i!==-1&&(r[n.slice(0,i)]=n.slice(i+2))}return r}log(t){let n=`${new Date().toISOString().replace("T"," ").slice(0,19)} ${t}
|
|
482
|
+
`,i=this.vfs.exists(this.logPath)?this.vfs.readFile(this.logPath):"";this.vfs.writeFile(this.logPath,i+n)}aptLog(t,r){let n=new Date().toISOString(),i=this.vfs.exists(this.aptLogPath)?this.vfs.readFile(this.aptLogPath):"",s=[`Start-Date: ${n}`,`Commandline: apt-get ${t} ${r.join(" ")}`,`${t==="install"?"Install":"Remove"}: ${r.join(", ")}`,`End-Date: ${n}`,""].join(`
|
|
483
|
+
`);this.vfs.writeFile(this.aptLogPath,i+s)}findInRegistry(t){return Ne.find(r=>r.name.toLowerCase()===t.toLowerCase())}listAvailable(){return[...Ne].sort((t,r)=>t.name.localeCompare(r.name))}listInstalled(){return[...this.installed.values()].sort((t,r)=>t.name.localeCompare(r.name))}isInstalled(t){return this.installed.has(t.toLowerCase())}installedCount(){return this.installed.size}install(t,r={}){let n=[],i=[],s=[],o=(l,c=new Set)=>{if(c.has(l)||(c.add(l),this.isInstalled(l)))return;let u=this.findInRegistry(l);if(!u){s.push(l);return}for(let d of u.depends??[])o(d,c);i.find(d=>d.name===u.name)||i.push(u)};for(let l of t)o(l);if(s.length>0)return{output:`E: Unable to locate package ${s.join(", ")}`,exitCode:100};if(i.length===0)return{output:t.map(l=>`${l} is already the newest version.`).join(`
|
|
484
|
+
`),exitCode:0};let a=i.reduce((l,c)=>l+(c.installedSizeKb??0),0);r.quiet||n.push("Reading package lists... Done","Building dependency tree... Done","Reading state information... Done","The following NEW packages will be installed:",` ${i.map(l=>l.name).join(" ")}`,`0 upgraded, ${i.length} newly installed, 0 to remove and 0 not upgraded.`,`Need to get 0 B/${a} kB of archives.`,`After this operation, ${a} kB of additional disk space will be used.`,"");for(let l of i){r.quiet||(n.push(`Selecting previously unselected package ${l.name}.`),n.push("(Reading database ... 12345 files and directories currently installed.)"),n.push(`Preparing to unpack .../archives/${l.name}_${l.version}_amd64.deb ...`),n.push(`Unpacking ${l.name} (${l.version}) ...`));for(let u of l.files??[]){let d=u.path.slice(0,u.path.lastIndexOf("/"));d&&!this.vfs.exists(d)&&this.vfs.mkdir(d,493),this.vfs.writeFile(u.path,u.content,{mode:u.mode??420})}l.onInstall?.(this.vfs,this.users),r.quiet||n.push(`Setting up ${l.name} (${l.version}) ...`);let c=new Date().toISOString();this.installed.set(l.name,{name:l.name,version:l.version,architecture:l.architecture??"amd64",maintainer:l.maintainer??"Fortune Maintainers <pkg@fortune.local>",description:l.description,section:l.section??"misc",installedSizeKb:l.installedSizeKb??0,installedAt:c,files:(l.files??[]).map(u=>u.path)}),this.log(`install ${l.name} ${l.version}`)}return this.aptLog("install",i.map(l=>l.name)),this.persist(),r.quiet||n.push("Processing triggers for man-db (2.11.2-2) ..."),{output:n.join(`
|
|
485
|
+
`),exitCode:0}}remove(t,r={}){let n=[],i=[];for(let s of t){let o=this.installed.get(s.toLowerCase());o?i.push(o):n.push(`Package '${s}' is not installed, so not removed`)}if(i.length===0)return{output:n.join(`
|
|
486
|
+
`)||"Nothing to remove.",exitCode:0};r.quiet||n.push("Reading package lists... Done","Building dependency tree... Done","The following packages will be REMOVED:",` ${i.map(s=>s.name).join(" ")}`,`0 upgraded, 0 newly installed, ${i.length} to remove and 0 not upgraded.`);for(let s of i){r.quiet||n.push(`Removing ${s.name} (${s.version}) ...`);for(let a of s.files)if(!(!r.purge&&(a.startsWith("/etc/")||a.endsWith(".conf"))))try{this.vfs.exists(a)&&this.vfs.remove(a)}catch{}this.findInRegistry(s.name)?.onRemove?.(this.vfs),this.installed.delete(s.name),this.log(`remove ${s.name} ${s.version}`)}return this.aptLog("remove",i.map(s=>s.name)),this.persist(),{output:n.join(`
|
|
487
|
+
`),exitCode:0}}search(t){let r=t.toLowerCase();return Ne.filter(n=>n.name.includes(r)||n.description.toLowerCase().includes(r)||(n.shortDesc??"").toLowerCase().includes(r)).sort((n,i)=>n.name.localeCompare(i.name))}show(t){let r=this.findInRegistry(t);if(!r)return null;let n=this.installed.get(t);return[`Package: ${r.name}`,`Version: ${r.version}`,`Architecture: ${r.architecture??"amd64"}`,`Maintainer: ${r.maintainer??"Fortune Maintainers <pkg@fortune.local>"}`,`Installed-Size: ${r.installedSizeKb??0}`,`Depends: ${(r.depends??[]).join(", ")||"(none)"}`,`Section: ${r.section??"misc"}`,"Priority: optional",`Description: ${r.description}`,`Status: ${n?"install ok installed":"install ok not-installed"}`].join(`
|
|
488
|
+
`)}};import{createHash as ps,randomBytes as Ai,randomUUID as Fi,scryptSync as Ni,timingSafeEqual as Ii}from"node:crypto";import{EventEmitter as Ri}from"node:events";import*as hs from"node:path";function Vi(){let e=process.env.SSH_MIMIC_FAST_PASSWORD_HASH;return!!e&&!["0","false","no","off"].includes(e.toLowerCase())}var Q=ae("VirtualUserManager"),ue=class e extends Ri{constructor(r,n=!0){super();this.vfs=r;this.autoSudoForNewUsers=n;Q.mark("constructor")}vfs;autoSudoForNewUsers;static recordCache=new Map;static fastPasswordHash=Vi();usersPath="/virtual-env-js/.auth/htpasswd";sudoersPath="/virtual-env-js/.auth/sudoers";quotasPath="/virtual-env-js/.auth/quotas";authDirPath="/virtual-env-js/.auth";users=new Map;sudoers=new Set;quotas=new Map;activeSessions=new Map;nextTty=0;async initialize(){Q.mark("initialize"),this.loadFromVfs(),this.loadSudoersFromVfs(),this.loadQuotasFromVfs();let r=!1;this.users.has("root")||(this.users.set("root",this.createRecord("root","")),r=!0),this.sudoers.add("root"),r&&await this.persist(),this.emit("initialized")}async setQuotaBytes(r,n){if(Q.mark("setQuotaBytes"),this.validateUsername(r),!this.users.has(r))throw new Error(`quota: user '${r}' does not exist`);if(!Number.isFinite(n)||n<0)throw new Error("quota: maxBytes must be a non-negative number");this.quotas.set(r,Math.floor(n)),await this.persist()}async clearQuota(r){Q.mark("clearQuota"),this.validateUsername(r),this.quotas.delete(r),await this.persist()}getQuotaBytes(r){return Q.mark("getQuotaBytes"),this.quotas.get(r)??null}getUsageBytes(r){Q.mark("getUsageBytes");let n=`/home/${r}`;return this.vfs.exists(n)?this.vfs.getUsageBytes(n):0}assertWriteWithinQuota(r,n,i){Q.mark("assertWriteWithinQuota");let s=this.quotas.get(r);if(s===void 0)return;let o=fs(n),a=fs(`/home/${r}`);if(!(o===a||o.startsWith(`${a}/`)))return;let c=this.getUsageBytes(r),u=0;if(this.vfs.exists(o)){let p=this.vfs.stat(o);p.type==="file"&&(u=p.size)}let d=Buffer.isBuffer(i)?i.length:Buffer.byteLength(i,"utf8"),m=c-u+d;if(m>s)throw new Error(`quota exceeded for '${r}': ${m}/${s} bytes`)}verifyPassword(r,n){Q.mark("verifyPassword");let i=this.users.get(r);if(!i)return this.hashPassword(n,""),!1;let s=this.hashPassword(n,i.salt),o=i.passwordHash;try{let a=Buffer.from(s,"hex"),l=Buffer.from(o,"hex");return a.length!==l.length?!1:Ii(a,l)}catch{return s===o}}async addUser(r,n){if(Q.mark("addUser"),this.validateUsername(r),this.validatePassword(n),this.users.has(r))return;this.users.set(r,this.createRecord(r,n)),this.autoSudoForNewUsers&&this.sudoers.add(r);let i=`/home/${r}`;this.vfs.exists(i)||(this.vfs.mkdir(i,493),this.vfs.writeFile(`${i}/README.txt`,`Welcome to the virtual environment, ${r}`)),await this.persist(),this.emit("user:add",{username:r})}getPasswordHash(r){Q.mark("getPasswordHash");let n=this.users.get(r);return n?n.passwordHash:null}async setPassword(r,n){if(Q.mark("setPassword"),this.validateUsername(r),this.validatePassword(n),!this.users.has(r))throw new Error(`passwd: user '${r}' does not exist`);this.users.set(r,this.createRecord(r,n)),await this.persist()}async deleteUser(r){if(Q.mark("deleteUser"),this.validateUsername(r),r==="root")throw new Error("deluser: cannot delete root");if(!this.users.delete(r))throw new Error(`deluser: user '${r}' does not exist`);this.sudoers.delete(r),this.emit("user:delete",{username:r}),await this.persist()}isSudoer(r){return Q.mark("isSudoer"),this.sudoers.has(r)}async addSudoer(r){if(Q.mark("addSudoer"),this.validateUsername(r),!this.users.has(r))throw new Error(`sudoers: user '${r}' does not exist`);this.sudoers.add(r),await this.persist()}async removeSudoer(r){if(Q.mark("removeSudoer"),this.validateUsername(r),r==="root")throw new Error("sudoers: cannot remove root");this.sudoers.delete(r),await this.persist()}registerSession(r,n){Q.mark("registerSession");let i={id:Fi(),username:r,tty:`pts/${this.nextTty++}`,remoteAddress:n,startedAt:new Date().toISOString()};return this.activeSessions.set(i.id,i),this.emit("session:register",{sessionId:i.id,username:r,remoteAddress:n}),i}unregisterSession(r){if(Q.mark("unregisterSession"),!r)return;let n=this.activeSessions.get(r);this.activeSessions.delete(r),n&&this.emit("session:unregister",{sessionId:r,username:n.username}),this.activeSessions.delete(r)}updateSession(r,n,i){if(Q.mark("updateSession"),!r)return;let s=this.activeSessions.get(r);s&&this.activeSessions.set(r,{...s,username:n,remoteAddress:i})}listActiveSessions(){return Q.mark("listActiveSessions"),Array.from(this.activeSessions.values()).sort((r,n)=>r.startedAt.localeCompare(n.startedAt))}listUsers(){return Array.from(this.users.keys()).sort()}loadFromVfs(){if(this.users.clear(),!this.vfs.exists(this.usersPath))return;let r=this.vfs.readFile(this.usersPath);for(let n of r.split(`
|
|
489
|
+
`)){let i=n.trim();if(i.length===0)continue;let s=i.split(":");if(s.length<3)continue;let[o,a,l]=s;!o||!a||!l||this.users.set(o,{username:o,salt:a,passwordHash:l})}}loadSudoersFromVfs(){if(this.sudoers.clear(),!this.vfs.exists(this.sudoersPath))return;let r=this.vfs.readFile(this.sudoersPath);for(let n of r.split(`
|
|
490
|
+
`)){let i=n.trim();i.length>0&&this.sudoers.add(i)}}loadQuotasFromVfs(){if(this.quotas.clear(),!this.vfs.exists(this.quotasPath))return;let r=this.vfs.readFile(this.quotasPath);for(let n of r.split(`
|
|
491
|
+
`)){let i=n.trim();if(i.length===0)continue;let[s,o]=i.split(":"),a=Number.parseInt(o??"",10);!s||!Number.isFinite(a)||a<0||this.quotas.set(s,a)}}async persist(){this.vfs.exists(this.authDirPath)||this.vfs.mkdir(this.authDirPath,448);let r=Array.from(this.users.values()).sort((o,a)=>o.username.localeCompare(a.username)).map(o=>[o.username,o.salt,o.passwordHash].join(":")).join(`
|
|
440
492
|
`),n=Array.from(this.sudoers.values()).sort().join(`
|
|
441
493
|
`),i=Array.from(this.quotas.entries()).sort(([o],[a])=>o.localeCompare(a)).map(([o,a])=>`${o}:${a}`).join(`
|
|
442
|
-
`),s=!1;s=this.writeIfChanged(this.usersPath,
|
|
494
|
+
`),s=!1;s=this.writeIfChanged(this.usersPath,r.length>0?`${r}
|
|
443
495
|
`:"",384)||s,s=this.writeIfChanged(this.sudoersPath,n.length>0?`${n}
|
|
444
496
|
`:"",384)||s,s=this.writeIfChanged(this.quotasPath,i.length>0?`${i}
|
|
445
|
-
`:"",384)||s,s&&await this.vfs.flushMirror()}writeIfChanged(
|
|
446
|
-
`).
|
|
447
|
-
`).replace(/\n/g,`\r
|
|
448
|
-
`)}function rs(r,t){let e=Number.isFinite(t.cols)&&t.cols>0?Math.floor(t.cols):80,n=Number.isFinite(t.rows)&&t.rows>0?Math.floor(t.rows):24;return`stty cols ${e} rows ${n} 2>/dev/null; ${r}`}function ns(r,t){return!t||t.trim()===""||t==="."?r:t.startsWith("/")?ie.posix.normalize(t):ie.posix.normalize(ie.posix.join(r,t))}async function ss(r){try{let e=(await Ei(`/proc/${r}/task/${r}/children`,"utf8")).trim().split(/\s+/).filter(Boolean).map(i=>Number.parseInt(i,10)).filter(i=>Number.isInteger(i)&&i>0),n=await Promise.all(e.map(i=>ss(i)));return[...e,...n.flat()]}catch{return[]}}async function is(r=process.pid){let t=await ss(r),e=Array.from(new Set(t)).sort((n,i)=>n-i);return e.length===0?null:e.join(",")}function os(r,t,e){let n=rs(r,t),i=Ai("script",["-qfec",n,"/dev/null"],{stdio:["pipe","pipe","pipe"],env:{...process.env,TERM:process.env.TERM??"xterm-256color"}});return i.stdout.on("data",s=>{e.write(s.toString("utf8"))}),i.stderr.on("data",s=>{e.write(s.toString("utf8"))}),i}function as(r,t,e){return os(`nano -- ${Me(r)}`,t,e)}function ls(r,t,e){return os(`htop -p ${Me(r)}`,t,e)}function cs(r,t,e,n,i,s="unknown",o={cols:80,rows:24},a){let l="",c=0,u=Vi(a.vfs),d=null,m="",f=`/home/${e}`,x=kt(e,n),g=null,y=null,$=()=>{let C=`/home/${e}`,A=f===C?"~":Ee.posix.basename(f)||"/";return Xt(e,n,A)},V=Array.from(new Set(xe())).sort();console.log(`[${i}] Shell started for user '${e}' at ${s}`),(async()=>{let C=`/home/${e}/.bashrc`;if(a.vfs.exists(C))try{let A=a.vfs.readFile(C);for(let _ of A.split(`
|
|
449
|
-
`)){let F=_.trim();!F||F.startsWith("#")||await Z(F,e,n,"shell",f,a,void 0,x)}}catch{}})();function k(){let C=$();t.write(`\r${C}${l}\x1B[K`);let A=l.length-c;A>0&&t.write(`\x1B[${A}D`)}function R(){t.write("\r\x1B[K")}function D(C){y={...C,buffer:""},R(),t.write(C.prompt)}async function tt(C){if(!y)return;let A=y;if(y=null,!C){t.write(`\r
|
|
497
|
+
`:"",384)||s,s&&await this.vfs.flushMirror()}writeIfChanged(r,n,i){return this.vfs.exists(r)&&this.vfs.readFile(r)===n?(this.vfs.chmod(r,i),!1):(this.vfs.writeFile(r,n,{mode:i}),!0)}createRecord(r,n){let i=ps("sha256").update(r).update(":").update(n).digest("hex"),s=e.recordCache.get(i);if(s)return s;let o=Ai(16).toString("hex"),a={username:r,salt:o,passwordHash:this.hashPassword(n,o)};return e.recordCache.set(i,a),a}hasPassword(r){Q.mark("hasPassword");let n=this.users.get(r);if(!n)return!1;let i=this.hashPassword("",n.salt);return n.passwordHash===i?!1:!!n.passwordHash}hashPassword(r,n=""){return e.fastPasswordHash?ps("sha256").update(n).update(r).digest("hex"):Ni(r,n||"",32).toString("hex")}validateUsername(r){if(!r||r.trim()==="")throw new Error("invalid username");if(!/^[a-z_][a-z0-9_-]{0,31}$/i.test(r))throw new Error("invalid username")}validatePassword(r){if(!r||r.trim()==="")throw new Error("invalid password")}authorizedKeys=new Map;addAuthorizedKey(r,n,i){Q.mark("addAuthorizedKey");let s=this.authorizedKeys.get(r)??[];s.push({algo:n,data:i}),this.authorizedKeys.set(r,s),this.emit("key:add",{username:r,algo:n})}removeAuthorizedKeys(r){this.authorizedKeys.delete(r),this.emit("key:remove",{username:r})}getAuthorizedKeys(r){return this.authorizedKeys.get(r)??[]}};function fs(e){let t=hs.posix.normalize(e);return t.startsWith("/")?t:`/${t}`}import{readFile as Di,unlink as _i,writeFile as Li}from"node:fs/promises";import*as Ie from"node:path";function gs(e,t,r,n,i,s="unknown",o={cols:80,rows:24},a){let l="",c=0,u=Ti(a.vfs),d=null,m="",p=`/home/${r}`,S=At(r,n),g=null,f=null,$=()=>{let A=`/home/${r}`,D=p===A?"~":Ie.posix.basename(p)||"/";return ie(r,n,D)},F=Array.from(new Set(Ce())).sort();console.log(`[${i}] Shell started for user '${r}' at ${s}`),(async()=>{let A=`/home/${r}/.bashrc`;if(a.vfs.exists(A))try{let D=a.vfs.readFile(A);for(let T of D.split(`
|
|
498
|
+
`)){let _=T.trim();!_||_.startsWith("#")||await q(_,r,n,"shell",p,a,void 0,S)}}catch{}})();function M(){let A=$();t.write(`\r${A}${l}\x1B[K`);let D=l.length-c;D>0&&t.write(`\x1B[${D}D`)}function w(){t.write("\r\x1B[K")}function k(A){f={...A,buffer:""},w(),t.write(A.prompt)}async function R(A){if(!f)return;let D=f;if(f=null,!A){t.write(`\r
|
|
450
499
|
Sorry, try again.\r
|
|
451
|
-
`),
|
|
452
|
-
`),
|
|
453
|
-
`),
|
|
454
|
-
`),
|
|
455
|
-
`),
|
|
456
|
-
`),
|
|
457
|
-
`),
|
|
458
|
-
`);return}let
|
|
459
|
-
`),
|
|
460
|
-
`),t.write(`${
|
|
461
|
-
`),
|
|
500
|
+
`),M();return}if(!D.commandLine){r=D.targetUser,D.loginShell&&(p=`/home/${r}`),a.users.updateSession(i,r,s),t.write(`\r
|
|
501
|
+
`),M();return}let T=D.loginShell?`/home/${D.targetUser}`:p,_=await Promise.resolve(q(D.commandLine,D.targetUser,n,"shell",T,a));if(t.write(`\r
|
|
502
|
+
`),_.openEditor){await P(_.openEditor.targetPath,_.openEditor.initialContent,_.openEditor.tempPath);return}if(_.openHtop){await V();return}_.clearScreen&&t.write("\x1B[2J\x1B[H"),_.stdout&&t.write(`${Ot(_.stdout)}\r
|
|
503
|
+
`),_.stderr&&t.write(`${Ot(_.stderr)}\r
|
|
504
|
+
`),_.switchUser?(r=_.switchUser,p=_.nextCwd??`/home/${r}`,a.users.updateSession(i,r,s)):_.nextCwd&&(p=_.nextCwd),await a.vfs.flushMirror(),M()}async function b(){if(!g)return;let A=g;if(A.kind==="nano"){try{let D=await Di(A.tempPath,"utf8");a.writeFileAsUser(r,A.targetPath,D),await a.vfs.flushMirror()}catch{}await _i(A.tempPath).catch(()=>{})}g=null,l="",c=0,t.write(`\r
|
|
505
|
+
`),M()}async function P(A,D,T){a.vfs.exists(A)&&await Li(T,D,"utf8");let _=ne(T,o,t);_.on("error",X=>{t.write(`nano: ${X.message}\r
|
|
506
|
+
`),b()}),_.on("close",()=>{b()}),g={kind:"nano",targetPath:A,tempPath:T,process:_}}async function V(){let A=await Jn();if(!A){t.write(`htop: no child_process processes to display\r
|
|
507
|
+
`);return}let D=Qn(A,o,t);D.on("error",T=>{t.write(`htop: ${T.message}\r
|
|
508
|
+
`),b()}),D.on("close",()=>{b()}),g={kind:"htop",targetPath:"",tempPath:"",process:D}}function C(A){l=A,c=l.length,M()}function v(A){l=`${l.slice(0,c)}${A}${l.slice(c)}`,c+=A.length,M()}function N(A,D){let T=D;for(;T>0&&!/\s/.test(A[T-1]);)T-=1;let _=D;for(;_<A.length&&!/\s/.test(A[_]);)_+=1;return{start:T,end:_}}function G(A){let D=A.lastIndexOf("/"),T=D>=0?A.slice(0,D+1):"",_=D>=0?A.slice(D+1):A,X=Gn(p,T||".");try{return a.vfs.list(X).filter(z=>!z.startsWith(".")).filter(z=>z.startsWith(_)).map(z=>{let ct=Ie.posix.join(X,z),bt=a.vfs.stat(ct).type==="directory"?"/":"";return`${T}${z}${bt}`}).sort()}catch{return[]}}function U(){let{start:A,end:D}=N(l,c),T=l.slice(A,c);if(T.length===0)return;let X=l.slice(0,A).trim().length===0?F.filter(at=>at.startsWith(T)):[],z=G(T),ct=Array.from(new Set([...X,...z])).sort();if(ct.length!==0){if(ct.length===1){let at=ct[0],bt=at.endsWith("/")?"":" ";l=`${l.slice(0,A)}${at}${bt}${l.slice(D)}`,c=A+at.length+bt.length,M();return}t.write(`\r
|
|
509
|
+
`),t.write(`${ct.join(" ")}\r
|
|
510
|
+
`),M()}}function Z(A){if(A.length===0)return;u.push(A),u.length>500&&(u=u.slice(u.length-500));let D=u.length>0?`${u.join(`
|
|
511
|
+
`)}
|
|
512
|
+
`:"";a.vfs.writeFile("/virtual-env-js/.bash_history",D)}function gt(){let A=`/virtual-env-js/.lastlog/${r}.json`;if(!a.vfs.exists(A))return null;try{return JSON.parse(a.vfs.readFile(A))}catch{return null}}function lt(A){let D="/virtual-env-js/.lastlog";a.vfs.exists(D)||a.vfs.mkdir(D,448);let T=`${D}/${r}.json`;a.vfs.writeFile(T,JSON.stringify({at:A,from:s}))}function yt(){let A=gt(),D=new Date().toISOString();t.write(se(n,e,A)),lt(D)}yt(),M(),t.on("data",async A=>{if(g){g.process.stdin.write(A);return}if(f){let T=A.toString("utf8");for(let _=0;_<T.length;_+=1){let X=T[_];if(X===""){f=null,t.write(`^C\r
|
|
513
|
+
`),M();return}if(X==="\x7F"||X==="\b"){f.buffer=f.buffer.slice(0,-1);continue}if(X==="\r"||X===`
|
|
514
|
+
`){let z=f.buffer;if(f.buffer="",f.onPassword){let{result:at,nextPrompt:bt}=await f.onPassword(z,a);t.write(`\r
|
|
515
|
+
`),at!==null?(f=null,at.stdout&&t.write(at.stdout.replace(/\n/g,`\r
|
|
516
|
+
`)),at.stderr&&t.write(at.stderr.replace(/\n/g,`\r
|
|
517
|
+
`)),M()):(bt&&(f.prompt=bt),t.write(f.prompt));return}let ct=a.users.verifyPassword(f.username,z);await R(ct);return}X>=" "&&(f.buffer+=X)}return}let D=A.toString("utf8");for(let T=0;T<D.length;T+=1){let _=D[T];if(_===""){l="",c=0,d=null,m="",t.write(`bye\r
|
|
518
|
+
`),Z("bye"),await a.vfs.flushMirror(),t.write(`logout\r
|
|
519
|
+
`),t.exit(0),t.end();return}if(_===" "){U();continue}if(_==="\x1B"){let X=D[T+1],z=D[T+2],ct=D[T+3];if(X==="["&&z){if(z==="A"){T+=2,u.length>0&&(d===null?(m=l,d=u.length-1):d>0&&(d-=1),C(u[d]??""));continue}if(z==="B"){T+=2,d!==null&&(d<u.length-1?(d+=1,C(u[d]??"")):(d=null,C(m)));continue}if(z==="C"){T+=2,c<l.length&&(c+=1,t.write("\x1B[C"));continue}if(z==="D"){T+=2,c>0&&(c-=1,t.write("\x1B[D"));continue}if(z==="3"&&ct==="~"){T+=3,c<l.length&&(l=`${l.slice(0,c)}${l.slice(c+1)}`,M());continue}}}if(_===""){l="",c=0,d=null,m="",t.write(`^C\r
|
|
520
|
+
`),M();continue}if(_==="\r"||_===`
|
|
521
|
+
`){let X=l.trim();if(l="",c=0,d=null,m="",t.write(`\r
|
|
522
|
+
`),X.length>0){let z=await Promise.resolve(q(X,r,n,"shell",p,a,void 0,S));if(Z(X),z.openEditor){await P(z.openEditor.targetPath,z.openEditor.initialContent,z.openEditor.tempPath);return}if(z.openHtop){await V();return}if(z.sudoChallenge){k(z.sudoChallenge);return}if(z.clearScreen&&t.write("\x1B[2J\x1B[H"),z.stdout&&t.write(`${Ot(z.stdout)}\r
|
|
523
|
+
`),z.stderr&&t.write(`${Ot(z.stderr)}\r
|
|
524
|
+
`),z.closeSession){t.write(`logout\r
|
|
525
|
+
`),t.exit(z.exitCode??0),t.end();return}z.nextCwd&&(p=z.nextCwd),z.switchUser&&(r=z.switchUser,p=z.nextCwd??`/home/${r}`,a.users.updateSession(i,r,s),l="",c=0),await a.vfs.flushMirror()}M();continue}if(_==="\x7F"||_==="\b"){c>0&&(l=`${l.slice(0,c-1)}${l.slice(c)}`,c-=1,M());continue}v(_)}}),t.on("close",()=>{g&&(g.process.kill("SIGTERM"),g=null)})}function Ti(e){let t="/virtual-env-js/.bash_history";return e.exists(t)?e.readFile(t).split(`
|
|
526
|
+
`).map(n=>n.trim()).filter(n=>n.length>0):(e.writeFile(t,""),[])}function Oi(e){return typeof e=="object"&&e!==null&&"vfsInstance"in e&&ys(e.vfsInstance)}function ys(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.restoreMirror=="function"&&typeof t.flushMirror=="function"&&typeof t.writeFile=="function"&&typeof t.readFile=="function"&&typeof t.mkdir=="function"&&typeof t.exists=="function"&&typeof t.stat=="function"&&typeof t.list=="function"&&typeof t.remove=="function"&&typeof t.copy=="function"&&typeof t.move=="function"&&typeof t.touch=="function"}var Ui={kernel:"1.0.0+itsrealfortune+1-amd64",os:"Fortune GNU/Linux x64",arch:"x86_64"},Ut=ae("VirtualShell");function Bi(){let e=process.env.SSH_MIMIC_AUTO_SUDO_NEW_USERS;return e?!["0","false","no","off"].includes(e.toLowerCase()):!0}var de=class extends zi{vfs;users;packageManager;hostname;properties;startTime;initialized;constructor(t,r,n){super(),Ut.mark("constructor"),this.hostname=t,this.properties=r||Ui,this.startTime=Date.now(),ys(n)?this.vfs=n:Oi(n)?this.vfs=n.vfsInstance:this.vfs=new ms(n??{}),this.users=new ue(this.vfs,Bi()),this.packageManager=new ce(this.vfs,this.users);let i=this.vfs,s=this.users,o=this.packageManager,a=this.properties,l=this.hostname,c=this.startTime;this.initialized=(async()=>{await i.restoreMirror(),await s.initialize(),es(i,s,l,a,c),o.load(),this.emit("initialized")})()}async ensureInitialized(){Ut.mark("ensureInitialized"),await this.initialized}addCommand(t,r,n){let i=t.trim().toLowerCase();if(i.length===0||/\s/.test(i))throw new Error("Command name must be non-empty and contain no spaces");be(ve(i,r,n))}executeCommand(t,r,n){Ut.mark("executeCommand"),q(t,r,this.hostname,"shell",n,this),this.emit("command",{command:t,user:r,cwd:n})}startInteractiveSession(t,r,n,i,s){Ut.mark("startInteractiveSession"),this.emit("session:start",{user:r,sessionId:n,remoteAddress:i}),gs(this.properties,t,r,this.hostname,n,i,s,this),this.refreshProcSessions()}refreshProcFs(){oe(this.vfs,this.properties,this.hostname,this.startTime,this.users.listActiveSessions())}refreshProcSessions(){oe(this.vfs,this.properties,this.hostname,this.startTime,this.users.listActiveSessions())}syncPasswd(){Pe(this.vfs,this.users)}getVfs(){return this?.vfs??null}getUsers(){return this?.users??null}getHostname(){return this?.hostname}writeFileAsUser(t,r,n){Ut.mark("writeFileAsUser"),this.users.assertWriteWithinQuota(t,r,n),this.vfs.writeFile(r,n)}};var It=process.env.SSH_MIMIC_HOSTNAME??"typescript-vm",Re=process.argv.slice(2);function Gi(){for(let e=0;e<Re.length;e+=1){let t=Re[e];if(t==="--user"){let r=Re[e+1];if(!r||r.startsWith("--"))throw new Error("self-standalone: --user requires a value");return r}if(t?.startsWith("--user="))return t.slice(7)||"root"}return"root"}var Zi=Gi(),H=new de(It,void 0,{mode:"fs",snapshotPath:".vfs"});function Ji(e){let t=`/virtual-env-js/.lastlog/${e}.json`;if(!H.vfs.exists(t))return null;try{return JSON.parse(H.vfs.readFile(t))}catch{return null}}function Bt(e,t){return new Promise(r=>{if(!it.isTTY||!rt.isTTY){e.question(t,r);return}let n=!!it.isRaw,i="",s=()=>{it.off("data",a),n||it.setRawMode(!1),e.resume()},o=l=>{s(),rt.write(`
|
|
527
|
+
`),r(l)},a=l=>{let c=l.toString("utf8");for(let u=0;u<c.length;u+=1){let d=c[u];if(d==="\r"||d===`
|
|
528
|
+
`){o(i);return}if(d==="\x7F"||d==="\b"){i=i.slice(0,-1);continue}d>=" "&&(i+=d)}};e.pause(),rt.write(t),n||it.setRawMode(!0),it.resume(),it.on("data",a)})}function Yi(e,t){let r="/virtual-env-js/.lastlog";H.vfs.exists(r)||H.vfs.mkdir(r,448),H.vfs.writeFile(`/virtual-env-js/.lastlog/${e}.json`,JSON.stringify({at:new Date().toISOString(),from:t}))}async function Wt(){await H.vfs.flushMirror()}function Qi(){let e="/virtual-env-js/.bash_history";return H.vfs.exists(e)?H.vfs.readFile(e).split(`
|
|
529
|
+
`).map(t=>t.trim()).filter(t=>t.length>0):(H.vfs.writeFile(e,""),[])}function Xi(e){let t=e.length>0?`${e.join(`
|
|
462
530
|
`)}
|
|
463
|
-
`:"";
|
|
464
|
-
`),
|
|
465
|
-
`)
|
|
466
|
-
`),
|
|
467
|
-
`)
|
|
468
|
-
`)
|
|
469
|
-
`)
|
|
470
|
-
`)
|
|
471
|
-
`),
|
|
472
|
-
|
|
473
|
-
`),
|
|
474
|
-
`)
|
|
475
|
-
`),
|
|
476
|
-
`)
|
|
477
|
-
`),
|
|
478
|
-
`)
|
|
479
|
-
`),u.
|
|
480
|
-
`)?u.stderr:`${u.stderr}
|
|
481
|
-
`),u.clearScreen&&Lt.write("\x1B[2J\x1B[H"),u.switchUser?(i=u.switchUser,s=u.nextCwd??`/home/${i}`,n.vars.USER=i,n.vars.LOGNAME=i,n.vars.HOME=`/home/${i}`,n.vars.PWD=s):u.nextCwd&&(s=u.nextCwd,n.vars.PWD=s),u.closeSession&&(r.close(),process.exit(u.exitCode??0)),l(),r.resume()}}qi().catch(r=>{console.error("Failed to start readline SSH emulation:",r),process.exit(1)});process.on("uncaughtException",r=>{console.log("Oh my god, something terrible happened: ",r)});process.on("unhandledRejection",(r,t)=>{console.log(" Oh Lord! We forgot to handle a promise rejection here: ",t),console.log(" The error was: ",r)});
|
|
531
|
+
`:"";H.vfs.writeFile("/virtual-env-js/.bash_history",t)}function to(e,t,r,n){let i=e,s=t;return r.switchUser?(i=r.switchUser,s=r.nextCwd??`/home/${i}`,n.vars.USER=i,n.vars.LOGNAME=i,n.vars.HOME=`/home/${i}`,n.vars.PWD=s):r.nextCwd&&(s=r.nextCwd,n.vars.PWD=s),{authUser:i,cwd:s}}H.addCommand("demo",[],()=>({stdout:"This is a demo command. It does nothing useful.",exitCode:0}));async function eo(){let e=Ki({input:it,output:rt,terminal:!0});await H.ensureInitialized();let t=Qi(),r=e;r.history=[...t].reverse();let n=Zi.trim()||"root";H.users.getPasswordHash(n)!==null||(process.stderr.write(`self-standalone: user '${n}' does not exist
|
|
532
|
+
`),process.exit(1));let s=At(n,It),o=n,a=`/home/${o}`;s.vars.PWD=a;let l="localhost",c={cols:rt.columns??80,rows:rt.rows??24};async function u(f,$,F){H.vfs.exists(f)&&await Hi(F,$,"utf8"),e.pause();let M=ne(F,c,{write:rt.write.bind(rt),exit:()=>{},end:()=>{}}),w=!!it.isRaw,k=R=>{M.stdin.write(R)};it.resume(),w||it.setRawMode(!0),it.on("data",k),await new Promise(R=>{let b=()=>{it.off("data",k),w||it.setRawMode(!1),e.resume()};M.on("error",P=>{b(),rt.write(`nano: ${P.message}\r
|
|
533
|
+
`),R()}),M.on("close",async()=>{b(),e.write("",{ctrl:!0,name:"u"});try{let P=await Wi(F,"utf8");H.writeFileAsUser(o,f,P),await Wt()}catch{}await ji(F).catch(()=>{}),rt.write(`\r
|
|
534
|
+
`),R()})})}async function d(f){if(f.onPassword){let w=f.prompt;for(;;){let k=await Bt(e,w),R=await f.onPassword(k,H);if(R.result===null){w=R.nextPrompt??w;continue}await p(R.result);return}}let $=await Bt(e,f.prompt);if(!H.users.verifyPassword(f.username,$)){process.stderr.write(`Sorry, try again.
|
|
535
|
+
`);return}if(!f.commandLine){o=f.targetUser,a=`/home/${o}`,s.vars.USER=o,s.vars.LOGNAME=o,s.vars.HOME=`/home/${o}`,s.vars.PWD=a;return}let F=f.loginShell?`/home/${f.targetUser}`:a,M=await q(f.commandLine,f.targetUser,It,"shell",F,H,void 0,s);await p(M)}async function m(f){let $=await Bt(e,f.prompt);if(f.confirmPrompt&&await Bt(e,f.confirmPrompt)!==$){process.stderr.write(`passwords do not match
|
|
536
|
+
`);return}switch(f.action){case"passwd":await H.users.setPassword(f.targetUsername,$),rt.write(`passwd: password updated successfully
|
|
537
|
+
`);break;case"adduser":if(!f.newUsername){process.stderr.write(`adduser: missing username
|
|
538
|
+
`);return}await H.users.addUser(f.newUsername,$),rt.write(`adduser: user '${f.newUsername}' created
|
|
539
|
+
`);break;case"deluser":await H.users.deleteUser(f.targetUsername),rt.write(`Removing user '${f.targetUsername}' ...
|
|
540
|
+
deluser: done.
|
|
541
|
+
`);break;case"su":o=f.targetUsername,a=`/home/${o}`,s.vars.USER=o,s.vars.LOGNAME=o,s.vars.HOME=`/home/${o}`,s.vars.PWD=a;break}}async function p(f){if(f.openEditor){await u(f.openEditor.targetPath,f.openEditor.initialContent,f.openEditor.tempPath);return}if(f.sudoChallenge){await d(f.sudoChallenge);return}if(f.passwordChallenge){await m(f.passwordChallenge);return}f.stdout&&rt.write(f.stdout.endsWith(`
|
|
542
|
+
`)?f.stdout:`${f.stdout}
|
|
543
|
+
`),f.stderr&&process.stderr.write(f.stderr.endsWith(`
|
|
544
|
+
`)?f.stderr:`${f.stderr}
|
|
545
|
+
`),f.clearScreen&&(rt.write("\x1B[2J\x1B[H"),console.clear());let $=to(o,a,f,s);o=$.authUser,a=$.cwd,f.closeSession&&(await Wt(),e.close(),process.exit(f.exitCode??0))}if(process.env.USER!=="root"&&H.users.hasPassword(o)){let f=await Bt(e,`Password for ${o}: `);H.users.verifyPassword(o,f)||(process.stderr.write(`self-standalone: authentication failed
|
|
546
|
+
`),process.exit(1))}let S=()=>{let f=a===`/home/${o}`?"~":qi(a)||"/";return ie(o,It,f)},g=()=>{e.setPrompt(S()),e.prompt()};for(e.on("SIGINT",()=>{rt.write(`^C
|
|
547
|
+
`),e.write("",{ctrl:!0,name:"u"}),g()}),e.on("close",()=>{(async()=>(await Wt(),console.log(""),process.exit(0)))()}),rt.write(se(It,H.properties,Ji(o))),Yi(o,l),await Wt(),g();;){let f=await new Promise(F=>{e.once("line",M=>F(M))});e.pause(),f.trim().length>0&&(t.push(f),t.length>500&&(t=t.slice(t.length-500)),Xi(t),r.history=[...t].reverse());let $=await q(f,o,It,"shell",a,H,void 0,s);await p($),await Wt(),g(),e.resume()}}eo().catch(e=>{console.error("Failed to start readline SSH emulation:",e),process.exit(1)});process.on("uncaughtException",e=>{console.log("Oh my god, something terrible happened: ",e)});process.on("unhandledRejection",(e,t)=>{console.log(" Oh Lord! We forgot to handle a promise rejection here: ",t),console.log(" The error was: ",e)});
|
|
482
548
|
//# sourceMappingURL=self-standalone.js.map
|