scrivener

Scrivener project format internals, data model, and programmatic access. Use when parsing .scriv bundles, querying DuckDB exports, extracting manuscript text, or building AI-assisted novel tools from Scrivener data. Covers Windows-origin projects, cross-platform migration, and RTF content.

16 stars

Best use case

scrivener is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Scrivener project format internals, data model, and programmatic access. Use when parsing .scriv bundles, querying DuckDB exports, extracting manuscript text, or building AI-assisted novel tools from Scrivener data. Covers Windows-origin projects, cross-platform migration, and RTF content.

Teams using scrivener should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/scrivener/SKILL.md --create-dirs "https://raw.githubusercontent.com/plurigrid/asi/main/plugins/asi/skills/scrivener/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/scrivener/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How scrivener Compares

Feature / AgentscrivenerStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Scrivener project format internals, data model, and programmatic access. Use when parsing .scriv bundles, querying DuckDB exports, extracting manuscript text, or building AI-assisted novel tools from Scrivener data. Covers Windows-origin projects, cross-platform migration, and RTF content.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Scrivener: Project Format, Data Model & Programmatic Access

**Trit**: -1 (MINUS - validator/extractor)
**Color**: #E91A2F (Character Notes red)

## When to use this skill

- Parsing or inspecting `.scriv` project bundles (XML, RTF, metadata)
- Querying a DuckDB export of Scrivener data (documents, content, labels)
- Extracting manuscript text, character info, or synopses programmatically
- Migrating projects across Scrivener versions or platforms (Windows ↔ macOS)
- Building tools that read/write Scrivener project structures

## File Format: .scriv Bundle

A `.scriv` project is a directory. On macOS it displays as a single file (document package); on Windows it's a regular folder.

```
MyProject.scriv/
├── Files/
│   ├── Data/
│   │   ├── <UUID>/
│   │   │   ├── content.rtf       # Document body (RTF format)
│   │   │   ├── notes.rtf         # Inspector notes (RTF)
│   │   │   ├── synopsis.txt      # Synopsis text
│   │   │   └── snapshot-*.rtf    # Version snapshots
│   │   └── docs.checksum         # Integrity checksums
│   ├── binder.autosave           # Auto-saved binder state
│   ├── binder.backup             # Binder backup
│   ├── search.indexes            # Full-text search index
│   ├── styles.xml                # Document styles
│   ├── version.txt               # Format version
│   └── writing.history           # Session word counts
├── <ProjectName>.scrivx           # Master XML: binder tree + metadata
├── Settings/
│   ├── recents.txt               # Recent documents
│   ├── ui-common.xml             # Cross-platform UI state
│   └── ui.ini                    # Platform-specific UI state
└── QuickLook/
    └── Preview.html              # Finder preview (macOS only)
```

## Version History & Cross-Platform Migration

The ☼ project was **created on Windows** and has been migrated through multiple Scrivener versions:

| Version | Platform | Format | Notes |
|---------|----------|--------|-------|
| Scrivener 1 (Win) | Windows | XML `.scrivx` v1 + RTF | Original Windows port. `.scriv` is a visible folder. |
| Scrivener 1 (Mac) | macOS | Binary plist `.scrivproj` + RTF | macOS only, different format entirely. |
| Scrivener 2 (Mac) | macOS | Binary plist → XML | Transitional. No Windows v2 existed. |
| Scrivener 3 (Win) | Windows | XML `.scrivx` v2 + RTF | **Current**. Creator tag: `SCRWIN-3.x.x.x` |
| Scrivener 3 (Mac) | macOS | XML `.scrivx` v2 + RTF | **Current**. Creator tag: `SCRMAC-3.x.x` |

### Windows → macOS migration

- `.scriv` folder on Windows is a regular directory; on macOS it becomes a document package (UTI: `com.literatureandlatte.scrivener3.scriv`)
- Copy the entire `.scriv` folder to macOS and open with Scrivener 3 — it auto-upgrades
- The `Creator` attribute in `.scrivx` preserves origin: `SCRWIN-3.1.5.1` means Windows Scrivener 3.1.5.1
- `ui.ini` stores platform-specific UI state; `ui-common.xml` stores cross-platform state
- QuickLook/ only generated on macOS
- Line endings in RTF may differ (CRLF from Windows, LF on macOS) — both parse correctly

### Version upgrade path

Windows v1 → Windows v3: Scrivener auto-converts on open. Creates backup of v1 project first. Binder structure, labels, statuses, and content preserved. Custom metadata fields may need manual re-setup.

## .scrivx XML Schema

