Coverage for src / osiris_cli / command_palette.py: 0%
50 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-27 17:41 +0200
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-27 17:41 +0200
1#!/usr/bin/env python3
2"""
3Enhanced Command Palette for Osiris CLI v4.0
4Beautiful, automatic, interactive menu system
5"""
7import questionary
8from questionary import Style
9from rich.console import Console
10from rich.table import Table
11from rich.panel import Panel
12from typing import Optional, List, Dict
14console = Console()
16# Custom style for the command palette
17PALETTE_STYLE = Style([
18 ('qmark', 'fg:#3b82f6 bold'),
19 ('question', 'bold'),
20 ('answer', 'fg:#10b981 bold'),
21 ('pointer', 'fg:#3b82f6 bold'),
22 ('highlighted', 'fg:#3b82f6 bold'),
23 ('selected', 'fg:#10b981'),
24 ('separator', 'fg:#6b7280'),
25 ('instruction', 'fg:#9ca3af'),
26 ('text', ''),
27 ('disabled', 'fg:#6b7280 italic')
28])
30# Command definitions with rich metadata
31COMMANDS = {
32 "Core": [
33 {"name": "/help", "desc": "Show complete command reference with examples", "icon": "📚"},
34 {"name": "/exit", "desc": "Exit Osiris CLI gracefully", "icon": "👋"},
35 ],
36 "Model & Provider": [
37 {"name": "/model", "desc": "Change AI model (gpt-4, claude-3.5, etc.)", "icon": "🤖"},
38 {"name": "/provider", "desc": "Switch AI provider (openai, anthropic, etc.)", "icon": "🔄"},
39 {"name": "/yolo", "desc": "Toggle autonomous mode (auto-approve all tools)", "icon": "⚡"},
40 ],
41 "Memory System": [
42 {"name": "/remember", "desc": "Add key:value to agent's long-term memory", "icon": "🧠"},
43 {"name": "/forget", "desc": "Remove a key from agent memory", "icon": "🗑️"},
44 {"name": "/memory", "desc": "Display all stored memories and skills", "icon": "💾"},
45 {"name": "/init", "desc": "Interactive wizard to initialize agent memory", "icon": "✨"},
46 {"name": "/skill", "desc": "Teach the agent a new capability or skill", "icon": "🎓"},
47 ],
48 "Session Management": [
49 {"name": "/session", "desc": "List and manage saved conversation sessions", "icon": "📂"},
50 {"name": "/clear", "desc": "Clear screen while keeping conversation history", "icon": "🧹"},
51 {"name": "/reset", "desc": "Reset conversation but preserve agent memory", "icon": "🔄"},
52 ],
53 "Context & Tools": [
54 {"name": "/context", "desc": "Show loaded OSIRIS.md context files", "icon": "📄"},
55 {"name": "/tools", "desc": "List all 13+ available tools and capabilities", "icon": "🛠️"},
56 ],
57 "Advanced Features": [
58 {"name": "/shadow", "desc": "Test mode - preview changes before applying", "icon": "👻"},
59 {"name": "/vim", "desc": "Toggle Vim-style keybindings (: prompt)", "icon": "⌨️"},
60 {"name": "/plan", "desc": "Request AI to create execution plan first", "icon": "📋"},
61 ],
62}
65async def show_command_palette() -> Optional[str]:
66 """
67 Display beautiful command palette and return selected command.
68 Returns None if cancelled.
69 """
70 # Build choices list with rich formatting
71 choices = []
73 for category, commands in COMMANDS.items():
74 # Add category separator
75 choices.append(questionary.Separator(f"\n═══ {category} ═══"))
77 # Add commands in this category
78 for cmd in commands:
79 icon = cmd.get("icon", "•")
80 name = cmd["name"]
81 desc = cmd["desc"]
82 # Format: "icon /command - description"
83 choice_text = f"{icon} {name:<12} │ {desc}"
84 choices.append(questionary.Choice(title=choice_text, value=name))
86 # Add cancel option
87 choices.append(questionary.Separator("\n───────────────────────────────────────"))
88 choices.append(questionary.Choice(title="❌ Cancel", value=None))
90 # Show the palette
91 try:
92 result = await questionary.select(
93 "Select a command:",
94 choices=choices,
95 style=PALETTE_STYLE,
96 use_shortcuts=True,
97 use_arrow_keys=True,
98 use_indicator=True,
99 instruction="(Use arrow keys, type to filter, Enter to select)",
100 ).ask_async()
102 return result
103 except (KeyboardInterrupt, EOFError):
104 return None
107def show_command_table():
108 """Display all commands in a beautiful table"""
109 table = Table(title="🎯 Osiris CLI Commands", show_header=True, header_style="bold cyan")
110 table.add_column("Command", style="cyan", width=15)
111 table.add_column("Description", style="white")
112 table.add_column("Category", style="magenta", width=20)
114 for category, commands in COMMANDS.items():
115 for cmd in commands:
116 icon = cmd.get("icon", "•")
117 table.add_row(
118 f"{icon} {cmd['name']}",
119 cmd['desc'],
120 category
121 )
123 console.print(table)
126def search_commands(query: str) -> List[Dict]:
127 """Search commands by name or description"""
128 query = query.lower()
129 results = []
131 for category, commands in COMMANDS.items():
132 for cmd in commands:
133 if query in cmd["name"].lower() or query in cmd["desc"].lower():
134 results.append({**cmd, "category": category})
136 return results
139if __name__ == "__main__":
140 # Test the palette
141 console.print("\n[bold cyan]Osiris Command Palette Demo[/bold cyan]\n")
143 selected = show_command_palette()
145 if selected:
146 console.print(f"\n[green]✓[/green] Selected: [bold]{selected}[/bold]\n")
147 else:
148 console.print("\n[yellow]Cancelled[/yellow]\n")