npm package: @lcap/wave-sandbox-sdk
Description: SDK for Wave Sandbox Client
Latest version: 0.0.7

# Wave Sandbox SDK

浏览器端的 Wave Sandbox SDK，用于与 Wave Sandbox Server 进行通信，提供文件系统操作、命令执行、端口监听和项目管理等功能。

## 安装

```bash
npm install wave-sandbox-sdk
# 或
pnpm add wave-sandbox-sdk
# 或
yarn add wave-sandbox-sdk
```

## 快速开始

```typescript
import { WaveSandboxClient } from 'wave-sandbox-sdk';

// 创建客户端实例
const client = new WaveSandboxClient({
  url: 'http://localhost:3030',
  projectId: 'optional-project-id', // 可选，用于工作空间模式
  options: {
    autoConnect: true,
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionAttempts: 5,
  },
});

// 监听连接事件
client.onConnect(() => {
  console.log('已连接到服务器');
});

// 使用各个模块...
```

## API 文档

### WaveSandboxClient

主客户端类，提供与服务器的连接和各个功能模块。

#### 构造函数

```typescript
new WaveSandboxClient(options: SDKOptions)
```

**参数：**

- `options.url` (string): 服务器地址，例如 `'http://localhost:3030'`
- `options.projectId` (string, 可选): 项目 ID，用于工作空间模式
- `options.options` (object, 可选): Socket.IO 连接选项
  - `autoConnect` (boolean): 是否自动连接，默认 `true`
  - `reconnection` (boolean): 是否自动重连，默认 `true`
  - `reconnectionDelay` (number): 重连延迟（毫秒），默认 `1000`
  - `reconnectionAttempts` (number): 最大重连次数，默认 `5`

#### 方法

- `connect()`: 手动连接到服务器
- `disconnect()`: 断开连接
- `onConnect(callback)`: 监听连接事件，返回取消监听的函数
- `onDisconnect(callback)`: 监听断开连接事件，返回取消监听的函数
- `onError(callback)`: 监听错误事件，返回取消监听的函数

#### 属性

- `connected` (boolean): 是否已连接
- `id` (string | undefined): Socket ID
- `exec`: 命令执行模块
- `fileSystem` / `fs`: 文件系统模块（`fs` 是 `fileSystem` 的简写别名）
- `port`: 端口监听模块
- `project`: 项目模块
- `agent`: Agent 模块

---

### 命令执行模块 (ExecModule)

执行命令并监听输出。

#### 方法

##### `exec(sessionId: string, command: string): Promise<number>`

执行命令。

**参数：**
- `sessionId`: 会话 ID，用于标识命令执行会话
- `command`: 要执行的命令

**返回：** Promise<number> 命令退出码

**示例：**
```typescript
const exitCode = await client.exec.exec('session-1', 'ls -la');
console.log('退出码:', exitCode);
```

##### `abort(sessionId: string): Promise<void>`

中止命令执行。

**参数：**
- `sessionId`: 会话 ID

**示例：**
```typescript
await client.exec.abort('session-1');
```

##### `onOutput(sessionId: string, callback: (data: Uint8Array) => void): () => void`

监听命令输出。

**参数：**
- `sessionId`: 会话 ID
- `callback`: 输出回调函数，接收 Uint8Array 数据

**返回：** 取消监听的函数

**示例：**
```typescript
const unsubscribe = client.exec.onOutput('session-1', (data) => {
  const text = new TextDecoder().decode(data);
  console.log('输出:', text);
});

// 取消监听
unsubscribe();
```

**完整示例：**
```typescript
const sessionId = 'my-session';

// 监听输出
const unsubscribe = client.exec.onOutput(sessionId, (data) => {
  const text = new TextDecoder().decode(data);
  process.stdout.write(text);
});

try {
  // 执行命令
  const exitCode = await client.exec.exec(sessionId, 'npm install');
  console.log(`命令执行完成，退出码: ${exitCode}`);
} catch (error) {
  console.error('执行失败:', error);
} finally {
  unsubscribe();
}
```

---

