Files
qiming/qimingclaw/crates/agent-electron-client/docs/sandbox/SANDBOX-API.md

628 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 沙箱 API 接口文档
> **版本**: 1.0.0
> **更新**: 2026-03-22
> **状态**: 待实现
---
## 1. 概览
本文档定义 Qiming Agent 沙箱的 TypeScript/JavaScript API 接口。
---
## 2. 类型定义
### 2.1 核心类型
```typescript
// src/shared/types/sandbox.ts
export type Platform = 'darwin' | 'win32' | 'linux';
export type SandboxType = 'docker' | 'wsl' | 'firejail' | 'none';
export type PermissionLevel = 0 | 1 | 2 | 3;
export interface SandboxConfig {
type: SandboxType;
platform: Platform;
enabled: boolean;
workspaceRoot: string;
memoryLimit?: string; // 如 "2g"
cpuLimit?: number; // 如 2
diskQuota?: string; // 如 "10g"
networkEnabled?: boolean;
mode?: SandboxMode; // "strict" | "compat" | "permissive"
}
export interface Workspace {
id: string;
rootPath: string;
projectsPath: string;
nodeModulesPath: string;
pythonEnvPath: string;
binPath: string;
cachePath: string;
sandboxConfig: SandboxConfig;
createdAt: Date;
lastAccessedAt: Date;
retentionPolicy: RetentionPolicy;
}
export interface ExecuteOptions {
cwd?: string;
env?: Record<string, string>;
timeout?: number;
maxMemory?: string;
stdio?: 'pipe' | 'inherit';
permissionLevel?: PermissionLevel;
}
export interface ExecuteResult {
stdout: string;
stderr: string;
exitCode: number;
timedOut: boolean;
duration: number;
}
export interface RetentionPolicy {
mode: 'always' | 'timeout' | 'manual';
maxAge?: number;
maxWorkspaces?: number;
maxSize?: string;
preserveOnError?: boolean;
}
export interface Permission {
type: PermissionType;
target: string;
sessionId: string;
approvedBy: 'system' | 'user' | 'policy' | 'denied';
timestamp: Date;
reason?: string;
}
export type PermissionType =
| 'file:read'
| 'file:write'
| 'file:delete'
| 'command:execute'
| 'network:access'
| 'network:download'
| 'package:install:npm'
| 'package:install:python'
| 'package:install:system';
```
---
## 3. SandboxManager 接口
### 3.1 类签名
```typescript
// src/main/services/sandbox/SandboxManager.ts
export abstract class SandboxManager {
protected config: SandboxConfig;
protected workspaces: Map<string, Workspace>;
constructor(config: SandboxConfig);
// 初始化
abstract init(): Promise<void>;
// 检查沙箱是否可用
abstract isAvailable(): Promise<boolean>;
// 创建工作区
abstract createWorkspace(sessionId: string): Promise<Workspace>;
// 销毁工作区
abstract destroyWorkspace(sessionId: string): Promise<void>;
// 执行命令
abstract execute(
sessionId: string,
command: string,
args: string[],
options?: ExecuteOptions
): Promise<ExecuteResult>;
// 文件操作
abstract readFile(sessionId: string, path: string): Promise<string>;
abstract writeFile(sessionId: string, path: string, content: string): Promise<void>;
abstract readDir(sessionId: string, path: string): Promise<FileInfo[]>;
// 工作区信息
abstract getWorkspace(sessionId: string): Workspace | undefined;
abstract listWorkspaces(): Workspace[];
// 清理
abstract cleanup(): Promise<void>;
}
```
### 3.2 Docker 实现
```typescript
// src/main/services/sandbox/DockerSandbox.ts
export class DockerSandbox extends SandboxManager {
private containerIds: Map<string, string>;
constructor(config: SandboxConfig & {
dockerImage: string;
dockerHost?: string;
});
async init(): Promise<void>;
async isAvailable(): Promise<boolean>;
async createWorkspace(sessionId: string): Promise<Workspace>;
async destroyWorkspace(sessionId: string): Promise<void>;
async execute(
sessionId: string,
command: string,
args: string[],
options?: ExecuteOptions
): Promise<ExecuteResult>;
async readFile(sessionId: string, path: string): Promise<string>;
async writeFile(sessionId: string, path: string, content: string): Promise<void>;
// Docker 特有
async listContainers(): Promise<ContainerInfo[]>;
async getContainerLogs(sessionId: string): Promise<string>;
}
```
### 3.3 WSL 实现Windows
```typescript
// src/main/services/sandbox/WslSandbox.ts
export class WslSandbox extends SandboxManager {
private distribution: string;
private instanceId: string;
constructor(config: SandboxConfig & {
distribution: string;
});
async init(): Promise<void>;
async isAvailable(): Promise<boolean>;
async createWorkspace(sessionId: string): Promise<Workspace>;
async destroyWorkspace(sessionId: string): Promise<void>;
async execute(
sessionId: string,
command: string,
args: string[],
options?: ExecuteOptions
): Promise<ExecuteResult>;
}
```
### 3.4 Firejail 实现Linux
```typescript
// src/main/services/sandbox/FirejailSandbox.ts
export class FirejailSandbox extends SandboxManager {
private profiles: Map<string, string>;
constructor(config: SandboxConfig & {
profileDir?: string;
});
async init(): Promise<void>;
async isAvailable(): Promise<boolean>;
async createWorkspace(sessionId: string): Promise<Workspace>;
async destroyWorkspace(sessionId: string): Promise<void>;
async execute(
sessionId: string,
command: string,
args: string[],
options?: ExecuteOptions
): Promise<ExecuteResult>;
}
```
---
## 4. PermissionManager 接口
### 4.1 类签名
```typescript
// src/main/services/sandbox/PermissionManager.ts
export class PermissionManager {
private policy: PermissionPolicy;
private pendingRequests: Map<string, PermissionRequest>;
private approvedCache: Map<string, Permission>;
constructor(policy: PermissionPolicy);
// 检查权限
async checkPermission(
sessionId: string,
permission: PermissionType,
target: string
): Promise<PermissionResult>;
// 请求权限
async requestPermission(
sessionId: string,
permission: PermissionType,
target: string,
reason?: string
): Promise<Permission>;
// 批准权限
async approve(
requestId: string,
approvedBy: 'user' | 'system',
reason?: string
): Promise<void>;
// 拒绝权限
async deny(requestId: string, reason?: string): Promise<void>;
// 批量批准
async approveBatch(requestIds: string[]): Promise<void>;
// 获取待审批列表
getPendingRequests(sessionId?: string): PermissionRequest[];
// 清除缓存
clearCache(): void;
}
export interface PermissionPolicy {
autoApprove: PermissionType[]; // 自动批准的类型
requireConfirm: PermissionType[]; // 需要确认的类型
denyList: PermissionType[]; // 禁止的类型
workspaceOnly: boolean; // 是否只允许工作区操作
safeCommands: string[]; // 安全命令白名单
}
export interface PermissionResult {
allowed: boolean;
reason: string;
requestId?: string;
}
export interface PermissionRequest {
id: string;
sessionId: string;
type: PermissionType;
target: string;
reason?: string;
requestedAt: Date;
status: 'pending' | 'approved' | 'denied';
}
```
---
## 5. WorkspaceManager 接口
### 5.1 类签名
```typescript
// src/main/services/sandbox/WorkspaceManager.ts
export class WorkspaceManager {
private sandboxManager: SandboxManager;
private permissionManager: PermissionManager;
private workspaceStore: WorkspaceStore;
constructor(
sandboxManager: SandboxManager,
permissionManager: PermissionManager
);
// 工作区生命周期
async create(sessionId: string, options?: CreateWorkspaceOptions): Promise<Workspace>;
async destroy(sessionId: string, force?: boolean): Promise<void>;
async get(sessionId: string): Promise<Workspace | undefined>;
async list(): Promise<Workspace[]>;
// 工作区操作(带权限检查)
async readFile(sessionId: string, path: string): Promise<string>;
async writeFile(sessionId: string, path: string, content: string): Promise<void>;
async execute(
sessionId: string,
command: string,
args: string[],
options?: ExecuteOptions
): Promise<ExecuteResult>;
// 清理
async cleanupExpired(): Promise<CleanupResult>;
async cleanupAll(): Promise<void>;
// 保留策略
async setRetentionPolicy(sessionId: string, policy: RetentionPolicy): Promise<void>;
async getRetentionPolicy(sessionId: string): Promise<RetentionPolicy>;
}
export interface CreateWorkspaceOptions {
retention?: Partial<RetentionPolicy>;
platform?: Platform;
sandboxType?: SandboxType;
}
export interface CleanupResult {
deletedCount: number;
freedSpace: number;
errors: string[];
}
```
---
## 6. IPC 接口
### 6.1 IPC 通道定义
```typescript
// src/main/ipc/channels.ts
export const SANDBOX_CHANNELS = {
// 工作区管理
'sandbox:create': {
request: { sessionId: string },
response: Workspace
},
'sandbox:destroy': {
request: { sessionId: string, force?: boolean },
response: { success: boolean }
},
'sandbox:list': {
request: void,
response: Workspace[]
},
'sandbox:info': {
request: { sessionId: string },
response: Workspace | null
},
// 文件操作
'sandbox:readFile': {
request: { sessionId: string, path: string },
response: { content: string }
},
'sandbox:writeFile': {
request: { sessionId: string, path: string, content: string },
response: { success: boolean }
},
// 执行
'sandbox:execute': {
request: {
sessionId: string,
command: string,
args: string[],
options?: ExecuteOptions
},
response: ExecuteResult
},
// 权限
'sandbox:checkPermission': {
request: { sessionId: string, type: PermissionType, target: string },
response: PermissionResult
},
'sandbox:requestPermission': {
request: { sessionId: string, type: PermissionType, target: string, reason?: string },
response: Permission
},
'sandbox:getPendingPermissions': {
request: { sessionId?: string },
response: PermissionRequest[]
},
'sandbox:approvePermission': {
request: { requestId: string },
response: { success: boolean }
},
'sandbox:denyPermission': {
request: { requestId: string },
response: { success: boolean }
},
// 清理
'sandbox:cleanup': {
request: void,
response: CleanupResult
},
// 状态
'sandbox:status': {
request: void,
response: SandboxStatus
},
// 策略
'sandbox:policy:get': {
request: void,
response: SandboxPolicy
},
'sandbox:policy:set': {
request: Partial<SandboxPolicy>,
response: SandboxPolicy
},
'sandbox:capabilities': {
request: void,
response: SandboxCapabilities
},
// 后端初始化Windows Codex setup
'sandbox:setup': {
request: {
windows?: { codex?: { mode?: 'unelevated' | 'elevated' } }
},
response: { success: boolean; message?: string }
}
} as const;
export interface SandboxStatus {
available: boolean;
type: SandboxType;
backend?: SandboxBackend;
platform: Platform;
activeWorkspaces: number;
degraded?: boolean;
reason?: string;
capabilities?: SandboxCapabilities;
totalMemory?: string;
diskUsage?: string;
}
export interface SandboxPolicy {
enabled: boolean;
mode: SandboxMode; // "strict" | "compat" | "permissive"
backend: SandboxBackend; // "auto" | "docker" | "macos-seatbelt" | "linux-bwrap" | "windows-sandbox"
autoFallback: SandboxAutoFallback; // "startup-only" | "session" | "manual"
windowsMode: WindowsSandboxMode; // "read-only" | "workspace-write"
}
```
---
## 7. 事件
### 7.1 事件类型
```typescript
// src/shared/events/sandbox.ts
export const SANDBOX_EVENTS = {
// 工作区事件
'workspace:created': { workspace: Workspace };
'workspace:destroyed': { workspaceId: string };
'workspace:accessed': { workspaceId: string; timestamp: Date };
// 权限事件
'permission:requested': { request: PermissionRequest };
'permission:approved': { permission: Permission };
'permission:denied': { requestId: string; reason?: string };
// 执行事件
'execute:start': { sessionId: string; command: string };
'execute:complete': { sessionId: string; result: ExecuteResult };
'execute:error': { sessionId: string; error: string };
// 清理事件
'cleanup:start': void;
'cleanup:complete': { result: CleanupResult };
// 沙箱事件
'sandbox:unavailable': { reason: string };
'sandbox:recovered': void;
} as const;
```
---
## 8. 错误类型
### 8.1 错误类
```typescript
// src/shared/errors/sandbox.ts
export class SandboxError extends Error {
constructor(
message: string,
public code: SandboxErrorCode,
public sessionId?: string
);
}
export enum SandboxErrorCode {
SANDBOX_UNAVAILABLE = 'SANDBOX_UNAVAILABLE',
WORKSPACE_NOT_FOUND = 'WORKSPACE_NOT_FOUND',
WORKSPACE_EXISTS = 'WORKSPACE_EXISTS',
PERMISSION_DENIED = 'PERMISSION_DENIED',
EXECUTION_FAILED = 'EXECUTION_FAILED',
EXECUTION_TIMEOUT = 'EXECUTION_TIMEOUT',
FILE_NOT_FOUND = 'FILE_NOT_FOUND',
FILE_WRITE_FAILED = 'FILE_WRITE_FAILED',
CLEANUP_FAILED = 'CLEANUP_FAILED',
CONFIG_INVALID = 'CONFIG_INVALID'
}
```
---
## 9. 使用示例
### 9.1 创建工作区
```typescript
import { WorkspaceManager } from './services/sandbox/WorkspaceManager';
const workspaceManager = new WorkspaceManager(
new DockerSandbox({ type: 'docker', platform: 'darwin', enabled: true }),
new PermissionManager({ /* policy */ })
);
// 创建工作区
const workspace = await workspaceManager.create('session-123', {
retention: { mode: 'timeout', maxAge: 7 * 24 * 60 * 60 * 1000 }
});
console.log(`Workspace created at: ${workspace.rootPath}`);
```
### 9.2 执行命令
```typescript
// 检查权限
const result = await workspaceManager.execute(
'session-123',
'npm',
['install', 'lodash'],
{ cwd: workspace.projectsPath }
);
console.log(`Exit code: ${result.exitCode}`);
console.log(`Output: ${result.stdout}`);
```
### 9.3 权限请求
```typescript
// 请求安装包权限
const permission = await workspaceManager.permissionManager.requestPermission(
'session-123',
'package:install:npm',
'lodash',
'Need lodash for utility functions'
);
// 等待用户批准
if (permission.approvedBy === 'user') {
// 执行安装
}
```
---
## 10. 变更记录
| 日期 | 版本 | 变更 |
|------|------|------|
| 2026-03-22 | 1.0.0 | 初始版本 |