fix: resolve terminal display wobble and effect dimension stability

- Fix TerminalDisplay: add screen clear each frame (cursor home + erase down)
- Fix CameraStage: use set_canvas_size instead of read-only viewport properties
- Fix Glitch effect: preserve visible line lengths, remove cursor positioning
- Fix Fade effect: return original line when fade=0 instead of empty string
- Fix Noise effect: use input line length instead of terminal_width
- Remove HUD effect from all presets (redundant with border FPS display)
- Add regression tests for effect dimension stability
- Add docs/ARCHITECTURE.md with Mermaid diagrams
- Add mise tasks: diagram-ascii, diagram-validate, diagram-check
- Move markdown docs to docs/ (ARCHITECTURE, Refactor, hardware specs)
- Remove redundant requirements files (use pyproject.toml)
- Add *.dot and *.png to .gitignore

Closes #25
This commit is contained in:
2026-03-18 03:34:36 -07:00
parent a65fb50464
commit b926b346ad
30 changed files with 1472 additions and 40 deletions

View File

@@ -483,7 +483,7 @@ class TestPipelineParams:
assert params.source == "headlines"
assert params.display == "terminal"
assert params.camera_mode == "vertical"
assert params.effect_order == ["noise", "fade", "glitch", "firehose", "hud"]
assert params.effect_order == ["noise", "fade", "glitch", "firehose"]
def test_effect_config(self):
"""PipelineParams effect config methods work."""
@@ -634,6 +634,33 @@ class TestStageAdapters:
assert "camera" in stage.capabilities
assert "render.output" in stage.dependencies # Depends on rendered content
def test_camera_stage_does_not_error_on_process(self):
"""CameraStage.process should not error when setting viewport.
Regression test: Previously CameraStage tried to set viewport_width
and viewport_height as writable properties, but they are computed
from canvas_size / zoom. This caused an AttributeError each frame.
"""
from engine.camera import Camera, CameraMode
from engine.pipeline.adapters import CameraStage
from engine.pipeline.core import PipelineContext
from engine.pipeline.params import PipelineParams
camera = Camera(mode=CameraMode.FEED)
stage = CameraStage(camera, name="vertical")
ctx = PipelineContext()
ctx.params = PipelineParams(viewport_width=80, viewport_height=24)
buffer = ["line" + str(i) for i in range(24)]
# This should not raise AttributeError
result = stage.process(buffer, ctx)
# Should return the buffer (unchanged for FEED mode)
assert result is not None
assert len(result) == 24
class TestDataSourceStage:
"""Tests for DataSourceStage adapter."""