Complete reference for lintent's JSON output structure.
Top-Level Structure
interface LintentReport {
violations: EnrichedViolation[];
linters: {
detected: string[];
results: LinterResult[];
};
summary: Summary;
}
Violations
Each violation includes location, linter info, and semantic context.
interface EnrichedViolation {
file: string; // Absolute or relative path
line: number; // 1-indexed line number
column: number; // 1-indexed column number
tool: string; // Linter name (ruff, eslint, etc.)
code: string; // Rule code (E501, no-unused-vars, etc.)
message: string; // Linter's error message
semantic: SemanticRule | null;
}
interface SemanticRule {
illegal: string; // What the rule catches
legal: string; // What correct code looks like
why: string; // Reasoning behind the rule
}
Example Violation
{
"file": "src/main.py",
"line": 3,
"column": 8,
"tool": "ruff",
"code": "F401",
"message": "`os` imported but unused",
"semantic": {
"illegal": "Importing modules that are not used",
"legal": "Only import what you use, or mark with # noqa: F401",
"why": "Clean dependency graph, faster startup"
}
}
Violation Without Semantic Rule
If no semantic rule is defined for a violation, semantic is null:
{
"file": "src/main.py",
"line": 10,
"column": 1,
"tool": "ruff",
"code": "E999",
"message": "Some uncommon error",
"semantic": null
}
Linters
Information about detected and executed linters.
interface LinterResult {
name: string;
status: "success" | "error" | "not_found";
violations_count: number;
error?: string; // Present when status is "error" or "not_found"
}
Example
{
"linters": {
"detected": ["ruff", "pyright", "eslint"],
"results": [
{
"name": "ruff",
"status": "success",
"violations_count": 5
},
{
"name": "pyright",
"status": "not_found",
"violations_count": 0,
"error": "'pyright' is not installed. Install it with: pip install pyright"
},
{
"name": "eslint",
"status": "error",
"violations_count": 0,
"error": "ESLint configuration error"
}
]
}
}
Linter Statuses
| Status | Description |
|---|---|
success |
Linter ran and produced output (may have 0 violations) |
not_found |
Linter binary not found / not installed |
error |
Linter ran but encountered an error |
Summary
Aggregate statistics about the run.
interface Summary {
total: number; // Total violations
with_semantic: number; // Violations with semantic rules
without_semantic: number; // Violations without semantic rules
by_tool: Record<string, number>; // Count per linter
files_affected: number; // Unique files with violations
}
Example
{
"summary": {
"total": 15,
"with_semantic": 12,
"without_semantic": 3,
"by_tool": {
"ruff": 10,
"eslint": 5
},
"files_affected": 4
}
}
Error Responses
When lintent encounters an error, it returns:
interface LintentError {
error: true;
code: string;
message: string;
}
Example
{
"error": true,
"code": "CONFIG_NOT_FOUND",
"message": "Config file not found: ./lintent.yaml"
}
Error Codes
| Code | Description |
|---|---|
CONFIG_NOT_FOUND |
lintent.yaml not found |
CONFIG_INVALID |
lintent.yaml has syntax/structure errors |
NO_LINTERS |
No linters detected |
LINTER_NOT_FOUND |
Specified linter (via --tool) not found |
RUNTIME_ERROR |
Unexpected error |
Complete Example
{
"violations": [
{
"file": "/project/src/main.py",
"line": 1,
"column": 8,
"tool": "ruff",
"code": "F401",
"message": "`os` imported but unused",
"semantic": {
"illegal": "Importing modules that are not used",
"legal": "Only import what you use",
"why": "Clean dependency graph"
}
},
{
"file": "/project/src/main.py",
"line": 10,
"column": 89,
"tool": "ruff",
"code": "E501",
"message": "Line too long (120 > 88)",
"semantic": {
"illegal": "Lines over 88 characters",
"legal": "Break into multiple lines",
"why": "Readability"
}
}
],
"linters": {
"detected": ["ruff", "pyright"],
"results": [
{
"name": "ruff",
"status": "success",
"violations_count": 2
},
{
"name": "pyright",
"status": "not_found",
"violations_count": 0,
"error": "'pyright' is not installed..."
}
]
},
"summary": {
"total": 2,
"with_semantic": 2,
"without_semantic": 0,
"by_tool": {
"ruff": 2
},
"files_affected": 1
}
}