Skip to content

feat(presets): Composition strategies (prepend, append, wrap) for templates, commands, and scripts#2133

Open
Copilot wants to merge 4 commits intomainfrom
copilot/add-composition-strategies-to-presets
Open

feat(presets): Composition strategies (prepend, append, wrap) for templates, commands, and scripts#2133
Copilot wants to merge 4 commits intomainfrom
copilot/add-composition-strategies-to-presets

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 8, 2026

Presets can now augment lower-priority templates instead of only fully replacing them. A new optional strategy field in preset.yml controls how content is composed across the priority stack.

provides:
  templates:
    - type: "template"
      name: "spec-template"
      file: "templates/spec-addendum.md"
      strategy: "append"  # new field; default: "replace"
Strategy Behavior Templates Commands Scripts
replace Full replacement (existing default)
prepend Insert before lower-priority content
append Insert after lower-priority content
wrap {CORE_TEMPLATE} / $CORE_SCRIPT placeholder substitution

Multiple composing presets chain recursively (e.g. security prepend + compliance append → header + core + footer).

Python resolver (src/specify_cli/presets.py)

  • VALID_PRESET_STRATEGIES / VALID_SCRIPT_STRATEGIES constants; validation in _validate() rejects prepend/append for scripts
  • PresetResolver._collect_all_layers() — walks full priority stack, reads strategy from each preset manifest
  • PresetResolver.resolve_content() — bottom-up composition across layers
  • PresetManager._register_commands() — composes command content before writing to agent directories

Shell resolvers

  • resolve_template_content() in scripts/bash/common.sh
  • Resolve-TemplateContent in scripts/powershell/common.ps1

CLI

  • specify preset resolve shows composition chain when non-replace strategies are present

Documentation

  • presets/scaffold/preset.yml — strategy field docs and composition examples
  • presets/README.md — composition strategies section; moved implemented items out of future considerations
  • presets/ARCHITECTURE.md — strategy table and content resolution function references

Tests

  • 26 new tests: strategy validation (valid/invalid/script restrictions), resolve_content() for each strategy × type, multi-preset chaining, override precedence, separator behavior, _collect_all_layers() ordering

Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 20:55
Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 21:05
Comment thread src/specify_cli/presets.py Fixed
Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 21:08
Copilot AI changed the title [WIP] Add composition strategies for templates, commands, and scripts feat(presets): Composition strategies (prepend, append, wrap) for templates, commands, and scripts Apr 8, 2026
Copilot AI requested a review from mnriem April 8, 2026 21:09
Copilot AI review requested due to automatic review settings April 20, 2026 18:51
@mnriem mnriem force-pushed the copilot/add-composition-strategies-to-presets branch from 00edba1 to fa04828 Compare April 20, 2026 18:53
@mnriem mnriem review requested due to automatic review settings April 20, 2026 18:54
@mnriem mnriem marked this pull request as ready for review April 20, 2026 19:02
Copilot AI review requested due to automatic review settings April 20, 2026 19:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so higher-priority presets can augment (prepend/append/wrap) lower-priority templates/commands/scripts instead of always fully replacing them.

Changes:

  • Introduces strategy validation in preset manifests and a new Python composition resolver (_collect_all_layers() + resolve_content()).
  • Updates command registration to attempt composing command content before writing into agent directories.
  • Adds shell (bash/PowerShell) “resolve composed content” helpers plus docs and extensive new tests for strategy behavior.
Show a summary per file
File Description
tests/test_presets.py Adds strategy validation + composition resolver unit tests (including multi-preset chaining).
src/specify_cli/presets.py Adds strategy constants/validation, command composition during registration, and composition-aware resolution APIs.
src/specify_cli/init.py Enhances specify preset resolve output to show the composition chain when applicable.
scripts/powershell/common.ps1 Adds Resolve-TemplateContent to compose template layers using strategies.
scripts/bash/common.sh Adds resolve_template_content to compose template layers using strategies.
presets/scaffold/preset.yml Documents the new strategy field and shows composition examples.
presets/README.md Documents strategy semantics, supported combinations, and chaining behavior.
presets/ARCHITECTURE.md Documents strategy table and where composition resolution is implemented across runtimes.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 8/8 changed files
  • Comments generated: 8

