Commit graph

5 commits

Author SHA1 Message Date
Nathan Esquenazi
e8dbf94a6f fix(i18n+tests): complete locale parity + bump test windows for new menu action
PR #2294 added the show_previous_messaging_sessions setting and a "Hide
from list" menu action for external sessions, but tripped 8 tests:

  - 4 locale-parity tests (tests/test_{japanese,russian,spanish,chinese}_locale.py)
    demand every en key be defined in ja/ru/es/zh blocks. The contributor
    only added the 5 new keys to en + ko, leaving ja/ru/es/zh/it/de/zh-TW/pt/fr
    missing them. tests/test_provider_quota_status.py also requires the two
    settings_{label,desc}_previous_messaging_sessions keys in ALL 11 locales.

  - tests/test_1466_sidebar_cancel_clarify.py read the first 5200 chars of
    _openSessionActionMenu to find cancelSessionStream/delete actions; the
    new "Hide from list" branch (17 lines for external sessions) pushed
    those past the read window.

  - tests/test_issue1611_session_profile_filtering.py grep'd for the
    literal string `_keep_latest_messaging_session_per_source(scoped)`,
    which no longer exists after the call was rewritten as a multi-line
    keyword-arg form.

Fixes:

1. Translations for the 5 new i18n keys added to all 9 missing locales
   (it, ja, ru, es, de, zh-CN, zh-TW, pt, fr):
   - session_hide_external
   - session_hide_external_desc
   - session_hidden
   - settings_label_previous_messaging_sessions
   - settings_desc_previous_messaging_sessions

   Where the locale already used the English fallback for related keys
   (ru/es/de session_archive), I provided localized translations for the
   new keys to match the project's general direction. Native-script
   quality, not machine-translation.

2. test_1466 window bumped 5200 → 6400 with a comment explaining the
   bump (mirrors the existing 3200→4400→5200 history annotations).

3. test_1611 dedupe-position check loosened to match the function name
   without the `(scoped)` suffix so it tolerates both single-line and
   keyword-arg call shapes.

Tests: full suite 5828 passed / 63 skipped / 0 failed (was 8 failed).
Behavioral harness verifies the toggle's claimed behavior — off (default)
hides reset/compression segments, on shows all rows in timestamp order.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 21:38:06 -07:00
Frank Song
4e8899592d Prefer worktree retention responses in session UI 2026-05-12 10:17:12 +08:00
nesquena-hermes
f77a44fce2 feat(ux): three high-leverage context-menu essentials from #1764
Issue #1764 asked for a much larger surface (Reveal + Copy-path on
every UI surface that references a file path, plus Rename in session
menus). Per Nathan's curation we ship only the three highest-leverage
pieces in this PR — they cover the three concrete user-visible
frictions Cygnus reported, and leave the broader sweep for follow-up.

## 1. Copy file path in workspace tree right-click menu

The tree's right-click already had Rename and Reveal in File Manager.
Reveal is slow when the user just wants the path string for a
terminal/editor — and there was no Copy-path action anywhere.

Added "Copy file path" between Reveal and Delete. It POSTs to a new
`/api/file/path` endpoint that resolves the relative tree-rooted path
into the absolute on-disk path (the frontend can't compute it because
only the server knows the workspace root) and writes the result to
the OS clipboard via `navigator.clipboard.writeText()`. Falls back to
the legacy execCommand pattern on browsers where the modern Clipboard
API is gated.

The new endpoint deliberately does NOT require the target to exist:
copy-path on a recently-deleted file is still useful (paste into a
terminal to investigate). `safe_resolve` continues to gate path
traversal — the test suite pins this with a `../../../../../etc/passwd`
attempt that 400s.

## 2. Rename in session three-dot menu

Cygnus's specific ask: double-click rename in the sidebar is timing-
sensitive — the first click frequently registers as "open the chat"
before the second click arrives, so users open the conversation when
they meant to rename it. Putting Rename in the menu eliminates the
timing entirely.

Added Rename as the FIRST item in `_openSessionActionMenu` (above
Pin). It reuses the existing `startRename` closure attached to each
session row — no duplicated state, no second API call out of band
with the double-click path. Mechanism: the row builder now stores
`el._startRename = startRename` and `el.dataset.sid = s.session_id`,
so the menu can find the row by data-sid and call its closure
directly. This keeps all the `_renamingSid`/`oldTitle`/`applyTitle`
bookkeeping single-sourced.

Read-only imported sessions skip the menu item via the same
`_isReadOnlySession` gate the closure already uses.

## 3. Reveal-failed toast includes the resolved server-side path

Cygnus posted a screenshot of a "Failed to reveal: not found" toast
that dropped the path entirely. Without it the user can't tell which
file the system expected — useful when a stale session row still
references a deleted file.

Server-side fix in `_handle_file_reveal`: instead of returning
`bad(handler, "File not found", 404)`, return
`bad(handler, f"File not found: {target}", 404)` where target is the
resolved absolute path. Frontend toast also defends against err with
no .message: `(err.message||err)` instead of `err.message` alone.

Verified live: a missing-file reveal now produces:

    Failed to reveal: File not found: /home/hermes/workspace/missing-xyz.txt

Cygnus's exact diagnostic-friction is gone.

## Tests

* tests/test_1764_context_menu_essentials.py (new)
  - 13 source-level pinning tests
  - 6 live HTTP behaviour tests against the conftest test server

* tests/test_1466_sidebar_cancel_clarify.py
  - Two assertion-window bumps (3200→4400, 3600→4800) to accommodate
    the new Rename action prepended to _openSessionActionMenu. The
    test relied on a fixed-byte-window function-body slice — comments
    added explaining why the bumps were needed.

* All 9 locales got translations for the 5 new keys
  (copy_file_path, path_copied, path_copy_failed, session_rename,
  session_rename_desc) — locale parity tests pass.

## Verification

Full pytest suite: 4671 passed, 2 skipped, 3 xpassed (matches
pre-change baseline).

Live browser verification on port 8789:
- Right-click .git folder in workspace tree → menu shows
  Rename / Reveal in File Manager / Copy file path / Delete (red).
- Click Copy file path → clipboard gets "/home/hermes/workspace/.git",
  toast confirms "File path copied to clipboard".
- Open session three-dot menu → Rename conversation appears first
  with pencil icon, followed by Pin / Move / Archive / Duplicate /
  Delete in the same order as before.
- Trigger reveal on a non-existent file → toast reads
  "Failed to reveal: File not found: /home/hermes/workspace/<filename>".
  The resolved server-side path is now visible in the failure.

Refs nesquena/hermes-webui#1764.
2026-05-07 01:39:52 +00:00
Frank Song
79d0762d8c Filter low-value CLI agent sessions 2026-05-05 01:52:42 +00:00
Dennis Soong
cbb251b823 fix: add sidebar cancel for running sessions 2026-05-03 08:46:36 +08:00