Stage 382: PR #2503
This commit is contained in:
26
AGENTS.md
26
AGENTS.md
@@ -11,7 +11,8 @@ Before making changes, read:
|
|||||||
|
|
||||||
1. `README.md`
|
1. `README.md`
|
||||||
2. `CONTRIBUTING.md`
|
2. `CONTRIBUTING.md`
|
||||||
3. `CHANGELOG.md`
|
3. `docs/CONTRACTS.md`
|
||||||
|
4. `CHANGELOG.md`
|
||||||
|
|
||||||
For architecture, testing, or setup work, also read the matching reference:
|
For architecture, testing, or setup work, also read the matching reference:
|
||||||
|
|
||||||
@@ -19,6 +20,10 @@ For architecture, testing, or setup work, also read the matching reference:
|
|||||||
- `TESTING.md` for local verification commands and manual test guidance
|
- `TESTING.md` for local verification commands and manual test guidance
|
||||||
- `docs/onboarding.md` for first-run onboarding behavior
|
- `docs/onboarding.md` for first-run onboarding behavior
|
||||||
- `docs/troubleshooting.md` for diagnostic flows
|
- `docs/troubleshooting.md` for diagnostic flows
|
||||||
|
- `docs/rfcs/README.md` for larger RFCs and state/durability contracts
|
||||||
|
|
||||||
|
For UI or UX work, read `docs/UIUX-GUIDE.md` and `DESIGN.md` before
|
||||||
|
changing layout, interaction flow, themes, chat rendering, or composer chrome.
|
||||||
|
|
||||||
## Onboarding and reinstall support
|
## Onboarding and reinstall support
|
||||||
|
|
||||||
@@ -39,15 +44,22 @@ Follow that checklist's safety rules:
|
|||||||
|
|
||||||
## Contribution style
|
## Contribution style
|
||||||
|
|
||||||
- Keep changes focused on one logical problem.
|
- Keep one logical change per PR; split unrelated refactors or cleanup.
|
||||||
- Prefer the existing Python + vanilla JavaScript structure over new
|
- Read `docs/CONTRACTS.md` and the linked contract/RFC for the touched
|
||||||
dependencies or build steps.
|
subsystem before editing.
|
||||||
|
- Prefer the existing Python + vanilla JavaScript structure. Do not add
|
||||||
|
dependencies, build tools, frameworks, or long-lived processes without clear
|
||||||
|
justification and a rollback story.
|
||||||
- Update docs when changing setup, onboarding, runtime behavior, architecture,
|
- Update docs when changing setup, onboarding, runtime behavior, architecture,
|
||||||
or testing guidance.
|
testing guidance, or user-facing workflows.
|
||||||
- Update `CHANGELOG.md` for user-visible behavior, setup, workflow, or
|
- Update `CHANGELOG.md` for user-visible behavior, setup, workflow, or
|
||||||
documentation changes that should be release-note ready.
|
documentation changes that should be release-note ready.
|
||||||
- For UI or UX changes, follow `CONTRIBUTING.md`: include before/after evidence
|
- For UI or UX changes, include before/after evidence and test relevant
|
||||||
and test relevant responsive states.
|
desktop, narrow, and mobile states.
|
||||||
|
- For behavior changes, add or update automated tests where practical and list
|
||||||
|
the manual verification performed.
|
||||||
|
- For runtime, streaming, recovery, replay, compression, or sidebar metadata
|
||||||
|
changes, name the state layer being mutated and prove the relevant invariant.
|
||||||
|
|
||||||
## Local state and secrets
|
## Local state and secrets
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
- **PR #2499** by @franksong2702 — Keep server-idle session rows from inheriting stale local streaming fields during sidebar optimistic merging, so PWA/browser caches cannot keep a completed session's spinner alive after `/api/sessions` reports no active stream or pending user message.
|
- **PR #2499** by @franksong2702 — Keep server-idle session rows from inheriting stale local streaming fields during sidebar optimistic merging, so PWA/browser caches cannot keep a completed session's spinner alive after `/api/sessions` reports no active stream or pending user message.
|
||||||
- **PR #2501** (closes #1855) — Short-circuit the `resolve_model_provider` stage in `POST /api/chat/start` (and sibling chat-handler call sites) when the request already carries an explicit `(model, model_provider)` pair and the model isn't `@provider:model`-qualified. The new fast path in `_resolve_compatible_session_model_state()` returns the inputs verbatim without calling `get_available_models()` — that catalog rebuild can do network I/O (custom OpenAI-compat `/models`, OpenRouter `/models`, LM Studio probes, credential-pool refresh) under an RLock thundering-herd guard and was observed wedging a single request for 115 seconds in a production-grade local deployment. The recurrence captured via the PR #1911 stage diagnostics confirmed the wedge sat entirely in `resolve_model_provider` while every other stage completed in <5 ms. Users behind default-60s reverse proxies (nginx / Apache / Caddy / Cloudflare) were seeing a `502 Proxy Error` while the WebUI eventually completed the run anyway, creating a duplicate-send risk if the user retried in the browser. The slow path is preserved for the inputs that genuinely need it: bare/un-qualified models without a stored `model_provider` (cross-provider repair), `@provider:model`-qualified strings (active-provider validation per #1253), and empty models (default-model lookup). 14 new regression tests in `tests/test_issue1855_resolve_model_provider_fast_path.py` cover both directions — fast-path skips, slow-path still fires — including a static check that the short-circuit precedes the catalog call in source order.
|
- **PR #2501** (closes #1855) — Short-circuit the `resolve_model_provider` stage in `POST /api/chat/start` (and sibling chat-handler call sites) when the request already carries an explicit `(model, model_provider)` pair and the model isn't `@provider:model`-qualified. The new fast path in `_resolve_compatible_session_model_state()` returns the inputs verbatim without calling `get_available_models()` — that catalog rebuild can do network I/O (custom OpenAI-compat `/models`, OpenRouter `/models`, LM Studio probes, credential-pool refresh) under an RLock thundering-herd guard and was observed wedging a single request for 115 seconds in a production-grade local deployment. The recurrence captured via the PR #1911 stage diagnostics confirmed the wedge sat entirely in `resolve_model_provider` while every other stage completed in <5 ms. Users behind default-60s reverse proxies (nginx / Apache / Caddy / Cloudflare) were seeing a `502 Proxy Error` while the WebUI eventually completed the run anyway, creating a duplicate-send risk if the user retried in the browser. The slow path is preserved for the inputs that genuinely need it: bare/un-qualified models without a stored `model_provider` (cross-provider repair), `@provider:model`-qualified strings (active-provider validation per #1253), and empty models (default-model lookup). 14 new regression tests in `tests/test_issue1855_resolve_model_provider_fast_path.py` cover both directions — fast-path skips, slow-path still fires — including a static check that the short-circuit precedes the catalog call in source order.
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
- **PR #2503** by @franksong2702 (refs #2502) — Add `docs/CONTRACTS.md` as a public contributor-facing routing index that points UI/UX, runtime/state, and onboarding/setup changes to the relevant public docs (DESIGN.md, AGENTS.md, RFCs, troubleshooting) before contributors edit code or open PRs. Also adds `docs/UIUX-GUIDE.md` synthesizing the calm-developer-console UI/UX principles from DESIGN.md / README.md / THEMES.md / `docs/ui-ux/` into one contributor guide, refreshes the README and THEMES.md skin lists to cover all ten built-in skins (`catppuccin` + `nous`), and tightens the AGENTS.md / CONTRIBUTING.md contribution-style notes for state-layer and evidence requirements. Docs-only — no runtime or maintainer-policy changes.
|
||||||
|
|
||||||
## [v0.51.88] — 2026-05-18 — Release BL (stage-381 — 3-PR security + UX + lineage batch — session-bound CSRF tokens for unsafe browser requests + quoted-reply selected-text composer append + compression-continuation sidebar collapse)
|
## [v0.51.88] — 2026-05-18 — Release BL (stage-381 — 3-PR security + UX + lineage batch — session-bound CSRF tokens for unsafe browser requests + quoted-reply selected-text composer append + compression-continuation sidebar collapse)
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|||||||
@@ -4,6 +4,22 @@ Thanks for contributing.
|
|||||||
|
|
||||||
Hermes WebUI is intentionally simple to work on: Python on the server, vanilla JS in the browser, no build step, no bundler, no frontend framework. The best pull requests preserve that simplicity while solving a real problem cleanly.
|
Hermes WebUI is intentionally simple to work on: Python on the server, vanilla JS in the browser, no build step, no bundler, no frontend framework. The best pull requests preserve that simplicity while solving a real problem cleanly.
|
||||||
|
|
||||||
|
## Before You Start
|
||||||
|
|
||||||
|
- Read [`AGENTS.md`](AGENTS.md) if an AI assistant is doing or helping with the
|
||||||
|
change.
|
||||||
|
- Read [`docs/CONTRACTS.md`](docs/CONTRACTS.md) and any linked contract/RFC for
|
||||||
|
the subsystem you will touch.
|
||||||
|
- For UI or UX work, read [`docs/UIUX-GUIDE.md`](docs/UIUX-GUIDE.md)
|
||||||
|
and [`DESIGN.md`](DESIGN.md).
|
||||||
|
- For runtime, streaming, recovery, replay, compression, context reconstruction,
|
||||||
|
or session metadata work, start with [`docs/rfcs/README.md`](docs/rfcs/README.md)
|
||||||
|
and the relevant RFC listed there.
|
||||||
|
|
||||||
|
Use those documents as review guardrails: keep the change scoped, preserve the
|
||||||
|
no-build-step architecture, update docs/changelog when behavior changes, include
|
||||||
|
UI evidence for UI changes, and add tests for behavior changes where practical.
|
||||||
|
|
||||||
## Two Paths to a Strong Pull Request
|
## Two Paths to a Strong Pull Request
|
||||||
|
|
||||||
### Path 1: Small, Focused Changes
|
### Path 1: Small, Focused Changes
|
||||||
@@ -60,7 +76,7 @@ There is currently no PR template in this repo, so include the important section
|
|||||||
|
|
||||||
If the change is user-visible, include screenshots or a short video.
|
If the change is user-visible, include screenshots or a short video.
|
||||||
|
|
||||||
For UI or UX changes, before/after images are required. PRs that change the interface or interaction flow without before/after images will likely be ignored, or closed in a regular maintainer sweep without review.
|
For UI or UX changes, before/after images are required. PRs that change the interface or interaction flow without before/after images may not receive meaningful review until that evidence is added.
|
||||||
|
|
||||||
### 4. AI Usage Disclosure
|
### 4. AI Usage Disclosure
|
||||||
|
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -467,10 +467,13 @@ Production data and real cron jobs are never touched. Current snapshot:
|
|||||||
- CDN resources pinned with SRI integrity hashes
|
- CDN resources pinned with SRI integrity hashes
|
||||||
|
|
||||||
### Themes
|
### Themes
|
||||||
- 7 built-in themes: Dark (default), Light, Slate, Solarized Dark, Monokai, Nord, OLED
|
- Appearance is split into two axes: Theme (`system`, `dark`, `light`) and Skin
|
||||||
- Switch via Settings panel dropdown (instant live preview) or `/theme` command
|
(`default`, `ares`, `mono`, `slate`, `poseidon`, `sisyphus`, `charizard`,
|
||||||
|
`sienna`, `catppuccin`, `nous`)
|
||||||
|
- Switch via Settings -> Appearance (instant live preview) or `/theme <theme-or-skin>`
|
||||||
- Persists across reloads (server-side in settings.json + localStorage for flicker-free loading)
|
- Persists across reloads (server-side in settings.json + localStorage for flicker-free loading)
|
||||||
- Custom themes: define a `:root[data-theme="name"]` CSS block and it works — see [THEMES.md](THEMES.md)
|
- Skins use `data-skin` plus CSS variables; dark mode resolves through the
|
||||||
|
`.dark` class, not a `data-theme` custom-theme axis — see [THEMES.md](THEMES.md)
|
||||||
|
|
||||||
### Settings and configuration
|
### Settings and configuration
|
||||||
- **Hermes Control Center** (sidebar launcher button) -- Conversation tab (export/import/clear), Preferences tab (model, send key, theme, language, all toggles), System tab (version, password)
|
- **Hermes Control Center** (sidebar launcher button) -- Conversation tab (export/import/clear), Preferences tab (model, send key, theme, language, all toggles), System tab (version, password)
|
||||||
@@ -556,6 +559,8 @@ State lives outside the repo at `~/.hermes/webui/` by default
|
|||||||
- `CHANGELOG.md` -- release notes per sprint
|
- `CHANGELOG.md` -- release notes per sprint
|
||||||
- `SPRINTS.md` -- forward sprint plan with CLI + Claude parity targets
|
- `SPRINTS.md` -- forward sprint plan with CLI + Claude parity targets
|
||||||
- `THEMES.md` -- theme system documentation, custom theme guide
|
- `THEMES.md` -- theme system documentation, custom theme guide
|
||||||
|
- `docs/CONTRACTS.md` -- project contract/RFC/design index for contributors and agents
|
||||||
|
- `docs/UIUX-GUIDE.md` -- UI/UX principles sourced from existing design docs and visual inventories
|
||||||
- `docs/docker.md` -- Docker compose setup, common failures, and bind-mount migration
|
- `docs/docker.md` -- Docker compose setup, common failures, and bind-mount migration
|
||||||
- `docs/supervisor.md` -- launchd, systemd, supervisord, runit, and s6 process-supervisor setup
|
- `docs/supervisor.md` -- launchd, systemd, supervisord, runit, and s6 process-supervisor setup
|
||||||
- `docs/onboarding.md` -- first-run wizard, provider setup, local model server Base URLs, and safe re-runs
|
- `docs/onboarding.md` -- first-run wizard, provider setup, local model server Base URLs, and safe re-runs
|
||||||
|
|||||||
11
THEMES.md
11
THEMES.md
@@ -4,7 +4,7 @@ Hermes Web UI splits **appearance** into two independent pickers:
|
|||||||
|
|
||||||
- **Theme** — the mode: `System`, `Dark`, or `Light`. Drives the background,
|
- **Theme** — the mode: `System`, `Dark`, or `Light`. Drives the background,
|
||||||
text, surface, and chrome colors.
|
text, surface, and chrome colors.
|
||||||
- **Skin** — the accent palette: eight named skins ship built-in. Drives only
|
- **Skin** — the accent palette: ten named skins ship built-in. Drives only
|
||||||
the `--accent` family (active states, links, focus rings, primary actions).
|
the `--accent` family (active states, links, focus rings, primary actions).
|
||||||
|
|
||||||
You pick one of each and they combine, so the look adapts to your environment
|
You pick one of each and they combine, so the look adapts to your environment
|
||||||
@@ -15,13 +15,14 @@ without losing your favorite accent — pure CSS, no Python changes needed.
|
|||||||
## Switching Appearance
|
## Switching Appearance
|
||||||
|
|
||||||
**Settings panel:** Click the gear icon → **Appearance**. The **Theme** card
|
**Settings panel:** Click the gear icon → **Appearance**. The **Theme** card
|
||||||
toggles Light/Dark/System; the **Skin** grid offers eight accent palettes.
|
toggles Light/Dark/System; the **Skin** grid offers ten accent palettes.
|
||||||
Preview is instant — the UI updates as you click.
|
Preview is instant — the UI updates as you click.
|
||||||
|
|
||||||
**Slash command:** Type `/theme <name>` in the composer. The command accepts
|
**Slash command:** Type `/theme <name>` in the composer. The command accepts
|
||||||
both theme names (`system`, `dark`, `light`) and skin names (`default`, `ares`,
|
both theme names (`system`, `dark`, `light`) and skin names (`default`, `ares`,
|
||||||
`mono`, `slate`, `poseidon`, `sisyphus`, `charizard`, `sienna`). It updates the
|
`mono`, `slate`, `poseidon`, `sisyphus`, `charizard`, `sienna`,
|
||||||
matching axis and leaves the other one alone.
|
`catppuccin`, `nous`). It updates the matching axis and leaves the other one
|
||||||
|
alone.
|
||||||
|
|
||||||
**Persistence:** Both choices are stored in `localStorage` for flicker-free
|
**Persistence:** Both choices are stored in `localStorage` for flicker-free
|
||||||
loading, and saved server-side via `POST /api/settings` (under `theme` and
|
loading, and saved server-side via `POST /api/settings` (under `theme` and
|
||||||
@@ -54,6 +55,8 @@ absent for light. System mode tracks the OS preference at runtime.
|
|||||||
| **Sisyphus** | Vivid purple. Distinctive without being loud. |
|
| **Sisyphus** | Vivid purple. Distinctive without being loud. |
|
||||||
| **Charizard** | Warm orange. Energetic and easy on the eyes. |
|
| **Charizard** | Warm orange. Energetic and easy on the eyes. |
|
||||||
| **Sienna** | Warm clay and sand earth palette. Soft and natural. |
|
| **Sienna** | Warm clay and sand earth palette. Soft and natural. |
|
||||||
|
| **Catppuccin** | Catppuccin Latte/Mocha palette with Mauve accent. |
|
||||||
|
| **Nous** | Steel-blue accent with dashed technical surfaces. |
|
||||||
|
|
||||||
Each skin defines paired light + dark variants so it reads cleanly on either
|
Each skin defines paired light + dark variants so it reads cleanly on either
|
||||||
theme. The skin is applied as `data-skin="<name>"` on `<html>` (the default
|
theme. The skin is applied as `data-skin="<name>"` on `<html>` (the default
|
||||||
|
|||||||
173
docs/CONTRACTS.md
Normal file
173
docs/CONTRACTS.md
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
# Project Contracts
|
||||||
|
|
||||||
|
This document is a contributor-facing index for existing Hermes WebUI contracts,
|
||||||
|
RFCs, design constraints, and review expectations. It does not replace the
|
||||||
|
source documents and it does not mark proposals as implemented. Follow each
|
||||||
|
linked document's status and scope.
|
||||||
|
|
||||||
|
Use this file when starting a change so the relevant public contract is visible
|
||||||
|
before code is edited. This first version focuses on documentation routing; it
|
||||||
|
does not change runtime behavior, maintainer policy, bot behavior, or CI gates.
|
||||||
|
|
||||||
|
## Start here
|
||||||
|
|
||||||
|
- [`AGENTS.md`](../AGENTS.md): repository entry point for AI assistants,
|
||||||
|
public-safety rules, and the short redline checklist.
|
||||||
|
- [`CONTRIBUTING.md`](../CONTRIBUTING.md): contribution style, verification,
|
||||||
|
PR description expectations, UI evidence, and project-specific constraints.
|
||||||
|
- [`README.md`](../README.md): product overview, quick start, architecture map,
|
||||||
|
feature inventory, and docs index.
|
||||||
|
- [`CHANGELOG.md`](../CHANGELOG.md): release-note-ready history. Update it when
|
||||||
|
maintainers should carry the change into release notes.
|
||||||
|
|
||||||
|
## Runtime, durability, and state contracts
|
||||||
|
|
||||||
|
- [`docs/rfcs/webui-run-state-consistency-contract.md`](rfcs/webui-run-state-consistency-contract.md):
|
||||||
|
proposed consistency rules for current WebUI streaming, recovery, replay,
|
||||||
|
model-context reconstruction, compression, UI scene/cache, and sidebar metadata
|
||||||
|
repairs. Start here for narrow fixes that keep the existing WebUI execution
|
||||||
|
path.
|
||||||
|
- [`docs/rfcs/hermes-run-adapter-contract.md`](rfcs/hermes-run-adapter-contract.md):
|
||||||
|
proposed event/control contract, runtime-state ownership matrix,
|
||||||
|
acceptance-test catalog, and reversible migration gates for moving WebUI
|
||||||
|
execution behind an adapter boundary. Use this for adapter-seam, control-plane,
|
||||||
|
runner, sidecar, or execution-ownership work; do not treat it as authorization
|
||||||
|
to implement those slices.
|
||||||
|
- [`docs/rfcs/turn-journal.md`](rfcs/turn-journal.md): proposed crash-safe
|
||||||
|
write-ahead journal for browser-originated chat turns.
|
||||||
|
- [`docs/rfcs/README.md`](rfcs/README.md): RFC conventions and current RFC index.
|
||||||
|
|
||||||
|
When a change touches streaming, recovery, replay, compression, context
|
||||||
|
reconstruction, cancellation, approval/clarify, session metadata, or run state,
|
||||||
|
read the relevant RFC before editing. In the PR description, name the state layer
|
||||||
|
or event/control surface affected and include a regression test or manual
|
||||||
|
verification for the relevant invariant.
|
||||||
|
|
||||||
|
Proposed RFCs are review guardrails, not implementation authorization. Do not
|
||||||
|
implement RFC fragments unless the task or tracking issue explicitly asks for
|
||||||
|
that slice.
|
||||||
|
|
||||||
|
## UI, UX, and theme contracts
|
||||||
|
|
||||||
|
- [`DESIGN.md`](../DESIGN.md): design tokens and the current calm-console
|
||||||
|
direction: conversation first, quiet metadata, restrained accents, and
|
||||||
|
progressive disclosure for debugging detail.
|
||||||
|
- [`docs/UIUX-GUIDE.md`](UIUX-GUIDE.md): contributor-facing synthesis of the
|
||||||
|
repository's UI/UX principles, sourced from existing project docs and code
|
||||||
|
comments.
|
||||||
|
- [`docs/ui-ux/index.html`](ui-ux/index.html): message-area inventory wired to
|
||||||
|
the real app stylesheet.
|
||||||
|
- [`docs/ui-ux/two-stage-proposal.html`](ui-ux/two-stage-proposal.html):
|
||||||
|
existing two-stage chat UX proposal for issue #536.
|
||||||
|
- [`THEMES.md`](../THEMES.md): theme and skin guidance; the core palette
|
||||||
|
variable contract lives in `static/style.css`.
|
||||||
|
|
||||||
|
Current appearance has a theme axis (`light`, `dark`, `system`) and a separate
|
||||||
|
skin axis (`default`, `ares`, `mono`, `slate`, `poseidon`, `sisyphus`,
|
||||||
|
`charizard`, `sienna`, `catppuccin`, `nous`) in `static/boot.js` and
|
||||||
|
`static/style.css`. Do not follow stale `data-theme`-only theme guidance unless
|
||||||
|
the current code and tests prove that model still applies.
|
||||||
|
|
||||||
|
For UI or UX work, include before/after evidence, verify relevant responsive
|
||||||
|
states, and prefer stable class/data hooks over one-off visual behavior.
|
||||||
|
|
||||||
|
## Choosing the relevant contract
|
||||||
|
|
||||||
|
Before editing, identify which contract family the task exercises. This is a
|
||||||
|
routing check, not a request to read every document in the repository. Read the
|
||||||
|
documents that match the touched subsystem.
|
||||||
|
|
||||||
|
Use this lightweight note in an issue comment, draft PR, task note, or AI-agent
|
||||||
|
handoff when it helps clarify scope:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Contract Routing
|
||||||
|
|
||||||
|
Task type:
|
||||||
|
Touched areas:
|
||||||
|
Relevant public docs:
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `CONTRIBUTING.md`
|
||||||
|
- `docs/CONTRACTS.md`
|
||||||
|
- <subsystem-specific documents>
|
||||||
|
Scope boundaries:
|
||||||
|
Evidence needed before claiming done:
|
||||||
|
```
|
||||||
|
|
||||||
|
For small, obvious fixes, keep this short. The goal is to avoid routing mistakes,
|
||||||
|
not to create process overhead.
|
||||||
|
|
||||||
|
## PR preparation checklist
|
||||||
|
|
||||||
|
Before opening or updating a PR, verify `CONTRIBUTING.md` against the actual PR
|
||||||
|
body. This checklist applies even when code and tests are already done.
|
||||||
|
|
||||||
|
Required checks:
|
||||||
|
|
||||||
|
- The PR solves one logical problem.
|
||||||
|
- The PR body contains all required sections from `CONTRIBUTING.md`:
|
||||||
|
`Thinking Path`, `What Changed`, `Why It Matters`, `Verification`,
|
||||||
|
`Risks / Follow-ups`, and `Model Used`.
|
||||||
|
- `Model Used` discloses provider/model and notable agent/tool use, or says
|
||||||
|
`None -- human-authored`.
|
||||||
|
- UI/UX changes include before/after evidence and responsive-state coverage.
|
||||||
|
- Runtime/streaming changes name the state layer or invariant being changed and
|
||||||
|
list the regression or manual invariant check.
|
||||||
|
- Onboarding/setup validation used isolated `HERMES_HOME` and
|
||||||
|
`HERMES_WEBUI_STATE_DIR`, unless the human operator explicitly requested real
|
||||||
|
state.
|
||||||
|
- Docs and `CHANGELOG.md` updates are either included or explicitly not needed.
|
||||||
|
- After the GitHub write, read the PR back and verify the headings rendered as
|
||||||
|
intended.
|
||||||
|
|
||||||
|
Green CI plus a focused diff is not sufficient if the PR description or evidence
|
||||||
|
does not match the touched subsystem.
|
||||||
|
|
||||||
|
## Setup, onboarding, and operational references
|
||||||
|
|
||||||
|
- [`TESTING.md`](../TESTING.md): automated test command and manual browser test
|
||||||
|
plan.
|
||||||
|
- [`ARCHITECTURE.md`](../ARCHITECTURE.md): API, module layout, and design
|
||||||
|
constraints.
|
||||||
|
- [`docs/onboarding.md`](onboarding.md): first-run wizard and provider setup.
|
||||||
|
- [`docs/onboarding-agent-checklist.md`](onboarding-agent-checklist.md): safety
|
||||||
|
rules for assistant-led install, reinstall, bootstrap, provider setup, local
|
||||||
|
model setup, Docker onboarding, and WSL onboarding.
|
||||||
|
- [`docs/docker.md`](docker.md): Docker compose setup, common failures, and
|
||||||
|
bind-mount migration.
|
||||||
|
- [`docs/troubleshooting.md`](troubleshooting.md): diagnostic flows for common
|
||||||
|
failures.
|
||||||
|
- [`docs/EXTENSIONS.md`](EXTENSIONS.md): administrator-controlled WebUI
|
||||||
|
extension injection.
|
||||||
|
|
||||||
|
## Quick redline checklist
|
||||||
|
|
||||||
|
Before opening a change for review, confirm:
|
||||||
|
|
||||||
|
- The change solves one logical problem; unrelated refactors are split out.
|
||||||
|
- `AGENTS.md`, this index, and any linked contract for the touched subsystem were
|
||||||
|
read before editing.
|
||||||
|
- Behavior, setup, architecture, testing, or workflow changes update the relevant
|
||||||
|
docs; release-note-ready changes update `CHANGELOG.md`.
|
||||||
|
- UI/UX changes include before/after evidence and cover relevant desktop,
|
||||||
|
narrow, and mobile states.
|
||||||
|
- Runtime, streaming, recovery, replay, compression, or sidebar changes state
|
||||||
|
which layer they mutate and include a regression for the invariant.
|
||||||
|
- New dependencies, build tools, frameworks, or long-lived processes are avoided
|
||||||
|
unless the benefit and rollback story are explicit.
|
||||||
|
- Onboarding/setup validation uses isolated `HERMES_HOME` and
|
||||||
|
`HERMES_WEBUI_STATE_DIR` unless the human operator explicitly asks to use real
|
||||||
|
state.
|
||||||
|
- Secrets, private paths, local-only workflows, and personal notes stay out of
|
||||||
|
tracked docs and examples.
|
||||||
|
|
||||||
|
## Future evolution
|
||||||
|
|
||||||
|
This index is not intended to make the first contract set final. Future PRs may
|
||||||
|
add, revise, split, or retire contracts when real issues, implementation changes,
|
||||||
|
RFC decisions, contributor feedback, or review experience show that guidance is
|
||||||
|
incomplete or stale.
|
||||||
|
|
||||||
|
Potential follow-up areas include session import/export, cron, extensions,
|
||||||
|
security boundaries, Docker/runtime isolation, and lightweight checks that keep
|
||||||
|
key contract links from drifting.
|
||||||
191
docs/UIUX-GUIDE.md
Normal file
191
docs/UIUX-GUIDE.md
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
# UI/UX Guide
|
||||||
|
|
||||||
|
This document summarizes UI/UX principles that are already visible in the
|
||||||
|
repository. It is a contributor guide, not a new design proposal. Source
|
||||||
|
documents include [`DESIGN.md`](../DESIGN.md), [`README.md`](../README.md),
|
||||||
|
[`THEMES.md`](../THEMES.md), [`docs/ui-ux/index.html`](ui-ux/index.html),
|
||||||
|
[`docs/ui-ux/two-stage-proposal.html`](ui-ux/two-stage-proposal.html), and
|
||||||
|
design comments in `static/style.css`.
|
||||||
|
|
||||||
|
Use this guide when a change touches layout, chat rendering, composer chrome,
|
||||||
|
navigation, theme/skin behavior, responsive behavior, or visual hierarchy. For
|
||||||
|
purely backend changes, use the runtime/state contracts instead.
|
||||||
|
|
||||||
|
## Product shape
|
||||||
|
|
||||||
|
Hermes WebUI is a browser workbench for Hermes Agent with near-CLI parity and a
|
||||||
|
simple implementation shape: Python on the server, vanilla JavaScript in the
|
||||||
|
browser, no build step, no bundler, and no frontend framework.
|
||||||
|
|
||||||
|
The primary layout is three-panel:
|
||||||
|
|
||||||
|
- left sidebar for sessions and navigation,
|
||||||
|
- center panel for chat,
|
||||||
|
- right panel for workspace file browsing and previews.
|
||||||
|
|
||||||
|
Model, profile, workspace, attachments, voice input, context usage, Stop, and
|
||||||
|
Send controls live in the composer footer. Settings and session-level tools live
|
||||||
|
in the Hermes Control Center. Preserve this shape unless the change explicitly
|
||||||
|
justifies a different interaction model.
|
||||||
|
|
||||||
|
## Core feeling: calm developer console
|
||||||
|
|
||||||
|
The main artifact is the conversation. Tool calls, thinking traces, context
|
||||||
|
compaction records, token usage, runtime status, and other internals are useful,
|
||||||
|
but they are transcript metadata. They should sit below user and assistant prose
|
||||||
|
in visual priority.
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
- quiet surfaces,
|
||||||
|
- clear spacing,
|
||||||
|
- restrained accent use,
|
||||||
|
- progressive disclosure for debugging detail,
|
||||||
|
- legible text over decorative chrome.
|
||||||
|
|
||||||
|
Avoid turning the interface into a demo page of colorful cards. Errors,
|
||||||
|
approvals, and other action-required states may be prominent because the user
|
||||||
|
must notice and respond to them.
|
||||||
|
|
||||||
|
## Conversation hierarchy
|
||||||
|
|
||||||
|
A chat turn should read as one coherent story:
|
||||||
|
|
||||||
|
1. User message: right-aligned, compact bubble.
|
||||||
|
2. Assistant content: left-aligned, prose-first, not a heavy bubble.
|
||||||
|
3. Tool, thinking, progress, and context traces: quiet disclosure rows inside or
|
||||||
|
adjacent to the assistant turn.
|
||||||
|
4. Raw logs and verbose details: hidden until explicitly expanded.
|
||||||
|
|
||||||
|
Do not render every internal event as a first-class chat card. A turn that used
|
||||||
|
many tools should summarize the work as inspectable activity, not make the user
|
||||||
|
read a stack of unrelated-looking cards.
|
||||||
|
|
||||||
|
## Tool, thinking, and activity traces
|
||||||
|
|
||||||
|
Tool cards are debug event rows, not chat messages. Show the icon, name, short
|
||||||
|
target or preview, and status first. Arguments, result snippets, and long logs
|
||||||
|
belong behind expansion, with result snippets truncated and full output behind a
|
||||||
|
show-more affordance where needed.
|
||||||
|
|
||||||
|
Thinking and context cards should share the quiet metadata visual family. They
|
||||||
|
should not overpower assistant prose. Collapsed activity summaries should be
|
||||||
|
terse, for example `Activity: 4 tools`, and should not duplicate the thinking
|
||||||
|
area, list every tool name in the summary, or add redundant trailing count
|
||||||
|
badges.
|
||||||
|
|
||||||
|
The existing two-stage proposal in `docs/ui-ux/two-stage-proposal.html` records a
|
||||||
|
compatible direction for long turns: live work can be grouped as a worklog, then
|
||||||
|
settled history can collapse while the final answer reads as the calm
|
||||||
|
conclusion. Treat that page as an existing proposal, not as shipped behavior
|
||||||
|
unless the code and tests prove it is implemented.
|
||||||
|
|
||||||
|
## Typography and content
|
||||||
|
|
||||||
|
Use split typography intentionally:
|
||||||
|
|
||||||
|
- assistant prose uses the same system sans stack as the rest of the UI by
|
||||||
|
default (`--font-ui` in `static/style.css`),
|
||||||
|
- editorial serif assistant prose is historical/proposal or skin-scoped only;
|
||||||
|
do not reintroduce a global assistant serif without explicit design approval
|
||||||
|
plus code and test evidence,
|
||||||
|
- user bubbles and functional UI also use the system sans stack unless a scoped
|
||||||
|
skin intentionally overrides typography,
|
||||||
|
- monospace is for code, file paths, commands, tool names, and compact metadata.
|
||||||
|
|
||||||
|
Keep scale tight. Avoid introducing near-duplicate one-off font sizes, colors,
|
||||||
|
radius values, or spacing values when an existing token works.
|
||||||
|
|
||||||
|
## Color, depth, and shape
|
||||||
|
|
||||||
|
Use one accent at a time. Semantic colors are for semantic state: success,
|
||||||
|
warning, error, and info. Do not mix many bright colors decoratively in the same
|
||||||
|
viewport.
|
||||||
|
|
||||||
|
Use almost no shadows in the transcript. Reserve shadows for popovers,
|
||||||
|
dropdowns, modals, and floating controls. Chat cards should usually use either a
|
||||||
|
subtle border or a subtle tint, not aggressive combinations of both.
|
||||||
|
|
||||||
|
Avoid stacks of nested rounded rectangles. Rows and list items should feel
|
||||||
|
compact; panels and cards may be slightly rounder; true pills are reserved for
|
||||||
|
chips and badges.
|
||||||
|
|
||||||
|
## Composer and controls
|
||||||
|
|
||||||
|
The composer is the command surface. Keep it legible, stable, and focused:
|
||||||
|
|
||||||
|
- no theatrical hover scaling for routine controls,
|
||||||
|
- no ambient chrome that crowds the model/workspace/profile controls,
|
||||||
|
- no new footer buttons on tight layouts without a clear value tradeoff,
|
||||||
|
- keep Stop/Send and context feedback easy to find while composing.
|
||||||
|
|
||||||
|
When adding a control, consider where users will find it on both wide desktop and
|
||||||
|
mobile. If a setting or quota/control surface does not fit in the composer, route
|
||||||
|
it through the appropriate Control Center panel instead of squeezing the footer.
|
||||||
|
|
||||||
|
## Responsive behavior
|
||||||
|
|
||||||
|
Mobile is not an afterthought. The repository documents a responsive layout with
|
||||||
|
a hamburger sidebar, mobile-accessible top tabs, a right-edge file slide-over,
|
||||||
|
full-height chat/composer behavior on phones, and touch-friendly controls.
|
||||||
|
|
||||||
|
For UI changes, verify the relevant states:
|
||||||
|
|
||||||
|
- wide desktop,
|
||||||
|
- ordinary laptop width,
|
||||||
|
- narrow/mobile width,
|
||||||
|
- open and closed side panels when relevant,
|
||||||
|
- long chat content and live streaming when relevant.
|
||||||
|
|
||||||
|
Controls should remain usable at touch sizes, and mobile navigation should not
|
||||||
|
steal chat height unnecessarily.
|
||||||
|
|
||||||
|
## Themes and skins
|
||||||
|
|
||||||
|
Theme and skin work should use the existing variable system. `THEMES.md` points
|
||||||
|
to the core palette variables in `static/style.css`; skin comments in the CSS
|
||||||
|
show the expected pattern for full palette rewrites and accent-only changes.
|
||||||
|
|
||||||
|
Current implementation has two appearance axes, sourced from `static/boot.js`:
|
||||||
|
`theme` is only `light`, `dark`, or `system` and resolves to the `.dark` class
|
||||||
|
for dark mode; `skin` is a separate axis applied with `data-skin` and currently
|
||||||
|
includes `default`, `ares`, `mono`, `slate`, `poseidon`, `sisyphus`,
|
||||||
|
`charizard`, `sienna`, `catppuccin`, and `nous`. `slate` is both an active skin
|
||||||
|
and a legacy theme-name migration target; `solarized`, `monokai`, `nord`, and
|
||||||
|
`oled` are legacy theme names mapped to current theme/skin pairs. Do not follow
|
||||||
|
stale `data-theme`-only guidance without first proving the current
|
||||||
|
`static/boot.js`, `static/index.html`, and `static/style.css` contracts still
|
||||||
|
support it.
|
||||||
|
|
||||||
|
Do not hardcode new colors, radii, shadows, or typography values into isolated
|
||||||
|
components when a token or existing variable can carry the intent. If a token is
|
||||||
|
missing, explain why a new one is needed.
|
||||||
|
|
||||||
|
## Evidence expected for UI changes
|
||||||
|
|
||||||
|
For any interface or interaction change:
|
||||||
|
|
||||||
|
- include before/after images or a short video,
|
||||||
|
- mention the tested viewport sizes and responsive states,
|
||||||
|
- reference the affected visual inventory or design source when applicable,
|
||||||
|
- add or update tests for behavior, state persistence, or regression-prone DOM
|
||||||
|
structure where practical,
|
||||||
|
- keep stable class or data hooks when they help future visual regression tests.
|
||||||
|
|
||||||
|
## Do / don't summary
|
||||||
|
|
||||||
|
Do:
|
||||||
|
|
||||||
|
- keep the conversation primary,
|
||||||
|
- collapse noisy internals by default when settled,
|
||||||
|
- make debugging details accessible without making them visually dominant,
|
||||||
|
- use existing tokens, variables, and component patterns,
|
||||||
|
- protect action-required states such as errors and approvals.
|
||||||
|
|
||||||
|
Don't:
|
||||||
|
|
||||||
|
- make every tool call look like a separate chat message,
|
||||||
|
- add decorative color or motion without a user-facing reason,
|
||||||
|
- introduce a frontend framework, bundler, or build step for ordinary UI work,
|
||||||
|
- hide important recovery, error, or approval state,
|
||||||
|
- treat proposal mockups as shipped behavior without code/test evidence.
|
||||||
@@ -42,7 +42,14 @@ docker compose up -d
|
|||||||
open http://localhost:8787
|
open http://localhost:8787
|
||||||
```
|
```
|
||||||
|
|
||||||
That's it. Your existing `~/.hermes` directory is mounted, your `~/workspace` is browsable, and the WebUI auto-detects your UID/GID from the mounted volume.
|
That's it for a real personal Docker install. Your existing `~/.hermes`
|
||||||
|
directory is mounted, your `~/workspace` is browsable, and the WebUI
|
||||||
|
auto-detects your UID/GID from the mounted volume.
|
||||||
|
|
||||||
|
For troubleshooting, reinstall, or onboarding reproduction trials, do not mount
|
||||||
|
your real `~/.hermes` unless you intentionally want to test real state. Use an
|
||||||
|
isolated Hermes home and follow
|
||||||
|
[`docs/onboarding-agent-checklist.md`](onboarding-agent-checklist.md) instead.
|
||||||
|
|
||||||
## What goes wrong (and how to fix it)
|
## What goes wrong (and how to fix it)
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,11 @@ runtime boundary instead of remaining scattered through the main WebUI request
|
|||||||
process.
|
process.
|
||||||
|
|
||||||
This document is intentionally a reviewable spec and migration gate. It should be
|
This document is intentionally a reviewable spec and migration gate. It should be
|
||||||
accepted before any implementation PR changes the streaming hot path, introduces a
|
accepted before any implementation PR for this adapter direction changes the
|
||||||
runner process, or moves a new approval / clarify / queue / goal control path.
|
streaming hot path, introduces a runner process, or moves a new approval /
|
||||||
|
clarify / queue / goal control path. Narrow current-path bug fixes that do not
|
||||||
|
introduce a new runtime boundary can still proceed under the WebUI run-state
|
||||||
|
consistency contract and the relevant issue scope.
|
||||||
|
|
||||||
## Problem
|
## Problem
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Concrete diagnostic flows for the most common failure modes when running Hermes WebUI. Each entry has the symptom, the diagnostic commands you should run *before* opening an issue, and the fix that has worked for past reporters.
|
Concrete diagnostic flows for the most common failure modes when running Hermes WebUI. Each entry has the symptom, the diagnostic commands you should run *before* opening an issue, and the fix that has worked for past reporters.
|
||||||
|
|
||||||
If your symptom isn't listed and the diagnostics don't narrow it down, file a bug at https://github.com/nesquena/hermes-webui/issues — include the **full output** of every command in the relevant section.
|
If your symptom isn't listed and the diagnostics don't narrow it down, file a bug at https://github.com/nesquena/hermes-webui/issues — include the relevant command output after redacting secrets, private paths, full `.env` files, full `auth.json` files, cookies, tokens, and password hashes.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user