41 Commits
Author SHA1 Message Date
toor ecb7c9501c expand and search the new chat Agent profile picker
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
2026-10-25 00:10:21 +08:00
toor d3b3a0833e show assistant replies below avatar and profile name
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
2026-10-24 22:45:16 +08:00
toor a54913efd2 fix false missing Hermes CLI detection after deployment
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
2026-10-24 20:59:08 +08:00
toor 05a6fbfbae Merge branch 'main' of https://gitea.erhe.top/toor/hermes-ui
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
2026-10-24 20:42:35 +08:00
toor 7119e04a65 ++ 2026-10-24 16:34:02 +08:00
toor 99e5687ce0 fix thinking tool rows to fill chat width
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
2026-10-22 15:08:36 +08:00
toor 3ca960f388 优化页面交互并增强 Provider 配置能力
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
- 表单下拉框不再用 label 包裹,改为 div + aria-label,避免点击后
  下拉面板瞬间关闭
- Provider 卡片新增「从上游获取模型」和「修改」入口,支持编辑
  base URL、API Key 与 api_mode,凭据写入对应的环境变量
- 服务端抽出 provider-model-discovery 统一不同 api_mode 的模型发现,
  旧的 custom_providers 与新的 providers 字典结构都能正确更新
- Agent Bridge 改为后台启动,HTTP 接口在 Python 运行时就绪前即可用;
  worker 连接被拒时按类型重试,不重放可能已产生副作用的请求
- 断线重连后恢复 profiles、models 与会话列表,健康检查改为自调度
  的 setTimeout,离线时 2 秒后重试
- 批量删除确认文案改用 Popconfirm content,避免变成侧栏触发器文本
2026-10-22 14:29:48 +08:00
toor 421ffa0714 增加一键重启所有网关按钮
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
2026-10-21 17:21:11 +08:00
toor 8fdec02a1c add a foreground dev launcher and close the Arco token gaps
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
The CYBER skin left a class of defects that unit tests could not see: Arco
components kept their own light-theme appearance because the token bridge
never covered the neutral, gray, tooltip, mask and border-radius families,
and four override rules targeted class names that do not exist in Arco, so
they silently matched nothing.

Bridge the missing families and point the dead selectors at the real ones
(.arco-switch-handle, .arco-checkbox-icon, .arco-select-dropdown,
.arco-slider-bar), so switches stop rendering a white knob and checkboxes
finally glow.

