Pavel/add tabnine cli support (#1503)

* feat: add Tabnine CLI agent support

Tabnine CLI is a Gemini fork that uses TOML commands with the
.tabnine/agent/ directory structure and TABNINE.md context files.

Changes:
- Add 'tabnine' to AGENT_CONFIG in __init__.py
- Update release scripts (bash + PowerShell) for TOML command generation
- Update agent context scripts (bash + PowerShell)
- Add to GitHub release packages
- Update README.md and AGENTS.md documentation
- Bump version to 0.1.14
- Add 8 new tests for cross-file consistency

* fix: add missing generic to agent-context script usage string
This commit is contained in:
Pavel-tabnine
2026-03-09 21:04:02 +02:00
committed by GitHub
parent 3033834d64
commit 1df24f1953
13 changed files with 135 additions and 17 deletions

View File

@@ -97,3 +97,70 @@ class TestAgentConfigConsistency:
assert "kiro-cli" in pwsh_text
assert "Amazon Q Developer CLI" not in bash_text
assert "Amazon Q Developer CLI" not in pwsh_text
# --- Tabnine CLI consistency checks ---
def test_runtime_config_includes_tabnine(self):
"""AGENT_CONFIG should include tabnine with correct folder and subdir."""
assert "tabnine" in AGENT_CONFIG
assert AGENT_CONFIG["tabnine"]["folder"] == ".tabnine/agent/"
assert AGENT_CONFIG["tabnine"]["commands_subdir"] == "commands"
assert AGENT_CONFIG["tabnine"]["requires_cli"] is True
assert AGENT_CONFIG["tabnine"]["install_url"] is not None
def test_extension_registrar_includes_tabnine(self):
"""CommandRegistrar.AGENT_CONFIGS should include tabnine with correct TOML config."""
from specify_cli.extensions import CommandRegistrar
assert "tabnine" in CommandRegistrar.AGENT_CONFIGS
cfg = CommandRegistrar.AGENT_CONFIGS["tabnine"]
assert cfg["dir"] == ".tabnine/agent/commands"
assert cfg["format"] == "toml"
assert cfg["args"] == "{{args}}"
assert cfg["extension"] == ".toml"
def test_release_agent_lists_include_tabnine(self):
"""Bash and PowerShell release scripts should include tabnine in agent lists."""
sh_text = (REPO_ROOT / ".github" / "workflows" / "scripts" / "create-release-packages.sh").read_text(encoding="utf-8")
ps_text = (REPO_ROOT / ".github" / "workflows" / "scripts" / "create-release-packages.ps1").read_text(encoding="utf-8")
sh_match = re.search(r"ALL_AGENTS=\(([^)]*)\)", sh_text)
assert sh_match is not None
sh_agents = sh_match.group(1).split()
ps_match = re.search(r"\$AllAgents = @\(([^)]*)\)", ps_text)
assert ps_match is not None
ps_agents = re.findall(r"'([^']+)'", ps_match.group(1))
assert "tabnine" in sh_agents
assert "tabnine" in ps_agents
def test_release_scripts_generate_tabnine_toml_commands(self):
"""Release scripts should generate TOML commands for tabnine in .tabnine/agent/commands."""
sh_text = (REPO_ROOT / ".github" / "workflows" / "scripts" / "create-release-packages.sh").read_text(encoding="utf-8")
ps_text = (REPO_ROOT / ".github" / "workflows" / "scripts" / "create-release-packages.ps1").read_text(encoding="utf-8")
assert ".tabnine/agent/commands" in sh_text
assert ".tabnine/agent/commands" in ps_text
assert re.search(r"'tabnine'\s*\{.*?\.tabnine/agent/commands", ps_text, re.S) is not None
def test_github_release_includes_tabnine_packages(self):
"""GitHub release script should include tabnine template packages."""
gh_release_text = (REPO_ROOT / ".github" / "workflows" / "scripts" / "create-github-release.sh").read_text(encoding="utf-8")
assert "spec-kit-template-tabnine-sh-" in gh_release_text
assert "spec-kit-template-tabnine-ps-" in gh_release_text
def test_agent_context_scripts_include_tabnine(self):
"""Agent context scripts should support tabnine agent type."""
bash_text = (REPO_ROOT / "scripts" / "bash" / "update-agent-context.sh").read_text(encoding="utf-8")
pwsh_text = (REPO_ROOT / "scripts" / "powershell" / "update-agent-context.ps1").read_text(encoding="utf-8")
assert "tabnine" in bash_text
assert "TABNINE_FILE" in bash_text
assert "tabnine" in pwsh_text
assert "TABNINE_FILE" in pwsh_text
def test_ai_help_includes_tabnine(self):
"""CLI help text for --ai should include tabnine."""
assert "tabnine" in AI_ASSISTANT_HELP

View File

@@ -147,6 +147,11 @@ class TestGetSkillsDir:
result = _get_skills_dir(project_dir, "gemini")
assert result == project_dir / ".gemini" / "skills"
def test_tabnine_skills_dir(self, project_dir):
"""Tabnine should use .tabnine/agent/skills/."""
result = _get_skills_dir(project_dir, "tabnine")
assert result == project_dir / ".tabnine" / "agent" / "skills"
def test_copilot_skills_dir(self, project_dir):
"""Copilot should use .github/skills/."""
result = _get_skills_dir(project_dir, "copilot")