Skip to content
lawlint
Esc
navigateopen⌘Jpreview
On this page

Setting up AI features

What lawlint init does, which providers are supported, and where API keys are stored.

Linting is deterministic and offline. Two features are not — the soft-rule AI judge and lawlint learn — and neither does anything until you configure a model.

lawlint init

The walkthrough covers AI-model choice, whether the judge runs on every lint, Markdown handling for stdin, and custom rule directories. It writes .lawlint/config.json, plus an optional starter rules package under .lawlint/rules/.

Hosted providers

The recommended path: better quality, no multi-gigabyte download.

Provider Model spec Key
Anthropic (recommended) anthropic:<model> ANTHROPIC_API_KEY
OpenAI-compatible openai:<base-url>#<model> OPENAI_API_KEY
Azure AI Foundry foundry:<deployment> AZURE_FOUNDRY_API_KEY

API keys go to a user-level credential file — ~/.lawlint/credentials, mode 0600 — or to the environment. The environment wins. Keys are never written into your project, so .lawlint/config.json is safe to commit.

Once a key and a model are configured, the soft rules run on every lint, including in directories with no project config. --no-ai skips them for a run; "judge": { "enabled": false } turns them off for good.

Before 0.8 the credential file lived at ~/.config/lawlint/credentials. It is still read from there, and the next lawlint init moves it to ~/.lawlint/ and reports the move.

Keeping text on your machine

lawlint has no built-in model. If the document must not leave your machine — privileged material, a client matter under an engagement term that forbids it — run an OpenAI-compatible server yourself and point lawlint at it:

ollama serve && ollama pull qwen3:30b
lawlint init --ai openai:http://localhost:11434/v1#qwen3:30b

That spec needs no API key, and nothing but your own server ever sees the text. Ollama, vLLM, llama.cpp and LM Studio all speak this protocol.

Non-interactive setup

lawlint init --yes                          # accept defaults (hosted)
lawlint init --ai anthropic:claude-haiku-4-5-20251001
lawlint init --ai openai:http://localhost:11434/v1#qwen3:30b  # self-hosted
lawlint init --force                        # overwrite an existing config
PropType
--yes?flag

Accept the default answer for every prompt.

Typeflag
--force?flag

Overwrite an existing .lawlint/config.json.

Typeflag
--ai?string

Model spec, skipping the catalog prompt (anthropic:<model>, openai:<base-url>#<model>, foundry:<deployment>).

Typestring

What it writes

// .lawlint/config.json — every field optional, camelCase
{
  "ai": {
    "model": "anthropic:claude-haiku-4-5-20251001",
    "features": { "judge": "...", "learn": "..." },
  },
  "judge": { "enabled": false },
  "markdown": false,
  "ruleDirs": [".lawlint/rules"]
}

ai.model is the default for every AI feature; ai.features overrides it per feature. The full schema is in Configuration.

Where config is found

The CLI walks up from the current directory looking for .lawlint/config.json, falling back to the legacy lawlint.config.json at each level. The first directory containing either is the project root, and relative ruleDirs resolve against it.

A config file that exists but does not parse is a configuration error — exit 2 — never a silent skip.

Last updated on July 24, 2026