Skip to content

release: v0.6.2 — 更新器可用性修复 - #52

Merged
BlackStar-Agent merged 433 commits into
mainfrom
dev
Nov 3, 2026
Merged

BlackStar-Agent merged 433 commits into
mainfrom
dev

Conversation

@BlackStar-Agent

Copy link
Copy Markdown
Collaborator

版本

v0.6.2(Cargo.toml workspace 版本已 bump)

变更(全部为更新器实测暴露的真实缺陷)

状态机

  • 僵尸 PID 判活:脚本被 SIGKILL 后 PID 变 defunct,kill -0 仍成功 → 任务永久判 running(实测卡死 pulling)。改为同时检查 /proc/<pid>/stat 的 Z 状态。
  • 状态文件 pid 保真:网关 spawn 的是 exec setsid sh script,记录的 child.id() 是中间进程(exec 后立即退出);脚本在 set_phase 时改写为自身 $$。

更新范围与部署

  • 只操作网关服务:compose pull/up 收窄到 exmachina 服务(--no-deps),附属服务(napcat)不再随版本更新被拉取重建(实测误拉 275MB 无关镜像)。
  • 辅助容器同路径挂载(严重):此前挂到 /host 再 -w /host,compose 相对路径 ./entities 被解析成宿主 /host/entities(空目录)→ 重建后挂载全错、编成数据归零(实测 agents 40→0)。改为挂载宿主原始绝对路径。

私有 registry

  • 部署目录 .docker/config.json 自动注入 DOCKER_CONFIG,私有 ghcr 包可一键更新;凭据只留部署目录(.gitignore)。
  • EXM_UPDATE_HELPER_IMAGE 可覆盖辅助镜像;本地已有则跳过 pull(受限网络下拉 Docker Hub 会长时间卡住)。

验收

verify-batch 6/6 全绿(clippy 0 警告 / workspace 测试 / e2e / webui tsc / eslint / 构建)。
生产实测:v0.6.1 镜像上一键更新全链路(pulling → recreating → 重启后 idle),挂载正确、agents:40、版本与 health 正常。

KurohaneKaoruko and others added 30 commits October 7, 2026 23:22
* ci: 工作流触发策略收敛——CI 仅 PR 触发,发版仅 dev→main 合入触发,dev 日常提交零消耗

* docs: 新增开发规范——分支模型/提交纪律/发版仪式/工作流触发矩阵固化成文;CONTRIBUTING 对齐实际提交类型并挂规范入口

* fix: 更新检查分支感知——本地在什么分支就对比该分支的上游(main 用户看 main,dev 开发者看 dev);「上游最新」标签随实际上游渲染

* ui: 「上游最新」行渲染实际上游 ref——不再写死分支名(dev/main 通吃)

* fix: add_message_full 过程数据按 id 原位替换回 jsonl——此前 put 写独立文档,思维链/工具轨迹刷新即失

* feat: 单体直接工具循环——chat_execute(系统提示+历史+工具面自主决策)+ run_round 单体分支 + execute_named 过程轨迹补录

* test: 单体直接循环冒烟(工具回灌/轨迹留痕/无任务图)+ 上下文压缩用例改组模式承载;修复 dev 存量测试编译债(link 字段/ExmConfig::default)

* chore: 版本推进 0.1.1——单体直接工具循环 + 编成模板 + 版本更新/一键更新

* ci: CI/发版流水线补装 libxdo——computer-use 栈(enigo/xcap)链接期缺库,cargo test 未跑先挂

* docs: 单体直接工具循环 4.5 部署实测勾选——真实模型两轮验证通过

* test: git_panel 干净断言过滤注册表播种目录——entities/skills 是测试环境噪声,不属于提交流程

* fix: 更新检查 rev-parse 加 --verify——上游 ref 不存在时保持空值走降级,而非把字面量当 sha 返回

