Commit Graph

440 Commits

Author SHA1 Message Date
晴天
b852ebb6ee feat(hermes): P1-3 lazy_deps 预处理 - 加 IM 渠道不再「首启 Gateway 卡 30 秒后崩」
Hermes 内核 tools/lazy_deps.py 维护了一个 allowlist:每个 feature(如 platform.telegram /
tts.elevenlabs / search.exa)对应一组 PyPI 包。原本只有 Gateway 启动 platform 模块时
才会调 ensure() 装包,导致首次启动卡 30 秒甚至超时崩溃。

本 PR 把 lazy_deps 暴露给 ClawPanel UI,让用户能主动预装。

## 后端三个新 Tauri 命令
- hermes_lazy_deps_features() — 列所有 LAZY_DEPS allowlist feature(17 个)
- hermes_lazy_deps_status(features) — 批量查每个 feature 是否已装好
- hermes_lazy_deps_ensure(feature) — 主动调内核 tools.lazy_deps.ensure 装

实现方式:
- 找到 ~/.hermes-venv 的 python 路径(unix: bin/python,windows: Scripts/python.exe)
- 用 tokio::process::Command spawn `python -c "<embedded script>"` 跑临时 Python 脚本
- 脚本走 from tools.lazy_deps import ensure / feature_missing / LAZY_DEPS
- 把结果以 JSON dump 给 stdout,Rust 端解析最后一行
- enhanced_path() 注入 PATH 兼容 macOS Tauri 启动后 PATH 不全
- serde_json::to_string 把字符串和列表序列化为 Python 合法字面量(防注入)

已注册到 lib.rs,前端 wrapper 在 tauri-api.js(features 走 10min 缓存)。

## 前端
- 新页面 src/engines/hermes/pages/lazy-deps.js
- 分类 grid(消息渠道 / TTS / STT / 搜索 / 模型商 / 记忆 / 图像 / 其他),每类有 emoji
- 卡片式:feature 名(友好显示)+ specs 元信息 + 状态徽章(已装✓ / 未装warn / 未知)+ 装/重装按钮
- 装/重装按钮 await ensure,期间「安装中…」disabled,完成后刷新整张表
- 失败走 humanizeError 统一提示
- 17 个 feature 都有友好显示名 i18n(platform.telegram → Telegram,platform.dingtalk → 钉钉 等)
- 完整 11 语言 i18n(hermesLazyDeps 模块),其它语言 fallback 到 en

## sidebar
- Hermes 引擎「管理」section 新增「可选依赖管理」入口
- 路由 /h/lazy-deps

## CSS
- 加 .lazy-deps-grid / .lazy-deps-card / .lazy-deps-badge.{ok,warn,unknown}
- 复用现有 .empty-state / .empty-compact 风格

## Web 模式
- dev-api.js 加三个同名 handler:
  - features 返回内置常见 platform 列表
  - status 全标 unknown(无法 spawn python)
  - ensure 直接 reject,提示走桌面端

## 累计变动
- 2 新文件(lazy-deps.js page + hermesLazyDeps.js i18n)
- 7 修改(dev-api / hermes.rs / lib.rs / hermes/index.js / tauri-api.js / locales/index.js / components.css)
- 11 语言 × ~17 个新 i18n 键
- cargo check ✓ + npm build ✓
2026-05-14 04:18:33 +08:00
晴天
c4bf769eab feat(hermes): P1-4 hermes_read_config_full 全字段解析 - 解锁 14+ Gateway 高价值配置
之前 hermes_read_config 只读 5 字段(model/base_url/provider/api_key/config_exists),
为「快速面板」服务。Hermes Gateway 实际有 14+ 个顶层配置项,ClawPanel 完全没读到。

本次新增 hermes_read_config_full 命令,作为高级配置编辑器的数据源。

## 后端实现
- 加 serde_yaml 0.9 依赖
- 新命令 hermes_read_config_full:
  · 用 serde_yaml 完整解析 config.yaml
  · 转 JSON 返回 { exists, raw, config, highlights }
  · highlights 字段单独抽出 14 个高价值顶层字段:
    streaming / stt_enabled / quick_commands / reset_triggers /
    default_reset_policy / unauthorized_dm_behavior /
    session_store_max_age_days / always_log_local /
    group_sessions_per_user / thread_sessions_per_user /
    platforms / dashboard / memory / skills
  · 已注册到 lib.rs

## 前端
- tauri-api.js 加 hermesReadConfigFull wrapper

## Web 模式
- dev-api.js 加 hermes_read_config_full handler(Web 模式不强制 yaml 解析,
  返回 raw + null highlights,前端按需 fallback)

## 后续
- 实际「高级配置编辑器」UI 后续单独开 — 本次仅打通数据通道
- 与轻量版 hermes_read_config 互补共存,model 配置页继续用轻量版
2026-05-14 03:56:17 +08:00
晴天
7eababad4a feat(ux): toast 智能行动按钮 + 拓展 ⓘ 到 gateway/agents + sidebar 加术语表入口
延续上一轮小白 UX 改造的尾声三连:

## 1. toast 智能行动按钮(U2 收尾)
- humanizeError 输出新增 action 字段:{ label, route?, handler?, kind }
- 自动按错误 kind 给默认按钮:
  · gatewayDown → [去启动 Gateway] → /services
  · cmdMissing / permission → [打开设置] → /settings
  · auth → [检查 API Key] → /models
  · network / timeout / rateLimit / generic → 不给(重试由用户控制)
