Skip to content

kumulativ Docs smartwriter

smartwriter Say what you want to write and be questioned, directed, read back, or handed a draft — by a model on your own machine.

smartwriter

A creative midwife for writers. Say what you want to write — for the whole piece, for a chapter, for the paragraph in front of you, for one sentence — and be questioned, given directions, read back against your own intent, or handed a draft you can take or leave. By a model running on your own machine: nothing you write, intend or gather leaves the computer, and the app works with the network off.

A Wails desktop app: Go backend, Svelte 5 frontend, and a local Qwen3.5 served by the model runtime every kumulativ app shares (kumulativ-core). It shares its stack and its “Maison” design language with smartreader and smartdiary.


What it does

Write. One measure of serif text on paper. The page is a rich-text editor: bold, italic, underline, strike-through, headings, quotations and list items, set from a small bar that appears over a selection or with the shortcuts everyone already has (Ctrl+B/I/U, Ctrl+Alt+1/2/3 for headings, Ctrl+Alt+0 for a paragraph, Ctrl+Shift+. for a quotation). Pastes arrive as plain text with their paragraphs kept and their fonts left behind. Chapters sit in a list on the left and can be added, reordered and removed. Everything saves on a pause in typing; the bar says saved.

Export. As a Word document, a PDF, or Markdown, from the Export button. The Word file carries real styles — Title, Heading 1 for chapters, Quote, List Paragraph — so Word’s navigation pane and style gallery work on it. The PDF is set in Source Serif 4 with a title page, one chapter per page break and page numbers.

Say what you want. This is the point of the app. There are four levels of intent, and the midwife panel on the right works at whichever one you choose:

Level Where it is set What it is for
Piece The Brief tab, or the panel at Piece level The premise, the reader, the register, what it should leave behind
Chapter The Brief tab, or the panel at Chapter level What this chapter has to do for the piece
Paragraph The panel, with the caret in the paragraph What this paragraph must accomplish
Sentence Select the sentence, then What I want here on the bar What this one sentence must do

A paragraph with an intent carries a small dot in the margin. A sentence with one is underlined faintly. Both are paint rather than markup — the page’s DOM is exactly what you typed — so they never catch the caret.

Ask the midwife. With a level chosen and an intent stated (or not — she will ask for it), five things can be asked:

Ask What comes back
Ask me Probing questions that draw out what you mean, without answering them
Suggest Three or four concrete directions the piece, chapter, paragraph or sentence could take
Read back What is already working, quoted, and exactly where the text parts company with the intent; then the one change that would matter most
Draft A draft in your own voice as it shows on the page — a paragraph, the next paragraph of a chapter, a sentence, or (for the piece) an outline. Insert it after the paragraph, at the end of the chapter, or in place of the sentence; or copy it
Rephrase Other ways to say the sentence or paragraph, each one a click to use

Plus a free question about whatever is in focus. Every conversation is kept against its focus: come back to a paragraph a week later and the panel shows what was asked and said about it, and a follow-up is answered in the light of it. Forget this drops one.

The midwife’s manner — gentle, direct or rigorous — is a setting. What she knows is the same either way: the intents at every level above the focus, the chapter so far (whole when it fits, otherwise the paragraphs around the focus), what the other chapters are and do, and the sources.

Sources. Add PDFs, EPUBs, Word files or plain text to a piece — from the Sources tab, the Sources screen, or by dropping them on the window. Each one is read once, in the background, and summarised section by section and as a whole (the same pass smartreader’s Study this makes, with the same right-of-way rule: a question you ask cuts the summarising short, and it resumes after). When you ask about the piece or a chapter, the midwife is shown every source’s summary; when you ask about a paragraph or a sentence, she is shown the passages of your sources that bear on it, found by lexical retrieval (BM25 over paragraph-sized chunks) from what you wrote there and what you said you wanted. She is told to name the source she draws on and never to invent what one says.


Where things live

<UserConfigDir>/smartwriter/
  data.json                 settings, the pieces, the sources, every conversation
  projects/<id>.json        one piece's chapters and paragraphs
  sources/<id>.json         one source's extracted text
  sources/<id>.study.json   its summaries

<UserConfigDir>/kumulativ/    shared with every kumulativ app — see kumulativ-core
  models/                   the Qwen weights, one copy for every app
  engines/                  the llama.cpp build for this machine
  run/                      the one running server: registry, lock, presets

Environment variables

Variable Effect
SMARTWRITER_CONFIG_DIR Move the whole data directory (portable install, tests)
SMARTWRITER_GGUF Use this .gguf and download nothing
KUMULATIV_HOME Move the shared model store
KUMULATIV_BIN_DIR Look for llama-server here first
KUMULATIV_IDLE_UNLOAD_MIN Minutes of quiet before the model is put to sleep (default 1; 0 = never)
KUMULATIV_LLAMA_ASSET / KUMULATIV_LLAMA_RELEASE Pin a specific llama.cpp release asset
KUMULATIV_LLAMA_EXTRA_ARGS Extra flags for the llama-server command line
KUMULATIV_FORCE_CPU Never use the CUDA build
KUMULATIV_NO_ENGINE_FETCH Refuse to download an engine
KUMULATIV_DEBUG Forward the server’s output instead of swallowing it

How it is put together

The page is the DOM

The editor is one contenteditable element whose children are the chapter’s paragraphs, each carrying its id in data-block. The browser does the editing; after every input editor.ts reads the DOM back into Para records, reducing the markup to five inline tags (strong, em, u, s, br) and carrying each paragraph’s intent and sentence marks across by id. A paragraph the browser clones (Enter in the middle of one copies its attributes) keeps its id on the first half and gets a fresh one on the second, so an intent stays with the words it was written about.

The Go side makes the same reduction again on save (richtext.go), derives the plain text from the reduced markup, and re-finds each sentence mark in the new text by its words. Offsets are UTF-16 units, because JavaScript is the one counting.

Marked and focused sentences are drawn with the CSS Custom Highlight API — ranges the browser paints over, not elements — so the DOM stays exactly what was typed and the offset invariant (text nodes in order, one \n per <br>, concatenate to the paragraph’s text) never depends on a wrapper staying put.

The prompt

prompts.go builds every message. One system message carries the midwife’s standing instructions and the whole context from the general to the particular: the piece and its intent, an outline of the other chapters, the chapter in focus and its intent and text, the paragraph and its intent, the sentence and its intent, the sources. Then the conversation about this focus so far as user/assistant pairs, then one imperative for the mode and level. Context goes in the system message on purpose: the history clamp trims from the oldest non-system message, and the text must be the last thing to go.

Retrieval

sources.go cuts each source into chunks of about nine hundred characters on paragraph boundaries and scores them with BM25 against a query made of the question, the intents and the text in focus. A chunk has to meet the query on at least two terms to count. It is lexical on purpose: exact, instant, no second model beside the one that writes, and explainable when it misses.


Known limits

  • The midwife drafts in the voice of what is on the page. An empty chapter with a one-line intent gets a generic opening; the more you have written and said, the better she reads you.
  • Retrieval is by words. A source that says the same thing in different words is not found for a paragraph; its summary still reaches the midwife at piece and chapter level.
  • Scanned PDFs need OCR first, and PDFs with broken font maps are refused, as in smartreader.
  • The PDF export does not justify and does not hyphenate; the Word export leaves that to Word.