A writing dashboard plugin that integrates AI-powered chapter generation, micro-editing, and character management into your writing workflow.
- Install and enable Writing dashboard.
- Open Settings → Writing dashboard (plugin settings).
- Choose an API provider, paste your API key, and select a model.
- Set Book main file using the file tree picker (select your active manuscript note from the dropdown).
- Optional but recommended: set Story bible path.
- Open the dashboard:
- Ribbon icon: Open dashboard
- Command palette: Open dashboard
- OpenAI:
https://platform.openai.com/api-keys - Anthropic:
https://console.anthropic.com/settings/keys - Google Gemini:
https://aistudio.google.com/app/apikey - OpenRouter:
https://openrouter.ai/keys
-
Generate chapter - Generate new chapters using your slate method, pulling from:
- Retrieved context (whole vault) - RAG retrieval from all indexed files
- Story Bible + Extractions
- Sliding Window - Last 20,000 words of your active manuscript (extracted automatically)
- Your Scene Summary + Rewrite Instructions
- Target word range (Min/Max)
Important: The plugin only sends the last 20,000 words of your active manuscript (sliding window) to the AI, not full book files. Continuity is maintained through RAG retrieval from your whole vault.
-
Micro Edit - Refine specific passages with:
- Selected text analysis
- Your grievances and directives
- Full context awareness (characters, canon, style)
- Surrounding context - Automatically includes 500 words before and after for seamless narrative flow
- Single refined alternative output
-
Character Update - Extract and update character notes (dedicated "Characters" tab):
- Own Tab: Character Update has its own dedicated tab in the dashboard for easy access
- Manual extraction from pasted narrative text
- Timestamped updates with word/character counts
- Voice evidence, traits, relationships, arc progression
- Automatic character folder management
- AI Backend Choice: Use Ollama (local) or Cloud API for character extraction
- Bulk backfill (Process Entire Book) with improved recall:
- Pick which file to process (Book 1 / Book 2 / any note)
- Splits by H1 chapter headings (
#) - 2-pass pipeline (roster pass + per-chapter extraction)
-
Continuity check - Scan a draft against canon and context:
- Flags violations (knowledge state, timeline, POV drift, naming)
- Includes evidence quotes and suggested patches (copy/paste)
- Full vault browser with folder structure
- Read/write access to all Obsidian files
- Automatic path detection
- Configurable file paths
The plugin provides dedicated tools for maintaining your local semantic index:
- Re-index Vault: Manually trigger a full rescan and re-embedding of your vault.
- Clear Index: Wipe the local vector cache to fix corrupted states or start fresh.
- Live Progress: The Re-index button shows dynamic progress ("Indexing 12/39...") and is disabled during indexing.
- Persistent Status: Settings display "📊 Index Status: X chunks across Y files" so you always know your index health.
- Circuit Breaker: If embedding repeatedly fails, the plugin pauses for 15 seconds to prevent infinite spinning.
- Robust Processing: Automatically handles long contiguous strings (like logs or base64) by splitting them into digestible chunks for the embedding model, preventing API "400 Bad Request" errors.
- Ollama Integration: Uses your local Ollama instance (defaulting to
nomic-embed-text) for high-quality, private semantic embeddings. - Bidirectional Model Matching: Recognizes models whether you use
nomic-embed-textornomic-embed-text:latest.
The plugin automatically prevents system freezes by deriving safe context limits from your hardware:
- First-Run Setup: On first install, a modal asks "How much RAM does this machine have?" (8/16/24/32/64/128 GB)
- Safety Tables: Conservative limits for each RAM + Model size combination. A 70B model is blocked on 16GB RAM; a 7B model gets generous context.
- Risk Profiles: Choose between Safe (conservative), Moderate (balanced), or Aggressive (maximum performance, higher freeze risk)
- Dynamic Derivation:
derivedCap = min(BASE × MULTIPLIER, PROFILE_CAP, model's actual num_ctx) - Slider Control: Settings include a context window slider within your safe range
- Model Verification: Query Ollama to get the model's actual context limit
For Local AI (Ollama), the plugin treats the generation field as a Living Document:
- 3-Chunk Juggling: Maintains a rolling buffer of the last ~1500 words to ensure narrative cohesion.
- Live Patching: The AI background "Stitcher" pass polishes transitions in real-time. You'll see text "settle" into its final form with a subtle highlight.
- Consolidated Single-Model Architecture: Optimized for 16GB-32GB RAM machines. All text tasks (Writing, Auditing, Stitching) use your primary Smart Model with specialized task profiles (Temp 0.7 for writing, Temp 0.1 for mechanical logic). This eliminates the 30-60 second latency penalty of VRAM swapping between different models.
- Hardware Optimization: Uses KV Cache Grafting and a stable prefix to keep Ollama "warm" between different tasks.
- Multi-Segment Generation: Fixed 700-token output reserve per segment allows more context per call. A 16k context window can effectively access 100k+ tokens through RAG-refreshed multi-segment generation.
Five layers of protection ensure the AI never breaks your story:
- Hash Gate: Rejects AI edits if you've manually changed the paragraph in the meantime.
- User-Dirty Protection: Once you edit a paragraph, the AI is strictly forbidden from auto-patching it.
- LockMap Gate: Protects proper nouns, character names, and dates from being altered.
- Tuple Gate: Prevents the introduction of contradictory facts or "hallucinated" canon.
- Budget Gate: Limits the amount of change the background pass can make, preventing "runaway" edits.
The "Process Entire Book" feature uses a sophisticated pipeline:
- Pass 1 (Roster Discovery): Scans the manuscript to build a global list of names and resolve aliases.
- Pass 2 (Extraction): Re-scans each chapter with the roster in mind to ensure accurate, non-duplicate character notes.
The RAG engine uses Reciprocal Rank Fusion (RRF) to combine keyword (BM25) and semantic results, followed by Maximal Marginal Relevance (MMR) to filter out redundant context snippets.
GWriter can share its embedding index with the StoryBoard plugin:
- Handshake Protocol: Plugins exchange compatibility info via
.obsidian/embeddings/handshake/ - Shared Index: When compatible, both plugins read/write to
/Embeddings/shared-index/ - Locking: Prevents simultaneous writes with heartbeat-based lock system
- Auto-Discovery: In "Auto" mode, GWriter detects StoryBoard's presence and shares automatically
- Storage Modes: Isolated (private), Auto (shared if compatible), or Manual (user-specified path)
- Fully Self-Contained - No Python backend required! Everything runs within Obsidian
- Multi-Provider Support - Works with OpenAI, Anthropic (Claude), Google Gemini, OpenRouter, and local Ollama
- RAM-Aware Safety - Automatically derives safe context limits based on your hardware (8GB-128GB+), preventing system freezes
- Local AI Optimized - Use a single Smart Model (e.g., Llama 3.2) for all text tasks and a specialized Embedding Model (e.g., Nomic) for lightning-fast semantic indexing.
- Smart Context Integration - Automatically pulls from your Story Bible, Extractions, sliding window (last 20k words), and Character notes via RAG retrieval
- Efficient Context Usage - Only sends the last 20,000 words of your active manuscript to the AI, not full book files. Full continuity comes from RAG retrieval.
- Multi-Segment Generation - Even with a 16k context window, GWriter can produce 10,000+ word chapters through RAG-refreshed multi-segment generation
- Surrounding Context - Micro-edit mode includes 500 words before/after selected text for better narrative continuity
- Prompt Size Warning - Estimates prompt size and warns if you exceed your configured context limit
- Setup Wizard - First-run wizard to create default vault structure (Book-Main.md, Story Bible, Characters folder, etc.)
- Hybrid retrieval (local RAG) - Combines BM25 lexical ranking, local Ollama embeddings, and diversity selection to inject relevant context without a server
- Shared Brain - Share embedding index with StoryBoard plugin for cross-plugin context awareness
- File Chunking - Manually chunk large files into 500-word segments for processing
- Developer Tools - Built-in stress test for comprehensive plugin diagnostics, including adversarial word handling and safety gate verification.
- Pure Obsidian Plugin - TypeScript/React UI
- Direct AI API Integration - Makes API calls directly from the plugin
- No Backend Required - Everything runs within Obsidian
Note: The backend/ folder contains legacy Python code that is no longer required. The plugin now handles all AI processing internally.
- Obsidian installed
- An AI API key from one of the supported providers:
- OpenAI (GPT-4, GPT-3.5, etc.)
- Anthropic (Claude 3 Opus, Claude 3 Sonnet, etc.)
- Google Gemini (for example:
gemini-2.5-pro,gemini-2.5-flash,gemini-1.5-pro) - OpenRouter (multi-provider gateway)
- Open Obsidian Settings
- Go to Community Plugins
- Turn off Safe Mode (if enabled)
- Click Browse and search for "Writing Dashboard"
- Click Install
- Enable the plugin
- Download the latest release from GitHub Releases
- Extract the
obsidian-pluginfolder - Copy it to your vault's
.obsidian/plugins/directory - Rename it to
writing-dashboard - Restart Obsidian
- Go to Settings → Community Plugins → Enable "Writing Dashboard"
- In Obsidian: Settings → Community Plugins → Browse
- Click "..." (three dots) → "Install from URL"
- Enter:
https://github.com/JHarp199345/Gwriter - Obsidian will find the plugin in the
obsidian-pluginfolder
On first run, the plugin will automatically show a Setup Wizard to help you create the default vault structure. You can also manually trigger it:
- Open Obsidian settings → Writing dashboard
- Click "Run setup wizard" button
- Or use Command Palette: "Run setup wizard"
The wizard lets you:
- Create default files:
Book-Main.md,Book - Story Bible.md,Memory - Sliding Window.md - Create the
Characters/folder with a template - All files/folders are only created if they don't already exist (won't overwrite)
-
Open Obsidian settings → Writing dashboard
-
Configure:
- API Key: Your AI API key (OpenAI, Anthropic, or Gemini)
- API Provider: Choose your provider (openai, anthropic, gemini, or openrouter)
- Model: examples:
gpt-4o,claude-3-5-sonnet,gemini-2.5-pro - Vault Path: Auto-detected, but can be overridden
- Character Folder: Use the folder tree picker to select or create a folder (default:
Characters) - Book main file: Use the file tree picker to select your active manuscript (supports files at root or in folders)
- Story Bible Path: Use the file tree picker to select your story bible file
- Generation Logs Folder: Optional folder for logging generation runs (excluded from retrieval)
Memory & Performance (for local AI):
- RAM Tier: Select your machine's RAM (8/16/24/32/64/128 GB) - asked on first run
- Risk Profile: Safe (conservative) / Moderate / Aggressive
- Context Window: Slider within your safe range
- Verify Model: Query Ollama for actual model context limit
Embedding Storage Mode:
- Isolated: Private index (default)
- Auto: Share with StoryBoard if installed and compatible
- Manual: Specify custom path
Note: The sliding window is automatically extracted from your book main file (last 20,000 words), so no separate sliding window path is needed.
Note: model names change frequently. The plugin does not hardcode model availability; it sends the model id you enter to your chosen provider.
- Click the book icon in the ribbon
- Or use Command Palette (
Cmd+P/Ctrl+P): "Open dashboard"
- Select Chapter Generate mode (bottom-right dropdown)
- Write your Scene Summary / Directions
- Review/edit Rewrite Instructions (defaults are auto-filled; includes a Reset button)
- Set a target word range (Min → Max). For an exact target, set Min=Max.
- Optional: click Preview prompt to see the exact prompt that will be sent.
- Click Generate chapter
- Review output and copy to clipboard
Notes:
- The dashboard shows word/character counters for Scene Summary, Rewrite Instructions, and Generated Output.
- The dashboard may warn you if the prompt is estimated to exceed your configured context window.
- Select Micro Edit mode
- Paste the problematic passage in "Selected Text"
- Enter your grievances/directives in "Grievances and directives"
- Optional: click Preview prompt to see the exact prompt that will be sent.
- Click Generate edit
- The plugin automatically includes 500 words before and after your selection for context
- Copy the refined alternative and paste into your manuscript
The dashboard displays your current book file path at the top of the main workspace for quick reference.
Examples you can paste into grievances/directives:
Character A has no knowledge of Event X yet; remove any references that imply they do. Keep the scene outcome the same.Fix POV leaks: this is Character B POV only.Tone is too modern; make it tighter and more tense, matching surrounding chapters.Continuity: the injury is on the left arm, not the right.
- Select Character Update mode
- Paste character-relevant text in "Selected Text"
- Optional: click Preview prompt to see the exact extraction prompt.
- Click Update characters
- Select Continuity check mode
- Paste the draft to check (defaults to the last generated output when empty)
- Optional: adjust focus toggles (Knowledge, Timeline, POV, Naming)
- Optional: click Preview prompt
- Click Run continuity check
Each mode keeps its own saved inputs (per vault). Switching modes does not overwrite other mode fields.
Bulk character backfill:
- Select Character Update mode
- Click Select file to process and choose the manuscript you want to scan
- Click Process Entire Book
- The plugin performs a 2-pass scan (roster + per-chapter extraction) and updates character notes
Manually chunk large files into smaller segments:
- Select Character Update mode
- Select text in your editor OR select a file to process
- Click Chunk Selected File
- The plugin creates a
[FILENAME]-Chunked/folder with numbered chunk files (e.g.,Book-Main-CHUNK-001.md) - Each chunk is approximately 500 words with overlap for context
Gwriter/ ├── backend/ # Legacy Python backend (no longer required) │ ├── main.py │ ├── requirements.txt │ └── services/ │ └── obsidian-plugin/ # The actual plugin ├── main.js # Built plugin (for installation) ├── main.ts # Source code ├── manifest.json # Plugin manifest ├── package.json ├── styles.css ├── README.md # Plugin-specific README ├── services/ │ ├── AIClient.ts # Direct AI API calls │ ├── PromptEngine.ts # Prompt building │ ├── ContextAggregator.ts # Vault file reading │ ├── CharacterExtractor.ts # Character parsing │ └── VaultService.ts # File operations └── ui/ ├── DashboardView.ts ├── DashboardComponent.tsx ├── VaultBrowser.tsx ├── EditorPanel.tsx ├── DirectorNotes.tsx ├── ModeSelector.tsx └── SettingsTab.ts
Character notes are stored in markdown with timestamped updates:
Voice Evidence: [quoted dialogue]
New Traits:
Relationships:
- OtherCharacter: [relationship change]
Arc Progression: [what changed]
Spoiler Notes: [sensitive information]
This plugin includes whole-vault retrieval to keep prompts relevant without manual curation. This is how the plugin maintains continuity across large manuscripts - instead of sending full book files, it retrieves relevant chunks from your entire vault.
By default, the plugin uses fast, local, deterministic retrieval:
- Hash-based embeddings: Lightweight hashed bag-of-words for semantic matching
- BM25: Lexical search engine scoring for keyword relevance
- Hybrid fusion: Combines both using reciprocal rank fusion (RRF) and diversity selection (MMR)
- No API keys required: Works entirely offline
For higher-quality semantic retrieval, you can optionally use an external embedding API:
- Supported providers: OpenAI, Cohere, Google Gemini
- Hybrid approach: External embeddings + local BM25, combined with RRF
- Default models:
- OpenAI:
text-embedding-3-small - Cohere:
embed-english-v3.0 - Google Gemini:
gemini-embedding-001
- OpenAI:
- Batch embeddings: Google Gemini supports batch endpoint for efficiency
- Fallback: Automatically falls back to local retrieval if API fails
If you have the Smart Connections plugin installed, you can optionally include its context:
- Via Bases: Reads Smart Connections Bases files automatically
- Via copied note: Reads a specific note containing Smart Connections context
- Best-effort: Never required - retrieval works perfectly without it
- You can exclude non-story folders in Settings → Writing dashboard → Retrieval.
- You can use retrieval profiles to include only specific folders (for example: story-only vs research-heavy).
- Semantic retrieval builds a local index in the background (the dashboard shows index status).
- The plugin only sends the last 20,000 words of your active manuscript (sliding window) to the AI, relying on RAG retrieval for full continuity.
These paths are configurable in settings. The names below are recommended defaults.
Characters/- One note per character (auto-updated by Character update).
- Book main file (your manuscript note)
- The active manuscript you're currently writing.
- Used to extract the sliding window (last 20,000 words) for immediate context.
- Continuity with previous books/chapters comes from RAG retrieval, not full file loads.
- Story bible path
- Canon rules, arcs, timelines, constraints.
- When you save updated story bibles, they're automatically saved to
Story bibles/folder with timestamps. - The plugin auto-updates the active story bible path when you save new versions.
- Extractions path (optional)
- Any distilled notes/summaries/constraints you want included in prompts.
<Manuscript>-Chunked/(created automatically)- Chunked copy of a manuscript note (used by the plugin's chunking and bulk workflows).
Story bibles/(created automatically when saving story bible updates)- Versioned story bible files (e.g.,
Story bible - 2024-12-20.md) - The plugin automatically uses the latest version when configured.
- Versioned story bible files (e.g.,
You can export a professional EPUB directly from the plugin:
- Open the command palette and run Export to epub.
- Default mode: compile your Book main path split by H1 (
#) chapter headings. - Optional: select TOC note mode if each chapter is a separate note.
- Choose title/author/language, optional front matter, and an optional license template.
- Output defaults to
Exports/in your vault.
Typography:
- Default styling targets Literata.
- To guarantee the font, enable Embed custom fonts and select your font files.
Font licensing note: only embed fonts you have the rights to redistribute.
Your text is sent only to the AI provider you configured when you click generate/extraction buttons. No backend server is required for this plugin.
- Ensure your API key is correctly entered in settings
- Verify the API key is valid and has credits/quota
- Check that the model name matches your provider:
- OpenAI:
gpt-4o,gpt-4o-mini, etc. - Anthropic:
claude-3-5-sonnet,claude-3-5-haiku, etc. - Gemini:
gemini-2.5-pro,gemini-2.5-flash, etc. - OpenRouter: provider-prefixed model ids like
openai/gpt-4oorgoogle/gemini-2.5-pro
- OpenAI:
- Verify your API key is correct
- Check your API provider account for rate limits
- Ensure the model name is correct for your provider
- Check your internet connection
- Verify file paths in settings match your vault structure
- Ensure files exist at the specified paths
- Check vault path is correct
- Make sure file names match exactly (case-sensitive on Mac/Linux)
- Check Ollama Status - Ensure Ollama is running (
ollama serve) and the embedding model (e.g.,nomic-embed-text) is pulled. - BM25 retrieval still works - Even if embeddings fail, the plugin uses BM25 (text-based) retrieval which works reliably.
- Check index status - Go to Settings → Writing dashboard → Retrieval to see indexing status.
- Manual Management - Use the Re-index Vault or Clear Index buttons in settings to fix corrupted states.
- Run stress test - Use the Developer Tools stress test (Settings → Writing dashboard → Developer Tools) to get detailed diagnostics.
- Check RAM Tier - Ensure your RAM tier is set correctly in Settings → Memory & Performance.
- Model Too Large - If generation causes freezes, the model may be too large for your RAM. The plugin blocks known-dangerous combinations (e.g., 70B on 16GB RAM).
- Use Safe Profile - Switch from Aggressive to Safe risk profile for more conservative context limits.
- Lower Context Slider - Move the context window slider lower (toward 50% of max) for more headroom.
- Verify Model Context - Click "Verify" in Memory & Performance to query the model's actual limit from Ollama.
- Close Other Apps - Large language models need RAM for both weights and KV cache. Close memory-heavy applications.
- This was fixed in v0.1.0. If you experience issues, try:
- Clicking in the text area again
- Restarting Obsidian
- Updating to the latest version
The plugin includes a comprehensive stress test for diagnostics:
- Go to Settings → Writing dashboard → Developer Tools
- Click "Start Stress Test"
- The test will:
- Create temporary test files
- Test all plugin operations (indexing, retrieval, AI calls, character extraction)
- Generate a detailed log with error diagnostics
- Clean up all temporary files automatically
- The log is saved as a note in your vault:
Stress Test Log - [timestamp].md
This is especially useful for diagnosing embedding/indexing issues.
cd obsidian-plugin
npm install
npm run dev
npm run build
cd obsidian-plugin
npm run build
# main.js will be created/updatedContributions are welcome! Please feel free to:
- Open issues for bugs or feature requests
- Submit pull requests
- Share feedback and suggestions
MIT License - Free to use and modify
For issues, feature requests, or questions:
- Open an issue on GitHub
- Check the plugin README for detailed usage
Note: The Python backend in the backend/ folder is legacy code and is no longer required. The plugin is now fully self-contained and makes AI API calls directly from within Obsidian.