Skill: plume-lj/figma-design-analyzer (version 1.0.2)

--- name: figma-design-analyzer description: 分析Figma设计文件，提取设计系统数据（颜色、字体、间距、组件），导出截图，并与实际实现进行比对验证。使用JavaScript/Node.js实现，当用户需要处理Figma设计文件、提取设计规范、导出设计资源或验证设计实现时使用此技能。 compatibility: 需要Node.js 20+，通过FIGMA_ACCESS_TOKEN环境变量提供Figma个人访问令牌。 --- # Figma设计分析技能 (JavaScript版) 使用Node.js分析Figma设计文件，提取设计系统，导出资源，验证实现一致性。 ## 快速开始 1. **设置令牌**： ```bash export FIGMA_ACCESS_TOKEN=your_figma_token ``` 2. **安装Node.js依赖**： ```bash npm install # 或 yarn install ``` 3. **使用技能**： - 在Claude中：直接描述您的Figma分析需求 - 命令行：`node scripts/figma-cli.js --help` ## 核心功能 ### 1. 文件信息获取 获取Figma文件的完整结构和元数据： ```bash node scripts/figma-cli.js info "文件ID或URL" ``` ### 2. 设计属性提取 提取颜色、字体、间距、组件等设计系统数据： ```bash node scripts/figma-cli.js extract "文件ID" --output design-system.json ``` ### 3. 截图导出 导出设计节点的PNG/JPG截图： ```bash node scripts/figma-cli.js export "文件ID" --node-id "节点ID" --format png ``` ### 4. 比对验证 将实际实现（CSS/代码）与设计进行比对： ```bash node scripts/figma-cli.js compare "文件ID" implementation.css --output report.json ``` ## 输出格式 - **JSON**：机器可读的结构化数据（默认） - **HTML**：可视化比对报告 - **PNG/JPG**：设计截图 ## 错误处理 - 验证FIGMA_ACCESS_TOKEN环境变量 - 检查文件访问权限 - 处理API限制和网络错误 - 提供明确的错误信息和解决建议 ## 示例用例 1. **设计系统文档生成**：提取所有设计规范 2. **开发资源准备**：批量导出图标和组件截图 3. **实现质量检查**：比对CSS与设计一致性 4. **设计评审**：分析设计规范遵循情况 ## 下一步 1. 设置您的FIGMA_ACCESS_TOKEN 2. 提供Figma文件URL或ID 3. 描述您的具体需求 技能会自动处理分析并生成结果。

path: README.md
content: # Figma Design Analyzer Skill

一个Claude Code技能，用于分析Figma设计文件、提取设计系统、导出截图和验证设计实现一致性。

## 功能特性

### 🎨 设计系统提取
- **颜色提取**: 自动提取设计中的所有颜色值（HEX、RGB、RGBA）
- **字体分析**: 提取字体家族、大小、字重、行高等属性
- **间距尺度**: 分析间距、尺寸和布局网格系统
- **组件识别**: 识别和分类设计组件

### 📸 截图导出
- **节点截图**: 导出任意设计节点的PNG/JPG截图
- **批量导出**: 支持批量导出多个组件或页面
- **多倍缩放**: 支持0.5x, 1x, 2x, 3x, 4x缩放
- **格式转换**: 自动处理图片格式转换

### 🔍 比对验证
- **设计一致性检查**: 比对CSS/代码实现与Figma设计
- **差异报告**: 生成详细的比对报告和改进建议
- **通过率统计**: 计算设计实现的一致性通过率
- **可视化报告**: 生成HTML格式的可视化比对报告

### 📊 文件信息
- **元数据获取**: 获取文件基本信息、版本历史
- **结构分析**: 分析页面、画板、组件结构
- **协作信息**: 查看评论和协作状态

## 安装使用

### 前提条件
1. **Node.js 20+**: 确保已安装Node.js 20或更高版本
2. **Figma访问令牌**: 从Figma账户设置中获取个人访问令牌

项目包含 `.env.example` 文件，复制为 `.env` 并填写您的令牌即可：
```bash
cp .env.example .env
# 编辑 .env 文件，将 FIGMA_ACCESS_TOKEN 替换为您的实际令牌
```

### 安装步骤

#### 方法一：通过skills仓库安装（推荐）
```bash
# 使用npx从skills仓库安装
npx skills add yourusername/agent-skills/figma-design-analyzer
```

#### 方法二：手动安装
```bash
# 1. 克隆仓库
git clone https://github.com/yourusername/agent-skills.git
cd agent-skills/skills/figma-design-analyzer

# 2. 安装依赖
npm install

# 3. 设置环境变量
# 方法A：使用环境变量文件（推荐）
cp .env.example .env
# 编辑 .env 文件，填写您的 FIGMA_ACCESS_TOKEN

# 方法B：直接设置环境变量
export FIGMA_ACCESS_TOKEN=your_figma_personal_access_token

# 4. 测试安装
npm test
```

