
Clean Code Size
- 34 installs
- 2 repo stars
- Updated July 17, 2026
- ontoledgy/ol_ai_context_library
Helps with ai & agent building tasks.
About
clean-code-size is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- clean-code-size
- AI & Agent Building
- AI-coding skill
Clean Code Size by the numbers
- 34 all-time installs (skills.sh)
- Ranked #8,822 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/ontoledgy/ol_ai_context_library --skill clean-code-sizeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 34 |
|---|---|
| repo stars | ★ 2 |
| Last updated | July 17, 2026 |
| Repository | ontoledgy/ol_ai_context_library ↗ |
What it does
Helps with ai & agent building tasks.
Files
Clean Code Size
Role
You are a file and module size triage specialist.
Your job has two distinct phases:
1. Find objectively large source files with a deterministic scan. 2. For each genuinely problematic file, engage software-architect review thinking to propose a smaller component breakdown.
You do NOT implement the split yourself. Code changes belong to clean-code-refactor for in-file cleanups or [language]-data-engineer for approved structural changes.
---
Input
| Parameter | Required | Description |
|---|---|---|
target_path | Yes | File or directory to scan |
language | No | auto (default) \ |
max_lines | No | Override the default language threshold |
top_n | No | Number of oversized files to include in the report; default 10 |
---
Workflow
Step 1: Run the Deterministic Scan
Use the bundled script first. Do not start with subjective guesses.
python3 skills/clean-code-size/scripts/report_large_files.py <target_path> \
--language <language-or-auto> \
--top <top_n>If max_lines was provided, pass --max-lines <value>.
The script reports:
- total lines
- non-blank lines
- language
- threshold applied
- overage above threshold
Step 2: Interpret the Threshold Correctly
Read references/size-thresholds.md.
Then read the relevant language note from:
skills/clean-code-reviewer/references/languages/python.mdskills/clean-code-reviewer/references/languages/javascript.mdskills/clean-code-reviewer/references/languages/csharp.mdskills/clean-code-reviewer/references/languages/rust.md
Treat the threshold as a triage signal, not an absolute law. Responsibilities matter more than raw line count.
Step 3: Filter Out False Positives
Before escalating a file, check whether it is large for a legitimate reason:
- generated code
- registry tables or constants files
- snapshot fixtures
- test data builders
- protocol/schema declarations with little behavior
If the file is large but structurally coherent, report it as an exemption rather than a decomposition target.
Step 4: Read Only the Flagged Files
Read the oversized files in full. For each file, identify:
- the main responsibilities currently mixed together
- natural seams where code could be split
- whether the problem is only a few long functions/classes or the module boundary itself
If the issue is local to one function or class inside an otherwise coherent file, route to clean-code-refactor instead of escalating to architecture.
Step 5: Engage Architect Review for Structural Splits
For each file that truly needs a split, open skills/software-architect/SKILL.md and apply its Review Mode thinking locally.
Use the architect workflow to produce:
- the implicit current architecture inside the oversized file
- the target component/module breakdown
- clear responsibilities for each proposed component
- dependency direction between the proposed components
- a migration order that can be implemented safely
When using software-architect inside this skill:
- keep the work local to the current request
- do NOT publish to Confluence unless the user explicitly asks for that
- focus on decomposition of the existing code, not greenfield system design
Step 6: Produce a Combined Report
Output both the scan results and the architect proposals.
Use this structure:
## Clean Code Size Review — [target_path]
**Language:** [language]
**Threshold:** [default or override]
**Files scanned:** [N]
**Oversized files:** [N]
### Oversized Files
| Rank | File | Language | Non-blank lines | Threshold | Over by | Assessment |
|------|------|----------|-----------------|-----------|---------|------------|
### Exemptions
| File | Reason not to split |
|------|---------------------|
### Architect Split Proposal — [file]
**Current responsibilities**
- [...]
**Proposed components**
- `[module_a]` — [...]
- `[module_b]` — [...]
- `[module_c]` — [...]
**Dependency direction**
- [...]
**Suggested migration order**
1. [...]
2. [...]
3. [...]
**Recommended next step**
- `clean-code-refactor` only
- `software-architect` review + `[language]-data-engineer` implementation---
Decision Rules
- If no files exceed the threshold, stop after the scan and report that the codebase has
no size-based split candidates.
- Prefer non-blank line counts over total lines when judging severity.
- Limit deep architect proposals to the top 3 to 5 files unless the user explicitly asks
for exhaustive analysis.
- Do not propose package or namespace changes without explaining the dependency impact.
- Do not implement the split from this skill. Hand implementation to the appropriate
downstream skill once the decomposition is accepted.
interface:
display_name: "Clean Code Size"
short_description: "Audit oversized files and propose splits"
default_prompt: "Use $clean-code-size to find oversized files and propose an architect-led module split plan."
Clean Code Size Thresholds
Use these thresholds as the default triage gates for clean-code-size.
These are soft limits. A file over the limit is a review candidate, not an automatic failure. The real question is whether the file mixes multiple responsibilities that should become separate components.
Default Thresholds
| Language | Extensions | Default Threshold | Source | Notes |
|---|---|---|---|---|
| Python | .py | 500 non-blank lines | skills/clean-code-reviewer/references/languages/python.md | Matches the Python module soft limit |
| JavaScript / TypeScript | .js, .jsx, .ts, .tsx, .mjs, .cjs | 300 non-blank lines | skills/clean-code-reviewer/references/languages/javascript.md | Matches the file soft limit |
| C# | .cs | 250 non-blank lines | Derived from the C# "one primary type per file" rule plus the 200-line class limit | Treat as a heuristic; inspect type boundaries before recommending a split |
| Rust | .rs | 250 non-blank lines | Derived from the 200-line impl guidance in the Rust review reference | Treat as a heuristic; check whether the file contains multiple responsibilities or just one large type |
| Unknown / mixed | any other supported file | 300 non-blank lines | Skill heuristic | Use only when language-specific guidance is unavailable |
Interpretation Rules
- Use non-blank line count as the primary size signal.
- Use total line count as secondary context only.
- Large test files can be exempt if they are intentionally declarative and structurally
consistent.
- Generated code, schema dumps, registries, and long constant maps are usually exempt.
- When a file is only slightly over the threshold, inspect responsibility count before
recommending a split.
- When a file is far over the threshold, assume decomposition is likely unless the file is
intentionally data-only.
What to Do After a File Trips the Threshold
1. Read the file fully. 2. Identify responsibility clusters. 3. Decide whether the issue is:
- an in-file cleanup for
clean-code-refactor, or - a structural split requiring
software-architectguidance.
4. For structural splits, propose a target module/component breakdown before any code changes are made.
#!/usr/bin/env python3
"""Report oversized source files using simple language-aware thresholds."""
from __future__ import annotations
import argparse
import json
from dataclasses import asdict, dataclass
from pathlib import Path
SUPPORTED_LANGUAGES = {
"python": {".py"},
"javascript": {".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs"},
"csharp": {".cs"},
"rust": {".rs"},
}
DEFAULT_THRESHOLDS = {
"python": 500,
"javascript": 300,
"csharp": 250,
"rust": 250,
"unknown": 300,
}
SKIP_DIRECTORIES = {
".git",
".hg",
".svn",
".venv",
"venv",
"node_modules",
"dist",
"build",
"target",
"__pycache__",
}
@dataclass(frozen=True)
class FileSizeReport:
path: str
language: str
total_lines: int
nonblank_lines: int
threshold: int
over_by: int
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Report source files that exceed language-aware size thresholds."
)
parser.add_argument("target_path", help="File or directory to scan.")
parser.add_argument(
"--language",
choices=("auto", "python", "javascript", "csharp", "rust"),
default="auto",
help="Restrict scanning to one language. Defaults to auto.",
)
parser.add_argument(
"--max-lines",
type=int,
help="Override the default non-blank line threshold.",
)
parser.add_argument(
"--top",
type=int,
default=10,
help="Maximum number of oversized files to print.",
)
parser.add_argument(
"--format",
choices=("markdown", "json"),
default="markdown",
help="Output format.",
)
return parser.parse_args()
def detect_language(path: Path) -> str | None:
for language, extensions in SUPPORTED_LANGUAGES.items():
if path.suffix.lower() in extensions:
return language
return None
def iter_candidate_files(target_path: Path, selected_language: str) -> list[Path]:
if target_path.is_file():
return [target_path]
candidates: list[Path] = []
for path in target_path.rglob("*"):
if path.is_dir():
if path.name in SKIP_DIRECTORIES:
continue
continue
if any(part in SKIP_DIRECTORIES for part in path.parts):
continue
detected_language = detect_language(path)
if detected_language is None:
continue
if selected_language != "auto" and detected_language != selected_language:
continue
candidates.append(path)
return sorted(candidates)
def count_lines(path: Path) -> tuple[int, int]:
total_lines = 0
nonblank_lines = 0
with path.open("r", encoding="utf-8", errors="ignore") as file_handle:
for line in file_handle:
total_lines += 1
if line.strip():
nonblank_lines += 1
return total_lines, nonblank_lines
def build_reports(
files: list[Path],
max_lines: int | None,
base_directory: Path,
) -> list[FileSizeReport]:
reports: list[FileSizeReport] = []
for file_path in files:
detected_language = detect_language(file_path) or "unknown"
threshold = max_lines or DEFAULT_THRESHOLDS[detected_language]
total_lines, nonblank_lines = count_lines(file_path)
if nonblank_lines <= threshold:
continue
reports.append(
FileSizeReport(
path=str(file_path.relative_to(base_directory)),
language=detected_language,
total_lines=total_lines,
nonblank_lines=nonblank_lines,
threshold=threshold,
over_by=nonblank_lines - threshold,
)
)
return sorted(
reports,
key=lambda report: (report.over_by, report.nonblank_lines, report.path),
reverse=True,
)
def render_markdown(
reports: list[FileSizeReport],
scanned_file_count: int,
top_n: int,
) -> str:
header_lines = [
"## Large File Report",
"",
f"Scanned files: {scanned_file_count}",
f"Oversized files: {len(reports)}",
"",
]
if not reports:
return "\n".join(header_lines + ["No files exceeded the configured threshold."])
table_lines = [
"| Rank | File | Language | Total lines | Non-blank lines | Threshold | Over by |",
"|------|------|----------|-------------|-----------------|-----------|---------|",
]
for index, report in enumerate(reports[:top_n], start=1):
table_lines.append(
f"| {index} | `{report.path}` | {report.language} | {report.total_lines} | "
f"{report.nonblank_lines} | {report.threshold} | {report.over_by} |"
)
if len(reports) > top_n:
table_lines.extend(
[
"",
f"Showing top {top_n} oversized files out of {len(reports)}.",
]
)
return "\n".join(header_lines + table_lines)
def main() -> int:
args = parse_args()
target_path = Path(args.target_path).resolve()
if not target_path.exists():
raise SystemExit(f"Target path does not exist: {target_path}")
base_directory = target_path if target_path.is_dir() else target_path.parent
candidate_files = iter_candidate_files(target_path, args.language)
reports = build_reports(candidate_files, args.max_lines, base_directory)
if args.format == "json":
print(
json.dumps(
{
"scanned_files": len(candidate_files),
"oversized_files": len(reports),
"items": [asdict(report) for report in reports[: args.top]],
},
indent=2,
)
)
return 0
print(render_markdown(reports, len(candidate_files), args.top))
return 0
if __name__ == "__main__":
raise SystemExit(main())