Organic book quality: - write_chapter: strip key_events spoilers from character context so the writer doesn't know planned future events when writing early chapters - write_chapter: added next_chapter_hint — seeds anticipation for the next scene in the final paragraphs of each chapter for natural story flow - write_chapter: added DIALOGUE VOICE instruction referencing CHARACTER TRACKING speech styles so every character sounds distinctly different - Lowered SCORE_AUTO_ACCEPT 9→8 to stop over-refining already-professional drafts Speed improvements: - check_pacing: reduced from every chapter to every other chapter (~50% fewer calls) - refine_persona: reduced from every 3 to every 5 chapters (~40% fewer calls) - Resume summary rebuild: uses first + last-4 chapters instead of all chapters to avoid massive prompts when resuming mid-book - Summary context sent to writer capped at 8000 chars (most-recent events) - update_tracking text cap lowered 500000→20000 (covers any realistic chapter) Logging and progress bars: - Progress bar updates at chapter START, not just after completion - Chapter banner logged before each write so the log shows which chapter is active - Word count logged after first draft (e.g. "Draft: 2,341 words (target: ~2200)") - Word count added to chapter completion TIMING line - Pacing check now logs "Pacing OK" with reason when no intervention needed - utils: added log_banner() helper for phase separator lines UI: - run_details.html: log lines are now phase-coloured (WRITER=cyan, ARCHITECT=green, TIMING=gray, SYSTEM=yellow, TRACKER=purple, RESUME=orange, etc.) - Status bar shows current active phase (e.g. "Status: Running — WRITER") Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📚 BookApp: AI-Powered Series Engine
An automated pipeline for planning, drafting, and publishing novels using Google Gemini.
🚀 Quick Start
- Install:
pip install -r requirements.txt - Web Dependencies:
pip install -r modules/requirements_web.txt - Setup: Add your API key to
.env. - Launch Dashboard:
python -m modules.web_app - Open Browser: Go to
http://localhost:5000to create projects, manage personas, and generate books.
Alternative: CLI Mode
If you prefer the command line:
- Run
python wizard.pyto create or edit your book settings interactively. - Run
python main.py <path_to_bible.json>to generate the book(s).
🛡️ Admin Access
The application includes a protected Admin Dashboard at /admin for managing users and performing factory resets. Access is password-protected and restricted to users with the Admin role.
Method 1: Environment Variables (Recommended for Docker)
Set ADMIN_USERNAME and ADMIN_PASSWORD in your environment (or docker-compose.yml). The system will automatically create this admin account on startup.
Method 2: Manual Promotion
Register a normal account, then manually update the database row (is_admin = 1) or use a CLI script if available.
<EFBFBD> Docker Setup (Recommended for Raspberry Pi)
This is the best way to run the Web Dashboard on a server using Portainer.
1. Git Setup
- Create a new Git repository (GitHub/GitLab).
- For local servers like Gitea, your URL will be something like
http://10.0.0.102:3000/thethreemagi/bookapp.git.
- For local servers like Gitea, your URL will be something like
- Push this project code to the repository.
- IMPORTANT: Ensure
.env,token.json,credentials.json, and thedata/folder are in your.gitignore. Do not commit secrets to the repo.
- IMPORTANT: Ensure
2. Server Preparation (One-Time Setup)
Since secrets and database files shouldn't be in Git, you need to place them on your server manually.
- Authenticate Locally: Run the app on your PC first (
python wizard.py) to generate thetoken.jsonfile (Google Login). - SSH into your server and create a folder for your app data:
mkdir -p /opt/bookapp # Or any other path you prefer - Upload Files: Use WinSCP or SCP to upload these two files from your PC to the folder you just created (e.g.,
/opt/bookapp):token.json(Generated in step 1)credentials.json(Your Google Cloud OAuth file) Thedatasubfolder, which stores your database and projects, will be created automatically by Docker when the container starts.
3. Portainer Stack Setup
-
Log in to Portainer.
-
Go to Stacks > Add stack.
-
Select Repository.
- Repository URL:
http://10.0.0.102:3000/thethreemagi/bookapp.git - Compose path:
docker-compose.yml
- Repository URL:
-
Enable Authentication: Since your Gitea repository is private, you will need to provide credentials.
- Toggle on Authentication.
- Username: Your Gitea username (
thethreemagi). - Password: Use a Personal Access Token from Gitea, not your actual password.
- In Gitea, go to your User Settings > Applications and generate a new token with repository read access.
-
Under Environment variables, add the following:
HOST_PATH:/opt/bookapp(The folder you created in Step 2)GEMINI_API_KEY:<your-api-key>ADMIN_USERNAME:admin(Or your preferred username)ADMIN_PASSWORD:<secure-password-for-web-ui>FLASK_SECRET_KEY:<random-string>FLASK_DEBUG:False(Set toTrueonly for troubleshooting)
Optional (Advanced / Vertex AI):
GCP_PROJECT: Your Google Cloud Project ID (Required for Imagen 3/Vertex AI).GCP_LOCATION:us-central1(Default).MODEL_LOGIC: Override the logic model (e.g.,models/gemini-1.5-pro-latest).MODEL_WRITER: Override the writer model.
-
Click Deploy the stack.
Portainer will pull the code from Git, build the image, and mount the secrets/data from your server folder.
4. Updating the App
To update the code:
- Run the app on your PC first (using
python wizard.pyormain.py). - Push changes to Git.
- In Portainer, go to your Stack.
- Click Editor > Pull and redeploy.
📂 How to Manage Files (Input/Output)
The Docker setup uses a Volume to map the container's internal /app/data folder to a folder on your server. This path is defined by the HOST_PATH variable you set in Portainer.
- To Add Personas/Fonts: On your server, place files into the
${HOST_PATH}/data/personas/or${HOST_PATH}/data/fonts/folders. The app will see them immediately. - To Download Books: You can download generated EPUBs directly from the Web Dashboard.
- To Backup: Just create a backup of the entire
${HOST_PATH}directory on your server. It contains the database, all projects, and generated books.
🐍 Native Web Setup (Alternative)
If you prefer to run the web app without Docker:
- Install Web Dependencies:
pip install -r modules/requirements_web.txt - Start the App:
python -m modules.web_app - Access: Open
http://localhost:5000in a browser.
<EFBFBD>️ Features
- Interactive Wizard: Create new books, series, or sequels. Edit existing blueprints with natural language commands.
- Modular Architecture: Logic is split into specialized modules for easier maintenance and upgrades.
- Smart Resume: If a run crashes, simply run the script again. It detects progress and asks to resume.
- Marketing Assets: Automatically generates a blurb, back cover text, and a cover image.
- Rich Text: Generates EPUBs with proper formatting (Bold, Italics, Headers).
- Consistency Checker: Scans the manuscript for plot holes and continuity errors.
- Manual Editing: Read and edit chapters directly in the browser; changes are preserved during file regeneration.
- Metadata Sync: Updates the "Story Bible" based on your manual edits to the text.
- Dynamic Structure: Automatically adapts the plot structure (e.g., "Hero's Journey" vs "Single Scene") based on the book length.
- Series Support: Automatically carries context, characters, and plot threads from Book 1 to Book 2, etc.
📂 Project Structure
Core Files
wizard.py: The interactive command-line interface for creating projects, managing personas, and editing the "Book Bible".main.py: The execution engine. It reads the Bible JSON and orchestrates the generation process using the modules.config.py: Central configuration for API keys, file paths, and model settings.utils.py: Shared utility functions for logging, JSON handling, and file I/O.
Modules (/modules)
ai.py: Handles authentication and connection to Google Gemini and Vertex AI.story.py: Contains the creative logic: enriching ideas, planning structure, and writing chapters.marketing.py: Generates cover art prompts, images, and blurbs.export.py: Compiles the final manuscript into DOCX and EPUB formats.
Data Folders
data/personas/: Stores author personas and writing samples.data/fonts/: Caches downloaded fonts for cover art.
<EFBFBD> Length Settings Explained
The Length Settings control not just the word count, but the structural complexity of the story.
| Type | Approx Words | Chapters | Description |
|---|---|---|---|
| Flash Fiction | 500 - 1.5k | 1 | A single scene or moment. |
| Short Story | 5k - 10k | 5 | One conflict, few characters. |
| Novella | 20k - 40k | 15 | Developed plot, A & B stories. |
| Novel | 60k - 80k | 30 | Deep subplots, slow pacing. |
| Epic | 100k+ | 50 | Massive scope, world-building focus. |
Note: This engine is designed for linear fiction. It does not currently support branching narratives like "Choose Your Own Adventure" books.
📂 Data Structure & File Dictionary
The application stores all data in the data/ directory. This makes backup and migration easy.
Folder Hierarchy
data/
├── users/
│ └── {user_id}/ # User-specific data
│ └── {Project_Name}/ # Project Root
│ ├── bible.json # Project Source of Truth
│ └── runs/ # Generation History
│ └── run_{id}/ # Specific Job/Run
│ ├── web_console.log
│ └── Book_{N}_{Title}/ # Generated Book Artifacts
│ ├── manuscript.json
│ ├── tracking_events.json
│ ├── {Title}.epub
│ └── ...
├── personas/ # Global Author Personas
│ └── personas.json
├── fonts/ # Cached Google Fonts
└── style_guidelines.json # Global AI Writing Rules
File Dictionary
| File | Scope | Description |
|---|---|---|
bible.json |
Project | The master plan. Contains the series title, author metadata, full character list, and the high-level plot outline for every book in the series. |
manuscript.json |
Book | The Book. A JSON array containing the raw text of every chapter written so far. Used to resume generation if interrupted. |
events.json |
Book | The structural outline (e.g., Hero's Journey beats) generated by the Architect. |
chapters.json |
Book | The detailed writing plan. Lists every chapter with its title, POV character, pacing, and estimated word count. |
tracking_events.json |
Book | The "Story So Far". Contains a cumulative summary of the plot and a log of key events to ensure continuity. |
tracking_characters.json |
Book | Tracks the current state of characters (e.g., "wearing a red dress", "lost an arm") to ensure visual consistency. |
final_blueprint.json |
Book | The final metadata state after the book is finished. Includes any new characters or plot points invented during writing. |
usage_log.json |
Book | A detailed report of AI token usage and estimated cost for this specific book. |
cover_art_prompt.txt |
Book | The exact prompt sent to the image generator (Imagen/Vertex) to create the cover. |
{Title}.epub |
Book | The compiled eBook file, ready for Kindle/Apple Books. |
{Title}.docx |
Book | The compiled Word document for editing. |
📖 JSON Data Schemas
Details on the internal structure of key data files.
bible.json
Located at the root of the project folder.
{
"project_metadata": {
"title": "Series Title",
"author": "Author Name",
"genre": "Sci-Fi",
"is_series": true,
"style": {
"tone": "Dark",
"pov_style": "Third Person Limited"
}
},
"characters": [
{
"name": "John Doe",
"role": "Protagonist",
"description": "Physical and personality details..."
}
],
"books": [
{
"book_number": 1,
"title": "Book One Title",
"manual_instruction": "High-level plot summary...",
"plot_beats": ["Beat 1", "Beat 2"]
}
]
}
manuscript.json
Located in each Book_X folder.
[
{
"num": 1,
"title": "Chapter Title",
"pov_character": "John Doe",
"content": "# Chapter 1\n\nThe raw markdown text of the chapter..."
}
]
tracking_characters.json
Located in each Book_X folder. Updates dynamically.
{
"Character Name": {
"descriptors": ["Blue eyes", "Tall"],
"likes_dislikes": ["Loves coffee"],
"last_worn": "Red dress (Ch 4)",
"major_events": ["Injured leg in Ch 2"]
}
}