- toast 结构化分支渲染 .toast-action-btn 按钮,点击后用 navigate(route) 或调 handler,并自动关闭 toast
- common.js 加 errorAction.* 三个按钮文案 i18n(11 语言)

## 2. ⓘ 拓展到 gateway / agents
- gateway.js: token label 后加 ⓘ(apikey 术语),renderConfig 末尾 attachTermTooltips
- agents.js: addAgent 弹窗 workspace 字段 label 加 ⓘ,setTimeout 扫 document.body 绑定
- term-tooltip.js 精简表新增 4 个术语:workspace / provider / baseurl + scope(已有)

## 3. sidebar 加术语表入口
- 在两个引擎(OpenClaw + Hermes)的最后一个 section 加「术语」条目
- sidebar.js i18n 新增 glossary 键(11 语言)
- 之前只能从 dashboard quick-actions 进入,现在 sidebar 永久可达

## 4. 顺手 bug 修复
- gateway.js 文件末尾历史残留的多余 `}` (line 348) syntax 错误,删除
- 与之前 hermes/cron.js 同类问题,本次改 ⓘ 时被 node --check 暴露

## 累计变动
- 10 个文件修改
- 7 个新 i18n 键(11 语言)
- Build OK
2026-05-14 03:47:25 +08:00
晴天
e710db6ffb feat(ux): 小白 UX 全面改造 - 错误友好度 + 致命操作强确认 + 空状态 + 新手引导 + 术语表
面向小白用户的产品定位重塑,从七大 UX 痛点逐一改造:

## U1 错误友好度(59 处改造)
- 新工具 src/lib/humanize-error.js:自动把后端原始错误(fetch failed、ENETUNREACH、ENOENT 等)
  映射成「主行 + hint 行动建议 + 折叠技术详情」三段式结构化对象
- toast 组件升级支持 { message, hint, raw } 结构化入参,向后完全兼容
- 14 个 page 文件中所有 toast(t('xxx.failed') + ': ' + e, 'error') 替换为 toast(humanizeError(e, t(...)), 'error')
- common.js 加 error.* / errorHint.* 共 13 个新 i18n 键(11 语言):
  网络/Gateway 未启动/命令缺失/权限/超时/限流/未找到/鉴权/服务繁忙/通用

## U2 致命操作强确认(14 处改造)
- showConfirm 升级支持结构化对象 { message, impact[], title, confirmText, cancelText, variant }
- 加 .modal-impact-list 红边样式(让小白看清楚删了会丢什么)
- 14 处致命操作改造,每处显示影响列表 + 红色「删除/移除/重置」按钮 + 灰色「保留」取消:
  · agents.js 删除 Agent(动态显示 N 个绑定影响)
  · channels.js 移除平台(动态算 N 个 binding)+ 移除 Agent binding
  · memory.js 删除记忆文件
  · services.js 卸载 Gateway(3 段影响)+ 删除备份
  · models.js 批量删模型
  · chat.js 删除会话 + 重置会话
  · dreaming.js 重置梦境日记 + 清空 grounded 短期记忆
  · agent-detail.js 解除渠道绑定
  · cron.js 删除任务(OpenClaw + Hermes 两端)
- skills.js 原生 confirm() 改 showConfirm
- hermes-cron.js 原生 confirm() 改 showConfirm,顺手修末尾多余 `}` 的 syntax 残留

## U3-C 空状态 emoji+CTA(5 页面)
- 通用 .empty-state 组件(大 emoji + 标题 + 副本 + CTA 按钮 + 紧凑变体)
- agents.js: 🤖 + 「+ 新建 Agent」CTA
- memory.js: 🧠 + 「+ 新建记忆文件」CTA(紧凑版)
- cron.js:  + 「+ 新建任务」CTA
- skills.js: 🛠️ + 「技能商店」CTA(点击切 Tab)
- channels.js: 💬 + 紧凑提示
- CTA 巧妙复用页面顶部已有按钮的 click,零重复逻辑

## U3-B Dashboard 新手任务卡片
- 蓝紫渐变卡片,4 步任务自动检测:启动 Gateway / 添加模型 / 创建 Agent / 第一次聊天
- 已完成:✓ 徽章 + 删除线 + 60% 透明
- 未完成:编号徽章 + 蓝色 CTA 按钮跳对应页面
- 全部完成 → 庆祝条「🎉 全部搞定!」+ 关闭按钮
- localStorage 标记,用户主动关闭后永久隐藏
- 14 个新 i18n 键,文案小白化(Gateway 是「发动机」/ Agent 是「分身」/ 模型给 AI 装「大脑」)

## U3-A 术语表页(/glossary)
- 25 个核心术语 × 4 大分类(核心 8 / 模型 6 / 接入 5 / 进阶 6)
- 搜索框实时过滤 + Tab 切换分类 + 卡片网格布局
- 每条术语:「比喻 + 一句话」描述(避免循环引用)+ 「打开页面 →」CTA 直达配置
- 3 语言(zh-CN / en / zh-TW)完整翻译,其他 8 语言 fallback
- 双引擎(OpenClaw + Hermes)共用路由
- dashboard quick-actions 加「📖 面板术语」入口