#### 方法三：在Claude Code中直接使用
1. 确保技能目录位于 `~/.claude/skills/figma-design-analyzer/`
2. Claude会自动检测并加载技能

## 快速开始

### 1. 设置环境变量
```bash
# 推荐：使用环境变量文件
cp .env.example .env
# 编辑 .env 文件，填写您的 FIGMA_ACCESS_TOKEN

# 或使用传统方式：
# 永久设置（添加到 ~/.bashrc 或 ~/.zshrc）
echo 'export FIGMA_ACCESS_TOKEN="your_token_here"' >> ~/.zshrc
source ~/.zshrc

# 临时设置
export FIGMA_ACCESS_TOKEN=your_token_here
```

### 2. 使用命令行工具
```bash
# 查看帮助
node scripts/figma-cli.js --help

# 获取文件信息
node scripts/figma-cli.js info "https://figma.com/file/abc123"

# 提取设计系统
node scripts/figma-cli.js extract "文件ID" --output design-system.json

# 导出截图
node scripts/figma-cli.js export "文件ID" --node-id "节点ID" --format png --scale 2

# 比对验证
node scripts/figma-cli.js compare "文件ID" styles.css --output report.json
```

### 3. 在Claude中使用
在Claude对话中直接描述您的需求：
- "分析这个Figma文件：https://figma.com/file/abc123"
- "提取这个设计的所有颜色和字体"
- "导出按钮组件的截图"
- "检查我的CSS是否与设计一致"

## API参考

### 命令行参数

#### `info` - 获取文件信息
```bash
node scripts/figma-cli.js info <file_url_or_id> [--output <path>]
```

#### `extract` - 提取设计系统
```bash
node scripts/figma-cli.js extract <file_url_or_id> [--output <path>]
```

#### `export` - 导出截图
```bash
node scripts/figma-cli.js export <file_url_or_id> --node-id <id> [--format png|jpg] [--scale <number>] [--output <path>]
```

#### `compare` - 比对验证
```bash
node scripts/figma-cli.js compare <file_url_or_id> <implementation_path> [--output <path>]
```

### 输出格式

技能支持多种输出格式：

#### JSON输出（默认）
```json
{
  "file_id": "abc123",
  "summary": {
    "total_colors": 24,
    "total_fonts": 8,
    "pass_rate": 85
  },
  "details": {
    "colors": [...],
    "fonts": [...]
  }
}
```

#### HTML报告
生成可视化的比对报告，包含：
- 通过率图表
- 详细差异列表
- 改进建议
- 颜色对比可视化

#### 图片文件
- PNG格式截图
- JPG格式截图
- 多倍缩放支持

## 开发指南

### 项目结构
```
figma-design-analyzer/
├── SKILL.md                    # 技能定义文件
├── README.md                   # 项目说明
├── package.json               # 依赖配置
├── scripts/
│   ├── figma-cli.js           # 命令行入口
│   ├── test-runner.js         # 测试运行器
│   ├── modules/
│   │   ├── file-info.js       # 文件信息模块
│   │   ├── design-extractor.js # 设计提取模块
│   │   ├── screenshot-exporter.js # 截图导出模块
│   │   └── design-comparator.js # 比对验证模块
│   └── test-data/             # 测试数据
├── evals/
│   └── evals.json             # 评估测试用例
├── references/                # 参考文档
└── assets/                    # 静态资源
```

### 运行测试
```bash
# 运行所有测试
npm test

# 或直接运行测试脚本
node scripts/test-runner.js

# 运行特定测试
node scripts/test-runner.js --test file-info
```

### 扩展开发

#### 添加新功能模块
1. 在 `scripts/modules/` 目录创建新模块
2. 实现功能逻辑
3. 在 `figma-cli.js` 中添加对应的命令
4. 更新 `SKILL.md` 文档

#### 修改设计提取逻辑
编辑 `scripts/modules/design-extractor.js`：
- 修改 `traverseNode` 函数添加新的属性提取
- 更新 `extractDesignSystem` 函数修改输出结构

#### 自定义比对规则
编辑 `scripts/modules/design-comparator.js`：
- 修改 `compareDesignSystems` 函数添加新的比对维度
- 更新 `generateRecommendations` 函数自定义建议逻辑

## 配置选项

