feat: initialize ZCLAW project with core systems and Tauri desktop

- Created backend core systems:
  - Remote Execution System (远程执行系统)
  - Task Orchestration Engine (任务编排引擎)
  - Persistent Memory System (持续记忆系统)
  - Proactive Service System (主动服务系统)

- Created Tauri desktop app:
  - Three-column layout based on AutoClaw design
  - React + TypeScript + Tailwind CSS
  - Zustand state management
  - Lucide React icons

- Components:
  - Sidebar (Agent list, IM channels, scheduled tasks)
  - ChatArea (Chat interface with message bubbles)
  - RightPanel (Task progress, statistics, next actions)

Next: Test Tauri dev server and integrate with OpenClaw backend
This commit is contained in:
iven
2026-03-11 22:06:07 +08:00
commit 045e9cef5b
59 changed files with 2819 additions and 0 deletions

1
src/core/memory/index.ts Normal file
View File

@@ -0,0 +1 @@
export * from './memory';

54
src/core/memory/memory.ts Normal file
View File

@@ -0,0 +1,54 @@
// 持续记忆系统
export interface UserProfile {
id: string;
preferences: {
language: 'zh' | 'en';
timezone: string;
responseStyle: 'concise' | 'detailed';
};
patterns: {
activeHours: number[];
frequentCommands: string[];
};
}
export interface MemoryEvent {
id: string;
userId: string;
type: string;
content: any;
timestamp: Date;
embedding?: number[];
}
export class PersistentMemorySystem {
private profiles: Map<string, UserProfile> = new Map();
private events: MemoryEvent[] = [];
async remember(userId: string, event: MemoryEvent): Promise<void> {
event.id = event.id || this.generateId();
event.timestamp = new Date();
this.events.push(event);
console.log([Memory] Event remembered: );
}
async recall(userId: string, query: string, limit: number = 10): Promise<MemoryEvent[]> {
// TODO: 实现向量搜索(后续实现)
return this.events.filter(e => e.userId === userId).slice(0, limit);
}
async getProfile(userId: string): Promise<UserProfile | undefined> {
return this.profiles.get(userId);
}
async updateProfile(userId: string, updates: Partial<UserProfile>): Promise<void> {
const profile = this.profiles.get(userId);
if (profile) {
Object.assign(profile, updates);
}
}
private generateId(): string {
return mem__;
}
}

View File

@@ -0,0 +1 @@
export * from './proactive';

View File

@@ -0,0 +1,49 @@
// 主动服务系统
export interface ScheduledTask {
id: string;
userId: string;
channel: string;
schedule: {
type: 'once' | 'daily' | 'weekly' | 'cron';
time: string;
timezone: string;
};
task: {
type: string;
prompt: string;
};
status: 'active' | 'paused' | 'completed';
lastRun?: Date;
nextRun?: Date;
}
export class ProactiveServiceSystem {
private tasks: Map<string, ScheduledTask> = new Map();
private cronJobs: Map<string, any> = new Map();
async scheduleTask(task: ScheduledTask): Promise<void> {
task.id = task.id || this.generateId();
task.status = 'active';
this.tasks.set(task.id, task);
// TODO: 使用 node-cron 设置定时任务(后续实现)
console.log([Proactive] Task scheduled: );
}
async cancelTask(taskId: string): Promise<void> {
const task = this.tasks.get(taskId);
if (task) {
task.status = 'paused';
// TODO: 取消 cron job
}
}
async listTasks(userId: string): Promise<ScheduledTask[]> {
return Array.from(this.tasks.values()).filter(t => t.userId === userId);
}
private generateId(): string {
return cron__;
}
}

View File

