feat: 实现循环防护和安全验证功能
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

refactor(loop_guard): 为LoopGuard添加Clone派生
feat(capabilities): 实现CapabilityManager.validate()安全验证
fix(agentStore): 添加token用量追踪
chore: 删除未实现的Predictor/Lead HAND.toml文件
style(Credits): 移除假数据并标注开发中状态
refactor(Skills): 动态加载技能卡片
perf(configStore): 为定时任务添加localStorage降级
docs: 更新功能文档和版本变更记录
This commit is contained in:
iven
2026-03-27 07:56:53 +08:00
parent 0d4fa96b82
commit eed347e1a6
14 changed files with 724 additions and 476 deletions

View File

@@ -3,13 +3,6 @@ import { useState } from 'react';
export function Credits() {
const [filter, setFilter] = useState<'all' | 'consume' | 'earn'>('all');
const logs = [
{ id: 1, action: 'AutoClaw网页搜索', date: '2026年03月11日 12:02:02', amount: -6 },
{ id: 2, action: 'AutoClaw网页搜索', date: '2026年03月11日 12:01:58', amount: -6 },
{ id: 3, action: 'AutoClaw网页搜索', date: '2026年03月11日 12:01:46', amount: -6 },
{ id: 4, action: 'AutoClaw网页搜索', date: '2026年03月11日 12:01:43', amount: -6 },
];
return (
<div className="max-w-3xl">
<div className="flex justify-between items-center mb-6">
@@ -24,9 +17,10 @@ export function Credits() {
</div>
</div>
<div className="text-center mb-8">
<div className="text-center mb-8 py-12">
<div className="text-xs text-gray-500 mb-1"></div>
<div className="text-3xl font-bold text-gray-900">2268</div>
<div className="text-3xl font-bold text-gray-900">--</div>
<div className="text-xs text-gray-400 mt-2"></div>
</div>
<div className="p-1 mb-6 flex rounded-lg bg-gray-50 border border-gray-100 shadow-sm">
@@ -50,18 +44,9 @@ export function Credits() {
</button>
</div>
<div className="bg-white rounded-xl border border-gray-200 divide-y divide-gray-100 shadow-sm">
{logs.map((log) => (
<div key={log.id} className="flex justify-between items-center p-4">
<div>
<div className="text-sm text-gray-700">{log.action}</div>
<div className="text-xs text-gray-500 mt-1">{log.date}</div>
</div>
<div className={`font-medium ${log.amount < 0 ? 'text-gray-500' : 'text-green-500'}`}>
{log.amount > 0 ? '+' : ''}{log.amount}
</div>
</div>
))}
<div className="bg-white rounded-xl border border-gray-200 p-8 text-center">
<div className="text-sm text-gray-400"></div>
<div className="text-xs text-gray-300 mt-1">使</div>
</div>
</div>
);

View File

@@ -2,67 +2,7 @@ import { useEffect, useState } from 'react';
import { useConnectionStore } from '../../store/connectionStore';
import { useConfigStore } from '../../store/configStore';
import { silentErrorHandler } from '../../lib/error-utils';
import { Wrench, Zap, FileCode, Globe, Mail, Database, Search, MessageSquare } from 'lucide-react';
// ZCLAW 内置系统技能
const SYSTEM_SKILLS = [
{
id: 'code-assistant',
name: '代码助手',
description: '代码编写、调试、重构和优化',
category: '开发',
icon: FileCode,
},
{
id: 'web-search',
name: '网络搜索',
description: '实时搜索互联网信息',
category: '信息',
icon: Search,
},
{
id: 'file-manager',
name: '文件管理',
description: '文件读写、搜索和整理',
category: '系统',
icon: Database,
},
{
id: 'web-browsing',
name: '网页浏览',
description: '访问和解析网页内容',
category: '信息',
icon: Globe,
},
{
id: 'email-handler',
name: '邮件处理',
description: '发送和管理电子邮件',
category: '通讯',
icon: Mail,
},
{
id: 'chat-skill',
name: '对话技能',
description: '自然语言对话和问答',
category: '交互',
icon: MessageSquare,
},
{
id: 'automation',
name: '自动化任务',
description: '自动化工作流程执行',
category: '系统',
icon: Zap,
},
{
id: 'tool-executor',
name: '工具执行器',
description: '执行系统命令和脚本',
category: '系统',
icon: Wrench,
},
];
import { Wrench } from 'lucide-react';
export function Skills() {
const connectionState = useConnectionStore((s) => s.connectionState);
@@ -116,35 +56,52 @@ export function Skills() {
</div>
)}
{/* 系统技能 */}
{/* 系统技能 — 从 skillsCatalog 动态加载,未连接时展示说明 */}
<div className="mb-6">
<h3 className="text-sm font-semibold text-gray-700 mb-3">ZCLAW </h3>
<div className="grid grid-cols-2 gap-3">
{SYSTEM_SKILLS.map((skill) => {
const Icon = skill.icon;
return (
<h3 className="text-sm font-semibold text-gray-700 mb-3">
ZCLAW
<span className="text-[10px] px-1.5 py-0.5 bg-blue-50 text-blue-600 rounded ml-2">
{connected ? `已加载 ${skillsCatalog.filter(s => s.source === 'builtin').length}` : '未连接'}
</span>
</h3>
{connected && skillsCatalog.length > 0 ? (
<div className="grid grid-cols-2 gap-3">
{skillsCatalog.slice(0, 16).map((skill) => (
<div
key={skill.id}
className="bg-white rounded-xl border border-gray-200 p-4 shadow-sm hover:shadow-md transition-shadow"
>
<div className="flex items-start gap-3">
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-purple-500 rounded-lg flex items-center justify-center flex-shrink-0">
<Icon className="w-5 h-5 text-white" />
<Wrench className="w-5 h-5 text-white" />
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-gray-900">{skill.name}</span>
<span className="text-[10px] px-1.5 py-0.5 bg-purple-50 text-purple-600 rounded">
{skill.category}
</span>
{skill.source && (
<span className="text-[10px] px-1.5 py-0.5 bg-purple-50 text-purple-600 rounded">
{skill.source === 'builtin' ? '内置' : '额外'}
</span>
)}
</div>
<p className="text-xs text-gray-500 mt-1">{skill.description}</p>
<p className="text-xs text-gray-500 mt-1">{skill.description || skill.path || skill.id}</p>
</div>
</div>
</div>
);
})}
</div>
))}
{skillsCatalog.length > 16 && (
<div className="text-xs text-gray-400 text-center col-span-2 py-2">
{skillsCatalog.length - 16}
</div>
)}
</div>
) : (
<div className="bg-white rounded-xl border border-gray-200 p-6 text-center shadow-sm">
<p className="text-sm text-gray-400">
{connected ? '暂无可用技能' : '连接后端后自动加载系统技能列表'}
</p>
</div>
)}
</div>
<div className="bg-white rounded-xl border border-gray-200 p-6 mb-6 shadow-sm">