GPTLint Rule Informal Spec
Version | 0.1.0 |
Last Updated | April 24, 2024 |
Author | Travis Fischer |
About
The GPTLint Rule Spec (abbreviated GRS in this doc) is an attempt to define a standard for how to describe higher-level lint rules that can be enforced across codebases using LLM-based tools compatible with GPTLint.
Example Rule
Here is an example markdown rule with yaml
frontmatter:
---
fixable: false
tags: [best practices]
languages: [javascript, typescript]
---
# Example Rule
Plain-text description of the rule's intent.
### Bad
optional example code blocks showing the rule being used incorrectly
### Good
optional example code blocks showing the rule being used correctly
This rule would canonically be stored in .gptlint/example-rule.md
and have the name example-rule
.
Rule Format
GRS rules are parsed into the following TypeScript format:
export type Rule = {
// core rule definition
name: string
title: string
description?: string
positiveExamples?: RuleExample[]
negativeExamples?: RuleExample[]
scope: LintRuleScope // defaults to 'file'
level: LintRuleLevel // defaults to 'error'
// optional metadata
fixable?: boolean
languages?: string[]
tags?: string[]
eslint?: string[]
include?: string[]
exclude?: string[]
resources?: string[]
model?: string
gritql?: string
gritqlNumLinesContext?: number
// optional custom functionality for rules scoped to the file-level
preProcessFile?: PreProcessFileFn
processFile?: ProcessFileFn
postProcessFile?: PostProcessFileFn
// optional custom functionality for rules scoped to the project-level
preProcessProject?: PreProcessProjectFn
processProject?: ProcessProjectFn
postProcessProject?: PostProcessProjectFn
}
export type LintRuleScope = 'file' | 'project' | 'repo'
export type LintRuleLevel = 'error' | 'warn' | 'off'
See the full types for more details.
Rule File Format
A GRS rule is defined in a GitHub Flavored Markdown (GFM) document. Each GRS rule must have its own markdown file, and GRS markdown files may only contain a single rule.
- GRS rule files must contain a single markdown
h1
header containing the rule’stitle
property. - Within this
h1
section, GRS rule files may optionally contain a metadata table for customizing the rule’s behavior. - The content from the
h1
section up until any optional example header sections will comprise the rule’sdescription
property which is intended to explain the rule’s intent in natural language. - The rule’s
name
will default to the rule’s filename (without the.md
extension).- This can be overridden via the frontmatter metadata’s
name
value. - If no valid
name
is found, it will fall back to a slugified version of the rule’stitle
value (mainh1
).
- This can be overridden via the frontmatter metadata’s
- GRS rules may optionally contain a single markdown
h3
header named “Bad” or “Incorrect” or “Fail”.- The content of this section should contain 1 or more code blocks to use as
negativeExamples
.
- The content of this section should contain 1 or more code blocks to use as
- GRS rules may optionally contain a single markdown
h3
header named “Good” or “Correct” or “Pass”.- The content of this section should contain 1 or more code blocks to use as
positiveExamples
.
- The content of this section should contain 1 or more code blocks to use as
- It is encouraged to specify a language for all code block examples, but it is not required.
- Rules with
file
scope may optionally contain a singlegrit
orgritql
code block. If provided, it must contain a valid gritql pattern which will be used to filter source files to only include matching portions before being processed by the linting engine.- Non-
file
-scoped rules must not contain agritql
pattern. - The
gritql
pattern will be assumed to be JS/TS for now.
- Non-
Rule Frontmatter Metadata
A GRS file may optionally contain YAML frontmatter for specifying metadata. Note that this is the same frontmatter format used by GitHub, so the metadata renders as an inline table on GitHub (example).
All metadata fields are optional.
Here is a breakdown of the supported metadata fields and their expected types.
Key | Type | Description |
---|---|---|
name | string | Short name of this rule. Defaults to the rule’s filename without the .md extension. |
level | warn | error | off | Default error level of this rule. Defaults to error . |
scope | file | project | repo | Granularity at which this rule is applied. Defaults to file . |
fixable | boolean | Whether or not this rule supports auto-fixing errors. |
tags | string[] | Array of tags / labels. |
eslint | string[] | Array of eslint rules which are related to this rule. |
languages | string[] | Array of programming languages this rule should be enabled for. |
include | string[] | Array of file glob patterns to include when enforcing this rule. If not specified, will operate on all input source files not excluded by exclude . |
exclude | string[] | Array of file glob patterns to ignore when enforcing this rule. |
resources | string[] | Array of URLs with more info on the rule’s intent. Very useful for linking to blog posts and internal docs. |
gritqlNumLinesContext | number | Number of lines before & after GritQL matches to include in the context sent to the LLM. Defaults to 0 . |
All metadata keys are case-sensitive, and all metadata values must match their expected types if present.
Example Rules
Documentation for all built-in rules is available here and their source is available here.
Parsing-wise, fixtures/valid-rules contains valid rules which test different parts of the spec, and fixtures/invalid-rules contains invalid rules which violate the spec and should fail parsing.