@@ -0,0 +1,125 @@
// 远程执行系统 - 实现类
import type {
RemoteExecutionSystem,
Device,
Task,
TaskStatus,
StatusHandler,
Result,
DeviceStatus
} from './types';
export class RemoteExecutionEngine implements RemoteExecutionSystem {
private devices: Map<string, Device> = new Map();
private tasks: Map<string, Task> = new Map();
private subscriptions: Map<string, StatusHandler[]> = new Map();
private taskQueue: Task[] = [];
async registerDevice(device: Device): Promise<void> {
this.devices.set(device.id, device);
console.log([RemoteExecution] Device registered: ());
}
async heartbeat(deviceId: string): Promise<DeviceStatus> {
const device = this.devices.get(deviceId);
if (!device) {
throw new Error(Device not found: );
}
device.lastHeartbeat = new Date();
return device.status;
}
async submitTask(task: Task): Promise<string> {
task.id = task.id || this.generateId();
task.status = 'pending';
task.createdAt = new Date();
this.tasks.set(task.id, task);
this.taskQueue.push(task);
console.log([RemoteExecution] Task submitted: );
// 立即执行(后续会改为队列处理)
this.executeTask(task).catch(console.error);
return task.id;
}
async cancelTask(taskId: string): Promise<void> {
const task = this.tasks.get(taskId);
if (!task) {
throw new Error(Task not found: );
}
task.status = 'cancelled';
this.notifySubscribers(taskId, 'cancelled');
}
async getStatus(taskId: string): Promise<TaskStatus> {
const task = this.tasks.get(taskId);
if (!task) {
throw new Error(Task not found: );
}
return task.status;
}
subscribe(taskId: string, handler: StatusHandler): void {
if (!this.subscriptions.has(taskId)) {
this.subscriptions.set(taskId, []);
}
this.subscriptions.get(taskId)!.push(handler);
}
async pushResult(taskId: string, result: Result): Promise<void> {
const task = this.tasks.get(taskId);
if (!task) {
throw new Error(Task not found: );
}
task.result = result;
task.status = result.success ? 'completed' : 'failed';
task.completedAt = new Date();
this.notifySubscribers(taskId, task.status);
}
private async executeTask(task: Task): Promise<void> {
try {
task.status = 'running';
task.startedAt = new Date();
this.notifySubscribers(task.id, 'running');
// TODO: 实际执行逻辑(调用 OpenClaw SDK
console.log([RemoteExecution] Executing task: );
// 模拟执行
await new Promise(resolve => setTimeout(resolve, 1000));
await this.pushResult(task.id, {
taskId: task.id,
success: true,
data: { message: 'Task completed successfully' }
});
} catch (error: any) {
await this.pushResult(task.id, {
taskId: task.id,
success: false,
error: error.message
});
}
}
private notifySubscribers(taskId: string, status: TaskStatus, progress?: number): void {
const handlers = this.subscriptions.get(taskId);
if (handlers) {
handlers.forEach(handler => handler(status, progress));
}
}
private generateId(): string {
return ask__;
}
}

View File

@@ -0,0 +1,2 @@
export * from './types';
export * from './engine';

View File

@@ -0,0 +1,46 @@
// 远程执行系统 - 核心接口
export interface Device {
id: string;
name: string;
userId: string;
platform: 'macos' | 'windows' | 'linux';
capabilities: string[];
status: 'online' | 'offline' | 'busy';
lastHeartbeat: Date;
}
export interface Task {
id: string;
userId: string;
deviceId: string;
channel: string;
type: 'immediate' | 'scheduled';
priority: 'high' | 'normal' | 'low';
payload: any;
status: TaskStatus;
result?: any;
createdAt: Date;
startedAt?: Date;
completedAt?: Date;
}
export type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
export interface RemoteExecutionSystem {
registerDevice(device: Device): Promise<void>;
heartbeat(deviceId: string): Promise<DeviceStatus>;
submitTask(task: Task): Promise<string>;
cancelTask(taskId: string): Promise<void>;
getStatus(taskId: string): Promise<TaskStatus>;
subscribe(taskId: string, handler: StatusHandler): void;
pushResult(taskId: string, result: Result): Promise<void>;
}
export type StatusHandler = (status: TaskStatus, progress?: number) => void;
export type DeviceStatus = 'online' | 'offline' | 'busy';
export interface Result {
taskId: string;
success: boolean;
data?: any;
error?: string;
}

View File

@@ -0,0 +1,2 @@
export * from './types';
export * from './orchestrator';

View File

