minion-code 0.1.0__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 (59) hide show
  1. examples/advance_tui.py +508 -0
  2. examples/agent_with_todos.py +165 -0
  3. examples/file_freshness_example.py +97 -0
  4. examples/file_watching_example.py +110 -0
  5. examples/interruptible_tui.py +5 -0
  6. examples/message_response_children_demo.py +226 -0
  7. examples/rich_example.py +4 -0
  8. examples/simple_file_watching.py +57 -0
  9. examples/simple_tui.py +267 -0
  10. examples/simple_usage.py +69 -0
  11. minion_code/__init__.py +16 -0
  12. minion_code/agents/__init__.py +11 -0
  13. minion_code/agents/code_agent.py +320 -0
  14. minion_code/cli.py +502 -0
  15. minion_code/commands/__init__.py +90 -0
  16. minion_code/commands/clear_command.py +70 -0
  17. minion_code/commands/help_command.py +90 -0
  18. minion_code/commands/history_command.py +104 -0
  19. minion_code/commands/quit_command.py +32 -0
  20. minion_code/commands/status_command.py +115 -0
  21. minion_code/commands/tools_command.py +86 -0
  22. minion_code/commands/version_command.py +104 -0
  23. minion_code/components/Message.py +304 -0
  24. minion_code/components/MessageResponse.py +188 -0
  25. minion_code/components/PromptInput.py +534 -0
  26. minion_code/components/__init__.py +29 -0
  27. minion_code/screens/REPL.py +925 -0
  28. minion_code/screens/__init__.py +4 -0
  29. minion_code/services/__init__.py +50 -0
  30. minion_code/services/event_system.py +108 -0
  31. minion_code/services/file_freshness_service.py +582 -0
  32. minion_code/tools/__init__.py +69 -0
  33. minion_code/tools/bash_tool.py +58 -0
  34. minion_code/tools/file_edit_tool.py +238 -0
  35. minion_code/tools/file_read_tool.py +73 -0
  36. minion_code/tools/file_write_tool.py +36 -0
  37. minion_code/tools/glob_tool.py +58 -0
  38. minion_code/tools/grep_tool.py +105 -0
  39. minion_code/tools/ls_tool.py +65 -0
  40. minion_code/tools/multi_edit_tool.py +271 -0
  41. minion_code/tools/python_interpreter_tool.py +105 -0
  42. minion_code/tools/todo_read_tool.py +100 -0
  43. minion_code/tools/todo_write_tool.py +234 -0
  44. minion_code/tools/user_input_tool.py +53 -0
  45. minion_code/types.py +88 -0
  46. minion_code/utils/__init__.py +44 -0
  47. minion_code/utils/mcp_loader.py +211 -0
  48. minion_code/utils/todo_file_utils.py +110 -0
  49. minion_code/utils/todo_storage.py +149 -0
  50. minion_code-0.1.0.dist-info/METADATA +350 -0
  51. minion_code-0.1.0.dist-info/RECORD +59 -0
  52. minion_code-0.1.0.dist-info/WHEEL +5 -0
  53. minion_code-0.1.0.dist-info/entry_points.txt +4 -0
  54. minion_code-0.1.0.dist-info/licenses/LICENSE +661 -0
  55. minion_code-0.1.0.dist-info/top_level.txt +3 -0
  56. tests/__init__.py +1 -0
  57. tests/test_basic.py +20 -0
  58. tests/test_readonly_tools.py +102 -0
  59. tests/test_tools.py +83 -0
