Introduce the pm store: a unified, hash-verified package store that
replaces lazy_deps and the old installer's ad-hoc tool downloads.
Store tools are provisioned on PATH (ffmpeg, node/npm via pinned uv),
with a resumable 8-way downloader, verify() returning failure reasons,
and adopt() made EPERM-safe. chromium ships in the payload for every
target. The 3600-line install.sh is replaced by a staged bootstrapper
(heavy deps are pm's job after this); setup-hermes.sh, Dockerfile and
nix pin tables are rewired onto the store. Old install-script tests,
lazy_deps/managed_uv/build_info, and the ps1/bash installer test
batteries are removed with the machinery they tested.
Rebuilt from ethie/pm onto upstream/main (ac6c8028e0) after the
utf-8-sig sweep. 16 hot files (main also churned them) hand-merged:
platform adapters, main.py, electron/main.ts, tui_gateway/server.py,
cua_backend, installer-tests workflow, install.sh (full rewrite),
setup-hermes.sh, plugins doc.
76 lines
2.9 KiB
PowerShell
76 lines
2.9 KiB
PowerShell
# ============================================================================
|
|
# venv-style activation for the Hermes dev environment (pm-managed tools).
|
|
#
|
|
# .\activate.ps1 (repo root; if script execution is disabled:
|
|
# powershell -ExecutionPolicy Bypass -File .\activate.ps1, or set
|
|
# Set-ExecutionPolicy RemoteSigned -Scope CurrentUser once)
|
|
#
|
|
# Emits the composed pm env (PATH + tool vars) into the CURRENT session, with
|
|
# save/restore: `deactivate` undoes exactly what activation changed.
|
|
#
|
|
# Requires a completed .\setup-hermes.ps1 — it never invokes uv. It runs the
|
|
# pm store's pinned python (fallback: the repo venv) to emit the env JSON.
|
|
# ============================================================================
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# Guard against double-sourcing: re-activating deactivates first.
|
|
if (Test-Path function:deactivate) { deactivate }
|
|
|
|
$repo = $PSScriptRoot
|
|
$machineArch = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment').PROCESSOR_ARCHITECTURE
|
|
$arch = if ($machineArch -eq 'ARM64') { 'arm64' } else { 'x64' }
|
|
$target = "win32-$arch"
|
|
|
|
$store = if ($env:HERMES_RUNTIME_DIR) { $env:HERMES_RUNTIME_DIR } else { Join-Path $HOME '.hermes/tools' }
|
|
|
|
$py = $null
|
|
$entry = Get-ChildItem -Path $store -Directory -Filter "python-*-$target" -ErrorAction SilentlyContinue |
|
|
Sort-Object Name | Select-Object -Last 1
|
|
if ($entry -and (Test-Path (Join-Path $entry.FullName 'bin/python.exe'))) {
|
|
$py = Join-Path $entry.FullName 'bin/python.exe'
|
|
}
|
|
if (-not $py) {
|
|
foreach ($candidate in @(
|
|
(Join-Path $repo 'venv/Scripts/python.exe'),
|
|
(Join-Path $repo 'venv/bin/python.exe'))) {
|
|
if (Test-Path $candidate) { $py = $candidate; break }
|
|
}
|
|
}
|
|
if (-not $py) {
|
|
Write-Error 'activate: no pm python found - run .\setup-hermes.ps1 first'
|
|
}
|
|
|
|
$envJSON = (& $py -m pm.cli env 2>$null) -join "`n"
|
|
if (-not $envJSON) {
|
|
Write-Error 'activate: could not read pm env - run .\setup-hermes.ps1 first'
|
|
}
|
|
$composed = $envJSON | ConvertFrom-Json
|
|
|
|
# --- snapshot what we are about to change (deactivate restores this) ---
|
|
$global:_hermesKeys = @($composed.PSObject.Properties.Name)
|
|
$global:_hermesSaved = @{}
|
|
foreach ($k in $global:_hermesKeys) {
|
|
$global:_hermesSaved[$k] = [pscustomobject]@{
|
|
WasSet = (Test-Path "env:$k")
|
|
Value = [Environment]::GetEnvironmentVariable($k)
|
|
}
|
|
}
|
|
|
|
foreach ($prop in $composed.PSObject.Properties) {
|
|
Set-Item -Path "env:$($prop.Name)" -Value ([string]$prop.Value)
|
|
}
|
|
|
|
function global:deactivate {
|
|
foreach ($k in $global:_hermesKeys) {
|
|
$saved = $global:_hermesSaved[$k]
|
|
if ($saved.WasSet) {
|
|
Set-Item -Path "env:$k" -Value $saved.Value
|
|
} else {
|
|
Remove-Item -Path "env:$k" -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
$global:_hermesKeys = $null
|
|
$global:_hermesSaved = $null
|
|
Remove-Item function:deactivate
|
|
}
|