# Scrivener Metadata

> When the user wants to set or inspect a Scrivener project's labels, statuses, section types, keywords, or custom metadata — "set the status to Done", "label these red", "make these section type Part", "what labels/statuses exist", "tag with keyword" (planned), or "add custom metadata" (planned). Use when the user says "set the status to", "label these", "what labels are there", "change the label", "set section type", or "what section types exist". For editing text/structure (add/move/split), see scrivener-edit; for direct fonts/color/highlight, see scrivener-formatting; for how section types map to compile layouts, see scrivener-compile.

- Skill: `donnfelker/scrivener-metadata` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add donnfelker/scrivener-metadata`
- Raw SKILL.md: https://api.skillmd.com/api/skills/donnfelker/scrivener-metadata/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: donnfelker (https://skillmd.com/u/donnfelker)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/donnfelker/scrivener-metadata

---


# Scrivener metadata: labels, statuses, section types

You help the writer **read and assign** the organizational metadata that lives on
binder items — **labels**, **statuses**, and **section types** — and you explain the
**keywords** and **custom-metadata** workflows that are on the roadmap but not yet in
the CLI. This skill is about *classification*, not text: it never rewrites
`content.rtf`. For body/synopsis/notes edits use `scrivener-edit`.

Two distinct jobs run through here:

1. **Definitions** — the project's *palette* of labels, statuses, and section types
   (their names, colors, and IDs). These are listed read-only.
2. **Assignment** — putting one of those definitions onto a specific item (writes
   `LabelID` / `StatusID` in the item's `<MetaData>`).

## Before any write (safety)

- **Close the project in Scrivener** and let **cloud sync (Dropbox/iCloud) finish**
  first — editing a `.scriv` mid-sync can corrupt or conflict even with Scrivener shut.
- Writes **auto-backup** (a timestamped zip) and **auto-snapshot** the document before
  changes; `set-label`/`set-status` accept `--no-backup`, `--no-snapshot`, `--dry-run`.
- **Titles are not unique** — pass a **UUID** for any write when a title is ambiguous.
  Resolve the UUID first with `find` or `outline` (see `scrivener-inspect`).

## Listing the palette (read-only)

Always read the definitions first so you assign a **valid ID**, not a guessed one:

```bash
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py labels        --project "<path.scriv>"
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py statuses      --project "<path.scriv>"
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py section-types --project "<path.scriv>"
```

- `labels` / `statuses` return each definition's ID, title, and color.
- `section-types` returns the type definitions **and** the `LevelTypes` structure
  defaults (which structural level maps to which type — see below).

When the user asks **"what labels/statuses exist"** or **"what section types are
there"**, run the matching list command and report the titles with their IDs.

## Assigning a label or status (write, validated)

`set-label` and `set-status` take the **item id** and a **definition id**, and the
toolkit **validates the id against the project's definitions** before writing — an
unknown id is refused, so map the user's words ("Done", "red", "First draft") to the
real ID from the list commands first.

```bash
# 1) find the item's UUID and the target ID, then:
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py set-status <uuid> <status_id> --project "<path.scriv>"
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py set-label  <uuid> <label_id>  --project "<path.scriv>"
```

- For "**label these**" / "**set the status to** X" across several items, resolve each
  UUID and run the command per item. Use `--dry-run` first to preview on bulk edits.
- These write only `LabelID` / `StatusID` in `<MetaData>`; no content is touched.

## Section types — three assignment states

A section type is **not** stored as a plain field on most items. It is resolved through
three states (Project Settings ▸ Section Types):

1. **Structure-based (inherited)** — the **default**, by an item's structural role/level.
   Defined in the `.scrivx` under `<SectionTypes>`: `<TypeDefinitions>` names each type
   ID, and `<LevelTypes>` (`<Folders>` / `<Containers>` / `<Files>`) maps each level to a
   type ID. `section-types` reports both. **Most items have no explicit section type —
   they inherit one from this structure map.**
2. **Default-subdocument-inherited** — from a container's default-subdocument setting.
3. **Manual per-item override** — set directly on the item.

So "**make these section type Part**" is usually *not* a per-item flag write today: the
right answer is often to change the **structure default** (the `LevelTypes` mapping) or
restructure so the item sits at the level whose default is "Part". A true per-item
override is **planned** — its exact `<MetaData>` element is unverified, so the toolkit
does not yet write it (see Toolkit support). When asked, list the current section types
and explain which state would deliver the result.

Why section types matter: at compile, the chosen **Format** binds each **section type →
section layout**, which controls titles, prefixes, numbering, separators, and page
breaks. That binding — not a per-item checkbox — is what gives "Part" its look. See
`scrivener-compile`. (In Scrivener 3 the old per-item "Page Break Before" and "Compile
As-Is" checkboxes were removed; both are now functions of the section-type→layout bind.)

## Custom metadata — exactly four types (no Number)

Custom metadata fields have **exactly four types: Text, Checkbox, List, Date.** There is
**no Number type** — if a user asks for a numeric field, store it as **Text**. Field
*definitions* (List items + "None" title, Date format, Text wrap/color, Checkbox
default) live in project settings; per-item *values* live in the item's `<MetaData>`.
Defining and setting custom metadata is **planned**, not yet in the CLI.

## Keywords (planned)

Keywords are case-sensitive, nestable tags applied to items (distinct from labels — an
item gets one label but many keywords). "**Tag with keyword**" / "add a keyword" is
**planned**; there is no `keywords` command yet. For now, a single classification can be
expressed with a **label** (`set-label`), or text can be made findable via
`scrivener-search`.

## Toolkit support

✅ Available now:
- `labels` — list label definitions (id, title, color)
- `statuses` — list status definitions (id, title, color)
- `section-types` — list type definitions **and** `LevelTypes` structure defaults
- `set-label <id> <label_id>` — write `LabelID` (validated against definitions)
- `set-status <id> <status_id>` — write `StatusID` (validated against definitions)

🔜 Planned (describe the workflow; suggest the closest available command):
- `keywords add|remove|list` — keyword tagging
- `meta define|set|get` — custom metadata (Text / Checkbox / List / Date — **no Number**)
- `section-type create|assign` — create types and set a **per-item override**
  (the override's `<MetaData>` element is unverified and not yet written)
- `collection list|create|add|remove` — saved/Arbitrary collections
- `bookmark` / `references` / `link` — bookmarks, references, internal links
- `autocomplete list|add|remove` — project autocomplete list

For listing the metadata palette closest to a planned need, fall back to `labels` /
`statuses` / `section-types`; for finding items to classify, use `scrivener-search`.

## Related skills

- **scrivener-inspect** — `outline` / `find` / `read` to get an item's UUID and see its
  current label/status/section type before you assign.
- **scrivener-edit** — add/move/rename/split items; restructuring is how you change a
  structure-based section type today.
- **scrivener-compile** — how the chosen Format binds **section type → section layout**
  (titles, numbering, separators, page breaks).
- **scrivener-formatting** — direct fonts/color/highlight on text (not classification).
- **scrivener-format** — the `.scrivx` schema: where `LabelID`/`StatusID`,
  `<SectionTypes>`/`<LevelTypes>`, and custom metadata serialize.

Definitions vs assignment, how the IDs are written, the section-type model, and the
planned keywords/custom-metadata/collections detail:
**[references/labels-status-section-types.md](references/labels-status-section-types.md)**.

