Commit Graph
4730 Commits
Author SHA1 Message Date
nesquena-hermes d3de2cbc1d Merge pull request #4623 from nesquena/fix/bootstrap-root-agent-discovery
Install-time-only bootstrap fix: discover agent installed as root (FHS /usr/local/lib/hermes-agent) or behind the bash launcher. Independently reviewed + approved (nesquena, OWNER); CI green on all 9 shards + browser-smoke + lint. No version bump (no runtime/agent change).
2026-06-21 10:10:02 -07:00
nesquena-hermes 11625aac1a fix(bootstrap): discover agent installed as root (FHS) or behind the bash launcher
A fresh root install on Linux (e.g. a new Proxmox/Ubuntu VM) places the Hermes
Agent at /usr/local/lib/hermes-agent and links the CLI into /usr/local/bin,
while the modern `hermes` launcher is a `#!/usr/bin/env bash` wrapper that
exec's the venv entrypoint. The old discovery only checked
~/.hermes/hermes-agent-style paths and parsed the launcher's shebang as a Python
interpreter, so on a root VM discover_agent_dir() returned None, bootstrap built
a WebUI-only .venv, and chat aborted at launch with "Python environment cannot
import both WebUI dependencies and Hermes Agent."

Two complementary fixes:
- Add /usr/local/lib/hermes-agent to discover_agent_dir()'s candidate list.
- Harden _agent_dir_from_hermes_cli() to follow the launcher's exec target (any
  absolute path quoted in the wrapper) up to run_agent.py, not just a Python
  shebang. Skips /usr/bin/env indirection.

