# ClickClack Self-hostable, API-first chat. Slack-style threads, Discord-ish warmth, and a light crustacean theme. Ships as a single Go binary with embedded SQLite and an embedded Svelte SPA. ```sh pnpm install pnpm build go run ./apps/api/cmd/clickclack serve # open http://localhost:8080 ``` ## What's in the box - One Go binary. Embedded Svelte SPA, embedded SQL migrations, embedded static assets — no separate web server, no extra services. - SQLite first-class storage with WAL, FTS5 search, and an online backup command. Postgres is planned behind the same store interface. - Realtime over WebSocket with a durable event log. Reconnect with a cursor to recover anything you missed; HTTP `/api/realtime/events` works as a pull-style fallback. - Channels with Slack-style threads (one level, no nesting), reactions, uploads, and direct messages. - CLI-managed bootstrap, magic-link auth, optional GitHub OAuth, and an agent-friendly client mode for sending/listing/replying from scripts. - Framework-neutral [TypeScript SDK](packages/sdk-ts) and a tiny [bot example](examples/bot-ts). - Mattermost-shaped incoming webhook and slash command surfaces for drop-in scripts. ## Documentation Product domain: **[clickclack.chat](https://clickclack.chat)**. App domain: **[app.clickclack.chat](https://app.clickclack.chat)**, with `/app` as the local path. Docs domain: **[docs.clickclack.chat](https://docs.clickclack.chat)**, built from `docs/` by `pnpm docs:site`. The [docs/](docs/) tree is organised so each file has a short `read_when` hint at the top — open the one that matches your change. - **Start here:** [docs/README.md](docs/README.md) — landing page + index. - [Architecture](docs/architecture/overview.md) — process layout, durable vs realtime split. - [API overview](docs/api/overview.md) — REST/WebSocket surface and where to find each endpoint. - [Data model](docs/data-model.md) — tables, IDs, invariants. - [CLI](docs/cli.md), [Agent-friendly CLI](docs/agent-friendly-cli.md), [Configuration](docs/configuration.md), [Deployment](docs/deployment.md), [Development](docs/development.md), [Releasing](docs/releasing.md). - [TypeScript SDK](docs/sdk.md). Per-feature docs: | Feature | Doc | |------------------|-----| | Auth | [docs/features/auth.md](docs/features/auth.md) | | Workspaces | [docs/features/workspaces.md](docs/features/workspaces.md) | | Messages | [docs/features/messages.md](docs/features/messages.md) | | Threads | [docs/features/threads.md](docs/features/threads.md) | | Reactions | [docs/features/reactions.md](docs/features/reactions.md) | | Realtime | [docs/features/realtime.md](docs/features/realtime.md) | | Search | [docs/features/search.md](docs/features/search.md) | | Uploads | [docs/features/uploads.md](docs/features/uploads.md) | | Direct messages | [docs/features/dms.md](docs/features/dms.md) | | Integrations | [docs/features/integrations.md](docs/features/integrations.md) | The product spec — locked decisions, milestones, and open questions — lives in [SPEC.md](SPEC.md). ## Quick start ```sh pnpm install # JS deps for SPA + SDK pnpm build # builds SPA, copies dist into the Go binary go run ./apps/api/cmd/clickclack serve # http://localhost:8080 ``` The dev fallback boots a default user, workspace, and channel so the SPA loads into something useful at `/app`. The root path is the public product website. Disable it with `--dev-bootstrap=false` for anything that isn't a local checkout. ### Two-process dev loop ```sh pnpm dev:api # Go server with hot rebuild via go run pnpm dev:web # Vite dev server proxied to /api ``` ### CLI ```sh go run ./apps/api/cmd/clickclack admin bootstrap \ --name "Peter" --email steipete@gmail.com go run ./apps/api/cmd/clickclack admin magic-link create \ --email steipete@gmail.com --name "Peter" go run ./apps/api/cmd/clickclack login --magic-token mgt_... go run ./apps/api/cmd/clickclack whoami go run ./apps/api/cmd/clickclack send --channel general "click clack" go run ./apps/api/cmd/clickclack messages list --channel general go run ./apps/api/cmd/clickclack threads reply msg_... --stdin