Skill: landyun/code-review-fix (version 1.0.0)

# Code Review & Fix / 智能代码审查与修复 自动审查代码问题、提供修复建议、直接修复代码 —— 解决开发者"代码质量"和"bug修复"的高频痛点。 ## Usage / 使用方法 ```bash # 审查当前文件 /code-review # 审查并自动修复 /code-review --fix # 只检查安全问题 /code-review --security # 学习模式（附带解释） /code-review --explain ``` ## Features / 功能特性 - ✅ 代码问题检测（bug、安全、性能） - ✅ 代码风格检查 - ✅ 自动修复 - ✅ 解释教育模式 - ✅ 多语言支持 ## Pricing / 定价 - 前3次免费 - 单次调用：0.001 USDT - 更多套餐见 skillpay.me

path: .gitignore
content: node_modules/
dist/
build/
*.log
.env
.DS_Store
.code-review-fix-state.json


path: example.ts
content: // 示例代码 - 包含一些常见问题
var [REDACTED_SECRET]';
var [REDACTED_SECRET]';

function unsafeFunction(userInput) {
  // 使用 eval - 安全问题
  var result = eval(userInput);
  return result;
}

function renderUserContent(content) {
  // 使用 innerHTML - XSS 风险
  var div = document.createElement('div');
  div.innerHTML = content;
  return div;
}

function logUserInfo(user) {
  // 记录敏感信息
  console.log('User login:', user.name, 'password:', password);
}

function updateElements() {
  // 循环中的 DOM 查询
  var items = document.querySelectorAll('.item');
  for (var i = 0; i < items.length; i++) {
    var element = document.querySelector('.item-' + i);
    if (element) {
      element.textContent = 'Updated';
    }
  }
}

console.log('Example loaded');


path: package.json
content: {
  "name": "code-review-fix",
  "version": "1.0.0",
  "description": "智能代码审查与修复 - Code Review & Fix with SkillPay billing",
  "main": "scripts/main.ts",
  "scripts": {
    "start": "bun scripts/main.ts",
    "dev": "bun --watch scripts/main.ts"
  },
  "keywords": ["code-review", "claude-code", "skill"],
  "author": "",
  "license": "MIT",
  "dependencies": {},
  "devDependencies": {
    "@types/bun": "^1.0.0"
  }
}


path: README.md
content: # Code Review & Fix Skill

智能代码审查与修复技能，支持 SkillPay 计费接入。

## 功能特性

- ✅ 代码问题检测（bug、安全、性能）
- ✅ 代码风格检查
- ✅ 自动修复
- ✅ 解释教育模式
- ✅ SkillPay 计费集成
- ✅ 前3次免费试用

## 快速开始

```bash
# 安装依赖
cd code-review-fix
bun install

# 运行帮助
bun run scripts/main.ts --help

# 审查代码
bun run scripts/main.ts your-file.ts

# 审查并自动修复
bun run scripts/main.ts your-file.ts --fix

# 学习模式（带解释）
bun run scripts/main.ts your-file.ts --explain
```

## SkillPay 计费配置

编辑 `lib/billing.ts` 中的配置：

```typescript
const BILLING_API_KEY = 'your-api-key';  // 从 skillpay.me 获取
export const SKILL_ID = 'your-skill-id';
```

## 计费命令

```bash
# 查看余额
bun run scripts/main.ts balance

# 获取充值链接
bun run scripts/main.ts payment-link 10  # 充值 10 USDT
```

## 目录结构

```
code-review-fix/
├── SKILL.md              # Skill 定义
├── README.md             # 本文件
├── package.json          # 项目配置
├── scripts/
│   └── main.ts          # 主入口
├── lib/
│   ├── billing.ts       # SkillPay 计费集成
│   └── analyzer.ts      # 代码分析核心
└── config/
    └── rules.json       # 审查规则（可选）
```

## 定价

- 前3次：免费
- 单次调用：0.001 USDT
- 更多套餐：见 skillpay.me

## 扩展开发

### 添加新的检查规则

编辑 `lib/analyzer.ts` 中的 `analyzeCode` 函数。

