Files
hermes-agent/activate.ps1
ethernet 3d12e86ef1 feat(pm): unified package manager — pm store foundation
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.
2026-08-31 18:00:48 -04:00

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
}