diff --git a/packages/cli/package.json b/packages/cli/package.json index be1e999f9..c6092d7d8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@openrouter/spawn", - "version": "0.27.6", + "version": "0.27.7", "type": "module", "bin": { "spawn": "cli.js" diff --git a/packages/cli/src/aws/aws.ts b/packages/cli/src/aws/aws.ts index 2d96ec1dd..accea4a66 100644 --- a/packages/cli/src/aws/aws.ts +++ b/packages/cli/src/aws/aws.ts @@ -1178,15 +1178,15 @@ export async function uploadFile(localPath: string, remotePath: string): Promise } export async function downloadFile(remotePath: string, localPath: string): Promise { - const normalizedRemote = validateRemotePath(remotePath, /^[a-zA-Z0-9/_.~$-]+$/); + const expandedRemote = remotePath.replace(/^\$HOME\//, "~/"); + const normalizedRemote = validateRemotePath(expandedRemote, /^[a-zA-Z0-9/_.~-]+$/); const keyOpts = getSshKeyOpts(await ensureSshKeys()); - const expandedPath = normalizedRemote.replace(/^\$HOME/, "~"); const proc = Bun.spawn( [ "scp", ...SSH_BASE_OPTS, ...keyOpts, - `${SSH_USER}@${_state.instanceIp}:${expandedPath}`, + `${SSH_USER}@${_state.instanceIp}:${normalizedRemote}`, localPath, ], { diff --git a/packages/cli/src/digitalocean/digitalocean.ts b/packages/cli/src/digitalocean/digitalocean.ts index 638114b99..ddd97d7d8 100644 --- a/packages/cli/src/digitalocean/digitalocean.ts +++ b/packages/cli/src/digitalocean/digitalocean.ts @@ -1448,17 +1448,17 @@ export async function uploadFile(localPath: string, remotePath: string, ip?: str export async function downloadFile(remotePath: string, localPath: string, ip?: string): Promise { const serverIp = ip || _state.serverIp; - const normalizedRemote = validateRemotePath(remotePath, /^[a-zA-Z0-9/_.~$-]+$/); + const expandedRemote = remotePath.replace(/^\$HOME\//, "~/"); + const normalizedRemote = validateRemotePath(expandedRemote, /^[a-zA-Z0-9/_.~-]+$/); const keyOpts = getSshKeyOpts(await ensureSshKeys()); - const expandedPath = normalizedRemote.replace(/^\$HOME/, "~"); const proc = Bun.spawn( [ "scp", ...SSH_BASE_OPTS, ...keyOpts, - `root@${serverIp}:${expandedPath}`, + `root@${serverIp}:${normalizedRemote}`, localPath, ], { diff --git a/packages/cli/src/gcp/gcp.ts b/packages/cli/src/gcp/gcp.ts index 4feef7e60..6d563177b 100644 --- a/packages/cli/src/gcp/gcp.ts +++ b/packages/cli/src/gcp/gcp.ts @@ -1028,10 +1028,9 @@ export async function uploadFile(localPath: string, remotePath: string): Promise logError(`Invalid local path: ${localPath}`); throw new Error("Invalid local path"); } - const normalizedRemote = validateRemotePath(remotePath, /^[a-zA-Z0-9/_.~$-]+$/); + const expandedRemote = remotePath.replace(/^\$HOME\//, "~/"); + const normalizedRemote = validateRemotePath(expandedRemote, /^[a-zA-Z0-9/_.~-]+$/); const username = resolveUsername(); - // Expand $HOME on remote side - const expandedPath = normalizedRemote.replace(/^\$HOME/, "~"); const keyOpts = getSshKeyOpts(await ensureSshKeys()); const proc = Bun.spawn( @@ -1040,7 +1039,7 @@ export async function uploadFile(localPath: string, remotePath: string): Promise ...SSH_BASE_OPTS, ...keyOpts, localPath, - `${username}@${_state.serverIp}:${expandedPath}`, + `${username}@${_state.serverIp}:${normalizedRemote}`, ], { stdio: [ @@ -1067,9 +1066,9 @@ export async function downloadFile(remotePath: string, localPath: string): Promi logError(`Invalid local path: ${localPath}`); throw new Error("Invalid local path"); } - const normalizedRemote = validateRemotePath(remotePath, /^[a-zA-Z0-9/_.~$-]+$/); + const expandedRemote = remotePath.replace(/^\$HOME\//, "~/"); + const normalizedRemote = validateRemotePath(expandedRemote, /^[a-zA-Z0-9/_.~-]+$/); const username = resolveUsername(); - const expandedPath = normalizedRemote.replace(/^\$HOME/, "~"); const keyOpts = getSshKeyOpts(await ensureSshKeys()); const proc = Bun.spawn( @@ -1077,7 +1076,7 @@ export async function downloadFile(remotePath: string, localPath: string): Promi "scp", ...SSH_BASE_OPTS, ...keyOpts, - `${username}@${_state.serverIp}:${expandedPath}`, + `${username}@${_state.serverIp}:${normalizedRemote}`, localPath, ], { diff --git a/packages/cli/src/hetzner/hetzner.ts b/packages/cli/src/hetzner/hetzner.ts index f76c43aed..c38c497ae 100644 --- a/packages/cli/src/hetzner/hetzner.ts +++ b/packages/cli/src/hetzner/hetzner.ts @@ -909,17 +909,17 @@ export async function uploadFile(localPath: string, remotePath: string, ip?: str export async function downloadFile(remotePath: string, localPath: string, ip?: string): Promise { const serverIp = ip || _state.serverIp; - const normalizedRemote = validateRemotePath(remotePath, /^[a-zA-Z0-9/_.~$-]+$/); + const expandedRemote = remotePath.replace(/^\$HOME\//, "~/"); + const normalizedRemote = validateRemotePath(expandedRemote, /^[a-zA-Z0-9/_.~-]+$/); const keyOpts = getSshKeyOpts(await ensureSshKeys()); - const expandedPath = normalizedRemote.replace(/^\$HOME/, "~"); const proc = Bun.spawn( [ "scp", ...SSH_BASE_OPTS, ...keyOpts, - `root@${serverIp}:${expandedPath}`, + `root@${serverIp}:${normalizedRemote}`, localPath, ], { diff --git a/packages/cli/src/sprite/sprite.ts b/packages/cli/src/sprite/sprite.ts index 047079622..f7284d18f 100644 --- a/packages/cli/src/sprite/sprite.ts +++ b/packages/cli/src/sprite/sprite.ts @@ -657,10 +657,10 @@ export async function uploadFileSprite(localPath: string, remotePath: string): P /** Download a file from the remote sprite by catting it to stdout. */ export async function downloadFileSprite(remotePath: string, localPath: string): Promise { - const normalizedRemote = validateRemotePath(remotePath, /^[a-zA-Z0-9/_.~$-]+$/); + const expandedRemote = remotePath.replace(/^\$HOME\//, "~/"); + const normalizedRemote = validateRemotePath(expandedRemote, /^[a-zA-Z0-9/_.~-]+$/); const spriteCmd = getSpriteCmd()!; - const expandedPath = normalizedRemote.replace(/^\$HOME/, "~"); await spriteRetry("sprite download", async () => { const proc = Bun.spawn( @@ -672,7 +672,7 @@ export async function downloadFileSprite(remotePath: string, localPath: string): _state.name, "--", "cat", - expandedPath, + normalizedRemote, ], { stdio: [