> ## Documentation Index
> Fetch the complete documentation index at: https://docs.docwriter.org/llms.txt
> Use this file to discover all available pages before exploring further.

# How it works

> A short technical overview, for the curious.

This page is for users who want to understand what DocWriter is doing
under the hood. You do not need any of this to use DocWriter.

## The data model

The editor state for every open tab is a [Yjs](https://yjs.dev) CRDT.
The authoritative copy lives on the DocWriter server; the browser is a
synced client connected over WebSocket via
[Hocuspocus](https://hocuspocus.dev). When you type, your keystroke is a
local CRDT operation that streams to the server and back to every other
connected client (typically just you, in another browser tab).

When the agent edits, it does the same thing: its tools open a direct
connection to the live document and apply CRDT operations tagged with an
agent origin. The browser receives those operations the same way it
receives any other remote update. This is what makes the agent feel like
a concurrent editor instead of a chat that operates on the document
externally.

## Persistence

DocWriter stores work in two places in your workspace:

* **Your tab files.** Whatever files you open (`essay.md`,
  `chapter-1.tex`, `notes/todo.txt`) are the durable record of your
  writing. DocWriter flushes the live CRDT for each tab back to its
  source file about one second after the last edit, so the file on disk
  is always a current copy you can open in any other editor or commit to
  git.

* **`.docwriter/`**. DocWriter's own state, kept in your workspace:

  * `.docwriter/docwriter.db`. SQLite. Holds the full Yjs CRDT update
    log for every tab (so undo, comment threads, and pending agent
    reviews survive restarts), plus tables for rules, hooks, comment
    threads, recent actions, and session key-value state.
  * `.docwriter/state.json`. A human-readable copy of rules, hooks, and
    agent settings. Updated alongside the database so you can read or
    edit it in any text editor and so it diffs cleanly under git.

The SQLite database is the source of truth for everything DocWriter
itself needs to reload (CRDT history, pending reviews, comments). Your
tab files are the source of truth for the writing.

## The agent loop

DocWriter is built directly on the
[Claude Agent SDK](https://docs.claude.com/en/agent-sdk/overview) — the
same runtime that powers Claude Code. The agent therefore has the same
built-in tool set Claude Code has:

| Tool                      | What it does                 |
| ------------------------- | ---------------------------- |
| `Edit` / `Write` / `Read` | Read and patch files on disk |
| `Bash`                    | Run arbitrary shell commands |
| `WebSearch` / `WebFetch`  | Web research                 |
| `TodoWrite`               | Track multi-step task plans  |

On top of those, DocWriter mounts two MCP servers with writing-specific tools:

* **`docwriter`** — `propose_rule`, `propose_hook` (surface review cards in the UI before committing anything).
* **`docwriter-doc`** — `edit_doc`, `read_doc`, `write_doc`, `post_comment`, `list_threads` (operate on the live CRDT documents rather than raw files, so edits appear as reviewable rounds).

When you send a prompt, `/api/render` streams a single `query()` call
over SSE. (For how the SDK's agent loop works in general, see
[How the agent loop works](https://docs.claude.com/en/agent-sdk/agent-loop).)
Each tool call is logged to the history pane as it happens.

## Further reading

For contributors and integrators:

* [`CLAUDE.md`](https://github.com/shreyashankar/docwriter/blob/main/CLAUDE.md).
  Orientation for working on DocWriter itself.
* [`ARCHITECTURE.md`](https://github.com/shreyashankar/docwriter/blob/main/ARCHITECTURE.md).
  The full system design.
