fix: [#309] point install endpoint at altimate.sh/install (not altimate.ai/install)#825
Conversation
…te.ai/install) altimate.ai is the marketing site (a React Router SPA on a different host) where `/install` falls through to an HTML 404 page. altimate.sh is the canonical altimate-code site and now serves the install script at `/install` via a Next.js route handler with proper text/x-shellscript content type and server-side GA4 tracking (companion PR in AltimateAI/altimate-code-website). The mismatch broke v0.7.1's standalone install path end-to-end: • `curl -fsSL https://altimate.ai/install | bash` fetched HTML and tried to bash-execute it (would error out, but the symptom was confusing). • `altimate upgrade` for curl-installed users fetches the install URL via `Installation.upgradeCurl()` to re-run the install script. With the broken URL, every curl-user's in-place upgrade silently failed. This PR swaps the seven references in this repo: • install (curl install script): two examples in --help block • README.md: install instruction • packages/opencode/src/installation/index.ts: the fetch URL inside `upgradeCurl()` • docs/docs/reference/troubleshooting.md: three references in the install troubleshooting section added in v0.7.1 • packages/opencode/test/install/upgrade-method.test.ts: assertion now requires altimate.sh/install AND explicitly rejects altimate.ai/install so a future regression that reintroduces the broken URL fires immediately • packages/opencode/test/branding/branding.test.ts: renamed brand-domain assertion to "references altimate-owned domain for user-facing URLs" that requires altimate.sh/install and rejects altimate.ai/install • packages/opencode/test/skill/release-v0.7.1-binary-adversarial.test.ts: the README curl-install assertion was pinning the old URL; updated `docs/mkdocs.yml`'s `altimate.ai/discord` link is unchanged — that's a separate marketing-site URL, not the install path. Pairs with AltimateAI/altimate-code-website#22 which adds the `app/install/route.ts` handler. Ship the website PR FIRST so the new URL is live before this one merges to main — otherwise curl-install would be broken in a different way (pointing at a not-yet-deployed endpoint) between merges. Closes #309. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
📝 WalkthroughWalkthroughThis PR replaces occurrences of the curl installer endpoint ChangesInstallation Endpoint Migration
🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues:
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
1 similar comment
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
❌ Tests — Failures DetectedTypeScript — 15 failure(s)
Next StepPlease address the failing cases above and re-run verification. |
… to Amplify After AltimateAI/altimate-code-website#22 merged and deployed, the install endpoint serves correctly from www.altimate.sh/install but the apex altimate.sh/install still returns HTTP 404 from a non-Amplify origin (ip-10-124-5-249.us-west-2.compute.internal, no x-amz-cf-id headers). The apex DNS / CloudFront alias is a separate infra fix. This is a same-day workaround: switch all install endpoint references from altimate.sh/install to www.altimate.sh/install. Once the apex routing is fixed, drop the `www.` prefix — the test assertions use a `(www\.)?` regex so they keep passing across both forms. Also adds an altimate_change marker block around the modified line in `packages/opencode/src/installation/index.ts:upgradeCurl()`. The line sits in upstream-shared territory and the marker guard flagged it as unmarked custom code; wrap it now so future upstream merges see the intent and don't auto-overwrite. Files touched: • install • README.md • docs/docs/reference/troubleshooting.md • packages/opencode/src/installation/index.ts (+ altimate_change markers) • packages/opencode/test/install/upgrade-method.test.ts (assertion → /https:\/\/(www\.)?altimate\.sh\/install/) • packages/opencode/test/skill/release-v0.7.1-binary-adversarial.test.ts (README assertion → /curl -fsSL https:\/\/(www\.)?altimate\.sh\/install \| bash/) Verified end-to-end: • `curl -fsSL https://www.altimate.sh/install` → HTTP 200, Content-Type text/x-shellscript, body identical to raw.githubusercontent.com/.../main/install (diff returns 0). • Full sandboxed install: `HOME=$(mktemp -d) bash <(curl ... www.altimate.sh)` completes; installed binary returns `0.7.1`. • Apex confirmed broken: `curl -sI https://altimate.sh/install` → 404 from `ip-10-124-5-249.us-west-2.compute.internal` (not Amplify). 176/176 tests pass across the touched suites. Marker guard passes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
2 similar comments
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/opencode/src/installation/index.ts (1)
10-17: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy liftReplace ad-hoc telemetry singleton with Effect-native composition/caching.
This new mutable cache helper (
_telemetryCache+getTelemetry) introduces a non-Effect pattern inpackages/opencode/**/*.ts. Please move this toEffect.fn/Effect.fnUntraced+Effect.cachedso lifecycle/tracing semantics stay consistent with the codebase conventions.As per coding guidelines, "Use
Effect.gen(function* () { ... })for composing Effect computations", "UseEffect.fn("Domain.method")for named/traced effects andEffect.fnUntracedfor internal helpers", and "UseEffect.cachedwhen multiple concurrent callers should share a single in-flight computation rather than storingFiber | undefinedorPromise | undefinedmanually".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/opencode/src/installation/index.ts` around lines 10 - 17, Replace the ad-hoc mutable singleton (_telemetryCache and getTelemetry) with an Effect-based cached function: create an Effect.fnUntraced (internal helper) that performs the dynamic import of "../telemetry" inside an Effect.gen and returns the Telemetry export, then wrap that Effect with Effect.cached so concurrent callers share a single in-flight computation; remove _telemetryCache and ensure callers invoke the new Effect (e.g., getTelemetryEffect) to run the effect rather than relying on the manual Promise/variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/opencode/src/installation/index.ts`:
- Around line 41-44: The fetch call that retrieves the install script in
upgradeCurl has no timeout and can hang; wrap the request with an
AbortController and a timer (e.g., 10s or appropriate constant) so the request
is aborted on timeout, clear the timer on success, and throw a clear error like
"install script fetch timed out" when aborted; update the fetch call that
assigns body (and any related error handling in upgradeCurl) to use
controller.signal and ensure the timer is cleaned up to avoid leaks.
---
Outside diff comments:
In `@packages/opencode/src/installation/index.ts`:
- Around line 10-17: Replace the ad-hoc mutable singleton (_telemetryCache and
getTelemetry) with an Effect-based cached function: create an Effect.fnUntraced
(internal helper) that performs the dynamic import of "../telemetry" inside an
Effect.gen and returns the Telemetry export, then wrap that Effect with
Effect.cached so concurrent callers share a single in-flight computation; remove
_telemetryCache and ensure callers invoke the new Effect (e.g.,
getTelemetryEffect) to run the effect rather than relying on the manual
Promise/variable.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 9af53dbb-b83b-4cbe-8d45-12364a6f4f91
📒 Files selected for processing (6)
README.mddocs/docs/reference/troubleshooting.mdinstallpackages/opencode/src/installation/index.tspackages/opencode/test/install/upgrade-method.test.tspackages/opencode/test/skill/release-v0.7.1-binary-adversarial.test.ts
✅ Files skipped from review due to trivial changes (2)
- install
- docs/docs/reference/troubleshooting.md
Address CodeRabbit review feedback on PR #825: the install-script `fetch` in `Installation.upgradeCurl()` had no timeout, so a stalled CDN/origin could hang `altimate upgrade` indefinitely. Wrap the request with `AbortSignal.timeout(15_000)` so it fails fast. - `packages/opencode/src/installation/index.ts` — add `signal: AbortSignal.timeout(15_000)` to the fetch options; keep inside the existing `altimate_change` block (now gates URL + timeout together). - `packages/opencode/test/install/upgrade-method.test.ts` — new regression assertion that the source still contains the bounded timeout. The other CodeRabbit comment (refactor `_telemetryCache` to `Effect.cached`) is outside this PR's diff and unrelated to the install URL fix — leaving it for a separate change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
2 similar comments
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
There was a problem hiding this comment.
♻️ Duplicate comments (1)
packages/opencode/src/installation/index.ts (1)
42-47:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winImprove error messaging for timeout scenarios.
The
AbortSignal.timeoutcorrectly bounds the request, but when it fires the resultingAbortErrorlacks context about the 15s timeout. The current.thenonly handles HTTP errors viares.statusText. Consider wrapping the fetch in a try-catch to provide a clearer message when the timeout is reached, so users can distinguish timeout failures from HTTP errors.🛡️ Suggested error handling improvement
- 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() - }) + 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() + }) + .catch((err) => { + if (err.name === "TimeoutError" || err.name === "AbortError") { + throw new Error("Install script fetch timed out after 15s") + } + throw err + })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/opencode/src/installation/index.ts` around lines 42 - 47, The fetch that assigns const body uses AbortSignal.timeout(15_000) but does not distinguish an abort from an HTTP error; wrap the await fetch(...) + res.ok check in a try-catch, catch errors from the fetch, and if the error is an AbortError (e.g., error.name === 'AbortError' or DOMException with name 'AbortError') rethrow a new, clear Error indicating the request to "https://www.altimate.sh/install" timed out after 15s; otherwise rethrow or log the original error so HTTP/non-timeout failures keep their original messages. Ensure you modify the block that creates body (the fetch + then/res.ok logic) and keep the AbortSignal.timeout(15_000) usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@packages/opencode/src/installation/index.ts`:
- Around line 42-47: The fetch that assigns const body uses
AbortSignal.timeout(15_000) but does not distinguish an abort from an HTTP
error; wrap the await fetch(...) + res.ok check in a try-catch, catch errors
from the fetch, and if the error is an AbortError (e.g., error.name ===
'AbortError' or DOMException with name 'AbortError') rethrow a new, clear Error
indicating the request to "https://www.altimate.sh/install" timed out after 15s;
otherwise rethrow or log the original error so HTTP/non-timeout failures keep
their original messages. Ensure you modify the block that creates body (the
fetch + then/res.ok logic) and keep the AbortSignal.timeout(15_000) usage.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 370ceb67-72e9-4120-914e-1336abcb4e15
📒 Files selected for processing (2)
packages/opencode/src/installation/index.tspackages/opencode/test/install/upgrade-method.test.ts
Hotfix for v0.7.1's broken install endpoint plus a defensive pass on the upgrade fetch surface (5-persona pre-release review caught two P0s that PR #825 did not). Fixed - `Installation.upgradeCurl()` fetches from www.altimate.sh/install instead of the unreachable altimate.ai/install. (#825, closes #309) - Published GitHub Action (`github/action.yml`) realigned with the v0.7.1 binary rename: cache + PATH use ~/.altimate/bin (was ~/.altimate-code/bin), binary invoked as `altimate` (was `altimate-code`). Action was broken on every cache miss for v0.7.1+ even before this URL fix. - 15s bounded timeout on the upgrader fetch via AbortSignal.timeout (CodeRabbit feedback on #825). Changed - Curl-upgrade fetch failures now surface an actionable error naming the URL + the manual re-install one-liner + the GitHub releases fallback, instead of a raw `AbortError: The operation was aborted` or `Error: Not Found`. HTTP non-2xx also includes the status code. - `UPGRADE_INSTALL_URL` and `UPGRADE_FETCH_TIMEOUT_MS` extracted as named constants inside the `altimate_change` block, so a future timeout tune is a single edit. Testing - 30 adversarial tests in `release-v0.7.2-adversarial.test.ts` covering URL eradication, cross-file host consistency, named- constant invariants, error-surface invariants, action.yml alignment, marker integrity, migration recovery surface, and CHANGELOG presence. - 529/529 tests pass across install/branding/v0.7.1/v0.7.2 suites. - Full opencode test suite: 8100 pass / 503 skip / 0 fail. - Pre-release sanity (`bun run pre-release`): all 4 checks pass. - Marker guard (`script/upstream/analyze.ts --markers --base main --strict`): ok. If you installed v0.7.1 via curl, your `altimate upgrade` will still fail until you re-install manually once: curl -fsSL https://www.altimate.sh/install | bash v0.7.2 and forward self-heal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
What does this PR do?
Swaps the install endpoint from
altimate.ai/install(unreachable — HTML 404 on the marketing-site SPA) toaltimate.sh/install(the canonical altimate-code site, where a Next.js route handler now serves the curl install script — see AltimateAI/altimate-code-website#22).The mismatch broke v0.7.1's standalone install path end-to-end. Two failures, one URL:
curl -fsSL https://altimate.ai/install | bashfetched HTML and tried to bash-execute it (would error out, but with a confusing symptom — not a clear "endpoint missing" message).altimate upgradefor curl-installed users fetches the install URL viaInstallation.upgradeCurl()inpackages/opencode/src/installation/index.ts:37to re-run the install script. With the broken URL, every curl-installed user's in-place upgrade silently failed.Type of change
Issue for this PR
Closes #309
How did you verify your code works?
bun turbo typecheck --filter=@altimateai/altimate-code— cleanbun test --timeout 30000 test/install/ test/installation/ test/branding/ test/skill/release-v0.7.1-*— 420/420 passbun run script/upstream/analyze.ts --markers --base main --strict—okno upstream-shared files modifiedpackages/opencode/test/install/upgrade-method.test.ts:88-93so the assertion now requiresaltimate.sh/installAND rejectsaltimate.ai/install(negative assertion catches future regression that reintroduces the broken URL)packages/opencode/test/branding/branding.test.ts:124-130"references altimate-owned domain" check the same waypackages/opencode/test/skill/release-v0.7.1-binary-adversarial.test.ts:284README curl-install assertion that was pinning the old URLaltimate upgradefrom a curl-installed binary upgrades in place (manual verification)curl -fsSL https://altimate.sh/install | bashend-to-end smoke (manual verification)Checklist
docs/docs/reference/troubleshooting.md)altimate.ai/installin two test files)altimate.sh/install. Merge order: website first, then this.Files touched
installaltimate.ai/install→altimate.sh/install(--help examples)README.mdpackages/opencode/src/installation/index.tsfetch("https://altimate.sh/install")inupgradeCurl()docs/docs/reference/troubleshooting.mdpackages/opencode/test/install/upgrade-method.test.tspackages/opencode/test/branding/branding.test.tspackages/opencode/test/skill/release-v0.7.1-binary-adversarial.test.tsOut of scope
docs/mkdocs.yml:51referencesaltimate.ai/discord— that's the Discord invite on the marketing site, not the install path. Left unchanged.Pairs with
app/install/route.tshandler that serves the curl script ataltimate.sh/installwith properContent-Typeand GA4 download tracking.🤖 Generated with Claude Code
Summary by cubic
Switch the install endpoint to https://www.altimate.sh/install and add a 15s timeout in
upgradeCurl()to prevent hung upgrades. Fixes curl installs and restoresaltimate upgradefor curl users (issue #309).upgradeCurl()now fetches fromhttps://www.altimate.sh/install(inside analtimate_changeblock).AbortSignal.timeout(15_000)to fail fast on stalls.install,README.md, and troubleshooting docs to use thewwwhost.https://(www\.)?altimate.sh/install, rejectaltimate.ai/install, and verify the timeout is present.Written for commit a511019. Summary will update on new commits. Review in cubic
Summary by CodeRabbit
Documentation
Chores
Bug Fixes