kollabor 0.4.9__py3-none-any.whl → 0.4.15__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 (192) hide show
  1. agents/__init__.py +2 -0
  2. agents/coder/__init__.py +0 -0
  3. agents/coder/agent.json +4 -0
  4. agents/coder/api-integration.md +2150 -0
  5. agents/coder/cli-pretty.md +765 -0
  6. agents/coder/code-review.md +1092 -0
  7. agents/coder/database-design.md +1525 -0
  8. agents/coder/debugging.md +1102 -0
  9. agents/coder/dependency-management.md +1397 -0
  10. agents/coder/git-workflow.md +1099 -0
  11. agents/coder/refactoring.md +1454 -0
  12. agents/coder/security-hardening.md +1732 -0
  13. agents/coder/system_prompt.md +1448 -0
  14. agents/coder/tdd.md +1367 -0
  15. agents/creative-writer/__init__.py +0 -0
  16. agents/creative-writer/agent.json +4 -0
  17. agents/creative-writer/character-development.md +1852 -0
  18. agents/creative-writer/dialogue-craft.md +1122 -0
  19. agents/creative-writer/plot-structure.md +1073 -0
  20. agents/creative-writer/revision-editing.md +1484 -0
  21. agents/creative-writer/system_prompt.md +690 -0
  22. agents/creative-writer/worldbuilding.md +2049 -0
  23. agents/data-analyst/__init__.py +30 -0
  24. agents/data-analyst/agent.json +4 -0
  25. agents/data-analyst/data-visualization.md +992 -0
  26. agents/data-analyst/exploratory-data-analysis.md +1110 -0
  27. agents/data-analyst/pandas-data-manipulation.md +1081 -0
  28. agents/data-analyst/sql-query-optimization.md +881 -0
  29. agents/data-analyst/statistical-analysis.md +1118 -0
  30. agents/data-analyst/system_prompt.md +928 -0
  31. agents/default/__init__.py +0 -0
  32. agents/default/agent.json +4 -0
  33. agents/default/dead-code.md +794 -0
  34. agents/default/explore-agent-system.md +585 -0
  35. agents/default/system_prompt.md +1448 -0
  36. agents/kollabor/__init__.py +0 -0
  37. agents/kollabor/analyze-plugin-lifecycle.md +175 -0
  38. agents/kollabor/analyze-terminal-rendering.md +388 -0
  39. agents/kollabor/code-review.md +1092 -0
  40. agents/kollabor/debug-mcp-integration.md +521 -0
  41. agents/kollabor/debug-plugin-hooks.md +547 -0
  42. agents/kollabor/debugging.md +1102 -0
  43. agents/kollabor/dependency-management.md +1397 -0
  44. agents/kollabor/git-workflow.md +1099 -0
  45. agents/kollabor/inspect-llm-conversation.md +148 -0
  46. agents/kollabor/monitor-event-bus.md +558 -0
  47. agents/kollabor/profile-performance.md +576 -0
  48. agents/kollabor/refactoring.md +1454 -0
  49. agents/kollabor/system_prompt copy.md +1448 -0
  50. agents/kollabor/system_prompt.md +757 -0
  51. agents/kollabor/trace-command-execution.md +178 -0
  52. agents/kollabor/validate-config.md +879 -0
  53. agents/research/__init__.py +0 -0
  54. agents/research/agent.json +4 -0
  55. agents/research/architecture-mapping.md +1099 -0
  56. agents/research/codebase-analysis.md +1077 -0
  57. agents/research/dependency-audit.md +1027 -0
  58. agents/research/performance-profiling.md +1047 -0
  59. agents/research/security-review.md +1359 -0
  60. agents/research/system_prompt.md +492 -0
  61. agents/technical-writer/__init__.py +0 -0
  62. agents/technical-writer/agent.json +4 -0
  63. agents/technical-writer/api-documentation.md +2328 -0
  64. agents/technical-writer/changelog-management.md +1181 -0
  65. agents/technical-writer/readme-writing.md +1360 -0
  66. agents/technical-writer/style-guide.md +1410 -0
  67. agents/technical-writer/system_prompt.md +653 -0
  68. agents/technical-writer/tutorial-creation.md +1448 -0
  69. core/__init__.py +0 -2
  70. core/application.py +343 -88
  71. core/cli.py +229 -10
  72. core/commands/menu_renderer.py +463 -59
  73. core/commands/registry.py +14 -9
  74. core/commands/system_commands.py +2461 -14
  75. core/config/loader.py +151 -37
  76. core/config/service.py +18 -6
  77. core/events/bus.py +29 -9
  78. core/events/executor.py +205 -75
  79. core/events/models.py +27 -8
  80. core/fullscreen/command_integration.py +20 -24
  81. core/fullscreen/components/__init__.py +10 -1
  82. core/fullscreen/components/matrix_components.py +1 -2
  83. core/fullscreen/components/space_shooter_components.py +654 -0
  84. core/fullscreen/plugin.py +5 -0
  85. core/fullscreen/renderer.py +52 -13
  86. core/fullscreen/session.py +52 -15
  87. core/io/__init__.py +29 -5
  88. core/io/buffer_manager.py +6 -1
  89. core/io/config_status_view.py +7 -29
  90. core/io/core_status_views.py +267 -347
  91. core/io/input/__init__.py +25 -0
  92. core/io/input/command_mode_handler.py +711 -0
  93. core/io/input/display_controller.py +128 -0
  94. core/io/input/hook_registrar.py +286 -0
  95. core/io/input/input_loop_manager.py +421 -0
  96. core/io/input/key_press_handler.py +502 -0
  97. core/io/input/modal_controller.py +1011 -0
  98. core/io/input/paste_processor.py +339 -0
  99. core/io/input/status_modal_renderer.py +184 -0
  100. core/io/input_errors.py +5 -1
  101. core/io/input_handler.py +211 -2452
  102. core/io/key_parser.py +7 -0
  103. core/io/layout.py +15 -3
  104. core/io/message_coordinator.py +111 -2
  105. core/io/message_renderer.py +129 -4
  106. core/io/status_renderer.py +147 -607
  107. core/io/terminal_renderer.py +97 -51
  108. core/io/terminal_state.py +21 -4
  109. core/io/visual_effects.py +816 -165
  110. core/llm/agent_manager.py +1063 -0
  111. core/llm/api_adapters/__init__.py +44 -0
  112. core/llm/api_adapters/anthropic_adapter.py +432 -0
  113. core/llm/api_adapters/base.py +241 -0
  114. core/llm/api_adapters/openai_adapter.py +326 -0
  115. core/llm/api_communication_service.py +167 -113
  116. core/llm/conversation_logger.py +322 -16
  117. core/llm/conversation_manager.py +556 -30
  118. core/llm/file_operations_executor.py +84 -32
  119. core/llm/llm_service.py +934 -103
  120. core/llm/mcp_integration.py +541 -57
  121. core/llm/message_display_service.py +135 -18
  122. core/llm/plugin_sdk.py +1 -2
  123. core/llm/profile_manager.py +1183 -0
  124. core/llm/response_parser.py +274 -56
  125. core/llm/response_processor.py +16 -3
  126. core/llm/tool_executor.py +6 -1
  127. core/logging/__init__.py +2 -0
  128. core/logging/setup.py +34 -6
  129. core/models/resume.py +54 -0
  130. core/plugins/__init__.py +4 -2
  131. core/plugins/base.py +127 -0
  132. core/plugins/collector.py +23 -161
  133. core/plugins/discovery.py +37 -3
  134. core/plugins/factory.py +6 -12
  135. core/plugins/registry.py +5 -17
  136. core/ui/config_widgets.py +128 -28
  137. core/ui/live_modal_renderer.py +2 -1
  138. core/ui/modal_actions.py +5 -0
  139. core/ui/modal_overlay_renderer.py +0 -60
  140. core/ui/modal_renderer.py +268 -7
  141. core/ui/modal_state_manager.py +29 -4
  142. core/ui/widgets/base_widget.py +7 -0
  143. core/updates/__init__.py +10 -0
  144. core/updates/version_check_service.py +348 -0
  145. core/updates/version_comparator.py +103 -0
  146. core/utils/config_utils.py +685 -526
  147. core/utils/plugin_utils.py +1 -1
  148. core/utils/session_naming.py +111 -0
  149. fonts/LICENSE +21 -0
  150. fonts/README.md +46 -0
  151. fonts/SymbolsNerdFont-Regular.ttf +0 -0
  152. fonts/SymbolsNerdFontMono-Regular.ttf +0 -0
  153. fonts/__init__.py +44 -0
  154. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/METADATA +54 -4
  155. kollabor-0.4.15.dist-info/RECORD +228 -0
  156. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/top_level.txt +2 -0
  157. plugins/agent_orchestrator/__init__.py +39 -0
  158. plugins/agent_orchestrator/activity_monitor.py +181 -0
  159. plugins/agent_orchestrator/file_attacher.py +77 -0
  160. plugins/agent_orchestrator/message_injector.py +135 -0
  161. plugins/agent_orchestrator/models.py +48 -0
  162. plugins/agent_orchestrator/orchestrator.py +403 -0
  163. plugins/agent_orchestrator/plugin.py +976 -0
  164. plugins/agent_orchestrator/xml_parser.py +191 -0
  165. plugins/agent_orchestrator_plugin.py +9 -0
  166. plugins/enhanced_input/box_styles.py +1 -0
  167. plugins/enhanced_input/color_engine.py +19 -4
  168. plugins/enhanced_input/config.py +2 -2
  169. plugins/enhanced_input_plugin.py +61 -11
  170. plugins/fullscreen/__init__.py +6 -2
  171. plugins/fullscreen/example_plugin.py +1035 -222
  172. plugins/fullscreen/setup_wizard_plugin.py +592 -0
  173. plugins/fullscreen/space_shooter_plugin.py +131 -0
  174. plugins/hook_monitoring_plugin.py +436 -78
  175. plugins/query_enhancer_plugin.py +66 -30
  176. plugins/resume_conversation_plugin.py +1494 -0
  177. plugins/save_conversation_plugin.py +98 -32
  178. plugins/system_commands_plugin.py +70 -56
  179. plugins/tmux_plugin.py +154 -78
  180. plugins/workflow_enforcement_plugin.py +94 -92
  181. system_prompt/default.md +952 -886
  182. core/io/input_mode_manager.py +0 -402
  183. core/io/modal_interaction_handler.py +0 -315
  184. core/io/raw_input_processor.py +0 -946
  185. core/storage/__init__.py +0 -5
  186. core/storage/state_manager.py +0 -84
  187. core/ui/widget_integration.py +0 -222
  188. core/utils/key_reader.py +0 -171
  189. kollabor-0.4.9.dist-info/RECORD +0 -128
  190. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/WHEEL +0 -0
  191. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/entry_points.txt +0 -0
  192. {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/licenses/LICENSE +0 -0
core/models/resume.py ADDED
@@ -0,0 +1,54 @@
1
+ """Data models for resume functionality."""
2
+
3
+ from dataclasses import dataclass
4
+ from datetime import datetime
5
+ from typing import Any, Dict, List, Optional
6
+
7
+
8
+ @dataclass
9
+ class SessionMetadata:
10
+ """Metadata for a conversation session."""
11
+ session_id: str
12
+ start_time: Optional[datetime]
13
+ end_time: Optional[datetime]
14
+ message_count: int
15
+ turn_count: int
16
+ working_directory: str
17
+ git_branch: str
18
+ themes: List[str]
19
+ files_mentioned: List[str]
20
+ last_activity: Optional[datetime]
21
+ size_bytes: int
22
+ is_valid: bool
23
+ validation_issues: List[str]
24
+
25
+
26
+ @dataclass
27
+ class SessionSummary:
28
+ """Summary of a conversation session."""
29
+ metadata: SessionMetadata
30
+ preview_messages: List[Dict]
31
+ key_topics: List[str]
32
+ user_patterns: List[str]
33
+ project_context: Dict[str, Any]
34
+ compatibility_score: float
35
+
36
+
37
+ @dataclass
38
+ class ConversationMetadata:
39
+ """Metadata for conversation discovery."""
40
+ file_path: str
41
+ session_id: str
42
+ title: str
43
+ message_count: int
44
+ created_time: Optional[datetime]
45
+ modified_time: Optional[datetime]
46
+ last_message_preview: str
47
+ topics: List[str]
48
+ file_id: str # Short ID for display (#12345)
49
+ working_directory: str
50
+ git_branch: str
51
+ duration: Optional[str]
52
+ size_bytes: int
53
+ preview_messages: List[Dict]
54
+ search_relevance: Optional[float] = None
core/plugins/__init__.py CHANGED
@@ -4,10 +4,12 @@ from .registry import PluginRegistry
4
4
  from .discovery import PluginDiscovery
5
5
  from .factory import PluginFactory
6
6
  from .collector import PluginStatusCollector
7
+ from .base import BasePlugin
7
8
 
8
9
  __all__ = [
9
10
  'PluginRegistry',
10
- 'PluginDiscovery',
11
+ 'PluginDiscovery',
11
12
  'PluginFactory',
12
- 'PluginStatusCollector'
13
+ 'PluginStatusCollector',
14
+ 'BasePlugin'
13
15
  ]
core/plugins/base.py ADDED
@@ -0,0 +1,127 @@
1
+ """Base plugin class for Kollabor CLI plugins.
2
+
3
+ This module defines the BasePlugin class that all plugins can inherit from.
4
+ It provides default implementations for plugin lifecycle methods including
5
+ CLI argument registration.
6
+ """
7
+
8
+ import argparse
9
+ from typing import Any
10
+
11
+
12
+ class BasePlugin:
13
+ """Base class for all Kollabor CLI plugins.
14
+
15
+ Plugins can inherit from this class to get default implementations
16
+ of common plugin methods. The class provides static methods for
17
+ CLI argument registration and early argument handling.
18
+ """
19
+
20
+ @staticmethod
21
+ def register_cli_args(parser: argparse.ArgumentParser) -> None:
22
+ """Register custom CLI arguments.
23
+
24
+ Called during early plugin discovery, before app initialization.
25
+ Use parser.add_argument_group() to organize args by plugin.
26
+
27
+ Args:
28
+ parser: The ArgumentParser instance to add arguments to.
29
+
30
+ Example:
31
+ @staticmethod
32
+ def register_cli_args(parser):
33
+ group = parser.add_argument_group("My Plugin")
34
+ group.add_argument("--my-arg", type=str,
35
+ help="My custom argument")
36
+ """
37
+ pass
38
+
39
+ @staticmethod
40
+ def handle_early_args(args: argparse.Namespace) -> bool:
41
+ """Handle args that should exit before app starts.
42
+
43
+ Called after argument parsing but before app initialization.
44
+ Return True to exit immediately (e.g., --capture mode).
45
+ Return False to continue normal startup.
46
+
47
+ Args:
48
+ args: The parsed CLI arguments namespace.
49
+
50
+ Returns:
51
+ True to exit immediately, False to continue normal startup.
52
+
53
+ Example:
54
+ @staticmethod
55
+ def handle_early_args(args):
56
+ if hasattr(args, 'my_flag') and args.my_flag:
57
+ print("Early exit triggered")
58
+ return True
59
+ return False
60
+ """
61
+ return False
62
+
63
+ def initialize(self, args: argparse.Namespace = None, **kwargs) -> None:
64
+ """Initialize the plugin.
65
+
66
+ Called during app startup. The args parameter contains
67
+ parsed CLI arguments including any plugin-registered args.
68
+
69
+ Args:
70
+ args: Parsed CLI arguments (optional, None if not available).
71
+ **kwargs: Additional initialization parameters including:
72
+ - event_bus: Event bus for hook registration
73
+ - config: Configuration manager
74
+ - command_registry: Command registry for slash commands
75
+ - input_handler: Input handler instance
76
+ - renderer: Terminal renderer
77
+ - llm_service: LLM service instance
78
+ - conversation_logger: Conversation logger instance
79
+ - conversation_manager: Conversation manager instance
80
+ """
81
+ pass
82
+
83
+ def register_hooks(self) -> None:
84
+ """Register plugin hooks with the event bus.
85
+
86
+ Called during plugin initialization after initialize().
87
+ Override this method to register event hooks.
88
+ """
89
+ pass
90
+
91
+ def shutdown(self) -> None:
92
+ """Shutdown the plugin.
93
+
94
+ Called during app shutdown. Override this method to
95
+ perform cleanup tasks.
96
+ """
97
+ pass
98
+
99
+ @staticmethod
100
+ def get_default_config() -> dict[str, Any]:
101
+ """Get default configuration for this plugin.
102
+
103
+ Returns:
104
+ Dictionary with default configuration values.
105
+ """
106
+ return {}
107
+
108
+ @staticmethod
109
+ def get_startup_info(config) -> list[str]:
110
+ """Get startup information for this plugin.
111
+
112
+ Args:
113
+ config: Configuration manager instance.
114
+
115
+ Returns:
116
+ List of strings to display during startup.
117
+ """
118
+ return []
119
+
120
+ @staticmethod
121
+ def get_config_widgets() -> dict[str, Any]:
122
+ """Get configuration widgets for this plugin.
123
+
124
+ Returns:
125
+ Widget section definition for the config modal.
126
+ """
127
+ return {}
core/plugins/collector.py CHANGED
@@ -1,212 +1,74 @@
1
- """Plugin status collector for aggregating status information from plugins."""
1
+ """Plugin collector for gathering plugin information."""
2
2
 
3
3
  import logging
4
4
  from typing import Any, Dict, List
5
5
 
6
- from ..utils.plugin_utils import collect_plugin_status_safely
7
6
  from ..utils.error_utils import safe_execute
8
7
 
9
8
  logger = logging.getLogger(__name__)
10
9
 
11
10
 
12
11
  class PluginStatusCollector:
13
- """Collects and aggregates status information from plugin instances.
14
-
15
- This class is responsible for gathering status lines from all plugins,
16
- organizing them by display areas, and providing aggregated status data.
12
+ """Collects plugin information like startup info.
13
+
14
+ Note: Status line collection has been removed in favor of
15
+ content provider-based status views.
17
16
  """
18
-
17
+
19
18
  def __init__(self):
20
- """Initialize the plugin status collector."""
21
- self.last_status_collection: Dict[str, Dict[str, List[str]]] = {}
22
- self.collection_errors: Dict[str, str] = {}
19
+ """Initialize the plugin collector."""
23
20
  logger.info("PluginStatusCollector initialized")
24
-
25
- def collect_plugin_status(self, plugin_name: str, plugin_instance: Any) -> Dict[str, List[str]]:
26
- """Collect status information from a single plugin.
27
-
28
- Args:
29
- plugin_name: Name of the plugin.
30
- plugin_instance: The plugin instance to collect status from.
31
-
32
- Returns:
33
- Dictionary with areas A, B, C containing lists of status lines.
34
- """
35
- plugin_status = collect_plugin_status_safely(plugin_instance, plugin_name)
36
-
37
- # Store the status for this plugin
38
- self.last_status_collection[plugin_name] = plugin_status
39
-
40
- # Clear any previous collection errors for this plugin
41
- if plugin_name in self.collection_errors:
42
- del self.collection_errors[plugin_name]
43
-
44
- return plugin_status
45
-
46
- def collect_all_status(self, plugin_instances: Dict[str, Any]) -> Dict[str, List[str]]:
47
- """Collect status lines from all plugins organized by area.
48
-
49
- Args:
50
- plugin_instances: Dictionary of plugin instances.
51
-
52
- Returns:
53
- Dictionary with areas A, B, C containing aggregated status lines.
54
- """
55
- status_areas = {"A": [], "B": [], "C": []}
56
-
57
- for plugin_name, plugin_instance in plugin_instances.items():
58
- plugin_status = self.collect_plugin_status(plugin_name, plugin_instance)
59
-
60
- # Merge the status from this plugin into our aggregated status
61
- for area in ["A", "B", "C"]:
62
- if area in plugin_status:
63
- status_areas[area].extend(plugin_status[area])
64
-
65
- #logger.debug(f"Collected status from {len(plugin_instances)} plugins")
66
- return status_areas
67
-
21
+
68
22
  def get_plugin_startup_info(self, plugin_name: str, plugin_class: type, config: Any) -> List[str]:
69
23
  """Get startup information for a specific plugin.
70
-
24
+
71
25
  Args:
72
26
  plugin_name: Name of the plugin.
73
27
  plugin_class: The plugin class.
74
28
  config: Configuration manager instance.
75
-
29
+
76
30
  Returns:
77
31
  List of startup info strings, or empty list if no info available.
78
32
  """
79
33
  def get_startup_info():
80
34
  return plugin_class.get_startup_info(config)
81
-
35
+
82
36
  result = safe_execute(
83
37
  get_startup_info,
84
38
  f"getting startup info from plugin {plugin_name}",
85
39
  default=[],
86
40
  logger_instance=logger
87
41
  )
88
-
42
+
89
43
  return result if isinstance(result, list) else []
90
-
44
+
91
45
  def collect_all_startup_info(self, plugin_classes: Dict[str, type], config: Any) -> Dict[str, List[str]]:
92
46
  """Collect startup information from all plugin classes.
93
-
47
+
94
48
  Args:
95
49
  plugin_classes: Dictionary mapping plugin names to classes.
96
50
  config: Configuration manager instance.
97
-
51
+
98
52
  Returns:
99
53
  Dictionary mapping plugin names to their startup info lists.
100
54
  """
101
55
  startup_info = {}
102
-
56
+
103
57
  for plugin_name, plugin_class in plugin_classes.items():
104
58
  info_list = self.get_plugin_startup_info(plugin_name, plugin_class, config)
105
59
  if info_list:
106
60
  startup_info[plugin_name] = info_list
107
-
61
+
108
62
  logger.debug(f"Collected startup info from {len(startup_info)} plugins")
109
63
  return startup_info
110
-
111
- def get_status_summary(self) -> Dict[str, Any]:
112
- """Get a summary of the last status collection.
113
-
114
- Returns:
115
- Dictionary with status collection summary.
116
- """
117
- total_lines = 0
118
- areas_summary = {"A": 0, "B": 0, "C": 0}
119
-
120
- for plugin_name, status in self.last_status_collection.items():
121
- for area in ["A", "B", "C"]:
122
- if area in status:
123
- line_count = len(status[area])
124
- areas_summary[area] += line_count
125
- total_lines += line_count
126
-
127
- return {
128
- "total_plugins": len(self.last_status_collection),
129
- "total_status_lines": total_lines,
130
- "lines_per_area": areas_summary,
131
- "collection_errors": len(self.collection_errors),
132
- "plugins_with_status": [
133
- name for name, status in self.last_status_collection.items()
134
- if any(status.get(area) for area in ["A", "B", "C"])
135
- ]
136
- }
137
-
138
- def get_plugin_status_details(self, plugin_name: str) -> Dict[str, Any]:
139
- """Get detailed status information for a specific plugin.
140
-
141
- Args:
142
- plugin_name: Name of the plugin.
143
-
144
- Returns:
145
- Dictionary with detailed status information for the plugin.
146
- """
147
- if plugin_name not in self.last_status_collection:
148
- return {
149
- "plugin_name": plugin_name,
150
- "status_collected": False,
151
- "error": "No status collection found"
152
- }
153
-
154
- status = self.last_status_collection[plugin_name]
155
-
156
- return {
157
- "plugin_name": plugin_name,
158
- "status_collected": True,
159
- "areas": {
160
- area: {
161
- "line_count": len(lines),
162
- "lines": lines
163
- }
164
- for area, lines in status.items()
165
- },
166
- "has_error": plugin_name in self.collection_errors,
167
- "error": self.collection_errors.get(plugin_name)
168
- }
169
-
170
- def clear_status_history(self) -> None:
171
- """Clear all stored status collection history."""
172
- self.last_status_collection.clear()
173
- self.collection_errors.clear()
174
- logger.debug("Cleared status collection history")
175
-
176
- def get_status_by_area(self, area: str) -> List[str]:
177
- """Get all status lines for a specific area across all plugins.
178
-
179
- Args:
180
- area: The area to get status for ("A", "B", or "C").
181
-
182
- Returns:
183
- List of status lines for the specified area.
184
- """
185
- if area not in ["A", "B", "C"]:
186
- logger.warning(f"Invalid status area: {area}")
187
- return []
188
-
189
- lines = []
190
- for plugin_name, status in self.last_status_collection.items():
191
- if area in status:
192
- lines.extend(status[area])
193
-
194
- return lines
195
-
64
+
196
65
  def get_collector_stats(self) -> Dict[str, Any]:
197
- """Get statistics about the collector's operations.
198
-
66
+ """Get statistics about the collector.
67
+
199
68
  Returns:
200
69
  Dictionary with collector statistics.
201
70
  """
202
- total_collections = len(self.last_status_collection)
203
- successful_collections = total_collections - len(self.collection_errors)
204
-
205
71
  return {
206
- "total_collections": total_collections,
207
- "successful_collections": successful_collections,
208
- "collection_errors": len(self.collection_errors),
209
- "plugins_tracked": list(self.last_status_collection.keys()),
210
- "error_plugins": list(self.collection_errors.keys()),
211
- "status_summary": self.get_status_summary()
212
- }
72
+ "type": "startup_info_collector",
73
+ "description": "Collects plugin startup information"
74
+ }
core/plugins/discovery.py CHANGED
@@ -275,18 +275,52 @@ class PluginDiscovery:
275
275
 
