forked from genewildish/Mainline
Implement a Read-Eval-Print Loop (REPL) effect that provides a HUD-style overlay for interactive pipeline control. ## New Files - engine/effects/plugins/repl.py - REPL effect plugin with command processor - engine/display/backends/terminal.py - Added raw mode and input handling - examples/repl_simple.py - Simple demonstration script - tests/test_repl_effect.py - 18 comprehensive tests ## Features ### REPL Interface - HUD-style overlay showing FPS, command history, output buffer size - Command history navigation (Up/Down arrows) - Command execution (Enter) - Character input and backspace support - Output buffer with scrolling ### Commands - help - Show available commands - status - Show pipeline status and metrics - effects - List all effects in pipeline - effect <name> <on|off> - Toggle effect - param <effect> <param> <value> - Set parameter - pipeline - Show current pipeline order - clear - Clear output buffer - quit - Show exit message ### Terminal Input Support - Added set_raw_mode() to TerminalDisplay for capturing keystrokes - Added get_input_keys() to read keyboard input - Proper terminal state restoration on cleanup ## Usage Add 'repl' to effects in your configuration: ## Testing All 18 REPL tests pass, covering: - Effect registration - Command processing - Navigation (history, editing) - Configuration - Rendering ## Integration The REPL effect integrates with the existing pipeline system: - Uses EffectPlugin interface - Supports partial updates - Reads metrics from EffectContext - Can be controlled via keyboard when terminal display is in raw mode Next steps: - Integrate REPL input handling into pipeline_runner.py - Add keyboard event processing loop - Create full demo with interactive features
79 lines
2.1 KiB
Python
79 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Simple REPL Demo - Just shows the REPL effect rendering
|
|
|
|
This is a simpler version that doesn't require raw terminal mode,
|
|
just demonstrates the REPL effect rendering.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from engine.effects.plugins import discover_plugins
|
|
from engine.effects.registry import get_registry
|
|
from engine.effects.types import EffectContext
|
|
from engine.pipeline.hybrid_config import PipelineConfig
|
|
|
|
|
|
def main():
|
|
"""Run simple REPL demo."""
|
|
print("Simple REPL Demo")
|
|
print("=" * 50)
|
|
|
|
# Discover plugins
|
|
discover_plugins()
|
|
|
|
# Create a simple pipeline with REPL
|
|
config = PipelineConfig(
|
|
source="headlines",
|
|
effects=[{"name": "repl", "intensity": 1.0}],
|
|
display={"backend": "null"},
|
|
)
|
|
|
|
pipeline = config.to_pipeline(viewport_width=80, viewport_height=24)
|
|
|
|
# Initialize pipeline
|
|
if not pipeline.initialize():
|
|
print("Failed to initialize pipeline")
|
|
return
|
|
|
|
# Get the REPL effect
|
|
repl_effect = None
|
|
for stage in pipeline._stages.values():
|
|
if hasattr(stage, "_effect") and stage._effect.name == "repl":
|
|
repl_effect = stage._effect
|
|
break
|
|
|
|
if not repl_effect:
|
|
print("REPL effect not found")
|
|
return
|
|
|
|
# Get the EffectContext for REPL
|
|
# Note: In a real pipeline, the EffectContext is created per-stage
|
|
# For this demo, we'll simulate by adding commands
|
|
|
|
# Add some commands to the output
|
|
repl_effect.process_command("help")
|
|
repl_effect.process_command("status")
|
|
repl_effect.process_command("effects")
|
|
repl_effect.process_command("pipeline")
|
|
|
|
# Execute pipeline to see REPL output
|
|
result = pipeline.execute([])
|
|
|
|
if result.success:
|
|
print("\nPipeline Output:")
|
|
print("-" * 50)
|
|
for line in result.data:
|
|
print(line)
|
|
print("-" * 50)
|
|
print(f"\n✓ Successfully rendered {len(result.data)} lines")
|
|
else:
|
|
print(f"✗ Pipeline error: {result.error}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|