The `.scrivx` file is the master index:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<ScrivenerProject Template="No" Version="2.0"
    Identifier="UUID" Creator="SCRWIN-3.1.5.1"
    Device="HOSTNAME" Modified="2025-03-14 22:15:28 -0600"
    ModID="UUID">
  <Binder>
    <BinderItem UUID="..." Type="DraftFolder" Created="..." Modified="...">
      <Title>Draft</Title>
      <MetaData>
        <IncludeInCompile>Yes</IncludeInCompile>
      </MetaData>
      <Children>
        <BinderItem UUID="..." Type="Text" Created="..." Modified="...">
          <Title>Chapter 1</Title>
          <MetaData>
            <LabelID>2</LabelID>
            <StatusID>-1</StatusID>
            <IncludeInCompile>Yes</IncludeInCompile>
            <SectionType>-1</SectionType>
          </MetaData>
        </BinderItem>
      </Children>
    </BinderItem>
  </Binder>
  <LabelSettings>
    <Labels>
      <Label ID="0" Color="0.993 0.227 0.172">Red</Label>
    </Labels>
  </LabelSettings>
  <StatusSettings>
    <StatusItems>
      <Status ID="1">To Do</Status>
      <Status ID="2">In Progress</Status>
      <Status ID="3">First Draft</Status>
    </StatusItems>
  </StatusSettings>
  <ProjectProperties>
    <ProjectTitle>My Novel</ProjectTitle>
    <FullName>Author Name</FullName>
  </ProjectProperties>
</ScrivenerProject>
```

### BinderItem Types

| Type | Description |
|------|-------------|
| `DraftFolder` | Manuscript root (compile target) |
| `ResearchFolder` | Research materials container |
| `TrashFolder` | Deleted items |
| `Folder` | User-created folder |
| `Text` | Document (main content unit) |
| `PDF` | Imported PDF |
| `Image` | Imported image |
| `WebArchive` | Saved web page |

### Document Content Storage

Each document's UUID maps to `Files/Data/<UUID>/`:

- **content.rtf**: Body text. Contains inline annotations via `{\Scrv_fn=...}` custom tags.
- **notes.rtf**: Inspector notes pane.
- **synopsis.txt**: Plain text synopsis (corkboard cards).
- **snapshot-YYYY-MM-DD-HH-MM-SS.rtf**: Version snapshots.

### Color Values

Colors in `.scrivx` are space-separated RGB floats (0.0–1.0):

```python
# "0.952941 0.917647 0.329412" → #F3EB54
hex_color = f"#{int(r*255):02x}{int(g*255):02x}{int(b*255):02x}"
```

## DuckDB Export Schema

When exported to DuckDB (via `build_sun_org.py` or similar):

### `documents`
```sql
CREATE TABLE documents (
    project VARCHAR,          -- e.g. '☼'
    uuid VARCHAR PRIMARY KEY,
    title VARCHAR,
    parent_uuid VARCHAR,
    depth_int INT,            -- Nesting depth in binder
    item_type VARCHAR,        -- 'Text', 'Folder', etc.
    label_id INT,
    status_id INT,
    include_in_compile VARCHAR,
    binder_id VARCHAR,        -- Binder sort order
    section_type INT
);
```

### `content`
```sql
CREATE TABLE content (
    project VARCHAR,
    uuid VARCHAR,             -- FK to documents
    body TEXT,                -- Full RTF body
    synopsis TEXT,
    notes TEXT,
    body_length INT,
    content_file_type VARCHAR
);
```

### `labels`, `statuses`, `comments`
```sql
CREATE TABLE labels (project VARCHAR, label_id INT, name VARCHAR, color VARCHAR);
CREATE TABLE statuses (project VARCHAR, status_id INT, name VARCHAR);
CREATE TABLE comments (project VARCHAR, uuid VARCHAR, comment_text TEXT, position INT);
```

Additional tables: `collections`, `bookmarks`, `styles`, `section_types`, `projects`.

## Common Queries

### Manuscript text in binder order
```sql
SELECT d.uuid, d.title, c.body, c.synopsis
FROM documents d
JOIN content c ON d.uuid = c.uuid AND d.project = c.project
WHERE d.project = '☼'
  AND d.item_type = 'Text'
  AND d.include_in_compile = 'Yes'
  AND c.body IS NOT NULL
ORDER BY d.binder_id;
```

### Find documents mentioning a character
```sql
SELECT d.uuid, d.title, d.binder_id, length(c.body) AS bodylen
FROM documents d
JOIN content c ON d.uuid = c.uuid AND d.project = c.project
WHERE d.project = '☼' AND c.body ILIKE '%edith%'
ORDER BY d.binder_id;
```

### Strip Scrivener RTF tags
```python
import re
clean = re.sub(r'\{\\Scrv_fn=.*?\\end_Scrv_fn\}', '', body)
```

## RTF Content Notes

- **Inline annotations**: `{\Scrv_fn=footnote ...text... \end_Scrv_fn}`
- **Comments**: Stored in `comments` table with position offsets
- **Styles**: Referenced by name from `styles.xml`
- **Images**: Embedded as RTF `\pict` objects or referenced externally
- **Links**: Internal links use `scrivener://` protocol with UUID targets

## Character Data Extraction

Scrivener fiction templates include a Characters folder with sketch documents (Role, Occupation, Physical Description, etc.) — but these are **plain RTF**, not structured data. In the ☼ project, the Characters folder contains only a blank template.

Characters must be detected from prose:

