@artenx/dshb 0.1.9 → 0.1.10
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/lib/client.js +8 -8
- package/lib/client.js.map +1 -1
- package/lib/core/index.js +5 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/routes.d.ts +8 -1
- package/lib/core/routes.js +65 -3
- package/lib/core/routes.js.map +1 -1
- package/lib/core/workspace-bindings.js +6 -4
- package/lib/core/workspace-bindings.js.map +1 -1
- package/lib/exec-docker/daemon-runner.js +2 -2
- package/lib/exec-docker/docker-backend.d.ts +8 -0
- package/lib/exec-docker/docker-client.d.ts +9 -0
- package/lib/exec-docker/docker-client.js +10 -2
- package/lib/exec-docker/docker-client.js.map +1 -1
- package/lib/exec-docker/docker-routes.js +1 -1
- package/lib/exec-docker/fs-provider.d.ts +3 -12
- package/lib/exec-docker/fs-provider.js +19 -2
- package/lib/exec-docker/fs-provider.js.map +1 -1
- package/lib/exec-docker/index.js +1 -1
- package/lib/exec-docker/remote-docker-cli.d.ts +8 -0
- package/lib/exec-docker/remote-docker-cli.js +27 -1
- package/lib/exec-docker/remote-docker-cli.js.map +1 -1
- package/lib/exec-docker/world.d.ts +1 -1
- package/lib/exec-ssh/executor.d.ts +7 -0
- package/lib/exec-ssh/executor.js +18 -0
- package/lib/exec-ssh/executor.js.map +1 -1
- package/lib/exec-ssh/fs-provider.d.ts +3 -12
- package/lib/exec-ssh/fs-provider.js +20 -3
- package/lib/exec-ssh/fs-provider.js.map +1 -1
- package/lib/exec-ssh/world.d.ts +1 -1
- package/lib/router/decorate-fs.js +16 -2
- package/lib/router/decorate-fs.js.map +1 -1
- package/lib/router/decorate-shell.d.ts +1 -1
- package/lib/router/index.d.ts +1 -1
- package/lib/router/resolve.d.ts +1 -1
- package/lib/router/router-fs.d.ts +1 -1
- package/lib/router/types.d.ts +1 -1
- package/lib/{types-ekJQQ4x6.d.ts → types-DPP05ZsA.d.ts} +2 -2
- package/package.json +1 -1
|
@@ -36,6 +36,14 @@ declare class RemoteDockerCli implements DockerBackend {
|
|
|
36
36
|
mtime: number;
|
|
37
37
|
isDirectory: boolean;
|
|
38
38
|
isFile: boolean;
|
|
39
|
+
isSymlink: boolean;
|
|
40
|
+
} | undefined>;
|
|
41
|
+
lstat(path: string): Promise<{
|
|
42
|
+
size: number;
|
|
43
|
+
mtime: number;
|
|
44
|
+
isDirectory: boolean;
|
|
45
|
+
isFile: boolean;
|
|
46
|
+
isSymlink: boolean;
|
|
39
47
|
} | undefined>;
|
|
40
48
|
mkdir(path: string): Promise<void>;
|
|
41
49
|
remove(path: string): Promise<void>;
|
|
@@ -81,6 +81,7 @@ var RemoteDockerCli = class {
|
|
|
81
81
|
"exec",
|
|
82
82
|
this.containerId,
|
|
83
83
|
"stat",
|
|
84
|
+
"-L",
|
|
84
85
|
"-c",
|
|
85
86
|
"%s %Y %F",
|
|
86
87
|
path
|
|
@@ -95,7 +96,32 @@ var RemoteDockerCli = class {
|
|
|
95
96
|
size,
|
|
96
97
|
mtime,
|
|
97
98
|
isDirectory: ftype.includes("directory"),
|
|
98
|
-
isFile: ftype.includes("regular")
|
|
99
|
+
isFile: ftype.includes("regular"),
|
|
100
|
+
isSymlink: ftype.includes("symbolic link")
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
async lstat(path) {
|
|
104
|
+
const line = (await this.ssh.exec([
|
|
105
|
+
"docker",
|
|
106
|
+
"exec",
|
|
107
|
+
this.containerId,
|
|
108
|
+
"stat",
|
|
109
|
+
"-c",
|
|
110
|
+
"%s %Y %F",
|
|
111
|
+
path
|
|
112
|
+
], "/")).stdout.trim();
|
|
113
|
+
if (!line) return void 0;
|
|
114
|
+
const parts = line.split(/\s+/);
|
|
115
|
+
if (parts.length < 3) return void 0;
|
|
116
|
+
const size = Number(parts[0]);
|
|
117
|
+
const mtime = Number(parts[1]) * 1e3;
|
|
118
|
+
const ftype = parts.slice(2).join(" ");
|
|
119
|
+
return {
|
|
120
|
+
size,
|
|
121
|
+
mtime,
|
|
122
|
+
isDirectory: ftype.includes("directory"),
|
|
123
|
+
isFile: ftype.includes("regular"),
|
|
124
|
+
isSymlink: ftype.includes("symbolic link")
|
|
99
125
|
};
|
|
100
126
|
}
|
|
101
127
|
async mkdir(path) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-docker-cli.js","names":[],"sources":["../../src/exec-docker/remote-docker-cli.ts"],"sourcesContent":["import type { DockerBackend } from './docker-backend.js'\n\ninterface SshExecutorLike {\n exec(argv: string[], cwd: string, env?: Record<string, string>, stdinData?: Buffer): Promise<{ code: number; stdout: string; stderr: string }>\n}\n\nexport class RemoteDockerCli implements DockerBackend {\n constructor(\n private readonly ssh: SshExecutorLike,\n private readonly containerId: string,\n ) {}\n\n async exec(argv: string[], cwd: string, env: Record<string, string> = {}, stdinData?: Buffer): Promise<{ code: number; stdout: string; stderr: string }> {\n const envFlags = Object.entries(env).map(([k, v]) => ['-e', `${k}=${v}`]).flat()\n return this.ssh.exec(['docker', 'exec', '-w', cwd, ...envFlags, this.containerId, ...argv], '/', {}, stdinData)\n }\n\n async execShell(command: string, cwd: string): Promise<{ code: number; stdout: string; stderr: string }> {\n return this.ssh.exec(['docker', 'exec', '-w', cwd, this.containerId, 'bash', '-c', command], '/')\n }\n\n async readFile(path: string): Promise<Buffer> {\n const result = await this.ssh.exec(['docker', 'exec', this.containerId, 'cat', path], '/')\n return Buffer.from(result.stdout, 'utf8')\n }\n\n async writeFile(path: string, content: Buffer | string): Promise<void> {\n const data = Buffer.isBuffer(content) ? content : Buffer.from(content, 'utf8')\n const b64 = data.toString('base64')\n await this.ssh.exec(['docker', 'exec', this.containerId, 'bash', '-c', `printf '%s' '${b64}' | base64 -d > '${path.replace(/'/g, \"'\\\\''\")}'`], '/')\n }\n\n async listDir(path: string): Promise<Array<{ name: string; isDir: boolean; isFile: boolean; isSymlink: boolean; size: number; mtime: number }>> {\n const result = await this.ssh.exec(['docker', 'exec', this.containerId, 'ls', '-1pa', '--time-style=+%s', path], '/')\n return result.stdout\n .split('\\n')\n .filter((line) => line.trim())\n .map((line) => {\n const name = line.replace(/[/@*]$/, '').trim()\n if (!name) return null\n const isDir = line.endsWith('/')\n const isSymlink = line.endsWith('@')\n return { name, isDir, isFile: !isDir && !isSymlink, isSymlink, size: 0, mtime: 0 }\n })\n .filter((e): e is NonNullable<typeof e> => e !== null)\n }\n\n async stat(path: string): Promise<{ size: number; mtime: number; isDirectory: boolean; isFile: boolean } | undefined> {\n const result = await this.ssh.exec(['docker', 'exec', this.containerId, 'stat', '-c', '%s %Y %F', path], '/')\n const line = result.stdout.trim()\n if (!line) return undefined\n const parts = line.split(/\\s+/)\n if (parts.length < 3) return undefined\n const size = Number(parts[0])\n const mtime = Number(parts[1]) * 1000\n const ftype = parts.slice(2).join(' ')\n return { size, mtime, isDirectory: ftype.includes('directory'), isFile: ftype.includes('regular') }\n }\n\n async mkdir(path: string): Promise<void> {\n await this.ssh.exec(['docker', 'exec', this.containerId, 'mkdir', '-p', path], '/')\n }\n\n async remove(path: string): Promise<void> {\n await this.ssh.exec(['docker', 'exec', this.containerId, 'rm', '-f', path], '/')\n }\n\n async rename(src: string, dest: string): Promise<void> {\n await this.ssh.exec(['docker', 'exec', this.containerId, 'mv', src, dest], '/')\n }\n\n async ensureRg(): Promise<void> {\n const result = await this.ssh.exec(['docker', 'exec', this.containerId, 'bash', '-c', 'command -v rg || echo __missing__'], '/')\n if (result.stdout.includes('__missing__')) {\n await this.ssh.exec(['docker', 'exec', this.containerId, 'bash', '-c', 'apk add --no-cache ripgrep 2>/dev/null || apt-get install -y ripgrep 2>/dev/null || true'], '/')\n }\n }\n\n async pty(_argv: string[], _cwd: string, _cols: number, _rows: number, _env?: Record<string, string>, _terminalType?: string): Promise<{ stream: NodeJS.ReadWriteStream; resize: (c: number, r: number) => void; kill: () => void }> {\n throw new Error('remote docker PTY not yet supported')\n }\n}\n"],"mappings":";AAMA,IAAa,kBAAb,MAAsD;CAEjC;CACA;CAFnB,YACE,KACA,aACA;EAFiB,KAAA,MAAA;EACA,KAAA,cAAA;CAChB;CAEH,MAAM,KAAK,MAAgB,KAAa,MAA8B,CAAC,GAAG,WAA+E;EACvJ,MAAM,WAAW,OAAO,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK;EAC/E,OAAO,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ;GAAM;GAAK,GAAG;GAAU,KAAK;GAAa,GAAG;EAAI,GAAG,KAAK,CAAC,GAAG,SAAS;CAChH;CAEA,MAAM,UAAU,SAAiB,KAAwE;EACvG,OAAO,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ;GAAM;GAAK,KAAK;GAAa;GAAQ;GAAM;EAAO,GAAG,GAAG;CAClG;CAEA,MAAM,SAAS,MAA+B;EAC5C,MAAM,SAAS,MAAM,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAO;EAAI,GAAG,GAAG;EACzF,OAAO,OAAO,KAAK,OAAO,QAAQ,MAAM;CAC1C;CAEA,MAAM,UAAU,MAAc,SAAyC;EAErE,MAAM,OADO,OAAO,SAAS,OAAO,IAAI,UAAU,OAAO,KAAK,SAAS,MAAM,EAAA,CAC5D,SAAS,QAAQ;EAClC,MAAM,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAQ;GAAM,gBAAgB,IAAI,mBAAmB,KAAK,QAAQ,MAAM,OAAO,EAAE;EAAE,GAAG,GAAG;CACpJ;CAEA,MAAM,QAAQ,MAAkI;EAE9I,QAAO,MADc,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAM;GAAQ;GAAoB;EAAI,GAAG,GAAG,EAAA,CACtG,OACX,MAAM,IAAI,CAAC,CACX,QAAQ,SAAS,KAAK,KAAK,CAAC,CAAC,CAC7B,KAAK,SAAS;GACb,MAAM,OAAO,KAAK,QAAQ,UAAU,EAAE,CAAC,CAAC,KAAK;GAC7C,IAAI,CAAC,MAAM,OAAO;GAClB,MAAM,QAAQ,KAAK,SAAS,GAAG;GAC/B,MAAM,YAAY,KAAK,SAAS,GAAG;GACnC,OAAO;IAAE;IAAM;IAAO,QAAQ,CAAC,SAAS,CAAC;IAAW;IAAW,MAAM;IAAG,OAAO;GAAE;EACnF,CAAC,CAAC,CACD,QAAQ,MAAkC,MAAM,IAAI;CACzD;CAEA,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"remote-docker-cli.js","names":[],"sources":["../../src/exec-docker/remote-docker-cli.ts"],"sourcesContent":["import type { DockerBackend } from './docker-backend.js'\n\ninterface SshExecutorLike {\n exec(argv: string[], cwd: string, env?: Record<string, string>, stdinData?: Buffer): Promise<{ code: number; stdout: string; stderr: string }>\n}\n\nexport class RemoteDockerCli implements DockerBackend {\n constructor(\n private readonly ssh: SshExecutorLike,\n private readonly containerId: string,\n ) {}\n\n async exec(argv: string[], cwd: string, env: Record<string, string> = {}, stdinData?: Buffer): Promise<{ code: number; stdout: string; stderr: string }> {\n const envFlags = Object.entries(env).map(([k, v]) => ['-e', `${k}=${v}`]).flat()\n return this.ssh.exec(['docker', 'exec', '-w', cwd, ...envFlags, this.containerId, ...argv], '/', {}, stdinData)\n }\n\n async execShell(command: string, cwd: string): Promise<{ code: number; stdout: string; stderr: string }> {\n return this.ssh.exec(['docker', 'exec', '-w', cwd, this.containerId, 'bash', '-c', command], '/')\n }\n\n async readFile(path: string): Promise<Buffer> {\n const result = await this.ssh.exec(['docker', 'exec', this.containerId, 'cat', path], '/')\n return Buffer.from(result.stdout, 'utf8')\n }\n\n async writeFile(path: string, content: Buffer | string): Promise<void> {\n const data = Buffer.isBuffer(content) ? content : Buffer.from(content, 'utf8')\n const b64 = data.toString('base64')\n await this.ssh.exec(['docker', 'exec', this.containerId, 'bash', '-c', `printf '%s' '${b64}' | base64 -d > '${path.replace(/'/g, \"'\\\\''\")}'`], '/')\n }\n\n async listDir(path: string): Promise<Array<{ name: string; isDir: boolean; isFile: boolean; isSymlink: boolean; size: number; mtime: number }>> {\n const result = await this.ssh.exec(['docker', 'exec', this.containerId, 'ls', '-1pa', '--time-style=+%s', path], '/')\n return result.stdout\n .split('\\n')\n .filter((line) => line.trim())\n .map((line) => {\n const name = line.replace(/[/@*]$/, '').trim()\n if (!name) return null\n const isDir = line.endsWith('/')\n const isSymlink = line.endsWith('@')\n return { name, isDir, isFile: !isDir && !isSymlink, isSymlink, size: 0, mtime: 0 }\n })\n .filter((e): e is NonNullable<typeof e> => e !== null)\n }\n\n async stat(path: string): Promise<{ size: number; mtime: number; isDirectory: boolean; isFile: boolean; isSymlink: boolean } | undefined> {\n const result = await this.ssh.exec(['docker', 'exec', this.containerId, 'stat', '-L', '-c', '%s %Y %F', path], '/')\n const line = result.stdout.trim()\n if (!line) return undefined\n const parts = line.split(/\\s+/)\n if (parts.length < 3) return undefined\n const size = Number(parts[0])\n const mtime = Number(parts[1]) * 1000\n const ftype = parts.slice(2).join(' ')\n return { size, mtime, isDirectory: ftype.includes('directory'), isFile: ftype.includes('regular'), isSymlink: ftype.includes('symbolic link') }\n }\n\n async lstat(path: string): Promise<{ size: number; mtime: number; isDirectory: boolean; isFile: boolean; isSymlink: boolean } | undefined> {\n const result = await this.ssh.exec(['docker', 'exec', this.containerId, 'stat', '-c', '%s %Y %F', path], '/')\n const line = result.stdout.trim()\n if (!line) return undefined\n const parts = line.split(/\\s+/)\n if (parts.length < 3) return undefined\n const size = Number(parts[0])\n const mtime = Number(parts[1]) * 1000\n const ftype = parts.slice(2).join(' ')\n return { size, mtime, isDirectory: ftype.includes('directory'), isFile: ftype.includes('regular'), isSymlink: ftype.includes('symbolic link') }\n }\n\n async mkdir(path: string): Promise<void> {\n await this.ssh.exec(['docker', 'exec', this.containerId, 'mkdir', '-p', path], '/')\n }\n\n async remove(path: string): Promise<void> {\n await this.ssh.exec(['docker', 'exec', this.containerId, 'rm', '-f', path], '/')\n }\n\n async rename(src: string, dest: string): Promise<void> {\n await this.ssh.exec(['docker', 'exec', this.containerId, 'mv', src, dest], '/')\n }\n\n async ensureRg(): Promise<void> {\n const result = await this.ssh.exec(['docker', 'exec', this.containerId, 'bash', '-c', 'command -v rg || echo __missing__'], '/')\n if (result.stdout.includes('__missing__')) {\n await this.ssh.exec(['docker', 'exec', this.containerId, 'bash', '-c', 'apk add --no-cache ripgrep 2>/dev/null || apt-get install -y ripgrep 2>/dev/null || true'], '/')\n }\n }\n\n async pty(_argv: string[], _cwd: string, _cols: number, _rows: number, _env?: Record<string, string>, _terminalType?: string): Promise<{ stream: NodeJS.ReadWriteStream; resize: (c: number, r: number) => void; kill: () => void }> {\n throw new Error('remote docker PTY not yet supported')\n }\n}\n"],"mappings":";AAMA,IAAa,kBAAb,MAAsD;CAEjC;CACA;CAFnB,YACE,KACA,aACA;EAFiB,KAAA,MAAA;EACA,KAAA,cAAA;CAChB;CAEH,MAAM,KAAK,MAAgB,KAAa,MAA8B,CAAC,GAAG,WAA+E;EACvJ,MAAM,WAAW,OAAO,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK;EAC/E,OAAO,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ;GAAM;GAAK,GAAG;GAAU,KAAK;GAAa,GAAG;EAAI,GAAG,KAAK,CAAC,GAAG,SAAS;CAChH;CAEA,MAAM,UAAU,SAAiB,KAAwE;EACvG,OAAO,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ;GAAM;GAAK,KAAK;GAAa;GAAQ;GAAM;EAAO,GAAG,GAAG;CAClG;CAEA,MAAM,SAAS,MAA+B;EAC5C,MAAM,SAAS,MAAM,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAO;EAAI,GAAG,GAAG;EACzF,OAAO,OAAO,KAAK,OAAO,QAAQ,MAAM;CAC1C;CAEA,MAAM,UAAU,MAAc,SAAyC;EAErE,MAAM,OADO,OAAO,SAAS,OAAO,IAAI,UAAU,OAAO,KAAK,SAAS,MAAM,EAAA,CAC5D,SAAS,QAAQ;EAClC,MAAM,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAQ;GAAM,gBAAgB,IAAI,mBAAmB,KAAK,QAAQ,MAAM,OAAO,EAAE;EAAE,GAAG,GAAG;CACpJ;CAEA,MAAM,QAAQ,MAAkI;EAE9I,QAAO,MADc,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAM;GAAQ;GAAoB;EAAI,GAAG,GAAG,EAAA,CACtG,OACX,MAAM,IAAI,CAAC,CACX,QAAQ,SAAS,KAAK,KAAK,CAAC,CAAC,CAC7B,KAAK,SAAS;GACb,MAAM,OAAO,KAAK,QAAQ,UAAU,EAAE,CAAC,CAAC,KAAK;GAC7C,IAAI,CAAC,MAAM,OAAO;GAClB,MAAM,QAAQ,KAAK,SAAS,GAAG;GAC/B,MAAM,YAAY,KAAK,SAAS,GAAG;GACnC,OAAO;IAAE;IAAM;IAAO,QAAQ,CAAC,SAAS,CAAC;IAAW;IAAW,MAAM;IAAG,OAAO;GAAE;EACnF,CAAC,CAAC,CACD,QAAQ,MAAkC,MAAM,IAAI;CACzD;CAEA,MAAM,KAAK,MAA+H;EAExI,MAAM,QAAO,MADQ,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAQ;GAAM;GAAM;GAAY;EAAI,GAAG,GAAG,EAAA,CAC9F,OAAO,KAAK;EAChC,IAAI,CAAC,MAAM,OAAO,KAAA;EAClB,MAAM,QAAQ,KAAK,MAAM,KAAK;EAC9B,IAAI,MAAM,SAAS,GAAG,OAAO,KAAA;EAC7B,MAAM,OAAO,OAAO,MAAM,EAAE;EAC5B,MAAM,QAAQ,OAAO,MAAM,EAAE,IAAI;EACjC,MAAM,QAAQ,MAAM,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG;EACrC,OAAO;GAAE;GAAM;GAAO,aAAa,MAAM,SAAS,WAAW;GAAG,QAAQ,MAAM,SAAS,SAAS;GAAG,WAAW,MAAM,SAAS,eAAe;EAAE;CAChJ;CAEA,MAAM,MAAM,MAA+H;EAEzI,MAAM,QAAO,MADQ,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAQ;GAAM;GAAY;EAAI,GAAG,GAAG,EAAA,CACxF,OAAO,KAAK;EAChC,IAAI,CAAC,MAAM,OAAO,KAAA;EAClB,MAAM,QAAQ,KAAK,MAAM,KAAK;EAC9B,IAAI,MAAM,SAAS,GAAG,OAAO,KAAA;EAC7B,MAAM,OAAO,OAAO,MAAM,EAAE;EAC5B,MAAM,QAAQ,OAAO,MAAM,EAAE,IAAI;EACjC,MAAM,QAAQ,MAAM,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG;EACrC,OAAO;GAAE;GAAM;GAAO,aAAa,MAAM,SAAS,WAAW;GAAG,QAAQ,MAAM,SAAS,SAAS;GAAG,WAAW,MAAM,SAAS,eAAe;EAAE;CAChJ;CAEA,MAAM,MAAM,MAA6B;EACvC,MAAM,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAS;GAAM;EAAI,GAAG,GAAG;CACpF;CAEA,MAAM,OAAO,MAA6B;EACxC,MAAM,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAM;GAAM;EAAI,GAAG,GAAG;CACjF;CAEA,MAAM,OAAO,KAAa,MAA6B;EACrD,MAAM,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAM;GAAK;EAAI,GAAG,GAAG;CAChF;CAEA,MAAM,WAA0B;EAE9B,KAAI,MADiB,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAQ;GAAM;EAAmC,GAAG,GAAG,EAAA,CACpH,OAAO,SAAS,aAAa,GACtC,MAAM,KAAK,IAAI,KAAK;GAAC;GAAU;GAAQ,KAAK;GAAa;GAAQ;GAAM;EAA0F,GAAG,GAAG;CAE3K;CAEA,MAAM,IAAI,OAAiB,MAAc,OAAe,OAAe,MAA+B,eAA+H;EACnO,MAAM,IAAI,MAAM,qCAAqC;CACvD;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DockerBackend } from "./docker-backend.js";
|
|
2
2
|
import { DockerFileSystem } from "./fs-provider.js";
|
|
3
|
-
import { a as NodeTestReport, t as ExecutionWorldProvider } from "../types-
|
|
3
|
+
import { a as NodeTestReport, t as ExecutionWorldProvider } from "../types-DPP05ZsA.js";
|
|
4
4
|
import { DockerShellExecutor, DockerSubprocessRuntime } from "./process-provider.js";
|
|
5
5
|
//#region src/exec-docker/world.d.ts
|
|
6
6
|
interface DockerNodeConfig {
|
|
@@ -30,6 +30,13 @@ declare class SshExecutor {
|
|
|
30
30
|
isDirectory: boolean;
|
|
31
31
|
isFile: boolean;
|
|
32
32
|
} | undefined>;
|
|
33
|
+
lstat(path: string): Promise<{
|
|
34
|
+
size: number;
|
|
35
|
+
mtime: number;
|
|
36
|
+
isDirectory: boolean;
|
|
37
|
+
isFile: boolean;
|
|
38
|
+
isSymlink: boolean;
|
|
39
|
+
} | undefined>;
|
|
33
40
|
mkdir(path: string): Promise<void>;
|
|
34
41
|
remove(path: string): Promise<void>;
|
|
35
42
|
rename(src: string, dest: string): Promise<void>;
|
package/lib/exec-ssh/executor.js
CHANGED
|
@@ -117,6 +117,24 @@ var SshExecutor = class {
|
|
|
117
117
|
});
|
|
118
118
|
});
|
|
119
119
|
}
|
|
120
|
+
async lstat(path) {
|
|
121
|
+
const sftp = await this.sftp();
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
sftp.lstat(path, (err, stats) => {
|
|
124
|
+
if (err) {
|
|
125
|
+
resolve(void 0);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
resolve({
|
|
129
|
+
size: Number(stats.size),
|
|
130
|
+
mtime: stats.mtime * 1e3,
|
|
131
|
+
isDirectory: stats.isDirectory(),
|
|
132
|
+
isFile: stats.isFile(),
|
|
133
|
+
isSymlink: stats.isSymbolicLink()
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}
|
|
120
138
|
async mkdir(path) {
|
|
121
139
|
const sftp = await this.sftp();
|
|
122
140
|
return new Promise((resolve, reject) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.js","names":[],"sources":["../../src/exec-ssh/executor.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { encodeRunnerPayload, REMOTE_RUNNER_COMMAND, type RunnerPayload } from './runner.js'\nimport type { SshConnection } from './connection.js'\n\nexport interface ExecResult {\n code: number\n signal?: string\n stdout: string\n stderr: string\n}\n\nexport class SshExecutor {\n private sftpCache: Promise<import('ssh2').SFTPWrapper> | null = null\n\n constructor(\n private readonly connection: SshConnection,\n private readonly nodeId = 'unknown',\n private readonly audit?: (op: string, target: string, result: string) => void,\n ) {}\n\n async exec(argv: string[], cwd: string, env: Record<string, string> = {}, stdinData?: Buffer): Promise<ExecResult> {\n const client = await this.connection.getClient()\n const payload: RunnerPayload = { argv, cwd, env }\n const body = encodeRunnerPayload(payload)\n const input = stdinData ? Buffer.concat([body, stdinData]) : body\n return new Promise((resolve, reject) => {\n client.exec(REMOTE_RUNNER_COMMAND, (err, channel) => {\n if (err) {\n reject(err)\n return\n }\n const stdout: Buffer[] = []\n const stderr: Buffer[] = []\n channel.stdout.on('data', (chunk: Buffer) => stdout.push(chunk))\n channel.stderr.on('data', (chunk: Buffer) => stderr.push(chunk))\n channel.on('close', (code: number, signal: string) => {\n this.audit?.('exec', argv.join(' '), `code=${code ?? 0}`)\n resolve({\n code: code ?? 0,\n signal,\n stdout: Buffer.concat(stdout).toString('utf8'),\n stderr: Buffer.concat(stderr).toString('utf8'),\n })\n })\n channel.on('error', reject)\n channel.end(input)\n })\n })\n }\n\n async sftp(): Promise<import('ssh2').SFTPWrapper> {\n if (this.sftpCache) return this.sftpCache\n const client = await this.connection.getClient()\n this.sftpCache = new Promise((resolve, reject) => {\n client.sftp((err, sftp) => {\n if (err) reject(err)\n else resolve(sftp)\n })\n })\n return this.sftpCache\n }\n\n async readFile(path: string): Promise<Buffer> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.readFile(path, (err, data) => (err ? reject(err) : resolve(data)))\n })\n }\n\n async writeFile(path: string, content: Buffer | string): Promise<void> {\n const sftp = await this.sftp()\n const tmp = `${path}.dshb-tmp-${process.pid}-${Date.now()}`\n return new Promise((resolve, reject) => {\n sftp.writeFile(tmp, content, (writeErr) => {\n if (writeErr) {\n reject(writeErr)\n return\n }\n sftp.ext_openssh_rename(tmp, path, (renameErr) => {\n if (renameErr) reject(renameErr)\n else {\n this.audit?.('write', path, 'ok')\n resolve()\n }\n })\n })\n })\n }\n\n async listDir(path: string): Promise<Array<{ name: string; isDir: boolean; isFile: boolean; isSymlink: boolean; size: number; mtime: number }>> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.readdir(path, (err, list) => {\n if (err) {\n reject(err)\n return\n }\n resolve(\n list.map((e) => ({\n name: e.filename,\n isDir: e.attrs.isDirectory(),\n isFile: e.attrs.isFile(),\n isSymlink: e.attrs.isSymbolicLink(),\n size: Number(e.attrs.size),\n mtime: e.attrs.mtime * 1000,\n })),\n )\n })\n })\n }\n\n async stat(path: string): Promise<{ size: number; mtime: number; isDirectory: boolean; isFile: boolean } | undefined> {\n const sftp = await this.sftp()\n return new Promise((resolve) => {\n sftp.stat(path, (err, stats) => {\n if (err) {\n resolve(undefined)\n return\n }\n resolve({ size: Number(stats.size), mtime: stats.mtime * 1000, isDirectory: stats.isDirectory(), isFile: stats.isFile() })\n })\n })\n }\n\n async mkdir(path: string): Promise<void> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.mkdir(path, (err) => (err ? reject(err) : resolve()))\n })\n }\n\n async remove(path: string): Promise<void> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.unlink(path, (err) => {\n if (err) reject(err)\n else {\n this.audit?.('remove', path, 'ok')\n resolve()\n }\n })\n })\n }\n\n async rename(src: string, dest: string): Promise<void> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.ext_openssh_rename(src, dest, (err) => {\n if (err) reject(err)\n else {\n this.audit?.('move', `${src} -> ${dest}`, 'ok')\n resolve()\n }\n })\n })\n }\n\n async ensureRg(): Promise<void> {\n const result = await this.exec(['sh', '-c', 'command -v rg || echo \"__DShB_RG_MISSING__\"'], '/')\n if (result.stdout.includes('__DShB_RG_MISSING__')) {\n const localRg = process.env.DSHB_LOCAL_RG ?? findLocalRg()\n if (!localRg) return\n const remoteRgDir = '~/.dshb/bin'\n await this.exec(['mkdir', '-p', remoteRgDir], '/')\n const remoteRg = `${remoteRgDir}/rg`\n const content = readFileSync(localRg)\n await this.writeFile(remoteRg, content)\n await this.exec(['chmod', '+x', remoteRg], '/')\n }\n }\n\n async pty(argv: string[], cwd: string, env: Record<string, string>, cols: number, rows: number, terminalType = 'xterm-256color'): Promise<{ channel: import('ssh2').ClientChannel; resize: (cols: number, rows: number) => void; kill: () => void }> {\n const client = await this.connection.getClient()\n const q = (s: string) => `'${s.replace(/'/g, \"'\\\\''\")}'`\n const environment = Object.entries(env).map(([key, value]) => {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`invalid terminal environment key: ${key}`)\n return `${key}=${value}`\n })\n const command = `bash -c 'cd \"$0\" && exec env -i HOME=\"$HOME\" PATH=\"\\${PATH:-/usr/local/bin:/usr/bin:/bin}\" \"$@\"' ${q(cwd)} ${[...environment, ...argv].map(q).join(' ')}`\n return new Promise((resolve, reject) => {\n client.exec(\n command,\n { pty: { cols, rows, term: terminalType } },\n (err, channel) => {\n if (err) {\n reject(err)\n return\n }\n resolve({\n channel,\n resize: (c, r) => channel.setWindow(c, r, 0, 0),\n kill: () => channel.close(),\n })\n },\n )\n })\n }\n}\n\nfunction findLocalRg(): string | undefined {\n const candidates = [\n join(homedir(), '.dsh', 'node_modules', '.bin', 'rg'),\n join(homedir(), '.dsh', 'node_modules', '@vscode', 'ripgrep', 'bin', 'rg'),\n join(homedir(), 'go', 'bin', 'rg'),\n '/usr/local/bin/rg',\n '/usr/bin/rg',\n ]\n for (const c of candidates) if (existsSync(c)) return c\n return undefined\n}\n"],"mappings":";;;;;AAaA,IAAa,cAAb,MAAyB;CAIJ;CACA;CACA;CALnB,YAAgE;CAEhE,YACE,YACA,SAA0B,WAC1B,OACA;EAHiB,KAAA,aAAA;EACA,KAAA,SAAA;EACA,KAAA,QAAA;CAChB;CAEH,MAAM,KAAK,MAAgB,KAAa,MAA8B,CAAC,GAAG,WAAyC;EACjH,MAAM,SAAS,MAAM,KAAK,WAAW,UAAU;EAE/C,MAAM,OAAO,oBAAoB;GADA;GAAM;GAAK;EACL,CAAC;EACxC,MAAM,QAAQ,YAAY,OAAO,OAAO,CAAC,MAAM,SAAS,CAAC,IAAI;EAC7D,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,OAAO,KAAK,wBAAwB,KAAK,YAAY;IACnD,IAAI,KAAK;KACP,OAAO,GAAG;KACV;IACF;IACA,MAAM,SAAmB,CAAC;IAC1B,MAAM,SAAmB,CAAC;IAC1B,QAAQ,OAAO,GAAG,SAAS,UAAkB,OAAO,KAAK,KAAK,CAAC;IAC/D,QAAQ,OAAO,GAAG,SAAS,UAAkB,OAAO,KAAK,KAAK,CAAC;IAC/D,QAAQ,GAAG,UAAU,MAAc,WAAmB;KACpD,KAAK,QAAQ,QAAQ,KAAK,KAAK,GAAG,GAAG,QAAQ,QAAQ,GAAG;KACxD,QAAQ;MACN,MAAM,QAAQ;MACd;MACA,QAAQ,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM;MAC7C,QAAQ,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM;KAC/C,CAAC;IACH,CAAC;IACD,QAAQ,GAAG,SAAS,MAAM;IAC1B,QAAQ,IAAI,KAAK;GACnB,CAAC;EACH,CAAC;CACH;CAEA,MAAM,OAA4C;EAChD,IAAI,KAAK,WAAW,OAAO,KAAK;EAChC,MAAM,SAAS,MAAM,KAAK,WAAW,UAAU;EAC/C,KAAK,YAAY,IAAI,SAAS,SAAS,WAAW;GAChD,OAAO,MAAM,KAAK,SAAS;IACzB,IAAI,KAAK,OAAO,GAAG;SACd,QAAQ,IAAI;GACnB,CAAC;EACH,CAAC;EACD,OAAO,KAAK;CACd;CAEA,MAAM,SAAS,MAA+B;EAC5C,MAAM,OAAO,MAAM,KAAK,KAAK;EAC7B,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,KAAK,SAAS,OAAO,KAAK,SAAU,MAAM,OAAO,GAAG,IAAI,QAAQ,IAAI,CAAE;EACxE,CAAC;CACH;CAEA,MAAM,UAAU,MAAc,SAAyC;EACrE,MAAM,OAAO,MAAM,KAAK,KAAK;EAC7B,MAAM,MAAM,GAAG,KAAK,YAAY,QAAQ,IAAI,GAAG,KAAK,IAAI;EACxD,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,KAAK,UAAU,KAAK,UAAU,aAAa;IACzC,IAAI,UAAU;KACZ,OAAO,QAAQ;KACf;IACF;IACA,KAAK,mBAAmB,KAAK,OAAO,cAAc;KAChD,IAAI,WAAW,OAAO,SAAS;UAC1B;MACH,KAAK,QAAQ,SAAS,MAAM,IAAI;MAChC,QAAQ;KACV;IACF,CAAC;GACH,CAAC;EACH,CAAC;CACH;CAEA,MAAM,QAAQ,MAAkI;EAC9I,MAAM,OAAO,MAAM,KAAK,KAAK;EAC7B,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,KAAK,QAAQ,OAAO,KAAK,SAAS;IAChC,IAAI,KAAK;KACP,OAAO,GAAG;KACV;IACF;IACA,QACE,KAAK,KAAK,OAAO;KACf,MAAM,EAAE;KACR,OAAO,EAAE,MAAM,YAAY;KAC3B,QAAQ,EAAE,MAAM,OAAO;KACvB,WAAW,EAAE,MAAM,eAAe;KAClC,MAAM,OAAO,EAAE,MAAM,IAAI;KACzB,OAAO,EAAE,MAAM,QAAQ;IACzB,EAAE,CACJ;GACF,CAAC;EACH,CAAC;CACH;CAEA,MAAM,KAAK,MAA2G;EACpH,MAAM,OAAO,MAAM,KAAK,KAAK;EAC7B,OAAO,IAAI,SAAS,YAAY;GAC9B,KAAK,KAAK,OAAO,KAAK,UAAU;IAC9B,IAAI,KAAK;KACP,QAAQ,KAAA,CAAS;KACjB;IACF;IACA,QAAQ;KAAE,MAAM,OAAO,MAAM,IAAI;KAAG,OAAO,MAAM,QAAQ;KAAM,aAAa,MAAM,YAAY;KAAG,QAAQ,MAAM,OAAO;IAAE,CAAC;GAC3H,CAAC;EACH,CAAC;CACH;CAEA,MAAM,MAAM,MAA6B;EACvC,MAAM,OAAO,MAAM,KAAK,KAAK;EAC7B,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,KAAK,MAAM,OAAO,QAAS,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAE;EAC3D,CAAC;CACH;CAEA,MAAM,OAAO,MAA6B;EACxC,MAAM,OAAO,MAAM,KAAK,KAAK;EAC7B,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,KAAK,OAAO,OAAO,QAAQ;IACzB,IAAI,KAAK,OAAO,GAAG;SACd;KACH,KAAK,QAAQ,UAAU,MAAM,IAAI;KACjC,QAAQ;IACV;GACF,CAAC;EACH,CAAC;CACH;CAEA,MAAM,OAAO,KAAa,MAA6B;EACrD,MAAM,OAAO,MAAM,KAAK,KAAK;EAC7B,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,KAAK,mBAAmB,KAAK,OAAO,QAAQ;IAC1C,IAAI,KAAK,OAAO,GAAG;SACd;KACH,KAAK,QAAQ,QAAQ,GAAG,IAAI,MAAM,QAAQ,IAAI;KAC9C,QAAQ;IACV;GACF,CAAC;EACH,CAAC;CACH;CAEA,MAAM,WAA0B;EAE9B,KAAI,MADiB,KAAK,KAAK;GAAC;GAAM;GAAM;EAA6C,GAAG,GAAG,EAAA,CACpF,OAAO,SAAS,qBAAqB,GAAG;GACjD,MAAM,UAAU,QAAQ,IAAI,iBAAiB,YAAY;GACzD,IAAI,CAAC,SAAS;GACd,MAAM,cAAc;GACpB,MAAM,KAAK,KAAK;IAAC;IAAS;IAAM;GAAW,GAAG,GAAG;GACjD,MAAM,WAAW,GAAG,YAAY;GAChC,MAAM,UAAU,aAAa,OAAO;GACpC,MAAM,KAAK,UAAU,UAAU,OAAO;GACtC,MAAM,KAAK,KAAK;IAAC;IAAS;IAAM;GAAQ,GAAG,GAAG;EAChD;CACF;CAEA,MAAM,IAAI,MAAgB,KAAa,KAA6B,MAAc,MAAc,eAAe,kBAAsI;EACnP,MAAM,SAAS,MAAM,KAAK,WAAW,UAAU;EAC/C,MAAM,KAAK,MAAc,IAAI,EAAE,QAAQ,MAAM,OAAO,EAAE;EACtD,MAAM,cAAc,OAAO,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW;GAC5D,IAAI,CAAC,2BAA2B,KAAK,GAAG,GAAG,MAAM,IAAI,MAAM,qCAAqC,KAAK;GACrG,OAAO,GAAG,IAAI,GAAG;EACnB,CAAC;EACD,MAAM,UAAU,oGAAoG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,aAAa,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;EACvK,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,OAAO,KACL,SACA,EAAE,KAAK;IAAE;IAAM;IAAM,MAAM;GAAa,EAAE,IACzC,KAAK,YAAY;IAChB,IAAI,KAAK;KACP,OAAO,GAAG;KACV;IACF;IACA,QAAQ;KACN;KACA,SAAS,GAAG,MAAM,QAAQ,UAAU,GAAG,GAAG,GAAG,CAAC;KAC9C,YAAY,QAAQ,MAAM;IAC5B,CAAC;GACH,CACF;EACF,CAAC;CACH;AACF;AAEA,SAAS,cAAkC;CACzC,MAAM,aAAa;EACjB,KAAK,QAAQ,GAAG,QAAQ,gBAAgB,QAAQ,IAAI;EACpD,KAAK,QAAQ,GAAG,QAAQ,gBAAgB,WAAW,WAAW,OAAO,IAAI;EACzE,KAAK,QAAQ,GAAG,MAAM,OAAO,IAAI;EACjC;EACA;CACF;CACA,KAAK,MAAM,KAAK,YAAY,IAAI,WAAW,CAAC,GAAG,OAAO;AAExD"}
|
|
1
|
+
{"version":3,"file":"executor.js","names":[],"sources":["../../src/exec-ssh/executor.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { encodeRunnerPayload, REMOTE_RUNNER_COMMAND, type RunnerPayload } from './runner.js'\nimport type { SshConnection } from './connection.js'\n\nexport interface ExecResult {\n code: number\n signal?: string\n stdout: string\n stderr: string\n}\n\nexport class SshExecutor {\n private sftpCache: Promise<import('ssh2').SFTPWrapper> | null = null\n\n constructor(\n private readonly connection: SshConnection,\n private readonly nodeId = 'unknown',\n private readonly audit?: (op: string, target: string, result: string) => void,\n ) {}\n\n async exec(argv: string[], cwd: string, env: Record<string, string> = {}, stdinData?: Buffer): Promise<ExecResult> {\n const client = await this.connection.getClient()\n const payload: RunnerPayload = { argv, cwd, env }\n const body = encodeRunnerPayload(payload)\n const input = stdinData ? Buffer.concat([body, stdinData]) : body\n return new Promise((resolve, reject) => {\n client.exec(REMOTE_RUNNER_COMMAND, (err, channel) => {\n if (err) {\n reject(err)\n return\n }\n const stdout: Buffer[] = []\n const stderr: Buffer[] = []\n channel.stdout.on('data', (chunk: Buffer) => stdout.push(chunk))\n channel.stderr.on('data', (chunk: Buffer) => stderr.push(chunk))\n channel.on('close', (code: number, signal: string) => {\n this.audit?.('exec', argv.join(' '), `code=${code ?? 0}`)\n resolve({\n code: code ?? 0,\n signal,\n stdout: Buffer.concat(stdout).toString('utf8'),\n stderr: Buffer.concat(stderr).toString('utf8'),\n })\n })\n channel.on('error', reject)\n channel.end(input)\n })\n })\n }\n\n async sftp(): Promise<import('ssh2').SFTPWrapper> {\n if (this.sftpCache) return this.sftpCache\n const client = await this.connection.getClient()\n this.sftpCache = new Promise((resolve, reject) => {\n client.sftp((err, sftp) => {\n if (err) reject(err)\n else resolve(sftp)\n })\n })\n return this.sftpCache\n }\n\n async readFile(path: string): Promise<Buffer> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.readFile(path, (err, data) => (err ? reject(err) : resolve(data)))\n })\n }\n\n async writeFile(path: string, content: Buffer | string): Promise<void> {\n const sftp = await this.sftp()\n const tmp = `${path}.dshb-tmp-${process.pid}-${Date.now()}`\n return new Promise((resolve, reject) => {\n sftp.writeFile(tmp, content, (writeErr) => {\n if (writeErr) {\n reject(writeErr)\n return\n }\n sftp.ext_openssh_rename(tmp, path, (renameErr) => {\n if (renameErr) reject(renameErr)\n else {\n this.audit?.('write', path, 'ok')\n resolve()\n }\n })\n })\n })\n }\n\n async listDir(path: string): Promise<Array<{ name: string; isDir: boolean; isFile: boolean; isSymlink: boolean; size: number; mtime: number }>> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.readdir(path, (err, list) => {\n if (err) {\n reject(err)\n return\n }\n resolve(\n list.map((e) => ({\n name: e.filename,\n isDir: e.attrs.isDirectory(),\n isFile: e.attrs.isFile(),\n isSymlink: e.attrs.isSymbolicLink(),\n size: Number(e.attrs.size),\n mtime: e.attrs.mtime * 1000,\n })),\n )\n })\n })\n }\n\n async stat(path: string): Promise<{ size: number; mtime: number; isDirectory: boolean; isFile: boolean } | undefined> {\n const sftp = await this.sftp()\n return new Promise((resolve) => {\n sftp.stat(path, (err, stats) => {\n if (err) {\n resolve(undefined)\n return\n }\n resolve({ size: Number(stats.size), mtime: stats.mtime * 1000, isDirectory: stats.isDirectory(), isFile: stats.isFile() })\n })\n })\n }\n\n async lstat(path: string): Promise<{ size: number; mtime: number; isDirectory: boolean; isFile: boolean; isSymlink: boolean } | undefined> {\n const sftp = await this.sftp()\n return new Promise((resolve) => {\n sftp.lstat(path, (err, stats) => {\n if (err) {\n resolve(undefined)\n return\n }\n resolve({\n size: Number(stats.size),\n mtime: stats.mtime * 1000,\n isDirectory: stats.isDirectory(),\n isFile: stats.isFile(),\n isSymlink: stats.isSymbolicLink(),\n })\n })\n })\n }\n\n async mkdir(path: string): Promise<void> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.mkdir(path, (err) => (err ? reject(err) : resolve()))\n })\n }\n\n async remove(path: string): Promise<void> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.unlink(path, (err) => {\n if (err) reject(err)\n else {\n this.audit?.('remove', path, 'ok')\n resolve()\n }\n })\n })\n }\n\n async rename(src: string, dest: string): Promise<void> {\n const sftp = await this.sftp()\n return new Promise((resolve, reject) => {\n sftp.ext_openssh_rename(src, dest, (err) => {\n if (err) reject(err)\n else {\n this.audit?.('move', `${src} -> ${dest}`, 'ok')\n resolve()\n }\n })\n })\n }\n\n async ensureRg(): Promise<void> {\n const result = await this.exec(['sh', '-c', 'command -v rg || echo \"__DShB_RG_MISSING__\"'], '/')\n if (result.stdout.includes('__DShB_RG_MISSING__')) {\n const localRg = process.env.DSHB_LOCAL_RG ?? findLocalRg()\n if (!localRg) return\n const remoteRgDir = '~/.dshb/bin'\n await this.exec(['mkdir', '-p', remoteRgDir], '/')\n const remoteRg = `${remoteRgDir}/rg`\n const content = readFileSync(localRg)\n await this.writeFile(remoteRg, content)\n await this.exec(['chmod', '+x', remoteRg], '/')\n }\n }\n\n async pty(argv: string[], cwd: string, env: Record<string, string>, cols: number, rows: number, terminalType = 'xterm-256color'): Promise<{ channel: import('ssh2').ClientChannel; resize: (cols: number, rows: number) => void; kill: () => void }> {\n const client = await this.connection.getClient()\n const q = (s: string) => `'${s.replace(/'/g, \"'\\\\''\")}'`\n const environment = Object.entries(env).map(([key, value]) => {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`invalid terminal environment key: ${key}`)\n return `${key}=${value}`\n })\n const command = `bash -c 'cd \"$0\" && exec env -i HOME=\"$HOME\" PATH=\"\\${PATH:-/usr/local/bin:/usr/bin:/bin}\" \"$@\"' ${q(cwd)} ${[...environment, ...argv].map(q).join(' ')}`\n return new Promise((resolve, reject) => {\n client.exec(\n command,\n { pty: { cols, rows, term: terminalType } },\n (err, channel) => {\n if (err) {\n reject(err)\n return\n }\n resolve({\n channel,\n resize: (c, r) => channel.setWindow(c, r, 0, 0),\n kill: () => channel.close(),\n })\n },\n )\n })\n }\n}\n\nfunction findLocalRg(): string | undefined {\n const candidates = [\n join(homedir(), '.dsh', 'node_modules', '.bin', 'rg'),\n join(homedir(), '.dsh', 'node_modules', '@vscode', 'ripgrep', 'bin', 'rg'),\n join(homedir(), 'go', 'bin', 'rg'),\n '/usr/local/bin/rg',\n '/usr/bin/rg',\n ]\n for (const c of candidates) if (existsSync(c)) return c\n return undefined\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SshExecutor } from "./executor.js";
|
|
2
|
+
import { FsInfo, FsPathInfo } from "@deepseek-ai/dsh-fs";
|
|
2
3
|
//#region src/exec-ssh/fs-provider.d.ts
|
|
3
4
|
declare class SshFileSystem {
|
|
4
5
|
private readonly executor;
|
|
@@ -7,20 +8,10 @@ declare class SshFileSystem {
|
|
|
7
8
|
processPath(target: string): string;
|
|
8
9
|
fileUrl(target: string): string;
|
|
9
10
|
contains(parent: string, child: string): boolean;
|
|
10
|
-
stat(target: string, _signal?: AbortSignal): Promise<
|
|
11
|
-
size: number;
|
|
12
|
-
mtime: number;
|
|
13
|
-
isDirectory: boolean;
|
|
14
|
-
isFile: boolean;
|
|
15
|
-
} | undefined>;
|
|
11
|
+
stat(target: string, _signal?: AbortSignal): Promise<FsInfo | undefined>;
|
|
16
12
|
lstat(path: string, _opts?: {
|
|
17
13
|
cwd?: string;
|
|
18
|
-
}, _signal?: AbortSignal): Promise<
|
|
19
|
-
size: number;
|
|
20
|
-
mtime: number;
|
|
21
|
-
isDirectory: boolean;
|
|
22
|
-
isFile: boolean;
|
|
23
|
-
} | undefined>;
|
|
14
|
+
}, _signal?: AbortSignal): Promise<FsPathInfo | undefined>;
|
|
24
15
|
readText(target: string, _signal?: AbortSignal): Promise<string>;
|
|
25
16
|
streamText(target: string, _signal?: AbortSignal): Promise<AsyncIterable<string>>;
|
|
26
17
|
readBytes(target: string, _signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array>;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import { FsVersion } from "@deepseek-ai/dsh-fs";
|
|
1
2
|
//#region src/exec-ssh/fs-provider.ts
|
|
3
|
+
function versionOf(info) {
|
|
4
|
+
const type = info.isDirectory ? "directory" : info.isFile ? "file" : "other";
|
|
5
|
+
return FsVersion(`${type}:${info.size}:${info.mtime}`);
|
|
6
|
+
}
|
|
2
7
|
var SshFileSystem = class {
|
|
3
8
|
executor;
|
|
4
9
|
constructor(executor) {
|
|
@@ -17,10 +22,22 @@ var SshFileSystem = class {
|
|
|
17
22
|
return child === parent || child.startsWith(`${parent}/`);
|
|
18
23
|
}
|
|
19
24
|
async stat(target, _signal) {
|
|
20
|
-
|
|
25
|
+
const info = await this.executor.stat(target);
|
|
26
|
+
if (!info) return void 0;
|
|
27
|
+
return {
|
|
28
|
+
version: versionOf(info),
|
|
29
|
+
type: info.isDirectory ? "directory" : info.isFile ? "file" : "other",
|
|
30
|
+
size: info.size
|
|
31
|
+
};
|
|
21
32
|
}
|
|
22
33
|
async lstat(path, _opts, _signal) {
|
|
23
|
-
|
|
34
|
+
const info = await this.executor.lstat(path);
|
|
35
|
+
if (!info) return void 0;
|
|
36
|
+
return {
|
|
37
|
+
version: versionOf(info),
|
|
38
|
+
type: info.isSymlink ? "symlink" : info.isDirectory ? "directory" : info.isFile ? "file" : "other",
|
|
39
|
+
size: info.size
|
|
40
|
+
};
|
|
24
41
|
}
|
|
25
42
|
async readText(target, _signal) {
|
|
26
43
|
return (await this.executor.readFile(target)).toString("utf8");
|
|
@@ -38,7 +55,7 @@ var SshFileSystem = class {
|
|
|
38
55
|
async listDir(target, _signal) {
|
|
39
56
|
return (await this.executor.listDir(target)).map((e) => ({
|
|
40
57
|
name: e.name,
|
|
41
|
-
path: `${target}/${e.name}`,
|
|
58
|
+
path: `${target.replace(/\/+$/, "")}/${e.name}`,
|
|
42
59
|
isDirectory: e.isDir,
|
|
43
60
|
isFile: e.isFile,
|
|
44
61
|
isSymlink: e.isSymlink,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-provider.js","names":[],"sources":["../../src/exec-ssh/fs-provider.ts"],"sourcesContent":["import type { SshExecutor } from './executor.js'\n\nexport class SshFileSystem {\n constructor(private readonly executor: SshExecutor) {}\n\n async resolve(path: string): Promise<string> {\n return path\n }\n\n processPath(target: string): string {\n return target\n }\n\n fileUrl(target: string): string {\n return `file://${target}`\n }\n\n contains(parent: string, child: string): boolean {\n return child === parent || child.startsWith(`${parent}/`)\n }\n\n async stat(target: string, _signal?: AbortSignal): Promise<
|
|
1
|
+
{"version":3,"file":"fs-provider.js","names":[],"sources":["../../src/exec-ssh/fs-provider.ts"],"sourcesContent":["import type { SshExecutor } from './executor.js'\nimport { FsVersion, type FsInfo, type FsPathInfo } from '@deepseek-ai/dsh-fs'\n\nfunction versionOf(info: { size: number; mtime: number; isDirectory: boolean; isFile: boolean }): FsInfo['version'] {\n const type = info.isDirectory ? 'directory' : info.isFile ? 'file' : 'other'\n return FsVersion(`${type}:${info.size}:${info.mtime}`)\n}\n\nexport class SshFileSystem {\n constructor(private readonly executor: SshExecutor) {}\n\n async resolve(path: string): Promise<string> {\n return path\n }\n\n processPath(target: string): string {\n return target\n }\n\n fileUrl(target: string): string {\n return `file://${target}`\n }\n\n contains(parent: string, child: string): boolean {\n return child === parent || child.startsWith(`${parent}/`)\n }\n\n async stat(target: string, _signal?: AbortSignal): Promise<FsInfo | undefined> {\n const info = await this.executor.stat(target)\n if (!info) return undefined\n return {\n version: versionOf(info),\n type: info.isDirectory ? 'directory' : info.isFile ? 'file' : 'other',\n size: info.size,\n }\n }\n\n async lstat(path: string, _opts?: { cwd?: string }, _signal?: AbortSignal): Promise<FsPathInfo | undefined> {\n const info = await this.executor.lstat(path)\n if (!info) return undefined\n return {\n version: versionOf(info),\n type: info.isSymlink ? 'symlink' : info.isDirectory ? 'directory' : info.isFile ? 'file' : 'other',\n size: info.size,\n }\n }\n\n async readText(target: string, _signal?: AbortSignal): Promise<string> {\n const data = await this.executor.readFile(target)\n return data.toString('utf8')\n }\n\n async streamText(target: string, _signal?: AbortSignal): Promise<AsyncIterable<string>> {\n const data = await this.executor.readFile(target)\n const text = data.toString('utf8')\n return (async function* () {\n yield text\n })()\n }\n\n async readBytes(target: string, _signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array> {\n const data = await this.executor.readFile(target)\n const slice = data.subarray(0, maxBytes)\n return new Uint8Array(slice.buffer, slice.byteOffset, slice.byteLength)\n }\n\n async listDir(target: string, _signal?: AbortSignal): Promise<Array<{ name: string; path: string; isDirectory: boolean; isFile: boolean; isSymlink: boolean; size: number; mtime: number }>> {\n const entries = await this.executor.listDir(target)\n return entries.map((e) => ({\n name: e.name,\n path: `${target.replace(/\\/+$/, '')}/${e.name}`,\n isDirectory: e.isDir,\n isFile: e.isFile,\n isSymlink: e.isSymlink,\n size: e.size,\n mtime: e.mtime,\n }))\n }\n\n async writeText(target: string, content: string, _expected?: unknown, _signal?: AbortSignal, _policy?: unknown): Promise<{ operation: 'create' | 'update'; version: string; before: string | null; after: string }> {\n const normalizeLf = (s: string) => s.replace(/\\r\\n/g, '\\n')\n const beforeInfo = await this.executor.stat(target)\n let before: string | null = null\n if (beforeInfo?.isFile) {\n try {\n before = normalizeLf((await this.executor.readFile(target)).toString('utf8'))\n } catch {\n before = null\n }\n }\n const after = normalizeLf(content)\n await this.executor.writeFile(target, content)\n const afterInfo = await this.executor.stat(target)\n const version = `${afterInfo?.size ?? content.length}:${afterInfo?.mtime ?? Date.now()}`\n return { operation: before === null ? 'create' : 'update', version, before, after }\n }\n\n async editText(target: string, edit: unknown, _expected?: unknown, _signal?: AbortSignal, _policy?: unknown): Promise<{ version: string; before: string; after: string }> {\n const normalizeLf = (s: string) => s.replace(/\\r\\n/g, '\\n')\n const before = normalizeLf((await this.executor.readFile(target)).toString('utf8'))\n const req = edit as { oldString: string; newString: string; replaceAll: boolean }\n const oldString = normalizeLf(String(req.oldString ?? ''))\n if (oldString.length === 0) throw new Error('edit oldString must be non-empty')\n const newString = normalizeLf(String(req.newString ?? ''))\n const matches = before.split(oldString).length - 1\n if (matches === 0) throw new Error('edit oldString not found in file')\n if (!req.replaceAll && matches !== 1) throw new Error(`edit oldString matched ${matches} times; expected exactly one`)\n const after = req.replaceAll ? before.split(oldString).join(newString) : before.replace(oldString, newString)\n await this.executor.writeFile(target, after)\n const afterInfo = await this.executor.stat(target)\n const version = `${afterInfo?.size ?? after.length}:${afterInfo?.mtime ?? Date.now()}`\n return { version, before, after }\n }\n}\n"],"mappings":"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"}
|
package/lib/exec-ssh/world.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as NodeTestReport, t as ExecutionWorldProvider } from "../types-
|
|
1
|
+
import { a as NodeTestReport, t as ExecutionWorldProvider } from "../types-DPP05ZsA.js";
|
|
2
2
|
import { SshConnectionPool } from "./connection-pool.js";
|
|
3
3
|
import { SshExecutor } from "./executor.js";
|
|
4
4
|
import { SshFileSystem } from "./fs-provider.js";
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { sharedWorldResolver } from "./resolve.js";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { FsTargetKey } from "@deepseek-ai/dsh-fs";
|
|
2
4
|
//#region src/router/decorate-fs.ts
|
|
3
5
|
function decorateFileSystem(fs) {
|
|
4
6
|
const resolver = sharedWorldResolver();
|
|
@@ -44,10 +46,22 @@ function decorateFileSystem(fs) {
|
|
|
44
46
|
return ref.provider.fs.readBytes(ref.remotePath, signal, maxBytes);
|
|
45
47
|
};
|
|
46
48
|
fs.listDir = async (target, signal) => {
|
|
47
|
-
const
|
|
49
|
+
const parentPath = targetPath(target);
|
|
50
|
+
const ref = resolver.resolve(parentPath);
|
|
48
51
|
if (ref.kind === "local") return origListDir(target, signal);
|
|
49
52
|
if (ref.kind === "unrouted") throw new Error(`node ${ref.nodeId} world not available`);
|
|
50
|
-
return ref.provider.fs.listDir(ref.remotePath, signal)
|
|
53
|
+
return (await ref.provider.fs.listDir(ref.remotePath, signal)).map((entry) => {
|
|
54
|
+
const childPath = join(parentPath, entry.name);
|
|
55
|
+
return {
|
|
56
|
+
name: entry.name,
|
|
57
|
+
type: entry.isDirectory ? "directory" : entry.isFile ? "file" : "other",
|
|
58
|
+
target: {
|
|
59
|
+
targetKey: FsTargetKey(childPath),
|
|
60
|
+
displayPath: childPath
|
|
61
|
+
},
|
|
62
|
+
...entry.size === void 0 ? {} : { size: entry.size }
|
|
63
|
+
};
|
|
64
|
+
});
|
|
51
65
|
};
|
|
52
66
|
fs.writeText = async (target, content, expected, signal, sandboxPolicy) => {
|
|
53
67
|
const ref = resolver.resolve(targetPath(target));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorate-fs.js","names":[],"sources":["../../src/router/decorate-fs.ts"],"sourcesContent":["import type { FileSystem } from '@deepseek-ai/dsh-fs'\nimport type { FsEditOutcome, FsEditRequest, FsTarget, FsVersion, FsWriteIntent, FsWriteOutcome, FsDirEntry, FsInfo, FsPathInfo } from '@deepseek-ai/dsh-fs'\nimport type { SandboxExecutionPolicy } from '@deepseek-ai/dsh-sandbox'\nimport { sharedWorldResolver } from './resolve.js'\n\nexport function decorateFileSystem(fs: FileSystem): () => void {\n const resolver = sharedWorldResolver()\n\n const origStat = fs.stat.bind(fs)\n const origLstat = fs.lstat.bind(fs)\n const origReadText = fs.readText.bind(fs)\n const origStreamText = fs.streamText.bind(fs)\n const origReadBytes = fs.readBytes.bind(fs)\n const origListDir = fs.listDir.bind(fs)\n const origWriteText = fs.writeText.bind(fs)\n const origEditText = fs.editText.bind(fs)\n\n function targetPath(target: FsTarget): string {\n return fs.processPath(target)\n }\n\n fs.stat = async (target: FsTarget, signal?: AbortSignal): Promise<FsInfo | undefined> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origStat(target, signal)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.stat(ref.remotePath, signal) as Promise<FsInfo | undefined>\n }\n\n fs.lstat = async (path: string, opts?: { cwd?: string }, signal?: AbortSignal): Promise<FsPathInfo | undefined> => {\n const ref = resolver.resolve(path)\n if (ref.kind === 'local') return origLstat(path, opts, signal)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.lstat(ref.remotePath, opts, signal) as Promise<FsPathInfo | undefined>\n }\n\n fs.readText = async (target: FsTarget, signal?: AbortSignal): Promise<string> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origReadText(target, signal)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.readText(ref.remotePath, signal)\n }\n\n fs.streamText = async (target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origStreamText(target, signal)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.streamText(ref.remotePath, signal)\n }\n\n fs.readBytes = async (target: FsTarget, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origReadBytes(target, signal, maxBytes)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.readBytes(ref.remotePath, signal, maxBytes)\n }\n\n fs.listDir = async (target: FsTarget, signal?: AbortSignal): Promise<FsDirEntry[]> => {\n const ref = resolver.resolve(
|
|
1
|
+
{"version":3,"file":"decorate-fs.js","names":[],"sources":["../../src/router/decorate-fs.ts"],"sourcesContent":["import { join } from 'node:path'\nimport { FsTargetKey } from '@deepseek-ai/dsh-fs'\nimport type { FileSystem } from '@deepseek-ai/dsh-fs'\nimport type { FsEditOutcome, FsEditRequest, FsTarget, FsVersion, FsWriteIntent, FsWriteOutcome, FsDirEntry, FsInfo, FsPathInfo } from '@deepseek-ai/dsh-fs'\nimport type { SandboxExecutionPolicy } from '@deepseek-ai/dsh-sandbox'\nimport { sharedWorldResolver } from './resolve.js'\n\nexport function decorateFileSystem(fs: FileSystem): () => void {\n const resolver = sharedWorldResolver()\n\n const origStat = fs.stat.bind(fs)\n const origLstat = fs.lstat.bind(fs)\n const origReadText = fs.readText.bind(fs)\n const origStreamText = fs.streamText.bind(fs)\n const origReadBytes = fs.readBytes.bind(fs)\n const origListDir = fs.listDir.bind(fs)\n const origWriteText = fs.writeText.bind(fs)\n const origEditText = fs.editText.bind(fs)\n\n function targetPath(target: FsTarget): string {\n return fs.processPath(target)\n }\n\n fs.stat = async (target: FsTarget, signal?: AbortSignal): Promise<FsInfo | undefined> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origStat(target, signal)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.stat(ref.remotePath, signal) as Promise<FsInfo | undefined>\n }\n\n fs.lstat = async (path: string, opts?: { cwd?: string }, signal?: AbortSignal): Promise<FsPathInfo | undefined> => {\n const ref = resolver.resolve(path)\n if (ref.kind === 'local') return origLstat(path, opts, signal)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.lstat(ref.remotePath, opts, signal) as Promise<FsPathInfo | undefined>\n }\n\n fs.readText = async (target: FsTarget, signal?: AbortSignal): Promise<string> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origReadText(target, signal)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.readText(ref.remotePath, signal)\n }\n\n fs.streamText = async (target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origStreamText(target, signal)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.streamText(ref.remotePath, signal)\n }\n\n fs.readBytes = async (target: FsTarget, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origReadBytes(target, signal, maxBytes)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.readBytes(ref.remotePath, signal, maxBytes)\n }\n\n fs.listDir = async (target: FsTarget, signal?: AbortSignal): Promise<FsDirEntry[]> => {\n const parentPath = targetPath(target)\n const ref = resolver.resolve(parentPath)\n if (ref.kind === 'local') return origListDir(target, signal)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n const entries = await ref.provider.fs.listDir(ref.remotePath, signal) as Array<{\n name: string\n isDirectory?: boolean\n isFile?: boolean\n isSymlink?: boolean\n size?: number\n }>\n return entries.map((entry) => {\n const childPath = join(parentPath, entry.name)\n return {\n name: entry.name,\n type: entry.isDirectory ? 'directory' : entry.isFile ? 'file' : 'other',\n target: { targetKey: FsTargetKey(childPath), displayPath: childPath },\n ...(entry.size === undefined ? {} : { size: entry.size }),\n }\n })\n }\n\n fs.writeText = async (target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy): Promise<FsWriteOutcome> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origWriteText(target, content, expected, signal, sandboxPolicy)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.writeText(ref.remotePath, content, expected, signal, sandboxPolicy) as Promise<FsWriteOutcome>\n }\n\n fs.editText = async (target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy): Promise<FsEditOutcome> => {\n const ref = resolver.resolve(targetPath(target))\n if (ref.kind === 'local') return origEditText(target, edit, expected, signal, sandboxPolicy)\n if (ref.kind === 'unrouted') throw new Error(`node ${ref.nodeId} world not available`)\n return ref.provider.fs.editText(ref.remotePath, edit, expected, signal, sandboxPolicy) as Promise<FsEditOutcome>\n }\n\n return () => {\n fs.stat = origStat\n fs.lstat = origLstat\n fs.readText = origReadText\n fs.streamText = origStreamText\n fs.readBytes = origReadBytes\n fs.listDir = origListDir\n fs.writeText = origWriteText\n fs.editText = origEditText\n }\n}\n"],"mappings":"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"}
|
package/lib/router/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as WorkspaceBindings, a as NodeTestReport, t as ExecutionWorldProvider, v as WorldRef, y as WorldRegistry } from "../types-
|
|
1
|
+
import { _ as WorkspaceBindings, a as NodeTestReport, t as ExecutionWorldProvider, v as WorldRef, y as WorldRegistry } from "../types-DPP05ZsA.js";
|
|
2
2
|
import { sharedWorldResolver } from "./resolve.js";
|
|
3
3
|
import { Context } from "@deepseek-ai/cordis";
|
|
4
4
|
//#region src/router/index.d.ts
|
package/lib/router/resolve.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as WorkspaceBindings, v as WorldRef, y as WorldRegistry } from "../types-
|
|
1
|
+
import { _ as WorkspaceBindings, v as WorldRef, y as WorldRegistry } from "../types-DPP05ZsA.js";
|
|
2
2
|
//#region src/router/resolve.d.ts
|
|
3
3
|
interface BindingHit {
|
|
4
4
|
nodeId: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
-
import SandboxedFileSystem from "@deepseek-ai/dsh-fs-sandbox";
|
|
3
2
|
import { FsDirEntry, FsEditOutcome, FsEditRequest, FsInfo, FsPathInfo, FsTarget, FsVersion, FsWriteIntent, FsWriteOutcome } from "@deepseek-ai/dsh-fs";
|
|
3
|
+
import SandboxedFileSystem from "@deepseek-ai/dsh-fs-sandbox";
|
|
4
4
|
import { SandboxExecutionPolicy } from "@deepseek-ai/dsh-sandbox";
|
|
5
5
|
//#region src/router/router-fs.d.ts
|
|
6
6
|
declare class RouterFileSystem extends SandboxedFileSystem {
|
package/lib/router/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as WorkspaceBindings, a as NodeTestReport, c as ShellExecSpec, d as SubprocessDelegate, f as SubprocessHandle, g as SubprocessTerminalSpawnSpec, h as SubprocessTerminalHandle, i as FsTargetLike, l as ShellProcess, m as SubprocessSpawnSpec, n as FileSystem, o as ShellDelegate, p as SubprocessRuntime, r as FsDelegate, s as ShellExecRequest, t as ExecutionWorldProvider, u as ShellRunResult, v as WorldRef, y as WorldRegistry } from "../types-
|
|
1
|
+
import { _ as WorkspaceBindings, a as NodeTestReport, c as ShellExecSpec, d as SubprocessDelegate, f as SubprocessHandle, g as SubprocessTerminalSpawnSpec, h as SubprocessTerminalHandle, i as FsTargetLike, l as ShellProcess, m as SubprocessSpawnSpec, n as FileSystem, o as ShellDelegate, p as SubprocessRuntime, r as FsDelegate, s as ShellExecRequest, t as ExecutionWorldProvider, u as ShellRunResult, v as WorldRef, y as WorldRegistry } from "../types-DPP05ZsA.js";
|
|
2
2
|
export { ExecutionWorldProvider, type FileSystem, FsDelegate, FsTargetLike, NodeTestReport, ShellDelegate, type ShellExecRequest, type ShellExecSpec, type ShellProcess, type ShellRunResult, SubprocessDelegate, type SubprocessHandle, type SubprocessRuntime, type SubprocessSpawnSpec, type SubprocessTerminalHandle, type SubprocessTerminalSpawnSpec, WorkspaceBindings, WorldRef, WorldRegistry };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SubprocessHandle as SubprocessHandle$1, SubprocessRuntime as SubprocessRuntime$1, SubprocessSpawnSpec as SubprocessSpawnSpec$1, SubprocessTerminalEnvironment, SubprocessTerminalHandle as SubprocessTerminalHandle$1, SubprocessTerminalSpawnSpec as SubprocessTerminalSpawnSpec$1 } from "@deepseek-ai/dsh-subprocess";
|
|
2
1
|
import { FileSystem as FileSystem$1 } from "@deepseek-ai/dsh-fs";
|
|
2
|
+
import { SubprocessHandle as SubprocessHandle$1, SubprocessRuntime as SubprocessRuntime$1, SubprocessSpawnSpec as SubprocessSpawnSpec$1, SubprocessTerminalEnvironment, SubprocessTerminalHandle as SubprocessTerminalHandle$1, SubprocessTerminalSpawnSpec as SubprocessTerminalSpawnSpec$1 } from "@deepseek-ai/dsh-subprocess";
|
|
3
3
|
import { ShellExecRequest as ShellExecRequest$1, ShellExecSpec as ShellExecSpec$1, ShellProcess as ShellProcess$1, ShellRunResult as ShellRunResult$1 } from "@deepseek-ai/dsh-shell";
|
|
4
4
|
//#region src/router/types.d.ts
|
|
5
5
|
interface NodeTestReport {
|
|
@@ -66,4 +66,4 @@ type WorldRef = {
|
|
|
66
66
|
};
|
|
67
67
|
//#endregion
|
|
68
68
|
export { WorkspaceBindings as _, NodeTestReport as a, ShellExecSpec$1 as c, SubprocessDelegate as d, SubprocessHandle$1 as f, SubprocessTerminalSpawnSpec$1 as g, SubprocessTerminalHandle$1 as h, FsTargetLike as i, ShellProcess$1 as l, SubprocessSpawnSpec$1 as m, FileSystem$1 as n, ShellDelegate as o, SubprocessRuntime$1 as p, FsDelegate as r, ShellExecRequest$1 as s, ExecutionWorldProvider as t, ShellRunResult$1 as u, WorldRef as v, WorldRegistry as y };
|
|
69
|
-
//# sourceMappingURL=types-
|
|
69
|
+
//# sourceMappingURL=types-DPP05ZsA.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artenx/dshb",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Routes DSH filesystem, shell, subprocess, and PTY operations to local, SSH, and Docker execution nodes, with a node registry, an authentication gate, a mobile-aware management UI, and per-workspace custom project instructions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|