@@ -0,0 +1,186 @@
// 任务编排引擎 - 实现类
import type {
TaskOrchestrationEngine,
TaskPlan,
TaskStep,
ExecutionResult,
Progress,
StepStatus
} from './types';
export class TaskOrchestrator implements TaskOrchestrationEngine {
private plans: Map<string, TaskPlan> = new Map();
async plan(goal: string, context: any): Promise<TaskPlan> {
// TODO: 使用 AI 规划任务(后续实现)
// 这里先返回一个简单的示例计划
const steps: TaskStep[] = [
{
id: 'step_1',
description: '分析任务需求',
tool: 'ai',
params: { goal },
dependencies: [],
status: 'pending'
},
{
id: 'step_2',
description: '执行任务',
tool: 'executor',
params: { goal },
dependencies: ['step_1'],
status: 'pending'
},
{
id: 'step_3',
description: '整理结果',
tool: 'combiner',
params: {},
dependencies: ['step_2'],
status: 'pending'
}
];
const plan: TaskPlan = {
id: this.generateId(),
goal,
steps,
dependencies: new Map(),
context: new Map(Object.entries(context)),
status: 'planned',
progress: 0
};
this.plans.set(plan.id, plan);
console.log([TaskOrchestrator] Plan created: );
return plan;
}
async execute(plan: TaskPlan): Promise<ExecutionResult> {
plan.status = 'executing';
try {
// 拓扑排序
const sortedSteps = this.topologicalSort(plan.steps);
for (const step of sortedSteps) {
// 检查依赖
await this.waitForDependencies(step, plan);
// 执行步骤
step.status = 'running';
plan.progress = this.calculateProgress(plan);
console.log([TaskOrchestrator] Executing step: );
// TODO: 实际执行逻辑(后续实现)
await new Promise(resolve => setTimeout(resolve, 500));
step.status = 'completed';
step.result = { message: 'Step completed' };
plan.progress = this.calculateProgress(plan);
}
plan.status = 'completed';
plan.progress = 1;
return {
planId: plan.id,
status: 'completed',
results: plan.steps.map(s => s.result)
};
} catch (error: any) {
plan.status = 'failed';
throw error;
}
}
async getProgress(planId: string): Promise<Progress> {
const plan = this.plans.get(planId);
if (!plan) {
throw new Error(Plan not found: );
}
const completed = plan.steps.filter(s => s.status === 'completed').length;
const percentage = (plan.progress * 100).toFixed(1) + '%';
return {
planId: plan.id,
goal: plan.goal,
total: plan.steps.length,
completed,
current: plan.steps.find(s => s.status === 'running')?.description || '',
percentage,
steps: plan.steps.map(s => ({
description: s.description,
status: s.status,
result: s.result
}))
};
}
async pause(planId: string): Promise<void> {
const plan = this.plans.get(planId);
if (plan) {
plan.status = 'paused';
}
}
async resume(planId: string): Promise<void> {
const plan = this.plans.get(planId);
if (plan && plan.status === 'paused') {
plan.status = 'executing';
// 继续执行(后续实现)
}
}
async cancel(planId: string): Promise<void> {
const plan = this.plans.get(planId);
if (plan) {
plan.status = 'failed';
}
}
private topologicalSort(steps: TaskStep[]): TaskStep[] {
// 简单实现:按依赖顺序排序
const sorted: TaskStep[] = [];
const visited = new Set<string>();
const visit = (step: TaskStep) => {
if (visited.has(step.id)) return;
visited.add(step.id);
for (const depId of step.dependencies) {
const dep = steps.find(s => s.id === depId);
if (dep) visit(dep);
}
sorted.push(step);
};
steps.forEach(visit);
return sorted;
}
private async waitForDependencies(step: TaskStep, plan: TaskPlan): Promise<void> {
for (const depId of step.dependencies) {
const dep = plan.steps.find(s => s.id === depId);
if (dep && dep.status !== 'completed') {
// 等待依赖完成(简单实现)
await new Promise(resolve => setTimeout(resolve, 100));
}
}
}
private calculateProgress(plan: TaskPlan): number {
const completed = plan.steps.filter(s => s.status === 'completed').length;
return completed / plan.steps.length;
}
private generateId(): string {
return plan__;
}
}

View File

@@ -0,0 +1,53 @@
// 任务编排引擎 - 类型定义
export interface TaskPlan {
id: string;
goal: string;
steps: TaskStep[];
dependencies: Map<string, string[]>;
context: Map<string, any>;
status: PlanStatus;
progress: number;
}
export interface TaskStep {
id: string;
description: string;
tool: string;
params: any;
dependencies: string[];
status: StepStatus;
result?: any;
error?: string;
}
export type PlanStatus = 'planned' | 'executing' | 'completed' | 'failed' | 'paused';
export type StepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';
export interface ExecutionResult {
planId: string;
status: PlanStatus;
results: any[];
}
export interface Progress {
planId: string;
goal: string;
total: number;
completed: number;
current: string;
percentage: string;
steps: Array<{
description: string;
status: StepStatus;
result?: any;
}>;
}
export interface TaskOrchestrationEngine {
plan(goal: string, context: any): Promise<TaskPlan>;
execute(plan: TaskPlan): Promise<ExecutionResult>;
getProgress(planId: string): Promise<Progress>;
pause(planId: string): Promise<void>;
resume(planId: string): Promise<void>;
cancel(planId: string): Promise<void>;
}

5
src/index.ts Normal file
View File

@@ -0,0 +1,5 @@
// ZCLAW 入口文件
export * from './core/remote-execution';
export * from './core/task-orchestration';
export * from './core/memory';
export * from './core/proactive';