Skill: caleb-niu007/skill-auditor-plus (version 1.0.0)

--- name: skill-auditor-plus description: Security, performance, and quality auditing for AgentSkills. Use when reviewing skills before installation, auditing during development, checking installed skills for risks, optimizing performance, or ensuring best practices compliance. Automated scanning for dangerous operations, credential leaks, token bloat, and quality issues. --- # Skill Auditor Plus Transform skill development from "hope it works" to "confidently secure and optimized". This skill provides automated auditing for AgentSkills across three dimensions: security, performance, and quality. ## Why Skill Auditing Matters - **Security**: Skills run with Codex's permissions - a vulnerable skill can delete files, leak credentials, or execute arbitrary commands - **Performance**: Large skills consume context window, reducing Codex's effectiveness for the actual task - **Quality**: Well-structured skills are easier to maintain, more reliable, and provide better user experience ## Core Capabilities ### 1. Security Audit Automatically scans for: - **Dangerous operations**: File deletion (`rm -rf`), system commands (`eval`, `exec`), code execution - **Credential leaks**: Hardcoded API keys, secrets, tokens, passwords - **Network requests**: External API calls that may be unsafe - **Suspicious patterns**: Pastebin links, URL shorteners, risky file paths - **Injection vulnerabilities**: Unsafe user input handling **Severity levels**: - 🔴 **High**: File deletion, credential leaks, system command execution - 🟡 **Medium**: Network requests, code execution, risky file paths - 🟢 **Low**: Suspicious URLs, file writes ### 2. Performance Audit Analyzes skill efficiency: - **Token usage**: Frontmatter (<100 tokens), body (<5000 tokens), line count (<500 lines) - **Context optimization**: Duplicate content, unreferenced files, large reference files - **Script efficiency**: Execute permissions, code duplication - **Recommendations**: Split into references/, use scripts for repeated code **Key metrics**: - Frontmatter token count (target: <100) - Body token count (target: <5000) - Line count (target: <500) - Reference file sizes (target: <10k tokens each) ### 3. Quality Audit Checks best practices compliance: - **SKILL.md structure**: Proper frontmatter, complete description - **File organization**: No unnecessary files (README.md, INSTALLATION_GUIDE.md, etc.) - **Documentation**: Clear usage instructions, examples, error handling - **Progressive disclosure**: Efficient context loading with references/ ## Quick Start ### Audit a skill before installation ```bash # Clone or download the skill cd skill-auditor-plus # Run security audit python3 scripts/security_audit.py /path/to/skill-to-audit # Run performance audit python3 scripts/performance_audit.py /path/to/skill-to-audit ``` ### During skill development ```bash # After making changes, audit your skill python3 scripts/security_audit.py /path/to/your-skill python3 scripts/performance_audit.py /path/to/your-skill # Fix issues, then re-audit # Iterate until no high/medium severity issues remain ``` ### Batch audit installed skills ```bash # Audit all skills in a directory for skill in /path/to/skills/*; do echo "Auditing $skill" python3 scripts/security_audit.py "$skill" python3 scripts/performance_audit.py "$skill" done ``` ## Understanding Audit Reports ### Security Audit Report ```json { "total_issues": 5, "high_severity": 1, "medium_severity": 2, "low_severity": 2, "issues": [ { "category": "credential_leaks", "severity": "high", "file": "scripts/api_client.py", "line": 15, "pattern": "api_key\\s*=\\s*[\"'][\\w-]+[\"']", "matched_text": "api_key = \"sk-1234567890\"", "context": "api_key = \"sk-1234567890\"" } ] } ``` **What to do**: 1. Review each issue by severity (high → medium → low) 2. For credential leaks: Use environment variables 3. For dangerous operations: Add warnings or safety checks 4. For network requests: Document purpose and add error handling ### Performance Audit Report ```json { "skill_md_stats": { "frontmatter_tokens": 85, "body_tokens": 7500, "total_tokens": 7585, "line_count": 520 }, "issues": [ { "severity": "high", "category": "body_too_long", "message": "Body is too long (7500 tokens, should be < 5000)", "suggestion": "Split content into references/ files and link from SKILL.md" } ] } ``` **What to do**: 1. **Frontmatter too long**: Move detailed descriptions to body 2. **Body too long**: Split into references/ files, link from SKILL.md 3. **Too many lines**: Break into smaller sections, use references/ 4. **Large reference files**: Split further or add grep patterns for searching ## Best Practices See [best-practices.md](references/best-practices.md) for comprehensive guidelines on: - Security best practices (credential management, input validation, safe operations) - Performance optimization (token efficiency, progressive disclosure, script usage) - Quality standards (documentation, file organization, structure) ## Advanced Usage ### Custom Security Patterns Edit `scripts/security_audit.py` to add custom patterns: ```python DANGEROUS_PATTERNS = { 'custom_risk': [ r'your_custom_regex_pattern', ], } ``` ### Performance Thresholds Edit `scripts/performance_audit.py` to adjust thresholds: ```python if stats['body_tokens'] > 5000: # Change this value issues.append({...}) ``` ### Integration with CI/CD Add to your CI pipeline: ```yaml # .github/workflows/skill-audit.yml name: Skill Audit on: [push, pull_request] jobs: audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Security Audit run: | python3 skill-auditor-plus/scripts/security_audit.py . - name: Performance Audit run: | python3 skill-auditor-plus/scripts/performance_audit.py . ``` ## Resources ### scripts/ - **security_audit.py**: Automated security scanning for dangerous operations, credential leaks, and suspicious patterns - **performance_audit.py**: Performance analysis for token usage, context optimization, and best practices compliance ### references/ - **[best-practices.md](references/best-practices.md)**: Comprehensive guide to AgentSkill development best practices, including security, performance, and quality standards ## Troubleshooting ### "Module not found" errors Install required dependencies: ```bash pip install pyyaml # if needed ``` ### False positives in security audit If the scanner flags safe code: 1. Review the pattern match 2. Add comments explaining why it's safe 3. Consider refactoring to avoid the pattern ### Performance audit shows large body This is normal for complex skills. Split content into references/: 1. Move detailed sections to references/feature-name.md 2. In SKILL.md, add: "See [FEATURE](references/feature-name.md) for details" 3. Keep only overview and navigation in SKILL.md ## Contributing Found a bug or want to add features? This skill is open source. Contributions welcome! ## License MIT License - See LICENSE file for details

