feat: expand platform coverage with 8 new adaptors, 7 new CLI agents, and OpenCode skill tools

Phase 1 - OpenCode Integration:
- Add OpenCodeAdaptor with directory-based packaging and dual-format YAML frontmatter
- Kebab-case name validation matching OpenCode's regex spec

Phase 2 - OpenAI-Compatible LLM Platforms:
- Extract OpenAICompatibleAdaptor base class from MiniMax (shared format/package/upload/enhance)
- Refactor MiniMax to ~20 lines of constants inheriting from base
- Add 6 new LLM adaptors: Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI
- All use OpenAI-compatible API with platform-specific constants

Phase 3 - CLI Agent Expansion:
- Add 7 new install-agent paths: roo, cline, aider, bolt, kilo, continue, kimi-code
- Total agents: 11 -> 18

Phase 4 - Advanced Features:
- OpenCode skill splitter (auto-split large docs into focused sub-skills with router)
- Bi-directional skill format converter (import/export between OpenCode and any platform)
- GitHub Actions template for automated skill updates

Totals: 12 --target platforms, 18 --agent paths, 2915 tests passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
yusyus
2026-03-21 20:31:51 +03:00
parent 1d3d7389d7
commit cd7b322b5e
24 changed files with 2482 additions and 499 deletions

View File

@@ -66,17 +66,38 @@ class TestAgentPathMapping:
get_agent_path("invalid_agent")
def test_get_available_agents(self):
"""Test that all 11 agents are listed."""
"""Test that all 18 agents are listed."""
agents = get_available_agents()
assert len(agents) == 11
assert len(agents) == 18
assert "claude" in agents
assert "cursor" in agents
assert "vscode" in agents
assert "amp" in agents
assert "goose" in agents
assert "neovate" in agents
assert "roo" in agents
assert "cline" in agents
assert "aider" in agents
assert "bolt" in agents
assert "kilo" in agents
assert "continue" in agents
assert "kimi-code" in agents
assert sorted(agents) == agents # Should be sorted
def test_new_agents_project_relative(self):
"""Test that project-relative new agents resolve correctly."""
for agent in ["roo", "cline", "bolt", "kilo"]:
path = get_agent_path(agent)
assert path.is_absolute()
assert str(Path.cwd()) in str(path)
def test_new_agents_global(self):
"""Test that global new agents resolve to home directory."""
for agent in ["aider", "continue", "kimi-code"]:
path = get_agent_path(agent)
assert path.is_absolute()
assert str(path).startswith(str(Path.home()))
def test_agent_path_case_insensitive(self):
"""Test that agent names are case-insensitive."""
path_lower = get_agent_path("claude")
@@ -340,7 +361,7 @@ class TestInstallToAllAgents:
shutil.rmtree(self.tmpdir, ignore_errors=True)
def test_install_to_all_success(self):
"""Test that install_to_all_agents attempts all 11 agents."""
"""Test that install_to_all_agents attempts all 18 agents."""
with tempfile.TemporaryDirectory() as agent_tmpdir:
def mock_get_agent_path(agent_name, _project_root=None):
@@ -352,7 +373,7 @@ class TestInstallToAllAgents:
):
results = install_to_all_agents(self.skill_dir, force=True)
assert len(results) == 11
assert len(results) == 18
assert "claude" in results
assert "cursor" in results
@@ -362,7 +383,7 @@ class TestInstallToAllAgents:
results = install_to_all_agents(self.skill_dir, dry_run=True)
# All should succeed in dry-run mode
assert len(results) == 11
assert len(results) == 18
for _agent_name, (success, message) in results.items():
assert success is True
assert "DRY RUN" in message
@@ -399,7 +420,7 @@ class TestInstallToAllAgents:
results = install_to_all_agents(self.skill_dir, dry_run=True)
assert isinstance(results, dict)
assert len(results) == 11
assert len(results) == 18
for agent_name, (success, message) in results.items():
assert isinstance(success, bool)