@musashishao/agent-kit 1.2.2 → 1.3.0
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/.agent/mcp-gateway/README.md +121 -0
- package/.agent/mcp-gateway/dist/index.d.ts +11 -0
- package/.agent/mcp-gateway/dist/index.js +504 -0
- package/.agent/mcp-gateway/dist/sync/debouncer.d.ts +56 -0
- package/.agent/mcp-gateway/dist/sync/debouncer.js +112 -0
- package/.agent/mcp-gateway/dist/sync/incremental_syncer.d.ts +58 -0
- package/.agent/mcp-gateway/dist/sync/incremental_syncer.js +172 -0
- package/.agent/mcp-gateway/dist/sync/index.d.ts +6 -0
- package/.agent/mcp-gateway/dist/sync/index.js +6 -0
- package/.agent/mcp-gateway/dist/sync/timestamp_checker.d.ts +69 -0
- package/.agent/mcp-gateway/dist/sync/timestamp_checker.js +169 -0
- package/.agent/mcp-gateway/package.json +28 -0
- package/.agent/mcp-gateway/src/index.ts +608 -0
- package/.agent/mcp-gateway/src/sync/debouncer.ts +129 -0
- package/.agent/mcp-gateway/src/sync/incremental_syncer.ts +237 -0
- package/.agent/mcp-gateway/src/sync/index.ts +7 -0
- package/.agent/mcp-gateway/src/sync/timestamp_checker.ts +194 -0
- package/.agent/scripts/ak_cli.py +533 -0
- package/.agent/scripts/setup_host.py +557 -0
- package/.agent/scripts/verify_install.py +174 -0
- package/.agent/skills/app-builder/SKILL.md +51 -1
- package/.agent/skills/app-builder/scripts/generate_ai_infra.py +510 -0
- package/.agent/skills/documentation-templates/SKILL.md +9 -1
- package/.agent/skills/documentation-templates/agents-template.md +202 -0
- package/.agent/skills/graph-mapper/SKILL.md +211 -0
- package/.agent/skills/graph-mapper/scripts/generate_graph.py +503 -0
- package/.agent/skills/rag-engineering/SKILL.md +342 -0
- package/.agent/skills/rag-engineering/chunking-strategies.md +229 -0
- package/.agent/skills/rag-engineering/contextual-retrieval.md +261 -0
- package/.agent/skills/rag-engineering/hybrid-search.md +356 -0
- package/.agent/skills/rag-engineering/scripts/chunk_code.py +606 -0
- package/.agent/templates/mcp_configs/claude_desktop.json +14 -0
- package/.agent/templates/mcp_configs/cursor.json +13 -0
- package/.agent/templates/mcp_configs/vscode.json +13 -0
- package/.agent/workflows/create.md +70 -2
- package/bin/cli.js +91 -0
- package/docs/AI_DATA_INFRASTRUCTURE.md +288 -0
- package/docs/CHANGELOG_AI_INFRA.md +111 -0
- package/package.json +7 -2
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
AI Host Auto-Configuration
|
|
4
|
+
|
|
5
|
+
Automatically detects and configures AI hosts (Claude Desktop, Cursor, VS Code)
|
|
6
|
+
to use the Agent Kit MCP Gateway.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python setup_host.py --project-root /path/to/project
|
|
10
|
+
python setup_host.py --list # List detected hosts only
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import sys
|
|
15
|
+
import json
|
|
16
|
+
import shutil
|
|
17
|
+
import platform
|
|
18
|
+
import argparse
|
|
19
|
+
import subprocess
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Dict, List, Optional, Tuple
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# ============================================================================
|
|
25
|
+
# Constants
|
|
26
|
+
# ============================================================================
|
|
27
|
+
|
|
28
|
+
SUPPORTED_HOSTS = {
|
|
29
|
+
"claude_desktop": {
|
|
30
|
+
"name": "Claude Desktop",
|
|
31
|
+
"config_paths": {
|
|
32
|
+
"Darwin": "~/Library/Application Support/Claude/claude_desktop_config.json",
|
|
33
|
+
"Windows": "%APPDATA%/Claude/claude_desktop_config.json",
|
|
34
|
+
"Linux": "~/.config/Claude/claude_desktop_config.json",
|
|
35
|
+
},
|
|
36
|
+
"detection": {
|
|
37
|
+
"Darwin": ["/Applications/Claude.app"],
|
|
38
|
+
"Windows": ["%LOCALAPPDATA%/Programs/Claude/Claude.exe"],
|
|
39
|
+
"Linux": [],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
"cursor": {
|
|
43
|
+
"name": "Cursor",
|
|
44
|
+
"config_paths": {
|
|
45
|
+
"Darwin": ".cursor/mcp.json", # Project-local
|
|
46
|
+
"Windows": ".cursor/mcp.json",
|
|
47
|
+
"Linux": ".cursor/mcp.json",
|
|
48
|
+
},
|
|
49
|
+
"detection": {
|
|
50
|
+
"Darwin": ["/Applications/Cursor.app"],
|
|
51
|
+
"Windows": ["%LOCALAPPDATA%/Programs/Cursor/Cursor.exe"],
|
|
52
|
+
"Linux": ["/usr/bin/cursor", "~/.local/bin/cursor"],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
"vscode": {
|
|
56
|
+
"name": "VS Code",
|
|
57
|
+
"config_paths": {
|
|
58
|
+
"Darwin": ".vscode/settings.json", # Project-local
|
|
59
|
+
"Windows": ".vscode/settings.json",
|
|
60
|
+
"Linux": ".vscode/settings.json",
|
|
61
|
+
},
|
|
62
|
+
"detection": {
|
|
63
|
+
"Darwin": ["/Applications/Visual Studio Code.app"],
|
|
64
|
+
"Windows": ["%LOCALAPPDATA%/Programs/Microsoft VS Code/Code.exe"],
|
|
65
|
+
"Linux": ["/usr/bin/code", "/snap/bin/code"],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
"windsurf": {
|
|
69
|
+
"name": "Windsurf",
|
|
70
|
+
"config_paths": {
|
|
71
|
+
"Darwin": ".windsurf/mcp.json",
|
|
72
|
+
"Windows": ".windsurf/mcp.json",
|
|
73
|
+
"Linux": ".windsurf/mcp.json",
|
|
74
|
+
},
|
|
75
|
+
"detection": {
|
|
76
|
+
"Darwin": ["/Applications/Windsurf.app"],
|
|
77
|
+
"Windows": [],
|
|
78
|
+
"Linux": [],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# ============================================================================
|
|
85
|
+
# Utility Functions
|
|
86
|
+
# ============================================================================
|
|
87
|
+
|
|
88
|
+
def get_os() -> str:
|
|
89
|
+
"""Get current operating system."""
|
|
90
|
+
return platform.system()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def expand_path(path: str) -> Path:
|
|
94
|
+
"""Expand environment variables and user home in path."""
|
|
95
|
+
expanded = os.path.expandvars(os.path.expanduser(path))
|
|
96
|
+
return Path(expanded)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def is_host_installed(host_id: str) -> bool:
|
|
100
|
+
"""Check if an AI host is installed."""
|
|
101
|
+
host = SUPPORTED_HOSTS.get(host_id)
|
|
102
|
+
if not host:
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
os_name = get_os()
|
|
106
|
+
detection_paths = host["detection"].get(os_name, [])
|
|
107
|
+
|
|
108
|
+
for path in detection_paths:
|
|
109
|
+
expanded = expand_path(path)
|
|
110
|
+
if expanded.exists():
|
|
111
|
+
return True
|
|
112
|
+
|
|
113
|
+
return False
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def detect_installed_hosts() -> List[str]:
|
|
117
|
+
"""Detect which AI hosts are installed on this system."""
|
|
118
|
+
installed = []
|
|
119
|
+
for host_id in SUPPORTED_HOSTS:
|
|
120
|
+
if is_host_installed(host_id):
|
|
121
|
+
installed.append(host_id)
|
|
122
|
+
return installed
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def get_config_path(host_id: str, project_root: Path) -> Optional[Path]:
|
|
126
|
+
"""Get the config file path for a host."""
|
|
127
|
+
host = SUPPORTED_HOSTS.get(host_id)
|
|
128
|
+
if not host:
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
os_name = get_os()
|
|
132
|
+
config_path = host["config_paths"].get(os_name)
|
|
133
|
+
if not config_path:
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
# Check if it's a project-local path (starts with .)
|
|
137
|
+
if config_path.startswith("."):
|
|
138
|
+
return project_root / config_path
|
|
139
|
+
else:
|
|
140
|
+
return expand_path(config_path)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def backup_config(config_path: Path) -> Optional[Path]:
|
|
144
|
+
"""Create a backup of existing config file."""
|
|
145
|
+
if not config_path.exists():
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
backup_path = config_path.with_suffix(config_path.suffix + ".backup")
|
|
149
|
+
shutil.copy2(config_path, backup_path)
|
|
150
|
+
return backup_path
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def load_json_config(path: Path) -> Dict:
|
|
154
|
+
"""Load JSON config file, return empty dict if not exists."""
|
|
155
|
+
if not path.exists():
|
|
156
|
+
return {}
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
160
|
+
return json.load(f)
|
|
161
|
+
except json.JSONDecodeError:
|
|
162
|
+
return {}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def save_json_config(path: Path, config: Dict) -> bool:
|
|
166
|
+
"""Save config to JSON file."""
|
|
167
|
+
try:
|
|
168
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
169
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
170
|
+
json.dump(config, f, indent=2)
|
|
171
|
+
return True
|
|
172
|
+
except Exception as e:
|
|
173
|
+
print(f"Error saving config: {e}")
|
|
174
|
+
return False
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# ============================================================================
|
|
178
|
+
# Configuration Functions
|
|
179
|
+
# ============================================================================
|
|
180
|
+
|
|
181
|
+
def generate_mcp_config(
|
|
182
|
+
project_root: Path,
|
|
183
|
+
mcp_server_path: Path,
|
|
184
|
+
kit_path: Path
|
|
185
|
+
) -> Dict:
|
|
186
|
+
"""Generate MCP server configuration."""
|
|
187
|
+
return {
|
|
188
|
+
"command": "node",
|
|
189
|
+
"args": [str(mcp_server_path)],
|
|
190
|
+
"env": {
|
|
191
|
+
"PROJECT_ROOT": str(project_root),
|
|
192
|
+
"AGENT_KIT_PATH": str(kit_path),
|
|
193
|
+
},
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def configure_claude_desktop(
|
|
198
|
+
project_root: Path,
|
|
199
|
+
mcp_server_path: Path,
|
|
200
|
+
kit_path: Path,
|
|
201
|
+
dry_run: bool = False
|
|
202
|
+
) -> Tuple[bool, str]:
|
|
203
|
+
"""Configure Claude Desktop to use Agent Kit MCP."""
|
|
204
|
+
config_path = get_config_path("claude_desktop", project_root)
|
|
205
|
+
if not config_path:
|
|
206
|
+
return False, "Could not determine Claude Desktop config path"
|
|
207
|
+
|
|
208
|
+
# Load existing config
|
|
209
|
+
config = load_json_config(config_path)
|
|
210
|
+
|
|
211
|
+
# Initialize mcpServers if not exists
|
|
212
|
+
if "mcpServers" not in config:
|
|
213
|
+
config["mcpServers"] = {}
|
|
214
|
+
|
|
215
|
+
# Check if already configured
|
|
216
|
+
if "agent-kit" in config["mcpServers"]:
|
|
217
|
+
existing = config["mcpServers"]["agent-kit"]
|
|
218
|
+
if existing.get("env", {}).get("PROJECT_ROOT") == str(project_root):
|
|
219
|
+
return True, "Already configured for this project"
|
|
220
|
+
|
|
221
|
+
# Add our server config
|
|
222
|
+
config["mcpServers"]["agent-kit"] = generate_mcp_config(
|
|
223
|
+
project_root, mcp_server_path, kit_path
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
if dry_run:
|
|
227
|
+
return True, f"Would update: {config_path}"
|
|
228
|
+
|
|
229
|
+
# Backup and save
|
|
230
|
+
backup = backup_config(config_path)
|
|
231
|
+
if backup:
|
|
232
|
+
print(f" Backed up to: {backup}")
|
|
233
|
+
|
|
234
|
+
if save_json_config(config_path, config):
|
|
235
|
+
return True, f"Configured: {config_path}"
|
|
236
|
+
else:
|
|
237
|
+
return False, "Failed to save config"
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def configure_cursor(
|
|
241
|
+
project_root: Path,
|
|
242
|
+
mcp_server_path: Path,
|
|
243
|
+
kit_path: Path,
|
|
244
|
+
dry_run: bool = False
|
|
245
|
+
) -> Tuple[bool, str]:
|
|
246
|
+
"""Configure Cursor to use Agent Kit MCP (project-local)."""
|
|
247
|
+
config_path = get_config_path("cursor", project_root)
|
|
248
|
+
if not config_path:
|
|
249
|
+
return False, "Could not determine Cursor config path"
|
|
250
|
+
|
|
251
|
+
# For Cursor, use relative paths since it's project-local
|
|
252
|
+
relative_mcp_path = ".agent/mcp-gateway/dist/index.js"
|
|
253
|
+
|
|
254
|
+
config = load_json_config(config_path)
|
|
255
|
+
|
|
256
|
+
if "mcpServers" not in config:
|
|
257
|
+
config["mcpServers"] = {}
|
|
258
|
+
|
|
259
|
+
config["mcpServers"]["agent-kit"] = {
|
|
260
|
+
"command": "node",
|
|
261
|
+
"args": [relative_mcp_path],
|
|
262
|
+
"env": {
|
|
263
|
+
"PROJECT_ROOT": ".",
|
|
264
|
+
},
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if dry_run:
|
|
268
|
+
return True, f"Would create: {config_path}"
|
|
269
|
+
|
|
270
|
+
if save_json_config(config_path, config):
|
|
271
|
+
return True, f"Created: {config_path}"
|
|
272
|
+
else:
|
|
273
|
+
return False, "Failed to save config"
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def configure_vscode(
|
|
277
|
+
project_root: Path,
|
|
278
|
+
mcp_server_path: Path,
|
|
279
|
+
kit_path: Path,
|
|
280
|
+
dry_run: bool = False
|
|
281
|
+
) -> Tuple[bool, str]:
|
|
282
|
+
"""Configure VS Code settings for MCP (if MCP extension is installed)."""
|
|
283
|
+
config_path = get_config_path("vscode", project_root)
|
|
284
|
+
if not config_path:
|
|
285
|
+
return False, "Could not determine VS Code config path"
|
|
286
|
+
|
|
287
|
+
config = load_json_config(config_path)
|
|
288
|
+
|
|
289
|
+
# Add MCP config (format may vary by extension)
|
|
290
|
+
if "mcp.servers" not in config:
|
|
291
|
+
config["mcp.servers"] = {}
|
|
292
|
+
|
|
293
|
+
config["mcp.servers"]["agent-kit"] = {
|
|
294
|
+
"command": "node",
|
|
295
|
+
"args": ["${workspaceFolder}/.agent/mcp-gateway/dist/index.js"],
|
|
296
|
+
"env": {
|
|
297
|
+
"PROJECT_ROOT": "${workspaceFolder}",
|
|
298
|
+
},
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if dry_run:
|
|
302
|
+
return True, f"Would update: {config_path}"
|
|
303
|
+
|
|
304
|
+
if save_json_config(config_path, config):
|
|
305
|
+
return True, f"Updated: {config_path}"
|
|
306
|
+
else:
|
|
307
|
+
return False, "Failed to save config"
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def configure_windsurf(
|
|
311
|
+
project_root: Path,
|
|
312
|
+
mcp_server_path: Path,
|
|
313
|
+
kit_path: Path,
|
|
314
|
+
dry_run: bool = False
|
|
315
|
+
) -> Tuple[bool, str]:
|
|
316
|
+
"""Configure Windsurf to use Agent Kit MCP (project-local)."""
|
|
317
|
+
config_path = get_config_path("windsurf", project_root)
|
|
318
|
+
if not config_path:
|
|
319
|
+
return False, "Could not determine Windsurf config path"
|
|
320
|
+
|
|
321
|
+
relative_mcp_path = ".agent/mcp-gateway/dist/index.js"
|
|
322
|
+
|
|
323
|
+
config = load_json_config(config_path)
|
|
324
|
+
|
|
325
|
+
if "mcpServers" not in config:
|
|
326
|
+
config["mcpServers"] = {}
|
|
327
|
+
|
|
328
|
+
config["mcpServers"]["agent-kit"] = {
|
|
329
|
+
"command": "node",
|
|
330
|
+
"args": [relative_mcp_path],
|
|
331
|
+
"env": {
|
|
332
|
+
"PROJECT_ROOT": ".",
|
|
333
|
+
},
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if dry_run:
|
|
337
|
+
return True, f"Would create: {config_path}"
|
|
338
|
+
|
|
339
|
+
if save_json_config(config_path, config):
|
|
340
|
+
return True, f"Created: {config_path}"
|
|
341
|
+
else:
|
|
342
|
+
return False, "Failed to save config"
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
# ============================================================================
|
|
346
|
+
# Clipboard Helper
|
|
347
|
+
# ============================================================================
|
|
348
|
+
|
|
349
|
+
def copy_to_clipboard(text: str) -> bool:
|
|
350
|
+
"""Copy text to system clipboard."""
|
|
351
|
+
os_name = get_os()
|
|
352
|
+
|
|
353
|
+
try:
|
|
354
|
+
if os_name == "Darwin":
|
|
355
|
+
process = subprocess.Popen(
|
|
356
|
+
["pbcopy"],
|
|
357
|
+
stdin=subprocess.PIPE,
|
|
358
|
+
)
|
|
359
|
+
process.communicate(text.encode("utf-8"))
|
|
360
|
+
return process.returncode == 0
|
|
361
|
+
elif os_name == "Windows":
|
|
362
|
+
process = subprocess.Popen(
|
|
363
|
+
["clip"],
|
|
364
|
+
stdin=subprocess.PIPE,
|
|
365
|
+
)
|
|
366
|
+
process.communicate(text.encode("utf-16"))
|
|
367
|
+
return process.returncode == 0
|
|
368
|
+
elif os_name == "Linux":
|
|
369
|
+
# Try xclip first, then xsel
|
|
370
|
+
for cmd in [["xclip", "-selection", "clipboard"], ["xsel", "--clipboard", "--input"]]:
|
|
371
|
+
try:
|
|
372
|
+
process = subprocess.Popen(cmd, stdin=subprocess.PIPE)
|
|
373
|
+
process.communicate(text.encode("utf-8"))
|
|
374
|
+
if process.returncode == 0:
|
|
375
|
+
return True
|
|
376
|
+
except FileNotFoundError:
|
|
377
|
+
continue
|
|
378
|
+
return False
|
|
379
|
+
except Exception:
|
|
380
|
+
return False
|
|
381
|
+
|
|
382
|
+
return False
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
# ============================================================================
|
|
386
|
+
# Main Setup Function
|
|
387
|
+
# ============================================================================
|
|
388
|
+
|
|
389
|
+
def setup_hosts(
|
|
390
|
+
project_root: Path,
|
|
391
|
+
hosts: Optional[List[str]] = None,
|
|
392
|
+
dry_run: bool = False,
|
|
393
|
+
force: bool = False
|
|
394
|
+
) -> Dict[str, Tuple[bool, str]]:
|
|
395
|
+
"""
|
|
396
|
+
Configure all detected AI hosts.
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
project_root: Path to the project root
|
|
400
|
+
hosts: Specific hosts to configure (None = all detected)
|
|
401
|
+
dry_run: If True, only show what would be done
|
|
402
|
+
force: If True, reconfigure even if already set up
|
|
403
|
+
|
|
404
|
+
Returns:
|
|
405
|
+
Dict mapping host_id to (success, message)
|
|
406
|
+
"""
|
|
407
|
+
results = {}
|
|
408
|
+
|
|
409
|
+
# Determine MCP server path
|
|
410
|
+
mcp_server_path = project_root / ".agent" / "mcp-gateway" / "dist" / "index.js"
|
|
411
|
+
kit_path = project_root / ".agent"
|
|
412
|
+
|
|
413
|
+
# Check if MCP server is built
|
|
414
|
+
if not mcp_server_path.exists():
|
|
415
|
+
print("⚠️ MCP Gateway not built. Building now...")
|
|
416
|
+
build_result = subprocess.run(
|
|
417
|
+
["npm", "run", "build"],
|
|
418
|
+
cwd=str(project_root / ".agent" / "mcp-gateway"),
|
|
419
|
+
capture_output=True,
|
|
420
|
+
text=True,
|
|
421
|
+
)
|
|
422
|
+
if build_result.returncode != 0:
|
|
423
|
+
return {"error": (False, "Failed to build MCP Gateway")}
|
|
424
|
+
|
|
425
|
+
# Determine which hosts to configure
|
|
426
|
+
if hosts:
|
|
427
|
+
target_hosts = hosts
|
|
428
|
+
else:
|
|
429
|
+
target_hosts = detect_installed_hosts()
|
|
430
|
+
# Always include project-local configs
|
|
431
|
+
target_hosts.extend(["cursor", "vscode", "windsurf"])
|
|
432
|
+
target_hosts = list(set(target_hosts))
|
|
433
|
+
|
|
434
|
+
# Configure each host
|
|
435
|
+
configurators = {
|
|
436
|
+
"claude_desktop": configure_claude_desktop,
|
|
437
|
+
"cursor": configure_cursor,
|
|
438
|
+
"vscode": configure_vscode,
|
|
439
|
+
"windsurf": configure_windsurf,
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
for host_id in target_hosts:
|
|
443
|
+
if host_id not in configurators:
|
|
444
|
+
results[host_id] = (False, f"Unknown host: {host_id}")
|
|
445
|
+
continue
|
|
446
|
+
|
|
447
|
+
print(f"\n🔧 Configuring {SUPPORTED_HOSTS[host_id]['name']}...")
|
|
448
|
+
success, message = configurators[host_id](
|
|
449
|
+
project_root, mcp_server_path, kit_path, dry_run
|
|
450
|
+
)
|
|
451
|
+
results[host_id] = (success, message)
|
|
452
|
+
|
|
453
|
+
status = "✅" if success else "❌"
|
|
454
|
+
print(f" {status} {message}")
|
|
455
|
+
|
|
456
|
+
return results
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
# ============================================================================
|
|
460
|
+
# CLI Entry Point
|
|
461
|
+
# ============================================================================
|
|
462
|
+
|
|
463
|
+
def main():
|
|
464
|
+
parser = argparse.ArgumentParser(
|
|
465
|
+
description="Auto-configure AI hosts for Agent Kit MCP"
|
|
466
|
+
)
|
|
467
|
+
parser.add_argument(
|
|
468
|
+
"--project-root",
|
|
469
|
+
default=".",
|
|
470
|
+
help="Project root directory",
|
|
471
|
+
)
|
|
472
|
+
parser.add_argument(
|
|
473
|
+
"--list",
|
|
474
|
+
action="store_true",
|
|
475
|
+
help="List detected AI hosts only",
|
|
476
|
+
)
|
|
477
|
+
parser.add_argument(
|
|
478
|
+
"--dry-run",
|
|
479
|
+
action="store_true",
|
|
480
|
+
help="Show what would be done without making changes",
|
|
481
|
+
)
|
|
482
|
+
parser.add_argument(
|
|
483
|
+
"--hosts",
|
|
484
|
+
nargs="+",
|
|
485
|
+
choices=list(SUPPORTED_HOSTS.keys()),
|
|
486
|
+
help="Specific hosts to configure",
|
|
487
|
+
)
|
|
488
|
+
parser.add_argument(
|
|
489
|
+
"--copy-config",
|
|
490
|
+
action="store_true",
|
|
491
|
+
help="Copy config to clipboard for manual setup",
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
args = parser.parse_args()
|
|
495
|
+
project_root = Path(args.project_root).resolve()
|
|
496
|
+
|
|
497
|
+
print("🤖 Agent Kit - AI Host Auto-Configuration")
|
|
498
|
+
print(f"📁 Project: {project_root}")
|
|
499
|
+
print(f"💻 OS: {get_os()}")
|
|
500
|
+
|
|
501
|
+
# List mode
|
|
502
|
+
if args.list:
|
|
503
|
+
print("\n📋 Detected AI Hosts:")
|
|
504
|
+
installed = detect_installed_hosts()
|
|
505
|
+
for host_id, host in SUPPORTED_HOSTS.items():
|
|
506
|
+
status = "✅ Installed" if host_id in installed else "❌ Not found"
|
|
507
|
+
print(f" - {host['name']}: {status}")
|
|
508
|
+
return 0
|
|
509
|
+
|
|
510
|
+
# Copy config to clipboard mode
|
|
511
|
+
if args.copy_config:
|
|
512
|
+
mcp_server_path = project_root / ".agent" / "mcp-gateway" / "dist" / "index.js"
|
|
513
|
+
config = {
|
|
514
|
+
"mcpServers": {
|
|
515
|
+
"agent-kit": {
|
|
516
|
+
"command": "node",
|
|
517
|
+
"args": [str(mcp_server_path)],
|
|
518
|
+
"env": {
|
|
519
|
+
"PROJECT_ROOT": str(project_root),
|
|
520
|
+
},
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
config_json = json.dumps(config, indent=2)
|
|
525
|
+
|
|
526
|
+
if copy_to_clipboard(config_json):
|
|
527
|
+
print("\n✅ Config copied to clipboard!")
|
|
528
|
+
print("\n📋 Paste this into your AI host's MCP configuration:")
|
|
529
|
+
print(config_json)
|
|
530
|
+
else:
|
|
531
|
+
print("\n⚠️ Could not copy to clipboard. Here's the config:")
|
|
532
|
+
print(config_json)
|
|
533
|
+
return 0
|
|
534
|
+
|
|
535
|
+
# Normal configuration mode
|
|
536
|
+
results = setup_hosts(
|
|
537
|
+
project_root,
|
|
538
|
+
hosts=args.hosts,
|
|
539
|
+
dry_run=args.dry_run,
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
# Summary
|
|
543
|
+
print("\n" + "=" * 50)
|
|
544
|
+
print("📊 Configuration Summary:")
|
|
545
|
+
success_count = sum(1 for success, _ in results.values() if success)
|
|
546
|
+
total_count = len(results)
|
|
547
|
+
print(f" ✅ {success_count}/{total_count} hosts configured successfully")
|
|
548
|
+
|
|
549
|
+
if success_count > 0:
|
|
550
|
+
print("\n🎉 Setup complete! Your AI hosts are now connected to Agent Kit.")
|
|
551
|
+
print(" Restart your AI host to apply changes.")
|
|
552
|
+
|
|
553
|
+
return 0 if success_count == total_count else 1
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
if __name__ == "__main__":
|
|
557
|
+
sys.exit(main())
|