kollabor 0.4.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. core/__init__.py +18 -0
  2. core/application.py +578 -0
  3. core/cli.py +193 -0
  4. core/commands/__init__.py +43 -0
  5. core/commands/executor.py +277 -0
  6. core/commands/menu_renderer.py +319 -0
  7. core/commands/parser.py +186 -0
  8. core/commands/registry.py +331 -0
  9. core/commands/system_commands.py +479 -0
  10. core/config/__init__.py +7 -0
  11. core/config/llm_task_config.py +110 -0
  12. core/config/loader.py +501 -0
  13. core/config/manager.py +112 -0
  14. core/config/plugin_config_manager.py +346 -0
  15. core/config/plugin_schema.py +424 -0
  16. core/config/service.py +399 -0
  17. core/effects/__init__.py +1 -0
  18. core/events/__init__.py +12 -0
  19. core/events/bus.py +129 -0
  20. core/events/executor.py +154 -0
  21. core/events/models.py +258 -0
  22. core/events/processor.py +176 -0
  23. core/events/registry.py +289 -0
  24. core/fullscreen/__init__.py +19 -0
  25. core/fullscreen/command_integration.py +290 -0
  26. core/fullscreen/components/__init__.py +12 -0
  27. core/fullscreen/components/animation.py +258 -0
  28. core/fullscreen/components/drawing.py +160 -0
  29. core/fullscreen/components/matrix_components.py +177 -0
  30. core/fullscreen/manager.py +302 -0
  31. core/fullscreen/plugin.py +204 -0
  32. core/fullscreen/renderer.py +282 -0
  33. core/fullscreen/session.py +324 -0
  34. core/io/__init__.py +52 -0
  35. core/io/buffer_manager.py +362 -0
  36. core/io/config_status_view.py +272 -0
  37. core/io/core_status_views.py +410 -0
  38. core/io/input_errors.py +313 -0
  39. core/io/input_handler.py +2655 -0
  40. core/io/input_mode_manager.py +402 -0
  41. core/io/key_parser.py +344 -0
  42. core/io/layout.py +587 -0
  43. core/io/message_coordinator.py +204 -0
  44. core/io/message_renderer.py +601 -0
  45. core/io/modal_interaction_handler.py +315 -0
  46. core/io/raw_input_processor.py +946 -0
  47. core/io/status_renderer.py +845 -0
  48. core/io/terminal_renderer.py +586 -0
  49. core/io/terminal_state.py +551 -0
  50. core/io/visual_effects.py +734 -0
  51. core/llm/__init__.py +26 -0
  52. core/llm/api_communication_service.py +863 -0
  53. core/llm/conversation_logger.py +473 -0
  54. core/llm/conversation_manager.py +414 -0
  55. core/llm/file_operations_executor.py +1401 -0
  56. core/llm/hook_system.py +402 -0
  57. core/llm/llm_service.py +1629 -0
  58. core/llm/mcp_integration.py +386 -0
  59. core/llm/message_display_service.py +450 -0
  60. core/llm/model_router.py +214 -0
  61. core/llm/plugin_sdk.py +396 -0
  62. core/llm/response_parser.py +848 -0
  63. core/llm/response_processor.py +364 -0
  64. core/llm/tool_executor.py +520 -0
  65. core/logging/__init__.py +19 -0
  66. core/logging/setup.py +208 -0
  67. core/models/__init__.py +5 -0
  68. core/models/base.py +23 -0
  69. core/plugins/__init__.py +13 -0
  70. core/plugins/collector.py +212 -0
  71. core/plugins/discovery.py +386 -0
  72. core/plugins/factory.py +263 -0
  73. core/plugins/registry.py +152 -0
  74. core/storage/__init__.py +5 -0
  75. core/storage/state_manager.py +84 -0
  76. core/ui/__init__.py +6 -0
  77. core/ui/config_merger.py +176 -0
  78. core/ui/config_widgets.py +369 -0
  79. core/ui/live_modal_renderer.py +276 -0
  80. core/ui/modal_actions.py +162 -0
  81. core/ui/modal_overlay_renderer.py +373 -0
  82. core/ui/modal_renderer.py +591 -0
  83. core/ui/modal_state_manager.py +443 -0
  84. core/ui/widget_integration.py +222 -0
  85. core/ui/widgets/__init__.py +27 -0
  86. core/ui/widgets/base_widget.py +136 -0
  87. core/ui/widgets/checkbox.py +85 -0
  88. core/ui/widgets/dropdown.py +140 -0
  89. core/ui/widgets/label.py +78 -0
  90. core/ui/widgets/slider.py +185 -0
  91. core/ui/widgets/text_input.py +224 -0
  92. core/utils/__init__.py +11 -0
  93. core/utils/config_utils.py +656 -0
  94. core/utils/dict_utils.py +212 -0
  95. core/utils/error_utils.py +275 -0
  96. core/utils/key_reader.py +171 -0
  97. core/utils/plugin_utils.py +267 -0
  98. core/utils/prompt_renderer.py +151 -0
  99. kollabor-0.4.9.dist-info/METADATA +298 -0
  100. kollabor-0.4.9.dist-info/RECORD +128 -0
  101. kollabor-0.4.9.dist-info/WHEEL +5 -0
  102. kollabor-0.4.9.dist-info/entry_points.txt +2 -0
  103. kollabor-0.4.9.dist-info/licenses/LICENSE +21 -0
  104. kollabor-0.4.9.dist-info/top_level.txt +4 -0
  105. kollabor_cli_main.py +20 -0
  106. plugins/__init__.py +1 -0
  107. plugins/enhanced_input/__init__.py +18 -0
  108. plugins/enhanced_input/box_renderer.py +103 -0
  109. plugins/enhanced_input/box_styles.py +142 -0
  110. plugins/enhanced_input/color_engine.py +165 -0
  111. plugins/enhanced_input/config.py +150 -0
  112. plugins/enhanced_input/cursor_manager.py +72 -0
  113. plugins/enhanced_input/geometry.py +81 -0
  114. plugins/enhanced_input/state.py +130 -0
  115. plugins/enhanced_input/text_processor.py +115 -0
  116. plugins/enhanced_input_plugin.py +385 -0
  117. plugins/fullscreen/__init__.py +9 -0
  118. plugins/fullscreen/example_plugin.py +327 -0
  119. plugins/fullscreen/matrix_plugin.py +132 -0
  120. plugins/hook_monitoring_plugin.py +1299 -0
  121. plugins/query_enhancer_plugin.py +350 -0
  122. plugins/save_conversation_plugin.py +502 -0
  123. plugins/system_commands_plugin.py +93 -0
  124. plugins/tmux_plugin.py +795 -0
  125. plugins/workflow_enforcement_plugin.py +629 -0
  126. system_prompt/default.md +1286 -0
  127. system_prompt/default_win.md +265 -0
  128. system_prompt/example_with_trender.md +47 -0
