Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 0 additions & 100 deletions README_TESTING.md

This file was deleted.

2 changes: 1 addition & 1 deletion examples/components/message_response_children_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from minion_code.components import Message, MessageResponse
from minion_code.types import Message as MessageType, MessageContent, MessageType as MsgType
from minion_code.type_defs import Message as MessageType, MessageContent, MessageType as MsgType


class MessageResponseChildrenDemo(App):
Expand Down
2 changes: 1 addition & 1 deletion examples/components/messages_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

# Import the components we want to test
from minion_code.components.Messages import Messages
from minion_code.types import Message, MessageType, MessageContent
from minion_code.type_defs import Message, MessageType, MessageContent


class TestMessagesApp(App):
Expand Down
74 changes: 58 additions & 16 deletions examples/interruptible_tui.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from minion_code import MinionCodeAgent
from minion_code.commands import command_registry
from minion_code.utils.mcp_loader import MCPToolsLoader
from minion_code.types import InputMode
from minion_code.type_defs import InputMode
from minion_code.adapters.rich_adapter import RichOutputAdapter

app = typer.Typer(
Expand Down Expand Up @@ -63,17 +63,21 @@ async def setup(self):
TextColumn("[progress.description]{task.description}"),
console=self.console,
) as progress:
# Load MCP tools if config provided
mcp_task = None
if self.mcp_config:
mcp_task = progress.add_task("🔌 Loading MCP tools...", total=None)
try:
self.mcp_loader = MCPToolsLoader(self.mcp_config)
# Load MCP tools - auto-discover if not explicitly provided
mcp_task = progress.add_task("🔌 Loading MCP tools...", total=None)
try:
# MCPToolsLoader will auto-discover config if mcp_config is None
self.mcp_loader = MCPToolsLoader(self.mcp_config, auto_discover=True)

if self.mcp_loader.config_path:
if self.verbose:
self.console.print(f"[dim]Using MCP config: {self.mcp_loader.config_path}[/dim]")

self.mcp_loader.load_config()
self.mcp_tools = await self.mcp_loader.load_all_tools()

if self.mcp_tools:
self.console.print(f"✅ Loaded {len(self.mcp_tools)} MCP tools")
self.console.print(f"✅ Loaded {len(self.mcp_tools)} MCP tools from {self.mcp_loader.config_path}")
else:
server_info = self.mcp_loader.get_server_info()
if server_info:
Expand All @@ -83,13 +87,17 @@ async def setup(self):
self.console.print(f" - {name}: {info['command']} ({status})")
else:
self.console.print("⚠️ No MCP servers found in config")

progress.update(mcp_task, completed=True)
except Exception as e:
self.console.print(f"❌ Failed to load MCP tools: {e}")
else:
if self.verbose:
import traceback
self.console.print(f"[dim]{traceback.format_exc()}[/dim]")
self.console.print("[dim]No MCP config found in standard locations[/dim]")

progress.update(mcp_task, completed=True)
except Exception as e:
self.console.print(f"❌ Failed to load MCP tools: {e}")
if self.verbose:
import traceback
self.console.print(f"[dim]{traceback.format_exc()}[/dim]")
progress.update(mcp_task, completed=True)

agent_task = progress.add_task("🔧 Setting up MinionCodeAgent...", total=None)

Expand Down Expand Up @@ -551,7 +559,9 @@ async def process_input(self, user_input: str):
self.console.print(f"[dim]Full traceback:\n{traceback.format_exc()}[/dim]")

async def process_command(self, command_input: str):
"""Process a command input."""
"""Process a command input with support for different command types."""
from minion_code.commands import CommandType

# Remove the leading /
command_input = command_input[1:] if command_input.startswith('/') else command_input

Expand All @@ -575,8 +585,40 @@ async def process_command(self, command_input: str):
self.console.print(error_panel)
return

# Create and execute command
# Get command type and is_skill
command_type = getattr(command_class, 'command_type', CommandType.LOCAL)
is_skill = getattr(command_class, 'is_skill', False)

# Handle PROMPT type commands - expand and send to LLM
if command_type == CommandType.PROMPT:
try:
output_adapter = RichOutputAdapter(self.console)
command_instance = command_class(output_adapter, self.agent)
expanded_prompt = await command_instance.get_prompt(args)

# Process expanded prompt through AI
self.console.print(f"[dim]Expanded prompt: {expanded_prompt[:100]}...[/dim]" if self.verbose else "")
await self.process_input(expanded_prompt)

except Exception as e:
error_panel = Panel(
f"❌ [bold red]Error expanding command /{command_name}: {e}[/bold red]",
title="[bold red]Command Error[/bold red]",
border_style="red"
)
self.console.print(error_panel)
return

# Handle LOCAL and LOCAL_JSX type commands - direct execution
try:
# Show status message based on is_skill
if is_skill:
status_text = f"⚙️ /{command_name} skill is executing..."
else:
status_text = f"⚙️ /{command_name} is executing..."

self.console.print(f"[dim]{status_text}[/dim]")

# Wrap console in RichOutputAdapter for commands
output_adapter = RichOutputAdapter(self.console)
command_instance = command_class(output_adapter, self.agent)
Expand Down
92 changes: 92 additions & 0 deletions examples/skills/code-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
name: code-review
description: Performs thorough code reviews with focus on best practices, security, performance, and maintainability. Use this skill when reviewing pull requests, auditing code quality, or getting feedback on implementations.
allowed-tools:
- Read
- Grep
- Glob
- Bash
---

# Code Review Skill

This skill provides a systematic approach to reviewing code for quality, security, and best practices.

## Review Checklist

### 1. Code Quality
- [ ] Code is readable and well-organized
- [ ] Functions/methods have single responsibility
- [ ] Variable and function names are descriptive
- [ ] No code duplication (DRY principle)
- [ ] Appropriate error handling

### 2. Security
- [ ] No hardcoded secrets or credentials
- [ ] Input validation present
- [ ] SQL injection prevention (parameterized queries)
- [ ] XSS prevention (output encoding)
- [ ] Authentication/authorization checks

### 3. Performance
- [ ] No N+1 query problems
- [ ] Appropriate caching strategies
- [ ] No unnecessary loops or computations
- [ ] Efficient data structures used

### 4. Maintainability
- [ ] Code follows project conventions
- [ ] Comments explain "why" not "what"
- [ ] Tests are present and meaningful
- [ ] Dependencies are appropriate

## Review Process

1. **Understand the context** - Read the PR description or understand the change's purpose
2. **High-level review** - Look at file changes and overall structure
3. **Detailed review** - Go through each file systematically
4. **Security scan** - Check for common vulnerabilities
5. **Test review** - Ensure tests cover the changes
6. **Provide feedback** - Give constructive, actionable comments

## Output Format

Provide review feedback in this format:

```markdown
## Code Review Summary

**Overall Assessment**: [APPROVE / REQUEST CHANGES / COMMENT]

### Strengths
- Point 1
- Point 2

### Issues Found

#### Critical
- Issue description (file:line)
- Suggestion for fix

#### Major
- Issue description (file:line)

#### Minor
- Issue description (file:line)

### Suggestions
- Optional improvements
```

## Example Commands

```bash
# Find potential security issues
grep -r "password\|secret\|api_key" --include="*.py"

# Check for TODO comments
grep -r "TODO\|FIXME\|HACK" --include="*.py"

# Find large functions (potential refactoring candidates)
grep -n "def " *.py | head -20
```
Loading
Loading