@softspark/ai-toolkit 2.0.2 → 2.1.1
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/CHANGELOG.md +49 -0
- package/README.md +143 -774
- package/app/ARCHITECTURE.md +1 -1
- package/app/plugins/README.md +6 -2
- package/app/skills/plugin-creator/SKILL.md +3 -4
- package/bin/ai-toolkit.js +34 -10
- package/kb/procedures/maintenance-sop.md +64 -16
- package/kb/procedures/release-preparation-sop.md +4 -2
- package/kb/procedures/release-verification-sop.md +15 -13
- package/kb/reference/architecture-overview.md +44 -5
- package/kb/reference/claude-ecosystem-expansion-foundations.md +4 -4
- package/kb/reference/cli-reference.md +135 -0
- package/kb/reference/codex-cli-compatibility.md +136 -0
- package/kb/reference/comparison.md +29 -0
- package/kb/reference/extension-api.md +23 -6
- package/kb/reference/global-install-model.md +62 -5
- package/kb/reference/mcp-editor-compatibility.md +62 -0
- package/kb/reference/mcp-templates.md +32 -6
- package/kb/reference/plugin-pack-conventions.md +22 -21
- package/kb/reference/skills-catalog.md +27 -5
- package/kb/reference/unique-features.md +213 -0
- package/llms-full.txt +903 -84
- package/llms.txt +5 -0
- package/package.json +6 -5
- package/scripts/codex_skill_adapter.py +295 -0
- package/scripts/dir_rules_shared.py +46 -7
- package/scripts/generate_agents_md.py +13 -0
- package/scripts/generate_antigravity.py +2 -1
- package/scripts/generate_augment_rules.py +2 -1
- package/scripts/generate_cline_rules.py +13 -3
- package/scripts/generate_codex.py +105 -0
- package/scripts/generate_codex_hooks.py +78 -0
- package/scripts/generate_codex_rules.py +52 -0
- package/scripts/generate_cursor_mdc.py +2 -1
- package/scripts/generate_roo_rules.py +2 -1
- package/scripts/generate_windsurf_rules.py +2 -1
- package/scripts/generator_base.py +15 -0
- package/scripts/install_steps/ai_tools.py +83 -4
- package/scripts/mcp_editors.py +340 -0
- package/scripts/mcp_manager.py +125 -13
- package/scripts/plugin.py +745 -301
- package/scripts/plugin_schema.py +16 -1
package/scripts/mcp_manager.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""MCP template manager -- add, remove,
|
|
2
|
+
"""MCP template manager -- add, remove, inspect, and install MCP configs.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
5
|
mcp_manager.py list List available templates
|
|
6
|
+
mcp_manager.py editors List native editor MCP adapters
|
|
6
7
|
mcp_manager.py show <name> Show template details
|
|
7
8
|
mcp_manager.py add <name> [names..] [--target <path>] Add to .mcp.json
|
|
9
|
+
mcp_manager.py install --editor <name[,..]> [--scope project|global] [--target <path>] [name..]
|
|
8
10
|
mcp_manager.py remove <name> Remove from .mcp.json
|
|
9
11
|
"""
|
|
10
12
|
from __future__ import annotations
|
|
@@ -13,6 +15,14 @@ import json
|
|
|
13
15
|
import sys
|
|
14
16
|
from pathlib import Path
|
|
15
17
|
|
|
18
|
+
from mcp_editors import (
|
|
19
|
+
editor_rows,
|
|
20
|
+
install_servers,
|
|
21
|
+
load_project_mcp_servers,
|
|
22
|
+
remove_servers,
|
|
23
|
+
supported_editors,
|
|
24
|
+
)
|
|
25
|
+
|
|
16
26
|
TOOLKIT_DIR = Path(__file__).resolve().parent.parent
|
|
17
27
|
TEMPLATES_DIR = TOOLKIT_DIR / "app" / "mcp-templates"
|
|
18
28
|
MCP_CONFIG_NAME = ".mcp.json"
|
|
@@ -85,6 +95,20 @@ def cmd_list() -> None:
|
|
|
85
95
|
print(f"Add with: ai-toolkit mcp add <name>")
|
|
86
96
|
|
|
87
97
|
|
|
98
|
+
def cmd_editors() -> None:
|
|
99
|
+
"""List editors with native MCP config adapters."""
|
|
100
|
+
rows = editor_rows()
|
|
101
|
+
print(f"{'Editor':<12} {'Scope':<18} {'Project Path':<28} {'Global Path'}")
|
|
102
|
+
print("-" * 110)
|
|
103
|
+
for row in rows:
|
|
104
|
+
print(
|
|
105
|
+
f"{row['name']:<12} {row['scope']:<18} "
|
|
106
|
+
f"{row['project_path']:<28} {row['global_path']}"
|
|
107
|
+
)
|
|
108
|
+
print()
|
|
109
|
+
print(f"{len(rows)} editors supported")
|
|
110
|
+
|
|
111
|
+
|
|
88
112
|
def cmd_show(name: str) -> None:
|
|
89
113
|
"""Show details of a specific template."""
|
|
90
114
|
data = load_template(name)
|
|
@@ -132,14 +156,84 @@ def cmd_add(names: list[str], target_dir: Path) -> None:
|
|
|
132
156
|
print(f"Added: {', '.join(added)}")
|
|
133
157
|
|
|
134
158
|
|
|
135
|
-
def
|
|
159
|
+
def cmd_install(
|
|
160
|
+
names: list[str],
|
|
161
|
+
editors: list[str],
|
|
162
|
+
*,
|
|
163
|
+
target_dir: Path | None,
|
|
164
|
+
scope: str | None,
|
|
165
|
+
) -> None:
|
|
166
|
+
"""Install MCP templates into native editor config files."""
|
|
167
|
+
if not editors:
|
|
168
|
+
print("Error: install requires --editor <name[,..]>", file=sys.stderr)
|
|
169
|
+
print(
|
|
170
|
+
f"Supported editors: {', '.join(supported_editors())}",
|
|
171
|
+
file=sys.stderr,
|
|
172
|
+
)
|
|
173
|
+
sys.exit(1)
|
|
174
|
+
|
|
175
|
+
eff_scope = scope or ("project" if target_dir is not None or not names else "global")
|
|
176
|
+
if eff_scope == "project":
|
|
177
|
+
project_dir = target_dir or Path.cwd()
|
|
178
|
+
if names:
|
|
179
|
+
cmd_add(names, project_dir)
|
|
180
|
+
servers = {}
|
|
181
|
+
for name in names:
|
|
182
|
+
servers.update(load_template(name).get("mcpServers", {}))
|
|
183
|
+
else:
|
|
184
|
+
servers = load_project_mcp_servers(project_dir)
|
|
185
|
+
updated = install_servers(
|
|
186
|
+
editors,
|
|
187
|
+
servers,
|
|
188
|
+
scope="project",
|
|
189
|
+
project_dir=project_dir,
|
|
190
|
+
)
|
|
191
|
+
else:
|
|
192
|
+
if not names:
|
|
193
|
+
print(
|
|
194
|
+
"Error: global install requires at least one template name.",
|
|
195
|
+
file=sys.stderr,
|
|
196
|
+
)
|
|
197
|
+
sys.exit(1)
|
|
198
|
+
servers = {}
|
|
199
|
+
for name in names:
|
|
200
|
+
servers.update(load_template(name).get("mcpServers", {}))
|
|
201
|
+
updated = install_servers(editors, servers, scope="global")
|
|
202
|
+
|
|
203
|
+
for path in updated:
|
|
204
|
+
print(f"Updated: {path}")
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def cmd_remove(name: str, target_dir: Path | None, *, editors: list[str], scope: str | None) -> None:
|
|
136
208
|
"""Remove an MCP server from .mcp.json."""
|
|
137
|
-
|
|
209
|
+
if editors:
|
|
210
|
+
eff_scope = scope or ("project" if target_dir else "global")
|
|
211
|
+
if eff_scope == "project":
|
|
212
|
+
project_dir = target_dir or Path.cwd()
|
|
213
|
+
config_path = project_dir / MCP_CONFIG_NAME
|
|
214
|
+
if config_path.is_file():
|
|
215
|
+
config = load_mcp_config(project_dir)
|
|
216
|
+
config.get("mcpServers", {}).pop(name, None)
|
|
217
|
+
write_mcp_config(project_dir, config)
|
|
218
|
+
updated = remove_servers(
|
|
219
|
+
editors,
|
|
220
|
+
[name],
|
|
221
|
+
scope="project",
|
|
222
|
+
project_dir=project_dir,
|
|
223
|
+
)
|
|
224
|
+
else:
|
|
225
|
+
updated = remove_servers(editors, [name], scope="global")
|
|
226
|
+
for path in updated:
|
|
227
|
+
print(f"Updated: {path}")
|
|
228
|
+
print(f"Removed: {name}")
|
|
229
|
+
return
|
|
230
|
+
|
|
231
|
+
config_path = (target_dir or Path.cwd()) / MCP_CONFIG_NAME
|
|
138
232
|
if not config_path.is_file():
|
|
139
233
|
print(f"Error: {config_path} not found.", file=sys.stderr)
|
|
140
234
|
sys.exit(1)
|
|
141
235
|
|
|
142
|
-
config = load_mcp_config(target_dir)
|
|
236
|
+
config = load_mcp_config(target_dir or Path.cwd())
|
|
143
237
|
servers = config.get("mcpServers", {})
|
|
144
238
|
|
|
145
239
|
if name not in servers:
|
|
@@ -148,7 +242,7 @@ def cmd_remove(name: str, target_dir: Path) -> None:
|
|
|
148
242
|
sys.exit(1)
|
|
149
243
|
|
|
150
244
|
del servers[name]
|
|
151
|
-
write_mcp_config(target_dir, config)
|
|
245
|
+
write_mcp_config(target_dir or Path.cwd(), config)
|
|
152
246
|
print(f"Removed: {name}")
|
|
153
247
|
|
|
154
248
|
|
|
@@ -156,19 +250,27 @@ def cmd_remove(name: str, target_dir: Path) -> None:
|
|
|
156
250
|
# Argument parsing
|
|
157
251
|
# ---------------------------------------------------------------------------
|
|
158
252
|
|
|
159
|
-
def
|
|
160
|
-
"""Extract
|
|
161
|
-
target_dir =
|
|
253
|
+
def parse_options(args: list[str]) -> tuple[list[str], Path | None, list[str], str | None]:
|
|
254
|
+
"""Extract common MCP CLI options."""
|
|
255
|
+
target_dir: Path | None = None
|
|
256
|
+
editors: list[str] = []
|
|
257
|
+
scope: str | None = None
|
|
162
258
|
remaining = []
|
|
163
259
|
i = 0
|
|
164
260
|
while i < len(args):
|
|
165
261
|
if args[i] == "--target" and i + 1 < len(args):
|
|
166
262
|
target_dir = Path(args[i + 1]).resolve()
|
|
167
263
|
i += 2
|
|
264
|
+
elif args[i] == "--editor" and i + 1 < len(args):
|
|
265
|
+
editors = [e.strip() for e in args[i + 1].split(",") if e.strip()]
|
|
266
|
+
i += 2
|
|
267
|
+
elif args[i] == "--scope" and i + 1 < len(args):
|
|
268
|
+
scope = args[i + 1]
|
|
269
|
+
i += 2
|
|
168
270
|
else:
|
|
169
271
|
remaining.append(args[i])
|
|
170
272
|
i += 1
|
|
171
|
-
return remaining, target_dir
|
|
273
|
+
return remaining, target_dir, editors, scope
|
|
172
274
|
|
|
173
275
|
|
|
174
276
|
def main() -> None:
|
|
@@ -182,20 +284,30 @@ def main() -> None:
|
|
|
182
284
|
|
|
183
285
|
if subcmd == "list":
|
|
184
286
|
cmd_list()
|
|
287
|
+
elif subcmd == "editors":
|
|
288
|
+
cmd_editors()
|
|
185
289
|
elif subcmd == "show":
|
|
186
290
|
if not rest:
|
|
187
291
|
print("Usage: ai-toolkit mcp show <name>", file=sys.stderr)
|
|
188
292
|
sys.exit(1)
|
|
189
293
|
cmd_show(rest[0])
|
|
190
294
|
elif subcmd == "add":
|
|
191
|
-
names, target_dir =
|
|
192
|
-
cmd_add(names, target_dir)
|
|
295
|
+
names, target_dir, _editors, _scope = parse_options(rest)
|
|
296
|
+
cmd_add(names, target_dir or Path.cwd())
|
|
297
|
+
elif subcmd == "install":
|
|
298
|
+
names, target_dir, editors, scope = parse_options(rest)
|
|
299
|
+
cmd_install(names, editors, target_dir=target_dir, scope=scope)
|
|
193
300
|
elif subcmd == "remove":
|
|
194
|
-
names, target_dir =
|
|
301
|
+
names, target_dir, editors, scope = parse_options(rest)
|
|
195
302
|
if not names:
|
|
196
303
|
print("Usage: ai-toolkit mcp remove <name>", file=sys.stderr)
|
|
197
304
|
sys.exit(1)
|
|
198
|
-
cmd_remove(
|
|
305
|
+
cmd_remove(
|
|
306
|
+
names[0],
|
|
307
|
+
target_dir if editors else (target_dir or Path.cwd()),
|
|
308
|
+
editors=editors,
|
|
309
|
+
scope=scope,
|
|
310
|
+
)
|
|
199
311
|
else:
|
|
200
312
|
print(f"Unknown subcommand: {subcmd}", file=sys.stderr)
|
|
201
313
|
print(__doc__)
|