code-qc

ClawSkills 作者 clawskills

Run a structured quality control audit on any codebase. Use when asked to QC, audit, review, or check code quality for a project. Supports Python, TypeScript, GDScript, and general projects. Produces a standardized report with PASS/WARN/FAIL verdict, covering tests, imports, type checking, static analysis, smoke tests, and documentation. Also use when asked to compare QC results over time.

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install clawskills:clawskills~isonaei-code-qc
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/clawskills%3Aclawskills~isonaei-code-qc/file -o isonaei-code-qc.md
# Code QC

Structured quality control audit for codebases. Delegates static analysis to proper tools (ruff, eslint, gdlint) and focuses on what AI adds: semantic understanding, cross-module consistency, and dynamic smoke test generation.

## Quick Start

1. Detect project type (read the profile for that language)
2. Load `.qc-config.yaml` if present (for custom thresholds/exclusions)
3. Run the 8-phase audit (or subset with `--quick`)
4. Generate report with verdict
5. Save baseline for future comparison

## Configuration (`.qc-config.yaml`)

Optional project-level config for monorepos and custom settings:

```yaml
# .qc-config.yaml
thresholds:
  test_failure_rate: 0.05    # >5% = FAIL, 0-5% = WARN, 0% = PASS
  lint_errors_max: 0         # Max lint errors before FAIL
  lint_warnings_max: 50      # Max warnings before WARN
  type_errors_max: 0         # Max type errors before FAIL (strict by default)

exclude:
  dirs: [vendor, third_party, generated]
  files: ["*_generated.py", "*.pb.go"]

changed_only: false          # Only check git-changed files (CI mode)
fail_fast: false             # Stop on first failure
quick_mode: false            # Only run Phase 1, 3, 3.5, 6

languages:
  python:
    min_coverage: 80
    ignore_rules: [T201]     # Allow print in this project
  typescript:
    strict_mode: true        # Require tsconfig strict: true
    ignore_rules: []         # eslint rules to ignore
  gdscript:
    godot_version: "4.2"
```

## Execution Modes

| Mode | Phases Run | Use Case |
|------|------------|----------|
| Full (default) | All 8 phases | Thorough audit |
| `--quick` | 1, 3, 3.5, 6 | Fast sanity check |
| `--changed-only` | All, filtered | CI on pull requests |
| `--fail-fast` | All, stops early | Find first issue fast |
| `--fix` | 3 with autofix | Apply automatic fixes |

## Phase Overview

| # | Phase | What | Tools |
|---|-------|------|-------|
| 1 | Test Suite | Run existing tests + coverage | pytest --cov / jest --coverage |
| 2 | Import Integrity | Verify all modules load | `scripts/import_check.py` |
| 3 | Static Analysis | Lint with proper tools | ruff / eslint / gdlint |
| 3.5 | Type Checking | Static type verification | mypy / tsc --noEmit / (N/A for GDScript) |
| 4 | Smoke Tests | Verify business logic works | AI-generated per project |
| 5 | UI/Frontend | Verify UI components load | Framework-specific |
| 6 | File Consistency | Syntax + git state | `scripts/syntax_check.py` + git |
| 7 | Documentation | Docstrings + docs accuracy | `scripts/docstring_check.py` |

## Phase Details

### Phase 1: Test Suite

Run the project's test suite with coverage. Auto-detect the test runner:

```
pytest.ini / pyproject.toml [tool.pytest] → pytest --cov
package.json scripts.test → npm test (or npx vitest --coverage)
Cargo.toml → cargo test
project.godot → (GUT if present, else manual)
```

**Record:** total, passed, failed, errors, skipped, duration, coverage %.

**Verdict contribution:**
- No tests found → **SKIP** (not FAIL; project may be config-only)
- Failure rate = 0% → **PASS**
- Failure rate ≤ threshold (default 5%) → **WARN**
- Failure rate > threshold → **FAIL**

**Coverage reporting (Python):**
```bash
pytest --cov=<package> --cov-report=term-missing --cov-report=json
```

### Phase 2: Import Integrity (Python/GDScript)

**Python:** Run `scripts/import_check.py` against the project root.

**GDScript:** Verify scene/preload references are valid (see gdscript-profile.md).

#### Critical vs Optional Import Classification

Use these heuristics to classify import failures:

