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 @@