Comment thread src/specify_cli/presets.py Outdated
Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py Outdated
Comment thread scripts/bash/common.sh
Comment thread scripts/bash/common.sh Outdated
Comment thread scripts/powershell/common.ps1 Outdated
Comment thread presets/scaffold/preset.yml
Comment thread presets/README.md
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so higher-priority presets can augment (prepend/append/wrap) lower-priority templates/commands/scripts instead of always fully replacing them.

Changes:

  • Introduces strategy validation in preset manifests and adds Python composition resolution across the full priority stack.
  • Updates command registration to write composed command content before registering with agent directories; adds CLI output to display a composition chain.
  • Adds bash/PowerShell template-content composition helpers, documentation updates, and a large set of new tests.
Show a summary per file
File Description
src/specify_cli/presets.py Adds strategy validation, layer collection, composed content resolver, and command registration changes to use composed content.
src/specify_cli/__init__.py Enhances specify preset resolve output to display a composition chain.
scripts/bash/common.sh Adds resolve_template_content() to compose template content in bash using the same strategy concepts.
scripts/powershell/common.ps1 Adds Resolve-TemplateContent to compose template content in PowerShell.
presets/scaffold/preset.yml Documents the new strategy field and provides composition examples.
presets/README.md Documents composition strategies and supported combinations; updates future-considerations list.
presets/ARCHITECTURE.md Adds strategy table and references to the new composition resolution functions.
tests/test_presets.py Adds extensive coverage for strategy validation, composition behavior, chaining, and layer collection ordering.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 8/8 changed files
  • Comments generated: 3

Comment thread src/specify_cli/__init__.py Outdated
Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset resolution stack so higher-priority presets can augment lower-priority templates/commands/scripts instead of only replacing them, with consistent behavior across Python + shell helpers and updated CLI/docs/tests.

Changes:

  • Introduces strategy support (replace/prepend/append/wrap) in preset manifests and implements bottom-up content composition in PresetResolver.
  • Updates command registration/removal flows to write/register composed command content and attempts to reconcile commands after uninstall.
  • Adds shell equivalents for composed template resolution, expands CLI preset resolve output, and updates preset documentation and test suite.
Show a summary per file
File Description
src/specify_cli/presets.py Validates strategy, collects full priority layers, composes content, and updates command registration/removal behavior.
src/specify_cli/__init__.py Enhances specify preset resolve output to display top layer and (optionally) a composition chain.
tests/test_presets.py Adds composition strategy validation and resolver behavior tests (including chaining and override precedence).
scripts/bash/common.sh Adds resolve_template_content() to compose template content via strategy metadata.
scripts/powershell/common.ps1 Adds Resolve-TemplateContent to compose template content via strategy metadata.
presets/scaffold/preset.yml Documents the new strategy field and provides composition examples.
presets/README.md Documents composition strategies and supported type/strategy combinations.
presets/ARCHITECTURE.md Documents composition strategy semantics and points to resolution implementations.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (1)

src/specify_cli/presets.py:658

  • In the composed branch of _reconcile_composed_commands, if not composed: continue will skip re-registration when the composed result is an empty string. Use an explicit is None check so empty-but-valid content still gets written and registered.
                composed = resolver.resolve_content(cmd_name, "command")
                if not composed:
                    continue
  • Files reviewed: 8/8 changed files
  • Comments generated: 5

Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py Outdated
Comment thread src/specify_cli/__init__.py Outdated
Comment thread scripts/powershell/common.ps1 Outdated
Copilot AI review requested due to automatic review settings April 20, 2026 20:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset/template resolution system so presets can augment lower-priority content (prepend/append/wrap) instead of only replacing, and updates CLI/docs/tests accordingly.

Changes:

  • Introduces strategy validation in preset manifests and implements layered composition via PresetResolver.collect_all_layers() + resolve_content().
  • Updates command registration to pre-compose command content (and reconcile after install/remove) so agent command files reflect the effective priority stack.
  • Adds shell equivalents for composed template resolution, expands documentation, and adds extensive test coverage for the new behaviors.