path: README.md
content: # Skill Auditor Plus

## Overview

Skill Auditor Plus 是一个综合性的 AgentSkill 审计工具，提供安全、性能和质量三个维度的自动化检查。

## 特性

- 🔒 **安全审计**：扫描危险操作、凭证泄露、可疑模式
- ⚡ **性能审计**：分析 token 使用、context 优化、脚本效率
- 📊 **质量审计**：检查最佳实践合规性、文档完整性

## 快速开始

### 安装

```bash
# 克隆或下载技能
git clone <repository-url>
cd skill-auditor-plus
```

### 使用

```bash
# 审计单个技能
python3 scripts/security_audit.py /path/to/skill
python3 scripts/performance_audit.py /path/to/skill

# 批量审计
for skill in /path/to/skills/*; do
    echo "Auditing $skill"
    python3 scripts/security_audit.py "$skill"
    python3 scripts/performance_audit.py "$skill"
done
```

## 审计报告

### 安全审计报告

```json
{
  "total_issues": 5,
  "high_severity": 1,
  "medium_severity": 2,
  "low_severity": 2,
  "issues": [...]
}
```

### 性能审计报告

```json
{
  "skill_md_stats": {
    "frontmatter_tokens": 85,
    "body_tokens": 1800,
    "total_tokens": 1885,
    "line_count": 240
  },
  "issues": [...]
}
```

## 最佳实践

详见 [references/best-practices.md](references/best-practices.md)

## 贡献

欢迎提交 Issue 和 Pull Request！

## 许可证

MIT License


path: scripts/performance_audit.py
content: #!/usr/bin/env python3
"""
Skill Performance Auditor
检查 AgentSkill 的性能和优化建议
"""

import os
import re
from pathlib import Path
from typing import List, Dict, Any