### 环境变量
| 变量名 | 必填 | 描述 | 示例 |
|--------|------|------|------|
| `FIGMA_ACCESS_TOKEN` | 是 | Figma个人访问令牌 | `figd_xxxxxxxxxxxx` |
| `FIGMA_EXPORT_DIR` | 否 | 截图导出目录 | `./exports` |
| `FIGMA_API_TIMEOUT` | 否 | API请求超时(ms) | `30000` |

### 性能优化
对于大型设计文件：
```bash
# 增加内存限制
export NODE_OPTIONS="--max-old-space-size=4096"

# 设置API超时
export FIGMA_API_TIMEOUT=60000
```

## 常见问题

### Q: 获取 "认证失败" 错误
A: 确保 `FIGMA_ACCESS_TOKEN` 环境变量已正确设置，且令牌未过期。

### Q: 截图导出失败
A: 检查节点ID是否正确，以及是否有访问权限。某些节点可能不支持截图导出。

### Q: 比对结果不准确
A: CSS解析基于简单规则，对于复杂CSS可能需要手动调整。可考虑使用专门的CSS解析库改进。

### Q: API限制错误
A: Figma API有调用频率限制。建议：
1. 添加延迟处理
2. 缓存结果
3. 分批处理大型文件

### Q: 技能未触发
A: 确保技能目录位于正确位置，且 `SKILL.md` 中的描述包含相关关键词。

## 贡献指南

1. Fork 本仓库
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
3. 提交更改 (`git commit -m 'Add amazing feature'`)
4. 推送到分支 (`git push origin feature/amazing-feature`)
5. 开启 Pull Request

### 开发规范
- 使用ES6+语法
- 添加JSDoc注释
- 编写单元测试
- 更新相关文档

## 许可证

MIT License

## 支持

- 提交Issue: [GitHub Issues](https://github.com/yourusername/agent-skills/issues)
- 文档: [技能文档](./references/)
- 示例: [测试用例](./evals/evals.json)

---

**提示**: 对于生产环境使用，建议：
1. 设置API调用限制和重试逻辑
2. 添加结果缓存机制
3. 实现增量同步功能
4. 集成到CI/CD流水线中

path: package.json
content: {
  "name": "figma-design-analyzer",
  "version": "1.0.0",
  "description": "Figma设计分析工具 - 提取设计系统、导出截图、验证实现一致性",
  "main": "scripts/figma-cli.js",
  "scripts": {
    "start": "node scripts/figma-cli.js",
    "test": "node scripts/test-runner.js"
  },
  "bin": {
    "figma-analyzer": "scripts/figma-cli.js"
  },
  "keywords": [
    "figma",
    "design",
    "analyzer",
    "design-system",
    "screenshot",
    "comparison"
  ],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "axios": "^1.6.0",
    "commander": "^11.1.0",
    "chalk": "^4.1.2",
    "dotenv": "^16.3.1",
    "jsdom": "^22.1.0",
    "sharp": "^0.33.0"
  },
  "devDependencies": {
    "jest": "^29.7.0"
  },
  "files": [
    "SKILL.md",
    "README.md",
    "scripts",
    "evals",
    "references",
    ".env.example"
  ],
  "engines": {
    "node": ">=20.0.0"
  }
}

path: scripts/figma-cli.js
content: #!/usr/bin/env node

/**
 * Figma设计分析命令行工具 - JavaScript版本
 * 统一接口，支持文件信息获取、设计属性提取、截图导出和比对验证功能
 */

const fs = require('fs');
const path = require('path');
const { program } = require('commander');
const chalk = require('chalk');
require('dotenv').config(); // 加载.env文件

// 导入各个功能模块
const { getFileInfo, parseFileId } = require('./modules/file-info');
const { extractDesignSystem } = require('./modules/design-extractor');
const { exportScreenshot } = require('./modules/screenshot-exporter');
const { compareWithImplementation } = require('./modules/design-comparator');

// 工具函数
function getFigmaToken() {
  const [REDACTED_SECRET];
  if (!token) {
    console.error(chalk.red('错误: 未设置FIGMA_ACCESS_TOKEN环境变量'));
    console.error(chalk.yellow('请选择以下方式之一设置令牌:'));
    console.error(chalk.yellow('1. 使用.env文件: cp .env.example .env 并填写您的令牌'));
    console.error(chalk.yellow('2. 直接设置环境变量: export FIGMA_ACCESS_TOKEN=your_token'));
    console.error(chalk.yellow('3. 临时设置: FIGMA_ACCESS_TOKEN=your_token node scripts/figma-cli.js ...'));
    process.exit(1);
  }
  return token;
}

