feat: implement preset wrap strategy#2189
feat: implement preset wrap strategy#2189kennedy-whytech wants to merge 5 commits intogithub:mainfrom
Conversation
…E_TEMPLATE} with core command body
…EMPLATE} for all agent types
604b585 to
444daef
Compare
There was a problem hiding this comment.
Pull request overview
Adds support for strategy: wrap on preset-provided commands, enabling preset authors to inject pre/post content around an existing “core” command body via a {CORE_TEMPLATE} placeholder during command/skill registration.
Changes:
- Introduces
_substitute_core_template()and applies it during preset skill registration (_register_skills) and generic agent command registration (CommandRegistrar.register_commands). - Extends the self-test preset with a new
speckit.wrap-testcommand and updates docs to markwrapas implemented for commands. - Adds unit + E2E-style tests covering placeholder substitution and install behavior.
Show a summary per file
| File | Description |
|---|---|
| tests/test_presets.py | Updates self-test manifest expectations; adds new TestWrapStrategy coverage. |
| src/specify_cli/presets.py | Adds _substitute_core_template() and wires it into preset skill generation. |
| src/specify_cli/agents.py | Wires wrap substitution into agent command registration. |
| presets/self-test/preset.yml | Adds a new wrap-strategy command entry to the self-test preset. |
| presets/self-test/commands/speckit.wrap-test.md | Adds a wrap command template using {CORE_TEMPLATE}. |
| presets/README.md | Updates roadmap/docs to reflect wrap implemented for commands/artifacts. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 6/6 changed files
- Comments generated: 1
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback. If not applicable, please explain why
444daef to
53220f8
Compare
|
@mnriem that makes sense to me. updated. |
There was a problem hiding this comment.
Pull request overview
Implements support for strategy: wrap on preset command templates by substituting {CORE_TEMPLATE} with the installed core command template body during installation/registration, enabling presets to extend core commands without copy/paste.
Changes:
- Added
_substitute_core_template()helper and applied it when generating skills from preset commands (Claude skills flow). - Applied the same substitution in
CommandRegistrar.register_commands()for non-skill agent command installation. - Added a self-test preset wrap command + unit/E2E tests, and updated preset strategy documentation.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/presets.py |
Adds {CORE_TEMPLATE} substitution helper and applies it in the skills generation path for wrap-strategy preset commands. |
src/specify_cli/agents.py |
Applies {CORE_TEMPLATE} substitution during normal agent command registration when strategy: wrap is set. |
tests/test_presets.py |
Updates self-test manifest expectations and adds unit + E2E coverage for wrap substitution. |
presets/self-test/preset.yml |
Registers a new wrap-strategy command in the bundled self-test preset. |
presets/self-test/commands/speckit.wrap-test.md |
New wrap command template containing {CORE_TEMPLATE} placeholder. |
presets/README.md |
Updates roadmap/docs to reflect wrap being implemented for commands/artifacts (not scripts). |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 6/6 changed files
- Comments generated: 2
| @@ -3043,4 +3043,136 @@ def test_bundled_preset_missing_locally_cli_error(self, project_dir): | |||
| assert result.exit_code == 1 | |||
| output = strip_ansi(result.output).lower() | |||
| assert "bundled" in output, result.output | |||
There was a problem hiding this comment.
This test previously asserted the CLI error also suggests how to recover (e.g., a reinstall hint). The CLI code path still prints a "Try reinstalling…" message for missing bundled presets, so dropping the "reinstall" assertion reduces coverage and makes regressions easier to miss. Consider restoring an assertion that the output includes a reinstall hint (or the specific REINSTALL_COMMAND string).
| assert "bundled" in output, result.output | |
| assert "bundled" in output, result.output | |
| assert "reinstall" in output, result.output |
| finally: | ||
| registrar.AGENT_CONFIGS = original | ||
|
|
There was a problem hiding this comment.
The test mutates CommandRegistrar.AGENT_CONFIGS (a class variable) but restores it by assigning to the instance (registrar.AGENT_CONFIGS = original). That leaves the class-level dict modified for subsequent tests. Restore via CommandRegistrar.AGENT_CONFIGS (or use patch.dict/monkeypatch) so the mutation is fully undone.
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
Description
Implements
strategy: wrapfor preset commands, which was listed as a roadmapitem in
presets/README.md. When a preset command setsstrategy: wrap, the{CORE_TEMPLATE}placeholder in its body is substituted with the body of theinstalled core speckit command template at install time.
This lets preset authors add pre/post logic around core commands without
copy-pasting the entire command body — useful for extending frequently-updated
templates like
/speckit.specifyor/speckit.tasks. Personally, I find it neccessary.Changes
src/specify_cli/presets.py— adds_substitute_core_template()helper;wires substitution into
_register_skills(skills-backed agents like Claude)src/specify_cli/agents.py— wires substitution intoregister_commands(all other agent types)
presets/self-test/— adds aspeckit.wrap-testcommand for E2E coveragepresets/README.md— markswrapas implemented for command/template typesTest results
184 tests pass (
tests/test_presets.py), including a newTestWrapStrategyclass with unit tests for the helper and an end-to-end install test.
Manual test results
Agent: Claude Code | OS/Shell: macOS/zsh
specify preset installwithstrategy: wrapcommand{CORE_TEMPLATE}correctly substituted in written skill/command fileEnd-to-end test with my own presets. The wrapping seems doing good. Also, I feel like "wrap" can cover prepend and append already.

Testing
uv run specify --helpuv sync && uv run pytestAI Disclosure
I did not use AI assistance for this contribution
I did use AI assistance (describe below)
AI assistance disclosure
This PR was implemented with AI assistance (Claude Code) for code generation,
test writing, and commit messages. All changes were reviewed and verified
manually.