class PerformanceAuditor:
    """性能审计器"""

    def __init__(self, skill_path: str):
        self.skill_path = Path(skill_path)
        self.issues = []

    def count_tokens(self, text: str) -> int:
        """估算 token 数量（粗略估算：1 token ≈ 4 字符）"""
        return len(text) // 4

    def audit_skill_md(self, file_path: Path) -> Dict[str, Any]:
        """审计 SKILL.md 文件"""
        content = file_path.read_text(encoding='utf-8')

        # 分离 frontmatter 和 body
        frontmatter_match = re.match(r'^---\n(.*?)\n---\n(.*)$', content, re.DOTALL)
        if not frontmatter_match:
            return {'error': 'Invalid SKILL.md format'}

        frontmatter = frontmatter_match.group(1)
        body = frontmatter_match.group(2)

        issues = []
        stats = {
            'frontmatter_tokens': self.count_tokens(frontmatter),
            'body_tokens': self.count_tokens(body),
            'total_tokens': self.count_tokens(content),
            'line_count': len(content.split('\n')),
        }

        # 检查 frontmatter 大小（应该 < 100 tokens）
        if stats['frontmatter_tokens'] > 100:
            issues.append({
                'severity': 'medium',
                'category': 'frontmatter_too_long',
                'message': f'Frontmatter is too long ({stats["frontmatter_tokens"]} tokens, should be < 100)',
                'suggestion': 'Move detailed descriptions to body, keep frontmatter concise',
            })

        # 检查 body 大小（应该 < 5000 tokens）
        if stats['body_tokens'] > 5000:
            issues.append({
                'severity': 'high',
                'category': 'body_too_long',
                'message': f'Body is too long ({stats["body_tokens"]} tokens, should be < 5000)',
                'suggestion': 'Split content into references/ files and link from SKILL.md',
            })

        # 检查行数（应该 < 500 行）
        if stats['line_count'] > 500:
            issues.append({
                'severity': 'medium',
                'category': 'too_many_lines',
                'message': f'Too many lines ({stats["line_count"]} lines, should be < 500)',
                'suggestion': 'Split content into references/ files to reduce bloat',
            })

        # 检查是否有重复内容
        duplicate_sections = re.findall(r'##\s+(.+)', body)
        if len(duplicate_sections) != len(set(duplicate_sections)):
            issues.append({
                'severity': 'low',
                'category': 'duplicate_sections',
                'message': 'Duplicate section headers found',
                'suggestion': 'Remove or merge duplicate sections',
            })

        # 检查是否有未使用的资源引用
        refs_dir = self.skill_path / 'references'
        if refs_dir.exists():
            referenced_files = set(re.findall(r'\[([^\]]+)\]\(([^)]+)\)', body))
            referenced_files.update(re.findall(r'\[([^\]]+)\]\[([^\]]+)\]', body))

            existing_files = {f.name for f in refs_dir.glob('*.md')}
            unreferenced = existing_files - {Path(r[1]).name for r in referenced_files}

            if unreferenced:
                issues.append({
                    'severity': 'low',
                    'category': 'unreferenced_files',
                    'message': f'Unreferenced files in references/: {", ".join(unreferenced)}',
                    'suggestion': 'Either link them in SKILL.md or remove if not needed',
                })

        return {
            'stats': stats,
            'issues': issues,
        }

    def audit_scripts(self, scripts_dir: Path) -> List[Dict[str, Any]]:
        """审计脚本目录"""
        issues = []

        if not scripts_dir.exists():
            return issues

        # 检查脚本是否有执行权限
        for script_file in scripts_dir.glob('*'):
            if script_file.is_file():
                if not os.access(script_file, os.X_OK):
                    issues.append({
                        'severity': 'low',
                        'category': 'no_execute_permission',
                        'file': str(script_file.relative_to(self.skill_path)),
                        'message': f'Script lacks execute permission',
                        'suggestion': f'Run: chmod +x {script_file.name}',
                    })

        return issues

    def audit_references(self, refs_dir: Path) -> List[Dict[str, Any]]:
        """审计 references 目录"""
        issues = []

        if not refs_dir.exists():
            return issues

        # 检查是否有超大文件
        for ref_file in refs_dir.glob('*.md'):
            content = ref_file.read_text(encoding='utf-8')
            tokens = self.count_tokens(content)

            if tokens > 10000:
                issues.append({
                    'severity': 'medium',
                    'category': 'large_reference_file',
                    'file': str(ref_file.relative_to(self.skill_path)),
                    'message': f'Large reference file ({tokens} tokens)',
                    'suggestion': 'Consider splitting into smaller files or adding grep patterns',
                })

        return issues

    def audit_skill(self) -> Dict[str, Any]:
        """审计整个技能"""
        all_issues = []

        # 审计 SKILL.md
        skill_md = self.skill_path / 'SKILL.md'
        if skill_md.exists():
            skill_md_result = self.audit_skill_md(skill_md)
            all_issues.extend(skill_md_result.get('issues', []))
            skill_md_stats = skill_md_result.get('stats', {})
        else:
            all_issues.append({
                'severity': 'high',
                'category': 'missing_skill_md',
                'message': 'SKILL.md not found',
                'suggestion': 'Create SKILL.md with proper frontmatter and body',
            })
            skill_md_stats = {}

        # 审计 scripts/
        scripts_dir = self.skill_path / 'scripts'
        all_issues.extend(self.audit_scripts(scripts_dir))

        # 审计 references/
        refs_dir = self.skill_path / 'references'
        all_issues.extend(self.audit_references(refs_dir))

        # 检查是否有 README.md 等不应该存在的文件
        for unwanted in ['README.md', 'INSTALLATION_GUIDE.md', 'QUICK_REFERENCE.md', 'CHANGELOG.md']:
            unwanted_file = self.skill_path / unwanted
            if unwanted_file.exists():
                all_issues.append({
                    'severity': 'low',
                    'category': 'unnecessary_file',
                    'file': unwanted,
                    'message': f'Unnecessary file: {unwanted}',
                    'suggestion': f'Remove {unwanted} - skills should only contain essential files',
                })

        # 按严重程度排序
        all_issues.sort(key=lambda x: (
            {'high': 0, 'medium': 1, 'low': 2}[x.get('severity', 'low')],
            x.get('file', ''),
        ))

        return {
            'skill_path': str(self.skill_path),
            'skill_md_stats': skill_md_stats,
            'total_issues': len(all_issues),
            'high_severity': len([i for i in all_issues if i.get('severity') == 'high']),
            'medium_severity': len([i for i in all_issues if i.get('severity') == 'medium']),
            'low_severity': len([i for i in all_issues if i.get('severity') == 'low']),
            'issues': all_issues,
        }

def main():
    import sys
    import json

    if len(sys.argv) < 2:
        print("Usage: python3 performance_audit.py <skill-path>")
        sys.exit(1)

    skill_path = sys.argv[1]
    auditor = PerformanceAuditor(skill_path)
    result = auditor.audit_skill()

    print(json.dumps(result, indent=2, ensure_ascii=False))

if __name__ == '__main__':
    main()


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