"""Exemption tables for the 250-line file-length cap. The data half: which extensions are capped, and which paths are generated, vendored, third-party or session artifacts. :mod:`file_length.exemptions` holds the rules that read these, and :mod:`file_length.config` re-exports both as the public surface. Duplicating these lists in shell is what lets a gate and a survey silently disagree, so they live here once. """ from __future__ import annotations import re #: Hard cap. Files above this fail the gate. Code and prose alike. MAX_LINES = 250 #: Extensions the cap applies to: real programming languages plus prose. #: Markup (.html/.css/.scss) is deliberately absent -- templates split into #: partials, not functions, so a line cap does not express anything useful. CAPPED_EXTENSIONS = { # code ".py", ".dart", ".ts", ".tsx", ".js", ".jsx", ".sh", ".bash", ".zsh", ".c", ".h", ".cpp", ".cc", ".hpp", ".go", ".rs", ".java", ".kt", ".kts", ".swift", ".rb", ".lua", ".sql", ".vue", ".cs", ".php", # prose ".md", ".markdown", ".txt", ".rst", ".tex", ".org", } #: Generated files: regenerated by a tool, so splitting them is meaningless #: (the tool would just rewrite the original next run). GENERATED_PATTERN = re.compile( r"\.g\.dart$" r"|\.freezed\.dart$" r"|\.gr\.dart$" r"|\.config\.dart$" r"|\.mocks\.dart$" r"|\.min\.(js|css)$" r"|\.pb\.(go|py)$" r"|_pb2(_grpc)?\.py$" r"|\.generated\.ts$" r"|\.d\.ts$" r"|/l10n/generated/" r"|/generated/" ) #: A marker in the first few lines also marks a file generated. Covers tools #: that do not use a distinguishing extension. GENERATED_MARKERS = ( "GENERATED CODE - DO NOT MODIFY", "@generated", "DO NOT EDIT", "Autogenerated", "AUTOGENERATED", "generated by", ) #: Directory names never descended into: dependencies, build output, caches. EXCLUDED_DIRS = frozenset( { ".git", "node_modules", ".dart_tool", "build", ".venv", "venv", "env", "site-packages", "target", "ephemeral", "__pycache__", ".mypy_cache", ".pytest_cache", ".ruff_cache", "dist", ".next", "vendor", "third_party", "Pods", ".gradle", ".idea", ".cxx", "coverage", "htmlcov", ".tox", "Library", "Temp", "obj", ".terraform", ".fvm", ".angular", ".cache", ".svelte-kit", "migrations", ".ci-mirror-venv", ".hippo", ".build-deps", # Where CI checks out the shared gate itself (kuhyx/utils). Without # this, a repo's lint job fails on utils' own long files -- a gate # that fails for reasons the repo being gated cannot fix. ".utils", } ) #: Third-party content living *inside* a repo you own, keyed by repo dir name. #: Verified by git remote / vendor manifest, not guessed. VENDORED_SUBPATHS = { "mcp-servers": ("servers",), "dufs-cloud": ("app/assets/pdfjs", "web/assets/pdfjs"), # godot-cpp bindings, a git submodule of github.com/godotengine/godot-cpp. "legatus": ("gdextension/godot-cpp",), ".claude": ( "projects", "shell-snapshots", "cache", "backups", "todos", "statsig", "history", "chrome", "downloads", "plugins", "ide", ), # Agent skill bundles vendored from Anthropic (todo: commit f91311f). # A SKILL.md is a fixed-name file with frontmatter; detail belongs in a # sibling references/ dir, so splitting one into SKILL.part2.md would # break the format rather than improve readability. "todo": (".agents/skills",), # University coursework archive. The authoritative list, with a verified # reason per entry, is gates/vendored.txt in that repo -- this tuple is a # mirror of it. Keep the two in step (`./run.sh sync-vendored` there). "WUT_Computer_Science": ( # ASP.NET scaffolder's jQuery/Bootstrap dist bundle: 30,875 lines of # JS and 43,027 of CSS, ~98% of all JS and CSS in the repo. "Programming/EGUI/lab2/lab2/wwwroot/lib", # Stock Unity package and new-project template content. "Programming/E-PSYOPS/theProject/Assets/TextMesh Pro", "Programming/E-PSYOPS/theProject/Assets/TutorialInfo", # Manufacturer-supplied Altium/EAGLE/PADS component libraries. "NotProgramming/EMISY/componentSchematic", "NotProgramming/EMISY/schematic", # EOPSY simulators shipped by the department as tarballs; work/ is the # extraction target of `make setup`. Verified 2026-08-28 by extracting # ftp/sched.tgz and ftp/memory.tgz and diffing: 14/14 java files # byte-identical to the originals, so nothing here is student-written. "Programming/EOPSY/lab3/task3/work", "Programming/EOPSY/lab4/task4/work", # sightpy, the BSD-3 ray tracer from rafael-fuente/Python-Raytracer. # Verified 2026-08-28 against a fresh upstream clone, line endings # normalised: 30/32 .py byte-identical; ray.py and scene.py carry a # 12- and 13-line local patch adding ray counters for the report. "Programming/TRAK/sightpy", ), } #: Directory names that mark a vendored agent-skill tree wherever they appear. #: Keyed by name rather than repo because these bundles get dropped into any #: repo that wants them, not just the one they were first seen in. VENDORED_ANYWHERE = ("/.agents/skills/", "/.claude/skills/") #: Frozen records of past agent sessions: an implementation plan or an #: append-only session log describes what was done at one moment. Splitting one #: rewrites a historical record for no reading benefit -- nobody navigates them, #: they are read whole or not at all. Same category as generated files. #: #: Deliberately NOT the whole of docs/superpowers/: `specs/` and `contracts/` #: stay capped, because those are living documents that get re-read and edited. SESSION_ARTIFACTS_ANYWHERE = ( "/docs/superpowers/plans/", "/docs/superpowers/sessions/", ) #: Whole repos under ~ that are third-party clones, not kuhy's work. #: Verified 2026-08-14 by `git remote get-url origin` + commit authors. #: 2026-08-28: StringTheory / reaper-mcp / freesound-mcp deleted from disk. THIRD_PARTY_REPOS = frozenset( { "llama_cpp_dart_local", # generated FFI bindings "aseprite-mcp", "Mapperatorinator", # github.com/OliBomby/Mapperatorinator "aur", "build-your-own-x", "build_your_x", "byox-ladder", "warriorjs", "untools", "awesome-mcp-explorer", "runnerup", "depotdownloader", "actions-runner", } ) #: A `.txt` whose mean line is shorter than this is data (a wordlist, a #: coordinate dump), not prose, so the cap does not apply. DATA_TXT_MAX_MEAN_LINE = 25