diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-08-18 22:39:38 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-08-18 22:39:38 +0300 |
| commit | 9fac51722653fa0b0b6a5786166fb18c763424e0 (patch) | |
| tree | a8efd3b30cf29a8fb11138b7444bb9baa0dac2fa /website | |
| parent | 0bd445020ea19e0cea13f42a28212db7b2df196d (diff) | |
feat: make Windows generally available
Diffstat (limited to 'website')
| -rw-r--r-- | website/agent-guide.md | 4 | ||||
| -rw-r--r-- | website/astro.config.mjs | 2 | ||||
| -rw-r--r-- | website/index.html | 6 | ||||
| -rw-r--r-- | website/install.ps1 | 100 |
4 files changed, 82 insertions, 30 deletions
diff --git a/website/agent-guide.md b/website/agent-guide.md index 7e20c751..71392817 100644 --- a/website/agent-guide.md +++ b/website/agent-guide.md @@ -32,14 +32,14 @@ curl -fsSL https://herdr.dev/install.sh | sh herdr ``` -Windows preview beta: +Windows: ```powershell powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex" herdr ``` -Homebrew, mise, and Nix installs, verification, and manual downloads: https://herdr.dev/docs/install/. Direct installs update with `herdr update`; package-manager installs update through that package manager. Check the version with `herdr --version`. +Homebrew, mise, and Nix installs, verification, and manual downloads: https://herdr.dev/docs/install/. Direct installs use the stable channel by default and update with `herdr update`; preview is opt-in. Package-manager installs update through that package manager. Check the version with `herdr --version`. ## First-run walkthrough diff --git a/website/astro.config.mjs b/website/astro.config.mjs index 84992ed2..8afbf46f 100644 --- a/website/astro.config.mjs +++ b/website/astro.config.mjs @@ -225,7 +225,7 @@ export default defineConfig({ { label: 'Socket API', translations: { ja: 'ソケット API', 'zh-CN': 'Socket API' }, slug: 'docs/socket-api' }, { label: 'Integrations', translations: { ja: 'インテグレーション', 'zh-CN': '集成' }, slug: 'docs/integrations' }, { label: 'Agent skill file', translations: { ja: 'エージェントスキルファイル', 'zh-CN': '智能体技能文件' }, slug: 'docs/agent-skill' }, - { label: 'Windows beta', translations: { ja: 'Windows ベータ', 'zh-CN': 'Windows 测试版' }, slug: 'docs/windows-beta' }, + { label: 'Windows support', translations: { ja: 'Windows サポート', 'zh-CN': 'Windows 支持' }, slug: 'docs/windows-beta' }, ], }, { diff --git a/website/index.html b/website/index.html index b241c1b7..06750444 100644 --- a/website/index.html +++ b/website/index.html @@ -146,7 +146,7 @@ <button type="button" id="copy-btn" aria-label="Copy install command">copy</button> </div> </div> - <div class="meta">macOS · Linux · Windows beta · Apache 2.0 — <a href="/docs/install/">windows, homebrew, nix and manual install →</a></div> + <div class="meta">macOS · Linux · Windows · Apache 2.0 — <a href="/docs/install/">windows, homebrew, nix and manual install →</a></div> <div class="meta yc-meta"><a class="yc" href="/blog/herdr-is-joining-y-combinator/">backed by <img src="/assets/yc-logo.svg" alt="Y" width="13" height="13" /> Combinator</a></div> </div> </header> @@ -434,7 +434,7 @@ <div class="n"><span>04</span></div> <div class="cap-in"> <h3>Runs what you already run. <b class="arw">→</b></h3> - <p>Claude Code, Codex, Cursor, opencode, Grok and the rest. Herdr doesn't wrap them or replace them, it just owns their terminals — one binary, macOS and Linux, Windows in beta.</p> + <p>Claude Code, Codex, Cursor, opencode, Grok and the rest. Herdr doesn't wrap them or replace them, it just owns their terminals — one binary for macOS, Linux, and Windows.</p> </div> <div class="ev"> <div class="herd"> @@ -475,7 +475,7 @@ <button type="button" id="copy-btn-2" aria-label="Copy install command">copy</button> </div> </div> - <div class="meta">Windows beta: <code>irm https://herdr.dev/install.ps1 | iex</code> — <a href="/docs/">all install methods →</a></div> + <div class="meta">Windows: <code>irm https://herdr.dev/install.ps1 | iex</code> — <a href="/docs/">all install methods →</a></div> </div> </section> diff --git a/website/install.ps1 b/website/install.ps1 index cef4af04..9dacfaa9 100644 --- a/website/install.ps1 +++ b/website/install.ps1 @@ -15,12 +15,9 @@ Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" $ProgressPreference = "SilentlyContinue" -if ([string]::IsNullOrWhiteSpace($Channel)) { - $Channel = "preview" -} - -if ($Channel -notin @("stable", "preview")) { - Write-Error "Invalid Herdr channel '$Channel'. Use 'preview'." +$channelWasExplicit = -not [string]::IsNullOrWhiteSpace($Channel) +if ($channelWasExplicit -and $Channel -notin @("stable", "preview")) { + Write-Error "Invalid Herdr channel '$Channel'. Use 'stable' or 'preview'." exit 1 } @@ -406,6 +403,33 @@ function Move-DirectoryWithRetry { } } +function Remove-DirectoryWithRetry { + param( + [string]$Path, + [int]$TimeoutMilliseconds = 5000 + ) + + $fullPath = [System.IO.Path]::GetFullPath($Path) + $extendedPath = if ($fullPath.StartsWith("\\")) { + "\\?\UNC\" + $fullPath.TrimStart([char]'\') + } else { + "\\?\" + $fullPath + } + $deadline = [DateTime]::UtcNow.AddMilliseconds($TimeoutMilliseconds) + while (Test-Path -LiteralPath $Path) { + try { + [System.IO.Directory]::Delete($extendedPath, $true) + return + } catch { + if ([DateTime]::UtcNow -ge $deadline) { + Write-WarningStep "Herdr installed successfully but could not remove a temporary release backup at $Path." + return + } + Start-Sleep -Milliseconds 100 + } + } +} + function Invoke-WithInstallLock { param( [string]$LockPath, @@ -579,11 +603,6 @@ if (-not [Environment]::Is64BitOperatingSystem) { exit 1 } -if ($Channel -eq "stable") { - Write-Error "Windows builds are preview-only for now. Omit -Channel or use -Channel preview." - exit 1 -} - $architecture = [System.Runtime.InteropServices.RuntimeInformation,mscorlib]::OSArchitecture.ToString() switch ($architecture) { "X64" { @@ -601,14 +620,6 @@ switch ($architecture) { } } -if (-not $useLocalPackage -and [string]::IsNullOrWhiteSpace($ManifestUrl)) { - $ManifestUrl = if ($Channel -eq "preview") { - "https://herdr.dev/preview.json" - } else { - "https://herdr.dev/latest.json" - } -} - $herdrHome = if ([string]::IsNullOrWhiteSpace($env:HERDR_HOME)) { Join-Path $env:USERPROFILE ".herdr" } else { @@ -649,13 +660,57 @@ if ($useLocalPackage) { Format = $LocalPackageFormat } } else { + if (-not $channelWasExplicit) { + if (-not [string]::IsNullOrWhiteSpace($existingHerdr)) { + $detectedChannel = [string](& $existingHerdr channel show 2>$null | Select-Object -Last 1) + $detectedChannel = $detectedChannel.Trim() + if ($LASTEXITCODE -ne 0 -or $detectedChannel -notin @("stable", "preview")) { + throw "Could not determine the existing Herdr update channel. Rerun with -Channel stable or -Channel preview." + } + $Channel = $detectedChannel + Write-Step "Preserving existing Herdr $Channel channel" + } elseif (-not [string]::IsNullOrWhiteSpace($ManifestUrl) -and $ManifestUrl -match "/preview\.json$") { + $Channel = "preview" + } else { + $Channel = "stable" + } + } + + if ([string]::IsNullOrWhiteSpace($ManifestUrl)) { + $ManifestUrl = if ($Channel -eq "preview") { + "https://herdr.dev/preview.json" + } else { + "https://herdr.dev/latest.json" + } + } + Write-Step "Fetching Herdr $Channel manifest" $manifest = ConvertTo-ManifestObject -Manifest (Invoke-RestMethod -Uri $ManifestUrl) + $manifestChannelProperty = $manifest.PSObject.Properties["channel"] + if (-not $channelWasExplicit -and $null -ne $manifestChannelProperty -and [string]$manifestChannelProperty.Value -eq "preview") { + $Channel = "preview" + } + $assetsProperty = $manifest.PSObject.Properties["assets"] + $assetProperty = if ($null -eq $assetsProperty) { + $null + } else { + $assetsProperty.Value.PSObject.Properties[$target] + } + if ($null -eq $assetProperty -and + -not $channelWasExplicit -and + $Channel -eq "stable" -and + $ManifestUrl -match "/latest\.json$") { + Write-WarningStep "The stable manifest does not include Windows yet; using preview during the stable-channel rollout." + $Channel = "preview" + $ManifestUrl = $ManifestUrl.Substring(0, $ManifestUrl.Length - "latest.json".Length) + "preview.json" + Write-Step "Fetching Herdr preview manifest" + $manifest = ConvertTo-ManifestObject -Manifest (Invoke-RestMethod -Uri $ManifestUrl) + } + $asset = Get-ManifestAsset -Manifest $manifest -Target $target if (-not [string]::IsNullOrWhiteSpace($ExpectedBuildId) -and [string]$manifest.build_id -ne $ExpectedBuildId) { throw "Preview manifest changed while updating. Expected build $ExpectedBuildId but found $($manifest.build_id). Run herdr update again." } $versionIdentity = Resolve-HerdrVersion -Manifest $manifest -SelectedChannel $Channel - $asset = Get-ManifestAsset -Manifest $manifest -Target $target } $safeVersionIdentity = $versionIdentity -replace '[^0-9A-Za-z._-]', '-' $releaseName = "$safeVersionIdentity-$targetTriple" @@ -710,9 +765,6 @@ try { Write-WarningStep "Windows could not activate the downloaded release. Another process may have a package file open, such as antivirus or indexing. No incomplete release was activated. Run herdr update again." throw } - if ($null -ne $backupDir) { - Remove-Item -LiteralPath $backupDir -Recurse -Force -ErrorAction SilentlyContinue - } } $releaseHerdr = Join-Path $releaseDir "herdr.exe" @@ -721,7 +773,7 @@ try { throw "Installed Herdr command failed verification: $releaseHerdr --version" } Get-ChildItem -LiteralPath $releasesDir -Force -Directory -Filter ".backup.$releaseName.*" -ErrorAction SilentlyContinue | - Remove-Item -Recurse -Force -ErrorAction SilentlyContinue + ForEach-Object { Remove-DirectoryWithRetry -Path $_.FullName } Set-ManagedJunction -LinkPath $currentDir -TargetPath $releaseDir -ManagedTargetPrefix $releasesDir Set-ManagedJunction -LinkPath $visibleBinDir -TargetPath $releaseDir -ManagedTargetPrefix $standaloneRoot -AllowLegacyHerdrBinMigration $allowLegacyVisibleBinMigration |
