mirror of
https://github.com/SuperClaude-Org/SuperClaude_Framework.git
synced 2025-12-29 16:16:08 +00:00
Introduces a multi-expert specification review and improvement system powered by renowned software engineering and specification experts. This command transforms technical specifications through the lens of industry experts, providing actionable feedback and systematic improvement recommendations. 🎯 Key Features Expert Panel System - 10 Industry Experts: Karl Wiegers, Gojko Adzic, Alistair Cockburn, Martin Fowler, Michael Nygard, Sam Newman, Gregor Hohpe, Lisa Crispin, Janet Gregory, and Kelsey Hightower - Domain Specialization: Requirements engineering, architecture, testing, compliance, and cloud-native patterns - Authentic Methodologies: Each expert applies their real-world frameworks and critique styles Analysis Modes - Discussion Mode: Collaborative improvement through expert dialogue - Critique Mode: Systematic review with prioritized recommendations - Socratic Mode: Learning-focused questioning for deeper understanding Focus Areas - Requirements: Clarity, completeness, testability validation - Architecture: Interface design, scalability, maintainability analysis - Testing: Quality attributes, coverage, edge case identification - Compliance: Regulatory requirements, security, operational excellence 🔧 Technical Implementation Command Structure /sc:spec-panel [content|@file] [--mode discussion|critique|socratic] [--focus area] [--iterations N] MCP Integration - Sequential MCP: Expert panel coordination and structured analysis - Context7 MCP: Industry patterns and best practices - Persona System: Technical Writer, System Architect, Quality Engineer activation Quality Metrics - Clarity Score (0-10): Language precision and understandability - Completeness Score (0-10): Coverage of essential elements - Testability Score (0-10): Measurability and validation capability - Consistency Score (0-10): Internal coherence assessment 📊 Output Examples Expert Critique Format KARL WIEGERS - Requirements Engineering: ❌ CRITICAL: Password complexity requirements not specified 📝 RECOMMENDATION: Add requirement "System SHALL enforce password complexity: minimum 8 characters, mixed case, numbers" 🎯 PRIORITY: High - Security vulnerability without standards 📊 QUALITY IMPACT: +35% security compliance, +20% completeness Improvement Roadmap - Immediate: Critical security and clarity issues - Short-term: Architecture refinements and testing strategies - Long-term: Evolution planning and advanced optimizations 🚀 Integration Patterns Workflow 1. Generate specification using https://github.com/github/spec-kit/blob/main/spec-driven.md 2. Review and improve with expert panel 3. Iterative refinement based on feedback CI/CD Integration - Specification validation in development workflow - Quality gate enforcement with automated checks - Version control integration for evolution tracking 📈 Quality Impact Based on an example review: - Security Completeness: +35% improvement - Requirements Clarity: +14% improvement - Testability Score: +19% improvement - Production Readiness: +47% improvement - Overall Quality: +24% improvement 🎓 Learning Features Educational Value - Socratic questioning mode for skill development - Expert methodology exposure and learning - Progressive specification writing guidance - Best practice pattern recognition Mentoring Integration - Step-by-step improvement guidance - Industry standard alignment - Professional specification writing techniques 🔗 Files Changed - SuperClaude/Commands/spec-panel.md - Complete command specification 🧪 Testing Includes comprehensive examples: - API specification review with security focus - Requirements workshop with collaborative analysis - Architecture validation with socratic questioning - Multi-iteration improvement workflows This feature significantly enhances SuperClaude's specification analysis capabilities, providing professional-grade review and improvement guidance through authentic expert perspectives and proven methodologies.
312 lines
14 KiB
YAML
312 lines
14 KiB
YAML
name: README Quality Check
|
||
|
||
on:
|
||
pull_request:
|
||
paths:
|
||
- 'README*.md'
|
||
- 'Docs/**/*.md'
|
||
push:
|
||
branches: [main, master, develop]
|
||
workflow_dispatch:
|
||
|
||
permissions:
|
||
contents: read
|
||
pull-requests: write
|
||
issues: write
|
||
|
||
jobs:
|
||
readme-quality-check:
|
||
name: Multi-language README Quality Assessment
|
||
runs-on: ubuntu-latest
|
||
|
||
steps:
|
||
- name: Checkout repository
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Set up Python
|
||
uses: actions/setup-python@v5
|
||
with:
|
||
python-version: '3.11'
|
||
|
||
- name: Install dependencies
|
||
run: |
|
||
python -m pip install --upgrade pip
|
||
pip install requests beautifulsoup4 pyyaml
|
||
|
||
- name: Create quality checker script
|
||
run: |
|
||
cat > readme_checker.py << 'EOF'
|
||
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
SuperClaude多语言README质量检查器
|
||
检查版本同步、链接有效性、结构一致性
|
||
"""
|
||
|
||
import os
|
||
import re
|
||
import requests
|
||
import json
|
||
from pathlib import Path
|
||
from urllib.parse import urljoin
|
||
|
||
class READMEQualityChecker:
|
||
def __init__(self):
|
||
self.readme_files = ['README.md', 'README-zh.md', 'README-ja.md']
|
||
self.results = {
|
||
'structure_consistency': [],
|
||
'link_validation': [],
|
||
'translation_sync': [],
|
||
'overall_score': 0
|
||
}
|
||
|
||
def check_structure_consistency(self):
|
||
"""检查结构一致性"""
|
||
print("🔍 检查结构一致性...")
|
||
|
||
structures = {}
|
||
for file in self.readme_files:
|
||
if os.path.exists(file):
|
||
with open(file, 'r', encoding='utf-8') as f:
|
||
content = f.read()
|
||
# 提取标题结构
|
||
headers = re.findall(r'^#{1,6}\s+(.+)$', content, re.MULTILINE)
|
||
structures[file] = len(headers)
|
||
|
||
# 比较结构差异
|
||
line_counts = [structures.get(f, 0) for f in self.readme_files if f in structures]
|
||
if line_counts:
|
||
max_diff = max(line_counts) - min(line_counts)
|
||
consistency_score = max(0, 100 - (max_diff * 5))
|
||
|
||
self.results['structure_consistency'] = {
|
||
'score': consistency_score,
|
||
'details': structures,
|
||
'status': 'PASS' if consistency_score >= 90 else 'WARN'
|
||
}
|
||
|
||
print(f"✅ 结构一致性: {consistency_score}/100")
|
||
for file, count in structures.items():
|
||
print(f" {file}: {count} headers")
|
||
|
||
def check_link_validation(self):
|
||
"""检查链接有效性"""
|
||
print("🔗 检查链接有效性...")
|
||
|
||
all_links = {}
|
||
broken_links = []
|
||
|
||
for file in self.readme_files:
|
||
if os.path.exists(file):
|
||
with open(file, 'r', encoding='utf-8') as f:
|
||
content = f.read()
|
||
|
||
# 提取所有链接
|
||
links = re.findall(r'\[([^\]]+)\]\(([^)]+)\)', content)
|
||
all_links[file] = []
|
||
|
||
for text, url in links:
|
||
link_info = {'text': text, 'url': url, 'status': 'unknown'}
|
||
|
||
# 检查本地文件链接
|
||
if not url.startswith(('http://', 'https://', '#')):
|
||
if os.path.exists(url):
|
||
link_info['status'] = 'valid'
|
||
else:
|
||
link_info['status'] = 'broken'
|
||
broken_links.append(f"{file}: {url}")
|
||
|
||
# HTTP链接检查(简化版)
|
||
elif url.startswith(('http://', 'https://')):
|
||
try:
|
||
# 只检查几个关键链接,避免过多请求
|
||
if any(domain in url for domain in ['github.com', 'pypi.org', 'npmjs.com']):
|
||
response = requests.head(url, timeout=10, allow_redirects=True)
|
||
link_info['status'] = 'valid' if response.status_code < 400 else 'broken'
|
||
else:
|
||
link_info['status'] = 'skipped'
|
||
except:
|
||
link_info['status'] = 'error'
|
||
else:
|
||
link_info['status'] = 'anchor'
|
||
|
||
all_links[file].append(link_info)
|
||
|
||
# 计算链接健康度
|
||
total_links = sum(len(links) for links in all_links.values())
|
||
broken_count = len(broken_links)
|
||
link_score = max(0, 100 - (broken_count * 10)) if total_links > 0 else 100
|
||
|
||
self.results['link_validation'] = {
|
||
'score': link_score,
|
||
'total_links': total_links,
|
||
'broken_links': broken_count,
|
||
'broken_list': broken_links[:10], # 最多显示10个
|
||
'status': 'PASS' if link_score >= 80 else 'FAIL'
|
||
}
|
||
|
||
print(f"✅ 链接有效性: {link_score}/100")
|
||
print(f" 总链接数: {total_links}")
|
||
print(f" 损坏链接: {broken_count}")
|
||
|
||
def check_translation_sync(self):
|
||
"""检查翻译同步性"""
|
||
print("🌍 检查翻译同步性...")
|
||
|
||
if not all(os.path.exists(f) for f in self.readme_files):
|
||
print("⚠️ 缺少某些README文件")
|
||
self.results['translation_sync'] = {
|
||
'score': 60,
|
||
'status': 'WARN',
|
||
'message': '缺少某些README文件'
|
||
}
|
||
return
|
||
|
||
# 检查文件修改时间
|
||
mod_times = {}
|
||
for file in self.readme_files:
|
||
mod_times[file] = os.path.getmtime(file)
|
||
|
||
# 计算时间差异(秒)
|
||
times = list(mod_times.values())
|
||
time_diff = max(times) - min(times)
|
||
|
||
# 根据时间差评分(7天内修改认为是同步的)
|
||
sync_score = max(0, 100 - (time_diff / (7 * 24 * 3600) * 20))
|
||
|
||
self.results['translation_sync'] = {
|
||
'score': int(sync_score),
|
||
'time_diff_days': round(time_diff / (24 * 3600), 2),
|
||
'status': 'PASS' if sync_score >= 80 else 'WARN',
|
||
'mod_times': {f: f"{os.path.getmtime(f):.0f}" for f in self.readme_files}
|
||
}
|
||
|
||
print(f"✅ 翻译同步性: {int(sync_score)}/100")
|
||
print(f" 最大时间差: {round(time_diff / (24 * 3600), 1)} 天")
|
||
|
||
def generate_report(self):
|
||
"""生成质量报告"""
|
||
print("\n📊 生成质量报告...")
|
||
|
||
# 计算总分
|
||
scores = [
|
||
self.results['structure_consistency'].get('score', 0),
|
||
self.results['link_validation'].get('score', 0),
|
||
self.results['translation_sync'].get('score', 0)
|
||
]
|
||
overall_score = sum(scores) // len(scores)
|
||
self.results['overall_score'] = overall_score
|
||
|
||
# 生成GitHub Actions摘要
|
||
pipe = "|"
|
||
table_header = f"{pipe} 检查项目 {pipe} 分数 {pipe} 状态 {pipe} 详情 {pipe}"
|
||
table_separator = f"{pipe}----------|------|------|------|"
|
||
table_row1 = f"{pipe} 📐 结构一致性 {pipe} {self.results['structure_consistency'].get('score', 0)}/100 {pipe} {self.results['structure_consistency'].get('status', 'N/A')} {pipe} {len(self.results['structure_consistency'].get('details', {}))} 个文件 {pipe}"
|
||
table_row2 = f"{pipe} 🔗 链接有效性 {pipe} {self.results['link_validation'].get('score', 0)}/100 {pipe} {self.results['link_validation'].get('status', 'N/A')} {pipe} {self.results['link_validation'].get('broken_links', 0)} 个损坏链接 {pipe}"
|
||
table_row3 = f"{pipe} 🌍 翻译同步性 {pipe} {self.results['translation_sync'].get('score', 0)}/100 {pipe} {self.results['translation_sync'].get('status', 'N/A')} {pipe} {self.results['translation_sync'].get('time_diff_days', 0)} 天差异 {pipe}"
|
||
|
||
summary_parts = [
|
||
"## 📊 README质量检查报告",
|
||
"",
|
||
f"### 🏆 总体评分: {overall_score}/100",
|
||
"",
|
||
table_header,
|
||
table_separator,
|
||
table_row1,
|
||
table_row2,
|
||
table_row3,
|
||
"",
|
||
"### 📋 详细信息",
|
||
"",
|
||
"**结构一致性详情:**"
|
||
]
|
||
summary = "\n".join(summary_parts)
|
||
|
||
for file, count in self.results['structure_consistency'].get('details', {}).items():
|
||
summary += f"\n- `{file}`: {count} 个标题"
|
||
|
||
if self.results['link_validation'].get('broken_links'):
|
||
summary += f"\n\n**损坏链接列表:**\n"
|
||
for link in self.results['link_validation']['broken_list']:
|
||
summary += f"\n- ❌ {link}"
|
||
|
||
summary += f"\n\n### 🎯 建议\n"
|
||
|
||
if overall_score >= 90:
|
||
summary += "✅ 质量优秀!继续保持。"
|
||
elif overall_score >= 70:
|
||
summary += "⚠️ 质量良好,有改进空间。"
|
||
else:
|
||
summary += "🚨 需要改进!请检查上述问题。"
|
||
|
||
# 写入GitHub Actions摘要
|
||
github_step_summary = os.environ.get('GITHUB_STEP_SUMMARY')
|
||
if github_step_summary:
|
||
with open(github_step_summary, 'w', encoding='utf-8') as f:
|
||
f.write(summary)
|
||
|
||
# 保存详细结果
|
||
with open('readme-quality-report.json', 'w', encoding='utf-8') as f:
|
||
json.dump(self.results, f, indent=2, ensure_ascii=False)
|
||
|
||
print("✅ 报告已生成")
|
||
|
||
# 根据分数决定退出码
|
||
return 0 if overall_score >= 70 else 1
|
||
|
||
def run_all_checks(self):
|
||
"""运行所有检查"""
|
||
print("🚀 开始README质量检查...\n")
|
||
|
||
self.check_structure_consistency()
|
||
self.check_link_validation()
|
||
self.check_translation_sync()
|
||
|
||
exit_code = self.generate_report()
|
||
|
||
print(f"\n🎯 检查完成!总分: {self.results['overall_score']}/100")
|
||
return exit_code
|
||
|
||
if __name__ == "__main__":
|
||
checker = READMEQualityChecker()
|
||
exit_code = checker.run_all_checks()
|
||
exit(exit_code)
|
||
EOF
|
||
|
||
- name: Run README quality check
|
||
run: python readme_checker.py
|
||
|
||
- name: Upload quality report
|
||
if: always()
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: readme-quality-report
|
||
path: readme-quality-report.json
|
||
retention-days: 30
|
||
|
||
- name: Comment PR (if applicable)
|
||
if: github.event_name == 'pull_request' && always() && github.event.pull_request.head.repo.full_name == github.repository
|
||
uses: actions/github-script@v7
|
||
with:
|
||
script: |
|
||
const fs = require('fs');
|
||
|
||
if (fs.existsSync('readme-quality-report.json')) {
|
||
const report = JSON.parse(fs.readFileSync('readme-quality-report.json', 'utf8'));
|
||
|
||
const score = report.overall_score;
|
||
const emoji = score >= 90 ? '🏆' : score >= 70 ? '✅' : '⚠️';
|
||
|
||
const comment = `${emoji} **README质量检查结果: ${score}/100**\n\n` +
|
||
`📐 结构一致性: ${report.structure_consistency?.score || 0}/100\n` +
|
||
`🔗 链接有效性: ${report.link_validation?.score || 0}/100\n` +
|
||
`🌍 翻译同步性: ${report.translation_sync?.score || 0}/100\n\n` +
|
||
`查看详细报告请点击 Actions 标签页。`;
|
||
|
||
github.rest.issues.createComment({
|
||
issue_number: context.issue.number,
|
||
owner: context.repo.owner,
|
||
repo: context.repo.repo,
|
||
body: comment
|
||
});
|
||
} |