mirror of
https://github.com/EKKOLearnAI/hermes-web-ui.git
synced 2026-06-06 19:10:17 +00:00
dcbf601e35
Co-authored-by: xingzhi <chuzihao.czh@alibaba-inc.com>
4.1 KiB
4.1 KiB
Architecture
Hermes Web UI is a TypeScript monorepo that ships a browser dashboard, a Koa backend, and an Electron desktop distribution around Hermes Agent.
Package Boundaries
| Area | Path | Responsibility |
|---|---|---|
| Client | packages/client/src |
Vue UI, routing, Pinia stores, API wrappers, i18n, browser-visible state. |
| Server | packages/server/src |
HTTP API, auth, Socket.IO, SQLite stores, file access, Hermes runtime integration. |
| Desktop | packages/desktop |
Electron shell, local Web UI server bootstrap, updater, bundled Python/Hermes runtime. |
| Tests | tests |
Vitest unit/integration tests and Playwright browser tests. |
| CI | .github/workflows |
Build, e2e, lockfile, Docker, and desktop release automation. |
Request Flow
- The browser loads the Vite-built client from the Koa server.
- Client modules call API helpers from
packages/client/src/api. - Server routes in
packages/server/src/routeswire HTTP paths to controllers. - Controllers validate request concerns and delegate reusable behavior to services.
- Services own side effects: files, SQLite, Hermes profiles, subprocesses, bridges, and credentials.
- Long-running chat and group-chat flows use Socket.IO namespaces managed by server services.
Keep each layer narrow. Routes should not grow business logic, and client code should not duplicate server persistence rules.
State And Data Ownership
- Web UI state defaults to
~/.hermes-web-uithroughconfig.appHome. HERMES_WEB_UI_HOMEandHERMES_WEBUI_STATE_DIRoverride Web UI state location.- Hermes Agent state lives under Hermes profile directories and must stay distinct from Web UI state.
- Uploads default to
config.uploadDir, which is derived from the Web UI home unlessUPLOAD_DIRis set. - Runtime data directories must also live under the Web UI home, not beside built
distassets. - Profile-scoped Hermes data should use existing profile helpers instead of manually joining paths.
Server Structure
routes/registers HTTP and WebSocket entry points.controllers/handles request-level behavior.services/owns reusable IO, domain behavior, external process calls, and integration logic.db/owns SQLite schemas and stores.middleware/owns request middleware such as user auth.shared/contains cross-server constants and helpers.
Architecture rules:
- Register local API routes before proxy catch-all routes.
- Keep auth behavior centralized in
packages/server/src/services/auth.ts. - Prefer
execFileorspawnwith argument arrays over shell command strings. - Use structured file and YAML/JSON parsers when editing structured data.
Client Structure
views/contains route-level screens.components/contains reusable UI.stores/contains Pinia state.api/contains HTTP clients and should usepackages/client/src/api/client.ts.i18n/contains locale messages for user-facing strings.styles/contains global styling and theme primitives.
Frontend rules:
- Use Vue 3 Composition API with
<script setup lang="ts">. - Use existing Naive UI patterns before adding new UI conventions.
- Add visible text to all locale files.
- Keep component styles scoped unless the style is intentionally global.
Desktop Release Flow
Desktop packaging is intentionally split:
- Pull requests run a Linux desktop smoke test in
.github/workflows/build.yml. - Published releases and manual dispatches run
.github/workflows/desktop-release.yml. - Each release matrix target uploads only the artifact globs for its own platform.
Do not make a Windows job require macOS .dmg files or a Linux job require
Windows installers. Keep fail_on_unmatched_files: true where platform-specific
artifact lists make the expectation explicit.
Validation Surface
The minimum mechanical harness is:
npm run harness:checkfor repository docs, workflow, and package-script invariants.npm run testor focused Vitest tests for local logic.npm run test:e2efor browser-visible routing/auth/chat regressions.npm run buildfor type checking and production bundles.
See docs/harness/validation.md for change-specific commands.