Help us shape the future of Go! Take the 2026 Go Developer Survey

lintpal

module
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2026 License: MIT

README

LintPal

Grayscale DiffPal family mascot sticker with a white outline

ci lintpal-dev review npm Product Hunt

Turn your freeform engineering rules into PR checks.

Use System One models like Jev through compatible Decisions APIs. LintPal checks Git changes against your team's Markdown rules and reports findings on changed lines. Gate CI by severity, run locally, or publish reviews directly to GitHub.

LintPal is part of the DiffPal family. It checks explicit repository rules; DiffPal provides broader AI pull-request review across GitHub, GitLab, and Azure DevOps.

Website · Quickstart · Documentation · Rule packs · Demo PR (v0.5.0)

For example, a Go error-handling rule can flag a violating changed line in a pull request; the configured severity gate can then fail the check.

Features

  • Provider choice: use TypeSafe/Jev, OpenRouter, OpenAI, or your own compatible Decisions service with the same repository rules and CI workflow.
  • Freeform rules: write one clear requirement per Markdown file, with optional severity and decision-threshold policy in frontmatter.
  • Rule packs: import a local directory or a versioned GitHub catalog, then review and commit the rules with your code.
  • Gating: choose which finding severities block CI while retaining the complete findings artifact after each successful evaluation.
  • Platform feedback: publish a GitHub review summary and inline comments, or consume the same findings as JSON or Markdown in CI.

Supported Providers

Choose the provider that fits your account and deployment. Your Markdown rules, findings, and severity gate work the same way across providers.

Provider Choose it for CLI option Credential
TypeSafe / Jev Direct access to Jev; the default setup --provider jev TYPESAFE_API_KEY
OpenRouter Decisions through your OpenRouter account --provider openrouter OPENROUTER_API_KEY
OpenAI Native OpenAI Decisions API support --provider openai --model gpt-6-luna OPENAI_API_KEY
Custom Your own compatible service, including a local endpoint --provider custom --base-url <url> --api-path <path> LINTPAL_TOKEN or your chosen token variable

All four provider options are included. The OpenAI preset uses the official POST /v1/decisions schema. As of October 6, 2026, OpenAI describes Decisions API as a limited preview, so access may depend on the API account. See provider setup and commands for all four options. The quickstart below uses TypeSafe/Jev.

How It Works

Stage What LintPal does
Rules Loads the repository's .lintpal/rules/**/*.md requirements
Diff Reads changed lines from the unique merge base through head, or from HEAD to the working tree with --uncommitted
Evaluation Evaluates each applicable rule through the selected AI provider
Findings Writes findings tied to changed lines as JSON or Markdown
Feedback (optional) feedback github publishes GitHub comments; --gate applies the stored severity gate after publication

Your repository defines the rules. Review and update them alongside the code as your team's requirements change.

Minimal GitHub Quickstart

Use Git and Node.js 16 or newer. npm packages provide native binaries for Linux and macOS (x64 and arm64), and Windows (x64). Install the CLI globally and add a versioned rule pack in your repository:

npm install -g lintpal
lintpal rule import github:diffpal/lintpal-rules//general@v1.1.0 --prefix general
lintpal rule validate

Review and commit .lintpal/rules/ so the workflow can load the rules. The selected remote provider receives bounded source context and rule text. Check whether that transfer is permitted for your repository before adding TYPESAFE_API_KEY as an Actions secret; see privacy. Then create .github/workflows/lintpal.yml:

name: lintpal

on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]

