diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 87c2d79..b4d4d96 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,6 +36,9 @@ jobs: npm ci --ignore-scripts npm rebuild node-pty + - name: Check repository harness + run: npm run harness:check + - name: Test with coverage run: npm run test:coverage diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..3afb514 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,52 @@ +# Agent Map + +This file is a short map for coding agents. Keep detailed guidance in `docs/` +and keep this file small enough to fit into every task context. + +## First Reads + +- `DEVELOPMENT.md` - project commands, coding rules, test rules, and PR shape. +- `ARCHITECTURE.md` - package boundaries, data ownership, and runtime flow. +- `docs/harness/README.md` - how this repository is prepared for agent work. +- `docs/harness/validation.md` - which checks to run for each change type. +- `docs/harness/worktree-runbook.md` - isolated local dev and test setup. +- `docs/harness/pr-review.md` - self-review checklist before pushing. + +## Common Commands + +```bash +npm ci --ignore-scripts +npm run harness:check +npm run test +npm run test:e2e +npm run build +``` + +Use the smallest relevant check while iterating. Before a broad PR, run +`npm run harness:check`, `npm run test:coverage`, `npm run test:e2e`, and +`npm run build`. + +## Code Ownership Map + +- `packages/client/src` - Vue 3 client, stores, routes, i18n, API helpers. +- `packages/server/src` - Koa API, Socket.IO, persistence, Hermes integration. +- `packages/desktop` - Electron wrapper, bundled Python/Hermes runtime, release artifacts. +- `tests/client`, `tests/server`, `tests/shared` - Vitest coverage. +- `tests/e2e` - Playwright browser coverage with mocked backend services. +- `.github/workflows` - CI, release, Docker, and desktop packaging automation. + +## Hard Rules + +- Keep routes thin: put request handling in controllers and reusable behavior in services. +- Keep Web UI state under `HERMES_WEB_UI_HOME` or `HERMES_WEBUI_STATE_DIR`. +- Keep Hermes Agent state separate from Web UI state. +- Register local API routes before proxy catch-all routes. +- Use structured APIs and argument arrays instead of shell string construction. +- Add user-facing strings to every locale file. +- Do not mix unrelated refactors into a bug fix. + +## When The Agent Gets Stuck + +Improve the harness instead of repeating the same prompt. Add missing docs, +tests, logs, scripts, or CI checks so the next agent can see and verify the +constraint directly. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..8c0034f --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,89 @@ +# 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 + +1. The browser loads the Vite-built client from the Koa server. +2. Client modules call API helpers from `packages/client/src/api`. +3. Server routes in `packages/server/src/routes` wire HTTP paths to controllers. +4. Controllers validate request concerns and delegate reusable behavior to services. +5. Services own side effects: files, SQLite, Hermes profiles, subprocesses, bridges, and credentials. +6. 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-ui` through `config.appHome`. +- `HERMES_WEB_UI_HOME` and `HERMES_WEBUI_STATE_DIR` override 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 unless `UPLOAD_DIR` is set. +- 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 `execFile` or `spawn` with 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 use `packages/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 `