From 4e4906eb306627fc0b22c5c9fed1c3daf950e630 Mon Sep 17 00:00:00 2001 From: rbbtsn0w Date: Fri, 20 Mar 2026 15:46:58 +0800 Subject: [PATCH 1/2] docs(sdk): align native skills frontmatter + document multi-generator drift --- .github/workflows/scripts/create-release-packages.ps1 | 6 +++++- .github/workflows/scripts/create-release-packages.sh | 8 ++++++++ AGENTS.md | 4 ++-- src/specify_cli/__init__.py | 9 +++++++++ src/specify_cli/agents.py | 6 ++++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scripts/create-release-packages.ps1 b/.github/workflows/scripts/create-release-packages.ps1 index 80c2ef021..4b3160286 100644 --- a/.github/workflows/scripts/create-release-packages.ps1 +++ b/.github/workflows/scripts/create-release-packages.ps1 @@ -204,6 +204,10 @@ agent: $basename # Create skills in \\SKILL.md format. # Most agents use hyphenated names (e.g. speckit-plan); Kimi is the # current dotted-name exception (e.g. speckit.plan). +# +# Technical debt note: +# Keep SKILL.md frontmatter aligned with `install_ai_skills()` and extension +# overrides (at minimum: name/description/compatibility/metadata.source). function New-Skills { param( [string]$SkillsDir, @@ -285,7 +289,7 @@ function New-Skills { if ($inBody) { $templateBody += "$line`n" } } - $skillContent = "---`nname: `"$skillName`"`ndescription: `"$description`"`n---`n`n$templateBody" + $skillContent = "---`nname: `"$skillName`"`ndescription: `"$description`"`ncompatibility: `"Requires spec-kit project structure with .specify/ directory`"`nmetadata:`n author: `"github-spec-kit`"`n source: `"templates/commands/$name.md`"`n---`n`n$templateBody" Set-Content -Path (Join-Path $skillDir "SKILL.md") -Value $skillContent -NoNewline } } diff --git a/.github/workflows/scripts/create-release-packages.sh b/.github/workflows/scripts/create-release-packages.sh index fedf84147..32430ce78 100755 --- a/.github/workflows/scripts/create-release-packages.sh +++ b/.github/workflows/scripts/create-release-packages.sh @@ -124,6 +124,10 @@ EOF # Create skills in //SKILL.md format. # Most agents use hyphenated names (e.g. speckit-plan); Kimi is the # current dotted-name exception (e.g. speckit.plan). +# +# Technical debt note: +# Keep SKILL.md frontmatter aligned with `install_ai_skills()` and extension +# overrides (at minimum: name/description/compatibility/metadata.source). create_skills() { local skills_dir="$1" local script_variant="$2" @@ -187,6 +191,10 @@ create_skills() { printf -- '---\n' printf 'name: "%s"\n' "$skill_name" printf 'description: "%s"\n' "$description" + printf 'compatibility: "%s"\n' "Requires spec-kit project structure with .specify/ directory" + printf -- 'metadata:\n' + printf ' author: "%s"\n' "github-spec-kit" + printf ' source: "%s"\n' "templates/commands/${name}.md" printf -- '---\n\n' printf '%s\n' "$template_body" } > "$skill_dir/SKILL.md" diff --git a/AGENTS.md b/AGENTS.md index a48fb15ff..1392ee4b8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,7 +33,7 @@ Specify supports multiple AI agents by generating agent-specific command files a | **Cursor** | `.cursor/commands/` | Markdown | `cursor-agent` | Cursor CLI | | **Qwen Code** | `.qwen/commands/` | Markdown | `qwen` | Alibaba's Qwen Code CLI | | **opencode** | `.opencode/command/` | Markdown | `opencode` | opencode CLI | -| **Codex CLI** | `.codex/prompts/` | Markdown | `codex` | Codex CLI | +| **Codex CLI** | `.agents/skills/` | Markdown | `codex` | Codex CLI (skills) | | **Windsurf** | `.windsurf/workflows/` | Markdown | N/A (IDE-based) | Windsurf IDE workflows | | **Junie** | `.junie/commands/` | Markdown | `junie` | Junie by JetBrains | | **Kilo Code** | `.kilocode/workflows/` | Markdown | N/A (IDE-based) | Kilo Code IDE | @@ -380,7 +380,7 @@ Command content with {SCRIPT} and {{args}} placeholders. - **CLI agents**: Usually `./commands/` - **Common prompt-based exceptions**: - - Codex: `.codex/prompts/` + - Codex: `.agents/skills/` (skills, invoked as `$speckit-`) - Kiro CLI: `.kiro/prompts/` - Pi: `.pi/prompts/` - **IDE agents**: Follow IDE-specific patterns: diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index caca381a5..72cba4d36 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -1218,6 +1218,15 @@ def load_init_options(project_path: Path) -> dict[str, Any]: DEFAULT_SKILLS_DIR = ".agents/skills" # Agents whose downloaded template already contains skills in the final layout. +# +# Technical debt note: +# - Spec-kit currently has multiple SKILL.md generators: +# 1) release packaging scripts that build the template zip (native skills), +# 2) `install_ai_skills()` which converts extracted command templates to skills, +# 3) extension/preset overrides via `agents.CommandRegistrar.render_skill_command()`. +# - Keep the skills frontmatter schema aligned across all generators +# (at minimum: name/description/compatibility/metadata.source). +# - When adding fields here, update the release scripts and override writers too. NATIVE_SKILLS_AGENTS = {"codex", "kimi"} # Enhanced descriptions for each spec-kit command skill diff --git a/src/specify_cli/agents.py b/src/specify_cli/agents.py index 10b2c7484..2117acda6 100644 --- a/src/specify_cli/agents.py +++ b/src/specify_cli/agents.py @@ -298,6 +298,12 @@ def render_skill_command( SKILL-target agents should receive the same skills-oriented frontmatter shape used elsewhere in the project instead of the original command frontmatter. + + Technical debt note: + Spec-kit currently has multiple SKILL.md generators (template packaging, + init-time conversion, and extension/preset overrides). Keep the skill + frontmatter keys aligned (name/description/compatibility/metadata) to + avoid drift across agents. """ if not isinstance(frontmatter, dict): frontmatter = {} From 77efcb25e6f570c188dfe70cc3b458fd714a1a58 Mon Sep 17 00:00:00 2001 From: rbbtsn0w Date: Fri, 20 Mar 2026 22:40:28 +0800 Subject: [PATCH 2/2] fix: clarify skills frontmatter contract and AGENTS sections --- .github/workflows/scripts/create-release-packages.ps1 | 2 +- .github/workflows/scripts/create-release-packages.sh | 2 +- AGENTS.md | 3 ++- src/specify_cli/__init__.py | 2 +- src/specify_cli/agents.py | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/scripts/create-release-packages.ps1 b/.github/workflows/scripts/create-release-packages.ps1 index 4b3160286..8f3cfec36 100644 --- a/.github/workflows/scripts/create-release-packages.ps1 +++ b/.github/workflows/scripts/create-release-packages.ps1 @@ -207,7 +207,7 @@ agent: $basename # # Technical debt note: # Keep SKILL.md frontmatter aligned with `install_ai_skills()` and extension -# overrides (at minimum: name/description/compatibility/metadata.source). +# overrides (at minimum: name/description/compatibility/metadata.{author,source}). function New-Skills { param( [string]$SkillsDir, diff --git a/.github/workflows/scripts/create-release-packages.sh b/.github/workflows/scripts/create-release-packages.sh index 32430ce78..c2bd792fd 100755 --- a/.github/workflows/scripts/create-release-packages.sh +++ b/.github/workflows/scripts/create-release-packages.sh @@ -127,7 +127,7 @@ EOF # # Technical debt note: # Keep SKILL.md frontmatter aligned with `install_ai_skills()` and extension -# overrides (at minimum: name/description/compatibility/metadata.source). +# overrides (at minimum: name/description/compatibility/metadata.{author,source}). create_skills() { local skills_dir="$1" local script_variant="$2" diff --git a/AGENTS.md b/AGENTS.md index 1392ee4b8..a15e0bc4b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -379,8 +379,9 @@ Command content with {SCRIPT} and {{args}} placeholders. ## Directory Conventions - **CLI agents**: Usually `./commands/` -- **Common prompt-based exceptions**: +- **Skills-based exceptions**: - Codex: `.agents/skills/` (skills, invoked as `$speckit-`) +- **Prompt-based exceptions**: - Kiro CLI: `.kiro/prompts/` - Pi: `.pi/prompts/` - **IDE agents**: Follow IDE-specific patterns: diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index 72cba4d36..701d4c74e 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -1225,7 +1225,7 @@ def load_init_options(project_path: Path) -> dict[str, Any]: # 2) `install_ai_skills()` which converts extracted command templates to skills, # 3) extension/preset overrides via `agents.CommandRegistrar.render_skill_command()`. # - Keep the skills frontmatter schema aligned across all generators -# (at minimum: name/description/compatibility/metadata.source). +# (at minimum: name/description/compatibility/metadata.{author,source}). # - When adding fields here, update the release scripts and override writers too. NATIVE_SKILLS_AGENTS = {"codex", "kimi"} diff --git a/src/specify_cli/agents.py b/src/specify_cli/agents.py index 2117acda6..4f1ab728f 100644 --- a/src/specify_cli/agents.py +++ b/src/specify_cli/agents.py @@ -302,8 +302,8 @@ def render_skill_command( Technical debt note: Spec-kit currently has multiple SKILL.md generators (template packaging, init-time conversion, and extension/preset overrides). Keep the skill - frontmatter keys aligned (name/description/compatibility/metadata) to - avoid drift across agents. + frontmatter keys aligned (name/description/compatibility/metadata, with + metadata.author and metadata.source subkeys) to avoid drift across agents. """ if not isinstance(frontmatter, dict): frontmatter = {}