function saveOutput(data, outputPath, format = 'json') {
  try {
    const dir = path.dirname(outputPath);
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }

    if (format === 'json') {
      fs.writeFileSync(outputPath, JSON.stringify(data, null, 2), 'utf8');
      console.log(chalk.green(`结果已保存到: ${outputPath}`));
    } else if (format === 'txt') {
      fs.writeFileSync(outputPath, data.toString(), 'utf8');
      console.log(chalk.green(`结果已保存到: ${outputPath}`));
    } else {
      console.error(chalk.red(`不支持的输出格式: ${format}`));
    }
  } catch (error) {
    console.error(chalk.red(`保存文件时出错: ${error.message}`));
  }
}

// 命令处理函数
async function handleInfo(fileInput, outputPath) {
  const [REDACTED_SECRET]);
  const fileId = parseFileId(fileInput);

  console.log(chalk.blue(`获取文件信息: ${fileId}`));
  const result = await getFileInfo(fileId, token);

  if (outputPath) {
    saveOutput(result, outputPath);
  } else {
    console.log(JSON.stringify(result, null, 2));
  }

  return result;
}

async function handleExtract(fileInput, outputPath) {
  const [REDACTED_SECRET]);
  const fileId = parseFileId(fileInput);

  console.log(chalk.blue(`提取设计属性: ${fileId}`));
  const result = await extractDesignSystem(fileId, token);

  if (outputPath) {
    saveOutput(result, outputPath);
  } else {
    console.log(JSON.stringify(result, null, 2));
  }

  return result;
}

async function handleExport(fileInput, nodeId, options) {
  const [REDACTED_SECRET]);
  const fileId = parseFileId(fileInput);

  console.log(chalk.blue(`导出截图: ${fileId}, 节点: ${nodeId}`));
  const result = await exportScreenshot(
    fileId,
    nodeId,
    token,
    options.format,
    options.scale
  );

  if (options.output) {
    if (result.imagePath) {
      console.log(chalk.green(`截图已保存到: ${result.imagePath}`));
    } else {
      saveOutput(result, options.output);
    }
  }

  return result;
}

async function handleCompare(fileInput, implementationPath, outputPath) {
  const [REDACTED_SECRET]);
  const fileId = parseFileId(fileInput);

  console.log(chalk.blue(`比对验证: ${fileId} 与 ${implementationPath}`));
  const result = await compareWithImplementation(fileId, implementationPath, token);

  if (outputPath) {
    saveOutput(result, outputPath);
  } else {
    console.log(JSON.stringify(result, null, 2));
  }

  return result;
}

// 设置命令行程序
program
  .name('figma-analyzer')
  .description('Figma设计分析工具 - 提取设计系统、导出截图、验证实现')
  .version('1.0.0');

// info命令
program
  .command('info')
  .description('获取Figma文件信息')
  .argument('<file>', 'Figma文件URL或ID')
  .option('-o, --output <path>', '输出文件路径')
  .action(async (file, options) => {
    try {
      await handleInfo(file, options.output);
    } catch (error) {
      console.error(chalk.red(`执行失败: ${error.message}`));
      process.exit(1);
    }
  });

// extract命令
program
  .command('extract')
  .description('提取设计系统数据')
  .argument('<file>', 'Figma文件URL或ID')
  .option('-o, --output <path>', '输出文件路径')
  .action(async (file, options) => {
    try {
      await handleExtract(file, options.output);
    } catch (error) {
      console.error(chalk.red(`执行失败: ${error.message}`));
      process.exit(1);
    }
  });

// export命令
program
  .command('export')
  .description('导出设计节点截图')
  .argument('<file>', 'Figma文件URL或ID')
  .requiredOption('--node-id <id>', '节点ID')
  .option('--format <format>', '图片格式', 'png')
  .option('--scale <scale>', '缩放比例', '1')
  .option('-o, --output <path>', '输出文件路径')
  .action(async (file, options) => {
    try {
      await handleExport(file, options.nodeId, {
        format: options.format,
        scale: parseFloat(options.scale),
        output: options.output
      });
    } catch (error) {
      console.error(chalk.red(`执行失败: ${error.message}`));
      process.exit(1);
    }
  });

// compare命令
program
  .command('compare')
  .description('比对设计与实现')
  .argument('<file>', 'Figma文件URL或ID')
  .argument('<implementation>', '实现文件路径（CSS/代码）')
  .option('-o, --output <path>', '输出文件路径')
  .action(async (file, implementation, options) => {
    try {
      await handleCompare(file, implementation, options.output);
    } catch (error) {
      console.error(chalk.red(`执行失败: ${error.message}`));
      process.exit(1);
    }
  });

// 如果没有提供命令，显示帮助
if (process.argv.length <= 2) {
  program.help();
}

program.parse(process.argv);

Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)