### 文件系统模块 (FileSystemModule)

提供文件系统操作功能。

#### 方法

##### `stat(filePath: string): Promise<FileStat>`

获取文件状态信息。

**参数：**
- `filePath`: 文件路径

**返回：** Promise<FileStat> 文件状态信息

**示例：**
```typescript
const stat = await client.fs.stat('package.json');
console.log('文件类型:', stat.type);
console.log('文件大小:', stat.size);
console.log('修改时间:', new Date(stat.mtime));
```

##### `readFile(filePath: string): Promise<string>`

读取文件内容（文本形式）。

**参数：**
- `filePath`: 文件路径

**返回：** Promise<string> 文件文本内容

**示例：**
```typescript
const content = await client.fs.readFile('package.json');
console.log(content);
```

##### `read(filePath: string, asText?: boolean): Promise<string | Blob>`

读取文件。

**参数：**
- `filePath`: 文件路径
- `asText`: 是否以文本形式读取，默认 `false`（返回 Blob）

**返回：** Promise<string | Blob> 文件内容

**示例：**
```typescript
// 读取文本文件
const text = await client.fs.read('readme.md', true);

// 读取二进制文件
const blob = await client.fs.read('image.png');
const url = URL.createObjectURL(blob);
```

##### `readdir(filePath: string): Promise<DirectoryItem[]>`

读取目录内容。

**参数：**
- `filePath`: 目录路径

**返回：** Promise<DirectoryItem[]> 目录项数组，每个项为 `[文件名, 文件类型]`

**示例：**
```typescript
const items = await client.fs.readdir('.');
items.forEach(([name, type]) => {
  console.log(`${name} - 类型: ${type}`);
});
```

##### `files(dirPath: string): Promise<Record<string, ProjectFile>>`

获取指定目录下的所有文件（递归）。

**参数：**
- `dirPath`: 目录路径

**返回：** Promise<Record<string, ProjectFile>> 文件路径到文件信息的映射

**示例：**
```typescript
const files = await client.fs.files('.');
Object.entries(files).forEach(([path, file]) => {
  console.log(`文件路径: ${path}`);
  console.log(`文件名: ${file.name}`);
  console.log(`MIME类型: ${file.type}`);
  console.log(`是否二进制: ${file.isBinary}`);
  console.log(`最后修改时间: ${new Date(file.lastModified)}`);
  console.log(`文件大小: ${file.size} 字节`);
});
```

##### `writeFile(filePath: string, data: string | Blob | ArrayBuffer | Uint8Array, chunkSize?: number): Promise<void>`

写入文件（流式）。

**参数：**
- `filePath`: 文件路径
- `data`: 文件数据（可以是字符串、Blob、ArrayBuffer 或 Uint8Array）
- `chunkSize`: 分块大小（字节），默认 64KB

**示例：**
```typescript
// 写入文本
await client.fs.writeFile('test.txt', 'Hello World');

// 写入二进制数据
const buffer = new Uint8Array([1, 2, 3, 4, 5]);
await client.fs.writeFile('data.bin', buffer);

// 写入 Blob
const blob = new Blob(['content'], { type: 'text/plain' });
await client.fs.writeFile('file.txt', blob);
```

##### `mkdir(filePath: string): Promise<string | undefined>`

创建目录。

**参数：**
- `filePath`: 目录路径

**示例：**
```typescript
await client.fs.mkdir('new-folder');
```

##### `rename(oldPath: string, newPath: string): Promise<void>`

重命名文件或目录。

**参数：**
- `oldPath`: 原路径
- `newPath`: 新路径

**示例：**
```typescript
await client.fs.rename('old.txt', 'new.txt');
```

##### `rm(filePath: string): Promise<void>`

删除文件或目录。

**参数：**
- `filePath`: 文件或目录路径

**示例：**
```typescript
await client.fs.rm('file.txt');
await client.fs.rm('directory');
```

##### `watch(paths: string[], ignored: string[], callback: (event: FileChangeEvent) => void): () => void`

监听文件变化。

