# Extension points — github/spec-kit

> Canonical page: https://codevetter.com/unpack/spec-kit/extension-points

# Extension points — github/spec-kit

Scanned commit 175adbcd826befdccce8c60faa07ae3d8bbc8d87 (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The repo is essentially a plugin framework. Five registration seams exist: (1) `INTEGRATION_REGISTRY` for AI agents via small class-attr subclasses of four base classes; (2) `STEP_REGISTRY`/`StepBase` for workflow step types, including project-local dynamically-loaded custom steps; (3) extension packages (`extension.yml`) adding commands/hooks/events/config; (4) presets (`preset.yml`) overriding templates via priority-resolved `replaces:` entries; (5) bundles (`bundle.yml`) packaging all of the above. All five are discoverable/installable through per-domain catalog stacks that users can extend with custom catalog URLs.
- New AI-agent integrations plug in via `INTEGRATION_REGISTRY`: create `src/specify_cli/integrations/<pkg>/__init__.py` with a class setting `key`, `config`, `registrar_config`, then add one import + one `_register()` call (both alphabetical) in `_register_builtins()`; package dirs use underscores while `key` keeps the hyphenated CLI name. — [src/specify_cli/integrations/__init__.py#L54-150](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/__init__.py#L54-L150) [AGENTS.md](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/AGENTS.md)
- Four integration base classes cover the output formats — `MarkdownIntegration`, `TomlIntegration`, `YamlIntegration`, `SkillsIntegration`, or `IntegrationBase` for fully custom setup (e.g. Copilot's dual skills/commands layouts) — with documented override points: `setup()`, `teardown()`, `command_filename()`, `options()`, `post_process_command_content()`, `effective_invoke_separator()`. — [src/specify_cli/integrations/base.py#L1079-1165,1173-1180](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/base.py#L1079-1165,1173-L1180) [src/specify_cli/integrations/copilot/__init__.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/copilot/__init__.py) [AGENTS.md](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/AGENTS.md)
- Per-integration CLI flags are declared via `IntegrationOption` entries returned from `options()` and consumed through `--integration-options` (e.g. codex `--skills`, copilot `--commands`, generic `--commands-dir`); `options()` auto-adds `--events` when the integration declares `CANONICAL_TO_NATIVE` + `events_config_file`. — [src/specify_cli/integrations/base.py#L79-95,167-180](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/base.py#L79-95,167-L180) [src/specify_cli/integrations/codex/__init__.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/codex/__init__.py) [src/specify_cli/integrations/generic/__init__.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/generic/__init__.py)
- `specify integration scaffold` generates a new integration subpackage from templates (`command_scaffold.py` + `_command_scaffold_generation.py`), giving a code-level entry point for the documented 'add an integration in 5 steps' flow. — [src/specify_cli/integrations/command_scaffold.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/command_scaffold.py) [src/specify_cli/integrations/_command_scaffold_generation.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/_command_scaffold_generation.py) [AGENTS.md](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/AGENTS.md)
- Workflow step types plug into `STEP_REGISTRY` (`type_key` → `StepBase` subclass); beyond the 11 builtins, `load_custom_steps` imports project-local step packages from `.specify/workflows/steps/<pkg>/` defined by `step.yml` (`step.type_key`) + `__init__.py` (`StepBase` subclass). — [src/specify_cli/workflows/__init__.py#L22-35,85-140](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/workflows/__init__.py#L22-35,85-L140) [src/specify_cli/workflows/base.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/workflows/base.py)
- Extensions are self-contained packages declared by `extension.yml` (`schema_version`, `extension` metadata, `requires`, `provides.commands|config|templates|scripts`, `hooks.<before|after>_<command>`, `events`, `config.defaults`) — validated by `ExtensionManifest` and installed by `ExtensionManager`; `extensions/template/` is the starter scaffold. — [extensions/git/extension.yml#L1-45](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/extensions/git/extension.yml#L1-L45) [extensions/template/extension.yml](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/extensions/template/extension.yml) [src/specify_cli/extensions/__init__.py#L290-430](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/extensions/__init__.py#L290-L430)
- Presets override core behavior declaratively: `preset.yml` `provides.templates` entries with `replaces: "speckit.<cmd>"` substitute command/template/script artifacts, and `PresetResolver` composes the stack by priority (lower number wins) — e.g. `lean` replaces the five core commands with minimal variants. — [presets/lean/preset.yml#L15-46](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/presets/lean/preset.yml#L15-L46) [src/specify_cli/presets/__init__.py#L1-56](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/presets/__init__.py#L1-L56) [presets/constitution-sync/preset.yml](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/presets/constitution-sync/preset.yml)
- Bundles (`bundle.yml`) compose extensions, presets, workflows, and step types into one installable unit (`specify bundle install`); first-party `bugfix` and `assess` bundles plus a community catalog JSON ship in the wheel for offline discovery. — [bundles/bugfix/bundle.yml](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/bundles/bugfix/bundle.yml) [bundles/catalog.json](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/bundles/catalog.json) [src/specify_cli/bundles/installer.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/bundles/installer.py) [pyproject.toml#L55-57](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/pyproject.toml#L55-L57)
- Every domain (integrations, extensions, presets, workflows, bundles) supports user-added remote catalogs through `catalog add/list/remove` commands backed by `CatalogStackBase` entries with `url`, `priority`, and `install_allowed` flags — so organizations can host private catalogs. — [src/specify_cli/catalogs.py#L14-40](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/catalogs.py#L14-L40) [src/specify_cli/extensions/catalog/command_add.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/extensions/catalog/command_add.py) [src/specify_cli/integrations/catalog/command_add.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/catalog/command_add.py) [integrations/catalog.json](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/integrations/catalog.json)
- Workflow overlays (`workflows/overlays/` composer + `workflow overlay` command group) let projects layer modifications onto installed workflows without forking them — merge, layer_sources, and schema modules define the overlay pipeline. — [src/specify_cli/workflows/overlays/composer.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/workflows/overlays/composer.py) [src/specify_cli/workflows/overlays/merge.py](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/workflows/overlays/merge.py) [src/specify_cli/workflows/_commands.py#L63-68](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/workflows/_commands.py#L63-L68)
- Agent-native runtime events plug in per-integration: a class declaring `CANONICAL_TO_NATIVE` (canonical snake_case events → native hook names) and `events_config_file` automatically gets `--events` support and native hook emission via `install_integration_events`; canonical events are session_start, pre_tool_use, post_tool_use, session_end, user_prompt_submit, stop. — [src/specify_cli/events.py#L59-67](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/events.py#L59-L67) [src/specify_cli/integrations/base.py#L167-180,1014-1035](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/src/specify_cli/integrations/base.py#L167-180,1014-L1035)
- The `agent-context` extension owns all context-file (CLAUDE.md/AGENTS.md) management as a fully opt-in, generic component driven by `agent-context-config.yml` markers — deliberately keeping context-file knowledge out of the CLI/registry so new integrations add nothing for it. — [extensions/agent-context/extension.yml](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/extensions/agent-context/extension.yml) [extensions/agent-context/agent-context-config.yml](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/extensions/agent-context/agent-context-config.yml) [AGENTS.md](https://github.com/github/spec-kit/blob/175adbcd826befdccce8c60faa07ae3d8bbc8d87/AGENTS.md)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