Show a summary per file
File Description
src/specify_cli/presets.py Adds strategy validation, layer collection + content composition, and command registration/reconciliation updates.
src/specify_cli/__init__.py Enhances specify preset resolve output to display composition chain details.
scripts/bash/common.sh Adds resolve_template_content() and filters disabled presets when reading registry.
scripts/powershell/common.ps1 Adds Resolve-TemplateContent, a Python3 locator helper, and filters disabled presets when reading registry.
tests/test_presets.py Adds new tests for strategy validation, composition behaviors, layer ordering, and remove-time reconciliation.
presets/scaffold/preset.yml Documents the new strategy field and provides examples.
presets/README.md Adds a “Composition Strategies” section and updates future considerations.
presets/ARCHITECTURE.md Documents supported strategies and points to the new composition resolvers.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 8/8 changed files
  • Comments generated: 3

Comment thread src/specify_cli/presets.py Outdated
Comment thread src/specify_cli/presets.py Outdated
Comment thread src/specify_cli/presets.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so higher-priority presets can augment lower-priority layers (instead of always replacing), spanning Python resolution, shell helpers, CLI output, docs, and tests.

Changes:

  • Introduces strategy validation in preset manifests and implements bottom-up composition (replace/prepend/append/wrap) via PresetResolver.collect_all_layers() + resolve_content().
  • Updates command registration to register composed command content and adds post-install/remove reconciliation so agent command files reflect the current priority stack.
  • Extends bash/powershell helpers, CLI preset resolve output, scaffold/docs, and adds extensive tests for composition behavior.
Show a summary per file
File Description
src/specify_cli/presets.py Core implementation: strategy validation, layer collection, composition, and command reconciliation/registration updates.
src/specify_cli/agents.py Adds a registrar helper to register commands while skipping SKILL.md-based agents.
src/specify_cli/__init__.py Enhances specify preset resolve to show composition chain using the new layer collector.
scripts/bash/common.sh Adds resolve_template_content() and filters disabled presets from registry traversal.
scripts/powershell/common.ps1 Adds YAML-aware Resolve-TemplateContent, Python 3 detection, and filters disabled presets.
tests/test_presets.py Adds a large new test suite covering validation, composition behavior, ordering, and removal reconciliation.
presets/scaffold/preset.yml Documents the new strategy field and provides composition examples.
presets/README.md Adds a Composition Strategies section and updates “future considerations”.
presets/ARCHITECTURE.md Documents strategy semantics and points to new resolution/composition functions.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 3

Comment thread src/specify_cli/agents.py
Comment thread src/specify_cli/__init__.py
Comment thread src/specify_cli/presets.py
@mnriem mnriem requested a review from Copilot April 21, 2026 18:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so higher-priority presets can augment (prepend/append/wrap) lower-priority templates/commands/scripts instead of always fully replacing them, and updates registration + tooling to reflect the composed result.

Changes:

  • Introduces per-template strategy validation and bottom-up layer composition in PresetResolver (including command frontmatter handling and core command stem fallback).
  • Updates command registration to materialize composed command content and reconciles agent command files after install/remove.
  • Adds cross-platform resolver parity (bash/PowerShell), CLI output updates for preset resolve, and extensive test coverage + docs.
Show a summary per file
File Description
src/specify_cli/presets.py Implements strategy validation, layer collection, composition, composed command registration, and reconciliation logic.
src/specify_cli/agents.py Adds registration helper to skip skill-based agents during reconciliation.
src/specify_cli/__init__.py Updates specify preset resolve to display layer chain and composition info.
scripts/bash/common.sh Adds resolve_template_content() and filters disabled presets in registry parsing.
scripts/powershell/common.ps1 Adds Resolve-TemplateContent, Python3 discovery, and filters disabled presets.
tests/test_presets.py Adds validation + composition tests, multi-layer chaining, command frontmatter behavior, and reconciliation coverage.
presets/scaffold/preset.yml Documents strategy options and provides composition examples in the scaffold.
presets/README.md Documents strategies, supported combinations, and removes now-implemented “future” items.
presets/ARCHITECTURE.md Documents strategy semantics and references composition resolution functions.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 4

Comment thread scripts/bash/common.sh Outdated
Comment thread scripts/powershell/common.ps1 Outdated
Comment thread src/specify_cli/presets.py Outdated
Comment thread src/specify_cli/presets.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds preset composition strategies so higher-priority presets can augment (prepend/append/wrap) lower-priority templates/commands/scripts instead of only replacing them, and wires this through resolution, command registration/reconciliation, CLI output, docs, and tests.

