feat: Agent tools permission config UI + auto-heal (v0.4.4)

- Gateway config page: add tools profile selector (full/limited/none)
- Gateway config page: add session visibility selector (all/own/none)
- Auto-heal: setup + dashboard auto-set tools.profile:full on install/load
- Fixes OpenClaw 2026.3.2 breaking change that disabled tools by default
This commit is contained in:
晴天
2026-03-05 22:40:02 +08:00
parent aae531a7bd
commit cb5cbe2f71
9 changed files with 110 additions and 23 deletions

View File

@@ -5,6 +5,13 @@
格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
## [0.4.4] - 2026-03-06
### 新增 (Features)
- **Agent 工具权限配置** — Gateway 配置页新增「工具权限」区域可选完整权限full/ 受限模式limited/ 禁用工具none以及会话可见性设置
- **工具权限自愈** — 安装/升级后自动设置 `tools.profile: "full"` + `tools.sessions.visibility: "all"`,老用户打开面板也会自动补全,避免 OpenClaw 2026.3.2 新版默认关闭工具导致不好用
## [0.4.3] - 2026-03-06
### 修复 (Bug Fixes)

View File

@@ -34,7 +34,7 @@
"description": "OpenClaw AI Agent 可视化管理面板,基于 Tauri v2 的跨平台桌面应用。支持仪表盘监控、多模型配置、实时 AI 聊天、记忆管理、Agent 管理、网关配置、内网穿透等功能。",
"url": "https://claw.qt.cool/",
"downloadUrl": "https://github.com/qingchencloud/clawpanel/releases/latest",
"softwareVersion": "0.4.3",
"softwareVersion": "0.4.4",
"author": {
"@type": "Organization",
"name": "晴辰云 QingchenCloud",
@@ -429,7 +429,7 @@
<div class="orb orb-1" id="orb1"></div>
<div class="orb orb-2" id="orb2"></div>
<div class="hero-inner">
<div class="reveal hero-badge"><span class="pulse"></span> v0.4.3 已发布 — Gateway 守护、配置同步、流式超时</div>
<div class="reveal hero-badge"><span class="pulse"></span> v0.4.4 已发布 — Gateway 守护、配置同步、流式超时</div>
<h1 class="reveal hero-title">管理你的 <span class="gradient-text shimmer">AI Agent</span><br>从未如此直观</h1>
<p class="reveal hero-subtitle">ClawPanel 是 <strong>OpenClaw</strong> 的可视化管理面板,基于 Tauri v2 构建。<br>仪表盘、模型配置、实时聊天、记忆管理 — 一站式掌控。</p>
<div class="reveal hero-cta">
@@ -696,7 +696,7 @@
<div class="orb orb-2" style="top:auto;bottom:-100px"></div>
<div class="container-sm" style="position:relative;z-index:10">
<div class="section-header">
<div class="reveal download-version"><span class="pulse"></span> v0.4.3 最新版</div>
<div class="reveal download-version"><span class="pulse"></span> v0.4.4 最新版</div>
<h2 class="reveal section-title"><span class="gradient-text">下载安装</span></h2>
<p class="reveal section-desc">选择你的操作系统,一键下载安装</p>
</div>
@@ -706,11 +706,11 @@
<h3>macOS</h3>
<p class="dl-desc">支持 Apple Silicon 和 Intel 芯片</p>
<div class="dl-links">
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.3_aarch64.dmg" target="_blank" rel="noopener">
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.4_aarch64.dmg" target="_blank" rel="noopener">
Apple Silicon (M1/M2/M3/M4)
<span class="dl-format">.dmg</span>
</a>
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.3_x64.dmg" target="_blank" rel="noopener">
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.4_x64.dmg" target="_blank" rel="noopener">
Intel 芯片
<span class="dl-format">.dmg</span>
</a>
@@ -721,11 +721,11 @@
<h3>Windows</h3>
<p class="dl-desc">支持 Windows 10 及以上版本</p>
<div class="dl-links">
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.3_x64-setup.exe" target="_blank" rel="noopener">
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.4_x64-setup.exe" target="_blank" rel="noopener">
安装程序
<span class="dl-format">.exe</span>
</a>
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.3_x64_en-US.msi" target="_blank" rel="noopener">
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.4_x64_en-US.msi" target="_blank" rel="noopener">
MSI 安装包
<span class="dl-format">.msi</span>
</a>
@@ -736,11 +736,11 @@
<h3>Linux</h3>
<p class="dl-desc">支持主流 Linux 发行版</p>
<div class="dl-links">
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.3_amd64.AppImage" target="_blank" rel="noopener">
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.4_amd64.AppImage" target="_blank" rel="noopener">
通用版
<span class="dl-format">.AppImage</span>
</a>
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.3_amd64.deb" target="_blank" rel="noopener">
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.4_amd64.deb" target="_blank" rel="noopener">
Debian / Ubuntu
<span class="dl-format">.deb</span>
</a>

View File

@@ -1,6 +1,6 @@
{
"name": "clawpanel",
"version": "0.4.3",
"version": "0.4.4",
"private": true,
"description": "ClawPanel - OpenClaw 可视化管理面板,基于 Tauri v2 的跨平台桌面应用",
"type": "module",

2
src-tauri/Cargo.lock generated
View File

@@ -328,7 +328,7 @@ dependencies = [
[[package]]
name = "clawpanel"
version = "0.4.3"
version = "0.4.4"
dependencies = [
"base64 0.22.1",
"chrono",

View File

@@ -1,6 +1,6 @@
[package]
name = "clawpanel"
version = "0.4.3"
version = "0.4.4"
edition = "2021"
description = "ClawPanel - OpenClaw 可视化管理面板"
authors = ["qingchencloud"]

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-config-schema/schema.json",
"productName": "ClawPanel",
"version": "0.4.3",
"version": "0.4.4",
"identifier": "ai.openclaw.clawpanel",
"build": {
"frontendDist": "../dist",

View File

@@ -76,10 +76,18 @@ async function loadDashboardData(page) {
if (servicesRes.status === 'rejected') toast('服务状态加载失败', 'error')
if (versionRes.status === 'rejected') toast('版本信息加载失败', 'error')
// 自愈:如果 openclaw.json 没有 mode 字段,自动设为 local否则 Gateway 启动不了
if (config && !config.mode) {
config.mode = 'local'
api.writeOpenclawConfig(config).catch(() => {})
// 自愈:补全关键默认值
if (config) {
let patched = false
if (!config.mode) { config.mode = 'local'; patched = true }
if (!config.tools || config.tools.profile !== 'full') {
config.tools = { profile: 'full', sessions: { visibility: 'all' }, ...(config.tools || {}) }
config.tools.profile = 'full'
if (!config.tools.sessions) config.tools.sessions = {}
config.tools.sessions.visibility = 'all'
patched = true
}
if (patched) api.writeOpenclawConfig(config).catch(() => {})
}
renderStatCards(page, services, version, [], config, null)

View File

@@ -181,6 +181,57 @@ function renderConfig(page, state) {
</div>
</div>
<div class="config-section">
<div class="config-section-title">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><path d="M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z"/></svg>
Agent 工具权限
</div>
<div class="form-group" style="margin-bottom:var(--space-md)">
<label class="form-label">工具调用权限</label>
<div class="gw-option-cards">
<label class="gw-option-card ${(gw.tools?.profile || 'full') === 'full' ? 'selected' : ''}" data-tools-profile="full">
<input type="radio" name="gw-tools-profile" value="full" ${(gw.tools?.profile || 'full') === 'full' ? 'checked' : ''} hidden>
<div class="gw-option-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
</div>
<div class="gw-option-text">
<div class="gw-option-title">完整权限</div>
<div class="gw-option-desc">Agent 可使用所有工具(推荐)</div>
</div>
</label>
<label class="gw-option-card ${gw.tools?.profile === 'limited' ? 'selected' : ''}" data-tools-profile="limited">
<input type="radio" name="gw-tools-profile" value="limited" ${gw.tools?.profile === 'limited' ? 'checked' : ''} hidden>
<div class="gw-option-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/></svg>
</div>
<div class="gw-option-text">
<div class="gw-option-title">受限模式</div>
<div class="gw-option-desc">仅允许安全工具,禁用文件/命令操作</div>
</div>
</label>
<label class="gw-option-card ${gw.tools?.profile === 'none' ? 'selected' : ''}" data-tools-profile="none">
<input type="radio" name="gw-tools-profile" value="none" ${gw.tools?.profile === 'none' ? 'checked' : ''} hidden>
<div class="gw-option-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="8" y1="12" x2="16" y2="12"/></svg>
</div>
<div class="gw-option-text">
<div class="gw-option-title">禁用工具</div>
<div class="gw-option-desc">Agent 只能对话,不能调用任何工具</div>
</div>
</label>
</div>
</div>
<div class="form-group">
<label class="form-label">会话可见性</label>
<select class="form-input" id="gw-sessions-visibility" style="width:auto;min-width:180px">
<option value="all" ${(gw.tools?.sessions?.visibility || 'all') === 'all' ? 'selected' : ''}>所有会话可见</option>
<option value="own" ${gw.tools?.sessions?.visibility === 'own' ? 'selected' : ''}>仅自己的会话</option>
<option value="none" ${gw.tools?.sessions?.visibility === 'none' ? 'selected' : ''}>不可见</option>
</select>
<div class="form-hint">控制 Agent 是否能查看其他会话的上下文</div>
</div>
</div>
<div class="gw-advanced-toggle" id="gw-advanced-toggle">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><polyline points="6 9 12 15 18 9"/></svg>
高级选项
@@ -269,6 +320,15 @@ async function saveConfig(page, state) {
? { mode: 'password', password: authPassword }
: authToken ? { mode: 'token', token: authToken } : {}
const toolsProfile = page.querySelector('input[name="gw-tools-profile"]:checked')?.value || 'full'
const sessionsVisibility = page.querySelector('#gw-sessions-visibility')?.value || 'all'
state.config.tools = {
...(state.config.tools || {}),
profile: toolsProfile,
sessions: { ...(state.config.tools?.sessions || {}), visibility: sessionsVisibility },
}
state.config.gateway = {
...state.config.gateway,
port, bind, mode,

View File

@@ -287,16 +287,28 @@ function bindEvents(page, nodeOk) {
modal.appendLog('⚠️ Gateway 安装失败: ' + e)
}
// 确保 openclaw.json 有 mode: "local",否则 Gateway 启动不了
// 确保 openclaw.json 有关键默认值,否则 Gateway 启动不了或功能受限
try {
const config = await api.readOpenclawConfig()
if (config && !config.mode) {
config.mode = 'local'
await api.writeOpenclawConfig(config)
modal.appendLog('✅ 已设置 Gateway 运行模式为 local')
if (config) {
let patched = false
if (!config.mode) {
config.mode = 'local'
patched = true
modal.appendLog('✅ 已设置 Gateway 运行模式为 local')
}
if (!config.tools || config.tools.profile !== 'full') {
config.tools = { profile: 'full', sessions: { visibility: 'all' }, ...(config.tools || {}) }
config.tools.profile = 'full'
if (!config.tools.sessions) config.tools.sessions = {}
config.tools.sessions.visibility = 'all'
patched = true
modal.appendLog('✅ 已开启 Agent 工具全部权限')
}
if (patched) await api.writeOpenclawConfig(config)
}
} catch (e) {
modal.appendLog('⚠️ 配置 mode 失败: ' + e)
modal.appendLog('⚠️ 自动配置失败: ' + e)
}
toast('OpenClaw 安装成功', 'success')