## U3-D 术语 ⓘ tooltip
- 通用 src/lib/term-tooltip.js helper:termHelpHtml(id) + attachTermTooltips(root)
- 8 个高频术语精简表(OAuth / Webhook / Bot Token / API Key / Token / Context Window / Binding / Scope)
- channels.js 字段 label 智能匹配关键词自动追加 ⓘ(覆盖 8 个渠道全部敏感字段)
- models.js 添加/编辑 provider 的 API Key label 也加 ⓘ
- 点 ⓘ → 弹小型 modal 含解释 + 「打开术语表 →」CTA
- attachTermTooltips 内部去重,可安全多次调用

## 累计交付
- 4 个新文件(humanize-error.js / term-tooltip.js / glossary.js page / glossary.js i18n)
- 6 个升级文件(toast / modal / components.css / dashboard / channels / models)
- 14 个 page 错误 toast 友好化(59 处)
- 14 处致命操作强确认
- 5 处空状态升级 + Dashboard 新手卡片 + 术语表 + ⓘ tooltip
- 109 个新 i18n 键(11 语言)
- Build 全程通过
2026-05-14 03:38:47 +08:00
晴天
1d6843c4fb feat(hermes): expose '/v1/capabilities' as the 'hermes_capabilities' Tauri command
Hermes 已在 v2026.5.x 暴露 GET /v1/capabilities 给外部 UI 用作机器可读的能力描述,让前端能动态适配可用 endpoint / feature 而无需用版本号硬匹配。ClawPanel 之前完全没利用这层抽象,本 commit 加一条 Tauri 命令 + Web handler + 前端 wrapper,为后续 chat/runs/approval 等动态降级(老版 Gateway 没有的能力优雅隐藏 UI)打底。
2026-05-14 02:31:35 +08:00
晴天
69cce64985 fix(hermes-model-switch): clear stale 'context_length' when switching model in config.yaml
When the user switches model via the model picker, hermes_update_model rewrites
model.default and model.provider in config.yaml but historically left model.context_length
untouched. The Hermes kernel (8ac351407, May 2026) now actively clears that field on
model switch because the previous model's context window almost never matches the new
model — leaving the stale value caused 'context too large' errors and silently truncated
output. Mirror the upstream behavior by dropping the context_length line as we walk the
model: block, so Hermes falls back to the new model's default window.
2026-05-14 02:30:53 +08:00
晴天
65e9a4c90c feat(hermes-provider): rename 'Alibaba Cloud (DashScope)' to 'Qwen Cloud' to match upstream
Hermes core 1e01b25e7 (May 2026) renamed the display label across the model picker / wizard / status output but kept the provider slug 'alibaba' and the DASHSCOPE_* env vars unchanged. Mirror the label here so the picker label in ClawPanel matches what users see in the Hermes TUI/CLI; existing configs are not migrated because slug and env vars are stable.
2026-05-14 02:30:34 +08:00
晴天
7d4a423df0 feat(hermes-install): diagnose network failures and add optional Git mirror (#273)
- Detect git/network failure patterns (failed to connect, could not resolve host,
  unable to access, etc.) in install/update output and append a clear hint
  pointing users to the proxy or mirror settings instead of leaving them with
  raw multi-line git stderr.
- Add optional 'Hermes Install Mirror' setting (panelConfig.gitMirror): when set,
  install/upgrade injects GIT_CONFIG_COUNT/KEY_0/VALUE_0 to rewrite
  https://github.com/ via the mirror prefix at process scope only — the user's
  global ~/.gitconfig is never touched.
- Surface the new mirror field in Settings (works for both engines), with
  zh-CN/en/zh-TW copy and a hint explaining how it interacts with the install
  flow.
2026-05-14 01:46:55 +08:00
晴天
e9cd2c6059 feat(hermes-chat): show readiness banner when Hermes is missing or Gateway is down (#256)
- Surface a top-of-input warning banner on the chat page when:
  * Hermes Agent is not installed -> red 'go to dashboard' banner;
  * Gateway is not running -> amber banner with the same dashboard link.
- Disable the send button (with a contextual tooltip) so users no longer
  hit cryptic backend errors when their environment is not ready.
- Force-refresh the cached check_hermes status on chat mount so a freshly
  started Gateway is reflected immediately instead of waiting 30s.
- Add zh-CN/en/zh-TW copy + matching error/warn styling that reuses the
  existing Hermes color tokens.
2026-05-14 01:37:59 +08:00
晴天
d0d6950628 fix(web-mode): consolidate Tauri event subscription helper to silence transformCallback errors (#256)
- Add shared safeTauriListen helper in tauri-api.js that returns a noop
  unsubscriber when running outside Tauri, so dynamic-importing
  @tauri-apps/api/event in the browser no longer throws
  'Cannot read properties of undefined (reading transformCallback)'.
- Replace 4 bare 'await import(@tauri-apps/api/event)' call sites
  (about.js hermes upgrade button + channels.js three install/action flows)
  that previously crashed the page on web mode.
- Drop the duplicated local tauriListen helpers in hermes dashboard / chat
  store and route them through the shared helper.
2026-05-14 01:31:58 +08:00
晴天
081ad4af25 fix(hermes): prefer /v1/runs over /v1/responses to reuse session_id (#275)
- /v1/responses ignores body.session_id and generates a fresh server-side
  session for each request, causing the Hermes sessions list to grow by
  one entry per ClawPanel message.
- /v1/runs honors body.session_id directly, so reversing the call priority
  (try /v1/runs first; fall back to /v1/responses on HTTP 404 for older
  Hermes Agent builds) lets sessions group naturally without breaking
  backward compatibility.
2026-05-14 01:28:04 +08:00
晴天
31dcf64426 fix(ws): friendlier error when Gateway kernel does not support v3 handshake (#272)
- Detect 'device signature invalid' / 'protocol mismatch' on WebSocket close (code 1008)
- Detect DEVICE_AUTH_SIGNATURE_INVALID/PROTOCOL_VERSION_MISMATCH on connect failure after auto-pair
- Replace cryptic English reason with kernel.tooOldForProtocol message (zh-CN + en)
- Suggest upgrading Gateway kernel to recommended version (2026.5.x)
- Stop auto-reconnect loop in these unrecoverable cases
2026-05-14 01:16:33 +08:00
friendfish
1584d53bf9 fix: 修复批量测试模型时误触发 Gateway 重启 (#270)
Fixes #271
2026-05-14 01:12:04 +08:00
github-actions[bot]
eeb6bab6c6 ci: update latest.json for v0.15.3 2026-05-13 09:06:28 +00:00
晴天
c3d25aab62 chore: release v0.15.3 v0.15.3 2026-05-13 16:53:47 +08:00
github-actions[bot]
d5059949bc ci: update latest.json for v0.15.2 2026-05-13 08:26:17 +00:00
晴天
1467d58b55 chore: release v0.15.2 v0.15.2 2026-05-13 16:10:13 +08:00
晴天
33e0487574 fix: 退出时直接调用 taskkill.exe,避免关机阶段 cmd.exe 初始化失败导致 0xc0000142 2026-05-13 16:00:07 +08:00
github-actions[bot]
c11c2e5580 ci: update latest.json for v0.15.1 2026-05-10 13:43:18 +00:00
晴天
81c42dbfe2 chore: release v0.15.1 v0.15.1 2026-05-10 21:30:36 +08:00
github-actions[bot]
2a547e9603 ci: update latest.json for v0.15.0 2026-05-07 20:52:43 +00:00
晴天
328624cf03 chore: release v0.15.0
发布 0.15.0:
- 新增内核版本兼容层、特性门控、低版本阻断和升级提示
- 新增 PATH 中 OpenClaw CLI 冲突检测、隔离与恢复
- 修复 Hermes Gateway loopback 自动拉起与 /v1/runs 诊断
- 修复 standalone 一键安装包在 About/仪表盘显示未知版本
- 同步 OpenClaw 2026.5.6 推荐版本和热更新 minAppVersion
- 补齐本地 JS/Rust 测试与发布前检查说明

验证:
- npm run build
- node --test tests/*.test.js
- node --check src/scripts JS 文件
- cargo fmt --all -- --check
- cargo check
- cargo clippy --all-targets -- -D warnings
- cargo test
v0.15.0
2026-05-08 04:39:36 +08:00
晴天
09fe9c601d docs: showcase Hermes Agent in README
在 README 首屏介绍后新增 Hermes Agent 第二引擎展示区:
- 主视觉链接到 docs/hermes-agent.md
- 展示 h00-h03 四张截图矩阵
- 强化长期记忆、会话运营、人格维护、渠道扩展四个卖点

让 0.14.0 新增的 Hermes Agent 图文指南和截图在仓库首页更醒目。
2026-04-26 21:15:36 +08:00
friendfish
2ad5e2d5ce refactor(models): unify primary model rotation and sync
Refactor the model management page so every primary-model entry point goes through setPrimary(). This centralizes fallback-chain rotation, removes stale/deleted models from fallbacks, deduplicates the chain, and refreshes both the default bar and provider cards after primary changes.
2026-04-26 21:03:54 +08:00
晴天
f6470d9e6a ci: update latest.json for v0.14.0
release.yml 的"提交 latest.json 到 main"步骤在本次发版被静默吞错
(`git push HEAD:main || true`):Release CI 跑期间我推了 fmt fix
commit (88928b7) 让 main 领先于 CI 检出的版本,CI 试图 push 时被
GitHub 因 non-fast-forward 拒绝。

手动补提此清单,让前端热更新可识别 0.14.0 包:
- hash 来自下载 https://github.com/qingchencloud/clawpanel/releases/download/v0.14.0/web-0.14.0.zip 后计算的 sha256
- size 取实际字节数
- releasedAt 取 Release.publishedAt
2026-04-26 00:02:05 +08:00
晴天
88928b7397 fix(ci): apply rustfmt to hermes_dashboard_start
`cargo fmt --check` 在 CI 上失败:hermes.rs:884 处的 `let log_file = …`
绑定语句宽度超出 rustfmt 默认 100 列阈值,需要把赋值表达式拆成
let-rhs 起始换行的形式。

不影响 Release tag build(release.yml 不跑 fmt/clippy),仅修 main
的 CI 红灯。
2026-04-25 23:50:01 +08:00
晴天
9ee99ead24 chore: release v0.14.0
集中发版:

新功能(10)
- 心甜Claw 引擎入口(第 3 个引擎模式)
- Hermes 22 个 Provider 注册表 + 安装/仪表盘动态加载
- Hermes .env 高级编辑(拒绝触碰托管 Provider 密钥)
- Hermes 会话与用量分析增强
- Hermes Dashboard 自动拉起 + Windows POSIX-only 兼容模态
- Hermes Skills 工具集面板
- 官网 Hermes Agent 黑金特色区 + 图文指南
- Boot Manifest 启动页(双语 + 错峰动画)
- 官网 Markdown 阅读器图片 lightbox
- Hermes Memory 概览卡

改进(9)
- Hermes 仪表盘/扩展页全面本地化
- 记忆编辑大尺寸模态
- 日志下载 Web/桌面分流
- 侧边栏导航补全
- 模型备选管理 UI(PR #232)
- 模型加载错误 UX 重做(错误卡 + 详情 + 重试)
- .page 布局 clamp + .page-narrow
- Memory 单列断点提早到 1100px
- Web 模式跳过前端热更新检查

修复(12)
- Gateway 启动 platforms.api_server.enabled 自修复(含 7 unit test)
- Memory 页 overview 卡穿模(旧 flex 列约束 → 自然块流)
- Skills 页 hero/toolsets 被压缩(flex-shrink:0)
- Web 模式 Skills ReferenceError(补 _readHermesDisabledSkills)
- 日志/记忆下载行为分流
- src/pages/models.js 5 处 typo
- 删除 56 行 .hm-memory-* 死代码 + line-clamp 标准属性
- Dependabot rustls-webpki / postcss / rand
v0.14.0
2026-04-25 23:47:22 +08:00
晴天
8a314ff64e Merge PR #232 fallback model UI optimization 2026-04-25 11:49:35 +08:00
晴天
102bebc10f docs: clarify remaining rand dependabot alert 2026-04-25 11:32:35 +08:00
晴天
561b6efc42 fix(security): resolve remaining dependabot alerts 2026-04-25 11:29:12 +08:00
晴天
a3a1c4db82 fix(security): update rustls-webpki for dependabot alert 2026-04-25 11:25:24 +08:00
晴天
e6616deb1b docs: update unreleased changelog 2026-04-25 11:02:32 +08:00
晴天
3ed59fcb2b feat(hermes): align dashboard APIs and add xintian engine 2026-04-25 10:31:32 +08:00
晴天
b25808f7f0 feat(hermes): auto-heal platforms.api_server.enabled before gateway start (Step 5)
Close the G7 gap from the v3 integration design.

Scenario: A user upgrades Hermes (or manually edits config.yaml and drops
the api_server platform block). The next `gateway start` silently produces
a Gateway that doesn't expose /v1/runs, and ClawPanel's chat/agent flows
fail with confusing errors.

Solution: Run a pre-start guardian that checks
`platforms.api_server.enabled: true` and auto-heals the file when
missing, with a timestamped backup so users can always roll back.

Backend (src-tauri/src/commands/hermes.rs):
- New pure helpers `config_has_api_server_enabled(raw)` and
  `patch_yaml_ensure_api_server(raw)` working directly on YAML strings
  (no serde_yaml dependency needed — we only touch 3 structural keys).
- `ensure_api_server_enabled(app)` wraps the helpers with filesystem
  I/O: reads config.yaml, writes `config.yaml.bak-<epoch>` on mutation,
  writes the patched content back, emits `hermes-config-patched` so
  the frontend can show a transparent toast.
- Called from `hermes_gateway_action` on every `start` action. If
  config.yaml doesn't exist, the guardian is a no-op (configure_hermes
  creates a compliant file on first run).
- 7 new unit tests covering: truthy value variants (true/yes/on/1),
  missing/disabled/commented scenarios, no-op when healthy,
  appending a full platforms block, injecting into existing platforms,
  replacing an explicitly disabled api_server subtree.

Web mode (scripts/dev-api.js):
- Mirrors the three helpers as `_hermesConfigHasApiServerEnabled`,
  `_hermesPatchYamlEnsureApiServer`, `_hermesEnsureApiServerEnabled`.
- Called in `hermes_gateway_action` start path.
- Logs to console.warn instead of emitting a Tauri event.

Frontend (src/engines/hermes/pages/dashboard.js):
- Dashboard subscribes to `hermes-config-patched` and surfaces a toast
  (6s duration) so the user knows the auto-heal happened and where the
  backup lives.

Verified: cargo fmt / cargo clippy -D warnings / cargo test all green
(12 hermes tests pass total: 5 provider registry + 7 guardian).
`node --check scripts/dev-api.js` passes. `npm run build` green.
2026-04-24 20:58:30 +08:00
晴天
31936b4779 feat(hermes): add .env editor page for unmanaged env vars (Step 4)
Users may need to configure custom environment variables for Hermes
(e.g. `TAVILY_API_KEY` for the tavily skill, `HTTP_PROXY`, SKILL_*
settings). Previously the only way to set these was to hand-edit
~/.hermes/.env, which risks clobbering the provider keys that
ClawPanel writes through configure_hermes.

This patch adds a dedicated editor UI backed by three new Tauri
commands that refuse to touch managed keys.

Backend (src-tauri/src/commands/hermes.rs):
- `hermes_env_read_unmanaged` — returns every KEY=VALUE pair whose key
  is NOT in `hermes_providers::all_managed_env_keys()` (so provider
  API keys, base URLs, `GATEWAY_ALLOW_ALL_USERS`, `API_SERVER_KEY`
  stay hidden). Preserves file order, dedups.
- `hermes_env_set(key, value)` — validates key against `^[A-Z0-9_]+$`,
  refuses managed keys, updates first occurrence or appends,
  preserves comments/blanks.
- `hermes_env_delete(key)` — refuses managed keys, removes first
  matching line, preserves other structure.

All three commands registered in `src-tauri/src/lib.rs`.

Frontend:
- New page `src/engines/hermes/pages/env-editor.js`:
  - Header with "back to dashboard" link and warning banner listing
    which keys are managed by ClawPanel.
  - Table with Key / Value / Actions columns.
  - Inline edit mode per row (save / cancel).
  - "Add variable" button for new entries.
  - Value column masks long secrets (`sk-a…xyz9`) so glances don't
    leak credentials.
  - Toast feedback on save / delete / validation errors.
  - Inline Chinese copy (TODO: wire up i18n when the locales module
    lands).
- Route registered at `/h/env` in `src/engines/hermes/index.js`.
- Dashboard "Model config" section now has a subtle link
  ".env 高级编辑 →" pointing to the new page.

API wiring:
- `src/lib/tauri-api.js`: added `hermesEnvReadUnmanaged`,
  `hermesEnvSet`, `hermesEnvDelete`.
- `scripts/dev-api.js`: mirrors the three commands in Web mode with
  a duplicated managed-key list (keep in sync with Rust's
  `hermes_providers::all_managed_env_keys` as new providers land).

Verified: cargo fmt / cargo clippy -D warnings / cargo test / npm run
build all green. Dashboard chunk unchanged (24.30 kB); new env-editor
chunk is ~7 kB gzip.
2026-04-24 20:50:29 +08:00
晴天
42d6758eb4 feat(hermes): dynamically load provider registry in setup & dashboard (Step 2)
Wire the new Rust `hermes_list_providers` command into the frontend and
replace the hardcoded OpenClaw PROVIDER_PRESETS usage with the
authoritative Hermes registry. Closes the G4 gap from the v3 design.

New module `src/engines/hermes/lib/providers.js`:
- Async `loadHermesProviders()` with per-session cache.
- `groupProviders()` buckets by authType + region: apiKeyIntl,
  apiKeyCn, aggregators, oauth, externalProc, custom.
- Lookup helpers: `findProviderById`, `inferProviderByBaseUrl`,
  `defaultModelFor`, plus cache reset for hot-reload scenarios.
- Exported auth_type / transport string constants mirroring Rust.

Refactored `src/engines/hermes/pages/setup.js`:
- Drops `PROVIDER_PRESETS` import; loads registry before first paint.
- Provider buttons are grouped under labeled sections (International,
  China, Aggregators), with an OAuth hint block listing the CLI
  commands users must run (e.g. `hermes auth login nous`).
- Selected provider detail panel now shows target env var
  (`ANTHROPIC_API_KEY`, `DEEPSEEK_API_KEY`, etc.) and model catalog
  size.
- `doSaveConfig` sends the provider id (not preset key) through
  `api.configureHermes`; falls back to `custom` when the base URL
  doesn't match any registered provider.
- `doFetchModels` maps provider.transport → apiType.
- Graceful fallback: when the registry is empty (Web mode), UI
  degrades to manual Base URL + API Key entry.

Refactored `src/engines/hermes/pages/dashboard.js`:
- Loads provider registry in parallel with gateway refresh.
- Preset buttons filter out the `custom` placeholder and source
  data from the async-loaded list.
- Uses `inferProviderByBaseUrl` consistently for highlight / fetch /
  save flows.

Frontend API wiring:
- `src/lib/tauri-api.js`:
  - Added `hermesListProviders` (10-minute cache).
  - Extended `hermesFetchModels` and `hermesUpdateModel` with
    optional `provider` param.
- `scripts/dev-api.js`:
  - `hermes_list_providers`: Web-mode stub returning [] (triggers
    frontend fallback UI).
  - `hermes_fetch_models` / `hermes_update_model` accept provider
    param (no-op in fetch; full YAML rewrite in update_model matching
    Rust behavior).

Verified: `npm run build` green (1.04s). Setup chunk 24.34 kB,
dashboard chunk 24.30 kB. No new warnings.
2026-04-24 20:41:06 +08:00
晴天
17759fc1e6 feat(hermes): add 22-provider registry + rewrite core commands (Step 1)
Introduce an authoritative Hermes provider registry in Rust, mirroring
upstream `hermes-agent` data (PROVIDER_REGISTRY + _PROVIDER_MODELS), and
refactor the four critical Hermes commands to be provider-aware.

Closes the G1/G2/G3 blockers identified in the v3 integration design.

New module `src-tauri/src/commands/hermes_providers.rs`:
- Static catalog of 22 providers: 17 api_key (incl. DeepSeek, Gemini,
  xAI, GLM/Z.AI, Kimi, MiniMax int'l + CN, Alibaba DashScope, Xiaomi,
  Copilot PAT, HuggingFace, OpenRouter, Vercel AI Gateway, OpenCode
  Zen/Go, Kilocode), 3 OAuth (Nous, OpenAI Codex, Qwen OAuth), 1
  external_process (Copilot ACP), and `custom` placeholder.
- Each entry carries id, display name, auth_type, base_url, env var
  priority list, transport, probe strategy, known models, aggregator
  flag, and CLI auth hint.
- Helpers: `get_provider`, `primary_api_key_env`, `primary_base_url_env`,
  `all_managed_env_keys`, `infer_provider_from_env_keys`,
  `find_provider_by_model`.
- New Tauri command `hermes_list_providers` (cached client-side).
- 5 unit tests covering registry integrity and lookup semantics.

Refactored `src-tauri/src/commands/hermes.rs`:
- `configure_hermes`: writes `model.provider` in config.yaml and routes
  API keys through the registry's `api_key_env_vars`. Skips key write
  for OAuth providers (Hermes CLI manages auth.json itself). Clears
  all managed keys on provider switch to avoid stale credentials.
- `hermes_read_config`: reads `model.provider`, then reverse-looks up
  the matching API key from the registry's env var priority list.
  Falls back to inferring provider from .env when config.yaml omits
  the provider field.
- `hermes_update_model`: accepts optional `provider` param; writes
  `model.provider` line into config.yaml (adds it when missing, updates
  in place when present, removes it for `custom`).
- `hermes_fetch_models`: accepts optional `provider` param; uses
  registry's probe strategy (`PROBE_NONE` returns static catalog for
  OAuth providers instead of hitting the API).

Registration:
- `src-tauri/src/commands/mod.rs`: declare `hermes_providers` module.
- `src-tauri/src/lib.rs`: import + register `hermes_list_providers`.

Verified: cargo fmt / cargo clippy -D warnings / cargo test all green
(5 new unit tests pass).
2026-04-24 20:40:40 +08:00
晴天
11cd6218dc feat(diagnose): detect and inform about @homebridge/ciao cmd popup bug (#250)
* feat(diagnose): detect and inform about @homebridge/ciao cmd popup bug

On Windows, OpenClaw's transitive dependency @homebridge/ciao (<=1.3.6)
calls child_process.exec('arp -a ...') every 15-30 seconds without
passing windowsHide:true, causing a cmd.exe popup to flash.

This is an upstream library bug:
- Issue: homebridge/ciao#64
- PR:    homebridge/ciao#65 (open, not merged)

ClawPanel deliberately chooses 'detect and inform' rather than silently
patching the user's node_modules. We respect the user's control over
their own machine.

Changes:
- src-tauri/src/commands/diagnose.rs: new check_ciao_windowshide_bug
  command; scans openclaw's @homebridge/ciao/lib/NetworkManager.js and
  reports whether the buggy exec pattern is present
- src-tauri/src/lib.rs: register the new command
- scripts/dev-api.js: Web-mode stub (returns affected:false since the
  bug does not manifest off-Windows)
- src/lib/tauri-api.js: add api.checkCiaoWindowsHideBug
- src/lib/ciao-bug-warning.js: new module with toast + modal flow,
  version-scoped dismiss (localStorage)
- src/locales/modules/ciaoBug.js: translations in 5 primary languages
- src/locales/index.js: register the ciaoBug module
- src/main.js: call checker 3s after splash hides

Non-Windows users see nothing; Windows users see a single warning toast
(version-dismissible) linking to three fix paths: wait for upstream,
apply patch-package, or edit NetworkManager.js manually.

* fix(diagnose): gate helper with cfg(windows), drop unneeded return

CI failures on Linux + macOS:
- openclaw_module_root was dead code when target_os != windows
  since the only caller is the #[cfg(target_os = "windows")] block
  inside check_ciao_windowshide_bug
- Explicit `return CiaoCheckResult {...};` in the non-Windows branch
  triggered clippy::needless_return

Fix:
- Add #[cfg(target_os = "windows")] to openclaw_module_root so it
  is not compiled on other platforms
- Convert the non-Windows early exit to a tail expression
2026-04-24 19:36:20 +08:00
晴天
da5adc5843 fix(gateway): conservative zombie cleanup on windows (#249)
Fix for #244 Hidden-start repeat loop:

cleanup_zombie_gateway_processes used a single /health probe to
decide whether a port-listening process is a zombie. When Gateway
reaches 'ready' but is still initializing (loading plugins, connecting
channels, warming up networks), a single probe can time out -> the
healthy Gateway gets killed -> start_service_impl Hidden-starts a new
one -> loop.

Add is_gateway_port_responsive_with_retry: 3 attempts with 800ms
interval before classifying as zombie. Maximum wait 2.4s for a
process that's genuinely healthy to show up as such.

Effect: healthy Gateway no longer misidentified during warm-up,
Hidden-start no longer triggered on an already-ready Gateway.

Refs #244
2026-04-24 19:36:07 +08:00
晴天
5235853373 fix(gateway): debounce restart with single-flight queue (#248)
Root cause for #243 / #244 / #240: model edits trigger
api.restartGateway() with only 300ms debounce. Fast consecutive
edits stack up restart calls, creating zombie Gateway processes,
failed restarts, and CPU fan spikes.

Layer A (frontend):
- New src/lib/gateway-restart-queue.js: 3s debounce + single-flight
  lock + reschedule on in-flight request
- Refactor src/pages/models.js doAutoSave: write config immediately,
  schedule restart via queue with 'Apply now' toast button
- Subscribe to queue state for unified success/failure toast
- Add i18n: models.configQueued, models.applyNow

Layer B (backend):
- src-tauri/src/commands/config.rs: wrap restart_gateway /
  reload_gateway with tokio::sync::Mutex + 2s cooldown
- Cargo.toml: add tokio 'sync' feature
- scripts/dev-api.js: same guard for Web mode (inflight promise
  reuse + 2s cooldown)

Effects:
- 10 rapid edits within 3s -> 1 restart (was 10+ with races)
- Backend serializes concurrent restart calls, no zombie spawns
- User sees single 'Apply now' toast instead of restart storm

Refs #243 #244 #240
2026-04-24 19:35:39 +08:00
friendfish
66e57adab0 fix(models): recognize google-generative-ai as google-gemini api type (#241)
Fixes #239
2026-04-24 17:39:39 +08:00
晴天
cb540564f8 docs: add FAQ for hot update rollback 2026-04-21 17:50:07 +08:00
friendfish
9afe6eeb24 feat(models): refine fallback UI styling
- Display fallback chain as colored chips in a dedicated row when collapsed
- Add background colors to active chain and candidate pool for visual distinction
- Remove redundant Cancel/Save buttons since autoSave is enforced
2026-04-21 01:48:38 +08:00
friendfish
f61cb65b4a refactor(models): address PR #232 review comments
- i18n: Extract hardcoded Chinese strings to translation keys
- fix(url): Restore full-width punctuation in URL regex
- chore: Remove linux-schema.json (build artifact)
- chore: Add linux-schema.json to .gitignore
- refactor: Unify save strategy to use autoSave consistently
- style: Add trailing newline to en.json

Closes review items 1-6 from PR #232
2026-04-21 01:00:19 +08:00
github-actions[bot]
96aa1f061d ci: update latest.json for v0.13.4 2026-04-20 08:31:04 +00:00
晴天
53720e4e33 fix: cargo fmt formatting for list_remote_models v0.13.4 2026-04-20 16:16:57 +08:00
晴天
1d4f4a4db2 chore: release v0.13.4 2026-04-20 16:08:15 +08:00
晴天
46cd8ae01e fix(deploy): 修复 Linux 全新系统部署 npm 缓存权限问题 (#236)
现象:全新 Ubuntu 上执行一键部署脚本后,npm install 报大量
TAR_ENTRY_ERROR / ENOTEMPTY / EACCES 错误,node_modules 处于半损坏状态,
导致后续 vite build 找不到 picomatch 等依赖。

根因:OpenClaw 安装阶段使用 sudo -E npm install -g 安装全局包时,
会在用户主目录 ~/.npm 缓存目录里留下 root 拥有的文件,
后续用户态的 npm install 无法写缓存 → 安装中断 → node_modules 残缺。

修复:
- 新增 fix_npm_cache_permissions:检测 ~/.npm 中是否存在 root 拥有的文件,
  自动执行 chown 恢复当前用户权限(root/普通用户分别走 chown 与 sudo chown)
- install_clawpanel 调用一次权限预检,并对 npm install 失败场景增加一次
  清理 node_modules 后的重试,避免半损坏目录污染构建
- 升级路径里补充对不完整 node_modules 的探测(缺少 .package-lock.json 即清理)
2026-04-20 16:01:43 +08:00
晴天
1ef9ca8ede fix(models): 获取模型列表 404 改为友好提示 + 助手侧走后端绕 CORS
场景:部分服务商(如某些厂商的 Anthropic 兼容接口)不提供 /models 列表接口,
之前会直接显示 HTTP 404 Not Found / Failed to fetch 等技术错误,用户体验差。

- Rust list_remote_models:识别 404/405/501 作为"不支持自动获取"场景,
  返回带 [NOT_SUPPORTED] 前缀的友好错误,而非裸 HTTP 状态码
- 模型配置页「获取列表」:识别 [NOT_SUPPORTED] 后弹出引导对话框,
  点击「模型」按钮直接进入手动添加流程
- 助手设置页「获取列表」:改为走 Rust 后端 api.listRemoteModels,
  原先直接用前端 fetch 会被 WebView CORS 拦截(provider 不返回 CORS 头),
  改走后端既绕开 CORS 又能获得一致的友好提示
- Web 模式 dev-api.js 同步 404 识别逻辑,保证桌面 / Web 行为一致
- 补齐 models.fetchNotSupported / assistant.fetchNotSupported 多语言文案
2026-04-20 16:01:24 +08:00
晴天
12cdc72d2b fix(assistant): 模型测试按钮改用流式累积 + 增强诊断信息
- 测试请求切换到 stream: true + SSE 累积,绕开部分兼容网关
  non-streaming 分支对某些模型返回 200 + 空 body 的已知 bug,
  行为与真实对话路径一致
- 后端 test_model_verbose 显式设置 Accept-Encoding: identity,
  避免压缩协商带来的解码风险
- 用 resp.bytes() + 严格 UTF-8 decode,失败时 fallback 到
  lossy 字符串 + 前 200 字节 hex dump,方便定位非 UTF-8 响应
- 展开 reqwest error source 链,响应头与字节数原样返回前端
- 前端结果面板突出显示完整模型回复、固定 prompt 标注、
  响应头与 raw bytes hex,方便用户自查上游问题
- scripts/dev-api.js 同步 Rust 后端行为,保证 Web/桌面两侧诊断一致
2026-04-20 15:36:09 +08:00