2361 Commits
Author SHA1 Message Date
nesquena-hermesandwebtecnica fac3470668 docs(changelog): stamp #6964 title-dedup + add manual-rename-during-retry test
Codex SHOULD-FIX: add a committed test proving the de-dup retry variant never
clobbers a user-source manual rename (retry goes through the same provenance
rank guard). Additive test-only; no behavior change to the contributor's fix.

Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
2026-08-13 00:39:07 +00:00
nesquena-hermesandjosephcy95 38db12d72a docs(changelog): stamp #6944 + add ambiguous-suffix-match regression test
Codex round-2 SHOULD-FIX: add a committed test asserting the hinted bare-id
fallback returns null when two same-provider options normalize identically
(refuses to guess), plus single-match resolves and exact-match unaffected.
Additive test-only; no behavior change to the contributor's fix.

Co-authored-by: josephcy95 <josephcy95@users.noreply.github.com>
2026-08-12 22:48:19 +00:00
nesquena-hermesandharsh2hell 7f03b52a00 docs(changelog): stamp #6935 persist_user_timestamp kwarg-compat fix
Co-authored-by: harsh2hell <harsh2hell@users.noreply.github.com>
2026-08-12 20:51:13 +00:00
nesquena-hermesandliuguangyong93 d73cea803e docs(changelog): stamp #6892 + add direct sync_session_title coverage tests
Codex round-1 SHOULD-FIX: the PR's only test change mocked the new write to a
no-op. Add real-SessionDB tests proving generated-title persistence, manual-rename
no-overwrite, and cli/gateway source preservation on ensure_session. Additive
test-only; no behavior change to the contributor's fix.

Co-authored-by: liuguangyong93 <liuguangyong93@users.noreply.github.com>
2026-08-12 18:51:46 +00:00
nesquena-hermesandhappy5318 fb5a40f132 docs(changelog): stamp #6938 + add loadSession compression-cleanup regression test
Co-authored-by: happy5318 <happy5318@users.noreply.github.com>
2026-08-12 06:52:45 +00:00
nesquena-hermes bf2f8f125f docs(changelog): stamp #6932 skill keyword autocomplete 2026-08-11 17:51:59 +00:00
nesquena-hermes 1f046e11b0 docs(changelog): stamp #6924 extension turn-lifecycle events 2026-08-11 10:53:44 +00:00
nesquena-hermes 222596cf17 docs(changelog): stamp #6795 cooperative extension identity handle 2026-08-11 03:35:22 +00:00
nesquena-hermes f642dc6820 Merge remote-tracking branch 'origin/master' into release/stage-6410-1786414679
# Conflicts:
#	CHANGELOG.md
2026-08-11 03:04:27 +00:00
nesquena-hermes 892e73f7d6 Merge remote-tracking branch 'origin/master' into release/stage-6410-1786414679 2026-08-11 02:57:31 +00:00
nesquena-hermes b77d4a2fb0 Merge remote-tracking branch 'origin/master' into release/stage-6757-1786414089 2026-08-11 02:57:05 +00:00
nesquena-hermes 90426570f2 test(kanban): drop synthetic 480x320 case; keep scroll-reachable off-viewport fix
The kanban board layout test's 480x320 short-landscape case was environment-
marginal: multiple assertions (inline field-vs-modal geometry AND the shared
off-viewport check) each differ by a few px between the CI runner's font render
and local Chromium, producing a CI-only flake that varied by shard + locale.
480x320 landscape is a viewport essentially no real device uses.

Drop that one synthetic case (keep 1280x800, 768x800, 400x800, 1024x600 x
en/ru/de). The scroll-reachable off-viewport tolerance in _layout_helpers.py +
its 2 control tests are retained as a genuine correctness improvement.
2026-08-11 02:51:25 +00:00
nesquena-hermes 903ace3f49 test(layout): don't flag scroll-reachable fields as off-viewport
The shared assert_layout_sane degenerate check flagged an interactive element
as 'off-viewport' when it sat below the fold at rest but was reachable by
scrolling an overflow-y:auto ancestor (tall dialog on a short viewport). This
produced a CI-environment-sensitive false positive on the Kanban board settings
modal at 480x320 German (the field is inside the .kanban-modal-overlay which is
overflow-y:auto), passing locally but failing on the CI runner's font render.