Now `python3 bootstrap.py` works out of the box for root/container installs with
no HERMES_WEBUI_PYTHON override needed. Adds tests for the bash-wrapper shape,
the env-indirection no-false-positive case, and the FHS candidate probe; updates
docs/troubleshooting.md.
2026-06-21 16:55:40 +00:00
nesquena-hermes f5a0d047ed Merge pull request #4615 from nesquena/stage-4608
Release v0.51.560 — recovered journal output reaches model context (#4608)
2026-06-21 03:22:18 -07:00
nesquena-hermes f3d443c6d4 docs(release): stamp v0.51.560 — recovered journal output reaches model context (#4608) 2026-06-21 10:19:20 +00:00
nesquena-hermes 215c819fae stage #4608 onto master (v0.51.559) — backfill run-journal-recovered rows into model context
allenliang2022: recovered assistant rows were added to the visible transcript but not context_messages,
so the model lost recovered output. Adds _append_recovered_turn_to_context with a role-dedup guard.
Co-authored-by: allenliang2022 <allenliang2022@users.noreply.github.com>
2026-06-21 10:11:35 +00:00
nesquena-hermes af6cf0f139 Merge pull request #4614 from nesquena/stage-4031
Release v0.51.559 — cron model picker copy polish (#4031)
2026-06-21 03:07:52 -07:00
nesquena-hermes b2818cd46f docs(release): stamp v0.51.559 — cron model picker copy polish (#4031) 2026-06-21 09:57:22 +00:00
nesquena-hermes 879324290c fix(#4031): add cron_model_no_agent_hint to ALL 13 locales (strict locale-parity tests)
The repo enforces every locale defines every English key (test_*_locale.py). Adding the key to
English only broke 6 locale-coverage tests. Added the key (English fallback text) to all 13 locale
blocks. Full suite catches what targeted tests miss.
2026-06-21 09:49:40 +00:00
nesquena-hermes 3924966940 fix(#4031): define cron_model_no_agent_hint i18n key (was rendering the literal key)
Codex gate (SILENT): panels.js referenced t('cron_model_no_agent_hint') but the key was never added
to i18n.js. t() returns the key name for a missing translation (falls back to LOCALES.en, then the
key), so script-only cron jobs rendered the literal 'cron_model_no_agent_hint'. Added the English key
(other locales fall back to en) + strengthened the i18n-keys test to assert the value is defined.
2026-06-21 09:41:51 +00:00
nesquena-hermes 675bc7d9e7 stage #4031 onto master (v0.51.558) — polish cron model picker copy + regression tests
TomBanksAU: cron model picker copy (esc()+i18n fallbacks, no_agent hint for script-only jobs) +
195-line provider-picker regression test. Core picker already shipped; this is polish + guardrails.
Co-authored-by: TomBanksAU <TomBanksAU@users.noreply.github.com>
2026-06-21 09:36:24 +00:00
nesquena-hermes 1b194a397c Merge pull request #4610 from nesquena/stage-4581
Release v0.51.558 — escape-target symlinks display-only (#4581)
2026-06-21 02:28:15 -07:00
nesquena-hermes 7641e7d42e docs(release): stamp v0.51.558 — escape-target symlink display-only rows (#4581) + dialog Cancel fix 2026-06-21 09:17:46 +00:00
nesquena-hermes 96b5214523 fix(#4581): restore hidden Cancel button in showPromptDialog after a hideCancel confirm
Codex gate (SILENT): the new outside-symlink info dialog uses showConfirmDialog({hideCancel:true})
which sets the shared #appDialogCancel to display:none; showPromptDialog only reset textContent, so a
later rename/new-file prompt opened with no Cancel button. Fix: showPromptDialog now restores
cancelBtn.style.display='' first. + regression test.
2026-06-21 09:17:26 +00:00
nesquena-hermes 077de5455c harden(#4581): display-only escape symlinks must not disclose target path/metadata
Codex+Opus gate (info-leak): the display-only escape-target rows still returned the resolved
outside path (target), target-derived is_dir, and target stat size; ui.js showed the outside path
in the open-dialog. Fix: emit ONLY name/path/type/target_outside_workspace/mtime for outside rows
(no target, no size, is_dir=False); dialog uses a generic 'points outside workspace' message (dropped
{target} from external_link_open_confirm across all 13 locales). Containment was already intact (both
gates confirmed); this closes the path-disclosure. Tests updated to assert the no-leak property.
2026-06-21 09:15:22 +00:00
nesquena-hermes 1e18c336f1 stage #4581 onto master (v0.51.556) — surface escape-target symlinks as display-only workspace rows
claw-io: symlinks whose target resolves outside the workspace root were silently dropped; now emitted
with target_outside_workspace=True (display-only — safe_resolve_ws/open_anchored_fd still block
navigation). Dedup-winner over #4573 (stronger tests). Co-authored-by: claw-io <claw-io@users.noreply.github.com>
2026-06-21 09:15:22 +00:00
nesquena-hermes 4c45fc8a55 Merge pull request #4609 from nesquena/stage-4592
Release v0.51.557 — desktop question-jump discoverable (#4592)
2026-06-21 01:56:54 -07:00
nesquena-hermes f763b8adf8 docs(release): stamp v0.51.557 — desktop question-jump discoverable (#4592) 2026-06-21 08:53:10 +00:00
nesquena-hermes 382856e170 stage #4592 onto master (v0.51.555) — keep per-turn question-jump button discoverable on desktop (#2246 follow-up)
santastabber: desktop ≥641px keeps the jump-to-question affordance visible (it's navigation) while
timestamp/actions chrome stays hover/focus-only, via :has(.msg-question-jump-btn) selectors. CSS+test only.
Co-authored-by: santastabber <santastabber@users.noreply.github.com>
2026-06-21 08:52:46 +00:00
nesquena-hermes 3aaeea881b Merge pull request #4607 from nesquena/stage-4599
Release v0.51.556 — Indonesian Edge TTS voice + Listen button fix (#4599)
2026-06-21 01:46:22 -07:00
nesquena-hermes 1ef996b112 docs(release): stamp v0.51.556 — id-ID Edge TTS voice + Listen button state (#4599) 2026-06-21 08:43:17 +00:00
nesquena-hermes 07e6a839fa stage #4599 onto master (v0.51.555) — add id-ID Edge TTS voice + fix Listen button playing-state (parity)
latipun7: adds id-ID-GadisNeural to the Edge TTS allowlist (Edge TTS is a core builtin -> parity, default-in)
+ picker label + sets speaking-state at start of _playEdgeTtsChunked so the Listen button reflects playback.
Co-authored-by: latipun7 <latipun7@users.noreply.github.com>
2026-06-21 08:35:03 +00:00
nesquena-hermes be36fc3c71 Merge pull request #4606 from nesquena/stage-2980
Release v0.51.555 — mobile reload recovery after compression (#2980)
2026-06-21 01:30:45 -07:00
nesquena-hermes 760a5168c9 docs(release): stamp v0.51.555 — mobile reload recovery after compression (#2980/#3133-adjacent) 2026-06-21 08:19:15 +00:00
nesquena-hermes aaa14066b2 fix(#2980): drop unused 'import types' in cross-profile test (ruff F401 — the only CI lint blocker) 2026-06-21 08:18:29 +00:00
nesquena-hermes fbaaa90a64 test: widen run-journal static-window 18000->20000 (my +600-char #2980 continuation block pushed runtime_journal_snapshot past the brittle fixed offset; not a regression) 2026-06-21 08:17:32 +00:00
nesquena-hermes 64ca1f8686 harden(#2980): profile-scope continuation lookup + safe-sid + no speculative restore write
Gate findings (Codex 2-CORE / Opus SHIP-WITH-FIXES), both fixed:
1. cross-profile leak — _pre_compression_continuation_session_id scanned all profiles' sessions,
   matched only by parent_session_id; now filters children by _profiles_match(child, snapshot)
   + validates returned sid with is_safe_session_id. +cross-profile regression test.
2. restore-state poison — frontend wrote continuationSid to localStorage/URL BEFORE the inner
   loadSession proved it loadable; removed the speculative write (success path at the loaded id
   handles it). Updated the source-grep test to assert the safe form.
Bounded BFS (range(20)+seen) + recursion guard confirmed safe by both gates.
2026-06-21 08:17:32 +00:00
nesquena-hermes dbeb437bcc rebase #2980 onto master (v0.51.548) for ship-gate — recover mobile reloads after compression rotation
george-andra: GET /api/session surfaces continuation_session_id for a hidden pre-compression
snapshot; loadSession follows it so a mobile reload mid-compression recovers to the visible
continuation instead of a hidden snapshot (chat looked 'lost'). Resolved 2 conflicts (1615 behind):
sessions.js merged w/ #2971 re-arm guard; routes.py merged w/ _session_source_is_webui branch.
Co-authored-by: george-andra <george-andra@users.noreply.github.com>
2026-06-21 08:17:32 +00:00
nesquena-hermes 69edf01bcc Merge pull request #4605 from nesquena/stage-4578
Release v0.51.554 — preserve mid-stream scroll anchor (#4578/#4295)
2026-06-21 00:40:08 -07:00
nesquena-hermes 05d776d6d3 docs(release): stamp v0.51.554 — preserve mid-stream scroll anchor (#4578/#4295) 2026-06-21 07:36:46 +00:00
nesquena-hermes 5e818546f8 stage #4578 onto master (v0.51.553) — preserve mid-stream scroll anchor + honor manual unpin (#4295)
franksong2702: preserve the reader's semantic viewport anchor during mid-stream transcript rebuilds
before raw scrollTop fallback; remount virtualized anchors before restore w/ _programmaticScroll
scoped to the remount frame; treat captured userUnpinned/pinned snapshot as authoritative so
distance-inference can't re-pin a reader who scrolled away during a live reply. Browser-only scroll
state. Co-authored-by: franksong2702 <franksong2702@users.noreply.github.com>
2026-06-21 07:25:11 +00:00
nesquena-hermes ca5fe0accf Merge pull request #4604 from nesquena/stage-4588
Release v0.51.553 — extensions diagnostics panel (#4588)
2026-06-21 00:23:08 -07:00
nesquena-hermes 5eafbfb41a docs(release): stamp v0.51.553 — extensions diagnostics panel (#4588) 2026-06-21 07:19:49 +00:00
nesquena-hermes 813e5aa3b2 stage #4588 — extensions settings diagnostics panel 2026-06-21 07:10:05 +00:00
nesquena-hermes 15342a821f Merge pull request #4603 from nesquena/stage-4593
Release v0.51.552 — extension sidecar CSP docs (#4593)
2026-06-21 00:08:33 -07:00
nesquena-hermes 4aa0c7a37f docs(release): stamp v0.51.552 — extension sidecar CSP docs (#4593) 2026-06-21 07:05:19 +00:00
nesquena-hermes 8f3f6ea67a stage #4593 onto master (v0.51.550) — document extension sidecar CSP support + CSP test coverage
santastabber: docs (README + EXTENSIONS.md) clarifying extension sidecar CSP behavior +
test_issue1909_csp_enforcement / test_issue2901_csp_connect_extra assertions. Docs+tests only, no
prod code. Co-authored-by: santastabber <santastabber@users.noreply.github.com>
2026-06-21 07:04:31 +00:00
nesquena-hermes cf16ad4bb5 Merge pull request #4602 from nesquena/stage-4594
Release v0.51.551 — manual /compress preserves visible transcript (#4594/#3133)
2026-06-20 23:58:40 -07:00
nesquena-hermes d281b7cf63 docs(release): stamp v0.51.551 — manual /compress preserves visible transcript (#4594/#3133) 2026-06-21 06:54:48 +00:00
nesquena-hermes 4bf9ff7518 stage #4594 onto master (v0.51.550) — preserve visible transcript after manual /compress (#3133)
Manual /compress wrote the compressed payload into BOTH s.messages (visible) and s.context_messages
(model-facing) + wiped s.tool_calls -> messages vanished from the window. Fix keeps s.messages +
tool history durable, deep-copies compressed only into s.context_messages, anchors off visible msgs.
Co-authored-by: franksong2702 <franksong2702@users.noreply.github.com>
2026-06-21 06:46:47 +00:00
nesquena-hermes ccc000a911 Merge pull request #4600 from nesquena/stage-4587
Release v0.51.550 — Transparent Stream activity survives settle/reload (#4587/#4568)
2026-06-20 23:39:36 -07:00
nesquena-hermes d38b95076a docs(release): stamp v0.51.550 — Transparent Stream activity survives settle/reload (#4587/#4568) 2026-06-21 06:35:16 +00:00
nesquena-hermes 236b165b7a harden(#4587): align scene-builder final-answer filters to the renderer's >=0.9 ratio
Codex gate (SILENT): the scene-builder/hydrator _anchor_scene_row_looks_like_final_answer
(messages.js + routes.py) used a loose '>=80 + prefix' rule while the renderer
_anchorSceneProseMatchesFinalAnswer uses '>=80 + ratio>=0.9'. A short intermediate-prose row that
was a prefix of the final answer could be dropped from the persisted scene by the looser builder,
leaving the stricter renderer no row to show -> silent prose loss. Aligned both filters to the
renderer's rule (drop fewer -> preserve more intermediate prose). Matrix already GREEN; this closes
the edge the fixture didn't exercise.
2026-06-21 06:03:44 +00:00
nesquena-hermes 332b24bec9 stage #4587 onto master (v0.51.549) — render persisted anchor activity in Transparent Stream on reload (#4568)
Transparent Stream lost ALL tool/thinking activity on every rehydrate path (settle/switch/hide/blur/
reload) — only final answer survived, because _renderSettledAnchorSceneForMessage early-returned
outside Compact Worklog. Adds a transparent-mode settled renderer (same persisted activity_scene_v1,
event rows) + intermediate-prose preservation (suppress only the final-answer-dup prose). Compact
Worklog unchanged.
2026-06-21 05:39:39 +00:00
nesquena-hermes 5d2e510d75 Merge pull request #4596 from nesquena/stage-4589
Release v0.51.549 — HOTFIX profile switching for single-user named profiles (#4589/#4586)
2026-06-20 22:36:23 -07:00
nesquena-hermes fbab5bb42b docs(release): stamp v0.51.549 — hotfix profile switching for single-user named profiles (#4589/#4586) 2026-06-21 05:32:53 +00:00
nesquena-hermes fba80e6981 harden(#4589): close the SECOND isolation-escape door (runtime-env path)
Codex re-gate (CORE, reproduced): _reload_dotenv() was guarded, but get_profile_runtime_env() also
copies a profile .env into runtime env, which profile_env_for_background_worker()/streaming apply to
os.environ -> HERMES_WEBUI_ISOLATED_PROFILE=0 in a profile .env still escaped isolation on that path.
Fix: filter _PROTECTED_ENV_KEYS in get_profile_runtime_env's .env loop + add the key to
_BLOCKED_RUNTIME_ENV_KEYS (gateway-parity filter). + runtime-path regression test.
2026-06-21 05:23:09 +00:00
nesquena-hermes cb7efedc38 harden(#4589): protect HERMES_WEBUI_ISOLATED_PROFILE from profile-.env override
Codex gate (CORE, reproduced): _reload_dotenv() copies a profile's .env into os.environ, so a
contained user could set HERMES_WEBUI_ISOLATED_PROFILE=0 in their own profile .env and silently
escape isolation. Fix: _PROTECTED_ENV_KEYS — _reload_dotenv refuses to override operator/deployment
keys from a profile .env (logs a warning). + regression test proving .env can't disable isolation.
2026-06-21 05:17:20 +00:00
nesquena-hermes 17eb82f087 stage HOTFIX #4589 onto master (v0.51.548) — require explicit opt-in for isolated profile mode (#4586)
Profile-isolation regression: isolated mode was inferred from HERMES_HOME path shape (*/profiles/<name>),
which the launcher exports for ANY normal named profile -> single-users on a named profile lost profile
switching + saw only 1 profile. Fix: HERMES_WEBUI_ISOLATED_PROFILE explicit opt-in is now the PRIMARY gate.
2026-06-21 05:08:59 +00:00
nesquena-hermes 6c78d1c315 Merge pull request #4585 from nesquena/stage-4569
Release v0.51.548 — extension load diagnostics (#4569)
2026-06-20 21:20:25 -07:00
nesquena-hermes 4fa9abd9d2 docs(release): stamp v0.51.548 — extension load diagnostics (#4569) 2026-06-21 04:16:58 +00:00