grimoire a terminal writing desk for novels github
what it is

what it is

Grimoire is a writing desk for novels that lives in your terminal. It knows what a manuscript is — parts, chapters, scenes, word targets — and it keeps all of it as plain files you could read with cat.

┌ MANUSCRIPT ────────────┐┌ Chapter One / Gravel ─────────────────────────┐
▾ Part One        2,120 ││                                               
  ▾ Chapter One   2,120 ││  The caretaker was waiting by her car when    
    • The Archive 1,240 ││  she came back out, which meant he had been   
    ● Gravel        880 ││  watching the door the whole time she was     
  ▸ Chapter Two       0 ││  inside.                                      
── NOTES ───────────────││                                               
▾ Characters         64 ││  "You'll want to come back in daylight,"      
  • Wren             64 ││  he said.                                     
                        ││                                               
                        ││  It was daylight.                             
└────────────────────────┘└───────────────────────────────────────────────┘
 2,120 / 80,000 ░░░░░░░░░  today 412            Tab pane  ^S save  ^Q quit

Rust and Ratatui. One binary, 2.5 MB. macOS and Linux.

why

Every open-source novel tool makes one of two mistakes. It traps your manuscript in a database, or it is a text editor with no idea what a manuscript is.

Grimoire does neither. The directory tree is the outline. There is no index file, so there is no central thing to conflict when you sync across machines. Reordering is renaming. Backing up is copying a folder.

If this project is abandoned tomorrow you still have your book. That is the whole design constraint, and everything else follows from it.

Frontmatter is round-tripped verbatim — Grimoire reads a few keys and never rewrites the block, so Obsidian can own fields it has never heard of.

on disk

Folders are containers, at any depth. Files are scenes. Order comes from the name.

the-archive/
├─ novel.toml                    title, author, word targets
├─ manuscript/
│  └─ 01-part-one/
│     ├─ 01-chapter-one/
│     │  ├─ 01-the-archive.md         a scene
│     │  └─ 02-gravel.md
│     └─ 02-chapter-two/
├─ notes/
│  └─ characters/wren.md
└─ .grimoire/                    session state, gitignored

A leading 01- orders the file and is stripped for display.

---
title: Gravel
pov: Wren
status: draft
synopsis: Confronts the caretaker in the lot.
target: 1200
---

keys

Tabswitch pane
↑ ↓ · j kmove in tree
→ · l · ↵expand container, or open scene
← · hcollapse, or jump to parent
Ctrl-Ssave all changed scenes
Ctrl-Qquit — twice if unsaved
F2 · F3start or pause the timer · reset
F4 F5 F6previous · play-pause · next

Vertical movement in the editor is visual, not logical. Down moves one screen row inside a wrapped paragraph rather than jumping the whole paragraph, which is the only behaviour that feels right for prose.

Function keys work from either pane, so they can never eat a keystroke mid-sentence.

the clearing

Below the manuscript tree is a forest, and the forest is the timer.

┌ focus · 18:04 ─────────────┐
  ·                         
                 ·         
    ▲      ▲       ▲        
   ▲▲▲    ▲▲▲     ▲▲▲    ▲  
  ▲▲▲▲▲  ▲▲▲▲▲   ▲▲▲▲▲  ▲▲▲ 
    ┃      ┃       ┃     ┃  
   (\_/)            (\_/)   
   (•ᴥ•)    ❀  ✿    (•ᴥ•)   
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
└────────────────────────────┘

The sun's position is the clock. It crosses the sky over a twenty-five minute session, so you read the time remaining off the light instead of watching a number count down.

Break time is night: the moon rises, the flowers close, and fireflies come out between the rabbits.

The rabbits flick their ears on mutually-prime cycles, so the two of them never move in lockstep.

music

There is no official YouTube Music API, and anything that extracts stream URLs both violates the terms and side-steps the subscription you already pay for. So Grimoire never plays audio.

It drives YTMDesktop's Companion Server instead, which is already signed into your real account. Your playlists, your Premium, your playback — Grimoire just presses the buttons.

┌ ♪ ─────────────────────────┐
▶ Weightless                
━━─────────────────── 0:50  
└────────────────────────────┘

With no token configured the pane stays inert and never touches the network.

install

Requires Rust 1.85 or newer.

git clone https://github.com/kelsierbot/GrimoireTUI cd GrimoireTUI && cargo install --path . grimoire example

The crate is grimoire-tui; the binary it installs is grimoire. A crates.io release is coming.

For music, optionally:

brew install --cask ytmdesktop-youtube-music enable Settings → Integrations → Companion Server grimoire music-auth

status

v0.1. It opens a manuscript, shows you the shape of it, tracks your words, and lets you write. That is the whole thing so far.

Not yet:

  • command palette
  • corkboard view — pov and status are already parsed and waiting
  • git sync
  • scene reordering, and creating files from inside the app
  • search, spellcheck

MIT. Issues and patches welcome at the repo.