KEEL · YARD v0.10.0

CLI reference

The zero-CLI principle. Nothing on this page is required. Every command here is also reachable from inside the TUI — open the palette with ^p and start the line with : to get the command console, which runs any of these in place and shows the output. This reference exists for scripts, automation, and power use.

One binary, no daemon. Run keel with no arguments inside a series folder and the TUI opens; run it with a subcommand and it does one thing and exits. Every command fails loudly — error messages carry the reason, the object, and usually the cure.

Workspace & revisions

The strict-RCS core: check out, edit plain text, check in. Reads never need a lock; edits always do.

init NAME [--author A]Create a series workspace under the current directory, fully seeded (spine, calendar, frames, ledger). Author defaults to your OS username.
co IDCheck out: take the exclusive lock, pull the head revision into checked-out/ as plain text.
co -lList what you are holding, with lock ages.
ci ID -m MSG [--changeset a-N]Check in: new immutable revision, release the lock. Structured content is validated first; leaves get Plank-formatted. With --changeset, the revision lands pending inside an open amendment.
log IDThe full revision trail — rev, date, author, status, message.
diff ID [A..B]Word-level diff between two revisions; defaults to previous..head.
statusEvery open checkout with holder and age, the spine frontier, stale amendment debt, and unproofread leaves.
$ keel init "The Long Year" --author reza $ cd the-long-year $ keel co s-0001 checked out s-0001 r1 → checked-out\s-0001.md $ keel ci s-0001 -m "the ferryman scene" checked in s-0001 r2 $ keel diff s-0001 # word-level: [-removed-] and +added+ $ keel log s-0001 $ keel status

Spine & structure

Position is encoded in the id — arc-v1.2, mv-v1.2.1, b-v1.2.1.1 — and parents must exist first. Leaves are gated: no leaf outside a specified-or-better beat.

new ID [--title T]Create an arc, movement, or beat (beats arrive as stubs — not writeable until specified). For entities: new e-slug [--name N] [--category character|location|faction|lore]. For leaves: new s-#### --beat b-… — the write gate checks the beat's status.
synopsisThe whole spine stitched into continuous prose — the book before it is written — plus the frontier.
framesChapters over beats with word budgets and real printed-page estimates.
$ keel new arc-v1.2 --title "Salt and Ash" $ keel new mv-v1.2.1 --title "The Crossing" $ keel new b-v1.2.1.1 --title "The River" created b-v1.2.1.1 — "The River" (stub · not writeable until specified) $ keel new s-0002 --beat b-v1.2.1.1 keel: the write gate refuses this: beat b-v1.2.1.1 is Stub… $ keel new e-kael --name Kael --category character $ keel synopsis $ keel frames

Writing & proofreading

proofread LEAFRun the strict AI copy-edit pass and show the corrections as a word diff. Nothing is written.
proofread LEAF --acceptApply the corrections as a new revision and mark it proofread.
proofread LEAF --mark-onlyRecord a human proofread of the current head — no AI. Marks are per-revision; any edit clears them.
plank fmt IDExpand bare @end to @end name in the working file (also happens on every check-in).
plank strip IDPrint the leaf as clean CommonMark — markup collapsed, @cut interiors gone.
plank check IDReport Plank issues; structural markup in prose and unclosed blocks are errors.
$ keel proofread s-0001 s-0001 r2 — corrections ([-…-] +…+): He [-walkked-]+walked+ to the gate. $ keel proofread s-0001 --accept $ keel plank check s-0001 s-0001: clean (4 plank tokens)

The Ledger & amendments

Facts and promises are canon memory; amendments are migrations with a computed blast radius, landed atomically.

