Files
hermes-agent/website
teknium1 36773e0d78 refactor(ts): one GatewayEventMap in apps/shared typed from tui_gateway emitters; drop never-emitted tool.progress
Three TypeScript clients each declared their own copy of the tui_gateway wire
types and had drifted apart: apps/shared had a partial GatewayEventName union
with a `(string & {})` escape hatch, ui-tui/gatewayTypes.ts a 150-line
discriminated union, and apps/desktop an `RpcEvent<T>` that was field-for-field
the shared GatewayEvent with `type: string`. None matched the emitter:
message.complete lacked warning/status/error/recoverable/error_surface,
tool.start/tool.complete lacked args/result, SessionResumeResponse lacked
session_key/messages_omitted/hydrating/auto_continue/todo_state, three
different ModelOptionProvider shapes disagreed on fields, and all three unions
handled a `tool.progress` event that no Python emitter has ever produced.

Now:

* `apps/shared/src/gateway-events.ts` is the single home: payload interfaces
  typed from the Python emitters (file::symbol cited per interface),
  `BackendGatewayEventMap` (89 backend names) + `ClientLocalGatewayEventMap`
  (5 TUI-synthetic transport events, clearly marked, excluded from the
  contract) merged into `GatewayEventMap`; `GatewayEvent<K>` is discriminated
  on `type` with `seq` typed. RPC shapes shared by 2+ surfaces live beside it
  (ModelOptionProvider = union of every field hermes_cli/inventory.py sets,
  incl. pricing_pending/free_tier_pending; SessionResumeResponse<Info>;
  SessionListItem with resolved_id; Usage).
* `JsonRpcGatewayClient.on<K>` is keyed by event name; the gateway.ready
  heartbeat/replay_epoch and per-frame `seq` reads are typed instead of cast.
* ui-tui and apps/desktop import the shared names; their local duplicates are
  deleted (no re-export shims — importers are repointed; the desktop plugin
  SDK barrel keeps its public `RpcEvent` name as an alias of GatewayEvent).
  web/src repoints ModelOptionProvider/ModelOptionsResponse.
* `tool.progress` handling is removed from the TUI handler/turnController,
  desktop event sets/tools handler, shared union, tests, and two docs
  (`grep '"tool.progress"' tui_gateway/` = 0 hits; the `display.tool_progress`
  config mode is unrelated and untouched).
* `message.complete.warning` (history-commit note from
  prompt_turn.py::_complete_turn_payload) is typed and surfaced on both
  surfaces through their existing notice paths (TUI pushActivity 'warn',
  desktop notify kind 'warning').

Contract: `apps/shared/src/gateway-events.json` is the sorted list of
backend-emitted names. `tests/tui_gateway/test_gateway_event_contract.py`
collects names from the Python emitter side (emit-helper literals, the
`.request → .expire` table, change-watcher table, child delta mirror,
subagent relay, desktop_ui tool emitters, gateway.ready/setup.ready/
browser-controller frames) and asserts emitted == JSON in both directions.
`apps/shared/src/gateway-events.test.ts` asserts BACKEND_EVENT_NAMES (which
the map type is `satisfies`-checked against) == JSON. Sabotage-verified: a
fake JSON name fails both tests; a fake TS name fails tsc + vitest; a fake
Python `_emit("...")` fails pytest.
2026-09-13 05:42:31 -07:00
..
…

Website

This website is built using Docusaurus, a modern static website generator.

Installation

yarn

Local Development

yarn start

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

Build

yarn build

This command generates static content into the build directory and can be served using any static contents hosting service.

Deployment

Using SSH:

USE_SSH=true yarn deploy

Not using SSH:

GIT_USER=<Your GitHub username> yarn deploy

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the gh-pages branch.

Diagram Linting

CI runs ascii-guard to lint docs for ASCII box diagrams. Use Mermaid (````mermaid`) or plain lists/tables instead of ASCII boxes to avoid CI failures.