# Cairnquire Cairnquire is a Go-first documentation platform for serving Markdown as secure, fast HTML with room for later sync, collaboration, and offline features. ## Current Status This repository now contains the Milestone 1 foundation scaffold: - Go application server with chi routing, slog logging, config loading, and graceful shutdown - SQLite/libsql-oriented data layer with startup migrations - Markdown rendering pipeline with wiki-link rewriting, tag extraction, and SSR templates - Content-addressed attachment storage with secure serving - Go-served HTML templates with embedded CSS and browser scripts - Docker, Compose, CI, OpenAPI, and local development targets ## Quick Start ### Prerequisites - `mise` - Docker (optional) - CGO-capable toolchain for `go-libsql` - `air` for Go live reload (`go install github.com/air-verse/air@v1.65.1`) - Xcode command-line tools for the optional macOS sync app and CLI Install the pinned toolchain with: ```bash mise install ``` ### Development Mode (with live reload) Run the Go server with live reload: ```bash mise run dev ``` This starts the Go server with `air` live reload on `http://localhost:8080`. ### Production Mode Run the Go server: ```bash mise run server-run ``` The server listens on `http://localhost:8080` by default. ### macOS Sync and CLI The menu bar sync app and companion CLI live in `apps/macos-sync`. For local development, start the server with its local-only auth shortcut: ```bash PORT=9000 CAIRNQUIRE_DEV_MODE=1 mise run server-run cd apps/macos-sync swift run cairnquire-cli config \ --server http://localhost:9000 \ --token dev \ --folder "$HOME/Documents/Cairnquire" swift run cairnquire-cli sync swift run CairnquireSync ``` The app automatically uses the `dev` token for localhost servers. For a deployed server, create an API token from `/account/tokens/new` and store that token in the app settings. See [`apps/macos-sync/README.md`](apps/macos-sync/README.md) for upload, sync, and Keychain details. ### Fresh Server Deployment The Compose deployment keeps its database and attachment store in `./data` and its editable Markdown source in `./content`. ```bash cp .env.example .env # Edit CAIRNQUIRE_PUBLIC_ORIGIN in .env to match your HTTPS URL. docker compose up -d --build curl http://127.0.0.1:8080/health ``` Open `${CAIRNQUIRE_PUBLIC_ORIGIN}/setup` in a browser. The first-run wizard creates the admin account and asks whether visitors may create accounts. The setup endpoint closes after the first admin is created. An admin can change the signup setting later from the account page. Compose also starts Mailpit for local email testing; inspect outgoing messages at `http://127.0.0.1:8025`. ### Common commands ```bash mise run server-test mise run server-build mise run docker-build mise run ci mise run fmt ``` ## Configuration Configuration can come from: 1. `config.json` via `CAIRNQUIRE_CONFIG` 2. Environment variables Supported variables: - `CAIRNQUIRE_PUBLIC_ORIGIN` - Required for deployment. Exact public HTTPS origin used for passkeys and device-flow URLs, for example `https://cairnquire.example.com`. - `CAIRNQUIRE_SERVER_ADDR` - Listen address. Defaults to `:8080`. - `PORT` - Optional shorthand for the listen port, for example `PORT=9000`. - `CAIRNQUIRE_DATABASE_PATH` - Local SQLite/libsql path. Defaults to `../../data/db.sqlite` when running from `apps/server`. - `CAIRNQUIRE_DATABASE_PRIMARY_URL` - Optional remote libsql primary URL for an embedded replica. - `CAIRNQUIRE_DATABASE_AUTH_TOKEN` - Optional auth token for the remote libsql primary. - `CAIRNQUIRE_CONTENT_SOURCE_DIR` - Editable Markdown source directory. - `CAIRNQUIRE_CONTENT_STORE_DIR` - Content-addressed attachment store. - `CAIRNQUIRE_EMAIL_SMTP_HOST` - SMTP host. Set to an empty string in JSON config to disable delivery. - `CAIRNQUIRE_EMAIL_SMTP_PORT` - SMTP port. Defaults to `1025`. - `CAIRNQUIRE_EMAIL_FROM` - Notification sender address. - `CAIRNQUIRE_LOG_LEVEL` - Defaults to `INFO`. - `CAIRNQUIRE_DEV_MODE` - Optional local-only auth shortcut. Do not enable on a deployed server. ## Dev Mode With `CAIRNQUIRE_DEV_MODE=1`, API requests using `Authorization: Bearer dev` authenticate as the local development admin. This is intended only for localhost testing. ## Noted Gaps - The docs call for `golang-migrate`, but the current foundation uses an internal migration runner while `go-libsql` integration details are validated. - The sync docs describe JSON messages while the Milestone 1 layout mentions a protobuf package; both are preserved in `packages/protocol/` pending a later protocol lock.