fact add --subject S --statement T --scene L [--year Y] [--day D] [--quote Q]Record a fact with provenance; validity defaults to the establishing beat's story time.
fact listEvery fact with subject, source, and reveal position.
promise add --statement T --opened-in B [--due-arc N]Open a promise (setup, question, threat) with a due-by.
promise pay ID --in BMark it discharged by a beat. Paying twice is refused.
promise listPaid and hanging promises, with due arcs.
extract LEAF [--accept all|1,3]Propose facts from @fact/@ref markup (always) and the AI extractor (when keyed). Nothing lands without --accept — human triage is the design.
amend BEAT -m MSGDiff your edited beat card, compute the blast radius, open changeset a-N with the beat as its first member, and print the reconcile tasks.
land CS [--waive REASON]Flip every pending revision canon atomically. Refused while a blocking impact is unreconciled, unless waived with the reason on record. Unreconciled warnings become tracked stale debt.
abandon CSWalk heads back over the retained pending revisions. History is never deleted.
changesetsEvery amendment with status and pending count.
$ keel co b-v1.1.1.1 # edit exits_with in the card… $ keel amend b-v1.1.1.1 -m "the toll is memory" amendment a-1 opened — b-v1.1.1.1 (exits_with) blast radius (2 impacts): ⛔ b-v1.1.1.2 enters_with must be re-satisfied ⚠ s-0001 realizes b-v1.1.1.1 $ keel co b-v1.1.1.2 # reconcile the successor… $ keel ci b-v1.1.1.2 -m "re-satisfy entry" --changeset a-1 $ keel land a-1 a-1 landed — 2 revisions canon $ keel promise add --statement "whose memory did he lose?" --opened-in b-v1.1.1.1 --due-arc 1 $ keel extract s-0001 --accept all

The book & exports

render [--open] [--publish]Typeset the volume to a true B-format PDF via Typst. --open launches your viewer (it reloads on re-render); --publish pushes the PDF to the signed-in Yard, viewable at /preview/<slug>.pdf.
export --tree [--out DIR]The whole series as ordinary files — the portability story, on demand.
export --epub | --docx [--out PATH]E-book and manuscript formats via pandoc.
snapshot [NAME]Pin every object's head under a name; with no name, list snapshots.
statsWords against target, printed pages, weekly pace, and a fourteen-day burn-down.
$ keel render --open --publish rendered .keel\render\book.pdf published — view it at http://localhost:8000/preview/the-long-year.pdf $ keel export --tree $ keel export --epub $ keel snapshot "draft one" $ keel stats

Search & the index

search QUERYFull-text search (FTS5) across every object; rebuilds a missing index automatically.
index --rebuildReconstruct the derived index (search, refs) and the project dictionary from the store alone — byte-identical every time.
geometryThe derived page geometry: trim, text block, ~62 characters × 34 lines, ~300 words per printed page.
$ keel search "poured pewter" s-0001 scene … the river went past them the colour of [poured pewter] … $ keel index --rebuild $ keel geometry

Davy & voice

ai draft LEAF -i ASKDavy from the CLI: assembles the full context recipe, streams the draft to stdout, logs usage. Nothing is written to the store.
ai usageToday's and the month's AI spend from the usage log.
voice seed FILEStore ~1,500 words of your own prose as the voice profile Davy writes toward.
$ keel voice seed my-old-story.txt $ keel ai draft s-0002 -i "He realises the toll was a name. No dialogue." $ keel ai usage today $0.14

Session & meta

login --url U --username N --password PSign in to the Yard and lock the TUI to it. The password flag is the MVP test login only.
logoutSign out; the TUI returns to local dev mode.
changelogPrint the changelog — the same text the TUI overlay and the Yard show.
auto-novel TITLE [--pages N] [--setting S] [--world W] [--characters A,B] [--author A] [--offline]Build a complete sample series from minimal input — every layer populated, deterministic offline, Davy-drafted when keyed. Educational.
$ keel login --url http://localhost:8000 --username admin --password mvp signed in to the Yard at http://localhost:8000 (v0.9.0) as admin $ keel auto-novel "The Salt Ledger" --pages 24 --characters "Kael,Vess,Immy" $ keel changelog $ keel logout

Exit codes are meaningful: 0 success · 1 error · 2 usage · 3 lock conflict · 4 integrity violation (the loud, should-be-impossible one). Scripts can branch on them.