Files
zooqueenandHanzo Dev b144973bfc fix(lint): resolve all ruff + black errors across all packages
Fix 35 ruff errors (E722, F841, B904, B905, B007, E741, S202, S310,
S306, S110, TID251, UP042, F401) and run black on 526 files.

Co-authored-by: Hanzo Dev <[email protected]>
2026-02-21 23:32:32 -08:00

93 lines
2.4 KiB
Python

"""NPX tool for both sync and background execution."""
from typing import Optional, override
from pathlib import Path
from mcp.server import FastMCP
from mcp.server.fastmcp import Context as MCPContext
from hanzo_tools.core import auto_timeout
from hanzo_tools.shell.base_process import BaseBinaryTool
class NpxTool(BaseBinaryTool):
"""Tool for running npx commands."""
name = "npx"
@property
@override
def description(self) -> str:
"""Get the tool description."""
return """Run npx packages with automatic backgrounding for long-running processes.
Commands that run for more than 2 minutes will automatically continue in the background.
Usage:
npx create-react-app my-app
npx http-server -p 8080 # Auto-backgrounds after 2 minutes
npx prettier --write "**/*.js"
npx json-server db.json # Auto-backgrounds if needed"""
@override
def get_binary_name(self) -> str:
"""Get the binary name."""
return "npx"
@override
async def run(
self,
ctx: MCPContext,
package: str,
args: str = "",
cwd: Optional[str] = None,
yes: bool = True,
) -> str:
"""Run an npx command with auto-backgrounding."""
work_dir = Path(cwd).resolve() if cwd else Path.cwd()
flags = []
if yes:
flags.append("-y")
full_args = args.split() if args else []
return await self.execute_sync(
package,
cwd=work_dir,
flags=flags,
args=full_args,
timeout=None,
)
def register(self, server: FastMCP) -> None:
"""Register the tool with the MCP server."""
tool_self = self
@server.tool(name=self.name, description=self.description)
async def npx(
ctx: MCPContext,
package: str,
args: str = "",
cwd: Optional[str] = None,
yes: bool = True,
) -> str:
return await tool_self.run(
ctx, package=package, args=args, cwd=cwd, yes=yes
)
@auto_timeout("npx")
async def call(self, ctx: MCPContext, **params) -> str:
"""Call the tool with arguments."""
return await self.run(
ctx,
package=params["package"],
args=params.get("args", ""),
cwd=params.get("cwd"),
yes=params.get("yes", True),
)
# Create tool instance
npx_tool = NpxTool()