Major changes:
- Pipeline architecture with capability-based dependency resolution
- Effects plugin system with performance monitoring
- Display abstraction with multiple backends (terminal, null, websocket)
- Camera system for viewport scrolling
- Sensor framework for real-time input
- Command-and-control system via ntfy
- WebSocket display backend for browser clients
- Comprehensive test suite and documentation
Issue #48: ADR for preset scripting language included
This commit consolidates 110 individual commits into a single
feature integration that can be reviewed and tested before
further refinement.
Gracefully skips figment tests when system Cairo library is unavailable
instead of crashing with opaque OSError during test collection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire render_figment_overlay() into stream() between the effects chain
and the ntfy message overlay, with optional cairosvg import guard.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements phase-aware (REVEAL/HOLD/DISSOLVE) ANSI cursor-positioning overlay
renderer for figment glyphs, with deterministic shuffle seeding and gradient
coloring via _color_codes_to_ansi(). Includes 6 TDD tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements the core figment plugin: timer-driven SVG selection, REVEAL →
HOLD → DISSOLVE state machine, trigger API, and get_figment_state() for
overlay rendering. process() is a deliberate no-op; scroll.py will call
get_figment_state() instead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8-task plan covering SVG rasterization, overlay rendering,
FigmentEffect plugin, trigger protocol, and scroll loop integration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hybrid plugin + overlay architecture for periodic SVG glyph display
with theme-aware coloring and extensible input abstraction.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace lr_gradient_opposite() with msg_gradient() in render_message_overlay().
Messages now render in complementary colors matching the active theme:
- Green theme → magenta messages
- Orange theme → blue messages
- Purple theme → yellow messages
Resolved conflicts in tests/test_config.py by keeping TestActiveTheme tests.
Main branch has new architecture components (controller, events, layers, effects).
Color scheme feature preserved and compatible.
Add msg_gradient() helper function to render.py that applies message
(ntfy) gradient using the active theme's message_gradient property.
This replaces hardcoded magenta gradient in scroll.py with a theme-aware
approach that uses complementary colors from the active theme.
- Add msg_gradient(rows, offset) helper in render.py with fallback to
default magenta gradient when no theme is active
- Update scroll.py imports to use msg_gradient instead of
lr_gradient_opposite
- Replace lr_gradient_opposite() call with msg_gradient() in message
overlay rendering
- Add 6 comprehensive tests for msg_gradient covering theme usage,
fallback behavior, and edge cases
All tests pass (121 passed), no regressions detected.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Remove hardcoded GRAD_COLS and MSG_GRAD_COLS module constants
- Add _default_green_gradient() and _default_magenta_gradient() fallback functions
- Add _color_codes_to_ansi() to convert integer color codes from themes to ANSI escape strings
- Update lr_gradient() signature: cols parameter (was grad_cols)
- lr_gradient() now pulls colors from config.ACTIVE_THEME when available
- Falls back to default green gradient when no theme is active
- Existing calls with explicit cols parameter continue to work
- Add comprehensive tests for new functionality
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Comprehensive plan with 6 chunks, each containing bite-sized TDD tasks:
- Chunk 1: Theme class and registry
- Chunk 2: Config integration
- Chunk 3: Render pipeline
- Chunk 4: Message gradient integration
- Chunk 5: Color picker UI
- Chunk 6: Integration and validation
Each step includes exact code, test commands, and expected output.
- Update opening description to mention selectable color gradients
- Add new 'Color Schemes' section with picker usage instructions
- Document three available themes (Green, Orange, Purple)
- Clarify that boot UI uses hardcoded green, not theme colors
- Clarify boot messages use hardcoded green, not theme gradients
- Finalize all gradient ANSI color codes (no TBD)
- Add initialization guarantee for ACTIVE_THEME
- Resolve circular import risk with data-only themes.py
- Update theme ID naming to match menu labels
- Expand test strategy and mock approach
Add typed dataclasses for tuple returns:
- types.py: HeadlineItem, FetchResult, Block dataclasses with legacy tuple converters
- fetch.py: Add type hints and HeadlineTuple type alias
Add pyright for static type checking:
- Add pyright to dependencies
- Verify type coverage with pyright (0 errors in core modules)
This enables:
- Named types instead of raw tuples (better IDE support, self-documenting)
- Type-safe APIs across modules
- Backward compatibility via to_tuple/from_tuple methods
Note: Lazy imports skipped for render.py - startup impact is minimal.