### 接入 LLM 进行智能分析

可以在 `analyzeCode` 函数中接入 Claude API 或其他 LLM：

```typescript
const response = await fetch('https://api.anthropic.com/v1/messages', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.ANTHROPIC_API_KEY,
    'content-type': 'application/json',
  },
  body: JSON.stringify({
    model: 'claude-sonnet-4-6',
    messages: [{ role: 'user', content: `审查代码: ${code}` }],
  }),
});
```

## License

MIT


path: scripts/main.ts
content: #!/usr/bin/env bun
import { parseArgs } from 'util';
import { readFileSync, writeFileSync, existsSync } from 'fs';
import { join } from 'path';
import { chargeUser, checkBalance, getPaymentLink } from '../lib/billing';
import { analyzeCode, fixCode } from '../lib/analyzer';

const CONFIG = {
  freeCalls: 3, // 前3次免费
  stateFile: join(process.cwd(), '.code-review-fix-state.json'),
};

interface State {
  [userId: string]: {
    freeCallsUsed: number;
    totalCalls: number;
  };
}

function loadState(): State {
  if (existsSync(CONFIG.stateFile)) {
    return JSON.parse(readFileSync(CONFIG.stateFile, 'utf-8'));
  }
  return {};
}

function saveState(state: State) {
  writeFileSync(CONFIG.stateFile, JSON.stringify(state, null, 2));
}

function getUserId(): string {
  // 使用环境变量或机器标识作为用户ID
  return process.env.SKILLPAY_USER_ID || 'local-user-' + require('os').userInfo().username;
}

async function main() {
  const { values, positionals } = parseArgs({
    args: Bun.argv,
    options: {
      fix: { type: 'boolean' },
      security: { type: 'boolean' },
      style: { type: 'boolean' },
      performance: { type: 'boolean' },
      explain: { type: 'boolean' },
      help: { type: 'boolean' },
    },
    strict: true,
    allowPositionals: true,
  });

  if (values.help) {
    console.log(`
Code Review & Fix - 智能代码审查与修复

Usage:
  /code-review [file]          审查代码
  /code-review --fix            审查并自动修复
  /code-review --security       只检查安全问题
  /code-review --style          只检查风格问题
  /code-review --performance    只检查性能问题
  /code-review --explain        学习模式（附带解释）

Options:
  --fix         自动修复问题
  --security    安全检查模式
  --style       风格检查模式
  --performance 性能检查模式
  --explain     解释模式
  --help        显示帮助
`);
    return;
  }

  // 获取要审查的文件
  let targetFile = positionals[2];
  if (!targetFile) {
    // 如果没有指定文件，尝试找当前目录的主要文件
    const files = ['index.ts', 'index.js', 'main.ts', 'main.js', 'app.ts', 'app.js'];
    for (const f of files) {
      if (existsSync(join(process.cwd(), f))) {
        targetFile = f;
        break;
      }
    }
  }

  if (!targetFile || !existsSync(join(process.cwd(), targetFile))) {
    console.log('❌ 请指定要审查的文件，或在包含代码文件的目录中运行');
    return;
  }

  const filePath = join(process.cwd(), targetFile);
  const code = readFileSync(filePath, 'utf-8');

  // === 计费流程开始 ===
  const userId = getUserId();
  const state = loadState();
  const userState = state[userId] || { freeCallsUsed: 0, totalCalls: 0 };

  const isFree = userState.freeCallsUsed < CONFIG.freeCalls;

  if (!isFree) {
    console.log('⏳ 检查计费状态...');
    const result = await chargeUser(userId);
    if (!result.ok) {
      console.log(`
❌ 余额不足！
当前余额: ${result.balance} USDT

请充值: ${result.paymentUrl}

或获取充值链接:
$ /code-review payment-link 10  # 充值 10 USDT
`);
      return;
    }
    console.log(`✅ 扣费成功！当前余额: ${result.balance} USDT`);
  } else {
    userState.freeCallsUsed++;
    console.log(`🎁 免费试用 (${userState.freeCallsUsed}/${CONFIG.freeCalls})`);
  }

  userState.totalCalls++;
  state[userId] = userState;
  saveState(state);
  // === 计费流程结束 ===

  // 执行代码审查
  console.log(`\n🔍 正在审查: ${targetFile}`);
  console.log('═══════════════════════════════════════');

  const analysis = await analyzeCode(code, {
    security: values.security,
    style: values.style,
    performance: values.performance,
    explain: values.explain,
  });

  console.log(analysis.report);

  // 如果需要修复
  if (values.fix && analysis.fixable) {
    console.log('\n🔧 正在自动修复...');
    const fixedCode = await fixCode(code, analysis);
    writeFileSync(filePath, fixedCode);
    console.log('✅ 修复完成！');
  }

  if (isFree && userState.freeCallsUsed >= CONFIG.freeCalls) {
    console.log(`
═══════════════════════════════════════
🎉 免费试用已结束，下次调用将开始计费

定价:
  单次调用: 0.001 USDT
  更多套餐: https://skillpay.me/skill/${SKILL_ID}
`);
  }
}