```python
import duckdb

con = duckdb.connect('scrivener.duckdb', read_only=True)

def character_chunks(char_name: str) -> list:
    return con.execute("""
        SELECT d.title, left(c.body, 500) as preview, d.binder_id
        FROM documents d
        JOIN content c ON d.uuid = c.uuid AND d.project = c.project
        WHERE d.project = '☼'
          AND c.body ILIKE ?
          AND length(c.body) > 50
        ORDER BY d.binder_id
    """, [f'%{char_name}%']).fetchall()

# ☼ characters: she, narrator, ack, edith, deb, rad, glen, will, hub
```

## macOS vs Windows Differences

| Aspect | macOS | Windows |
|--------|-------|---------|
| `.scriv` appearance | Document package (single file) | Regular folder |
| Browse internals | Right-click → Show Package Contents | Open folder normally |
| UTI | `com.literatureandlatte.scrivener3.scriv` | N/A |
| QuickLook preview | Generated automatically | Not available |
| Spotlight indexing | Via `mdls` metadata | Windows Search indexes RTF |
| Line endings in RTF | LF | CRLF |
| Creator tag | `SCRMAC-3.x.x` | `SCRWIN-3.x.x.x` |

## Verify it worked

After parsing a `.scriv` project:

1. Check that the `.scrivx` XML parses and contains `<Binder>` with at least one `<BinderItem>`
2. Verify UUID directories exist under `Files/Data/` for documents listed in the binder
3. Confirm `content.rtf` files are valid RTF (start with `{\rtf1`)
4. If using DuckDB export: `SELECT count(*) FROM documents` should match binder item count

## What not to do

- Don't modify `.scriv` files while Scrivener has the project open — it uses file locks
- Don't assume synopsis or notes fields are populated — many projects leave them empty
- Don't parse RTF with regex for anything beyond stripping Scrivener tags — use a real RTF parser for styled content
- Don't assume macOS package structure on Windows — `.scriv` is just a folder there
- Don't delete `docs.checksum` — Scrivener uses it for integrity verification on open

## ☼ Project Specifics

- **949 documents**: 900 Text, 42 Folders, 2 PDF, 2 Image
- **432 manuscript chunks** with body > 50 chars
- **Labels**: Idea (#F3EB54), Chapter (#48B300), Scene (#468EFF), Notes (#E48738), Character Notes (#E91A2F)
- **Characters folder**: Only a blank template (unfilled)
- **No synopsis metadata** (1 boilerplate entry on Title Page)
- **2 inline comments**: Both authorial reminders
- **Origin**: Created on Windows Scrivener, migrated through version updates

## References

- [Literature & Latte](https://www.literatureandlatte.com/)
- [Scrivener 3 User Manual (macOS PDF)](https://www.literatureandlatte.com/docs/Scrivener_Manual-Mac.pdf)
- [File format analysis (Obsolete Thor)](https://preservation.tylerthorsted.com/2025/03/21/scrivener/)
- [Archive Team: Scrivener](http://justsolve.archiveteam.org/wiki/Scrivener)
- [Character management blog](https://www.literatureandlatte.com/blog/how-to-manage-your-characters-in-scrivener)

## GF(3) Triads

```
scrivener (-1) + catcolab-schemas (+1) + database-design (0) = 0
scrivener (-1) + build-sun-org (+1) + duckdb-ies (0) = 0
```

Related Skills

jepsen-testing

16
from plurigrid/asi

Jepsen-style correctness testing for distributed systems under faults (partitions, crashes, clock skew) using concurrent operation histories and formal checkers (linearizability/serializability and Elle-style anomalies). Use when designing, implementing, or running Jepsen tests, or interpreting histories/violations.

Deterministic Color Generation via Metadata Hashing

16
from plurigrid/asi

**Status**: ✅ Production Ready

cyton-dongle

16
from plurigrid/asi

Connect and stream from OpenBCI Cyton/Daisy via USB dongle, including first-time radio channel pairing

asi-transient-agenda

16
from plurigrid/asi

Org-agenda-like transient views for ASI skill orchestration via nbb/squint + Emacs hydra

Topological Superintelligence (TSI)

16
from plurigrid/asi

Compositional AI framework using GF(3) triadic balance and category-theoretic foundations.

zx-calculus

16
from plurigrid/asi

Coecke's ZX-calculus for quantum circuit reasoning via string diagrams with Z-spiders (green) and X-spiders (red)

zulip-cogen

16
from plurigrid/asi

Zulip Cogen Skill 🐸⚡

zls-integration

16
from plurigrid/asi

zls-integration skill

zig

16
from plurigrid/asi

zig skill

zig-syrup-bci

16
from plurigrid/asi

Multimodal BCI pipeline in Zig: DSI-24 EEG, fNIRS mBLL, eye tracking IVT, LSL sync, EDF read/write, GF(3) conservation

zig-programming

16
from plurigrid/asi

zig-programming skill

zeroth-bot

16
from plurigrid/asi

Zeroth Bot - 3D-printed open-source humanoid robot platform for sim-to-real and RL research. Affordable entry point for humanoid robotics.