mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-06 08:35:21 +08:00
Merge upstream/main at 2469ecc3 into integrate-upstream-split-search-tools while retaining branch-specific incremental indexing, MCP API consolidation, and graph extraction behavior.
The staged tree adds upstream's Mojo and Perl grammar support, issue reproduction suites, Graph UI changes, Windows smoke coverage, TOON graph output, subprocess supervision, and Laravel facade route handling. Conflict resolutions in src/pipeline/httplink.c and pass_httplinks.c retain dynamic growth and IMPORTS edge identity; scripts/smoke-test.sh and scripts/soak-test.sh retain hermetic cache isolation.
Validation against the merge plus the follow-up working-tree reconciliation: ASan/UBSan MCP suite 216/216 passed. Follow-up semantic and concurrency fixes remain intentionally unstaged for the next focused commit.
197 lines
6.9 KiB
PowerShell
197 lines
6.9 KiB
PowerShell
# install.ps1 — One-line installer for codebase-memory-mcp (Windows).
|
|
#
|
|
# Usage: see README.md for install instructions.
|
|
#
|
|
# Environment:
|
|
# CBM_DOWNLOAD_URL Override base URL for downloads (for testing)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# Enforce TLS 1.2+ (older PowerShell defaults to TLS 1.0 which GitHub rejects)
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
|
|
|
|
$Repo = "DeusData/codebase-memory-mcp"
|
|
$InstallDir = "$env:LOCALAPPDATA\Programs\codebase-memory-mcp"
|
|
$BinName = "codebase-memory-mcp.exe"
|
|
$BaseUrl = if ($env:CBM_DOWNLOAD_URL) { $env:CBM_DOWNLOAD_URL } else { "https://github.com/$Repo/releases/latest/download" }
|
|
|
|
# Security: reject non-HTTPS download URLs (defense-in-depth)
|
|
if (-not $BaseUrl.StartsWith("https://") -and -not $BaseUrl.StartsWith("http://localhost") -and -not $BaseUrl.StartsWith("http://127.0.0.1")) {
|
|
Write-Host "error: refusing non-HTTPS download URL: $BaseUrl" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
# Detect variant from args (--ui or --standard)
|
|
$Variant = "standard"
|
|
$SkipConfig = $false
|
|
foreach ($arg in $args) {
|
|
if ($arg -eq "--ui") { $Variant = "ui" }
|
|
if ($arg -eq "--standard") { $Variant = "standard" }
|
|
if ($arg -eq "--skip-config") { $SkipConfig = $true }
|
|
if ($arg -like "--dir=*") { $InstallDir = $arg.Substring(6) }
|
|
}
|
|
|
|
# Detect the OS architecture. RuntimeInformation.OSArchitecture reports the real
|
|
# OS arch (Arm64) even from an x64 process running under emulation on ARM64 --
|
|
# unlike $env:PROCESSOR_ARCHITECTURE, which reports the emulated "AMD64", and
|
|
# PROCESSOR_ARCHITEW6432, which is unset for 64-bit emulated processes. Fall back
|
|
# to the env vars only if the .NET API is somehow unavailable.
|
|
if ($env:CBM_ARCH) {
|
|
# Explicit override wins — used by CI/tests, and an escape hatch under x64
|
|
# emulation on ARM64 where no in-process detection is reliable.
|
|
$Arch = $env:CBM_ARCH
|
|
} else {
|
|
try {
|
|
$osArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
|
|
$Arch = if ($osArch -eq 'Arm64') { "arm64" } else { "amd64" }
|
|
} catch {
|
|
if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64" -or $env:PROCESSOR_ARCHITEW6432 -eq "ARM64") {
|
|
$Arch = "arm64"
|
|
} else {
|
|
$Arch = "amd64"
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-Host "codebase-memory-mcp installer (Windows)"
|
|
Write-Host " variant: $Variant"
|
|
Write-Host " arch: $Arch"
|
|
Write-Host " target: $InstallDir\$BinName"
|
|
Write-Host ""
|
|
|
|
# Build download URL
|
|
if ($Variant -eq "ui") {
|
|
$Archive = "codebase-memory-mcp-ui-windows-$Arch.zip"
|
|
} else {
|
|
$Archive = "codebase-memory-mcp-windows-$Arch.zip"
|
|
}
|
|
$Url = "$BaseUrl/$Archive"
|
|
|
|
# Download
|
|
$TmpDir = Join-Path ([System.IO.Path]::GetTempPath()) "cbm-install-$(Get-Random)"
|
|
New-Item -ItemType Directory -Path $TmpDir -Force | Out-Null
|
|
try {
|
|
|
|
Write-Host "Downloading $Archive..."
|
|
try {
|
|
Invoke-WebRequest -Uri $Url -OutFile "$TmpDir\$Archive" -UseBasicParsing
|
|
} catch {
|
|
Write-Host "error: download failed: $_" -ForegroundColor Red
|
|
Remove-Item -Recurse -Force $TmpDir -ErrorAction SilentlyContinue
|
|
exit 1
|
|
}
|
|
|
|
|
|
# Checksum verification
|
|
$ChecksumUrl = "$BaseUrl/checksums.txt"
|
|
try {
|
|
Invoke-WebRequest -Uri $ChecksumUrl -OutFile "$TmpDir\checksums.txt" -UseBasicParsing
|
|
$checksumLine = Get-Content "$TmpDir\checksums.txt" | Where-Object { $_ -like "*$Archive*" }
|
|
if ($checksumLine) {
|
|
$expected = ($checksumLine -split '\s+')[0]
|
|
$actual = (Get-FileHash -Path "$TmpDir\$Archive" -Algorithm SHA256).Hash.ToLower()
|
|
if ($expected -ne $actual) {
|
|
Write-Host "error: CHECKSUM MISMATCH!" -ForegroundColor Red
|
|
Write-Host " expected: $expected"
|
|
Write-Host " actual: $actual"
|
|
Remove-Item -Recurse -Force $TmpDir
|
|
exit 1
|
|
}
|
|
Write-Host "Checksum verified."
|
|
}
|
|
} catch {
|
|
Write-Host "warning: could not verify checksum (non-fatal)"
|
|
}
|
|
|
|
# Extract
|
|
Write-Host "Extracting..."
|
|
Expand-Archive -Path "$TmpDir\$Archive" -DestinationPath $TmpDir -Force
|
|
|
|
$DlBin = Join-Path $TmpDir $BinName
|
|
if (-not (Test-Path $DlBin)) {
|
|
# UI variant may have different name in zip
|
|
$UiBin = Join-Path $TmpDir "codebase-memory-mcp-ui.exe"
|
|
if (Test-Path $UiBin) {
|
|
Rename-Item $UiBin $BinName
|
|
$DlBin = Join-Path $TmpDir $BinName
|
|
} else {
|
|
Write-Host "error: binary not found after extraction" -ForegroundColor Red
|
|
Remove-Item -Recurse -Force $TmpDir
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Install
|
|
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
|
|
$Dest = Join-Path $InstallDir $BinName
|
|
|
|
# Handle replace-if-running (rename-aside)
|
|
$OldDest = $null
|
|
if (Test-Path $Dest) {
|
|
$OldCandidate = "$Dest.old"
|
|
Remove-Item $OldCandidate -Force -ErrorAction SilentlyContinue
|
|
try {
|
|
Rename-Item $Dest $OldCandidate -ErrorAction Stop
|
|
$OldDest = $OldCandidate
|
|
} catch {
|
|
Write-Host "error: could not preserve existing binary for rollback: $_" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Copy and verify before discarding the rollback candidate. Native executable
|
|
# failures do not throw automatically in Windows PowerShell, so check the exit
|
|
# code explicitly and restore the prior binary on every failed replacement.
|
|
try {
|
|
Copy-Item $DlBin $Dest -Force
|
|
$ver = & $Dest --version 2>&1
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "installed binary exited with code $LASTEXITCODE"
|
|
}
|
|
Write-Host "Installed: $ver"
|
|
} catch {
|
|
Write-Host "error: installed binary failed to run: $_" -ForegroundColor Red
|
|
if ($OldDest -and (Test-Path $OldDest)) {
|
|
Remove-Item $Dest -Force -ErrorAction SilentlyContinue
|
|
Move-Item $OldDest $Dest -Force
|
|
Write-Host "Restored previous binary."
|
|
} elseif (Test-Path $Dest) {
|
|
Remove-Item $Dest -Force -ErrorAction SilentlyContinue
|
|
}
|
|
exit 1
|
|
}
|
|
if ($OldDest -and (Test-Path $OldDest)) {
|
|
Remove-Item $OldDest -Force
|
|
}
|
|
|
|
# Configure agents
|
|
if ($SkipConfig) {
|
|
Write-Host ""
|
|
Write-Host "Skipping agent configuration (--skip-config)"
|
|
} else {
|
|
Write-Host ""
|
|
Write-Host "Configuring coding agents..."
|
|
& $Dest install -y 2>&1 | Write-Host
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host ""
|
|
Write-Host "error: agent configuration failed (exit code $LASTEXITCODE)" -ForegroundColor Red
|
|
Write-Host "The binary was installed, but no coding agents were configured."
|
|
Write-Host "Run manually to configure: `"$Dest`" install"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Add to PATH (user scope, no admin needed)
|
|
$UserPath = [Environment]::GetEnvironmentVariable("PATH", "User")
|
|
if ($UserPath -notlike "*$InstallDir*") {
|
|
[Environment]::SetEnvironmentVariable("PATH", "$UserPath;$InstallDir", "User")
|
|
$env:PATH = "$env:PATH;$InstallDir"
|
|
Write-Host "Added $InstallDir to user PATH"
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Done! Restart your terminal and coding agent to start using codebase-memory-mcp."
|
|
} finally {
|
|
Remove-Item -Recurse -Force $TmpDir -ErrorAction SilentlyContinue
|
|
}
|