Add start.sh so a dev run can be started without a second terminal: it
frees the ports left over from a previous run, refusing to kill processes
that do not belong to this project, then starts the API server and the
Vite client in the foreground.
2026-10-21 10:13:38 +08:00
toor bbb9a6b61f rework the memory view and rename profiles to Agent
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
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.
2026-10-20 13:33:10 +08:00
toor b709ec6742 remove the desktop-pet system
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
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.
2026-10-20 13:24:17 +08:00
toor 5e1003ceb7 replace the monochrome theme with the CYBER neon-cyan skin
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
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.
2026-10-20 11:17:46 +08:00
toor a1fff482bf make the test suite and openapi generator platform-independent
Windows checkouts turned LF into CRLF (core.autocrlf=true), and several
tests plus the openapi generator hardcoded LF or POSIX path separators.
The result was a suite that was green on Linux CI but red on Windows, and
an openapi.json whose /api/hermes/* routes silently disappeared when
generated on Windows.

Pin the repository to LF via .gitattributes, strip shebangs before
Vite's SSR transform, and key route files by their posix path. Add a
manually triggered macOS verification workflow so the same checks run
on a self-hosted macOS runner.
2026-10-20 11:17:34 +08:00
toor 8052bf5781 read the shell prompt again and stop the reconnect loop
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
The terminal was the last surface in the chat tool panel still wearing
someone else's design system, and it had two defects underneath that.

The font stack named no Nerd Font, so the private-use glyphs a default
zsh prompt draws its separators and branch marks from rendered as notdef
boxes. The ~ and the path after it drew fine, which is what made it read
as a font bug rather than a missing-glyph one.

Both components also carried their own copy of the palette -- four themes
in one, fifteen in the other, drifting, defaulting to a near-black that
appears nowhere in the token set. Changing --code-bg did nothing to the
terminal because the terminal never read a token. They now share one
module built from the tokens, so an error in the terminal is the same
red as an error anywhere else.

TerminalView reconnected on a bare setTimeout with no attempt cap and no
error surface, retrying invisibly every three seconds forever against an
unreachable backend. It now shares the panel's cap of three and renders
the same retry affordance, counting down again once a session is created.

Also drops a dead ws.onopen assignment and a 21px padding that was on no
spacing scale, and records what the chat page still owes the prototype.
2026-10-19 17:03:38 +08:00
toor a623398fe8 split one accent into three colours that each mean one thing
Build / build (pull_request) Canceled after 0s
Playwright / e2e (pull_request) Canceled after 0s
The app had a single cyan accent, so every emphasis in the chat chain
was a shade of the same hue. An approval waiting on the user, a tool
that had already run, a streaming response and an outright error all
looked equally urgent — the hue carried no information at all.

The colours are now split by meaning rather than by shade, and the rule
is documented at the top of variables.scss so it survives future edits:

  cyan   the system itself   brand, primary buttons, selection, user bubbles
  amber  needs you           approval cards, context about to fill
  lime   the machine works   tool execution, assistant output, streaming
  red    something failed    errors only — deliberately not a palette member

Red staying out is the load-bearing part: when failure reuses the accent
family the urgency signal disappears entirely.

`--warning` moves from yellow (hue 85) to amber (hue 68) and `--success`
from a muted green to fluorescent lime (hue 128). Because both are global
tokens, every page using them changes hue in the same pass; the Arco
`--green-*` / `--orange-*` bridges are updated with them so solid controls
follow instead of staying behind. Six translucent companions
(`--success-soft`, `--warning-line`, …) were added for fills and borders.

On the chat surface: the approval card goes amber with a slow pulse on
its icon — the only moving part in the chain, marking the one thing that
is genuinely waiting. Tool-change cards and assistant bubbles take a 2px
lime left edge meaning "already ran"; user bubbles get a cyan right edge
so the two sides read apart without labels. The context meter is green
under 60%, amber to 80%, red above; those thresholds already existed and
only the colours were wrong.

Rendering-layer only. No store logic, no /chat-run payload, no markup or
event wiring.
2026-10-19 15:34:31 +08:00
toor 993b6b968c give the pages the CYBER shell they were missing
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.
2026-10-19 15:23:01 +08:00
toor 3debe903f7 retire the last light-theme branches and fix three latent color bugs
Dark is now the only theme, so every `.dark` selector matched
unconditionally while each non-dark branch was unreachable. That left
fourteen `.dark &` blocks sitting on top of token-based base rules and
silently overriding them with hardcoded grays from the previous palette
(#333333, #999999, #cccccc, #f2f2f2, #1f1f1f, #2a2a2a). Merged each value
down into its base rule and deleted the wrapper, then replaced fifteen
more legacy grays with the CYBER tokens.

Three bugs surfaced along the way:

- FileEditor read `documentElement.classList.contains('dark')`, but the
  `dark` class is bound on `.app-root`, so Monaco always loaded the
  light `vs` theme inside the dark editor surface.
- CodexLoginModal, CopilotLoginModal and NousLoginModal wrote
  `border-color: var(--arcoblue-6, #165dff)` and VoiceApiFormModal wrote
  `color: var(--primary-6, #18a058)`. Those Arco variables hold bare
  RGB triplets, not colors, so each declaration was invalid and
  discarded — the hover border and link color stayed stock Arco
  blue/green instead of the cyan accent.
- JourneyView drew the pinned-node ring in amber, a leftover from the
  old palette.

Rendering-layer only: no store logic, no /chat-run payload, no message
rendering path.
2026-10-19 14:56:23 +08:00
toor f4f45304a6 bring the journey graph onto the cyan edge palette
The canvas renderer branched on isDark for every color, but isDark has
been a constant true since the theme switch was removed, so half of each
ternary was unreachable. Resolve the values directly and shift the
hues from the old pale blue to the accent cyan, keeping alpha as the only
thing that varies between idle and focused edges.

useTheme is no longer referenced here and is dropped from the imports.
2026-10-19 14:44:41 +08:00
toor 4ddf5337ad collapse the syntax theme to one dark palette
code-block.scss carried two full highlight.js themes — a light set plus a
.dark override — left over from the ink era, with keywords in violet and
no relationship to the rest of the surface. CYBER has a single dark
theme, so keep one rule set and pull every token color from the existing
semantic variables: cyan for keywords, green for strings, amber for
literals, red for types. Keywords matching the accent keeps a code block
from competing with the chrome.

Diff line chrome also moves off the old slate values onto tokens, and the
code header now reads as part of the block instead of a light strip.
2026-10-19 14:42:47 +08:00
toor 2d7069bdf9 move the remaining light panels onto the dark tokens
The scroll-to-bottom control, the approval and queue float panels, and
the inline code chips still carried the light-theme fills (#ffffff,
rgba(255,255,255,.94/.68)) with .dark overrides pinned to old greys.
Point all of them at --bg-card and its rgb triple so the alpha layers
keep working, then drop the overrides that became identical to the base
rule.

Low-alpha white overlays are left alone — on a dark surface they read as
a lift, which is the intent.
2026-10-19 14:41:13 +08:00
toor 189270e046 carry the neon language into the sidebar and page header
The nav still used the ink palette: flat fills, oversized rows, and a
tinted background with no marker for the active route. Adopt the CYBER
treatment from the prototype — a 2px glowing cyan bar on the left of the
active item, hairline borders instead of full-contrast ones, monospace
group labels with wide tracking, and a faint cyan wash at the top of the
rail so it does not read as a dead dark slab.

PageSidebarNav gets the same active treatment as AppSidebar so the
conversation routes do not feel like a different product.

Header height stays at 64px — style-system.test.ts asserts it as a
layout contract.
2026-10-19 14:38:08 +08:00
toor b48d67a823 pin the boot fallback to the dark palette
The inline boot styles and FOUC script still branched on the removed
light/dark and ink/comic settings, so the first paint flashed the old
light surface before Vue mounted. Match the single dark theme and give
the logo sweep the neon tint.
2026-10-19 14:34:08 +08:00
toor 3769ed3068 remove the isometric wave from the login page
The angled slab texture came from the first prototype pass and clashed
with the flat neon treatment that replaced it. Drop the component
usage, its decor wrapper and the positioning rules.

The vendored IsometricWave directory stays — it is shared vendor code
and JourneyView may still want it.
2026-10-19 14:25:39 +08:00
toor fc341158ab keep the credential fields on the theme palette
Chrome flags the filled-in credentials as an autofill match and paints
its own light background and muted fill over the field, which read as a
white block with grey text against the dark card. Take the fill color
back with -webkit-text-fill-color and lay the theme input color over the
injected background with a large inset shadow.

Safe for the password field: masking is done by -webkit-text-security
rendering dots, which fill-color does not affect.
2026-10-19 14:18:11 +08:00
toor 8c73871982 drop the login footer note
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.
2026-10-19 14:02:38 +08:00
toor 716a8f6d16 add the neon tube sheen and quiet down the login page
Port the sweeping highlight from the prototype: a 38%-wide white band
travels left to right on a 3.4s loop, idle for the first 62% so it reads
as an occasional flare rather than a constant shimmer. The tube mixes
now clip overflow so the band stays inside the button, and the loading
state suppresses it in favour of the existing pulse.

Drop the masked grid and scanline from the login page — low-contrast
texture behind a credential form makes the text harder to read. Only the
IsometricWave remains.

Brighten input text to near-white and bump it to 14.5px; Arco's default
--color-text-1 sits too dark on the recessed input fill. Avoid
-webkit-text-fill-color, which would defeat the password field's masking.
2026-10-19 14:01:07 +08:00
toor ce184fc151 outrank Arco button variants and drop the credential hint
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.
2026-10-19 13:55:02 +08:00
toor 336d08fc05 render buttons as neon tubes and rebuild the login page
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.
2026-10-19 13:47:12 +08:00
toor 282624f801 adopt CYBER neon-dark theme tokens
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.
2026-10-19 13:04:49 +08:00
toor 145d240dc2 Ignore the local prototype_reference design HTMLs
Build / build (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
NPM Lockfile Check / npm ci --ignore-scripts (push) Canceled after 0s
Two hand-written HTML mockups sitting in the project root, not source. Adding
them to the ignore list alongside the already-removed reference_code entry so
they cannot be swept into a commit by a broad `git add`.
2026-10-19 09:50:39 +08:00
toor 77b1858163 Remove the API relay link and the ESP32 device feature
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.
2026-10-19 01:32:51 +08:00
toor 3c963bb1d9 Scope coverage to our own sources
v8 coverage had no include, so it walked the entire project root. With the
read-only reference_code checkout present that pulled 572 of 1031 entries into
the report and reported 23.94% for "All files" - a number describing the
reference, not this project. Restricting it to packages/*/src puts the figure
at 59.71%.

