forked from genewildish/Mainline
feat(repl): Add REPL effect with HUD-style interactive interface
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
This commit is contained in:
78
examples/repl_simple.py
Normal file
78
examples/repl_simple.py
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user