Skip to content

Commit fb68069

Browse files
author
James Zhu
committed
Update files
🤖 Generated with Claude Code
1 parent 7a46db8 commit fb68069

6 files changed

Lines changed: 423 additions & 3 deletions

File tree

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
**One CLI to Rule Them All.**
99
<br>
10-
Tired of juggling multiple AI coding assistants? **CAM** is a unified Python CLI to manage configurations, prompts, skills, and plugins for **16 AI assistants** including Claude, Codex, Gemini, Qwen, Copilot, Goose, Continue, and more from a single, polished terminal interface.
10+
Tired of juggling multiple AI coding assistants? **CAM** is a unified Python CLI to manage configurations, prompts, skills, and plugins for **17 AI assistants** including Claude, Codex, Gemini, Qwen, Copilot, Blackbox, Goose, Continue, and more from a single, polished terminal interface.
1111

1212
</div>
1313

@@ -43,7 +43,7 @@ CAM solves this by providing a single, consistent interface to manage everything
4343

4444
## Supported AI Assistants
4545

46-
CAM supports **16 AI coding assistants**:
46+
CAM supports **17 AI coding assistants**:
4747

4848
| Assistant | Command | Description | Install Method |
4949
| :--- | :--- | :--- | :--- |
@@ -57,6 +57,7 @@ CAM supports **16 AI coding assistants**:
5757
| **iFlow** | `iflow` | iFlow AI CLI | npm |
5858
| **Crush** | `crush` | Charmland Crush CLI | npm |
5959
| **Cursor** | `cursor-agent` | Cursor Agent CLI | Shell script |
60+
| **Blackbox** | `blackbox` | Blackbox AI CLI | Shell script |
6061
| **Neovate** | `neovate` | Neovate Code CLI | npm |
6162
| **Qoder** | `qodercli` | Qoder CLI | npm |
6263
| **Zed** | `zed` | Zed Editor | Shell script |
@@ -74,7 +75,7 @@ CAM supports **16 AI coding assistants**:
7475
| **Plugin** Support ||||||||
7576
| **MCP** Integration ||||||||
7677

77-
**MCP Integration** is supported across all 16 assistants including: Claude, Codex, Gemini, Qwen, Copilot, CodeBuddy, Droid, iFlow, Zed, Qoder, Neovate, Crush, Cursor, Goose, Continue, and OpenCode.
78+
**MCP Integration** is supported across all 17 assistants including: Claude, Codex, Gemini, Qwen, Copilot, CodeBuddy, Droid, iFlow, Zed, Qoder, Neovate, Crush, Cursor, Blackbox, Goose, Continue, and OpenCode.
7879

7980
> **Note:** Some tools (Zed, Qoder, Neovate) are disabled by default in the menu as they are still under development. You can enable them in `tools.yaml` by setting `enabled: true`.
8081

code_assistant_manager/tools.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,3 +361,34 @@ tools:
361361
- "Configuration and extensions via Model Context Protocol (MCP)."
362362
cli_parameters:
363363
injected: []
364+
365+
blackbox:
366+
enabled: true
367+
install_cmd: curl -fsSL https://shell.blackbox.ai/api/scripts/blackbox-cli-v2/download.sh | bash
368+
cli_command: blackbox
369+
description: "Blackbox AI CLI"
370+
env:
371+
exported:
372+
BLACKBOX_API_KEY: "Resolved from endpoint configuration and environment (masked in output)."
373+
BLACKBOX_API_BASE_URL: "Populated from selected endpoint.endpoint."
374+
BLACKBOX_API_MODEL: "Model ID selected via code-assistant-manager prompt."
375+
NODE_TLS_REJECT_UNAUTHORIZED: "0"
376+
configuration:
377+
required:
378+
endpoint: "Base URL for Blackbox-compatible API."
379+
list_models_cmd: "Shell command returning available models for the endpoint."
380+
optional:
381+
api_key_env: "Environment variable name containing the API key."
382+
supported_client: "Comma-separated list used to filter endpoints; must include blackbox."
383+
keep_proxy_config: "When true, preserve proxy variables during model discovery."
384+
use_proxy: "When true, apply proxies from common config to runtime requests."
385+
description: "Display label shown during endpoint selection."
386+
model_listing_env:
387+
endpoint: "Provided to list_models_cmd as env var endpoint."
388+
api_key: "Provided to list_models_cmd as env var api_key (resolved API key)."
389+
proxies: "Proxy variables removed unless keep_proxy_config is true."
390+
cli_parameters:
391+
injected: []
392+
filesystem:
393+
generated:
394+
- "~/.blackboxcli/settings.json containing provider configuration based on selected endpoint"

code_assistant_manager/tools/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def _ensure_tools_loaded() -> None:
4646

