第十三章:技术栈分析
📚 本章详细分析 MiniClaw 使用的技术栈和依赖。
13.1 核心依赖
13.1.1 @modelcontextprotocol/sdk(MCP SDK)
┌─────────────────────────────────────────────────────────────────────┐
│ MCP SDK 分析 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 包名:@modelcontextprotocol/sdk │
│ 版本:^1.0.0 │
│ 来源:Anthropic 官方 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 核心组件: │ │
│ │ ├── Server // MCP 服务器类 │ │
│ │ ├── StdioServerTransport // 标准输入输出传输层 │ │
│ │ ├── ListResourcesRequestSchema │ │
│ │ ├── ReadResourceRequestSchema │ │
│ │ ├── ListToolsRequestSchema │ │
│ │ ├── CallToolRequestSchema │ │
│ │ ├── ListPromptsRequestSchema │ │
│ │ └── GetPromptRequestSchema │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 使用示例: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ import { Server } from '@modelcontextprotocol/sdk/server'; │ │
│ │ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';│
│ │ │ │
│ │ const server = new Server( │ │
│ │ { name: "miniclaw", version: "0.5.0" }, │ │
│ │ { capabilities: { resources: {}, tools: {}, prompts: {} } }│ │
│ │ ); │ │
│ │ │ │
│ │ const transport = new StdioServerTransport(); │ │
│ │ await server.connect(transport); │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.1.2 node-cron(调度器)
┌─────────────────────────────────────────────────────────────────────┐
│ node-cron 分析 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 包名:node-cron │
│ 版本:^3.0.0 │
│ 功能:基于 cron 表达式的任务调度 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ MiniClaw 使用场景: │ │
│ │ • 心跳检测调度(每 30 分钟) │ │
│ │ • 日志检查 │ │
│ │ • 蒸馏评估 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 使用示例: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ import cron from 'node-cron'; │ │
│ │ │ │
│ │ // 每 30 分钟执行心跳 │ │
│ │ cron.schedule('*/30 * * * *', async () => { │ │
│ │ await executeHeartbeat(); │ │
│ │ }); │ │
│ │ │ │
│ │ // Cron 表达式说明 │ │
│ │ // ┌───────────── 分钟 (0-59) │ │
│ │ // │ ┌───────────── 小时 (0-23) │ │
│ │ // │ │ ┌───────────── 日期 (1-31) │ │
│ │ // │ │ │ ┌───────────── 月份 (1-12) │ │
│ │ // │ │ │ │ ┌───────────── 星期 (0-7) │ │
│ │ // │ │ │ │ │ │ │
│ │ // * * * * * │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.1.3 zod(参数验证)
┌─────────────────────────────────────────────────────────────────────┐
│ zod 分析 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 包名:zod │
│ 版本:^3.22.0 │
│ 功能:TypeScript 优先的 schema 声明和验证库 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ MiniClaw 使用场景: │ │
│ │ • 工具参数验证 │ │
│ │ • 类型安全 │ │
│ │ • 错误提示 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 使用示例: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ import { z } from 'zod'; │ │
│ │ │ │
│ │ // 定义 Schema │ │
│ │ const UpdateSchema = z.object({ │ │
│ │ file: z.enum(['AGENTS.md', 'SOUL.md', 'USER.md']), │ │
│ │ content: z.string().max(50000), │ │
│ │ mode: z.enum(['append', 'replace']).optional(), │ │
│ │ }); │ │
│ │ │ │
│ │ // 使用验证 │ │
│ │ const validated = UpdateSchema.parse(args); │ │
│ │ // validated.file → 类型安全访问 │ │
│ │ // validated.content → 类型安全访问 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 常用验证方法: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ z.string() → 字符串验证 │ │
│ │ z.number() → 数字验证 │ │
│ │ z.boolean() → 布尔验证 │ │
│ │ z.enum([...]) → 枚举验证 │ │
│ │ z.object({...}) → 对象验证 │ │
│ │ z.array(...) → 数组验证 │ │
│ │ .optional() → 可选字段 │ │
│ │ .default(...) → 默认值 │ │
│ │ .min(n) → 最小值/长度 │ │
│ │ .max(n) → 最大值/长度 │ │
│ │ .refine(fn) → 自定义验证 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.2 开发依赖
13.2.1 TypeScript
┌─────────────────────────────────────────────────────────────────────┐
│ TypeScript 分析 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 包名:typescript │
│ 版本:^5.0.0 │
│ 功能:JavaScript 超集,提供静态类型检查 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ MiniClaw 使用特性: │ │
│ │ ├── 严格模式 (strict: true) │ │
│ │ ├── ES Module 支持 │ │
│ │ ├── 接口定义 │ │
│ │ ├── 类型推断 │ │
│ │ └── 泛型 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 类型定义示例: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ // 接口定义 │ │
│ │ interface Entity { │ │
│ │ name: string; │ │
│ │ type: EntityType; │ │
│ │ attributes: Record<string, string>; │ │
│ │ relations: string[]; │ │
│ │ mentionCount: number; │ │
│ │ } │ │
│ │ │ │
│ │ // 类型别名 │ │
│ │ type TimeMode = 'morning' | 'work' | 'break' | 'evening' | 'night';│
│ │ type ContextMode = 'full' | 'minimal'; │ │
│ │ │ │
│ │ // 泛型使用 │ │
│ │ class SkillCache { │ │
│ │ private cache: Map<string, SkillCacheEntry>; │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.2.2 @types/node
┌─────────────────────────────────────────────────────────────────────┐
│ @types/node 分析 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 包名:@types/node │
│ 版本:^20.0.0 │
│ 功能:Node.js 类型定义 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 提供类型定义的 Node.js API: │ │
│ │ ├── fs/promises → 文件系统 Promise API │ │
│ │ ├── path → 路径处理 │ │
│ │ ├── os → 操作系统信息 │ │
│ │ ├── crypto → 加密哈希 │ │
│ │ ├── child_process → 子进程 │ │
│ │ └── process → 进程信息 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.2.3 @types/node-cron
┌─────────────────────────────────────────────────────────────────────┐
│ @types/node-cron 分析 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 包名:@types/node-cron │
│ 版本:^3.0.0 │
│ 功能:node-cron 类型定义 │
│ │
│ 类型定义示例: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ declare module 'node-cron' { │ │
│ │ export function schedule( │ │
│ │ expression: string, │ │
│ │ func: () => void | Promise<void>, │ │
│ │ options?: ScheduleOptions │ │
│ │ ): ScheduledTask; │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.3 Node.js API 使用
13.3.1 fs/promises(文件系统)
┌─────────────────────────────────────────────────────────────────────┐
│ fs/promises 使用 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ import { promises as fs } from 'fs'; │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ MiniClaw 使用场景: │ │
│ │ ├── 读取模板文件 │ │
│ │ ├── 写入日志文件 │ │
│ │ ├── 创建目录 │ │
│ │ ├── 检查文件存在 │ │
│ │ └── 扫描技能目录 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 常用方法: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ // 读取文件 │ │
│ │ const content = await fs.readFile(path, 'utf-8'); │ │
│ │ │ │
│ │ // 写入文件 │ │
│ │ await fs.writeFile(path, content, 'utf-8'); │ │
│ │ │ │
│ │ // 追加内容 │ │
│ │ await fs.appendFile(path, content, 'utf-8'); │ │
│ │ │ │
│ │ // 检查文件存在 │ │
│ │ await fs.access(path); // 不存在则抛出异常 │ │
│ │ │ │
│ │ // 创建目录 │ │
│ │ await fs.mkdir(dir, { recursive: true }); │ │
│ │ │ │
│ │ // 读取目录 │ │
│ │ const files = await fs.readdir(dir); │ │
│ │ │ │
│ │ // 获取文件信息 │ │
│ │ const stat = await fs.stat(path); │ │
│ │ console.log(stat.size, stat.mtime); │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.3.2 path(路径处理)
┌─────────────────────────────────────────────────────────────────────┐
│ path 使用 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ import path from 'path'; │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ MiniClaw 使用场景: │ │
│ │ ├── 构建文件路径 │ │
│ │ ├── 获取文件扩展名 │ │
│ │ ├── 解析路径组件 │ │
│ │ └── 跨平台路径兼容 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 常用方法: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ // 路径拼接 │ │
│ │ const fullPath = path.join(baseDir, 'memory', 'log.md'); │ │
│ │ │ │
│ │ // 获取目录名 │ │
│ │ const dir = path.dirname('/home/user/file.txt'); │ │
│ │ // → '/home/user' │ │
│ │ │ │
│ │ // 获取文件名 │ │
│ │ const name = path.basename('/home/user/file.txt'); │ │
│ │ // → 'file.txt' │ │
│ │ │ │
│ │ // 获取扩展名 │ │
│ │ const ext = path.extname('file.md'); │ │
│ │ // → '.md' │ │
│ │ │ │
│ │ // 解析路径 │ │
│ │ const parsed = path.parse('/home/user/file.txt'); │ │
│ │ // { root, dir, base, ext, name } │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.3.3 os(系统信息)
┌─────────────────────────────────────────────────────────────────────┐
│ os 使用 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ import os from 'os'; │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ MiniClaw 使用场景: │ │
│ │ ├── 获取用户主目录 │ │
│ │ ├── 获取系统平台 │ │
│ │ ├── 获取主机名 │ │
│ │ └── 获取用户信息 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 常用方法: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ // 获取主目录 │ │
│ │ const homeDir = os.homedir(); │ │
│ │ // → '/Users/username' 或 'C:\Users\username' │ │
│ │ │ │
│ │ // 获取平台 │ │
│ │ const platform = os.platform(); │ │
│ │ // → 'darwin', 'win32', 'linux' │ │
│ │ │ │
│ │ // 获取主机名 │ │
│ │ const hostname = os.hostname(); │ │
│ │ │ │
│ │ // 获取用户信息 │ │
│ │ const userInfo = os.userInfo(); │ │
│ │ // { username, homedir, shell } │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.3.4 crypto(哈希计算)
┌─────────────────────────────────────────────────────────────────────┐
│ crypto 使用 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ import crypto from 'crypto'; │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ MiniClaw 使用场景: │ │
│ │ • 内容哈希计算(用于差异检测) │ │
│ │ • 检测上下文变化 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 使用示例: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ // 计算内容哈希 │ │
│ │ function hashString(content: string): string { │ │
│ │ return crypto │ │
│ │ .createHash('md5') │ │
│ │ .update(content) │ │
│ │ .digest('hex') │ │
│ │ .slice(0, 8); // 取前 8 位 │ │
│ │ } │ │
│ │ │ │
│ │ // 使用哈希检测变化 │ │
│ │ const currentHash = hashString(content); │ │
│ │ if (currentHash !== previousHash) { │ │
│ │ // 内容已变化 │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.3.5 child_process(命令执行)
┌─────────────────────────────────────────────────────────────────────┐
│ child_process 使用 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ import { exec } from 'child_process'; │
│ import { promisify } from 'util'; │
│ const execAsync = promisify(exec); │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ MiniClaw 使用场景: │ │
│ │ • 执行安全命令 │ │
│ │ • 获取 Git 状态 │ │
│ │ • 检测技术栈 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 使用示例: │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ // 执行命令 │ │
│ │ async function execCommand(cmd: string): Promise<string> { │ │
│ │ const { stdout } = await execAsync(cmd, { │ │
│ │ timeout: 10000, // 10 秒超时 │ │
│ │ maxBuffer: 1024 * 1024, // 1MB 输出限制 │ │
│ │ cwd: process.cwd(), // 工作目录限制 │ │
│ │ }); │ │
│ │ return stdout; │ │
│ │ } │ │
│ │ │ │
│ │ // 获取 Git 分支 │ │
│ │ const branch = await execCommand('git branch --show-current');│
│ │ │ │
│ │ // 检测 package.json │ │
│ │ const pkgContent = await execCommand('cat package.json'); │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
13.4 依赖关系图
┌─────────────────────────────────────────────────────────────────────┐
│ 依赖关系图 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ MiniClaw │ │
│ └──────┬──────┘ │
│ │ │
│ ┌───────────────────┼───────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ MCP SDK │ │ node-cron │ │ zod │ │
│ │ (协议实现) │ │ (任务调度) │ │ (参数验证) │ │
│ └──────┬──────┘ └──────┬──────┘ └─────────────┘ │
│ │ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Node.js API │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ fs │ │ path │ │ os │ │ crypto │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ child_process │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
本章小结
┌─────────────────────────────────────────────────────────────────────┐
│ 第十三章 核心要点 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 📦 核心依赖 │
│ • @modelcontextprotocol/sdk:MCP 协议实现 │
│ • node-cron:心跳调度(每 30 分钟) │
│ • zod:工具参数验证 │
│ │
│ 🛠️ 开发依赖 │
│ • TypeScript:静态类型检查 │
│ • @types/node:Node.js 类型定义 │
│ • @types/node-cron:cron 类型定义 │
│ │
│ 🔧 Node.js API │
│ • fs/promises:文件系统操作 │
│ • path:路径处理 │
│ • os:系统信息 │
│ • crypto:哈希计算 │
│ • child_process:命令执行 │
│ │
└─────────────────────────────────────────────────────────────────────┘
下一章:代码质量分析 →