276
276
  def discover_and_load(self) -> Dict[str, Type]:
277
277
  """Perform complete discovery and loading process.
278
-
278
+
279
279
  Returns:
280
280
  Dictionary mapping plugin names to their classes.
281
281
  """
282
282
  # Scan for plugin files
283
283
  self.scan_plugin_files()
284
-
284
+
285
285
  # Load all discovered modules
286
286
  self.load_all_modules()
287
-
287
+
288
288
  logger.info(f"Discovery complete: {len(self.loaded_classes)} plugins loaded")
289
289
  return self.loaded_classes
290
+
291
+ def discover_classes_only(self) -> List[Type]:
292
+ """Lightweight discovery that only loads plugin classes.
293
+
294
+ Does NOT instantiate plugins. Used for CLI arg registration
295
+ before app initialization. This allows plugins to register
296
+ custom CLI arguments without full plugin initialization.
297
+
298
+ Returns:
299
+ List of plugin class types.
300
+
301
+ Note:
302
+ This is a minimal discovery that loads modules and extracts
303
+ plugin classes but does not perform full instantiation or
304
+ configuration merging.
305
+ """
306
+ # Scan for plugin files
307
+ self.scan_plugin_files()
308
+
309
+ plugin_classes = []
310
+
311
+ for module_name in self.discovered_modules:
312
+ try:
313
+ # Load each module and extract plugin classes
314
+ if self.load_module(module_name):
315
+ # Get all loaded plugin classes from this module
316
+ for class_name, class_obj in self.loaded_classes.items():
317
+ if class_obj not in plugin_classes:
318
+ plugin_classes.append(class_obj)
319
+ except Exception as e:
320
+ logger.warning(f"Failed to load plugin {module_name} for CLI arg discovery: {e}")
321
+
322
+ logger.info(f"CLI arg discovery: {len(plugin_classes)} plugin classes found")
323
+ return plugin_classes
290
324
 