Changes:

  • Implement strategy validation + composed resolution (collect_all_layers(), resolve_content()) and command reconciliation in PresetManager.
  • Update CLI (specify preset resolve) to display composition chains when applicable.
  • Add shell equivalents for composed template resolution (bash/powershell) and expand documentation + tests.
Show a summary per file
File Description
src/specify_cli/presets.py Core implementation: strategy validation, layered resolution/composition, composed command registration + reconciliation logic.
src/specify_cli/agents.py Adds registrar helper to register commands for non-skill agents (used by reconciliation).
src/specify_cli/__init__.py Enhances preset resolve output to show composition chain and validate composability.
scripts/bash/common.sh Adds resolve_template_content() and filters disabled presets when reading registry.
scripts/powershell/common.ps1 Adds Resolve-TemplateContent, python discovery helper, and filters disabled presets.
tests/test_presets.py Adds extensive tests for strategy validation, composition behavior, chaining, and reconciliation.
presets/scaffold/preset.yml Documents strategy field and provides composition examples in scaffold preset.
presets/README.md Adds composition strategies docs; updates “future considerations”.
presets/ARCHITECTURE.md Documents strategy matrix and points to the new resolution functions across implementations.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 4

Comment thread scripts/powershell/common.ps1 Outdated
Comment thread src/specify_cli/presets.py Outdated
Comment thread src/specify_cli/presets.py Outdated
Comment thread tests/test_presets.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so higher-priority presets can augment (prepend/append/wrap) lower-priority templates/commands/scripts instead of only fully replacing them, with matching resolver logic across Python + shell helpers and expanded test coverage.

Changes:

  • Introduces strategy validation in preset manifests and bottom-up composition in PresetResolver.resolve_content() (including command frontmatter handling).
  • Updates command registration to write composed command content and adds reconciliation on install/remove to keep agent command files aligned with the current priority stack.
  • Adds shell helpers for composed template resolution plus docs/scaffold updates and a large test suite covering strategies and chaining.
Show a summary per file
File Description
tests/test_presets.py Adds comprehensive tests for strategy validation, composition behavior, chaining, and layer collection.
src/specify_cli/presets.py Implements strategy validation, layer collection, composed content resolution, and command registration/reconciliation changes.
src/specify_cli/agents.py Adds a registrar helper to register commands for non-skill agents (used by reconciliation).
src/specify_cli/init.py Enhances specify preset resolve output to display composition chains when applicable.
scripts/bash/common.sh Adds resolve_template_content() and ensures disabled presets are skipped when reading the registry.
scripts/powershell/common.ps1 Adds Resolve-TemplateContent, a Python 3 locator helper, and skips disabled presets from the registry.
presets/scaffold/preset.yml Documents the new strategy field and provides composition examples.
presets/README.md Documents composition strategies and updates future-considerations list.
presets/ARCHITECTURE.md Documents strategies and points to the new composition resolution functions.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 2

Comment thread src/specify_cli/presets.py
Comment thread scripts/powershell/common.ps1
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so presets can augment (prepend/append/wrap) lower-priority templates/commands/scripts instead of only fully replacing them, with resolver + CLI + docs + tests updated accordingly.

Changes:

  • Introduces strategy validation in PresetManifest and bottom-up composition via PresetResolver.collect_all_layers() + resolve_content().
  • Updates PresetManager command registration to write composed command content and reconciles commands after install/remove to reflect the true priority winner.
  • Adds shell equivalents for template composition, expands CLI preset resolve output, and adds extensive test coverage + documentation updates.
Show a summary per file
File Description
src/specify_cli/presets.py Core implementation: strategy validation, layer collection, content composition, command registration changes + reconciliation logic.
src/specify_cli/agents.py Adds a non-skill-agent-only registration method used during reconciliation.
src/specify_cli/__init__.py Enhances specify preset resolve to display composition chains when applicable.
scripts/bash/common.sh Adds resolve_template_content() to compose template content in bash, and skips disabled presets from registry.
scripts/powershell/common.ps1 Adds Resolve-TemplateContent + Python 3 detection, and skips disabled presets from registry.
tests/test_presets.py Adds composition strategy tests for validation, resolver composition behavior, layer ordering, and removal reconciliation.
presets/scaffold/preset.yml Documents strategy usage + examples in the scaffold preset manifest.
presets/README.md Documents composition strategies and updates future-considerations section accordingly.
presets/ARCHITECTURE.md Adds architecture-level documentation for strategies and references resolver functions across implementations.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 3

Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py Outdated
Comment thread tests/test_presets.py
@mnriem mnriem requested a review from Copilot April 21, 2026 19:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so higher-priority presets can augment (prepend/append/wrap) lower-priority templates/commands/scripts instead of only replacing them, and ensures command registration stays consistent after install/remove operations.

Changes:

  • Introduces strategy validation in preset.yml (with script restrictions) and implements bottom-up multi-layer composition via PresetResolver.collect_all_layers() + resolve_content().
  • Updates command registration to write/register composed command content and reconciles command + skill outputs after install/remove.
  • Adds shell equivalents for composed template resolution plus expanded tests and documentation for strategies.
Show a summary per file
File Description
src/specify_cli/presets.py Adds strategy validation, layer collection, composition, command composition registration, and reconciliation logic.
src/specify_cli/agents.py Adds non-skill-agent registration helper used by reconciliation to avoid overwriting SKILL.md agents.
src/specify_cli/__init__.py Updates specify preset resolve to show the full layer chain and composition details.
scripts/bash/common.sh Filters disabled presets in registry parsing and adds resolve_template_content composition logic.
scripts/powershell/common.ps1 Filters disabled presets, adds Python discovery helper, and adds Resolve-TemplateContent composition logic.
tests/test_presets.py Adds extensive coverage for strategy validation, composition behaviors, and reconciliation after removal.
presets/scaffold/preset.yml Documents the new strategy field and provides usage examples.
presets/README.md Documents strategies, supported combinations, and examples; updates future considerations.
presets/ARCHITECTURE.md Describes strategy semantics and points to the implementation functions across languages.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (2)

scripts/bash/common.sh:413

  • Same as above: this enabled filter treats enabled: null as enabled, which diverges from the Python registry semantics (null/falsy => disabled). Consider switching to a truthiness check so resolve_template_content matches the Python resolver when the registry is corrupted or manually edited.
    for pid, meta in sorted(presets.items(), key=lambda x: x[1].get('priority', 10)):
        if meta.get('enabled', True) is not False:
            print(pid)

scripts/powershell/common.ps1:407

  • Same enabled filtering issue as Resolve-Template: treating $null as enabled diverges from the Python registry semantics for an explicit enabled: null entry. Consider checking property existence so missing defaults to enabled, but explicit null/false disables the preset.
                    $sortedPresets = $presets.PSObject.Properties |
                        Where-Object { $null -eq $_.Value.enabled -or $_.Value.enabled -ne $false } |
                        Sort-Object { if ($null -ne $_.Value.priority) { $_.Value.priority } else { 10 } } |
  • Files reviewed: 9/9 changed files
  • Comments generated: 3

Comment thread scripts/bash/common.sh
Comment thread scripts/powershell/common.ps1
Comment thread src/specify_cli/__init__.py
upstream/main merged PR #2189 (wrap-only strategy) which overlaps with
our comprehensive composition strategies (prepend/append/wrap). Resolved
conflicts keeping our implementation as source of truth:

- README: keep our future considerations (composition is now fully
  implemented, not a future item)
- presets.py: keep our composition architecture (_reconcile_composed_commands,
  collect_all_layers, resolve_content) while preserving #2189's
  _substitute_core_template which is used by agents.py for skill
  generation
- tests: keep both test sets (our composition tests + #2189's wrap
  tests), removed TestReplayWrapsForCommand and
  TestInstallRemoveWrapLifecycle which test the superseded
  _replay_wraps_for_command API; our composition tests cover equivalent
  scenarios
- Restored missing _unregister_commands call in remove() that was lost
  during #2189 merge
