code-puppy 0.0.214__py3-none-any.whl ā 0.0.366__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.
- code_puppy/__init__.py +7 -1
- code_puppy/agents/__init__.py +2 -0
- code_puppy/agents/agent_c_reviewer.py +59 -6
- code_puppy/agents/agent_code_puppy.py +7 -1
- code_puppy/agents/agent_code_reviewer.py +12 -2
- code_puppy/agents/agent_cpp_reviewer.py +73 -6
- code_puppy/agents/agent_creator_agent.py +45 -4
- code_puppy/agents/agent_golang_reviewer.py +92 -3
- code_puppy/agents/agent_javascript_reviewer.py +101 -8
- code_puppy/agents/agent_manager.py +81 -4
- code_puppy/agents/agent_pack_leader.py +383 -0
- code_puppy/agents/agent_planning.py +163 -0
- code_puppy/agents/agent_python_programmer.py +165 -0
- code_puppy/agents/agent_python_reviewer.py +28 -6
- code_puppy/agents/agent_qa_expert.py +98 -6
- code_puppy/agents/agent_qa_kitten.py +12 -7
- code_puppy/agents/agent_security_auditor.py +113 -3
- code_puppy/agents/agent_terminal_qa.py +323 -0
- code_puppy/agents/agent_typescript_reviewer.py +106 -7
- code_puppy/agents/base_agent.py +802 -176
- code_puppy/agents/event_stream_handler.py +350 -0
- code_puppy/agents/pack/__init__.py +34 -0
- code_puppy/agents/pack/bloodhound.py +304 -0
- code_puppy/agents/pack/husky.py +321 -0
- code_puppy/agents/pack/retriever.py +393 -0
- code_puppy/agents/pack/shepherd.py +348 -0
- code_puppy/agents/pack/terrier.py +287 -0
- code_puppy/agents/pack/watchdog.py +367 -0
- code_puppy/agents/prompt_reviewer.py +145 -0
- code_puppy/agents/subagent_stream_handler.py +276 -0
- code_puppy/api/__init__.py +13 -0
- code_puppy/api/app.py +169 -0
- code_puppy/api/main.py +21 -0
- code_puppy/api/pty_manager.py +446 -0
- code_puppy/api/routers/__init__.py +12 -0
- code_puppy/api/routers/agents.py +36 -0
- code_puppy/api/routers/commands.py +217 -0
- code_puppy/api/routers/config.py +74 -0
- code_puppy/api/routers/sessions.py +232 -0
- code_puppy/api/templates/terminal.html +361 -0
- code_puppy/api/websocket.py +154 -0
- code_puppy/callbacks.py +142 -4
- code_puppy/chatgpt_codex_client.py +283 -0
- code_puppy/claude_cache_client.py +586 -0
- code_puppy/cli_runner.py +916 -0
- code_puppy/command_line/add_model_menu.py +1079 -0
- code_puppy/command_line/agent_menu.py +395 -0
- code_puppy/command_line/attachments.py +10 -5
- code_puppy/command_line/autosave_menu.py +605 -0
- code_puppy/command_line/clipboard.py +527 -0
- code_puppy/command_line/colors_menu.py +520 -0
- code_puppy/command_line/command_handler.py +176 -738
- code_puppy/command_line/command_registry.py +150 -0
- code_puppy/command_line/config_commands.py +715 -0
- code_puppy/command_line/core_commands.py +792 -0
- code_puppy/command_line/diff_menu.py +863 -0
- code_puppy/command_line/load_context_completion.py +15 -22
- code_puppy/command_line/mcp/base.py +0 -3
- code_puppy/command_line/mcp/catalog_server_installer.py +175 -0
- code_puppy/command_line/mcp/custom_server_form.py +688 -0
- code_puppy/command_line/mcp/custom_server_installer.py +195 -0
- code_puppy/command_line/mcp/edit_command.py +148 -0
- code_puppy/command_line/mcp/handler.py +9 -4
- code_puppy/command_line/mcp/help_command.py +6 -5
- code_puppy/command_line/mcp/install_command.py +15 -26
- code_puppy/command_line/mcp/install_menu.py +685 -0
- code_puppy/command_line/mcp/list_command.py +2 -2
- code_puppy/command_line/mcp/logs_command.py +174 -65
- code_puppy/command_line/mcp/remove_command.py +2 -2
- code_puppy/command_line/mcp/restart_command.py +12 -4
- code_puppy/command_line/mcp/search_command.py +16 -10
- code_puppy/command_line/mcp/start_all_command.py +18 -6
- code_puppy/command_line/mcp/start_command.py +47 -25
- code_puppy/command_line/mcp/status_command.py +4 -5
- code_puppy/command_line/mcp/stop_all_command.py +7 -1
- code_puppy/command_line/mcp/stop_command.py +8 -4
- code_puppy/command_line/mcp/test_command.py +2 -2
- code_puppy/command_line/mcp/wizard_utils.py +20 -16
- code_puppy/command_line/mcp_completion.py +174 -0
- code_puppy/command_line/model_picker_completion.py +75 -25
- code_puppy/command_line/model_settings_menu.py +884 -0
- code_puppy/command_line/motd.py +14 -8
- code_puppy/command_line/onboarding_slides.py +179 -0
- code_puppy/command_line/onboarding_wizard.py +340 -0
- code_puppy/command_line/pin_command_completion.py +329 -0
- code_puppy/command_line/prompt_toolkit_completion.py +463 -63
- code_puppy/command_line/session_commands.py +296 -0
- code_puppy/command_line/utils.py +54 -0
- code_puppy/config.py +898 -112
- code_puppy/error_logging.py +118 -0
- code_puppy/gemini_code_assist.py +385 -0
- code_puppy/gemini_model.py +602 -0
- code_puppy/http_utils.py +210 -148
- code_puppy/keymap.py +128 -0
- code_puppy/main.py +5 -698
- code_puppy/mcp_/__init__.py +17 -0
- code_puppy/mcp_/async_lifecycle.py +35 -4
- code_puppy/mcp_/blocking_startup.py +70 -43
- code_puppy/mcp_/captured_stdio_server.py +2 -2
- code_puppy/mcp_/config_wizard.py +4 -4
- code_puppy/mcp_/dashboard.py +15 -6
- code_puppy/mcp_/managed_server.py +65 -38
- code_puppy/mcp_/manager.py +146 -52
- code_puppy/mcp_/mcp_logs.py +224 -0
- code_puppy/mcp_/registry.py +6 -6
- code_puppy/mcp_/server_registry_catalog.py +24 -5
- code_puppy/messaging/__init__.py +199 -2
- code_puppy/messaging/bus.py +610 -0
- code_puppy/messaging/commands.py +167 -0
- code_puppy/messaging/markdown_patches.py +57 -0
- code_puppy/messaging/message_queue.py +17 -48
- code_puppy/messaging/messages.py +500 -0
- code_puppy/messaging/queue_console.py +1 -24
- code_puppy/messaging/renderers.py +43 -146
- code_puppy/messaging/rich_renderer.py +1027 -0
- code_puppy/messaging/spinner/__init__.py +21 -5
- code_puppy/messaging/spinner/console_spinner.py +86 -51
- code_puppy/messaging/subagent_console.py +461 -0
- code_puppy/model_factory.py +634 -83
- code_puppy/model_utils.py +167 -0
- code_puppy/models.json +66 -68
- code_puppy/models_dev_api.json +1 -0
- code_puppy/models_dev_parser.py +592 -0
- code_puppy/plugins/__init__.py +164 -10
- code_puppy/plugins/antigravity_oauth/__init__.py +10 -0
- code_puppy/plugins/antigravity_oauth/accounts.py +406 -0
- code_puppy/plugins/antigravity_oauth/antigravity_model.py +704 -0
- code_puppy/plugins/antigravity_oauth/config.py +42 -0
- code_puppy/plugins/antigravity_oauth/constants.py +136 -0
- code_puppy/plugins/antigravity_oauth/oauth.py +478 -0
- code_puppy/plugins/antigravity_oauth/register_callbacks.py +406 -0
- code_puppy/plugins/antigravity_oauth/storage.py +271 -0
- code_puppy/plugins/antigravity_oauth/test_plugin.py +319 -0
- code_puppy/plugins/antigravity_oauth/token.py +167 -0
- code_puppy/plugins/antigravity_oauth/transport.py +767 -0
- code_puppy/plugins/antigravity_oauth/utils.py +169 -0
- code_puppy/plugins/chatgpt_oauth/__init__.py +8 -0
- code_puppy/plugins/chatgpt_oauth/config.py +52 -0
- code_puppy/plugins/chatgpt_oauth/oauth_flow.py +328 -0
- code_puppy/plugins/chatgpt_oauth/register_callbacks.py +94 -0
- code_puppy/plugins/chatgpt_oauth/test_plugin.py +293 -0
- code_puppy/plugins/chatgpt_oauth/utils.py +489 -0
- code_puppy/plugins/claude_code_oauth/README.md +167 -0
- code_puppy/plugins/claude_code_oauth/SETUP.md +93 -0
- code_puppy/plugins/claude_code_oauth/__init__.py +6 -0
- code_puppy/plugins/claude_code_oauth/config.py +50 -0
- code_puppy/plugins/claude_code_oauth/register_callbacks.py +308 -0
- code_puppy/plugins/claude_code_oauth/test_plugin.py +283 -0
- code_puppy/plugins/claude_code_oauth/utils.py +518 -0
- code_puppy/plugins/customizable_commands/__init__.py +0 -0
- code_puppy/plugins/customizable_commands/register_callbacks.py +169 -0
- code_puppy/plugins/example_custom_command/README.md +280 -0
- code_puppy/plugins/example_custom_command/register_callbacks.py +2 -2
- code_puppy/plugins/file_permission_handler/__init__.py +4 -0
- code_puppy/plugins/file_permission_handler/register_callbacks.py +523 -0
- code_puppy/plugins/frontend_emitter/__init__.py +25 -0
- code_puppy/plugins/frontend_emitter/emitter.py +121 -0
- code_puppy/plugins/frontend_emitter/register_callbacks.py +261 -0
- code_puppy/plugins/oauth_puppy_html.py +228 -0
- code_puppy/plugins/shell_safety/__init__.py +6 -0
- code_puppy/plugins/shell_safety/agent_shell_safety.py +69 -0
- code_puppy/plugins/shell_safety/command_cache.py +156 -0
- code_puppy/plugins/shell_safety/register_callbacks.py +202 -0
- code_puppy/prompts/antigravity_system_prompt.md +1 -0
- code_puppy/prompts/codex_system_prompt.md +310 -0
- code_puppy/pydantic_patches.py +131 -0
- code_puppy/reopenable_async_client.py +8 -8
- code_puppy/round_robin_model.py +9 -12
- code_puppy/session_storage.py +2 -1
- code_puppy/status_display.py +21 -4
- code_puppy/summarization_agent.py +41 -13
- code_puppy/terminal_utils.py +418 -0
- code_puppy/tools/__init__.py +37 -1
- code_puppy/tools/agent_tools.py +536 -52
- code_puppy/tools/browser/__init__.py +37 -0
- code_puppy/tools/browser/browser_control.py +19 -23
- code_puppy/tools/browser/browser_interactions.py +41 -48
- code_puppy/tools/browser/browser_locators.py +36 -38
- code_puppy/tools/browser/browser_manager.py +316 -0
- code_puppy/tools/browser/browser_navigation.py +16 -16
- code_puppy/tools/browser/browser_screenshot.py +79 -143
- code_puppy/tools/browser/browser_scripts.py +32 -42
- code_puppy/tools/browser/browser_workflows.py +44 -27
- code_puppy/tools/browser/chromium_terminal_manager.py +259 -0
- code_puppy/tools/browser/terminal_command_tools.py +521 -0
- code_puppy/tools/browser/terminal_screenshot_tools.py +556 -0
- code_puppy/tools/browser/terminal_tools.py +525 -0
- code_puppy/tools/command_runner.py +930 -147
- code_puppy/tools/common.py +1113 -5
- code_puppy/tools/display.py +84 -0
- code_puppy/tools/file_modifications.py +288 -89
- code_puppy/tools/file_operations.py +226 -154
- code_puppy/tools/subagent_context.py +158 -0
- code_puppy/uvx_detection.py +242 -0
- code_puppy/version_checker.py +30 -11
- code_puppy-0.0.366.data/data/code_puppy/models.json +110 -0
- code_puppy-0.0.366.data/data/code_puppy/models_dev_api.json +1 -0
- {code_puppy-0.0.214.dist-info ā code_puppy-0.0.366.dist-info}/METADATA +149 -75
- code_puppy-0.0.366.dist-info/RECORD +217 -0
- {code_puppy-0.0.214.dist-info ā code_puppy-0.0.366.dist-info}/WHEEL +1 -1
- code_puppy/command_line/mcp/add_command.py +0 -183
- code_puppy/messaging/spinner/textual_spinner.py +0 -106
- code_puppy/tools/browser/camoufox_manager.py +0 -216
- code_puppy/tools/browser/vqa_agent.py +0 -70
- code_puppy/tui/__init__.py +0 -10
- code_puppy/tui/app.py +0 -1105
- code_puppy/tui/components/__init__.py +0 -21
- code_puppy/tui/components/chat_view.py +0 -551
- code_puppy/tui/components/command_history_modal.py +0 -218
- code_puppy/tui/components/copy_button.py +0 -139
- code_puppy/tui/components/custom_widgets.py +0 -63
- code_puppy/tui/components/human_input_modal.py +0 -175
- code_puppy/tui/components/input_area.py +0 -167
- code_puppy/tui/components/sidebar.py +0 -309
- code_puppy/tui/components/status_bar.py +0 -185
- code_puppy/tui/messages.py +0 -27
- code_puppy/tui/models/__init__.py +0 -8
- code_puppy/tui/models/chat_message.py +0 -25
- code_puppy/tui/models/command_history.py +0 -89
- code_puppy/tui/models/enums.py +0 -24
- code_puppy/tui/screens/__init__.py +0 -17
- code_puppy/tui/screens/autosave_picker.py +0 -175
- code_puppy/tui/screens/help.py +0 -130
- code_puppy/tui/screens/mcp_install_wizard.py +0 -803
- code_puppy/tui/screens/settings.py +0 -306
- code_puppy/tui/screens/tools.py +0 -74
- code_puppy/tui_state.py +0 -55
- code_puppy-0.0.214.data/data/code_puppy/models.json +0 -112
- code_puppy-0.0.214.dist-info/RECORD +0 -131
- {code_puppy-0.0.214.dist-info ā code_puppy-0.0.366.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.214.dist-info ā code_puppy-0.0.366.dist-info}/licenses/LICENSE +0 -0
|
@@ -10,36 +10,29 @@ class LoadContextCompleter(Completer):
|
|
|
10
10
|
self.trigger = trigger
|
|
11
11
|
|
|
12
12
|
def get_completions(self, document, complete_event):
|
|
13
|
+
cursor_position = document.cursor_position
|
|
13
14
|
text_before_cursor = document.text_before_cursor
|
|
14
15
|
stripped_text_for_trigger_check = text_before_cursor.lstrip()
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# Determine the part of the text that is relevant for this completer
|
|
20
|
-
actual_trigger_pos = text_before_cursor.find(self.trigger)
|
|
21
|
-
effective_input = text_before_cursor[actual_trigger_pos:]
|
|
22
|
-
|
|
23
|
-
tokens = effective_input.split()
|
|
24
|
-
|
|
25
|
-
# Case 1: Input is exactly the trigger (e.g., "/load_context") and nothing more
|
|
26
|
-
if (
|
|
27
|
-
len(tokens) == 1
|
|
28
|
-
and tokens[0] == self.trigger
|
|
29
|
-
and not effective_input.endswith(" ")
|
|
30
|
-
):
|
|
17
|
+
# If user types just /load_context (no space), suggest adding a space
|
|
18
|
+
if stripped_text_for_trigger_check == self.trigger:
|
|
31
19
|
yield Completion(
|
|
32
|
-
|
|
33
|
-
start_position=-len(
|
|
20
|
+
self.trigger + " ",
|
|
21
|
+
start_position=-len(self.trigger),
|
|
34
22
|
display=self.trigger + " ",
|
|
35
23
|
display_meta="load saved context",
|
|
36
24
|
)
|
|
37
25
|
return
|
|
38
26
|
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
# Require a space after /load_context before showing completions (consistency with other completers)
|
|
28
|
+
if not stripped_text_for_trigger_check.startswith(self.trigger + " "):
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
# Extract the session name after /load_context and space (up to cursor)
|
|
32
|
+
actual_trigger_pos = text_before_cursor.find(self.trigger)
|
|
33
|
+
trigger_end = actual_trigger_pos + len(self.trigger) + 1 # +1 for the space
|
|
34
|
+
session_filter = text_before_cursor[trigger_end:cursor_position].lstrip()
|
|
35
|
+
start_position = -(len(session_filter))
|
|
43
36
|
|
|
44
37
|
# Get available context files
|
|
45
38
|
try:
|
|
@@ -50,7 +43,7 @@ class LoadContextCompleter(Completer):
|
|
|
50
43
|
if session_name.startswith(session_filter):
|
|
51
44
|
yield Completion(
|
|
52
45
|
session_name,
|
|
53
|
-
start_position
|
|
46
|
+
start_position=start_position,
|
|
54
47
|
display=session_name,
|
|
55
48
|
display_meta="saved context session",
|
|
56
49
|
)
|
|
@@ -6,8 +6,6 @@ Provides base classes and common utilities used across all MCP command modules.
|
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
8
|
|
|
9
|
-
from rich.console import Console
|
|
10
|
-
|
|
11
9
|
from code_puppy.mcp_.manager import get_mcp_manager
|
|
12
10
|
|
|
13
11
|
# Configure logging
|
|
@@ -24,7 +22,6 @@ class MCPCommandBase:
|
|
|
24
22
|
|
|
25
23
|
def __init__(self):
|
|
26
24
|
"""Initialize the base command handler."""
|
|
27
|
-
self.console = Console()
|
|
28
25
|
self.manager = get_mcp_manager()
|
|
29
26
|
logger.debug(f"Initialized {self.__class__.__name__}")
|
|
30
27
|
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""Catalog MCP server installation logic.
|
|
2
|
+
|
|
3
|
+
Handles prompting users for configuration and installing
|
|
4
|
+
MCP servers from the catalog.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from typing import Dict, Optional
|
|
9
|
+
|
|
10
|
+
from code_puppy.command_line.utils import safe_input
|
|
11
|
+
from code_puppy.messaging import emit_info, emit_success, emit_warning
|
|
12
|
+
|
|
13
|
+
# Helpful hints for common environment variables
|
|
14
|
+
ENV_VAR_HINTS = {
|
|
15
|
+
"GITHUB_TOKEN": "š” Get from https://github.com/settings/tokens",
|
|
16
|
+
"GITLAB_TOKEN": "š” Get from GitLab > Preferences > Access Tokens",
|
|
17
|
+
"SLACK_TOKEN": "š” Get from https://api.slack.com/apps",
|
|
18
|
+
"DISCORD_TOKEN": "š” Get from Discord Developer Portal",
|
|
19
|
+
"OPENAI_API_KEY": "š” Get from https://platform.openai.com/api-keys",
|
|
20
|
+
"ANTHROPIC_API_KEY": "š” Get from https://console.anthropic.com/",
|
|
21
|
+
"GOOGLE_CLIENT_ID": "š” Get from Google Cloud Console",
|
|
22
|
+
"GOOGLE_CLIENT_SECRET": "š” Get from Google Cloud Console",
|
|
23
|
+
"NOTION_TOKEN": "š” Get from https://www.notion.so/my-integrations",
|
|
24
|
+
"CONFLUENCE_TOKEN": "š” Get from Atlassian API tokens",
|
|
25
|
+
"JIRA_TOKEN": "š” Get from Atlassian API tokens",
|
|
26
|
+
"GRAFANA_TOKEN": "š” Get from Grafana > Configuration > API Keys",
|
|
27
|
+
"DATABASE_URL": "š” Format: postgresql://user:pass@host:5432/db",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_env_var_hint(env_var: str) -> str:
|
|
32
|
+
"""Get a helpful hint for common environment variables."""
|
|
33
|
+
return ENV_VAR_HINTS.get(env_var, "")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def prompt_for_server_config(manager, server) -> Optional[Dict]:
|
|
37
|
+
"""Prompt user for server configuration (env vars and cmd args).
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
manager: MCP manager instance
|
|
41
|
+
server: Server template from catalog
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Dict with 'name', 'env_vars', 'cmd_args' if successful, None if cancelled
|
|
45
|
+
"""
|
|
46
|
+
from code_puppy.config import set_config_value
|
|
47
|
+
|
|
48
|
+
from .utils import find_server_id_by_name
|
|
49
|
+
|
|
50
|
+
emit_info(f"\nš¦ Installing: {server.display_name}\n")
|
|
51
|
+
emit_info(f" {server.description}\n")
|
|
52
|
+
|
|
53
|
+
# Get custom name
|
|
54
|
+
default_name = server.name
|
|
55
|
+
try:
|
|
56
|
+
name_input = safe_input(f" Server name [{default_name}]: ")
|
|
57
|
+
server_name = name_input if name_input else default_name
|
|
58
|
+
except (KeyboardInterrupt, EOFError):
|
|
59
|
+
emit_info("")
|
|
60
|
+
emit_warning("Installation cancelled")
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
# Check if server already exists
|
|
64
|
+
existing = find_server_id_by_name(manager, server_name)
|
|
65
|
+
if existing:
|
|
66
|
+
try:
|
|
67
|
+
override = safe_input(f" Server '{server_name}' exists. Override? [y/N]: ")
|
|
68
|
+
if not override.lower().startswith("y"):
|
|
69
|
+
emit_warning("Installation cancelled")
|
|
70
|
+
return None
|
|
71
|
+
except (KeyboardInterrupt, EOFError):
|
|
72
|
+
emit_info("")
|
|
73
|
+
emit_warning("Installation cancelled")
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
env_vars = {}
|
|
77
|
+
cmd_args = {}
|
|
78
|
+
|
|
79
|
+
# Collect environment variables
|
|
80
|
+
required_env_vars = server.get_environment_vars()
|
|
81
|
+
if required_env_vars:
|
|
82
|
+
emit_info("\n š Environment Variables:")
|
|
83
|
+
for var in required_env_vars:
|
|
84
|
+
current_value = os.environ.get(var, "")
|
|
85
|
+
if current_value:
|
|
86
|
+
emit_info(f" ā {var}: Already set")
|
|
87
|
+
env_vars[var] = current_value
|
|
88
|
+
else:
|
|
89
|
+
try:
|
|
90
|
+
hint = get_env_var_hint(var)
|
|
91
|
+
if hint:
|
|
92
|
+
emit_info(f" {hint}")
|
|
93
|
+
value = safe_input(f" Enter {var}: ")
|
|
94
|
+
if value:
|
|
95
|
+
env_vars[var] = value
|
|
96
|
+
# Save to config for future use
|
|
97
|
+
set_config_value(var, value)
|
|
98
|
+
os.environ[var] = value
|
|
99
|
+
except (KeyboardInterrupt, EOFError):
|
|
100
|
+
emit_info("")
|
|
101
|
+
emit_warning("Installation cancelled")
|
|
102
|
+
return None
|
|
103
|
+
|
|
104
|
+
# Collect command line arguments
|
|
105
|
+
required_cmd_args = server.get_command_line_args()
|
|
106
|
+
if required_cmd_args:
|
|
107
|
+
emit_info("\n āļø Configuration:")
|
|
108
|
+
for arg_config in required_cmd_args:
|
|
109
|
+
name = arg_config.get("name", "")
|
|
110
|
+
prompt_text = arg_config.get("prompt", name)
|
|
111
|
+
default = arg_config.get("default", "")
|
|
112
|
+
required = arg_config.get("required", True)
|
|
113
|
+
|
|
114
|
+
prompt_str = f" {prompt_text}"
|
|
115
|
+
if default:
|
|
116
|
+
prompt_str += f" [{default}]"
|
|
117
|
+
if not required:
|
|
118
|
+
prompt_str += " (optional)"
|
|
119
|
+
|
|
120
|
+
try:
|
|
121
|
+
value = safe_input(f"{prompt_str}: ")
|
|
122
|
+
if value:
|
|
123
|
+
cmd_args[name] = value
|
|
124
|
+
elif default:
|
|
125
|
+
cmd_args[name] = default
|
|
126
|
+
elif required:
|
|
127
|
+
emit_warning(f"Required value '{name}' not provided")
|
|
128
|
+
return None
|
|
129
|
+
except (KeyboardInterrupt, EOFError):
|
|
130
|
+
emit_info("")
|
|
131
|
+
emit_warning("Installation cancelled")
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
"name": server_name,
|
|
136
|
+
"env_vars": env_vars,
|
|
137
|
+
"cmd_args": cmd_args,
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def install_catalog_server(manager, server, config: Dict) -> bool:
|
|
142
|
+
"""Install a server from the catalog with the given configuration.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
manager: MCP manager instance
|
|
146
|
+
server: Server template from catalog
|
|
147
|
+
config: Configuration dict with 'name', 'env_vars', 'cmd_args'
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
True if successful, False otherwise
|
|
151
|
+
"""
|
|
152
|
+
import uuid
|
|
153
|
+
|
|
154
|
+
from .wizard_utils import install_server_from_catalog
|
|
155
|
+
|
|
156
|
+
server_name = config["name"]
|
|
157
|
+
env_vars = config["env_vars"]
|
|
158
|
+
cmd_args = config["cmd_args"]
|
|
159
|
+
|
|
160
|
+
# Generate a group ID for messages
|
|
161
|
+
group_id = f"mcp-install-{uuid.uuid4().hex[:8]}"
|
|
162
|
+
|
|
163
|
+
emit_info(f"\n š¦ Installing {server.display_name} as '{server_name}'...")
|
|
164
|
+
|
|
165
|
+
success = install_server_from_catalog(
|
|
166
|
+
manager, server, server_name, env_vars, cmd_args, group_id
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
if success:
|
|
170
|
+
emit_success(f"\n ā
Successfully installed '{server_name}'!")
|
|
171
|
+
emit_info(f" Use '/mcp start {server_name}' to start the server.\n")
|
|
172
|
+
else:
|
|
173
|
+
emit_warning("\n ā Installation failed.\n")
|
|
174
|
+
|
|
175
|
+
return success
|