mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-04-28 11:59:29 +00:00
feat: add Windows PowerShell support — remove bash dependency for local execution (#2727)
Replace hardcoded "bash" shell references with platform-aware utilities so spawn works natively from PowerShell on Windows without WSL or Git Bash. - New shared/shell.ts: isWindows(), getLocalShell(), getInstallScriptUrl(), getInstallCmd(), getWhichCommand() with platform override for testability - local/local.ts: use getLocalShell() for runLocal() and interactiveSession() - commands/run.ts: spawnScript/runScriptHeadless use getLocalShell() - commands/update.ts: Windows downloads install.ps1, runs via PowerShell - update-check.ts: Windows auto-update uses install.ps1; "where" replaces "which" - shared/orchestrate.ts: PowerShell-compatible .spawnrc setup for local Windows - Remote SSH commands unchanged — remote servers are always Linux Closes #2726 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: L <6723574+louisgv@users.noreply.github.com>
This commit is contained in:
parent
ba94f681b3
commit
66b16d8651
8 changed files with 306 additions and 54 deletions
|
|
@ -16,6 +16,7 @@ import { generateEnvConfig } from "./agents";
|
|||
import { getOrPromptApiKey } from "./oauth";
|
||||
import { getSpawnPreferencesPath } from "./paths";
|
||||
import { asyncTryCatch, asyncTryCatchIf, isFileError, isOperationalError, tryCatchIf } from "./result.js";
|
||||
import { isWindows } from "./shell";
|
||||
import { startSshTunnel } from "./ssh";
|
||||
import { ensureSshKeys, getSshKeyOpts } from "./ssh-keys";
|
||||
import {
|
||||
|
|
@ -199,21 +200,19 @@ export async function runOrchestration(
|
|||
// 9. Inject environment variables via .spawnrc
|
||||
logStep("Setting up environment variables...");
|
||||
const envB64 = Buffer.from(envContent).toString("base64");
|
||||
|
||||
// On Windows local execution, use PowerShell-compatible env setup.
|
||||
// Remote servers (SSH) are always Linux, so bash commands are correct for all non-local clouds.
|
||||
const isLocalWindows = cloud.cloudName === "local" && isWindows();
|
||||
const envSetupCmd = isLocalWindows
|
||||
? `$bytes = [Convert]::FromBase64String('${envB64}'); ` + `[IO.File]::WriteAllBytes("$HOME/.spawnrc", $bytes)`
|
||||
: `printf '%s' '${envB64}' | base64 -d > ~/.spawnrc && chmod 600 ~/.spawnrc; ` +
|
||||
"for _rc in ~/.bashrc ~/.profile ~/.bash_profile ~/.zshrc; do " +
|
||||
`grep -q 'source ~/.spawnrc' "$_rc" 2>/dev/null || echo '[ -f ~/.spawnrc ] && source ~/.spawnrc' >> "$_rc"; ` +
|
||||
"done";
|
||||
|
||||
const envResult = await asyncTryCatch(() =>
|
||||
withRetry(
|
||||
"env setup",
|
||||
() =>
|
||||
wrapSshCall(
|
||||
cloud.runner.runServer(
|
||||
`printf '%s' '${envB64}' | base64 -d > ~/.spawnrc && chmod 600 ~/.spawnrc; ` +
|
||||
"for _rc in ~/.bashrc ~/.profile ~/.bash_profile ~/.zshrc; do " +
|
||||
`grep -q 'source ~/.spawnrc' "$_rc" 2>/dev/null || echo '[ -f ~/.spawnrc ] && source ~/.spawnrc' >> "$_rc"; ` +
|
||||
"done",
|
||||
),
|
||||
),
|
||||
2,
|
||||
5,
|
||||
),
|
||||
withRetry("env setup", () => wrapSshCall(cloud.runner.runServer(envSetupCmd)), 2, 5),
|
||||
);
|
||||
if (!envResult.ok) {
|
||||
logWarn("Environment setup had errors");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue