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.
- examples/advance_tui.py +508 -0
- examples/agent_with_todos.py +165 -0
- examples/file_freshness_example.py +97 -0
- examples/file_watching_example.py +110 -0
- examples/interruptible_tui.py +5 -0
- examples/message_response_children_demo.py +226 -0
- examples/rich_example.py +4 -0
- examples/simple_file_watching.py +57 -0
- examples/simple_tui.py +267 -0
- examples/simple_usage.py +69 -0
- minion_code/__init__.py +16 -0
- minion_code/agents/__init__.py +11 -0
- minion_code/agents/code_agent.py +320 -0
- minion_code/cli.py +502 -0
- minion_code/commands/__init__.py +90 -0
- minion_code/commands/clear_command.py +70 -0
- minion_code/commands/help_command.py +90 -0
- minion_code/commands/history_command.py +104 -0
- minion_code/commands/quit_command.py +32 -0
- minion_code/commands/status_command.py +115 -0
- minion_code/commands/tools_command.py +86 -0
- minion_code/commands/version_command.py +104 -0
- minion_code/components/Message.py +304 -0
- minion_code/components/MessageResponse.py +188 -0
- minion_code/components/PromptInput.py +534 -0
- minion_code/components/__init__.py +29 -0
- minion_code/screens/REPL.py +925 -0
- minion_code/screens/__init__.py +4 -0
- minion_code/services/__init__.py +50 -0
- minion_code/services/event_system.py +108 -0
- minion_code/services/file_freshness_service.py +582 -0
- minion_code/tools/__init__.py +69 -0
- minion_code/tools/bash_tool.py +58 -0
- minion_code/tools/file_edit_tool.py +238 -0
- minion_code/tools/file_read_tool.py +73 -0
- minion_code/tools/file_write_tool.py +36 -0
- minion_code/tools/glob_tool.py +58 -0
- minion_code/tools/grep_tool.py +105 -0
- minion_code/tools/ls_tool.py +65 -0
- minion_code/tools/multi_edit_tool.py +271 -0
- minion_code/tools/python_interpreter_tool.py +105 -0
- minion_code/tools/todo_read_tool.py +100 -0
- minion_code/tools/todo_write_tool.py +234 -0
- minion_code/tools/user_input_tool.py +53 -0
- minion_code/types.py +88 -0
- minion_code/utils/__init__.py +44 -0
- minion_code/utils/mcp_loader.py +211 -0
- minion_code/utils/todo_file_utils.py +110 -0
- minion_code/utils/todo_storage.py +149 -0
- minion_code-0.1.0.dist-info/METADATA +350 -0
- minion_code-0.1.0.dist-info/RECORD +59 -0
- minion_code-0.1.0.dist-info/WHEEL +5 -0
- minion_code-0.1.0.dist-info/entry_points.txt +4 -0
- minion_code-0.1.0.dist-info/licenses/LICENSE +661 -0
- minion_code-0.1.0.dist-info/top_level.txt +3 -0
- tests/__init__.py +1 -0
- tests/test_basic.py +20 -0
- tests/test_readonly_tools.py +102 -0
- tests/test_tools.py +83 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Help command - Show available commands and their usage
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
from rich.panel import Panel
|
|
9
|
+
from rich.markdown import Markdown
|
|
10
|
+
from minion_code.commands import BaseCommand
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class HelpCommand(BaseCommand):
|
|
14
|
+
"""Show help information for commands."""
|
|
15
|
+
|
|
16
|
+
name = "help"
|
|
17
|
+
description = "Show available commands and their usage"
|
|
18
|
+
usage = "/help [command_name]"
|
|
19
|
+
aliases = ["h", "?"]
|
|
20
|
+
|
|
21
|
+
async def execute(self, args: str) -> None:
|
|
22
|
+
"""Execute the help command."""
|
|
23
|
+
args = args.strip()
|
|
24
|
+
|
|
25
|
+
if args:
|
|
26
|
+
# Show help for specific command
|
|
27
|
+
await self._show_command_help(args)
|
|
28
|
+
else:
|
|
29
|
+
# Show general help
|
|
30
|
+
await self._show_general_help()
|
|
31
|
+
|
|
32
|
+
async def _show_command_help(self, command_name: str) -> None:
|
|
33
|
+
"""Show help for a specific command."""
|
|
34
|
+
from minion_code.commands import command_registry
|
|
35
|
+
|
|
36
|
+
command_class = command_registry.get_command(command_name)
|
|
37
|
+
if not command_class:
|
|
38
|
+
error_panel = Panel(
|
|
39
|
+
f"❌ [bold red]Command '/{command_name}' not found[/bold red]",
|
|
40
|
+
title="[bold red]Error[/bold red]",
|
|
41
|
+
border_style="red"
|
|
42
|
+
)
|
|
43
|
+
self.console.print(error_panel)
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
# Create temporary command instance to get help
|
|
47
|
+
temp_command = command_class(self.console, self.agent)
|
|
48
|
+
help_text = temp_command.get_help()
|
|
49
|
+
|
|
50
|
+
help_panel = Panel(
|
|
51
|
+
Markdown(help_text),
|
|
52
|
+
title=f"[bold blue]Help: /{command_name}[/bold blue]",
|
|
53
|
+
border_style="blue"
|
|
54
|
+
)
|
|
55
|
+
self.console.print(help_panel)
|
|
56
|
+
|
|
57
|
+
async def _show_general_help(self) -> None:
|
|
58
|
+
"""Show general help with all commands."""
|
|
59
|
+
from minion_code.commands import command_registry
|
|
60
|
+
|
|
61
|
+
commands = command_registry.list_commands()
|
|
62
|
+
|
|
63
|
+
help_table = Table(
|
|
64
|
+
title="📚 Available Commands",
|
|
65
|
+
show_header=True,
|
|
66
|
+
header_style="bold blue"
|
|
67
|
+
)
|
|
68
|
+
help_table.add_column("Command", style="cyan", no_wrap=True)
|
|
69
|
+
help_table.add_column("Description", style="white")
|
|
70
|
+
help_table.add_column("Aliases", style="yellow")
|
|
71
|
+
|
|
72
|
+
for name, command_class in sorted(commands.items()):
|
|
73
|
+
aliases = ", ".join(f"/{alias}" for alias in command_class.aliases)
|
|
74
|
+
help_table.add_row(
|
|
75
|
+
f"/{name}",
|
|
76
|
+
command_class.description,
|
|
77
|
+
aliases or "-"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
self.console.print(help_table)
|
|
81
|
+
|
|
82
|
+
# Show usage info
|
|
83
|
+
usage_panel = Panel(
|
|
84
|
+
"💡 [italic]Commands must start with '/' (e.g., /help, /tools)[/italic]\n"
|
|
85
|
+
"💬 [italic]Regular messages are sent to the AI agent[/italic]\n"
|
|
86
|
+
"🔍 [italic]Use '/help <command>' for detailed help on a specific command[/italic]",
|
|
87
|
+
title="[bold green]Usage Tips[/bold green]",
|
|
88
|
+
border_style="green"
|
|
89
|
+
)
|
|
90
|
+
self.console.print(usage_panel)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
History command - Show conversation history
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from rich.panel import Panel
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
from minion_code.commands import BaseCommand
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class HistoryCommand(BaseCommand):
|
|
13
|
+
"""Show conversation history."""
|
|
14
|
+
|
|
15
|
+
name = "history"
|
|
16
|
+
description = "Show conversation history with the agent"
|
|
17
|
+
usage = "/history [count]"
|
|
18
|
+
aliases = ["hist", "h"]
|
|
19
|
+
|
|
20
|
+
async def execute(self, args: str) -> None:
|
|
21
|
+
"""Execute the history command."""
|
|
22
|
+
if not self.agent:
|
|
23
|
+
error_panel = Panel(
|
|
24
|
+
"❌ [bold red]Agent not initialized[/bold red]",
|
|
25
|
+
title="[bold red]Error[/bold red]",
|
|
26
|
+
border_style="red"
|
|
27
|
+
)
|
|
28
|
+
self.console.print(error_panel)
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
# Parse count argument
|
|
32
|
+
count = 5 # default
|
|
33
|
+
if args.strip():
|
|
34
|
+
try:
|
|
35
|
+
count = int(args.strip())
|
|
36
|
+
if count <= 0:
|
|
37
|
+
count = 5
|
|
38
|
+
except ValueError:
|
|
39
|
+
error_panel = Panel(
|
|
40
|
+
f"❌ [bold red]Invalid count: '{args.strip()}'. Using default (5)[/bold red]",
|
|
41
|
+
title="[bold red]Warning[/bold red]",
|
|
42
|
+
border_style="yellow"
|
|
43
|
+
)
|
|
44
|
+
self.console.print(error_panel)
|
|
45
|
+
|
|
46
|
+
history = self.agent.get_conversation_history()
|
|
47
|
+
if not history:
|
|
48
|
+
no_history_panel = Panel(
|
|
49
|
+
"📝 [italic]No conversation history yet.[/italic]",
|
|
50
|
+
title="[bold blue]History[/bold blue]",
|
|
51
|
+
border_style="blue"
|
|
52
|
+
)
|
|
53
|
+
self.console.print(no_history_panel)
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
# Show header
|
|
57
|
+
header_panel = Panel(
|
|
58
|
+
f"📝 [bold blue]Conversation History (showing last {min(count, len(history))} of {len(history)} messages)[/bold blue]",
|
|
59
|
+
border_style="blue"
|
|
60
|
+
)
|
|
61
|
+
self.console.print(header_panel)
|
|
62
|
+
|
|
63
|
+
# Show recent messages
|
|
64
|
+
recent_history = history[-count:] if count < len(history) else history
|
|
65
|
+
|
|
66
|
+
for i, entry in enumerate(recent_history, 1):
|
|
67
|
+
message_num = len(history) - len(recent_history) + i
|
|
68
|
+
|
|
69
|
+
# User message
|
|
70
|
+
user_msg = entry['user_message']
|
|
71
|
+
if len(user_msg) > 150:
|
|
72
|
+
user_msg = user_msg[:150] + "..."
|
|
73
|
+
|
|
74
|
+
user_panel = Panel(
|
|
75
|
+
user_msg,
|
|
76
|
+
title=f"👤 [bold cyan]You (#{message_num})[/bold cyan]",
|
|
77
|
+
border_style="cyan"
|
|
78
|
+
)
|
|
79
|
+
self.console.print(user_panel)
|
|
80
|
+
|
|
81
|
+
# Agent response
|
|
82
|
+
agent_msg = entry['agent_response']
|
|
83
|
+
if len(agent_msg) > 200:
|
|
84
|
+
agent_msg = agent_msg[:200] + "..."
|
|
85
|
+
|
|
86
|
+
agent_panel = Panel(
|
|
87
|
+
agent_msg,
|
|
88
|
+
title="🤖 [bold green]Agent[/bold green]",
|
|
89
|
+
border_style="green"
|
|
90
|
+
)
|
|
91
|
+
self.console.print(agent_panel)
|
|
92
|
+
|
|
93
|
+
if i < len(recent_history): # Don't add spacing after last message
|
|
94
|
+
self.console.print()
|
|
95
|
+
|
|
96
|
+
# Show summary if there are more messages
|
|
97
|
+
if len(history) > count:
|
|
98
|
+
summary_panel = Panel(
|
|
99
|
+
f"💡 [italic]Showing {count} most recent messages. "
|
|
100
|
+
f"Use '/history {len(history)}' to see all {len(history)} messages.[/italic]",
|
|
101
|
+
title="[bold yellow]Note[/bold yellow]",
|
|
102
|
+
border_style="yellow"
|
|
103
|
+
)
|
|
104
|
+
self.console.print(summary_panel)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Quit command - Exit the application
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from rich.panel import Panel
|
|
8
|
+
from minion_code.commands import BaseCommand
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class QuitCommand(BaseCommand):
|
|
12
|
+
"""Exit the application."""
|
|
13
|
+
|
|
14
|
+
name = "quit"
|
|
15
|
+
description = "Exit the application"
|
|
16
|
+
usage = "/quit"
|
|
17
|
+
aliases = ["exit", "q", "bye"]
|
|
18
|
+
|
|
19
|
+
async def execute(self, args: str) -> None:
|
|
20
|
+
"""Execute the quit command."""
|
|
21
|
+
goodbye_panel = Panel(
|
|
22
|
+
"👋 [bold yellow]Goodbye! Thanks for using MinionCode![/bold yellow]",
|
|
23
|
+
title="[bold red]Exit[/bold red]",
|
|
24
|
+
border_style="red"
|
|
25
|
+
)
|
|
26
|
+
self.console.print(goodbye_panel)
|
|
27
|
+
|
|
28
|
+
# Set a flag that the TUI can check and cleanup resources
|
|
29
|
+
if hasattr(self, '_tui_instance'):
|
|
30
|
+
self._tui_instance.running = False
|
|
31
|
+
# Cleanup MCP resources
|
|
32
|
+
await self._tui_instance.cleanup()
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Status command - Show system status and information
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from rich.panel import Panel
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
from rich.text import Text
|
|
10
|
+
import sys
|
|
11
|
+
import platform
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from minion_code.commands import BaseCommand
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class StatusCommand(BaseCommand):
|
|
17
|
+
"""Show system status and information."""
|
|
18
|
+
|
|
19
|
+
name = "status"
|
|
20
|
+
description = "Show system status, agent info, and statistics"
|
|
21
|
+
usage = "/status"
|
|
22
|
+
aliases = ["info", "stat"]
|
|
23
|
+
|
|
24
|
+
async def execute(self, args: str) -> None:
|
|
25
|
+
"""Execute the status command."""
|
|
26
|
+
# Create status table
|
|
27
|
+
status_table = Table(
|
|
28
|
+
title="📊 System Status",
|
|
29
|
+
show_header=True,
|
|
30
|
+
header_style="bold blue"
|
|
31
|
+
)
|
|
32
|
+
status_table.add_column("Component", style="cyan", no_wrap=True)
|
|
33
|
+
status_table.add_column("Status", style="white")
|
|
34
|
+
status_table.add_column("Details", style="yellow")
|
|
35
|
+
|
|
36
|
+
# System info
|
|
37
|
+
status_table.add_row(
|
|
38
|
+
"System",
|
|
39
|
+
"✅ Running",
|
|
40
|
+
f"{platform.system()} {platform.release()}"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
status_table.add_row(
|
|
44
|
+
"Python",
|
|
45
|
+
"✅ Active",
|
|
46
|
+
f"{sys.version.split()[0]}"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Agent info
|
|
50
|
+
if self.agent:
|
|
51
|
+
history = self.agent.get_conversation_history()
|
|
52
|
+
tools_count = len(self.agent.tools) if self.agent.tools else 0
|
|
53
|
+
|
|
54
|
+
status_table.add_row(
|
|
55
|
+
"Agent",
|
|
56
|
+
"✅ Ready",
|
|
57
|
+
f"{tools_count} tools loaded"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
status_table.add_row(
|
|
61
|
+
"Conversation",
|
|
62
|
+
"📝 Active" if history else "📝 Empty",
|
|
63
|
+
f"{len(history)} messages" if history else "No messages"
|
|
64
|
+
)
|
|
65
|
+
else:
|
|
66
|
+
status_table.add_row(
|
|
67
|
+
"Agent",
|
|
68
|
+
"❌ Not Ready",
|
|
69
|
+
"Not initialized"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Memory info (basic)
|
|
73
|
+
try:
|
|
74
|
+
import psutil
|
|
75
|
+
memory = psutil.virtual_memory()
|
|
76
|
+
status_table.add_row(
|
|
77
|
+
"Memory",
|
|
78
|
+
"📊 Monitored",
|
|
79
|
+
f"{memory.percent}% used ({memory.available // (1024**3)} GB free)"
|
|
80
|
+
)
|
|
81
|
+
except ImportError:
|
|
82
|
+
status_table.add_row(
|
|
83
|
+
"Memory",
|
|
84
|
+
"❌ Not Available",
|
|
85
|
+
"psutil not installed"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
self.console.print(status_table)
|
|
89
|
+
|
|
90
|
+
# Additional info panel
|
|
91
|
+
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
92
|
+
|
|
93
|
+
info_text = Text()
|
|
94
|
+
info_text.append("🕒 Current Time: ", style="bold")
|
|
95
|
+
info_text.append(f"{current_time}\n", style="white")
|
|
96
|
+
|
|
97
|
+
if self.agent:
|
|
98
|
+
info_text.append("🤖 Agent Model: ", style="bold")
|
|
99
|
+
info_text.append(f"{getattr(self.agent, 'llm', 'Unknown')}\n", style="white")
|
|
100
|
+
|
|
101
|
+
info_text.append("🛠️ Available Tools: ", style="bold")
|
|
102
|
+
if self.agent.tools:
|
|
103
|
+
tool_names = [tool.name for tool in self.agent.tools[:5]]
|
|
104
|
+
if len(self.agent.tools) > 5:
|
|
105
|
+
tool_names.append(f"... and {len(self.agent.tools) - 5} more")
|
|
106
|
+
info_text.append(", ".join(tool_names), style="white")
|
|
107
|
+
else:
|
|
108
|
+
info_text.append("None", style="red")
|
|
109
|
+
|
|
110
|
+
info_panel = Panel(
|
|
111
|
+
info_text,
|
|
112
|
+
title="[bold green]Additional Information[/bold green]",
|
|
113
|
+
border_style="green"
|
|
114
|
+
)
|
|
115
|
+
self.console.print(info_panel)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Tools command - Show available tools
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
from rich.panel import Panel
|
|
9
|
+
from minion_code.commands import BaseCommand
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ToolsCommand(BaseCommand):
|
|
13
|
+
"""Show available tools."""
|
|
14
|
+
|
|
15
|
+
name = "tools"
|
|
16
|
+
description = "List all available tools and their descriptions"
|
|
17
|
+
usage = "/tools [filter]"
|
|
18
|
+
aliases = ["t"]
|
|
19
|
+
|
|
20
|
+
async def execute(self, args: str) -> None:
|
|
21
|
+
"""Execute the tools command."""
|
|
22
|
+
if not self.agent or not self.agent.tools:
|
|
23
|
+
error_panel = Panel(
|
|
24
|
+
"❌ [bold red]No tools available or agent not initialized[/bold red]",
|
|
25
|
+
title="[bold red]Error[/bold red]",
|
|
26
|
+
border_style="red"
|
|
27
|
+
)
|
|
28
|
+
self.console.print(error_panel)
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
filter_text = args.strip().lower()
|
|
32
|
+
tools = self.agent.tools
|
|
33
|
+
|
|
34
|
+
# Filter tools if filter text provided
|
|
35
|
+
if filter_text:
|
|
36
|
+
tools = [tool for tool in tools
|
|
37
|
+
if filter_text in tool.name.lower() or
|
|
38
|
+
filter_text in tool.description.lower()]
|
|
39
|
+
|
|
40
|
+
if not tools:
|
|
41
|
+
no_tools_panel = Panel(
|
|
42
|
+
f"❌ [bold yellow]No tools found matching '{filter_text}'[/bold yellow]",
|
|
43
|
+
title="[bold yellow]No Results[/bold yellow]",
|
|
44
|
+
border_style="yellow"
|
|
45
|
+
)
|
|
46
|
+
self.console.print(no_tools_panel)
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
# Create tools table
|
|
50
|
+
tools_table = Table(
|
|
51
|
+
title=f"🛠️ Available Tools{f' (filtered: {filter_text})' if filter_text else ''}",
|
|
52
|
+
show_header=True,
|
|
53
|
+
header_style="bold magenta"
|
|
54
|
+
)
|
|
55
|
+
tools_table.add_column("Tool Name", style="cyan", no_wrap=True)
|
|
56
|
+
tools_table.add_column("Description", style="white")
|
|
57
|
+
tools_table.add_column("Type", style="yellow")
|
|
58
|
+
tools_table.add_column("Inputs", style="green")
|
|
59
|
+
|
|
60
|
+
for tool in tools:
|
|
61
|
+
tool_type = "Read-only" if getattr(tool, 'readonly', False) else "Read-write"
|
|
62
|
+
|
|
63
|
+
# Get input parameters
|
|
64
|
+
inputs = getattr(tool, 'inputs', {})
|
|
65
|
+
input_names = list(inputs.keys()) if inputs else []
|
|
66
|
+
input_str = ", ".join(input_names[:3]) # Show first 3 inputs
|
|
67
|
+
if len(input_names) > 3:
|
|
68
|
+
input_str += f" (+{len(input_names) - 3} more)"
|
|
69
|
+
|
|
70
|
+
tools_table.add_row(
|
|
71
|
+
tool.name,
|
|
72
|
+
tool.description[:50] + "..." if len(tool.description) > 50 else tool.description,
|
|
73
|
+
tool_type,
|
|
74
|
+
input_str or "-"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
self.console.print(tools_table)
|
|
78
|
+
|
|
79
|
+
# Show summary
|
|
80
|
+
summary_panel = Panel(
|
|
81
|
+
f"📊 [bold blue]Total: {len(tools)} tools[/bold blue]"
|
|
82
|
+
f"{f' (filtered from {len(self.agent.tools)} total)' if filter_text else ''}",
|
|
83
|
+
title="[bold green]Summary[/bold green]",
|
|
84
|
+
border_style="green"
|
|
85
|
+
)
|
|
86
|
+
self.console.print(summary_panel)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Version command - Show version information
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from rich.panel import Panel
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
from minion_code.commands import BaseCommand
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class VersionCommand(BaseCommand):
|
|
13
|
+
"""Show version information."""
|
|
14
|
+
|
|
15
|
+
name = "version"
|
|
16
|
+
description = "Show version information for MinionCode and dependencies"
|
|
17
|
+
usage = "/version"
|
|
18
|
+
aliases = ["v", "ver"]
|
|
19
|
+
|
|
20
|
+
async def execute(self, args: str) -> None:
|
|
21
|
+
"""Execute the version command."""
|
|
22
|
+
# Create version table
|
|
23
|
+
version_table = Table(
|
|
24
|
+
title="📦 Version Information",
|
|
25
|
+
show_header=True,
|
|
26
|
+
header_style="bold blue"
|
|
27
|
+
)
|
|
28
|
+
version_table.add_column("Component", style="cyan", no_wrap=True)
|
|
29
|
+
version_table.add_column("Version", style="white")
|
|
30
|
+
version_table.add_column("Status", style="green")
|
|
31
|
+
|
|
32
|
+
# MinionCode version
|
|
33
|
+
version_table.add_row(
|
|
34
|
+
"MinionCode",
|
|
35
|
+
"0.1.0",
|
|
36
|
+
"✅ Active"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Python version
|
|
40
|
+
import sys
|
|
41
|
+
version_table.add_row(
|
|
42
|
+
"Python",
|
|
43
|
+
f"{sys.version.split()[0]}",
|
|
44
|
+
"✅ Compatible"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Rich version
|
|
48
|
+
try:
|
|
49
|
+
import rich
|
|
50
|
+
version = getattr(rich, '__version__', 'Unknown')
|
|
51
|
+
version_table.add_row(
|
|
52
|
+
"Rich",
|
|
53
|
+
version,
|
|
54
|
+
"✅ Loaded"
|
|
55
|
+
)
|
|
56
|
+
except ImportError:
|
|
57
|
+
version_table.add_row(
|
|
58
|
+
"Rich",
|
|
59
|
+
"Not installed",
|
|
60
|
+
"❌ Missing"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Textual version
|
|
64
|
+
try:
|
|
65
|
+
import textual
|
|
66
|
+
version = getattr(textual, '__version__', 'Unknown')
|
|
67
|
+
version_table.add_row(
|
|
68
|
+
"Textual",
|
|
69
|
+
version,
|
|
70
|
+
"✅ Available"
|
|
71
|
+
)
|
|
72
|
+
except ImportError:
|
|
73
|
+
version_table.add_row(
|
|
74
|
+
"Textual",
|
|
75
|
+
"Not installed",
|
|
76
|
+
"⚠️ Optional"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Minion version
|
|
80
|
+
try:
|
|
81
|
+
import minion
|
|
82
|
+
version_table.add_row(
|
|
83
|
+
"Minion",
|
|
84
|
+
getattr(minion, '__version__', 'Unknown'),
|
|
85
|
+
"✅ Core"
|
|
86
|
+
)
|
|
87
|
+
except ImportError:
|
|
88
|
+
version_table.add_row(
|
|
89
|
+
"Minion",
|
|
90
|
+
"Not found",
|
|
91
|
+
"❌ Required"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
self.console.print(version_table)
|
|
95
|
+
|
|
96
|
+
# Additional info
|
|
97
|
+
info_panel = Panel(
|
|
98
|
+
"🚀 [bold blue]MinionCode TUI[/bold blue] - Advanced AI-powered development assistant\n"
|
|
99
|
+
"🔗 Built with Rich for beautiful terminal interfaces\n"
|
|
100
|
+
"🤖 Powered by Minion framework for AI agent capabilities",
|
|
101
|
+
title="[bold green]About[/bold green]",
|
|
102
|
+
border_style="green"
|
|
103
|
+
)
|
|
104
|
+
self.console.print(info_panel)
|