// 处理支付链接生成
if (Bun.argv[2] === 'payment-link') {
  const amount = parseFloat(Bun.argv[3] || '10');
  const userId = getUserId();
  const link = await getPaymentLink(userId, amount);
  console.log(`💰 充值链接 (${amount} USDT):\n${link}`);
  process.exit(0);
}

// 处理余额查询
if (Bun.argv[2] === 'balance') {
  const userId = getUserId();
  const balance = await checkBalance(userId);
  console.log(`💰 当前余额: ${balance} USDT`);
  process.exit(0);
}

main().catch(console.error);


path: lib/analyzer.ts
content: interface AnalysisOptions {
  security?: boolean;
  style?: boolean;
  performance?: boolean;
  explain?: boolean;
}

interface CodeIssue {
  severity: 'Critical' | 'High' | 'Medium' | 'Low';
  line: number;
  type: 'bug' | 'security' | 'performance' | 'style';
  description: string;
  fixSuggestion?: string;
  explanation?: string;
}

interface AnalysisResult {
  report: string;
  issues: CodeIssue[];
  fixable: boolean;
}

// 简单的启发式代码分析（实际项目可以接入 LLM）
export async function analyzeCode(code: string, options: AnalysisOptions): Promise<AnalysisResult> {
  const issues: CodeIssue[] = [];
  const lines = code.split('\n');

  // 检查常见问题
  lines.forEach((line, index) => {
    const lineNum = index + 1;

    // 安全问题检测
    if (options.security || (!options.security && !options.style && !options.performance)) {
      if (line.includes('eval(')) {
        issues.push({
          severity: 'Critical',
          line: lineNum,
          type: 'security',
          description: '使用了 eval()，可能导致代码注入攻击',
          fixSuggestion: '使用 safer 的替代方案，如 JSON.parse() 或 Function 构造函数',
          explanation: options.explain ? 'eval() 会执行任意字符串作为代码，攻击者可以通过注入恶意代码来控制你的程序。' : undefined,
        });
      }
      if (line.includes('innerHTML') && !line.includes('textContent')) {
        issues.push({
          severity: 'High',
          line: lineNum,
          type: 'security',
          description: '使用 innerHTML 可能导致 XSS 攻击',
          fixSuggestion: '使用 textContent 替代，或对内容进行 sanitize',
          explanation: options.explain ? 'XSS (Cross-Site Scripting) 攻击允许攻击者在用户浏览器中执行恶意脚本。' : undefined,
        });
      }
      if (line.includes('console.log') && line.includes('password')) {
        issues.push({
          severity: 'High',
          line: lineNum,
          type: 'security',
          description: '敏感信息（密码）可能被记录到日志',
          fixSuggestion: '删除或注释掉包含敏感信息的日志',
          explanation: options.explain ? '日志可能被存储在不安全的地方，导致敏感信息泄露。' : undefined,
        });
      }
    }

    // 性能问题检测
    if (options.performance || (!options.security && !options.style && !options.performance)) {
      if (line.includes('document.querySelectorAll') && line.includes('forEach')) {
        issues.push({
          severity: 'Medium',
          line: lineNum,
          type: 'performance',
          description: '循环中进行 DOM 查询可能影响性能',
          fixSuggestion: '将 DOM 查询结果缓存到循环外部',
          explanation: options.explain ? 'DOM 查询是昂贵的操作，在循环中重复执行会显著降低性能。' : undefined,
        });
      }
    }

    // 风格问题检测
    if (options.style || (!options.security && !options.style && !options.performance)) {
      if (line.includes('var ')) {
        issues.push({
          severity: 'Low',
          line: lineNum,
          type: 'style',
          description: '使用 var 而不是 let/const',
          fixSuggestion: '使用 let 或 const 替代 var',
          explanation: options.explain ? 'var 有函数作用域提升问题，let/const 提供块级作用域，更安全。' : undefined,
        });
      }
      if (line.trim().endsWith(';') === false && line.trim().length > 0 && !line.trim().startsWith('//') && !line.trim().startsWith('/*') && !line.trim().startsWith('*') && !line.includes('{') && !line.includes('}') && !line.includes('`')) {
        // 简单的分号检查（避免误报）
      }
    }
  });

  // 生成报告
  const report = generateReport(issues, options);

  return {
    report,
    issues,
    fixable: issues.some(i => i.fixSuggestion),
  };
}

