| name | check-license |
| description | Check for a license file (LICENSE, LICENSE.txt, LICENSE.md, COPYING, etc.) in the repository root, and if one exists, verify every source and test file carries a header consistent with it. Learns the header format from files that already have one; if none carry a header yet, generates a standard header for that license type. Invoke as `/check-license` to scan the whole repository, or `/check-license <path-or-glob>` to scope the check to specific files/directories. Use whenever the user wants license-header compliance checked or backfilled, instead of eyeballing individual files. |
Check License
Verify that source and test files in this repository carry a license header consistent with the repository's
license, and add one to any file that's missing it or has it wrong. This skill only adds/fixes header comments —
it does not change code logic, signatures, formatting, or existing non-header comments. It makes no assumptions
about this being any particular repository or language — discover the license and the header convention fresh
each run.
Step 1 — Find the license
Look in the repository root for a license file: LICENSE, LICENSE.txt, LICENSE.md, COPYING, COPYING.txt,
or similar (case-insensitive). Also check pom.xml/package.json/build.gradle/setup.py/Cargo.toml etc. for
a declared license identifier (e.g. Maven's <licenses> block, npm's "license" field) — it can confirm which
license the root file represents and surface a copyright holder or inception year if the file itself omits one.
- No license file found and no license declared anywhere: tell the user there's nothing to check against and
stop. Don't invent a license or a header.
- License file found: read it fully and identify which license it is (Apache-2.0, MIT, BSD-3-Clause, GPL,
MPL, etc.) from its title/boilerplate text. This determines the content of the header (which notice text a
compliant header must contain) — see Step 3 for exactly what "consistent with it" means per license family.
Step 2 — Determine the scope of files to check
- Argument provided (a path or glob): scope the check to files matching it.
- No argument: scope to every source and test file in the repository's actual source roots (e.g.
src/main,
src/test for Maven/Gradle Java projects; src/, lib/, test/ for other stacks — discover the real layout
rather than assuming one). Skip generated/vendored directories (target/, build/, node_modules/, dist/,
.git/, anything matching the project's own .gitignore) and non-code files (config, markdown, data) unless
the project's existing headers (found in Step 3) show those file types are also headered.
- Determine the set of distinct source file extensions actually present in scope (
.java, .js, .ts, .py,
.go, .xml, etc.) — each may need its own comment-syntax variant of the same header (see Step 3).
Step 3 — Learn the existing header convention (or fall back to a standard one)
For each file extension found in Step 2, search a sample of in-scope files for an existing header — a comment
block at the very top of the file (before package/import/module/shebang lines) that mentions the license
name, a copyright line, or a URL to the license text:
- If a header is found: use it verbatim as the template for that extension — same comment delimiters
(
/* ... */, //, #, <!-- -->, etc.), same wording, same line wrapping, same copyright line format
(holder name, contact, year). Cross-check 2-3 more instances of that extension to confirm the format is
consistent repo-wide; if instances disagree, prefer the version used by the newest files (git log -1 -- <file> per candidate) and note the inconsistency in the final report rather than silently picking one.
- If no header exists anywhere in the repo for any extension: don't generate anything yet. Ask the user
(via
AskUserQuestion if available, otherwise a plain question) whether to skip header handling entirely or
generate headers from scratch.
-
User chooses skip: record that no template exists and headers won't be added; proceed to Step 4 in
report-only mode (see the note there) — do not fabricate a template or edit any file.
-
User chooses generate: draft a standard header for the identified license and each extension's native
comment syntax. For Apache-2.0, MIT, and BSD-style licenses this is the boilerplate given in the license
text's own "how to apply this license" section (Apache-2.0 has one explicitly; MIT/BSD conventionally use
the short notice paragraph from the license body itself). Use the copyright holder name and year found in
the license file, pom.xml/package.json/git config, or (if truly undiscoverable) ask the user for the
copyright holder name before drafting anything — do not guess a person's or company's name.
Before touching any file, show the user a concrete example: the full drafted header rendered in the comment
syntax of one representative in-scope extension (pick the most common one, e.g. the main source language),
applied at the top of one real file from the repo so they can see it in context. Then ask the user to:
- accept it as the template and proceed to Step 4 using it as-is, or
- reject with changes — take their proposed edits (wording, holder name, year, format, comment style,
etc.), redraft the example, and show it again for another round of accept/reject, repeating until they
accept or choose to stop, or
- skip generation altogether — same outcome as the skip choice above: no template, proceed to Step 4 in
report-only mode.
Never write the accepted header to any file until the user has explicitly accepted a shown example.
- Determine the year to use in generated/backfilled headers: if the project already stamps a fixed year
across all existing headers (e.g. a repo-wide inception year regardless of when each file was authored — check
in or similar), reuse that same fixed year for consistency, even for brand-new
files. Otherwise, use each file's first-commit year via (or the current year if the file is untracked/new).
Step 4 — Audit every in-scope file
If Step 3 ended with no template (the user chose to skip header generation, with no pre-existing header to learn
from either), there's nothing to audit against — skip straight to Step 6 and report that no license-header check
was performed, rather than guessing at what a compliant header would look like.
Otherwise, for each file:
- No header comment at all before the first code/package/import statement: missing entirely.
- A header comment exists but is a different license, is missing the copyright line, has a stale/wrong holder
name, or otherwise diverges from the template from Step 3 in substance (not just incidental whitespace):
wrong/needs fixing. Minor cosmetic differences that don't change the legal meaning (e.g. trailing whitespace)
aren't worth flagging.
- Header matches the template: compliant, no action.
Record each file's status (missing / wrong / compliant) before making any edits, so Step 6 can report accurately.
Step 5 — Fix what's missing or wrong
Using the Edit tool (or Write only for brand-new files):
- Missing header: insert the template header as the very first content in the file, followed by a single
blank line, then the file's existing first line (package/import/module declaration, shebang stays above a
header if the file has one, etc.) unchanged.
- Wrong header: replace only the header comment block, leaving everything else in the file — including any
code-level Javadoc/docstring immediately below it — untouched.
- Never alter code logic, imports, formatting elsewhere in the file, or comments that aren't part of the license
header itself.
Step 6 — Report
If Step 3 had no template and the user chose to skip: state plainly that no header convention existed in the
repository, the user opted not to generate one, and no files were checked or modified.
Otherwise, state which license was identified and where the header template came from (learned from existing
files, with an example path, vs. drafted fresh and accepted by the user, noting how many revision rounds it
took). Then list, per file: compliant (no action), fixed (missing → added, or wrong → corrected), grouped so the
summary is scannable rather than one line per file when the repository is large. Call out any header-format
inconsistency spotted across existing files in Step 3, and any file skipped because it was ambiguous (e.g. a
generated file that looked hand-edited) rather than silently leaving it out.