diff --git a/scripts/bash/update-agent-context.sh b/scripts/bash/update-agent-context.sh index da06ed4697..b0ef4b422a 100644 --- a/scripts/bash/update-agent-context.sh +++ b/scripts/bash/update-agent-context.sh @@ -84,7 +84,7 @@ AGY_FILE="$REPO_ROOT/.agent/rules/specify-rules.md" BOB_FILE="$AGENTS_FILE" VIBE_FILE="$REPO_ROOT/.vibe/agents/specify-agents.md" KIMI_FILE="$REPO_ROOT/KIMI.md" -TRAE_FILE="$REPO_ROOT/.trae/rules/AGENTS.md" +TRAE_FILE="$REPO_ROOT/.trae/rules/project_rules.md" IFLOW_FILE="$REPO_ROOT/IFLOW.md" FORGE_FILE="$AGENTS_FILE" diff --git a/scripts/powershell/update-agent-context.ps1 b/scripts/powershell/update-agent-context.ps1 index 342ee5464d..12caa306da 100644 --- a/scripts/powershell/update-agent-context.ps1 +++ b/scripts/powershell/update-agent-context.ps1 @@ -65,7 +65,7 @@ $AGY_FILE = Join-Path $REPO_ROOT '.agent/rules/specify-rules.md' $BOB_FILE = Join-Path $REPO_ROOT 'AGENTS.md' $VIBE_FILE = Join-Path $REPO_ROOT '.vibe/agents/specify-agents.md' $KIMI_FILE = Join-Path $REPO_ROOT 'KIMI.md' -$TRAE_FILE = Join-Path $REPO_ROOT '.trae/rules/AGENTS.md' +$TRAE_FILE = Join-Path $REPO_ROOT '.trae/rules/project_rules.md' $IFLOW_FILE = Join-Path $REPO_ROOT 'IFLOW.md' $FORGE_FILE = Join-Path $REPO_ROOT 'AGENTS.md' diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index 1c62a4a3be..a3aa7d94f9 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -1287,7 +1287,7 @@ def init( step_num = 2 # Determine skill display mode for the next-steps panel. - # Skills integrations (codex, kimi, agy) should show skill invocation syntax. + # Skills integrations (codex, kimi, agy, trae) should show skill invocation syntax. from .integrations.base import SkillsIntegration as _SkillsInt _is_skills_integration = isinstance(resolved_integration, _SkillsInt) @@ -1295,7 +1295,8 @@ def init( claude_skill_mode = selected_ai == "claude" and (ai_skills or _is_skills_integration) kimi_skill_mode = selected_ai == "kimi" agy_skill_mode = selected_ai == "agy" and _is_skills_integration - native_skill_mode = codex_skill_mode or claude_skill_mode or kimi_skill_mode or agy_skill_mode + trae_skill_mode = selected_ai == "trae" + native_skill_mode = codex_skill_mode or claude_skill_mode or kimi_skill_mode or agy_skill_mode or trae_skill_mode if codex_skill_mode and not ai_skills: # Integration path installed skills; show the helpful notice @@ -1307,7 +1308,7 @@ def init( usage_label = "skills" if native_skill_mode else "slash commands" def _display_cmd(name: str) -> str: - if codex_skill_mode or agy_skill_mode: + if codex_skill_mode or agy_skill_mode or trae_skill_mode: return f"$speckit-{name}" if claude_skill_mode: return f"/speckit-{name}" diff --git a/src/specify_cli/integrations/trae/__init__.py b/src/specify_cli/integrations/trae/__init__.py index 7037eecb8c..343a7527f8 100644 --- a/src/specify_cli/integrations/trae/__init__.py +++ b/src/specify_cli/integrations/trae/__init__.py @@ -1,21 +1,40 @@ -"""Trae IDE integration.""" +"""Trae IDE integration. — skills-based agent. -from ..base import MarkdownIntegration +Trae IDE uses ``.trae/skills/speckit-/SKILL.md`` layout. +In the Specify CLI Trae integration, explicit command support was deprecated +since v0.5.1; ``--skills`` defaults to ``True``. +""" +from __future__ import annotations +from ..base import IntegrationOption, SkillsIntegration + + +class TraeIntegration(SkillsIntegration): + """Integration for Trae IDE.""" -class TraeIntegration(MarkdownIntegration): key = "trae" config = { "name": "Trae", "folder": ".trae/", - "commands_subdir": "rules", + "commands_subdir": "skills", "install_url": None, "requires_cli": False, } registrar_config = { - "dir": ".trae/rules", + "dir": ".trae/skills", "format": "markdown", "args": "$ARGUMENTS", - "extension": ".md", + "extension": "/SKILL.md", } - context_file = ".trae/rules/AGENTS.md" + context_file = ".trae/rules/project_rules.md" + + @classmethod + def options(cls) -> list[IntegrationOption]: + return [ + IntegrationOption( + "--skills", + is_flag=True, + default=True, + help="Install as agent skills (default for trae since v0.5.1)", + ), + ] diff --git a/src/specify_cli/integrations/trae/scripts/update-context.ps1 b/src/specify_cli/integrations/trae/scripts/update-context.ps1 index f72d96318e..ae9a3d1cd0 100644 --- a/src/specify_cli/integrations/trae/scripts/update-context.ps1 +++ b/src/specify_cli/integrations/trae/scripts/update-context.ps1 @@ -1,4 +1,4 @@ -# update-context.ps1 — Trae integration: create/update .trae/rules/AGENTS.md +# update-context.ps1 — Trae integration: create/update .trae/rules/project_rules.md # # Thin wrapper that delegates to the shared update-agent-context script. # Activated in Stage 7 when the shared script uses integration.json dispatch. diff --git a/src/specify_cli/integrations/trae/scripts/update-context.sh b/src/specify_cli/integrations/trae/scripts/update-context.sh index b868a7c983..32e5c16b29 100755 --- a/src/specify_cli/integrations/trae/scripts/update-context.sh +++ b/src/specify_cli/integrations/trae/scripts/update-context.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# update-context.sh — Trae integration: create/update .trae/rules/AGENTS.md +# update-context.sh — Trae integration: create/update .trae/rules/project_rules.md # # Thin wrapper that delegates to the shared update-agent-context script. # Activated in Stage 7 when the shared script uses integration.json dispatch. diff --git a/src/specify_cli/presets.py b/src/specify_cli/presets.py index 0c8bba1757..137d1d22a8 100644 --- a/src/specify_cli/presets.py +++ b/src/specify_cli/presets.py @@ -717,7 +717,7 @@ def _register_skills( ai_skills_enabled = bool(init_opts.get("ai_skills")) registrar = CommandRegistrar() agent_config = registrar.AGENT_CONFIGS.get(selected_ai, {}) - # Native skill agents (e.g. codex/kimi/agy) materialize brand-new + # Native skill agents (e.g. codex/kimi/agy/trae) materialize brand-new # preset skills in _register_commands() because their detected agent # directory is already the skills directory. This flag is only for # command-backed agents that also mirror commands into skills. diff --git a/tests/integrations/test_integration_trae.py b/tests/integrations/test_integration_trae.py index 307c3481db..74b8b41c3f 100644 --- a/tests/integrations/test_integration_trae.py +++ b/tests/integrations/test_integration_trae.py @@ -1,11 +1,11 @@ """Tests for TraeIntegration.""" -from .test_integration_base_markdown import MarkdownIntegrationTests +from .test_integration_base_skills import SkillsIntegrationTests -class TestTraeIntegration(MarkdownIntegrationTests): +class TestTraeIntegration(SkillsIntegrationTests): KEY = "trae" FOLDER = ".trae/" - COMMANDS_SUBDIR = "rules" - REGISTRAR_DIR = ".trae/rules" - CONTEXT_FILE = ".trae/rules/AGENTS.md" + COMMANDS_SUBDIR = "skills" + REGISTRAR_DIR = ".trae/skills" + CONTEXT_FILE = ".trae/rules/project_rules.md" diff --git a/tests/test_agent_config_consistency.py b/tests/test_agent_config_consistency.py index 8e293baa17..35d8c02f7e 100644 --- a/tests/test_agent_config_consistency.py +++ b/tests/test_agent_config_consistency.py @@ -139,7 +139,7 @@ def test_trae_in_agent_config(self): """AGENT_CONFIG should include trae with correct folder and commands_subdir.""" assert "trae" in AGENT_CONFIG assert AGENT_CONFIG["trae"]["folder"] == ".trae/" - assert AGENT_CONFIG["trae"]["commands_subdir"] == "rules" + assert AGENT_CONFIG["trae"]["commands_subdir"] == "skills" assert AGENT_CONFIG["trae"]["requires_cli"] is False assert AGENT_CONFIG["trae"]["install_url"] is None @@ -151,7 +151,7 @@ def test_trae_in_extension_registrar(self): trae_cfg = cfg["trae"] assert trae_cfg["format"] == "markdown" assert trae_cfg["args"] == "$ARGUMENTS" - assert trae_cfg["extension"] == ".md" + assert trae_cfg["extension"] == "/SKILL.md" def test_trae_in_agent_context_scripts(self): """Agent context scripts should support trae agent type."""