291
325
  def get_plugin_class(self, plugin_name: str) -> Type:
292
326
  """Get a loaded plugin class by name.
core/plugins/factory.py CHANGED
@@ -26,21 +26,19 @@ class PluginFactory:
26
26
  self,
27
27
  plugin_class: Type,
28
28
  plugin_name: str,
29
- state_manager: Any,
30
29
  event_bus: Any,
31
30
  renderer: Any,
32
31
  config: Any
33
32
  ) -> Any:
34
33
  """Instantiate a single plugin with dependencies.
35
-
34
+
36
35
  Args:
37
36
  plugin_class: The plugin class to instantiate.
38
37
  plugin_name: Name of the plugin.
39
- state_manager: State management system.
40
38
  event_bus: Event bus for hook registration.
41
39
  renderer: Terminal renderer.
42
40
  config: Configuration manager.
43
-
41
+
44
42
  Returns:
45
43
  Plugin instance if successful, None otherwise.
46
44
  """
@@ -48,7 +46,7 @@ class PluginFactory:
48
46
  if not has_method(plugin_class, '__init__'):
49
47
  logger.debug(f"Plugin {plugin_name} is not instantiable (no __init__ method)")
50
48
  return None
51
-
49
+
52
50
  # Try to instantiate the plugin
53
51
  # Clean plugin name: remove 'Plugin' suffix if present and use as name
54
52
  clean_name = plugin_name
@@ -58,7 +56,6 @@ class PluginFactory:
58
56
  instance = instantiate_plugin_safely(
59
57
  plugin_class,
60
58
  name=clean_name,
61
- state_manager=state_manager,
62
59
  event_bus=event_bus,
63
60
  renderer=renderer,
64
61
  config=config
@@ -78,30 +75,27 @@ class PluginFactory:
78
75
  def instantiate_all(
79
76
  self,
80
77
  plugin_classes: Dict[str, Type],
81
- state_manager: Any,
82
78
  event_bus: Any,
83
79
  renderer: Any,
84
80
  config: Any
85
81
  ) -> Dict[str, Any]:
86
82
  """Instantiate all provided plugin classes.
