Skip to content

CI and Editors

Fred Souza edited this page Aug 3, 2026 · 1 revision

Pre-commit

lanekeep check --staged

Only what is about to be committed, intersected with the config's include/exclude. On a warm cache this is the fast path — unchanged files are cache hits and execute no JavaScript at all.

Cross-file rules are skipped, and named on stderr when they are. A whole-corpus rule over a subset gives a wrong answer, not a smaller one, so it is skipped rather than quietly producing one. Run the full check in CI.

With pre-commit:

- repo: local
  hooks:
    - id: lanekeep
      name: lanekeep
      entry: lanekeep check --staged
      language: system
      pass_filenames: false

GitHub Actions

- name: lanekeep
  run: npx lanekeep check --format sarif > lanekeep.sarif
- uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: lanekeep.sarif

SARIF puts violations in the Security tab and inline on the pull request. Swap npx for pipx run lanekeep, go tool lanekeep or a downloaded binary as suits the repository.

To check only what a pull request changed:

lanekeep check --since origin/main

Adopting on an existing codebase

lanekeep check --warn-only

Reports everything and exits 0, so a rule can go in before the violations are gone. Or set the rule to warn in the config's severity map and raise it later.

Output formats

--format For
human The default. Colored, one violation per line, with the remediation.
json Versioned, stable schema. For your own tooling.
sarif GitHub code scanning, and most other analysis platforms.
agent Token-minimal. Grouped by rule rather than by file, with each card stated once.

Diagnostics always go to stderr, so piping into a parser works even when something fails.

Editors

lanekeep server

LSP over stdio. Diagnostics publish on open and on save — not per keystroke, because a check reads from disk and the buffer an editor holds mid-edit is not there yet. Publishing against stale bytes puts squiggles under the wrong characters, which is worse than a save-length delay.

Point any language client at that command. For Neovim with nvim-lspconfig, a custom server entry running lanekeep server is enough; VS Code needs a thin extension wrapping the same command.

Agents

The same binary serves MCP over stdio — --protocol mcp, where lsp is the default — with three tools:

Tool Does
lanekeep_check Runs a check and returns the agent format
lanekeep_rules Lists configured rules
lanekeep_explain One rule's card
{
  "mcpServers": {
    "lanekeep": { "command": "lanekeep", "args": ["server", "--protocol", "mcp"] }
  }
}

An agent can then ask what it broke and what the rule wants without shelling out and parsing text. That is the case the agent reporter exists for: grouped by rule, each card stated once instead of once per violation.

Nothing is printed to stdout that is not a protocol message, in either mode — a stray line there desynchronizes the client for good.

Watching

lanekeep check --watch

A foreground loop, not a daemon: it holds nothing a fresh run would not rebuild, and Ctrl-C ends it. The warm cache is what makes each re-run fast.

Performance notes

  • gates.fileContains rejects files before parsing. Free on any rule with a distinctive token.
  • --profile reports where a run spent its time, per rule, split between query matching and handler execution — which tells you whether the query or the code is the problem.
  • The cache lives in .lanekeep/, inside the project root. lanekeep init adds it to .gitignore; it is a multi-megabyte binary and does not belong in git.
  • --no-cache recomputes everything. For diagnosing a suspected stale result — if you ever find one, the cache key is missing an input, which is a bug worth reporting.

Clone this wiki locally