mirror of
https://github.com/github/spec-kit.git
synced 2026-07-03 20:36:23 +08:00
* feat: implement strategy: wrap * fix: resolve merge conflict for strategy wrap correctness * feat: multi-preset composable wrapping with priority ordering Implements comment #4 from PR review: multiple installed wrap presets now compose in priority order rather than overwriting each other. Key changes: - PresetResolver.resolve() gains skip_presets flag; resolve_core() wraps it to skip tier 2, preventing accidental nesting during replay - _replay_wraps_for_command() recomposed all enabled wrap presets for a command in ascending priority order (innermost-first) after any install or remove - _replay_skill_override() keeps SKILL.md in sync with the recomposed command body for ai-skills-enabled projects - install_from_directory() detects strategy: wrap commands, stores wrap_commands in the registry entry, and calls replay after install - remove() reads wrap_commands before deletion, removes registry entry before rmtree so replay sees post-removal state, then replays remaining wraps or unregisters when none remain Tests: TestResolveCore (5), TestReplayWrapsForCommand (5), TestInstallRemoveWrapLifecycle (5), plus 2 skill/alias regression tests * fix: resolve extension commands via manifest file mapping PresetResolver.resolve_extension_command_via_manifest() consults each installed extension.yml to find the actual file declared for a command name, rather than assuming the file is named <cmd_name>.md. This fixes _substitute_core_template for extensions like selftest where the manifest maps speckit.selftest.extension → commands/selftest.md. Resolution order in _substitute_core_template is now: 1. resolve_core(cmd_name) — project overrides win, then name-based lookup 2. resolve_extension_command_via_manifest(cmd_name) — manifest fallback 3. resolve_core(short_name) — core template short-name fallback Path traversal guard mirrors the containment check already present in ExtensionManager to reject absolute paths or paths escaping the extension root. * fix: add bundled core_pack as Priority 5 in PresetResolver.resolve() resolve_core() was returning None for built-in commands (implement, specify, etc.) because PresetResolver only checked .specify/templates/ commands/ (Priority 4), which is never populated for commands in a normal project. strategy:wrap presets rely on resolve_core() to fetch the {CORE_TEMPLATE} body, so the wrap was silently skipped and SKILL.md was never updated. Priority 5 now checks core_pack/commands/ (wheel install) or repo_root/templates/commands/ (source checkout), mirroring the pattern used by _locate_core_pack() elsewhere. Updated two tests whose assertions assumed resolve_core() always returned None when .specify/templates/commands/ was absent. * fix: harden preset wrap replay removal * fix: stabilize existing directory error output * fix: track outermost_pack_id from contributing preset; use Path.parts in tests - outermost_pack_id now updates alongside outermost_frontmatter inside the wrap loop, so it reflects the actual last contributing preset rather than always taking wrap_presets[0] (which may have been skipped) - Replace str(path) substring checks in TestResolveCore with Path.parts tuple comparisons for correct behaviour on Windows (CI runs windows-latest) * fix: guard against non-mapping YAML manifests; apply integration post-processing in replay - ExtensionManifest._load raises ValidationError for non-dict YAML roots instead of TypeError - PresetManager._replay_wraps_for_command calls integration.post_process_skill_content, matching _register_skills behaviour - PresetResolver skips extensions that raise OSError/TypeError/AttributeError on manifest load - Tests: non-mapping YAML, OSError manifest skip, and replay integration post-processing
67 lines
1.8 KiB
YAML
67 lines
1.8 KiB
YAML
schema_version: "1.0"
|
|
|
|
preset:
|
|
id: "self-test"
|
|
name: "Self-Test Preset"
|
|
version: "1.0.0"
|
|
description: "A preset that overrides all core templates for testing purposes"
|
|
author: "github"
|
|
repository: "https://github.com/github/spec-kit"
|
|
license: "MIT"
|
|
|
|
requires:
|
|
speckit_version: ">=0.1.0"
|
|
|
|
provides:
|
|
templates:
|
|
- type: "template"
|
|
name: "spec-template"
|
|
file: "templates/spec-template.md"
|
|
description: "Self-test spec template"
|
|
replaces: "spec-template"
|
|
|
|
- type: "template"
|
|
name: "plan-template"
|
|
file: "templates/plan-template.md"
|
|
description: "Self-test plan template"
|
|
replaces: "plan-template"
|
|
|
|
- type: "template"
|
|
name: "tasks-template"
|
|
file: "templates/tasks-template.md"
|
|
description: "Self-test tasks template"
|
|
replaces: "tasks-template"
|
|
|
|
- type: "template"
|
|
name: "checklist-template"
|
|
file: "templates/checklist-template.md"
|
|
description: "Self-test checklist template"
|
|
replaces: "checklist-template"
|
|
|
|
- type: "template"
|
|
name: "constitution-template"
|
|
file: "templates/constitution-template.md"
|
|
description: "Self-test constitution template"
|
|
replaces: "constitution-template"
|
|
|
|
- type: "template"
|
|
name: "agent-file-template"
|
|
file: "templates/agent-file-template.md"
|
|
description: "Self-test agent file template"
|
|
replaces: "agent-file-template"
|
|
|
|
- type: "command"
|
|
name: "speckit.specify"
|
|
file: "commands/speckit.specify.md"
|
|
description: "Self-test override of the specify command"
|
|
replaces: "speckit.specify"
|
|
|
|
- type: "command"
|
|
name: "speckit.wrap-test"
|
|
file: "commands/speckit.wrap-test.md"
|
|
description: "Self-test wrap strategy command"
|
|
|
|
tags:
|
|
- "testing"
|
|
- "self-test"
|