@@ -0,0 +1,4 @@
1
+ """
2
+ Screens module for minion_code
3
+ Contains UI screen components using Textual
4
+ """
@@ -0,0 +1,50 @@
1
+ """Services module for minion_code."""
2
+
3
+ from .event_system import (
4
+ EventDispatcher,
5
+ EventContext,
6
+ EventType,
7
+ EventCallback,
8
+ global_event_dispatcher,
9
+ add_event_listener,
10
+ emit_event,
11
+ remove_event_listener,
12
+ )
13
+
14
+ from .file_freshness_service import (
15
+ FileFreshnessService,
16
+ FileTimestamp,
17
+ FreshnessResult,
18
+ file_freshness_service,
19
+ record_file_read,
20
+ record_file_edit,
21
+ check_file_freshness,
22
+ generate_file_modification_reminder,
23
+ reset_file_freshness_session,
24
+ start_watching_todo_file,
25
+ stop_watching_todo_file,
26
+ )
27
+
28
+ __all__ = [
29
+ # Event system
30
+ 'EventDispatcher',
31
+ 'EventContext',
32
+ 'EventType',
33
+ 'EventCallback',
34
+ 'global_event_dispatcher',
35
+ 'add_event_listener',
36
+ 'emit_event',
37
+ 'remove_event_listener',
38
+ # File freshness service
39
+ 'FileFreshnessService',
40
+ 'FileTimestamp',
41
+ 'FreshnessResult',
42
+ 'file_freshness_service',
43
+ 'record_file_read',
44
+ 'record_file_edit',
45
+ 'check_file_freshness',
46
+ 'generate_file_modification_reminder',
47
+ 'reset_file_freshness_session',
48
+ 'start_watching_todo_file',
49
+ 'stop_watching_todo_file',
50
+ ]
@@ -0,0 +1,108 @@
1
+ """Event system for minion_code services."""
2
+
3
+ from typing import Dict, List, Callable, Any, Optional
4
+ import logging
5
+ from dataclasses import dataclass
6
+ from enum import Enum
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class EventType(Enum):
12
+ """Supported event types."""
13
+ SESSION_STARTUP = "session:startup"
14
+ TODO_CHANGED = "todo:changed"
15
+ TODO_FILE_CHANGED = "todo:file_changed"
16
+ FILE_READ = "file:read"
17
+ FILE_EDITED = "file:edited"
18
+ FILE_CONFLICT = "file:conflict"
19
+ AGENT_MENTIONED = "agent:mentioned"
20
+ FILE_MENTIONED = "file:mentioned"
21
+ ASK_MODEL_MENTIONED = "ask-model:mentioned"
22
+ REMINDER_INJECT = "reminder:inject"
23
+
24
+
25
+ @dataclass
26
+ class EventContext:
27
+ """Context data for events."""
28
+ event_type: str
29
+ timestamp: float
30
+ data: Dict[str, Any]
31
+
32
+
33
+ EventCallback = Callable[[EventContext], None]
34
+
35
+
36
+ class EventDispatcher:
37
+ """Simple event dispatcher for handling system events."""
38
+
39
+ def __init__(self):
40
+ self._listeners: Dict[str, List[EventCallback]] = {}
41
+
42
+ def add_event_listener(self, event_type: str, callback: EventCallback) -> None:
43
+ """Add an event listener for a specific event type."""
44
+ if event_type not in self._listeners:
45
+ self._listeners[event_type] = []
46
+ self._listeners[event_type].append(callback)
47
+ logger.debug(f"Added event listener for {event_type}")
48
+
49
+ def remove_event_listener(self, event_type: str, callback: EventCallback) -> bool:
50
+ """Remove a specific event listener."""
51
+ if event_type in self._listeners:
52
+ try:
53
+ self._listeners[event_type].remove(callback)
54
+ logger.debug(f"Removed event listener for {event_type}")
55
+ return True
56
+ except ValueError:
57
+ pass
58
+ return False
59
+
60
+ def emit_event(self, event_type: str, data: Optional[Dict[str, Any]] = None) -> None:
61
+ """Emit an event to all registered listeners."""
62
+ if event_type not in self._listeners:
63
+ return
64
+
65
+ import time
66
+ context = EventContext(
67
+ event_type=event_type,
68
+ timestamp=time.time(),
69
+ data=data or {}
70
+ )
71
+
72
+ listeners = self._listeners[event_type].copy() # Avoid modification during iteration
73
+ for callback in listeners:
74
+ try:
75
+ callback(context)
76
+ except Exception as error:
77
+ logger.error(f"Error in event listener for {event_type}: {error}")
78
+
79
+ def clear_listeners(self, event_type: Optional[str] = None) -> None:
80
+ """Clear listeners for a specific event type or all listeners."""
81
+ if event_type:
82
+ self._listeners.pop(event_type, None)
83
+ else:
84
+ self._listeners.clear()
85
+
86
+ def get_listener_count(self, event_type: str) -> int:
87
+ """Get the number of listeners for an event type."""
88
+ return len(self._listeners.get(event_type, []))
89
+
90
+
91
+ # Global event dispatcher instance
92
+ global_event_dispatcher = EventDispatcher()
93
+
94
+
95
+ # Convenience functions
96
+ def add_event_listener(event_type: str, callback: EventCallback) -> None:
97
+ """Add an event listener using the global dispatcher."""
98
+ global_event_dispatcher.add_event_listener(event_type, callback)
99
+
100
+
101
+ def emit_event(event_type: str, data: Optional[Dict[str, Any]] = None) -> None:
102
+ """Emit an event using the global dispatcher."""
103
+ global_event_dispatcher.emit_event(event_type, data)
104
+
105
+
106
+ def remove_event_listener(event_type: str, callback: EventCallback) -> bool:
107
+ """Remove an event listener using the global dispatcher."""
108
+ return global_event_dispatcher.remove_event_listener(event_type, callback)