From 92804f109052c2ac6a89c4ded1d2b94cd516aeb5 Mon Sep 17 00:00:00 2001 From: Clay Good Date: Mon, 26 Oct 2026 16:25:20 -0500 Subject: [PATCH 1/6] docs(install): simplify the install page and ship archives - Install docs: just the two commands, using openspec.dev URLs. Details move to a short "Install options" section. - Releases attach .tar.gz archives (.zip on Windows) instead of bare binaries. The installers unpack them and still install older releases that only have bare binaries. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/release-openspec/SKILL.md | 2 +- .changeset/install-archives.md | 5 ++ .github/workflows/binaries.yml | 28 +++++++--- README.md | 8 ++- docs-lab/reference/cli.md | 2 +- docs-lab/start/installation.md | 65 +++++++++--------------- docs/README.md | 2 +- docs/getting-started.md | 2 +- docs/installation.md | 40 ++++++++------- install.md | 8 +-- scripts/README.md | 5 +- scripts/binary/install.ps1 | 33 +++++++++--- scripts/binary/install.sh | 28 +++++++--- test/binary-installer.test.ts | 32 ++++++++++-- 14 files changed, 159 insertions(+), 101 deletions(-) create mode 100644 .changeset/install-archives.md diff --git a/.agents/skills/release-openspec/SKILL.md b/.agents/skills/release-openspec/SKILL.md index 19c03a6c03..c9f414daa6 100644 --- a/.agents/skills/release-openspec/SKILL.md +++ b/.agents/skills/release-openspec/SKILL.md @@ -146,7 +146,7 @@ After the Version Packages PR merges: - `npm view @fission-ai/openspec@ version` - remote tag `v` points at the expected commit; - `gh release view v` exists and is not a prerelease. - - The release's assets include the 8 `openspec-*` standalone binaries and `SHA256SUMS`, attached by the Binaries workflow (`binaries.yml`) about 10 minutes after the release is published. Until `SHA256SUMS` is there, the install scripts keep installing the previous release, so users are never left without one. + - The release's assets include the 8 `openspec-*` standalone archives (`.tar.gz`, `.zip` on Windows) and `SHA256SUMS`, attached by the Binaries workflow (`binaries.yml`) about 10 minutes after the release is published. Until `SHA256SUMS` is there, the install scripts keep installing the previous release, so users are never left without one. 3. If only some artifacts exist, report partial state and resume verification before retrying any publish action. Never republish a version already on npm. Missing binaries never need an npm action: re-run `binaries.yml` with `workflow_dispatch` and the release tag to attach them. 4. Once all artifacts exist, read [references/release-notes.md](references/release-notes.md), polish the GitHub Release, and verify the saved title/body. diff --git a/.changeset/install-archives.md b/.changeset/install-archives.md new file mode 100644 index 0000000000..7e591e26b3 --- /dev/null +++ b/.changeset/install-archives.md @@ -0,0 +1,5 @@ +--- +"@fission-ai/openspec": patch +--- + +Simpler install: `curl -fsSL https://openspec.dev/install.sh | sh` (Windows: `irm https://openspec.dev/install.ps1 | iex`). Release downloads are now archives: `.tar.gz`, or `.zip` on Windows. diff --git a/.github/workflows/binaries.yml b/.github/workflows/binaries.yml index 22cfec30fc..00ac817de9 100644 --- a/.github/workflows/binaries.yml +++ b/.github/workflows/binaries.yml @@ -65,10 +65,24 @@ jobs: echo "::error::package.json version $version does not match tag $REF" exit 1 } - - name: Checksums and installer + # Users download archives: .tar.gz, or .zip on Windows. The bare + # binaries stay in dist-bin for the tests below. + - name: Archives, checksums and installer run: | cd dist-bin - sha256sum openspec-* > SHA256SUMS + for bin in openspec-*; do + name=${bin%.exe} + rm -rf pack && mkdir pack && cp ../LICENSE pack/ + if [ "$bin" != "$name" ]; then + cp "$bin" pack/openspec.exe + (cd pack && zip -q "../$name.zip" openspec.exe LICENSE) + else + cp "$bin" pack/openspec && chmod 755 pack/openspec + tar -czf "$name.tar.gz" -C pack openspec LICENSE + fi + done + rm -rf pack + sha256sum openspec-*.tar.gz openspec-*.zip > SHA256SUMS cp ../scripts/binary/install.sh ../scripts/binary/install.ps1 . cat SHA256SUMS - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -196,7 +210,7 @@ jobs: foreach ($tag in 'v1.1.0', 'v1.2.0') { $d = Join-Path $site "releases/download/$tag" New-Item -ItemType Directory -Force -Path $d | Out-Null - Copy-Item "dist-bin/openspec-$env:ASSET.exe" $d + Copy-Item "dist-bin/openspec-$env:ASSET.zip" $d if ($tag -eq 'v1.1.0') { Copy-Item dist-bin/SHA256SUMS $d } } Set-Content -Path (Join-Path $site 'releases.atom') -Value ('' + (('v1.2.0', 'v1.1.0' | ForEach-Object { "" }) -join '') + '') @@ -283,13 +297,15 @@ jobs: # SHA256SUMS goes last: installers treat a release that has it as # complete and keep installing the previous one until then. The # installers themselves are served from main, not from releases. - gh release upload "$tag" openspec-* --clobber --repo "$GITHUB_REPOSITORY" + gh release upload "$tag" openspec-*.tar.gz openspec-*.zip --clobber --repo "$GITHUB_REPOSITORY" gh release upload "$tag" SHA256SUMS --clobber --repo "$GITHUB_REPOSITORY" - # Signed proof each binary was built by this workflow from this tag, which + # Signed proof each archive was built by this workflow from this tag, which # anyone can check with `gh attestation verify`. The binaries are not # notarized or code-signed yet, so this is the verifiable trail meanwhile. # After the upload, so a first-time problem here never holds binaries back. - uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2 continue-on-error: true with: - subject-path: 'dist-bin/openspec-*' + subject-path: | + dist-bin/openspec-*.tar.gz + dist-bin/openspec-*.zip diff --git a/README.md b/README.md index ce794e0949..b504c82e64 100644 --- a/README.md +++ b/README.md @@ -117,18 +117,16 @@ Solo, OpenSpec keeps you and your AI honest on a single repo. On a team, the har ## Quick Start -Install OpenSpec. It is a single file and needs no Node.js (on Alpine Linux, first run `apk add libstdc++ libgcc`). - -macOS and Linux: +Install OpenSpec on macOS or Linux: ```bash -curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh +curl -fsSL https://openspec.dev/install.sh | sh ``` Windows (PowerShell): ```powershell -irm https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.ps1 | iex +irm https://openspec.dev/install.ps1 | iex ``` Prefer a package manager? `npm install -g @fission-ai/openspec@latest` (needs Node.js 20.19.0 or higher) or the official [Homebrew formula](https://formulae.brew.sh/formula/openspec), `brew install openspec`. diff --git a/docs-lab/reference/cli.md b/docs-lab/reference/cli.md index 982acf456d..ef7e7a700d 100644 --- a/docs-lab/reference/cli.md +++ b/docs-lab/reference/cli.md @@ -2329,7 +2329,7 @@ For the standalone install, the update command is `openspec install`. ## openspec install -Installs the standalone `openspec`, a single file that runs without Node.js. Run it from an npm or Homebrew install to switch, or from the standalone install to upgrade it in place. +Installs the standalone `openspec`. Run it from an npm or Homebrew install to switch, or from the standalone install to upgrade it in place. ```bash openspec install # newest release diff --git a/docs-lab/start/installation.md b/docs-lab/start/installation.md index 1e228cf821..3f0bf7221e 100644 --- a/docs-lab/start/installation.md +++ b/docs-lab/start/installation.md @@ -5,55 +5,19 @@ ## Install -OpenSpec installs as a single `openspec` file. It needs no Node.js. - -On macOS or Linux, in your terminal: +On macOS or Linux: ```bash -curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh +curl -fsSL https://openspec.dev/install.sh | sh ``` On Windows, in PowerShell: ```powershell -irm https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.ps1 | iex +irm https://openspec.dev/install.ps1 | iex ``` -- **Where it goes**: `~/.local/bin`; on Windows, `%LOCALAPPDATA%\Programs\openspec`, which it adds to your user PATH. -- **What it checks**: it picks the file for your machine and verifies it against the release's `SHA256SUMS` before installing. -- **Which release**: the newest one whose files are all attached. For the few minutes after a release is published while its files upload, it installs the previous one and says so. -- **Alpine Linux**: run `apk add libstdc++ libgcc` first. -- **Options**: set `OPENSPEC_INSTALL_DIR` to install elsewhere, or `OPENSPEC_VERSION=v1.15.0` to pin a release. - -If the installer says the folder isn't on your PATH, add it as it shows. Then [check it worked](#check-it-worked). - -The workflow itself runs inside an AI coding tool: Claude Code, Cursor, or any other tool on the [supported list](../reference/supported-tools.md). - -### Download it yourself - -Each [release](https://github.com/Fission-AI/OpenSpec/releases/latest) has one file per platform: - -| Platform | File | -|---|---| -| macOS 13+ (Apple silicon / Intel) | `openspec-darwin-arm64` / `openspec-darwin-x64` | -| Linux, glibc 2.17+ (arm64 / x64) | `openspec-linux-arm64` / `openspec-linux-x64` | -| Alpine 3.17+ (arm64 / x64) | `openspec-linux-arm64-musl` / `openspec-linux-x64-musl` | -| Windows 10+ (arm64 / x64) | `openspec-windows-arm64.exe` / `openspec-windows-x64.exe` | - -Rename it to `openspec` (`openspec.exe` on Windows), run `chmod +x openspec` on macOS or Linux, and put it in a folder on your PATH. - -> [!NOTE] -> macOS blocks a file downloaded in a browser until you run `xattr -d com.apple.quarantine openspec`. The install command above doesn't need this. - -### Verify a download - -Each release binary comes with a signed record of the workflow run that built it. With the [GitHub CLI](https://cli.github.com), in your terminal: - -```bash -gh attestation verify openspec-darwin-arm64 --repo Fission-AI/OpenSpec -``` - -It confirms the file is the one that release's workflow built, or fails. This is optional; the installer already checks every download against `SHA256SUMS`. +Then [check it worked](#check-it-worked). Need a specific version or folder? See [install options](#install-options). ## Install with your AI assistant @@ -165,6 +129,27 @@ If that prints a version number, the CLI is on your PATH. It installs once per m Next, [set up your project](setup.md). If your assistant already ran init, that page shows what it wrote and how to adjust it. +## Install options + +- **Folder**: set `OPENSPEC_INSTALL_DIR`. The default is `~/.local/bin` (Windows: `%LOCALAPPDATA%\Programs\openspec`). +- **Version**: set `OPENSPEC_VERSION`, for example `OPENSPEC_VERSION=v1.15.0`. +- **Alpine Linux**: run `apk add libstdc++ libgcc` first. + +To download by hand, get the archive for your machine from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), unpack it, and put `openspec` on your PATH. On macOS, also run `xattr -d com.apple.quarantine openspec`. + +| Platform | File | +|---|---| +| macOS (Apple silicon / Intel) | `openspec-darwin-arm64.tar.gz` / `openspec-darwin-x64.tar.gz` | +| Linux (arm64 / x64) | `openspec-linux-arm64.tar.gz` / `openspec-linux-x64.tar.gz` | +| Alpine (arm64 / x64) | `openspec-linux-arm64-musl.tar.gz` / `openspec-linux-x64-musl.tar.gz` | +| Windows (arm64 / x64) | `openspec-windows-arm64.zip` / `openspec-windows-x64.zip` | + +To check a download came from our release workflow, use the [GitHub CLI](https://cli.github.com): + +```bash +gh attestation verify openspec-darwin-arm64.tar.gz --repo Fission-AI/OpenSpec +``` + ## Switch from npm to the standalone install Switching is optional; npm keeps working. Your settings and your projects carry over; only the program changes. diff --git a/docs/README.md b/docs/README.md index 8c5df9d12e..17d9536235 100644 --- a/docs/README.md +++ b/docs/README.md @@ -99,7 +99,7 @@ That second one matters more than it looks. OpenSpec has two halves: a command l ## The thirty-second version ```text -1. Install curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh +1. Install curl -fsSL https://openspec.dev/install.sh | sh 2. Initialize cd your-project && openspec init 3. Explore (in your AI chat) /opsx:explore ← optional, but a great habit 4. Propose (in your AI chat) /opsx:propose add-dark-mode diff --git a/docs/getting-started.md b/docs/getting-started.md index 2112a65e4c..7f40b3595b 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -14,7 +14,7 @@ This guide explains how OpenSpec works after you've installed and initialized it The whole loop, with each step labeled by where it happens: ```text -TERMINAL $ curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh +TERMINAL $ curl -fsSL https://openspec.dev/install.sh | sh TERMINAL $ cd your-project && openspec init AI CHAT /opsx:explore (optional: think it through first) AI CHAT /opsx:propose add-dark-mode (AI drafts the plan; you review it) diff --git a/docs/installation.md b/docs/installation.md index 759d29414e..9b50667c08 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -2,32 +2,19 @@ ## Install -OpenSpec is a single file. It needs no Node.js or anything else (on Alpine Linux, first run `apk add libstdc++ libgcc`). - macOS and Linux: ```bash -curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh +curl -fsSL https://openspec.dev/install.sh | sh ``` Windows (PowerShell): ```powershell -irm https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.ps1 | iex +irm https://openspec.dev/install.ps1 | iex ``` -The installer picks the newest release whose files are all attached and the right file for your machine, checks it against the release's `SHA256SUMS`, and installs it to `~/.local/bin` (Windows: `%LOCALAPPDATA%\Programs\openspec`, added to your user `PATH`). Set `OPENSPEC_INSTALL_DIR` to choose another folder, or `OPENSPEC_VERSION=v1.15.0` to pin a release. Prefer npm or another package manager? See [Package Managers](#package-managers). - -To install by hand, download your platform's file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), rename it to `openspec` (`openspec.exe` on Windows), make it executable on macOS and Linux (`chmod +x openspec`), and put it on your `PATH`: - -| Platform | File | -|---|---| -| macOS 13+ (Apple Silicon / Intel) | `openspec-darwin-arm64` / `openspec-darwin-x64` | -| Linux (glibc 2.17+) | `openspec-linux-x64` / `openspec-linux-arm64` | -| Alpine 3.17+ (needs `apk add libstdc++ libgcc`) | `openspec-linux-x64-musl` / `openspec-linux-arm64-musl` | -| Windows 10+ | `openspec-windows-x64.exe` / `openspec-windows-arm64.exe` | - -On macOS, a file downloaded with a browser is blocked until you run `xattr -d com.apple.quarantine openspec`; the install script avoids this. On Windows, SmartScreen may warn the first time you run it from Explorer. +Then [verify the installation](#verify-installation). Need a specific version or folder? See [install options](#install-options). ## Install with your AI assistant @@ -46,10 +33,10 @@ order, and stop where a step tells you to stop. skip to step 3. If I installed it with a package manager, mention once that `openspec install` switches to the standalone install, but only switch if I ask; never switch it to a different install method on your own. Otherwise install - the standalone OpenSpec binary, which needs no Node.js. Show me the command + the standalone OpenSpec binary. Show me the command for my OS and run it only once I confirm, then skip to step 3: - macOS / Linux: curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh - Windows (PowerShell): irm https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.ps1 | iex + macOS / Linux: curl -fsSL https://openspec.dev/install.sh | sh + Windows (PowerShell): irm https://openspec.dev/install.ps1 | iex If I'd rather use a package manager, or the installer fails, go to step 2. 2. PACKAGE MANAGER (only if step 1 did not install it). Run `node --version`: @@ -203,6 +190,21 @@ Or add to your development environment in `flake.nix`: openspec --version ``` +## Install options + +- **Folder**: set `OPENSPEC_INSTALL_DIR`. The default is `~/.local/bin` (Windows: `%LOCALAPPDATA%\Programs\openspec`). +- **Version**: set `OPENSPEC_VERSION`, for example `OPENSPEC_VERSION=v1.15.0`. +- **Alpine Linux**: run `apk add libstdc++ libgcc` first. + +To download by hand, get the archive for your machine from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), unpack it, and put `openspec` on your PATH. On macOS, also run `xattr -d com.apple.quarantine openspec`. + +| Platform | File | +|---|---| +| macOS (Apple Silicon / Intel) | `openspec-darwin-arm64.tar.gz` / `openspec-darwin-x64.tar.gz` | +| Linux (arm64 / x64) | `openspec-linux-arm64.tar.gz` / `openspec-linux-x64.tar.gz` | +| Alpine (arm64 / x64) | `openspec-linux-arm64-musl.tar.gz` / `openspec-linux-x64-musl.tar.gz` | +| Windows (arm64 / x64) | `openspec-windows-arm64.zip` / `openspec-windows-x64.zip` | + ## Switch from npm to the standalone install Your settings and projects carry over; only the program changes. diff --git a/install.md b/install.md index 51e73bacc4..5357ed3660 100644 --- a/install.md +++ b/install.md @@ -21,18 +21,18 @@ TODO: ## 1. Install -Run `openspec --version` first. If it already prints a version, the CLI is installed: say so, run `openspec version --check` (it prints the update command for how OpenSpec was installed when it can tell; otherwise update it the way it was installed, e.g. `brew upgrade openspec`), offer to run that command, and skip ahead to step 3. If it was installed with npm or another package manager, mention once that `openspec install` switches to the standalone install, which runs without Node.js. Only offer it: the user may have chosen npm on purpose, so don't repeat it or switch unless they ask. Never switch an install to a different method on your own; that leaves two copies competing on PATH. +Run `openspec --version` first. If it already prints a version, the CLI is installed: say so, run `openspec version --check` (it prints the update command for how OpenSpec was installed when it can tell; otherwise update it the way it was installed, e.g. `brew upgrade openspec`), offer to run that command, and skip ahead to step 3. If it was installed with npm or another package manager, mention once that `openspec install` switches to the standalone install. Only offer it: the user may have chosen npm on purpose, so don't repeat it or switch unless they ask. Never switch an install to a different method on your own; that leaves two copies competing on PATH. -Install the standalone OpenSpec binary. It is a single file and needs no Node.js (on Alpine Linux, `apk add libstdc++ libgcc` first). Show the command for the user's OS and run it only once they confirm, then skip to step 3: +Install the standalone OpenSpec binary (on Alpine Linux, `apk add libstdc++ libgcc` first). Show the command for the user's OS and run it only once they confirm, then skip to step 3: ```bash # macOS / Linux -curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh +curl -fsSL https://openspec.dev/install.sh | sh ``` ```powershell # Windows (PowerShell) -irm https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.ps1 | iex +irm https://openspec.dev/install.ps1 | iex ``` If the user would rather use a package manager, or the installer fails, continue with step 2. diff --git a/scripts/README.md b/scripts/README.md index 2d1d82842f..92e16b188c 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -75,8 +75,9 @@ Validates package version consistency before publishing. Builds the standalone `openspec` executables (no Node.js needed), the default way users install OpenSpec. `.github/workflows/binaries.yml` cross-compiles -every asset on Linux, tests each on its own OS and CPU, and attaches them, -`SHA256SUMS`, `install.sh` and `install.ps1` to each published release. +every asset on Linux, tests each on its own OS and CPU, and attaches them to +each published release as `.tar.gz` archives (`.zip` on Windows) with +`SHA256SUMS`. The installers are served from main. | File | What it is | |---|---| diff --git a/scripts/binary/install.ps1 b/scripts/binary/install.ps1 index 685fb7e9b5..080dd4873f 100644 --- a/scripts/binary/install.ps1 +++ b/scripts/binary/install.ps1 @@ -1,6 +1,6 @@ # Installs the standalone `openspec.exe` (no Node.js needed) on Windows. # -# irm https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.ps1 | iex +# irm https://openspec.dev/install.ps1 | iex # # $env:OPENSPEC_VERSION release to install (default: the newest complete one), e.g. v1.15.0 # $env:OPENSPEC_INSTALL_DIR where to put it (default: %LOCALAPPDATA%\Programs\openspec) @@ -84,19 +84,36 @@ $base = "$releases/download/$version" } - Write-Host "Downloading $asset ($version)..." try { - Invoke-WebRequest -UseBasicParsing -Uri "$base/$asset" -OutFile $exe if (-not (Test-Path $sums)) { Invoke-WebRequest -UseBasicParsing -Uri "$base/SHA256SUMS" -OutFile $sums } } catch { throw "openspec install: could not download from ${base}: $($_.Exception.Message). $npmHint" } - $line = Get-Content $sums | Where-Object { ($_ -split '\s+')[1] -eq $asset } | Select-Object -First 1 - if (-not $line) { throw "openspec install: $asset is not listed in SHA256SUMS" } - $expected = ($line -split '\s+')[0] - $actual = (Get-FileHash -Algorithm SHA256 -Path $exe).Hash - if ($actual -ne $expected) { throw "openspec install: checksum mismatch for $asset; refusing to install" } + # Releases ship a .zip; v1.15.0 and earlier, the bare .exe. + $lines = Get-Content $sums + $file = $null + $expected = $null + foreach ($candidate in "$($asset -replace '\.exe$', '.zip')", $asset) { + $line = $lines | Where-Object { ($_ -split '\s+')[1] -eq $candidate } | Select-Object -First 1 + if ($line) { $file = $candidate; $expected = ($line -split '\s+')[0]; break } + } + if (-not $file) { throw "openspec install: $asset is not listed in SHA256SUMS" } + + Write-Host "Downloading $file ($version)..." + $download = Join-Path $tmp $file + try { + Invoke-WebRequest -UseBasicParsing -Uri "$base/$file" -OutFile $download + } catch { + throw "openspec install: could not download from ${base}: $($_.Exception.Message). $npmHint" + } + $actual = (Get-FileHash -Algorithm SHA256 -Path $download).Hash + if ($actual -ne $expected) { throw "openspec install: checksum mismatch for $file; refusing to install" } + if ($file -ne $asset) { + $unpacked = Join-Path $tmp 'unpacked' + Expand-Archive -Path $download -DestinationPath $unpacked + Move-Item -Path (Join-Path $unpacked 'openspec.exe') -Destination $exe + } $installed = $null # A binary that cannot start at all throws instead of setting an exit code. diff --git a/scripts/binary/install.sh b/scripts/binary/install.sh index 956b5088cf..948efe813d 100644 --- a/scripts/binary/install.sh +++ b/scripts/binary/install.sh @@ -1,7 +1,7 @@ #!/bin/sh # Installs the standalone `openspec` binary (no Node.js needed) on Linux or macOS. # -# curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh +# curl -fsSL https://openspec.dev/install.sh | sh # # OPENSPEC_VERSION release to install (default: the newest complete one), e.g. v1.15.0 # OPENSPEC_INSTALL_DIR where to put it (default: ~/.local/bin) @@ -46,7 +46,7 @@ main() { case "$(uname -s)" in Linux) os=linux ;; Darwin) os=darwin ;; - *) fail "unsupported OS $(uname -s). On Windows, download openspec-windows-x64.exe from the release page." ;; + *) fail "unsupported OS $(uname -s). On Windows, use install.ps1." ;; esac case "$(uname -m)" in x86_64 | amd64) arch=x64 ;; @@ -138,21 +138,33 @@ main() { base="$releases/download/$version" fi - echo "Downloading $asset ($version)..." - download "$base/$asset" "$tmp/$asset" || fail "could not download $base/$asset; $npm_hint" if [ ! -s "$tmp/SHA256SUMS" ]; then download "$base/SHA256SUMS" "$tmp/SHA256SUMS" || fail "could not download $base/SHA256SUMS; $npm_hint" fi - expected=$(awk -v f="$asset" '$2 == f { print $1 }' "$tmp/SHA256SUMS") + # Releases ship a .tar.gz; v1.15.0 and earlier, the bare binary. + file="$asset.tar.gz" + expected=$(awk -v f="$file" '$2 == f { print $1 }' "$tmp/SHA256SUMS") + if [ -z "$expected" ]; then + file=$asset + expected=$(awk -v f="$file" '$2 == f { print $1 }' "$tmp/SHA256SUMS") + fi [ -n "$expected" ] || fail "$asset is not listed in SHA256SUMS" + + echo "Downloading $file ($version)..." + download "$base/$file" "$tmp/$file" || fail "could not download $base/$file; $npm_hint" if command -v sha256sum >/dev/null 2>&1; then - actual=$(sha256sum "$tmp/$asset" | awk '{ print $1 }') + actual=$(sha256sum "$tmp/$file" | awk '{ print $1 }') else - actual=$(shasum -a 256 "$tmp/$asset" | awk '{ print $1 }') + actual=$(shasum -a 256 "$tmp/$file" | awk '{ print $1 }') fi - [ "$actual" = "$expected" ] || fail "checksum mismatch for $asset; refusing to install" + [ "$actual" = "$expected" ] || fail "checksum mismatch for $file; refusing to install" + if [ "$file" != "$asset" ]; then + mkdir "$tmp/unpacked" + tar -xzf "$tmp/$file" -C "$tmp/unpacked" openspec || fail "could not unpack $file" + mv "$tmp/unpacked/openspec" "$tmp/$asset" + fi chmod 755 "$tmp/$asset" if ! installed=$("$tmp/$asset" --version); then case "$asset" in diff --git a/test/binary-installer.test.ts b/test/binary-installer.test.ts index fc26f6f6e4..ac532dc491 100644 --- a/test/binary-installer.test.ts +++ b/test/binary-installer.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; -import { execFile } from 'node:child_process'; +import { execFile, execFileSync } from 'node:child_process'; import { createHash } from 'node:crypto'; import fs from 'node:fs'; import http from 'node:http'; @@ -25,15 +25,28 @@ describe.skipIf(process.platform === 'win32')('standalone installer (install.sh) let server: http.Server; let base: string; - /** A release whose files are attached; `complete: false` leaves out SHA256SUMS, as mid-upload. */ - function release(site: string, tag: string, options: { complete?: boolean; tamper?: boolean } = {}) { + /** + * A release whose files are attached, as .tar.gz archives (`bare: true`: bare + * binaries, as v1.15.0 and earlier). `complete: false` leaves out SHA256SUMS, + * as mid-upload. + */ + function release(site: string, tag: string, options: { complete?: boolean; tamper?: boolean; bare?: boolean } = {}) { const dir = path.join(root, site, 'releases', 'download', tag); fs.mkdirSync(dir, { recursive: true }); const sums: string[] = []; for (const asset of ASSETS) { const body = `#!/bin/sh\necho ${tag.replace(/^v/, '')}\n`; - fs.writeFileSync(path.join(dir, asset), options.tamper ? `${body}# changed\n` : body); - sums.push(`${createHash('sha256').update(body).digest('hex')} ${asset}`); + let file = asset; + if (options.bare) { + fs.writeFileSync(path.join(dir, file), body); + } else { + file = `${asset}.tar.gz`; + const pack = fs.mkdtempSync(path.join(root, 'pack-')); + fs.writeFileSync(path.join(pack, 'openspec'), body); + execFileSync('tar', ['-czf', path.join(dir, file), '-C', pack, 'openspec']); + } + sums.push(`${createHash('sha256').update(fs.readFileSync(path.join(dir, file))).digest('hex')} ${file}`); + if (options.tamper) fs.appendFileSync(path.join(dir, file), '# changed\n'); } if (options.complete !== false) fs.writeFileSync(path.join(dir, 'SHA256SUMS'), sums.join('\n') + '\n'); } @@ -109,6 +122,9 @@ describe.skipIf(process.platform === 'win32')('standalone installer (install.sh) release('noise', 'v1.3.0-beta.1'); release('noise', 'v1.2.0'); + feed('bare', ['v1.15.0']); + release('bare', 'v1.15.0', { bare: true }); + feed('tampered', ['v1.2.0']); release('tampered', 'v1.2.0', { tamper: true }); }); @@ -152,6 +168,12 @@ describe.skipIf(process.platform === 'win32')('standalone installer (install.sh) expect(result.installed).toContain('echo 1.2.0'); }); + it('installs a release that attached bare binaries instead of archives', async () => { + const result = await install('bare'); + expect(result.code, result.out).toBe(0); + expect(result.installed).toContain('echo 1.15.0'); + }); + it('refuses a file that does not match SHA256SUMS', async () => { const result = await install('tampered'); expect(result.code).not.toBe(0); From b3098c54b14c44af1d25c5aad1f55f1eef9452bd Mon Sep 17 00:00:00 2001 From: Clay Good Date: Mon, 26 Oct 2026 16:26:42 -0500 Subject: [PATCH 2/6] docs(install): use openspec.dev/cli install URLs openspec.dev/install.sh already serves the Desktop beta installer. Co-Authored-By: Claude Opus 5.5 --- .changeset/install-archives.md | 2 +- README.md | 4 ++-- docs-lab/start/installation.md | 4 ++-- docs/README.md | 2 +- docs/getting-started.md | 2 +- docs/installation.md | 8 ++++---- install.md | 4 ++-- scripts/binary/install.ps1 | 2 +- scripts/binary/install.sh | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.changeset/install-archives.md b/.changeset/install-archives.md index 7e591e26b3..6a4d5ce18e 100644 --- a/.changeset/install-archives.md +++ b/.changeset/install-archives.md @@ -2,4 +2,4 @@ "@fission-ai/openspec": patch --- -Simpler install: `curl -fsSL https://openspec.dev/install.sh | sh` (Windows: `irm https://openspec.dev/install.ps1 | iex`). Release downloads are now archives: `.tar.gz`, or `.zip` on Windows. +Simpler install: `curl -fsSL https://openspec.dev/cli/install.sh | sh` (Windows: `irm https://openspec.dev/cli/install.ps1 | iex`). Release downloads are now archives: `.tar.gz`, or `.zip` on Windows. diff --git a/README.md b/README.md index b504c82e64..cdb2f07313 100644 --- a/README.md +++ b/README.md @@ -120,13 +120,13 @@ Solo, OpenSpec keeps you and your AI honest on a single repo. On a team, the har Install OpenSpec on macOS or Linux: ```bash -curl -fsSL https://openspec.dev/install.sh | sh +curl -fsSL https://openspec.dev/cli/install.sh | sh ``` Windows (PowerShell): ```powershell -irm https://openspec.dev/install.ps1 | iex +irm https://openspec.dev/cli/install.ps1 | iex ``` Prefer a package manager? `npm install -g @fission-ai/openspec@latest` (needs Node.js 20.19.0 or higher) or the official [Homebrew formula](https://formulae.brew.sh/formula/openspec), `brew install openspec`. diff --git a/docs-lab/start/installation.md b/docs-lab/start/installation.md index 3f0bf7221e..a06d8c6b26 100644 --- a/docs-lab/start/installation.md +++ b/docs-lab/start/installation.md @@ -8,13 +8,13 @@ On macOS or Linux: ```bash -curl -fsSL https://openspec.dev/install.sh | sh +curl -fsSL https://openspec.dev/cli/install.sh | sh ``` On Windows, in PowerShell: ```powershell -irm https://openspec.dev/install.ps1 | iex +irm https://openspec.dev/cli/install.ps1 | iex ``` Then [check it worked](#check-it-worked). Need a specific version or folder? See [install options](#install-options). diff --git a/docs/README.md b/docs/README.md index 17d9536235..42240619e0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -99,7 +99,7 @@ That second one matters more than it looks. OpenSpec has two halves: a command l ## The thirty-second version ```text -1. Install curl -fsSL https://openspec.dev/install.sh | sh +1. Install curl -fsSL https://openspec.dev/cli/install.sh | sh 2. Initialize cd your-project && openspec init 3. Explore (in your AI chat) /opsx:explore ← optional, but a great habit 4. Propose (in your AI chat) /opsx:propose add-dark-mode diff --git a/docs/getting-started.md b/docs/getting-started.md index 7f40b3595b..0da2cd32b5 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -14,7 +14,7 @@ This guide explains how OpenSpec works after you've installed and initialized it The whole loop, with each step labeled by where it happens: ```text -TERMINAL $ curl -fsSL https://openspec.dev/install.sh | sh +TERMINAL $ curl -fsSL https://openspec.dev/cli/install.sh | sh TERMINAL $ cd your-project && openspec init AI CHAT /opsx:explore (optional: think it through first) AI CHAT /opsx:propose add-dark-mode (AI drafts the plan; you review it) diff --git a/docs/installation.md b/docs/installation.md index 9b50667c08..e0ec482d77 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -5,13 +5,13 @@ macOS and Linux: ```bash -curl -fsSL https://openspec.dev/install.sh | sh +curl -fsSL https://openspec.dev/cli/install.sh | sh ``` Windows (PowerShell): ```powershell -irm https://openspec.dev/install.ps1 | iex +irm https://openspec.dev/cli/install.ps1 | iex ``` Then [verify the installation](#verify-installation). Need a specific version or folder? See [install options](#install-options). @@ -35,8 +35,8 @@ order, and stop where a step tells you to stop. ask; never switch it to a different install method on your own. Otherwise install the standalone OpenSpec binary. Show me the command for my OS and run it only once I confirm, then skip to step 3: - macOS / Linux: curl -fsSL https://openspec.dev/install.sh | sh - Windows (PowerShell): irm https://openspec.dev/install.ps1 | iex + macOS / Linux: curl -fsSL https://openspec.dev/cli/install.sh | sh + Windows (PowerShell): irm https://openspec.dev/cli/install.ps1 | iex If I'd rather use a package manager, or the installer fails, go to step 2. 2. PACKAGE MANAGER (only if step 1 did not install it). Run `node --version`: diff --git a/install.md b/install.md index 5357ed3660..936368cfaf 100644 --- a/install.md +++ b/install.md @@ -27,12 +27,12 @@ Install the standalone OpenSpec binary (on Alpine Linux, `apk add libstdc++ libg ```bash # macOS / Linux -curl -fsSL https://openspec.dev/install.sh | sh +curl -fsSL https://openspec.dev/cli/install.sh | sh ``` ```powershell # Windows (PowerShell) -irm https://openspec.dev/install.ps1 | iex +irm https://openspec.dev/cli/install.ps1 | iex ``` If the user would rather use a package manager, or the installer fails, continue with step 2. diff --git a/scripts/binary/install.ps1 b/scripts/binary/install.ps1 index 080dd4873f..eb058c9dcf 100644 --- a/scripts/binary/install.ps1 +++ b/scripts/binary/install.ps1 @@ -1,6 +1,6 @@ # Installs the standalone `openspec.exe` (no Node.js needed) on Windows. # -# irm https://openspec.dev/install.ps1 | iex +# irm https://openspec.dev/cli/install.ps1 | iex # # $env:OPENSPEC_VERSION release to install (default: the newest complete one), e.g. v1.15.0 # $env:OPENSPEC_INSTALL_DIR where to put it (default: %LOCALAPPDATA%\Programs\openspec) diff --git a/scripts/binary/install.sh b/scripts/binary/install.sh index 948efe813d..4d9b248f38 100644 --- a/scripts/binary/install.sh +++ b/scripts/binary/install.sh @@ -1,7 +1,7 @@ #!/bin/sh # Installs the standalone `openspec` binary (no Node.js needed) on Linux or macOS. # -# curl -fsSL https://openspec.dev/install.sh | sh +# curl -fsSL https://openspec.dev/cli/install.sh | sh # # OPENSPEC_VERSION release to install (default: the newest complete one), e.g. v1.15.0 # OPENSPEC_INSTALL_DIR where to put it (default: ~/.local/bin) From 9068da507ba70bfb3f30ce57d82e01076aeba995 Mon Sep 17 00:00:00 2001 From: Clay Good Date: Mon, 26 Oct 2026 17:27:19 -0500 Subject: [PATCH 3/6] docs(install): simplify install options wording Co-Authored-By: Claude Opus 5.5 --- docs-lab/start/installation.md | 33 ++++++++++++++++++++++----------- docs/installation.md | 31 +++++++++++++++++++++---------- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/docs-lab/start/installation.md b/docs-lab/start/installation.md index a06d8c6b26..5419e87ece 100644 --- a/docs-lab/start/installation.md +++ b/docs-lab/start/installation.md @@ -17,7 +17,7 @@ On Windows, in PowerShell: irm https://openspec.dev/cli/install.ps1 | iex ``` -Then [check it worked](#check-it-worked). Need a specific version or folder? See [install options](#install-options). +Then [check it worked](#check-it-worked). ## Install with your AI assistant @@ -131,20 +131,31 @@ Next, [set up your project](setup.md). If your assistant already ran init, that ## Install options -- **Folder**: set `OPENSPEC_INSTALL_DIR`. The default is `~/.local/bin` (Windows: `%LOCALAPPDATA%\Programs\openspec`). -- **Version**: set `OPENSPEC_VERSION`, for example `OPENSPEC_VERSION=v1.15.0`. -- **Alpine Linux**: run `apk add libstdc++ libgcc` first. +To pick a version or folder, add a setting before `sh`: -To download by hand, get the archive for your machine from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), unpack it, and put `openspec` on your PATH. On macOS, also run `xattr -d com.apple.quarantine openspec`. +```bash +curl -fsSL https://openspec.dev/cli/install.sh | OPENSPEC_VERSION=v1.15.0 sh +``` + +- `OPENSPEC_VERSION=v1.15.0` installs that version. +- `OPENSPEC_INSTALL_DIR=~/bin` installs to that folder (default: `~/.local/bin`). + +On Windows, set it first, for example `$env:OPENSPEC_VERSION = 'v1.15.0'`, then run the install command. + +On Alpine Linux, run `apk add libstdc++ libgcc` first. + +### Download by hand + +Download your file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), unzip it, and move `openspec` to a folder on your PATH. On macOS, then run `xattr -d com.apple.quarantine openspec`. -| Platform | File | +| Computer | File | |---|---| -| macOS (Apple silicon / Intel) | `openspec-darwin-arm64.tar.gz` / `openspec-darwin-x64.tar.gz` | -| Linux (arm64 / x64) | `openspec-linux-arm64.tar.gz` / `openspec-linux-x64.tar.gz` | -| Alpine (arm64 / x64) | `openspec-linux-arm64-musl.tar.gz` / `openspec-linux-x64-musl.tar.gz` | -| Windows (arm64 / x64) | `openspec-windows-arm64.zip` / `openspec-windows-x64.zip` | +| Mac with Apple chip / Intel | `openspec-darwin-arm64.tar.gz` / `openspec-darwin-x64.tar.gz` | +| Linux arm64 / x64 | `openspec-linux-arm64.tar.gz` / `openspec-linux-x64.tar.gz` | +| Alpine arm64 / x64 | `openspec-linux-arm64-musl.tar.gz` / `openspec-linux-x64-musl.tar.gz` | +| Windows arm64 / x64 | `openspec-windows-arm64.zip` / `openspec-windows-x64.zip` | -To check a download came from our release workflow, use the [GitHub CLI](https://cli.github.com): +To check a file is really ours, use the [GitHub CLI](https://cli.github.com): ```bash gh attestation verify openspec-darwin-arm64.tar.gz --repo Fission-AI/OpenSpec diff --git a/docs/installation.md b/docs/installation.md index e0ec482d77..1f8c6792fd 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -14,7 +14,7 @@ Windows (PowerShell): irm https://openspec.dev/cli/install.ps1 | iex ``` -Then [verify the installation](#verify-installation). Need a specific version or folder? See [install options](#install-options). +Then [verify the installation](#verify-installation). ## Install with your AI assistant @@ -192,18 +192,29 @@ openspec --version ## Install options -- **Folder**: set `OPENSPEC_INSTALL_DIR`. The default is `~/.local/bin` (Windows: `%LOCALAPPDATA%\Programs\openspec`). -- **Version**: set `OPENSPEC_VERSION`, for example `OPENSPEC_VERSION=v1.15.0`. -- **Alpine Linux**: run `apk add libstdc++ libgcc` first. +To pick a version or folder, add a setting before `sh`: -To download by hand, get the archive for your machine from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), unpack it, and put `openspec` on your PATH. On macOS, also run `xattr -d com.apple.quarantine openspec`. +```bash +curl -fsSL https://openspec.dev/cli/install.sh | OPENSPEC_VERSION=v1.15.0 sh +``` + +- `OPENSPEC_VERSION=v1.15.0` installs that version. +- `OPENSPEC_INSTALL_DIR=~/bin` installs to that folder (default: `~/.local/bin`). + +On Windows, set it first, for example `$env:OPENSPEC_VERSION = 'v1.15.0'`, then run the install command. + +On Alpine Linux, run `apk add libstdc++ libgcc` first. + +### Download by hand + +Download your file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), unzip it, and move `openspec` to a folder on your PATH. On macOS, then run `xattr -d com.apple.quarantine openspec`. -| Platform | File | +| Computer | File | |---|---| -| macOS (Apple Silicon / Intel) | `openspec-darwin-arm64.tar.gz` / `openspec-darwin-x64.tar.gz` | -| Linux (arm64 / x64) | `openspec-linux-arm64.tar.gz` / `openspec-linux-x64.tar.gz` | -| Alpine (arm64 / x64) | `openspec-linux-arm64-musl.tar.gz` / `openspec-linux-x64-musl.tar.gz` | -| Windows (arm64 / x64) | `openspec-windows-arm64.zip` / `openspec-windows-x64.zip` | +| Mac with Apple chip / Intel | `openspec-darwin-arm64.tar.gz` / `openspec-darwin-x64.tar.gz` | +| Linux arm64 / x64 | `openspec-linux-arm64.tar.gz` / `openspec-linux-x64.tar.gz` | +| Alpine arm64 / x64 | `openspec-linux-arm64-musl.tar.gz` / `openspec-linux-x64-musl.tar.gz` | +| Windows arm64 / x64 | `openspec-windows-arm64.zip` / `openspec-windows-x64.zip` | ## Switch from npm to the standalone install From ed7a70b527c63cf6c7b85808e0b2360233445837 Mon Sep 17 00:00:00 2001 From: Clay Good Date: Tue, 27 Oct 2026 17:34:31 -0500 Subject: [PATCH 4/6] docs(install): keep install docs changes to docs-lab Revert the docs/ edits; docs-lab is where install docs live now. Rewrite the docs-lab install options to match the docs-lab style guide. Co-Authored-By: Claude Opus 5.5 --- docs-lab/start/installation.md | 42 +++++++++++++++++++--------- docs/README.md | 2 +- docs/getting-started.md | 2 +- docs/installation.md | 51 +++++++++++++--------------------- 4 files changed, 50 insertions(+), 47 deletions(-) diff --git a/docs-lab/start/installation.md b/docs-lab/start/installation.md index 5419e87ece..45c4333b71 100644 --- a/docs-lab/start/installation.md +++ b/docs-lab/start/installation.md @@ -5,7 +5,7 @@ ## Install -On macOS or Linux: +On macOS or Linux, in your terminal: ```bash curl -fsSL https://openspec.dev/cli/install.sh | sh @@ -17,7 +17,7 @@ On Windows, in PowerShell: irm https://openspec.dev/cli/install.ps1 | iex ``` -Then [check it worked](#check-it-worked). +If the installer says its folder isn't on your PATH, add it with the line it prints. Then [check it worked](#check-it-worked). ## Install with your AI assistant @@ -131,36 +131,52 @@ Next, [set up your project](setup.md). If your assistant already ran init, that ## Install options -To pick a version or folder, add a setting before `sh`: +To pick a version or a folder, add a setting before `sh`: ```bash curl -fsSL https://openspec.dev/cli/install.sh | OPENSPEC_VERSION=v1.15.0 sh ``` -- `OPENSPEC_VERSION=v1.15.0` installs that version. -- `OPENSPEC_INSTALL_DIR=~/bin` installs to that folder (default: `~/.local/bin`). +- **`OPENSPEC_VERSION`**: the release to install, such as `v1.15.0`. The default is the newest release. +- **`OPENSPEC_INSTALL_DIR`**: the folder to install to. The default is `~/.local/bin` (Windows: `%LOCALAPPDATA%\Programs\openspec`). -On Windows, set it first, for example `$env:OPENSPEC_VERSION = 'v1.15.0'`, then run the install command. +On Windows, set it in PowerShell before the install command: -On Alpine Linux, run `apk add libstdc++ libgcc` first. +```powershell +$env:OPENSPEC_VERSION = 'v1.15.0' +irm https://openspec.dev/cli/install.ps1 | iex +``` + +On Alpine Linux, run `apk add libstdc++ libgcc` before installing. ### Download by hand -Download your file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), unzip it, and move `openspec` to a folder on your PATH. On macOS, then run `xattr -d com.apple.quarantine openspec`. +1. **Download** your file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest). The table below lists them. +2. **Unpack** it. In your terminal: `tar -xzf openspec-darwin-arm64.tar.gz`. On Windows, right-click the `.zip` and choose Extract All. +3. **Move** `openspec` (Windows: `openspec.exe`) into a folder on your PATH, such as `~/.local/bin`. +4. **On macOS**, run `xattr -d com.apple.quarantine openspec`. macOS blocks files downloaded in a browser until you do. | Computer | File | |---|---| -| Mac with Apple chip / Intel | `openspec-darwin-arm64.tar.gz` / `openspec-darwin-x64.tar.gz` | -| Linux arm64 / x64 | `openspec-linux-arm64.tar.gz` / `openspec-linux-x64.tar.gz` | -| Alpine arm64 / x64 | `openspec-linux-arm64-musl.tar.gz` / `openspec-linux-x64-musl.tar.gz` | -| Windows arm64 / x64 | `openspec-windows-arm64.zip` / `openspec-windows-x64.zip` | +| Mac, Apple silicon | `openspec-darwin-arm64.tar.gz` | +| Mac, Intel | `openspec-darwin-x64.tar.gz` | +| Linux, arm64 | `openspec-linux-arm64.tar.gz` | +| Linux, x64 | `openspec-linux-x64.tar.gz` | +| Alpine, arm64 | `openspec-linux-arm64-musl.tar.gz` | +| Alpine, x64 | `openspec-linux-x64-musl.tar.gz` | +| Windows, arm64 | `openspec-windows-arm64.zip` | +| Windows, x64 | `openspec-windows-x64.zip` | + +### Verify a download -To check a file is really ours, use the [GitHub CLI](https://cli.github.com): +To check that a file was built by the OpenSpec release workflow, run this with the [GitHub CLI](https://cli.github.com): ```bash gh attestation verify openspec-darwin-arm64.tar.gz --repo Fission-AI/OpenSpec ``` +It fails if the file wasn't built there. The install command already checks each download against the release's `SHA256SUMS`, so this step is optional. + ## Switch from npm to the standalone install Switching is optional; npm keeps working. Your settings and your projects carry over; only the program changes. diff --git a/docs/README.md b/docs/README.md index 42240619e0..8c5df9d12e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -99,7 +99,7 @@ That second one matters more than it looks. OpenSpec has two halves: a command l ## The thirty-second version ```text -1. Install curl -fsSL https://openspec.dev/cli/install.sh | sh +1. Install curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh 2. Initialize cd your-project && openspec init 3. Explore (in your AI chat) /opsx:explore ← optional, but a great habit 4. Propose (in your AI chat) /opsx:propose add-dark-mode diff --git a/docs/getting-started.md b/docs/getting-started.md index 0da2cd32b5..2112a65e4c 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -14,7 +14,7 @@ This guide explains how OpenSpec works after you've installed and initialized it The whole loop, with each step labeled by where it happens: ```text -TERMINAL $ curl -fsSL https://openspec.dev/cli/install.sh | sh +TERMINAL $ curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh TERMINAL $ cd your-project && openspec init AI CHAT /opsx:explore (optional: think it through first) AI CHAT /opsx:propose add-dark-mode (AI drafts the plan; you review it) diff --git a/docs/installation.md b/docs/installation.md index 1f8c6792fd..759d29414e 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -2,19 +2,32 @@ ## Install +OpenSpec is a single file. It needs no Node.js or anything else (on Alpine Linux, first run `apk add libstdc++ libgcc`). + macOS and Linux: ```bash -curl -fsSL https://openspec.dev/cli/install.sh | sh +curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh ``` Windows (PowerShell): ```powershell -irm https://openspec.dev/cli/install.ps1 | iex +irm https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.ps1 | iex ``` -Then [verify the installation](#verify-installation). +The installer picks the newest release whose files are all attached and the right file for your machine, checks it against the release's `SHA256SUMS`, and installs it to `~/.local/bin` (Windows: `%LOCALAPPDATA%\Programs\openspec`, added to your user `PATH`). Set `OPENSPEC_INSTALL_DIR` to choose another folder, or `OPENSPEC_VERSION=v1.15.0` to pin a release. Prefer npm or another package manager? See [Package Managers](#package-managers). + +To install by hand, download your platform's file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), rename it to `openspec` (`openspec.exe` on Windows), make it executable on macOS and Linux (`chmod +x openspec`), and put it on your `PATH`: + +| Platform | File | +|---|---| +| macOS 13+ (Apple Silicon / Intel) | `openspec-darwin-arm64` / `openspec-darwin-x64` | +| Linux (glibc 2.17+) | `openspec-linux-x64` / `openspec-linux-arm64` | +| Alpine 3.17+ (needs `apk add libstdc++ libgcc`) | `openspec-linux-x64-musl` / `openspec-linux-arm64-musl` | +| Windows 10+ | `openspec-windows-x64.exe` / `openspec-windows-arm64.exe` | + +On macOS, a file downloaded with a browser is blocked until you run `xattr -d com.apple.quarantine openspec`; the install script avoids this. On Windows, SmartScreen may warn the first time you run it from Explorer. ## Install with your AI assistant @@ -33,10 +46,10 @@ order, and stop where a step tells you to stop. skip to step 3. If I installed it with a package manager, mention once that `openspec install` switches to the standalone install, but only switch if I ask; never switch it to a different install method on your own. Otherwise install - the standalone OpenSpec binary. Show me the command + the standalone OpenSpec binary, which needs no Node.js. Show me the command for my OS and run it only once I confirm, then skip to step 3: - macOS / Linux: curl -fsSL https://openspec.dev/cli/install.sh | sh - Windows (PowerShell): irm https://openspec.dev/cli/install.ps1 | iex + macOS / Linux: curl -fsSL https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.sh | sh + Windows (PowerShell): irm https://raw.githubusercontent.com/Fission-AI/OpenSpec/main/scripts/binary/install.ps1 | iex If I'd rather use a package manager, or the installer fails, go to step 2. 2. PACKAGE MANAGER (only if step 1 did not install it). Run `node --version`: @@ -190,32 +203,6 @@ Or add to your development environment in `flake.nix`: openspec --version ``` -## Install options - -To pick a version or folder, add a setting before `sh`: - -```bash -curl -fsSL https://openspec.dev/cli/install.sh | OPENSPEC_VERSION=v1.15.0 sh -``` - -- `OPENSPEC_VERSION=v1.15.0` installs that version. -- `OPENSPEC_INSTALL_DIR=~/bin` installs to that folder (default: `~/.local/bin`). - -On Windows, set it first, for example `$env:OPENSPEC_VERSION = 'v1.15.0'`, then run the install command. - -On Alpine Linux, run `apk add libstdc++ libgcc` first. - -### Download by hand - -Download your file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest), unzip it, and move `openspec` to a folder on your PATH. On macOS, then run `xattr -d com.apple.quarantine openspec`. - -| Computer | File | -|---|---| -| Mac with Apple chip / Intel | `openspec-darwin-arm64.tar.gz` / `openspec-darwin-x64.tar.gz` | -| Linux arm64 / x64 | `openspec-linux-arm64.tar.gz` / `openspec-linux-x64.tar.gz` | -| Alpine arm64 / x64 | `openspec-linux-arm64-musl.tar.gz` / `openspec-linux-x64-musl.tar.gz` | -| Windows arm64 / x64 | `openspec-windows-arm64.zip` / `openspec-windows-x64.zip` | - ## Switch from npm to the standalone install Your settings and projects carry over; only the program changes. From b909e2998d527bb91732ab0d77482bc2d945988b Mon Sep 17 00:00:00 2001 From: Clay Good Date: Thu, 29 Oct 2026 11:29:03 -0500 Subject: [PATCH 5/6] docs(install): tighten install wording Co-Authored-By: Claude Opus 5.5 --- .changeset/install-archives.md | 2 +- README.md | 4 ++-- docs-lab/start/installation.md | 18 ++++++++++-------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.changeset/install-archives.md b/.changeset/install-archives.md index 6a4d5ce18e..6225edb521 100644 --- a/.changeset/install-archives.md +++ b/.changeset/install-archives.md @@ -2,4 +2,4 @@ "@fission-ai/openspec": patch --- -Simpler install: `curl -fsSL https://openspec.dev/cli/install.sh | sh` (Windows: `irm https://openspec.dev/cli/install.ps1 | iex`). Release downloads are now archives: `.tar.gz`, or `.zip` on Windows. +Install from openspec.dev: `curl -fsSL https://openspec.dev/cli/install.sh | sh` (Windows: `irm https://openspec.dev/cli/install.ps1 | iex`). Release files are now `.tar.gz` archives (`.zip` on Windows). diff --git a/README.md b/README.md index cdb2f07313..22279aca46 100644 --- a/README.md +++ b/README.md @@ -117,13 +117,13 @@ Solo, OpenSpec keeps you and your AI honest on a single repo. On a team, the har ## Quick Start -Install OpenSpec on macOS or Linux: +Install OpenSpec. On macOS or Linux, in your terminal: ```bash curl -fsSL https://openspec.dev/cli/install.sh | sh ``` -Windows (PowerShell): +On Windows, in PowerShell: ```powershell irm https://openspec.dev/cli/install.ps1 | iex diff --git a/docs-lab/start/installation.md b/docs-lab/start/installation.md index 45c4333b71..178b33a1b7 100644 --- a/docs-lab/start/installation.md +++ b/docs-lab/start/installation.md @@ -17,7 +17,7 @@ On Windows, in PowerShell: irm https://openspec.dev/cli/install.ps1 | iex ``` -If the installer says its folder isn't on your PATH, add it with the line it prints. Then [check it worked](#check-it-worked). +If the installer prints an `export PATH=...` line, run it. Then [check it worked](#check-it-worked). ## Install with your AI assistant @@ -131,7 +131,7 @@ Next, [set up your project](setup.md). If your assistant already ran init, that ## Install options -To pick a version or a folder, add a setting before `sh`: +To pick a version or a folder, set a variable before `sh`: ```bash curl -fsSL https://openspec.dev/cli/install.sh | OPENSPEC_VERSION=v1.15.0 sh @@ -140,7 +140,7 @@ curl -fsSL https://openspec.dev/cli/install.sh | OPENSPEC_VERSION=v1.15.0 sh - **`OPENSPEC_VERSION`**: the release to install, such as `v1.15.0`. The default is the newest release. - **`OPENSPEC_INSTALL_DIR`**: the folder to install to. The default is `~/.local/bin` (Windows: `%LOCALAPPDATA%\Programs\openspec`). -On Windows, set it in PowerShell before the install command: +On Windows, set the variable first: ```powershell $env:OPENSPEC_VERSION = 'v1.15.0' @@ -151,10 +151,7 @@ On Alpine Linux, run `apk add libstdc++ libgcc` before installing. ### Download by hand -1. **Download** your file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest). The table below lists them. -2. **Unpack** it. In your terminal: `tar -xzf openspec-darwin-arm64.tar.gz`. On Windows, right-click the `.zip` and choose Extract All. -3. **Move** `openspec` (Windows: `openspec.exe`) into a folder on your PATH, such as `~/.local/bin`. -4. **On macOS**, run `xattr -d com.apple.quarantine openspec`. macOS blocks files downloaded in a browser until you do. +Each release has one file per computer: | Computer | File | |---|---| @@ -167,6 +164,11 @@ On Alpine Linux, run `apk add libstdc++ libgcc` before installing. | Windows, arm64 | `openspec-windows-arm64.zip` | | Windows, x64 | `openspec-windows-x64.zip` | +1. **Download** your file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest). +2. **Unpack** it. In your terminal: `tar -xzf openspec-darwin-arm64.tar.gz`. On Windows, right-click the `.zip` and choose Extract All. +3. **Move** `openspec` (Windows: `openspec.exe`) into a folder on your PATH, such as `~/.local/bin`. +4. **On macOS**, run `xattr -d com.apple.quarantine openspec`. macOS blocks files downloaded in a browser until you do. + ### Verify a download To check that a file was built by the OpenSpec release workflow, run this with the [GitHub CLI](https://cli.github.com): @@ -175,7 +177,7 @@ To check that a file was built by the OpenSpec release workflow, run this with t gh attestation verify openspec-darwin-arm64.tar.gz --repo Fission-AI/OpenSpec ``` -It fails if the file wasn't built there. The install command already checks each download against the release's `SHA256SUMS`, so this step is optional. +It fails if the workflow didn't build the file. The install command already checks each download against the release's `SHA256SUMS`, so this step is optional. ## Switch from npm to the standalone install From 36e1f2e678210cd4a091d32212fcd6026acf5be5 Mon Sep 17 00:00:00 2001 From: Clay Good Date: Thu, 29 Oct 2026 14:22:11 -0500 Subject: [PATCH 6/6] docs(install): fix the manual download steps Step 4 ran `xattr` on `openspec` in the current folder after step 3 had already moved the file away, so it cleared nothing. Clear the quarantine flag before moving. Give Windows its own destination example, since `~/.local/bin` is a POSIX path. Say that files land a few minutes after a release is published, so a missing file means wait or use the previous release. Co-Authored-By: Claude Opus 5.5 --- docs-lab/start/installation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs-lab/start/installation.md b/docs-lab/start/installation.md index 178b33a1b7..b367cdf169 100644 --- a/docs-lab/start/installation.md +++ b/docs-lab/start/installation.md @@ -164,10 +164,10 @@ Each release has one file per computer: | Windows, arm64 | `openspec-windows-arm64.zip` | | Windows, x64 | `openspec-windows-x64.zip` | -1. **Download** your file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest). +1. **Download** your file from the [latest release](https://github.com/Fission-AI/OpenSpec/releases/latest). Files are attached a few minutes after a release is published. If yours isn't listed yet, wait and reload, or take it from the previous release. 2. **Unpack** it. In your terminal: `tar -xzf openspec-darwin-arm64.tar.gz`. On Windows, right-click the `.zip` and choose Extract All. -3. **Move** `openspec` (Windows: `openspec.exe`) into a folder on your PATH, such as `~/.local/bin`. -4. **On macOS**, run `xattr -d com.apple.quarantine openspec`. macOS blocks files downloaded in a browser until you do. +3. **On macOS**, run `xattr -d com.apple.quarantine openspec` in the folder you unpacked to. macOS blocks files downloaded in a browser until you do. +4. **Move** `openspec` into a folder on your PATH, such as `~/.local/bin`. On Windows, move `openspec.exe` into a folder on your user PATH, such as `%LOCALAPPDATA%\Programs\openspec`. ### Verify a download