mermaid-cli 0.14.2

Open-source AI pair programmer with agentic capabilities. Local-first with Ollama, native tool calling, and beautiful TUI.
Documentation
<#
.SYNOPSIS
  Mermaid installer (Windows). Downloads the latest (or a pinned) release for
  this machine from GitHub Releases, verifies it against SHA256SUMS, and
  installs mermaid.exe + mermaidd.exe, adding the install dir to your user
  PATH. No Rust or cargo required.

    irm https://noahsabaj.github.io/mermaid-cli/install.ps1 | iex

.NOTES
  Environment overrides:
    $env:MERMAID_VERSION      = 'v0.11.0'   # install a specific tag (default: latest)
    $env:MERMAID_INSTALL_DIR  = 'C:\path'   # install location (default: %LOCALAPPDATA%\Programs\mermaid)
    $env:MERMAID_NO_MODIFY_PATH = '1'       # skip adding the dir to PATH
#>
$ErrorActionPreference = 'Stop'
$repo = 'noahsabaj/mermaid-cli'

$arch = $env:PROCESSOR_ARCHITECTURE
if ($arch -ne 'AMD64') {
    throw "Mermaid currently ships only x86_64 Windows builds (this machine is $arch). Build from source with cargo instead."
}
$asset = 'mermaid-windows-x86_64.zip'

if ($env:MERMAID_VERSION) {
    $base = "https://github.com/$repo/releases/download/$($env:MERMAID_VERSION)"
} else {
    $base = "https://github.com/$repo/releases/latest/download"
}

$dir = if ($env:MERMAID_INSTALL_DIR) { $env:MERMAID_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA 'Programs\mermaid' }
$tmp = Join-Path ([System.IO.Path]::GetTempPath()) ("mermaid-" + [guid]::NewGuid().ToString('N'))
New-Item -ItemType Directory -Force -Path $tmp | Out-Null

try {
    Write-Host "Downloading $asset..."
    $zip = Join-Path $tmp $asset
    $sums = Join-Path $tmp 'SHA256SUMS'
    Invoke-WebRequest -Uri "$base/$asset" -OutFile $zip -UseBasicParsing
    Invoke-WebRequest -Uri "$base/SHA256SUMS" -OutFile $sums -UseBasicParsing

    # Verify against SHA256SUMS ("<hash>  <filename>").
    $line = (Select-String -Path $sums -Pattern ("\s" + [regex]::Escape($asset) + "$") | Select-Object -First 1).Line
    if (-not $line) { throw "no checksum listed for $asset" }
    $want = ($line.Trim() -split '\s+')[0]
    $got = (Get-FileHash -Algorithm SHA256 -Path $zip).Hash
    if ($want.ToLower() -ne $got.ToLower()) {
        throw "checksum mismatch for ${asset}: expected $want, got $got"
    }
    Write-Host "Checksum verified."

    # Extract.
    $extract = Join-Path $tmp 'x'
    Expand-Archive -Path $zip -DestinationPath $extract -Force
    New-Item -ItemType Directory -Force -Path $dir | Out-Null

    foreach ($bin in @('mermaid.exe', 'mermaidd.exe')) {
        $src = Join-Path $extract $bin
        if (-not (Test-Path $src)) { throw "archive is missing $bin" }
        $dest = Join-Path $dir $bin
        # Windows won't overwrite a running .exe, but it WILL let you rename one.
        # Move the current binary aside (so an in-place `mermaid update` works),
        # then drop the new one in.
        if (Test-Path $dest) {
            $old = "$dest.old"
            Remove-Item -Force $old -ErrorAction SilentlyContinue
            try { Move-Item -Force $dest $old } catch {}
        }
        Copy-Item -Force $src $dest
    }
    # Best-effort cleanup of binaries renamed aside on a previous update.
    Get-ChildItem -Path $dir -Filter '*.exe.old' -ErrorAction SilentlyContinue |
        ForEach-Object { Remove-Item -Force $_.FullName -ErrorAction SilentlyContinue }

    Write-Host "Installed mermaid + mermaidd to $dir"

    if (-not $env:MERMAID_NO_MODIFY_PATH) {
        # Prepend our dir to the *user* PATH so this install wins over any older
        # mermaid earlier on PATH (e.g. a stale `cargo install` in ~\.cargo\bin).
        # Drop any existing entry for our dir first to keep it at the front and
        # avoid duplicates.
        $userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
        $parts = @()
        if (-not [string]::IsNullOrEmpty($userPath)) {
            $parts = @($userPath -split ';' | Where-Object { $_ -and $_ -ne $dir })
        }
        [Environment]::SetEnvironmentVariable('Path', ((@($dir) + $parts) -join ';'), 'User')
        # Take effect in the current session too, at the front.
        $env:Path = "$dir;" + (($env:Path -split ';' | Where-Object { $_ -and $_ -ne $dir }) -join ';')
        Write-Host "Added $dir to the front of your user PATH."
    }

    # Warn if another mermaid elsewhere on PATH could shadow this install.
    $others = @(Get-Command mermaid.exe -All -ErrorAction SilentlyContinue |
        Where-Object { $_.Source -and (Split-Path $_.Source) -ne $dir })
    if ($others.Count -gt 0) {
        Write-Host ""
        Write-Host "Note: another 'mermaid' is also on your PATH and may shadow this one:"
        $others | ForEach-Object { Write-Host "  $($_.Source)" }
        Write-Host "If 'mermaid' keeps running an old version, remove that copy (e.g. 'cargo uninstall mermaid-cli')."
    }

    try { & (Join-Path $dir 'mermaid.exe') --version } catch {}
    Write-Host ""
    Write-Host "Done. Run 'mermaid' to start, or 'mermaid update' to upgrade later."
}
finally {
    Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
}