* Fix/cross platform release (#16)

* build: 跨平台编译修复——computer.rs 平台差异(enigo Send/Key::Insert 平台门控)+ 一键更新 Unix 门控;release 流水线支持分支手动触发(编译预验,发布仍钉死 main)

* build: 重生成 tauri icon.ico——原文件是改扩展名的 PNG,Windows 资源编译器与 macOS 图标解码均拒绝

---------

Co-authored-by: BlackStar-Agent <kurohoshi@126.com>

---------

Co-authored-by: KurohaneKaoruko <kurohanekaoruko@gmail.com>
Co-authored-by: Kaoruko <101451942+KurohaneKaoruko@users.noreply.github.com>
* feat: B1 SQLite 存储底座——store.sqlite 主库(会话/消息/任务图/回流/账本/快照/审计)+ 自动迁移旧 FSDB 数据

- store_sqlite.rs: SQLite 实现(62 方法全量移植,WAL 单写者)
- 自动迁移: Store::open 检测旧 FSDB 数据一次性转换
- rusqlite bundled(零外部依赖,构建环境自带 C 编译器即可)
- 已知边界: 证据/事件/检查点/outbox 等低频集合本批次仍走 FsDb

* feat: B1 SQLite 存储底座——store.sqlite 主库 + 自动迁移 + rusqlite 依赖(bundled)

* fix: 补齐 feat/sqlite-storage 分支丢失的 Cargo.toml/lib.rs 改动(分支切换时丢失)
* feat: EXMACHINA 智械体集群 —— Rust 多智能体协作系统(集群调度 / 契约回流 / 三账 / 记忆 / 多模型 / WebUI)

core: orchestrator DAG planning + concurrent dispatch, SyncReport contract enforcement with auto-rewrite, conflict arbitration, three-ledger (task/evidence/risk), recallable memory with decay, group/agent scoping and reliability stats

models: four protocols (openai/anthropic/gemini/azure) with sticky multi-key pools and per-protocol connectivity probe; per-agent/group default model resolution (agent -> group -> global) via ModelPool

platform: skills, cron/heartbeat automation, exec approval gate + auth key; Telegram/webhook/qq/wechat bridge channels; single-process gateway serving REST+WS+WebUI

delivery: exm/exmachina CLI, native-tls via system store, release profile LTO+strip (single binary ~5MB), GitHub Actions release pipeline for compile-free low-spec deployment; WebUI on React 19.3 + antd 6 (14 panels, 5 themes)

docs: four-doc set (install/usage/design/protocol); no provenance metadata in repo

* feat: P0 batch 1 — native function calling, model failover chain, context compaction, followup/collect

function calling: protocol-level tools for openai/anthropic/gemini/azure (definitions, streaming fragment assembly, per-protocol result threading); text protocol kept as mock/compatible fallback; whitelist/approval/audit preserved

failover: profile-level fallback chains (cycle-guarded), 45s cooldown skipping, switch only before any token emitted, global profile tail, model.failover event; provider form gains fallback selector

compaction: multi-turn context for planning — rolling summary (LLM-compressed) + recent-12 window injected into plan prompt; session.rollingSummary/summaryUpto persisted

followup/collect: Core::chat serializes runs per session (all channels migrated); queued inputs within a window merge into one round goal

fix latent ordering assumption: list_messages is chronological (fsdb read_lines), oldest->newest

tests: 17/17 green incl. failover chain/cooldown, compaction+collect semantics

* feat: P1 batch 2 — MCP client (stdio + streamable http) with tool gateway integration

mcp.rs: JSON-RPC 2.0 client, lazy initialize handshake, tools/list snapshot cache (sync) + connection pool (async, Send-safe), per-server allowedAgents visibility, tools/call with text content normalization

integration: config mcpServers[] persisted + hot rebuild on apply_config; ToolGateway.execute_mcp with unified audit; runtime tool specs extended per-agent with mcp:server:tool; native function-calling path routes mcp names; gateway serves GET /api/mcp + POST /api/mcp/refresh with background refresh on startup

tests: 18/18 green incl. in-test axum MCP server covering configure/refresh/snapshot/call/allowlist

* feat: P1 batch 3 — hybrid memory retrieval (semantic embeddings + lexical scoring)

provider: embed() on trait (openai /embeddings + azure deployments), deterministic pseudo-embeddings for mock channel; profile embedModel config + WebUI field

memory: entry vectors with write-path background backfill, query embedding boost in scoring, semantic fallback scan when lexical candidates empty; cosine similarity with layer/group scoping preserved

orchestrator: embed_query via active profile embed model injected into planning + dispatch recall paths

tests: 19/19 green (semantic fallback/boost smoke); serial guard for Core-based tests sharing repo workspace

* feat: P1 batch 4 — web_fetch tool and multimodal image input

web_fetch: ToolName variant with zero-dependency HTML body extraction (script/style/tag stripping, whitespace compaction), 20s timeout, 2MB cap, allowlist + audit semantics; dispatch made async

vision: ChatMessage.images (data URLs) mapped per protocol (openai image_url parts / anthropic base64 image blocks / gemini inline_data); image_stash module stages channel attachments for next planning turn; gateway chat body accepts images; WebUI attach button with canvas compression (<=1280px JPEG 82%, up to 4)

tests: 20/20 green incl. in-test axum page fetch (script/style stripped) and stash take-once semantics

* feat: P2 batch 5 — distributed execution nodes (old-device worker cluster)

protocol: /worker WebSocket endpoint with JSON frames (hello/dispatch/tokens/report/error), authKey auth; WorkerHub pool with per-worker outbound channels, pending dispatch table, token streaming into event bus, timeout-bounded execution

orchestrator: remote-first routing (sync accepts check + remote execute with local fallback, remote.fallback event); Core::set_remote hot-rebuilds orchestrator; execute_unit entry for worker side

worker: WorkerSession client (tokio-tungstenite plain WS) runs full local Core — its own model profiles/tool gateway; exm worker --url --token --id CLI subcommand (hostname default)

tests: 21/21 green incl. two-Core full-wire smoke (worker session via real WS executes dispatched nodes, DAG terminal)

* feat: P2 batch 6 — interrupted-session resume on gateway boot

resume: scan sessions with Executing graphs containing non-terminal nodes; replay done nodes (reports backfilled from sync_reports_by_node, report ids restored), reset interrupted to Ready, re-run scheduler, converge with resumed flag

plumbing: store.sync_report_of_node typed lookup; TaskGraphModel.set_report_id; ExecCtx/run_node/converge made public for resume path; gateway serve() triggers resume at boot

tests: 22/22 green incl. interrupted-graph reconstruction smoke (all nodes terminal, >=3 done after resume)

* feat: P2 batch 7 — terminal hardening (timeout kill) and session token budget

terminal: async execution via tokio (no runtime-thread blocking), kill_on_drop timeouts — 120s dispatch / 300s approval execution; hung commands can no longer stall nodes

budget: maxSessionTokens config (estimated chars/4, 0 = unlimited); Core::chat gate rejects over-budget sessions with clear guidance; schema entry for settings page

tests: isolated per-test agents tree copy (fixes cross-test repo workspace pollution — leftover active_group from interrupted runs broke roster loading); 23/23 green incl. hung-command kill and budget-gate smokes

* feat: P2 batch 8 — voice input pipeline and windows process-tree kill

voice: transcribe on LlmProvider trait (openai/azure /audio/transcriptions, multipart), Core::transcribe via active profile (whisper-1), POST /api/voice/transcribe endpoint; WebUI mic button (MediaRecorder webm -> gateway -> text into input, recording state)

hardening: timeout kill now taskkills the full process tree on Windows (cmd grandchildren no longer leak); pid captured before wait_with_output move

tests: 24/24 green incl. transcribe channel contract (mock explicitly unsupported)

* feat: P2 batch 9 — text-to-speech read-aloud and session usage observability

tts: speak() on LlmProvider trait (openai/azure /audio/speech, mp3 bytes), Core::speak via active profile (tts-1); POST /api/voice/speak returns audio/mpeg; WebUI per-message read-aloud button with playback state

usage: GET /api/sessions/:id/tokens (estimate + budget); chat rail shows live token usage, refreshed per round

tests: 24/24 green (speak channel contract alongside transcribe)

* feat: P1 batch 10 — telegram voice input and channel chat allowlist

voice: telegram voice messages -> getFile download (ogg) -> active-profile transcription -> normal text flow; failed transcription degrades gracefully

security: Channel.allowedChats allowlist (empty = unrestricted); non-listed chats ignored with log; exposed in create/update endpoints and WebUI channel form (comma-separated)

tests: 24/24 green regression

* feat: settings page categorized redesign + empty model defaults without keys

settings: sectioned cards (runtime/memory/security/automation) with icon+description headers, label-left control-right rows, proper widgets (switch for booleans, textarea for prompts/allowlists), per-page save button; LLM section stays on provider page

defaults: model names default to empty instead of gpt-4o placeholders — without API keys placeholder models are meaningless; users set real models when configuring a provider; mock channel ignores model names

gateway: maxSessionTokens exposed in GET/PUT /api/config; settings page shows live budget

* feat(ui): settings page v3 — left category nav, single-panel view

one category visible at a time (runtime/memory/security/automation) instead of stacked cards; enum select for approval mode; per-section save; fixed-width right-aligned controls

* feat: P1 batch 11 — dual memory modes (deep db vs memory.md file-only) + full config exposure

deep-off mode: planning injects memory.md (<=8000 chars) instead of db recall; memory panel becomes markdown editor via GET/PUT /api/memory/md; settings labels clarified

config exposure: GET /api/config now returns memory/security/automation groups — settings page shows actual values instead of schema defaults (was the incomplete part)

* feat: memory.md size limit with autonomous AI compaction and archiving

config: memoryMdMaxChars (default 5000) in memory group + settings schema; PUT /api/memory/md auto-triggers background compaction when over limit

compaction: LLM simplification via orchestrator provider (compression contract), original text archived — deep-on writes digest entry into db (searchable), deep-off appends workspace memory_archive.md; nothing lost either way

ui: md editor shows char count vs limit, save reports background compaction; mock channel deterministic compression output; 25/25 tests green

* feat(ui): units page group selector, flat member list (primary first), no domain division

units page: group dropdown to view/manage any group members (no longer bound to background active group); nav renamed units; primary agent listed first; domain grouping/inputs removed from units/groups/singles create forms — single-domain labels added complexity without value

gateway: DELETE /api/groups/:gid/agents/:identifier for cross-group member management; api.ts removeGroupAgent + allowedChats passthrough on channel create/update

* fix(ui): remove leftover activation wording from management pages

group/channel management pages no longer surface session-scoped activation state; wording aligned to per-session target selection

* feat(ui): language switcher (zh/en) next to theme switcher + shell translations

sidebar language panel in same position/style as theme; localStorage persisted; nav/branding/status/settings fully bilingual via shared i18n infra

cleanup: remove redundant tip line in GroupsView (group switching is already noted in chat rail)

* fix(ui): settings i18n — replace remaining title/desc refs with t() keys

* docs+core: 文档与事实对齐;移除「无密钥自动降级模拟通道」;修复终端超时用例挂起

文档(与代码事实逐条核对)
- docs/协议与契约.md:SyncReport 契约按代码修正(statements / risks /
  blockers{reason,unblockCondition} / conflicts);扩展点路径改 <identifier>.json
- docs/使用指南.md:group/agent create 的名称是位置参数(原文误写 --name);
  补 worker、group export/import、经验优化三节
- docs/架构与设计.md:重复小节去重;测试策略改为「测试替身仅测试使用」
- docs/安装指南.md:FAQ 由「无密钥自动降级模拟通道」改为「不会用模拟输出充数,需先配置模型」

代码(产品行为)
- 新增 UnconfiguredProvider:未配置端点/密钥的通道调用即报错并给出配置指引
- Provider 规则改为显式配置优先:有 base_url+key → 真实推理;未配置 → 替身模式给 Mock、
  产品模式给 Unconfigured;use_mock 仅由 EXM_LLM_MOCK=1(或测试)开启
- 移除全部「自动置 mock」点(config/gateway/cli/install);配置热更新不改变替身状态
- install / doctor / model list / chat 头 / 网关 banner 文案统一为「未配置——请在模型提供商页配置」

测试
- 修复 tools.rs 终端超时路径:stdio 读取独立任务 + 超时 abort + taskkill /T /F +
  child.wait() 有界回收(原实现挂死,曾导致全量测试 20+ 分钟不结束)
- 清理编译告警:删死结构体、noop clone、未用 mut/导入、测试函数名 ASCII 化

验证:cargo test --workspace 8 单测 + 17 冒烟全绿;gateway e2e 92/92 全绿

* ui: 排版层级重构 —— 新增表单只留主流程,可选与运维细节收进「高级设置」

用户反馈:新增提供商把厂商预设全铺成按钮墙、还要求填指挥体/子个体模型、嵌入模型、失败回退——
这些不该出现在「接入一个厂商」的主流程里。

设计原则(本轮确立):一页只回答一件事;可选与运维细节一律折叠,默认收起。

- 「提供商」页重写(ModelsView.tsx)
  - 厂商预设 9 按钮墙 → 下拉(带端点形态提示 + 自定义/自建端点)
  - 主表单只剩:提供商类型 → Base URL → API Key(Key 池为可选多行)
  - 高级设置(折叠):显示名称 / 档案 ID / API 协议 / 默认模型(预设自动填)/
    指挥体与子个体模型覆盖 / 嵌入模型 / 失败回退
  - 卡片信息层级重排:端点(+协议短标签) / 模型 / 密钥状态 / 回退链 / 嵌入模型
  - 措辞修正:不再出现「Mock / 模拟通道」,未配密钥显示「未配置(对话前请补填)」
- 新增统一页头组件 components/PageHeader.tsx(标题 + 一句话说明 + 右侧操作区),
  落地于:提供商 / 子个体 / 智能体组 / 独立智能体 / 技能 / 自动化 / 审批 / 通道 / 记忆 / 活动;
  原先挤在按钮行里的长提示统一挪入说明段(层级:标题 → 说明 → 操作)
- 通道表单 8 项平铺 → 核心 = 平台/通道 ID/Token/绑定组,高级 = 备注/白名单/出站回调
- 自动化表单 6 项平铺 → 触发方式改 Segmented(周期 Cron | 一次性时间)互斥切换,会话标题进高级
- styles.css 新增 .page-head/.page-title/.page-desc/.page-actions/.form-advanced/.model-kv/.form-grid-2
- 命名对齐:与工作区正在进行的「模型提供商 → 提供商」全局改名保持一致

验证:npm run build:webui(tsc + vite)通过;产物含新样式与新文案,
「厂商预设 / 模拟通道 / Mock 模拟」字样已从产物消失;网关实测启动正常(health 200 / 托管 dist / 40 个体)

* ui: 控制台视觉重构 —— 工程图刻度语汇、页面编号 01–14、科研感登录门与任务图

三类线条语汇(全部由 CSS 变量驱动,随 5 套强调色联动):
- hud 角标:面板四角短刻线;scale 刻度尺:等差刻度 + mask 淡出;grid 剖面:低透明度栅格

全局
- 新增令牌 --tick-step / --tick-color / --tick-color-hi / --grid-size / --accent-04·08·30
- body 双向 40px 栅格底纹;全局 tabular-nums 保证读数对齐

侧栏与页头
- 侧栏右缘刻度尺(每 5 格长刻线);菜单项加序号列,序号与图标间加短刻线,选中项左侧荧光轨
- 页面编号 01–14:单一事实源 NAV_ITEMS,侧栏与页头同源
- PageHeader 重构:desc 移出 .page-head-row 独占整行,修复说明文字被操作按钮压住

组件
- 表格表头列间竖刻线分隔;补齐此前完全缺失的 .plain-table / .model-card / .skill-card / .pane-loading
- LedgerView 补页头(原无页头且空态早退);SettingsView 统一 pane-wrap;ChatView 加控制台读数条

仪器感页面
- 登录门:72 条刻度环 + 十字准星 + 双层同心圆,去圆角,标题下加测量基线
- 任务图:坐标刻度、节点状态轨 + 量度条、正交折线连线、NODES/EDGES/DEPTH 读数

文档
- docs/使用指南.md WebUI 章节表格按 01–14 重排

* 提供商页回到「只回答一件事」+ 侧栏/间距回正 + 编排词清理

提供商设置(用户反馈:不该加的东西不要往这加):
- API Key 与 Key 池合并为一个可增删列表,不再分两块填
- 指挥体模型 / 子个体模型从全栈删除(此前只是折进「高级设置」,等于没删):
  LlmProfile/LlmConfig 的 orch_model/unit_model/embed_model 合并为单一 model;
  ModelPool 的 insert/resolve/entry 去掉 unit 参数;expand_chain 同上;
  gateway/CLI/install 向导同步;旧配置由 LlmProfileFile/LlmConfigFile 兼容读取,保存后不再回写旧键
- 嵌入模型移到「记忆」页「语义检索」卡(memory.semanticModel),core 新增 semantic_recall()
- 提供商类型名后不再挂多余描述

WebUI:
- 侧栏去掉序号列、恢复原有顺序与文案(撤销上一轮擅自的改名「独立智能体」与换位)
- .pane-wrap 去掉在已有内边距容器里的二次居中(智能体组/子个体左空隙过大的根因)
- list-rail 300→260px、skill-grid 最小 380→320px

文案:
- 清除「公司架构/团队架构」类比(9 处),示例组名改「研发组」
- 清除自造的「独立智能体」,统一为「智能体」

修复:
- e2e.rs 未带密钥 401 用例中重复的请求行(第二次请求覆盖第一次,属脚本改写的残留)

验证:cargo check --all-targets 0 警告;cargo test 8+17 全绿;e2e 92/92;
tsc --noEmit 干净;vite build 通过;产物禁用语扫描全 0。

* webui: 修复「记忆」页白屏崩溃 + 提供商卡片信息层级 + 设计令牌归一

修复(实测发现,非推断):
- 记忆页整页白屏:MemoryView 用 stats?.memory.total,外层可选链挡不住内层缺失
  (stats 有值而 memory 为 undefined 时照样抛错,整棵 React 树塌掉)。
  改为逐层 stats?.memory?.total ?? 0;同类 config?.memory?.enabled / semanticModel 一并加固。
- 侧栏底栏的 MOCK/LINK 徽标删除:测试替身不是产品状态,违反项目铁律。
  改为「通道就绪 / 未接入」,由 config.llm.apiKey 是否非空驱动。

提供商卡片:
- 改为四行事实:端点 / 模型 / 密钥 / 状态;「全局默认」从标题行移入事实区,
  标题只留身份,不再与操作按钮争位置
- 「已配置(N 把)」原用 warning 琥珀色(读起来像出故障),改为绿色中性态;
  「未配置」才用 warning
- 卡片头统一高度,避免「有无次要按钮」导致事实行跨卡错位
- 页头说明压成一句

版式与令牌:
- 颜色归一:手抄近似值 #8fa6b8 / #9fb6c6 → var(--text),
  rgba(29,42,54,0.6~0.9) → var(--line),共 8 处
- antd token 同步:colorTextSecondary #8fa6b8 → #6d8296(= --muted),
  colorTextTertiary → #4a5c6c(= --muted-dim)
- 智能体组元信息行的全角空格分隔改为真实元素 + flex gap

验证:cargo check --all-targets 0 警告 0 错误;cargo test 8+17 全过;e2e 92/92;
tsc --noEmit 干净;vite build 通过;提供商/记忆/智能体组/侧栏多页截图实拍复核。

* docs: 统一 orchestrator 注释措辞为「单体智能体」

「独立智能体」是此前自造的叫法,全库仅剩这两处(均为注释)。代码库既有术语
是「单体智能体 / 单体模式」(registry.rs、singles.rs、SINGLE_CONTRACT 正文、
smoke.rs 一致使用),本次对齐,全库该词归零。

验证:cargo check --all-targets 无代码级告警;cargo test 8+17 全过;e2e 92/92。

* feat(ui): markdown rendering for chat messages (GFM, dark-theme code blocks)

* feat(ui): session search, rename, and chat rail cleanup

* refactor(ui): groups page — clean flat layout, settings modal, remove inline editing clutter

* feat(ui): groups page settings modal (workspace + default model) with gear button

* fix(ui): chat page declutter — remove duplicate speak btn, simplify console bar, hover session ops, shorter hints

* feat(ui): collapsible chat sidebar with edge toggle button

* fix(ui): restore console bar readouts (MODE/STATE/TOKENS) removed in earlier cleanup

* fix(ui): chat-shell height and CSS cleanup

* fix(ui): chat-shell row-reverse in main rule not trailing override

* fix(ui): remove redundant read-aloud button from message bubbles

* feat(ui): task graph page — session label + selector, clear which session the DAG belongs to

* fix(ui): graph page — stats readout left, session selector right

* feat: one-click quickstart scripts (sh + bat)

* docs: README quickstart — one-click scripts first, manual build second

* feat: full auto-install scripts (install.sh + install.bat) — clone, install deps, build, run

* feat: quickstart downloads prebuilt releases (no compile needed); CI workflow builds and publishes on tag

* chore: move install/quickstart scripts to scripts/ folder; update README URLs

* ci: add test-only workflow on push; release.yml waits for manual tag (no auto-publish until fully tested)

* fix(docs): README ASCII art — pure ASCII # style, equal-width lines render correctly on GitHub

* feat(docs): SVG logo with DAG node design, terminal aesthetic, animated status LED

* docs: SVG logo — 58px font, compact DAG, text glow, fills canvas

* docs: SVG logo — hard edges, diamond DAG nodes, right-angle wire routing, no ONLINE

* docs: SVG logo — diamond nodes drawn after lines (no overlap), diagonal wire routing restored

* docs: redesigned product logo — hex lattice + center diamond, large 68px wordmark; separate 256px app icon

* docs: premium logo — layered hex, glowing core with inner diamond, HUD tick marks, corner brackets, gradient wordmark

* docs: logo — restore EX·MACHINA dot separator, align connector lines to diamond vertices

* docs: full-width banner logo (icon left, wordmark + tagline right); README adds H1 heading; intro text embedded in SVG

* docs: logo — precise flat-top hexagon geometry, centered text block, proper icon-text spacing; README H1 updated

* docs: restore original subtitle and README H1

* docs: README H1 = ExMachina — 一个群体协作的智能集群

* docs: logo subtitle = ExMachina — 一个群体协作的智能集群

* docs: logo — remove icon, pure centered text banner

* docs: logo — 110px title nearly fills width, wider underline

* docs: logo — 100px title with top spacing, 18px subtitle, 14px body text

* docs: add LICENSE (MIT), SECURITY.md, CONTRIBUTING.md

* docs: SECURITY.md and CONTRIBUTING.md now bilingual (zh/en)

* docs: split README into zh (README.md) + en (README_EN.md) with language switcher

* docs: logo subtitle restored to 智械体集群 · MULTI-AGENT CLUSTER

* docs: logo subtitle — 智械体集群 // AGENT CLUSTER (original)

* docs: language switcher moved below badges, centered

* docs: logo — subtitle 18→22px semibold, body 14→18px, brighter colors, more height

* docs: logo — 画布 1200x300,字号与线宽按 Retina 重做;背景改纯色、去副标题

README 头部 SVG 的「字小、线细、锯齿」三个根因与修法:

1. 字小 —— 画布 960x280 经 width=100% 引用后在 GitHub 阅读栏(1012px)
   只剩 ~295px 高。改为 1200x300,主标题 100→88px(配 letter-spacing 撑满)、
   底部文案 18→23px。删掉副标题后标题整体下移到视觉居中。
2. 线细 —— 原字体栈以 'SF Mono','Cascadia Code' 打头,Windows 会落到
   Courier New(细衬线等宽)。字体栈改为 ui-monospace 打头;
   主标题改 fill + 同色 stroke + paint-order 加粗字面。
3. 锯齿 —— 0.4px 级描边在 Retina 上被采样成灰虚线。全部细线提到 >=1.6px
   且落在整数设备像素;移除 0.4px 网格线。

排版取舍:
- 背景改为纯色 #0b1118,不使用渐变。
- 删除副标题「智械体集群 // AGENT CLUSTER」。
- 不加角标等装饰性元素,只保留刻度尺 / HUD 角标 / 边框 / 分隔线。
- 底部文案含「零情绪」,属此前已否掉的自造氛围词,删除;
  压成四个短标签(契约回流 / 冲突裁决 / 证据分级 / 结论收束)。

exmachina-icon.svg 未改动。

* feat: 通道平台全面扩展 —— QQ 官方机器人 / NapCat 适配器 + 运行状态 + 密钥掩码

通道网关(后端):
- 新增 qqbot 适配器:开放平台 WS 长连接,token 缓存提前刷新,断线先 Resume 再
  Identify,被动回复携带 msg_id + 递增 msg_seq,sandbox 可选
- 新增 napcat 适配器:OneBot 11 正向 WS(NapCat / Lagrange 通用),读循环常开 +
  mpsc 专职写任务,数组段与 CQ 码双格式解析
- 通道配置平台目录化:Channel.config{} 扩展配置,新平台零结构体改动;
  create 校验 qqbot 需 appId/appSecret、napcat 需 url
- 通道运行状态:适配器连上/断开/出错覆盖上报,GET /api/channels/status 查询,
  删除/停用即清除
- 密钥全链路掩码回显(***已配置***):顶层 token/secret + 敏感 config 键;
  更新三态语义(掩码沿用 / 空清除 / 新值)
- 修复:PUT /channels/:id 的 body.id 无默认值,前端更新通道(不发 id)一直 422,
  通道编辑与启停开关自上线即不可用;补 #[serde(default)] + e2e 锁定

WebUI:
- 通道页重写为平台目录驱动(PLATFORMS):表单/凭证判定/回复形态由目录出,
  状态列轮询运行状态(已连接 / 连接异常 + 明细)
- 修复:ModelsView 本地掩码哨兵 ***MASK*** 与后端 ***已配置*** 漂移,编辑档案
  不改密钥会把掩码字面量存成 API Key;统一为 api.ts 共享 KEY_MASK
- i18n 架构化:i18n/ 注册表(TKey 编译期键检查,en 缺键回退 zh,新语言零成本),
  全部视图清扫,中英双份词条
- 布局修复:对话页与右侧会话栏间距(row-reverse 无 gap)

验证:
- cargo check --workspace 零警告;e2e 103/103(新增通道校验/掩码落盘/状态接口
  断言;e2e 环境自持,不再随本机 config 漂移)
- npm build 通过;通道页中英表格与编辑弹窗截图复核

* feat: 「提供商」→「模型设置」—— 模型清单 + 能力模型(组级覆盖)+ 视觉转述

模型设置页(原「提供商」页改名,nav.models):
- LlmProfile.models[]:每个提供商一份模型清单(模型名 + 视觉/语音能力开关);
  默认模型保存时自动并入清单;清单未标记 = 能力未知,输入直通(向后兼容)
- 能力模型槽位(capabilities 配置节 + GET/PUT /api/llm/capabilities):
  语音合成(TTS)/ 语音识别(语音转述)/ 视觉转述 / 嵌入;
  嵌入与记忆页 semanticModel 同一字段(两处入口等价);TTS/STT 由硬编码 tts-1/whisper-1
  改为按槽位解析,未配置回落原默认
- 视觉转述降级:生效模型明确 vision=false 且配置了转述模型时,逐图转文字描述注入规划;
  未配置则忽略图片并在输入中说明;能力未知保持直通
- UI:提供商卡新增模型清单行(默认 / 视觉 / 语音);页底「能力模型 · 全局默认」卡;
  编辑弹窗 Form.List 模型清单(开关 + 增删)

组级能力覆盖(能力槽位不再全局单值):
- GroupMeta.capabilities 持久化 + PUT /api/groups/:id/capabilities
  (空串 = 清除该项跟随全局;全空 = 整块收回)
- 槽位解析两级:组覆盖 → 全局槽位 → 出厂默认;TTS / STT / 视觉转述 / 嵌入四处统一
- 组设置弹窗新增「能力模型(组级覆盖)」四槽位,留空 = 跟随全局默认

修复:
- tr() 改用 useLang.getState() 同步读语言:原 hook 形式在组件渲染期被调用
  (构造 Select options)会把 hook 计入当前组件,两次渲染间钩子数漂移导致 React #310
  全树崩溃;同时消除 api.ts / models.ts 三处同类隐患

验证:cargo check 零警告;e2e 全过(模型清单与开关回显、能力槽位写入/回读、
组级覆盖写入/空串清除/落盘回读);npm build 通过;中英双页截图复核

* docs: README 头部改用同款 EXMACHINA 字符画(字母间 2 空格),快速开始前移至告警之后

* docs: 警告块前移至字符画之前(H1 下首元素)

* docs: 字符画首行补 1 空格对齐 88 列——修复逐行居中渲染下的右偏

* build(rust): toolchain by host + silence Linux-only unused pid

- rust-toolchain.toml / .cargo/config.toml: switch to stable channel so
  rustup auto-selects the host triple (Linux/macOS/Windows all build
  without edits); comment updated accordingly.

- crates/exm-core/src/tools.rs: mark the local \`pid\` binding with
  \`cfg_attr(not(target_os = \"windows\"), allow(unused_variables))\`.
  The PID is only consumed inside the Windows taskkill branch; on POSIX,
  tokio::Child::kill_on_drop already handles process teardown.

Verified on Debian 13 / x86_64-unknown-linux-gnu: `cargo check --workspace`
and `cargo build --workspace --release` both report zero warnings; the
`exm` / `exmachina` / `exm-gateway` binaries are produced and a
`cargo run -p exm-gateway --release` smoke test answers
`/api/health` with agents=40, ok=true.

* feat(gateway): bind on 0.0.0.0 by default; add --host flag

VPS / 容器 / 局域网部署场景下,loopback 默认值导致 '能跑起来但远程
访问不到'。改为:

- exm-gateway 默认监听 0.0.0.0,公网/局域网可访问(向后兼容:
  EXM_HOST=127.0.0.1 或 --host 127.0.0.1 仍可收紧)。
- `exm serve` 新增 --host 选项(短 -H),显式传入覆盖默认 / 环境变量。
- 启动日志链接打印改为绑定到的真实地址(不写死 127.0.0.1)。

API 变化:`exm_gateway::serve(core, port)` → `serve(core, port, host: Option<&str>)`,
库调用方需更新;唯一调用方(exm-cli 与 exm-gateway 独立入口)已同步。

* fix: 批量修复 WebUI/网关缺陷 17 项(API Key 保存与池掩码令牌化、鉴权设置入口、个体/智能体编辑、设置页契约、WS 重连竞态、间距统一等)+ 主智能体更名指挥体 + 单体去职责化;并入在途 WIP(browser 闸门/自定义工具/discord/matrix/slack 通道)

* fix: API Key 表单绑定真根因(Form.List 行绑定致输入被过滤)+ 智能体卡片 ⋮ 菜单(切换模型/编辑描述/编辑 SOUL.MD)+ 单体人设读写与 plan/converge 双注入 + 默认组/指挥体英文标注映射

* feat: 安装脚本重写(4 文件)——预检/重试/校验和/升级保数据/--port/--help/品牌化输出;修 macOS arm64 硬编码与构建日志吞错;bat 改 PS5.1 引导壳全 ASCII 免疫代码页 bug

* chore: 移除误入提交的测试残留文件 upgrading

* docs: 移除 README 低性能设备预编译包引导段落

* Update README with project inspiration details

Added a note about the project's inspiration from Ex-Machina in No Game No Life.

* Fix formatting in README.md for project inspiration

* feat: 编码体验全量落地 + 编成组目录制定稿 + Computer Use + WebUI 编码工作台/PWA + 桌面端 Tauri 壳

思维链与过程透明(对标编码型 Agent):
- provider 双轨流式:解析 reasoning_content/thinking_delta/Gemini thought,新增
  StreamDelta::{Text,Thinking};新 WS 事件 orchestrator.thinking / unit.thinking
- tool.call / tool.result 事件(callId/args/ok/耗时/摘要/images),工具执行全程可见
- 审批等待回灌:拦截后原地等待 approvalWaitSecs,批准后代执行、输出直灌模型继续干活
- WebUI 聊天页:思维流折叠、工具执行卡(edit diff/终端输出/截图预览)、内联审批卡

Computer Use:
- computer 工具(enigo 键鼠 + xcap 截屏):screenshot/click/move/scroll/type/key
- 默认关闭显式开启;输入动作过审批闸门 + 动作节流;截图经 ToolResult.images
  回灌视觉模型(vision 能力检测)并可在工具卡内预览

WebUI:
- 新增编码工作台 [CODE]:会话 | 工具优先对话流 | 工作区文件树 + 变更清单 + 代码预览
- 网关配套 /api/asset(截图预览)与 /api/fs/list|file(文件树/预览,沙箱只读)
- PWA(manifest + Service Worker + 图标)与移动端抽屉导航;与客户端同端口交付

编成组目录制定稿(多轮评审定稿):
- 组 = groups/<gid>/:group.json + SOUL.md(主智能体人格,仅用户面持有)+
  MEMORY.md(组浅层记忆快照,6000 字截断)+ agents/*.json + prompts/*.md + adaptations/
- 单体 = singles/<id>/:agent.json + PROMPT.md + SOUL.md + MEMORY.md
- 子个体无人格层、无独立文件夹(定义+提示词合并存储于组内);深/浅记忆分层语义定稿
- 提示词分层:主智能体偏助手(对话优先/L0 直答)、子个体各司其职(编码位增补作业纪律)、
  单体全能;registry 全链适配 + gen-agents.mjs/doctor/install/e2e 同步

桌面端:
- desktop/(Tauri v2):捆绑 exm-gateway sidecar 本机模式 + --remote/--key 远程直连,
  退出杀进程树;MSVC 为官方构建目标(README 内说明)

测试:test_config 密封化(强制 Mock + 审批等待 0);新增审批等待回灌三场景用例;
cargo test --workspace 8 单测 + 21 冒烟全绿;npm run build:webui 通过;网关冒烟全过

* chore: 接入 OpenSpec 规范驱动开发——新增 openspec/ 目录骨架与配置,.gitignore 放行 .gitkeep

* feat: OpenSpec 变更 capability-completion 落地(1/3)——配置 v2 六段新配置与迁移、存储三集合骨架、patch 补丁工具(统一 diff 解析/整体拒绝/行尾容差)+ coding/ops 白名单

* feat: capability-completion(2/3)——工作区变更接口(git 口径/检查点回退)、文件保存接口(沙箱+检查点+审计)、simple_unified_diff 生成器;测试 5+23 全绿

* feat: capability-completion(3/3 P0)——git 面板(概览/暂存/提交/切换 + 破坏性审批单)、CodingView 三标签改造、webui i18n;测试 3/5 全绿

* test: P0 闸门验证——修复上游脆弱测试(审批等待用例未显式声明 risky 闸门模式);workspace 52 测试全绿

* feat: capability-completion 组3 通道身份与门控——/pair 配对码(短码/TTL/单次)、入站统一闸门(群聊唤醒门控+身份管控前置裁决)、六适配器提及归一化(tg getMe 缓存/discord mentions/slack app_mention/napcat CQ:at/qqbot @驱动/matrix m.mentions)、审批单来源升级标(origin_user/origin_role)、IdentityPanel 控制台 UI;闸门单测 5/5

* feat: capability-completion 组4 用量治理——滑动窗口限流(通道主体/API 维度)、周期配额(请求数 @admit + token @run,按会话台账)、组内派发豁免、/api/limits/stats + SettingsView 用量卡片;P0 闸门关闭(workspace 全绿 68 测、validate 通过)

* feat: capability-completion 组6(1/3)——出站能力矩阵与降级决策、typing 指示(telegram/discord)、长回复分段推送(段落优先/代码块完整/超长硬切续接);回复分段/降级单测 5 个

* docs: design.md 增补 D12——媒体产物透出(outbox/artifacts)与出站投递实施口径(组 6.2-6.4)

* feat: capability-completion 组6(2/3)——媒体产物透出(outbox/截图与投递目录登记/run.finished artifacts)、spawn_reply 双闭包投递(直发+降级并注)、telegram/discord/slack 媒体直发(multipart/三步上传)

* feat: capability-completion 组6(3/3)——napcat 媒体直发(base64:// 段,远程安全)、matrix 媒体上传(media v3→content_uri)、入站媒体解析(telegram photo/document、discord attachments、napcat 段:下载落 inbox→图片暂存/文件注记,失败回退)+ 注入单测 2

* feat: capability-completion 组6 收尾——slack url_private 下载 / qqbot attachments / matrix mxc 媒体下载与失败占位回退;六通道入站媒体全通 + 注入/回退单测

* feat: capability-completion 组7-9——事件触发器(文件监听去抖合并/webhook HMAC+审计/cron 推送订阅/心跳 per-agent)、记忆三工具(组隔离/source=agent/主智能体默认授权)、会话历史管控(轮次快照/undo 检查点联动/编辑重发/fork 分支+REST+WebUI 入口)

* feat: capability-completion 组10 MCP 服务端——ACL 可见性矩阵(组/会话/工具清单)、stdio exm mcp serve(JSON-RPC 会话亲和)、网关 /mcp HTTP 挂载(鉴权+限流)、外部调用安全口径一致(审批/审计 mcp 来源标注);协议端到端/亲和/ACL/审批口径测试

* feat: capability-completion 组11-12——桌面集成(系统托盘/关窗驻留可配/原生通知三类含类别开关与事件映射单测/全局快捷键可改绑冲突提示)、doctor 新配置段诊断、文档同步(README 能力表/使用指南新章节/协议契约 REST+WS 事件)、原创性验收禁用词零命中

* chore: capability-completion 12.4 最终闸门——Dockerfile 补齐容器构建/运行时依赖(xcap dbus vendored 静态编译、enigo libxdo 构建包与 X11 运行时栈),compose 冒烟通过(health ok + 40 个体装载)

* chore: compose 支持 EXM_AUTH_KEY 注入(后台访问密钥,.env 注入不入库)

* fix: 用户测试反馈 12 项——WS 鉴权豁免(浏览器无法带头)+服务端 Ping 保活+客户端指数退避看门狗、组页卡片化+子个体并入组详情、编码页撤并为对话页编码模式开关、指挥体显示名目标感知、弹窗防溢出+全局紧凑化、MiniMax 预设+端点模型清单拉取+默认模型改清单选择、登录页十六进制稳定 8 列、导航改模型/网关措辞

* i18n: 组详情视图新增键(返回/交互中/组成员等)

* fix: 左下角「通道就绪」改「模型就绪/模型未配置」(区分 IM 通道页与模型接入状态),WS 断连提示统一网关措辞

* feat: 体验优化批次——组内个体/单体系统提示词在线编辑(PROMPT 读写端点+弹窗重构,去领域/能力字段)、orchestrator 改名去前缀+主智能体标签后置、设置页移除用量卡、加载/输出卡互斥+内联<think>归入思维链(MiniMax-M1)、组卡片头换行修复、单体菜单重构(修改PROMPT.md/删除沉底确认)、Machina 提示词沉浸化重写(去系统机制自述)

* fix: 组卡片头单行(名称不折+id省略号)与设置页撑满正式部署;此前容器误载旧CSS(column版)

* fix: 块级标题卡片(组卡/模型卡/单体卡/技能卡)隐藏标题内联装饰——装饰遇块级标题折行为「装饰行+文字行+装饰行」

* fix: 卡片标题装饰保留并与文字同行——组卡/模型卡标题容器改 inline-flex(内联装饰不再被块级标题挤到独立行)

* fix: 设置页界面分类选中时运行时不再误亮(current回退groups[0]的bug);webui细节打磨——移除压角测量标记、选中色/光标跟随强调色、控件圆角统一、卡片与表格悬停反馈、弹窗分隔线质感、内联代码样式、菜单选中强调线、滚动条细化

* fix: 侧栏分隔线移除无意义的「CHANNEL」标签(避免与真正的通道页混淆)

* feat: 对话界面过程呈现重构(OpenCode 模式)——撤编码模式开关;思维链随收束留存(不再消失);思维/工具/调度过程全部收入「使用了 N 个…」收起栏(默认收起、点击展开、流式带呼吸点)

* fix: 内联<think>分流截断点按字符边界回退——中文等多字节思考内容触发 is_char_boundary 断言恐慌(线上实测);回归测试覆盖多字节小步增量/完整分离/前缀判定

* fix: 删除当前会话未从 sessions 列表状态移除——后续删除用旧快照重建列表导致已删会话「复活」;统一从 getState 最新状态过滤并先落列表

* fix: 规划阶段流式输出改道思维轨——L0/L1+ 的内部协议 JSON 不再裸奔到可见输出区;非流式回退的内联<think>按阶段分轨(思考轨/可见轨)

* fix: 断点续跑改后台执行——不再阻塞端口绑定(中断会话的多节点调度+LLM往返曾导致启动期间整站502)

* feat: ux-refinements 组1-4 实施——停止轮次(令牌+检查点+端点+按钮+通道/stop)、思维链落盘(messages 扩展+round_trace)、会话搜索/通道标识过滤/导出、工具审计页、用量面板回归、审批跳转、通道连通测试探针、cron 下次执行+模板

* chore: ux-refinements 任务勾选

* feat: 智能连结网络(实验性)——nexus.links 配置段+LinkTarget、连结体执行器(exmachina REST/CLI opencode/codex/claude/custom)、编成 link 代理声明+run_node 路由、连结体 CRUD 端点与智能体组页管理区、指挥体/子个体集群措辞与默认智能体改名「智能连结」

* fix: 「智能连结」是默认智能体组名(连结体)而非单体智能体——组名改智能连结、单体恢复 Machina;registry 缺省组名同步

* fix: 智能连结网络独立为侧栏页(智能体组下方);组成员单元格 id 移到中文名下方;恢复成员 SOUL.md 编辑(重构时误删);NexusView 补 message 导入

* ui: 侧栏顺序调整——任务图/自动化上移至技能/模型之前

* ui: 智能连结网络显性实验性声明(侧栏实验角标+页内警示条)+ 图标改 ClusterOutlined 消除与任务图撞图标

* fix: 智能连结网络实验声明改到点子上——如实说明设想尚未被验证、效果可能达不到预期,而非泛泛的接口变动免责

* ui: 智能连结网络实验声明精简为一句话

* ui: 侧栏智能连结项精简命名并保证左对齐单行(实验角标浮右)

* ui: 侧栏实验角标改为紧跟文字内联(浮右被甩出可视区)

* ui: 侧栏不再显示实验角标——实验声明保留在智能连结网络页内

* feat: experience-polish 实施——草稿/召回/复制/会话预览与相对时间、浏览器通知(授权+分类开关+点击跳转)、hash 视图路由+会话深链、骨架屏+横幅统一

* chore: experience-polish 任务勾选

* feat: WebUI 移动端适配——触屏操作常显(无hover)、设置页纵向堆叠、表格横向滚动兜底、网格窄屏单列、刘海屏安全区、页头操作换行

* ui: 回到底部悬浮按钮+视图切换淡入

* fix: 登录页窄屏适配——品牌字 clamp 缩放不再截断;底部签名去「全连结」残留(指挥体就绪)

* ui: 登录页签名去掉 DEUS 前缀(恢复用户已删的措辞)

* fix: 设置页 SECTIONS 补齐 6 个新分类(Computer Use/通道身份/用量限制/事件触发器/MCP 服务端/结果推送)——此前选择这些分类因缺 SECTIONS 条目导致面板永远加载

* refactor: agents 结构重组——skills 移至项目根、protocol 移入默认组、组 id default→exmachina

* feat: 默认智能体/指挥体/默认 SOUL 提示词全面重构——参考成熟编码智能体注入完整编码工作流(编辑纪律/终端纪律/搜索策略/调试流程)、机械语言协议(状态播报/情绪抑制/判定短语)、安全与权限协议、错误分级处理

* fix: SOUL.md 去掉身份标签只留人设描述;registry 残留 default 引用清理

* fix: SOUL 文件去除元描述引言——组指挥体与默认人格只留角色本身

* ui: 组成员表紧凑列宽——子个体列固定 220 消除空白,职责 260,工具/状态列收窄

* fix: 组成员提示词校验文案修正——不再误用模型名提示

* fix: SOUL 只留性格层(工作流归 PROMPT);成员表 tableLayout=fixed + 子个体列 220 真正生效

* refactor: 编成目录 agents/ → entities/——entities/agents(单体,常见 AI 软件同款) + entities/groups(智能体组);修复 skills 未入镜像

* copy: 默认智能体描述精简——默认智能体,以「本机」自称

* ui: 组成员表工具列加宽到 300,职责列让位——标签不再逐行堆叠

* rename: 子个体「媒体体」→「影音体」——避免「媒体+体」双体拗口

* feat: 编成模板机制——entities/templates/(unit×4 + group×1),用户与 agent 均可基于模板创建组和子个体(GET /api/templates + agent_manage templates/create + 前端模板选择)

* fix: 模板创建按 template.json 的 id 解析目录(此前误用 id 拼路径导致创建失败)

* feat: 版本更新功能——版本号定为 0.1.0,/api/version(+check) 对比上游 dev,设置页「版本更新」面板,Docker 构建注入 GIT_HASH

* fix: compose build.args 重复键合并——GIT_HASH 与 EXM_LANG 同段

* feat: 一键更新——POST /api/version/apply 经 docker.sock 执行 git pull→build→up -d,状态轮询端点 + 设置页一键更新按钮与恢复检测

* change: 更新检查源 dev→main——发版口径(dev 开发线,merge 到 main 时推送新版本);main 尚不存在时优雅降级提示

* fix: 一键更新重启步骤借道一次性辅助容器——compose 客户端不再随被重启的旧容器一起被杀(实测踩坑:recreate 半途而废)

* fix: 工具链下载 ADD url → RUN curl --retry——消除构建期持续联网校验,网络抖动不再炸构建

* fix: 一键更新工具链改挂载宿主 docker cli/compose 插件——移除构建期下载,内层构建零网络依赖(根治缓存不命中+网络抖动)

* docs: 替换“智械体集群”为“智能集群”并更新示例文案

* fix: 更新脚本自造 DOCKER_CONFIG/config.json——docker pull 无配置文件时报 no configuration file provided

* perf: GIT_HASH 移至 runtime 阶段注入——commit 变化不再作废 Rust 编译缓存(外层构建 10min→<1min,一键更新内层构建不再触发 rustup 全量同步)

* copy: 更新检查描述去掉工作流括号说明

* fix: 辅助容器挂载仓库宿主真实路径(从容器 mount 反解)——/host 只存在于网关容器内,宿主侧不存在导致 compose 找不到编排文件

* ci: 工作流触发策略收敛——CI 仅 PR 触发,发版仅 dev→main 合入触发,dev 日常提交零消耗

* docs: 新增开发规范——分支模型/提交纪律/发版仪式/工作流触发矩阵固化成文;CONTRIBUTING 对齐实际提交类型并挂规范入口

* fix: 更新检查分支感知——本地在什么分支就对比该分支的上游(main 用户看 main,dev 开发者看 dev);「上游最新」标签随实际上游渲染

* ui: 「上游最新」行渲染实际上游 ref——不再写死分支名(dev/main 通吃)

* fix: add_message_full 过程数据按 id 原位替换回 jsonl——此前 put 写独立文档,思维链/工具轨迹刷新即失

* feat: 单体直接工具循环——chat_execute(系统提示+历史+工具面自主决策)+ run_round 单体分支 + execute_named 过程轨迹补录

* test: 单体直接循环冒烟(工具回灌/轨迹留痕/无任务图)+ 上下文压缩用例改组模式承载;修复 dev 存量测试编译债(link 字段/ExmConfig::default)

* chore: 版本推进 0.1.1——单体直接工具循环 + 编成模板 + 版本更新/一键更新

* ci: CI/发版流水线补装 libxdo——computer-use 栈(enigo/xcap)链接期缺库,cargo test 未跑先挂

* docs: 单体直接工具循环 4.5 部署实测勾选——真实模型两轮验证通过

* test: git_panel 干净断言过滤注册表播种目录——entities/skills 是测试环境噪声,不属于提交流程

* fix: 更新检查 rev-parse 加 --verify——上游 ref 不存在时保持空值走降级,而非把字面量当 sha 返回

* release: v0.1.1 (#12)

* ci: 工作流触发策略收敛——CI 仅 PR 触发,发版仅 dev→main 合入触发,dev 日常提交零消耗

* docs: 新增开发规范——分支模型/提交纪律/发版仪式/工作流触发矩阵固化成文;CONTRIBUTING 对齐实际提交类型并挂规范入口

* fix: 更新检查分支感知——本地在什么分支就对比该分支的上游(main 用户看 main,dev 开发者看 dev);「上游最新」标签随实际上游渲染

* ui: 「上游最新」行渲染实际上游 ref——不再写死分支名(dev/main 通吃)

* fix: add_message_full 过程数据按 id 原位替换回 jsonl——此前 put 写独立文档,思维链/工具轨迹刷新即失

* feat: 单体直接工具循环——chat_execute(系统提示+历史+工具面自主决策)+ run_round 单体分支 + execute_named 过程轨迹补录

* test: 单体直接循环冒烟(工具回灌/轨迹留痕/无任务图)+ 上下文压缩用例改组模式承载;修复 dev 存量测试编译债(link 字段/ExmConfig::default)

* chore: 版本推进 0.1.1——单体直接工具循环 + 编成模板 + 版本更新/一键更新

* ci: CI/发版流水线补装 libxdo——computer-use 栈(enigo/xcap)链接期缺库,cargo test 未跑先挂

* docs: 单体直接工具循环 4.5 部署实测勾选——真实模型两轮验证通过

* test: git_panel 干净断言过滤注册表播种目录——entities/skills 是测试环境噪声,不属于提交流程

* fix: 更新检查 rev-parse 加 --verify——上游 ref 不存在时保持空值走降级,而非把字面量当 sha 返回

---------

Co-authored-by: KurohaneKaoruko <kurohanekaoruko@gmail.com>

* Fix/cross platform release (#16)

* build: 跨平台编译修复——computer.rs 平台差异(enigo Send/Key::Insert 平台门控)+ 一键更新 Unix 门控;release 流水线支持分支手动触发(编译预验,发布仍钉死 main)

* build: 重生成 tauri icon.ico——原文件是改扩展名的 PNG,Windows 资源编译器与 macOS 图标解码均拒绝

---------

Co-authored-by: BlackStar-Agent <kurohoshi@126.com>

* build: 桌面端重写为 egui 纯原生应用(无 webview)——chat-first 主窗口 + 原生设置页 + 隐藏终端侧车 + Inno Setup/tar.gz/dmg 安装链 (#18)

* feat: B1 SQLite 存储底座——store.sqlite 主库(会话/消息/任务图/回流/账本/快照/审计)+ 自动迁移旧 FSDB 数据

- store_sqlite.rs: SQLite 实现(62 方法全量移植,WAL 单写者)
- 自动迁移: Store::open 检测旧 FSDB 数据一次性转换
- rusqlite bundled(零外部依赖,构建环境自带 C 编译器即可)
- 已知边界: 证据/事件/检查点/outbox 等低频集合本批次仍走 FsDb

* feat: B1 SQLite 存储底座——store.sqlite 主库 + 自动迁移 + rusqlite 依赖(bundled)

* build: 打包脚本路径改仓库根口径——移除 ../ 前缀(CI 上指向仓库外)

* ci: 发版 tag 自动追加后缀——同版本重发时自动递增(v0.1.1 → v0.1.1.1 → v0.1.1.2),不再跳过

---------

Co-authored-by: KurohaneKaoruko <kurohanekaoruko@gmail.com>
Co-authored-by: BlackStar-Agent <blackstar-agent@users.noreply.github.com>
Co-authored-by: Kaoruko <101451942+KurohaneKaoruko@users.noreply.github.com>
* feat: EXMACHINA 智械体集群 —— Rust 多智能体协作系统(集群调度 / 契约回流 / 三账 / 记忆 / 多模型 / WebUI)

core: orchestrator DAG planning + concurrent dispatch, SyncReport contract enforcement with auto-rewrite, conflict arbitration, three-ledger (task/evidence/risk), recallable memory with decay, group/agent scoping and reliability stats

models: four protocols (openai/anthropic/gemini/azure) with sticky multi-key pools and per-protocol connectivity probe; per-agent/group default model resolution (agent -> group -> global) via ModelPool

platform: skills, cron/heartbeat automation, exec approval gate + auth key; Telegram/webhook/qq/wechat bridge channels; single-process gateway serving REST+WS+WebUI

delivery: exm/exmachina CLI, native-tls via system store, release profile LTO+strip (single binary ~5MB), GitHub Actions release pipeline for compile-free low-spec deployment; WebUI on React 19.3 + antd 6 (14 panels, 5 themes)

docs: four-doc set (install/usage/design/protocol); no provenance metadata in repo

* feat: P0 batch 1 — native function calling, model failover chain, context compaction, followup/collect

function calling: protocol-level tools for openai/anthropic/gemini/azure (definitions, streaming fragment assembly, per-protocol result threading); text protocol kept as mock/compatible fallback; whitelist/approval/audit preserved

failover: profile-level fallback chains (cycle-guarded), 45s cooldown skipping, switch only before any token emitted, global profile tail, model.failover event; provider form gains fallback selector

compaction: multi-turn context for planning — rolling summary (LLM-compressed) + recent-12 window injected into plan prompt; session.rollingSummary/summaryUpto persisted

followup/collect: Core::chat serializes runs per session (all channels migrated); queued inputs within a window merge into one round goal

fix latent ordering assumption: list_messages is chronological (fsdb read_lines), oldest->newest

tests: 17/17 green incl. failover chain/cooldown, compaction+collect semantics

* feat: P1 batch 2 — MCP client (stdio + streamable http) with tool gateway integration

mcp.rs: JSON-RPC 2.0 client, lazy initialize handshake, tools/list snapshot cache (sync) + connection pool (async, Send-safe), per-server allowedAgents visibility, tools/call with text content normalization

integration: config mcpServers[] persisted + hot rebuild on apply_config; ToolGateway.execute_mcp with unified audit; runtime tool specs extended per-agent with mcp:server:tool; native function-calling path routes mcp names; gateway serves GET /api/mcp + POST /api/mcp/refresh with background refresh on startup

tests: 18/18 green incl. in-test axum MCP server covering configure/refresh/snapshot/call/allowlist

* feat: P1 batch 3 — hybrid memory retrieval (semantic embeddings + lexical scoring)

provider: embed() on trait (openai /embeddings + azure deployments), deterministic pseudo-embeddings for mock channel; profile embedModel config + WebUI field

memory: entry vectors with write-path background backfill, query embedding boost in scoring, semantic fallback scan when lexical candidates empty; cosine similarity with layer/group scoping preserved

orchestrator: embed_query via active profile embed model injected into planning + dispatch recall paths

tests: 19/19 green (semantic fallback/boost smoke); serial guard for Core-based tests sharing repo workspace

* feat: P1 batch 4 — web_fetch tool and multimodal image input

web_fetch: ToolName variant with zero-dependency HTML body extraction (script/style/tag stripping, whitespace compaction), 20s timeout, 2MB cap, allowlist + audit semantics; dispatch made async

vision: ChatMessage.images (data URLs) mapped per protocol (openai image_url parts / anthropic base64 image blocks / gemini inline_data); image_stash module stages channel attachments for next planning turn; gateway chat body accepts images; WebUI attach button with canvas compression (<=1280px JPEG 82%, up to 4)

tests: 20/20 green incl. in-test axum page fetch (script/style stripped) and stash take-once semantics

* feat: P2 batch 5 — distributed execution nodes (old-device worker cluster)

protocol: /worker WebSocket endpoint with JSON frames (hello/dispatch/tokens/report/error), authKey auth; WorkerHub pool with per-worker outbound channels, pending dispatch table, token streaming into event bus, timeout-bounded execution

orchestrator: remote-first routing (sync accepts check + remote execute with local fallback, remote.fallback event); Core::set_remote hot-rebuilds orchestrator; execute_unit entry for worker side

worker: WorkerSession client (tokio-tungstenite plain WS) runs full local Core — its own model profiles/tool gateway; exm worker --url --token --id CLI subcommand (hostname default)

tests: 21/21 green incl. two-Core full-wire smoke (worker session via real WS executes dispatched nodes, DAG terminal)

* feat: P2 batch 6 — interrupted-session resume on gateway boot

resume: scan sessions with Executing graphs containing non-terminal nodes; replay done nodes (reports backfilled from sync_reports_by_node, report ids restored), reset interrupted to Ready, re-run scheduler, converge with resumed flag

plumbing: store.sync_report_of_node typed lookup; TaskGraphModel.set_report_id; ExecCtx/run_node/converge made public for resume path; gateway serve() triggers resume at boot

tests: 22/22 green incl. interrupted-graph reconstruction smoke (all nodes terminal, >=3 done after resume)

* feat: P2 batch 7 — terminal hardening (timeout kill) and session token budget

terminal: async execution via tokio (no runtime-thread blocking), kill_on_drop timeouts — 120s dispatch / 300s approval execution; hung commands can no longer stall nodes

budget: maxSessionTokens config (estimated chars/4, 0 = unlimited); Core::chat gate rejects over-budget sessions with clear guidance; schema entry for settings page

tests: isolated per-test agents tree copy (fixes cross-test repo workspace pollution — leftover active_group from interrupted runs broke roster loading); 23/23 green incl. hung-command kill and budget-gate smokes

* feat: P2 batch 8 — voice input pipeline and windows process-tree kill

voice: transcribe on LlmProvider trait (openai/azure /audio/transcriptions, multipart), Core::transcribe via active profile (whisper-1), POST /api/voice/transcribe endpoint; WebUI mic button (MediaRecorder webm -> gateway -> text into input, recording state)

hardening: timeout kill now taskkills the full process tree on Windows (cmd grandchildren no longer leak); pid captured before wait_with_output move

tests: 24/24 green incl. transcribe channel contract (mock explicitly unsupported)

* feat: P2 batch 9 — text-to-speech read-aloud and session usage observability

tts: speak() on LlmProvider trait (openai/azure /audio/speech, mp3 bytes), Core::speak via active profile (tts-1); POST /api/voice/speak returns audio/mpeg; WebUI per-message read-aloud button with playback state

usage: GET /api/sessions/:id/tokens (estimate + budget); chat rail shows live token usage, refreshed per round

tests: 24/24 green (speak channel contract alongside transcribe)

* feat: P1 batch 10 — telegram voice input and channel chat allowlist

voice: telegram voice messages -> getFile download (ogg) -> active-profile transcription -> normal text flow; failed transcription degrades gracefully

security: Channel.allowedChats allowlist (empty = unrestricted); non-listed chats ignored with log; exposed in create/update endpoints and WebUI channel form (comma-separated)

tests: 24/24 green regression

* feat: settings page categorized redesign + empty model defaults without keys

settings: sectioned cards (runtime/memory/security/automation) with icon+description headers, label-left control-right rows, proper widgets (switch for booleans, textarea for prompts/allowlists), per-page save button; LLM section stays on provider page

defaults: model names default to empty instead of gpt-4o placeholders — without API keys placeholder models are meaningless; users set real models when configuring a provider; mock channel ignores model names

gateway: maxSessionTokens exposed in GET/PUT /api/config; settings page shows live budget

* feat(ui): settings page v3 — left category nav, single-panel view

one category visible at a time (runtime/memory/security/automation) instead of stacked cards; enum select for approval mode; per-section save; fixed-width right-aligned controls

* feat: P1 batch 11 — dual memory modes (deep db vs memory.md file-only) + full config exposure

deep-off mode: planning injects memory.md (<=8000 chars) instead of db recall; memory panel becomes markdown editor via GET/PUT /api/memory/md; settings labels clarified

config exposure: GET /api/config now returns memory/security/automation groups — settings page shows actual values instead of schema defaults (was the incomplete part)

* feat: memory.md size limit with autonomous AI compaction and archiving

config: memoryMdMaxChars (default 5000) in memory group + settings schema; PUT /api/memory/md auto-triggers background compaction when over limit

compaction: LLM simplification via orchestrator provider (compression contract), original text archived — deep-on writes digest entry into db (searchable), deep-off appends workspace memory_archive.md; nothing lost either way

ui: md editor shows char count vs limit, save reports background compaction; mock channel deterministic compression output; 25/25 tests green

* feat(ui): units page group selector, flat member list (primary first), no domain division

units page: group dropdown to view/manage any group members (no longer bound to background active group); nav renamed units; primary agent listed first; domain grouping/inputs removed from units/groups/singles create forms — single-domain labels added complexity without value

gateway: DELETE /api/groups/:gid/agents/:identifier for cross-group member management; api.ts removeGroupAgent + allowedChats passthrough on channel create/update

* fix(ui): remove leftover activation wording from management pages

group/channel management pages no longer surface session-scoped activation state; wording aligned to per-session target selection

* feat(ui): language switcher (zh/en) next to theme switcher + shell translations

sidebar language panel in same position/style as theme; localStorage persisted; nav/branding/status/settings fully bilingual via shared i18n infra

cleanup: remove redundant tip line in GroupsView (group switching is already noted in chat rail)

* fix(ui): settings i18n — replace remaining title/desc refs with t() keys

* docs+core: 文档与事实对齐;移除「无密钥自动降级模拟通道」;修复终端超时用例挂起

文档(与代码事实逐条核对)
- docs/协议与契约.md:SyncReport 契约按代码修正(statements / risks /
  blockers{reason,unblockCondition} / conflicts);扩展点路径改 <identifier>.json
- docs/使用指南.md:group/agent create 的名称是位置参数(原文误写 --name);
  补 worker、group export/import、经验优化三节
- docs/架构与设计.md:重复小节去重;测试策略改为「测试替身仅测试使用」
- docs/安装指南.md:FAQ 由「无密钥自动降级模拟通道」改为「不会用模拟输出充数,需先配置模型」

代码(产品行为)
- 新增 UnconfiguredProvider:未配置端点/密钥的通道调用即报错并给出配置指引
- Provider 规则改为显式配置优先:有 base_url+key → 真实推理;未配置 → 替身模式给 Mock、
  产品模式给 Unconfigured;use_mock 仅由 EXM_LLM_MOCK=1(或测试)开启
- 移除全部「自动置 mock」点(config/gateway/cli/install);配置热更新不改变替身状态
- install / doctor / model list / chat 头 / 网关 banner 文案统一为「未配置——请在模型提供商页配置」

测试
- 修复 tools.rs 终端超时路径:stdio 读取独立任务 + 超时 abort + taskkill /T /F +
  child.wait() 有界回收(原实现挂死,曾导致全量测试 20+ 分钟不结束)
- 清理编译告警:删死结构体、noop clone、未用 mut/导入、测试函数名 ASCII 化

验证:cargo test --workspace 8 单测 + 17 冒烟全绿;gateway e2e 92/92 全绿

* ui: 排版层级重构 —— 新增表单只留主流程,可选与运维细节收进「高级设置」

用户反馈:新增提供商把厂商预设全铺成按钮墙、还要求填指挥体/子个体模型、嵌入模型、失败回退——
这些不该出现在「接入一个厂商」的主流程里。

设计原则(本轮确立):一页只回答一件事;可选与运维细节一律折叠,默认收起。

- 「提供商」页重写(ModelsView.tsx)
  - 厂商预设 9 按钮墙 → 下拉(带端点形态提示 + 自定义/自建端点)
  - 主表单只剩:提供商类型 → Base URL → API Key(Key 池为可选多行)
  - 高级设置(折叠):显示名称 / 档案 ID / API 协议 / 默认模型(预设自动填)/
    指挥体与子个体模型覆盖 / 嵌入模型 / 失败回退
  - 卡片信息层级重排:端点(+协议短标签) / 模型 / 密钥状态 / 回退链 / 嵌入模型
  - 措辞修正:不再出现「Mock / 模拟通道」,未配密钥显示「未配置(对话前请补填)」
- 新增统一页头组件 components/PageHeader.tsx(标题 + 一句话说明 + 右侧操作区),
  落地于:提供商 / 子个体 / 智能体组 / 独立智能体 / 技能 / 自动化 / 审批 / 通道 / 记忆 / 活动;
  原先挤在按钮行里的长提示统一挪入说明段(层级:标题 → 说明 → 操作)
- 通道表单 8 项平铺 → 核心 = 平台/通道 ID/Token/绑定组,高级 = 备注/白名单/出站回调
- 自动化表单 6 项平铺 → 触发方式改 Segmented(周期 Cron | 一次性时间)互斥切换,会话标题进高级
- styles.css 新增 .page-head/.page-title/.page-desc/.page-actions/.form-advanced/.model-kv/.form-grid-2
- 命名对齐:与工作区正在进行的「模型提供商 → 提供商」全局改名保持一致

验证:npm run build:webui(tsc + vite)通过;产物含新样式与新文案,
「厂商预设 / 模拟通道 / Mock 模拟」字样已从产物消失;网关实测启动正常(health 200 / 托管 dist / 40 个体)

* ui: 控制台视觉重构 —— 工程图刻度语汇、页面编号 01–14、科研感登录门与任务图

三类线条语汇(全部由 CSS 变量驱动,随 5 套强调色联动):
- hud 角标:面板四角短刻线;scale 刻度尺:等差刻度 + mask 淡出;grid 剖面:低透明度栅格

全局
- 新增令牌 --tick-step / --tick-color / --tick-color-hi / --grid-size / --accent-04·08·30
- body 双向 40px 栅格底纹;全局 tabular-nums 保证读数对齐

侧栏与页头
- 侧栏右缘刻度尺(每 5 格长刻线);菜单项加序号列,序号与图标间加短刻线,选中项左侧荧光轨
- 页面编号 01–14:单一事实源 NAV_ITEMS,侧栏与页头同源
- PageHeader 重构:desc 移出 .page-head-row 独占整行,修复说明文字被操作按钮压住

组件
- 表格表头列间竖刻线分隔;补齐此前完全缺失的 .plain-table / .model-card / .skill-card / .pane-loading
- LedgerView 补页头(原无页头且空态早退);SettingsView 统一 pane-wrap;ChatView 加控制台读数条

仪器感页面
- 登录门:72 条刻度环 + 十字准星 + 双层同心圆,去圆角,标题下加测量基线
- 任务图:坐标刻度、节点状态轨 + 量度条、正交折线连线、NODES/EDGES/DEPTH 读数

文档
- docs/使用指南.md WebUI 章节表格按 01–14 重排

* 提供商页回到「只回答一件事」+ 侧栏/间距回正 + 编排词清理

提供商设置(用户反馈:不该加的东西不要往这加):
- API Key 与 Key 池合并为一个可增删列表,不再分两块填
- 指挥体模型 / 子个体模型从全栈删除(此前只是折进「高级设置」,等于没删):
  LlmProfile/LlmConfig 的 orch_model/unit_model/embed_model 合并为单一 model;
  ModelPool 的 insert/resolve/entry 去掉 unit 参数;expand_chain 同上;
  gateway/CLI/install 向导同步;旧配置由 LlmProfileFile/LlmConfigFile 兼容读取,保存后不再回写旧键
- 嵌入模型移到「记忆」页「语义检索」卡(memory.semanticModel),core 新增 semantic_recall()
- 提供商类型名后不再挂多余描述

WebUI:
- 侧栏去掉序号列、恢复原有顺序与文案(撤销上一轮擅自的改名「独立智能体」与换位)
- .pane-wrap 去掉在已有内边距容器里的二次居中(智能体组/子个体左空隙过大的根因)
- list-rail 300→260px、skill-grid 最小 380→320px

文案:
- 清除「公司架构/团队架构」类比(9 处),示例组名改「研发组」
- 清除自造的「独立智能体」,统一为「智能体」

修复:
- e2e.rs 未带密钥 401 用例中重复的请求行(第二次请求覆盖第一次,属脚本改写的残留)

验证:cargo check --all-targets 0 警告;cargo test 8+17 全绿;e2e 92/92;
tsc --noEmit 干净;vite build 通过;产物禁用语扫描全 0。

* webui: 修复「记忆」页白屏崩溃 + 提供商卡片信息层级 + 设计令牌归一

修复(实测发现,非推断):
- 记忆页整页白屏:MemoryView 用 stats?.memory.total,外层可选链挡不住内层缺失
  (stats 有值而 memory 为 undefined 时照样抛错,整棵 React 树塌掉)。
  改为逐层 stats?.memory?.total ?? 0;同类 config?.memory?.enabled / semanticModel 一并加固。
- 侧栏底栏的 MOCK/LINK 徽标删除:测试替身不是产品状态,违反项目铁律。
  改为「通道就绪 / 未接入」,由 config.llm.apiKey 是否非空驱动。

提供商卡片:
- 改为四行事实:端点 / 模型 / 密钥 / 状态;「全局默认」从标题行移入事实区,
  标题只留身份,不再与操作按钮争位置
- 「已配置(N 把)」原用 warning 琥珀色(读起来像出故障),改为绿色中性态;
  「未配置」才用 warning
- 卡片头统一高度,避免「有无次要按钮」导致事实行跨卡错位
- 页头说明压成一句

版式与令牌:
- 颜色归一:手抄近似值 #8fa6b8 / #9fb6c6 → var(--text),
  rgba(29,42,54,0.6~0.9) → var(--line),共 8 处
- antd token 同步:colorTextSecondary #8fa6b8 → #6d8296(= --muted),
  colorTextTertiary → #4a5c6c(= --muted-dim)
- 智能体组元信息行的全角空格分隔改为真实元素 + flex gap

验证:cargo check --all-targets 0 警告 0 错误;cargo test 8+17 全过;e2e 92/92;
tsc --noEmit 干净;vite build 通过;提供商/记忆/智能体组/侧栏多页截图实拍复核。

* docs: 统一 orchestrator 注释措辞为「单体智能体」

「独立智能体」是此前自造的叫法,全库仅剩这两处(均为注释)。代码库既有术语
是「单体智能体 / 单体模式」(registry.rs、singles.rs、SINGLE_CONTRACT 正文、
smoke.rs 一致使用),本次对齐,全库该词归零。

验证:cargo check --all-targets 无代码级告警;cargo test 8+17 全过;e2e 92/92。

* feat(ui): markdown rendering for chat messages (GFM, dark-theme code blocks)

* feat(ui): session search, rename, and chat rail cleanup

* refactor(ui): groups page — clean flat layout, settings modal, remove inline editing clutter

* feat(ui): groups page settings modal (workspace + default model) with gear button

* fix(ui): chat page declutter — remove duplicate speak btn, simplify console bar, hover session ops, shorter hints

* feat(ui): collapsible chat sidebar with edge toggle button

* fix(ui): restore console bar readouts (MODE/STATE/TOKENS) removed in earlier cleanup

* fix(ui): chat-shell height and CSS cleanup

* fix(ui): chat-shell row-reverse in main rule not trailing override

* fix(ui): remove redundant read-aloud button from message bubbles

* feat(ui): task graph page — session label + selector, clear which session the DAG belongs to

* fix(ui): graph page — stats readout left, session selector right

* feat: one-click quickstart scripts (sh + bat)

* docs: README quickstart — one-click scripts first, manual build second

* feat: full auto-install scripts (install.sh + install.bat) — clone, install deps, build, run

* feat: quickstart downloads prebuilt releases (no compile needed); CI workflow builds and publishes on tag

* chore: move install/quickstart scripts to scripts/ folder; update README URLs

* ci: add test-only workflow on push; release.yml waits for manual tag (no auto-publish until fully tested)

* fix(docs): README ASCII art — pure ASCII # style, equal-width lines render correctly on GitHub

* feat(docs): SVG logo with DAG node design, terminal aesthetic, animated status LED

* docs: SVG logo — 58px font, compact DAG, text glow, fills canvas

* docs: SVG logo — hard edges, diamond DAG nodes, right-angle wire routing, no ONLINE

* docs: SVG logo — diamond nodes drawn after lines (no overlap), diagonal wire routing restored

* docs: redesigned product logo — hex lattice + center diamond, large 68px wordmark; separate 256px app icon

* docs: premium logo — layered hex, glowing core with inner diamond, HUD tick marks, corner brackets, gradient wordmark

* docs: logo — restore EX·MACHINA dot separator, align connector lines to diamond vertices

* docs: full-width banner logo (icon left, wordmark + tagline right); README adds H1 heading; intro text embedded in SVG

* docs: logo — precise flat-top hexagon geometry, centered text block, proper icon-text spacing; README H1 updated

* docs: restore original subtitle and README H1

* docs: README H1 = ExMachina — 一个群体协作的智能集群

* docs: logo subtitle = ExMachina — 一个群体协作的智能集群

* docs: logo — remove icon, pure centered text banner

* docs: logo — 110px title nearly fills width, wider underline

* docs: logo — 100px title with top spacing, 18px subtitle, 14px body text

* docs: add LICENSE (MIT), SECURITY.md, CONTRIBUTING.md

* docs: SECURITY.md and CONTRIBUTING.md now bilingual (zh/en)

* docs: split README into zh (README.md) + en (README_EN.md) with language switcher

* docs: logo subtitle restored to 智械体集群 · MULTI-AGENT CLUSTER

* docs: logo subtitle — 智械体集群 // AGENT CLUSTER (original)

* docs: language switcher moved below badges, centered

* docs: logo — subtitle 18→22px semibold, body 14→18px, brighter colors, more height

* docs: logo — 画布 1200x300,字号与线宽按 Retina 重做;背景改纯色、去副标题

README 头部 SVG 的「字小、线细、锯齿」三个根因与修法:

1. 字小 —— 画布 960x280 经 width=100% 引用后在 GitHub 阅读栏(1012px)
   只剩 ~295px 高。改为 1200x300,主标题 100→88px(配 letter-spacing 撑满)、
   底部文案 18→23px。删掉副标题后标题整体下移到视觉居中。
2. 线细 —— 原字体栈以 'SF Mono','Cascadia Code' 打头,Windows 会落到
   Courier New(细衬线等宽)。字体栈改为 ui-monospace 打头;
   主标题改 fill + 同色 stroke + paint-order 加粗字面。
3. 锯齿 —— 0.4px 级描边在 Retina 上被采样成灰虚线。全部细线提到 >=1.6px
   且落在整数设备像素;移除 0.4px 网格线。

排版取舍:
- 背景改为纯色 #0b1118,不使用渐变。
- 删除副标题「智械体集群 // AGENT CLUSTER」。
- 不加角标等装饰性元素,只保留刻度尺 / HUD 角标 / 边框 / 分隔线。
- 底部文案含「零情绪」,属此前已否掉的自造氛围词,删除;
  压成四个短标签(契约回流 / 冲突裁决 / 证据分级 / 结论收束)。

exmachina-icon.svg 未改动。

* feat: 通道平台全面扩展 —— QQ 官方机器人 / NapCat 适配器 + 运行状态 + 密钥掩码

通道网关(后端):
- 新增 qqbot 适配器:开放平台 WS 长连接,token 缓存提前刷新,断线先 Resume 再
  Identify,被动回复携带 msg_id + 递增 msg_seq,sandbox 可选
- 新增 napcat 适配器:OneBot 11 正向 WS(NapCat / Lagrange 通用),读循环常开 +
  mpsc 专职写任务,数组段与 CQ 码双格式解析
- 通道配置平台目录化:Channel.config{} 扩展配置,新平台零结构体改动;
  create 校验 qqbot 需 appId/appSecret、napcat 需 url
- 通道运行状态:适配器连上/断开/出错覆盖上报,GET /api/channels/status 查询,
  删除/停用即清除
- 密钥全链路掩码回显(***已配置***):顶层 token/secret + 敏感 config 键;
  更新三态语义(掩码沿用 / 空清除 / 新值)
- 修复:PUT /channels/:id 的 body.id 无默认值,前端更新通道(不发 id)一直 422,
  通道编辑与启停开关自上线即不可用;补 #[serde(default)] + e2e 锁定

WebUI:
- 通道页重写为平台目录驱动(PLATFORMS):表单/凭证判定/回复形态由目录出,
  状态列轮询运行状态(已连接 / 连接异常 + 明细)
- 修复:ModelsView 本地掩码哨兵 ***MASK*** 与后端 ***已配置*** 漂移,编辑档案
  不改密钥会把掩码字面量存成 API Key;统一为 api.ts 共享 KEY_MASK
- i18n 架构化:i18n/ 注册表(TKey 编译期键检查,en 缺键回退 zh,新语言零成本),
  全部视图清扫,中英双份词条
- 布局修复:对话页与右侧会话栏间距(row-reverse 无 gap)

验证:
- cargo check --workspace 零警告;e2e 103/103(新增通道校验/掩码落盘/状态接口
  断言;e2e 环境自持,不再随本机 config 漂移)
- npm build 通过;通道页中英表格与编辑弹窗截图复核

* feat: 「提供商」→「模型设置」—— 模型清单 + 能力模型(组级覆盖)+ 视觉转述

模型设置页(原「提供商」页改名,nav.models):
- LlmProfile.models[]:每个提供商一份模型清单(模型名 + 视觉/语音能力开关);
  默认模型保存时自动并入清单;清单未标记 = 能力未知,输入直通(向后兼容)
- 能力模型槽位(capabilities 配置节 + GET/PUT /api/llm/capabilities):
  语音合成(TTS)/ 语音识别(语音转述)/ 视觉转述 / 嵌入;
  嵌入与记忆页 semanticModel 同一字段(两处入口等价);TTS/STT 由硬编码 tts-1/whisper-1
  改为按槽位解析,未配置回落原默认
- 视觉转述降级:生效模型明确 vision=false 且配置了转述模型时,逐图转文字描述注入规划;
  未配置则忽略图片并在输入中说明;能力未知保持直通
- UI:提供商卡新增模型清单行(默认 / 视觉 / 语音);页底「能力模型 · 全局默认」卡;
  编辑弹窗 Form.List 模型清单(开关 + 增删)

组级能力覆盖(能力槽位不再全局单值):
- GroupMeta.capabilities 持久化 + PUT /api/groups/:id/capabilities
  (空串 = 清除该项跟随全局;全空 = 整块收回)
- 槽位解析两级:组覆盖 → 全局槽位 → 出厂默认;TTS / STT / 视觉转述 / 嵌入四处统一
- 组设置弹窗新增「能力模型(组级覆盖)」四槽位,留空 = 跟随全局默认

修复:
- tr() 改用 useLang.getState() 同步读语言:原 hook 形式在组件渲染期被调用
  (构造 Select options)会把 hook 计入当前组件,两次渲染间钩子数漂移导致 React #310
  全树崩溃;同时消除 api.ts / models.ts 三处同类隐患

验证:cargo check 零警告;e2e 全过(模型清单与开关回显、能力槽位写入/回读、
组级覆盖写入/空串清除/落盘回读);npm build 通过;中英双页截图复核

* docs: README 头部改用同款 EXMACHINA 字符画(字母间 2 空格),快速开始前移至告警之后

* docs: 警告块前移至字符画之前(H1 下首元素)

* docs: 字符画首行补 1 空格对齐 88 列——修复逐行居中渲染下的右偏

* build(rust): toolchain by host + silence Linux-only unused pid

- rust-toolchain.toml / .cargo/config.toml: switch to stable channel so
  rustup auto-selects the host triple (Linux/macOS/Windows all build
  without edits); comment updated accordingly.

- crates/exm-core/src/tools.rs: mark the local \`pid\` binding with
  \`cfg_attr(not(target_os = \"windows\"), allow(unused_variables))\`.
  The PID is only consumed inside the Windows taskkill branch; on POSIX,
  tokio::Child::kill_on_drop already handles process teardown.

Verified on Debian 13 / x86_64-unknown-linux-gnu: `cargo check --workspace`
and `cargo build --workspace --release` both report zero warnings; the
`exm` / `exmachina` / `exm-gateway` binaries are produced and a
`cargo run -p exm-gateway --release` smoke test answers
`/api/health` with agents=40, ok=true.

* feat(gateway): bind on 0.0.0.0 by default; add --host flag

VPS / 容器 / 局域网部署场景下,loopback 默认值导致 '能跑起来但远程
访问不到'。改为:

- exm-gateway 默认监听 0.0.0.0,公网/局域网可访问(向后兼容:
  EXM_HOST=127.0.0.1 或 --host 127.0.0.1 仍可收紧)。
- `exm serve` 新增 --host 选项(短 -H),显式传入覆盖默认 / 环境变量。
- 启动日志链接打印改为绑定到的真实地址(不写死 127.0.0.1)。

API 变化:`exm_gateway::serve(core, port)` → `serve(core, port, host: Option<&str>)`,
库调用方需更新;唯一调用方(exm-cli 与 exm-gateway 独立入口)已同步。

* fix: 批量修复 WebUI/网关缺陷 17 项(API Key 保存与池掩码令牌化、鉴权设置入口、个体/智能体编辑、设置页契约、WS 重连竞态、间距统一等)+ 主智能体更名指挥体 + 单体去职责化;并入在途 WIP(browser 闸门/自定义工具/discord/matrix/slack 通道)

* fix: API Key 表单绑定真根因(Form.List 行绑定致输入被过滤)+ 智能体卡片 ⋮ 菜单(切换模型/编辑描述/编辑 SOUL.MD)+ 单体人设读写与 plan/converge 双注入 + 默认组/指挥体英文标注映射

* feat: 安装脚本重写(4 文件)——预检/重试/校验和/升级保数据/--port/--help/品牌化输出;修 macOS arm64 硬编码与构建日志吞错;bat 改 PS5.1 引导壳全 ASCII 免疫代码页 bug

* chore: 移除误入提交的测试残留文件 upgrading

* docs: 移除 README 低性能设备预编译包引导段落

* Update README with project inspiration details

Added a note about the project's inspiration from Ex-Machina in No Game No Life.

* Fix formatting in README.md for project inspiration

* feat: 编码体验全量落地 + 编成组目录制定稿 + Computer Use + WebUI 编码工作台/PWA + 桌面端 Tauri 壳

思维链与过程透明(对标编码型 Agent):
- provider 双轨流式:解析 reasoning_content/thinking_delta/Gemini thought,新增
  StreamDelta::{Text,Thinking};新 WS 事件 orchestrator.thinking / unit.thinking
- tool.call / tool.result 事件(callId/args/ok/耗时/摘要/images),工具执行全程可见
- 审批等待回灌:拦截后原地等待 approvalWaitSecs,批准后代执行、输出直灌模型继续干活
- WebUI 聊天页:思维流折叠、工具执行卡(edit diff/终端输出/截图预览)、内联审批卡

Computer Use:
- computer 工具(enigo 键鼠 + xcap 截屏):screenshot/click/move/scroll/type/key
- 默认关闭显式开启;输入动作过审批闸门 + 动作节流;截图经 ToolResult.images
  回灌视觉模型(vision 能力检测)并可在工具卡内预览

WebUI:
- 新增编码工作台 [CODE]:会话 | 工具优先对话流 | 工作区文件树 + 变更清单 + 代码预览
- 网关配套 /api/asset(截图预览)与 /api/fs/list|file(文件树/预览,沙箱只读)
- PWA(manifest + Service Worker + 图标)与移动端抽屉导航;与客户端同端口交付

编成组目录制定稿(多轮评审定稿):
- 组 = groups/<gid>/:group.json + SOUL.md(主智能体人格,仅用户面持有)+
  MEMORY.md(组浅层记忆快照,6000 字截断)+ agents/*.json + prompts/*.md + adaptations/
- 单体 = singles/<id>/:agent.json + PROMPT.md + SOUL.md + MEMORY.md
- 子个体无人格层、无独立文件夹(定义+提示词合并存储于组内);深/浅记忆分层语义定稿
- 提示词分层:主智能体偏助手(对话优先/L0 直答)、子个体各司其职(编码位增补作业纪律)、
  单体全能;registry 全链适配 + gen-agents.mjs/doctor/install/e2e 同步

桌面端:
- desktop/(Tauri v2):捆绑 exm-gateway sidecar 本机模式 + --remote/--key 远程直连,
  退出杀进程树;MSVC 为官方构建目标(README 内说明)

测试:test_config 密封化(强制 Mock + 审批等待 0);新增审批等待回灌三场景用例;
cargo test --workspace 8 单测 + 21 冒烟全绿;npm run build:webui 通过;网关冒烟全过

* chore: 接入 OpenSpec 规范驱动开发——新增 openspec/ 目录骨架与配置,.gitignore 放行 .gitkeep

* feat: OpenSpec 变更 capability-completion 落地(1/3)——配置 v2 六段新配置与迁移、存储三集合骨架、patch 补丁工具(统一 diff 解析/整体拒绝/行尾容差)+ coding/ops 白名单

* feat: capability-completion(2/3)——工作区变更接口(git 口径/检查点回退)、文件保存接口(沙箱+检查点+审计)、simple_unified_diff 生成器;测试 5+23 全绿

* feat: capability-completion(3/3 P0)——git 面板(概览/暂存/提交/切换 + 破坏性审批单)、CodingView 三标签改造、webui i18n;测试 3/5 全绿

* test: P0 闸门验证——修复上游脆弱测试(审批等待用例未显式声明 risky 闸门模式);workspace 52 测试全绿

* feat: capability-completion 组3 通道身份与门控——/pair 配对码(短码/TTL/单次)、入站统一闸门(群聊唤醒门控+身份管控前置裁决)、六适配器提及归一化(tg getMe 缓存/discord mentions/slack app_mention/napcat CQ:at/qqbot @驱动/matrix m.mentions)、审批单来源升级标(origin_user/origin_role)、IdentityPanel 控制台 UI;闸门单测 5/5

* feat: capability-completion 组4 用量治理——滑动窗口限流(通道主体/API 维度)、周期配额(请求数 @admit + token @run,按会话台账)、组内派发豁免、/api/limits/stats + SettingsView 用量卡片;P0 闸门关闭(workspace 全绿 68 测、validate 通过)

* feat: capability-completion 组6(1/3)——出站能力矩阵与降级决策、typing 指示(telegram/discord)、长回复分段推送(段落优先/代码块完整/超长硬切续接);回复分段/降级单测 5 个

* docs: design.md 增补 D12——媒体产物透出(outbox/artifacts)与出站投递实施口径(组 6.2-6.4)

* feat: capability-completion 组6(2/3)——媒体产物透出(outbox/截图与投递目录登记/run.finished artifacts)、spawn_reply 双闭包投递(直发+降级并注)、telegram/discord/slack 媒体直发(multipart/三步上传)

* feat: capability-completion 组6(3/3)——napcat 媒体直发(base64:// 段,远程安全)、matrix 媒体上传(media v3→content_uri)、入站媒体解析(telegram photo/document、discord attachments、napcat 段:下载落 inbox→图片暂存/文件注记,失败回退)+ 注入单测 2

* feat: capability-completion 组6 收尾——slack url_private 下载 / qqbot attachments / matrix mxc 媒体下载与失败占位回退;六通道入站媒体全通 + 注入/回退单测

* feat: capability-completion 组7-9——事件触发器(文件监听去抖合并/webhook HMAC+审计/cron 推送订阅/心跳 per-agent)、记忆三工具(组隔离/source=agent/主智能体默认授权)、会话历史管控(轮次快照/undo 检查点联动/编辑重发/fork 分支+REST+WebUI 入口)

* feat: capability-completion 组10 MCP 服务端——ACL 可见性矩阵(组/会话/工具清单)、stdio exm mcp serve(JSON-RPC 会话亲和)、网关 /mcp HTTP 挂载(鉴权+限流)、外部调用安全口径一致(审批/审计 mcp 来源标注);协议端到端/亲和/ACL/审批口径测试

* feat: capability-completion 组11-12——桌面集成(系统托盘/关窗驻留可配/原生通知三类含类别开关与事件映射单测/全局快捷键可改绑冲突提示)、doctor 新配置段诊断、文档同步(README 能力表/使用指南新章节/协议契约 REST+WS 事件)、原创性验收禁用词零命中

* chore: capability-completion 12.4 最终闸门——Dockerfile 补齐容器构建/运行时依赖(xcap dbus vendored 静态编译、enigo libxdo 构建包与 X11 运行时栈),compose 冒烟通过(health ok + 40 个体装载)

* chore: compose 支持 EXM_AUTH_KEY 注入(后台访问密钥,.env 注入不入库)

* fix: 用户测试反馈 12 项——WS 鉴权豁免(浏览器无法带头)+服务端 Ping 保活+客户端指数退避看门狗、组页卡片化+子个体并入组详情、编码页撤并为对话页编码模式开关、指挥体显示名目标感知、弹窗防溢出+全局紧凑化、MiniMax 预设+端点模型清单拉取+默认模型改清单选择、登录页十六进制稳定 8 列、导航改模型/网关措辞

* i18n: 组详情视图新增键(返回/交互中/组成员等)

* fix: 左下角「通道就绪」改「模型就绪/模型未配置」(区分 IM 通道页与模型接入状态),WS 断连提示统一网关措辞

* feat: 体验优化批次——组内个体/单体系统提示词在线编辑(PROMPT 读写端点+弹窗重构,去领域/能力字段)、orchestrator 改名去前缀+主智能体标签后置、设置页移除用量卡、加载/输出卡互斥+内联<think>归入思维链(MiniMax-M1)、组卡片头换行修复、单体菜单重构(修改PROMPT.md/删除沉底确认)、Machina 提示词沉浸化重写(去系统机制自述)

* fix: 组卡片头单行(名称不折+id省略号)与设置页撑满正式部署;此前容器误载旧CSS(column版)

* fix: 块级标题卡片(组卡/模型卡/单体卡/技能卡)隐藏标题内联装饰——装饰遇块级标题折行为「装饰行+文字行+装饰行」

* fix: 卡片标题装饰保留并与文字同行——组卡/模型卡标题容器改 inline-flex(内联装饰不再被块级标题挤到独立行)

* fix: 设置页界面分类选中时运行时不再误亮(current回退groups[0]的bug);webui细节打磨——移除压角测量标记、选中色/光标跟随强调色、控件圆角统一、卡片与表格悬停反馈、弹窗分隔线质感、内联代码样式、菜单选中强调线、滚动条细化

* fix: 侧栏分隔线移除无意义的「CHANNEL」标签(避免与真正的通道页混淆)

* feat: 对话界面过程呈现重构(OpenCode 模式)——撤编码模式开关;思维链随收束留存(不再消失);思维/工具/调度过程全部收入「使用了 N 个…」收起栏(默认收起、点击展开、流式带呼吸点)

* fix: 内联<think>分流截断点按字符边界回退——中文等多字节思考内容触发 is_char_boundary 断言恐慌(线上实测);回归测试覆盖多字节小步增量/完整分离/前缀判定

* fix: 删除当前会话未从 sessions 列表状态移除——后续删除用旧快照重建列表导致已删会话「复活」;统一从 getState 最新状态过滤并先落列表

* fix: 规划阶段流式输出改道思维轨——L0/L1+ 的内部协议 JSON 不再裸奔到可见输出区;非流式回退的内联<think>按阶段分轨(思考轨/可见轨)

* fix: 断点续跑改后台执行——不再阻塞端口绑定(中断会话的多节点调度+LLM往返曾导致启动期间整站502)

* feat: ux-refinements 组1-4 实施——停止轮次(令牌+检查点+端点+按钮+通道/stop)、思维链落盘(messages 扩展+round_trace)、会话搜索/通道标识过滤/导出、工具审计页、用量面板回归、审批跳转、通道连通测试探针、cron 下次执行+模板

* chore: ux-refinements 任务勾选

* feat: 智能连结网络(实验性)——nexus.links 配置段+LinkTarget、连结体执行器(exmachina REST/CLI opencode/codex/claude/custom)、编成 link 代理声明+run_node 路由、连结体 CRUD 端点与智能体组页管理区、指挥体/子个体集群措辞与默认智能体改名「智能连结」

* fix: 「智能连结」是默认智能体组名(连结体)而非单体智能体——组名改智能连结、单体恢复 Machina;registry 缺省组名同步

* fix: 智能连结网络独立为侧栏页(智能体组下方);组成员单元格 id 移到中文名下方;恢复成员 SOUL.md 编辑(重构时误删);NexusView 补 message 导入

* ui: 侧栏顺序调整——任务图/自动化上移至技能/模型之前

* ui: 智能连结网络显性实验性声明(侧栏实验角标+页内警示条)+ 图标改 ClusterOutlined 消除与任务图撞图标

* fix: 智能连结网络实验声明改到点子上——如实说明设想尚未被验证、效果可能达不到预期,而非泛泛的接口变动免责

* ui: 智能连结网络实验声明精简为一句话

* ui: 侧栏智能连结项精简命名并保证左对齐单行(实验角标浮右)

* ui: 侧栏实验角标改为紧跟文字内联(浮右被甩出可视区)

* ui: 侧栏不再显示实验角标——实验声明保留在智能连结网络页内

* feat: experience-polish 实施——草稿/召回/复制/会话预览与相对时间、浏览器通知(授权+分类开关+点击跳转)、hash 视图路由+会话深链、骨架屏+横幅统一

* chore: experience-polish 任务勾选

* feat: WebUI 移动端适配——触屏操作常显(无hover)、设置页纵向堆叠、表格横向滚动兜底、网格窄屏单列、刘海屏安全区、页头操作换行

* ui: 回到底部悬浮按钮+视图切换淡入

* fix: 登录页窄屏适配——品牌字 clamp 缩放不再截断;底部签名去「全连结」残留(指挥体就绪)

* ui: 登录页签名去掉 DEUS 前缀(恢复用户已删的措辞)

* fix: 设置页 SECTIONS 补齐 6 个新分类(Computer Use/通道身份/用量限制/事件触发器/MCP 服务端/结果推送)——此前选择这些分类因缺 SECTIONS 条目导致面板永远加载

* refactor: agents 结构重组——skills 移至项目根、protocol 移入默认组、组 id default→exmachina

* feat: 默认智能体/指挥体/默认 SOUL 提示词全面重构——参考成熟编码智能体注入完整编码工作流(编辑纪律/终端纪律/搜索策略/调试流程)、机械语言协议(状态播报/情绪抑制/判定短语)、安全与权限协议、错误分级处理

* fix: SOUL.md 去掉身份标签只留人设描述;registry 残留 default 引用清理

* fix: SOUL 文件去除元描述引言——组指挥体与默认人格只留角色本身

* ui: 组成员表紧凑列宽——子个体列固定 220 消除空白,职责 260,工具/状态列收窄

* fix: 组成员提示词校验文案修正——不再误用模型名提示

* fix: SOUL 只留性格层(工作流归 PROMPT);成员表 tableLayout=fixed + 子个体列 220 真正生效

* refactor: 编成目录 agents/ → entities/——entities/agents(单体,常见 AI 软件同款) + entities/groups(智能体组);修复 skills 未入镜像

* copy: 默认智能体描述精简——默认智能体,以「本机」自称

* ui: 组成员表工具列加宽到 300,职责列让位——标签不再逐行堆叠

* rename: 子个体「媒体体」→「影音体」——避免「媒体+体」双体拗口

* feat: 编成模板机制——entities/templates/(unit×4 + group×1),用户与 agent 均可基于模板创建组和子个体(GET /api/templates + agent_manage templates/create + 前端模板选择)

* fix: 模板创建按 template.json 的 id 解析目录(此前误用 id 拼路径导致创建失败)

* feat: 版本更新功能——版本号定为 0.1.0,/api/version(+check) 对比上游 dev,设置页「版本更新」面板,Docker 构建注入 GIT_HASH

* fix: compose build.args 重复键合并——GIT_HASH 与 EXM_LANG 同段

* feat: 一键更新——POST /api/version/apply 经 docker.sock 执行 git pull→build→up -d,状态轮询端点 + 设置页一键更新按钮与恢复检测

* change: 更新检查源 dev→main——发版口径(dev 开发线,merge 到 main 时推送新版本);main 尚不存在时优雅降级提示

* fix: 一键更新重启步骤借道一次性辅助容器——compose 客户端不再随被重启的旧容器一起被杀(实测踩坑:recreate 半途而废)

* fix: 工具链下载 ADD url → RUN curl --retry——消除构建期持续联网校验,网络抖动不再炸构建

* fix: 一键更新工具链改挂载宿主 docker cli/compose 插件——移除构建期下载,内层构建零网络依赖(根治缓存不命中+网络抖动)

* docs: 替换“智械体集群”为“智能集群”并更新示例文案

* fix: 更新脚本自造 DOCKER_CONFIG/config.json——docker pull 无配置文件时报 no configuration file provided

* perf: GIT_HASH 移至 runtime 阶段注入——commit 变化不再作废 Rust 编译缓存(外层构建 10min→<1min,一键更新内层构建不再触发 rustup 全量同步)

* copy: 更新检查描述去掉工作流括号说明

* fix: 辅助容器挂载仓库宿主真实路径(从容器 mount 反解)——/host 只存在于网关容器内,宿主侧不存在导致 compose 找不到编排文件

* ci: 工作流触发策略收敛——CI 仅 PR 触发,发版仅 dev→main 合入触发,dev 日常提交零消耗

* docs: 新增开发规范——分支模型/提交纪律/发版仪式/工作流触发矩阵固化成文;CONTRIBUTING 对齐实际提交类型并挂规范入口

* fix: 更新检查分支感知——本地在什么分支就对比该分支的上游(main 用户看 main,dev 开发者看 dev);「上游最新」标签随实际上游渲染

* ui: 「上游最新」行渲染实际上游 ref——不再写死分支名(dev/main 通吃)

* fix: add_message_full 过程数据按 id 原位替换回 jsonl——此前 put 写独立文档,思维链/工具轨迹刷新即失

* feat: 单体直接工具循环——chat_execute(系统提示+历史+工具面自主决策)+ run_round 单体分支 + execute_named 过程轨迹补录

* test: 单体直接循环冒烟(工具回灌/轨迹留痕/无任务图)+ 上下文压缩用例改组模式承载;修复 dev 存量测试编译债(link 字段/ExmConfig::default)

* chore: 版本推进 0.1.1——单体直接工具循环 + 编成模板 + 版本更新/一键更新

* ci: CI/发版流水线补装 libxdo——computer-use 栈(enigo/xcap)链接期缺库,cargo test 未跑先挂

* docs: 单体直接工具循环 4.5 部署实测勾选——真实模型两轮验证通过

* test: git_panel 干净断言过滤注册表播种目录——entities/skills 是测试环境噪声,不属于提交流程

* fix: 更新检查 rev-parse 加 --verify——上游 ref 不存在时保持空值走降级,而非把字面量当 sha 返回

* release: v0.1.1 (#12)

* ci: 工作流触发策略收敛——CI 仅 PR 触发,发版仅 dev→main 合入触发,dev 日常提交零消耗

* docs: 新增开发规范——分支模型/提交纪律/发版仪式/工作流触发矩阵固化成文;CONTRIBUTING 对齐实际提交类型并挂规范入口

* fix: 更新检查分支感知——本地在什么分支就对比该分支的上游(main 用户看 main,dev 开发者看 dev);「上游最新」标签随实际上游渲染

* ui: 「上游最新」行渲染实际上游 ref——不再写死分支名(dev/main 通吃)

* fix: add_message_full 过程数据按 id 原位替换回 jsonl——此前 put 写独立文档,思维链/工具轨迹刷新即失

* feat: 单体直接工具循环——chat_execute(系统提示+历史+工具面自主决策)+ run_round 单体分支 + execute_named 过程轨迹补录

* test: 单体直接循环冒烟(工具回灌/轨迹留痕/无任务图)+ 上下文压缩用例改组模式承载;修复 dev 存量测试编译债(link 字段/ExmConfig::default)

* chore: 版本推进 0.1.1——单体直接工具循环 + 编成模板 + 版本更新/一键更新

* ci: CI/发版流水线补装 libxdo——computer-use 栈(enigo/xcap)链接期缺库,cargo test 未跑先挂

* docs: 单体直接工具循环 4.5 部署实测勾选——真实模型两轮验证通过

* test: git_panel 干净断言过滤注册表播种目录——entities/skills 是测试环境噪声,不属于提交流程

* fix: 更新检查 rev-parse 加 --verify——上游 ref 不存在时保持空值走降级,而非把字面量当 sha 返回

---------

Co-authored-by: KurohaneKaoruko <kurohanekaoruko@gmail.com>

* Fix/cross platform release (#16)

* build: 跨平台编译修复——computer.rs 平台差异(enigo Send/Key::Insert 平台门控)+ 一键更新 Unix 门控;release 流水线支持分支手动触发(编译预验,发布仍钉死 main)

* build: 重生成 tauri icon.ico——原文件是改扩展名的 PNG,Windows 资源编译器与 macOS 图标解码均拒绝

---------

Co-authored-by: BlackStar-Agent <kurohoshi@126.com>

* build: 桌面端重写为 egui 纯原生应用(无 webview)——chat-first 主窗口 + 原生设置页 + 隐藏终端侧车 + Inno Setup/tar.gz/dmg 安装链 (#18)

* feat: B1 SQLite 存储底座——store.sqlite 主库(会话/消息/任务图/回流/账本/快照/审计)+ 自动迁移旧 FSDB 数据

- store_sqlite.rs: SQLite 实现(62 方法全量移植,WAL 单写者)
- 自动迁移: Store::open 检测旧 FSDB 数据一次性转换
- rusqlite bundled(零外部依赖,构建环境自带 C 编译器即可)
- 已知边界: 证据/事件/检查点/outbox 等低频集合本批次仍走 FsDb

* feat: B1 SQLite 存储底座——store.sqlite 主库 + 自动迁移 + rusqlite 依赖(bundled)

* build: 打包脚本路径改仓库根口径——移除 ../ 前缀(CI 上指向仓库外)

* ci: 发版 tag 自动追加后缀——同版本重发时自动递增(v0.1.1 → v0.1.1.1 → v0.1.1.2),不再跳过

---------

Co-authored-by: KurohaneKaoruko <kurohanekaoruko@gmail.com>
Co-authored-by: BlackStar-Agent <blackstar-agent@users.noreply.github.com>
Co-authored-by: Kaoruko <101451942+KurohaneKaoruko@users.noreply.github.com>
* feat: EXMACHINA 智械体集群 —— Rust 多智能体协作系统(集群调度 / 契约回流 / 三账 / 记忆 / 多模型 / WebUI)

core: orchestrator DAG planning + concurrent dispatch, SyncReport contract enforcement with auto-rewrite, conflict arbitration, three-ledger (task/evidence/risk), recallable memory with decay, group/agent scoping and reliability stats

models: four protocols (openai/anthropic/gemini/azure) with sticky multi-key pools and per-protocol connectivity probe; per-agent/group default model resolution (agent -> group -> global) via ModelPool

platform: skills, cron/heartbeat automation, exec approval gate + auth key; Telegram/webhook/qq/wechat bridge channels; single-process gateway serving REST+WS+WebUI

delivery: exm/exmachina CLI, native-tls via system store, release profile LTO+strip (single binary ~5MB), GitHub Actions release pipeline for compile-free low-spec deployment; WebUI on React 19.3 + antd 6 (14 panels, 5 themes)

docs: four-doc set (install/usage/design/protocol); no provenance metadata in repo

* feat: P0 batch 1 — native function calling, model failover chain, context compaction, followup/collect

function calling: protocol-level tools for openai/anthropic/gemini/azure (definitions, streaming fragment assembly, per-protocol result threading); text protocol kept as mock/compatible fallback; whitelist/approval/audit preserved

failover: profile-level fallback chains (cycle-guarded), 45s cooldown skipping, switch only before any token emitted, global profile tail, model.failover event; provider form gains fallback selector

compaction: multi-turn context for planning — rolling summary (LLM-compressed) + recent-12 window injected into plan prompt; session.rollingSummary/summaryUpto persisted

followup/collect: Core::chat serializes runs per session (all channels migrated); queued inputs within a window merge into one round goal

fix latent ordering assumption: list_messages is chronological (fsdb read_lines), oldest->newest

tests: 17/17 green incl. failover chain/cooldown, compaction+collect semantics

* feat: P1 batch 2 — MCP client (stdio + streamable http) with tool gateway integration

mcp.rs: JSON-RPC 2.0 client, lazy initialize handshake, tools/list snapshot cache (sync) + connection pool (async, Send-safe), per-server allowedAgents visibility, tools/call with text content normalization

integration: config mcpServers[] persisted + hot rebuild on apply_config; ToolGateway.execute_mcp with unified audit; runtime tool specs extended per-agent with mcp:server:tool; native function-calling path routes mcp names; gateway serves GET /api/mcp + POST /api/mcp/refresh with background refresh on startup

tests: 18/18 green incl. in-test axum MCP server covering configure/refresh/snapshot/call/allowlist

* feat: P1 batch 3 — hybrid memory retrieval (semantic embeddings + lexical scoring)

provider: embed() on trait (openai /embeddings + azure deployments), deterministic pseudo-embeddings for mock channel; profile embedModel config + WebUI field

memory: entry vectors with write-path background backfill, query embedding boost in scoring, semantic fallback scan when lexical candidates empty; cosine similarity with layer/group scoping preserved

orchestrator: embed_query via active profile embed model injected into planning + dispatch recall paths

tests: 19/19 green (semantic fallback/boost smoke); serial guard for Core-based tests sharing repo workspace

* feat: P1 batch 4 — web_fetch tool and multimodal image input

web_fetch: ToolName variant with zero-dependency HTML body extraction (script/style/tag stripping, whitespace compaction), 20s timeout, 2MB cap, allowlist + audit semantics; dispatch made async

vision: ChatMessage.images (data URLs) mapped per protocol (openai image_url parts / anthropic base64 image blocks / gemini inline_data); image_stash module stages channel attachments for next planning turn; gateway chat body accepts images; WebUI attach button with canvas compression (<=1280px JPEG 82%, up to 4)

tests: 20/20 green incl. in-test axum page fetch (script/style stripped) and stash take-once semantics

* feat: P2 batch 5 — distributed execution nodes (old-device worker cluster)

protocol: /worker WebSocket endpoint with JSON frames (hello/dispatch/tokens/report/error), authKey auth; WorkerHub pool with per-worker outbound channels, pending dispatch table, token streaming into event bus, timeout-bounded execution

orchestrator: remote-first routing (sync accepts check + remote execute with local fallback, remote.fallback event); Core::set_remote hot-rebuilds orchestrator; execute_unit entry for worker side

worker: WorkerSession client (tokio-tungstenite plain WS) runs full local Core — its own model profiles/tool gateway; exm worker --url --token --id CLI subcommand (hostname default)

tests: 21/21 green incl. two-Core full-wire smoke (worker session via real WS executes dispatched nodes, DAG terminal)

* feat: P2 batch 6 — interrupted-session resume on gateway boot

resume: scan sessions with Executing graphs containing non-terminal nodes; replay done nodes (reports backfilled from sync_reports_by_node, report ids restored), reset interrupted to Ready, re-run scheduler, converge with resumed flag

plumbing: store.sync_report_of_node typed lookup; TaskGraphModel.set_report_id; ExecCtx/run_node/converge made public for resume path; gateway serve() triggers resume at boot

tests: 22/22 green incl. interrupted-graph reconstruction smoke (all nodes terminal, >=3 done after resume)

* feat: P2 batch 7 — terminal hardening (timeout kill) and session token budget

terminal: async execution via tokio (no runtime-thread blocking), kill_on_drop timeouts — 120s dispatch / 300s approval execution; hung commands can no longer stall nodes

budget: maxSessionTokens config (estimated chars/4, 0 = unlimited); Core::chat gate rejects over-budget sessions with clear guidance; schema entry for settings page

tests: isolated per-test agents tree copy (fixes cross-test repo workspace pollution — leftover active_group from interrupted runs broke roster loading); 23/23 green incl. hung-command kill and budget-gate smokes

* feat: P2 batch 8 — voice input pipeline and windows process-tree kill

voice: transcribe on LlmProvider trait (openai/azure /audio/transcriptions, multipart), Core::transcribe via active profile (whisper-1), POST /api/voice/transcribe endpoint; WebUI mic button (MediaRecorder webm -> gateway -> text into input, recording state)

hardening: timeout kill now taskkills the full process tree on Windows (cmd grandchildren no longer leak); pid captured before wait_with_output move

tests: 24/24 green incl. transcribe channel contract (mock explicitly unsupported)

* feat: P2 batch 9 — text-to-speech read-aloud and session usage observability

tts: speak() on LlmProvider trait (openai/azure /audio/speech, mp3 bytes), Core::speak via active profile (tts-1); POST /api/voice/speak returns audio/mpeg; WebUI per-message read-aloud button with playback state

usage: GET /api/sessions/:id/tokens (estimate + budget); chat rail shows live token usage, refreshed per round

tests: 24/24 green (speak channel contract alongside transcribe)

* feat: P1 batch 10 — telegram voice input and channel chat allowlist

voice: telegram voice messages -> getFile download (ogg) -> active-profile transcription -> normal text flow; failed transcription degrades gracefully

security: Channel.allowedChats allowlist (empty = unrestricted); non-listed chats ignored with log; exposed in create/update endpoints and WebUI channel form (comma-separated)

tests: 24/24 green regression

* feat: settings page categorized redesign + empty model defaults without keys

settings: sectioned cards (runtime/memory/security/automation) with icon+description headers, label-left control-right rows, proper widgets (switch for booleans, textarea for prompts/allowlists), per-page save button; LLM section stays on provider page

defaults: model names default to empty instead of gpt-4o placeholders — without API keys placeholder models are meaningless; users set real models when configuring a provider; mock channel ignores model names

gateway: maxSessionTokens exposed in GET/PUT /api/config; settings page shows live budget

* feat(ui): settings page v3 — left category nav, single-panel view

one category visible at a time (runtime/memory/security/automation) instead of stacked cards; enum select for approval mode; per-section save; fixed-width right-aligned controls

* feat: P1 batch 11 — dual memory modes (deep db vs memory.md file-only) + full config exposure

deep-off mode: planning injects memory.md (<=8000 chars) instead of db recall; memory panel becomes markdown editor via GET/PUT /api/memory/md; settings labels clarified

config exposure: GET /api/config now returns memory/security/automation groups — settings page shows actual values instead of schema defaults (was the incomplete part)

* feat: memory.md size limit with autonomous AI compaction and archiving

config: memoryMdMaxChars (default 5000) in memory group + settings schema; PUT /api/memory/md auto-triggers background compaction when over limit

compaction: LLM simplification via orchestrator provider (compression contract), original text archived — deep-on writes digest entry into db (searchable), deep-off appends workspace memory_archive.md; nothing lost either way

ui: md editor shows char count vs limit, save reports background compaction; mock channel deterministic compression output; 25/25 tests green

* feat(ui): units page group selector, flat member list (primary first), no domain division

units page: group dropdown to view/manage any group members (no longer bound to background active group); nav renamed units; primary agent listed first; domain grouping/inputs removed from units/groups/singles create forms — single-domain labels added complexity without value

gateway: DELETE /api/groups/:gid/agents/:identifier for cross-group member management; api.ts removeGroupAgent + allowedChats passthrough on channel create/update

* fix(ui): remove leftover activation wording from management pages

group/channel management pages no longer surface session-scoped activation state; wording aligned to per-session target selection

* feat(ui): language switcher (zh/en) next to theme switcher + shell translations

sidebar language panel in same position/style as theme; localStorage persisted; nav/branding/status/settings fully bilingual via shared i18n infra

cleanup: remove redundant tip line in GroupsView (group switching is already noted in chat rail)

* fix(ui): settings i18n — replace remaining title/desc refs with t() keys

* docs+core: 文档与事实对齐;移除「无密钥自动降级模拟通道」;修复终端超时用例挂起

文档(与代码事实逐条核对)
- docs/协议与契约.md:SyncReport 契约按代码修正(statements / risks /
  blockers{reason,unblockCondition} / conflicts);扩展点路径改 <identifier>.json
- docs/使用指南.md:group/agent create 的名称是位置参数(原文误写 --name);
  补 worker、group export/import、经验优化三节
- docs/架构与设计.md:重复小节去重;测试策略改为「测试替身仅测试使用」
- docs/安装指南.md:FAQ 由「无密钥自动降级模拟通道」改为「不会用模拟输出充数,需先配置模型」

代码(产品行为)
- 新增 UnconfiguredProvider:未配置端点/密钥的通道调用即报错并给出配置指引
- Provider 规则改为显式配置优先:有 base_url+key → 真实推理;未配置 → 替身模式给 Mock、
  产品模式给 Unconfigured;use_mock 仅由 EXM_LLM_MOCK=1(或测试)开启
- 移除全部「自动置 mock」点(config/gateway/cli/install);配置热更新不改变替身状态
- install / doctor / model list / chat 头 / 网关 banner 文案统一为「未配置——请在模型提供商页配置」

测试
- 修复 tools.rs 终端超时路径:stdio 读取独立任务 + 超时 abort + taskkill /T /F +
  child.wait() 有界回收(原实现挂死,曾导致全量测试 20+ 分钟不结束)
- 清理编译告警:删死结构体、noop clone、未用 mut/导入、测试函数名 ASCII 化

验证:cargo test --workspace 8 单测 + 17 冒烟全绿;gateway e2e 92/92 全绿

* ui: 排版层级重构 —— 新增表单只留主流程,可选与运维细节收进「高级设置」

用户反馈:新增提供商把厂商预设全铺成按钮墙、还要求填指挥体/子个体模型、嵌入模型、失败回退——
这些不该出现在「接入一个厂商」的主流程里。

设计原则(本轮确立):一页只回答一件事;可选与运维细节一律折叠,默认收起。

- 「提供商」页重写(ModelsView.tsx)
  - 厂商预设 9 按钮墙 → 下拉(带端点形态提示 + 自定义/自建端点)
  - 主表单只剩:提供商类型 → Base URL → API Key(Key 池为可选多行)
  - 高级设置(折叠):显示名称 / 档案 ID / API 协议 / 默认模型(预设自动填)/
    指挥体与子个体模型覆盖 / 嵌入模型 / 失败回退
  - 卡片信息层级重排:端点(+协议短标签) / 模型 / 密钥状态 / 回退链 / 嵌入模型
  - 措辞修正:不再出现「Mock / 模拟通道」,未配密钥显示「未配置(对话前请补填)」
- 新增统一页头组件 components/PageHeader.tsx(标题 + 一句话说明 + 右侧操作区),
  落地于:提供商 / 子个体 / 智能体组 / 独立智能体 / 技能 / 自动化 / 审批 / 通道 / 记忆 / 活动;
  原先挤在按钮行里的长提示统一挪入说明段(层级:标题 → 说明 → 操作)
- 通道表单 8 项平铺 → 核心 = 平台/通道 ID/Token/绑定组,高级 = 备注/白名单/出站回调
- 自动化表单 6 项平铺 → 触发方式改 Segmented(周期 Cron | 一次性时间)互斥切换,会话标题进高级
- styles.css 新增 .page-head/.page-title/.page-desc/.page-actions/.form-advanced/.model-kv/.form-grid-2
- 命名对齐:与工作区正在进行的「模型提供商 → 提供商」全局改名保持一致

验证:npm run build:webui(tsc + vite)通过;产物含新样式与新文案,
「厂商预设 / 模拟通道 / Mock 模拟」字样已从产物消失;网关实测启动正常(health 200 / 托管 dist / 40 个体)

* ui: 控制台视觉重构 —— 工程图刻度语汇、页面编号 01–14、科研感登录门与任务图

三类线条语汇(全部由 CSS 变量驱动,随 5 套强调色联动):
- hud 角标:面板四角短刻线;scale 刻度尺:等差刻度 + mask 淡出;grid 剖面:低透明度栅格

全局
- 新增令牌 --tick-step / --tick-color / --tick-color-hi / --grid-size / --accent-04·08·30
- body 双向 40px 栅格底纹;全局 tabular-nums 保证读数对齐

侧栏与页头
- 侧栏右缘刻度尺(每 5 格长刻线);菜单项加序号列,序号与图标间加短刻线,选中项左侧荧光轨
- 页面编号 01–14:单一事实源 NAV_ITEMS,侧栏与页头同源
- PageHeader 重构:desc 移出 .page-head-row 独占整行,修复说明文字被操作按钮压住

组件
- 表格表头列间竖刻线分隔;补齐此前完全缺失的 .plain-table / .model-card / .skill-card / .pane-loading
- LedgerView 补页头(原无页头且空态早退);SettingsView 统一 pane-wrap;ChatView 加控制台读数条

仪器感页面
- 登录门:72 条刻度环 + 十字准星 + 双层同心圆,去圆角,标题下加测量基线
- 任务图:坐标刻度、节点状态轨 + 量度条、正交折线连线、NODES/EDGES/DEPTH 读数

文档
- docs/使用指南.md WebUI 章节表格按 01–14 重排

* 提供商页回到「只回答一件事」+ 侧栏/间距回正 + 编排词清理

提供商设置(用户反馈:不该加的东西不要往这加):
- API Key 与 Key 池合并为一个可增删列表,不再分两块填
- 指挥体模型 / 子个体模型从全栈删除(此前只是折进「高级设置」,等于没删):
  LlmProfile/LlmConfig 的 orch_model/unit_model/embed_model 合并为单一 model;
  ModelPool 的 insert/resolve/entry 去掉 unit 参数;expand_chain 同上;
  gateway/CLI/install 向导同步;旧配置由 LlmProfileFile/LlmConfigFile 兼容读取,保存后不再回写旧键
- 嵌入模型移到「记忆」页「语义检索」卡(memory.semanticModel),core 新增 semantic_recall()
- 提供商类型名后不再挂多余描述

WebUI:
- 侧栏去掉序号列、恢复原有顺序与文案(撤销上一轮擅自的改名「独立智能体」与换位)
- .pane-wrap 去掉在已有内边距容器里的二次居中(智能体组/子个体左空隙过大的根因)
- list-rail 300→260px、skill-grid 最小 380→320px

文案:
- 清除「公司架构/团队架构」类比(9 处),示例组名改「研发组」
- 清除自造的「独立智能体」,统一为「智能体」

修复:
- e2e.rs 未带密钥 401 用例中重复的请求行(第二次请求覆盖第一次,属脚本改写的残留)

验证:cargo check --all-targets 0 警告;cargo test 8+17 全绿;e2e 92/92;
tsc --noEmit 干净;vite build 通过;产物禁用语扫描全 0。

* webui: 修复「记忆」页白屏崩溃 + 提供商卡片信息层级 + 设计令牌归一

修复(实测发现,非推断):
- 记忆页整页白屏:MemoryView 用 stats?.memory.total,外层可选链挡不住内层缺失
  (stats 有值而 memory 为 undefined 时照样抛错,整棵 React 树塌掉)。
  改为逐层 stats?.memory?.total ?? 0;同类 config?.memory?.enabled / semanticModel 一并加固。
- 侧栏底栏的 MOCK/LINK 徽标删除:测试替身不是产品状态,违反项目铁律。
  改为「通道就绪 / 未接入」,由 config.llm.apiKey 是否非空驱动。

提供商卡片:
- 改为四行事实:端点 / 模型 / 密钥 / 状态;「全局默认」从标题行移入事实区,
  标题只留身份,不再与操作按钮争位置
- 「已配置(N 把)」原用 warning 琥珀色(读起来像出故障),改为绿色中性态;
  「未配置」才用 warning
- 卡片头统一高度,避免「有无次要按钮」导致事实行跨卡错位
- 页头说明压成一句

版式与令牌:
- 颜色归一:手抄近似值 #8fa6b8 / #9fb6c6 → var(--text),
  rgba(29,42,54,0.6~0.9) → var(--line),共 8 处
- antd token 同步:colorTextSecondary #8fa6b8 → #6d8296(= --muted),
  colorTextTertiary → #4a5c6c(= --muted-dim)
- 智能体组元信息行的全角空格分隔改为真实元素 + flex gap

验证:cargo check --all-targets 0 警告 0 错误;cargo test 8+17 全过;e2e 92/92;
tsc --noEmit 干净;vite build 通过;提供商/记忆/智能体组/侧栏多页截图实拍复核。

* docs: 统一 orchestrator 注释措辞为「单体智能体」

「独立智能体」是此前自造的叫法,全库仅剩这两处(均为注释)。代码库既有术语
是「单体智能体 / 单体模式」(registry.rs、singles.rs、SINGLE_CONTRACT 正文、
smoke.rs 一致使用),本次对齐,全库该词归零。

验证:cargo check --all-targets 无代码级告警;cargo test 8+17 全过;e2e 92/92。

* feat(ui): markdown rendering for chat messages (GFM, dark-theme code blocks)

* feat(ui): session search, rename, and chat rail cleanup

* refactor(ui): groups page — clean flat layout, settings modal, remove inline editing clutter

* feat(ui): groups page settings modal (workspace + default model) with gear button

* fix(ui): chat page declutter — remove duplicate speak btn, simplify console bar, hover session ops, shorter hints

* feat(ui): collapsible chat sidebar with edge toggle button

* fix(ui): restore console bar readouts (MODE/STATE/TOKENS) removed in earlier cleanup

* fix(ui): chat-shell height and CSS cleanup

* fix(ui): chat-shell row-reverse in main rule not trailing override

* fix(ui): remove redundant read-aloud button from message bubbles

* feat(ui): task graph page — session label + selector, clear which session the DAG belongs to

* fix(ui): graph page — stats readout left, session selector right

* feat: one-click quickstart scripts (sh + bat)

* docs: README quickstart — one-click scripts first, manual build second

* feat: full auto-install scripts (install.sh + install.bat) — clone, install deps, build, run

* feat: quickstart downloads prebuilt releases (no compile needed); CI workflow builds and publishes on tag

* chore: move install/quickstart scripts to scripts/ folder; update README URLs

* ci: add test-only workflow on push; release.yml waits for manual tag (no auto-publish until fully tested)

* fix(docs): README ASCII art — pure ASCII # style, equal-width lines render correctly on GitHub

* feat(docs): SVG logo with DAG node design, terminal aesthetic, animated status LED

* docs: SVG logo — 58px font, compact DAG, text glow, fills canvas

* docs: SVG logo — hard edges, diamond DAG nodes, right-angle wire routing, no ONLINE

* docs: SVG logo — diamond nodes drawn after lines (no overlap), diagonal wire routing restored

* docs: redesigned product logo — hex lattice + center diamond, large 68px wordmark; separate 256px app icon

* docs: premium logo — layered hex, glowing core with inner diamond, HUD tick marks, corner brackets, gradient wordmark

* docs: logo — restore EX·MACHINA dot separator, align connector lines to diamond vertices

* docs: full-width banner logo (icon left, wordmark + tagline right); README adds H1 heading; intro text embedded in SVG

* docs: logo — precise flat-top hexagon geometry, centered text block, proper icon-text spacing; README H1 updated

* docs: restore original subtitle and README H1

* docs: README H1 = ExMachina — 一个群体协作的智能集群

* docs: logo subtitle = ExMachina — 一个群体协作的智能集群

* docs: logo — remove icon, pure centered text banner

* docs: logo — 110px title nearly fills width, wider underline

* docs: logo — 100px title with top spacing, 18px subtitle, 14px body text

* docs: add LICENSE (MIT), SECURITY.md, CONTRIBUTING.md

* docs: SECURITY.md and CONTRIBUTING.md now bilingual (zh/en)

* docs: split README into zh (README.md) + en (README_EN.md) with language switcher

* docs: logo subtitle restored to 智械体集群 · MULTI-AGENT CLUSTER

* docs: logo subtitle — 智械体集群 // AGENT CLUSTER (original)

* docs: language switcher moved below badges, centered

* docs: logo — subtitle 18→22px semibold, body 14→18px, brighter colors, more height

* docs: logo — 画布 1200x300,字号与线宽按 Retina 重做;背景改纯色、去副标题

README 头部 SVG 的「字小、线细、锯齿」三个根因与修法:

1. 字小 —— 画布 960x280 经 width=100% 引用后在 GitHub 阅读栏(1012px)
   只剩 ~295px 高。改为 1200x300,主标题 100→88px(配 letter-spacing 撑满)、
   底部文案 18→23px。删掉副标题后标题整体下移到视觉居中。
2. 线细 —— 原字体栈以 'SF Mono','Cascadia Code' 打头,Windows 会落到
   Courier New(细衬线等宽)。字体栈改为 ui-monospace 打头;
   主标题改 fill + 同色 stroke + paint-order 加粗字面。
3. 锯齿 —— 0.4px 级描边在 Retina 上被采样成灰虚线。全部细线提到 >=1.6px
   且落在整数设备像素;移除 0.4px 网格线。

排版取舍:
- 背景改为纯色 #0b1118,不使用渐变。
- 删除副标题「智械体集群 // AGENT CLUSTER」。
- 不加角标等装饰性元素,只保留刻度尺 / HUD 角标 / 边框 / 分隔线。
- 底部文案含「零情绪」,属此前已否掉的自造氛围词,删除;
  压成四个短标签(契约回流 / 冲突裁决 / 证据分级 / 结论收束)。

exmachina-icon.svg 未改动。

* feat: 通道平台全面扩展 —— QQ 官方机器人 / NapCat 适配器 + 运行状态 + 密钥掩码

通道网关(后端):
- 新增 qqbot 适配器:开放平台 WS 长连接,token 缓存提前刷新,断线先 Resume 再
  Identify,被动回复携带 msg_id + 递增 msg_seq,sandbox 可选
- 新增 napcat 适配器:OneBot 11 正向 WS(NapCat / Lagrange 通用),读循环常开 +
  mpsc 专职写任务,数组段与 CQ 码双格式解析
- 通道配置平台目录化:Channel.config{} 扩展配置,新平台零结构体改动;
  create 校验 qqbot 需 appId/appSecret、napcat 需 url
- 通道运行状态:适配器连上/断开/出错覆盖上报,GET /api/channels/status 查询,
  删除/停用即清除
- 密钥全链路掩码回显(***已配置***):顶层 token/secret + 敏感 config 键;
  更新三态语义(掩码沿用 / 空清除 / 新值)
- 修复:PUT /channels/:id 的 body.id 无默认值,前端更新通道(不发 id)一直 422,
  通道编辑与启停开关自上线即不可用;补 #[serde(default)] + e2e 锁定

WebUI:
- 通道页重写为平台目录驱动(PLATFORMS):表单/凭证判定/回复形态由目录出,
  状态列轮询运行状态(已连接 / 连接异常 + 明细)
- 修复:ModelsView 本地掩码哨兵 ***MASK*** 与后端 ***已配置*** 漂移,编辑档案
  不改密钥会把掩码字面量存成 API Key;统一为 api.ts 共享 KEY_MASK
- i18n 架构化:i18n/ 注册表(TKey 编译期键检查,en 缺键回退 zh,新语言零成本),
  全部视图清扫,中英双份词条
- 布局修复:对话页与右侧会话栏间距(row-reverse 无 gap)

验证:
- cargo check --workspace 零警告;e2e 103/103(新增通道校验/掩码落盘/状态接口
  断言;e2e 环境自持,不再随本机 config 漂移)
- npm build 通过;通道页中英表格与编辑弹窗截图复核

* feat: 「提供商」→「模型设置」—— 模型清单 + 能力模型(组级覆盖)+ 视觉转述

模型设置页(原「提供商」页改名,nav.models):
- LlmProfile.models[]:每个提供商一份模型清单(模型名 + 视觉/语音能力开关);
  默认模型保存时自动并入清单;清单未标记 = 能力未知,输入直通(向后兼容)
- 能力模型槽位(capabilities 配置节 + GET/PUT /api/llm/capabilities):
  语音合成(TTS)/ 语音识别(语音转述)/ 视觉转述 / 嵌入;
  嵌入与记忆页 semanticModel 同一字段(两处入口等价);TTS/STT 由硬编码 tts-1/whisper-1
  改为按槽位解析,未配置回落原默认
- 视觉转述降级:生效模型明确 vision=false 且配置了转述模型时,逐图转文字描述注入规划;
  未配置则忽略图片并在输入中说明;能力未知保持直通
- UI:提供商卡新增模型清单行(默认 / 视觉 / 语音);页底「能力模型 · 全局默认」卡;
  编辑弹窗 Form.List 模型清单(开关 + 增删)

组级能力覆盖(能力槽位不再全局单值):
- GroupMeta.capabilities 持久化 + PUT /api/groups/:id/capabilities
  (空串 = 清除该项跟随全局;全空 = 整块收回)
- 槽位解析两级:组覆盖 → 全局槽位 → 出厂默认;TTS / STT / 视觉转述 / 嵌入四处统一
- 组设置弹窗新增「能力模型(组级覆盖)」四槽位,留空 = 跟随全局默认

修复:
- tr() 改用 useLang.getState() 同步读语言:原 hook 形式在组件渲染期被调用
  (构造 Select options)会把 hook 计入当前组件,两次渲染间钩子数漂移导致 React #310
  全树崩溃;同时消除 api.ts / models.ts 三处同类隐患

验证:cargo check 零警告;e2e 全过(模型清单与开关回显、能力槽位写入/回读、
组级覆盖写入/空串清除/落盘回读);npm build 通过;中英双页截图复核

* docs: README 头部改用同款 EXMACHINA 字符画(字母间 2 空格),快速开始前移至告警之后

* docs: 警告块前移至字符画之前(H1 下首元素)

* docs: 字符画首行补 1 空格对齐 88 列——修复逐行居中渲染下的右偏

* build(rust): toolchain by host + silence Linux-only unused pid

- rust-toolchain.toml / .cargo/config.toml: switch to stable channel so
  rustup auto-selects the host triple (Linux/macOS/Windows all build
  without edits); comment updated accordingly.

- crates/exm-core/src/tools.rs: mark the local \`pid\` binding with
  \`cfg_attr(not(target_os = \"windows\"), allow(unused_variables))\`.
  The PID is only consumed inside the Windows taskkill branch; on POSIX,
  tokio::Child::kill_on_drop already handles process teardown.

Verified on Debian 13 / x86_64-unknown-linux-gnu: `cargo check --workspace`
and `cargo build --workspace --release` both report zero warnings; the
`exm` / `exmachina` / `exm-gateway` binaries are produced and a
`cargo run -p exm-gateway --release` smoke test answers
`/api/health` with agents=40, ok=true.

* feat(gateway): bind on 0.0.0.0 by default; add --host flag

VPS / 容器 / 局域网部署场景下,loopback 默认值导致 '能跑起来但远程
访问不到'。改为:

- exm-gateway 默认监听 0.0.0.0,公网/局域网可访问(向后兼容:
  EXM_HOST=127.0.0.1 或 --host 127.0.0.1 仍可收紧)。
- `exm serve` 新增 --host 选项(短 -H),显式传入覆盖默认 / 环境变量。
- 启动日志链接打印改为绑定到的真实地址(不写死 127.0.0.1)。

API 变化:`exm_gateway::serve(core, port)` → `serve(core, port, host: Option<&str>)`,
库调用方需更新;唯一调用方(exm-cli 与 exm-gateway 独立入口)已同步。

* fix: 批量修复 WebUI/网关缺陷 17 项(API Key 保存与池掩码令牌化、鉴权设置入口、个体/智能体编辑、设置页契约、WS 重连竞态、间距统一等)+ 主智能体更名指挥体 + 单体去职责化;并入在途 WIP(browser 闸门/自定义工具/discord/matrix/slack 通道)

* fix: API Key 表单绑定真根因(Form.List 行绑定致输入被过滤)+ 智能体卡片 ⋮ 菜单(切换模型/编辑描述/编辑 SOUL.MD)+ 单体人设读写与 plan/converge 双注入 + 默认组/指挥体英文标注映射

* feat: 安装脚本重写(4 文件)——预检/重试/校验和/升级保数据/--port/--help/品牌化输出;修 macOS arm64 硬编码与构建日志吞错;bat 改 PS5.1 引导壳全 ASCII 免疫代码页 bug

* chore: 移除误入提交的测试残留文件 upgrading

* docs: 移除 README 低性能设备预编译包引导段落

* Update README with project inspiration details

Added a note about the project's inspiration from Ex-Machina in No Game No Life.

* Fix formatting in README.md for project inspiration

* feat: 编码体验全量落地 + 编成组目录制定稿 + Computer Use + WebUI 编码工作台/PWA + 桌面端 Tauri 壳

思维链与过程透明(对标编码型 Agent):
- provider 双轨流式:解析 reasoning_content/thinking_delta/Gemini thought,新增
  StreamDelta::{Text,Thinking};新 WS 事件 orchestrator.thinking / unit.thinking
- tool.call / tool.result 事件(callId/args/ok/耗时/摘要/images),工具执行全程可见
- 审批等待回灌:拦截后原地等待 approvalWaitSecs,批准后代执行、输出直灌模型继续干活
- WebUI 聊天页:思维流折叠、工具执行卡(edit diff/终端输出/截图预览)、内联审批卡

Computer Use:
- computer 工具(enigo 键鼠 + xcap 截屏):screenshot/click/move/scroll/type/key
- 默认关闭显式开启;输入动作过审批闸门 + 动作节流;截图经 ToolResult.images
  回灌视觉模型(vision 能力检测)并可在工具卡内预览

WebUI:
- 新增编码工作台 [CODE]:会话 | 工具优先对话流 | 工作区文件树 + 变更清单 + 代码预览
- 网关配套 /api/asset(截图预览)与 /api/fs/list|file(文件树/预览,沙箱只读)
- PWA(manifest + Service Worker + 图标)与移动端抽屉导航;与客户端同端口交付

编成组目录制定稿(多轮评审定稿):
- 组 = groups/<gid>/:group.json + SOUL.md(主智能体人格,仅用户面持有)+
  MEMORY.md(组浅层记忆快照,6000 字截断)+ agents/*.json + prompts/*.md + adaptations/
- 单体 = singles/<id>/:agent.json + PROMPT.md + SOUL.md + MEMORY.md
- 子个体无人格层、无独立文件夹(定义+提示词合并存储于组内);深/浅记忆分层语义定稿
- 提示词分层:主智能体偏助手(对话优先/L0 直答)、子个体各司其职(编码位增补作业纪律)、
  单体全能;registry 全链适配 + gen-agents.mjs/doctor/install/e2e 同步

桌面端:
- desktop/(Tauri v2):捆绑 exm-gateway sidecar 本机模式 + --remote/--key 远程直连,
  退出杀进程树;MSVC 为官方构建目标(README 内说明)

测试:test_config 密封化(强制 Mock + 审批等待 0);新增审批等待回灌三场景用例;
cargo test --workspace 8 单测 + 21 冒烟全绿;npm run build:webui 通过;网关冒烟全过

* chore: 接入 OpenSpec 规范驱动开发——新增 openspec/ 目录骨架与配置,.gitignore 放行 .gitkeep

* feat: OpenSpec 变更 capability-completion 落地(1/3)——配置 v2 六段新配置与迁移、存储三集合骨架、patch 补丁工具(统一 diff 解析/整体拒绝/行尾容差)+ coding/ops 白名单

* feat: capability-completion(2/3)——工作区变更接口(git 口径/检查点回退)、文件保存接口(沙箱+检查点+审计)、simple_unified_diff 生成器;测试 5+23 全绿

* feat: capability-completion(3/3 P0)——git 面板(概览/暂存/提交/切换 + 破坏性审批单)、CodingView 三标签改造、webui i18n;测试 3/5 全绿

* test: P0 闸门验证——修复上游脆弱测试(审批等待用例未显式声明 risky 闸门模式);workspace 52 测试全绿

* feat: capability-completion 组3 通道身份与门控——/pair 配对码(短码/TTL/单次)、入站统一闸门(群聊唤醒门控+身份管控前置裁决)、六适配器提及归一化(tg getMe 缓存/discord mentions/slack app_mention/napcat CQ:at/qqbot @驱动/matrix m.mentions)、审批单来源升级标(origin_user/origin_role)、IdentityPanel 控制台 UI;闸门单测 5/5

* feat: capability-completion 组4 用量治理——滑动窗口限流(通道主体/API 维度)、周期配额(请求数 @admit + token @run,按会话台账)、组内派发豁免、/api/limits/stats + SettingsView 用量卡片;P0 闸门关闭(workspace 全绿 68 测、validate 通过)

* feat: capability-completion 组6(1/3)——出站能力矩阵与降级决策、typing 指示(telegram/discord)、长回复分段推送(段落优先/代码块完整/超长硬切续接);回复分段/降级单测 5 个

* docs: design.md 增补 D12——媒体产物透出(outbox/artifacts)与出站投递实施口径(组 6.2-6.4)

* feat: capability-completion 组6(2/3)——媒体产物透出(outbox/截图与投递目录登记/run.finished artifacts)、spawn_reply 双闭包投递(直发+降级并注)、telegram/discord/slack 媒体直发(multipart/三步上传)

* feat: capability-completion 组6(3/3)——napcat 媒体直发(base64:// 段,远程安全)、matrix 媒体上传(media v3→content_uri)、入站媒体解析(telegram photo/document、discord attachments、napcat 段:下载落 inbox→图片暂存/文件注记,失败回退)+ 注入单测 2

* feat: capability-completion 组6 收尾——slack url_private 下载 / qqbot attachments / matrix mxc 媒体下载与失败占位回退;六通道入站媒体全通 + 注入/回退单测

* feat: capability-completion 组7-9——事件触发器(文件监听去抖合并/webhook HMAC+审计/cron 推送订阅/心跳 per-agent)、记忆三工具(组隔离/source=agent/主智能体默认授权)、会话历史管控(轮次快照/undo 检查点联动/编辑重发/fork 分支+REST+WebUI 入口)

* feat: capability-completion 组10 MCP 服务端——ACL 可见性矩阵(组/会话/工具清单)、stdio exm mcp serve(JSON-RPC 会话亲和)、网关 /mcp HTTP 挂载(鉴权+限流)、外部调用安全口径一致(审批/审计 mcp 来源标注);协议端到端/亲和/ACL/审批口径测试

* feat: capability-completion 组11-12——桌面集成(系统托盘/关窗驻留可配/原生通知三类含类别开关与事件映射单测/全局快捷键可改绑冲突提示)、doctor 新配置段诊断、文档同步(README 能力表/使用指南新章节/协议契约 REST+WS 事件)、原创性验收禁用词零命中

* chore: capability-completion 12.4 最终闸门——Dockerfile 补齐容器构建/运行时依赖(xcap dbus vendored 静态编译、enigo libxdo 构建包与 X11 运行时栈),compose 冒烟通过(health ok + 40 个体装载)

* chore: compose 支持 EXM_AUTH_KEY 注入(后台访问密钥,.env 注入不入库)

* fix: 用户测试反馈 12 项——WS 鉴权豁免(浏览器无法带头)+服务端 Ping 保活+客户端指数退避看门狗、组页卡片化+子个体并入组详情、编码页撤并为对话页编码模式开关、指挥体显示名目标感知、弹窗防溢出+全局紧凑化、MiniMax 预设+端点模型清单拉取+默认模型改清单选择、登录页十六进制稳定 8 列、导航改模型/网关措辞

* i18n: 组详情视图新增键(返回/交互中/组成员等)

* fix: 左下角「通道就绪」改「模型就绪/模型未配置」(区分 IM 通道页与模型接入状态),WS 断连提示统一网关措辞

* feat: 体验优化批次——组内个体/单体系统提示词在线编辑(PROMPT 读写端点+弹窗重构,去领域/能力字段)、orchestrator 改名去前缀+主智能体标签后置、设置页移除用量卡、加载/输出卡互斥+内联<think>归入思维链(MiniMax-M1)、组卡片头换行修复、单体菜单重构(修改PROMPT.md/删除沉底确认)、Machina 提示词沉浸化重写(去系统机制自述)

* fix: 组卡片头单行(名称不折+id省略号)与设置页撑满正式部署;此前容器误载旧CSS(column版)

* fix: 块级标题卡片(组卡/模型卡/单体卡/技能卡)隐藏标题内联装饰——装饰遇块级标题折行为「装饰行+文字行+装饰行」

* fix: 卡片标题装饰保留并与文字同行——组卡/模型卡标题容器改 inline-flex(内联装饰不再被块级标题挤到独立行)

* fix: 设置页界面分类选中时运行时不再误亮(current回退groups[0]的bug);webui细节打磨——移除压角测量标记、选中色/光标跟随强调色、控件圆角统一、卡片与表格悬停反馈、弹窗分隔线质感、内联代码样式、菜单选中强调线、滚动条细化

* fix: 侧栏分隔线移除无意义的「CHANNEL」标签(避免与真正的通道页混淆)

* feat: 对话界面过程呈现重构(OpenCode 模式)——撤编码模式开关;思维链随收束留存(不再消失);思维/工具/调度过程全部收入「使用了 N 个…」收起栏(默认收起、点击展开、流式带呼吸点)

* fix: 内联<think>分流截断点按字符边界回退——中文等多字节思考内容触发 is_char_boundary 断言恐慌(线上实测);回归测试覆盖多字节小步增量/完整分离/前缀判定

* fix: 删除当前会话未从 sessions 列表状态移除——后续删除用旧快照重建列表导致已删会话「复活」;统一从 getState 最新状态过滤并先落列表

* fix: 规划阶段流式输出改道思维轨——L0/L1+ 的内部协议 JSON 不再裸奔到可见输出区;非流式回退的内联<think>按阶段分轨(思考轨/可见轨)

* fix: 断点续跑改后台执行——不再阻塞端口绑定(中断会话的多节点调度+LLM往返曾导致启动期间整站502)

* feat: ux-refinements 组1-4 实施——停止轮次(令牌+检查点+端点+按钮+通道/stop)、思维链落盘(messages 扩展+round_trace)、会话搜索/通道标识过滤/导出、工具审计页、用量面板回归、审批跳转、通道连通测试探针、cron 下次执行+模板

* chore: ux-refinements 任务勾选

* feat: 智能连结网络(实验性)——nexus.links 配置段+LinkTarget、连结体执行器(exmachina REST/CLI opencode/codex/claude/custom)、编成 link 代理声明+run_node 路由、连结体 CRUD 端点与智能体组页管理区、指挥体/子个体集群措辞与默认智能体改名「智能连结」

* fix: 「智能连结」是默认智能体组名(连结体)而非单体智能体——组名改智能连结、单体恢复 Machina;registry 缺省组名同步

* fix: 智能连结网络独立为侧栏页(智能体组下方);组成员单元格 id 移到中文名下方;恢复成员 SOUL.md 编辑(重构时误删);NexusView 补 message 导入

* ui: 侧栏顺序调整——任务图/自动化上移至技能/模型之前

* ui: 智能连结网络显性实验性声明(侧栏实验角标+页内警示条)+ 图标改 ClusterOutlined 消除与任务图撞图标

* fix: 智能连结网络实验声明改到点子上——如实说明设想尚未被验证、效果可能达不到预期,而非泛泛的接口变动免责

* ui: 智能连结网络实验声明精简为一句话

* ui: 侧栏智能连结项精简命名并保证左对齐单行(实验角标浮右)

* ui: 侧栏实验角标改为紧跟文字内联(浮右被甩出可视区)

* ui: 侧栏不再显示实验角标——实验声明保留在智能连结网络页内

* feat: experience-polish 实施——草稿/召回/复制/会话预览与相对时间、浏览器通知(授权+分类开关+点击跳转)、hash 视图路由+会话深链、骨架屏+横幅统一

* chore: experience-polish 任务勾选

* feat: WebUI 移动端适配——触屏操作常显(无hover)、设置页纵向堆叠、表格横向滚动兜底、网格窄屏单列、刘海屏安全区、页头操作换行

* ui: 回到底部悬浮按钮+视图切换淡入

* fix: 登录页窄屏适配——品牌字 clamp 缩放不再截断;底部签名去「全连结」残留(指挥体就绪)

* ui: 登录页签名去掉 DEUS 前缀(恢复用户已删的措辞)

* fix: 设置页 SECTIONS 补齐 6 个新分类(Computer Use/通道身份/用量限制/事件触发器/MCP 服务端/结果推送)——此前选择这些分类因缺 SECTIONS 条目导致面板永远加载

* refactor: agents 结构重组——skills 移至项目根、protocol 移入默认组、组 id default→exmachina

* feat: 默认智能体/指挥体/默认 SOUL 提示词全面重构——参考成熟编码智能体注入完整编码工作流(编辑纪律/终端纪律/搜索策略/调试流程)、机械语言协议(状态播报/情绪抑制/判定短语)、安全与权限协议、错误分级处理

* fix: SOUL.md 去掉身份标签只留人设描述;registry 残留 default 引用清理

* fix: SOUL 文件去除元描述引言——组指挥体与默认人格只留角色本身

* ui: 组成员表紧凑列宽——子个体列固定 220 消除空白,职责 260,工具/状态列收窄

* fix: 组成员提示词校验文案修正——不再误用模型名提示

* fix: SOUL 只留性格层(工作流归 PROMPT);成员表 tableLayout=fixed + 子个体列 220 真正生效

* refactor: 编成目录 agents/ → entities/——entities/agents(单体,常见 AI 软件同款) + entities/groups(智能体组);修复 skills 未入镜像

* copy: 默认智能体描述精简——默认智能体,以「本机」自称

* ui: 组成员表工具列加宽到 300,职责列让位——标签不再逐行堆叠

* rename: 子个体「媒体体」→「影音体」——避免「媒体+体」双体拗口

* feat: 编成模板机制——entities/templates/(unit×4 + group×1),用户与 agent 均可基于模板创建组和子个体(GET /api/templates + agent_manage templates/create + 前端模板选择)

* fix: 模板创建按 template.json 的 id 解析目录(此前误用 id 拼路径导致创建失败)

* feat: 版本更新功能——版本号定为 0.1.0,/api/version(+check) 对比上游 dev,设置页「版本更新」面板,Docker 构建注入 GIT_HASH

* fix: compose build.args 重复键合并——GIT_HASH 与 EXM_LANG 同段

* feat: 一键更新——POST /api/version/apply 经 docker.sock 执行 git pull→build→up -d,状态轮询端点 + 设置页一键更新按钮与恢复检测

* change: 更新检查源 dev→main——发版口径(dev 开发线,merge 到 main 时推送新版本);main 尚不存在时优雅降级提示

* fix: 一键更新重启步骤借道一次性辅助容器——compose 客户端不再随被重启的旧容器一起被杀(实测踩坑:recreate 半途而废)

* fix: 工具链下载 ADD url → RUN curl --retry——消除构建期持续联网校验,网络抖动不再炸构建

* fix: 一键更新工具链改挂载宿主 docker cli/compose 插件——移除构建期下载,内层构建零网络依赖(根治缓存不命中+网络抖动)

* docs: 替换“智械体集群”为“智能集群”并更新示例文案

* fix: 更新脚本自造 DOCKER_CONFIG/config.json——docker pull 无配置文件时报 no configuration file provided

* perf: GIT_HASH 移至 runtime 阶段注入——commit 变化不再作废 Rust 编译缓存(外层构建 10min→<1min,一键更新内层构建不再触发 rustup 全量同步)

* copy: 更新检查描述去掉工作流括号说明

* fix: 辅助容器挂载仓库宿主真实路径(从容器 mount 反解)——/host 只存在于网关容器内,宿主侧不存在导致 compose 找不到编排文件

* ci: 工作流触发策略收敛——CI 仅 PR 触发,发版仅 dev→main 合入触发,dev 日常提交零消耗

* docs: 新增开发规范——分支模型/提交纪律/发版仪式/工作流触发矩阵固化成文;CONTRIBUTING 对齐实际提交类型并挂规范入口

* fix: 更新检查分支感知——本地在什么分支就对比该分支的上游(main 用户看 main,dev 开发者看 dev);「上游最新」标签随实际上游渲染

* ui: 「上游最新」行渲染实际上游 ref——不再写死分支名(dev/main 通吃)

* fix: add_message_full 过程数据按 id 原位替换回 jsonl——此前 put 写独立文档,思维链/工具轨迹刷新即失

* feat: 单体直接工具循环——chat_execute(系统提示+历史+工具面自主决策)+ run_round 单体分支 + execute_named 过程轨迹补录

* test: 单体直接循环冒烟(工具回灌/轨迹留痕/无任务图)+ 上下文压缩用例改组模式承载;修复 dev 存量测试编译债(link 字段/ExmConfig::default)

* chore: 版本推进 0.1.1——单体直接工具循环 + 编成模板 + 版本更新/一键更新

* ci: CI/发版流水线补装 libxdo——computer-use 栈(enigo/xcap)链接期缺库,cargo test 未跑先挂

* docs: 单体直接工具循环 4.5 部署实测勾选——真实模型两轮验证通过

* test: git_panel 干净断言过滤注册表播种目录——entities/skills 是测试环境噪声,不属于提交流程

* fix: 更新检查 rev-parse 加 --verify——上游 ref 不存在时保持空值走降级,而非把字面量当 sha 返回

* release: v0.1.1 (#12)

* ci: 工作流触发策略收敛——CI 仅 PR 触发,发版仅 dev→main 合入触发,dev 日常提交零消耗

* docs: 新增开发规范——分支模型/提交纪律/发版仪式/工作流触发矩阵固化成文;CONTRIBUTING 对齐实际提交类型并挂规范入口

* fix: 更新检查分支感知——本地在什么分支就对比该分支的上游(main 用户看 main,dev 开发者看 dev);「上游最新」标签随实际上游渲染

* ui: 「上游最新」行渲染实际上游 ref——不再写死分支名(dev/main 通吃)

* fix: add_message_full 过程数据按 id 原位替换回 jsonl——此前 put 写独立文档,思维链/工具轨迹刷新即失

* feat: 单体直接工具循环——chat_execute(系统提示+历史+工具面自主决策)+ run_round 单体分支 + execute_named 过程轨迹补录

* test: 单体直接循环冒烟(工具回灌/轨迹留痕/无任务图)+ 上下文压缩用例改组模式承载;修复 dev 存量测试编译债(link 字段/ExmConfig::default)

* chore: 版本推进 0.1.1——单体直接工具循环 + 编成模板 + 版本更新/一键更新

* ci: CI/发版流水线补装 libxdo——computer-use 栈(enigo/xcap)链接期缺库,cargo test 未跑先挂

* docs: 单体直接工具循环 4.5 部署实测勾选——真实模型两轮验证通过

* test: git_panel 干净断言过滤注册表播种目录——entities/skills 是测试环境噪声,不属于提交流程

* fix: 更新检查 rev-parse 加 --verify——上游 ref 不存在时保持空值走降级,而非把字面量当 sha 返回

---------

Co-authored-by: KurohaneKaoruko <kurohanekaoruko@gmail.com>

* Fix/cross platform release (#16)

* build: 跨平台编译修复——computer.rs 平台差异(enigo Send/Key::Insert 平台门控)+ 一键更新 Unix 门控;release 流水线支持分支手动触发(编译预验,发布仍钉死 main)

* build: 重生成 tauri icon.ico——原文件是改扩展名的 PNG,Windows 资源编译器与 macOS 图标解码均拒绝

---------

Co-authored-by: BlackStar-Agent <kurohoshi@126.com>

* build: 桌面端重写为 egui 纯原生应用(无 webview)——chat-first 主窗口 + 原生设置页 + 隐藏终端侧车 + Inno Setup/tar.gz/dmg 安装链 (#18)

* feat: B1 SQLite 存储底座——store.sqlite 主库(会话/消息/任务图/回流/账本/快照/审计)+ 自动迁移旧 FSDB 数据

- store_sqlite.rs: SQLite 实现(62 方法全量移植,WAL 单写者)
- 自动迁移: Store::open 检测旧 FSDB 数据一次性转换
- rusqlite bundled(零外部依赖,构建环境自带 C 编译器即可)
- 已知边界: 证据/事件/检查点/outbox 等低频集合本批次仍走 FsDb

* feat: B1 SQLite 存储底座——store.sqlite 主库 + 自动迁移 + rusqlite 依赖(bundled)

* build: 打包脚本路径改仓库根口径——移除 ../ 前缀(CI 上指向仓库外)

* ci: 发版 tag 自动追加后缀——同版本重发时自动递增(v0.1.1 → v0.1.1.1 → v0.1.1.2),不再跳过

* ci: 修正发版检查——TAG 引用 ver 步骤输出(非自身),补 exists 输出

---------

Co-authored-by: KurohaneKaoruko <kurohanekaoruko@gmail.com>
Co-authored-by: BlackStar-Agent <blackstar-agent@users.noreply.github.com>
Co-authored-by: Kaoruko <101451942+KurohaneKaoruko@users.noreply.github.com>
* feat: EXMACHINA 智械体集群 —— Rust 多智能体协作系统(集群调度 / 契约回流 / 三账 / 记忆 / 多模型 / WebUI)

core: orchestrator DAG planning + concurrent dispatch, SyncReport contract enforcement with auto-rewrite, conflict arbitration, three-ledger (task/evidence/risk), recallable memory with decay, group/agent scoping and reliability stats

models: four protocols (openai/anthropic/gemini/azure) with sticky multi-key pools and per-protocol connectivity probe; per-agent/group default model resolution (agent -> group -> global) via ModelPool

platform: skills, cron/heartbeat automation, exec approval gate + auth key; Telegram/webhook/qq/wechat bridge channels; single-process gateway serving REST+WS+WebUI

delivery: exm/exmachina CLI, native-tls via system store, release profile LTO+strip (single binary ~5MB), GitHub Actions release pipeline for compile-free low-spec deployment; WebUI on React 19.3 + antd 6 (14 panels, 5 themes)

docs: four-doc set (install/usage/design/protocol); no provenance metadata in repo

* feat: P0 batch 1 — native function calling, model failover chain, context compaction, followup/collect

function calling: protocol-level tools for openai/anthropic/gemini/azure (definitions, streaming fragment assembly, per-protocol result threading); text protocol kept as mock/compatible fallback; whitelist/approval/audit preserved

failover: profile-level fallback chains (cycle-guarded), 45s cooldown skipping, switch only before any token emitted, global profile tail, model.failover event; provider form gains fallback selector

compaction: multi-turn context for planning — rolling summary (LLM-compressed) + recent-12 window injected into plan prompt; session.rollingSummary/summaryUpto persisted

followup/collect: Core::chat serializes runs per session (all channels migrated); queued inputs within a window merge into one round goal

fix latent ordering assumption: list_messages is chronological (fsdb read_lines), oldest->newest

tests: 17/17 green incl. failover chain/cooldown, compaction+collect semantics

* feat: P1 batch 2 — MCP client (stdio + streamable http) with tool gateway integration

mcp.rs: JSON-RPC 2.0 client, lazy initialize handshake, tools/list snapshot cache (sync) + connection pool (async, Send-safe), per-server allowedAgents visibility, tools/call with text content normalization

integration: config mcpServers[] persisted + hot rebuild on apply_config; ToolGateway.execute_mcp with unified audit; runtime tool specs extended per-agent with mcp:server:tool; native function-calling path routes mcp names; gateway serves GET /api/mcp + POST /api/mcp/refresh with background refresh on startup

tests: 18/18 green incl. in-test axum MCP server covering configure/refresh/snapshot/call/allowlist

* feat: P1 batch 3 — hybrid memory retrieval (semantic embeddings + lexical scoring)

provider: embed() on trait (openai /embeddings + azure deployments), deterministic pseudo-embeddings for mock channel; profile embedModel config + WebUI field

memory: entry vectors with write-path background backfill, query embedding boost in scoring, semantic fallback scan when lexical candidates empty; cosine similarity with layer/group scoping preserved

orchestrator: embed_query via active profile embed model injected into planning + dispatch recall paths

tests: 19/19 green (semantic fallback/boost smoke); serial guard for Core-based tests sharing repo workspace

* feat: P1 batch 4 — web_fetch tool and multimodal image input

web_fetch: ToolName variant with zero-dependency HTML body extraction (script/style/tag stripping, whitespace compaction), 20s timeout, 2MB cap, allowlist + audit semantics; dispatch made async

vision: ChatMessage.images (data URLs) mapped per protocol (openai image_url parts / anthropic base64 image blocks / gemini inline_data); image_stash module stages channel attachments for next planning turn; gateway chat body accepts images; WebUI attach button with canvas compression (<=1280px JPEG 82%, up to 4)

tests: 20/20 green incl. in-test axum page fetch (script/style stripped) and stash take-once semantics

* feat: P2 batch 5 — distributed execution nodes (old-device worker cluster)

protocol: /worker WebSocket endpoint with JSON frames (hello/dispatch/tokens/report/error), authKey auth; WorkerHub pool with per-worker outbound channels, pending dispatch table, token streaming into event bus, timeout-bounded execution

orchestrator: remote-first routing (sync accepts check + remote execute with local fallback, remote.fallback event); Core::set_remote hot-rebuilds orchestrator; execute_unit entry for worker side

worker: WorkerSession client (tokio-tungstenite plain WS) runs full local Core — its own model profiles/tool gateway; exm worker --url --token --id CLI subcommand (hostname default)

tests: 21/21 green incl. two-Core full-wire smoke (worker session via real WS executes dispatched nodes, DAG terminal)

* feat: P2 batch 6 — interrupted-session resume on gateway boot

resume: scan sessions with Executing graphs containing non-terminal nodes; replay done nodes (reports backfilled from sync_reports_by_node, report ids restored), reset interrupted to Ready, re-run scheduler, converge with resumed flag

plumbing: store.sync_report_of_node typed lookup; TaskGraphModel.set_report_id; ExecCtx/run_node/converge made public for resume path; gateway serve() triggers resume at boot

tests: 22/22 green incl. interrupted-graph reconstruction smoke (all nodes terminal, >=3 done after resume)

* feat: P2 batch 7 — terminal hardening (timeout kill) and session token budget

terminal: async execution via tokio (no runtime-thread blocking), kill_on_drop timeouts — 120s dispatch / 300s approval execution; hung commands can no longer stall nodes

budget: maxSessionTokens config (estimated chars/4, 0 = unlimited); Core::chat gate rejects over-budget sessions with clear guidance; schema entry for settings page

tests: isolated per-test agents tree copy (fixes cross-test repo workspace pollution — leftover active_group from interrupted runs broke roster loading); 23/23 green incl. hung-command kill and budget-gate smokes

* feat: P2 batch 8 — voice input pipeline and windows process-tree kill

voice: transcribe on LlmProvider trait (openai/azure /audio/transcriptions, multipart), Core::transcribe via active profile (whisper-1), POST /api/voice/transcribe endpoint; WebUI mic button (MediaRecorder webm -> gateway -> text into input, recording state)

hardening: timeout kill now taskkills the full process tree on Windows (cmd grandchildren no longer leak); pid captured before wait_with_output move

tests: 24/24 green incl. transcribe channel contract (mock explicitly unsupported)

* feat: P2 batch 9 — text-to-speech read-aloud and session usage observability

tts: speak() on LlmProvider trait (openai/azure /audio/speech, mp3 bytes), Core::speak via active profile (tts-1); POST /api/voice/speak returns audio/mpeg; WebUI per-message read-aloud button with playback state

usage: GET /api/sessions/:id/tokens (estimate + budget); chat rail shows live token usage, refreshed per round

tests: 24/24 green (speak channel contract alongside transcribe)

* feat: P1 batch 10 — telegram voice input and channel chat allowlist

voice: telegram voice messages -> getFile download (ogg) -> active-profile transcription -> normal text flow; failed transcription degrades gracefully

security: Channel.allowedChats allowlist (empty = unrestricted); non-listed chats ignored with log; exposed in create/update endpoints and WebUI channel form (comma-separated)

tests: 24/24 green regression

* feat: settings page categorized redesign + empty model defaults without keys

settings: sectioned cards (runtime/memory/security/automation) with icon+description headers, label-left control-right rows, proper widgets (switch for booleans, textarea for prompts/allowlists), per-page save button; LLM section stays on provider page

defaults: model names default to empty instead of gpt-4o placeholders — without API keys placeholder models are meaningless; users set real models when configuring a provider; mock channel ignores model names

gateway: maxSessionTokens exposed in GET/PUT /api/config; settings page shows live budget

* feat(ui): settings page v3 — left category nav, single-panel view

one category visible at a time (runtime/memory/security/automation) instead of stacked cards; enum select for approval mode; per-section save; fixed-width right-aligned controls

* feat: P1 batch 11 — dual memory modes (deep db vs memory.md file-only) + full config exposure

deep-off mode: planning injects memory.md (<=8000 chars) instead of db recall; memory panel becomes markdown editor via GET/PUT /api/memory/md; settings labels clarified

config exposure: GET /api/config now returns memory/security/automation groups — settings page shows actual values instead of schema defaults (was the incomplete part)

* feat: memory.md size limit with autonomous AI compaction and archiving

config: memoryMdMaxChars (default 5000) in memory group + settings schema; PUT /api/memory/md auto-triggers background compaction when over limit

compaction: LLM simplification via orchestrator provider (compression contract), original text archived — deep-on writes digest entry into db (searchable), deep-off appends workspace memory_archive.md; nothing lost either way

ui: md editor shows char count vs limit, save reports background compaction; mock channel deterministic compression output; 25/25 tests green

* feat(ui): units page group selector, flat member list (primary first), no domain division

units page: group dropdown to view/manage any group members (no longer bound to background active group); nav renamed units; primary agent listed first; domain grouping/inputs removed from units/groups/singles create forms — single-domain labels added complexity without value

gateway: DELETE /api/groups/:gid/agents/:identifier for cross-group member management; api.ts removeGroupAgent + allowedChats passthrough on channel create/update

* fix(ui): remove leftover activation wording from management pages

group/channel management pages no longer surface session-scoped activation state; wording aligned to per-session target selection

* feat(ui): language switcher (zh/en) next to theme switcher + shell translations

sidebar language panel in same position/style as theme; localStorage persisted; nav/branding/status/settings fully bilingual via shared i18n infra

cleanup: remove redundant tip line in GroupsView (group switching is already noted in chat rail)

* fix(ui): settings i18n — replace remaining title/desc refs with t() keys

* docs+core: 文档与事实对齐;移除「无密钥自动降级模拟通道」;修复终端超时用例挂起

文档(与代码事实逐条核对)
- docs/协议与契约.md:SyncReport 契约按代码修正(statements / risks /
  blockers{reason,unblockCondition} / conflicts);扩展点路径改 <identifier>.json
- docs/使用指南.md:group/agent create 的名称是位置参数(原文误写 --name);
  补 worker、group export/import、经验优化三节
- docs/架构与设计.md:重复小节去重;测试策略改为「测试替身仅测试使用」
- docs/安装指南.md:FAQ 由「无密钥自动降级模拟通道」改为「不会用模拟输出充数,需先配置模型」

代码(产品行为)
- 新增 UnconfiguredProvider:未配置端点/密钥的通道调用即报错并给出配置指引
- Provider 规则改为显式配置优先:有 base_url+key → 真实推理;未配置 → 替身模式给 Mock、
  产品模式给 Unconfigured;use_mock 仅由 EXM_LLM_MOCK=1(或测试)开启
- 移除全部「自动置 mock」点(config/gateway/cli/install);配置热更新不改变替身状态
- install / doctor / model list / chat 头 / 网关 banner 文案统一为「未配置——请在模型提供商页配置」

测试
- 修复 tools.rs 终端超时路径:stdio 读取独立任务 + 超时 abort + taskkill /T /F +
  child.wait() 有界回收(原实现挂死,曾导致全量测试 20+ 分钟不结束)
- 清理编译告警:删死结构体、noop clone、未用 mut/导入、测试函数名 ASCII 化

验证:cargo test --workspace 8 单测 + 17 冒烟全绿;gateway e2e 92/92 全绿

* ui: 排版层级重构 —— 新增表单只留主流程,可选与运维细节收进「高级设置」

用户反馈:新增提供商把厂商预设全铺成按钮墙、还要求填指挥体/子个体模型、嵌入模型、失败回退——
这些不该出现在「接入一个厂商」的主流程里。

设计原则(本轮确立):一页只回答一件事;可选与运维细节一律折叠,默认收起。

- 「提供商」页重写(ModelsView.tsx)
  - 厂商预设 9 按钮墙 → 下拉(带端点形态提示 + 自定义/自建端点)
  - 主表单只剩:提供商类型 → Base URL → API Key(Key 池为可选多行)
  - 高级设置(折叠):显示名称 / 档案 ID / API 协议 / 默认模型(预设自动填)/
    指挥体与子个体模型覆盖 / 嵌入模型 / 失败回退
  - 卡片信息层级重排:端点(+协议短标签) / 模型 / 密钥状态 / 回退链 / 嵌入模型
  - 措辞修正:不再出现「Mock / 模拟通道」,未配密钥显示「未配置(对话前请补填)」
- 新增统一页头组件 components/PageHeader.tsx(标题 + 一句话说明 + 右侧操作区),
  落地于:提供商 / 子个体 / 智能体组 / 独立智能体 / 技能 / 自动化 / 审批 / 通道 / 记忆 / 活动;
  原先挤在按钮行里的长提示统一挪入说明段(层级:标题 → 说明 → 操作)
- 通道表单 8 项平铺 → 核心 = 平台/通道 ID/Token/绑定组,高级 = 备注/白名单/出站回调
- 自动化表单 6 项平铺 → 触发方式改 Segmented(周期 Cron | 一次性时间)互斥切换,会话标题进高级
- styles.css 新增 .page-head/.page-title/.page-desc/.page-actions/.form-advanced/.model-kv/.form-grid-2
- 命名对齐:与工作区正在进行的「模型提供商 → 提供商」全局改名保持一致

验证:npm run build:webui(tsc + vite)通过;产物含新样式与新文案,
「厂商预设 / 模拟通道 / Mock 模拟」字样已从产物消失;网关实测启动正常(health 200 / 托管 dist / 40 个体)

* ui: 控制台视觉重构 —— 工程图刻度语汇、页面编号 01–14、科研感登录门与任务图

三类线条语汇(全部由 CSS 变量驱动,随 5 套强调色联动):
- hud 角标:面板四角短刻线;scale 刻度尺:等差刻度 + mask 淡出;grid 剖面:低透明度栅格

全局
- 新增令牌 --tick-step / --tick-color / --tick-color-hi / --grid-size / --accent-04·08·30
- body 双向 40px 栅格底纹;全局 tabular-nums 保证读数对齐

侧栏与页头
- 侧栏右缘刻度尺(每 5 格长刻线);菜单项加序号列,序号与图标间加短刻线,选中项左侧荧光轨
- 页面编号 01–14:单一事实源 NAV_ITEMS,侧栏与页头同源
- PageHeader 重构:desc 移出 .page-head-row 独占整行,修复说明文字被操作按钮压住

组件
- 表格表头列间竖刻线分隔;补齐此前完全缺失的 .plain-table / .model-card / .skill-card / .pane-loading
- LedgerView 补页头(原无页头且空态早退);SettingsView 统一 pane-wrap;ChatView 加控制台读数条

仪器感页面
- 登录门:72 条刻度环 + 十字准星 + 双层同心圆,去圆角,标题下加测量基线
- 任务图:坐标刻度、节点状态轨 + 量度条、正交折线连线、NODES/EDGES/DEPTH 读数

文档
- docs/使用指南.md WebUI 章节表格按 01–14 重排

* 提供商页回到「只回答一件事」+ 侧栏/间距回正 + 编排词清理

提供商设置(用户反馈:不该加的东西不要往这加):
- API Key 与 Key 池合并为一个可增删列表,不再分两块填
- 指挥体模型 / 子个体模型从全栈删除(此前只是折进「高级设置」,等于没删):
  LlmProfile/LlmConfig 的 orch_model/unit_model/embed_model 合并为单一 model;
  ModelPool 的 insert/resolve/entry 去掉 unit 参数;expand_chain 同上;
  gateway/CLI/install 向导同步;旧配置由 LlmProfileFile/LlmConfigFile 兼容读取,保存后不再回写旧键
- 嵌入模型移到「记忆」页「语义检索」卡(memory.semanticModel),core 新增 semantic_recall()
- 提供商类型名后不再挂多余描述

WebUI:
- 侧栏去掉序号列、恢复原有顺序与文案(撤销上一轮擅自的改名「独立智能体」与换位)
- .pane-wrap 去掉在已有内边距容器里的二次居中(智能体组/子个体左空隙过大的根因)
- list-rail 300→260px、skill-grid 最小 380→320px

文案:
- 清除「公司架构/团队架构」类比(9 处),示例组名改「研发组」
- 清除自造的「独立智能体」,统一为「智能体」

修复:
- e2e.rs 未带密钥 401 用例中重复的请求行(第二次请求覆盖第一次,属脚本改写的残留)

验证:cargo check --all-targets 0 警告;cargo test 8+17 全绿;e2e 92/92;
tsc --noEmit 干净;vite build 通过;产物禁用语扫描全 0。

* webui: 修复「记忆」页白屏崩溃 + 提供商卡片信息层级 + 设计令牌归一

修复(实测发现,非推断):
- 记忆页整页白屏:MemoryView 用 stats?.memory.total,外层可选链挡不住内层缺失
  (stats 有值而 memory 为 undefined 时照样抛错,整棵 React 树塌掉)。
  改为逐层 stats?.memory?.total ?? 0;同类 config?.memory?.enabled / semanticModel 一并加固。
- 侧栏底栏的 MOCK/LINK 徽标删除:测试替身不是产品状态,违反项目铁律。
  改为「通道就绪 / 未接入」,由 config.llm.apiKey 是否非空驱动。

提供商卡片:
- 改为四行事实:端点 / 模型 / 密钥 / 状态;「全局默认」从标题行移入事实区,
  标题只留身份,不再与操作按钮争位置
- 「已配置(N 把)」原用 warning 琥珀色(读起来像出故障),改为绿色中性态;
  「未配置」才用 warning
- 卡片头统一高度,避免「有无次要按钮」导致事实行跨卡错位
- 页头说明压成一句

版式与令牌:
- 颜色归一:手抄近似值 #8fa6b8 / #9fb6c6 → var(--text),
  rgba(29,42,54,0.6~0.9) → var(--line),共 8 处
- antd token 同步:colorTextSecondary #8fa6b8 → #6d8296(= --muted),
  colorTextTertiary → #4a5c6c(= --muted-dim)
- 智能体组元信息行的全角空格分隔改为真实元素 + flex gap

验证:cargo check --all-targets 0 警告 0 错误;cargo test 8+17 全过;e2e 92/92;
tsc --noEmit 干净;vite build 通过;提供商/记忆/智能体组/侧栏多页截图实拍复核。

* docs: 统一 orchestrator 注释措辞为「单体智能体」

「独立智能体」是此前自造的叫法,全库仅剩这两处(均为注释)。代码库既有术语
是「单体智能体 / 单体模式」(registry.rs、singles.rs、SINGLE_CONTRACT 正文、
smoke.rs 一致使用),本次对齐,全库该词归零。

验证:cargo check --all-targets 无代码级告警;cargo test 8+17 全过;e2e 92/92。

* feat(ui): markdown rendering for chat messages (GFM, dark-theme code blocks)

* feat(ui): session search, rename, and chat rail cleanup

* refactor(ui): groups page — clean flat layout, settings modal, remove inline editing clutter

* feat(ui): groups page settings modal (workspace + default model) with gear button

* fix(ui): chat page declutter — remove duplicate speak btn, simplify console bar, hover session ops, shorter hints

* feat(ui): collapsible chat sidebar with edge toggle button

* fix(ui): restore console bar readouts (MODE/STATE/TOKENS) removed in earlier cleanup

* fix(ui): chat-shell height and CSS cleanup

* fix(ui): chat-shell row-reverse in main rule not trailing override

* fix(ui): remove redundant read-aloud button from message bubbles

* feat(ui): task graph page — session label + selector, clear which session the DAG belongs to

* fix(ui): graph page — stats readout left, session selector right

* feat: one-click quickstart scripts (sh + bat)

* docs: README quickstart — one-click scripts first, manual build second

* feat: full auto-install scripts (install.sh + install.bat) — clone, install deps, build, run

* feat: quickstart downloads prebuilt releases (no compile needed); CI workflow builds and publishes on tag

* chore: move install/quickstart scripts to scripts/ folder; update README URLs

* ci: add test-only workflow on push; release.yml waits for manual tag (no auto-publish until fully tested)

* fix(docs): README ASCII art — pure ASCII # style, equal-width lines render correctly on GitHub

* feat(docs): SVG logo with DAG node design, terminal aesthetic, animated status LED

* docs: SVG logo — 58px font, compact DAG, text glow, fills canvas

* docs: SVG logo — hard edges, diamond DAG nodes, right-angle wire routing, no ONLINE

* docs: SVG logo — diamond nodes drawn after lines (no overlap), diagonal wire routing restored

* docs: redesigned product logo — hex lattice + center diamond, large 68px wordmark; separate 256px app icon

* docs: premium logo — layered hex, glowing core with inner diamond, HUD tick marks, corner brackets, gradient wordmark

* docs: logo — restore EX·MACHINA dot separator, align connector lines to diamond vertices

* docs: full-width banner logo (icon left, wordmark + tagline right); README adds H1 heading; intro text embedded in SVG

* docs: logo — precise flat-top hexagon geometry, centered text block, proper icon-text spacing; README H1 updated

* docs: restore original subtitle and README H1

* docs: README H1 = ExMachina — 一个群体协作的智能集群

* docs: logo subtitle = ExMachina — 一个群体协作的智能集群

* docs: logo — remove icon, pure centered text banner

* docs: logo — 110px title nearly fills width, wider underline

* docs: logo — 100px title with top spacing, 18px subtitle, 14px body text

* docs: add LICENSE (MIT), SECURITY.md, CONTRIBUTING.md

* docs: SECURITY.md and CONTRIBUTING.md now bilingual (zh/en)

* docs: split README into zh (README.md) + en (README_EN.md) with language switcher

* docs: logo subtitle restored to 智械体集群 · MULTI-AGENT CLUSTER

* docs: logo subtitle — 智械体集群 // AGENT CLUSTER (original)

* docs: language switcher moved below badges, centered

* docs: logo — subtitle 18→22px semibold, body 14→18px, brighter colors, more height

* docs: logo — 画布 1200x300,字号与线宽按 Retina 重做;背景改纯色、去副标题

README 头部 SVG 的「字小、线细、锯齿」三个根因与修法:

1. 字小 —— 画布 960x280 经 width=100% 引用后在 GitHub 阅读栏(1012px)
   只剩 ~295px 高。改为 1200x300,主标题 100→88px(配 letter-spacing 撑满)、
   底部文案 18→23px。删掉副标题后标题整体下移到视觉居中。
2. 线细 —— 原字体栈以 'SF Mono','Cascadia Code' 打头,Windows 会落到
   Courier New(细衬线等宽)。字体栈改为 ui-monospace 打头;
   主标题改 fill + 同色 stroke + paint-order 加粗字面。
3. 锯齿 —— 0.4px 级描边在 Retina 上被采样成灰虚线。全部细线提到 >=1.6px
   且落在整数设备像素;移除 0.4px 网格线。

排版取舍:
- 背景改为纯色 #0b1118,不使用渐变。
- 删除副标题「智械体集群 // AGENT CLUSTER」。
- 不加角标等装饰性元素,只保留刻度尺 / HUD 角标 / 边框 / 分隔线。
- 底部文案含「零情绪」,属此前已否掉的自造氛围词,删除;
  压成四个短标签(契约回流 / 冲突裁决 / 证据分级 / 结论收束)。

exmachina-icon.svg 未改动。

* feat: 通道平台全面扩展 —— QQ 官方机器人 / NapCat 适配器 + 运行状态 + 密钥掩码

通道网关(后端):
- 新增 qqbot 适配器:开放平台 WS 长连接,token 缓存提前刷新,断线先 Resume 再
  Identify,被动回复携带 msg_id + 递增 msg_seq,sandbox 可选
- 新增 napcat 适配器:OneBot 11 正向 WS(NapCat / Lagrange 通用),读循环常开 +
  mpsc 专职写任务,数组段与 CQ 码双格式解析
- 通道配置平台目录化:Channel.config{} 扩展配置,新平台零结构体改动;
  create 校验 qqbot 需 appId/appSecret、napcat 需 url
- 通道运行状态:适配器连上/断开/出错覆盖上报,GET /api/channels/status 查询,
  删除/停用即清除
- 密钥全链路掩码回显(***已配置***):顶层 token/secret + 敏感 config 键;
  更新三态语义(掩码沿用 / 空清除 / 新值)
- 修复:PUT /channels/:id 的 body.id 无默认值,前端更新通道(不发 id)一直 422,
  通道编辑与启停开关自上线即不可用;补 #[serde(default)] + e2e 锁定

WebUI:
- 通道页重写为平台目录驱动(PLATFORMS):表单/凭证判定/回复形态由目录出,
  状态列轮询运行状态(已连接 / 连接异常 + 明细)
- 修复:ModelsView 本地掩码哨兵 ***MASK*** 与后端 ***已配置*** 漂移,编辑档案
  不改密钥会把掩码字面量存成 API Key;统一为 api.ts 共享 KEY_MASK
- i18n 架构化:i18n/ 注册表(TKey 编译期键检查,en 缺键回退 zh,新语言零成本),
  全部视图清扫,中英双份词条
- 布局修复:对话页与右侧会话栏间距(row-reverse 无 gap)

验证:
- cargo check --workspace 零警告;e2e 103/103(新增通道校验/掩码落盘/状态接口
  断言;e2e 环境自持,不再随本机 config 漂移)
- npm build 通过;通道页中英表格与编辑弹窗截图复核

* feat: 「提供商」→「模型设置」—— 模型清单 + 能力模型(组级覆盖)+ 视觉转述

模型设置页(原「提供商」页改名,nav.models):
- LlmProfile.models[]:每个提供商一份模型清单(模型名 + 视觉/语音能力开关);
  默认模型保存时自动并入清单;清单未标记 = 能力未知,输入直通(向后兼容)
- 能力模型槽位(capabilities 配置节 + GET/PUT /api/llm/capabilities):
  语音合成(TTS)/ 语音识别(语音转述)/ 视觉转述 / 嵌入;
  嵌入与记忆页 semanticModel 同一字段(两处入口等价);TTS/STT 由硬编码 tts-1/whisper-1
  改为按槽位解析,未配置回落原默认
- 视觉转述降级:生效模型明确 vision=false 且配置了转述模型时,逐图转文字描述注入规划;
  未配置则忽略图片并在输入中说明;能力未知保持直通
- UI:提供商卡新增模型清单行(默认 / 视觉 / 语音);页底「能力模型 · 全局默认」卡;
  编辑弹窗 Form.List 模型清单(开关 + 增删)

组级能力覆盖(能力槽位不再全局单值):
- GroupMeta.capabilities 持久化 + PUT /api/groups/:id/capabilities
  (空串 = 清除该项跟随全局;全空 = 整块收回)
- 槽位解析两级:组覆盖 → 全局槽位 → 出厂默认;TTS / STT / 视觉转述 / 嵌入四处统一
- 组设置弹窗新增「能力模型(组级覆盖)」四槽位,留空 = 跟随全局默认

修复:
- tr() 改用 useLang.getState() 同步读语言:原 hook 形式在组件渲染期被调用
  (构造 Select options)会把 hook 计入当前组件,两次渲染间钩子数漂移导致 React #310
  全树崩溃;同时消除 api.ts / models.ts 三处同类隐患

验证:cargo check 零警告;e2e 全过(模型清单与开关回显、能力槽位写入/回读、
组级覆盖写入/空串清除/落盘回读);npm build 通过;中英双页截图复核

* docs: README 头部改用同款 EXMACHINA 字符画(字母间 2 空格),快速开始前移至告警之后

* docs: 警告块前移至字符画之前(H1 下首元素)

* docs: 字符画首行补 1 空格对齐 88 列——修复逐行居中渲染下的右偏

* build(rust): toolchain by host + silence Linux-only unused pid

- rust-toolchain.toml / .cargo/config.toml: switch to stable channel so
  rustup auto-selects the host triple (Linux/macOS/Windows all build
  without edits); comment updated accordingly.

- crates/exm-core/src/tools.rs: mark the local \`pid\` binding with
  \`cfg_attr(not(target_os = \"windows\"), allow(unused_variables))\`.
  The PID is only consumed inside the Windows taskkill branch; on POSIX,
  tokio::Child::kill_on_drop already handles process teardown.

Verified on Debian 13 / x86_64-unknown-linux-gnu: `cargo check --workspace`
and `cargo build --workspace --release` both report zero warnings; the
`exm` / `exmachina` / `exm-gateway` binaries are produced and a
`cargo run -p exm-gateway --release` smoke test answers
`/api/health` with agents=40, ok=true.

* feat(gateway): bind on 0.0.0.0 by default; add --host flag

VPS / 容器 / 局域网部署场景下,loopback 默认值导致 '能跑起来但远程
访问不到'。改为:

- exm-gateway 默认监听 0.0.0.0,公网/局域网可访问(向后兼容:
  EXM_HOST=127.0.0.1 或 --host 127.0.0.1 仍可收紧)。
- `exm serve` 新增 --host 选项(短 -H),显式传入覆盖默认 / 环境变量。
- 启动日志链接打印改为绑定到的真实地址(不写死 127.0.0.1)。

API 变化:`exm_gateway::serve(core, port)` → `serve(core, port, host: Option<&str>)`,
库调用方需更新;唯一调用方(exm-cli 与 exm-gateway 独立入口)已同步。

* fix: 批量修复 WebUI/网关缺陷 17 项(API Key 保存与池掩码令牌化、鉴权设置入口、个体/智能体编辑、设置页契约、WS 重连竞态、间距统一等)+ 主智能体更名指挥体 + 单体去职责化;并入在途 WIP(browser 闸门/自定义工具/discord/matrix/slack 通道)

* fix: API Key 表单绑定真根因(Form.List 行绑定致输入被过滤)+ 智能体卡片 ⋮ 菜单(切换模型/编辑描述/编辑 SOUL.MD)+ 单体人设读写与 plan/converge 双注入 + 默认组/指挥体英文标注映射

* feat: 安装脚本重写(4 文件)——预检/重试/校验和/升级保数据/--port/--help/品牌化输出;修 macOS arm64 硬编码与构建日志吞错;bat 改 PS5.1 引导壳全 ASCII 免疫代码页 bug

* chore: 移除误入提交的测试残留文件 upgrading

* docs: 移除 README 低性能设备预编译包引导段落

* Update README with project inspiration details

Added a note about the project's inspiration from Ex-Machina in No Game No Life.

* Fix formatting in README.md for project inspiration

* feat: 编码体验全量落地 + 编成组目录制定稿 + Computer Use + WebUI 编码工作台/PWA + 桌面端 Tauri 壳

思维链与过程透明(对标编码型 Agent):
- provider 双轨流式:解析 reasoning_content/thinking_delta/Gemini thought,新增
  StreamDelta::{Text,Thinking};新 WS 事件 orchestrator.thinking / unit.thinking
- tool.call / tool.result 事件(callId/args/ok/耗时/摘要/images),工具执行全程可见
- 审批等待回灌:拦截后原地等待 approvalWaitSecs,批准后代执行、输出直灌模型继续干活
- WebUI 聊天页:思维流折叠、工具执行卡(edit diff/终端输出/截图预览)、内联审批卡

Computer Use:
- computer 工具(enigo 键鼠 + xcap 截屏):screenshot/click/move/scroll/type/key
- 默认关闭显式开启;输入动作过审批闸门 + 动作节流;截图经 ToolResult.images
  回灌视觉模型(vision 能力检测)并可在工具卡内预览

WebUI:
- 新增编码工作台 [CODE]:会话 | 工具优先对话流 | 工作区文件树 + 变更清单 + 代码预览
- 网关配套 /api/asset(截图预览)与 /api/fs/list|file(文件树/预览,沙箱只读)
- PWA(manifest + Service Worker + 图标)与移动端抽屉导航;与客户端同端口交付

编成组目录制定稿(多轮评审定稿):
- 组 = groups/<gid>/:group.json + SOUL.md(主智能体人格,仅用户面持有)+
  MEMORY.md(组浅层记忆快照,6000 字截断)+ agents/*.json + prompts/*.md + adaptations/
- 单体 = singles/<id>/:agent.json + PROMPT.md + SOUL.md + MEMORY.md
- 子个体无人格层、无独立文件夹(定义+提示词合并存储于组内);深/浅记忆分层语义定稿
- 提示词分层:主智能体偏助手(对话优先/L0 直答)、子个体各司其职(编码位增补作业纪律)、
  单体全能;registry 全链适配 + gen-agents.mjs/doctor/install/e2e 同步

桌面端:
- desktop/(Tauri v2):捆绑 exm-gateway sidecar 本机模式 + --remote/--key 远程直连,
  退出杀进程树;MSVC 为官方构建目标(README 内说明)

测试:test_config 密封化(强制 Mock + 审批等待 0);新增审批等待回灌三场景用例;
cargo test --workspace 8 单测 + 21 冒烟全绿;npm run build:webui 通过;网关冒烟全过

* chore: 接入 OpenSpec 规范驱动开发——新增 openspec/ 目录骨架与配置,.gitignore 放行 .gitkeep

* feat: OpenSpec 变更 capability-completion 落地(1/3)——配置 v2 六段新配置与迁移、存储三集合骨架、patch 补丁工具(统一 diff 解析/整体拒绝/行尾容差)+ coding/ops 白名单

* feat: capability-completion(2/3)——工作区变更接口(git 口径/检查点回退)、文件保存接口(沙箱+检查点+审计)、simple_unified_diff 生成器;测试 5+23 全绿

* feat: capability-completion(3/3 P0)——git 面板(概览/暂存/提交/切换 + 破坏性审批单)、CodingView 三标签改造、webui i18n;测试 3/5 全绿

* test: P0 闸门验证——修复上游脆弱测试(审批等待用例未显式声明 risky 闸门模式);workspace 52 测试全绿

* feat: capability-completion 组3 通道身份与门控——/pair 配对码(短码/TTL/单次)、入站统一闸门(群聊唤醒门控+身份管控前置裁决)、六适配器提及归一化(tg getMe 缓存/discord mentions/slack app_mention/napcat CQ:at/qqbot @驱动/matrix m.mentions)、审批单来源升级标(origin_user/origin_role)、IdentityPanel 控制台 UI;闸门单测 5/5

* feat: capability-completion 组4 用量治理——滑动窗口限流(通道主体/API 维度)、周期配额(请求数 @admit + token @run,按会话台账)、组内派发豁免、/api/limits/stats + SettingsView 用量卡片;P0 闸门关闭(workspace 全绿 68 测、validate 通过)

* feat: capability-completion 组6(1/3)——出站能力矩阵与降级决策、typing 指示(telegram/discord)、长回复分段推送(段落优先/代码块完整/超长硬切续接);回复分段/降级单测 5 个

* docs: design.md 增补 D12——媒体产物透出(outbox/artifacts)与出站投递实施口径(组 6.2-6.4)

* feat: capability-completion 组6(2/3)——媒体产物透出(outbox/截图与投递目录登记/run.finished artifacts)、spawn_reply 双闭包投递(直发+降级并注)、telegram/discord/slack 媒体直发(multipart/三步上传)

* feat: capability-completion 组6(3/3)——napcat 媒体直发(base64:// 段,远程安全)、matrix 媒体上传(media v3→content_uri)、入站媒体解析(telegram photo/document、discord attachments、napcat 段:下载落 inbox→图片暂存/文件注记,失败回退)+ 注入单测 2

* feat: capability-completion 组6 收尾——slack url_private 下载 / qqbot attachments / matrix mxc 媒体下载与失败占位回退;六通道入站媒体全通 + 注入/回退单测

* feat: capability-completion 组7-9——事件触发器(文件监听去抖合并/webhook HMAC+审计/cron 推送订阅/心跳 per-agent)、记忆三工具(组隔离/source=agent/主智能体默认授权)、会话历史管控(轮次快照/undo 检查点联动/编辑重发/fork 分支+REST+WebUI 入口)

* feat: capability-completion 组10 MCP 服务端——ACL 可见性矩阵(组/会话/工具清单)、stdio exm mcp serve(JSON-RPC 会话亲和)、网关 /mcp HTTP 挂载(鉴权+限流)、外部调用安全口径一致(审批/审计 mcp 来源标注);协议端到端/亲和/ACL/审批口径测试

* feat: capability-completion 组11-12——桌面集成(系统托盘/关窗驻留可配/原生通知三类含类别开关与事件映射单测/全局快捷键可改绑冲突提示)、doctor 新配置段诊断、文档同步(README 能力表/使用指南新章节/协议契约 REST+WS 事件)、原创性验收禁用词零命中

* chore: capability-completion 12.4 最终闸门——Dockerfile 补齐容器构建/运行时依赖(xcap dbus vendored 静态编译、enigo libxdo 构建包与 X11 运行时栈),compose 冒烟通过(health ok + 40 个体装载)

* chore: compose 支持 EXM_AUTH_KEY 注入(后台访问密钥,.env 注入不入库)

* fix: 用户测试反馈 12 项——WS 鉴权豁免(浏览器无法带头)+服务端 Ping 保活+客户端指数退避看门狗、组页卡片化+子个体并入组详情、编码页撤并为对话页编码模式开关、指挥体显示名目标感知、弹窗防溢出+全局紧凑化、MiniMax 预设+端点模型清单拉取+默认模型改清单选择、登录页十六进制稳定 8 列、导航改模型/网关措辞

* i18n: 组详情视图新增键(返回/交互中/组成员等)

* fix: 左下角「通道就绪」改「模型就绪/模型未配置」(区分 IM 通道页与模型接入状态),WS 断连提示统一网关措辞

* feat: 体验优化批次——组内个体/单体系统提示词在线编辑(PROMPT 读写端点+弹窗重构,去领域/能力字段)、orchestrator 改名去前缀+主智能体标签后置、设置页移除用量卡、加载/输出卡互斥+内联<think>归入思维链(MiniMax-M1)、组卡片头换行修复、单体菜单重构(修改PROMPT.md/删除沉底确认)、Machina 提示词沉浸化重写(去系统机制自述)

* fix: 组卡片头单行(名称不折+id省略号)与设置页撑满正式部署;此前容器误载旧CSS(column版)

* fix: 块级标题卡片(组卡/模型卡/单体卡/技能卡)隐藏标题内联装饰——装饰遇块级标题折行为「装饰行+文字行+装饰行」

* fix: 卡片标题装饰保留并与文字同行——组卡/模型卡标题容器改 inline-flex(内联装饰不再被块级标题挤到独立行)

* fix: 设置页界面分类选中时运行时不再误亮(current回退groups[0]的bug);webui细节打磨——移除压角测量标记、选中色/光标跟随强调色、控件圆角统一、卡片与表格悬停反馈、弹窗分隔线质感、内联代码样式、菜单选中强调线、滚动条细化

* fix: 侧栏分隔线移除无意义的「CHANNEL」标签(避免与真正的通道页混淆)

* feat: 对话界面过程呈现重构(OpenCode 模式)——撤编码模式开关;思维链随收束留存(不再消失);思维/工具/调度过程全部收入「使用了 N 个…」收起栏(默认收起、点击展开、流式带呼吸点)

* fix: 内联<think>分流截断点按字符边界回退——中文等多字节思考内容触发 is_char_boundary 断言恐慌(线上实测);回归测试覆盖多字节小步增量/完整分离/前缀判定

* fix: 删除当前会话未从 sessions 列表状态移除——后续删除用旧快照重建列表导致已删会话「复活」;统一从 getState 最新状态过滤并先落列表

* fix: 规划阶段流式输出改道思维轨——L0/L1+ 的内部协议 JSON 不再裸奔到可见输出区;非流式回退的内联<think>按阶段分轨(思考轨/可见轨)

* fix: 断点续跑改后台执行——不再阻塞端口绑定(中断会话的多节点调度+LLM往返曾导致启动期间整站502)

* feat: ux-refinements 组1-4 实施——停止轮次(令牌+检查点+端点+按钮+通道/stop)、思维链落盘(messages 扩展+round_trace)、会话搜索/通道标识过滤/导出、工具审计页、用量面板回归、审批跳转、通道连通测试探针、cron 下次执行+模板

* chore: ux-refinements 任务勾选

* feat: 智能连结网络(实验性)——nexus.links 配置段+LinkTarget、连结体执行器(exmachina REST/CLI opencode/codex/claude/custom)、编成 link 代理声明+run_node 路由、连结体 CRUD 端点与智能体组页管理区、指挥体/子个体集群措辞与默认智能体改名「智能连结」

* fix: 「智能连结」是默认智能体组名(连结体)而非单体智能体——组名改智能连结、单体恢复 Machina;registry 缺省组名同步

* fix: 智能连结网络独立为侧栏页(智能体组下方);组成员单元格 id 移到中文名下方;恢复成员 SOUL.md 编辑(重构时误删);NexusView 补 message 导入

* ui: 侧栏顺序调整——任务图/自动化上移至技能/模型之前

* ui: 智能连结网络显性实验性声明(侧栏实验角标+页内警示条)+ 图标改 ClusterOutlined 消除与任务图撞图标

* fix: 智能连结网络实验声明改到点子上——如实说明设想尚未被验证、效果可能达不到预期,而非泛泛的接口变动免责

* ui: 智能连结网络实验声明精简为一句话

* ui: 侧栏智能连结项精简命名并保证左对齐单行(实验角标浮右)

* ui: 侧栏实验角标改为紧跟文字内联(浮右被甩出可视区)

* ui: 侧栏不再显示实验角标——实验声明保留在智能连结网络页内

* feat: experience-polish 实施——草稿/召回/复制/会话预览与相对时间、浏览器通知(授权+分类开关+点击跳转)、hash 视图路由+会话深链、骨架屏+横幅统一

* chore: experience-polish 任务勾选

* feat: WebUI 移动端适配——触屏操作常显(无hover)、设置页纵向堆叠、表格横向滚动兜底、网格窄屏单列、刘海屏安全区、页头操作换行

* ui: 回到底部悬浮按钮+视图切换淡入

* fix: 登录页窄屏适配——品牌字 clamp 缩放不再截断;底部签名去「全连结」残留(指挥体就绪)

* ui: 登录页签名去掉 DEUS 前缀(恢复用户已删的措辞)

* fix: 设置页 SECTIONS 补齐 6 个新分类(Computer Use/通道身份/用量限制/事件触发器/MCP 服务端/结果推送)——此前选择这些分类因缺 SECTIONS 条目导致面板永远加载

* refactor: agents 结构重组——skills 移至项目根、protocol 移入默认组、组 id default→exmachina

* feat: 默认智能体/指挥体/默认 SOUL 提示词全面重构——参考成熟编码智能体注入完整编码工作流(编辑纪律/终端纪律/搜索策略/调试流程)、机械语言协议(状态播报/情绪抑制/判定短语)、安全与权限协议、错误分级处理

* fix: SOUL.md 去掉身份标签只留人设描述;registry 残留 default 引用清理

* fix: SOUL 文件去除元描述引言——组指挥体与默认人格只留角色本身

* ui: 组成员表紧凑列宽——子个体列固定 220 消除空白,职责 260,工具/状态列收窄

* fix: 组成员提示词校验文案修正——不再误用模型名提示

* fix: SOUL 只留性格层(工作流归 PROMPT);成员表 tableLayout=fixed + 子个体列 220 真正生效

* refactor: 编成目录 agents/ → entities/——entities/agents(单体,常见 AI 软件同款) + entities/groups(智能体组);修复 skills 未入镜像

* copy: 默认智能体描述精简——默认智能体,以「本机」自称

* ui: 组成员表工具列加宽到 300,职责列让位——标签不再逐行堆叠

* rename: 子个体「媒体体」→「影音体」——避免「媒体+体」双体拗口

* feat: 编成模板机制——entities/templates/(unit×4 + group×1),用户与 agent 均可基于模板创建组和子个体(GET /api/templates + agent_manage templates/create + 前端模板选择)

* fix: 模板创建按 template.json 的 id 解析目录(此前误用 id 拼路径导致创建失败)

* feat: 版本更新功能——版本号定为 0.1.0,/api/version(+check) 对比上游 dev,设置页「版本更新」面板,Docker 构建注入 GIT_HASH

* fix: compose build.args 重复键合并——GIT_HASH 与 EXM_LANG 同段

* feat: 一键更新——POST /api/version/apply 经 docker.sock 执行 git pull→build→up -d,状态轮询端点 + 设置页一键更新按钮与恢复检测

* change: 更新检查源 dev→main——发版口径(dev 开发线,merge 到 main 时推送新版本);main 尚不存在时优雅降级提示

* fix: 一键更新重启步骤借道一次性辅助容器——compose 客户端不再随被重启的旧容器一起被杀(实测踩坑:recreate 半途而废)

* fix: 工具链下载 ADD url → RUN curl --retry——消除构建期持续联网校验,网络抖动不再炸构建

* fix: 一键更新工具链改挂载宿主 docker cli/compose 插件——移除构建期下载,内层构建零网络依赖(根治缓存不命中+网络抖动)

* docs: 替换“智械体集群”为“智能集群”并更新示例文案

* fix: 更新脚本自造 DOCKER_CONFIG/config.json——docker pull 无配置文件时报 no configuration file provided

* perf: GIT_HASH 移至 runtime 阶段注入——commit 变化不再作废 Rust 编译缓存(外层构建 10min→<1min,一键更新内层构建不再触发 rustup 全量同步)

* copy: 更新检查描述去掉工作流括号说明

* fix: 辅助容器挂载仓库宿主真实路径(从容器 mount 反解)——/host 只存在于网关容器内,宿主侧不存在导致 compose 找不到编排文件

* ci: 工作流触发策略收敛——CI 仅 PR 触发,发版仅 dev→main 合入触发,dev 日常提交零消耗

* docs: 新增开发规范——分支模型/提交纪律/发版仪式/工作流触发矩阵固化成文;CONTRIBUTING 对齐实际提交类型并挂规范入口

* fix: 更新检查分支感知——本地在什么分支就对比该分支的上游(main 用户看 main,dev 开发者看 dev);「上游最新」标签随实际上游渲染

* ui: 「上游最新」行渲染实际上游 ref——不再写死分支名(dev/main 通吃)

* fix: add_message_full 过程数据按 id 原位替换回 jsonl——此前 put 写独立文档,思维链/工具轨迹刷新即失

* feat: 单体直接工具循环——chat_execute(系统提示+历史+工具面自主决策)+ run_round 单体分支 + execute_named 过程轨迹补录

* test: 单体直接循环冒烟(工具回灌/轨迹留痕/无任务图)+ 上下文压缩用例改组模式承载;修复 dev 存量测试编译债(link 字段/ExmConfig::default)

* chore: 版本推进 0.1.1——单体直接工具循环 + 编成模板 + 版本更新/一键更新

* ci: CI/发版流水线补装 libxdo——computer-use 栈(enigo/xcap)链接期缺库,cargo test 未跑先挂

* docs: 单体直接工具循环 4.5 部署实测勾选——真实模型两轮验证通过

* test: git_panel 干净断言过滤注册表播种目录——entities/skills 是测试环境噪声,不属于提交流程

* fix: 更新检查 rev-parse 加 --verify——上游 ref 不存在时保持空值走降级,而非把字面量当 sha 返回

* release: v0.1.1 (#12)

* ci: 工作流触发策略收敛——CI 仅 PR 触发,发版仅 dev→main 合入触发,dev 日常提交零消耗

* docs: 新增开发规范——分支模型/提交纪律/发版仪式/工作流触发矩阵固化成文;CONTRIBUTING 对齐实际提交类型并挂规范入口

* fix: 更新检查分支感知——本地在什么分支就对比该分支的上游(main 用户看 main,dev 开发者看 dev);「上游最新」标签随实际上游渲染

* ui: 「上游最新」行渲染实际上游 ref——不再写死分支名(dev/main 通吃)

* fix: add_message_full 过程数据按 id 原位替换回 jsonl——此前 put 写独立文档,思维链/工具轨迹刷新即失

* feat: 单体直接工具循环——chat_execute(系统提示+历史+工具面自主决策)+ run_round 单体分支 + execute_named 过程轨迹补录

* test: 单体直接循环冒烟(工具回灌/轨迹留痕/无任务图)+ 上下文压缩用例改组模式承载;修复 dev 存量测试编译债(link 字段/ExmConfig::default)

* chore: 版本推进 0.1.1——单体直接工具循环 + 编成模板 + 版本更新/一键更新

* ci: CI/发版流水线补装 libxdo——computer-use 栈(enigo/xcap)链接期缺库,cargo test 未跑先挂

* docs: 单体直接工具循环 4.5 部署实测勾选——真实模型两轮验证通过

* test: git_panel 干净断言过滤注册表播种目录——entities/skills 是测试环境噪声,不属于提交流程

* fix: 更新检查 rev-parse 加 --verify——上游 ref 不存在时保持空值走降级,而非把字面量当 sha 返回

---------

Co-authored-by: KurohaneKaoruko <kurohanekaoruko@gmail.com>

* Fix/cross platform release (#16)

* build: 跨平台编译修复——computer.rs 平台差异(enigo Send/Key::Insert 平台门控)+ 一键更新 Unix 门控;release 流水线支持分支手动触发(编译预验,发布仍钉死 main)

* build: 重生成 tauri icon.ico——原文件是改扩展名的 PNG,Windows 资源编译器与 macOS 图标解码均拒绝

---------

Co-authored-by: BlackStar-Agent <kurohoshi@126.com>

* build: 桌面端重写为 egui 纯原生应用(无 webview)——chat-first 主窗口 + 原生设置页 + 隐藏终端侧车 + Inno Setup/tar.gz/dmg 安装链 (#18)

* feat: B1 SQLite 存储底座——store.sqlite 主库(会话/消息/任务图/回流/账本/快照/审计)+ 自动迁移旧 FSDB 数据

- store_sqlite.rs: SQLite 实现(62 方法全量移植,WAL 单写者)
- 自动迁移: Store::open 检测旧 FSDB 数据一次性转换
- rusqlite bundled(零外部依赖,构建环境自带 C 编译器即可)
- 已知边界: 证据/事件/检查点/outbox 等低频集合本批次仍走 FsDb

* feat: B1 SQLite 存储底座——store.sqlite 主库 + 自动迁移 + rusqlite 依赖(bundled)

* build: 打包脚本路径改仓库根口径——移除 ../ 前缀(CI 上指向仓库外)

* ci: 发版 tag 自动追加后缀——同版本重发时自动递增(v0.1.1 → v0.1.1.1 → v0.1.1.2),不再跳过

* ci: 修正发版检查——TAG 引用 ver 步骤输出(非自身),补 exists 输出

* build: 打包脚本 default-soul.md 路径修正——entities 重构后移至 entities/ 下

* build: icon.ico 放桌面工程根目录——winresource 生成的 .rc 相对路径可找到

---------

Co-authored-by: KurohaneKaoruko <kurohanekaoruko@gmail.com>
Co-authored-by: BlackStar-Agent <blackstar-agent@users.noreply.github.com>
Co-authored-by: Kaoruko <101451942+KurohaneKaoruko@users.noreply.github.com>
* fix: 桌面端打包 icon 路径修正 + 打包脚本 entities/default-soul 路径改仓库根口径 + 发版 tag 自动追加后缀

* build: windows 打包 default-soul.md 路径修正——entities/ 下
* fix: 桌面端打包 icon 路径修正 + 打包脚本 entities/default-soul 路径改仓库根口径 + 发版 tag 自动追加后缀

* build: windows 打包 default-soul.md 路径修正——entities/ 下

* build: 桌面端回退为 tauri 壳——egui 原生方案搁置,tauri 构建稳定

* build: 桌面 Linux 补装 libxdo-dev——enigo 链接需要

* build: tauri icon 重新生成——标准 Tauri 图标集(修复 ICO 格式错误)
* fix: 桌面端打包 icon 路径修正 + 打包脚本 entities/default-soul 路径改仓库根口径 + 发版 tag 自动追加后缀

* build: windows 打包 default-soul.md 路径修正——entities/ 下

* build: 桌面端回退为 tauri 壳——egui 原生方案搁置,tauri 构建稳定

* build: 桌面 Linux 补装 libxdo-dev——enigo 链接需要

* build: tauri icon 重新生成——标准 Tauri 图标集(修复 ICO 格式错误)

* fix: 桌面端三连修——安装包图标 / 网关终端弹窗 / 窗口无法访问

- icon.ico 重建:原全部帧为 PNG 压缩(规范仅允许 256x256),Explorer/NSIS 经典
  LoadImage 通路解析失败致安装包与应用显示空白图标;重建为 16~128 BMP(DIB) +
  256 PNG 共 7 帧,同步覆盖遗留 desktop/icon.ico
- main.rs:Windows 拉起网关加 CREATE_NO_WINDOW(0x08000000)——网关为控制台子系统
  程序,GUI 进程无控制台可继承,系统为其新开终端窗口
- 窗口「无法访问」根因:webui-dist 从未随安装包捆绑,网关根路径 404。
  release.yml 桌面 job 将 webui/dist 打入 src-tauri/binaries/webui-dist(随
  resources 进包),壳启动网关时经 EXM_WEBUI_DIST 指向之,同端口托管 WebUI

* release: v0.1.1——桌面端三连修(安装包图标/终端弹窗/窗口无法访问) 后的候选版
* fix: 桌面端打包 icon 路径修正 + 打包脚本 entities/default-soul 路径改仓库根口径 + 发版 tag 自动追加后缀

* build: windows 打包 default-soul.md 路径修正——entities/ 下

* build: 桌面端回退为 tauri 壳——egui 原生方案搁置,tauri 构建稳定

* build: 桌面 Linux 补装 libxdo-dev——enigo 链接需要

* build: tauri icon 重新生成——标准 Tauri 图标集(修复 ICO 格式错误)

* fix: 桌面端三连修——安装包图标 / 网关终端弹窗 / 窗口无法访问

- icon.ico 重建:原全部帧为 PNG 压缩(规范仅允许 256x256),Explorer/NSIS 经典
  LoadImage 通路解析失败致安装包与应用显示空白图标;重建为 16~128 BMP(DIB) +
  256 PNG 共 7 帧,同步覆盖遗留 desktop/icon.ico
- main.rs:Windows 拉起网关加 CREATE_NO_WINDOW(0x08000000)——网关为控制台子系统
  程序,GUI 进程无控制台可继承,系统为其新开终端窗口
- 窗口「无法访问」根因:webui-dist 从未随安装包捆绑,网关根路径 404。
  release.yml 桌面 job 将 webui/dist 打入 src-tauri/binaries/webui-dist(随
  resources 进包),壳启动网关时经 EXM_WEBUI_DIST 指向之,同端口托管 WebUI

* release: v0.1.1——桌面端三连修(安装包图标/终端弹窗/窗口无法访问) 后的候选版

* build: 发版产物附加版本号 + NSIS 安装器显式指定应用图标

- release.yml:server/desktop 两 job 上传前重命名产物,文件名附 tag
  (如 exmachina-desktop-windows-x64-setup-v0.1.1.exe),publish 扁平化
  后 Release 资产即带版本
- tauri.conf.json:bundle.windows.nsis 显式 installerIcon/uninstallerIcon——
  不设置时安装器用 NSIS 自带默认图标(地球+箭头),而非应用图标

* feat: 桌面端对话界面——主窗口改为对话优先形态,控制台收为浏览器次级入口

- desktop/ui:全新对话式 UI(无构建,经 frontendDist 嵌入壳二进制)——
  会话列表/新建/删除、流式回答(orchestrator.token rAF 合帧)、思维链与
  工具轨迹过程回看、审批内联裁决、欢迎屏引导、迷你安全 Markdown 渲染
  (先转义后生成,防死循环与 XSS)
- main.rs:主窗口改载内嵌 UI(WebviewUrl::App),网关地址/密钥经初始化
  脚本注入 window.__EXM_GATEWAY__;托盘与命令新增「打开控制台(浏览器)」
  (零新依赖,Windows 经 cmd start + CREATE_NO_WINDOW)
- tauri.conf.json:withGlobalTauri 开启(UI 调用 open_console 命令)
- WebUI 不再作为桌面主界面:控制台降为托盘/侧栏次级入口,网关仍同端口
  托管(浏览器/手机 PWA 同源客户端口径不变)
- E2E:EXM_LLM_MOCK 网关 + 真实浏览器验证——发话→流式→收束落位、
  会话切换/历史回载/侧栏预览、跨重载持久化全通过
- 版本 0.1.1 → 0.1.1

* feat: 桌面对话界面三栏化——项目会话分组 / 子个体执行面板 / 输入区上下文工具条

- 侧栏:会话按项目(组)分组,组头可折叠、当前组置顶
- 右栏(执行面板):任务派发图(指挥体→子个体节点卡,状态徽章实时
  更新:待派发/已派发/执行中/回流/完成…)、子个体实时输出流、回执
  列表(含置信度);运行中自动弹出,开关持久化
- 输入区底部工具条:+附件(图片 data URL 多模态,缩略图可删)+
  工作目录(组 workspace)/ 智能体·智能体组切换(PUT /target,切后
  回到该上下文最新会话)/ 模型(档案·档案内模型,组模型或单体
  modelHint)/ 思考强度(自动=跟随规划 | direct=强制直答 | full=
  强制拆解派发,经 chat.mode 下发)
- E2E:mock 网关全链路——派发图 4 节点 done、回执 4 条、WS 事件
  (graph.updated/dispatch.sent/unit.token/sync.received)齐备,
  菜单切换/附件/多轮往返全通过

* feat: 模型思考强度 / 工作目录与目标解耦 / 子个体会话下钻 / 术语修正

- 思考强度改为真正的模型推理强度:ChatRequest.reasoning + 进程级
  set_reasoning_effort(请求级优先),按协议注入——OpenAI 兼容
  reasoning_effort / Anthropic thinking.budget_tokens(max_tokens 相应
  抬升)/ Gemini thinkingConfig;非法档位归一 medium;新路由
  GET/PUT /api/llm/effort;UI 芯片替换原编排模式(低/中/高/端点默认,
  本地记忆 + 启动重设),三协议注入有单测覆盖
- 工作目录与交互目标解耦:registry 新增 active_workspace(持久化,
  智能体与智能体组通用),effective_workspace 优先级 显式设置 > 组
  声明 > 全局根,tools.effective_root 统一委托;新路由 GET/PUT
  /api/workspace(目录须存在,空=清除回退);UI 工作目录芯片在两种
  模式下均可见可设(原来单体模式直接隐藏)
- 右栏子个体可点击下钻:个体会话视图(派发单契约:目标/验收/边界、
  实时输出/思维链、工具轨迹、回执),派发单经存储事件懒加载,返回
  总览一键切换
- 术语:『单体智能体』→『智能体』;智能体组不再括号『(项目)』——
  工作目录即项目,智能体同样可以写项目
- .gitignore 补 entities/active_workspace(运行时状态,同 agents/active_group 口径)
- 环境说明:smoke 浏览器沙箱用例在本机失败为 CDP 环境问题(干净树
  复现一致),与本次改动无关

* feat: 子代理会话(可与子个体单独对话)/ 工作空间选择器 / 模型芯片显示实际配置

- 后端 unit_direct_round:绕过编排与指定子个体直接对话——复用个体执行
  回路(chat_execute 工具循环与人格和派发执行完全一致),上下文携带
  最近派发单契约(目标/验收),历史窗口含指挥体收束(标注来源)与本
  个体既往回复;流式走 unit.token / unit.thinking 同通道,回复落库
  role=unit,新增 unit.finished 收尾事件;chat 接口 body.agent 路由
- 桌面 UI:右栏子个体卡点击 → 中栏切换为与指挥体同款的子代理会话
  (派发单契约卡 + 用户/该个体全部往来 + 实时输入态 + 底部输入直聊),
  顶栏「‹ @个体」返回主会话;unit.finished 即时收束实时态
- 工作空间选择器(图一口径):最近工作空间列表(本地记忆 5 个)+
  打开本地文件夹(tauri-plugin-dialog 原生目录选择)+ 不使用工作空间;
  芯片显示 📂 项目名
- 模型芯片显示实际生效模型(组/个体覆盖 > 生效档案默认模型,如
  GLM-5.3-Flash),菜单合并「模型 + 推理等级」两段式(图二口径)
- E2E:子代理直聊 API 链路验证通过(user + unit/architect-agent 落账,
  回复非空);浏览器 UI 断连,界面交互待人工过一眼

* fix: 消息去头像,发送者名字直达;派发单不再用叙述性口吻

- 全部消息块移除头像(主会话/子代理会话/实时区),仅保留「名字 · 时间」
- 子代理会话的派发单卡改为发送者署名(@组主智能体 id + 任务标题),
  不再显示「指挥体派发的任务」叙述文案
- 修复:实时区/右栏改 setTimeout 节流——窗口隐藏时 rAF 永不触发,
  面板与流式内容会冻住不刷新

* fix: 控制台打开失败可诊断 + 模型/推理菜单对齐图二三四 + 直角 UI 对齐 webui

- openConsole 空值陷阱修复:__TAURI__ 缺失时可选链求值 undefined,
  await 不抛错致 catch/回退永不执行(点按钮无任何反应的根因);
  显式判断 invoke 存在,失败回退 window.open,被拦截时 alert 给出地址
- Rust open_in_browser 返回 Result 并上抛:命令与托盘失败不再静默
- 模型菜单改图二交互:两行式入口(模型/推理等级,右侧当前值 + ›)
- 模型列表改图三:搜索框 + 按供应商(档案)分组纯模型行,✓ 标当前;
  无模型清单的档案回退单行默认
- 推理等级改图四:Default/Low/High/Max 纯列表(medium 显示为 High、
  high 显示为 Max),✓ 标当前,选中即下发网关
- UI 风格对齐 webui:全部圆角归零(直角);品牌区去掉渐变 LOGO 块,
  左上角只显示 EXMACHINA 文字

* fix: 欢迎屏去掉 LOGO 块——与品牌区口径一致,仅文字

* feat: 桌面端设置独立整页——原生管理面,彻底移除 webui 依赖

架构口径落地:exm-core 是功能核心,webui/tauri/channel 都是连结核心的
客户端。桌面端零 webui 依赖,管理能力全部原生:

- 设置改为独立整页(左导航 + 内容区,接管整个窗口),不再挤在对话流里;
  「‹ 返回对话」一键回主界面
- 五个分区直连环口 API(即 exm-core):
  · 模型——提供商档案 CRUD(端点/协议/Key/默认模型)、设为生效、测连通、
    拉取端点模型清单
  · 组与个体——组列表/新建/删除/工作目录、组内个体清单与设主
  · 通道——列表(运行状态)/启停/测试/删除/新增
  · 定时任务——列表/启停/立即执行/删除/新建
  · 安全——访问密钥/终端命令审批(off|risky|always)/前缀白名单/超时
- 移除:托盘「打开控制台(浏览器)」、open_console 命令、
  spawn 时 EXM_WEBUI_DIST 注入、release.yml 桌面 job 的 webui 构建
  与捆绑步骤——桌面端构建产物不再包含任何 webui 产物
- 服务器口径不变:服务端预编译包仍带 webui-dist(浏览器/PWA 客户端)

* release: v0.1.2——桌面端原生对话与管理面(零 webui 依赖)
* fix: 桌面端打包 icon 路径修正 + 打包脚本 entities/default-soul 路径改仓库根口径 + 发版 tag 自动追加后缀

* build: windows 打包 default-soul.md 路径修正——entities/ 下

* build: 桌面端回退为 tauri 壳——egui 原生方案搁置,tauri 构建稳定

* build: 桌面 Linux 补装 libxdo-dev——enigo 链接需要

* build: tauri icon 重新生成——标准 Tauri 图标集(修复 ICO 格式错误)

* fix: 桌面端三连修——安装包图标 / 网关终端弹窗 / 窗口无法访问

- icon.ico 重建:原全部帧为 PNG 压缩(规范仅允许 256x256),Explorer/NSIS 经典
  LoadImage 通路解析失败致安装包与应用显示空白图标;重建为 16~128 BMP(DIB) +
  256 PNG 共 7 帧,同步覆盖遗留 desktop/icon.ico
- main.rs:Windows 拉起网关加 CREATE_NO_WINDOW(0x08000000)——网关为控制台子系统
  程序,GUI 进程无控制台可继承,系统为其新开终端窗口
- 窗口「无法访问」根因:webui-dist 从未随安装包捆绑,网关根路径 404。
  release.yml 桌面 job 将 webui/dist 打入 src-tauri/binaries/webui-dist(随
  resources 进包),壳启动网关时经 EXM_WEBUI_DIST 指向之,同端口托管 WebUI

* release: v0.1.1——桌面端三连修(安装包图标/终端弹窗/窗口无法访问) 后的候选版

* build: 发版产物附加版本号 + NSIS 安装器显式指定应用图标

- release.yml:server/desktop 两 job 上传前重命名产物,文件名附 tag
  (如 exmachina-desktop-windows-x64-setup-v0.1.1.exe),publish 扁平化
  后 Release 资产即带版本
- tauri.conf.json:bundle.windows.nsis 显式 installerIcon/uninstallerIcon——
  不设置时安装器用 NSIS 自带默认图标(地球+箭头),而非应用图标

* feat: 桌面端对话界面——主窗口改为对话优先形态,控制台收为浏览器次级入口

- desktop/ui:全新对话式 UI(无构建,经 frontendDist 嵌入壳二进制)——
  会话列表/新建/删除、流式回答(orchestrator.token rAF 合帧)、思维链与
  工具轨迹过程回看、审批内联裁决、欢迎屏引导、迷你安全 Markdown 渲染
  (先转义后生成,防死循环与 XSS)
- main.rs:主窗口改载内嵌 UI(WebviewUrl::App),网关地址/密钥经初始化
  脚本注入 window.__EXM_GATEWAY__;托盘与命令新增「打开控制台(浏览器)」
  (零新依赖,Windows 经 cmd start + CREATE_NO_WINDOW)
- tauri.conf.json:withGlobalTauri 开启(UI 调用 open_console 命令)
- WebUI 不再作为桌面主界面:控制台降为托盘/侧栏次级入口,网关仍同端口
  托管(浏览器/手机 PWA 同源客户端口径不变)
- E2E:EXM_LLM_MOCK 网关 + 真实浏览器验证——发话→流式→收束落位、
  会话切换/历史回载/侧栏预览、跨重载持久化全通过
- 版本 0.1.1 → 0.1.1

* feat: 桌面对话界面三栏化——项目会话分组 / 子个体执行面板 / 输入区上下文工具条

- 侧栏:会话按项目(组)分组,组头可折叠、当前组置顶
- 右栏(执行面板):任务派发图(指挥体→子个体节点卡,状态徽章实时
  更新:待派发/已派发/执行中/回流/完成…)、子个体实时输出流、回执
  列表(含置信度);运行中自动弹出,开关持久化
- 输入区底部工具条:+附件(图片 data URL 多模态,缩略图可删)+
  工作目录(组 workspace)/ 智能体·智能体组切换(PUT /target,切后
  回到该上下文最新会话)/ 模型(档案·档案内模型,组模型或单体
  modelHint)/ 思考强度(自动=跟随规划 | direct=强制直答 | full=
  强制拆解派发,经 chat.mode 下发)
- E2E:mock 网关全链路——派发图 4 节点 done、回执 4 条、WS 事件
  (graph.updated/dispatch.sent/unit.token/sync.received)齐备,
  菜单切换/附件/多轮往返全通过

* feat: 模型思考强度 / 工作目录与目标解耦 / 子个体会话下钻 / 术语修正

- 思考强度改为真正的模型推理强度:ChatRequest.reasoning + 进程级
  set_reasoning_effort(请求级优先),按协议注入——OpenAI 兼容
  reasoning_effort / Anthropic thinking.budget_tokens(max_tokens 相应
  抬升)/ Gemini thinkingConfig;非法档位归一 medium;新路由
  GET/PUT /api/llm/effort;UI 芯片替换原编排模式(低/中/高/端点默认,
  本地记忆 + 启动重设),三协议注入有单测覆盖
- 工作目录与交互目标解耦:registry 新增 active_workspace(持久化,
  智能体与智能体组通用),effective_workspace 优先级 显式设置 > 组
  声明 > 全局根,tools.effective_root 统一委托;新路由 GET/PUT
  /api/workspace(目录须存在,空=清除回退);UI 工作目录芯片在两种
  模式下均可见可设(原来单体模式直接隐藏)
- 右栏子个体可点击下钻:个体会话视图(派发单契约:目标/验收/边界、
  实时输出/思维链、工具轨迹、回执),派发单经存储事件懒加载,返回
  总览一键切换
- 术语:『单体智能体』→『智能体』;智能体组不再括号『(项目)』——
  工作目录即项目,智能体同样可以写项目
- .gitignore 补 entities/active_workspace(运行时状态,同 agents/active_group 口径)
- 环境说明:smoke 浏览器沙箱用例在本机失败为 CDP 环境问题(干净树
  复现一致),与本次改动无关

* feat: 子代理会话(可与子个体单独对话)/ 工作空间选择器 / 模型芯片显示实际配置

- 后端 unit_direct_round:绕过编排与指定子个体直接对话——复用个体执行
  回路(chat_execute 工具循环与人格和派发执行完全一致),上下文携带
  最近派发单契约(目标/验收),历史窗口含指挥体收束(标注来源)与本
  个体既往回复;流式走 unit.token / unit.thinking 同通道,回复落库
  role=unit,新增 unit.finished 收尾事件;chat 接口 body.agent 路由
- 桌面 UI:右栏子个体卡点击 → 中栏切换为与指挥体同款的子代理会话
  (派发单契约卡 + 用户/该个体全部往来 + 实时输入态 + 底部输入直聊),
  顶栏「‹ @个体」返回主会话;unit.finished 即时收束实时态
- 工作空间选择器(图一口径):最近工作空间列表(本地记忆 5 个)+
  打开本地文件夹(tauri-plugin-dialog 原生目录选择)+ 不使用工作空间;
  芯片显示 📂 项目名
- 模型芯片显示实际生效模型(组/个体覆盖 > 生效档案默认模型,如
  GLM-5.3-Flash),菜单合并「模型 + 推理等级」两段式(图二口径)
- E2E:子代理直聊 API 链路验证通过(user + unit/architect-agent 落账,
  回复非空);浏览器 UI 断连,界面交互待人工过一眼

* fix: 消息去头像,发送者名字直达;派发单不再用叙述性口吻

- 全部消息块移除头像(主会话/子代理会话/实时区),仅保留「名字 · 时间」
- 子代理会话的派发单卡改为发送者署名(@组主智能体 id + 任务标题),
  不再显示「指挥体派发的任务」叙述文案
- 修复:实时区/右栏改 setTimeout 节流——窗口隐藏时 rAF 永不触发,
  面板与流式内容会冻住不刷新

* fix: 控制台打开失败可诊断 + 模型/推理菜单对齐图二三四 + 直角 UI 对齐 webui

- openConsole 空值陷阱修复:__TAURI__ 缺失时可选链求值 undefined,
  await 不抛错致 catch/回退永不执行(点按钮无任何反应的根因);
  显式判断 invoke 存在,失败回退 window.open,被拦截时 alert 给出地址
- Rust open_in_browser 返回 Result 并上抛:命令与托盘失败不再静默
- 模型菜单改图二交互:两行式入口(模型/推理等级,右侧当前值 + ›)
- 模型列表改图三:搜索框 + 按供应商(档案)分组纯模型行,✓ 标当前;
  无模型清单的档案回退单行默认
- 推理等级改图四:Default/Low/High/Max 纯列表(medium 显示为 High、
  high 显示为 Max),✓ 标当前,选中即下发网关
- UI 风格对齐 webui:全部圆角归零(直角);品牌区去掉渐变 LOGO 块,
  左上角只显示 EXMACHINA 文字

* fix: 欢迎屏去掉 LOGO 块——与品牌区口径一致,仅文字

* feat: 桌面端设置独立整页——原生管理面,彻底移除 webui 依赖

架构口径落地:exm-core 是功能核心,webui/tauri/channel 都是连结核心的
客户端。桌面端零 webui 依赖,管理能力全部原生:

- 设置改为独立整页(左导航 + 内容区,接管整个窗口),不再挤在对话流里;
  「‹ 返回对话」一键回主界面
- 五个分区直连环口 API(即 exm-core):
  · 模型——提供商档案 CRUD(端点/协议/Key/默认模型)、设为生效、测连通、
    拉取端点模型清单
  · 组与个体——组列表/新建/删除/工作目录、组内个体清单与设主
  · 通道——列表(运行状态)/启停/测试/删除/新增
  · 定时任务——列表/启停/立即执行/删除/新建
  · 安全——访问密钥/终端命令审批(off|risky|always)/前缀白名单/超时
- 移除:托盘「打开控制台(浏览器)」、open_console 命令、
  spawn 时 EXM_WEBUI_DIST 注入、release.yml 桌面 job 的 webui 构建
  与捆绑步骤——桌面端构建产物不再包含任何 webui 产物
- 服务器口径不变:服务端预编译包仍带 webui-dist(浏览器/PWA 客户端)

* release: v0.1.2——桌面端原生对话与管理面(零 webui 依赖)

* fix: 发布流水线移除复活的 webui 捆绑步骤——桌面 job 不再依赖 webui/dist

c8b9a23 合并 main(#33 squash) 时,dev 侧在 1e31141 删除的「捆绑 WebUI
产物」步骤与 main 侧同位置新增的步骤净 diff 相互抵消,自动合并取了
main 侧——步骤复活,而桌面 job 的 Build WebUI 已删,webui/dist 不存在,
三平台桌面构建全部在捆绑步骤失败,连带 publish 跳过(未打 tag,发版
可干净重跑)。

教训落袋:合并 main 后必须复查关键文件语义(尤其『我删过的东西是否被
复活』),不能只看冲突文件。
* fix: 桌面端打包 icon 路径修正 + 打包脚本 entities/default-soul 路径改仓库根口径 + 发版 tag 自动追加后缀

* build: windows 打包 default-soul.md 路径修正——entities/ 下

* build: 桌面端回退为 tauri 壳——egui 原生方案搁置,tauri 构建稳定

* build: 桌面 Linux 补装 libxdo-dev——enigo 链接需要

* build: tauri icon 重新生成——标准 Tauri 图标集(修复 ICO 格式错误)

* fix: 桌面端三连修——安装包图标 / 网关终端弹窗 / 窗口无法访问

- icon.ico 重建:原全部帧为 PNG 压缩(规范仅允许 256x256),Explorer/NSIS 经典
  LoadImage 通路解析失败致安装包与应用显示空白图标;重建为 16~128 BMP(DIB) +
  256 PNG 共 7 帧,同步覆盖遗留 desktop/icon.ico
- main.rs:Windows 拉起网关加 CREATE_NO_WINDOW(0x08000000)——网关为控制台子系统
  程序,GUI 进程无控制台可继承,系统为其新开终端窗口
- 窗口「无法访问」根因:webui-dist 从未随安装包捆绑,网关根路径 404。
  release.yml 桌面 job 将 webui/dist 打入 src-tauri/binaries/webui-dist(随
  resources 进包),壳启动网关时经 EXM_WEBUI_DIST 指向之,同端口托管 WebUI

* release: v0.1.1——桌面端三连修(安装包图标/终端弹窗/窗口无法访问) 后的候选版

* build: 发版产物附加版本号 + NSIS 安装器显式指定应用图标

- release.yml:server/desktop 两 job 上传前重命名产物,文件名附 tag
  (如 exmachina-desktop-windows-x64-setup-v0.1.1.exe),publish 扁平化
  后 Release 资产即带版本
- tauri.conf.json:bundle.windows.nsis 显式 installerIcon/uninstallerIcon——
  不设置时安装器用 NSIS 自带默认图标(地球+箭头),而非应用图标

* feat: 桌面端对话界面——主窗口改为对话优先形态,控制台收为浏览器次级入口

- desktop/ui:全新对话式 UI(无构建,经 frontendDist 嵌入壳二进制)——
  会话列表/新建/删除、流式回答(orchestrator.token rAF 合帧)、思维链与
  工具轨迹过程回看、审批内联裁决、欢迎屏引导、迷你安全 Markdown 渲染
  (先转义后生成,防死循环与 XSS)
- main.rs:主窗口改载内嵌 UI(WebviewUrl::App),网关地址/密钥经初始化
  脚本注入 window.__EXM_GATEWAY__;托盘与命令新增「打开控制台(浏览器)」
  (零新依赖,Windows 经 cmd start + CREATE_NO_WINDOW)
- tauri.conf.json:withGlobalTauri 开启(UI 调用 open_console 命令)
- WebUI 不再作为桌面主界面:控制台降为托盘/侧栏次级入口,网关仍同端口
  托管(浏览器/手机 PWA 同源客户端口径不变)
- E2E:EXM_LLM_MOCK 网关 + 真实浏览器验证——发话→流式→收束落位、
  会话切换/历史回载/侧栏预览、跨重载持久化全通过
- 版本 0.1.1 → 0.1.1

* feat: 桌面对话界面三栏化——项目会话分组 / 子个体执行面板 / 输入区上下文工具条

- 侧栏:会话按项目(组)分组,组头可折叠、当前组置顶
- 右栏(执行面板):任务派发图(指挥体→子个体节点卡,状态徽章实时
  更新:待派发/已派发/执行中/回流/完成…)、子个体实时输出流、回执
  列表(含置信度);运行中自动弹出,开关持久化
- 输入区底部工具条:+附件(图片 data URL 多模态,缩略图可删)+
  工作目录(组 workspace)/ 智能体·智能体组切换(PUT /target,切后
  回到该上下文最新会话)/ 模型(档案·档案内模型,组模型或单体
  modelHint)/ 思考强度(自动=跟随规划 | direct=强制直答 | full=
  强制拆解派发,经 chat.mode 下发)
- E2E:mock 网关全链路——派发图 4 节点 done、回执 4 条、WS 事件
  (graph.updated/dispatch.sent/unit.token/sync.received)齐备,
  菜单切换/附件/多轮往返全通过

* feat: 模型思考强度 / 工作目录与目标解耦 / 子个体会话下钻 / 术语修正

- 思考强度改为真正的模型推理强度:ChatRequest.reasoning + 进程级
  set_reasoning_effort(请求级优先),按协议注入——OpenAI 兼容
  reasoning_effort / Anthropic thinking.budget_tokens(max_tokens 相应
  抬升)/ Gemini thinkingConfig;非法档位归一 medium;新路由
  GET/PUT /api/llm/effort;UI 芯片替换原编排模式(低/中/高/端点默认,
  本地记忆 + 启动重设),三协议注入有单测覆盖
- 工作目录与交互目标解耦:registry 新增 active_workspace(持久化,
  智能体与智能体组通用),effective_workspace 优先级 显式设置 > 组
  声明 > 全局根,tools.effective_root 统一委托;新路由 GET/PUT
  /api/workspace(目录须存在,空=清除回退);UI 工作目录芯片在两种
  模式下均可见可设(原来单体模式直接隐藏)
- 右栏子个体可点击下钻:个体会话视图(派发单契约:目标/验收/边界、
  实时输出/思维链、工具轨迹、回执),派发单经存储事件懒加载,返回
  总览一键切换
- 术语:『单体智能体』→『智能体』;智能体组不再括号『(项目)』——
  工作目录即项目,智能体同样可以写项目
- .gitignore 补 entities/active_workspace(运行时状态,同 agents/active_group 口径)
- 环境说明:smoke 浏览器沙箱用例在本机失败为 CDP 环境问题(干净树
  复现一致),与本次改动无关

* feat: 子代理会话(可与子个体单独对话)/ 工作空间选择器 / 模型芯片显示实际配置

- 后端 unit_direct_round:绕过编排与指定子个体直接对话——复用个体执行
  回路(chat_execute 工具循环与人格和派发执行完全一致),上下文携带
  最近派发单契约(目标/验收),历史窗口含指挥体收束(标注来源)与本
  个体既往回复;流式走 unit.token / unit.thinking 同通道,回复落库
  role=unit,新增 unit.finished 收尾事件;chat 接口 body.agent 路由
- 桌面 UI:右栏子个体卡点击 → 中栏切换为与指挥体同款的子代理会话
  (派发单契约卡 + 用户/该个体全部往来 + 实时输入态 + 底部输入直聊),
  顶栏「‹ @个体」返回主会话;unit.finished 即时收束实时态
- 工作空间选择器(图一口径):最近工作空间列表(本地记忆 5 个)+
  打开本地文件夹(tauri-plugin-dialog 原生目录选择)+ 不使用工作空间;
  芯片显示 📂 项目名
- 模型芯片显示实际生效模型(组/个体覆盖 > 生效档案默认模型,如
  GLM-5.3-Flash),菜单合并「模型 + 推理等级」两段式(图二口径)
- E2E:子代理直聊 API 链路验证通过(user + unit/architect-agent 落账,
  回复非空);浏览器 UI 断连,界面交互待人工过一眼

* fix: 消息去头像,发送者名字直达;派发单不再用叙述性口吻

- 全部消息块移除头像(主会话/子代理会话/实时区),仅保留「名字 · 时间」
- 子代理会话的派发单卡改为发送者署名(@组主智能体 id + 任务标题),
  不再显示「指挥体派发的任务」叙述文案
- 修复:实时区/右栏改 setTimeout 节流——窗口隐藏时 rAF 永不触发,
  面板与流式内容会冻住不刷新

* fix: 控制台打开失败可诊断 + 模型/推理菜单对齐图二三四 + 直角 UI 对齐 webui

- openConsole 空值陷阱修复:__TAURI__ 缺失时可选链求值 undefined,
  await 不抛错致 catch/回退永不执行(点按钮无任何反应的根因);
  显式判断 invoke 存在,失败回退 window.open,被拦截时 alert 给出地址
- Rust open_in_browser 返回 Result 并上抛:命令与托盘失败不再静默
- 模型菜单改图二交互:两行式入口(模型/推理等级,右侧当前值 + ›)
- 模型列表改图三:搜索框 + 按供应商(档案)分组纯模型行,✓ 标当前;
  无模型清单的档案回退单行默认
- 推理等级改图四:Default/Low/High/Max 纯列表(medium 显示为 High、
  high 显示为 Max),✓ 标当前,选中即下发网关
- UI 风格对齐 webui:全部圆角归零(直角);品牌区去掉渐变 LOGO 块,
  左上角只显示 EXMACHINA 文字

* fix: 欢迎屏去掉 LOGO 块——与品牌区口径一致,仅文字

* feat: 桌面端设置独立整页——原生管理面,彻底移除 webui 依赖

架构口径落地:exm-core 是功能核心,webui/tauri/channel 都是连结核心的
客户端。桌面端零 webui 依赖,管理能力全部原生:

- 设置改为独立整页(左导航 + 内容区,接管整个窗口),不再挤在对话流里;
  「‹ 返回对话」一键回主界面
- 五个分区直连环口 API(即 exm-core):
  · 模型——提供商档案 CRUD(端点/协议/Key/默认模型)、设为生效、测连通、
    拉取端点模型清单
  · 组与个体——组列表/新建/删除/工作目录、组内个体清单与设主
  · 通道——列表(运行状态)/启停/测试/删除/新增
  · 定时任务——列表/启停/立即执行/删除/新建
  · 安全——访问密钥/终端命令审批(off|risky|always)/前缀白名单/超时
- 移除:托盘「打开控制台(浏览器)」、open_console 命令、
  spawn 时 EXM_WEBUI_DIST 注入、release.yml 桌面 job 的 webui 构建
  与捆绑步骤——桌面端构建产物不再包含任何 webui 产物
- 服务器口径不变:服务端预编译包仍带 webui-dist(浏览器/PWA 客户端)

* release: v0.1.2——桌面端原生对话与管理面(零 webui 依赖)

* fix: 发布流水线移除复活的 webui 捆绑步骤——桌面 job 不再依赖 webui/dist

c8b9a23 合并 main(#33 squash) 时,dev 侧在 1e31141 删除的「捆绑 WebUI
产物」步骤与 main 侧同位置新增的步骤净 diff 相互抵消,自动合并取了
main 侧——步骤复活,而桌面 job 的 Build WebUI 已删,webui/dist 不存在,
三平台桌面构建全部在捆绑步骤失败,连带 publish 跳过(未打 tag,发版
可干净重跑)。

教训落袋:合并 main 后必须复查关键文件语义(尤其『我删过的东西是否被
复活』),不能只看冲突文件。

* feat: 自绘标题栏 / 极简黑白 ICON / 工作区隔离安装目录 / 浮窗消失修复 / 设置表单补齐

- 浮窗消失修复:popItem/popRow 统一 stopPropagation——子菜单切换会重建
  浮窗内容,原 target 脱离容器后冒泡到 document 关闭监听被误判「点在外
  面」直接关浮窗
- 默认工作区隔离安装目录:网关支持 EXM_WORKSPACE_ROOT(覆盖工作区根,
  终端/文件工具/检查点/资产全部以此为根);桌面壳默认指向用户数据目录
  下 workspace/ 并以之为网关 CWD——agent 默认搞不坏应用自身
- 自绘标题栏:decorations(false) + 固定顶栏(品牌字 + 拖拽区 + 最小化/
  最大化/关闭,控制走自有命令零 ACL 依赖);关闭仍走 CloseRequested
  (默认驻留托盘);浏览器调试自动隐藏按钮
- 极简黑白 ICON 重制:黑底白色几何 EX 单字标(纯矩形/斜线绘制,无字体
  依赖),ico(BMP 小帧+PNG 256)/icns/全尺寸 png/Android(方/圆/前景)/iOS
  全套再生成
- 设置表单补齐:模型清单拉取后入库档案(模型选择器可选真实模型)、
  通道按平台动态字段(qqbot appId/appSecret、napcat url/token)、
  定时任务单次时间、组创建带描述

* feat: 设置页对齐 webui 全量功能——记忆/技能/审计/schema 配置 + 个体与人格管理

- 组与个体:组内个体行式管理(设主/人格 SOUL 编辑/系统提示词编辑/移除/
  新增);单体智能体区(新建/删除/设为对话目标/人格/提示词)
- 记忆:统计、检索、条目列表(置顶/删除)、新增
- 技能:列表/创建(触发词 + 指令)/删除
- 审计:最近 50 条工具调用(个体/工具/耗时/摘要)
- 配置:config schema 驱动(16 分组全量覆盖——安全/自动化/沙箱/
  Computer Use/搜索/记忆参数/钩子/限流等),子导航 + 按组保存,
  嵌套字段 PUT 口径与 webui 一致
- 原「安全」独立页被 schema 配置页覆盖,移除

* feat: 智能体组与智能体拆分为独立设置页,功能对齐 webui

- 智能体组 tab:overview 统计(个体/编成/会话/记忆)、成员行式管理
  (设主/人格/提示词/移除)、添加个体可选编成模板、组设置卡(组模型
  + 能力槽位四项,PUT model+capabilities)、新建组可选编成模板;
  内置组编成受保护——隐藏添加表单并提示(对齐服务端契约)
- 智能体 tab(单体,对齐 SinglesView):档案卡(模型解析显示/描述)、
  设为对话目标、切换模型(modelHint)、编辑描述、人格、提示词、删除、
  新建(名称/标识/负责域/描述)
- 修:renderSetSingles 漏写 body.appendChild(list) 致列表卡不渲染

* feat: exm config 升级 schema 驱动——63 键全量读写对齐 WebUI

- get/set 从 9 键硬编码升级为 config_schema() 驱动的全键覆盖(16 组
  63 键):安全/自动化/沙箱/Computer Use/搜索/浏览器/钩子/身份/限流/
  触发器/MCP/通知/记忆参数/运行时全可读写
- 值类型按 schema kind 归一(boolean/number/string),非法布尔/未知键
  明确报错;password 类读取打码(与 WebUI 掩码口径一致)
- llm.* 双写语义:顶层种子值与生效档案同步更新(对齐 load 的档案优先
  口径,否则写入被档案覆盖失效)
- 写入后检测运行中网关(安装清单端口)并提示:需重启生效,即时生效
  请用 WebUI / 桌面端设置页(PUT /config)
- tools.custom 为结构化契约,CLI 拒改并引导至配置页

* chore: 清理已完成变更 spec(4 组全部任务完成,历史可溯)

* feat(WIP): 桌面端编码页/任务视图/审批与会话增强 + WebUI 配置 i18n 补齐

- 桌面端(子代理完成):编码页(文件树/编辑器/变更 diff/Git 面板)、
  任务视图(任务图拓扑展示 + 台账分区渲染)、审批列表与角标轮询、
  会话重命名/分叉/撤销/归档、错误统一 toast、停止按钮状态机
- WebUI(子代理中断,人工收尾):SettingsView 扩展 FIELD_I18N 覆盖
  新增配置组(触发器/身份/限流/通知等),i18n 词典补 52 键(中英),
  tsc 零错误、vite build 通过

* fix(WIP): channel_util 通道小件抽取(内置命令 /new /status + 消息去重)+ telegram 收发修复

- 新增 channel_util.rs:内置命令识别与执行(/new 开新会话归档旧会话、
  /status 状态回显)、按平台消息 id 去重(断线重放/双事件)
- telegram:媒体占位正文(纯图/纯文件不再被丢弃)、caption 支持、
  inbound_text/has_media 辅助函数;修复中断重构留下的括号失衡

* feat(webui): 通道 config 扩展字段 + 定时任务结果推送订阅

- ChannelsView:新增「config 扩展字段(JSON)」折叠面板——平台目录外
  的 config 键可填(编辑时 pretty-JSON 预填,保存前强校验合法性与
  标量键值,目录字段优先防同名键复活);config 空值键不再提交
- AutomationsView:定时任务新增 notifyChannels 多选(结果推送订阅,
  选项来自通道清单,表格回显已订阅)
- i18n:zh/en 各补 8 键(channels.advConfig 等)

* feat(desktop): 编码页编辑器增强 / SVG DAG 任务图 / 变更批量操作 / 审批角标事件驱动

- 编辑器:行号列滚动同步、当前行高亮、Tab/Shift+Tab 缩进(保留原生
  undo 栈 + 降级路径)、切文件/切视图/换工作区未保存拦截
- 任务图升级 SVG 连线 DAG:依赖深度分层布局 + 状态色贝塞尔连线
  (悬停显示 A → B),点击节点直聊子代理保留
- 变更面板:单文件 +n/−n 统计与合计、暂存全部/全部丢弃(discard 走
  审批闸门)、按状态分组计数
- 审批角标事件驱动:approval.required/resolved 即时刷新(序号守卫防
  乱序回写)+ 重连补偿校准,60s 轮询降为兜底
- 细节:会话当前项渐变高亮/运行中转圈、文件树字形图标与状态色点、
  mkBtn 统一 loading 态

* feat(core): Agent 循环与工具面强化(子代理交付,人工收尾)

- provider:SSE 字节流行解码器——网络 chunk 边界落在多字节 UTF-8 字符
  中间时不再产生 U+FFFD 乱码(按字节攒、完整行才解码)
- tools:命令超时路径读出终止前的部分输出(增量读者写共享缓冲,残留
  孙进程占管道也不黑箱);修 MutexGuard 临时值生命周期编译错
- orchestrator:收束降级路径——收束 LLM 不可用时不再把整轮判死,
  各节点已回流成果(状态/摘要/阻塞项)确定性聚合成可执行结论,
  失败原因显式注入残余未知段,带降级聚合单测
- runtime:派发时限(timeout_ms = 步数 × 30s)——挂死的 LLM 流不再
  无限期占住编排并发槽;deadline 内有界收增量、到点 abort 流任务
- 测试:lib 65 全绿(新增收束降级/时限相关用例)

* feat(channel): 五平台适配器对齐 telegram 完成度(子代理交付)

- 断线重连指数退避(3→6→12…封顶 300s,成功即复位)——凭证失效时
  不再每 3 秒敲一次网关
- 消息去重:断线 Resume 重放/双事件按平台消息 id 首见放行(重放期间
  不重复下载附件、不重复执行对话轮)
- 纯媒体消息占位正文兜底(官方平台发图常无 caption,曾直接丢弃)
- 内置命令 /new /status 接入五平台(闸门放行后拦截,未绑定用户已被
  闸门挡住);channel_util 共用小件扩展

* feat(core): 记忆系统与工具执行面强化(78 测试全绿,+13)

记忆系统:
- 空查询越权泄漏修复——回退近期召回补分层/组/scope 三维过滤
- 衰减数学收敛为纯函数:未来时间戳不反向增寿、非法半衰期回落默认、
  结果收进 [floor, 1.0];配置层 sanitize 半衰期非法值
- MemoryStore 写串行锁:并发 remember 去重不裂条、提升不丢增量、
  与 forget 交错不留孤儿哈希(16 线程并发单测)
- 条目标题/正文长度上限(200/8000 字符,不劈 UTF-8),哈希对落库
  内容计算保证截断后去重一致
- 文件记忆模式(memory.enabled=false)行为补齐:memory_read 回落读
  memory.md(与规划注入同源)、write/link 拒绝并给可行动引导、
  schema 不再下发必然失败的工具定义

工具执行面:
- 失败命令 error 字段自包含可诊断:退出码 + stdout 尾部 + stderr
  (此前模型只看到「执行失败:」空原因,审计/审批单同样空串)
- 三处输出截断追加显式标记(阈值与总数声明,契约不变)
- read 工具 maxChars 钳 [1, 100000]、offset 越界返回可行动提示

* feat(desktop): 编码页只读态/未保存行标记/审批跳转/DAG 缩放/关窗兜底

- 编辑器只读态:truncated/非 UTF-8 文件 readOnly + 只读提示条
  (Tab 放行默认行为、保存/Ctrl+S 双重拦截——防误改后白干)
- 未保存行边际标记:行号列青色方点(前/后缀裁剪连续区间,含纯删行
  退标接缝行兜底),保存成功基线翻新即清除;9 例边界单测
- 暂存全部后自动聚焦提交框;提交框 Enter 直接提交(组词不触发)
- 审批列表「跳转会话」:sessionId 精确直用、截断 id 前缀唯一匹配才跳,
  多/零命中置灰并说明
- 任务图 Ctrl+滚轮缩放(0.5~2 倍)+ 倍率读数 + 重置视图;graph.updated
  重渲染不丢倍率
- beforeunload 兜底:编码页 dirty 时关窗/刷新浏览器级留人

* perf(webui): 路由级懒加载 + vendor 分组——首屏入口 1597→121 kB(↓92%)

- App.tsx 15 视图静态 import → React.lazy + Suspense(Spin 兜底),
  首屏不再拉取 14 个非活跃视图代码
- manualChunks 函数式按包名分类:react 系 / antd 系 / markdown 系 /
  兜底 vendor——生态胶水包归对类消除循环 chunk(react-is→react 系、
  extend/dequal/style-to-*→markdown 系);仅 static 边零环(DFS 验证)
- chunkSizeWarningLimit 1500 并注明理由(antd 全量 957 kB 为固有)

* fix(channel): 五平台扫尾对齐——matrix 媒体标记真 bug 修复 + 媒体/语音/typing 补齐

- matrix:媒体标记行产出 5 段而消费方按 3 段解析——纯媒体消息从未
  下载、控制字符标记行原样进入模型上下文(真 bug,提取
  parse_media_marker 纯函数修复 + 镜像负例测试);caps 开位
  image/file/voice;补 typing 指示;语音转写
- discord:按住说话的 audio/ogg 归 voice + 转写
- napcat:语音段(record/voice,QQ 高频输入)下载转写注记
- slack:纯文件消息空正文石沉大海——先盘附件再定正文;音频归 voice
  + 转写
- qqbot:附件图片判定改扩展名整词(a.png.txt 不再误判,补
  gif/webp/bmp);官方被动消息仅文本的口径在 caps 注明
- channel_util:voice_transcript_note / classify_attachment 共用小件
- gateway 测试 68 全绿(新增媒体标记镜像负例/附件归类/图片判定)

* feat(channel): telegram 接入内置命令 /new /status + 文档口径对齐

- telegram:闸门 Allow 后拦截内置命令(与其他五适配器同口径),
  补齐基线自身的最后一块缺口
- 架构文档渠道清单补桌面端;README 桌面端/移动端口径更新
  (桌面端零 webui 依赖;WebUI 同端口托管属服务器部署形态)

* release: v0.1.3——exm-core 强化 + 桌面端原生对话与管理面 + Channel 六平台对齐
- icon.ico 的 256px PNG 帧转 RGBA(tauri 打包器 ico 严格解码要求,
  此前 RGB 帧致 macOS dmg 打包失败;Windows/Linux 路径宽容未暴露);
  icns 与全套 png 统一 RGBA
- browser.rs 导航轮询:单次 CDP 命令超时容忍重试(CI runner 偶发
  Runtime.evaluate 30s 超时致 smoke 浏览器用例抖动失败),连续两次
  无响应才判僵死
- v0.1.2 已正常发布(6 产物含版本号齐全);本 PR 合并即以修复后
  代码重跑 v0.1.3 发版,补齐 macOS dmg 后三平台桌面 + 服务端全量
- icon.ico 的 256px PNG 帧转 RGBA(tauri 打包器 ico 严格解码要求,
  此前 RGB 帧致 macOS dmg 打包失败;Windows/Linux 路径宽容未暴露);
  icns 与全套 png 统一 RGBA
- browser.rs 导航轮询:单次 CDP 命令超时容忍重试(CI runner 偶发
  Runtime.evaluate 30s 超时致 smoke 浏览器用例抖动失败),连续两次
  无响应才判僵死
- v0.1.2 已正常发布(6 产物含版本号齐全);本 PR 合并即以修复后
  代码重跑 v0.1.3 发版,补齐 macOS dmg 后三平台桌面 + 服务端全量
v0.1.3 发版 run 中 server-windows 在 rustup 解析 channel-rust-stable
清单时 TCP 超时(CDN 抖动,同 run 的 macos/linux server 均正常)。
server/desktop 两 job 在 dtolnay 工具链步骤前加 5 次重试预装
(已装则 dtolnay 步骤秒过);version/publish 不涉及
* release: v0.1.3 重跑——ICO PNG 帧 RGBA 化(macOS dmg 根因修复)+ 导航超时容忍

- icon.ico 的 256px PNG 帧转 RGBA(tauri 打包器 ico 严格解码要求,
  此前 RGB 帧致 macOS dmg 打包失败;Windows/Linux 路径宽容未暴露);
  icns 与全套 png 统一 RGBA
- browser.rs 导航轮询:单次 CDP 命令超时容忍重试(CI runner 偶发
  Runtime.evaluate 30s 超时致 smoke 浏览器用例抖动失败),连续两次
  无响应才判僵死
- v0.1.2 已正常发布(6 产物含版本号齐全);本 PR 合并即以修复后
  代码重跑 v0.1.3 发版,补齐 macOS dmg 后三平台桌面 + 服务端全量

* fix(release): 工具链安装加重试——server-windows 因 rustup CDN 抖动拉清单超时失败

v0.1.3 发版 run 中 server-windows 在 rustup 解析 channel-rust-stable
清单时 TCP 超时(CDN 抖动,同 run 的 macos/linux server 均正常)。
server/desktop 两 job 在 dtolnay 工具链步骤前加 5 次重试预装
(已装则 dtolnay 步骤秒过);version/publish 不涉及
- sfx 模块:AudioContext 懒初始化 + 手势 resume,localStorage exm.sfx
  静音开关(侧栏 🔊/🔇 切换),prefers-reduced-motion 用户缺省静音
- 六音合成(单一 tone 原语:波形+频率滑移+快衰减包络):click/send/
  success/error/notify/connect,主增益 0.12
- 接线:mkBtn/chip 统一包装、send、settingsSave 成败、alertErr、
  run.error、审批到达(跨会话也提醒)、sync.received、hideSplash——
  toast 本体不重复发声,hover 不发声,批量渲染天然静默
- 全部 try/catch 吞异常:音频不可用绝不干扰功能
- 色板重置:纯黑 #000 底 / 黑阶面板(#0a0a0a/#111) / 纯白文字(低透明
  做明度层级)/ 单一青色 #00e5ff 强调 + 语义纯色(绿/黄/红)
- 零渐变:accent 渐变、渐变字、渐变描边、group-dot 全部纯色化
- 零柔光:box-shadow/drop-shadow/blur 辉光全移除,弹层悬浮改 1px
  白色低透明边框分隔
- DAG 状态色 syncing 紫转青与 CSS 对齐;屏外杂色收编语义色
- 动效层完整保留(rise-in/msg-in/page-in/pop-in/stagger-in +
  prefers-reduced-motion 降级,重复块合并);四弧品牌纹样纯色线条版
- antd theme:colorBgBase #000 / colorText #fff / borderRadius 0 /
  colorPrimary 青 #00e5ff;全局 CSS 42 处 border-radius 归零
- 纯色 accent 语义化:青(主)/蓝(信息)/绿(成功)/红(危险)/黄(警示)
- 零渐变零辉光:text-shadow/drop-shadow/backdrop-filter 全清,
  分隔只靠 1px 线与明度差
- 动效保留:view-fade 视图切换、卡片 stagger、led/skeleton 脉冲、
  字节雨改 transform 位移
- LoginView 品牌重设计:四弧 Emblem 缓旋 + 等宽标题 + 直角面板;
  BrandEmpty 空态组件;prefers-reduced-motion 全局降级
- 仲裁说明:并行旧方案会话的结构资产(Emblem/BrandEmpty/hooks)
  保留,渐变/辉光实现清除;i18n 五个强调色名中英双份齐落
v0.1.3 重跑中 publish 因「tag already exists」失败(tag 已在远端而
本地新克隆不知道)——重跑发布属常见操作,tag 步骤必须幂等:
已存在 = 跳过创建/推送,Release 挂到既有 tag 即可
KurohaneKaoruko and others added 29 commits November 1, 2026 04:16
模型页:
- 功能分配改能力槽位卡:图标+名称+已指定/未配置徽标+选择器
  (原为四行表单字段平铺,观感单薄)
- 提供商卡:默认模型提为卡内主角行(大字 mono+使用中徽标),
  全局默认档案卡加强调色左边条+头部徽标

交互深度(HUD 语汇内的克制层):
- 卡片 hover 微浮起(1px 上移+阴影),表格行 hover 已有底色
- 表格行高补呼吸感(padding-block 11px)
- primary 按钮按压触感;输入控件聚焦轻光环(accent-soft)

时间展示:
- relativeTime/fullTime 提取 src/time.ts 共用(ChatView 原实现迁出)
- 通道表「账号」列裸 ISO 时间戳改相对时间+悬浮完整时间

验证:tsc 零错、生产构建通过;dev 实测槽位卡 4 组渲染、
激活档案左边条与主角行、通道表相对时间生效
- 用户消息:强调色左边条(滚动中与智能体输出一眼分流,
  对齐激活档案卡语汇)
- 消息头部:去底横线(横线让消息读成表格行);头像徽记化
  (20px 圆角块底,用户=强调色/智能体=面板底),用户名提亮
- 会话列表选中态:补 2px 强调色左指示条(对齐侧栏导航选中语汇)
- 日期分组标签(今天/昨天/更早):mono 大写宽字距(资产标签语汇,
  与 rail-label/表头同语言)

验证:tsc 零错、生产构建通过、dev 实测四处样式计算值全部生效
对话页左栏新增「聊天流」段(TARGET 与会话列表之间):
- 按通道分组:连接状态灯(复用通道状态)、账号名、平台短标
- 每条流:群/私聊图标(#/@)、显示名、最后消息预览、相对时间
- 当前打开会话所属流带强调色左边条 + 活跃呼吸点
- 点流直达绑定会话(消息接口按 id 直查,跨组也能打开)

后端补齐:webhook 测试端点(channel_inbound)迁移流模型
- 流绑定优先 + 旧 title 会话自动认领 + 新会话自动绑定
- 入站文本回写流预览(此前该端点未建流,列表恒空)

i18n 补 zh/en 2 键;流列表样式对齐 HUD 面板语汇

回归:clippy 零警、网关 127 测试全过、e2e 170/170;
生产实测入站消息建流成功(绑定会话+预览+时间正确)
方向 G(消毒管道,全部):
- sanitize 入站消毒:隐藏字符/角色伪装/劫持短语/工具结果伪装四规则,
  觱件可配置(security.sanitizeRules 单项可关),命中发审计事件+统计端点
- 外部内容隔离包装:fetch/RSS/视频描述等 7 入口统一来源标注+长度上限
- 配对码防爆破:pair 键失败计数+锁定窗口(复用 RateLimiter),锁定审计

线上缺陷修复:
- 逐行【报告】墙:text_to_statements 剥列表标记解析真实句式 tag,
  未标记行按段落聚合为单条(不再逐行各起一条)
- 群聊发送者统一成「用户」:六通道(napcat/telegram/qqbot/discord/
  slack/matrix)群聊拼 [来自 名字 (id)] 标注,私聊不加
- 带@消息 @ 被剥:napcat at 段/CQ 码转写 @<名字|qq> 内联(语义保留)
- 主人称呼统一「管理者」:orchestrator.md/组 SOUL/模板/registry 内置

轮次作用域重构(切换人设无效修复的正确形态):
- 旧实现轮次写全局激活态再还原,run.finished 事件先于还原到达时
  泄漏临时态(e2e 记忆隔离三连挂根因);并发跨组轮次互踩
- 重做为 task-local ROUND_SCOPE:归属只在本轮任务内生效,全局态
  零污染;registry 10 读口统一 effective_context();删除旧
  align_to_session_group/restore_context

自主性实验开关(experiments.*,默认全关):
- superAgent 深度委托:单智能体轮+组规划轮+收束轮注入工作法纪律
  (静默推进/按影响停/只问一个具体问题/诚实汇报/组模式并行拆解)
- autoAgent 自主行动:周期 Eval 门控(JSON 判定,解析失败保守拒绝)
  +风险闸门(删除/外部发送/消费配额跳过留人)+线性退避;
  配套 automation.autoAgent 三参数;cron_scheduler 接线
- llmDrivenMemory 自主记忆摘要 + slidingContextWindow 滑动窗口
  (与 dynamicCompaction 互斥)

基建:
- scripts/verify-batch.sh 批次验收(clippy/测试/e2e/tsc/构建五步)
- docs/审计/ 三路子代理审计报告 + 日志归类
- 4.4 会话导出 / 4.5 管理页空态

验证:workspace 测试全绿(exm-core 236+23、gateway 140)、
e2e 183/183、verify-batch 5/5(691s)
.cfg-nav 的 max-height 补偿值 168px 与实测几何不符(页头 54 +
上边距 8 = 62px),短内容分类(如版本更新)下导航被压在 706px,
面板 794px,底部恒空 ~86px(视觉断口)。

- 补偿改为 70px(几何实测:62 + 8 呼吸),并补 align-self: stretch
  显式声明等高意图
- 实测验证(1440x900):短分类 navH=panelH=794 gap=0;
  长分类面板 1187 时导航封顶 806 贴视口,页面正常滚动不拉空壳
- 来源标记约定:user 消息 agent_id 承载前缀语义——auto:xxx 系统自动内容、
  im:名字(id) 群聊发送者、无标记 = 真人输入;正文保持纯净
- channel_util:sender_prefix_if_group(拼正文)改为 sender_origin(产 im: 标记),
  私聊返回 None(双方固定,标注是噪音)
- 六适配器(napcat/telegram/qqbot/discord/slack/matrix):删正文前缀拼接,
  前置计算 sender_mark 经 with_origin 落库进消息 agent_id
- 模型侧上下文:im: 标记渲染「[用户·名字]」(compaction 两处);history
  user 消息行内署名「(名字 说)」;collect_pending_inputs 合并排队窗口
  多人输入时逐条署名(区分谁说了什么)
- WebUI:消息头解析 im: 前缀显示发送者名(替代「用户」)
- 文档:协议与契约补「消息来源标记」节
- 探活短路(IM 会话):在吗/你好/晚安/致谢/确认/链路测试词表命中时
  零 LLM 直答——不进规划流水线(全量注册表 + 记忆召回注入 + 规划调用
  就为回一句「在」,纯浪费);直答按语义分类(晚安不回「在」)
- 词表刻意保守:裸词 ≤10 字符、标点剥离精确匹配;带任务语义、超长、
  模糊碎片不命中,照常走完整轮次
- 短路点在 collect 之前:探活不并入排队窗口 goal 合并
- 规划纪律:输入无任务语义时必须 L0 澄清,禁止从会话历史捡旧任务执行
  (部署实测:「对应×4」曾触发规划器重启旧任务,39 次工具调用 / 480s 超时)
- run.finished 带 shortCircuit=probe 标记;协议文档补行为契约
- 三级漏斗(platform/proactive.rs,六平台共用——判定在 admit ②一处生效):
  ① 回复率采样(零成本概率闸门,proactiveRate 0~100,缺省 100)
  ② 探活词表(零成本:在吗/晚安等不该被主动抢答)
  ③ 决策模型一次轻量调用(最近 8 条群聊上下文含发送者署名,
    输出 {"reply":bool};失败/非法保守拒——主动回复是增益不是义务)
- 配置(通道级,默认关):proactiveReply 开关 + proactiveRate 回复率;
  ChannelBody/channel_json 透传,WebUI 开关 + 回复率滑块(两语文案)
- 审计:决策 emit proactive.decision(reply/why);调用失败 proactive.evalError
- 放行后与 @ 消息同链路(身份闸门/消毒/用量治理照常,不绕过成本治理)
- 单测:决策解析(围栏/杂文/非法保守拒)+ 采样边界 + 漏斗端到端保守拒
- 任务 18/18 全勾(7.3 归档自指项随执行勾掉;audit-backlog 由
  long-horizon-iteration 方向 E 承接消化中)
- delta spec ops-audit-loop 同步进主 specs(+3 需求)
- 归档目录 2026-11-02-subagent-audit-hardening
- 流未读(4.1):Core flow_unread 内存态(流粒度,重启归零——单一事实源
  原则下的合理取舍);bump 挂 spawn_reply 收束点 + webhook 回调路径
  (与回帖同语义:一次收束记 1 条,不按分段计);REST flows 带 unread
  + POST /flows/:id/read 清零;WebUI 徽标 99+ 封顶 + 打开乐观清零 +
  run.finished 事件驱动刷新
- 流内会话切换(4.2):REST GET /flows/:id/sessions(同流标题前缀口径
  与 /sessions 指令一致,active 标记 + 倒序)+ PUT /flows/:id/active
  (bind_flow_session 与 /new /use 同源绑定);scope 解析修正——通道
  target 缺省回落 single:默认单体(非激活组,与 ChannelRun::begin 一致);
  跨流错绑 400
- WebUI 流面板:展开钮 + 会话子列表(活跃标记 + 相对时间),选择即改绑
  + 跳转 + 刷新;i18n 两语
- e2e +7 断言(未读累积/清零/回调 bump/非法 id + 会话列表/幂等改绑/
  跨流 400),190/190;FlowActiveBody 补 camelCase(此前 422 反序列化拒)
- 单测:流未读_累积与清零;verify-batch 5/5
- 4.2 引入的 3 个 useState + 2 个 useCallback 声明在早退 return 之后:
  loading 结束后 hooks 数量 7→12,React 检测到顺序变化直接抛错——
  配置过通道的生产环境聊天页白屏(e2e 只测 REST、tsc 不查 Hooks,
  双双漏网;DOM 实测 puppeteer 抓到 pageerror)
- 修复:全部 hooks 提至早退前,早退后只留普通函数与分组计算
- 防线:eslint + eslint-plugin-react-hooks + typescript-eslint 接入
  (仅查 Hooks 规则与运行时相关项,不做风格检查),verify-batch
  增至 6 步;顺手清零 store.ts 冗余 Boolean 与 ActivityView 无效赋值
- DOM 复测:流 3 条 / 展开子列表 / 活跃标记 / 徽标样式 / 无控制台错误
会话管理(session-management):
- 归档:Session 增 archived_at(serde 缺省 None 零迁移);主列表/组内列表
  默认过滤归档态,?archived=true 归档区视图(按归档时间倒序);归档可逆
  不删内容,恢复回主列表原分组;sqlite 侧同口径(含 archived_at 列迁移)
- 批量:POST /sessions/batch(archive/unarchive/delete,尽力而为 +
  failed 明细 + 作用计数;空 ids/未知动作 400);管理口径 all=true 附
  messageCount(JSONL 非空行计数)
- SessionsView 新页:工具条(搜索=标题+预览/类型过滤/排序=活跃·创建·
  消息数/归档区切换)+ CSS Grid 表格(多选/标题/类型/范围/活跃/消息数)
  + 批量工具条(确认与成功反馈带计数)+ 行操作(打开/重命名/置顶/导出/
  归档/删除危险确认);侧栏「会话管理」入口 + 左栏管理按钮双入口
- 左栏瘦身:⋮ 菜单收敛为重命名/置顶/跳管理页(管理职能解耦);
  ChatView 挂 exm:flows-refresh 监听同步列表(同一事实源)
- e2e +7 断言(批量归档/主列表隐身/归档区可见/恢复回归/批量删除/非法
  动作 400)197/197;单测「会话归档_过滤恢复与隔离」

模型设置档案化(model-settings-ux):
- 档案卡状态行:密钥池健康/模型清单数/上次测试(延迟+时间+结论,
  localStorage 留存刷新不丢,失败保留语义);/llm/test 回 latencyMs
- CapabilityBadges 组件:能力徽章带来源标注(探测/手工),未探测不
  渲染空徽章;接入档案卡模型清单
- 编辑表单分节:基础常驻(预设/端点/命名/协议)+ 密钥池/模型清单/
  高级 Collapse 三节(节标题带计数,高级默认折叠);窄屏单列不溢出
- 视觉走查修复:页头「视图切换与动作」分组分隔

交互反馈基线(ui-visual-language):
- feedback.ts 统一出口:toastOk/toastErr(errText 兼容 Error/string/
  {error}/{message},不吞错);SessionsView 全量接入;通道/组页抽查合规

视觉验证闭环:
- scripts/ui-shot.mjs:8 页截图 + 结构断言(只锚选择器不锚文案像素)
  → docs/审计/截图/<日期>/;首轮 8/8 通过,截图留档随批提交
- 子代理读图审阅:5 页 OK,models 顶栏当场修;channels 表格拥挤与
  settings 导航过长记录为下批候选

顺带修复:
- 流会话列表排序三处统一(/sessions /use REST flows/:id/sessions):
  updated_at 倒序 + created_at/id 双破平键——/use 序号寻址在并发下的
  确定性(tests_identity_gate「聊天流_会话绑定与切换」间歇挂根治)

verify-batch 6/6 全绿(clippy/workspace/e2e/tsc/eslint/构建)
- 键盘遮挡:visualViewport 实时高写入 --vvh,窄屏壳层取 min(100dvh, --vvh) 收缩(iOS 键盘弹出不再盖住输入区)
- 审批页窄屏裁次要列(结果/所属会话 md+),表格 min-width 窄屏 100%,跳转并入命令元信息行(link-btn)——批准/拒绝首屏可见
- 通道页窄屏裁凭据/状态/回复列,启用开关/编辑/删除首屏可见
- 设置页分类导航横滚 chips 化 + 右缘渐隐提示(截断分类可发现)
- 会话表 640px 列收敛(隐藏计数/类型,行高 48);模型页头动作允许换行
- 全局小按钮/复选框触控热区扩至 ≥40px(视觉尺寸不变)
- 活动页/审批页时间戳短格式(相对时间 + MM-DD HH:mm,完整时间悬浮)

验收:DevTools 390×844 逐页 DOM 断言 + 两轮截图审阅;verify-batch 6/6
群聊旁听(仅 @ 回复模式的上下文保障):
- 门控拦下的未 @ 群消息不再丢弃:以 imctx: 标记落流会话(不触发轮次、不 bump 未读),
  被点名时最近对话窗口/滚动摘要天然包含群聊上下文
- collect 跳过 imctx: 消息——旁听是背景,不会被当成任务输入重新执行
- 模型侧渲染「群聊·发送者」(plan/单智能体两处 history + compaction user_label),
  主动回复决策上下文同源可见真实群聊记录
- 旁听文本照常入站消毒(finding 带 ambient 审计),流预览跟随最新群消息
- WebUI 消息头署名 + 「群聊」弱化标签;设置项帮助文案说明该行为

设置页分类导航:
- 修复整卡内顶部 19~34px 灰带(吸顶从内层 cfg-nav-scroll 移到外层 cfg-nav,
  内层回归常规滚动;滚动长面板时导航仍悬停可达,首项不再看似被切)

验收:新增单测 5(goal 排除/边界/全旁听/门控落库/私聊豁免)+ compaction 署名;
workspace 307s 全绿,e2e 91s;verify-batch 6/6
- 检索:GET /api/sessions/search(标题 + 最近 200 条消息,大小写不敏感;
  空 q 400、limit 1~50、标题优先、每会话 ≤2 片段、Unicode 安全截取);
  Store/SqliteStore 双实现 + Core 封装
- 管理页搜索升级:250ms 防抖、结果片段高亮、点击打开并定位命中消息
  (data-message-id + msg-flash);接口失败回退本地过滤并提示
- 全局速查:Ctrl/Cmd+K(浏览器保留时为 / 兜底),↑↓/Enter/Esc,
  与管理页共用检索与定位链路
- 历史检查点:会话行菜单入口,轮次倒序展示状态/时间/消息数/文件检查点数/
  该轮输入预览;回到此轮(undo + 文件回滚)与从此轮分叉(自动跳转)
- snapshots 增量 preview;消息气泡锚点;i18n zh/en;契约文档更新
- 验收:workspace 全绿、e2e +15(212)、verify-batch 6/6、ui-shot 8/8、
  三场景 DOM 断言 + 截图审阅
一、更新管线与部署隔离(update-pipeline-and-deploy-isolation)
- version.rs 状态机修复:结构化 UpdateStateFile 为唯一事实源(元组反序列化、
  phase 大小写、Debug 格式化、pid 覆写 4 处 bug)+ 9 单测
- apply-update.sh 双模式重写:image=辅助容器 pull+recreate;git 兼容三步;
  各阶段 state 写入与幂等清理
- 部署隔离:deploy/ 生产模板(无 build 段、sock 可选注释);根 compose 开发
  隔离化(exmachina-dev / 4174 / -dev 卷);Dockerfile 内建 exm 用户(uid 911)
- release.yml 增 ghcr docker job(secrets 缺失跳过);WebUI 双模式面板 +
  phase 文案 + i18n;安装指南三方式改写

二、执行身份约束(agent-exec-confinement)
- security.execUser/execHome:spawn 侧 uid/gid 降权 + cwd 圈禁 + HOME 注入;
  bwrap 同开时 --uid/--gid 原生叠加;fs 工具双保险路径校验
- 提权命令(sudo/su/doas/run0/runuser,链式逐段)无视白名单直达 [root]
  审批;批准后剥冗余壳以 root 代执行;普通审批代执行收口加固路径
- 修复 bwrap 潜伏 bug:/tmp 独立挂载时显式 bind(原 tmpfs 掩盖 /tmp 下工作区)
- WebUI 提权警示徽标 + 安全模型文档

三、元智能体(meta-agent,实验性默认关)
- 数据聚合 meta.rs:system_observation 7 天窗(工具统计/最近失败/adaptation 现状)
- meta_observe/propose/build 工具组:[meta] 审批单(meta_json 扩展位);
  未决单去重;审批卡紫色徽标
- approval_decide [meta] 路由:prompt 锚点+history 备份 / adaptation 版本化 /
  roster 两阶段+逆序回滚 / build 注册走 agent_manage 同校验;内置组保护
- meta_agent_tick 周期巡检(Eval 保守自评 → 自主会话落提议);
  轮内元认知反思(连续失败≥2 策略注入,每轮 1 次)
- experiments.metaAgent + automation.metaIntervalMin 配置面 + schema + 文档

验证:exm-core 281 单测 / workspace 全量 / e2e 217 项 / clippy 0 警告 /
verify-batch 6/6 全绿(1067s)
- sandbox: WinJob Drop 去掉 trait impl 内非法的 pub(crate) 限定(E0449)
- sandbox: Windows 下补 bwrap_available() 恒 false 桩(tools/mod.rs re-export 跨平台可用)
- sandbox: ShellOpts::plain() Windows 分支去掉 unix-only 的 uid_gid 字段(E0560)
- sandbox_helpers: 非 unix 下 confine 显式 None(E0425)
- release.yml: 镜像仓库名取小写 owner(ExMachina-Project 含大写被 docker 拒绝)
# Conflicts:
#	.github/workflows/release.yml
#	crates/exm-core/src/tools/sandbox.rs
#	crates/exm-core/src/tools/sandbox_helpers.rs
docker job 的 buildx 摘要产物(<repo>~<repo>~<hash>.dockerbuild,0 MB 非 zip)
会被 publish 的无过滤 download-artifact 一并拉取,解包重试耗尽 → publish 必失败。
改用 pattern 过滤(server-* / desktop-*)+ merge-multiple,docker 产物不再进发布目录。
- version.rs: pid_alive 追加 /proc/<pid>/stat 的 Z 状态检查——脚本被 SIGKILL 后
  PID 变 defunct 但 kill -0 仍成功,曾把已死任务永久判 running(实测卡死 pulling)
- apply-update.sh: pull / up 收窄到 exmachina 服务(--no-deps + 服务名),
  同项目附属服务(如 napcat)不再随版本更新被拉取重建
- apply-update.sh: 部署目录 .docker/config.json 自动注入 DOCKER_CONFIG,
  私有 ghcr 包可一键更新;凭据只留部署目录(.gitignore 已加)
- deploy/README: 私有仓库凭据配置说明

新增单测 zombie_pid_is_not_alive 覆盖僵尸态回归。
网关 spawn 的是 `exec setsid sh script`,记录到的 child.id() 是 setsid 中间进程,
exec 后立即退出成僵尸——真实脚本 pid 不同,判活会误判。
脚本在每次 set_phase 时把 pid 改写为自身 $$,状态机据此判活。
严重修复:辅助容器此前把部署目录挂到 /host 再 -w /host,而 compose 里的
相对路径(./entities、./skills)按 compose 文件所在目录解析——落到宿主
/host/entities(空目录),重建后容器挂载全部指向错误位置,编成数据整体归零
(实测 agents 40→0)。改为挂载到宿主原始绝对路径并 -w 同路径。

- HELPER_IMAGE 支持 EXM_UPDATE_HELPER_IMAGE 覆盖(离线环境预置本地镜像)
- 本地已有辅助镜像则跳过 pull(受限网络下拉 Docker Hub 会长时间卡住)
更新器可用性修复批(僵尸 PID 判活 / 单服务更新 / 私有 registry 凭据 /
辅助容器同路径挂载)随本版发布。
@BlackStar-Agent
BlackStar-Agent merged commit 8e7c423 into main Nov 3, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants