Skip to content

Unify Kimi/Codex skill naming and migrate legacy dotted Kimi dirs#1971

Merged
mnriem merged 23 commits intogithub:mainfrom
RbBtSn0w:fix/kimi-skill-hyphen-invocation
Mar 26, 2026
Merged

Unify Kimi/Codex skill naming and migrate legacy dotted Kimi dirs#1971
mnriem merged 23 commits intogithub:mainfrom
RbBtSn0w:fix/kimi-skill-hyphen-invocation

Conversation

@RbBtSn0w
Copy link
Contributor

@RbBtSn0w RbBtSn0w commented Mar 25, 2026

Summary

This PR now combines two tightly related tracks on the same branch:

  1. Kimi/Codex skill naming + legacy migration alignment (discussion context: Hooks + Extensions: decouple logical command IDs from agent invocation (slash vs skills), and align skill naming rules #1918, Skills generation drift: native skills vs install_ai_skills vs extension overrides (frontmatter + naming) #1919)
  2. Follow-up hardening from issue Tech Debt: Consolidate skill rendering/parsing paths and harden TOML safety #1976 (rendering/parsing consistency + TOML safety)

What Changed

A) Skill naming/migration alignment (original scope)

  • Unified generated skill names to hyphenated format (speckit-*) for Kimi/Codex paths.
  • Updated hook invocation rendering to emit agent-specific invocation strings and EXECUTE_COMMAND_INVOCATION.
  • Fixed preset skill override mapping for multi-segment command IDs.
  • Added temporary Kimi migration helper for legacy dotted skill dirs (speckit.xxx) with conservative cleanup behavior.
  • Synced release packaging scripts (sh/ps1) to hyphenated Kimi skill output.

B) Regression fixes discovered in review cycle

  • Kept sequential branch numbering working beyond 999 and ensured timestamp-style dirs are ignored in sequential mode.
  • Added explicit PR summary rationale for this inclusion to keep review scope transparent.

C) Issue #1976 hardening (newly included)

  • agents.py:
    • Hardened render_toml_command() so TOML remains valid even when body contains triple-quote delimiters.
    • Made _adjust_script_paths() non-mutating (defensive copy) to reduce side effects.
  • presets.py:
    • _unregister_skills() now reuses CommandRegistrar.parse_frontmatter().
    • Restored skills now run through placeholder resolution ({SCRIPT}, {AGENT_SCRIPT}, {ARGS}, __AGENT__) for consistency with other skill-generation paths.
  • Tests added/updated for all above behavior.

Why

Validation

  • uv run pytest tests/test_extensions.py tests/test_presets.py::TestPresetSkills
    • Result: 150 passed
  • uv run pytest tests/test_timestamp_branches.py::TestSequentialBranch::test_sequential_supports_four_digit_prefixes tests/test_timestamp_branches.py::TestSequentialBranch::test_sequential_ignores_timestamp_dirs
    • Result: 2 passed
  • uvx ruff check src/specify_cli/agents.py src/specify_cli/presets.py tests/test_extensions.py tests/test_presets.py
    • Result: All checks passed

Related

@RbBtSn0w RbBtSn0w requested a review from mnriem as a code owner March 25, 2026 09:02
Copilot AI review requested due to automatic review settings March 25, 2026 09:02
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR standardizes skill naming to a single hyphenated format (speckit-...) across Kimi and Codex, and updates related plumbing (hook invocation rendering, preset/extension overrides, packaging) to match that canonical scheme while adding a temporary Kimi legacy directory migration.

Changes:

  • Normalize generated skill directory names to hyphenated form and update extension/preset override mapping for multi-segment command IDs.
  • Update hook messaging/execution metadata to emit agent-specific invocation strings (e.g., /skill:speckit-plan for Kimi, $speckit-tasks for Codex skills mode).
  • Sync template packaging scripts and add a temporary migration helper for legacy dotted Kimi skill directories.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/specify_cli/__init__.py Unifies skill naming, adds Kimi dotted-dir migration helper, updates init output/invocation hints, removes Codex skills dir override.
