Prepare the repository for a public release. Ignore local Claude Code session files.
3.8 KiB
Contributing to LMR
Thanks for your interest. This page tells you how to set up a development environment, how to run the checks, and what a good pull request looks like.
Development setup
You need Go 1.27 or newer, Node 22 or newer, Docker, and make.
cd backend
cp .env.example .env
echo GATEWAY_SECURITY_ENCRYPTION_KEY=$(openssl rand -hex 32) >> .env
make dev
make dev starts a Postgres container, applies the migrations, runs the Go
server on port 8080, and runs the Vite dev server on port 5173 with a proxy to
the Go server. The dashboard needs an OIDC provider to sign in. Any provider
works; the .env.example file shows the Authentik shape.
Run make help to list every target.
Checks
Run these before you open a pull request. The CI pipeline runs the same set.
cd backend
go vet ./...
make test # unit tests, no database needed
make lint # golangci-lint, config in backend/.golangci.yml
cd dashboard && npx tsc --noEmit && npm run build
Database tests
The internal/store and internal/catalog packages have integration tests
against a real Postgres. They skip unless GATEWAY_TEST_DB_URL is set.
cd backend
make dev-db # or any Postgres 16
export GATEWAY_TEST_DB_URL='postgres://gateway:gateway@localhost:5432/gateway?sslmode=disable'
GATEWAY_DB_URL=$GATEWAY_TEST_DB_URL go run ./cmd/migrate up
go test ./internal/store/ ./internal/catalog/
The tests delete and recreate rows, so point them at a throwaway database.
Project layout
See the "Repo layout" section of the README and the architecture notes. The short version:
backend/internal/apiholds the HTTP handlers.backend/internal/providersholds the provider abstraction. Each upstream type lives in its own package and registers itself ininit().backend/internal/catalogholds the runtime model library.backend/internal/storeholds hand-written SQL onpgx.backend/migrationsholds the schema. Add a new numbered pair ofupanddownfiles for every schema change. Never edit an applied one.backend/dashboardholds the React UI. The Go binary embeds the build.
Adding a provider
- Create
backend/internal/providers/<type>/with aNewfactory and aninit()that callsproviders.Register. - Implement the capability interfaces the upstream supports:
ChatCompleter,Embedder,ImageGenerator,ModelLister. - Import the package in
backend/internal/providers/all. - If the upstream is OpenAI-compatible, embed
openaicompat.Transportand only add what differs. See theopenrouterpackage for an example. - Add the type to the providers table in the README and to the dashboard's provider form.
Pull requests
- Keep one change per pull request.
- Add or update tests for the code you touch. Handler tests live in
backend/internal/apiand use fake dependencies, so they do not need a database. - Run
gofmt. The lint step fails on unformatted code. - Write commit messages as
<area>: <short summary>in the imperative mood, for examplecatalog: store output modalities as capabilities. Explain the reason in the body when it is not obvious from the diff. - Do not include generated files. The
internal/web/distfolder andbin/are ignored on purpose.
Reporting bugs
Open an issue with the version or commit, the steps to reproduce, the expected result, and the actual result. For a request that failed at the proxy, include the row from the Logs page with the key prefix removed.
Security problems go to the address in SECURITY.md, not to the issue tracker.
License
By contributing you agree that your contributions are licensed under the GNU Affero General Public License, version 3, the same as the project.