diff --git a/README.md b/README.md index 9991a3bbe..9dbf2d307 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ npm install -g altimate-code Or via curl (installs the `altimate` binary to `~/.altimate/bin`): ```bash -curl -fsSL https://altimate.ai/install | bash +curl -fsSL https://www.altimate.sh/install | bash ``` The curl install drops a single self-contained binary named `altimate`. The npm install exposes both `altimate` and `altimate-code` on PATH; the curl install only exposes `altimate`. Alpine Linux (musl) and Windows on ARM64 are not currently supported by the standalone binary — use `apk add gcompat` on Alpine, or use WSL on Windows-on-ARM. diff --git a/docs/docs/reference/troubleshooting.md b/docs/docs/reference/troubleshooting.md index 55ae8449a..a8ff5761c 100644 --- a/docs/docs/reference/troubleshooting.md +++ b/docs/docs/reference/troubleshooting.md @@ -4,7 +4,7 @@ ### Standalone binary not found after curl install -**Symptoms:** `altimate-code: command not found` after running `curl -fsSL https://altimate.ai/install | bash`. +**Symptoms:** `altimate-code: command not found` after running `curl -fsSL https://www.altimate.sh/install | bash`. As of v0.7.1 the curl-installed binary is named `altimate`, not `altimate-code`. The npm package continues to ship both names. If you scripted against the curl install: @@ -25,7 +25,7 @@ Or stay on the `altimate-code` name by installing via npm: `npm install -g altim The v0.7.0 curl install shipped without the NAPI native module. Fixed in v0.7.1 — the native module is now embedded directly into the binary. Re-install with: ```bash -curl -fsSL https://altimate.ai/install | bash +curl -fsSL https://www.altimate.sh/install | bash ``` ### Alpine Linux (musl) not supported @@ -39,7 +39,7 @@ curl -fsSL https://altimate.ai/install | bash apk add gcompat # Then either: -curl -fsSL https://altimate.ai/install | bash # standalone binary +curl -fsSL https://www.altimate.sh/install | bash # standalone binary # or: apk add gcompat && npm install -g altimate-code # npm install ``` diff --git a/install b/install index 80487e41a..2cf359ba0 100755 --- a/install +++ b/install @@ -20,8 +20,8 @@ Options: --no-modify-path Don't modify shell config files (.zshrc, .bashrc, etc.) Examples: - curl -fsSL https://altimate.ai/install | bash - curl -fsSL https://altimate.ai/install | bash -s -- --version 1.0.180 + curl -fsSL https://www.altimate.sh/install | bash + curl -fsSL https://www.altimate.sh/install | bash -s -- --version 1.0.180 ./install --binary /path/to/altimate EOF } diff --git a/packages/opencode/src/installation/index.ts b/packages/opencode/src/installation/index.ts index d8adad1b1..8994d8721 100644 --- a/packages/opencode/src/installation/index.ts +++ b/packages/opencode/src/installation/index.ts @@ -34,10 +34,18 @@ export namespace Installation { } async function upgradeCurl(target: string) { - const body = await fetch("https://altimate.ai/install").then((res) => { + // altimate_change start — curl-upgrade endpoint URL + bounded fetch timeout + // Upstream uses opencode.ai/install. We fetch the altimate install script + // from www.altimate.sh/install (the apex altimate.sh isn't routed to the + // Amplify Next.js app — tracked separately; revisit when apex DNS is fixed). + // 15s timeout so a stalled CDN/origin can't hang `altimate upgrade` forever. + const body = await fetch("https://www.altimate.sh/install", { + signal: AbortSignal.timeout(15_000), + }).then((res) => { if (!res.ok) throw new Error(res.statusText) return res.text() }) + // altimate_change end const proc = Process.spawn(["bash"], { stdin: "pipe", stdout: "pipe", diff --git a/packages/opencode/test/branding/branding.test.ts b/packages/opencode/test/branding/branding.test.ts index 95b8a7b69..01543a830 100644 --- a/packages/opencode/test/branding/branding.test.ts +++ b/packages/opencode/test/branding/branding.test.ts @@ -121,8 +121,12 @@ describe("Installation Script", () => { expect(installContent).not.toContain("anomalyco") }) - test("references altimate.ai domain for user-facing URLs", () => { - expect(installContent).toContain("altimate.ai") + test("references altimate-owned domain for user-facing URLs", () => { + // The install URL moved from altimate.ai → altimate.sh in v0.7.1 because + // altimate.ai/install was an unreachable route on the marketing SPA + // (issue #309). altimate.sh is the canonical altimate-code site. + expect(installContent).toContain("altimate.sh/install") + expect(installContent).not.toContain("altimate.ai/install") }) }) diff --git a/packages/opencode/test/install/upgrade-method.test.ts b/packages/opencode/test/install/upgrade-method.test.ts index 787c9052c..ce26b70a5 100644 --- a/packages/opencode/test/install/upgrade-method.test.ts +++ b/packages/opencode/test/install/upgrade-method.test.ts @@ -85,8 +85,23 @@ describe("upgrade execution", () => { expect(INSTALLATION_SRC).toContain("HOMEBREW_NO_AUTO_UPDATE") }) - test("curl upgrade uses altimate.ai/install endpoint", () => { - expect(INSTALLATION_SRC).toContain("https://altimate.ai/install") + test("curl upgrade uses altimate.sh/install endpoint", () => { + // Accept either apex (altimate.sh) or www. host. Apex routes to a non- + // Amplify origin today, so the source uses www.altimate.sh; once the + // apex is fixed (separate infra change), the source can drop www. and + // this assertion still passes. + expect(INSTALLATION_SRC).toMatch(/https:\/\/(www\.)?altimate\.sh\/install/) + // altimate.ai/install was the legacy URL (broken since 2026-05; tracked in + // #309). Keep the assertion so any future regression that reintroduces it + // fires immediately. + expect(INSTALLATION_SRC).not.toContain("https://altimate.ai/install") + }) + + test("curl upgrade fetch has a bounded timeout", () => { + // Without a timeout the install-script fetch can stall indefinitely on a + // hung CDN/origin, blocking `altimate upgrade` forever. Use AbortSignal.timeout + // so the request fails fast with a clear error instead. + expect(INSTALLATION_SRC).toMatch(/AbortSignal\.timeout\(\s*15_000\s*\)/) }) test("VERSION normalization strips v prefix", () => { diff --git a/packages/opencode/test/skill/release-v0.7.1-binary-adversarial.test.ts b/packages/opencode/test/skill/release-v0.7.1-binary-adversarial.test.ts index 3f974b8c8..5c32174e0 100644 --- a/packages/opencode/test/skill/release-v0.7.1-binary-adversarial.test.ts +++ b/packages/opencode/test/skill/release-v0.7.1-binary-adversarial.test.ts @@ -281,7 +281,9 @@ describe("v0.7.1 PR #820 — docs surface coverage", () => { }) test("README documents the curl install option with the correct binary name", () => { const readme = readFileSync(path.join(REPO_ROOT, "README.md"), "utf8") - expect(readme).toContain("curl -fsSL https://altimate.ai/install | bash") + // Accept either apex (altimate.sh) or www. host so a future apex-DNS fix + // that swaps www.altimate.sh → altimate.sh doesn't need another test update. + expect(readme).toMatch(/curl -fsSL https:\/\/(www\.)?altimate\.sh\/install \| bash/) expect(readme).toContain("~/.altimate/bin") expect(readme).toMatch(/single self-contained binary named `altimate`/) })