**参数：**
- `paths`: 要监听的文件路径数组
- `ignored`: 要忽略的文件路径数组
- `callback`: 文件变化回调函数

**返回：** 取消监听的函数

**示例：**
```typescript
const unsubscribe = client.fs.watch(
  ['.'],
  ['node_modules', '.git'],
  (event) => {
    console.log(`文件 ${event.type}: ${event.path}`);
  }
);

// 取消监听
unsubscribe();
```

---

### 端口监听模块 (PortModule)

监听端口状态变化。

#### 方法

##### `getPorts(count?: number): Promise<number[]>`

获取可用端口。

**参数：**
- `count`: 需要获取的端口数量，默认 `2`

**返回：** Promise<number[]> 可用端口数组

**示例：**
```typescript
const ports = await client.port.getPorts(3);
console.log('可用端口:', ports); // [6606, 6607, 6608]
```

##### `startWatch(ports: number[]): Promise<void>`

开始监听端口状态。

**参数：**
- `ports`: 要监听的端口数组

**示例：**
```typescript
await client.port.startWatch([3000, 3001]);
```

##### `stopWatch(): Promise<void>`

停止监听端口状态。

**示例：**
```typescript
await client.port.stopWatch();
```

##### `onStatusChanged(callback: (event: PortStatusChangedEvent) => void): () => void`

监听端口状态变化。

**参数：**
- `callback`: 端口状态变化回调函数

**返回：** 取消监听的函数

**示例：**
```typescript
const unsubscribe = client.port.onStatusChanged((event) => {
  console.log(`端口 ${event.port} 状态: ${event.type}`);
});

// 取消监听
unsubscribe();
```

**完整示例：**
```typescript
// 获取可用端口
const ports = await client.port.getPorts(2);

// 监听端口状态变化
const unsubscribe = client.port.onStatusChanged((event) => {
  if (event.type === 'open') {
    console.log(`端口 ${event.port} 已打开`);
  } else {
    console.log(`端口 ${event.port} 已关闭`);
  }
});

// 开始监听
await client.port.startWatch(ports);

// 停止监听
await client.port.stopWatch();
unsubscribe();
```

---

### 项目模块 (ProjectModule)

管理项目信息和文件。

#### 方法

##### `getInfo(): Promise<ProjectInfo>`

获取项目信息。

**返回：** Promise<ProjectInfo> 项目信息

**示例：**
```typescript
const info = await client.project.getInfo();
console.log('项目 ID:', info.projectId);
console.log('工作目录:', info.workdir);
console.log('工作空间模式:', info.workspace);
```

##### `getFiles(): Promise<ProjectFile[]>`

获取项目文件列表（仅返回文件，不包含目录）。

**返回：** Promise<ProjectFile[]> 项目文件数组

**示例：**
```typescript
const files = await client.project.getFiles();
files.forEach((file) => {
  console.log('文件路径:', file.path);
  console.log('文件名:', file.name);
  console.log('MIME类型:', file.type);
  console.log('是否二进制:', file.isBinary);
  console.log('最后修改时间:', new Date(file.lastModified));
  console.log('文件大小:', file.size, '字节');
});
```

##### `watch(): Promise<void>`

开始监听项目变化。

**示例：**
```typescript
await client.project.watch();
```

##### `unwatch(): Promise<void>`

停止监听项目变化。

**示例：**
```typescript
await client.project.unwatch();
```

##### `onFileChange(callback: (event: unknown) => void): () => void`

监听项目文件变化。

**参数：**
- `callback`: 文件变化回调函数

**返回：** 取消监听的函数

**示例：**
```typescript
const unsubscribe = client.project.onFileChange((event) => {
  console.log('项目文件变化:', event);
});

// 取消监听
unsubscribe();
```

---

### Agent 模块 (AgentModule)

与 AI Agent 进行交互，发送消息并监听 Agent 的各种事件。

#### 方法

##### `sendMessage(options: SendMessageOptions): Promise<string>`

发送消息给 Agent。

**参数：**
- `options.id`: 消息 ID
- `options.sessionId`: 会话 ID
- `options.message`: 消息内容
- `options.attachments`: 附件数组（可选）

