diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 8f6e5abb..7e586f2c 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -45,51 +45,63 @@ actions. The topbar remains focused on conversation context and the workspace/fi ## 2. File Inventory / - server.py Thin routing shell + HTTP Handler + auth middleware. ~446 lines. + server.py Thin routing shell + HTTP Handler + auth middleware. Delegates all route handling to api/routes.py. bootstrap.py One-shot launcher: optional agent install, deps, health wait, browser open. start.sh Thin wrapper around bootstrap.py for shell-based startup. - Dockerfile python:3.12-slim container image (~89 lines) - docker-compose.yml Compose config with named volume and optional auth (~57 lines) + ctl.sh Daemon lifecycle wrapper (start/stop/restart/status/logs) for homelab installs. + pyproject.toml Tooling config (ruff lint gate). NOT a packaged distribution. + Dockerfile python:3.12-slim container image + docker-compose.yml Compose config with named volume and optional auth .dockerignore Excludes .git, tests/, .env* from Docker builds api/ __init__.py Package marker - auth.py Optional password authentication, signed cookies (~366 lines) - config.py Discovery, globals, model detection, reloadable config (~4139 lines) - helpers.py HTTP helpers: j(), bad(), require(), safe_resolve(), security headers (~302 lines) - models.py Session model + CRUD, per-session profile tracking (~1927 lines) - profiles.py Profile state management, hermes_cli wrapper (~1056 lines) - onboarding.py First-run onboarding status, real provider config writes, OAuth linking, and readiness detection (~1002 lines) - routes.py All GET + POST route handlers (~9772 lines) - startup.py Startup helpers: auto_install_agent_deps() (~128 lines) - streaming.py SSE engine, run_agent, cancel, HERMES_HOME save/restore (~4420 lines) - upload.py Multipart parser, file upload handler (~284 lines) - workspace.py File ops: list_dir, read_file_content, workspace helpers (~810 lines) + auth.py Optional password authentication, signed cookies, passkeys/WebAuthn + config.py Discovery, globals, model detection, reloadable config + helpers.py HTTP helpers: j(), bad(), require(), safe_resolve(), security headers + models.py Session model + CRUD, per-session profile tracking, CLI/state.db bridge + profiles.py Profile state management, hermes_cli wrapper + onboarding.py First-run onboarding status, real provider config writes, OAuth linking, readiness detection + routes.py All GET + POST route handlers (if/elif dispatch, no decorators) + startup.py Startup helpers: auto_install_agent_deps() + state_sync.py /insights sync — message_count to the agent's state.db + streaming.py SSE engine, run_agent, cancel, compression, HERMES_HOME save/restore + updates.py Self-update check and release notes + upload.py Multipart parser, file upload handler + workspace.py File ops: list_dir, read_file_content, git detection, workspace helpers static/ - index.html HTML template (~1323 lines) - style.css All CSS incl. mobile responsive (~3767 lines) - ui.js DOM helpers, renderMd, tool cards, model dropdown, file tree (~7216 lines) - workspace.js File preview, file ops, loadDir, clearPreview (~369 lines) - sessions.js Session CRUD, list rendering, search, SVG icons, dropdown actions (~3517 lines) - messages.js send(), SSE event handlers, approval, transcript (~2301 lines) - panels.js Cron, skills, memory, workspace, profiles, todo, settings (~6480 lines) - commands.js Slash command registry, parser, autocomplete dropdown (~1302 lines) - onboarding.js First-run wizard overlay, provider setup flow, and settings/workspace orchestration. - boot.js Event wiring, mobile sidebar/workspace nav, voice input, boot IIFE (~1607 lines) + index.html HTML template + style.css All CSS incl. mobile responsive, themes + skins, KaTeX + ui.js DOM helpers, renderMd, tool cards, context indicator, file tree + workspace.js File preview, file ops, git badge, central api() fetch wrapper + sessions.js Session CRUD, list rendering, collapsible groups, search, SSE sync + messages.js send(), SSE event handlers, approval/clarify, transcript, recovery + panels.js Cron, skills, memory, profiles, todo, settings (Control Center) + commands.js Slash command registry, parser, autocomplete dropdown + boot.js Event wiring, mobile nav, voice input, theme/skin boot, bfcache handler + onboarding.js First-run wizard overlay, provider setup flow + i18n.js Localization catalog (en, es, de, zh, zh-Hant, ru, …) + login.js Login page + open-redirect guard + icons.js Lucide icon path registry + sw.js Service worker: offline shell cache, version-pinned assets tests/ - conftest.py Isolated test server/state fixtures (~644 lines) - 488 test files 5303 tests collected via pytest - test_regressions.py Permanent regression gate (~976 lines) + conftest.py Isolated test server/state fixtures + ~700 test files ~7,150 tests collected via pytest (run `pytest --collect-only -q` for exact) + test_regressions.py Permanent regression gate CONTRIBUTING.md Contributor workflow and PR expectations. ROADMAP.md Feature and product roadmap document. SPRINTS.md Forward sprint plan with CLI + Claude parity targets. ARCHITECTURE.md THIS FILE. TESTING.md Manual browser test plan and automated coverage reference. - CHANGELOG.md Release notes per sprint. - BUGS.md Bug backlog and fixed items tracker. + CHANGELOG.md Release notes per version. + CONTRIBUTORS.md Community credit roll (regenerated via the maintainer workspace script). requirements.txt Python dependencies. .env.example Sample environment variable overrides. +> Per-file line counts intentionally omitted — they drift every release. Use +> `git ls-files | xargs wc -l` (or your editor) for current sizes; the role of +> each file above is the durable part. + State directory (runtime data, separate from source): ~/.hermes/webui/ diff --git a/README.md b/README.md index d0e51ab9..c1370afe 100644 --- a/README.md +++ b/README.md @@ -736,25 +736,25 @@ See [`CONTRIBUTORS.md`](CONTRIBUTORS.md) for the full ranked list of all 194 con ### Notable contributions -**[@franksong2702](https://github.com/franksong2702)** — Most prolific external contributor (117 PRs, `v0.49.3` → `v0.51.58`) +**[@franksong2702](https://github.com/franksong2702)** — Most prolific external contributor (148 PRs, `v0.49.3` → `v0.51.153`) Across the longest tenure of any external contributor: the session title guard (#301), breadcrumb workspace navigation (#302), embedded workspace terminal (#1099), worktree-backed session creation (#2053), onboarding documentation (#2052), composer footer container queries, streaming-session sidebar exemption (#1327), session sidecar repair, cron output preservation (#1295), profile default workspace persistence, manual `/compress` async start/status endpoints (#2128), worktree status surface (#2109) + guarded remove (#2156) for the lifecycle umbrella #2057, session post-render dedup (#2166), native-WebUI fast path (#2170), tail-window response trim (#2171), stale-stream guard extension (#2158), CSP report collector (#2160), and a long tail of polish across mobile/responsive, the session sidebar, and the workspace state machine. -**[@Michaelyklam](https://github.com/Michaelyklam)** — Most prolific contributor of recent releases (92 PRs, `v0.50.240` → `v0.51.57`) +**[@Michaelyklam](https://github.com/Michaelyklam)** — Most prolific contributor of recent releases (117 PRs, `v0.50.240` → `v0.51.139`) Production Docker hardening (#1921, drops sudo-capable staging user), profile-scoped skills endpoints (#1903), gateway PID resolution under profile-scoped HERMES_HOME (#1901), profile-aware AIAgent cache (#1898/#1904), backslash LaTeX delimiters (#1848), Codex quota error surfacing (#1770), shell-route HTML 503 (#1836), stale Kanban client recovery (#1828), context auto-compression toast lifetime (#1988), `/goal` command (#1866), Kanban detail-view scrolling (#1916), CLI session tool metadata preservation (#1778), Traditional Chinese kanban locale backfill (#1979), v0.51.51 mobile Insights bucketing/layout (#2120/#2121), Hermes run adapter RFC (#2105 for #1925), fork-from-here absolute index (#2198 for #2184), opencode-go custom-provider overlap routing (#2204 for #1894). -**[@bergeouss](https://github.com/bergeouss)** — Provider management UI + Docker hardening (62 PRs, `v0.48.0` → `v0.51.46`) +**[@bergeouss](https://github.com/bergeouss)** — Provider management UI + Docker hardening (70 PRs, `v0.48.0` → `v0.51.46`) Provider management UI for adding/editing custom providers from Settings, OAuth provider status detection (#1552), two-container Docker setup, profile isolation hardening (per-profile `.env` secrets), the bulk of what users see when they touch Settings → Providers, Reveal-in-Finder context menu (#1551), gateway status card (#1552), auto-assign session to active project filter (#1550), "What's new?" link in update banner (#1549), OpenRouter free-tier live fetch (#1548), credential pool 401 self-heal (#1553), inline provider chip + group model count in model picker (#1644). -**[@ai-ag2026](https://github.com/ai-ag2026)** — Session recovery + audit infrastructure (55 PRs, `v0.50.279` → `v0.51.47`) +**[@ai-ag2026](https://github.com/ai-ag2026)** — Session recovery + audit infrastructure (67 PRs, `v0.50.279` → `v0.51.190`) Autonomous-AI contributor (Hermes Agent-driven) focused on durability: `state.db`-backed sidecar reconciliation (#2041), orphan `.json.bak` recovery on startup (#2035), read-only session recovery audit endpoints (#2036, #2040), active run lifecycle in `/health` (#2039), crash-safe turn-journal RFC at `docs/rfcs/turn-journal.md` (#2042), append-only turn-journal helper (#2059), lifecycle events layer (#2062), `Content-Security-Policy-Report-Only` header (#2084), per-cron toast toggle (#2100), fork-session compression lineage isolation (#2014). -**[@dso2ng](https://github.com/dso2ng)** — Session lineage + diagnostics (23 PRs, `v0.50.227` → `v0.51.51`) +**[@dso2ng](https://github.com/dso2ng)** — Session lineage + diagnostics (25 PRs, `v0.50.227` → `v0.51.153`) `/api/session/lineage-report/` endpoint for bounded session graph diagnostics (#2012), stale Mermaid render error cleanup (#1337), `session_source="fork"` continuation-chain isolation (#2063), lazy lineage-report fetch on sidebar badge expand (#2130), and a long tail of frontend reliability fixes around session loading. -**[@jasonjcwu](https://github.com/jasonjcwu)** — Composer + transcript polish (16 PRs, `v0.50.227` → `v0.51.55`) +**[@jasonjcwu](https://github.com/jasonjcwu)** — Composer + transcript polish (16 PRs, `v0.50.227` → `v0.51.132`) Sidebar collapse via active-rail click (#2054, fuses #1884 + #1924), composer chip lightbox (#1758), title fixes for tool-heavy first turns, silent compress-status during session switch (#2185), concurrent-send loss fix (#2186), in-transcript steer message badges (#2187), and a string of frontend polish fixes. -**[@Jordan-SkyLF](https://github.com/Jordan-SkyLF)** — Live streaming + UX polish (12 PRs, `v0.50.18` → `v0.51.58`) +**[@Jordan-SkyLF](https://github.com/Jordan-SkyLF)** — Live streaming + UX polish (12 PRs, `v0.50.18` → `v0.51.66`) Original sprint of workspace fallback resolution, live reasoning cards (#366, #367, #394–#397), then a recent burst: manual "Refresh usage" button on the Provider quota card (#2150), cancelled-turn status classification (#2151), Firefox sidebar scroll stabilization (#2200), early provisional session titles (#2202), target-aware "What's new?" update-banner links (#2207), and MCP tools overflow fix in Settings (#2210). **[@aronprins](https://github.com/aronprins)** — `v0.50.0` UI overhaul (PR #242, plus 9 follow-ups) @@ -766,10 +766,10 @@ Six consecutive, focused security PRs: session memory leak fix (expired token pr **[@lucasrc](https://github.com/lucasrc)** — Auth-hardening trilogy (PRs #2191, #2192, #2193) Three coordinated security PRs that all landed in v0.51.57: thread-safe login rate limiter with PBKDF2 key separation, password-hash cache invalidation on Settings save, and the full 64-char HMAC-SHA256 session signature with a backwards-compatible migration bridge. The kind of cleanly-decomposed security work that's reviewable as three independent pieces. -**[@LumenYoung](https://github.com/LumenYoung)** — Streaming hot-path correctness (4 PRs, `v0.51.47` → `v0.51.55`) +**[@LumenYoung](https://github.com/LumenYoung)** — Streaming hot-path correctness (8 PRs, `v0.51.47` → `v0.51.99`) The original stale-stream writeback guard (#2136 — the bug class the next two releases extended), gateway-state alive-null classification (#2075), compression-banner anchor alignment (#2182), and context-progress ring auto-refresh on compression complete (#2188). Each PR opened a small surgical fix in one of the most fragile subsystems in the codebase. -**[@dobby-d-elf](https://github.com/dobby-d-elf)** — Frontend reliability + motion polish (6 PRs, `v0.51.38` → `v0.51.58`) +**[@dobby-d-elf](https://github.com/dobby-d-elf)** — Frontend reliability + motion polish (15 PRs, `v0.51.38` → `v0.51.161`) Workspace fallback on deleted directories (#2138), iPhone PWA bottom-scroll fix (#2143), the new "Activity: X tools" composer footer shimmer animation (#2203), and follow-up animation tuning (#2212). **[@JKJameson](https://github.com/JKJameson)** — Composer + session polish (10 PRs) diff --git a/ROADMAP.md b/ROADMAP.md index 4aceb531..8a26fbe6 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -18,7 +18,7 @@ | **Sessions + projects + search** | ✅ CRUD, content search, projects, tags, archive, fork, import | | **Mobile + Docker + auth** | ✅ Hamburger nav, slide-overs, password auth, GHCR images | | **Auxiliary surfaces** | ✅ Workspace tree + edit, cron CRUD, skills CRUD, memory write, MCP server UI | -| **Visual polish** | ✅ 8 themes (incl. light/system/OLED/Sienna), Mermaid, KaTeX, syntax highlighting | +| **Visual polish** | ✅ Light/dark/system themes × 11 skins (default, ares, mono, slate, poseidon, sisyphus, charizard, sienna, catppuccin, nous, geist-contrast), Mermaid, KaTeX, syntax highlighting | | **Native distribution** | ✅ macOS desktop app (universal arm64+x86_64 DMG, signed) — separate repo | Remaining gaps and forward work live in [Forward Work](#forward-work) below. @@ -29,15 +29,17 @@ Remaining gaps and forward work live in [Forward Work](#forward-work) below. | Layer | Files | Status | |---|---|---| -| Python server | `server.py` (~165 lines) + `api/` modules (~20k lines) | Thin shell + auth middleware + business logic | -| HTML template | `static/index.html` (~600 lines) | Served from disk | -| CSS | `static/style.css` (~3k lines) | Themes, mobile responsive, KaTeX, table styles | -| JavaScript | `static/{ui,sessions,messages,workspace,panels,boot,commands,icons,i18n,login,onboarding}.js` (~26k lines) | 11 modules served as static files | +| Python server | `server.py` + `api/` modules | Thin HTTP shell + auth middleware over the `api/` business logic (config, sessions, streaming, profiles, routes, onboarding, workspace, updates, upload) | +| HTML template | `static/index.html` | Served from disk | +| CSS | `static/style.css` | Themes + skins, mobile responsive, KaTeX, table styles | +| JavaScript | `static/{ui,sessions,messages,workspace,panels,boot,commands,icons,i18n,login,onboarding}.js` | Vanilla-JS modules served as static files — no bundler | | Service worker | `static/sw.js` | Offline shell cache, version-pinned assets | | Docker | `Dockerfile`, `docker-compose.yml` | `python:3.12-slim`, multi-arch (amd64+arm64), HEALTHCHECK | -| CI/CD | `.github/workflows/release.yml` | Auto-release + GHCR publish on tag push | +| CI/CD | `.github/workflows/` | ruff lint + sharded pytest + browser smoke + Docker smoke on every PR; auto-release + GHCR publish on tag push | | Test isolation | `tests/_pytest_port.py` | Per-worktree port + state-dir derivation, no collisions | +> Per-file line counts drift every release; see `ARCHITECTURE.md` for the current module map and `git ls-files` for exact sizes. + --- ## Feature parity checklist