4747
# Import tool modules so their subclasses are registered
4848
from . import ( # noqa: F401
49+
blackbox,
4950
claude,
5051
codebuddy,
5152
codex,
@@ -120,6 +121,7 @@ def get_registered_tools() -> Dict[str, Type[CLITool]]:
120121
def __getattr__(name: str):
121122
"""Lazy-load tool classes when explicitly imported."""
122123
tool_map = {
124+
"BlackboxTool": "blackbox",
123125
"ClaudeTool": "claude",
124126
"CodeBuddyTool": "codebuddy",
125127
"CodexTool": "codex",
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import json
2+
import os
3+
from pathlib import Path
4+
from typing import List
5+
6+
from .base import CLITool
7+
8+
9+
class BlackboxTool(CLITool):
10+
"""Blackbox AI CLI wrapper."""
11+
12+
command_name = "blackbox"
13+
tool_key = "blackbox"
14+
install_description = "Blackbox AI CLI"
15+
16+
def _write_blackbox_config(
17+
self, endpoint_config: dict, model: str, endpoint_name: str
18+
) -> Path:
19+
"""
20+
Write Blackbox CLI configuration to ~/.blackboxcli/settings.json.
21+
22+
Args:
23+
endpoint_config: Endpoint configuration dictionary
24+
model: Selected model name
25+
endpoint_name: Name of the endpoint
26+
27+
Returns:
28+
Path to the written settings file
29+
"""
30+
config_dir = Path.home() / ".blackboxcli"
31+
config_file = config_dir / "settings.json"
32+
33+
# Preserve existing configuration if it exists
34+
existing_config = {}
35+
if config_file.exists():
36+
try:
37+
existing_config = json.loads(config_file.read_text(encoding="utf-8"))
38+
except Exception:
39+
pass
40+
41+
# Build the Blackbox configuration
42+
blackbox_config = {
43+
"security": {
44+
"auth": {
45+
"selectedType": "blackbox-api",
46+
"selectedProvider": "blackbox",
47+
"blackbox": {
48+
"apiKey": endpoint_config.get("actual_api_key", ""),
49+
"baseUrl": endpoint_config.get("endpoint", "https://api.blackbox.ai"),
50+
"model": model,
51+
},
52+
}
53+
},
54+
"model": {"name": model},
55+
}
56+
57+
# Merge with existing configuration to preserve other settings
58+
if isinstance(existing_config, dict):
59+
# Deep merge security.auth settings
60+
if "security" not in existing_config:
61+
existing_config["security"] = {}
62+
if "auth" not in existing_config["security"]:
63+
existing_config["security"]["auth"] = {}
64+
65+
existing_config["security"]["auth"].update(blackbox_config["security"]["auth"])
66+
existing_config["model"] = blackbox_config["model"]
67+
final_config = existing_config
68+
else:
69+
final_config = blackbox_config
70+
71+
# Write the configuration
72+
config_dir.mkdir(parents=True, exist_ok=True)
73+
with open(config_file, "w", encoding="utf-8") as f:
74+
json.dump(final_config, f, indent=2, ensure_ascii=False)
75+
76+
return config_file
77+
78+
def run(self, args: List[str] = None) -> int:
79+
"""
80+
Configure and launch the Blackbox AI CLI.
81+
82+
Args:
83+
args: List of arguments to pass to the Blackbox CLI
84+
85+
Returns:
86+
Exit code of the Blackbox CLI process
87+
"""
88+
args = args or []
89+
90+
# Set up endpoint and model for Blackbox
91+
success, result = self._validate_and_setup_tool("blackbox", select_multiple=False)
92+
if not success:
93+
return 1
94+
95+
# Extract endpoint configuration and selected model
96+
endpoint_config, endpoint_name, model = result
97+
98+
# Write Blackbox configuration file
99+
config_file = self._write_blackbox_config(endpoint_config, model, endpoint_name)
100+
print(f"Blackbox configuration written to {config_file}")
101+
102+
# Set up environment variables for Blackbox based on tools.yaml configuration
103+
env = os.environ.copy()
104+
env["BLACKBOX_API_KEY"] = endpoint_config["actual_api_key"]
105+
env["BLACKBOX_API_BASE_URL"] = endpoint_config["endpoint"]
106+
env["BLACKBOX_API_MODEL"] = model
107+
self._set_node_tls_env(env)
108+
109+
# Execute the Blackbox CLI with the configured environment
110+
command = ["blackbox"] + args
111+
112+
# Display the complete command that will be executed
113+
args_str = " ".join(args) if args else ""
114+
command_str = f"blackbox {args_str}".strip()
115+
print("")
116+
print("Complete command to execute:")
117+
print(
118+
f"BLACKBOX_API_BASE_URL={env['BLACKBOX_API_BASE_URL']} "
119+
f"BLACKBOX_API_KEY=*** "
120+
f"BLACKBOX_API_MODEL={model} {command_str}"
121+
)
122+
print("")
123+
124+
return self._run_tool_with_env(command, env, "blackbox", interactive=True)

0 commit comments

Comments
 (0)