Vibecode Novelcrafter
track this build4 phases, 12 steps, beginner friendly0%The core loop is buildable, but a dependable replacement becomes a real weekend or multi-day project. For Novelcrafter, organize a novel bible, scenes, characters, and optional bring-your-own-model drafting. The hard boundary is its mature manuscript workflow, codex structure, and community templates, plus polish, integrations, and proprietary language models.
You are building a lean indie version of Novelcrafter. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # Novelcrafter · indie build A novel-writing environment whose real problem is continuity across a hundred thousand words: a character's eye colour established in chapter three, a timeline that has to hold, and an assistant that must be given the relevant facts rather than allowed to invent them. Estimated effort: **multi-day**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | TypeScript with a local application and SQLite | an unfinished manuscript is the most private thing a writer has | | Bible | Entities with typed attributes, each citing where it was established | a fact without its source cannot be checked when the text changes | | Retrieval | Relevant bible entries and prior scenes selected per request | context is finite and a hundred thousand words does not fit | | Continuity | Checks comparing the manuscript against the bible | the bible is only useful if divergence is detected | | Models | Local by default, hosted as an explicit per-project choice | sending an unpublished manuscript anywhere should be a decision | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **Node.js 22 or newer** · free - Why: Runs the local application. - Get it: nodejs.org, or nvm install 22. - Verify: node --version prints v22 or higher - [ ] **A local model runner** · free, needs memory - Why: An unpublished manuscript is the most private thing a novelist has, and the default should not be sending it to a service. - Get it: Any local runner with a model that handles long context and follows structured instructions. - Verify: A generation completes locally using supplied context - [ ] **A real manuscript of at least sixty thousand words** · free - Why: Editor performance, fact extraction and continuity checking all behave completely differently at novel length, and a short test project demonstrates none of the problems. - Get it: Your own draft, or a public domain novel imported as scenes and chapters. - Verify: Sixty thousand words are loaded as scenes with chapter structure - [ ] **Twenty known facts with a deliberate contradiction** · free - Why: Continuity checking cannot be evaluated without knowing the right answer, and the interesting cases are the deliberate deviations fiction is full of. - Get it: From your manuscript, list twenty established facts and introduce one genuine contradiction and one intentional deviation. - Verify: Both the contradiction and the intentional deviation are identified by hand first ## Quick start Follow Phase 1 in `BUILD_PLAN.md`; it creates the project. Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Prose quality. - Publishing and print formatting. - Collaborative writing. - Plot generation. - its mature manuscript workflow, codex structure, and community templates - cross-device sync - large proprietary style models - browser and office-suite extensions - team style guides If one of those is essential to you, that is the reason to keep paying for Novelcrafter, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · Novelcrafter The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a long-form fiction workspace where the story bible actually constrains the writing to replace Novelcrafter. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - Runtime: TypeScript with a local application and SQLite · an unfinished manuscript is the most private thing a writer has - Bible: Entities with typed attributes, each citing where it was established · a fact without its source cannot be checked when the text changes - Retrieval: Relevant bible entries and prior scenes selected per request · context is finite and a hundred thousand words does not fit - Continuity: Checks comparing the manuscript against the bible · the bible is only useful if divergence is detected - Models: Local by default, hosted as an explicit per-project choice · sending an unpublished manuscript anywhere should be a decision ### Data model (create this before Phase 1) - projects(id, title, model_policy, created_at) - chapters(id, project_id, ordinal, title) and scenes(id, chapter_id, ordinal, body, word_count, updated_at) - entities(id, project_id, kind, name, aliases_json) · kind is character, place, object or faction - facts(id, entity_id, attribute, value, established_in_scene_id, confidence, superseded_by) - timeline(id, project_id, scene_id, story_time, duration, ordering_note) · story order is not manuscript order - continuity_flags(id, scene_id, fact_id, kind, detail, resolved_at) · kind is contradiction, unestablished or anachronism - generations(id, scene_id, prompt, context_fact_ids_json, output, accepted) · what the assistant was told, kept - A fact records the scene that established it, so when that scene is rewritten the fact is flagged rather than silently orphaned. ### Phase 1 · A manuscript that survives a hundred thousand words Build: Scenes within chapters, reorderable, with autosave and version snapshots per session. Full text search across the manuscript. Verify performance at a hundred thousand words rather than at ten thousand. Trap: Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. Done when: A hundred thousand word project loads, edits and searches without perceptible delay. An hour of writing survives a hard kill. Reordering scenes and chapters does not rewrite unrelated content. Session snapshots accumulate per writing session rather than per keystroke. Do not build yet: No bible, retrieval or continuity. ### Phase 2 · A bible whose facts point at the text Build: Entities with typed attributes, each fact recording the scene it came from. Extract candidate facts from the manuscript for confirmation rather than asking the writer to enter everything. Handle a fact that is later superseded in the story. Trap: A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. Done when: Facts record the scene that established them. Candidate facts are extracted from the manuscript for confirmation rather than requiring manual entry. A fact superseded later in the story is recorded as superseded rather than contradicting. Rewriting the establishing scene flags the fact for review. Do not build yet: No retrieval or continuity checks yet. ### Phase 3 · Telling the assistant what it needs to know Build: Select the bible entries and prior scenes relevant to the scene being written, within a context budget. Record exactly which facts were sent. Show the writer the context before it is used. Trap: Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. Done when: Context selection prioritises entities present in the scene over general project facts, verified against a scene with a minor character. The writer can see the selected context before generation. Every generation records which facts it was given. Context stays within the budget without silently dropping the most relevant items. Do not build yet: No continuity checking or model policy yet. ### Phase 4 · Catching contradictions before a reader does Build: Check scenes against established facts, flagging contradictions and details asserted without having been established. Check story-time ordering for impossibilities. Let a flag be dismissed as intentional and stay dismissed. Trap: Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. Done when: A contradiction against an established fact is flagged with both locations. A detail asserted without having been established is flagged distinctly from a contradiction. A dismissed flag stays dismissed across re-checks. A story-time impossibility, such as a character in two places, is detected. Do not build yet: No model policy or export yet. ### Phase 5 · Where the manuscript goes, and getting it out Build: Model policy per project enforced at the call site. Export to standard manuscript formats with chapters intact. Verify the export is exactly the written text with no generated content marked otherwise. Trap: A global model setting means one careless change sends an unpublished manuscript to a service, and for a novelist that is a genuinely serious event. Put the policy on the project and enforce it where the request is made, so a local-only project raises rather than sends. Done when: A local-only project cannot send text anywhere, verified by attempting it and observing a raised error rather than a request. Export produces standard manuscript format with chapters and scene breaks intact. Exported text matches the stored manuscript exactly. Which passages came from a generation is recorded and can be listed. Do not build yet: Nothing after this. ### Out of scope (and why) - Prose quality. The assistant supplies continuity and context; whether the writing is good is not something this measures or improves. - Publishing, formatting for print and distribution, which is a separate craft and a separate toolchain. - Collaborative writing with several authors, which is a different synchronisation and permissions problem. - Plot generation, which produces the kind of structure that reads as generated and is not what the bible is for. ### README must contain - That the bible is derived from the manuscript rather than maintained beside it - That every fact records the scene that established it, so rewriting that scene flags the fact - That generation context is selected by scene relevance and shown before use - That a continuity flag can be dismissed as intentional and stays dismissed - That the model policy is per project and enforced at the call site ===== AGENTS.md ===== # Agent instructions · Novelcrafter indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: TypeScript with a local application and SQLite, Entities with typed attributes, each citing where it was established, Relevant bible entries and prior scenes selected per request, Checks comparing the manuscript against the bible, Local by default, hosted as an explicit per-project choice. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. ===== BUILD_PLAN.md ===== # Build plan · Novelcrafter A novel-writing environment whose real problem is continuity across a hundred thousand words: a character's eye colour established in chapter three, a timeline that has to hold, and an assistant that must be given the relevant facts rather than allowed to invent them. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · A manuscript that survives a hundred thousand words Writing, reordering and searching stay fast at novel length. ### Steps 1. Load and save per scene Whole-manuscript loading fails exactly when the stakes are highest. Files: `src/scenes.ts` 2. Test at realistic length Generate a hundred thousand word fixture. Ten thousand proves nothing. Files: `tests/scale.test.ts` 3. Snapshot per session Per keystroke fills the history and makes it useless. Files: `src/versions.ts` ### Done when - [ ] A hundred thousand words loads and searches quickly - [ ] An hour of writing survives a hard kill - [ ] Reordering does not rewrite unrelated content - [ ] Snapshots accumulate per session ### Watch out - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. ## Phase 2 · A bible whose facts point at the text Every established fact knows which scene established it. ### Steps 1. Record the establishing scene per fact A fact with no source cannot be rechecked when the text changes. Files: `src/facts.ts` 2. Extract candidates for confirmation A hand-maintained bible diverges within a week. Files: `src/extract.ts` 3. Support supersession Characters change. A later fact is not always a contradiction. Files: `src/facts.ts` ### Done when - [ ] Facts record their establishing scene - [ ] Candidates are extracted for confirmation - [ ] Supersession is distinct from contradiction - [ ] Rewriting a source scene flags its facts ### Watch out - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. ## Phase 3 · Telling the assistant what it needs to know A generation request carries the relevant facts and nothing irrelevant. ### Steps 1. Select by scene relevance Entities in this scene first, then timeline neighbours. Files: `src/retrieve.ts`, `src/retrieve.test.ts` 2. Show the context before use A bad selection should be visible rather than mysterious. Files: `src/context-view.ts` 3. Record what was sent So a wrong output can be traced to a missing fact. Files: `src/generations.ts` ### Done when - [ ] Selection prioritises entities present in the scene - [ ] Context is visible before generation - [ ] Every generation records its facts - [ ] The budget does not drop the most relevant items ### Watch out - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. ## Phase 4 · Catching contradictions before a reader does The manuscript is checked against the bible and against itself. ### Steps 1. Flag contradictions with both locations The writer needs to see the two passages together. Files: `src/continuity.ts` 2. Distinguish unestablished from contradictory One is a possible mistake, the other is possibly just new. Files: `src/continuity.ts` 3. Make dismissals permanent Fiction is full of intentional deviations. Re-flagging them ends the feature. Files: `src/flags.ts` ### Done when - [ ] Contradictions are flagged with both locations - [ ] Unestablished details are flagged distinctly - [ ] Dismissed flags stay dismissed - [ ] Story-time impossibilities are detected ### Watch out - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. ## Not in this build - Prose quality. - Publishing and print formatting. - Collaborative writing. - Plot generation. ## After v1, if you want it - A timeline view, which is where continuity problems become obvious - Per-character voice notes fed into context, once retrieval is trustworthy - Revision tracking across drafts, which is the other half of a long project ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. The manuscript and the bible. Back this up above everything else. DB_PATH=~/.local/share/novel/project.db # Required. What a new project gets. Local, so sending a manuscript is a decision. DEFAULT_MODEL_POLICY=local # Required. How much context a generation may carry. Selection matters more than size. CONTEXT_BUDGET_TOKENS=8000 # Required. The gap that ends a writing session and snapshots a version. SESSION_GAP_MINUTES=30 # Required. The format editors expect. Chapters and scene breaks preserved. EXPORT_FORMAT=docx # Optional · secret. Only for projects explicitly set to a hosted model. Absent means local only. HOSTED_API_KEY=sk-...
You are building a lean indie version of Novelcrafter. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # Novelcrafter · indie build A novel-writing environment whose real problem is continuity across a hundred thousand words: a character's eye colour established in chapter three, a timeline that has to hold, and an assistant that must be given the relevant facts rather than allowed to invent them. Estimated effort: **multi-day**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | TypeScript with a local application and SQLite | an unfinished manuscript is the most private thing a writer has | | Bible | Entities with typed attributes, each citing where it was established | a fact without its source cannot be checked when the text changes | | Retrieval | Relevant bible entries and prior scenes selected per request | context is finite and a hundred thousand words does not fit | | Continuity | Checks comparing the manuscript against the bible | the bible is only useful if divergence is detected | | Models | Local by default, hosted as an explicit per-project choice | sending an unpublished manuscript anywhere should be a decision | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **Node.js 22 or newer** · free - Why: Runs the local application. - Get it: nodejs.org, or nvm install 22. - Verify: node --version prints v22 or higher - [ ] **A local model runner** · free, needs memory - Why: An unpublished manuscript is the most private thing a novelist has, and the default should not be sending it to a service. - Get it: Any local runner with a model that handles long context and follows structured instructions. - Verify: A generation completes locally using supplied context - [ ] **A real manuscript of at least sixty thousand words** · free - Why: Editor performance, fact extraction and continuity checking all behave completely differently at novel length, and a short test project demonstrates none of the problems. - Get it: Your own draft, or a public domain novel imported as scenes and chapters. - Verify: Sixty thousand words are loaded as scenes with chapter structure - [ ] **Twenty known facts with a deliberate contradiction** · free - Why: Continuity checking cannot be evaluated without knowing the right answer, and the interesting cases are the deliberate deviations fiction is full of. - Get it: From your manuscript, list twenty established facts and introduce one genuine contradiction and one intentional deviation. - Verify: Both the contradiction and the intentional deviation are identified by hand first ## Quick start Follow Phase 1 in `BUILD_PLAN.md`; it creates the project. Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Prose quality. - Publishing and print formatting. - Collaborative writing. - Plot generation. - its mature manuscript workflow, codex structure, and community templates - cross-device sync - large proprietary style models - browser and office-suite extensions - team style guides If one of those is essential to you, that is the reason to keep paying for Novelcrafter, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · Novelcrafter The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a long-form fiction workspace where the story bible actually constrains the writing to replace Novelcrafter. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - Runtime: TypeScript with a local application and SQLite · an unfinished manuscript is the most private thing a writer has - Bible: Entities with typed attributes, each citing where it was established · a fact without its source cannot be checked when the text changes - Retrieval: Relevant bible entries and prior scenes selected per request · context is finite and a hundred thousand words does not fit - Continuity: Checks comparing the manuscript against the bible · the bible is only useful if divergence is detected - Models: Local by default, hosted as an explicit per-project choice · sending an unpublished manuscript anywhere should be a decision ### Data model (create this before Phase 1) - projects(id, title, model_policy, created_at) - chapters(id, project_id, ordinal, title) and scenes(id, chapter_id, ordinal, body, word_count, updated_at) - entities(id, project_id, kind, name, aliases_json) · kind is character, place, object or faction - facts(id, entity_id, attribute, value, established_in_scene_id, confidence, superseded_by) - timeline(id, project_id, scene_id, story_time, duration, ordering_note) · story order is not manuscript order - continuity_flags(id, scene_id, fact_id, kind, detail, resolved_at) · kind is contradiction, unestablished or anachronism - generations(id, scene_id, prompt, context_fact_ids_json, output, accepted) · what the assistant was told, kept - A fact records the scene that established it, so when that scene is rewritten the fact is flagged rather than silently orphaned. ### Phase 1 · A manuscript that survives a hundred thousand words Build: Scenes within chapters, reorderable, with autosave and version snapshots per session. Full text search across the manuscript. Verify performance at a hundred thousand words rather than at ten thousand. Trap: Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. Done when: A hundred thousand word project loads, edits and searches without perceptible delay. An hour of writing survives a hard kill. Reordering scenes and chapters does not rewrite unrelated content. Session snapshots accumulate per writing session rather than per keystroke. Do not build yet: No bible, retrieval or continuity. ### Phase 2 · A bible whose facts point at the text Build: Entities with typed attributes, each fact recording the scene it came from. Extract candidate facts from the manuscript for confirmation rather than asking the writer to enter everything. Handle a fact that is later superseded in the story. Trap: A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. Done when: Facts record the scene that established them. Candidate facts are extracted from the manuscript for confirmation rather than requiring manual entry. A fact superseded later in the story is recorded as superseded rather than contradicting. Rewriting the establishing scene flags the fact for review. Do not build yet: No retrieval or continuity checks yet. ### Phase 3 · Telling the assistant what it needs to know Build: Select the bible entries and prior scenes relevant to the scene being written, within a context budget. Record exactly which facts were sent. Show the writer the context before it is used. Trap: Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. Done when: Context selection prioritises entities present in the scene over general project facts, verified against a scene with a minor character. The writer can see the selected context before generation. Every generation records which facts it was given. Context stays within the budget without silently dropping the most relevant items. Do not build yet: No continuity checking or model policy yet. ### Phase 4 · Catching contradictions before a reader does Build: Check scenes against established facts, flagging contradictions and details asserted without having been established. Check story-time ordering for impossibilities. Let a flag be dismissed as intentional and stay dismissed. Trap: Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. Done when: A contradiction against an established fact is flagged with both locations. A detail asserted without having been established is flagged distinctly from a contradiction. A dismissed flag stays dismissed across re-checks. A story-time impossibility, such as a character in two places, is detected. Do not build yet: No model policy or export yet. ### Phase 5 · Where the manuscript goes, and getting it out Build: Model policy per project enforced at the call site. Export to standard manuscript formats with chapters intact. Verify the export is exactly the written text with no generated content marked otherwise. Trap: A global model setting means one careless change sends an unpublished manuscript to a service, and for a novelist that is a genuinely serious event. Put the policy on the project and enforce it where the request is made, so a local-only project raises rather than sends. Done when: A local-only project cannot send text anywhere, verified by attempting it and observing a raised error rather than a request. Export produces standard manuscript format with chapters and scene breaks intact. Exported text matches the stored manuscript exactly. Which passages came from a generation is recorded and can be listed. Do not build yet: Nothing after this. ### Out of scope (and why) - Prose quality. The assistant supplies continuity and context; whether the writing is good is not something this measures or improves. - Publishing, formatting for print and distribution, which is a separate craft and a separate toolchain. - Collaborative writing with several authors, which is a different synchronisation and permissions problem. - Plot generation, which produces the kind of structure that reads as generated and is not what the bible is for. ### README must contain - That the bible is derived from the manuscript rather than maintained beside it - That every fact records the scene that established it, so rewriting that scene flags the fact - That generation context is selected by scene relevance and shown before use - That a continuity flag can be dismissed as intentional and stays dismissed - That the model policy is per project and enforced at the call site ===== AGENTS.md ===== # Agent instructions · Novelcrafter indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: TypeScript with a local application and SQLite, Entities with typed attributes, each citing where it was established, Relevant bible entries and prior scenes selected per request, Checks comparing the manuscript against the bible, Local by default, hosted as an explicit per-project choice. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. ===== BUILD_PLAN.md ===== # Build plan · Novelcrafter A novel-writing environment whose real problem is continuity across a hundred thousand words: a character's eye colour established in chapter three, a timeline that has to hold, and an assistant that must be given the relevant facts rather than allowed to invent them. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · A manuscript that survives a hundred thousand words Writing, reordering and searching stay fast at novel length. ### Steps 1. Load and save per scene Whole-manuscript loading fails exactly when the stakes are highest. Files: `src/scenes.ts` 2. Test at realistic length Generate a hundred thousand word fixture. Ten thousand proves nothing. Files: `tests/scale.test.ts` 3. Snapshot per session Per keystroke fills the history and makes it useless. Files: `src/versions.ts` ### Done when - [ ] A hundred thousand words loads and searches quickly - [ ] An hour of writing survives a hard kill - [ ] Reordering does not rewrite unrelated content - [ ] Snapshots accumulate per session ### Watch out - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. ## Phase 2 · A bible whose facts point at the text Every established fact knows which scene established it. ### Steps 1. Record the establishing scene per fact A fact with no source cannot be rechecked when the text changes. Files: `src/facts.ts` 2. Extract candidates for confirmation A hand-maintained bible diverges within a week. Files: `src/extract.ts` 3. Support supersession Characters change. A later fact is not always a contradiction. Files: `src/facts.ts` ### Done when - [ ] Facts record their establishing scene - [ ] Candidates are extracted for confirmation - [ ] Supersession is distinct from contradiction - [ ] Rewriting a source scene flags its facts ### Watch out - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. ## Phase 3 · Telling the assistant what it needs to know A generation request carries the relevant facts and nothing irrelevant. ### Steps 1. Select by scene relevance Entities in this scene first, then timeline neighbours. Files: `src/retrieve.ts`, `src/retrieve.test.ts` 2. Show the context before use A bad selection should be visible rather than mysterious. Files: `src/context-view.ts` 3. Record what was sent So a wrong output can be traced to a missing fact. Files: `src/generations.ts` ### Done when - [ ] Selection prioritises entities present in the scene - [ ] Context is visible before generation - [ ] Every generation records its facts - [ ] The budget does not drop the most relevant items ### Watch out - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. ## Phase 4 · Catching contradictions before a reader does The manuscript is checked against the bible and against itself. ### Steps 1. Flag contradictions with both locations The writer needs to see the two passages together. Files: `src/continuity.ts` 2. Distinguish unestablished from contradictory One is a possible mistake, the other is possibly just new. Files: `src/continuity.ts` 3. Make dismissals permanent Fiction is full of intentional deviations. Re-flagging them ends the feature. Files: `src/flags.ts` ### Done when - [ ] Contradictions are flagged with both locations - [ ] Unestablished details are flagged distinctly - [ ] Dismissed flags stay dismissed - [ ] Story-time impossibilities are detected ### Watch out - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. ## Not in this build - Prose quality. - Publishing and print formatting. - Collaborative writing. - Plot generation. ## After v1, if you want it - A timeline view, which is where continuity problems become obvious - Per-character voice notes fed into context, once retrieval is trustworthy - Revision tracking across drafts, which is the other half of a long project ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. The manuscript and the bible. Back this up above everything else. DB_PATH=~/.local/share/novel/project.db # Required. What a new project gets. Local, so sending a manuscript is a decision. DEFAULT_MODEL_POLICY=local # Required. How much context a generation may carry. Selection matters more than size. CONTEXT_BUDGET_TOKENS=8000 # Required. The gap that ends a writing session and snapshots a version. SESSION_GAP_MINUTES=30 # Required. The format editors expect. Chapters and scene breaks preserved. EXPORT_FORMAT=docx # Optional · secret. Only for projects explicitly set to a hosted model. Absent means local only. HOSTED_API_KEY=sk-...
You are building a production product version of Novelcrafter. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== PRODUCT.md ===== # Novelcrafter · product brief ## Problem The core loop is buildable, but a dependable replacement becomes a real weekend or multi-day project. For Novelcrafter, organize a novel bible, scenes, characters, and optional bring-your-own-model drafting. The hard boundary is its mature manuscript workflow, codex structure, and community templates, plus polish, integrations, and proprietary language models. ## Product outcome A novel workspace that stays fast at a hundred thousand words, keeps a story bible that is actually derived from the text, and tells the assistant the facts it needs instead of letting it guess. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - macOS, Windows, or Linux - local files - optional OpenAI or Anthropic API key for semantic rewrites ## Explicit non-goals for v1 - Prose quality. - Publishing and print formatting. - Collaborative writing. - Plot generation. - its mature manuscript workflow, codex structure, and community templates - cross-device sync - large proprietary style models - browser and office-suite extensions - team style guides ## Success criteria - A hundred thousand words is confirmed to load and search quickly - Facts are confirmed to record their establishing scene - Context selection is confirmed to prioritise scene entities - Dismissed flags are confirmed to stay dismissed - A local-only project is confirmed to raise rather than send ===== BRIEF.md ===== # Build brief · Novelcrafter The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a long-form fiction workspace where the story bible actually constrains the writing to replace Novelcrafter. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - Runtime: TypeScript with a local application and SQLite · an unfinished manuscript is the most private thing a writer has - Bible: Entities with typed attributes, each citing where it was established · a fact without its source cannot be checked when the text changes - Retrieval: Relevant bible entries and prior scenes selected per request · context is finite and a hundred thousand words does not fit - Continuity: Checks comparing the manuscript against the bible · the bible is only useful if divergence is detected - Models: Local by default, hosted as an explicit per-project choice · sending an unpublished manuscript anywhere should be a decision ### Data model (create this before Phase 1) - projects(id, title, model_policy, created_at) - chapters(id, project_id, ordinal, title) and scenes(id, chapter_id, ordinal, body, word_count, updated_at) - entities(id, project_id, kind, name, aliases_json) · kind is character, place, object or faction - facts(id, entity_id, attribute, value, established_in_scene_id, confidence, superseded_by) - timeline(id, project_id, scene_id, story_time, duration, ordering_note) · story order is not manuscript order - continuity_flags(id, scene_id, fact_id, kind, detail, resolved_at) · kind is contradiction, unestablished or anachronism - generations(id, scene_id, prompt, context_fact_ids_json, output, accepted) · what the assistant was told, kept - A fact records the scene that established it, so when that scene is rewritten the fact is flagged rather than silently orphaned. ### Phase 1 · A manuscript that survives a hundred thousand words Build: Scenes within chapters, reorderable, with autosave and version snapshots per session. Full text search across the manuscript. Verify performance at a hundred thousand words rather than at ten thousand. Trap: Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. Done when: A hundred thousand word project loads, edits and searches without perceptible delay. An hour of writing survives a hard kill. Reordering scenes and chapters does not rewrite unrelated content. Session snapshots accumulate per writing session rather than per keystroke. Do not build yet: No bible, retrieval or continuity. ### Phase 2 · A bible whose facts point at the text Build: Entities with typed attributes, each fact recording the scene it came from. Extract candidate facts from the manuscript for confirmation rather than asking the writer to enter everything. Handle a fact that is later superseded in the story. Trap: A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. Done when: Facts record the scene that established them. Candidate facts are extracted from the manuscript for confirmation rather than requiring manual entry. A fact superseded later in the story is recorded as superseded rather than contradicting. Rewriting the establishing scene flags the fact for review. Do not build yet: No retrieval or continuity checks yet. ### Phase 3 · Telling the assistant what it needs to know Build: Select the bible entries and prior scenes relevant to the scene being written, within a context budget. Record exactly which facts were sent. Show the writer the context before it is used. Trap: Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. Done when: Context selection prioritises entities present in the scene over general project facts, verified against a scene with a minor character. The writer can see the selected context before generation. Every generation records which facts it was given. Context stays within the budget without silently dropping the most relevant items. Do not build yet: No continuity checking or model policy yet. ### Phase 4 · Catching contradictions before a reader does Build: Check scenes against established facts, flagging contradictions and details asserted without having been established. Check story-time ordering for impossibilities. Let a flag be dismissed as intentional and stay dismissed. Trap: Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. Done when: A contradiction against an established fact is flagged with both locations. A detail asserted without having been established is flagged distinctly from a contradiction. A dismissed flag stays dismissed across re-checks. A story-time impossibility, such as a character in two places, is detected. Do not build yet: No model policy or export yet. ### Phase 5 · Where the manuscript goes, and getting it out Build: Model policy per project enforced at the call site. Export to standard manuscript formats with chapters intact. Verify the export is exactly the written text with no generated content marked otherwise. Trap: A global model setting means one careless change sends an unpublished manuscript to a service, and for a novelist that is a genuinely serious event. Put the policy on the project and enforce it where the request is made, so a local-only project raises rather than sends. Done when: A local-only project cannot send text anywhere, verified by attempting it and observing a raised error rather than a request. Export produces standard manuscript format with chapters and scene breaks intact. Exported text matches the stored manuscript exactly. Which passages came from a generation is recorded and can be listed. Do not build yet: Nothing after this. ### Out of scope (and why) - Prose quality. The assistant supplies continuity and context; whether the writing is good is not something this measures or improves. - Publishing, formatting for print and distribution, which is a separate craft and a separate toolchain. - Collaborative writing with several authors, which is a different synchronisation and permissions problem. - Plot generation, which produces the kind of structure that reads as generated and is not what the bible is for. ### README must contain - That the bible is derived from the manuscript rather than maintained beside it - That every fact records the scene that established it, so rewriting that scene flags the fact - That generation context is selected by scene relevance and shown before use - That a continuity flag can be dismissed as intentional and stays dismissed - That the model policy is per project and enforced at the call site ===== ARCHITECTURE.md ===== # Architecture · Novelcrafter ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | TypeScript with a local application and SQLite | an unfinished manuscript is the most private thing a writer has | | Bible | Entities with typed attributes, each citing where it was established | a fact without its source cannot be checked when the text changes | | Retrieval | Relevant bible entries and prior scenes selected per request | context is finite and a hundred thousand words does not fit | | Continuity | Checks comparing the manuscript against the bible | the bible is only useful if divergence is detected | | Models | Local by default, hosted as an explicit per-project choice | sending an unpublished manuscript anywhere should be a decision | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Manuscript | Scenes, chapters and version history. | Any editor, provided it loads per scene rather than whole. | | Bible | Facts with establishing scenes. | Any store, provided facts are derived from the text and cite their source. | | Retrieval | Relevance-based context selection. | Any selection, provided it is shown to the writer and recorded. | | Continuity | Contradiction detection with permanent dismissals. | Any checker, provided dismissals persist since fiction deviates on purpose. | | Policy | Per-project model choice at the call site. | Not swappable for a global setting, which sends the wrong manuscript eventually. | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - `DB_PATH` · required · The manuscript and the bible. Back this up above everything else. - `DEFAULT_MODEL_POLICY` · required · What a new project gets. Local, so sending a manuscript is a decision. - `CONTEXT_BUDGET_TOKENS` · required · How much context a generation may carry. Selection matters more than size. - `SESSION_GAP_MINUTES` · required · The gap that ends a writing session and snapshots a version. - `EXPORT_FORMAT` · required · The format editors expect. Chapters and scene breaks preserved. - `HOSTED_API_KEY` · optional, secret · Only for projects explicitly set to a hosted model. Absent means local only. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it. ===== AGENTS.md ===== # Agent instructions · Novelcrafter product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: TypeScript with a local application and SQLite, Entities with typed attributes, each citing where it was established, Relevant bible entries and prior scenes selected per request, Checks comparing the manuscript against the bible, Local by default, hosted as an explicit per-project choice. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone. ## Known traps - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. - A global model setting means one careless change sends an unpublished manuscript to a service, and for a novelist that is a genuinely serious event. Put the policy on the project and enforce it where the request is made, so a local-only project raises rather than sends. ===== MILESTONES.md ===== # Delivery milestones · Novelcrafter Estimated effort: **multi-day** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · A manuscript that survives a hundred thousand words Writing, reordering and searching stay fast at novel length. ### Steps 1. Load and save per scene Whole-manuscript loading fails exactly when the stakes are highest. Files: `src/scenes.ts` 2. Test at realistic length Generate a hundred thousand word fixture. Ten thousand proves nothing. Files: `tests/scale.test.ts` 3. Snapshot per session Per keystroke fills the history and makes it useless. Files: `src/versions.ts` ### Done when - [ ] A hundred thousand words loads and searches quickly - [ ] An hour of writing survives a hard kill - [ ] Reordering does not rewrite unrelated content - [ ] Snapshots accumulate per session ### Watch out - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. ## M2 · A bible whose facts point at the text Every established fact knows which scene established it. ### Steps 1. Record the establishing scene per fact A fact with no source cannot be rechecked when the text changes. Files: `src/facts.ts` 2. Extract candidates for confirmation A hand-maintained bible diverges within a week. Files: `src/extract.ts` 3. Support supersession Characters change. A later fact is not always a contradiction. Files: `src/facts.ts` ### Done when - [ ] Facts record their establishing scene - [ ] Candidates are extracted for confirmation - [ ] Supersession is distinct from contradiction - [ ] Rewriting a source scene flags its facts ### Watch out - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. ## M3 · Telling the assistant what it needs to know A generation request carries the relevant facts and nothing irrelevant. ### Steps 1. Select by scene relevance Entities in this scene first, then timeline neighbours. Files: `src/retrieve.ts`, `src/retrieve.test.ts` 2. Show the context before use A bad selection should be visible rather than mysterious. Files: `src/context-view.ts` 3. Record what was sent So a wrong output can be traced to a missing fact. Files: `src/generations.ts` ### Done when - [ ] Selection prioritises entities present in the scene - [ ] Context is visible before generation - [ ] Every generation records its facts - [ ] The budget does not drop the most relevant items ### Watch out - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. ## M4 · Catching contradictions before a reader does The manuscript is checked against the bible and against itself. ### Steps 1. Flag contradictions with both locations The writer needs to see the two passages together. Files: `src/continuity.ts` 2. Distinguish unestablished from contradictory One is a possible mistake, the other is possibly just new. Files: `src/continuity.ts` 3. Make dismissals permanent Fiction is full of intentional deviations. Re-flagging them ends the feature. Files: `src/flags.ts` ### Done when - [ ] Contradictions are flagged with both locations - [ ] Unestablished details are flagged distinctly - [ ] Dismissed flags stay dismissed - [ ] Story-time impossibilities are detected ### Watch out - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. ## M5 · Where the manuscript goes, and getting it out (production only) You choose whether the book ever leaves the machine, and it exports cleanly. ### Steps 1. Policy per project, enforced at the call site A global setting sends the wrong manuscript eventually. Files: `src/policy.ts`, `src/policy.test.ts` 2. Export to a real manuscript format Chapters, scene breaks, the conventions editors expect. Files: `src/export.ts` 3. Keep a record of generated passages Useful to the writer, and increasingly asked about by publishers. Files: `src/provenance.ts` ### Done when - [ ] A local-only project raises rather than sends - [ ] Export preserves chapters and scene breaks - [ ] Exported text matches the manuscript exactly - [ ] Generated passages can be listed ### Watch out - A global model setting means one careless change sends an unpublished manuscript to a service, and for a novelist that is a genuinely serious event. Put the policy on the project and enforce it where the request is made, so a local-only project raises rather than sends. ===== OPERATIONS.md ===== # Operations · Novelcrafter ## Backup A manuscript is years of work and is not reconstructible. Back up the database frequently and export to a plain manuscript format periodically, since the export outlives any application. ## Restore Restore and confirm the bible's establishing-scene references still resolve, since a restore that loses scene identifiers leaves a bible of facts pointing nowhere. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring For a personal tool the number worth watching is how many continuity flags get dismissed as intentional. A very high rate means the checker is too eager and is training the writer to ignore it. ## Incident checklist Losing writing is the only real incident here. Per-scene saving and session snapshots are the controls, and the hard-kill test is what proves them rather than the absence of reports. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] A hundred thousand words is confirmed to load and search quickly - [ ] Facts are confirmed to record their establishing scene - [ ] Context selection is confirmed to prioritise scene entities - [ ] Dismissed flags are confirmed to stay dismissed - [ ] A local-only project is confirmed to raise rather than send ## Launch constraint Do not market omitted Novelcrafter capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered. ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. The manuscript and the bible. Back this up above everything else. DB_PATH=~/.local/share/novel/project.db # Required. What a new project gets. Local, so sending a manuscript is a decision. DEFAULT_MODEL_POLICY=local # Required. How much context a generation may carry. Selection matters more than size. CONTEXT_BUDGET_TOKENS=8000 # Required. The gap that ends a writing session and snapshots a version. SESSION_GAP_MINUTES=30 # Required. The format editors expect. Chapters and scene breaks preserved. EXPORT_FORMAT=docx # Optional · secret. Only for projects explicitly set to a hosted model. Absent means local only. HOSTED_API_KEY=sk-...
# Novelcrafter · indie build A novel-writing environment whose real problem is continuity across a hundred thousand words: a character's eye colour established in chapter three, a timeline that has to hold, and an assistant that must be given the relevant facts rather than allowed to invent them. Estimated effort: **multi-day**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | TypeScript with a local application and SQLite | an unfinished manuscript is the most private thing a writer has | | Bible | Entities with typed attributes, each citing where it was established | a fact without its source cannot be checked when the text changes | | Retrieval | Relevant bible entries and prior scenes selected per request | context is finite and a hundred thousand words does not fit | | Continuity | Checks comparing the manuscript against the bible | the bible is only useful if divergence is detected | | Models | Local by default, hosted as an explicit per-project choice | sending an unpublished manuscript anywhere should be a decision | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **Node.js 22 or newer** · free - Why: Runs the local application. - Get it: nodejs.org, or nvm install 22. - Verify: node --version prints v22 or higher - [ ] **A local model runner** · free, needs memory - Why: An unpublished manuscript is the most private thing a novelist has, and the default should not be sending it to a service. - Get it: Any local runner with a model that handles long context and follows structured instructions. - Verify: A generation completes locally using supplied context - [ ] **A real manuscript of at least sixty thousand words** · free - Why: Editor performance, fact extraction and continuity checking all behave completely differently at novel length, and a short test project demonstrates none of the problems. - Get it: Your own draft, or a public domain novel imported as scenes and chapters. - Verify: Sixty thousand words are loaded as scenes with chapter structure - [ ] **Twenty known facts with a deliberate contradiction** · free - Why: Continuity checking cannot be evaluated without knowing the right answer, and the interesting cases are the deliberate deviations fiction is full of. - Get it: From your manuscript, list twenty established facts and introduce one genuine contradiction and one intentional deviation. - Verify: Both the contradiction and the intentional deviation are identified by hand first ## Quick start Follow Phase 1 in `BUILD_PLAN.md`; it creates the project. Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Prose quality. - Publishing and print formatting. - Collaborative writing. - Plot generation. - its mature manuscript workflow, codex structure, and community templates - cross-device sync - large proprietary style models - browser and office-suite extensions - team style guides If one of those is essential to you, that is the reason to keep paying for Novelcrafter, and the README should say so rather than pretend.
# Build brief · Novelcrafter The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a long-form fiction workspace where the story bible actually constrains the writing to replace Novelcrafter. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - Runtime: TypeScript with a local application and SQLite · an unfinished manuscript is the most private thing a writer has - Bible: Entities with typed attributes, each citing where it was established · a fact without its source cannot be checked when the text changes - Retrieval: Relevant bible entries and prior scenes selected per request · context is finite and a hundred thousand words does not fit - Continuity: Checks comparing the manuscript against the bible · the bible is only useful if divergence is detected - Models: Local by default, hosted as an explicit per-project choice · sending an unpublished manuscript anywhere should be a decision ### Data model (create this before Phase 1) - projects(id, title, model_policy, created_at) - chapters(id, project_id, ordinal, title) and scenes(id, chapter_id, ordinal, body, word_count, updated_at) - entities(id, project_id, kind, name, aliases_json) · kind is character, place, object or faction - facts(id, entity_id, attribute, value, established_in_scene_id, confidence, superseded_by) - timeline(id, project_id, scene_id, story_time, duration, ordering_note) · story order is not manuscript order - continuity_flags(id, scene_id, fact_id, kind, detail, resolved_at) · kind is contradiction, unestablished or anachronism - generations(id, scene_id, prompt, context_fact_ids_json, output, accepted) · what the assistant was told, kept - A fact records the scene that established it, so when that scene is rewritten the fact is flagged rather than silently orphaned. ### Phase 1 · A manuscript that survives a hundred thousand words Build: Scenes within chapters, reorderable, with autosave and version snapshots per session. Full text search across the manuscript. Verify performance at a hundred thousand words rather than at ten thousand. Trap: Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. Done when: A hundred thousand word project loads, edits and searches without perceptible delay. An hour of writing survives a hard kill. Reordering scenes and chapters does not rewrite unrelated content. Session snapshots accumulate per writing session rather than per keystroke. Do not build yet: No bible, retrieval or continuity. ### Phase 2 · A bible whose facts point at the text Build: Entities with typed attributes, each fact recording the scene it came from. Extract candidate facts from the manuscript for confirmation rather than asking the writer to enter everything. Handle a fact that is later superseded in the story. Trap: A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. Done when: Facts record the scene that established them. Candidate facts are extracted from the manuscript for confirmation rather than requiring manual entry. A fact superseded later in the story is recorded as superseded rather than contradicting. Rewriting the establishing scene flags the fact for review. Do not build yet: No retrieval or continuity checks yet. ### Phase 3 · Telling the assistant what it needs to know Build: Select the bible entries and prior scenes relevant to the scene being written, within a context budget. Record exactly which facts were sent. Show the writer the context before it is used. Trap: Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. Done when: Context selection prioritises entities present in the scene over general project facts, verified against a scene with a minor character. The writer can see the selected context before generation. Every generation records which facts it was given. Context stays within the budget without silently dropping the most relevant items. Do not build yet: No continuity checking or model policy yet. ### Phase 4 · Catching contradictions before a reader does Build: Check scenes against established facts, flagging contradictions and details asserted without having been established. Check story-time ordering for impossibilities. Let a flag be dismissed as intentional and stay dismissed. Trap: Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. Done when: A contradiction against an established fact is flagged with both locations. A detail asserted without having been established is flagged distinctly from a contradiction. A dismissed flag stays dismissed across re-checks. A story-time impossibility, such as a character in two places, is detected. Do not build yet: No model policy or export yet. ### Phase 5 · Where the manuscript goes, and getting it out Build: Model policy per project enforced at the call site. Export to standard manuscript formats with chapters intact. Verify the export is exactly the written text with no generated content marked otherwise. Trap: A global model setting means one careless change sends an unpublished manuscript to a service, and for a novelist that is a genuinely serious event. Put the policy on the project and enforce it where the request is made, so a local-only project raises rather than sends. Done when: A local-only project cannot send text anywhere, verified by attempting it and observing a raised error rather than a request. Export produces standard manuscript format with chapters and scene breaks intact. Exported text matches the stored manuscript exactly. Which passages came from a generation is recorded and can be listed. Do not build yet: Nothing after this. ### Out of scope (and why) - Prose quality. The assistant supplies continuity and context; whether the writing is good is not something this measures or improves. - Publishing, formatting for print and distribution, which is a separate craft and a separate toolchain. - Collaborative writing with several authors, which is a different synchronisation and permissions problem. - Plot generation, which produces the kind of structure that reads as generated and is not what the bible is for. ### README must contain - That the bible is derived from the manuscript rather than maintained beside it - That every fact records the scene that established it, so rewriting that scene flags the fact - That generation context is selected by scene relevance and shown before use - That a continuity flag can be dismissed as intentional and stays dismissed - That the model policy is per project and enforced at the call site
# Agent instructions · Novelcrafter indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: TypeScript with a local application and SQLite, Entities with typed attributes, each citing where it was established, Relevant bible entries and prior scenes selected per request, Checks comparing the manuscript against the bible, Local by default, hosted as an explicit per-project choice. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again.
# Build plan · Novelcrafter A novel-writing environment whose real problem is continuity across a hundred thousand words: a character's eye colour established in chapter three, a timeline that has to hold, and an assistant that must be given the relevant facts rather than allowed to invent them. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · A manuscript that survives a hundred thousand words Writing, reordering and searching stay fast at novel length. ### Steps 1. Load and save per scene Whole-manuscript loading fails exactly when the stakes are highest. Files: `src/scenes.ts` 2. Test at realistic length Generate a hundred thousand word fixture. Ten thousand proves nothing. Files: `tests/scale.test.ts` 3. Snapshot per session Per keystroke fills the history and makes it useless. Files: `src/versions.ts` ### Done when - [ ] A hundred thousand words loads and searches quickly - [ ] An hour of writing survives a hard kill - [ ] Reordering does not rewrite unrelated content - [ ] Snapshots accumulate per session ### Watch out - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. ## Phase 2 · A bible whose facts point at the text Every established fact knows which scene established it. ### Steps 1. Record the establishing scene per fact A fact with no source cannot be rechecked when the text changes. Files: `src/facts.ts` 2. Extract candidates for confirmation A hand-maintained bible diverges within a week. Files: `src/extract.ts` 3. Support supersession Characters change. A later fact is not always a contradiction. Files: `src/facts.ts` ### Done when - [ ] Facts record their establishing scene - [ ] Candidates are extracted for confirmation - [ ] Supersession is distinct from contradiction - [ ] Rewriting a source scene flags its facts ### Watch out - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. ## Phase 3 · Telling the assistant what it needs to know A generation request carries the relevant facts and nothing irrelevant. ### Steps 1. Select by scene relevance Entities in this scene first, then timeline neighbours. Files: `src/retrieve.ts`, `src/retrieve.test.ts` 2. Show the context before use A bad selection should be visible rather than mysterious. Files: `src/context-view.ts` 3. Record what was sent So a wrong output can be traced to a missing fact. Files: `src/generations.ts` ### Done when - [ ] Selection prioritises entities present in the scene - [ ] Context is visible before generation - [ ] Every generation records its facts - [ ] The budget does not drop the most relevant items ### Watch out - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. ## Phase 4 · Catching contradictions before a reader does The manuscript is checked against the bible and against itself. ### Steps 1. Flag contradictions with both locations The writer needs to see the two passages together. Files: `src/continuity.ts` 2. Distinguish unestablished from contradictory One is a possible mistake, the other is possibly just new. Files: `src/continuity.ts` 3. Make dismissals permanent Fiction is full of intentional deviations. Re-flagging them ends the feature. Files: `src/flags.ts` ### Done when - [ ] Contradictions are flagged with both locations - [ ] Unestablished details are flagged distinctly - [ ] Dismissed flags stay dismissed - [ ] Story-time impossibilities are detected ### Watch out - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. ## Not in this build - Prose quality. - Publishing and print formatting. - Collaborative writing. - Plot generation. ## After v1, if you want it - A timeline view, which is where continuity problems become obvious - Per-character voice notes fed into context, once retrieval is trustworthy - Revision tracking across drafts, which is the other half of a long project
# Copy to .env and fill in. Never commit .env; this file documents it. # Required. The manuscript and the bible. Back this up above everything else. DB_PATH=~/.local/share/novel/project.db # Required. What a new project gets. Local, so sending a manuscript is a decision. DEFAULT_MODEL_POLICY=local # Required. How much context a generation may carry. Selection matters more than size. CONTEXT_BUDGET_TOKENS=8000 # Required. The gap that ends a writing session and snapshots a version. SESSION_GAP_MINUTES=30 # Required. The format editors expect. Chapters and scene breaks preserved. EXPORT_FORMAT=docx # Optional · secret. Only for projects explicitly set to a hosted model. Absent means local only. HOSTED_API_KEY=sk-...
# Novelcrafter · product brief ## Problem The core loop is buildable, but a dependable replacement becomes a real weekend or multi-day project. For Novelcrafter, organize a novel bible, scenes, characters, and optional bring-your-own-model drafting. The hard boundary is its mature manuscript workflow, codex structure, and community templates, plus polish, integrations, and proprietary language models. ## Product outcome A novel workspace that stays fast at a hundred thousand words, keeps a story bible that is actually derived from the text, and tells the assistant the facts it needs instead of letting it guess. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - macOS, Windows, or Linux - local files - optional OpenAI or Anthropic API key for semantic rewrites ## Explicit non-goals for v1 - Prose quality. - Publishing and print formatting. - Collaborative writing. - Plot generation. - its mature manuscript workflow, codex structure, and community templates - cross-device sync - large proprietary style models - browser and office-suite extensions - team style guides ## Success criteria - A hundred thousand words is confirmed to load and search quickly - Facts are confirmed to record their establishing scene - Context selection is confirmed to prioritise scene entities - Dismissed flags are confirmed to stay dismissed - A local-only project is confirmed to raise rather than send
# Build brief · Novelcrafter The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a long-form fiction workspace where the story bible actually constrains the writing to replace Novelcrafter. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - Runtime: TypeScript with a local application and SQLite · an unfinished manuscript is the most private thing a writer has - Bible: Entities with typed attributes, each citing where it was established · a fact without its source cannot be checked when the text changes - Retrieval: Relevant bible entries and prior scenes selected per request · context is finite and a hundred thousand words does not fit - Continuity: Checks comparing the manuscript against the bible · the bible is only useful if divergence is detected - Models: Local by default, hosted as an explicit per-project choice · sending an unpublished manuscript anywhere should be a decision ### Data model (create this before Phase 1) - projects(id, title, model_policy, created_at) - chapters(id, project_id, ordinal, title) and scenes(id, chapter_id, ordinal, body, word_count, updated_at) - entities(id, project_id, kind, name, aliases_json) · kind is character, place, object or faction - facts(id, entity_id, attribute, value, established_in_scene_id, confidence, superseded_by) - timeline(id, project_id, scene_id, story_time, duration, ordering_note) · story order is not manuscript order - continuity_flags(id, scene_id, fact_id, kind, detail, resolved_at) · kind is contradiction, unestablished or anachronism - generations(id, scene_id, prompt, context_fact_ids_json, output, accepted) · what the assistant was told, kept - A fact records the scene that established it, so when that scene is rewritten the fact is flagged rather than silently orphaned. ### Phase 1 · A manuscript that survives a hundred thousand words Build: Scenes within chapters, reorderable, with autosave and version snapshots per session. Full text search across the manuscript. Verify performance at a hundred thousand words rather than at ten thousand. Trap: Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. Done when: A hundred thousand word project loads, edits and searches without perceptible delay. An hour of writing survives a hard kill. Reordering scenes and chapters does not rewrite unrelated content. Session snapshots accumulate per writing session rather than per keystroke. Do not build yet: No bible, retrieval or continuity. ### Phase 2 · A bible whose facts point at the text Build: Entities with typed attributes, each fact recording the scene it came from. Extract candidate facts from the manuscript for confirmation rather than asking the writer to enter everything. Handle a fact that is later superseded in the story. Trap: A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. Done when: Facts record the scene that established them. Candidate facts are extracted from the manuscript for confirmation rather than requiring manual entry. A fact superseded later in the story is recorded as superseded rather than contradicting. Rewriting the establishing scene flags the fact for review. Do not build yet: No retrieval or continuity checks yet. ### Phase 3 · Telling the assistant what it needs to know Build: Select the bible entries and prior scenes relevant to the scene being written, within a context budget. Record exactly which facts were sent. Show the writer the context before it is used. Trap: Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. Done when: Context selection prioritises entities present in the scene over general project facts, verified against a scene with a minor character. The writer can see the selected context before generation. Every generation records which facts it was given. Context stays within the budget without silently dropping the most relevant items. Do not build yet: No continuity checking or model policy yet. ### Phase 4 · Catching contradictions before a reader does Build: Check scenes against established facts, flagging contradictions and details asserted without having been established. Check story-time ordering for impossibilities. Let a flag be dismissed as intentional and stay dismissed. Trap: Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. Done when: A contradiction against an established fact is flagged with both locations. A detail asserted without having been established is flagged distinctly from a contradiction. A dismissed flag stays dismissed across re-checks. A story-time impossibility, such as a character in two places, is detected. Do not build yet: No model policy or export yet. ### Phase 5 · Where the manuscript goes, and getting it out Build: Model policy per project enforced at the call site. Export to standard manuscript formats with chapters intact. Verify the export is exactly the written text with no generated content marked otherwise. Trap: A global model setting means one careless change sends an unpublished manuscript to a service, and for a novelist that is a genuinely serious event. Put the policy on the project and enforce it where the request is made, so a local-only project raises rather than sends. Done when: A local-only project cannot send text anywhere, verified by attempting it and observing a raised error rather than a request. Export produces standard manuscript format with chapters and scene breaks intact. Exported text matches the stored manuscript exactly. Which passages came from a generation is recorded and can be listed. Do not build yet: Nothing after this. ### Out of scope (and why) - Prose quality. The assistant supplies continuity and context; whether the writing is good is not something this measures or improves. - Publishing, formatting for print and distribution, which is a separate craft and a separate toolchain. - Collaborative writing with several authors, which is a different synchronisation and permissions problem. - Plot generation, which produces the kind of structure that reads as generated and is not what the bible is for. ### README must contain - That the bible is derived from the manuscript rather than maintained beside it - That every fact records the scene that established it, so rewriting that scene flags the fact - That generation context is selected by scene relevance and shown before use - That a continuity flag can be dismissed as intentional and stays dismissed - That the model policy is per project and enforced at the call site
# Architecture · Novelcrafter ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | TypeScript with a local application and SQLite | an unfinished manuscript is the most private thing a writer has | | Bible | Entities with typed attributes, each citing where it was established | a fact without its source cannot be checked when the text changes | | Retrieval | Relevant bible entries and prior scenes selected per request | context is finite and a hundred thousand words does not fit | | Continuity | Checks comparing the manuscript against the bible | the bible is only useful if divergence is detected | | Models | Local by default, hosted as an explicit per-project choice | sending an unpublished manuscript anywhere should be a decision | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Manuscript | Scenes, chapters and version history. | Any editor, provided it loads per scene rather than whole. | | Bible | Facts with establishing scenes. | Any store, provided facts are derived from the text and cite their source. | | Retrieval | Relevance-based context selection. | Any selection, provided it is shown to the writer and recorded. | | Continuity | Contradiction detection with permanent dismissals. | Any checker, provided dismissals persist since fiction deviates on purpose. | | Policy | Per-project model choice at the call site. | Not swappable for a global setting, which sends the wrong manuscript eventually. | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - `DB_PATH` · required · The manuscript and the bible. Back this up above everything else. - `DEFAULT_MODEL_POLICY` · required · What a new project gets. Local, so sending a manuscript is a decision. - `CONTEXT_BUDGET_TOKENS` · required · How much context a generation may carry. Selection matters more than size. - `SESSION_GAP_MINUTES` · required · The gap that ends a writing session and snapshots a version. - `EXPORT_FORMAT` · required · The format editors expect. Chapters and scene breaks preserved. - `HOSTED_API_KEY` · optional, secret · Only for projects explicitly set to a hosted model. Absent means local only. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it.
# Agent instructions · Novelcrafter product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: TypeScript with a local application and SQLite, Entities with typed attributes, each citing where it was established, Relevant bible entries and prior scenes selected per request, Checks comparing the manuscript against the bible, Local by default, hosted as an explicit per-project choice. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone. ## Known traps - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. - A global model setting means one careless change sends an unpublished manuscript to a service, and for a novelist that is a genuinely serious event. Put the policy on the project and enforce it where the request is made, so a local-only project raises rather than sends.
# Delivery milestones · Novelcrafter Estimated effort: **multi-day** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · A manuscript that survives a hundred thousand words Writing, reordering and searching stay fast at novel length. ### Steps 1. Load and save per scene Whole-manuscript loading fails exactly when the stakes are highest. Files: `src/scenes.ts` 2. Test at realistic length Generate a hundred thousand word fixture. Ten thousand proves nothing. Files: `tests/scale.test.ts` 3. Snapshot per session Per keystroke fills the history and makes it useless. Files: `src/versions.ts` ### Done when - [ ] A hundred thousand words loads and searches quickly - [ ] An hour of writing survives a hard kill - [ ] Reordering does not rewrite unrelated content - [ ] Snapshots accumulate per session ### Watch out - Loading the whole manuscript into the editor works beautifully at twenty thousand words and becomes unusable at a hundred thousand, which is exactly when the writer has the most to lose. Load and save per scene, and test against a manuscript of realistic length from the start. ## M2 · A bible whose facts point at the text Every established fact knows which scene established it. ### Steps 1. Record the establishing scene per fact A fact with no source cannot be rechecked when the text changes. Files: `src/facts.ts` 2. Extract candidates for confirmation A hand-maintained bible diverges within a week. Files: `src/extract.ts` 3. Support supersession Characters change. A later fact is not always a contradiction. Files: `src/facts.ts` ### Done when - [ ] Facts record their establishing scene - [ ] Candidates are extracted for confirmation - [ ] Supersession is distinct from contradiction - [ ] Rewriting a source scene flags its facts ### Watch out - A bible maintained by hand diverges from the manuscript within a week, because writers change things while writing and updating a separate document is the first thing to go. Extract candidates from the text and have the writer confirm them, so the bible is derived from the manuscript rather than parallel to it. ## M3 · Telling the assistant what it needs to know A generation request carries the relevant facts and nothing irrelevant. ### Steps 1. Select by scene relevance Entities in this scene first, then timeline neighbours. Files: `src/retrieve.ts`, `src/retrieve.test.ts` 2. Show the context before use A bad selection should be visible rather than mysterious. Files: `src/context-view.ts` 3. Record what was sent So a wrong output can be traced to a missing fact. Files: `src/generations.ts` ### Done when - [ ] Selection prioritises entities present in the scene - [ ] Context is visible before generation - [ ] Every generation records its facts - [ ] The budget does not drop the most relevant items ### Watch out - Sending whatever fits, in bible order, fills the context with the protagonist's full history while omitting the one fact about the character actually in the scene. Select by relevance to the scene's entities and its position in the story, and show the writer what was selected so a bad selection is visible rather than mysterious. ## M4 · Catching contradictions before a reader does The manuscript is checked against the bible and against itself. ### Steps 1. Flag contradictions with both locations The writer needs to see the two passages together. Files: `src/continuity.ts` 2. Distinguish unestablished from contradictory One is a possible mistake, the other is possibly just new. Files: `src/continuity.ts` 3. Make dismissals permanent Fiction is full of intentional deviations. Re-flagging them ends the feature. Files: `src/flags.ts` ### Done when - [ ] Contradictions are flagged with both locations - [ ] Unestablished details are flagged distinctly - [ ] Dismissed flags stay dismissed - [ ] Story-time impossibilities are detected ### Watch out - Flagging every deviation as an error makes the check unusable in fiction, where a character lying about their eye colour is a plot point rather than a mistake. Let a flag be dismissed as intentional, keep the dismissal, and never raise the same one again. ## M5 · Where the manuscript goes, and getting it out (production only) You choose whether the book ever leaves the machine, and it exports cleanly. ### Steps 1. Policy per project, enforced at the call site A global setting sends the wrong manuscript eventually. Files: `src/policy.ts`, `src/policy.test.ts` 2. Export to a real manuscript format Chapters, scene breaks, the conventions editors expect. Files: `src/export.ts` 3. Keep a record of generated passages Useful to the writer, and increasingly asked about by publishers. Files: `src/provenance.ts` ### Done when - [ ] A local-only project raises rather than sends - [ ] Export preserves chapters and scene breaks - [ ] Exported text matches the manuscript exactly - [ ] Generated passages can be listed ### Watch out - A global model setting means one careless change sends an unpublished manuscript to a service, and for a novelist that is a genuinely serious event. Put the policy on the project and enforce it where the request is made, so a local-only project raises rather than sends.
# Operations · Novelcrafter ## Backup A manuscript is years of work and is not reconstructible. Back up the database frequently and export to a plain manuscript format periodically, since the export outlives any application. ## Restore Restore and confirm the bible's establishing-scene references still resolve, since a restore that loses scene identifiers leaves a bible of facts pointing nowhere. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring For a personal tool the number worth watching is how many continuity flags get dismissed as intentional. A very high rate means the checker is too eager and is training the writer to ignore it. ## Incident checklist Losing writing is the only real incident here. Per-scene saving and session snapshots are the controls, and the hard-kill test is what proves them rather than the absence of reports. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] A hundred thousand words is confirmed to load and search quickly - [ ] Facts are confirmed to record their establishing scene - [ ] Context selection is confirmed to prioritise scene entities - [ ] Dismissed flags are confirmed to stay dismissed - [ ] A local-only project is confirmed to raise rather than send ## Launch constraint Do not market omitted Novelcrafter capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered.
# Copy to .env and fill in. Never commit .env; this file documents it. # Required. The manuscript and the bible. Back this up above everything else. DB_PATH=~/.local/share/novel/project.db # Required. What a new project gets. Local, so sending a manuscript is a decision. DEFAULT_MODEL_POLICY=local # Required. How much context a generation may carry. Selection matters more than size. CONTEXT_BUDGET_TOKENS=8000 # Required. The gap that ends a writing session and snapshots a version. SESSION_GAP_MINUTES=30 # Required. The format editors expect. Chapters and scene breaks preserved. EXPORT_FORMAT=docx # Optional · secret. Only for projects explicitly set to a hosted model. Absent means local only. HOSTED_API_KEY=sk-...
$ choose a build depth, inspect the files, then open the complete pack in your agent
People still pay for Novelcrafter because the paid tool is already present everywhere they write and its suggestions have been tuned across millions of documents. The recurring cost buys model quality, extension compatibility, dictionaries, releases, and sync, not just the visible interface.
xits mature manuscript workflow, codex structure, and community templates
xcross-device sync
xlarge proprietary style models
xbrowser and office-suite extensions
xteam style guides
Don't feel like building it? These folks already made it free.
all 7 free alternatives to Novelcrafter →· no votes, no pay-to-list · just what's real
Novelcrafter pricing
| plan | monthly | annual (per mo) | what you get |
|---|---|---|---|
| scribe | $4/user | $3.33/user | Unlimited books; basic review tools; no BYOK AI; cannot invite collaborators or create teams |
| hobbyist | $8/user | $6.67/user | Unlimited books; BYOK AI, scene summarization and character extraction; no Workshop Chat or collaborator invites |
| artisan | $14/user | $11.67/user | Unlimited books; BYOK AI and Workshop Chat; cannot invite collaborators or create teams |
| specialist | $20/user | $16.67/user | Unlimited books; collaborator invitations; series collaboration; create and manage teams |
free tierno free tier
billingmonthly + annual (2 months free); 21-day no-card trial is not a free tier
hidden costsAI-capable tiers are bring-your-own-key, so model/API charges are separate; collaborators need individual paid subscriptions to edit, and upgrades are prorated.
verified 2026-08-12 · source ↗
Vibecode Novelcrafter
Kinda. The core of Novelcrafter is buildable in a weekend with the prompt on this page, but there are real gaps: its mature manuscript workflow, codex structure, and community templates, cross-device sync. Read the honest list above before committing.
How much does Novelcrafter cost?
Novelcrafter's pricing is usage-based or varies by plan · Official Hobbyist tier excludes model usage; users bring their own provider..
What do I lose by replacing Novelcrafter?
Honestly: its mature manuscript workflow, codex structure, and community templates; cross-device sync; large proprietary style models; browser and office-suite extensions; team style guides. If any of those are load-bearing for you, keep paying.
Is there an open-source alternative to Novelcrafter?
Yes: KoboldCpp (One executable plus a model download gets you story continuation, memory, world info and author’s notes; elegance was not bundled.) novelWriter (A plain-text novel room with scenes, synopses, cross-references, and no cloud account between you and chapter twelve.) Manuskript (A Scrivener-shaped box of scenes, characters, plots, index cards, and rough edges that cost exactly nothing.) All 7 curated free alternatives are at vibecodeit.com/novelcrafter/alternatives. The prompt is for when you want it exactly your way.