typescript-virtual-container 1.3.2 → 1.3.4
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/builds/self-standalone.js +21 -20
- package/builds/self-standalone.js.map +3 -3
- package/builds/standalone-wo-sftp.js +103 -112
- package/builds/standalone-wo-sftp.js.map +4 -4
- package/builds/standalone.js +184 -193
- package/builds/standalone.js.map +4 -4
- package/builds/web-full-api.min.js +1 -1
- package/builds/web-full-api.min.js.map +2 -2
- package/builds/web.min.js +2 -2
- package/builds/web.min.js.map +3 -3
- package/dist/VirtualUserManager/index.js +5 -8
- package/examples/web.min.js +2 -2
- package/package.json +5 -5
- package/src/VirtualUserManager/index.ts +9 -9
- /package/polyfills/{node:child_process → node_child_process}/index.js +0 -0
- /package/polyfills/{node:crypto → node_crypto}/index.js +0 -0
- /package/polyfills/{node:events → node_events}/index.js +0 -0
- /package/polyfills/{node:fs → node_fs}/index.js +0 -0
- /package/polyfills/{node:fs → node_fs}/promises.js +0 -0
- /package/polyfills/{node:os → node_os}/index.js +0 -0
- /package/polyfills/{node:path → node_path}/index.js +0 -0
- /package/polyfills/{node:vm → node_vm}/index.js +0 -0
- /package/polyfills/{node:zlib → node_zlib}/index.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/self-standalone.ts", "../src/commands/adduser.ts", "../src/commands/command-helpers.ts", "../src/commands/alias.ts", "../src/commands/helpers.ts", "../src/commands/apt.ts", "../src/commands/awk.ts", "../src/commands/base64.ts", "../src/commands/cat.ts", "../src/commands/cd.ts", "../src/commands/chmod.ts", "../src/commands/clear.ts", "../src/commands/cp.ts", "../src/commands/curl.ts", "../src/commands/cut.ts", "../src/commands/date.ts", "../src/commands/declare.ts", "../src/commands/deluser.ts", "../src/commands/df.ts", "../src/commands/diff.ts", "../src/commands/dpkg.ts", "../src/commands/du.ts", "../src/utils/expand.ts", "../src/commands/echo.ts", "../src/commands/env.ts", "../src/commands/exit.ts", "../src/commands/export.ts", "../src/commands/find.ts", "../src/commands/free.ts", "../src/commands/grep.ts", "../src/commands/groups.ts", "../src/commands/gzip.ts", "../src/commands/head.ts", "../src/commands/help.ts", "../src/commands/history.ts", "../src/commands/hostname.ts", "../src/commands/htop.ts", "../src/commands/id.ts", "../src/commands/kill.ts", "../src/commands/ln.ts", "../src/commands/ls.ts", "../src/commands/lsb-release.ts", "../src/commands/man.ts", "../src/commands/mkdir.ts", "../src/commands/mv.ts", "../src/commands/nano.ts", "../src/modules/neofetch.ts", "../src/commands/set.ts", "../src/commands/neofetch.ts", "../src/commands/node.ts", "../src/commands/npm.ts", "../src/commands/passwd.ts", "../src/commands/ping.ts", "../src/commands/printf.ts", "../src/commands/ps.ts", "../src/commands/pwd.ts", "../src/commands/python.ts", "../src/commands/read.ts", "../src/commands/rm.ts", "../src/commands/sed.ts", "../src/commands/sh.ts", "../src/commands/shift.ts", "../src/commands/sleep.ts", "../src/commands/sort.ts", "../src/commands/source.ts", "../src/commands/su.ts", "../src/commands/sudo.ts", "../src/commands/tail.ts", "../src/commands/tar.ts", "../src/commands/tee.ts", "../src/commands/test.ts", "../src/commands/touch.ts", "../src/commands/tr.ts", "../src/commands/tree.ts", "../src/commands/true.ts", "../src/commands/type.ts", "../src/commands/uname.ts", "../src/commands/uniq.ts", "../src/commands/unset.ts", "../src/commands/uptime.ts", "../src/commands/wc.ts", "../src/commands/wget.ts", "../src/commands/which.ts", "../src/SSHMimic/loginFormat.ts", "../src/commands/who.ts", "../src/commands/whoami.ts", "../src/commands/xargs.ts", "../src/commands/registry.ts", "../src/SSHMimic/executor.ts", "../src/VirtualShell/shellParser.ts", "../src/commands/runtime.ts", "../src/SSHMimic/loginBanner.ts", "../src/SSHMimic/prompt.ts", "../src/VirtualShell/index.ts", "../src/modules/linuxRootfs.ts", "../src/utils/perfLogger.ts", "../src/VirtualFileSystem/index.ts", "../src/VirtualFileSystem/binaryPack.ts", "../src/VirtualFileSystem/path.ts", "../src/VirtualPackageManager/index.ts", "../src/VirtualUserManager/index.ts", "../src/VirtualShell/shell.ts", "../src/modules/shellInteractive.ts", "../src/modules/shellRuntime.ts"],
|
|
4
|
-
"sourcesContent": ["import { basename } from \"node:path\";\nimport { stdin, stdout } from \"node:process\";\nimport { createInterface, type Interface } from \"node:readline\";\n\nimport { makeDefaultEnv, runCommand } from \"./commands/runtime\";\nimport { buildLoginBanner, type LoginBannerState } from \"./SSHMimic/loginBanner\";\nimport { buildPrompt } from \"./SSHMimic/prompt\";\nimport { VirtualShell } from \"./VirtualShell\";\n\nconst hostname = process.env.SSH_MIMIC_HOSTNAME ?? \"typescript-vm\";\nconst argv = process.argv.slice(2);\n\nfunction readUserArg(): string {\n\tfor (let index = 0; index < argv.length; index += 1) {\n\t\tconst current = argv[index];\n\t\tif (current === \"--user\") {\n\t\t\tconst next = argv[index + 1];\n\t\t\tif (!next || next.startsWith(\"--\")) {\n\t\t\t\tthrow new Error(\"self-standalone: --user requires a value\");\n\t\t\t}\n\t\t\treturn next;\n\t\t}\n\t\tif (current?.startsWith(\"--user=\")) {\n\t\t\treturn current.slice(\"--user=\".length) || \"root\";\n\t\t}\n\t}\n\n\treturn \"root\";\n}\n\nconst initialUser = readUserArg();\nconst virtualShell = new VirtualShell(hostname, undefined, {\n\tmode: \"fs\",\n\tsnapshotPath: \".vfs\",\n});\n\nfunction readLastLogin(username: string): LoginBannerState | null {\n\tconst lastlogPath = `/virtual-env-js/.lastlog/${username}.json`;\n\tif (!virtualShell.vfs.exists(lastlogPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\treturn JSON.parse(virtualShell.vfs.readFile(lastlogPath)) as LoginBannerState;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction askQuestion(rl: Interface, promptText: string): Promise<string> {\n\treturn new Promise((resolve) => {\n\t\trl.question(promptText, resolve);\n\t});\n}\n\nfunction writeLastLogin(username: string, from: string): void {\n\tconst dir = \"/virtual-env-js/.lastlog\";\n\tif (!virtualShell.vfs.exists(dir)) {\n\t\tvirtualShell.vfs.mkdir(dir, 0o700);\n\t}\n\n\tvirtualShell.vfs.writeFile(\n\t\t`/virtual-env-js/.lastlog/${username}.json`,\n\t\tJSON.stringify({ at: new Date().toISOString(), from }),\n\t);\n}\n\nvirtualShell.addCommand(\"demo\", [], () => {\n\treturn {\n\t\tstdout: \"This is a demo command. It does nothing useful.\",\n\t\texitCode: 0,\n\t};\n});\n\nasync function runReadlineShell() {\n\tconst rl = createInterface({ input: stdin, output: stdout, terminal: true });\n\tawait virtualShell.ensureInitialized();\n\n\tconst selectedUser = initialUser.trim() || \"root\";\n\tconst userExists = virtualShell.users.getPasswordHash(selectedUser) !== null;\n\tif (!userExists) {\n\t\tprocess.stderr.write(`self-standalone: user '${selectedUser}' does not exist\\n`);\n\t\tprocess.exit(1);\n\t}\n\n\tconst shellEnv = makeDefaultEnv(selectedUser, hostname);\n\tlet authUser = selectedUser;\n\tlet cwd = `/home/${authUser}`;\n\tshellEnv.vars.PWD = cwd;\n\tconst remoteAddress = \"localhost\";\n\n\tif (process.env.USER !== \"root\" && virtualShell.users.hasPassword(authUser)) {\n\t\tconst password = await askQuestion(rl, `Password for ${authUser}: `);\n\t\tif (!virtualShell.users.verifyPassword(authUser, password)) {\n\t\t\tprocess.stderr.write(\"self-standalone: authentication failed\\n\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tconst renderPrompt = (): string => {\n\t\tconst cwdLabel = cwd === `/home/${authUser}` ? \"~\" : basename(cwd) || \"/\";\n\t\treturn buildPrompt(authUser, hostname, cwdLabel);\n\t};\n\n\tconst prompt = (): void => {\n\t\trl.setPrompt(renderPrompt());\n\t\trl.prompt();\n\t};\n\n\trl.on(\"SIGINT\", () => {\n\t\tstdout.write(\"^C\\n\");\n\t\trl.write(\"\", { ctrl: true, name: \"u\" });\n\t\tprompt();\n\t});\n\n\trl.on(\"close\", () => {\n\t\tconsole.log(\"\")\n\t\tprocess.exit(0);\n\t});\n\n\tstdout.write(buildLoginBanner(hostname, virtualShell.properties, readLastLogin(authUser)));\n\twriteLastLogin(authUser, remoteAddress);\n\tprompt();\n\n\twhile (true) {\n\t\tconst inputLine = await new Promise<string>((resolve) => {\n\t\t\trl.once(\"line\", (line) => resolve(line));\n\t\t});\n\n\t\trl.pause();\n\n\t\tconst result = await runCommand(inputLine, authUser, hostname, \"shell\", cwd, virtualShell, undefined, shellEnv);\n\n\t\tif (result.stdout) {\n\t\t\tstdout.write(result.stdout.endsWith(\"\\n\") ? result.stdout : `${result.stdout}\\n`);\n\t\t}\n\n\t\tif (result.stderr) {\n\t\t\tprocess.stderr.write(result.stderr.endsWith(\"\\n\") ? result.stderr : `${result.stderr}\\n`);\n\t\t}\n\n\t\tif (result.clearScreen) {\n\t\t\tstdout.write(\"\\u001b[2J\\u001b[H\");\n\t\t}\n\n\t\tif (result.switchUser) {\n\t\t\tauthUser = result.switchUser;\n\t\t\tcwd = result.nextCwd ?? `/home/${authUser}`;\n\t\t\tshellEnv.vars.USER = authUser;\n\t\t\tshellEnv.vars.LOGNAME = authUser;\n\t\t\tshellEnv.vars.HOME = `/home/${authUser}`;\n\t\t\tshellEnv.vars.PWD = cwd;\n\t\t} else if (result.nextCwd) {\n\t\t\tcwd = result.nextCwd;\n\t\t\tshellEnv.vars.PWD = cwd;\n\t\t}\n\n\t\tif (result.closeSession) {\n\t\t\trl.close();\n\t\t\tprocess.exit(result.exitCode ?? 0);\n\t\t}\n\n\t\tprompt();\n\t\trl.resume();\n\t}\n}\n\nrunReadlineShell().catch((error: unknown) => {\n\tconsole.error(\"Failed to start readline SSH emulation:\", error);\n\tprocess.exit(1);\n});\n\nprocess.on(\"uncaughtException\", (error) => {\n\tconsole.log(\"Oh my god, something terrible happened: \", error);\n});\n\nprocess.on(\"unhandledRejection\", (error, promise) => {\n\tconsole.log(\n\t\t\" Oh Lord! We forgot to handle a promise rejection here: \",\n\t\tpromise,\n\t);\n\tconsole.log(\" The error was: \", error);\n});\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Add a new user to the virtual user database.\n * @category users\n * @params [\"<username> <password>\"]\n * @returns ShellModule\n */\nexport const adduserCommand: ShellModule = {\n\tname: \"adduser\",\n\tdescription: \"Add a new user\",\n\tcategory: \"users\",\n\tparams: [\"<username> <password>\"],\n\trun: async ({ authUser, shell, args }) => {\n\t\tif (authUser !== \"root\") {\n\t\t\treturn { stderr: \"adduser: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tconst [username, password] = args;\n\t\tif (!username || !password) {\n\t\t\treturn {\n\t\t\t\tstderr: \"adduser: usage: adduser <username> <password>\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\n\t\tawait shell.users.addUser(username, password);\n\t\treturn { stdout: `adduser: user '${username}' created`, exitCode: 0 };\n\t},\n};\n", "type ArgParseOptions = {\n\tflags?: string[];\n\tflagsWithValue?: string[];\n};\n\nfunction toFlagList(flags: string | string[]): string[] {\n\treturn Array.isArray(flags) ? flags : [flags];\n}\n\nfunction matchFlagToken(\n\ttoken: string,\n\tflag: string,\n): { matched: boolean; inlineValue: string | null } {\n\tif (token === flag) {\n\t\treturn { matched: true, inlineValue: null };\n\t}\n\n\tconst prefix = `${flag}=`;\n\tif (token.startsWith(prefix)) {\n\t\treturn { matched: true, inlineValue: token.slice(prefix.length) };\n\t}\n\n\treturn { matched: false, inlineValue: null };\n}\n\nfunction collectPositionals(\n\targs: string[],\n\toptions: ArgParseOptions = {},\n): string[] {\n\tconst boolFlags = new Set(options.flags ?? []);\n\tconst valueFlags = new Set(options.flagsWithValue ?? []);\n\tconst positionals: string[] = [];\n\tlet passthrough = false;\n\n\tfor (let index = 0; index < args.length; index += 1) {\n\t\tconst arg = args[index]!;\n\n\t\tif (passthrough) {\n\t\t\tpositionals.push(arg);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--\") {\n\t\t\tpassthrough = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet consumed = false;\n\n\t\tfor (const flag of boolFlags) {\n\t\t\tconst { matched } = matchFlagToken(arg, flag);\n\t\t\tif (matched) {\n\t\t\t\tconsumed = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (consumed) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const flag of valueFlags) {\n\t\t\tconst match = matchFlagToken(arg, flag);\n\t\t\tif (!match.matched) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconsumed = true;\n\t\t\tif (match.inlineValue === null && index + 1 < args.length) {\n\t\t\t\tindex += 1;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!consumed) {\n\t\t\tpositionals.push(arg);\n\t\t}\n\t}\n\n\treturn positionals;\n}\n\n/**\n * Returns `true` when any of the given flags appear in `args`.\n *\n * Matches both standalone tokens (`-s`, `--silent`) and inline forms\n * (`--output=file`). Useful for simple boolean flag checks inside command\n * `run` handlers.\n *\n * @param args Tokenized argument array from `CommandContext.args`.\n * @param flags Single flag string or array of equivalent flag strings.\n * @returns `true` if at least one flag is present, otherwise `false`.\n *\n * @example\n * ```ts\n * ifFlag(args, \"-r\") // single flag\n * ifFlag(args, [\"-r\", \"--recursive\"]) // aliases\n * ```\n */\nexport function ifFlag(args: string[], flags: string | string[]): boolean {\n\tconst allFlags = toFlagList(flags);\n\n\tfor (const arg of args) {\n\t\tfor (const flag of allFlags) {\n\t\t\tif (matchFlagToken(arg, flag).matched) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Returns the value associated with a flag, or `true` if the flag is present\n * but has no associated value, or `undefined` if the flag is absent.\n *\n * Handles three forms:\n * - `--output file` \u2192 returns `\"file\"` (next token)\n * - `--output=file` \u2192 returns `\"file\"` (inline `=` form)\n * - `--verbose` \u2192 returns `true` (flag with no value)\n *\n * @param args Tokenized argument array from `CommandContext.args`.\n * @param flags Single flag string or array of equivalent flag strings.\n * @returns The flag value string, `true` when valueless, or `undefined`.\n *\n * @example\n * ```ts\n * const output = getFlag(args, [\"-o\", \"--output\"]);\n * if (typeof output === \"string\") { /* use path *\\/ }\n * ```\n */\nexport function getFlag(\n\targs: string[],\n\tflags: string | string[],\n): string | true | undefined {\n\tconst allFlags = toFlagList(flags);\n\n\tfor (let index = 0; index < args.length; index += 1) {\n\t\tconst arg = args[index]!;\n\n\t\tfor (const flag of allFlags) {\n\t\t\tconst match = matchFlagToken(arg, flag);\n\t\t\tif (!match.matched) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (match.inlineValue !== null) {\n\t\t\t\treturn match.inlineValue;\n\t\t\t}\n\n\t\t\tconst next = args[index + 1];\n\t\t\tif (next !== undefined && next !== \"--\") {\n\t\t\t\treturn next;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Returns the positional argument at the given zero-based index, skipping\n * known flags and their values.\n *\n * Flags declared in `options.flags` are treated as boolean and skipped.\n * Flags declared in `options.flagsWithValue` consume the next token too.\n * Tokens after `--` are always treated as positionals.\n *\n * @param args Tokenized argument array from `CommandContext.args`.\n * @param index Zero-based positional index to retrieve.\n * @param options Optional flag declarations to skip during positional collection.\n * @returns The positional value, or `undefined` if the index is out of range.\n *\n * @example\n * ```ts\n * // args = [\"-r\", \"src\", \"dest\"]\n * getArg(args, 0, { flags: [\"-r\"] }) // \"src\"\n * getArg(args, 1, { flags: [\"-r\"] }) // \"dest\"\n * ```\n */\nexport function getArg(\n\targs: string[],\n\tindex: number,\n\toptions: ArgParseOptions = {},\n): string | undefined {\n\tconst positionals = collectPositionals(args, options);\n\treturn positionals[index];\n}\n\n/**\n * Parses an argument array into structured flags, flag values, and positionals.\n *\n * - `options.flags` \u2014 boolean flags (e.g. `[\"-r\", \"--recursive\"]`); collected\n * into a `Set<string>` and not treated as positionals.\n * - `options.flagsWithValue` \u2014 flags that consume the next token or an inline\n * `=value`; collected into a `Map<string, string>`.\n * - All remaining tokens are positionals.\n * - Tokens after `--` are always positionals, regardless of `-` prefix.\n *\n * @param args Tokenized argument array from `CommandContext.args`.\n * @param options Flag declaration lists.\n * @returns `{ flags, flagsWithValues, positionals }`.\n *\n * @example\n * ```ts\n * const { flags, flagsWithValues, positionals } = parseArgs(args, {\n * flags: [\"-r\", \"--recursive\"],\n * flagsWithValue: [\"-o\", \"--output\"],\n * });\n * const recursive = flags.has(\"-r\");\n * const output = flagsWithValues.get(\"-o\");\n * ```\n */\nexport function parseArgs(\n\targs: string[],\n\toptions: { flags?: string[]; flagsWithValue?: string[] } = {},\n): {\n\tflags: Set<string>;\n\tflagsWithValues: Map<string, string>;\n\tpositionals: string[];\n} {\n\tconst flags = new Set<string>();\n\tconst flagsWithValues = new Map<string, string>();\n\tconst positionals: string[] = [];\n\tconst boolFlags = new Set(options.flags ?? []);\n\tconst valueFlags = new Set(options.flagsWithValue ?? []);\n\tlet passthrough = false;\n\n\tfor (let index = 0; index < args.length; index += 1) {\n\t\tconst arg = args[index]!;\n\n\t\tif (passthrough) {\n\t\t\tpositionals.push(arg);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--\") {\n\t\t\tpassthrough = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (boolFlags.has(arg)) {\n\t\t\tflags.add(arg);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (valueFlags.has(arg)) {\n\t\t\tconst next = args[index + 1];\n\t\t\tif (next && !next.startsWith(\"-\")) {\n\t\t\t\tflagsWithValues.set(arg, next);\n\t\t\t\tindex += 1;\n\t\t\t} else {\n\t\t\t\tflagsWithValues.set(arg, \"\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst inlineFlag = Array.from(valueFlags).find((flag) =>\n\t\t\targ.startsWith(`${flag}=`),\n\t\t);\n\t\tif (inlineFlag) {\n\t\t\tflagsWithValues.set(inlineFlag, arg.slice(inlineFlag.length + 1));\n\t\t\tcontinue;\n\t\t}\n\n\t\tpositionals.push(arg);\n\t}\n\n\treturn { flags, flagsWithValues, positionals };\n}\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n/**\n * Manage shell aliases (list / set / remove).\n * @category shell\n * @params [\"[name[=value] ...]\"]\n */\nexport const aliasCommand: ShellModule = {\n\tname: \"alias\",\n\tdescription: \"Define or display aliases\",\n\tcategory: \"shell\",\n\tparams: [\"[name[=value] ...]\"],\n\trun: ({ args, env }) => {\n\t\tif (!env) return { exitCode: 0 };\n\n\t\t// Aliases stored in env.vars under prefix __alias_\n\t\tif (args.length === 0) {\n\t\t\tconst aliases = Object.entries(env.vars)\n\t\t\t\t.filter(([k]) => k.startsWith(\"__alias_\"))\n\t\t\t\t.map(([k, v]) => `alias ${k.slice(\"__alias_\".length)}='${v}'`);\n\t\t\treturn { stdout: aliases.join(\"\\n\") || \"\", exitCode: 0 };\n\t\t}\n\n\t\tconst lines: string[] = [];\n\t\tfor (const arg of args) {\n\t\t\tconst eq = arg.indexOf(\"=\");\n\t\t\tif (eq === -1) {\n\t\t\t\t// Display single alias\n\t\t\t\tconst val = env.vars[`__alias_${arg}`];\n\t\t\t\tif (val) lines.push(`alias ${arg}='${val}'`);\n\t\t\t\telse return { stderr: `alias: ${arg}: not found`, exitCode: 1 };\n\t\t\t} else {\n\t\t\t\t// Set alias\n\t\t\t\tconst name = arg.slice(0, eq);\n\t\t\t\tconst val = arg.slice(eq + 1).replace(/^['\"]|['\"]$/g, \"\");\n\t\t\t\tenv.vars[`__alias_${name}`] = val;\n\t\t\t}\n\t\t}\n\n\t\treturn { stdout: lines.join(\"\\n\") || undefined, exitCode: 0 };\n\t},\n};\n\nexport const unaliasCommand: ShellModule = {\n\tname: \"unalias\",\n\tdescription: \"Remove alias definitions\",\n\tcategory: \"shell\",\n\tparams: [\"<name...> | -a\"],\n\trun: ({ args, env }) => {\n\t\tif (!env) return { exitCode: 0 };\n\n\t\tif (ifFlag(args, [\"-a\"])) {\n\t\t\tfor (const k of Object.keys(env.vars)) {\n\t\t\t\tif (k.startsWith(\"__alias_\")) delete env.vars[k];\n\t\t\t}\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\tfor (const name of args) {\n\t\t\tdelete env.vars[`__alias_${name}`];\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import { spawn } from \"node:child_process\";\nimport * as path from \"node:path\";\nimport type VirtualFileSystem from \"../VirtualFileSystem\";\nimport type { VirtualPackageManager } from \"../VirtualPackageManager\";\nimport type { VirtualShell } from \"../VirtualShell\";\n\nconst PROTECTED_PREFIXES = [\"/virtual-env-js/.auth\"] as const;\n\nfunction normalizeFetchUrl(input: string): string {\n\tif (/^[a-zA-Z][a-zA-Z\\d+\\-.]*:/.test(input)) {\n\t\treturn input;\n\t}\n\n\treturn `http://${input}`;\n}\n\nexport function normalizeTerminalOutput(text: string): string {\n\treturn text\n\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t.replace(/\\r/g, \"\\n\")\n\t\t.replace(/\\t/g, \" \")\n\t\t.split(\"\\n\")\n\t\t.map((line) =>\n\t\t\tline.replace(/^[ \\u00A0]{8,}/, \" \").replace(/[ \\u00A0]{3,}/g, \" \"),\n\t\t)\n\t\t.join(\"\\n\")\n\t\t.replace(/\\n{3,}/g, \"\\n\\n\")\n\t\t.trimEnd();\n}\n\nexport function resolvePath(cwd: string, inputPath: string): string {\n\tif (!inputPath || inputPath.trim() === \"\") {\n\t\treturn cwd;\n\t}\n\treturn inputPath.startsWith(\"/\")\n\t\t? path.posix.normalize(inputPath)\n\t\t: path.posix.normalize(path.posix.join(cwd, inputPath));\n}\n\nfunction isProtectedPath(targetPath: string): boolean {\n\tconst normalized = targetPath.startsWith(\"/\")\n\t\t? path.posix.normalize(targetPath)\n\t\t: path.posix.normalize(`/${targetPath}`);\n\n\treturn PROTECTED_PREFIXES.some(\n\t\t(prefix) => normalized === prefix || normalized.startsWith(`${prefix}/`),\n\t);\n}\n\nexport function assertPathAccess(\n\tauthUser: string,\n\ttargetPath: string,\n\toperation: string,\n): void {\n\tif (authUser === \"root\") {\n\t\treturn;\n\t}\n\n\tif (isProtectedPath(targetPath)) {\n\t\tthrow new Error(`${operation}: permission denied: ${targetPath}`);\n\t}\n}\n\nexport function stripUrlFilename(url: string): string {\n\tconst cleaned = url.split(\"?\")[0]?.split(\"#\")[0] ?? url;\n\tconst lastPart = cleaned.split(\"/\").filter(Boolean).pop();\n\treturn lastPart && lastPart.length > 0 ? lastPart : \"index.html\";\n}\n\nexport async function fetchResource(\n\turl: string,\n): Promise<{ text: string; status: number; contentType: string | null }> {\n\tconst response = await fetch(normalizeFetchUrl(url));\n\tconst contentType = response.headers.get(\"content-type\");\n\treturn {\n\t\ttext: await response.text(),\n\t\tstatus: response.status,\n\t\tcontentType,\n\t};\n}\n\n/**\n * Run a host command like curl or wget and capture its output.\n * @param binary - The binary to execute (e.g., \"curl\", \"wget\").\n * @param args - Arguments to pass to the binary.\n * @returns Promise resolving with stdout, stderr, and exit code.\n */\nexport function runHostCommand(\n\tbinary: string,\n\targs: string[],\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n\treturn new Promise((resolve) => {\n\t\tlet childProcess: ReturnType<typeof spawn>;\n\n\t\ttry {\n\t\t\tchildProcess = spawn(binary, args, {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tresolve({\n\t\t\t\tstdout: \"\",\n\t\t\t\tstderr: `${binary}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\texitCode: 1,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tlet stdout = \"\";\n\t\tlet stderr = \"\";\n\t\tconst stdoutStream = childProcess.stdout;\n\t\tconst stderrStream = childProcess.stderr;\n\n\t\tif (!stdoutStream || !stderrStream) {\n\t\t\tresolve({\n\t\t\t\tstdout: \"\",\n\t\t\t\tstderr: `${binary}: failed to capture process output`,\n\t\t\t\texitCode: 1,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tstdoutStream.setEncoding(\"utf8\");\n\t\tstderrStream.setEncoding(\"utf8\");\n\n\t\tstdoutStream.on(\"data\", (chunk: string) => {\n\t\t\tstdout += chunk;\n\t\t});\n\n\t\tstderrStream.on(\"data\", (chunk: string) => {\n\t\t\tstderr += chunk;\n\t\t});\n\n\t\tchildProcess.on(\"error\", (error) => {\n\t\t\tconst errorCode =\n\t\t\t\terror instanceof Error && \"code\" in error\n\t\t\t\t\t? String((error as NodeJS.ErrnoException).code ?? \"\")\n\t\t\t\t\t: \"\";\n\t\t\tresolve({\n\t\t\t\tstdout: \"\",\n\t\t\t\tstderr: `${binary}: ${error.message}`,\n\t\t\t\texitCode: errorCode === \"ENOENT\" ? 127 : 1,\n\t\t\t});\n\t\t});\n\n\t\tchildProcess.on(\"close\", (code) => {\n\t\t\tresolve({\n\t\t\t\tstdout,\n\t\t\t\tstderr,\n\t\t\t\texitCode: code ?? 1,\n\t\t\t});\n\t\t});\n\t});\n}\n\nfunction levenshtein(a: string, b: string): number {\n\tconst dp: number[][] = Array.from({ length: a.length + 1 }, () =>\n\t\tArray<number>(b.length + 1).fill(0),\n\t);\n\n\tfor (let i = 0; i <= a.length; i += 1) {\n\t\tdp[i]![0] = i;\n\t}\n\tfor (let j = 0; j <= b.length; j += 1) {\n\t\tdp[0]![j] = j;\n\t}\n\n\tfor (let i = 1; i <= a.length; i += 1) {\n\t\tfor (let j = 1; j <= b.length; j += 1) {\n\t\t\tconst cost = a[i - 1] === b[j - 1] ? 0 : 1;\n\t\t\tdp[i]![j] = Math.min(\n\t\t\t\tdp[i - 1]![j]! + 1,\n\t\t\t\tdp[i]![j - 1]! + 1,\n\t\t\t\tdp[i - 1]![j - 1]! + cost,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn dp[a.length]![b.length]!;\n}\n\nexport function resolveReadablePath(\n\tvfs: VirtualFileSystem,\n\tcwd: string,\n\tinputPath: string,\n): string {\n\tconst exactPath = resolvePath(cwd, inputPath);\n\tif (vfs.exists(exactPath)) {\n\t\treturn exactPath;\n\t}\n\n\tconst parent = path.posix.dirname(exactPath);\n\tconst fileName = path.posix.basename(exactPath);\n\tconst siblings = vfs.list(parent);\n\n\tconst caseInsensitive = siblings.filter(\n\t\t(name) => name.toLowerCase() === fileName.toLowerCase(),\n\t);\n\tif (caseInsensitive.length === 1) {\n\t\treturn path.posix.join(parent, caseInsensitive[0]!);\n\t}\n\n\tconst near = siblings.filter(\n\t\t(name) => levenshtein(name.toLowerCase(), fileName.toLowerCase()) <= 1,\n\t);\n\tif (near.length === 1) {\n\t\treturn path.posix.join(parent, near[0]!);\n\t}\n\n\treturn exactPath;\n}\n\nexport function joinListWithType(\n\tcwd: string,\n\titems: string[],\n\tstatAt: (p: string) => { type: \"file\" | \"directory\" },\n): string {\n\treturn items\n\t\t.map((name) => {\n\t\t\tconst childPath = resolvePath(cwd, name);\n\t\t\tconst stats = statAt(childPath);\n\t\t\treturn stats.type === \"directory\" ? `${name}/` : name;\n\t\t})\n\t\t.join(\" \");\n}\n\nexport function getPackageManager(\n\tshell: VirtualShell,\n): VirtualPackageManager | undefined {\n\treturn shell.packageManager;\n}\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { getPackageManager } from \"./helpers\";\n\n/**\n * APT package manager front-end (simulated).\n * @category package\n * @params [\"<install|remove|update|upgrade|search|show|list> [pkg...]\"]\n */\nexport const aptCommand: ShellModule = {\n\tname: \"apt\",\n\taliases: [\"apt-get\"],\n\tdescription: \"Package manager\",\n\tcategory: \"package\",\n\tparams: [\"<install|remove|update|upgrade|search|show|list> [pkg...]\"],\n\trun: ({ args, shell, authUser }) => {\n\t\tconst pm = getPackageManager(shell);\n\t\tif (!pm)\n\t\t\treturn { stderr: \"apt: package manager not initialised\", exitCode: 1 };\n\n\t\tconst sub = args[0]?.toLowerCase();\n\t\tconst rest = args.slice(1);\n\n\t\tconst quiet = ifFlag(rest, [\"-q\", \"--quiet\", \"-qq\"]);\n\t\tconst purge = ifFlag(rest, [\"--purge\"]);\n\t\tconst pkgs = rest.filter((a) => !a.startsWith(\"-\"));\n\n\t\t// Non-root check\n\t\tconst restricted = [\"install\", \"remove\", \"purge\", \"upgrade\", \"update\"];\n\t\tif (restricted.includes(sub ?? \"\") && authUser !== \"root\") {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)\\nE: Unable to acquire the dpkg frontend lock, are you root?\",\n\t\t\t\texitCode: 100,\n\t\t\t};\n\t\t}\n\n\t\tswitch (sub) {\n\t\t\tcase \"install\": {\n\t\t\t\tif (pkgs.length === 0)\n\t\t\t\t\treturn { stderr: \"apt: no packages specified\", exitCode: 1 };\n\t\t\t\tconst { output, exitCode } = pm.install(pkgs, { quiet });\n\t\t\t\treturn { stdout: output || undefined, exitCode };\n\t\t\t}\n\n\t\t\tcase \"remove\":\n\t\t\tcase \"purge\": {\n\t\t\t\tif (pkgs.length === 0)\n\t\t\t\t\treturn { stderr: \"apt: no packages specified\", exitCode: 1 };\n\t\t\t\tconst { output, exitCode } = pm.remove(pkgs, {\n\t\t\t\t\tpurge: sub === \"purge\" || purge,\n\t\t\t\t\tquiet,\n\t\t\t\t});\n\t\t\t\treturn { stdout: output || undefined, exitCode };\n\t\t\t}\n\n\t\t\tcase \"update\": {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t\"Hit:1 fortune://packages.fortune.local aurora InRelease\",\n\t\t\t\t\t\t\"Hit:2 fortune://security.fortune.local aurora-security InRelease\",\n\t\t\t\t\t\t\"Reading package lists... Done\",\n\t\t\t\t\t\t\"Building dependency tree... Done\",\n\t\t\t\t\t\t\"Reading state information... Done\",\n\t\t\t\t\t\t`All packages are up to date.`,\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"upgrade\": {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t\"Reading package lists... Done\",\n\t\t\t\t\t\t\"Building dependency tree... Done\",\n\t\t\t\t\t\t\"Reading state information... Done\",\n\t\t\t\t\t\t\"Calculating upgrade... Done\",\n\t\t\t\t\t\t\"0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.\",\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"search\": {\n\t\t\t\tconst term = pkgs[0];\n\t\t\t\tif (!term)\n\t\t\t\t\treturn { stderr: \"apt: search requires a term\", exitCode: 1 };\n\t\t\t\tconst results = pm.search(term);\n\t\t\t\tif (results.length === 0)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstdout: `Sorting... Done\\nFull Text Search... Done\\n(no results)`,\n\t\t\t\t\t\texitCode: 0,\n\t\t\t\t\t};\n\t\t\t\tconst lines = results.map(\n\t\t\t\t\t(p) =>\n\t\t\t\t\t\t`${p.name}/${p.section ?? \"misc\"} ${p.version} amd64\\n ${p.shortDesc ?? p.description}`,\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\tstdout: `Sorting... Done\\nFull Text Search... Done\\n${lines.join(\"\\n\")}`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"show\": {\n\t\t\t\tconst name = pkgs[0];\n\t\t\t\tif (!name)\n\t\t\t\t\treturn { stderr: \"apt: show requires a package name\", exitCode: 1 };\n\t\t\t\tconst info = pm.show(name);\n\t\t\t\tif (!info)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `N: Unable to locate package ${name}`,\n\t\t\t\t\t\texitCode: 100,\n\t\t\t\t\t};\n\t\t\t\treturn { stdout: info, exitCode: 0 };\n\t\t\t}\n\n\t\t\tcase \"list\": {\n\t\t\t\tconst installedFlag = ifFlag(rest, [\"--installed\"]);\n\t\t\t\tif (installedFlag) {\n\t\t\t\t\tconst pkgList = pm.listInstalled();\n\t\t\t\t\tif (pkgList.length === 0)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tstdout: \"Listing... Done\\n(no packages installed)\",\n\t\t\t\t\t\t\texitCode: 0,\n\t\t\t\t\t\t};\n\t\t\t\t\tconst lines = pkgList.map(\n\t\t\t\t\t\t(p) =>\n\t\t\t\t\t\t\t`${p.name}/${p.section} ${p.version} ${p.architecture} [installed]`,\n\t\t\t\t\t);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstdout: `Listing... Done\\n${lines.join(\"\\n\")}`,\n\t\t\t\t\t\texitCode: 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// all available\n\t\t\t\tconst all = pm.listAvailable();\n\t\t\t\tconst lines = all.map(\n\t\t\t\t\t(p) => `${p.name}/${p.section ?? \"misc\"} ${p.version} amd64`,\n\t\t\t\t);\n\t\t\t\treturn { stdout: `Listing... Done\\n${lines.join(\"\\n\")}`, exitCode: 0 };\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t\"Usage: apt [options] command\",\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\"Commands:\",\n\t\t\t\t\t\t\" install <pkg...> Install packages\",\n\t\t\t\t\t\t\" remove <pkg...> Remove packages\",\n\t\t\t\t\t\t\" purge <pkg...> Remove packages and config files\",\n\t\t\t\t\t\t\" update Refresh package index\",\n\t\t\t\t\t\t\" upgrade Upgrade all packages\",\n\t\t\t\t\t\t\" search <term> Search in package descriptions\",\n\t\t\t\t\t\t\" show <pkg> Show package details\",\n\t\t\t\t\t\t\" list [--installed] List packages\",\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t},\n};\n\nexport const aptCacheCommand: ShellModule = {\n\tname: \"apt-cache\",\n\tdescription: \"Query the package cache\",\n\tcategory: \"package\",\n\tparams: [\"<search|show|policy> [pkg]\"],\n\trun: ({ args, shell }) => {\n\t\tconst pm = getPackageManager(shell);\n\t\tif (!pm)\n\t\t\treturn {\n\t\t\t\tstderr: \"apt-cache: package manager not initialised\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\n\t\tconst sub = args[0]?.toLowerCase();\n\t\tconst pkgName = args[1];\n\n\t\tswitch (sub) {\n\t\t\tcase \"search\": {\n\t\t\t\tif (!pkgName) return { stderr: \"Need a search term\", exitCode: 1 };\n\t\t\t\tconst results = pm.search(pkgName);\n\t\t\t\treturn {\n\t\t\t\t\tstdout:\n\t\t\t\t\t\tresults\n\t\t\t\t\t\t\t.map((p) => `${p.name} - ${p.shortDesc ?? p.description}`)\n\t\t\t\t\t\t\t.join(\"\\n\") || \"(no results)\",\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"show\": {\n\t\t\t\tif (!pkgName) return { stderr: \"Need a package name\", exitCode: 1 };\n\t\t\t\tconst info = pm.show(pkgName);\n\t\t\t\treturn info\n\t\t\t\t\t? { stdout: info, exitCode: 0 }\n\t\t\t\t\t: { stderr: `N: Unable to locate package ${pkgName}`, exitCode: 100 };\n\t\t\t}\n\t\t\tcase \"policy\": {\n\t\t\t\tif (!pkgName) return { stderr: \"Need a package name\", exitCode: 1 };\n\t\t\t\tconst def = pm.findInRegistry(pkgName);\n\t\t\t\tif (!def)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `N: Unable to locate package ${pkgName}`,\n\t\t\t\t\t\texitCode: 100,\n\t\t\t\t\t};\n\t\t\t\tconst inst = pm.isInstalled(pkgName);\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t`${pkgName}:`,\n\t\t\t\t\t\t` Installed: ${inst ? def.version : \"(none)\"}`,\n\t\t\t\t\t\t` Candidate: ${def.version}`,\n\t\t\t\t\t\t` Version table:`,\n\t\t\t\t\t\t` ${def.version} 500`,\n\t\t\t\t\t\t` 500 fortune://packages.fortune.local aurora/main amd64 Packages`,\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `apt-cache: unknown command '${sub ?? \"\"}'`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\n\n/**\n * Minimal `awk`-like pattern scanner (supports simple print patterns).\n * @category text\n * @params [\"[-F <sep>] '<program>' [file]\"]\n *\n * Supported program patterns:\n * - `print $N` (e.g. `print $1`, `print $2, $3`, `print $0`)\n * - `{print $N}` (e.g. `{print $1}`, `{print $2, $3}`, `{print $0}`)\n *\n * The field separator can be set with `-F` (default is space, which splits on any whitespace).\n */\nexport const awkCommand: ShellModule = {\n\tname: \"awk\",\n\tdescription: \"Pattern scanning and processing language (minimal)\",\n\tcategory: \"text\",\n\tparams: [\"[-F <sep>] '<program>' [file]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst sep = (getFlag(args, [\"-F\"]) as string | undefined) ?? \" \";\n\t\tconst prog = args.find((a) => !a.startsWith(\"-\") && a !== sep);\n\t\tif (!prog) return { stderr: \"awk: no program\", exitCode: 1 };\n\n\t\t// Only support print $N and {print $N} patterns\n\t\tconst printMatch = prog.match(/^\\{?\\s*print\\s+([^}]+)\\s*\\}?$/);\n\t\tif (!printMatch)\n\t\t\treturn { stderr: `awk: unsupported program: ${prog}`, exitCode: 1 };\n\n\t\tconst fields = printMatch[1]!.split(/\\s*,\\s*/).map((f) => f.trim());\n\t\tconst lines = (stdin ?? \"\").split(\"\\n\").filter(Boolean);\n\t\tconst out = lines.map((line) => {\n\t\t\tconst parts = line.split(sep === \" \" ? /\\s+/ : sep);\n\t\t\treturn fields\n\t\t\t\t.map((f) => {\n\t\t\t\t\tif (f === \"$0\") return line;\n\t\t\t\t\tconst n = parseInt(f.replace(\"$\", \"\"), 10);\n\t\t\t\t\treturn Number.isNaN(n) ? f.replace(/\"/g, \"\") : (parts[n - 1] ?? \"\");\n\t\t\t\t})\n\t\t\t\t.join(sep === \" \" ? \"\\t\" : sep);\n\t\t});\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\n/**\n * Encode or decode base64 data.\n * @category text\n * @params [\"[-d] [file]\"]\n */\nexport const base64Command: ShellModule = {\n\tname: \"base64\",\n\tdescription: \"Encode/decode base64\",\n\tcategory: \"text\",\n\tparams: [\"[-d] [file]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst decode = ifFlag(args, [\"-d\", \"--decode\"]);\n\t\tconst input = stdin ?? \"\";\n\t\tif (decode) {\n\t\t\ttry {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: Buffer.from(input.trim(), \"base64\").toString(\"utf8\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\treturn { stderr: \"base64: invalid input\", exitCode: 1 };\n\t\t\t}\n\t\t}\n\t\treturn { stdout: Buffer.from(input).toString(\"base64\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolveReadablePath } from \"./helpers\";\n\n/**\n * Concatenate and print files to stdout.\n * @category files\n * @params [\"[-n] [-b] <file...>\"]\n */\nexport const catCommand: ShellModule = {\n\tname: \"cat\",\n\tdescription: \"Concatenate and print files\",\n\tcategory: \"files\",\n\tparams: [\"[-n] [-b] <file...>\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst numberAll = ifFlag(args, [\"-n\", \"--number\"]);\n\t\tconst numberNonBlank = ifFlag(args, [\"-b\", \"--number-nonblank\"]);\n\t\tconst fileArgs = args.filter((a) => !a.startsWith(\"-\"));\n\n\t\tif (fileArgs.length === 0 && stdin !== undefined) {\n\t\t\treturn { stdout: stdin, exitCode: 0 };\n\t\t}\n\n\t\tif (fileArgs.length === 0) {\n\t\t\treturn { stderr: \"cat: missing file operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst parts: string[] = [];\n\t\tfor (const fileArg of fileArgs) {\n\t\t\tconst target = resolveReadablePath(shell.vfs, cwd, fileArg);\n\t\t\tassertPathAccess(authUser, target, \"cat\");\n\t\t\tparts.push(shell.vfs.readFile(target));\n\t\t}\n\n\t\tconst combined = parts.join(\"\");\n\n\t\tif (!numberAll && !numberNonBlank) {\n\t\t\treturn { stdout: combined, exitCode: 0 };\n\t\t}\n\n\t\tlet lineNum = 1;\n\t\tconst numbered = combined\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => {\n\t\t\t\tif (numberNonBlank && line.trim() === \"\") return line;\n\t\t\t\treturn `${String(lineNum++).padStart(6)}\\t${line}`;\n\t\t\t})\n\t\t\t.join(\"\\n\");\n\n\t\treturn { stdout: numbered, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Change current working directory.\n * @category navigation\n * @params [\"[path]\"]\n */\nexport const cdCommand: ShellModule = {\n\tname: \"cd\",\n\tdescription: \"Change directory\",\n\tcategory: \"navigation\",\n\tparams: [\"[path]\"],\n\trun: ({ authUser, shell, cwd, args, mode }) => {\n\t\tconst target = resolvePath(cwd, args[0] ?? \"/virtual-env-js\");\n\t\tassertPathAccess(authUser, target, \"cd\");\n\t\tconst stats = shell.vfs.stat(target);\n\t\tif (stats.type !== \"directory\") {\n\t\t\treturn { stderr: `cd: not a directory: ${target}`, exitCode: 1 };\n\t\t}\n\n\t\tif (mode === \"exec\") {\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\treturn { nextCwd: target, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Parse a symbolic chmod mode string (e.g. \"+x\", \"u+x\", \"go-w\", \"a+rx\")\n * and apply it to the existing mode bits.\n * Returns null if the string is not a valid symbolic mode.\n */\nfunction applySymbolicMode(existing: number, modeStr: string): number | null {\n\tconst pattern = /^([ugoa]*)([+\\-=])([rwx]*)$/;\n\tconst parts = modeStr.split(\",\");\n\tlet mode = existing;\n\tfor (const part of parts) {\n\t\tconst m = part.trim().match(pattern);\n\t\tif (!m) return null;\n\t\tconst [, who = \"a\", op, perms = \"\"] = m;\n\t\tconst targets = who === \"\" || who === \"a\" ? [\"u\", \"g\", \"o\"] : who.split(\"\");\n\t\tconst bits: Record<string, Record<string, number>> = {\n\t\t\tu: { r: 0o400, w: 0o200, x: 0o100 },\n\t\t\tg: { r: 0o040, w: 0o020, x: 0o010 },\n\t\t\to: { r: 0o004, w: 0o002, x: 0o001 },\n\t\t};\n\t\tfor (const t of targets) {\n\t\t\tfor (const p of perms.split(\"\")) {\n\t\t\t\tconst bit = bits[t]?.[p];\n\t\t\t\tif (bit === undefined) continue;\n\t\t\t\tif (op === \"+\") mode |= bit;\n\t\t\t\telse if (op === \"-\") mode &= ~bit;\n\t\t\t\telse if (op === \"=\") {\n\t\t\t\t\t// clear all bits for this target, then set requested\n\t\t\t\t\tconst mask = Object.values(bits[t] ?? {}).reduce((a, b) => a | b, 0);\n\t\t\t\t\tmode = (mode & ~mask) | bit;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn mode;\n}\n\n/**\n * Change file permissions (octal or symbolic).\n * @category files\n * @params [\"<mode> <file>\"]\n */\nexport const chmodCommand: ShellModule = {\n\tname: \"chmod\",\n\tdescription: \"Change file permissions\",\n\tcategory: \"files\",\n\tparams: [\"<mode> <file>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst [modeArg, fileArg] = args;\n\t\tif (!modeArg || !fileArg) {\n\t\t\treturn { stderr: \"chmod: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst filePath = resolvePath(cwd, fileArg);\n\t\ttry {\n\t\t\tassertPathAccess(authUser, filePath, \"chmod\");\n\t\t\tif (!shell.vfs.exists(filePath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `chmod: ${fileArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tlet mode: number;\n\t\t\tconst octal = parseInt(modeArg, 8);\n\t\t\tif (!Number.isNaN(octal) && /^[0-7]+$/.test(modeArg)) {\n\t\t\t\tmode = octal;\n\t\t\t} else {\n\t\t\t\t// symbolic mode\n\t\t\t\tconst existing = shell.vfs.stat(filePath).mode;\n\t\t\t\tconst result = applySymbolicMode(existing, modeArg);\n\t\t\t\tif (result === null) {\n\t\t\t\t\treturn { stderr: `chmod: invalid mode: ${modeArg}`, exitCode: 1 };\n\t\t\t\t}\n\t\t\t\tmode = result;\n\t\t\t}\n\t\t\tshell.vfs.chmod(filePath, mode);\n\t\t\treturn { exitCode: 0 };\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `chmod: ${msg}`, exitCode: 1 };\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const clearCommand: ShellModule = {\n\tname: \"clear\",\n\tdescription: \"Clear the terminal screen\",\n\tcategory: \"shell\",\n\tparams: [],\n\t// clearScreen flag triggers \\x1b[2J\\x1b[H in the shell layer\n\trun: () => ({ clearScreen: true, stdout: \"\", exitCode: 0 }),\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Copy files or directories inside the virtual filesystem.\n * @category files\n * @params [\"[-r] <source> <dest>\"]\n */\nexport const cpCommand: ShellModule = {\n\tname: \"cp\",\n\tdescription: \"Copy files or directories\",\n\tcategory: \"files\",\n\tparams: [\"[-r] <source> <dest>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst recursive = ifFlag(args, [\"-r\", \"-R\", \"--recursive\"]);\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst [srcArg, destArg] = positionals;\n\n\t\tif (!srcArg || !destArg) {\n\t\t\treturn { stderr: \"cp: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst srcPath = resolvePath(cwd, srcArg);\n\t\tconst destPath = resolvePath(cwd, destArg);\n\n\t\ttry {\n\t\t\tassertPathAccess(authUser, srcPath, \"cp\");\n\t\t\tassertPathAccess(authUser, destPath, \"cp\");\n\n\t\t\tif (!shell.vfs.exists(srcPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `cp: ${srcArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst srcStat = shell.vfs.stat(srcPath);\n\n\t\t\tif (srcStat.type === \"directory\") {\n\t\t\t\tif (!recursive) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `cp: ${srcArg}: is a directory (use -r)`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst copyDir = (from: string, to: string) => {\n\t\t\t\t\tshell.vfs.mkdir(to, 0o755);\n\t\t\t\t\tfor (const entry of shell.vfs.list(from)) {\n\t\t\t\t\t\tconst fromEntry = `${from}/${entry}`;\n\t\t\t\t\t\tconst toEntry = `${to}/${entry}`;\n\t\t\t\t\t\tconst stat = shell.vfs.stat(fromEntry);\n\t\t\t\t\t\tif (stat.type === \"directory\") {\n\t\t\t\t\t\t\tcopyDir(fromEntry, toEntry);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst content = shell.vfs.readFileRaw(fromEntry);\n\t\t\t\t\t\t\tshell.writeFileAsUser(authUser, toEntry, content);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tconst finalDest =\n\t\t\t\t\tshell.vfs.exists(destPath) &&\n\t\t\t\t\tshell.vfs.stat(destPath).type === \"directory\"\n\t\t\t\t\t\t? `${destPath}/${srcArg.split(\"/\").pop()}`\n\t\t\t\t\t\t: destPath;\n\t\t\t\tcopyDir(srcPath, finalDest);\n\t\t\t} else {\n\t\t\t\tconst finalDest =\n\t\t\t\t\tshell.vfs.exists(destPath) &&\n\t\t\t\t\tshell.vfs.stat(destPath).type === \"directory\"\n\t\t\t\t\t\t? `${destPath}/${srcArg.split(\"/\").pop()}`\n\t\t\t\t\t\t: destPath;\n\t\t\t\tconst content = shell.vfs.readFileRaw(srcPath);\n\t\t\t\tshell.writeFileAsUser(authUser, finalDest, content);\n\t\t\t}\n\n\t\t\treturn { exitCode: 0 };\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `cp: ${msg}`, exitCode: 1 };\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag, parseArgs } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * HTTP client wrapper using `fetch()` semantics (virtual curl).\n * @category network\n * @params [\"[options] <url>\"]\n */\nexport const curlCommand: ShellModule = {\n\tname: \"curl\",\n\tdescription: \"Transfer data from or to a server (pure fetch)\",\n\tcategory: \"network\",\n\tparams: [\"[options] <url>\"],\n\trun: async ({ authUser, cwd, args, shell }) => {\n\t\tconst { flagsWithValues, positionals } = parseArgs(args, {\n\t\t\tflagsWithValue: [\n\t\t\t\t\"-o\",\n\t\t\t\t\"--output\",\n\t\t\t\t\"-X\",\n\t\t\t\t\"--request\",\n\t\t\t\t\"-d\",\n\t\t\t\t\"--data\",\n\t\t\t\t\"-H\",\n\t\t\t\t\"--header\",\n\t\t\t\t\"-u\",\n\t\t\t\t\"--user\",\n\t\t\t],\n\t\t});\n\n\t\tif (ifFlag(args, [\"--help\", \"-h\"])) {\n\t\t\treturn {\n\t\t\t\tstdout: [\n\t\t\t\t\t\"Usage: curl [options] <url>\",\n\t\t\t\t\t\" -o, --output <file> Write to file\",\n\t\t\t\t\t\" -X, --request <method> HTTP method\",\n\t\t\t\t\t\" -d, --data <data> POST data\",\n\t\t\t\t\t\" -H, --header <hdr> Extra header\",\n\t\t\t\t\t\" -s, --silent Silent mode\",\n\t\t\t\t\t\" -I, --head Fetch headers only\",\n\t\t\t\t\t\" -L, --location Follow redirects\",\n\t\t\t\t\t\" -v, --verbose Verbose\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst url = positionals[0];\n\t\tif (!url) return { stderr: \"curl: no URL specified\", exitCode: 1 };\n\n\t\tconst outputPath =\n\t\t\tflagsWithValues.get(\"-o\") ?? flagsWithValues.get(\"--output\") ?? null;\n\t\tconst method = (\n\t\t\tflagsWithValues.get(\"-X\") ??\n\t\t\tflagsWithValues.get(\"--request\") ??\n\t\t\t\"GET\"\n\t\t).toUpperCase();\n\t\tconst postData =\n\t\t\tflagsWithValues.get(\"-d\") ?? flagsWithValues.get(\"--data\") ?? null;\n\t\tconst headerRaw =\n\t\t\tflagsWithValues.get(\"-H\") ?? flagsWithValues.get(\"--header\") ?? null;\n\t\tconst silent = ifFlag(args, [\"-s\", \"--silent\"]);\n\t\tconst headOnly = ifFlag(args, [\"-I\", \"--head\"]);\n\t\tconst followRedirects = ifFlag(args, [\"-L\", \"--location\"]);\n\t\tconst verbose = ifFlag(args, [\"-v\", \"--verbose\"]);\n\n\t\tconst extraHeaders: Record<string, string> = {\n\t\t\t\"User-Agent\": \"curl/7.88.1\",\n\t\t};\n\t\tif (headerRaw) {\n\t\t\tconst idx = headerRaw.indexOf(\":\");\n\t\t\tif (idx !== -1)\n\t\t\t\textraHeaders[headerRaw.slice(0, idx).trim()] = headerRaw\n\t\t\t\t\t.slice(idx + 1)\n\t\t\t\t\t.trim();\n\t\t}\n\n\t\tconst finalMethod = postData && method === \"GET\" ? \"POST\" : method;\n\t\tconst fetchOpts: RequestInit = {\n\t\t\tmethod: finalMethod,\n\t\t\theaders: extraHeaders,\n\t\t\tredirect: followRedirects ? \"follow\" : \"manual\",\n\t\t};\n\t\tif (postData) {\n\t\t\textraHeaders[\"Content-Type\"] ??= \"application/x-www-form-urlencoded\";\n\t\t\tfetchOpts.body = postData;\n\t\t}\n\n\t\tconst stderrLines: string[] = [];\n\t\tif (verbose) {\n\t\t\tstderrLines.push(`* Trying ${url}...`, `* Connected`);\n\t\t\tstderrLines.push(\n\t\t\t\t`> ${finalMethod} / HTTP/1.1`,\n\t\t\t\t`> Host: ${new URL(url).host}`,\n\t\t\t);\n\t\t}\n\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetch(url, fetchOpts);\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn {\n\t\t\t\tstderr: `curl: (6) Could not resolve host: ${msg}`,\n\t\t\t\texitCode: 6,\n\t\t\t};\n\t\t}\n\n\t\tif (verbose) {\n\t\t\tstderrLines.push(`< HTTP/1.1 ${response.status} ${response.statusText}`);\n\t\t}\n\n\t\tif (headOnly) {\n\t\t\tconst lines = [`HTTP/1.1 ${response.status} ${response.statusText}`];\n\t\t\tfor (const [k, v] of response.headers.entries()) lines.push(`${k}: ${v}`);\n\t\t\treturn { stdout: `${lines.join(\"\\r\\n\")}\\r\\n`, exitCode: 0 };\n\t\t}\n\n\t\tlet body: string;\n\t\ttry {\n\t\t\tbody = await response.text();\n\t\t} catch {\n\t\t\treturn { stderr: \"curl: failed to read response body\", exitCode: 1 };\n\t\t}\n\n\t\tif (outputPath) {\n\t\t\tconst target = resolvePath(cwd, outputPath);\n\t\t\tassertPathAccess(authUser, target, \"curl\");\n\t\t\tshell.writeFileAsUser(authUser, target, body);\n\t\t\tif (!silent)\n\t\t\t\tstderrLines.push(\n\t\t\t\t\t` % Total % Received\\n100 ${body.length} 100 ${body.length}`,\n\t\t\t\t);\n\t\t\treturn {\n\t\t\t\tstderr: stderrLines.join(\"\\n\") || undefined,\n\t\t\t\texitCode: response.ok ? 0 : 22,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstdout: body,\n\t\t\tstderr: stderrLines.length > 0 ? stderrLines.join(\"\\n\") : undefined,\n\t\t\texitCode: response.ok ? 0 : 22,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\n\n/**\n * Extract selected fields from each line of input.\n * @category text\n * @params [\"-d <delim> -f <fields> [file]\"]\n */\nexport const cutCommand: ShellModule = {\n\tname: \"cut\",\n\tdescription: \"Remove sections from lines\",\n\tcategory: \"text\",\n\tparams: [\"-d <delim> -f <fields> [file]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst delim = (getFlag(args, [\"-d\"]) as string | undefined) ?? \"\\t\";\n\t\tconst fields = (getFlag(args, [\"-f\"]) as string | undefined) ?? \"1\";\n\t\tconst cols = fields.split(\",\").map((f) => {\n\t\t\tconst [a, b] = f.split(\"-\").map(Number);\n\t\t\treturn b !== undefined\n\t\t\t\t? { from: (a ?? 1) - 1, to: b - 1 }\n\t\t\t\t: { from: (a ?? 1) - 1, to: (a ?? 1) - 1 };\n\t\t});\n\t\tconst lines = (stdin ?? \"\").split(\"\\n\");\n\t\tconst out = lines.map((line) => {\n\t\t\tconst parts = line.split(delim);\n\t\t\tconst selected: string[] = [];\n\t\t\tfor (const col of cols) {\n\t\t\t\tfor (let i = col.from; i <= Math.min(col.to, parts.length - 1); i++) {\n\t\t\t\t\tselected.push(parts[i] ?? \"\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn selected.join(delim);\n\t\t});\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Print the current date/time or a formatted representation.\n * @category system\n * @params [\"[+format]\"]\n */\nexport const dateCommand: ShellModule = {\n\tname: \"date\",\n\tdescription: \"Print current date and time\",\n\tcategory: \"system\",\n\tparams: [\"[+format]\"],\n\trun: ({ args }) => {\n\t\tconst now = new Date();\n\t\tconst fmt = args[0];\n\t\tif (fmt?.startsWith(\"+\")) {\n\t\t\tconst f = fmt\n\t\t\t\t.slice(1)\n\t\t\t\t.replace(\"%Y\", String(now.getFullYear()))\n\t\t\t\t.replace(\"%m\", String(now.getMonth() + 1).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%d\", String(now.getDate()).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%H\", String(now.getHours()).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%M\", String(now.getMinutes()).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%S\", String(now.getSeconds()).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%s\", String(Math.floor(now.getTime() / 1000)));\n\t\t\treturn { stdout: f, exitCode: 0 };\n\t\t}\n\t\treturn { stdout: now.toString(), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const declareCommand: ShellModule = {\n\tname: \"declare\",\n\taliases: [\"local\", \"typeset\"],\n\tdescription: \"Declare variables and give them attributes\",\n\tcategory: \"shell\",\n\tparams: [\"[-i] [-r] [-x] [-a] [name[=value]...]\"],\n\trun: ({ args, env }) => {\n\t\tif (!env) return { exitCode: 0 };\n\n\t\tconst integer = ifFlag(args, [\"-i\"]);\n\t\tconst _readonly = ifFlag(args, [\"-r\"]);\n\t\tconst _export_ = ifFlag(args, [\"-x\"]);\n\t\tconst printAll = args.filter((a) => !a.startsWith(\"-\")).length === 0;\n\n\t\tif (printAll) {\n\t\t\tconst lines = Object.entries(env.vars).map(\n\t\t\t\t([k, v]) => `declare -- ${k}=\"${v}\"`,\n\t\t\t);\n\t\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t\t}\n\n\t\tconst assignments = args.filter((a) => !a.startsWith(\"-\"));\n\t\tfor (const token of assignments) {\n\t\t\tconst eq = token.indexOf(\"=\");\n\t\t\tif (eq === -1) {\n\t\t\t\t// Just declare (no value)\n\t\t\t\tif (!(token in env.vars)) env.vars[token] = \"\";\n\t\t\t} else {\n\t\t\t\tconst name = token.slice(0, eq);\n\t\t\t\tlet val = token.slice(eq + 1);\n\t\t\t\tif (integer) {\n\t\t\t\t\tconst n = parseInt(val, 10);\n\t\t\t\t\tval = Number.isNaN(n) ? \"0\" : String(n);\n\t\t\t\t}\n\t\t\t\tenv.vars[name] = val;\n\t\t\t}\n\t\t}\n\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const deluserCommand: ShellModule = {\n\tname: \"deluser\",\n\tdescription: \"Delete a user\",\n\tcategory: \"users\",\n\tparams: [\"<username>\"],\n\trun: async ({ authUser, args, shell }) => {\n\t\tif (authUser !== \"root\") {\n\t\t\treturn { stderr: \"deluser: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tconst [username] = args;\n\t\tif (!username) {\n\t\t\treturn { stderr: \"deluser: usage: deluser <username>\", exitCode: 1 };\n\t\t}\n\n\t\tawait shell.users.deleteUser(username);\n\t\treturn { stdout: `deluser: user '${username}' deleted`, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const dfCommand: ShellModule = {\n\tname: \"df\",\n\tdescription: \"Report filesystem disk space usage\",\n\tcategory: \"system\",\n\tparams: [\"[-h]\"],\n\trun: ({ shell }) => {\n\t\tconst bytes = shell.vfs.getUsageBytes();\n\t\tconst used = (bytes / 1024).toFixed(0);\n\t\tconst total = \"1048576\"; // 1GB virtual\n\t\tconst avail = String(Number(total) - Number(used));\n\t\tconst pct = Math.round((Number(used) / Number(total)) * 100);\n\t\tconst hdr = \"Filesystem 1K-blocks Used Available Use% Mounted on\";\n\t\tconst row = `virtual-fs ${total.padStart(9)} ${used.padStart(7)} ${avail.padStart(9)} ${pct}% /`;\n\t\treturn { stdout: `${hdr}\\n${row}`, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { resolvePath } from \"./helpers\";\n\n/**\n * Compare files line-by-line and print differing lines.\n * @category text\n * @params [\"<file1> <file2>\"]\n */\nexport const diffCommand: ShellModule = {\n\tname: \"diff\",\n\tdescription: \"Compare files line by line\",\n\tcategory: \"text\",\n\tparams: [\"<file1> <file2>\"],\n\trun: ({ shell, cwd, args }) => {\n\t\tconst [f1, f2] = args;\n\t\tif (!f1 || !f2) return { stderr: \"diff: missing operand\", exitCode: 1 };\n\t\tconst p1 = resolvePath(cwd, f1);\n\t\tconst p2 = resolvePath(cwd, f2);\n\t\tlet a: string[], b: string[];\n\t\ttry {\n\t\t\ta = shell.vfs.readFile(p1).split(\"\\n\");\n\t\t} catch {\n\t\t\treturn { stderr: `diff: ${f1}: No such file or directory`, exitCode: 2 };\n\t\t}\n\t\ttry {\n\t\t\tb = shell.vfs.readFile(p2).split(\"\\n\");\n\t\t} catch {\n\t\t\treturn { stderr: `diff: ${f2}: No such file or directory`, exitCode: 2 };\n\t\t}\n\n\t\tconst out: string[] = [];\n\t\tconst max = Math.max(a.length, b.length);\n\t\tfor (let i = 0; i < max; i++) {\n\t\t\tconst la = a[i];\n\t\t\tconst lb = b[i];\n\t\t\tif (la !== lb) {\n\t\t\t\tif (la !== undefined) out.push(`< ${la}`);\n\t\t\t\tif (lb !== undefined) out.push(`> ${lb}`);\n\t\t\t}\n\t\t}\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: out.length > 0 ? 1 : 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag, parseArgs } from \"./command-helpers\";\nimport { getPackageManager } from \"./helpers\";\n\n/**\n * dpkg compatibility command (query/remove/list) backed by the virtual package manager.\n * @category package\n * @params [\"[-l] [-s pkg] [-L pkg] [-i pkg] [--remove pkg]\"]\n */\nexport const dpkgCommand: ShellModule = {\n\tname: \"dpkg\",\n\tdescription: \"Debian package manager low-level tool\",\n\tcategory: \"package\",\n\tparams: [\"[-l] [-s pkg] [-L pkg] [-i pkg] [--remove pkg]\"],\n\trun: ({ args, authUser, shell }) => {\n\t\tconst pm = getPackageManager(shell);\n\t\tif (!pm)\n\t\t\treturn { stderr: \"dpkg: package manager not initialised\", exitCode: 1 };\n\n\t\tconst listFlag = ifFlag(args, [\"-l\", \"--list\"]);\n\t\tconst statusFlag = ifFlag(args, [\"-s\", \"--status\"]);\n\t\tconst listFilesFlag = ifFlag(args, [\"-L\", \"--listfiles\"]);\n\t\tconst removeFlag = ifFlag(args, [\"-r\", \"--remove\"]);\n\t\tconst purgeFlag = ifFlag(args, [\"-P\", \"--purge\"]);\n\n\t\tconst { positionals } = parseArgs(args, {\n\t\t\tflags: [\n\t\t\t\t\"-l\",\n\t\t\t\t\"--list\",\n\t\t\t\t\"-s\",\n\t\t\t\t\"--status\",\n\t\t\t\t\"-L\",\n\t\t\t\t\"--listfiles\",\n\t\t\t\t\"-r\",\n\t\t\t\t\"--remove\",\n\t\t\t\t\"-P\",\n\t\t\t\t\"--purge\",\n\t\t\t],\n\t\t});\n\n\t\tif (listFlag) {\n\t\t\tconst pkgList = pm.listInstalled();\n\t\t\tif (pkgList.length === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t\"Desired=Unknown/Install/Remove/Purge/Hold\",\n\t\t\t\t\t\t\"|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend\",\n\t\t\t\t\t\t\"|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)\",\n\t\t\t\t\t\t\"||/ Name Version Architecture Description\",\n\t\t\t\t\t\t\"+++-==============-===============-============-========================================\",\n\t\t\t\t\t\t\"(no packages installed)\",\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst header = [\n\t\t\t\t\"Desired=Unknown/Install/Remove/Purge/Hold\",\n\t\t\t\t\"|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend\",\n\t\t\t\t\"|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)\",\n\t\t\t\t\"||/ Name Version Architecture Description\",\n\t\t\t\t\"+++-==============-===============-============-========================================\",\n\t\t\t];\n\n\t\t\tconst rows = pkgList.map((p) => {\n\t\t\t\tconst name = p.name.padEnd(14).slice(0, 14);\n\t\t\t\tconst ver = p.version.padEnd(15).slice(0, 15);\n\t\t\t\tconst arch = p.architecture.padEnd(12).slice(0, 12);\n\t\t\t\tconst desc = (p.description || \"\").slice(0, 40);\n\t\t\t\treturn `ii ${name} ${ver} ${arch} ${desc}`;\n\t\t\t});\n\n\t\t\treturn { stdout: [...header, ...rows].join(\"\\n\"), exitCode: 0 };\n\t\t}\n\n\t\tif (statusFlag) {\n\t\t\tconst pkgName = positionals[0];\n\t\t\tif (!pkgName)\n\t\t\t\treturn { stderr: \"dpkg: -s needs a package name\", exitCode: 1 };\n\t\t\tconst info = pm.show(pkgName);\n\t\t\tif (!info)\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `dpkg-query: package '${pkgName}' is not installed and no information is available`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\treturn { stdout: info, exitCode: 0 };\n\t\t}\n\n\t\tif (listFilesFlag) {\n\t\t\tconst pkgName = positionals[0];\n\t\t\tif (!pkgName)\n\t\t\t\treturn { stderr: \"dpkg: -L needs a package name\", exitCode: 1 };\n\t\t\tconst installed = pm.listInstalled().find((p) => p.name === pkgName);\n\t\t\tif (!installed)\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `dpkg-query: package '${pkgName}' is not installed`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\tif (installed.files.length === 0)\n\t\t\t\treturn { stdout: \"/.keep\", exitCode: 0 };\n\t\t\treturn { stdout: installed.files.join(\"\\n\"), exitCode: 0 };\n\t\t}\n\n\t\tif (removeFlag || purgeFlag) {\n\t\t\tif (authUser !== \"root\")\n\t\t\t\treturn {\n\t\t\t\t\tstderr:\n\t\t\t\t\t\t\"dpkg: error: requested operation requires superuser privilege\",\n\t\t\t\t\texitCode: 2,\n\t\t\t\t};\n\t\t\tif (positionals.length === 0)\n\t\t\t\treturn { stderr: \"dpkg: error: need an action option\", exitCode: 2 };\n\t\t\tconst { output, exitCode } = pm.remove(positionals, { purge: purgeFlag });\n\t\t\treturn { stdout: output || undefined, exitCode };\n\t\t}\n\n\t\t// Default: show help\n\t\treturn {\n\t\t\tstdout: [\n\t\t\t\t\"Usage: dpkg [<option>...] <command>\",\n\t\t\t\t\"\",\n\t\t\t\t\"Commands:\",\n\t\t\t\t\" -l, --list List packages matching given pattern\",\n\t\t\t\t\" -s, --status <pkg>... Report status of specified package\",\n\t\t\t\t\" -L, --listfiles <pkg>... List files owned by package\",\n\t\t\t\t\" -r, --remove <pkg>... Remove <pkg> but leave its configuration\",\n\t\t\t\t\" -P, --purge <pkg>... Remove <pkg> and its configuration\",\n\t\t\t].join(\"\\n\"),\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n\nexport const dpkgQueryCommand: ShellModule = {\n\tname: \"dpkg-query\",\n\tdescription: \"Show information about installed packages\",\n\tcategory: \"package\",\n\tparams: [\"-W [pkg] | -l [pattern]\"],\n\trun: ({ args, shell }) => {\n\t\tconst pm = getPackageManager(shell);\n\t\tif (!pm)\n\t\t\treturn {\n\t\t\t\tstderr: \"dpkg-query: package manager not initialised\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\n\t\tconst listFlag = ifFlag(args, [\"-l\"]);\n\t\tconst showFlag = ifFlag(args, [\"-W\", \"--show\"]);\n\t\tconst { positionals } = parseArgs(args, {\n\t\t\tflags: [\"-l\", \"-W\", \"--show\"],\n\t\t});\n\n\t\tif (listFlag || showFlag) {\n\t\t\tconst pkgList = pm.listInstalled();\n\t\t\tconst pattern = positionals[0];\n\t\t\tconst filtered = pattern\n\t\t\t\t? pkgList.filter((p) => p.name.includes(pattern))\n\t\t\t\t: pkgList;\n\n\t\t\tif (showFlag) {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: filtered.map((p) => `${p.name}\\t${p.version}`).join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst rows = filtered.map((p) => {\n\t\t\t\tconst name = p.name.padEnd(14).slice(0, 14);\n\t\t\t\tconst ver = p.version.padEnd(15).slice(0, 15);\n\t\t\t\treturn `ii ${name} ${ver} amd64 ${(p.description || \"\").slice(0, 40)}`;\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tstdout: rows.join(\"\\n\") || \"(no packages match)\",\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\treturn { stderr: \"dpkg-query: need a flag (-l, -W)\", exitCode: 1 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nexport const duCommand: ShellModule = {\n\tname: \"du\",\n\tdescription: \"Estimate file space usage\",\n\tcategory: \"system\",\n\tparams: [\"[-h] [-s] [path]\"],\n\trun: ({ shell, cwd, args }) => {\n\t\tconst human = ifFlag(args, [\"-h\"]);\n\t\tconst summary = ifFlag(args, [\"-s\"]);\n\t\tconst target = args.find((a) => !a.startsWith(\"-\")) ?? \".\";\n\t\tconst p = resolvePath(cwd, target);\n\n\t\tconst fmt = (b: number) =>\n\t\t\thuman ? `${(b / 1024).toFixed(1)}K` : String(Math.ceil(b / 1024));\n\n\t\tif (!shell.vfs.exists(p))\n\t\t\treturn {\n\t\t\t\tstderr: `du: ${target}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\n\t\tif (summary || shell.vfs.stat(p).type === \"file\") {\n\t\t\treturn {\n\t\t\t\tstdout: `${fmt(shell.vfs.getUsageBytes(p))}\\t${target}`,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst lines: string[] = [];\n\t\tconst walk = (dir: string, rel: string) => {\n\t\t\tlet total = 0;\n\t\t\tfor (const e of shell.vfs.list(dir)) {\n\t\t\t\tconst full = `${dir}/${e}`,\n\t\t\t\t\tr = `${rel}/${e}`;\n\t\t\t\tconst st = shell.vfs.stat(full);\n\t\t\t\tif (st.type === \"directory\") total += walk(full, r);\n\t\t\t\telse {\n\t\t\t\t\ttotal += st.size;\n\t\t\t\t\tif (!summary) lines.push(`${fmt(st.size)}\\t${r}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlines.push(`${fmt(total)}\\t${rel}`);\n\t\t\treturn total;\n\t\t};\n\t\twalk(p, target);\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "/**\n * expand.ts\n *\n * Centralised shell variable and expression expansion.\n * Used by `runCommand` (index.ts), `echo`, and `sh.ts`.\n *\n * Handles (in order):\n * ~ tilde to $HOME\n * $? last exit code\n * $$ mock PID\n * $# argument count (0 outside scripts)\n * ${#VAR} string length\n * ${VAR:-def} default if unset/empty\n * ${VAR:=def} assign default if unset/empty\n * ${VAR:+val} alternate value if set\n * ${VAR} simple braced reference\n * $VAR simple reference\n * $((expr)) arithmetic (integer)\n */\n\n// \u2500\u2500\u2500 arithmetic evaluator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Evaluate a simple integer arithmetic expression.\n * Supports: + - * / % ** unary- ( )\n * Variables are resolved from `env` before evaluation.\n * Returns NaN on syntax error.\n */\nexport function evalArith(expr: string, env: Record<string, string>): number {\n\t// Substitute variable names before evaluating\n\tconst substituted = expr.replace(\n\t\t/\\b([A-Za-z_][A-Za-z0-9_]*)\\b/g,\n\t\t(_, name) => {\n\t\t\tconst val = env[name];\n\t\t\treturn val !== undefined && val !== \"\" ? val : \"0\";\n\t\t},\n\t);\n\n\t// Whitelist: only digits, operators, spaces, parens\n\tif (!/^[\\d\\s+\\-*/%()^!&|<>=,. ]+$/.test(substituted)) return NaN;\n\n\ttry {\n\t\t// Use Function constructor for safe subset (no identifiers remain)\n\t\t// eslint-disable-next-line no-new-func\n\t\tconst result = Function(\n\t\t\t`\"use strict\"; return (${substituted.replace(/\\*\\*/g, \"**\")});`,\n\t\t)();\n\t\treturn typeof result === \"number\" ? Math.trunc(result) : NaN;\n\t} catch {\n\t\treturn NaN;\n\t}\n}\n\n// \u2500\u2500\u2500 synchronous expansion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Apply a replacer only to portions of `input` that are NOT inside single quotes.\n * Single-quoted content is passed through verbatim (POSIX sh behaviour).\n */\nfunction outsideSingleQuotes(\n\tinput: string,\n\treplacer: (chunk: string) => string,\n): string {\n\tconst parts: string[] = [];\n\tlet i = 0;\n\twhile (i < input.length) {\n\t\tconst sqIdx = input.indexOf(\"'\", i);\n\t\tif (sqIdx === -1) {\n\t\t\t// No more single quotes \u2014 expand the rest\n\t\t\tparts.push(replacer(input.slice(i)));\n\t\t\tbreak;\n\t\t}\n\t\t// Expand the part before the single quote\n\t\tparts.push(replacer(input.slice(i, sqIdx)));\n\t\t// Find closing single quote \u2014 everything inside is literal\n\t\tconst closeIdx = input.indexOf(\"'\", sqIdx + 1);\n\t\tif (closeIdx === -1) {\n\t\t\t// Unclosed quote \u2014 treat rest as literal\n\t\t\tparts.push(input.slice(sqIdx));\n\t\t\tbreak;\n\t\t}\n\t\tparts.push(input.slice(sqIdx, closeIdx + 1)); // include quotes\n\t\ti = closeIdx + 1;\n\t}\n\treturn parts.join(\"\");\n}\n\n/**\n * Expand all shell variable and expression forms synchronously.\n * Does NOT handle `$(cmd)` \u2014 that requires async; see `expandAsync`.\n * Content inside single quotes is left verbatim per POSIX sh rules.\n *\n * @param input Raw string possibly containing `$VAR`, `${...}`, `$((...))`.\n * @param env Current session env vars.\n * @param lastExit Last command exit code (for `$?`).\n * @param home Home directory path (for `~`).\n */\nexport function expandSync(\n\tinput: string,\n\tenv: Record<string, string>,\n\tlastExit = 0,\n\thome?: string,\n): string {\n\tconst homePath = home ?? env.HOME ?? \"/home/user\";\n\n\treturn outsideSingleQuotes(input, (chunk) => {\n\t\tlet s = chunk;\n\n\t\t// Tilde expansion \u2014 only at start of token or after `:` or whitespace\n\t\ts = s.replace(\n\t\t\t/(^|[\\s:])~(\\/|$)/g,\n\t\t\t(_, pre, post) => `${pre}${homePath}${post}`,\n\t\t);\n\n\t\t// $? $$ $#\n\t\ts = s.replace(/\\$\\?/g, String(lastExit));\n\t\ts = s.replace(/\\$\\$/g, \"1\");\n\t\ts = s.replace(/\\$#/g, \"0\");\n\n\t\t// $(( arithmetic )) \u2014 must come before ${ and $VAR to avoid conflicts\n\t\ts = s.replace(/\\$\\(\\(([^)]+(?:\\([^)]*\\)[^)]*)*)\\)\\)/g, (_, expr) => {\n\t\t\tconst result = evalArith(expr, env);\n\t\t\treturn Number.isNaN(result) ? \"0\" : String(result);\n\t\t});\n\n\t\t// ${#VAR} \u2014 string length\n\t\ts = s.replace(/\\$\\{#([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_, name) =>\n\t\t\tString((env[name] ?? \"\").length),\n\t\t);\n\n\t\t// ${VAR:-default}\n\t\ts = s.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_]*):-([^}]*)\\}/g, (_, name, def) =>\n\t\t\tenv[name] !== undefined && env[name] !== \"\" ? (env[name] as string) : def,\n\t\t);\n\n\t\t// ${VAR:=default} \u2014 also assigns to env\n\t\ts = s.replace(\n\t\t\t/\\$\\{([A-Za-z_][A-Za-z0-9_]*):=([^}]*)\\}/g,\n\t\t\t(_, name, def) => {\n\t\t\t\tif (env[name] === undefined || env[name] === \"\") env[name] = def;\n\t\t\t\treturn env[name] as string;\n\t\t\t},\n\t\t);\n\n\t\t// ${VAR:+alternate}\n\t\ts = s.replace(\n\t\t\t/\\$\\{([A-Za-z_][A-Za-z0-9_]*):\\+([^}]*)\\}/g,\n\t\t\t(_, name, alt) =>\n\t\t\t\tenv[name] !== undefined && env[name] !== \"\" ? alt : \"\",\n\t\t);\n\n\t\t// ${VAR}\n\t\ts = s.replace(\n\t\t\t/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g,\n\t\t\t(_, name) => env[name] ?? \"\",\n\t\t);\n\n\t\t// $VAR\n\t\ts = s.replace(/\\$([A-Za-z_][A-Za-z0-9_]*)/g, (_, name) => env[name] ?? \"\");\n\n\t\treturn s;\n\t});\n}\n\n// \u2500\u2500\u2500 async expansion (includes $(cmd)) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Expand all shell forms including `$(cmd)` command substitution.\n *\n * Processes `$(...)` blocks depth-first, respecting single-quote boundaries.\n * Then delegates to `expandSync` for the remaining forms.\n *\n * @param input Raw string.\n * @param env Current session env vars.\n * @param lastExit Last exit code.\n * @param runCmd Async callback to execute a command and return its stdout.\n */\nexport async function expandAsync(\n\tinput: string,\n\tenv: Record<string, string>,\n\tlastExit: number,\n\trunCmd: (cmd: string) => Promise<string>,\n): Promise<string> {\n\t// $(cmd) substitution \u2014 skip content inside single quotes\n\tif (input.includes(\"$(\")) {\n\t\tlet result = \"\";\n\t\tlet inSingle = false;\n\t\tlet i = 0;\n\n\t\twhile (i < input.length) {\n\t\t\tconst ch = input[i]!;\n\n\t\t\tif (ch === \"'\" && !inSingle) {\n\t\t\t\tinSingle = true;\n\t\t\t\tresult += ch;\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === \"'\" && inSingle) {\n\t\t\t\tinSingle = false;\n\t\t\t\tresult += ch;\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!inSingle && ch === \"$\" && input[i + 1] === \"(\") {\n\t\t\t\t// $((expr)) arithmetic \u2014 NOT a $(cmd) substitution, skip it\n\t\t\t\tif (input[i + 2] === \"(\") {\n\t\t\t\t\tresult += ch;\n\t\t\t\t\ti++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// Find matching ) with depth tracking\n\t\t\t\tlet depth = 0;\n\t\t\t\tlet j = i + 1;\n\t\t\t\twhile (j < input.length) {\n\t\t\t\t\tif (input[j] === \"(\") depth++;\n\t\t\t\t\telse if (input[j] === \")\") {\n\t\t\t\t\t\tdepth--;\n\t\t\t\t\t\tif (depth === 0) break;\n\t\t\t\t\t}\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tconst sub = input.slice(i + 2, j).trim();\n\t\t\t\tconst out = (await runCmd(sub)).replace(/\\n$/, \"\");\n\t\t\t\tresult += out;\n\t\t\t\ti = j + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tresult += ch;\n\t\t\ti++;\n\t\t}\n\t\tinput = result;\n\t}\n\n\treturn expandSync(input, env, lastExit);\n}\n", "import type { ShellModule } from \"../types/commands\";\nimport { parseArgs } from \"./command-helpers\";\nimport { expandSync } from \"../utils/expand\";\n\n/**\n * Expand escape sequences for `echo -e`.\n * Handles \\n \\t \\r \\\\ \\a \\b \\f \\v and \\0NNN (octal).\n */\nfunction expandEscapes(text: string): string {\n\treturn text\n\t\t.replace(/\\\\n/g, \"\\n\")\n\t\t.replace(/\\\\t/g, \"\\t\")\n\t\t.replace(/\\\\r/g, \"\\r\")\n\t\t.replace(/\\\\\\\\/g, \"\\\\\")\n\t\t.replace(/\\\\a/g, \"\\x07\")\n\t\t.replace(/\\\\b/g, \"\\x08\")\n\t\t.replace(/\\\\f/g, \"\\x0C\")\n\t\t.replace(/\\\\v/g, \"\\x0B\")\n\t\t.replace(/\\\\0(\\d{1,3})/g, (_, oct) =>\n\t\t\tString.fromCharCode(parseInt(oct, 8)),\n\t\t);\n}\n\n/**\n * Echo text to stdout with shell-style expansion and escape support.\n * @category shell\n * @params [\"[-n] [-e] [text...]\"]\n */\nexport const echoCommand: ShellModule = {\n\tname: \"echo\",\n\tdescription: \"Display text\",\n\tcategory: \"shell\",\n\tparams: [\"[-n] [-e] [text...]\"],\n\trun: ({ args, stdin, env }) => {\n\t\tconst { flags, positionals } = parseArgs(args, {\n\t\t\tflags: [\"-n\", \"-e\", \"-E\"],\n\t\t});\n\t\tconst noNewline = flags.has(\"-n\");\n\t\tconst escapes = flags.has(\"-e\");\n\n\t\tconst rawText =\n\t\t\tpositionals.length > 0 ? positionals.join(\" \") : (stdin ?? \"\");\n\n\t\t// Full expansion: $? ${#VAR} $((expr)) ~ ${VAR:-def} $VAR etc.\n\t\t// $(cmd) is already resolved upstream by runCommand before echo.run is called.\n\t\tconst expanded = expandSync(\n\t\t\trawText,\n\t\t\tenv?.vars ?? {},\n\t\t\tenv?.lastExitCode ?? 0,\n\t\t);\n\t\tconst text = escapes ? expandEscapes(expanded) : expanded;\n\n\t\treturn {\n\t\t\tstdout: noNewline ? text : `${text}\\n`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "/** biome-ignore-all lint/style/useNamingConvention: ENV VARS */\nimport type { ShellModule } from \"../types/commands\";\n\n/**\n * Print environment variables for the current session.\n * @category shell\n * @params []\n */\nexport const envCommand: ShellModule = {\n\tname: \"env\",\n\tdescription: \"Print environment variables\",\n\tcategory: \"shell\",\n\tparams: [],\n\trun: ({ env, authUser }) => {\n\t\tconst vars = { ...env.vars, USER: authUser, HOME: `/home/${authUser}` };\n\t\treturn {\n\t\t\tstdout: Object.entries(vars)\n\t\t\t\t.map(([k, v]) => `${k}=${v}`)\n\t\t\t\t.join(\"\\n\"),\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Exit the current shell session (closeSession flag).\n * @category shell\n * @params [\"[code]\"]\n */\nexport const exitCommand: ShellModule = {\n\tname: \"exit\",\n\taliases: [\"bye\"],\n\tdescription: \"Exit the shell session\",\n\tcategory: \"shell\",\n\tparams: [\"[code]\"],\n\trun: ({ args }) => ({\n\t\tcloseSession: true,\n\t\texitCode: parseInt(args[0] ?? \"0\", 10) || 0,\n\t}),\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const exportCommand: ShellModule = {\n\tname: \"export\",\n\tdescription: \"Set shell environment variable\",\n\tcategory: \"shell\",\n\tparams: [\"[VAR=value]\"],\n\trun: ({ args, env }) => {\n\t\tif (args.length === 0) {\n\t\t\tconst out = Object.entries(env.vars)\n\t\t\t\t.map(([k, v]) => `declare -x ${k}=\"${v}\"`)\n\t\t\t\t.join(\"\\n\");\n\t\t\treturn { stdout: out, exitCode: 0 };\n\t\t}\n\t\tfor (const arg of args) {\n\t\t\tif (arg.includes(\"=\")) {\n\t\t\t\tconst eq = arg.indexOf(\"=\");\n\t\t\t\tconst name = arg.slice(0, eq);\n\t\t\t\tconst value = arg.slice(eq + 1);\n\t\t\t\tenv.vars[name] = value;\n\t\t\t} else {\n\t\t\t\t// mark existing as exported (already is)\n\t\t\t}\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Find files and directories by name and type with minimal pattern support.\n * @category files\n * @params [\"[path] [-name <pattern>] [-type f|d]\"]\n */\nexport const findCommand: ShellModule = {\n\tname: \"find\",\n\tdescription: \"Search for files\",\n\tcategory: \"files\",\n\tparams: [\"[path] [-name <pattern>] [-type f|d]\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst namePattern = getFlag(args, [\"-name\"]);\n\t\tconst typeFilter = getFlag(args, [\"-type\"]);\n\t\tconst positionals = args.filter(\n\t\t\t(a) => !a.startsWith(\"-\") && a !== namePattern && a !== typeFilter,\n\t\t);\n\t\tconst rootArg = positionals[0] ?? \".\";\n\t\tconst rootPath = resolvePath(cwd, rootArg);\n\n\t\ttry {\n\t\t\tassertPathAccess(authUser, rootPath, \"find\");\n\t\t\tif (!shell.vfs.exists(rootPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `find: ${rootArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `find: ${msg}`, exitCode: 1 };\n\t\t}\n\n\t\tconst nameRegex = namePattern\n\t\t\t? new RegExp(\n\t\t\t\t\t`^${(namePattern as string).replace(/\\./g, \"\\\\.\").replace(/\\*/g, \".*\").replace(/\\?/g, \".\")}$`,\n\t\t\t\t)\n\t\t\t: null;\n\n\t\tconst results: string[] = [];\n\t\tconst walk = (currentPath: string, display: string) => {\n\t\t\tconst stat = shell.vfs.stat(currentPath);\n\n\t\t\tconst matchesType =\n\t\t\t\t!typeFilter ||\n\t\t\t\t(typeFilter === \"f\" && stat.type === \"file\") ||\n\t\t\t\t(typeFilter === \"d\" && stat.type === \"directory\");\n\t\t\tconst matchesName =\n\t\t\t\t!nameRegex || nameRegex.test(currentPath.split(\"/\").pop() ?? \"\");\n\n\t\t\tif (matchesType && matchesName) results.push(display);\n\n\t\t\tif (stat.type === \"directory\") {\n\t\t\t\tfor (const entry of shell.vfs.list(currentPath)) {\n\t\t\t\t\tconst full = `${currentPath}/${entry}`;\n\t\t\t\t\tconst disp = `${display}/${entry}`;\n\t\t\t\t\twalk(full, disp);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\twalk(rootPath, rootArg);\n\t\treturn { stdout: results.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import * as os from \"node:os\";\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\n/**\n * Display memory usage information (human / MB / GB options).\n * @category system\n * @params [\"[-h] [-m] [-g]\"]\n */\nexport const freeCommand: ShellModule = {\n\tname: \"free\",\n\tdescription: \"Display amount of free and used memory\",\n\tcategory: \"system\",\n\tparams: [\"[-h] [-m] [-g]\"],\n\trun: ({ args }) => {\n\t\tconst human = ifFlag(args, [\"-h\", \"--human\"]);\n\t\tconst mb = ifFlag(args, [\"-m\"]);\n\t\tconst gb = ifFlag(args, [\"-g\"]);\n\n\t\tconst osTotalB = os.totalmem();\n\t\tconst osFreeB = os.freemem();\n\t\tconst usedB = osTotalB - osFreeB;\n\t\tconst sharedB = Math.floor(osTotalB * 0.02);\n\t\tconst buffersB = Math.floor(osTotalB * 0.05);\n\t\tconst availableB = Math.floor(osFreeB * 0.95);\n\t\tconst swapB = Math.floor(osTotalB * 0.5);\n\n\t\tconst fmt = (bytes: number): string => {\n\t\t\tif (human) {\n\t\t\t\tif (bytes >= 1024 * 1024 * 1024)\n\t\t\t\t\treturn `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}G`;\n\t\t\t\tif (bytes >= 1024 * 1024)\n\t\t\t\t\treturn `${(bytes / (1024 * 1024)).toFixed(1)}M`;\n\t\t\t\treturn `${(bytes / 1024).toFixed(1)}K`;\n\t\t\t}\n\t\t\tif (gb) return String(Math.floor(bytes / (1024 * 1024 * 1024)));\n\t\t\tif (mb) return String(Math.floor(bytes / (1024 * 1024)));\n\t\t\treturn String(Math.floor(bytes / 1024));\n\t\t};\n\n\t\tconst header = ` total used free shared buff/cache available`;\n\t\tconst memRow = `Mem: ${fmt(osTotalB).padStart(12)} ${fmt(usedB).padStart(11)} ${fmt(osFreeB).padStart(11)} ${fmt(sharedB).padStart(11)} ${fmt(buffersB).padStart(11)} ${fmt(availableB).padStart(11)}`;\n\t\tconst swapRow = `Swap: ${fmt(swapB).padStart(12)} ${fmt(0).padStart(11)} ${fmt(swapB).padStart(11)}`;\n\n\t\treturn { stdout: [header, memRow, swapRow].join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { parseArgs } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Search for a regex pattern in files or stdin with common flags.\n * @category text\n * @params [\"[-i] [-v] [-n] [-r] <pattern> [file...]\"]\n */\nexport const grepCommand: ShellModule = {\n\tname: \"grep\",\n\tdescription: \"Search text patterns\",\n\tcategory: \"text\",\n\tparams: [\"[-i] [-v] [-n] [-r] <pattern> [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst { flags, positionals } = parseArgs(args, {\n\t\t\tflags: [\"-i\", \"-v\", \"-n\", \"-r\"],\n\t\t});\n\t\tconst caseInsensitive = flags.has(\"-i\");\n\t\tconst invertMatch = flags.has(\"-v\");\n\t\tconst showLineNumbers = flags.has(\"-n\");\n\t\tconst recursive = flags.has(\"-r\");\n\t\tconst pattern = positionals[0];\n\t\tconst files = positionals.slice(1);\n\n\t\tif (!pattern) {\n\t\t\treturn { stderr: \"grep: no pattern specified\", exitCode: 1 };\n\t\t}\n\n\t\tlet regex: RegExp;\n\t\ttry {\n\t\t\t// No \"g\" flag \u2014 avoids the stateful lastIndex problem with regex.test()\n\t\t\tconst regexFlags = caseInsensitive ? \"mi\" : \"m\";\n\t\t\tregex = new RegExp(pattern, regexFlags);\n\t\t} catch {\n\t\t\treturn { stderr: `grep: invalid regex: ${pattern}`, exitCode: 1 };\n\t\t}\n\n\t\tconst matchLines = (content: string, prefix = \"\"): string[] => {\n\t\t\tconst lines = content.split(\"\\n\");\n\t\t\tconst out: string[] = [];\n\t\t\tfor (let i = 0; i < lines.length; i++) {\n\t\t\t\tconst line = lines[i] ?? \"\";\n\t\t\t\tconst matches = regex.test(line);\n\t\t\t\tconst shouldInclude = invertMatch ? !matches : matches;\n\t\t\t\tif (shouldInclude) {\n\t\t\t\t\tconst lineLabel = showLineNumbers ? `${i + 1}:` : \"\";\n\t\t\t\t\tout.push(`${prefix}${lineLabel}${line}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out;\n\t\t};\n\n\t\tconst readPaths = (base: string): string[] => {\n\t\t\tif (!shell.vfs.exists(base)) return [];\n\t\t\tconst stat = shell.vfs.stat(base);\n\t\t\tif (stat.type === \"file\") return [base];\n\t\t\tif (!recursive) return [];\n\t\t\tconst paths: string[] = [];\n\t\t\tconst walk = (dir: string) => {\n\t\t\t\tfor (const entry of shell.vfs.list(dir)) {\n\t\t\t\t\tconst full = `${dir}/${entry}`;\n\t\t\t\t\tconst s = shell.vfs.stat(full);\n\t\t\t\t\tif (s.type === \"file\") paths.push(full);\n\t\t\t\t\telse walk(full);\n\t\t\t\t}\n\t\t\t};\n\t\t\twalk(base);\n\t\t\treturn paths;\n\t\t};\n\n\t\tconst results: string[] = [];\n\n\t\tif (files.length === 0) {\n\t\t\tif (!stdin) return { stdout: \"\", exitCode: 1 };\n\t\t\tresults.push(...matchLines(stdin));\n\t\t} else {\n\t\t\tconst resolvedPaths = files.flatMap((f) => {\n\t\t\t\tconst target = resolvePath(cwd, f);\n\t\t\t\treturn readPaths(target).map((p) => ({ file: f, path: p }));\n\t\t\t});\n\n\t\t\tfor (const { file, path: filePath } of resolvedPaths) {\n\t\t\t\ttry {\n\t\t\t\t\tassertPathAccess(authUser, filePath, \"grep\");\n\t\t\t\t\tconst content = shell.vfs.readFile(filePath);\n\t\t\t\t\tconst prefix = resolvedPaths.length > 1 ? `${file}:` : \"\";\n\t\t\t\t\tresults.push(...matchLines(content, prefix));\n\t\t\t\t} catch {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `grep: ${file}: No such file or directory`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tstdout: results.length > 0 ? results.join(\"\\n\") : \"\",\n\t\t\texitCode: results.length > 0 ? 0 : 1,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const groupsCommand: ShellModule = {\n\tname: \"groups\",\n\tdescription: \"Print group memberships\",\n\tcategory: \"system\",\n\tparams: [\"[user]\"],\n\trun: ({ authUser, shell, args }) => {\n\t\tconst target = args[0] ?? authUser;\n\t\tconst isSudo = shell.users.isSudoer(target);\n\t\tconst grps = isSudo ? `${target} sudo root` : target;\n\t\treturn { stdout: grps, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { resolvePath } from \"./helpers\";\n\n/**\n * Compress files using gzip (stores in VFS as compressed content).\n * @category archive\n * @params [\"<file>\"]\n */\nexport const gzipCommand: ShellModule = {\n\tname: \"gzip\",\n\tdescription: \"Compress files\",\n\tcategory: \"archive\",\n\tparams: [\"<file>\"],\n\trun: ({ shell, cwd, args }) => {\n\t\tconst file = args[0];\n\t\tif (!file) return { stderr: \"gzip: no file specified\", exitCode: 1 };\n\t\tconst p = resolvePath(cwd, file);\n\t\ttry {\n\t\t\tshell.vfs.compressFile(p);\n\t\t\treturn { exitCode: 0 };\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstderr: `gzip: ${file}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t},\n};\n\nexport const gunzipCommand: ShellModule = {\n\t/**\n\t * Decompress gzip files (or zcat alias).\n\t * @category archive\n\t * @params [\"<file>\"]\n\t */\n\tname: \"gunzip\",\n\tdescription: \"Decompress files\",\n\tcategory: \"archive\",\n\tparams: [\"<file>\"],\n\taliases: [\"zcat\"],\n\trun: ({ shell, cwd, args }) => {\n\t\tconst file = args[0];\n\t\tif (!file) return { stderr: \"gunzip: no file specified\", exitCode: 1 };\n\t\tconst p = resolvePath(cwd, file);\n\t\ttry {\n\t\t\tshell.vfs.decompressFile(p);\n\t\t\treturn { exitCode: 0 };\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstderr: `gunzip: ${file}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Output the first part of files or stdin (head).\n * @category text\n * @params [\"[-n <lines>] [file...]\"]\n */\nexport const headCommand: ShellModule = {\n\tname: \"head\",\n\tdescription: \"Output first lines\",\n\tcategory: \"text\",\n\tparams: [\"[-n <lines>] [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst nArg = getFlag(args, [\"-n\"]);\n\t\tconst n = typeof nArg === \"string\" ? parseInt(nArg, 10) : 10;\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\") && a !== nArg);\n\n\t\tconst take = (content: string) =>\n\t\t\tcontent.split(\"\\n\").slice(0, n).join(\"\\n\");\n\n\t\tif (positionals.length === 0) {\n\t\t\treturn { stdout: take(stdin ?? \"\"), exitCode: 0 };\n\t\t}\n\n\t\tconst results: string[] = [];\n\t\tfor (const file of positionals) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\ttry {\n\t\t\t\tassertPathAccess(authUser, filePath, \"head\");\n\t\t\t\tresults.push(take(shell.vfs.readFile(filePath)));\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `head: ${file}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn { stdout: results.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getCommandModulesPublic } from \"./registry\";\n\n// \u2500\u2500\u2500 category config \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst CATEGORY_ORDER = [\n\t\"navigation\",\n\t\"files\",\n\t\"text\",\n\t\"archive\",\n\t\"system\",\n\t\"package\",\n\t\"network\",\n\t\"shell\",\n\t\"users\",\n\t\"misc\",\n];\n\nconst CATEGORY_LABELS: Record<string, string> = {\n\tnavigation: \"Navigation\",\n\tfiles: \"Files & Filesystem\",\n\ttext: \"Text Processing\",\n\tarchive: \"Archive & Compression\",\n\tsystem: \"System\",\n\tpackage: \"Package Management\",\n\tnetwork: \"Network\",\n\tshell: \"Shell & Scripting\",\n\tusers: \"Users & Permissions\",\n\tmisc: \"Miscellaneous\",\n};\n\n// \u2500\u2500\u2500 formatting helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst BOLD = \"\\x1b[1m\";\nconst RESET = \"\\x1b[0m\";\nconst CYAN = \"\\x1b[36m\";\nconst YLW = \"\\x1b[33m\";\nconst DIM = \"\\x1b[2m\";\nconst GREEN = \"\\x1b[32m\";\n\nfunction pad(s: string, n: number): string {\n\treturn s.length >= n ? s : s + \" \".repeat(n - s.length);\n}\n\nfunction formatCmdLine(mod: ShellModule): string {\n\tconst aliases = mod.aliases?.length\n\t\t? ` ${DIM}(${mod.aliases.join(\", \")})${RESET}`\n\t\t: \"\";\n\treturn ` ${CYAN}${pad(mod.name, 16)}${RESET}${aliases}${pad(\"\", mod.aliases?.length ? 0 : 0)} ${mod.description ?? \"\"}`;\n}\n\n// \u2500\u2500\u2500 full grouped listing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction renderFull(modules: ShellModule[]): string {\n\tconst grouped: Record<string, ShellModule[]> = {};\n\tfor (const mod of modules) {\n\t\tconst cat = mod.category ?? \"misc\";\n\t\tif (!grouped[cat]) grouped[cat] = [];\n\t\tgrouped[cat]!.push(mod);\n\t}\n\n\tconst lines: string[] = [\n\t\t`${BOLD}Available commands${RESET}`,\n\t\t`${DIM}Type 'help <command>' for detailed usage.${RESET}`,\n\t\t\"\",\n\t];\n\n\tconst cats = [\n\t\t...CATEGORY_ORDER.filter((c) => grouped[c]),\n\t\t...Object.keys(grouped)\n\t\t\t.filter((c) => !CATEGORY_ORDER.includes(c))\n\t\t\t.sort(),\n\t];\n\n\tfor (const cat of cats) {\n\t\tconst mods = grouped[cat];\n\t\tif (!mods?.length) continue;\n\n\t\tlines.push(`${YLW}${CATEGORY_LABELS[cat] ?? cat}${RESET}`);\n\t\tconst sorted = [...mods].sort((a, b) => a.name.localeCompare(b.name));\n\t\tfor (const mod of sorted) {\n\t\t\tlines.push(formatCmdLine(mod));\n\t\t}\n\t\tlines.push(\"\");\n\t}\n\n\tconst total = modules.length;\n\tlines.push(`${DIM}${total} commands available.${RESET}`);\n\n\treturn lines.join(\"\\n\");\n}\n\n// \u2500\u2500\u2500 single-command detail \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction renderDetail(mod: ShellModule): string {\n\tconst lines: string[] = [];\n\n\tlines.push(\n\t\t`${BOLD}${mod.name}${RESET} \u2014 ${mod.description ?? \"no description\"}`,\n\t);\n\n\tif (mod.aliases?.length) {\n\t\tlines.push(`${DIM}Aliases: ${mod.aliases.join(\", \")}${RESET}`);\n\t}\n\n\tlines.push(\"\");\n\tlines.push(`${GREEN}Usage:${RESET}`);\n\tif (mod.params.length) {\n\t\tfor (const p of mod.params) {\n\t\t\tlines.push(` ${mod.name} ${p}`);\n\t\t}\n\t} else {\n\t\tlines.push(` ${mod.name}`);\n\t}\n\n\tconst catLabel =\n\t\tCATEGORY_LABELS[mod.category ?? \"misc\"] ?? mod.category ?? \"misc\";\n\tlines.push(\"\");\n\tlines.push(`${DIM}Category: ${catLabel}${RESET}`);\n\n\treturn lines.join(\"\\n\");\n}\n\n// \u2500\u2500\u2500 export \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function createHelpCommand(_getNames: () => string[]): ShellModule {\n\treturn {\n\t\tname: \"help\",\n\t\tdescription: \"List all commands, or show usage for a specific command\",\n\t\tcategory: \"shell\",\n\t\tparams: [\"[command]\"],\n\t\trun: ({ args }) => {\n\t\t\tconst modules = getCommandModulesPublic();\n\n\t\t\tif (args[0]) {\n\t\t\t\tconst target = args[0].toLowerCase();\n\t\t\t\tconst mod = modules.find(\n\t\t\t\t\t(m) => m.name === target || m.aliases?.includes(target),\n\t\t\t\t);\n\t\t\t\tif (!mod) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `help: no help entry for '${args[0]}'`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn { stdout: renderDetail(mod), exitCode: 0 };\n\t\t\t}\n\n\t\t\treturn { stdout: renderFull(modules), exitCode: 0 };\n\t\t},\n\t};\n}\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Display persisted command history for the session (from VFS).\n * @category shell\n * @params [\"[n]\"]\n */\nexport const historyCommand: ShellModule = {\n\tname: \"history\",\n\tdescription: \"Display command history\",\n\tcategory: \"shell\",\n\tparams: [\"[n]\"],\n\trun: ({ args, shell }) => {\n\t\t// History is persisted in the VFS by the interactive shell\n\t\tconst histPath = \"/virtual-env-js/.bash_history\";\n\t\tif (!shell.vfs.exists(histPath)) {\n\t\t\treturn { stdout: \"\", exitCode: 0 };\n\t\t}\n\n\t\tconst raw = shell.vfs.readFile(histPath);\n\t\tconst lines = raw.split(\"\\n\").filter(Boolean);\n\n\t\tconst nArg = args[0];\n\t\tconst n = nArg ? parseInt(nArg, 10) : null;\n\t\tconst slice = n && !Number.isNaN(n) ? lines.slice(-n) : lines;\n\n\t\tconst offset = lines.length - slice.length + 1;\n\t\tconst numbered = slice.map(\n\t\t\t(line, i) => `${String(offset + i).padStart(5)} ${line}`,\n\t\t);\n\n\t\treturn { stdout: numbered.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Print the configured hostname for the virtual shell.\n * @category system\n * @params []\n */\nexport const hostnameCommand: ShellModule = {\n\tname: \"hostname\",\n\tdescription: \"Print hostname\",\n\tcategory: \"system\",\n\tparams: [],\n\trun: ({ hostname }) => ({ stdout: hostname, exitCode: 0 }),\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const htopCommand: ShellModule = {\n\tname: \"htop\",\n\tdescription: \"System monitor\",\n\tcategory: \"system\",\n\tparams: [],\n\trun: ({ mode }) => {\n\t\tif (mode === \"exec\") {\n\t\t\treturn { stderr: \"htop: interactive terminal required\", exitCode: 1 };\n\t\t}\n\n\t\treturn { openHtop: true, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const idCommand: ShellModule = {\n\tname: \"id\",\n\tdescription: \"Print user identity\",\n\tcategory: \"system\",\n\tparams: [\"[user]\"],\n\trun: ({ authUser, shell, args }) => {\n\t\tconst target = args[0] ?? authUser;\n\t\tconst uid = target === \"root\" ? 0 : 1000;\n\t\tconst gid = uid;\n\t\tconst isSudo = shell.users.isSudoer(target);\n\t\tconst groups = isSudo ? `${gid}(${target}),0(root)` : `${gid}(${target})`;\n\t\treturn {\n\t\t\tstdout: `uid=${uid}(${target}) gid=${gid}(${target}) groups=${groups}`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const killCommand: ShellModule = {\n\tname: \"kill\",\n\tdescription: \"Send signal to process\",\n\tcategory: \"system\",\n\tparams: [\"[-9] <pid>\"],\n\trun: ({ args }) => {\n\t\tconst pid = args.find((a) => !a.startsWith(\"-\"));\n\t\tif (!pid) return { stderr: \"kill: no pid specified\", exitCode: 1 };\n\t\t// In virtual env, we just acknowledge the kill\n\t\treturn { stdout: ``, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const lnCommand: ShellModule = {\n\tname: \"ln\",\n\tdescription: \"Create links\",\n\tcategory: \"files\",\n\tparams: [\"[-s] <target> <link_name>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst symbolic = ifFlag(args, [\"-s\", \"--symbolic\"]);\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst [targetArg, linkArg] = positionals;\n\n\t\tif (!targetArg || !linkArg) {\n\t\t\treturn { stderr: \"ln: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst linkPath = resolvePath(cwd, linkArg);\n\t\tconst targetPath = symbolic\n\t\t\t? targetArg // keep relative for symlinks\n\t\t\t: resolvePath(cwd, targetArg);\n\n\t\ttry {\n\t\t\tassertPathAccess(authUser, linkPath, \"ln\");\n\n\t\t\tif (!symbolic) {\n\t\t\t\t// Hard link \u2014 copy file contents\n\t\t\t\tconst srcPath = resolvePath(cwd, targetArg);\n\t\t\t\tassertPathAccess(authUser, srcPath, \"ln\");\n\t\t\t\tif (!shell.vfs.exists(srcPath)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `ln: ${targetArg}: No such file or directory`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst content = shell.vfs.readFile(srcPath);\n\t\t\t\tshell.writeFileAsUser(authUser, linkPath, content);\n\t\t\t} else {\n\t\t\t\tshell.vfs.symlink(targetPath, linkPath);\n\t\t\t}\n\n\t\t\treturn { exitCode: 0 };\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `ln: ${msg}`, exitCode: 1 };\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg, ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, joinListWithType, resolvePath } from \"./helpers\";\n\nfunction formatPermissions(mode: number, isDirectory: boolean): string {\n\tconst fileType = isDirectory ? \"d\" : \"-\";\n\tconst permissionBits = [\n\t\t[0o400, \"r\"],\n\t\t[0o200, \"w\"],\n\t\t[0o100, \"x\"],\n\t\t[0o040, \"r\"],\n\t\t[0o020, \"w\"],\n\t\t[0o010, \"x\"],\n\t\t[0o004, \"r\"],\n\t\t[0o002, \"w\"],\n\t\t[0o001, \"x\"],\n\t] as const;\n\tconst permissions = permissionBits\n\t\t.map(([bit, symbol]) => (mode & bit ? symbol : \"-\"))\n\t\t.join(\"\");\n\n\treturn `${fileType}${permissions}`;\n}\n\nfunction formatDate(date: Date): string {\n\treturn date.toISOString().replace(\"T\", \" \").slice(0, 16);\n}\n\nexport const lsCommand: ShellModule = {\n\tname: \"ls\",\n\tdescription: \"List directory contents\",\n\tcategory: \"navigation\",\n\tparams: [\"[-la] [path]\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst longFormat = ifFlag(args, [\"-l\", \"--long\"]);\n\t\tconst showHidden = ifFlag(args, [\"-a\", \"--all\"]);\n\t\tconst targetArg = getArg(args, 0, {\n\t\t\tflags: [\"-l\", \"--long\", \"-a\", \"--all\", \"-la\", \"-al\"],\n\t\t});\n\t\tconst target = resolvePath(cwd, targetArg ?? cwd);\n\t\tassertPathAccess(authUser, target, \"ls\");\n\t\tconst items = shell.vfs\n\t\t\t.list(target)\n\t\t\t.filter((name) => showHidden || !name.startsWith(\".\"));\n\t\tconst rendered = longFormat\n\t\t\t? items\n\t\t\t\t\t.map((name) => {\n\t\t\t\t\t\tconst childPath = resolvePath(target, name);\n\t\t\t\t\t\tconst stat = shell.vfs.stat(childPath);\n\t\t\t\t\t\tconst size = stat.type === \"file\" ? stat.size : stat.childrenCount;\n\t\t\t\t\t\treturn `${formatPermissions(stat.mode, stat.type === \"directory\")} 1 ${size} ${formatDate(stat.updatedAt)} ${name}${stat.type === \"directory\" ? \"/\" : \"\"}`;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t: joinListWithType(target, items, (p) => shell.vfs.stat(p));\n\t\treturn { stdout: rendered, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const lsbReleaseCommand: ShellModule = {\n\tname: \"lsb_release\",\n\tdescription: \"Print distribution-specific information\",\n\tcategory: \"system\",\n\tparams: [\"[-a] [-i] [-d] [-r] [-c]\"],\n\trun: ({ args, shell }) => {\n\t\tlet osName = shell.properties?.os ?? \"Fortune GNU/Linux x64\";\n\t\tlet codename = \"aurora\";\n\t\tlet version = \"1.0\";\n\n\t\ttry {\n\t\t\tconst content = shell.vfs.readFile(\"/etc/os-release\");\n\t\t\tfor (const line of content.split(\"\\n\")) {\n\t\t\t\tif (line.startsWith(\"PRETTY_NAME=\"))\n\t\t\t\t\tosName = line\n\t\t\t\t\t\t.slice(\"PRETTY_NAME=\".length)\n\t\t\t\t\t\t.replace(/^\"|\"$/g, \"\")\n\t\t\t\t\t\t.trim();\n\t\t\t\tif (line.startsWith(\"VERSION_CODENAME=\"))\n\t\t\t\t\tcodename = line.slice(\"VERSION_CODENAME=\".length).trim();\n\t\t\t\tif (line.startsWith(\"VERSION_ID=\"))\n\t\t\t\t\tversion = line\n\t\t\t\t\t\t.slice(\"VERSION_ID=\".length)\n\t\t\t\t\t\t.replace(/^\"|\"$/g, \"\")\n\t\t\t\t\t\t.trim();\n\t\t\t}\n\t\t} catch {}\n\n\t\tconst all = ifFlag(args, [\"-a\", \"--all\"]);\n\t\tconst showId = ifFlag(args, [\"-i\", \"--id\"]);\n\t\tconst showDesc = ifFlag(args, [\"-d\", \"--description\"]);\n\t\tconst showRelease = ifFlag(args, [\"-r\", \"--release\"]);\n\t\tconst showCodename = ifFlag(args, [\"-c\", \"--codename\"]);\n\n\t\tif (all || args.length === 0) {\n\t\t\treturn {\n\t\t\t\tstdout: [\n\t\t\t\t\t`Distributor ID:\\tFortune`,\n\t\t\t\t\t`Description:\\t${osName}`,\n\t\t\t\t\t`Release:\\t${version}`,\n\t\t\t\t\t`Codename:\\t${codename}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst lines: string[] = [];\n\t\tif (showId) lines.push(`Distributor ID:\\tFortune`);\n\t\tif (showDesc) lines.push(`Description:\\t${osName}`);\n\t\tif (showRelease) lines.push(`Release:\\t${version}`);\n\t\tif (showCodename) lines.push(`Codename:\\t${codename}`);\n\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nconst MAN_PAGES: Record<string, string> = {\n\tls: `LS(1) User Commands LS(1)\n\nNAME\n ls - list directory contents\n\nSYNOPSIS\n ls [OPTION]... [FILE]...\n\nDESCRIPTION\n List information about the FILEs (the current directory by default).\n\nOPTIONS\n -l use a long listing format\n -a do not ignore entries starting with .\n -h with -l, print human readable sizes\n -r reverse order while sorting\n -t sort by modification time\n\nAUTHOR\n Written by Richard M. Stallman and David MacKenzie.`,\n\n\tcat: `CAT(1) User Commands CAT(1)\n\nNAME\n cat - concatenate files and print on the standard output\n\nSYNOPSIS\n cat [OPTION]... [FILE]...\n\nDESCRIPTION\n Concatenate FILE(s) to standard output.\n\nOPTIONS\n -n, --number number all output lines\n -b, --number-nonblank number nonempty output lines`,\n\n\tgrep: `GREP(1) User Commands GREP(1)\n\nNAME\n grep, egrep, fgrep - print lines that match patterns\n\nSYNOPSIS\n grep [OPTION]... PATTERNS [FILE]...\n\nOPTIONS\n -i, --ignore-case ignore case distinctions in patterns and data\n -v, --invert-match select non-matching lines\n -n, --line-number print line number with output lines\n -r, --recursive read all files under each directory, recursively`,\n\n\tapt: `APT(8) APT APT(8)\n\nNAME\n apt - command-line interface\n\nSYNOPSIS\n apt [options] command\n\nDESCRIPTION\n apt provides a high-level commandline interface for the package\n management system.\n\nCOMMANDS\n install pkg... Install packages\n remove pkg... Remove packages\n update Download package information\n upgrade Upgrade installed packages\n search term Search in package descriptions\n show pkg Show package information\n list List packages`,\n\n\tssh: `SSH(1) OpenSSH SSH(1)\n\nNAME\n ssh - OpenSSH remote login client\n\nSYNOPSIS\n ssh [-p port] [user@]hostname [command]\n\nDESCRIPTION\n ssh (SSH client) is a program for logging into a remote machine and\n for executing commands on a remote machine.`,\n\n\tcurl: `CURL(1) User Commands CURL(1)\n\nNAME\n curl - transfer a URL\n\nSYNOPSIS\n curl [options / URLs]\n\nDESCRIPTION\n curl is a tool for transferring data with URL syntax.\n\nOPTIONS\n -o, --output <file> Write output to <file>\n -X, --request <method> Specify request method\n -d, --data <data> HTTP POST data\n -H, --header <header> Pass custom header\n -s, --silent Silent mode\n -I, --head Show document info only\n -L, --location Follow redirects\n -v, --verbose Make the operation more talkative`,\n\n\tchmod: `CHMOD(1) User Commands CHMOD(1)\n\nNAME\n chmod - change file mode bits\n\nSYNOPSIS\n chmod [OPTION]... MODE[,MODE]... FILE...\n chmod [OPTION]... OCTAL-MODE FILE...\n\nDESCRIPTION\n Change the file mode bits of each given file according to MODE.\n\nEXAMPLES\n chmod 755 script.sh rwxr-xr-x\n chmod 644 file.txt rw-r--r--\n chmod +x script.sh add execute permission`,\n\n\ttar: `TAR(1) GNU tar Manual TAR(1)\n\nNAME\n tar - an archiving utility\n\nSYNOPSIS\n tar [OPTION...] [FILE]...\n\nDESCRIPTION\n tar saves many files together into a single tape or disk archive,\n and can restore individual files from the archive.\n\nOPTIONS\n -c, --create create a new archive\n -x, --extract extract files from an archive\n -z, --gzip filter the archive through gzip\n -f, --file=ARCHIVE use archive file or device ARCHIVE\n -v, --verbose verbosely list files processed\n -t, --list list the contents of an archive`,\n};\n\nexport const manCommand: ShellModule = {\n\tname: \"man\",\n\tdescription: \"Interface to the system reference manuals\",\n\tcategory: \"shell\",\n\tparams: [\"<command>\"],\n\trun: ({ args, shell }) => {\n\t\tconst name = args[0];\n\t\tif (!name) return { stderr: \"What manual page do you want?\", exitCode: 1 };\n\n\t\t// VFS-installed man pages take priority\n\t\tconst manPath = `/usr/share/man/man1/${name}.1`;\n\t\tif (shell.vfs.exists(manPath)) {\n\t\t\treturn { stdout: shell.vfs.readFile(manPath), exitCode: 0 };\n\t\t}\n\n\t\tconst page = MAN_PAGES[name.toLowerCase()];\n\t\tif (page) return { stdout: page, exitCode: 0 };\n\n\t\treturn { stderr: `No manual entry for ${name}`, exitCode: 16 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const mkdirCommand: ShellModule = {\n\tname: \"mkdir\",\n\tdescription: \"Make directories\",\n\tcategory: \"files\",\n\tparams: [\"<dir>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tif (args.length === 0) {\n\t\t\treturn { stderr: \"mkdir: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tfor (let index = 0; index < args.length; index++) {\n\t\t\tconst dir = getArg(args, index);\n\t\t\tif (!dir) {\n\t\t\t\treturn { stderr: \"mkdir: missing operand\", exitCode: 1 };\n\t\t\t}\n\t\t\tconst target = resolvePath(cwd, dir);\n\t\t\tassertPathAccess(authUser, target, \"mkdir\");\n\t\t\tshell.vfs.mkdir(target);\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const mvCommand: ShellModule = {\n\tname: \"mv\",\n\tdescription: \"Move or rename files\",\n\tcategory: \"files\",\n\tparams: [\"<source> <dest>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst [srcArg, destArg] = positionals;\n\n\t\tif (!srcArg || !destArg) {\n\t\t\treturn { stderr: \"mv: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst srcPath = resolvePath(cwd, srcArg);\n\t\tconst destPath = resolvePath(cwd, destArg);\n\n\t\ttry {\n\t\t\tassertPathAccess(authUser, srcPath, \"mv\");\n\t\t\tassertPathAccess(authUser, destPath, \"mv\");\n\n\t\t\tif (!shell.vfs.exists(srcPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `mv: ${srcArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// If dest is a directory, move into it\n\t\t\tconst finalDest =\n\t\t\t\tshell.vfs.exists(destPath) &&\n\t\t\t\tshell.vfs.stat(destPath).type === \"directory\"\n\t\t\t\t\t? `${destPath}/${srcArg.split(\"/\").pop()}`\n\t\t\t\t\t: destPath;\n\n\t\t\tshell.vfs.move(srcPath, finalDest);\n\t\t\treturn { exitCode: 0 };\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `mv: ${msg}`, exitCode: 1 };\n\t\t}\n\t},\n};\n", "import * as path from \"node:path\";\nimport type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const nanoCommand: ShellModule = {\n\tname: \"nano\",\n\tdescription: \"Text editor\",\n\tcategory: \"files\",\n\tparams: [\"<file>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst fileArg = args[0];\n\t\tif (!fileArg) {\n\t\t\treturn { stderr: \"nano: missing file operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst targetPath = resolvePath(cwd, fileArg);\n\t\tassertPathAccess(authUser, targetPath, \"nano\");\n\t\tconst initialContent = shell.vfs.exists(targetPath)\n\t\t\t? shell.vfs.readFile(targetPath)\n\t\t\t: \"\";\n\t\tconst safeName = path.posix.basename(targetPath) || \"buffer\";\n\t\tconst tempPath = `/tmp/sshmimic-nano-${Date.now()}-${safeName}.tmp`;\n\n\t\treturn {\n\t\t\topenEditor: {\n\t\t\t\ttargetPath,\n\t\t\t\ttempPath,\n\t\t\t\tinitialContent,\n\t\t\t},\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { ShellProperties } from \"../VirtualShell\";\n\nfunction formatUptime(seconds: number): string {\n\tconst totalMinutes = Math.max(1, Math.floor(seconds / 60));\n\tconst days = Math.floor(totalMinutes / (24 * 60));\n\tconst hours = Math.floor((totalMinutes % (24 * 60)) / 60);\n\tconst minutes = totalMinutes % 60;\n\n\tconst parts: string[] = [];\n\tif (days > 0) {\n\t\tparts.push(`${days} day${days > 1 ? \"s\" : \"\"}`);\n\t}\n\tif (hours > 0) {\n\t\tparts.push(`${hours} hour${hours > 1 ? \"s\" : \"\"}`);\n\t}\n\tif (minutes > 0 || parts.length === 0) {\n\t\tparts.push(`${minutes} min${minutes > 1 ? \"s\" : \"\"}`);\n\t}\n\n\treturn parts.join(\", \");\n}\n\nfunction colorBlock(code: number): string {\n\treturn `\\u001b[${code}m \\u001b[0m`;\n}\n\nfunction buildColorBars(): string[] {\n\tconst normal = [40, 41, 42, 43, 44, 45, 46, 47].map(colorBlock).join(\"\");\n\tconst bright = [100, 101, 102, 103, 104, 105, 106, 107]\n\t\t.map(colorBlock)\n\t\t.join(\"\");\n\treturn [normal, bright];\n}\n\nfunction colorizeLogoLine(line: string, index: number, total: number): string {\n\tif (line.trim().length === 0) {\n\t\treturn line;\n\t}\n\n\tconst start = { r: 255, g: 255, b: 255 };\n\tconst end = { r: 168, g: 85, b: 247 };\n\tconst ratio = total <= 1 ? 0 : index / (total - 1);\n\n\tconst r = Math.round(start.r + (end.r - start.r) * ratio);\n\tconst g = Math.round(start.g + (end.g - start.g) * ratio);\n\tconst b = Math.round(start.b + (end.b - start.b) * ratio);\n\n\treturn `\\u001b[38;2;${r};${g};${b}m${line}\\u001b[0m`;\n}\n\nfunction colorizeDetailLine(line: string): string {\n\tif (line.trim().length === 0) {\n\t\treturn line;\n\t}\n\n\tconst colonIndex = line.indexOf(\":\");\n\n\tif (colonIndex === -1) {\n\t\t// Pas de ':', chercher '@' pour identifier user@host\n\t\tif (line.includes(\"@\")) {\n\t\t\t// C'est user@host, appliquer d\u00E9grad\u00E9 horizontal\n\t\t\treturn applyHorizontalGradient(line);\n\t\t}\n\t\t// Sinon c'est un separator ou autre, laisser tel quel\n\t\treturn line;\n\t}\n\n\t// Il y a un ':', c'est titre: valeur\n\tconst title = line.substring(0, colonIndex + 1);\n\tconst value = line.substring(colonIndex + 1);\n\n\t// Appliquer le d\u00E9grad\u00E9 seulement au titre\n\tconst colorized = applyHorizontalGradient(title);\n\treturn colorized + value;\n}\n\nfunction applyHorizontalGradient(text: string): string {\n\t// Nettoyer les codes ANSI existants\n\tconst ansiRegex = new RegExp(`${String.fromCharCode(27)}\\\\[[\\\\d;]*m`, \"g\");\n\tconst cleaned = text.replace(ansiRegex, \"\");\n\n\tif (cleaned.trim().length === 0) {\n\t\treturn text;\n\t}\n\n\tconst start = { r: 255, g: 255, b: 255 };\n\tconst end = { r: 168, g: 85, b: 247 };\n\tlet result = \"\";\n\n\tfor (let i = 0; i < cleaned.length; i += 1) {\n\t\tconst ratio = cleaned.length <= 1 ? 0 : i / (cleaned.length - 1);\n\n\t\tconst r = Math.round(start.r + (end.r - start.r) * ratio);\n\t\tconst g = Math.round(start.g + (end.g - start.g) * ratio);\n\t\tconst b = Math.round(start.b + (end.b - start.b) * ratio);\n\n\t\tresult += `\\u001b[38;2;${r};${g};${b}m${cleaned[i]}\\u001b[0m`;\n\t}\n\n\treturn result;\n}\n\nexport interface NeofetchInfo {\n\tuser: string;\n\thost: string;\n\tosName?: string;\n\tkernel?: string;\n\tuptimeSeconds?: number;\n\tpackages?: string;\n\tshell?: string;\n\tshellProps?: ShellProperties;\n\tresolution?: string;\n\tterminal?: string;\n\tcpu?: string;\n\tgpu?: string;\n\tmemoryUsedMiB?: number;\n\tmemoryTotalMiB?: number;\n}\n\nfunction toMiB(bytes: number): number {\n\treturn Math.max(0, Math.round(bytes / (1024 * 1024)));\n}\n\nfunction readOsPrettyName(): string | undefined {\n\ttry {\n\t\tconst data = readFileSync(\"/etc/os-release\", \"utf8\");\n\t\tfor (const line of data.split(\"\\n\")) {\n\t\t\tif (!line.startsWith(\"PRETTY_NAME=\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst value = line.slice(\"PRETTY_NAME=\".length).trim();\n\t\t\treturn value.replace(/^\"|\"$/g, \"\");\n\t\t}\n\t} catch {\n\t\treturn undefined;\n\t}\n\n\treturn undefined;\n}\n\nfunction readFirstLine(filePath: string): string | undefined {\n\ttry {\n\t\tconst data = readFileSync(filePath, \"utf8\").split(\"\\n\")[0]?.trim();\n\t\tif (!data || data.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn data;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction resolveHostLabel(fallback: string): string {\n\tconst vendor = readFirstLine(\"/sys/devices/virtual/dmi/id/sys_vendor\");\n\tconst product = readFirstLine(\"/sys/devices/virtual/dmi/id/product_name\");\n\n\tif (vendor && product) {\n\t\treturn `${vendor} ${product}`;\n\t}\n\tif (product) {\n\t\treturn product;\n\t}\n\n\treturn fallback;\n}\n\nfunction countDpkgPackages(): number | undefined {\n\tconst candidates = [\"/var/lib/dpkg/status\", \"/usr/local/var/lib/dpkg/status\"];\n\n\tfor (const filePath of candidates) {\n\t\tif (!existsSync(filePath)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\tconst data = readFileSync(filePath, \"utf8\");\n\t\t\tconst matches = data.match(/^Package:\\s+/gm);\n\t\t\treturn matches?.length ?? 0;\n\t\t} catch {}\n\t}\n\n\treturn undefined;\n}\n\nfunction countSnapPackages(): number | undefined {\n\tconst candidates = [\"/snap\", \"/var/lib/snapd/snaps\"];\n\n\tfor (const dirPath of candidates) {\n\t\tif (!existsSync(dirPath)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\tconst entries = readdirSync(dirPath, { withFileTypes: true });\n\t\t\tconst count = entries.filter((entry) => entry.isDirectory()).length;\n\t\t\treturn count;\n\t\t} catch {}\n\t}\n\n\treturn undefined;\n}\n\nfunction resolvePackagesLabel(): string {\n\tconst dpkgCount = countDpkgPackages();\n\tconst snapCount = countSnapPackages();\n\n\tif (dpkgCount !== undefined && snapCount !== undefined) {\n\t\treturn `${dpkgCount} (dpkg), ${snapCount} (snap)`;\n\t}\n\tif (dpkgCount !== undefined) {\n\t\treturn `${dpkgCount} (dpkg)`;\n\t}\n\tif (snapCount !== undefined) {\n\t\treturn `${snapCount} (snap)`;\n\t}\n\n\treturn \"n/a\";\n}\n\nfunction resolveCpuLabel(): string {\n\tconst cpus = os.cpus();\n\tif (cpus.length === 0) {\n\t\treturn \"unknown\";\n\t}\n\n\tconst first = cpus[0];\n\tif (!first) {\n\t\treturn \"unknown\";\n\t}\n\n\tconst ghz = (first.speed / 1000).toFixed(2);\n\treturn `${first.model} (${cpus.length}) @ ${ghz}GHz`;\n}\n\nfunction resolveShellLabel(shell?: string): string {\n\tif (!shell || shell.trim().length === 0) {\n\t\treturn \"unknown\";\n\t}\n\n\treturn path.posix.basename(shell.trim());\n}\n\nfunction resolveDefaults(info: NeofetchInfo): Required<NeofetchInfo> {\n\tconst totalMem = os.totalmem();\n\tconst freeMem = os.freemem();\n\tconst usedMem = Math.max(0, totalMem - freeMem);\n\tconst shellProps = info.shellProps;\n\n\tconst processUptime = process.uptime();\n\tif (info.uptimeSeconds === undefined) {\n\t\tinfo.uptimeSeconds = Math.round(processUptime);\n\t}\n\n\treturn {\n\t\tuser: info.user,\n\t\thost: info.host,\n\t\tosName:\n\t\t\tshellProps?.os ??\n\t\t\tinfo.osName ??\n\t\t\t`${readOsPrettyName() ?? os.type()} ${os.arch()}`,\n\t\tkernel: shellProps?.kernel ?? info.kernel ?? os.release(),\n\t\tuptimeSeconds: info.uptimeSeconds ?? os.uptime(),\n\t\tpackages: info.packages ?? resolvePackagesLabel(),\n\t\tshell: resolveShellLabel(info.shell),\n\t\tshellProps: (info.shellProps as ShellProperties) ?? {\n\t\t\tkernel: info.kernel ?? os.release(),\n\t\t\tos: info.osName ?? `${readOsPrettyName() ?? os.type()} ${os.arch()}`,\n\t\t\tarch: os.arch(),\n\t\t},\n\t\tresolution: info.resolution ?? \"n/a (ssh)\",\n\t\tterminal: info.terminal ?? \"unknown\",\n\t\tcpu: info.cpu ?? resolveCpuLabel(),\n\t\tgpu: info.gpu ?? \"n/a\",\n\t\tmemoryUsedMiB: info.memoryUsedMiB ?? toMiB(usedMem),\n\t\tmemoryTotalMiB: info.memoryTotalMiB ?? toMiB(totalMem),\n\t};\n}\n\nexport function buildNeofetchOutput(info: NeofetchInfo): string {\n\tconst fields = resolveDefaults(info);\n\tconst uptime = formatUptime(fields.uptimeSeconds);\n\tconst colorBars = buildColorBars();\n\n\tconst distroLogo = [\n\t\t\" .. .:. \",\n\t\t\" .::.. .. .. \",\n\t\t\". .... ... .. \",\n\t\t\": .... .:. .. \",\n\t\t\": .:.:........:. .. \",\n\t\t\": .. \",\n\t\t\". : \",\n\t\t\". : \",\n\t\t\".. : \",\n\t\t\" :. .. \",\n\t\t\" .. .. \",\n\t\t\" :-. :: \",\n\t\t\" .:. :. \",\n\t\t\" ..: ... \",\n\t\t\" ..: :.. \",\n\t\t\" :... :....\",\n\t\t\" .. ....\",\n\t\t\" . .. \",\n\t\t\" .:. .: \",\n\t\t\" :. .. \",\n\t\t\" ::. .. \",\n\t\t\"..... ..:... \",\n\t\t\"...:. .. \",\n\t\t\".:...:. ::. .. \",\n\t\t\" ... ..:::::.. ..:::::::.. \",\n\t];\n\n\tconst details = [\n\t\t`${fields.user}@${fields.host}`,\n\t\t\"-------------------------\",\n\t\t`OS: ${fields.osName}`,\n\t\t`Host: ${resolveHostLabel(fields.host)}`,\n\t\t`Kernel: ${fields.kernel}`,\n\t\t`Uptime: ${uptime}`,\n\t\t// `Packages: ${fields.packages}`,\n\t\t`Packages: ${fields.packages}`,\n\t\t`Shell: ${fields.shell}`,\n\t\t// `Shell Props: ${fields.shellProps}`,\n\t\t`Resolution: ${fields.resolution}`,\n\t\t`Terminal: ${fields.terminal}`,\n\t\t`CPU: ${fields.cpu}`,\n\t\t`GPU: ${fields.gpu}`,\n\t\t`Memory: ${fields.memoryUsedMiB}MiB / ${fields.memoryTotalMiB}MiB`,\n\t\t\"\",\n\t\tcolorBars[0],\n\t\tcolorBars[1],\n\t];\n\n\tconst width = Math.max(distroLogo.length, details.length);\n\tconst lines: string[] = [];\n\n\tfor (let i = 0; i < width; i += 1) {\n\t\tconst rawLeft = distroLogo[i] ?? \"\";\n\t\tconst right = details[i] ?? \"\";\n\t\tif (right.length > 0) {\n\t\t\tconst left = colorizeLogoLine(\n\t\t\t\trawLeft.padEnd(31, \" \"),\n\t\t\t\ti,\n\t\t\t\tdistroLogo.length,\n\t\t\t);\n\t\t\tconst coloredRight = colorizeDetailLine(right);\n\t\t\tlines.push(`${left} ${coloredRight}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tlines.push(colorizeLogoLine(rawLeft, i, distroLogo.length));\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n", "/** biome-ignore-all lint/style/useNamingConvention: env variables */\nimport type { ShellModule } from \"../types/commands\";\n\n// Legacy global store kept for compatibility with older callers\nconst _globalEnv: Record<string, string> = {\n\tPATH: \"/usr/local/bin:/usr/bin:/bin\",\n\tHOME: \"/home/user\",\n\tSHELL: \"/bin/sh\",\n\tTERM: \"xterm-256color\",\n\tUSER: \"user\",\n};\n\n/** @deprecated use env.vars from CommandContext */\nexport function getEnvVar(name: string): string | undefined {\n\treturn _globalEnv[name];\n}\n/** @deprecated use env.vars from CommandContext */\nexport function setEnvVar(name: string, value: string): void {\n\t_globalEnv[name] = value;\n}\n/** @deprecated use env.vars from CommandContext */\nexport function getAllEnvVars(authUser: string): Record<string, string> {\n\t_globalEnv.USER = authUser;\n\t_globalEnv.HOME = `/home/${authUser}`;\n\treturn { ..._globalEnv };\n}\n\nexport const setCommand: ShellModule = {\n\tname: \"set\",\n\tdescription: \"Display or set shell variables\",\n\tcategory: \"shell\",\n\tparams: [\"[VAR=value]\"],\n\trun: ({ args, env }) => {\n\t\tif (args.length === 0) {\n\t\t\tconst out = Object.entries(env.vars)\n\t\t\t\t.map(([k, v]) => `${k}=${v}`)\n\t\t\t\t.join(\"\\n\");\n\t\t\treturn { stdout: out, exitCode: 0 };\n\t\t}\n\t\tfor (const arg of args) {\n\t\t\tif (arg.includes(\"=\")) {\n\t\t\t\tconst eq = arg.indexOf(\"=\");\n\t\t\t\tenv.vars[arg.slice(0, eq)] = arg.slice(eq + 1);\n\t\t\t}\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import { buildNeofetchOutput } from \"../modules/neofetch\";\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { getAllEnvVars } from \"./set\";\n\nexport const neofetchCommand: ShellModule = {\n\tname: \"neofetch\",\n\tdescription: \"System info display\",\n\tcategory: \"system\",\n\tparams: [\"[--off]\"],\n\trun: ({ args, authUser, hostname, shell }) => {\n\t\tconst env = getAllEnvVars(authUser);\n\n\t\tif (ifFlag(args, \"--help\")) {\n\t\t\treturn {\n\t\t\t\tstdout: \"Usage: neofetch [--off]\",\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tif (ifFlag(args, \"--off\")) {\n\t\t\treturn {\n\t\t\t\tstdout: `${authUser}@${hostname}`,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstdout: buildNeofetchOutput({\n\t\t\t\tuser: authUser,\n\t\t\t\thost: hostname,\n\t\t\t\tshell: env.SHELL,\n\t\t\t\tshellProps: shell.properties,\n\t\t\t\tterminal: env.TERM,\n\t\t\t\tuptimeSeconds: Math.floor((Date.now() - shell.startTime) / 1000),\n\t\t\t\tpackages: (() => {\n\t\t\t\t\tconst count = shell.packageManager?.installedCount() ?? 0;\n\t\t\t\t\treturn `${count} (dpkg)`;\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "/** biome-ignore-all lint/style/useNamingConvention: node globals and ENV VAR KEYS */\n/**\n * node.ts \u2014 Virtual Node.js runtime.\n *\n * Uses `node:vm` for sandboxed evaluation with a controlled context that\n * intercepts `process`, `require`, `console`, and all standard globals.\n * No host filesystem access, no network, no child processes.\n */\nimport vm from \"node:vm\";\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nconst VIRTUAL_VERSION = \"v18.19.0\";\nconst VIRTUAL_VERSIONS = {\n\tnode: VIRTUAL_VERSION,\n\tnpm: \"9.2.0\",\n\tv8: \"10.2.154.26-node.22\",\n};\n\n// \u2500\u2500\u2500 sandbox context \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction makeContext(outputLines: string[], stderrLines: string[]) {\n\tconst fakeProcess = {\n\t\tversion: VIRTUAL_VERSION,\n\t\tversions: VIRTUAL_VERSIONS,\n\t\tplatform: \"linux\",\n\t\tarch: \"x64\",\n\t\tenv: {\n\t\t\tNODE_ENV: \"production\",\n\t\t\tHOME: \"/root\",\n\t\t\tPATH: \"/usr/local/bin:/usr/bin:/bin\",\n\t\t},\n\t\targv: [\"node\"],\n\t\tstdout: {\n\t\t\twrite: (s: string) => {\n\t\t\t\toutputLines.push(s);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t},\n\t\tstderr: {\n\t\t\twrite: (s: string) => {\n\t\t\t\tstderrLines.push(s);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t},\n\t\texit: (code = 0) => {\n\t\t\tthrow new ExitSignal(code);\n\t\t},\n\t\tcwd: () => \"/root\",\n\t\thrtime: () => [0, 0],\n\t};\n\n\tconst fakeConsole = {\n\t\tlog: (...a: unknown[]) => outputLines.push(a.map(formatValue).join(\" \")),\n\t\terror: (...a: unknown[]) => stderrLines.push(a.map(formatValue).join(\" \")),\n\t\twarn: (...a: unknown[]) => stderrLines.push(a.map(formatValue).join(\" \")),\n\t\tinfo: (...a: unknown[]) => outputLines.push(a.map(formatValue).join(\" \")),\n\t\tdir: (v: unknown) => outputLines.push(formatValue(v)),\n\t};\n\n\tconst fakeRequire = (mod: string): unknown => {\n\t\t// Provide stubs for common modules\n\t\tswitch (mod) {\n\t\t\tcase \"path\":\n\t\t\t\treturn {\n\t\t\t\t\tjoin: (...parts: string[]) => parts.join(\"/\").replace(/\\/+/g, \"/\"),\n\t\t\t\t\tresolve: (...parts: string[]) =>\n\t\t\t\t\t\t`/${parts.join(\"/\").replace(/^\\/+/, \"\")}`,\n\t\t\t\t\tdirname: (p: string) => p.split(\"/\").slice(0, -1).join(\"/\") || \"/\",\n\t\t\t\t\tbasename: (p: string) => p.split(\"/\").pop() ?? \"\",\n\t\t\t\t\textname: (p: string) => {\n\t\t\t\t\t\tconst b = p.split(\"/\").pop() ?? \"\";\n\t\t\t\t\t\tconst d = b.lastIndexOf(\".\");\n\t\t\t\t\t\treturn d > 0 ? b.slice(d) : \"\";\n\t\t\t\t\t},\n\t\t\t\t\tsep: \"/\",\n\t\t\t\t\tdelimiter: \":\",\n\t\t\t\t};\n\t\t\tcase \"os\":\n\t\t\t\treturn {\n\t\t\t\t\tplatform: () => \"linux\",\n\t\t\t\t\tarch: () => \"x64\",\n\t\t\t\t\ttype: () => \"Linux\",\n\t\t\t\t\thostname: () => \"fortune-vm\",\n\t\t\t\t\thomedir: () => \"/root\",\n\t\t\t\t\ttmpdir: () => \"/tmp\",\n\t\t\t\t\tEOL: \"\\n\",\n\t\t\t\t};\n\t\t\tcase \"util\":\n\t\t\t\treturn {\n\t\t\t\t\tformat: (...a: unknown[]) => a.map(formatValue).join(\" \"),\n\t\t\t\t\tinspect: (v: unknown) => formatValue(v),\n\t\t\t\t};\n\t\t\tcase \"fs\":\n\t\t\tcase \"fs/promises\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot require '${mod}': filesystem access not available in virtual runtime`,\n\t\t\t\t);\n\t\t\tcase \"child_process\":\n\t\t\tcase \"net\":\n\t\t\tcase \"http\":\n\t\t\tcase \"https\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot require '${mod}': not available in virtual runtime`,\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Cannot find module '${mod}'`);\n\t\t}\n\t};\n\tfakeRequire.resolve = (id: string) => {\n\t\tthrow new Error(`Cannot resolve '${id}'`);\n\t};\n\tfakeRequire.cache = {};\n\tfakeRequire.extensions = {};\n\n\treturn vm.createContext({\n\t\t// Core globals\n\t\tconsole: fakeConsole,\n\t\tprocess: fakeProcess,\n\t\trequire: fakeRequire,\n\n\t\t// JS built-ins\n\t\tMath,\n\t\tJSON,\n\t\tObject,\n\t\tArray,\n\t\tString,\n\t\tNumber,\n\t\tBoolean,\n\t\tSymbol,\n\t\tDate,\n\t\tRegExp,\n\t\tError,\n\t\tTypeError,\n\t\tRangeError,\n\t\tSyntaxError,\n\t\tPromise,\n\t\tMap,\n\t\tSet,\n\t\tWeakMap,\n\t\tWeakSet,\n\t\tparseInt,\n\t\tparseFloat,\n\t\tisNaN,\n\t\tisFinite,\n\t\tencodeURIComponent,\n\t\tdecodeURIComponent,\n\t\tencodeURI,\n\t\tdecodeURI,\n\t\tsetTimeout: () => {},\n\t\tclearTimeout: () => {},\n\t\tsetInterval: () => {},\n\t\tclearInterval: () => {},\n\t\tqueueMicrotask: () => {},\n\t\tglobalThis: undefined as unknown, // set below\n\t\tundefined,\n\t\tInfinity,\n\t\tNaN,\n\t});\n}\n\nclass ExitSignal {\n\tconstructor(public readonly code: number) {}\n}\n\nfunction formatValue(v: unknown): string {\n\tif (v === null) return \"null\";\n\tif (v === undefined) return \"undefined\";\n\tif (typeof v === \"string\") return v;\n\tif (typeof v === \"function\") return `[Function: ${v.name || \"(anonymous)\"}]`;\n\tif (Array.isArray(v)) return `[ ${v.map(formatValue).join(\", \")} ]`;\n\tif (v instanceof Error) return `${v.name}: ${v.message}`;\n\tif (typeof v === \"object\") {\n\t\ttry {\n\t\t\tconst entries = Object.entries(v as Record<string, unknown>)\n\t\t\t\t.map(([k, val]) => `${k}: ${formatValue(val)}`)\n\t\t\t\t.join(\", \");\n\t\t\treturn `{ ${entries} }`;\n\t\t} catch {\n\t\t\treturn \"[Object]\";\n\t\t}\n\t}\n\treturn String(v);\n}\n\n// \u2500\u2500\u2500 execution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction runJs(code: string): {\n\tstdout: string;\n\tstderr: string;\n\texitCode: number;\n} {\n\tconst outputLines: string[] = [];\n\tconst stderrLines: string[] = [];\n\tconst ctx = makeContext(outputLines, stderrLines);\n\n\tlet exitCode = 0;\n\n\ttry {\n\t\tconst result = vm.runInContext(code, ctx, { timeout: 5000 });\n\t\t// If the expression returned a value and nothing was console.log'd, print it\n\t\tif (result !== undefined && outputLines.length === 0) {\n\t\t\toutputLines.push(formatValue(result));\n\t\t}\n\t} catch (err) {\n\t\tif (err instanceof ExitSignal) {\n\t\t\texitCode = err.code;\n\t\t} else if (err instanceof Error) {\n\t\t\tstderrLines.push(`${err.name}: ${err.message}`);\n\t\t\texitCode = 1;\n\t\t} else {\n\t\t\tstderrLines.push(String(err));\n\t\t\texitCode = 1;\n\t\t}\n\t}\n\n\treturn {\n\t\tstdout: outputLines.length ? `${outputLines.join(\"\\n\")}\\n` : \"\",\n\t\tstderr: stderrLines.length ? `${stderrLines.join(\"\\n\")}\\n` : \"\",\n\t\texitCode,\n\t};\n}\n\nfunction runJsFile(code: string): {\n\tstdout: string;\n\tstderr: string;\n\texitCode: number;\n} {\n\t// If the code is a single expression (no semicolons, no newlines, no statements),\n\t// wrap it to capture the return value like a REPL would\n\tconst trimmed = code.trim();\n\tconst isExpression =\n\t\t!trimmed.includes(\"\\n\") &&\n\t\t!trimmed.startsWith(\"const \") &&\n\t\t!trimmed.startsWith(\"let \") &&\n\t\t!trimmed.startsWith(\"var \") &&\n\t\t!trimmed.startsWith(\"function \") &&\n\t\t!trimmed.startsWith(\"class \") &&\n\t\t!trimmed.startsWith(\"if \") &&\n\t\t!trimmed.startsWith(\"for \") &&\n\t\t!trimmed.startsWith(\"while \") &&\n\t\t!trimmed.startsWith(\"import \") &&\n\t\t!trimmed.startsWith(\"//\");\n\n\tif (isExpression) return runJs(trimmed);\n\n\t// Multi-line: wrap in IIFE\n\treturn runJs(`(async () => { ${code} })()`);\n}\n\n// \u2500\u2500\u2500 command \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n/**\n * `node` virtual runtime command. Executes JS in a safe sandbox with\n * limited globals and no host FS/child process access.\n * @category system\n * @params []\n */\nexport const nodeCommand: ShellModule = {\n\tname: \"node\",\n\tdescription: \"JavaScript runtime (virtual)\",\n\tcategory: \"system\",\n\tparams: [\"[--version] [-e <expr>] [-p <expr>] [file]\"],\n\trun: ({ args, shell, cwd }) => {\n\t\t// Require explicit installation via `apt install nodejs`\n\t\tif (!shell.packageManager.isInstalled(\"nodejs\")) {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"bash: node: command not found\\nHint: install it with: apt install nodejs\\n\",\n\t\t\t\texitCode: 127,\n\t\t\t};\n\t\t}\n\t\tif (ifFlag(args, [\"--version\", \"-v\"])) {\n\t\t\treturn { stdout: `${VIRTUAL_VERSION}\\n`, exitCode: 0 };\n\t\t}\n\n\t\tif (ifFlag(args, [\"--versions\"])) {\n\t\t\treturn {\n\t\t\t\tstdout: `${JSON.stringify(VIRTUAL_VERSIONS, null, 2)}\\n`,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\t// -e 'expr'\n\t\tconst eIdx = args.findIndex((a) => a === \"-e\" || a === \"--eval\");\n\t\tif (eIdx !== -1) {\n\t\t\tconst expr = args[eIdx + 1];\n\t\t\tif (!expr)\n\t\t\t\treturn { stderr: \"node: -e requires an argument\\n\", exitCode: 1 };\n\t\t\tconst { stdout, stderr, exitCode } = runJs(expr);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || undefined,\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\t// -p 'expr' \u2014 print mode\n\t\tconst pIdx = args.findIndex((a) => a === \"-p\" || a === \"--print\");\n\t\tif (pIdx !== -1) {\n\t\t\tconst expr = args[pIdx + 1];\n\t\t\tif (!expr)\n\t\t\t\treturn { stderr: \"node: -p requires an argument\\n\", exitCode: 1 };\n\t\t\tconst { stdout, stderr, exitCode } = runJs(expr);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || (exitCode === 0 ? \"\\n\" : undefined),\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\t// node <file>\n\t\tconst file = args.find((a) => !a.startsWith(\"-\"));\n\t\tif (file) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\tif (!shell.vfs.exists(filePath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `node: cannot open file '${file}': No such file or directory\\n`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst code = shell.vfs.readFile(filePath);\n\t\t\tconst { stdout, stderr, exitCode } = runJsFile(code);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || undefined,\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\t// No args \u2014 REPL hint\n\t\treturn {\n\t\t\tstdout: [\n\t\t\t\t`Welcome to Node.js ${VIRTUAL_VERSION}.`,\n\t\t\t\t`Type \".exit\" to exit the REPL.`,\n\t\t\t\t`> `,\n\t\t\t].join(\"\\n\"),\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "/**\n * npm.ts \u2014 Virtual npm command.\n * Gated behind `apt install npm`. Provides version info and informative\n * stubs for common subcommands.\n */\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nconst NPM_VERSION = \"9.2.0\";\nconst NODE_VERSION = \"18.19.0\";\n\n/**\n * `npm` virtual CLI. Requires `apt install npm` in the virtual package manager.\n * @category system\n * @params [\"<command> [args]\"]\n */\nexport const npmCommand: ShellModule = {\n\tname: \"npm\",\n\tdescription: \"Node.js package manager (virtual)\",\n\tcategory: \"system\",\n\tparams: [\"<command> [args]\"],\n\trun: ({ args, shell }) => {\n\t\t// Require explicit installation\n\t\tif (!shell.packageManager.isInstalled(\"npm\")) {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"bash: npm: command not found\\nHint: install it with: apt install npm\\n\",\n\t\t\t\texitCode: 127,\n\t\t\t};\n\t\t}\n\n\t\tif (ifFlag(args, [\"--version\", \"-v\"])) {\n\t\t\treturn { stdout: `${NPM_VERSION}\\n`, exitCode: 0 };\n\t\t}\n\n\t\tconst sub = args[0]?.toLowerCase();\n\n\t\tswitch (sub) {\n\t\t\tcase \"version\":\n\t\t\tcase \"-version\":\n\t\t\t\treturn {\n\t\t\t\t\tstdout: `{ npm: '${NPM_VERSION}', node: '${NODE_VERSION}', v8: '10.2.154.26' }\\n`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\n\t\t\tcase \"install\":\n\t\t\tcase \"i\":\n\t\t\tcase \"add\":\n\t\t\t\treturn {\n\t\t\t\t\tstderr:\n\t\t\t\t\t\t\"npm warn: package installation is not available in the virtual runtime.\\nnpm warn: This environment simulates npm CLI behaviour only.\\n\",\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\n\t\t\tcase \"run\":\n\t\t\tcase \"exec\":\n\t\t\tcase \"x\":\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `npm error: script execution is not available in the virtual runtime.\\n`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\n\t\t\tcase \"init\":\n\t\t\t\treturn {\n\t\t\t\t\tstdout: \"Wrote to /home/user/package.json\\n\",\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\n\t\t\tcase \"list\":\n\t\t\tcase \"ls\":\n\t\t\t\treturn {\n\t\t\t\t\tstdout: `${sub === \"ls\" || sub === \"list\" ? \"virtual-env@1.0.0\" : \"\"}\\n\u2514\u2500\u2500 (empty)\\n`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\n\t\t\tcase \"help\":\n\t\t\tcase undefined:\n\t\t\t\treturn {\n\t\t\t\t\tstdout: `${[\n\t\t\t\t\t\t`npm ${NPM_VERSION}`,\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\"Usage: npm <command>\",\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\"Commands:\",\n\t\t\t\t\t\t\" install (not available in virtual runtime)\",\n\t\t\t\t\t\t\" run (not available in virtual runtime)\",\n\t\t\t\t\t\t\" exec (not available in virtual runtime)\",\n\t\t\t\t\t\t\" list List installed packages\",\n\t\t\t\t\t\t\" version Print versions\",\n\t\t\t\t\t\t\" --version Print npm version\",\n\t\t\t\t\t].join(\"\\n\")}\\n`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\n\t\t\tdefault:\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `npm error: unknown command: ${sub}\\n`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t}\n\t},\n};\n\n/**\n * `npx` virtual runner. Requires `apt install npm` in the virtual package manager.\n * @category system\n * @params [\"<package> [args]\"]\n */\nexport const npxCommand: ShellModule = {\n\tname: \"npx\",\n\tdescription: \"Node.js package runner (virtual)\",\n\tcategory: \"system\",\n\tparams: [\"<package> [args]\"],\n\trun: ({ args, shell }) => {\n\t\tif (!shell.packageManager.isInstalled(\"npm\")) {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"bash: npx: command not found\\nHint: install it with: apt install npm\\n\",\n\t\t\t\texitCode: 127,\n\t\t\t};\n\t\t}\n\n\t\tif (ifFlag(args, [\"--version\"])) {\n\t\t\treturn { stdout: `${NPM_VERSION}\\n`, exitCode: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\tstderr: `npx: package execution is not available in the virtual runtime.\\n`,\n\t\t\texitCode: 1,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const passwdCommand: ShellModule = {\n\tname: \"passwd\",\n\tdescription: \"Change user password\",\n\tcategory: \"users\",\n\tparams: [\"<username> <password>\"],\n\trun: async ({ authUser, args, shell }) => {\n\t\tconst [username, password] = args;\n\t\tif (!username || !password) {\n\t\t\treturn {\n\t\t\t\tstderr: \"passwd: usage: passwd <username> <password>\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\n\t\tif (authUser !== \"root\" && authUser !== username) {\n\t\t\treturn { stderr: \"passwd: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tawait shell.users.setPassword(username, password);\n\t\treturn {\n\t\t\tstdout: `passwd: password updated for '${username}'`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { parseArgs } from \"./command-helpers\";\n\nexport const pingCommand: ShellModule = {\n\tname: \"ping\",\n\tdescription: \"Send ICMP ECHO_REQUEST (mock)\",\n\tcategory: \"network\",\n\tparams: [\"[-c <count>] <host>\"],\n\trun: ({ args }) => {\n\t\tconst { flagsWithValues, positionals } = parseArgs(args, {\n\t\t\tflagsWithValue: [\"-c\", \"-i\", \"-W\"],\n\t\t});\n\t\tconst host = positionals[0] ?? \"localhost\";\n\t\tconst countArg = flagsWithValues.get(\"-c\");\n\t\tconst count = countArg ? Math.max(1, parseInt(countArg, 10) || 4) : 4;\n\t\tconst lines = [`PING ${host}: 56 data bytes`];\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst ms = (Math.random() * 10 + 1).toFixed(3);\n\t\t\tlines.push(`64 bytes from ${host}: icmp_seq=${i} ttl=64 time=${ms} ms`);\n\t\t}\n\t\tlines.push(`--- ${host} ping statistics ---`);\n\t\tlines.push(\n\t\t\t`${count} packets transmitted, ${count} received, 0% packet loss`,\n\t\t);\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Render a printf format string with given arguments.\n * Supports: %s %d %i %f %o %x %X %% \\n \\t \\r \\\\\n */\nfunction renderPrintf(fmt: string, args: string[]): string {\n\tlet argIdx = 0;\n\tlet out = \"\";\n\tlet i = 0;\n\twhile (i < fmt.length) {\n\t\tif (fmt[i] === \"\\\\\" && i + 1 < fmt.length) {\n\t\t\tswitch (fmt[i + 1]) {\n\t\t\t\tcase \"n\":\n\t\t\t\t\tout += \"\\n\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"t\":\n\t\t\t\t\tout += \"\\t\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"r\":\n\t\t\t\t\tout += \"\\r\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"\\\\\":\n\t\t\t\t\tout += \"\\\\\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"a\":\n\t\t\t\t\tout += \"\\x07\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tout += \"\\x08\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"f\":\n\t\t\t\t\tout += \"\\x0C\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"v\":\n\t\t\t\t\tout += \"\\x0B\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tdefault:\n\t\t\t\t\tout += fmt[i]!;\n\t\t\t\t\ti++;\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (fmt[i] === \"%\" && i + 1 < fmt.length) {\n\t\t\t// Optional width/precision: %[-][width][.prec]spec\n\t\t\tlet j = i + 1;\n\t\t\tif (fmt[j] === \"-\") j++;\n\t\t\twhile (j < fmt.length && /\\d/.test(fmt[j]!)) j++;\n\t\t\tif (fmt[j] === \".\") {\n\t\t\t\tj++;\n\t\t\t\twhile (j < fmt.length && /\\d/.test(fmt[j]!)) j++;\n\t\t\t}\n\t\t\tconst spec = fmt[j];\n\t\t\tconst arg = args[argIdx++] ?? \"\";\n\t\t\tswitch (spec) {\n\t\t\t\tcase \"s\":\n\t\t\t\t\tout += arg;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"d\":\n\t\t\t\tcase \"i\":\n\t\t\t\t\tout += String(parseInt(arg, 10) || 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"f\":\n\t\t\t\t\tout += String(parseFloat(arg) || 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"o\":\n\t\t\t\t\tout += (parseInt(arg, 10) || 0).toString(8);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"x\":\n\t\t\t\t\tout += (parseInt(arg, 10) || 0).toString(16);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"X\":\n\t\t\t\t\tout += (parseInt(arg, 10) || 0).toString(16).toUpperCase();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"%\":\n\t\t\t\t\tout += \"%\";\n\t\t\t\t\targIdx--;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tout += fmt[i]!;\n\t\t\t\t\ti++;\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ti = j + 1;\n\t\t\tcontinue;\n\t\t}\n\t\tout += fmt[i]!;\n\t\ti++;\n\t}\n\treturn out;\n}\n\nexport const printfCommand: ShellModule = {\n\tname: \"printf\",\n\tdescription: \"Format and print data\",\n\tcategory: \"shell\",\n\tparams: [\"<format> [args...]\"],\n\trun: ({ args }) => {\n\t\tconst fmt = args[0];\n\t\tif (!fmt) return { stderr: \"printf: missing format string\", exitCode: 1 };\n\t\tconst output = renderPrintf(fmt, args.slice(1));\n\t\treturn { stdout: output, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const psCommand: ShellModule = {\n\tname: \"ps\",\n\tdescription: \"Report process status\",\n\tcategory: \"system\",\n\tparams: [\"[-a] [-u] [-x] [aux]\"],\n\trun: ({ authUser, shell, args }) => {\n\t\tconst sessions = shell.users.listActiveSessions();\n\t\tconst showUser =\n\t\t\tifFlag(args, [\"-u\"]) ||\n\t\t\targs.includes(\"u\") ||\n\t\t\targs.includes(\"aux\") ||\n\t\t\targs.includes(\"au\");\n\t\tconst showAll =\n\t\t\tifFlag(args, [\"-a\", \"-x\"]) || args.includes(\"a\") || args.includes(\"aux\");\n\n\t\tif (showUser) {\n\t\t\tconst header =\n\t\t\t\t\"USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND\";\n\t\t\tconst rows: string[] = [header];\n\t\t\tlet pid = 1000;\n\t\t\tfor (const s of sessions) {\n\t\t\t\tconst user = s.username.padEnd(10).slice(0, 10);\n\t\t\t\tconst mem = (Math.random() * 0.5).toFixed(1);\n\t\t\t\tconst vsz = Math.floor(Math.random() * 20000 + 5000);\n\t\t\t\tconst rss = Math.floor(Math.random() * 5000 + 1000);\n\t\t\t\trows.push(\n\t\t\t\t\t`${user} ${String(pid).padStart(6)} 0.0 ${mem.padStart(4)} ${String(vsz).padStart(6)} ${String(rss).padStart(5)} ${s.tty.padEnd(8)} Ss 00:00 0:00 bash`,\n\t\t\t\t);\n\t\t\t\tpid++;\n\t\t\t}\n\t\t\trows.push(\n\t\t\t\t`root ${String(pid).padStart(6)} 0.0 0.0 0 0 ? S 00:00 0:00 ps`,\n\t\t\t);\n\t\t\treturn { stdout: rows.join(\"\\n\"), exitCode: 0 };\n\t\t}\n\n\t\tconst header = \" PID TTY TIME CMD\";\n\t\tconst rows: string[] = [header];\n\t\tlet pid = 1000;\n\t\tfor (const s of sessions) {\n\t\t\tif (!showAll && s.username !== authUser) continue;\n\t\t\trows.push(\n\t\t\t\t`${String(pid).padStart(5)} ${s.tty.padEnd(12)} 00:00:00 ${s.username === authUser ? \"bash\" : `bash (${s.username})`}`,\n\t\t\t);\n\t\t\tpid++;\n\t\t}\n\t\trows.push(`${String(pid).padStart(5)} pts/0 00:00:00 ps`);\n\t\treturn { stdout: rows.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const pwdCommand: ShellModule = {\n\tname: \"pwd\",\n\tdescription: \"Print working directory\",\n\tcategory: \"navigation\",\n\tparams: [],\n\trun: ({ cwd }) => ({ stdout: cwd, exitCode: 0 }),\n};\n", "/** biome-ignore-all lint/suspicious/useIterableCallbackReturn: intentional side-effect forEach */\n/**\n * python.ts \u2014 Virtual Python 3 interpreter.\n *\n * Implements a genuine mini-interpreter capable of:\n * - print(), len(), type(), range(), list(), str(), int(), float(), bool()\n * - max(), min(), abs(), sum(), sorted(), reversed(), enumerate(), zip()\n * - str methods: upper(), lower(), strip(), split(), join(), replace(),\n * startswith(), endswith(), format(), count(), find()\n * - list methods: append(), extend(), pop(), sort(), reverse(), index()\n * - dict: keys(), values(), items(), get()\n * - import os, sys, math, json, re (stubs)\n * - f-strings, multi-line scripts, assignments, for/while loops, if/elif/else\n * - functions (def), return, class basics\n */\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nconst VERSION = \"Python 3.11.2\";\nconst _VERSION_SHORT = \"3.11.2\";\nconst VERSION_INFO = \"3.11.2 (default, Mar 13 2023, 12:18:29) [GCC 12.2.0]\";\n\n// \u2500\u2500\u2500 Python value type \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype PyVal =\n\t| null\n\t| boolean\n\t| number\n\t| string\n\t| PyVal[]\n\t| PyDict\n\t| PyRange\n\t| PyFunc\n\t| PyClass\n\t| PyInstance\n\t| PyNone;\ntype PyDict = { __pytype__: \"dict\"; data: Map<string, PyVal> };\ntype PyRange = {\n\t__pytype__: \"range\";\n\tstart: number;\n\tstop: number;\n\tstep: number;\n};\ntype PyFunc = {\n\t__pytype__: \"func\";\n\tname: string;\n\tparams: string[];\n\tbody: string[];\n\tclosure: Scope;\n};\ntype PyClass = {\n\t__pytype__: \"class\";\n\tname: string;\n\tmethods: Map<string, PyFunc>;\n\tbases: string[];\n};\ntype PyInstance = {\n\t__pytype__: \"instance\";\n\tcls: PyClass;\n\tattrs: Map<string, PyVal>;\n};\ntype PyNone = { __pytype__: \"none\" };\n\nconst NONE: PyNone = { __pytype__: \"none\" };\n\nfunction pyDict(entries: [string, PyVal][] = []): PyDict {\n\treturn { __pytype__: \"dict\", data: new Map(entries) };\n}\nfunction pyRange(start: number, stop: number, step = 1): PyRange {\n\treturn { __pytype__: \"range\", start, stop, step };\n}\n\nfunction isPyDict(v: PyVal): v is PyDict {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyDict).__pytype__ === \"dict\"\n\t);\n}\nfunction isPyRange(v: PyVal): v is PyRange {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyRange).__pytype__ === \"range\"\n\t);\n}\nfunction isPyFunc(v: PyVal): v is PyFunc {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyFunc).__pytype__ === \"func\"\n\t);\n}\nfunction isPyClass(v: PyVal): v is PyClass {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyClass).__pytype__ === \"class\"\n\t);\n}\nfunction isPyInstance(v: PyVal): v is PyInstance {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyInstance).__pytype__ === \"instance\"\n\t);\n}\nfunction isPyNone(v: PyVal): v is PyNone {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyNone).__pytype__ === \"none\"\n\t);\n}\n\n// \u2500\u2500\u2500 repr / str \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction pyRepr(v: PyVal): string {\n\tif (v === null || isPyNone(v)) return \"None\";\n\tif (v === true) return \"True\";\n\tif (v === false) return \"False\";\n\tif (typeof v === \"number\")\n\t\treturn Number.isInteger(v)\n\t\t\t? String(v)\n\t\t\t: v.toPrecision(12).replace(/\\.?0+$/, \"\");\n\tif (typeof v === \"string\") return `'${v.replace(/'/g, \"\\\\'\")}'`;\n\tif (Array.isArray(v)) return `[${v.map(pyRepr).join(\", \")}]`;\n\tif (isPyDict(v))\n\t\treturn `{${[...v.data.entries()].map(([k, val]) => `'${k}': ${pyRepr(val)}`).join(\", \")}}`;\n\tif (isPyRange(v))\n\t\treturn `range(${v.start}, ${v.stop}${v.step !== 1 ? `, ${v.step}` : \"\"})`;\n\tif (isPyFunc(v)) return `<function ${v.name} at 0x...>`;\n\tif (isPyClass(v)) return `<class '${v.name}'>`;\n\tif (isPyInstance(v)) return `<${v.cls.name} object at 0x...>`;\n\treturn String(v);\n}\n\nfunction pyStr(v: PyVal): string {\n\tif (v === null || isPyNone(v)) return \"None\";\n\tif (v === true) return \"True\";\n\tif (v === false) return \"False\";\n\tif (typeof v === \"number\")\n\t\treturn Number.isInteger(v)\n\t\t\t? String(v)\n\t\t\t: v.toPrecision(12).replace(/\\.?0+$/, \"\");\n\tif (typeof v === \"string\") return v;\n\tif (Array.isArray(v)) return `[${v.map(pyRepr).join(\", \")}]`;\n\tif (isPyDict(v))\n\t\treturn `{${[...v.data.entries()].map(([k, val]) => `'${k}': ${pyRepr(val)}`).join(\", \")}}`;\n\tif (isPyRange(v))\n\t\treturn `range(${v.start}, ${v.stop}${v.step !== 1 ? `, ${v.step}` : \"\"})`;\n\treturn pyRepr(v);\n}\n\nfunction pyBool(v: PyVal): boolean {\n\tif (v === null || isPyNone(v)) return false;\n\tif (typeof v === \"boolean\") return v;\n\tif (typeof v === \"number\") return v !== 0;\n\tif (typeof v === \"string\") return v.length > 0;\n\tif (Array.isArray(v)) return v.length > 0;\n\tif (isPyDict(v)) return v.data.size > 0;\n\tif (isPyRange(v)) return pyRangeLength(v) > 0;\n\treturn true;\n}\n\nfunction pyRangeLength(r: PyRange): number {\n\tif (r.step === 0) return 0;\n\tconst n = Math.ceil((r.stop - r.start) / r.step);\n\treturn Math.max(0, n);\n}\n\nfunction pyRangeItems(r: PyRange): number[] {\n\tconst items: number[] = [];\n\tfor (let i = r.start; r.step > 0 ? i < r.stop : i > r.stop; i += r.step) {\n\t\titems.push(i);\n\t\tif (items.length > 10000) break;\n\t}\n\treturn items;\n}\n\nfunction pyIter(v: PyVal): PyVal[] {\n\tif (Array.isArray(v)) return v;\n\tif (typeof v === \"string\") return [...v];\n\tif (isPyRange(v)) return pyRangeItems(v);\n\tif (isPyDict(v)) return [...v.data.keys()];\n\tthrow new PyError(\"TypeError\", `'${pyTypeName(v)}' object is not iterable`);\n}\n\nfunction pyTypeName(v: PyVal): string {\n\tif (v === null || isPyNone(v)) return \"NoneType\";\n\tif (typeof v === \"boolean\") return \"bool\";\n\tif (typeof v === \"number\") return Number.isInteger(v) ? \"int\" : \"float\";\n\tif (typeof v === \"string\") return \"str\";\n\tif (Array.isArray(v)) return \"list\";\n\tif (isPyDict(v)) return \"dict\";\n\tif (isPyRange(v)) return \"range\";\n\tif (isPyFunc(v)) return \"function\";\n\tif (isPyClass(v)) return \"type\";\n\tif (isPyInstance(v)) return v.cls.name;\n\treturn \"object\";\n}\n\nclass PyError {\n\tconstructor(\n\t\tpublic type: string,\n\t\tpublic message: string,\n\t) {}\n\ttoString() {\n\t\treturn `${this.type}: ${this.message}`;\n\t}\n}\nclass ReturnSignal {\n\tconstructor(public value: PyVal) {}\n}\nclass BreakSignal {}\nclass ContinueSignal {}\nclass ExitSignal {\n\tconstructor(public code: number) {}\n}\n\n// \u2500\u2500\u2500 scope \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype Scope = Map<string, PyVal>;\n\nfunction makeRootScope(cwd: string): Scope {\n\tconst scope = new Map<string, PyVal>();\n\n\t// Built-in modules (lazy)\n\tconst osModule = pyDict([\n\t\t[\"sep\", \"/\"],\n\t\t[\"linesep\", \"\\n\"],\n\t\t[\"curdir\", \".\"],\n\t\t[\"pardir\", \"..\"],\n\t]);\n\t(osModule as unknown as Record<string, PyVal>).__methods__ = {\n\t\tgetcwd: () => cwd,\n\t\tgetenv: (k: PyVal) =>\n\t\t\ttypeof k === \"string\" ? (process.env[k] ?? NONE) : NONE,\n\t\tpath: pyDict([\n\t\t\t[\"join\", NONE],\n\t\t\t[\"exists\", NONE],\n\t\t\t[\"dirname\", NONE],\n\t\t\t[\"basename\", NONE],\n\t\t]),\n\t\tlistdir: () => [],\n\t} as unknown as PyVal;\n\n\tscope.set(\"__builtins__\", NONE);\n\tscope.set(\"__name__\", \"__main__\");\n\tscope.set(\"__cwd__\", cwd);\n\n\treturn scope;\n}\n\n// \u2500\u2500\u2500 built-in modules \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction makeOsModule(cwd: string): PyDict {\n\tconst path = pyDict([\n\t\t[\"sep\", \"/\"],\n\t\t[\"curdir\", \".\"],\n\t]);\n\tconst os = pyDict([\n\t\t[\"sep\", \"/\"],\n\t\t[\"linesep\", \"\\n\"],\n\t\t[\"name\", \"posix\"],\n\t]);\n\t// We'll handle method calls in callMethod\n\t(os as unknown as { _cwd: string })._cwd = cwd;\n\t(path as unknown as { _cwd: string })._cwd = cwd;\n\t(os as unknown as { path: PyDict }).path = path;\n\treturn os;\n}\n\nfunction makeSysModule(): PyDict {\n\treturn pyDict([\n\t\t[\"version\", VERSION_INFO],\n\t\t[\n\t\t\t\"version_info\",\n\t\t\tpyDict(\n\t\t\t\t[\n\t\t\t\t\t[\"major\", 3],\n\t\t\t\t\t[\"minor\", 11],\n\t\t\t\t\t[\"micro\", 2],\n\t\t\t\t].map(([k, v]) => [k as string, v as number]),\n\t\t\t),\n\t\t],\n\t\t[\"platform\", \"linux\"],\n\t\t[\"executable\", \"/usr/bin/python3\"],\n\t\t[\"prefix\", \"/usr\"],\n\t\t[\"path\", [\"/usr/lib/python3.11\", \"/usr/lib/python3.11/lib-dynload\"]],\n\t\t[\"argv\", [\"\"]],\n\t\t[\"maxsize\", 9007199254740991],\n\t]);\n}\n\nfunction makeMathModule(): PyDict {\n\treturn pyDict([\n\t\t[\"pi\", Math.PI],\n\t\t[\"e\", Math.E],\n\t\t[\"tau\", Math.PI * 2],\n\t\t[\"inf\", Infinity],\n\t\t[\"nan\", NaN],\n\t\t[\"sqrt\", NONE],\n\t\t[\"floor\", NONE],\n\t\t[\"ceil\", NONE],\n\t\t[\"log\", NONE],\n\t\t[\"pow\", NONE],\n\t\t[\"sin\", NONE],\n\t\t[\"cos\", NONE],\n\t\t[\"tan\", NONE],\n\t\t[\"fabs\", NONE],\n\t\t[\"factorial\", NONE],\n\t]);\n}\n\nfunction makeJsonModule(): PyDict {\n\treturn pyDict([\n\t\t[\"dumps\", NONE],\n\t\t[\"loads\", NONE],\n\t]);\n}\n\nfunction makeReModule(): PyDict {\n\treturn pyDict([\n\t\t[\"match\", NONE],\n\t\t[\"search\", NONE],\n\t\t[\"findall\", NONE],\n\t\t[\"sub\", NONE],\n\t\t[\"split\", NONE],\n\t\t[\"compile\", NONE],\n\t]);\n}\n\nconst MODULE_FACTORIES: Record<string, (cwd: string) => PyDict> = {\n\tos: makeOsModule,\n\tsys: () => makeSysModule(),\n\tmath: () => makeMathModule(),\n\tjson: () => makeJsonModule(),\n\tre: () => makeReModule(),\n\trandom: () =>\n\t\tpyDict([\n\t\t\t[\"random\", NONE],\n\t\t\t[\"randint\", NONE],\n\t\t\t[\"choice\", NONE],\n\t\t\t[\"shuffle\", NONE],\n\t\t]),\n\ttime: () =>\n\t\tpyDict([\n\t\t\t[\"time\", NONE],\n\t\t\t[\"sleep\", NONE],\n\t\t\t[\"ctime\", NONE],\n\t\t]),\n\tdatetime: () =>\n\t\tpyDict([\n\t\t\t[\"datetime\", NONE],\n\t\t\t[\"date\", NONE],\n\t\t\t[\"timedelta\", NONE],\n\t\t]),\n\tcollections: () =>\n\t\tpyDict([\n\t\t\t[\"Counter\", NONE],\n\t\t\t[\"defaultdict\", NONE],\n\t\t\t[\"OrderedDict\", NONE],\n\t\t]),\n\titertools: () =>\n\t\tpyDict([\n\t\t\t[\"chain\", NONE],\n\t\t\t[\"product\", NONE],\n\t\t\t[\"combinations\", NONE],\n\t\t\t[\"permutations\", NONE],\n\t\t]),\n\tfunctools: () =>\n\t\tpyDict([\n\t\t\t[\"reduce\", NONE],\n\t\t\t[\"partial\", NONE],\n\t\t\t[\"lru_cache\", NONE],\n\t\t]),\n\tstring: () =>\n\t\tpyDict([\n\t\t\t[\"ascii_letters\", \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"],\n\t\t\t[\"digits\", \"0123456789\"],\n\t\t\t[\"punctuation\", \"!\\\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~\"],\n\t\t]),\n};\n\n// \u2500\u2500\u2500 interpreter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nclass Interpreter {\n\tprivate output: string[] = [];\n\tprivate stderr: string[] = [];\n\tprivate modules = new Map<string, PyDict>();\n\n\tconstructor(private readonly cwd: string) {}\n\n\tgetOutput(): string {\n\t\treturn this.output.join(\"\\n\") + (this.output.length ? \"\\n\" : \"\");\n\t}\n\tgetStderr(): string {\n\t\treturn this.stderr.join(\"\\n\") + (this.stderr.length ? \"\\n\" : \"\");\n\t}\n\n\t// \u2500\u2500 tokenizer / parser helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate splitArgs(s: string): string[] {\n\t\t// Split on commas respecting balanced parens, brackets, braces, quotes\n\t\tconst args: string[] = [];\n\t\tlet depth = 0,\n\t\t\tcur = \"\",\n\t\t\tinStr = false,\n\t\t\tstrChar = \"\";\n\t\tfor (let i = 0; i < s.length; i++) {\n\t\t\tconst ch = s[i]!;\n\t\t\tif (inStr) {\n\t\t\t\tcur += ch;\n\t\t\t\tif (ch === strChar && s[i - 1] !== \"\\\\\") inStr = false;\n\t\t\t} else if (ch === '\"' || ch === \"'\") {\n\t\t\t\tinStr = true;\n\t\t\t\tstrChar = ch;\n\t\t\t\tcur += ch;\n\t\t\t} else if (\"([{\".includes(ch)) {\n\t\t\t\tdepth++;\n\t\t\t\tcur += ch;\n\t\t\t} else if (\")]}\".includes(ch)) {\n\t\t\t\tdepth--;\n\t\t\t\tcur += ch;\n\t\t\t} else if (ch === \",\" && depth === 0) {\n\t\t\t\targs.push(cur.trim());\n\t\t\t\tcur = \"\";\n\t\t\t} else {\n\t\t\t\tcur += ch;\n\t\t\t}\n\t\t}\n\t\tif (cur.trim()) args.push(cur.trim());\n\t\treturn args;\n\t}\n\n\t// \u2500\u2500 expression evaluator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tpyEval(expr: string, scope: Scope): PyVal {\n\t\texpr = expr.trim();\n\t\tif (!expr) return NONE;\n\n\t\t// None True False literals\n\t\tif (expr === \"None\") return NONE;\n\t\tif (expr === \"True\") return true;\n\t\tif (expr === \"False\") return false;\n\t\tif (expr === \"...\") return NONE;\n\n\t\t// Number literals\n\t\tif (/^-?\\d+$/.test(expr)) return parseInt(expr, 10);\n\t\tif (/^-?\\d+\\.\\d*$/.test(expr)) return parseFloat(expr);\n\t\tif (/^0x[0-9a-fA-F]+$/.test(expr)) return parseInt(expr, 16);\n\t\tif (/^0o[0-7]+$/.test(expr)) return parseInt(expr.slice(2), 8);\n\n\t\t// String literals (single, double, triple)\n\t\tif (/^('''[\\s\\S]*'''|\"\"\"[\\s\\S]*\"\"\")$/.test(expr)) {\n\t\t\treturn expr.slice(3, -3);\n\t\t}\n\t\tif (/^(['\"])(.*)\\1$/s.test(expr)) {\n\t\t\tconst inner = expr.slice(1, -1);\n\t\t\treturn inner\n\t\t\t\t.replace(/\\\\n/g, \"\\n\")\n\t\t\t\t.replace(/\\\\t/g, \"\\t\")\n\t\t\t\t.replace(/\\\\r/g, \"\\r\")\n\t\t\t\t.replace(/\\\\\\\\/g, \"\\\\\")\n\t\t\t\t.replace(/\\\\'/g, \"'\")\n\t\t\t\t.replace(/\\\\\"/g, '\"');\n\t\t}\n\n\t\t// f-strings\n\t\tconst fMatch = expr.match(/^f(['\"])([\\s\\S]*)\\1$/);\n\t\tif (fMatch) {\n\t\t\tlet result = fMatch[2]!;\n\t\t\tresult = result.replace(/\\{([^{}]+)\\}/g, (_, inner) => {\n\t\t\t\ttry {\n\t\t\t\t\treturn pyStr(this.pyEval(inner.trim(), scope));\n\t\t\t\t} catch {\n\t\t\t\t\treturn `{${inner}}`;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn result;\n\t\t}\n\n\t\t// Byte strings b\"...\" \u2014 treat as string\n\t\tconst bMatch = expr.match(/^b(['\"])(.*)\\1$/s);\n\t\tif (bMatch) return bMatch[2]!;\n\n\t\t// List literal [...]\n\t\tif (expr.startsWith(\"[\") && expr.endsWith(\"]\")) {\n\t\t\tconst inner = expr.slice(1, -1).trim();\n\t\t\tif (!inner) return [];\n\t\t\t// List comprehension\n\t\t\tconst compMatch = inner.match(\n\t\t\t\t/^(.+?)\\s+for\\s+(\\w+)\\s+in\\s+(.+?)(?:\\s+if\\s+(.+))?$/,\n\t\t\t);\n\t\t\tif (compMatch) {\n\t\t\t\tconst [, itemExpr, varName, iterExpr, condExpr] = compMatch;\n\t\t\t\tconst iterable = pyIter(this.pyEval(iterExpr!.trim(), scope));\n\t\t\t\tconst result: PyVal[] = [];\n\t\t\t\tfor (const item of iterable) {\n\t\t\t\t\tconst inner2 = new Map(scope);\n\t\t\t\t\tinner2.set(varName!, item);\n\t\t\t\t\tif (condExpr && !pyBool(this.pyEval(condExpr, inner2))) continue;\n\t\t\t\t\tresult.push(this.pyEval(itemExpr!.trim(), inner2));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\treturn this.splitArgs(inner).map((a) => this.pyEval(a, scope));\n\t\t}\n\n\t\t// Tuple (...)\n\t\tif (expr.startsWith(\"(\") && expr.endsWith(\")\")) {\n\t\t\tconst inner = expr.slice(1, -1).trim();\n\t\t\tif (!inner) return [];\n\t\t\tconst parts = this.splitArgs(inner);\n\t\t\tif (parts.length === 1 && !inner.endsWith(\",\"))\n\t\t\t\treturn this.pyEval(parts[0]!, scope);\n\t\t\treturn parts.map((a) => this.pyEval(a, scope));\n\t\t}\n\n\t\t// Dict literal {...}\n\t\tif (expr.startsWith(\"{\") && expr.endsWith(\"}\")) {\n\t\t\tconst inner = expr.slice(1, -1).trim();\n\t\t\tif (!inner) return pyDict();\n\t\t\tconst dict = pyDict();\n\t\t\tfor (const entry of this.splitArgs(inner)) {\n\t\t\t\tconst colonIdx = entry.indexOf(\":\");\n\t\t\t\tif (colonIdx === -1) continue;\n\t\t\t\tconst k = pyStr(this.pyEval(entry.slice(0, colonIdx).trim(), scope));\n\t\t\t\tconst v = this.pyEval(entry.slice(colonIdx + 1).trim(), scope);\n\t\t\t\tdict.data.set(k, v);\n\t\t\t}\n\t\t\treturn dict;\n\t\t}\n\n\t\t// not expr\n\t\tconst notMatch = expr.match(/^not\\s+(.+)$/);\n\t\tif (notMatch) return !pyBool(this.pyEval(notMatch[1]!, scope));\n\n\t\t// Binary operators (right-to-left scan at lowest depth)\n\t\tconst binaryOps = [\n\t\t\t[\"or\"],\n\t\t\t[\"and\"],\n\t\t\t[\"in\", \"not in\", \"is not\", \"is\", \"==\", \"!=\", \"<=\", \">=\", \"<\", \">\"],\n\t\t\t[\"+\", \"-\"],\n\t\t\t[\"**\"],\n\t\t\t[\"*\", \"//\", \"/\", \"%\"],\n\t\t];\n\t\tfor (const ops of binaryOps) {\n\t\t\tconst result = this.tryBinaryOp(expr, ops, scope);\n\t\t\tif (result !== undefined) return result;\n\t\t}\n\n\t\t// Unary minus\n\t\tif (expr.startsWith(\"-\")) {\n\t\t\tconst val = this.pyEval(expr.slice(1), scope);\n\t\t\tif (typeof val === \"number\") return -val;\n\t\t}\n\n\t\t// Subscript: expr[key] or expr[start:stop]\n\t\tif (process.env.PY_DEBUG) console.error(\"eval:\", JSON.stringify(expr));\n\t\tif (expr.endsWith(\"]\") && !expr.startsWith(\"[\")) {\n\t\t\tconst bracketStart = this.findMatchingBracket(expr, \"[\");\n\t\t\tif (bracketStart !== -1) {\n\t\t\t\tconst obj = this.pyEval(expr.slice(0, bracketStart), scope);\n\t\t\t\tconst key = expr.slice(bracketStart + 1, -1);\n\t\t\t\treturn this.subscript(obj, key, scope);\n\t\t\t}\n\t\t}\n\n\t\t// Function call: name(args...) \u2014 must come BEFORE dotMatch to avoid\n\t\t// print('x'.upper()) being parsed as dotMatch(\"print('x'\", \"upper\", \"()\")\n\t\tconst callMatch = expr.match(/^([A-Za-z_][A-Za-z0-9_]*)\\s*\\(([\\s\\S]*)\\)$/);\n\t\tif (callMatch) {\n\t\t\tconst [, name, argsStr] = callMatch;\n\t\t\tconst callArgs = (argsStr?.trim() ? this.splitArgs(argsStr) : []).map(\n\t\t\t\t(a) => this.pyEval(a, scope),\n\t\t\t);\n\t\t\treturn this.callBuiltin(name!, callArgs, scope);\n\t\t}\n\n\t\t// Attribute access / method call: expr.attr or expr.method(args)\n\t\t// Uses a depth-aware scanner to find the rightmost dot at depth 0\n\t\tconst dotResult = this.findDotAccess(expr);\n\t\tif (dotResult) {\n\t\t\tconst { objExpr, attr, callPart } = dotResult;\n\t\t\tconst obj = this.pyEval(objExpr, scope);\n\t\t\tif (callPart !== undefined) {\n\t\t\t\tconst argsInner = callPart.slice(1, -1);\n\t\t\t\tconst callArgs = argsInner.trim()\n\t\t\t\t\t? this.splitArgs(argsInner).map((a) => this.pyEval(a, scope))\n\t\t\t\t\t: [];\n\t\t\t\treturn this.callMethod(obj, attr, callArgs, scope);\n\t\t\t}\n\t\t\treturn this.getAttr(obj, attr, scope);\n\t\t}\n\n\t\t// Variable lookup\n\t\tif (/^[A-Za-z_][A-Za-z0-9_]*$/.test(expr)) {\n\t\t\tif (scope.has(expr)) return scope.get(expr)!;\n\t\t\t// Check parent scopes (for closures)\n\t\t\tthrow new PyError(\"NameError\", `name '${expr}' is not defined`);\n\t\t}\n\n\t\t// Dotted name lookup (module.attr)\n\t\tif (/^[A-Za-z_][A-Za-z0-9_.]+$/.test(expr)) {\n\t\t\tconst parts = expr.split(\".\");\n\t\t\tlet val: PyVal =\n\t\t\t\tscope.get(parts[0]!) ??\n\t\t\t\t(() => {\n\t\t\t\t\tthrow new PyError(\"NameError\", `name '${parts[0]}' is not defined`);\n\t\t\t\t})();\n\t\t\tfor (const part of parts.slice(1)) {\n\t\t\t\tval = this.getAttr(val, part, scope);\n\t\t\t}\n\t\t\treturn val;\n\t\t}\n\n\t\treturn NONE;\n\t}\n\n\tprivate findMatchingBracket(s: string, open: string): number {\n\t\tconst close = open === \"[\" ? \"]\" : open === \"(\" ? \")\" : \"}\";\n\t\tlet depth = 0;\n\t\tfor (let i = s.length - 1; i >= 0; i--) {\n\t\t\tif (s[i] === close) depth++;\n\t\t\tif (s[i] === open) {\n\t\t\t\tdepth--;\n\t\t\t\tif (depth === 0) return i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\t/**\n\t * Find the rightmost dot-attribute access at depth 0, respecting strings/parens.\n\t * Returns {objExpr, attr, callPart} or null if not a dot-access expression.\n\t */\n\tprivate findDotAccess(\n\t\texpr: string,\n\t): { objExpr: string; attr: string; callPart: string | undefined } | null {\n\t\t// Scan right to left for a dot at depth 0 (not inside strings/brackets)\n\t\tlet depth = 0,\n\t\t\tinStr = false,\n\t\t\tstrChar = \"\";\n\t\tfor (let i = expr.length - 1; i > 0; i--) {\n\t\t\tconst ch = expr[i]!;\n\t\t\tif (inStr) {\n\t\t\t\tif (ch === strChar && expr[i - 1] !== \"\\\\\") inStr = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === '\"' || ch === \"'\") {\n\t\t\t\tinStr = true;\n\t\t\t\tstrChar = ch;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\")]}\".includes(ch)) {\n\t\t\t\tdepth++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\"([{\".includes(ch)) {\n\t\t\t\tdepth--;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (depth !== 0) continue;\n\t\t\tif (ch !== \".\") continue;\n\t\t\t// Found a dot at depth 0\n\t\t\tconst objExpr = expr.slice(0, i).trim();\n\t\t\tconst rest = expr.slice(i + 1); // \"attr\" or \"attr(args)\"\n\t\t\tconst attrMatch = rest.match(/^(\\w+)(\\([\\s\\S]*\\))?$/);\n\t\t\tif (!attrMatch) continue;\n\t\t\t// Skip float literals like 1.5\n\t\t\tif (/^-?\\d+$/.test(objExpr)) continue;\n\t\t\treturn { objExpr, attr: attrMatch[1]!, callPart: attrMatch[2] };\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate tryBinaryOp(\n\t\texpr: string,\n\t\tops: string[],\n\t\tscope: Scope,\n\t): PyVal | undefined {\n\t\tlet depth = 0,\n\t\t\tinStr = false,\n\t\t\tstrChar = \"\";\n\t\tfor (let i = expr.length - 1; i >= 0; i--) {\n\t\t\tconst ch = expr[i]!;\n\t\t\tif (inStr) {\n\t\t\t\tif (ch === strChar && expr[i - 1] !== \"\\\\\") inStr = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === '\"' || ch === \"'\") {\n\t\t\t\tinStr = true;\n\t\t\t\tstrChar = ch;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\")]}\".includes(ch)) {\n\t\t\t\tdepth++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\"([{\".includes(ch)) {\n\t\t\t\tdepth--;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (depth !== 0) continue;\n\n\t\t\tfor (const op of ops) {\n\t\t\t\tif (expr.slice(i, i + op.length) === op) {\n\t\t\t\t\t// Skip \"*\" if it's actually part of \"**\"\n\t\t\t\t\tif (op === \"*\" && (expr[i + 1] === \"*\" || expr[i - 1] === \"*\"))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t// Ensure it's a standalone operator (not part of identifier)\n\t\t\t\t\tconst before = expr[i - 1];\n\t\t\t\t\tconst after = expr[i + op.length];\n\t\t\t\t\tconst wordOp = /^[a-z]/.test(op);\n\t\t\t\t\tif (wordOp) {\n\t\t\t\t\t\tif (before && /\\w/.test(before)) continue;\n\t\t\t\t\t\tif (after && /\\w/.test(after)) continue;\n\t\t\t\t\t}\n\t\t\t\t\tconst left = expr.slice(0, i).trim();\n\t\t\t\t\tconst right = expr.slice(i + op.length).trim();\n\t\t\t\t\tif (!left || !right) continue;\n\t\t\t\t\treturn this.applyBinaryOp(op, left, right, scope);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate applyBinaryOp(\n\t\top: string,\n\t\tleftExpr: string,\n\t\trightExpr: string,\n\t\tscope: Scope,\n\t): PyVal {\n\t\tif (op === \"and\") {\n\t\t\tconst l = this.pyEval(leftExpr, scope);\n\t\t\treturn pyBool(l) ? this.pyEval(rightExpr, scope) : l;\n\t\t}\n\t\tif (op === \"or\") {\n\t\t\tconst l = this.pyEval(leftExpr, scope);\n\t\t\treturn pyBool(l) ? l : this.pyEval(rightExpr, scope);\n\t\t}\n\n\t\tconst left = this.pyEval(leftExpr, scope);\n\t\tconst right = this.pyEval(rightExpr, scope);\n\n\t\tswitch (op) {\n\t\t\tcase \"+\":\n\t\t\t\tif (typeof left === \"string\" && typeof right === \"string\")\n\t\t\t\t\treturn left + right;\n\t\t\t\tif (Array.isArray(left) && Array.isArray(right))\n\t\t\t\t\treturn [...left, ...right];\n\t\t\t\treturn (left as number) + (right as number);\n\t\t\tcase \"-\":\n\t\t\t\treturn (left as number) - (right as number);\n\t\t\tcase \"*\":\n\t\t\t\tif (typeof left === \"string\" && typeof right === \"number\")\n\t\t\t\t\treturn left.repeat(right);\n\t\t\t\tif (Array.isArray(left) && typeof right === \"number\") {\n\t\t\t\t\tconst arr: PyVal[] = [];\n\t\t\t\t\tfor (let i = 0; i < right; i++) arr.push(...left);\n\t\t\t\t\treturn arr;\n\t\t\t\t}\n\t\t\t\treturn (left as number) * (right as number);\n\t\t\tcase \"/\": {\n\t\t\t\tif ((right as number) === 0)\n\t\t\t\t\tthrow new PyError(\"ZeroDivisionError\", \"division by zero\");\n\t\t\t\treturn (left as number) / (right as number);\n\t\t\t}\n\t\t\tcase \"//\": {\n\t\t\t\tif ((right as number) === 0)\n\t\t\t\t\tthrow new PyError(\n\t\t\t\t\t\t\"ZeroDivisionError\",\n\t\t\t\t\t\t\"integer division or modulo by zero\",\n\t\t\t\t\t);\n\t\t\t\treturn Math.floor((left as number) / (right as number));\n\t\t\t}\n\t\t\tcase \"%\": {\n\t\t\t\tif (typeof left === \"string\")\n\t\t\t\t\treturn this.pyStringFormat(\n\t\t\t\t\t\tleft,\n\t\t\t\t\t\tArray.isArray(right) ? right : [right],\n\t\t\t\t\t);\n\t\t\t\tif ((right as number) === 0)\n\t\t\t\t\tthrow new PyError(\n\t\t\t\t\t\t\"ZeroDivisionError\",\n\t\t\t\t\t\t\"integer division or modulo by zero\",\n\t\t\t\t\t);\n\t\t\t\treturn (left as number) % (right as number);\n\t\t\t}\n\t\t\tcase \"**\":\n\t\t\t\treturn (left as number) ** (right as number);\n\t\t\tcase \"==\":\n\t\t\t\treturn pyRepr(left) === pyRepr(right) || left === right;\n\t\t\tcase \"!=\":\n\t\t\t\treturn pyRepr(left) !== pyRepr(right) && left !== right;\n\t\t\tcase \"<\":\n\t\t\t\treturn (left as number) < (right as number);\n\t\t\tcase \"<=\":\n\t\t\t\treturn (left as number) <= (right as number);\n\t\t\tcase \">\":\n\t\t\t\treturn (left as number) > (right as number);\n\t\t\tcase \">=\":\n\t\t\t\treturn (left as number) >= (right as number);\n\t\t\tcase \"in\":\n\t\t\t\treturn this.pyIn(right, left);\n\t\t\tcase \"not in\":\n\t\t\t\treturn !this.pyIn(right, left);\n\t\t\tcase \"is\":\n\t\t\t\treturn (\n\t\t\t\t\tleft === right ||\n\t\t\t\t\t(isPyNone(left as PyVal) && isPyNone(right as PyVal))\n\t\t\t\t);\n\t\t\tcase \"is not\":\n\t\t\t\treturn !(\n\t\t\t\t\tleft === right ||\n\t\t\t\t\t(isPyNone(left as PyVal) && isPyNone(right as PyVal))\n\t\t\t\t);\n\t\t}\n\t\treturn NONE;\n\t}\n\n\tprivate pyIn(container: PyVal, item: PyVal): boolean {\n\t\tif (typeof container === \"string\")\n\t\t\treturn typeof item === \"string\" && container.includes(item);\n\t\tif (Array.isArray(container))\n\t\t\treturn container.some((v) => pyRepr(v) === pyRepr(item));\n\t\tif (isPyDict(container)) return container.data.has(pyStr(item));\n\t\treturn false;\n\t}\n\n\tprivate subscript(obj: PyVal, key: string, scope: Scope): PyVal {\n\t\t// Slice\n\t\tif (key.includes(\":\")) {\n\t\t\tconst parts = key.split(\":\").map((p) => p.trim());\n\t\t\tconst start = parts[0]\n\t\t\t\t? (this.pyEval(parts[0], scope) as number)\n\t\t\t\t: undefined;\n\t\t\tconst stop = parts[1]\n\t\t\t\t? (this.pyEval(parts[1], scope) as number)\n\t\t\t\t: undefined;\n\t\t\tif (typeof obj === \"string\") return obj.slice(start, stop);\n\t\t\tif (Array.isArray(obj)) return obj.slice(start, stop);\n\t\t\treturn NONE;\n\t\t}\n\t\tconst k = this.pyEval(key, scope);\n\t\tif (Array.isArray(obj)) {\n\t\t\tlet idx = k as number;\n\t\t\tif (idx < 0) idx = obj.length + idx;\n\t\t\treturn obj[idx] ?? NONE;\n\t\t}\n\t\tif (typeof obj === \"string\") {\n\t\t\tlet idx = k as number;\n\t\t\tif (idx < 0) idx = obj.length + idx;\n\t\t\treturn obj[idx] ?? NONE;\n\t\t}\n\t\tif (isPyDict(obj)) return obj.data.get(pyStr(k)) ?? NONE;\n\t\tthrow new PyError(\"TypeError\", `'${pyTypeName(obj)}' is not subscriptable`);\n\t}\n\n\t// \u2500\u2500 attribute access \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate getAttr(obj: PyVal, attr: string, _scope: Scope): PyVal {\n\t\tif (isPyDict(obj)) {\n\t\t\tif (obj.data.has(attr)) return obj.data.get(attr)!;\n\t\t\t// Special dict attributes\n\t\t\tif (attr === \"path\" && (obj as unknown as { path: PyVal }).path)\n\t\t\t\treturn (obj as unknown as { path: PyVal }).path;\n\t\t\treturn NONE;\n\t\t}\n\t\tif (isPyInstance(obj)) return obj.attrs.get(attr) ?? NONE;\n\t\tif (typeof obj === \"string\") {\n\t\t\t// String attributes\n\t\t\tconst strMethods: Record<string, PyVal> = {\n\t\t\t\t__class__: { __pytype__: \"class\", name: \"str\" } as unknown as PyClass,\n\t\t\t};\n\t\t\treturn strMethods[attr] ?? NONE;\n\t\t}\n\t\treturn NONE;\n\t}\n\n\t// \u2500\u2500 method calls \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate callMethod(\n\t\tobj: PyVal,\n\t\tmethod: string,\n\t\targs: PyVal[],\n\t\t_scope: Scope,\n\t): PyVal {\n\t\t// String methods\n\t\tif (typeof obj === \"string\") {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"upper\":\n\t\t\t\t\treturn obj.toUpperCase();\n\t\t\t\tcase \"lower\":\n\t\t\t\t\treturn obj.toLowerCase();\n\t\t\t\tcase \"strip\":\n\t\t\t\t\treturn (\n\t\t\t\t\t\targs[0] ? obj.replace(new RegExp(`[${args[0]}]+`, \"g\"), \"\") : obj\n\t\t\t\t\t).trim();\n\t\t\t\tcase \"lstrip\":\n\t\t\t\t\treturn obj.trimStart();\n\t\t\t\tcase \"rstrip\":\n\t\t\t\t\treturn obj.trimEnd();\n\t\t\t\tcase \"split\":\n\t\t\t\t\treturn obj\n\t\t\t\t\t\t.split(typeof args[0] === \"string\" ? args[0] : /\\s+/)\n\t\t\t\t\t\t.filter((s, i) => i > 0 || s !== \"\") as PyVal[];\n\t\t\t\tcase \"splitlines\":\n\t\t\t\t\treturn obj.split(\"\\n\") as PyVal[];\n\t\t\t\tcase \"join\":\n\t\t\t\t\treturn pyIter(args[0] ?? [])\n\t\t\t\t\t\t.map(pyStr)\n\t\t\t\t\t\t.join(obj);\n\t\t\t\tcase \"replace\":\n\t\t\t\t\treturn obj.replaceAll(pyStr(args[0] ?? \"\"), pyStr(args[1] ?? \"\"));\n\t\t\t\tcase \"startswith\":\n\t\t\t\t\treturn obj.startsWith(pyStr(args[0] ?? \"\"));\n\t\t\t\tcase \"endswith\":\n\t\t\t\t\treturn obj.endsWith(pyStr(args[0] ?? \"\"));\n\t\t\t\tcase \"find\":\n\t\t\t\t\treturn obj.indexOf(pyStr(args[0] ?? \"\"));\n\t\t\t\tcase \"index\": {\n\t\t\t\t\tconst i = obj.indexOf(pyStr(args[0] ?? \"\"));\n\t\t\t\t\tif (i === -1) throw new PyError(\"ValueError\", \"substring not found\");\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t\tcase \"count\":\n\t\t\t\t\treturn obj.split(pyStr(args[0] ?? \"\")).length - 1;\n\t\t\t\tcase \"format\":\n\t\t\t\t\treturn this.pyStringFormat(obj, args);\n\t\t\t\tcase \"encode\":\n\t\t\t\t\treturn obj; // bytes stub\n\t\t\t\tcase \"decode\":\n\t\t\t\t\treturn obj;\n\t\t\t\tcase \"isdigit\":\n\t\t\t\t\treturn /^\\d+$/.test(obj);\n\t\t\t\tcase \"isalpha\":\n\t\t\t\t\treturn /^[a-zA-Z]+$/.test(obj);\n\t\t\t\tcase \"isalnum\":\n\t\t\t\t\treturn /^[a-zA-Z0-9]+$/.test(obj);\n\t\t\t\tcase \"isspace\":\n\t\t\t\t\treturn /^\\s+$/.test(obj);\n\t\t\t\tcase \"isupper\":\n\t\t\t\t\treturn obj === obj.toUpperCase() && obj !== obj.toLowerCase();\n\t\t\t\tcase \"islower\":\n\t\t\t\t\treturn obj === obj.toLowerCase() && obj !== obj.toUpperCase();\n\t\t\t\tcase \"center\": {\n\t\t\t\t\tconst w = (args[0] as number) ?? 0;\n\t\t\t\t\tconst f = pyStr(args[1] ?? \" \");\n\t\t\t\t\treturn obj.padStart(Math.floor((w + obj.length) / 2), f).padEnd(w, f);\n\t\t\t\t}\n\t\t\t\tcase \"ljust\":\n\t\t\t\t\treturn obj.padEnd((args[0] as number) ?? 0, pyStr(args[1] ?? \" \"));\n\t\t\t\tcase \"rjust\":\n\t\t\t\t\treturn obj.padStart((args[0] as number) ?? 0, pyStr(args[1] ?? \" \"));\n\t\t\t\tcase \"zfill\":\n\t\t\t\t\treturn obj.padStart((args[0] as number) ?? 0, \"0\");\n\t\t\t\tcase \"title\":\n\t\t\t\t\treturn obj.replace(/\\b\\w/g, (c) => c.toUpperCase());\n\t\t\t\tcase \"capitalize\":\n\t\t\t\t\treturn obj[0]?.toUpperCase() + obj.slice(1).toLowerCase();\n\t\t\t\tcase \"swapcase\":\n\t\t\t\t\treturn [...obj]\n\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\tc === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase(),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join(\"\");\n\t\t\t}\n\t\t}\n\n\t\t// List methods\n\t\tif (Array.isArray(obj)) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"append\":\n\t\t\t\t\tobj.push(args[0] ?? NONE);\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"extend\":\n\t\t\t\t\tfor (const v of pyIter(args[0] ?? [])) obj.push(v);\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"insert\":\n\t\t\t\t\tobj.splice((args[0] as number) ?? 0, 0, args[1] ?? NONE);\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"pop\": {\n\t\t\t\t\tconst idx = args[0] !== undefined ? (args[0] as number) : -1;\n\t\t\t\t\tconst i = idx < 0 ? obj.length + idx : idx;\n\t\t\t\t\treturn obj.splice(i, 1)[0] ?? NONE;\n\t\t\t\t}\n\t\t\t\tcase \"remove\": {\n\t\t\t\t\tconst i = obj.findIndex((v) => pyRepr(v) === pyRepr(args[0] ?? NONE));\n\t\t\t\t\tif (i !== -1) obj.splice(i, 1);\n\t\t\t\t\treturn NONE;\n\t\t\t\t}\n\t\t\t\tcase \"index\": {\n\t\t\t\t\tconst i = obj.findIndex((v) => pyRepr(v) === pyRepr(args[0] ?? NONE));\n\t\t\t\t\tif (i === -1) throw new PyError(\"ValueError\", \"is not in list\");\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t\tcase \"count\":\n\t\t\t\t\treturn obj.filter((v) => pyRepr(v) === pyRepr(args[0] ?? NONE))\n\t\t\t\t\t\t.length;\n\t\t\t\tcase \"sort\":\n\t\t\t\t\tobj.sort((a, b) =>\n\t\t\t\t\t\ttypeof a === \"number\" && typeof b === \"number\"\n\t\t\t\t\t\t\t? a - b\n\t\t\t\t\t\t\t: pyStr(a).localeCompare(pyStr(b)),\n\t\t\t\t\t);\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"reverse\":\n\t\t\t\t\tobj.reverse();\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"copy\":\n\t\t\t\t\treturn [...obj];\n\t\t\t\tcase \"clear\":\n\t\t\t\t\tobj.splice(0);\n\t\t\t\t\treturn NONE;\n\t\t\t}\n\t\t}\n\n\t\t// Dict methods\n\t\tif (isPyDict(obj)) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"keys\":\n\t\t\t\t\treturn [...obj.data.keys()];\n\t\t\t\tcase \"values\":\n\t\t\t\t\treturn [...obj.data.values()];\n\t\t\t\tcase \"items\":\n\t\t\t\t\treturn [...obj.data.entries()].map(([k, v]) => [k, v] as PyVal);\n\t\t\t\tcase \"get\":\n\t\t\t\t\treturn obj.data.get(pyStr(args[0] ?? \"\")) ?? args[1] ?? NONE;\n\t\t\t\tcase \"update\": {\n\t\t\t\t\tif (isPyDict(args[0] ?? NONE))\n\t\t\t\t\t\tfor (const [k, v] of (args[0] as PyDict).data) obj.data.set(k, v);\n\t\t\t\t\treturn NONE;\n\t\t\t\t}\n\t\t\t\tcase \"pop\": {\n\t\t\t\t\tconst k = pyStr(args[0] ?? \"\");\n\t\t\t\t\tconst v = obj.data.get(k) ?? args[1] ?? NONE;\n\t\t\t\t\tobj.data.delete(k);\n\t\t\t\t\treturn v;\n\t\t\t\t}\n\t\t\t\tcase \"clear\":\n\t\t\t\t\tobj.data.clear();\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"copy\":\n\t\t\t\t\treturn pyDict([...obj.data.entries()]);\n\t\t\t\tcase \"setdefault\": {\n\t\t\t\t\tconst k = pyStr(args[0] ?? \"\");\n\t\t\t\t\tif (!obj.data.has(k)) obj.data.set(k, args[1] ?? NONE);\n\t\t\t\t\treturn obj.data.get(k) ?? NONE;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// os module methods\n\t\tif (\n\t\t\tisPyDict(obj) &&\n\t\t\tobj.data.has(\"name\") &&\n\t\t\tobj.data.get(\"name\") === \"posix\"\n\t\t) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"getcwd\":\n\t\t\t\t\treturn this.cwd;\n\t\t\t\tcase \"getenv\":\n\t\t\t\t\treturn typeof args[0] === \"string\"\n\t\t\t\t\t\t? (process.env[args[0]] ?? args[1] ?? NONE)\n\t\t\t\t\t\t: NONE;\n\t\t\t\tcase \"listdir\":\n\t\t\t\t\treturn [];\n\t\t\t\tcase \"path\":\n\t\t\t\t\treturn obj; // return self\n\t\t\t}\n\t\t}\n\n\t\t// os.path methods\n\t\tif (isPyDict(obj)) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"join\":\n\t\t\t\t\treturn args.map(pyStr).join(\"/\").replace(/\\/+/g, \"/\");\n\t\t\t\tcase \"exists\":\n\t\t\t\t\treturn false; // no real fs access\n\t\t\t\tcase \"dirname\": {\n\t\t\t\t\tconst p = pyStr(args[0] ?? \"\");\n\t\t\t\t\treturn p.split(\"/\").slice(0, -1).join(\"/\") || \"/\";\n\t\t\t\t}\n\t\t\t\tcase \"basename\": {\n\t\t\t\t\tconst p = pyStr(args[0] ?? \"\");\n\t\t\t\t\treturn p.split(\"/\").pop() ?? \"\";\n\t\t\t\t}\n\t\t\t\tcase \"abspath\":\n\t\t\t\t\treturn pyStr(args[0] ?? \"\");\n\t\t\t\tcase \"splitext\": {\n\t\t\t\t\tconst p = pyStr(args[0] ?? \"\");\n\t\t\t\t\tconst d = p.lastIndexOf(\".\");\n\t\t\t\t\treturn d > 0 ? [p.slice(0, d), p.slice(d)] : [p, \"\"];\n\t\t\t\t}\n\t\t\t\tcase \"isfile\":\n\t\t\t\t\treturn false;\n\t\t\t\tcase \"isdir\":\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// sys module\n\t\tif (\n\t\t\tisPyDict(obj) &&\n\t\t\tobj.data.has(\"version\") &&\n\t\t\tobj.data.get(\"version\") === VERSION_INFO\n\t\t) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"exit\":\n\t\t\t\t\tthrow new ExitSignal((args[0] as number) ?? 0);\n\t\t\t}\n\t\t}\n\n\t\t// math module\n\t\tif (isPyDict(obj)) {\n\t\t\tconst mathFns: Record<string, (...a: number[]) => number> = {\n\t\t\t\tsqrt: Math.sqrt,\n\t\t\t\tfloor: Math.floor,\n\t\t\t\tceil: Math.ceil,\n\t\t\t\tfabs: Math.abs,\n\t\t\t\tlog: Math.log,\n\t\t\t\tlog2: Math.log2,\n\t\t\t\tlog10: Math.log10,\n\t\t\t\tsin: Math.sin,\n\t\t\t\tcos: Math.cos,\n\t\t\t\ttan: Math.tan,\n\t\t\t\tasin: Math.asin,\n\t\t\t\tacos: Math.acos,\n\t\t\t\tatan: Math.atan,\n\t\t\t\tatan2: Math.atan2,\n\t\t\t\tpow: Math.pow,\n\t\t\t\texp: Math.exp,\n\t\t\t\thypot: Math.hypot,\n\t\t\t};\n\t\t\tif (method in mathFns) {\n\t\t\t\tconst fn = mathFns[method]!;\n\t\t\t\treturn fn(...args.map((a) => a as number));\n\t\t\t}\n\t\t\tif (method === \"factorial\") {\n\t\t\t\tlet n = (args[0] as number) ?? 0;\n\t\t\t\tlet r = 1;\n\t\t\t\twhile (n > 1) {\n\t\t\t\t\tr *= n--;\n\t\t\t\t}\n\t\t\t\treturn r;\n\t\t\t}\n\t\t\tif (method === \"gcd\") {\n\t\t\t\tlet a = Math.abs((args[0] as number) ?? 0);\n\t\t\t\tlet b = Math.abs((args[1] as number) ?? 0);\n\t\t\t\twhile (b) {\n\t\t\t\t\t[a, b] = [b, a % b];\n\t\t\t\t}\n\t\t\t\treturn a;\n\t\t\t}\n\t\t}\n\n\t\t// json module\n\t\tif (isPyDict(obj)) {\n\t\t\tif (method === \"dumps\") {\n\t\t\t\tconst opts: PyDict | undefined = isPyDict(args[1] ?? NONE)\n\t\t\t\t\t? (args[1] as PyDict)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst indent = opts ? (opts.data.get(\"indent\") as number) : undefined;\n\t\t\t\treturn JSON.stringify(this.pyToJs(args[0] ?? NONE), null, indent);\n\t\t\t}\n\t\t\tif (method === \"loads\") {\n\t\t\t\treturn this.jsToPy(JSON.parse(pyStr(args[0] ?? \"\")));\n\t\t\t}\n\t\t}\n\n\t\t// Instance method calls\n\t\tif (isPyInstance(obj)) {\n\t\t\tconst fn: PyVal =\n\t\t\t\tobj.attrs.get(method) ?? obj.cls.methods.get(method) ?? NONE;\n\t\t\tif (isPyFunc(fn)) {\n\t\t\t\tconst callScope = new Map(fn.closure);\n\t\t\t\tcallScope.set(\"self\", obj);\n\t\t\t\tfn.params.slice(1).forEach((p, i) => callScope.set(p, args[i] ?? NONE));\n\t\t\t\treturn this.execBlock(fn.body, callScope);\n\t\t\t}\n\t\t}\n\n\t\tthrow new PyError(\n\t\t\t\"AttributeError\",\n\t\t\t`'${pyTypeName(obj)}' object has no attribute '${method}'`,\n\t\t);\n\t}\n\n\tprivate pyStringFormat(fmt: string, args: PyVal[]): string {\n\t\tlet i = 0;\n\t\treturn fmt.replace(/%([diouxXeEfFgGcrs%])/g, (_, spec: string) => {\n\t\t\tif (spec === \"%\") return \"%\";\n\t\t\tconst val = args[i++];\n\t\t\tswitch (spec) {\n\t\t\t\tcase \"d\":\n\t\t\t\tcase \"i\":\n\t\t\t\t\treturn String(Math.trunc(val as number));\n\t\t\t\tcase \"f\":\n\t\t\t\t\treturn (val as number).toFixed(6);\n\t\t\t\tcase \"s\":\n\t\t\t\t\treturn pyStr(val ?? NONE);\n\t\t\t\tcase \"r\":\n\t\t\t\t\treturn pyRepr(val ?? NONE);\n\t\t\t\tdefault:\n\t\t\t\t\treturn String(val);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate pyToJs(v: PyVal): unknown {\n\t\tif (isPyNone(v)) return null;\n\t\tif (isPyDict(v))\n\t\t\treturn Object.fromEntries(\n\t\t\t\t[...v.data.entries()].map(([k, val]) => [k, this.pyToJs(val)]),\n\t\t\t);\n\t\tif (Array.isArray(v)) return v.map((i) => this.pyToJs(i));\n\t\treturn v;\n\t}\n\n\tprivate jsToPy(v: unknown): PyVal {\n\t\tif (v === null || v === undefined) return NONE;\n\t\tif (typeof v === \"boolean\") return v;\n\t\tif (typeof v === \"number\") return v;\n\t\tif (typeof v === \"string\") return v;\n\t\tif (Array.isArray(v)) return v.map((i) => this.jsToPy(i));\n\t\tif (typeof v === \"object\")\n\t\t\treturn pyDict(\n\t\t\t\tObject.entries(v as Record<string, unknown>).map(([k, val]) => [\n\t\t\t\t\tk,\n\t\t\t\t\tthis.jsToPy(val),\n\t\t\t\t]),\n\t\t\t);\n\t\treturn NONE;\n\t}\n\n\t// \u2500\u2500 built-in functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate callBuiltin(name: string, args: PyVal[], scope: Scope): PyVal {\n\t\t// User-defined functions\n\t\tif (scope.has(name)) {\n\t\t\tconst fn: PyVal = scope.get(name) ?? NONE;\n\t\t\tif (isPyFunc(fn)) return this.callFunc(fn, args, scope);\n\t\t\tif (isPyClass(fn)) return this.instantiate(fn as PyClass, args, scope);\n\t\t\treturn fn;\n\t\t}\n\n\t\tswitch (name) {\n\t\t\t// Output\n\t\t\tcase \"print\": {\n\t\t\t\tconst sep = \" \",\n\t\t\t\t\tend = \"\\n\";\n\t\t\t\tthis.output.push(args.map(pyStr).join(sep) + end.replace(/\\\\n/g, \"\"));\n\t\t\t\treturn NONE;\n\t\t\t}\n\t\t\tcase \"input\": {\n\t\t\t\tthis.output.push(pyStr(args[0] ?? \"\"));\n\t\t\t\treturn \"\";\n\t\t\t}\n\n\t\t\t// Type constructors\n\t\t\tcase \"int\": {\n\t\t\t\tif (args.length === 0) return 0;\n\t\t\t\tconst base = (args[1] as number) ?? 10;\n\t\t\t\tconst n = parseInt(pyStr(args[0] ?? 0), base);\n\t\t\t\treturn Number.isNaN(n)\n\t\t\t\t\t? (() => {\n\t\t\t\t\t\t\tthrow new PyError(\"ValueError\", `invalid literal for int()`);\n\t\t\t\t\t\t})()\n\t\t\t\t\t: n;\n\t\t\t}\n\t\t\tcase \"float\": {\n\t\t\t\tif (args.length === 0) return 0.0;\n\t\t\t\tconst f = parseFloat(pyStr(args[0] ?? 0));\n\t\t\t\treturn Number.isNaN(f)\n\t\t\t\t\t? (() => {\n\t\t\t\t\t\t\tthrow new PyError(\"ValueError\", `could not convert to float`);\n\t\t\t\t\t\t})()\n\t\t\t\t\t: f;\n\t\t\t}\n\t\t\tcase \"str\":\n\t\t\t\treturn args.length === 0 ? \"\" : pyStr(args[0] ?? NONE);\n\t\t\tcase \"bool\":\n\t\t\t\treturn args.length === 0 ? false : pyBool(args[0] ?? NONE);\n\t\t\tcase \"list\":\n\t\t\t\treturn args.length === 0 ? [] : pyIter(args[0] ?? []);\n\t\t\tcase \"tuple\":\n\t\t\t\treturn args.length === 0 ? [] : pyIter(args[0] ?? []);\n\t\t\tcase \"set\":\n\t\t\t\treturn args.length === 0\n\t\t\t\t\t? []\n\t\t\t\t\t: [...new Set(pyIter(args[0] ?? []).map(pyRepr))].map((s) => {\n\t\t\t\t\t\t\tconst v = pyIter(args[0] ?? []).find(\n\t\t\t\t\t\t\t\t(item) => pyRepr(item) === s,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn v ?? NONE;\n\t\t\t\t\t\t});\n\t\t\tcase \"dict\":\n\t\t\t\treturn args.length === 0\n\t\t\t\t\t? pyDict()\n\t\t\t\t\t: isPyDict(args[0] ?? NONE)\n\t\t\t\t\t\t? (args[0] as PyDict)\n\t\t\t\t\t\t: pyDict();\n\t\t\tcase \"bytes\":\n\t\t\t\treturn typeof args[0] === \"string\" ? args[0] : pyStr(args[0] ?? \"\");\n\t\t\tcase \"bytearray\":\n\t\t\t\treturn args.length === 0 ? \"\" : pyStr(args[0] ?? \"\");\n\n\t\t\t// Type inspection\n\t\t\tcase \"type\": {\n\t\t\t\tif (args.length === 1)\n\t\t\t\t\treturn `<class '${pyTypeName(args[0] ?? NONE)}'>`;\n\t\t\t\treturn NONE;\n\t\t\t}\n\t\t\tcase \"isinstance\":\n\t\t\t\treturn pyTypeName(args[0] ?? NONE) === pyStr(args[1] ?? \"\");\n\t\t\tcase \"issubclass\":\n\t\t\t\treturn false;\n\t\t\tcase \"callable\":\n\t\t\t\treturn isPyFunc(args[0] ?? NONE);\n\t\t\tcase \"hasattr\":\n\t\t\t\treturn isPyDict(args[0] ?? NONE)\n\t\t\t\t\t? (args[0] as PyDict).data.has(pyStr(args[1] ?? \"\"))\n\t\t\t\t\t: false;\n\t\t\tcase \"getattr\": {\n\t\t\t\tif (!isPyDict(args[0] ?? NONE)) return args[2] ?? NONE;\n\t\t\t\treturn (\n\t\t\t\t\t(args[0] as PyDict).data.get(pyStr(args[1] ?? \"\")) ?? args[2] ?? NONE\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"setattr\": {\n\t\t\t\tif (isPyDict(args[0] ?? NONE))\n\t\t\t\t\t(args[0] as PyDict).data.set(pyStr(args[1] ?? \"\"), args[2] ?? NONE);\n\t\t\t\treturn NONE;\n\t\t\t}\n\n\t\t\t// Functional\n\t\t\tcase \"len\": {\n\t\t\t\tconst v = args[0] ?? NONE;\n\t\t\t\tif (typeof v === \"string\") return v.length;\n\t\t\t\tif (Array.isArray(v)) return v.length;\n\t\t\t\tif (isPyDict(v)) return v.data.size;\n\t\t\t\tif (isPyRange(v)) return pyRangeLength(v);\n\t\t\t\tthrow new PyError(\n\t\t\t\t\t\"TypeError\",\n\t\t\t\t\t`object of type '${pyTypeName(v)}' has no len()`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"range\": {\n\t\t\t\tif (args.length === 1) return pyRange(0, args[0] as number);\n\t\t\t\tif (args.length === 2)\n\t\t\t\t\treturn pyRange(args[0] as number, args[1] as number);\n\t\t\t\treturn pyRange(args[0] as number, args[1] as number, args[2] as number);\n\t\t\t}\n\t\t\tcase \"enumerate\": {\n\t\t\t\tconst start = (args[1] as number) ?? 0;\n\t\t\t\treturn pyIter(args[0] ?? []).map((v, i) => [i + start, v] as PyVal);\n\t\t\t}\n\t\t\tcase \"zip\": {\n\t\t\t\tconst iters = args.map(pyIter);\n\t\t\t\tconst len = Math.min(...iters.map((it) => it.length));\n\t\t\t\treturn Array.from({ length: len }, (_, i) =>\n\t\t\t\t\titers.map((it) => it[i] ?? NONE),\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"map\": {\n\t\t\t\tconst fn: PyVal = args[0] ?? NONE;\n\t\t\t\treturn pyIter(args[1] ?? []).map((v) =>\n\t\t\t\t\tisPyFunc(fn) ? this.callFunc(fn, [v], scope) : NONE,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"filter\": {\n\t\t\t\tconst fn: PyVal = args[0] ?? NONE;\n\t\t\t\treturn pyIter(args[1] ?? []).filter((v) =>\n\t\t\t\t\tisPyFunc(fn) ? pyBool(this.callFunc(fn, [v], scope)) : pyBool(v),\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"reduce\": {\n\t\t\t\tconst fn: PyVal = args[0] ?? NONE;\n\t\t\t\tconst items = pyIter(args[1] ?? []);\n\t\t\t\tif (items.length === 0) return args[2] ?? NONE;\n\t\t\t\tlet acc: PyVal = args[2] !== undefined ? args[2] : items[0]!;\n\t\t\t\tfor (const item of args[2] !== undefined ? items : items.slice(1)) {\n\t\t\t\t\tacc = isPyFunc(fn)\n\t\t\t\t\t\t? this.callFunc(fn as PyFunc, [acc, item], scope)\n\t\t\t\t\t\t: NONE;\n\t\t\t\t}\n\t\t\t\treturn acc;\n\t\t\t}\n\t\t\tcase \"sorted\": {\n\t\t\t\tconst items = [...pyIter(args[0] ?? [])];\n\t\t\t\tconst sortArg1 = args[1] ?? NONE;\n\t\t\t\tconst keyFn: PyVal = isPyDict(sortArg1)\n\t\t\t\t\t? (sortArg1.data.get(\"key\") ?? NONE)\n\t\t\t\t\t: sortArg1;\n\t\t\t\titems.sort((a, b) => {\n\t\t\t\t\tconst ka: PyVal = isPyFunc(keyFn)\n\t\t\t\t\t\t? this.callFunc(keyFn, [a], scope)\n\t\t\t\t\t\t: a;\n\t\t\t\t\tconst kb: PyVal = isPyFunc(keyFn)\n\t\t\t\t\t\t? this.callFunc(keyFn, [b], scope)\n\t\t\t\t\t\t: b;\n\t\t\t\t\treturn typeof ka === \"number\" && typeof kb === \"number\"\n\t\t\t\t\t\t? ka - kb\n\t\t\t\t\t\t: pyStr(ka).localeCompare(pyStr(kb));\n\t\t\t\t});\n\t\t\t\treturn items;\n\t\t\t}\n\t\t\tcase \"reversed\":\n\t\t\t\treturn [...pyIter(args[0] ?? [])].reverse();\n\t\t\tcase \"any\":\n\t\t\t\treturn pyIter(args[0] ?? []).some(pyBool);\n\t\t\tcase \"all\":\n\t\t\t\treturn pyIter(args[0] ?? []).every(pyBool);\n\t\t\tcase \"sum\":\n\t\t\t\treturn pyIter(args[0] ?? []).reduce(\n\t\t\t\t\t(acc, v) => (acc as number) + (v as number),\n\t\t\t\t\t(args[1] ?? 0) as number,\n\t\t\t\t);\n\t\t\tcase \"max\": {\n\t\t\t\tconst items = args.length === 1 ? pyIter(args[0] ?? []) : args;\n\t\t\t\treturn items.reduce((a, b) => ((a as number) >= (b as number) ? a : b));\n\t\t\t}\n\t\t\tcase \"min\": {\n\t\t\t\tconst items = args.length === 1 ? pyIter(args[0] ?? []) : args;\n\t\t\t\treturn items.reduce((a, b) => ((a as number) <= (b as number) ? a : b));\n\t\t\t}\n\t\t\tcase \"abs\":\n\t\t\t\treturn Math.abs((args[0] as number) ?? 0);\n\t\t\tcase \"round\":\n\t\t\t\treturn args[1] !== undefined\n\t\t\t\t\t? parseFloat((args[0] as number).toFixed(args[1] as number))\n\t\t\t\t\t: Math.round((args[0] as number) ?? 0);\n\t\t\tcase \"divmod\": {\n\t\t\t\tconst a = args[0] as number,\n\t\t\t\t\tb = args[1] as number;\n\t\t\t\treturn [Math.floor(a / b), a % b];\n\t\t\t}\n\t\t\tcase \"pow\":\n\t\t\t\treturn (args[0] as number) ** (args[1] as number);\n\t\t\tcase \"hex\":\n\t\t\t\treturn `0x${(args[0] as number).toString(16)}`;\n\t\t\tcase \"oct\":\n\t\t\t\treturn `0o${(args[0] as number).toString(8)}`;\n\t\t\tcase \"bin\":\n\t\t\t\treturn `0b${(args[0] as number).toString(2)}`;\n\t\t\tcase \"ord\":\n\t\t\t\treturn pyStr(args[0] ?? \"\").charCodeAt(0);\n\t\t\tcase \"chr\":\n\t\t\t\treturn String.fromCharCode((args[0] as number) ?? 0);\n\t\t\tcase \"id\":\n\t\t\t\treturn Math.floor(Math.random() * 0xffffffff);\n\t\t\tcase \"hash\":\n\t\t\t\treturn typeof args[0] === \"number\"\n\t\t\t\t\t? args[0]\n\t\t\t\t\t: pyStr(args[0] ?? \"\")\n\t\t\t\t\t\t\t.split(\"\")\n\t\t\t\t\t\t\t.reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0);\n\n\t\t\t// I/O\n\t\t\tcase \"open\":\n\t\t\t\tthrow new PyError(\n\t\t\t\t\t\"PermissionError\",\n\t\t\t\t\t\"open() not available in virtual runtime\",\n\t\t\t\t);\n\t\t\tcase \"repr\":\n\t\t\t\treturn pyRepr(args[0] ?? NONE);\n\n\t\t\t// Iteration helpers\n\t\t\tcase \"iter\":\n\t\t\t\treturn args[0] ?? NONE; // simplification\n\t\t\tcase \"next\": {\n\t\t\t\tif (Array.isArray(args[0]) && args[0].length > 0)\n\t\t\t\t\treturn args[0].shift()!;\n\t\t\t\treturn (\n\t\t\t\t\targs[1] ??\n\t\t\t\t\t(() => {\n\t\t\t\t\t\tthrow new PyError(\"StopIteration\", \"\");\n\t\t\t\t\t})()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// vars/globals/locals\n\t\t\tcase \"vars\":\n\t\t\t\treturn pyDict([...scope.entries()].map(([k, v]) => [k, v]));\n\t\t\tcase \"globals\":\n\t\t\t\treturn pyDict([...scope.entries()].map(([k, v]) => [k, v]));\n\t\t\tcase \"locals\":\n\t\t\t\treturn pyDict([...scope.entries()].map(([k, v]) => [k, v]));\n\t\t\tcase \"dir\": {\n\t\t\t\tif (args.length === 0) return [...scope.keys()];\n\t\t\t\tconst obj = args[0] ?? NONE;\n\t\t\t\tif (typeof obj === \"string\")\n\t\t\t\t\treturn [\n\t\t\t\t\t\t\"upper\",\n\t\t\t\t\t\t\"lower\",\n\t\t\t\t\t\t\"strip\",\n\t\t\t\t\t\t\"split\",\n\t\t\t\t\t\t\"join\",\n\t\t\t\t\t\t\"replace\",\n\t\t\t\t\t\t\"find\",\n\t\t\t\t\t\t\"format\",\n\t\t\t\t\t\t\"encode\",\n\t\t\t\t\t\t\"startswith\",\n\t\t\t\t\t\t\"endswith\",\n\t\t\t\t\t\t\"count\",\n\t\t\t\t\t\t\"isdigit\",\n\t\t\t\t\t\t\"isalpha\",\n\t\t\t\t\t\t\"title\",\n\t\t\t\t\t\t\"capitalize\",\n\t\t\t\t\t];\n\t\t\t\tif (Array.isArray(obj))\n\t\t\t\t\treturn [\n\t\t\t\t\t\t\"append\",\n\t\t\t\t\t\t\"extend\",\n\t\t\t\t\t\t\"insert\",\n\t\t\t\t\t\t\"pop\",\n\t\t\t\t\t\t\"remove\",\n\t\t\t\t\t\t\"index\",\n\t\t\t\t\t\t\"count\",\n\t\t\t\t\t\t\"sort\",\n\t\t\t\t\t\t\"reverse\",\n\t\t\t\t\t\t\"copy\",\n\t\t\t\t\t\t\"clear\",\n\t\t\t\t\t];\n\t\t\t\tif (isPyDict(obj))\n\t\t\t\t\treturn [\n\t\t\t\t\t\t\"keys\",\n\t\t\t\t\t\t\"values\",\n\t\t\t\t\t\t\"items\",\n\t\t\t\t\t\t\"get\",\n\t\t\t\t\t\t\"update\",\n\t\t\t\t\t\t\"pop\",\n\t\t\t\t\t\t\"clear\",\n\t\t\t\t\t\t\"copy\",\n\t\t\t\t\t\t\"setdefault\",\n\t\t\t\t\t];\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\t// Exception\n\t\t\tcase \"Exception\":\n\t\t\tcase \"ValueError\":\n\t\t\tcase \"TypeError\":\n\t\t\tcase \"KeyError\":\n\t\t\tcase \"IndexError\":\n\t\t\tcase \"AttributeError\":\n\t\t\tcase \"NameError\":\n\t\t\tcase \"RuntimeError\":\n\t\t\tcase \"StopIteration\":\n\t\t\tcase \"NotImplementedError\":\n\t\t\tcase \"OSError\":\n\t\t\tcase \"IOError\":\n\t\t\t\tthrow new PyError(name, pyStr(args[0] ?? \"\"));\n\n\t\t\t// exec/eval\n\t\t\tcase \"exec\": {\n\t\t\t\tthis.execScript(pyStr(args[0] ?? \"\"), scope);\n\t\t\t\treturn NONE;\n\t\t\t}\n\t\t\tcase \"eval\":\n\t\t\t\treturn this.pyEval(pyStr(args[0] ?? \"\"), scope);\n\n\t\t\tdefault:\n\t\t\t\tthrow new PyError(\"NameError\", `name '${name}' is not defined`);\n\t\t}\n\t}\n\n\tprivate callFunc(fn: PyFunc, args: PyVal[], _scope: Scope): PyVal {\n\t\tconst callScope = new Map(fn.closure);\n\t\tfn.params.forEach((p, i) => {\n\t\t\tif (p.startsWith(\"*\")) {\n\t\t\t\tcallScope.set(p.slice(1), args.slice(i));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcallScope.set(p, args[i] ?? NONE);\n\t\t});\n\t\ttry {\n\t\t\treturn this.execBlock(fn.body, callScope);\n\t\t} catch (e) {\n\t\t\tif (e instanceof ReturnSignal) return e.value;\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tprivate instantiate(cls: PyClass, args: PyVal[], scope: Scope): PyInstance {\n\t\tconst inst: PyInstance = { __pytype__: \"instance\", cls, attrs: new Map() };\n\t\tconst init = cls.methods.get(\"__init__\");\n\t\tif (init) this.callMethod(inst, \"__init__\", args, scope);\n\t\treturn inst;\n\t}\n\n\t// \u2500\u2500 statement executor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\texecScript(code: string, scope: Scope): void {\n\t\tconst lines = code.split(\"\\n\");\n\t\tthis.execLines(lines, 0, scope);\n\t}\n\n\tprivate execLines(lines: string[], startIdx: number, scope: Scope): number {\n\t\tlet i = startIdx;\n\t\twhile (i < lines.length) {\n\t\t\tconst raw = lines[i]!;\n\t\t\tif (!raw.trim() || raw.trim().startsWith(\"#\")) {\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ti = this.execStatement(lines, i, scope);\n\t\t}\n\t\treturn i;\n\t}\n\n\tprivate execBlock(bodyLines: string[], scope: Scope): PyVal {\n\t\ttry {\n\t\t\tthis.execLines(bodyLines, 0, scope);\n\t\t} catch (e) {\n\t\t\tif (e instanceof ReturnSignal) return e.value;\n\t\t\tthrow e;\n\t\t}\n\t\treturn NONE;\n\t}\n\n\tprivate getIndent(line: string): number {\n\t\tlet n = 0;\n\t\tfor (const ch of line) {\n\t\t\tif (ch === \" \") n++;\n\t\t\telse if (ch === \"\\t\") n += 4;\n\t\t\telse break;\n\t\t}\n\t\treturn n;\n\t}\n\n\tprivate collectBlock(\n\t\tlines: string[],\n\t\tstartIdx: number,\n\t\tbaseIndent: number,\n\t): string[] {\n\t\tconst block: string[] = [];\n\t\tfor (let i = startIdx; i < lines.length; i++) {\n\t\t\tconst l = lines[i]!;\n\t\t\tif (!l.trim()) {\n\t\t\t\tblock.push(\"\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.getIndent(l) <= baseIndent) break;\n\t\t\tblock.push(l.slice(baseIndent + 4));\n\t\t}\n\t\treturn block;\n\t}\n\n\tprivate execStatement(lines: string[], idx: number, scope: Scope): number {\n\t\tconst raw = lines[idx]!;\n\t\tconst line = raw.trim();\n\t\tconst indent = this.getIndent(raw);\n\n\t\t// pass\n\t\tif (line === \"pass\") return idx + 1;\n\n\t\t// break / continue\n\t\tif (line === \"break\") {\n\t\t\tthrow new BreakSignal();\n\t\t}\n\t\tif (line === \"continue\") {\n\t\t\tthrow new ContinueSignal();\n\t\t}\n\n\t\t// return\n\t\tconst retMatch = line.match(/^return(?:\\s+(.+))?$/);\n\t\tif (retMatch)\n\t\t\tthrow new ReturnSignal(\n\t\t\t\tretMatch[1] ? this.pyEval(retMatch[1], scope) : NONE,\n\t\t\t);\n\n\t\t// raise\n\t\tconst raiseMatch = line.match(/^raise(?:\\s+(.+))?$/);\n\t\tif (raiseMatch) {\n\t\t\tif (raiseMatch[1]) {\n\t\t\t\tconst ex = this.pyEval(raiseMatch[1], scope);\n\t\t\t\tthrow new PyError(\n\t\t\t\t\ttypeof ex === \"string\" ? ex : pyTypeName(ex),\n\t\t\t\t\tpyStr(ex),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new PyError(\"RuntimeError\", \"\");\n\t\t}\n\n\t\t// assert\n\t\tconst assertMatch = line.match(/^assert\\s+(.+?)(?:,\\s*(.+))?$/);\n\t\tif (assertMatch) {\n\t\t\tif (!pyBool(this.pyEval(assertMatch[1]!, scope))) {\n\t\t\t\tthrow new PyError(\n\t\t\t\t\t\"AssertionError\",\n\t\t\t\t\tassertMatch[2] ? pyStr(this.pyEval(assertMatch[2], scope)) : \"\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// del\n\t\tconst delMatch = line.match(/^del\\s+(.+)$/);\n\t\tif (delMatch) {\n\t\t\tscope.delete(delMatch[1]!.trim());\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// import / from\n\t\tconst importMatch = line.match(/^import\\s+(\\w+)(?:\\s+as\\s+(\\w+))?$/);\n\t\tif (importMatch) {\n\t\t\tconst [, modName, alias] = importMatch;\n\t\t\tconst factory = MODULE_FACTORIES[modName!];\n\t\t\tif (factory) {\n\t\t\t\tconst mod = factory(this.cwd);\n\t\t\t\tthis.modules.set(modName!, mod);\n\t\t\t\tscope.set(alias ?? modName!, mod);\n\t\t\t}\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\tconst fromMatch = line.match(/^from\\s+(\\w+)\\s+import\\s+(.+)$/);\n\t\tif (fromMatch) {\n\t\t\tconst [, modName, imports] = fromMatch;\n\t\t\tconst factory = MODULE_FACTORIES[modName!];\n\t\t\tif (factory) {\n\t\t\t\tconst mod = factory(this.cwd);\n\t\t\t\tif (imports?.trim() === \"*\") {\n\t\t\t\t\tfor (const [k, v] of mod.data) scope.set(k, v);\n\t\t\t\t} else {\n\t\t\t\t\tfor (const name of imports!.split(\",\").map((s) => s.trim())) {\n\t\t\t\t\t\tscope.set(name, mod.data.get(name) ?? NONE);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// def\n\t\tconst defMatch = line.match(/^def\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*:$/);\n\t\tif (defMatch) {\n\t\t\tconst [, fnName, paramsStr] = defMatch;\n\t\t\tconst params = paramsStr!\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((p) => p.trim())\n\t\t\t\t.filter(Boolean);\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tconst fn: PyFunc = {\n\t\t\t\t__pytype__: \"func\",\n\t\t\t\tname: fnName!,\n\t\t\t\tparams,\n\t\t\t\tbody,\n\t\t\t\tclosure: new Map(scope),\n\t\t\t};\n\t\t\tscope.set(fnName!, fn);\n\t\t\treturn idx + 1 + body.length;\n\t\t}\n\n\t\t// class\n\t\tconst classMatch = line.match(/^class\\s+(\\w+)(?:\\(([^)]*)\\))?\\s*:$/);\n\t\tif (classMatch) {\n\t\t\tconst [, className, basesStr] = classMatch;\n\t\t\tconst bases = basesStr ? basesStr.split(\",\").map((s) => s.trim()) : [];\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tconst cls: PyClass = {\n\t\t\t\t__pytype__: \"class\",\n\t\t\t\tname: className!,\n\t\t\t\tmethods: new Map(),\n\t\t\t\tbases,\n\t\t\t};\n\t\t\t// Parse method definitions from body\n\t\t\tlet j = 0;\n\t\t\twhile (j < body.length) {\n\t\t\t\tconst bl = body[j]!.trim();\n\t\t\t\tconst mMatch = bl.match(/^def\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*:$/);\n\t\t\t\tif (mMatch) {\n\t\t\t\t\tconst [, mName, mParams] = mMatch;\n\t\t\t\t\tconst params = mParams!\n\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t.map((p) => p.trim())\n\t\t\t\t\t\t.filter(Boolean);\n\t\t\t\t\tconst mBody = this.collectBlock(body, j + 1, 0);\n\t\t\t\t\tcls.methods.set(mName!, {\n\t\t\t\t\t\t__pytype__: \"func\",\n\t\t\t\t\t\tname: mName!,\n\t\t\t\t\t\tparams,\n\t\t\t\t\t\tbody: mBody,\n\t\t\t\t\t\tclosure: new Map(scope),\n\t\t\t\t\t});\n\t\t\t\t\tj += 1 + mBody.length;\n\t\t\t\t} else {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tscope.set(className!, cls);\n\t\t\treturn idx + 1 + body.length;\n\t\t}\n\n\t\t// if / elif / else\n\t\tif (line.startsWith(\"if \") && line.endsWith(\":\")) {\n\t\t\tconst cond = line.slice(3, -1).trim();\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tconst _skip = body.length + 1;\n\n\t\t\tif (pyBool(this.pyEval(cond, scope))) {\n\t\t\t\tthis.execBlock(\n\t\t\t\t\tbody,\n\t\t\t\t\tnew Map(scope).also?.((s) => {\n\t\t\t\t\t\tfor (const [k, v] of scope) s.set(k, v);\n\t\t\t\t\t}) ?? scope,\n\t\t\t\t);\n\t\t\t\t// Update scope from block (assignments)\n\t\t\t\tthis.runBlockInScope(body, scope);\n\t\t\t\t// Skip elif/else\n\t\t\t\tlet j = idx + 1 + body.length;\n\t\t\t\twhile (j < lines.length) {\n\t\t\t\t\tconst l = lines[j]!.trim();\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.getIndent(lines[j]!) < indent ||\n\t\t\t\t\t\t(!l.startsWith(\"elif\") && !l.startsWith(\"else\"))\n\t\t\t\t\t)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tconst bk = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tj += 1 + bk.length;\n\t\t\t\t}\n\t\t\t\treturn j;\n\t\t\t}\n\n\t\t\t// Check elif / else\n\t\t\tlet j = idx + 1 + body.length;\n\t\t\twhile (j < lines.length) {\n\t\t\t\tconst el = lines[j]!;\n\t\t\t\tconst elt = el.trim();\n\t\t\t\tif (this.getIndent(el) !== indent) break;\n\n\t\t\t\tconst elifMatch = elt.match(/^elif\\s+(.+):$/);\n\t\t\t\tif (elifMatch) {\n\t\t\t\t\tconst eBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tif (pyBool(this.pyEval(elifMatch[1]!, scope))) {\n\t\t\t\t\t\tthis.runBlockInScope(eBody, scope);\n\t\t\t\t\t\tj += 1 + eBody.length;\n\t\t\t\t\t\t// Skip remaining elif/else\n\t\t\t\t\t\twhile (j < lines.length) {\n\t\t\t\t\t\t\tconst sl = lines[j]!.trim();\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tthis.getIndent(lines[j]!) !== indent ||\n\t\t\t\t\t\t\t\t(!sl.startsWith(\"elif\") && !sl.startsWith(\"else\"))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tconst sb = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\t\t\tj += 1 + sb.length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn j;\n\t\t\t\t\t}\n\t\t\t\t\tj += 1 + eBody.length;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (elt === \"else:\") {\n\t\t\t\t\tconst eBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tthis.runBlockInScope(eBody, scope);\n\t\t\t\t\treturn j + 1 + eBody.length;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn j;\n\t\t}\n\n\t\t// for\n\t\tconst forMatch = line.match(/^for\\s+(.+?)\\s+in\\s+(.+?)\\s*:$/);\n\t\tif (forMatch) {\n\t\t\tconst [, target, iterExpr] = forMatch;\n\t\t\tconst iterable = pyIter(this.pyEval(iterExpr!.trim(), scope));\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\n\t\t\t// Check for else clause\n\t\t\tlet elseBody: string[] = [];\n\t\t\tlet afterIdx = idx + 1 + body.length;\n\t\t\tif (afterIdx < lines.length && lines[afterIdx]?.trim() === \"else:\") {\n\t\t\t\telseBody = this.collectBlock(lines, afterIdx + 1, indent);\n\t\t\t\tafterIdx += 1 + elseBody.length;\n\t\t\t}\n\n\t\t\tlet broken = false;\n\t\t\tfor (const item of iterable) {\n\t\t\t\t// Unpack\n\t\t\t\tif (target!.includes(\",\")) {\n\t\t\t\t\tconst targets = target!.split(\",\").map((t) => t.trim());\n\t\t\t\t\tconst items = Array.isArray(item) ? item : [item];\n\t\t\t\t\ttargets.forEach((t, i) => scope.set(t, items[i] ?? NONE));\n\t\t\t\t} else {\n\t\t\t\t\tscope.set(target!.trim(), item);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tthis.runBlockInScope(body, scope);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (e instanceof BreakSignal) {\n\t\t\t\t\t\tbroken = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (e instanceof ContinueSignal) continue;\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!broken && elseBody.length) this.runBlockInScope(elseBody, scope);\n\t\t\treturn afterIdx;\n\t\t}\n\n\t\t// while\n\t\tconst whileMatch = line.match(/^while\\s+(.+?)\\s*:$/);\n\t\tif (whileMatch) {\n\t\t\tconst cond = whileMatch[1]!;\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tlet iterations = 0;\n\t\t\twhile (pyBool(this.pyEval(cond, scope)) && iterations++ < 100000) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.runBlockInScope(body, scope);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (e instanceof BreakSignal) break;\n\t\t\t\t\tif (e instanceof ContinueSignal) continue;\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn idx + 1 + body.length;\n\t\t}\n\n\t\t// try / except\n\t\tif (line === \"try:\") {\n\t\t\tconst tryBody = this.collectBlock(lines, idx + 1, indent);\n\t\t\tlet j = idx + 1 + tryBody.length;\n\t\t\tconst exceptClauses: Array<{ exc: string | null; body: string[] }> = [];\n\t\t\tlet finallyBody: string[] = [];\n\t\t\tlet elseBody: string[] = [];\n\n\t\t\twhile (j < lines.length) {\n\t\t\t\tconst el = lines[j]!;\n\t\t\t\tconst elt = el.trim();\n\t\t\t\tif (this.getIndent(el) !== indent) break;\n\t\t\t\tif (elt.startsWith(\"except\")) {\n\t\t\t\t\tconst excMatch = elt.match(\n\t\t\t\t\t\t/^except(?:\\s+(\\w+)(?:\\s+as\\s+(\\w+))?)?\\s*:$/,\n\t\t\t\t\t);\n\t\t\t\t\tconst excName = excMatch?.[1] ?? null;\n\t\t\t\t\tconst excAlias = excMatch?.[2];\n\t\t\t\t\tconst excBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\texceptClauses.push({ exc: excName, body: excBody });\n\t\t\t\t\tif (excAlias) scope.set(excAlias, \"\");\n\t\t\t\t\tj += 1 + excBody.length;\n\t\t\t\t} else if (elt === \"else:\") {\n\t\t\t\t\telseBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tj += 1 + elseBody.length;\n\t\t\t\t} else if (elt === \"finally:\") {\n\t\t\t\t\tfinallyBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tj += 1 + finallyBody.length;\n\t\t\t\t} else break;\n\t\t\t}\n\n\t\t\tlet _caughtErr: PyError | null = null;\n\t\t\ttry {\n\t\t\t\tthis.runBlockInScope(tryBody, scope);\n\t\t\t\tif (elseBody.length) this.runBlockInScope(elseBody, scope);\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof PyError) {\n\t\t\t\t\t_caughtErr = e;\n\t\t\t\t\tlet handled = false;\n\t\t\t\t\tfor (const clause of exceptClauses) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tclause.exc === null ||\n\t\t\t\t\t\t\tclause.exc === e.type ||\n\t\t\t\t\t\t\tclause.exc === \"Exception\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.runBlockInScope(clause.body, scope);\n\t\t\t\t\t\t\thandled = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!handled) throw e;\n\t\t\t\t} else throw e;\n\t\t\t} finally {\n\t\t\t\tif (finallyBody.length) this.runBlockInScope(finallyBody, scope);\n\t\t\t}\n\t\t\treturn j;\n\t\t}\n\n\t\t// with\n\t\tconst withMatch = line.match(/^with\\s+(.+?)\\s+as\\s+(\\w+)\\s*:$/);\n\t\tif (withMatch) {\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tscope.set(withMatch[2]!, NONE); // stub: just set to None\n\t\t\tthis.runBlockInScope(body, scope);\n\t\t\treturn idx + 1 + body.length;\n\t\t}\n\n\t\t// Augmented assignments: +=, -=, *=, /=, //=, %= **=\n\t\tconst augMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_]*)\\s*(\\+=|-=|\\*=|\\/\\/=|\\/=|%=|\\*\\*=|&=|\\|=)\\s*(.+)$/,\n\t\t);\n\t\tif (augMatch) {\n\t\t\tconst [, name, op, rhsExpr] = augMatch;\n\t\t\tconst lhs = scope.get(name!) ?? 0;\n\t\t\tconst rhs = this.pyEval(rhsExpr!, scope);\n\t\t\tlet result: PyVal;\n\t\t\tswitch (op) {\n\t\t\t\tcase \"+=\":\n\t\t\t\t\tresult =\n\t\t\t\t\t\ttypeof lhs === \"string\"\n\t\t\t\t\t\t\t? lhs + pyStr(rhs)\n\t\t\t\t\t\t\t: (lhs as number) + (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"-=\":\n\t\t\t\t\tresult = (lhs as number) - (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"*=\":\n\t\t\t\t\tresult = (lhs as number) * (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"/=\":\n\t\t\t\t\tresult = (lhs as number) / (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"//=\":\n\t\t\t\t\tresult = Math.floor((lhs as number) / (rhs as number));\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"%=\":\n\t\t\t\t\tresult = (lhs as number) % (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"**=\":\n\t\t\t\t\tresult = (lhs as number) ** (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tresult = rhs;\n\t\t\t}\n\t\t\tscope.set(name!, result);\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// Subscript assignment: obj[key] = val\n\t\tconst subAssignMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_]*)\\[(.+)\\]\\s*=\\s*(.+)$/,\n\t\t);\n\t\tif (subAssignMatch) {\n\t\t\tconst [, name, key, valExpr] = subAssignMatch;\n\t\t\tconst obj = scope.get(name!) ?? NONE;\n\t\t\tconst val: PyVal = this.pyEval(valExpr!, scope) ?? NONE;\n\t\t\tconst k: PyVal = this.pyEval(key!, scope) ?? NONE;\n\t\t\tif (Array.isArray(obj)) (obj as PyVal[])[k as number] = val;\n\t\t\telse if (isPyDict(obj)) obj.data.set(pyStr(k), val);\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// Attribute assignment: obj.attr = val\n\t\tconst attrAssignMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_.]+)\\s*=\\s*(.+)$/,\n\t\t);\n\t\tif (attrAssignMatch) {\n\t\t\tconst dotIdx = attrAssignMatch[1]!.lastIndexOf(\".\");\n\t\t\tif (dotIdx !== -1) {\n\t\t\t\tconst objExpr = attrAssignMatch[1]!.slice(0, dotIdx);\n\t\t\t\tconst attr = attrAssignMatch[1]!.slice(dotIdx + 1);\n\t\t\t\tconst val = this.pyEval(attrAssignMatch[2]!, scope);\n\t\t\t\tconst obj = this.pyEval(objExpr, scope);\n\t\t\t\tif (isPyDict(obj)) obj.data.set(attr, val);\n\t\t\t\telse if (isPyInstance(obj)) obj.attrs.set(attr, val);\n\t\t\t\treturn idx + 1;\n\t\t\t}\n\t\t}\n\n\t\t// Tuple / multi-assignment: a, b = expr\n\t\tconst multiAssignMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_,\\s]*),\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*(.+)$/,\n\t\t);\n\t\tif (multiAssignMatch) {\n\t\t\tconst rhs = this.pyEval(multiAssignMatch[3]!, scope);\n\t\t\tconst targets = line\n\t\t\t\t.split(\"=\")[0]!\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim());\n\t\t\tconst values = pyIter(rhs);\n\t\t\ttargets.forEach((t, i) => scope.set(t, values[i] ?? NONE));\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// Simple assignment: name = expr (or name: type = expr)\n\t\tconst assignMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_]*)\\s*(?::[^=]+)?\\s*=\\s*(.+)$/,\n\t\t);\n\t\tif (assignMatch) {\n\t\t\tconst [, name, rhs] = assignMatch;\n\t\t\tscope.set(name!, this.pyEval(rhs!, scope));\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// Expression statement (function call, etc.)\n\t\ttry {\n\t\t\tthis.pyEval(line, scope);\n\t\t} catch (e) {\n\t\t\tif (e instanceof PyError || e instanceof ExitSignal) throw e;\n\t\t\t// Ignore eval errors for expression statements\n\t\t}\n\t\treturn idx + 1;\n\t}\n\n\tprivate runBlockInScope(body: string[], scope: Scope): void {\n\t\tthis.execLines(body, 0, scope);\n\t}\n\n\trun(code: string): { stdout: string; stderr: string; exitCode: number } {\n\t\tconst scope = makeRootScope(this.cwd);\n\t\ttry {\n\t\t\tthis.execScript(code, scope);\n\t\t} catch (e) {\n\t\t\tif (e instanceof ExitSignal)\n\t\t\t\treturn {\n\t\t\t\t\tstdout: this.getOutput(),\n\t\t\t\t\tstderr: this.getStderr(),\n\t\t\t\t\texitCode: e.code,\n\t\t\t\t};\n\t\t\tif (e instanceof PyError) {\n\t\t\t\tthis.stderr.push(e.toString());\n\t\t\t\treturn {\n\t\t\t\t\tstdout: this.getOutput(),\n\t\t\t\t\tstderr: this.getStderr(),\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (e instanceof ReturnSignal)\n\t\t\t\treturn {\n\t\t\t\t\tstdout: this.getOutput(),\n\t\t\t\t\tstderr: this.getStderr(),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\tthis.stderr.push(`RuntimeError: ${e}`);\n\t\t\treturn {\n\t\t\t\tstdout: this.getOutput(),\n\t\t\t\tstderr: this.getStderr(),\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t\treturn { stdout: this.getOutput(), stderr: this.getStderr(), exitCode: 0 };\n\t}\n}\n\n// Polyfill: Map doesn't have .also in TS\ndeclare global {\n\tinterface Map<K, V> {\n\t\talso?: ((fn: (m: Map<K, V>) => void) => Map<K, V>) | undefined;\n\t}\n}\n\n// \u2500\u2500\u2500 command \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Virtual Python 3 interpreter command. Implements a small Python subset\n * for scripts and `-c` invocations. Requires `apt install python3` in the\n * virtual package manager to be available.\n * @category system\n * @params [\"[--version] [-c <code>] [-V] [file]\"]\n */\nexport const python3Command: ShellModule = {\n\tname: \"python3\",\n\taliases: [\"python\"],\n\tdescription: \"Python 3 interpreter (virtual)\",\n\tcategory: \"system\",\n\tparams: [\"[--version] [-c <code>] [-V] [file]\"],\n\trun: ({ args, shell, cwd }) => {\n\t\t// Require explicit installation via `apt install python3`\n\t\tif (!shell.packageManager.isInstalled(\"python3\")) {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"bash: python3: command not found\\nHint: install it with: apt install python3\\n\",\n\t\t\t\texitCode: 127,\n\t\t\t};\n\t\t}\n\t\tif (ifFlag(args, [\"--version\", \"-V\"])) {\n\t\t\treturn { stdout: `${VERSION}\\n`, exitCode: 0 };\n\t\t}\n\t\tif (ifFlag(args, [\"--version-full\"])) {\n\t\t\treturn { stdout: `${VERSION_INFO}\\n`, exitCode: 0 };\n\t\t}\n\n\t\tconst cIdx = args.indexOf(\"-c\");\n\t\tif (cIdx !== -1) {\n\t\t\tconst code = args[cIdx + 1];\n\t\t\tif (!code)\n\t\t\t\treturn {\n\t\t\t\t\tstderr: \"python3: -c requires a code argument\\n\",\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t// Handle \\n as actual newlines\n\t\t\tconst normalised = code.replace(/\\\\n/g, \"\\n\").replace(/\\\\t/g, \"\\t\");\n\t\t\tconst interp = new Interpreter(cwd);\n\t\t\tconst { stdout, stderr, exitCode } = interp.run(normalised);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || undefined,\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\tconst file = args.find((a) => !a.startsWith(\"-\"));\n\t\tif (file) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\tif (!shell.vfs.exists(filePath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `python3: can't open file '${file}': [Errno 2] No such file or directory\\n`,\n\t\t\t\t\texitCode: 2,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst code = shell.vfs.readFile(filePath);\n\t\t\tconst interp = new Interpreter(cwd);\n\t\t\tconst { stdout, stderr, exitCode } = interp.run(code);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || undefined,\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstdout: `${VERSION_INFO}\\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\\n>>> `,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const readCommand: ShellModule = {\n\tname: \"read\",\n\tdescription: \"Read a line from stdin into variables\",\n\tcategory: \"shell\",\n\tparams: [\"[-r] [-p prompt] <var...>\"],\n\trun: ({ args, stdin, env }) => {\n\t\tconst _promptIdx = args.indexOf(\"-p\");\n\t\tconst varNames = args.filter(\n\t\t\t(a, i) => a !== \"-r\" && a !== \"-p\" && args[i - 1] !== \"-p\",\n\t\t);\n\n\t\t// In non-interactive context, read from stdin pipe\n\t\tconst input = (stdin ?? \"\").split(\"\\n\")[0] ?? \"\";\n\t\tconst line = ifFlag(args, [\"-r\"])\n\t\t\t? input\n\t\t\t: input.replace(/\\\\(?:\\r?\\n|.)/g, (m) =>\n\t\t\t\t\tm[1] === \"\\n\" || m[1] === \"\\r\" ? \"\" : m[1]!,\n\t\t\t\t);\n\n\t\tif (!env) return { exitCode: 0 };\n\n\t\tif (varNames.length === 0) {\n\t\t\t// No var names: store into REPLY\n\t\t\tenv.vars.REPLY = line;\n\t\t} else if (varNames.length === 1) {\n\t\t\tenv.vars[varNames[0]!] = line;\n\t\t} else {\n\t\t\t// Split on whitespace, last var gets remainder\n\t\t\tconst parts = line.split(/\\s+/);\n\t\t\tfor (let i = 0; i < varNames.length; i++) {\n\t\t\t\tenv.vars[varNames[i]!] =\n\t\t\t\t\ti < varNames.length - 1 ? (parts[i] ?? \"\") : parts.slice(i).join(\" \");\n\t\t\t}\n\t\t}\n\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg, ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const rmCommand: ShellModule = {\n\tname: \"rm\",\n\tdescription: \"Remove files or directories\",\n\tcategory: \"files\",\n\tparams: [\"[-r|-rf] <path>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tif (args.length === 0) {\n\t\t\treturn { stderr: \"rm: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst recursive = ifFlag(args, [\"-r\", \"-rf\", \"-fr\"]);\n\t\tconst targets: string[] = [];\n\t\tfor (let index = 0; ; index += 1) {\n\t\t\tconst target = getArg(args, index, { flags: [\"-r\", \"-rf\", \"-fr\"] });\n\t\t\tif (!target) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ttargets.push(target);\n\t\t}\n\n\t\tif (targets.length === 0) {\n\t\t\treturn { stderr: \"rm: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tfor (const target of targets) {\n\t\t\tconst resolvedTarget = resolvePath(cwd, target);\n\t\t\tassertPathAccess(authUser, resolvedTarget, \"rm\");\n\t\t\tshell.vfs.remove(resolvedTarget, { recursive });\n\t\t}\n\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag, ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nexport const sedCommand: ShellModule = {\n\tname: \"sed\",\n\tdescription: \"Stream editor for filtering and transforming text\",\n\tcategory: \"text\",\n\tparams: [\"-e <expr> [file]\", \"s/pattern/replace/[g]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst inPlace = ifFlag(args, [\"-i\"]);\n\t\tconst expr =\n\t\t\t(getFlag(args, [\"-e\"]) as string | undefined) ??\n\t\t\targs.find((a) => !a.startsWith(\"-\"));\n\t\tconst fileArg = args.filter((a) => !a.startsWith(\"-\") && a !== expr).pop();\n\n\t\tif (!expr) return { stderr: \"sed: no expression\", exitCode: 1 };\n\n\t\tlet content = stdin ?? \"\";\n\t\tif (fileArg) {\n\t\t\tconst p = resolvePath(cwd, fileArg);\n\t\t\ttry {\n\t\t\t\tcontent = shell.vfs.readFile(p);\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `sed: ${fileArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Parse s/from/to/[g]\n\t\tconst sMatch = expr.match(/^s([^a-zA-Z0-9])(.+?)\\1(.*?)\\1([gi]*)$/);\n\t\tif (!sMatch)\n\t\t\treturn { stderr: `sed: unrecognized command: ${expr}`, exitCode: 1 };\n\n\t\tconst [, , from, to, flags] = sMatch;\n\t\tconst regexFlags = (flags ?? \"\").includes(\"i\")\n\t\t\t? \"gi\"\n\t\t\t: (flags ?? \"\").includes(\"g\")\n\t\t\t\t? \"g\"\n\t\t\t\t: \"\";\n\t\tlet regex: RegExp;\n\t\ttry {\n\t\t\tregex = new RegExp(from!, regexFlags || \"\");\n\t\t} catch (_e) {\n\t\t\treturn { stderr: `sed: invalid regex: ${from}`, exitCode: 1 };\n\t\t}\n\n\t\tconst result =\n\t\t\t(flags ?? \"\").includes(\"g\") || regexFlags.includes(\"g\")\n\t\t\t\t? content.replace(regex, to ?? \"\")\n\t\t\t\t: content.replace(regex, to ?? \"\");\n\n\t\tif (inPlace && fileArg) {\n\t\t\tconst p = resolvePath(cwd, fileArg);\n\t\t\tshell.writeFileAsUser(authUser, p, result);\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\treturn { stdout: result, exitCode: 0 };\n\t},\n};\n", "import type {\n CommandContext,\n CommandResult,\n ShellModule,\n} from \"../types/commands\";\nimport { expandAsync } from \"../utils/expand\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\nimport { runCommand } from \"./runtime\";\n\n/** Alias for clarity inside sh.ts */\ntype ShellContext = CommandContext;\n\n/**\n * Expand all shell forms including $(cmd) substitution.\n * Delegates to centralised expandAsync (single-quote-aware, depth-tracked).\n */\nasync function expandVars(\n\tline: string,\n\tenv: Record<string, string>,\n\tlastExit: number,\n\tctx: ShellContext,\n): Promise<string> {\n\treturn expandAsync(line, env, lastExit, (sub) =>\n\t\trunCommand(\n\t\t\tsub,\n\t\t\tctx.authUser,\n\t\t\tctx.hostname,\n\t\t\tctx.mode,\n\t\t\tctx.cwd,\n\t\t\tctx.shell,\n\t\t\tundefined,\n\t\t\tctx.env,\n\t\t).then((r) => r.stdout ?? \"\"),\n\t);\n}\n\ntype Block =\n\t| {\n\t\t\ttype: \"if\";\n\t\t\tcond: string;\n\t\t\tthen_: string[];\n\t\t\telif: Array<{ cond: string; body: string[] }>;\n\t\t\telse_: string[];\n\t }\n\t| { type: \"for\"; var: string; list: string; body: string[] }\n\t| { type: \"while\"; cond: string; body: string[] }\n\t| { type: \"cmd\"; line: string };\n\n/** Very small shell interpreter: supports if/elif/else/fi, for/do/done, while/do/done */\nfunction parseBlocks(lines: string[]): Block[] {\n\tconst blocks: Block[] = [];\n\tlet i = 0;\n\twhile (i < lines.length) {\n\t\tconst line = lines[i]!.trim();\n\t\tif (!line || line.startsWith(\"#\")) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (line.startsWith(\"if \") || line === \"if\") {\n\t\t\tconst cond = line\n\t\t\t\t.replace(/^if\\s+/, \"\")\n\t\t\t\t.replace(/;\\s*then\\s*$/, \"\")\n\t\t\t\t.trim();\n\t\t\tconst thenLines: string[] = [];\n\t\t\tconst elifBlocks: Array<{ cond: string; body: string[] }> = [];\n\t\t\tconst elseLines: string[] = [];\n\t\t\tlet section: \"then\" | \"elif\" | \"else\" = \"then\";\n\t\t\tlet elifCond = \"\";\n\t\t\ti++;\n\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"fi\") {\n\t\t\t\tconst l = lines[i]!.trim();\n\t\t\t\tif (l.startsWith(\"elif \")) {\n\t\t\t\t\tsection = \"elif\";\n\t\t\t\t\telifCond = l\n\t\t\t\t\t\t.replace(/^elif\\s+/, \"\")\n\t\t\t\t\t\t.replace(/;\\s*then\\s*$/, \"\")\n\t\t\t\t\t\t.trim();\n\t\t\t\t\telifBlocks.push({ cond: elifCond, body: [] });\n\t\t\t\t} else if (l === \"else\") {\n\t\t\t\t\tsection = \"else\";\n\t\t\t\t} else if (l !== \"then\") {\n\t\t\t\t\tif (section === \"then\") thenLines.push(l);\n\t\t\t\t\telse if (section === \"elif\" && elifBlocks.length > 0)\n\t\t\t\t\t\telifBlocks[elifBlocks.length - 1]!.body.push(l);\n\t\t\t\t\telse elseLines.push(l);\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tblocks.push({\n\t\t\t\ttype: \"if\",\n\t\t\t\tcond,\n\t\t\t\tthen_: thenLines,\n\t\t\t\telif: elifBlocks,\n\t\t\t\telse_: elseLines,\n\t\t\t});\n\t\t} else if (line.startsWith(\"for \")) {\n\t\t\tconst m = line.match(/^for\\s+(\\w+)\\s+in\\s+(.+?)(?:\\s*;\\s*do)?$/);\n\t\t\tif (m) {\n\t\t\t\tconst body: string[] = [];\n\t\t\t\ti++;\n\t\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"done\") {\n\t\t\t\t\tconst l = lines[i]!.trim().replace(/^do\\s+/, \"\");\n\t\t\t\t\tif (l && l !== \"do\") body.push(l);\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\tblocks.push({ type: \"for\", var: m[1]!, list: m[2]!, body });\n\t\t\t} else {\n\t\t\t\tblocks.push({ type: \"cmd\", line });\n\t\t\t}\n\t\t} else if (line.startsWith(\"while \")) {\n\t\t\tconst cond = line\n\t\t\t\t.replace(/^while\\s+/, \"\")\n\t\t\t\t.replace(/;\\s*do\\s*$/, \"\")\n\t\t\t\t.trim();\n\t\t\tconst body: string[] = [];\n\t\t\ti++;\n\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"done\") {\n\t\t\t\tconst l = lines[i]!.trim().replace(/^do\\s+/, \"\");\n\t\t\t\tif (l && l !== \"do\") body.push(l);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tblocks.push({ type: \"while\", cond, body });\n\t\t} else {\n\t\t\tblocks.push({ type: \"cmd\", line });\n\t\t}\n\t\ti++;\n\t}\n\treturn blocks;\n}\n\nasync function evalCondition(\n\tcond: string,\n\tctx: CommandContext,\n): Promise<boolean> {\n\tconst expanded = await expandVars(\n\t\tcond,\n\t\tctx.env.vars,\n\t\tctx.env.lastExitCode,\n\t\tctx,\n\t);\n\t// test -f / test -d / [ ... ]\n\tconst testMatch = expanded.match(/^\\[?\\s*(.+?)\\s*\\]?$/);\n\tif (testMatch) {\n\t\tconst expr = testMatch[1]!;\n\t\t// -f file\n\t\tconst fTest = expr.match(/^-([fdeznr])\\s+(.+)$/);\n\t\tif (fTest) {\n\t\t\tconst [, flag, arg] = fTest;\n\t\t\tconst p = resolvePath(ctx.cwd, arg!);\n\t\t\tif (flag === \"f\")\n\t\t\t\treturn ctx.shell.vfs.exists(p) && ctx.shell.vfs.stat(p).type === \"file\";\n\t\t\tif (flag === \"d\")\n\t\t\t\treturn (\n\t\t\t\t\tctx.shell.vfs.exists(p) && ctx.shell.vfs.stat(p).type === \"directory\"\n\t\t\t\t);\n\t\t\tif (flag === \"e\") return ctx.shell.vfs.exists(p);\n\t\t\tif (flag === \"z\") return (arg ?? \"\").length === 0;\n\t\t\tif (flag === \"n\") return (arg ?? \"\").length > 0;\n\t\t}\n\t\t// string comparison\n\t\tconst cmpMatch = expr.match(/^\"?([^\"]*)\"?\\s*(==|!=|=|<|>)\\s*\"?([^\"]*)\"?$/);\n\t\tif (cmpMatch) {\n\t\t\tconst [, a, op, b] = cmpMatch;\n\t\t\tif (op === \"==\" || op === \"=\") return a === b;\n\t\t\tif (op === \"!=\") return a !== b;\n\t\t}\n\t\t// numeric\n\t\tconst numMatch = expr.match(/^(\\S+)\\s+(-eq|-ne|-lt|-le|-gt|-ge)\\s+(\\S+)$/);\n\t\tif (numMatch) {\n\t\t\tconst [, a, op, b] = numMatch;\n\t\t\tconst na = Number(a),\n\t\t\t\tnb = Number(b);\n\t\t\tif (op === \"-eq\") return na === nb;\n\t\t\tif (op === \"-ne\") return na !== nb;\n\t\t\tif (op === \"-lt\") return na < nb;\n\t\t\tif (op === \"-le\") return na <= nb;\n\t\t\tif (op === \"-gt\") return na > nb;\n\t\t\tif (op === \"-ge\") return na >= nb;\n\t\t}\n\t}\n\t// fallback: run command and check exit code\n\tconst r = await runCommand(\n\t\texpanded,\n\t\tctx.authUser,\n\t\tctx.hostname,\n\t\tctx.mode,\n\t\tctx.cwd,\n\t\tctx.shell,\n\t\tundefined,\n\t\tctx.env,\n\t);\n\treturn (r.exitCode ?? 0) === 0;\n}\n\nasync function runBlocks(\n\tblocks: Block[],\n\tctx: CommandContext,\n): Promise<CommandResult> {\n\tlet lastResult: CommandResult = { exitCode: 0 };\n\tlet output = \"\";\n\n\tfor (const block of blocks) {\n\t\tif (block.type === \"cmd\") {\n\t\t\tconst expanded = await expandVars(\n\t\t\t\tblock.line,\n\t\t\t\tctx.env.vars,\n\t\t\t\tctx.env.lastExitCode,\n\t\t\t\tctx,\n\t\t\t);\n\n\t\t\t// Bare VAR=val assignment(s) \u2014 handle before dispatching to runCommand\n\t\t\tconst assignRe = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)/;\n\t\t\tconst tokens = expanded.trim().split(/\\s+/);\n\t\t\tif (tokens.length > 0 && assignRe.test(tokens[0]!)) {\n\t\t\t\tconst allAssign = tokens.every((t) => assignRe.test(t));\n\t\t\t\tif (allAssign) {\n\t\t\t\t\tfor (const tok of tokens) {\n\t\t\t\t\t\tconst m = tok.match(assignRe)!;\n\t\t\t\t\t\tctx.env.vars[m[1]!] = m[2]!;\n\t\t\t\t\t}\n\t\t\t\t\tctx.env.lastExitCode = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst r = await runCommand(\n\t\t\t\texpanded,\n\t\t\t\tctx.authUser,\n\t\t\t\tctx.hostname,\n\t\t\t\tctx.mode,\n\t\t\t\tctx.cwd,\n\t\t\t\tctx.shell,\n\t\t\t\tundefined,\n\t\t\t\tctx.env,\n\t\t\t);\n\t\t\tctx.env.lastExitCode = r.exitCode ?? 0;\n\t\t\tif (r.stdout) output += `${r.stdout}\\n`;\n\t\t\tif (r.stderr) return { ...r, stdout: output.trim() };\n\t\t\tlastResult = r;\n\t\t} else if (block.type === \"if\") {\n\t\t\tlet ran = false;\n\t\t\tif (await evalCondition(block.cond, ctx)) {\n\t\t\t\tconst sub = await runBlocks(parseBlocks(block.then_), ctx);\n\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\tran = true;\n\t\t\t} else {\n\t\t\t\tfor (const elif of block.elif) {\n\t\t\t\t\tif (await evalCondition(elif.cond, ctx)) {\n\t\t\t\t\t\tconst sub = await runBlocks(parseBlocks(elif.body), ctx);\n\t\t\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\t\t\tran = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!ran && block.else_.length > 0) {\n\t\t\t\t\tconst sub = await runBlocks(parseBlocks(block.else_), ctx);\n\t\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (block.type === \"for\") {\n\t\t\tconst listExpanded = await expandVars(\n\t\t\t\tblock.list,\n\t\t\t\tctx.env.vars,\n\t\t\t\tctx.env.lastExitCode,\n\t\t\t\tctx,\n\t\t\t);\n\t\t\tconst items = listExpanded.trim().split(/\\s+/);\n\t\t\tfor (const item of items) {\n\t\t\t\tctx.env.vars[block.var] = item;\n\t\t\t\tconst sub = await runBlocks(parseBlocks(block.body), ctx);\n\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\tif (sub.closeSession) return sub;\n\t\t\t}\n\t\t} else if (block.type === \"while\") {\n\t\t\tlet iterations = 0;\n\t\t\twhile (iterations < 1000 && (await evalCondition(block.cond, ctx))) {\n\t\t\t\tconst sub = await runBlocks(parseBlocks(block.body), ctx);\n\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\tif (sub.closeSession) return sub;\n\t\t\t\titerations++;\n\t\t\t}\n\t\t}\n\t}\n\treturn { ...lastResult, stdout: output.trim() || lastResult.stdout };\n}\n\nexport const shCommand: ShellModule = {\n\tname: \"sh\",\n\taliases: [\"bash\"],\n\tdescription: \"Execute shell script or command\",\n\tcategory: \"shell\",\n\tparams: [\"-c <script>\", \"[<file>]\"],\n\trun: async (ctx: CommandContext) => {\n\t\tconst { args, shell, cwd } = ctx;\n\n\t\t// sh -c \"inline script\"\n\t\tif (ifFlag(args, \"-c\")) {\n\t\t\tconst script = args[args.indexOf(\"-c\") + 1] ?? \"\";\n\t\t\tif (!script) return { stderr: \"sh: -c requires a script\", exitCode: 1 };\n\t\t\tconst lines = script\n\t\t\t\t.split(/[;\\n]/)\n\t\t\t\t.map((l) => l.trim())\n\t\t\t\t.filter((l) => l && !l.startsWith(\"#\"));\n\t\t\tconst blocks = parseBlocks(lines);\n\t\t\treturn runBlocks(blocks, ctx);\n\t\t}\n\n\t\t// sh <file>\n\t\tconst fileArg = args[0];\n\t\tif (fileArg) {\n\t\t\tconst p = resolvePath(cwd, fileArg);\n\t\t\tif (!shell.vfs.exists(p))\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `sh: ${fileArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\tconst content = shell.vfs.readFile(p);\n\t\t\tconst lines = content\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((l) => l.trim())\n\t\t\t\t.filter((l) => l && !l.startsWith(\"#\"));\n\t\t\tconst blocks = parseBlocks(lines);\n\t\t\treturn runBlocks(blocks, ctx);\n\t\t}\n\n\t\treturn {\n\t\t\tstderr: \"sh: invalid usage. Use: sh -c 'cmd' or sh <file>\",\n\t\t\texitCode: 1,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const shiftCommand: ShellModule = {\n\tname: \"shift\",\n\tdescription: \"Shift positional parameters\",\n\tcategory: \"shell\",\n\tparams: [\"[n]\"],\n\t// shift is meaningful only inside sh scripts where positional params exist.\n\t// In the current impl, positional params ($1 $2 \u2026) aren't tracked in env by default.\n\t// We store them under env.vars.__argv and shift there if present.\n\trun: ({ args, env }) => {\n\t\tif (!env) return { exitCode: 0 };\n\t\tconst n = parseInt(args[0] ?? \"1\", 10) || 1;\n\t\tconst argv = env.vars.__argv?.split(\"\\x00\").filter(Boolean) ?? [];\n\t\tenv.vars.__argv = argv.slice(n).join(\"\\x00\");\n\t\t// Update $1 $2 \u2026 in env\n\t\tconst shifted = argv.slice(n);\n\t\tfor (let i = 1; i <= 9; i++) {\n\t\t\tenv.vars[String(i)] = shifted[i - 1] ?? \"\";\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n\nexport const trapCommand: ShellModule = {\n\tname: \"trap\",\n\tdescription: \"Trap signals and events\",\n\tcategory: \"shell\",\n\tparams: [\"[action] [signal...]\"],\n\t// Store trap handlers in env for EXIT signal support\n\trun: ({ args, env }) => {\n\t\tif (!env || args.length === 0) return { exitCode: 0 };\n\t\tconst action = args[0] ?? \"\";\n\t\tconst signals = args.slice(1);\n\t\tfor (const sig of signals) {\n\t\t\tenv.vars[`__trap_${sig.toUpperCase()}`] = action;\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n\nexport const returnCommand: ShellModule = {\n\tname: \"return\",\n\tdescription: \"Return from a shell function\",\n\tcategory: \"shell\",\n\tparams: [\"[n]\"],\n\trun: ({ args, env }) => {\n\t\tconst code = parseInt(args[0] ?? \"0\", 10);\n\t\tif (env) env.lastExitCode = code;\n\t\t// Signal the caller via exitCode; function return is handled by runBlocks\n\t\treturn { exitCode: code };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const sleepCommand: ShellModule = {\n\tname: \"sleep\",\n\tdescription: \"Delay execution\",\n\tcategory: \"system\",\n\tparams: [\"<seconds>\"],\n\trun: async ({ args }) => {\n\t\tconst secs = parseFloat(args[0] ?? \"1\");\n\t\tif (Number.isNaN(secs) || secs < 0)\n\t\t\treturn { stderr: \"sleep: invalid time\", exitCode: 1 };\n\t\tawait new Promise((r) => setTimeout(r, secs * 1000));\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const sortCommand: ShellModule = {\n\tname: \"sort\",\n\tdescription: \"Sort lines of text\",\n\tcategory: \"text\",\n\tparams: [\"[-r] [-n] [-u] [-k <col>] [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst reverse = ifFlag(args, [\"-r\"]);\n\t\tconst numeric = ifFlag(args, [\"-n\"]);\n\t\tconst unique = ifFlag(args, [\"-u\"]);\n\t\tconst files = args.filter((a) => !a.startsWith(\"-\"));\n\n\t\tconst getContent = (): string => {\n\t\t\tif (files.length > 0) {\n\t\t\t\treturn files\n\t\t\t\t\t.map((f) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tassertPathAccess(authUser, resolvePath(cwd, f), \"sort\");\n\t\t\t\t\t\t\treturn shell.vfs.readFile(resolvePath(cwd, f));\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t}\n\t\t\treturn stdin ?? \"\";\n\t\t};\n\n\t\tconst lines = getContent().split(\"\\n\").filter(Boolean);\n\t\tconst sorted = [...lines].sort((a, b) => {\n\t\t\tif (numeric) return Number(a) - Number(b);\n\t\t\treturn a.localeCompare(b);\n\t\t});\n\t\tconst result = reverse ? sorted.reverse() : sorted;\n\t\tconst out = unique ? [...new Set(result)] : result;\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { resolvePath } from \"./helpers\";\nimport { runCommand } from \"./runtime\";\n\nexport const sourceCommand: ShellModule = {\n\tname: \"source\",\n\taliases: [\".\"],\n\tdescription: \"Execute commands from a file in the current shell environment\",\n\tcategory: \"shell\",\n\tparams: [\"<file> [args...]\"],\n\trun: async ({ args, authUser, hostname, cwd, shell, env }) => {\n\t\tconst fileArg = args[0];\n\t\tif (!fileArg) {\n\t\t\treturn { stderr: \"source: missing filename\", exitCode: 1 };\n\t\t}\n\n\t\tconst filePath = resolvePath(cwd, fileArg);\n\t\tif (!shell.vfs.exists(filePath)) {\n\t\t\treturn {\n\t\t\t\tstderr: `source: ${fileArg}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\n\t\tconst content = shell.vfs.readFile(filePath);\n\t\tlet lastExitCode = 0;\n\n\t\tfor (const line of content.split(\"\\n\")) {\n\t\t\tconst l = line.trim();\n\t\t\tif (!l || l.startsWith(\"#\")) continue;\n\t\t\tconst result = await runCommand(\n\t\t\t\tl,\n\t\t\t\tauthUser,\n\t\t\t\thostname,\n\t\t\t\t\"shell\",\n\t\t\t\tcwd,\n\t\t\t\tshell,\n\t\t\t\tundefined,\n\t\t\t\tenv,\n\t\t\t);\n\t\t\tlastExitCode = result.exitCode ?? 0;\n\t\t\tif (result.closeSession || result.switchUser) return result;\n\t\t}\n\n\t\treturn { exitCode: lastExitCode };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg } from \"./command-helpers\";\n\nexport const suCommand: ShellModule = {\n\tname: \"su\",\n\tdescription: \"Switch user\",\n\tcategory: \"users\",\n\tparams: [\"- <username>\"],\n\trun: ({ authUser, shell, args }) => {\n\t\tconst users = shell.users!;\n\t\tconst targetUser = getArg(args, 0, { flags: [\"-\"] });\n\n\t\tif (!targetUser) {\n\t\t\treturn { stderr: \"su: missing username\", exitCode: 1 };\n\t\t}\n\n\t\tif (!users.isSudoer(authUser) && authUser !== \"root\") {\n\t\t\treturn { stderr: \"su: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tif (\n\t\t\t!users.verifyPassword(targetUser, getArg(args, 1) ?? \"\") &&\n\t\t\tauthUser !== \"root\"\n\t\t) {\n\t\t\treturn { stderr: \"su: authentication failure\", exitCode: 1 };\n\t\t}\n\n\t\treturn {\n\t\t\tswitchUser: targetUser,\n\t\t\tnextCwd: `/home/${targetUser}`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { parseArgs } from \"./command-helpers\";\nimport { runCommand } from \"./runtime\";\n\nfunction parseSudoArgs(args: string[]): {\n\ttargetUser: string;\n\tloginShell: boolean;\n\tcommandLine: string | null;\n} {\n\tconst { flags, flagsWithValues, positionals } = parseArgs(args, {\n\t\tflags: [\"-i\", \"-S\"],\n\t\tflagsWithValue: [\"-u\", \"--user\"],\n\t});\n\n\tconst loginShell = flags.has(\"-i\");\n\tconst targetUser =\n\t\tflagsWithValues.get(\"-u\") || flagsWithValues.get(\"--user\") || \"root\";\n\tconst commandLine = positionals.length > 0 ? positionals.join(\" \") : null;\n\n\treturn { targetUser, loginShell, commandLine };\n}\nexport const sudoCommand: ShellModule = {\n\tname: \"sudo\",\n\tdescription: \"Execute as superuser\",\n\tcategory: \"users\",\n\tparams: [\"<command...>\"],\n\trun: async ({ authUser, hostname, mode, cwd, shell, args }) => {\n\t\tconst { targetUser, loginShell, commandLine } = parseSudoArgs(args);\n\n\t\tif (authUser !== \"root\" && !shell.users.isSudoer(authUser)) {\n\t\t\treturn { stderr: \"sudo: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tconst effectiveUser = targetUser || \"root\";\n\t\tconst prompt = `[sudo] password for ${authUser}: `;\n\n\t\tif (authUser === \"root\") {\n\t\t\tif (!commandLine && loginShell) {\n\t\t\t\treturn {\n\t\t\t\t\tswitchUser: effectiveUser,\n\t\t\t\t\tnextCwd: `/home/${effectiveUser}`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (!commandLine) {\n\t\t\t\treturn { stderr: \"sudo: missing command\", exitCode: 1 };\n\t\t\t}\n\n\t\t\treturn runCommand(\n\t\t\t\tcommandLine,\n\t\t\t\teffectiveUser,\n\t\t\t\thostname,\n\t\t\t\tmode,\n\t\t\t\tloginShell ? `/home/${effectiveUser}` : cwd,\n\t\t\t\tshell,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tsudoChallenge: {\n\t\t\t\tusername: authUser,\n\t\t\t\ttargetUser: effectiveUser,\n\t\t\t\tcommandLine,\n\t\t\t\tloginShell,\n\t\t\t\tprompt,\n\t\t\t},\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const tailCommand: ShellModule = {\n\tname: \"tail\",\n\tdescription: \"Output last lines\",\n\tcategory: \"text\",\n\tparams: [\"[-n <lines>] [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst nArg = getFlag(args, [\"-n\"]);\n\t\tconst n = typeof nArg === \"string\" ? parseInt(nArg, 10) : 10;\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\") && a !== nArg);\n\n\t\tconst take = (content: string) => {\n\t\t\tconst lines = content.split(\"\\n\");\n\t\t\treturn lines.slice(Math.max(0, lines.length - n)).join(\"\\n\");\n\t\t};\n\n\t\tif (positionals.length === 0) {\n\t\t\treturn { stdout: take(stdin ?? \"\"), exitCode: 0 };\n\t\t}\n\n\t\tconst results: string[] = [];\n\t\tfor (const file of positionals) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\ttry {\n\t\t\t\tassertPathAccess(authUser, filePath, \"tail\");\n\t\t\t\tresults.push(take(shell.vfs.readFile(filePath)));\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `tail: ${file}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn { stdout: results.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nexport const tarCommand: ShellModule = {\n\tname: \"tar\",\n\tdescription: \"Archive utility\",\n\tcategory: \"archive\",\n\tparams: [\"[-czf|-xzf|-tf] <archive> [files...]\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst create = ifFlag(args, [\"-c\"]);\n\t\tconst extract = ifFlag(args, [\"-x\"]);\n\t\tconst list = ifFlag(args, [\"-t\"]);\n\t\tconst fFlag = args.findIndex((a) => a.includes(\"f\"));\n\t\tconst archiveName =\n\t\t\tfFlag !== -1\n\t\t\t\t? args[fFlag + 1]\n\t\t\t\t: args.find(\n\t\t\t\t\t\t(a) =>\n\t\t\t\t\t\t\ta.endsWith(\".tar\") || a.endsWith(\".tar.gz\") || a.endsWith(\".tgz\"),\n\t\t\t\t\t);\n\n\t\tif (!archiveName)\n\t\t\treturn { stderr: \"tar: no archive specified\", exitCode: 1 };\n\t\tconst archivePath = resolvePath(cwd, archiveName);\n\n\t\tif (create) {\n\t\t\tconst fileArgs = args.filter(\n\t\t\t\t(a) => !a.startsWith(\"-\") && a !== archiveName,\n\t\t\t);\n\t\t\tconst entries: Record<string, string> = {};\n\t\t\tfor (const f of fileArgs) {\n\t\t\t\tconst p = resolvePath(cwd, f);\n\t\t\t\ttry {\n\t\t\t\t\tconst stat = shell.vfs.stat(p);\n\t\t\t\t\tif (stat.type === \"file\") entries[f] = shell.vfs.readFile(p);\n\t\t\t\t\telse {\n\t\t\t\t\t\tconst walk = (dir: string, prefix: string) => {\n\t\t\t\t\t\t\tfor (const e of shell.vfs.list(dir)) {\n\t\t\t\t\t\t\t\tconst full = `${dir}/${e}`,\n\t\t\t\t\t\t\t\t\trel = `${prefix}/${e}`;\n\t\t\t\t\t\t\t\tconst s = shell.vfs.stat(full);\n\t\t\t\t\t\t\t\tif (s.type === \"file\") entries[rel] = shell.vfs.readFile(full);\n\t\t\t\t\t\t\t\telse walk(full, rel);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\twalk(p, f);\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `tar: ${f}: No such file or directory`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\tshell.writeFileAsUser(authUser, archivePath, JSON.stringify(entries));\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\tif (list || extract) {\n\t\t\tlet entries: Record<string, string>;\n\t\t\ttry {\n\t\t\t\tentries = JSON.parse(shell.vfs.readFile(archivePath));\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `tar: ${archiveName}: cannot open archive`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (list) return { stdout: Object.keys(entries).join(\"\\n\"), exitCode: 0 };\n\t\t\tfor (const [name, content] of Object.entries(entries)) {\n\t\t\t\tshell.writeFileAsUser(authUser, resolvePath(cwd, name), content);\n\t\t\t}\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\treturn { stderr: \"tar: must specify -c, -x, or -t\", exitCode: 1 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nexport const teeCommand: ShellModule = {\n\tname: \"tee\",\n\tdescription: \"Read stdin, write to stdout and files\",\n\tcategory: \"text\",\n\tparams: [\"[-a] <file...>\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst append = ifFlag(args, [\"-a\"]);\n\t\tconst files = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst input = stdin ?? \"\";\n\t\tfor (const f of files) {\n\t\t\tconst p = resolvePath(cwd, f);\n\t\t\tif (append) {\n\t\t\t\tconst existing = (() => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn shell.vfs.readFile(p);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t\tshell.writeFileAsUser(authUser, p, existing + input);\n\t\t\t} else {\n\t\t\t\tshell.writeFileAsUser(authUser, p, input);\n\t\t\t}\n\t\t}\n\t\treturn { stdout: input, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Evaluate a POSIX test expression.\n * Supports: -f, -d, -e, -r, -w, -x, -s, -z, -n,\n * string =, !=, numeric -eq -ne -lt -le -gt -ge,\n * ! (negate), -a (and), -o (or).\n */\nfunction evalTest(\n\ttokens: string[],\n\tshell: import(\"../VirtualShell\").VirtualShell,\n\tcwd: string,\n): boolean {\n\t// When called via [ command, ] is the last arg \u2014 strip it\n\t// When called via test command, no brackets present\n\tif (tokens[tokens.length - 1] === \"]\") {\n\t\ttokens = tokens.slice(0, -1);\n\t}\n\t// Also strip leading [ if present (shouldn't normally happen but be safe)\n\tif (tokens[0] === \"[\") {\n\t\ttokens = tokens.slice(1);\n\t}\n\n\tif (tokens.length === 0) return false;\n\n\t// Negation\n\tif (tokens[0] === \"!\") return !evalTest(tokens.slice(1), shell, cwd);\n\n\t// Boolean -a / -o (simple left-right, no precedence)\n\tconst andIdx = tokens.indexOf(\"-a\");\n\tif (andIdx !== -1) {\n\t\treturn (\n\t\t\tevalTest(tokens.slice(0, andIdx), shell, cwd) &&\n\t\t\tevalTest(tokens.slice(andIdx + 1), shell, cwd)\n\t\t);\n\t}\n\tconst orIdx = tokens.indexOf(\"-o\");\n\tif (orIdx !== -1) {\n\t\treturn (\n\t\t\tevalTest(tokens.slice(0, orIdx), shell, cwd) ||\n\t\t\tevalTest(tokens.slice(orIdx + 1), shell, cwd)\n\t\t);\n\t}\n\n\t// Unary file tests\n\tif (tokens.length === 2) {\n\t\tconst [flag, operand = \"\"] = tokens;\n\t\tconst resolvePath = (p: string) =>\n\t\t\tp.startsWith(\"/\") ? p : `${cwd}/${p}`.replace(/\\/+/g, \"/\");\n\t\tconst path = resolvePath(operand);\n\n\t\tswitch (flag) {\n\t\t\tcase \"-e\":\n\t\t\t\treturn shell.vfs.exists(path);\n\t\t\tcase \"-f\":\n\t\t\t\treturn shell.vfs.exists(path) && shell.vfs.stat(path).type === \"file\";\n\t\t\tcase \"-d\":\n\t\t\t\treturn (\n\t\t\t\t\tshell.vfs.exists(path) && shell.vfs.stat(path).type === \"directory\"\n\t\t\t\t);\n\t\t\tcase \"-r\":\n\t\t\t\treturn shell.vfs.exists(path); // all readable in virtual env\n\t\t\tcase \"-w\":\n\t\t\t\treturn shell.vfs.exists(path);\n\t\t\tcase \"-x\":\n\t\t\t\treturn shell.vfs.exists(path) && !!(shell.vfs.stat(path).mode & 0o111);\n\t\t\tcase \"-s\":\n\t\t\t\treturn (\n\t\t\t\t\tshell.vfs.exists(path) &&\n\t\t\t\t\tshell.vfs.stat(path).type === \"file\" &&\n\t\t\t\t\t(shell.vfs.stat(path) as import(\"../types/vfs\").VfsFileNode).size > 0\n\t\t\t\t);\n\t\t\tcase \"-z\":\n\t\t\t\treturn operand.length === 0;\n\t\t\tcase \"-n\":\n\t\t\t\treturn operand.length > 0;\n\t\t\tcase \"-L\":\n\t\t\t\treturn shell.vfs.isSymlink(path);\n\t\t}\n\t}\n\n\t// Binary comparisons\n\tif (tokens.length === 3) {\n\t\tconst [left = \"\", op, right = \"\"] = tokens;\n\t\tconst leftN = Number(left);\n\t\tconst rightN = Number(right);\n\n\t\tswitch (op) {\n\t\t\t// String\n\t\t\tcase \"=\":\n\t\t\tcase \"==\":\n\t\t\t\treturn left === right;\n\t\t\tcase \"!=\":\n\t\t\t\treturn left !== right;\n\t\t\tcase \"<\":\n\t\t\t\treturn left < right;\n\t\t\tcase \">\":\n\t\t\t\treturn left > right;\n\t\t\t// Numeric\n\t\t\tcase \"-eq\":\n\t\t\t\treturn leftN === rightN;\n\t\t\tcase \"-ne\":\n\t\t\t\treturn leftN !== rightN;\n\t\t\tcase \"-lt\":\n\t\t\t\treturn leftN < rightN;\n\t\t\tcase \"-le\":\n\t\t\t\treturn leftN <= rightN;\n\t\t\tcase \"-gt\":\n\t\t\t\treturn leftN > rightN;\n\t\t\tcase \"-ge\":\n\t\t\t\treturn leftN >= rightN;\n\t\t}\n\t}\n\n\t// Single string (truthy if non-empty)\n\tif (tokens.length === 1) return (tokens[0] ?? \"\").length > 0;\n\n\treturn false;\n}\n\nexport const testCommand: ShellModule = {\n\tname: \"test\",\n\taliases: [\"[\"],\n\tdescription: \"Evaluate conditional expression\",\n\tcategory: \"shell\",\n\tparams: [\"<expression>\"],\n\trun: ({ args, shell, cwd }) => {\n\t\ttry {\n\t\t\tconst result = evalTest([...args], shell, cwd);\n\t\t\treturn { exitCode: result ? 0 : 1 };\n\t\t} catch {\n\t\t\treturn { stderr: \"test: malformed expression\", exitCode: 2 };\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const touchCommand: ShellModule = {\n\tname: \"touch\",\n\tdescription: \"Create or update files\",\n\tcategory: \"files\",\n\tparams: [\"<file>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tif (args.length === 0) {\n\t\t\treturn { stderr: \"touch: missing file operand\", exitCode: 1 };\n\t\t}\n\n\t\tfor (const file of args) {\n\t\t\tconst target = resolvePath(cwd, file);\n\t\t\tassertPathAccess(authUser, target, \"touch\");\n\t\t\tif (!shell.vfs.exists(target)) {\n\t\t\t\tshell.writeFileAsUser(authUser, target, \"\");\n\t\t\t}\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const trCommand: ShellModule = {\n\tname: \"tr\",\n\tdescription: \"Translate or delete characters\",\n\tcategory: \"text\",\n\tparams: [\"[-d] <set1> [set2]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst del = ifFlag(args, [\"-d\"]);\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst set1 = positionals[0] ?? \"\";\n\t\tconst set2 = positionals[1] ?? \"\";\n\t\tlet input = stdin ?? \"\";\n\t\tif (del) {\n\t\t\tfor (const c of set1) input = input.split(c).join(\"\");\n\t\t} else if (set2) {\n\t\t\tfor (let i = 0; i < set1.length; i++) {\n\t\t\t\tinput = input\n\t\t\t\t\t.split(set1[i]!)\n\t\t\t\t\t.join(set2[i] ?? set2[set2.length - 1] ?? \"\");\n\t\t\t}\n\t\t}\n\t\treturn { stdout: input, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const treeCommand: ShellModule = {\n\tname: \"tree\",\n\tdescription: \"Display directory tree\",\n\tcategory: \"navigation\",\n\tparams: [\"[path]\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst target = resolvePath(cwd, getArg(args, 0) ?? cwd);\n\t\tassertPathAccess(authUser, target, \"tree\");\n\t\treturn { stdout: shell.vfs.tree(target), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const trueCommand: ShellModule = {\n\tname: \"true\",\n\tdescription: \"Return success exit code\",\n\tcategory: \"shell\",\n\tparams: [],\n\trun: () => ({ exitCode: 0 }),\n};\n\nexport const falseCommand: ShellModule = {\n\tname: \"false\",\n\tdescription: \"Return failure exit code\",\n\tcategory: \"shell\",\n\tparams: [],\n\trun: () => ({ exitCode: 1 }),\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { resolveModule } from \"./registry\";\n\nexport const typeCommand: ShellModule = {\n\tname: \"type\",\n\tdescription: \"Describe how a command would be interpreted\",\n\tcategory: \"shell\",\n\tparams: [\"<command...>\"],\n\trun: ({ args, shell, env }) => {\n\t\tif (args.length === 0)\n\t\t\treturn { stderr: \"type: missing argument\", exitCode: 1 };\n\n\t\tconst pathDirs = (env?.vars?.PATH ?? \"/usr/local/bin:/usr/bin:/bin\").split(\n\t\t\t\":\",\n\t\t);\n\t\tconst lines: string[] = [];\n\t\tlet exitCode = 0;\n\n\t\tfor (const name of args) {\n\t\t\tif (resolveModule(name)) {\n\t\t\t\tlines.push(`${name} is a shell builtin`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet found = false;\n\t\t\tfor (const dir of pathDirs) {\n\t\t\t\tconst full = `${dir}/${name}`;\n\t\t\t\tif (shell.vfs.exists(full)) {\n\t\t\t\t\tlines.push(`${name} is ${full}`);\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!found) {\n\t\t\t\tlines.push(`${name}: not found`);\n\t\t\t\texitCode = 1;\n\t\t\t}\n\t\t}\n\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const unameCommand: ShellModule = {\n\tname: \"uname\",\n\tdescription: \"Print system information\",\n\tcategory: \"system\",\n\tparams: [\"[-a] [-s] [-r] [-m]\"],\n\trun: ({ shell, args }) => {\n\t\tconst all = ifFlag(args, [\"-a\"]);\n\t\tconst sysname = \"Linux\";\n\t\tconst release = shell.properties?.kernel ?? \"5.15.0\";\n\t\tconst machine = shell.properties?.arch ?? \"x86_64\";\n\t\tconst hostname = shell.hostname;\n\t\tif (all)\n\t\t\treturn {\n\t\t\t\tstdout: `${sysname} ${hostname} ${release} #1 SMP ${machine} GNU/Linux`,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\tif (ifFlag(args, [\"-r\"])) return { stdout: release, exitCode: 0 };\n\t\tif (ifFlag(args, [\"-m\"])) return { stdout: machine, exitCode: 0 };\n\t\treturn { stdout: sysname, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const uniqCommand: ShellModule = {\n\tname: \"uniq\",\n\tdescription: \"Report or filter out repeated lines\",\n\tcategory: \"text\",\n\tparams: [\"[-c] [-d] [-u] [file]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst count = ifFlag(args, [\"-c\"]);\n\t\tconst dupOnly = ifFlag(args, [\"-d\"]);\n\t\tconst uniqOnly = ifFlag(args, [\"-u\"]);\n\t\tconst lines = (stdin ?? \"\").split(\"\\n\");\n\t\tconst out: string[] = [];\n\t\tlet i = 0;\n\t\twhile (i < lines.length) {\n\t\t\tlet j = i;\n\t\t\twhile (j < lines.length && lines[j] === lines[i]) j++;\n\t\t\tconst n = j - i;\n\t\t\tconst line = lines[i]!;\n\t\t\tif (dupOnly && n === 1) {\n\t\t\t\ti = j;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (uniqOnly && n > 1) {\n\t\t\t\ti = j;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tout.push(count ? `${String(n).padStart(4)} ${line}` : line);\n\t\t\ti = j;\n\t\t}\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const unsetCommand: ShellModule = {\n\tname: \"unset\",\n\tdescription: \"Remove shell variable\",\n\tcategory: \"shell\",\n\tparams: [\"<VAR>\"],\n\trun: ({ args, env }) => {\n\t\tfor (const name of args) delete env.vars[name];\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const uptimeCommand: ShellModule = {\n\tname: \"uptime\",\n\tdescription: \"Tell how long the system has been running\",\n\tcategory: \"system\",\n\tparams: [\"[-p] [-s]\"],\n\trun: ({ args, shell }) => {\n\t\tconst pretty = ifFlag(args, [\"-p\"]);\n\t\tconst since = ifFlag(args, [\"-s\"]);\n\n\t\tconst uptimeSec = Math.floor((Date.now() - shell.startTime) / 1000);\n\t\tconst days = Math.floor(uptimeSec / 86400);\n\t\tconst hours = Math.floor((uptimeSec % 86400) / 3600);\n\t\tconst mins = Math.floor((uptimeSec % 3600) / 60);\n\n\t\tif (since) {\n\t\t\treturn {\n\t\t\t\tstdout: new Date(shell.startTime)\n\t\t\t\t\t.toISOString()\n\t\t\t\t\t.slice(0, 19)\n\t\t\t\t\t.replace(\"T\", \" \"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tif (pretty) {\n\t\t\tconst parts: string[] = [];\n\t\t\tif (days > 0) parts.push(`${days} day${days > 1 ? \"s\" : \"\"}`);\n\t\t\tif (hours > 0) parts.push(`${hours} hour${hours > 1 ? \"s\" : \"\"}`);\n\t\t\tparts.push(`${mins} minute${mins !== 1 ? \"s\" : \"\"}`);\n\t\t\treturn { stdout: `up ${parts.join(\", \")}`, exitCode: 0 };\n\t\t}\n\n\t\tconst timeStr = new Date().toTimeString().slice(0, 8);\n\t\tconst uptimeStr =\n\t\t\tdays > 0\n\t\t\t\t? `${days} day${days > 1 ? \"s\" : \"\"}, ${String(hours).padStart(2)}:${String(mins).padStart(2, \"0\")}`\n\t\t\t\t: `${String(hours).padStart(2)}:${String(mins).padStart(2, \"0\")}`;\n\t\tconst sessions = shell.users.listActiveSessions().length;\n\t\tconst load = (Math.random() * 0.5).toFixed(2);\n\n\t\treturn {\n\t\t\tstdout: ` ${timeStr} up ${uptimeStr}, ${sessions} user${sessions !== 1 ? \"s\" : \"\"}, load average: ${load}, ${load}, ${load}`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const wcCommand: ShellModule = {\n\tname: \"wc\",\n\tdescription: \"Count words/lines/bytes\",\n\tcategory: \"text\",\n\tparams: [\"[-l] [-w] [-c] [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst lines = ifFlag(args, [\"-l\"]);\n\t\tconst words = ifFlag(args, [\"-w\"]);\n\t\tconst bytes = ifFlag(args, [\"-c\"]);\n\t\tconst showAll = !lines && !words && !bytes;\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\n\t\tconst count = (content: string, label: string): string => {\n\t\t\tconst l = content.split(\"\\n\").length - (content.endsWith(\"\\n\") ? 1 : 0);\n\t\t\tconst w = content.trim().split(/\\s+/).filter(Boolean).length;\n\t\t\tconst c = Buffer.byteLength(content, \"utf8\");\n\t\t\tconst parts: string[] = [];\n\t\t\tif (showAll || lines) parts.push(String(l).padStart(7));\n\t\t\tif (showAll || words) parts.push(String(w).padStart(7));\n\t\t\tif (showAll || bytes) parts.push(String(c).padStart(7));\n\t\t\tif (label) parts.push(` ${label}`);\n\t\t\treturn parts.join(\"\");\n\t\t};\n\n\t\tif (positionals.length === 0) {\n\t\t\tconst content = stdin ?? \"\";\n\t\t\treturn { stdout: count(content, \"\"), exitCode: 0 };\n\t\t}\n\n\t\tconst results: string[] = [];\n\t\tfor (const file of positionals) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\ttry {\n\t\t\t\tassertPathAccess(authUser, filePath, \"wc\");\n\t\t\t\tconst content = shell.vfs.readFile(filePath);\n\t\t\t\tresults.push(count(content, file));\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `wc: ${file}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn { stdout: results.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag, parseArgs } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath, stripUrlFilename } from \"./helpers\";\n\nexport const wgetCommand: ShellModule = {\n\tname: \"wget\",\n\tdescription: \"File downloader (pure fetch)\",\n\tcategory: \"network\",\n\tparams: [\"[options] <url>\"],\n\trun: async ({ authUser, cwd, args, shell }) => {\n\t\tconst { flagsWithValues, positionals } = parseArgs(args, {\n\t\t\tflagsWithValue: [\n\t\t\t\t\"-O\",\n\t\t\t\t\"--output-document\",\n\t\t\t\t\"-o\",\n\t\t\t\t\"--output-file\",\n\t\t\t\t\"-P\",\n\t\t\t\t\"--directory-prefix\",\n\t\t\t\t\"--tries\",\n\t\t\t\t\"--timeout\",\n\t\t\t],\n\t\t});\n\n\t\tif (ifFlag(args, [\"-h\", \"--help\"])) {\n\t\t\treturn {\n\t\t\t\tstdout: [\n\t\t\t\t\t\"Usage: wget [option]... [URL]...\",\n\t\t\t\t\t\" -O, --output-document=FILE Write to FILE ('-' for stdout)\",\n\t\t\t\t\t\" -P, --directory-prefix=DIR Save files in DIR\",\n\t\t\t\t\t\" -q, --quiet Quiet mode\",\n\t\t\t\t\t\" -v, --verbose Verbose output (default)\",\n\t\t\t\t\t\" -c, --continue Continue partial download\",\n\t\t\t\t\t\" --tries=N Retry N times\",\n\t\t\t\t\t\" --timeout=N Timeout in seconds\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tif (ifFlag(args, [\"-V\", \"--version\"])) {\n\t\t\treturn {\n\t\t\t\tstdout: \"GNU Wget 1.21.3 (virtual) built on Fortune GNU/Linux.\",\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst url = positionals[0];\n\t\tif (!url)\n\t\t\treturn {\n\t\t\t\tstderr: \"wget: missing URL\\nUsage: wget [OPTION]... [URL]...\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\n\t\tconst outputArg =\n\t\t\tflagsWithValues.get(\"-O\") ??\n\t\t\tflagsWithValues.get(\"--output-document\") ??\n\t\t\tnull;\n\t\tconst dirPrefix =\n\t\t\tflagsWithValues.get(\"-P\") ??\n\t\t\tflagsWithValues.get(\"--directory-prefix\") ??\n\t\t\tnull;\n\t\tconst quiet = ifFlag(args, [\"-q\", \"--quiet\"]);\n\n\t\t// Derive target filename\n\t\tconst filename =\n\t\t\toutputArg === \"-\" ? null : (outputArg ?? stripUrlFilename(url));\n\t\tconst targetPath = filename\n\t\t\t? resolvePath(cwd, dirPrefix ? `${dirPrefix}/${filename}` : filename)\n\t\t\t: null;\n\n\t\tif (targetPath) assertPathAccess(authUser, targetPath, \"wget\");\n\n\t\tconst stderrLines: string[] = [];\n\t\tif (!quiet) {\n\t\t\tstderrLines.push(`--${new Date().toISOString()}-- ${url}`);\n\t\t\tstderrLines.push(`Resolving ${new URL(url).host}...`);\n\t\t\tstderrLines.push(`Connecting to ${new URL(url).host}...`);\n\t\t}\n\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetch(url, {\n\t\t\t\theaders: { \"User-Agent\": \"Wget/1.21.3 (Fortune GNU/Linux)\" },\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\tstderrLines.push(`wget: unable to resolve host: ${msg}`);\n\t\t\treturn { stderr: stderrLines.join(\"\\n\"), exitCode: 4 };\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tstderrLines.push(`ERROR ${response.status}: ${response.statusText}`);\n\t\t\treturn { stderr: stderrLines.join(\"\\n\"), exitCode: 8 };\n\t\t}\n\n\t\tlet body: string;\n\t\ttry {\n\t\t\tbody = await response.text();\n\t\t} catch {\n\t\t\treturn { stderr: \"wget: failed to read response\", exitCode: 1 };\n\t\t}\n\n\t\tif (!quiet) {\n\t\t\tconst ct =\n\t\t\t\tresponse.headers.get(\"content-type\") ?? \"application/octet-stream\";\n\t\t\tstderrLines.push(\n\t\t\t\t`HTTP request sent, awaiting response... ${response.status} ${response.statusText}`,\n\t\t\t);\n\t\t\tstderrLines.push(`Length: ${body.length} [${ct}]`);\n\t\t}\n\n\t\t// Output to stdout (pipe) or file\n\t\tif (outputArg === \"-\") {\n\t\t\treturn {\n\t\t\t\tstdout: body,\n\t\t\t\tstderr: stderrLines.join(\"\\n\") || undefined,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tif (targetPath) {\n\t\t\tshell.writeFileAsUser(authUser, targetPath, body);\n\t\t\tif (!quiet)\n\t\t\t\tstderrLines.push(\n\t\t\t\t\t`Saving to: '${targetPath}'\\n${targetPath} 100%[==================>] ${body.length} B`,\n\t\t\t\t);\n\t\t\treturn { stderr: stderrLines.join(\"\\n\") || undefined, exitCode: 0 };\n\t\t}\n\n\t\treturn { stdout: body, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const whichCommand: ShellModule = {\n\tname: \"which\",\n\tdescription: \"Locate a command in PATH\",\n\tcategory: \"shell\",\n\tparams: [\"<command...>\"],\n\trun: ({ args, shell, env }) => {\n\t\tif (args.length === 0)\n\t\t\treturn { stderr: \"which: missing argument\", exitCode: 1 };\n\n\t\tconst pathDirs = (env?.vars?.PATH ?? \"/usr/local/bin:/usr/bin:/bin\").split(\n\t\t\t\":\",\n\t\t);\n\t\tconst lines: string[] = [];\n\t\tlet anyMissing = false;\n\n\t\tfor (const name of args) {\n\t\t\tlet found = false;\n\t\t\tfor (const dir of pathDirs) {\n\t\t\t\tconst full = `${dir}/${name}`;\n\t\t\t\tif (shell.vfs.exists(full)) {\n\t\t\t\t\tconst st = shell.vfs.stat(full);\n\t\t\t\t\tif (st.type === \"file\") {\n\t\t\t\t\t\tlines.push(full);\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) anyMissing = true;\n\t\t}\n\n\t\tif (lines.length === 0) return { exitCode: 1 };\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: anyMissing ? 1 : 0 };\n\t},\n};\n", "export function formatLoginDate(date: Date): string {\n\tconst weekday = date.toLocaleString(\"en-US\", { weekday: \"short\" });\n\tconst month = date.toLocaleString(\"en-US\", { month: \"short\" });\n\tconst day = date.getDate().toString().padStart(2, \"0\");\n\tconst hh = date.getHours().toString().padStart(2, \"0\");\n\tconst mm = date.getMinutes().toString().padStart(2, \"0\");\n\tconst ss = date.getSeconds().toString().padStart(2, \"0\");\n\tconst year = date.getFullYear();\n\treturn `${weekday} ${month} ${day} ${hh}:${mm}:${ss} ${year}`;\n}\n", "import { formatLoginDate } from \"../SSHMimic/loginFormat\";\nimport type { ShellModule } from \"../types/commands\";\n\nexport const whoCommand: ShellModule = {\n\tname: \"who\",\n\tdescription: \"Show active sessions\",\n\tcategory: \"system\",\n\tparams: [],\n\trun: ({ shell }) => {\n\t\tconst lines = shell.users.listActiveSessions().map((session) => {\n\t\t\tconst loginAt = new Date(session.startedAt);\n\t\t\tconst displayDate = Number.isNaN(loginAt.getTime())\n\t\t\t\t? session.startedAt\n\t\t\t\t: formatLoginDate(loginAt);\n\t\t\treturn `${session.username} ${session.tty} ${displayDate} (${session.remoteAddress || \"unknown\"})`;\n\t\t});\n\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const whoamiCommand: ShellModule = {\n\tname: \"whoami\",\n\tdescription: \"Print current user\",\n\tcategory: \"system\",\n\tparams: [],\n\trun: ({ authUser }) => ({ stdout: authUser, exitCode: 0 }),\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { runCommand } from \"./runtime\";\n\nexport const xargsCommand: ShellModule = {\n\tname: \"xargs\",\n\tdescription: \"Build and execute command lines from stdin\",\n\tcategory: \"text\",\n\tparams: [\"[command] [args...]\"],\n\trun: async ({ authUser, hostname, mode, cwd, args, stdin, shell, env }) => {\n\t\tconst baseCmd = args[0] ?? \"echo\";\n\t\tconst extraArgs = args.slice(1);\n\t\tconst items = (stdin ?? \"\").trim().split(/\\s+/).filter(Boolean);\n\t\tif (items.length === 0) return { exitCode: 0 };\n\t\tconst fullCmd = [baseCmd, ...extraArgs, ...items].join(\" \");\n\t\treturn runCommand(\n\t\t\tfullCmd,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tundefined,\n\t\t\tenv,\n\t\t);\n\t},\n};\n", "/** biome-ignore-all lint/style/useNamingConvention: ENV VARIABLES */\nimport type { CommandContext, CommandResult, ShellModule } from \"../types/commands\";\nimport { adduserCommand } from \"./adduser\";\nimport { aliasCommand, unaliasCommand } from \"./alias\";\nimport { aptCacheCommand, aptCommand } from \"./apt\";\nimport { awkCommand } from \"./awk\";\nimport { base64Command } from \"./base64\";\nimport { catCommand } from \"./cat\";\nimport { cdCommand } from \"./cd\";\nimport { chmodCommand } from \"./chmod\";\nimport { clearCommand } from \"./clear\";\nimport { cpCommand } from \"./cp\";\nimport { curlCommand } from \"./curl\";\nimport { cutCommand } from \"./cut\";\nimport { dateCommand } from \"./date\";\nimport { declareCommand } from \"./declare\";\nimport { deluserCommand } from \"./deluser\";\nimport { dfCommand } from \"./df\";\nimport { diffCommand } from \"./diff\";\nimport { dpkgCommand, dpkgQueryCommand } from \"./dpkg\";\nimport { duCommand } from \"./du\";\nimport { echoCommand } from \"./echo\";\nimport { envCommand } from \"./env\";\nimport { exitCommand } from \"./exit\";\nimport { exportCommand } from \"./export\";\nimport { findCommand } from \"./find\";\nimport { freeCommand } from \"./free\";\nimport { grepCommand } from \"./grep\";\nimport { groupsCommand } from \"./groups\";\nimport { gunzipCommand, gzipCommand } from \"./gzip\";\nimport { headCommand } from \"./head\";\nimport { createHelpCommand } from \"./help\";\nimport { historyCommand } from \"./history\";\nimport { hostnameCommand } from \"./hostname\";\nimport { htopCommand } from \"./htop\";\nimport { idCommand } from \"./id\";\nimport { killCommand } from \"./kill\";\nimport { lnCommand } from \"./ln\";\nimport { lsCommand } from \"./ls\";\nimport { lsbReleaseCommand } from \"./lsb-release\";\nimport { manCommand } from \"./man\";\nimport { mkdirCommand } from \"./mkdir\";\nimport { mvCommand } from \"./mv\";\nimport { nanoCommand } from \"./nano\";\nimport { neofetchCommand } from \"./neofetch\";\nimport { nodeCommand } from \"./node\";\nimport { npmCommand, npxCommand } from \"./npm\";\nimport { passwdCommand } from \"./passwd\";\nimport { pingCommand } from \"./ping\";\nimport { printfCommand } from \"./printf\";\nimport { psCommand } from \"./ps\";\nimport { pwdCommand } from \"./pwd\";\nimport { python3Command } from \"./python\";\nimport { readCommand } from \"./read\";\nimport { rmCommand } from \"./rm\";\nimport { sedCommand } from \"./sed\";\nimport { setCommand } from \"./set\";\nimport { shCommand } from \"./sh\";\nimport { returnCommand, shiftCommand, trapCommand } from \"./shift\";\nimport { sleepCommand } from \"./sleep\";\nimport { sortCommand } from \"./sort\";\nimport { sourceCommand } from \"./source\";\nimport { suCommand } from \"./su\";\nimport { sudoCommand } from \"./sudo\";\nimport { tailCommand } from \"./tail\";\nimport { tarCommand } from \"./tar\";\nimport { teeCommand } from \"./tee\";\nimport { testCommand } from \"./test\";\nimport { touchCommand } from \"./touch\";\nimport { trCommand } from \"./tr\";\nimport { treeCommand } from \"./tree\";\nimport { falseCommand, trueCommand } from \"./true\";\nimport { typeCommand } from \"./type\";\nimport { unameCommand } from \"./uname\";\nimport { uniqCommand } from \"./uniq\";\nimport { unsetCommand } from \"./unset\";\nimport { uptimeCommand } from \"./uptime\";\nimport { wcCommand } from \"./wc\";\nimport { wgetCommand } from \"./wget\";\nimport { whichCommand } from \"./which\";\nimport { whoCommand } from \"./who\";\nimport { whoamiCommand } from \"./whoami\";\nimport { xargsCommand } from \"./xargs\";\n\nconst BASE_COMMANDS: ShellModule[] = [\n\t// Navigation\n\tpwdCommand,\n\tcdCommand,\n\tlsCommand,\n\ttreeCommand,\n\t// Files\n\tcatCommand,\n\ttouchCommand,\n\trmCommand,\n\tmkdirCommand,\n\tcpCommand,\n\tmvCommand,\n\tlnCommand,\n\tchmodCommand,\n\tfindCommand,\n\t// Text processing\n\tgrepCommand,\n\tsedCommand,\n\tawkCommand,\n\tsortCommand,\n\tuniqCommand,\n\twcCommand,\n\theadCommand,\n\ttailCommand,\n\tcutCommand,\n\ttrCommand,\n\tteeCommand,\n\txargsCommand,\n\tdiffCommand,\n\t// Archives\n\ttarCommand,\n\tgzipCommand,\n\tgunzipCommand,\n\tbase64Command,\n\t// System info\n\twhoamiCommand,\n\twhoCommand,\n\thostnameCommand,\n\tidCommand,\n\tgroupsCommand,\n\tunameCommand,\n\tpsCommand,\n\tkillCommand,\n\tdfCommand,\n\tduCommand,\n\tdateCommand,\n\tsleepCommand,\n\tpingCommand,\n\t// Shell\n\techoCommand,\n\tenvCommand,\n\texportCommand,\n\tsetCommand,\n\tunsetCommand,\n\tshCommand,\n\tclearCommand,\n\texitCommand,\n\t// Editors\n\tnanoCommand,\n\thtopCommand,\n\t// Network\n\tcurlCommand,\n\twgetCommand,\n\t// Users\n\tadduserCommand,\n\tpasswdCommand,\n\tdeluserCommand,\n\tsudoCommand,\n\tsuCommand,\n\t// Misc\n\tneofetchCommand,\n\t// Package management\n\taptCommand,\n\taptCacheCommand,\n\tdpkgCommand,\n\tdpkgQueryCommand,\n\t// Shell (extended)\n\twhichCommand,\n\ttypeCommand,\n\tmanCommand,\n\taliasCommand,\n\tunaliasCommand,\n\ttestCommand,\n\tsourceCommand,\n\thistoryCommand,\n\tprintfCommand,\n\treadCommand,\n\tdeclareCommand,\n\tshiftCommand,\n\ttrapCommand,\n\treturnCommand,\n\ttrueCommand,\n\tfalseCommand,\n\tnpmCommand,\n\tnpxCommand,\n\tnodeCommand,\n\tpython3Command,\n\t// System (extended)\n\tuptimeCommand,\n\tfreeCommand,\n\tlsbReleaseCommand,\n];\n\nconst customCommands: ShellModule[] = [];\nconst commandRegistry = new Map<string, ShellModule>();\nlet cachedCommandNames: string[] | null = null;\n\nconst helpCommand = createHelpCommand(() =>\n\tgetCommandModules().map((cmd) => cmd.name),\n);\n\nfunction buildCache(): void {\n\tcommandRegistry.clear();\n\tfor (const mod of getCommandModules()) {\n\t\tcommandRegistry.set(mod.name, mod);\n\t\tfor (const alias of mod.aliases ?? []) commandRegistry.set(alias, mod);\n\t}\n\tcachedCommandNames = Array.from(commandRegistry.keys()).sort();\n}\n\nfunction getCommandModules(): ShellModule[] {\n\treturn [...BASE_COMMANDS, ...customCommands, helpCommand];\n}\n\nexport function registerCommand(module: ShellModule): void {\n\tconst normalized: ShellModule = {\n\t\t...module,\n\t\tname: module.name.trim().toLowerCase(),\n\t\taliases: module.aliases?.map((a) => a.trim().toLowerCase()),\n\t};\n\tconst names = [normalized.name, ...(normalized.aliases ?? [])];\n\tif (names.some((n) => n.length === 0 || /\\s/.test(n))) {\n\t\tthrow new Error(\"Command names must be non-empty and contain no spaces\");\n\t}\n\tcustomCommands.push(normalized);\n\tbuildCache();\n}\n\nexport function createCustomCommand(\n\tname: string,\n\tparams: string[],\n\trun: (ctx: CommandContext) => CommandResult | Promise<CommandResult>,\n): ShellModule {\n\treturn { name, params, run };\n}\n\nexport function getCommandNames(): string[] {\n\tif (!cachedCommandNames) buildCache();\n\treturn cachedCommandNames!;\n}\n\nexport function getCommandModulesPublic(): ShellModule[] {\n\treturn getCommandModules();\n}\n\nexport function resolveModule(name: string): ShellModule | undefined {\n\tif (!cachedCommandNames) buildCache();\n\treturn commandRegistry.get(name.toLowerCase());\n}\n", "import { runCommandDirect } from \"../commands\";\nimport { resolvePath } from \"../commands/helpers\";\nimport type { CommandMode, CommandResult, ShellEnv } from \"../types/commands\";\nimport type {\n\tPipeline,\n\tPipelineCommand,\n\tScript,\n\tStatement,\n} from \"../types/pipeline\";\nimport type { VirtualShell } from \"../VirtualShell\";\n\n// \u2500\u2500 Script executor (handles &&/||/;) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function executeScript(\n\tscript: Script,\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tif (!script.isValid)\n\t\treturn { stderr: script.error || \"Syntax error\", exitCode: 1 };\n\n\tlet lastResult: CommandResult = { exitCode: 0 };\n\n\tfor (const stmt of script.statements) {\n\t\t// Decide whether to run this statement based on previous op\n\t\tlastResult = await executePipeline(\n\t\t\tstmt.pipeline,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tenv,\n\t\t);\n\t\tenv.lastExitCode = lastResult.exitCode ?? 0;\n\n\t\t// Propagate session-control signals\n\t\tif (\n\t\t\tlastResult.closeSession ||\n\t\t\tlastResult.switchUser ||\n\t\t\tlastResult.nextCwd\n\t\t) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn lastResult;\n}\n\n/** Execute statements connected by &&/||/; */\nexport async function executeStatements(\n\tstatements: Statement[],\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tlet last: CommandResult = { exitCode: 0 };\n\tlet i = 0;\n\n\twhile (i < statements.length) {\n\t\tconst stmt = statements[i]!;\n\t\tlast = await executePipeline(\n\t\t\tstmt.pipeline,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tenv,\n\t\t);\n\t\tenv.lastExitCode = last.exitCode ?? 0;\n\n\t\tif (last.closeSession || last.switchUser) return last;\n\n\t\tconst op = stmt.op;\n\t\tif (!op || op === \";\") {\n\t\t\t// always run next\n\t\t} else if (op === \"&&\") {\n\t\t\tif ((last.exitCode ?? 0) !== 0) {\n\t\t\t\t// skip until next ; or end\n\t\t\t\twhile (i < statements.length && statements[i]?.op === \"&&\") i++;\n\t\t\t}\n\t\t} else if (op === \"||\") {\n\t\t\tif ((last.exitCode ?? 0) === 0) {\n\t\t\t\t// skip until next ; or end\n\t\t\t\twhile (i < statements.length && statements[i]?.op === \"||\") i++;\n\t\t\t}\n\t\t}\n\t\ti++;\n\t}\n\treturn last;\n}\n\n// \u2500\u2500 Pipeline executor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function executePipeline(\n\tpipeline: Pipeline,\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv?: ShellEnv,\n): Promise<CommandResult> {\n\tif (!pipeline.isValid)\n\t\treturn { stderr: pipeline.error || \"Syntax error\", exitCode: 1 };\n\tif (pipeline.commands.length === 0) return { exitCode: 0 };\n\n\tconst shellEnv: ShellEnv = env ?? { vars: {}, lastExitCode: 0 };\n\n\tif (pipeline.commands.length === 1) {\n\t\treturn executeSingleCommandWithRedirections(\n\t\t\tpipeline.commands[0] as PipelineCommand,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tshellEnv,\n\t\t);\n\t}\n\n\treturn executePipelineChain(\n\t\tpipeline.commands as PipelineCommand[],\n\t\tauthUser,\n\t\thostname,\n\t\tmode,\n\t\tcwd,\n\t\tshell,\n\t\tshellEnv,\n\t);\n}\n\nasync function executeSingleCommandWithRedirections(\n\tcmd: PipelineCommand,\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tlet stdin: string | undefined;\n\tif (cmd.inputFile) {\n\t\tconst inputPath = resolvePath(cwd, cmd.inputFile);\n\t\ttry {\n\t\t\tstdin = shell.vfs.readFile(inputPath);\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstderr: `${cmd.inputFile}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t}\n\n\tconst result = await runCommandDirect(\n\t\tcmd.name,\n\t\tcmd.args,\n\t\tauthUser,\n\t\thostname,\n\t\tmode,\n\t\tcwd,\n\t\tshell,\n\t\tstdin,\n\t\tenv,\n\t);\n\n\tif (cmd.outputFile) {\n\t\tconst outputPath = resolvePath(cwd, cmd.outputFile);\n\t\tconst output = result.stdout || \"\";\n\t\ttry {\n\t\t\tif (cmd.appendOutput) {\n\t\t\t\tconst existing = (() => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn shell.vfs.readFile(outputPath);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t\tshell.writeFileAsUser(authUser, outputPath, existing + output);\n\t\t\t} else {\n\t\t\t\tshell.writeFileAsUser(authUser, outputPath, output);\n\t\t\t}\n\t\t\treturn { ...result, stdout: \"\" };\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\t...result,\n\t\t\t\tstderr: `Failed to write to ${cmd.outputFile}`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn result;\n}\n\nasync function executePipelineChain(\n\tcommands: PipelineCommand[],\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tlet currentOutput = \"\";\n\tlet exitCode = 0;\n\n\tfor (let i = 0; i < commands.length; i++) {\n\t\tconst cmd = commands[i] as PipelineCommand;\n\n\t\tif (i === 0 && cmd.inputFile) {\n\t\t\tconst inputPath = resolvePath(cwd, cmd.inputFile);\n\t\t\ttry {\n\t\t\t\tcurrentOutput = shell.vfs.readFile(inputPath);\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `${cmd.inputFile}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tconst result = await runCommandDirect(\n\t\t\tcmd.name,\n\t\t\tcmd.args,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tcurrentOutput,\n\t\t\tenv,\n\t\t);\n\t\texitCode = result.exitCode ?? 0;\n\n\t\tif (i === commands.length - 1 && cmd.outputFile) {\n\t\t\tconst outputPath = resolvePath(cwd, cmd.outputFile);\n\t\t\tconst output = result.stdout || \"\";\n\t\t\ttry {\n\t\t\t\tif (cmd.appendOutput) {\n\t\t\t\t\tconst existing = (() => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn shell.vfs.readFile(outputPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t\tshell.writeFileAsUser(authUser, outputPath, existing + output);\n\t\t\t\t} else {\n\t\t\t\t\tshell.writeFileAsUser(authUser, outputPath, output);\n\t\t\t\t}\n\t\t\t\tcurrentOutput = \"\";\n\t\t\t} catch {\n\t\t\t\treturn { stderr: `Failed to write to ${cmd.outputFile}`, exitCode: 1 };\n\t\t\t}\n\t\t} else {\n\t\t\tcurrentOutput = result.stdout || \"\";\n\t\t}\n\n\t\tif (result.stderr && exitCode !== 0)\n\t\t\treturn { stderr: result.stderr, exitCode };\n\t\tif (result.closeSession || result.switchUser) return result;\n\t}\n\n\treturn { stdout: currentOutput, exitCode };\n}\n", "import type {\n\tPipeline,\n\tPipelineCommand,\n\tScript,\n\tStatement,\n\tLogicalOp,\n} from \"../types/pipeline\";\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Parse a shell input line into a Script (sequence of statements connected\n * by && / || / ;). Each statement contains one Pipeline (commands connected\n * by |).\n */\nexport function parseScript(rawInput: string): Script {\n\tconst trimmed = rawInput.trim();\n\tif (!trimmed) return { statements: [], isValid: true };\n\n\ttry {\n\t\tconst statements = parseStatements(trimmed);\n\t\treturn { statements, isValid: true };\n\t} catch (e) {\n\t\treturn { statements: [], isValid: false, error: (e as Error).message };\n\t}\n}\n\n/** Legacy compat: parse a single pipeline (no &&/||/;) */\nexport function parseShellPipeline(rawInput: string): Pipeline {\n\tconst trimmed = rawInput.trim();\n\tif (!trimmed) return { commands: [], isValid: true };\n\ttry {\n\t\tconst commands = parsePipeline(trimmed);\n\t\treturn { commands, isValid: true };\n\t} catch (e) {\n\t\treturn { commands: [], isValid: false, error: (e as Error).message };\n\t}\n}\n\n// \u2500\u2500 Variable & tilde expansion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Expand ~ and $VAR / ${VAR} / ${VAR:-default} / $(cmd placeholder) in a\n * token, given the current env vars and home path.\n * Command substitution $(\u2026) is NOT executed here \u2014 it's left as a marker so\n * the executor can handle it.\n */\nexport function expandToken(\n\ttoken: string,\n\tenv: Record<string, string>,\n\tauthUser: string,\n\tlastExitCode = 0,\n): string {\n\t// tilde expansion\n\ttoken = token.replace(/^~(\\/|$)/, `/home/${authUser}$1`);\n\n\t// $? special var\n\ttoken = token.replace(/\\$\\?/g, String(lastExitCode));\n\t// $$ PID (mock)\n\ttoken = token.replace(/\\$\\$/g, \"1\");\n\t// $# argc (0 for interactive)\n\ttoken = token.replace(/\\$#/g, \"0\");\n\n\t// ${VAR:-default} and ${VAR:+value}\n\ttoken = token.replace(\n\t\t/\\$\\{([^}:]+):-([^}]*)\\}/g,\n\t\t(_, name, def) => env[name] ?? def,\n\t);\n\ttoken = token.replace(/\\$\\{([^}:]+):\\+([^}]*)\\}/g, (_, name, val) =>\n\t\tenv[name] ? val : \"\",\n\t);\n\n\t// ${VAR}\n\ttoken = token.replace(/\\$\\{([^}]+)\\}/g, (_, name) => env[name] ?? \"\");\n\n\t// $VAR (greedy: match longest valid identifier)\n\ttoken = token.replace(\n\t\t/\\$([A-Za-z_][A-Za-z0-9_]*)/g,\n\t\t(_, name) => env[name] ?? \"\",\n\t);\n\n\treturn token;\n}\n\n/**\n * Expand glob patterns (*, ?, [abc]) against a list of entries.\n * Returns the original pattern if no match.\n */\nexport function expandGlob(pattern: string, entries: string[]): string[] {\n\tif (!/[*?[]/.test(pattern)) return [pattern];\n\tconst regex = globToRegex(pattern);\n\tconst matches = entries.filter((e) => regex.test(e));\n\treturn matches.length > 0 ? matches.sort() : [pattern];\n}\n\nfunction globToRegex(pattern: string): RegExp {\n\tlet re = \"^\";\n\tfor (let i = 0; i < pattern.length; i++) {\n\t\tconst c = pattern[i]!;\n\t\tif (c === \"*\") re += \".*\";\n\t\telse if (c === \"?\") re += \".\";\n\t\telse if (c === \"[\") {\n\t\t\tconst close = pattern.indexOf(\"]\", i + 1);\n\t\t\tif (close === -1) re += \"\\\\[\";\n\t\t\telse {\n\t\t\t\tre += `[${pattern.slice(i + 1, close)}]`;\n\t\t\t\ti = close;\n\t\t\t}\n\t\t} else re += c.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\t}\n\treturn new RegExp(`${re}$`);\n}\n\n// \u2500\u2500 Internal parser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction parseStatements(input: string): Statement[] {\n\t// Split by ;, &&, || \u2014 respecting quotes and parens\n\tconst segments = splitByLogicalOps(input);\n\tconst statements: Statement[] = [];\n\n\tfor (const seg of segments) {\n\t\tconst commands = parsePipeline(seg.text.trim());\n\t\tconst stmt: Statement = { pipeline: { commands, isValid: true } };\n\t\tif (seg.op) stmt.op = seg.op;\n\t\tstatements.push(stmt);\n\t}\n\n\treturn statements;\n}\n\ninterface Segment {\n\ttext: string;\n\top?: LogicalOp;\n}\n\nfunction splitByLogicalOps(input: string): Segment[] {\n\tconst segments: Segment[] = [];\n\tlet current = \"\";\n\tlet depth = 0; // parens/subshell depth\n\tlet inQ = false;\n\tlet qChar = \"\";\n\tlet i = 0;\n\n\tconst flush = (op?: LogicalOp) => {\n\t\tif (current.trim()) segments.push({ text: current, op });\n\t\tcurrent = \"\";\n\t};\n\n\twhile (i < input.length) {\n\t\tconst ch = input[i]!;\n\t\tconst ch2 = input.slice(i, i + 2);\n\n\t\tif ((ch === '\"' || ch === \"'\") && !inQ) {\n\t\t\tinQ = true;\n\t\t\tqChar = ch;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ && ch === qChar) {\n\t\t\tinQ = false;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ) {\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ch === \"(\") {\n\t\t\tdepth++;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \")\") {\n\t\t\tdepth--;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (depth > 0) {\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ch2 === \"&&\") {\n\t\t\tflush(\"&&\");\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch2 === \"||\") {\n\t\t\tflush(\"||\");\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \";\") {\n\t\t\tflush(\";\");\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += ch;\n\t\ti++;\n\t}\n\tflush();\n\treturn segments;\n}\n\nfunction parsePipeline(input: string): PipelineCommand[] {\n\tconst pipeTokens = splitByPipe(input);\n\treturn pipeTokens.map(parseCommandWithRedirections);\n}\n\nfunction splitByPipe(input: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet inQ = false;\n\tlet qChar = \"\";\n\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst ch = input[i]!;\n\t\tif ((ch === '\"' || ch === \"'\") && !inQ) {\n\t\t\tinQ = true;\n\t\t\tqChar = ch;\n\t\t\tcurrent += ch;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ && ch === qChar) {\n\t\t\tinQ = false;\n\t\t\tcurrent += ch;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ) {\n\t\t\tcurrent += ch;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// || was already consumed at statement level, bare | is pipe\n\t\tif (ch === \"|\" && input[i + 1] !== \"|\") {\n\t\t\tif (!current.trim())\n\t\t\t\tthrow new Error(\"Syntax error near unexpected token '|'\");\n\t\t\ttokens.push(current.trim());\n\t\t\tcurrent = \"\";\n\t\t} else {\n\t\t\tcurrent += ch;\n\t\t}\n\t}\n\n\tconst tail = current.trim();\n\tif (!tail && tokens.length > 0)\n\t\tthrow new Error(\"Syntax error near unexpected token '|'\");\n\tif (tail) tokens.push(tail);\n\treturn tokens;\n}\n\nfunction parseCommandWithRedirections(token: string): PipelineCommand {\n\tconst parts = tokenizeCommand(token);\n\tif (parts.length === 0) return { name: \"\", args: [] };\n\n\tconst cmdParts: string[] = [];\n\tlet inputFile: string | undefined;\n\tlet outputFile: string | undefined;\n\tlet appendOutput = false;\n\tlet i = 0;\n\n\twhile (i < parts.length) {\n\t\tconst part = parts[i]!;\n\t\tif (part === \"<\") {\n\t\t\ti++;\n\t\t\tif (i >= parts.length)\n\t\t\t\tthrow new Error(\"Syntax error: expected filename after <\");\n\t\t\tinputFile = parts[i];\n\t\t\ti++;\n\t\t} else if (part === \">>\") {\n\t\t\ti++;\n\t\t\tif (i >= parts.length)\n\t\t\t\tthrow new Error(\"Syntax error: expected filename after >>\");\n\t\t\toutputFile = parts[i];\n\t\t\tappendOutput = true;\n\t\t\ti++;\n\t\t} else if (part === \">\") {\n\t\t\ti++;\n\t\t\tif (i >= parts.length)\n\t\t\t\tthrow new Error(\"Syntax error: expected filename after >\");\n\t\t\toutputFile = parts[i];\n\t\t\tappendOutput = false;\n\t\t\ti++;\n\t\t} else {\n\t\t\tcmdParts.push(part);\n\t\t\ti++;\n\t\t}\n\t}\n\n\tconst name = (cmdParts[0] ?? \"\").toLowerCase();\n\treturn { name, args: cmdParts.slice(1), inputFile, outputFile, appendOutput };\n}\n\nfunction tokenizeCommand(input: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet inQ = false;\n\tlet qChar = \"\";\n\tlet i = 0;\n\n\twhile (i < input.length) {\n\t\tconst ch = input[i]!;\n\t\tconst next = input[i + 1];\n\n\t\tif ((ch === '\"' || ch === \"'\") && !inQ) {\n\t\t\tinQ = true;\n\t\t\tqChar = ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ && ch === qChar) {\n\t\t\tinQ = false;\n\t\t\tqChar = \"\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ) {\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ch === \" \") {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((ch === \">\" || ch === \"<\") && !inQ) {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\tif (ch === \">\" && next === \">\") {\n\t\t\t\ttokens.push(\">>\");\n\t\t\t\ti += 2;\n\t\t\t} else {\n\t\t\t\ttokens.push(ch);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += ch;\n\t\ti++;\n\t}\n\tif (current) tokens.push(current);\n\treturn tokens;\n}\n", "/** biome-ignore-all lint/style/useNamingConvention: ENV VARIABLES */\nimport { executeStatements } from \"../SSHMimic/executor\";\nimport type { VirtualShell } from \"../VirtualShell\";\nimport { parseScript } from \"../VirtualShell/shellParser\";\nimport type {\n CommandMode,\n CommandResult,\n ShellEnv,\n} from \"../types/commands\";\nimport { expandAsync } from \"../utils/expand\";\nimport { resolveModule } from \"./registry\";\n\n// \u2500\u2500 Tokenize command input respecting quotes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction tokenizeCommand(input: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet inQ = false;\n\tlet qChar = \"\";\n\tlet i = 0;\n\n\twhile (i < input.length) {\n\t\tconst ch = input[i]!;\n\t\tconst next = input[i + 1];\n\n\t\tif ((ch === '\"' || ch === \"'\") && !inQ) {\n\t\t\tinQ = true;\n\t\t\tqChar = ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ && ch === qChar) {\n\t\t\tinQ = false;\n\t\t\tqChar = \"\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ) {\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ch === \" \") {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((ch === \">\" || ch === \"<\") && !inQ) {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\tif (ch === \">\" && next === \">\") {\n\t\t\t\ttokens.push(\">>\");\n\t\t\t\ti += 2;\n\t\t\t} else {\n\t\t\t\ttokens.push(ch);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += ch;\n\t\ti++;\n\t}\n\tif (current) tokens.push(current);\n\treturn tokens;\n}\n\nexport function makeDefaultEnv(authUser: string, hostname: string): ShellEnv {\n\treturn {\n\t\tvars: {\n\t\t\tPATH: \"/usr/local/bin:/usr/bin:/bin\",\n\t\t\tHOME: `/home/${authUser}`,\n\t\t\tUSER: authUser,\n\t\t\tLOGNAME: authUser,\n\t\t\tSHELL: \"/bin/sh\",\n\t\t\tTERM: \"xterm-256color\",\n\t\t\tHOSTNAME: hostname,\n\t\t\tPS1: \"\\\\u@\\\\h:\\\\w\\\\$ \",\n\t\t},\n\t\tlastExitCode: 0,\n\t};\n}\n\nfunction resolveVfsBinary(\n\tname: string,\n\tenv: ShellEnv,\n\tshell: VirtualShell,\n\tauthUser: string,\n): string | null {\n\tif (name.startsWith(\"/\")) {\n\t\tif (!shell.vfs.exists(name)) return null;\n\t\ttry {\n\t\t\tconst st = shell.vfs.stat(name);\n\t\t\tif (st.type !== \"file\") return null;\n\t\t\tif (!(st.mode & 0o111)) return null;\n\t\t\tif (\n\t\t\t\t(name.startsWith(\"/sbin/\") || name.startsWith(\"/usr/sbin/\")) &&\n\t\t\t\tauthUser !== \"root\"\n\t\t\t)\n\t\t\t\treturn null;\n\t\t\treturn name;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tconst pathDirs = (env.vars.PATH ?? \"/usr/local/bin:/usr/bin:/bin\").split(\":\");\n\tfor (const dir of pathDirs) {\n\t\tif ((dir === \"/sbin\" || dir === \"/usr/sbin\") && authUser !== \"root\")\n\t\t\tcontinue;\n\t\tconst full = `${dir}/${name}`;\n\t\tif (!shell.vfs.exists(full)) continue;\n\t\ttry {\n\t\t\tconst st = shell.vfs.stat(full);\n\t\t\tif (st.type !== \"file\") continue;\n\t\t\tif (!(st.mode & 0o111)) continue;\n\t\t\treturn full;\n\t\t} catch {}\n\t}\n\treturn null;\n}\n\nexport async function runCommandDirect(\n\tname: string,\n\targs: string[],\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tstdin: string | undefined,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tconst aliasVal = env.vars[`__alias_${name}`];\n\tif (aliasVal) {\n\t\treturn runCommand(\n\t\t\t`${aliasVal} ${args.join(\" \")}`,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tstdin,\n\t\t\tenv,\n\t\t);\n\t}\n\n\tconst mod = resolveModule(name);\n\tif (!mod) {\n\t\tconst vfsBinary = resolveVfsBinary(name, env, shell, authUser);\n\t\tif (vfsBinary) {\n\t\t\tconst stubContent = shell.vfs.readFile(vfsBinary);\n\t\t\tconst builtinMatch = stubContent.match(/exec\\s+builtin\\s+(\\S+)/);\n\t\t\tif (builtinMatch) {\n\t\t\t\tconst builtinMod = resolveModule(builtinMatch[1]!);\n\t\t\t\tif (builtinMod) {\n\t\t\t\t\treturn await builtinMod.run({\n\t\t\t\t\t\tauthUser,\n\t\t\t\t\t\thostname,\n\t\t\t\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\t\t\t\trawInput: [name, ...args].join(\" \"),\n\t\t\t\t\t\tmode,\n\t\t\t\t\t\targs,\n\t\t\t\t\t\tstdin,\n\t\t\t\t\t\tcwd,\n\t\t\t\t\t\tshell,\n\t\t\t\t\t\tenv,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst shMod = resolveModule(\"sh\");\n\t\t\tif (shMod) {\n\t\t\t\treturn await shMod.run({\n\t\t\t\t\tauthUser,\n\t\t\t\t\thostname,\n\t\t\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\t\t\trawInput: `sh -c ${JSON.stringify(stubContent)}`,\n\t\t\t\t\tmode,\n\t\t\t\t\targs: [\"-c\", stubContent, \"--\", ...args],\n\t\t\t\t\tstdin,\n\t\t\t\t\tcwd,\n\t\t\t\t\tshell,\n\t\t\t\t\tenv,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn { stderr: `${name}: command not found`, exitCode: 127 };\n\t}\n\n\ttry {\n\t\treturn await mod.run({\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\trawInput: [name, ...args].join(\" \"),\n\t\t\tmode,\n\t\t\targs,\n\t\t\tstdin,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tenv,\n\t\t});\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tstderr: error instanceof Error ? error.message : \"Command failed\",\n\t\t\texitCode: 1,\n\t\t};\n\t}\n}\n\nexport async function runCommand(\n\trawInput: string,\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tstdin?: string,\n\tenv?: ShellEnv,\n): Promise<CommandResult> {\n\tconst trimmed = rawInput.trim();\n\tif (trimmed.length === 0) return { exitCode: 0 };\n\n\tconst shellEnv: ShellEnv = env ?? makeDefaultEnv(authUser, hostname);\n\n\tconst rawTokens = tokenizeCommand(trimmed);\n\tconst rawFirstWord = rawTokens[0]?.toLowerCase() ?? \"\";\n\tconst aliasVal = shellEnv.vars[`__alias_${rawFirstWord}`];\n\tconst aliasExpanded = aliasVal\n\t\t? trimmed.replace(rawFirstWord, aliasVal)\n\t\t: trimmed;\n\n\tconst hasOperators =\n\t\t/(?<![|&])[|](?![|])/.test(aliasExpanded) ||\n\t\taliasExpanded.includes(\">\") ||\n\t\taliasExpanded.includes(\"<\") ||\n\t\taliasExpanded.includes(\"&&\") ||\n\t\taliasExpanded.includes(\"||\") ||\n\t\taliasExpanded.includes(\";\");\n\n\tif (hasOperators) {\n\t\tconst script = parseScript(aliasExpanded);\n\t\tif (!script.isValid)\n\t\t\treturn { stderr: script.error || \"Syntax error\", exitCode: 1 };\n\t\ttry {\n\t\t\treturn await executeStatements(\n\t\t\t\tscript.statements,\n\t\t\t\tauthUser,\n\t\t\t\thostname,\n\t\t\t\tmode,\n\t\t\t\tcwd,\n\t\t\t\tshell,\n\t\t\t\tshellEnv,\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\treturn {\n\t\t\t\tstderr: error instanceof Error ? error.message : \"Execution failed\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t}\n\n\tconst expanded = await expandAsync(\n\t\taliasExpanded,\n\t\tshellEnv.vars,\n\t\tshellEnv.lastExitCode,\n\t\t(sub) =>\n\t\t\trunCommand(\n\t\t\t\tsub,\n\t\t\t\tauthUser,\n\t\t\t\thostname,\n\t\t\t\tmode,\n\t\t\t\tcwd,\n\t\t\t\tshell,\n\t\t\t\tundefined,\n\t\t\t\tshellEnv,\n\t\t\t).then((r) => r.stdout ?? \"\"),\n\t);\n\n\tconst parts = tokenizeCommand(expanded.trim());\n\tconst commandName = parts[0]?.toLowerCase() ?? \"\";\n\tconst args = parts.slice(1);\n\tconst mod = resolveModule(commandName);\n\n\tif (!mod) {\n\t\tconst vfsBinary = resolveVfsBinary(commandName, shellEnv, shell, authUser);\n\t\tif (vfsBinary) {\n\t\t\tconst stubContent = shell.vfs.readFile(vfsBinary);\n\t\t\tconst builtinMatch = stubContent.match(/exec\\s+builtin\\s+(\\S+)/);\n\t\t\tif (builtinMatch) {\n\t\t\t\tconst builtinName = builtinMatch[1]!;\n\t\t\t\tconst builtinMod = resolveModule(builtinName);\n\t\t\t\tif (builtinMod) {\n\t\t\t\t\treturn await builtinMod.run({\n\t\t\t\t\t\tauthUser,\n\t\t\t\t\t\thostname,\n\t\t\t\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\t\t\t\trawInput: [commandName, ...args].join(\" \"),\n\t\t\t\t\t\tmode,\n\t\t\t\t\t\targs,\n\t\t\t\t\t\tstdin,\n\t\t\t\t\t\tcwd,\n\t\t\t\t\t\tshell,\n\t\t\t\t\t\tenv: shellEnv,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst shMod = resolveModule(\"sh\");\n\t\t\tif (shMod) {\n\t\t\t\treturn await shMod.run({\n\t\t\t\t\tauthUser,\n\t\t\t\t\thostname,\n\t\t\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\t\t\trawInput: `sh -c ${JSON.stringify(stubContent)}`,\n\t\t\t\t\tmode,\n\t\t\t\t\targs: [\"-c\", stubContent, \"--\", ...args],\n\t\t\t\t\tstdin,\n\t\t\t\t\tcwd,\n\t\t\t\t\tshell,\n\t\t\t\t\tenv: shellEnv,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn { stderr: `${commandName}: command not found`, exitCode: 127 };\n\t}\n\n\ttry {\n\t\treturn await mod.run({\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\trawInput: expanded,\n\t\t\tmode,\n\t\t\targs,\n\t\t\tstdin,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tenv: shellEnv,\n\t\t});\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tstderr: error instanceof Error ? error.message : \"Command failed\",\n\t\t\texitCode: 1,\n\t\t};\n\t}\n}\n", "import type { ShellProperties } from \"../VirtualShell\";\nimport { formatLoginDate } from \"./loginFormat\";\n\nexport interface LoginBannerState {\n\tat: string;\n\tfrom: string;\n}\n\nexport function buildLoginBanner(\n\thostname: string,\n\tproperties: ShellProperties,\n\tlastLogin: LoginBannerState | null,\n): string {\n\tconst lines = [\n\t\t`Linux ${hostname} ${properties.kernel} ${properties.arch}`,\n\t\t\"\",\n\t\t\"The programs included with the Fortune GNU/Linux system are free software;\",\n\t\t\"the exact distribution terms for each program are described in the\",\n\t\t\"individual files in /usr/share/doc/*/copyright.\",\n\t\t\"\",\n\t\t\"Fortune GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent\",\n\t\t\"permitted by applicable law.\",\n\t];\n\n\tif (lastLogin) {\n\t\tconst when = new Date(lastLogin.at);\n\t\tconst displayed = Number.isNaN(when.getTime())\n\t\t\t? lastLogin.at\n\t\t\t: formatLoginDate(when);\n\t\tlines.push(`Last login: ${displayed} from ${lastLogin.from || \"unknown\"}`);\n\t}\n\n\tlines.push(\"\");\n\n\treturn `${lines.map((line) => `${line}\\r\\n`).join(\"\")}`;\n}", "export function buildPrompt(\n\tuser: string,\n\thost: string,\n\tcwdName: string,\n): string {\n\tconst isRoot = user === \"root\";\n\tconst colorUser = isRoot ? \"\\u001b[31;1m\" : \"\\u001b[35;1m\";\n\tconst colorWhite = \"\\u001b[37;1m\";\n\tconst colorBlue = \"\\u001b[34;1m\";\n\tconst colorReset = \"\\u001b[0m\";\n\tconst symbol = isRoot ? \"#\" : \"$\";\n\n\treturn `${colorWhite}[${colorUser}${user}${colorWhite}@${colorBlue}${host}${colorReset} ${cwdName}${colorWhite}]${colorReset}${symbol} `;\n}\n", "import { EventEmitter } from \"node:events\";\nimport { createCustomCommand, registerCommand } from \"../commands/registry\";\nimport { runCommand } from \"../commands/runtime\";\nimport {\n\tbootstrapLinuxRootfs,\n\trefreshProc,\n\tsyncEtcPasswd,\n} from \"../modules/linuxRootfs\";\nimport type { CommandContext, CommandResult } from \"../types/commands\";\nimport type { ShellStream } from \"../types/streams\";\nimport type { VfsNodeStats } from \"../types/vfs\";\nimport type { PerfLogger } from \"../utils/perfLogger\";\nimport { createPerfLogger } from \"../utils/perfLogger\";\nimport VirtualFileSystem, { type VfsOptions } from \"../VirtualFileSystem\";\nimport { VirtualPackageManager } from \"../VirtualPackageManager\";\nimport { VirtualUserManager } from \"../VirtualUserManager\";\nimport { startShell } from \"./shell\";\n\n/**\n * Virtual machine identity strings surfaced by system-info commands\n * (`uname`, `neofetch`, `lsb_release`, `/proc/version`, `/etc/os-release`).\n *\n * Pass this as the second argument to `new VirtualShell()` to customise the\n * distro name, kernel version, and CPU architecture reported inside the shell.\n *\n * @example\n * ```ts\n * const shell = new VirtualShell(\"my-vm\", {\n * kernel: \"6.1.0+custom-amd64\",\n * os: \"Acme GNU/Linux x64\",\n * arch: \"x86_64\",\n * });\n * ```\n */\nexport interface ShellProperties {\n\t/** Kernel version string (e.g. `\"1.0.0+itsrealfortune+1-amd64\"`). */\n\tkernel: string;\n\t/** Full OS description (e.g. `\"Fortune GNU/Linux x64\"`). */\n\tos: string;\n\t/** CPU architecture label (e.g. `\"x86_64\"`, `\"aarch64\"`). */\n\tarch: string;\n}\n\nexport interface VirtualShellVfsLike {\n\trestoreMirror(): Promise<void>;\n\tflushMirror(): Promise<void>;\n\twriteFile(targetPath: string, content: string | Uint8Array): void;\n\treadFile(targetPath: string): string;\n\tmkdir(targetPath: string, mode?: number): void;\n\texists(targetPath: string): boolean;\n\tstat(targetPath: string): VfsNodeStats;\n\tlist(targetPath: string): string[];\n\tremove(targetPath: string, options?: { recursive?: boolean }): void;\n\tchmod?(targetPath: string, mode: number): void;\n\tsymlink?(targetPath: string, linkPath: string): void;\n\tgetUsageBytes?(targetPath?: string): number;\n}\n\nexport interface VirtualShellVfsOptions {\n\tvfsInstance?: VirtualShellVfsLike;\n}\n\nfunction hasVfsInstance(obj: unknown): obj is { vfsInstance: VirtualShellVfsLike } {\n\treturn (\n\t\ttypeof obj === \"object\" &&\n\t\tobj !== null &&\n\t\t\"vfsInstance\" in obj &&\n\t\tisVirtualShellVfsLike((obj as Record<string, unknown>).vfsInstance)\n\t);\n}\n\nfunction isVirtualShellVfsLike(value: unknown): value is VirtualShellVfsLike {\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\n\tconst candidate = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof candidate.restoreMirror === \"function\" &&\n\t\ttypeof candidate.flushMirror === \"function\" &&\n\t\ttypeof candidate.writeFile === \"function\" &&\n\t\ttypeof candidate.readFile === \"function\" &&\n\t\ttypeof candidate.mkdir === \"function\" &&\n\t\ttypeof candidate.exists === \"function\" &&\n\t\ttypeof candidate.stat === \"function\" &&\n\t\ttypeof candidate.list === \"function\" &&\n\t\ttypeof candidate.remove === \"function\" &&\n\t\ttypeof candidate.copy === \"function\" &&\n\t\ttypeof candidate.move === \"function\" &&\n\t\ttypeof candidate.touch === \"function\"\n\t);\n}\n\nconst defaultShellProperties: ShellProperties = {\n\tkernel: \"1.0.0+itsrealfortune+1-amd64\",\n\tos: \"Fortune GNU/Linux x64\",\n\tarch: \"x86_64\",\n};\n\nconst perf: PerfLogger = createPerfLogger(\"VirtualShell\");\n\nfunction resolveAutoSudoForNewUsers(): boolean {\n\tconst configured = process.env.SSH_MIMIC_AUTO_SUDO_NEW_USERS;\n\tif (!configured) {\n\t\treturn true;\n\t}\n\n\treturn ![\"0\", \"false\", \"no\", \"off\"].includes(configured.toLowerCase());\n}\n\n/**\n * Coordinates the virtual filesystem, user manager, package manager, and\n * command runtime for a single isolated shell environment.\n *\n * Each instance owns its own VFS tree, user database, package registry, and\n * session state \u2014 multiple instances are fully independent.\n *\n * Instances are consumed both by the SSH/SFTP server facades and directly via\n * the programmatic `SshClient` API.\n *\n * @example\n * ```ts\n * const shell = new VirtualShell(\"my-vm\");\n * await shell.ensureInitialized();\n * const client = new SshClient(shell, \"root\");\n * const result = await client.exec(\"uname -a\");\n * ```\n *\n * @fires VirtualShell#initialized Emitted once the VFS and users are ready.\n * @fires VirtualShell#command Emitted after every command execution.\n * @fires VirtualShell#session:start Emitted when an interactive session opens.\n */\nclass VirtualShell extends EventEmitter {\n\t/** Backing virtual filesystem \u2014 use for direct path operations. */\n\tvfs: VirtualFileSystem;\n\t/** Virtual user database \u2014 use for auth, quotas, and session tracking. */\n\tusers: VirtualUserManager;\n\t/** APT/dpkg package manager backed by the built-in package registry. */\n\tpackageManager: VirtualPackageManager;\n\t/** Hostname shown in the shell prompt and SSH ident string. */\n\thostname: string;\n\t/** Distro identity strings surfaced by `uname`, `neofetch`, etc. */\n\tproperties: ShellProperties;\n\t/** Unix ms timestamp of shell creation \u2014 used by `uptime` and `/proc/uptime`. */\n\tstartTime: number;\n\tprivate initialized: Promise<void>;\n\n\t/**\n\t * Creates a new virtual shell instance.\n\t *\n\t * @param hostname Virtual hostname used for prompts and idents.\n\t * @param properties Customizable properties shown in `uname -a` and similar commands.\n\t * @param vfsOptions Optional VFS persistence options (mode, snapshotPath).\n\t */\n\tconstructor(\n\t\thostname: string,\n\t\tproperties?: ShellProperties,\n\t\tvfsOptionsOrInstance?: VfsOptions | VirtualShellVfsLike | VirtualShellVfsOptions,\n\t) {\n\t\tsuper();\n\t\tperf.mark(\"constructor\");\n\t\tthis.hostname = hostname;\n\t\tthis.properties = properties || defaultShellProperties;\n\t\tthis.startTime = Date.now();\n\n\t\tif (isVirtualShellVfsLike(vfsOptionsOrInstance)) {\n\t\t\tthis.vfs = vfsOptionsOrInstance as unknown as VirtualFileSystem;\n\t\t} else if (hasVfsInstance(vfsOptionsOrInstance)) {\n\t\t\tthis.vfs = vfsOptionsOrInstance.vfsInstance as unknown as VirtualFileSystem;\n\t\t} else {\n\t\t\tthis.vfs = new VirtualFileSystem((vfsOptionsOrInstance as VfsOptions) ?? {});\n\t\t}\n\t\tthis.users = new VirtualUserManager(this.vfs, resolveAutoSudoForNewUsers());\n\t\tthis.packageManager = new VirtualPackageManager(this.vfs, this.users);\n\n\t\t// Store references to avoid TypeScript \"used before assigned\" errors\n\t\tconst vfs = this.vfs;\n\t\tconst users = this.users;\n\t\tconst pm = this.packageManager;\n\t\tconst shellProps = this.properties;\n\t\tconst shellHostname = this.hostname;\n\t\tconst startTime = this.startTime;\n\n\t\t// Initialize both VFS mirror and users, ensuring all is ready before auth\n\t\tthis.initialized = (async () => {\n\t\t\tawait vfs.restoreMirror();\n\t\t\tawait users.initialize();\n\t\t\t// Bootstrap Linux rootfs (idempotent)\n\t\t\tbootstrapLinuxRootfs(vfs, users, shellHostname, shellProps, startTime);\n\t\t\t// Load installed packages from dpkg status\n\t\t\tpm.load();\n\t\t\tthis.emit(\"initialized\");\n\t\t})();\n\t}\n\n\t/**\n\t * Ensures initialization is complete before allowing operations.\n\t * Call this before any authentication or command execution.\n\t */\n\tpublic async ensureInitialized(): Promise<void> {\n\t\tperf.mark(\"ensureInitialized\");\n\t\tawait this.initialized;\n\t}\n\n\t/**\n\t * Registers a new command in the shell runtime.\n\t *\n\t * @param name Case-insensitive command name (no spaces).\n\t * @param params List of parameter names for help text (no validation).\n\t * @param callback Function invoked with command context on execution.\n\t */\n\taddCommand(\n\t\tname: string,\n\t\tparams: string[],\n\t\tcallback: (ctx: CommandContext) => CommandResult | Promise<CommandResult>,\n\t): void {\n\t\tconst normalized = name.trim().toLowerCase();\n\t\tif (normalized.length === 0 || /\\s/.test(normalized)) {\n\t\t\tthrow new Error(\"Command name must be non-empty and contain no spaces\");\n\t\t}\n\n\t\tregisterCommand(createCustomCommand(normalized, params, callback));\n\t}\n\n\t/**\n\t * Executes a raw command line string programmatically.\n\t *\n\t * Supports the full shell operator set (`&&`, `||`, `;`, `|`, `>`, `<`,\n\t * `$(cmd)`) and alias expansion. The result is emitted via the\n\t * `\"command\"` event but not returned \u2014 use `SshClient.exec()` for a\n\t * result-returning wrapper.\n\t *\n\t * @param rawInput Unparsed command line (e.g. `\"ls -la /tmp\"`).\n\t * @param authUser Username to run the command as.\n\t * @param cwd Current working directory for path resolution.\n\t */\n\texecuteCommand(rawInput: string, authUser: string, cwd: string): void {\n\t\tperf.mark(\"executeCommand\");\n\t\trunCommand(rawInput, authUser, this.hostname, \"shell\", cwd, this);\n\t\tthis.emit(\"command\", { command: rawInput, user: authUser, cwd });\n\t}\n\n\t/**\n\t * Attaches an interactive PTY session to this shell instance.\n\t *\n\t * Called internally by `SshMimic` when a client opens a shell channel.\n\t * The session reads from `stream` (user keystrokes) and writes back ANSI\n\t * output. History, `.bashrc` sourcing, and Ctrl+W/Ctrl+U line editing are\n\t * handled automatically.\n\t *\n\t * @param stream Bidirectional SSH channel stream.\n\t * @param authUser Authenticated username bound to this session.\n\t * @param sessionId Stable session UUID (used for `who` output), or `null`.\n\t * @param remoteAddress IP or hostname of the connecting client.\n\t * @param terminalSize Initial terminal dimensions in columns and rows.\n\t */\n\tstartInteractiveSession(\n\t\tstream: ShellStream,\n\t\tauthUser: string,\n\t\tsessionId: string | null,\n\t\tremoteAddress: string,\n\t\tterminalSize: { cols: number; rows: number },\n\t): void {\n\t\tperf.mark(\"startInteractiveSession\");\n\t\t// Interactive shell logic\n\t\tthis.emit(\"session:start\", { user: authUser, sessionId, remoteAddress });\n\t\tstartShell(\n\t\t\tthis.properties,\n\t\t\tstream,\n\t\t\tauthUser,\n\t\t\tthis.hostname,\n\t\t\tsessionId,\n\t\t\tremoteAddress,\n\t\t\tterminalSize,\n\t\t\tthis,\n\t\t);\n\t\t// Refresh /proc/<pid> and /proc/self after session is registered\n\t\tthis.refreshProcSessions();\n\t}\n\n\t/**\n\t * Refreshes the `/proc` virtual filesystem with current system state.\n\t *\n\t * Updates `/proc/uptime`, `/proc/meminfo`, `/proc/cpuinfo`,\n\t * `/proc/version`, `/proc/loadavg`, `/proc/self`, and per-session\n\t * `/proc/<pid>` entries from live session and host data.\n\t *\n\t * Called automatically during `bootstrapLinuxRootfs`. Call again before\n\t * reading `/proc` files for up-to-date values.\n\t */\n\tpublic refreshProcFs(): void {\n\t\trefreshProc(\n\t\t\tthis.vfs,\n\t\t\tthis.properties,\n\t\t\tthis.hostname,\n\t\t\tthis.startTime,\n\t\t\tthis.users.listActiveSessions(),\n\t\t);\n\t}\n\n\t/**\n\t * Updates only the session-dependent `/proc` entries (`/proc/<pid>`,\n\t * `/proc/self`). Cheaper than a full `refreshProcFs()` \u2014 call this\n\t * whenever a session is registered or unregistered.\n\t */\n\tpublic refreshProcSessions(): void {\n\t\trefreshProc(\n\t\t\tthis.vfs,\n\t\t\tthis.properties,\n\t\t\tthis.hostname,\n\t\t\tthis.startTime,\n\t\t\tthis.users.listActiveSessions(),\n\t\t);\n\t}\n\n\t/**\n\t * Syncs `/etc/passwd`, `/etc/group`, and `/etc/shadow` from the current\n\t * `VirtualUserManager` state.\n\t *\n\t * Called automatically during `bootstrapLinuxRootfs`. Call again after\n\t * `users.addUser()`, `users.deleteUser()`, or `users.addSudoer()` to keep\n\t * the classic Unix credential files in sync with the user manager.\n\t */\n\tpublic syncPasswd(): void {\n\t\tsyncEtcPasswd(this.vfs, this.users);\n\t}\n\n\t/**\n\t * Returns virtual filesystem instance after server started.\n\t *\n\t * @returns VirtualFileSystem or null when not started.\n\t */\n\tpublic getVfs(): VirtualFileSystem | null {\n\t\treturn this?.vfs ?? null;\n\t}\n\n\t/**\n\t * Returns user manager instance after server started.\n\t *\n\t * @returns VirtualUserManager or null when not started.\n\t */\n\tpublic getUsers(): VirtualUserManager | null {\n\t\treturn this?.users ?? null;\n\t}\n\n\t/**\n\t * Returns hostname shown in prompts and idents.\n\t *\n\t * @returns Configured hostname label.\n\t */\n\tpublic getHostname(): string {\n\t\treturn this?.hostname;\n\t}\n\n\t/**\n\t * Writes a file on behalf of a user with quota enforcement.\n\t *\n\t * @param authUser User performing the write.\n\t * @param targetPath Destination path.\n\t * @param content File content.\n\t */\n\tpublic writeFileAsUser(\n\t\tauthUser: string,\n\t\ttargetPath: string,\n\t\tcontent: string | Buffer,\n\t): void {\n\t\tperf.mark(\"writeFileAsUser\");\n\t\tthis.users.assertWriteWithinQuota(authUser, targetPath, content);\n\t\tthis.vfs.writeFile(targetPath, content);\n\t}\n}\n\nexport { VirtualShell };\n", "/** biome-ignore-all lint/style/useNamingConvention: ENV VAR KEYS */\n/**\n * linuxRootfs.ts\n *\n * Bootstraps a realistic Linux directory hierarchy in the VFS.\n * Called once during VirtualShell initialization. Idempotent \u2014 skips\n * paths that already exist so FS-mode snapshots survive restarts.\n */\n\nimport * as os from \"node:os\";\nimport type { ShellProperties } from \"../VirtualShell\";\nimport type VirtualFileSystem from \"../VirtualFileSystem\";\nimport type { VirtualUserManager } from \"../VirtualUserManager\";\n\n// \u2500\u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction ensureDir(vfs: VirtualFileSystem, path: string, mode = 0o755): void {\n\tif (!vfs.exists(path)) vfs.mkdir(path, mode);\n}\n\nfunction ensureFile(\n\tvfs: VirtualFileSystem,\n\tpath: string,\n\tcontent: string,\n\tmode = 0o644,\n): void {\n\tif (!vfs.exists(path)) vfs.writeFile(path, content, { mode });\n}\n\n// \u2500\u2500\u2500 /etc \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapEtc(\n\tvfs: VirtualFileSystem,\n\thostname: string,\n\tprops: ShellProperties,\n): void {\n\tensureDir(vfs, \"/etc\");\n\n\t// os-release \u2014 authoritative distro identity used by neofetch, lsb_release\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/os-release\",\n\t\t`${[\n\t\t\t`NAME=\"Fortune GNU/Linux\"`,\n\t\t\t`PRETTY_NAME=\"${props.os}\"`,\n\t\t\t`ID=fortune`,\n\t\t\t`ID_LIKE=debian`,\n\t\t\t`HOME_URL=\"https://github.com/itsrealfortune/typescript-virtual-container\"`,\n\t\t\t`VERSION_CODENAME=aurora`,\n\t\t\t`VERSION_ID=\"1.0\"`,\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tensureFile(vfs, \"/etc/debian_version\", \"12.0\\n\");\n\tensureFile(vfs, \"/etc/hostname\", `${hostname}\\n`);\n\tensureFile(vfs, \"/etc/shells\", \"/bin/sh\\n/bin/bash\\n/usr/bin/bash\\n\");\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/profile\",\n\t\t`${[\n\t\t\t\"export PATH=/usr/local/bin:/usr/bin:/bin\",\n\t\t\t\"export PS1='\\\\u@\\\\h:\\\\w\\\\$ '\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tensureFile(vfs, \"/etc/issue\", `Fortune GNU/Linux 1.0 \\\\n \\\\l\\n`);\n\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/motd\",\n\t\t[\"\", `Welcome to ${props.os}`, `Kernel: ${props.kernel}`, \"\"].join(\"\\n\"),\n\t);\n\n\t// APT sources\n\tensureDir(vfs, \"/etc/apt\");\n\tensureDir(vfs, \"/etc/apt/sources.list.d\");\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/apt/sources.list\",\n\t\t`${[\n\t\t\t\"# Fortune GNU/Linux package sources\",\n\t\t\t\"deb [virtual] fortune://packages.fortune.local aurora main contrib\",\n\t\t\t\"deb [virtual] fortune://security.fortune.local aurora-security main\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\t// network stubs\n\tensureDir(vfs, \"/etc/network\");\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/network/interfaces\",\n\t\t`${[\n\t\t\t\"auto lo\",\n\t\t\t\"iface lo inet loopback\",\n\t\t\t\"\",\n\t\t\t\"auto eth0\",\n\t\t\t\"iface eth0 inet dhcp\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/resolv.conf\",\n\t\t\"nameserver 1.1.1.1\\nnameserver 8.8.8.8\\n\",\n\t);\n\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/hosts\",\n\t\t`${[\n\t\t\t\"127.0.0.1 localhost\",\n\t\t\t`127.0.1.1 ${hostname}`,\n\t\t\t\"::1 localhost ip6-localhost ip6-loopback\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tensureDir(vfs, \"/etc/cron.d\");\n\tensureDir(vfs, \"/etc/init.d\");\n\tensureDir(vfs, \"/etc/systemd\");\n\tensureDir(vfs, \"/etc/systemd/system\");\n}\n\n// \u2500\u2500\u2500 /etc/passwd + /etc/group + /etc/shadow \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Sync `/etc/passwd`, `/etc/group`, and `/etc/shadow` from the\n * VirtualUserManager's current user list into the VFS.\n * @param vfs VirtualFileSystem instance to write files into\n * @param users VirtualUserManager to source users from\n */\nexport function syncEtcPasswd(\n\tvfs: VirtualFileSystem,\n\tusers: VirtualUserManager,\n): void {\n\tconst userList = users.listUsers();\n\n\tconst passwdLines = [\n\t\t\"root:x:0:0:root:/root:/bin/bash\",\n\t\t\"daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\",\n\t\t\"www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\",\n\t\t\"nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin\",\n\t];\n\n\tlet uid = 1000;\n\tfor (const u of userList) {\n\t\tif (u === \"root\") continue;\n\t\tpasswdLines.push(`${u}:x:${uid}:${uid}::/home/${u}:/bin/bash`);\n\t\tuid++;\n\t}\n\n\tvfs.writeFile(\"/etc/passwd\", `${passwdLines.join(\"\\n\")}\\n`);\n\n\tconst groupLines = [\n\t\t\"root:x:0:\",\n\t\t\"daemon:x:1:\",\n\t\t`sudo:x:27:${userList.filter((u) => users.isSudoer(u)).join(\",\")}`,\n\t\t`users:x:100:${userList.filter((u) => u !== \"root\").join(\",\")}`,\n\t\t\"nogroup:x:65534:\",\n\t];\n\tvfs.writeFile(\"/etc/group\", `${groupLines.join(\"\\n\")}\\n`);\n\n\t// shadow \u2014 fake hashes, never real\n\tconst shadowLines = [\n\t\t\"root:*:19000:0:99999:7:::\",\n\t\t\"daemon:*:19000:0:99999:7:::\",\n\t];\n\tfor (const u of userList) {\n\t\tif (u === \"root\") continue;\n\t\tshadowLines.push(`${u}:!:19000:0:99999:7:::`);\n\t}\n\tvfs.writeFile(\"/etc/shadow\", `${shadowLines.join(\"\\n\")}\\n`, { mode: 0o640 });\n}\n\n// \u2500\u2500\u2500 /proc \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Derive a stable virtual PID from a tty string like \"pts/0\" \u2192 1000, \"pts/1\" \u2192 1001 */\nfunction ttyToPid(tty: string): number {\n\tconst match = tty.match(/(\\d+)$/);\n\treturn 1000 + (match?.[1] ? parseInt(match[1], 10) : 0);\n}\n\n/** Write /proc/<pid>/ subtree for a single virtual process */\nfunction writeProcPid(\n\tvfs: VirtualFileSystem,\n\tpid: number,\n\tusername: string,\n\t_tty: string,\n\tcmdline: string,\n\tstartedAt: string,\n\tenv: Record<string, string>,\n): void {\n\tconst dir = `/proc/${pid}`;\n\tensureDir(vfs, dir);\n\tensureDir(vfs, `${dir}/fd`);\n\tensureDir(vfs, `${dir}/fdinfo`);\n\n\tconst uptimeSec = Math.floor(\n\t\t(Date.now() - new Date(startedAt).getTime()) / 1000,\n\t);\n\n\tvfs.writeFile(`${dir}/cmdline`, `${cmdline.replace(/\\s+/g, \"\\0\")}\\0`);\n\tvfs.writeFile(`${dir}/comm`, cmdline.split(/\\s+/)[0] ?? \"bash\");\n\tvfs.writeFile(\n\t\t`${dir}/status`,\n\t\t`${[\n\t\t\t`Name: ${cmdline.split(/\\s+/)[0] ?? \"bash\"}`,\n\t\t\t`State: S (sleeping)`,\n\t\t\t`Pid: ${pid}`,\n\t\t\t`PPid: 1`,\n\t\t\t`Uid: 0\\t0\\t0\\t0`,\n\t\t\t`Gid: 0\\t0\\t0\\t0`,\n\t\t\t`VmRSS: 4096 kB`,\n\t\t\t`VmSize: 16384 kB`,\n\t\t\t`Threads: 1`,\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\tvfs.writeFile(\n\t\t`${dir}/stat`,\n\t\t`${pid} (${cmdline.split(/\\s+/)[0] ?? \"bash\"}) S 1 ${pid} ${pid} 0 -1 4194304 0 0 0 0 ${uptimeSec} 0 0 0 20 0 1 0 0 16384 4096 0\\n`,\n\t);\n\tvfs.writeFile(\n\t\t`${dir}/environ`,\n\t\t`${Object.entries(env)\n\t\t\t.map(([k, v]) => `${k}=${v}`)\n\t\t\t.join(\"\\0\")}\\0`,\n\t);\n\tvfs.writeFile(`${dir}/cwd`, `/home/${username}\\0`);\n\tvfs.writeFile(`${dir}/exe`, \"/bin/bash\\0\");\n\n\t// Standard fd entries\n\tvfs.writeFile(`${dir}/fd/0`, \"\");\n\tvfs.writeFile(`${dir}/fd/1`, \"\");\n\tvfs.writeFile(`${dir}/fd/2`, \"\");\n}\n\n/**\n * Populate and refresh `/proc` virtual entries based on host stats and\n * provided active sessions. Rewrites `/proc/uptime`, `/proc/meminfo`,\n * `/proc/cpuinfo`, `/proc/<pid>` entries and `/proc/self` content.\n * @param vfs VirtualFileSystem instance\n * @param props ShellProperties used for version strings\n * @param hostname Hostname to write into /proc/hostname\n * @param shellStartTime Start time used to compute uptime\n * @param sessions Optional active sessions list to populate per-pid entries\n */\nexport function refreshProc(\n\tvfs: VirtualFileSystem,\n\tprops: ShellProperties,\n\thostname: string,\n\tshellStartTime: number,\n\tsessions?: import(\"../VirtualUserManager\").VirtualActiveSession[],\n): void {\n\tensureDir(vfs, \"/proc\");\n\n\tconst uptimeSec = Math.floor((Date.now() - shellStartTime) / 1000);\n\tvfs.writeFile(\n\t\t\"/proc/uptime\",\n\t\t`${uptimeSec}.00 ${Math.floor(uptimeSec * 0.9)}.00\\n`,\n\t);\n\n\tconst totalMemKb = Math.floor(os.totalmem() / 1024);\n\tconst freeMemKb = Math.floor(os.freemem() / 1024);\n\tconst availMemKb = Math.floor(freeMemKb * 0.95);\n\tvfs.writeFile(\n\t\t\"/proc/meminfo\",\n\t\t`${[\n\t\t\t`MemTotal: ${String(totalMemKb).padStart(10)} kB`,\n\t\t\t`MemFree: ${String(freeMemKb).padStart(10)} kB`,\n\t\t\t`MemAvailable: ${String(availMemKb).padStart(10)} kB`,\n\t\t\t`Buffers: ${String(Math.floor(totalMemKb * 0.02)).padStart(10)} kB`,\n\t\t\t`Cached: ${String(Math.floor(totalMemKb * 0.15)).padStart(10)} kB`,\n\t\t\t`SwapTotal: ${String(Math.floor(totalMemKb * 0.5)).padStart(10)} kB`,\n\t\t\t`SwapFree: ${String(Math.floor(totalMemKb * 0.5)).padStart(10)} kB`,\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tconst cpus = os.cpus();\n\tconst cpuLines: string[] = [];\n\tfor (let i = 0; i < cpus.length; i++) {\n\t\tconst c = cpus[i];\n\t\tif (!c) continue;\n\t\tconst mhz = c.speed.toFixed(3);\n\t\tcpuLines.push(\n\t\t\t`processor\\t: ${i}`,\n\t\t\t`model name\\t: ${c.model}`,\n\t\t\t`cpu MHz\\t\\t: ${mhz}`,\n\t\t\t`cache size\\t: 8192 KB`,\n\t\t\t\"\",\n\t\t);\n\t}\n\tvfs.writeFile(\"/proc/cpuinfo\", `${cpuLines.join(\"\\n\")}\\n`);\n\n\tvfs.writeFile(\n\t\t\"/proc/version\",\n\t\t`Linux version ${props.kernel} (fortune@build) (gcc version 12.2.0) #1 SMP\\n`,\n\t);\n\n\tvfs.writeFile(\"/proc/hostname\", `${hostname}\\n`);\n\n\t// /proc/loadavg\n\tconst load = (Math.random() * 0.5).toFixed(2);\n\tconst numProcs = 1 + (sessions?.length ?? 0);\n\tvfs.writeFile(\n\t\t\"/proc/loadavg\",\n\t\t`${load} ${load} ${load} ${numProcs}/${numProcs} 1\\n`,\n\t);\n\n\t// /proc/net stubs\n\tensureDir(vfs, \"/proc/net\");\n\tensureFile(\n\t\tvfs,\n\t\t\"/proc/net/dev\",\n\t\t`${[\n\t\t\t\"Inter-| Receive | Transmit\",\n\t\t\t\" face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\",\n\t\t\t\" lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\",\n\t\t\t\" eth0: 131072 1024 0 0 0 0 0 0 65536 512 0 0 0 0 0 0\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\t// \u2500\u2500 /proc/1 \u2014 init process \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\twriteProcPid(\n\t\tvfs,\n\t\t1,\n\t\t\"root\",\n\t\t\"pts/0\",\n\t\t\"/sbin/init\",\n\t\tnew Date(shellStartTime).toISOString(),\n\t\t{},\n\t);\n\n\t// \u2500\u2500 /proc/<pid> per session \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\tconst activeSessions = sessions ?? [];\n\tfor (const session of activeSessions) {\n\t\tconst pid = ttyToPid(session.tty);\n\t\twriteProcPid(\n\t\t\tvfs,\n\t\t\tpid,\n\t\t\tsession.username,\n\t\t\tsession.tty,\n\t\t\t\"bash\",\n\t\t\tsession.startedAt,\n\t\t\t{\n\t\t\t\tUSER: session.username,\n\t\t\t\tHOME: `/home/${session.username}`,\n\t\t\t\tTERM: \"xterm-256color\",\n\t\t\t\tSHELL: \"/bin/bash\",\n\t\t\t},\n\t\t);\n\t}\n\n\t// \u2500\u2500 /proc/self \u2014 symlink to current session PID or 1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\t// We can't know which session is \"current\" at populate time,\n\t// so /proc/self is a directory that mirrors the most recent session,\n\t// or init if no sessions. Commands that read /proc/self get consistent data.\n\tconst selfPid =\n\t\tactiveSessions.length > 0\n\t\t\t? ttyToPid(activeSessions[activeSessions.length - 1]!.tty)\n\t\t\t: 1;\n\n\t// Remove existing /proc/self and recreate as content copy\n\tif (vfs.exists(\"/proc/self\")) {\n\t\ttry {\n\t\t\tvfs.remove(\"/proc/self\");\n\t\t} catch {}\n\t}\n\t// /proc/self is a real directory (not a symlink, which VFS may not support for dirs)\n\tconst selfSrc = `/proc/${selfPid}`;\n\tif (vfs.exists(selfSrc)) {\n\t\tensureDir(vfs, \"/proc/self\");\n\t\tensureDir(vfs, \"/proc/self/fd\");\n\t\tfor (const entry of vfs.list(selfSrc)) {\n\t\t\tconst srcPath = `${selfSrc}/${entry}`;\n\t\t\tconst dstPath = `/proc/self/${entry}`;\n\t\t\ttry {\n\t\t\t\tconst st = vfs.stat(srcPath);\n\t\t\t\tif (st.type === \"file\") {\n\t\t\t\t\tvfs.writeFile(dstPath, vfs.readFile(srcPath));\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t\tvfs.writeFile(\n\t\t\t\"/proc/self/status\",\n\t\t\tvfs.exists(`${selfSrc}/status`) ? vfs.readFile(`${selfSrc}/status`) : \"\",\n\t\t);\n\t} else {\n\t\t// Fallback minimal /proc/self\n\t\tensureDir(vfs, \"/proc/self\");\n\t\tvfs.writeFile(\"/proc/self/cmdline\", \"bash\\0\");\n\t\tvfs.writeFile(\"/proc/self/comm\", \"bash\");\n\t\tvfs.writeFile(\n\t\t\t\"/proc/self/status\",\n\t\t\t\"Name:\\tbash\\nState:\\tS (sleeping)\\nPid:\\t1\\nPPid:\\t0\\n\",\n\t\t);\n\t\tvfs.writeFile(\"/proc/self/environ\", \"\");\n\t\tvfs.writeFile(\"/proc/self/cwd\", \"/root\\0\");\n\t\tvfs.writeFile(\"/proc/self/exe\", \"/bin/bash\\0\");\n\t}\n}\n\n// \u2500\u2500\u2500 /sys \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapSys(vfs: VirtualFileSystem, props: ShellProperties): void {\n\tensureDir(vfs, \"/sys\");\n\tensureDir(vfs, \"/sys/devices\");\n\tensureDir(vfs, \"/sys/devices/virtual\");\n\tensureDir(vfs, \"/sys/devices/virtual/dmi\");\n\tensureDir(vfs, \"/sys/devices/virtual/dmi/id\");\n\n\tensureFile(\n\t\tvfs,\n\t\t\"/sys/devices/virtual/dmi/id/sys_vendor\",\n\t\t\"Fortune Systems\\n\",\n\t);\n\tensureFile(\n\t\tvfs,\n\t\t\"/sys/devices/virtual/dmi/id/product_name\",\n\t\t\"VirtualContainer v1\\n\",\n\t);\n\tensureFile(vfs, \"/sys/devices/virtual/dmi/id/board_name\", \"fortune-board\\n\");\n\n\tensureDir(vfs, \"/sys/class\");\n\tensureDir(vfs, \"/sys/class/net\");\n\n\tensureDir(vfs, \"/sys/kernel\");\n\tensureFile(vfs, \"/sys/kernel/hostname\", \"fortune-vm\\n\");\n\tensureFile(vfs, \"/sys/kernel/osrelease\", `${props.kernel}\\n`);\n\tensureFile(vfs, \"/sys/kernel/ostype\", \"Linux\\n\");\n}\n\n// \u2500\u2500\u2500 /dev \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapDev(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/dev\");\n\tensureFile(vfs, \"/dev/null\", \"\", 0o666);\n\tensureFile(vfs, \"/dev/zero\", \"\", 0o666);\n\tensureFile(vfs, \"/dev/random\", \"\", 0o444);\n\tensureFile(vfs, \"/dev/urandom\", \"\", 0o444);\n\tensureDir(vfs, \"/dev/pts\");\n\tensureDir(vfs, \"/dev/shm\");\n}\n\n// \u2500\u2500\u2500 /usr \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapUsr(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/usr\");\n\tensureDir(vfs, \"/usr/bin\");\n\tensureDir(vfs, \"/usr/sbin\");\n\tensureDir(vfs, \"/usr/local\");\n\tensureDir(vfs, \"/usr/local/bin\");\n\tensureDir(vfs, \"/usr/local/lib\");\n\tensureDir(vfs, \"/usr/local/share\");\n\tensureDir(vfs, \"/usr/share\");\n\tensureDir(vfs, \"/usr/share/doc\");\n\tensureDir(vfs, \"/usr/share/man\");\n\tensureDir(vfs, \"/usr/share/man/man1\");\n\tensureDir(vfs, \"/usr/lib\");\n\n\t// Stub binaries so `which` can find built-in commands\n\tconst builtins = [\n\t\t\"sh\",\n\t\t\"bash\",\n\t\t\"ls\",\n\t\t\"cat\",\n\t\t\"echo\",\n\t\t\"grep\",\n\t\t\"find\",\n\t\t\"sort\",\n\t\t\"head\",\n\t\t\"tail\",\n\t\t\"cut\",\n\t\t\"tr\",\n\t\t\"sed\",\n\t\t\"awk\",\n\t\t\"wc\",\n\t\t\"tee\",\n\t\t\"tar\",\n\t\t\"gzip\",\n\t\t\"gunzip\",\n\t\t\"touch\",\n\t\t\"mkdir\",\n\t\t\"rm\",\n\t\t\"mv\",\n\t\t\"cp\",\n\t\t\"chmod\",\n\t\t\"ln\",\n\t\t\"pwd\",\n\t\t\"env\",\n\t\t\"date\",\n\t\t\"sleep\",\n\t\t\"id\",\n\t\t\"whoami\",\n\t\t\"hostname\",\n\t\t\"uname\",\n\t\t\"ps\",\n\t\t\"kill\",\n\t\t\"df\",\n\t\t\"du\",\n\t\t\"curl\",\n\t\t\"wget\",\n\t\t\"nano\",\n\t\t\"diff\",\n\t\t\"uniq\",\n\t\t\"xargs\",\n\t\t\"base64\",\n\t];\n\tfor (const bin of builtins) {\n\t\tensureFile(\n\t\t\tvfs,\n\t\t\t`/usr/bin/${bin}`,\n\t\t\t`#!/bin/sh\\nexec builtin ${bin} \"$@\"\\n`,\n\t\t\t0o755,\n\t\t);\n\t}\n\n\t// lsb_release script\n\tensureFile(\n\t\tvfs,\n\t\t\"/usr/bin/lsb_release\",\n\t\t'#!/bin/sh\\nexec lsb_release \"$@\"\\n',\n\t\t0o755,\n\t);\n}\n\n// \u2500\u2500\u2500 /var \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapVar(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/var\");\n\tensureDir(vfs, \"/var/log\");\n\tensureDir(vfs, \"/var/tmp\");\n\tensureDir(vfs, \"/var/run\");\n\tensureDir(vfs, \"/var/cache\");\n\tensureDir(vfs, \"/var/cache/apt\");\n\tensureDir(vfs, \"/var/cache/apt/archives\");\n\tensureDir(vfs, \"/var/lib\");\n\tensureDir(vfs, \"/var/lib/apt\");\n\tensureDir(vfs, \"/var/lib/apt/lists\");\n\tensureDir(vfs, \"/var/lib/dpkg\");\n\tensureDir(vfs, \"/var/lib/dpkg/info\");\n\n\t// dpkg status \u2014 starts empty, apt install populates it\n\tensureFile(vfs, \"/var/lib/dpkg/status\", \"\");\n\tensureFile(vfs, \"/var/lib/dpkg/available\", \"\");\n\n\t// syslog stub\n\tensureFile(\n\t\tvfs,\n\t\t\"/var/log/syslog\",\n\t\t`${new Date().toUTCString()} fortune kernel: Virtual container started\\n`,\n\t);\n\tensureFile(vfs, \"/var/log/auth.log\", \"\");\n\tensureFile(vfs, \"/var/log/dpkg.log\", \"\");\n\tensureFile(vfs, \"/var/log/apt/history.log\", \"\");\n\tensureFile(vfs, \"/var/log/apt/term.log\", \"\");\n}\n\n// \u2500\u2500\u2500 /bin + /sbin symlinks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapBin(vfs: VirtualFileSystem): void {\n\t// On modern Debian/Ubuntu /bin is a symlink to /usr/bin\n\tif (!vfs.exists(\"/bin\")) {\n\t\tvfs.symlink(\"/usr/bin\", \"/bin\");\n\t}\n\tif (!vfs.exists(\"/sbin\")) {\n\t\tvfs.symlink(\"/usr/sbin\", \"/sbin\");\n\t}\n\tif (!vfs.exists(\"/lib\")) {\n\t\tensureDir(vfs, \"/lib\");\n\t}\n\tif (!vfs.exists(\"/lib64\")) {\n\t\tensureDir(vfs, \"/lib64\");\n\t}\n}\n\n// \u2500\u2500\u2500 /tmp \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapTmp(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/tmp\", 0o1777);\n}\n\n// \u2500\u2500\u2500 /root \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapRoot(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/root\", 0o700);\n\tensureFile(\n\t\tvfs,\n\t\t\"/root/.bashrc\",\n\t\t`${[\n\t\t\t\"# root .bashrc\",\n\t\t\t\"export PS1='\\\\[\\\\033[0;31m\\\\]\\\\u@\\\\h\\\\[\\\\033[0m\\\\]:\\\\[\\\\033[0;34m\\\\]\\\\w\\\\[\\\\033[0m\\\\]# '\",\n\t\t\t\"export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\n\t\t\t\"alias ll='ls -la'\",\n\t\t\t\"alias la='ls -A'\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\tensureFile(vfs, \"/root/.profile\", \"[ -f ~/.bashrc ] && . ~/.bashrc\\n\");\n\t// Fix: /home/root should map to /root for root user\n\tif (!vfs.exists(\"/home/root\")) {\n\t\tvfs.symlink(\"/root\", \"/home/root\");\n\t}\n}\n\n// \u2500\u2500\u2500 /opt + /srv + /mnt + /media \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapMisc(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/opt\");\n\tensureDir(vfs, \"/srv\");\n\tensureDir(vfs, \"/mnt\");\n\tensureDir(vfs, \"/media\");\n}\n\n// \u2500\u2500\u2500 main entry point \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Bootstraps the full Linux rootfs hierarchy in the VFS.\n * Safe to call multiple times \u2014 idempotent.\n *\n * @param vfs Target virtual filesystem.\n * @param users User manager (for /etc/passwd sync).\n * @param hostname Virtual hostname.\n * @param props Shell properties (kernel, os, arch).\n * @param shellStartTime Unix ms of shell creation (for uptime).\n */\nexport function bootstrapLinuxRootfs(\n\tvfs: VirtualFileSystem,\n\tusers: VirtualUserManager,\n\thostname: string,\n\tprops: ShellProperties,\n\tshellStartTime: number,\n): void {\n\tbootstrapEtc(vfs, hostname, props);\n\tbootstrapSys(vfs, props);\n\tbootstrapDev(vfs);\n\tbootstrapUsr(vfs);\n\tbootstrapVar(vfs);\n\tbootstrapBin(vfs);\n\tbootstrapTmp(vfs);\n\tbootstrapRoot(vfs);\n\tbootstrapMisc(vfs);\n\trefreshProc(vfs, props, hostname, shellStartTime, []);\n\tsyncEtcPasswd(vfs, users);\n}\n", "export type PerfLogger = {\n\tenabled: boolean;\n\tmark: (label: string) => void;\n\tdone: (label?: string) => void;\n};\n\nfunction isTruthyEnv(value: string | undefined): boolean {\n\treturn value === \"1\" || value === \"true\";\n}\n\nfunction nowMs(): number {\n\tif (\n\t\ttypeof performance !== \"undefined\" &&\n\t\ttypeof performance.now === \"function\"\n\t) {\n\t\treturn performance.now();\n\t}\n\n\treturn Date.now();\n}\n\nexport function isPerfLoggingEnabled(): boolean {\n\treturn (\n\t\tisTruthyEnv(process.env.DEV_MODE) || isTruthyEnv(process.env.RENDER_PERF)\n\t);\n}\n\nexport function createPerfLogger(scope: string): PerfLogger {\n\tconst enabled = isPerfLoggingEnabled();\n\tif (!enabled) {\n\t\treturn {\n\t\t\tenabled,\n\t\t\tmark: () => undefined,\n\t\t\tdone: () => undefined,\n\t\t};\n\t}\n\n\tconst startedAt = nowMs();\n\n\tconst mark = (label: string): void => {\n\t\tconst elapsedMs = nowMs() - startedAt;\n\t\tconsole.log(`[perf][${scope}] ${label}: ${elapsedMs.toFixed(1)}ms`);\n\t};\n\n\tconst done = (label = \"done\"): void => {\n\t\tmark(label);\n\t};\n\n\treturn {\n\t\tenabled,\n\t\tmark,\n\t\tdone,\n\t};\n}\n\nexport async function withPerf<T>(\n\tscope: string,\n\tlabel: string,\n\twork: () => Promise<T>,\n): Promise<T> {\n\tconst perf = createPerfLogger(scope);\n\tif (!perf.enabled) {\n\t\treturn work();\n\t}\n\n\tperf.mark(`${label}:start`);\n\ttry {\n\t\treturn await work();\n\t} finally {\n\t\tperf.done(`${label}:done`);\n\t}\n}\n", "import { EventEmitter } from \"node:events\";\nimport * as fsSync from \"node:fs\";\nimport * as path from \"node:path\";\nimport { gunzipSync, gzipSync } from \"node:zlib\";\nimport type {\n\tInternalDirectoryNode,\n\tInternalFileNode,\n\tInternalNode,\n} from \"./internalTypes\";\nimport { decodeVfs, encodeVfs, isBinarySnapshot } from \"./binaryPack\";\nimport { getNode, getParentDirectory, normalizePath } from \"./path\";\nimport type {\n\tRemoveOptions,\n\tVfsNodeStats,\n\tVfsSnapshot,\n\tVfsSnapshotDirectoryNode,\n\tVfsSnapshotFileNode,\n\tVfsSnapshotNode,\n\tWriteFileOptions,\n} from \"../types/vfs\";\n\n// \u2500\u2500 Persistence options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * \"memory\" \u2014 pure in-memory, no disk I/O (default).\n *\n * \"fs\" \u2014 mirrors the VFS tree to a directory on the host filesystem.\n * `snapshotPath` must be set to the directory where the binary\n * snapshot file will be read/written (`vfs-snapshot.vfsb`).\n */\nexport type VfsPersistenceMode = \"memory\" | \"fs\";\n\nexport interface VfsOptions {\n\t/**\n\t * Persistence mode.\n\t * - `\"memory\"` (default): no disk access, snapshot via `toSnapshot()`.\n\t * - `\"fs\"`: auto-save JSON snapshot to `snapshotPath` on every\n\t * `flushMirror()` call, and restore from it on `restoreMirror()`.\n\t */\n\tmode?: VfsPersistenceMode;\n\t/**\n\t * Directory used by `\"fs\"` mode.\n\t * The snapshot file will be written to `<snapshotPath>/vfs-snapshot.json`.\n\t * Required when `mode` is `\"fs\"`.\n\t */\n\tsnapshotPath?: string;\n}\n\n// \u2500\u2500 VirtualFileSystem \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * In-memory virtual filesystem with optional JSON-snapshot persistence.\n *\n * **Memory mode** (default) \u2014 all state lives in a fast recursive tree.\n * Use `toSnapshot()` / `fromSnapshot()` / `importSnapshot()` for serialisation.\n *\n * **FS mode** \u2014 same in-memory tree, but `restoreMirror()` loads a binary\n * snapshot from disk and `flushMirror()` writes it back. This gives you\n * persistent VFS state across process restarts without any real POSIX filesystem\n * semantics leaking through.\n *\n * @example\n * ```ts\n * // Pure in-memory (default)\n * const vfs = new VirtualFileSystem();\n *\n * // With disk persistence\n * const vfs = new VirtualFileSystem({ mode: \"fs\", snapshotPath: \"./data\" });\n * await vfs.restoreMirror(); // load from disk (no-op if no snapshot yet)\n * // ... use vfs ...\n * await vfs.flushMirror(); // persist to disk\n * ```\n */\nclass VirtualFileSystem extends EventEmitter {\n\tprivate root: InternalDirectoryNode;\n\tprivate readonly mode: VfsPersistenceMode;\n\tprivate readonly snapshotFile: string | null;\n\n\tconstructor(options: VfsOptions = {}) {\n\t\tsuper();\n\t\tthis.mode = options.mode ?? \"memory\";\n\t\tif (this.mode === \"fs\") {\n\t\t\tif (!options.snapshotPath) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'VirtualFileSystem: \"snapshotPath\" is required when mode is \"fs\".',\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.snapshotFile = path.resolve(\n\t\t\t\toptions.snapshotPath,\n\t\t\t\t\"vfs-snapshot.vfsb\",\n\t\t\t);\n\t\t} else {\n\t\t\tthis.snapshotFile = null;\n\t\t}\n\t\tthis.root = this.makeDir(\"\", 0o755);\n\t}\n\n\t// \u2500\u2500 Internal helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate makeDir(name: string, mode: number): InternalDirectoryNode {\n\t\tconst now = new Date();\n\t\treturn {\n\t\t\ttype: \"directory\",\n\t\t\tname,\n\t\t\tmode,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t\tchildren: new Map(),\n\t\t};\n\t}\n\n\tprivate makeFile(\n\t\tname: string,\n\t\tcontent: Buffer,\n\t\tmode: number,\n\t\tcompressed: boolean,\n\t): InternalFileNode {\n\t\tconst now = new Date();\n\t\treturn {\n\t\t\ttype: \"file\",\n\t\t\tname,\n\t\t\tcontent,\n\t\t\tmode,\n\t\t\tcompressed,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t};\n\t}\n\n\tprivate mkdirRecursive(targetPath: string, mode: number): void {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tif (normalized === \"/\") return;\n\t\tconst parts = normalized.split(\"/\").filter(Boolean);\n\t\tlet current = this.root;\n\t\tlet builtPath = \"\";\n\t\tfor (const part of parts) {\n\t\t\tbuiltPath += `/${part}`;\n\t\t\tlet child = current.children.get(part);\n\t\t\tif (!child) {\n\t\t\t\tchild = this.makeDir(part, mode);\n\t\t\t\tcurrent.children.set(part, child);\n\t\t\t\tthis.emit(\"dir:create\", { path: builtPath, mode });\n\t\t\t} else if (child.type !== \"directory\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot create directory '${builtPath}': path is a file.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcurrent = child as InternalDirectoryNode;\n\t\t}\n\t}\n\n\t// \u2500\u2500 Persistence \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\t/**\n\t * In `\"fs\"` mode: reads the binary snapshot (`vfs-snapshot.vfsb`) from disk.\n\t * Automatically falls back to legacy JSON format for backward compatibility.\n\t * Silently succeeds when the snapshot file does not exist yet.\n\t *\n\t * In `\"memory\"` mode: no-op (kept for API compatibility).\n\t */\n\tpublic async restoreMirror(): Promise<void> {\n\t\tif (this.mode !== \"fs\" || !this.snapshotFile) return;\n\n\t\tif (!fsSync.existsSync(this.snapshotFile)) return;\n\n\t\ttry {\n\t\t\tconst raw = fsSync.readFileSync(this.snapshotFile);\n\t\t\tif (isBinarySnapshot(raw)) {\n\t\t\t\t// Fast binary format (current)\n\t\t\t\tthis.root = decodeVfs(raw);\n\t\t\t} else {\n\t\t\t\t// Legacy JSON fallback \u2014 auto-migrates on next flushMirror()\n\t\t\t\tconst snapshot: VfsSnapshot = JSON.parse(raw.toString(\"utf8\"));\n\t\t\t\tthis.root = this.deserializeDir(snapshot.root, \"\");\n\t\t\t\tconsole.info(\n\t\t\t\t\t\"[VirtualFileSystem] Migrating legacy JSON snapshot to binary format.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.emit(\"snapshot:restore\", { path: this.snapshotFile });\n\t\t} catch (err) {\n\t\t\t// Corrupt or unreadable snapshot \u2014 start fresh and warn\n\t\t\tconsole.warn(\n\t\t\t\t`[VirtualFileSystem] Could not restore snapshot from ${this.snapshotFile}:`,\n\t\t\t\terr instanceof Error ? err.message : String(err),\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * In `\"fs\"` mode: serialises the in-memory tree to a binary snapshot on disk\n\t * (`vfs-snapshot.vfsb`). ~27% smaller and significantly faster than JSON+base64.\n\t * The directory is created if it does not exist.\n\t *\n\t * In `\"memory\"` mode: emits `\"mirror:flush\"` and returns (no disk write).\n\t */\n\tpublic async flushMirror(): Promise<void> {\n\t\tif (this.mode !== \"fs\" || !this.snapshotFile) {\n\t\t\tthis.emit(\"mirror:flush\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst dir = path.dirname(this.snapshotFile);\n\t\tfsSync.mkdirSync(dir, { recursive: true });\n\t\tconst binary = encodeVfs(this.root);\n\t\tfsSync.writeFileSync(this.snapshotFile, binary);\n\t\tthis.emit(\"mirror:flush\", { path: this.snapshotFile });\n\t}\n\n\t/** Returns the current persistence mode. */\n\tpublic getMode(): VfsPersistenceMode {\n\t\treturn this.mode;\n\t}\n\n\t/** Returns the snapshot file path used in `\"fs\"` mode, or `null`. */\n\tpublic getSnapshotPath(): string | null {\n\t\treturn this.snapshotFile;\n\t}\n\n\t// \u2500\u2500 Public filesystem API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\t/** Creates a directory (and any missing parents). */\n\tpublic mkdir(targetPath: string, mode: number = 0o755): void {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst existing = (() => {\n\t\t\ttry {\n\t\t\t\treturn getNode(this.root, normalized);\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t})();\n\t\tif (existing && existing.type !== \"directory\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot create directory '${normalized}': path is a file.`,\n\t\t\t);\n\t\t}\n\t\tthis.mkdirRecursive(normalized, mode);\n\t}\n\n\t/**\n\t * Writes UTF-8 text or binary content into a file.\n\t * Parent directories are created when missing.\n\t */\n\tpublic writeFile(\n\t\ttargetPath: string,\n\t\tcontent: string | Buffer,\n\t\toptions: WriteFileOptions = {},\n\t): void {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst { parent, name } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\tnormalized,\n\t\t\ttrue,\n\t\t\t(p) => this.mkdirRecursive(p, 0o755),\n\t\t);\n\n\t\tconst existing = parent.children.get(name);\n\t\tif (existing?.type === \"directory\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot write file '${normalized}': path is a directory.`,\n\t\t\t);\n\t\t}\n\n\t\tconst rawContent = Buffer.isBuffer(content)\n\t\t\t? content\n\t\t\t: Buffer.from(content, \"utf8\");\n\t\tconst shouldCompress = options.compress ?? false;\n\t\tconst storedContent = shouldCompress ? gzipSync(rawContent) : rawContent;\n\t\tconst mode = options.mode ?? 0o644;\n\n\t\tif (existing) {\n\t\t\tconst f = existing as InternalFileNode;\n\t\t\tf.content = storedContent;\n\t\t\tf.compressed = shouldCompress;\n\t\t\tf.mode = mode;\n\t\t\tf.updatedAt = new Date();\n\t\t} else {\n\t\t\tparent.children.set(\n\t\t\t\tname,\n\t\t\t\tthis.makeFile(name, storedContent, mode, shouldCompress),\n\t\t\t);\n\t\t}\n\n\t\tthis.emit(\"file:write\", { path: normalized, size: storedContent.length });\n\t}\n\n\t/**\n\t * Reads file content as a UTF-8 string.\n\t * Gzip-compressed files are transparently decompressed.\n\t */\n\tpublic readFile(targetPath: string): string {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type !== \"file\") {\n\t\t\tthrow new Error(`Cannot read '${targetPath}': not a file.`);\n\t\t}\n\t\tconst f = node as InternalFileNode;\n\t\tconst raw = f.compressed ? gunzipSync(f.content) : f.content;\n\t\tthis.emit(\"file:read\", { path: normalized, size: raw.length });\n\t\treturn raw.toString(\"utf8\");\n\t}\n\n\t/** Reads file content as a Buffer (decompresses if needed). */\n\tpublic readFileRaw(targetPath: string): Buffer {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type !== \"file\") {\n\t\t\tthrow new Error(`Cannot read '${targetPath}': not a file.`);\n\t\t}\n\t\tconst f = node as InternalFileNode;\n\t\tconst raw = f.compressed ? gunzipSync(f.content) : f.content;\n\t\tthis.emit(\"file:read\", { path: normalized, size: raw.length });\n\t\treturn raw;\n\t}\n\n\t/** Returns true when a file or directory exists at path. */\n\tpublic exists(targetPath: string): boolean {\n\t\ttry {\n\t\t\tgetNode(this.root, normalizePath(targetPath));\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/** Updates mode bits on a node. */\n\tpublic chmod(targetPath: string, mode: number): void {\n\t\tgetNode(this.root, normalizePath(targetPath)).mode = mode;\n\t}\n\n\t/** Returns metadata for a file or directory. */\n\tpublic stat(targetPath: string): VfsNodeStats {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tconst name = normalized === \"/\" ? \"\" : path.posix.basename(normalized);\n\t\tif (node.type === \"file\") {\n\t\t\tconst f = node as InternalFileNode;\n\t\t\treturn {\n\t\t\t\ttype: \"file\",\n\t\t\t\tname,\n\t\t\t\tpath: normalized,\n\t\t\t\tmode: f.mode,\n\t\t\t\tcreatedAt: f.createdAt,\n\t\t\t\tupdatedAt: f.updatedAt,\n\t\t\t\tcompressed: f.compressed,\n\t\t\t\tsize: f.content.length,\n\t\t\t};\n\t\t}\n\t\tconst d = node as InternalDirectoryNode;\n\t\treturn {\n\t\t\ttype: \"directory\",\n\t\t\tname,\n\t\t\tpath: normalized,\n\t\t\tmode: d.mode,\n\t\t\tcreatedAt: d.createdAt,\n\t\t\tupdatedAt: d.updatedAt,\n\t\t\tchildrenCount: d.children.size,\n\t\t};\n\t}\n\n\t/** Lists direct children names of a directory (sorted). */\n\tpublic list(dirPath: string = \"/\"): string[] {\n\t\tconst normalized = normalizePath(dirPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type !== \"directory\") {\n\t\t\tthrow new Error(`Cannot list '${dirPath}': not a directory.`);\n\t\t}\n\t\treturn Array.from((node as InternalDirectoryNode).children.keys()).sort();\n\t}\n\n\t/** Renders ASCII tree view of a directory hierarchy. */\n\tpublic tree(dirPath: string = \"/\"): string {\n\t\tconst normalized = normalizePath(dirPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type !== \"directory\") {\n\t\t\tthrow new Error(`Cannot render tree for '${dirPath}': not a directory.`);\n\t\t}\n\t\tconst label = dirPath === \"/\" ? \"/\" : path.posix.basename(normalized);\n\t\treturn this.renderTreeLines(node as InternalDirectoryNode, label);\n\t}\n\n\tprivate renderTreeLines(dir: InternalDirectoryNode, label: string): string {\n\t\tconst lines = [label];\n\t\tconst entries = Array.from(dir.children.keys()).sort();\n\t\tfor (let i = 0; i < entries.length; i++) {\n\t\t\tconst name = entries[i]!;\n\t\t\tconst child = dir.children.get(name)!;\n\t\t\tconst isLast = i === entries.length - 1;\n\t\t\tconst connector = isLast ? \"\u2514\u2500\u2500 \" : \"\u251C\u2500\u2500 \";\n\t\t\tconst nextPrefix = isLast ? \" \" : \"\u2502 \";\n\t\t\tlines.push(`${connector}${name}`);\n\t\t\tif (child.type === \"directory\") {\n\t\t\t\tconst sub = this.renderTreeLines(child as InternalDirectoryNode, \"\")\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.slice(1)\n\t\t\t\t\t.map((l) => `${nextPrefix}${l}`);\n\t\t\t\tlines.push(...sub);\n\t\t\t}\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\t/** Computes total stored bytes under a path. */\n\tpublic getUsageBytes(targetPath: string = \"/\"): number {\n\t\treturn this.computeUsage(getNode(this.root, normalizePath(targetPath)));\n\t}\n\n\tprivate computeUsage(node: InternalNode): number {\n\t\tif (node.type === \"file\") return (node as InternalFileNode).content.length;\n\t\tlet total = 0;\n\t\tfor (const child of (node as InternalDirectoryNode).children.values()) {\n\t\t\ttotal += this.computeUsage(child);\n\t\t}\n\t\treturn total;\n\t}\n\n\t/** Compresses a file's content with gzip in place. */\n\tpublic compressFile(targetPath: string): void {\n\t\tconst node = getNode(this.root, normalizePath(targetPath));\n\t\tif (node.type !== \"file\")\n\t\t\tthrow new Error(`Cannot compress '${targetPath}': not a file.`);\n\t\tconst f = node as InternalFileNode;\n\t\tif (!f.compressed) {\n\t\t\tf.content = gzipSync(f.content);\n\t\t\tf.compressed = true;\n\t\t\tf.updatedAt = new Date();\n\t\t}\n\t}\n\n\t/** Decompresses a gzip-compressed file in place. */\n\tpublic decompressFile(targetPath: string): void {\n\t\tconst node = getNode(this.root, normalizePath(targetPath));\n\t\tif (node.type !== \"file\")\n\t\t\tthrow new Error(`Cannot decompress '${targetPath}': not a file.`);\n\t\tconst f = node as InternalFileNode;\n\t\tif (f.compressed) {\n\t\t\tf.content = gunzipSync(f.content);\n\t\t\tf.compressed = false;\n\t\t\tf.updatedAt = new Date();\n\t\t}\n\t}\n\n\t/**\n\t * Creates a symbolic link.\n\t * The link node is stored with mode `0o120777` (POSIX symlink convention).\n\t */\n\tpublic symlink(targetPath: string, linkPath: string): void {\n\t\tconst normalizedLink = normalizePath(linkPath);\n\t\tconst normalizedTarget = targetPath.startsWith(\"/\")\n\t\t\t? normalizePath(targetPath)\n\t\t\t: targetPath;\n\t\tconst { parent, name } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\tnormalizedLink,\n\t\t\ttrue,\n\t\t\t(p) => this.mkdirRecursive(p, 0o755),\n\t\t);\n\t\tconst symNode: InternalFileNode = {\n\t\t\ttype: \"file\",\n\t\t\tname,\n\t\t\tcontent: Buffer.from(normalizedTarget, \"utf8\"),\n\t\t\tmode: 0o120777,\n\t\t\tcompressed: false,\n\t\t\tcreatedAt: new Date(),\n\t\t\tupdatedAt: new Date(),\n\t\t};\n\t\tparent.children.set(name, symNode);\n\t\tthis.emit(\"symlink:create\", {\n\t\t\tlink: normalizedLink,\n\t\t\ttarget: normalizedTarget,\n\t\t});\n\t}\n\n\t/** Returns true when the path is a symbolic link node. */\n\tpublic isSymlink(targetPath: string): boolean {\n\t\ttry {\n\t\t\tconst node = getNode(this.root, normalizePath(targetPath));\n\t\t\treturn node.type === \"file\" && node.mode === 0o120777;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Resolves a symlink chain up to `maxDepth` hops.\n\t * Throws when the chain is too long (circular links).\n\t */\n\tpublic resolveSymlink(linkPath: string, maxDepth = 8): string {\n\t\tlet current = normalizePath(linkPath);\n\t\tfor (let depth = 0; depth < maxDepth; depth++) {\n\t\t\ttry {\n\t\t\t\tconst node = getNode(this.root, current);\n\t\t\t\tif (node.type === \"file\" && node.mode === 0o120777) {\n\t\t\t\t\tconst target = (node as InternalFileNode).content.toString(\"utf8\");\n\t\t\t\t\tcurrent = target.startsWith(\"/\")\n\t\t\t\t\t\t? target\n\t\t\t\t\t\t: normalizePath(\n\t\t\t\t\t\t\t\tpath.posix.join(path.posix.dirname(current), target),\n\t\t\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn current;\n\t\t}\n\t\tthrow new Error(`Too many levels of symbolic links: ${linkPath}`);\n\t}\n\n\t/** Removes a file or directory node. */\n\tpublic remove(targetPath: string, options: RemoveOptions = {}): void {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tif (normalized === \"/\") throw new Error(\"Cannot remove root directory.\");\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type === \"directory\") {\n\t\t\tconst dir = node as InternalDirectoryNode;\n\t\t\tif (!options.recursive && dir.children.size > 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Directory '${normalized}' is not empty. Use recursive option.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tconst { parent, name } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\tnormalized,\n\t\t\tfalse,\n\t\t\t() => {},\n\t\t);\n\t\tparent.children.delete(name);\n\t\tthis.emit(\"node:remove\", { path: normalized });\n\t}\n\n\t/** Moves or renames a node. */\n\tpublic move(fromPath: string, toPath: string): void {\n\t\tconst fromNormalized = normalizePath(fromPath);\n\t\tconst toNormalized = normalizePath(toPath);\n\t\tif (fromNormalized === \"/\" || toNormalized === \"/\") {\n\t\t\tthrow new Error(\"Cannot move root directory.\");\n\t\t}\n\t\tconst node = getNode(this.root, fromNormalized);\n\t\tif (this.exists(toNormalized)) {\n\t\t\tthrow new Error(`Destination '${toNormalized}' already exists.`);\n\t\t}\n\t\tthis.mkdirRecursive(path.posix.dirname(toNormalized), 0o755);\n\t\tconst { parent: destParent, name: destName } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\ttoNormalized,\n\t\t\tfalse,\n\t\t\t() => {},\n\t\t);\n\t\tconst { parent: srcParent, name: srcName } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\tfromNormalized,\n\t\t\tfalse,\n\t\t\t() => {},\n\t\t);\n\t\tsrcParent.children.delete(srcName);\n\t\tnode.name = destName;\n\t\tdestParent.children.set(destName, node);\n\t}\n\n\t// \u2500\u2500 Snapshot serialisation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\t/**\n\t * Exports the entire filesystem as a JSON-serialisable snapshot.\n\t *\n\t * Works regardless of the persistence mode. Useful for test fixtures,\n\t * manual backups, or passing VFS state between processes.\n\t */\n\tpublic toSnapshot(): VfsSnapshot {\n\t\treturn { root: this.serializeDir(this.root) };\n\t}\n\n\tprivate serializeDir(dir: InternalDirectoryNode): VfsSnapshotDirectoryNode {\n\t\tconst children: VfsSnapshotNode[] = [];\n\t\tfor (const child of dir.children.values()) {\n\t\t\tchildren.push(\n\t\t\t\tchild.type === \"file\"\n\t\t\t\t\t? this.serializeFile(child as InternalFileNode)\n\t\t\t\t\t: this.serializeDir(child as InternalDirectoryNode),\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\ttype: \"directory\",\n\t\t\tname: dir.name,\n\t\t\tmode: dir.mode,\n\t\t\tcreatedAt: dir.createdAt.toISOString(),\n\t\t\tupdatedAt: dir.updatedAt.toISOString(),\n\t\t\tchildren,\n\t\t};\n\t}\n\n\tprivate serializeFile(file: InternalFileNode): VfsSnapshotFileNode {\n\t\treturn {\n\t\t\ttype: \"file\",\n\t\t\tname: file.name,\n\t\t\tmode: file.mode,\n\t\t\tcreatedAt: file.createdAt.toISOString(),\n\t\t\tupdatedAt: file.updatedAt.toISOString(),\n\t\t\tcompressed: file.compressed,\n\t\t\tcontentBase64: file.content.toString(\"base64\"),\n\t\t};\n\t}\n\n\t/**\n\t * Creates a new `VirtualFileSystem` instance (memory mode) from a snapshot.\n\t *\n\t * @example\n\t * ```ts\n\t * const vfs = VirtualFileSystem.fromSnapshot(savedSnapshot);\n\t * ```\n\t */\n\tpublic static fromSnapshot(snapshot: VfsSnapshot): VirtualFileSystem {\n\t\tconst vfs = new VirtualFileSystem();\n\t\tvfs.root = vfs.deserializeDir(snapshot.root, \"\");\n\t\treturn vfs;\n\t}\n\n\t/**\n\t * Replaces the current filesystem state with the content of a snapshot.\n\t * The persistence mode is preserved.\n\t *\n\t * @example\n\t * ```ts\n\t * vfs.importSnapshot(savedSnapshot);\n\t * ```\n\t */\n\tpublic importSnapshot(snapshot: VfsSnapshot): void {\n\t\tthis.root = this.deserializeDir(snapshot.root, \"\");\n\t\tthis.emit(\"snapshot:import\");\n\t}\n\n\tprivate deserializeDir(\n\t\tsnap: VfsSnapshotDirectoryNode,\n\t\tname: string,\n\t): InternalDirectoryNode {\n\t\tconst dir: InternalDirectoryNode = {\n\t\t\ttype: \"directory\",\n\t\t\tname,\n\t\t\tmode: snap.mode,\n\t\t\tcreatedAt: new Date(snap.createdAt),\n\t\t\tupdatedAt: new Date(snap.updatedAt),\n\t\t\tchildren: new Map(),\n\t\t};\n\t\tfor (const child of snap.children) {\n\t\t\tif (child.type === \"file\") {\n\t\t\t\tconst f = child as VfsSnapshotFileNode;\n\t\t\t\tdir.children.set(f.name, {\n\t\t\t\t\ttype: \"file\",\n\t\t\t\t\tname: f.name,\n\t\t\t\t\tmode: f.mode,\n\t\t\t\t\tcreatedAt: new Date(f.createdAt),\n\t\t\t\t\tupdatedAt: new Date(f.updatedAt),\n\t\t\t\t\tcompressed: f.compressed,\n\t\t\t\t\tcontent: Buffer.from(f.contentBase64, \"base64\"),\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst sub = this.deserializeDir(\n\t\t\t\t\tchild as VfsSnapshotDirectoryNode,\n\t\t\t\t\tchild.name,\n\t\t\t\t);\n\t\t\t\tdir.children.set(child.name, sub);\n\t\t\t}\n\t\t}\n\t\treturn dir;\n\t}\n}\n\nexport default VirtualFileSystem;\n", "/**\n * Binary serialisation format for VirtualFileSystem snapshots.\n *\n * Replaces the JSON+base64 approach. No external dependencies.\n *\n * Wire format (little-endian throughout):\n *\n * File header:\n * [4] magic = 0x56 0x46 0x53 0x21 (\"VFS!\")\n * [1] version = 0x01\n *\n * Node (recursive):\n * [1] type = 0x01 (file) | 0x02 (directory)\n * [2] name length (uint16)\n * [N] name bytes (utf8)\n * [4] mode (uint32)\n * [8] createdAt ms (float64)\n * [8] updatedAt ms (float64)\n *\n * File node extra:\n * [1] compressed flag (0x00 | 0x01)\n * [4] content length (uint32)\n * [N] content bytes (raw \u2014 no base64)\n *\n * Directory node extra:\n * [4] children count (uint32)\n * [N] children nodes (recursive)\n *\n * Total overhead vs JSON+base64 for 1 MB of file data:\n * JSON+base64 : ~1.37 MB (base64 33% bloat) + JSON string wrapping\n * Binary pack : ~1.00 MB + ~40 bytes/node header \u2192 ~27% smaller, no string parsing\n */\n\nimport type {\n\tInternalDirectoryNode,\n\tInternalFileNode,\n\tInternalNode,\n} from \"./internalTypes\";\n\nconst MAGIC = Buffer.from([0x56, 0x46, 0x53, 0x21]); // \"VFS!\"\nconst VERSION = 0x01;\nconst TYPE_FILE = 0x01;\nconst TYPE_DIR = 0x02;\n\n// \u2500\u2500 Encoder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nclass Encoder {\n\tprivate chunks: Buffer[] = [];\n\n\twrite(buf: Buffer): void {\n\t\tthis.chunks.push(buf);\n\t}\n\n\twriteUint8(n: number): void {\n\t\tconst b = Buffer.allocUnsafe(1);\n\t\tb.writeUInt8(n, 0);\n\t\tthis.chunks.push(b);\n\t}\n\n\twriteUint16(n: number): void {\n\t\tconst b = Buffer.allocUnsafe(2);\n\t\tb.writeUInt16LE(n, 0);\n\t\tthis.chunks.push(b);\n\t}\n\n\twriteUint32(n: number): void {\n\t\tconst b = Buffer.allocUnsafe(4);\n\t\tb.writeUInt32LE(n, 0);\n\t\tthis.chunks.push(b);\n\t}\n\n\twriteFloat64(n: number): void {\n\t\tconst b = Buffer.allocUnsafe(8);\n\t\tb.writeDoubleBE(n, 0);\n\t\tthis.chunks.push(b);\n\t}\n\n\twriteString(s: string): void {\n\t\tconst encoded = Buffer.from(s, \"utf8\");\n\t\tthis.writeUint16(encoded.length);\n\t\tthis.chunks.push(encoded);\n\t}\n\n\twriteBytes(bytes: Buffer): void {\n\t\tthis.writeUint32(bytes.length);\n\t\tthis.chunks.push(bytes);\n\t}\n\n\ttoBuffer(): Buffer {\n\t\treturn Buffer.concat(this.chunks);\n\t}\n}\n\nfunction encodeNode(enc: Encoder, node: InternalNode): void {\n\tif (node.type === \"file\") {\n\t\tconst f = node as InternalFileNode;\n\t\tenc.writeUint8(TYPE_FILE);\n\t\tenc.writeString(f.name);\n\t\tenc.writeUint32(f.mode);\n\t\tenc.writeFloat64(f.createdAt.getTime());\n\t\tenc.writeFloat64(f.updatedAt.getTime());\n\t\tenc.writeUint8(f.compressed ? 0x01 : 0x00);\n\t\tenc.writeBytes(f.content);\n\t} else {\n\t\tconst d = node as InternalDirectoryNode;\n\t\tenc.writeUint8(TYPE_DIR);\n\t\tenc.writeString(d.name);\n\t\tenc.writeUint32(d.mode);\n\t\tenc.writeFloat64(d.createdAt.getTime());\n\t\tenc.writeFloat64(d.updatedAt.getTime());\n\t\tconst children = Array.from(d.children.values());\n\t\tenc.writeUint32(children.length);\n\t\tfor (const child of children) encodeNode(enc, child);\n\t}\n}\n\n/**\n * Serialise an in-memory VFS root to a compact binary Buffer.\n * No base64, no JSON. ~27% smaller than the JSON+base64 format for typical VFS trees.\n */\nexport function encodeVfs(root: InternalDirectoryNode): Buffer {\n\tconst enc = new Encoder();\n\tenc.write(MAGIC);\n\tenc.writeUint8(VERSION);\n\tencodeNode(enc, root);\n\treturn enc.toBuffer();\n}\n\n// \u2500\u2500 Decoder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nclass Decoder {\n\tprivate pos = 0;\n\tconstructor(private readonly buf: Buffer) {}\n\n\treadUint8(): number {\n\t\treturn this.buf.readUInt8(this.pos++);\n\t}\n\n\treadUint16(): number {\n\t\tconst v = this.buf.readUInt16LE(this.pos);\n\t\tthis.pos += 2;\n\t\treturn v;\n\t}\n\n\treadUint32(): number {\n\t\tconst v = this.buf.readUInt32LE(this.pos);\n\t\tthis.pos += 4;\n\t\treturn v;\n\t}\n\n\treadFloat64(): number {\n\t\tconst v = this.buf.readDoubleBE(this.pos);\n\t\tthis.pos += 8;\n\t\treturn v;\n\t}\n\n\treadString(): string {\n\t\tconst len = this.readUint16();\n\t\tconst s = this.buf.toString(\"utf8\", this.pos, this.pos + len);\n\t\tthis.pos += len;\n\t\treturn s;\n\t}\n\n\treadBytes(): Buffer {\n\t\tconst len = this.readUint32();\n\t\tconst b = this.buf.slice(this.pos, this.pos + len);\n\t\tthis.pos += len;\n\t\treturn b;\n\t}\n\n\tremaining(): number {\n\t\treturn this.buf.length - this.pos;\n\t}\n}\n\nfunction decodeNode(dec: Decoder): InternalNode {\n\tconst type = dec.readUint8();\n\tconst name = dec.readString();\n\tconst mode = dec.readUint32();\n\tconst createdAt = new Date(dec.readFloat64());\n\tconst updatedAt = new Date(dec.readFloat64());\n\n\tif (type === TYPE_FILE) {\n\t\tconst compressed = dec.readUint8() === 0x01;\n\t\tconst content = dec.readBytes();\n\t\treturn {\n\t\t\ttype: \"file\",\n\t\t\tname,\n\t\t\tmode,\n\t\t\tcreatedAt,\n\t\t\tupdatedAt,\n\t\t\tcompressed,\n\t\t\tcontent,\n\t\t} satisfies InternalFileNode;\n\t}\n\n\tif (type === TYPE_DIR) {\n\t\tconst count = dec.readUint32();\n\t\tconst children = new Map<string, InternalNode>();\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst child = decodeNode(dec);\n\t\t\tchildren.set(child.name, child);\n\t\t}\n\t\treturn {\n\t\t\ttype: \"directory\",\n\t\t\tname,\n\t\t\tmode,\n\t\t\tcreatedAt,\n\t\t\tupdatedAt,\n\t\t\tchildren,\n\t\t} satisfies InternalDirectoryNode;\n\t}\n\n\tthrow new Error(`[VFS binary] Unknown node type: 0x${type.toString(16)}`);\n}\n\n/**\n * Deserialise a binary Buffer produced by {@link encodeVfs} back into an\n * InternalDirectoryNode tree. Throws on magic/version mismatch or truncation.\n */\nexport function decodeVfs(buf: Buffer): InternalDirectoryNode {\n\tif (buf.length < 5) throw new Error(\"[VFS binary] Buffer too short\");\n\n\tconst magic = buf.slice(0, 4);\n\tif (!magic.equals(MAGIC)) {\n\t\tthrow new Error(\"[VFS binary] Invalid magic \u2014 not a VFS binary snapshot\");\n\t}\n\n\tconst dec = new Decoder(buf);\n\t// skip magic (4) + version (1)\n\tfor (let i = 0; i < 5; i++) dec.readUint8();\n\n\tconst root = decodeNode(dec);\n\tif (root.type !== \"directory\") {\n\t\tthrow new Error(\"[VFS binary] Root node must be a directory\");\n\t}\n\treturn root as InternalDirectoryNode;\n}\n\n/**\n * Returns true if `buf` looks like a VFS binary snapshot (starts with magic bytes).\n * Used to auto-detect format when loading from disk.\n */\nexport function isBinarySnapshot(buf: Buffer): boolean {\n\treturn buf.length >= 4 && buf.slice(0, 4).equals(MAGIC);\n}\n", "import * as path from \"node:path\";\nimport type { InternalDirectoryNode, InternalNode } from \"./internalTypes\";\n\nexport function normalizePath(rawPath: string): string {\n\tif (!rawPath || rawPath.trim() === \"\") {\n\t\treturn \"/\";\n\t}\n\n\tconst normalized = path.posix.normalize(\n\t\trawPath.startsWith(\"/\") ? rawPath : `/${rawPath}`,\n\t);\n\treturn normalized === \"\" ? \"/\" : normalized;\n}\n\nexport function splitPath(normalizedPath: string): string[] {\n\treturn normalizedPath.split(\"/\").filter(Boolean);\n}\n\nexport function getNode(\n\troot: InternalDirectoryNode,\n\ttargetPath: string,\n): InternalNode {\n\tconst normalized = normalizePath(targetPath);\n\tif (normalized === \"/\") {\n\t\treturn root;\n\t}\n\n\tconst parts = splitPath(normalized);\n\tlet current: InternalNode = root;\n\n\tfor (const part of parts) {\n\t\tif (current.type !== \"directory\") {\n\t\t\tthrow new Error(`Path '${normalized}' does not exist.`);\n\t\t}\n\n\t\tconst next = current.children.get(part);\n\t\tif (!next) {\n\t\t\tthrow new Error(`Path '${normalized}' does not exist.`);\n\t\t}\n\t\tcurrent = next;\n\t}\n\n\treturn current;\n}\n\nexport function getParentDirectory(\n\troot: InternalDirectoryNode,\n\ttargetPath: string,\n\tcreateIfMissing: boolean,\n\tcreatePath: (pathToCreate: string) => void,\n): { parent: InternalDirectoryNode; name: string } {\n\tconst normalized = normalizePath(targetPath);\n\tif (normalized === \"/\") {\n\t\tthrow new Error(\"Root path has no parent directory.\");\n\t}\n\n\tconst parentPath = path.posix.dirname(normalized);\n\tconst name = path.posix.basename(normalized);\n\n\tif (!name) {\n\t\tthrow new Error(`Invalid path '${targetPath}'.`);\n\t}\n\n\tif (createIfMissing) {\n\t\tcreatePath(parentPath);\n\t}\n\n\tconst parentNode = getNode(root, parentPath);\n\tif (parentNode.type !== \"directory\") {\n\t\tthrow new Error(`Parent path '${parentPath}' is not a directory.`);\n\t}\n\n\treturn { parent: parentNode, name };\n}\n", "import type VirtualFileSystem from \"../VirtualFileSystem\";\nimport type { VirtualUserManager } from \"../VirtualUserManager\";\n\n// \u2500\u2500\u2500 types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * A single file entry written into the VFS when a package is installed.\n */\nexport interface PackageFile {\n\t/** Absolute VFS destination path (e.g. `\"/usr/bin/vim\"`). */\n\tpath: string;\n\t/** Text content to write. */\n\tcontent: string;\n\t/** POSIX mode bits (default `0o644`; use `0o755` for executables). */\n\tmode?: number;\n}\n\n/**\n * Metadata and behaviour definition for a single package in the registry.\n *\n * Used both for the built-in registry entries and for consumer-supplied custom\n * packages. `files` are written to the VFS on `install()`, and `onInstall` /\n * `onRemove` hooks allow arbitrary VFS mutations.\n */\nexport interface PackageDefinition {\n\t/** Package name \u2014 lowercase, no spaces (e.g. `\"vim\"`, `\"build-essential\"`). */\n\tname: string;\n\t/** Debian-style version string (e.g. `\"2:9.0.1378-2\"`). */\n\tversion: string;\n\t/** CPU architecture label (default `\"amd64\"`). */\n\tarchitecture?: string;\n\t/** Maintainer name and email shown in `apt show` output. */\n\tmaintainer?: string;\n\t/** Full package description. */\n\tdescription: string;\n\t/** Short one-line summary shown in `apt search` results. */\n\tshortDesc?: string;\n\t/** Installed disk usage in kilobytes (informational). */\n\tinstalledSizeKb?: number;\n\t/** Other package names that must be installed first (resolved recursively). */\n\tdepends?: string[];\n\t/** Repository section (e.g. `\"utils\"`, `\"net\"`, `\"editors\"`, `\"devel\"`). */\n\tsection?: string;\n\t/** Files to write into the VFS during installation. */\n\tfiles?: PackageFile[];\n\t/**\n\t * Hook called after all files are written.\n\t * Use to create directories, write config, or register shell commands.\n\t */\n\tonInstall?: (vfs: VirtualFileSystem, users: VirtualUserManager) => void;\n\t/** Hook called before VFS files are removed during uninstall. */\n\tonRemove?: (vfs: VirtualFileSystem) => void;\n}\n\n/**\n * Runtime record of an installed package, persisted to `/var/lib/dpkg/status`.\n */\nexport interface InstalledPackage {\n\t/** Package name. */\n\tname: string;\n\t/** Installed version string. */\n\tversion: string;\n\t/** CPU architecture. */\n\tarchitecture: string;\n\t/** Maintainer display string. */\n\tmaintainer: string;\n\t/** Full description. */\n\tdescription: string;\n\t/** Repository section. */\n\tsection: string;\n\t/** Installed disk usage in kilobytes. */\n\tinstalledSizeKb: number;\n\t/** ISO-8601 timestamp of when the package was installed. */\n\tinstalledAt: string;\n\t/** Absolute VFS paths written by this package (used by `dpkg -L`). */\n\tfiles: string[];\n}\n\n// \u2500\u2500\u2500 built-in package registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst PACKAGE_REGISTRY: PackageDefinition[] = [\n\t{\n\t\tname: \"vim\",\n\t\tversion: \"2:9.0.1378-2\",\n\t\tsection: \"editors\",\n\t\tdescription: \"Vi IMproved - enhanced vi editor\",\n\t\tshortDesc: \"Vi IMproved\",\n\t\tinstalledSizeKb: 3812,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/vim\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'vim: use nano for editing in this environment'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/vi\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec vim \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/share/doc/vim/README\",\n\t\t\t\tcontent: \"Vim editor \u2014 virtual package.\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"git\",\n\t\tversion: \"1:2.39.2-1\",\n\t\tsection: \"vcs\",\n\t\tdescription: \"Fast, scalable, distributed revision control system\",\n\t\tshortDesc: \"fast distributed version control system\",\n\t\tinstalledSizeKb: 11240,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/git\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'git: virtual stub \u2014 no host access'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/share/doc/git/README.Debian\",\n\t\t\t\tcontent: \"Git virtual package for Fortune GNU/Linux.\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"python3\",\n\t\tversion: \"3.11.2-1+b1\",\n\t\tsection: \"python\",\n\t\tdescription: \"Interactive high-level object-oriented language (version 3)\",\n\t\tshortDesc: \"interactive high-level object-oriented language\",\n\t\tinstalledSizeKb: 512,\n\t\tdepends: [\"python3-minimal\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/python3\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'Python 3.11.2 (virtual)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/python3.11\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec python3 \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{ path: \"/usr/lib/python3.11/.keep\", content: \"\" },\n\t\t],\n\t},\n\t{\n\t\tname: \"python3-minimal\",\n\t\tversion: \"3.11.2-1+b1\",\n\t\tsection: \"python\",\n\t\tdescription: \"Minimal subset of the Python language (version 3)\",\n\t\tshortDesc: \"minimal subset of Python language\",\n\t\tinstalledSizeKb: 196,\n\t\tfiles: [{ path: \"/usr/lib/python3-minimal/.keep\", content: \"\" }],\n\t},\n\t{\n\t\tname: \"nodejs\",\n\t\tversion: \"18.19.0+dfsg-6\",\n\t\tsection: \"javascript\",\n\t\tdescription: \"Evented I/O for V8 javascript - runtime executable\",\n\t\tshortDesc: \"Node.js JavaScript runtime\",\n\t\tinstalledSizeKb: 15360,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/node\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'node v18.19.0 (virtual)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/nodejs\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec node \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/share/doc/nodejs/README\",\n\t\t\t\tcontent: \"Node.js virtual package.\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"npm\",\n\t\tversion: \"9.2.0~ds1-2\",\n\t\tsection: \"javascript\",\n\t\tdescription: \"package manager for Node.js\",\n\t\tshortDesc: \"package manager for Node.js\",\n\t\tinstalledSizeKb: 9814,\n\t\tdepends: [\"nodejs\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/npm\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin npm \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/npx\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin npx \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"curl\",\n\t\tversion: \"7.88.1-10+deb12u5\",\n\t\tsection: \"web\",\n\t\tdescription: \"command line tool for transferring data with URL syntax\",\n\t\tshortDesc: \"command line tool for transferring data\",\n\t\tinstalledSizeKb: 368,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/curl\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin curl \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"wget\",\n\t\tversion: \"1.21.3-1+b2\",\n\t\tsection: \"web\",\n\t\tdescription: \"Retrieves files from the web\",\n\t\tshortDesc: \"retrieves files from the web\",\n\t\tinstalledSizeKb: 952,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/wget\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin wget \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"htop\",\n\t\tversion: \"3.2.2-2\",\n\t\tsection: \"utils\",\n\t\tdescription: \"interactive processes viewer\",\n\t\tshortDesc: \"interactive process viewer\",\n\t\tinstalledSizeKb: 412,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/htop\",\n\t\t\t\tcontent: \"#!/bin/sh\\nexec builtin htop\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"openssh-client\",\n\t\tversion: \"1:9.2p1-2+deb12u2\",\n\t\tsection: \"net\",\n\t\tdescription: \"Secure Shell (SSH) client\",\n\t\tshortDesc: \"secure shell (SSH) client\",\n\t\tinstalledSizeKb: 4540,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/ssh\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'ssh: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/ssh-keygen\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'ssh-keygen: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/etc/ssh/ssh_config\",\n\t\t\t\tcontent: \"Host *\\n StrictHostKeyChecking ask\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"openssh-server\",\n\t\tversion: \"1:9.2p1-2+deb12u2\",\n\t\tsection: \"net\",\n\t\tdescription: \"Secure Shell server (sshd)\",\n\t\tshortDesc: \"secure shell server\",\n\t\tinstalledSizeKb: 1732,\n\t\tdepends: [\"openssh-client\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/sbin/sshd\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'sshd: virtual \u2014 server already running'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/etc/ssh/sshd_config\",\n\t\t\t\tcontent: \"Port 22\\nPermitRootLogin yes\\nPasswordAuthentication yes\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"net-tools\",\n\t\tversion: \"2.10-0.1\",\n\t\tsection: \"net\",\n\t\tdescription: \"NET-3 networking toolkit (ifconfig, netstat, route)\",\n\t\tshortDesc: \"networking toolkit\",\n\t\tinstalledSizeKb: 988,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/ifconfig\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500'\\necho ' inet 10.0.0.2 netmask 255.255.255.0 broadcast 10.0.0.255'\\necho ' ether 02:42:0a:00:00:02 txqueuelen 0 (Ethernet)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/netstat\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'Active Internet connections (only servers)'\\necho 'Proto Recv-Q Send-Q Local Address Foreign Address State'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/route\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'Kernel IP routing table'\\necho 'Destination Gateway Genmask Flags Metric Ref Use Iface'\\necho '0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth0'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"iputils-ping\",\n\t\tversion: \"3:20221126-1\",\n\t\tsection: \"net\",\n\t\tdescription: \"Tools to test the reachability of network hosts\",\n\t\tshortDesc: \"test reachability of network hosts\",\n\t\tinstalledSizeKb: 164,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/ping\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin ping \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"jq\",\n\t\tversion: \"1.6-2.1\",\n\t\tsection: \"utils\",\n\t\tdescription: \"Lightweight and flexible command-line JSON processor\",\n\t\tshortDesc: \"command-line JSON processor\",\n\t\tinstalledSizeKb: 296,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/jq\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'jq: virtual stub \u2014 pipe JSON here'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"build-essential\",\n\t\tversion: \"12.9\",\n\t\tsection: \"devel\",\n\t\tdescription: \"Informational list of build-essential packages\",\n\t\tshortDesc: \"build-essential meta-package\",\n\t\tinstalledSizeKb: 12,\n\t\tdepends: [\"gcc\", \"g++\", \"make\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/share/doc/build-essential/README\",\n\t\t\t\tcontent: \"Build-essential virtual meta-package.\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"gcc\",\n\t\tversion: \"4:12.2.0-3\",\n\t\tsection: \"devel\",\n\t\tdescription: \"GNU C compiler\",\n\t\tshortDesc: \"GNU C compiler\",\n\t\tinstalledSizeKb: 24448,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/gcc\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'gcc (Fortune GNU/Linux) 12.2.0 (virtual)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/gcc-12\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec gcc \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"g++\",\n\t\tversion: \"4:12.2.0-3\",\n\t\tsection: \"devel\",\n\t\tdescription: \"GNU C++ compiler\",\n\t\tshortDesc: \"GNU C++ compiler\",\n\t\tinstalledSizeKb: 1024,\n\t\tdepends: [\"gcc\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/g++\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'g++ (Fortune GNU/Linux) 12.2.0 (virtual)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"make\",\n\t\tversion: \"4.3-4.1\",\n\t\tsection: \"devel\",\n\t\tdescription: \"Utility for directing compilation\",\n\t\tshortDesc: \"build utility\",\n\t\tinstalledSizeKb: 504,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/make\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'make: *** No targets specified and no makefile found. Stop.'\\nexit 2\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"less\",\n\t\tversion: \"590-2\",\n\t\tsection: \"text\",\n\t\tdescription: \"Pager program similar to more\",\n\t\tshortDesc: \"pager program\",\n\t\tinstalledSizeKb: 328,\n\t\tfiles: [\n\t\t\t{ path: \"/usr/bin/less\", content: '#!/bin/sh\\ncat \"$@\"\\n', mode: 0o755 },\n\t\t],\n\t},\n\t{\n\t\tname: \"unzip\",\n\t\tversion: \"6.0-28\",\n\t\tsection: \"utils\",\n\t\tdescription: \"De-archiver for .zip files\",\n\t\tshortDesc: \"de-archiver for .zip files\",\n\t\tinstalledSizeKb: 464,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/unzip\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'unzip: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"rsync\",\n\t\tversion: \"3.2.7-1\",\n\t\tsection: \"net\",\n\t\tdescription: \"Fast, versatile, remote (and local) file-copying tool\",\n\t\tshortDesc: \"fast remote file copy program\",\n\t\tinstalledSizeKb: 716,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/rsync\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'rsync: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"tmux\",\n\t\tversion: \"3.3a-3\",\n\t\tsection: \"utils\",\n\t\tdescription: \"Terminal multiplexer\",\n\t\tshortDesc: \"terminal multiplexer\",\n\t\tinstalledSizeKb: 812,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/tmux\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'tmux: terminal multiplexer (virtual stub)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"tree\",\n\t\tversion: \"2.1.0-1\",\n\t\tsection: \"utils\",\n\t\tdescription: \"Displays an indented directory tree, in color\",\n\t\tshortDesc: \"list files in tree format\",\n\t\tinstalledSizeKb: 108,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/tree\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin tree \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"ca-certificates\",\n\t\tversion: \"20230311\",\n\t\tsection: \"misc\",\n\t\tdescription: \"Common CA certificates\",\n\t\tshortDesc: \"common CA certificates\",\n\t\tinstalledSizeKb: 388,\n\t\tfiles: [\n\t\t\t{ path: \"/etc/ssl/certs/.keep\", content: \"\" },\n\t\t\t{ path: \"/etc/ssl/private/.keep\", content: \"\" },\n\t\t\t{ path: \"/usr/share/ca-certificates/.keep\", content: \"\" },\n\t\t],\n\t\tonInstall: (vfs) => {\n\t\t\tif (!vfs.exists(\"/etc/ssl\")) vfs.mkdir(\"/etc/ssl\", 0o755);\n\t\t\tif (!vfs.exists(\"/etc/ssl/certs\")) vfs.mkdir(\"/etc/ssl/certs\", 0o755);\n\t\t},\n\t},\n\t{\n\t\tname: \"locales\",\n\t\tversion: \"2.36-9+deb12u3\",\n\t\tsection: \"localization\",\n\t\tdescription: \"GNU C Library: National Language (locale) data\",\n\t\tshortDesc: \"locale data\",\n\t\tinstalledSizeKb: 16484,\n\t\tfiles: [\n\t\t\t{ path: \"/etc/locale.gen\", content: \"en_US.UTF-8 UTF-8\\n\" },\n\t\t\t{\n\t\t\t\tpath: \"/etc/default/locale\",\n\t\t\t\tcontent: \"LANG=en_US.UTF-8\\nLANGUAGE=en_US:en\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"sudo\",\n\t\tversion: \"1.9.13p3-1+deb12u1\",\n\t\tsection: \"admin\",\n\t\tdescription: \"Provide limited super user privileges to specific users\",\n\t\tshortDesc: \"super user privilege execution\",\n\t\tinstalledSizeKb: 2304,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/sudo\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin sudo \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/etc/sudoers\",\n\t\t\t\tcontent: \"root ALL=(ALL:ALL) ALL\\n%sudo ALL=(ALL:ALL) ALL\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"systemd\",\n\t\tversion: \"252.22-1~deb12u1\",\n\t\tsection: \"admin\",\n\t\tdescription: \"System and service manager\",\n\t\tshortDesc: \"system and service manager\",\n\t\tinstalledSizeKb: 26624,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/systemctl\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'systemd is not running in this virtual container.'\\nexit 1\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/journalctl\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'journalctl: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n];\n\n/**\n * Pure-TypeScript APT/dpkg package manager backed by a built-in registry.\n *\n * Accessed via `shell.packageManager` \u2014 not constructed directly.\n *\n * `install()` resolves dependencies recursively, writes declared files to the\n * VFS, runs `onInstall` hooks, and persists state to `/var/lib/dpkg/status`.\n * `remove()` reverses the process. All state survives VFS snapshot round-trips.\n *\n * @example\n * ```ts\n * const pm = shell.packageManager;\n * pm.install([\"vim\", \"git\"]);\n * console.log(pm.isInstalled(\"vim\")); // true\n * console.log(pm.installedCount()); // 2\n * ```\n */\nexport class VirtualPackageManager {\n\tprivate readonly installed = new Map<string, InstalledPackage>();\n\tprivate readonly registryPath = \"/var/lib/dpkg/status\";\n\tprivate readonly logPath = \"/var/log/dpkg.log\";\n\tprivate readonly aptLogPath = \"/var/log/apt/history.log\";\n\n\t/**\n\t * @param vfs Backing virtual filesystem for file I/O and dpkg status persistence.\n\t * @param users User manager reference passed to `onInstall` hooks.\n\t */\n\tconstructor(\n\t\tprivate readonly vfs: VirtualFileSystem,\n\t\tprivate readonly users: VirtualUserManager,\n\t) {}\n\n\t/**\n\t * Loads installed package state from `/var/lib/dpkg/status` in the VFS.\n\t *\n\t * Called automatically by `VirtualShell` after `bootstrapLinuxRootfs`.\n\t * Safe to call again to reload state after a snapshot restore.\n\t */\n\tpublic load(): void {\n\t\tif (!this.vfs.exists(this.registryPath)) return;\n\t\tconst status = this.vfs.readFile(this.registryPath);\n\t\tif (!status.trim()) return;\n\n\t\tconst blocks = status.split(/\\n\\n+/);\n\t\tfor (const block of blocks) {\n\t\t\tif (!block.trim()) continue;\n\t\t\tconst fields = this.parseFields(block);\n\t\t\tconst name = fields.Package;\n\t\t\tif (!name) continue;\n\t\t\tthis.installed.set(name, {\n\t\t\t\tname,\n\t\t\t\tversion: fields.Version ?? \"unknown\",\n\t\t\t\tarchitecture: fields.Architecture ?? \"amd64\",\n\t\t\t\tmaintainer: fields.Maintainer ?? \"Fortune Maintainers\",\n\t\t\t\tdescription: fields.Description ?? \"\",\n\t\t\t\tsection: fields.Section ?? \"misc\",\n\t\t\t\tinstalledSizeKb: Number(fields[\"Installed-Size\"] ?? 0),\n\t\t\t\tinstalledAt: fields[\"X-Installed-At\"] ?? new Date().toISOString(),\n\t\t\t\tfiles: (fields[\"X-Files\"] ?? \"\").split(\"|\").filter(Boolean),\n\t\t\t});\n\t\t}\n\t}\n\n\t/** Persist installed state to /var/lib/dpkg/status. */\n\tprivate persist(): void {\n\t\tconst blocks: string[] = [];\n\t\tfor (const pkg of this.installed.values()) {\n\t\t\tblocks.push(\n\t\t\t\t[\n\t\t\t\t\t`Package: ${pkg.name}`,\n\t\t\t\t\t`Status: install ok installed`,\n\t\t\t\t\t`Priority: optional`,\n\t\t\t\t\t`Section: ${pkg.section}`,\n\t\t\t\t\t`Installed-Size: ${pkg.installedSizeKb}`,\n\t\t\t\t\t`Maintainer: ${pkg.maintainer}`,\n\t\t\t\t\t`Architecture: ${pkg.architecture}`,\n\t\t\t\t\t`Version: ${pkg.version}`,\n\t\t\t\t\t`Description: ${pkg.description}`,\n\t\t\t\t\t`X-Installed-At: ${pkg.installedAt}`,\n\t\t\t\t\t`X-Files: ${pkg.files.join(\"|\")}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t}\n\t\tthis.vfs.writeFile(this.registryPath, `${blocks.join(\"\\n\\n\")}\\n`);\n\t}\n\n\tprivate parseFields(block: string): Record<string, string> {\n\t\tconst result: Record<string, string> = {};\n\t\tfor (const line of block.split(\"\\n\")) {\n\t\t\tconst idx = line.indexOf(\": \");\n\t\t\tif (idx === -1) continue;\n\t\t\tresult[line.slice(0, idx)] = line.slice(idx + 2);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate log(msg: string): void {\n\t\tconst ts = new Date().toISOString().replace(\"T\", \" \").slice(0, 19);\n\t\tconst line = `${ts} ${msg}\\n`;\n\t\tconst existing = this.vfs.exists(this.logPath)\n\t\t\t? this.vfs.readFile(this.logPath)\n\t\t\t: \"\";\n\t\tthis.vfs.writeFile(this.logPath, existing + line);\n\t}\n\n\tprivate aptLog(action: string, pkgs: string[]): void {\n\t\tconst ts = new Date().toISOString();\n\t\tconst existing = this.vfs.exists(this.aptLogPath)\n\t\t\t? this.vfs.readFile(this.aptLogPath)\n\t\t\t: \"\";\n\t\tconst entry = [\n\t\t\t`Start-Date: ${ts}`,\n\t\t\t`Commandline: apt-get ${action} ${pkgs.join(\" \")}`,\n\t\t\t`${action === \"install\" ? \"Install\" : \"Remove\"}: ${pkgs.join(\", \")}`,\n\t\t\t`End-Date: ${ts}`,\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\t\tthis.vfs.writeFile(this.aptLogPath, existing + entry);\n\t}\n\n\t/**\n\t * Looks up a package definition in the built-in registry by name.\n\t *\n\t * @param name Package name (case-insensitive).\n\t * @returns The matching `PackageDefinition`, or `undefined` if not found.\n\t */\n\tpublic findInRegistry(name: string): PackageDefinition | undefined {\n\t\treturn PACKAGE_REGISTRY.find(\n\t\t\t(p) => p.name.toLowerCase() === name.toLowerCase(),\n\t\t);\n\t}\n\n\t/**\n\t * Returns all packages in the built-in registry, sorted alphabetically.\n\t *\n\t * @returns Array of `PackageDefinition` entries.\n\t */\n\tpublic listAvailable(): PackageDefinition[] {\n\t\treturn [...PACKAGE_REGISTRY].sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\t/**\n\t * Returns all currently installed packages, sorted alphabetically.\n\t *\n\t * @returns Array of `InstalledPackage` records.\n\t */\n\tpublic listInstalled(): InstalledPackage[] {\n\t\treturn [...this.installed.values()].sort((a, b) =>\n\t\t\ta.name.localeCompare(b.name),\n\t\t);\n\t}\n\n\t/**\n\t * Returns `true` when the given package is currently installed.\n\t *\n\t * @param name Package name (case-insensitive).\n\t */\n\tpublic isInstalled(name: string): boolean {\n\t\treturn this.installed.has(name.toLowerCase());\n\t}\n\n\t/**\n\t * Returns the total number of installed packages.\n\t *\n\t * Used by `neofetch` to populate the `Packages:` field.\n\t */\n\tpublic installedCount(): number {\n\t\treturn this.installed.size;\n\t}\n\n\t/**\n\t * Installs one or more packages from the registry.\n\t *\n\t * Dependencies listed in `PackageDefinition.depends` are resolved and\n\t * installed automatically. Already-installed packages are skipped. Files\n\t * declared in `PackageDefinition.files` are written to the VFS and\n\t * `onInstall` hooks are called in dependency order.\n\t *\n\t * @param names Package names to install.\n\t * @param opts Installation options.\n\t * @param opts.quiet Suppress progress output lines when `true`.\n\t * @returns Terminal-style `output` string and an APT-compatible `exitCode`\n\t * (`0` on success, `100` when a package is not found).\n\t */\n\tpublic install(\n\t\tnames: string[],\n\t\topts: { quiet?: boolean } = {},\n\t): { output: string; exitCode: number } {\n\t\tconst lines: string[] = [];\n\t\tconst toInstall: PackageDefinition[] = [];\n\t\tconst notFound: string[] = [];\n\n\t\t// Resolve + deduplicate including deps\n\t\tconst resolve = (name: string, seen = new Set<string>()): void => {\n\t\t\tif (seen.has(name)) return;\n\t\t\tseen.add(name);\n\t\t\tif (this.isInstalled(name)) return;\n\t\t\tconst def = this.findInRegistry(name);\n\t\t\tif (!def) {\n\t\t\t\tnotFound.push(name);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const dep of def.depends ?? []) resolve(dep, seen);\n\t\t\tif (!toInstall.find((p) => p.name === def.name)) {\n\t\t\t\ttoInstall.push(def);\n\t\t\t}\n\t\t};\n\n\t\tfor (const n of names) resolve(n);\n\n\t\tif (notFound.length > 0) {\n\t\t\treturn {\n\t\t\t\toutput: `E: Unable to locate package ${notFound.join(\", \")}`,\n\t\t\t\texitCode: 100,\n\t\t\t};\n\t\t}\n\n\t\tif (toInstall.length === 0) {\n\t\t\treturn {\n\t\t\t\toutput: names\n\t\t\t\t\t.map((n) => `${n} is already the newest version.`)\n\t\t\t\t\t.join(\"\\n\"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst totalKb = toInstall.reduce(\n\t\t\t(acc, p) => acc + (p.installedSizeKb ?? 0),\n\t\t\t0,\n\t\t);\n\n\t\tif (!opts.quiet) {\n\t\t\tlines.push(\n\t\t\t\t`Reading package lists... Done`,\n\t\t\t\t`Building dependency tree... Done`,\n\t\t\t\t`Reading state information... Done`,\n\t\t\t\t`The following NEW packages will be installed:`,\n\t\t\t\t` ${toInstall.map((p) => p.name).join(\" \")}`,\n\t\t\t\t`0 upgraded, ${toInstall.length} newly installed, 0 to remove and 0 not upgraded.`,\n\t\t\t\t`Need to get 0 B/${totalKb} kB of archives.`,\n\t\t\t\t`After this operation, ${totalKb} kB of additional disk space will be used.`,\n\t\t\t\t``,\n\t\t\t);\n\t\t}\n\n\t\tfor (const def of toInstall) {\n\t\t\tif (!opts.quiet) {\n\t\t\t\tlines.push(`Selecting previously unselected package ${def.name}.`);\n\t\t\t\tlines.push(\n\t\t\t\t\t`(Reading database ... 12345 files and directories currently installed.)`,\n\t\t\t\t);\n\t\t\t\tlines.push(\n\t\t\t\t\t`Preparing to unpack .../archives/${def.name}_${def.version}_amd64.deb ...`,\n\t\t\t\t);\n\t\t\t\tlines.push(`Unpacking ${def.name} (${def.version}) ...`);\n\t\t\t}\n\n\t\t\t// Write files\n\t\t\tfor (const f of def.files ?? []) {\n\t\t\t\tconst dir = f.path.slice(0, f.path.lastIndexOf(\"/\"));\n\t\t\t\tif (dir && !this.vfs.exists(dir)) this.vfs.mkdir(dir, 0o755);\n\t\t\t\tthis.vfs.writeFile(f.path, f.content, { mode: f.mode ?? 0o644 });\n\t\t\t}\n\n\t\t\t// Run install hook\n\t\t\tdef.onInstall?.(this.vfs, this.users);\n\n\t\t\tif (!opts.quiet) {\n\t\t\t\tlines.push(`Setting up ${def.name} (${def.version}) ...`);\n\t\t\t}\n\n\t\t\tconst now = new Date().toISOString();\n\t\t\tthis.installed.set(def.name, {\n\t\t\t\tname: def.name,\n\t\t\t\tversion: def.version,\n\t\t\t\tarchitecture: def.architecture ?? \"amd64\",\n\t\t\t\tmaintainer: def.maintainer ?? \"Fortune Maintainers <pkg@fortune.local>\",\n\t\t\t\tdescription: def.description,\n\t\t\t\tsection: def.section ?? \"misc\",\n\t\t\t\tinstalledSizeKb: def.installedSizeKb ?? 0,\n\t\t\t\tinstalledAt: now,\n\t\t\t\tfiles: (def.files ?? []).map((f) => f.path),\n\t\t\t});\n\n\t\t\tthis.log(`install ${def.name} ${def.version}`);\n\t\t}\n\n\t\tthis.aptLog(\n\t\t\t\"install\",\n\t\t\ttoInstall.map((p) => p.name),\n\t\t);\n\t\tthis.persist();\n\n\t\tif (!opts.quiet) {\n\t\t\tlines.push(`Processing triggers for man-db (2.11.2-2) ...`);\n\t\t}\n\n\t\treturn { output: lines.join(\"\\n\"), exitCode: 0 };\n\t}\n\n\t/**\n\t * Removes one or more installed packages.\n\t *\n\t * Package files are deleted from the VFS. Config files (paths under\n\t * `/etc/` or ending in `.conf`) are preserved unless `opts.purge` is set.\n\t * The `onRemove` hook is called for each package.\n\t *\n\t * @param names Package names to remove.\n\t * @param opts Removal options.\n\t * @param opts.purge Also delete configuration files when `true`.\n\t * @param opts.quiet Suppress progress output lines when `true`.\n\t * @returns Terminal-style `output` string and exit code (`0` on success).\n\t */\n\tpublic remove(\n\t\tnames: string[],\n\t\topts: { purge?: boolean; quiet?: boolean } = {},\n\t): { output: string; exitCode: number } {\n\t\tconst lines: string[] = [];\n\t\tconst toRemove: InstalledPackage[] = [];\n\n\t\tfor (const name of names) {\n\t\t\tconst pkg = this.installed.get(name.toLowerCase());\n\t\t\tif (!pkg) {\n\t\t\t\tlines.push(`Package '${name}' is not installed, so not removed`);\n\t\t\t} else {\n\t\t\t\ttoRemove.push(pkg);\n\t\t\t}\n\t\t}\n\n\t\tif (toRemove.length === 0) {\n\t\t\treturn { output: lines.join(\"\\n\") || \"Nothing to remove.\", exitCode: 0 };\n\t\t}\n\n\t\tif (!opts.quiet) {\n\t\t\tlines.push(\n\t\t\t\t`Reading package lists... Done`,\n\t\t\t\t`Building dependency tree... Done`,\n\t\t\t\t`The following packages will be REMOVED:`,\n\t\t\t\t` ${toRemove.map((p) => p.name).join(\" \")}`,\n\t\t\t\t`0 upgraded, 0 newly installed, ${toRemove.length} to remove and 0 not upgraded.`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const pkg of toRemove) {\n\t\t\tif (!opts.quiet) lines.push(`Removing ${pkg.name} (${pkg.version}) ...`);\n\n\t\t\t// Remove files (if purge, include config files)\n\t\t\tfor (const filePath of pkg.files) {\n\t\t\t\tif (\n\t\t\t\t\t!opts.purge &&\n\t\t\t\t\t(filePath.startsWith(\"/etc/\") || filePath.endsWith(\".conf\"))\n\t\t\t\t) {\n\t\t\t\t\tcontinue; // keep config unless --purge\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tif (this.vfs.exists(filePath)) this.vfs.remove(filePath);\n\t\t\t\t} catch {}\n\t\t\t}\n\n\t\t\t// Run remove hook\n\t\t\tconst def = this.findInRegistry(pkg.name);\n\t\t\tdef?.onRemove?.(this.vfs);\n\n\t\t\tthis.installed.delete(pkg.name);\n\t\t\tthis.log(`remove ${pkg.name} ${pkg.version}`);\n\t\t}\n\n\t\tthis.aptLog(\n\t\t\t\"remove\",\n\t\t\ttoRemove.map((p) => p.name),\n\t\t);\n\t\tthis.persist();\n\n\t\treturn { output: lines.join(\"\\n\"), exitCode: 0 };\n\t}\n\n\t/**\n\t * Searches the registry for packages whose name or description contains\n\t * the given term (case-insensitive). Equivalent to `apt-cache search`.\n\t *\n\t * @param term Search string.\n\t * @returns Matching `PackageDefinition` entries sorted alphabetically.\n\t */\n\tpublic search(term: string): PackageDefinition[] {\n\t\tconst t = term.toLowerCase();\n\t\treturn PACKAGE_REGISTRY.filter(\n\t\t\t(p) =>\n\t\t\t\tp.name.includes(t) ||\n\t\t\t\tp.description.toLowerCase().includes(t) ||\n\t\t\t\t(p.shortDesc ?? \"\").toLowerCase().includes(t),\n\t\t).sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\t/**\n\t * Returns a dpkg-style metadata block for a package, including its\n\t * install status. Equivalent to `apt-cache show` / `dpkg -s`.\n\t *\n\t * @param name Package name.\n\t * @returns Multi-line metadata string, or `null` if not in the registry.\n\t */\n\tpublic show(name: string): string | null {\n\t\tconst def = this.findInRegistry(name);\n\t\tif (!def) return null;\n\t\tconst inst = this.installed.get(name);\n\t\treturn [\n\t\t\t`Package: ${def.name}`,\n\t\t\t`Version: ${def.version}`,\n\t\t\t`Architecture: ${def.architecture ?? \"amd64\"}`,\n\t\t\t`Maintainer: ${def.maintainer ?? \"Fortune Maintainers <pkg@fortune.local>\"}`,\n\t\t\t`Installed-Size: ${def.installedSizeKb ?? 0}`,\n\t\t\t`Depends: ${(def.depends ?? []).join(\", \") || \"(none)\"}`,\n\t\t\t`Section: ${def.section ?? \"misc\"}`,\n\t\t\t`Priority: optional`,\n\t\t\t`Description: ${def.description}`,\n\t\t\t`Status: ${inst ? \"install ok installed\" : \"install ok not-installed\"}`,\n\t\t].join(\"\\n\");\n\t}\n}\n", "import { createHash, randomBytes, randomUUID, scryptSync } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport * as path from \"node:path\";\nimport type { PerfLogger } from \"../utils/perfLogger\";\nimport { createPerfLogger } from \"../utils/perfLogger\";\nimport type VirtualFileSystem from \"../VirtualFileSystem\";\n\n/** Persisted virtual user credential record. */\nexport interface VirtualUserRecord {\n\t/** Unique login name. */\n\tusername: string;\n\t/** Per-user random salt used for password hashing. */\n\tsalt: string;\n\t/** Scrypt-derived password hash in hex encoding. */\n\tpasswordHash: string;\n}\n\n/** Runtime representation of authenticated SSH session. */\nexport interface VirtualActiveSession {\n\t/** Stable session identifier (UUID). */\n\tid: string;\n\t/** Username bound to session. */\n\tusername: string;\n\t/** Virtual terminal identifier (pts/*). */\n\ttty: string;\n\t/** Remote client IP or host label. */\n\tremoteAddress: string;\n\t/** ISO-8601 start timestamp. */\n\tstartedAt: string;\n}\n\nfunction resolveFastPasswordHash(): boolean {\n\tconst configured = process.env.SSH_MIMIC_FAST_PASSWORD_HASH;\n\treturn (\n\t\t!!configured &&\n\t\t![\"0\", \"false\", \"no\", \"off\"].includes(configured.toLowerCase())\n\t);\n}\n\nconst perf: PerfLogger = createPerfLogger(\"VirtualUserManager\");\n\n/**\n * Persistent user, sudoers, and active-session manager for the shell runtime.\n *\n * Passwords are hashed with scrypt by default and stored in the backing virtual filesystem.\n */\nexport class VirtualUserManager extends EventEmitter {\n\tprivate static readonly recordCache = new Map<string, VirtualUserRecord>();\n\tprivate static readonly fastPasswordHash = resolveFastPasswordHash();\n\tprivate readonly usersPath = \"/virtual-env-js/.auth/htpasswd\";\n\tprivate readonly sudoersPath = \"/virtual-env-js/.auth/sudoers\";\n\tprivate readonly quotasPath = \"/virtual-env-js/.auth/quotas\";\n\tprivate readonly authDirPath = \"/virtual-env-js/.auth\";\n\tprivate readonly users = new Map<string, VirtualUserRecord>();\n\tprivate readonly sudoers = new Set<string>();\n\tprivate readonly quotas = new Map<string, number>();\n\tprivate readonly activeSessions = new Map<string, VirtualActiveSession>();\n\tprivate nextTty = 0;\n\n\t/**\n\t * Creates a user manager instance backed by a virtual filesystem.\n\t *\n\t * @param vfs Backing virtual filesystem used for persistence.\n\t * @param defaultRootPassword Initial root password used when root is created.\n\t * @param autoSudoForNewUsers Whether newly created users are added to sudoers.\n\t */\n\tconstructor(\n\t\tprivate readonly vfs: VirtualFileSystem,\n\t\t// private readonly defaultRootPassword: string = process.env\n\t\t// .SSH_MIMIC_ROOT_PASSWORD || \"root\",\n\t\tprivate readonly autoSudoForNewUsers: boolean = true,\n\t) {\n\t\tsuper();\n\t\tperf.mark(\"constructor\");\n\t}\n\n\t/**\n\t * Loads users/sudoers from disk and ensures root account exists.\n\t * Also creates the current system user if not already present.\n\t */\n\tpublic async initialize(): Promise<void> {\n\t\tperf.mark(\"initialize\");\n\t\tthis.loadFromVfs();\n\t\tthis.loadSudoersFromVfs();\n\t\tthis.loadQuotasFromVfs();\n\n\t\tlet changed = false;\n\t\tif (!this.users.has(\"root\")) {\n\t\t\tthis.users.set(\"root\", this.createRecord(\"root\", \"\"));\n\t\t\tchanged = true;\n\t\t}\n\n\t\tthis.sudoers.add(\"root\");\n\n\t\t// Auto-create current system user for easier authentication\n\t\t// const currentUser = process.env.USER || process.env.USERNAME;\n\t\t// if (currentUser && currentUser !== \"root\" && !this.users.has(currentUser)) {\n\t\t// \tconst userPassword = this.defaultRootPassword;\n\t\t// \tthis.users.set(currentUser, this.createRecord(currentUser, userPassword));\n\t\t// \tthis.sudoers.add(currentUser);\n\t\t// \tchanged = true;\n\n\t\t// \tconst homePath = `/home/${currentUser}`;\n\t\t// \tif (!this.vfs.exists(homePath)) {\n\t\t// \t\tthis.vfs.mkdir(homePath, 0o755);\n\t\t// \t\tthis.vfs.writeFile(\n\t\t// \t\t\t`${homePath}/README.txt`,\n\t\t// \t\t\t`Welcome to the virtual environment, ${currentUser}`,\n\t\t// \t\t);\n\t\t// \t}\n\t\t// }\n\n\t\tif (changed) {\n\t\t\tawait this.persist();\n\t\t}\n\t\tthis.emit(\"initialized\");\n\t}\n\n\t/**\n\t * Sets max allowed bytes under /home/<username>.\n\t *\n\t * @param username Target username.\n\t * @param maxBytes Quota ceiling in bytes.\n\t */\n\tpublic async setQuotaBytes(\n\t\tusername: string,\n\t\tmaxBytes: number,\n\t): Promise<void> {\n\t\tperf.mark(\"setQuotaBytes\");\n\t\tthis.validateUsername(username);\n\t\tif (!this.users.has(username)) {\n\t\t\tthrow new Error(`quota: user '${username}' does not exist`);\n\t\t}\n\n\t\tif (!Number.isFinite(maxBytes) || maxBytes < 0) {\n\t\t\tthrow new Error(\"quota: maxBytes must be a non-negative number\");\n\t\t}\n\n\t\tthis.quotas.set(username, Math.floor(maxBytes));\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Removes quota for a user.\n\t *\n\t * @param username Target username.\n\t */\n\tpublic async clearQuota(username: string): Promise<void> {\n\t\tperf.mark(\"clearQuota\");\n\t\tthis.validateUsername(username);\n\t\tthis.quotas.delete(username);\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Gets configured quota in bytes for a user.\n\t *\n\t * @param username Target username.\n\t * @returns Quota in bytes, or null when unlimited.\n\t */\n\tpublic getQuotaBytes(username: string): number | null {\n\t\tperf.mark(\"getQuotaBytes\");\n\t\treturn this.quotas.get(username) ?? null;\n\t}\n\n\t/**\n\t * Computes current usage under /home/<username>.\n\t *\n\t * @param username Target username.\n\t * @returns Current usage in bytes.\n\t */\n\tpublic getUsageBytes(username: string): number {\n\t\tperf.mark(\"getUsageBytes\");\n\t\tconst homePath = `/home/${username}`;\n\t\tif (!this.vfs.exists(homePath)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn this.vfs.getUsageBytes(homePath);\n\t}\n\n\t/**\n\t * Validates that writing file content would not exceed user quota.\n\t *\n\t * Quotas are enforced only for writes inside /home/<username>.\n\t *\n\t * @param username Authenticated user.\n\t * @param targetPath Target file path.\n\t * @param nextContent New file content.\n\t */\n\tpublic assertWriteWithinQuota(\n\t\tusername: string,\n\t\ttargetPath: string,\n\t\tnextContent: string | Buffer,\n\t): void {\n\t\tperf.mark(\"assertWriteWithinQuota\");\n\t\tconst quota = this.quotas.get(username);\n\t\tif (quota === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst normalizedPath = normalizeVfsPath(targetPath);\n\t\tconst homePath = normalizeVfsPath(`/home/${username}`);\n\t\tconst inUserHome =\n\t\t\tnormalizedPath === homePath || normalizedPath.startsWith(`${homePath}/`);\n\t\tif (!inUserHome) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentUsage = this.getUsageBytes(username);\n\t\tlet existingSize = 0;\n\t\tif (this.vfs.exists(normalizedPath)) {\n\t\t\tconst existing = this.vfs.stat(normalizedPath);\n\t\t\tif (existing.type === \"file\") {\n\t\t\t\texistingSize = existing.size;\n\t\t\t}\n\t\t}\n\n\t\tconst incomingSize = Buffer.isBuffer(nextContent)\n\t\t\t? nextContent.length\n\t\t\t: Buffer.byteLength(nextContent, \"utf8\");\n\t\tconst projectedUsage = currentUsage - existingSize + incomingSize;\n\n\t\tif (projectedUsage > quota) {\n\t\t\tthrow new Error(\n\t\t\t\t`quota exceeded for '${username}': ${projectedUsage}/${quota} bytes`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Verifies plaintext password against stored record.\n\t *\n\t * @param username User login name.\n\t * @param password Plaintext password candidate.\n\t * @returns True when credentials are valid.\n\t */\n\tpublic verifyPassword(username: string, password: string): boolean {\n\t\tperf.mark(\"verifyPassword\");\n\t\tconst record = this.users.get(username);\n\t\tif (!record) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.hashPassword(password) === record.passwordHash;\n\t}\n\n\t/**\n\t * Creates user, home directory, and sudo access entry.\n\t *\n\t * @param username New username.\n\t * @param password Initial plaintext password.\n\t */\n\tpublic async addUser(username: string, password: string): Promise<void> {\n\t\tperf.mark(\"addUser\");\n\t\tthis.validateUsername(username);\n\t\tthis.validatePassword(password);\n\n\t\tif (this.users.has(username)) {\n\t\t\treturn;\n\t\t\t// throw new Error(`adduser: user '${username}' already exists`);\n\t\t}\n\n\t\tthis.users.set(username, this.createRecord(username, password));\n\t\tif (this.autoSudoForNewUsers) {\n\t\t\tthis.sudoers.add(username);\n\t\t}\n\t\tconst homePath = `/home/${username}`;\n\t\tif (!this.vfs.exists(homePath)) {\n\t\t\tthis.vfs.mkdir(homePath, 0o755);\n\t\t\tthis.vfs.writeFile(\n\t\t\t\t`${homePath}/README.txt`,\n\t\t\t\t`Welcome to the virtual environment, ${username}`,\n\t\t\t);\n\t\t}\n\t\tawait this.persist();\n\t\tthis.emit(\"user:add\", { username });\n\t}\n\n\t/**\n\t * Retrieves stored password hash for a user, or null if user does not exist.\n\t *\n\t * @param username Target username.\n\t * @returns Password hash in hex encoding, or null when user is not found.\n\t */\n\tpublic getPasswordHash(username: string): string | null {\n\t\tperf.mark(\"getPasswordHash\");\n\t\tconst record = this.users.get(username);\n\t\treturn record ? record.passwordHash : null;\n\t}\n\n\t/**\n\t * Updates the password for an existing user account.\n\t *\n\t * @param username Username to update.\n\t * @param password New plaintext password (must be non-empty).\n\t * @throws When the user does not exist or the password is empty.\n\t */\n\tpublic async setPassword(username: string, password: string): Promise<void> {\n\t\tperf.mark(\"setPassword\");\n\t\tthis.validateUsername(username);\n\t\tthis.validatePassword(password);\n\n\t\tif (!this.users.has(username)) {\n\t\t\tthrow new Error(`passwd: user '${username}' does not exist`);\n\t\t}\n\n\t\tthis.users.set(username, this.createRecord(username, password));\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Deletes an existing non-root user account and revokes sudo access.\n\t *\n\t * @param username Username to remove.\n\t * @throws When `username` is `\"root\"` or the user does not exist.\n\t */\n\tpublic async deleteUser(username: string): Promise<void> {\n\t\tperf.mark(\"deleteUser\");\n\t\tthis.validateUsername(username);\n\n\t\tif (username === \"root\") {\n\t\t\tthrow new Error(\"deluser: cannot delete root\");\n\t\t}\n\n\t\tif (!this.users.delete(username)) {\n\t\t\tthrow new Error(`deluser: user '${username}' does not exist`);\n\t\t}\n\n\t\tthis.sudoers.delete(username);\n\n\t\tthis.emit(\"user:delete\", { username });\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Checks whether user is member of sudoers set.\n\t *\n\t * @param username Username to test.\n\t * @returns True when user can run sudo.\n\t */\n\tpublic isSudoer(username: string): boolean {\n\t\tperf.mark(\"isSudoer\");\n\t\treturn this.sudoers.has(username);\n\t}\n\n\t/**\n\t * Grants sudo privileges to an existing user.\n\t *\n\t * @param username Username to promote.\n\t * @throws When the user does not exist.\n\t */\n\tpublic async addSudoer(username: string): Promise<void> {\n\t\tperf.mark(\"addSudoer\");\n\t\tthis.validateUsername(username);\n\t\tif (!this.users.has(username)) {\n\t\t\tthrow new Error(`sudoers: user '${username}' does not exist`);\n\t\t}\n\n\t\tthis.sudoers.add(username);\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Revokes sudo privileges from a user. Root cannot be demoted.\n\t *\n\t * @param username Username to demote.\n\t * @throws When `username` is `\"root\"`.\n\t */\n\tpublic async removeSudoer(username: string): Promise<void> {\n\t\tperf.mark(\"removeSudoer\");\n\t\tthis.validateUsername(username);\n\t\tif (username === \"root\") {\n\t\t\tthrow new Error(\"sudoers: cannot remove root\");\n\t\t}\n\n\t\tthis.sudoers.delete(username);\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Registers a new active session and allocates a virtual TTY identifier.\n\t *\n\t * Called by the SSH server when a client is authenticated. The returned\n\t * descriptor is visible in `who` output and `listActiveSessions()`.\n\t *\n\t * @param username Authenticated username bound to the session.\n\t * @param remoteAddress IP address or hostname of the connecting client.\n\t * @returns The newly created `VirtualActiveSession` descriptor.\n\t */\n\tpublic registerSession(\n\t\tusername: string,\n\t\tremoteAddress: string,\n\t): VirtualActiveSession {\n\t\tperf.mark(\"registerSession\");\n\t\tconst session: VirtualActiveSession = {\n\t\t\tid: randomUUID(),\n\t\t\tusername,\n\t\t\ttty: `pts/${this.nextTty++}`,\n\t\t\tremoteAddress,\n\t\t\tstartedAt: new Date().toISOString(),\n\t\t};\n\t\tthis.activeSessions.set(session.id, session);\n\t\tthis.emit(\"session:register\", {\n\t\t\tsessionId: session.id,\n\t\t\tusername,\n\t\t\tremoteAddress,\n\t\t});\n\t\treturn session;\n\t}\n\n\t/**\n\t * Removes an active session record when the connection closes.\n\t *\n\t * Safe to call with a `null` or `undefined` session ID \u2014 it will be a no-op.\n\t *\n\t * @param sessionId Session UUID returned by `registerSession()`, or nullish.\n\t */\n\tpublic unregisterSession(sessionId: string | null | undefined): void {\n\t\tperf.mark(\"unregisterSession\");\n\t\tif (!sessionId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst session = this.activeSessions.get(sessionId);\n\t\tthis.activeSessions.delete(sessionId);\n\t\tif (session) {\n\t\t\tthis.emit(\"session:unregister\", {\n\t\t\t\tsessionId,\n\t\t\t\tusername: session.username,\n\t\t\t});\n\t\t}\n\t\tthis.activeSessions.delete(sessionId);\n\t}\n\n\t/**\n\t * Updates the username and remote address metadata for an active session.\n\t *\n\t * Called internally by `su` and `sudo` when the effective user changes\n\t * within a session. Silently ignored when the session ID is nullish or\n\t * unknown.\n\t *\n\t * @param sessionId Session UUID to update, or nullish for no-op.\n\t * @param username New effective username.\n\t * @param remoteAddress New remote address (usually unchanged).\n\t */\n\tpublic updateSession(\n\t\tsessionId: string | null | undefined,\n\t\tusername: string,\n\t\tremoteAddress: string,\n\t): void {\n\t\tperf.mark(\"updateSession\");\n\t\tif (!sessionId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst session = this.activeSessions.get(sessionId);\n\t\tif (!session) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.activeSessions.set(sessionId, {\n\t\t\t...session,\n\t\t\tusername,\n\t\t\tremoteAddress,\n\t\t});\n\t}\n\n\t/**\n\t * Returns a snapshot of all currently active sessions, sorted by start time.\n\t *\n\t * Used by `who`, `ps`, `uptime`, and the `HoneyPot` auditor.\n\t *\n\t * @returns Array of `VirtualActiveSession` descriptors.\n\t */\n\tpublic listActiveSessions(): VirtualActiveSession[] {\n\t\tperf.mark(\"listActiveSessions\");\n\t\treturn Array.from(this.activeSessions.values()).sort((left, right) =>\n\t\t\tleft.startedAt.localeCompare(right.startedAt),\n\t\t);\n\t}\n\n\t/**\n\t * Returns a sorted list of all registered usernames.\n\t *\n\t * @returns Array of username strings sorted alphabetically.\n\t */\n\tpublic listUsers(): string[] {\n\t\treturn Array.from(this.users.keys()).sort();\n\t}\n\n\tprivate loadFromVfs(): void {\n\t\tthis.users.clear();\n\n\t\tif (!this.vfs.exists(this.usersPath)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst raw = this.vfs.readFile(this.usersPath);\n\t\tfor (const line of raw.split(\"\\n\")) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (trimmed.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst parts = trimmed.split(\":\");\n\t\t\tif (parts.length < 3) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst [username, salt, passwordHash] = parts;\n\t\t\tif (!username || !salt || !passwordHash) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis.users.set(username, { username, salt, passwordHash });\n\t\t}\n\t}\n\n\tprivate loadSudoersFromVfs(): void {\n\t\tthis.sudoers.clear();\n\n\t\tif (!this.vfs.exists(this.sudoersPath)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst raw = this.vfs.readFile(this.sudoersPath);\n\t\tfor (const line of raw.split(\"\\n\")) {\n\t\t\tconst username = line.trim();\n\t\t\tif (username.length > 0) {\n\t\t\t\tthis.sudoers.add(username);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate loadQuotasFromVfs(): void {\n\t\tthis.quotas.clear();\n\n\t\tif (!this.vfs.exists(this.quotasPath)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst raw = this.vfs.readFile(this.quotasPath);\n\t\tfor (const line of raw.split(\"\\n\")) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (trimmed.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst [username, value] = trimmed.split(\":\");\n\t\t\tconst bytes = Number.parseInt(value ?? \"\", 10);\n\t\t\tif (!username || !Number.isFinite(bytes) || bytes < 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis.quotas.set(username, bytes);\n\t\t}\n\t}\n\n\tprivate async persist(): Promise<void> {\n\t\tif (!this.vfs.exists(this.authDirPath)) {\n\t\t\tthis.vfs.mkdir(this.authDirPath, 0o700);\n\t\t}\n\n\t\tconst authContent = Array.from(this.users.values())\n\t\t\t.sort((left, right) => left.username.localeCompare(right.username))\n\t\t\t.map((record) =>\n\t\t\t\t[record.username, record.salt, record.passwordHash].join(\":\"),\n\t\t\t)\n\t\t\t.join(\"\\n\");\n\t\tconst sudoersContent = Array.from(this.sudoers.values()).sort().join(\"\\n\");\n\t\tconst quotasContent = Array.from(this.quotas.entries())\n\t\t\t.sort(([left], [right]) => left.localeCompare(right))\n\t\t\t.map(([username, maxBytes]) => `${username}:${maxBytes}`)\n\t\t\t.join(\"\\n\");\n\n\t\tlet changed = false;\n\t\tchanged =\n\t\t\tthis.writeIfChanged(\n\t\t\t\tthis.usersPath,\n\t\t\t\tauthContent.length > 0 ? `${authContent}\\n` : \"\",\n\t\t\t\t0o600,\n\t\t\t) || changed;\n\t\tchanged =\n\t\t\tthis.writeIfChanged(\n\t\t\t\tthis.sudoersPath,\n\t\t\t\tsudoersContent.length > 0 ? `${sudoersContent}\\n` : \"\",\n\t\t\t\t0o600,\n\t\t\t) || changed;\n\t\tchanged =\n\t\t\tthis.writeIfChanged(\n\t\t\t\tthis.quotasPath,\n\t\t\t\tquotasContent.length > 0 ? `${quotasContent}\\n` : \"\",\n\t\t\t\t0o600,\n\t\t\t) || changed;\n\n\t\tif (changed) {\n\t\t\tawait this.vfs.flushMirror();\n\t\t}\n\t}\n\n\tprivate writeIfChanged(\n\t\ttargetPath: string,\n\t\tcontent: string,\n\t\tmode: number,\n\t): boolean {\n\t\tif (this.vfs.exists(targetPath)) {\n\t\t\tconst existing = this.vfs.readFile(targetPath);\n\t\t\tif (existing === content) {\n\t\t\t\tthis.vfs.chmod(targetPath, mode);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.vfs.writeFile(targetPath, content, { mode });\n\t\treturn true;\n\t}\n\n\tprivate createRecord(username: string, password: string): VirtualUserRecord {\n\t\tconst cacheKey = `${username}:${password}`;\n\t\tconst cached = VirtualUserManager.recordCache.get(cacheKey);\n\t\tif (cached) {\n\t\t\treturn cached;\n\t\t}\n\n\t\tconst salt = randomBytes(16).toString(\"hex\");\n\t\tconst record = {\n\t\t\tusername,\n\t\t\tsalt,\n\t\t\tpasswordHash: this.hashPassword(password),\n\t\t};\n\n\t\tVirtualUserManager.recordCache.set(cacheKey, record);\n\t\treturn record;\n\t}\n\n\t/**\n\t * Returns `true` when the user has a non-empty password set.\n\t *\n\t * A user with no password (or whose password hash matches the empty-string\n\t * hash) is allowed to authenticate without a credential check.\n\t *\n\t * @param username Target username.\n\t */\n\tpublic hasPassword(username: string): boolean {\n\t\tperf.mark(\"hasPassword\");\n\t\tif (this.getPasswordHash(username) === this.hashPassword(\"\")) {\n\t\t\treturn false;\n\t\t}\n\t\tconst record = this.users.get(username);\n\t\treturn !!record && !!record.passwordHash;\n\t}\n\n\t/**\n\t * Hashes a plaintext password using scrypt (or SHA-256 in fast-hash mode).\n\t *\n\t * Set `SSH_MIMIC_FAST_PASSWORD_HASH=1` to switch to SHA-256 for test\n\t * environments where scrypt latency is undesirable.\n\t *\n\t * @param password Plaintext password string.\n\t * @returns Hex-encoded hash string.\n\t */\n\tpublic hashPassword(password: string): string {\n\t\tif (VirtualUserManager.fastPasswordHash) {\n\t\t\treturn createHash(\"sha256\").update(`${password}`).digest(\"hex\");\n\t\t}\n\n\t\treturn scryptSync(password, \"\", 32).toString(\"hex\");\n\t}\n\n\tprivate validateUsername(username: string): void {\n\t\tif (!username || username.trim() === \"\") {\n\t\t\tthrow new Error(\"invalid username\");\n\t\t}\n\n\t\tif (!/^[a-z_][a-z0-9_-]{0,31}$/i.test(username)) {\n\t\t\tthrow new Error(\"invalid username\");\n\t\t}\n\t}\n\n\tprivate validatePassword(password: string): void {\n\t\tif (!password || password.trim() === \"\") {\n\t\t\tthrow new Error(\"invalid password\");\n\t\t}\n\t}\n\tprivate readonly authorizedKeys = new Map<\n\t\tstring,\n\t\tArray<{ algo: string; data: Buffer }>\n\t>();\n\n\t/**\n\t * Adds an SSH public key for a user, enabling public-key authentication.\n\t *\n\t * @param username Target user.\n\t * @param algo Key algorithm (e.g. \"ssh-rsa\", \"ssh-ed25519\").\n\t * @param data Raw key data as a Buffer (the base64-decoded key bytes).\n\t */\n\tpublic addAuthorizedKey(username: string, algo: string, data: Buffer): void {\n\t\tperf.mark(\"addAuthorizedKey\");\n\t\tconst keys = this.authorizedKeys.get(username) ?? [];\n\t\tkeys.push({ algo, data });\n\t\tthis.authorizedKeys.set(username, keys);\n\t\tthis.emit(\"key:add\", { username, algo });\n\t}\n\n\t/**\n\t * Removes all authorized keys for a user.\n\t *\n\t * @param username Target user.\n\t */\n\tpublic removeAuthorizedKeys(username: string): void {\n\t\tthis.authorizedKeys.delete(username);\n\t\tthis.emit(\"key:remove\", { username });\n\t}\n\n\t/**\n\t * Returns the list of authorized keys for a user.\n\t * Returns an empty array when no keys are registered.\n\t *\n\t * @param username Target user.\n\t */\n\tpublic getAuthorizedKeys(\n\t\tusername: string,\n\t): Array<{ algo: string; data: Buffer }> {\n\t\treturn this.authorizedKeys.get(username) ?? [];\n\t}\n}\n\nfunction normalizeVfsPath(targetPath: string): string {\n\tconst normalized = path.posix.normalize(targetPath);\n\treturn normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n", "import type { ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { readFile, unlink, writeFile } from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { ShellProperties, VirtualShell } from \".\";\nimport { getCommandNames, makeDefaultEnv, runCommand } from \"../commands\";\nimport {\n\tspawnHtopProcess,\n\tspawnNanoEditorProcess,\n} from \"../modules/shellInteractive\";\nimport {\n\tgetVisibleHtopPidList,\n\tresolvePath,\n\ttype TerminalSize,\n\ttoTtyLines,\n} from \"../modules/shellRuntime\";\nimport { buildLoginBanner } from \"../SSHMimic/loginBanner\";\nimport { buildPrompt } from \"../SSHMimic/prompt\";\nimport type { ShellEnv } from \"../types/commands\";\nimport type { ShellStream } from \"../types/streams\";\nimport type VirtualFileSystem from \"../VirtualFileSystem\";\n\ninterface NanoSession {\n\tkind: \"nano\" | \"htop\";\n\ttargetPath: string;\n\ttempPath: string;\n\tprocess: ChildProcessWithoutNullStreams;\n}\n\ninterface PendingSudo {\n\tusername: string;\n\ttargetUser: string;\n\tcommandLine: string | null;\n\tloginShell: boolean;\n\tprompt: string;\n\tbuffer: string;\n}\n\nexport function startShell(\n\tproperties: ShellProperties,\n\tstream: ShellStream,\n\tauthUser: string,\n\thostname: string,\n\tsessionId: string | null,\n\tremoteAddress = \"unknown\",\n\tterminalSize: TerminalSize = { cols: 80, rows: 24 },\n\tshell: VirtualShell,\n): void {\n\tlet lineBuffer = \"\";\n\tlet cursorPos = 0;\n\tlet history = loadHistory(shell.vfs);\n\tlet historyIndex: number | null = null;\n\tlet historyDraft = \"\";\n\tlet cwd = `/home/${authUser}`;\n\tconst shellEnv: ShellEnv = makeDefaultEnv(authUser, hostname);\n\tlet nanoSession: NanoSession | null = null;\n\tlet pendingSudo: PendingSudo | null = null;\n\tconst buildCurrentPrompt = (): string => {\n\t\tconst homePath = `/home/${authUser}`;\n\t\tconst cwdLabel = cwd === homePath ? \"~\" : path.posix.basename(cwd) || \"/\";\n\t\treturn buildPrompt(authUser, hostname, cwdLabel);\n\t};\n\tconst commandNames = Array.from(new Set(getCommandNames())).sort();\n\tconsole.log(\n\t\t`[${sessionId}] Shell started for user '${authUser}' at ${remoteAddress}`,\n\t);\n\n\t// Load .bashrc if it exists\n\tvoid (async () => {\n\t\tconst bashrcPath = `/home/${authUser}/.bashrc`;\n\t\tif (shell.vfs.exists(bashrcPath)) {\n\t\t\ttry {\n\t\t\t\tconst bashrc = shell.vfs.readFile(bashrcPath);\n\t\t\t\tfor (const line of bashrc.split(\"\\n\")) {\n\t\t\t\t\tconst l = line.trim();\n\t\t\t\t\tif (!l || l.startsWith(\"#\")) continue;\n\t\t\t\t\tawait runCommand(\n\t\t\t\t\t\tl,\n\t\t\t\t\t\tauthUser,\n\t\t\t\t\t\thostname,\n\t\t\t\t\t\t\"shell\",\n\t\t\t\t\t\tcwd,\n\t\t\t\t\t\tshell,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tshellEnv,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t/* ignore bashrc errors */\n\t\t\t}\n\t\t}\n\t})();\n\n\tfunction renderLine(): void {\n\t\tconst prompt = buildCurrentPrompt();\n\t\tstream.write(`\\r${prompt}${lineBuffer}\\u001b[K`);\n\n\t\tconst moveLeft = lineBuffer.length - cursorPos;\n\t\tif (moveLeft > 0) {\n\t\t\tstream.write(`\\u001b[${moveLeft}D`);\n\t\t}\n\t}\n\n\tfunction clearCurrentLine(): void {\n\t\tstream.write(\"\\r\\u001b[K\");\n\t}\n\n\tfunction startSudoPrompt(challenge: {\n\t\tusername: string;\n\t\ttargetUser: string;\n\t\tcommandLine: string | null;\n\t\tloginShell: boolean;\n\t\tprompt: string;\n\t}): void {\n\t\tpendingSudo = {\n\t\t\t...challenge,\n\t\t\tbuffer: \"\",\n\t\t};\n\t\tclearCurrentLine();\n\t\tstream.write(challenge.prompt);\n\t}\n\n\tasync function finishSudoPrompt(success: boolean): Promise<void> {\n\t\tif (!pendingSudo) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst challenge = pendingSudo;\n\t\tpendingSudo = null;\n\n\t\tif (!success) {\n\t\t\tstream.write(\"\\r\\nSorry, try again.\\r\\n\");\n\t\t\trenderLine();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!challenge.commandLine) {\n\t\t\tauthUser = challenge.targetUser;\n\t\t\tcwd = `/home/${authUser}`;\n\t\t\tshell.users.updateSession(sessionId, authUser, remoteAddress);\n\t\t\tstream.write(\"\\r\\n\");\n\t\t\trenderLine();\n\t\t\treturn;\n\t\t}\n\n\t\tconst runCwd = challenge.loginShell ? `/home/${challenge.targetUser}` : cwd;\n\t\tconst result = await Promise.resolve(\n\t\t\trunCommand(\n\t\t\t\tchallenge.commandLine,\n\t\t\t\tchallenge.targetUser,\n\t\t\t\thostname,\n\t\t\t\t\"shell\",\n\t\t\t\trunCwd,\n\t\t\t\tshell,\n\t\t\t),\n\t\t);\n\n\t\tstream.write(\"\\r\\n\");\n\n\t\tif (result.openEditor) {\n\t\t\tawait startNanoEditor(\n\t\t\t\tresult.openEditor.targetPath,\n\t\t\t\tresult.openEditor.initialContent,\n\t\t\t\tresult.openEditor.tempPath,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (result.openHtop) {\n\t\t\tawait startHtop();\n\t\t\treturn;\n\t\t}\n\n\t\tif (result.clearScreen) {\n\t\t\tstream.write(\"\\u001b[2J\\u001b[H\");\n\t\t}\n\n\t\tif (result.stdout) {\n\t\t\tstream.write(`${toTtyLines(result.stdout)}\\r\\n`);\n\t\t}\n\n\t\tif (result.stderr) {\n\t\t\tstream.write(`${toTtyLines(result.stderr)}\\r\\n`);\n\t\t}\n\n\t\tif (result.switchUser) {\n\t\t\tauthUser = result.switchUser;\n\t\t\tcwd = result.nextCwd ?? `/home/${authUser}`;\n\t\t\tshell.users.updateSession(sessionId, authUser, remoteAddress);\n\t\t} else if (result.nextCwd) {\n\t\t\tcwd = result.nextCwd;\n\t\t}\n\n\t\tawait shell.vfs.flushMirror();\n\t\trenderLine();\n\t}\n\n\tasync function finishNanoEditor(): Promise<void> {\n\t\tif (!nanoSession) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst activeSession = nanoSession;\n\n\t\tif (activeSession.kind === \"nano\") {\n\t\t\ttry {\n\t\t\t\tconst updatedContent = await readFile(activeSession.tempPath, \"utf8\");\n\t\t\t\tshell.writeFileAsUser(\n\t\t\t\t\tauthUser,\n\t\t\t\t\tactiveSession.targetPath,\n\t\t\t\t\tupdatedContent,\n\t\t\t\t);\n\t\t\t\tawait shell.vfs.flushMirror();\n\t\t\t} catch {\n\t\t\t\t// If temp file does not exist, nano exited without writing.\n\t\t\t}\n\n\t\t\tawait unlink(activeSession.tempPath).catch(() => undefined);\n\t\t}\n\n\t\tnanoSession = null;\n\t\tlineBuffer = \"\";\n\t\tcursorPos = 0;\n\t\tstream.write(\"\\r\\n\");\n\t\trenderLine();\n\t}\n\n\tasync function startNanoEditor(\n\t\ttargetPath: string,\n\t\tinitialContent: string,\n\t\ttempPath: string,\n\t): Promise<void> {\n\t\tif (shell.vfs.exists(targetPath)) {\n\t\t\tawait writeFile(tempPath, initialContent, \"utf8\");\n\t\t}\n\n\t\tconst editor = spawnNanoEditorProcess(tempPath, terminalSize, stream);\n\n\t\teditor.on(\"error\", (error: Error) => {\n\t\t\tstream.write(`nano: ${error.message}\\r\\n`);\n\t\t\tvoid finishNanoEditor();\n\t\t});\n\n\t\teditor.on(\"close\", () => {\n\t\t\tvoid finishNanoEditor();\n\t\t});\n\n\t\tnanoSession = {\n\t\t\tkind: \"nano\",\n\t\t\ttargetPath,\n\t\t\ttempPath,\n\t\t\tprocess: editor,\n\t\t};\n\t}\n\n\tasync function startHtop(): Promise<void> {\n\t\tconst pidList = await getVisibleHtopPidList();\n\t\tif (!pidList) {\n\t\t\tstream.write(\"htop: no child_process processes to display\\r\\n\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst monitor = spawnHtopProcess(pidList, terminalSize, stream);\n\n\t\tmonitor.on(\"error\", (error: Error) => {\n\t\t\tstream.write(`htop: ${error.message}\\r\\n`);\n\t\t\tvoid finishNanoEditor();\n\t\t});\n\n\t\tmonitor.on(\"close\", () => {\n\t\t\tvoid finishNanoEditor();\n\t\t});\n\n\t\tnanoSession = {\n\t\t\tkind: \"htop\",\n\t\t\ttargetPath: \"\",\n\t\t\ttempPath: \"\",\n\t\t\tprocess: monitor,\n\t\t};\n\t}\n\n\tfunction applyHistoryLine(nextLine: string): void {\n\t\tlineBuffer = nextLine;\n\t\tcursorPos = lineBuffer.length;\n\t\trenderLine();\n\t}\n\n\tfunction insertText(text: string): void {\n\t\tlineBuffer = `${lineBuffer.slice(0, cursorPos)}${text}${lineBuffer.slice(cursorPos)}`;\n\t\tcursorPos += text.length;\n\t\trenderLine();\n\t}\n\n\tfunction getTokenRange(\n\t\tline: string,\n\t\tcursor: number,\n\t): { start: number; end: number } {\n\t\tlet start = cursor;\n\t\twhile (start > 0 && !/\\s/.test(line[start - 1]!)) {\n\t\t\tstart -= 1;\n\t\t}\n\n\t\tlet end = cursor;\n\t\twhile (end < line.length && !/\\s/.test(line[end]!)) {\n\t\t\tend += 1;\n\t\t}\n\n\t\treturn { start, end };\n\t}\n\n\tfunction listPathCompletions(prefix: string): string[] {\n\t\tconst slashIndex = prefix.lastIndexOf(\"/\");\n\t\tconst dirPart = slashIndex >= 0 ? prefix.slice(0, slashIndex + 1) : \"\";\n\t\tconst namePart = slashIndex >= 0 ? prefix.slice(slashIndex + 1) : prefix;\n\t\tconst basePath = resolvePath(cwd, dirPart || \".\");\n\n\t\ttry {\n\t\t\treturn shell.vfs\n\t\t\t\t.list(basePath)\n\t\t\t\t.filter((entry) => !entry.startsWith(\".\"))\n\t\t\t\t.filter((entry) => entry.startsWith(namePart))\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst fullPath = path.posix.join(basePath, entry);\n\t\t\t\t\tconst st = shell.vfs.stat(fullPath);\n\t\t\t\t\tconst suffix = st.type === \"directory\" ? \"/\" : \"\";\n\t\t\t\t\treturn `${dirPart}${entry}${suffix}`;\n\t\t\t\t})\n\t\t\t\t.sort();\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tfunction handleTabCompletion(): void {\n\t\tconst { start, end } = getTokenRange(lineBuffer, cursorPos);\n\t\tconst token = lineBuffer.slice(start, cursorPos);\n\n\t\tif (token.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst firstToken = lineBuffer.slice(0, start).trim().length === 0;\n\t\tconst commandCandidates = firstToken\n\t\t\t? commandNames.filter((name) => name.startsWith(token))\n\t\t\t: [];\n\t\tconst pathCandidates = listPathCompletions(token);\n\t\tconst candidates = Array.from(\n\t\t\tnew Set([...commandCandidates, ...pathCandidates]),\n\t\t).sort();\n\n\t\tif (candidates.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (candidates.length === 1) {\n\t\t\tconst completed = candidates[0]!;\n\t\t\tconst suffix = completed.endsWith(\"/\") ? \"\" : \" \";\n\t\t\tlineBuffer = `${lineBuffer.slice(0, start)}${completed}${suffix}${lineBuffer.slice(end)}`;\n\t\t\tcursorPos = start + completed.length + suffix.length;\n\t\t\trenderLine();\n\t\t\treturn;\n\t\t}\n\n\t\tstream.write(\"\\r\\n\");\n\t\tstream.write(`${candidates.join(\" \")}\\r\\n`);\n\t\trenderLine();\n\t}\n\n\tfunction pushHistory(cmd: string): void {\n\t\tif (cmd.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\thistory.push(cmd);\n\t\tif (history.length > 500) {\n\t\t\thistory = history.slice(history.length - 500);\n\t\t}\n\n\t\tconst data = history.length > 0 ? `${history.join(\"\\n\")}\\n` : \"\";\n\t\tshell.vfs.writeFile(\"/virtual-env-js/.bash_history\", data);\n\t}\n\n\tfunction readLastLogin(): { at: string; from: string } | null {\n\t\tconst lastlogPath = `/virtual-env-js/.lastlog/${authUser}.json`;\n\t\tif (!shell.vfs.exists(lastlogPath)) {\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\treturn JSON.parse(shell.vfs.readFile(lastlogPath)) as {\n\t\t\t\tat: string;\n\t\t\t\tfrom: string;\n\t\t\t};\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tfunction writeLastLogin(nowIso: string): void {\n\t\tconst dir = \"/virtual-env-js/.lastlog\";\n\t\tif (!shell.vfs.exists(dir)) {\n\t\t\tshell.vfs.mkdir(dir, 0o700);\n\t\t}\n\n\t\tconst lastlogPath = `${dir}/${authUser}.json`;\n\t\tshell.vfs.writeFile(\n\t\t\tlastlogPath,\n\t\t\tJSON.stringify({ at: nowIso, from: remoteAddress }),\n\t\t);\n\t}\n\n\tfunction renderLoginBanner(): void {\n\t\tconst last = readLastLogin();\n\t\tconst nowIso = new Date().toISOString();\n\t\tstream.write(buildLoginBanner(hostname, properties, last));\n\t\twriteLastLogin(nowIso);\n\t}\n\n\trenderLoginBanner();\n\trenderLine();\n\n\tstream.on(\"data\", async (chunk: Buffer) => {\n\t\tif (nanoSession) {\n\t\t\tnanoSession.process.stdin.write(chunk);\n\t\t\treturn;\n\t\t}\n\n\t\tif (pendingSudo) {\n\t\t\tconst input = chunk.toString(\"utf8\");\n\n\t\t\tfor (let i = 0; i < input.length; i += 1) {\n\t\t\t\tconst ch = input[i]!;\n\n\t\t\t\tif (ch === \"\\u0003\") {\n\t\t\t\t\tpendingSudo = null;\n\t\t\t\t\tstream.write(\"^C\\r\\n\");\n\t\t\t\t\trenderLine();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (ch === \"\\u007f\" || ch === \"\\b\") {\n\t\t\t\t\tpendingSudo.buffer = pendingSudo.buffer.slice(0, -1);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (ch === \"\\r\" || ch === \"\\n\") {\n\t\t\t\t\tconst password = pendingSudo.buffer;\n\t\t\t\t\tpendingSudo.buffer = \"\";\n\t\t\t\t\tconst valid = shell.users.verifyPassword(\n\t\t\t\t\t\tpendingSudo.username,\n\t\t\t\t\t\tpassword,\n\t\t\t\t\t);\n\t\t\t\t\tawait finishSudoPrompt(valid);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (ch >= \" \") {\n\t\t\t\t\tpendingSudo.buffer += ch;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst input = chunk.toString(\"utf8\");\n\n\t\tfor (let i = 0; i < input.length; i += 1) {\n\t\t\tconst ch = input[i]!;\n\n\t\t\tif (ch === \"\\u0004\") {\n\t\t\t\tlineBuffer = \"\";\n\t\t\t\tcursorPos = 0;\n\t\t\t\thistoryIndex = null;\n\t\t\t\thistoryDraft = \"\";\n\t\t\t\tstream.write(\"bye\\r\\n\");\n\t\t\t\tpushHistory(\"bye\");\n\t\t\t\tawait shell.vfs.flushMirror();\n\t\t\t\tstream.write(\"logout\\r\\n\");\n\t\t\t\tstream.exit(0);\n\t\t\t\tstream.end();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (ch === \"\\t\") {\n\t\t\t\thandleTabCompletion();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (ch === \"\\u001b\") {\n\t\t\t\tconst next = input[i + 1];\n\t\t\t\tconst third = input[i + 2];\n\t\t\t\tconst fourth = input[i + 3];\n\n\t\t\t\tif (next === \"[\" && third) {\n\t\t\t\t\tif (third === \"A\") {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tif (history.length > 0) {\n\t\t\t\t\t\t\tif (historyIndex === null) {\n\t\t\t\t\t\t\t\thistoryDraft = lineBuffer;\n\t\t\t\t\t\t\t\thistoryIndex = history.length - 1;\n\t\t\t\t\t\t\t} else if (historyIndex > 0) {\n\t\t\t\t\t\t\t\thistoryIndex -= 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tapplyHistoryLine(history[historyIndex] ?? \"\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (third === \"B\") {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tif (historyIndex !== null) {\n\t\t\t\t\t\t\tif (historyIndex < history.length - 1) {\n\t\t\t\t\t\t\t\thistoryIndex += 1;\n\t\t\t\t\t\t\t\tapplyHistoryLine(history[historyIndex] ?? \"\");\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\thistoryIndex = null;\n\t\t\t\t\t\t\t\tapplyHistoryLine(historyDraft);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (third === \"C\") {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tif (cursorPos < lineBuffer.length) {\n\t\t\t\t\t\t\tcursorPos += 1;\n\t\t\t\t\t\t\tstream.write(\"\\u001b[C\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (third === \"D\") {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tif (cursorPos > 0) {\n\t\t\t\t\t\t\tcursorPos -= 1;\n\t\t\t\t\t\t\tstream.write(\"\\u001b[D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (third === \"3\" && fourth === \"~\") {\n\t\t\t\t\t\ti += 3;\n\t\t\t\t\t\tif (cursorPos < lineBuffer.length) {\n\t\t\t\t\t\t\tlineBuffer = `${lineBuffer.slice(0, cursorPos)}${lineBuffer.slice(cursorPos + 1)}`;\n\t\t\t\t\t\t\trenderLine();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (ch === \"\\u0003\") {\n\t\t\t\tlineBuffer = \"\";\n\t\t\t\tcursorPos = 0;\n\t\t\t\thistoryIndex = null;\n\t\t\t\thistoryDraft = \"\";\n\t\t\t\tstream.write(\"^C\\r\\n\");\n\t\t\t\trenderLine();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (ch === \"\\r\" || ch === \"\\n\") {\n\t\t\t\tconst line = lineBuffer.trim();\n\t\t\t\tlineBuffer = \"\";\n\t\t\t\tcursorPos = 0;\n\t\t\t\thistoryIndex = null;\n\t\t\t\thistoryDraft = \"\";\n\t\t\t\tstream.write(\"\\r\\n\");\n\n\t\t\t\tif (line.length > 0) {\n\t\t\t\t\tconst result = await Promise.resolve(\n\t\t\t\t\t\trunCommand(\n\t\t\t\t\t\t\tline,\n\t\t\t\t\t\t\tauthUser,\n\t\t\t\t\t\t\thostname,\n\t\t\t\t\t\t\t\"shell\",\n\t\t\t\t\t\t\tcwd,\n\t\t\t\t\t\t\tshell,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tshellEnv,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tpushHistory(line);\n\n\t\t\t\t\tif (result.openEditor) {\n\t\t\t\t\t\tawait startNanoEditor(\n\t\t\t\t\t\t\tresult.openEditor.targetPath,\n\t\t\t\t\t\t\tresult.openEditor.initialContent,\n\t\t\t\t\t\t\tresult.openEditor.tempPath,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.openHtop) {\n\t\t\t\t\t\tawait startHtop();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.sudoChallenge) {\n\t\t\t\t\t\tstartSudoPrompt(result.sudoChallenge);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.clearScreen) {\n\t\t\t\t\t\tstream.write(\"\\u001b[2J\\u001b[H\");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.stdout) {\n\t\t\t\t\t\tstream.write(`${toTtyLines(result.stdout)}\\r\\n`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.stderr) {\n\t\t\t\t\t\tstream.write(`${toTtyLines(result.stderr)}\\r\\n`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.closeSession) {\n\t\t\t\t\t\tstream.write(\"logout\\r\\n\");\n\t\t\t\t\t\tstream.exit(result.exitCode ?? 0);\n\t\t\t\t\t\tstream.end();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.nextCwd) {\n\t\t\t\t\t\tcwd = result.nextCwd;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.switchUser) {\n\t\t\t\t\t\tauthUser = result.switchUser;\n\t\t\t\t\t\tcwd = result.nextCwd ?? `/home/${authUser}`;\n\t\t\t\t\t\tshell.users.updateSession(sessionId, authUser, remoteAddress);\n\t\t\t\t\t\tlineBuffer = \"\";\n\t\t\t\t\t\tcursorPos = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait shell.vfs.flushMirror();\n\t\t\t\t}\n\n\t\t\t\trenderLine();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (ch === \"\\u007f\" || ch === \"\\b\") {\n\t\t\t\tif (cursorPos > 0) {\n\t\t\t\t\tlineBuffer = `${lineBuffer.slice(0, cursorPos - 1)}${lineBuffer.slice(cursorPos)}`;\n\t\t\t\t\tcursorPos -= 1;\n\t\t\t\t\trenderLine();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tinsertText(ch);\n\t\t}\n\t});\n\n\tstream.on(\"close\", () => {\n\t\tif (nanoSession) {\n\t\t\tnanoSession.process.kill(\"SIGTERM\");\n\t\t\tnanoSession = null;\n\t\t}\n\t});\n}\n\nfunction loadHistory(vfs: VirtualFileSystem): string[] {\n\tconst historyPath = \"/virtual-env-js/.bash_history\";\n\tif (!vfs.exists(historyPath)) {\n\t\tvfs.writeFile(historyPath, \"\");\n\t\treturn [];\n\t}\n\n\tconst raw = vfs.readFile(historyPath);\n\treturn raw\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trim())\n\t\t.filter((line) => line.length > 0);\n}\n", "import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport type { ShellStream } from \"../types/streams\";\nimport {\n\tshellQuote,\n\ttype TerminalSize,\n\twithTerminalSize,\n} from \"./shellRuntime\";\n\nfunction spawnScriptProcess(\n\tcommand: string,\n\tterminalSize: TerminalSize,\n\tstream: ShellStream,\n): ChildProcessWithoutNullStreams {\n\tconst formatted = withTerminalSize(command, terminalSize);\n\tconst proc = spawn(\"script\", [\"-qfec\", formatted, \"/dev/null\"], {\n\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t// biome-ignore lint/style/useNamingConvention: env variable should be uppercase\n\t\t\tTERM: process.env.TERM ?? \"xterm-256color\",\n\t\t},\n\t});\n\n\tproc.stdout.on(\"data\", (data: Buffer) => {\n\t\tstream.write(data.toString(\"utf8\"));\n\t});\n\n\tproc.stderr.on(\"data\", (data: Buffer) => {\n\t\tstream.write(data.toString(\"utf8\"));\n\t});\n\n\treturn proc;\n}\n\nexport function spawnNanoEditorProcess(\n\ttempPath: string,\n\tterminalSize: TerminalSize,\n\tstream: ShellStream,\n): ChildProcessWithoutNullStreams {\n\treturn spawnScriptProcess(\n\t\t`nano -- ${shellQuote(tempPath)}`,\n\t\tterminalSize,\n\t\tstream,\n\t);\n}\n\nexport function spawnHtopProcess(\n\tpidList: string,\n\tterminalSize: TerminalSize,\n\tstream: ShellStream,\n): ChildProcessWithoutNullStreams {\n\treturn spawnScriptProcess(\n\t\t`htop -p ${shellQuote(pidList)}`,\n\t\tterminalSize,\n\t\tstream,\n\t);\n}\n", "import { readFile } from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nexport interface TerminalSize {\n\tcols: number;\n\trows: number;\n}\n\nexport function shellQuote(value: string): string {\n\treturn `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nexport function toTtyLines(text: string): string {\n\treturn text\n\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t.replace(/\\r/g, \"\\n\")\n\t\t.replace(/\\n/g, \"\\r\\n\");\n}\n\nexport function withTerminalSize(\n\tcommand: string,\n\tterminalSize: TerminalSize,\n): string {\n\tconst cols =\n\t\tNumber.isFinite(terminalSize.cols) && terminalSize.cols > 0\n\t\t\t? Math.floor(terminalSize.cols)\n\t\t\t: 80;\n\tconst rows =\n\t\tNumber.isFinite(terminalSize.rows) && terminalSize.rows > 0\n\t\t\t? Math.floor(terminalSize.rows)\n\t\t\t: 24;\n\treturn `stty cols ${cols} rows ${rows} 2>/dev/null; ${command}`;\n}\n\nexport function resolvePath(base: string, inputPath: string): string {\n\tif (!inputPath || inputPath.trim() === \"\" || inputPath === \".\") {\n\t\treturn base;\n\t}\n\treturn inputPath.startsWith(\"/\")\n\t\t? path.posix.normalize(inputPath)\n\t\t: path.posix.normalize(path.posix.join(base, inputPath));\n}\n\nexport async function collectChildPids(parentPid: number): Promise<number[]> {\n\ttry {\n\t\tconst childrenRaw = await readFile(\n\t\t\t`/proc/${parentPid}/task/${parentPid}/children`,\n\t\t\t\"utf8\",\n\t\t);\n\t\tconst directChildren = childrenRaw\n\t\t\t.trim()\n\t\t\t.split(/\\s+/)\n\t\t\t.filter(Boolean)\n\t\t\t.map((value) => Number.parseInt(value, 10))\n\t\t\t.filter((pid) => Number.isInteger(pid) && pid > 0);\n\n\t\tconst nested = await Promise.all(\n\t\t\tdirectChildren.map((pid) => collectChildPids(pid)),\n\t\t);\n\t\treturn [...directChildren, ...nested.flat()];\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nexport async function getVisibleHtopPidList(\n\trootPid = process.pid,\n): Promise<string | null> {\n\tconst descendants = await collectChildPids(rootPid);\n\tconst unique = Array.from(new Set(descendants)).sort((a, b) => a - b);\n\tif (unique.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn unique.join(\",\");\n}\n"],
|
|
5
|
-
"mappings": "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AAA;AAAA,EACT,KAAM,GACP,EACA,CAAE,KAAM,4BAA6B,QAAS,EAAG,CAClD,CACD,EACA,CACC,KAAM,kBACN,QAAS,cACT,QAAS,SACT,YAAa,oDACb,UAAW,oCACX,gBAAiB,IACjB,MAAO,CAAC,CAAE,KAAM,iCAAkC,QAAS,EAAG,CAAC,CAChE,EACA,CACC,KAAM,SACN,QAAS,iBACT,QAAS,aACT,YAAa,qDACb,UAAW,6BACX,gBAAiB,MACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,kBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,+BACN,QAAS;AAAA,CACV,CACD,CACD,EACA,CACC,KAAM,MACN,QAAS,cACT,QAAS,aACT,YAAa,8BACb,UAAW,8BACX,gBAAiB,KACjB,QAAS,CAAC,QAAQ,EAClB,MAAO,CACN,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,oBACT,QAAS,MACT,YAAa,0DACb,UAAW,0CACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,cACT,QAAS,MACT,YAAa,+BACb,UAAW,+BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,UACT,QAAS,QACT,YAAa,+BACb,UAAW,6BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,iBACN,QAAS,oBACT,QAAS,MACT,YAAa,4BACb,UAAW,4BACX,gBAAiB,KACjB,MAAO,CACN,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,sBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,sBACN,QAAS;AAAA;AAAA,CACV,CACD,CACD,EACA,CACC,KAAM,iBACN,QAAS,oBACT,QAAS,MACT,YAAa,6BACb,UAAW,sBACX,gBAAiB,KACjB,QAAS,CAAC,gBAAgB,EAC1B,MAAO,CACN,CACC,KAAM,iBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,uBACN,QAAS;AAAA;AAAA;AAAA,CACV,CACD,CACD,EACA,CACC,KAAM,YACN,QAAS,WACT,QAAS,MACT,YAAa,sDACb,UAAW,qBACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,oBACN,QACC;AAAA;AAAA;AAAA;AAAA,EACD,KAAM,GACP,EACA,CACC,KAAM,mBACN,QACC;AAAA;AAAA;AAAA,EACD,KAAM,GACP,EACA,CACC,KAAM,iBACN,QACC;AAAA;AAAA;AAAA;AAAA,EACD,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,eACN,QAAS,eACT,QAAS,MACT,YAAa,kDACb,UAAW,qCACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,KACN,QAAS,UACT,QAAS,QACT,YAAa,uDACb,UAAW,8BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,cACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,kBACN,QAAS,OACT,QAAS,QACT,YAAa,iDACb,UAAW,+BACX,gBAAiB,GACjB,QAAS,CAAC,MAAO,MAAO,MAAM,EAC9B,MAAO,CACN,CACC,KAAM,wCACN,QAAS;AAAA,CACV,CACD,CACD,EACA,CACC,KAAM,MACN,QAAS,aACT,QAAS,QACT,YAAa,iBACb,UAAW,iBACX,gBAAiB,MACjB,MAAO,CACN,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,kBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,MACN,QAAS,aACT,QAAS,QACT,YAAa,mBACb,UAAW,mBACX,gBAAiB,KACjB,QAAS,CAAC,KAAK,EACf,MAAO,CACN,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,UACT,QAAS,QACT,YAAa,oCACb,UAAW,gBACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QACC;AAAA;AAAA;AAAA,EACD,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,QACT,QAAS,OACT,YAAa,gCACb,UAAW,gBACX,gBAAiB,IACjB,MAAO,CACN,CAAE,KAAM,gBAAiB,QAAS;AAAA;AAAA,EAAyB,KAAM,GAAM,CACxE,CACD,EACA,CACC,KAAM,QACN,QAAS,SACT,QAAS,QACT,YAAa,6BACb,UAAW,6BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,iBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,QACN,QAAS,UACT,QAAS,MACT,YAAa,wDACb,UAAW,gCACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,iBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,SACT,QAAS,QACT,YAAa,uBACb,UAAW,uBACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QACC;AAAA;AAAA,EACD,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,UACT,QAAS,QACT,YAAa,gDACb,UAAW,4BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,kBACN,QAAS,WACT,QAAS,OACT,YAAa,yBACb,UAAW,yBACX,gBAAiB,IACjB,MAAO,CACN,CAAE,KAAM,uBAAwB,QAAS,EAAG,EAC5C,CAAE,KAAM,yBAA0B,QAAS,EAAG,EAC9C,CAAE,KAAM,mCAAoC,QAAS,EAAG,CACzD,EA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",
|
|
6
|
-
"names": ["basename", "stdin", "stdout", "createInterface", "adduserCommand", "authUser", "shell", "args", "username", "password", "toFlagList", "flags", "matchFlagToken", "token", "flag", "prefix", "collectPositionals", "args", "options", "boolFlags", "valueFlags", "positionals", "passthrough", "index", "arg", "consumed", "matched", "match", "ifFlag", "allFlags", "getFlag", "next", "getArg", "parseArgs", "flagsWithValues", "inlineFlag", "aliasCommand", "args", "env", "k", "v", "lines", "arg", "eq", "val", "name", "unaliasCommand", "ifFlag", "path", "PROTECTED_PREFIXES", "resolvePath", "cwd", "inputPath", "isProtectedPath", "targetPath", "normalized", "PROTECTED_PREFIXES", "prefix", "assertPathAccess", "authUser", "operation", "stripUrlFilename", "url", "lastPart", "levenshtein", "a", "b", "dp", "i", "j", "cost", "resolveReadablePath", "vfs", "cwd", "inputPath", "exactPath", "resolvePath", "parent", "fileName", "siblings", "caseInsensitive", "name", "near", "joinListWithType", "items", "statAt", "childPath", "getPackageManager", "shell", "aptCommand", "args", "shell", "authUser", "pm", "getPackageManager", "sub", "rest", "quiet", "ifFlag", "purge", "pkgs", "a", "output", "exitCode", "term", "results", "p", "name", "info", "pkgList", "aptCacheCommand", "pkgName", "def", "inst", "awkCommand", "args", "stdin", "sep", "getFlag", "prog", "a", "printMatch", "fields", "f", "line", "parts", "n", "base64Command", "args", "stdin", "decode", "ifFlag", "input", "catCommand", "authUser", "shell", "cwd", "args", "stdin", "numberAll", "ifFlag", "numberNonBlank", "fileArgs", "a", "parts", "fileArg", "target", "resolveReadablePath", "assertPathAccess", "combined", "lineNum", "line", "cdCommand", "authUser", "shell", "cwd", "args", "mode", "target", "resolvePath", "assertPathAccess", "applySymbolicMode", "existing", "modeStr", "pattern", "parts", "mode", "part", "m", "who", "op", "perms", "targets", "bits", "t", "p", "bit", "mask", "a", "b", "chmodCommand", "authUser", "shell", "cwd", "args", "modeArg", "fileArg", "filePath", "resolvePath", "assertPathAccess", "octal", "result", "err", "clearCommand", "cpCommand", "authUser", "shell", "cwd", "args", "recursive", "ifFlag", "positionals", "a", "srcArg", "destArg", "srcPath", "resolvePath", "destPath", "assertPathAccess", "copyDir", "from", "to", "entry", "fromEntry", "toEntry", "content", "finalDest", "err", "curlCommand", "authUser", "cwd", "args", "shell", "flagsWithValues", "positionals", "parseArgs", "ifFlag", "url", "outputPath", "method", "postData", "headerRaw", "silent", "headOnly", "followRedirects", "verbose", "extraHeaders", "idx", "finalMethod", "fetchOpts", "stderrLines", "response", "err", "lines", "k", "v", "body", "target", "resolvePath", "assertPathAccess", "cutCommand", "args", "stdin", "delim", "getFlag", "cols", "f", "a", "b", "line", "parts", "selected", "col", "i", "dateCommand", "args", "now", "fmt", "declareCommand", "args", "env", "integer", "ifFlag", "_readonly", "_export_", "k", "v", "assignments", "token", "eq", "name", "val", "n", "deluserCommand", "authUser", "args", "shell", "username", "dfCommand", "shell", "used", "total", "avail", "pct", "hdr", "row", "diffCommand", "shell", "cwd", "args", "f1", "f2", "p1", "resolvePath", "p2", "b", "out", "max", "i", "la", "lb", "dpkgCommand", "args", "authUser", "shell", "pm", "getPackageManager", "listFlag", "ifFlag", "statusFlag", "listFilesFlag", "removeFlag", "purgeFlag", "positionals", "parseArgs", "pkgList", "header", "rows", "p", "name", "ver", "arch", "desc", "pkgName", "info", "installed", "output", "exitCode", "dpkgQueryCommand", "showFlag", "pattern", "filtered", "duCommand", "shell", "cwd", "args", "human", "ifFlag", "summary", "target", "a", "p", "resolvePath", "fmt", "b", "lines", "walk", "dir", "rel", "total", "e", "full", "r", "st", "evalArith", "expr", "env", "substituted", "_", "name", "val", "result", "outsideSingleQuotes", "input", "replacer", "parts", "i", "sqIdx", "closeIdx", "expandSync", "lastExit", "home", "homePath", "chunk", "s", "pre", "post", "def", "alt", "expandAsync", "runCmd", "inSingle", "ch", "depth", "j", "sub", "out", "expandEscapes", "text", "_", "oct", "echoCommand", "args", "stdin", "env", "flags", "positionals", "parseArgs", "noNewline", "escapes", "rawText", "expanded", "expandSync", "envCommand", "env", "authUser", "vars", "k", "v", "exitCommand", "args", "exportCommand", "args", "env", "k", "v", "arg", "eq", "name", "value", "findCommand", "authUser", "shell", "cwd", "args", "namePattern", "getFlag", "typeFilter", "rootArg", "a", "rootPath", "resolvePath", "assertPathAccess", "err", "nameRegex", "results", "walk", "currentPath", "display", "stat", "matchesType", "matchesName", "entry", "full", "disp", "os", "freeCommand", "args", "human", "ifFlag", "mb", "gb", "osTotalB", "osFreeB", "usedB", "sharedB", "buffersB", "availableB", "swapB", "fmt", "bytes", "header", "memRow", "swapRow", "grepCommand", "authUser", "shell", "cwd", "args", "stdin", "flags", "positionals", "parseArgs", "caseInsensitive", "invertMatch", "showLineNumbers", "recursive", "pattern", "files", "regex", "regexFlags", "matchLines", "content", "prefix", "lines", "out", "i", "line", "matches", "lineLabel", "readPaths", "base", "paths", "walk", "dir", "entry", "full", "results", "resolvedPaths", "f", "target", "resolvePath", "p", "file", "filePath", "assertPathAccess", "groupsCommand", "authUser", "shell", "args", "target", "gzipCommand", "shell", "cwd", "args", "file", "p", "resolvePath", "gunzipCommand", "headCommand", "authUser", "shell", "cwd", "args", "stdin", "nArg", "getFlag", "n", "positionals", "a", "take", "content", "results", "file", "filePath", "resolvePath", "assertPathAccess", "CATEGORY_ORDER", "CATEGORY_LABELS", "BOLD", "RESET", "CYAN", "YLW", "DIM", "GREEN", "pad", "s", "n", "formatCmdLine", "mod", "aliases", "renderFull", "modules", "grouped", "cat", "lines", "cats", "c", "mods", "sorted", "a", "b", "total", "renderDetail", "p", "catLabel", "createHelpCommand", "_getNames", "args", "getCommandModulesPublic", "target", "m", "historyCommand", "args", "shell", "histPath", "lines", "nArg", "n", "slice", "offset", "line", "i", "hostnameCommand", "hostname", "htopCommand", "mode", "idCommand", "authUser", "shell", "args", "target", "uid", "gid", "groups", "killCommand", "args", "a", "lnCommand", "authUser", "shell", "cwd", "args", "symbolic", "ifFlag", "positionals", "a", "targetArg", "linkArg", "linkPath", "resolvePath", "targetPath", "assertPathAccess", "srcPath", "content", "err", "formatPermissions", "mode", "isDirectory", "fileType", "permissions", "bit", "symbol", "formatDate", "date", "lsCommand", "authUser", "shell", "cwd", "args", "longFormat", "ifFlag", "showHidden", "targetArg", "getArg", "target", "resolvePath", "assertPathAccess", "items", "name", "childPath", "stat", "size", "joinListWithType", "p", "lsbReleaseCommand", "args", "shell", "osName", "codename", "version", "content", "line", "all", "ifFlag", "showId", "showDesc", "showRelease", "showCodename", "lines", "MAN_PAGES", "manCommand", "args", "shell", "name", "manPath", "page", "mkdirCommand", "authUser", "shell", "cwd", "args", "index", "dir", "getArg", "target", "resolvePath", "assertPathAccess", "mvCommand", "authUser", "shell", "cwd", "args", "positionals", "a", "srcArg", "destArg", "srcPath", "resolvePath", "destPath", "assertPathAccess", "finalDest", "err", "path", "nanoCommand", "authUser", "shell", "cwd", "args", "fileArg", "targetPath", "resolvePath", "assertPathAccess", "initialContent", "safeName", "tempPath", "existsSync", "readdirSync", "readFileSync", "os", "path", "formatUptime", "seconds", "totalMinutes", "days", "hours", "minutes", "parts", "colorBlock", "code", "buildColorBars", "normal", "bright", "colorizeLogoLine", "line", "index", "total", "start", "end", "ratio", "r", "g", "b", "colorizeDetailLine", "colonIndex", "applyHorizontalGradient", "title", "value", "text", "ansiRegex", "cleaned", "result", "i", "toMiB", "bytes", "readOsPrettyName", "data", "readFirstLine", "filePath", "resolveHostLabel", "fallback", "vendor", "product", "countDpkgPackages", "candidates", "countSnapPackages", "dirPath", "entry", "resolvePackagesLabel", "dpkgCount", "snapCount", "resolveCpuLabel", "cpus", "first", "ghz", "resolveShellLabel", "shell", "resolveDefaults", "info", "totalMem", "freeMem", "usedMem", "shellProps", "processUptime", "buildNeofetchOutput", "fields", "uptime", "colorBars", "distroLogo", "details", "width", "lines", "rawLeft", "right", "left", "coloredRight", "_globalEnv", "getAllEnvVars", "authUser", "_globalEnv", "setCommand", "args", "env", "k", "v", "arg", "eq", "neofetchCommand", "args", "authUser", "hostname", "shell", "env", "getAllEnvVars", "ifFlag", "buildNeofetchOutput", "vm", "VIRTUAL_VERSION", "VIRTUAL_VERSIONS", "makeContext", "outputLines", "stderrLines", "fakeProcess", "code", "ExitSignal", "fakeConsole", "a", "formatValue", "v", "fakeRequire", "mod", "parts", "p", "b", "d", "id", "vm", "k", "val", "runJs", "ctx", "exitCode", "result", "err", "runJsFile", "trimmed", "nodeCommand", "args", "shell", "cwd", "ifFlag", "eIdx", "expr", "stdout", "stderr", "pIdx", "file", "filePath", "resolvePath", "NPM_VERSION", "NODE_VERSION", "npmCommand", "args", "shell", "ifFlag", "sub", "npxCommand", "passwdCommand", "authUser", "args", "shell", "username", "password", "pingCommand", "args", "flagsWithValues", "positionals", "parseArgs", "host", "countArg", "count", "lines", "i", "ms", "renderPrintf", "fmt", "args", "argIdx", "out", "j", "spec", "arg", "printfCommand", "psCommand", "authUser", "shell", "args", "sessions", "showUser", "ifFlag", "showAll", "rows", "pid", "s", "user", "mem", "vsz", "rss", "pwdCommand", "cwd", "VERSION", "VERSION_INFO", "NONE", "pyDict", "entries", "pyRange", "start", "stop", "step", "isPyDict", "v", "isPyRange", "isPyFunc", "isPyClass", "isPyInstance", "isPyNone", "pyRepr", "k", "val", "pyStr", "pyBool", "pyRangeLength", "n", "pyRangeItems", "items", "i", "pyIter", "PyError", "pyTypeName", "type", "message", "ReturnSignal", "value", "BreakSignal", "ContinueSignal", "ExitSignal", "code", "makeRootScope", "cwd", "scope", "osModule", "makeOsModule", "path", "os", "makeSysModule", "makeMathModule", "makeJsonModule", "makeReModule", "MODULE_FACTORIES", "Interpreter", "s", "args", "depth", "cur", "inStr", "strChar", "ch", "expr", "fMatch", "result", "_", "inner", "bMatch", "compMatch", "itemExpr", "varName", "iterExpr", "condExpr", "iterable", "item", "inner2", "a", "parts", "dict", "entry", "colonIdx", "notMatch", "binaryOps", "ops", "bracketStart", "obj", "key", "callMatch", "name", "argsStr", "callArgs", "dotResult", "objExpr", "attr", "callPart", "argsInner", "part", "open", "close", "attrMatch", "op", "before", "after", "left", "right", "leftExpr", "rightExpr", "l", "arr", "container", "p", "idx", "_scope", "method", "w", "f", "c", "b", "d", "mathFns", "fn", "r", "opts", "indent", "callScope", "fmt", "spec", "base", "iters", "len", "it", "acc", "sortArg1", "keyFn", "ka", "kb", "h", "e", "cls", "inst", "lines", "startIdx", "raw", "bodyLines", "line", "baseIndent", "block", "retMatch", "raiseMatch", "ex", "assertMatch", "delMatch", "importMatch", "modName", "alias", "factory", "mod", "fromMatch", "imports", "defMatch", "fnName", "paramsStr", "params", "body", "classMatch", "className", "basesStr", "bases", "j", "mMatch", "mName", "mParams", "mBody", "cond", "_skip", "bk", "el", "elt", "elifMatch", "eBody", "sl", "sb", "forMatch", "target", "elseBody", "afterIdx", "broken", "targets", "t", "whileMatch", "iterations", "tryBody", "exceptClauses", "finallyBody", "excMatch", "excName", "excAlias", "excBody", "_caughtErr", "handled", "clause", "withMatch", "augMatch", "rhsExpr", "lhs", "rhs", "subAssignMatch", "valExpr", "attrAssignMatch", "dotIdx", "multiAssignMatch", "values", "assignMatch", "python3Command", "shell", "ifFlag", "VERSION", "cIdx", "normalised", "interp", "stdout", "stderr", "exitCode", "file", "filePath", "resolvePath", "readCommand", "args", "stdin", "env", "_promptIdx", "varNames", "i", "input", "line", "ifFlag", "m", "parts", "rmCommand", "authUser", "shell", "cwd", "args", "recursive", "ifFlag", "targets", "index", "target", "getArg", "resolvedTarget", "resolvePath", "assertPathAccess", "sedCommand", "authUser", "shell", "cwd", "args", "stdin", "inPlace", "ifFlag", "expr", "getFlag", "a", "fileArg", "content", "p", "resolvePath", "sMatch", "from", "to", "flags", "regexFlags", "regex", "result", "expandVars", "line", "env", "lastExit", "ctx", "expandAsync", "sub", "runCommand", "r", "parseBlocks", "lines", "blocks", "i", "cond", "thenLines", "elifBlocks", "elseLines", "section", "elifCond", "l", "m", "body", "evalCondition", "expanded", "testMatch", "expr", "fTest", "flag", "arg", "p", "resolvePath", "cmpMatch", "a", "op", "b", "numMatch", "na", "nb", "runBlocks", "lastResult", "output", "block", "assignRe", "tokens", "t", "tok", "ran", "elif", "items", "item", "iterations", "shCommand", "args", "shell", "cwd", "ifFlag", "script", "fileArg", "shiftCommand", "args", "env", "n", "argv", "shifted", "i", "trapCommand", "action", "signals", "sig", "returnCommand", "code", "sleepCommand", "args", "secs", "r", "sortCommand", "authUser", "shell", "cwd", "args", "stdin", "reverse", "ifFlag", "numeric", "unique", "files", "a", "sorted", "f", "assertPathAccess", "resolvePath", "b", "result", "sourceCommand", "args", "authUser", "hostname", "cwd", "shell", "env", "fileArg", "filePath", "resolvePath", "content", "lastExitCode", "line", "l", "result", "runCommand", "suCommand", "authUser", "shell", "args", "users", "targetUser", "getArg", "parseSudoArgs", "args", "flags", "flagsWithValues", "positionals", "parseArgs", "loginShell", "targetUser", "commandLine", "sudoCommand", "authUser", "hostname", "mode", "cwd", "shell", "effectiveUser", "prompt", "runCommand", "tailCommand", "authUser", "shell", "cwd", "args", "stdin", "nArg", "getFlag", "n", "positionals", "a", "take", "content", "lines", "results", "file", "filePath", "resolvePath", "assertPathAccess", "tarCommand", "authUser", "shell", "cwd", "args", "create", "ifFlag", "extract", "list", "fFlag", "a", "archiveName", "archivePath", "resolvePath", "fileArgs", "entries", "f", "p", "walk", "dir", "prefix", "e", "full", "rel", "name", "content", "teeCommand", "authUser", "shell", "cwd", "args", "stdin", "append", "ifFlag", "files", "a", "input", "f", "p", "resolvePath", "existing", "evalTest", "tokens", "shell", "cwd", "andIdx", "orIdx", "flag", "operand", "path", "p", "left", "op", "right", "leftN", "rightN", "testCommand", "args", "touchCommand", "authUser", "shell", "cwd", "args", "file", "target", "resolvePath", "assertPathAccess", "trCommand", "args", "stdin", "del", "ifFlag", "positionals", "set1", "set2", "input", "c", "i", "treeCommand", "authUser", "shell", "cwd", "args", "target", "resolvePath", "getArg", "assertPathAccess", "trueCommand", "falseCommand", "typeCommand", "args", "shell", "env", "pathDirs", "lines", "exitCode", "name", "resolveModule", "found", "dir", "full", "unameCommand", "shell", "args", "all", "ifFlag", "sysname", "release", "machine", "hostname", "uniqCommand", "args", "stdin", "count", "ifFlag", "dupOnly", "uniqOnly", "lines", "out", "i", "j", "n", "line", "unsetCommand", "args", "env", "name", "uptimeCommand", "args", "shell", "pretty", "ifFlag", "since", "uptimeSec", "days", "hours", "mins", "parts", "timeStr", "uptimeStr", "sessions", "load", "wcCommand", "authUser", "shell", "cwd", "args", "stdin", "lines", "ifFlag", "words", "bytes", "showAll", "positionals", "a", "count", "content", "label", "l", "w", "c", "parts", "results", "file", "filePath", "resolvePath", "assertPathAccess", "wgetCommand", "authUser", "cwd", "args", "shell", "flagsWithValues", "positionals", "parseArgs", "ifFlag", "url", "outputArg", "dirPrefix", "quiet", "filename", "stripUrlFilename", "targetPath", "resolvePath", "assertPathAccess", "stderrLines", "response", "err", "msg", "body", "ct", "whichCommand", "args", "shell", "env", "pathDirs", "lines", "anyMissing", "name", "found", "dir", "full", "formatLoginDate", "date", "weekday", "month", "day", "hh", "mm", "ss", "year", "whoCommand", "shell", "session", "loginAt", "displayDate", "formatLoginDate", "whoamiCommand", "authUser", "xargsCommand", "authUser", "hostname", "mode", "cwd", "args", "stdin", "shell", "env", "baseCmd", "extraArgs", "items", "fullCmd", "runCommand", "BASE_COMMANDS", "pwdCommand", "cdCommand", "lsCommand", "treeCommand", "catCommand", "touchCommand", "rmCommand", "mkdirCommand", "cpCommand", "mvCommand", "lnCommand", "chmodCommand", "findCommand", "grepCommand", "sedCommand", "awkCommand", "sortCommand", "uniqCommand", "wcCommand", "headCommand", "tailCommand", "cutCommand", "trCommand", "teeCommand", "xargsCommand", "diffCommand", "tarCommand", "gzipCommand", "gunzipCommand", "base64Command", "whoamiCommand", "whoCommand", "hostnameCommand", "idCommand", "groupsCommand", "unameCommand", "psCommand", "killCommand", "dfCommand", "duCommand", "dateCommand", "sleepCommand", "pingCommand", "echoCommand", "envCommand", "exportCommand", "setCommand", "unsetCommand", "shCommand", "clearCommand", "exitCommand", "nanoCommand", "htopCommand", "curlCommand", "wgetCommand", "adduserCommand", "passwdCommand", "deluserCommand", "sudoCommand", "suCommand", "neofetchCommand", "aptCommand", "aptCacheCommand", "dpkgCommand", "dpkgQueryCommand", "whichCommand", "typeCommand", "manCommand", "aliasCommand", "unaliasCommand", "testCommand", "sourceCommand", "historyCommand", "printfCommand", "readCommand", "declareCommand", "shiftCommand", "trapCommand", "returnCommand", "trueCommand", "falseCommand", "npmCommand", "npxCommand", "nodeCommand", "python3Command", "uptimeCommand", "freeCommand", "lsbReleaseCommand", "customCommands", "commandRegistry", "cachedCommandNames", "helpCommand", "createHelpCommand", "getCommandModules", "cmd", "buildCache", "mod", "alias", "registerCommand", "module", "normalized", "a", "createCustomCommand", "name", "params", "run", "getCommandNames", "getCommandModulesPublic", "resolveModule", "executeStatements", "statements", "authUser", "hostname", "mode", "cwd", "shell", "env", "last", "i", "stmt", "executePipeline", "op", "pipeline", "shellEnv", "executeSingleCommandWithRedirections", "executePipelineChain", "cmd", "stdin", "inputPath", "resolvePath", "result", "runCommandDirect", "outputPath", "output", "existing", "commands", "currentOutput", "exitCode", "parseScript", "rawInput", "trimmed", "parseStatements", "parseStatements", "input", "segments", "splitByLogicalOps", "statements", "seg", "stmt", "parsePipeline", "current", "depth", "inQ", "qChar", "i", "flush", "op", "ch", "ch2", "splitByPipe", "parseCommandWithRedirections", "tokens", "tail", "token", "parts", "tokenizeCommand", "cmdParts", "inputFile", "outputFile", "appendOutput", "part", "next", "tokenizeCommand", "input", "tokens", "current", "inQ", "qChar", "i", "ch", "next", "makeDefaultEnv", "authUser", "hostname", "resolveVfsBinary", "name", "env", "shell", "st", "pathDirs", "dir", "full", "runCommandDirect", "args", "mode", "cwd", "stdin", "aliasVal", "runCommand", "mod", "resolveModule", "vfsBinary", "stubContent", "builtinMatch", "builtinMod", "shMod", "error", "rawInput", "trimmed", "shellEnv", "rawFirstWord", "aliasExpanded", "script", "parseScript", "executeStatements", "expanded", "expandAsync", "sub", "r", "parts", "commandName", "builtinName", "buildLoginBanner", "hostname", "properties", "lastLogin", "lines", "when", "displayed", "formatLoginDate", "line", "buildPrompt", "user", "host", "cwdName", "isRoot", "colorUser", "colorWhite", "colorBlue", "colorReset", "EventEmitter", "os", "ensureDir", "vfs", "path", "mode", "ensureFile", "content", "bootstrapEtc", "hostname", "props", "syncEtcPasswd", "users", "userList", "passwdLines", "uid", "u", "groupLines", "shadowLines", "ttyToPid", "tty", "match", "writeProcPid", "pid", "username", "_tty", "cmdline", "startedAt", "env", "dir", "uptimeSec", "k", "v", "refreshProc", "shellStartTime", "sessions", "totalMemKb", "freeMemKb", "availMemKb", "cpus", "cpuLines", "i", "c", "mhz", "load", "numProcs", "activeSessions", "session", "selfPid", "selfSrc", "entry", "srcPath", "dstPath", "bootstrapSys", "bootstrapDev", "bootstrapUsr", "builtins", "bin", "bootstrapVar", "bootstrapBin", "bootstrapTmp", "bootstrapRoot", "bootstrapMisc", "bootstrapLinuxRootfs", "isTruthyEnv", "value", "nowMs", "isPerfLoggingEnabled", "createPerfLogger", "scope", "enabled", "startedAt", "mark", "label", "elapsedMs", "EventEmitter", "fsSync", "path", "gunzipSync", "gzipSync", "MAGIC", "VERSION", "TYPE_FILE", "TYPE_DIR", "Encoder", "buf", "n", "b", "s", "encoded", "bytes", "encodeNode", "enc", "node", "f", "d", "children", "child", "encodeVfs", "root", "Decoder", "v", "len", "decodeNode", "dec", "type", "name", "mode", "createdAt", "updatedAt", "compressed", "content", "count", "i", "decodeVfs", "isBinarySnapshot", "path", "normalizePath", "rawPath", "normalized", "splitPath", "normalizedPath", "getNode", "root", "targetPath", "parts", "current", "part", "next", "getParentDirectory", "createIfMissing", "createPath", "parentPath", "name", "parentNode", "VirtualFileSystem", "_VirtualFileSystem", "EventEmitter", "options", "name", "mode", "now", "content", "compressed", "targetPath", "normalized", "normalizePath", "parts", "current", "builtPath", "part", "child", "raw", "isBinarySnapshot", "decodeVfs", "snapshot", "err", "dir", "binary", "encodeVfs", "existing", "getNode", "parent", "getParentDirectory", "p", "rawContent", "shouldCompress", "storedContent", "gzipSync", "f", "node", "gunzipSync", "d", "dirPath", "label", "lines", "entries", "i", "isLast", "connector", "nextPrefix", "sub", "l", "total", "linkPath", "normalizedLink", "normalizedTarget", "symNode", "maxDepth", "depth", "target", "fromPath", "toPath", "fromNormalized", "toNormalized", "destParent", "destName", "srcParent", "srcName", "children", "file", "vfs", "snap", "VirtualFileSystem_default", "PACKAGE_REGISTRY", "vfs", "VirtualPackageManager", "users", "status", "blocks", "block", "fields", "name", "pkg", "result", "line", "idx", "msg", "existing", "action", "pkgs", "ts", "entry", "p", "a", "b", "names", "opts", "lines", "toInstall", "notFound", "resolve", "seen", "def", "dep", "n", "totalKb", "acc", "f", "dir", "now", "toRemove", "filePath", "term", "t", "inst", "createHash", "randomBytes", "randomUUID", "scryptSync", "EventEmitter", "path", "resolveFastPasswordHash", "configured", "perf", "createPerfLogger", "VirtualUserManager", "_VirtualUserManager", "EventEmitter", "vfs", "autoSudoForNewUsers", "changed", "username", "maxBytes", "homePath", "targetPath", "nextContent", "quota", "normalizedPath", "normalizeVfsPath", "currentUsage", "existingSize", "existing", "incomingSize", "projectedUsage", "password", "record", "remoteAddress", "session", "randomUUID", "sessionId", "left", "right", "raw", "line", "trimmed", "parts", "salt", "passwordHash", "value", "bytes", "authContent", "sudoersContent", "quotasContent", "content", "mode", "cacheKey", "cached", "randomBytes", "createHash", "scryptSync", "algo", "data", "keys", "normalized", "readFile", "unlink", "writeFile", "path", "spawn", "readFile", "path", "shellQuote", "value", "toTtyLines", "text", "withTerminalSize", "command", "terminalSize", "cols", "rows", "resolvePath", "base", "inputPath", "collectChildPids", "parentPid", "directChildren", "pid", "nested", "getVisibleHtopPidList", "rootPid", "descendants", "unique", "a", "b", "spawnScriptProcess", "command", "terminalSize", "stream", "formatted", "withTerminalSize", "proc", "spawn", "data", "spawnNanoEditorProcess", "tempPath", "shellQuote", "spawnHtopProcess", "pidList", "startShell", "properties", "stream", "authUser", "hostname", "sessionId", "remoteAddress", "terminalSize", "shell", "lineBuffer", "cursorPos", "history", "loadHistory", "historyIndex", "historyDraft", "cwd", "shellEnv", "makeDefaultEnv", "nanoSession", "pendingSudo", "buildCurrentPrompt", "homePath", "cwdLabel", "buildPrompt", "commandNames", "getCommandNames", "bashrcPath", "bashrc", "line", "l", "runCommand", "renderLine", "prompt", "moveLeft", "clearCurrentLine", "startSudoPrompt", "challenge", "finishSudoPrompt", "success", "runCwd", "result", "startNanoEditor", "startHtop", "toTtyLines", "finishNanoEditor", "activeSession", "updatedContent", "readFile", "unlink", "targetPath", "initialContent", "tempPath", "writeFile", "editor", "spawnNanoEditorProcess", "error", "pidList", "getVisibleHtopPidList", "monitor", "spawnHtopProcess", "applyHistoryLine", "nextLine", "insertText", "text", "getTokenRange", "cursor", "start", "end", "listPathCompletions", "prefix", "slashIndex", "dirPart", "namePart", "basePath", "resolvePath", "entry", "fullPath", "suffix", "handleTabCompletion", "token", "commandCandidates", "name", "pathCandidates", "candidates", "completed", "pushHistory", "cmd", "data", "readLastLogin", "lastlogPath", "writeLastLogin", "nowIso", "dir", "renderLoginBanner", "last", "buildLoginBanner", "chunk", "input", "i", "ch", "password", "valid", "next", "third", "fourth", "vfs", "historyPath", "hasVfsInstance", "obj", "isVirtualShellVfsLike", "value", "candidate", "defaultShellProperties", "perf", "createPerfLogger", "resolveAutoSudoForNewUsers", "configured", "VirtualShell", "EventEmitter", "hostname", "properties", "vfsOptionsOrInstance", "VirtualFileSystem_default", "VirtualUserManager", "VirtualPackageManager", "vfs", "users", "pm", "shellProps", "shellHostname", "startTime", "bootstrapLinuxRootfs", "name", "params", "callback", "normalized", "registerCommand", "createCustomCommand", "rawInput", "authUser", "cwd", "runCommand", "stream", "sessionId", "remoteAddress", "terminalSize", "startShell", "refreshProc", "syncEtcPasswd", "targetPath", "content", "hostname", "argv", "readUserArg", "index", "current", "next", "initialUser", "virtualShell", "VirtualShell", "readLastLogin", "username", "lastlogPath", "askQuestion", "rl", "promptText", "resolve", "writeLastLogin", "from", "dir", "runReadlineShell", "createInterface", "stdin", "stdout", "selectedUser", "shellEnv", "makeDefaultEnv", "authUser", "cwd", "remoteAddress", "password", "renderPrompt", "cwdLabel", "basename", "buildPrompt", "prompt", "buildLoginBanner", "inputLine", "line", "result", "runCommand", "error", "promise"]
|
|
4
|
+
"sourcesContent": ["import { basename } from \"node:path\";\nimport { stdin, stdout } from \"node:process\";\nimport { createInterface, type Interface } from \"node:readline\";\n\nimport { makeDefaultEnv, runCommand } from \"./commands/runtime\";\nimport { buildLoginBanner, type LoginBannerState } from \"./SSHMimic/loginBanner\";\nimport { buildPrompt } from \"./SSHMimic/prompt\";\nimport { VirtualShell } from \"./VirtualShell\";\n\nconst hostname = process.env.SSH_MIMIC_HOSTNAME ?? \"typescript-vm\";\nconst argv = process.argv.slice(2);\n\nfunction readUserArg(): string {\n\tfor (let index = 0; index < argv.length; index += 1) {\n\t\tconst current = argv[index];\n\t\tif (current === \"--user\") {\n\t\t\tconst next = argv[index + 1];\n\t\t\tif (!next || next.startsWith(\"--\")) {\n\t\t\t\tthrow new Error(\"self-standalone: --user requires a value\");\n\t\t\t}\n\t\t\treturn next;\n\t\t}\n\t\tif (current?.startsWith(\"--user=\")) {\n\t\t\treturn current.slice(\"--user=\".length) || \"root\";\n\t\t}\n\t}\n\n\treturn \"root\";\n}\n\nconst initialUser = readUserArg();\nconst virtualShell = new VirtualShell(hostname, undefined, {\n\tmode: \"fs\",\n\tsnapshotPath: \".vfs\",\n});\n\nfunction readLastLogin(username: string): LoginBannerState | null {\n\tconst lastlogPath = `/virtual-env-js/.lastlog/${username}.json`;\n\tif (!virtualShell.vfs.exists(lastlogPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\treturn JSON.parse(virtualShell.vfs.readFile(lastlogPath)) as LoginBannerState;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction askQuestion(rl: Interface, promptText: string): Promise<string> {\n\treturn new Promise((resolve) => {\n\t\trl.question(promptText, resolve);\n\t});\n}\n\nfunction writeLastLogin(username: string, from: string): void {\n\tconst dir = \"/virtual-env-js/.lastlog\";\n\tif (!virtualShell.vfs.exists(dir)) {\n\t\tvirtualShell.vfs.mkdir(dir, 0o700);\n\t}\n\n\tvirtualShell.vfs.writeFile(\n\t\t`/virtual-env-js/.lastlog/${username}.json`,\n\t\tJSON.stringify({ at: new Date().toISOString(), from }),\n\t);\n}\n\nvirtualShell.addCommand(\"demo\", [], () => {\n\treturn {\n\t\tstdout: \"This is a demo command. It does nothing useful.\",\n\t\texitCode: 0,\n\t};\n});\n\nasync function runReadlineShell() {\n\tconst rl = createInterface({ input: stdin, output: stdout, terminal: true });\n\tawait virtualShell.ensureInitialized();\n\n\tconst selectedUser = initialUser.trim() || \"root\";\n\tconst userExists = virtualShell.users.getPasswordHash(selectedUser) !== null;\n\tif (!userExists) {\n\t\tprocess.stderr.write(`self-standalone: user '${selectedUser}' does not exist\\n`);\n\t\tprocess.exit(1);\n\t}\n\n\tconst shellEnv = makeDefaultEnv(selectedUser, hostname);\n\tlet authUser = selectedUser;\n\tlet cwd = `/home/${authUser}`;\n\tshellEnv.vars.PWD = cwd;\n\tconst remoteAddress = \"localhost\";\n\n\tif (process.env.USER !== \"root\" && virtualShell.users.hasPassword(authUser)) {\n\t\tconst password = await askQuestion(rl, `Password for ${authUser}: `);\n\t\tif (!virtualShell.users.verifyPassword(authUser, password)) {\n\t\t\tprocess.stderr.write(\"self-standalone: authentication failed\\n\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tconst renderPrompt = (): string => {\n\t\tconst cwdLabel = cwd === `/home/${authUser}` ? \"~\" : basename(cwd) || \"/\";\n\t\treturn buildPrompt(authUser, hostname, cwdLabel);\n\t};\n\n\tconst prompt = (): void => {\n\t\trl.setPrompt(renderPrompt());\n\t\trl.prompt();\n\t};\n\n\trl.on(\"SIGINT\", () => {\n\t\tstdout.write(\"^C\\n\");\n\t\trl.write(\"\", { ctrl: true, name: \"u\" });\n\t\tprompt();\n\t});\n\n\trl.on(\"close\", () => {\n\t\tconsole.log(\"\")\n\t\tprocess.exit(0);\n\t});\n\n\tstdout.write(buildLoginBanner(hostname, virtualShell.properties, readLastLogin(authUser)));\n\twriteLastLogin(authUser, remoteAddress);\n\tprompt();\n\n\twhile (true) {\n\t\tconst inputLine = await new Promise<string>((resolve) => {\n\t\t\trl.once(\"line\", (line) => resolve(line));\n\t\t});\n\n\t\trl.pause();\n\n\t\tconst result = await runCommand(inputLine, authUser, hostname, \"shell\", cwd, virtualShell, undefined, shellEnv);\n\n\t\tif (result.stdout) {\n\t\t\tstdout.write(result.stdout.endsWith(\"\\n\") ? result.stdout : `${result.stdout}\\n`);\n\t\t}\n\n\t\tif (result.stderr) {\n\t\t\tprocess.stderr.write(result.stderr.endsWith(\"\\n\") ? result.stderr : `${result.stderr}\\n`);\n\t\t}\n\n\t\tif (result.clearScreen) {\n\t\t\tstdout.write(\"\\u001b[2J\\u001b[H\");\n\t\t}\n\n\t\tif (result.switchUser) {\n\t\t\tauthUser = result.switchUser;\n\t\t\tcwd = result.nextCwd ?? `/home/${authUser}`;\n\t\t\tshellEnv.vars.USER = authUser;\n\t\t\tshellEnv.vars.LOGNAME = authUser;\n\t\t\tshellEnv.vars.HOME = `/home/${authUser}`;\n\t\t\tshellEnv.vars.PWD = cwd;\n\t\t} else if (result.nextCwd) {\n\t\t\tcwd = result.nextCwd;\n\t\t\tshellEnv.vars.PWD = cwd;\n\t\t}\n\n\t\tif (result.closeSession) {\n\t\t\trl.close();\n\t\t\tprocess.exit(result.exitCode ?? 0);\n\t\t}\n\n\t\tprompt();\n\t\trl.resume();\n\t}\n}\n\nrunReadlineShell().catch((error: unknown) => {\n\tconsole.error(\"Failed to start readline SSH emulation:\", error);\n\tprocess.exit(1);\n});\n\nprocess.on(\"uncaughtException\", (error) => {\n\tconsole.log(\"Oh my god, something terrible happened: \", error);\n});\n\nprocess.on(\"unhandledRejection\", (error, promise) => {\n\tconsole.log(\n\t\t\" Oh Lord! We forgot to handle a promise rejection here: \",\n\t\tpromise,\n\t);\n\tconsole.log(\" The error was: \", error);\n});\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Add a new user to the virtual user database.\n * @category users\n * @params [\"<username> <password>\"]\n * @returns ShellModule\n */\nexport const adduserCommand: ShellModule = {\n\tname: \"adduser\",\n\tdescription: \"Add a new user\",\n\tcategory: \"users\",\n\tparams: [\"<username> <password>\"],\n\trun: async ({ authUser, shell, args }) => {\n\t\tif (authUser !== \"root\") {\n\t\t\treturn { stderr: \"adduser: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tconst [username, password] = args;\n\t\tif (!username || !password) {\n\t\t\treturn {\n\t\t\t\tstderr: \"adduser: usage: adduser <username> <password>\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\n\t\tawait shell.users.addUser(username, password);\n\t\treturn { stdout: `adduser: user '${username}' created`, exitCode: 0 };\n\t},\n};\n", "type ArgParseOptions = {\n\tflags?: string[];\n\tflagsWithValue?: string[];\n};\n\nfunction toFlagList(flags: string | string[]): string[] {\n\treturn Array.isArray(flags) ? flags : [flags];\n}\n\nfunction matchFlagToken(\n\ttoken: string,\n\tflag: string,\n): { matched: boolean; inlineValue: string | null } {\n\tif (token === flag) {\n\t\treturn { matched: true, inlineValue: null };\n\t}\n\n\tconst prefix = `${flag}=`;\n\tif (token.startsWith(prefix)) {\n\t\treturn { matched: true, inlineValue: token.slice(prefix.length) };\n\t}\n\n\treturn { matched: false, inlineValue: null };\n}\n\nfunction collectPositionals(\n\targs: string[],\n\toptions: ArgParseOptions = {},\n): string[] {\n\tconst boolFlags = new Set(options.flags ?? []);\n\tconst valueFlags = new Set(options.flagsWithValue ?? []);\n\tconst positionals: string[] = [];\n\tlet passthrough = false;\n\n\tfor (let index = 0; index < args.length; index += 1) {\n\t\tconst arg = args[index]!;\n\n\t\tif (passthrough) {\n\t\t\tpositionals.push(arg);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--\") {\n\t\t\tpassthrough = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet consumed = false;\n\n\t\tfor (const flag of boolFlags) {\n\t\t\tconst { matched } = matchFlagToken(arg, flag);\n\t\t\tif (matched) {\n\t\t\t\tconsumed = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (consumed) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const flag of valueFlags) {\n\t\t\tconst match = matchFlagToken(arg, flag);\n\t\t\tif (!match.matched) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconsumed = true;\n\t\t\tif (match.inlineValue === null && index + 1 < args.length) {\n\t\t\t\tindex += 1;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!consumed) {\n\t\t\tpositionals.push(arg);\n\t\t}\n\t}\n\n\treturn positionals;\n}\n\n/**\n * Returns `true` when any of the given flags appear in `args`.\n *\n * Matches both standalone tokens (`-s`, `--silent`) and inline forms\n * (`--output=file`). Useful for simple boolean flag checks inside command\n * `run` handlers.\n *\n * @param args Tokenized argument array from `CommandContext.args`.\n * @param flags Single flag string or array of equivalent flag strings.\n * @returns `true` if at least one flag is present, otherwise `false`.\n *\n * @example\n * ```ts\n * ifFlag(args, \"-r\") // single flag\n * ifFlag(args, [\"-r\", \"--recursive\"]) // aliases\n * ```\n */\nexport function ifFlag(args: string[], flags: string | string[]): boolean {\n\tconst allFlags = toFlagList(flags);\n\n\tfor (const arg of args) {\n\t\tfor (const flag of allFlags) {\n\t\t\tif (matchFlagToken(arg, flag).matched) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Returns the value associated with a flag, or `true` if the flag is present\n * but has no associated value, or `undefined` if the flag is absent.\n *\n * Handles three forms:\n * - `--output file` \u2192 returns `\"file\"` (next token)\n * - `--output=file` \u2192 returns `\"file\"` (inline `=` form)\n * - `--verbose` \u2192 returns `true` (flag with no value)\n *\n * @param args Tokenized argument array from `CommandContext.args`.\n * @param flags Single flag string or array of equivalent flag strings.\n * @returns The flag value string, `true` when valueless, or `undefined`.\n *\n * @example\n * ```ts\n * const output = getFlag(args, [\"-o\", \"--output\"]);\n * if (typeof output === \"string\") { /* use path *\\/ }\n * ```\n */\nexport function getFlag(\n\targs: string[],\n\tflags: string | string[],\n): string | true | undefined {\n\tconst allFlags = toFlagList(flags);\n\n\tfor (let index = 0; index < args.length; index += 1) {\n\t\tconst arg = args[index]!;\n\n\t\tfor (const flag of allFlags) {\n\t\t\tconst match = matchFlagToken(arg, flag);\n\t\t\tif (!match.matched) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (match.inlineValue !== null) {\n\t\t\t\treturn match.inlineValue;\n\t\t\t}\n\n\t\t\tconst next = args[index + 1];\n\t\t\tif (next !== undefined && next !== \"--\") {\n\t\t\t\treturn next;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Returns the positional argument at the given zero-based index, skipping\n * known flags and their values.\n *\n * Flags declared in `options.flags` are treated as boolean and skipped.\n * Flags declared in `options.flagsWithValue` consume the next token too.\n * Tokens after `--` are always treated as positionals.\n *\n * @param args Tokenized argument array from `CommandContext.args`.\n * @param index Zero-based positional index to retrieve.\n * @param options Optional flag declarations to skip during positional collection.\n * @returns The positional value, or `undefined` if the index is out of range.\n *\n * @example\n * ```ts\n * // args = [\"-r\", \"src\", \"dest\"]\n * getArg(args, 0, { flags: [\"-r\"] }) // \"src\"\n * getArg(args, 1, { flags: [\"-r\"] }) // \"dest\"\n * ```\n */\nexport function getArg(\n\targs: string[],\n\tindex: number,\n\toptions: ArgParseOptions = {},\n): string | undefined {\n\tconst positionals = collectPositionals(args, options);\n\treturn positionals[index];\n}\n\n/**\n * Parses an argument array into structured flags, flag values, and positionals.\n *\n * - `options.flags` \u2014 boolean flags (e.g. `[\"-r\", \"--recursive\"]`); collected\n * into a `Set<string>` and not treated as positionals.\n * - `options.flagsWithValue` \u2014 flags that consume the next token or an inline\n * `=value`; collected into a `Map<string, string>`.\n * - All remaining tokens are positionals.\n * - Tokens after `--` are always positionals, regardless of `-` prefix.\n *\n * @param args Tokenized argument array from `CommandContext.args`.\n * @param options Flag declaration lists.\n * @returns `{ flags, flagsWithValues, positionals }`.\n *\n * @example\n * ```ts\n * const { flags, flagsWithValues, positionals } = parseArgs(args, {\n * flags: [\"-r\", \"--recursive\"],\n * flagsWithValue: [\"-o\", \"--output\"],\n * });\n * const recursive = flags.has(\"-r\");\n * const output = flagsWithValues.get(\"-o\");\n * ```\n */\nexport function parseArgs(\n\targs: string[],\n\toptions: { flags?: string[]; flagsWithValue?: string[] } = {},\n): {\n\tflags: Set<string>;\n\tflagsWithValues: Map<string, string>;\n\tpositionals: string[];\n} {\n\tconst flags = new Set<string>();\n\tconst flagsWithValues = new Map<string, string>();\n\tconst positionals: string[] = [];\n\tconst boolFlags = new Set(options.flags ?? []);\n\tconst valueFlags = new Set(options.flagsWithValue ?? []);\n\tlet passthrough = false;\n\n\tfor (let index = 0; index < args.length; index += 1) {\n\t\tconst arg = args[index]!;\n\n\t\tif (passthrough) {\n\t\t\tpositionals.push(arg);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (arg === \"--\") {\n\t\t\tpassthrough = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (boolFlags.has(arg)) {\n\t\t\tflags.add(arg);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (valueFlags.has(arg)) {\n\t\t\tconst next = args[index + 1];\n\t\t\tif (next && !next.startsWith(\"-\")) {\n\t\t\t\tflagsWithValues.set(arg, next);\n\t\t\t\tindex += 1;\n\t\t\t} else {\n\t\t\t\tflagsWithValues.set(arg, \"\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst inlineFlag = Array.from(valueFlags).find((flag) =>\n\t\t\targ.startsWith(`${flag}=`),\n\t\t);\n\t\tif (inlineFlag) {\n\t\t\tflagsWithValues.set(inlineFlag, arg.slice(inlineFlag.length + 1));\n\t\t\tcontinue;\n\t\t}\n\n\t\tpositionals.push(arg);\n\t}\n\n\treturn { flags, flagsWithValues, positionals };\n}\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n/**\n * Manage shell aliases (list / set / remove).\n * @category shell\n * @params [\"[name[=value] ...]\"]\n */\nexport const aliasCommand: ShellModule = {\n\tname: \"alias\",\n\tdescription: \"Define or display aliases\",\n\tcategory: \"shell\",\n\tparams: [\"[name[=value] ...]\"],\n\trun: ({ args, env }) => {\n\t\tif (!env) return { exitCode: 0 };\n\n\t\t// Aliases stored in env.vars under prefix __alias_\n\t\tif (args.length === 0) {\n\t\t\tconst aliases = Object.entries(env.vars)\n\t\t\t\t.filter(([k]) => k.startsWith(\"__alias_\"))\n\t\t\t\t.map(([k, v]) => `alias ${k.slice(\"__alias_\".length)}='${v}'`);\n\t\t\treturn { stdout: aliases.join(\"\\n\") || \"\", exitCode: 0 };\n\t\t}\n\n\t\tconst lines: string[] = [];\n\t\tfor (const arg of args) {\n\t\t\tconst eq = arg.indexOf(\"=\");\n\t\t\tif (eq === -1) {\n\t\t\t\t// Display single alias\n\t\t\t\tconst val = env.vars[`__alias_${arg}`];\n\t\t\t\tif (val) lines.push(`alias ${arg}='${val}'`);\n\t\t\t\telse return { stderr: `alias: ${arg}: not found`, exitCode: 1 };\n\t\t\t} else {\n\t\t\t\t// Set alias\n\t\t\t\tconst name = arg.slice(0, eq);\n\t\t\t\tconst val = arg.slice(eq + 1).replace(/^['\"]|['\"]$/g, \"\");\n\t\t\t\tenv.vars[`__alias_${name}`] = val;\n\t\t\t}\n\t\t}\n\n\t\treturn { stdout: lines.join(\"\\n\") || undefined, exitCode: 0 };\n\t},\n};\n\nexport const unaliasCommand: ShellModule = {\n\tname: \"unalias\",\n\tdescription: \"Remove alias definitions\",\n\tcategory: \"shell\",\n\tparams: [\"<name...> | -a\"],\n\trun: ({ args, env }) => {\n\t\tif (!env) return { exitCode: 0 };\n\n\t\tif (ifFlag(args, [\"-a\"])) {\n\t\t\tfor (const k of Object.keys(env.vars)) {\n\t\t\t\tif (k.startsWith(\"__alias_\")) delete env.vars[k];\n\t\t\t}\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\tfor (const name of args) {\n\t\t\tdelete env.vars[`__alias_${name}`];\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import { spawn } from \"node:child_process\";\nimport * as path from \"node:path\";\nimport type VirtualFileSystem from \"../VirtualFileSystem\";\nimport type { VirtualPackageManager } from \"../VirtualPackageManager\";\nimport type { VirtualShell } from \"../VirtualShell\";\n\nconst PROTECTED_PREFIXES = [\"/virtual-env-js/.auth\"] as const;\n\nfunction normalizeFetchUrl(input: string): string {\n\tif (/^[a-zA-Z][a-zA-Z\\d+\\-.]*:/.test(input)) {\n\t\treturn input;\n\t}\n\n\treturn `http://${input}`;\n}\n\nexport function normalizeTerminalOutput(text: string): string {\n\treturn text\n\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t.replace(/\\r/g, \"\\n\")\n\t\t.replace(/\\t/g, \" \")\n\t\t.split(\"\\n\")\n\t\t.map((line) =>\n\t\t\tline.replace(/^[ \\u00A0]{8,}/, \" \").replace(/[ \\u00A0]{3,}/g, \" \"),\n\t\t)\n\t\t.join(\"\\n\")\n\t\t.replace(/\\n{3,}/g, \"\\n\\n\")\n\t\t.trimEnd();\n}\n\nexport function resolvePath(cwd: string, inputPath: string): string {\n\tif (!inputPath || inputPath.trim() === \"\") {\n\t\treturn cwd;\n\t}\n\treturn inputPath.startsWith(\"/\")\n\t\t? path.posix.normalize(inputPath)\n\t\t: path.posix.normalize(path.posix.join(cwd, inputPath));\n}\n\nfunction isProtectedPath(targetPath: string): boolean {\n\tconst normalized = targetPath.startsWith(\"/\")\n\t\t? path.posix.normalize(targetPath)\n\t\t: path.posix.normalize(`/${targetPath}`);\n\n\treturn PROTECTED_PREFIXES.some(\n\t\t(prefix) => normalized === prefix || normalized.startsWith(`${prefix}/`),\n\t);\n}\n\nexport function assertPathAccess(\n\tauthUser: string,\n\ttargetPath: string,\n\toperation: string,\n): void {\n\tif (authUser === \"root\") {\n\t\treturn;\n\t}\n\n\tif (isProtectedPath(targetPath)) {\n\t\tthrow new Error(`${operation}: permission denied: ${targetPath}`);\n\t}\n}\n\nexport function stripUrlFilename(url: string): string {\n\tconst cleaned = url.split(\"?\")[0]?.split(\"#\")[0] ?? url;\n\tconst lastPart = cleaned.split(\"/\").filter(Boolean).pop();\n\treturn lastPart && lastPart.length > 0 ? lastPart : \"index.html\";\n}\n\nexport async function fetchResource(\n\turl: string,\n): Promise<{ text: string; status: number; contentType: string | null }> {\n\tconst response = await fetch(normalizeFetchUrl(url));\n\tconst contentType = response.headers.get(\"content-type\");\n\treturn {\n\t\ttext: await response.text(),\n\t\tstatus: response.status,\n\t\tcontentType,\n\t};\n}\n\n/**\n * Run a host command like curl or wget and capture its output.\n * @param binary - The binary to execute (e.g., \"curl\", \"wget\").\n * @param args - Arguments to pass to the binary.\n * @returns Promise resolving with stdout, stderr, and exit code.\n */\nexport function runHostCommand(\n\tbinary: string,\n\targs: string[],\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n\treturn new Promise((resolve) => {\n\t\tlet childProcess: ReturnType<typeof spawn>;\n\n\t\ttry {\n\t\t\tchildProcess = spawn(binary, args, {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tresolve({\n\t\t\t\tstdout: \"\",\n\t\t\t\tstderr: `${binary}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\texitCode: 1,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tlet stdout = \"\";\n\t\tlet stderr = \"\";\n\t\tconst stdoutStream = childProcess.stdout;\n\t\tconst stderrStream = childProcess.stderr;\n\n\t\tif (!stdoutStream || !stderrStream) {\n\t\t\tresolve({\n\t\t\t\tstdout: \"\",\n\t\t\t\tstderr: `${binary}: failed to capture process output`,\n\t\t\t\texitCode: 1,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tstdoutStream.setEncoding(\"utf8\");\n\t\tstderrStream.setEncoding(\"utf8\");\n\n\t\tstdoutStream.on(\"data\", (chunk: string) => {\n\t\t\tstdout += chunk;\n\t\t});\n\n\t\tstderrStream.on(\"data\", (chunk: string) => {\n\t\t\tstderr += chunk;\n\t\t});\n\n\t\tchildProcess.on(\"error\", (error) => {\n\t\t\tconst errorCode =\n\t\t\t\terror instanceof Error && \"code\" in error\n\t\t\t\t\t? String((error as NodeJS.ErrnoException).code ?? \"\")\n\t\t\t\t\t: \"\";\n\t\t\tresolve({\n\t\t\t\tstdout: \"\",\n\t\t\t\tstderr: `${binary}: ${error.message}`,\n\t\t\t\texitCode: errorCode === \"ENOENT\" ? 127 : 1,\n\t\t\t});\n\t\t});\n\n\t\tchildProcess.on(\"close\", (code) => {\n\t\t\tresolve({\n\t\t\t\tstdout,\n\t\t\t\tstderr,\n\t\t\t\texitCode: code ?? 1,\n\t\t\t});\n\t\t});\n\t});\n}\n\nfunction levenshtein(a: string, b: string): number {\n\tconst dp: number[][] = Array.from({ length: a.length + 1 }, () =>\n\t\tArray<number>(b.length + 1).fill(0),\n\t);\n\n\tfor (let i = 0; i <= a.length; i += 1) {\n\t\tdp[i]![0] = i;\n\t}\n\tfor (let j = 0; j <= b.length; j += 1) {\n\t\tdp[0]![j] = j;\n\t}\n\n\tfor (let i = 1; i <= a.length; i += 1) {\n\t\tfor (let j = 1; j <= b.length; j += 1) {\n\t\t\tconst cost = a[i - 1] === b[j - 1] ? 0 : 1;\n\t\t\tdp[i]![j] = Math.min(\n\t\t\t\tdp[i - 1]![j]! + 1,\n\t\t\t\tdp[i]![j - 1]! + 1,\n\t\t\t\tdp[i - 1]![j - 1]! + cost,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn dp[a.length]![b.length]!;\n}\n\nexport function resolveReadablePath(\n\tvfs: VirtualFileSystem,\n\tcwd: string,\n\tinputPath: string,\n): string {\n\tconst exactPath = resolvePath(cwd, inputPath);\n\tif (vfs.exists(exactPath)) {\n\t\treturn exactPath;\n\t}\n\n\tconst parent = path.posix.dirname(exactPath);\n\tconst fileName = path.posix.basename(exactPath);\n\tconst siblings = vfs.list(parent);\n\n\tconst caseInsensitive = siblings.filter(\n\t\t(name) => name.toLowerCase() === fileName.toLowerCase(),\n\t);\n\tif (caseInsensitive.length === 1) {\n\t\treturn path.posix.join(parent, caseInsensitive[0]!);\n\t}\n\n\tconst near = siblings.filter(\n\t\t(name) => levenshtein(name.toLowerCase(), fileName.toLowerCase()) <= 1,\n\t);\n\tif (near.length === 1) {\n\t\treturn path.posix.join(parent, near[0]!);\n\t}\n\n\treturn exactPath;\n}\n\nexport function joinListWithType(\n\tcwd: string,\n\titems: string[],\n\tstatAt: (p: string) => { type: \"file\" | \"directory\" },\n): string {\n\treturn items\n\t\t.map((name) => {\n\t\t\tconst childPath = resolvePath(cwd, name);\n\t\t\tconst stats = statAt(childPath);\n\t\t\treturn stats.type === \"directory\" ? `${name}/` : name;\n\t\t})\n\t\t.join(\" \");\n}\n\nexport function getPackageManager(\n\tshell: VirtualShell,\n): VirtualPackageManager | undefined {\n\treturn shell.packageManager;\n}\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { getPackageManager } from \"./helpers\";\n\n/**\n * APT package manager front-end (simulated).\n * @category package\n * @params [\"<install|remove|update|upgrade|search|show|list> [pkg...]\"]\n */\nexport const aptCommand: ShellModule = {\n\tname: \"apt\",\n\taliases: [\"apt-get\"],\n\tdescription: \"Package manager\",\n\tcategory: \"package\",\n\tparams: [\"<install|remove|update|upgrade|search|show|list> [pkg...]\"],\n\trun: ({ args, shell, authUser }) => {\n\t\tconst pm = getPackageManager(shell);\n\t\tif (!pm)\n\t\t\treturn { stderr: \"apt: package manager not initialised\", exitCode: 1 };\n\n\t\tconst sub = args[0]?.toLowerCase();\n\t\tconst rest = args.slice(1);\n\n\t\tconst quiet = ifFlag(rest, [\"-q\", \"--quiet\", \"-qq\"]);\n\t\tconst purge = ifFlag(rest, [\"--purge\"]);\n\t\tconst pkgs = rest.filter((a) => !a.startsWith(\"-\"));\n\n\t\t// Non-root check\n\t\tconst restricted = [\"install\", \"remove\", \"purge\", \"upgrade\", \"update\"];\n\t\tif (restricted.includes(sub ?? \"\") && authUser !== \"root\") {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)\\nE: Unable to acquire the dpkg frontend lock, are you root?\",\n\t\t\t\texitCode: 100,\n\t\t\t};\n\t\t}\n\n\t\tswitch (sub) {\n\t\t\tcase \"install\": {\n\t\t\t\tif (pkgs.length === 0)\n\t\t\t\t\treturn { stderr: \"apt: no packages specified\", exitCode: 1 };\n\t\t\t\tconst { output, exitCode } = pm.install(pkgs, { quiet });\n\t\t\t\treturn { stdout: output || undefined, exitCode };\n\t\t\t}\n\n\t\t\tcase \"remove\":\n\t\t\tcase \"purge\": {\n\t\t\t\tif (pkgs.length === 0)\n\t\t\t\t\treturn { stderr: \"apt: no packages specified\", exitCode: 1 };\n\t\t\t\tconst { output, exitCode } = pm.remove(pkgs, {\n\t\t\t\t\tpurge: sub === \"purge\" || purge,\n\t\t\t\t\tquiet,\n\t\t\t\t});\n\t\t\t\treturn { stdout: output || undefined, exitCode };\n\t\t\t}\n\n\t\t\tcase \"update\": {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t\"Hit:1 fortune://packages.fortune.local aurora InRelease\",\n\t\t\t\t\t\t\"Hit:2 fortune://security.fortune.local aurora-security InRelease\",\n\t\t\t\t\t\t\"Reading package lists... Done\",\n\t\t\t\t\t\t\"Building dependency tree... Done\",\n\t\t\t\t\t\t\"Reading state information... Done\",\n\t\t\t\t\t\t`All packages are up to date.`,\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"upgrade\": {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t\"Reading package lists... Done\",\n\t\t\t\t\t\t\"Building dependency tree... Done\",\n\t\t\t\t\t\t\"Reading state information... Done\",\n\t\t\t\t\t\t\"Calculating upgrade... Done\",\n\t\t\t\t\t\t\"0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.\",\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"search\": {\n\t\t\t\tconst term = pkgs[0];\n\t\t\t\tif (!term)\n\t\t\t\t\treturn { stderr: \"apt: search requires a term\", exitCode: 1 };\n\t\t\t\tconst results = pm.search(term);\n\t\t\t\tif (results.length === 0)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstdout: `Sorting... Done\\nFull Text Search... Done\\n(no results)`,\n\t\t\t\t\t\texitCode: 0,\n\t\t\t\t\t};\n\t\t\t\tconst lines = results.map(\n\t\t\t\t\t(p) =>\n\t\t\t\t\t\t`${p.name}/${p.section ?? \"misc\"} ${p.version} amd64\\n ${p.shortDesc ?? p.description}`,\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\tstdout: `Sorting... Done\\nFull Text Search... Done\\n${lines.join(\"\\n\")}`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"show\": {\n\t\t\t\tconst name = pkgs[0];\n\t\t\t\tif (!name)\n\t\t\t\t\treturn { stderr: \"apt: show requires a package name\", exitCode: 1 };\n\t\t\t\tconst info = pm.show(name);\n\t\t\t\tif (!info)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `N: Unable to locate package ${name}`,\n\t\t\t\t\t\texitCode: 100,\n\t\t\t\t\t};\n\t\t\t\treturn { stdout: info, exitCode: 0 };\n\t\t\t}\n\n\t\t\tcase \"list\": {\n\t\t\t\tconst installedFlag = ifFlag(rest, [\"--installed\"]);\n\t\t\t\tif (installedFlag) {\n\t\t\t\t\tconst pkgList = pm.listInstalled();\n\t\t\t\t\tif (pkgList.length === 0)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tstdout: \"Listing... Done\\n(no packages installed)\",\n\t\t\t\t\t\t\texitCode: 0,\n\t\t\t\t\t\t};\n\t\t\t\t\tconst lines = pkgList.map(\n\t\t\t\t\t\t(p) =>\n\t\t\t\t\t\t\t`${p.name}/${p.section} ${p.version} ${p.architecture} [installed]`,\n\t\t\t\t\t);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstdout: `Listing... Done\\n${lines.join(\"\\n\")}`,\n\t\t\t\t\t\texitCode: 0,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// all available\n\t\t\t\tconst all = pm.listAvailable();\n\t\t\t\tconst lines = all.map(\n\t\t\t\t\t(p) => `${p.name}/${p.section ?? \"misc\"} ${p.version} amd64`,\n\t\t\t\t);\n\t\t\t\treturn { stdout: `Listing... Done\\n${lines.join(\"\\n\")}`, exitCode: 0 };\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t\"Usage: apt [options] command\",\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\"Commands:\",\n\t\t\t\t\t\t\" install <pkg...> Install packages\",\n\t\t\t\t\t\t\" remove <pkg...> Remove packages\",\n\t\t\t\t\t\t\" purge <pkg...> Remove packages and config files\",\n\t\t\t\t\t\t\" update Refresh package index\",\n\t\t\t\t\t\t\" upgrade Upgrade all packages\",\n\t\t\t\t\t\t\" search <term> Search in package descriptions\",\n\t\t\t\t\t\t\" show <pkg> Show package details\",\n\t\t\t\t\t\t\" list [--installed] List packages\",\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t},\n};\n\nexport const aptCacheCommand: ShellModule = {\n\tname: \"apt-cache\",\n\tdescription: \"Query the package cache\",\n\tcategory: \"package\",\n\tparams: [\"<search|show|policy> [pkg]\"],\n\trun: ({ args, shell }) => {\n\t\tconst pm = getPackageManager(shell);\n\t\tif (!pm)\n\t\t\treturn {\n\t\t\t\tstderr: \"apt-cache: package manager not initialised\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\n\t\tconst sub = args[0]?.toLowerCase();\n\t\tconst pkgName = args[1];\n\n\t\tswitch (sub) {\n\t\t\tcase \"search\": {\n\t\t\t\tif (!pkgName) return { stderr: \"Need a search term\", exitCode: 1 };\n\t\t\t\tconst results = pm.search(pkgName);\n\t\t\t\treturn {\n\t\t\t\t\tstdout:\n\t\t\t\t\t\tresults\n\t\t\t\t\t\t\t.map((p) => `${p.name} - ${p.shortDesc ?? p.description}`)\n\t\t\t\t\t\t\t.join(\"\\n\") || \"(no results)\",\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"show\": {\n\t\t\t\tif (!pkgName) return { stderr: \"Need a package name\", exitCode: 1 };\n\t\t\t\tconst info = pm.show(pkgName);\n\t\t\t\treturn info\n\t\t\t\t\t? { stdout: info, exitCode: 0 }\n\t\t\t\t\t: { stderr: `N: Unable to locate package ${pkgName}`, exitCode: 100 };\n\t\t\t}\n\t\t\tcase \"policy\": {\n\t\t\t\tif (!pkgName) return { stderr: \"Need a package name\", exitCode: 1 };\n\t\t\t\tconst def = pm.findInRegistry(pkgName);\n\t\t\t\tif (!def)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `N: Unable to locate package ${pkgName}`,\n\t\t\t\t\t\texitCode: 100,\n\t\t\t\t\t};\n\t\t\t\tconst inst = pm.isInstalled(pkgName);\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t`${pkgName}:`,\n\t\t\t\t\t\t` Installed: ${inst ? def.version : \"(none)\"}`,\n\t\t\t\t\t\t` Candidate: ${def.version}`,\n\t\t\t\t\t\t` Version table:`,\n\t\t\t\t\t\t` ${def.version} 500`,\n\t\t\t\t\t\t` 500 fortune://packages.fortune.local aurora/main amd64 Packages`,\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `apt-cache: unknown command '${sub ?? \"\"}'`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\n\n/**\n * Minimal `awk`-like pattern scanner (supports simple print patterns).\n * @category text\n * @params [\"[-F <sep>] '<program>' [file]\"]\n *\n * Supported program patterns:\n * - `print $N` (e.g. `print $1`, `print $2, $3`, `print $0`)\n * - `{print $N}` (e.g. `{print $1}`, `{print $2, $3}`, `{print $0}`)\n *\n * The field separator can be set with `-F` (default is space, which splits on any whitespace).\n */\nexport const awkCommand: ShellModule = {\n\tname: \"awk\",\n\tdescription: \"Pattern scanning and processing language (minimal)\",\n\tcategory: \"text\",\n\tparams: [\"[-F <sep>] '<program>' [file]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst sep = (getFlag(args, [\"-F\"]) as string | undefined) ?? \" \";\n\t\tconst prog = args.find((a) => !a.startsWith(\"-\") && a !== sep);\n\t\tif (!prog) return { stderr: \"awk: no program\", exitCode: 1 };\n\n\t\t// Only support print $N and {print $N} patterns\n\t\tconst printMatch = prog.match(/^\\{?\\s*print\\s+([^}]+)\\s*\\}?$/);\n\t\tif (!printMatch)\n\t\t\treturn { stderr: `awk: unsupported program: ${prog}`, exitCode: 1 };\n\n\t\tconst fields = printMatch[1]!.split(/\\s*,\\s*/).map((f) => f.trim());\n\t\tconst lines = (stdin ?? \"\").split(\"\\n\").filter(Boolean);\n\t\tconst out = lines.map((line) => {\n\t\t\tconst parts = line.split(sep === \" \" ? /\\s+/ : sep);\n\t\t\treturn fields\n\t\t\t\t.map((f) => {\n\t\t\t\t\tif (f === \"$0\") return line;\n\t\t\t\t\tconst n = parseInt(f.replace(\"$\", \"\"), 10);\n\t\t\t\t\treturn Number.isNaN(n) ? f.replace(/\"/g, \"\") : (parts[n - 1] ?? \"\");\n\t\t\t\t})\n\t\t\t\t.join(sep === \" \" ? \"\\t\" : sep);\n\t\t});\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\n/**\n * Encode or decode base64 data.\n * @category text\n * @params [\"[-d] [file]\"]\n */\nexport const base64Command: ShellModule = {\n\tname: \"base64\",\n\tdescription: \"Encode/decode base64\",\n\tcategory: \"text\",\n\tparams: [\"[-d] [file]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst decode = ifFlag(args, [\"-d\", \"--decode\"]);\n\t\tconst input = stdin ?? \"\";\n\t\tif (decode) {\n\t\t\ttry {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: Buffer.from(input.trim(), \"base64\").toString(\"utf8\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\treturn { stderr: \"base64: invalid input\", exitCode: 1 };\n\t\t\t}\n\t\t}\n\t\treturn { stdout: Buffer.from(input).toString(\"base64\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolveReadablePath } from \"./helpers\";\n\n/**\n * Concatenate and print files to stdout.\n * @category files\n * @params [\"[-n] [-b] <file...>\"]\n */\nexport const catCommand: ShellModule = {\n\tname: \"cat\",\n\tdescription: \"Concatenate and print files\",\n\tcategory: \"files\",\n\tparams: [\"[-n] [-b] <file...>\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst numberAll = ifFlag(args, [\"-n\", \"--number\"]);\n\t\tconst numberNonBlank = ifFlag(args, [\"-b\", \"--number-nonblank\"]);\n\t\tconst fileArgs = args.filter((a) => !a.startsWith(\"-\"));\n\n\t\tif (fileArgs.length === 0 && stdin !== undefined) {\n\t\t\treturn { stdout: stdin, exitCode: 0 };\n\t\t}\n\n\t\tif (fileArgs.length === 0) {\n\t\t\treturn { stderr: \"cat: missing file operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst parts: string[] = [];\n\t\tfor (const fileArg of fileArgs) {\n\t\t\tconst target = resolveReadablePath(shell.vfs, cwd, fileArg);\n\t\t\tassertPathAccess(authUser, target, \"cat\");\n\t\t\tparts.push(shell.vfs.readFile(target));\n\t\t}\n\n\t\tconst combined = parts.join(\"\");\n\n\t\tif (!numberAll && !numberNonBlank) {\n\t\t\treturn { stdout: combined, exitCode: 0 };\n\t\t}\n\n\t\tlet lineNum = 1;\n\t\tconst numbered = combined\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => {\n\t\t\t\tif (numberNonBlank && line.trim() === \"\") return line;\n\t\t\t\treturn `${String(lineNum++).padStart(6)}\\t${line}`;\n\t\t\t})\n\t\t\t.join(\"\\n\");\n\n\t\treturn { stdout: numbered, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Change current working directory.\n * @category navigation\n * @params [\"[path]\"]\n */\nexport const cdCommand: ShellModule = {\n\tname: \"cd\",\n\tdescription: \"Change directory\",\n\tcategory: \"navigation\",\n\tparams: [\"[path]\"],\n\trun: ({ authUser, shell, cwd, args, mode }) => {\n\t\tconst target = resolvePath(cwd, args[0] ?? \"/virtual-env-js\");\n\t\tassertPathAccess(authUser, target, \"cd\");\n\t\tconst stats = shell.vfs.stat(target);\n\t\tif (stats.type !== \"directory\") {\n\t\t\treturn { stderr: `cd: not a directory: ${target}`, exitCode: 1 };\n\t\t}\n\n\t\tif (mode === \"exec\") {\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\treturn { nextCwd: target, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Parse a symbolic chmod mode string (e.g. \"+x\", \"u+x\", \"go-w\", \"a+rx\")\n * and apply it to the existing mode bits.\n * Returns null if the string is not a valid symbolic mode.\n */\nfunction applySymbolicMode(existing: number, modeStr: string): number | null {\n\tconst pattern = /^([ugoa]*)([+\\-=])([rwx]*)$/;\n\tconst parts = modeStr.split(\",\");\n\tlet mode = existing;\n\tfor (const part of parts) {\n\t\tconst m = part.trim().match(pattern);\n\t\tif (!m) return null;\n\t\tconst [, who = \"a\", op, perms = \"\"] = m;\n\t\tconst targets = who === \"\" || who === \"a\" ? [\"u\", \"g\", \"o\"] : who.split(\"\");\n\t\tconst bits: Record<string, Record<string, number>> = {\n\t\t\tu: { r: 0o400, w: 0o200, x: 0o100 },\n\t\t\tg: { r: 0o040, w: 0o020, x: 0o010 },\n\t\t\to: { r: 0o004, w: 0o002, x: 0o001 },\n\t\t};\n\t\tfor (const t of targets) {\n\t\t\tfor (const p of perms.split(\"\")) {\n\t\t\t\tconst bit = bits[t]?.[p];\n\t\t\t\tif (bit === undefined) continue;\n\t\t\t\tif (op === \"+\") mode |= bit;\n\t\t\t\telse if (op === \"-\") mode &= ~bit;\n\t\t\t\telse if (op === \"=\") {\n\t\t\t\t\t// clear all bits for this target, then set requested\n\t\t\t\t\tconst mask = Object.values(bits[t] ?? {}).reduce((a, b) => a | b, 0);\n\t\t\t\t\tmode = (mode & ~mask) | bit;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn mode;\n}\n\n/**\n * Change file permissions (octal or symbolic).\n * @category files\n * @params [\"<mode> <file>\"]\n */\nexport const chmodCommand: ShellModule = {\n\tname: \"chmod\",\n\tdescription: \"Change file permissions\",\n\tcategory: \"files\",\n\tparams: [\"<mode> <file>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst [modeArg, fileArg] = args;\n\t\tif (!modeArg || !fileArg) {\n\t\t\treturn { stderr: \"chmod: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst filePath = resolvePath(cwd, fileArg);\n\t\ttry {\n\t\t\tassertPathAccess(authUser, filePath, \"chmod\");\n\t\t\tif (!shell.vfs.exists(filePath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `chmod: ${fileArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tlet mode: number;\n\t\t\tconst octal = parseInt(modeArg, 8);\n\t\t\tif (!Number.isNaN(octal) && /^[0-7]+$/.test(modeArg)) {\n\t\t\t\tmode = octal;\n\t\t\t} else {\n\t\t\t\t// symbolic mode\n\t\t\t\tconst existing = shell.vfs.stat(filePath).mode;\n\t\t\t\tconst result = applySymbolicMode(existing, modeArg);\n\t\t\t\tif (result === null) {\n\t\t\t\t\treturn { stderr: `chmod: invalid mode: ${modeArg}`, exitCode: 1 };\n\t\t\t\t}\n\t\t\t\tmode = result;\n\t\t\t}\n\t\t\tshell.vfs.chmod(filePath, mode);\n\t\t\treturn { exitCode: 0 };\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `chmod: ${msg}`, exitCode: 1 };\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const clearCommand: ShellModule = {\n\tname: \"clear\",\n\tdescription: \"Clear the terminal screen\",\n\tcategory: \"shell\",\n\tparams: [],\n\t// clearScreen flag triggers \\x1b[2J\\x1b[H in the shell layer\n\trun: () => ({ clearScreen: true, stdout: \"\", exitCode: 0 }),\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Copy files or directories inside the virtual filesystem.\n * @category files\n * @params [\"[-r] <source> <dest>\"]\n */\nexport const cpCommand: ShellModule = {\n\tname: \"cp\",\n\tdescription: \"Copy files or directories\",\n\tcategory: \"files\",\n\tparams: [\"[-r] <source> <dest>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst recursive = ifFlag(args, [\"-r\", \"-R\", \"--recursive\"]);\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst [srcArg, destArg] = positionals;\n\n\t\tif (!srcArg || !destArg) {\n\t\t\treturn { stderr: \"cp: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst srcPath = resolvePath(cwd, srcArg);\n\t\tconst destPath = resolvePath(cwd, destArg);\n\n\t\ttry {\n\t\t\tassertPathAccess(authUser, srcPath, \"cp\");\n\t\t\tassertPathAccess(authUser, destPath, \"cp\");\n\n\t\t\tif (!shell.vfs.exists(srcPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `cp: ${srcArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst srcStat = shell.vfs.stat(srcPath);\n\n\t\t\tif (srcStat.type === \"directory\") {\n\t\t\t\tif (!recursive) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `cp: ${srcArg}: is a directory (use -r)`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst copyDir = (from: string, to: string) => {\n\t\t\t\t\tshell.vfs.mkdir(to, 0o755);\n\t\t\t\t\tfor (const entry of shell.vfs.list(from)) {\n\t\t\t\t\t\tconst fromEntry = `${from}/${entry}`;\n\t\t\t\t\t\tconst toEntry = `${to}/${entry}`;\n\t\t\t\t\t\tconst stat = shell.vfs.stat(fromEntry);\n\t\t\t\t\t\tif (stat.type === \"directory\") {\n\t\t\t\t\t\t\tcopyDir(fromEntry, toEntry);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst content = shell.vfs.readFileRaw(fromEntry);\n\t\t\t\t\t\t\tshell.writeFileAsUser(authUser, toEntry, content);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tconst finalDest =\n\t\t\t\t\tshell.vfs.exists(destPath) &&\n\t\t\t\t\tshell.vfs.stat(destPath).type === \"directory\"\n\t\t\t\t\t\t? `${destPath}/${srcArg.split(\"/\").pop()}`\n\t\t\t\t\t\t: destPath;\n\t\t\t\tcopyDir(srcPath, finalDest);\n\t\t\t} else {\n\t\t\t\tconst finalDest =\n\t\t\t\t\tshell.vfs.exists(destPath) &&\n\t\t\t\t\tshell.vfs.stat(destPath).type === \"directory\"\n\t\t\t\t\t\t? `${destPath}/${srcArg.split(\"/\").pop()}`\n\t\t\t\t\t\t: destPath;\n\t\t\t\tconst content = shell.vfs.readFileRaw(srcPath);\n\t\t\t\tshell.writeFileAsUser(authUser, finalDest, content);\n\t\t\t}\n\n\t\t\treturn { exitCode: 0 };\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `cp: ${msg}`, exitCode: 1 };\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag, parseArgs } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * HTTP client wrapper using `fetch()` semantics (virtual curl).\n * @category network\n * @params [\"[options] <url>\"]\n */\nexport const curlCommand: ShellModule = {\n\tname: \"curl\",\n\tdescription: \"Transfer data from or to a server (pure fetch)\",\n\tcategory: \"network\",\n\tparams: [\"[options] <url>\"],\n\trun: async ({ authUser, cwd, args, shell }) => {\n\t\tconst { flagsWithValues, positionals } = parseArgs(args, {\n\t\t\tflagsWithValue: [\n\t\t\t\t\"-o\",\n\t\t\t\t\"--output\",\n\t\t\t\t\"-X\",\n\t\t\t\t\"--request\",\n\t\t\t\t\"-d\",\n\t\t\t\t\"--data\",\n\t\t\t\t\"-H\",\n\t\t\t\t\"--header\",\n\t\t\t\t\"-u\",\n\t\t\t\t\"--user\",\n\t\t\t],\n\t\t});\n\n\t\tif (ifFlag(args, [\"--help\", \"-h\"])) {\n\t\t\treturn {\n\t\t\t\tstdout: [\n\t\t\t\t\t\"Usage: curl [options] <url>\",\n\t\t\t\t\t\" -o, --output <file> Write to file\",\n\t\t\t\t\t\" -X, --request <method> HTTP method\",\n\t\t\t\t\t\" -d, --data <data> POST data\",\n\t\t\t\t\t\" -H, --header <hdr> Extra header\",\n\t\t\t\t\t\" -s, --silent Silent mode\",\n\t\t\t\t\t\" -I, --head Fetch headers only\",\n\t\t\t\t\t\" -L, --location Follow redirects\",\n\t\t\t\t\t\" -v, --verbose Verbose\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst url = positionals[0];\n\t\tif (!url) return { stderr: \"curl: no URL specified\", exitCode: 1 };\n\n\t\tconst outputPath =\n\t\t\tflagsWithValues.get(\"-o\") ?? flagsWithValues.get(\"--output\") ?? null;\n\t\tconst method = (\n\t\t\tflagsWithValues.get(\"-X\") ??\n\t\t\tflagsWithValues.get(\"--request\") ??\n\t\t\t\"GET\"\n\t\t).toUpperCase();\n\t\tconst postData =\n\t\t\tflagsWithValues.get(\"-d\") ?? flagsWithValues.get(\"--data\") ?? null;\n\t\tconst headerRaw =\n\t\t\tflagsWithValues.get(\"-H\") ?? flagsWithValues.get(\"--header\") ?? null;\n\t\tconst silent = ifFlag(args, [\"-s\", \"--silent\"]);\n\t\tconst headOnly = ifFlag(args, [\"-I\", \"--head\"]);\n\t\tconst followRedirects = ifFlag(args, [\"-L\", \"--location\"]);\n\t\tconst verbose = ifFlag(args, [\"-v\", \"--verbose\"]);\n\n\t\tconst extraHeaders: Record<string, string> = {\n\t\t\t\"User-Agent\": \"curl/7.88.1\",\n\t\t};\n\t\tif (headerRaw) {\n\t\t\tconst idx = headerRaw.indexOf(\":\");\n\t\t\tif (idx !== -1)\n\t\t\t\textraHeaders[headerRaw.slice(0, idx).trim()] = headerRaw\n\t\t\t\t\t.slice(idx + 1)\n\t\t\t\t\t.trim();\n\t\t}\n\n\t\tconst finalMethod = postData && method === \"GET\" ? \"POST\" : method;\n\t\tconst fetchOpts: RequestInit = {\n\t\t\tmethod: finalMethod,\n\t\t\theaders: extraHeaders,\n\t\t\tredirect: followRedirects ? \"follow\" : \"manual\",\n\t\t};\n\t\tif (postData) {\n\t\t\textraHeaders[\"Content-Type\"] ??= \"application/x-www-form-urlencoded\";\n\t\t\tfetchOpts.body = postData;\n\t\t}\n\n\t\tconst stderrLines: string[] = [];\n\t\tif (verbose) {\n\t\t\tstderrLines.push(`* Trying ${url}...`, `* Connected`);\n\t\t\tstderrLines.push(\n\t\t\t\t`> ${finalMethod} / HTTP/1.1`,\n\t\t\t\t`> Host: ${new URL(url).host}`,\n\t\t\t);\n\t\t}\n\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetch(url, fetchOpts);\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn {\n\t\t\t\tstderr: `curl: (6) Could not resolve host: ${msg}`,\n\t\t\t\texitCode: 6,\n\t\t\t};\n\t\t}\n\n\t\tif (verbose) {\n\t\t\tstderrLines.push(`< HTTP/1.1 ${response.status} ${response.statusText}`);\n\t\t}\n\n\t\tif (headOnly) {\n\t\t\tconst lines = [`HTTP/1.1 ${response.status} ${response.statusText}`];\n\t\t\tfor (const [k, v] of response.headers.entries()) lines.push(`${k}: ${v}`);\n\t\t\treturn { stdout: `${lines.join(\"\\r\\n\")}\\r\\n`, exitCode: 0 };\n\t\t}\n\n\t\tlet body: string;\n\t\ttry {\n\t\t\tbody = await response.text();\n\t\t} catch {\n\t\t\treturn { stderr: \"curl: failed to read response body\", exitCode: 1 };\n\t\t}\n\n\t\tif (outputPath) {\n\t\t\tconst target = resolvePath(cwd, outputPath);\n\t\t\tassertPathAccess(authUser, target, \"curl\");\n\t\t\tshell.writeFileAsUser(authUser, target, body);\n\t\t\tif (!silent)\n\t\t\t\tstderrLines.push(\n\t\t\t\t\t` % Total % Received\\n100 ${body.length} 100 ${body.length}`,\n\t\t\t\t);\n\t\t\treturn {\n\t\t\t\tstderr: stderrLines.join(\"\\n\") || undefined,\n\t\t\t\texitCode: response.ok ? 0 : 22,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstdout: body,\n\t\t\tstderr: stderrLines.length > 0 ? stderrLines.join(\"\\n\") : undefined,\n\t\t\texitCode: response.ok ? 0 : 22,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\n\n/**\n * Extract selected fields from each line of input.\n * @category text\n * @params [\"-d <delim> -f <fields> [file]\"]\n */\nexport const cutCommand: ShellModule = {\n\tname: \"cut\",\n\tdescription: \"Remove sections from lines\",\n\tcategory: \"text\",\n\tparams: [\"-d <delim> -f <fields> [file]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst delim = (getFlag(args, [\"-d\"]) as string | undefined) ?? \"\\t\";\n\t\tconst fields = (getFlag(args, [\"-f\"]) as string | undefined) ?? \"1\";\n\t\tconst cols = fields.split(\",\").map((f) => {\n\t\t\tconst [a, b] = f.split(\"-\").map(Number);\n\t\t\treturn b !== undefined\n\t\t\t\t? { from: (a ?? 1) - 1, to: b - 1 }\n\t\t\t\t: { from: (a ?? 1) - 1, to: (a ?? 1) - 1 };\n\t\t});\n\t\tconst lines = (stdin ?? \"\").split(\"\\n\");\n\t\tconst out = lines.map((line) => {\n\t\t\tconst parts = line.split(delim);\n\t\t\tconst selected: string[] = [];\n\t\t\tfor (const col of cols) {\n\t\t\t\tfor (let i = col.from; i <= Math.min(col.to, parts.length - 1); i++) {\n\t\t\t\t\tselected.push(parts[i] ?? \"\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn selected.join(delim);\n\t\t});\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Print the current date/time or a formatted representation.\n * @category system\n * @params [\"[+format]\"]\n */\nexport const dateCommand: ShellModule = {\n\tname: \"date\",\n\tdescription: \"Print current date and time\",\n\tcategory: \"system\",\n\tparams: [\"[+format]\"],\n\trun: ({ args }) => {\n\t\tconst now = new Date();\n\t\tconst fmt = args[0];\n\t\tif (fmt?.startsWith(\"+\")) {\n\t\t\tconst f = fmt\n\t\t\t\t.slice(1)\n\t\t\t\t.replace(\"%Y\", String(now.getFullYear()))\n\t\t\t\t.replace(\"%m\", String(now.getMonth() + 1).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%d\", String(now.getDate()).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%H\", String(now.getHours()).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%M\", String(now.getMinutes()).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%S\", String(now.getSeconds()).padStart(2, \"0\"))\n\t\t\t\t.replace(\"%s\", String(Math.floor(now.getTime() / 1000)));\n\t\t\treturn { stdout: f, exitCode: 0 };\n\t\t}\n\t\treturn { stdout: now.toString(), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const declareCommand: ShellModule = {\n\tname: \"declare\",\n\taliases: [\"local\", \"typeset\"],\n\tdescription: \"Declare variables and give them attributes\",\n\tcategory: \"shell\",\n\tparams: [\"[-i] [-r] [-x] [-a] [name[=value]...]\"],\n\trun: ({ args, env }) => {\n\t\tif (!env) return { exitCode: 0 };\n\n\t\tconst integer = ifFlag(args, [\"-i\"]);\n\t\tconst _readonly = ifFlag(args, [\"-r\"]);\n\t\tconst _export_ = ifFlag(args, [\"-x\"]);\n\t\tconst printAll = args.filter((a) => !a.startsWith(\"-\")).length === 0;\n\n\t\tif (printAll) {\n\t\t\tconst lines = Object.entries(env.vars).map(\n\t\t\t\t([k, v]) => `declare -- ${k}=\"${v}\"`,\n\t\t\t);\n\t\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t\t}\n\n\t\tconst assignments = args.filter((a) => !a.startsWith(\"-\"));\n\t\tfor (const token of assignments) {\n\t\t\tconst eq = token.indexOf(\"=\");\n\t\t\tif (eq === -1) {\n\t\t\t\t// Just declare (no value)\n\t\t\t\tif (!(token in env.vars)) env.vars[token] = \"\";\n\t\t\t} else {\n\t\t\t\tconst name = token.slice(0, eq);\n\t\t\t\tlet val = token.slice(eq + 1);\n\t\t\t\tif (integer) {\n\t\t\t\t\tconst n = parseInt(val, 10);\n\t\t\t\t\tval = Number.isNaN(n) ? \"0\" : String(n);\n\t\t\t\t}\n\t\t\t\tenv.vars[name] = val;\n\t\t\t}\n\t\t}\n\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const deluserCommand: ShellModule = {\n\tname: \"deluser\",\n\tdescription: \"Delete a user\",\n\tcategory: \"users\",\n\tparams: [\"<username>\"],\n\trun: async ({ authUser, args, shell }) => {\n\t\tif (authUser !== \"root\") {\n\t\t\treturn { stderr: \"deluser: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tconst [username] = args;\n\t\tif (!username) {\n\t\t\treturn { stderr: \"deluser: usage: deluser <username>\", exitCode: 1 };\n\t\t}\n\n\t\tawait shell.users.deleteUser(username);\n\t\treturn { stdout: `deluser: user '${username}' deleted`, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const dfCommand: ShellModule = {\n\tname: \"df\",\n\tdescription: \"Report filesystem disk space usage\",\n\tcategory: \"system\",\n\tparams: [\"[-h]\"],\n\trun: ({ shell }) => {\n\t\tconst bytes = shell.vfs.getUsageBytes();\n\t\tconst used = (bytes / 1024).toFixed(0);\n\t\tconst total = \"1048576\"; // 1GB virtual\n\t\tconst avail = String(Number(total) - Number(used));\n\t\tconst pct = Math.round((Number(used) / Number(total)) * 100);\n\t\tconst hdr = \"Filesystem 1K-blocks Used Available Use% Mounted on\";\n\t\tconst row = `virtual-fs ${total.padStart(9)} ${used.padStart(7)} ${avail.padStart(9)} ${pct}% /`;\n\t\treturn { stdout: `${hdr}\\n${row}`, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { resolvePath } from \"./helpers\";\n\n/**\n * Compare files line-by-line and print differing lines.\n * @category text\n * @params [\"<file1> <file2>\"]\n */\nexport const diffCommand: ShellModule = {\n\tname: \"diff\",\n\tdescription: \"Compare files line by line\",\n\tcategory: \"text\",\n\tparams: [\"<file1> <file2>\"],\n\trun: ({ shell, cwd, args }) => {\n\t\tconst [f1, f2] = args;\n\t\tif (!f1 || !f2) return { stderr: \"diff: missing operand\", exitCode: 1 };\n\t\tconst p1 = resolvePath(cwd, f1);\n\t\tconst p2 = resolvePath(cwd, f2);\n\t\tlet a: string[], b: string[];\n\t\ttry {\n\t\t\ta = shell.vfs.readFile(p1).split(\"\\n\");\n\t\t} catch {\n\t\t\treturn { stderr: `diff: ${f1}: No such file or directory`, exitCode: 2 };\n\t\t}\n\t\ttry {\n\t\t\tb = shell.vfs.readFile(p2).split(\"\\n\");\n\t\t} catch {\n\t\t\treturn { stderr: `diff: ${f2}: No such file or directory`, exitCode: 2 };\n\t\t}\n\n\t\tconst out: string[] = [];\n\t\tconst max = Math.max(a.length, b.length);\n\t\tfor (let i = 0; i < max; i++) {\n\t\t\tconst la = a[i];\n\t\t\tconst lb = b[i];\n\t\t\tif (la !== lb) {\n\t\t\t\tif (la !== undefined) out.push(`< ${la}`);\n\t\t\t\tif (lb !== undefined) out.push(`> ${lb}`);\n\t\t\t}\n\t\t}\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: out.length > 0 ? 1 : 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag, parseArgs } from \"./command-helpers\";\nimport { getPackageManager } from \"./helpers\";\n\n/**\n * dpkg compatibility command (query/remove/list) backed by the virtual package manager.\n * @category package\n * @params [\"[-l] [-s pkg] [-L pkg] [-i pkg] [--remove pkg]\"]\n */\nexport const dpkgCommand: ShellModule = {\n\tname: \"dpkg\",\n\tdescription: \"Debian package manager low-level tool\",\n\tcategory: \"package\",\n\tparams: [\"[-l] [-s pkg] [-L pkg] [-i pkg] [--remove pkg]\"],\n\trun: ({ args, authUser, shell }) => {\n\t\tconst pm = getPackageManager(shell);\n\t\tif (!pm)\n\t\t\treturn { stderr: \"dpkg: package manager not initialised\", exitCode: 1 };\n\n\t\tconst listFlag = ifFlag(args, [\"-l\", \"--list\"]);\n\t\tconst statusFlag = ifFlag(args, [\"-s\", \"--status\"]);\n\t\tconst listFilesFlag = ifFlag(args, [\"-L\", \"--listfiles\"]);\n\t\tconst removeFlag = ifFlag(args, [\"-r\", \"--remove\"]);\n\t\tconst purgeFlag = ifFlag(args, [\"-P\", \"--purge\"]);\n\n\t\tconst { positionals } = parseArgs(args, {\n\t\t\tflags: [\n\t\t\t\t\"-l\",\n\t\t\t\t\"--list\",\n\t\t\t\t\"-s\",\n\t\t\t\t\"--status\",\n\t\t\t\t\"-L\",\n\t\t\t\t\"--listfiles\",\n\t\t\t\t\"-r\",\n\t\t\t\t\"--remove\",\n\t\t\t\t\"-P\",\n\t\t\t\t\"--purge\",\n\t\t\t],\n\t\t});\n\n\t\tif (listFlag) {\n\t\t\tconst pkgList = pm.listInstalled();\n\t\t\tif (pkgList.length === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: [\n\t\t\t\t\t\t\"Desired=Unknown/Install/Remove/Purge/Hold\",\n\t\t\t\t\t\t\"|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend\",\n\t\t\t\t\t\t\"|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)\",\n\t\t\t\t\t\t\"||/ Name Version Architecture Description\",\n\t\t\t\t\t\t\"+++-==============-===============-============-========================================\",\n\t\t\t\t\t\t\"(no packages installed)\",\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst header = [\n\t\t\t\t\"Desired=Unknown/Install/Remove/Purge/Hold\",\n\t\t\t\t\"|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend\",\n\t\t\t\t\"|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)\",\n\t\t\t\t\"||/ Name Version Architecture Description\",\n\t\t\t\t\"+++-==============-===============-============-========================================\",\n\t\t\t];\n\n\t\t\tconst rows = pkgList.map((p) => {\n\t\t\t\tconst name = p.name.padEnd(14).slice(0, 14);\n\t\t\t\tconst ver = p.version.padEnd(15).slice(0, 15);\n\t\t\t\tconst arch = p.architecture.padEnd(12).slice(0, 12);\n\t\t\t\tconst desc = (p.description || \"\").slice(0, 40);\n\t\t\t\treturn `ii ${name} ${ver} ${arch} ${desc}`;\n\t\t\t});\n\n\t\t\treturn { stdout: [...header, ...rows].join(\"\\n\"), exitCode: 0 };\n\t\t}\n\n\t\tif (statusFlag) {\n\t\t\tconst pkgName = positionals[0];\n\t\t\tif (!pkgName)\n\t\t\t\treturn { stderr: \"dpkg: -s needs a package name\", exitCode: 1 };\n\t\t\tconst info = pm.show(pkgName);\n\t\t\tif (!info)\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `dpkg-query: package '${pkgName}' is not installed and no information is available`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\treturn { stdout: info, exitCode: 0 };\n\t\t}\n\n\t\tif (listFilesFlag) {\n\t\t\tconst pkgName = positionals[0];\n\t\t\tif (!pkgName)\n\t\t\t\treturn { stderr: \"dpkg: -L needs a package name\", exitCode: 1 };\n\t\t\tconst installed = pm.listInstalled().find((p) => p.name === pkgName);\n\t\t\tif (!installed)\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `dpkg-query: package '${pkgName}' is not installed`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\tif (installed.files.length === 0)\n\t\t\t\treturn { stdout: \"/.keep\", exitCode: 0 };\n\t\t\treturn { stdout: installed.files.join(\"\\n\"), exitCode: 0 };\n\t\t}\n\n\t\tif (removeFlag || purgeFlag) {\n\t\t\tif (authUser !== \"root\")\n\t\t\t\treturn {\n\t\t\t\t\tstderr:\n\t\t\t\t\t\t\"dpkg: error: requested operation requires superuser privilege\",\n\t\t\t\t\texitCode: 2,\n\t\t\t\t};\n\t\t\tif (positionals.length === 0)\n\t\t\t\treturn { stderr: \"dpkg: error: need an action option\", exitCode: 2 };\n\t\t\tconst { output, exitCode } = pm.remove(positionals, { purge: purgeFlag });\n\t\t\treturn { stdout: output || undefined, exitCode };\n\t\t}\n\n\t\t// Default: show help\n\t\treturn {\n\t\t\tstdout: [\n\t\t\t\t\"Usage: dpkg [<option>...] <command>\",\n\t\t\t\t\"\",\n\t\t\t\t\"Commands:\",\n\t\t\t\t\" -l, --list List packages matching given pattern\",\n\t\t\t\t\" -s, --status <pkg>... Report status of specified package\",\n\t\t\t\t\" -L, --listfiles <pkg>... List files owned by package\",\n\t\t\t\t\" -r, --remove <pkg>... Remove <pkg> but leave its configuration\",\n\t\t\t\t\" -P, --purge <pkg>... Remove <pkg> and its configuration\",\n\t\t\t].join(\"\\n\"),\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n\nexport const dpkgQueryCommand: ShellModule = {\n\tname: \"dpkg-query\",\n\tdescription: \"Show information about installed packages\",\n\tcategory: \"package\",\n\tparams: [\"-W [pkg] | -l [pattern]\"],\n\trun: ({ args, shell }) => {\n\t\tconst pm = getPackageManager(shell);\n\t\tif (!pm)\n\t\t\treturn {\n\t\t\t\tstderr: \"dpkg-query: package manager not initialised\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\n\t\tconst listFlag = ifFlag(args, [\"-l\"]);\n\t\tconst showFlag = ifFlag(args, [\"-W\", \"--show\"]);\n\t\tconst { positionals } = parseArgs(args, {\n\t\t\tflags: [\"-l\", \"-W\", \"--show\"],\n\t\t});\n\n\t\tif (listFlag || showFlag) {\n\t\t\tconst pkgList = pm.listInstalled();\n\t\t\tconst pattern = positionals[0];\n\t\t\tconst filtered = pattern\n\t\t\t\t? pkgList.filter((p) => p.name.includes(pattern))\n\t\t\t\t: pkgList;\n\n\t\t\tif (showFlag) {\n\t\t\t\treturn {\n\t\t\t\t\tstdout: filtered.map((p) => `${p.name}\\t${p.version}`).join(\"\\n\"),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst rows = filtered.map((p) => {\n\t\t\t\tconst name = p.name.padEnd(14).slice(0, 14);\n\t\t\t\tconst ver = p.version.padEnd(15).slice(0, 15);\n\t\t\t\treturn `ii ${name} ${ver} amd64 ${(p.description || \"\").slice(0, 40)}`;\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tstdout: rows.join(\"\\n\") || \"(no packages match)\",\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\treturn { stderr: \"dpkg-query: need a flag (-l, -W)\", exitCode: 1 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nexport const duCommand: ShellModule = {\n\tname: \"du\",\n\tdescription: \"Estimate file space usage\",\n\tcategory: \"system\",\n\tparams: [\"[-h] [-s] [path]\"],\n\trun: ({ shell, cwd, args }) => {\n\t\tconst human = ifFlag(args, [\"-h\"]);\n\t\tconst summary = ifFlag(args, [\"-s\"]);\n\t\tconst target = args.find((a) => !a.startsWith(\"-\")) ?? \".\";\n\t\tconst p = resolvePath(cwd, target);\n\n\t\tconst fmt = (b: number) =>\n\t\t\thuman ? `${(b / 1024).toFixed(1)}K` : String(Math.ceil(b / 1024));\n\n\t\tif (!shell.vfs.exists(p))\n\t\t\treturn {\n\t\t\t\tstderr: `du: ${target}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\n\t\tif (summary || shell.vfs.stat(p).type === \"file\") {\n\t\t\treturn {\n\t\t\t\tstdout: `${fmt(shell.vfs.getUsageBytes(p))}\\t${target}`,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst lines: string[] = [];\n\t\tconst walk = (dir: string, rel: string) => {\n\t\t\tlet total = 0;\n\t\t\tfor (const e of shell.vfs.list(dir)) {\n\t\t\t\tconst full = `${dir}/${e}`,\n\t\t\t\t\tr = `${rel}/${e}`;\n\t\t\t\tconst st = shell.vfs.stat(full);\n\t\t\t\tif (st.type === \"directory\") total += walk(full, r);\n\t\t\t\telse {\n\t\t\t\t\ttotal += st.size;\n\t\t\t\t\tif (!summary) lines.push(`${fmt(st.size)}\\t${r}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlines.push(`${fmt(total)}\\t${rel}`);\n\t\t\treturn total;\n\t\t};\n\t\twalk(p, target);\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "/**\n * expand.ts\n *\n * Centralised shell variable and expression expansion.\n * Used by `runCommand` (index.ts), `echo`, and `sh.ts`.\n *\n * Handles (in order):\n * ~ tilde to $HOME\n * $? last exit code\n * $$ mock PID\n * $# argument count (0 outside scripts)\n * ${#VAR} string length\n * ${VAR:-def} default if unset/empty\n * ${VAR:=def} assign default if unset/empty\n * ${VAR:+val} alternate value if set\n * ${VAR} simple braced reference\n * $VAR simple reference\n * $((expr)) arithmetic (integer)\n */\n\n// \u2500\u2500\u2500 arithmetic evaluator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Evaluate a simple integer arithmetic expression.\n * Supports: + - * / % ** unary- ( )\n * Variables are resolved from `env` before evaluation.\n * Returns NaN on syntax error.\n */\nexport function evalArith(expr: string, env: Record<string, string>): number {\n\t// Substitute variable names before evaluating\n\tconst substituted = expr.replace(\n\t\t/\\b([A-Za-z_][A-Za-z0-9_]*)\\b/g,\n\t\t(_, name) => {\n\t\t\tconst val = env[name];\n\t\t\treturn val !== undefined && val !== \"\" ? val : \"0\";\n\t\t},\n\t);\n\n\t// Whitelist: only digits, operators, spaces, parens\n\tif (!/^[\\d\\s+\\-*/%()^!&|<>=,. ]+$/.test(substituted)) return NaN;\n\n\ttry {\n\t\t// Use Function constructor for safe subset (no identifiers remain)\n\t\t// eslint-disable-next-line no-new-func\n\t\tconst result = Function(\n\t\t\t`\"use strict\"; return (${substituted.replace(/\\*\\*/g, \"**\")});`,\n\t\t)();\n\t\treturn typeof result === \"number\" ? Math.trunc(result) : NaN;\n\t} catch {\n\t\treturn NaN;\n\t}\n}\n\n// \u2500\u2500\u2500 synchronous expansion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Apply a replacer only to portions of `input` that are NOT inside single quotes.\n * Single-quoted content is passed through verbatim (POSIX sh behaviour).\n */\nfunction outsideSingleQuotes(\n\tinput: string,\n\treplacer: (chunk: string) => string,\n): string {\n\tconst parts: string[] = [];\n\tlet i = 0;\n\twhile (i < input.length) {\n\t\tconst sqIdx = input.indexOf(\"'\", i);\n\t\tif (sqIdx === -1) {\n\t\t\t// No more single quotes \u2014 expand the rest\n\t\t\tparts.push(replacer(input.slice(i)));\n\t\t\tbreak;\n\t\t}\n\t\t// Expand the part before the single quote\n\t\tparts.push(replacer(input.slice(i, sqIdx)));\n\t\t// Find closing single quote \u2014 everything inside is literal\n\t\tconst closeIdx = input.indexOf(\"'\", sqIdx + 1);\n\t\tif (closeIdx === -1) {\n\t\t\t// Unclosed quote \u2014 treat rest as literal\n\t\t\tparts.push(input.slice(sqIdx));\n\t\t\tbreak;\n\t\t}\n\t\tparts.push(input.slice(sqIdx, closeIdx + 1)); // include quotes\n\t\ti = closeIdx + 1;\n\t}\n\treturn parts.join(\"\");\n}\n\n/**\n * Expand all shell variable and expression forms synchronously.\n * Does NOT handle `$(cmd)` \u2014 that requires async; see `expandAsync`.\n * Content inside single quotes is left verbatim per POSIX sh rules.\n *\n * @param input Raw string possibly containing `$VAR`, `${...}`, `$((...))`.\n * @param env Current session env vars.\n * @param lastExit Last command exit code (for `$?`).\n * @param home Home directory path (for `~`).\n */\nexport function expandSync(\n\tinput: string,\n\tenv: Record<string, string>,\n\tlastExit = 0,\n\thome?: string,\n): string {\n\tconst homePath = home ?? env.HOME ?? \"/home/user\";\n\n\treturn outsideSingleQuotes(input, (chunk) => {\n\t\tlet s = chunk;\n\n\t\t// Tilde expansion \u2014 only at start of token or after `:` or whitespace\n\t\ts = s.replace(\n\t\t\t/(^|[\\s:])~(\\/|$)/g,\n\t\t\t(_, pre, post) => `${pre}${homePath}${post}`,\n\t\t);\n\n\t\t// $? $$ $#\n\t\ts = s.replace(/\\$\\?/g, String(lastExit));\n\t\ts = s.replace(/\\$\\$/g, \"1\");\n\t\ts = s.replace(/\\$#/g, \"0\");\n\n\t\t// $(( arithmetic )) \u2014 must come before ${ and $VAR to avoid conflicts\n\t\ts = s.replace(/\\$\\(\\(([^)]+(?:\\([^)]*\\)[^)]*)*)\\)\\)/g, (_, expr) => {\n\t\t\tconst result = evalArith(expr, env);\n\t\t\treturn Number.isNaN(result) ? \"0\" : String(result);\n\t\t});\n\n\t\t// ${#VAR} \u2014 string length\n\t\ts = s.replace(/\\$\\{#([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_, name) =>\n\t\t\tString((env[name] ?? \"\").length),\n\t\t);\n\n\t\t// ${VAR:-default}\n\t\ts = s.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_]*):-([^}]*)\\}/g, (_, name, def) =>\n\t\t\tenv[name] !== undefined && env[name] !== \"\" ? (env[name] as string) : def,\n\t\t);\n\n\t\t// ${VAR:=default} \u2014 also assigns to env\n\t\ts = s.replace(\n\t\t\t/\\$\\{([A-Za-z_][A-Za-z0-9_]*):=([^}]*)\\}/g,\n\t\t\t(_, name, def) => {\n\t\t\t\tif (env[name] === undefined || env[name] === \"\") env[name] = def;\n\t\t\t\treturn env[name] as string;\n\t\t\t},\n\t\t);\n\n\t\t// ${VAR:+alternate}\n\t\ts = s.replace(\n\t\t\t/\\$\\{([A-Za-z_][A-Za-z0-9_]*):\\+([^}]*)\\}/g,\n\t\t\t(_, name, alt) =>\n\t\t\t\tenv[name] !== undefined && env[name] !== \"\" ? alt : \"\",\n\t\t);\n\n\t\t// ${VAR}\n\t\ts = s.replace(\n\t\t\t/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g,\n\t\t\t(_, name) => env[name] ?? \"\",\n\t\t);\n\n\t\t// $VAR\n\t\ts = s.replace(/\\$([A-Za-z_][A-Za-z0-9_]*)/g, (_, name) => env[name] ?? \"\");\n\n\t\treturn s;\n\t});\n}\n\n// \u2500\u2500\u2500 async expansion (includes $(cmd)) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Expand all shell forms including `$(cmd)` command substitution.\n *\n * Processes `$(...)` blocks depth-first, respecting single-quote boundaries.\n * Then delegates to `expandSync` for the remaining forms.\n *\n * @param input Raw string.\n * @param env Current session env vars.\n * @param lastExit Last exit code.\n * @param runCmd Async callback to execute a command and return its stdout.\n */\nexport async function expandAsync(\n\tinput: string,\n\tenv: Record<string, string>,\n\tlastExit: number,\n\trunCmd: (cmd: string) => Promise<string>,\n): Promise<string> {\n\t// $(cmd) substitution \u2014 skip content inside single quotes\n\tif (input.includes(\"$(\")) {\n\t\tlet result = \"\";\n\t\tlet inSingle = false;\n\t\tlet i = 0;\n\n\t\twhile (i < input.length) {\n\t\t\tconst ch = input[i]!;\n\n\t\t\tif (ch === \"'\" && !inSingle) {\n\t\t\t\tinSingle = true;\n\t\t\t\tresult += ch;\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === \"'\" && inSingle) {\n\t\t\t\tinSingle = false;\n\t\t\t\tresult += ch;\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!inSingle && ch === \"$\" && input[i + 1] === \"(\") {\n\t\t\t\t// $((expr)) arithmetic \u2014 NOT a $(cmd) substitution, skip it\n\t\t\t\tif (input[i + 2] === \"(\") {\n\t\t\t\t\tresult += ch;\n\t\t\t\t\ti++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// Find matching ) with depth tracking\n\t\t\t\tlet depth = 0;\n\t\t\t\tlet j = i + 1;\n\t\t\t\twhile (j < input.length) {\n\t\t\t\t\tif (input[j] === \"(\") depth++;\n\t\t\t\t\telse if (input[j] === \")\") {\n\t\t\t\t\t\tdepth--;\n\t\t\t\t\t\tif (depth === 0) break;\n\t\t\t\t\t}\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\tconst sub = input.slice(i + 2, j).trim();\n\t\t\t\tconst out = (await runCmd(sub)).replace(/\\n$/, \"\");\n\t\t\t\tresult += out;\n\t\t\t\ti = j + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tresult += ch;\n\t\t\ti++;\n\t\t}\n\t\tinput = result;\n\t}\n\n\treturn expandSync(input, env, lastExit);\n}\n", "import type { ShellModule } from \"../types/commands\";\nimport { parseArgs } from \"./command-helpers\";\nimport { expandSync } from \"../utils/expand\";\n\n/**\n * Expand escape sequences for `echo -e`.\n * Handles \\n \\t \\r \\\\ \\a \\b \\f \\v and \\0NNN (octal).\n */\nfunction expandEscapes(text: string): string {\n\treturn text\n\t\t.replace(/\\\\n/g, \"\\n\")\n\t\t.replace(/\\\\t/g, \"\\t\")\n\t\t.replace(/\\\\r/g, \"\\r\")\n\t\t.replace(/\\\\\\\\/g, \"\\\\\")\n\t\t.replace(/\\\\a/g, \"\\x07\")\n\t\t.replace(/\\\\b/g, \"\\x08\")\n\t\t.replace(/\\\\f/g, \"\\x0C\")\n\t\t.replace(/\\\\v/g, \"\\x0B\")\n\t\t.replace(/\\\\0(\\d{1,3})/g, (_, oct) =>\n\t\t\tString.fromCharCode(parseInt(oct, 8)),\n\t\t);\n}\n\n/**\n * Echo text to stdout with shell-style expansion and escape support.\n * @category shell\n * @params [\"[-n] [-e] [text...]\"]\n */\nexport const echoCommand: ShellModule = {\n\tname: \"echo\",\n\tdescription: \"Display text\",\n\tcategory: \"shell\",\n\tparams: [\"[-n] [-e] [text...]\"],\n\trun: ({ args, stdin, env }) => {\n\t\tconst { flags, positionals } = parseArgs(args, {\n\t\t\tflags: [\"-n\", \"-e\", \"-E\"],\n\t\t});\n\t\tconst noNewline = flags.has(\"-n\");\n\t\tconst escapes = flags.has(\"-e\");\n\n\t\tconst rawText =\n\t\t\tpositionals.length > 0 ? positionals.join(\" \") : (stdin ?? \"\");\n\n\t\t// Full expansion: $? ${#VAR} $((expr)) ~ ${VAR:-def} $VAR etc.\n\t\t// $(cmd) is already resolved upstream by runCommand before echo.run is called.\n\t\tconst expanded = expandSync(\n\t\t\trawText,\n\t\t\tenv?.vars ?? {},\n\t\t\tenv?.lastExitCode ?? 0,\n\t\t);\n\t\tconst text = escapes ? expandEscapes(expanded) : expanded;\n\n\t\treturn {\n\t\t\tstdout: noNewline ? text : `${text}\\n`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "/** biome-ignore-all lint/style/useNamingConvention: ENV VARS */\nimport type { ShellModule } from \"../types/commands\";\n\n/**\n * Print environment variables for the current session.\n * @category shell\n * @params []\n */\nexport const envCommand: ShellModule = {\n\tname: \"env\",\n\tdescription: \"Print environment variables\",\n\tcategory: \"shell\",\n\tparams: [],\n\trun: ({ env, authUser }) => {\n\t\tconst vars = { ...env.vars, USER: authUser, HOME: `/home/${authUser}` };\n\t\treturn {\n\t\t\tstdout: Object.entries(vars)\n\t\t\t\t.map(([k, v]) => `${k}=${v}`)\n\t\t\t\t.join(\"\\n\"),\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Exit the current shell session (closeSession flag).\n * @category shell\n * @params [\"[code]\"]\n */\nexport const exitCommand: ShellModule = {\n\tname: \"exit\",\n\taliases: [\"bye\"],\n\tdescription: \"Exit the shell session\",\n\tcategory: \"shell\",\n\tparams: [\"[code]\"],\n\trun: ({ args }) => ({\n\t\tcloseSession: true,\n\t\texitCode: parseInt(args[0] ?? \"0\", 10) || 0,\n\t}),\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const exportCommand: ShellModule = {\n\tname: \"export\",\n\tdescription: \"Set shell environment variable\",\n\tcategory: \"shell\",\n\tparams: [\"[VAR=value]\"],\n\trun: ({ args, env }) => {\n\t\tif (args.length === 0) {\n\t\t\tconst out = Object.entries(env.vars)\n\t\t\t\t.map(([k, v]) => `declare -x ${k}=\"${v}\"`)\n\t\t\t\t.join(\"\\n\");\n\t\t\treturn { stdout: out, exitCode: 0 };\n\t\t}\n\t\tfor (const arg of args) {\n\t\t\tif (arg.includes(\"=\")) {\n\t\t\t\tconst eq = arg.indexOf(\"=\");\n\t\t\t\tconst name = arg.slice(0, eq);\n\t\t\t\tconst value = arg.slice(eq + 1);\n\t\t\t\tenv.vars[name] = value;\n\t\t\t} else {\n\t\t\t\t// mark existing as exported (already is)\n\t\t\t}\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Find files and directories by name and type with minimal pattern support.\n * @category files\n * @params [\"[path] [-name <pattern>] [-type f|d]\"]\n */\nexport const findCommand: ShellModule = {\n\tname: \"find\",\n\tdescription: \"Search for files\",\n\tcategory: \"files\",\n\tparams: [\"[path] [-name <pattern>] [-type f|d]\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst namePattern = getFlag(args, [\"-name\"]);\n\t\tconst typeFilter = getFlag(args, [\"-type\"]);\n\t\tconst positionals = args.filter(\n\t\t\t(a) => !a.startsWith(\"-\") && a !== namePattern && a !== typeFilter,\n\t\t);\n\t\tconst rootArg = positionals[0] ?? \".\";\n\t\tconst rootPath = resolvePath(cwd, rootArg);\n\n\t\ttry {\n\t\t\tassertPathAccess(authUser, rootPath, \"find\");\n\t\t\tif (!shell.vfs.exists(rootPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `find: ${rootArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `find: ${msg}`, exitCode: 1 };\n\t\t}\n\n\t\tconst nameRegex = namePattern\n\t\t\t? new RegExp(\n\t\t\t\t\t`^${(namePattern as string).replace(/\\./g, \"\\\\.\").replace(/\\*/g, \".*\").replace(/\\?/g, \".\")}$`,\n\t\t\t\t)\n\t\t\t: null;\n\n\t\tconst results: string[] = [];\n\t\tconst walk = (currentPath: string, display: string) => {\n\t\t\tconst stat = shell.vfs.stat(currentPath);\n\n\t\t\tconst matchesType =\n\t\t\t\t!typeFilter ||\n\t\t\t\t(typeFilter === \"f\" && stat.type === \"file\") ||\n\t\t\t\t(typeFilter === \"d\" && stat.type === \"directory\");\n\t\t\tconst matchesName =\n\t\t\t\t!nameRegex || nameRegex.test(currentPath.split(\"/\").pop() ?? \"\");\n\n\t\t\tif (matchesType && matchesName) results.push(display);\n\n\t\t\tif (stat.type === \"directory\") {\n\t\t\t\tfor (const entry of shell.vfs.list(currentPath)) {\n\t\t\t\t\tconst full = `${currentPath}/${entry}`;\n\t\t\t\t\tconst disp = `${display}/${entry}`;\n\t\t\t\t\twalk(full, disp);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\twalk(rootPath, rootArg);\n\t\treturn { stdout: results.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import * as os from \"node:os\";\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\n/**\n * Display memory usage information (human / MB / GB options).\n * @category system\n * @params [\"[-h] [-m] [-g]\"]\n */\nexport const freeCommand: ShellModule = {\n\tname: \"free\",\n\tdescription: \"Display amount of free and used memory\",\n\tcategory: \"system\",\n\tparams: [\"[-h] [-m] [-g]\"],\n\trun: ({ args }) => {\n\t\tconst human = ifFlag(args, [\"-h\", \"--human\"]);\n\t\tconst mb = ifFlag(args, [\"-m\"]);\n\t\tconst gb = ifFlag(args, [\"-g\"]);\n\n\t\tconst osTotalB = os.totalmem();\n\t\tconst osFreeB = os.freemem();\n\t\tconst usedB = osTotalB - osFreeB;\n\t\tconst sharedB = Math.floor(osTotalB * 0.02);\n\t\tconst buffersB = Math.floor(osTotalB * 0.05);\n\t\tconst availableB = Math.floor(osFreeB * 0.95);\n\t\tconst swapB = Math.floor(osTotalB * 0.5);\n\n\t\tconst fmt = (bytes: number): string => {\n\t\t\tif (human) {\n\t\t\t\tif (bytes >= 1024 * 1024 * 1024)\n\t\t\t\t\treturn `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}G`;\n\t\t\t\tif (bytes >= 1024 * 1024)\n\t\t\t\t\treturn `${(bytes / (1024 * 1024)).toFixed(1)}M`;\n\t\t\t\treturn `${(bytes / 1024).toFixed(1)}K`;\n\t\t\t}\n\t\t\tif (gb) return String(Math.floor(bytes / (1024 * 1024 * 1024)));\n\t\t\tif (mb) return String(Math.floor(bytes / (1024 * 1024)));\n\t\t\treturn String(Math.floor(bytes / 1024));\n\t\t};\n\n\t\tconst header = ` total used free shared buff/cache available`;\n\t\tconst memRow = `Mem: ${fmt(osTotalB).padStart(12)} ${fmt(usedB).padStart(11)} ${fmt(osFreeB).padStart(11)} ${fmt(sharedB).padStart(11)} ${fmt(buffersB).padStart(11)} ${fmt(availableB).padStart(11)}`;\n\t\tconst swapRow = `Swap: ${fmt(swapB).padStart(12)} ${fmt(0).padStart(11)} ${fmt(swapB).padStart(11)}`;\n\n\t\treturn { stdout: [header, memRow, swapRow].join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { parseArgs } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Search for a regex pattern in files or stdin with common flags.\n * @category text\n * @params [\"[-i] [-v] [-n] [-r] <pattern> [file...]\"]\n */\nexport const grepCommand: ShellModule = {\n\tname: \"grep\",\n\tdescription: \"Search text patterns\",\n\tcategory: \"text\",\n\tparams: [\"[-i] [-v] [-n] [-r] <pattern> [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst { flags, positionals } = parseArgs(args, {\n\t\t\tflags: [\"-i\", \"-v\", \"-n\", \"-r\"],\n\t\t});\n\t\tconst caseInsensitive = flags.has(\"-i\");\n\t\tconst invertMatch = flags.has(\"-v\");\n\t\tconst showLineNumbers = flags.has(\"-n\");\n\t\tconst recursive = flags.has(\"-r\");\n\t\tconst pattern = positionals[0];\n\t\tconst files = positionals.slice(1);\n\n\t\tif (!pattern) {\n\t\t\treturn { stderr: \"grep: no pattern specified\", exitCode: 1 };\n\t\t}\n\n\t\tlet regex: RegExp;\n\t\ttry {\n\t\t\t// No \"g\" flag \u2014 avoids the stateful lastIndex problem with regex.test()\n\t\t\tconst regexFlags = caseInsensitive ? \"mi\" : \"m\";\n\t\t\tregex = new RegExp(pattern, regexFlags);\n\t\t} catch {\n\t\t\treturn { stderr: `grep: invalid regex: ${pattern}`, exitCode: 1 };\n\t\t}\n\n\t\tconst matchLines = (content: string, prefix = \"\"): string[] => {\n\t\t\tconst lines = content.split(\"\\n\");\n\t\t\tconst out: string[] = [];\n\t\t\tfor (let i = 0; i < lines.length; i++) {\n\t\t\t\tconst line = lines[i] ?? \"\";\n\t\t\t\tconst matches = regex.test(line);\n\t\t\t\tconst shouldInclude = invertMatch ? !matches : matches;\n\t\t\t\tif (shouldInclude) {\n\t\t\t\t\tconst lineLabel = showLineNumbers ? `${i + 1}:` : \"\";\n\t\t\t\t\tout.push(`${prefix}${lineLabel}${line}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out;\n\t\t};\n\n\t\tconst readPaths = (base: string): string[] => {\n\t\t\tif (!shell.vfs.exists(base)) return [];\n\t\t\tconst stat = shell.vfs.stat(base);\n\t\t\tif (stat.type === \"file\") return [base];\n\t\t\tif (!recursive) return [];\n\t\t\tconst paths: string[] = [];\n\t\t\tconst walk = (dir: string) => {\n\t\t\t\tfor (const entry of shell.vfs.list(dir)) {\n\t\t\t\t\tconst full = `${dir}/${entry}`;\n\t\t\t\t\tconst s = shell.vfs.stat(full);\n\t\t\t\t\tif (s.type === \"file\") paths.push(full);\n\t\t\t\t\telse walk(full);\n\t\t\t\t}\n\t\t\t};\n\t\t\twalk(base);\n\t\t\treturn paths;\n\t\t};\n\n\t\tconst results: string[] = [];\n\n\t\tif (files.length === 0) {\n\t\t\tif (!stdin) return { stdout: \"\", exitCode: 1 };\n\t\t\tresults.push(...matchLines(stdin));\n\t\t} else {\n\t\t\tconst resolvedPaths = files.flatMap((f) => {\n\t\t\t\tconst target = resolvePath(cwd, f);\n\t\t\t\treturn readPaths(target).map((p) => ({ file: f, path: p }));\n\t\t\t});\n\n\t\t\tfor (const { file, path: filePath } of resolvedPaths) {\n\t\t\t\ttry {\n\t\t\t\t\tassertPathAccess(authUser, filePath, \"grep\");\n\t\t\t\t\tconst content = shell.vfs.readFile(filePath);\n\t\t\t\t\tconst prefix = resolvedPaths.length > 1 ? `${file}:` : \"\";\n\t\t\t\t\tresults.push(...matchLines(content, prefix));\n\t\t\t\t} catch {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `grep: ${file}: No such file or directory`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tstdout: results.length > 0 ? results.join(\"\\n\") : \"\",\n\t\t\texitCode: results.length > 0 ? 0 : 1,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const groupsCommand: ShellModule = {\n\tname: \"groups\",\n\tdescription: \"Print group memberships\",\n\tcategory: \"system\",\n\tparams: [\"[user]\"],\n\trun: ({ authUser, shell, args }) => {\n\t\tconst target = args[0] ?? authUser;\n\t\tconst isSudo = shell.users.isSudoer(target);\n\t\tconst grps = isSudo ? `${target} sudo root` : target;\n\t\treturn { stdout: grps, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { resolvePath } from \"./helpers\";\n\n/**\n * Compress files using gzip (stores in VFS as compressed content).\n * @category archive\n * @params [\"<file>\"]\n */\nexport const gzipCommand: ShellModule = {\n\tname: \"gzip\",\n\tdescription: \"Compress files\",\n\tcategory: \"archive\",\n\tparams: [\"<file>\"],\n\trun: ({ shell, cwd, args }) => {\n\t\tconst file = args[0];\n\t\tif (!file) return { stderr: \"gzip: no file specified\", exitCode: 1 };\n\t\tconst p = resolvePath(cwd, file);\n\t\ttry {\n\t\t\tshell.vfs.compressFile(p);\n\t\t\treturn { exitCode: 0 };\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstderr: `gzip: ${file}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t},\n};\n\nexport const gunzipCommand: ShellModule = {\n\t/**\n\t * Decompress gzip files (or zcat alias).\n\t * @category archive\n\t * @params [\"<file>\"]\n\t */\n\tname: \"gunzip\",\n\tdescription: \"Decompress files\",\n\tcategory: \"archive\",\n\tparams: [\"<file>\"],\n\taliases: [\"zcat\"],\n\trun: ({ shell, cwd, args }) => {\n\t\tconst file = args[0];\n\t\tif (!file) return { stderr: \"gunzip: no file specified\", exitCode: 1 };\n\t\tconst p = resolvePath(cwd, file);\n\t\ttry {\n\t\t\tshell.vfs.decompressFile(p);\n\t\t\treturn { exitCode: 0 };\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstderr: `gunzip: ${file}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\n/**\n * Output the first part of files or stdin (head).\n * @category text\n * @params [\"[-n <lines>] [file...]\"]\n */\nexport const headCommand: ShellModule = {\n\tname: \"head\",\n\tdescription: \"Output first lines\",\n\tcategory: \"text\",\n\tparams: [\"[-n <lines>] [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst nArg = getFlag(args, [\"-n\"]);\n\t\tconst n = typeof nArg === \"string\" ? parseInt(nArg, 10) : 10;\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\") && a !== nArg);\n\n\t\tconst take = (content: string) =>\n\t\t\tcontent.split(\"\\n\").slice(0, n).join(\"\\n\");\n\n\t\tif (positionals.length === 0) {\n\t\t\treturn { stdout: take(stdin ?? \"\"), exitCode: 0 };\n\t\t}\n\n\t\tconst results: string[] = [];\n\t\tfor (const file of positionals) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\ttry {\n\t\t\t\tassertPathAccess(authUser, filePath, \"head\");\n\t\t\t\tresults.push(take(shell.vfs.readFile(filePath)));\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `head: ${file}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn { stdout: results.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getCommandModulesPublic } from \"./registry\";\n\n// \u2500\u2500\u2500 category config \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst CATEGORY_ORDER = [\n\t\"navigation\",\n\t\"files\",\n\t\"text\",\n\t\"archive\",\n\t\"system\",\n\t\"package\",\n\t\"network\",\n\t\"shell\",\n\t\"users\",\n\t\"misc\",\n];\n\nconst CATEGORY_LABELS: Record<string, string> = {\n\tnavigation: \"Navigation\",\n\tfiles: \"Files & Filesystem\",\n\ttext: \"Text Processing\",\n\tarchive: \"Archive & Compression\",\n\tsystem: \"System\",\n\tpackage: \"Package Management\",\n\tnetwork: \"Network\",\n\tshell: \"Shell & Scripting\",\n\tusers: \"Users & Permissions\",\n\tmisc: \"Miscellaneous\",\n};\n\n// \u2500\u2500\u2500 formatting helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst BOLD = \"\\x1b[1m\";\nconst RESET = \"\\x1b[0m\";\nconst CYAN = \"\\x1b[36m\";\nconst YLW = \"\\x1b[33m\";\nconst DIM = \"\\x1b[2m\";\nconst GREEN = \"\\x1b[32m\";\n\nfunction pad(s: string, n: number): string {\n\treturn s.length >= n ? s : s + \" \".repeat(n - s.length);\n}\n\nfunction formatCmdLine(mod: ShellModule): string {\n\tconst aliases = mod.aliases?.length\n\t\t? ` ${DIM}(${mod.aliases.join(\", \")})${RESET}`\n\t\t: \"\";\n\treturn ` ${CYAN}${pad(mod.name, 16)}${RESET}${aliases}${pad(\"\", mod.aliases?.length ? 0 : 0)} ${mod.description ?? \"\"}`;\n}\n\n// \u2500\u2500\u2500 full grouped listing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction renderFull(modules: ShellModule[]): string {\n\tconst grouped: Record<string, ShellModule[]> = {};\n\tfor (const mod of modules) {\n\t\tconst cat = mod.category ?? \"misc\";\n\t\tif (!grouped[cat]) grouped[cat] = [];\n\t\tgrouped[cat]!.push(mod);\n\t}\n\n\tconst lines: string[] = [\n\t\t`${BOLD}Available commands${RESET}`,\n\t\t`${DIM}Type 'help <command>' for detailed usage.${RESET}`,\n\t\t\"\",\n\t];\n\n\tconst cats = [\n\t\t...CATEGORY_ORDER.filter((c) => grouped[c]),\n\t\t...Object.keys(grouped)\n\t\t\t.filter((c) => !CATEGORY_ORDER.includes(c))\n\t\t\t.sort(),\n\t];\n\n\tfor (const cat of cats) {\n\t\tconst mods = grouped[cat];\n\t\tif (!mods?.length) continue;\n\n\t\tlines.push(`${YLW}${CATEGORY_LABELS[cat] ?? cat}${RESET}`);\n\t\tconst sorted = [...mods].sort((a, b) => a.name.localeCompare(b.name));\n\t\tfor (const mod of sorted) {\n\t\t\tlines.push(formatCmdLine(mod));\n\t\t}\n\t\tlines.push(\"\");\n\t}\n\n\tconst total = modules.length;\n\tlines.push(`${DIM}${total} commands available.${RESET}`);\n\n\treturn lines.join(\"\\n\");\n}\n\n// \u2500\u2500\u2500 single-command detail \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction renderDetail(mod: ShellModule): string {\n\tconst lines: string[] = [];\n\n\tlines.push(\n\t\t`${BOLD}${mod.name}${RESET} \u2014 ${mod.description ?? \"no description\"}`,\n\t);\n\n\tif (mod.aliases?.length) {\n\t\tlines.push(`${DIM}Aliases: ${mod.aliases.join(\", \")}${RESET}`);\n\t}\n\n\tlines.push(\"\");\n\tlines.push(`${GREEN}Usage:${RESET}`);\n\tif (mod.params.length) {\n\t\tfor (const p of mod.params) {\n\t\t\tlines.push(` ${mod.name} ${p}`);\n\t\t}\n\t} else {\n\t\tlines.push(` ${mod.name}`);\n\t}\n\n\tconst catLabel =\n\t\tCATEGORY_LABELS[mod.category ?? \"misc\"] ?? mod.category ?? \"misc\";\n\tlines.push(\"\");\n\tlines.push(`${DIM}Category: ${catLabel}${RESET}`);\n\n\treturn lines.join(\"\\n\");\n}\n\n// \u2500\u2500\u2500 export \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function createHelpCommand(_getNames: () => string[]): ShellModule {\n\treturn {\n\t\tname: \"help\",\n\t\tdescription: \"List all commands, or show usage for a specific command\",\n\t\tcategory: \"shell\",\n\t\tparams: [\"[command]\"],\n\t\trun: ({ args }) => {\n\t\t\tconst modules = getCommandModulesPublic();\n\n\t\t\tif (args[0]) {\n\t\t\t\tconst target = args[0].toLowerCase();\n\t\t\t\tconst mod = modules.find(\n\t\t\t\t\t(m) => m.name === target || m.aliases?.includes(target),\n\t\t\t\t);\n\t\t\t\tif (!mod) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `help: no help entry for '${args[0]}'`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn { stdout: renderDetail(mod), exitCode: 0 };\n\t\t\t}\n\n\t\t\treturn { stdout: renderFull(modules), exitCode: 0 };\n\t\t},\n\t};\n}\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Display persisted command history for the session (from VFS).\n * @category shell\n * @params [\"[n]\"]\n */\nexport const historyCommand: ShellModule = {\n\tname: \"history\",\n\tdescription: \"Display command history\",\n\tcategory: \"shell\",\n\tparams: [\"[n]\"],\n\trun: ({ args, shell }) => {\n\t\t// History is persisted in the VFS by the interactive shell\n\t\tconst histPath = \"/virtual-env-js/.bash_history\";\n\t\tif (!shell.vfs.exists(histPath)) {\n\t\t\treturn { stdout: \"\", exitCode: 0 };\n\t\t}\n\n\t\tconst raw = shell.vfs.readFile(histPath);\n\t\tconst lines = raw.split(\"\\n\").filter(Boolean);\n\n\t\tconst nArg = args[0];\n\t\tconst n = nArg ? parseInt(nArg, 10) : null;\n\t\tconst slice = n && !Number.isNaN(n) ? lines.slice(-n) : lines;\n\n\t\tconst offset = lines.length - slice.length + 1;\n\t\tconst numbered = slice.map(\n\t\t\t(line, i) => `${String(offset + i).padStart(5)} ${line}`,\n\t\t);\n\n\t\treturn { stdout: numbered.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Print the configured hostname for the virtual shell.\n * @category system\n * @params []\n */\nexport const hostnameCommand: ShellModule = {\n\tname: \"hostname\",\n\tdescription: \"Print hostname\",\n\tcategory: \"system\",\n\tparams: [],\n\trun: ({ hostname }) => ({ stdout: hostname, exitCode: 0 }),\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const htopCommand: ShellModule = {\n\tname: \"htop\",\n\tdescription: \"System monitor\",\n\tcategory: \"system\",\n\tparams: [],\n\trun: ({ mode }) => {\n\t\tif (mode === \"exec\") {\n\t\t\treturn { stderr: \"htop: interactive terminal required\", exitCode: 1 };\n\t\t}\n\n\t\treturn { openHtop: true, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const idCommand: ShellModule = {\n\tname: \"id\",\n\tdescription: \"Print user identity\",\n\tcategory: \"system\",\n\tparams: [\"[user]\"],\n\trun: ({ authUser, shell, args }) => {\n\t\tconst target = args[0] ?? authUser;\n\t\tconst uid = target === \"root\" ? 0 : 1000;\n\t\tconst gid = uid;\n\t\tconst isSudo = shell.users.isSudoer(target);\n\t\tconst groups = isSudo ? `${gid}(${target}),0(root)` : `${gid}(${target})`;\n\t\treturn {\n\t\t\tstdout: `uid=${uid}(${target}) gid=${gid}(${target}) groups=${groups}`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const killCommand: ShellModule = {\n\tname: \"kill\",\n\tdescription: \"Send signal to process\",\n\tcategory: \"system\",\n\tparams: [\"[-9] <pid>\"],\n\trun: ({ args }) => {\n\t\tconst pid = args.find((a) => !a.startsWith(\"-\"));\n\t\tif (!pid) return { stderr: \"kill: no pid specified\", exitCode: 1 };\n\t\t// In virtual env, we just acknowledge the kill\n\t\treturn { stdout: ``, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const lnCommand: ShellModule = {\n\tname: \"ln\",\n\tdescription: \"Create links\",\n\tcategory: \"files\",\n\tparams: [\"[-s] <target> <link_name>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst symbolic = ifFlag(args, [\"-s\", \"--symbolic\"]);\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst [targetArg, linkArg] = positionals;\n\n\t\tif (!targetArg || !linkArg) {\n\t\t\treturn { stderr: \"ln: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst linkPath = resolvePath(cwd, linkArg);\n\t\tconst targetPath = symbolic\n\t\t\t? targetArg // keep relative for symlinks\n\t\t\t: resolvePath(cwd, targetArg);\n\n\t\ttry {\n\t\t\tassertPathAccess(authUser, linkPath, \"ln\");\n\n\t\t\tif (!symbolic) {\n\t\t\t\t// Hard link \u2014 copy file contents\n\t\t\t\tconst srcPath = resolvePath(cwd, targetArg);\n\t\t\t\tassertPathAccess(authUser, srcPath, \"ln\");\n\t\t\t\tif (!shell.vfs.exists(srcPath)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `ln: ${targetArg}: No such file or directory`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst content = shell.vfs.readFile(srcPath);\n\t\t\t\tshell.writeFileAsUser(authUser, linkPath, content);\n\t\t\t} else {\n\t\t\t\tshell.vfs.symlink(targetPath, linkPath);\n\t\t\t}\n\n\t\t\treturn { exitCode: 0 };\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `ln: ${msg}`, exitCode: 1 };\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg, ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, joinListWithType, resolvePath } from \"./helpers\";\n\nfunction formatPermissions(mode: number, isDirectory: boolean): string {\n\tconst fileType = isDirectory ? \"d\" : \"-\";\n\tconst permissionBits = [\n\t\t[0o400, \"r\"],\n\t\t[0o200, \"w\"],\n\t\t[0o100, \"x\"],\n\t\t[0o040, \"r\"],\n\t\t[0o020, \"w\"],\n\t\t[0o010, \"x\"],\n\t\t[0o004, \"r\"],\n\t\t[0o002, \"w\"],\n\t\t[0o001, \"x\"],\n\t] as const;\n\tconst permissions = permissionBits\n\t\t.map(([bit, symbol]) => (mode & bit ? symbol : \"-\"))\n\t\t.join(\"\");\n\n\treturn `${fileType}${permissions}`;\n}\n\nfunction formatDate(date: Date): string {\n\treturn date.toISOString().replace(\"T\", \" \").slice(0, 16);\n}\n\nexport const lsCommand: ShellModule = {\n\tname: \"ls\",\n\tdescription: \"List directory contents\",\n\tcategory: \"navigation\",\n\tparams: [\"[-la] [path]\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst longFormat = ifFlag(args, [\"-l\", \"--long\"]);\n\t\tconst showHidden = ifFlag(args, [\"-a\", \"--all\"]);\n\t\tconst targetArg = getArg(args, 0, {\n\t\t\tflags: [\"-l\", \"--long\", \"-a\", \"--all\", \"-la\", \"-al\"],\n\t\t});\n\t\tconst target = resolvePath(cwd, targetArg ?? cwd);\n\t\tassertPathAccess(authUser, target, \"ls\");\n\t\tconst items = shell.vfs\n\t\t\t.list(target)\n\t\t\t.filter((name) => showHidden || !name.startsWith(\".\"));\n\t\tconst rendered = longFormat\n\t\t\t? items\n\t\t\t\t\t.map((name) => {\n\t\t\t\t\t\tconst childPath = resolvePath(target, name);\n\t\t\t\t\t\tconst stat = shell.vfs.stat(childPath);\n\t\t\t\t\t\tconst size = stat.type === \"file\" ? stat.size : stat.childrenCount;\n\t\t\t\t\t\treturn `${formatPermissions(stat.mode, stat.type === \"directory\")} 1 ${size} ${formatDate(stat.updatedAt)} ${name}${stat.type === \"directory\" ? \"/\" : \"\"}`;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t: joinListWithType(target, items, (p) => shell.vfs.stat(p));\n\t\treturn { stdout: rendered, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const lsbReleaseCommand: ShellModule = {\n\tname: \"lsb_release\",\n\tdescription: \"Print distribution-specific information\",\n\tcategory: \"system\",\n\tparams: [\"[-a] [-i] [-d] [-r] [-c]\"],\n\trun: ({ args, shell }) => {\n\t\tlet osName = shell.properties?.os ?? \"Fortune GNU/Linux x64\";\n\t\tlet codename = \"aurora\";\n\t\tlet version = \"1.0\";\n\n\t\ttry {\n\t\t\tconst content = shell.vfs.readFile(\"/etc/os-release\");\n\t\t\tfor (const line of content.split(\"\\n\")) {\n\t\t\t\tif (line.startsWith(\"PRETTY_NAME=\"))\n\t\t\t\t\tosName = line\n\t\t\t\t\t\t.slice(\"PRETTY_NAME=\".length)\n\t\t\t\t\t\t.replace(/^\"|\"$/g, \"\")\n\t\t\t\t\t\t.trim();\n\t\t\t\tif (line.startsWith(\"VERSION_CODENAME=\"))\n\t\t\t\t\tcodename = line.slice(\"VERSION_CODENAME=\".length).trim();\n\t\t\t\tif (line.startsWith(\"VERSION_ID=\"))\n\t\t\t\t\tversion = line\n\t\t\t\t\t\t.slice(\"VERSION_ID=\".length)\n\t\t\t\t\t\t.replace(/^\"|\"$/g, \"\")\n\t\t\t\t\t\t.trim();\n\t\t\t}\n\t\t} catch {}\n\n\t\tconst all = ifFlag(args, [\"-a\", \"--all\"]);\n\t\tconst showId = ifFlag(args, [\"-i\", \"--id\"]);\n\t\tconst showDesc = ifFlag(args, [\"-d\", \"--description\"]);\n\t\tconst showRelease = ifFlag(args, [\"-r\", \"--release\"]);\n\t\tconst showCodename = ifFlag(args, [\"-c\", \"--codename\"]);\n\n\t\tif (all || args.length === 0) {\n\t\t\treturn {\n\t\t\t\tstdout: [\n\t\t\t\t\t`Distributor ID:\\tFortune`,\n\t\t\t\t\t`Description:\\t${osName}`,\n\t\t\t\t\t`Release:\\t${version}`,\n\t\t\t\t\t`Codename:\\t${codename}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst lines: string[] = [];\n\t\tif (showId) lines.push(`Distributor ID:\\tFortune`);\n\t\tif (showDesc) lines.push(`Description:\\t${osName}`);\n\t\tif (showRelease) lines.push(`Release:\\t${version}`);\n\t\tif (showCodename) lines.push(`Codename:\\t${codename}`);\n\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nconst MAN_PAGES: Record<string, string> = {\n\tls: `LS(1) User Commands LS(1)\n\nNAME\n ls - list directory contents\n\nSYNOPSIS\n ls [OPTION]... [FILE]...\n\nDESCRIPTION\n List information about the FILEs (the current directory by default).\n\nOPTIONS\n -l use a long listing format\n -a do not ignore entries starting with .\n -h with -l, print human readable sizes\n -r reverse order while sorting\n -t sort by modification time\n\nAUTHOR\n Written by Richard M. Stallman and David MacKenzie.`,\n\n\tcat: `CAT(1) User Commands CAT(1)\n\nNAME\n cat - concatenate files and print on the standard output\n\nSYNOPSIS\n cat [OPTION]... [FILE]...\n\nDESCRIPTION\n Concatenate FILE(s) to standard output.\n\nOPTIONS\n -n, --number number all output lines\n -b, --number-nonblank number nonempty output lines`,\n\n\tgrep: `GREP(1) User Commands GREP(1)\n\nNAME\n grep, egrep, fgrep - print lines that match patterns\n\nSYNOPSIS\n grep [OPTION]... PATTERNS [FILE]...\n\nOPTIONS\n -i, --ignore-case ignore case distinctions in patterns and data\n -v, --invert-match select non-matching lines\n -n, --line-number print line number with output lines\n -r, --recursive read all files under each directory, recursively`,\n\n\tapt: `APT(8) APT APT(8)\n\nNAME\n apt - command-line interface\n\nSYNOPSIS\n apt [options] command\n\nDESCRIPTION\n apt provides a high-level commandline interface for the package\n management system.\n\nCOMMANDS\n install pkg... Install packages\n remove pkg... Remove packages\n update Download package information\n upgrade Upgrade installed packages\n search term Search in package descriptions\n show pkg Show package information\n list List packages`,\n\n\tssh: `SSH(1) OpenSSH SSH(1)\n\nNAME\n ssh - OpenSSH remote login client\n\nSYNOPSIS\n ssh [-p port] [user@]hostname [command]\n\nDESCRIPTION\n ssh (SSH client) is a program for logging into a remote machine and\n for executing commands on a remote machine.`,\n\n\tcurl: `CURL(1) User Commands CURL(1)\n\nNAME\n curl - transfer a URL\n\nSYNOPSIS\n curl [options / URLs]\n\nDESCRIPTION\n curl is a tool for transferring data with URL syntax.\n\nOPTIONS\n -o, --output <file> Write output to <file>\n -X, --request <method> Specify request method\n -d, --data <data> HTTP POST data\n -H, --header <header> Pass custom header\n -s, --silent Silent mode\n -I, --head Show document info only\n -L, --location Follow redirects\n -v, --verbose Make the operation more talkative`,\n\n\tchmod: `CHMOD(1) User Commands CHMOD(1)\n\nNAME\n chmod - change file mode bits\n\nSYNOPSIS\n chmod [OPTION]... MODE[,MODE]... FILE...\n chmod [OPTION]... OCTAL-MODE FILE...\n\nDESCRIPTION\n Change the file mode bits of each given file according to MODE.\n\nEXAMPLES\n chmod 755 script.sh rwxr-xr-x\n chmod 644 file.txt rw-r--r--\n chmod +x script.sh add execute permission`,\n\n\ttar: `TAR(1) GNU tar Manual TAR(1)\n\nNAME\n tar - an archiving utility\n\nSYNOPSIS\n tar [OPTION...] [FILE]...\n\nDESCRIPTION\n tar saves many files together into a single tape or disk archive,\n and can restore individual files from the archive.\n\nOPTIONS\n -c, --create create a new archive\n -x, --extract extract files from an archive\n -z, --gzip filter the archive through gzip\n -f, --file=ARCHIVE use archive file or device ARCHIVE\n -v, --verbose verbosely list files processed\n -t, --list list the contents of an archive`,\n};\n\nexport const manCommand: ShellModule = {\n\tname: \"man\",\n\tdescription: \"Interface to the system reference manuals\",\n\tcategory: \"shell\",\n\tparams: [\"<command>\"],\n\trun: ({ args, shell }) => {\n\t\tconst name = args[0];\n\t\tif (!name) return { stderr: \"What manual page do you want?\", exitCode: 1 };\n\n\t\t// VFS-installed man pages take priority\n\t\tconst manPath = `/usr/share/man/man1/${name}.1`;\n\t\tif (shell.vfs.exists(manPath)) {\n\t\t\treturn { stdout: shell.vfs.readFile(manPath), exitCode: 0 };\n\t\t}\n\n\t\tconst page = MAN_PAGES[name.toLowerCase()];\n\t\tif (page) return { stdout: page, exitCode: 0 };\n\n\t\treturn { stderr: `No manual entry for ${name}`, exitCode: 16 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const mkdirCommand: ShellModule = {\n\tname: \"mkdir\",\n\tdescription: \"Make directories\",\n\tcategory: \"files\",\n\tparams: [\"<dir>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tif (args.length === 0) {\n\t\t\treturn { stderr: \"mkdir: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tfor (let index = 0; index < args.length; index++) {\n\t\t\tconst dir = getArg(args, index);\n\t\t\tif (!dir) {\n\t\t\t\treturn { stderr: \"mkdir: missing operand\", exitCode: 1 };\n\t\t\t}\n\t\t\tconst target = resolvePath(cwd, dir);\n\t\t\tassertPathAccess(authUser, target, \"mkdir\");\n\t\t\tshell.vfs.mkdir(target);\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const mvCommand: ShellModule = {\n\tname: \"mv\",\n\tdescription: \"Move or rename files\",\n\tcategory: \"files\",\n\tparams: [\"<source> <dest>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst [srcArg, destArg] = positionals;\n\n\t\tif (!srcArg || !destArg) {\n\t\t\treturn { stderr: \"mv: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst srcPath = resolvePath(cwd, srcArg);\n\t\tconst destPath = resolvePath(cwd, destArg);\n\n\t\ttry {\n\t\t\tassertPathAccess(authUser, srcPath, \"mv\");\n\t\t\tassertPathAccess(authUser, destPath, \"mv\");\n\n\t\t\tif (!shell.vfs.exists(srcPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `mv: ${srcArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// If dest is a directory, move into it\n\t\t\tconst finalDest =\n\t\t\t\tshell.vfs.exists(destPath) &&\n\t\t\t\tshell.vfs.stat(destPath).type === \"directory\"\n\t\t\t\t\t? `${destPath}/${srcArg.split(\"/\").pop()}`\n\t\t\t\t\t: destPath;\n\n\t\t\tshell.vfs.move(srcPath, finalDest);\n\t\t\treturn { exitCode: 0 };\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\treturn { stderr: `mv: ${msg}`, exitCode: 1 };\n\t\t}\n\t},\n};\n", "import * as path from \"node:path\";\nimport type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const nanoCommand: ShellModule = {\n\tname: \"nano\",\n\tdescription: \"Text editor\",\n\tcategory: \"files\",\n\tparams: [\"<file>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst fileArg = args[0];\n\t\tif (!fileArg) {\n\t\t\treturn { stderr: \"nano: missing file operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst targetPath = resolvePath(cwd, fileArg);\n\t\tassertPathAccess(authUser, targetPath, \"nano\");\n\t\tconst initialContent = shell.vfs.exists(targetPath)\n\t\t\t? shell.vfs.readFile(targetPath)\n\t\t\t: \"\";\n\t\tconst safeName = path.posix.basename(targetPath) || \"buffer\";\n\t\tconst tempPath = `/tmp/sshmimic-nano-${Date.now()}-${safeName}.tmp`;\n\n\t\treturn {\n\t\t\topenEditor: {\n\t\t\t\ttargetPath,\n\t\t\t\ttempPath,\n\t\t\t\tinitialContent,\n\t\t\t},\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { ShellProperties } from \"../VirtualShell\";\n\nfunction formatUptime(seconds: number): string {\n\tconst totalMinutes = Math.max(1, Math.floor(seconds / 60));\n\tconst days = Math.floor(totalMinutes / (24 * 60));\n\tconst hours = Math.floor((totalMinutes % (24 * 60)) / 60);\n\tconst minutes = totalMinutes % 60;\n\n\tconst parts: string[] = [];\n\tif (days > 0) {\n\t\tparts.push(`${days} day${days > 1 ? \"s\" : \"\"}`);\n\t}\n\tif (hours > 0) {\n\t\tparts.push(`${hours} hour${hours > 1 ? \"s\" : \"\"}`);\n\t}\n\tif (minutes > 0 || parts.length === 0) {\n\t\tparts.push(`${minutes} min${minutes > 1 ? \"s\" : \"\"}`);\n\t}\n\n\treturn parts.join(\", \");\n}\n\nfunction colorBlock(code: number): string {\n\treturn `\\u001b[${code}m \\u001b[0m`;\n}\n\nfunction buildColorBars(): string[] {\n\tconst normal = [40, 41, 42, 43, 44, 45, 46, 47].map(colorBlock).join(\"\");\n\tconst bright = [100, 101, 102, 103, 104, 105, 106, 107]\n\t\t.map(colorBlock)\n\t\t.join(\"\");\n\treturn [normal, bright];\n}\n\nfunction colorizeLogoLine(line: string, index: number, total: number): string {\n\tif (line.trim().length === 0) {\n\t\treturn line;\n\t}\n\n\tconst start = { r: 255, g: 255, b: 255 };\n\tconst end = { r: 168, g: 85, b: 247 };\n\tconst ratio = total <= 1 ? 0 : index / (total - 1);\n\n\tconst r = Math.round(start.r + (end.r - start.r) * ratio);\n\tconst g = Math.round(start.g + (end.g - start.g) * ratio);\n\tconst b = Math.round(start.b + (end.b - start.b) * ratio);\n\n\treturn `\\u001b[38;2;${r};${g};${b}m${line}\\u001b[0m`;\n}\n\nfunction colorizeDetailLine(line: string): string {\n\tif (line.trim().length === 0) {\n\t\treturn line;\n\t}\n\n\tconst colonIndex = line.indexOf(\":\");\n\n\tif (colonIndex === -1) {\n\t\t// Pas de ':', chercher '@' pour identifier user@host\n\t\tif (line.includes(\"@\")) {\n\t\t\t// C'est user@host, appliquer d\u00E9grad\u00E9 horizontal\n\t\t\treturn applyHorizontalGradient(line);\n\t\t}\n\t\t// Sinon c'est un separator ou autre, laisser tel quel\n\t\treturn line;\n\t}\n\n\t// Il y a un ':', c'est titre: valeur\n\tconst title = line.substring(0, colonIndex + 1);\n\tconst value = line.substring(colonIndex + 1);\n\n\t// Appliquer le d\u00E9grad\u00E9 seulement au titre\n\tconst colorized = applyHorizontalGradient(title);\n\treturn colorized + value;\n}\n\nfunction applyHorizontalGradient(text: string): string {\n\t// Nettoyer les codes ANSI existants\n\tconst ansiRegex = new RegExp(`${String.fromCharCode(27)}\\\\[[\\\\d;]*m`, \"g\");\n\tconst cleaned = text.replace(ansiRegex, \"\");\n\n\tif (cleaned.trim().length === 0) {\n\t\treturn text;\n\t}\n\n\tconst start = { r: 255, g: 255, b: 255 };\n\tconst end = { r: 168, g: 85, b: 247 };\n\tlet result = \"\";\n\n\tfor (let i = 0; i < cleaned.length; i += 1) {\n\t\tconst ratio = cleaned.length <= 1 ? 0 : i / (cleaned.length - 1);\n\n\t\tconst r = Math.round(start.r + (end.r - start.r) * ratio);\n\t\tconst g = Math.round(start.g + (end.g - start.g) * ratio);\n\t\tconst b = Math.round(start.b + (end.b - start.b) * ratio);\n\n\t\tresult += `\\u001b[38;2;${r};${g};${b}m${cleaned[i]}\\u001b[0m`;\n\t}\n\n\treturn result;\n}\n\nexport interface NeofetchInfo {\n\tuser: string;\n\thost: string;\n\tosName?: string;\n\tkernel?: string;\n\tuptimeSeconds?: number;\n\tpackages?: string;\n\tshell?: string;\n\tshellProps?: ShellProperties;\n\tresolution?: string;\n\tterminal?: string;\n\tcpu?: string;\n\tgpu?: string;\n\tmemoryUsedMiB?: number;\n\tmemoryTotalMiB?: number;\n}\n\nfunction toMiB(bytes: number): number {\n\treturn Math.max(0, Math.round(bytes / (1024 * 1024)));\n}\n\nfunction readOsPrettyName(): string | undefined {\n\ttry {\n\t\tconst data = readFileSync(\"/etc/os-release\", \"utf8\");\n\t\tfor (const line of data.split(\"\\n\")) {\n\t\t\tif (!line.startsWith(\"PRETTY_NAME=\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst value = line.slice(\"PRETTY_NAME=\".length).trim();\n\t\t\treturn value.replace(/^\"|\"$/g, \"\");\n\t\t}\n\t} catch {\n\t\treturn undefined;\n\t}\n\n\treturn undefined;\n}\n\nfunction readFirstLine(filePath: string): string | undefined {\n\ttry {\n\t\tconst data = readFileSync(filePath, \"utf8\").split(\"\\n\")[0]?.trim();\n\t\tif (!data || data.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn data;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction resolveHostLabel(fallback: string): string {\n\tconst vendor = readFirstLine(\"/sys/devices/virtual/dmi/id/sys_vendor\");\n\tconst product = readFirstLine(\"/sys/devices/virtual/dmi/id/product_name\");\n\n\tif (vendor && product) {\n\t\treturn `${vendor} ${product}`;\n\t}\n\tif (product) {\n\t\treturn product;\n\t}\n\n\treturn fallback;\n}\n\nfunction countDpkgPackages(): number | undefined {\n\tconst candidates = [\"/var/lib/dpkg/status\", \"/usr/local/var/lib/dpkg/status\"];\n\n\tfor (const filePath of candidates) {\n\t\tif (!existsSync(filePath)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\tconst data = readFileSync(filePath, \"utf8\");\n\t\t\tconst matches = data.match(/^Package:\\s+/gm);\n\t\t\treturn matches?.length ?? 0;\n\t\t} catch {}\n\t}\n\n\treturn undefined;\n}\n\nfunction countSnapPackages(): number | undefined {\n\tconst candidates = [\"/snap\", \"/var/lib/snapd/snaps\"];\n\n\tfor (const dirPath of candidates) {\n\t\tif (!existsSync(dirPath)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\tconst entries = readdirSync(dirPath, { withFileTypes: true });\n\t\t\tconst count = entries.filter((entry) => entry.isDirectory()).length;\n\t\t\treturn count;\n\t\t} catch {}\n\t}\n\n\treturn undefined;\n}\n\nfunction resolvePackagesLabel(): string {\n\tconst dpkgCount = countDpkgPackages();\n\tconst snapCount = countSnapPackages();\n\n\tif (dpkgCount !== undefined && snapCount !== undefined) {\n\t\treturn `${dpkgCount} (dpkg), ${snapCount} (snap)`;\n\t}\n\tif (dpkgCount !== undefined) {\n\t\treturn `${dpkgCount} (dpkg)`;\n\t}\n\tif (snapCount !== undefined) {\n\t\treturn `${snapCount} (snap)`;\n\t}\n\n\treturn \"n/a\";\n}\n\nfunction resolveCpuLabel(): string {\n\tconst cpus = os.cpus();\n\tif (cpus.length === 0) {\n\t\treturn \"unknown\";\n\t}\n\n\tconst first = cpus[0];\n\tif (!first) {\n\t\treturn \"unknown\";\n\t}\n\n\tconst ghz = (first.speed / 1000).toFixed(2);\n\treturn `${first.model} (${cpus.length}) @ ${ghz}GHz`;\n}\n\nfunction resolveShellLabel(shell?: string): string {\n\tif (!shell || shell.trim().length === 0) {\n\t\treturn \"unknown\";\n\t}\n\n\treturn path.posix.basename(shell.trim());\n}\n\nfunction resolveDefaults(info: NeofetchInfo): Required<NeofetchInfo> {\n\tconst totalMem = os.totalmem();\n\tconst freeMem = os.freemem();\n\tconst usedMem = Math.max(0, totalMem - freeMem);\n\tconst shellProps = info.shellProps;\n\n\tconst processUptime = process.uptime();\n\tif (info.uptimeSeconds === undefined) {\n\t\tinfo.uptimeSeconds = Math.round(processUptime);\n\t}\n\n\treturn {\n\t\tuser: info.user,\n\t\thost: info.host,\n\t\tosName:\n\t\t\tshellProps?.os ??\n\t\t\tinfo.osName ??\n\t\t\t`${readOsPrettyName() ?? os.type()} ${os.arch()}`,\n\t\tkernel: shellProps?.kernel ?? info.kernel ?? os.release(),\n\t\tuptimeSeconds: info.uptimeSeconds ?? os.uptime(),\n\t\tpackages: info.packages ?? resolvePackagesLabel(),\n\t\tshell: resolveShellLabel(info.shell),\n\t\tshellProps: (info.shellProps as ShellProperties) ?? {\n\t\t\tkernel: info.kernel ?? os.release(),\n\t\t\tos: info.osName ?? `${readOsPrettyName() ?? os.type()} ${os.arch()}`,\n\t\t\tarch: os.arch(),\n\t\t},\n\t\tresolution: info.resolution ?? \"n/a (ssh)\",\n\t\tterminal: info.terminal ?? \"unknown\",\n\t\tcpu: info.cpu ?? resolveCpuLabel(),\n\t\tgpu: info.gpu ?? \"n/a\",\n\t\tmemoryUsedMiB: info.memoryUsedMiB ?? toMiB(usedMem),\n\t\tmemoryTotalMiB: info.memoryTotalMiB ?? toMiB(totalMem),\n\t};\n}\n\nexport function buildNeofetchOutput(info: NeofetchInfo): string {\n\tconst fields = resolveDefaults(info);\n\tconst uptime = formatUptime(fields.uptimeSeconds);\n\tconst colorBars = buildColorBars();\n\n\tconst distroLogo = [\n\t\t\" .. .:. \",\n\t\t\" .::.. .. .. \",\n\t\t\". .... ... .. \",\n\t\t\": .... .:. .. \",\n\t\t\": .:.:........:. .. \",\n\t\t\": .. \",\n\t\t\". : \",\n\t\t\". : \",\n\t\t\".. : \",\n\t\t\" :. .. \",\n\t\t\" .. .. \",\n\t\t\" :-. :: \",\n\t\t\" .:. :. \",\n\t\t\" ..: ... \",\n\t\t\" ..: :.. \",\n\t\t\" :... :....\",\n\t\t\" .. ....\",\n\t\t\" . .. \",\n\t\t\" .:. .: \",\n\t\t\" :. .. \",\n\t\t\" ::. .. \",\n\t\t\"..... ..:... \",\n\t\t\"...:. .. \",\n\t\t\".:...:. ::. .. \",\n\t\t\" ... ..:::::.. ..:::::::.. \",\n\t];\n\n\tconst details = [\n\t\t`${fields.user}@${fields.host}`,\n\t\t\"-------------------------\",\n\t\t`OS: ${fields.osName}`,\n\t\t`Host: ${resolveHostLabel(fields.host)}`,\n\t\t`Kernel: ${fields.kernel}`,\n\t\t`Uptime: ${uptime}`,\n\t\t// `Packages: ${fields.packages}`,\n\t\t`Packages: ${fields.packages}`,\n\t\t`Shell: ${fields.shell}`,\n\t\t// `Shell Props: ${fields.shellProps}`,\n\t\t`Resolution: ${fields.resolution}`,\n\t\t`Terminal: ${fields.terminal}`,\n\t\t`CPU: ${fields.cpu}`,\n\t\t`GPU: ${fields.gpu}`,\n\t\t`Memory: ${fields.memoryUsedMiB}MiB / ${fields.memoryTotalMiB}MiB`,\n\t\t\"\",\n\t\tcolorBars[0],\n\t\tcolorBars[1],\n\t];\n\n\tconst width = Math.max(distroLogo.length, details.length);\n\tconst lines: string[] = [];\n\n\tfor (let i = 0; i < width; i += 1) {\n\t\tconst rawLeft = distroLogo[i] ?? \"\";\n\t\tconst right = details[i] ?? \"\";\n\t\tif (right.length > 0) {\n\t\t\tconst left = colorizeLogoLine(\n\t\t\t\trawLeft.padEnd(31, \" \"),\n\t\t\t\ti,\n\t\t\t\tdistroLogo.length,\n\t\t\t);\n\t\t\tconst coloredRight = colorizeDetailLine(right);\n\t\t\tlines.push(`${left} ${coloredRight}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tlines.push(colorizeLogoLine(rawLeft, i, distroLogo.length));\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n", "/** biome-ignore-all lint/style/useNamingConvention: env variables */\nimport type { ShellModule } from \"../types/commands\";\n\n// Legacy global store kept for compatibility with older callers\nconst _globalEnv: Record<string, string> = {\n\tPATH: \"/usr/local/bin:/usr/bin:/bin\",\n\tHOME: \"/home/user\",\n\tSHELL: \"/bin/sh\",\n\tTERM: \"xterm-256color\",\n\tUSER: \"user\",\n};\n\n/** @deprecated use env.vars from CommandContext */\nexport function getEnvVar(name: string): string | undefined {\n\treturn _globalEnv[name];\n}\n/** @deprecated use env.vars from CommandContext */\nexport function setEnvVar(name: string, value: string): void {\n\t_globalEnv[name] = value;\n}\n/** @deprecated use env.vars from CommandContext */\nexport function getAllEnvVars(authUser: string): Record<string, string> {\n\t_globalEnv.USER = authUser;\n\t_globalEnv.HOME = `/home/${authUser}`;\n\treturn { ..._globalEnv };\n}\n\nexport const setCommand: ShellModule = {\n\tname: \"set\",\n\tdescription: \"Display or set shell variables\",\n\tcategory: \"shell\",\n\tparams: [\"[VAR=value]\"],\n\trun: ({ args, env }) => {\n\t\tif (args.length === 0) {\n\t\t\tconst out = Object.entries(env.vars)\n\t\t\t\t.map(([k, v]) => `${k}=${v}`)\n\t\t\t\t.join(\"\\n\");\n\t\t\treturn { stdout: out, exitCode: 0 };\n\t\t}\n\t\tfor (const arg of args) {\n\t\t\tif (arg.includes(\"=\")) {\n\t\t\t\tconst eq = arg.indexOf(\"=\");\n\t\t\t\tenv.vars[arg.slice(0, eq)] = arg.slice(eq + 1);\n\t\t\t}\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import { buildNeofetchOutput } from \"../modules/neofetch\";\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { getAllEnvVars } from \"./set\";\n\nexport const neofetchCommand: ShellModule = {\n\tname: \"neofetch\",\n\tdescription: \"System info display\",\n\tcategory: \"system\",\n\tparams: [\"[--off]\"],\n\trun: ({ args, authUser, hostname, shell }) => {\n\t\tconst env = getAllEnvVars(authUser);\n\n\t\tif (ifFlag(args, \"--help\")) {\n\t\t\treturn {\n\t\t\t\tstdout: \"Usage: neofetch [--off]\",\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tif (ifFlag(args, \"--off\")) {\n\t\t\treturn {\n\t\t\t\tstdout: `${authUser}@${hostname}`,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstdout: buildNeofetchOutput({\n\t\t\t\tuser: authUser,\n\t\t\t\thost: hostname,\n\t\t\t\tshell: env.SHELL,\n\t\t\t\tshellProps: shell.properties,\n\t\t\t\tterminal: env.TERM,\n\t\t\t\tuptimeSeconds: Math.floor((Date.now() - shell.startTime) / 1000),\n\t\t\t\tpackages: (() => {\n\t\t\t\t\tconst count = shell.packageManager?.installedCount() ?? 0;\n\t\t\t\t\treturn `${count} (dpkg)`;\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "/** biome-ignore-all lint/style/useNamingConvention: node globals and ENV VAR KEYS */\n/**\n * node.ts \u2014 Virtual Node.js runtime.\n *\n * Uses `node:vm` for sandboxed evaluation with a controlled context that\n * intercepts `process`, `require`, `console`, and all standard globals.\n * No host filesystem access, no network, no child processes.\n */\nimport vm from \"node:vm\";\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nconst VIRTUAL_VERSION = \"v18.19.0\";\nconst VIRTUAL_VERSIONS = {\n\tnode: VIRTUAL_VERSION,\n\tnpm: \"9.2.0\",\n\tv8: \"10.2.154.26-node.22\",\n};\n\n// \u2500\u2500\u2500 sandbox context \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction makeContext(outputLines: string[], stderrLines: string[]) {\n\tconst fakeProcess = {\n\t\tversion: VIRTUAL_VERSION,\n\t\tversions: VIRTUAL_VERSIONS,\n\t\tplatform: \"linux\",\n\t\tarch: \"x64\",\n\t\tenv: {\n\t\t\tNODE_ENV: \"production\",\n\t\t\tHOME: \"/root\",\n\t\t\tPATH: \"/usr/local/bin:/usr/bin:/bin\",\n\t\t},\n\t\targv: [\"node\"],\n\t\tstdout: {\n\t\t\twrite: (s: string) => {\n\t\t\t\toutputLines.push(s);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t},\n\t\tstderr: {\n\t\t\twrite: (s: string) => {\n\t\t\t\tstderrLines.push(s);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t},\n\t\texit: (code = 0) => {\n\t\t\tthrow new ExitSignal(code);\n\t\t},\n\t\tcwd: () => \"/root\",\n\t\thrtime: () => [0, 0],\n\t};\n\n\tconst fakeConsole = {\n\t\tlog: (...a: unknown[]) => outputLines.push(a.map(formatValue).join(\" \")),\n\t\terror: (...a: unknown[]) => stderrLines.push(a.map(formatValue).join(\" \")),\n\t\twarn: (...a: unknown[]) => stderrLines.push(a.map(formatValue).join(\" \")),\n\t\tinfo: (...a: unknown[]) => outputLines.push(a.map(formatValue).join(\" \")),\n\t\tdir: (v: unknown) => outputLines.push(formatValue(v)),\n\t};\n\n\tconst fakeRequire = (mod: string): unknown => {\n\t\t// Provide stubs for common modules\n\t\tswitch (mod) {\n\t\t\tcase \"path\":\n\t\t\t\treturn {\n\t\t\t\t\tjoin: (...parts: string[]) => parts.join(\"/\").replace(/\\/+/g, \"/\"),\n\t\t\t\t\tresolve: (...parts: string[]) =>\n\t\t\t\t\t\t`/${parts.join(\"/\").replace(/^\\/+/, \"\")}`,\n\t\t\t\t\tdirname: (p: string) => p.split(\"/\").slice(0, -1).join(\"/\") || \"/\",\n\t\t\t\t\tbasename: (p: string) => p.split(\"/\").pop() ?? \"\",\n\t\t\t\t\textname: (p: string) => {\n\t\t\t\t\t\tconst b = p.split(\"/\").pop() ?? \"\";\n\t\t\t\t\t\tconst d = b.lastIndexOf(\".\");\n\t\t\t\t\t\treturn d > 0 ? b.slice(d) : \"\";\n\t\t\t\t\t},\n\t\t\t\t\tsep: \"/\",\n\t\t\t\t\tdelimiter: \":\",\n\t\t\t\t};\n\t\t\tcase \"os\":\n\t\t\t\treturn {\n\t\t\t\t\tplatform: () => \"linux\",\n\t\t\t\t\tarch: () => \"x64\",\n\t\t\t\t\ttype: () => \"Linux\",\n\t\t\t\t\thostname: () => \"fortune-vm\",\n\t\t\t\t\thomedir: () => \"/root\",\n\t\t\t\t\ttmpdir: () => \"/tmp\",\n\t\t\t\t\tEOL: \"\\n\",\n\t\t\t\t};\n\t\t\tcase \"util\":\n\t\t\t\treturn {\n\t\t\t\t\tformat: (...a: unknown[]) => a.map(formatValue).join(\" \"),\n\t\t\t\t\tinspect: (v: unknown) => formatValue(v),\n\t\t\t\t};\n\t\t\tcase \"fs\":\n\t\t\tcase \"fs/promises\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot require '${mod}': filesystem access not available in virtual runtime`,\n\t\t\t\t);\n\t\t\tcase \"child_process\":\n\t\t\tcase \"net\":\n\t\t\tcase \"http\":\n\t\t\tcase \"https\":\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot require '${mod}': not available in virtual runtime`,\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Cannot find module '${mod}'`);\n\t\t}\n\t};\n\tfakeRequire.resolve = (id: string) => {\n\t\tthrow new Error(`Cannot resolve '${id}'`);\n\t};\n\tfakeRequire.cache = {};\n\tfakeRequire.extensions = {};\n\n\treturn vm.createContext({\n\t\t// Core globals\n\t\tconsole: fakeConsole,\n\t\tprocess: fakeProcess,\n\t\trequire: fakeRequire,\n\n\t\t// JS built-ins\n\t\tMath,\n\t\tJSON,\n\t\tObject,\n\t\tArray,\n\t\tString,\n\t\tNumber,\n\t\tBoolean,\n\t\tSymbol,\n\t\tDate,\n\t\tRegExp,\n\t\tError,\n\t\tTypeError,\n\t\tRangeError,\n\t\tSyntaxError,\n\t\tPromise,\n\t\tMap,\n\t\tSet,\n\t\tWeakMap,\n\t\tWeakSet,\n\t\tparseInt,\n\t\tparseFloat,\n\t\tisNaN,\n\t\tisFinite,\n\t\tencodeURIComponent,\n\t\tdecodeURIComponent,\n\t\tencodeURI,\n\t\tdecodeURI,\n\t\tsetTimeout: () => {},\n\t\tclearTimeout: () => {},\n\t\tsetInterval: () => {},\n\t\tclearInterval: () => {},\n\t\tqueueMicrotask: () => {},\n\t\tglobalThis: undefined as unknown, // set below\n\t\tundefined,\n\t\tInfinity,\n\t\tNaN,\n\t});\n}\n\nclass ExitSignal {\n\tconstructor(public readonly code: number) {}\n}\n\nfunction formatValue(v: unknown): string {\n\tif (v === null) return \"null\";\n\tif (v === undefined) return \"undefined\";\n\tif (typeof v === \"string\") return v;\n\tif (typeof v === \"function\") return `[Function: ${v.name || \"(anonymous)\"}]`;\n\tif (Array.isArray(v)) return `[ ${v.map(formatValue).join(\", \")} ]`;\n\tif (v instanceof Error) return `${v.name}: ${v.message}`;\n\tif (typeof v === \"object\") {\n\t\ttry {\n\t\t\tconst entries = Object.entries(v as Record<string, unknown>)\n\t\t\t\t.map(([k, val]) => `${k}: ${formatValue(val)}`)\n\t\t\t\t.join(\", \");\n\t\t\treturn `{ ${entries} }`;\n\t\t} catch {\n\t\t\treturn \"[Object]\";\n\t\t}\n\t}\n\treturn String(v);\n}\n\n// \u2500\u2500\u2500 execution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction runJs(code: string): {\n\tstdout: string;\n\tstderr: string;\n\texitCode: number;\n} {\n\tconst outputLines: string[] = [];\n\tconst stderrLines: string[] = [];\n\tconst ctx = makeContext(outputLines, stderrLines);\n\n\tlet exitCode = 0;\n\n\ttry {\n\t\tconst result = vm.runInContext(code, ctx, { timeout: 5000 });\n\t\t// If the expression returned a value and nothing was console.log'd, print it\n\t\tif (result !== undefined && outputLines.length === 0) {\n\t\t\toutputLines.push(formatValue(result));\n\t\t}\n\t} catch (err) {\n\t\tif (err instanceof ExitSignal) {\n\t\t\texitCode = err.code;\n\t\t} else if (err instanceof Error) {\n\t\t\tstderrLines.push(`${err.name}: ${err.message}`);\n\t\t\texitCode = 1;\n\t\t} else {\n\t\t\tstderrLines.push(String(err));\n\t\t\texitCode = 1;\n\t\t}\n\t}\n\n\treturn {\n\t\tstdout: outputLines.length ? `${outputLines.join(\"\\n\")}\\n` : \"\",\n\t\tstderr: stderrLines.length ? `${stderrLines.join(\"\\n\")}\\n` : \"\",\n\t\texitCode,\n\t};\n}\n\nfunction runJsFile(code: string): {\n\tstdout: string;\n\tstderr: string;\n\texitCode: number;\n} {\n\t// If the code is a single expression (no semicolons, no newlines, no statements),\n\t// wrap it to capture the return value like a REPL would\n\tconst trimmed = code.trim();\n\tconst isExpression =\n\t\t!trimmed.includes(\"\\n\") &&\n\t\t!trimmed.startsWith(\"const \") &&\n\t\t!trimmed.startsWith(\"let \") &&\n\t\t!trimmed.startsWith(\"var \") &&\n\t\t!trimmed.startsWith(\"function \") &&\n\t\t!trimmed.startsWith(\"class \") &&\n\t\t!trimmed.startsWith(\"if \") &&\n\t\t!trimmed.startsWith(\"for \") &&\n\t\t!trimmed.startsWith(\"while \") &&\n\t\t!trimmed.startsWith(\"import \") &&\n\t\t!trimmed.startsWith(\"//\");\n\n\tif (isExpression) return runJs(trimmed);\n\n\t// Multi-line: wrap in IIFE\n\treturn runJs(`(async () => { ${code} })()`);\n}\n\n// \u2500\u2500\u2500 command \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n/**\n * `node` virtual runtime command. Executes JS in a safe sandbox with\n * limited globals and no host FS/child process access.\n * @category system\n * @params []\n */\nexport const nodeCommand: ShellModule = {\n\tname: \"node\",\n\tdescription: \"JavaScript runtime (virtual)\",\n\tcategory: \"system\",\n\tparams: [\"[--version] [-e <expr>] [-p <expr>] [file]\"],\n\trun: ({ args, shell, cwd }) => {\n\t\t// Require explicit installation via `apt install nodejs`\n\t\tif (!shell.packageManager.isInstalled(\"nodejs\")) {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"bash: node: command not found\\nHint: install it with: apt install nodejs\\n\",\n\t\t\t\texitCode: 127,\n\t\t\t};\n\t\t}\n\t\tif (ifFlag(args, [\"--version\", \"-v\"])) {\n\t\t\treturn { stdout: `${VIRTUAL_VERSION}\\n`, exitCode: 0 };\n\t\t}\n\n\t\tif (ifFlag(args, [\"--versions\"])) {\n\t\t\treturn {\n\t\t\t\tstdout: `${JSON.stringify(VIRTUAL_VERSIONS, null, 2)}\\n`,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\t// -e 'expr'\n\t\tconst eIdx = args.findIndex((a) => a === \"-e\" || a === \"--eval\");\n\t\tif (eIdx !== -1) {\n\t\t\tconst expr = args[eIdx + 1];\n\t\t\tif (!expr)\n\t\t\t\treturn { stderr: \"node: -e requires an argument\\n\", exitCode: 1 };\n\t\t\tconst { stdout, stderr, exitCode } = runJs(expr);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || undefined,\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\t// -p 'expr' \u2014 print mode\n\t\tconst pIdx = args.findIndex((a) => a === \"-p\" || a === \"--print\");\n\t\tif (pIdx !== -1) {\n\t\t\tconst expr = args[pIdx + 1];\n\t\t\tif (!expr)\n\t\t\t\treturn { stderr: \"node: -p requires an argument\\n\", exitCode: 1 };\n\t\t\tconst { stdout, stderr, exitCode } = runJs(expr);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || (exitCode === 0 ? \"\\n\" : undefined),\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\t// node <file>\n\t\tconst file = args.find((a) => !a.startsWith(\"-\"));\n\t\tif (file) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\tif (!shell.vfs.exists(filePath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `node: cannot open file '${file}': No such file or directory\\n`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst code = shell.vfs.readFile(filePath);\n\t\t\tconst { stdout, stderr, exitCode } = runJsFile(code);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || undefined,\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\t// No args \u2014 REPL hint\n\t\treturn {\n\t\t\tstdout: [\n\t\t\t\t`Welcome to Node.js ${VIRTUAL_VERSION}.`,\n\t\t\t\t`Type \".exit\" to exit the REPL.`,\n\t\t\t\t`> `,\n\t\t\t].join(\"\\n\"),\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "/**\n * npm.ts \u2014 Virtual npm command.\n * Gated behind `apt install npm`. Provides version info and informative\n * stubs for common subcommands.\n */\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nconst NPM_VERSION = \"9.2.0\";\nconst NODE_VERSION = \"18.19.0\";\n\n/**\n * `npm` virtual CLI. Requires `apt install npm` in the virtual package manager.\n * @category system\n * @params [\"<command> [args]\"]\n */\nexport const npmCommand: ShellModule = {\n\tname: \"npm\",\n\tdescription: \"Node.js package manager (virtual)\",\n\tcategory: \"system\",\n\tparams: [\"<command> [args]\"],\n\trun: ({ args, shell }) => {\n\t\t// Require explicit installation\n\t\tif (!shell.packageManager.isInstalled(\"npm\")) {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"bash: npm: command not found\\nHint: install it with: apt install npm\\n\",\n\t\t\t\texitCode: 127,\n\t\t\t};\n\t\t}\n\n\t\tif (ifFlag(args, [\"--version\", \"-v\"])) {\n\t\t\treturn { stdout: `${NPM_VERSION}\\n`, exitCode: 0 };\n\t\t}\n\n\t\tconst sub = args[0]?.toLowerCase();\n\n\t\tswitch (sub) {\n\t\t\tcase \"version\":\n\t\t\tcase \"-version\":\n\t\t\t\treturn {\n\t\t\t\t\tstdout: `{ npm: '${NPM_VERSION}', node: '${NODE_VERSION}', v8: '10.2.154.26' }\\n`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\n\t\t\tcase \"install\":\n\t\t\tcase \"i\":\n\t\t\tcase \"add\":\n\t\t\t\treturn {\n\t\t\t\t\tstderr:\n\t\t\t\t\t\t\"npm warn: package installation is not available in the virtual runtime.\\nnpm warn: This environment simulates npm CLI behaviour only.\\n\",\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\n\t\t\tcase \"run\":\n\t\t\tcase \"exec\":\n\t\t\tcase \"x\":\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `npm error: script execution is not available in the virtual runtime.\\n`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\n\t\t\tcase \"init\":\n\t\t\t\treturn {\n\t\t\t\t\tstdout: \"Wrote to /home/user/package.json\\n\",\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\n\t\t\tcase \"list\":\n\t\t\tcase \"ls\":\n\t\t\t\treturn {\n\t\t\t\t\tstdout: `${sub === \"ls\" || sub === \"list\" ? \"virtual-env@1.0.0\" : \"\"}\\n\u2514\u2500\u2500 (empty)\\n`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\n\t\t\tcase \"help\":\n\t\t\tcase undefined:\n\t\t\t\treturn {\n\t\t\t\t\tstdout: `${[\n\t\t\t\t\t\t`npm ${NPM_VERSION}`,\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\"Usage: npm <command>\",\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\"Commands:\",\n\t\t\t\t\t\t\" install (not available in virtual runtime)\",\n\t\t\t\t\t\t\" run (not available in virtual runtime)\",\n\t\t\t\t\t\t\" exec (not available in virtual runtime)\",\n\t\t\t\t\t\t\" list List installed packages\",\n\t\t\t\t\t\t\" version Print versions\",\n\t\t\t\t\t\t\" --version Print npm version\",\n\t\t\t\t\t].join(\"\\n\")}\\n`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\n\t\t\tdefault:\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `npm error: unknown command: ${sub}\\n`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t}\n\t},\n};\n\n/**\n * `npx` virtual runner. Requires `apt install npm` in the virtual package manager.\n * @category system\n * @params [\"<package> [args]\"]\n */\nexport const npxCommand: ShellModule = {\n\tname: \"npx\",\n\tdescription: \"Node.js package runner (virtual)\",\n\tcategory: \"system\",\n\tparams: [\"<package> [args]\"],\n\trun: ({ args, shell }) => {\n\t\tif (!shell.packageManager.isInstalled(\"npm\")) {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"bash: npx: command not found\\nHint: install it with: apt install npm\\n\",\n\t\t\t\texitCode: 127,\n\t\t\t};\n\t\t}\n\n\t\tif (ifFlag(args, [\"--version\"])) {\n\t\t\treturn { stdout: `${NPM_VERSION}\\n`, exitCode: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\tstderr: `npx: package execution is not available in the virtual runtime.\\n`,\n\t\t\texitCode: 1,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const passwdCommand: ShellModule = {\n\tname: \"passwd\",\n\tdescription: \"Change user password\",\n\tcategory: \"users\",\n\tparams: [\"<username> <password>\"],\n\trun: async ({ authUser, args, shell }) => {\n\t\tconst [username, password] = args;\n\t\tif (!username || !password) {\n\t\t\treturn {\n\t\t\t\tstderr: \"passwd: usage: passwd <username> <password>\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\n\t\tif (authUser !== \"root\" && authUser !== username) {\n\t\t\treturn { stderr: \"passwd: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tawait shell.users.setPassword(username, password);\n\t\treturn {\n\t\t\tstdout: `passwd: password updated for '${username}'`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { parseArgs } from \"./command-helpers\";\n\nexport const pingCommand: ShellModule = {\n\tname: \"ping\",\n\tdescription: \"Send ICMP ECHO_REQUEST (mock)\",\n\tcategory: \"network\",\n\tparams: [\"[-c <count>] <host>\"],\n\trun: ({ args }) => {\n\t\tconst { flagsWithValues, positionals } = parseArgs(args, {\n\t\t\tflagsWithValue: [\"-c\", \"-i\", \"-W\"],\n\t\t});\n\t\tconst host = positionals[0] ?? \"localhost\";\n\t\tconst countArg = flagsWithValues.get(\"-c\");\n\t\tconst count = countArg ? Math.max(1, parseInt(countArg, 10) || 4) : 4;\n\t\tconst lines = [`PING ${host}: 56 data bytes`];\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst ms = (Math.random() * 10 + 1).toFixed(3);\n\t\t\tlines.push(`64 bytes from ${host}: icmp_seq=${i} ttl=64 time=${ms} ms`);\n\t\t}\n\t\tlines.push(`--- ${host} ping statistics ---`);\n\t\tlines.push(\n\t\t\t`${count} packets transmitted, ${count} received, 0% packet loss`,\n\t\t);\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Render a printf format string with given arguments.\n * Supports: %s %d %i %f %o %x %X %% \\n \\t \\r \\\\\n */\nfunction renderPrintf(fmt: string, args: string[]): string {\n\tlet argIdx = 0;\n\tlet out = \"\";\n\tlet i = 0;\n\twhile (i < fmt.length) {\n\t\tif (fmt[i] === \"\\\\\" && i + 1 < fmt.length) {\n\t\t\tswitch (fmt[i + 1]) {\n\t\t\t\tcase \"n\":\n\t\t\t\t\tout += \"\\n\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"t\":\n\t\t\t\t\tout += \"\\t\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"r\":\n\t\t\t\t\tout += \"\\r\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"\\\\\":\n\t\t\t\t\tout += \"\\\\\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"a\":\n\t\t\t\t\tout += \"\\x07\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tout += \"\\x08\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"f\":\n\t\t\t\t\tout += \"\\x0C\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"v\":\n\t\t\t\t\tout += \"\\x0B\";\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\tdefault:\n\t\t\t\t\tout += fmt[i]!;\n\t\t\t\t\ti++;\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (fmt[i] === \"%\" && i + 1 < fmt.length) {\n\t\t\t// Optional width/precision: %[-][width][.prec]spec\n\t\t\tlet j = i + 1;\n\t\t\tif (fmt[j] === \"-\") j++;\n\t\t\twhile (j < fmt.length && /\\d/.test(fmt[j]!)) j++;\n\t\t\tif (fmt[j] === \".\") {\n\t\t\t\tj++;\n\t\t\t\twhile (j < fmt.length && /\\d/.test(fmt[j]!)) j++;\n\t\t\t}\n\t\t\tconst spec = fmt[j];\n\t\t\tconst arg = args[argIdx++] ?? \"\";\n\t\t\tswitch (spec) {\n\t\t\t\tcase \"s\":\n\t\t\t\t\tout += arg;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"d\":\n\t\t\t\tcase \"i\":\n\t\t\t\t\tout += String(parseInt(arg, 10) || 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"f\":\n\t\t\t\t\tout += String(parseFloat(arg) || 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"o\":\n\t\t\t\t\tout += (parseInt(arg, 10) || 0).toString(8);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"x\":\n\t\t\t\t\tout += (parseInt(arg, 10) || 0).toString(16);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"X\":\n\t\t\t\t\tout += (parseInt(arg, 10) || 0).toString(16).toUpperCase();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"%\":\n\t\t\t\t\tout += \"%\";\n\t\t\t\t\targIdx--;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tout += fmt[i]!;\n\t\t\t\t\ti++;\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ti = j + 1;\n\t\t\tcontinue;\n\t\t}\n\t\tout += fmt[i]!;\n\t\ti++;\n\t}\n\treturn out;\n}\n\nexport const printfCommand: ShellModule = {\n\tname: \"printf\",\n\tdescription: \"Format and print data\",\n\tcategory: \"shell\",\n\tparams: [\"<format> [args...]\"],\n\trun: ({ args }) => {\n\t\tconst fmt = args[0];\n\t\tif (!fmt) return { stderr: \"printf: missing format string\", exitCode: 1 };\n\t\tconst output = renderPrintf(fmt, args.slice(1));\n\t\treturn { stdout: output, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const psCommand: ShellModule = {\n\tname: \"ps\",\n\tdescription: \"Report process status\",\n\tcategory: \"system\",\n\tparams: [\"[-a] [-u] [-x] [aux]\"],\n\trun: ({ authUser, shell, args }) => {\n\t\tconst sessions = shell.users.listActiveSessions();\n\t\tconst showUser =\n\t\t\tifFlag(args, [\"-u\"]) ||\n\t\t\targs.includes(\"u\") ||\n\t\t\targs.includes(\"aux\") ||\n\t\t\targs.includes(\"au\");\n\t\tconst showAll =\n\t\t\tifFlag(args, [\"-a\", \"-x\"]) || args.includes(\"a\") || args.includes(\"aux\");\n\n\t\tif (showUser) {\n\t\t\tconst header =\n\t\t\t\t\"USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND\";\n\t\t\tconst rows: string[] = [header];\n\t\t\tlet pid = 1000;\n\t\t\tfor (const s of sessions) {\n\t\t\t\tconst user = s.username.padEnd(10).slice(0, 10);\n\t\t\t\tconst mem = (Math.random() * 0.5).toFixed(1);\n\t\t\t\tconst vsz = Math.floor(Math.random() * 20000 + 5000);\n\t\t\t\tconst rss = Math.floor(Math.random() * 5000 + 1000);\n\t\t\t\trows.push(\n\t\t\t\t\t`${user} ${String(pid).padStart(6)} 0.0 ${mem.padStart(4)} ${String(vsz).padStart(6)} ${String(rss).padStart(5)} ${s.tty.padEnd(8)} Ss 00:00 0:00 bash`,\n\t\t\t\t);\n\t\t\t\tpid++;\n\t\t\t}\n\t\t\trows.push(\n\t\t\t\t`root ${String(pid).padStart(6)} 0.0 0.0 0 0 ? S 00:00 0:00 ps`,\n\t\t\t);\n\t\t\treturn { stdout: rows.join(\"\\n\"), exitCode: 0 };\n\t\t}\n\n\t\tconst header = \" PID TTY TIME CMD\";\n\t\tconst rows: string[] = [header];\n\t\tlet pid = 1000;\n\t\tfor (const s of sessions) {\n\t\t\tif (!showAll && s.username !== authUser) continue;\n\t\t\trows.push(\n\t\t\t\t`${String(pid).padStart(5)} ${s.tty.padEnd(12)} 00:00:00 ${s.username === authUser ? \"bash\" : `bash (${s.username})`}`,\n\t\t\t);\n\t\t\tpid++;\n\t\t}\n\t\trows.push(`${String(pid).padStart(5)} pts/0 00:00:00 ps`);\n\t\treturn { stdout: rows.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const pwdCommand: ShellModule = {\n\tname: \"pwd\",\n\tdescription: \"Print working directory\",\n\tcategory: \"navigation\",\n\tparams: [],\n\trun: ({ cwd }) => ({ stdout: cwd, exitCode: 0 }),\n};\n", "/** biome-ignore-all lint/suspicious/useIterableCallbackReturn: intentional side-effect forEach */\n/**\n * python.ts \u2014 Virtual Python 3 interpreter.\n *\n * Implements a genuine mini-interpreter capable of:\n * - print(), len(), type(), range(), list(), str(), int(), float(), bool()\n * - max(), min(), abs(), sum(), sorted(), reversed(), enumerate(), zip()\n * - str methods: upper(), lower(), strip(), split(), join(), replace(),\n * startswith(), endswith(), format(), count(), find()\n * - list methods: append(), extend(), pop(), sort(), reverse(), index()\n * - dict: keys(), values(), items(), get()\n * - import os, sys, math, json, re (stubs)\n * - f-strings, multi-line scripts, assignments, for/while loops, if/elif/else\n * - functions (def), return, class basics\n */\nimport type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nconst VERSION = \"Python 3.11.2\";\nconst _VERSION_SHORT = \"3.11.2\";\nconst VERSION_INFO = \"3.11.2 (default, Mar 13 2023, 12:18:29) [GCC 12.2.0]\";\n\n// \u2500\u2500\u2500 Python value type \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype PyVal =\n\t| null\n\t| boolean\n\t| number\n\t| string\n\t| PyVal[]\n\t| PyDict\n\t| PyRange\n\t| PyFunc\n\t| PyClass\n\t| PyInstance\n\t| PyNone;\ntype PyDict = { __pytype__: \"dict\"; data: Map<string, PyVal> };\ntype PyRange = {\n\t__pytype__: \"range\";\n\tstart: number;\n\tstop: number;\n\tstep: number;\n};\ntype PyFunc = {\n\t__pytype__: \"func\";\n\tname: string;\n\tparams: string[];\n\tbody: string[];\n\tclosure: Scope;\n};\ntype PyClass = {\n\t__pytype__: \"class\";\n\tname: string;\n\tmethods: Map<string, PyFunc>;\n\tbases: string[];\n};\ntype PyInstance = {\n\t__pytype__: \"instance\";\n\tcls: PyClass;\n\tattrs: Map<string, PyVal>;\n};\ntype PyNone = { __pytype__: \"none\" };\n\nconst NONE: PyNone = { __pytype__: \"none\" };\n\nfunction pyDict(entries: [string, PyVal][] = []): PyDict {\n\treturn { __pytype__: \"dict\", data: new Map(entries) };\n}\nfunction pyRange(start: number, stop: number, step = 1): PyRange {\n\treturn { __pytype__: \"range\", start, stop, step };\n}\n\nfunction isPyDict(v: PyVal): v is PyDict {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyDict).__pytype__ === \"dict\"\n\t);\n}\nfunction isPyRange(v: PyVal): v is PyRange {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyRange).__pytype__ === \"range\"\n\t);\n}\nfunction isPyFunc(v: PyVal): v is PyFunc {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyFunc).__pytype__ === \"func\"\n\t);\n}\nfunction isPyClass(v: PyVal): v is PyClass {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyClass).__pytype__ === \"class\"\n\t);\n}\nfunction isPyInstance(v: PyVal): v is PyInstance {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyInstance).__pytype__ === \"instance\"\n\t);\n}\nfunction isPyNone(v: PyVal): v is PyNone {\n\treturn (\n\t\t!!v &&\n\t\ttypeof v === \"object\" &&\n\t\t!Array.isArray(v) &&\n\t\t(v as PyNone).__pytype__ === \"none\"\n\t);\n}\n\n// \u2500\u2500\u2500 repr / str \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction pyRepr(v: PyVal): string {\n\tif (v === null || isPyNone(v)) return \"None\";\n\tif (v === true) return \"True\";\n\tif (v === false) return \"False\";\n\tif (typeof v === \"number\")\n\t\treturn Number.isInteger(v)\n\t\t\t? String(v)\n\t\t\t: v.toPrecision(12).replace(/\\.?0+$/, \"\");\n\tif (typeof v === \"string\") return `'${v.replace(/'/g, \"\\\\'\")}'`;\n\tif (Array.isArray(v)) return `[${v.map(pyRepr).join(\", \")}]`;\n\tif (isPyDict(v))\n\t\treturn `{${[...v.data.entries()].map(([k, val]) => `'${k}': ${pyRepr(val)}`).join(\", \")}}`;\n\tif (isPyRange(v))\n\t\treturn `range(${v.start}, ${v.stop}${v.step !== 1 ? `, ${v.step}` : \"\"})`;\n\tif (isPyFunc(v)) return `<function ${v.name} at 0x...>`;\n\tif (isPyClass(v)) return `<class '${v.name}'>`;\n\tif (isPyInstance(v)) return `<${v.cls.name} object at 0x...>`;\n\treturn String(v);\n}\n\nfunction pyStr(v: PyVal): string {\n\tif (v === null || isPyNone(v)) return \"None\";\n\tif (v === true) return \"True\";\n\tif (v === false) return \"False\";\n\tif (typeof v === \"number\")\n\t\treturn Number.isInteger(v)\n\t\t\t? String(v)\n\t\t\t: v.toPrecision(12).replace(/\\.?0+$/, \"\");\n\tif (typeof v === \"string\") return v;\n\tif (Array.isArray(v)) return `[${v.map(pyRepr).join(\", \")}]`;\n\tif (isPyDict(v))\n\t\treturn `{${[...v.data.entries()].map(([k, val]) => `'${k}': ${pyRepr(val)}`).join(\", \")}}`;\n\tif (isPyRange(v))\n\t\treturn `range(${v.start}, ${v.stop}${v.step !== 1 ? `, ${v.step}` : \"\"})`;\n\treturn pyRepr(v);\n}\n\nfunction pyBool(v: PyVal): boolean {\n\tif (v === null || isPyNone(v)) return false;\n\tif (typeof v === \"boolean\") return v;\n\tif (typeof v === \"number\") return v !== 0;\n\tif (typeof v === \"string\") return v.length > 0;\n\tif (Array.isArray(v)) return v.length > 0;\n\tif (isPyDict(v)) return v.data.size > 0;\n\tif (isPyRange(v)) return pyRangeLength(v) > 0;\n\treturn true;\n}\n\nfunction pyRangeLength(r: PyRange): number {\n\tif (r.step === 0) return 0;\n\tconst n = Math.ceil((r.stop - r.start) / r.step);\n\treturn Math.max(0, n);\n}\n\nfunction pyRangeItems(r: PyRange): number[] {\n\tconst items: number[] = [];\n\tfor (let i = r.start; r.step > 0 ? i < r.stop : i > r.stop; i += r.step) {\n\t\titems.push(i);\n\t\tif (items.length > 10000) break;\n\t}\n\treturn items;\n}\n\nfunction pyIter(v: PyVal): PyVal[] {\n\tif (Array.isArray(v)) return v;\n\tif (typeof v === \"string\") return [...v];\n\tif (isPyRange(v)) return pyRangeItems(v);\n\tif (isPyDict(v)) return [...v.data.keys()];\n\tthrow new PyError(\"TypeError\", `'${pyTypeName(v)}' object is not iterable`);\n}\n\nfunction pyTypeName(v: PyVal): string {\n\tif (v === null || isPyNone(v)) return \"NoneType\";\n\tif (typeof v === \"boolean\") return \"bool\";\n\tif (typeof v === \"number\") return Number.isInteger(v) ? \"int\" : \"float\";\n\tif (typeof v === \"string\") return \"str\";\n\tif (Array.isArray(v)) return \"list\";\n\tif (isPyDict(v)) return \"dict\";\n\tif (isPyRange(v)) return \"range\";\n\tif (isPyFunc(v)) return \"function\";\n\tif (isPyClass(v)) return \"type\";\n\tif (isPyInstance(v)) return v.cls.name;\n\treturn \"object\";\n}\n\nclass PyError {\n\tconstructor(\n\t\tpublic type: string,\n\t\tpublic message: string,\n\t) {}\n\ttoString() {\n\t\treturn `${this.type}: ${this.message}`;\n\t}\n}\nclass ReturnSignal {\n\tconstructor(public value: PyVal) {}\n}\nclass BreakSignal {}\nclass ContinueSignal {}\nclass ExitSignal {\n\tconstructor(public code: number) {}\n}\n\n// \u2500\u2500\u2500 scope \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype Scope = Map<string, PyVal>;\n\nfunction makeRootScope(cwd: string): Scope {\n\tconst scope = new Map<string, PyVal>();\n\n\t// Built-in modules (lazy)\n\tconst osModule = pyDict([\n\t\t[\"sep\", \"/\"],\n\t\t[\"linesep\", \"\\n\"],\n\t\t[\"curdir\", \".\"],\n\t\t[\"pardir\", \"..\"],\n\t]);\n\t(osModule as unknown as Record<string, PyVal>).__methods__ = {\n\t\tgetcwd: () => cwd,\n\t\tgetenv: (k: PyVal) =>\n\t\t\ttypeof k === \"string\" ? (process.env[k] ?? NONE) : NONE,\n\t\tpath: pyDict([\n\t\t\t[\"join\", NONE],\n\t\t\t[\"exists\", NONE],\n\t\t\t[\"dirname\", NONE],\n\t\t\t[\"basename\", NONE],\n\t\t]),\n\t\tlistdir: () => [],\n\t} as unknown as PyVal;\n\n\tscope.set(\"__builtins__\", NONE);\n\tscope.set(\"__name__\", \"__main__\");\n\tscope.set(\"__cwd__\", cwd);\n\n\treturn scope;\n}\n\n// \u2500\u2500\u2500 built-in modules \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction makeOsModule(cwd: string): PyDict {\n\tconst path = pyDict([\n\t\t[\"sep\", \"/\"],\n\t\t[\"curdir\", \".\"],\n\t]);\n\tconst os = pyDict([\n\t\t[\"sep\", \"/\"],\n\t\t[\"linesep\", \"\\n\"],\n\t\t[\"name\", \"posix\"],\n\t]);\n\t// We'll handle method calls in callMethod\n\t(os as unknown as { _cwd: string })._cwd = cwd;\n\t(path as unknown as { _cwd: string })._cwd = cwd;\n\t(os as unknown as { path: PyDict }).path = path;\n\treturn os;\n}\n\nfunction makeSysModule(): PyDict {\n\treturn pyDict([\n\t\t[\"version\", VERSION_INFO],\n\t\t[\n\t\t\t\"version_info\",\n\t\t\tpyDict(\n\t\t\t\t[\n\t\t\t\t\t[\"major\", 3],\n\t\t\t\t\t[\"minor\", 11],\n\t\t\t\t\t[\"micro\", 2],\n\t\t\t\t].map(([k, v]) => [k as string, v as number]),\n\t\t\t),\n\t\t],\n\t\t[\"platform\", \"linux\"],\n\t\t[\"executable\", \"/usr/bin/python3\"],\n\t\t[\"prefix\", \"/usr\"],\n\t\t[\"path\", [\"/usr/lib/python3.11\", \"/usr/lib/python3.11/lib-dynload\"]],\n\t\t[\"argv\", [\"\"]],\n\t\t[\"maxsize\", 9007199254740991],\n\t]);\n}\n\nfunction makeMathModule(): PyDict {\n\treturn pyDict([\n\t\t[\"pi\", Math.PI],\n\t\t[\"e\", Math.E],\n\t\t[\"tau\", Math.PI * 2],\n\t\t[\"inf\", Infinity],\n\t\t[\"nan\", NaN],\n\t\t[\"sqrt\", NONE],\n\t\t[\"floor\", NONE],\n\t\t[\"ceil\", NONE],\n\t\t[\"log\", NONE],\n\t\t[\"pow\", NONE],\n\t\t[\"sin\", NONE],\n\t\t[\"cos\", NONE],\n\t\t[\"tan\", NONE],\n\t\t[\"fabs\", NONE],\n\t\t[\"factorial\", NONE],\n\t]);\n}\n\nfunction makeJsonModule(): PyDict {\n\treturn pyDict([\n\t\t[\"dumps\", NONE],\n\t\t[\"loads\", NONE],\n\t]);\n}\n\nfunction makeReModule(): PyDict {\n\treturn pyDict([\n\t\t[\"match\", NONE],\n\t\t[\"search\", NONE],\n\t\t[\"findall\", NONE],\n\t\t[\"sub\", NONE],\n\t\t[\"split\", NONE],\n\t\t[\"compile\", NONE],\n\t]);\n}\n\nconst MODULE_FACTORIES: Record<string, (cwd: string) => PyDict> = {\n\tos: makeOsModule,\n\tsys: () => makeSysModule(),\n\tmath: () => makeMathModule(),\n\tjson: () => makeJsonModule(),\n\tre: () => makeReModule(),\n\trandom: () =>\n\t\tpyDict([\n\t\t\t[\"random\", NONE],\n\t\t\t[\"randint\", NONE],\n\t\t\t[\"choice\", NONE],\n\t\t\t[\"shuffle\", NONE],\n\t\t]),\n\ttime: () =>\n\t\tpyDict([\n\t\t\t[\"time\", NONE],\n\t\t\t[\"sleep\", NONE],\n\t\t\t[\"ctime\", NONE],\n\t\t]),\n\tdatetime: () =>\n\t\tpyDict([\n\t\t\t[\"datetime\", NONE],\n\t\t\t[\"date\", NONE],\n\t\t\t[\"timedelta\", NONE],\n\t\t]),\n\tcollections: () =>\n\t\tpyDict([\n\t\t\t[\"Counter\", NONE],\n\t\t\t[\"defaultdict\", NONE],\n\t\t\t[\"OrderedDict\", NONE],\n\t\t]),\n\titertools: () =>\n\t\tpyDict([\n\t\t\t[\"chain\", NONE],\n\t\t\t[\"product\", NONE],\n\t\t\t[\"combinations\", NONE],\n\t\t\t[\"permutations\", NONE],\n\t\t]),\n\tfunctools: () =>\n\t\tpyDict([\n\t\t\t[\"reduce\", NONE],\n\t\t\t[\"partial\", NONE],\n\t\t\t[\"lru_cache\", NONE],\n\t\t]),\n\tstring: () =>\n\t\tpyDict([\n\t\t\t[\"ascii_letters\", \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"],\n\t\t\t[\"digits\", \"0123456789\"],\n\t\t\t[\"punctuation\", \"!\\\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~\"],\n\t\t]),\n};\n\n// \u2500\u2500\u2500 interpreter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nclass Interpreter {\n\tprivate output: string[] = [];\n\tprivate stderr: string[] = [];\n\tprivate modules = new Map<string, PyDict>();\n\n\tconstructor(private readonly cwd: string) {}\n\n\tgetOutput(): string {\n\t\treturn this.output.join(\"\\n\") + (this.output.length ? \"\\n\" : \"\");\n\t}\n\tgetStderr(): string {\n\t\treturn this.stderr.join(\"\\n\") + (this.stderr.length ? \"\\n\" : \"\");\n\t}\n\n\t// \u2500\u2500 tokenizer / parser helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate splitArgs(s: string): string[] {\n\t\t// Split on commas respecting balanced parens, brackets, braces, quotes\n\t\tconst args: string[] = [];\n\t\tlet depth = 0,\n\t\t\tcur = \"\",\n\t\t\tinStr = false,\n\t\t\tstrChar = \"\";\n\t\tfor (let i = 0; i < s.length; i++) {\n\t\t\tconst ch = s[i]!;\n\t\t\tif (inStr) {\n\t\t\t\tcur += ch;\n\t\t\t\tif (ch === strChar && s[i - 1] !== \"\\\\\") inStr = false;\n\t\t\t} else if (ch === '\"' || ch === \"'\") {\n\t\t\t\tinStr = true;\n\t\t\t\tstrChar = ch;\n\t\t\t\tcur += ch;\n\t\t\t} else if (\"([{\".includes(ch)) {\n\t\t\t\tdepth++;\n\t\t\t\tcur += ch;\n\t\t\t} else if (\")]}\".includes(ch)) {\n\t\t\t\tdepth--;\n\t\t\t\tcur += ch;\n\t\t\t} else if (ch === \",\" && depth === 0) {\n\t\t\t\targs.push(cur.trim());\n\t\t\t\tcur = \"\";\n\t\t\t} else {\n\t\t\t\tcur += ch;\n\t\t\t}\n\t\t}\n\t\tif (cur.trim()) args.push(cur.trim());\n\t\treturn args;\n\t}\n\n\t// \u2500\u2500 expression evaluator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tpyEval(expr: string, scope: Scope): PyVal {\n\t\texpr = expr.trim();\n\t\tif (!expr) return NONE;\n\n\t\t// None True False literals\n\t\tif (expr === \"None\") return NONE;\n\t\tif (expr === \"True\") return true;\n\t\tif (expr === \"False\") return false;\n\t\tif (expr === \"...\") return NONE;\n\n\t\t// Number literals\n\t\tif (/^-?\\d+$/.test(expr)) return parseInt(expr, 10);\n\t\tif (/^-?\\d+\\.\\d*$/.test(expr)) return parseFloat(expr);\n\t\tif (/^0x[0-9a-fA-F]+$/.test(expr)) return parseInt(expr, 16);\n\t\tif (/^0o[0-7]+$/.test(expr)) return parseInt(expr.slice(2), 8);\n\n\t\t// String literals (single, double, triple)\n\t\tif (/^('''[\\s\\S]*'''|\"\"\"[\\s\\S]*\"\"\")$/.test(expr)) {\n\t\t\treturn expr.slice(3, -3);\n\t\t}\n\t\tif (/^(['\"])(.*)\\1$/s.test(expr)) {\n\t\t\tconst inner = expr.slice(1, -1);\n\t\t\treturn inner\n\t\t\t\t.replace(/\\\\n/g, \"\\n\")\n\t\t\t\t.replace(/\\\\t/g, \"\\t\")\n\t\t\t\t.replace(/\\\\r/g, \"\\r\")\n\t\t\t\t.replace(/\\\\\\\\/g, \"\\\\\")\n\t\t\t\t.replace(/\\\\'/g, \"'\")\n\t\t\t\t.replace(/\\\\\"/g, '\"');\n\t\t}\n\n\t\t// f-strings\n\t\tconst fMatch = expr.match(/^f(['\"])([\\s\\S]*)\\1$/);\n\t\tif (fMatch) {\n\t\t\tlet result = fMatch[2]!;\n\t\t\tresult = result.replace(/\\{([^{}]+)\\}/g, (_, inner) => {\n\t\t\t\ttry {\n\t\t\t\t\treturn pyStr(this.pyEval(inner.trim(), scope));\n\t\t\t\t} catch {\n\t\t\t\t\treturn `{${inner}}`;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn result;\n\t\t}\n\n\t\t// Byte strings b\"...\" \u2014 treat as string\n\t\tconst bMatch = expr.match(/^b(['\"])(.*)\\1$/s);\n\t\tif (bMatch) return bMatch[2]!;\n\n\t\t// List literal [...]\n\t\tif (expr.startsWith(\"[\") && expr.endsWith(\"]\")) {\n\t\t\tconst inner = expr.slice(1, -1).trim();\n\t\t\tif (!inner) return [];\n\t\t\t// List comprehension\n\t\t\tconst compMatch = inner.match(\n\t\t\t\t/^(.+?)\\s+for\\s+(\\w+)\\s+in\\s+(.+?)(?:\\s+if\\s+(.+))?$/,\n\t\t\t);\n\t\t\tif (compMatch) {\n\t\t\t\tconst [, itemExpr, varName, iterExpr, condExpr] = compMatch;\n\t\t\t\tconst iterable = pyIter(this.pyEval(iterExpr!.trim(), scope));\n\t\t\t\tconst result: PyVal[] = [];\n\t\t\t\tfor (const item of iterable) {\n\t\t\t\t\tconst inner2 = new Map(scope);\n\t\t\t\t\tinner2.set(varName!, item);\n\t\t\t\t\tif (condExpr && !pyBool(this.pyEval(condExpr, inner2))) continue;\n\t\t\t\t\tresult.push(this.pyEval(itemExpr!.trim(), inner2));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\treturn this.splitArgs(inner).map((a) => this.pyEval(a, scope));\n\t\t}\n\n\t\t// Tuple (...)\n\t\tif (expr.startsWith(\"(\") && expr.endsWith(\")\")) {\n\t\t\tconst inner = expr.slice(1, -1).trim();\n\t\t\tif (!inner) return [];\n\t\t\tconst parts = this.splitArgs(inner);\n\t\t\tif (parts.length === 1 && !inner.endsWith(\",\"))\n\t\t\t\treturn this.pyEval(parts[0]!, scope);\n\t\t\treturn parts.map((a) => this.pyEval(a, scope));\n\t\t}\n\n\t\t// Dict literal {...}\n\t\tif (expr.startsWith(\"{\") && expr.endsWith(\"}\")) {\n\t\t\tconst inner = expr.slice(1, -1).trim();\n\t\t\tif (!inner) return pyDict();\n\t\t\tconst dict = pyDict();\n\t\t\tfor (const entry of this.splitArgs(inner)) {\n\t\t\t\tconst colonIdx = entry.indexOf(\":\");\n\t\t\t\tif (colonIdx === -1) continue;\n\t\t\t\tconst k = pyStr(this.pyEval(entry.slice(0, colonIdx).trim(), scope));\n\t\t\t\tconst v = this.pyEval(entry.slice(colonIdx + 1).trim(), scope);\n\t\t\t\tdict.data.set(k, v);\n\t\t\t}\n\t\t\treturn dict;\n\t\t}\n\n\t\t// not expr\n\t\tconst notMatch = expr.match(/^not\\s+(.+)$/);\n\t\tif (notMatch) return !pyBool(this.pyEval(notMatch[1]!, scope));\n\n\t\t// Binary operators (right-to-left scan at lowest depth)\n\t\tconst binaryOps = [\n\t\t\t[\"or\"],\n\t\t\t[\"and\"],\n\t\t\t[\"in\", \"not in\", \"is not\", \"is\", \"==\", \"!=\", \"<=\", \">=\", \"<\", \">\"],\n\t\t\t[\"+\", \"-\"],\n\t\t\t[\"**\"],\n\t\t\t[\"*\", \"//\", \"/\", \"%\"],\n\t\t];\n\t\tfor (const ops of binaryOps) {\n\t\t\tconst result = this.tryBinaryOp(expr, ops, scope);\n\t\t\tif (result !== undefined) return result;\n\t\t}\n\n\t\t// Unary minus\n\t\tif (expr.startsWith(\"-\")) {\n\t\t\tconst val = this.pyEval(expr.slice(1), scope);\n\t\t\tif (typeof val === \"number\") return -val;\n\t\t}\n\n\t\t// Subscript: expr[key] or expr[start:stop]\n\t\tif (process.env.PY_DEBUG) console.error(\"eval:\", JSON.stringify(expr));\n\t\tif (expr.endsWith(\"]\") && !expr.startsWith(\"[\")) {\n\t\t\tconst bracketStart = this.findMatchingBracket(expr, \"[\");\n\t\t\tif (bracketStart !== -1) {\n\t\t\t\tconst obj = this.pyEval(expr.slice(0, bracketStart), scope);\n\t\t\t\tconst key = expr.slice(bracketStart + 1, -1);\n\t\t\t\treturn this.subscript(obj, key, scope);\n\t\t\t}\n\t\t}\n\n\t\t// Function call: name(args...) \u2014 must come BEFORE dotMatch to avoid\n\t\t// print('x'.upper()) being parsed as dotMatch(\"print('x'\", \"upper\", \"()\")\n\t\tconst callMatch = expr.match(/^([A-Za-z_][A-Za-z0-9_]*)\\s*\\(([\\s\\S]*)\\)$/);\n\t\tif (callMatch) {\n\t\t\tconst [, name, argsStr] = callMatch;\n\t\t\tconst callArgs = (argsStr?.trim() ? this.splitArgs(argsStr) : []).map(\n\t\t\t\t(a) => this.pyEval(a, scope),\n\t\t\t);\n\t\t\treturn this.callBuiltin(name!, callArgs, scope);\n\t\t}\n\n\t\t// Attribute access / method call: expr.attr or expr.method(args)\n\t\t// Uses a depth-aware scanner to find the rightmost dot at depth 0\n\t\tconst dotResult = this.findDotAccess(expr);\n\t\tif (dotResult) {\n\t\t\tconst { objExpr, attr, callPart } = dotResult;\n\t\t\tconst obj = this.pyEval(objExpr, scope);\n\t\t\tif (callPart !== undefined) {\n\t\t\t\tconst argsInner = callPart.slice(1, -1);\n\t\t\t\tconst callArgs = argsInner.trim()\n\t\t\t\t\t? this.splitArgs(argsInner).map((a) => this.pyEval(a, scope))\n\t\t\t\t\t: [];\n\t\t\t\treturn this.callMethod(obj, attr, callArgs, scope);\n\t\t\t}\n\t\t\treturn this.getAttr(obj, attr, scope);\n\t\t}\n\n\t\t// Variable lookup\n\t\tif (/^[A-Za-z_][A-Za-z0-9_]*$/.test(expr)) {\n\t\t\tif (scope.has(expr)) return scope.get(expr)!;\n\t\t\t// Check parent scopes (for closures)\n\t\t\tthrow new PyError(\"NameError\", `name '${expr}' is not defined`);\n\t\t}\n\n\t\t// Dotted name lookup (module.attr)\n\t\tif (/^[A-Za-z_][A-Za-z0-9_.]+$/.test(expr)) {\n\t\t\tconst parts = expr.split(\".\");\n\t\t\tlet val: PyVal =\n\t\t\t\tscope.get(parts[0]!) ??\n\t\t\t\t(() => {\n\t\t\t\t\tthrow new PyError(\"NameError\", `name '${parts[0]}' is not defined`);\n\t\t\t\t})();\n\t\t\tfor (const part of parts.slice(1)) {\n\t\t\t\tval = this.getAttr(val, part, scope);\n\t\t\t}\n\t\t\treturn val;\n\t\t}\n\n\t\treturn NONE;\n\t}\n\n\tprivate findMatchingBracket(s: string, open: string): number {\n\t\tconst close = open === \"[\" ? \"]\" : open === \"(\" ? \")\" : \"}\";\n\t\tlet depth = 0;\n\t\tfor (let i = s.length - 1; i >= 0; i--) {\n\t\t\tif (s[i] === close) depth++;\n\t\t\tif (s[i] === open) {\n\t\t\t\tdepth--;\n\t\t\t\tif (depth === 0) return i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\t/**\n\t * Find the rightmost dot-attribute access at depth 0, respecting strings/parens.\n\t * Returns {objExpr, attr, callPart} or null if not a dot-access expression.\n\t */\n\tprivate findDotAccess(\n\t\texpr: string,\n\t): { objExpr: string; attr: string; callPart: string | undefined } | null {\n\t\t// Scan right to left for a dot at depth 0 (not inside strings/brackets)\n\t\tlet depth = 0,\n\t\t\tinStr = false,\n\t\t\tstrChar = \"\";\n\t\tfor (let i = expr.length - 1; i > 0; i--) {\n\t\t\tconst ch = expr[i]!;\n\t\t\tif (inStr) {\n\t\t\t\tif (ch === strChar && expr[i - 1] !== \"\\\\\") inStr = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === '\"' || ch === \"'\") {\n\t\t\t\tinStr = true;\n\t\t\t\tstrChar = ch;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\")]}\".includes(ch)) {\n\t\t\t\tdepth++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\"([{\".includes(ch)) {\n\t\t\t\tdepth--;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (depth !== 0) continue;\n\t\t\tif (ch !== \".\") continue;\n\t\t\t// Found a dot at depth 0\n\t\t\tconst objExpr = expr.slice(0, i).trim();\n\t\t\tconst rest = expr.slice(i + 1); // \"attr\" or \"attr(args)\"\n\t\t\tconst attrMatch = rest.match(/^(\\w+)(\\([\\s\\S]*\\))?$/);\n\t\t\tif (!attrMatch) continue;\n\t\t\t// Skip float literals like 1.5\n\t\t\tif (/^-?\\d+$/.test(objExpr)) continue;\n\t\t\treturn { objExpr, attr: attrMatch[1]!, callPart: attrMatch[2] };\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate tryBinaryOp(\n\t\texpr: string,\n\t\tops: string[],\n\t\tscope: Scope,\n\t): PyVal | undefined {\n\t\tlet depth = 0,\n\t\t\tinStr = false,\n\t\t\tstrChar = \"\";\n\t\tfor (let i = expr.length - 1; i >= 0; i--) {\n\t\t\tconst ch = expr[i]!;\n\t\t\tif (inStr) {\n\t\t\t\tif (ch === strChar && expr[i - 1] !== \"\\\\\") inStr = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === '\"' || ch === \"'\") {\n\t\t\t\tinStr = true;\n\t\t\t\tstrChar = ch;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\")]}\".includes(ch)) {\n\t\t\t\tdepth++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\"([{\".includes(ch)) {\n\t\t\t\tdepth--;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (depth !== 0) continue;\n\n\t\t\tfor (const op of ops) {\n\t\t\t\tif (expr.slice(i, i + op.length) === op) {\n\t\t\t\t\t// Skip \"*\" if it's actually part of \"**\"\n\t\t\t\t\tif (op === \"*\" && (expr[i + 1] === \"*\" || expr[i - 1] === \"*\"))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t// Ensure it's a standalone operator (not part of identifier)\n\t\t\t\t\tconst before = expr[i - 1];\n\t\t\t\t\tconst after = expr[i + op.length];\n\t\t\t\t\tconst wordOp = /^[a-z]/.test(op);\n\t\t\t\t\tif (wordOp) {\n\t\t\t\t\t\tif (before && /\\w/.test(before)) continue;\n\t\t\t\t\t\tif (after && /\\w/.test(after)) continue;\n\t\t\t\t\t}\n\t\t\t\t\tconst left = expr.slice(0, i).trim();\n\t\t\t\t\tconst right = expr.slice(i + op.length).trim();\n\t\t\t\t\tif (!left || !right) continue;\n\t\t\t\t\treturn this.applyBinaryOp(op, left, right, scope);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate applyBinaryOp(\n\t\top: string,\n\t\tleftExpr: string,\n\t\trightExpr: string,\n\t\tscope: Scope,\n\t): PyVal {\n\t\tif (op === \"and\") {\n\t\t\tconst l = this.pyEval(leftExpr, scope);\n\t\t\treturn pyBool(l) ? this.pyEval(rightExpr, scope) : l;\n\t\t}\n\t\tif (op === \"or\") {\n\t\t\tconst l = this.pyEval(leftExpr, scope);\n\t\t\treturn pyBool(l) ? l : this.pyEval(rightExpr, scope);\n\t\t}\n\n\t\tconst left = this.pyEval(leftExpr, scope);\n\t\tconst right = this.pyEval(rightExpr, scope);\n\n\t\tswitch (op) {\n\t\t\tcase \"+\":\n\t\t\t\tif (typeof left === \"string\" && typeof right === \"string\")\n\t\t\t\t\treturn left + right;\n\t\t\t\tif (Array.isArray(left) && Array.isArray(right))\n\t\t\t\t\treturn [...left, ...right];\n\t\t\t\treturn (left as number) + (right as number);\n\t\t\tcase \"-\":\n\t\t\t\treturn (left as number) - (right as number);\n\t\t\tcase \"*\":\n\t\t\t\tif (typeof left === \"string\" && typeof right === \"number\")\n\t\t\t\t\treturn left.repeat(right);\n\t\t\t\tif (Array.isArray(left) && typeof right === \"number\") {\n\t\t\t\t\tconst arr: PyVal[] = [];\n\t\t\t\t\tfor (let i = 0; i < right; i++) arr.push(...left);\n\t\t\t\t\treturn arr;\n\t\t\t\t}\n\t\t\t\treturn (left as number) * (right as number);\n\t\t\tcase \"/\": {\n\t\t\t\tif ((right as number) === 0)\n\t\t\t\t\tthrow new PyError(\"ZeroDivisionError\", \"division by zero\");\n\t\t\t\treturn (left as number) / (right as number);\n\t\t\t}\n\t\t\tcase \"//\": {\n\t\t\t\tif ((right as number) === 0)\n\t\t\t\t\tthrow new PyError(\n\t\t\t\t\t\t\"ZeroDivisionError\",\n\t\t\t\t\t\t\"integer division or modulo by zero\",\n\t\t\t\t\t);\n\t\t\t\treturn Math.floor((left as number) / (right as number));\n\t\t\t}\n\t\t\tcase \"%\": {\n\t\t\t\tif (typeof left === \"string\")\n\t\t\t\t\treturn this.pyStringFormat(\n\t\t\t\t\t\tleft,\n\t\t\t\t\t\tArray.isArray(right) ? right : [right],\n\t\t\t\t\t);\n\t\t\t\tif ((right as number) === 0)\n\t\t\t\t\tthrow new PyError(\n\t\t\t\t\t\t\"ZeroDivisionError\",\n\t\t\t\t\t\t\"integer division or modulo by zero\",\n\t\t\t\t\t);\n\t\t\t\treturn (left as number) % (right as number);\n\t\t\t}\n\t\t\tcase \"**\":\n\t\t\t\treturn (left as number) ** (right as number);\n\t\t\tcase \"==\":\n\t\t\t\treturn pyRepr(left) === pyRepr(right) || left === right;\n\t\t\tcase \"!=\":\n\t\t\t\treturn pyRepr(left) !== pyRepr(right) && left !== right;\n\t\t\tcase \"<\":\n\t\t\t\treturn (left as number) < (right as number);\n\t\t\tcase \"<=\":\n\t\t\t\treturn (left as number) <= (right as number);\n\t\t\tcase \">\":\n\t\t\t\treturn (left as number) > (right as number);\n\t\t\tcase \">=\":\n\t\t\t\treturn (left as number) >= (right as number);\n\t\t\tcase \"in\":\n\t\t\t\treturn this.pyIn(right, left);\n\t\t\tcase \"not in\":\n\t\t\t\treturn !this.pyIn(right, left);\n\t\t\tcase \"is\":\n\t\t\t\treturn (\n\t\t\t\t\tleft === right ||\n\t\t\t\t\t(isPyNone(left as PyVal) && isPyNone(right as PyVal))\n\t\t\t\t);\n\t\t\tcase \"is not\":\n\t\t\t\treturn !(\n\t\t\t\t\tleft === right ||\n\t\t\t\t\t(isPyNone(left as PyVal) && isPyNone(right as PyVal))\n\t\t\t\t);\n\t\t}\n\t\treturn NONE;\n\t}\n\n\tprivate pyIn(container: PyVal, item: PyVal): boolean {\n\t\tif (typeof container === \"string\")\n\t\t\treturn typeof item === \"string\" && container.includes(item);\n\t\tif (Array.isArray(container))\n\t\t\treturn container.some((v) => pyRepr(v) === pyRepr(item));\n\t\tif (isPyDict(container)) return container.data.has(pyStr(item));\n\t\treturn false;\n\t}\n\n\tprivate subscript(obj: PyVal, key: string, scope: Scope): PyVal {\n\t\t// Slice\n\t\tif (key.includes(\":\")) {\n\t\t\tconst parts = key.split(\":\").map((p) => p.trim());\n\t\t\tconst start = parts[0]\n\t\t\t\t? (this.pyEval(parts[0], scope) as number)\n\t\t\t\t: undefined;\n\t\t\tconst stop = parts[1]\n\t\t\t\t? (this.pyEval(parts[1], scope) as number)\n\t\t\t\t: undefined;\n\t\t\tif (typeof obj === \"string\") return obj.slice(start, stop);\n\t\t\tif (Array.isArray(obj)) return obj.slice(start, stop);\n\t\t\treturn NONE;\n\t\t}\n\t\tconst k = this.pyEval(key, scope);\n\t\tif (Array.isArray(obj)) {\n\t\t\tlet idx = k as number;\n\t\t\tif (idx < 0) idx = obj.length + idx;\n\t\t\treturn obj[idx] ?? NONE;\n\t\t}\n\t\tif (typeof obj === \"string\") {\n\t\t\tlet idx = k as number;\n\t\t\tif (idx < 0) idx = obj.length + idx;\n\t\t\treturn obj[idx] ?? NONE;\n\t\t}\n\t\tif (isPyDict(obj)) return obj.data.get(pyStr(k)) ?? NONE;\n\t\tthrow new PyError(\"TypeError\", `'${pyTypeName(obj)}' is not subscriptable`);\n\t}\n\n\t// \u2500\u2500 attribute access \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate getAttr(obj: PyVal, attr: string, _scope: Scope): PyVal {\n\t\tif (isPyDict(obj)) {\n\t\t\tif (obj.data.has(attr)) return obj.data.get(attr)!;\n\t\t\t// Special dict attributes\n\t\t\tif (attr === \"path\" && (obj as unknown as { path: PyVal }).path)\n\t\t\t\treturn (obj as unknown as { path: PyVal }).path;\n\t\t\treturn NONE;\n\t\t}\n\t\tif (isPyInstance(obj)) return obj.attrs.get(attr) ?? NONE;\n\t\tif (typeof obj === \"string\") {\n\t\t\t// String attributes\n\t\t\tconst strMethods: Record<string, PyVal> = {\n\t\t\t\t__class__: { __pytype__: \"class\", name: \"str\" } as unknown as PyClass,\n\t\t\t};\n\t\t\treturn strMethods[attr] ?? NONE;\n\t\t}\n\t\treturn NONE;\n\t}\n\n\t// \u2500\u2500 method calls \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate callMethod(\n\t\tobj: PyVal,\n\t\tmethod: string,\n\t\targs: PyVal[],\n\t\t_scope: Scope,\n\t): PyVal {\n\t\t// String methods\n\t\tif (typeof obj === \"string\") {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"upper\":\n\t\t\t\t\treturn obj.toUpperCase();\n\t\t\t\tcase \"lower\":\n\t\t\t\t\treturn obj.toLowerCase();\n\t\t\t\tcase \"strip\":\n\t\t\t\t\treturn (\n\t\t\t\t\t\targs[0] ? obj.replace(new RegExp(`[${args[0]}]+`, \"g\"), \"\") : obj\n\t\t\t\t\t).trim();\n\t\t\t\tcase \"lstrip\":\n\t\t\t\t\treturn obj.trimStart();\n\t\t\t\tcase \"rstrip\":\n\t\t\t\t\treturn obj.trimEnd();\n\t\t\t\tcase \"split\":\n\t\t\t\t\treturn obj\n\t\t\t\t\t\t.split(typeof args[0] === \"string\" ? args[0] : /\\s+/)\n\t\t\t\t\t\t.filter((s, i) => i > 0 || s !== \"\") as PyVal[];\n\t\t\t\tcase \"splitlines\":\n\t\t\t\t\treturn obj.split(\"\\n\") as PyVal[];\n\t\t\t\tcase \"join\":\n\t\t\t\t\treturn pyIter(args[0] ?? [])\n\t\t\t\t\t\t.map(pyStr)\n\t\t\t\t\t\t.join(obj);\n\t\t\t\tcase \"replace\":\n\t\t\t\t\treturn obj.replaceAll(pyStr(args[0] ?? \"\"), pyStr(args[1] ?? \"\"));\n\t\t\t\tcase \"startswith\":\n\t\t\t\t\treturn obj.startsWith(pyStr(args[0] ?? \"\"));\n\t\t\t\tcase \"endswith\":\n\t\t\t\t\treturn obj.endsWith(pyStr(args[0] ?? \"\"));\n\t\t\t\tcase \"find\":\n\t\t\t\t\treturn obj.indexOf(pyStr(args[0] ?? \"\"));\n\t\t\t\tcase \"index\": {\n\t\t\t\t\tconst i = obj.indexOf(pyStr(args[0] ?? \"\"));\n\t\t\t\t\tif (i === -1) throw new PyError(\"ValueError\", \"substring not found\");\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t\tcase \"count\":\n\t\t\t\t\treturn obj.split(pyStr(args[0] ?? \"\")).length - 1;\n\t\t\t\tcase \"format\":\n\t\t\t\t\treturn this.pyStringFormat(obj, args);\n\t\t\t\tcase \"encode\":\n\t\t\t\t\treturn obj; // bytes stub\n\t\t\t\tcase \"decode\":\n\t\t\t\t\treturn obj;\n\t\t\t\tcase \"isdigit\":\n\t\t\t\t\treturn /^\\d+$/.test(obj);\n\t\t\t\tcase \"isalpha\":\n\t\t\t\t\treturn /^[a-zA-Z]+$/.test(obj);\n\t\t\t\tcase \"isalnum\":\n\t\t\t\t\treturn /^[a-zA-Z0-9]+$/.test(obj);\n\t\t\t\tcase \"isspace\":\n\t\t\t\t\treturn /^\\s+$/.test(obj);\n\t\t\t\tcase \"isupper\":\n\t\t\t\t\treturn obj === obj.toUpperCase() && obj !== obj.toLowerCase();\n\t\t\t\tcase \"islower\":\n\t\t\t\t\treturn obj === obj.toLowerCase() && obj !== obj.toUpperCase();\n\t\t\t\tcase \"center\": {\n\t\t\t\t\tconst w = (args[0] as number) ?? 0;\n\t\t\t\t\tconst f = pyStr(args[1] ?? \" \");\n\t\t\t\t\treturn obj.padStart(Math.floor((w + obj.length) / 2), f).padEnd(w, f);\n\t\t\t\t}\n\t\t\t\tcase \"ljust\":\n\t\t\t\t\treturn obj.padEnd((args[0] as number) ?? 0, pyStr(args[1] ?? \" \"));\n\t\t\t\tcase \"rjust\":\n\t\t\t\t\treturn obj.padStart((args[0] as number) ?? 0, pyStr(args[1] ?? \" \"));\n\t\t\t\tcase \"zfill\":\n\t\t\t\t\treturn obj.padStart((args[0] as number) ?? 0, \"0\");\n\t\t\t\tcase \"title\":\n\t\t\t\t\treturn obj.replace(/\\b\\w/g, (c) => c.toUpperCase());\n\t\t\t\tcase \"capitalize\":\n\t\t\t\t\treturn obj[0]?.toUpperCase() + obj.slice(1).toLowerCase();\n\t\t\t\tcase \"swapcase\":\n\t\t\t\t\treturn [...obj]\n\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\tc === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase(),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join(\"\");\n\t\t\t}\n\t\t}\n\n\t\t// List methods\n\t\tif (Array.isArray(obj)) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"append\":\n\t\t\t\t\tobj.push(args[0] ?? NONE);\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"extend\":\n\t\t\t\t\tfor (const v of pyIter(args[0] ?? [])) obj.push(v);\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"insert\":\n\t\t\t\t\tobj.splice((args[0] as number) ?? 0, 0, args[1] ?? NONE);\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"pop\": {\n\t\t\t\t\tconst idx = args[0] !== undefined ? (args[0] as number) : -1;\n\t\t\t\t\tconst i = idx < 0 ? obj.length + idx : idx;\n\t\t\t\t\treturn obj.splice(i, 1)[0] ?? NONE;\n\t\t\t\t}\n\t\t\t\tcase \"remove\": {\n\t\t\t\t\tconst i = obj.findIndex((v) => pyRepr(v) === pyRepr(args[0] ?? NONE));\n\t\t\t\t\tif (i !== -1) obj.splice(i, 1);\n\t\t\t\t\treturn NONE;\n\t\t\t\t}\n\t\t\t\tcase \"index\": {\n\t\t\t\t\tconst i = obj.findIndex((v) => pyRepr(v) === pyRepr(args[0] ?? NONE));\n\t\t\t\t\tif (i === -1) throw new PyError(\"ValueError\", \"is not in list\");\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t\tcase \"count\":\n\t\t\t\t\treturn obj.filter((v) => pyRepr(v) === pyRepr(args[0] ?? NONE))\n\t\t\t\t\t\t.length;\n\t\t\t\tcase \"sort\":\n\t\t\t\t\tobj.sort((a, b) =>\n\t\t\t\t\t\ttypeof a === \"number\" && typeof b === \"number\"\n\t\t\t\t\t\t\t? a - b\n\t\t\t\t\t\t\t: pyStr(a).localeCompare(pyStr(b)),\n\t\t\t\t\t);\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"reverse\":\n\t\t\t\t\tobj.reverse();\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"copy\":\n\t\t\t\t\treturn [...obj];\n\t\t\t\tcase \"clear\":\n\t\t\t\t\tobj.splice(0);\n\t\t\t\t\treturn NONE;\n\t\t\t}\n\t\t}\n\n\t\t// Dict methods\n\t\tif (isPyDict(obj)) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"keys\":\n\t\t\t\t\treturn [...obj.data.keys()];\n\t\t\t\tcase \"values\":\n\t\t\t\t\treturn [...obj.data.values()];\n\t\t\t\tcase \"items\":\n\t\t\t\t\treturn [...obj.data.entries()].map(([k, v]) => [k, v] as PyVal);\n\t\t\t\tcase \"get\":\n\t\t\t\t\treturn obj.data.get(pyStr(args[0] ?? \"\")) ?? args[1] ?? NONE;\n\t\t\t\tcase \"update\": {\n\t\t\t\t\tif (isPyDict(args[0] ?? NONE))\n\t\t\t\t\t\tfor (const [k, v] of (args[0] as PyDict).data) obj.data.set(k, v);\n\t\t\t\t\treturn NONE;\n\t\t\t\t}\n\t\t\t\tcase \"pop\": {\n\t\t\t\t\tconst k = pyStr(args[0] ?? \"\");\n\t\t\t\t\tconst v = obj.data.get(k) ?? args[1] ?? NONE;\n\t\t\t\t\tobj.data.delete(k);\n\t\t\t\t\treturn v;\n\t\t\t\t}\n\t\t\t\tcase \"clear\":\n\t\t\t\t\tobj.data.clear();\n\t\t\t\t\treturn NONE;\n\t\t\t\tcase \"copy\":\n\t\t\t\t\treturn pyDict([...obj.data.entries()]);\n\t\t\t\tcase \"setdefault\": {\n\t\t\t\t\tconst k = pyStr(args[0] ?? \"\");\n\t\t\t\t\tif (!obj.data.has(k)) obj.data.set(k, args[1] ?? NONE);\n\t\t\t\t\treturn obj.data.get(k) ?? NONE;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// os module methods\n\t\tif (\n\t\t\tisPyDict(obj) &&\n\t\t\tobj.data.has(\"name\") &&\n\t\t\tobj.data.get(\"name\") === \"posix\"\n\t\t) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"getcwd\":\n\t\t\t\t\treturn this.cwd;\n\t\t\t\tcase \"getenv\":\n\t\t\t\t\treturn typeof args[0] === \"string\"\n\t\t\t\t\t\t? (process.env[args[0]] ?? args[1] ?? NONE)\n\t\t\t\t\t\t: NONE;\n\t\t\t\tcase \"listdir\":\n\t\t\t\t\treturn [];\n\t\t\t\tcase \"path\":\n\t\t\t\t\treturn obj; // return self\n\t\t\t}\n\t\t}\n\n\t\t// os.path methods\n\t\tif (isPyDict(obj)) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"join\":\n\t\t\t\t\treturn args.map(pyStr).join(\"/\").replace(/\\/+/g, \"/\");\n\t\t\t\tcase \"exists\":\n\t\t\t\t\treturn false; // no real fs access\n\t\t\t\tcase \"dirname\": {\n\t\t\t\t\tconst p = pyStr(args[0] ?? \"\");\n\t\t\t\t\treturn p.split(\"/\").slice(0, -1).join(\"/\") || \"/\";\n\t\t\t\t}\n\t\t\t\tcase \"basename\": {\n\t\t\t\t\tconst p = pyStr(args[0] ?? \"\");\n\t\t\t\t\treturn p.split(\"/\").pop() ?? \"\";\n\t\t\t\t}\n\t\t\t\tcase \"abspath\":\n\t\t\t\t\treturn pyStr(args[0] ?? \"\");\n\t\t\t\tcase \"splitext\": {\n\t\t\t\t\tconst p = pyStr(args[0] ?? \"\");\n\t\t\t\t\tconst d = p.lastIndexOf(\".\");\n\t\t\t\t\treturn d > 0 ? [p.slice(0, d), p.slice(d)] : [p, \"\"];\n\t\t\t\t}\n\t\t\t\tcase \"isfile\":\n\t\t\t\t\treturn false;\n\t\t\t\tcase \"isdir\":\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// sys module\n\t\tif (\n\t\t\tisPyDict(obj) &&\n\t\t\tobj.data.has(\"version\") &&\n\t\t\tobj.data.get(\"version\") === VERSION_INFO\n\t\t) {\n\t\t\tswitch (method) {\n\t\t\t\tcase \"exit\":\n\t\t\t\t\tthrow new ExitSignal((args[0] as number) ?? 0);\n\t\t\t}\n\t\t}\n\n\t\t// math module\n\t\tif (isPyDict(obj)) {\n\t\t\tconst mathFns: Record<string, (...a: number[]) => number> = {\n\t\t\t\tsqrt: Math.sqrt,\n\t\t\t\tfloor: Math.floor,\n\t\t\t\tceil: Math.ceil,\n\t\t\t\tfabs: Math.abs,\n\t\t\t\tlog: Math.log,\n\t\t\t\tlog2: Math.log2,\n\t\t\t\tlog10: Math.log10,\n\t\t\t\tsin: Math.sin,\n\t\t\t\tcos: Math.cos,\n\t\t\t\ttan: Math.tan,\n\t\t\t\tasin: Math.asin,\n\t\t\t\tacos: Math.acos,\n\t\t\t\tatan: Math.atan,\n\t\t\t\tatan2: Math.atan2,\n\t\t\t\tpow: Math.pow,\n\t\t\t\texp: Math.exp,\n\t\t\t\thypot: Math.hypot,\n\t\t\t};\n\t\t\tif (method in mathFns) {\n\t\t\t\tconst fn = mathFns[method]!;\n\t\t\t\treturn fn(...args.map((a) => a as number));\n\t\t\t}\n\t\t\tif (method === \"factorial\") {\n\t\t\t\tlet n = (args[0] as number) ?? 0;\n\t\t\t\tlet r = 1;\n\t\t\t\twhile (n > 1) {\n\t\t\t\t\tr *= n--;\n\t\t\t\t}\n\t\t\t\treturn r;\n\t\t\t}\n\t\t\tif (method === \"gcd\") {\n\t\t\t\tlet a = Math.abs((args[0] as number) ?? 0);\n\t\t\t\tlet b = Math.abs((args[1] as number) ?? 0);\n\t\t\t\twhile (b) {\n\t\t\t\t\t[a, b] = [b, a % b];\n\t\t\t\t}\n\t\t\t\treturn a;\n\t\t\t}\n\t\t}\n\n\t\t// json module\n\t\tif (isPyDict(obj)) {\n\t\t\tif (method === \"dumps\") {\n\t\t\t\tconst opts: PyDict | undefined = isPyDict(args[1] ?? NONE)\n\t\t\t\t\t? (args[1] as PyDict)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst indent = opts ? (opts.data.get(\"indent\") as number) : undefined;\n\t\t\t\treturn JSON.stringify(this.pyToJs(args[0] ?? NONE), null, indent);\n\t\t\t}\n\t\t\tif (method === \"loads\") {\n\t\t\t\treturn this.jsToPy(JSON.parse(pyStr(args[0] ?? \"\")));\n\t\t\t}\n\t\t}\n\n\t\t// Instance method calls\n\t\tif (isPyInstance(obj)) {\n\t\t\tconst fn: PyVal =\n\t\t\t\tobj.attrs.get(method) ?? obj.cls.methods.get(method) ?? NONE;\n\t\t\tif (isPyFunc(fn)) {\n\t\t\t\tconst callScope = new Map(fn.closure);\n\t\t\t\tcallScope.set(\"self\", obj);\n\t\t\t\tfn.params.slice(1).forEach((p, i) => callScope.set(p, args[i] ?? NONE));\n\t\t\t\treturn this.execBlock(fn.body, callScope);\n\t\t\t}\n\t\t}\n\n\t\tthrow new PyError(\n\t\t\t\"AttributeError\",\n\t\t\t`'${pyTypeName(obj)}' object has no attribute '${method}'`,\n\t\t);\n\t}\n\n\tprivate pyStringFormat(fmt: string, args: PyVal[]): string {\n\t\tlet i = 0;\n\t\treturn fmt.replace(/%([diouxXeEfFgGcrs%])/g, (_, spec: string) => {\n\t\t\tif (spec === \"%\") return \"%\";\n\t\t\tconst val = args[i++];\n\t\t\tswitch (spec) {\n\t\t\t\tcase \"d\":\n\t\t\t\tcase \"i\":\n\t\t\t\t\treturn String(Math.trunc(val as number));\n\t\t\t\tcase \"f\":\n\t\t\t\t\treturn (val as number).toFixed(6);\n\t\t\t\tcase \"s\":\n\t\t\t\t\treturn pyStr(val ?? NONE);\n\t\t\t\tcase \"r\":\n\t\t\t\t\treturn pyRepr(val ?? NONE);\n\t\t\t\tdefault:\n\t\t\t\t\treturn String(val);\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate pyToJs(v: PyVal): unknown {\n\t\tif (isPyNone(v)) return null;\n\t\tif (isPyDict(v))\n\t\t\treturn Object.fromEntries(\n\t\t\t\t[...v.data.entries()].map(([k, val]) => [k, this.pyToJs(val)]),\n\t\t\t);\n\t\tif (Array.isArray(v)) return v.map((i) => this.pyToJs(i));\n\t\treturn v;\n\t}\n\n\tprivate jsToPy(v: unknown): PyVal {\n\t\tif (v === null || v === undefined) return NONE;\n\t\tif (typeof v === \"boolean\") return v;\n\t\tif (typeof v === \"number\") return v;\n\t\tif (typeof v === \"string\") return v;\n\t\tif (Array.isArray(v)) return v.map((i) => this.jsToPy(i));\n\t\tif (typeof v === \"object\")\n\t\t\treturn pyDict(\n\t\t\t\tObject.entries(v as Record<string, unknown>).map(([k, val]) => [\n\t\t\t\t\tk,\n\t\t\t\t\tthis.jsToPy(val),\n\t\t\t\t]),\n\t\t\t);\n\t\treturn NONE;\n\t}\n\n\t// \u2500\u2500 built-in functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate callBuiltin(name: string, args: PyVal[], scope: Scope): PyVal {\n\t\t// User-defined functions\n\t\tif (scope.has(name)) {\n\t\t\tconst fn: PyVal = scope.get(name) ?? NONE;\n\t\t\tif (isPyFunc(fn)) return this.callFunc(fn, args, scope);\n\t\t\tif (isPyClass(fn)) return this.instantiate(fn as PyClass, args, scope);\n\t\t\treturn fn;\n\t\t}\n\n\t\tswitch (name) {\n\t\t\t// Output\n\t\t\tcase \"print\": {\n\t\t\t\tconst sep = \" \",\n\t\t\t\t\tend = \"\\n\";\n\t\t\t\tthis.output.push(args.map(pyStr).join(sep) + end.replace(/\\\\n/g, \"\"));\n\t\t\t\treturn NONE;\n\t\t\t}\n\t\t\tcase \"input\": {\n\t\t\t\tthis.output.push(pyStr(args[0] ?? \"\"));\n\t\t\t\treturn \"\";\n\t\t\t}\n\n\t\t\t// Type constructors\n\t\t\tcase \"int\": {\n\t\t\t\tif (args.length === 0) return 0;\n\t\t\t\tconst base = (args[1] as number) ?? 10;\n\t\t\t\tconst n = parseInt(pyStr(args[0] ?? 0), base);\n\t\t\t\treturn Number.isNaN(n)\n\t\t\t\t\t? (() => {\n\t\t\t\t\t\t\tthrow new PyError(\"ValueError\", `invalid literal for int()`);\n\t\t\t\t\t\t})()\n\t\t\t\t\t: n;\n\t\t\t}\n\t\t\tcase \"float\": {\n\t\t\t\tif (args.length === 0) return 0.0;\n\t\t\t\tconst f = parseFloat(pyStr(args[0] ?? 0));\n\t\t\t\treturn Number.isNaN(f)\n\t\t\t\t\t? (() => {\n\t\t\t\t\t\t\tthrow new PyError(\"ValueError\", `could not convert to float`);\n\t\t\t\t\t\t})()\n\t\t\t\t\t: f;\n\t\t\t}\n\t\t\tcase \"str\":\n\t\t\t\treturn args.length === 0 ? \"\" : pyStr(args[0] ?? NONE);\n\t\t\tcase \"bool\":\n\t\t\t\treturn args.length === 0 ? false : pyBool(args[0] ?? NONE);\n\t\t\tcase \"list\":\n\t\t\t\treturn args.length === 0 ? [] : pyIter(args[0] ?? []);\n\t\t\tcase \"tuple\":\n\t\t\t\treturn args.length === 0 ? [] : pyIter(args[0] ?? []);\n\t\t\tcase \"set\":\n\t\t\t\treturn args.length === 0\n\t\t\t\t\t? []\n\t\t\t\t\t: [...new Set(pyIter(args[0] ?? []).map(pyRepr))].map((s) => {\n\t\t\t\t\t\t\tconst v = pyIter(args[0] ?? []).find(\n\t\t\t\t\t\t\t\t(item) => pyRepr(item) === s,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn v ?? NONE;\n\t\t\t\t\t\t});\n\t\t\tcase \"dict\":\n\t\t\t\treturn args.length === 0\n\t\t\t\t\t? pyDict()\n\t\t\t\t\t: isPyDict(args[0] ?? NONE)\n\t\t\t\t\t\t? (args[0] as PyDict)\n\t\t\t\t\t\t: pyDict();\n\t\t\tcase \"bytes\":\n\t\t\t\treturn typeof args[0] === \"string\" ? args[0] : pyStr(args[0] ?? \"\");\n\t\t\tcase \"bytearray\":\n\t\t\t\treturn args.length === 0 ? \"\" : pyStr(args[0] ?? \"\");\n\n\t\t\t// Type inspection\n\t\t\tcase \"type\": {\n\t\t\t\tif (args.length === 1)\n\t\t\t\t\treturn `<class '${pyTypeName(args[0] ?? NONE)}'>`;\n\t\t\t\treturn NONE;\n\t\t\t}\n\t\t\tcase \"isinstance\":\n\t\t\t\treturn pyTypeName(args[0] ?? NONE) === pyStr(args[1] ?? \"\");\n\t\t\tcase \"issubclass\":\n\t\t\t\treturn false;\n\t\t\tcase \"callable\":\n\t\t\t\treturn isPyFunc(args[0] ?? NONE);\n\t\t\tcase \"hasattr\":\n\t\t\t\treturn isPyDict(args[0] ?? NONE)\n\t\t\t\t\t? (args[0] as PyDict).data.has(pyStr(args[1] ?? \"\"))\n\t\t\t\t\t: false;\n\t\t\tcase \"getattr\": {\n\t\t\t\tif (!isPyDict(args[0] ?? NONE)) return args[2] ?? NONE;\n\t\t\t\treturn (\n\t\t\t\t\t(args[0] as PyDict).data.get(pyStr(args[1] ?? \"\")) ?? args[2] ?? NONE\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"setattr\": {\n\t\t\t\tif (isPyDict(args[0] ?? NONE))\n\t\t\t\t\t(args[0] as PyDict).data.set(pyStr(args[1] ?? \"\"), args[2] ?? NONE);\n\t\t\t\treturn NONE;\n\t\t\t}\n\n\t\t\t// Functional\n\t\t\tcase \"len\": {\n\t\t\t\tconst v = args[0] ?? NONE;\n\t\t\t\tif (typeof v === \"string\") return v.length;\n\t\t\t\tif (Array.isArray(v)) return v.length;\n\t\t\t\tif (isPyDict(v)) return v.data.size;\n\t\t\t\tif (isPyRange(v)) return pyRangeLength(v);\n\t\t\t\tthrow new PyError(\n\t\t\t\t\t\"TypeError\",\n\t\t\t\t\t`object of type '${pyTypeName(v)}' has no len()`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"range\": {\n\t\t\t\tif (args.length === 1) return pyRange(0, args[0] as number);\n\t\t\t\tif (args.length === 2)\n\t\t\t\t\treturn pyRange(args[0] as number, args[1] as number);\n\t\t\t\treturn pyRange(args[0] as number, args[1] as number, args[2] as number);\n\t\t\t}\n\t\t\tcase \"enumerate\": {\n\t\t\t\tconst start = (args[1] as number) ?? 0;\n\t\t\t\treturn pyIter(args[0] ?? []).map((v, i) => [i + start, v] as PyVal);\n\t\t\t}\n\t\t\tcase \"zip\": {\n\t\t\t\tconst iters = args.map(pyIter);\n\t\t\t\tconst len = Math.min(...iters.map((it) => it.length));\n\t\t\t\treturn Array.from({ length: len }, (_, i) =>\n\t\t\t\t\titers.map((it) => it[i] ?? NONE),\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"map\": {\n\t\t\t\tconst fn: PyVal = args[0] ?? NONE;\n\t\t\t\treturn pyIter(args[1] ?? []).map((v) =>\n\t\t\t\t\tisPyFunc(fn) ? this.callFunc(fn, [v], scope) : NONE,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"filter\": {\n\t\t\t\tconst fn: PyVal = args[0] ?? NONE;\n\t\t\t\treturn pyIter(args[1] ?? []).filter((v) =>\n\t\t\t\t\tisPyFunc(fn) ? pyBool(this.callFunc(fn, [v], scope)) : pyBool(v),\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase \"reduce\": {\n\t\t\t\tconst fn: PyVal = args[0] ?? NONE;\n\t\t\t\tconst items = pyIter(args[1] ?? []);\n\t\t\t\tif (items.length === 0) return args[2] ?? NONE;\n\t\t\t\tlet acc: PyVal = args[2] !== undefined ? args[2] : items[0]!;\n\t\t\t\tfor (const item of args[2] !== undefined ? items : items.slice(1)) {\n\t\t\t\t\tacc = isPyFunc(fn)\n\t\t\t\t\t\t? this.callFunc(fn as PyFunc, [acc, item], scope)\n\t\t\t\t\t\t: NONE;\n\t\t\t\t}\n\t\t\t\treturn acc;\n\t\t\t}\n\t\t\tcase \"sorted\": {\n\t\t\t\tconst items = [...pyIter(args[0] ?? [])];\n\t\t\t\tconst sortArg1 = args[1] ?? NONE;\n\t\t\t\tconst keyFn: PyVal = isPyDict(sortArg1)\n\t\t\t\t\t? (sortArg1.data.get(\"key\") ?? NONE)\n\t\t\t\t\t: sortArg1;\n\t\t\t\titems.sort((a, b) => {\n\t\t\t\t\tconst ka: PyVal = isPyFunc(keyFn)\n\t\t\t\t\t\t? this.callFunc(keyFn, [a], scope)\n\t\t\t\t\t\t: a;\n\t\t\t\t\tconst kb: PyVal = isPyFunc(keyFn)\n\t\t\t\t\t\t? this.callFunc(keyFn, [b], scope)\n\t\t\t\t\t\t: b;\n\t\t\t\t\treturn typeof ka === \"number\" && typeof kb === \"number\"\n\t\t\t\t\t\t? ka - kb\n\t\t\t\t\t\t: pyStr(ka).localeCompare(pyStr(kb));\n\t\t\t\t});\n\t\t\t\treturn items;\n\t\t\t}\n\t\t\tcase \"reversed\":\n\t\t\t\treturn [...pyIter(args[0] ?? [])].reverse();\n\t\t\tcase \"any\":\n\t\t\t\treturn pyIter(args[0] ?? []).some(pyBool);\n\t\t\tcase \"all\":\n\t\t\t\treturn pyIter(args[0] ?? []).every(pyBool);\n\t\t\tcase \"sum\":\n\t\t\t\treturn pyIter(args[0] ?? []).reduce(\n\t\t\t\t\t(acc, v) => (acc as number) + (v as number),\n\t\t\t\t\t(args[1] ?? 0) as number,\n\t\t\t\t);\n\t\t\tcase \"max\": {\n\t\t\t\tconst items = args.length === 1 ? pyIter(args[0] ?? []) : args;\n\t\t\t\treturn items.reduce((a, b) => ((a as number) >= (b as number) ? a : b));\n\t\t\t}\n\t\t\tcase \"min\": {\n\t\t\t\tconst items = args.length === 1 ? pyIter(args[0] ?? []) : args;\n\t\t\t\treturn items.reduce((a, b) => ((a as number) <= (b as number) ? a : b));\n\t\t\t}\n\t\t\tcase \"abs\":\n\t\t\t\treturn Math.abs((args[0] as number) ?? 0);\n\t\t\tcase \"round\":\n\t\t\t\treturn args[1] !== undefined\n\t\t\t\t\t? parseFloat((args[0] as number).toFixed(args[1] as number))\n\t\t\t\t\t: Math.round((args[0] as number) ?? 0);\n\t\t\tcase \"divmod\": {\n\t\t\t\tconst a = args[0] as number,\n\t\t\t\t\tb = args[1] as number;\n\t\t\t\treturn [Math.floor(a / b), a % b];\n\t\t\t}\n\t\t\tcase \"pow\":\n\t\t\t\treturn (args[0] as number) ** (args[1] as number);\n\t\t\tcase \"hex\":\n\t\t\t\treturn `0x${(args[0] as number).toString(16)}`;\n\t\t\tcase \"oct\":\n\t\t\t\treturn `0o${(args[0] as number).toString(8)}`;\n\t\t\tcase \"bin\":\n\t\t\t\treturn `0b${(args[0] as number).toString(2)}`;\n\t\t\tcase \"ord\":\n\t\t\t\treturn pyStr(args[0] ?? \"\").charCodeAt(0);\n\t\t\tcase \"chr\":\n\t\t\t\treturn String.fromCharCode((args[0] as number) ?? 0);\n\t\t\tcase \"id\":\n\t\t\t\treturn Math.floor(Math.random() * 0xffffffff);\n\t\t\tcase \"hash\":\n\t\t\t\treturn typeof args[0] === \"number\"\n\t\t\t\t\t? args[0]\n\t\t\t\t\t: pyStr(args[0] ?? \"\")\n\t\t\t\t\t\t\t.split(\"\")\n\t\t\t\t\t\t\t.reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0);\n\n\t\t\t// I/O\n\t\t\tcase \"open\":\n\t\t\t\tthrow new PyError(\n\t\t\t\t\t\"PermissionError\",\n\t\t\t\t\t\"open() not available in virtual runtime\",\n\t\t\t\t);\n\t\t\tcase \"repr\":\n\t\t\t\treturn pyRepr(args[0] ?? NONE);\n\n\t\t\t// Iteration helpers\n\t\t\tcase \"iter\":\n\t\t\t\treturn args[0] ?? NONE; // simplification\n\t\t\tcase \"next\": {\n\t\t\t\tif (Array.isArray(args[0]) && args[0].length > 0)\n\t\t\t\t\treturn args[0].shift()!;\n\t\t\t\treturn (\n\t\t\t\t\targs[1] ??\n\t\t\t\t\t(() => {\n\t\t\t\t\t\tthrow new PyError(\"StopIteration\", \"\");\n\t\t\t\t\t})()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// vars/globals/locals\n\t\t\tcase \"vars\":\n\t\t\t\treturn pyDict([...scope.entries()].map(([k, v]) => [k, v]));\n\t\t\tcase \"globals\":\n\t\t\t\treturn pyDict([...scope.entries()].map(([k, v]) => [k, v]));\n\t\t\tcase \"locals\":\n\t\t\t\treturn pyDict([...scope.entries()].map(([k, v]) => [k, v]));\n\t\t\tcase \"dir\": {\n\t\t\t\tif (args.length === 0) return [...scope.keys()];\n\t\t\t\tconst obj = args[0] ?? NONE;\n\t\t\t\tif (typeof obj === \"string\")\n\t\t\t\t\treturn [\n\t\t\t\t\t\t\"upper\",\n\t\t\t\t\t\t\"lower\",\n\t\t\t\t\t\t\"strip\",\n\t\t\t\t\t\t\"split\",\n\t\t\t\t\t\t\"join\",\n\t\t\t\t\t\t\"replace\",\n\t\t\t\t\t\t\"find\",\n\t\t\t\t\t\t\"format\",\n\t\t\t\t\t\t\"encode\",\n\t\t\t\t\t\t\"startswith\",\n\t\t\t\t\t\t\"endswith\",\n\t\t\t\t\t\t\"count\",\n\t\t\t\t\t\t\"isdigit\",\n\t\t\t\t\t\t\"isalpha\",\n\t\t\t\t\t\t\"title\",\n\t\t\t\t\t\t\"capitalize\",\n\t\t\t\t\t];\n\t\t\t\tif (Array.isArray(obj))\n\t\t\t\t\treturn [\n\t\t\t\t\t\t\"append\",\n\t\t\t\t\t\t\"extend\",\n\t\t\t\t\t\t\"insert\",\n\t\t\t\t\t\t\"pop\",\n\t\t\t\t\t\t\"remove\",\n\t\t\t\t\t\t\"index\",\n\t\t\t\t\t\t\"count\",\n\t\t\t\t\t\t\"sort\",\n\t\t\t\t\t\t\"reverse\",\n\t\t\t\t\t\t\"copy\",\n\t\t\t\t\t\t\"clear\",\n\t\t\t\t\t];\n\t\t\t\tif (isPyDict(obj))\n\t\t\t\t\treturn [\n\t\t\t\t\t\t\"keys\",\n\t\t\t\t\t\t\"values\",\n\t\t\t\t\t\t\"items\",\n\t\t\t\t\t\t\"get\",\n\t\t\t\t\t\t\"update\",\n\t\t\t\t\t\t\"pop\",\n\t\t\t\t\t\t\"clear\",\n\t\t\t\t\t\t\"copy\",\n\t\t\t\t\t\t\"setdefault\",\n\t\t\t\t\t];\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\t// Exception\n\t\t\tcase \"Exception\":\n\t\t\tcase \"ValueError\":\n\t\t\tcase \"TypeError\":\n\t\t\tcase \"KeyError\":\n\t\t\tcase \"IndexError\":\n\t\t\tcase \"AttributeError\":\n\t\t\tcase \"NameError\":\n\t\t\tcase \"RuntimeError\":\n\t\t\tcase \"StopIteration\":\n\t\t\tcase \"NotImplementedError\":\n\t\t\tcase \"OSError\":\n\t\t\tcase \"IOError\":\n\t\t\t\tthrow new PyError(name, pyStr(args[0] ?? \"\"));\n\n\t\t\t// exec/eval\n\t\t\tcase \"exec\": {\n\t\t\t\tthis.execScript(pyStr(args[0] ?? \"\"), scope);\n\t\t\t\treturn NONE;\n\t\t\t}\n\t\t\tcase \"eval\":\n\t\t\t\treturn this.pyEval(pyStr(args[0] ?? \"\"), scope);\n\n\t\t\tdefault:\n\t\t\t\tthrow new PyError(\"NameError\", `name '${name}' is not defined`);\n\t\t}\n\t}\n\n\tprivate callFunc(fn: PyFunc, args: PyVal[], _scope: Scope): PyVal {\n\t\tconst callScope = new Map(fn.closure);\n\t\tfn.params.forEach((p, i) => {\n\t\t\tif (p.startsWith(\"*\")) {\n\t\t\t\tcallScope.set(p.slice(1), args.slice(i));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcallScope.set(p, args[i] ?? NONE);\n\t\t});\n\t\ttry {\n\t\t\treturn this.execBlock(fn.body, callScope);\n\t\t} catch (e) {\n\t\t\tif (e instanceof ReturnSignal) return e.value;\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tprivate instantiate(cls: PyClass, args: PyVal[], scope: Scope): PyInstance {\n\t\tconst inst: PyInstance = { __pytype__: \"instance\", cls, attrs: new Map() };\n\t\tconst init = cls.methods.get(\"__init__\");\n\t\tif (init) this.callMethod(inst, \"__init__\", args, scope);\n\t\treturn inst;\n\t}\n\n\t// \u2500\u2500 statement executor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\texecScript(code: string, scope: Scope): void {\n\t\tconst lines = code.split(\"\\n\");\n\t\tthis.execLines(lines, 0, scope);\n\t}\n\n\tprivate execLines(lines: string[], startIdx: number, scope: Scope): number {\n\t\tlet i = startIdx;\n\t\twhile (i < lines.length) {\n\t\t\tconst raw = lines[i]!;\n\t\t\tif (!raw.trim() || raw.trim().startsWith(\"#\")) {\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ti = this.execStatement(lines, i, scope);\n\t\t}\n\t\treturn i;\n\t}\n\n\tprivate execBlock(bodyLines: string[], scope: Scope): PyVal {\n\t\ttry {\n\t\t\tthis.execLines(bodyLines, 0, scope);\n\t\t} catch (e) {\n\t\t\tif (e instanceof ReturnSignal) return e.value;\n\t\t\tthrow e;\n\t\t}\n\t\treturn NONE;\n\t}\n\n\tprivate getIndent(line: string): number {\n\t\tlet n = 0;\n\t\tfor (const ch of line) {\n\t\t\tif (ch === \" \") n++;\n\t\t\telse if (ch === \"\\t\") n += 4;\n\t\t\telse break;\n\t\t}\n\t\treturn n;\n\t}\n\n\tprivate collectBlock(\n\t\tlines: string[],\n\t\tstartIdx: number,\n\t\tbaseIndent: number,\n\t): string[] {\n\t\tconst block: string[] = [];\n\t\tfor (let i = startIdx; i < lines.length; i++) {\n\t\t\tconst l = lines[i]!;\n\t\t\tif (!l.trim()) {\n\t\t\t\tblock.push(\"\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.getIndent(l) <= baseIndent) break;\n\t\t\tblock.push(l.slice(baseIndent + 4));\n\t\t}\n\t\treturn block;\n\t}\n\n\tprivate execStatement(lines: string[], idx: number, scope: Scope): number {\n\t\tconst raw = lines[idx]!;\n\t\tconst line = raw.trim();\n\t\tconst indent = this.getIndent(raw);\n\n\t\t// pass\n\t\tif (line === \"pass\") return idx + 1;\n\n\t\t// break / continue\n\t\tif (line === \"break\") {\n\t\t\tthrow new BreakSignal();\n\t\t}\n\t\tif (line === \"continue\") {\n\t\t\tthrow new ContinueSignal();\n\t\t}\n\n\t\t// return\n\t\tconst retMatch = line.match(/^return(?:\\s+(.+))?$/);\n\t\tif (retMatch)\n\t\t\tthrow new ReturnSignal(\n\t\t\t\tretMatch[1] ? this.pyEval(retMatch[1], scope) : NONE,\n\t\t\t);\n\n\t\t// raise\n\t\tconst raiseMatch = line.match(/^raise(?:\\s+(.+))?$/);\n\t\tif (raiseMatch) {\n\t\t\tif (raiseMatch[1]) {\n\t\t\t\tconst ex = this.pyEval(raiseMatch[1], scope);\n\t\t\t\tthrow new PyError(\n\t\t\t\t\ttypeof ex === \"string\" ? ex : pyTypeName(ex),\n\t\t\t\t\tpyStr(ex),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new PyError(\"RuntimeError\", \"\");\n\t\t}\n\n\t\t// assert\n\t\tconst assertMatch = line.match(/^assert\\s+(.+?)(?:,\\s*(.+))?$/);\n\t\tif (assertMatch) {\n\t\t\tif (!pyBool(this.pyEval(assertMatch[1]!, scope))) {\n\t\t\t\tthrow new PyError(\n\t\t\t\t\t\"AssertionError\",\n\t\t\t\t\tassertMatch[2] ? pyStr(this.pyEval(assertMatch[2], scope)) : \"\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// del\n\t\tconst delMatch = line.match(/^del\\s+(.+)$/);\n\t\tif (delMatch) {\n\t\t\tscope.delete(delMatch[1]!.trim());\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// import / from\n\t\tconst importMatch = line.match(/^import\\s+(\\w+)(?:\\s+as\\s+(\\w+))?$/);\n\t\tif (importMatch) {\n\t\t\tconst [, modName, alias] = importMatch;\n\t\t\tconst factory = MODULE_FACTORIES[modName!];\n\t\t\tif (factory) {\n\t\t\t\tconst mod = factory(this.cwd);\n\t\t\t\tthis.modules.set(modName!, mod);\n\t\t\t\tscope.set(alias ?? modName!, mod);\n\t\t\t}\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\tconst fromMatch = line.match(/^from\\s+(\\w+)\\s+import\\s+(.+)$/);\n\t\tif (fromMatch) {\n\t\t\tconst [, modName, imports] = fromMatch;\n\t\t\tconst factory = MODULE_FACTORIES[modName!];\n\t\t\tif (factory) {\n\t\t\t\tconst mod = factory(this.cwd);\n\t\t\t\tif (imports?.trim() === \"*\") {\n\t\t\t\t\tfor (const [k, v] of mod.data) scope.set(k, v);\n\t\t\t\t} else {\n\t\t\t\t\tfor (const name of imports!.split(\",\").map((s) => s.trim())) {\n\t\t\t\t\t\tscope.set(name, mod.data.get(name) ?? NONE);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// def\n\t\tconst defMatch = line.match(/^def\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*:$/);\n\t\tif (defMatch) {\n\t\t\tconst [, fnName, paramsStr] = defMatch;\n\t\t\tconst params = paramsStr!\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((p) => p.trim())\n\t\t\t\t.filter(Boolean);\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tconst fn: PyFunc = {\n\t\t\t\t__pytype__: \"func\",\n\t\t\t\tname: fnName!,\n\t\t\t\tparams,\n\t\t\t\tbody,\n\t\t\t\tclosure: new Map(scope),\n\t\t\t};\n\t\t\tscope.set(fnName!, fn);\n\t\t\treturn idx + 1 + body.length;\n\t\t}\n\n\t\t// class\n\t\tconst classMatch = line.match(/^class\\s+(\\w+)(?:\\(([^)]*)\\))?\\s*:$/);\n\t\tif (classMatch) {\n\t\t\tconst [, className, basesStr] = classMatch;\n\t\t\tconst bases = basesStr ? basesStr.split(\",\").map((s) => s.trim()) : [];\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tconst cls: PyClass = {\n\t\t\t\t__pytype__: \"class\",\n\t\t\t\tname: className!,\n\t\t\t\tmethods: new Map(),\n\t\t\t\tbases,\n\t\t\t};\n\t\t\t// Parse method definitions from body\n\t\t\tlet j = 0;\n\t\t\twhile (j < body.length) {\n\t\t\t\tconst bl = body[j]!.trim();\n\t\t\t\tconst mMatch = bl.match(/^def\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*:$/);\n\t\t\t\tif (mMatch) {\n\t\t\t\t\tconst [, mName, mParams] = mMatch;\n\t\t\t\t\tconst params = mParams!\n\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t.map((p) => p.trim())\n\t\t\t\t\t\t.filter(Boolean);\n\t\t\t\t\tconst mBody = this.collectBlock(body, j + 1, 0);\n\t\t\t\t\tcls.methods.set(mName!, {\n\t\t\t\t\t\t__pytype__: \"func\",\n\t\t\t\t\t\tname: mName!,\n\t\t\t\t\t\tparams,\n\t\t\t\t\t\tbody: mBody,\n\t\t\t\t\t\tclosure: new Map(scope),\n\t\t\t\t\t});\n\t\t\t\t\tj += 1 + mBody.length;\n\t\t\t\t} else {\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tscope.set(className!, cls);\n\t\t\treturn idx + 1 + body.length;\n\t\t}\n\n\t\t// if / elif / else\n\t\tif (line.startsWith(\"if \") && line.endsWith(\":\")) {\n\t\t\tconst cond = line.slice(3, -1).trim();\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tconst _skip = body.length + 1;\n\n\t\t\tif (pyBool(this.pyEval(cond, scope))) {\n\t\t\t\tthis.execBlock(\n\t\t\t\t\tbody,\n\t\t\t\t\tnew Map(scope).also?.((s) => {\n\t\t\t\t\t\tfor (const [k, v] of scope) s.set(k, v);\n\t\t\t\t\t}) ?? scope,\n\t\t\t\t);\n\t\t\t\t// Update scope from block (assignments)\n\t\t\t\tthis.runBlockInScope(body, scope);\n\t\t\t\t// Skip elif/else\n\t\t\t\tlet j = idx + 1 + body.length;\n\t\t\t\twhile (j < lines.length) {\n\t\t\t\t\tconst l = lines[j]!.trim();\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.getIndent(lines[j]!) < indent ||\n\t\t\t\t\t\t(!l.startsWith(\"elif\") && !l.startsWith(\"else\"))\n\t\t\t\t\t)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tconst bk = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tj += 1 + bk.length;\n\t\t\t\t}\n\t\t\t\treturn j;\n\t\t\t}\n\n\t\t\t// Check elif / else\n\t\t\tlet j = idx + 1 + body.length;\n\t\t\twhile (j < lines.length) {\n\t\t\t\tconst el = lines[j]!;\n\t\t\t\tconst elt = el.trim();\n\t\t\t\tif (this.getIndent(el) !== indent) break;\n\n\t\t\t\tconst elifMatch = elt.match(/^elif\\s+(.+):$/);\n\t\t\t\tif (elifMatch) {\n\t\t\t\t\tconst eBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tif (pyBool(this.pyEval(elifMatch[1]!, scope))) {\n\t\t\t\t\t\tthis.runBlockInScope(eBody, scope);\n\t\t\t\t\t\tj += 1 + eBody.length;\n\t\t\t\t\t\t// Skip remaining elif/else\n\t\t\t\t\t\twhile (j < lines.length) {\n\t\t\t\t\t\t\tconst sl = lines[j]!.trim();\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tthis.getIndent(lines[j]!) !== indent ||\n\t\t\t\t\t\t\t\t(!sl.startsWith(\"elif\") && !sl.startsWith(\"else\"))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tconst sb = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\t\t\tj += 1 + sb.length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn j;\n\t\t\t\t\t}\n\t\t\t\t\tj += 1 + eBody.length;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (elt === \"else:\") {\n\t\t\t\t\tconst eBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tthis.runBlockInScope(eBody, scope);\n\t\t\t\t\treturn j + 1 + eBody.length;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn j;\n\t\t}\n\n\t\t// for\n\t\tconst forMatch = line.match(/^for\\s+(.+?)\\s+in\\s+(.+?)\\s*:$/);\n\t\tif (forMatch) {\n\t\t\tconst [, target, iterExpr] = forMatch;\n\t\t\tconst iterable = pyIter(this.pyEval(iterExpr!.trim(), scope));\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\n\t\t\t// Check for else clause\n\t\t\tlet elseBody: string[] = [];\n\t\t\tlet afterIdx = idx + 1 + body.length;\n\t\t\tif (afterIdx < lines.length && lines[afterIdx]?.trim() === \"else:\") {\n\t\t\t\telseBody = this.collectBlock(lines, afterIdx + 1, indent);\n\t\t\t\tafterIdx += 1 + elseBody.length;\n\t\t\t}\n\n\t\t\tlet broken = false;\n\t\t\tfor (const item of iterable) {\n\t\t\t\t// Unpack\n\t\t\t\tif (target!.includes(\",\")) {\n\t\t\t\t\tconst targets = target!.split(\",\").map((t) => t.trim());\n\t\t\t\t\tconst items = Array.isArray(item) ? item : [item];\n\t\t\t\t\ttargets.forEach((t, i) => scope.set(t, items[i] ?? NONE));\n\t\t\t\t} else {\n\t\t\t\t\tscope.set(target!.trim(), item);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tthis.runBlockInScope(body, scope);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (e instanceof BreakSignal) {\n\t\t\t\t\t\tbroken = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (e instanceof ContinueSignal) continue;\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!broken && elseBody.length) this.runBlockInScope(elseBody, scope);\n\t\t\treturn afterIdx;\n\t\t}\n\n\t\t// while\n\t\tconst whileMatch = line.match(/^while\\s+(.+?)\\s*:$/);\n\t\tif (whileMatch) {\n\t\t\tconst cond = whileMatch[1]!;\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tlet iterations = 0;\n\t\t\twhile (pyBool(this.pyEval(cond, scope)) && iterations++ < 100000) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.runBlockInScope(body, scope);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (e instanceof BreakSignal) break;\n\t\t\t\t\tif (e instanceof ContinueSignal) continue;\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn idx + 1 + body.length;\n\t\t}\n\n\t\t// try / except\n\t\tif (line === \"try:\") {\n\t\t\tconst tryBody = this.collectBlock(lines, idx + 1, indent);\n\t\t\tlet j = idx + 1 + tryBody.length;\n\t\t\tconst exceptClauses: Array<{ exc: string | null; body: string[] }> = [];\n\t\t\tlet finallyBody: string[] = [];\n\t\t\tlet elseBody: string[] = [];\n\n\t\t\twhile (j < lines.length) {\n\t\t\t\tconst el = lines[j]!;\n\t\t\t\tconst elt = el.trim();\n\t\t\t\tif (this.getIndent(el) !== indent) break;\n\t\t\t\tif (elt.startsWith(\"except\")) {\n\t\t\t\t\tconst excMatch = elt.match(\n\t\t\t\t\t\t/^except(?:\\s+(\\w+)(?:\\s+as\\s+(\\w+))?)?\\s*:$/,\n\t\t\t\t\t);\n\t\t\t\t\tconst excName = excMatch?.[1] ?? null;\n\t\t\t\t\tconst excAlias = excMatch?.[2];\n\t\t\t\t\tconst excBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\texceptClauses.push({ exc: excName, body: excBody });\n\t\t\t\t\tif (excAlias) scope.set(excAlias, \"\");\n\t\t\t\t\tj += 1 + excBody.length;\n\t\t\t\t} else if (elt === \"else:\") {\n\t\t\t\t\telseBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tj += 1 + elseBody.length;\n\t\t\t\t} else if (elt === \"finally:\") {\n\t\t\t\t\tfinallyBody = this.collectBlock(lines, j + 1, indent);\n\t\t\t\t\tj += 1 + finallyBody.length;\n\t\t\t\t} else break;\n\t\t\t}\n\n\t\t\tlet _caughtErr: PyError | null = null;\n\t\t\ttry {\n\t\t\t\tthis.runBlockInScope(tryBody, scope);\n\t\t\t\tif (elseBody.length) this.runBlockInScope(elseBody, scope);\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof PyError) {\n\t\t\t\t\t_caughtErr = e;\n\t\t\t\t\tlet handled = false;\n\t\t\t\t\tfor (const clause of exceptClauses) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tclause.exc === null ||\n\t\t\t\t\t\t\tclause.exc === e.type ||\n\t\t\t\t\t\t\tclause.exc === \"Exception\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.runBlockInScope(clause.body, scope);\n\t\t\t\t\t\t\thandled = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!handled) throw e;\n\t\t\t\t} else throw e;\n\t\t\t} finally {\n\t\t\t\tif (finallyBody.length) this.runBlockInScope(finallyBody, scope);\n\t\t\t}\n\t\t\treturn j;\n\t\t}\n\n\t\t// with\n\t\tconst withMatch = line.match(/^with\\s+(.+?)\\s+as\\s+(\\w+)\\s*:$/);\n\t\tif (withMatch) {\n\t\t\tconst body = this.collectBlock(lines, idx + 1, indent);\n\t\t\tscope.set(withMatch[2]!, NONE); // stub: just set to None\n\t\t\tthis.runBlockInScope(body, scope);\n\t\t\treturn idx + 1 + body.length;\n\t\t}\n\n\t\t// Augmented assignments: +=, -=, *=, /=, //=, %= **=\n\t\tconst augMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_]*)\\s*(\\+=|-=|\\*=|\\/\\/=|\\/=|%=|\\*\\*=|&=|\\|=)\\s*(.+)$/,\n\t\t);\n\t\tif (augMatch) {\n\t\t\tconst [, name, op, rhsExpr] = augMatch;\n\t\t\tconst lhs = scope.get(name!) ?? 0;\n\t\t\tconst rhs = this.pyEval(rhsExpr!, scope);\n\t\t\tlet result: PyVal;\n\t\t\tswitch (op) {\n\t\t\t\tcase \"+=\":\n\t\t\t\t\tresult =\n\t\t\t\t\t\ttypeof lhs === \"string\"\n\t\t\t\t\t\t\t? lhs + pyStr(rhs)\n\t\t\t\t\t\t\t: (lhs as number) + (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"-=\":\n\t\t\t\t\tresult = (lhs as number) - (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"*=\":\n\t\t\t\t\tresult = (lhs as number) * (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"/=\":\n\t\t\t\t\tresult = (lhs as number) / (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"//=\":\n\t\t\t\t\tresult = Math.floor((lhs as number) / (rhs as number));\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"%=\":\n\t\t\t\t\tresult = (lhs as number) % (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"**=\":\n\t\t\t\t\tresult = (lhs as number) ** (rhs as number);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tresult = rhs;\n\t\t\t}\n\t\t\tscope.set(name!, result);\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// Subscript assignment: obj[key] = val\n\t\tconst subAssignMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_]*)\\[(.+)\\]\\s*=\\s*(.+)$/,\n\t\t);\n\t\tif (subAssignMatch) {\n\t\t\tconst [, name, key, valExpr] = subAssignMatch;\n\t\t\tconst obj = scope.get(name!) ?? NONE;\n\t\t\tconst val: PyVal = this.pyEval(valExpr!, scope) ?? NONE;\n\t\t\tconst k: PyVal = this.pyEval(key!, scope) ?? NONE;\n\t\t\tif (Array.isArray(obj)) (obj as PyVal[])[k as number] = val;\n\t\t\telse if (isPyDict(obj)) obj.data.set(pyStr(k), val);\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// Attribute assignment: obj.attr = val\n\t\tconst attrAssignMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_.]+)\\s*=\\s*(.+)$/,\n\t\t);\n\t\tif (attrAssignMatch) {\n\t\t\tconst dotIdx = attrAssignMatch[1]!.lastIndexOf(\".\");\n\t\t\tif (dotIdx !== -1) {\n\t\t\t\tconst objExpr = attrAssignMatch[1]!.slice(0, dotIdx);\n\t\t\t\tconst attr = attrAssignMatch[1]!.slice(dotIdx + 1);\n\t\t\t\tconst val = this.pyEval(attrAssignMatch[2]!, scope);\n\t\t\t\tconst obj = this.pyEval(objExpr, scope);\n\t\t\t\tif (isPyDict(obj)) obj.data.set(attr, val);\n\t\t\t\telse if (isPyInstance(obj)) obj.attrs.set(attr, val);\n\t\t\t\treturn idx + 1;\n\t\t\t}\n\t\t}\n\n\t\t// Tuple / multi-assignment: a, b = expr\n\t\tconst multiAssignMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_,\\s]*),\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*(.+)$/,\n\t\t);\n\t\tif (multiAssignMatch) {\n\t\t\tconst rhs = this.pyEval(multiAssignMatch[3]!, scope);\n\t\t\tconst targets = line\n\t\t\t\t.split(\"=\")[0]!\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((s) => s.trim());\n\t\t\tconst values = pyIter(rhs);\n\t\t\ttargets.forEach((t, i) => scope.set(t, values[i] ?? NONE));\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// Simple assignment: name = expr (or name: type = expr)\n\t\tconst assignMatch = line.match(\n\t\t\t/^([A-Za-z_][A-Za-z0-9_]*)\\s*(?::[^=]+)?\\s*=\\s*(.+)$/,\n\t\t);\n\t\tif (assignMatch) {\n\t\t\tconst [, name, rhs] = assignMatch;\n\t\t\tscope.set(name!, this.pyEval(rhs!, scope));\n\t\t\treturn idx + 1;\n\t\t}\n\n\t\t// Expression statement (function call, etc.)\n\t\ttry {\n\t\t\tthis.pyEval(line, scope);\n\t\t} catch (e) {\n\t\t\tif (e instanceof PyError || e instanceof ExitSignal) throw e;\n\t\t\t// Ignore eval errors for expression statements\n\t\t}\n\t\treturn idx + 1;\n\t}\n\n\tprivate runBlockInScope(body: string[], scope: Scope): void {\n\t\tthis.execLines(body, 0, scope);\n\t}\n\n\trun(code: string): { stdout: string; stderr: string; exitCode: number } {\n\t\tconst scope = makeRootScope(this.cwd);\n\t\ttry {\n\t\t\tthis.execScript(code, scope);\n\t\t} catch (e) {\n\t\t\tif (e instanceof ExitSignal)\n\t\t\t\treturn {\n\t\t\t\t\tstdout: this.getOutput(),\n\t\t\t\t\tstderr: this.getStderr(),\n\t\t\t\t\texitCode: e.code,\n\t\t\t\t};\n\t\t\tif (e instanceof PyError) {\n\t\t\t\tthis.stderr.push(e.toString());\n\t\t\t\treturn {\n\t\t\t\t\tstdout: this.getOutput(),\n\t\t\t\t\tstderr: this.getStderr(),\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (e instanceof ReturnSignal)\n\t\t\t\treturn {\n\t\t\t\t\tstdout: this.getOutput(),\n\t\t\t\t\tstderr: this.getStderr(),\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\tthis.stderr.push(`RuntimeError: ${e}`);\n\t\t\treturn {\n\t\t\t\tstdout: this.getOutput(),\n\t\t\t\tstderr: this.getStderr(),\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t\treturn { stdout: this.getOutput(), stderr: this.getStderr(), exitCode: 0 };\n\t}\n}\n\n// Polyfill: Map doesn't have .also in TS\ndeclare global {\n\tinterface Map<K, V> {\n\t\talso?: ((fn: (m: Map<K, V>) => void) => Map<K, V>) | undefined;\n\t}\n}\n\n// \u2500\u2500\u2500 command \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Virtual Python 3 interpreter command. Implements a small Python subset\n * for scripts and `-c` invocations. Requires `apt install python3` in the\n * virtual package manager to be available.\n * @category system\n * @params [\"[--version] [-c <code>] [-V] [file]\"]\n */\nexport const python3Command: ShellModule = {\n\tname: \"python3\",\n\taliases: [\"python\"],\n\tdescription: \"Python 3 interpreter (virtual)\",\n\tcategory: \"system\",\n\tparams: [\"[--version] [-c <code>] [-V] [file]\"],\n\trun: ({ args, shell, cwd }) => {\n\t\t// Require explicit installation via `apt install python3`\n\t\tif (!shell.packageManager.isInstalled(\"python3\")) {\n\t\t\treturn {\n\t\t\t\tstderr:\n\t\t\t\t\t\"bash: python3: command not found\\nHint: install it with: apt install python3\\n\",\n\t\t\t\texitCode: 127,\n\t\t\t};\n\t\t}\n\t\tif (ifFlag(args, [\"--version\", \"-V\"])) {\n\t\t\treturn { stdout: `${VERSION}\\n`, exitCode: 0 };\n\t\t}\n\t\tif (ifFlag(args, [\"--version-full\"])) {\n\t\t\treturn { stdout: `${VERSION_INFO}\\n`, exitCode: 0 };\n\t\t}\n\n\t\tconst cIdx = args.indexOf(\"-c\");\n\t\tif (cIdx !== -1) {\n\t\t\tconst code = args[cIdx + 1];\n\t\t\tif (!code)\n\t\t\t\treturn {\n\t\t\t\t\tstderr: \"python3: -c requires a code argument\\n\",\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t// Handle \\n as actual newlines\n\t\t\tconst normalised = code.replace(/\\\\n/g, \"\\n\").replace(/\\\\t/g, \"\\t\");\n\t\t\tconst interp = new Interpreter(cwd);\n\t\t\tconst { stdout, stderr, exitCode } = interp.run(normalised);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || undefined,\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\tconst file = args.find((a) => !a.startsWith(\"-\"));\n\t\tif (file) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\tif (!shell.vfs.exists(filePath)) {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `python3: can't open file '${file}': [Errno 2] No such file or directory\\n`,\n\t\t\t\t\texitCode: 2,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst code = shell.vfs.readFile(filePath);\n\t\t\tconst interp = new Interpreter(cwd);\n\t\t\tconst { stdout, stderr, exitCode } = interp.run(code);\n\t\t\treturn {\n\t\t\t\tstdout: stdout || undefined,\n\t\t\t\tstderr: stderr || undefined,\n\t\t\t\texitCode,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstdout: `${VERSION_INFO}\\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\\n>>> `,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const readCommand: ShellModule = {\n\tname: \"read\",\n\tdescription: \"Read a line from stdin into variables\",\n\tcategory: \"shell\",\n\tparams: [\"[-r] [-p prompt] <var...>\"],\n\trun: ({ args, stdin, env }) => {\n\t\tconst _promptIdx = args.indexOf(\"-p\");\n\t\tconst varNames = args.filter(\n\t\t\t(a, i) => a !== \"-r\" && a !== \"-p\" && args[i - 1] !== \"-p\",\n\t\t);\n\n\t\t// In non-interactive context, read from stdin pipe\n\t\tconst input = (stdin ?? \"\").split(\"\\n\")[0] ?? \"\";\n\t\tconst line = ifFlag(args, [\"-r\"])\n\t\t\t? input\n\t\t\t: input.replace(/\\\\(?:\\r?\\n|.)/g, (m) =>\n\t\t\t\t\tm[1] === \"\\n\" || m[1] === \"\\r\" ? \"\" : m[1]!,\n\t\t\t\t);\n\n\t\tif (!env) return { exitCode: 0 };\n\n\t\tif (varNames.length === 0) {\n\t\t\t// No var names: store into REPLY\n\t\t\tenv.vars.REPLY = line;\n\t\t} else if (varNames.length === 1) {\n\t\t\tenv.vars[varNames[0]!] = line;\n\t\t} else {\n\t\t\t// Split on whitespace, last var gets remainder\n\t\t\tconst parts = line.split(/\\s+/);\n\t\t\tfor (let i = 0; i < varNames.length; i++) {\n\t\t\t\tenv.vars[varNames[i]!] =\n\t\t\t\t\ti < varNames.length - 1 ? (parts[i] ?? \"\") : parts.slice(i).join(\" \");\n\t\t\t}\n\t\t}\n\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg, ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const rmCommand: ShellModule = {\n\tname: \"rm\",\n\tdescription: \"Remove files or directories\",\n\tcategory: \"files\",\n\tparams: [\"[-r|-rf] <path>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tif (args.length === 0) {\n\t\t\treturn { stderr: \"rm: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tconst recursive = ifFlag(args, [\"-r\", \"-rf\", \"-fr\"]);\n\t\tconst targets: string[] = [];\n\t\tfor (let index = 0; ; index += 1) {\n\t\t\tconst target = getArg(args, index, { flags: [\"-r\", \"-rf\", \"-fr\"] });\n\t\t\tif (!target) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ttargets.push(target);\n\t\t}\n\n\t\tif (targets.length === 0) {\n\t\t\treturn { stderr: \"rm: missing operand\", exitCode: 1 };\n\t\t}\n\n\t\tfor (const target of targets) {\n\t\t\tconst resolvedTarget = resolvePath(cwd, target);\n\t\t\tassertPathAccess(authUser, resolvedTarget, \"rm\");\n\t\t\tshell.vfs.remove(resolvedTarget, { recursive });\n\t\t}\n\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag, ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nexport const sedCommand: ShellModule = {\n\tname: \"sed\",\n\tdescription: \"Stream editor for filtering and transforming text\",\n\tcategory: \"text\",\n\tparams: [\"-e <expr> [file]\", \"s/pattern/replace/[g]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst inPlace = ifFlag(args, [\"-i\"]);\n\t\tconst expr =\n\t\t\t(getFlag(args, [\"-e\"]) as string | undefined) ??\n\t\t\targs.find((a) => !a.startsWith(\"-\"));\n\t\tconst fileArg = args.filter((a) => !a.startsWith(\"-\") && a !== expr).pop();\n\n\t\tif (!expr) return { stderr: \"sed: no expression\", exitCode: 1 };\n\n\t\tlet content = stdin ?? \"\";\n\t\tif (fileArg) {\n\t\t\tconst p = resolvePath(cwd, fileArg);\n\t\t\ttry {\n\t\t\t\tcontent = shell.vfs.readFile(p);\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `sed: ${fileArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Parse s/from/to/[g]\n\t\tconst sMatch = expr.match(/^s([^a-zA-Z0-9])(.+?)\\1(.*?)\\1([gi]*)$/);\n\t\tif (!sMatch)\n\t\t\treturn { stderr: `sed: unrecognized command: ${expr}`, exitCode: 1 };\n\n\t\tconst [, , from, to, flags] = sMatch;\n\t\tconst regexFlags = (flags ?? \"\").includes(\"i\")\n\t\t\t? \"gi\"\n\t\t\t: (flags ?? \"\").includes(\"g\")\n\t\t\t\t? \"g\"\n\t\t\t\t: \"\";\n\t\tlet regex: RegExp;\n\t\ttry {\n\t\t\tregex = new RegExp(from!, regexFlags || \"\");\n\t\t} catch (_e) {\n\t\t\treturn { stderr: `sed: invalid regex: ${from}`, exitCode: 1 };\n\t\t}\n\n\t\tconst result =\n\t\t\t(flags ?? \"\").includes(\"g\") || regexFlags.includes(\"g\")\n\t\t\t\t? content.replace(regex, to ?? \"\")\n\t\t\t\t: content.replace(regex, to ?? \"\");\n\n\t\tif (inPlace && fileArg) {\n\t\t\tconst p = resolvePath(cwd, fileArg);\n\t\t\tshell.writeFileAsUser(authUser, p, result);\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\treturn { stdout: result, exitCode: 0 };\n\t},\n};\n", "import type {\n CommandContext,\n CommandResult,\n ShellModule,\n} from \"../types/commands\";\nimport { expandAsync } from \"../utils/expand\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\nimport { runCommand } from \"./runtime\";\n\n/** Alias for clarity inside sh.ts */\ntype ShellContext = CommandContext;\n\n/**\n * Expand all shell forms including $(cmd) substitution.\n * Delegates to centralised expandAsync (single-quote-aware, depth-tracked).\n */\nasync function expandVars(\n\tline: string,\n\tenv: Record<string, string>,\n\tlastExit: number,\n\tctx: ShellContext,\n): Promise<string> {\n\treturn expandAsync(line, env, lastExit, (sub) =>\n\t\trunCommand(\n\t\t\tsub,\n\t\t\tctx.authUser,\n\t\t\tctx.hostname,\n\t\t\tctx.mode,\n\t\t\tctx.cwd,\n\t\t\tctx.shell,\n\t\t\tundefined,\n\t\t\tctx.env,\n\t\t).then((r) => r.stdout ?? \"\"),\n\t);\n}\n\ntype Block =\n\t| {\n\t\t\ttype: \"if\";\n\t\t\tcond: string;\n\t\t\tthen_: string[];\n\t\t\telif: Array<{ cond: string; body: string[] }>;\n\t\t\telse_: string[];\n\t }\n\t| { type: \"for\"; var: string; list: string; body: string[] }\n\t| { type: \"while\"; cond: string; body: string[] }\n\t| { type: \"cmd\"; line: string };\n\n/** Very small shell interpreter: supports if/elif/else/fi, for/do/done, while/do/done */\nfunction parseBlocks(lines: string[]): Block[] {\n\tconst blocks: Block[] = [];\n\tlet i = 0;\n\twhile (i < lines.length) {\n\t\tconst line = lines[i]!.trim();\n\t\tif (!line || line.startsWith(\"#\")) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (line.startsWith(\"if \") || line === \"if\") {\n\t\t\tconst cond = line\n\t\t\t\t.replace(/^if\\s+/, \"\")\n\t\t\t\t.replace(/;\\s*then\\s*$/, \"\")\n\t\t\t\t.trim();\n\t\t\tconst thenLines: string[] = [];\n\t\t\tconst elifBlocks: Array<{ cond: string; body: string[] }> = [];\n\t\t\tconst elseLines: string[] = [];\n\t\t\tlet section: \"then\" | \"elif\" | \"else\" = \"then\";\n\t\t\tlet elifCond = \"\";\n\t\t\ti++;\n\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"fi\") {\n\t\t\t\tconst l = lines[i]!.trim();\n\t\t\t\tif (l.startsWith(\"elif \")) {\n\t\t\t\t\tsection = \"elif\";\n\t\t\t\t\telifCond = l\n\t\t\t\t\t\t.replace(/^elif\\s+/, \"\")\n\t\t\t\t\t\t.replace(/;\\s*then\\s*$/, \"\")\n\t\t\t\t\t\t.trim();\n\t\t\t\t\telifBlocks.push({ cond: elifCond, body: [] });\n\t\t\t\t} else if (l === \"else\") {\n\t\t\t\t\tsection = \"else\";\n\t\t\t\t} else if (l !== \"then\") {\n\t\t\t\t\tif (section === \"then\") thenLines.push(l);\n\t\t\t\t\telse if (section === \"elif\" && elifBlocks.length > 0)\n\t\t\t\t\t\telifBlocks[elifBlocks.length - 1]!.body.push(l);\n\t\t\t\t\telse elseLines.push(l);\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tblocks.push({\n\t\t\t\ttype: \"if\",\n\t\t\t\tcond,\n\t\t\t\tthen_: thenLines,\n\t\t\t\telif: elifBlocks,\n\t\t\t\telse_: elseLines,\n\t\t\t});\n\t\t} else if (line.startsWith(\"for \")) {\n\t\t\tconst m = line.match(/^for\\s+(\\w+)\\s+in\\s+(.+?)(?:\\s*;\\s*do)?$/);\n\t\t\tif (m) {\n\t\t\t\tconst body: string[] = [];\n\t\t\t\ti++;\n\t\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"done\") {\n\t\t\t\t\tconst l = lines[i]!.trim().replace(/^do\\s+/, \"\");\n\t\t\t\t\tif (l && l !== \"do\") body.push(l);\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\tblocks.push({ type: \"for\", var: m[1]!, list: m[2]!, body });\n\t\t\t} else {\n\t\t\t\tblocks.push({ type: \"cmd\", line });\n\t\t\t}\n\t\t} else if (line.startsWith(\"while \")) {\n\t\t\tconst cond = line\n\t\t\t\t.replace(/^while\\s+/, \"\")\n\t\t\t\t.replace(/;\\s*do\\s*$/, \"\")\n\t\t\t\t.trim();\n\t\t\tconst body: string[] = [];\n\t\t\ti++;\n\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"done\") {\n\t\t\t\tconst l = lines[i]!.trim().replace(/^do\\s+/, \"\");\n\t\t\t\tif (l && l !== \"do\") body.push(l);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tblocks.push({ type: \"while\", cond, body });\n\t\t} else {\n\t\t\tblocks.push({ type: \"cmd\", line });\n\t\t}\n\t\ti++;\n\t}\n\treturn blocks;\n}\n\nasync function evalCondition(\n\tcond: string,\n\tctx: CommandContext,\n): Promise<boolean> {\n\tconst expanded = await expandVars(\n\t\tcond,\n\t\tctx.env.vars,\n\t\tctx.env.lastExitCode,\n\t\tctx,\n\t);\n\t// test -f / test -d / [ ... ]\n\tconst testMatch = expanded.match(/^\\[?\\s*(.+?)\\s*\\]?$/);\n\tif (testMatch) {\n\t\tconst expr = testMatch[1]!;\n\t\t// -f file\n\t\tconst fTest = expr.match(/^-([fdeznr])\\s+(.+)$/);\n\t\tif (fTest) {\n\t\t\tconst [, flag, arg] = fTest;\n\t\t\tconst p = resolvePath(ctx.cwd, arg!);\n\t\t\tif (flag === \"f\")\n\t\t\t\treturn ctx.shell.vfs.exists(p) && ctx.shell.vfs.stat(p).type === \"file\";\n\t\t\tif (flag === \"d\")\n\t\t\t\treturn (\n\t\t\t\t\tctx.shell.vfs.exists(p) && ctx.shell.vfs.stat(p).type === \"directory\"\n\t\t\t\t);\n\t\t\tif (flag === \"e\") return ctx.shell.vfs.exists(p);\n\t\t\tif (flag === \"z\") return (arg ?? \"\").length === 0;\n\t\t\tif (flag === \"n\") return (arg ?? \"\").length > 0;\n\t\t}\n\t\t// string comparison\n\t\tconst cmpMatch = expr.match(/^\"?([^\"]*)\"?\\s*(==|!=|=|<|>)\\s*\"?([^\"]*)\"?$/);\n\t\tif (cmpMatch) {\n\t\t\tconst [, a, op, b] = cmpMatch;\n\t\t\tif (op === \"==\" || op === \"=\") return a === b;\n\t\t\tif (op === \"!=\") return a !== b;\n\t\t}\n\t\t// numeric\n\t\tconst numMatch = expr.match(/^(\\S+)\\s+(-eq|-ne|-lt|-le|-gt|-ge)\\s+(\\S+)$/);\n\t\tif (numMatch) {\n\t\t\tconst [, a, op, b] = numMatch;\n\t\t\tconst na = Number(a),\n\t\t\t\tnb = Number(b);\n\t\t\tif (op === \"-eq\") return na === nb;\n\t\t\tif (op === \"-ne\") return na !== nb;\n\t\t\tif (op === \"-lt\") return na < nb;\n\t\t\tif (op === \"-le\") return na <= nb;\n\t\t\tif (op === \"-gt\") return na > nb;\n\t\t\tif (op === \"-ge\") return na >= nb;\n\t\t}\n\t}\n\t// fallback: run command and check exit code\n\tconst r = await runCommand(\n\t\texpanded,\n\t\tctx.authUser,\n\t\tctx.hostname,\n\t\tctx.mode,\n\t\tctx.cwd,\n\t\tctx.shell,\n\t\tundefined,\n\t\tctx.env,\n\t);\n\treturn (r.exitCode ?? 0) === 0;\n}\n\nasync function runBlocks(\n\tblocks: Block[],\n\tctx: CommandContext,\n): Promise<CommandResult> {\n\tlet lastResult: CommandResult = { exitCode: 0 };\n\tlet output = \"\";\n\n\tfor (const block of blocks) {\n\t\tif (block.type === \"cmd\") {\n\t\t\tconst expanded = await expandVars(\n\t\t\t\tblock.line,\n\t\t\t\tctx.env.vars,\n\t\t\t\tctx.env.lastExitCode,\n\t\t\t\tctx,\n\t\t\t);\n\n\t\t\t// Bare VAR=val assignment(s) \u2014 handle before dispatching to runCommand\n\t\t\tconst assignRe = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)/;\n\t\t\tconst tokens = expanded.trim().split(/\\s+/);\n\t\t\tif (tokens.length > 0 && assignRe.test(tokens[0]!)) {\n\t\t\t\tconst allAssign = tokens.every((t) => assignRe.test(t));\n\t\t\t\tif (allAssign) {\n\t\t\t\t\tfor (const tok of tokens) {\n\t\t\t\t\t\tconst m = tok.match(assignRe)!;\n\t\t\t\t\t\tctx.env.vars[m[1]!] = m[2]!;\n\t\t\t\t\t}\n\t\t\t\t\tctx.env.lastExitCode = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst r = await runCommand(\n\t\t\t\texpanded,\n\t\t\t\tctx.authUser,\n\t\t\t\tctx.hostname,\n\t\t\t\tctx.mode,\n\t\t\t\tctx.cwd,\n\t\t\t\tctx.shell,\n\t\t\t\tundefined,\n\t\t\t\tctx.env,\n\t\t\t);\n\t\t\tctx.env.lastExitCode = r.exitCode ?? 0;\n\t\t\tif (r.stdout) output += `${r.stdout}\\n`;\n\t\t\tif (r.stderr) return { ...r, stdout: output.trim() };\n\t\t\tlastResult = r;\n\t\t} else if (block.type === \"if\") {\n\t\t\tlet ran = false;\n\t\t\tif (await evalCondition(block.cond, ctx)) {\n\t\t\t\tconst sub = await runBlocks(parseBlocks(block.then_), ctx);\n\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\tran = true;\n\t\t\t} else {\n\t\t\t\tfor (const elif of block.elif) {\n\t\t\t\t\tif (await evalCondition(elif.cond, ctx)) {\n\t\t\t\t\t\tconst sub = await runBlocks(parseBlocks(elif.body), ctx);\n\t\t\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\t\t\tran = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!ran && block.else_.length > 0) {\n\t\t\t\t\tconst sub = await runBlocks(parseBlocks(block.else_), ctx);\n\t\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (block.type === \"for\") {\n\t\t\tconst listExpanded = await expandVars(\n\t\t\t\tblock.list,\n\t\t\t\tctx.env.vars,\n\t\t\t\tctx.env.lastExitCode,\n\t\t\t\tctx,\n\t\t\t);\n\t\t\tconst items = listExpanded.trim().split(/\\s+/);\n\t\t\tfor (const item of items) {\n\t\t\t\tctx.env.vars[block.var] = item;\n\t\t\t\tconst sub = await runBlocks(parseBlocks(block.body), ctx);\n\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\tif (sub.closeSession) return sub;\n\t\t\t}\n\t\t} else if (block.type === \"while\") {\n\t\t\tlet iterations = 0;\n\t\t\twhile (iterations < 1000 && (await evalCondition(block.cond, ctx))) {\n\t\t\t\tconst sub = await runBlocks(parseBlocks(block.body), ctx);\n\t\t\t\tif (sub.stdout) output += `${sub.stdout}\\n`;\n\t\t\t\tif (sub.closeSession) return sub;\n\t\t\t\titerations++;\n\t\t\t}\n\t\t}\n\t}\n\treturn { ...lastResult, stdout: output.trim() || lastResult.stdout };\n}\n\nexport const shCommand: ShellModule = {\n\tname: \"sh\",\n\taliases: [\"bash\"],\n\tdescription: \"Execute shell script or command\",\n\tcategory: \"shell\",\n\tparams: [\"-c <script>\", \"[<file>]\"],\n\trun: async (ctx: CommandContext) => {\n\t\tconst { args, shell, cwd } = ctx;\n\n\t\t// sh -c \"inline script\"\n\t\tif (ifFlag(args, \"-c\")) {\n\t\t\tconst script = args[args.indexOf(\"-c\") + 1] ?? \"\";\n\t\t\tif (!script) return { stderr: \"sh: -c requires a script\", exitCode: 1 };\n\t\t\tconst lines = script\n\t\t\t\t.split(/[;\\n]/)\n\t\t\t\t.map((l) => l.trim())\n\t\t\t\t.filter((l) => l && !l.startsWith(\"#\"));\n\t\t\tconst blocks = parseBlocks(lines);\n\t\t\treturn runBlocks(blocks, ctx);\n\t\t}\n\n\t\t// sh <file>\n\t\tconst fileArg = args[0];\n\t\tif (fileArg) {\n\t\t\tconst p = resolvePath(cwd, fileArg);\n\t\t\tif (!shell.vfs.exists(p))\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `sh: ${fileArg}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\tconst content = shell.vfs.readFile(p);\n\t\t\tconst lines = content\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((l) => l.trim())\n\t\t\t\t.filter((l) => l && !l.startsWith(\"#\"));\n\t\t\tconst blocks = parseBlocks(lines);\n\t\t\treturn runBlocks(blocks, ctx);\n\t\t}\n\n\t\treturn {\n\t\t\tstderr: \"sh: invalid usage. Use: sh -c 'cmd' or sh <file>\",\n\t\t\texitCode: 1,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const shiftCommand: ShellModule = {\n\tname: \"shift\",\n\tdescription: \"Shift positional parameters\",\n\tcategory: \"shell\",\n\tparams: [\"[n]\"],\n\t// shift is meaningful only inside sh scripts where positional params exist.\n\t// In the current impl, positional params ($1 $2 \u2026) aren't tracked in env by default.\n\t// We store them under env.vars.__argv and shift there if present.\n\trun: ({ args, env }) => {\n\t\tif (!env) return { exitCode: 0 };\n\t\tconst n = parseInt(args[0] ?? \"1\", 10) || 1;\n\t\tconst argv = env.vars.__argv?.split(\"\\x00\").filter(Boolean) ?? [];\n\t\tenv.vars.__argv = argv.slice(n).join(\"\\x00\");\n\t\t// Update $1 $2 \u2026 in env\n\t\tconst shifted = argv.slice(n);\n\t\tfor (let i = 1; i <= 9; i++) {\n\t\t\tenv.vars[String(i)] = shifted[i - 1] ?? \"\";\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n\nexport const trapCommand: ShellModule = {\n\tname: \"trap\",\n\tdescription: \"Trap signals and events\",\n\tcategory: \"shell\",\n\tparams: [\"[action] [signal...]\"],\n\t// Store trap handlers in env for EXIT signal support\n\trun: ({ args, env }) => {\n\t\tif (!env || args.length === 0) return { exitCode: 0 };\n\t\tconst action = args[0] ?? \"\";\n\t\tconst signals = args.slice(1);\n\t\tfor (const sig of signals) {\n\t\t\tenv.vars[`__trap_${sig.toUpperCase()}`] = action;\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n\nexport const returnCommand: ShellModule = {\n\tname: \"return\",\n\tdescription: \"Return from a shell function\",\n\tcategory: \"shell\",\n\tparams: [\"[n]\"],\n\trun: ({ args, env }) => {\n\t\tconst code = parseInt(args[0] ?? \"0\", 10);\n\t\tif (env) env.lastExitCode = code;\n\t\t// Signal the caller via exitCode; function return is handled by runBlocks\n\t\treturn { exitCode: code };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const sleepCommand: ShellModule = {\n\tname: \"sleep\",\n\tdescription: \"Delay execution\",\n\tcategory: \"system\",\n\tparams: [\"<seconds>\"],\n\trun: async ({ args }) => {\n\t\tconst secs = parseFloat(args[0] ?? \"1\");\n\t\tif (Number.isNaN(secs) || secs < 0)\n\t\t\treturn { stderr: \"sleep: invalid time\", exitCode: 1 };\n\t\tawait new Promise((r) => setTimeout(r, secs * 1000));\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const sortCommand: ShellModule = {\n\tname: \"sort\",\n\tdescription: \"Sort lines of text\",\n\tcategory: \"text\",\n\tparams: [\"[-r] [-n] [-u] [-k <col>] [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst reverse = ifFlag(args, [\"-r\"]);\n\t\tconst numeric = ifFlag(args, [\"-n\"]);\n\t\tconst unique = ifFlag(args, [\"-u\"]);\n\t\tconst files = args.filter((a) => !a.startsWith(\"-\"));\n\n\t\tconst getContent = (): string => {\n\t\t\tif (files.length > 0) {\n\t\t\t\treturn files\n\t\t\t\t\t.map((f) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tassertPathAccess(authUser, resolvePath(cwd, f), \"sort\");\n\t\t\t\t\t\t\treturn shell.vfs.readFile(resolvePath(cwd, f));\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t}\n\t\t\treturn stdin ?? \"\";\n\t\t};\n\n\t\tconst lines = getContent().split(\"\\n\").filter(Boolean);\n\t\tconst sorted = [...lines].sort((a, b) => {\n\t\t\tif (numeric) return Number(a) - Number(b);\n\t\t\treturn a.localeCompare(b);\n\t\t});\n\t\tconst result = reverse ? sorted.reverse() : sorted;\n\t\tconst out = unique ? [...new Set(result)] : result;\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { resolvePath } from \"./helpers\";\nimport { runCommand } from \"./runtime\";\n\nexport const sourceCommand: ShellModule = {\n\tname: \"source\",\n\taliases: [\".\"],\n\tdescription: \"Execute commands from a file in the current shell environment\",\n\tcategory: \"shell\",\n\tparams: [\"<file> [args...]\"],\n\trun: async ({ args, authUser, hostname, cwd, shell, env }) => {\n\t\tconst fileArg = args[0];\n\t\tif (!fileArg) {\n\t\t\treturn { stderr: \"source: missing filename\", exitCode: 1 };\n\t\t}\n\n\t\tconst filePath = resolvePath(cwd, fileArg);\n\t\tif (!shell.vfs.exists(filePath)) {\n\t\t\treturn {\n\t\t\t\tstderr: `source: ${fileArg}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\n\t\tconst content = shell.vfs.readFile(filePath);\n\t\tlet lastExitCode = 0;\n\n\t\tfor (const line of content.split(\"\\n\")) {\n\t\t\tconst l = line.trim();\n\t\t\tif (!l || l.startsWith(\"#\")) continue;\n\t\t\tconst result = await runCommand(\n\t\t\t\tl,\n\t\t\t\tauthUser,\n\t\t\t\thostname,\n\t\t\t\t\"shell\",\n\t\t\t\tcwd,\n\t\t\t\tshell,\n\t\t\t\tundefined,\n\t\t\t\tenv,\n\t\t\t);\n\t\t\tlastExitCode = result.exitCode ?? 0;\n\t\t\tif (result.closeSession || result.switchUser) return result;\n\t\t}\n\n\t\treturn { exitCode: lastExitCode };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg } from \"./command-helpers\";\n\nexport const suCommand: ShellModule = {\n\tname: \"su\",\n\tdescription: \"Switch user\",\n\tcategory: \"users\",\n\tparams: [\"- <username>\"],\n\trun: ({ authUser, shell, args }) => {\n\t\tconst users = shell.users!;\n\t\tconst targetUser = getArg(args, 0, { flags: [\"-\"] });\n\n\t\tif (!targetUser) {\n\t\t\treturn { stderr: \"su: missing username\", exitCode: 1 };\n\t\t}\n\n\t\tif (!users.isSudoer(authUser) && authUser !== \"root\") {\n\t\t\treturn { stderr: \"su: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tif (\n\t\t\t!users.verifyPassword(targetUser, getArg(args, 1) ?? \"\") &&\n\t\t\tauthUser !== \"root\"\n\t\t) {\n\t\t\treturn { stderr: \"su: authentication failure\", exitCode: 1 };\n\t\t}\n\n\t\treturn {\n\t\t\tswitchUser: targetUser,\n\t\t\tnextCwd: `/home/${targetUser}`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { parseArgs } from \"./command-helpers\";\nimport { runCommand } from \"./runtime\";\n\nfunction parseSudoArgs(args: string[]): {\n\ttargetUser: string;\n\tloginShell: boolean;\n\tcommandLine: string | null;\n} {\n\tconst { flags, flagsWithValues, positionals } = parseArgs(args, {\n\t\tflags: [\"-i\", \"-S\"],\n\t\tflagsWithValue: [\"-u\", \"--user\"],\n\t});\n\n\tconst loginShell = flags.has(\"-i\");\n\tconst targetUser =\n\t\tflagsWithValues.get(\"-u\") || flagsWithValues.get(\"--user\") || \"root\";\n\tconst commandLine = positionals.length > 0 ? positionals.join(\" \") : null;\n\n\treturn { targetUser, loginShell, commandLine };\n}\nexport const sudoCommand: ShellModule = {\n\tname: \"sudo\",\n\tdescription: \"Execute as superuser\",\n\tcategory: \"users\",\n\tparams: [\"<command...>\"],\n\trun: async ({ authUser, hostname, mode, cwd, shell, args }) => {\n\t\tconst { targetUser, loginShell, commandLine } = parseSudoArgs(args);\n\n\t\tif (authUser !== \"root\" && !shell.users.isSudoer(authUser)) {\n\t\t\treturn { stderr: \"sudo: permission denied\", exitCode: 1 };\n\t\t}\n\n\t\tconst effectiveUser = targetUser || \"root\";\n\t\tconst prompt = `[sudo] password for ${authUser}: `;\n\n\t\tif (authUser === \"root\") {\n\t\t\tif (!commandLine && loginShell) {\n\t\t\t\treturn {\n\t\t\t\t\tswitchUser: effectiveUser,\n\t\t\t\t\tnextCwd: `/home/${effectiveUser}`,\n\t\t\t\t\texitCode: 0,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (!commandLine) {\n\t\t\t\treturn { stderr: \"sudo: missing command\", exitCode: 1 };\n\t\t\t}\n\n\t\t\treturn runCommand(\n\t\t\t\tcommandLine,\n\t\t\t\teffectiveUser,\n\t\t\t\thostname,\n\t\t\t\tmode,\n\t\t\t\tloginShell ? `/home/${effectiveUser}` : cwd,\n\t\t\t\tshell,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tsudoChallenge: {\n\t\t\t\tusername: authUser,\n\t\t\t\ttargetUser: effectiveUser,\n\t\t\t\tcommandLine,\n\t\t\t\tloginShell,\n\t\t\t\tprompt,\n\t\t\t},\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const tailCommand: ShellModule = {\n\tname: \"tail\",\n\tdescription: \"Output last lines\",\n\tcategory: \"text\",\n\tparams: [\"[-n <lines>] [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst nArg = getFlag(args, [\"-n\"]);\n\t\tconst n = typeof nArg === \"string\" ? parseInt(nArg, 10) : 10;\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\") && a !== nArg);\n\n\t\tconst take = (content: string) => {\n\t\t\tconst lines = content.split(\"\\n\");\n\t\t\treturn lines.slice(Math.max(0, lines.length - n)).join(\"\\n\");\n\t\t};\n\n\t\tif (positionals.length === 0) {\n\t\t\treturn { stdout: take(stdin ?? \"\"), exitCode: 0 };\n\t\t}\n\n\t\tconst results: string[] = [];\n\t\tfor (const file of positionals) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\ttry {\n\t\t\t\tassertPathAccess(authUser, filePath, \"tail\");\n\t\t\t\tresults.push(take(shell.vfs.readFile(filePath)));\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `tail: ${file}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn { stdout: results.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nexport const tarCommand: ShellModule = {\n\tname: \"tar\",\n\tdescription: \"Archive utility\",\n\tcategory: \"archive\",\n\tparams: [\"[-czf|-xzf|-tf] <archive> [files...]\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst create = ifFlag(args, [\"-c\"]);\n\t\tconst extract = ifFlag(args, [\"-x\"]);\n\t\tconst list = ifFlag(args, [\"-t\"]);\n\t\tconst fFlag = args.findIndex((a) => a.includes(\"f\"));\n\t\tconst archiveName =\n\t\t\tfFlag !== -1\n\t\t\t\t? args[fFlag + 1]\n\t\t\t\t: args.find(\n\t\t\t\t\t\t(a) =>\n\t\t\t\t\t\t\ta.endsWith(\".tar\") || a.endsWith(\".tar.gz\") || a.endsWith(\".tgz\"),\n\t\t\t\t\t);\n\n\t\tif (!archiveName)\n\t\t\treturn { stderr: \"tar: no archive specified\", exitCode: 1 };\n\t\tconst archivePath = resolvePath(cwd, archiveName);\n\n\t\tif (create) {\n\t\t\tconst fileArgs = args.filter(\n\t\t\t\t(a) => !a.startsWith(\"-\") && a !== archiveName,\n\t\t\t);\n\t\t\tconst entries: Record<string, string> = {};\n\t\t\tfor (const f of fileArgs) {\n\t\t\t\tconst p = resolvePath(cwd, f);\n\t\t\t\ttry {\n\t\t\t\t\tconst stat = shell.vfs.stat(p);\n\t\t\t\t\tif (stat.type === \"file\") entries[f] = shell.vfs.readFile(p);\n\t\t\t\t\telse {\n\t\t\t\t\t\tconst walk = (dir: string, prefix: string) => {\n\t\t\t\t\t\t\tfor (const e of shell.vfs.list(dir)) {\n\t\t\t\t\t\t\t\tconst full = `${dir}/${e}`,\n\t\t\t\t\t\t\t\t\trel = `${prefix}/${e}`;\n\t\t\t\t\t\t\t\tconst s = shell.vfs.stat(full);\n\t\t\t\t\t\t\t\tif (s.type === \"file\") entries[rel] = shell.vfs.readFile(full);\n\t\t\t\t\t\t\t\telse walk(full, rel);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\twalk(p, f);\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstderr: `tar: ${f}: No such file or directory`,\n\t\t\t\t\t\texitCode: 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\tshell.writeFileAsUser(authUser, archivePath, JSON.stringify(entries));\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\tif (list || extract) {\n\t\t\tlet entries: Record<string, string>;\n\t\t\ttry {\n\t\t\t\tentries = JSON.parse(shell.vfs.readFile(archivePath));\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `tar: ${archiveName}: cannot open archive`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (list) return { stdout: Object.keys(entries).join(\"\\n\"), exitCode: 0 };\n\t\t\tfor (const [name, content] of Object.entries(entries)) {\n\t\t\t\tshell.writeFileAsUser(authUser, resolvePath(cwd, name), content);\n\t\t\t}\n\t\t\treturn { exitCode: 0 };\n\t\t}\n\n\t\treturn { stderr: \"tar: must specify -c, -x, or -t\", exitCode: 1 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { resolvePath } from \"./helpers\";\n\nexport const teeCommand: ShellModule = {\n\tname: \"tee\",\n\tdescription: \"Read stdin, write to stdout and files\",\n\tcategory: \"text\",\n\tparams: [\"[-a] <file...>\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst append = ifFlag(args, [\"-a\"]);\n\t\tconst files = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst input = stdin ?? \"\";\n\t\tfor (const f of files) {\n\t\t\tconst p = resolvePath(cwd, f);\n\t\t\tif (append) {\n\t\t\t\tconst existing = (() => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn shell.vfs.readFile(p);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t\tshell.writeFileAsUser(authUser, p, existing + input);\n\t\t\t} else {\n\t\t\t\tshell.writeFileAsUser(authUser, p, input);\n\t\t\t}\n\t\t}\n\t\treturn { stdout: input, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\n/**\n * Evaluate a POSIX test expression.\n * Supports: -f, -d, -e, -r, -w, -x, -s, -z, -n,\n * string =, !=, numeric -eq -ne -lt -le -gt -ge,\n * ! (negate), -a (and), -o (or).\n */\nfunction evalTest(\n\ttokens: string[],\n\tshell: import(\"../VirtualShell\").VirtualShell,\n\tcwd: string,\n): boolean {\n\t// When called via [ command, ] is the last arg \u2014 strip it\n\t// When called via test command, no brackets present\n\tif (tokens[tokens.length - 1] === \"]\") {\n\t\ttokens = tokens.slice(0, -1);\n\t}\n\t// Also strip leading [ if present (shouldn't normally happen but be safe)\n\tif (tokens[0] === \"[\") {\n\t\ttokens = tokens.slice(1);\n\t}\n\n\tif (tokens.length === 0) return false;\n\n\t// Negation\n\tif (tokens[0] === \"!\") return !evalTest(tokens.slice(1), shell, cwd);\n\n\t// Boolean -a / -o (simple left-right, no precedence)\n\tconst andIdx = tokens.indexOf(\"-a\");\n\tif (andIdx !== -1) {\n\t\treturn (\n\t\t\tevalTest(tokens.slice(0, andIdx), shell, cwd) &&\n\t\t\tevalTest(tokens.slice(andIdx + 1), shell, cwd)\n\t\t);\n\t}\n\tconst orIdx = tokens.indexOf(\"-o\");\n\tif (orIdx !== -1) {\n\t\treturn (\n\t\t\tevalTest(tokens.slice(0, orIdx), shell, cwd) ||\n\t\t\tevalTest(tokens.slice(orIdx + 1), shell, cwd)\n\t\t);\n\t}\n\n\t// Unary file tests\n\tif (tokens.length === 2) {\n\t\tconst [flag, operand = \"\"] = tokens;\n\t\tconst resolvePath = (p: string) =>\n\t\t\tp.startsWith(\"/\") ? p : `${cwd}/${p}`.replace(/\\/+/g, \"/\");\n\t\tconst path = resolvePath(operand);\n\n\t\tswitch (flag) {\n\t\t\tcase \"-e\":\n\t\t\t\treturn shell.vfs.exists(path);\n\t\t\tcase \"-f\":\n\t\t\t\treturn shell.vfs.exists(path) && shell.vfs.stat(path).type === \"file\";\n\t\t\tcase \"-d\":\n\t\t\t\treturn (\n\t\t\t\t\tshell.vfs.exists(path) && shell.vfs.stat(path).type === \"directory\"\n\t\t\t\t);\n\t\t\tcase \"-r\":\n\t\t\t\treturn shell.vfs.exists(path); // all readable in virtual env\n\t\t\tcase \"-w\":\n\t\t\t\treturn shell.vfs.exists(path);\n\t\t\tcase \"-x\":\n\t\t\t\treturn shell.vfs.exists(path) && !!(shell.vfs.stat(path).mode & 0o111);\n\t\t\tcase \"-s\":\n\t\t\t\treturn (\n\t\t\t\t\tshell.vfs.exists(path) &&\n\t\t\t\t\tshell.vfs.stat(path).type === \"file\" &&\n\t\t\t\t\t(shell.vfs.stat(path) as import(\"../types/vfs\").VfsFileNode).size > 0\n\t\t\t\t);\n\t\t\tcase \"-z\":\n\t\t\t\treturn operand.length === 0;\n\t\t\tcase \"-n\":\n\t\t\t\treturn operand.length > 0;\n\t\t\tcase \"-L\":\n\t\t\t\treturn shell.vfs.isSymlink(path);\n\t\t}\n\t}\n\n\t// Binary comparisons\n\tif (tokens.length === 3) {\n\t\tconst [left = \"\", op, right = \"\"] = tokens;\n\t\tconst leftN = Number(left);\n\t\tconst rightN = Number(right);\n\n\t\tswitch (op) {\n\t\t\t// String\n\t\t\tcase \"=\":\n\t\t\tcase \"==\":\n\t\t\t\treturn left === right;\n\t\t\tcase \"!=\":\n\t\t\t\treturn left !== right;\n\t\t\tcase \"<\":\n\t\t\t\treturn left < right;\n\t\t\tcase \">\":\n\t\t\t\treturn left > right;\n\t\t\t// Numeric\n\t\t\tcase \"-eq\":\n\t\t\t\treturn leftN === rightN;\n\t\t\tcase \"-ne\":\n\t\t\t\treturn leftN !== rightN;\n\t\t\tcase \"-lt\":\n\t\t\t\treturn leftN < rightN;\n\t\t\tcase \"-le\":\n\t\t\t\treturn leftN <= rightN;\n\t\t\tcase \"-gt\":\n\t\t\t\treturn leftN > rightN;\n\t\t\tcase \"-ge\":\n\t\t\t\treturn leftN >= rightN;\n\t\t}\n\t}\n\n\t// Single string (truthy if non-empty)\n\tif (tokens.length === 1) return (tokens[0] ?? \"\").length > 0;\n\n\treturn false;\n}\n\nexport const testCommand: ShellModule = {\n\tname: \"test\",\n\taliases: [\"[\"],\n\tdescription: \"Evaluate conditional expression\",\n\tcategory: \"shell\",\n\tparams: [\"<expression>\"],\n\trun: ({ args, shell, cwd }) => {\n\t\ttry {\n\t\t\tconst result = evalTest([...args], shell, cwd);\n\t\t\treturn { exitCode: result ? 0 : 1 };\n\t\t} catch {\n\t\t\treturn { stderr: \"test: malformed expression\", exitCode: 2 };\n\t\t}\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const touchCommand: ShellModule = {\n\tname: \"touch\",\n\tdescription: \"Create or update files\",\n\tcategory: \"files\",\n\tparams: [\"<file>\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tif (args.length === 0) {\n\t\t\treturn { stderr: \"touch: missing file operand\", exitCode: 1 };\n\t\t}\n\n\t\tfor (const file of args) {\n\t\t\tconst target = resolvePath(cwd, file);\n\t\t\tassertPathAccess(authUser, target, \"touch\");\n\t\t\tif (!shell.vfs.exists(target)) {\n\t\t\t\tshell.writeFileAsUser(authUser, target, \"\");\n\t\t\t}\n\t\t}\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const trCommand: ShellModule = {\n\tname: \"tr\",\n\tdescription: \"Translate or delete characters\",\n\tcategory: \"text\",\n\tparams: [\"[-d] <set1> [set2]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst del = ifFlag(args, [\"-d\"]);\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\t\tconst set1 = positionals[0] ?? \"\";\n\t\tconst set2 = positionals[1] ?? \"\";\n\t\tlet input = stdin ?? \"\";\n\t\tif (del) {\n\t\t\tfor (const c of set1) input = input.split(c).join(\"\");\n\t\t} else if (set2) {\n\t\t\tfor (let i = 0; i < set1.length; i++) {\n\t\t\t\tinput = input\n\t\t\t\t\t.split(set1[i]!)\n\t\t\t\t\t.join(set2[i] ?? set2[set2.length - 1] ?? \"\");\n\t\t\t}\n\t\t}\n\t\treturn { stdout: input, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { getArg } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const treeCommand: ShellModule = {\n\tname: \"tree\",\n\tdescription: \"Display directory tree\",\n\tcategory: \"navigation\",\n\tparams: [\"[path]\"],\n\trun: ({ authUser, shell, cwd, args }) => {\n\t\tconst target = resolvePath(cwd, getArg(args, 0) ?? cwd);\n\t\tassertPathAccess(authUser, target, \"tree\");\n\t\treturn { stdout: shell.vfs.tree(target), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const trueCommand: ShellModule = {\n\tname: \"true\",\n\tdescription: \"Return success exit code\",\n\tcategory: \"shell\",\n\tparams: [],\n\trun: () => ({ exitCode: 0 }),\n};\n\nexport const falseCommand: ShellModule = {\n\tname: \"false\",\n\tdescription: \"Return failure exit code\",\n\tcategory: \"shell\",\n\tparams: [],\n\trun: () => ({ exitCode: 1 }),\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { resolveModule } from \"./registry\";\n\nexport const typeCommand: ShellModule = {\n\tname: \"type\",\n\tdescription: \"Describe how a command would be interpreted\",\n\tcategory: \"shell\",\n\tparams: [\"<command...>\"],\n\trun: ({ args, shell, env }) => {\n\t\tif (args.length === 0)\n\t\t\treturn { stderr: \"type: missing argument\", exitCode: 1 };\n\n\t\tconst pathDirs = (env?.vars?.PATH ?? \"/usr/local/bin:/usr/bin:/bin\").split(\n\t\t\t\":\",\n\t\t);\n\t\tconst lines: string[] = [];\n\t\tlet exitCode = 0;\n\n\t\tfor (const name of args) {\n\t\t\tif (resolveModule(name)) {\n\t\t\t\tlines.push(`${name} is a shell builtin`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet found = false;\n\t\t\tfor (const dir of pathDirs) {\n\t\t\t\tconst full = `${dir}/${name}`;\n\t\t\t\tif (shell.vfs.exists(full)) {\n\t\t\t\t\tlines.push(`${name} is ${full}`);\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!found) {\n\t\t\t\tlines.push(`${name}: not found`);\n\t\t\t\texitCode = 1;\n\t\t\t}\n\t\t}\n\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const unameCommand: ShellModule = {\n\tname: \"uname\",\n\tdescription: \"Print system information\",\n\tcategory: \"system\",\n\tparams: [\"[-a] [-s] [-r] [-m]\"],\n\trun: ({ shell, args }) => {\n\t\tconst all = ifFlag(args, [\"-a\"]);\n\t\tconst sysname = \"Linux\";\n\t\tconst release = shell.properties?.kernel ?? \"5.15.0\";\n\t\tconst machine = shell.properties?.arch ?? \"x86_64\";\n\t\tconst hostname = shell.hostname;\n\t\tif (all)\n\t\t\treturn {\n\t\t\t\tstdout: `${sysname} ${hostname} ${release} #1 SMP ${machine} GNU/Linux`,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\tif (ifFlag(args, [\"-r\"])) return { stdout: release, exitCode: 0 };\n\t\tif (ifFlag(args, [\"-m\"])) return { stdout: machine, exitCode: 0 };\n\t\treturn { stdout: sysname, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const uniqCommand: ShellModule = {\n\tname: \"uniq\",\n\tdescription: \"Report or filter out repeated lines\",\n\tcategory: \"text\",\n\tparams: [\"[-c] [-d] [-u] [file]\"],\n\trun: ({ args, stdin }) => {\n\t\tconst count = ifFlag(args, [\"-c\"]);\n\t\tconst dupOnly = ifFlag(args, [\"-d\"]);\n\t\tconst uniqOnly = ifFlag(args, [\"-u\"]);\n\t\tconst lines = (stdin ?? \"\").split(\"\\n\");\n\t\tconst out: string[] = [];\n\t\tlet i = 0;\n\t\twhile (i < lines.length) {\n\t\t\tlet j = i;\n\t\t\twhile (j < lines.length && lines[j] === lines[i]) j++;\n\t\t\tconst n = j - i;\n\t\t\tconst line = lines[i]!;\n\t\t\tif (dupOnly && n === 1) {\n\t\t\t\ti = j;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (uniqOnly && n > 1) {\n\t\t\t\ti = j;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tout.push(count ? `${String(n).padStart(4)} ${line}` : line);\n\t\t\ti = j;\n\t\t}\n\t\treturn { stdout: out.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const unsetCommand: ShellModule = {\n\tname: \"unset\",\n\tdescription: \"Remove shell variable\",\n\tcategory: \"shell\",\n\tparams: [\"<VAR>\"],\n\trun: ({ args, env }) => {\n\t\tfor (const name of args) delete env.vars[name];\n\t\treturn { exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\n\nexport const uptimeCommand: ShellModule = {\n\tname: \"uptime\",\n\tdescription: \"Tell how long the system has been running\",\n\tcategory: \"system\",\n\tparams: [\"[-p] [-s]\"],\n\trun: ({ args, shell }) => {\n\t\tconst pretty = ifFlag(args, [\"-p\"]);\n\t\tconst since = ifFlag(args, [\"-s\"]);\n\n\t\tconst uptimeSec = Math.floor((Date.now() - shell.startTime) / 1000);\n\t\tconst days = Math.floor(uptimeSec / 86400);\n\t\tconst hours = Math.floor((uptimeSec % 86400) / 3600);\n\t\tconst mins = Math.floor((uptimeSec % 3600) / 60);\n\n\t\tif (since) {\n\t\t\treturn {\n\t\t\t\tstdout: new Date(shell.startTime)\n\t\t\t\t\t.toISOString()\n\t\t\t\t\t.slice(0, 19)\n\t\t\t\t\t.replace(\"T\", \" \"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tif (pretty) {\n\t\t\tconst parts: string[] = [];\n\t\t\tif (days > 0) parts.push(`${days} day${days > 1 ? \"s\" : \"\"}`);\n\t\t\tif (hours > 0) parts.push(`${hours} hour${hours > 1 ? \"s\" : \"\"}`);\n\t\t\tparts.push(`${mins} minute${mins !== 1 ? \"s\" : \"\"}`);\n\t\t\treturn { stdout: `up ${parts.join(\", \")}`, exitCode: 0 };\n\t\t}\n\n\t\tconst timeStr = new Date().toTimeString().slice(0, 8);\n\t\tconst uptimeStr =\n\t\t\tdays > 0\n\t\t\t\t? `${days} day${days > 1 ? \"s\" : \"\"}, ${String(hours).padStart(2)}:${String(mins).padStart(2, \"0\")}`\n\t\t\t\t: `${String(hours).padStart(2)}:${String(mins).padStart(2, \"0\")}`;\n\t\tconst sessions = shell.users.listActiveSessions().length;\n\t\tconst load = (Math.random() * 0.5).toFixed(2);\n\n\t\treturn {\n\t\t\tstdout: ` ${timeStr} up ${uptimeStr}, ${sessions} user${sessions !== 1 ? \"s\" : \"\"}, load average: ${load}, ${load}, ${load}`,\n\t\t\texitCode: 0,\n\t\t};\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath } from \"./helpers\";\n\nexport const wcCommand: ShellModule = {\n\tname: \"wc\",\n\tdescription: \"Count words/lines/bytes\",\n\tcategory: \"text\",\n\tparams: [\"[-l] [-w] [-c] [file...]\"],\n\trun: ({ authUser, shell, cwd, args, stdin }) => {\n\t\tconst lines = ifFlag(args, [\"-l\"]);\n\t\tconst words = ifFlag(args, [\"-w\"]);\n\t\tconst bytes = ifFlag(args, [\"-c\"]);\n\t\tconst showAll = !lines && !words && !bytes;\n\t\tconst positionals = args.filter((a) => !a.startsWith(\"-\"));\n\n\t\tconst count = (content: string, label: string): string => {\n\t\t\tconst l = content.split(\"\\n\").length - (content.endsWith(\"\\n\") ? 1 : 0);\n\t\t\tconst w = content.trim().split(/\\s+/).filter(Boolean).length;\n\t\t\tconst c = Buffer.byteLength(content, \"utf8\");\n\t\t\tconst parts: string[] = [];\n\t\t\tif (showAll || lines) parts.push(String(l).padStart(7));\n\t\t\tif (showAll || words) parts.push(String(w).padStart(7));\n\t\t\tif (showAll || bytes) parts.push(String(c).padStart(7));\n\t\t\tif (label) parts.push(` ${label}`);\n\t\t\treturn parts.join(\"\");\n\t\t};\n\n\t\tif (positionals.length === 0) {\n\t\t\tconst content = stdin ?? \"\";\n\t\t\treturn { stdout: count(content, \"\"), exitCode: 0 };\n\t\t}\n\n\t\tconst results: string[] = [];\n\t\tfor (const file of positionals) {\n\t\t\tconst filePath = resolvePath(cwd, file);\n\t\t\ttry {\n\t\t\t\tassertPathAccess(authUser, filePath, \"wc\");\n\t\t\t\tconst content = shell.vfs.readFile(filePath);\n\t\t\t\tresults.push(count(content, file));\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `wc: ${file}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn { stdout: results.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { ifFlag, parseArgs } from \"./command-helpers\";\nimport { assertPathAccess, resolvePath, stripUrlFilename } from \"./helpers\";\n\nexport const wgetCommand: ShellModule = {\n\tname: \"wget\",\n\tdescription: \"File downloader (pure fetch)\",\n\tcategory: \"network\",\n\tparams: [\"[options] <url>\"],\n\trun: async ({ authUser, cwd, args, shell }) => {\n\t\tconst { flagsWithValues, positionals } = parseArgs(args, {\n\t\t\tflagsWithValue: [\n\t\t\t\t\"-O\",\n\t\t\t\t\"--output-document\",\n\t\t\t\t\"-o\",\n\t\t\t\t\"--output-file\",\n\t\t\t\t\"-P\",\n\t\t\t\t\"--directory-prefix\",\n\t\t\t\t\"--tries\",\n\t\t\t\t\"--timeout\",\n\t\t\t],\n\t\t});\n\n\t\tif (ifFlag(args, [\"-h\", \"--help\"])) {\n\t\t\treturn {\n\t\t\t\tstdout: [\n\t\t\t\t\t\"Usage: wget [option]... [URL]...\",\n\t\t\t\t\t\" -O, --output-document=FILE Write to FILE ('-' for stdout)\",\n\t\t\t\t\t\" -P, --directory-prefix=DIR Save files in DIR\",\n\t\t\t\t\t\" -q, --quiet Quiet mode\",\n\t\t\t\t\t\" -v, --verbose Verbose output (default)\",\n\t\t\t\t\t\" -c, --continue Continue partial download\",\n\t\t\t\t\t\" --tries=N Retry N times\",\n\t\t\t\t\t\" --timeout=N Timeout in seconds\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tif (ifFlag(args, [\"-V\", \"--version\"])) {\n\t\t\treturn {\n\t\t\t\tstdout: \"GNU Wget 1.21.3 (virtual) built on Fortune GNU/Linux.\",\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst url = positionals[0];\n\t\tif (!url)\n\t\t\treturn {\n\t\t\t\tstderr: \"wget: missing URL\\nUsage: wget [OPTION]... [URL]...\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\n\t\tconst outputArg =\n\t\t\tflagsWithValues.get(\"-O\") ??\n\t\t\tflagsWithValues.get(\"--output-document\") ??\n\t\t\tnull;\n\t\tconst dirPrefix =\n\t\t\tflagsWithValues.get(\"-P\") ??\n\t\t\tflagsWithValues.get(\"--directory-prefix\") ??\n\t\t\tnull;\n\t\tconst quiet = ifFlag(args, [\"-q\", \"--quiet\"]);\n\n\t\t// Derive target filename\n\t\tconst filename =\n\t\t\toutputArg === \"-\" ? null : (outputArg ?? stripUrlFilename(url));\n\t\tconst targetPath = filename\n\t\t\t? resolvePath(cwd, dirPrefix ? `${dirPrefix}/${filename}` : filename)\n\t\t\t: null;\n\n\t\tif (targetPath) assertPathAccess(authUser, targetPath, \"wget\");\n\n\t\tconst stderrLines: string[] = [];\n\t\tif (!quiet) {\n\t\t\tstderrLines.push(`--${new Date().toISOString()}-- ${url}`);\n\t\t\tstderrLines.push(`Resolving ${new URL(url).host}...`);\n\t\t\tstderrLines.push(`Connecting to ${new URL(url).host}...`);\n\t\t}\n\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetch(url, {\n\t\t\t\theaders: { \"User-Agent\": \"Wget/1.21.3 (Fortune GNU/Linux)\" },\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\tstderrLines.push(`wget: unable to resolve host: ${msg}`);\n\t\t\treturn { stderr: stderrLines.join(\"\\n\"), exitCode: 4 };\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tstderrLines.push(`ERROR ${response.status}: ${response.statusText}`);\n\t\t\treturn { stderr: stderrLines.join(\"\\n\"), exitCode: 8 };\n\t\t}\n\n\t\tlet body: string;\n\t\ttry {\n\t\t\tbody = await response.text();\n\t\t} catch {\n\t\t\treturn { stderr: \"wget: failed to read response\", exitCode: 1 };\n\t\t}\n\n\t\tif (!quiet) {\n\t\t\tconst ct =\n\t\t\t\tresponse.headers.get(\"content-type\") ?? \"application/octet-stream\";\n\t\t\tstderrLines.push(\n\t\t\t\t`HTTP request sent, awaiting response... ${response.status} ${response.statusText}`,\n\t\t\t);\n\t\t\tstderrLines.push(`Length: ${body.length} [${ct}]`);\n\t\t}\n\n\t\t// Output to stdout (pipe) or file\n\t\tif (outputArg === \"-\") {\n\t\t\treturn {\n\t\t\t\tstdout: body,\n\t\t\t\tstderr: stderrLines.join(\"\\n\") || undefined,\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tif (targetPath) {\n\t\t\tshell.writeFileAsUser(authUser, targetPath, body);\n\t\t\tif (!quiet)\n\t\t\t\tstderrLines.push(\n\t\t\t\t\t`Saving to: '${targetPath}'\\n${targetPath} 100%[==================>] ${body.length} B`,\n\t\t\t\t);\n\t\t\treturn { stderr: stderrLines.join(\"\\n\") || undefined, exitCode: 0 };\n\t\t}\n\n\t\treturn { stdout: body, exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const whichCommand: ShellModule = {\n\tname: \"which\",\n\tdescription: \"Locate a command in PATH\",\n\tcategory: \"shell\",\n\tparams: [\"<command...>\"],\n\trun: ({ args, shell, env }) => {\n\t\tif (args.length === 0)\n\t\t\treturn { stderr: \"which: missing argument\", exitCode: 1 };\n\n\t\tconst pathDirs = (env?.vars?.PATH ?? \"/usr/local/bin:/usr/bin:/bin\").split(\n\t\t\t\":\",\n\t\t);\n\t\tconst lines: string[] = [];\n\t\tlet anyMissing = false;\n\n\t\tfor (const name of args) {\n\t\t\tlet found = false;\n\t\t\tfor (const dir of pathDirs) {\n\t\t\t\tconst full = `${dir}/${name}`;\n\t\t\t\tif (shell.vfs.exists(full)) {\n\t\t\t\t\tconst st = shell.vfs.stat(full);\n\t\t\t\t\tif (st.type === \"file\") {\n\t\t\t\t\t\tlines.push(full);\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) anyMissing = true;\n\t\t}\n\n\t\tif (lines.length === 0) return { exitCode: 1 };\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: anyMissing ? 1 : 0 };\n\t},\n};\n", "export function formatLoginDate(date: Date): string {\n\tconst weekday = date.toLocaleString(\"en-US\", { weekday: \"short\" });\n\tconst month = date.toLocaleString(\"en-US\", { month: \"short\" });\n\tconst day = date.getDate().toString().padStart(2, \"0\");\n\tconst hh = date.getHours().toString().padStart(2, \"0\");\n\tconst mm = date.getMinutes().toString().padStart(2, \"0\");\n\tconst ss = date.getSeconds().toString().padStart(2, \"0\");\n\tconst year = date.getFullYear();\n\treturn `${weekday} ${month} ${day} ${hh}:${mm}:${ss} ${year}`;\n}\n", "import { formatLoginDate } from \"../SSHMimic/loginFormat\";\nimport type { ShellModule } from \"../types/commands\";\n\nexport const whoCommand: ShellModule = {\n\tname: \"who\",\n\tdescription: \"Show active sessions\",\n\tcategory: \"system\",\n\tparams: [],\n\trun: ({ shell }) => {\n\t\tconst lines = shell.users.listActiveSessions().map((session) => {\n\t\t\tconst loginAt = new Date(session.startedAt);\n\t\t\tconst displayDate = Number.isNaN(loginAt.getTime())\n\t\t\t\t? session.startedAt\n\t\t\t\t: formatLoginDate(loginAt);\n\t\t\treturn `${session.username} ${session.tty} ${displayDate} (${session.remoteAddress || \"unknown\"})`;\n\t\t});\n\n\t\treturn { stdout: lines.join(\"\\n\"), exitCode: 0 };\n\t},\n};\n", "import type { ShellModule } from \"../types/commands\";\n\nexport const whoamiCommand: ShellModule = {\n\tname: \"whoami\",\n\tdescription: \"Print current user\",\n\tcategory: \"system\",\n\tparams: [],\n\trun: ({ authUser }) => ({ stdout: authUser, exitCode: 0 }),\n};\n", "import type { ShellModule } from \"../types/commands\";\nimport { runCommand } from \"./runtime\";\n\nexport const xargsCommand: ShellModule = {\n\tname: \"xargs\",\n\tdescription: \"Build and execute command lines from stdin\",\n\tcategory: \"text\",\n\tparams: [\"[command] [args...]\"],\n\trun: async ({ authUser, hostname, mode, cwd, args, stdin, shell, env }) => {\n\t\tconst baseCmd = args[0] ?? \"echo\";\n\t\tconst extraArgs = args.slice(1);\n\t\tconst items = (stdin ?? \"\").trim().split(/\\s+/).filter(Boolean);\n\t\tif (items.length === 0) return { exitCode: 0 };\n\t\tconst fullCmd = [baseCmd, ...extraArgs, ...items].join(\" \");\n\t\treturn runCommand(\n\t\t\tfullCmd,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tundefined,\n\t\t\tenv,\n\t\t);\n\t},\n};\n", "/** biome-ignore-all lint/style/useNamingConvention: ENV VARIABLES */\nimport type { CommandContext, CommandResult, ShellModule } from \"../types/commands\";\nimport { adduserCommand } from \"./adduser\";\nimport { aliasCommand, unaliasCommand } from \"./alias\";\nimport { aptCacheCommand, aptCommand } from \"./apt\";\nimport { awkCommand } from \"./awk\";\nimport { base64Command } from \"./base64\";\nimport { catCommand } from \"./cat\";\nimport { cdCommand } from \"./cd\";\nimport { chmodCommand } from \"./chmod\";\nimport { clearCommand } from \"./clear\";\nimport { cpCommand } from \"./cp\";\nimport { curlCommand } from \"./curl\";\nimport { cutCommand } from \"./cut\";\nimport { dateCommand } from \"./date\";\nimport { declareCommand } from \"./declare\";\nimport { deluserCommand } from \"./deluser\";\nimport { dfCommand } from \"./df\";\nimport { diffCommand } from \"./diff\";\nimport { dpkgCommand, dpkgQueryCommand } from \"./dpkg\";\nimport { duCommand } from \"./du\";\nimport { echoCommand } from \"./echo\";\nimport { envCommand } from \"./env\";\nimport { exitCommand } from \"./exit\";\nimport { exportCommand } from \"./export\";\nimport { findCommand } from \"./find\";\nimport { freeCommand } from \"./free\";\nimport { grepCommand } from \"./grep\";\nimport { groupsCommand } from \"./groups\";\nimport { gunzipCommand, gzipCommand } from \"./gzip\";\nimport { headCommand } from \"./head\";\nimport { createHelpCommand } from \"./help\";\nimport { historyCommand } from \"./history\";\nimport { hostnameCommand } from \"./hostname\";\nimport { htopCommand } from \"./htop\";\nimport { idCommand } from \"./id\";\nimport { killCommand } from \"./kill\";\nimport { lnCommand } from \"./ln\";\nimport { lsCommand } from \"./ls\";\nimport { lsbReleaseCommand } from \"./lsb-release\";\nimport { manCommand } from \"./man\";\nimport { mkdirCommand } from \"./mkdir\";\nimport { mvCommand } from \"./mv\";\nimport { nanoCommand } from \"./nano\";\nimport { neofetchCommand } from \"./neofetch\";\nimport { nodeCommand } from \"./node\";\nimport { npmCommand, npxCommand } from \"./npm\";\nimport { passwdCommand } from \"./passwd\";\nimport { pingCommand } from \"./ping\";\nimport { printfCommand } from \"./printf\";\nimport { psCommand } from \"./ps\";\nimport { pwdCommand } from \"./pwd\";\nimport { python3Command } from \"./python\";\nimport { readCommand } from \"./read\";\nimport { rmCommand } from \"./rm\";\nimport { sedCommand } from \"./sed\";\nimport { setCommand } from \"./set\";\nimport { shCommand } from \"./sh\";\nimport { returnCommand, shiftCommand, trapCommand } from \"./shift\";\nimport { sleepCommand } from \"./sleep\";\nimport { sortCommand } from \"./sort\";\nimport { sourceCommand } from \"./source\";\nimport { suCommand } from \"./su\";\nimport { sudoCommand } from \"./sudo\";\nimport { tailCommand } from \"./tail\";\nimport { tarCommand } from \"./tar\";\nimport { teeCommand } from \"./tee\";\nimport { testCommand } from \"./test\";\nimport { touchCommand } from \"./touch\";\nimport { trCommand } from \"./tr\";\nimport { treeCommand } from \"./tree\";\nimport { falseCommand, trueCommand } from \"./true\";\nimport { typeCommand } from \"./type\";\nimport { unameCommand } from \"./uname\";\nimport { uniqCommand } from \"./uniq\";\nimport { unsetCommand } from \"./unset\";\nimport { uptimeCommand } from \"./uptime\";\nimport { wcCommand } from \"./wc\";\nimport { wgetCommand } from \"./wget\";\nimport { whichCommand } from \"./which\";\nimport { whoCommand } from \"./who\";\nimport { whoamiCommand } from \"./whoami\";\nimport { xargsCommand } from \"./xargs\";\n\nconst BASE_COMMANDS: ShellModule[] = [\n\t// Navigation\n\tpwdCommand,\n\tcdCommand,\n\tlsCommand,\n\ttreeCommand,\n\t// Files\n\tcatCommand,\n\ttouchCommand,\n\trmCommand,\n\tmkdirCommand,\n\tcpCommand,\n\tmvCommand,\n\tlnCommand,\n\tchmodCommand,\n\tfindCommand,\n\t// Text processing\n\tgrepCommand,\n\tsedCommand,\n\tawkCommand,\n\tsortCommand,\n\tuniqCommand,\n\twcCommand,\n\theadCommand,\n\ttailCommand,\n\tcutCommand,\n\ttrCommand,\n\tteeCommand,\n\txargsCommand,\n\tdiffCommand,\n\t// Archives\n\ttarCommand,\n\tgzipCommand,\n\tgunzipCommand,\n\tbase64Command,\n\t// System info\n\twhoamiCommand,\n\twhoCommand,\n\thostnameCommand,\n\tidCommand,\n\tgroupsCommand,\n\tunameCommand,\n\tpsCommand,\n\tkillCommand,\n\tdfCommand,\n\tduCommand,\n\tdateCommand,\n\tsleepCommand,\n\tpingCommand,\n\t// Shell\n\techoCommand,\n\tenvCommand,\n\texportCommand,\n\tsetCommand,\n\tunsetCommand,\n\tshCommand,\n\tclearCommand,\n\texitCommand,\n\t// Editors\n\tnanoCommand,\n\thtopCommand,\n\t// Network\n\tcurlCommand,\n\twgetCommand,\n\t// Users\n\tadduserCommand,\n\tpasswdCommand,\n\tdeluserCommand,\n\tsudoCommand,\n\tsuCommand,\n\t// Misc\n\tneofetchCommand,\n\t// Package management\n\taptCommand,\n\taptCacheCommand,\n\tdpkgCommand,\n\tdpkgQueryCommand,\n\t// Shell (extended)\n\twhichCommand,\n\ttypeCommand,\n\tmanCommand,\n\taliasCommand,\n\tunaliasCommand,\n\ttestCommand,\n\tsourceCommand,\n\thistoryCommand,\n\tprintfCommand,\n\treadCommand,\n\tdeclareCommand,\n\tshiftCommand,\n\ttrapCommand,\n\treturnCommand,\n\ttrueCommand,\n\tfalseCommand,\n\tnpmCommand,\n\tnpxCommand,\n\tnodeCommand,\n\tpython3Command,\n\t// System (extended)\n\tuptimeCommand,\n\tfreeCommand,\n\tlsbReleaseCommand,\n];\n\nconst customCommands: ShellModule[] = [];\nconst commandRegistry = new Map<string, ShellModule>();\nlet cachedCommandNames: string[] | null = null;\n\nconst helpCommand = createHelpCommand(() =>\n\tgetCommandModules().map((cmd) => cmd.name),\n);\n\nfunction buildCache(): void {\n\tcommandRegistry.clear();\n\tfor (const mod of getCommandModules()) {\n\t\tcommandRegistry.set(mod.name, mod);\n\t\tfor (const alias of mod.aliases ?? []) commandRegistry.set(alias, mod);\n\t}\n\tcachedCommandNames = Array.from(commandRegistry.keys()).sort();\n}\n\nfunction getCommandModules(): ShellModule[] {\n\treturn [...BASE_COMMANDS, ...customCommands, helpCommand];\n}\n\nexport function registerCommand(module: ShellModule): void {\n\tconst normalized: ShellModule = {\n\t\t...module,\n\t\tname: module.name.trim().toLowerCase(),\n\t\taliases: module.aliases?.map((a) => a.trim().toLowerCase()),\n\t};\n\tconst names = [normalized.name, ...(normalized.aliases ?? [])];\n\tif (names.some((n) => n.length === 0 || /\\s/.test(n))) {\n\t\tthrow new Error(\"Command names must be non-empty and contain no spaces\");\n\t}\n\tcustomCommands.push(normalized);\n\tbuildCache();\n}\n\nexport function createCustomCommand(\n\tname: string,\n\tparams: string[],\n\trun: (ctx: CommandContext) => CommandResult | Promise<CommandResult>,\n): ShellModule {\n\treturn { name, params, run };\n}\n\nexport function getCommandNames(): string[] {\n\tif (!cachedCommandNames) buildCache();\n\treturn cachedCommandNames!;\n}\n\nexport function getCommandModulesPublic(): ShellModule[] {\n\treturn getCommandModules();\n}\n\nexport function resolveModule(name: string): ShellModule | undefined {\n\tif (!cachedCommandNames) buildCache();\n\treturn commandRegistry.get(name.toLowerCase());\n}\n", "import { runCommandDirect } from \"../commands\";\nimport { resolvePath } from \"../commands/helpers\";\nimport type { CommandMode, CommandResult, ShellEnv } from \"../types/commands\";\nimport type {\n\tPipeline,\n\tPipelineCommand,\n\tScript,\n\tStatement,\n} from \"../types/pipeline\";\nimport type { VirtualShell } from \"../VirtualShell\";\n\n// \u2500\u2500 Script executor (handles &&/||/;) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function executeScript(\n\tscript: Script,\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tif (!script.isValid)\n\t\treturn { stderr: script.error || \"Syntax error\", exitCode: 1 };\n\n\tlet lastResult: CommandResult = { exitCode: 0 };\n\n\tfor (const stmt of script.statements) {\n\t\t// Decide whether to run this statement based on previous op\n\t\tlastResult = await executePipeline(\n\t\t\tstmt.pipeline,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tenv,\n\t\t);\n\t\tenv.lastExitCode = lastResult.exitCode ?? 0;\n\n\t\t// Propagate session-control signals\n\t\tif (\n\t\t\tlastResult.closeSession ||\n\t\t\tlastResult.switchUser ||\n\t\t\tlastResult.nextCwd\n\t\t) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn lastResult;\n}\n\n/** Execute statements connected by &&/||/; */\nexport async function executeStatements(\n\tstatements: Statement[],\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tlet last: CommandResult = { exitCode: 0 };\n\tlet i = 0;\n\n\twhile (i < statements.length) {\n\t\tconst stmt = statements[i]!;\n\t\tlast = await executePipeline(\n\t\t\tstmt.pipeline,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tenv,\n\t\t);\n\t\tenv.lastExitCode = last.exitCode ?? 0;\n\n\t\tif (last.closeSession || last.switchUser) return last;\n\n\t\tconst op = stmt.op;\n\t\tif (!op || op === \";\") {\n\t\t\t// always run next\n\t\t} else if (op === \"&&\") {\n\t\t\tif ((last.exitCode ?? 0) !== 0) {\n\t\t\t\t// skip until next ; or end\n\t\t\t\twhile (i < statements.length && statements[i]?.op === \"&&\") i++;\n\t\t\t}\n\t\t} else if (op === \"||\") {\n\t\t\tif ((last.exitCode ?? 0) === 0) {\n\t\t\t\t// skip until next ; or end\n\t\t\t\twhile (i < statements.length && statements[i]?.op === \"||\") i++;\n\t\t\t}\n\t\t}\n\t\ti++;\n\t}\n\treturn last;\n}\n\n// \u2500\u2500 Pipeline executor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function executePipeline(\n\tpipeline: Pipeline,\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv?: ShellEnv,\n): Promise<CommandResult> {\n\tif (!pipeline.isValid)\n\t\treturn { stderr: pipeline.error || \"Syntax error\", exitCode: 1 };\n\tif (pipeline.commands.length === 0) return { exitCode: 0 };\n\n\tconst shellEnv: ShellEnv = env ?? { vars: {}, lastExitCode: 0 };\n\n\tif (pipeline.commands.length === 1) {\n\t\treturn executeSingleCommandWithRedirections(\n\t\t\tpipeline.commands[0] as PipelineCommand,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tshellEnv,\n\t\t);\n\t}\n\n\treturn executePipelineChain(\n\t\tpipeline.commands as PipelineCommand[],\n\t\tauthUser,\n\t\thostname,\n\t\tmode,\n\t\tcwd,\n\t\tshell,\n\t\tshellEnv,\n\t);\n}\n\nasync function executeSingleCommandWithRedirections(\n\tcmd: PipelineCommand,\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tlet stdin: string | undefined;\n\tif (cmd.inputFile) {\n\t\tconst inputPath = resolvePath(cwd, cmd.inputFile);\n\t\ttry {\n\t\t\tstdin = shell.vfs.readFile(inputPath);\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tstderr: `${cmd.inputFile}: No such file or directory`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t}\n\n\tconst result = await runCommandDirect(\n\t\tcmd.name,\n\t\tcmd.args,\n\t\tauthUser,\n\t\thostname,\n\t\tmode,\n\t\tcwd,\n\t\tshell,\n\t\tstdin,\n\t\tenv,\n\t);\n\n\tif (cmd.outputFile) {\n\t\tconst outputPath = resolvePath(cwd, cmd.outputFile);\n\t\tconst output = result.stdout || \"\";\n\t\ttry {\n\t\t\tif (cmd.appendOutput) {\n\t\t\t\tconst existing = (() => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn shell.vfs.readFile(outputPath);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t\tshell.writeFileAsUser(authUser, outputPath, existing + output);\n\t\t\t} else {\n\t\t\t\tshell.writeFileAsUser(authUser, outputPath, output);\n\t\t\t}\n\t\t\treturn { ...result, stdout: \"\" };\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\t...result,\n\t\t\t\tstderr: `Failed to write to ${cmd.outputFile}`,\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn result;\n}\n\nasync function executePipelineChain(\n\tcommands: PipelineCommand[],\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tlet currentOutput = \"\";\n\tlet exitCode = 0;\n\n\tfor (let i = 0; i < commands.length; i++) {\n\t\tconst cmd = commands[i] as PipelineCommand;\n\n\t\tif (i === 0 && cmd.inputFile) {\n\t\t\tconst inputPath = resolvePath(cwd, cmd.inputFile);\n\t\t\ttry {\n\t\t\t\tcurrentOutput = shell.vfs.readFile(inputPath);\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tstderr: `${cmd.inputFile}: No such file or directory`,\n\t\t\t\t\texitCode: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tconst result = await runCommandDirect(\n\t\t\tcmd.name,\n\t\t\tcmd.args,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tcurrentOutput,\n\t\t\tenv,\n\t\t);\n\t\texitCode = result.exitCode ?? 0;\n\n\t\tif (i === commands.length - 1 && cmd.outputFile) {\n\t\t\tconst outputPath = resolvePath(cwd, cmd.outputFile);\n\t\t\tconst output = result.stdout || \"\";\n\t\t\ttry {\n\t\t\t\tif (cmd.appendOutput) {\n\t\t\t\t\tconst existing = (() => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn shell.vfs.readFile(outputPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t\tshell.writeFileAsUser(authUser, outputPath, existing + output);\n\t\t\t\t} else {\n\t\t\t\t\tshell.writeFileAsUser(authUser, outputPath, output);\n\t\t\t\t}\n\t\t\t\tcurrentOutput = \"\";\n\t\t\t} catch {\n\t\t\t\treturn { stderr: `Failed to write to ${cmd.outputFile}`, exitCode: 1 };\n\t\t\t}\n\t\t} else {\n\t\t\tcurrentOutput = result.stdout || \"\";\n\t\t}\n\n\t\tif (result.stderr && exitCode !== 0)\n\t\t\treturn { stderr: result.stderr, exitCode };\n\t\tif (result.closeSession || result.switchUser) return result;\n\t}\n\n\treturn { stdout: currentOutput, exitCode };\n}\n", "import type {\n\tPipeline,\n\tPipelineCommand,\n\tScript,\n\tStatement,\n\tLogicalOp,\n} from \"../types/pipeline\";\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Parse a shell input line into a Script (sequence of statements connected\n * by && / || / ;). Each statement contains one Pipeline (commands connected\n * by |).\n */\nexport function parseScript(rawInput: string): Script {\n\tconst trimmed = rawInput.trim();\n\tif (!trimmed) return { statements: [], isValid: true };\n\n\ttry {\n\t\tconst statements = parseStatements(trimmed);\n\t\treturn { statements, isValid: true };\n\t} catch (e) {\n\t\treturn { statements: [], isValid: false, error: (e as Error).message };\n\t}\n}\n\n/** Legacy compat: parse a single pipeline (no &&/||/;) */\nexport function parseShellPipeline(rawInput: string): Pipeline {\n\tconst trimmed = rawInput.trim();\n\tif (!trimmed) return { commands: [], isValid: true };\n\ttry {\n\t\tconst commands = parsePipeline(trimmed);\n\t\treturn { commands, isValid: true };\n\t} catch (e) {\n\t\treturn { commands: [], isValid: false, error: (e as Error).message };\n\t}\n}\n\n// \u2500\u2500 Variable & tilde expansion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Expand ~ and $VAR / ${VAR} / ${VAR:-default} / $(cmd placeholder) in a\n * token, given the current env vars and home path.\n * Command substitution $(\u2026) is NOT executed here \u2014 it's left as a marker so\n * the executor can handle it.\n */\nexport function expandToken(\n\ttoken: string,\n\tenv: Record<string, string>,\n\tauthUser: string,\n\tlastExitCode = 0,\n): string {\n\t// tilde expansion\n\ttoken = token.replace(/^~(\\/|$)/, `/home/${authUser}$1`);\n\n\t// $? special var\n\ttoken = token.replace(/\\$\\?/g, String(lastExitCode));\n\t// $$ PID (mock)\n\ttoken = token.replace(/\\$\\$/g, \"1\");\n\t// $# argc (0 for interactive)\n\ttoken = token.replace(/\\$#/g, \"0\");\n\n\t// ${VAR:-default} and ${VAR:+value}\n\ttoken = token.replace(\n\t\t/\\$\\{([^}:]+):-([^}]*)\\}/g,\n\t\t(_, name, def) => env[name] ?? def,\n\t);\n\ttoken = token.replace(/\\$\\{([^}:]+):\\+([^}]*)\\}/g, (_, name, val) =>\n\t\tenv[name] ? val : \"\",\n\t);\n\n\t// ${VAR}\n\ttoken = token.replace(/\\$\\{([^}]+)\\}/g, (_, name) => env[name] ?? \"\");\n\n\t// $VAR (greedy: match longest valid identifier)\n\ttoken = token.replace(\n\t\t/\\$([A-Za-z_][A-Za-z0-9_]*)/g,\n\t\t(_, name) => env[name] ?? \"\",\n\t);\n\n\treturn token;\n}\n\n/**\n * Expand glob patterns (*, ?, [abc]) against a list of entries.\n * Returns the original pattern if no match.\n */\nexport function expandGlob(pattern: string, entries: string[]): string[] {\n\tif (!/[*?[]/.test(pattern)) return [pattern];\n\tconst regex = globToRegex(pattern);\n\tconst matches = entries.filter((e) => regex.test(e));\n\treturn matches.length > 0 ? matches.sort() : [pattern];\n}\n\nfunction globToRegex(pattern: string): RegExp {\n\tlet re = \"^\";\n\tfor (let i = 0; i < pattern.length; i++) {\n\t\tconst c = pattern[i]!;\n\t\tif (c === \"*\") re += \".*\";\n\t\telse if (c === \"?\") re += \".\";\n\t\telse if (c === \"[\") {\n\t\t\tconst close = pattern.indexOf(\"]\", i + 1);\n\t\t\tif (close === -1) re += \"\\\\[\";\n\t\t\telse {\n\t\t\t\tre += `[${pattern.slice(i + 1, close)}]`;\n\t\t\t\ti = close;\n\t\t\t}\n\t\t} else re += c.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\t}\n\treturn new RegExp(`${re}$`);\n}\n\n// \u2500\u2500 Internal parser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction parseStatements(input: string): Statement[] {\n\t// Split by ;, &&, || \u2014 respecting quotes and parens\n\tconst segments = splitByLogicalOps(input);\n\tconst statements: Statement[] = [];\n\n\tfor (const seg of segments) {\n\t\tconst commands = parsePipeline(seg.text.trim());\n\t\tconst stmt: Statement = { pipeline: { commands, isValid: true } };\n\t\tif (seg.op) stmt.op = seg.op;\n\t\tstatements.push(stmt);\n\t}\n\n\treturn statements;\n}\n\ninterface Segment {\n\ttext: string;\n\top?: LogicalOp;\n}\n\nfunction splitByLogicalOps(input: string): Segment[] {\n\tconst segments: Segment[] = [];\n\tlet current = \"\";\n\tlet depth = 0; // parens/subshell depth\n\tlet inQ = false;\n\tlet qChar = \"\";\n\tlet i = 0;\n\n\tconst flush = (op?: LogicalOp) => {\n\t\tif (current.trim()) segments.push({ text: current, op });\n\t\tcurrent = \"\";\n\t};\n\n\twhile (i < input.length) {\n\t\tconst ch = input[i]!;\n\t\tconst ch2 = input.slice(i, i + 2);\n\n\t\tif ((ch === '\"' || ch === \"'\") && !inQ) {\n\t\t\tinQ = true;\n\t\t\tqChar = ch;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ && ch === qChar) {\n\t\t\tinQ = false;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ) {\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ch === \"(\") {\n\t\t\tdepth++;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \")\") {\n\t\t\tdepth--;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (depth > 0) {\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ch2 === \"&&\") {\n\t\t\tflush(\"&&\");\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch2 === \"||\") {\n\t\t\tflush(\"||\");\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \";\") {\n\t\t\tflush(\";\");\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += ch;\n\t\ti++;\n\t}\n\tflush();\n\treturn segments;\n}\n\nfunction parsePipeline(input: string): PipelineCommand[] {\n\tconst pipeTokens = splitByPipe(input);\n\treturn pipeTokens.map(parseCommandWithRedirections);\n}\n\nfunction splitByPipe(input: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet inQ = false;\n\tlet qChar = \"\";\n\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst ch = input[i]!;\n\t\tif ((ch === '\"' || ch === \"'\") && !inQ) {\n\t\t\tinQ = true;\n\t\t\tqChar = ch;\n\t\t\tcurrent += ch;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ && ch === qChar) {\n\t\t\tinQ = false;\n\t\t\tcurrent += ch;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ) {\n\t\t\tcurrent += ch;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// || was already consumed at statement level, bare | is pipe\n\t\tif (ch === \"|\" && input[i + 1] !== \"|\") {\n\t\t\tif (!current.trim())\n\t\t\t\tthrow new Error(\"Syntax error near unexpected token '|'\");\n\t\t\ttokens.push(current.trim());\n\t\t\tcurrent = \"\";\n\t\t} else {\n\t\t\tcurrent += ch;\n\t\t}\n\t}\n\n\tconst tail = current.trim();\n\tif (!tail && tokens.length > 0)\n\t\tthrow new Error(\"Syntax error near unexpected token '|'\");\n\tif (tail) tokens.push(tail);\n\treturn tokens;\n}\n\nfunction parseCommandWithRedirections(token: string): PipelineCommand {\n\tconst parts = tokenizeCommand(token);\n\tif (parts.length === 0) return { name: \"\", args: [] };\n\n\tconst cmdParts: string[] = [];\n\tlet inputFile: string | undefined;\n\tlet outputFile: string | undefined;\n\tlet appendOutput = false;\n\tlet i = 0;\n\n\twhile (i < parts.length) {\n\t\tconst part = parts[i]!;\n\t\tif (part === \"<\") {\n\t\t\ti++;\n\t\t\tif (i >= parts.length)\n\t\t\t\tthrow new Error(\"Syntax error: expected filename after <\");\n\t\t\tinputFile = parts[i];\n\t\t\ti++;\n\t\t} else if (part === \">>\") {\n\t\t\ti++;\n\t\t\tif (i >= parts.length)\n\t\t\t\tthrow new Error(\"Syntax error: expected filename after >>\");\n\t\t\toutputFile = parts[i];\n\t\t\tappendOutput = true;\n\t\t\ti++;\n\t\t} else if (part === \">\") {\n\t\t\ti++;\n\t\t\tif (i >= parts.length)\n\t\t\t\tthrow new Error(\"Syntax error: expected filename after >\");\n\t\t\toutputFile = parts[i];\n\t\t\tappendOutput = false;\n\t\t\ti++;\n\t\t} else {\n\t\t\tcmdParts.push(part);\n\t\t\ti++;\n\t\t}\n\t}\n\n\tconst name = (cmdParts[0] ?? \"\").toLowerCase();\n\treturn { name, args: cmdParts.slice(1), inputFile, outputFile, appendOutput };\n}\n\nfunction tokenizeCommand(input: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet inQ = false;\n\tlet qChar = \"\";\n\tlet i = 0;\n\n\twhile (i < input.length) {\n\t\tconst ch = input[i]!;\n\t\tconst next = input[i + 1];\n\n\t\tif ((ch === '\"' || ch === \"'\") && !inQ) {\n\t\t\tinQ = true;\n\t\t\tqChar = ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ && ch === qChar) {\n\t\t\tinQ = false;\n\t\t\tqChar = \"\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ) {\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ch === \" \") {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((ch === \">\" || ch === \"<\") && !inQ) {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\tif (ch === \">\" && next === \">\") {\n\t\t\t\ttokens.push(\">>\");\n\t\t\t\ti += 2;\n\t\t\t} else {\n\t\t\t\ttokens.push(ch);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += ch;\n\t\ti++;\n\t}\n\tif (current) tokens.push(current);\n\treturn tokens;\n}\n", "/** biome-ignore-all lint/style/useNamingConvention: ENV VARIABLES */\nimport { executeStatements } from \"../SSHMimic/executor\";\nimport type { VirtualShell } from \"../VirtualShell\";\nimport { parseScript } from \"../VirtualShell/shellParser\";\nimport type {\n CommandMode,\n CommandResult,\n ShellEnv,\n} from \"../types/commands\";\nimport { expandAsync } from \"../utils/expand\";\nimport { resolveModule } from \"./registry\";\n\n// \u2500\u2500 Tokenize command input respecting quotes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction tokenizeCommand(input: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet inQ = false;\n\tlet qChar = \"\";\n\tlet i = 0;\n\n\twhile (i < input.length) {\n\t\tconst ch = input[i]!;\n\t\tconst next = input[i + 1];\n\n\t\tif ((ch === '\"' || ch === \"'\") && !inQ) {\n\t\t\tinQ = true;\n\t\t\tqChar = ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ && ch === qChar) {\n\t\t\tinQ = false;\n\t\t\tqChar = \"\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inQ) {\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ch === \" \") {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((ch === \">\" || ch === \"<\") && !inQ) {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\tif (ch === \">\" && next === \">\") {\n\t\t\t\ttokens.push(\">>\");\n\t\t\t\ti += 2;\n\t\t\t} else {\n\t\t\t\ttokens.push(ch);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += ch;\n\t\ti++;\n\t}\n\tif (current) tokens.push(current);\n\treturn tokens;\n}\n\nexport function makeDefaultEnv(authUser: string, hostname: string): ShellEnv {\n\treturn {\n\t\tvars: {\n\t\t\tPATH: \"/usr/local/bin:/usr/bin:/bin\",\n\t\t\tHOME: `/home/${authUser}`,\n\t\t\tUSER: authUser,\n\t\t\tLOGNAME: authUser,\n\t\t\tSHELL: \"/bin/sh\",\n\t\t\tTERM: \"xterm-256color\",\n\t\t\tHOSTNAME: hostname,\n\t\t\tPS1: \"\\\\u@\\\\h:\\\\w\\\\$ \",\n\t\t},\n\t\tlastExitCode: 0,\n\t};\n}\n\nfunction resolveVfsBinary(\n\tname: string,\n\tenv: ShellEnv,\n\tshell: VirtualShell,\n\tauthUser: string,\n): string | null {\n\tif (name.startsWith(\"/\")) {\n\t\tif (!shell.vfs.exists(name)) return null;\n\t\ttry {\n\t\t\tconst st = shell.vfs.stat(name);\n\t\t\tif (st.type !== \"file\") return null;\n\t\t\tif (!(st.mode & 0o111)) return null;\n\t\t\tif (\n\t\t\t\t(name.startsWith(\"/sbin/\") || name.startsWith(\"/usr/sbin/\")) &&\n\t\t\t\tauthUser !== \"root\"\n\t\t\t)\n\t\t\t\treturn null;\n\t\t\treturn name;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tconst pathDirs = (env.vars.PATH ?? \"/usr/local/bin:/usr/bin:/bin\").split(\":\");\n\tfor (const dir of pathDirs) {\n\t\tif ((dir === \"/sbin\" || dir === \"/usr/sbin\") && authUser !== \"root\")\n\t\t\tcontinue;\n\t\tconst full = `${dir}/${name}`;\n\t\tif (!shell.vfs.exists(full)) continue;\n\t\ttry {\n\t\t\tconst st = shell.vfs.stat(full);\n\t\t\tif (st.type !== \"file\") continue;\n\t\t\tif (!(st.mode & 0o111)) continue;\n\t\t\treturn full;\n\t\t} catch {}\n\t}\n\treturn null;\n}\n\nexport async function runCommandDirect(\n\tname: string,\n\targs: string[],\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tstdin: string | undefined,\n\tenv: ShellEnv,\n): Promise<CommandResult> {\n\tconst aliasVal = env.vars[`__alias_${name}`];\n\tif (aliasVal) {\n\t\treturn runCommand(\n\t\t\t`${aliasVal} ${args.join(\" \")}`,\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tmode,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tstdin,\n\t\t\tenv,\n\t\t);\n\t}\n\n\tconst mod = resolveModule(name);\n\tif (!mod) {\n\t\tconst vfsBinary = resolveVfsBinary(name, env, shell, authUser);\n\t\tif (vfsBinary) {\n\t\t\tconst stubContent = shell.vfs.readFile(vfsBinary);\n\t\t\tconst builtinMatch = stubContent.match(/exec\\s+builtin\\s+(\\S+)/);\n\t\t\tif (builtinMatch) {\n\t\t\t\tconst builtinMod = resolveModule(builtinMatch[1]!);\n\t\t\t\tif (builtinMod) {\n\t\t\t\t\treturn await builtinMod.run({\n\t\t\t\t\t\tauthUser,\n\t\t\t\t\t\thostname,\n\t\t\t\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\t\t\t\trawInput: [name, ...args].join(\" \"),\n\t\t\t\t\t\tmode,\n\t\t\t\t\t\targs,\n\t\t\t\t\t\tstdin,\n\t\t\t\t\t\tcwd,\n\t\t\t\t\t\tshell,\n\t\t\t\t\t\tenv,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst shMod = resolveModule(\"sh\");\n\t\t\tif (shMod) {\n\t\t\t\treturn await shMod.run({\n\t\t\t\t\tauthUser,\n\t\t\t\t\thostname,\n\t\t\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\t\t\trawInput: `sh -c ${JSON.stringify(stubContent)}`,\n\t\t\t\t\tmode,\n\t\t\t\t\targs: [\"-c\", stubContent, \"--\", ...args],\n\t\t\t\t\tstdin,\n\t\t\t\t\tcwd,\n\t\t\t\t\tshell,\n\t\t\t\t\tenv,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn { stderr: `${name}: command not found`, exitCode: 127 };\n\t}\n\n\ttry {\n\t\treturn await mod.run({\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\trawInput: [name, ...args].join(\" \"),\n\t\t\tmode,\n\t\t\targs,\n\t\t\tstdin,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tenv,\n\t\t});\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tstderr: error instanceof Error ? error.message : \"Command failed\",\n\t\t\texitCode: 1,\n\t\t};\n\t}\n}\n\nexport async function runCommand(\n\trawInput: string,\n\tauthUser: string,\n\thostname: string,\n\tmode: CommandMode,\n\tcwd: string,\n\tshell: VirtualShell,\n\tstdin?: string,\n\tenv?: ShellEnv,\n): Promise<CommandResult> {\n\tconst trimmed = rawInput.trim();\n\tif (trimmed.length === 0) return { exitCode: 0 };\n\n\tconst shellEnv: ShellEnv = env ?? makeDefaultEnv(authUser, hostname);\n\n\tconst rawTokens = tokenizeCommand(trimmed);\n\tconst rawFirstWord = rawTokens[0]?.toLowerCase() ?? \"\";\n\tconst aliasVal = shellEnv.vars[`__alias_${rawFirstWord}`];\n\tconst aliasExpanded = aliasVal\n\t\t? trimmed.replace(rawFirstWord, aliasVal)\n\t\t: trimmed;\n\n\tconst hasOperators =\n\t\t/(?<![|&])[|](?![|])/.test(aliasExpanded) ||\n\t\taliasExpanded.includes(\">\") ||\n\t\taliasExpanded.includes(\"<\") ||\n\t\taliasExpanded.includes(\"&&\") ||\n\t\taliasExpanded.includes(\"||\") ||\n\t\taliasExpanded.includes(\";\");\n\n\tif (hasOperators) {\n\t\tconst script = parseScript(aliasExpanded);\n\t\tif (!script.isValid)\n\t\t\treturn { stderr: script.error || \"Syntax error\", exitCode: 1 };\n\t\ttry {\n\t\t\treturn await executeStatements(\n\t\t\t\tscript.statements,\n\t\t\t\tauthUser,\n\t\t\t\thostname,\n\t\t\t\tmode,\n\t\t\t\tcwd,\n\t\t\t\tshell,\n\t\t\t\tshellEnv,\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\treturn {\n\t\t\t\tstderr: error instanceof Error ? error.message : \"Execution failed\",\n\t\t\t\texitCode: 1,\n\t\t\t};\n\t\t}\n\t}\n\n\tconst expanded = await expandAsync(\n\t\taliasExpanded,\n\t\tshellEnv.vars,\n\t\tshellEnv.lastExitCode,\n\t\t(sub) =>\n\t\t\trunCommand(\n\t\t\t\tsub,\n\t\t\t\tauthUser,\n\t\t\t\thostname,\n\t\t\t\tmode,\n\t\t\t\tcwd,\n\t\t\t\tshell,\n\t\t\t\tundefined,\n\t\t\t\tshellEnv,\n\t\t\t).then((r) => r.stdout ?? \"\"),\n\t);\n\n\tconst parts = tokenizeCommand(expanded.trim());\n\tconst commandName = parts[0]?.toLowerCase() ?? \"\";\n\tconst args = parts.slice(1);\n\tconst mod = resolveModule(commandName);\n\n\tif (!mod) {\n\t\tconst vfsBinary = resolveVfsBinary(commandName, shellEnv, shell, authUser);\n\t\tif (vfsBinary) {\n\t\t\tconst stubContent = shell.vfs.readFile(vfsBinary);\n\t\t\tconst builtinMatch = stubContent.match(/exec\\s+builtin\\s+(\\S+)/);\n\t\t\tif (builtinMatch) {\n\t\t\t\tconst builtinName = builtinMatch[1]!;\n\t\t\t\tconst builtinMod = resolveModule(builtinName);\n\t\t\t\tif (builtinMod) {\n\t\t\t\t\treturn await builtinMod.run({\n\t\t\t\t\t\tauthUser,\n\t\t\t\t\t\thostname,\n\t\t\t\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\t\t\t\trawInput: [commandName, ...args].join(\" \"),\n\t\t\t\t\t\tmode,\n\t\t\t\t\t\targs,\n\t\t\t\t\t\tstdin,\n\t\t\t\t\t\tcwd,\n\t\t\t\t\t\tshell,\n\t\t\t\t\t\tenv: shellEnv,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst shMod = resolveModule(\"sh\");\n\t\t\tif (shMod) {\n\t\t\t\treturn await shMod.run({\n\t\t\t\t\tauthUser,\n\t\t\t\t\thostname,\n\t\t\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\t\t\trawInput: `sh -c ${JSON.stringify(stubContent)}`,\n\t\t\t\t\tmode,\n\t\t\t\t\targs: [\"-c\", stubContent, \"--\", ...args],\n\t\t\t\t\tstdin,\n\t\t\t\t\tcwd,\n\t\t\t\t\tshell,\n\t\t\t\t\tenv: shellEnv,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn { stderr: `${commandName}: command not found`, exitCode: 127 };\n\t}\n\n\ttry {\n\t\treturn await mod.run({\n\t\t\tauthUser,\n\t\t\thostname,\n\t\t\tactiveSessions: shell.users.listActiveSessions(),\n\t\t\trawInput: expanded,\n\t\t\tmode,\n\t\t\targs,\n\t\t\tstdin,\n\t\t\tcwd,\n\t\t\tshell,\n\t\t\tenv: shellEnv,\n\t\t});\n\t} catch (error: unknown) {\n\t\treturn {\n\t\t\tstderr: error instanceof Error ? error.message : \"Command failed\",\n\t\t\texitCode: 1,\n\t\t};\n\t}\n}\n", "import type { ShellProperties } from \"../VirtualShell\";\nimport { formatLoginDate } from \"./loginFormat\";\n\nexport interface LoginBannerState {\n\tat: string;\n\tfrom: string;\n}\n\nexport function buildLoginBanner(\n\thostname: string,\n\tproperties: ShellProperties,\n\tlastLogin: LoginBannerState | null,\n): string {\n\tconst lines = [\n\t\t`Linux ${hostname} ${properties.kernel} ${properties.arch}`,\n\t\t\"\",\n\t\t\"The programs included with the Fortune GNU/Linux system are free software;\",\n\t\t\"the exact distribution terms for each program are described in the\",\n\t\t\"individual files in /usr/share/doc/*/copyright.\",\n\t\t\"\",\n\t\t\"Fortune GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent\",\n\t\t\"permitted by applicable law.\",\n\t];\n\n\tif (lastLogin) {\n\t\tconst when = new Date(lastLogin.at);\n\t\tconst displayed = Number.isNaN(when.getTime())\n\t\t\t? lastLogin.at\n\t\t\t: formatLoginDate(when);\n\t\tlines.push(`Last login: ${displayed} from ${lastLogin.from || \"unknown\"}`);\n\t}\n\n\tlines.push(\"\");\n\n\treturn `${lines.map((line) => `${line}\\r\\n`).join(\"\")}`;\n}", "export function buildPrompt(\n\tuser: string,\n\thost: string,\n\tcwdName: string,\n): string {\n\tconst isRoot = user === \"root\";\n\tconst colorUser = isRoot ? \"\\u001b[31;1m\" : \"\\u001b[35;1m\";\n\tconst colorWhite = \"\\u001b[37;1m\";\n\tconst colorBlue = \"\\u001b[34;1m\";\n\tconst colorReset = \"\\u001b[0m\";\n\tconst symbol = isRoot ? \"#\" : \"$\";\n\n\treturn `${colorWhite}[${colorUser}${user}${colorWhite}@${colorBlue}${host}${colorReset} ${cwdName}${colorWhite}]${colorReset}${symbol} `;\n}\n", "import { EventEmitter } from \"node:events\";\nimport { createCustomCommand, registerCommand } from \"../commands/registry\";\nimport { runCommand } from \"../commands/runtime\";\nimport {\n\tbootstrapLinuxRootfs,\n\trefreshProc,\n\tsyncEtcPasswd,\n} from \"../modules/linuxRootfs\";\nimport type { CommandContext, CommandResult } from \"../types/commands\";\nimport type { ShellStream } from \"../types/streams\";\nimport type { VfsNodeStats } from \"../types/vfs\";\nimport type { PerfLogger } from \"../utils/perfLogger\";\nimport { createPerfLogger } from \"../utils/perfLogger\";\nimport VirtualFileSystem, { type VfsOptions } from \"../VirtualFileSystem\";\nimport { VirtualPackageManager } from \"../VirtualPackageManager\";\nimport { VirtualUserManager } from \"../VirtualUserManager\";\nimport { startShell } from \"./shell\";\n\n/**\n * Virtual machine identity strings surfaced by system-info commands\n * (`uname`, `neofetch`, `lsb_release`, `/proc/version`, `/etc/os-release`).\n *\n * Pass this as the second argument to `new VirtualShell()` to customise the\n * distro name, kernel version, and CPU architecture reported inside the shell.\n *\n * @example\n * ```ts\n * const shell = new VirtualShell(\"my-vm\", {\n * kernel: \"6.1.0+custom-amd64\",\n * os: \"Acme GNU/Linux x64\",\n * arch: \"x86_64\",\n * });\n * ```\n */\nexport interface ShellProperties {\n\t/** Kernel version string (e.g. `\"1.0.0+itsrealfortune+1-amd64\"`). */\n\tkernel: string;\n\t/** Full OS description (e.g. `\"Fortune GNU/Linux x64\"`). */\n\tos: string;\n\t/** CPU architecture label (e.g. `\"x86_64\"`, `\"aarch64\"`). */\n\tarch: string;\n}\n\nexport interface VirtualShellVfsLike {\n\trestoreMirror(): Promise<void>;\n\tflushMirror(): Promise<void>;\n\twriteFile(targetPath: string, content: string | Uint8Array): void;\n\treadFile(targetPath: string): string;\n\tmkdir(targetPath: string, mode?: number): void;\n\texists(targetPath: string): boolean;\n\tstat(targetPath: string): VfsNodeStats;\n\tlist(targetPath: string): string[];\n\tremove(targetPath: string, options?: { recursive?: boolean }): void;\n\tchmod?(targetPath: string, mode: number): void;\n\tsymlink?(targetPath: string, linkPath: string): void;\n\tgetUsageBytes?(targetPath?: string): number;\n}\n\nexport interface VirtualShellVfsOptions {\n\tvfsInstance?: VirtualShellVfsLike;\n}\n\nfunction hasVfsInstance(obj: unknown): obj is { vfsInstance: VirtualShellVfsLike } {\n\treturn (\n\t\ttypeof obj === \"object\" &&\n\t\tobj !== null &&\n\t\t\"vfsInstance\" in obj &&\n\t\tisVirtualShellVfsLike((obj as Record<string, unknown>).vfsInstance)\n\t);\n}\n\nfunction isVirtualShellVfsLike(value: unknown): value is VirtualShellVfsLike {\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\n\tconst candidate = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof candidate.restoreMirror === \"function\" &&\n\t\ttypeof candidate.flushMirror === \"function\" &&\n\t\ttypeof candidate.writeFile === \"function\" &&\n\t\ttypeof candidate.readFile === \"function\" &&\n\t\ttypeof candidate.mkdir === \"function\" &&\n\t\ttypeof candidate.exists === \"function\" &&\n\t\ttypeof candidate.stat === \"function\" &&\n\t\ttypeof candidate.list === \"function\" &&\n\t\ttypeof candidate.remove === \"function\" &&\n\t\ttypeof candidate.copy === \"function\" &&\n\t\ttypeof candidate.move === \"function\" &&\n\t\ttypeof candidate.touch === \"function\"\n\t);\n}\n\nconst defaultShellProperties: ShellProperties = {\n\tkernel: \"1.0.0+itsrealfortune+1-amd64\",\n\tos: \"Fortune GNU/Linux x64\",\n\tarch: \"x86_64\",\n};\n\nconst perf: PerfLogger = createPerfLogger(\"VirtualShell\");\n\nfunction resolveAutoSudoForNewUsers(): boolean {\n\tconst configured = process.env.SSH_MIMIC_AUTO_SUDO_NEW_USERS;\n\tif (!configured) {\n\t\treturn true;\n\t}\n\n\treturn ![\"0\", \"false\", \"no\", \"off\"].includes(configured.toLowerCase());\n}\n\n/**\n * Coordinates the virtual filesystem, user manager, package manager, and\n * command runtime for a single isolated shell environment.\n *\n * Each instance owns its own VFS tree, user database, package registry, and\n * session state \u2014 multiple instances are fully independent.\n *\n * Instances are consumed both by the SSH/SFTP server facades and directly via\n * the programmatic `SshClient` API.\n *\n * @example\n * ```ts\n * const shell = new VirtualShell(\"my-vm\");\n * await shell.ensureInitialized();\n * const client = new SshClient(shell, \"root\");\n * const result = await client.exec(\"uname -a\");\n * ```\n *\n * @fires VirtualShell#initialized Emitted once the VFS and users are ready.\n * @fires VirtualShell#command Emitted after every command execution.\n * @fires VirtualShell#session:start Emitted when an interactive session opens.\n */\nclass VirtualShell extends EventEmitter {\n\t/** Backing virtual filesystem \u2014 use for direct path operations. */\n\tvfs: VirtualFileSystem;\n\t/** Virtual user database \u2014 use for auth, quotas, and session tracking. */\n\tusers: VirtualUserManager;\n\t/** APT/dpkg package manager backed by the built-in package registry. */\n\tpackageManager: VirtualPackageManager;\n\t/** Hostname shown in the shell prompt and SSH ident string. */\n\thostname: string;\n\t/** Distro identity strings surfaced by `uname`, `neofetch`, etc. */\n\tproperties: ShellProperties;\n\t/** Unix ms timestamp of shell creation \u2014 used by `uptime` and `/proc/uptime`. */\n\tstartTime: number;\n\tprivate initialized: Promise<void>;\n\n\t/**\n\t * Creates a new virtual shell instance.\n\t *\n\t * @param hostname Virtual hostname used for prompts and idents.\n\t * @param properties Customizable properties shown in `uname -a` and similar commands.\n\t * @param vfsOptions Optional VFS persistence options (mode, snapshotPath).\n\t */\n\tconstructor(\n\t\thostname: string,\n\t\tproperties?: ShellProperties,\n\t\tvfsOptionsOrInstance?: VfsOptions | VirtualShellVfsLike | VirtualShellVfsOptions,\n\t) {\n\t\tsuper();\n\t\tperf.mark(\"constructor\");\n\t\tthis.hostname = hostname;\n\t\tthis.properties = properties || defaultShellProperties;\n\t\tthis.startTime = Date.now();\n\n\t\tif (isVirtualShellVfsLike(vfsOptionsOrInstance)) {\n\t\t\tthis.vfs = vfsOptionsOrInstance as unknown as VirtualFileSystem;\n\t\t} else if (hasVfsInstance(vfsOptionsOrInstance)) {\n\t\t\tthis.vfs = vfsOptionsOrInstance.vfsInstance as unknown as VirtualFileSystem;\n\t\t} else {\n\t\t\tthis.vfs = new VirtualFileSystem((vfsOptionsOrInstance as VfsOptions) ?? {});\n\t\t}\n\t\tthis.users = new VirtualUserManager(this.vfs, resolveAutoSudoForNewUsers());\n\t\tthis.packageManager = new VirtualPackageManager(this.vfs, this.users);\n\n\t\t// Store references to avoid TypeScript \"used before assigned\" errors\n\t\tconst vfs = this.vfs;\n\t\tconst users = this.users;\n\t\tconst pm = this.packageManager;\n\t\tconst shellProps = this.properties;\n\t\tconst shellHostname = this.hostname;\n\t\tconst startTime = this.startTime;\n\n\t\t// Initialize both VFS mirror and users, ensuring all is ready before auth\n\t\tthis.initialized = (async () => {\n\t\t\tawait vfs.restoreMirror();\n\t\t\tawait users.initialize();\n\t\t\t// Bootstrap Linux rootfs (idempotent)\n\t\t\tbootstrapLinuxRootfs(vfs, users, shellHostname, shellProps, startTime);\n\t\t\t// Load installed packages from dpkg status\n\t\t\tpm.load();\n\t\t\tthis.emit(\"initialized\");\n\t\t})();\n\t}\n\n\t/**\n\t * Ensures initialization is complete before allowing operations.\n\t * Call this before any authentication or command execution.\n\t */\n\tpublic async ensureInitialized(): Promise<void> {\n\t\tperf.mark(\"ensureInitialized\");\n\t\tawait this.initialized;\n\t}\n\n\t/**\n\t * Registers a new command in the shell runtime.\n\t *\n\t * @param name Case-insensitive command name (no spaces).\n\t * @param params List of parameter names for help text (no validation).\n\t * @param callback Function invoked with command context on execution.\n\t */\n\taddCommand(\n\t\tname: string,\n\t\tparams: string[],\n\t\tcallback: (ctx: CommandContext) => CommandResult | Promise<CommandResult>,\n\t): void {\n\t\tconst normalized = name.trim().toLowerCase();\n\t\tif (normalized.length === 0 || /\\s/.test(normalized)) {\n\t\t\tthrow new Error(\"Command name must be non-empty and contain no spaces\");\n\t\t}\n\n\t\tregisterCommand(createCustomCommand(normalized, params, callback));\n\t}\n\n\t/**\n\t * Executes a raw command line string programmatically.\n\t *\n\t * Supports the full shell operator set (`&&`, `||`, `;`, `|`, `>`, `<`,\n\t * `$(cmd)`) and alias expansion. The result is emitted via the\n\t * `\"command\"` event but not returned \u2014 use `SshClient.exec()` for a\n\t * result-returning wrapper.\n\t *\n\t * @param rawInput Unparsed command line (e.g. `\"ls -la /tmp\"`).\n\t * @param authUser Username to run the command as.\n\t * @param cwd Current working directory for path resolution.\n\t */\n\texecuteCommand(rawInput: string, authUser: string, cwd: string): void {\n\t\tperf.mark(\"executeCommand\");\n\t\trunCommand(rawInput, authUser, this.hostname, \"shell\", cwd, this);\n\t\tthis.emit(\"command\", { command: rawInput, user: authUser, cwd });\n\t}\n\n\t/**\n\t * Attaches an interactive PTY session to this shell instance.\n\t *\n\t * Called internally by `SshMimic` when a client opens a shell channel.\n\t * The session reads from `stream` (user keystrokes) and writes back ANSI\n\t * output. History, `.bashrc` sourcing, and Ctrl+W/Ctrl+U line editing are\n\t * handled automatically.\n\t *\n\t * @param stream Bidirectional SSH channel stream.\n\t * @param authUser Authenticated username bound to this session.\n\t * @param sessionId Stable session UUID (used for `who` output), or `null`.\n\t * @param remoteAddress IP or hostname of the connecting client.\n\t * @param terminalSize Initial terminal dimensions in columns and rows.\n\t */\n\tstartInteractiveSession(\n\t\tstream: ShellStream,\n\t\tauthUser: string,\n\t\tsessionId: string | null,\n\t\tremoteAddress: string,\n\t\tterminalSize: { cols: number; rows: number },\n\t): void {\n\t\tperf.mark(\"startInteractiveSession\");\n\t\t// Interactive shell logic\n\t\tthis.emit(\"session:start\", { user: authUser, sessionId, remoteAddress });\n\t\tstartShell(\n\t\t\tthis.properties,\n\t\t\tstream,\n\t\t\tauthUser,\n\t\t\tthis.hostname,\n\t\t\tsessionId,\n\t\t\tremoteAddress,\n\t\t\tterminalSize,\n\t\t\tthis,\n\t\t);\n\t\t// Refresh /proc/<pid> and /proc/self after session is registered\n\t\tthis.refreshProcSessions();\n\t}\n\n\t/**\n\t * Refreshes the `/proc` virtual filesystem with current system state.\n\t *\n\t * Updates `/proc/uptime`, `/proc/meminfo`, `/proc/cpuinfo`,\n\t * `/proc/version`, `/proc/loadavg`, `/proc/self`, and per-session\n\t * `/proc/<pid>` entries from live session and host data.\n\t *\n\t * Called automatically during `bootstrapLinuxRootfs`. Call again before\n\t * reading `/proc` files for up-to-date values.\n\t */\n\tpublic refreshProcFs(): void {\n\t\trefreshProc(\n\t\t\tthis.vfs,\n\t\t\tthis.properties,\n\t\t\tthis.hostname,\n\t\t\tthis.startTime,\n\t\t\tthis.users.listActiveSessions(),\n\t\t);\n\t}\n\n\t/**\n\t * Updates only the session-dependent `/proc` entries (`/proc/<pid>`,\n\t * `/proc/self`). Cheaper than a full `refreshProcFs()` \u2014 call this\n\t * whenever a session is registered or unregistered.\n\t */\n\tpublic refreshProcSessions(): void {\n\t\trefreshProc(\n\t\t\tthis.vfs,\n\t\t\tthis.properties,\n\t\t\tthis.hostname,\n\t\t\tthis.startTime,\n\t\t\tthis.users.listActiveSessions(),\n\t\t);\n\t}\n\n\t/**\n\t * Syncs `/etc/passwd`, `/etc/group`, and `/etc/shadow` from the current\n\t * `VirtualUserManager` state.\n\t *\n\t * Called automatically during `bootstrapLinuxRootfs`. Call again after\n\t * `users.addUser()`, `users.deleteUser()`, or `users.addSudoer()` to keep\n\t * the classic Unix credential files in sync with the user manager.\n\t */\n\tpublic syncPasswd(): void {\n\t\tsyncEtcPasswd(this.vfs, this.users);\n\t}\n\n\t/**\n\t * Returns virtual filesystem instance after server started.\n\t *\n\t * @returns VirtualFileSystem or null when not started.\n\t */\n\tpublic getVfs(): VirtualFileSystem | null {\n\t\treturn this?.vfs ?? null;\n\t}\n\n\t/**\n\t * Returns user manager instance after server started.\n\t *\n\t * @returns VirtualUserManager or null when not started.\n\t */\n\tpublic getUsers(): VirtualUserManager | null {\n\t\treturn this?.users ?? null;\n\t}\n\n\t/**\n\t * Returns hostname shown in prompts and idents.\n\t *\n\t * @returns Configured hostname label.\n\t */\n\tpublic getHostname(): string {\n\t\treturn this?.hostname;\n\t}\n\n\t/**\n\t * Writes a file on behalf of a user with quota enforcement.\n\t *\n\t * @param authUser User performing the write.\n\t * @param targetPath Destination path.\n\t * @param content File content.\n\t */\n\tpublic writeFileAsUser(\n\t\tauthUser: string,\n\t\ttargetPath: string,\n\t\tcontent: string | Buffer,\n\t): void {\n\t\tperf.mark(\"writeFileAsUser\");\n\t\tthis.users.assertWriteWithinQuota(authUser, targetPath, content);\n\t\tthis.vfs.writeFile(targetPath, content);\n\t}\n}\n\nexport { VirtualShell };\n", "/** biome-ignore-all lint/style/useNamingConvention: ENV VAR KEYS */\n/**\n * linuxRootfs.ts\n *\n * Bootstraps a realistic Linux directory hierarchy in the VFS.\n * Called once during VirtualShell initialization. Idempotent \u2014 skips\n * paths that already exist so FS-mode snapshots survive restarts.\n */\n\nimport * as os from \"node:os\";\nimport type { ShellProperties } from \"../VirtualShell\";\nimport type VirtualFileSystem from \"../VirtualFileSystem\";\nimport type { VirtualUserManager } from \"../VirtualUserManager\";\n\n// \u2500\u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction ensureDir(vfs: VirtualFileSystem, path: string, mode = 0o755): void {\n\tif (!vfs.exists(path)) vfs.mkdir(path, mode);\n}\n\nfunction ensureFile(\n\tvfs: VirtualFileSystem,\n\tpath: string,\n\tcontent: string,\n\tmode = 0o644,\n): void {\n\tif (!vfs.exists(path)) vfs.writeFile(path, content, { mode });\n}\n\n// \u2500\u2500\u2500 /etc \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapEtc(\n\tvfs: VirtualFileSystem,\n\thostname: string,\n\tprops: ShellProperties,\n): void {\n\tensureDir(vfs, \"/etc\");\n\n\t// os-release \u2014 authoritative distro identity used by neofetch, lsb_release\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/os-release\",\n\t\t`${[\n\t\t\t`NAME=\"Fortune GNU/Linux\"`,\n\t\t\t`PRETTY_NAME=\"${props.os}\"`,\n\t\t\t`ID=fortune`,\n\t\t\t`ID_LIKE=debian`,\n\t\t\t`HOME_URL=\"https://github.com/itsrealfortune/typescript-virtual-container\"`,\n\t\t\t`VERSION_CODENAME=aurora`,\n\t\t\t`VERSION_ID=\"1.0\"`,\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tensureFile(vfs, \"/etc/debian_version\", \"12.0\\n\");\n\tensureFile(vfs, \"/etc/hostname\", `${hostname}\\n`);\n\tensureFile(vfs, \"/etc/shells\", \"/bin/sh\\n/bin/bash\\n/usr/bin/bash\\n\");\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/profile\",\n\t\t`${[\n\t\t\t\"export PATH=/usr/local/bin:/usr/bin:/bin\",\n\t\t\t\"export PS1='\\\\u@\\\\h:\\\\w\\\\$ '\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tensureFile(vfs, \"/etc/issue\", `Fortune GNU/Linux 1.0 \\\\n \\\\l\\n`);\n\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/motd\",\n\t\t[\"\", `Welcome to ${props.os}`, `Kernel: ${props.kernel}`, \"\"].join(\"\\n\"),\n\t);\n\n\t// APT sources\n\tensureDir(vfs, \"/etc/apt\");\n\tensureDir(vfs, \"/etc/apt/sources.list.d\");\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/apt/sources.list\",\n\t\t`${[\n\t\t\t\"# Fortune GNU/Linux package sources\",\n\t\t\t\"deb [virtual] fortune://packages.fortune.local aurora main contrib\",\n\t\t\t\"deb [virtual] fortune://security.fortune.local aurora-security main\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\t// network stubs\n\tensureDir(vfs, \"/etc/network\");\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/network/interfaces\",\n\t\t`${[\n\t\t\t\"auto lo\",\n\t\t\t\"iface lo inet loopback\",\n\t\t\t\"\",\n\t\t\t\"auto eth0\",\n\t\t\t\"iface eth0 inet dhcp\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/resolv.conf\",\n\t\t\"nameserver 1.1.1.1\\nnameserver 8.8.8.8\\n\",\n\t);\n\n\tensureFile(\n\t\tvfs,\n\t\t\"/etc/hosts\",\n\t\t`${[\n\t\t\t\"127.0.0.1 localhost\",\n\t\t\t`127.0.1.1 ${hostname}`,\n\t\t\t\"::1 localhost ip6-localhost ip6-loopback\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tensureDir(vfs, \"/etc/cron.d\");\n\tensureDir(vfs, \"/etc/init.d\");\n\tensureDir(vfs, \"/etc/systemd\");\n\tensureDir(vfs, \"/etc/systemd/system\");\n}\n\n// \u2500\u2500\u2500 /etc/passwd + /etc/group + /etc/shadow \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Sync `/etc/passwd`, `/etc/group`, and `/etc/shadow` from the\n * VirtualUserManager's current user list into the VFS.\n * @param vfs VirtualFileSystem instance to write files into\n * @param users VirtualUserManager to source users from\n */\nexport function syncEtcPasswd(\n\tvfs: VirtualFileSystem,\n\tusers: VirtualUserManager,\n): void {\n\tconst userList = users.listUsers();\n\n\tconst passwdLines = [\n\t\t\"root:x:0:0:root:/root:/bin/bash\",\n\t\t\"daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\",\n\t\t\"www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\",\n\t\t\"nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin\",\n\t];\n\n\tlet uid = 1000;\n\tfor (const u of userList) {\n\t\tif (u === \"root\") continue;\n\t\tpasswdLines.push(`${u}:x:${uid}:${uid}::/home/${u}:/bin/bash`);\n\t\tuid++;\n\t}\n\n\tvfs.writeFile(\"/etc/passwd\", `${passwdLines.join(\"\\n\")}\\n`);\n\n\tconst groupLines = [\n\t\t\"root:x:0:\",\n\t\t\"daemon:x:1:\",\n\t\t`sudo:x:27:${userList.filter((u) => users.isSudoer(u)).join(\",\")}`,\n\t\t`users:x:100:${userList.filter((u) => u !== \"root\").join(\",\")}`,\n\t\t\"nogroup:x:65534:\",\n\t];\n\tvfs.writeFile(\"/etc/group\", `${groupLines.join(\"\\n\")}\\n`);\n\n\t// shadow \u2014 fake hashes, never real\n\tconst shadowLines = [\n\t\t\"root:*:19000:0:99999:7:::\",\n\t\t\"daemon:*:19000:0:99999:7:::\",\n\t];\n\tfor (const u of userList) {\n\t\tif (u === \"root\") continue;\n\t\tshadowLines.push(`${u}:!:19000:0:99999:7:::`);\n\t}\n\tvfs.writeFile(\"/etc/shadow\", `${shadowLines.join(\"\\n\")}\\n`, { mode: 0o640 });\n}\n\n// \u2500\u2500\u2500 /proc \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Derive a stable virtual PID from a tty string like \"pts/0\" \u2192 1000, \"pts/1\" \u2192 1001 */\nfunction ttyToPid(tty: string): number {\n\tconst match = tty.match(/(\\d+)$/);\n\treturn 1000 + (match?.[1] ? parseInt(match[1], 10) : 0);\n}\n\n/** Write /proc/<pid>/ subtree for a single virtual process */\nfunction writeProcPid(\n\tvfs: VirtualFileSystem,\n\tpid: number,\n\tusername: string,\n\t_tty: string,\n\tcmdline: string,\n\tstartedAt: string,\n\tenv: Record<string, string>,\n): void {\n\tconst dir = `/proc/${pid}`;\n\tensureDir(vfs, dir);\n\tensureDir(vfs, `${dir}/fd`);\n\tensureDir(vfs, `${dir}/fdinfo`);\n\n\tconst uptimeSec = Math.floor(\n\t\t(Date.now() - new Date(startedAt).getTime()) / 1000,\n\t);\n\n\tvfs.writeFile(`${dir}/cmdline`, `${cmdline.replace(/\\s+/g, \"\\0\")}\\0`);\n\tvfs.writeFile(`${dir}/comm`, cmdline.split(/\\s+/)[0] ?? \"bash\");\n\tvfs.writeFile(\n\t\t`${dir}/status`,\n\t\t`${[\n\t\t\t`Name: ${cmdline.split(/\\s+/)[0] ?? \"bash\"}`,\n\t\t\t`State: S (sleeping)`,\n\t\t\t`Pid: ${pid}`,\n\t\t\t`PPid: 1`,\n\t\t\t`Uid: 0\\t0\\t0\\t0`,\n\t\t\t`Gid: 0\\t0\\t0\\t0`,\n\t\t\t`VmRSS: 4096 kB`,\n\t\t\t`VmSize: 16384 kB`,\n\t\t\t`Threads: 1`,\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\tvfs.writeFile(\n\t\t`${dir}/stat`,\n\t\t`${pid} (${cmdline.split(/\\s+/)[0] ?? \"bash\"}) S 1 ${pid} ${pid} 0 -1 4194304 0 0 0 0 ${uptimeSec} 0 0 0 20 0 1 0 0 16384 4096 0\\n`,\n\t);\n\tvfs.writeFile(\n\t\t`${dir}/environ`,\n\t\t`${Object.entries(env)\n\t\t\t.map(([k, v]) => `${k}=${v}`)\n\t\t\t.join(\"\\0\")}\\0`,\n\t);\n\tvfs.writeFile(`${dir}/cwd`, `/home/${username}\\0`);\n\tvfs.writeFile(`${dir}/exe`, \"/bin/bash\\0\");\n\n\t// Standard fd entries\n\tvfs.writeFile(`${dir}/fd/0`, \"\");\n\tvfs.writeFile(`${dir}/fd/1`, \"\");\n\tvfs.writeFile(`${dir}/fd/2`, \"\");\n}\n\n/**\n * Populate and refresh `/proc` virtual entries based on host stats and\n * provided active sessions. Rewrites `/proc/uptime`, `/proc/meminfo`,\n * `/proc/cpuinfo`, `/proc/<pid>` entries and `/proc/self` content.\n * @param vfs VirtualFileSystem instance\n * @param props ShellProperties used for version strings\n * @param hostname Hostname to write into /proc/hostname\n * @param shellStartTime Start time used to compute uptime\n * @param sessions Optional active sessions list to populate per-pid entries\n */\nexport function refreshProc(\n\tvfs: VirtualFileSystem,\n\tprops: ShellProperties,\n\thostname: string,\n\tshellStartTime: number,\n\tsessions?: import(\"../VirtualUserManager\").VirtualActiveSession[],\n): void {\n\tensureDir(vfs, \"/proc\");\n\n\tconst uptimeSec = Math.floor((Date.now() - shellStartTime) / 1000);\n\tvfs.writeFile(\n\t\t\"/proc/uptime\",\n\t\t`${uptimeSec}.00 ${Math.floor(uptimeSec * 0.9)}.00\\n`,\n\t);\n\n\tconst totalMemKb = Math.floor(os.totalmem() / 1024);\n\tconst freeMemKb = Math.floor(os.freemem() / 1024);\n\tconst availMemKb = Math.floor(freeMemKb * 0.95);\n\tvfs.writeFile(\n\t\t\"/proc/meminfo\",\n\t\t`${[\n\t\t\t`MemTotal: ${String(totalMemKb).padStart(10)} kB`,\n\t\t\t`MemFree: ${String(freeMemKb).padStart(10)} kB`,\n\t\t\t`MemAvailable: ${String(availMemKb).padStart(10)} kB`,\n\t\t\t`Buffers: ${String(Math.floor(totalMemKb * 0.02)).padStart(10)} kB`,\n\t\t\t`Cached: ${String(Math.floor(totalMemKb * 0.15)).padStart(10)} kB`,\n\t\t\t`SwapTotal: ${String(Math.floor(totalMemKb * 0.5)).padStart(10)} kB`,\n\t\t\t`SwapFree: ${String(Math.floor(totalMemKb * 0.5)).padStart(10)} kB`,\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\tconst cpus = os.cpus();\n\tconst cpuLines: string[] = [];\n\tfor (let i = 0; i < cpus.length; i++) {\n\t\tconst c = cpus[i];\n\t\tif (!c) continue;\n\t\tconst mhz = c.speed.toFixed(3);\n\t\tcpuLines.push(\n\t\t\t`processor\\t: ${i}`,\n\t\t\t`model name\\t: ${c.model}`,\n\t\t\t`cpu MHz\\t\\t: ${mhz}`,\n\t\t\t`cache size\\t: 8192 KB`,\n\t\t\t\"\",\n\t\t);\n\t}\n\tvfs.writeFile(\"/proc/cpuinfo\", `${cpuLines.join(\"\\n\")}\\n`);\n\n\tvfs.writeFile(\n\t\t\"/proc/version\",\n\t\t`Linux version ${props.kernel} (fortune@build) (gcc version 12.2.0) #1 SMP\\n`,\n\t);\n\n\tvfs.writeFile(\"/proc/hostname\", `${hostname}\\n`);\n\n\t// /proc/loadavg\n\tconst load = (Math.random() * 0.5).toFixed(2);\n\tconst numProcs = 1 + (sessions?.length ?? 0);\n\tvfs.writeFile(\n\t\t\"/proc/loadavg\",\n\t\t`${load} ${load} ${load} ${numProcs}/${numProcs} 1\\n`,\n\t);\n\n\t// /proc/net stubs\n\tensureDir(vfs, \"/proc/net\");\n\tensureFile(\n\t\tvfs,\n\t\t\"/proc/net/dev\",\n\t\t`${[\n\t\t\t\"Inter-| Receive | Transmit\",\n\t\t\t\" face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\",\n\t\t\t\" lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\",\n\t\t\t\" eth0: 131072 1024 0 0 0 0 0 0 65536 512 0 0 0 0 0 0\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\n\t// \u2500\u2500 /proc/1 \u2014 init process \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\twriteProcPid(\n\t\tvfs,\n\t\t1,\n\t\t\"root\",\n\t\t\"pts/0\",\n\t\t\"/sbin/init\",\n\t\tnew Date(shellStartTime).toISOString(),\n\t\t{},\n\t);\n\n\t// \u2500\u2500 /proc/<pid> per session \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\tconst activeSessions = sessions ?? [];\n\tfor (const session of activeSessions) {\n\t\tconst pid = ttyToPid(session.tty);\n\t\twriteProcPid(\n\t\t\tvfs,\n\t\t\tpid,\n\t\t\tsession.username,\n\t\t\tsession.tty,\n\t\t\t\"bash\",\n\t\t\tsession.startedAt,\n\t\t\t{\n\t\t\t\tUSER: session.username,\n\t\t\t\tHOME: `/home/${session.username}`,\n\t\t\t\tTERM: \"xterm-256color\",\n\t\t\t\tSHELL: \"/bin/bash\",\n\t\t\t},\n\t\t);\n\t}\n\n\t// \u2500\u2500 /proc/self \u2014 symlink to current session PID or 1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\t// We can't know which session is \"current\" at populate time,\n\t// so /proc/self is a directory that mirrors the most recent session,\n\t// or init if no sessions. Commands that read /proc/self get consistent data.\n\tconst selfPid =\n\t\tactiveSessions.length > 0\n\t\t\t? ttyToPid(activeSessions[activeSessions.length - 1]!.tty)\n\t\t\t: 1;\n\n\t// Remove existing /proc/self and recreate as content copy\n\tif (vfs.exists(\"/proc/self\")) {\n\t\ttry {\n\t\t\tvfs.remove(\"/proc/self\");\n\t\t} catch {}\n\t}\n\t// /proc/self is a real directory (not a symlink, which VFS may not support for dirs)\n\tconst selfSrc = `/proc/${selfPid}`;\n\tif (vfs.exists(selfSrc)) {\n\t\tensureDir(vfs, \"/proc/self\");\n\t\tensureDir(vfs, \"/proc/self/fd\");\n\t\tfor (const entry of vfs.list(selfSrc)) {\n\t\t\tconst srcPath = `${selfSrc}/${entry}`;\n\t\t\tconst dstPath = `/proc/self/${entry}`;\n\t\t\ttry {\n\t\t\t\tconst st = vfs.stat(srcPath);\n\t\t\t\tif (st.type === \"file\") {\n\t\t\t\t\tvfs.writeFile(dstPath, vfs.readFile(srcPath));\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t\tvfs.writeFile(\n\t\t\t\"/proc/self/status\",\n\t\t\tvfs.exists(`${selfSrc}/status`) ? vfs.readFile(`${selfSrc}/status`) : \"\",\n\t\t);\n\t} else {\n\t\t// Fallback minimal /proc/self\n\t\tensureDir(vfs, \"/proc/self\");\n\t\tvfs.writeFile(\"/proc/self/cmdline\", \"bash\\0\");\n\t\tvfs.writeFile(\"/proc/self/comm\", \"bash\");\n\t\tvfs.writeFile(\n\t\t\t\"/proc/self/status\",\n\t\t\t\"Name:\\tbash\\nState:\\tS (sleeping)\\nPid:\\t1\\nPPid:\\t0\\n\",\n\t\t);\n\t\tvfs.writeFile(\"/proc/self/environ\", \"\");\n\t\tvfs.writeFile(\"/proc/self/cwd\", \"/root\\0\");\n\t\tvfs.writeFile(\"/proc/self/exe\", \"/bin/bash\\0\");\n\t}\n}\n\n// \u2500\u2500\u2500 /sys \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapSys(vfs: VirtualFileSystem, props: ShellProperties): void {\n\tensureDir(vfs, \"/sys\");\n\tensureDir(vfs, \"/sys/devices\");\n\tensureDir(vfs, \"/sys/devices/virtual\");\n\tensureDir(vfs, \"/sys/devices/virtual/dmi\");\n\tensureDir(vfs, \"/sys/devices/virtual/dmi/id\");\n\n\tensureFile(\n\t\tvfs,\n\t\t\"/sys/devices/virtual/dmi/id/sys_vendor\",\n\t\t\"Fortune Systems\\n\",\n\t);\n\tensureFile(\n\t\tvfs,\n\t\t\"/sys/devices/virtual/dmi/id/product_name\",\n\t\t\"VirtualContainer v1\\n\",\n\t);\n\tensureFile(vfs, \"/sys/devices/virtual/dmi/id/board_name\", \"fortune-board\\n\");\n\n\tensureDir(vfs, \"/sys/class\");\n\tensureDir(vfs, \"/sys/class/net\");\n\n\tensureDir(vfs, \"/sys/kernel\");\n\tensureFile(vfs, \"/sys/kernel/hostname\", \"fortune-vm\\n\");\n\tensureFile(vfs, \"/sys/kernel/osrelease\", `${props.kernel}\\n`);\n\tensureFile(vfs, \"/sys/kernel/ostype\", \"Linux\\n\");\n}\n\n// \u2500\u2500\u2500 /dev \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapDev(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/dev\");\n\tensureFile(vfs, \"/dev/null\", \"\", 0o666);\n\tensureFile(vfs, \"/dev/zero\", \"\", 0o666);\n\tensureFile(vfs, \"/dev/random\", \"\", 0o444);\n\tensureFile(vfs, \"/dev/urandom\", \"\", 0o444);\n\tensureDir(vfs, \"/dev/pts\");\n\tensureDir(vfs, \"/dev/shm\");\n}\n\n// \u2500\u2500\u2500 /usr \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapUsr(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/usr\");\n\tensureDir(vfs, \"/usr/bin\");\n\tensureDir(vfs, \"/usr/sbin\");\n\tensureDir(vfs, \"/usr/local\");\n\tensureDir(vfs, \"/usr/local/bin\");\n\tensureDir(vfs, \"/usr/local/lib\");\n\tensureDir(vfs, \"/usr/local/share\");\n\tensureDir(vfs, \"/usr/share\");\n\tensureDir(vfs, \"/usr/share/doc\");\n\tensureDir(vfs, \"/usr/share/man\");\n\tensureDir(vfs, \"/usr/share/man/man1\");\n\tensureDir(vfs, \"/usr/lib\");\n\n\t// Stub binaries so `which` can find built-in commands\n\tconst builtins = [\n\t\t\"sh\",\n\t\t\"bash\",\n\t\t\"ls\",\n\t\t\"cat\",\n\t\t\"echo\",\n\t\t\"grep\",\n\t\t\"find\",\n\t\t\"sort\",\n\t\t\"head\",\n\t\t\"tail\",\n\t\t\"cut\",\n\t\t\"tr\",\n\t\t\"sed\",\n\t\t\"awk\",\n\t\t\"wc\",\n\t\t\"tee\",\n\t\t\"tar\",\n\t\t\"gzip\",\n\t\t\"gunzip\",\n\t\t\"touch\",\n\t\t\"mkdir\",\n\t\t\"rm\",\n\t\t\"mv\",\n\t\t\"cp\",\n\t\t\"chmod\",\n\t\t\"ln\",\n\t\t\"pwd\",\n\t\t\"env\",\n\t\t\"date\",\n\t\t\"sleep\",\n\t\t\"id\",\n\t\t\"whoami\",\n\t\t\"hostname\",\n\t\t\"uname\",\n\t\t\"ps\",\n\t\t\"kill\",\n\t\t\"df\",\n\t\t\"du\",\n\t\t\"curl\",\n\t\t\"wget\",\n\t\t\"nano\",\n\t\t\"diff\",\n\t\t\"uniq\",\n\t\t\"xargs\",\n\t\t\"base64\",\n\t];\n\tfor (const bin of builtins) {\n\t\tensureFile(\n\t\t\tvfs,\n\t\t\t`/usr/bin/${bin}`,\n\t\t\t`#!/bin/sh\\nexec builtin ${bin} \"$@\"\\n`,\n\t\t\t0o755,\n\t\t);\n\t}\n\n\t// lsb_release script\n\tensureFile(\n\t\tvfs,\n\t\t\"/usr/bin/lsb_release\",\n\t\t'#!/bin/sh\\nexec lsb_release \"$@\"\\n',\n\t\t0o755,\n\t);\n}\n\n// \u2500\u2500\u2500 /var \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapVar(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/var\");\n\tensureDir(vfs, \"/var/log\");\n\tensureDir(vfs, \"/var/tmp\");\n\tensureDir(vfs, \"/var/run\");\n\tensureDir(vfs, \"/var/cache\");\n\tensureDir(vfs, \"/var/cache/apt\");\n\tensureDir(vfs, \"/var/cache/apt/archives\");\n\tensureDir(vfs, \"/var/lib\");\n\tensureDir(vfs, \"/var/lib/apt\");\n\tensureDir(vfs, \"/var/lib/apt/lists\");\n\tensureDir(vfs, \"/var/lib/dpkg\");\n\tensureDir(vfs, \"/var/lib/dpkg/info\");\n\n\t// dpkg status \u2014 starts empty, apt install populates it\n\tensureFile(vfs, \"/var/lib/dpkg/status\", \"\");\n\tensureFile(vfs, \"/var/lib/dpkg/available\", \"\");\n\n\t// syslog stub\n\tensureFile(\n\t\tvfs,\n\t\t\"/var/log/syslog\",\n\t\t`${new Date().toUTCString()} fortune kernel: Virtual container started\\n`,\n\t);\n\tensureFile(vfs, \"/var/log/auth.log\", \"\");\n\tensureFile(vfs, \"/var/log/dpkg.log\", \"\");\n\tensureFile(vfs, \"/var/log/apt/history.log\", \"\");\n\tensureFile(vfs, \"/var/log/apt/term.log\", \"\");\n}\n\n// \u2500\u2500\u2500 /bin + /sbin symlinks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapBin(vfs: VirtualFileSystem): void {\n\t// On modern Debian/Ubuntu /bin is a symlink to /usr/bin\n\tif (!vfs.exists(\"/bin\")) {\n\t\tvfs.symlink(\"/usr/bin\", \"/bin\");\n\t}\n\tif (!vfs.exists(\"/sbin\")) {\n\t\tvfs.symlink(\"/usr/sbin\", \"/sbin\");\n\t}\n\tif (!vfs.exists(\"/lib\")) {\n\t\tensureDir(vfs, \"/lib\");\n\t}\n\tif (!vfs.exists(\"/lib64\")) {\n\t\tensureDir(vfs, \"/lib64\");\n\t}\n}\n\n// \u2500\u2500\u2500 /tmp \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapTmp(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/tmp\", 0o1777);\n}\n\n// \u2500\u2500\u2500 /root \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapRoot(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/root\", 0o700);\n\tensureFile(\n\t\tvfs,\n\t\t\"/root/.bashrc\",\n\t\t`${[\n\t\t\t\"# root .bashrc\",\n\t\t\t\"export PS1='\\\\[\\\\033[0;31m\\\\]\\\\u@\\\\h\\\\[\\\\033[0m\\\\]:\\\\[\\\\033[0;34m\\\\]\\\\w\\\\[\\\\033[0m\\\\]# '\",\n\t\t\t\"export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\n\t\t\t\"alias ll='ls -la'\",\n\t\t\t\"alias la='ls -A'\",\n\t\t].join(\"\\n\")}\\n`,\n\t);\n\tensureFile(vfs, \"/root/.profile\", \"[ -f ~/.bashrc ] && . ~/.bashrc\\n\");\n\t// Fix: /home/root should map to /root for root user\n\tif (!vfs.exists(\"/home/root\")) {\n\t\tvfs.symlink(\"/root\", \"/home/root\");\n\t}\n}\n\n// \u2500\u2500\u2500 /opt + /srv + /mnt + /media \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bootstrapMisc(vfs: VirtualFileSystem): void {\n\tensureDir(vfs, \"/opt\");\n\tensureDir(vfs, \"/srv\");\n\tensureDir(vfs, \"/mnt\");\n\tensureDir(vfs, \"/media\");\n}\n\n// \u2500\u2500\u2500 main entry point \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Bootstraps the full Linux rootfs hierarchy in the VFS.\n * Safe to call multiple times \u2014 idempotent.\n *\n * @param vfs Target virtual filesystem.\n * @param users User manager (for /etc/passwd sync).\n * @param hostname Virtual hostname.\n * @param props Shell properties (kernel, os, arch).\n * @param shellStartTime Unix ms of shell creation (for uptime).\n */\nexport function bootstrapLinuxRootfs(\n\tvfs: VirtualFileSystem,\n\tusers: VirtualUserManager,\n\thostname: string,\n\tprops: ShellProperties,\n\tshellStartTime: number,\n): void {\n\tbootstrapEtc(vfs, hostname, props);\n\tbootstrapSys(vfs, props);\n\tbootstrapDev(vfs);\n\tbootstrapUsr(vfs);\n\tbootstrapVar(vfs);\n\tbootstrapBin(vfs);\n\tbootstrapTmp(vfs);\n\tbootstrapRoot(vfs);\n\tbootstrapMisc(vfs);\n\trefreshProc(vfs, props, hostname, shellStartTime, []);\n\tsyncEtcPasswd(vfs, users);\n}\n", "export type PerfLogger = {\n\tenabled: boolean;\n\tmark: (label: string) => void;\n\tdone: (label?: string) => void;\n};\n\nfunction isTruthyEnv(value: string | undefined): boolean {\n\treturn value === \"1\" || value === \"true\";\n}\n\nfunction nowMs(): number {\n\tif (\n\t\ttypeof performance !== \"undefined\" &&\n\t\ttypeof performance.now === \"function\"\n\t) {\n\t\treturn performance.now();\n\t}\n\n\treturn Date.now();\n}\n\nexport function isPerfLoggingEnabled(): boolean {\n\treturn (\n\t\tisTruthyEnv(process.env.DEV_MODE) || isTruthyEnv(process.env.RENDER_PERF)\n\t);\n}\n\nexport function createPerfLogger(scope: string): PerfLogger {\n\tconst enabled = isPerfLoggingEnabled();\n\tif (!enabled) {\n\t\treturn {\n\t\t\tenabled,\n\t\t\tmark: () => undefined,\n\t\t\tdone: () => undefined,\n\t\t};\n\t}\n\n\tconst startedAt = nowMs();\n\n\tconst mark = (label: string): void => {\n\t\tconst elapsedMs = nowMs() - startedAt;\n\t\tconsole.log(`[perf][${scope}] ${label}: ${elapsedMs.toFixed(1)}ms`);\n\t};\n\n\tconst done = (label = \"done\"): void => {\n\t\tmark(label);\n\t};\n\n\treturn {\n\t\tenabled,\n\t\tmark,\n\t\tdone,\n\t};\n}\n\nexport async function withPerf<T>(\n\tscope: string,\n\tlabel: string,\n\twork: () => Promise<T>,\n): Promise<T> {\n\tconst perf = createPerfLogger(scope);\n\tif (!perf.enabled) {\n\t\treturn work();\n\t}\n\n\tperf.mark(`${label}:start`);\n\ttry {\n\t\treturn await work();\n\t} finally {\n\t\tperf.done(`${label}:done`);\n\t}\n}\n", "import { EventEmitter } from \"node:events\";\nimport * as fsSync from \"node:fs\";\nimport * as path from \"node:path\";\nimport { gunzipSync, gzipSync } from \"node:zlib\";\nimport type {\n\tInternalDirectoryNode,\n\tInternalFileNode,\n\tInternalNode,\n} from \"./internalTypes\";\nimport { decodeVfs, encodeVfs, isBinarySnapshot } from \"./binaryPack\";\nimport { getNode, getParentDirectory, normalizePath } from \"./path\";\nimport type {\n\tRemoveOptions,\n\tVfsNodeStats,\n\tVfsSnapshot,\n\tVfsSnapshotDirectoryNode,\n\tVfsSnapshotFileNode,\n\tVfsSnapshotNode,\n\tWriteFileOptions,\n} from \"../types/vfs\";\n\n// \u2500\u2500 Persistence options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * \"memory\" \u2014 pure in-memory, no disk I/O (default).\n *\n * \"fs\" \u2014 mirrors the VFS tree to a directory on the host filesystem.\n * `snapshotPath` must be set to the directory where the binary\n * snapshot file will be read/written (`vfs-snapshot.vfsb`).\n */\nexport type VfsPersistenceMode = \"memory\" | \"fs\";\n\nexport interface VfsOptions {\n\t/**\n\t * Persistence mode.\n\t * - `\"memory\"` (default): no disk access, snapshot via `toSnapshot()`.\n\t * - `\"fs\"`: auto-save JSON snapshot to `snapshotPath` on every\n\t * `flushMirror()` call, and restore from it on `restoreMirror()`.\n\t */\n\tmode?: VfsPersistenceMode;\n\t/**\n\t * Directory used by `\"fs\"` mode.\n\t * The snapshot file will be written to `<snapshotPath>/vfs-snapshot.json`.\n\t * Required when `mode` is `\"fs\"`.\n\t */\n\tsnapshotPath?: string;\n}\n\n// \u2500\u2500 VirtualFileSystem \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * In-memory virtual filesystem with optional JSON-snapshot persistence.\n *\n * **Memory mode** (default) \u2014 all state lives in a fast recursive tree.\n * Use `toSnapshot()` / `fromSnapshot()` / `importSnapshot()` for serialisation.\n *\n * **FS mode** \u2014 same in-memory tree, but `restoreMirror()` loads a binary\n * snapshot from disk and `flushMirror()` writes it back. This gives you\n * persistent VFS state across process restarts without any real POSIX filesystem\n * semantics leaking through.\n *\n * @example\n * ```ts\n * // Pure in-memory (default)\n * const vfs = new VirtualFileSystem();\n *\n * // With disk persistence\n * const vfs = new VirtualFileSystem({ mode: \"fs\", snapshotPath: \"./data\" });\n * await vfs.restoreMirror(); // load from disk (no-op if no snapshot yet)\n * // ... use vfs ...\n * await vfs.flushMirror(); // persist to disk\n * ```\n */\nclass VirtualFileSystem extends EventEmitter {\n\tprivate root: InternalDirectoryNode;\n\tprivate readonly mode: VfsPersistenceMode;\n\tprivate readonly snapshotFile: string | null;\n\n\tconstructor(options: VfsOptions = {}) {\n\t\tsuper();\n\t\tthis.mode = options.mode ?? \"memory\";\n\t\tif (this.mode === \"fs\") {\n\t\t\tif (!options.snapshotPath) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'VirtualFileSystem: \"snapshotPath\" is required when mode is \"fs\".',\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.snapshotFile = path.resolve(\n\t\t\t\toptions.snapshotPath,\n\t\t\t\t\"vfs-snapshot.vfsb\",\n\t\t\t);\n\t\t} else {\n\t\t\tthis.snapshotFile = null;\n\t\t}\n\t\tthis.root = this.makeDir(\"\", 0o755);\n\t}\n\n\t// \u2500\u2500 Internal helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\tprivate makeDir(name: string, mode: number): InternalDirectoryNode {\n\t\tconst now = new Date();\n\t\treturn {\n\t\t\ttype: \"directory\",\n\t\t\tname,\n\t\t\tmode,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t\tchildren: new Map(),\n\t\t};\n\t}\n\n\tprivate makeFile(\n\t\tname: string,\n\t\tcontent: Buffer,\n\t\tmode: number,\n\t\tcompressed: boolean,\n\t): InternalFileNode {\n\t\tconst now = new Date();\n\t\treturn {\n\t\t\ttype: \"file\",\n\t\t\tname,\n\t\t\tcontent,\n\t\t\tmode,\n\t\t\tcompressed,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t};\n\t}\n\n\tprivate mkdirRecursive(targetPath: string, mode: number): void {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tif (normalized === \"/\") return;\n\t\tconst parts = normalized.split(\"/\").filter(Boolean);\n\t\tlet current = this.root;\n\t\tlet builtPath = \"\";\n\t\tfor (const part of parts) {\n\t\t\tbuiltPath += `/${part}`;\n\t\t\tlet child = current.children.get(part);\n\t\t\tif (!child) {\n\t\t\t\tchild = this.makeDir(part, mode);\n\t\t\t\tcurrent.children.set(part, child);\n\t\t\t\tthis.emit(\"dir:create\", { path: builtPath, mode });\n\t\t\t} else if (child.type !== \"directory\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot create directory '${builtPath}': path is a file.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcurrent = child as InternalDirectoryNode;\n\t\t}\n\t}\n\n\t// \u2500\u2500 Persistence \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\t/**\n\t * In `\"fs\"` mode: reads the binary snapshot (`vfs-snapshot.vfsb`) from disk.\n\t * Automatically falls back to legacy JSON format for backward compatibility.\n\t * Silently succeeds when the snapshot file does not exist yet.\n\t *\n\t * In `\"memory\"` mode: no-op (kept for API compatibility).\n\t */\n\tpublic async restoreMirror(): Promise<void> {\n\t\tif (this.mode !== \"fs\" || !this.snapshotFile) return;\n\n\t\tif (!fsSync.existsSync(this.snapshotFile)) return;\n\n\t\ttry {\n\t\t\tconst raw = fsSync.readFileSync(this.snapshotFile);\n\t\t\tif (isBinarySnapshot(raw)) {\n\t\t\t\t// Fast binary format (current)\n\t\t\t\tthis.root = decodeVfs(raw);\n\t\t\t} else {\n\t\t\t\t// Legacy JSON fallback \u2014 auto-migrates on next flushMirror()\n\t\t\t\tconst snapshot: VfsSnapshot = JSON.parse(raw.toString(\"utf8\"));\n\t\t\t\tthis.root = this.deserializeDir(snapshot.root, \"\");\n\t\t\t\tconsole.info(\n\t\t\t\t\t\"[VirtualFileSystem] Migrating legacy JSON snapshot to binary format.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.emit(\"snapshot:restore\", { path: this.snapshotFile });\n\t\t} catch (err) {\n\t\t\t// Corrupt or unreadable snapshot \u2014 start fresh and warn\n\t\t\tconsole.warn(\n\t\t\t\t`[VirtualFileSystem] Could not restore snapshot from ${this.snapshotFile}:`,\n\t\t\t\terr instanceof Error ? err.message : String(err),\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * In `\"fs\"` mode: serialises the in-memory tree to a binary snapshot on disk\n\t * (`vfs-snapshot.vfsb`). ~27% smaller and significantly faster than JSON+base64.\n\t * The directory is created if it does not exist.\n\t *\n\t * In `\"memory\"` mode: emits `\"mirror:flush\"` and returns (no disk write).\n\t */\n\tpublic async flushMirror(): Promise<void> {\n\t\tif (this.mode !== \"fs\" || !this.snapshotFile) {\n\t\t\tthis.emit(\"mirror:flush\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst dir = path.dirname(this.snapshotFile);\n\t\tfsSync.mkdirSync(dir, { recursive: true });\n\t\tconst binary = encodeVfs(this.root);\n\t\tfsSync.writeFileSync(this.snapshotFile, binary);\n\t\tthis.emit(\"mirror:flush\", { path: this.snapshotFile });\n\t}\n\n\t/** Returns the current persistence mode. */\n\tpublic getMode(): VfsPersistenceMode {\n\t\treturn this.mode;\n\t}\n\n\t/** Returns the snapshot file path used in `\"fs\"` mode, or `null`. */\n\tpublic getSnapshotPath(): string | null {\n\t\treturn this.snapshotFile;\n\t}\n\n\t// \u2500\u2500 Public filesystem API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\t/** Creates a directory (and any missing parents). */\n\tpublic mkdir(targetPath: string, mode: number = 0o755): void {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst existing = (() => {\n\t\t\ttry {\n\t\t\t\treturn getNode(this.root, normalized);\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t})();\n\t\tif (existing && existing.type !== \"directory\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot create directory '${normalized}': path is a file.`,\n\t\t\t);\n\t\t}\n\t\tthis.mkdirRecursive(normalized, mode);\n\t}\n\n\t/**\n\t * Writes UTF-8 text or binary content into a file.\n\t * Parent directories are created when missing.\n\t */\n\tpublic writeFile(\n\t\ttargetPath: string,\n\t\tcontent: string | Buffer,\n\t\toptions: WriteFileOptions = {},\n\t): void {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst { parent, name } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\tnormalized,\n\t\t\ttrue,\n\t\t\t(p) => this.mkdirRecursive(p, 0o755),\n\t\t);\n\n\t\tconst existing = parent.children.get(name);\n\t\tif (existing?.type === \"directory\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot write file '${normalized}': path is a directory.`,\n\t\t\t);\n\t\t}\n\n\t\tconst rawContent = Buffer.isBuffer(content)\n\t\t\t? content\n\t\t\t: Buffer.from(content, \"utf8\");\n\t\tconst shouldCompress = options.compress ?? false;\n\t\tconst storedContent = shouldCompress ? gzipSync(rawContent) : rawContent;\n\t\tconst mode = options.mode ?? 0o644;\n\n\t\tif (existing) {\n\t\t\tconst f = existing as InternalFileNode;\n\t\t\tf.content = storedContent;\n\t\t\tf.compressed = shouldCompress;\n\t\t\tf.mode = mode;\n\t\t\tf.updatedAt = new Date();\n\t\t} else {\n\t\t\tparent.children.set(\n\t\t\t\tname,\n\t\t\t\tthis.makeFile(name, storedContent, mode, shouldCompress),\n\t\t\t);\n\t\t}\n\n\t\tthis.emit(\"file:write\", { path: normalized, size: storedContent.length });\n\t}\n\n\t/**\n\t * Reads file content as a UTF-8 string.\n\t * Gzip-compressed files are transparently decompressed.\n\t */\n\tpublic readFile(targetPath: string): string {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type !== \"file\") {\n\t\t\tthrow new Error(`Cannot read '${targetPath}': not a file.`);\n\t\t}\n\t\tconst f = node as InternalFileNode;\n\t\tconst raw = f.compressed ? gunzipSync(f.content) : f.content;\n\t\tthis.emit(\"file:read\", { path: normalized, size: raw.length });\n\t\treturn raw.toString(\"utf8\");\n\t}\n\n\t/** Reads file content as a Buffer (decompresses if needed). */\n\tpublic readFileRaw(targetPath: string): Buffer {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type !== \"file\") {\n\t\t\tthrow new Error(`Cannot read '${targetPath}': not a file.`);\n\t\t}\n\t\tconst f = node as InternalFileNode;\n\t\tconst raw = f.compressed ? gunzipSync(f.content) : f.content;\n\t\tthis.emit(\"file:read\", { path: normalized, size: raw.length });\n\t\treturn raw;\n\t}\n\n\t/** Returns true when a file or directory exists at path. */\n\tpublic exists(targetPath: string): boolean {\n\t\ttry {\n\t\t\tgetNode(this.root, normalizePath(targetPath));\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/** Updates mode bits on a node. */\n\tpublic chmod(targetPath: string, mode: number): void {\n\t\tgetNode(this.root, normalizePath(targetPath)).mode = mode;\n\t}\n\n\t/** Returns metadata for a file or directory. */\n\tpublic stat(targetPath: string): VfsNodeStats {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tconst name = normalized === \"/\" ? \"\" : path.posix.basename(normalized);\n\t\tif (node.type === \"file\") {\n\t\t\tconst f = node as InternalFileNode;\n\t\t\treturn {\n\t\t\t\ttype: \"file\",\n\t\t\t\tname,\n\t\t\t\tpath: normalized,\n\t\t\t\tmode: f.mode,\n\t\t\t\tcreatedAt: f.createdAt,\n\t\t\t\tupdatedAt: f.updatedAt,\n\t\t\t\tcompressed: f.compressed,\n\t\t\t\tsize: f.content.length,\n\t\t\t};\n\t\t}\n\t\tconst d = node as InternalDirectoryNode;\n\t\treturn {\n\t\t\ttype: \"directory\",\n\t\t\tname,\n\t\t\tpath: normalized,\n\t\t\tmode: d.mode,\n\t\t\tcreatedAt: d.createdAt,\n\t\t\tupdatedAt: d.updatedAt,\n\t\t\tchildrenCount: d.children.size,\n\t\t};\n\t}\n\n\t/** Lists direct children names of a directory (sorted). */\n\tpublic list(dirPath: string = \"/\"): string[] {\n\t\tconst normalized = normalizePath(dirPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type !== \"directory\") {\n\t\t\tthrow new Error(`Cannot list '${dirPath}': not a directory.`);\n\t\t}\n\t\treturn Array.from((node as InternalDirectoryNode).children.keys()).sort();\n\t}\n\n\t/** Renders ASCII tree view of a directory hierarchy. */\n\tpublic tree(dirPath: string = \"/\"): string {\n\t\tconst normalized = normalizePath(dirPath);\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type !== \"directory\") {\n\t\t\tthrow new Error(`Cannot render tree for '${dirPath}': not a directory.`);\n\t\t}\n\t\tconst label = dirPath === \"/\" ? \"/\" : path.posix.basename(normalized);\n\t\treturn this.renderTreeLines(node as InternalDirectoryNode, label);\n\t}\n\n\tprivate renderTreeLines(dir: InternalDirectoryNode, label: string): string {\n\t\tconst lines = [label];\n\t\tconst entries = Array.from(dir.children.keys()).sort();\n\t\tfor (let i = 0; i < entries.length; i++) {\n\t\t\tconst name = entries[i]!;\n\t\t\tconst child = dir.children.get(name)!;\n\t\t\tconst isLast = i === entries.length - 1;\n\t\t\tconst connector = isLast ? \"\u2514\u2500\u2500 \" : \"\u251C\u2500\u2500 \";\n\t\t\tconst nextPrefix = isLast ? \" \" : \"\u2502 \";\n\t\t\tlines.push(`${connector}${name}`);\n\t\t\tif (child.type === \"directory\") {\n\t\t\t\tconst sub = this.renderTreeLines(child as InternalDirectoryNode, \"\")\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.slice(1)\n\t\t\t\t\t.map((l) => `${nextPrefix}${l}`);\n\t\t\t\tlines.push(...sub);\n\t\t\t}\n\t\t}\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\t/** Computes total stored bytes under a path. */\n\tpublic getUsageBytes(targetPath: string = \"/\"): number {\n\t\treturn this.computeUsage(getNode(this.root, normalizePath(targetPath)));\n\t}\n\n\tprivate computeUsage(node: InternalNode): number {\n\t\tif (node.type === \"file\") return (node as InternalFileNode).content.length;\n\t\tlet total = 0;\n\t\tfor (const child of (node as InternalDirectoryNode).children.values()) {\n\t\t\ttotal += this.computeUsage(child);\n\t\t}\n\t\treturn total;\n\t}\n\n\t/** Compresses a file's content with gzip in place. */\n\tpublic compressFile(targetPath: string): void {\n\t\tconst node = getNode(this.root, normalizePath(targetPath));\n\t\tif (node.type !== \"file\")\n\t\t\tthrow new Error(`Cannot compress '${targetPath}': not a file.`);\n\t\tconst f = node as InternalFileNode;\n\t\tif (!f.compressed) {\n\t\t\tf.content = gzipSync(f.content);\n\t\t\tf.compressed = true;\n\t\t\tf.updatedAt = new Date();\n\t\t}\n\t}\n\n\t/** Decompresses a gzip-compressed file in place. */\n\tpublic decompressFile(targetPath: string): void {\n\t\tconst node = getNode(this.root, normalizePath(targetPath));\n\t\tif (node.type !== \"file\")\n\t\t\tthrow new Error(`Cannot decompress '${targetPath}': not a file.`);\n\t\tconst f = node as InternalFileNode;\n\t\tif (f.compressed) {\n\t\t\tf.content = gunzipSync(f.content);\n\t\t\tf.compressed = false;\n\t\t\tf.updatedAt = new Date();\n\t\t}\n\t}\n\n\t/**\n\t * Creates a symbolic link.\n\t * The link node is stored with mode `0o120777` (POSIX symlink convention).\n\t */\n\tpublic symlink(targetPath: string, linkPath: string): void {\n\t\tconst normalizedLink = normalizePath(linkPath);\n\t\tconst normalizedTarget = targetPath.startsWith(\"/\")\n\t\t\t? normalizePath(targetPath)\n\t\t\t: targetPath;\n\t\tconst { parent, name } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\tnormalizedLink,\n\t\t\ttrue,\n\t\t\t(p) => this.mkdirRecursive(p, 0o755),\n\t\t);\n\t\tconst symNode: InternalFileNode = {\n\t\t\ttype: \"file\",\n\t\t\tname,\n\t\t\tcontent: Buffer.from(normalizedTarget, \"utf8\"),\n\t\t\tmode: 0o120777,\n\t\t\tcompressed: false,\n\t\t\tcreatedAt: new Date(),\n\t\t\tupdatedAt: new Date(),\n\t\t};\n\t\tparent.children.set(name, symNode);\n\t\tthis.emit(\"symlink:create\", {\n\t\t\tlink: normalizedLink,\n\t\t\ttarget: normalizedTarget,\n\t\t});\n\t}\n\n\t/** Returns true when the path is a symbolic link node. */\n\tpublic isSymlink(targetPath: string): boolean {\n\t\ttry {\n\t\t\tconst node = getNode(this.root, normalizePath(targetPath));\n\t\t\treturn node.type === \"file\" && node.mode === 0o120777;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Resolves a symlink chain up to `maxDepth` hops.\n\t * Throws when the chain is too long (circular links).\n\t */\n\tpublic resolveSymlink(linkPath: string, maxDepth = 8): string {\n\t\tlet current = normalizePath(linkPath);\n\t\tfor (let depth = 0; depth < maxDepth; depth++) {\n\t\t\ttry {\n\t\t\t\tconst node = getNode(this.root, current);\n\t\t\t\tif (node.type === \"file\" && node.mode === 0o120777) {\n\t\t\t\t\tconst target = (node as InternalFileNode).content.toString(\"utf8\");\n\t\t\t\t\tcurrent = target.startsWith(\"/\")\n\t\t\t\t\t\t? target\n\t\t\t\t\t\t: normalizePath(\n\t\t\t\t\t\t\t\tpath.posix.join(path.posix.dirname(current), target),\n\t\t\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn current;\n\t\t}\n\t\tthrow new Error(`Too many levels of symbolic links: ${linkPath}`);\n\t}\n\n\t/** Removes a file or directory node. */\n\tpublic remove(targetPath: string, options: RemoveOptions = {}): void {\n\t\tconst normalized = normalizePath(targetPath);\n\t\tif (normalized === \"/\") throw new Error(\"Cannot remove root directory.\");\n\t\tconst node = getNode(this.root, normalized);\n\t\tif (node.type === \"directory\") {\n\t\t\tconst dir = node as InternalDirectoryNode;\n\t\t\tif (!options.recursive && dir.children.size > 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Directory '${normalized}' is not empty. Use recursive option.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tconst { parent, name } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\tnormalized,\n\t\t\tfalse,\n\t\t\t() => {},\n\t\t);\n\t\tparent.children.delete(name);\n\t\tthis.emit(\"node:remove\", { path: normalized });\n\t}\n\n\t/** Moves or renames a node. */\n\tpublic move(fromPath: string, toPath: string): void {\n\t\tconst fromNormalized = normalizePath(fromPath);\n\t\tconst toNormalized = normalizePath(toPath);\n\t\tif (fromNormalized === \"/\" || toNormalized === \"/\") {\n\t\t\tthrow new Error(\"Cannot move root directory.\");\n\t\t}\n\t\tconst node = getNode(this.root, fromNormalized);\n\t\tif (this.exists(toNormalized)) {\n\t\t\tthrow new Error(`Destination '${toNormalized}' already exists.`);\n\t\t}\n\t\tthis.mkdirRecursive(path.posix.dirname(toNormalized), 0o755);\n\t\tconst { parent: destParent, name: destName } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\ttoNormalized,\n\t\t\tfalse,\n\t\t\t() => {},\n\t\t);\n\t\tconst { parent: srcParent, name: srcName } = getParentDirectory(\n\t\t\tthis.root,\n\t\t\tfromNormalized,\n\t\t\tfalse,\n\t\t\t() => {},\n\t\t);\n\t\tsrcParent.children.delete(srcName);\n\t\tnode.name = destName;\n\t\tdestParent.children.set(destName, node);\n\t}\n\n\t// \u2500\u2500 Snapshot serialisation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\t/**\n\t * Exports the entire filesystem as a JSON-serialisable snapshot.\n\t *\n\t * Works regardless of the persistence mode. Useful for test fixtures,\n\t * manual backups, or passing VFS state between processes.\n\t */\n\tpublic toSnapshot(): VfsSnapshot {\n\t\treturn { root: this.serializeDir(this.root) };\n\t}\n\n\tprivate serializeDir(dir: InternalDirectoryNode): VfsSnapshotDirectoryNode {\n\t\tconst children: VfsSnapshotNode[] = [];\n\t\tfor (const child of dir.children.values()) {\n\t\t\tchildren.push(\n\t\t\t\tchild.type === \"file\"\n\t\t\t\t\t? this.serializeFile(child as InternalFileNode)\n\t\t\t\t\t: this.serializeDir(child as InternalDirectoryNode),\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\ttype: \"directory\",\n\t\t\tname: dir.name,\n\t\t\tmode: dir.mode,\n\t\t\tcreatedAt: dir.createdAt.toISOString(),\n\t\t\tupdatedAt: dir.updatedAt.toISOString(),\n\t\t\tchildren,\n\t\t};\n\t}\n\n\tprivate serializeFile(file: InternalFileNode): VfsSnapshotFileNode {\n\t\treturn {\n\t\t\ttype: \"file\",\n\t\t\tname: file.name,\n\t\t\tmode: file.mode,\n\t\t\tcreatedAt: file.createdAt.toISOString(),\n\t\t\tupdatedAt: file.updatedAt.toISOString(),\n\t\t\tcompressed: file.compressed,\n\t\t\tcontentBase64: file.content.toString(\"base64\"),\n\t\t};\n\t}\n\n\t/**\n\t * Creates a new `VirtualFileSystem` instance (memory mode) from a snapshot.\n\t *\n\t * @example\n\t * ```ts\n\t * const vfs = VirtualFileSystem.fromSnapshot(savedSnapshot);\n\t * ```\n\t */\n\tpublic static fromSnapshot(snapshot: VfsSnapshot): VirtualFileSystem {\n\t\tconst vfs = new VirtualFileSystem();\n\t\tvfs.root = vfs.deserializeDir(snapshot.root, \"\");\n\t\treturn vfs;\n\t}\n\n\t/**\n\t * Replaces the current filesystem state with the content of a snapshot.\n\t * The persistence mode is preserved.\n\t *\n\t * @example\n\t * ```ts\n\t * vfs.importSnapshot(savedSnapshot);\n\t * ```\n\t */\n\tpublic importSnapshot(snapshot: VfsSnapshot): void {\n\t\tthis.root = this.deserializeDir(snapshot.root, \"\");\n\t\tthis.emit(\"snapshot:import\");\n\t}\n\n\tprivate deserializeDir(\n\t\tsnap: VfsSnapshotDirectoryNode,\n\t\tname: string,\n\t): InternalDirectoryNode {\n\t\tconst dir: InternalDirectoryNode = {\n\t\t\ttype: \"directory\",\n\t\t\tname,\n\t\t\tmode: snap.mode,\n\t\t\tcreatedAt: new Date(snap.createdAt),\n\t\t\tupdatedAt: new Date(snap.updatedAt),\n\t\t\tchildren: new Map(),\n\t\t};\n\t\tfor (const child of snap.children) {\n\t\t\tif (child.type === \"file\") {\n\t\t\t\tconst f = child as VfsSnapshotFileNode;\n\t\t\t\tdir.children.set(f.name, {\n\t\t\t\t\ttype: \"file\",\n\t\t\t\t\tname: f.name,\n\t\t\t\t\tmode: f.mode,\n\t\t\t\t\tcreatedAt: new Date(f.createdAt),\n\t\t\t\t\tupdatedAt: new Date(f.updatedAt),\n\t\t\t\t\tcompressed: f.compressed,\n\t\t\t\t\tcontent: Buffer.from(f.contentBase64, \"base64\"),\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst sub = this.deserializeDir(\n\t\t\t\t\tchild as VfsSnapshotDirectoryNode,\n\t\t\t\t\tchild.name,\n\t\t\t\t);\n\t\t\t\tdir.children.set(child.name, sub);\n\t\t\t}\n\t\t}\n\t\treturn dir;\n\t}\n}\n\nexport default VirtualFileSystem;\n", "/**\n * Binary serialisation format for VirtualFileSystem snapshots.\n *\n * Replaces the JSON+base64 approach. No external dependencies.\n *\n * Wire format (little-endian throughout):\n *\n * File header:\n * [4] magic = 0x56 0x46 0x53 0x21 (\"VFS!\")\n * [1] version = 0x01\n *\n * Node (recursive):\n * [1] type = 0x01 (file) | 0x02 (directory)\n * [2] name length (uint16)\n * [N] name bytes (utf8)\n * [4] mode (uint32)\n * [8] createdAt ms (float64)\n * [8] updatedAt ms (float64)\n *\n * File node extra:\n * [1] compressed flag (0x00 | 0x01)\n * [4] content length (uint32)\n * [N] content bytes (raw \u2014 no base64)\n *\n * Directory node extra:\n * [4] children count (uint32)\n * [N] children nodes (recursive)\n *\n * Total overhead vs JSON+base64 for 1 MB of file data:\n * JSON+base64 : ~1.37 MB (base64 33% bloat) + JSON string wrapping\n * Binary pack : ~1.00 MB + ~40 bytes/node header \u2192 ~27% smaller, no string parsing\n */\n\nimport type {\n\tInternalDirectoryNode,\n\tInternalFileNode,\n\tInternalNode,\n} from \"./internalTypes\";\n\nconst MAGIC = Buffer.from([0x56, 0x46, 0x53, 0x21]); // \"VFS!\"\nconst VERSION = 0x01;\nconst TYPE_FILE = 0x01;\nconst TYPE_DIR = 0x02;\n\n// \u2500\u2500 Encoder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nclass Encoder {\n\tprivate chunks: Buffer[] = [];\n\n\twrite(buf: Buffer): void {\n\t\tthis.chunks.push(buf);\n\t}\n\n\twriteUint8(n: number): void {\n\t\tconst b = Buffer.allocUnsafe(1);\n\t\tb.writeUInt8(n, 0);\n\t\tthis.chunks.push(b);\n\t}\n\n\twriteUint16(n: number): void {\n\t\tconst b = Buffer.allocUnsafe(2);\n\t\tb.writeUInt16LE(n, 0);\n\t\tthis.chunks.push(b);\n\t}\n\n\twriteUint32(n: number): void {\n\t\tconst b = Buffer.allocUnsafe(4);\n\t\tb.writeUInt32LE(n, 0);\n\t\tthis.chunks.push(b);\n\t}\n\n\twriteFloat64(n: number): void {\n\t\tconst b = Buffer.allocUnsafe(8);\n\t\tb.writeDoubleBE(n, 0);\n\t\tthis.chunks.push(b);\n\t}\n\n\twriteString(s: string): void {\n\t\tconst encoded = Buffer.from(s, \"utf8\");\n\t\tthis.writeUint16(encoded.length);\n\t\tthis.chunks.push(encoded);\n\t}\n\n\twriteBytes(bytes: Buffer): void {\n\t\tthis.writeUint32(bytes.length);\n\t\tthis.chunks.push(bytes);\n\t}\n\n\ttoBuffer(): Buffer {\n\t\treturn Buffer.concat(this.chunks);\n\t}\n}\n\nfunction encodeNode(enc: Encoder, node: InternalNode): void {\n\tif (node.type === \"file\") {\n\t\tconst f = node as InternalFileNode;\n\t\tenc.writeUint8(TYPE_FILE);\n\t\tenc.writeString(f.name);\n\t\tenc.writeUint32(f.mode);\n\t\tenc.writeFloat64(f.createdAt.getTime());\n\t\tenc.writeFloat64(f.updatedAt.getTime());\n\t\tenc.writeUint8(f.compressed ? 0x01 : 0x00);\n\t\tenc.writeBytes(f.content);\n\t} else {\n\t\tconst d = node as InternalDirectoryNode;\n\t\tenc.writeUint8(TYPE_DIR);\n\t\tenc.writeString(d.name);\n\t\tenc.writeUint32(d.mode);\n\t\tenc.writeFloat64(d.createdAt.getTime());\n\t\tenc.writeFloat64(d.updatedAt.getTime());\n\t\tconst children = Array.from(d.children.values());\n\t\tenc.writeUint32(children.length);\n\t\tfor (const child of children) encodeNode(enc, child);\n\t}\n}\n\n/**\n * Serialise an in-memory VFS root to a compact binary Buffer.\n * No base64, no JSON. ~27% smaller than the JSON+base64 format for typical VFS trees.\n */\nexport function encodeVfs(root: InternalDirectoryNode): Buffer {\n\tconst enc = new Encoder();\n\tenc.write(MAGIC);\n\tenc.writeUint8(VERSION);\n\tencodeNode(enc, root);\n\treturn enc.toBuffer();\n}\n\n// \u2500\u2500 Decoder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nclass Decoder {\n\tprivate pos = 0;\n\tconstructor(private readonly buf: Buffer) {}\n\n\treadUint8(): number {\n\t\treturn this.buf.readUInt8(this.pos++);\n\t}\n\n\treadUint16(): number {\n\t\tconst v = this.buf.readUInt16LE(this.pos);\n\t\tthis.pos += 2;\n\t\treturn v;\n\t}\n\n\treadUint32(): number {\n\t\tconst v = this.buf.readUInt32LE(this.pos);\n\t\tthis.pos += 4;\n\t\treturn v;\n\t}\n\n\treadFloat64(): number {\n\t\tconst v = this.buf.readDoubleBE(this.pos);\n\t\tthis.pos += 8;\n\t\treturn v;\n\t}\n\n\treadString(): string {\n\t\tconst len = this.readUint16();\n\t\tconst s = this.buf.toString(\"utf8\", this.pos, this.pos + len);\n\t\tthis.pos += len;\n\t\treturn s;\n\t}\n\n\treadBytes(): Buffer {\n\t\tconst len = this.readUint32();\n\t\tconst b = this.buf.slice(this.pos, this.pos + len);\n\t\tthis.pos += len;\n\t\treturn b;\n\t}\n\n\tremaining(): number {\n\t\treturn this.buf.length - this.pos;\n\t}\n}\n\nfunction decodeNode(dec: Decoder): InternalNode {\n\tconst type = dec.readUint8();\n\tconst name = dec.readString();\n\tconst mode = dec.readUint32();\n\tconst createdAt = new Date(dec.readFloat64());\n\tconst updatedAt = new Date(dec.readFloat64());\n\n\tif (type === TYPE_FILE) {\n\t\tconst compressed = dec.readUint8() === 0x01;\n\t\tconst content = dec.readBytes();\n\t\treturn {\n\t\t\ttype: \"file\",\n\t\t\tname,\n\t\t\tmode,\n\t\t\tcreatedAt,\n\t\t\tupdatedAt,\n\t\t\tcompressed,\n\t\t\tcontent,\n\t\t} satisfies InternalFileNode;\n\t}\n\n\tif (type === TYPE_DIR) {\n\t\tconst count = dec.readUint32();\n\t\tconst children = new Map<string, InternalNode>();\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst child = decodeNode(dec);\n\t\t\tchildren.set(child.name, child);\n\t\t}\n\t\treturn {\n\t\t\ttype: \"directory\",\n\t\t\tname,\n\t\t\tmode,\n\t\t\tcreatedAt,\n\t\t\tupdatedAt,\n\t\t\tchildren,\n\t\t} satisfies InternalDirectoryNode;\n\t}\n\n\tthrow new Error(`[VFS binary] Unknown node type: 0x${type.toString(16)}`);\n}\n\n/**\n * Deserialise a binary Buffer produced by {@link encodeVfs} back into an\n * InternalDirectoryNode tree. Throws on magic/version mismatch or truncation.\n */\nexport function decodeVfs(buf: Buffer): InternalDirectoryNode {\n\tif (buf.length < 5) throw new Error(\"[VFS binary] Buffer too short\");\n\n\tconst magic = buf.slice(0, 4);\n\tif (!magic.equals(MAGIC)) {\n\t\tthrow new Error(\"[VFS binary] Invalid magic \u2014 not a VFS binary snapshot\");\n\t}\n\n\tconst dec = new Decoder(buf);\n\t// skip magic (4) + version (1)\n\tfor (let i = 0; i < 5; i++) dec.readUint8();\n\n\tconst root = decodeNode(dec);\n\tif (root.type !== \"directory\") {\n\t\tthrow new Error(\"[VFS binary] Root node must be a directory\");\n\t}\n\treturn root as InternalDirectoryNode;\n}\n\n/**\n * Returns true if `buf` looks like a VFS binary snapshot (starts with magic bytes).\n * Used to auto-detect format when loading from disk.\n */\nexport function isBinarySnapshot(buf: Buffer): boolean {\n\treturn buf.length >= 4 && buf.slice(0, 4).equals(MAGIC);\n}\n", "import * as path from \"node:path\";\nimport type { InternalDirectoryNode, InternalNode } from \"./internalTypes\";\n\nexport function normalizePath(rawPath: string): string {\n\tif (!rawPath || rawPath.trim() === \"\") {\n\t\treturn \"/\";\n\t}\n\n\tconst normalized = path.posix.normalize(\n\t\trawPath.startsWith(\"/\") ? rawPath : `/${rawPath}`,\n\t);\n\treturn normalized === \"\" ? \"/\" : normalized;\n}\n\nexport function splitPath(normalizedPath: string): string[] {\n\treturn normalizedPath.split(\"/\").filter(Boolean);\n}\n\nexport function getNode(\n\troot: InternalDirectoryNode,\n\ttargetPath: string,\n): InternalNode {\n\tconst normalized = normalizePath(targetPath);\n\tif (normalized === \"/\") {\n\t\treturn root;\n\t}\n\n\tconst parts = splitPath(normalized);\n\tlet current: InternalNode = root;\n\n\tfor (const part of parts) {\n\t\tif (current.type !== \"directory\") {\n\t\t\tthrow new Error(`Path '${normalized}' does not exist.`);\n\t\t}\n\n\t\tconst next = current.children.get(part);\n\t\tif (!next) {\n\t\t\tthrow new Error(`Path '${normalized}' does not exist.`);\n\t\t}\n\t\tcurrent = next;\n\t}\n\n\treturn current;\n}\n\nexport function getParentDirectory(\n\troot: InternalDirectoryNode,\n\ttargetPath: string,\n\tcreateIfMissing: boolean,\n\tcreatePath: (pathToCreate: string) => void,\n): { parent: InternalDirectoryNode; name: string } {\n\tconst normalized = normalizePath(targetPath);\n\tif (normalized === \"/\") {\n\t\tthrow new Error(\"Root path has no parent directory.\");\n\t}\n\n\tconst parentPath = path.posix.dirname(normalized);\n\tconst name = path.posix.basename(normalized);\n\n\tif (!name) {\n\t\tthrow new Error(`Invalid path '${targetPath}'.`);\n\t}\n\n\tif (createIfMissing) {\n\t\tcreatePath(parentPath);\n\t}\n\n\tconst parentNode = getNode(root, parentPath);\n\tif (parentNode.type !== \"directory\") {\n\t\tthrow new Error(`Parent path '${parentPath}' is not a directory.`);\n\t}\n\n\treturn { parent: parentNode, name };\n}\n", "import type VirtualFileSystem from \"../VirtualFileSystem\";\nimport type { VirtualUserManager } from \"../VirtualUserManager\";\n\n// \u2500\u2500\u2500 types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * A single file entry written into the VFS when a package is installed.\n */\nexport interface PackageFile {\n\t/** Absolute VFS destination path (e.g. `\"/usr/bin/vim\"`). */\n\tpath: string;\n\t/** Text content to write. */\n\tcontent: string;\n\t/** POSIX mode bits (default `0o644`; use `0o755` for executables). */\n\tmode?: number;\n}\n\n/**\n * Metadata and behaviour definition for a single package in the registry.\n *\n * Used both for the built-in registry entries and for consumer-supplied custom\n * packages. `files` are written to the VFS on `install()`, and `onInstall` /\n * `onRemove` hooks allow arbitrary VFS mutations.\n */\nexport interface PackageDefinition {\n\t/** Package name \u2014 lowercase, no spaces (e.g. `\"vim\"`, `\"build-essential\"`). */\n\tname: string;\n\t/** Debian-style version string (e.g. `\"2:9.0.1378-2\"`). */\n\tversion: string;\n\t/** CPU architecture label (default `\"amd64\"`). */\n\tarchitecture?: string;\n\t/** Maintainer name and email shown in `apt show` output. */\n\tmaintainer?: string;\n\t/** Full package description. */\n\tdescription: string;\n\t/** Short one-line summary shown in `apt search` results. */\n\tshortDesc?: string;\n\t/** Installed disk usage in kilobytes (informational). */\n\tinstalledSizeKb?: number;\n\t/** Other package names that must be installed first (resolved recursively). */\n\tdepends?: string[];\n\t/** Repository section (e.g. `\"utils\"`, `\"net\"`, `\"editors\"`, `\"devel\"`). */\n\tsection?: string;\n\t/** Files to write into the VFS during installation. */\n\tfiles?: PackageFile[];\n\t/**\n\t * Hook called after all files are written.\n\t * Use to create directories, write config, or register shell commands.\n\t */\n\tonInstall?: (vfs: VirtualFileSystem, users: VirtualUserManager) => void;\n\t/** Hook called before VFS files are removed during uninstall. */\n\tonRemove?: (vfs: VirtualFileSystem) => void;\n}\n\n/**\n * Runtime record of an installed package, persisted to `/var/lib/dpkg/status`.\n */\nexport interface InstalledPackage {\n\t/** Package name. */\n\tname: string;\n\t/** Installed version string. */\n\tversion: string;\n\t/** CPU architecture. */\n\tarchitecture: string;\n\t/** Maintainer display string. */\n\tmaintainer: string;\n\t/** Full description. */\n\tdescription: string;\n\t/** Repository section. */\n\tsection: string;\n\t/** Installed disk usage in kilobytes. */\n\tinstalledSizeKb: number;\n\t/** ISO-8601 timestamp of when the package was installed. */\n\tinstalledAt: string;\n\t/** Absolute VFS paths written by this package (used by `dpkg -L`). */\n\tfiles: string[];\n}\n\n// \u2500\u2500\u2500 built-in package registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst PACKAGE_REGISTRY: PackageDefinition[] = [\n\t{\n\t\tname: \"vim\",\n\t\tversion: \"2:9.0.1378-2\",\n\t\tsection: \"editors\",\n\t\tdescription: \"Vi IMproved - enhanced vi editor\",\n\t\tshortDesc: \"Vi IMproved\",\n\t\tinstalledSizeKb: 3812,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/vim\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'vim: use nano for editing in this environment'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/vi\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec vim \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/share/doc/vim/README\",\n\t\t\t\tcontent: \"Vim editor \u2014 virtual package.\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"git\",\n\t\tversion: \"1:2.39.2-1\",\n\t\tsection: \"vcs\",\n\t\tdescription: \"Fast, scalable, distributed revision control system\",\n\t\tshortDesc: \"fast distributed version control system\",\n\t\tinstalledSizeKb: 11240,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/git\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'git: virtual stub \u2014 no host access'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/share/doc/git/README.Debian\",\n\t\t\t\tcontent: \"Git virtual package for Fortune GNU/Linux.\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"python3\",\n\t\tversion: \"3.11.2-1+b1\",\n\t\tsection: \"python\",\n\t\tdescription: \"Interactive high-level object-oriented language (version 3)\",\n\t\tshortDesc: \"interactive high-level object-oriented language\",\n\t\tinstalledSizeKb: 512,\n\t\tdepends: [\"python3-minimal\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/python3\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'Python 3.11.2 (virtual)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/python3.11\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec python3 \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{ path: \"/usr/lib/python3.11/.keep\", content: \"\" },\n\t\t],\n\t},\n\t{\n\t\tname: \"python3-minimal\",\n\t\tversion: \"3.11.2-1+b1\",\n\t\tsection: \"python\",\n\t\tdescription: \"Minimal subset of the Python language (version 3)\",\n\t\tshortDesc: \"minimal subset of Python language\",\n\t\tinstalledSizeKb: 196,\n\t\tfiles: [{ path: \"/usr/lib/python3-minimal/.keep\", content: \"\" }],\n\t},\n\t{\n\t\tname: \"nodejs\",\n\t\tversion: \"18.19.0+dfsg-6\",\n\t\tsection: \"javascript\",\n\t\tdescription: \"Evented I/O for V8 javascript - runtime executable\",\n\t\tshortDesc: \"Node.js JavaScript runtime\",\n\t\tinstalledSizeKb: 15360,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/node\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'node v18.19.0 (virtual)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/nodejs\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec node \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/share/doc/nodejs/README\",\n\t\t\t\tcontent: \"Node.js virtual package.\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"npm\",\n\t\tversion: \"9.2.0~ds1-2\",\n\t\tsection: \"javascript\",\n\t\tdescription: \"package manager for Node.js\",\n\t\tshortDesc: \"package manager for Node.js\",\n\t\tinstalledSizeKb: 9814,\n\t\tdepends: [\"nodejs\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/npm\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin npm \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/npx\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin npx \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"curl\",\n\t\tversion: \"7.88.1-10+deb12u5\",\n\t\tsection: \"web\",\n\t\tdescription: \"command line tool for transferring data with URL syntax\",\n\t\tshortDesc: \"command line tool for transferring data\",\n\t\tinstalledSizeKb: 368,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/curl\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin curl \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"wget\",\n\t\tversion: \"1.21.3-1+b2\",\n\t\tsection: \"web\",\n\t\tdescription: \"Retrieves files from the web\",\n\t\tshortDesc: \"retrieves files from the web\",\n\t\tinstalledSizeKb: 952,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/wget\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin wget \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"htop\",\n\t\tversion: \"3.2.2-2\",\n\t\tsection: \"utils\",\n\t\tdescription: \"interactive processes viewer\",\n\t\tshortDesc: \"interactive process viewer\",\n\t\tinstalledSizeKb: 412,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/htop\",\n\t\t\t\tcontent: \"#!/bin/sh\\nexec builtin htop\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"openssh-client\",\n\t\tversion: \"1:9.2p1-2+deb12u2\",\n\t\tsection: \"net\",\n\t\tdescription: \"Secure Shell (SSH) client\",\n\t\tshortDesc: \"secure shell (SSH) client\",\n\t\tinstalledSizeKb: 4540,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/ssh\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'ssh: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/ssh-keygen\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'ssh-keygen: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/etc/ssh/ssh_config\",\n\t\t\t\tcontent: \"Host *\\n StrictHostKeyChecking ask\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"openssh-server\",\n\t\tversion: \"1:9.2p1-2+deb12u2\",\n\t\tsection: \"net\",\n\t\tdescription: \"Secure Shell server (sshd)\",\n\t\tshortDesc: \"secure shell server\",\n\t\tinstalledSizeKb: 1732,\n\t\tdepends: [\"openssh-client\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/sbin/sshd\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'sshd: virtual \u2014 server already running'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/etc/ssh/sshd_config\",\n\t\t\t\tcontent: \"Port 22\\nPermitRootLogin yes\\nPasswordAuthentication yes\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"net-tools\",\n\t\tversion: \"2.10-0.1\",\n\t\tsection: \"net\",\n\t\tdescription: \"NET-3 networking toolkit (ifconfig, netstat, route)\",\n\t\tshortDesc: \"networking toolkit\",\n\t\tinstalledSizeKb: 988,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/ifconfig\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500'\\necho ' inet 10.0.0.2 netmask 255.255.255.0 broadcast 10.0.0.255'\\necho ' ether 02:42:0a:00:00:02 txqueuelen 0 (Ethernet)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/netstat\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'Active Internet connections (only servers)'\\necho 'Proto Recv-Q Send-Q Local Address Foreign Address State'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/route\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'Kernel IP routing table'\\necho 'Destination Gateway Genmask Flags Metric Ref Use Iface'\\necho '0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth0'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"iputils-ping\",\n\t\tversion: \"3:20221126-1\",\n\t\tsection: \"net\",\n\t\tdescription: \"Tools to test the reachability of network hosts\",\n\t\tshortDesc: \"test reachability of network hosts\",\n\t\tinstalledSizeKb: 164,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/ping\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin ping \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"jq\",\n\t\tversion: \"1.6-2.1\",\n\t\tsection: \"utils\",\n\t\tdescription: \"Lightweight and flexible command-line JSON processor\",\n\t\tshortDesc: \"command-line JSON processor\",\n\t\tinstalledSizeKb: 296,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/jq\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'jq: virtual stub \u2014 pipe JSON here'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"build-essential\",\n\t\tversion: \"12.9\",\n\t\tsection: \"devel\",\n\t\tdescription: \"Informational list of build-essential packages\",\n\t\tshortDesc: \"build-essential meta-package\",\n\t\tinstalledSizeKb: 12,\n\t\tdepends: [\"gcc\", \"g++\", \"make\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/share/doc/build-essential/README\",\n\t\t\t\tcontent: \"Build-essential virtual meta-package.\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"gcc\",\n\t\tversion: \"4:12.2.0-3\",\n\t\tsection: \"devel\",\n\t\tdescription: \"GNU C compiler\",\n\t\tshortDesc: \"GNU C compiler\",\n\t\tinstalledSizeKb: 24448,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/gcc\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'gcc (Fortune GNU/Linux) 12.2.0 (virtual)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/gcc-12\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec gcc \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"g++\",\n\t\tversion: \"4:12.2.0-3\",\n\t\tsection: \"devel\",\n\t\tdescription: \"GNU C++ compiler\",\n\t\tshortDesc: \"GNU C++ compiler\",\n\t\tinstalledSizeKb: 1024,\n\t\tdepends: [\"gcc\"],\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/g++\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'g++ (Fortune GNU/Linux) 12.2.0 (virtual)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"make\",\n\t\tversion: \"4.3-4.1\",\n\t\tsection: \"devel\",\n\t\tdescription: \"Utility for directing compilation\",\n\t\tshortDesc: \"build utility\",\n\t\tinstalledSizeKb: 504,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/make\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'make: *** No targets specified and no makefile found. Stop.'\\nexit 2\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"less\",\n\t\tversion: \"590-2\",\n\t\tsection: \"text\",\n\t\tdescription: \"Pager program similar to more\",\n\t\tshortDesc: \"pager program\",\n\t\tinstalledSizeKb: 328,\n\t\tfiles: [\n\t\t\t{ path: \"/usr/bin/less\", content: '#!/bin/sh\\ncat \"$@\"\\n', mode: 0o755 },\n\t\t],\n\t},\n\t{\n\t\tname: \"unzip\",\n\t\tversion: \"6.0-28\",\n\t\tsection: \"utils\",\n\t\tdescription: \"De-archiver for .zip files\",\n\t\tshortDesc: \"de-archiver for .zip files\",\n\t\tinstalledSizeKb: 464,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/unzip\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'unzip: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"rsync\",\n\t\tversion: \"3.2.7-1\",\n\t\tsection: \"net\",\n\t\tdescription: \"Fast, versatile, remote (and local) file-copying tool\",\n\t\tshortDesc: \"fast remote file copy program\",\n\t\tinstalledSizeKb: 716,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/rsync\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'rsync: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"tmux\",\n\t\tversion: \"3.3a-3\",\n\t\tsection: \"utils\",\n\t\tdescription: \"Terminal multiplexer\",\n\t\tshortDesc: \"terminal multiplexer\",\n\t\tinstalledSizeKb: 812,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/tmux\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'tmux: terminal multiplexer (virtual stub)'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"tree\",\n\t\tversion: \"2.1.0-1\",\n\t\tsection: \"utils\",\n\t\tdescription: \"Displays an indented directory tree, in color\",\n\t\tshortDesc: \"list files in tree format\",\n\t\tinstalledSizeKb: 108,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/tree\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin tree \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"ca-certificates\",\n\t\tversion: \"20230311\",\n\t\tsection: \"misc\",\n\t\tdescription: \"Common CA certificates\",\n\t\tshortDesc: \"common CA certificates\",\n\t\tinstalledSizeKb: 388,\n\t\tfiles: [\n\t\t\t{ path: \"/etc/ssl/certs/.keep\", content: \"\" },\n\t\t\t{ path: \"/etc/ssl/private/.keep\", content: \"\" },\n\t\t\t{ path: \"/usr/share/ca-certificates/.keep\", content: \"\" },\n\t\t],\n\t\tonInstall: (vfs) => {\n\t\t\tif (!vfs.exists(\"/etc/ssl\")) vfs.mkdir(\"/etc/ssl\", 0o755);\n\t\t\tif (!vfs.exists(\"/etc/ssl/certs\")) vfs.mkdir(\"/etc/ssl/certs\", 0o755);\n\t\t},\n\t},\n\t{\n\t\tname: \"locales\",\n\t\tversion: \"2.36-9+deb12u3\",\n\t\tsection: \"localization\",\n\t\tdescription: \"GNU C Library: National Language (locale) data\",\n\t\tshortDesc: \"locale data\",\n\t\tinstalledSizeKb: 16484,\n\t\tfiles: [\n\t\t\t{ path: \"/etc/locale.gen\", content: \"en_US.UTF-8 UTF-8\\n\" },\n\t\t\t{\n\t\t\t\tpath: \"/etc/default/locale\",\n\t\t\t\tcontent: \"LANG=en_US.UTF-8\\nLANGUAGE=en_US:en\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"sudo\",\n\t\tversion: \"1.9.13p3-1+deb12u1\",\n\t\tsection: \"admin\",\n\t\tdescription: \"Provide limited super user privileges to specific users\",\n\t\tshortDesc: \"super user privilege execution\",\n\t\tinstalledSizeKb: 2304,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/sudo\",\n\t\t\t\tcontent: '#!/bin/sh\\nexec builtin sudo \"$@\"\\n',\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/etc/sudoers\",\n\t\t\t\tcontent: \"root ALL=(ALL:ALL) ALL\\n%sudo ALL=(ALL:ALL) ALL\\n\",\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: \"systemd\",\n\t\tversion: \"252.22-1~deb12u1\",\n\t\tsection: \"admin\",\n\t\tdescription: \"System and service manager\",\n\t\tshortDesc: \"system and service manager\",\n\t\tinstalledSizeKb: 26624,\n\t\tfiles: [\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/systemctl\",\n\t\t\t\tcontent:\n\t\t\t\t\t\"#!/bin/sh\\necho 'systemd is not running in this virtual container.'\\nexit 1\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: \"/usr/bin/journalctl\",\n\t\t\t\tcontent: \"#!/bin/sh\\necho 'journalctl: virtual stub'\\n\",\n\t\t\t\tmode: 0o755,\n\t\t\t},\n\t\t],\n\t},\n];\n\n/**\n * Pure-TypeScript APT/dpkg package manager backed by a built-in registry.\n *\n * Accessed via `shell.packageManager` \u2014 not constructed directly.\n *\n * `install()` resolves dependencies recursively, writes declared files to the\n * VFS, runs `onInstall` hooks, and persists state to `/var/lib/dpkg/status`.\n * `remove()` reverses the process. All state survives VFS snapshot round-trips.\n *\n * @example\n * ```ts\n * const pm = shell.packageManager;\n * pm.install([\"vim\", \"git\"]);\n * console.log(pm.isInstalled(\"vim\")); // true\n * console.log(pm.installedCount()); // 2\n * ```\n */\nexport class VirtualPackageManager {\n\tprivate readonly installed = new Map<string, InstalledPackage>();\n\tprivate readonly registryPath = \"/var/lib/dpkg/status\";\n\tprivate readonly logPath = \"/var/log/dpkg.log\";\n\tprivate readonly aptLogPath = \"/var/log/apt/history.log\";\n\n\t/**\n\t * @param vfs Backing virtual filesystem for file I/O and dpkg status persistence.\n\t * @param users User manager reference passed to `onInstall` hooks.\n\t */\n\tconstructor(\n\t\tprivate readonly vfs: VirtualFileSystem,\n\t\tprivate readonly users: VirtualUserManager,\n\t) {}\n\n\t/**\n\t * Loads installed package state from `/var/lib/dpkg/status` in the VFS.\n\t *\n\t * Called automatically by `VirtualShell` after `bootstrapLinuxRootfs`.\n\t * Safe to call again to reload state after a snapshot restore.\n\t */\n\tpublic load(): void {\n\t\tif (!this.vfs.exists(this.registryPath)) return;\n\t\tconst status = this.vfs.readFile(this.registryPath);\n\t\tif (!status.trim()) return;\n\n\t\tconst blocks = status.split(/\\n\\n+/);\n\t\tfor (const block of blocks) {\n\t\t\tif (!block.trim()) continue;\n\t\t\tconst fields = this.parseFields(block);\n\t\t\tconst name = fields.Package;\n\t\t\tif (!name) continue;\n\t\t\tthis.installed.set(name, {\n\t\t\t\tname,\n\t\t\t\tversion: fields.Version ?? \"unknown\",\n\t\t\t\tarchitecture: fields.Architecture ?? \"amd64\",\n\t\t\t\tmaintainer: fields.Maintainer ?? \"Fortune Maintainers\",\n\t\t\t\tdescription: fields.Description ?? \"\",\n\t\t\t\tsection: fields.Section ?? \"misc\",\n\t\t\t\tinstalledSizeKb: Number(fields[\"Installed-Size\"] ?? 0),\n\t\t\t\tinstalledAt: fields[\"X-Installed-At\"] ?? new Date().toISOString(),\n\t\t\t\tfiles: (fields[\"X-Files\"] ?? \"\").split(\"|\").filter(Boolean),\n\t\t\t});\n\t\t}\n\t}\n\n\t/** Persist installed state to /var/lib/dpkg/status. */\n\tprivate persist(): void {\n\t\tconst blocks: string[] = [];\n\t\tfor (const pkg of this.installed.values()) {\n\t\t\tblocks.push(\n\t\t\t\t[\n\t\t\t\t\t`Package: ${pkg.name}`,\n\t\t\t\t\t`Status: install ok installed`,\n\t\t\t\t\t`Priority: optional`,\n\t\t\t\t\t`Section: ${pkg.section}`,\n\t\t\t\t\t`Installed-Size: ${pkg.installedSizeKb}`,\n\t\t\t\t\t`Maintainer: ${pkg.maintainer}`,\n\t\t\t\t\t`Architecture: ${pkg.architecture}`,\n\t\t\t\t\t`Version: ${pkg.version}`,\n\t\t\t\t\t`Description: ${pkg.description}`,\n\t\t\t\t\t`X-Installed-At: ${pkg.installedAt}`,\n\t\t\t\t\t`X-Files: ${pkg.files.join(\"|\")}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t}\n\t\tthis.vfs.writeFile(this.registryPath, `${blocks.join(\"\\n\\n\")}\\n`);\n\t}\n\n\tprivate parseFields(block: string): Record<string, string> {\n\t\tconst result: Record<string, string> = {};\n\t\tfor (const line of block.split(\"\\n\")) {\n\t\t\tconst idx = line.indexOf(\": \");\n\t\t\tif (idx === -1) continue;\n\t\t\tresult[line.slice(0, idx)] = line.slice(idx + 2);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate log(msg: string): void {\n\t\tconst ts = new Date().toISOString().replace(\"T\", \" \").slice(0, 19);\n\t\tconst line = `${ts} ${msg}\\n`;\n\t\tconst existing = this.vfs.exists(this.logPath)\n\t\t\t? this.vfs.readFile(this.logPath)\n\t\t\t: \"\";\n\t\tthis.vfs.writeFile(this.logPath, existing + line);\n\t}\n\n\tprivate aptLog(action: string, pkgs: string[]): void {\n\t\tconst ts = new Date().toISOString();\n\t\tconst existing = this.vfs.exists(this.aptLogPath)\n\t\t\t? this.vfs.readFile(this.aptLogPath)\n\t\t\t: \"\";\n\t\tconst entry = [\n\t\t\t`Start-Date: ${ts}`,\n\t\t\t`Commandline: apt-get ${action} ${pkgs.join(\" \")}`,\n\t\t\t`${action === \"install\" ? \"Install\" : \"Remove\"}: ${pkgs.join(\", \")}`,\n\t\t\t`End-Date: ${ts}`,\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\t\tthis.vfs.writeFile(this.aptLogPath, existing + entry);\n\t}\n\n\t/**\n\t * Looks up a package definition in the built-in registry by name.\n\t *\n\t * @param name Package name (case-insensitive).\n\t * @returns The matching `PackageDefinition`, or `undefined` if not found.\n\t */\n\tpublic findInRegistry(name: string): PackageDefinition | undefined {\n\t\treturn PACKAGE_REGISTRY.find(\n\t\t\t(p) => p.name.toLowerCase() === name.toLowerCase(),\n\t\t);\n\t}\n\n\t/**\n\t * Returns all packages in the built-in registry, sorted alphabetically.\n\t *\n\t * @returns Array of `PackageDefinition` entries.\n\t */\n\tpublic listAvailable(): PackageDefinition[] {\n\t\treturn [...PACKAGE_REGISTRY].sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\t/**\n\t * Returns all currently installed packages, sorted alphabetically.\n\t *\n\t * @returns Array of `InstalledPackage` records.\n\t */\n\tpublic listInstalled(): InstalledPackage[] {\n\t\treturn [...this.installed.values()].sort((a, b) =>\n\t\t\ta.name.localeCompare(b.name),\n\t\t);\n\t}\n\n\t/**\n\t * Returns `true` when the given package is currently installed.\n\t *\n\t * @param name Package name (case-insensitive).\n\t */\n\tpublic isInstalled(name: string): boolean {\n\t\treturn this.installed.has(name.toLowerCase());\n\t}\n\n\t/**\n\t * Returns the total number of installed packages.\n\t *\n\t * Used by `neofetch` to populate the `Packages:` field.\n\t */\n\tpublic installedCount(): number {\n\t\treturn this.installed.size;\n\t}\n\n\t/**\n\t * Installs one or more packages from the registry.\n\t *\n\t * Dependencies listed in `PackageDefinition.depends` are resolved and\n\t * installed automatically. Already-installed packages are skipped. Files\n\t * declared in `PackageDefinition.files` are written to the VFS and\n\t * `onInstall` hooks are called in dependency order.\n\t *\n\t * @param names Package names to install.\n\t * @param opts Installation options.\n\t * @param opts.quiet Suppress progress output lines when `true`.\n\t * @returns Terminal-style `output` string and an APT-compatible `exitCode`\n\t * (`0` on success, `100` when a package is not found).\n\t */\n\tpublic install(\n\t\tnames: string[],\n\t\topts: { quiet?: boolean } = {},\n\t): { output: string; exitCode: number } {\n\t\tconst lines: string[] = [];\n\t\tconst toInstall: PackageDefinition[] = [];\n\t\tconst notFound: string[] = [];\n\n\t\t// Resolve + deduplicate including deps\n\t\tconst resolve = (name: string, seen = new Set<string>()): void => {\n\t\t\tif (seen.has(name)) return;\n\t\t\tseen.add(name);\n\t\t\tif (this.isInstalled(name)) return;\n\t\t\tconst def = this.findInRegistry(name);\n\t\t\tif (!def) {\n\t\t\t\tnotFound.push(name);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const dep of def.depends ?? []) resolve(dep, seen);\n\t\t\tif (!toInstall.find((p) => p.name === def.name)) {\n\t\t\t\ttoInstall.push(def);\n\t\t\t}\n\t\t};\n\n\t\tfor (const n of names) resolve(n);\n\n\t\tif (notFound.length > 0) {\n\t\t\treturn {\n\t\t\t\toutput: `E: Unable to locate package ${notFound.join(\", \")}`,\n\t\t\t\texitCode: 100,\n\t\t\t};\n\t\t}\n\n\t\tif (toInstall.length === 0) {\n\t\t\treturn {\n\t\t\t\toutput: names\n\t\t\t\t\t.map((n) => `${n} is already the newest version.`)\n\t\t\t\t\t.join(\"\\n\"),\n\t\t\t\texitCode: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst totalKb = toInstall.reduce(\n\t\t\t(acc, p) => acc + (p.installedSizeKb ?? 0),\n\t\t\t0,\n\t\t);\n\n\t\tif (!opts.quiet) {\n\t\t\tlines.push(\n\t\t\t\t`Reading package lists... Done`,\n\t\t\t\t`Building dependency tree... Done`,\n\t\t\t\t`Reading state information... Done`,\n\t\t\t\t`The following NEW packages will be installed:`,\n\t\t\t\t` ${toInstall.map((p) => p.name).join(\" \")}`,\n\t\t\t\t`0 upgraded, ${toInstall.length} newly installed, 0 to remove and 0 not upgraded.`,\n\t\t\t\t`Need to get 0 B/${totalKb} kB of archives.`,\n\t\t\t\t`After this operation, ${totalKb} kB of additional disk space will be used.`,\n\t\t\t\t``,\n\t\t\t);\n\t\t}\n\n\t\tfor (const def of toInstall) {\n\t\t\tif (!opts.quiet) {\n\t\t\t\tlines.push(`Selecting previously unselected package ${def.name}.`);\n\t\t\t\tlines.push(\n\t\t\t\t\t`(Reading database ... 12345 files and directories currently installed.)`,\n\t\t\t\t);\n\t\t\t\tlines.push(\n\t\t\t\t\t`Preparing to unpack .../archives/${def.name}_${def.version}_amd64.deb ...`,\n\t\t\t\t);\n\t\t\t\tlines.push(`Unpacking ${def.name} (${def.version}) ...`);\n\t\t\t}\n\n\t\t\t// Write files\n\t\t\tfor (const f of def.files ?? []) {\n\t\t\t\tconst dir = f.path.slice(0, f.path.lastIndexOf(\"/\"));\n\t\t\t\tif (dir && !this.vfs.exists(dir)) this.vfs.mkdir(dir, 0o755);\n\t\t\t\tthis.vfs.writeFile(f.path, f.content, { mode: f.mode ?? 0o644 });\n\t\t\t}\n\n\t\t\t// Run install hook\n\t\t\tdef.onInstall?.(this.vfs, this.users);\n\n\t\t\tif (!opts.quiet) {\n\t\t\t\tlines.push(`Setting up ${def.name} (${def.version}) ...`);\n\t\t\t}\n\n\t\t\tconst now = new Date().toISOString();\n\t\t\tthis.installed.set(def.name, {\n\t\t\t\tname: def.name,\n\t\t\t\tversion: def.version,\n\t\t\t\tarchitecture: def.architecture ?? \"amd64\",\n\t\t\t\tmaintainer: def.maintainer ?? \"Fortune Maintainers <pkg@fortune.local>\",\n\t\t\t\tdescription: def.description,\n\t\t\t\tsection: def.section ?? \"misc\",\n\t\t\t\tinstalledSizeKb: def.installedSizeKb ?? 0,\n\t\t\t\tinstalledAt: now,\n\t\t\t\tfiles: (def.files ?? []).map((f) => f.path),\n\t\t\t});\n\n\t\t\tthis.log(`install ${def.name} ${def.version}`);\n\t\t}\n\n\t\tthis.aptLog(\n\t\t\t\"install\",\n\t\t\ttoInstall.map((p) => p.name),\n\t\t);\n\t\tthis.persist();\n\n\t\tif (!opts.quiet) {\n\t\t\tlines.push(`Processing triggers for man-db (2.11.2-2) ...`);\n\t\t}\n\n\t\treturn { output: lines.join(\"\\n\"), exitCode: 0 };\n\t}\n\n\t/**\n\t * Removes one or more installed packages.\n\t *\n\t * Package files are deleted from the VFS. Config files (paths under\n\t * `/etc/` or ending in `.conf`) are preserved unless `opts.purge` is set.\n\t * The `onRemove` hook is called for each package.\n\t *\n\t * @param names Package names to remove.\n\t * @param opts Removal options.\n\t * @param opts.purge Also delete configuration files when `true`.\n\t * @param opts.quiet Suppress progress output lines when `true`.\n\t * @returns Terminal-style `output` string and exit code (`0` on success).\n\t */\n\tpublic remove(\n\t\tnames: string[],\n\t\topts: { purge?: boolean; quiet?: boolean } = {},\n\t): { output: string; exitCode: number } {\n\t\tconst lines: string[] = [];\n\t\tconst toRemove: InstalledPackage[] = [];\n\n\t\tfor (const name of names) {\n\t\t\tconst pkg = this.installed.get(name.toLowerCase());\n\t\t\tif (!pkg) {\n\t\t\t\tlines.push(`Package '${name}' is not installed, so not removed`);\n\t\t\t} else {\n\t\t\t\ttoRemove.push(pkg);\n\t\t\t}\n\t\t}\n\n\t\tif (toRemove.length === 0) {\n\t\t\treturn { output: lines.join(\"\\n\") || \"Nothing to remove.\", exitCode: 0 };\n\t\t}\n\n\t\tif (!opts.quiet) {\n\t\t\tlines.push(\n\t\t\t\t`Reading package lists... Done`,\n\t\t\t\t`Building dependency tree... Done`,\n\t\t\t\t`The following packages will be REMOVED:`,\n\t\t\t\t` ${toRemove.map((p) => p.name).join(\" \")}`,\n\t\t\t\t`0 upgraded, 0 newly installed, ${toRemove.length} to remove and 0 not upgraded.`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const pkg of toRemove) {\n\t\t\tif (!opts.quiet) lines.push(`Removing ${pkg.name} (${pkg.version}) ...`);\n\n\t\t\t// Remove files (if purge, include config files)\n\t\t\tfor (const filePath of pkg.files) {\n\t\t\t\tif (\n\t\t\t\t\t!opts.purge &&\n\t\t\t\t\t(filePath.startsWith(\"/etc/\") || filePath.endsWith(\".conf\"))\n\t\t\t\t) {\n\t\t\t\t\tcontinue; // keep config unless --purge\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tif (this.vfs.exists(filePath)) this.vfs.remove(filePath);\n\t\t\t\t} catch {}\n\t\t\t}\n\n\t\t\t// Run remove hook\n\t\t\tconst def = this.findInRegistry(pkg.name);\n\t\t\tdef?.onRemove?.(this.vfs);\n\n\t\t\tthis.installed.delete(pkg.name);\n\t\t\tthis.log(`remove ${pkg.name} ${pkg.version}`);\n\t\t}\n\n\t\tthis.aptLog(\n\t\t\t\"remove\",\n\t\t\ttoRemove.map((p) => p.name),\n\t\t);\n\t\tthis.persist();\n\n\t\treturn { output: lines.join(\"\\n\"), exitCode: 0 };\n\t}\n\n\t/**\n\t * Searches the registry for packages whose name or description contains\n\t * the given term (case-insensitive). Equivalent to `apt-cache search`.\n\t *\n\t * @param term Search string.\n\t * @returns Matching `PackageDefinition` entries sorted alphabetically.\n\t */\n\tpublic search(term: string): PackageDefinition[] {\n\t\tconst t = term.toLowerCase();\n\t\treturn PACKAGE_REGISTRY.filter(\n\t\t\t(p) =>\n\t\t\t\tp.name.includes(t) ||\n\t\t\t\tp.description.toLowerCase().includes(t) ||\n\t\t\t\t(p.shortDesc ?? \"\").toLowerCase().includes(t),\n\t\t).sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\t/**\n\t * Returns a dpkg-style metadata block for a package, including its\n\t * install status. Equivalent to `apt-cache show` / `dpkg -s`.\n\t *\n\t * @param name Package name.\n\t * @returns Multi-line metadata string, or `null` if not in the registry.\n\t */\n\tpublic show(name: string): string | null {\n\t\tconst def = this.findInRegistry(name);\n\t\tif (!def) return null;\n\t\tconst inst = this.installed.get(name);\n\t\treturn [\n\t\t\t`Package: ${def.name}`,\n\t\t\t`Version: ${def.version}`,\n\t\t\t`Architecture: ${def.architecture ?? \"amd64\"}`,\n\t\t\t`Maintainer: ${def.maintainer ?? \"Fortune Maintainers <pkg@fortune.local>\"}`,\n\t\t\t`Installed-Size: ${def.installedSizeKb ?? 0}`,\n\t\t\t`Depends: ${(def.depends ?? []).join(\", \") || \"(none)\"}`,\n\t\t\t`Section: ${def.section ?? \"misc\"}`,\n\t\t\t`Priority: optional`,\n\t\t\t`Description: ${def.description}`,\n\t\t\t`Status: ${inst ? \"install ok installed\" : \"install ok not-installed\"}`,\n\t\t].join(\"\\n\");\n\t}\n}\n", "import { createHash, randomBytes, randomUUID, scryptSync } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport * as path from \"node:path\";\nimport type { PerfLogger } from \"../utils/perfLogger\";\nimport { createPerfLogger } from \"../utils/perfLogger\";\nimport type VirtualFileSystem from \"../VirtualFileSystem\";\n\n/** Persisted virtual user credential record. */\nexport interface VirtualUserRecord {\n\t/** Unique login name. */\n\tusername: string;\n\t/** Per-user random salt used for password hashing. */\n\tsalt: string;\n\t/** Scrypt-derived password hash in hex encoding. */\n\tpasswordHash: string;\n}\n\n/** Runtime representation of authenticated SSH session. */\nexport interface VirtualActiveSession {\n\t/** Stable session identifier (UUID). */\n\tid: string;\n\t/** Username bound to session. */\n\tusername: string;\n\t/** Virtual terminal identifier (pts/*). */\n\ttty: string;\n\t/** Remote client IP or host label. */\n\tremoteAddress: string;\n\t/** ISO-8601 start timestamp. */\n\tstartedAt: string;\n}\n\nfunction resolveFastPasswordHash(): boolean {\n\tconst configured = process.env.SSH_MIMIC_FAST_PASSWORD_HASH;\n\treturn (\n\t\t!!configured &&\n\t\t![\"0\", \"false\", \"no\", \"off\"].includes(configured.toLowerCase())\n\t);\n}\n\nconst perf: PerfLogger = createPerfLogger(\"VirtualUserManager\");\n\n/**\n * Persistent user, sudoers, and active-session manager for the shell runtime.\n *\n * Passwords are hashed with scrypt by default and stored in the backing virtual filesystem.\n */\nexport class VirtualUserManager extends EventEmitter {\n\tprivate static readonly recordCache = new Map<string, VirtualUserRecord>();\n\tprivate static readonly fastPasswordHash = resolveFastPasswordHash();\n\tprivate readonly usersPath = \"/virtual-env-js/.auth/htpasswd\";\n\tprivate readonly sudoersPath = \"/virtual-env-js/.auth/sudoers\";\n\tprivate readonly quotasPath = \"/virtual-env-js/.auth/quotas\";\n\tprivate readonly authDirPath = \"/virtual-env-js/.auth\";\n\tprivate readonly users = new Map<string, VirtualUserRecord>();\n\tprivate readonly sudoers = new Set<string>();\n\tprivate readonly quotas = new Map<string, number>();\n\tprivate readonly activeSessions = new Map<string, VirtualActiveSession>();\n\tprivate nextTty = 0;\n\n\t/**\n\t * Creates a user manager instance backed by a virtual filesystem.\n\t *\n\t * @param vfs Backing virtual filesystem used for persistence.\n\t * @param defaultRootPassword Initial root password used when root is created.\n\t * @param autoSudoForNewUsers Whether newly created users are added to sudoers.\n\t */\n\tconstructor(\n\t\tprivate readonly vfs: VirtualFileSystem,\n\t\t// private readonly defaultRootPassword: string = process.env\n\t\t// .SSH_MIMIC_ROOT_PASSWORD || \"root\",\n\t\tprivate readonly autoSudoForNewUsers: boolean = true,\n\t) {\n\t\tsuper();\n\t\tperf.mark(\"constructor\");\n\t}\n\n\t/**\n\t * Loads users/sudoers from disk and ensures root account exists.\n\t * Also creates the current system user if not already present.\n\t */\n\tpublic async initialize(): Promise<void> {\n\t\tperf.mark(\"initialize\");\n\t\tthis.loadFromVfs();\n\t\tthis.loadSudoersFromVfs();\n\t\tthis.loadQuotasFromVfs();\n\n\t\tlet changed = false;\n\t\tif (!this.users.has(\"root\")) {\n\t\t\tthis.users.set(\"root\", this.createRecord(\"root\", \"\"));\n\t\t\tchanged = true;\n\t\t}\n\n\t\tthis.sudoers.add(\"root\");\n\n\t\t// Auto-create current system user for easier authentication\n\t\t// const currentUser = process.env.USER || process.env.USERNAME;\n\t\t// if (currentUser && currentUser !== \"root\" && !this.users.has(currentUser)) {\n\t\t// \tconst userPassword = this.defaultRootPassword;\n\t\t// \tthis.users.set(currentUser, this.createRecord(currentUser, userPassword));\n\t\t// \tthis.sudoers.add(currentUser);\n\t\t// \tchanged = true;\n\t\t// }\n\t\t\n\t\tconst homePath = `/home/root`;\n\t\tif (!this.vfs.exists(homePath)) {\n\t\t\tthis.vfs.mkdir(homePath, 0o755);\n\t\t\tthis.vfs.writeFile(\n\t\t\t\t`${homePath}/README.txt`,\n\t\t\t\t`Welcome to the virtual environment, root`,\n\t\t\t);\n\t\t}\n\n\t\tif (changed) {\n\t\t\tawait this.persist();\n\t\t}\n\t\tthis.emit(\"initialized\");\n\t}\n\n\t/**\n\t * Sets max allowed bytes under /home/<username>.\n\t *\n\t * @param username Target username.\n\t * @param maxBytes Quota ceiling in bytes.\n\t */\n\tpublic async setQuotaBytes(\n\t\tusername: string,\n\t\tmaxBytes: number,\n\t): Promise<void> {\n\t\tperf.mark(\"setQuotaBytes\");\n\t\tthis.validateUsername(username);\n\t\tif (!this.users.has(username)) {\n\t\t\tthrow new Error(`quota: user '${username}' does not exist`);\n\t\t}\n\n\t\tif (!Number.isFinite(maxBytes) || maxBytes < 0) {\n\t\t\tthrow new Error(\"quota: maxBytes must be a non-negative number\");\n\t\t}\n\n\t\tthis.quotas.set(username, Math.floor(maxBytes));\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Removes quota for a user.\n\t *\n\t * @param username Target username.\n\t */\n\tpublic async clearQuota(username: string): Promise<void> {\n\t\tperf.mark(\"clearQuota\");\n\t\tthis.validateUsername(username);\n\t\tthis.quotas.delete(username);\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Gets configured quota in bytes for a user.\n\t *\n\t * @param username Target username.\n\t * @returns Quota in bytes, or null when unlimited.\n\t */\n\tpublic getQuotaBytes(username: string): number | null {\n\t\tperf.mark(\"getQuotaBytes\");\n\t\treturn this.quotas.get(username) ?? null;\n\t}\n\n\t/**\n\t * Computes current usage under /home/<username>.\n\t *\n\t * @param username Target username.\n\t * @returns Current usage in bytes.\n\t */\n\tpublic getUsageBytes(username: string): number {\n\t\tperf.mark(\"getUsageBytes\");\n\t\tconst homePath = `/home/${username}`;\n\t\tif (!this.vfs.exists(homePath)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn this.vfs.getUsageBytes(homePath);\n\t}\n\n\t/**\n\t * Validates that writing file content would not exceed user quota.\n\t *\n\t * Quotas are enforced only for writes inside /home/<username>.\n\t *\n\t * @param username Authenticated user.\n\t * @param targetPath Target file path.\n\t * @param nextContent New file content.\n\t */\n\tpublic assertWriteWithinQuota(\n\t\tusername: string,\n\t\ttargetPath: string,\n\t\tnextContent: string | Buffer,\n\t): void {\n\t\tperf.mark(\"assertWriteWithinQuota\");\n\t\tconst quota = this.quotas.get(username);\n\t\tif (quota === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst normalizedPath = normalizeVfsPath(targetPath);\n\t\tconst homePath = normalizeVfsPath(`/home/${username}`);\n\t\tconst inUserHome =\n\t\t\tnormalizedPath === homePath || normalizedPath.startsWith(`${homePath}/`);\n\t\tif (!inUserHome) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentUsage = this.getUsageBytes(username);\n\t\tlet existingSize = 0;\n\t\tif (this.vfs.exists(normalizedPath)) {\n\t\t\tconst existing = this.vfs.stat(normalizedPath);\n\t\t\tif (existing.type === \"file\") {\n\t\t\t\texistingSize = existing.size;\n\t\t\t}\n\t\t}\n\n\t\tconst incomingSize = Buffer.isBuffer(nextContent)\n\t\t\t? nextContent.length\n\t\t\t: Buffer.byteLength(nextContent, \"utf8\");\n\t\tconst projectedUsage = currentUsage - existingSize + incomingSize;\n\n\t\tif (projectedUsage > quota) {\n\t\t\tthrow new Error(\n\t\t\t\t`quota exceeded for '${username}': ${projectedUsage}/${quota} bytes`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Verifies plaintext password against stored record.\n\t *\n\t * @param username User login name.\n\t * @param password Plaintext password candidate.\n\t * @returns True when credentials are valid.\n\t */\n\tpublic verifyPassword(username: string, password: string): boolean {\n\t\tperf.mark(\"verifyPassword\");\n\t\tconst record = this.users.get(username);\n\t\tif (!record) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.hashPassword(password) === record.passwordHash;\n\t}\n\n\t/**\n\t * Creates user, home directory, and sudo access entry.\n\t *\n\t * @param username New username.\n\t * @param password Initial plaintext password.\n\t */\n\tpublic async addUser(username: string, password: string): Promise<void> {\n\t\tperf.mark(\"addUser\");\n\t\tthis.validateUsername(username);\n\t\tthis.validatePassword(password);\n\n\t\tif (this.users.has(username)) {\n\t\t\treturn;\n\t\t\t// throw new Error(`adduser: user '${username}' already exists`);\n\t\t}\n\n\t\tthis.users.set(username, this.createRecord(username, password));\n\t\tif (this.autoSudoForNewUsers) {\n\t\t\tthis.sudoers.add(username);\n\t\t}\n\t\tconst homePath = `/home/${username}`;\n\t\tif (!this.vfs.exists(homePath)) {\n\t\t\tthis.vfs.mkdir(homePath, 0o755);\n\t\t\tthis.vfs.writeFile(\n\t\t\t\t`${homePath}/README.txt`,\n\t\t\t\t`Welcome to the virtual environment, ${username}`,\n\t\t\t);\n\t\t}\n\t\tawait this.persist();\n\t\tthis.emit(\"user:add\", { username });\n\t}\n\n\t/**\n\t * Retrieves stored password hash for a user, or null if user does not exist.\n\t *\n\t * @param username Target username.\n\t * @returns Password hash in hex encoding, or null when user is not found.\n\t */\n\tpublic getPasswordHash(username: string): string | null {\n\t\tperf.mark(\"getPasswordHash\");\n\t\tconst record = this.users.get(username);\n\t\treturn record ? record.passwordHash : null;\n\t}\n\n\t/**\n\t * Updates the password for an existing user account.\n\t *\n\t * @param username Username to update.\n\t * @param password New plaintext password (must be non-empty).\n\t * @throws When the user does not exist or the password is empty.\n\t */\n\tpublic async setPassword(username: string, password: string): Promise<void> {\n\t\tperf.mark(\"setPassword\");\n\t\tthis.validateUsername(username);\n\t\tthis.validatePassword(password);\n\n\t\tif (!this.users.has(username)) {\n\t\t\tthrow new Error(`passwd: user '${username}' does not exist`);\n\t\t}\n\n\t\tthis.users.set(username, this.createRecord(username, password));\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Deletes an existing non-root user account and revokes sudo access.\n\t *\n\t * @param username Username to remove.\n\t * @throws When `username` is `\"root\"` or the user does not exist.\n\t */\n\tpublic async deleteUser(username: string): Promise<void> {\n\t\tperf.mark(\"deleteUser\");\n\t\tthis.validateUsername(username);\n\n\t\tif (username === \"root\") {\n\t\t\tthrow new Error(\"deluser: cannot delete root\");\n\t\t}\n\n\t\tif (!this.users.delete(username)) {\n\t\t\tthrow new Error(`deluser: user '${username}' does not exist`);\n\t\t}\n\n\t\tthis.sudoers.delete(username);\n\n\t\tthis.emit(\"user:delete\", { username });\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Checks whether user is member of sudoers set.\n\t *\n\t * @param username Username to test.\n\t * @returns True when user can run sudo.\n\t */\n\tpublic isSudoer(username: string): boolean {\n\t\tperf.mark(\"isSudoer\");\n\t\treturn this.sudoers.has(username);\n\t}\n\n\t/**\n\t * Grants sudo privileges to an existing user.\n\t *\n\t * @param username Username to promote.\n\t * @throws When the user does not exist.\n\t */\n\tpublic async addSudoer(username: string): Promise<void> {\n\t\tperf.mark(\"addSudoer\");\n\t\tthis.validateUsername(username);\n\t\tif (!this.users.has(username)) {\n\t\t\tthrow new Error(`sudoers: user '${username}' does not exist`);\n\t\t}\n\n\t\tthis.sudoers.add(username);\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Revokes sudo privileges from a user. Root cannot be demoted.\n\t *\n\t * @param username Username to demote.\n\t * @throws When `username` is `\"root\"`.\n\t */\n\tpublic async removeSudoer(username: string): Promise<void> {\n\t\tperf.mark(\"removeSudoer\");\n\t\tthis.validateUsername(username);\n\t\tif (username === \"root\") {\n\t\t\tthrow new Error(\"sudoers: cannot remove root\");\n\t\t}\n\n\t\tthis.sudoers.delete(username);\n\t\tawait this.persist();\n\t}\n\n\t/**\n\t * Registers a new active session and allocates a virtual TTY identifier.\n\t *\n\t * Called by the SSH server when a client is authenticated. The returned\n\t * descriptor is visible in `who` output and `listActiveSessions()`.\n\t *\n\t * @param username Authenticated username bound to the session.\n\t * @param remoteAddress IP address or hostname of the connecting client.\n\t * @returns The newly created `VirtualActiveSession` descriptor.\n\t */\n\tpublic registerSession(\n\t\tusername: string,\n\t\tremoteAddress: string,\n\t): VirtualActiveSession {\n\t\tperf.mark(\"registerSession\");\n\t\tconst session: VirtualActiveSession = {\n\t\t\tid: randomUUID(),\n\t\t\tusername,\n\t\t\ttty: `pts/${this.nextTty++}`,\n\t\t\tremoteAddress,\n\t\t\tstartedAt: new Date().toISOString(),\n\t\t};\n\t\tthis.activeSessions.set(session.id, session);\n\t\tthis.emit(\"session:register\", {\n\t\t\tsessionId: session.id,\n\t\t\tusername,\n\t\t\tremoteAddress,\n\t\t});\n\t\treturn session;\n\t}\n\n\t/**\n\t * Removes an active session record when the connection closes.\n\t *\n\t * Safe to call with a `null` or `undefined` session ID \u2014 it will be a no-op.\n\t *\n\t * @param sessionId Session UUID returned by `registerSession()`, or nullish.\n\t */\n\tpublic unregisterSession(sessionId: string | null | undefined): void {\n\t\tperf.mark(\"unregisterSession\");\n\t\tif (!sessionId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst session = this.activeSessions.get(sessionId);\n\t\tthis.activeSessions.delete(sessionId);\n\t\tif (session) {\n\t\t\tthis.emit(\"session:unregister\", {\n\t\t\t\tsessionId,\n\t\t\t\tusername: session.username,\n\t\t\t});\n\t\t}\n\t\tthis.activeSessions.delete(sessionId);\n\t}\n\n\t/**\n\t * Updates the username and remote address metadata for an active session.\n\t *\n\t * Called internally by `su` and `sudo` when the effective user changes\n\t * within a session. Silently ignored when the session ID is nullish or\n\t * unknown.\n\t *\n\t * @param sessionId Session UUID to update, or nullish for no-op.\n\t * @param username New effective username.\n\t * @param remoteAddress New remote address (usually unchanged).\n\t */\n\tpublic updateSession(\n\t\tsessionId: string | null | undefined,\n\t\tusername: string,\n\t\tremoteAddress: string,\n\t): void {\n\t\tperf.mark(\"updateSession\");\n\t\tif (!sessionId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst session = this.activeSessions.get(sessionId);\n\t\tif (!session) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.activeSessions.set(sessionId, {\n\t\t\t...session,\n\t\t\tusername,\n\t\t\tremoteAddress,\n\t\t});\n\t}\n\n\t/**\n\t * Returns a snapshot of all currently active sessions, sorted by start time.\n\t *\n\t * Used by `who`, `ps`, `uptime`, and the `HoneyPot` auditor.\n\t *\n\t * @returns Array of `VirtualActiveSession` descriptors.\n\t */\n\tpublic listActiveSessions(): VirtualActiveSession[] {\n\t\tperf.mark(\"listActiveSessions\");\n\t\treturn Array.from(this.activeSessions.values()).sort((left, right) =>\n\t\t\tleft.startedAt.localeCompare(right.startedAt),\n\t\t);\n\t}\n\n\t/**\n\t * Returns a sorted list of all registered usernames.\n\t *\n\t * @returns Array of username strings sorted alphabetically.\n\t */\n\tpublic listUsers(): string[] {\n\t\treturn Array.from(this.users.keys()).sort();\n\t}\n\n\tprivate loadFromVfs(): void {\n\t\tthis.users.clear();\n\n\t\tif (!this.vfs.exists(this.usersPath)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst raw = this.vfs.readFile(this.usersPath);\n\t\tfor (const line of raw.split(\"\\n\")) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (trimmed.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst parts = trimmed.split(\":\");\n\t\t\tif (parts.length < 3) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst [username, salt, passwordHash] = parts;\n\t\t\tif (!username || !salt || !passwordHash) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis.users.set(username, { username, salt, passwordHash });\n\t\t}\n\t}\n\n\tprivate loadSudoersFromVfs(): void {\n\t\tthis.sudoers.clear();\n\n\t\tif (!this.vfs.exists(this.sudoersPath)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst raw = this.vfs.readFile(this.sudoersPath);\n\t\tfor (const line of raw.split(\"\\n\")) {\n\t\t\tconst username = line.trim();\n\t\t\tif (username.length > 0) {\n\t\t\t\tthis.sudoers.add(username);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate loadQuotasFromVfs(): void {\n\t\tthis.quotas.clear();\n\n\t\tif (!this.vfs.exists(this.quotasPath)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst raw = this.vfs.readFile(this.quotasPath);\n\t\tfor (const line of raw.split(\"\\n\")) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (trimmed.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst [username, value] = trimmed.split(\":\");\n\t\t\tconst bytes = Number.parseInt(value ?? \"\", 10);\n\t\t\tif (!username || !Number.isFinite(bytes) || bytes < 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis.quotas.set(username, bytes);\n\t\t}\n\t}\n\n\tprivate async persist(): Promise<void> {\n\t\tif (!this.vfs.exists(this.authDirPath)) {\n\t\t\tthis.vfs.mkdir(this.authDirPath, 0o700);\n\t\t}\n\n\t\tconst authContent = Array.from(this.users.values())\n\t\t\t.sort((left, right) => left.username.localeCompare(right.username))\n\t\t\t.map((record) =>\n\t\t\t\t[record.username, record.salt, record.passwordHash].join(\":\"),\n\t\t\t)\n\t\t\t.join(\"\\n\");\n\t\tconst sudoersContent = Array.from(this.sudoers.values()).sort().join(\"\\n\");\n\t\tconst quotasContent = Array.from(this.quotas.entries())\n\t\t\t.sort(([left], [right]) => left.localeCompare(right))\n\t\t\t.map(([username, maxBytes]) => `${username}:${maxBytes}`)\n\t\t\t.join(\"\\n\");\n\n\t\tlet changed = false;\n\t\tchanged =\n\t\t\tthis.writeIfChanged(\n\t\t\t\tthis.usersPath,\n\t\t\t\tauthContent.length > 0 ? `${authContent}\\n` : \"\",\n\t\t\t\t0o600,\n\t\t\t) || changed;\n\t\tchanged =\n\t\t\tthis.writeIfChanged(\n\t\t\t\tthis.sudoersPath,\n\t\t\t\tsudoersContent.length > 0 ? `${sudoersContent}\\n` : \"\",\n\t\t\t\t0o600,\n\t\t\t) || changed;\n\t\tchanged =\n\t\t\tthis.writeIfChanged(\n\t\t\t\tthis.quotasPath,\n\t\t\t\tquotasContent.length > 0 ? `${quotasContent}\\n` : \"\",\n\t\t\t\t0o600,\n\t\t\t) || changed;\n\n\t\tif (changed) {\n\t\t\tawait this.vfs.flushMirror();\n\t\t}\n\t}\n\n\tprivate writeIfChanged(\n\t\ttargetPath: string,\n\t\tcontent: string,\n\t\tmode: number,\n\t): boolean {\n\t\tif (this.vfs.exists(targetPath)) {\n\t\t\tconst existing = this.vfs.readFile(targetPath);\n\t\t\tif (existing === content) {\n\t\t\t\tthis.vfs.chmod(targetPath, mode);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.vfs.writeFile(targetPath, content, { mode });\n\t\treturn true;\n\t}\n\n\tprivate createRecord(username: string, password: string): VirtualUserRecord {\n\t\tconst cacheKey = `${username}:${password}`;\n\t\tconst cached = VirtualUserManager.recordCache.get(cacheKey);\n\t\tif (cached) {\n\t\t\treturn cached;\n\t\t}\n\n\t\tconst salt = randomBytes(16).toString(\"hex\");\n\t\tconst record = {\n\t\t\tusername,\n\t\t\tsalt,\n\t\t\tpasswordHash: this.hashPassword(password),\n\t\t};\n\n\t\tVirtualUserManager.recordCache.set(cacheKey, record);\n\t\treturn record;\n\t}\n\n\t/**\n\t * Returns `true` when the user has a non-empty password set.\n\t *\n\t * A user with no password (or whose password hash matches the empty-string\n\t * hash) is allowed to authenticate without a credential check.\n\t *\n\t * @param username Target username.\n\t */\n\tpublic hasPassword(username: string): boolean {\n\t\tperf.mark(\"hasPassword\");\n\t\tif (this.getPasswordHash(username) === this.hashPassword(\"\")) {\n\t\t\treturn false;\n\t\t}\n\t\tconst record = this.users.get(username);\n\t\treturn !!record && !!record.passwordHash;\n\t}\n\n\t/**\n\t * Hashes a plaintext password using scrypt (or SHA-256 in fast-hash mode).\n\t *\n\t * Set `SSH_MIMIC_FAST_PASSWORD_HASH=1` to switch to SHA-256 for test\n\t * environments where scrypt latency is undesirable.\n\t *\n\t * @param password Plaintext password string.\n\t * @returns Hex-encoded hash string.\n\t */\n\tpublic hashPassword(password: string): string {\n\t\tif (VirtualUserManager.fastPasswordHash) {\n\t\t\treturn createHash(\"sha256\").update(`${password}`).digest(\"hex\");\n\t\t}\n\n\t\treturn scryptSync(password, \"\", 32).toString(\"hex\");\n\t}\n\n\tprivate validateUsername(username: string): void {\n\t\tif (!username || username.trim() === \"\") {\n\t\t\tthrow new Error(\"invalid username\");\n\t\t}\n\n\t\tif (!/^[a-z_][a-z0-9_-]{0,31}$/i.test(username)) {\n\t\t\tthrow new Error(\"invalid username\");\n\t\t}\n\t}\n\n\tprivate validatePassword(password: string): void {\n\t\tif (!password || password.trim() === \"\") {\n\t\t\tthrow new Error(\"invalid password\");\n\t\t}\n\t}\n\tprivate readonly authorizedKeys = new Map<\n\t\tstring,\n\t\tArray<{ algo: string; data: Buffer }>\n\t>();\n\n\t/**\n\t * Adds an SSH public key for a user, enabling public-key authentication.\n\t *\n\t * @param username Target user.\n\t * @param algo Key algorithm (e.g. \"ssh-rsa\", \"ssh-ed25519\").\n\t * @param data Raw key data as a Buffer (the base64-decoded key bytes).\n\t */\n\tpublic addAuthorizedKey(username: string, algo: string, data: Buffer): void {\n\t\tperf.mark(\"addAuthorizedKey\");\n\t\tconst keys = this.authorizedKeys.get(username) ?? [];\n\t\tkeys.push({ algo, data });\n\t\tthis.authorizedKeys.set(username, keys);\n\t\tthis.emit(\"key:add\", { username, algo });\n\t}\n\n\t/**\n\t * Removes all authorized keys for a user.\n\t *\n\t * @param username Target user.\n\t */\n\tpublic removeAuthorizedKeys(username: string): void {\n\t\tthis.authorizedKeys.delete(username);\n\t\tthis.emit(\"key:remove\", { username });\n\t}\n\n\t/**\n\t * Returns the list of authorized keys for a user.\n\t * Returns an empty array when no keys are registered.\n\t *\n\t * @param username Target user.\n\t */\n\tpublic getAuthorizedKeys(\n\t\tusername: string,\n\t): Array<{ algo: string; data: Buffer }> {\n\t\treturn this.authorizedKeys.get(username) ?? [];\n\t}\n}\n\nfunction normalizeVfsPath(targetPath: string): string {\n\tconst normalized = path.posix.normalize(targetPath);\n\treturn normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n", "import type { ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { readFile, unlink, writeFile } from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { ShellProperties, VirtualShell } from \".\";\nimport { getCommandNames, makeDefaultEnv, runCommand } from \"../commands\";\nimport {\n\tspawnHtopProcess,\n\tspawnNanoEditorProcess,\n} from \"../modules/shellInteractive\";\nimport {\n\tgetVisibleHtopPidList,\n\tresolvePath,\n\ttype TerminalSize,\n\ttoTtyLines,\n} from \"../modules/shellRuntime\";\nimport { buildLoginBanner } from \"../SSHMimic/loginBanner\";\nimport { buildPrompt } from \"../SSHMimic/prompt\";\nimport type { ShellEnv } from \"../types/commands\";\nimport type { ShellStream } from \"../types/streams\";\nimport type VirtualFileSystem from \"../VirtualFileSystem\";\n\ninterface NanoSession {\n\tkind: \"nano\" | \"htop\";\n\ttargetPath: string;\n\ttempPath: string;\n\tprocess: ChildProcessWithoutNullStreams;\n}\n\ninterface PendingSudo {\n\tusername: string;\n\ttargetUser: string;\n\tcommandLine: string | null;\n\tloginShell: boolean;\n\tprompt: string;\n\tbuffer: string;\n}\n\nexport function startShell(\n\tproperties: ShellProperties,\n\tstream: ShellStream,\n\tauthUser: string,\n\thostname: string,\n\tsessionId: string | null,\n\tremoteAddress = \"unknown\",\n\tterminalSize: TerminalSize = { cols: 80, rows: 24 },\n\tshell: VirtualShell,\n): void {\n\tlet lineBuffer = \"\";\n\tlet cursorPos = 0;\n\tlet history = loadHistory(shell.vfs);\n\tlet historyIndex: number | null = null;\n\tlet historyDraft = \"\";\n\tlet cwd = `/home/${authUser}`;\n\tconst shellEnv: ShellEnv = makeDefaultEnv(authUser, hostname);\n\tlet nanoSession: NanoSession | null = null;\n\tlet pendingSudo: PendingSudo | null = null;\n\tconst buildCurrentPrompt = (): string => {\n\t\tconst homePath = `/home/${authUser}`;\n\t\tconst cwdLabel = cwd === homePath ? \"~\" : path.posix.basename(cwd) || \"/\";\n\t\treturn buildPrompt(authUser, hostname, cwdLabel);\n\t};\n\tconst commandNames = Array.from(new Set(getCommandNames())).sort();\n\tconsole.log(\n\t\t`[${sessionId}] Shell started for user '${authUser}' at ${remoteAddress}`,\n\t);\n\n\t// Load .bashrc if it exists\n\tvoid (async () => {\n\t\tconst bashrcPath = `/home/${authUser}/.bashrc`;\n\t\tif (shell.vfs.exists(bashrcPath)) {\n\t\t\ttry {\n\t\t\t\tconst bashrc = shell.vfs.readFile(bashrcPath);\n\t\t\t\tfor (const line of bashrc.split(\"\\n\")) {\n\t\t\t\t\tconst l = line.trim();\n\t\t\t\t\tif (!l || l.startsWith(\"#\")) continue;\n\t\t\t\t\tawait runCommand(\n\t\t\t\t\t\tl,\n\t\t\t\t\t\tauthUser,\n\t\t\t\t\t\thostname,\n\t\t\t\t\t\t\"shell\",\n\t\t\t\t\t\tcwd,\n\t\t\t\t\t\tshell,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tshellEnv,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t/* ignore bashrc errors */\n\t\t\t}\n\t\t}\n\t})();\n\n\tfunction renderLine(): void {\n\t\tconst prompt = buildCurrentPrompt();\n\t\tstream.write(`\\r${prompt}${lineBuffer}\\u001b[K`);\n\n\t\tconst moveLeft = lineBuffer.length - cursorPos;\n\t\tif (moveLeft > 0) {\n\t\t\tstream.write(`\\u001b[${moveLeft}D`);\n\t\t}\n\t}\n\n\tfunction clearCurrentLine(): void {\n\t\tstream.write(\"\\r\\u001b[K\");\n\t}\n\n\tfunction startSudoPrompt(challenge: {\n\t\tusername: string;\n\t\ttargetUser: string;\n\t\tcommandLine: string | null;\n\t\tloginShell: boolean;\n\t\tprompt: string;\n\t}): void {\n\t\tpendingSudo = {\n\t\t\t...challenge,\n\t\t\tbuffer: \"\",\n\t\t};\n\t\tclearCurrentLine();\n\t\tstream.write(challenge.prompt);\n\t}\n\n\tasync function finishSudoPrompt(success: boolean): Promise<void> {\n\t\tif (!pendingSudo) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst challenge = pendingSudo;\n\t\tpendingSudo = null;\n\n\t\tif (!success) {\n\t\t\tstream.write(\"\\r\\nSorry, try again.\\r\\n\");\n\t\t\trenderLine();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!challenge.commandLine) {\n\t\t\tauthUser = challenge.targetUser;\n\t\t\tcwd = `/home/${authUser}`;\n\t\t\tshell.users.updateSession(sessionId, authUser, remoteAddress);\n\t\t\tstream.write(\"\\r\\n\");\n\t\t\trenderLine();\n\t\t\treturn;\n\t\t}\n\n\t\tconst runCwd = challenge.loginShell ? `/home/${challenge.targetUser}` : cwd;\n\t\tconst result = await Promise.resolve(\n\t\t\trunCommand(\n\t\t\t\tchallenge.commandLine,\n\t\t\t\tchallenge.targetUser,\n\t\t\t\thostname,\n\t\t\t\t\"shell\",\n\t\t\t\trunCwd,\n\t\t\t\tshell,\n\t\t\t),\n\t\t);\n\n\t\tstream.write(\"\\r\\n\");\n\n\t\tif (result.openEditor) {\n\t\t\tawait startNanoEditor(\n\t\t\t\tresult.openEditor.targetPath,\n\t\t\t\tresult.openEditor.initialContent,\n\t\t\t\tresult.openEditor.tempPath,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (result.openHtop) {\n\t\t\tawait startHtop();\n\t\t\treturn;\n\t\t}\n\n\t\tif (result.clearScreen) {\n\t\t\tstream.write(\"\\u001b[2J\\u001b[H\");\n\t\t}\n\n\t\tif (result.stdout) {\n\t\t\tstream.write(`${toTtyLines(result.stdout)}\\r\\n`);\n\t\t}\n\n\t\tif (result.stderr) {\n\t\t\tstream.write(`${toTtyLines(result.stderr)}\\r\\n`);\n\t\t}\n\n\t\tif (result.switchUser) {\n\t\t\tauthUser = result.switchUser;\n\t\t\tcwd = result.nextCwd ?? `/home/${authUser}`;\n\t\t\tshell.users.updateSession(sessionId, authUser, remoteAddress);\n\t\t} else if (result.nextCwd) {\n\t\t\tcwd = result.nextCwd;\n\t\t}\n\n\t\tawait shell.vfs.flushMirror();\n\t\trenderLine();\n\t}\n\n\tasync function finishNanoEditor(): Promise<void> {\n\t\tif (!nanoSession) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst activeSession = nanoSession;\n\n\t\tif (activeSession.kind === \"nano\") {\n\t\t\ttry {\n\t\t\t\tconst updatedContent = await readFile(activeSession.tempPath, \"utf8\");\n\t\t\t\tshell.writeFileAsUser(\n\t\t\t\t\tauthUser,\n\t\t\t\t\tactiveSession.targetPath,\n\t\t\t\t\tupdatedContent,\n\t\t\t\t);\n\t\t\t\tawait shell.vfs.flushMirror();\n\t\t\t} catch {\n\t\t\t\t// If temp file does not exist, nano exited without writing.\n\t\t\t}\n\n\t\t\tawait unlink(activeSession.tempPath).catch(() => undefined);\n\t\t}\n\n\t\tnanoSession = null;\n\t\tlineBuffer = \"\";\n\t\tcursorPos = 0;\n\t\tstream.write(\"\\r\\n\");\n\t\trenderLine();\n\t}\n\n\tasync function startNanoEditor(\n\t\ttargetPath: string,\n\t\tinitialContent: string,\n\t\ttempPath: string,\n\t): Promise<void> {\n\t\tif (shell.vfs.exists(targetPath)) {\n\t\t\tawait writeFile(tempPath, initialContent, \"utf8\");\n\t\t}\n\n\t\tconst editor = spawnNanoEditorProcess(tempPath, terminalSize, stream);\n\n\t\teditor.on(\"error\", (error: Error) => {\n\t\t\tstream.write(`nano: ${error.message}\\r\\n`);\n\t\t\tvoid finishNanoEditor();\n\t\t});\n\n\t\teditor.on(\"close\", () => {\n\t\t\tvoid finishNanoEditor();\n\t\t});\n\n\t\tnanoSession = {\n\t\t\tkind: \"nano\",\n\t\t\ttargetPath,\n\t\t\ttempPath,\n\t\t\tprocess: editor,\n\t\t};\n\t}\n\n\tasync function startHtop(): Promise<void> {\n\t\tconst pidList = await getVisibleHtopPidList();\n\t\tif (!pidList) {\n\t\t\tstream.write(\"htop: no child_process processes to display\\r\\n\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst monitor = spawnHtopProcess(pidList, terminalSize, stream);\n\n\t\tmonitor.on(\"error\", (error: Error) => {\n\t\t\tstream.write(`htop: ${error.message}\\r\\n`);\n\t\t\tvoid finishNanoEditor();\n\t\t});\n\n\t\tmonitor.on(\"close\", () => {\n\t\t\tvoid finishNanoEditor();\n\t\t});\n\n\t\tnanoSession = {\n\t\t\tkind: \"htop\",\n\t\t\ttargetPath: \"\",\n\t\t\ttempPath: \"\",\n\t\t\tprocess: monitor,\n\t\t};\n\t}\n\n\tfunction applyHistoryLine(nextLine: string): void {\n\t\tlineBuffer = nextLine;\n\t\tcursorPos = lineBuffer.length;\n\t\trenderLine();\n\t}\n\n\tfunction insertText(text: string): void {\n\t\tlineBuffer = `${lineBuffer.slice(0, cursorPos)}${text}${lineBuffer.slice(cursorPos)}`;\n\t\tcursorPos += text.length;\n\t\trenderLine();\n\t}\n\n\tfunction getTokenRange(\n\t\tline: string,\n\t\tcursor: number,\n\t): { start: number; end: number } {\n\t\tlet start = cursor;\n\t\twhile (start > 0 && !/\\s/.test(line[start - 1]!)) {\n\t\t\tstart -= 1;\n\t\t}\n\n\t\tlet end = cursor;\n\t\twhile (end < line.length && !/\\s/.test(line[end]!)) {\n\t\t\tend += 1;\n\t\t}\n\n\t\treturn { start, end };\n\t}\n\n\tfunction listPathCompletions(prefix: string): string[] {\n\t\tconst slashIndex = prefix.lastIndexOf(\"/\");\n\t\tconst dirPart = slashIndex >= 0 ? prefix.slice(0, slashIndex + 1) : \"\";\n\t\tconst namePart = slashIndex >= 0 ? prefix.slice(slashIndex + 1) : prefix;\n\t\tconst basePath = resolvePath(cwd, dirPart || \".\");\n\n\t\ttry {\n\t\t\treturn shell.vfs\n\t\t\t\t.list(basePath)\n\t\t\t\t.filter((entry) => !entry.startsWith(\".\"))\n\t\t\t\t.filter((entry) => entry.startsWith(namePart))\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst fullPath = path.posix.join(basePath, entry);\n\t\t\t\t\tconst st = shell.vfs.stat(fullPath);\n\t\t\t\t\tconst suffix = st.type === \"directory\" ? \"/\" : \"\";\n\t\t\t\t\treturn `${dirPart}${entry}${suffix}`;\n\t\t\t\t})\n\t\t\t\t.sort();\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tfunction handleTabCompletion(): void {\n\t\tconst { start, end } = getTokenRange(lineBuffer, cursorPos);\n\t\tconst token = lineBuffer.slice(start, cursorPos);\n\n\t\tif (token.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst firstToken = lineBuffer.slice(0, start).trim().length === 0;\n\t\tconst commandCandidates = firstToken\n\t\t\t? commandNames.filter((name) => name.startsWith(token))\n\t\t\t: [];\n\t\tconst pathCandidates = listPathCompletions(token);\n\t\tconst candidates = Array.from(\n\t\t\tnew Set([...commandCandidates, ...pathCandidates]),\n\t\t).sort();\n\n\t\tif (candidates.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (candidates.length === 1) {\n\t\t\tconst completed = candidates[0]!;\n\t\t\tconst suffix = completed.endsWith(\"/\") ? \"\" : \" \";\n\t\t\tlineBuffer = `${lineBuffer.slice(0, start)}${completed}${suffix}${lineBuffer.slice(end)}`;\n\t\t\tcursorPos = start + completed.length + suffix.length;\n\t\t\trenderLine();\n\t\t\treturn;\n\t\t}\n\n\t\tstream.write(\"\\r\\n\");\n\t\tstream.write(`${candidates.join(\" \")}\\r\\n`);\n\t\trenderLine();\n\t}\n\n\tfunction pushHistory(cmd: string): void {\n\t\tif (cmd.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\thistory.push(cmd);\n\t\tif (history.length > 500) {\n\t\t\thistory = history.slice(history.length - 500);\n\t\t}\n\n\t\tconst data = history.length > 0 ? `${history.join(\"\\n\")}\\n` : \"\";\n\t\tshell.vfs.writeFile(\"/virtual-env-js/.bash_history\", data);\n\t}\n\n\tfunction readLastLogin(): { at: string; from: string } | null {\n\t\tconst lastlogPath = `/virtual-env-js/.lastlog/${authUser}.json`;\n\t\tif (!shell.vfs.exists(lastlogPath)) {\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\treturn JSON.parse(shell.vfs.readFile(lastlogPath)) as {\n\t\t\t\tat: string;\n\t\t\t\tfrom: string;\n\t\t\t};\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tfunction writeLastLogin(nowIso: string): void {\n\t\tconst dir = \"/virtual-env-js/.lastlog\";\n\t\tif (!shell.vfs.exists(dir)) {\n\t\t\tshell.vfs.mkdir(dir, 0o700);\n\t\t}\n\n\t\tconst lastlogPath = `${dir}/${authUser}.json`;\n\t\tshell.vfs.writeFile(\n\t\t\tlastlogPath,\n\t\t\tJSON.stringify({ at: nowIso, from: remoteAddress }),\n\t\t);\n\t}\n\n\tfunction renderLoginBanner(): void {\n\t\tconst last = readLastLogin();\n\t\tconst nowIso = new Date().toISOString();\n\t\tstream.write(buildLoginBanner(hostname, properties, last));\n\t\twriteLastLogin(nowIso);\n\t}\n\n\trenderLoginBanner();\n\trenderLine();\n\n\tstream.on(\"data\", async (chunk: Buffer) => {\n\t\tif (nanoSession) {\n\t\t\tnanoSession.process.stdin.write(chunk);\n\t\t\treturn;\n\t\t}\n\n\t\tif (pendingSudo) {\n\t\t\tconst input = chunk.toString(\"utf8\");\n\n\t\t\tfor (let i = 0; i < input.length; i += 1) {\n\t\t\t\tconst ch = input[i]!;\n\n\t\t\t\tif (ch === \"\\u0003\") {\n\t\t\t\t\tpendingSudo = null;\n\t\t\t\t\tstream.write(\"^C\\r\\n\");\n\t\t\t\t\trenderLine();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (ch === \"\\u007f\" || ch === \"\\b\") {\n\t\t\t\t\tpendingSudo.buffer = pendingSudo.buffer.slice(0, -1);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (ch === \"\\r\" || ch === \"\\n\") {\n\t\t\t\t\tconst password = pendingSudo.buffer;\n\t\t\t\t\tpendingSudo.buffer = \"\";\n\t\t\t\t\tconst valid = shell.users.verifyPassword(\n\t\t\t\t\t\tpendingSudo.username,\n\t\t\t\t\t\tpassword,\n\t\t\t\t\t);\n\t\t\t\t\tawait finishSudoPrompt(valid);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (ch >= \" \") {\n\t\t\t\t\tpendingSudo.buffer += ch;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst input = chunk.toString(\"utf8\");\n\n\t\tfor (let i = 0; i < input.length; i += 1) {\n\t\t\tconst ch = input[i]!;\n\n\t\t\tif (ch === \"\\u0004\") {\n\t\t\t\tlineBuffer = \"\";\n\t\t\t\tcursorPos = 0;\n\t\t\t\thistoryIndex = null;\n\t\t\t\thistoryDraft = \"\";\n\t\t\t\tstream.write(\"bye\\r\\n\");\n\t\t\t\tpushHistory(\"bye\");\n\t\t\t\tawait shell.vfs.flushMirror();\n\t\t\t\tstream.write(\"logout\\r\\n\");\n\t\t\t\tstream.exit(0);\n\t\t\t\tstream.end();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (ch === \"\\t\") {\n\t\t\t\thandleTabCompletion();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (ch === \"\\u001b\") {\n\t\t\t\tconst next = input[i + 1];\n\t\t\t\tconst third = input[i + 2];\n\t\t\t\tconst fourth = input[i + 3];\n\n\t\t\t\tif (next === \"[\" && third) {\n\t\t\t\t\tif (third === \"A\") {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tif (history.length > 0) {\n\t\t\t\t\t\t\tif (historyIndex === null) {\n\t\t\t\t\t\t\t\thistoryDraft = lineBuffer;\n\t\t\t\t\t\t\t\thistoryIndex = history.length - 1;\n\t\t\t\t\t\t\t} else if (historyIndex > 0) {\n\t\t\t\t\t\t\t\thistoryIndex -= 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tapplyHistoryLine(history[historyIndex] ?? \"\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (third === \"B\") {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tif (historyIndex !== null) {\n\t\t\t\t\t\t\tif (historyIndex < history.length - 1) {\n\t\t\t\t\t\t\t\thistoryIndex += 1;\n\t\t\t\t\t\t\t\tapplyHistoryLine(history[historyIndex] ?? \"\");\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\thistoryIndex = null;\n\t\t\t\t\t\t\t\tapplyHistoryLine(historyDraft);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (third === \"C\") {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tif (cursorPos < lineBuffer.length) {\n\t\t\t\t\t\t\tcursorPos += 1;\n\t\t\t\t\t\t\tstream.write(\"\\u001b[C\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (third === \"D\") {\n\t\t\t\t\t\ti += 2;\n\t\t\t\t\t\tif (cursorPos > 0) {\n\t\t\t\t\t\t\tcursorPos -= 1;\n\t\t\t\t\t\t\tstream.write(\"\\u001b[D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (third === \"3\" && fourth === \"~\") {\n\t\t\t\t\t\ti += 3;\n\t\t\t\t\t\tif (cursorPos < lineBuffer.length) {\n\t\t\t\t\t\t\tlineBuffer = `${lineBuffer.slice(0, cursorPos)}${lineBuffer.slice(cursorPos + 1)}`;\n\t\t\t\t\t\t\trenderLine();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (ch === \"\\u0003\") {\n\t\t\t\tlineBuffer = \"\";\n\t\t\t\tcursorPos = 0;\n\t\t\t\thistoryIndex = null;\n\t\t\t\thistoryDraft = \"\";\n\t\t\t\tstream.write(\"^C\\r\\n\");\n\t\t\t\trenderLine();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (ch === \"\\r\" || ch === \"\\n\") {\n\t\t\t\tconst line = lineBuffer.trim();\n\t\t\t\tlineBuffer = \"\";\n\t\t\t\tcursorPos = 0;\n\t\t\t\thistoryIndex = null;\n\t\t\t\thistoryDraft = \"\";\n\t\t\t\tstream.write(\"\\r\\n\");\n\n\t\t\t\tif (line.length > 0) {\n\t\t\t\t\tconst result = await Promise.resolve(\n\t\t\t\t\t\trunCommand(\n\t\t\t\t\t\t\tline,\n\t\t\t\t\t\t\tauthUser,\n\t\t\t\t\t\t\thostname,\n\t\t\t\t\t\t\t\"shell\",\n\t\t\t\t\t\t\tcwd,\n\t\t\t\t\t\t\tshell,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tshellEnv,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\tpushHistory(line);\n\n\t\t\t\t\tif (result.openEditor) {\n\t\t\t\t\t\tawait startNanoEditor(\n\t\t\t\t\t\t\tresult.openEditor.targetPath,\n\t\t\t\t\t\t\tresult.openEditor.initialContent,\n\t\t\t\t\t\t\tresult.openEditor.tempPath,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.openHtop) {\n\t\t\t\t\t\tawait startHtop();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.sudoChallenge) {\n\t\t\t\t\t\tstartSudoPrompt(result.sudoChallenge);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.clearScreen) {\n\t\t\t\t\t\tstream.write(\"\\u001b[2J\\u001b[H\");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.stdout) {\n\t\t\t\t\t\tstream.write(`${toTtyLines(result.stdout)}\\r\\n`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.stderr) {\n\t\t\t\t\t\tstream.write(`${toTtyLines(result.stderr)}\\r\\n`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.closeSession) {\n\t\t\t\t\t\tstream.write(\"logout\\r\\n\");\n\t\t\t\t\t\tstream.exit(result.exitCode ?? 0);\n\t\t\t\t\t\tstream.end();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.nextCwd) {\n\t\t\t\t\t\tcwd = result.nextCwd;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.switchUser) {\n\t\t\t\t\t\tauthUser = result.switchUser;\n\t\t\t\t\t\tcwd = result.nextCwd ?? `/home/${authUser}`;\n\t\t\t\t\t\tshell.users.updateSession(sessionId, authUser, remoteAddress);\n\t\t\t\t\t\tlineBuffer = \"\";\n\t\t\t\t\t\tcursorPos = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait shell.vfs.flushMirror();\n\t\t\t\t}\n\n\t\t\t\trenderLine();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (ch === \"\\u007f\" || ch === \"\\b\") {\n\t\t\t\tif (cursorPos > 0) {\n\t\t\t\t\tlineBuffer = `${lineBuffer.slice(0, cursorPos - 1)}${lineBuffer.slice(cursorPos)}`;\n\t\t\t\t\tcursorPos -= 1;\n\t\t\t\t\trenderLine();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tinsertText(ch);\n\t\t}\n\t});\n\n\tstream.on(\"close\", () => {\n\t\tif (nanoSession) {\n\t\t\tnanoSession.process.kill(\"SIGTERM\");\n\t\t\tnanoSession = null;\n\t\t}\n\t});\n}\n\nfunction loadHistory(vfs: VirtualFileSystem): string[] {\n\tconst historyPath = \"/virtual-env-js/.bash_history\";\n\tif (!vfs.exists(historyPath)) {\n\t\tvfs.writeFile(historyPath, \"\");\n\t\treturn [];\n\t}\n\n\tconst raw = vfs.readFile(historyPath);\n\treturn raw\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trim())\n\t\t.filter((line) => line.length > 0);\n}\n", "import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport type { ShellStream } from \"../types/streams\";\nimport {\n\tshellQuote,\n\ttype TerminalSize,\n\twithTerminalSize,\n} from \"./shellRuntime\";\n\nfunction spawnScriptProcess(\n\tcommand: string,\n\tterminalSize: TerminalSize,\n\tstream: ShellStream,\n): ChildProcessWithoutNullStreams {\n\tconst formatted = withTerminalSize(command, terminalSize);\n\tconst proc = spawn(\"script\", [\"-qfec\", formatted, \"/dev/null\"], {\n\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t// biome-ignore lint/style/useNamingConvention: env variable should be uppercase\n\t\t\tTERM: process.env.TERM ?? \"xterm-256color\",\n\t\t},\n\t});\n\n\tproc.stdout.on(\"data\", (data: Buffer) => {\n\t\tstream.write(data.toString(\"utf8\"));\n\t});\n\n\tproc.stderr.on(\"data\", (data: Buffer) => {\n\t\tstream.write(data.toString(\"utf8\"));\n\t});\n\n\treturn proc;\n}\n\nexport function spawnNanoEditorProcess(\n\ttempPath: string,\n\tterminalSize: TerminalSize,\n\tstream: ShellStream,\n): ChildProcessWithoutNullStreams {\n\treturn spawnScriptProcess(\n\t\t`nano -- ${shellQuote(tempPath)}`,\n\t\tterminalSize,\n\t\tstream,\n\t);\n}\n\nexport function spawnHtopProcess(\n\tpidList: string,\n\tterminalSize: TerminalSize,\n\tstream: ShellStream,\n): ChildProcessWithoutNullStreams {\n\treturn spawnScriptProcess(\n\t\t`htop -p ${shellQuote(pidList)}`,\n\t\tterminalSize,\n\t\tstream,\n\t);\n}\n", "import { readFile } from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nexport interface TerminalSize {\n\tcols: number;\n\trows: number;\n}\n\nexport function shellQuote(value: string): string {\n\treturn `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nexport function toTtyLines(text: string): string {\n\treturn text\n\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t.replace(/\\r/g, \"\\n\")\n\t\t.replace(/\\n/g, \"\\r\\n\");\n}\n\nexport function withTerminalSize(\n\tcommand: string,\n\tterminalSize: TerminalSize,\n): string {\n\tconst cols =\n\t\tNumber.isFinite(terminalSize.cols) && terminalSize.cols > 0\n\t\t\t? Math.floor(terminalSize.cols)\n\t\t\t: 80;\n\tconst rows =\n\t\tNumber.isFinite(terminalSize.rows) && terminalSize.rows > 0\n\t\t\t? Math.floor(terminalSize.rows)\n\t\t\t: 24;\n\treturn `stty cols ${cols} rows ${rows} 2>/dev/null; ${command}`;\n}\n\nexport function resolvePath(base: string, inputPath: string): string {\n\tif (!inputPath || inputPath.trim() === \"\" || inputPath === \".\") {\n\t\treturn base;\n\t}\n\treturn inputPath.startsWith(\"/\")\n\t\t? path.posix.normalize(inputPath)\n\t\t: path.posix.normalize(path.posix.join(base, inputPath));\n}\n\nexport async function collectChildPids(parentPid: number): Promise<number[]> {\n\ttry {\n\t\tconst childrenRaw = await readFile(\n\t\t\t`/proc/${parentPid}/task/${parentPid}/children`,\n\t\t\t\"utf8\",\n\t\t);\n\t\tconst directChildren = childrenRaw\n\t\t\t.trim()\n\t\t\t.split(/\\s+/)\n\t\t\t.filter(Boolean)\n\t\t\t.map((value) => Number.parseInt(value, 10))\n\t\t\t.filter((pid) => Number.isInteger(pid) && pid > 0);\n\n\t\tconst nested = await Promise.all(\n\t\t\tdirectChildren.map((pid) => collectChildPids(pid)),\n\t\t);\n\t\treturn [...directChildren, ...nested.flat()];\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nexport async function getVisibleHtopPidList(\n\trootPid = process.pid,\n): Promise<string | null> {\n\tconst descendants = await collectChildPids(rootPid);\n\tconst unique = Array.from(new Set(descendants)).sort((a, b) => a - b);\n\tif (unique.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn unique.join(\",\");\n}\n"],
|
|
5
|
+
"mappings": "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AAAA;AAAA,EACT,KAAM,GACP,EACA,CAAE,KAAM,4BAA6B,QAAS,EAAG,CAClD,CACD,EACA,CACC,KAAM,kBACN,QAAS,cACT,QAAS,SACT,YAAa,oDACb,UAAW,oCACX,gBAAiB,IACjB,MAAO,CAAC,CAAE,KAAM,iCAAkC,QAAS,EAAG,CAAC,CAChE,EACA,CACC,KAAM,SACN,QAAS,iBACT,QAAS,aACT,YAAa,qDACb,UAAW,6BACX,gBAAiB,MACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,kBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,+BACN,QAAS;AAAA,CACV,CACD,CACD,EACA,CACC,KAAM,MACN,QAAS,cACT,QAAS,aACT,YAAa,8BACb,UAAW,8BACX,gBAAiB,KACjB,QAAS,CAAC,QAAQ,EAClB,MAAO,CACN,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,oBACT,QAAS,MACT,YAAa,0DACb,UAAW,0CACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,cACT,QAAS,MACT,YAAa,+BACb,UAAW,+BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,UACT,QAAS,QACT,YAAa,+BACb,UAAW,6BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,iBACN,QAAS,oBACT,QAAS,MACT,YAAa,4BACb,UAAW,4BACX,gBAAiB,KACjB,MAAO,CACN,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,sBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,sBACN,QAAS;AAAA;AAAA,CACV,CACD,CACD,EACA,CACC,KAAM,iBACN,QAAS,oBACT,QAAS,MACT,YAAa,6BACb,UAAW,sBACX,gBAAiB,KACjB,QAAS,CAAC,gBAAgB,EAC1B,MAAO,CACN,CACC,KAAM,iBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,uBACN,QAAS;AAAA;AAAA;AAAA,CACV,CACD,CACD,EACA,CACC,KAAM,YACN,QAAS,WACT,QAAS,MACT,YAAa,sDACb,UAAW,qBACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,oBACN,QACC;AAAA;AAAA;AAAA;AAAA,EACD,KAAM,GACP,EACA,CACC,KAAM,mBACN,QACC;AAAA;AAAA;AAAA,EACD,KAAM,GACP,EACA,CACC,KAAM,iBACN,QACC;AAAA;AAAA;AAAA;AAAA,EACD,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,eACN,QAAS,eACT,QAAS,MACT,YAAa,kDACb,UAAW,qCACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,KACN,QAAS,UACT,QAAS,QACT,YAAa,uDACb,UAAW,8BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,cACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,kBACN,QAAS,OACT,QAAS,QACT,YAAa,iDACb,UAAW,+BACX,gBAAiB,GACjB,QAAS,CAAC,MAAO,MAAO,MAAM,EAC9B,MAAO,CACN,CACC,KAAM,wCACN,QAAS;AAAA,CACV,CACD,CACD,EACA,CACC,KAAM,MACN,QAAS,aACT,QAAS,QACT,YAAa,iBACb,UAAW,iBACX,gBAAiB,MACjB,MAAO,CACN,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,EACA,CACC,KAAM,kBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,MACN,QAAS,aACT,QAAS,QACT,YAAa,mBACb,UAAW,mBACX,gBAAiB,KACjB,QAAS,CAAC,KAAK,EACf,MAAO,CACN,CACC,KAAM,eACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,UACT,QAAS,QACT,YAAa,oCACb,UAAW,gBACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QACC;AAAA;AAAA;AAAA,EACD,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,QACT,QAAS,OACT,YAAa,gCACb,UAAW,gBACX,gBAAiB,IACjB,MAAO,CACN,CAAE,KAAM,gBAAiB,QAAS;AAAA;AAAA,EAAyB,KAAM,GAAM,CACxE,CACD,EACA,CACC,KAAM,QACN,QAAS,SACT,QAAS,QACT,YAAa,6BACb,UAAW,6BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,iBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,QACN,QAAS,UACT,QAAS,MACT,YAAa,wDACb,UAAW,gCACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,iBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,SACT,QAAS,QACT,YAAa,uBACb,UAAW,uBACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QACC;AAAA;AAAA,EACD,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,OACN,QAAS,UACT,QAAS,QACT,YAAa,gDACb,UAAW,4BACX,gBAAiB,IACjB,MAAO,CACN,CACC,KAAM,gBACN,QAAS;AAAA;AAAA,EACT,KAAM,GACP,CACD,CACD,EACA,CACC,KAAM,kBACN,QAAS,WACT,QAAS,OACT,YAAa,yBACb,UAAW,yBACX,gBAAiB,IACjB,MAAO,CACN,CAAE,KAAM,uBAAwB,QAAS,EAAG,EAC5C,CAAE,KAAM,yBAA0B,QAAS,EAAG,EAC9C,CAAE,KAAM,mCAAoC,QAAS,EAAG,CACzD,E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",
|
|
6
|
+
"names": ["basename", "stdin", "stdout", "createInterface", "adduserCommand", "authUser", "shell", "args", "username", "password", "toFlagList", "flags", "matchFlagToken", "token", "flag", "prefix", "collectPositionals", "args", "options", "boolFlags", "valueFlags", "positionals", "passthrough", "index", "arg", "consumed", "matched", "match", "ifFlag", "allFlags", "getFlag", "next", "getArg", "parseArgs", "flagsWithValues", "inlineFlag", "aliasCommand", "args", "env", "k", "v", "lines", "arg", "eq", "val", "name", "unaliasCommand", "ifFlag", "path", "PROTECTED_PREFIXES", "resolvePath", "cwd", "inputPath", "isProtectedPath", "targetPath", "normalized", "PROTECTED_PREFIXES", "prefix", "assertPathAccess", "authUser", "operation", "stripUrlFilename", "url", "lastPart", "levenshtein", "a", "b", "dp", "i", "j", "cost", "resolveReadablePath", "vfs", "cwd", "inputPath", "exactPath", "resolvePath", "parent", "fileName", "siblings", "caseInsensitive", "name", "near", "joinListWithType", "items", "statAt", "childPath", "getPackageManager", "shell", "aptCommand", "args", "shell", "authUser", "pm", "getPackageManager", "sub", "rest", "quiet", "ifFlag", "purge", "pkgs", "a", "output", "exitCode", "term", "results", "p", "name", "info", "pkgList", "aptCacheCommand", "pkgName", "def", "inst", "awkCommand", "args", "stdin", "sep", "getFlag", "prog", "a", "printMatch", "fields", "f", "line", "parts", "n", "base64Command", "args", "stdin", "decode", "ifFlag", "input", "catCommand", "authUser", "shell", "cwd", "args", "stdin", "numberAll", "ifFlag", "numberNonBlank", "fileArgs", "a", "parts", "fileArg", "target", "resolveReadablePath", "assertPathAccess", "combined", "lineNum", "line", "cdCommand", "authUser", "shell", "cwd", "args", "mode", "target", "resolvePath", "assertPathAccess", "applySymbolicMode", "existing", "modeStr", "pattern", "parts", "mode", "part", "m", "who", "op", "perms", "targets", "bits", "t", "p", "bit", "mask", "a", "b", "chmodCommand", "authUser", "shell", "cwd", "args", "modeArg", "fileArg", "filePath", "resolvePath", "assertPathAccess", "octal", "result", "err", "clearCommand", "cpCommand", "authUser", "shell", "cwd", "args", "recursive", "ifFlag", "positionals", "a", "srcArg", "destArg", "srcPath", "resolvePath", "destPath", "assertPathAccess", "copyDir", "from", "to", "entry", "fromEntry", "toEntry", "content", "finalDest", "err", "curlCommand", "authUser", "cwd", "args", "shell", "flagsWithValues", "positionals", "parseArgs", "ifFlag", "url", "outputPath", "method", "postData", "headerRaw", "silent", "headOnly", "followRedirects", "verbose", "extraHeaders", "idx", "finalMethod", "fetchOpts", "stderrLines", "response", "err", "lines", "k", "v", "body", "target", "resolvePath", "assertPathAccess", "cutCommand", "args", "stdin", "delim", "getFlag", "cols", "f", "a", "b", "line", "parts", "selected", "col", "i", "dateCommand", "args", "now", "fmt", "declareCommand", "args", "env", "integer", "ifFlag", "_readonly", "_export_", "k", "v", "assignments", "token", "eq", "name", "val", "n", "deluserCommand", "authUser", "args", "shell", "username", "dfCommand", "shell", "used", "total", "avail", "pct", "hdr", "row", "diffCommand", "shell", "cwd", "args", "f1", "f2", "p1", "resolvePath", "p2", "b", "out", "max", "i", "la", "lb", "dpkgCommand", "args", "authUser", "shell", "pm", "getPackageManager", "listFlag", "ifFlag", "statusFlag", "listFilesFlag", "removeFlag", "purgeFlag", "positionals", "parseArgs", "pkgList", "header", "rows", "p", "name", "ver", "arch", "desc", "pkgName", "info", "installed", "output", "exitCode", "dpkgQueryCommand", "showFlag", "pattern", "filtered", "duCommand", "shell", "cwd", "args", "human", "ifFlag", "summary", "target", "a", "p", "resolvePath", "fmt", "b", "lines", "walk", "dir", "rel", "total", "e", "full", "r", "st", "evalArith", "expr", "env", "substituted", "_", "name", "val", "result", "outsideSingleQuotes", "input", "replacer", "parts", "i", "sqIdx", "closeIdx", "expandSync", "lastExit", "home", "homePath", "chunk", "s", "pre", "post", "def", "alt", "expandAsync", "runCmd", "inSingle", "ch", "depth", "j", "sub", "out", "expandEscapes", "text", "_", "oct", "echoCommand", "args", "stdin", "env", "flags", "positionals", "parseArgs", "noNewline", "escapes", "rawText", "expanded", "expandSync", "envCommand", "env", "authUser", "vars", "k", "v", "exitCommand", "args", "exportCommand", "args", "env", "k", "v", "arg", "eq", "name", "value", "findCommand", "authUser", "shell", "cwd", "args", "namePattern", "getFlag", "typeFilter", "rootArg", "a", "rootPath", "resolvePath", "assertPathAccess", "err", "nameRegex", "results", "walk", "currentPath", "display", "stat", "matchesType", "matchesName", "entry", "full", "disp", "os", "freeCommand", "args", "human", "ifFlag", "mb", "gb", "osTotalB", "osFreeB", "usedB", "sharedB", "buffersB", "availableB", "swapB", "fmt", "bytes", "header", "memRow", "swapRow", "grepCommand", "authUser", "shell", "cwd", "args", "stdin", "flags", "positionals", "parseArgs", "caseInsensitive", "invertMatch", "showLineNumbers", "recursive", "pattern", "files", "regex", "regexFlags", "matchLines", "content", "prefix", "lines", "out", "i", "line", "matches", "lineLabel", "readPaths", "base", "paths", "walk", "dir", "entry", "full", "results", "resolvedPaths", "f", "target", "resolvePath", "p", "file", "filePath", "assertPathAccess", "groupsCommand", "authUser", "shell", "args", "target", "gzipCommand", "shell", "cwd", "args", "file", "p", "resolvePath", "gunzipCommand", "headCommand", "authUser", "shell", "cwd", "args", "stdin", "nArg", "getFlag", "n", "positionals", "a", "take", "content", "results", "file", "filePath", "resolvePath", "assertPathAccess", "CATEGORY_ORDER", "CATEGORY_LABELS", "BOLD", "RESET", "CYAN", "YLW", "DIM", "GREEN", "pad", "s", "n", "formatCmdLine", "mod", "aliases", "renderFull", "modules", "grouped", "cat", "lines", "cats", "c", "mods", "sorted", "a", "b", "total", "renderDetail", "p", "catLabel", "createHelpCommand", "_getNames", "args", "getCommandModulesPublic", "target", "m", "historyCommand", "args", "shell", "histPath", "lines", "nArg", "n", "slice", "offset", "line", "i", "hostnameCommand", "hostname", "htopCommand", "mode", "idCommand", "authUser", "shell", "args", "target", "uid", "gid", "groups", "killCommand", "args", "a", "lnCommand", "authUser", "shell", "cwd", "args", "symbolic", "ifFlag", "positionals", "a", "targetArg", "linkArg", "linkPath", "resolvePath", "targetPath", "assertPathAccess", "srcPath", "content", "err", "formatPermissions", "mode", "isDirectory", "fileType", "permissions", "bit", "symbol", "formatDate", "date", "lsCommand", "authUser", "shell", "cwd", "args", "longFormat", "ifFlag", "showHidden", "targetArg", "getArg", "target", "resolvePath", "assertPathAccess", "items", "name", "childPath", "stat", "size", "joinListWithType", "p", "lsbReleaseCommand", "args", "shell", "osName", "codename", "version", "content", "line", "all", "ifFlag", "showId", "showDesc", "showRelease", "showCodename", "lines", "MAN_PAGES", "manCommand", "args", "shell", "name", "manPath", "page", "mkdirCommand", "authUser", "shell", "cwd", "args", "index", "dir", "getArg", "target", "resolvePath", "assertPathAccess", "mvCommand", "authUser", "shell", "cwd", "args", "positionals", "a", "srcArg", "destArg", "srcPath", "resolvePath", "destPath", "assertPathAccess", "finalDest", "err", "path", "nanoCommand", "authUser", "shell", "cwd", "args", "fileArg", "targetPath", "resolvePath", "assertPathAccess", "initialContent", "safeName", "tempPath", "existsSync", "readdirSync", "readFileSync", "os", "path", "formatUptime", "seconds", "totalMinutes", "days", "hours", "minutes", "parts", "colorBlock", "code", "buildColorBars", "normal", "bright", "colorizeLogoLine", "line", "index", "total", "start", "end", "ratio", "r", "g", "b", "colorizeDetailLine", "colonIndex", "applyHorizontalGradient", "title", "value", "text", "ansiRegex", "cleaned", "result", "i", "toMiB", "bytes", "readOsPrettyName", "data", "readFirstLine", "filePath", "resolveHostLabel", "fallback", "vendor", "product", "countDpkgPackages", "candidates", "countSnapPackages", "dirPath", "entry", "resolvePackagesLabel", "dpkgCount", "snapCount", "resolveCpuLabel", "cpus", "first", "ghz", "resolveShellLabel", "shell", "resolveDefaults", "info", "totalMem", "freeMem", "usedMem", "shellProps", "processUptime", "buildNeofetchOutput", "fields", "uptime", "colorBars", "distroLogo", "details", "width", "lines", "rawLeft", "right", "left", "coloredRight", "_globalEnv", "getAllEnvVars", "authUser", "_globalEnv", "setCommand", "args", "env", "k", "v", "arg", "eq", "neofetchCommand", "args", "authUser", "hostname", "shell", "env", "getAllEnvVars", "ifFlag", "buildNeofetchOutput", "vm", "VIRTUAL_VERSION", "VIRTUAL_VERSIONS", "makeContext", "outputLines", "stderrLines", "fakeProcess", "code", "ExitSignal", "fakeConsole", "a", "formatValue", "v", "fakeRequire", "mod", "parts", "p", "b", "d", "id", "vm", "k", "val", "runJs", "ctx", "exitCode", "result", "err", "runJsFile", "trimmed", "nodeCommand", "args", "shell", "cwd", "ifFlag", "eIdx", "expr", "stdout", "stderr", "pIdx", "file", "filePath", "resolvePath", "NPM_VERSION", "NODE_VERSION", "npmCommand", "args", "shell", "ifFlag", "sub", "npxCommand", "passwdCommand", "authUser", "args", "shell", "username", "password", "pingCommand", "args", "flagsWithValues", "positionals", "parseArgs", "host", "countArg", "count", "lines", "i", "ms", "renderPrintf", "fmt", "args", "argIdx", "out", "j", "spec", "arg", "printfCommand", "psCommand", "authUser", "shell", "args", "sessions", "showUser", "ifFlag", "showAll", "rows", "pid", "s", "user", "mem", "vsz", "rss", "pwdCommand", "cwd", "VERSION", "VERSION_INFO", "NONE", "pyDict", "entries", "pyRange", "start", "stop", "step", "isPyDict", "v", "isPyRange", "isPyFunc", "isPyClass", "isPyInstance", "isPyNone", "pyRepr", "k", "val", "pyStr", "pyBool", "pyRangeLength", "n", "pyRangeItems", "items", "i", "pyIter", "PyError", "pyTypeName", "type", "message", "ReturnSignal", "value", "BreakSignal", "ContinueSignal", "ExitSignal", "code", "makeRootScope", "cwd", "scope", "osModule", "makeOsModule", "path", "os", "makeSysModule", "makeMathModule", "makeJsonModule", "makeReModule", "MODULE_FACTORIES", "Interpreter", "s", "args", "depth", "cur", "inStr", "strChar", "ch", "expr", "fMatch", "result", "_", "inner", "bMatch", "compMatch", "itemExpr", "varName", "iterExpr", "condExpr", "iterable", "item", "inner2", "a", "parts", "dict", "entry", "colonIdx", "notMatch", "binaryOps", "ops", "bracketStart", "obj", "key", "callMatch", "name", "argsStr", "callArgs", "dotResult", "objExpr", "attr", "callPart", "argsInner", "part", "open", "close", "attrMatch", "op", "before", "after", "left", "right", "leftExpr", "rightExpr", "l", "arr", "container", "p", "idx", "_scope", "method", "w", "f", "c", "b", "d", "mathFns", "fn", "r", "opts", "indent", "callScope", "fmt", "spec", "base", "iters", "len", "it", "acc", "sortArg1", "keyFn", "ka", "kb", "h", "e", "cls", "inst", "lines", "startIdx", "raw", "bodyLines", "line", "baseIndent", "block", "retMatch", "raiseMatch", "ex", "assertMatch", "delMatch", "importMatch", "modName", "alias", "factory", "mod", "fromMatch", "imports", "defMatch", "fnName", "paramsStr", "params", "body", "classMatch", "className", "basesStr", "bases", "j", "mMatch", "mName", "mParams", "mBody", "cond", "_skip", "bk", "el", "elt", "elifMatch", "eBody", "sl", "sb", "forMatch", "target", "elseBody", "afterIdx", "broken", "targets", "t", "whileMatch", "iterations", "tryBody", "exceptClauses", "finallyBody", "excMatch", "excName", "excAlias", "excBody", "_caughtErr", "handled", "clause", "withMatch", "augMatch", "rhsExpr", "lhs", "rhs", "subAssignMatch", "valExpr", "attrAssignMatch", "dotIdx", "multiAssignMatch", "values", "assignMatch", "python3Command", "shell", "ifFlag", "VERSION", "cIdx", "normalised", "interp", "stdout", "stderr", "exitCode", "file", "filePath", "resolvePath", "readCommand", "args", "stdin", "env", "_promptIdx", "varNames", "i", "input", "line", "ifFlag", "m", "parts", "rmCommand", "authUser", "shell", "cwd", "args", "recursive", "ifFlag", "targets", "index", "target", "getArg", "resolvedTarget", "resolvePath", "assertPathAccess", "sedCommand", "authUser", "shell", "cwd", "args", "stdin", "inPlace", "ifFlag", "expr", "getFlag", "a", "fileArg", "content", "p", "resolvePath", "sMatch", "from", "to", "flags", "regexFlags", "regex", "result", "expandVars", "line", "env", "lastExit", "ctx", "expandAsync", "sub", "runCommand", "r", "parseBlocks", "lines", "blocks", "i", "cond", "thenLines", "elifBlocks", "elseLines", "section", "elifCond", "l", "m", "body", "evalCondition", "expanded", "testMatch", "expr", "fTest", "flag", "arg", "p", "resolvePath", "cmpMatch", "a", "op", "b", "numMatch", "na", "nb", "runBlocks", "lastResult", "output", "block", "assignRe", "tokens", "t", "tok", "ran", "elif", "items", "item", "iterations", "shCommand", "args", "shell", "cwd", "ifFlag", "script", "fileArg", "shiftCommand", "args", "env", "n", "argv", "shifted", "i", "trapCommand", "action", "signals", "sig", "returnCommand", "code", "sleepCommand", "args", "secs", "r", "sortCommand", "authUser", "shell", "cwd", "args", "stdin", "reverse", "ifFlag", "numeric", "unique", "files", "a", "sorted", "f", "assertPathAccess", "resolvePath", "b", "result", "sourceCommand", "args", "authUser", "hostname", "cwd", "shell", "env", "fileArg", "filePath", "resolvePath", "content", "lastExitCode", "line", "l", "result", "runCommand", "suCommand", "authUser", "shell", "args", "users", "targetUser", "getArg", "parseSudoArgs", "args", "flags", "flagsWithValues", "positionals", "parseArgs", "loginShell", "targetUser", "commandLine", "sudoCommand", "authUser", "hostname", "mode", "cwd", "shell", "effectiveUser", "prompt", "runCommand", "tailCommand", "authUser", "shell", "cwd", "args", "stdin", "nArg", "getFlag", "n", "positionals", "a", "take", "content", "lines", "results", "file", "filePath", "resolvePath", "assertPathAccess", "tarCommand", "authUser", "shell", "cwd", "args", "create", "ifFlag", "extract", "list", "fFlag", "a", "archiveName", "archivePath", "resolvePath", "fileArgs", "entries", "f", "p", "walk", "dir", "prefix", "e", "full", "rel", "name", "content", "teeCommand", "authUser", "shell", "cwd", "args", "stdin", "append", "ifFlag", "files", "a", "input", "f", "p", "resolvePath", "existing", "evalTest", "tokens", "shell", "cwd", "andIdx", "orIdx", "flag", "operand", "path", "p", "left", "op", "right", "leftN", "rightN", "testCommand", "args", "touchCommand", "authUser", "shell", "cwd", "args", "file", "target", "resolvePath", "assertPathAccess", "trCommand", "args", "stdin", "del", "ifFlag", "positionals", "set1", "set2", "input", "c", "i", "treeCommand", "authUser", "shell", "cwd", "args", "target", "resolvePath", "getArg", "assertPathAccess", "trueCommand", "falseCommand", "typeCommand", "args", "shell", "env", "pathDirs", "lines", "exitCode", "name", "resolveModule", "found", "dir", "full", "unameCommand", "shell", "args", "all", "ifFlag", "sysname", "release", "machine", "hostname", "uniqCommand", "args", "stdin", "count", "ifFlag", "dupOnly", "uniqOnly", "lines", "out", "i", "j", "n", "line", "unsetCommand", "args", "env", "name", "uptimeCommand", "args", "shell", "pretty", "ifFlag", "since", "uptimeSec", "days", "hours", "mins", "parts", "timeStr", "uptimeStr", "sessions", "load", "wcCommand", "authUser", "shell", "cwd", "args", "stdin", "lines", "ifFlag", "words", "bytes", "showAll", "positionals", "a", "count", "content", "label", "l", "w", "c", "parts", "results", "file", "filePath", "resolvePath", "assertPathAccess", "wgetCommand", "authUser", "cwd", "args", "shell", "flagsWithValues", "positionals", "parseArgs", "ifFlag", "url", "outputArg", "dirPrefix", "quiet", "filename", "stripUrlFilename", "targetPath", "resolvePath", "assertPathAccess", "stderrLines", "response", "err", "msg", "body", "ct", "whichCommand", "args", "shell", "env", "pathDirs", "lines", "anyMissing", "name", "found", "dir", "full", "formatLoginDate", "date", "weekday", "month", "day", "hh", "mm", "ss", "year", "whoCommand", "shell", "session", "loginAt", "displayDate", "formatLoginDate", "whoamiCommand", "authUser", "xargsCommand", "authUser", "hostname", "mode", "cwd", "args", "stdin", "shell", "env", "baseCmd", "extraArgs", "items", "fullCmd", "runCommand", "BASE_COMMANDS", "pwdCommand", "cdCommand", "lsCommand", "treeCommand", "catCommand", "touchCommand", "rmCommand", "mkdirCommand", "cpCommand", "mvCommand", "lnCommand", "chmodCommand", "findCommand", "grepCommand", "sedCommand", "awkCommand", "sortCommand", "uniqCommand", "wcCommand", "headCommand", "tailCommand", "cutCommand", "trCommand", "teeCommand", "xargsCommand", "diffCommand", "tarCommand", "gzipCommand", "gunzipCommand", "base64Command", "whoamiCommand", "whoCommand", "hostnameCommand", "idCommand", "groupsCommand", "unameCommand", "psCommand", "killCommand", "dfCommand", "duCommand", "dateCommand", "sleepCommand", "pingCommand", "echoCommand", "envCommand", "exportCommand", "setCommand", "unsetCommand", "shCommand", "clearCommand", "exitCommand", "nanoCommand", "htopCommand", "curlCommand", "wgetCommand", "adduserCommand", "passwdCommand", "deluserCommand", "sudoCommand", "suCommand", "neofetchCommand", "aptCommand", "aptCacheCommand", "dpkgCommand", "dpkgQueryCommand", "whichCommand", "typeCommand", "manCommand", "aliasCommand", "unaliasCommand", "testCommand", "sourceCommand", "historyCommand", "printfCommand", "readCommand", "declareCommand", "shiftCommand", "trapCommand", "returnCommand", "trueCommand", "falseCommand", "npmCommand", "npxCommand", "nodeCommand", "python3Command", "uptimeCommand", "freeCommand", "lsbReleaseCommand", "customCommands", "commandRegistry", "cachedCommandNames", "helpCommand", "createHelpCommand", "getCommandModules", "cmd", "buildCache", "mod", "alias", "registerCommand", "module", "normalized", "a", "createCustomCommand", "name", "params", "run", "getCommandNames", "getCommandModulesPublic", "resolveModule", "executeStatements", "statements", "authUser", "hostname", "mode", "cwd", "shell", "env", "last", "i", "stmt", "executePipeline", "op", "pipeline", "shellEnv", "executeSingleCommandWithRedirections", "executePipelineChain", "cmd", "stdin", "inputPath", "resolvePath", "result", "runCommandDirect", "outputPath", "output", "existing", "commands", "currentOutput", "exitCode", "parseScript", "rawInput", "trimmed", "parseStatements", "parseStatements", "input", "segments", "splitByLogicalOps", "statements", "seg", "stmt", "parsePipeline", "current", "depth", "inQ", "qChar", "i", "flush", "op", "ch", "ch2", "splitByPipe", "parseCommandWithRedirections", "tokens", "tail", "token", "parts", "tokenizeCommand", "cmdParts", "inputFile", "outputFile", "appendOutput", "part", "next", "tokenizeCommand", "input", "tokens", "current", "inQ", "qChar", "i", "ch", "next", "makeDefaultEnv", "authUser", "hostname", "resolveVfsBinary", "name", "env", "shell", "st", "pathDirs", "dir", "full", "runCommandDirect", "args", "mode", "cwd", "stdin", "aliasVal", "runCommand", "mod", "resolveModule", "vfsBinary", "stubContent", "builtinMatch", "builtinMod", "shMod", "error", "rawInput", "trimmed", "shellEnv", "rawFirstWord", "aliasExpanded", "script", "parseScript", "executeStatements", "expanded", "expandAsync", "sub", "r", "parts", "commandName", "builtinName", "buildLoginBanner", "hostname", "properties", "lastLogin", "lines", "when", "displayed", "formatLoginDate", "line", "buildPrompt", "user", "host", "cwdName", "isRoot", "colorUser", "colorWhite", "colorBlue", "colorReset", "EventEmitter", "os", "ensureDir", "vfs", "path", "mode", "ensureFile", "content", "bootstrapEtc", "hostname", "props", "syncEtcPasswd", "users", "userList", "passwdLines", "uid", "u", "groupLines", "shadowLines", "ttyToPid", "tty", "match", "writeProcPid", "pid", "username", "_tty", "cmdline", "startedAt", "env", "dir", "uptimeSec", "k", "v", "refreshProc", "shellStartTime", "sessions", "totalMemKb", "freeMemKb", "availMemKb", "cpus", "cpuLines", "i", "c", "mhz", "load", "numProcs", "activeSessions", "session", "selfPid", "selfSrc", "entry", "srcPath", "dstPath", "bootstrapSys", "bootstrapDev", "bootstrapUsr", "builtins", "bin", "bootstrapVar", "bootstrapBin", "bootstrapTmp", "bootstrapRoot", "bootstrapMisc", "bootstrapLinuxRootfs", "isTruthyEnv", "value", "nowMs", "isPerfLoggingEnabled", "createPerfLogger", "scope", "enabled", "startedAt", "mark", "label", "elapsedMs", "EventEmitter", "fsSync", "path", "gunzipSync", "gzipSync", "MAGIC", "VERSION", "TYPE_FILE", "TYPE_DIR", "Encoder", "buf", "n", "b", "s", "encoded", "bytes", "encodeNode", "enc", "node", "f", "d", "children", "child", "encodeVfs", "root", "Decoder", "v", "len", "decodeNode", "dec", "type", "name", "mode", "createdAt", "updatedAt", "compressed", "content", "count", "i", "decodeVfs", "isBinarySnapshot", "path", "normalizePath", "rawPath", "normalized", "splitPath", "normalizedPath", "getNode", "root", "targetPath", "parts", "current", "part", "next", "getParentDirectory", "createIfMissing", "createPath", "parentPath", "name", "parentNode", "VirtualFileSystem", "_VirtualFileSystem", "EventEmitter", "options", "name", "mode", "now", "content", "compressed", "targetPath", "normalized", "normalizePath", "parts", "current", "builtPath", "part", "child", "raw", "isBinarySnapshot", "decodeVfs", "snapshot", "err", "dir", "binary", "encodeVfs", "existing", "getNode", "parent", "getParentDirectory", "p", "rawContent", "shouldCompress", "storedContent", "gzipSync", "f", "node", "gunzipSync", "d", "dirPath", "label", "lines", "entries", "i", "isLast", "connector", "nextPrefix", "sub", "l", "total", "linkPath", "normalizedLink", "normalizedTarget", "symNode", "maxDepth", "depth", "target", "fromPath", "toPath", "fromNormalized", "toNormalized", "destParent", "destName", "srcParent", "srcName", "children", "file", "vfs", "snap", "VirtualFileSystem_default", "PACKAGE_REGISTRY", "vfs", "VirtualPackageManager", "users", "status", "blocks", "block", "fields", "name", "pkg", "result", "line", "idx", "msg", "existing", "action", "pkgs", "ts", "entry", "p", "a", "b", "names", "opts", "lines", "toInstall", "notFound", "resolve", "seen", "def", "dep", "n", "totalKb", "acc", "f", "dir", "now", "toRemove", "filePath", "term", "t", "inst", "createHash", "randomBytes", "randomUUID", "scryptSync", "EventEmitter", "path", "resolveFastPasswordHash", "configured", "perf", "createPerfLogger", "VirtualUserManager", "_VirtualUserManager", "EventEmitter", "vfs", "autoSudoForNewUsers", "changed", "homePath", "username", "maxBytes", "targetPath", "nextContent", "quota", "normalizedPath", "normalizeVfsPath", "currentUsage", "existingSize", "existing", "incomingSize", "projectedUsage", "password", "record", "remoteAddress", "session", "randomUUID", "sessionId", "left", "right", "raw", "line", "trimmed", "parts", "salt", "passwordHash", "value", "bytes", "authContent", "sudoersContent", "quotasContent", "content", "mode", "cacheKey", "cached", "randomBytes", "createHash", "scryptSync", "algo", "data", "keys", "normalized", "readFile", "unlink", "writeFile", "path", "spawn", "readFile", "path", "shellQuote", "value", "toTtyLines", "text", "withTerminalSize", "command", "terminalSize", "cols", "rows", "resolvePath", "base", "inputPath", "collectChildPids", "parentPid", "directChildren", "pid", "nested", "getVisibleHtopPidList", "rootPid", "descendants", "unique", "a", "b", "spawnScriptProcess", "command", "terminalSize", "stream", "formatted", "withTerminalSize", "proc", "spawn", "data", "spawnNanoEditorProcess", "tempPath", "shellQuote", "spawnHtopProcess", "pidList", "startShell", "properties", "stream", "authUser", "hostname", "sessionId", "remoteAddress", "terminalSize", "shell", "lineBuffer", "cursorPos", "history", "loadHistory", "historyIndex", "historyDraft", "cwd", "shellEnv", "makeDefaultEnv", "nanoSession", "pendingSudo", "buildCurrentPrompt", "homePath", "cwdLabel", "buildPrompt", "commandNames", "getCommandNames", "bashrcPath", "bashrc", "line", "l", "runCommand", "renderLine", "prompt", "moveLeft", "clearCurrentLine", "startSudoPrompt", "challenge", "finishSudoPrompt", "success", "runCwd", "result", "startNanoEditor", "startHtop", "toTtyLines", "finishNanoEditor", "activeSession", "updatedContent", "readFile", "unlink", "targetPath", "initialContent", "tempPath", "writeFile", "editor", "spawnNanoEditorProcess", "error", "pidList", "getVisibleHtopPidList", "monitor", "spawnHtopProcess", "applyHistoryLine", "nextLine", "insertText", "text", "getTokenRange", "cursor", "start", "end", "listPathCompletions", "prefix", "slashIndex", "dirPart", "namePart", "basePath", "resolvePath", "entry", "fullPath", "suffix", "handleTabCompletion", "token", "commandCandidates", "name", "pathCandidates", "candidates", "completed", "pushHistory", "cmd", "data", "readLastLogin", "lastlogPath", "writeLastLogin", "nowIso", "dir", "renderLoginBanner", "last", "buildLoginBanner", "chunk", "input", "i", "ch", "password", "valid", "next", "third", "fourth", "vfs", "historyPath", "hasVfsInstance", "obj", "isVirtualShellVfsLike", "value", "candidate", "defaultShellProperties", "perf", "createPerfLogger", "resolveAutoSudoForNewUsers", "configured", "VirtualShell", "EventEmitter", "hostname", "properties", "vfsOptionsOrInstance", "VirtualFileSystem_default", "VirtualUserManager", "VirtualPackageManager", "vfs", "users", "pm", "shellProps", "shellHostname", "startTime", "bootstrapLinuxRootfs", "name", "params", "callback", "normalized", "registerCommand", "createCustomCommand", "rawInput", "authUser", "cwd", "runCommand", "stream", "sessionId", "remoteAddress", "terminalSize", "startShell", "refreshProc", "syncEtcPasswd", "targetPath", "content", "hostname", "argv", "readUserArg", "index", "current", "next", "initialUser", "virtualShell", "VirtualShell", "readLastLogin", "username", "lastlogPath", "askQuestion", "rl", "promptText", "resolve", "writeLastLogin", "from", "dir", "runReadlineShell", "createInterface", "stdin", "stdout", "selectedUser", "shellEnv", "makeDefaultEnv", "authUser", "cwd", "remoteAddress", "password", "renderPrompt", "cwdLabel", "basename", "buildPrompt", "prompt", "buildLoginBanner", "inputLine", "line", "result", "runCommand", "error", "promise"]
|
|
7
7
|
}
|