**返回：** Promise<string> 返回 assistantMessageId

**示例：**
```typescript
const assistantMessageId = await client.agent.sendMessage({
  id: 'msg-1',
  sessionId: 'session-1',
  message: 'Hello, agent!',
  attachments: [
    {
      path: './file.txt',
      mimeType: 'text/plain',
    },
  ],
});
console.log('Assistant Message ID:', assistantMessageId);
```

##### `abortMessage(messageId: string): Promise<void>`

中止消息处理。

**参数：**
- `messageId`: 要中止的消息 ID

**示例：**
```typescript
await client.agent.abortMessage('msg-1');
```

##### `removeSession(sessionId: string): Promise<void>`

删除 session，包括日志记录和 agent 对象。如果当前正在处理该 session 的消息，则抛出错误。

**参数：**
- `sessionId`: 要删除的会话 ID

**抛出：**
- 如果当前正在处理该 session 的消息，则抛出错误

**示例：**
```typescript
try {
  await client.agent.removeSession('session-1');
  console.log('Session 已删除');
} catch (error) {
  console.error('删除失败:', error.message);
  // 如果当前正在处理该 session 的消息，会抛出错误
}
```

#### 事件监听

##### `onMessageSend(callback: (event: MessageSendEvent) => void): () => void`

监听消息发送事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageSend((event) => {
  console.log('消息已发送:', event.assistantMessageId);
});
```

##### `onMessageRunning(callback: (event: MessageRunningEvent) => void): () => void`

监听消息运行事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageRunning((event) => {
  console.log('消息运行中:', event.assistantMessageId);
});
```

##### `onMessageFinished(callback: (event: MessageFinishedEvent) => void): () => void`

监听消息完成事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageFinished((event) => {
  console.log('消息完成:', event.status);
});
```

##### `onMessageQueueChanged(callback: (event: MessageQueueChangedEvent) => void): () => void`

监听消息队列变化事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageQueueChanged((event) => {
  console.log('队列长度:', event.queue.length);
  console.log('当前消息:', event.current);
});
```

##### `onInitializing(callback: (event: InitializingEvent) => void): () => void`

监听 Agent 初始化事件。

**示例：**
```typescript
const unsubscribe = client.agent.onInitializing((event) => {
  console.log('Agent 初始化中:', event.sessionId);
});
```

##### `onInitialized(callback: (event: InitializedEvent) => void): () => void`

监听 Agent 初始化完成事件。

**示例：**
```typescript
const unsubscribe = client.agent.onInitialized((event) => {
  console.log('Agent 初始化完成:', event.sessionId);
});
```

##### `onMessageBlockAdded(callback: (event: MessageBlockAddedEvent) => void): () => void`

监听消息块添加事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageBlockAdded((event) => {
  event.data.blocks.forEach((block) => {
    console.log('添加块:', block.type);
  });
});
```

##### `onMessageBlockUpdated(callback: (event: MessageBlockUpdatedEvent) => void): () => void`

监听消息块更新事件（用于流式内容更新）。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageBlockUpdated((event) => {
  console.log('消息块更新:', event.data.type, event.data.content);
});
```

##### `onMessageToolBlockUpdated(callback: (event: MessageToolBlockUpdatedEvent) => void): () => void`

监听工具块更新事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageToolBlockUpdated((event) => {
  console.log('工具块更新:', event.data.name, event.data.stage);
});
```

##### `onMessageSubagentBlockStatusUpdated(callback: (event: MessageSubagentBlockStatusUpdatedEvent) => void): () => void`

监听子代理块状态更新事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageSubagentBlockStatusUpdated((event) => {
  console.log('子代理状态更新:', event.data.status);
});
```

##### `onMessageSubagentBlockContentUpdated(callback: (event: MessageSubagentBlockContentUpdatedEvent) => void): () => void`

