diff --git a/templates/commands/specify.md b/templates/commands/specify.md index 52b2b24565..2dbad6d63d 100644 --- a/templates/commands/specify.md +++ b/templates/commands/specify.md @@ -8,6 +8,10 @@ handoffs: agent: speckit.clarify prompt: Clarify specification requirements send: true +scripts: + sh: scripts/bash/resolve-template.sh spec-template --json + ps: scripts/powershell/resolve-template.ps1 spec-template -Json + py: scripts/python/resolve_template.py spec-template --json --- ## User Input @@ -92,9 +96,9 @@ Given that feature description, do this: - If `branch_numbering` was used (and `feature_numbering` was absent), emit a one-line warning: "⚠️ `branch_numbering` in init-options.json is deprecated. Rename to `feature_numbering`." **Create the directory and spec file**: + - Run `{SCRIPT}` from the repository root and parse `TEMPLATE_CONTENT` as the active `spec-template`. The shared resolver composes project overrides, preset layers, and extension layers over the core template, including `append`, `prepend`, and `wrap` strategies. If it fails, stop and report the resolution error; do not continue with only one contributing template layer. - `mkdir -p SPECIFY_FEATURE_DIRECTORY` - - Resolve the active `spec-template` through the Spec Kit preset/template resolution stack (equivalent to `specify preset resolve spec-template`) - - Copy the resolved `spec-template` file to `SPECIFY_FEATURE_DIRECTORY/spec.md` as the starting point + - Write `TEMPLATE_CONTENT` to `SPECIFY_FEATURE_DIRECTORY/spec.md` as the starting point. Do not copy a template file from disk instead: when a preset composes `spec-template`, no single file holds the full template. - Set `SPEC_FILE` to `SPECIFY_FEATURE_DIRECTORY/spec.md` - Persist the resolved path to `.specify/feature.json`: ```json @@ -110,7 +114,7 @@ Given that feature description, do this: - The spec directory name and the git branch name are independent — they may be the same but that is the user's choice - The spec directory and file are always created by this command, never by the hook -4. Load the resolved active `spec-template` file to understand required sections. +4. Use `TEMPLATE_CONTENT` to understand required sections. 5. **IF EXISTS**: Load `/memory/constitution.md` for project principles and governance constraints. diff --git a/tests/integrations/test_integration_copilot.py b/tests/integrations/test_integration_copilot.py index 921b023be6..04098650e5 100644 --- a/tests/integrations/test_integration_copilot.py +++ b/tests/integrations/test_integration_copilot.py @@ -208,8 +208,11 @@ def test_specify_agent_resolves_active_spec_template(self, tmp_path): specify_file = tmp_path / ".github" / "agents" / "speckit.specify.agent.md" content = specify_file.read_text(encoding="utf-8") - assert "specify preset resolve spec-template" in content - assert "resolved active `spec-template`" in content + assert "resolve-template" in content + assert "{SCRIPT}" not in content + assert "parse `TEMPLATE_CONTENT` as the active `spec-template`" in content + assert "Write `TEMPLATE_CONTENT` to `SPECIFY_FEATURE_DIRECTORY/spec.md`" in content + assert "Copy the resolved `spec-template` file" not in content assert "Copy `.specify/templates/spec-template.md`" not in content assert "Load `.specify/templates/spec-template.md`" not in content diff --git a/tests/test_presets.py b/tests/test_presets.py index a15ca4694b..705367a7a5 100644 --- a/tests/test_presets.py +++ b/tests/test_presets.py @@ -506,6 +506,21 @@ def test_core_checklist_command_resolves_template_at_runtime(): assert "Use TEMPLATE_CONTENT as the structural template" in content +def test_core_specify_command_writes_composed_spec_template(): + """The specify command must start spec.md from the composed spec-template.""" + content = (CORE_CONSTITUTION_COMMAND.parent / "specify.md").read_text( + encoding="utf-8" + ) + + assert "resolve-template.sh spec-template --json" in content + assert "resolve-template.ps1 spec-template -Json" in content + assert "resolve_template.py spec-template --json" in content + assert "parse `TEMPLATE_CONTENT` as the active `spec-template`" in content + assert "Write `TEMPLATE_CONTENT` to `SPECIFY_FEATURE_DIRECTORY/spec.md`" in content + assert "do not continue with only one contributing template layer" in content + assert "Copy the resolved `spec-template` file" not in content + + class TestLeanPreset: """Tests for the lean preset that ships with the repo."""