Thank you for your interest. Issues and pull requests are both welcome.
If you found a vulnerability, do not open an issue. Report it privately, as SECURITY.md describes.
You need Go 1.26+ and Docker with Compose v2. Every AWS component has a local substitute: MinIO for S3 and STS, dex for the OIDC provider, and libsql-server for Turso. No cloud account is necessary to develop or to test.
git clone https://github.com/closeio/click.git && cd click
make up # MinIO + PostgreSQL + clickd + nginx
make examples # build the CLI and deploy the demo sitesThen open http://hello.click.localhost:8080/. The full walkthrough is in DEPLOY.md: both stack modes, the CLI environment, and troubleshooting.
Run what CI runs:
go build ./... && go vet ./... && gofmt -l ./cmd ./internal && make testgofmt -l must print nothing. make test is the Go unit-test suite. It is
hermetic: it fakes every external service in-process, with no Docker and no
network, and it covers about 99% of statements. Keep it that way when you add
code. go test ./... -short skips the one slow case, and make cover prints
the total.
Then run the smoke suite for each mode that your change affects. These are end-to-end shell scripts against a live stack:
make up && make smoke # open mode: 33 checks
make down
make up-auth && make smoke-auth # auth mode: 34 checksTo switch modes, run make down first. A suite that fails partway can leave
state behind. Reset it with
docker compose -f docker-compose.yml -f docker-compose.auth.yml down -v.
CI runs the unit tests in the checks job, and both smoke suites on amd64 and
arm64. It skips them for docs-only pull requests (paths-ignore covers root
*.md and docs/**). If you move a documentation section, re-check the
cross-document links yourself: they are heading anchors and they break
silently.
For CLI-only changes, neither smoke suite applies. make test covers the CLI,
and make build lets you drive bin/click against a scratch directory.
AGENTS.md is the orientation document. It carries the load-bearing
architecture and the invariants that you must know before you change anything.
Two matter most: nginx is the trust boundary, and per-site isolation is
enforced in four mirrored layers. Read it first.
Prose is split across four root documents, each owning a scope. Extend the right one instead of duplicating:
| Document | Scope |
|---|---|
| README.md | The narrative and the CLI reference |
| ARCHITECTURE.md | Component map, request path, repo layout |
| DESIGN.md | Database API, auth/ownership, isolation, performance, limitations |
| DEPLOY.md | Local stack, test suites, real AWS S3, EKS/Terraform |
Deep dives go in docs/.
cmd/clickis a cobra CLI. Each subcommand is anxxxCmd() *cobra.Commandconstructor next to therunXxx(ctx, …)function that it calls, androotCmd()inmain.goconnects them. Wrap argument validators inmisuseArgs(…), so that a bad invocation exits 2 with usage and a failed command exits 1.go build ./...drops a strayclickdbinary at the repository root. Runrm -f clickdbefore you commit, or usemake build, which writes tobin/.- Never accept a site name or an identity from a request body or a query
string. nginx derives
X-Click-SiteandX-Auth-Request-Email, and it always overwrites them, so handlers trust nginx and never the caller.
When you contribute, you agree that your contributions are licensed under the MIT License that covers this project.