Replace the three separate memory editors with a card layout that shows the
source file, a plain-text summary, the last modified time, and the character
count for each section, so the stored files are visible without opening
them.
Rename the sidebar "用户" entry to "Agent" in both locales and add the
memory.editTitle, memory.writeTo, and memory.charCount strings.
The pet feature was three loosely coupled subsystems that no core flow
depended on: the Petdex catalog page, the pet install/preference store, and
the pet-state socket. All three are removed.
The only cross-boundary touch point was a try/catch-wrapped observer that
mapped chat-run events to pet animations. Removing it leaves the /chat-run
event contract unchanged: no event name, field name, field type, or emission
timing changed.
Removing petdexPublicRoutes also closes the unauthenticated outbound proxy
at /api/hermes/petdex/asset, which shrinks the SSRF surface.
The project shipped a black-and-white theme that was only half converted:
the login page looked right, the message page was halfway, and the
settings page had not been started. This finishes the move to the CYBER
reference in prototype_reference/.
Colors now come from a single token source (styles/variables.scss), where
every semantic color is declared twice: once as OKLCH for the CSS, and
once as an RGB triple so translucent variants can be built as
rgba(var(--*-rgb), alpha). Cyan is the system itself, amber means the user
has to intervene, green means the machine is working, and red only ever
means something broke. The RGB triples are derived from the OKLCH values
so the two declarations cannot drift apart.
Pages adopt the .cy-* shell classes from the reference (view, panel,
kpis, tabs, grid, table, field) instead of ad-hoc markup, which is what
makes 19 of 26 views consistent. The remaining seven are deliberately
bespoke: chat streams, the kanban board, the workflow canvas, the
terminal, and the missing-agent screen.
The chart palette and the kanban column colors move into single-source
modules so they cannot drift either. A new guard test rejects raw hex
colors, named colors, and literal RGB triples anywhere in the client
source, with an explicit exemption list for the places that genuinely
cannot read a CSS variable. The existing chat semantics spec keeps the
chat chain honest.
No behavior changes: no logic, no i18n keys, no data structures, and the
/chat-run event contract is untouched.
The token swap made every control dark, but the pages themselves kept
their Arco defaults — bare `padding: 20px` with components laid straight
on the background. That is why the running app still read as "not the
prototype" no matter how many variables were replaced: the prototype's
page structure (panel / panel-h / panel-b / kv / tabs) was never built.
Rather than restate that shell in each of the 25 views, it now lives in
global.scss as .cy-view / .cy-panel / .cy-panel-h / .cy-panel-b /
.cy-kv / .cy-tabs / .cy-tab / .cy-stack / .cy-sec-t, and the settings
components share a global .settings-section + .section-title so all nine
panes pick up the mono section headers at once. The per-component
duplicates of those two rules were deleted.
Settings is converted as the reference case: Arco's a-tabs/a-tab-pane
became the underline tab strip, and the pane body sits in a panel. The
URL-query sync moved to a watcher on activeTab so pane order and deep
links still hold. Pane order is a contract, so it is asserted.
Two tests lock the shell in place — one for the global classes and the
cyan underline selected state, one for the settings structure and pane
order. Without them the next edit easily slides back to bare Arco.
Remove the deployment blurb and the token-storage hint from the sign-in
page. They described implementation details rather than helping anyone
sign in, and the token line exposed the storage mechanism to anyone
looking at the screen. Also removes the now-unused .login-legal rule and
the two locale keys behind it.
The neon tube rules never applied. Arco emits .arco-btn-primary along
with three attribute variants ([type='button'], [type='submit'],
[type='reset']) that lift specificity to (0,2,0), and their :hover forms
reach (0,3,0) — all of which beat a bare .arco-btn-primary. Every rule
now uses .arco-btn.arco-btn-X[type='...'] so the skin wins regardless of
the rendered html-type; login is a submit button, which is why it stayed
solid.
Verified with jsdom computed styles against the real arco.css.
Also remove the default-credential chips from the login page: printing
admin / 123456 on a sign-in screen leaks the credentials of a reachable
deployment. The one-click fill shortcut stays. The test that asserted
the hint is now shown is inverted to assert it is absent.
The previous commit only swapped theme tokens, so buttons kept the solid
blue from arco.css: a-button fills with rgb(var(--primary-6)), which maps
to --arcoblue-6, not --color-primary. Bridge both naming families so no
Arco blue survives.
Style buttons as hollow tubes rather than filled blocks: transparent
fill, 1px cyan wall, inner glow plus two outer halos, and a glowing
label. Hover brightens the wall, active pinches the halo inward,
loading pulses, disabled cuts power entirely. Same treatment in red for
destructive actions, and hollow-line chips for inputs, tags, switches
and popups.
Rebuild LoginView to match the approved prototype: 32px masked grid,
scanline, IsometricWave, neon card edge, badge, probe status lamp, and
default-credential chips. Logic, API calls and lock/reset messaging are
unchanged.
Replace the Pure Ink light/dark/comic theme system with the CYBER
single-theme dark palette from the reviewed prototype: OKLCH surfaces,
one neon-cyan accent, and monospace-first typography.
Arco components were reading colors from arco.css because no
ConfigProvider was mounted, so the theme values in arco-theme.ts never
took effect. Bridge CYBER into Arco through its --color-* variables in
global.scss instead, and align arco-theme.ts to match.
Brightness and style switches are gone: useTheme now pins dark, the
comic font faces and locale keys are removed, and ThemeSwitch.vue is
deleted along with its sidebar slot and display setting.
Two pieces of upstream promotion came out of this deployment.
The sidebar "apiRelay" tab only opened a registration page on a third-party
site, so it goes with no replacement.
The circuit badge next to Settings was not what it looked like. It opened an
ESP32 device manager: add a device, show LAN status, remote connect/disconnect,
rename, delete, backed by six REST routes and an mcu_devices table. The purchase
button inside that dialog was the promotional part; the rest was real device
management. Since the hardware is out of scope here, the entire feature is
removed rather than just the link that pointed upstream - UI entry, client API,
routes, controller, store, schema, locale strings, and the one GlobalAgentServer
method that only existed to answer its status column.
Table creation is dropped but no DROP TABLE was added, so an already-provisioned
database keeps its rows as harmless orphans instead of losing data on upgrade.
DevicesView and the hermes.devices route are untouched: that is LAN device
discovery, a separate feature.
AGENTS.md now records the removal so the badge does not come back.
- Drop all desktop/Electron branches, scripts, and UI (title bar, pets,
desktop bridge); LAN endpoint kind is now web/custom only
- Replace the bundled hermes CLI with user-side installation: add
GET /api/hermes/cli-status plus a HermesMissingView onboarding guide
- Remove the version-management UI (snapshots handled by git) and prune
dead website/mcu/claude scripts and lockfile entries
Every chat session now runs through the Hermes bridge, so the three chat
chains become feature-equivalent instead of three partially-maintained
dispatch paths. Keeping the coding-agent and in-house agent runtimes alive
meant every bridge change had to be mirrored into two more runtimes that
had already drifted.
Historical rows are read, not migrated: sessions stored with the retired
source normalize to cli on load, workflow graphs naming the retired agents
keep loading and run on the bridge, and the visible-source check plus
SOURCE_LABELS still recognize the old value so those sessions stay listed.
The public surface follows the code: the OpenAPI generator and the MCP
chat-run tool schema drop the six retired entry fields so external callers
are not told about runtimes that no longer exist.
harness-check gains a RETIRED_RUNTIME scan so the residual check is a
mechanical gate instead of a manual grep, with the two surviving read-side
compat sites recorded with reasons.
Refs: docs/phases/phase_003.md
Removes the ekko / hermes-web-ui branding from the whole tree and drops
eight locale files, so the project presents one name and one language pair.
Data compatibility is deliberate, not accidental: DB filenames, the JWT
audience, and skill manifest ownership all still recognise their pre-rename
values so existing deployments under ~/.hermes-web-ui keep working without a
re-login or a re-injection.
scripts/harness-check.mjs now scans for the legacy strings and fails the
build on any new occurrence, with an explicit allow-list (and reasons) for
the compatibility paths that must keep them.
Import the client, server, skills, tests, and build scripts as the starting
point for the rebuild, then trim the surfaces this project does not ship:
Electron desktop packaging, the marketing website, and the ESP32 firmware
tree. CI keeps the web build, e2e, lockfile, release, and Docker workflows.
Rename the package and CLI entry points to hermes-ui, drop the prepare hook so
npm ci no longer triggers a build, and drop the removed tsconfig and nodemon
references. Rewrite AGENTS.md, ARCHITECTURE.md, DEVELOPMENT.md, and the READMEs
so the documented package map and hard rules match this repository.
reference_code/ is ignored: it is a read-only snapshot, not an input to the build.