VernLLMVernLLM

Contributing

How to set up the workspace, run the checks, and open a PR

Thanks for considering a contribution to VernLLM! This page covers workspace setup, expectations for tests, and the pre-PR checklist.

Setup

Fork the repo and branch off main, then install the workspace:

pnpm install

Coding standard

VernLLM's job is to make the call reliable, not necessarily the app. Every module in packages/vern-llm should stay inside that lane: normalize provider quirks, handle failure modes explicitly, and hand the caller a predictable result. It is not the place for app-level concerns (business logic, UI state, persistence beyond the built-in cache). If a change starts pulling in those concerns, it's probably the wrong framework.

Anything that comes from a call, meaning a timeout, a bad response, a circuit trip, a provider error, should come out the other end as an LLMError with a clear type and code if it is possible, never a bare exception or a raw provider error. This only applies to the call path though. An internal bug, like an out of range index inside vernLLM.ts, is a plain thrown error or assertion, not an LLMError, since it isn't something a caller should branch on.

Reliability code such as circuitBreaker.ts, rateLimit.ts, and retry.utils.ts should handle the weird inputs on purpose (zero, negative, Infinity, concurrent calls) instead of assuming the happy path. Explain unusual decisions with a short comment describing why, not a restatement of the code. Provider quirks stay inside src/adapters/*; everything else works against the shared LLMClient shape and stays provider agnostic. Tests run entirely on fakes and mocks, never real network calls.

Keep types precise. any is a final escape hatch, not a shortcut. Reach for it only when a provider SDK genuinely gives you no usable type (see the Gemini adapter's thinkingLevel), and when you do, leave a comment explaining why it's there instead of a narrower type.

Tests

Add or update tests alongside any change to packages/vern-llm:

  • tests/unit/ for isolated behavior
  • tests/integration/ for cross-cutting workflows

No real API calls are made anywhere in the suite; everything runs against fakes and mocks. See Development for the full test layout.

New or changed lines in packages/vern-llm need at least 80% test coverage; CI enforces this through Codecov's patch check. Overall project coverage is also tracked and shouldn't regress by more than a small margin. Run pnpm run test:coverage locally to see where you stand before opening a PR.

Before a change is merged, expect a personal canary test on a simple real app, like a small chat CLI, to confirm the change behaves as intended outside the test suite.

Before opening a PR

Every PR runs the following checks in CI. Run the equivalent commands locally first so nothing surprises you:

CheckWorkflowLocal command
Lintlint.ymlpnpm run lint
Typecheck sourcetypecheck.ymlpnpm run typecheck:package
Typecheck teststypecheck.ymlpnpm run typecheck:test
Unit tests + coveragetest-unit.ymlpnpm run test:unit:coverage
Integration tests + coveragetest-integration.ymlpnpm run test:int:coverage
Build, bundle size, smoke testbuild-checks.ymlpnpm run build:package && pnpm --filter vern-llm run size && pnpm --filter vern-llm run smoke-test
Changeset presentchangeset.ymlpnpm changeset status --since=origin/main
Docs build (only if apps/docs/** changed)docs-build.ymlpnpm --filter vern-llm-docs run lint && pnpm --filter vern-llm-docs run types:check && pnpm --filter vern-llm-docs run build
Coverage thresholdsCodecovpnpm run test:coverage
Static analysiscodeql.ymlruns on GitHub only

The quickest local pass before pushing:

pnpm run lint
pnpm run typecheck
pnpm run typecheck:test
pnpm run test:unit:coverage
pnpm run test:int:coverage
pnpm run build:package

build-checks.yml also verifies peer dependencies (pnpm peers check), checks the published bundle stays under the configured size-limit, and runs a smoke test against the built output, so if you're touching packages/vern-llm's public surface or its dependencies, run pnpm run build:package and pnpm --filter vern-llm run size before pushing.

changeset.yml blocks any PR touching packages/vern-llm that doesn't include a changeset (see below). docs-build.yml only runs when apps/docs/** or the lockfile changes, so it won't fire on pure library changes.

Changesets

Record your change with:

pnpm run changeset

CI checks every PR touching packages/vern-llm for a changeset. If your change doesn't need a release, run pnpm changeset add --empty instead of skipping it.

This drives versioned release notes. Releases themselves are automated through .github/workflows/version.yml and .github/workflows/publish.yml, so there are no manual version bumps or publishing steps.

Code of Conduct

Participation in this project is governed by our Code of Conduct.

Security issues

Please don't open a public issue for a security vulnerability. See Security for how to report one privately.

On this page