@reaatech/agents-markdown-linter
v1.0.0
Published
Linting rules engine for AGENTS.md and SKILL.md files
Readme
@reaatech/agents-markdown-linter
Status: Pre-1.0 — APIs may change in minor versions. Pin to a specific version in production.
Style, content, and best-practice linting rules for AGENTS.md and SKILL.md files. Ships with 18 built-in rules across three categories, plus an extensible rule registry and auto-fix engine for format-level issues.
Installation
npm install @reaatech/agents-markdown-linter
# or
pnpm add @reaatech/agents-markdown-linterFeature Overview
- 18 built-in rules — Style (6), Content (7), Best Practice (5) covering formatting, structure, and quality
- Extensible rule registry — Register custom lint rules with
registerRule - Auto-fix engine — Fix trailing whitespace, missing code block languages, inconsistent table formats, and missing headings
- Severity levels —
error,warning,info,suggestion - Per-rule isolation — A failing rule does not abort the lint run
- Finding output — Standard
Finding[]format consumable by reporters
Quick Start
import { parseMarkdown } from "@reaatech/agents-markdown-parser";
import { runLintRules, registerRule, runAutoFix } from "@reaatech/agents-markdown-linter";
const doc = await parseMarkdown(content, "./AGENTS.md");
const result = runLintRules(doc);
console.log(`Errors: ${result.errorCount}, Warnings: ${result.warningCount}`);
for (const finding of result.findings) {
console.log(`${finding.severity}: ${finding.rule} — ${finding.message}`);
}
// Auto-fix formatting issues
const fixed = runAutoFix(content, ["trailing-whitespace", "no-code-language", "table-format"]);API Reference
runLintRules(document)
Runs all registered rules against a document. Catches per-rule errors so one failing rule does not abort the run.
function runLintRules(
document: AgentsMdDocument | SkillMdDocument
): LintResultregisterRule(category, ruleId, rule, definition)
Register a custom lint rule. Rules are side-effect modules — importing @reaatech/agents-markdown-linter automatically registers all built-in rules.
function registerRule(
category: "style" | "content" | "bestPractice",
ruleId: string,
rule: LintRule,
definition: RuleDefinition
): voidgetRegisteredRules()
function getRegisteredRules(): RuleDefinition[]runAutoFix(content, ruleIds)
Apply auto-fixes for the specified rules. Returns the fixed content string.
function runAutoFix(content: string, ruleIds: string[]): stringgetAutoFixableRules()
Returns the list of rule IDs that support auto-fix.
function getAutoFixableRules(): string[]Built-in Rules
Style Rules
| Rule ID | Severity | Auto-fix | Description |
|---------|----------|----------|-------------|
| heading-order | warning | No | Heading levels must not be skipped (e.g., ## then ####) |
| no-code-language | warning | Yes | Code blocks should specify a language |
| trailing-whitespace | info | Yes | Lines must not have trailing whitespace |
| line-too-long | info | No | Lines must not exceed 120 characters |
| table-format | warning | Yes | Table rows must have consistent column counts |
| list-format | warning | No | List markers must be consistent within a list |
Content Rules
| Rule ID | Severity | Auto-fix | Description |
|---------|----------|----------|-------------|
| heading-missing | error | Yes | Required section headings must be present |
| empty-section | warning | No | Sections must contain content |
| placeholder-text | warning | No | No TODO/FIXME/TBD placeholders |
| duplicate-section | error | No | Section titles must be unique |
| broken-skill-ref | error | No | Referenced skill files must exist |
| duplicate-skill-id | error | No | Skill IDs must be unique |
| section-ordering | warning | No | Sections should follow recommended order |
| min-content-length | warning | No | Sections should have minimum content (20 chars) |
Best Practice Rules
| Rule ID | Severity | Auto-fix | Description |
|---------|----------|----------|-------------|
| missing-pii-mention | warning | No | Security section should mention PII handling |
| missing-observability | warning | No | Observability section should mention structured logging |
| incomplete-examples | warning | No | Usage examples should include both success and error cases |
| missing-mcp-schema | warning | No | MCP tools should have input schemas documented |
| missing-confidence | error | No | Agent config must include confidence_threshold |
Custom Rule Example
import { registerRule } from "@reaatech/agents-markdown-linter";
registerRule("style", "my-custom-rule",
(doc) => {
const findings = [];
if (!doc.frontmatter.description) {
findings.push({
ruleId: "my-custom-rule",
severity: "warning",
message: "Description is recommended in frontmatter",
});
}
return findings;
},
{
id: "my-custom-rule",
description: "Enforce description in frontmatter",
severity: "warning",
category: "style",
autoFixable: false,
}
);Related Packages
@reaatech/agents-markdown— Core types and domain interfaces@reaatech/agents-markdown-parser— Markdown AST parser@reaatech/agents-markdown-validator— Schema validation engine