function generateReport(issues: CodeIssue[], options: AnalysisOptions): string {
  if (issues.length === 0) {
    return '✅ 代码检查通过，未发现问题！';
  }

  let report = '';

  // 按严重程度分组
  const critical = issues.filter(i => i.severity === 'Critical');
  const high = issues.filter(i => i.severity === 'High');
  const medium = issues.filter(i => i.severity === 'Medium');
  const low = issues.filter(i => i.severity === 'Low');

  report += `📊 发现 ${issues.length} 个问题\n`;
  report += '═══════════════════════════════════════\n\n';

  if (critical.length > 0) {
    report += `🔴 Critical (${critical.length})\n`;
    critical.forEach(issue => {
      report += `   Line ${issue.line}: ${issue.description}\n`;
      if (issue.explanation) report += `      ℹ️ ${issue.explanation}\n`;
      if (issue.fixSuggestion) report += `      💡 ${issue.fixSuggestion}\n`;
    });
    report += '\n';
  }

  if (high.length > 0) {
    report += `🟠 High (${high.length})\n`;
    high.forEach(issue => {
      report += `   Line ${issue.line}: ${issue.description}\n`;
      if (issue.explanation) report += `      ℹ️ ${issue.explanation}\n`;
      if (issue.fixSuggestion) report += `      💡 ${issue.fixSuggestion}\n`;
    });
    report += '\n';
  }

  if (medium.length > 0) {
    report += `🟡 Medium (${medium.length})\n`;
    medium.forEach(issue => {
      report += `   Line ${issue.line}: ${issue.description}\n`;
      if (issue.explanation) report += `      ℹ️ ${issue.explanation}\n`;
      if (issue.fixSuggestion) report += `      💡 ${issue.fixSuggestion}\n`;
    });
    report += '\n';
  }

  if (low.length > 0) {
    report += `🟢 Low (${low.length})\n`;
    low.forEach(issue => {
      report += `   Line ${issue.line}: ${issue.description}\n`;
      if (issue.explanation) report += `      ℹ️ ${issue.explanation}\n`;
      if (issue.fixSuggestion) report += `      💡 ${issue.fixSuggestion}\n`;
    });
    report += '\n';
  }

  const fixableCount = issues.filter(i => i.fixSuggestion).length;
  if (fixableCount > 0) {
    report += `\n═══════════════════════════════════════\n`;
    report += `💪 ${fixableCount} 个问题可自动修复\n`;
    report += `运行: /code-review --fix 来自动修复\n`;
  }

  return report;
}

