Files
Outpost/CLAUDE.md
T

43 lines
3.6 KiB
Markdown

# CLAUDE.md
Context file for Claude Code. Read this before making changes. See `docs/ARCHITECTURE.md` for deep technical rationale.
## Project
Native Apple ecosystem client for a self-hosted [Outline](https://github.com/outline/outline) instance (wiki/knowledge base). Targets **iOS, iPadOS, macOS**, single SwiftUI multiplatform codebase. Goal is **full editing parity** with Outline's web app — not a read-only viewer.
Working name: `OutlineClient` (rename freely — placeholder only, not a branding decision).
## License context (do not re-litigate)
Outline server is BSL 1.1 licensed. This restricts *hosting/reselling Outline itself as a service*. It does **not** restrict building an API client. This app only ever talks to Outline's public REST/WebSocket API — it never vendors, forks, or redistributes Outline's server source. No license concerns for this codebase.
## Architecture summary
- **REST layer** — Outline's RPC-style API (`/api/*`), Bearer token auth (`Authorization: Bearer <token>`). Handles collections, documents (non-realtime CRUD), search, users.
- **Realtime collab layer** — Outline runs a **Hocuspocus** server (Yjs CRDT over WebSocket) at `wss://<host>/collaboration/document.<id>`. This is the actual editing transport when a document is open — not the REST API. Full parity requires speaking this protocol, including the Yjs awareness protocol for remote cursors/presence.
- **CRDT engine** — [YSwift](https://github.com/y-crdt/yswift) (Swift bindings over `yrs`, the Rust Yjs port, via UniFFI). This is the only realistic native path to binary-compatible Yjs sync. It is pre-1.0 / WIP — expect to patch or contribute upstream, don't assume full feature coverage going in.
- **Editor UI** — native TextKit 2 (`NSTextLayoutManager` / `AttributedString`) rendering mapped from Outline's ProseMirror document schema (headings, lists, checklists, tables, code blocks, embeds, comments). This is the largest single scope item in the project — treat it as its own subsystem, not a UI detail.
## Phased build order
1. **Phase 1 — Read/browse + REST-only editing.** Auth, collections tree, document list, search, markdown-rendered read view, basic edit-and-PUT (last-write-wins, no live collab). Ship this before touching Yjs at all.
2. **Phase 2 — Realtime collaboration.** Integrate YSwift + Hocuspocus WebSocket, map Yjs XML fragment ↔ native editor state, add awareness/presence.
3. **Phase 3 — Polish.** Offline cache, conflict UI, embeds/attachments, tables, comments, macOS-specific affordances (menu bar, multiple windows).
Do not start Phase 2 work until Phase 1 is stable and shipped to the device. The CRDT/editor layer is high-risk; de-risk everything else first.
## Conventions
- Swift, SwiftUI-first. No UIKit/AppKit escape hatches unless SwiftUI genuinely can't do it (flag these explicitly in PR/commit messages).
- Networking: `URLSession` + `async/await`, no third-party HTTP client.
- API tokens stored in Keychain only — never UserDefaults, never logged.
- Prefer protocol-oriented boundaries between the REST layer, the CRDT/sync layer, and the editor UI layer so any one of them (especially YSwift) can be swapped without touching the others.
- Target iOS 17+ / macOS 14+ minimum (needed for mature `AttributedString`/TextKit 2 APIs).
## Do not
- Do not attempt to reimplement Yjs's CRDT algorithm from scratch — use YSwift/yrs. This has been tried by others and is a multi-year effort (see Yrs project history).
- Do not fall back to polling the REST API for "realtime" — it will visibly diverge from true collaborative editing and defeats the point of this project.
- Do not vendor or copy Outline's server source into this repo.