mirror of
https://github.com/github/spec-kit.git
synced 2026-03-19 11:53:08 +00:00
Feature/spec kit add pi coding agent pullrequest (#1853)
* feat(ai): add native support for Pi coding agent by pi+gpt 5.4 * docs(pi): document MCP limitations for Pi agent * fix: unitended kimi agent mention added to update-agent-context.ps1 * fix: address reviewer feedback * Apply suggestions from code review Changes in AGENTS.md weren't part of my PR, but the Copilot feedback seems to be correct is correct. I've doublechecked it with contents of test_agent_config_consistency.py and create-release-packages scripts Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -309,3 +309,81 @@ class TestAgentConfigConsistency:
|
||||
def test_ai_help_includes_trae(self):
|
||||
"""CLI help text for --ai should include trae."""
|
||||
assert "trae" in AI_ASSISTANT_HELP
|
||||
|
||||
# --- Pi Coding Agent consistency checks ---
|
||||
|
||||
def test_pi_in_agent_config(self):
|
||||
"""AGENT_CONFIG should include pi with correct folder and commands_subdir."""
|
||||
assert "pi" in AGENT_CONFIG
|
||||
assert AGENT_CONFIG["pi"]["folder"] == ".pi/"
|
||||
assert AGENT_CONFIG["pi"]["commands_subdir"] == "prompts"
|
||||
assert AGENT_CONFIG["pi"]["requires_cli"] is True
|
||||
assert AGENT_CONFIG["pi"]["install_url"] is not None
|
||||
|
||||
def test_pi_in_extension_registrar(self):
|
||||
"""Extension command registrar should include pi using .pi/prompts."""
|
||||
cfg = CommandRegistrar.AGENT_CONFIGS
|
||||
|
||||
assert "pi" in cfg
|
||||
pi_cfg = cfg["pi"]
|
||||
assert pi_cfg["dir"] == ".pi/prompts"
|
||||
assert pi_cfg["format"] == "markdown"
|
||||
assert pi_cfg["args"] == "$ARGUMENTS"
|
||||
assert pi_cfg["extension"] == ".md"
|
||||
|
||||
def test_pi_in_release_agent_lists(self):
|
||||
"""Bash and PowerShell release scripts should include pi 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 "pi" in sh_agents
|
||||
assert "pi" in ps_agents
|
||||
|
||||
def test_release_scripts_generate_pi_prompt_templates(self):
|
||||
"""Release scripts should generate Markdown prompt templates for pi in .pi/prompts."""
|
||||
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 ".pi/prompts" in sh_text
|
||||
assert ".pi/prompts" in ps_text
|
||||
assert re.search(r"pi\)\s*\n.*?\.pi/prompts", sh_text, re.S) is not None
|
||||
assert re.search(r"'pi'\s*\{.*?\.pi/prompts", ps_text, re.S) is not None
|
||||
|
||||
def test_pi_in_powershell_validate_set(self):
|
||||
"""PowerShell update-agent-context script should include 'pi' in ValidateSet."""
|
||||
ps_text = (REPO_ROOT / "scripts" / "powershell" / "update-agent-context.ps1").read_text(encoding="utf-8")
|
||||
|
||||
validate_set_match = re.search(r"\[ValidateSet\(([^)]*)\)\]", ps_text)
|
||||
assert validate_set_match is not None
|
||||
validate_set_values = re.findall(r"'([^']+)'", validate_set_match.group(1))
|
||||
|
||||
assert "pi" in validate_set_values
|
||||
|
||||
def test_pi_in_github_release_output(self):
|
||||
"""GitHub release script should include pi template packages."""
|
||||
gh_release_text = (REPO_ROOT / ".github" / "workflows" / "scripts" / "create-github-release.sh").read_text(encoding="utf-8")
|
||||
|
||||
assert "spec-kit-template-pi-sh-" in gh_release_text
|
||||
assert "spec-kit-template-pi-ps-" in gh_release_text
|
||||
|
||||
def test_agent_context_scripts_include_pi(self):
|
||||
"""Agent context scripts should support pi 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 "pi" in bash_text
|
||||
assert "Pi Coding Agent" in bash_text
|
||||
assert "pi" in pwsh_text
|
||||
assert "Pi Coding Agent" in pwsh_text
|
||||
|
||||
def test_ai_help_includes_pi(self):
|
||||
"""CLI help text for --ai should include pi."""
|
||||
assert "pi" in AI_ASSISTANT_HELP
|
||||
|
||||
@@ -182,6 +182,11 @@ class TestGetSkillsDir:
|
||||
result = _get_skills_dir(project_dir, "kiro-cli")
|
||||
assert result == project_dir / ".kiro" / "skills"
|
||||
|
||||
def test_pi_skills_dir(self, project_dir):
|
||||
"""Pi should use .pi/skills/."""
|
||||
result = _get_skills_dir(project_dir, "pi")
|
||||
assert result == project_dir / ".pi" / "skills"
|
||||
|
||||
def test_unknown_agent_uses_default(self, project_dir):
|
||||
"""Unknown agents should fall back to DEFAULT_SKILLS_DIR."""
|
||||
result = _get_skills_dir(project_dir, "nonexistent-agent")
|
||||
@@ -422,6 +427,27 @@ class TestInstallAiSkills:
|
||||
assert (cmds_dir / "speckit.specify.md").exists()
|
||||
assert (cmds_dir / "speckit.plan.md").exists()
|
||||
|
||||
def test_pi_prompt_dir_installs_skills(self, project_dir):
|
||||
"""Pi should install skills directly from .pi/prompts/."""
|
||||
prompts_dir = project_dir / ".pi" / "prompts"
|
||||
prompts_dir.mkdir(parents=True)
|
||||
(prompts_dir / "speckit.specify.md").write_text(
|
||||
"---\ndescription: Create or update the feature specification.\n---\n\n# Specify\n\nBody.\n"
|
||||
)
|
||||
(prompts_dir / "speckit.plan.md").write_text(
|
||||
"---\ndescription: Generate implementation plan.\n---\n\n# Plan\n\nBody.\n"
|
||||
)
|
||||
|
||||
result = install_ai_skills(project_dir, "pi")
|
||||
|
||||
assert result is True
|
||||
skills_dir = project_dir / ".pi" / "skills"
|
||||
assert skills_dir.exists()
|
||||
skill_dirs = [d.name for d in skills_dir.iterdir() if d.is_dir()]
|
||||
assert len(skill_dirs) >= 1
|
||||
assert (prompts_dir / "speckit.specify.md").exists()
|
||||
assert (prompts_dir / "speckit.plan.md").exists()
|
||||
|
||||
@pytest.mark.parametrize("agent_key", [k for k in AGENT_CONFIG.keys() if k != "generic"])
|
||||
def test_skills_install_for_all_agents(self, temp_dir, agent_key):
|
||||
"""install_ai_skills should produce skills for every configured agent."""
|
||||
|
||||
@@ -593,6 +593,15 @@ class TestCommandRegistrar:
|
||||
assert "codex" in CommandRegistrar.AGENT_CONFIGS
|
||||
assert CommandRegistrar.AGENT_CONFIGS["codex"]["dir"] == ".codex/prompts"
|
||||
|
||||
def test_pi_agent_config_present(self):
|
||||
"""Pi should be mapped to .pi/prompts."""
|
||||
assert "pi" in CommandRegistrar.AGENT_CONFIGS
|
||||
cfg = CommandRegistrar.AGENT_CONFIGS["pi"]
|
||||
assert cfg["dir"] == ".pi/prompts"
|
||||
assert cfg["format"] == "markdown"
|
||||
assert cfg["args"] == "$ARGUMENTS"
|
||||
assert cfg["extension"] == ".md"
|
||||
|
||||
def test_qwen_agent_config_is_markdown(self):
|
||||
"""Qwen should use Markdown format with $ARGUMENTS (not TOML)."""
|
||||
assert "qwen" in CommandRegistrar.AGENT_CONFIGS
|
||||
|
||||
Reference in New Issue
Block a user