noumen 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +237 -93
- package/dist/a2a/index.d.ts +5 -7
- package/dist/a2a/index.js +3 -4
- package/dist/a2a/index.js.map +1 -1
- package/dist/acp/index.d.ts +5 -7
- package/dist/acp/index.js +0 -1
- package/dist/acp/index.js.map +1 -1
- package/dist/{agent-DWE4_P5X.d.ts → agent-D0gl-qYi.d.ts} +89 -34
- package/dist/{chunk-6MMYCGJQ.js → chunk-5HY4IYNT.js} +1529 -2321
- package/dist/chunk-5HY4IYNT.js.map +1 -0
- package/dist/chunk-BC5BLWBC.js +21 -0
- package/dist/chunk-BC5BLWBC.js.map +1 -0
- package/dist/{chunk-XZN4QZLK.js → chunk-CX4BL6PC.js} +25 -15
- package/dist/chunk-CX4BL6PC.js.map +1 -0
- package/dist/{chunk-5GEX6ZSB.js → chunk-HQISH4D7.js} +60 -1
- package/dist/chunk-HQISH4D7.js.map +1 -0
- package/dist/{chunk-Y45R3PQL.js → chunk-NUCJXOUV.js} +32 -18
- package/dist/{chunk-Y45R3PQL.js.map → chunk-NUCJXOUV.js.map} +1 -1
- package/dist/chunk-OPFFLQZL.js +40 -0
- package/dist/chunk-OPFFLQZL.js.map +1 -0
- package/dist/chunk-PDEAJ272.js +660 -0
- package/dist/chunk-PDEAJ272.js.map +1 -0
- package/dist/chunk-PKHLGGEC.js +115 -0
- package/dist/chunk-PKHLGGEC.js.map +1 -0
- package/dist/chunk-XQTNXRE7.js +176 -0
- package/dist/chunk-XQTNXRE7.js.map +1 -0
- package/dist/chunk-XZPAA5TO.js +817 -0
- package/dist/chunk-XZPAA5TO.js.map +1 -0
- package/dist/cli/index.js +77 -42
- package/dist/cli/index.js.map +1 -1
- package/dist/client/index.d.ts +1 -2
- package/dist/client/index.js +0 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client-JJFLE6RT.js +9 -0
- package/dist/{computer-BPdxSo6X.d.ts → computer-DzMR92tK.d.ts} +1 -1
- package/dist/docker.d.ts +2 -2
- package/dist/docker.js +0 -1
- package/dist/docker.js.map +1 -1
- package/dist/e2b.d.ts +2 -2
- package/dist/e2b.js +0 -1
- package/dist/e2b.js.map +1 -1
- package/dist/freestyle.d.ts +2 -2
- package/dist/freestyle.js +0 -1
- package/dist/freestyle.js.map +1 -1
- package/dist/{headless-FFU2DESQ.js → headless-25DU4MJQ.js} +1 -3
- package/dist/{headless-FFU2DESQ.js.map → headless-25DU4MJQ.js.map} +1 -1
- package/dist/{history-snip-64GYP4ZL.js → history-snip-HAWNAYKY.js} +1 -2
- package/dist/index.d.ts +351 -72
- package/dist/index.js +54 -55
- package/dist/jsonrpc/index.js +0 -1
- package/dist/local.d.ts +168 -0
- package/dist/local.js +40 -0
- package/dist/local.js.map +1 -0
- package/dist/lsp/index.d.ts +4 -5
- package/dist/lsp/index.js +0 -1
- package/dist/{lsp-PS3BWIHC.js → lsp-3APWNKB2.js} +1 -2
- package/dist/{manager-DLXK63XC.js → manager-Z5EQ7YYV.js} +1 -2
- package/dist/mcp/index.d.ts +16 -8
- package/dist/mcp/index.js +5 -6
- package/dist/mcp/index.js.map +1 -1
- package/dist/{mcp-auth-AEI2R4ZC.js → mcp-auth-NOIQPF7W.js} +1 -2
- package/dist/{provider-factory-TUHU3DIG.js → provider-factory-KNBSHXJ6.js} +3 -3
- package/dist/{render-GRN4ZSSW.js → render-4VEODRK7.js} +1 -2
- package/dist/{resolve-6KUZNEYW.js → resolve-AGQZFMKD.js} +3 -3
- package/dist/sandbox-DAqQo0Tj.d.ts +49 -0
- package/dist/sandbox-index-ODNREIFA.js +32 -0
- package/dist/sandbox-index-ODNREIFA.js.map +1 -0
- package/dist/server/index.d.ts +18 -7
- package/dist/server/index.js +9 -5
- package/dist/server/index.js.map +1 -1
- package/dist/{server-BzNGKTP6.d.ts → server-DFXdlqyX.d.ts} +1 -1
- package/dist/{spinner-OJNR6NFO.js → spinner-72JEISPK.js} +1 -2
- package/dist/sprites.d.ts +2 -2
- package/dist/sprites.js +0 -1
- package/dist/sprites.js.map +1 -1
- package/dist/ssh.d.ts +2 -2
- package/dist/ssh.js +0 -1
- package/dist/ssh.js.map +1 -1
- package/dist/{types-DhXwOQwD.d.ts → types-BX4ALqoN.d.ts} +76 -4
- package/dist/{types-kiGBF35b.d.ts → types-DLZNyF5t.d.ts} +125 -1
- package/dist/unsandboxed.d.ts +59 -0
- package/dist/unsandboxed.js +32 -0
- package/dist/unsandboxed.js.map +1 -0
- package/dist/{uuid-RVN2T26F.js → uuid-CVTNAPEB.js} +1 -2
- package/dist/{zod-7YXKWYMC.js → zod-VKURGPRT.js} +1 -2
- package/package.json +35 -50
- package/dist/cache-BlBwXXPS.d.ts +0 -38
- package/dist/chunk-5GEX6ZSB.js.map +0 -1
- package/dist/chunk-6MMYCGJQ.js.map +0 -1
- package/dist/chunk-7IQCQI2G.js +0 -94
- package/dist/chunk-7IQCQI2G.js.map +0 -1
- package/dist/chunk-CCM2AXZG.js +0 -16
- package/dist/chunk-CCM2AXZG.js.map +0 -1
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-HEQQQGK5.js +0 -131
- package/dist/chunk-HEQQQGK5.js.map +0 -1
- package/dist/chunk-I3JTUFPK.js +0 -171
- package/dist/chunk-I3JTUFPK.js.map +0 -1
- package/dist/chunk-XZN4QZLK.js.map +0 -1
- package/dist/chunk-ZXSDKBYB.js +0 -474
- package/dist/chunk-ZXSDKBYB.js.map +0 -1
- package/dist/client-CRRO2376.js +0 -10
- package/dist/providers/anthropic.d.ts +0 -19
- package/dist/providers/anthropic.js +0 -36
- package/dist/providers/anthropic.js.map +0 -1
- package/dist/providers/bedrock.d.ts +0 -39
- package/dist/providers/bedrock.js +0 -56
- package/dist/providers/bedrock.js.map +0 -1
- package/dist/providers/gemini.d.ts +0 -17
- package/dist/providers/gemini.js +0 -262
- package/dist/providers/gemini.js.map +0 -1
- package/dist/providers/ollama.d.ts +0 -13
- package/dist/providers/ollama.js +0 -20
- package/dist/providers/ollama.js.map +0 -1
- package/dist/providers/openai.d.ts +0 -21
- package/dist/providers/openai.js +0 -9
- package/dist/providers/openrouter.d.ts +0 -16
- package/dist/providers/openrouter.js +0 -24
- package/dist/providers/openrouter.js.map +0 -1
- package/dist/providers/vertex.d.ts +0 -42
- package/dist/providers/vertex.js +0 -68
- package/dist/providers/vertex.js.map +0 -1
- package/dist/sandbox-9qeMTNrD.d.ts +0 -126
- package/dist/types-CD0rUKKT.d.ts +0 -109
- package/dist/uuid-RVN2T26F.js.map +0 -1
- package/dist/zod-7YXKWYMC.js.map +0 -1
- /package/dist/{chunk-DGUM43GV.js.map → client-JJFLE6RT.js.map} +0 -0
- /package/dist/{client-CRRO2376.js.map → history-snip-HAWNAYKY.js.map} +0 -0
- /package/dist/{history-snip-64GYP4ZL.js.map → lsp-3APWNKB2.js.map} +0 -0
- /package/dist/{lsp-PS3BWIHC.js.map → manager-Z5EQ7YYV.js.map} +0 -0
- /package/dist/{manager-DLXK63XC.js.map → mcp-auth-NOIQPF7W.js.map} +0 -0
- /package/dist/{mcp-auth-AEI2R4ZC.js.map → provider-factory-KNBSHXJ6.js.map} +0 -0
- /package/dist/{provider-factory-TUHU3DIG.js.map → render-4VEODRK7.js.map} +0 -0
- /package/dist/{providers/openai.js.map → resolve-AGQZFMKD.js.map} +0 -0
- /package/dist/{render-GRN4ZSSW.js.map → spinner-72JEISPK.js.map} +0 -0
- /package/dist/{resolve-6KUZNEYW.js.map → uuid-CVTNAPEB.js.map} +0 -0
- /package/dist/{spinner-OJNR6NFO.js.map → zod-VKURGPRT.js.map} +0 -0
package/dist/ssh.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/virtual/ssh-fs.ts","../src/virtual/ssh-computer.ts","../src/virtual/ssh-sandbox.ts"],"sourcesContent":["import * as pathMod from \"node:path\";\nimport type { VirtualFs, FileEntry, FileStat, ReadOptions } from \"./fs.js\";\nimport type { SshClient, SshSftpSession } from \"./ssh-computer.js\";\n\nexport interface SshFsOptions {\n /** A connected ssh2 Client instance. */\n client: SshClient;\n /** Working directory for relative path resolution (default: /). */\n workingDir?: string;\n}\n\n/**\n * VirtualFs backed by SFTP file operations over SSH.\n *\n * Uses the ssh2 Client's SFTP subsystem for all file I/O. The SFTP session\n * is opened lazily on the first operation and reused for the lifetime of\n * the SshFs instance.\n *\n * Requires `ssh2` as an optional peer dependency.\n * The caller is responsible for the Client lifecycle.\n */\nexport class SshFs implements VirtualFs {\n private client: SshClient;\n private workingDir: string;\n private sftpSession: SshSftpSession | null = null;\n private sftpPromise: Promise<SshSftpSession> | null = null;\n\n constructor(opts: SshFsOptions) {\n this.client = opts.client;\n this.workingDir = opts.workingDir ?? \"/\";\n }\n\n private getSftp(): Promise<SshSftpSession> {\n if (this.sftpSession) return Promise.resolve(this.sftpSession);\n if (this.sftpPromise) return this.sftpPromise;\n this.sftpPromise = new Promise<SshSftpSession>((resolve, reject) => {\n this.client.sftp((err, sftp) => {\n if (err) {\n this.sftpPromise = null;\n reject(err);\n } else {\n this.sftpSession = sftp;\n resolve(sftp);\n }\n });\n });\n return this.sftpPromise;\n }\n\n private resolvePath(p: string): string {\n if (p.includes(\"\\0\")) {\n throw new Error(\"Path contains null bytes\");\n }\n const normalizedBase = this.workingDir.endsWith(\"/\")\n ? this.workingDir\n : this.workingDir + \"/\";\n if (p.startsWith(\"/\")) {\n const normalized = pathMod.normalize(p);\n if (\n normalized !== this.workingDir &&\n !normalized.startsWith(normalizedBase)\n ) {\n throw new Error(\n `Absolute path \"${p}\" is outside working directory \"${this.workingDir}\"`,\n );\n }\n return normalized;\n }\n const resolved = pathMod.resolve(this.workingDir, p);\n if (\n resolved !== this.workingDir &&\n !resolved.startsWith(normalizedBase)\n ) {\n throw new Error(\n `Path \"${p}\" escapes working directory \"${this.workingDir}\"`,\n );\n }\n return resolved;\n }\n\n async readFile(path: string, _opts?: ReadOptions): Promise<string> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n return new Promise<string>((resolve, reject) => {\n sftp.readFile(resolved, { encoding: \"utf8\" }, (err, data) => {\n if (err) reject(new Error(`SshFs readFile failed: ${err.message}`));\n else resolve(data as string);\n });\n });\n }\n\n async readFileBytes(path: string, maxBytes?: number): Promise<Buffer> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n\n if (maxBytes === undefined) {\n return new Promise<Buffer>((resolve, reject) => {\n sftp.readFile(resolved, (err, data) => {\n if (err) reject(new Error(`SshFs readFileBytes failed: ${err.message}`));\n else resolve(data);\n });\n });\n }\n\n return new Promise<Buffer>((resolve, reject) => {\n sftp.open(resolved, \"r\", (err, handle) => {\n if (err) {\n reject(new Error(`SshFs readFileBytes failed: ${err.message}`));\n return;\n }\n const buf = Buffer.alloc(maxBytes);\n sftp.read(handle, buf, 0, maxBytes, 0, (readErr, bytesRead, readBuf) => {\n sftp.close(handle, () => {});\n if (readErr) {\n reject(new Error(`SshFs readFileBytes failed: ${readErr.message}`));\n } else {\n resolve(readBuf.subarray(0, bytesRead));\n }\n });\n });\n });\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n const dir = pathMod.dirname(resolved);\n await this.mkdirRecursive(sftp, dir);\n return new Promise<void>((resolve, reject) => {\n sftp.writeFile(resolved, content, (err) => {\n if (err) reject(new Error(`SshFs writeFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n async appendFile(path: string, content: string): Promise<void> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n const dir = pathMod.dirname(resolved);\n await this.mkdirRecursive(sftp, dir);\n return new Promise<void>((resolve, reject) => {\n sftp.appendFile(resolved, content, (err) => {\n if (err) reject(new Error(`SshFs appendFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n async deleteFile(\n path: string,\n opts?: { recursive?: boolean },\n ): Promise<void> {\n const resolved = this.resolvePath(path);\n if (opts?.recursive) {\n const sftp = await this.getSftp();\n await this.rmRecursive(sftp, resolved);\n return;\n }\n const sftp = await this.getSftp();\n return new Promise<void>((resolve, reject) => {\n sftp.unlink(resolved, (err) => {\n if (err) reject(new Error(`SshFs deleteFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n async mkdir(path: string, opts?: { recursive?: boolean }): Promise<void> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n if (opts?.recursive) {\n await this.mkdirRecursive(sftp, resolved);\n return;\n }\n return new Promise<void>((resolve, reject) => {\n sftp.mkdir(resolved, (err) => {\n if (err) reject(new Error(`SshFs mkdir failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n async readdir(\n path: string,\n _opts?: { recursive?: boolean },\n ): Promise<FileEntry[]> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n return new Promise<FileEntry[]>((resolve, reject) => {\n sftp.readdir(resolved, (err, list) => {\n if (err) {\n reject(new Error(`SshFs readdir failed: ${err.message}`));\n return;\n }\n const entries: FileEntry[] = list.map((item) => ({\n name: item.filename,\n path: pathMod.join(resolved, item.filename),\n isDirectory: item.attrs.isDirectory(),\n isFile: item.attrs.isFile(),\n }));\n resolve(entries);\n });\n });\n }\n\n async exists(path: string): Promise<boolean> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n return new Promise<boolean>((resolve) => {\n sftp.stat(resolved, (err) => {\n resolve(!err);\n });\n });\n }\n\n async stat(path: string): Promise<FileStat> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n return new Promise<FileStat>((resolve, reject) => {\n sftp.stat(resolved, (err, stats) => {\n if (err) {\n reject(new Error(`SshFs stat failed: ${err.message}`));\n return;\n }\n resolve({\n size: stats.size,\n isDirectory: stats.isDirectory(),\n isFile: stats.isFile(),\n modifiedAt: stats.mtime > 0 ? new Date(stats.mtime * 1000) : undefined,\n });\n });\n });\n }\n\n private async mkdirRecursive(\n sftp: SshSftpSession,\n dir: string,\n ): Promise<void> {\n const parts = dir.split(\"/\").filter(Boolean);\n let current = \"/\";\n for (const part of parts) {\n current = pathMod.join(current, part);\n await new Promise<void>((resolve) => {\n sftp.mkdir(current, () => {\n resolve();\n });\n });\n }\n }\n\n private async rmRecursive(\n sftp: SshSftpSession,\n target: string,\n ): Promise<void> {\n const isDir = await new Promise<boolean>((resolve) => {\n sftp.stat(target, (err, stats) => {\n if (err) resolve(false);\n else resolve(stats.isDirectory());\n });\n });\n\n if (!isDir) {\n return new Promise<void>((resolve, reject) => {\n sftp.unlink(target, (err) => {\n if (err) reject(new Error(`SshFs deleteFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n const entries = await new Promise<Array<{ filename: string; attrs: { isDirectory(): boolean } }>>(\n (resolve, reject) => {\n sftp.readdir(target, (err, list) => {\n if (err) reject(new Error(`SshFs deleteFile failed: ${err.message}`));\n else resolve(list);\n });\n },\n );\n\n for (const entry of entries) {\n await this.rmRecursive(sftp, pathMod.join(target, entry.filename));\n }\n\n return new Promise<void>((resolve, reject) => {\n sftp.rmdir(target, (err) => {\n if (err) reject(new Error(`SshFs deleteFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n}\n","import type { VirtualComputer, ExecOptions, CommandResult } from \"./computer.js\";\n\n/**\n * Minimal subset of the ssh2 Channel interface used by SshComputer / SshFs.\n * Avoids a hard import of ssh2 at the module level.\n */\nexport interface SshChannel {\n on(event: string, listener: (...args: any[]) => void): SshChannel;\n stderr: { on(event: string, listener: (...args: any[]) => void): unknown };\n destroy?(): void;\n}\n\n/**\n * Minimal subset of the ssh2 SFTPWrapper interface used by SshFs.\n */\nexport interface SshSftpSession {\n readFile(\n path: string,\n callback: (err: Error | undefined, data: Buffer) => void,\n ): void;\n readFile(\n path: string,\n opts: { encoding: string },\n callback: (err: Error | undefined, data: string) => void,\n ): void;\n writeFile(\n path: string,\n data: string | Buffer,\n callback: (err: Error | undefined) => void,\n ): void;\n appendFile(\n path: string,\n data: string | Buffer,\n callback: (err: Error | undefined) => void,\n ): void;\n unlink(path: string, callback: (err: Error | undefined) => void): void;\n rmdir(path: string, callback: (err: Error | undefined) => void): void;\n mkdir(path: string, callback: (err: Error | undefined) => void): void;\n readdir(\n path: string,\n callback: (\n err: Error | undefined,\n list: Array<{\n filename: string;\n longname: string;\n attrs: { size: number; isDirectory(): boolean; isFile(): boolean; mtime: number; atime: number };\n }>,\n ) => void,\n ): void;\n stat(\n path: string,\n callback: (\n err: Error | undefined,\n stats: { size: number; isDirectory(): boolean; isFile(): boolean; mtime: number; atime: number },\n ) => void,\n ): void;\n open(\n path: string,\n flags: string,\n callback: (err: Error | undefined, handle: Buffer) => void,\n ): void;\n read(\n handle: Buffer,\n buffer: Buffer,\n offset: number,\n length: number,\n position: number,\n callback: (err: Error | undefined, bytesRead: number, buf: Buffer) => void,\n ): void;\n close(handle: Buffer, callback: (err: Error | undefined) => void): void;\n end(): void;\n}\n\n/**\n * Minimal subset of the ssh2 Client interface used by SshComputer and SshFs.\n * Avoids a hard import of ssh2 at the module level.\n */\nexport interface SshClient {\n exec(\n command: string,\n callback: (err: Error | undefined, channel: SshChannel) => void,\n ): void;\n exec(\n command: string,\n opts: Record<string, unknown>,\n callback: (err: Error | undefined, channel: SshChannel) => void,\n ): void;\n sftp(\n callback: (err: Error | undefined, sftp: SshSftpSession) => void,\n ): void;\n end(): void;\n on(event: string, listener: (...args: any[]) => void): this;\n}\n\nexport interface SshComputerOptions {\n /** A connected ssh2 Client instance. */\n client: SshClient;\n /** Default working directory for commands (default: /). */\n defaultCwd?: string;\n /** Default timeout in ms for commands (default: 30000). */\n defaultTimeout?: number;\n}\n\n/**\n * VirtualComputer backed by command execution over SSH.\n *\n * Requires `ssh2` as an optional peer dependency.\n * The caller is responsible for the Client lifecycle (connect, end).\n */\nexport class SshComputer implements VirtualComputer {\n private client: SshClient;\n private defaultCwd: string;\n private defaultTimeout: number;\n\n constructor(opts: SshComputerOptions) {\n this.client = opts.client;\n this.defaultCwd = opts.defaultCwd ?? \"/\";\n this.defaultTimeout = opts.defaultTimeout ?? 30_000;\n }\n\n async executeCommand(\n command: string,\n opts?: ExecOptions,\n ): Promise<CommandResult> {\n const cwd = opts?.cwd ?? this.defaultCwd;\n const timeout = opts?.timeout ?? this.defaultTimeout;\n\n let envPrefix = \"\";\n if (opts?.env) {\n envPrefix = Object.entries(opts.env)\n .map(([k, v]) => `${k}=${shellEscape(v)}`)\n .join(\" \") + \" \";\n }\n\n const fullCommand = `cd ${shellEscape(cwd)} && ${envPrefix}${command}`;\n\n return new Promise<CommandResult>((resolve, reject) => {\n this.client.exec(fullCommand, (err, channel) => {\n if (err) {\n reject(err);\n return;\n }\n\n const stdoutBufs: Buffer[] = [];\n const stderrBufs: Buffer[] = [];\n\n const timer = setTimeout(() => {\n channel.destroy?.();\n resolve({\n exitCode: 1,\n stdout: Buffer.concat(stdoutBufs).toString(\"utf-8\"),\n stderr:\n Buffer.concat(stderrBufs).toString(\"utf-8\") +\n \"\\n[timeout after \" + timeout + \"ms]\",\n });\n }, timeout);\n\n channel.on(\"data\", (chunk: Buffer) => {\n stdoutBufs.push(Buffer.from(chunk));\n });\n\n channel.stderr.on(\"data\", (chunk: Buffer) => {\n stderrBufs.push(Buffer.from(chunk));\n });\n\n channel.on(\"close\", (code: number) => {\n clearTimeout(timer);\n resolve({\n exitCode: code ?? 0,\n stdout: Buffer.concat(stdoutBufs).toString(\"utf-8\"),\n stderr: Buffer.concat(stderrBufs).toString(\"utf-8\"),\n });\n });\n\n channel.on(\"error\", (channelErr: Error) => {\n clearTimeout(timer);\n reject(channelErr);\n });\n });\n });\n }\n}\n\nfunction shellEscape(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n","import type { Sandbox } from \"./sandbox.js\";\nimport { SshFs } from \"./ssh-fs.js\";\nimport { SshComputer, type SshClient } from \"./ssh-computer.js\";\nimport { createFsProxy, createComputerProxy } from \"./proxy.js\";\n\nexport interface SshSandboxOptions {\n /**\n * A pre-connected ssh2 Client instance. When provided the sandbox uses\n * this client directly — no auto-connect occurs and `dispose()` will\n * **not** call `client.end()`.\n *\n * When omitted, a new ssh2 Client is created and connected on the first\n * `init()` call using `host`, `port`, `username`, and the provided\n * credentials. The client is ended when `dispose()` is called.\n */\n client?: SshClient;\n /**\n * SSH hostname. Required when `client` is omitted; ignored when `client`\n * is provided.\n */\n host?: string;\n /** SSH port (default: 22). Only used during auto-connect. */\n port?: number;\n /** SSH username (default: \"root\"). Only used during auto-connect. */\n username?: string;\n /** Password for password-based authentication. Only used during auto-connect. */\n password?: string;\n /** Private key for key-based authentication (PEM string or Buffer). Only used during auto-connect. */\n privateKey?: string | Buffer;\n /** Passphrase for an encrypted private key. Only used during auto-connect. */\n passphrase?: string;\n /** Working directory on the remote host. */\n cwd?: string;\n /** Default timeout (ms) for shell commands. */\n defaultTimeout?: number;\n}\n\n/**\n * Create a `Sandbox` backed by a remote host over SSH.\n * Requires `ssh2` as an optional peer dependency.\n *\n * **Auto-connect:** When `client` is omitted and `host` is provided,\n * an ssh2 Client is created and connected lazily on the first `init()`\n * call. The connection identifier (`host:port`) is available through\n * `sandboxId()` for session persistence.\n *\n * **Explicit client:** When `client` is provided, `init()` binds it\n * immediately. `dispose()` is a no-op — the caller owns the client's\n * lifecycle.\n *\n * @example\n * ```ts\n * // Auto-connect with private key\n * const sandbox = SshSandbox({\n * host: \"dev.example.com\",\n * username: \"deploy\",\n * privateKey: fs.readFileSync(\"~/.ssh/id_ed25519\"),\n * cwd: \"/home/deploy/project\",\n * });\n *\n * // Explicit client (lifecycle managed externally)\n * const sandbox = SshSandbox({ client: myConnectedClient, cwd: \"/workspace\" });\n * ```\n */\nexport function SshSandbox(opts: SshSandboxOptions): Sandbox {\n if (opts.client) {\n const c = opts.client;\n return {\n fs: new SshFs({ client: c, workingDir: opts.cwd }),\n computer: new SshComputer({\n client: c,\n defaultCwd: opts.cwd,\n defaultTimeout: opts.defaultTimeout,\n }),\n sandboxId: () =>\n opts.host ? `${opts.host}:${opts.port ?? 22}` : undefined,\n };\n }\n\n if (!opts.host) {\n throw new Error(\"SshSandbox requires either `client` or `host`\");\n }\n\n const fsProxy = createFsProxy();\n const computerProxy = createComputerProxy();\n const identifier = `${opts.host}:${opts.port ?? 22}`;\n let clientRef: SshClient | null = null;\n let autoCreated = false;\n let initPromise: Promise<void> | null = null;\n\n async function doInit(): Promise<void> {\n const modName = \"ssh2\";\n const ssh2 = await import(/* webpackIgnore: true */ modName);\n const ClientClass =\n (ssh2 as any).Client ?? (ssh2 as any).default?.Client;\n if (!ClientClass) {\n throw new Error(\n \"Could not resolve Client class from 'ssh2' package\",\n );\n }\n\n const client: SshClient = new ClientClass();\n await new Promise<void>((resolve, reject) => {\n client.on(\"ready\", () => resolve());\n client.on(\"error\", (err: Error) => reject(err));\n (client as any).connect({\n host: opts.host,\n port: opts.port ?? 22,\n username: opts.username ?? \"root\",\n password: opts.password,\n privateKey: opts.privateKey,\n passphrase: opts.passphrase,\n });\n });\n\n clientRef = client;\n autoCreated = true;\n fsProxy.setTarget(new SshFs({ client, workingDir: opts.cwd }));\n computerProxy.setTarget(\n new SshComputer({\n client,\n defaultCwd: opts.cwd,\n defaultTimeout: opts.defaultTimeout,\n }),\n );\n }\n\n return {\n fs: fsProxy,\n computer: computerProxy,\n sandboxId: () => identifier,\n\n init(): Promise<void> {\n if (!initPromise) {\n initPromise = doInit().catch((err) => {\n initPromise = null;\n throw err;\n });\n }\n return initPromise;\n },\n\n async dispose(): Promise<void> {\n if (initPromise) {\n await initPromise.catch(() => {});\n }\n if (!autoCreated || !clientRef) return;\n try {\n clientRef.end();\n } catch {\n /* best-effort */\n }\n },\n };\n}\n"],"mappings":";;;;;;;AAAA,YAAY,aAAa;AAqBlB,IAAM,QAAN,MAAiC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,cAAqC;AAAA,EACrC,cAA8C;AAAA,EAEtD,YAAY,MAAoB;AAC9B,SAAK,SAAS,KAAK;AACnB,SAAK,aAAa,KAAK,cAAc;AAAA,EACvC;AAAA,EAEQ,UAAmC;AACzC,QAAI,KAAK,YAAa,QAAO,QAAQ,QAAQ,KAAK,WAAW;AAC7D,QAAI,KAAK,YAAa,QAAO,KAAK;AAClC,SAAK,cAAc,IAAI,QAAwB,CAACA,UAAS,WAAW;AAClE,WAAK,OAAO,KAAK,CAAC,KAAK,SAAS;AAC9B,YAAI,KAAK;AACP,eAAK,cAAc;AACnB,iBAAO,GAAG;AAAA,QACZ,OAAO;AACL,eAAK,cAAc;AACnB,UAAAA,SAAQ,IAAI;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,YAAY,GAAmB;AACrC,QAAI,EAAE,SAAS,IAAI,GAAG;AACpB,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AACA,UAAM,iBAAiB,KAAK,WAAW,SAAS,GAAG,IAC/C,KAAK,aACL,KAAK,aAAa;AACtB,QAAI,EAAE,WAAW,GAAG,GAAG;AACrB,YAAM,aAAqB,kBAAU,CAAC;AACtC,UACE,eAAe,KAAK,cACpB,CAAC,WAAW,WAAW,cAAc,GACrC;AACA,cAAM,IAAI;AAAA,UACR,kBAAkB,CAAC,mCAAmC,KAAK,UAAU;AAAA,QACvE;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,UAAM,WAAmB,gBAAQ,KAAK,YAAY,CAAC;AACnD,QACE,aAAa,KAAK,cAClB,CAAC,SAAS,WAAW,cAAc,GACnC;AACA,YAAM,IAAI;AAAA,QACR,SAAS,CAAC,gCAAgC,KAAK,UAAU;AAAA,MAC3D;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,MAAc,OAAsC;AACjE,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,WAAO,IAAI,QAAgB,CAACA,UAAS,WAAW;AAC9C,WAAK,SAAS,UAAU,EAAE,UAAU,OAAO,GAAG,CAAC,KAAK,SAAS;AAC3D,YAAI,IAAK,QAAO,IAAI,MAAM,0BAA0B,IAAI,OAAO,EAAE,CAAC;AAAA,YAC7D,CAAAA,SAAQ,IAAc;AAAA,MAC7B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,MAAc,UAAoC;AACpE,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAM,OAAO,MAAM,KAAK,QAAQ;AAEhC,QAAI,aAAa,QAAW;AAC1B,aAAO,IAAI,QAAgB,CAACA,UAAS,WAAW;AAC9C,aAAK,SAAS,UAAU,CAAC,KAAK,SAAS;AACrC,cAAI,IAAK,QAAO,IAAI,MAAM,+BAA+B,IAAI,OAAO,EAAE,CAAC;AAAA,cAClE,CAAAA,SAAQ,IAAI;AAAA,QACnB,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,QAAgB,CAACA,UAAS,WAAW;AAC9C,WAAK,KAAK,UAAU,KAAK,CAAC,KAAK,WAAW;AACxC,YAAI,KAAK;AACP,iBAAO,IAAI,MAAM,+BAA+B,IAAI,OAAO,EAAE,CAAC;AAC9D;AAAA,QACF;AACA,cAAM,MAAM,OAAO,MAAM,QAAQ;AACjC,aAAK,KAAK,QAAQ,KAAK,GAAG,UAAU,GAAG,CAAC,SAAS,WAAW,YAAY;AACtE,eAAK,MAAM,QAAQ,MAAM;AAAA,UAAC,CAAC;AAC3B,cAAI,SAAS;AACX,mBAAO,IAAI,MAAM,+BAA+B,QAAQ,OAAO,EAAE,CAAC;AAAA,UACpE,OAAO;AACL,YAAAA,SAAQ,QAAQ,SAAS,GAAG,SAAS,CAAC;AAAA,UACxC;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU,MAAc,SAAgC;AAC5D,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,UAAM,MAAc,gBAAQ,QAAQ;AACpC,UAAM,KAAK,eAAe,MAAM,GAAG;AACnC,WAAO,IAAI,QAAc,CAACA,UAAS,WAAW;AAC5C,WAAK,UAAU,UAAU,SAAS,CAAC,QAAQ;AACzC,YAAI,IAAK,QAAO,IAAI,MAAM,2BAA2B,IAAI,OAAO,EAAE,CAAC;AAAA,YAC9D,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAW,MAAc,SAAgC;AAC7D,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,UAAM,MAAc,gBAAQ,QAAQ;AACpC,UAAM,KAAK,eAAe,MAAM,GAAG;AACnC,WAAO,IAAI,QAAc,CAACA,UAAS,WAAW;AAC5C,WAAK,WAAW,UAAU,SAAS,CAAC,QAAQ;AAC1C,YAAI,IAAK,QAAO,IAAI,MAAM,4BAA4B,IAAI,OAAO,EAAE,CAAC;AAAA,YAC/D,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WACJ,MACA,MACe;AACf,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,QAAI,MAAM,WAAW;AACnB,YAAMC,QAAO,MAAM,KAAK,QAAQ;AAChC,YAAM,KAAK,YAAYA,OAAM,QAAQ;AACrC;AAAA,IACF;AACA,UAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,WAAO,IAAI,QAAc,CAACD,UAAS,WAAW;AAC5C,WAAK,OAAO,UAAU,CAAC,QAAQ;AAC7B,YAAI,IAAK,QAAO,IAAI,MAAM,4BAA4B,IAAI,OAAO,EAAE,CAAC;AAAA,YAC/D,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,MAAc,MAA+C;AACvE,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,QAAI,MAAM,WAAW;AACnB,YAAM,KAAK,eAAe,MAAM,QAAQ;AACxC;AAAA,IACF;AACA,WAAO,IAAI,QAAc,CAACA,UAAS,WAAW;AAC5C,WAAK,MAAM,UAAU,CAAC,QAAQ;AAC5B,YAAI,IAAK,QAAO,IAAI,MAAM,uBAAuB,IAAI,OAAO,EAAE,CAAC;AAAA,YAC1D,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QACJ,MACA,OACsB;AACtB,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,WAAO,IAAI,QAAqB,CAACA,UAAS,WAAW;AACnD,WAAK,QAAQ,UAAU,CAAC,KAAK,SAAS;AACpC,YAAI,KAAK;AACP,iBAAO,IAAI,MAAM,yBAAyB,IAAI,OAAO,EAAE,CAAC;AACxD;AAAA,QACF;AACA,cAAM,UAAuB,KAAK,IAAI,CAAC,UAAU;AAAA,UAC/C,MAAM,KAAK;AAAA,UACX,MAAc,aAAK,UAAU,KAAK,QAAQ;AAAA,UAC1C,aAAa,KAAK,MAAM,YAAY;AAAA,UACpC,QAAQ,KAAK,MAAM,OAAO;AAAA,QAC5B,EAAE;AACF,QAAAA,SAAQ,OAAO;AAAA,MACjB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,MAAgC;AAC3C,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,WAAO,IAAI,QAAiB,CAACA,aAAY;AACvC,WAAK,KAAK,UAAU,CAAC,QAAQ;AAC3B,QAAAA,SAAQ,CAAC,GAAG;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,KAAK,MAAiC;AAC1C,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,UAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,WAAO,IAAI,QAAkB,CAACA,UAAS,WAAW;AAChD,WAAK,KAAK,UAAU,CAAC,KAAK,UAAU;AAClC,YAAI,KAAK;AACP,iBAAO,IAAI,MAAM,sBAAsB,IAAI,OAAO,EAAE,CAAC;AACrD;AAAA,QACF;AACA,QAAAA,SAAQ;AAAA,UACN,MAAM,MAAM;AAAA,UACZ,aAAa,MAAM,YAAY;AAAA,UAC/B,QAAQ,MAAM,OAAO;AAAA,UACrB,YAAY,MAAM,QAAQ,IAAI,IAAI,KAAK,MAAM,QAAQ,GAAI,IAAI;AAAA,QAC/D,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,eACZ,MACA,KACe;AACf,UAAM,QAAQ,IAAI,MAAM,GAAG,EAAE,OAAO,OAAO;AAC3C,QAAI,UAAU;AACd,eAAW,QAAQ,OAAO;AACxB,gBAAkB,aAAK,SAAS,IAAI;AACpC,YAAM,IAAI,QAAc,CAACA,aAAY;AACnC,aAAK,MAAM,SAAS,MAAM;AACxB,UAAAA,SAAQ;AAAA,QACV,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,YACZ,MACA,QACe;AACf,UAAM,QAAQ,MAAM,IAAI,QAAiB,CAACA,aAAY;AACpD,WAAK,KAAK,QAAQ,CAAC,KAAK,UAAU;AAChC,YAAI,IAAK,CAAAA,SAAQ,KAAK;AAAA,YACjB,CAAAA,SAAQ,MAAM,YAAY,CAAC;AAAA,MAClC,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,OAAO;AACV,aAAO,IAAI,QAAc,CAACA,UAAS,WAAW;AAC5C,aAAK,OAAO,QAAQ,CAAC,QAAQ;AAC3B,cAAI,IAAK,QAAO,IAAI,MAAM,4BAA4B,IAAI,OAAO,EAAE,CAAC;AAAA,cAC/D,CAAAA,SAAQ;AAAA,QACf,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,UAAM,UAAU,MAAM,IAAI;AAAA,MACxB,CAACA,UAAS,WAAW;AACnB,aAAK,QAAQ,QAAQ,CAAC,KAAK,SAAS;AAClC,cAAI,IAAK,QAAO,IAAI,MAAM,4BAA4B,IAAI,OAAO,EAAE,CAAC;AAAA,cAC/D,CAAAA,SAAQ,IAAI;AAAA,QACnB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,eAAW,SAAS,SAAS;AAC3B,YAAM,KAAK,YAAY,MAAc,aAAK,QAAQ,MAAM,QAAQ,CAAC;AAAA,IACnE;AAEA,WAAO,IAAI,QAAc,CAACA,UAAS,WAAW;AAC5C,WAAK,MAAM,QAAQ,CAAC,QAAQ;AAC1B,YAAI,IAAK,QAAO,IAAI,MAAM,4BAA4B,IAAI,OAAO,EAAE,CAAC;AAAA,YAC/D,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;;;ACtLO,IAAM,cAAN,MAA6C;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,MAA0B;AACpC,SAAK,SAAS,KAAK;AACnB,SAAK,aAAa,KAAK,cAAc;AACrC,SAAK,iBAAiB,KAAK,kBAAkB;AAAA,EAC/C;AAAA,EAEA,MAAM,eACJ,SACA,MACwB;AACxB,UAAM,MAAM,MAAM,OAAO,KAAK;AAC9B,UAAM,UAAU,MAAM,WAAW,KAAK;AAEtC,QAAI,YAAY;AAChB,QAAI,MAAM,KAAK;AACb,kBAAY,OAAO,QAAQ,KAAK,GAAG,EAChC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,CAAC,CAAC,EAAE,EACxC,KAAK,GAAG,IAAI;AAAA,IACjB;AAEA,UAAM,cAAc,MAAM,YAAY,GAAG,CAAC,OAAO,SAAS,GAAG,OAAO;AAEpE,WAAO,IAAI,QAAuB,CAACE,UAAS,WAAW;AACrD,WAAK,OAAO,KAAK,aAAa,CAAC,KAAK,YAAY;AAC9C,YAAI,KAAK;AACP,iBAAO,GAAG;AACV;AAAA,QACF;AAEA,cAAM,aAAuB,CAAC;AAC9B,cAAM,aAAuB,CAAC;AAE9B,cAAM,QAAQ,WAAW,MAAM;AAC7B,kBAAQ,UAAU;AAClB,UAAAA,SAAQ;AAAA,YACN,UAAU;AAAA,YACV,QAAQ,OAAO,OAAO,UAAU,EAAE,SAAS,OAAO;AAAA,YAClD,QACE,OAAO,OAAO,UAAU,EAAE,SAAS,OAAO,IAC1C,sBAAsB,UAAU;AAAA,UACpC,CAAC;AAAA,QACH,GAAG,OAAO;AAEV,gBAAQ,GAAG,QAAQ,CAAC,UAAkB;AACpC,qBAAW,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,QACpC,CAAC;AAED,gBAAQ,OAAO,GAAG,QAAQ,CAAC,UAAkB;AAC3C,qBAAW,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,QACpC,CAAC;AAED,gBAAQ,GAAG,SAAS,CAAC,SAAiB;AACpC,uBAAa,KAAK;AAClB,UAAAA,SAAQ;AAAA,YACN,UAAU,QAAQ;AAAA,YAClB,QAAQ,OAAO,OAAO,UAAU,EAAE,SAAS,OAAO;AAAA,YAClD,QAAQ,OAAO,OAAO,UAAU,EAAE,SAAS,OAAO;AAAA,UACpD,CAAC;AAAA,QACH,CAAC;AAED,gBAAQ,GAAG,SAAS,CAAC,eAAsB;AACzC,uBAAa,KAAK;AAClB,iBAAO,UAAU;AAAA,QACnB,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAEA,SAAS,YAAY,GAAmB;AACtC,SAAO,IAAI,EAAE,QAAQ,MAAM,OAAO,CAAC;AACrC;;;ACzHO,SAAS,WAAW,MAAkC;AAC3D,MAAI,KAAK,QAAQ;AACf,UAAM,IAAI,KAAK;AACf,WAAO;AAAA,MACL,IAAI,IAAI,MAAM,EAAE,QAAQ,GAAG,YAAY,KAAK,IAAI,CAAC;AAAA,MACjD,UAAU,IAAI,YAAY;AAAA,QACxB,QAAQ;AAAA,QACR,YAAY,KAAK;AAAA,QACjB,gBAAgB,KAAK;AAAA,MACvB,CAAC;AAAA,MACD,WAAW,MACT,KAAK,OAAO,GAAG,KAAK,IAAI,IAAI,KAAK,QAAQ,EAAE,KAAK;AAAA,IACpD;AAAA,EACF;AAEA,MAAI,CAAC,KAAK,MAAM;AACd,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAEA,QAAM,UAAU,cAAc;AAC9B,QAAM,gBAAgB,oBAAoB;AAC1C,QAAM,aAAa,GAAG,KAAK,IAAI,IAAI,KAAK,QAAQ,EAAE;AAClD,MAAI,YAA8B;AAClC,MAAI,cAAc;AAClB,MAAI,cAAoC;AAExC,iBAAe,SAAwB;AACrC,UAAM,UAAU;AAChB,UAAM,OAAO,MAAM;AAAA;AAAA,MAAiC;AAAA;AACpD,UAAM,cACH,KAAa,UAAW,KAAa,SAAS;AACjD,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAoB,IAAI,YAAY;AAC1C,UAAM,IAAI,QAAc,CAACC,UAAS,WAAW;AAC3C,aAAO,GAAG,SAAS,MAAMA,SAAQ,CAAC;AAClC,aAAO,GAAG,SAAS,CAAC,QAAe,OAAO,GAAG,CAAC;AAC9C,MAAC,OAAe,QAAQ;AAAA,QACtB,MAAM,KAAK;AAAA,QACX,MAAM,KAAK,QAAQ;AAAA,QACnB,UAAU,KAAK,YAAY;AAAA,QAC3B,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB,YAAY,KAAK;AAAA,MACnB,CAAC;AAAA,IACH,CAAC;AAED,gBAAY;AACZ,kBAAc;AACd,YAAQ,UAAU,IAAI,MAAM,EAAE,QAAQ,YAAY,KAAK,IAAI,CAAC,CAAC;AAC7D,kBAAc;AAAA,MACZ,IAAI,YAAY;AAAA,QACd;AAAA,QACA,YAAY,KAAK;AAAA,QACjB,gBAAgB,KAAK;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,WAAW,MAAM;AAAA,IAEjB,OAAsB;AACpB,UAAI,CAAC,aAAa;AAChB,sBAAc,OAAO,EAAE,MAAM,CAAC,QAAQ;AACpC,wBAAc;AACd,gBAAM;AAAA,QACR,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,UAAyB;AAC7B,UAAI,aAAa;AACf,cAAM,YAAY,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAClC;AACA,UAAI,CAAC,eAAe,CAAC,UAAW;AAChC,UAAI;AACF,kBAAU,IAAI;AAAA,MAChB,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;","names":["resolve","sftp","resolve","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../src/virtual/ssh-fs.ts","../src/virtual/ssh-computer.ts","../src/virtual/ssh-sandbox.ts"],"sourcesContent":["import * as pathMod from \"node:path\";\nimport type { VirtualFs, FileEntry, FileStat, ReadOptions } from \"./fs.js\";\nimport type { SshClient, SshSftpSession } from \"./ssh-computer.js\";\n\nexport interface SshFsOptions {\n /** A connected ssh2 Client instance. */\n client: SshClient;\n /** Working directory for relative path resolution (default: /). */\n workingDir?: string;\n}\n\n/**\n * VirtualFs backed by SFTP file operations over SSH.\n *\n * Uses the ssh2 Client's SFTP subsystem for all file I/O. The SFTP session\n * is opened lazily on the first operation and reused for the lifetime of\n * the SshFs instance.\n *\n * Requires `ssh2` as an optional peer dependency.\n * The caller is responsible for the Client lifecycle.\n */\nexport class SshFs implements VirtualFs {\n private client: SshClient;\n private workingDir: string;\n private sftpSession: SshSftpSession | null = null;\n private sftpPromise: Promise<SshSftpSession> | null = null;\n\n constructor(opts: SshFsOptions) {\n this.client = opts.client;\n this.workingDir = opts.workingDir ?? \"/\";\n }\n\n private getSftp(): Promise<SshSftpSession> {\n if (this.sftpSession) return Promise.resolve(this.sftpSession);\n if (this.sftpPromise) return this.sftpPromise;\n this.sftpPromise = new Promise<SshSftpSession>((resolve, reject) => {\n this.client.sftp((err, sftp) => {\n if (err) {\n this.sftpPromise = null;\n reject(err);\n } else {\n this.sftpSession = sftp;\n resolve(sftp);\n }\n });\n });\n return this.sftpPromise;\n }\n\n private resolvePath(p: string): string {\n if (p.includes(\"\\0\")) {\n throw new Error(\"Path contains null bytes\");\n }\n const normalizedBase = this.workingDir.endsWith(\"/\")\n ? this.workingDir\n : this.workingDir + \"/\";\n if (p.startsWith(\"/\")) {\n const normalized = pathMod.normalize(p);\n if (\n normalized !== this.workingDir &&\n !normalized.startsWith(normalizedBase)\n ) {\n throw new Error(\n `Absolute path \"${p}\" is outside working directory \"${this.workingDir}\"`,\n );\n }\n return normalized;\n }\n const resolved = pathMod.resolve(this.workingDir, p);\n if (\n resolved !== this.workingDir &&\n !resolved.startsWith(normalizedBase)\n ) {\n throw new Error(\n `Path \"${p}\" escapes working directory \"${this.workingDir}\"`,\n );\n }\n return resolved;\n }\n\n async readFile(path: string, _opts?: ReadOptions): Promise<string> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n return new Promise<string>((resolve, reject) => {\n sftp.readFile(resolved, { encoding: \"utf8\" }, (err, data) => {\n if (err) reject(new Error(`SshFs readFile failed: ${err.message}`));\n else resolve(data as string);\n });\n });\n }\n\n async readFileBytes(path: string, maxBytes?: number): Promise<Buffer> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n\n if (maxBytes === undefined) {\n return new Promise<Buffer>((resolve, reject) => {\n sftp.readFile(resolved, (err, data) => {\n if (err) reject(new Error(`SshFs readFileBytes failed: ${err.message}`));\n else resolve(data);\n });\n });\n }\n\n return new Promise<Buffer>((resolve, reject) => {\n sftp.open(resolved, \"r\", (err, handle) => {\n if (err) {\n reject(new Error(`SshFs readFileBytes failed: ${err.message}`));\n return;\n }\n const buf = Buffer.alloc(maxBytes);\n sftp.read(handle, buf, 0, maxBytes, 0, (readErr, bytesRead, readBuf) => {\n sftp.close(handle, () => {});\n if (readErr) {\n reject(new Error(`SshFs readFileBytes failed: ${readErr.message}`));\n } else {\n resolve(readBuf.subarray(0, bytesRead));\n }\n });\n });\n });\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n const dir = pathMod.dirname(resolved);\n await this.mkdirRecursive(sftp, dir);\n return new Promise<void>((resolve, reject) => {\n sftp.writeFile(resolved, content, (err) => {\n if (err) reject(new Error(`SshFs writeFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n async appendFile(path: string, content: string): Promise<void> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n const dir = pathMod.dirname(resolved);\n await this.mkdirRecursive(sftp, dir);\n return new Promise<void>((resolve, reject) => {\n sftp.appendFile(resolved, content, (err) => {\n if (err) reject(new Error(`SshFs appendFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n async deleteFile(\n path: string,\n opts?: { recursive?: boolean },\n ): Promise<void> {\n const resolved = this.resolvePath(path);\n if (opts?.recursive) {\n const sftp = await this.getSftp();\n await this.rmRecursive(sftp, resolved);\n return;\n }\n const sftp = await this.getSftp();\n return new Promise<void>((resolve, reject) => {\n sftp.unlink(resolved, (err) => {\n if (err) reject(new Error(`SshFs deleteFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n async mkdir(path: string, opts?: { recursive?: boolean }): Promise<void> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n if (opts?.recursive) {\n await this.mkdirRecursive(sftp, resolved);\n return;\n }\n return new Promise<void>((resolve, reject) => {\n sftp.mkdir(resolved, (err) => {\n if (err) reject(new Error(`SshFs mkdir failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n async readdir(\n path: string,\n _opts?: { recursive?: boolean },\n ): Promise<FileEntry[]> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n return new Promise<FileEntry[]>((resolve, reject) => {\n sftp.readdir(resolved, (err, list) => {\n if (err) {\n reject(new Error(`SshFs readdir failed: ${err.message}`));\n return;\n }\n const entries: FileEntry[] = list.map((item) => ({\n name: item.filename,\n path: pathMod.join(resolved, item.filename),\n isDirectory: item.attrs.isDirectory(),\n isFile: item.attrs.isFile(),\n }));\n resolve(entries);\n });\n });\n }\n\n async exists(path: string): Promise<boolean> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n return new Promise<boolean>((resolve) => {\n sftp.stat(resolved, (err) => {\n resolve(!err);\n });\n });\n }\n\n async stat(path: string): Promise<FileStat> {\n const resolved = this.resolvePath(path);\n const sftp = await this.getSftp();\n return new Promise<FileStat>((resolve, reject) => {\n sftp.stat(resolved, (err, stats) => {\n if (err) {\n reject(new Error(`SshFs stat failed: ${err.message}`));\n return;\n }\n resolve({\n size: stats.size,\n isDirectory: stats.isDirectory(),\n isFile: stats.isFile(),\n modifiedAt: stats.mtime > 0 ? new Date(stats.mtime * 1000) : undefined,\n });\n });\n });\n }\n\n private async mkdirRecursive(\n sftp: SshSftpSession,\n dir: string,\n ): Promise<void> {\n const parts = dir.split(\"/\").filter(Boolean);\n let current = \"/\";\n for (const part of parts) {\n current = pathMod.join(current, part);\n await new Promise<void>((resolve) => {\n sftp.mkdir(current, () => {\n resolve();\n });\n });\n }\n }\n\n private async rmRecursive(\n sftp: SshSftpSession,\n target: string,\n ): Promise<void> {\n const isDir = await new Promise<boolean>((resolve) => {\n sftp.stat(target, (err, stats) => {\n if (err) resolve(false);\n else resolve(stats.isDirectory());\n });\n });\n\n if (!isDir) {\n return new Promise<void>((resolve, reject) => {\n sftp.unlink(target, (err) => {\n if (err) reject(new Error(`SshFs deleteFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n\n const entries = await new Promise<Array<{ filename: string; attrs: { isDirectory(): boolean } }>>(\n (resolve, reject) => {\n sftp.readdir(target, (err, list) => {\n if (err) reject(new Error(`SshFs deleteFile failed: ${err.message}`));\n else resolve(list);\n });\n },\n );\n\n for (const entry of entries) {\n await this.rmRecursive(sftp, pathMod.join(target, entry.filename));\n }\n\n return new Promise<void>((resolve, reject) => {\n sftp.rmdir(target, (err) => {\n if (err) reject(new Error(`SshFs deleteFile failed: ${err.message}`));\n else resolve();\n });\n });\n }\n}\n","import type { VirtualComputer, ExecOptions, CommandResult } from \"./computer.js\";\n\n/**\n * Minimal subset of the ssh2 Channel interface used by SshComputer / SshFs.\n * Avoids a hard import of ssh2 at the module level.\n */\nexport interface SshChannel {\n on(event: string, listener: (...args: any[]) => void): SshChannel;\n stderr: { on(event: string, listener: (...args: any[]) => void): unknown };\n destroy?(): void;\n}\n\n/**\n * Minimal subset of the ssh2 SFTPWrapper interface used by SshFs.\n */\nexport interface SshSftpSession {\n readFile(\n path: string,\n callback: (err: Error | undefined, data: Buffer) => void,\n ): void;\n readFile(\n path: string,\n opts: { encoding: string },\n callback: (err: Error | undefined, data: string) => void,\n ): void;\n writeFile(\n path: string,\n data: string | Buffer,\n callback: (err: Error | undefined) => void,\n ): void;\n appendFile(\n path: string,\n data: string | Buffer,\n callback: (err: Error | undefined) => void,\n ): void;\n unlink(path: string, callback: (err: Error | undefined) => void): void;\n rmdir(path: string, callback: (err: Error | undefined) => void): void;\n mkdir(path: string, callback: (err: Error | undefined) => void): void;\n readdir(\n path: string,\n callback: (\n err: Error | undefined,\n list: Array<{\n filename: string;\n longname: string;\n attrs: { size: number; isDirectory(): boolean; isFile(): boolean; mtime: number; atime: number };\n }>,\n ) => void,\n ): void;\n stat(\n path: string,\n callback: (\n err: Error | undefined,\n stats: { size: number; isDirectory(): boolean; isFile(): boolean; mtime: number; atime: number },\n ) => void,\n ): void;\n open(\n path: string,\n flags: string,\n callback: (err: Error | undefined, handle: Buffer) => void,\n ): void;\n read(\n handle: Buffer,\n buffer: Buffer,\n offset: number,\n length: number,\n position: number,\n callback: (err: Error | undefined, bytesRead: number, buf: Buffer) => void,\n ): void;\n close(handle: Buffer, callback: (err: Error | undefined) => void): void;\n end(): void;\n}\n\n/**\n * Minimal subset of the ssh2 Client interface used by SshComputer and SshFs.\n * Avoids a hard import of ssh2 at the module level.\n */\nexport interface SshClient {\n exec(\n command: string,\n callback: (err: Error | undefined, channel: SshChannel) => void,\n ): void;\n exec(\n command: string,\n opts: Record<string, unknown>,\n callback: (err: Error | undefined, channel: SshChannel) => void,\n ): void;\n sftp(\n callback: (err: Error | undefined, sftp: SshSftpSession) => void,\n ): void;\n end(): void;\n on(event: string, listener: (...args: any[]) => void): this;\n}\n\nexport interface SshComputerOptions {\n /** A connected ssh2 Client instance. */\n client: SshClient;\n /** Default working directory for commands (default: /). */\n defaultCwd?: string;\n /** Default timeout in ms for commands (default: 30000). */\n defaultTimeout?: number;\n}\n\n/**\n * VirtualComputer backed by command execution over SSH.\n *\n * Requires `ssh2` as an optional peer dependency.\n * The caller is responsible for the Client lifecycle (connect, end).\n */\nexport class SshComputer implements VirtualComputer {\n private client: SshClient;\n private defaultCwd: string;\n private defaultTimeout: number;\n\n constructor(opts: SshComputerOptions) {\n this.client = opts.client;\n this.defaultCwd = opts.defaultCwd ?? \"/\";\n this.defaultTimeout = opts.defaultTimeout ?? 30_000;\n }\n\n async executeCommand(\n command: string,\n opts?: ExecOptions,\n ): Promise<CommandResult> {\n const cwd = opts?.cwd ?? this.defaultCwd;\n const timeout = opts?.timeout ?? this.defaultTimeout;\n\n let envPrefix = \"\";\n if (opts?.env) {\n envPrefix = Object.entries(opts.env)\n .map(([k, v]) => `${k}=${shellEscape(v)}`)\n .join(\" \") + \" \";\n }\n\n const fullCommand = `cd ${shellEscape(cwd)} && ${envPrefix}${command}`;\n\n return new Promise<CommandResult>((resolve, reject) => {\n this.client.exec(fullCommand, (err, channel) => {\n if (err) {\n reject(err);\n return;\n }\n\n const stdoutBufs: Buffer[] = [];\n const stderrBufs: Buffer[] = [];\n\n const timer = setTimeout(() => {\n channel.destroy?.();\n resolve({\n exitCode: 1,\n stdout: Buffer.concat(stdoutBufs).toString(\"utf-8\"),\n stderr:\n Buffer.concat(stderrBufs).toString(\"utf-8\") +\n \"\\n[timeout after \" + timeout + \"ms]\",\n });\n }, timeout);\n\n channel.on(\"data\", (chunk: Buffer) => {\n stdoutBufs.push(Buffer.from(chunk));\n });\n\n channel.stderr.on(\"data\", (chunk: Buffer) => {\n stderrBufs.push(Buffer.from(chunk));\n });\n\n channel.on(\"close\", (code: number) => {\n clearTimeout(timer);\n resolve({\n exitCode: code ?? 0,\n stdout: Buffer.concat(stdoutBufs).toString(\"utf-8\"),\n stderr: Buffer.concat(stderrBufs).toString(\"utf-8\"),\n });\n });\n\n channel.on(\"error\", (channelErr: Error) => {\n clearTimeout(timer);\n reject(channelErr);\n });\n });\n });\n }\n}\n\nfunction shellEscape(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n","import type { Sandbox } from \"./sandbox.js\";\nimport { SshFs } from \"./ssh-fs.js\";\nimport { SshComputer, type SshClient } from \"./ssh-computer.js\";\nimport { createFsProxy, createComputerProxy } from \"./proxy.js\";\n\nexport interface SshSandboxOptions {\n /**\n * A pre-connected ssh2 Client instance. When provided the sandbox uses\n * this client directly — no auto-connect occurs and `dispose()` will\n * **not** call `client.end()`.\n *\n * When omitted, a new ssh2 Client is created and connected on the first\n * `init()` call using `host`, `port`, `username`, and the provided\n * credentials. The client is ended when `dispose()` is called.\n */\n client?: SshClient;\n /**\n * SSH hostname. Required when `client` is omitted; ignored when `client`\n * is provided.\n */\n host?: string;\n /** SSH port (default: 22). Only used during auto-connect. */\n port?: number;\n /** SSH username (default: \"root\"). Only used during auto-connect. */\n username?: string;\n /** Password for password-based authentication. Only used during auto-connect. */\n password?: string;\n /** Private key for key-based authentication (PEM string or Buffer). Only used during auto-connect. */\n privateKey?: string | Buffer;\n /** Passphrase for an encrypted private key. Only used during auto-connect. */\n passphrase?: string;\n /** Working directory on the remote host. */\n cwd?: string;\n /** Default timeout (ms) for shell commands. */\n defaultTimeout?: number;\n}\n\n/**\n * Create a `Sandbox` backed by a remote host over SSH.\n * Requires `ssh2` as an optional peer dependency.\n *\n * **Auto-connect:** When `client` is omitted and `host` is provided,\n * an ssh2 Client is created and connected lazily on the first `init()`\n * call. The connection identifier (`host:port`) is available through\n * `sandboxId()` for session persistence.\n *\n * **Explicit client:** When `client` is provided, `init()` binds it\n * immediately. `dispose()` is a no-op — the caller owns the client's\n * lifecycle.\n *\n * @example\n * ```ts\n * // Auto-connect with private key\n * const sandbox = SshSandbox({\n * host: \"dev.example.com\",\n * username: \"deploy\",\n * privateKey: fs.readFileSync(\"~/.ssh/id_ed25519\"),\n * cwd: \"/home/deploy/project\",\n * });\n *\n * // Explicit client (lifecycle managed externally)\n * const sandbox = SshSandbox({ client: myConnectedClient, cwd: \"/workspace\" });\n * ```\n */\nexport function SshSandbox(opts: SshSandboxOptions): Sandbox {\n if (opts.client) {\n const c = opts.client;\n return {\n fs: new SshFs({ client: c, workingDir: opts.cwd }),\n computer: new SshComputer({\n client: c,\n defaultCwd: opts.cwd,\n defaultTimeout: opts.defaultTimeout,\n }),\n sandboxId: () =>\n opts.host ? `${opts.host}:${opts.port ?? 22}` : undefined,\n };\n }\n\n if (!opts.host) {\n throw new Error(\"SshSandbox requires either `client` or `host`\");\n }\n\n const fsProxy = createFsProxy();\n const computerProxy = createComputerProxy();\n const identifier = `${opts.host}:${opts.port ?? 22}`;\n let clientRef: SshClient | null = null;\n let autoCreated = false;\n let initPromise: Promise<void> | null = null;\n\n async function doInit(): Promise<void> {\n const modName = \"ssh2\";\n const ssh2 = await import(/* webpackIgnore: true */ modName);\n const ClientClass =\n (ssh2 as any).Client ?? (ssh2 as any).default?.Client;\n if (!ClientClass) {\n throw new Error(\n \"Could not resolve Client class from 'ssh2' package\",\n );\n }\n\n const client: SshClient = new ClientClass();\n await new Promise<void>((resolve, reject) => {\n client.on(\"ready\", () => resolve());\n client.on(\"error\", (err: Error) => reject(err));\n (client as any).connect({\n host: opts.host,\n port: opts.port ?? 22,\n username: opts.username ?? \"root\",\n password: opts.password,\n privateKey: opts.privateKey,\n passphrase: opts.passphrase,\n });\n });\n\n clientRef = client;\n autoCreated = true;\n fsProxy.setTarget(new SshFs({ client, workingDir: opts.cwd }));\n computerProxy.setTarget(\n new SshComputer({\n client,\n defaultCwd: opts.cwd,\n defaultTimeout: opts.defaultTimeout,\n }),\n );\n }\n\n return {\n fs: fsProxy,\n computer: computerProxy,\n sandboxId: () => identifier,\n\n init(): Promise<void> {\n if (!initPromise) {\n initPromise = doInit().catch((err) => {\n initPromise = null;\n throw err;\n });\n }\n return initPromise;\n },\n\n async dispose(): Promise<void> {\n if (initPromise) {\n await initPromise.catch(() => {});\n }\n if (!autoCreated || !clientRef) return;\n try {\n clientRef.end();\n } catch {\n /* best-effort */\n }\n },\n };\n}\n"],"mappings":"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","names":["resolve","sftp","resolve","resolve"]}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as
|
|
3
|
-
import { a as PermissionMode, b as PermissionResult } from './types-CD0rUKKT.js';
|
|
1
|
+
import { V as VirtualFs, a as VirtualComputer } from './computer-DzMR92tK.js';
|
|
2
|
+
import { C as CheckpointConfig, F as FileCheckpointState, D as DiffStats, a as FileCheckpointSnapshot, b as PermissionMode, S as StreamEvent, c as PermissionResult, d as ContentPart } from './types-DLZNyF5t.js';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Zod integration utilities. Users bring their own `zod` dependency — these
|
|
@@ -46,6 +45,74 @@ declare function registerZodToJsonSchema(fn: (schema: unknown) => JsonSchemaType
|
|
|
46
45
|
*/
|
|
47
46
|
declare function formatZodValidationError(toolName: string, issues: SafeParseResult["error"]): string;
|
|
48
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Configuration for which dot-directory names the agent recognizes when
|
|
50
|
+
* reading and writing auxiliary state (context files, skills, sessions,
|
|
51
|
+
* tasks, checkpoints, CLI config, MCP auth tokens, etc).
|
|
52
|
+
*
|
|
53
|
+
* The list is ordered by preference:
|
|
54
|
+
* - `names[0]` is the canonical write target.
|
|
55
|
+
* - For single-file reads (e.g. `config.json`), callers use first-hit-wins
|
|
56
|
+
* across candidates in order.
|
|
57
|
+
* - For additive reads (e.g. rules, skills), every candidate is loaded and
|
|
58
|
+
* later entries in the list have higher precedence when resolving
|
|
59
|
+
* collisions (mirrors the context loader's layer ordering).
|
|
60
|
+
*
|
|
61
|
+
* The same list applies to both project scope (cwd ancestors) and user
|
|
62
|
+
* scope (home directory). There is intentionally no per-scope split — if
|
|
63
|
+
* a caller needs that, they can route through different resolvers.
|
|
64
|
+
*/
|
|
65
|
+
interface DotDirConfig {
|
|
66
|
+
names: string[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Default dot-directory configuration. Recognizes `.noumen` (canonical)
|
|
70
|
+
* and `.claude` (compatibility), preferring `.noumen` for writes.
|
|
71
|
+
*/
|
|
72
|
+
declare const DEFAULT_DOT_DIRS: DotDirConfig;
|
|
73
|
+
/**
|
|
74
|
+
* Pure path resolver over a `DotDirConfig`. Does no I/O — callers pair it
|
|
75
|
+
* with `readFirstDotDir` / `readAllDotDirs` (VirtualFs helpers below) or
|
|
76
|
+
* their own filesystem code.
|
|
77
|
+
*/
|
|
78
|
+
interface DotDirResolver {
|
|
79
|
+
/** The underlying configuration (exposed for permissions and logging). */
|
|
80
|
+
config: DotDirConfig;
|
|
81
|
+
/**
|
|
82
|
+
* Absolute paths for each candidate dot-dir under `base`, in preference
|
|
83
|
+
* order (most preferred first). `base` is appended with a `/` separator
|
|
84
|
+
* unless already present.
|
|
85
|
+
*/
|
|
86
|
+
candidates(base: string): string[];
|
|
87
|
+
/** The canonical write target (`candidates(base)[0]`). */
|
|
88
|
+
writePath(base: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* Each candidate joined with `rel`, in preference order. Use this for
|
|
91
|
+
* first-hit-wins reads (e.g. `config.json`).
|
|
92
|
+
*/
|
|
93
|
+
joinRead(base: string, rel: string): string[];
|
|
94
|
+
/** Write path joined with `rel`. */
|
|
95
|
+
joinWrite(base: string, rel: string): string;
|
|
96
|
+
}
|
|
97
|
+
declare function createDotDirResolver(config?: DotDirConfig): DotDirResolver;
|
|
98
|
+
/**
|
|
99
|
+
* Read the first file that exists across the resolver's candidate paths
|
|
100
|
+
* under `base/<name>/<rel>`. Returns `null` if none match.
|
|
101
|
+
*/
|
|
102
|
+
declare function readFirstDotDir(fs: VirtualFs, resolver: DotDirResolver, base: string, rel: string): Promise<{
|
|
103
|
+
path: string;
|
|
104
|
+
content: string;
|
|
105
|
+
} | null>;
|
|
106
|
+
/**
|
|
107
|
+
* Read every candidate file that exists under `base/<name>/<rel>`. Results
|
|
108
|
+
* are ordered from lowest to highest precedence (matching the context
|
|
109
|
+
* loader's layer-stacking convention where later entries win).
|
|
110
|
+
*/
|
|
111
|
+
declare function readAllDotDirs(fs: VirtualFs, resolver: DotDirResolver, base: string, rel: string): Promise<Array<{
|
|
112
|
+
path: string;
|
|
113
|
+
content: string;
|
|
114
|
+
}>>;
|
|
115
|
+
|
|
49
116
|
type HookEvent = "PreToolUse" | "PostToolUse" | "PostToolUseFailure" | "PreCompact" | "PostCompact" | "TurnStart" | "TurnEnd" | "SubagentStart" | "SubagentStop" | "SessionStart" | "SessionEnd" | "PermissionRequest" | "PermissionDenied" | "FileWrite" | "ModelSwitch" | "RetryAttempt" | "MemoryUpdate" | "Error";
|
|
50
117
|
interface PreToolUseHookInput {
|
|
51
118
|
event: "PreToolUse";
|
|
@@ -474,6 +541,11 @@ interface ToolContext {
|
|
|
474
541
|
notifyHook?: (event: string, input: Record<string, unknown>) => Promise<void>;
|
|
475
542
|
/** Abort signal — tools should check this to terminate early on user abort. */
|
|
476
543
|
signal?: AbortSignal;
|
|
544
|
+
/**
|
|
545
|
+
* Dot-directory resolver — lets tools honor custom dot-dir configurations
|
|
546
|
+
* (e.g. Worktree writes under `<dotdir>/worktrees/<slug>`).
|
|
547
|
+
*/
|
|
548
|
+
dotDirResolver?: DotDirResolver;
|
|
477
549
|
}
|
|
478
550
|
interface ToolParameterProperty {
|
|
479
551
|
type: string;
|
|
@@ -556,4 +628,4 @@ interface Tool {
|
|
|
556
628
|
call(args: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
|
|
557
629
|
}
|
|
558
630
|
|
|
559
|
-
export { type
|
|
631
|
+
export { readFirstDotDir as $, type PermissionDeniedHookInput as A, type PermissionRequestHookInput as B, type SafeParseResult as C, DiagnosticRegistry as D, type SessionEndHookInput as E, FileCheckpointManager as F, type SessionStartHookInput as G, type HookDefinition as H, type SubagentStartHookInput as I, type JsonSchemaType as J, type SubagentStopHookInput as K, type LspServerConfig as L, type MemoryUpdateHookInput as M, type NotificationHookInput as N, type Task as O, type PostToolUseFailureHookInput as P, type TaskCreateInput as Q, type RetryAttemptHookInput as R, type SubagentConfig as S, type Tool as T, type TaskStatus as U, type TaskUpdateInput as V, type ToolParameters as W, createDotDirResolver as X, formatZodValidationError as Y, type ZodLikeSchema as Z, readAllDotDirs as _, type LspServerState as a, registerZodToJsonSchema as a0, zodToJsonSchema as a1, type LspDiagnostic as b, type LspLocation as c, type LspOperation as d, LspServerManager as e, type LspSymbol as f, type ToolResult as g, type ToolContext as h, type DotDirResolver as i, type DotDirConfig as j, type SubagentRun as k, TaskStore as l, type FileStateCacheConfig as m, type HookEvent as n, type HookInput as o, type PostToolUseFailureHookOutput as p, type PostToolUseHookInput as q, type PostToolUseHookOutput as r, type PreToolUseHookInput as s, type PreToolUseHookOutput as t, DEFAULT_DOT_DIRS as u, type FileState as v, FileStateCache as w, type FileWriteHookInput as x, type HookOutput as y, type ModelSwitchHookInput as z };
|
|
@@ -574,6 +574,15 @@ interface ChatParams {
|
|
|
574
574
|
system?: string;
|
|
575
575
|
temperature?: number;
|
|
576
576
|
thinking?: ThinkingConfig;
|
|
577
|
+
/**
|
|
578
|
+
* Fine-grained reasoning effort hint. Honored by providers whose
|
|
579
|
+
* reasoning-capable models expose an explicit effort knob (OpenAI
|
|
580
|
+
* GPT-5 / o-series today). Providers that don't recognise the knob
|
|
581
|
+
* ignore it. Use `"minimal"` for cheap structural calls (e.g.
|
|
582
|
+
* auto-title, classification) so the model doesn't burn the whole
|
|
583
|
+
* `max_tokens` budget on internal reasoning before emitting output.
|
|
584
|
+
*/
|
|
585
|
+
reasoningEffort?: "minimal" | "low" | "medium" | "high";
|
|
577
586
|
/** Constrain the model to produce structured output matching this schema. */
|
|
578
587
|
outputFormat?: OutputFormat;
|
|
579
588
|
/**
|
|
@@ -610,4 +619,119 @@ declare class ChatStreamError extends Error {
|
|
|
610
619
|
});
|
|
611
620
|
}
|
|
612
621
|
|
|
613
|
-
|
|
622
|
+
type PermissionMode = "default" | "plan" | "acceptEdits" | "auto" | "bypassPermissions" | "dontAsk";
|
|
623
|
+
type PermissionBehavior = "allow" | "deny" | "ask";
|
|
624
|
+
type PermissionRuleSource = "user" | "project" | "session" | "policy";
|
|
625
|
+
/** Precedence order: policy > project > user > session. */
|
|
626
|
+
declare const RULE_SOURCE_PRECEDENCE: PermissionRuleSource[];
|
|
627
|
+
interface PermissionRule {
|
|
628
|
+
toolName: string;
|
|
629
|
+
ruleContent?: string;
|
|
630
|
+
behavior: PermissionBehavior;
|
|
631
|
+
/** Where this rule came from. Higher-precedence sources override lower ones. */
|
|
632
|
+
source?: PermissionRuleSource;
|
|
633
|
+
}
|
|
634
|
+
type PermissionUpdate = {
|
|
635
|
+
type: "addRules";
|
|
636
|
+
rules: PermissionRule[];
|
|
637
|
+
} | {
|
|
638
|
+
type: "removeRules";
|
|
639
|
+
toolName: string;
|
|
640
|
+
behavior?: PermissionBehavior;
|
|
641
|
+
} | {
|
|
642
|
+
type: "setMode";
|
|
643
|
+
mode: PermissionMode;
|
|
644
|
+
} | {
|
|
645
|
+
type: "addDirectories";
|
|
646
|
+
directories: string[];
|
|
647
|
+
} | {
|
|
648
|
+
type: "removeDirectories";
|
|
649
|
+
directories: string[];
|
|
650
|
+
};
|
|
651
|
+
interface PermissionAllowResult<Input extends Record<string, unknown> = Record<string, unknown>> {
|
|
652
|
+
behavior: "allow";
|
|
653
|
+
updatedInput?: Input;
|
|
654
|
+
reason?: string;
|
|
655
|
+
}
|
|
656
|
+
interface PermissionDenyResult {
|
|
657
|
+
behavior: "deny";
|
|
658
|
+
message: string;
|
|
659
|
+
reason?: string;
|
|
660
|
+
}
|
|
661
|
+
interface PermissionAskResult {
|
|
662
|
+
behavior: "ask";
|
|
663
|
+
message: string;
|
|
664
|
+
reason?: string;
|
|
665
|
+
suggestions?: PermissionRule[];
|
|
666
|
+
}
|
|
667
|
+
interface PermissionPassthroughResult {
|
|
668
|
+
behavior: "passthrough";
|
|
669
|
+
message: string;
|
|
670
|
+
reason?: string;
|
|
671
|
+
suggestions?: PermissionRule[];
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* What `Tool.checkPermissions` returns. Includes `passthrough` for tools that
|
|
675
|
+
* have no opinion and want the global pipeline to decide.
|
|
676
|
+
*/
|
|
677
|
+
type PermissionResult<Input extends Record<string, unknown> = Record<string, unknown>> = PermissionAllowResult<Input> | PermissionDenyResult | PermissionAskResult | PermissionPassthroughResult;
|
|
678
|
+
/**
|
|
679
|
+
* Final decision after the pipeline resolves. No `passthrough` — always
|
|
680
|
+
* one of allow / deny / ask.
|
|
681
|
+
*/
|
|
682
|
+
type PermissionDecision<Input extends Record<string, unknown> = Record<string, unknown>> = PermissionAllowResult<Input> | PermissionDenyResult | PermissionAskResult;
|
|
683
|
+
interface PermissionRequest {
|
|
684
|
+
toolName: string;
|
|
685
|
+
input: Record<string, unknown>;
|
|
686
|
+
message: string;
|
|
687
|
+
suggestions?: PermissionRule[];
|
|
688
|
+
isReadOnly: boolean;
|
|
689
|
+
isDestructive: boolean;
|
|
690
|
+
/** Abort signal from the session — handlers should stop promptly when fired. */
|
|
691
|
+
signal?: AbortSignal;
|
|
692
|
+
}
|
|
693
|
+
interface PermissionResponse {
|
|
694
|
+
allow: boolean;
|
|
695
|
+
updatedInput?: Record<string, unknown>;
|
|
696
|
+
feedback?: string;
|
|
697
|
+
addRules?: PermissionRule[];
|
|
698
|
+
}
|
|
699
|
+
type PermissionHandler = (request: PermissionRequest) => Promise<PermissionResponse>;
|
|
700
|
+
interface AutoModeConfig {
|
|
701
|
+
/** Custom system prompt for the classifier. When omitted, uses a default. */
|
|
702
|
+
classifierPrompt?: string;
|
|
703
|
+
/** Model to use for classification. When omitted, uses the thread's model. */
|
|
704
|
+
classifierModel?: string;
|
|
705
|
+
}
|
|
706
|
+
interface DenialTrackingConfig {
|
|
707
|
+
/** Max consecutive denials before fallback (default: 3). */
|
|
708
|
+
maxConsecutive?: number;
|
|
709
|
+
/** Max total denials before fallback (default: 20). */
|
|
710
|
+
maxTotal?: number;
|
|
711
|
+
}
|
|
712
|
+
interface PermissionConfig {
|
|
713
|
+
mode?: PermissionMode;
|
|
714
|
+
rules?: PermissionRule[];
|
|
715
|
+
handler?: PermissionHandler;
|
|
716
|
+
workingDirectories?: string[];
|
|
717
|
+
/** Called when a permission update is applied (for host-side persistence). */
|
|
718
|
+
onPermissionUpdate?: (update: PermissionUpdate) => void;
|
|
719
|
+
/** Configuration for auto mode classifier. */
|
|
720
|
+
autoMode?: AutoModeConfig;
|
|
721
|
+
/** Configuration for denial tracking limits. */
|
|
722
|
+
denialTracking?: DenialTrackingConfig;
|
|
723
|
+
}
|
|
724
|
+
interface PermissionContext {
|
|
725
|
+
mode: PermissionMode;
|
|
726
|
+
rules: PermissionRule[];
|
|
727
|
+
workingDirectories: string[];
|
|
728
|
+
/**
|
|
729
|
+
* Ordered list of dot-directory names (e.g. `['.noumen', '.claude']`)
|
|
730
|
+
* whose contents are treated as dangerous paths for write/edit tools.
|
|
731
|
+
* When unset, defaults to the conservative built-in list
|
|
732
|
+
* (`['.noumen', '.claude']`) so non-agent callers stay protected.
|
|
733
|
+
*/
|
|
734
|
+
dotDirNames?: string[];
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
export { type ImageContent as $, type AIProvider as A, type MemoryEntry as B, type CheckpointConfig as C, type DiffStats as D, type Entry as E, type FileCheckpointState as F, type AssistantMessage as G, type ToolResultMessage as H, type ToolResultOverflowEntry as I, type JsonSchemaOutputFormat as J, type AiTitleEntry as K, type ChatStreamChoice as L, type ModelPricing as M, type ChatStreamDelta as N, type OutputFormat as O, type PermissionResponse as P, ChatStreamError as Q, type RunOptions as R, type StreamEvent as S, type ToolDefinition as T, type UUID as U, type CompactBoundaryEntry as V, type ContentReplacementEntry as W, type CustomTitleEntry as X, type DenialTrackingConfig as Y, type FileCheckpointBackup as Z, type FileCheckpointEntry as _, type FileCheckpointSnapshot as a, type ImageUrlContent as a0, type JsonObjectOutputFormat as a1, type MemoryType as a2, type MessageEntry as a3, type MetadataEntry as a4, type PermissionAllowResult as a5, type PermissionAskResult as a6, type PermissionDenyResult as a7, type PermissionPassthroughResult as a8, type PermissionRequest as a9, type PermissionRuleSource as aa, RULE_SOURCE_PRECEDENCE as ab, type SerializedMessage as ac, type SnipBoundaryEntry as ad, type SummaryEntry as ae, type SystemMessage as af, type TextContent as ag, type ToolParameterProperty as ah, type UserMessage as ai, createCheckpointState as aj, type PermissionMode as b, type PermissionResult as c, type ContentPart as d, type ChatMessage as e, type ContentReplacementRecord as f, type SessionInfo as g, type UsageRecord as h, type CostSummary as i, type ModelUsageSummary as j, type ChatCompletionUsage as k, type PermissionHandler as l, type PermissionConfig as m, type ThinkingConfig as n, type MemoryConfig as o, type ToolResult as p, type ChatParams as q, type ChatStreamChunk as r, type ToolCallContent as s, type PermissionContext as t, type PermissionBehavior as u, type PermissionRule as v, type AutoModeConfig as w, type PermissionDecision as x, type PermissionUpdate as y, type MemoryProvider as z };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { A as AgentOptions, a as Agent } from './agent-D0gl-qYi.js';
|
|
2
|
+
import { S as Sandbox } from './sandbox-DAqQo0Tj.js';
|
|
3
|
+
import './types-DLZNyF5t.js';
|
|
4
|
+
import './types-BX4ALqoN.js';
|
|
5
|
+
import './computer-DzMR92tK.js';
|
|
6
|
+
import './types-2kTLUCnD.js';
|
|
7
|
+
import '@modelcontextprotocol/sdk/client/index.js';
|
|
8
|
+
import '@modelcontextprotocol/sdk/client/auth.js';
|
|
9
|
+
import '@modelcontextprotocol/sdk/shared/auth.js';
|
|
10
|
+
|
|
11
|
+
interface UnsandboxedLocalOptions {
|
|
12
|
+
/** Working directory for both file resolution and command execution. */
|
|
13
|
+
cwd?: string;
|
|
14
|
+
/** Default timeout (ms) for shell commands. */
|
|
15
|
+
defaultTimeout?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create a `Sandbox` backed by the host filesystem and shell with **no
|
|
19
|
+
* OS-level isolation**. The agent can access anything the host process can.
|
|
20
|
+
*
|
|
21
|
+
* Use this for development or fully-trusted environments where sandboxing
|
|
22
|
+
* overhead is unwanted. For production use, prefer `LocalSandbox()` (which
|
|
23
|
+
* wraps commands with `@anthropic-ai/sandbox-runtime`).
|
|
24
|
+
*/
|
|
25
|
+
declare function UnsandboxedLocal(opts?: UnsandboxedLocalOptions): Sandbox;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Options for {@link UnsandboxedAgent} — the full `AgentOptions` surface
|
|
29
|
+
* minus `sandbox`, plus an optional `unsandboxed` block for tuning the
|
|
30
|
+
* default-created {@link UnsandboxedLocal} (timeouts, etc.).
|
|
31
|
+
*/
|
|
32
|
+
interface UnsandboxedAgentOptions extends Omit<AgentOptions, "sandbox"> {
|
|
33
|
+
/**
|
|
34
|
+
* Forwarded to {@link UnsandboxedLocal}. If `cwd` is omitted here it
|
|
35
|
+
* defaults to `opts.cwd` / `opts.options.cwd` / `process.cwd()`.
|
|
36
|
+
*/
|
|
37
|
+
unsandboxed?: Omit<UnsandboxedLocalOptions, "cwd"> & {
|
|
38
|
+
cwd?: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Convenience factory that constructs an {@link Agent} backed by an
|
|
43
|
+
* {@link UnsandboxedLocal} sandbox. Equivalent to:
|
|
44
|
+
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* new Agent({ ...opts, sandbox: UnsandboxedLocal({ cwd }) })
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* Lives on the `noumen/unsandboxed` subpath rather than the root barrel
|
|
50
|
+
* so that `import { Agent } from "noumen"` never transitively pulls
|
|
51
|
+
* `node:child_process` into the module graph. Callers who want raw host
|
|
52
|
+
* access opt into that cost at the import line.
|
|
53
|
+
*
|
|
54
|
+
* For production, prefer {@link "./local".LocalAgent} (OS-level sandboxing)
|
|
55
|
+
* or a remote sandbox subpath.
|
|
56
|
+
*/
|
|
57
|
+
declare function UnsandboxedAgent(opts: UnsandboxedAgentOptions): Agent;
|
|
58
|
+
|
|
59
|
+
export { UnsandboxedAgent, type UnsandboxedAgentOptions, UnsandboxedLocal, type UnsandboxedLocalOptions };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UnsandboxedLocal
|
|
3
|
+
} from "./chunk-BC5BLWBC.js";
|
|
4
|
+
import "./chunk-XQTNXRE7.js";
|
|
5
|
+
import {
|
|
6
|
+
Agent
|
|
7
|
+
} from "./chunk-5HY4IYNT.js";
|
|
8
|
+
import "./chunk-42PHHZUA.js";
|
|
9
|
+
import "./chunk-OPFFLQZL.js";
|
|
10
|
+
import "./chunk-3HEYCV26.js";
|
|
11
|
+
import "./chunk-CX4BL6PC.js";
|
|
12
|
+
import "./chunk-3SK5GCI6.js";
|
|
13
|
+
import "./chunk-HQISH4D7.js";
|
|
14
|
+
import "./chunk-JACGEMTF.js";
|
|
15
|
+
|
|
16
|
+
// src/unsandboxed.ts
|
|
17
|
+
function UnsandboxedAgent(opts) {
|
|
18
|
+
const cwd = opts.unsandboxed?.cwd ?? opts.cwd ?? opts.options?.cwd ?? process.cwd();
|
|
19
|
+
const { unsandboxed, ...rest } = opts;
|
|
20
|
+
return new Agent({
|
|
21
|
+
...rest,
|
|
22
|
+
sandbox: UnsandboxedLocal({
|
|
23
|
+
cwd,
|
|
24
|
+
defaultTimeout: unsandboxed?.defaultTimeout
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
UnsandboxedAgent,
|
|
30
|
+
UnsandboxedLocal
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=unsandboxed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/unsandboxed.ts"],"sourcesContent":["// Unsandboxed local binding — raw host access, no isolation.\n//\n// Importing this subpath is the explicit opt-in to a sandbox that gives the\n// agent everything the host process has. The root barrel (`noumen`) does not\n// re-export this module, so reaching for unsandboxed execution always shows\n// up as a dedicated import line.\n//\n// import { UnsandboxedLocal } from \"noumen/unsandboxed\";\n\nimport { Agent, type AgentOptions } from \"./agent.js\";\nimport { UnsandboxedLocal, type UnsandboxedLocalOptions } from \"./virtual/unsandboxed.js\";\n\nexport {\n UnsandboxedLocal,\n type UnsandboxedLocalOptions,\n} from \"./virtual/unsandboxed.js\";\n\n/**\n * Options for {@link UnsandboxedAgent} — the full `AgentOptions` surface\n * minus `sandbox`, plus an optional `unsandboxed` block for tuning the\n * default-created {@link UnsandboxedLocal} (timeouts, etc.).\n */\nexport interface UnsandboxedAgentOptions extends Omit<AgentOptions, \"sandbox\"> {\n /**\n * Forwarded to {@link UnsandboxedLocal}. If `cwd` is omitted here it\n * defaults to `opts.cwd` / `opts.options.cwd` / `process.cwd()`.\n */\n unsandboxed?: Omit<UnsandboxedLocalOptions, \"cwd\"> & { cwd?: string };\n}\n\n/**\n * Convenience factory that constructs an {@link Agent} backed by an\n * {@link UnsandboxedLocal} sandbox. Equivalent to:\n *\n * ```ts\n * new Agent({ ...opts, sandbox: UnsandboxedLocal({ cwd }) })\n * ```\n *\n * Lives on the `noumen/unsandboxed` subpath rather than the root barrel\n * so that `import { Agent } from \"noumen\"` never transitively pulls\n * `node:child_process` into the module graph. Callers who want raw host\n * access opt into that cost at the import line.\n *\n * For production, prefer {@link \"./local\".LocalAgent} (OS-level sandboxing)\n * or a remote sandbox subpath.\n */\nexport function UnsandboxedAgent(opts: UnsandboxedAgentOptions): Agent {\n const cwd = opts.unsandboxed?.cwd ?? opts.cwd ?? opts.options?.cwd ?? process.cwd();\n const { unsandboxed, ...rest } = opts;\n return new Agent({\n ...rest,\n sandbox: UnsandboxedLocal({\n cwd,\n defaultTimeout: unsandboxed?.defaultTimeout,\n }),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA8CO,SAAS,iBAAiB,MAAsC;AACrE,QAAM,MAAM,KAAK,aAAa,OAAO,KAAK,OAAO,KAAK,SAAS,OAAO,QAAQ,IAAI;AAClF,QAAM,EAAE,aAAa,GAAG,KAAK,IAAI;AACjC,SAAO,IAAI,MAAM;AAAA,IACf,GAAG;AAAA,IACH,SAAS,iBAAiB;AAAA,MACxB;AAAA,MACA,gBAAgB,aAAa;AAAA,IAC/B,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
|
@@ -3,10 +3,9 @@ import {
|
|
|
3
3
|
registerZodToJsonSchema,
|
|
4
4
|
zodToJsonSchema
|
|
5
5
|
} from "./chunk-3SK5GCI6.js";
|
|
6
|
-
import "./chunk-DGUM43GV.js";
|
|
7
6
|
export {
|
|
8
7
|
formatZodValidationError,
|
|
9
8
|
registerZodToJsonSchema,
|
|
10
9
|
zodToJsonSchema
|
|
11
10
|
};
|
|
12
|
-
//# sourceMappingURL=zod-
|
|
11
|
+
//# sourceMappingURL=zod-VKURGPRT.js.map
|