From d8131c3df612d762433ba5333207e677b7a7bb71 Mon Sep 17 00:00:00 2001 From: A <258483684+la14-1@users.noreply.github.com> Date: Fri, 27 Feb 2026 00:20:31 -0800 Subject: [PATCH] fix(hetzner): update deprecated server types to cx23/cpx22 gen (#1983) * fix(hetzner): update deprecated cx22/cpx21 server types to cx23/cpx22 Hetzner deprecated the entire cx*2 and cpx*1 server lines on Jan 1, 2026. New orders fail with "server type is deprecated". Updates to the current gen3 CX and gen2 CPX lines (cx23, cx33, cx43, cx53, cpx22, cpx32). Also shows the server type picker by default instead of requiring --custom, so users can choose their instance size on every deploy. Co-Authored-By: Claude Opus 4.6 * fix(zeroclaw): append autonomy config instead of overwriting onboard output zeroclaw onboard generates a complete config with required fields like default_temperature. Our setup was overwriting that with a partial config missing required fields, causing a crash loop on startup. Now appends the security/shell settings instead so onboard's fields are preserved. Co-Authored-By: Claude Opus 4.6 * style: fix biome formatting in agent-setup.ts Co-Authored-By: Claude Sonnet 4.5 Agent: pr-maintainer --------- Co-authored-by: spawn-bot Co-authored-by: Claude Opus 4.6 Co-authored-by: B <6723574+louisgv@users.noreply.github.com> --- packages/cli/package.json | 2 +- .../cli/src/__tests__/custom-flag.test.ts | 3 +- packages/cli/src/hetzner/hetzner.ts | 30 ++++++++----------- packages/cli/src/shared/agent-setup.ts | 10 +++++-- sh/test/fixtures/hetzner/_env.sh | 2 +- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 0488f32c..f49d0e77 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@openrouter/spawn", - "version": "0.11.1", + "version": "0.11.2", "type": "module", "bin": { "spawn": "cli.js" diff --git a/packages/cli/src/__tests__/custom-flag.test.ts b/packages/cli/src/__tests__/custom-flag.test.ts index 237f335f..b0df88af 100644 --- a/packages/cli/src/__tests__/custom-flag.test.ts +++ b/packages/cli/src/__tests__/custom-flag.test.ts @@ -146,9 +146,10 @@ describe("Hetzner --custom prompts", () => { restoreEnv("HETZNER_LOCATION", savedLocation); }); - it("promptServerType should return default without --custom", async () => { + it("promptServerType should return default in non-interactive mode", async () => { delete process.env.HETZNER_SERVER_TYPE; delete process.env.SPAWN_CUSTOM; + process.env.SPAWN_NON_INTERACTIVE = "1"; const { promptServerType, DEFAULT_SERVER_TYPE } = await import("../hetzner/hetzner"); const result = await promptServerType(); expect(result).toBe(DEFAULT_SERVER_TYPE); diff --git a/packages/cli/src/hetzner/hetzner.ts b/packages/cli/src/hetzner/hetzner.ts index 98393c4f..c086a0ab 100644 --- a/packages/cli/src/hetzner/hetzner.ts +++ b/packages/cli/src/hetzner/hetzner.ts @@ -276,32 +276,32 @@ export interface ServerTypeTier { export const SERVER_TYPES: ServerTypeTier[] = [ { - id: "cx22", - label: "2 vCPU \u00b7 4 GB RAM \u00b7 40 GB (~\u20AC3.29/mo)", + id: "cx23", + label: "cx23 \u00b7 2 vCPU \u00b7 4 GB \u00b7 40 GB (~\u20AC3.49/mo, EU only)", }, { - id: "cx32", - label: "4 vCPU \u00b7 8 GB RAM \u00b7 80 GB (~\u20AC5.39/mo)", + id: "cx33", + label: "cx33 \u00b7 4 vCPU \u00b7 8 GB \u00b7 80 GB (~\u20AC6.49/mo, EU only)", }, { - id: "cx42", - label: "8 vCPU \u00b7 16 GB RAM \u00b7 160 GB (~\u20AC14.49/mo)", + id: "cx43", + label: "cx43 \u00b7 8 vCPU \u00b7 16 GB \u00b7 160 GB (~\u20AC14.49/mo, EU only)", }, { - id: "cx52", - label: "16 vCPU \u00b7 32 GB RAM \u00b7 320 GB (~\u20AC28.49/mo)", + id: "cx53", + label: "cx53 \u00b7 16 vCPU \u00b7 32 GB \u00b7 320 GB (~\u20AC28.49/mo, EU only)", }, { - id: "cpx21", - label: "3 AMD vCPU \u00b7 4 GB RAM \u00b7 80 GB (~\u20AC4.35/mo)", + id: "cpx22", + label: "cpx22 \u00b7 3 AMD vCPU \u00b7 4 GB \u00b7 80 GB (~\u20AC5.49/mo)", }, { - id: "cpx31", - label: "4 AMD vCPU \u00b7 8 GB RAM \u00b7 160 GB (~\u20AC7.59/mo)", + id: "cpx32", + label: "cpx32 \u00b7 4 AMD vCPU \u00b7 8 GB \u00b7 160 GB (~\u20AC9.49/mo)", }, ]; -export const DEFAULT_SERVER_TYPE = "cx22"; +export const DEFAULT_SERVER_TYPE = "cx23"; // ─── Location Options ──────────────────────────────────────────────────────── @@ -343,10 +343,6 @@ export async function promptServerType(): Promise { return process.env.HETZNER_SERVER_TYPE; } - if (process.env.SPAWN_CUSTOM !== "1") { - return DEFAULT_SERVER_TYPE; - } - if (process.env.SPAWN_NON_INTERACTIVE === "1") { return DEFAULT_SERVER_TYPE; } diff --git a/packages/cli/src/shared/agent-setup.ts b/packages/cli/src/shared/agent-setup.ts index 42fcc198..c066a905 100644 --- a/packages/cli/src/shared/agent-setup.ts +++ b/packages/cli/src/shared/agent-setup.ts @@ -381,8 +381,11 @@ export async function setupZeroclawConfig(runner: CloudRunner, _apiKey: string): `source ~/.spawnrc 2>/dev/null; export PATH="$HOME/.cargo/bin:$PATH"; zeroclaw onboard --api-key "\${OPENROUTER_API_KEY}" --provider openrouter`, ); - // Write autonomy config — equivalent to Claude Code's dangerouslySkipPermissions - const config = `[security] + // Patch autonomy settings into the config generated by `zeroclaw onboard`. + // We append rather than overwrite so we keep the fields onboard wrote + // (api_key, default_provider, default_model, default_temperature, etc.). + const patch = ` +[security] autonomy = "full" supervised = false allow_destructive = true @@ -390,7 +393,8 @@ allow_destructive = true [shell] policy = "allow_all" `; - await uploadConfigFile(runner, config, "$HOME/.zeroclaw/config.toml"); + const patchB64 = Buffer.from(patch).toString("base64"); + await runner.runServer(`printf '%s' '${patchB64}' | base64 -d >> ~/.zeroclaw/config.toml`); logInfo("ZeroClaw configured for autonomous operation"); } diff --git a/sh/test/fixtures/hetzner/_env.sh b/sh/test/fixtures/hetzner/_env.sh index 66fa9083..6a25f0c0 100644 --- a/sh/test/fixtures/hetzner/_env.sh +++ b/sh/test/fixtures/hetzner/_env.sh @@ -1,4 +1,4 @@ export HCLOUD_TOKEN="test-token-hetzner" export HETZNER_SERVER_NAME="test-srv" -export HETZNER_SERVER_TYPE="cx22" +export HETZNER_SERVER_TYPE="cx23" export HETZNER_LOCATION="fsn1"