hermes-agent/hermes_cli
Taylor H. Perkins 8a76de962f fix(secrets): make 1Password bootstrap token reliable outside systemd
The 1Password secret source resolves op:// references using
OP_SERVICE_ACCOUNT_TOKEN read from os.environ. Under systemd the gateway
gets that token via EnvironmentFile, but cron jobs, subprocesses, CLI
runs, macOS launchd, and Docker containers spawn fresh interpreters with
no inherited shell state — so they silently failed to resolve any
reference and fell back to empty strings.

Two patches close the gap, matching Bitwarden's reliability guarantees:

1. env_loader: auto-load ~/.hermes/.op.env after .env so the gitignored
   bootstrap token is available everywhere. override=False plus an
   explicit guard ensure it never clobbers a token already in env (e.g.
   from a systemd EnvironmentFile, which keeps precedence).

2. credential_pool: _get_env_prefer_dotenv() now prefers the resolved
   value in os.environ when .env still holds a raw op:// reference,
   instead of handing a URL to provider auth. Non-op:// values keep the
   existing .env-takes-precedence behaviour.

Also gitignore .op.env, document the three bootstrap-token options, and
add tests covering auto-load, no-override, and the resolved-vs-raw
precedence (plus regression guards).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 04:58:07 -07:00
..
dashboard_auth fix(dashboard): accept HA ingress prefix paths 2026-07-06 03:18:02 -07:00
proxy security(gateway): set explicit client_max_size on 3 uncapped aiohttp servers (#59180) 2026-07-05 14:48:28 -07:00
subcommands feat(cli): add --connect-timeout flag to hermes mcp add 2026-07-05 19:10:00 -07:00
__init__.py chore: release v0.18.0 (2026.7.1) (#56611) 2026-07-01 13:07:40 -07:00
_parser.py Add safe Hermes console REPL 2026-07-03 20:18:00 +05:30
_subprocess_compat.py revert(windows): roll back terminal-popup PRs #53791 #53810 #53829 (#53853) 2026-06-27 15:59:00 -07:00
active_sessions.py fix(tui): preserve live session identity across compression (#49041) 2026-06-24 00:54:18 +05:30
auth.py fix(config): refuse unreadable config overwrites 2026-07-05 23:00:34 +05:30
auth_commands.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
azure_detect.py feat(azure-foundry): add Microsoft Entra ID auth 2026-05-18 10:14:38 -07:00
backup.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
banner.py revert(windows): roll back terminal-popup PRs #53791 #53810 #53829 (#53853) 2026-06-27 15:59:00 -07:00
blueprint_cmd.py refactor(cron): rebrand Cron Recipes -> Automation Blueprints 2026-06-11 10:49:47 -07:00
browser_connect.py fix(browser): surface launch diagnostics when debug browser never opens the CDP port 2026-07-03 01:05:22 -07:00
build_info.py fix(docker): bake build-time git SHA into the image 2026-05-28 15:14:05 +10:00
bundles.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
callbacks.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
checkpoints.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
claw.py revert(windows): roll back terminal-popup PRs #53791 #53810 #53829 (#53853) 2026-06-27 15:59:00 -07:00
cli_agent_setup_mixin.py fix(cli): publish agent ref to cli module so memory on_session_end fires on exit 2026-06-19 16:59:43 -07:00
cli_commands_mixin.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
cli_output.py fix(cli): show masked feedback for secret prompts 2026-05-25 01:20:33 -07:00
clipboard.py revert(windows): roll back terminal-popup PRs #53791 #53810 #53829 (#53853) 2026-06-27 15:59:00 -07:00
codex_models.py fix(codex): drop dead model slugs that HTTP 400 on ChatGPT Pro (#33424) 2026-05-27 12:16:15 -07:00
codex_runtime_plugin_migration.py fix(codex-runtime): de-dup [plugins.X] tables and stop leaking HERMES_HOME into config.toml 2026-05-15 02:31:30 -07:00
codex_runtime_switch.py refactor(codex-runtime): tidy reapply-migration control flow 2026-07-01 23:51:54 +05:30
colors.py
commands.py feat(cli): autocomplete + ghost text for stacked slash-skill invocations (#58763) 2026-07-05 04:34:14 -07:00
completion.py fix: batch of small robustness/correctness fixes from @kyssta-exe 2026-06-01 19:51:03 -07:00
config.py feat(secrets): add 1Password (op://) secret source 2026-07-06 04:58:07 -07:00
console_engine.py perf(console): cache CLI-surface summaries + bound console worker pool 2026-07-03 20:18:00 +05:30
container_boot.py fix(container-boot): also autostart a gateway stranded in 'degraded' 2026-06-29 21:12:36 -07:00
context_switch_guard.py fix(cli): log instead of swallow preflight-warning errors; consistent TUI warning field 2026-06-21 16:31:56 +05:30
copilot_auth.py fix(copilot): prefer endpoints.api for base URL, guard empty chat base URL 2026-06-30 03:27:41 -07:00
cron.py fix(gateway,cron): guard cron model-tool path + add auto-resume loop breaker (#30719) 2026-07-01 02:48:36 -07:00
curator.py feat(curator): make skill consolidation opt-in (prune stays default-on) (#47840) 2026-06-17 05:20:32 -07:00
curses_ui.py feat(cli): ranked fuzzy search in the curses model picker 2026-06-01 16:58:58 -07:00
dashboard_register.py fix(cli): correct stale hermes auth login nous hints to hermes auth add nous (#53929) 2026-06-27 21:30:37 -07:00
debug.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
default_soul.py fix(soul): installers seed the real default persona, upgrade legacy empty templates (#52246) 2026-06-24 18:56:26 -07:00
dep_ensure.py fix(security): centralize credential-safe subprocess env (#29157) 2026-06-27 20:45:31 -07:00
diagnostics_upload.py feat(debug): drop dead confirm step from --nous upload (stateless NAS) 2026-06-30 17:29:23 -07:00
dingtalk_auth.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
doctor.py fix(config): close unreadable-overwrite bug class at a single chokepoint 2026-07-05 23:00:34 +05:30
dump.py fix(dump): flag API keys visible only to the shell, not the managed backend 2026-07-02 19:52:18 -05:00
env_loader.py fix(secrets): make 1Password bootstrap token reliable outside systemd 2026-07-06 04:58:07 -07:00
fallback_cmd.py fix(fallback): merge fallback_providers with legacy fallback_model configurations 2026-05-23 05:24:57 -07:00
fallback_config.py fix(fallback): merge fallback_providers with legacy fallback_model configurations 2026-05-23 05:24:57 -07:00
gateway.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
gateway_enroll.py fix(cli): correct stale hermes auth login nous hints to hermes auth add nous (#53929) 2026-06-27 21:30:37 -07:00
gateway_windows.py revert(windows): roll back terminal-popup PRs #53791 #53810 #53829 (#53853) 2026-06-27 15:59:00 -07:00
goals.py feat(goals): completion contracts for /goal — evidence-based judging (#50501) 2026-06-22 12:20:09 -07:00
gui_uninstall.py feat: uninstall the Chat GUI without removing the agent (CLI + desktop UI) (#40355) 2026-06-06 18:22:38 -07:00
hooks.py feat(agent): add pre_verify hook and verify-on-stop coding guidance 2026-06-30 00:59:29 -05:00
inventory.py fix(desktop): avoid probing custom providers on model picker open 2026-07-04 13:29:00 -07:00
journey.py fix(cli): render /journey color instead of leaking raw ANSI 2026-07-01 16:25:48 -05:00
kanban.py feat(kanban): typed block reasons + unblock-loop breaker (#52848) 2026-06-25 21:46:58 -07:00
kanban_db.py fix(kanban): retry write_txn on transient SQLITE_BUSY 2026-06-28 02:44:04 -07:00
kanban_decompose.py docs(kanban): clarify decomposer profile roles 2026-06-06 19:29:00 -07:00
kanban_diagnostics.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
kanban_specify.py fix: guard int(os.getenv()) casts against malformed env vars (#40598) 2026-06-07 06:14:24 -07:00
kanban_swarm.py refactor(kanban): fold worker/orchestrator skills into injected guidance (#50473) 2026-06-21 17:06:48 -07:00
logs.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
main.py feat(secrets): add 1Password (op://) secret source 2026-07-06 04:58:07 -07:00
managed_scope.py fix(managed-scope): honor managed scope in all standalone config loaders 2026-06-19 07:46:33 -07:00
managed_uv.py revert(windows): roll back terminal-popup PRs #53791 #53810 #53829 (#53853) 2026-06-27 15:59:00 -07:00
mcp_catalog.py revert(windows): roll back terminal-popup PRs #53791 #53810 #53829 (#53853) 2026-06-27 15:59:00 -07:00
mcp_config.py fix(mcp): sanitize server names for auth env keys 2026-07-06 03:18:07 -07:00
mcp_picker.py feat(mcp): Nous-approved MCP catalog with interactive picker (#30870) 2026-05-26 12:48:14 -07:00
mcp_security.py fix(security): close hermes-0day MCP-persistence attack surface 2026-06-21 19:05:27 -07:00
mcp_startup.py fix(mcp): late-refresh must see desktop/dashboard discovery thread owner (#55514) 2026-06-30 02:08:37 -07:00
memory_oauth.py feat(memory): Honcho OAuth connect — desktop and CLI flows + token refresh (#44335) 2026-06-22 19:16:47 -05:00
memory_providers.py fix(desktop): show Hindsight memory provider (#37546) 2026-06-18 16:48:47 -05:00
memory_setup.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
middleware.py fix(middleware): single-use next_call guard + deepcopy-safe request copies 2026-06-06 23:07:25 +05:30
migrate.py feat(cli): hermes migrate xai [--apply] [--no-backup] 2026-05-20 09:18:23 -07:00
moa_cmd.py feat(moa): expose MoA presets as selectable virtual models (#46081) 2026-06-25 13:52:06 -07:00
moa_config.py feat(moa): per-preset fanout cadence — user_turn runs advisors once per user turn (#57591) 2026-07-03 01:02:44 -07:00
model_catalog.py feat(models): seed model-catalog disk cache from checkout on update (#42614) 2026-06-08 22:31:06 -07:00
model_cost_guard.py fix(model): require confirmation for expensive model selections 2026-06-10 00:24:06 -07:00
model_normalize.py fix(gemini): strip native self prefixes before generateContent (#36141) 2026-06-13 13:47:08 -07:00
model_setup_flows.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
model_switch.py fix: preserve static custom provider models 2026-07-05 00:55:51 -07:00
models.py fix(copilot): set x-initiator per turn so user prompts bill as premium requests (salvage #4097) (#58544) 2026-07-05 00:44:15 -07:00
nous_account.py feat(billing): /credits command — balance + portal top-up handoff (#44776) 2026-06-12 08:51:10 +00:00
nous_auth_keepalive.py fix Nous auth refresh for idle agents 2026-06-21 22:43:48 -07:00
nous_billing.py feat(billing): /billing terminal billing — interactive TUI + CLI client (#45449) 2026-06-19 01:53:32 +05:30
nous_subscription.py fix(browser): validate agent-browser is runnable, not just present (#51740) 2026-06-24 00:14:49 -07:00
onepassword_secrets_cli.py fix(secrets): remove unused masked_secret_prompt import from onepassword CLI 2026-07-06 04:58:07 -07:00
oneshot.py fix(agent,cli): surface empty-body API errors and fail oneshot exit code 2026-06-28 02:05:20 -07:00
pairing.py fix(pairing): enforce lockout on approve_code, not just generate_code (#10195) (#21325) 2026-05-07 07:18:21 -07:00
partial_compress.py feat(commands): /compact alias + --preview/--dry-run flags for /compress (#3243 salvage) 2026-07-02 05:10:31 -07:00
pets.py feat(pets): generation RPCs, non-blocking gallery + gateway plumbing 2026-06-24 13:48:38 -05:00
platforms.py feat(whatsapp): add WhatsApp Business Cloud API adapter 2026-05-23 01:07:01 -04:00
plugins.py feat(secrets): pluggable SecretSource interface + multi-source orchestrator 2026-07-06 04:58:07 -07:00
plugins_cmd.py fix(web): correct 'disabled plugin' diagnosis for web backends (#59573) 2026-07-06 04:38:17 -07:00
portal_cli.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
profile_describer.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
profile_distribution.py revert(windows): roll back terminal-popup PRs #53791 #53810 #53829 (#53853) 2026-06-27 15:59:00 -07:00
profiles.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
projects_cmd.py feat(projects): add per-profile project store 2026-06-25 16:40:26 -05:00
projects_db.py feat(projects): add per-profile project store 2026-06-25 16:40:26 -05:00
prompt_size.py fix(prompt-size): respect enabled/disabled toolsets per platform 2026-07-05 19:13:20 -07:00
provider_catalog.py feat(moa): expose MoA presets as selectable virtual models (#46081) 2026-06-25 13:52:06 -07:00
providers.py fix: propagate key_env from custom_providers into ProviderDef 2026-06-29 02:25:48 -07:00
psutil_android.py fix(android): reject unsafe tar members in psutil compatibility installer 2026-05-28 02:36:09 -07:00
pt_input_extras.py fix(cli): ignore terminal focus reports (salvage of #16780) 2026-05-29 00:31:44 -07:00
pty_bridge.py fix(pty-bridge): mark os.killpg/getpgid windows-footgun-ok (POSIX-only module) 2026-06-08 07:03:12 -07:00
relaunch.py revert(windows): roll back terminal-popup PRs #53791 #53810 #53829 (#53853) 2026-06-27 15:59:00 -07:00
runtime_provider.py fix(opencode-go): heal stripped /v1 base_url so non-minimax models stop 404ing (#57585) 2026-07-03 00:46:45 -07:00
secret_prompt.py feat(memory): improve OpenViking setup UX 2026-06-17 01:04:26 +08:00
secrets_cli.py fix(secrets): fail early with clear error when bitwarden setup runs without TTY (#40571) 2026-06-06 18:36:40 -07:00
security_advisories.py fix(stt,tts): restore mistralai — 2.4.8 is clean, ban lifted (#34841) 2026-05-29 13:24:12 -07:00
security_audit.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
security_audit_startup.py style(security-audit): add explicit encoding to read_text calls (ruff PLW1514) 2026-06-21 19:05:27 -07:00
send_cmd.py fix(managed-scope): honor managed scope in config→env bridges too 2026-06-19 07:46:33 -07:00
service_manager.py fix(s6): dot-prefix gateway staging dir so svscan ignores it mid-build (#54834) 2026-06-29 21:33:00 +10:00
session_filters.py feat(sessions): full filter surface for prune + bulk archive subcommand (#59327) 2026-07-05 22:04:52 -07:00
session_listing.py feat(gateway): add /sessions search <query> (#57685) 2026-07-03 13:44:00 -07:00
session_recap.py chore: ruff auto-fix PLR6201 resweep — tuple → set in membership tests (#27355) 2026-05-17 02:29:41 -07:00
setup.py fix(setup): exclude posture toolsets from blank-slate disabled_toolsets 2026-07-05 14:51:49 -07:00
setup_whatsapp_cloud.py fix(whatsapp-cloud): review follow-ups for #43921 2026-06-11 07:51:01 -07:00
skills_config.py fix(skills): apply global|platform disabled union to all resolution sites 2026-06-14 22:54:54 +05:30
skills_hub.py fix(skills-hub): surface per-tap providers (NVIDIA/OpenAI/...) in runtime search (#53191) 2026-06-26 11:04:41 -07:00
skin_engine.py fix(tui): improve charizard completion menu contrast 2026-05-18 20:05:23 -07:00
slack_cli.py fix(slack): subscribe to message.mpim + mpim scopes so group DMs work 2026-06-29 01:02:53 -07:00
sqlite_util.py feat(projects): add per-profile project store 2026-06-25 16:40:26 -05:00
status.py refactor: consolidate gateway session metadata into state.db (#58899) 2026-07-05 14:01:03 -07:00
stdio.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
suggestions_cmd.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
telegram_managed_bot.py Add CLI Telegram QR onboarding 2026-06-05 03:20:10 -07:00
timeouts.py perf(agent-loop): cut 47% of per-conversation function calls via 3 targeted hot-path optimizations (#28866) 2026-05-19 14:25:10 -07:00
tips.py fix: use os.pathsep, add tests, update tips for multi-root support 2026-06-27 04:01:12 +05:30
tools_config.py fix(cli): drop shell=True from cua-driver installer — download to mkstemp, exec as argv (#58796) 2026-07-05 05:35:44 -07:00
toolset_validation.py fix(config): surface invalid platform_toolsets instead of silently dropping tools (#38798) 2026-06-26 14:07:43 +05:30
uninstall.py feat: uninstall the Chat GUI without removing the agent (CLI + desktop UI) (#40355) 2026-06-06 18:22:38 -07:00
voice.py fix(tui): restore voice push-to-talk parity (#20897) 2026-05-06 15:49:59 -07:00
web_git.py refactor(web_git): unify porcelain-v2 parsing into one walker 2026-06-28 14:29:59 -05:00
web_server.py feat(sessions): any prune filter matches all ages; preview shows age span (#59415) 2026-07-05 23:01:10 -07:00
webhook.py fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
win_pty_bridge.py feat(windows): enable dashboard /chat tab via ConPTY (win_pty_bridge) + tests (#42251) 2026-06-08 11:32:43 -07:00
write_approval_commands.py refactor(memory,skills): replace tri-state write_mode with boolean write_approval (default off) (#43354) 2026-06-09 23:21:14 -07:00
xai_retirement.py fix(config): guard xai migration writer + drop gratuitous annotation 2026-07-05 23:00:34 +05:30