# Writing Modes Reference

## Two Modes

| Mode | Name | Behavior |
|------|------|----------|
| **Direct Write** | Default | Agent writes content directly. A version snapshot is auto-created on every PATCH write so the user can revert. |
| **Suggest** | Collaborative | Agent proposes changes as tracked suggestions. Document owner reviews in the editor and accepts or rejects each one. |

## Content Format

Send content as **markdown**. The server converts to the editor's internal
format automatically.

**Title handling:** If your markdown starts with `# Title`, the server extracts
it as the document title (metadata) and stores the rest as body content. On read,
the title is always returned as the first H1 line. This ensures clean round-trips.

Supported markdown features:

- Headings (H1-H6, where H1 = document title)
- Bold, italic, strikethrough, code
- Ordered and unordered lists, task lists
- Tables (GFM pipe syntax)
- Code blocks with syntax highlighting
- Math: `$inline$` and `$$block$$` (KaTeX)
- Horizontal rules
- Block quotes
- Images and links
- Superscript and subscript

## Version Snapshots

Every `write_document` call (Direct Write mode) auto-creates a version snapshot
before applying changes. This means:

- The user can always revert to any previous state via `list_versions`
- Agents can write confidently knowing no content is permanently lost
- No explicit "save version" call is needed

## Workflow: Write then Publish

```
1. create_document(title: "My Article")        → { id: "abc-123" }
2. write_document(id: "abc-123", content: "# My Article\n\n...")
   → version snapshot auto-created before content is replaced
3. publish_document(id: "abc-123")             → { url: "/p/my-article" }
```

## Workflow: Suggest Changes (collaborative)

Two suggest sub-modes exist:

**Find/Replace** — propose a specific text substitution:
```
1. read_document(id: "abc-123")
2. suggest_edits(id: "abc-123", find: "dramatically outpace", replace: "significantly outperform")
3. Owner opens document → sees tracked changes → accepts or rejects
```

**Full-Document Diff** — send a complete new version of the document and let
the server compute the diff as tracked suggestions:
```
1. read_document(id: "abc-123")
2. write_document(id: "abc-123", content: "# Revised Article\n\n...", mode: "suggest")
   → Server diffs old vs new, stores all differences as pending suggestions
3. Owner opens document → sees full set of tracked changes
```

### REST `mode` Parameter

When calling `PATCH /api/d/<id>`:

| `mode` value | Behavior |
|--------------|----------|
| _(omitted)_ | Direct Write. Replaces content, creates version snapshot. |
| `suggest` | Full-document diff. Server computes tracked changes from old-to-new. |
| `suggest_replace` | Find/replace. Requires `find` and `replace` fields. Targets a specific text span. |

### Optional Parameters for Suggestions

| Parameter | Type | Purpose |
|-----------|------|---------|
| `authorName` | string | Display name shown on the suggestion badge in the editor (defaults to token owner name) |
| `reason` | string | Short explanation shown alongside the suggestion so the reviewer understands why the change was proposed |

## Workflow: Targeting Duplicate Text

When the same text appears in multiple places, use `format=nodes` to identify
the exact node, then target your edit with `nodeId`:

```
1. read_document(id: "abc-123", format: "nodes")
   → { nodes: [
       { index: 0, type: "heading", attrs: { nodeId: "a1b2c3..." }, ... },
       { index: 1, type: "paragraph", attrs: { nodeId: "d4e5f6..." }, content: [{ type: "text", text: "Revenue grew 15%" }] },
       { index: 2, type: "paragraph", attrs: { nodeId: "g7h8i9..." }, content: [{ type: "text", text: "Revenue grew 15%" }] },
     ]}

2. suggest_edits(id: "abc-123", find: "Revenue grew 15%", replace: "Revenue grew 18%", nodeId: "d4e5f6...")
   → Only edits the first paragraph, not the second
```

## Rate Limits

- Read operations: 120 requests/minute
- Write operations: 60 requests/minute

