Papyrus Lint Export for AI document
The JSON document produced by the desktop app's Export for AI feature or the CLI's --format ai option. It contains the GUI's currently filtered lint findings, or the CLI's unfiltered findings, and metadata for each recognized rule represented in those findings.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://papyrus-lint.idrinth.de/schema/papyrus-lint-ai-export.v4.schema.json",
"title": "Papyrus Lint Export for AI document",
"description": "The JSON document produced by the desktop app's Export for AI feature or the CLI's --format ai option. It contains the GUI's currently filtered lint findings, or the CLI's unfiltered findings, and metadata for each recognized rule represented in those findings.",
"type": "object",
"additionalProperties": false,
"required": [
"$schema",
"header",
"configuration",
"findings",
"rule_details"
],
"properties": {
"$schema": {
"description": "The canonical JSON Schema for validating and interpreting this AI export document.",
"const": "https://papyrus-lint.idrinth.de/schema/papyrus-lint-ai-export.v4.schema.json"
},
"header": {
"$ref": "#/$defs/header"
},
"configuration": {
"description": "The fully resolved lint configuration used to produce the findings, including defaults for settings omitted from the project's YAML file.",
"$ref": "#/$defs/configuration"
},
"filters": {
"description": "The desktop GUI result filters active when the export was generated. This is optional because these filters do not exist in non-GUI integrations.",
"$ref": "#/$defs/filters"
},
"findings": {
"$ref": "#/$defs/findingsReport"
},
"rule_details": {
"description": "Tag metadata for each recognized rule represented in findings. Triggered rule ids for which Papyrus Lint has no metadata are omitted.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/$defs/ruleDetail"
}
}
},
"$defs": {
"severity": {
"description": "A diagnostic severity bucket.",
"type": "string",
"enum": [
"error",
"warning",
"info"
]
},
"importance": {
"description": "A rule's relative importance.",
"type": "string",
"enum": [
"low",
"medium",
"high"
]
},
"ruleId": {
"description": "A stable, hyphenated lint rule identifier.",
"type": "string",
"minLength": 1,
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
},
"filters": {
"type": "object",
"additionalProperties": false,
"required": [
"filename_pattern",
"severities",
"importances",
"rules",
"auto_fixable_only"
],
"properties": {
"filename_pattern": {
"description": "The filename search pattern, including any glob-like *, %, or ? characters; an empty string matches every file.",
"type": "string"
},
"severities": {
"description": "The diagnostic severity buckets selected in the GUI. The GUI never lets every bucket in a filter group (severities, importances, or rules) be deselected at once, so this is never empty; a bucket left out here was deliberately excluded, not \"no restriction\".",
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"$ref": "#/$defs/severity"
}
},
"importances": {
"description": "The rule importance levels selected in the GUI. Never empty; see severities above for why.",
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"$ref": "#/$defs/importance"
}
},
"rules": {
"description": "The rule ids selected across the GUI's kind-grouped rule filters. Never empty; see severities above for why. A finding whose rule carries no known tag metadata (e.g. a compiler-reported diagnostic) is exempt from this filter and importances, so it can still appear in findings even though its own rule id isn't listed here.",
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"$ref": "#/$defs/ruleId"
}
},
"auto_fixable_only": {
"description": "Whether the GUI was restricted to findings from auto-fixable rules.",
"type": "boolean"
}
}
},
"configuration": {
"type": "object",
"additionalProperties": false,
"required": [
"semicolon",
"indentation",
"indentation_width",
"identifier_casing",
"cyclomatic_complexity_warning",
"cyclomatic_complexity_error",
"type_casing",
"named_arguments",
"min_wait_interval",
"magic_numbers",
"fail_on_warning",
"fail_on_info",
"bool_like_int",
"assume_auto_properties_filled",
"enabled_rules"
],
"properties": {
"semicolon": {
"type": "boolean"
},
"indentation": {
"type": "string",
"enum": [
"tab",
"space"
]
},
"indentation_width": {
"type": "integer",
"minimum": 0,
"description": "A value of 0 is only valid for tabs. For spaces the value will be equal or greater 1"
},
"identifier_casing": {
"type": "string",
"enum": [
"camelCase",
"PascalCase",
"snake_case",
"CONSTANT_CASE"
]
},
"cyclomatic_complexity_warning": {
"description": "The cyclomatic complexity a function/event can reach before the cyclomatic-complexity finding's severity is [warning].",
"type": "integer",
"minimum": 0
},
"cyclomatic_complexity_error": {
"description": "The cyclomatic complexity a function/event can reach before the cyclomatic-complexity finding's severity is [error]. This value as configured can be lower than cyclomatic_complexity_warning, but Papyrus Lint then treats it as equal to cyclomatic_complexity_warning when actually deciding a finding's severity, since a lower error threshold would otherwise contradict the warning one it's supposed to escalate.",
"type": "integer",
"minimum": 0
},
"type_casing": {
"type": "string",
"enum": [
"PascalCase",
"camelCase",
"lowercase",
"UPPERCASE"
]
},
"named_arguments": {
"type": "string",
"enum": [
"always",
"instead_of_defaults",
"never"
]
},
"min_wait_interval": {
"type": "number",
"minimum": 0
},
"magic_numbers": {
"type": "string",
"enum": [
"loose",
"strict"
]
},
"fail_on_warning": {
"type": "boolean"
},
"fail_on_info": {
"type": "boolean"
},
"bool_like_int": {
"type": "boolean"
},
"assume_auto_properties_filled": {
"type": "boolean"
},
"enabled_rules": {
"description": "The hyphenated ids of every currently enabled lint rule, alphabetically sorted. A rule not listed here is disabled. Disabled rules will not be listed in the findings.",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/$defs/ruleId"
}
}
},
"if": {
"properties": {
"indentation": {
"const": "space"
}
}
},
"then": {
"properties": {
"indentation_width": {
"minimum": 1
}
}
}
},
"header": {
"type": "object",
"additionalProperties": false,
"required": [
"tool",
"version",
"website",
"target_game",
"generated_at"
],
"properties": {
"tool": {
"description": "The application that produced this document.",
"const": "Papyrus Lint"
},
"version": {
"description": "The running desktop app's version, or `unknown` when it could not be read.",
"type": "string",
"minLength": 1
},
"website": {
"description": "The Papyrus Lint website, where additional rule and configuration documentation is available.",
"type": "string",
"format": "uri"
},
"target_game": {
"description": "The Papyrus dialect/engine these findings and rule details were produced for. Papyrus Lint has no per-project game/edition setting, so this is fixed.",
"enum": [
"Skyrim SE/AE"
]
},
"generated_at": {
"description": "The UTC date and time at which this export was generated, in RFC 3339 format.",
"type": "string",
"format": "date-time",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
}
}
},
"findingsReport": {
"description": "The filtered findings. Every exported file has at least one diagnostic or parser error (see `fileReport`).",
"type": "object",
"additionalProperties": false,
"required": [
"files",
"total_diagnostics",
"severity_counts",
"rule_counts"
],
"properties": {
"files": {
"type": "array",
"items": {
"$ref": "#/$defs/fileReport"
}
},
"total_diagnostics": {
"description": "The total number of exported diagnostics across all files.",
"type": "integer",
"minimum": 0
},
"severity_counts": {
"description": "The sum of all file severity counts.",
"$ref": "#/$defs/severityCounts"
},
"rule_counts": {
"$ref": "#/$defs/ruleCounts"
}
}
},
"fileReport": {
"type": "object",
"additionalProperties": false,
"required": [
"path",
"severity_counts",
"rule_counts",
"diagnostics",
"parser_errors",
"source"
],
"properties": {
"path": {
"description": "The script path relative to the currently loaded project when possible.",
"type": "string",
"minLength": 1
},
"diagnostics": {
"description": "The diagnostics for this script that passed every active results filter. May be empty when the file is included only because the parser failed.",
"type": "array",
"items": {
"$ref": "#/$defs/diagnostic"
}
},
"parser_errors": {
"description": "Errors the lexer or parser raised while handling this script. Empty when the script lexed and parsed cleanly. Currently at most one entry, because parsing stops at the first error.",
"type": "array",
"items": {
"$ref": "#/$defs/parserError"
}
},
"rule_counts": {
"$ref": "#/$defs/ruleCounts"
},
"severity_counts": {
"$ref": "#/$defs/severityCounts"
},
"source": {
"description": "How this script's source is represented: null when none was attached at all; otherwise an object whose \"type\" names which of the other three forms it takes.",
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/sourceContent"
},
{
"$ref": "#/$defs/sourceHash"
},
{
"$ref": "#/$defs/sourceError"
}
]
}
}
},
"ruleCounts": {
"description": "Counts of exported diagnostics grouped by rule id. Rules with no diagnostics are omitted.",
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9]+(?:-[a-z0-9]+)*$": {
"type": "integer",
"minimum": 1
}
}
},
"severityCounts": {
"description": "Counts of exported diagnostics grouped by severity.",
"type": "object",
"additionalProperties": false,
"required": [
"errors",
"warnings",
"info"
],
"properties": {
"errors": {
"type": "integer",
"minimum": 0
},
"warnings": {
"type": "integer",
"minimum": 0
},
"info": {
"type": "integer",
"minimum": 0
}
}
},
"sourceContent": {
"description": "This script's current on-disk contents, letting the assistant see the code each diagnostic refers to without the project open.",
"type": "object",
"additionalProperties": false,
"required": [
"type",
"content"
],
"properties": {
"type": {
"const": "content"
},
"content": {
"type": "string"
}
}
},
"sourceHash": {
"description": "This script's content hash instead of its full text, attached via the desktop app's \"Redact source\" export option or the CLI's --hash-source flag so a report can be shared without exposing proprietary script text; a viewer can still tell files apart, or notice a file changed between exports, from the hash alone.",
"type": "object",
"additionalProperties": false,
"required": [
"type",
"algorithm",
"hash"
],
"properties": {
"type": {
"const": "hash"
},
"algorithm": {
"enum": [
"md5"
]
},
"hash": {
"description": "The lowercase hex digest of this script's current on-disk contents.",
"type": "string",
"pattern": "^[0-9a-f]+$"
}
}
},
"sourceError": {
"description": "Why this script's source couldn't be attached, e.g. it was moved or deleted since linting.",
"type": "object",
"additionalProperties": false,
"required": [
"type",
"message"
],
"properties": {
"type": {
"const": "error"
},
"message": {
"type": "string"
}
}
},
"parserError": {
"description": "One error raised while lexing or parsing this script.",
"type": "object",
"additionalProperties": false,
"required": [
"kind",
"line",
"column",
"message"
],
"properties": {
"kind": {
"description": "Whether this error came from the lexer or the recursive-descent parser.",
"type": "string",
"enum": [
"lex",
"parse"
]
},
"line": {
"description": "The 1-indexed source line where the error was detected.",
"type": "integer",
"minimum": 1
},
"column": {
"description": "The 1-indexed source column where the error was detected.",
"type": "integer",
"minimum": 1
},
"message": {
"description": "The human-readable parser or lexer error message.",
"type": "string",
"minLength": 1
}
}
},
"diagnostic": {
"type": "object",
"additionalProperties": false,
"required": [
"line",
"column",
"rule",
"level",
"message",
"doc_url"
],
"dependentRequired": {
"external": [
"source"
],
"source": [
"external"
]
},
"properties": {
"line": {
"description": "The 1-indexed source line where the diagnostic starts.",
"type": "integer",
"minimum": 1
},
"column": {
"description": "The 1-indexed source column where the diagnostic starts.",
"type": "integer",
"minimum": 1
},
"rule": {
"description": "The stable, hyphenated lint rule id.",
"$ref": "#/$defs/ruleId"
},
"level": {
"description": "The diagnostic severity. Untagged external diagnostics are classified as errors.",
"$ref": "#/$defs/severity"
},
"message": {
"description": "The human-readable diagnostic message.",
"type": "string",
"minLength": 1
},
"external": {
"description": "Present and `true` only for a diagnostic raised by a tool outside Papyrus Lint's own lint rules rather than one of Papyrus Lint's own rules; see `source` for which tool. Omitted for an ordinary lint finding.",
"const": true
},
"source": {
"description": "Which external tool raised this diagnostic. Present only alongside `external`. Currently always `compiler`, for a diagnostic parsed out of PapyrusCompiler.exe's own reported errors (rule `compiler-error`).",
"const": "compiler"
},
"repair": {
"description": "What this diagnostic's line would look like after applying its rule's automatic fix, present only when Papyrus Lint could compute one. Omitted for a rule with no automatic fix, for a finding that fix wouldn't actually change (e.g. type-casing's own \"no automatic fix\" case), or when the fix would shift the file's line count elsewhere (e.g. property-sorting relocating a property's declaration).",
"type": "string",
"minLength": 1
},
"doc_url": {
"description": "This rule's own documentation link on the project website, so the assistant can look up its full explanation, or null for a rule with no known tag metadata (e.g. a compiler-reported diagnostic).",
"type": [
"string",
"null"
],
"format": "uri"
}
}
},
"ruleDetail": {
"type": "object",
"additionalProperties": false,
"required": [
"rule",
"description",
"kinds",
"importance",
"auto_fixable",
"doc_url"
],
"properties": {
"rule": {
"description": "The stable, hyphenated identifier of the lint rule.",
"$ref": "#/$defs/ruleId"
},
"description": {
"description": "The rule's detailed description, copied from its row in the project README's Implemented Lints tables.",
"type": "string",
"minLength": 1
},
"kinds": {
"description": "The classes of issue this rule detects.",
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"enum": [
"style",
"performance",
"correctness",
"maintainability"
]
}
},
"importance": {
"description": "The rule's relative importance.",
"$ref": "#/$defs/importance"
},
"auto_fixable": {
"description": "Whether Papyrus Lint can automatically fix this rule's findings.",
"type": "boolean"
},
"doc_url": {
"description": "This rule's own documentation link on the project website (its row on the Implemented Lints table), so an assistant or a human reader can jump straight to it.",
"type": "string",
"format": "uri"
}
}
}
}
}