监听子代理块内容更新事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageSubagentBlockContentUpdated((event) => {
  console.log('子代理内容更新:', event.data.content);
});
```

##### `onMessageErrorBlockAdded(callback: (event: MessageErrorBlockAddedEvent) => void): () => void`

监听错误块添加事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageErrorBlockAdded((event) => {
  console.error('错误:', event.data.error);
});
```

##### `onMessageCommandOutputMessageAdded(callback: (event: MessageCommandOutputMessageAddedEvent) => void): () => void`

监听命令输出消息添加事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageCommandOutputMessageAdded((event) => {
  console.log('命令输出开始:', event.data.command);
});
```

##### `onMessageCommandOutputMessageUpdated(callback: (event: MessageCommandOutputMessageUpdatedEvent) => void): () => void`

监听命令输出消息更新事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageCommandOutputMessageUpdated((event) => {
  console.log('命令输出更新:', event.data.command, event.data.output);
});
```

##### `onMessageCommandOutputMessageCompleted(callback: (event: MessageCommandOutputMessageCompletedEvent) => void): () => void`

监听命令输出消息完成事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMessageCommandOutputMessageCompleted((event) => {
  console.log('命令完成:', event.data.command, '退出码:', event.data.exitCode);
});
```

##### `onMcpServersChange(callback: (event: McpServersChangeEvent) => void): () => void`

监听 MCP 服务器变化事件。

**示例：**
```typescript
const unsubscribe = client.agent.onMcpServersChange((event) => {
  console.log('MCP 服务器变化:', event.servers);
});
```

##### `onDocumentParseStart(callback: (event: DocumentParseStartEvent) => void): () => void`

监听文档解析开始事件。

**示例：**
```typescript
const unsubscribe = client.agent.onDocumentParseStart((event) => {
  console.log('文档解析开始:', event.url, event.mimeType);
});
```

##### `onDocumentParseComplete(callback: (event: DocumentParseCompleteEvent) => void): () => void`

监听文档解析完成事件。

**示例：**
```typescript
const unsubscribe = client.agent.onDocumentParseComplete((event) => {
  console.log('文档解析完成:', event.outputPath, `共 ${event.pageCount} 页`);
});
```

##### `onDocumentParseError(callback: (event: DocumentParseErrorEvent) => void): () => void`

监听文档解析错误事件。

**示例：**
```typescript
const unsubscribe = client.agent.onDocumentParseError((event) => {
  console.error('文档解析失败:', event.error);
});
```

##### `on<T = unknown>(eventName: string, callback: (event: T) => void): () => void`

通用事件监听方法，用于监听自定义事件。事件名称必须以 `'agent:'` 开头。支持泛型参数指定事件数据类型。

**示例：**
```typescript
// 监听自定义事件，使用泛型指定事件类型
interface CustomEventData {
  data: string;
  timestamp: number;
}

const unsubscribe = client.agent.on<CustomEventData>('agent:custom-event', (event) => {
  console.log('自定义事件:', event.data);
  console.log('时间戳:', event.timestamp);
  // event 的类型自动推断为 CustomEventData，无需类型断言
});

// 监听其他自定义事件，使用泛型
const unsubscribe2 = client.agent.on<{ message: string }>('agent:another-custom-event', (event) => {
  console.log('消息:', event.message);
});

// 不指定泛型时，event 类型为 unknown
const unsubscribe3 = client.agent.on('agent:unknown-event', (event) => {
  // event 类型为 unknown，需要类型断言
  const typedEvent = event as { value: number };
  console.log('值:', typedEvent.value);
});
```

**完整示例：**
```typescript
const sessionId = 'my-session';

// 监听消息完成事件
const unsubscribeFinished = client.agent.onMessageFinished((event) => {
  console.log('消息处理完成:', event.status);
});

// 监听消息块添加事件
const unsubscribeBlockAdded = client.agent.onMessageBlockAdded((event) => {
  event.data.blocks.forEach((block) => {
    if (block.type === 'text') {
      console.log('文本块:', block.content);
    } else if (block.type === 'tool') {
      console.log('工具块:', block.name);
    }
  });
});