Nothing failed on this before because there are no coverage thresholds, but the
report was misleading anyone reading it.
2026-10-19 00:39:57 +08:00
toor cc644c59f6 Phase 008: close the test and CI loop around the migration
Adds the checks that make the constraints from Phase 001-007 mechanical
instead of tribal knowledge, and clears the legacy brand text that was still
reachable at runtime.

New red-line tests:
  - no-legacy-brand mirrors the harness scan under vitest, and asserts its
    allow-list has not drifted from harness-check.mjs
  - hermes-db-readonly classifies every new DatabaseSync call site by
    following the path it opens, and fails if a state.db handle drops
    readOnly. It also pins the one legitimately writable database.
  - i18n-parity compares the raw zh/en locale objects both ways. The
    existing coverage test merged en into zh at import time, so a key
    missing from zh could never fail there.

harness:check gains the four missing gates from the phase brief - retired
package directories, retired package scripts, a single UI library, and the
required root files. Each was verified to fail by mutating the repo.

The online-update channel had hardcoded upstream URLs. It now reads
HERMES_WEB_UI_VERSION_MANIFEST_URL and friends and degrades with a named
error, because a reimplementation has nowhere to pull releases from.

The remaining legacy strings are deliberate and each carries a reason in the
allow-list: the global-agent relay address and the OpenRouter referer are
load-bearing, the socket role identifier is a wire contract, and the pre-rename
DB filenames would orphan existing deployments if changed. AGENTS.md now says
so explicitly, so a future agent does not "clean them up".