Copilot AI review requested due to automatic review settings April 21, 2026 20:19
@mnriem mnriem force-pushed the copilot/add-composition-strategies-to-presets branch from d5ec4f2 to fc15fdc Compare April 21, 2026 20:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds preset composition strategies (replace, prepend, append, wrap) so higher-priority presets can augment lower layers instead of only fully replacing them, spanning Python resolution/registration, shell helpers, CLI output, docs, and tests.

Changes:

  • Add strategy validation in PresetManifest and implement bottom-up composition via PresetResolver.collect_all_layers() + resolve_content().
  • Update PresetManager command registration/removal flow to compose commands and reconcile on-disk agent outputs independent of install/remove order.
  • Add Bash/PowerShell template-content composition helpers, enhance specify preset resolve output, and update preset docs/scaffold + tests.
Show a summary per file
File Description
tests/test_presets.py Reworks tests to cover strategy validation, layer collection, and composition behavior.
src/specify_cli/presets.py Core implementation: strategy validation, layer collection, content composition, command reconciliation, and install/remove flow changes.
src/specify_cli/agents.py Adds register_commands_for_non_skill_agents() used during reconciliation to avoid clobbering SKILL.md outputs.
src/specify_cli/init.py Enhances specify preset resolve to show composition chain when applicable.
scripts/powershell/common.ps1 Adds Python3 detection and implements Resolve-TemplateContent composition for templates.
scripts/bash/common.sh Filters disabled presets and adds resolve_template_content() composition for templates.
presets/scaffold/preset.yml Documents the new strategy field and provides composition examples.
presets/README.md Documents composition strategies and updates “future considerations”.
presets/ARCHITECTURE.md Documents strategy behavior and references composition resolution implementations.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 3

Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py
After _unregister_skills removes a skill directory, _register_skills
skips writing because the dir no longer passes the is_dir() check.
Fix by ensuring the skill subdirectory exists before calling
_register_skills so the next winning preset's content gets registered.

Fixes the Claude E2E failure where removing a top-priority override
preset left skill-based agents without any SKILL.md file.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so templates/commands/scripts can be layered (prepend/append/wrap) across the priority stack instead of only replacing content.

Changes:

  • Adds strategy validation to preset manifests and implements bottom-up composition via PresetResolver.collect_all_layers() + resolve_content().
  • Updates preset install/remove flows to reconcile effective command outputs across the full priority stack (including skill-agent handling).
  • Adds shell (Bash/PowerShell) helpers for composed template resolution and updates docs/tests to cover the new behavior.
Show a summary per file
File Description
src/specify_cli/presets.py Implements strategy validation, layer collection + composition, and reconciled command/skill registration on install/remove.
src/specify_cli/agents.py Adds a registration helper that skips skill-based agents for reconciliation flows.
src/specify_cli/__init__.py Enhances specify preset resolve to display layer stack + composition chain details.
scripts/bash/common.sh Adds resolve_template_content() for composed template output (and filters disabled presets).
scripts/powershell/common.ps1 Adds Resolve-TemplateContent + Python3 discovery for manifest-aware composition.
tests/test_presets.py Adds extensive tests for strategy validation, composition outcomes, chaining, and layer ordering.
presets/scaffold/preset.yml Documents the new strategy field and provides composition examples.
presets/README.md Documents composition strategies and updates future-considerations list.
presets/ARCHITECTURE.md Adds strategy table and references to composition resolution functions.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 4

Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py Outdated
Comment thread src/specify_cli/presets.py Outdated
- Protect reconciliation in remove(): wrap _reconcile_composed_commands
  and _reconcile_skills in try/except so failures emit a warning instead
  of leaving the project in an inconsistent state
- Protect reconciliation in install(): same pattern for post-install
  reconciliation so partial installs don't lack cleanup
- Inherit scripts/agent_scripts from base frontmatter: when composing
  commands, merge scripts and agent_scripts keys from the base command's
  frontmatter into the top layer's frontmatter if missing, preventing
  composed commands from losing required script references
- Add tier-5 bundled core fallback to collect_all_layers(): check the
  bundled core_pack (wheel) or repo-root templates (source checkout) when
  .specify/templates/ doesn't contain the core file, matching resolve()'s
  tier-5 fallback so composition can always find a base layer
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so templates/commands/scripts can be layered (prepend/append/wrap) across the preset priority stack instead of always fully replacing lower-priority content.