// 简单的自动修复
export async function fixCode(code: string, analysis: AnalysisResult): Promise<string> {
  let fixedCode = code;

  // 简单的替换修复
  analysis.issues.forEach(issue => {
    if (issue.type === 'style' && issue.description.includes('var ')) {
      // 将 var 替换为 let/const（简单实现）
      const lines = fixedCode.split('\n');
      const lineIndex = issue.line - 1;
      if (lines[lineIndex]) {
        lines[lineIndex] = lines[lineIndex].replace(/\bvar\s+/g, 'let ');
        fixedCode = lines.join('\n');
      }
    }
    // 更多修复规则可以在这里添加
  });

  return fixedCode;
}


path: lib/billing.ts
content: // ═══════════════════════════════════════════════════
// SkillPay Billing Integration / 计费接入
// スキルペイ課金統合 / 결제 연동 / Интеграция биллинга
// ═══════════════════════════════════════════════════

const BILLING_API_URL = 'https://skillpay.me';
const BILLING_API_KEY = [REDACTED_SECRET];  // Dashboard → 接入配置 / Integration Config
export const SKILL_ID = '3da52f24-9e3d-43bd-931d-0925e237ed93';

// ① Check balance / 查余额 / 残高確認 / 잔액 확인 / Проверка баланса
export async function checkBalance(userId: string): Promise<number> {
  const resp = await fetch(
    `${BILLING_API_URL}/api/v1/billing/balance?user_id=${encodeURIComponent(userId)}`,
    { headers: { 'X-API-Key': BILLING_API_KEY } }
  );
  const data = await resp.json();
  return data.balance;  // USDT amount / USDT 金额
}

// ② Charge per call / 每次调用扣费 / 呼び出しごとの課金 / 호출당 과금 / Списание за вызов
export async function chargeUser(userId: string): Promise<{
  ok: boolean;
  balance?: number;
  paymentUrl?: string;
}> {
  const resp = await fetch(`${BILLING_API_URL}/api/v1/billing/charge`, {
    method: 'POST',
    headers: {
      'X-API-Key': BILLING_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      user_id: userId,
      skill_id: SKILL_ID,
      amount: 0.001,  // USDT per call / 每次调用单价
    }),
  });
  const data = await resp.json();

  if (data.success) {
    return { ok: true, balance: data.balance };
  }

  // Insufficient balance → get payment link
  // 余额不足 → 生成充值链接
  // 残高不足 → 決済リンク生成
  // 잔액 부족 → 결제 링크 생성
  // Недостаточно средств → ссылка на оплату
  return { ok: false, balance: data.balance, paymentUrl: data.payment_url };
}

// ③ Generate payment link / 生成充值链接 / 決済リンク生成 / 결제 링크 생성 / Ссылка на оплату
export async function getPaymentLink(userId: string, amount: number): Promise<string> {
  const resp = await fetch(`${BILLING_API_URL}/api/v1/billing/payment-link`, {
    method: 'POST',
    headers: {
      'X-API-Key': BILLING_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ user_id: userId, amount }),
  });
  const data = await resp.json();
  return data.payment_url;  // BNB Chain USDT payment link / BNB链 USDT 付款链接
}

// ═══════ Usage example / 使用示例 ═══════
//
// async function handleRequest(userId) {
//   const result = await chargeUser(userId);
//   if (result.ok) {
//     // ✅ Execute your skill logic here
//     // ✅ 在这里执行你的 Skill 逻辑
//     return { success: true };
//   } else {
//     // ❌ Insufficient balance, return payment link to user
//     // ❌ 余额不足，返回充值链接给用户
//     return { success: false, paymentUrl: result.paymentUrl };
//   }
// }


path: config/rules.json
content: {
  "version": "1.0.0",
  "rules": {
    "security": {
      "enabled": true,
      "checkEval": true,
      "checkInnerHTML": true,
      "checkConsoleSensitive": true,
      "checkSQLInjection": true
    },
    "style": {
      "enabled": true,
      "checkVar": true,
      "checkSemicolon": false,
      "checkNaming": true,
      "maxLineLength": 120
    },
    "performance": {
      "enabled": true,
      "checkDOMInLoop": true,
      "checkUnusedImports": true
    }
  },
  "languages": {
    "javascript": true,
    "typescript": true,
    "python": true,
    "go": false
  }
}


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