Analyze repository structure and generate standardized AGENTS.md files that serve as contributor guides for AI agents. Supports both single-repo and monorepo structures...
This skill enables the agent to generate AGENTS.md files that serve as contributor guides for AI agents working on a codebase.
AGENTS.md documentAGENTS.md, preserving user-defined custom sections. Unmarked files require a concrete change preview and one-time adoption confirmation; files without matching standard headings require an explicit full-regeneration requestFor single repositories or individual packages in a monorepo:
For the root of a monorepo structure:
AGENTS.md from scratch (default when no AGENTS.md exists)AGENTS.md while preserving custom sections. A valid management marker establishes enrollment in this workflow; matching headings identify replacement candidates, not authorship. Unmarked files need one-time adoption confirmation after a concrete preview; zero matching headings require an explicit full-regeneration request. See ./references/update_strategy.md for the marker contract and adoption workflow.The agent automatically selects the appropriate mode based on whether an AGENTS.md file already exists at the target location.
Supports three modes: All (root + all packages, default), Root Only, and Single Package. See ./references/monorepo_strategy.md for detailed strategy and mode selection criteria.
Run these steps in order. Each step has a fixed output that the next step depends on; skipping ahead produces wrong character budgets, unmatched update sections, or missed monorepo packages. The bundled scripts under ./scripts/ make the deterministic steps reproducible — invoke them rather than re-deriving the logic each run.
Check whether AGENTS.md exists at the target location. Present → Update candidate (subject to the management check below). Absent → Generate.
Run monorepo detection at the repo root:
python ./scripts/detect_monorepo.py <repo_root>
Output: {is_monorepo, markers}. A true result is provisional: discover the actual packages per ./references/monorepo_detection.md. If fewer than 2 packages are found, treat the repo as a single document despite the marker. Otherwise choose All / Root Only / Single Package per ./references/monorepo_strategy.md. If is_monorepo is false, treat the repo as a single document.
Before LOC measurement or deep analysis, run python ./scripts/parse_sections.py <path/to/AGENTS.md> --doc-type <single_repo|monorepo_root> for each existing target. management_status is managed, unmarked, or invalid; generated_doc_type records the valid marker's original document type or is null. Invalid markers stop automatic updating. Resolve the original type in the next item before applying the heading-count gate: unmarked files with matching standard headings may proceed to preparation of an adoption preview, but not writing; zero matched headings under the original type require an explicit full-regeneration request. A matching heading alone never authorizes a write.
Compare a valid generated_doc_type with the current target type. When they differ, rerun the parser with the original type to identify the original managed and custom sections before preparing full regeneration. For an unmarked file, infer its original type from distinctive standard headings (## 3. Working Agreements versus ## 3. Core Behaviors & Patterns / ## 5. Working Agreements); ask which original type to use if these conflict or are insufficient. Preserve original custom sections and obtain confirmation of the concrete type-transition preview before overwriting.
For package documents, check whether the repository-root AGENTS.md exists. If it does, reference its actual relative path. If it does not, include the common working agreements directly in the package document plus any discovered package-local verification command. Do not create a root file for a Single Package request. In All mode, recheck after the root has been handled.
For each target document (single repo, or root + each package), run:
python ./scripts/loc_to_limit.py <target_directory>
Output: {loc, scale, character_limit}. If the script reports tokei is missing, surface its install message and stop — do not estimate LOC by hand. Use the proportions in ./references/loc_measurement.md as initial section allocations, then redistribute capacity according to verified content. Only the combined preamble and managed sections have a hard character limit; the section proportions are not independent ceilings.
Before pattern/convention analysis, read the package manifests at the document's scope (root or per package) per ./references/read_only_commands.md > Dependency Discovery. Skip lock files. Use this stack context to focus Step 4 on relevant frameworks rather than searching blindly.
Read ./references/content_quality.md before analysis. Keep a compact internal record of decision-relevant facts, their current source evidence, and their intended destination. In Generate mode, discover these facts from source. In Update mode, also extract important facts from the old analysis-derived managed sections as inspection leads, reconfirm them against current source, and discover what the old document missed. The old document is not evidence of current behavior, and the working record is not a new output section.
For selected important behaviors, inspect direct implementing helpers until applicable choices, guard/bypass paths, recovery outcomes, state lifetime, ownership/cleanup conditions, and actual recipients are established. Save that compact relationship record in a temporary scratch file outside the target repository before drafting. A feature or helper name by itself does not close source tracing. Recent history affects active-route classification, not whether a currently verified safety contract is retained.
Before history-driven prioritization, build the coverage table from documented capabilities and authoritative registrations/public surfaces. In Update mode, also account for every old managed Stable boundary, Active route, and core flow. Confirm each row's current owner/consumer and selection or evidence-based exclusion. Trace selected rows from open to closed using actual implementing files and symbols, including each behavior-changing stage of a pipeline. A history window with no changes cannot exclude a live hook, migration, or safety condition.
For Update mode, use git history as an ownership-discovery signal before deep source tracing:
Prefer changes since the last skill-generated AGENTS.md update for the target document. If no reliable update anchor exists, default to roughly the last 3 months and adjust by repository activity.
Run the bundled high-churn signal helper before manually expanding git history:
python ./scripts/git_ownership_signals.py <target_directory>
If a reliable update anchor exists, pass it with --anchor <commit-ish>. The script emits compact Markdown-KV to minimize context use.
Start with commit metadata and changed paths only. Do not read broad diffs by default.
Look for changed-path clusters, repeated co-change patterns, renames/moves, deleted paths, and high-churn boundary files.
Use history to decide where to inspect next, not what to document. Add an Ownership Map boundary only when current code or documented contracts confirm it.
Do not persist timeline summaries such as "earlier focus" or "current focus" in AGENTS.md. Report them only in the user-facing summary unless the transition is currently represented in code as a live migration or compatibility boundary.
See ./references/read_only_commands.md#git-history-signals-update-mode for token-safe git commands and expansion rules.
Run the multi-phase analysis defined in ./references/agents_md_template.md:
If Serena MCP is available, prefer its read-only symbol tools (find_symbol, find_referencing_symbols, get_symbols_overview, etc.) over rg / grep / find — symbolic queries are more accurate for caller tracing and cross-layer flows. See ./references/read_only_commands.md#symbol-level-analysis-optional-requires-serena-mcp.
Run this analysis in the current context only. Do not delegate to subagents — Phase 3 cross-pattern validation and section-level budget tracking require a unified view (see Scope Boundaries > Single-Context Execution).
Document only patterns/conventions actually observed. Preserve necessary entry points, behavior-changing alternatives, exception/fallback conditions, lifecycle obligations, and compatibility effects. If a section needs more than its initial allocation, redistribute unused capacity within the total limit rather than deleting these facts. Apply the compression order in the content-quality reference.
If optional ## 2. Ownership Map has no evidence-backed content, omit the section and keep later section numbers unchanged. Section numbers are update-mode identifiers; never renumber Core Behaviors & Patterns, Conventions, or Working Agreements to close the gap. When evidence exists, split Ownership Map content into Stable Ownership Boundaries for the durable safety boundaries the previous single-list Ownership Map would have documented, and Active Change Routes for recent history-informed routes confirmed against current code. Treat Active Change Routes as additive update-mode context, not as a replacement or filter for stable boundaries. Stable bullets are full change-routing rules; Active bullets are parent-linked or cross-boundary delta routes. Do not restate the parent Stable boundary's broad owner, contract, or verification in Active. If no meaningful delta remains after removing inherited Stable details, omit the Active route. Do not impose a bullet-count limit beyond the section character budget.
Draft the closed, decision-relevant contracts into Ownership Map/Core Behaviors first, without duplicating them across sections. Use remaining capacity for repository-specific conventions; do not fill generic naming, role, logging, or resource lists at the expense of a covered contract. Keep every coverage row accounted for when removing an Active label or consolidating sections.
Generate: Emit the document using the structure in ./references/agents_md_template.md (4-5 sections for single repo / package, 2-3 for monorepo root, depending on whether Ownership Map has evidence-backed content). Add exactly one standalone <!-- agents-md-generator: v1; doc-type: single_repo --> line to the preamble, before the first ## heading; use monorepo_root for a monorepo root. Use ./references/working_agreements.md for the Working Agreements section and its root-absence fallback.
Update: Run the section parser on the existing file:
python ./scripts/parse_sections.py <path/to/AGENTS.md> --doc-type single_repo
(Use --doc-type monorepo_root for a monorepo root, or the original type from Step 1 when preparing a transition.) The output marks each ## heading as is_standard (a replacement candidate subject to the management gate) or not (preserved), flags evidence-gated headings in optional_standard, and marks matched optional sections with is_optional_standard. Legacy ## 2. Folder Structure sections report canonical_title: "## 2. Ownership Map" so approved updates can migrate them. Replace only the standard sections' bodies; keep custom sections, the file title, and the preamble unchanged except for approved marker insertion or type-transition replacement. Insert missing required headings at their numbered position, and missing optional headings only when fresh analysis produced evidence-backed content. Full reassembly rules: ./references/update_strategy.md.
Management gate: use the Step 1 management result, not is_standard alone. For an unmarked file, finish a concrete preview of replacements, insertions, deletions, and marker insertion, then obtain one-time adoption confirmation. On approval, write the adoption and marker together; on refusal, leave the original file unchanged. A general update request is not adoption confirmation. Preserve all non-standard content and the existing preamble except the expressly approved marker insertion. Invalid markers must be reported rather than silently repaired. See the update strategy for details.
If the existing document type no longer matches the repo (e.g., a single repo became a monorepo), force full regeneration instead of update: carry every custom section over verbatim into the regenerated document (original order preserved) and get the user's confirmation before overwriting.
Before writing, confirm:
character_limit. Section allocations may be exceeded after rebalancing; preserve section responsibilities and do not add filler. Custom sections are excluded from the budget and must never be trimmed to satisfy it.AGENTS.md and report only material corrections or limitations to the user.open. Empty history, generic "lower value", or space pressure is not an exclusion reason for a current safety contract. Generic pipeline stage names do not establish the stages' actual choices or recovery conditions.Keep edits minimal, Minimal changes, preserve public APIs, existing plugin behavior, or avoid unnecessary abstraction; custom sections may keep any user-owned wording.Ownership Map or legacy Folder Structure section will be omitted because no current evidence supports it, report that whole-section removal and get confirmation before overwriting.Working Agreements section does not contain monorepo-only wording such as package-level AGENTS.md guidance.Then write with the Edit/Write tool. For Monorepo with mode = All, repeat Steps 2–6 per target package after handling the root, re-running the Step 1 Generate/Update decision, management check, and root-existence check for each package — a package without AGENTS.md is Generate even when the root was Update.
This skill uses the following read-only tools for repository analysis. See ./references/read_only_commands.md for detailed usage patterns.
find_symbol, find_referencing_symbols, find_referencing_code_snippets, get_symbols_overview, search_for_pattern, list_dir, find_file, read_file. Prefer these over rg / grep / find for symbol lookups, caller tracing, and structural analysis. Use only the read-only tools listed; do NOT invoke write/edit symbol tools or execute_shell_command. See ./references/read_only_commands.md#symbol-level-analysis-optional-requires-serena-mcp.tokei: LOC measurement (required)rg (ripgrep): Content search (fallback when Serena MCP is unavailable)grep / Select-String: Content search (fallback per OS, when neither Serena nor rg is available)sed -n / Get-Content \| Select-Object: Paginated file reading per OStree: Directory structure visualizationfind: File and directory discovery (Linux / macOS, fallback when Serena find_file is unavailable)ls, pwd: Basic directory navigationgit log, git show --stat, git show --name-only: Update-mode ownership discovery signals; use the bundled script first, then metadata and changed paths, never broad diffs by defaultDeterministic steps are bundled as scripts under ./scripts/ so they run identically across invocations and platforms. Prefer these over re-deriving the logic in natural language.
scripts/loc_to_limit.py: Runs tokei with the prescribed exclusions, parses the Total row, and returns {loc, scale, character_limit}. Surfaces the install message and exits non-zero if tokei is missing.scripts/detect_monorepo.py: Checks marker files (pnpm-workspace.yaml, lerna.json, nx.json, turbo.json, rush.json, .moon/workspace.yml, go.work, Cargo.toml [workspace] members, package.json workspaces, Gradle settings.gradle*, Maven pom.xml <modules>, Bazel, Buck2, Pants, Hatch/uv/rye). Gradle matching reads complete literal include declarations, including multiline forms, ignores comments/string examples, and deduplicates project paths; it does not evaluate dynamic Gradle expressions. Returns {is_monorepo, markers}; a true result is provisional until package discovery finds 2+ packages (Step 1).scripts/parse_sections.py: For Update mode. Returns a section map with standard-heading candidates, custom sections, and missing headings, plus management_status and generated_doc_type. Existing JSON fields and --doc-type matching remain unchanged; consumers must use the management gate before writing. Headings and markers inside fenced code blocks are ignored. The parser reports line ranges rather than rewriting content; splice preserved ranges from the original bytes, retaining line endings and trailing whitespace.scripts/git_ownership_signals.py: For Update mode. Runs token-safe git history aggregation over the target directory and prints compact Markdown-KV high-churn path signals. The output is a discovery signal only and must be confirmed against current code before documenting Ownership Map boundaries.pnpm-lock.yaml, package-lock.json, yarn.lock, etc.) are outside analysis scopeAgent / Task tool, Explore, general-purpose, or any delegated agent) at any step. AGENTS.md generation requires a unified view of the repository: accumulated stack context (Step 3), per-section character budgets (Step 2), Phase 3 validation across 3+ locations, and Update-mode byte-for-byte preservation of custom sections all depend on a single context. Splitting work across subagents loses this state and produces inconsistent or budget-violating output. A parent agent invoking this skill is fine — the skill's internal execution must stay in one context.