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/config/loader.py CHANGED
@@ -7,16 +7,44 @@ from importlib.metadata import version as get_version, PackageNotFoundError
7
7
 
8
8
  from ..utils import deep_merge
9
9
  from ..utils.error_utils import safe_execute, log_and_continue
10
- from ..utils.config_utils import get_system_prompt_content
10
+ from ..utils.config_utils import get_system_prompt_content, get_project_data_dir
11
11
  from ..utils.prompt_renderer import render_system_prompt
12
12
  from .manager import ConfigManager
13
13
  from .plugin_config_manager import PluginConfigManager
14
14
 
15
- # Get version from package metadata
16
- try:
17
- _package_version = get_version("kollabor")
18
- except PackageNotFoundError:
19
- _package_version = "0.4.7" # Fallback for development mode
15
+ def _get_version_from_pyproject() -> str:
16
+ """Read version from pyproject.toml for development mode."""
17
+ try:
18
+ pyproject_path = Path(__file__).parent.parent.parent / "pyproject.toml"
19
+ if pyproject_path.exists():
20
+ content = pyproject_path.read_text()
21
+ for line in content.splitlines():
22
+ if line.startswith("version ="):
23
+ # Extract version from: version = "0.4.10"
24
+ return line.split("=")[1].strip().strip('"').strip("'")
25
+ except Exception:
26
+ pass
27
+ return None # Return None if not found
28
+
29
+ def _is_running_from_source() -> bool:
30
+ """Check if we're running from source (development mode) vs installed package."""
31
+ try:
32
+ # If pyproject.toml exists in parent directory, we're running from source
33
+ pyproject_path = Path(__file__).parent.parent.parent / "pyproject.toml"
34
+ return pyproject_path.exists()
35
+ except Exception:
36
+ return False
37
+
38
+ # Get version: prefer pyproject.toml when running from source, otherwise use installed version
39
+ if _is_running_from_source():
40
+ # Development mode: use pyproject.toml
41
+ _package_version = _get_version_from_pyproject() or "0.0.0"
42
+ else:
43
+ # Production mode: use installed package version
44
+ try:
45
+ _package_version = get_version("kollabor")
46
+ except PackageNotFoundError:
47
+ _package_version = "0.0.0"
20
48
 
21
49
  logger = logging.getLogger(__name__)
22
50
 
@@ -113,7 +141,7 @@ class ConfigLoader:
113
141
  },
114
142
  "logging": {
115
143
  "level": "INFO",
116
- "file": ".kollabor-cli/logs/kollabor.log",
144
+ "file": None, # Determined dynamically by get_logs_dir()
117
145
  "format_type": "compact",
118
146
  "format": "%(asctime)s - %(levelname)-4s - %(message)-100s - %(filename)s:%(lineno)04d"
119
147
  },
@@ -129,11 +157,8 @@ class ConfigLoader:
129
157
  },