Changes:

  • Adds strategy validation in PresetManifest and implements full-stack layering + bottom-up composition via PresetResolver.collect_all_layers() and PresetResolver.resolve_content().
  • Updates command installation/removal to reconcile composed command outputs against the current priority stack, and introduces a registrar helper to avoid writing raw commands into SKILL-based agent layouts.
  • Updates CLI/docs and expands tests to cover strategy validation, composition behavior, and layer ordering.
Show a summary per file
File Description
tests/test_presets.py Adds coverage for strategy validation, composition behavior, and layer collection ordering.
src/specify_cli/presets.py Core implementation: strategy validation, layer collection, content composition, and install/remove reconciliation.
src/specify_cli/agents.py Adds register_commands_for_non_skill_agents() to support reconciliation without clobbering SKILL-based agents.
src/specify_cli/init.py Enhances specify preset resolve output to show composition chain when applicable.
scripts/powershell/common.ps1 Adds composed template resolution and filters disabled presets when reading the registry.
scripts/bash/common.sh Adds composed template resolution and filters disabled presets when reading the registry.
presets/scaffold/preset.yml Documents the new strategy field and provides composition examples.
presets/README.md Documents composition strategies and removes them from “future considerations”.
presets/ARCHITECTURE.md Documents strategy semantics and references the new resolution functions.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 2

Comment thread src/specify_cli/presets.py
Comment thread src/specify_cli/presets.py Outdated
- Use yaml.safe_load for frontmatter parsing in resolve_content instead
  of CommandRegistrar.parse_frontmatter which uses naive find('---',3);
  strip strategy key from final frontmatter to prevent leaking internal
  composition directives into rendered agent command files
- Filter _reconcile_skills to specific commands: use _FilteredManifest
  wrapper so only the commands being reconciled get their skills updated,
  preventing accidental overwrites of other commands' skills that may be
  owned by higher-priority presets
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds composition strategies to the preset system so higher-priority presets can augment (prepend/append/wrap) lower-priority content instead of always fully replacing it, and updates the CLI/docs/tests accordingly.

Changes:

  • Introduces strategy validation in PresetManifest and implements bottom-up content composition via PresetResolver.collect_all_layers() + PresetResolver.resolve_content().
  • Updates preset install/remove flows to reconcile command outputs against the full priority stack (including non-skill vs skill-agent handling).
  • Adds shell-side template composition helpers plus extensive new unit tests and documentation updates.
Show a summary per file
File Description
src/specify_cli/presets.py Adds strategy validation, layer collection, composed resolution, and reconciliation logic for commands/skills across the priority stack.
src/specify_cli/agents.py Adds register_commands_for_non_skill_agents() to support reconciliation without overwriting SKILL.md-based agents.
src/specify_cli/__init__.py Enhances specify preset resolve to display composition chain and validate composed output.
scripts/bash/common.sh Filters disabled presets and adds resolve_template_content() for strategy-based template composition.
scripts/powershell/common.ps1 Filters disabled presets, adds Python 3 discovery, and adds Resolve-TemplateContent composition helper.
tests/test_presets.py Replaces prior wrap replay tests with comprehensive strategy validation/composition/reconciliation coverage.
presets/scaffold/preset.yml Documents strategy field and provides composition examples.
presets/README.md Documents composition strategies and updates future-considerations section accordingly.
presets/ARCHITECTURE.md Adds strategy table and references to new composition resolution functions.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 9/9 changed files
  • Comments generated: 2

Comment on lines +890 to +896
# Ensure skill directory exists so _register_skills can write to it.
if skills_dir:
skill_name, _ = self._skill_names_for_command(cmd_name)
skill_subdir = skills_dir / skill_name
if not skill_subdir.exists():
skill_subdir.mkdir(parents=True, exist_ok=True)

Comment on lines +2508 to +2518
# Read strategy and manifest file path from preset manifest
strategy = "replace"
manifest_file_path = None
manifest = self._get_manifest(pack_dir)
if manifest:
for tmpl in manifest.templates:
if (tmpl.get("name") == template_name
and tmpl.get("type") == template_type):
strategy = tmpl.get("strategy", "replace")
manifest_file_path = tmpl.get("file")
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(presets): Composition strategies (prepend, append, wrap) for templates, commands, and scripts

3 participants