Initial commit

This commit is contained in:
Z User
2026-06-06 05:21:10 +00:00
Unverified
commit 6664758a6d
493 changed files with 135653 additions and 0 deletions

View File

@@ -0,0 +1,532 @@
---
name: storyboard-manager
description: Assist writers with story planning, character development, plot structuring, chapter writing, timeline tracking, and consistency checking. Use this skill when working with creative writing projects organized in folders containing characters, chapters, story planning documents, and summaries. Trigger this skill for tasks like "Help me develop this character," "Write the next chapter," "Check consistency across my story," or "Track the timeline of events."
---
# Storyboard Manager
## Overview
The Storyboard Manager skill equips Claude with specialized knowledge and tools for creative writing workflows. It provides frameworks for character development, story structure patterns, automated timeline tracking, and consistency checking across narrative projects. This skill automatically adapts to various storyboard folder structures while maintaining best practices for novel, screenplay, and serialized fiction writing.
## Core Capabilities
The skill provides four main capabilities:
### 1. Character Development & Management
Support creating deep, consistent character profiles with backstories, arcs, and relationships.
### 2. Story Planning & Structure
Guide plot development using established frameworks (Three-Act, Hero's Journey, Save the Cat, etc.) and help organize narrative elements.
### 3. Chapter & Scene Writing
Generate chapter content, scene breakdowns, and dialogue that maintains consistency with established characters and plot.
### 4. Timeline Tracking & Consistency Checking
Use automated tools to verify chronological consistency, character continuity, and world-building coherence.
## Detecting Project Structure
The Storyboard Manager automatically detects and adapts to various folder organizations. Look for these common directory patterns:
**Character folders:** `characters/`, `Characters/`, `cast/`, `Cast/`
**Chapter folders:** `chapters/`, `Chapters/`, `scenes/`, `Scenes/`, `story/`
**Planning folders:** `story-planning/`, `planning/`, `outline/`, `notes/`
**Summary files:** `summary.md`, `README.md`, `overview.md`
When triggered, scan the project root to identify the structure and adjust workflows accordingly. If no standard structure exists, recommend organizing files using the pattern: `characters/`, `chapters/`, `story-planning/`, and `summary.md`.
## Workflow Decision Tree
Use this decision tree to determine the appropriate workflow:
```
User Request
├─ Character-related? ("develop character," "create backstory," "character arc")
│ └─ → Character Development Workflow
├─ Planning/Plot? ("outline story," "plan act 2," "plot structure")
│ └─ → Story Planning Workflow
├─ Writing content? ("write chapter," "generate scene," "continue story")
│ └─ → Chapter/Scene Writing Workflow
└─ Checking/Analysis? ("check consistency," "track timeline," "find contradictions")
├─ Timeline? → Use timeline_tracker.py script
└─ Consistency? → Use consistency_checker.py script
```
## Character Development Workflow
### Step 1: Gather Context
Before developing a character, read existing character files to understand:
- Established naming conventions and profile format
- Existing characters and relationships
- Story genre and tone
- Character archetypes already in use
Use the Read tool to examine existing character files in the characters directory.
### Step 2: Access Character Development Framework
When detailed character guidance is needed, read `references/character_development.md` which contains:
- Core character elements (personality, motivation, goals)
- Backstory framework (ghost/wound, formative relationships)
- Character arc types (positive change, flat, negative)
- Relationship dynamics
- Voice development techniques
- Consistency guidelines
To efficiently find specific guidance, use Grep to search for relevant sections:
```bash
# Example: Find guidance on character arcs
grep -i "character arc" references/character_development.md
```
### Step 3: Develop Character Profile
Create or enhance character profiles with these essential elements:
**Basic Information**
- Name, age, role, physical appearance
- Key personality traits (both positive and negative)
**Background**
- Origin and formative experiences
- Ghost/wound that shapes their behavior
- Key relationships and family dynamics
**Character Arc**
- Starting belief or flaw
- Want vs. Need (external goal vs. internal growth)
- Transformation journey
- End state
**Relationships**
- Connections to other characters
- Dynamic types (ally, rival, mentor, etc.)
- How relationships evolve
**Unique Elements**
- Abilities, skills, or special knowledge
- Secrets or hidden aspects
- Voice/speech patterns
- Character-specific quirks
### Step 4: Ensure Consistency
Cross-reference with:
- Existing character profiles (avoid redundancy in roles/traits)
- Story planning documents (ensure alignment with plot needs)
- Summary/overview (match genre and tone)
### Step 5: Create or Update File
Write the character profile to `characters/[character-name].md` using markdown format. Match the existing style and structure found in other character files.
## Story Planning Workflow
### Step 1: Assess Current Planning State
Read existing planning documents to understand:
- Story concept and premise
- Established plot points or outline
- Target audience and genre
- Themes and central questions
- Planned structure (if any)
Look in folders like `story-planning/`, `outline/`, or files like `summary.md`.
### Step 2: Access Story Structure Reference
For detailed structural guidance, read `references/story_structures.md` which includes:
- Three-Act Structure
- Hero's Journey (Campbell's Monomyth)
- Save the Cat Beat Sheet
- Character arc templates
- Scene structure components
- Pacing guidelines by genre
- Subplot integration techniques
- Genre-specific structures
Use Grep to find specific frameworks:
```bash
# Example: Find Three-Act Structure details
grep -A 20 "Three-Act Structure" references/story_structures.md
```
### Step 3: Determine Structure Needs
Based on the user's request and story genre, recommend appropriate frameworks:
- **Thriller/Mystery**: Three-Act with strong midpoint reversal
- **Fantasy/Adventure**: Hero's Journey for quest narratives
- **YA/Contemporary**: Save the Cat for tight emotional beats
- **Literary Fiction**: Focus on character arc structure
- **Romance**: Genre-specific structure with relationship beats
### Step 4: Develop Planning Document
Create or enhance planning documents with:
**Story Overview**
- Premise in 2-3 sentences
- Genre, target audience, tone
- Central themes and questions
**Plot Structure**
- Act/chapter breakdown with key events
- Inciting incident and plot points
- Midpoint twist or revelation
- Climax and resolution
**Character Arcs**
- How each main character transforms
- Arc integration with plot beats
**World-Building Elements** (if applicable)
- Setting and locations
- Magic systems or technology
- Social structures or rules
- Historical context
**Timeline**
- Story duration
- Key event sequence
- Pacing considerations
### Step 5: Create Planning File
Write planning documents to `story-planning/[document-name].md`. Use clear hierarchical structure with markdown headers for easy navigation.
## Chapter & Scene Writing Workflow
### Step 1: Gather Story Context
Before writing any content, comprehensively read:
**Character Files**: All relevant character profiles to understand voices, motivations, arcs
**Planning Documents**: Story structure, plot points, current story position
**Previous Chapters**: Recent chapters to maintain continuity (read at least 1-2 prior chapters)
**Summary**: Overall story premise and themes
This ensures the new content aligns with established elements.
### Step 2: Identify Chapter Requirements
Determine:
- **Story Position**: Where does this fit in the overall structure?
- **POV Character**: Whose perspective?
- **Scene Goal**: What does the POV character want in this scene?
- **Conflict**: What opposes their goal?
- **Outcome**: How does the scene end? (typically with a complication)
- **Character Development**: What arc beats occur here?
- **Plot Advancement**: What story questions are raised or answered?
### Step 3: Structure the Chapter
Apply scene structure components:
**Scene (Action)**
1. Goal - What the POV character pursues
2. Conflict - Opposition encountered
3. Disaster - Negative outcome that propels forward
**Sequel (Reaction)**
1. Reaction - Emotional response to disaster
2. Dilemma - Processing options
3. Decision - Choice leading to next goal
Alternate between high-tension (action, conflict) and low-tension (reflection, world-building) beats for pacing.
### Step 4: Write with Character Consistency
Maintain character voice by referencing:
- Established personality traits
- Speech patterns and vocabulary
- Behavioral patterns (under stress, when happy, decision-making style)
- Current position in character arc
- Relationships with other characters present
### Step 5: Integrate Timeline Markers
Include timeline references to maintain chronological clarity:
- Explicit markers: "Day 3," "Two weeks later"
- Implicit markers: Time of day, seasonal cues, event references
- Format: `**Timeline:** Day 5, Evening` in chapter header or as section break
### Step 6: Create Chapter File
Write chapter content to `chapters/chapter-[number].md` or `chapters/[chapter-name].md`. Include:
**Chapter Header**
```markdown
# Chapter [Number]: [Optional Title]
**Timeline:** [When this occurs]
**POV:** [Character name]
**Location:** [Where this takes place]
```
**Chapter Content**
- Scene-by-scene breakdown
- Dialogue and action
- Character thoughts (for POV character)
- Descriptive elements
### Step 7: Note Continuity Elements
After writing, document any new information introduced:
- Character revelations or development
- Plot points or clues
- World-building details
- Timeline events
This helps maintain consistency in future chapters.
## Timeline Tracking
### When to Use Timeline Tracking
Invoke the timeline tracker when:
- User requests timeline analysis or event sequencing
- Checking chronological consistency
- Planning event order across chapters
- Identifying unmarked time periods
### Running the Timeline Tracker
Execute the script from the project root:
```bash
python3 .claude/skills/storyboard-manager/scripts/timeline_tracker.py . --output markdown
```
**Output format options:**
- `markdown` - Human-readable report (default)
- `json` - Structured data for further processing
### Understanding Timeline Output
The script provides:
**Statistics**
- Total events tracked
- Total characters appearing
- Events per character
**Timeline View**
- Chronological sequence of events
- Chapter/scene locations
- Characters present in each event
- Preview of event content
**Warnings**
- Events without timeline markers
- Characters mentioned but not defined in character files
### Acting on Timeline Results
After running the tracker:
1. **Review warnings** - Address missing timeline markers by adding them to chapters
2. **Check sequence** - Verify events occur in logical order
3. **Identify gaps** - Look for time periods without events
4. **Character tracking** - Ensure characters appear consistently with their arc
Add timeline markers to chapters where missing:
```markdown
**Timeline:** Day 7, Morning
```
Or use inline markers:
```markdown
Three days had passed since the incident...
```
## Consistency Checking
### When to Use Consistency Checking
Invoke the consistency checker when:
- User requests consistency analysis
- Before finalizing chapters or acts
- After making significant character or plot changes
- When tracking contradictions or errors
### Running the Consistency Checker
Execute the script from the project root:
```bash
python3 .claude/skills/storyboard-manager/scripts/consistency_checker.py . --output markdown
```
**Output format options:**
- `markdown` - Human-readable report with issue details (default)
- `json` - Structured data for programmatic analysis
### Understanding Consistency Output
The script identifies issues in three severity levels:
**Critical (🔴)**
- Major contradictions requiring immediate attention
- Character appearing after death
- Fundamental plot contradictions
**Warning (⚠️)**
- Potential inconsistencies to review
- Age discrepancies
- Physical description contradictions
- Relationship conflicts
**Info ()**
- Minor issues or variations
- Name capitalization inconsistencies
- Stylistic variations
### Acting on Consistency Results
For each issue reported:
1. **Read flagged locations** - Review the specific files mentioned
2. **Determine truth** - Decide which version is correct (usually character profile is authoritative)
3. **Update files** - Fix contradictions using the Edit tool
4. **Re-run checker** - Verify fixes resolved the issues
**Example workflow for character age inconsistency:**
```markdown
Issue: Age inconsistency for Maya
- Profile: 18 years old
- Chapter 3: mentions "21-year-old Maya"
Fix: Edit chapter-3.md to change "21-year-old" to "18-year-old"
```
### Consistency Checking Limitations
The automated checker catches:
- Physical attribute contradictions
- Age discrepancies
- Name variations
- Basic world-building facts
The checker cannot catch:
- Subtle personality inconsistencies
- Complex plot logic errors
- Thematic contradictions
- Nuanced relationship changes
Manual review is still essential for deep consistency.
## Best Practices
### Progressive Context Loading
Don't load all reference files at once. Instead:
1. Scan project structure first
2. Read only relevant character files for the current task
3. Access reference documentation only when specific guidance is needed
4. Use Grep to find specific sections in large reference files
### Maintaining Genre Voice
Match the story's established tone:
- **YA**: Present tense, immediate emotional connection, contemporary language
- **Fantasy**: Rich descriptive language, world-building integration
- **Thriller**: Short sentences, high tension, sensory details
- **Literary**: Complex prose, internal reflection, symbolic elements
Reference the summary.md to identify target audience and adjust accordingly.
### Character Arc Integration
Every chapter should serve character arcs:
- Track where each character is in their arc
- Show incremental change, not sudden transformation
- Use plot events to test character beliefs
- Demonstrate growth through choices and behavior
### Balancing Show vs. Tell
For narrative writing:
- **Show** emotions through actions, dialogue, physical reactions
- **Tell** to compress time, provide necessary information efficiently
- Use character-filtered description (what would this POV character notice?)
### Handling Multiple POV
When stories have multiple perspectives:
- Create distinct voices for each POV character
- Ensure each POV section advances both that character's arc and the plot
- Vary sentence structure and vocabulary by character
- Track what each character knows vs. doesn't know
## Common User Requests & Responses
### "Help me develop a character backstory"
1. Read existing character files for context
2. Read the character profile (if exists) to enhance
3. Access character_development.md reference for backstory framework
4. Create detailed backstory covering: ghost/wound, formative relationships, key history
5. Integrate with their character arc and story role
### "Write the next chapter"
1. Read summary.md and story planning documents
2. Read all character profiles for characters appearing in chapter
3. Read previous 2 chapters for continuity
4. Identify chapter position in story structure
5. Write chapter with scene/sequel structure
6. Include timeline markers and POV/location headers
### "Outline Act 2"
1. Read summary and any existing planning documents
2. Access story_structures.md for structural guidance
3. Identify act 2 requirements (complications, midpoint, rising tension)
4. Create beat-by-beat outline aligned with character arcs
5. Note how plot and character arcs intersect
### "Check my story for consistency"
1. Run consistency_checker.py script
2. Review output identifying issues
3. Read flagged files to understand contradictions
4. Recommend specific fixes for each issue
5. Offer to make edits if user confirms
### "Track the timeline of my story"
1. Run timeline_tracker.py script
2. Review output showing event sequence
3. Identify gaps or inconsistencies in chronology
4. Recommend adding timeline markers where missing
5. Provide timeline summary organized by character or chapter
### "What structure should I use for my thriller?"
1. Access story_structures.md reference
2. Recommend Three-Act Structure or Save the Cat
3. Explain thriller-specific requirements (escalating tension, ticking clock)
4. Provide beat sheet adapted to their story concept
5. Offer to create detailed planning document
## Resources
### scripts/timeline_tracker.py
Python script that analyzes markdown files to extract and organize timeline events. Tracks character appearances, identifies time markers, groups events chronologically, and flags consistency issues.
**Usage:** Run from project root with `python3 .claude/skills/storyboard-manager/scripts/timeline_tracker.py .`
### scripts/consistency_checker.py
Python script that detects inconsistencies in character details, physical descriptions, ages, names, and world-building facts across all story files. Outputs severity-ranked issues with file locations.
**Usage:** Run from project root with `python3 .claude/skills/storyboard-manager/scripts/consistency_checker.py .`
### references/character_development.md
Comprehensive framework for creating multi-dimensional characters including core elements, backstory structure, arc types, relationship dynamics, voice development, and consistency guidelines.
**Load when:** Developing new characters, enhancing existing profiles, resolving character consistency issues, or planning character arcs.
### references/story_structures.md
Detailed reference covering major story structures (Three-Act, Hero's Journey, Save the Cat), character arc templates, scene structure, pacing guidelines, plot development techniques, and genre-specific structures.
**Load when:** Planning story outline, structuring acts, organizing plot beats, determining pacing, or applying specific narrative frameworks.

View File

@@ -0,0 +1,9 @@
export default async function storyboard_manager(input) {
console.log("🧠 Running skill: storyboard-manager");
// TODO: implement actual logic for this skill
return {
message: "Skill 'storyboard-manager' executed successfully!",
input
};
}

View File

@@ -0,0 +1,11 @@
{
"name": "@ai-labs-claude-skills/storyboard-manager",
"version": "1.0.0",
"description": "Claude AI skill: storyboard-manager",
"main": "index.js",
"files": [
"."
],
"license": "MIT",
"author": "AI Labs"
}

View File

@@ -0,0 +1,232 @@
# Character Development Reference
This reference provides frameworks for creating compelling, multi-dimensional characters.
## Core Character Elements
### Basic Profile
- **Name**: Full name, nicknames, name meaning
- **Age**: Chronological and how they present
- **Physical Description**: Distinguishing features, style, mannerisms
- **Role**: Protagonist, antagonist, supporting, mentor, etc.
- **Archetype**: Hero, mentor, trickster, everyman, etc.
### Personality Dimensions
- **Temperament**: Sanguine, choleric, melancholic, phlegmatic
- **Traits**: 3-5 defining characteristics (both positive and negative)
- **Quirks**: Unique habits or behaviors
- **Speech Patterns**: How they talk, vocabulary, accent
- **Sense of Humor**: Type and style
### Motivation & Goals
- **External Goal**: What they're trying to achieve (plot-level)
- **Internal Goal**: What they're trying to become (character arc)
- **Motivation**: Why they want these things
- **Stakes**: What happens if they fail
- **Misbelief/Lie**: False belief holding them back
## Character Backstory Framework
### The Ghost (Past Wound)
- **Traumatic Event**: What happened in their past
- **Age When It Occurred**: How it shaped their development
- **Who Was Involved**: Other characters connected to trauma
- **How It Changed Them**: Before and after personality
- **Coping Mechanisms**: How they deal with the wound
### Formative Relationships
- **Family Dynamics**: Parents, siblings, family structure
- **Key Friendships**: Influences from peers
- **Romantic History**: Past relationships and their impact
- **Mentors/Role Models**: Who shaped their values
- **Enemies/Rivals**: Antagonistic relationships that defined them
### Life History
- **Childhood**: Key events, family situation, early personality
- **Adolescence**: Identity formation, major choices, first loves/losses
- **Young Adulthood**: Independence, career/path choices, relationships
- **Current Situation**: Where story finds them
## Character Arc Types
### Positive Change Arc
**Structure:**
1. Lie they believe
2. Want vs. Need established
3. First glimpse of truth
4. Rejection of truth (return to lie)
5. Moment of truth (crisis)
6. Choice to embrace truth
7. New worldview demonstrated
**Markers:**
- Start: Incomplete, held back by misbelief
- Midpoint: Glimpse growth but not ready
- Climax: Must choose between lie and truth
- End: Transformed, living truth
### Flat Arc
**Structure:**
1. Truth known from beginning
2. World believes lie
3. Character tested on their truth
4. Character demonstrates truth
5. World begins to change
6. Truth proven through action
**Markers:**
- Start: Strong in beliefs
- Midpoint: Severely tested
- Climax: Greatest test of faith
- End: Changed the world, not themselves
### Negative Arc
**Structure:**
1. Flaw/weakness established
2. Temptation introduced
3. Small compromises begin
4. Point of no return crossed
5. Descent accelerates
6. Rejection of redemption
7. Tragic conclusion
**Markers:**
- Start: Flawed but sympathetic
- Midpoint: Questionable choices
- Climax: Beyond redemption
- End: Destroyed or becomes villain
## Relationship Dynamics
### Character Relationships Matrix
For each significant relationship, define:
- **Dynamic Type**: Mentor/student, rivals, allies, romance, family
- **Conflict Source**: What creates tension
- **Common Ground**: What bonds them
- **Influence**: How they change each other
- **Arc**: How relationship evolves
### Protagonist-Antagonist Relationship
- **Opposition**: How antagonist blocks protagonist's goal
- **Mirror/Foil**: How they reflect/contrast each other
- **Personal Stakes**: Why this matters beyond plot
- **Symmetry**: Similar origins or opposite arc paths
- **Respect Level**: Do they understand each other?
## Character Voice Development
### Dialogue Markers
- **Vocabulary Level**: Formal, casual, slang, technical
- **Sentence Structure**: Short and punchy vs. long and flowing
- **Favorite Words/Phrases**: Repeated expressions
- **Topics They Discuss**: What they talk about most
- **What They Avoid**: Topics they don't address
- **Lying Tells**: How they behave when dishonest
### Internal Voice (POV Characters)
- **Thought Patterns**: Analytical, emotional, scattered, focused
- **Biases**: How they interpret events
- **Blind Spots**: What they don't see about themselves
- **Metaphors**: Types of comparisons they make
- **Narrative Distance**: Close, intimate vs. distant, observational
## Character Consistency
### Behavioral Patterns
- **Under Stress**: How they react to pressure
- **When Happy**: How they express joy
- **When Angry**: Explosive, cold, passive-aggressive
- **Decision-Making**: Impulsive, analytical, avoidant
- **Trust**: Quick or slow to trust others
### Core Values
- **Non-Negotiables**: Lines they won't cross
- **Flexible Areas**: Where they compromise
- **Value Hierarchy**: Ranking of priorities (family, honor, survival, etc.)
- **Values Testing**: Scenes where values conflict
### Growth Indicators
- **Early Story**: How they handle situation type X
- **Mid Story**: How handling of X begins to shift
- **Late Story**: How they handle X after growth
- **Demonstration**: Parallel scenes showing change
## Character Roles in Ensemble
### Ensemble Balance
- **The Leader**: Drives action, makes decisions
- **The Heart**: Emotional center, unifies group
- **The Brain**: Strategy, knowledge, analysis
- **The Warrior**: Action, protection, physical strength
- **The Wildcard**: Unpredictable, challenges norms
- **The Conscience**: Moral compass, voice of reason
### Avoiding Character Redundancy
- **Different Wants**: Each character pursuing different goals
- **Different Methods**: Varied approaches to problems
- **Different Worldviews**: Contrasting perspectives
- **Different Skills**: Complementary abilities
- **Different Arcs**: Each on unique journey
## Character Development Questions
### Surface Level
- What do they look like?
- How do they dress?
- What's their job/role?
- Where do they live?
### Deeper Level
- What do they fear most?
- What do they desire more than anything?
- What's their greatest secret?
- What do they lie to themselves about?
- What would they sacrifice everything for?
### Behavioral Level
- How do they treat people with less power?
- What makes them laugh?
- What makes them cry?
- When do they lie, and why?
- How do they handle failure?
### Thematic Level
- What do they represent in the story?
- What question does their arc answer?
- How do they embody or challenge the theme?
- What truth do they discover?
## Character Testing Scenarios
To ensure character depth, test them against:
1. **Moral Dilemma**: Force choice between two values
2. **Loss**: Take away something they depend on
3. **Temptation**: Offer something they want vs. need
4. **Betrayal**: Test their trust and forgiveness
5. **Sacrifice**: Force them to give up something important
6. **Revelation**: Expose a truth they've been avoiding
7. **Isolation**: Remove their support system
8. **Power**: Give them control and see how they use it
## Red Flags for Weak Characters
### Avoid:
- **Mary Sue/Gary Stu**: Too perfect, no real flaws
- **Inconsistent Behavior**: Acts differently for plot convenience
- **No Agency**: Things happen to them, they don't drive action
- **Single-Note**: Only one personality trait
- **No Growth**: Same at end as beginning (unless flat arc)
- **Reactive Only**: Never makes proactive choices
- **Exposition Puppet**: Exists to explain things
- **Token Diversity**: Defined only by identity marker
### Fix By:
- Adding meaningful flaws and consequences
- Establishing behavioral patterns and motivations
- Giving them goals and plans they actively pursue
- Layering contradictory traits and complexity
- Planning clear arc with transformation
- Creating scenes where they initiate action
- Giving them purpose beyond information delivery
- Developing full personality, backstory, and individual arc

View File

@@ -0,0 +1,148 @@
# Story Structure Reference
This reference provides common story structures and frameworks for planning narratives.
## Three-Act Structure
### Act One: Setup (25% of story)
- **Hook**: Opening scene that grabs attention
- **Inciting Incident**: Event that disrupts the protagonist's normal world
- **First Plot Point**: Decision/event that propels protagonist into Act Two (typically at 25% mark)
### Act Two: Confrontation (50% of story)
- **Rising Action**: Series of obstacles and complications
- **Midpoint**: Major revelation or reversal (at 50% mark)
- **Pinch Points**: Moments that increase pressure on protagonist
- **Second Plot Point**: Lowest point/crisis that leads into Act Three (at 75% mark)
### Act Three: Resolution (25% of story)
- **Climax**: Final confrontation or decision
- **Falling Action**: Immediate consequences of climax
- **Resolution**: New normal/equilibrium established
## Hero's Journey (Joseph Campbell)
1. **Ordinary World**: Hero's normal life
2. **Call to Adventure**: Challenge or quest presented
3. **Refusal of the Call**: Initial hesitation or fear
4. **Meeting the Mentor**: Guidance or magical aid
5. **Crossing the Threshold**: Commitment to the journey
6. **Tests, Allies, and Enemies**: Learning the rules of the new world
7. **Approach to the Inmost Cave**: Preparation for major challenge
8. **Ordeal**: Greatest fear/challenge faced
9. **Reward**: Achievement of goal or new knowledge
10. **The Road Back**: Return journey begins
11. **Resurrection**: Final test with everything at stake
12. **Return with the Elixir**: Hero returns transformed
## Save the Cat Beat Sheet (Blake Snyder)
1. **Opening Image**: Snapshot of protagonist's world before change
2. **Theme Stated**: Central question or theme introduced
3. **Setup**: Establish protagonist's world, flaws, and stakes
4. **Catalyst**: Event that starts the story (at 10% mark)
5. **Debate**: Internal conflict about whether to act
6. **Break into Two**: Protagonist commits to journey (at 20-25% mark)
7. **B Story**: Subplot introduced (often romantic or thematic)
8. **Fun and Games**: Promise of the premise delivered
9. **Midpoint**: False victory or defeat (at 50% mark)
10. **Bad Guys Close In**: External and internal pressure increases
11. **All Is Lost**: Lowest point (at 75% mark)
12. **Dark Night of the Soul**: Protagonist processes loss
13. **Break into Three**: Solution discovered (at 80% mark)
14. **Finale**: Climax and resolution
15. **Final Image**: Parallel to opening showing change
## Character Arc Templates
### Positive Change Arc
- **Lie Believed**: Character starts believing something false about themselves/world
- **Want vs. Need**: What they think they want vs. what they actually need
- **Ghost/Wound**: Past trauma influencing present behavior
- **Moment of Truth**: Forced to choose between lie and truth
- **Resolution**: Embraces truth and grows
### Flat Arc
- **Truth Known**: Character already knows the truth
- **World's Lie**: The world around them believes a lie
- **Testing**: Character's truth is challenged repeatedly
- **Impact**: Character changes the world around them
- **Affirmation**: Character's truth proven correct
### Negative Arc
- **Initial Weakness**: Character has a flaw or belief
- **Escalation**: Flaw grows worse through choices
- **Point of No Return**: Character chooses darkness
- **Descent**: Consequences spiral
- **Tragic End**: Character destroyed or becomes antagonist
## Scene Structure
### Scene Components
1. **Goal**: What the POV character wants in this scene
2. **Conflict**: Opposition to achieving the goal
3. **Disaster**: Outcome (usually negative) that propels to next scene
### Sequel Components (reaction to scene)
1. **Reaction**: Emotional response to disaster
2. **Dilemma**: Working through options
3. **Decision**: Choice that leads to next goal/scene
## Pacing Guidelines
### Chapter Length by Genre
- **Thriller/Mystery**: 2,000-3,000 words (faster pace)
- **Fantasy/Sci-Fi**: 3,000-5,000 words (world-building needs)
- **Romance**: 2,500-4,000 words (emotional beats)
- **Literary Fiction**: 2,000-6,000 words (varies widely)
- **YA**: 2,000-3,500 words (shorter attention span)
### Tension Management
- **High-tension scenes**: Action, conflict, revelations (shorter, punchier)
- **Low-tension scenes**: Character development, world-building (can be longer)
- **Rhythm**: Alternate between high and low tension
- **Overall trend**: Tension should increase as story progresses
## Plot Development
### Conflict Types
1. **Character vs. Character**: Antagonist opposition
2. **Character vs. Self**: Internal struggle
3. **Character vs. Society**: Against norms/systems
4. **Character vs. Nature**: Environmental challenges
5. **Character vs. Technology**: Man vs. machine
6. **Character vs. Fate**: Against destiny/prophecy
### Subplot Integration
- **Mirror subplots**: Reflect main theme differently
- **Contrast subplots**: Show opposite approach to theme
- **Complication subplots**: Add obstacles to main plot
- **Resolution rule**: Resolve minor subplots before climax, major ones during/after
## Genre-Specific Structures
### Mystery/Thriller
- Introduction of crime/mystery
- Investigation and clue discovery
- Red herrings and misdirection
- Escalating danger
- Revelation and confrontation
- Resolution and explanation
### Romance
- Meet-cute or introduction
- Attraction develops
- Barrier/conflict introduced
- Relationship deepens despite obstacles
- Black moment/breakup
- Grand gesture/reconciliation
- Happy ending or HEA (Happily Ever After)
### Fantasy/Sci-Fi
- Ordinary world establishment
- Introduction to magical/sci-fi elements
- Quest or mission defined
- Journey and world exploration
- Building towards prophesied/anticipated event
- Final battle or confrontation
- New world order established

View File

@@ -0,0 +1,391 @@
#!/usr/bin/env python3
"""
Consistency Checker for Storyboard Manager
This script analyzes markdown files in a storyboard project to detect inconsistencies
in character details, plot elements, and world-building across the story.
"""
import os
import re
import sys
import json
from pathlib import Path
from typing import List, Dict, Set, Tuple, Optional
from collections import defaultdict
class ConsistencyIssue:
"""Represents a consistency issue found in the story"""
def __init__(self, issue_type: str, severity: str, description: str,
locations: List[str], details: Dict = None):
self.issue_type = issue_type # character, plot, world, timeline
self.severity = severity # critical, warning, info
self.description = description
self.locations = locations
self.details = details or {}
def __repr__(self):
return f"ConsistencyIssue({self.severity}: {self.description})"
def to_dict(self):
return {
'type': self.issue_type,
'severity': self.severity,
'description': self.description,
'locations': self.locations,
'details': self.details
}
class CharacterProfile:
"""Stores character information from profile files"""
def __init__(self, name: str, file_path: str):
self.name = name
self.file_path = file_path
self.attributes = {}
self.aliases = []
self.relationships = {}
def add_attribute(self, key: str, value: str):
"""Add a character attribute"""
self.attributes[key.lower()] = value
def get_attribute(self, key: str) -> Optional[str]:
"""Get a character attribute"""
return self.attributes.get(key.lower())
class ConsistencyChecker:
"""Main consistency checking class"""
# Patterns to extract character attributes
ATTRIBUTE_PATTERNS = {
'age': r'\*\*Age:\*\*\s*(.+?)(?:\n|$)',
'appearance': r'\*\*Appearance:\*\*\s*(.+?)(?:\n|$)',
'hair': r'(?:hair|Hair)[\s:]+([^,\n]+)',
'eyes': r'(?:eyes|Eyes)[\s:]+([^,\n]+)',
'height': r'\*\*Height:\*\*\s*(.+?)(?:\n|$)',
'role': r'\*\*Role:\*\*\s*(.+?)(?:\n|$)',
}
def __init__(self, project_root: str):
self.project_root = Path(project_root)
self.characters: Dict[str, CharacterProfile] = {}
self.issues: List[ConsistencyIssue] = []
self.world_facts: Dict[str, Tuple[str, str]] = {} # fact -> (value, location)
def scan_directory(self, directory: Path) -> List[Path]:
"""Recursively find all markdown files in directory"""
md_files = []
if not directory.exists():
return md_files
for item in directory.iterdir():
if item.is_file() and item.suffix == '.md':
md_files.append(item)
elif item.is_dir() and not item.name.startswith('.'):
md_files.extend(self.scan_directory(item))
return md_files
def load_character_profile(self, file_path: Path) -> Optional[CharacterProfile]:
"""Load character information from a profile file"""
try:
content = file_path.read_text(encoding='utf-8')
# Extract character name from title
name_match = re.search(r'^#\s+(.+?)$', content, re.MULTILINE)
if not name_match:
return None
name = name_match.group(1).strip()
profile = CharacterProfile(name, str(file_path.relative_to(self.project_root)))
# Extract attributes
for attr_name, pattern in self.ATTRIBUTE_PATTERNS.items():
match = re.search(pattern, content, re.IGNORECASE)
if match:
profile.add_attribute(attr_name, match.group(1).strip())
# Extract aliases/nicknames
alias_match = re.search(
r'\*\*(?:Nicknames?|Aliases?):\*\*\s*(.+?)(?:\n|$)',
content, re.IGNORECASE
)
if alias_match:
aliases = re.split(r'[,;]', alias_match.group(1))
profile.aliases = [a.strip() for a in aliases if a.strip()]
return profile
except Exception as e:
print(f"Warning: Could not read character profile {file_path}: {e}",
file=sys.stderr)
return None
def load_all_characters(self):
"""Load all character profiles from the project"""
char_dirs = ['characters', 'Characters', 'cast', 'Cast']
for dirname in char_dirs:
char_dir = self.project_root / dirname
if char_dir.exists():
for char_file in self.scan_directory(char_dir):
profile = self.load_character_profile(char_file)
if profile:
self.characters[profile.name] = profile
def check_character_mentions(self, file_path: Path):
"""Check character mentions in content for inconsistencies"""
try:
content = file_path.read_text(encoding='utf-8')
location = str(file_path.relative_to(self.project_root))
for char_name, profile in self.characters.items():
# Check if character is mentioned
if not re.search(r'\b' + re.escape(char_name) + r'\b', content, re.IGNORECASE):
continue
# Check for attribute contradictions
for attr_name, attr_value in profile.attributes.items():
# Look for contradicting descriptions
if attr_name == 'age':
age_mentions = re.finditer(
r'\b' + re.escape(char_name) + r'\b[^.!?]*\b(\d+)[\s-](?:year|yr)',
content, re.IGNORECASE
)
for match in age_mentions:
mentioned_age = match.group(1)
profile_age = re.search(r'\d+', attr_value)
if profile_age and mentioned_age != profile_age.group(0):
self.issues.append(ConsistencyIssue(
issue_type='character',
severity='warning',
description=f"Age inconsistency for {char_name}",
locations=[location, profile.file_path],
details={
'character': char_name,
'profile_age': attr_value,
'mentioned_age': mentioned_age
}
))
elif attr_name in ['hair', 'eyes']:
# Check for contradicting physical descriptions
desc_pattern = rf'\b{re.escape(char_name)}\b[^.!?]*\b({attr_name})\b[^.!?]*'
desc_mentions = re.finditer(desc_pattern, content, re.IGNORECASE)
for match in desc_mentions:
context = match.group(0).lower()
# Simple check: if profile says "black hair" but text says "blonde"
profile_value_lower = attr_value.lower()
if profile_value_lower not in context:
# Extract the contradicting description
color_pattern = r'\b(black|brown|blonde|red|auburn|white|gray|grey|blue|green|hazel)\b'
colors = re.findall(color_pattern, context, re.IGNORECASE)
if colors:
self.issues.append(ConsistencyIssue(
issue_type='character',
severity='warning',
description=f"{attr_name.capitalize()} color inconsistency for {char_name}",
locations=[location, profile.file_path],
details={
'character': char_name,
'profile': attr_value,
'context': match.group(0)[:100]
}
))
except Exception as e:
print(f"Warning: Error checking {file_path}: {e}", file=sys.stderr)
def check_character_relationships(self):
"""Check for inconsistent character relationships"""
# This is a placeholder for more sophisticated relationship checking
# Would analyze relationship declarations in character files and compare
# with how relationships are portrayed in chapters
relationship_keywords = ['friend', 'enemy', 'lover', 'sibling', 'parent', 'child']
for char_name, profile in self.characters.items():
# Extract relationship info from profile
# Compare with relationships mentioned in story files
# Flag inconsistencies
pass
def check_world_building(self, file_path: Path):
"""Check for world-building inconsistencies"""
try:
content = file_path.read_text(encoding='utf-8')
location = str(file_path.relative_to(self.project_root))
# Look for world-building facts (places, magic systems, technology, etc.)
# This is a simplified version - would need more sophisticated pattern matching
# Example: Check for location descriptions
location_pattern = r'\*\*Location:\*\*\s*(.+?)(?:\n|$)'
for match in re.finditer(location_pattern, content, re.IGNORECASE):
loc_name = match.group(1).strip()
if loc_name in self.world_facts:
# Check if description is consistent
prev_value, prev_location = self.world_facts[loc_name]
# In a real implementation, would do semantic comparison
else:
self.world_facts[loc_name] = (match.group(0), location)
except Exception as e:
print(f"Warning: Error checking world-building in {file_path}: {e}",
file=sys.stderr)
def check_plot_consistency(self):
"""Check for plot inconsistencies"""
# Placeholder for plot consistency checking
# Would track plot points, events, and check for contradictions
# Examples to check:
# - Events happening out of order
# - Characters appearing after their death
# - Objects used before acquisition
# - Locations visited before discovery
pass
def check_name_variations(self, file_path: Path):
"""Check for inconsistent name usage"""
try:
content = file_path.read_text(encoding='utf-8')
location = str(file_path.relative_to(self.project_root))
# Check if character names are spelled consistently
for char_name, profile in self.characters.items():
# Look for potential misspellings (Levenshtein distance)
# This is simplified - would use actual string distance algorithm
# Check for variations in capitalization
variations = re.findall(
r'\b' + re.escape(char_name) + r'\b',
content,
re.IGNORECASE
)
inconsistent_caps = [v for v in variations if v != char_name]
if inconsistent_caps:
unique_variations = list(set(inconsistent_caps))
if len(unique_variations) > 0:
self.issues.append(ConsistencyIssue(
issue_type='character',
severity='info',
description=f"Name capitalization variations for {char_name}",
locations=[location],
details={
'character': char_name,
'variations': unique_variations
}
))
except Exception as e:
print(f"Warning: Error checking names in {file_path}: {e}", file=sys.stderr)
def analyze_project(self) -> Dict:
"""Run all consistency checks on the project"""
# Load character profiles
self.load_all_characters()
# Check all content files
content_dirs = ['chapters', 'Chapters', 'scenes', 'Scenes', 'story']
content_files = []
for dirname in content_dirs:
content_dir = self.project_root / dirname
if content_dir.exists():
content_files.extend(self.scan_directory(content_dir))
# Run checks on each file
for content_file in content_files:
self.check_character_mentions(content_file)
self.check_world_building(content_file)
self.check_name_variations(content_file)
# Run project-wide checks
self.check_character_relationships()
self.check_plot_consistency()
# Organize results
issues_by_severity = defaultdict(list)
for issue in self.issues:
issues_by_severity[issue.severity].append(issue.to_dict())
analysis = {
'total_issues': len(self.issues),
'critical_issues': len(issues_by_severity['critical']),
'warnings': len(issues_by_severity['warning']),
'info': len(issues_by_severity['info']),
'characters_analyzed': len(self.characters),
'issues_by_severity': dict(issues_by_severity),
'all_issues': [issue.to_dict() for issue in self.issues]
}
return analysis
def main():
"""Main entry point for consistency checker"""
if len(sys.argv) < 2:
print("Usage: consistency_checker.py <project_directory> [--output json|markdown]")
sys.exit(1)
project_dir = sys.argv[1]
output_format = 'markdown'
if len(sys.argv) > 2 and sys.argv[2] == '--output':
output_format = sys.argv[3] if len(sys.argv) > 3 else 'markdown'
checker = ConsistencyChecker(project_dir)
analysis = checker.analyze_project()
if output_format == 'json':
print(json.dumps(analysis, indent=2))
else:
# Markdown output
print("# Consistency Analysis\n")
print(f"**Total Issues Found:** {analysis['total_issues']}")
print(f"- Critical: {analysis['critical_issues']}")
print(f"- Warnings: {analysis['warnings']}")
print(f"- Info: {analysis['info']}\n")
print(f"**Characters Analyzed:** {analysis['characters_analyzed']}\n")
if analysis['total_issues'] == 0:
print("✅ No consistency issues found!\n")
else:
# Display issues by severity
for severity in ['critical', 'warning', 'info']:
issues = analysis['issues_by_severity'].get(severity, [])
if issues:
severity_emoji = {
'critical': '🔴',
'warning': '⚠️',
'info': ''
}
print(f"\n## {severity_emoji[severity]} {severity.upper()}\n")
for issue in issues:
print(f"### {issue['description']}")
print(f"**Type:** {issue['type']}")
print(f"**Locations:**")
for loc in issue['locations']:
print(f"- {loc}")
if issue['details']:
print(f"**Details:**")
for key, value in issue['details'].items():
print(f"- {key}: {value}")
print()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,352 @@
#!/usr/bin/env python3
"""
Timeline Tracker for Storyboard Manager
This script analyzes markdown files in a storyboard project to extract and organize
timeline events, helping writers maintain chronological consistency.
"""
import os
import re
import json
import sys
from pathlib import Path
from typing import List, Dict, Tuple, Optional
from datetime import datetime, timedelta
from collections import defaultdict
class TimelineEvent:
"""Represents a single event in the story timeline"""
def __init__(self, content: str, location: str, chapter: str = None,
timepoint: str = None, characters: List[str] = None):
self.content = content
self.location = location # File path where event was found
self.chapter = chapter
self.timepoint = timepoint # Relative time (e.g., "Day 1", "3 weeks later")
self.characters = characters or []
def __repr__(self):
return f"TimelineEvent({self.timepoint}: {self.content[:50]}...)"
class TimelineTracker:
"""Main timeline tracking and analysis class"""
# Patterns to detect time markers in text
TIME_PATTERNS = [
r'(?:Day|Night)\s+(\d+)', # Day 1, Night 3
r'(\d+)\s+(?:days?|weeks?|months?|years?)\s+(?:later|ago|after|before)',
r'(?:Morning|Afternoon|Evening|Night)\s+of\s+(?:Day\s+)?(\d+)',
r'Chapter\s+(\d+)', # Chapter markers
r'\*\*(?:Timeline|Time|When):\*\*\s*(.+?)(?:\n|$)', # Explicit timeline markers
r'\*\*Date:\*\*\s*(.+?)(?:\n|$)',
]
# Patterns to detect character mentions
CHARACTER_PATTERNS = [
r'\*\*Characters?:\*\*\s*(.+?)(?:\n|$)',
r'\*\*(?:POV|Perspective):\*\*\s*(.+?)(?:\n|$)',
]
def __init__(self, project_root: str):
self.project_root = Path(project_root)
self.events: List[TimelineEvent] = []
self.characters: set = set()
def scan_directory(self, directory: Path) -> List[Path]:
"""Recursively find all markdown files in directory"""
md_files = []
if not directory.exists():
return md_files
for item in directory.iterdir():
if item.is_file() and item.suffix == '.md':
md_files.append(item)
elif item.is_dir() and not item.name.startswith('.'):
md_files.extend(self.scan_directory(item))
return md_files
def extract_characters_from_file(self, file_path: Path) -> List[str]:
"""Extract character names from character profile files"""
try:
content = file_path.read_text(encoding='utf-8')
# Look for character name in title (# Character Name)
name_match = re.search(r'^#\s+(.+?)$', content, re.MULTILINE)
if name_match:
return [name_match.group(1).strip()]
# Look for explicit name field
name_match = re.search(r'\*\*Name:\*\*\s*(.+?)(?:\n|$)', content)
if name_match:
return [name_match.group(1).strip()]
except Exception as e:
print(f"Warning: Could not read {file_path}: {e}", file=sys.stderr)
return []
def extract_timeline_markers(self, content: str) -> List[Tuple[str, int]]:
"""Extract time markers from content, return list of (timepoint, position)"""
markers = []
for pattern in self.TIME_PATTERNS:
for match in re.finditer(pattern, content, re.IGNORECASE):
timepoint = match.group(1) if match.lastindex else match.group(0)
markers.append((timepoint.strip(), match.start()))
return sorted(markers, key=lambda x: x[1])
def extract_character_mentions(self, content: str) -> List[str]:
"""Extract character names from explicit character markers"""
characters = []
for pattern in self.CHARACTER_PATTERNS:
matches = re.finditer(pattern, content, re.IGNORECASE)
for match in matches:
char_text = match.group(1)
# Split by commas, 'and', '&'
names = re.split(r'[,&]|\sand\s', char_text)
characters.extend([name.strip() for name in names if name.strip()])
return characters
def find_character_references(self, content: str, known_characters: set) -> List[str]:
"""Find mentions of known characters in content"""
found = []
for character in known_characters:
# Simple word boundary check
if re.search(r'\b' + re.escape(character) + r'\b', content, re.IGNORECASE):
found.append(character)
return found
def parse_chapter_file(self, file_path: Path) -> List[TimelineEvent]:
"""Parse a chapter/scene file for timeline events"""
events = []
try:
content = file_path.read_text(encoding='utf-8')
# Get chapter number/name from filename or title
chapter = file_path.stem
title_match = re.search(r'^#\s+(.+?)$', content, re.MULTILINE)
if title_match:
chapter = title_match.group(1).strip()
# Extract explicit character mentions
explicit_chars = self.extract_character_mentions(content)
# Find timeline markers
markers = self.extract_timeline_markers(content)
# Split content into sections based on markers
if markers:
sections = []
for i, (timepoint, pos) in enumerate(markers):
start_pos = pos
end_pos = markers[i + 1][1] if i + 1 < len(markers) else len(content)
section_content = content[start_pos:end_pos]
# Find characters in this section
section_chars = explicit_chars.copy()
section_chars.extend(self.find_character_references(
section_content, self.characters))
event = TimelineEvent(
content=section_content[:500], # First 500 chars as preview
location=str(file_path.relative_to(self.project_root)),
chapter=chapter,
timepoint=timepoint,
characters=list(set(section_chars))
)
events.append(event)
else:
# No explicit markers, treat whole file as one event
all_chars = explicit_chars.copy()
all_chars.extend(self.find_character_references(content, self.characters))
event = TimelineEvent(
content=content[:500],
location=str(file_path.relative_to(self.project_root)),
chapter=chapter,
timepoint=None,
characters=list(set(all_chars))
)
events.append(event)
except Exception as e:
print(f"Warning: Error parsing {file_path}: {e}", file=sys.stderr)
return events
def analyze_project(self) -> Dict:
"""Analyze entire project and build timeline"""
# First, find all characters
char_dirs = ['characters', 'Characters', 'cast']
for dirname in char_dirs:
char_dir = self.project_root / dirname
if char_dir.exists():
for char_file in self.scan_directory(char_dir):
names = self.extract_characters_from_file(char_file)
self.characters.update(names)
# Then scan chapters/scenes
content_dirs = ['chapters', 'Chapters', 'scenes', 'Scenes', 'story']
for dirname in content_dirs:
content_dir = self.project_root / dirname
if content_dir.exists():
for content_file in self.scan_directory(content_dir):
events = self.parse_chapter_file(content_file)
self.events.extend(events)
# Build analysis
analysis = {
'total_events': len(self.events),
'total_characters': len(self.characters),
'characters': sorted(list(self.characters)),
'events_by_timepoint': self._group_events_by_time(),
'events_by_character': self._group_events_by_character(),
'events_by_chapter': self._group_events_by_chapter(),
'timeline': self._build_timeline(),
'warnings': self._check_consistency()
}
return analysis
def _group_events_by_time(self) -> Dict[str, List[Dict]]:
"""Group events by their timepoint"""
grouped = defaultdict(list)
for event in self.events:
timepoint = event.timepoint or "Unspecified"
grouped[timepoint].append({
'location': event.location,
'chapter': event.chapter,
'characters': event.characters,
'preview': event.content[:200]
})
return dict(grouped)
def _group_events_by_character(self) -> Dict[str, List[Dict]]:
"""Group events by character appearance"""
grouped = defaultdict(list)
for event in self.events:
for character in event.characters:
grouped[character].append({
'location': event.location,
'chapter': event.chapter,
'timepoint': event.timepoint,
'preview': event.content[:200]
})
return dict(grouped)
def _group_events_by_chapter(self) -> Dict[str, List[Dict]]:
"""Group events by chapter"""
grouped = defaultdict(list)
for event in self.events:
chapter = event.chapter or "Unknown"
grouped[chapter].append({
'location': event.location,
'timepoint': event.timepoint,
'characters': event.characters,
'preview': event.content[:200]
})
return dict(grouped)
def _build_timeline(self) -> List[Dict]:
"""Build chronological timeline of events"""
# Sort events by timepoint (this is simplified, real implementation
# would need more sophisticated time parsing)
timeline = []
for event in self.events:
timeline.append({
'timepoint': event.timepoint or "Unknown",
'chapter': event.chapter,
'location': event.location,
'characters': event.characters,
'preview': event.content[:200]
})
return timeline
def _check_consistency(self) -> List[str]:
"""Check for potential timeline inconsistencies"""
warnings = []
# Check for events without time markers
unmarked_events = [e for e in self.events if not e.timepoint]
if unmarked_events:
warnings.append(
f"Found {len(unmarked_events)} events without timeline markers"
)
# Check for characters appearing in timeline without character files
mentioned_chars = set()
for event in self.events:
mentioned_chars.update(event.characters)
undefined_chars = mentioned_chars - self.characters
if undefined_chars:
warnings.append(
f"Characters mentioned but not defined: {', '.join(sorted(undefined_chars))}"
)
return warnings
def main():
"""Main entry point for timeline tracker"""
if len(sys.argv) < 2:
print("Usage: timeline_tracker.py <project_directory> [--output json|markdown]")
sys.exit(1)
project_dir = sys.argv[1]
output_format = 'markdown'
if len(sys.argv) > 2 and sys.argv[2] == '--output':
output_format = sys.argv[3] if len(sys.argv) > 3 else 'markdown'
tracker = TimelineTracker(project_dir)
analysis = tracker.analyze_project()
if output_format == 'json':
print(json.dumps(analysis, indent=2))
else:
# Markdown output
print("# Timeline Analysis\n")
print(f"**Total Events:** {analysis['total_events']}")
print(f"**Total Characters:** {analysis['total_characters']}\n")
print("## Characters")
for char in analysis['characters']:
appearances = len(analysis['events_by_character'].get(char, []))
print(f"- {char} ({appearances} appearances)")
print("\n## Timeline")
for event in analysis['timeline']:
print(f"\n### {event['timepoint']} - {event['chapter']}")
print(f"**Location:** {event['location']}")
if event['characters']:
print(f"**Characters:** {', '.join(event['characters'])}")
print(f"\n{event['preview']}...\n")
print("---")
if analysis['warnings']:
print("\n## Warnings")
for warning in analysis['warnings']:
print(f"- ⚠️ {warning}")
if __name__ == '__main__':
main()