feature/capability-based-deps #53

Merged
david merged 130 commits from feature/capability-based-deps into main 2026-03-31 01:55:23 +00:00
4 changed files with 71 additions and 29 deletions
Showing only changes of commit 637cbc5515 - Show all commits

View File

@@ -51,6 +51,7 @@ def run_pipeline_mode(preset_name: str = "demo"):
from engine.fetch import fetch_all, fetch_poetry, load_cache from engine.fetch import fetch_all, fetch_poetry, load_cache
from engine.pipeline.adapters import ( from engine.pipeline.adapters import (
RenderStage, RenderStage,
SourceItemsToBufferStage,
create_items_stage, create_items_stage,
create_stage_from_display, create_stage_from_display,
create_stage_from_effect, create_stage_from_effect,
@@ -85,6 +86,16 @@ def run_pipeline_mode(preset_name: str = "demo"):
) )
print(" \033[38;5;245mFetching content...\033[0m") print(" \033[38;5;245mFetching content...\033[0m")
# Handle special sources that don't need traditional fetching
introspection_source = None
if preset.source == "pipeline-inspect":
items = []
print(" \033[38;5;245mUsing pipeline introspection source\033[0m")
elif preset.source == "empty":
items = []
print(" \033[38;5;245mUsing empty source (no content)\033[0m")
else:
cached = load_cache() cached = load_cache()
if cached: if cached:
items = cached items = cached
@@ -108,7 +119,34 @@ def run_pipeline_mode(preset_name: str = "demo"):
effect_registry = get_registry() effect_registry = get_registry()
# Create source stage based on preset source type
if preset.source == "pipeline-inspect":
from engine.data_sources.pipeline_introspection import (
PipelineIntrospectionSource,
)
from engine.pipeline.adapters import DataSourceStage
introspection_source = PipelineIntrospectionSource(
pipeline=None, # Will be set after pipeline.build()
viewport_width=80,
viewport_height=24,
)
pipeline.add_stage(
"source", DataSourceStage(introspection_source, name="pipeline-inspect")
)
elif preset.source == "empty":
from engine.data_sources.sources import EmptyDataSource
from engine.pipeline.adapters import DataSourceStage
empty_source = EmptyDataSource(width=80, height=24)
pipeline.add_stage("source", DataSourceStage(empty_source, name="empty"))
else:
pipeline.add_stage("source", create_items_stage(items, preset.source)) pipeline.add_stage("source", create_items_stage(items, preset.source))
# Add appropriate render stage
if preset.source in ("pipeline-inspect", "empty"):
pipeline.add_stage("render", SourceItemsToBufferStage(name="items-to-buffer"))
else:
pipeline.add_stage( pipeline.add_stage(
"render", "render",
RenderStage( RenderStage(
@@ -132,6 +170,10 @@ def run_pipeline_mode(preset_name: str = "demo"):
pipeline.build() pipeline.build()
# For pipeline-inspect, set the pipeline after build to avoid circular dependency
if introspection_source is not None:
introspection_source.set_pipeline(pipeline)
if not pipeline.initialize(): if not pipeline.initialize():
print(" \033[38;5;196mFailed to initialize pipeline\033[0m") print(" \033[38;5;196mFailed to initialize pipeline\033[0m")
sys.exit(1) sys.exit(1)
@@ -162,7 +204,7 @@ def run_pipeline_mode(preset_name: str = "demo"):
result = pipeline.execute(items) result = pipeline.execute(items)
if result.success: if result.success:
display.show(result.data) display.show(result.data, border=params.border)
if hasattr(display, "is_quit_requested") and display.is_quit_requested(): if hasattr(display, "is_quit_requested") and display.is_quit_requested():
if hasattr(display, "clear_quit_request"): if hasattr(display, "clear_quit_request"):

View File

@@ -30,9 +30,9 @@ class MultiDisplay:
for d in self.displays: for d in self.displays:
d.init(width, height, reuse=reuse) d.init(width, height, reuse=reuse)
def show(self, buffer: list[str]) -> None: def show(self, buffer: list[str], border: bool = False) -> None:
for d in self.displays: for d in self.displays:
d.show(buffer) d.show(buffer, border=border)
def clear(self) -> None: def clear(self) -> None:
for d in self.displays: for d in self.displays:

View File

@@ -24,7 +24,7 @@ class Display(Protocol):
"""Initialize display with dimensions.""" """Initialize display with dimensions."""
... ...
def show(self, buffer: list[str]) -> None: def show(self, buffer: list[str], border: bool = False) -> None:
"""Show buffer on display.""" """Show buffer on display."""
... ...

View File

@@ -165,10 +165,10 @@ class TestMultiDisplay:
multi = MultiDisplay([mock_display1, mock_display2]) multi = MultiDisplay([mock_display1, mock_display2])
buffer = ["line1", "line2"] buffer = ["line1", "line2"]
multi.show(buffer) multi.show(buffer, border=False)
mock_display1.show.assert_called_once_with(buffer) mock_display1.show.assert_called_once_with(buffer, border=False)
mock_display2.show.assert_called_once_with(buffer) mock_display2.show.assert_called_once_with(buffer, border=False)
def test_clear_forwards_to_all_displays(self): def test_clear_forwards_to_all_displays(self):
"""clear forwards to all displays.""" """clear forwards to all displays."""