87
-
83
+
88
84
  Args:
89
85
  plugin_classes: Dictionary mapping plugin names to classes.
90
- state_manager: State management system.
91
86
  event_bus: Event bus for hook registration.
92
87
  renderer: Terminal renderer.
93
88
  config: Configuration manager.
94
-
89
+
95
90
  Returns:
96
91
  Dictionary mapping plugin names to their instances.
97
92
  """
98
93
  error_accumulator = ErrorAccumulator(logger)
99
-
94
+
100
95
  for plugin_name, plugin_class in plugin_classes.items():
101
96
  instance = self.instantiate_plugin(
102
97
  plugin_class,
103
98
  plugin_name,
104
- state_manager,
105
99
  event_bus,
106
100
  renderer,
107
101
  config
core/plugins/registry.py CHANGED
@@ -110,34 +110,22 @@ class PluginRegistry:
110
110
  """
111
111
  return list(self.discovery.loaded_classes.keys())
112
112
 
113
- def instantiate_plugins(self, state_manager, event_bus, renderer, config) -> Dict[str, Any]:
113
+ def instantiate_plugins(self, event_bus, renderer, config) -> Dict[str, Any]:
114
114
  """Create instances of all registered plugins that can be instantiated.
115
-
115
+
116
116
  Args:
117
- state_manager: State management system.
118
117
  event_bus: Event bus for hook registration.
119
118
  renderer: Terminal renderer.
120
119
  config: Configuration manager.
121
-
120
+
122
121
  Returns:
123
122
  Dictionary mapping plugin names to their instances.
124
123
  """
125
124
  plugin_classes = self.discovery.loaded_classes
126
125
  return self.factory.instantiate_all(
127
- plugin_classes, state_manager, event_bus, renderer, config
126
+ plugin_classes, event_bus, renderer, config
128
127
  )
129
-
130
- def collect_status_lines(self, plugin_instances: Dict[str, Any]) -> Dict[str, List[str]]:
131
- """Collect status lines from all plugins organized by area.
132
-
133
- Args:
134
- plugin_instances: Dictionary of plugin instances.
135
-
136
- Returns:
137
- Dictionary with areas A, B, C containing lists of status lines.
138
- """
139
- return self.collector.collect_all_status(plugin_instances)
140
-
128
+
141
129
  def get_registry_stats(self) -> Dict[str, Any]:
142
130
  """Get comprehensive statistics about the registry and its components.
143
131