Also removes a dead electron mock alias, an i18n exemption that had stopped
exempting anything, and a teardown race in plugins-view.test.ts where a-spin
animation frames outlived the jsdom environment.

Verified self-contained: with reference_code/ moved aside, harness:check,
build, test and test:e2e all pass, so the directory can now be deleted.
2026-10-19 00:23:19 +08:00
toor 836d0228d2 Phase 007: migrate every remaining view from naive-ui to Arco Design Vue
The project now has exactly one UI library. Every naive-ui component in
packages/client/src is replaced by its Arco equivalent across 24 views and
roughly 80 components, and naive-ui is dropped from package.json along with
its transitive vueuc / @css-render / vdirs / seemly dependencies.

The migration is rendering-layer only. No store logic, no API contract, and
no /chat-run payload was touched.

Three classes of leftover were invisible to `grep naive-ui` and are now
covered by tests/client/no-naive-ui.test.ts, which asserts all three:
  - dead .n-* class names in style blocks
  - dead --n-* custom properties
  - naive-ui in package.json

Notable behavioural traps handled along the way, recorded in
docs/arco-migration-rules.md:
  - a-input-password defaults to masked; passing default-visibility="false"
    would have exposed API keys in clear text
  - a-upload fires a real XHR unless auto-upload is false
  - nested Trigger components fight over the first element child, so the
    group-chat settings dropdown was flattened
  - Arco renders tooltip default-slot text inline, which was silently
    collapsing the chat and group-chat toolbars
