{"version":3,"file":"filesystem.cjs","names":["dev: number","_mode: number","nlink: number","uid: number","gid: number","rdev: number","blksize: number","ino: number","size: number","blocks: number","atimeMs: number","mtimeMs: number","ctimeMs: number","birthtimeMs: number","name: string","type: number","parentPath: string","FIND_TYPE_TO_DIRENT: Record<string, number>","content: Buffer","appendContent: Buffer","result","args: string[]"],"sources":["../src/filesystem.ts"],"sourcesContent":["import type { Stats, Dirent } from \"fs\";\n\n// POSIX st_mode file-type bit masks. These are fixed, standardized values\n// (identical across Linux/Node's node:constants); inlined so the module needs\n// no Node builtin and works unchanged in the browser bundle.\nconst S_IFMT = 0o170000;\nconst S_IFREG = 0o100000;\nconst S_IFDIR = 0o040000;\nconst S_IFLNK = 0o120000;\nconst S_IFBLK = 0o060000;\nconst S_IFCHR = 0o020000;\nconst S_IFIFO = 0o010000;\nconst S_IFSOCK = 0o140000;\n\n// https://github.com/nodejs/node/blob/main/deps/uv/include/uv.h#L1267-L1276\n// exposed through node:constants but not in @types/node\nconst UV_DIRENT_FILE = 1;\nconst UV_DIRENT_DIR = 2;\nconst UV_DIRENT_LINK = 3;\nconst UV_DIRENT_FIFO = 4;\nconst UV_DIRENT_SOCKET = 5;\nconst UV_DIRENT_CHAR = 6;\nconst UV_DIRENT_BLOCK = 7;\n\ntype EncodingOption =\n  | { encoding?: BufferEncoding | null; signal?: AbortSignal }\n  | BufferEncoding\n  | null;\n\ntype WriteFileData = string | Buffer | Uint8Array;\n\ninterface MkdirOptions {\n  recursive?: boolean;\n  signal?: AbortSignal;\n}\n\ninterface RmOptions {\n  recursive?: boolean;\n  force?: boolean;\n  signal?: AbortSignal;\n}\n\nfunction fsError(\n  code: string,\n  message: string,\n  syscall: string,\n  path: string,\n): Error & { code: string; syscall: string; path: string } {\n  const err = new Error(\n    `${code}: ${message}, ${syscall} '${path}'`,\n  ) as Error & {\n    code: string;\n    syscall: string;\n    path: string;\n  };\n  err.code = code;\n  err.syscall = syscall;\n  err.path = path;\n  return err;\n}\n\ninterface SandboxHandle {\n  readFileToBuffer(\n    file: { path: string },\n    opts?: { signal?: AbortSignal },\n  ): Promise<Uint8Array | null>;\n  writeFiles(\n    files: { path: string; content: Uint8Array }[],\n    opts?: { signal?: AbortSignal },\n  ): Promise<void>;\n  mkDir(path: string, opts?: { signal?: AbortSignal }): Promise<void>;\n  runCommand(\n    cmd: string,\n    args?: string[],\n    opts?: { signal?: AbortSignal },\n  ): Promise<{\n    exitCode: number;\n    stdout(opts?: { signal?: AbortSignal }): Promise<string>;\n    stderr(opts?: { signal?: AbortSignal }): Promise<string>;\n  }>;\n}\n\nfunction parseEncoding(options?: EncodingOption): {\n  encoding: BufferEncoding | null;\n  signal?: AbortSignal;\n} {\n  if (options === null || options === undefined) {\n    return { encoding: null };\n  }\n  if (typeof options === \"string\") {\n    return { encoding: options };\n  }\n  return { encoding: options.encoding ?? null, signal: options.signal };\n}\n\nclass SandboxStats {\n  readonly atime: Date;\n  readonly mtime: Date;\n  readonly ctime: Date;\n  readonly birthtime: Date;\n\n  constructor(\n    readonly dev: number,\n    private readonly _mode: number,\n    readonly nlink: number,\n    readonly uid: number,\n    readonly gid: number,\n    readonly rdev: number,\n    readonly blksize: number,\n    readonly ino: number,\n    readonly size: number,\n    readonly blocks: number,\n    readonly atimeMs: number,\n    readonly mtimeMs: number,\n    readonly ctimeMs: number,\n    readonly birthtimeMs: number,\n  ) {\n    this.atime = new Date(atimeMs);\n    this.mtime = new Date(mtimeMs);\n    this.ctime = new Date(ctimeMs);\n    this.birthtime = new Date(birthtimeMs);\n  }\n\n  get mode(): number {\n    return this._mode;\n  }\n\n  isFile(): boolean {\n    return (this.mode & S_IFMT) === S_IFREG;\n  }\n  isDirectory(): boolean {\n    return (this.mode & S_IFMT) === S_IFDIR;\n  }\n  isBlockDevice(): boolean {\n    return (this.mode & S_IFMT) === S_IFBLK;\n  }\n  isCharacterDevice(): boolean {\n    return (this.mode & S_IFMT) === S_IFCHR;\n  }\n  isSymbolicLink(): boolean {\n    return (this.mode & S_IFMT) === S_IFLNK;\n  }\n  isFIFO(): boolean {\n    return (this.mode & S_IFMT) === S_IFIFO;\n  }\n  isSocket(): boolean {\n    return (this.mode & S_IFMT) === S_IFSOCK;\n  }\n}\n\nclass SandboxDirent {\n  readonly path: string;\n\n  constructor(\n    public name: string,\n    private type: number,\n    public parentPath: string,\n  ) {\n    this.path = `${this.parentPath}/${this.name}`;\n  }\n\n  isFile(): boolean {\n    return this.type === UV_DIRENT_FILE;\n  }\n  isDirectory(): boolean {\n    return this.type === UV_DIRENT_DIR;\n  }\n  isBlockDevice(): boolean {\n    return this.type === UV_DIRENT_BLOCK;\n  }\n  isCharacterDevice(): boolean {\n    return this.type === UV_DIRENT_CHAR;\n  }\n  isSymbolicLink(): boolean {\n    return this.type === UV_DIRENT_LINK;\n  }\n  isFIFO(): boolean {\n    return this.type === UV_DIRENT_FIFO;\n  }\n  isSocket(): boolean {\n    return this.type === UV_DIRENT_SOCKET;\n  }\n}\n\nfunction parseStat(stdout: string) {\n  // Format: size|rawModeHex|uid|gid|atimeMs|mtimeMs|ctimeMs|birthtimeMs|nlink|ino|dev|blksize|blocks\n  const parts = stdout.trim().split(\"|\");\n\n  return new SandboxStats(\n    parseInt(parts[10]!, 10), // dev\n    parseInt(parts[1]!, 16), // mode (raw mode from %f, hex)\n    parseInt(parts[8]!, 10), // nlink\n    parseInt(parts[2]!, 10), // uid\n    parseInt(parts[3]!, 10), // gid\n    0, // rdev\n    parseInt(parts[11]!, 10), // blksize\n    parseInt(parts[9]!, 10), // ino\n    parseInt(parts[0]!, 10), // size\n    parseInt(parts[12]!, 10), // blocks\n    parseFloat(parts[4]!) * 1000, // atimeMs\n    parseFloat(parts[5]!) * 1000, // mtimeMs\n    parseFloat(parts[6]!) * 1000, // ctimeMs\n    parseFloat(parts[7]!) * 1000, // birthtimeMs\n  ) satisfies Stats;\n}\n\nfunction parseDirent(stdout: string, path: string) {\n  const parts = stdout.trim().split(\"|\");\n  const name = parts[0];\n  const type = parts[1];\n\n  if (!name) {\n    throw fsError(\"ENOENT\", \"no such file or directory\", \"readdir\", path);\n  }\n\n  if (!type) {\n    throw new Error(`Invalid dirent type: ${type}`);\n  }\n\n  const direntType = FIND_TYPE_TO_DIRENT[type] ?? UV_DIRENT_FILE;\n  return new SandboxDirent(name, direntType, path) satisfies Dirent;\n}\n\n// %f = raw mode in hex, includes file type bits so Stats.isFile()/isDirectory()/etc. work\nconst STAT_FORMAT = \"%s|%f|%u|%g|%X|%Y|%Z|%W|%h|%i|%d|%B|%b\";\n\nconst FIND_TYPE_TO_DIRENT: Record<string, number> = {\n  f: UV_DIRENT_FILE,\n  d: UV_DIRENT_DIR,\n  l: UV_DIRENT_LINK,\n  b: UV_DIRENT_BLOCK,\n  c: UV_DIRENT_CHAR,\n  p: UV_DIRENT_FIFO,\n  s: UV_DIRENT_SOCKET,\n};\n\nexport class FileSystem {\n  /** @internal */\n  private sandbox: SandboxHandle;\n\n  /** @internal */\n  constructor(sandbox: SandboxHandle) {\n    this.sandbox = sandbox;\n  }\n\n  /**\n   * Read the entire contents of a file.\n   *\n   * @param path - Path to the file\n   * @param options - Encoding or options object. If encoding is specified, returns a string; otherwise returns a Buffer.\n   */\n  async readFile(\n    path: string,\n    options?: { encoding?: null; signal?: AbortSignal } | null,\n  ): Promise<Buffer>;\n  async readFile(\n    path: string,\n    options:\n      | { encoding: BufferEncoding; signal?: AbortSignal }\n      | BufferEncoding,\n  ): Promise<string>;\n  async readFile(\n    path: string,\n    options?: EncodingOption,\n  ): Promise<Uint8Array | string> {\n    const { encoding, signal } = parseEncoding(options);\n    const buffer = await this.sandbox.readFileToBuffer({ path }, { signal });\n    if (buffer === null) {\n      throw fsError(\"ENOENT\", \"no such file or directory\", \"open\", path);\n    }\n    return encoding ? new TextDecoder(encoding).decode(buffer) : buffer;\n  }\n\n  /**\n   * Write data to a file, replacing the file if it already exists.\n   *\n   * @param path - Path to the file\n   * @param data - The data to write\n   * @param options - Write options\n   */\n  async writeFile(\n    path: string,\n    data: WriteFileData,\n    options?:\n      | { encoding?: BufferEncoding; signal?: AbortSignal }\n      | BufferEncoding,\n  ): Promise<void> {\n    \"use step\";\n    const { encoding, signal } =\n      typeof options === \"string\"\n        ? { encoding: options, signal: undefined }\n        : { encoding: options?.encoding, signal: options?.signal };\n    let content: Buffer;\n    if (typeof data === \"string\") {\n      content = Buffer.from(data, encoding ?? \"utf8\");\n    } else if (Buffer.isBuffer(data)) {\n      content = data;\n    } else {\n      content = Buffer.from(data);\n    }\n    await this.sandbox.writeFiles([{ path, content }], { signal });\n  }\n\n  /**\n   * Append data to a file, creating the file if it does not yet exist.\n   *\n   * @param path - Path to the file\n   * @param data - The data to append\n   * @param options - Write options\n   */\n  async appendFile(\n    path: string,\n    data: WriteFileData,\n    options?:\n      | { encoding?: BufferEncoding; signal?: AbortSignal }\n      | BufferEncoding,\n  ): Promise<void> {\n    \"use step\";\n    const { encoding, signal } =\n      typeof options === \"string\"\n        ? { encoding: options, signal: undefined }\n        : { encoding: options?.encoding, signal: options?.signal };\n    let appendContent: Buffer;\n    if (typeof data === \"string\") {\n      appendContent = Buffer.from(data, encoding ?? \"utf8\");\n    } else if (Buffer.isBuffer(data)) {\n      appendContent = data;\n    } else {\n      appendContent = Buffer.from(data);\n    }\n\n    const existing = await this.sandbox.readFileToBuffer({ path }, { signal });\n    const content =\n      existing !== null\n        ? Buffer.concat([existing, appendContent])\n        : appendContent;\n    await this.sandbox.writeFiles([{ path, content }], { signal });\n  }\n\n  /**\n   * Create a directory.\n   *\n   * @param path - Path of the directory to create\n   * @param options - Options for directory creation\n   */\n  async mkdir(\n    path: string,\n    options?: MkdirOptions | number,\n  ): Promise<string | undefined> {\n    \"use step\";\n    const opts =\n      typeof options === \"number\" ? { recursive: false } : (options ?? {});\n    if (opts.recursive) {\n      const result = await this.sandbox.runCommand(\"mkdir\", [\"-p\", path], {\n        signal: opts.signal,\n      });\n      if (result.exitCode !== 0) {\n        const stderr = await result.stderr();\n        throw fsError(\n          \"EACCES\",\n          stderr.trim() || \"permission denied\",\n          \"mkdir\",\n          path,\n        );\n      }\n      return undefined;\n    }\n    await this.sandbox.mkDir(path, { signal: opts.signal });\n    return undefined;\n  }\n\n  /**\n   * Read the contents of a directory.\n   *\n   * @param path - Path to the directory\n   * @param options - Options. When `withFileTypes` is true, returns `Dirent` objects.\n   */\n  async readdir(\n    path: string,\n    options?: { signal?: AbortSignal; withFileTypes?: false },\n  ): Promise<string[]>;\n  async readdir(\n    path: string,\n    options: { signal?: AbortSignal; withFileTypes: true },\n  ): Promise<Dirent[]>;\n  async readdir(\n    path: string,\n    options?: { signal?: AbortSignal; withFileTypes?: boolean },\n  ): Promise<string[] | Dirent[]> {\n    \"use step\";\n    if (options?.withFileTypes) {\n      // Use find to get name and type in one pass\n      const result = await this.sandbox.runCommand(\n        \"find\",\n        [path, \"-maxdepth\", \"1\", \"-mindepth\", \"1\", \"-printf\", \"%f|%y\\\\n\"],\n        { signal: options?.signal },\n      );\n      if (result.exitCode !== 0) {\n        const stderr = await result.stderr();\n        if (stderr.includes(\"No such file or directory\")) {\n          throw fsError(\"ENOENT\", \"no such file or directory\", \"scandir\", path);\n        }\n        throw fsError(\"EACCES\", stderr.trim(), \"scandir\", path);\n      }\n      const stdout = await result.stdout();\n      const lines = stdout.trim().split(\"\\n\").filter(Boolean);\n\n      return lines.map((line) => parseDirent(line, path));\n    }\n\n    const result = await this.sandbox.runCommand(\"ls\", [\"-1\", path], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"scandir\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"scandir\", path);\n    }\n    const stdout = await result.stdout();\n    return stdout.trim().split(\"\\n\").filter(Boolean);\n  }\n\n  /**\n   * Get file status. Follows symbolic links.\n   *\n   * @param path - Path to the file\n   * @param options - Options\n   */\n  async stat(path: string, options?: { signal?: AbortSignal }): Promise<Stats> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\n      \"stat\",\n      [\"-L\", \"-c\", STAT_FORMAT, path],\n      { signal: options?.signal },\n    );\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"stat\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"stat\", path);\n    }\n    return parseStat(await result.stdout());\n  }\n\n  /**\n   * Get file status. Does not follow symbolic links.\n   *\n   * @param path - Path to the file\n   * @param options - Options\n   */\n  async lstat(\n    path: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<Stats> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\n      \"stat\",\n      [\"-c\", STAT_FORMAT, path],\n      { signal: options?.signal },\n    );\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"lstat\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"lstat\", path);\n    }\n    return parseStat(await result.stdout());\n  }\n\n  /**\n   * Remove a file or symbolic link.\n   *\n   * @param path - Path to the file\n   * @param options - Options\n   */\n  async unlink(\n    path: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<void> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\"rm\", [path], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"unlink\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"unlink\", path);\n    }\n  }\n\n  /**\n   * Remove files and directories.\n   *\n   * @param path - Path to remove\n   * @param options - Options\n   */\n  async rm(path: string, options?: RmOptions): Promise<void> {\n    \"use step\";\n    const args: string[] = [];\n    if (options?.recursive) args.push(\"-r\");\n    if (options?.force) args.push(\"-f\");\n    args.push(path);\n\n    const result = await this.sandbox.runCommand(\"rm\", args, {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"rm\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"rm\", path);\n    }\n  }\n\n  /**\n   * Remove a directory.\n   *\n   * @param path - Path to the directory\n   * @param options - Options\n   */\n  async rmdir(path: string, options?: { signal?: AbortSignal }): Promise<void> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\"rmdir\", [path], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"rmdir\", path);\n      }\n      if (stderr.includes(\"not empty\")) {\n        throw fsError(\"ENOTEMPTY\", \"directory not empty\", \"rmdir\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"rmdir\", path);\n    }\n  }\n\n  /**\n   * Rename a file or directory.\n   *\n   * @param oldPath - Current path\n   * @param newPath - New path\n   * @param options - Options\n   */\n  async rename(\n    oldPath: string,\n    newPath: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<void> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\"mv\", [oldPath, newPath], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"rename\", oldPath);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"rename\", oldPath);\n    }\n  }\n\n  /**\n   * Copy a file.\n   *\n   * @param src - Source path\n   * @param dest - Destination path\n   * @param options - Options\n   */\n  async copyFile(\n    src: string,\n    dest: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<void> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\"cp\", [src, dest], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"copyfile\", src);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"copyfile\", src);\n    }\n  }\n\n  /**\n   * Test whether a file exists and the user has the specified permissions.\n   *\n   * @param path - Path to the file\n   * @param options - Options\n   */\n  async access(\n    path: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<void> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\"test\", [\"-e\", path], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      throw fsError(\"ENOENT\", \"no such file or directory\", \"access\", path);\n    }\n  }\n\n  /**\n   * Check if a path exists.\n   *\n   * This is a convenience method not in `node:fs/promises` but commonly needed.\n   *\n   * @param path - Path to check\n   * @param options - Options\n   */\n  async exists(\n    path: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<boolean> {\n    const result = await this.sandbox.runCommand(\"test\", [\"-e\", path], {\n      signal: options?.signal,\n    });\n    return result.exitCode === 0;\n  }\n\n  /**\n   * Change file mode (permissions).\n   *\n   * @param path - Path to the file\n   * @param mode - File mode (e.g., 0o755 or \"755\")\n   * @param options - Options\n   */\n  async chmod(\n    path: string,\n    mode: number | string,\n    options?: { signal?: AbortSignal },\n  ): Promise<void> {\n    \"use step\";\n    const modeStr = typeof mode === \"number\" ? mode.toString(8) : mode;\n    const result = await this.sandbox.runCommand(\"chmod\", [modeStr, path], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"chmod\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"chmod\", path);\n    }\n  }\n\n  /**\n   * Change file owner and group.\n   *\n   * @param path - Path to the file\n   * @param uid - User ID\n   * @param gid - Group ID\n   * @param options - Options\n   */\n  async chown(\n    path: string,\n    uid: number,\n    gid: number,\n    options?: { signal?: AbortSignal },\n  ): Promise<void> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\n      \"chown\",\n      [`${uid}:${gid}`, path],\n      { signal: options?.signal },\n    );\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"chown\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"chown\", path);\n    }\n  }\n\n  /**\n   * Create a symbolic link.\n   *\n   * @param target - The target of the symbolic link\n   * @param path - The path of the symbolic link to create\n   * @param options - Options\n   */\n  async symlink(\n    target: string,\n    path: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<void> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\"ln\", [\"-s\", target, path], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"File exists\")) {\n        throw fsError(\"EEXIST\", \"file already exists\", \"symlink\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"symlink\", path);\n    }\n  }\n\n  /**\n   * Read the value of a symbolic link.\n   *\n   * @param path - Path to the symbolic link\n   * @param options - Options\n   */\n  async readlink(\n    path: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<string> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\"readlink\", [path], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"readlink\", path);\n      }\n      throw fsError(\"EINVAL\", \"invalid argument\", \"readlink\", path);\n    }\n    return (await result.stdout()).trim();\n  }\n\n  /**\n   * Resolve the real path of a file (resolving symlinks).\n   *\n   * @param path - Path to resolve\n   * @param options - Options\n   */\n  async realpath(\n    path: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<string> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\"realpath\", [path], {\n      signal: options?.signal,\n    });\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"realpath\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"realpath\", path);\n    }\n    return (await result.stdout()).trim();\n  }\n\n  /**\n   * Truncate a file to a specified length.\n   *\n   * @param path - Path to the file\n   * @param len - Length to truncate to (default: 0)\n   * @param options - Options\n   */\n  async truncate(\n    path: string,\n    len?: number,\n    options?: { signal?: AbortSignal },\n  ): Promise<void> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\n      \"truncate\",\n      [\"-s\", String(len ?? 0), path],\n      { signal: options?.signal },\n    );\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      if (stderr.includes(\"No such file or directory\")) {\n        throw fsError(\"ENOENT\", \"no such file or directory\", \"truncate\", path);\n      }\n      throw fsError(\"EACCES\", stderr.trim(), \"truncate\", path);\n    }\n  }\n\n  /**\n   * Create a unique temporary directory.\n   *\n   * @param prefix - The prefix for the temporary directory name\n   * @param options - Options\n   * @returns The path of the created temporary directory\n   */\n  async mkdtemp(\n    prefix: string,\n    options?: { signal?: AbortSignal },\n  ): Promise<string> {\n    \"use step\";\n    const result = await this.sandbox.runCommand(\n      \"mktemp\",\n      [\"-d\", `${prefix}XXXXXX`],\n      { signal: options?.signal },\n    );\n    if (result.exitCode !== 0) {\n      const stderr = await result.stderr();\n      throw fsError(\"EACCES\", stderr.trim(), \"mkdtemp\", prefix);\n    }\n    return (await result.stdout()).trim();\n  }\n}\n"],"mappings":";;AAKA,MAAM,SAAS;AACf,MAAM,UAAU;AAChB,MAAM,UAAU;AAChB,MAAM,UAAU;AAChB,MAAM,UAAU;AAChB,MAAM,UAAU;AAChB,MAAM,UAAU;AAChB,MAAM,WAAW;AAIjB,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AACvB,MAAM,iBAAiB;AACvB,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,kBAAkB;AAoBxB,SAAS,QACP,MACA,SACA,SACA,MACyD;CACzD,MAAM,sBAAM,IAAI,MACd,GAAG,KAAK,IAAI,QAAQ,IAAI,QAAQ,IAAI,KAAK,GAC1C;AAKD,KAAI,OAAO;AACX,KAAI,UAAU;AACd,KAAI,OAAO;AACX,QAAO;;AAwBT,SAAS,cAAc,SAGrB;AACA,KAAI,YAAY,QAAQ,YAAY,OAClC,QAAO,EAAE,UAAU,MAAM;AAE3B,KAAI,OAAO,YAAY,SACrB,QAAO,EAAE,UAAU,SAAS;AAE9B,QAAO;EAAE,UAAU,QAAQ,YAAY;EAAM,QAAQ,QAAQ;EAAQ;;AAGvE,IAAM,eAAN,MAAmB;CAMjB,YACE,AAASA,KACT,AAAiBC,OACjB,AAASC,OACT,AAASC,KACT,AAASC,KACT,AAASC,MACT,AAASC,SACT,AAASC,KACT,AAASC,MACT,AAASC,QACT,AAASC,SACT,AAASC,SACT,AAASC,SACT,AAASC,aACT;EAdS;EACQ;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAET,OAAK,QAAQ,IAAI,KAAK,QAAQ;AAC9B,OAAK,QAAQ,IAAI,KAAK,QAAQ;AAC9B,OAAK,QAAQ,IAAI,KAAK,QAAQ;AAC9B,OAAK,YAAY,IAAI,KAAK,YAAY;;CAGxC,IAAI,OAAe;AACjB,SAAO,KAAK;;CAGd,SAAkB;AAChB,UAAQ,KAAK,OAAO,YAAY;;CAElC,cAAuB;AACrB,UAAQ,KAAK,OAAO,YAAY;;CAElC,gBAAyB;AACvB,UAAQ,KAAK,OAAO,YAAY;;CAElC,oBAA6B;AAC3B,UAAQ,KAAK,OAAO,YAAY;;CAElC,iBAA0B;AACxB,UAAQ,KAAK,OAAO,YAAY;;CAElC,SAAkB;AAChB,UAAQ,KAAK,OAAO,YAAY;;CAElC,WAAoB;AAClB,UAAQ,KAAK,OAAO,YAAY;;;AAIpC,IAAM,gBAAN,MAAoB;CAGlB,YACE,AAAOC,MACP,AAAQC,MACR,AAAOC,YACP;EAHO;EACC;EACD;AAEP,OAAK,OAAO,GAAG,KAAK,WAAW,GAAG,KAAK;;CAGzC,SAAkB;AAChB,SAAO,KAAK,SAAS;;CAEvB,cAAuB;AACrB,SAAO,KAAK,SAAS;;CAEvB,gBAAyB;AACvB,SAAO,KAAK,SAAS;;CAEvB,oBAA6B;AAC3B,SAAO,KAAK,SAAS;;CAEvB,iBAA0B;AACxB,SAAO,KAAK,SAAS;;CAEvB,SAAkB;AAChB,SAAO,KAAK,SAAS;;CAEvB,WAAoB;AAClB,SAAO,KAAK,SAAS;;;AAIzB,SAAS,UAAU,QAAgB;CAEjC,MAAM,QAAQ,OAAO,MAAM,CAAC,MAAM,IAAI;AAEtC,QAAO,IAAI,aACT,SAAS,MAAM,KAAM,GAAG,EACxB,SAAS,MAAM,IAAK,GAAG,EACvB,SAAS,MAAM,IAAK,GAAG,EACvB,SAAS,MAAM,IAAK,GAAG,EACvB,SAAS,MAAM,IAAK,GAAG,EACvB,GACA,SAAS,MAAM,KAAM,GAAG,EACxB,SAAS,MAAM,IAAK,GAAG,EACvB,SAAS,MAAM,IAAK,GAAG,EACvB,SAAS,MAAM,KAAM,GAAG,EACxB,WAAW,MAAM,GAAI,GAAG,KACxB,WAAW,MAAM,GAAI,GAAG,KACxB,WAAW,MAAM,GAAI,GAAG,KACxB,WAAW,MAAM,GAAI,GAAG,IACzB;;AAGH,SAAS,YAAY,QAAgB,MAAc;CACjD,MAAM,QAAQ,OAAO,MAAM,CAAC,MAAM,IAAI;CACtC,MAAM,OAAO,MAAM;CACnB,MAAM,OAAO,MAAM;AAEnB,KAAI,CAAC,KACH,OAAM,QAAQ,UAAU,6BAA6B,WAAW,KAAK;AAGvE,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,wBAAwB,OAAO;AAIjD,QAAO,IAAI,cAAc,MADN,oBAAoB,SAAS,gBACL,KAAK;;AAIlD,MAAM,cAAc;AAEpB,MAAMC,sBAA8C;CAClD,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACJ;AAED,IAAa,aAAb,MAAwB;;CAKtB,YAAY,SAAwB;AAClC,OAAK,UAAU;;CAmBjB,MAAM,SACJ,MACA,SAC8B;EAC9B,MAAM,EAAE,UAAU,WAAW,cAAc,QAAQ;EACnD,MAAM,SAAS,MAAM,KAAK,QAAQ,iBAAiB,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC;AACxE,MAAI,WAAW,KACb,OAAM,QAAQ,UAAU,6BAA6B,QAAQ,KAAK;AAEpE,SAAO,WAAW,IAAI,YAAY,SAAS,CAAC,OAAO,OAAO,GAAG;;;;;;;;;CAU/D,MAAM,UACJ,MACA,MACA,SAGe;AACf;EACA,MAAM,EAAE,UAAU,WAChB,OAAO,YAAY,WACf;GAAE,UAAU;GAAS,QAAQ;GAAW,GACxC;GAAE,UAAU,SAAS;GAAU,QAAQ,SAAS;GAAQ;EAC9D,IAAIC;AACJ,MAAI,OAAO,SAAS,SAClB,WAAU,OAAO,KAAK,MAAM,YAAY,OAAO;WACtC,OAAO,SAAS,KAAK,CAC9B,WAAU;MAEV,WAAU,OAAO,KAAK,KAAK;AAE7B,QAAM,KAAK,QAAQ,WAAW,CAAC;GAAE;GAAM;GAAS,CAAC,EAAE,EAAE,QAAQ,CAAC;;;;;;;;;CAUhE,MAAM,WACJ,MACA,MACA,SAGe;AACf;EACA,MAAM,EAAE,UAAU,WAChB,OAAO,YAAY,WACf;GAAE,UAAU;GAAS,QAAQ;GAAW,GACxC;GAAE,UAAU,SAAS;GAAU,QAAQ,SAAS;GAAQ;EAC9D,IAAIC;AACJ,MAAI,OAAO,SAAS,SAClB,iBAAgB,OAAO,KAAK,MAAM,YAAY,OAAO;WAC5C,OAAO,SAAS,KAAK,CAC9B,iBAAgB;MAEhB,iBAAgB,OAAO,KAAK,KAAK;EAGnC,MAAM,WAAW,MAAM,KAAK,QAAQ,iBAAiB,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC;EAC1E,MAAM,UACJ,aAAa,OACT,OAAO,OAAO,CAAC,UAAU,cAAc,CAAC,GACxC;AACN,QAAM,KAAK,QAAQ,WAAW,CAAC;GAAE;GAAM;GAAS,CAAC,EAAE,EAAE,QAAQ,CAAC;;;;;;;;CAShE,MAAM,MACJ,MACA,SAC6B;AAC7B;EACA,MAAM,OACJ,OAAO,YAAY,WAAW,EAAE,WAAW,OAAO,GAAI,WAAW,EAAE;AACrE,MAAI,KAAK,WAAW;GAClB,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,SAAS,CAAC,MAAM,KAAK,EAAE,EAClE,QAAQ,KAAK,QACd,CAAC;AACF,OAAI,OAAO,aAAa,EAEtB,OAAM,QACJ,WAFa,MAAM,OAAO,QAAQ,EAG3B,MAAM,IAAI,qBACjB,SACA,KACD;AAEH;;AAEF,QAAM,KAAK,QAAQ,MAAM,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC;;CAkBzD,MAAM,QACJ,MACA,SAC8B;AAC9B;AACA,MAAI,SAAS,eAAe;GAE1B,MAAMC,WAAS,MAAM,KAAK,QAAQ,WAChC,QACA;IAAC;IAAM;IAAa;IAAK;IAAa;IAAK;IAAW;IAAW,EACjE,EAAE,QAAQ,SAAS,QAAQ,CAC5B;AACD,OAAIA,SAAO,aAAa,GAAG;IACzB,MAAM,SAAS,MAAMA,SAAO,QAAQ;AACpC,QAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,WAAW,KAAK;AAEvE,UAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,WAAW,KAAK;;AAKzD,WAHe,MAAMA,SAAO,QAAQ,EACf,MAAM,CAAC,MAAM,KAAK,CAAC,OAAO,QAAQ,CAE1C,KAAK,SAAS,YAAY,MAAM,KAAK,CAAC;;EAGrD,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,MAAM,CAAC,MAAM,KAAK,EAAE,EAC/D,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,WAAW,KAAK;AAEvE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,WAAW,KAAK;;AAGzD,UADe,MAAM,OAAO,QAAQ,EACtB,MAAM,CAAC,MAAM,KAAK,CAAC,OAAO,QAAQ;;;;;;;;CASlD,MAAM,KAAK,MAAc,SAAoD;AAC3E;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAChC,QACA;GAAC;GAAM;GAAM;GAAa;GAAK,EAC/B,EAAE,QAAQ,SAAS,QAAQ,CAC5B;AACD,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,QAAQ,KAAK;AAEpE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,QAAQ,KAAK;;AAEtD,SAAO,UAAU,MAAM,OAAO,QAAQ,CAAC;;;;;;;;CASzC,MAAM,MACJ,MACA,SACgB;AAChB;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAChC,QACA;GAAC;GAAM;GAAa;GAAK,EACzB,EAAE,QAAQ,SAAS,QAAQ,CAC5B;AACD,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,SAAS,KAAK;AAErE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,SAAS,KAAK;;AAEvD,SAAO,UAAU,MAAM,OAAO,QAAQ,CAAC;;;;;;;;CASzC,MAAM,OACJ,MACA,SACe;AACf;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,MAAM,CAAC,KAAK,EAAE,EACzD,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,UAAU,KAAK;AAEtE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,UAAU,KAAK;;;;;;;;;CAU1D,MAAM,GAAG,MAAc,SAAoC;AACzD;EACA,MAAMC,OAAiB,EAAE;AACzB,MAAI,SAAS,UAAW,MAAK,KAAK,KAAK;AACvC,MAAI,SAAS,MAAO,MAAK,KAAK,KAAK;AACnC,OAAK,KAAK,KAAK;EAEf,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,MAAM,MAAM,EACvD,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,MAAM,KAAK;AAElE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,MAAM,KAAK;;;;;;;;;CAUtD,MAAM,MAAM,MAAc,SAAmD;AAC3E;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,SAAS,CAAC,KAAK,EAAE,EAC5D,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,SAAS,KAAK;AAErE,OAAI,OAAO,SAAS,YAAY,CAC9B,OAAM,QAAQ,aAAa,uBAAuB,SAAS,KAAK;AAElE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,SAAS,KAAK;;;;;;;;;;CAWzD,MAAM,OACJ,SACA,SACA,SACe;AACf;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,MAAM,CAAC,SAAS,QAAQ,EAAE,EACrE,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,UAAU,QAAQ;AAEzE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,UAAU,QAAQ;;;;;;;;;;CAW7D,MAAM,SACJ,KACA,MACA,SACe;AACf;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,MAAM,CAAC,KAAK,KAAK,EAAE,EAC9D,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,YAAY,IAAI;AAEvE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,YAAY,IAAI;;;;;;;;;CAU3D,MAAM,OACJ,MACA,SACe;AACf;AAIA,OAHe,MAAM,KAAK,QAAQ,WAAW,QAAQ,CAAC,MAAM,KAAK,EAAE,EACjE,QAAQ,SAAS,QAClB,CAAC,EACS,aAAa,EACtB,OAAM,QAAQ,UAAU,6BAA6B,UAAU,KAAK;;;;;;;;;;CAYxE,MAAM,OACJ,MACA,SACkB;AAIlB,UAHe,MAAM,KAAK,QAAQ,WAAW,QAAQ,CAAC,MAAM,KAAK,EAAE,EACjE,QAAQ,SAAS,QAClB,CAAC,EACY,aAAa;;;;;;;;;CAU7B,MAAM,MACJ,MACA,MACA,SACe;AACf;EACA,MAAM,UAAU,OAAO,SAAS,WAAW,KAAK,SAAS,EAAE,GAAG;EAC9D,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,SAAS,CAAC,SAAS,KAAK,EAAE,EACrE,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,SAAS,KAAK;AAErE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,SAAS,KAAK;;;;;;;;;;;CAYzD,MAAM,MACJ,MACA,KACA,KACA,SACe;AACf;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAChC,SACA,CAAC,GAAG,IAAI,GAAG,OAAO,KAAK,EACvB,EAAE,QAAQ,SAAS,QAAQ,CAC5B;AACD,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,SAAS,KAAK;AAErE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,SAAS,KAAK;;;;;;;;;;CAWzD,MAAM,QACJ,QACA,MACA,SACe;AACf;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,MAAM;GAAC;GAAM;GAAQ;GAAK,EAAE,EACvE,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,cAAc,CAChC,OAAM,QAAQ,UAAU,uBAAuB,WAAW,KAAK;AAEjE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,WAAW,KAAK;;;;;;;;;CAU3D,MAAM,SACJ,MACA,SACiB;AACjB;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,YAAY,CAAC,KAAK,EAAE,EAC/D,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;AAEzB,QADe,MAAM,OAAO,QAAQ,EACzB,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,YAAY,KAAK;AAExE,SAAM,QAAQ,UAAU,oBAAoB,YAAY,KAAK;;AAE/D,UAAQ,MAAM,OAAO,QAAQ,EAAE,MAAM;;;;;;;;CASvC,MAAM,SACJ,MACA,SACiB;AACjB;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAAW,YAAY,CAAC,KAAK,EAAE,EAC/D,QAAQ,SAAS,QAClB,CAAC;AACF,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,YAAY,KAAK;AAExE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,YAAY,KAAK;;AAE1D,UAAQ,MAAM,OAAO,QAAQ,EAAE,MAAM;;;;;;;;;CAUvC,MAAM,SACJ,MACA,KACA,SACe;AACf;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAChC,YACA;GAAC;GAAM,OAAO,OAAO,EAAE;GAAE;GAAK,EAC9B,EAAE,QAAQ,SAAS,QAAQ,CAC5B;AACD,MAAI,OAAO,aAAa,GAAG;GACzB,MAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,OAAI,OAAO,SAAS,4BAA4B,CAC9C,OAAM,QAAQ,UAAU,6BAA6B,YAAY,KAAK;AAExE,SAAM,QAAQ,UAAU,OAAO,MAAM,EAAE,YAAY,KAAK;;;;;;;;;;CAW5D,MAAM,QACJ,QACA,SACiB;AACjB;EACA,MAAM,SAAS,MAAM,KAAK,QAAQ,WAChC,UACA,CAAC,MAAM,GAAG,OAAO,QAAQ,EACzB,EAAE,QAAQ,SAAS,QAAQ,CAC5B;AACD,MAAI,OAAO,aAAa,EAEtB,OAAM,QAAQ,WADC,MAAM,OAAO,QAAQ,EACL,MAAM,EAAE,WAAW,OAAO;AAE3D,UAAQ,MAAM,OAAO,QAAQ,EAAE,MAAM"}