Skip to content

Commit e38648d

Browse files
v0.2.0: standalone viewer as app, narratology runtime, rename tvplotlines → tvplot (#1)
* Add HTML build script and shell template for standalone viewer Build script assembles shell.html + parts (CSS, JS, demo data) into a single self-contained HTML file. Three-screen layout: welcome, grid, analytics with modal container and placeholder slots. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: build.py concatenates all JS parts, not just app.js * Port CSS from tvplotlines-app for standalone HTML viewer Keep battle-tested styles: color palette (light + Catppuccin Mocha dark), function colors, rank badges, tension variables, grid layout, analytics. Remove HTMX/edit-mode/merge/split styles (v1 is read-only). Add screen routing, welcome screen, and toolbar/navigation styles. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add grid rendering and app init for standalone HTML viewer Port plotline x episode grid from tvplotlines-app Jinja2 template to vanilla JS. Includes event grid lookup, character resolution, guest detection, rank sorting, function legend filtering, season/character filters, and read-only event detail modal. App.js handles screen routing, dark mode persistence, demo data loading, and file upload. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add analytics rendering with 5 sections ported from tvplotlines-app Port computation (analytics.py) and rendering (analytics.html) to standalone JS: scorecard, arc map, episode pulse, convergence moments, character weight. Wire up Analytics button in app.js. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add router, localStorage Store, toolbar, and JSON import Store object centralizes all localStorage access (API keys, results, settings, onboarding state). Toolbar now has series dropdown, Grid/Analytics tab buttons, dark mode toggle, load/export/LLM/onboarding placeholders. Series switching re-renders current view and persists last selection. Drop zone overlay supports drag-and-drop and file picker for JSON import. Init logic checks onboarding state and restores last session. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add export functions: JSON, TXT, CSV, Final Draft .fdx Export dropdown in toolbar with 4 formats. Single floating menu shared between grid and analytics screens. CSV chosen over XLS to avoid SheetJS dependency — includes both events and plotlines summary. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add LLM pipeline for browser-side plotline extraction Implement pipeline.js with streaming API client (Anthropic + OpenAI), all 5 passes with embedded prompts, post-processing, and synopsis file upload. Wire drop zone to accept .txt synopses alongside JSON, add LLM settings dialog, and pipeline progress overlay. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: dark mode CSS, inciting_incident styling, analytics header, episode labels - Force color-scheme to prevent Firefox dark mode override - .hidden !important to fix drop zone appearing on load - inciting_incident: no background, bright green text - crisis function color added - Story engine / logline moved above all analytics sections - Episode numbers shown once in scorecard header - Episode Pulse: removed themes, added plotline color legend Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add --html and --html-output flags to CLI run command Generate a standalone HTML viewer alongside the result JSON when --html is passed. Uses build_html() from the html module. Defaults to saving next to the JSON with .html extension; --html-output overrides the path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add minimal welcome screen with first-visit detection Japanese minimalism aesthetic: lightweight typography, pill-shaped "Play me" button, subtle "Skip" link. First visit shows welcome, returning visits skip straight to grid. Smooth fade-out transition. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add onboarding animation that demos full pipeline on real UI Animated walkthrough plays on actual app screens using Breaking Bad demo data: LLM settings modal, file upload, pipeline progress, grid reveal, analytics tour, and export. Ends with real LLM modal so user can connect their key. Skip link aborts animation cleanly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: consolidate hollywood and narratology prompts under one system parameter - Rename prompts_en/ to prompts/hollywood/ - Import 8 narratology prompts (formerly tvplotlines_narratology repo) into prompts/narratology/ - Drop prompts_ru/ entirely — Russian support out of current scope - Replace lang parameter with system across library: get_plotlines, LLMConfig, CLI - Narratology pipeline raises NotImplementedError for now; prompts in place for v2 - Copy schema.md into docs/layered-schema.md (base + layers JSON design) - Update pyproject.toml artifacts, example, tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(narratology): thread stable event ids through passes 2–6 - Pass 2: every event gets id {episode}#{index:02d} and keeps it downstream - Passes 4–6: reference events by id, not by description - Pass 5 mre: event_id instead of episode+description - glossary: plain-English actant names (who_chases, bigger_force, …) now mapped to their Greimas terms (subject, power, …) - docs/layered-schema.md aligned with prompt output Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(viewer): turn the HTML viewer into an end-to-end app - Welcome screen now has an "Analyze a series" form (show + season). Clicking Analyze asks the configured LLM for episode synopses from its training memory, shows them in an editable preview modal, then runs the 5-pass pipeline on whatever the user confirms. - LLM settings modal gains an "Analysis system" selector. Hollywood is live; Narratology is disabled with a "coming soon" note until its runtime lands in v2. - Exports: added "PDF (via print)" that calls window.print(); a print stylesheet hides the toolbar/modals and lays the grid out in landscape, so Cmd+P → "Save as PDF" produces a usable document. - Drag-and-drop .txt flow unchanged — it's the fallback when the model doesn't know the show. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: v2 scope — narratology runtime, prompt inlining, native PDF, knowledge move 1. Narratology pipeline is now runnable, Python and browser both: - src/tvplotlines/narratology.py runs all six passes (context → fabula → actants → story → arc → review) and maps results into the existing TVPlotlinesResult shape so the viewer renders either system unchanged - pipeline.js grows runPipelineNarratology mirroring the Python orchestrator (per-episode and per-plotline passes parallelised), and the top-level runPipeline dispatches on the user's system choice - The "Narratology" option in LLM settings is enabled 2. Viewer prompts are no longer hardcoded. build.py reads every prompts/{hollywood,narratology}/*.md at build time and injects them as a _PROMPTS object, eliminating drift between source prompts and the viewer 3. Native PDF export — jsPDF is lazy-loaded from CDN and generates a vector PDF from the loaded result (title, per-plotline sections with actants/ story-DNA + event list, episode appendix). Falls back to window.print() when offline 4. Knowledge consolidated from 3-resources/tvplotlines/ into docs/knowledge/ (decisions, specs, theory, prompting, results, v3_narratology evergreens, archive). Personal artifacts stay in place All 115 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(repo): pull internal docs back to 3-resources, rewrite README - docs/knowledge/ — moved to 3-resources/tvplotlines/. Knowledge, evergreens, autoresearch drafts, and strategy notes belong out of the public repo. Personal artifacts already lived there - docs/viewer/{spec,plan,decisions}.md — internal Russian planning docs, moved to 3-resources/tvplotlines/viewer-planning/ - .gitignore — exclude Untitled.md draft and the dacomply compliance/ scan output so they can sit in the working tree without leaking - README — rewrite to reflect the current code: hollywood + narratology systems with the --system flag, standalone HTML viewer mode, the "Analyze a series" entry flow, --html/--html-output, narratology's six-pass table, fixed the broken license badge and the dead prompts_en/glossary.md link Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: sync docs/ with the current code (hollywood + narratology) - api.md: get_plotlines signature gains `system`, `skip_review`, `base_url`, `suggested_plotlines`; new system-comparison table; Plotline gets reviewed_rank/computed_rank/nature/confidence, Event gets plot_fn; full CLI flag table for run + write-synopses - quickstart.md: --system and --html flags, standalone-viewer section with "Analyze a series" flow, system switch in Python example - index.md: mentions standalone viewer + layered-schema link - formulas.md: Pass 4 section (was missing), narratology pipeline section at the end documenting all six passes and the actant ↔ hero/goal/obstacle/stakes mapping Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: drop gitignore entries for drafts now moved out Untitled.md and compliance/ live in 3-resources/tvplotlines/ alongside the rest of the private notes; they don't need to be ignored here any more. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add AI disclosure, methodology, and viewer footer Address the compliance scan items that actually apply to an installable library with no hosted service: - docs/ai-disclosure.md — single source of truth for data flow, vendor policies, and user rights. Alpine Animation (Switzerland) is named as publisher; we collect nothing. Names the three synopsis paths (user-supplied, Wikipedia-scraped via write-synopses, and the browser's "Analyze a series" flow), covers Anthropic AUP and OpenAI Usage Policies compliance, and records a use-case paper trail - docs/methodology.md — plain-language Art. 50 explainer written from the code (pipeline.py, narratology.py, pass*.py, postprocess.py), not the dacomply template. Points to formulas.md for line-by-line rules - README gains a "How this uses AI" section linking both docs - HTML viewer shows a dismissible AI-assisted-content footer naming the model family and Alpine Animation; dismissal persists in localStorage; footer is hidden at print time so PDF exports stay clean Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add 411@alpineanimation.ch as contact Alongside GitHub issues — gives data-subject and methodology requests a direct channel to the publisher, which is what the compliance scan flagged as missing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: obfuscate contact email against naive scrapers Replace <411@alpineanimation.ch> with "411 [at] alpineanimation [dot] ch". Defeats ~80–90% of off-the-shelf email harvesters that look for mailto: links or @-symbols; humans read it without effort. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: switch contact to purpose-specific alias tvplotlines@alpineanimation.ch — easy to kill and recreate if it ever gets scraped, which is a better strategy than trying to obfuscate a shared catch-all mailbox. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: rename tvplotlines → tvplot Shorter, snappier. PyPI name, import path, CLI command (tvplot run), env vars (TVPLOT_*), localStorage keys, and all docs move in one step. Version bumps to 0.2.0 and CHANGELOG carries a BREAKING migration note. What changes externally: - pip install tvplot - from tvplot import get_plotlines - tvplot run my-show/ --system narratology - TVPLOT_OUTPUT_DIR, TVPLOT_SYNOPSES_DIR What stays: - Public API surface (get_plotlines signature, Plotline/Event models) - All pipeline logic and prompts - Existing result JSONs remain valid Rationale: no meaningful users yet on PyPI (80%+ of the 0.1.0 download count is bots and scanners), the rename is much cheaper now than after promotion. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0fd057e commit e38648d

81 files changed

Lines changed: 8653 additions & 3007 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
11
# Changelog
22

3-
## Unreleased
3+
## 0.2.0 — 2026-04-15
4+
5+
### Changed — BREAKING
6+
- **Package renamed `tvplotlines``tvplot`.** PyPI package, import path, CLI command, env vars, and localStorage keys all move. Migration: `pip install tvplot` and replace imports `from tvplotlines …``from tvplot …` and CLI invocations `tvplotlines run``tvplot run`. Env vars `TVPLOTLINES_OUTPUT_DIR` / `TVPLOTLINES_SYNOPSES_DIR` renamed to `TVPLOT_OUTPUT_DIR` / `TVPLOT_SYNOPSES_DIR`. `tvplotlines 0.1.0` on PyPI will be yanked with a "renamed to tvplot" notice.
7+
8+
### Added
9+
- **AI-use, privacy, and methodology docs**`docs/ai-disclosure.md` documents the data flow (nothing reaches Alpine Animation — your inputs and API key travel straight from your machine to the LLM vendor), lists Anthropic's and OpenAI's applicable policies, and records a paper-trail for vendor-policy compliance. `docs/methodology.md` is the plain-language Art. 50 description of how the pipeline decides, what it can't do, and where to read the code. README links both, and the standalone HTML viewer carries a dismissible AI-assisted-content footer.
10+
- **Narratology pipeline — runnable**. New module `src/tvplot/narratology.py` implements all six passes (context, fabula, actants, story, arc, review). Results are emitted in the existing `TVPlotlinesResult` shape so the HTML viewer renders hollywood and narratology output unchanged. Actants (`who_chases`, `what_they_chase`, `stands_in_the_way`, `who_wins_if_it_works`) map onto `hero`, `goal`, `obstacle`, `stakes`. Pass 5 arc functions land in `Event.plot_fn`. Pass 6 verdicts apply in-place (MERGE/DROP/REASSIGN/REFUNCTION) and reviewed ranks override computed ranks.
11+
- **Narratology in the browser viewer**. `runPipelineNarratology` in `pipeline.js` mirrors the Python orchestrator, runs all six passes via browser LLM calls (per-episode passes parallelised with `Promise.all`), and produces the same hollywood-compatible shape. `runPipeline` dispatches on the user's system choice. The "Narratology" option in LLM settings is now enabled.
12+
- **Prompts inlined at build time**. `src/tvplot/html/build.py` reads every `prompts/{hollywood,narratology}/*.md` and injects them into the HTML as a `_PROMPTS` object, so the viewer no longer carries a hardcoded copy that could drift from the source.
13+
- **"Analyze a series" entry flow** in the HTML viewer. Welcome screen now takes a show name + season; the viewer asks the configured LLM for episode synopses, shows them in an editable preview, then runs the normal pipeline. Download the single HTML and you have an end-to-end app. Fallback — drag-and-drop `.txt` synopses — still works.
14+
- **Native PDF export** via lazy-loaded jsPDF (CDN). Generates a vector PDF directly from the loaded result: title page, per-plotline sections with actant/story-DNA fields and event lists, and an episode-by-episode appendix. Falls back to the browser print stack if the library can't be fetched (offline).
15+
- **Knowledge consolidated into the repo**. `3-resources/tvplot/*``docs/knowledge/` with `decisions/` (ADR 001-005), `specs/` (architecture, per-pass specs, mas4bw audit), `theory/`, `prompting/`, `results/` (reference BB S01-S05 outputs), `v3_narratology/` (67 evergreen notes across 9 sources), and `archive/` (old autoresearch + plans). Personal artifacts (the book and friends-post) stay in `3-resources/tvplot/`.
16+
17+
### Changed
18+
- **Prompt layout**: `prompts_en/``prompts/hollywood/`. Added `prompts/narratology/` from the former sister project, bundling eight structuralist prompts (context, fabula, actants, story, arc, review, synopses_writer, glossary). `docs/layered-schema.md` documents the shared `base + layers` JSON.
19+
- **Library API**: `get_plotlines(..., lang=)` replaced by `get_plotlines(..., system=)` (values: `"hollywood"` default, `"narratology"`). `LLMConfig.lang``LLMConfig.system`. CLI: `tvplot run --lang``--system`; `write-synopses --system` added.
20+
- Narratology pipeline is not yet runnable — `system="narratology"` raises `NotImplementedError` with a clear message. Prompts are in place; runners come in v2.
21+
22+
### Removed
23+
- **Russian prompts** (`prompts_ru/`) — out of scope. Will be reintroduced once both analysis systems stabilise in English.
24+
- Sister repo `tvplot_narratology/` merged into this repo under `src/tvplot/prompts/narratology/`.
425

526
### Added
627
- **Pass 4: arc functions** (`plot_fn`) — each event gets a season-arc role alongside its episode function. Pass 4 runs per-plotline, sees episode functions as context.
@@ -15,7 +36,7 @@
1536
- **CLI**: `--stop-after pass1` saves intermediate JSON, `--resume-from` resumes from it
1637
- **CLI**: `--output-dir` saves timestamped copy of results
1738
- **CLI**: `--no-glossary`, `--no-fandom`, `--fandom-wiki` flags for write-synopses
18-
- **Environment variables**: `TVPLOTLINES_OUTPUT_DIR`, `TVPLOTLINES_SYNOPSES_DIR` — default output locations
39+
- **Environment variables**: `TVPLOT_OUTPUT_DIR`, `TVPLOT_SYNOPSES_DIR` — default output locations
1940
- **Rules and formulas reference**: `docs/formulas.md`
2041
- Chain-of-thought nudge in all prompts before OUTPUT section
2142

@@ -56,4 +77,4 @@ Initial open-source release.
5677
- Multi-season continuity via `prior` parameter
5778
- Providers: Anthropic (default), OpenAI, Ollama, DeepSeek, Groq, any OpenAI-compatible API
5879
- Pass 2 modes: parallel, batch (50% cheaper), sequential
59-
- CLI: `tvplotlines run`
80+
- CLI: `tvplot run`

CONTRIBUTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
## Setup
44

55
```bash
6-
git clone https://github.com/BirdInTheTree/tvplotlines.git
7-
cd tvplotlines
6+
git clone https://github.com/BirdInTheTree/tvplot.git
7+
cd tvplot
88
pip install -e ".[dev]"
99
```
1010

@@ -21,7 +21,7 @@ Tests use mocked LLM responses — no API key needed.
2121
- Python 3.11+
2222
- Type hints on public functions
2323
- `verb_noun` naming: `extract_plotlines`, `detect_context`
24-
- Prompts live in `src/tvplotlines/prompts_en/` as markdown files
24+
- Prompts live in `src/tvplot/prompts_en/` as markdown files
2525

2626
## Pull requests
2727

README.md

Lines changed: 93 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,84 @@
1-
# tvplotlines
1+
# tvplot
22

3-
[![PyPI](https://img.shields.io/pypi/v/tvplotlines?cacheSeconds=3600)](https://pypi.org/project/tvplotlines/)
4-
[![License](https://img.shields.io/github/license/BirdInTheTree/tvplotlines?cacheSeconds=3600)](LICENSE)
5-
[![Python](https://img.shields.io/pypi/pyversions/tvplotlines?cacheSeconds=3600)](https://pypi.org/project/tvplotlines/)
3+
[![PyPI](https://img.shields.io/pypi/v/tvplot?cacheSeconds=3600)](https://pypi.org/project/tvplot/)
4+
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5+
[![Python](https://img.shields.io/pypi/pyversions/tvplot?cacheSeconds=3600)](https://pypi.org/project/tvplot/)
66

7-
Turn episode synopses into a writers' room corkboard — story engine, plotlines with their *story DNA* and *arcs* (see definitions in [glossary](src/tvplotlines/prompts_en/glossary.md)) — in one function call.
7+
Turn episode synopses into a writers' room corkboard — story engine, plotlines with their *story DNA* and *arcs* (see [glossary](src/tvplot/prompts/hollywood/glossary.md)) — in one function call.
88

99
For TV researchers, screenwriters, and anyone building narrative analysis tools or a tv series.
1010

1111
<p align="center">
1212
<a href="https://birdinthetree.github.io/plotter-app/">
13-
<img src="docs/images/app-screenshot-1.png" alt="tvplotlines output — plotline×episode grid for Breaking Bad S01">
13+
<img src="docs/images/app-screenshot-1.png" alt="tvplot output — plotline×episode grid for Breaking Bad S01">
1414
</a>
1515
<br>
1616
<strong><a href="https://birdinthetree.github.io/plotter-app/">Try the interactive demo →</a></strong>
1717
</p>
1818

19-
A naive LLM prompt covers 5–12% of a season's source material. tvplotlines covers **78–91%** — by separating *what* the model looks for (narrative theory) from *how* it calculates the results (code).
19+
A naive LLM prompt covers 5–12% of a season's source material. tvplot covers **78–91%** — by separating *what* the model looks for (narrative theory) from *how* it calculates the results (code).
2020

21-
## Quick start
21+
## Two ways to use it
22+
23+
**Library / CLI**`pip install tvplot`, point it at synopsis files, get JSON.
24+
25+
**Standalone HTML viewer** — one self-contained `.html` file that runs the whole pipeline in your browser. Type a show name, the viewer asks the LLM for synopses, runs the analysis, and renders the grid. No server, no dependencies — download the file and it works.
26+
27+
## Quick start (CLI)
2228

2329
```bash
24-
pip install tvplotlines
30+
pip install tvplot
2531
export ANTHROPIC_API_KEY=sk-ant-…
2632
```
2733

2834
Working on your own series? Point it at your synopses — one `.txt` file per episode (see [Input format](#input-format)):
2935

3036
```bash
31-
tvplotlines run my-series/
37+
tvplot run my-series/
3238
```
3339

3440
Want to analyze an existing show? The optional `writer` extension generates synopses from online sources:
3541

3642
```bash
37-
pip install 'tvplotlines[writer]'
38-
tvplotlines write-synopses "Mad Men" --season 1
39-
tvplotlines run mad-men/
43+
pip install 'tvplot[writer]'
44+
tvplot write-synopses "Mad Men" --season 1
45+
tvplot run mad-men/
46+
```
47+
48+
Generate a standalone HTML viewer alongside the JSON:
49+
50+
```bash
51+
tvplot run mad-men/ --html # writes mad-men.json + mad-men.html
52+
tvplot run mad-men/ --html-output viewer.html
4053
```
4154

4255
Multiple seasons are supported — plotline continuity is tracked across seasons (see [Python API](#python-api)).
4356

4457
Pre-computed results are in [`examples/results/`](examples/results/) — explore the output without spending API credits.
4558

59+
## Quick start (standalone viewer)
60+
61+
```bash
62+
python -m tvplot.html.build --output tvplot.html
63+
open tvplot.html
64+
```
65+
66+
Then in the browser:
67+
68+
1. Click **LLM** in the toolbar, paste your Anthropic or OpenAI key, pick an analysis system.
69+
2. On the welcome screen, type a show name and season → click **Analyze**.
70+
3. The viewer asks the model for episode synopses, lets you preview/edit them, and runs the pipeline.
71+
4. Export the result as JSON, CSV, Final Draft (`.fdx`), or PDF.
72+
73+
If the model doesn't know the show, drop your own `.txt` synopsis files via the **+ Load** button.
74+
4675
## What you get
4776

4877
One JSON file per season. Each contains:
4978

5079
- **Cast** — characters with aliases
5180
- **Plotlines** — with A/B/C ranking, Story DNA (hero, goal, obstacle, stakes), and episode span
52-
- **Events** — per-episode, assigned to plotlines with narrative function (setup → inciting incident → escalation → crisis → climax → resolution)
81+
- **Events** — per-episode, assigned to plotlines with episode-level function and season-level arc function
5382

5483
<details>
5584
<summary>Example: Breaking Bad S01 (truncated)</summary>
@@ -85,6 +114,7 @@ One JSON file per season. Each contains:
85114
"event": "During the meth lab raid, Walt spots his former student Jesse escaping through a window",
86115
"plotline_id": "empire",
87116
"function": "inciting_incident",
117+
"plot_fn": "inciting_incident",
88118
"characters": ["walt", "jesse"]
89119
}
90120
]
@@ -97,9 +127,11 @@ One JSON file per season. Each contains:
97127

98128
## How it works
99129

100-
### Plotline extraction (`tvplotlines run`)
130+
You pick an **analysis system** with `--system` (CLI) or the LLM Settings dialog (viewer). Both systems share the same input format and output the same `TVPlotlinesResult` shape, so the viewer renders either one.
101131

102-
Five LLM passes, each with a specialized prompt:
132+
### Hollywood — screenwriting model (default)
133+
134+
Story DNA — hero, goal, obstacle, stakes — and Freytag's seven dramatic functions. Five LLM passes:
103135

104136
| Pass | Role | Output | Calls |
105137
|------|------|--------|-------|
@@ -111,15 +143,32 @@ Five LLM passes, each with a specialized prompt:
111143

112144
Pass 1 runs 3× in parallel and picks the most common plotline set. Pass 3 sees the full picture no earlier pass had and corrects structural problems. Pass 4 assigns arc-level functions — an event that was a climax in episode 3 might be an escalation in the season-long arc.
113145

146+
### Narratology — structuralist model
147+
148+
Bal's three layers, Greimas's actant model (subject/object/helper/opponent/power/receiver), Bremond's narrative cycle, Labov's reportability. Six LLM passes:
149+
150+
| Pass | Role | Output | Calls |
151+
|------|------|--------|-------|
152+
| **1 context** | Format, story schema, breach, protagonists | Show-level context | 1 |
153+
| **2 fabula** | Per-episode events as state transitions, with stable ids | Bare events + cast | 1 per episode |
154+
| **3 actants** | Plotlines via the actant model (anti-subject test) | Plotlines | 1 |
155+
| **4 story** | Per-event episode function and direction; theme | Story-level event tags | 1 per episode |
156+
| **5 arc** | Season arc function, drive vs texture, MRE per plotline | Season-level event tags | 1 per plotline |
157+
| **6 review** | Verdicts and ranks | Structural corrections | 1 |
158+
159+
The actant fields (`who_chases`, `what_they_chase`, `stands_in_the_way`, `who_wins_if_it_works`) map onto the same `hero / goal / obstacle / stakes` slots, so existing tools that consume `TVPlotlinesResult` see no schema change.
160+
161+
The schema document at [`docs/layered-schema.md`](docs/layered-schema.md) describes a richer `base + layers` JSON form for keeping multiple systems' analyses of the same season side by side.
162+
114163
### Synopsis generation (`write-synopses`)
115164

116165
The `writer` extension collects raw episode data from online sources, then rewrites each episode into a full synopsis via LLM — ensuring every sentence is a beat (conflict or change), with explicit causality and character names.
117166

118-
Tested with Claude Sonnet (default). OpenAI and Ollama supported for both pipelines. Ollama defaults to Qwen 2.5 14B — chosen to run on CPU without a GPU. Quality is noticeably lower than cloud models but works for experimentation.
167+
Tested with Claude Sonnet (default). OpenAI and Ollama supported for both pipelines and both analysis systems. Ollama defaults to Qwen 2.5 14B — chosen to run on CPU without a GPU. Quality is noticeably lower than cloud models but works for experimentation.
119168

120169
## Input format
121170

122-
One `.txt` file per episode. Include `S01E01`, `S01E02`, etc. in the filename. Each file is a plain-text (.txt) synopsis — 150–500 words covering the main events.
171+
One `.txt` file per episode. Include `S01E01`, `S01E02`, etc. in the filename. Each file is a plain-text synopsis — 150–500 words covering the main events.
123172

124173
```
125174
breaking-bad/
@@ -131,46 +180,63 @@ breaking-bad/
131180
The folder name becomes the show title. Override with `--show`:
132181

133182
```bash
134-
tvplotlines run got/ --show "Game of Thrones"
183+
tvplot run got/ --show "Game of Thrones"
135184
```
136185

137186
## Python API
138187

139188
```python
140-
from tvplotlines import get_plotlines
189+
from tvplot import get_plotlines
141190

142191
s01 = get_plotlines("Breaking Bad", season=1, episodes=season_1_synopses)
143192
s02 = get_plotlines("Breaking Bad", season=2, episodes=season_2_synopses, prior=s01)
193+
194+
# Or pick the analysis system explicitly
195+
result = get_plotlines(
196+
"Mad Men", season=1, episodes=synopses, system="narratology",
197+
)
144198
```
145199

146200
Pass `prior` to track plotline continuity across seasons.
147201

148202
## LLM providers
149203

150204
```bash
151-
tvplotlines run breaking-bad/ # Anthropic (default)
152-
tvplotlines run breaking-bad/ --provider openai # OpenAI
153-
tvplotlines run breaking-bad/ --provider ollama # Ollama (local, free)
205+
tvplot run breaking-bad/ # Anthropic (default)
206+
tvplot run breaking-bad/ --provider openai # OpenAI
207+
tvplot run breaking-bad/ --provider ollama # Ollama (local, free)
208+
tvplot run breaking-bad/ --system narratology # narratology pipeline
154209
```
155210

156211
See [docs/api.md](docs/api.md) for full API reference.
157212

158213
## Key concepts
159214

160215
- **Plotline** — a narrative thread across episodes (e.g. "Walt: Empire")
161-
- **Story DNA** — hero, goal, obstacle, stakes
216+
- **Story DNA** — hero, goal, obstacle, stakes (hollywood) ↔ subject, object, opponent, receiver (narratology)
162217
- **A/B/C ranking** — plotline weight (A = main, B = secondary, C = tertiary, runner = minor thread)
163218
- **Format** — procedural (House), serial (Breaking Bad), hybrid (X-Files), ensemble (Game of Thrones)
164219
- **Story engine** — one sentence capturing the show's core dramatic mechanism
220+
- **Function** — episode-level role in a plotline arc (setup, inciting_incident, escalation, turning_point, crisis, climax, resolution; narratology adds `recognition`)
221+
- **Arc function** — season-level role of the same event
222+
223+
## How this uses AI
224+
225+
`tvplot` calls either Claude (Anthropic) or GPT (OpenAI) — you pick one per run — to produce its analyses. If your application surfaces this library's output to end users, you're responsible for disclosing the AI involvement to them (EU AI Act Art. 50; Anthropic AUP; OpenAI Usage Policies). The standalone HTML viewer shipped here carries that notice in its footer.
226+
227+
- [`docs/ai-disclosure.md`](docs/ai-disclosure.md) — what gets sent where, and to whom. Alpine Animation (Switzerland) publishes the library and collects **no** data; your API key and inputs travel directly from your machine to the LLM vendor you pick.
228+
- [`docs/methodology.md`](docs/methodology.md) — plain-language description of how the pipeline decides, what it can't do, and where to find the code for each step.
229+
230+
Outputs are AI-generated and can contain hallucinations. Treat them as a starting point for your own analysis, not a verified source.
165231

166232
## Citation
167233

168234
```bibtex
169-
@software{tvplotlines2026,
235+
@software{tvplot2026,
170236
author = {Vashko, N.},
171-
title = {tvplotlines: LLM-Driven Plotline Extraction from Episode Synopses},
237+
title = {tvplot: LLM-Driven Plotline Extraction from Episode Synopses},
172238
year = {2026},
173-
url = {https://github.com/BirdInTheTree/tvplotlines}
239+
url = {https://github.com/BirdInTheTree/tvplot}
174240
}
175241
```
176242

0 commit comments

Comments
 (0)