| Pattern | Classification | Rationale |
|---------|---------------|-----------|
| `__init__.py`, `main.py`, `app.py`, `cli.py` | **Critical** | Core entry points |
| Module in `src/`, `lib/`, or top-level package | **Critical** | Core functionality |
| `*_test.py`, `test_*.py`, `conftest.py` | **Optional** | Test infrastructure |
| Modules in `examples/`, `scripts/`, `tools/` | **Optional** | Auxiliary code |
| Import error mentions `cuml`, `triton`, `tensorrt` | **Optional** | Hardware-specific |
| Import error mentions missing system lib | **Optional** | Environment-specific |
| Dependency in `[project.optional-dependencies]` | **Optional** | Declared optional |

### Phase 3: Static Analysis

**Do NOT use grep.** Use the language's standard linter.

#### Standard Mode
```bash
# Python
ruff check --select E722,T201,B006,F401,F841,UP,I --statistics <project>

# TypeScript  
npx eslint . --format json

# GDScript
gdlint <project>
```

#### Fix Mode (`--fix`)
When `--fix` is specified, apply automatic corrections:

```bash
# Python — safe auto-fixes
ruff check --fix --select E,F,I,UP <project>
ruff format <project>

# TypeScript
npx eslint . --fix

# GDScript
gdformat <project>
```

**Important:** After `--fix`, re-run the check to report remaining issues that couldn't be auto-fixed.

### Phase 3.5: Type Checking (NEW)

Run static type analysis before proceeding to runtime checks.

**Python:**
```bash
mypy <package> --ignore-missing-imports --no-error-summary
# or if pyproject.toml has [tool.pyright]:
pyright <package>
```

**TypeScript:**
```bash
npx tsc --noEmit
```

**GDScript:** Godot 4 has built-in static typing but no standalone checker. Estimate type coverage manually:

```bash
# Find untyped declarations
grep -rn "var \w\+ =" --include="*.gd" .       # Untyped variables
grep -rn "func \w\+(" --include="*.gd" . | grep -v ":"  # Untyped functions
```

Use the `estimate_type_coverage()` function from `gdscript-profile.md` to calculate coverage per file:
```python
# From gdscript-profile.md
def estimate_type_coverage(gd_file: str) -> float:
    """Count typed vs untyped declarations."""
    # See full implementation in gdscript-profile.md
```

Also check for `@warning_ignore` annotations which may hide type issues.

**Record:** Total errors, categorized by severity.

### Phase 4: Smoke Tests (Business Logic)

Test **backend/core functionality** — NOT UI components (that's Phase 5).

**API Discovery Heuristics:**

1. **Entry points:** Look for `main()`, `cli()`, `app`, `create_app()`, `__main__.py`
2. **Service layer:** Find classes/modules named `*Service`, `*Manager`, `*Handler`  
3. **Public API:** Check `__all__` exports in `__init__.py`
4. **FastAPI/Flask:** Find route decorators (`@app.get`, `@router.post`)
5. **CLI:** Find typer/click `@app.command()` decorators
6. **SDK:** Look for client classes, public methods without `_` prefix

**For each discovered API, generate a minimal test:**
```python
def smoke_test_user_service():
    """Test UserService basic CRUD."""
    from myproject.services.user import UserService
    svc = UserService(db=":memory:")
    user = svc.create(name="test")
    assert user.id is not None
    fetched = svc.get(user.id)
    assert fetched.name == "test"
    return "PASS"
```

**Guidelines:**
- Import + instantiate + call one method with minimal valid input
- Use in-memory/temp resources (`:memory:`, `tempdir`)
- Each test < 5 seconds
- Catch exceptions, report clearly

### Phase 5: UI/Frontend Verification

Test **UI components** separately from business logic.

| Framework | Test Method |
|-----------|-------------|
| **Gradio** | `from project.ui import create_ui` (no `launch()`) |
| **Streamlit** | `streamlit run app.py --headless` exits cleanly |
| **PyQt/PySide** | Set `QT_QPA_PLATFORM=offscreen`, import widget modules |
| **React** | `npm run build` succeeds |
| **Vue** | `npm run build` succeeds |
| **Godot** | Scene files parse without error, required scripts exist |
| **CLI** | `--help` on all subcommands returns 0 |

**Boundary:** Phase 4 tests "does the logic work?" Phase 5 tests "does the UI render?"

### Phase 6: File Consistency

Run `scripts/syntax_check.py` — compiles all source files to verify no syntax errors.

> **Note:** Phase 2 (Import Integrity) tests *runtime* import behavior including initialization code. Phase 6 tests *static* syntax correctness. Both are needed: a file can have valid syntax but fail