- web/tasks.py: db_log_callback now writes non-OperationalError exceptions to data/app.log for visibility
- web/tasks.py: generate_book_task restructured with try...finally to guarantee final status update — run can never be left in 'running' state if worker crashes
- templates/project.html: added .catch() to fetchLog() with console.error + polling resume on failure; added manual Refresh button to status bar
- templates/run_details.html: improved .catch() in updateLog() with descriptive message + 5s retry; added manual Refresh button to status bar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- web/tasks.py: db_log_callback bare `except: break` replaced with
explicit `except Exception as _e: print(...)` so insertion failures
are visible in Docker logs. Also fixed datetime.utcnow() → .isoformat()
for clean string storage in SQLite.
Same fix applied to db_progress_callback.
- web/routes/run.py (run_status): added db.session.expire_all() to
force fresh reads; raw sqlite3 bypass query when ORM returns no rows;
file fallback wrapped in try/except with stdout error reporting;
secondary check for web_console.log inside the run directory;
utf-8 encoding on all file opens.
- ai_blueprint.md: bumped to v2.11, documented root causes and fixes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: Consumer(huey, workers=1, worker_type='thread', loglevel=20)
raised TypeError on every app start because Huey 2.6.0 does not accept
a `loglevel` keyword argument. The exception was silently caught and only
printed to stdout, so the consumer never ran and all tasks stayed 'queued'
forever — causing the 'Preparing environment / Waiting for logs' hang.
Fixes:
- web/app.py: Remove invalid `loglevel=20` from Consumer(); configure
Huey logging via logging.basicConfig(WARNING) instead. Add persistent
error logging to data/consumer_error.log for future diagnosis.
- core/config.py: Replace emoji print() calls with ASCII-safe equivalents
to prevent UnicodeEncodeError on Windows cp1252 terminals at import time.
- core/config.py: Update VERSION to 2.9 (was stale at 1.5.0).
- ai_blueprint.md: Bump to v2.10, document root cause and fixes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ai/setup.py: Added threading import; OAuth block now detects background/headless
threads and skips run_local_server to prevent indefinite blocking. Logs a clear
warning and falls back to ADC for Vertex AI. Token file only written when creds
are not None.
- web/tasks.py: All sqlite3.connect() calls now use timeout=30, check_same_thread=False.
OperationalError on the initial status update is caught and logged via utils.log.
generate_book_task now touches initial_log immediately so the UI polling endpoint
always finds an existing file even if the worker crashes on the next line.
- ai_blueprint.md: Bumped to v2.9; Section 12.D sub-items 1-3 marked ✅; item 13
added to summary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Added Section 12 to ai_blueprint.md covering:
- A: API timeout hangs (ai/models.py 180s, ai/setup.py 30s, removed cascading init call)
- B: Huey consumer never started under flask/gunicorn (module-level start + reloader guard)
- C: 'Create new book not showing anything' — 3 root causes fixed:
(4) Jinja2 UndefinedError on s.tropes|join in project_setup.html
(5) Silent redirect when model_logic=None now renders form with defaults
(6) planner.enrich() called with wrong bible structure in create_project_final
Bumped blueprint version from v2.7 → v2.8.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sections 1 (RAG for Lore/Locations) and 2 (Thread Tracking) still showed
⏳ despite being fully implemented under Sections 8 and 9 in v2.5.
Updated both to ✅ with accurate implementation notes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- story/planner.py: enrich() and plan_structure() now extract series_metadata
and inject a SERIES_CONTEXT block (Book X of Y in series Z, with position-aware
guidance) into prompts when is_series is true.
- story/writer.py: write_chapter() builds and injects the same SERIES_CONTEXT
into the chapter draft prompt; passes series_context to evaluate_chapter_quality().
- story/editor.py: evaluate_chapter_quality() accepts optional series_context
parameter and injects it into METADATA so arc pacing is evaluated relative to
the book's position in the series.
- ai_blueprint.md: Section 11 marked complete (v2.7), summary updated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Appended entries from ai_blueprint.md guidelines to exclude AI planning
files, context indexes, and assistant directories from version control:
- ai_blueprint.md and plans/
- .claude/, .gemini/, .roo/, .cline/, .cursor/, .cascade/, .windsurfrules
- *.aiindex, ai_workspace_index.json
Also untracks the already-committed .claude/ and ai_blueprint.md files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>