jobs:
  lint:
    if: ${{ !github.event.pull_request.draft && github.event.pull_request.head.repo.full_name == github.repository }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v6
        with:
          node-version: 24
      - run: npm install -g lintpal
      - name: Lint pull request
        run: |
          mkdir -p .artifacts/lintpal
          lintpal lint --no-env-file --provider jev \
            --base ${{ github.event.pull_request.base.sha }} \
            --head ${{ github.event.pull_request.head.sha }} \
            --block-on high --format json --out .artifacts/lintpal/findings.json
        env:
          TYPESAFE_API_KEY: ${{ secrets.TYPESAFE_API_KEY }}
      - name: Publish review and apply gate
        run: lintpal feedback github --in .artifacts/lintpal/findings.json --gate
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: lintpal-findings
          path: .artifacts/lintpal/
          if-no-files-found: warn

Open a same-repository pull request. LintPal publishes a review with No blocking findings, 1 blocking finding, or N blocking findings, plus inline comments for eligible new or changed findings. Unchanged comments are deduplicated on later runs. The gate runs after publication; the workflow keeps .artifacts/lintpal/findings.json even when a blocking finding fails the job. Draft and fork pull requests are skipped. GitHub supplies the pull-request context to the feedback command.

See the CLI reference for provider selection, feedback commands, and exit codes. The LintPal Action is also available for workflows that prefer an Action wrapper.

Write Rules in Markdown

The file path beneath .lintpal/rules/ is the rule ID. The body is the requirement. Optional frontmatter controls its policy:

---
severity: high
threshold: 0.97
title: Unchecked error
---

Handle errors returned by calls when failure changes the result or behavior.

Save this rule as .lintpal/rules/go/unchecked-error.md. When the provider assigns a violation probability of at least 0.97, a finding identifies the changed file and line, the high severity, and rule ID go/unchecked-error.md. Its message is Changed code may violate go/unchecked-error.md. The default severity gate blocks on high or critical findings.

Rules are ordinary project files: review them, version them, and change them through the same pull-request process as code.

lintpal rule list
lintpal rule view general/authorization.md
lintpal rule validate
lintpal rule import github:diffpal/lintpal-rules//go@v1.1.0 --prefix go

Read rule authoring for the complete format and rule import for local and pinned GitHub sources.

Run Locally

Install the CLI and add rules using the getting started guide. Then run from your Git repository to check working-tree changes before committing or compare two committed revisions:

export TYPESAFE_API_KEY='your-provider-key'
lintpal doctor

# Lint uncommitted working-tree changes (staged, unstaged, and untracked regular files)
lintpal lint --uncommitted

# Or lint committed revisions
lintpal lint --base origin/main --head HEAD

Committed comparisons start at the unique merge base of base and head; changes found only on the base branch are excluded. See the CLI reference for report revision fields and uncommitted behavior.

Markdown findings go to stdout. Use --out to retain the complete JSON artifact, or --format json for JSON on stdout. The default gate returns exit code 10 when a high or critical finding blocks the run.

Choose TypeSafe/Jev, OpenRouter, OpenAI, or a custom compatible endpoint from Supported Providers. Configure credentials through environment variables or an uncommitted .env file. The selected remote provider receives bounded source context and rule text. See configuration and privacy.

Documentation by Goal

Goal Start here
Run the first check Getting started
Configure providers and policy Configuration
Write project rules Rule authoring
Import reusable rule packs Rule import
Understand findings and gates Report reference
Automate the CLI CLI reference
Review security and data flow Privacy and architecture
Ask a setup question GitHub Discussions Q&A
Suggest a workflow improvement GitHub Discussions Ideas
Report a bug or incorrect finding GitHub Issues
Contribute to LintPal Contributing

License

LintPal is released under the MIT License.

Directories

Path Synopsis
cmd
lintpal command
docs
internal
apps/lintpal/contextplan
Package contextplan assembles bounded committed-source context and plans typed questions without invoking a provider.
Package contextplan assembles bounded committed-source context and plans typed questions without invoking a provider.
apps/lintpal/eval
Package eval evaluates frozen examples with typed, local answers.
Package eval evaluates frozen examples with typed, local answers.
apps/lintpal/jev
Package jev defines the typed decision boundary used by lintpal.
Package jev defines the typed decision boundary used by lintpal.
apps/lintpal/provider/decisions
Package decisions implements the shared typed Decisions HTTP transport.
Package decisions implements the shared typed Decisions HTTP transport.
apps/lintpal/report
Package report defines LintPal's validated, deterministic findings artifact.
Package report defines LintPal's validated, deterministic findings artifact.
apps/lintpal/ruleimport
Package ruleimport copies validated Markdown mandates into a repository.
Package ruleimport copies validated Markdown mandates into a repository.
apps/lintpal/rules
Package rules loads declarative lint rules and maps typed Jev answers to deterministic decisions.
Package rules loads declarative lint rules and maps typed Jev answers to deterministic decisions.
apps/lintpal/rulesource
Package rulesource resolves a worktree and reads pinned remote Markdown rules.
Package rulesource resolves a worktree and reads pinned remote Markdown rules.
apps/lintpal/runtime/adk
Package adk owns the optional, local ADK observability lifecycle.
Package adk owns the optional, local ADK observability lifecycle.
scripts
self-review command
Command self-review builds lintpal and reviews a committed comparison.
Command self-review builds lintpal and reviews a committed comparison.
verify-docs command
Command verify-docs checks local Markdown links and rule examples offline.
Command verify-docs checks local Markdown links and rule examples offline.
verify-format command
Command verify-format checks Go formatting without a platform-specific shell.
Command verify-format checks Go formatting without a platform-specific shell.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL