# 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_PROVIDER` - `smtp`, `postmark`, `cloudflare`, or `noop`. Compose defaults to `smtp` with Mailpit.
- `CAIRNQUIRE_EMAIL_SMTP_HOST` - SMTP host for local delivery.
- `CAIRNQUIRE_EMAIL_SMTP_PORT` - SMTP port. Defaults to `1025`.
- `CAIRNQUIRE_EMAIL_POSTMARK_TOKEN` - Postmark server token when the provider is `postmark`.
- `CAIRNQUIRE_EMAIL_CLOUDFLARE_ACCOUNT_ID` - Cloudflare account with Email Sending enabled.
- `CAIRNQUIRE_EMAIL_CLOUDFLARE_API_TOKEN` - Cloudflare token with Email Sending permission.
- `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.
