@softspark/ai-toolkit 4.29.2 → 4.30.2
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 +82 -0
- package/README.md +44 -18
- package/app/.claude-plugin/plugin.json +1 -1
- package/app/ARCHITECTURE.md +2 -2
- package/app/mcp-templates/README.md +7 -2
- package/app/mcp-templates/rag-mcp-legal.json +11 -0
- package/app/mcp-templates/rag-mcp.json +11 -0
- package/app/surface.json +1 -0
- package/benchmarks/ecosystem-doctor-snapshot.json +29 -17
- package/bin/ai-toolkit.js +8 -0
- package/kb/history/completed/dsh-integration-plan-superseded.md +322 -0
- package/kb/history/completed/dsh-native-install-target-plan.md +331 -0
- package/kb/procedures/ecosystem-sync-sop.md +7 -5
- package/kb/procedures/maintenance-sop.md +1 -1
- package/kb/procedures/release-verification-sop.md +35 -5
- package/kb/reference/architecture-overview.md +24 -5
- package/kb/reference/cli-reference.md +1 -1
- package/kb/reference/dsh-compatibility.md +183 -0
- package/kb/reference/manifest-install.md +112 -5
- package/kb/reference/mcp-templates.md +11 -4
- package/kb/reference/plugin-pack-conventions.md +35 -18
- package/kb/reference/supported-tools-registry.md +30 -6
- package/llms-full.txt +1110 -50
- package/llms.txt +3 -0
- package/manifest.json +2 -2
- package/package.json +2 -2
- package/scripts/codex_skill_adapter.py +673 -34
- package/scripts/config_resolver.py +80 -14
- package/scripts/doctor.py +98 -20
- package/scripts/ecosystem_tools.json +51 -1
- package/scripts/generate_codex_skills.py +22 -20
- package/scripts/install.py +30 -13
- package/scripts/install_steps/ai_tools.py +97 -33
- package/scripts/install_steps/dsh.py +5063 -0
- package/scripts/install_steps/install_state.py +1645 -57
- package/scripts/mcp_editors.py +5 -2
- package/scripts/plugin.py +2495 -163
- package/scripts/plugin_mcp.py +279 -0
- package/scripts/plugin_rules.py +389 -0
- package/scripts/plugin_schema.py +139 -23
- package/scripts/uninstall.py +47 -4
- package/scripts/validate.py +421 -0
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"""Install global and project-local AI tool configs."""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
+
from dataclasses import dataclass
|
|
8
9
|
import os
|
|
9
10
|
import shutil
|
|
10
11
|
import subprocess
|
|
@@ -13,8 +14,10 @@ from pathlib import Path
|
|
|
13
14
|
from _common import app_dir, inject_section, toolkit_dir
|
|
14
15
|
from codex_skill_adapter import (
|
|
15
16
|
cleanup_codex_skills,
|
|
16
|
-
|
|
17
|
+
managed_skill_surface_transaction,
|
|
18
|
+
skill_surface_owners,
|
|
17
19
|
sync_codex_skill,
|
|
20
|
+
sync_dsh_skill,
|
|
18
21
|
unmanaged_codex_skill_names,
|
|
19
22
|
)
|
|
20
23
|
from mcp_editors import sync_project_mcp_to_editors
|
|
@@ -751,11 +754,40 @@ def run_script(script_name: str, *args: str, capture: bool = False) -> str:
|
|
|
751
754
|
return result.stdout if capture else ""
|
|
752
755
|
|
|
753
756
|
|
|
754
|
-
|
|
757
|
+
@dataclass(frozen=True, slots=True)
|
|
758
|
+
class EditorCapability:
|
|
759
|
+
"""Selection policy for one ``--editors`` target."""
|
|
760
|
+
|
|
761
|
+
include_in_all: bool = True
|
|
762
|
+
requires_local: bool = False
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
EDITOR_CAPABILITIES = {
|
|
766
|
+
"copilot": EditorCapability(),
|
|
767
|
+
"cursor": EditorCapability(),
|
|
768
|
+
"windsurf": EditorCapability(),
|
|
769
|
+
"cline": EditorCapability(),
|
|
770
|
+
"roo": EditorCapability(),
|
|
771
|
+
"aider": EditorCapability(),
|
|
772
|
+
"augment": EditorCapability(),
|
|
773
|
+
"antigravity": EditorCapability(),
|
|
774
|
+
"codex": EditorCapability(),
|
|
775
|
+
"gemini": EditorCapability(),
|
|
776
|
+
"opencode": EditorCapability(),
|
|
777
|
+
"dsh": EditorCapability(include_in_all=False, requires_local=True),
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
SELECTABLE_EDITORS = list(EDITOR_CAPABILITIES)
|
|
755
781
|
ALL_EDITORS = [
|
|
756
|
-
|
|
757
|
-
|
|
782
|
+
editor
|
|
783
|
+
for editor, capability in EDITOR_CAPABILITIES.items()
|
|
784
|
+
if capability.include_in_all
|
|
758
785
|
]
|
|
786
|
+
LOCAL_ONLY_EDITORS = {
|
|
787
|
+
editor
|
|
788
|
+
for editor, capability in EDITOR_CAPABILITIES.items()
|
|
789
|
+
if capability.requires_local
|
|
790
|
+
}
|
|
759
791
|
|
|
760
792
|
# Map of project files/dirs → editor names for auto-detection
|
|
761
793
|
_EDITOR_MARKERS: dict[str, str] = {
|
|
@@ -812,6 +844,10 @@ def _detect_editors(cwd: Path) -> list[str]:
|
|
|
812
844
|
# The canonical workspace Antigravity pointer also lives in
|
|
813
845
|
# .agents/skills/; only materialized skills indicate Codex.
|
|
814
846
|
continue
|
|
847
|
+
if marker == ".agents/skills":
|
|
848
|
+
owners = skill_surface_owners(p)
|
|
849
|
+
if owners is not None and "codex" not in owners:
|
|
850
|
+
continue
|
|
815
851
|
found.add(editor)
|
|
816
852
|
return sorted(found)
|
|
817
853
|
|
|
@@ -1234,7 +1270,8 @@ def _install_local_dry_run(reset: bool, editors: list[str] | None = None,
|
|
|
1234
1270
|
print(" Would generate: .agents/skills/ Codex skills")
|
|
1235
1271
|
if codex_skills:
|
|
1236
1272
|
print(" Would refresh: .agents/skills/ via --codex-skills")
|
|
1237
|
-
|
|
1273
|
+
if "dsh" in eds:
|
|
1274
|
+
print(" Would generate: .agents/skills/ DSH-compatible managed skills")
|
|
1238
1275
|
if not eds:
|
|
1239
1276
|
print(" No editors selected (use --editors <list> or --editors all)")
|
|
1240
1277
|
|
|
@@ -1330,42 +1367,53 @@ def _create_local_settings(cwd: Path, reset: bool) -> None:
|
|
|
1330
1367
|
print(" Kept: .claude/settings.local.json (already exists)")
|
|
1331
1368
|
|
|
1332
1369
|
|
|
1333
|
-
def
|
|
1334
|
-
"""Install all skills to
|
|
1370
|
+
def _install_agent_skills(cwd: Path, *, target: str) -> None:
|
|
1371
|
+
"""Install all skills to the managed ``.agents/skills`` surface.
|
|
1335
1372
|
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
with Codex-native delegation guidance.
|
|
1373
|
+
Codex-only installs retain Codex-specific wrappers. DSH-only and shared
|
|
1374
|
+
Codex/DSH installs use portable wrappers that retain DSH invocation fields.
|
|
1339
1375
|
"""
|
|
1376
|
+
if target not in {"codex", "dsh", "shared"}:
|
|
1377
|
+
raise ValueError(f"Unsupported agent skill target: {target}")
|
|
1340
1378
|
skills_src = app_dir / "skills"
|
|
1341
1379
|
if not skills_src.is_dir():
|
|
1342
1380
|
return
|
|
1343
1381
|
|
|
1344
|
-
skills_dst = prepare_codex_skills_dir(cwd)
|
|
1345
|
-
user_names = unmanaged_codex_skill_names(skills_dst, skills_src)
|
|
1346
|
-
|
|
1347
1382
|
linked = 0
|
|
1348
1383
|
adapted = 0
|
|
1349
1384
|
skipped = 0
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1385
|
+
with managed_skill_surface_transaction(cwd, skills_src) as transaction:
|
|
1386
|
+
skills_dst = transaction.skills_dst
|
|
1387
|
+
user_names = unmanaged_codex_skill_names(skills_dst, skills_src)
|
|
1388
|
+
|
|
1389
|
+
for skill_dir in sorted(skills_src.iterdir()):
|
|
1390
|
+
if not skill_dir.is_dir() or skill_dir.name.startswith("_"):
|
|
1391
|
+
continue
|
|
1392
|
+
skill_md = skill_dir / "SKILL.md"
|
|
1393
|
+
if not skill_md.is_file():
|
|
1394
|
+
continue
|
|
1395
|
+
if skill_dir.name in user_names:
|
|
1396
|
+
skipped += 1
|
|
1397
|
+
continue
|
|
1398
|
+
|
|
1399
|
+
if target == "codex":
|
|
1400
|
+
mode = sync_codex_skill(skill_dir, skills_dst)
|
|
1401
|
+
else:
|
|
1402
|
+
mode = sync_dsh_skill(
|
|
1403
|
+
skill_dir,
|
|
1404
|
+
skills_dst,
|
|
1405
|
+
shared=target == "shared",
|
|
1406
|
+
)
|
|
1407
|
+
if mode == "linked":
|
|
1408
|
+
linked += 1
|
|
1409
|
+
elif mode == "adapted":
|
|
1410
|
+
adapted += 1
|
|
1411
|
+
else:
|
|
1412
|
+
skipped += 1
|
|
1367
1413
|
|
|
1368
|
-
|
|
1414
|
+
cleanup_codex_skills(skills_dst, skills_src, user_names)
|
|
1415
|
+
owners = {"codex", "dsh"} if target == "shared" else {target}
|
|
1416
|
+
transaction.commit(owners)
|
|
1369
1417
|
|
|
1370
1418
|
print(
|
|
1371
1419
|
f" Installed: {linked + adapted} skills to .agents/skills/"
|
|
@@ -1373,6 +1421,16 @@ def _install_codex_skills(cwd: Path) -> None:
|
|
|
1373
1421
|
)
|
|
1374
1422
|
|
|
1375
1423
|
|
|
1424
|
+
def _install_codex_skills(cwd: Path) -> None:
|
|
1425
|
+
"""Install the Codex-specific managed skill surface."""
|
|
1426
|
+
_install_agent_skills(cwd, target="codex")
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
def _install_dsh_skills(cwd: Path, *, shared: bool = False) -> None:
|
|
1430
|
+
"""Install DSH-portable skills, optionally shared with Codex."""
|
|
1431
|
+
_install_agent_skills(cwd, target="shared" if shared else "dsh")
|
|
1432
|
+
|
|
1433
|
+
|
|
1376
1434
|
def _install_codex_agents(cwd: Path, *, config_root: Path | None = None) -> None:
|
|
1377
1435
|
"""Generate native Codex custom-agent TOML files."""
|
|
1378
1436
|
from generate_codex_agents import generate as gen_codex_agents
|
|
@@ -1581,13 +1639,19 @@ def _create_local_ai_tool_configs(cwd: Path, rules_dir: Path,
|
|
|
1581
1639
|
print(" Created: .codex/hooks.json")
|
|
1582
1640
|
# .codex/agents/ -- native Codex custom-agent definitions
|
|
1583
1641
|
_install_codex_agents(cwd)
|
|
1584
|
-
|
|
1642
|
+
if {"codex", "dsh"}.issubset(eds):
|
|
1643
|
+
# The clients share one discovery directory. A joint install therefore
|
|
1644
|
+
# converges on one portable rendering instead of depending on list order.
|
|
1645
|
+
_install_dsh_skills(cwd, shared=True)
|
|
1646
|
+
elif "codex" in eds:
|
|
1585
1647
|
_install_codex_skills(cwd)
|
|
1586
1648
|
# --codex-skills explicitly re-runs the same Codex skill sync path.
|
|
1587
|
-
# Codex upstream discovers skills from .agents/skills/, not .codex/skills/.
|
|
1588
1649
|
if codex_skills:
|
|
1589
1650
|
_try_generator("generate_codex_skills", cwd,
|
|
1590
1651
|
enable_codex_skills=True)
|
|
1652
|
+
elif "dsh" in eds:
|
|
1653
|
+
# DSH receives only the shared skill surface, without Codex config.
|
|
1654
|
+
_install_dsh_skills(cwd)
|
|
1591
1655
|
|
|
1592
1656
|
if "gemini" in eds:
|
|
1593
1657
|
# GEMINI.md — marker injection from the shared generator output
|