try {
  // 发送消息
  const assistantMessageId = await client.agent.sendMessage({
    id: 'msg-1',
    sessionId,
    message: '请帮我创建一个文件',
  });

  console.log('消息已发送，等待处理...');
} catch (error) {
  console.error('发送失败:', error);
} finally {
  // 取消监听
  unsubscribeFinished();
  unsubscribeBlockAdded();
}
```

---

## 类型定义

### FileStat

```typescript
interface FileStat {
  type: FileType;      // 文件类型
  size: number;        // 文件大小（字节）
  ctime: number;       // 创建时间（毫秒时间戳）
  mtime: number;       // 修改时间（毫秒时间戳）
}
```

### FileType

```typescript
enum FileType {
  Unknown = 0,
  File = 1,
  Directory = 2,
  SymbolicLink = 64,
}
```

### FileChangeEvent

```typescript
interface FileChangeEvent {
  type: 'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir';
  path: string;
  /** 是否为二进制文件（仅在 add 和 change 事件中存在） */
  isBinary?: boolean;
  /** 最后修改时间（毫秒时间戳，仅在文件事件中存在） */
  lastModified?: number;
  /** 文件大小（字节，仅在文件事件中存在） */
  size?: number;
}
```

### PortStatusChangedEvent

```typescript
interface PortStatusChangedEvent {
  port: number;
  type: 'open' | 'close';
}
```

### ProjectInfo

```typescript
interface ProjectInfo {
  projectId: string;
  workdir: string;
  workspace: boolean;
}
```

### ProjectFile

```typescript
interface ProjectFile {
  path: string;           // 文件相对路径
  name: string;            // 文件名
  type: string;            // MIME 类型
  isBinary: boolean;       // 是否为二进制文件
  lastModified: number;    // 最后修改时间（毫秒时间戳）
  size: number;           // 文件大小（字节）
}
```

### SendMessageOptions

```typescript
interface SendMessageOptions {
  id: string;
  sessionId: string;
  message: string;
  attachments?: Attachment[];
}
```

### Attachment

```typescript
interface Attachment {
  url?: string;
  path?: string;
  mimeType: string;
  content?: string;
}
```

### MessageSendEvent

```typescript
interface MessageSendEvent {
  sessionId: string;
  assistantMessageId: string;
  senderMessageId: string;
  options: SendMessageOptions;
}
```

### MessageRunningEvent

```typescript
interface MessageRunningEvent {
  sessionId: string;
  assistantMessageId: string;
  senderMessageId: string;
}
```

### MessageFinishedEvent

```typescript
interface MessageFinishedEvent {
  sessionId: string;
  assistantMessageId?: string;
  senderMessageId: string;
  status: 'pending' | 'running' | 'finished' | 'error' | 'aborted';
}
```

### MessageQueueChangedEvent

```typescript
interface MessageQueueChangedEvent {
  queue: ProcessQueueItem[];
  current: {
    sessionId: string;
    assistantMessageId?: string;
    senderMessageId: string;
  };
}
```

### MessageBlockAddedEvent

```typescript
interface MessageBlockAddedEvent {
  sessionId: string;
  assistantMessageId?: string;
  senderMessageId: string;
  data: {
    blocks: Array<TextBlock | ToolBlock | ErrorBlock | SubagentBlock>;
  };
}
```

### MessageBlockUpdatedEvent

```typescript
interface MessageBlockUpdatedEvent {
  sessionId: string;
  assistantMessageId?: string;
  senderMessageId: string;
  data: {
    type: 'text';
    content: string;
  };
}
```

### MessageToolBlockUpdatedEvent

```typescript
interface MessageToolBlockUpdatedEvent {
  sessionId: string;
  assistantMessageId?: string;
  senderMessageId: string;
  data: ToolBlock;
}
```

### DocumentParseStartEvent

```typescript
interface DocumentParseStartEvent {
  sessionId: string;
  senderMessageId: string;
  index: number;
  url: string;
  mimeType: string;
}
```

### DocumentParseCompleteEvent

```typescript
interface DocumentParseCompleteEvent {
  sessionId: string;
  senderMessageId: string;
  index: number;
  url: string;
  mimeType: string;
  outputPath: string;
  contentLength?: number;
  pageCount?: number;
}
```

### DocumentParseErrorEvent

```typescript
interface DocumentParseErrorEvent {
  sessionId: string;
  senderMessageId: string;
  index: number;
  url: string;
  mimeType: string;
  error: string;
}
```

### AgentEventMap

Agent 预定义事件名称到事件数据类型的映射，用于类型定义和类型推断。

```typescript
type AgentEventMap = {
  'agent:message-send': MessageSendEvent;
  'agent:message-running': MessageRunningEvent;
  'agent:message-finished': MessageFinishedEvent;
  'agent:message-queue-changed': MessageQueueChangedEvent;
  'agent:initializing': InitializingEvent;
  'agent:initialized': InitializedEvent;
  'agent:message-block-added': MessageBlockAddedEvent;
  'agent:message-block-updated': MessageBlockUpdatedEvent;
  'agent:message-tool-block-updated': MessageToolBlockUpdatedEvent;
  'agent:message-subagent-block-status-updated': MessageSubagentBlockStatusUpdatedEvent;
  'agent:message-subagent-block-content-updated': MessageSubagentBlockContentUpdatedEvent;
  'agent:message-error-block-added': MessageErrorBlockAddedEvent;
  'agent:message-command-output-message-added': MessageCommandOutputMessageAddedEvent;
  'agent:message-command-output-message-updated': MessageCommandOutputMessageUpdatedEvent;
  'agent:message-command-output-message-completed': MessageCommandOutputMessageCompletedEvent;
  'agent:mcp-servers-change': McpServersChangeEvent;
  'agent:document-parse-start': DocumentParseStartEvent;
  'agent:document-parse-complete': DocumentParseCompleteEvent;
  'agent:document-parse-error': DocumentParseErrorEvent;
};
```

### AgentEventName

Agent 预定义事件名称类型，是 `AgentEventMap` 的键类型。

```typescript
type AgentEventName = keyof AgentEventMap;
```

---

## 完整示例

```typescript
import { WaveSandboxClient } from 'wave-sandbox-sdk';

