--- name: mainline-architecture description: Pipeline stages, capability resolution, and core architecture patterns compatibility: opencode metadata: audience: developers source_type: codebase --- ## What This Skill Covers This skill covers Mainline's pipeline architecture - the Stage-based system for dependency resolution, data flow, and component composition. ## Key Concepts ### Stage Class (engine/pipeline/core.py) The `Stage` ABC is the foundation. All pipeline components inherit from it: ```python class Stage(ABC): name: str category: str # "source", "effect", "overlay", "display", "camera" optional: bool = False @property def capabilities(self) -> set[str]: """What this stage provides (e.g., 'source.headlines')""" return set() @property def dependencies(self) -> list[str]: """What this stage needs (e.g., ['source'])""" return [] ``` ### Capability-Based Dependencies The Pipeline resolves dependencies using **prefix matching**: - `"source"` matches `"source.headlines"`, `"source.poetry"`, etc. - This allows flexible composition without hardcoding specific stage names ### DataType Enum PureData-style data types for inlet/outlet validation: - `SOURCE_ITEMS`: List[SourceItem] - raw items from sources - `ITEM_TUPLES`: List[tuple] - (title, source, timestamp) tuples - `TEXT_BUFFER`: List[str] - rendered ANSI buffer - `RAW_TEXT`: str - raw text strings - `PIL_IMAGE`: PIL Image object ### Pipeline Execution The Pipeline (engine/pipeline/controller.py): 1. Collects all stages from StageRegistry 2. Resolves dependencies using prefix matching 3. Executes stages in dependency order 4. Handles errors for non-optional stages ### Canvas & Camera - **Canvas** (`engine/canvas.py`): 2D rendering surface with dirty region tracking - **Camera** (`engine/camera.py`): Viewport controller for scrolling content Canvas tracks dirty regions automatically when content is written via `put_region`, `put_text`, `fill`, enabling partial buffer updates. ## Adding New Stages 1. Create a class inheriting from `Stage` 2. Define `capabilities` and `dependencies` properties 3. Implement required abstract methods 4. Register in StageRegistry or use as adapter ## Common Patterns - Use adapters (engine/pipeline/adapters.py) to wrap existing components as stages - Set `optional=True` for stages that can fail gracefully - Use `stage_type` and `render_order` for execution ordering