Skip to content

copilot: Support --integration-options="--skills" for skills-based scaffolding #2323

@mnriem

Description

@mnriem

Summary

Add a --skills flag to the Copilot integration so users can scaffold commands as speckit-<name>/SKILL.md directories (agentskills.io format) instead of the default .agent.md + .prompt.md layout. The two modes are mutually exclusive — a project uses one or the other.

# Default: .agent.md agents + .prompt.md companions + settings merge
specify init my-project --integration copilot

# Skills mode: speckit-<name>/SKILL.md under .github/skills/
specify init my-project --integration copilot --integration-options="--skills"

Motivation

GitHub Copilot supports the agentskills.io skill format. Users who prefer the portable, directory-per-skill layout (speckit-<name>/SKILL.md) should be able to opt into it — just like Codex and Claude integrations already do. The default behavior (.agent.md agents + companion .prompt.md prompts + VS Code settings merge) remains unchanged.

Design Decisions

Question Decision
Skills directory path .github/skills/ — keeps everything under .github/ consistent with Copilot conventions
Copilot-specific post-processing Yes — implement post_process_skill_content() for Copilot-specific frontmatter (e.g., mode: field)
Mutual exclusivity Exclusive — --skills replaces the default agent scaffolding entirely; a project uses one mode or the other

Design: Composition over Inheritance

Keep CopilotIntegration extending IntegrationBase. Do not re-parent to SkillsIntegration.

Concern Detail
Default mode is non-skills Copilot's default output (.agent.md, .prompt.md, settings merge) has no overlap with SkillsIntegration. Making it the base would require overriding everything for the default path.
Unique Copilot features Companion .prompt.md generation and .vscode/settings.json merge are Copilot-only — SkillsIntegration has no concept of these.
Invocation model differs Default uses --agent speckit.<name>; skills use /speckit-<name>. Mutually exclusive per mode.
Skills setup is reusable The skills scaffolding logic (frontmatter normalization, speckit-<name>/SKILL.md layout, manifest tracking) can be called as a helper without inheriting.

Approach: When --skills is passed, delegate scaffolding to a composed SkillsIntegration helper or extract the skills-setup logic into a reusable method/mixin.

Implementation Plan

1. Add --skills option to CopilotIntegration

@classmethod
def options(cls) -> list[IntegrationOption]:
    return [
        IntegrationOption(
            "--skills",
            is_flag=True,
            default=False,
            help="Scaffold commands as agent skills (speckit-<name>/SKILL.md) instead of .agent.md files",
        ),
    ]

2. Branch setup() based on parsed_options

In CopilotIntegration.setup(), check parsed_options.get("skills"):

  • False (default): Current behavior — .agent.md + .prompt.md + settings merge.
  • True: Scaffold as speckit-<name>/SKILL.md under .github/skills/. Skip companion .prompt.md and settings merge since skills are self-contained.

3. Mode-specific behavior matrix

Aspect Default mode Skills mode
Output dir .github/agents/ .github/skills/
File layout speckit.<name>.agent.md speckit-<name>/SKILL.md
Companion files .github/prompts/speckit.<name>.prompt.md None
Settings merge Yes No
registrar_config.extension .agent.md /SKILL.md
Invocation --agent speckit.<name> /speckit-<name>
Post-processing None post_process_skill_content()

4. Implement post_process_skill_content()

Add Copilot-specific frontmatter injection (e.g., mode: field) when scaffolding skills. This mirrors how ClaudeIntegration injects user-invocable and disable-model-invocation flags.

5. Adjust build_command_invocation() and dispatch_command()

These methods must respect the active mode:

  • Default: --agent speckit.<name> dispatch
  • Skills: /speckit-<name> slash-command dispatch

Consider storing the active mode on the instance or detecting it from the project's file layout.

6. Tests

Add to tests/integrations/test_integration_copilot.py:

  • Skills directory structure created under .github/skills/ (speckit-plan/SKILL.md, etc.)
  • No companion .prompt.md files generated in skills mode
  • No .vscode/settings.json merge in skills mode
  • Frontmatter matches agentskills.io format (name, description, compatibility, metadata)
  • post_process_skill_content() injects Copilot-specific fields
  • Manifest tracks skill files correctly
  • Uninstall cleans up skill directories
  • Existing default-mode tests remain unchanged

7. Documentation

  • Update AGENTS.md Copilot section to document --skills option
  • Add skills mode example to CLI help text

Files to Modify

File Change
src/specify_cli/integrations/copilot/__init__.py Add options(), branch setup(), add post_process_skill_content(), adjust invocation methods
src/specify_cli/integrations/base.py Possibly extract skills-setup logic into a reusable function or mixin
tests/integrations/test_integration_copilot.py Add --skills mode test suite
AGENTS.md Document --skills option for Copilot

Acceptance Criteria

  • specify init my-project --integration copilot works unchanged (default .agent.md mode)
  • specify init my-project --integration copilot --integration-options="--skills" scaffolds speckit-<name>/SKILL.md under .github/skills/
  • Skills mode produces no .prompt.md companions and no settings merge
  • Skills frontmatter includes Copilot-specific fields via post_process_skill_content()
  • build_command_invocation() returns /speckit-<name> in skills mode
  • specify integration uninstall copilot cleans up whichever mode was installed
  • All existing Copilot tests pass
  • New skills-mode tests pass

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions