From 77b185816356edb5bb8e31fe1df100920e1524d0 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 19 Oct 2026 01:32:51 +0800 Subject: [PATCH] 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. --- AGENTS.md | 6 +- .../2026-10-17-remove-mcu-device-panel.md | 40 + docs/known-issues.md | 12 +- packages/client/src/api/hermes/mcu-devices.ts | 54 -- .../src/components/hermes/chat/ChatPanel.vue | 2 - .../hermes/group-chat/GroupChatPanel.vue | 2 - .../components/layout/PageSidebarFooter.vue | 2 - .../src/components/layout/PageSidebarNav.vue | 20 - .../layout/SettingsCircuitBadge.vue | 696 ------------------ packages/client/src/i18n/locales/en.ts | 42 -- packages/client/src/i18n/locales/zh.ts | 42 -- .../server/src/controllers/mcu-devices.ts | 234 ------ .../server/src/db/hermes/mcu-devices-store.ts | 124 ---- packages/server/src/db/hermes/schemas.ts | 23 - packages/server/src/routes/index.ts | 2 - packages/server/src/routes/mcu-devices.ts | 11 - .../src/services/global-agent/server.ts | 15 - scripts/harness-check.mjs | 5 - tests/server/hermes-schemas.test.ts | 10 +- tests/server/mcu-devices-store.test.ts | 88 --- tests/server/no-legacy-brand.test.ts | 6 - tests/server/schema-sync.test.ts | 18 - 22 files changed, 49 insertions(+), 1405 deletions(-) create mode 100644 docs/chat-chain-changes/2026-10-17-remove-mcu-device-panel.md delete mode 100644 packages/client/src/api/hermes/mcu-devices.ts delete mode 100644 packages/client/src/components/layout/SettingsCircuitBadge.vue delete mode 100644 packages/server/src/controllers/mcu-devices.ts delete mode 100644 packages/server/src/db/hermes/mcu-devices-store.ts delete mode 100644 packages/server/src/routes/mcu-devices.ts delete mode 100644 tests/server/mcu-devices-store.test.ts diff --git a/AGENTS.md b/AGENTS.md index f315b52..05a0e32 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,9 +59,13 @@ Use the smallest relevant check while iterating. Before a broad PR, run - This repo is a reimplementation. A few upstream service addresses are load-bearing and are deliberately kept, each with a whitelist entry in `scripts/harness-check.mjs`: the global-agent relay (`api.hermes-studio.ai`), the - OpenRouter referer, and the ESP32 purchase link. Do not "clean them up" as legacy + OpenRouter referer, and the sidebar website link. Do not "clean them up" as legacy brand text — removing them breaks those features. Do not read the relay address as project identity: this deployment is not affiliated with the upstream operator. +- The upstream ESP32 / MCU device feature was removed on purpose (no UI entry, no REST + routes, no store, no locale strings). Do not reintroduce it. Its "purchase" affordance + was the only part that merely advertised the upstream site; the rest was real device + management, and the whole thing is gone because the hardware is out of scope here. - The online-update channel (`runtime-version-manager.ts`) has no default URL. It reads `HERMES_WEB_UI_VERSION_MANIFEST_URL` / `HERMES_WEB_UI_DOWNLOAD_BASE_URL` / `HERMES_WEB_UI_GITHUB_REPO` and degrades with a named error when unset. Do not diff --git a/docs/chat-chain-changes/2026-10-17-remove-mcu-device-panel.md b/docs/chat-chain-changes/2026-10-17-remove-mcu-device-panel.md new file mode 100644 index 0000000..f7aa815 --- /dev/null +++ b/docs/chat-chain-changes/2026-10-17-remove-mcu-device-panel.md @@ -0,0 +1,40 @@ +--- +date: 2026-10-17 +pr: pending +feature: Remove the upstream ESP32/MCU device panel from the chat sidebars +impact: Sidebar-only deletion. Both files lose one child component (SettingsCircuitBadge) and its import from the settings row at the bottom of the page sidebar. No chat store, no message rendering, no /chat-run payload, no streaming, and no tool-call path is touched. Nothing in the chat chain gains or loses a capability. +--- + +## What changed + +`ChatPanel.vue` and `GroupChatPanel.vue` each rendered `` +next to the settings button in `.page-sidebar-bottom`. Both now omit it. + +## Why + +The badge opened an ESP32/MCU device management dialog. Its only outbound call to +the upstream operator was the "purchase" button inside that dialog, but the rest was +real functionality (add device, LAN status, remote connect/disconnect, rename, +delete) backed by six REST routes and the `mcu_devices` table. The hardware is out +of scope for this deployment, so the whole feature is gone rather than hidden. + +## Removal scope + +- `SettingsCircuitBadge.vue`, `api/hermes/mcu-devices.ts` +- server `routes/mcu-devices.ts`, `controllers/mcu-devices.ts`, + `db/hermes/mcu-devices-store.ts`, the `routes/index.ts` registration, and the + `mcu_devices` entry in `schemas.ts` +- `GlobalAgentServer.hasMcuDeviceCode()`, which only existed to answer the panel's + LAN-status column +- `mcuDevices.*` locale keys in both `zh.ts` and `en.ts` +- the corresponding harness and `no-legacy-brand` whitelist entries + +## Deliberately kept + +- `DevicesView.vue` and the `hermes.devices` route. That is LAN device discovery + backed by `@/api/hermes/devices`, a separate feature from MCU device management. +- `packages/server/src/services/global-agent/server.ts` itself. Only the one + now-unused method was removed; the relay is load-bearing for other features. +- Existing `mcu_devices` tables in already-provisioned databases. The table + creation was dropped but no `DROP TABLE` was added, so an old deployment keeps + its rows as harmless orphans instead of losing data on upgrade. diff --git a/docs/known-issues.md b/docs/known-issues.md index a4eae5b..edb66e8 100644 --- a/docs/known-issues.md +++ b/docs/known-issues.md @@ -45,13 +45,7 @@ - **位置**:`packages/client/src/views/hermes/WorkflowView.vue`,`showWorkflowBatchDeleteConfirm` - **证据**:naive 的 `NPopconfirm v-model:show` 需要它;Arco 的 `a-popconfirm` 无 `show` prop 后它失去读取方,只剩写。关闭改由 `@ok`/`@cancel` 驱动 -### 6. 两个弹窗共用一个 saving ref - -- **现象**:新增设备弹窗与改名弹窗同时存在时,按钮的 loading/disabled 会互相干扰 -- **位置**:`packages/client/src/components/layout/SettingsCircuitBadge.vue` -- **证据**:两个 modal 共用 `saving`。迁移前就是这样 - -### 7. ProfileCreateModal 有两个重复的 style 块 +### 6. ProfileCreateModal 有两个重复的 style 块 - **现象**:无功能影响 - **位置**:`packages/client/src/components/hermes/profiles/ProfileCreateModal.vue` @@ -154,7 +148,7 @@ ### 表格列的省略与 tooltip -- **文件**:`SettingsCircuitBadge.vue`、`UserManagementSettings.vue` +- **文件**:`UserManagementSettings.vue` - **备注**:naive 的 `ellipsis: { tooltip: true }` → Arco 的 `ellipsis: true` + 列顶层 `tooltip: true` - **需确认**:长文本省略后悬浮能显示完整内容 @@ -167,7 +161,7 @@ ### 弹窗的遮罩/ESC 行为 - **风险**:Arco 默认 `maskClosable` 和 `escToClose` 都是 `true`。用户填了一半的表单按 ESC 或点遮罩会**直接丢弃且不重置** -- **涉及**:`VoiceApiFormModal.vue`、`VoiceApiConfigurator.vue`、`SettingsCircuitBadge.vue` 的设备面板 +- **涉及**:`VoiceApiFormModal.vue`、`VoiceApiConfigurator.vue` - **需确认**:是否应该设 `:mask-closable="false"` / `:esc-to-close="false"` ### 模型选择弹窗(ProviderFormModal) diff --git a/packages/client/src/api/hermes/mcu-devices.ts b/packages/client/src/api/hermes/mcu-devices.ts deleted file mode 100644 index 2e85dbf..0000000 --- a/packages/client/src/api/hermes/mcu-devices.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { request } from '../client' - -export interface McuDevice { - id: number - name: string - device_code: string - is_official: boolean - created_at: number - lan_connected?: boolean - remote_connected?: boolean -} - -export interface McuDeviceListResponse { - devices: McuDevice[] -} - -export async function fetchMcuDevices(): Promise { - return request('/api/mcu-devices') -} - -export async function createMcuDevice(input: { - name: string - device_code: string -}): Promise { - return request('/api/mcu-devices', { - method: 'POST', - body: JSON.stringify(input), - }) -} - -export async function updateMcuDeviceName(id: number, name: string): Promise { - return request(`/api/mcu-devices/${encodeURIComponent(String(id))}`, { - method: 'PATCH', - body: JSON.stringify({ name }), - }) -} - -export async function deleteMcuDevice(id: number): Promise { - return request(`/api/mcu-devices/${encodeURIComponent(String(id))}`, { - method: 'DELETE', - }) -} - -export async function connectMcuDeviceRemote(id: number): Promise { - return request(`/api/mcu-devices/${encodeURIComponent(String(id))}/remote-connect`, { - method: 'POST', - }) -} - -export async function disconnectMcuDeviceRemote(id: number): Promise { - return request(`/api/mcu-devices/${encodeURIComponent(String(id))}/remote-disconnect`, { - method: 'POST', - }) -} diff --git a/packages/client/src/components/hermes/chat/ChatPanel.vue b/packages/client/src/components/hermes/chat/ChatPanel.vue index 21bf176..5380ad1 100644 --- a/packages/client/src/components/hermes/chat/ChatPanel.vue +++ b/packages/client/src/components/hermes/chat/ChatPanel.vue @@ -19,7 +19,6 @@ import OutlinePanel from "./OutlinePanel.vue"; import FilesPanel from "./FilesPanel.vue"; import TerminalPanel from "./TerminalPanel.vue"; import PageSidebarNav from "@/components/layout/PageSidebarNav.vue"; -import SettingsCircuitBadge from "@/components/layout/SettingsCircuitBadge.vue"; import { isStoredSuperAdmin } from "@/api/client"; import { useDefaultWorkspace } from "@/composables/useDefaultWorkspace"; @@ -1289,7 +1288,6 @@ async function handleSessionModelCustomSubmit() { {{ t("sidebar.settings") }} - diff --git a/packages/client/src/components/hermes/group-chat/GroupChatPanel.vue b/packages/client/src/components/hermes/group-chat/GroupChatPanel.vue index c72a3b9..34163dd 100644 --- a/packages/client/src/components/hermes/group-chat/GroupChatPanel.vue +++ b/packages/client/src/components/hermes/group-chat/GroupChatPanel.vue @@ -11,7 +11,6 @@ import GroupChatInput from './GroupChatInput.vue' import FolderPicker from '@/components/hermes/chat/FolderPicker.vue' import ProfileAvatar from '@/components/hermes/profiles/ProfileAvatar.vue' import PageSidebarNav from '@/components/layout/PageSidebarNav.vue' -import SettingsCircuitBadge from '@/components/layout/SettingsCircuitBadge.vue' import { copyToClipboard } from '@/utils/clipboard' import type { Attachment } from '@/stores/hermes/chat' import type { RoomAgent, RoomInfo } from '@/api/hermes/group-chat' @@ -512,7 +511,6 @@ async function handleApproval(choice: 'once' | 'session' | 'always' | 'deny') { {{ t('sidebar.settings') }} - diff --git a/packages/client/src/components/layout/PageSidebarFooter.vue b/packages/client/src/components/layout/PageSidebarFooter.vue index 802cd64..b21b940 100644 --- a/packages/client/src/components/layout/PageSidebarFooter.vue +++ b/packages/client/src/components/layout/PageSidebarFooter.vue @@ -1,7 +1,6 @@