@oneciel-ai/claude-any 0.1.91 → 0.1.92
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.
- package/claude_any.py +75 -9
- package/package.json +1 -1
package/claude_any.py
CHANGED
|
@@ -105,7 +105,7 @@ OFFICIAL_CHANNEL_PLUGINS = {
|
|
|
105
105
|
"fakechat": "plugin:fakechat@claude-plugins-official",
|
|
106
106
|
}
|
|
107
107
|
APP_NAME = "Claude Any"
|
|
108
|
-
VERSION = "0.1.
|
|
108
|
+
VERSION = "0.1.92"
|
|
109
109
|
CREDITS = "Credits: One Ciel LLC"
|
|
110
110
|
|
|
111
111
|
LOG_LEVELS = {"SILENT": 0, "ERROR": 1, "WARN": 2, "INFO": 3, "DEBUG": 4, "TRACE": 5}
|
|
@@ -1675,6 +1675,11 @@ def executable_candidates(name: str) -> list[str]:
|
|
|
1675
1675
|
|
|
1676
1676
|
def executable_extra_dirs() -> list[Path]:
|
|
1677
1677
|
dirs = [HOME / ".local" / "bin"]
|
|
1678
|
+
for env_name in ("UV_INSTALL_DIR", "CARGO_HOME"):
|
|
1679
|
+
root = os.environ.get(env_name)
|
|
1680
|
+
if root:
|
|
1681
|
+
path = Path(root)
|
|
1682
|
+
dirs.append(path if path.name == "bin" else path / "bin")
|
|
1678
1683
|
if os.name == "nt":
|
|
1679
1684
|
pyver = f"Python{sys.version_info.major}{sys.version_info.minor}"
|
|
1680
1685
|
for env_name in ("APPDATA", "LOCALAPPDATA"):
|
|
@@ -1688,7 +1693,27 @@ def executable_extra_dirs() -> list[Path]:
|
|
|
1688
1693
|
except Exception:
|
|
1689
1694
|
pass
|
|
1690
1695
|
dirs.append(Path(sys.executable).resolve().parent / "Scripts")
|
|
1691
|
-
|
|
1696
|
+
else:
|
|
1697
|
+
dirs.extend(
|
|
1698
|
+
[
|
|
1699
|
+
HOME / ".cargo" / "bin",
|
|
1700
|
+
HOME / ".npm-global" / "bin",
|
|
1701
|
+
HOME / ".bun" / "bin",
|
|
1702
|
+
Path(sys.executable).resolve().parent,
|
|
1703
|
+
Path("/usr/local/bin"),
|
|
1704
|
+
Path("/usr/bin"),
|
|
1705
|
+
Path("/bin"),
|
|
1706
|
+
Path("/opt/homebrew/bin"),
|
|
1707
|
+
]
|
|
1708
|
+
)
|
|
1709
|
+
out: list[Path] = []
|
|
1710
|
+
seen: set[str] = set()
|
|
1711
|
+
for directory in dirs:
|
|
1712
|
+
key = str(directory)
|
|
1713
|
+
if key and key not in seen:
|
|
1714
|
+
seen.add(key)
|
|
1715
|
+
out.append(directory)
|
|
1716
|
+
return out
|
|
1692
1717
|
|
|
1693
1718
|
|
|
1694
1719
|
def find_executable(name: str) -> str | None:
|
|
@@ -1704,6 +1729,29 @@ def find_executable(name: str) -> str | None:
|
|
|
1704
1729
|
return None
|
|
1705
1730
|
|
|
1706
1731
|
|
|
1732
|
+
def resolve_executable_for_subprocess(command: str) -> str:
|
|
1733
|
+
command = str(command or "").strip()
|
|
1734
|
+
if not command:
|
|
1735
|
+
return command
|
|
1736
|
+
pathish = Path(command).is_absolute() or os.sep in command or bool(os.altsep and os.altsep in command)
|
|
1737
|
+
if pathish:
|
|
1738
|
+
return command
|
|
1739
|
+
return find_executable(command) or command
|
|
1740
|
+
|
|
1741
|
+
|
|
1742
|
+
def resolve_mcp_server_process(command: str, args: list[str]) -> tuple[str, list[str]]:
|
|
1743
|
+
command = str(command or "").strip()
|
|
1744
|
+
resolved = resolve_executable_for_subprocess(command)
|
|
1745
|
+
name = Path(command).name.lower()
|
|
1746
|
+
if resolved == command and name in ("uvx", "uvx.exe", "uvx.cmd", "uvx.bat"):
|
|
1747
|
+
uv = find_executable("uv")
|
|
1748
|
+
if uv:
|
|
1749
|
+
return uv, ["tool", "run", *args]
|
|
1750
|
+
if importlib.util.find_spec("uv") is not None:
|
|
1751
|
+
return sys.executable, ["-m", "uv", "tool", "run", *args]
|
|
1752
|
+
return resolved, args
|
|
1753
|
+
|
|
1754
|
+
|
|
1707
1755
|
def shell_command_string(args: list[str]) -> str:
|
|
1708
1756
|
if os.name == "nt":
|
|
1709
1757
|
# Claude Code on Windows runs hook commands through sh/bash, which treats
|
|
@@ -9392,7 +9440,7 @@ def _mcp_server_is_stdio(server: dict[str, Any]) -> bool:
|
|
|
9392
9440
|
server_type = str(server.get("type") or "").strip().lower()
|
|
9393
9441
|
if server_type and server_type not in ("stdio", "command"):
|
|
9394
9442
|
return False
|
|
9395
|
-
command = str(server.get("command") or "").strip()
|
|
9443
|
+
command = resolve_executable_for_subprocess(str(server.get("command") or "").strip())
|
|
9396
9444
|
if not command:
|
|
9397
9445
|
return False
|
|
9398
9446
|
args = [str(item) for item in server.get("args", []) if item is not None] if isinstance(server.get("args", []), list) else []
|
|
@@ -13854,7 +13902,6 @@ def write_web_tools_mcp_config(cfg: dict[str, Any]) -> Path:
|
|
|
13854
13902
|
web = cfg.get("web_search", {})
|
|
13855
13903
|
package = web.get("package") or "ddg-mcp-search"
|
|
13856
13904
|
npx = find_executable("npx") or ("npx.cmd" if os.name == "nt" else "npx")
|
|
13857
|
-
uvx = find_executable("uvx") or "uvx"
|
|
13858
13905
|
servers: dict[str, Any] = {
|
|
13859
13906
|
"duckduckgo": {
|
|
13860
13907
|
"command": npx,
|
|
@@ -13867,11 +13914,29 @@ def write_web_tools_mcp_config(cfg: dict[str, Any]) -> Path:
|
|
|
13867
13914
|
fetch_args.extend(["--user-agent", str(web["fetch_user_agent"])])
|
|
13868
13915
|
if web.get("fetch_ignore_robots_txt", False):
|
|
13869
13916
|
fetch_args.append("--ignore-robots-txt")
|
|
13870
|
-
|
|
13871
|
-
|
|
13872
|
-
|
|
13873
|
-
|
|
13874
|
-
|
|
13917
|
+
fetch_command = find_executable("uvx")
|
|
13918
|
+
fetch_command_args = fetch_args
|
|
13919
|
+
if not fetch_command:
|
|
13920
|
+
uv = find_executable("uv")
|
|
13921
|
+
if uv:
|
|
13922
|
+
fetch_command = uv
|
|
13923
|
+
fetch_command_args = ["tool", "run", *fetch_args]
|
|
13924
|
+
elif importlib.util.find_spec("uv") is not None:
|
|
13925
|
+
fetch_command = sys.executable
|
|
13926
|
+
fetch_command_args = ["-m", "uv", "tool", "run", *fetch_args]
|
|
13927
|
+
else:
|
|
13928
|
+
pipx = find_executable("pipx")
|
|
13929
|
+
if pipx:
|
|
13930
|
+
fetch_command = pipx
|
|
13931
|
+
fetch_command_args = ["run", *fetch_args]
|
|
13932
|
+
if fetch_command:
|
|
13933
|
+
servers["web_fetch"] = {
|
|
13934
|
+
"command": fetch_command,
|
|
13935
|
+
"args": fetch_command_args,
|
|
13936
|
+
"claude_any_stdio": "jsonl",
|
|
13937
|
+
}
|
|
13938
|
+
else:
|
|
13939
|
+
router_log("WARN", "web_fetch_disabled_missing_runner install=uvx_or_uv")
|
|
13875
13940
|
data = {"mcpServers": servers}
|
|
13876
13941
|
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
13877
13942
|
WEB_TOOLS_MCP_CONFIG.write_text(json.dumps(data, indent=2) + "\n")
|
|
@@ -14600,6 +14665,7 @@ def run_mcp_stdio_proxy(server_name: str, server_config_path: Path) -> int:
|
|
|
14600
14665
|
return 2
|
|
14601
14666
|
command = str(server.get("command") or "").strip()
|
|
14602
14667
|
args = [str(item) for item in server.get("args", [])] if isinstance(server.get("args"), list) else []
|
|
14668
|
+
command, args = resolve_mcp_server_process(command, args)
|
|
14603
14669
|
env = os.environ.copy()
|
|
14604
14670
|
raw_env = server.get("env")
|
|
14605
14671
|
if isinstance(raw_env, dict):
|
package/package.json
CHANGED