refactor: remove ambiguous shell tool, keep specific shells

- Remove ShellTool from TOOLS list (too ambiguous)
- Keep zsh, bash, fish, dash as specific shell tools
- Update get_shell_tools to include bash
- Fix test imports (ShellTool now in shell_tools.py)
- Update tests to expect cmd as primary tool
- Verify asyncio.gather + uvloop works correctly

hanzo-tools-shell: 0.5.1 → 0.5.2
This commit is contained in:
2026-01-04 13:27:34 -08:00
parent 35c8288217
commit 4fa44a28fc
6 changed files with 43 additions and 30 deletions
+1
View File
@@ -40,6 +40,7 @@ dependencies = [
"hanzo-tools-llm>=0.1.0",
"hanzo-tools-agent>=0.2.3",
"hanzo-persona>=1.0.0",
"uvloop>=0.22.1",
]
# For local development, install hanzo-tools-* packages from pkg/
+1 -2
View File
@@ -5,8 +5,7 @@ from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
from hanzo_tools.shell.zsh_tool import ShellTool
from hanzo_tools.shell.bash_tool import BashTool
from hanzo_tools.shell.shell_tools import ShellTool, BashTool
from hanzo_tools.shell.base_process import ProcessManager
from hanzo_tools.shell.process_tool import ProcessTool
from hanzo_mcp.tools.common.permissions import PermissionManager
+10 -11
View File
@@ -13,8 +13,7 @@ import pytest
# Add parent directory to path for imports
sys.path.insert(0, str(Path(__file__).parent.parent))
from hanzo_tools.shell.zsh_tool import ZshTool, ShellTool
from hanzo_tools.shell.bash_tool import BashTool
from hanzo_tools.shell.shell_tools import ZshTool, BashTool, ShellTool
class MockContext:
@@ -224,14 +223,14 @@ class TestShellIntegration:
pm = PermissionManager()
tools = get_shell_tools(pm)
# Should have our shell tools
# Should have our core tools
tool_names = [tool.name for tool in tools]
assert "bash" in tool_names
assert "cmd" in tool_names # Primary command execution
assert "zsh" in tool_names
assert "shell" in tool_names
assert "bash" in tool_names
# Shell should be first (preferred)
assert tools[0].name == "shell"
# cmd should be first (primary)
assert tools[0].name == "cmd"
def test_shell_tool_ordering(self):
"""Test that shell tools are returned in correct order."""
@@ -241,11 +240,11 @@ class TestShellIntegration:
pm = PermissionManager()
tools = get_shell_tools(pm)
# Find shell tools
shell_tools = [t for t in tools if t.name in ["shell", "zsh", "bash"]]
# Find shell-related tools
shell_tools = [t for t in tools if t.name in ["cmd", "zsh", "bash"]]
# Order should be: shell (smart), zsh, bash
assert shell_tools[0].name == "shell"
# Order should be: cmd (primary), zsh, bash
assert shell_tools[0].name == "cmd"
assert shell_tools[1].name == "zsh"
assert shell_tools[2].name == "bash"
+24 -12
View File
@@ -572,12 +572,24 @@ wheels = [
]
[[package]]
name = "hanzo-mcp"
version = "0.10.25"
source = { editable = "." }
name = "hanzo-async"
version = "0.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiofiles" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c0/50/98dce04e47d666b701fc8ed85037d4144cd802018be987579d512a2b5148/hanzo_async-0.1.0.tar.gz", hash = "sha256:b1223049a90b846cce8f3f763a61061f7a353acb981242d83f8476d516d793ba", size = 8452, upload-time = "2026-01-04T01:40:09.492Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/27/ae/b94352e57fadead2e6fd48acd60d5e0a1ab9a68b2acaa0a80c3277a31c63/hanzo_async-0.1.0-py3-none-any.whl", hash = "sha256:ecba8b338d2be6d84b339140d6f1802f5cb9ed75acadd997c0f6fd15dac2042c", size = 8452, upload-time = "2026-01-04T01:40:08.245Z" },
]
[[package]]
name = "hanzo-mcp"
version = "0.10.31"
source = { editable = "." }
dependencies = [
{ name = "fastmcp" },
{ name = "hanzo-async" },
{ name = "hanzo-persona" },
{ name = "hanzo-tools" },
{ name = "hanzo-tools-agent" },
@@ -596,6 +608,7 @@ dependencies = [
{ name = "pydantic" },
{ name = "pydantic-settings" },
{ name = "typing-extensions" },
{ name = "uvloop" },
]
[package.optional-dependencies]
@@ -618,7 +631,6 @@ docs = [
performance = [
{ name = "orjson" },
{ name = "ujson" },
{ name = "uvloop", marker = "sys_platform != 'win32'" },
]
publish = [
{ name = "build" },
@@ -633,10 +645,10 @@ test = [
[package.metadata]
requires-dist = [
{ name = "aiofiles", specifier = ">=23.2.1" },
{ name = "black", marker = "extra == 'dev'", specifier = ">=23.3.0" },
{ name = "build", marker = "extra == 'publish'", specifier = ">=1.0.3" },
{ name = "fastmcp", specifier = ">=2.14.1" },
{ name = "hanzo-async", specifier = ">=0.1.0" },
{ name = "hanzo-persona", specifier = ">=1.0.0" },
{ name = "hanzo-tools", specifier = ">=0.3.0" },
{ name = "hanzo-tools-agent", specifier = ">=0.2.3" },
@@ -649,7 +661,7 @@ requires-dist = [
{ name = "hanzo-tools-memory", specifier = ">=0.1.0" },
{ name = "hanzo-tools-reasoning", specifier = ">=0.1.0" },
{ name = "hanzo-tools-refactor", specifier = ">=0.1.0" },
{ name = "hanzo-tools-shell", specifier = ">=0.1.0" },
{ name = "hanzo-tools-shell", specifier = ">=0.5.0" },
{ name = "hanzo-tools-todo", specifier = ">=0.1.0" },
{ name = "mcp", specifier = ">=1.25.0" },
{ name = "mypy", marker = "extra == 'dev'", specifier = ">=1.10.0" },
@@ -673,7 +685,7 @@ requires-dist = [
{ name = "types-setuptools", marker = "extra == 'dev'", specifier = ">=69.5.0" },
{ name = "typing-extensions", specifier = ">=4.13.0" },
{ name = "ujson", marker = "extra == 'performance'", specifier = ">=5.7.0" },
{ name = "uvloop", marker = "sys_platform != 'win32' and extra == 'performance'", specifier = ">=0.21.0" },
{ name = "uvloop", specifier = ">=0.22.1" },
]
provides-extras = ["dev", "docs", "test", "performance", "publish"]
@@ -868,18 +880,18 @@ wheels = [
[[package]]
name = "hanzo-tools-shell"
version = "0.2.0"
version = "0.5.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiofiles" },
{ name = "hanzo-tools-core" },
{ name = "hanzo-async" },
{ name = "hanzo-tools" },
{ name = "mcp" },
{ name = "pydantic" },
{ name = "tiktoken" },
]
sdist = { url = "https://files.pythonhosted.org/packages/41/01/92922bf2db084f21eedd380017120926510ecbf06907452ae6ac5f8ad3a3/hanzo_tools_shell-0.2.0.tar.gz", hash = "sha256:d287843e1dab426542c0ea076bc43111cdb8b24b2a89cb35176e817253438027", size = 15734, upload-time = "2025-12-26T14:46:43.18Z" }
sdist = { url = "https://files.pythonhosted.org/packages/31/69/c0e66d34c7aa9f6a9897c5fedc59c67eedbd06e456c1c02aa33abd36dc56/hanzo_tools_shell-0.5.1.tar.gz", hash = "sha256:794d60471ff001872af74878f7d3d28e1e5b6aa59eed10a501aad7d62b0559fe", size = 33558, upload-time = "2026-01-04T01:40:55.983Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/78/31/21ec1accc5968a144ac65b6c6fa8ee0ae0c3f5367856631ff72c9eb72770/hanzo_tools_shell-0.2.0-py3-none-any.whl", hash = "sha256:fe76fe90b30da9bb1d6ce275bca7609a43e191f2993c250005df3ba0e7e91e84", size = 20739, upload-time = "2025-12-26T14:46:36.519Z" },
{ url = "https://files.pythonhosted.org/packages/e9/09/e1974ecfbd16ba1b4134390548b71f3f906d25475ec642f25a1b7757f54e/hanzo_tools_shell-0.5.1-py3-none-any.whl", hash = "sha256:f76cab02c5ae28b240880f13c127b9c0b2ce55acac17b878c341a8bcd2693c8f", size = 39718, upload-time = "2026-01-04T01:40:54.955Z" },
]
[[package]]
@@ -8,7 +8,6 @@ Core tools:
- bash: Bash shell (thin wrapper over cmd)
- fish: Fish shell (thin wrapper over cmd)
- dash: Dash shell (fast POSIX, Ubuntu's /bin/sh)
- shell: Smart shell alias (zsh > bash > fish > dash > sh fallback)
- ps: Process management (list, kill, logs)
HTTP/Data tools:
@@ -78,8 +77,9 @@ from hanzo_tools.shell.dag_tool import DagTool, DagResult, DagNode, create_dag_t
# Tools list for entry point discovery
# - CmdTool: Primary command execution with DAG support
# - ZshTool, BashTool, ShellTool: Shell wrappers (thin shims over CmdTool)
TOOLS = [CmdTool, ZshTool, BashTool, FishTool, DashTool, ShellTool, PsTool, NpxTool, UvxTool, OpenTool, CurlTool, JqTool, WgetTool]
# - ZshTool, BashTool, etc: Specific shell wrappers (thin shims over CmdTool)
# Note: ShellTool removed - too ambiguous, use specific shells (zsh, bash, dash, fish)
TOOLS = [CmdTool, ZshTool, BashTool, FishTool, DashTool, PsTool, NpxTool, UvxTool, OpenTool, CurlTool, JqTool, WgetTool]
__all__ = [
# uvloop status
@@ -156,6 +156,7 @@ def get_shell_tools(
# Create shell wrappers with access to other tools
zsh = ZshTool(tools=all_tools or {})
bash = BashTool(tools=all_tools or {})
# Set permission manager for convenience tools
npx_tool.permission_manager = permission_manager
@@ -164,6 +165,7 @@ def get_shell_tools(
return [
cmd, # Primary command execution with DAG support
zsh, # Zsh shell wrapper
bash, # Bash shell wrapper
ps_tool, # Process management
npx_tool, # Node packages
uvx_tool, # Python packages
+2 -2
View File
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
[project]
name = "hanzo-tools-shell"
version = "0.5.1"
description = "Shell/command execution tools - cmd (unified execution graph), zsh, bash, shell, ps, npx, uvx, open, curl, jq, wget"
version = "0.5.2"
description = "Shell/command execution tools - cmd (unified DAG), zsh, bash, fish, dash, ps, npx, uvx, open, curl, jq, wget"
readme = "README.md"
requires-python = ">=3.12"
license = { text = "MIT" }