@@ -0,0 +1,327 @@
1
+ """Example full-screen plugin demonstrating framework capabilities."""
2
+
3
+ import asyncio
4
+ import math
5
+ from core.fullscreen import FullScreenPlugin
6
+ from core.fullscreen.plugin import PluginMetadata
7
+ from core.fullscreen.components.drawing import DrawingPrimitives
8
+ from core.fullscreen.components.animation import AnimationFramework, EasingFunctions
9
+ from core.io.visual_effects import ColorPalette
10
+ from core.io.key_parser import KeyPress
11
+
12
+
13
+ class ExamplePlugin(FullScreenPlugin):
14
+ """Example plugin showcasing full-screen framework features.
15
+
16
+ This plugin demonstrates:
17
+ - Drawing primitives (text, borders, shapes)
18
+ - Animation framework (fade, slide, bounce)
19
+ - Input handling
20
+ - Multi-page layouts
21
+ """
22
+
23
+ def __init__(self):
24
+ """Initialize the example plugin."""
25
+ metadata = PluginMetadata(
26
+ name="example",
27
+ description="Example plugin showcasing framework features",
28
+ version="1.0.0",
29
+ author="Framework",
30
+ category="demo",
31
+ icon="🎯",
32
+ aliases=[]
33
+ )
34
+ super().__init__(metadata)
35
+
36
+ # Plugin state
37
+ self.current_page = 0
38
+ self.total_pages = 4
39
+ self.animation_framework = AnimationFramework()
40
+ self.page_transition_id = None
41
+ self.demo_animations = {}
42
+ self.frame_count = 0
43
+
44
+ async def initialize(self, renderer) -> bool:
45
+ """Initialize the example plugin."""
46
+ print("🔍 CRITICAL: ExamplePlugin.initialize() called")
47
+ try:
48
+ if not await super().initialize(renderer):
49
+ print("❌ CRITICAL: super().initialize() failed")
50
+ return False
51
+
52
+ # Setup initial animations
53
+ current_time = asyncio.get_event_loop().time()
54
+ self.demo_animations['title_fade'] = self.animation_framework.fade_in(2.0, current_time)
55
+ self.demo_animations['bounce'] = self.animation_framework.bounce_in(1.5, current_time + 0.5)
56
+
57
+ print("✅ CRITICAL: ExamplePlugin.initialize() completed successfully")
58
+ return True
59
+ except Exception as e:
60
+ print(f"❌ CRITICAL: Exception in initialize(): {e}")
61
+ import traceback
62
+ traceback.print_exc()
63
+ return False
64
+
65
+ async def on_start(self):
66
+ """Called when Example plugin starts."""
67
+ await super().on_start()
68
+
69
+ async def render_frame(self, delta_time: float) -> bool:
70
+ """Render the example plugin frame."""
71
+ if not self.renderer:
72
+ return False
73
+
74
+ # Increment frame counter for animations
75
+ self.frame_count += 1
76
+
77
+ # Clear screen and show content
78
+ self.renderer.clear_screen()
79
+ width, height = self.renderer.get_terminal_size()
80
+
81
+ # Render current page
82
+ if self.current_page == 0:
83
+ self._render_welcome_page(width, height)
84
+ elif self.current_page == 1:
85
+ self._render_drawing_demo(width, height)
86
+ elif self.current_page == 2:
87
+ self._render_animation_demo(width, height)
88
+ elif self.current_page == 3:
89
+ self._render_final_page(width, height)
90
+
91
+ # Show navigation instructions
92
+ nav_text = f"Page {self.current_page + 1}/{self.total_pages} • ←→ or h/l navigate • 1-4 direct • q/ESC exit"
93
+ nav_x = (width - len(nav_text)) // 2
94
+ self.renderer.write_at(nav_x, height - 1, nav_text, "\033[37m")
95
+
96
+ # Flush output
97
+ self.renderer.flush()
98
+ return True
99
+
100
+ def _render_welcome_page(self, width: int, height: int):
101
+ """Render the welcome page."""
102
+ # Animated title
103
+ title_alpha = self.animation_framework.get_value(self.demo_animations.get('title_fade', 0))
104
+ if title_alpha > 0.5: # Show when fade is mostly complete
105
+ DrawingPrimitives.draw_text_centered(
106
+ self.renderer, height // 4,
107
+ "🎯 Full-Screen Framework Demo",
108
+ ColorPalette.BRIGHT_CYAN
109
+ )
110
+
111
+ # Bouncing subtitle
112
+ bounce_offset = int(self.animation_framework.get_value(self.demo_animations.get('bounce', 0)) * 3)
113
+ DrawingPrimitives.draw_text_centered(
114
+ self.renderer, height // 2 - bounce_offset,
115
+ "Welcome to the Plugin Framework!",
116
+ ColorPalette.BRIGHT_GREEN
117
+ )
118
+
119
+ # Static content
120
+ DrawingPrimitives.draw_text_centered(
121
+ self.renderer, height // 2 + 2,
122
+ "This framework provides:",
123
+ ColorPalette.WHITE
124
+ )
125
+
126
+ features = [
127
+ "• Complete terminal takeover",
128
+ "• Modal system integration",
129
+ "• Drawing primitives & animations",
130
+ "• Plugin lifecycle management",
131
+ "• Input handling & routing"
132
+ ]
133
+
134
+ for i, feature in enumerate(features):
135
+ DrawingPrimitives.draw_text_centered(
136
+ self.renderer, height // 2 + 4 + i,
137
+ feature,
138
+ ColorPalette.YELLOW
139
+ )
140
+
141
+ def _render_drawing_demo(self, width: int, height: int):
142
+ """Render drawing primitives demonstration."""
143
+ DrawingPrimitives.draw_text_centered(
144
+ self.renderer, 2,
145
+ "Drawing Primitives Demo",
146
+ ColorPalette.BRIGHT_MAGENTA
147
+ )
148
+
149
+ # Draw various shapes and elements
150
+ center_x, center_y = width // 2, height // 2
151
+
152
+ # Border around demo area
153
+ DrawingPrimitives.draw_border(
154
+ self.renderer, center_x - 20, center_y - 8, 40, 16,
155
+ color=ColorPalette.CYAN
156
+ )
157
+
158
+ # Progress bar
159
+ progress = (self.frame_count % 100) / 100.0
160
+ DrawingPrimitives.draw_progress_bar(
161
+ self.renderer, center_x - 15, center_y - 5, 30, progress,
162
+ color=ColorPalette.GREEN
163
+ )
164
+ DrawingPrimitives.draw_text_centered(
165
+ self.renderer, center_y - 6,
166
+ f"Progress: {progress:.0%}",
167
+ ColorPalette.WHITE
168
+ )
169
+
170
+ # Spinner
171
+ DrawingPrimitives.draw_spinner(
172
+ self.renderer, center_x - 2, center_y - 2, self.frame_count // 5,
173
+ color=ColorPalette.BRIGHT_BLUE
174
+ )
175
+ self.renderer.write_at(center_x + 2, center_y - 2, "Loading...", ColorPalette.WHITE)
176
+
177
+ # Circle points
178
+ radius = 8
179
+ DrawingPrimitives.draw_circle_points(
180
+ self.renderer, center_x, center_y + 3, radius,
181
+ char="●", color=ColorPalette.RED
182
+ )
183
+
184
+ # Wave
185
+ wave_phase = self.frame_count * 0.1
186
+ DrawingPrimitives.draw_wave(
187
+ self.renderer, height - 5, 2, 0.3, wave_phase,
188
+ char="~", color=ColorPalette.BLUE
189
+ )
190
+
191
+ def _render_animation_demo(self, width: int, height: int):
192
+ """Render animation framework demonstration."""
193
+ DrawingPrimitives.draw_text_centered(
194
+ self.renderer, 2,
195
+ "Animation Framework Demo",
196
+ ColorPalette.BRIGHT_YELLOW
197
+ )
198
+
199
+ center_x, center_y = width // 2, height // 2
200
+
201
+ # Create cycling animations
202
+ current_time = asyncio.get_event_loop().time()
203
+
204
+ # Pulsing circle
205
+ pulse_size = 5 + int(3 * math.sin(current_time * 2))
206
+ for r in range(1, pulse_size):
207
+ DrawingPrimitives.draw_circle_points(
208
+ self.renderer, center_x, center_y, r,
209
+ char="○", color=ColorPalette.GREEN
210
+ )
211
+
212
+ # Sliding text
213
+ slide_x = int(20 * math.sin(current_time))
214
+ self.renderer.write_at(center_x + slide_x, center_y - 5, "← Sliding Text →", ColorPalette.CYAN)
215
+
216
+ # Fading elements
217
+ fade_alpha = (math.sin(current_time * 1.5) + 1) / 2
218
+ if fade_alpha > 0.3: # Only show when bright enough
219
+ intensity = "▓" if fade_alpha > 0.7 else "░"
220
+ fade_text = f"Fading {intensity}"
221
+ DrawingPrimitives.draw_text_centered(
222
+ self.renderer, center_y + 3,
223
+ fade_text,
224
+ ColorPalette.MAGENTA
225
+ )
226
+
227
+ # Bouncing ball
228
+ bounce_y = center_y + 6 + int(3 * abs(math.sin(current_time * 3)))
229
+ self.renderer.write_at(center_x, bounce_y, "●", ColorPalette.RED)
230
+
231
+ def _render_final_page(self, width: int, height: int):
232
+ """Render the final page with improved layout."""
233
+ # Title at top
234
+ DrawingPrimitives.draw_text_centered(
235
+ self.renderer, 3,
236
+ "🚀 Ready to Build Plugins!",
237
+ ColorPalette.BRIGHT_GREEN
238
+ )
239
+
240
+ # Plugin template example - more compact positioning
241
+ code_lines = [
242
+ "class MyPlugin(FullScreenPlugin):",
243
+ " async def render_frame(self, delta_time):",
244
+ " self.renderer.clear_screen()",
245
+ " # Your awesome content here!",
246
+ " return True",
247
+ "",
248
+ " async def handle_input(self, key_press):",
249
+ " return key_press.char == 'q'"
250
+ ]
251
+
252
+ # Position code in upper middle area
253
+ start_y = 6
254
+ for i, line in enumerate(code_lines):
255
+ x = max(0, (width - len(line)) // 2)
256
+ self.renderer.write_at(x, start_y + i, line, ColorPalette.YELLOW)
257
+
258
+ # Features section positioned below code
259
+ features_start_y = start_y + len(code_lines) + 2
260
+ DrawingPrimitives.draw_text_centered(
261
+ self.renderer, features_start_y,
262
+ "Framework Features Available:",
263
+ ColorPalette.WHITE
264
+ )
265
+
266
+ features = [
267
+ "✓ Modal system integration",
268
+ "✓ Terminal state management",
269
+ "✓ Drawing primitives library",
270
+ "✓ Animation framework",
271
+ "✓ Input handling system"
272
+ ]
273
+
274
+ for i, feature in enumerate(features):
275
+ DrawingPrimitives.draw_text_centered(
276
+ self.renderer, features_start_y + 2 + i,
277
+ feature,
278
+ ColorPalette.BRIGHT_CYAN
279
+ )
280
+
281
+ def _render_navigation(self, width: int, height: int):
282
+ """Render navigation controls."""
283
+ nav_text = f"Page {self.current_page + 1}/{self.total_pages} • ←→ Navigate • Q/ESC Exit"
284
+ DrawingPrimitives.draw_text_centered(
285
+ self.renderer, height - 2,
286
+ nav_text,
287
+ ColorPalette.DIM_WHITE
288
+ )
289
+
290
+ async def handle_input(self, key_press: KeyPress) -> bool:
291
+ """Handle input for the example plugin."""
292
+ # Exit on 'q' or ESC
293
+ if key_press.char in ['q', '\x1b'] or key_press.name == "Escape":
294
+ return True
295
+
296
+ # Navigation with multiple options
297
+ if key_press.char == 'h' or key_press.char == 'a' or key_press.name == "ArrowLeft":
298
+ if self.current_page > 0:
299
+ self.current_page -= 1
300
+ await self._start_page_transition()
301
+ elif key_press.char == 'l' or key_press.char == 'd' or key_press.name == "ArrowRight":
302
+ if self.current_page < self.total_pages - 1:
303
+ self.current_page += 1
304
+ await self._start_page_transition()
305
+ elif key_press.char in ['1', '2', '3', '4']: # Direct page navigation
306
+ new_page = int(key_press.char) - 1
307
+ if 0 <= new_page < self.total_pages:
308
+ self.current_page = new_page
309
+ await self._start_page_transition()
310
+
311
+ return False
312
+
313
+ async def _start_page_transition(self):
314
+ """Start page transition animation."""
315
+ current_time = asyncio.get_event_loop().time()
316
+ # Could add page transition animations here
317
+ # For now, just reset some demo animations
318
+ self.demo_animations['bounce'] = self.animation_framework.bounce_in(0.5, current_time)
319
+
320
+ async def on_stop(self):
321
+ """Called when Example plugin stops."""
322
+ await super().on_stop()
323
+
324
+ async def cleanup(self):
325
+ """Clean up example plugin resources."""
326
+ self.animation_framework.clear_all()
327
+ await super().cleanup()
@@ -0,0 +1,132 @@
1
+ """Matrix rain plugin using the full-screen framework."""
2
+
3
+ import asyncio
4
+ import logging
5
+ from core.fullscreen import FullScreenPlugin
6
+ from core.fullscreen.plugin import PluginMetadata
7
+ from core.fullscreen.components.matrix_components import MatrixRenderer
8
+ from core.io.key_parser import KeyPress
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class MatrixRainPlugin(FullScreenPlugin):
14
+ """Matrix rain effect implemented as a full-screen plugin.
15
+
16
+ This plugin creates the iconic Matrix digital rain effect with falling
17
+ green characters, providing an immersive full-screen experience.
18
+ """
19
+
20
+ def __init__(self):
21
+ """Initialize the Matrix rain plugin."""
22
+ metadata = PluginMetadata(
23
+ name="matrix",
24
+ description="Enter the Matrix with falling code rain",
25
+ version="1.0.0",
26
+ author="Framework",
27
+ category="effects",
28
+ icon="🔋",
29
+ aliases=[]
30
+ )
31
+ super().__init__(metadata)
32
+
33
+ # Matrix-specific state
34
+ self.matrix_renderer = None
35
+ self.start_time = 0
36
+
37
+ async def initialize(self, renderer) -> bool:
38
+ """Initialize the Matrix plugin.
39
+
40
+ Args:
41
+ renderer: FullScreenRenderer instance
42
+
43
+ Returns:
44
+ True if initialization successful
45
+ """
46
+ if not await super().initialize(renderer):
47
+ return False
48
+
49
+ try:
50
+ # Get terminal dimensions for Matrix renderer
51
+ width, height = renderer.get_terminal_size()
52
+
53
+ # Create Matrix renderer with current terminal size
54
+ self.matrix_renderer = MatrixRenderer(width, height)
55
+
56
+ return True
57
+
58
+ except Exception as e:
59
+ logger.error(f"Failed to initialize Matrix renderer: {e}")
60
+ return False
61
+
62
+ async def on_start(self):
63
+ """Called when Matrix plugin starts."""
64
+ await super().on_start()
65
+ self.start_time = asyncio.get_event_loop().time()
66
+
67
+ # DISTINCTIVE LOG TO PROVE NEW FRAMEWORK IS USED
68
+ logger.info("🎯 NEW FRAMEWORK: MatrixRainPlugin.on_start() called - using full-screen plugin framework!")
69
+ print("🎯 NEW FRAMEWORK: Matrix plugin starting via full-screen framework!")
70
+
71
+ # Reset Matrix renderer for fresh start
72
+ if self.matrix_renderer:
73
+ self.matrix_renderer.reset()
74
+
75
+ async def render_frame(self, delta_time: float) -> bool:
76
+ """Render a Matrix rain frame.
77
+
78
+ Args:
79
+ delta_time: Time elapsed since last frame
80
+
81
+ Returns:
82
+ True to continue, False to exit
83
+ """
84
+ if not self.renderer or not self.matrix_renderer:
85
+ return False
86
+
87
+ try:
88
+ # Calculate current time for Matrix animation
89
+ current_time = asyncio.get_event_loop().time() - self.start_time
90
+
91
+ # Update Matrix animation
92
+ self.matrix_renderer.update(current_time)
93
+
94
+ # Render Matrix to screen
95
+ self.matrix_renderer.render(self.renderer)
96
+
97
+ # Update frame statistics
98
+ self.update_frame_stats()
99
+
100
+ return True
101
+
102
+ except Exception as e:
103
+ logger.error(f"Error rendering Matrix frame: {e}")
104
+ return False
105
+
106
+ async def handle_input(self, key_press: KeyPress) -> bool:
107
+ """Handle input for Matrix plugin.
108
+
109
+ Args:
110
+ key_press: Key that was pressed
111
+
112
+ Returns:
113
+ True to exit Matrix, False to continue
114
+ """
115
+ # Exit on 'q', ESC, or Escape key
116
+ if key_press.char in ['q', '\x1b'] or key_press.name == "Escape":
117
+ return True
118
+
119
+ # Continue running for all other keys
120
+ return False
121
+
122
+ async def on_stop(self):
123
+ """Called when Matrix plugin stops."""
124
+ await super().on_stop()
125
+
126
+ # Optional: Could add fade-out effect here
127
+ # or save statistics about the session
128
+
129
+ async def cleanup(self):
130
+ """Clean up Matrix plugin resources."""
131
+ self.matrix_renderer = None
132
+ await super().cleanup()