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,424 @@
1
+ """Plugin configuration schema system for dynamic widget generation.
2
+
3
+ This module provides a comprehensive system for plugins to define their
4
+ configuration schemas, which automatically generates UI widgets and validation.
5
+ """
6
+
7
+ from typing import Any, Dict, List, Optional, Union, Callable
8
+ from dataclasses import dataclass, field
9
+ from enum import Enum
10
+ import logging
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class WidgetType(Enum):
16
+ """Supported widget types for plugin configuration."""
17
+ CHECKBOX = "checkbox"
18
+ SLIDER = "slider"
19
+ TEXT_INPUT = "text_input"
20
+ DROPDOWN = "dropdown"
21
+ COLOR_PICKER = "color_picker"
22
+ FILE_PICKER = "file_picker"
23
+ DIRECTORY_PICKER = "directory_picker"
24
+ MULTI_SELECT = "multi_select"
25
+ KEY_VALUE = "key_value"
26
+ CODE_EDITOR = "code_editor"
27
+
28
+
29
+ class ValidationType(Enum):
30
+ """Supported validation types for config fields."""
31
+ NONE = "none"
32
+ STRING = "string"
33
+ INTEGER = "integer"
34
+ FLOAT = "float"
35
+ BOOLEAN = "boolean"
36
+ URL = "url"
37
+ EMAIL = "email"
38
+ FILE_PATH = "file_path"
39
+ DIRECTORY_PATH = "directory_path"
40
+ JSON = "json"
41
+ REGEX = "regex"
42
+
43
+
44
+ @dataclass
45
+ class ValidationRule:
46
+ """Validation rule for a configuration field."""
47
+ type: ValidationType = ValidationType.NONE
48
+ min_value: Optional[Union[int, float]] = None
49
+ max_value: Optional[Union[int, float]] = None
50
+ pattern: Optional[str] = None
51
+ custom_validator: Optional[Callable[[Any], bool]] = None
52
+ error_message: Optional[str] = None
53
+
54
+ def validate(self, value: Any) -> tuple[bool, Optional[str]]:
55
+ """Validate a value against this rule.
56
+
57
+ Args:
58
+ value: Value to validate.
59
+
60
+ Returns:
61
+ Tuple of (is_valid, error_message).
62
+ """
63
+ try:
64
+ # Type validation
65
+ if self.type == ValidationType.STRING:
66
+ if not isinstance(value, str):
67
+ return False, self.error_message or "Value must be a string"
68
+ elif self.type == ValidationType.INTEGER:
69
+ if not isinstance(value, int):
70
+ return False, self.error_message or "Value must be an integer"
71
+ elif self.type == ValidationType.FLOAT:
72
+ if not isinstance(value, (int, float)):
73
+ return False, self.error_message or "Value must be a number"
74
+ elif self.type == ValidationType.BOOLEAN:
75
+ if not isinstance(value, bool):
76
+ return False, self.error_message or "Value must be a boolean"
77
+
78
+ # Range validation
79
+ if self.min_value is not None and value < self.min_value:
80
+ return False, self.error_message or f"Value must be >= {self.min_value}"
81
+ if self.max_value is not None and value > self.max_value:
82
+ return False, self.error_message or f"Value must be <= {self.max_value}"
83
+
84
+ # Pattern validation
85
+ if self.pattern and isinstance(value, str):
86
+ import re
87
+ if not re.match(self.pattern, value):
88
+ return False, self.error_message or f"Value must match pattern: {self.pattern}"
89
+
90
+ # Custom validation
91
+ if self.custom_validator:
92
+ if not self.custom_validator(value):
93
+ return False, self.error_message or "Custom validation failed"
94
+
95
+ return True, None
96
+
97
+ except Exception as e:
98
+ logger.error(f"Validation error: {e}")
99
+ return False, self.error_message or f"Validation error: {e}"
100
+
101
+
102
+ @dataclass
103
+ class ConfigField:
104
+ """Configuration field definition for plugins."""
105
+ key: str
106
+ widget_type: WidgetType
107
+ label: str
108
+ default_value: Any
109
+ help_text: str = ""
110
+ validation: ValidationRule = field(default_factory=ValidationRule)
111
+
112
+ # Widget-specific options
113
+ options: List[str] = field(default_factory=list) # For dropdown, multi_select
114
+ min_value: Optional[Union[int, float]] = None # For slider
115
+ max_value: Optional[Union[int, float]] = None # For slider
116
+ step: Optional[Union[int, float]] = None # For slider
117
+ placeholder: str = "" # For text_input
118
+ file_extensions: List[str] = field(default_factory=list) # For file_picker
119
+
120
+ # Display options
121
+ category: str = "General"
122
+ advanced: bool = False
123
+ requires_restart: bool = False
124
+ environment_dependent: bool = False
125
+
126
+
127
+ @dataclass
128
+ class PluginConfigSchema:
129
+ """Complete configuration schema for a plugin."""
130
+ plugin_name: str
131
+ plugin_version: str = "1.0.0"
132
+ description: str = ""
133
+ categories: List[str] = field(default_factory=lambda: ["General"])
134
+ fields: List[ConfigField] = field(default_factory=list)
135
+
136
+ def add_field(self, field: ConfigField) -> 'PluginConfigSchema':
137
+ """Add a field to the schema.
138
+
139
+ Args:
140
+ field: Field to add.
141
+
142
+ Returns:
143
+ Self for method chaining.
144
+ """
145
+ self.fields.append(field)
146
+ if field.category not in self.categories:
147
+ self.categories.append(field.category)
148
+ return self
149
+
150
+ def get_fields_by_category(self, category: str) -> List[ConfigField]:
151
+ """Get all fields in a specific category.
152
+
153
+ Args:
154
+ category: Category to filter by.
155
+
156
+ Returns:
157
+ List of fields in the category.
158
+ """
159
+ return [f for f in self.fields if f.category == category]
160
+
161
+ def get_field(self, key: str) -> Optional[ConfigField]:
162
+ """Get a field by its key.
163
+
164
+ Args:
165
+ key: Field key to find.
166
+
167
+ Returns:
168
+ Field if found, None otherwise.
169
+ """
170
+ for field in self.fields:
171
+ if field.key == key:
172
+ return field
173
+ return None
174
+
175
+ def validate_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
176
+ """Validate a configuration dictionary against this schema.
177
+
178
+ Args:
179
+ config: Configuration to validate.
180
+
181
+ Returns:
182
+ Dictionary with validation results.
183
+ """
184
+ result = {
185
+ "valid": True,
186
+ "errors": {},
187
+ "warnings": {}
188
+ }
189
+
190
+ for field in self.fields:
191
+ value = config.get(field.key, field.default_value)
192
+
193
+ # Validate the value
194
+ is_valid, error_msg = field.validation.validate(value)
195
+
196
+ if not is_valid:
197
+ result["valid"] = False
198
+ result["errors"][field.key] = error_msg
199
+
200
+ # Check for deprecated or advanced fields
201
+ if field.advanced and value != field.default_value:
202
+ result["warnings"][field.key] = "Advanced setting changed"
203
+
204
+ return result
205
+
206
+ def get_default_config(self) -> Dict[str, Any]:
207
+ """Get default configuration from this schema.
208
+
209
+ Returns:
210
+ Default configuration dictionary.
211
+ """
212
+ return {field.key: field.default_value for field in self.fields}
213
+
214
+ def to_widget_definitions(self) -> List[Dict[str, Any]]:
215
+ """Convert schema to widget definitions for UI.
216
+
217
+ Returns:
218
+ List of widget definition dictionaries.
219
+ """
220
+ widgets = []
221
+
222
+ for field in self.fields:
223
+ widget_def = {
224
+ "type": field.widget_type.value,
225
+ "label": field.label,
226
+ "config_path": f"plugins.{self.plugin_name}.{field.key}",
227
+ "help": field.help_text,
228
+ "category": field.category,
229
+ "advanced": field.advanced,
230
+ "requires_restart": field.requires_restart
231
+ }
232
+
233
+ # Add widget-specific options
234
+ if field.options:
235
+ widget_def["options"] = field.options
236
+
237
+ if field.min_value is not None:
238
+ widget_def["min_value"] = field.min_value
239
+
240
+ if field.max_value is not None:
241
+ widget_def["max_value"] = field.max_value
242
+
243
+ if field.step is not None:
244
+ widget_def["step"] = field.step
245
+
246
+ if field.placeholder:
247
+ widget_def["placeholder"] = field.placeholder
248
+
249
+ if field.file_extensions:
250
+ widget_def["file_extensions"] = field.file_extensions
251
+
252
+ widgets.append(widget_def)
253
+
254
+ return widgets
255
+
256
+
257
+ # Builder pattern for easier schema creation
258
+ class ConfigSchemaBuilder:
259
+ """Builder for creating plugin configuration schemas."""
260
+
261
+ def __init__(self, plugin_name: str, description: str = ""):
262
+ """Initialize schema builder.
263
+
264
+ Args:
265
+ plugin_name: Name of the plugin.
266
+ description: Plugin description.
267
+ """
268
+ self.schema = PluginConfigSchema(
269
+ plugin_name=plugin_name,
270
+ description=description
271
+ )
272
+
273
+ def add_checkbox(self, key: str, label: str, default: bool = False,
274
+ help_text: str = "", category: str = "General",
275
+ advanced: bool = False, requires_restart: bool = False) -> 'ConfigSchemaBuilder':
276
+ """Add a checkbox field."""
277
+ field = ConfigField(
278
+ key=key,
279
+ widget_type=WidgetType.CHECKBOX,
280
+ label=label,
281
+ default_value=default,
282
+ help_text=help_text,
283
+ category=category,
284
+ advanced=advanced,
285
+ requires_restart=requires_restart,
286
+ validation=ValidationRule(type=ValidationType.BOOLEAN)
287
+ )
288
+ self.schema.add_field(field)
289
+ return self
290
+
291
+ def add_slider(self, key: str, label: str, default: Union[int, float],
292
+ min_value: Union[int, float], max_value: Union[int, float],
293
+ step: Union[int, float] = 1, help_text: str = "",
294
+ category: str = "General", advanced: bool = False,
295
+ requires_restart: bool = False) -> 'ConfigSchemaBuilder':
296
+ """Add a slider field."""
297
+ field = ConfigField(
298
+ key=key,
299
+ widget_type=WidgetType.SLIDER,
300
+ label=label,
301
+ default_value=default,
302
+ help_text=help_text,
303
+ category=category,
304
+ advanced=advanced,
305
+ requires_restart=requires_restart,
306
+ min_value=min_value,
307
+ max_value=max_value,
308
+ step=step,
309
+ validation=ValidationRule(
310
+ type=ValidationType.INTEGER if isinstance(default, int) else ValidationType.FLOAT,
311
+ min_value=min_value,
312
+ max_value=max_value
313
+ )
314
+ )
315
+ self.schema.add_field(field)
316
+ return self
317
+
318
+ def add_text_input(self, key: str, label: str, default: str = "",
319
+ placeholder: str = "", help_text: str = "",
320
+ category: str = "General", validation_type: ValidationType = ValidationType.STRING,
321
+ pattern: str = "", advanced: bool = False,
322
+ requires_restart: bool = False) -> 'ConfigSchemaBuilder':
323
+ """Add a text input field."""
324
+ validation = ValidationRule(type=validation_type, pattern=pattern if pattern else None)
325
+ if pattern:
326
+ validation.error_message = f"Value must match pattern: {pattern}"
327
+
328
+ field = ConfigField(
329
+ key=key,
330
+ widget_type=WidgetType.TEXT_INPUT,
331
+ label=label,
332
+ default_value=default,
333
+ help_text=help_text,
334
+ category=category,
335
+ advanced=advanced,
336
+ requires_restart=requires_restart,
337
+ placeholder=placeholder,
338
+ validation=validation
339
+ )
340
+ self.schema.add_field(field)
341
+ return self
342
+
343
+ def add_dropdown(self, key: str, label: str, options: List[str],
344
+ default: Optional[str] = None, help_text: str = "",
345
+ category: str = "General", advanced: bool = False,
346
+ requires_restart: bool = False) -> 'ConfigSchemaBuilder':
347
+ """Add a dropdown field."""
348
+ if default is None:
349
+ default = options[0] if options else ""
350
+
351
+ field = ConfigField(
352
+ key=key,
353
+ widget_type=WidgetType.DROPDOWN,
354
+ label=label,
355
+ default_value=default,
356
+ help_text=help_text,
357
+ category=category,
358
+ advanced=advanced,
359
+ requires_restart=requires_restart,
360
+ options=options,
361
+ validation=ValidationRule(
362
+ type=ValidationType.STRING,
363
+ custom_validator=lambda v: v in options,
364
+ error_message=f"Value must be one of: {', '.join(options)}"
365
+ )
366
+ )
367
+ self.schema.add_field(field)
368
+ return self
369
+
370
+ def add_file_picker(self, key: str, label: str, default: str = "",
371
+ extensions: List[str] = None, help_text: str = "",
372
+ category: str = "General", advanced: bool = False,
373
+ requires_restart: bool = False) -> 'ConfigSchemaBuilder':
374
+ """Add a file picker field."""
375
+ field = ConfigField(
376
+ key=key,
377
+ widget_type=WidgetType.FILE_PICKER,
378
+ label=label,
379
+ default_value=default,
380
+ help_text=help_text,
381
+ category=category,
382
+ advanced=advanced,
383
+ requires_restart=requires_restart,
384
+ file_extensions=extensions or [],
385
+ validation=ValidationRule(type=ValidationType.FILE_PATH)
386
+ )
387
+ self.schema.add_field(field)
388
+ return self
389
+
390
+ def build(self) -> PluginConfigSchema:
391
+ """Build and return the schema.
392
+
393
+ Returns:
394
+ Complete plugin configuration schema.
395
+ """
396
+ return self.schema
397
+
398
+
399
+ # Utility functions for common field types
400
+ def create_enabled_field(category: str = "General", requires_restart: bool = False) -> ConfigField:
401
+ """Create a standard 'enabled' checkbox field."""
402
+ return ConfigField(
403
+ key="enabled",
404
+ widget_type=WidgetType.CHECKBOX,
405
+ label="Enabled",
406
+ default_value=True,
407
+ help_text="Enable or disable this plugin",
408
+ category=category,
409
+ requires_restart=requires_restart,
410
+ validation=ValidationRule(type=ValidationType.BOOLEAN)
411
+ )
412
+
413
+
414
+ def create_debug_field(category: str = "General") -> ConfigField:
415
+ """Create a standard 'debug_logging' field."""
416
+ return ConfigField(
417
+ key="debug_logging",
418
+ widget_type=WidgetType.CHECKBOX,
419
+ label="Debug Logging",
420
+ default_value=False,
421
+ help_text="Enable detailed debug logging for this plugin",
422
+ category=category,
423
+ validation=ValidationRule(type=ValidationType.BOOLEAN)
424
+ )