src/specify_cli/agents.py Makes skills-mode output naming consistently hyphenated (including multi-segment IDs).
src/specify_cli/presets.py Fixes preset skill override mapping for multi-segment command IDs by hyphenating derived skill names.
src/specify_cli/extensions.py Adds init-options-aware hook invocation rendering and returns invocation metadata from hook execution.
tests/test_ai_skills.py Updates expectations to hyphenated Kimi skills and adds tests for legacy Kimi dotted-dir migration.
tests/test_extensions.py Updates Codex skill path/name assertions and adds hook invocation rendering tests.
tests/test_presets.py Adds regression test for hyphenated skill override mapping for speckit.<ext>.<cmd>.
.github/workflows/scripts/create-release-packages.sh Updates Kimi packaging to generate hyphenated skill names.
.github/workflows/scripts/create-release-packages.ps1 Updates Kimi packaging to generate hyphenated skill names.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Copilot feedback. If not applicable, please explain why.

Copilot AI review requested due to automatic review settings March 25, 2026 13:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mnriem mnriem self-requested a review March 25, 2026 14:04
Copy link
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Copilot feedback. If not applicable, please explain why

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/specify_cli/extensions.py:2024

  • HookExecutor.execute_hook() now returns an invocation field, but the docstring’s “Returns” section doesn’t mention it. Please update the return-value documentation to include invocation so callers know it’s available (and what format it uses).
        Returns:
            Dictionary with execution information:
            - command: str - Command to execute
            - extension: str - Extension ID
            - optional: bool - Whether hook is optional
            - description: str - Hook description
        """
        return {
            "command": hook.get("command"),
            "invocation": self._render_hook_invocation(hook.get("command")),
            "extension": hook.get("extension"),
            "optional": hook.get("optional", True),
            "description": hook.get("description", ""),
            "prompt": hook.get("prompt", "")

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

mnriem
mnriem previously approved these changes Mar 25, 2026
Copy link
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Copilot feedback. If not applicable, please explain why

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/specify_cli/extensions.py:1676

  • _render_hook_invocation() is annotated to take command: str, but it’s called with hook.get('command') (potentially None) and defensively checks for non-strings. Updating the parameter type (e.g., str | None) would better reflect actual usage and avoid type-checking warnings.
    def _render_hook_invocation(self, command: str) -> str:
        """Render an agent-specific invocation string for a hook command."""
        if not isinstance(command, str):
            return ""


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@RbBtSn0w RbBtSn0w requested a review from mnriem March 25, 2026 16:50
Copy link
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix test & lint errors

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

src/specify_cli/presets.py:704

  • Same robustness issue as _get_skills_dir(): load_init_options() may return a non-dict for malformed-but-parseable JSON, which would make init_opts.get('ai') raise here. Please defensively coerce to {} unless it’s a dict before reading ai so preset skill writes don’t crash.
        init_opts = load_init_options(self.project_root)
        selected_ai = init_opts.get("ai")
        if not isinstance(selected_ai, str):
            return []

src/specify_cli/presets.py:799

  • init_opts = load_init_options(...) is assumed to be a dict, but load_init_options() can return other JSON types if the file is corrupted (e.g., []). That would make init_opts.get('ai') raise and break preset removal. Consider normalizing init_opts to {} unless it’s a dict before reading ai.
        init_opts = load_init_options(self.project_root)
        selected_ai = init_opts.get("ai")
        registrar = CommandRegistrar()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor Author

@RbBtSn0w RbBtSn0w left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mnriem mnriem self-requested a review March 26, 2026 12:10
Copy link
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address more Copilot feedback. Hang in there we are close!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mnriem mnriem self-requested a review March 26, 2026 12:21
Copy link
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More Copilot feedback. It often pivots to one area and then when that is done goes to the next area. Hence why you see the back and forth. Hopefully this will be very close to the last round. You rock for working through this!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/specify_cli/presets.py:859

  • Same readability issue as in preset skill registration: the restored SKILL.md header uses short_name.title(), which preserves hyphens in multi-segment names. Consider replacing -/. with spaces before title-casing to keep generated headers consistent and human-friendly.
                    f"---\n\n"
                    f"# Speckit {short_name.title()} Skill\n\n"
                    f"{body}\n"

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings March 26, 2026 12:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@RbBtSn0w RbBtSn0w requested a review from mnriem March 26, 2026 12:54
@mnriem mnriem merged commit ccc44dd into github:main Mar 26, 2026
11 of 12 checks passed
@mnriem
Copy link
Collaborator

mnriem commented Mar 26, 2026

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants