@lousy-agents/lint
v5.21.6
Published
Programmatic lint API for validating AI coding assistant configurations — skills, agents, hooks, and instructions
Maintainers
Readme
@lousy-agents/lint
Programmatic lint API for AI agent skill, agent, hook, and instruction files. Use this package to integrate lousy-agents lint checks into your own tools, web apps, or CI pipelines without the CLI.
For CLI-based linting, see the lint command docs.
Installation
npm install @lousy-agents/lintQuick Start
import { runLint } from '@lousy-agents/lint';
const result = await runLint({ directory: '/path/to/project' });
if (result.hasErrors) {
console.error('Lint failed');
for (const output of result.outputs) {
for (const diagnostic of output.diagnostics) {
console.error(`${diagnostic.filePath}:${diagnostic.line} [${diagnostic.severity}] ${diagnostic.message}`);
}
}
}API
runLint(options): Promise<LintResult>
Runs all lint checks on a project directory and returns structured results.
import { runLint, LintValidationError } from '@lousy-agents/lint';
try {
const result = await runLint({
directory: '/path/to/project',
targets: {
skills: true,
agents: true,
hooks: false, // skip hook linting
instructions: false, // skip instruction linting
},
});
console.log('Has errors:', result.hasErrors);
console.log('Outputs:', result.outputs.length);
} catch (error) {
if (error instanceof LintValidationError) {
console.error('Invalid input:', error.message);
} else {
throw error;
}
}Options:
| Property | Type | Required | Description |
| --- | --- | --- | --- |
| directory | string | ✅ | Absolute or relative path to the project directory to lint |
| targets.skills | boolean | — | Lint skill frontmatter: .github/skills/*/SKILL.md, .claude/skills/*/SKILL.md, .agents/skills/*/SKILL.md, .pi/skills/*/SKILL.md, .pi/prompts/*/SKILL.md (skills listed in root skills-lock.json are omitted) |
| targets.agents | boolean | — | Lint agent frontmatter in .github/agents/**/*.md |
| targets.subagents | boolean | — | Flag-only (not GA) — lint Claude Code subagent frontmatter in .claude/agents/**/*.md. Never runs unless explicitly true, even when targets is entirely omitted |
| targets.hooks | boolean | — | Lint hook configs: .github/hooks/agent-shell/hooks.json (Copilot), .claude/settings.json and .claude/settings.local.json (Claude); only when content has preToolUse / PreToolUse; symlinks skipped |
| targets.instructions | boolean | — | Lint instruction quality: .github/copilot-instructions.md, .github/instructions/*.md, .github/agents/*.md (dual-use with agents), root AGENTS.md, root CLAUDE.md |
| targets.mcpServers | boolean | — | Flag-only (not GA) — validate MCP server config files: .mcp.json, .vscode/mcp.json. Never runs unless explicitly true, even when targets is entirely omitted |
| logger | LintLogger | — | Custom logger for gateway diagnostics (must have a .warn method); defaults to consola |
When targets is omitted or all flags are false, the default-enabled targets run: skills, agents, hooks, instructions. subagents and mcpServers are flag-only — part of a phased rollout (see Construct coverage) — and only run when explicitly set to true, even if no other flags are set.
Discovery paths come from the canonical agentic location catalog in @lousy-agents/core, shared with doctor. Doctor may inventory additional constructs lint still does not validate (plugins, multi-harness instruction trees, etc.). Intentional differences: skills-lock.json filtering (lint only), hook PreToolUse / preToolUse content heuristic (lint only, applies only to the two .claude/settings*.json / .github/hooks/agent-shell/hooks.json exact paths — kept, not relaxed, for this rollout), and symlink policy (lint skips; doctor follows in-repo).
Throws LintValidationError when directory is empty, contains control characters, path traversal sequences, does not exist, or is not a directory.
createFormatter(format): LintFormatter
Creates an output formatter for rendering LintOutput[] to a string.
import { runLint, createFormatter } from '@lousy-agents/lint';
const result = await runLint({ directory: '/path/to/project' });
const formatter = createFormatter('human');
console.log(formatter.format(result.outputs));| Format | Description |
| --- | --- |
| 'human' | Human-readable text, one diagnostic per line |
| 'json' | JSON array of all diagnostics |
| 'rdjsonl' | Reviewdog Diagnostic Format JSONL (one JSON object per line) — for CI integrations |
DEFAULT_LINT_RULES
The default rule configuration used when no lousy-agents.config.ts is present. Use this to inspect or extend the default rule set.
import { DEFAULT_LINT_RULES } from '@lousy-agents/lint';
console.log(DEFAULT_LINT_RULES.skills);
// { 'skill/missing-name': 'error', 'skill/missing-description': 'error', ... }LintValidationError
Thrown when user-supplied input fails validation. Catch this to distinguish user-input errors from system errors.
import { runLint, LintValidationError } from '@lousy-agents/lint';
try {
await runLint({ directory: '' });
} catch (error) {
if (error instanceof LintValidationError) {
// directory was empty, missing, or not a directory
console.error(error.message);
}
}Types
import type {
LintResult,
LintOutput,
LintDiagnostic,
LintSeverity,
LintTarget,
LintOptions,
LintLogger,
LintRulesConfig,
LintFormatType,
LintFormatter,
InstructionQualityResult,
} from '@lousy-agents/lint';Key types:
| Type | Description |
| --- | --- |
| LintResult | Top-level result: outputs array + hasErrors boolean |
| LintOutput | Per-target result: diagnostics, filesAnalyzed, summary, optional qualityResult |
| LintDiagnostic | Single diagnostic: filePath, line, severity, message, ruleId, target |
| LintSeverity | "error" \| "warning" \| "info" |
| LintTarget | "skill" \| "agent" \| "subagent" \| "instruction" \| "hook" \| "mcp-server" |
| InstructionQualityResult | Instruction quality scores and suggestions (populated when instructions target runs) |
Custom Logger
Pass any object with a .warn method to suppress or redirect gateway diagnostics:
import { runLint } from '@lousy-agents/lint';
import { createLogger } from 'your-logger';
const logger = createLogger('lint');
await runLint({
directory: '/path/to/project',
logger: { warn: (msg, ...args) => logger.warn(msg, ...args) },
});CI Integration (rdjsonl)
Output in Reviewdog Diagnostic Format for annotation-based CI feedback:
node -e "
const { runLint, createFormatter } = require('@lousy-agents/lint');
runLint({ directory: '.' }).then(r => {
process.stdout.write(createFormatter('rdjsonl').format(r.outputs));
process.exit(r.hasErrors ? 1 : 0);
});
"Related docs
lintCLI command — CLI-based linting withnpx @lousy-agents/cli lint- GitHub Action — run linting in GitHub Actions without installing Node.js
