hermes-agent/hermes_cli
Teknium f20d16fbf1
fix(windows): SSH ControlMaster gating + stop hijacking the user's python (#84452)
* fix(windows): SSH ControlMaster gating + stop hijacking the user's python

Two Windows environment-integrity fixes:

1. tools/environments/ssh.py (#73927): Windows OpenSSH has no
   Unix-domain-socket ControlMaster support, so unconditionally passing
   ControlPath/ControlMaster/ControlPersist failed EVERY tool call on a
   Windows-hosted ssh terminal backend with 'getsockname failed: Not a
   socket'. Gate the three multiplexing options behind a module-level
   _SSH_MULTIPLEX = (os.name != 'nt'); the scp upload path is gated the
   same way. On Windows the backend now works without connection pooling
   (each command a fresh connection); POSIX behavior is unchanged. The
   teardown 'ssh -O exit' is naturally inert because the socket never
   exists on Windows.

2. scripts/install.ps1 (#83797): the installer put the whole
   venv\Scripts directory on the user PATH, which contains python.exe /
   pythonw.exe / pip.exe and so silently hijacked the 'python' command in
   every terminal on the machine — unrelated projects started resolving
   python to Hermes' runtime interpreter. Now copy only the launchers
   (hermes.exe, hermes-acp.exe) into a dedicated $InstallDir\bin and put
   THAT on PATH. Existing installs are migrated: the legacy venv\Scripts
   entry is stripped from the user PATH on the next install/update. The
   new bin dir is under $InstallDir (…\hermes-agent), which the uninstall
   PATH sweep already matches via its \hermes-agent marker.

Updated the stale hermes_cli/update_cmd.py docstring that described the
old venv\Scripts-on-PATH layout.

Tests: SSH ControlMaster gating pinned both directions (multiplex on →
flags present; off → absent but BatchMode/StrictHostKeyChecking retained).
install.ps1 parses clean via the PowerShell AST parser.

* docs: update windows-native install docs for the bin\ launcher layout

CI (test_windows_native_docs) pins the docs and installer to the same
PATH layout. The #83797 fix moved the PATH entry from venv\Scripts to a
dedicated $InstallDir\bin holding only the hermes launchers, so update
the Windows-native guide to match: PATH-after-install section, the
install-steps list, the directory-layout table, the Get-Command
verification line, and the 'command not found' pitfall. Test now asserts
the bin\ layout and guards against a regression back to venv\Scripts on
PATH.

* fix: keep install.ps1 pure ASCII (PowerShell 5.1 codepage safety)

The two comments I added in the #83797 PATH-hijack fix used em-dashes,
tripping tests/test_install_ps1_ascii_only.py — Windows PowerShell 5.1
reads a BOM-less .ps1 in the system ANSI codepage (not UTF-8), so a
non-ASCII byte can misdecode into a stray quote and desync the parser
(issues #66994/#67000). Replace the em-dashes with ASCII '--'.
2026-08-12 02:56:33 -07:00
..
dashboard_auth fix(auth): /auth/native/authorize 空 provider 自动选择不再统计会被拒绝的密码 provider 2026-08-11 16:00:55 -04:00
observability
…
proxy
…
subcommands
…
web_routers fix(cron): managed-cron fires execute in the gateway process (live adapters + dashboard forwarder) (#84339) 2026-08-12 17:04:44 +10:00
__init__.py
…
_early_recovery.py
…
_parser.py
…
_scan_venv_blockers.py
…
_startup_fast.py
…
_subprocess_compat.py fix: Windows agent-loop papercuts — path splitting, hashing, autocomplete, screenshots, OS detection (#84419) 2026-08-12 01:45:18 -07:00
active_sessions.py
…
agent_import.py
…
agent_plugins.py
…
approval_mode.py
…
approvals_suggest.py
…
approvals_test.py
…
auth.py
…
auth_commands.py
…
azure_detect.py
…
backup.py
…
bang_shell.py
…
banner.py
…
blueprint_cmd.py
…
browser_connect.py
…
build_info.py
…
bundles.py
…
callbacks.py
…
checkpoints.py
…
claw.py
…
cli_agent_setup_mixin.py
…
cli_billing_mixin.py
…
cli_commands_mixin.py
…
cli_output.py
…
clipboard.py
…
codex_models.py
…
codex_runtime_plugin_migration.py
…
codex_runtime_switch.py
…
colors.py
…
commands.py fix: Windows agent-loop papercuts — path splitting, hashing, autocomplete, screenshots, OS detection (#84419) 2026-08-12 01:45:18 -07:00
completion.py
…
config.py
…
config_defaults.py fix: make verify_on_stop opt-in everywhere (default False, not auto) (#84383) 2026-08-12 01:15:25 -07:00
config_migrations.py
…
console_engine.py fix: Windows agent-loop papercuts — path splitting, hashing, autocomplete, screenshots, OS detection (#84419) 2026-08-12 01:45:18 -07:00
container_boot.py
…
context_switch_guard.py
…
copilot_auth.py
…
credential_lifecycle.py
…
cron.py
…
curator.py
…
curses_ui.py
…
dashboard_procs.py
…
dashboard_register.py
…
debug.py
…
default_soul.py
…
dep_ensure.py
…
diagnostics_upload.py
…
dingtalk_auth.py
…
doctor.py
…
doctor_live.py
…
dump.py
…
env_loader.py
…
fallback_cmd.py
…
fallback_config.py
…
focus_view.py
…
gateway.py feat(gateway): allow selective multiplex profile serving 2026-08-10 22:48:24 -07:00
gateway_enroll.py
…
gateway_windows.py
…
goals.py
…
gui_uninstall.py
…
heartbeat.py
…
hooks.py
…
init_command.py
…
input_sanitize.py
…
inventory.py
…
journey.py
…
kanban.py fix(kanban): query show graph before closing database 2026-08-12 13:20:38 +05:30
kanban_db.py
…
kanban_decompose.py
…
kanban_diagnostics.py
…
kanban_specify.py
…
kanban_swarm.py
…
lifecycle.py
…
linux_desktop_entry.py
…
logs.py
…
main.py
…
managed_scope.py
…
managed_uv.py
…
mcp_catalog.py
…
mcp_config.py
…
mcp_picker.py
…
mcp_security.py
…
mcp_startup.py
…
mem_trim.py
…
memory_oauth.py
…
memory_setup.py
…
middleware.py
…
migrate.py
…
moa_cmd.py
…
moa_config.py
…
model_catalog.py
…
model_cost_guard.py
…
model_normalize.py
…
model_search.py
…
model_setup_flows.py
…
model_switch.py
…
models.py
…
nous_account.py
…
nous_auth_keepalive.py
…
nous_billing.py
…
nous_subscription.py
…
npm_engine.py
…
onepassword_secrets_cli.py
…
oneshot.py
…
pairing.py
…
partial_compress.py
…
personality.py
…
pets.py
…
platforms.py
…
plugins.py
…
plugins_cmd.py
…
portal_cli.py
…
profile_describer.py
…
profile_distribution.py
…
profiles.py feat(gateway): allow selective multiplex profile serving 2026-08-10 22:48:24 -07:00
projects_cmd.py
…
projects_db.py
…
prompt_size.py
…
prompt_stash.py
…
provider_catalog.py
…
providers.py
…
proxy_cli.py
…
psutil_android.py
…
pt_input_extras.py
…
pty_bridge.py
…
pty_session.py
…
relaunch.py
…
resource_limits.py
…
route_identity.py
…
runtime_provider.py
…
secret_prompt.py
…
secrets_cli.py
…
security_advisories.py
…
security_audit.py
…
security_audit_startup.py
…
send_cmd.py
…
service_manager.py
…
session_export.py
…
session_export_html.py
…
session_export_md.py
…
session_filters.py
…
session_listing.py
…
session_recap.py
…
session_recovery.py
…
sessions_cmd.py
…
setup.py
…
setup_hidden_env.py
…
setup_whatsapp_cloud.py
…
sizefmt.py
…
skills_config.py
…
skills_hub.py
…
skin_cmd.py
…
skin_engine.py
…
slack_cli.py
…
slash_exec.py
…
sqlite_runtime.py
…
sqlite_safe_read.py
…
sqlite_util.py
…
status.py
…
stdio.py
…
suggestions_cmd.py
…
telegram_managed_bot.py
…
timefmt.py
…
timeouts.py
…
tips.py
…
tools_config.py feat(browser): auto-install the Browser Use CLI instead of silently downgrading 2026-08-11 17:06:15 -05:00
toolset_validation.py
…
uninstall.py
…
update_cmd.py fix(windows): SSH ControlMaster gating + stop hijacking the user's python (#84452) 2026-08-12 02:56:33 -07:00
update_lock.py
…
urllib_security.py
…
vercel_auth.py
…
verify_cmd.py
…
voice.py
…
web_deps.py
…
web_git.py
…
web_models.py
…
web_server.py fix(cron): managed-cron fires execute in the gateway process (live adapters + dashboard forwarder) (#84339) 2026-08-12 17:04:44 +10:00
webhook.py
…
win_pty_bridge.py
…
windows_ssh_runtime.py
…
write_approval_commands.py
…
xai_retirement.py
…