2026-10-18 22:57:25 +08:00
toor c3eeea4187 fix(chat): repair Arco migration fallout in the chat page
The Phase 006 walkthrough surfaced four issues the automated checks could
not see. Dead naive-ui class names left behind by the migration stopped
matching, tooltips that carried their label as trailing default-slot text
leaked that text into the flex row, the workspace panel squeezed the chat
column until the input toolbar wrapped, and the Escape fallback still
looked for naive-ui's modal mask.

Tooltips now pass their label through the content prop, the tool panel
reserves a minimum width for the chat column, and Escape finds the visible
Arco modal and clicks its close button.
2026-10-18 03:11:35 +08:00
toor effc29085c Phase 006: migrate the chat page from naive-ui to Arco Design Vue
Swaps the rendering layer only. Chat store logic, keyboard handling, and the
/chat-run Socket.IO contract are untouched, so a mixed UI cannot hide a chat
regression behind a library swap.

Arco's dropdowns take their items from a #content slot of a-doption children
rather than a droplist prop, and Arco Triggers cannot be nested, so the two
toolbar menus lost their a-tooltip in favour of a native title. Both rules are
recorded in docs/arco-mapping.md, and tests/e2e/chat-input-dropdown.spec.ts plus
tests/e2e/chat-rendering-smoke.spec.ts keep the menus, the streaming markdown
rendering, and the no-Arco-inside-the-bubble red line from regressing silently.
2026-10-17 22:17:32 +08:00
toor 4baccd5d88 Phase 005: vendor ArkScope, land the Arco style baseline, and fix bridge interpreter resolution
- Vendor ArkScope decorative layers (ScrambleTitle / IsometricWave) with provenance notes; decorative-only per AGENTS.md red lines
- Migrate theme tokens to Arco, register the Arco theme, and add hook adapter composables (useMessage / useDialog / useNotification) with matching signatures
- Sample pages: LoginView and AppSidebar on the new baseline; docs/arco-mapping.md and docs/ui-baseline.md land
- agent-bridge: prefer the PM-selected venv from facts.json over legacy in-tree venvs (legacy lacks the mcp extra, so every MCP server showed 0 tools / not connected)
- agent-bridge python (vendored, deliberate deviation): MCP discovery import fallback and pyyaml -> hermes_yaml so plugins and MCP work under the PM env; install the mcp extra via `hermes pm install --extra mcp`
- Chat-chain fragment: docs/chat-chain-changes/2026-10-17-phase005-arkscope-baseline.md

Verified: harness:check, test (2020 passed), test:e2e (30 passed), build all green; manual: plugins 100/0 warnings, MCP 6/6 servers connected with 104 tools.
2026-10-17 09:45:30 +08:00
toor 4701bf0ad0 Phase 004: remove the desktop shell, website tooling, and bundled hermes CLI
- 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
2026-10-16 15:33:56 +08:00
toor 8c1ddf415f Phase 003: remove the coding-agent and ekko-agent runtimes
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
2026-10-16 13:27:50 +08:00
toor c93e1fe1bd Phase 002: rebrand to hermes-ui and consolidate i18n to zh/en
Build / build (push) Canceled after 0s
NPM Lockfile Check / npm ci --ignore-scripts (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
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.
2026-10-16 11:11:29 +08:00
toor 1e9ea89d86 chore: bootstrap hermes-ui skeleton from 0.6.29 snapshot
Build / build (push) Canceled after 0s
NPM Lockfile Check / npm ci --ignore-scripts (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
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.
2026-10-16 10:34:35 +08:00