Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/8BitTacoSupreme/flowstate/llms.txt

Use this file to discover all available pages before exploring further.

FlowState is structured as three clean architectural layers that each do exactly one thing well. The deterministic layer produces files without touching an LLM. The bridge layer makes exactly two types of targeted LLM calls — research and strategy. The launcher layer never calls anything itself; it prints commands for native Claude Code execution. This separation makes every layer independently testable and means failures are contained to the bridge layer without dragging down context generation or the discipline audit.

The Three Architectural Layers

1

Layer 1 — Context Generator (context.py)

Pure Python templates. Transforms interview answers into the five files that downstream tools consume. No LLM, no timeouts, no network. Runs in under one second and is fully exercisable in unit tests without any mocking. Writes .planning/PROJECT.md, .planning/ROADMAP.md, .planning/config.json, .claude/CLAUDE.md, and research/brief.md.
2

Layer 2 — Targeted LLM Calls (research.py, strategy.py)

Uses claude --print for exactly two operations where an LLM adds value: per-topic research (~30 seconds per topic via ResearchAdapter) and a single strategic pressure-test (~75 seconds via StrategyAdapter). Each call is scoped with --allowedTools, --max-turns, and a focused system prompt so model usage stays bounded. When dry_run=True, both adapters return mock templates — no claude binary required.
3

Layer 3 — Session Launcher (launcher.py)

GSD phases and other native Claude Code skills run inside interactive claude sessions where slash commands actually work. flowstate launch gsd <N> prints the exact cd … && claude command and the /gsd:plan-phase N invocation. The launcher detects installed tools by checking for marker directories (.planning, .claude/skills/gstack, etc.) and prints suggested next steps at the end of every pipeline run.

Module Map

flowstate/
├── flowstate/
│   ├── cli.py              # Click CLI entrypoints
│   ├── interview.py        # Rich-powered intake interview
│   ├── orchestrator.py     # 5-step pipeline sequencing
│   ├── state.py            # Pydantic models + flowstate.json persistence
│   ├── bridge.py           # ClaudeBridge — claude CLI wrapper
│   ├── context.py          # Deterministic context file generator
│   ├── launcher.py         # Native session launch helpers
│   ├── discipline.py       # Pure Python project audit
│   ├── memory.py           # SQLite FTS5 memory store
│   ├── memory_handlers.py  # EventBus handlers for auto-storing results
│   ├── events/             # Event-driven infrastructure
│   └── tools/
│       ├── base.py         # ToolAdapter base class + ToolResult
│       ├── research.py     # Research adapter (split-topic)
│       ├── strategy.py     # Strategy adapter (pressure-test)
│       └── gsd_adapter.py  # Management adapter (context files)
├── tests/                  # 155 tests, 90% coverage
├── research/               # Generated research artifacts
├── flowstate.json          # Pipeline state (gitignored)
├── memory.db               # Persistent memory (gitignored)
└── pyproject.toml

How Components Interact

The full data path for a flowstate init run:
CLI (cli.py)
  └─▶ Interview (interview.py)          # gathers user answers
        └─▶ Orchestrator (orchestrator.py)
              ├─▶ Context Generator (context.py)   # Layer 1 — pure Python
              ├─▶ ResearchAdapter (research.py)
              │     └─▶ ClaudeBridge (bridge.py)   # Layer 2 — claude --print
              ├─▶ StrategyAdapter (strategy.py)
              │     └─▶ ClaudeBridge (bridge.py)   # Layer 2 — claude --print
              ├─▶ GSDAdapter (gsd_adapter.py)
              │     └─▶ Context Generator (context.py)
              └─▶ DisciplineAudit (discipline.py)  # pure Python
                    └─▶ Launcher (launcher.py)     # Layer 3 — prints commands

Architecture Diagram

┌──────────────────────────────────────────────────┐
│                   flowstate CLI                   │
│  init · status · launch · context · memory · check│
└─────────────────────┬────────────────────────────┘

┌─────────────────────▼────────────────────────────┐
│                 Orchestrator                       │
│   5-step pipeline with state persistence           │
│   EventBus emits StepCompleted / StepFailed        │
└──┬──────────┬──────────┬──────────┬──────────┬───┘
   │          │          │          │          │
   ▼          ▼          ▼          ▼          ▼
Context    Research   Strategy    GSD      Discipline
Generator  Adapter    Adapter   Adapter     Audit
(Python)   (bridge)   (bridge)  (context)  (Python)
   │          │          │          │          │
   ▼          ▼          ▼          ▼          ▼
 5 files   claude     claude    .planning/  git/test
 written   --print    --print   files       checks

              ┌───────▼────────┐
              │  MemoryStore   │
              │  (SQLite FTS5) │
              │  memory.db     │
              └────────────────┘

Event-Driven Side Channel

The EventBus runs alongside the main pipeline and decouples memory storage from step execution. After each tool succeeds or fails, _run_step() in the orchestrator emits a StepCompleted or StepFailed event. Memory handlers registered on the bus listen for these events and react independently without the orchestrator knowing anything about memory internals.
# orchestrator emits on success
bus.emit(
    StepCompleted(
        payload={"tool": tool_name, "artifacts": result.artifacts},
        source="orchestrator",
    )
)

# memory handler reacts — reads artifact files, splits by ## headings
@handler("step.completed", priority=EventPriority.AUDIT)
def on_step_completed(event: Event) -> None:
    ...
This means you can add logging, alerting, or custom persistence to the pipeline by registering a new handler on the bus — no changes to the orchestrator required.

Key Design Decisions

ClaudeBridge is the core abstraction. All LLM interaction flows through ClaudeBridge in bridge.py, which wraps claude --print with --system-prompt, --allowedTools, --max-turns, and model selection. Tool adapters never call subprocess themselves; they call self.bridge.run(...) and receive a BridgeResult.
Prompt is a positional argument to the claude CLI. The prompt text is passed as a positional argument, not via stdin or a flag. ClaudeBridge constructs the subprocess call accordingly.
The CLAUDECODE environment variable must be unset for nested invocation. When flowstate init runs from inside an existing Claude Code session, the CLAUDECODE env var set by the parent session would block subprocess invocation. ClaudeBridge strips this variable before every claude --print call.
State is persisted after every step for crash resilience. save_state(state, root) is called after context generation and inside _run_step() after each tool completes. If the pipeline crashes mid-run, flowstate init --skip-interview picks up from the last saved state and the next flowstate status renders the correct tool statuses from flowstate.json.

Test Approach

The test suite has 155 tests at 90% coverage. All tests use dry_run=True so no real claude CLI is required. The dry-run path is a first-class feature: every adapter has a mock template that writes realistic output files, _run_step() returns real ToolResult objects, and ClaudeBridge short-circuits before any subprocess call.
# Run the full suite — no claude CLI needed
source .venv/bin/activate
python -m pytest tests/ -v

Explore the Internals

Orchestrator

How run_pipeline() sequences the five steps, manages _run_step(), and coordinates the EventBus.

Adapters

ResearchAdapter, StrategyAdapter, GSDAdapter, and DisciplineAudit — their prompts, mock modes, and ToolResult contract.

State

Pydantic models, flowstate.json schema, ToolStatus lifecycle, and v0.1.0 → v0.2.0 migration.

Events

EventBus, StepCompleted/StepFailed events, and the memory handler registration pattern.

Build docs developers (and LLMs) love