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.
- core/__init__.py +18 -0
- core/application.py +578 -0
- core/cli.py +193 -0
- core/commands/__init__.py +43 -0
- core/commands/executor.py +277 -0
- core/commands/menu_renderer.py +319 -0
- core/commands/parser.py +186 -0
- core/commands/registry.py +331 -0
- core/commands/system_commands.py +479 -0
- core/config/__init__.py +7 -0
- core/config/llm_task_config.py +110 -0
- core/config/loader.py +501 -0
- core/config/manager.py +112 -0
- core/config/plugin_config_manager.py +346 -0
- core/config/plugin_schema.py +424 -0
- core/config/service.py +399 -0
- core/effects/__init__.py +1 -0
- core/events/__init__.py +12 -0
- core/events/bus.py +129 -0
- core/events/executor.py +154 -0
- core/events/models.py +258 -0
- core/events/processor.py +176 -0
- core/events/registry.py +289 -0
- core/fullscreen/__init__.py +19 -0
- core/fullscreen/command_integration.py +290 -0
- core/fullscreen/components/__init__.py +12 -0
- core/fullscreen/components/animation.py +258 -0
- core/fullscreen/components/drawing.py +160 -0
- core/fullscreen/components/matrix_components.py +177 -0
- core/fullscreen/manager.py +302 -0
- core/fullscreen/plugin.py +204 -0
- core/fullscreen/renderer.py +282 -0
- core/fullscreen/session.py +324 -0
- core/io/__init__.py +52 -0
- core/io/buffer_manager.py +362 -0
- core/io/config_status_view.py +272 -0
- core/io/core_status_views.py +410 -0
- core/io/input_errors.py +313 -0
- core/io/input_handler.py +2655 -0
- core/io/input_mode_manager.py +402 -0
- core/io/key_parser.py +344 -0
- core/io/layout.py +587 -0
- core/io/message_coordinator.py +204 -0
- core/io/message_renderer.py +601 -0
- core/io/modal_interaction_handler.py +315 -0
- core/io/raw_input_processor.py +946 -0
- core/io/status_renderer.py +845 -0
- core/io/terminal_renderer.py +586 -0
- core/io/terminal_state.py +551 -0
- core/io/visual_effects.py +734 -0
- core/llm/__init__.py +26 -0
- core/llm/api_communication_service.py +863 -0
- core/llm/conversation_logger.py +473 -0
- core/llm/conversation_manager.py +414 -0
- core/llm/file_operations_executor.py +1401 -0
- core/llm/hook_system.py +402 -0
- core/llm/llm_service.py +1629 -0
- core/llm/mcp_integration.py +386 -0
- core/llm/message_display_service.py +450 -0
- core/llm/model_router.py +214 -0
- core/llm/plugin_sdk.py +396 -0
- core/llm/response_parser.py +848 -0
- core/llm/response_processor.py +364 -0
- core/llm/tool_executor.py +520 -0
- core/logging/__init__.py +19 -0
- core/logging/setup.py +208 -0
- core/models/__init__.py +5 -0
- core/models/base.py +23 -0
- core/plugins/__init__.py +13 -0
- core/plugins/collector.py +212 -0
- core/plugins/discovery.py +386 -0
- core/plugins/factory.py +263 -0
- core/plugins/registry.py +152 -0
- core/storage/__init__.py +5 -0
- core/storage/state_manager.py +84 -0
- core/ui/__init__.py +6 -0
- core/ui/config_merger.py +176 -0
- core/ui/config_widgets.py +369 -0
- core/ui/live_modal_renderer.py +276 -0
- core/ui/modal_actions.py +162 -0
- core/ui/modal_overlay_renderer.py +373 -0
- core/ui/modal_renderer.py +591 -0
- core/ui/modal_state_manager.py +443 -0
- core/ui/widget_integration.py +222 -0
- core/ui/widgets/__init__.py +27 -0
- core/ui/widgets/base_widget.py +136 -0
- core/ui/widgets/checkbox.py +85 -0
- core/ui/widgets/dropdown.py +140 -0
- core/ui/widgets/label.py +78 -0
- core/ui/widgets/slider.py +185 -0
- core/ui/widgets/text_input.py +224 -0
- core/utils/__init__.py +11 -0
- core/utils/config_utils.py +656 -0
- core/utils/dict_utils.py +212 -0
- core/utils/error_utils.py +275 -0
- core/utils/key_reader.py +171 -0
- core/utils/plugin_utils.py +267 -0
- core/utils/prompt_renderer.py +151 -0
- kollabor-0.4.9.dist-info/METADATA +298 -0
- kollabor-0.4.9.dist-info/RECORD +128 -0
- kollabor-0.4.9.dist-info/WHEEL +5 -0
- kollabor-0.4.9.dist-info/entry_points.txt +2 -0
- kollabor-0.4.9.dist-info/licenses/LICENSE +21 -0
- kollabor-0.4.9.dist-info/top_level.txt +4 -0
- kollabor_cli_main.py +20 -0
- plugins/__init__.py +1 -0
- plugins/enhanced_input/__init__.py +18 -0
- plugins/enhanced_input/box_renderer.py +103 -0
- plugins/enhanced_input/box_styles.py +142 -0
- plugins/enhanced_input/color_engine.py +165 -0
- plugins/enhanced_input/config.py +150 -0
- plugins/enhanced_input/cursor_manager.py +72 -0
- plugins/enhanced_input/geometry.py +81 -0
- plugins/enhanced_input/state.py +130 -0
- plugins/enhanced_input/text_processor.py +115 -0
- plugins/enhanced_input_plugin.py +385 -0
- plugins/fullscreen/__init__.py +9 -0
- plugins/fullscreen/example_plugin.py +327 -0
- plugins/fullscreen/matrix_plugin.py +132 -0
- plugins/hook_monitoring_plugin.py +1299 -0
- plugins/query_enhancer_plugin.py +350 -0
- plugins/save_conversation_plugin.py +502 -0
- plugins/system_commands_plugin.py +93 -0
- plugins/tmux_plugin.py +795 -0
- plugins/workflow_enforcement_plugin.py +629 -0
- system_prompt/default.md +1286 -0
- system_prompt/default_win.md +265 -0
- 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
|
+
)
|