Add reachableByScrollableAncestor(): an off-viewport edge absorbed by a
scrollable (overflow auto/scroll, content-overflowing) ancestor is reachable and
not a defect. Genuinely-unreachable elements (no scroll escape, e.g. inside
overflow:hidden) are still flagged. +2 unit tests covering both directions.
2026-08-11 02:40:48 +00:00
nesquena-hermesandrodboev 8b873c55eb Release exp-v0.52.198: Refine selected transcript text in composer (#6410, @rodboev)
Ships PR #6410 with a maintainer UX fix folded in (authorship preserved).

Adds a 'Refine' action to the message text-selection toolbar: select text in a
chat message -> Refine seeds it into the composer as an editable quoted draft
(marker-free, one-way, existing draft + attachments preserved, 44x44 mobile
icon buttons, all 15 locales). ChatGPT/Notion-style quote-to-edit flow.

Maintainer fix (Fable UX gate): French instruction string now uses the
space-before-colon convention (Instruction d'affinage :).

Gate: Codex SAFE TO SHIP (marker-free, no XSS, one-way Range, Reply/drafts
preserved), Fable SHIP-WITH-UX-FIXES (fix applied), tests 19/19, ESLint clean.

Co-authored-by: rodboev <rodboev@users.noreply.github.com>
2026-08-11 02:19:06 +00:00
nesquena-hermesandfranksong2702 cf7eb48e56 Release exp-v0.52.197: preserve api_content for agent replay (#6757, @franksong2702)
Ships PR #6757 with a maintainer hardening pass folded in (authorship preserved).

Preserves the exact provider-facing reply text (api_content) through the internal
session store for byte-accurate agent replay, while guaranteeing it never reaches
a browser: every client-facing surface strips it via the public projection.

Maintainer fixes (2 defects my adversarial re-gate reproduced):
- Selective session redaction restored: only transcript fields are scrubbed;
  operational fields (e.g. workspace path) pass through unchanged, so a path
  containing credential-shaped text is no longer masked into an invalid path.
- Runner-backed SSE relay now projects payloads before emit, closing an
  api_content leak through _stream_runner_run_events.
+5 regression tests. Codex adversarial re-gate: SAFE TO SHIP. Full suite clean.

Co-authored-by: franksong2702 <franksong2702@users.noreply.github.com>
2026-08-11 02:10:21 +00:00
nesquena-hermes bdee6ff7c2 CHANGELOG: transparent-stream copy feedback (#6037, @Stacey2911) 2026-08-10 21:17:30 +00:00
nesquena-hermes 6e1254705b CHANGELOG: per-board default workspace path (#6055, @rodboev) 2026-08-10 20:19:31 +00:00
nesquena-hermes 125a2f1b45 CHANGELOG: workspace file-tree sort selector (#6091, @rodboev) 2026-08-10 19:08:32 +00:00
nesquena-hermesandnesquena-hermes bd91b649f1 Release exp-v0.52.193: a11y aria-expanded clear on panel switch (#6656, @rodrigogs) (#6887)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-09 21:46:31 +00:00
nesquena-hermesandnesquena-hermes 192df903c8 Release exp-v0.52.192: session-aware image-input routing (#6882, @happy5318) (#6883)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-09 16:10:26 +00:00
nesquena-hermesandnesquena-hermes d42dae81a8 Release: mark running cron sessions active in sidebar (#6734, @webtecnica) (#6879)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-09 09:41:53 +00:00
nesquena-hermesandnesquena-hermes 1af7eb5b16 Release: honor auxiliary.title_generation.enabled=false in WebUI (#6877, @X-Shihai) (#6878)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-09 07:36:57 +00:00
nesquena-hermesandnesquena-hermes 0b839f7ef8 Release: honor persisted auto-follow across settings-fetch failures (#6856, @sand01chi) (#6873)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-09 03:38:05 +00:00
nesquena-hermesandnesquena-hermes c354c13c7d Release: hide kanban worker sessions from the default sidebar (#6780, @vduke) (#6872)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-09 02:55:15 +00:00
nesquena-hermesandnesquena-hermes eb04bf5951 Release exp-v0.52.187: reject obsolete cancel finalizer after successor completes (#6636, @webtecnica) (#6868)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-09 01:12:19 +00:00
nesquena-hermesandnesquena-hermes 614b5c9f48 Release exp-v0.52.186: stop full-message fade replay on tool-call rewind (#6783, @silent-reader-cn) (#6866)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-08 23:40:08 +00:00
nesquena-hermesandnesquena-hermes 44fca1e9a4 Release exp-v0.52.185: preserve displayed conclusion in session forks (#6735, @ruizanthony) (#6865)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-08 22:58:49 +00:00
nesquena-hermesandnesquena-hermes 51e3d09ad6 Release exp-v0.52.184: three-font typography contract (#5918, @starship-s) (#6864)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-08 22:51:42 +00:00
nesquena-hermesandnesquena-hermes 84f9be2088 Release exp-v0.52.183: phantom compression barrier (#6572) + same-session renotify (#6681) (#6863)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-08 22:13:46 +00:00
nesquena-hermesandnesquena-hermes 0d37067123 Release exp-v0.52.182: isolate update_channel writes from generic autosave (#6666, @rodboev) (#6861)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-08 20:38:37 +00:00
nesquena-hermesandnesquena-hermes 7a94e34a6d Release exp-v0.52.181: compact active recovery snapshot transport (#6858, @allenliang2022) (#6860)
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-08 19:12:33 +00:00
7f27942393 Release exp-v0.52.180: don't drop async delegation completions while origin session busy (#6632 + #6662) (#6852)
* fix: preserve async completion delivery attempts while busy

* fix(async): keep legacy busy completions retryable

* fix(async): extend keep_legacy_retrying to resolved-target transient-failure exits; keep formatting failures bounded (combined #6632+#6662 gate findings)

* Release exp-v0.52.180: don't drop async delegation completions delivered while origin session busy (#6632, #6662)

---------

Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
Co-authored-by: ai-ag2026 <261867348+ai-ag2026@users.noreply.github.com>
2026-08-08 00:14:21 -07:00
21a8160338 Release exp-v0.52.179: gateway watcher index-covered fingerprint + failure-state preservation (#6821) (#6850)
* perf: keep gateway watcher fingerprint index-covered

* [verified] fix: preserve watcher state on projection failure

* Release exp-v0.52.179: keep gateway watcher fingerprint index-covered + preserve state on projection failure (#6821)

---------

Co-authored-by: StefanPieter <stefan@noble-pro.com>
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-07 23:18:33 -07:00
c1fc3f2c79 Release exp-v0.52.178: honor configured appearance defaults for no-settings-file users (#6834) (#6849)
* fix(settings): _SETTINGS_DEFAULTS theme/skin never reach a user with no settings file

`_read_raw_settings_file()` returns `{}` for a MISSING settings.json. `{}` is a
dict, so `load_settings()` always took its `isinstance(stored, dict)` arms:

    settings["theme"], settings["skin"] = _normalize_appearance(
        stored.get("theme") if isinstance(stored, dict) else settings.get("theme"),
        stored.get("skin") if isinstance(stored, dict) else settings.get("skin"),
    )

`stored.get("theme")` is then None, `_normalize_appearance(None, None)` falls
through to its unknown-theme branch, and the result is ("dark", "default").
`_SETTINGS_DEFAULTS["theme"]` and `["skin"]` are therefore unreachable for the
one case they exist to serve: a user who has no settings file yet.

This is invisible on the shipped defaults, because dark/default is exactly what
the fallback produces — the two paths agree, so nothing ever caught it. It only
surfaces once the defaults are changed, at which point the dict silently does
nothing: a deployment (or fork, or a future change to the shipped values) sets an
appearance and every new user still gets dark.

The fix falls back to the defaults instead of to None, gated on the PAIR of
keys. Per-field (`or settings.get(...)`) looks equivalent and is not: with a
stored legacy theme and no stored skin, `slate` normalises to ("dark", "slate"),
but per-field fallback injects the default skin and returns ("dark", "default"),
silently dropping the legacy migration. That is the same absent-vs-explicit
distinction the boot script draws in #6808 — this is its server-side half. #6808
stops the browser fabricating a choice; without this, the server still answers
with the fallback rather than the configured default.

Behaviour on stock defaults is provably unchanged: `_normalize_appearance(None,
None)` and `_normalize_appearance("dark", "default")` both return
("dark", "default"). A stored preference is untouched in every case.

13 tests. Both directions are pinned, and both were checked by injection:
reverting api/config.py fails exactly the two "defaults are honoured" cases and
nothing else; substituting the per-field variant fails 8, including four of the
five legacy migrations. Ran the full settings/appearance surface — 61 test files,
873 passed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Release exp-v0.52.178: honor configured appearance defaults for users with no settings file (#6834)

---------

Co-authored-by: Hermes Agent <hermes@aip.de>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-07 23:06:57 -07:00
80e3574eca Release exp-v0.52.177: scope aux-title test module stubs (#6661) (#6848)
* test(#6630): isolate auxiliary client fixtures

* test(#6630): route both aux-title suites through one scoped module stub

* test(#6630): drop dead import and record the patch.dict restore constraint

* Release exp-v0.52.177: scope auxiliary-title test module stubs, stop cross-file sys.modules leak (#6661)

---------

Co-authored-by: Rod Boev <rod.boev@gmail.com>
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-07 22:47:51 -07:00
5e5a41e79f Release exp-v0.52.176: start profile list-cache TTL after row build (#6846) (#6847)
* fix(profiles): start list cache TTL after row build

Slow row builds currently consume the cache TTL before the result is stored.
Timestamp the cache at completion so every successful build receives the full TTL.

Refs #5364

Assisted-by: Hermes Agent:gpt-5.6-sol
Assisted-by: Codex:gpt-5.6-luna

* Release exp-v0.52.176: start profile list-cache TTL after row build (#6846)

---------

Co-authored-by: starship-s <45587122+starship-s@users.noreply.github.com>
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-07 22:40:22 -07:00
nesquena-hermesandnesquena-hermes fcef6ba1af Release exp-v0.52.175: identical-prompt retry settlement regression (#6631) (#6845)
* test: pin identical-prompt retry settlement

* Release exp-v0.52.175: two-direction regression for identical-prompt retry settlement (#6631)

---------

Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-07 20:05:49 -07:00
e09ccbaac9 Release exp-v0.52.174: regression coverage for empty tool_calls drop on mirror path (#6803) (#6844)
* test(streaming): cover empty tool_calls drop in _api_safe_message_positions (#6796)

* Release exp-v0.52.174: regression coverage for empty tool_calls drop on mirror path (#6803)

---------

Co-authored-by: Webtecnica Bot <bot@webtecnica.com.br>
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-07 19:53:02 -07:00
898a01b766 Release exp-v0.52.173: don't mutate system prompt on workspace switch (#6683) (#6841)
* fix(cache): don't mutate system prompt on workspace switch (#6672)

* test(#6672): pin created_workspace freeze + compact round-trip + legacy fallback (closes coverage gap flagged in review)

* Release exp-v0.52.173: don't mutate system prompt on workspace switch (#6683)

---------

Co-authored-by: webtecnica <webtecnica@users.noreply.github.com>
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-07 19:42:15 -07:00
a818be1ed4 Release exp-v0.52.172: preserve reader scroll intent during live renders (#6453) (#6838)
* fix: preserve reader scroll intent during live renders

* fix: enforce programmatic scroll guard freshness

* test: update programmatic scroll guard assertion

* test: update scroll safety valve assertion

* fix: reconcile scroll intent helper after base refresh

* fix: timestamp fallback history scroll writes

* test: cover stale older-message fallback scroll guard

* test: execute the real slow-render history fallback

* test: provide the history fallback DOM helper

* test: retain async declaration in history fallback harness

* test: remove trailing blank line from scroll intent regression

* test(#6414): update scroll-intent harness for window._autoScrollFollow + _messageScrollInputGeneration (master drift)

* Release exp-v0.52.172: preserve reader scroll intent during live renders (#6453)

---------

Co-authored-by: Frank Song <franksong2702@gmail.com>
Co-authored-by: Frank Song <xuefu.song@qq.com>
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-07 18:37:31 -07:00
37547a7bd1 Release exp-v0.52.171: keep settled Worklog in place across stream settlement (#6454) (#6837)
* test: prove worklog continuity across stream settle

* fix: keep settled worklog in place on stream done

* fix: preserve settle follow ordering

* test: wire settled worklog frame proof

* fix: preserve settled worklog detail disclosure

* fix: preserve default-open settled worklogs

* fix: preserve blank-owner worklogs

* fix: keep render fallback self-contained

* ci: retrigger hosted checks

* style(worklog): grow collapsed Worklog rail tap target to 44px on touch devices (#6454 follow-up)

* Release exp-v0.52.171: keep settled Worklog in place across stream settlement (#6454)

---------

Co-authored-by: Frank Song <franksong2702@gmail.com>
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
2026-08-07 18:06:57 -07:00
nesquena-hermes b337609b38 Release exp-v0.52.170: resolve @provider:model through shared parser at gateway boundary (#6723) 2026-08-07 23:09:55 +00:00
nesquena-hermes 207ce37eed Release exp-v0.52.169: expand dict-shaped custom-provider models in Providers card (#6774) 2026-08-07 22:36:48 +00:00
nesquena-hermes 19b85e84a1 Release exp-v0.52.168: classify Matrix gateway sessions as messaging (#6816) 2026-08-07 21:55:07 +00:00
nesquena-hermes afc3066ec0 Release exp-v0.52.167: close leaked state.db read-only connections (#6823) 2026-08-07 21:34:53 +00:00
nesquena-hermes e6e9dde276 changelog: #6498 gate memory/user-profile reads via nested config (re-gate) 2026-08-06 02:26:59 +00:00
nesquena-hermes 2673fd24e2 changelog: #6486 render final report alongside tool-limit card 2026-08-06 01:06:13 +00:00
nesquena-hermes 84ace41206 changelog: #6670 don't duplicate active turn user row on mid-run reload 2026-08-06 00:27:33 +00:00
nesquena-hermes 408d77a073 changelog: #6688 Force-recovery dirty stable no-ref checkout 2026-08-05 23:21:20 +00:00
nesquena-hermes 23d66d45ce changelog: #6663 OIDC allow_values whitespace warning 2026-08-05 22:54:04 +00:00