hanzo-mcp 0.6.12__py3-none-any.whl → 0.6.13__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.
Potentially problematic release.
This version of hanzo-mcp might be problematic. Click here for more details.
- hanzo_mcp/__init__.py +2 -2
- hanzo_mcp/cli.py +2 -2
- hanzo_mcp/cli_enhanced.py +4 -4
- hanzo_mcp/cli_plugin.py +91 -0
- hanzo_mcp/config/__init__.py +1 -1
- hanzo_mcp/config/settings.py +69 -6
- hanzo_mcp/config/tool_config.py +2 -2
- hanzo_mcp/dev_server.py +3 -3
- hanzo_mcp/prompts/project_system.py +1 -1
- hanzo_mcp/server.py +6 -2
- hanzo_mcp/server_enhanced.py +69 -0
- hanzo_mcp/tools/__init__.py +75 -29
- hanzo_mcp/tools/agent/__init__.py +1 -1
- hanzo_mcp/tools/agent/agent_tool.py +2 -2
- hanzo_mcp/tools/common/__init__.py +15 -1
- hanzo_mcp/tools/common/base.py +4 -4
- hanzo_mcp/tools/common/batch_tool.py +1 -1
- hanzo_mcp/tools/common/config_tool.py +2 -2
- hanzo_mcp/tools/common/context.py +2 -2
- hanzo_mcp/tools/common/context_fix.py +26 -0
- hanzo_mcp/tools/common/critic_tool.py +196 -0
- hanzo_mcp/tools/common/decorators.py +208 -0
- hanzo_mcp/tools/common/enhanced_base.py +106 -0
- hanzo_mcp/tools/common/mode.py +116 -0
- hanzo_mcp/tools/common/mode_loader.py +105 -0
- hanzo_mcp/tools/common/permissions.py +1 -1
- hanzo_mcp/tools/common/personality.py +936 -0
- hanzo_mcp/tools/common/plugin_loader.py +287 -0
- hanzo_mcp/tools/common/stats.py +4 -4
- hanzo_mcp/tools/common/tool_list.py +1 -1
- hanzo_mcp/tools/common/validation.py +1 -1
- hanzo_mcp/tools/config/__init__.py +3 -1
- hanzo_mcp/tools/config/config_tool.py +1 -1
- hanzo_mcp/tools/config/mode_tool.py +209 -0
- hanzo_mcp/tools/database/__init__.py +1 -1
- hanzo_mcp/tools/editor/__init__.py +1 -1
- hanzo_mcp/tools/filesystem/__init__.py +19 -14
- hanzo_mcp/tools/filesystem/batch_search.py +3 -3
- hanzo_mcp/tools/filesystem/diff.py +2 -2
- hanzo_mcp/tools/filesystem/rules_tool.py +235 -0
- hanzo_mcp/tools/filesystem/{unified_search.py → search_tool.py} +12 -12
- hanzo_mcp/tools/filesystem/{symbols_unified.py → symbols_tool.py} +104 -5
- hanzo_mcp/tools/filesystem/watch.py +3 -2
- hanzo_mcp/tools/jupyter/__init__.py +2 -2
- hanzo_mcp/tools/jupyter/jupyter.py +1 -1
- hanzo_mcp/tools/llm/__init__.py +3 -3
- hanzo_mcp/tools/llm/llm_tool.py +648 -143
- hanzo_mcp/tools/mcp/__init__.py +2 -2
- hanzo_mcp/tools/mcp/{mcp_unified.py → mcp_tool.py} +3 -3
- hanzo_mcp/tools/shell/__init__.py +6 -6
- hanzo_mcp/tools/shell/base_process.py +4 -2
- hanzo_mcp/tools/shell/bash_session_executor.py +1 -1
- hanzo_mcp/tools/shell/{bash_unified.py → bash_tool.py} +1 -1
- hanzo_mcp/tools/shell/command_executor.py +2 -2
- hanzo_mcp/tools/shell/{npx_unified.py → npx_tool.py} +1 -1
- hanzo_mcp/tools/shell/open.py +2 -2
- hanzo_mcp/tools/shell/{process_unified.py → process_tool.py} +1 -1
- hanzo_mcp/tools/shell/run_command_windows.py +1 -1
- hanzo_mcp/tools/shell/uvx.py +47 -2
- hanzo_mcp/tools/shell/uvx_background.py +47 -2
- hanzo_mcp/tools/shell/{uvx_unified.py → uvx_tool.py} +1 -1
- hanzo_mcp/tools/todo/__init__.py +14 -19
- hanzo_mcp/tools/todo/todo.py +22 -1
- hanzo_mcp/tools/vector/__init__.py +1 -1
- hanzo_mcp/tools/vector/infinity_store.py +2 -2
- hanzo_mcp/tools/vector/project_manager.py +1 -1
- hanzo_mcp-0.6.13.dist-info/METADATA +359 -0
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/RECORD +72 -64
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/entry_points.txt +1 -0
- hanzo_mcp/tools/common/palette.py +0 -344
- hanzo_mcp/tools/common/palette_loader.py +0 -108
- hanzo_mcp/tools/config/palette_tool.py +0 -179
- hanzo_mcp/tools/llm/llm_unified.py +0 -851
- hanzo_mcp-0.6.12.dist-info/METADATA +0 -339
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/WHEEL +0 -0
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/licenses/LICENSE +0 -0
- {hanzo_mcp-0.6.12.dist-info → hanzo_mcp-0.6.13.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Mode system for organizing development tools based on programmer personalities."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Dict, List, Optional, Set
|
|
6
|
+
|
|
7
|
+
from hanzo_mcp.tools.common.personality import (
|
|
8
|
+
ToolPersonality,
|
|
9
|
+
register_default_personalities,
|
|
10
|
+
ensure_agent_enabled,
|
|
11
|
+
personalities
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class Mode(ToolPersonality):
|
|
17
|
+
"""Development mode combining tool preferences and environment settings."""
|
|
18
|
+
# Inherits all fields from ToolPersonality
|
|
19
|
+
# Adds mode-specific functionality
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def is_active(self) -> bool:
|
|
23
|
+
"""Check if this mode is currently active."""
|
|
24
|
+
return ModeRegistry.get_active() == self
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ModeRegistry:
|
|
28
|
+
"""Registry for development modes."""
|
|
29
|
+
|
|
30
|
+
_modes: Dict[str, Mode] = {}
|
|
31
|
+
_active_mode: Optional[str] = None
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def register(cls, mode: Mode) -> None:
|
|
35
|
+
"""Register a development mode."""
|
|
36
|
+
# Ensure agent is enabled if API keys present
|
|
37
|
+
mode = ensure_agent_enabled(mode)
|
|
38
|
+
cls._modes[mode.name] = mode
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def get(cls, name: str) -> Optional[Mode]:
|
|
42
|
+
"""Get a mode by name."""
|
|
43
|
+
return cls._modes.get(name)
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def list(cls) -> List[Mode]:
|
|
47
|
+
"""List all registered modes."""
|
|
48
|
+
return list(cls._modes.values())
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def set_active(cls, name: str) -> None:
|
|
52
|
+
"""Set the active mode."""
|
|
53
|
+
if name not in cls._modes:
|
|
54
|
+
raise ValueError(f"Mode '{name}' not found")
|
|
55
|
+
cls._active_mode = name
|
|
56
|
+
|
|
57
|
+
# Apply environment variables from the mode
|
|
58
|
+
mode = cls._modes[name]
|
|
59
|
+
if mode.environment:
|
|
60
|
+
for key, value in mode.environment.items():
|
|
61
|
+
os.environ[key] = value
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def get_active(cls) -> Optional[Mode]:
|
|
65
|
+
"""Get the active mode."""
|
|
66
|
+
if cls._active_mode:
|
|
67
|
+
return cls._modes.get(cls._active_mode)
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def get_active_tools(cls) -> Set[str]:
|
|
72
|
+
"""Get the set of tools from the active mode."""
|
|
73
|
+
mode = cls.get_active()
|
|
74
|
+
if mode:
|
|
75
|
+
return set(mode.tools)
|
|
76
|
+
return set()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def register_default_modes():
|
|
80
|
+
"""Register all default development modes."""
|
|
81
|
+
# Convert personalities to modes
|
|
82
|
+
for personality in personalities:
|
|
83
|
+
mode = Mode(
|
|
84
|
+
name=personality.name,
|
|
85
|
+
programmer=personality.programmer,
|
|
86
|
+
description=personality.description,
|
|
87
|
+
tools=personality.tools,
|
|
88
|
+
environment=personality.environment,
|
|
89
|
+
philosophy=personality.philosophy,
|
|
90
|
+
)
|
|
91
|
+
ModeRegistry.register(mode)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_mode_from_env() -> Optional[str]:
|
|
95
|
+
"""Get mode name from environment variables."""
|
|
96
|
+
# Check for HANZO_MODE, PERSONALITY, or MODE env vars
|
|
97
|
+
return (
|
|
98
|
+
os.environ.get("HANZO_MODE") or
|
|
99
|
+
os.environ.get("PERSONALITY") or
|
|
100
|
+
os.environ.get("MODE")
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def activate_mode_from_env():
|
|
105
|
+
"""Activate mode based on environment variables."""
|
|
106
|
+
mode_name = get_mode_from_env()
|
|
107
|
+
if mode_name:
|
|
108
|
+
try:
|
|
109
|
+
ModeRegistry.set_active(mode_name)
|
|
110
|
+
return True
|
|
111
|
+
except ValueError:
|
|
112
|
+
# Mode not found, ignore
|
|
113
|
+
pass
|
|
114
|
+
return False
|
|
115
|
+
|
|
116
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Tool mode loader for dynamic tool configuration."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Dict, List, Optional, Set
|
|
5
|
+
|
|
6
|
+
from hanzo_mcp.tools.common.mode import ModeRegistry, register_default_modes, activate_mode_from_env
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ModeLoader:
|
|
10
|
+
"""Loads and manages tool modes for dynamic configuration."""
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def initialize_modes() -> None:
|
|
14
|
+
"""Initialize the mode system with defaults."""
|
|
15
|
+
# Initialize modes
|
|
16
|
+
register_default_modes()
|
|
17
|
+
|
|
18
|
+
# Check for mode from environment
|
|
19
|
+
activate_mode_from_env()
|
|
20
|
+
|
|
21
|
+
# If no mode set, use default
|
|
22
|
+
if not ModeRegistry.get_active():
|
|
23
|
+
default_mode = os.environ.get("HANZO_DEFAULT_MODE", "hanzo")
|
|
24
|
+
if ModeRegistry.get(default_mode):
|
|
25
|
+
ModeRegistry.set_active(default_mode)
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def get_enabled_tools_from_mode(
|
|
29
|
+
base_enabled_tools: Optional[Dict[str, bool]] = None,
|
|
30
|
+
force_mode: Optional[str] = None
|
|
31
|
+
) -> Dict[str, bool]:
|
|
32
|
+
"""Get enabled tools configuration from active mode.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
base_enabled_tools: Base configuration to merge with
|
|
36
|
+
force_mode: Force a specific mode (overrides active)
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Dictionary of tool enable states
|
|
40
|
+
"""
|
|
41
|
+
# Initialize if needed
|
|
42
|
+
if not ModeRegistry.list():
|
|
43
|
+
ModeLoader.initialize_modes()
|
|
44
|
+
|
|
45
|
+
# Get mode to use
|
|
46
|
+
tools_list = None
|
|
47
|
+
|
|
48
|
+
if force_mode:
|
|
49
|
+
# Set and get mode
|
|
50
|
+
if ModeRegistry.get(force_mode):
|
|
51
|
+
ModeRegistry.set_active(force_mode)
|
|
52
|
+
mode = ModeRegistry.get_active()
|
|
53
|
+
tools_list = mode.tools if mode else None
|
|
54
|
+
else:
|
|
55
|
+
# Check active mode
|
|
56
|
+
mode = ModeRegistry.get_active()
|
|
57
|
+
if mode:
|
|
58
|
+
tools_list = mode.tools
|
|
59
|
+
|
|
60
|
+
if not tools_list:
|
|
61
|
+
# No active mode, return base config
|
|
62
|
+
return base_enabled_tools or {}
|
|
63
|
+
|
|
64
|
+
# Start with base configuration
|
|
65
|
+
result = base_enabled_tools.copy() if base_enabled_tools else {}
|
|
66
|
+
|
|
67
|
+
# Get all possible tools from registry
|
|
68
|
+
from hanzo_mcp.config.tool_config import TOOL_REGISTRY
|
|
69
|
+
all_possible_tools = set(TOOL_REGISTRY.keys())
|
|
70
|
+
|
|
71
|
+
# Disable all tools first (clean slate for mode)
|
|
72
|
+
for tool in all_possible_tools:
|
|
73
|
+
result[tool] = False
|
|
74
|
+
|
|
75
|
+
# Enable tools from mode
|
|
76
|
+
for tool in tools_list:
|
|
77
|
+
result[tool] = True
|
|
78
|
+
|
|
79
|
+
# Always enable mode tool (meta)
|
|
80
|
+
result["mode"] = True
|
|
81
|
+
|
|
82
|
+
return result
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def get_environment_from_mode() -> Dict[str, str]:
|
|
86
|
+
"""Get environment variables from active mode.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Dictionary of environment variables
|
|
90
|
+
"""
|
|
91
|
+
# Check mode
|
|
92
|
+
mode = ModeRegistry.get_active()
|
|
93
|
+
if mode and mode.environment:
|
|
94
|
+
return mode.environment.copy()
|
|
95
|
+
|
|
96
|
+
return {}
|
|
97
|
+
|
|
98
|
+
@staticmethod
|
|
99
|
+
def apply_environment_from_mode() -> None:
|
|
100
|
+
"""Apply environment variables from active mode."""
|
|
101
|
+
env_vars = ModeLoader.get_environment_from_mode()
|
|
102
|
+
for key, value in env_vars.items():
|
|
103
|
+
os.environ[key] = value
|
|
104
|
+
|
|
105
|
+
|