async function main() {
  // 创建客户端
  const client = new WaveSandboxClient({
    url: 'http://localhost:3030',
    projectId: 'my-project',
  });

  // 等待连接
  await new Promise<void>((resolve) => {
    if (client.connected) {
      resolve();
    } else {
      client.onConnect(() => resolve());
    }
  });

  try {
    // 读取文件
    const content = await client.fs.readFile('package.json');
    console.log('文件内容:', content);

    // 写入文件
    await client.fs.writeFile('test.txt', 'Hello World');

    // 执行命令
    const sessionId = 'session-1';
    client.exec.onOutput(sessionId, (data) => {
      console.log(new TextDecoder().decode(data));
    });
    const exitCode = await client.exec.exec(sessionId, 'ls -la');
    console.log('退出码:', exitCode);

    // 获取可用端口
    const ports = await client.port.getPorts(2);
    console.log('可用端口:', ports);

    // 监听文件变化
    const unsubscribe = client.fs.watch(['.'], ['node_modules'], (event) => {
      console.log(`文件 ${event.type}: ${event.path}`);
    });

    // 使用 Agent 模块
    const sessionId = 'my-session';
    client.agent.onMessageFinished((event) => {
      console.log('Agent 消息完成:', event.status);
    });
    const assistantMessageId = await client.agent.sendMessage({
      id: 'msg-1',
      sessionId,
      message: 'Hello, agent!',
    });
    console.log('Assistant Message ID:', assistantMessageId);

    // 删除 session（确保没有正在处理的消息）
    try {
      await client.agent.removeSession(sessionId);
      console.log('Session 已删除');
    } catch (error) {
      console.error('删除失败:', error.message);
    }

    // 5 秒后取消监听
    setTimeout(() => {
      unsubscribe();
    }, 5000);
  } catch (error) {
    console.error('错误:', error);
  } finally {
    // 断开连接
    client.disconnect();
  }
}

main();
```

---

## License

MIT