130
158
  "core": {
131
159
  "llm": {
132
- "api_url": "http://localhost:1234",
133
- "api_token": "",
134
- "model": "qwen/qwen3-4b",
135
- "temperature": 0.7,
136
- "timeout": 0,
160
+ # Note: api_url, api_token, model, temperature, timeout are now in profiles
161
+ # See core.llm.profiles.* for LLM connection settings
137
162
  "max_history": 90,
138
163
  "save_conversations": True,
139
164
  "conversation_format": "jsonl",
@@ -146,11 +171,11 @@ class ConfigLoader:
146
171
  "processing_delay": 0.1,
147
172
  "thinking_delay": 0.3,
148
173
  "api_poll_delay": 0.01,
149
- "terminal_timeout": 30,
174
+ "terminal_timeout": 120,
150
175
  "mcp_timeout": 60,
151
176
  "system_prompt": {
152
177
  "base_prompt": system_prompt,
153
- "include_project_structure": True,
178
+ "include_project_structure": False,
154
179
  "attachment_files": [],
155
180
  "custom_prompt_files": []
156
181
  },
@@ -384,10 +409,11 @@ class ConfigLoader:
384
409
  This is the main entry point for getting a fully merged configuration
385
410
  that includes base defaults, plugin configs, and user overrides.
386
411
 
387
- Priority order for user config:
388
- 1. Local config (.kollabor-cli/config.json in current directory)
389
- 2. Global config (~/.kollabor-cli/config.json in home directory)
390
- 3. Base defaults (if neither exists)
412
+ Priority order for user config (new layered system):
413
+ 1. Global config (~/.kollabor-cli/config.json) - base layer
414
+ 2. Project config (~/.kollabor-cli/projects/<encoded>/config.json) - project defaults
415
+ 3. Local config (.kollabor-cli/config.json in current directory) - local override
416
+ 4. Base defaults (if none exist)
391
417
 
392
418
  Returns:
393
419
  Complete merged configuration dictionary.
@@ -411,37 +437,81 @@ class ConfigLoader:
411
437
  return base_config
412
438
 
413
439
  def _load_user_config_with_fallback(self) -> Dict[str, Any]:
414
- """Load user configuration, falling back to global config if local doesn't exist.
440
+ """Load user configuration with layered resolution.
415
441
 
416
- Priority order:
417
- 1. Local config (current directory's .kollabor-cli/config.json)
418
- 2. Global config (~/.kollabor-cli/config.json)
442
+ Priority order (new layered system):
443
+ 1. Explicit config_manager.config_path (if provided and exists)
444
+ 2. Global config (~/.kollabor-cli/config.json) - base layer
445
+ 3. Project config (~/.kollabor-cli/projects/<encoded>/config.json) - project defaults
446
+ 4. Local config (.kollabor-cli/config.json) - local override
447
+
448
+ Each layer is merged on top of the previous one using deep_merge.
419
449
 
420
450
  Returns:
421
- User configuration dictionary, or empty dict if none found.
451
+ Merged user configuration dictionary, or empty dict if none found.
422
452
  """
423
- # Check if local config exists
424
- if self.config_manager.config_path.exists():
425
- user_config = self.config_manager.load_config_file()
426
- if user_config:
427
- logger.debug(f"Loaded local config from: {self.config_manager.config_path}")
428
- return user_config
429
-
430
- # Fall back to global config
453
+ import json
454
+
455
+ merged_config = {}
456
+
457
+ # Check if an explicit config path was provided (e.g., for testing)
458
+ explicit_path = None
459
+ if self.config_manager and self.config_manager.config_path:
460
+ explicit_path = self.config_manager.config_path
461
+ # If explicit path exists and is not in standard locations, load only from it
462
+ standard_paths = [
463
+ Path.home() / ".kollabor-cli" / "config.json",
464
+ get_project_data_dir() / "config.json",
465
+ Path.cwd() / ".kollabor-cli" / "config.json",
466
+ ]
467
+ if explicit_path.exists() and explicit_path not in standard_paths:
468
+ try:
469
+ with open(explicit_path, 'r') as f:
470
+ return json.load(f) or {}
471
+ except Exception as e:
472
+ logger.warning(f"Failed to load explicit config: {e}")
473
+ return {}
474
+
475
+ # Layer 1: Global config (base)
431
476
  global_config_path = Path.home() / ".kollabor-cli" / "config.json"
432
477
  if global_config_path.exists():
433
478
  try:
434
- import json
435
479
  with open(global_config_path, 'r') as f:
436
480
  global_config = json.load(f)
437
481
  if global_config:
438
- logger.info(f"Using global config as fallback from: {global_config_path}")
439
- return global_config
482
+ merged_config = global_config
483
+ logger.debug(f"Loaded global config from: {global_config_path}")
440
484
  except Exception as e:
441
485
  logger.warning(f"Failed to load global config: {e}")
442
486
 
443
- logger.debug("No user configuration found (local or global)")
444
- return {}
487
+ # Layer 2: Project config (defaults for this project)
488
+ project_config_path = get_project_data_dir() / "config.json"
489
+ if project_config_path.exists():
490
+ try:
491
+ with open(project_config_path, 'r') as f:
492
+ project_config = json.load(f)
493
+ if project_config:
494
+ merged_config = deep_merge(merged_config, project_config)
495
+ logger.debug(f"Merged project config from: {project_config_path}")
496
+ except Exception as e:
497
+ logger.warning(f"Failed to load project config: {e}")
498
+
499
+ # Layer 3: Local config (override)
500
+ local_config_path = Path.cwd() / ".kollabor-cli" / "config.json"
501
+ if local_config_path.exists():
502
+ try:
503
+ with open(local_config_path, 'r') as f:
504
+ local_config = json.load(f)
505
+ if local_config:
506
+ merged_config = deep_merge(merged_config, local_config)
507
+ logger.debug(f"Merged local config from: {local_config_path}")
508
+ except Exception as e:
509
+ logger.warning(f"Failed to load local config: {e}")
510
+
511
+ if not merged_config:
512
+ logger.debug("No user configuration found (global, project, or local)")
513
+
514
+ return merged_config
445
515
 
446
516
  def save_merged_config(self, config: Dict[str, Any]) -> bool:
447
517
  """Save the complete merged configuration to file.
@@ -449,6 +519,11 @@ class ConfigLoader:
449
519
  Note: base_prompt is excluded from saving because it should always
450
520
  be dynamically loaded from the system_prompt/*.md files on startup.
451
521
 
522
+ Save path determination (new layered system):
523
+ 1. Local .kollabor-cli/config.json (if exists) - local override
524
+ 2. Project config (if exists) - project defaults
525
+ 3. Global config - fallback
526
+
452
527
  Args:
453
528
  config: Configuration dictionary to save.
454
529
 
@@ -456,6 +531,7 @@ class ConfigLoader:
456
531
  True if save successful, False otherwise.
457
532
  """
458
533
  import copy
534
+ import json
459
535
  config_to_save = copy.deepcopy(config)
460
536
 
461
537
  # Remove base_prompt - it should always be loaded fresh from .md files
@@ -466,7 +542,45 @@ class ConfigLoader:
466
542
  except (KeyError, TypeError):
467
543
  pass # Config structure doesn't match expected format
468
544
 
469
- return self.config_manager.save_config_file(config_to_save)
545
+ # Use the config_manager's path if available, otherwise determine from layered system
546
+ if self.config_manager and self.config_manager.config_path:
547
+ save_path = self.config_manager.config_path
548
+ else:
549
+ save_path = self._get_config_save_path()
550
+ save_path.parent.mkdir(parents=True, exist_ok=True)
551
+
552
+ try:
553
+ with open(save_path, 'w') as f:
554
+ json.dump(config_to_save, f, indent=2, ensure_ascii=False)
555
+ logger.info(f"Saved configuration to: {save_path}")
556
+ return True
557
+ except Exception as e:
558
+ logger.error(f"Failed to save configuration to {save_path}: {e}")
559
+ return False
560
+
561
+ def _get_config_save_path(self) -> Path:
562
+ """Determine the appropriate config save path.
563
+
564
+ Priority:
565
+ 1. Local .kollabor-cli/config.json (if exists) - local override
566
+ 2. Project config (if exists) - project defaults
567
+ 3. Global config - fallback
568
+
569
+ Returns:
570
+ Path where config should be saved.
571
+ """
572
+ # Check local override
573
+ local_path = Path.cwd() / ".kollabor-cli" / "config.json"
574
+ if local_path.exists():
575
+ return local_path
576
+
577
+ # Check project config
578
+ project_path = get_project_data_dir() / "config.json"
579
+ if project_path.exists():
580
+ return project_path
581
+
582
+ # Default to global
583
+ return Path.home() / ".kollabor-cli" / "config.json"
470
584
 
471
585
  def update_with_plugins(self) -> bool:
472
586
  """Update the configuration file with newly discovered plugins.
core/config/service.py CHANGED
@@ -141,18 +141,30 @@ class ConfigService:
141
141
 
142
142
  def set(self, key_path: str, value: Any) -> bool:
143
143
  """Set a configuration value using dot notation.
144
-
144
+
145
+ Saves to the appropriate location based on the layered config system:
146
+ 1. Local .kollabor-cli/config.json (if exists)
147
+ 2. Project config (if exists)
148
+ 3. Global config (fallback)
149
+
145
150
  Args:
146
151
  key_path: Dot-separated path to the config value.
147
152
  value: Value to set.
148
-
153
+
149
154
  Returns:
150
155
  True if set successful, False otherwise.
151
156
  """
152
- success = self.config_manager.set(key_path, value)
153
- if success:
154
- logger.debug(f"Configuration updated: {key_path}")
155
- return success
157
+ from ..utils import safe_set
158
+
159
+ if safe_set(self.config_manager.config, key_path, value):
160
+ # Use the loader's save mechanism which respects the layered system
161
+ success = self.config_loader.save_merged_config(self.config_manager.config)
162
+ if success:
163
+ logger.debug(f"Configuration updated: {key_path}")
164
+ return True
165
+
166
+ logger.error(f"Failed to set config key: {key_path}")
167
+ return False
156
168
 
157
169
  def reload(self) -> bool:
158
170
  """Reload configuration from file and plugins.
core/events/bus.py CHANGED
@@ -1,36 +1,56 @@
1
1
  """Event system for plugin communication."""
2
2
 
3
3
  import logging
4
- from typing import Any, Dict
4
+ from typing import Any, Dict, Optional
5
5
 
6
6
  from .models import EventType, Hook
7
7
  from .registry import HookRegistry
8
- from .executor import HookExecutor
9
8
  from .processor import EventProcessor
10
9
 
11
10
  logger = logging.getLogger(__name__)
12
11
 
12
+ # Import constants after HookExecutor to avoid circular import
13
+ from .executor import (
14
+ HookExecutor,
15
+ DEFAULT_HOOK_TIMEOUT,
16
+ DEFAULT_HOOK_RETRIES,
17
+ DEFAULT_ERROR_ACTION,
18
+ ABSOLUTE_MAX_RETRIES,
19
+ MIN_TIMEOUT,
20
+ MAX_TIMEOUT,
21
+ VALID_ERROR_ACTIONS
22
+ )
23
+
13
24
 
14
25
  class EventBus:
15
26
  """Simplified event bus system for plugin communication.
16
-
27
+
17
28
  Coordinates between specialized components for hook registration
18
29
  and event processing with clean separation of concerns.
19
30
  """
20
-
21
- def __init__(self) -> None:
22
- """Initialize the event bus with specialized components."""
31
+
32
+ def __init__(self, config: Optional[Dict[str, Any]] = None) -> None:
33
+ """Initialize the event bus with specialized components.
34
+
35
+ Args:
36
+ config: Configuration dictionary for hook defaults.
37
+ """
38
+ self.config = config or {}
23
39
  self.hook_registry = HookRegistry()
24
- self.hook_executor = HookExecutor()
40
+ self.hook_executor = HookExecutor(config=self.config)
25
41
  self.event_processor = EventProcessor(self.hook_registry, self.hook_executor)
26
42
  logger.info("Event bus initialized with specialized components")
27
43
 
28
44
  async def register_hook(self, hook: Hook) -> bool:
29
45
  """Register a hook with the event bus.
30
-
46
+
47
+ Note: Config defaults are applied during execution in HookExecutor,
48
+ not during registration. This allows runtime config changes to take
49
+ effect immediately without re-registering hooks.
50
+
31
51
  Args:
32
52
  hook: The hook to register.
33
-
53
+
34
54
  Returns:
35
55
  True if registration successful, False otherwise.
36
56
  """