feat(presets): Composition strategies (prepend, append, wrap) for templates, commands, and scripts#2133
feat(presets): Composition strategies (prepend, append, wrap) for templates, commands, and scripts#2133
Conversation
00edba1 to
fa04828
Compare
There was a problem hiding this comment.
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
strategyvalidation 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
There was a problem hiding this comment.
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
strategyvalidation 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
There was a problem hiding this comment.
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
strategysupport (replace/prepend/append/wrap) in preset manifests and implements bottom-up content composition inPresetResolver. - 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 resolveoutput, 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: continuewill skip re-registration when the composed result is an empty string. Use an explicitis Nonecheck 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
There was a problem hiding this comment.
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
strategyvalidation in preset manifests and implements layered composition viaPresetResolver.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
There was a problem hiding this comment.
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
strategyvalidation in preset manifests and implements bottom-up composition (replace/prepend/append/wrap) viaPresetResolver.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 resolveoutput, 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
There was a problem hiding this comment.
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
strategyvalidation and bottom-up layer composition inPresetResolver(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
There was a problem hiding this comment.
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 inPresetManager. - 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
There was a problem hiding this comment.
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
strategyvalidation in preset manifests and bottom-up composition inPresetResolver.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
There was a problem hiding this comment.
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
strategyvalidation inPresetManifestand bottom-up composition viaPresetResolver.collect_all_layers()+resolve_content(). - Updates
PresetManagercommand 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 resolveoutput, 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
There was a problem hiding this comment.
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
strategyvalidation inpreset.yml(with script restrictions) and implements bottom-up multi-layer composition viaPresetResolver.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: nullas enabled, which diverges from the Python registry semantics (null/falsy => disabled). Consider switching to a truthiness check soresolve_template_contentmatches 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$nullas enabled diverges from the Python registry semantics for an explicitenabled: nullentry. 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
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
d5ec4f2 to
fc15fdc
Compare
There was a problem hiding this comment.
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
strategyvalidation inPresetManifestand implement bottom-up composition viaPresetResolver.collect_all_layers()+resolve_content(). - Update
PresetManagercommand 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 resolveoutput, 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
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.
There was a problem hiding this comment.
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
strategyvalidation to preset manifests and implements bottom-up composition viaPresetResolver.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
- 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
There was a problem hiding this comment.
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
strategyvalidation inPresetManifestand implements full-stack layering + bottom-up composition viaPresetResolver.collect_all_layers()andPresetResolver.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
- 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
There was a problem hiding this comment.
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
strategyvalidation inPresetManifestand implements bottom-up content composition viaPresetResolver.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
| # 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) | ||
|
|
| # 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 |
Presets can now augment lower-priority templates instead of only fully replacing them. A new optional
strategyfield inpreset.ymlcontrols how content is composed across the priority stack.replaceprependappendwrap{CORE_TEMPLATE}/$CORE_SCRIPTplaceholder substitutionMultiple composing presets chain recursively (e.g. security
prepend+ complianceappend→ header + core + footer).Python resolver (
src/specify_cli/presets.py)VALID_PRESET_STRATEGIES/VALID_SCRIPT_STRATEGIESconstants; validation in_validate()rejectsprepend/appendfor scriptsPresetResolver._collect_all_layers()— walks full priority stack, reads strategy from each preset manifestPresetResolver.resolve_content()— bottom-up composition across layersPresetManager._register_commands()— composes command content before writing to agent directoriesShell resolvers
resolve_template_content()inscripts/bash/common.shResolve-TemplateContentinscripts/powershell/common.ps1CLI
specify preset resolveshows composition chain when non-replace strategies are presentDocumentation
presets/scaffold/preset.yml— strategy field docs and composition examplespresets/README.md— composition strategies section; moved implemented items out of future considerationspresets/ARCHITECTURE.md— strategy table and content resolution function referencesTests
resolve_content()for each strategy × type, multi-preset chaining, override precedence, separator behavior,_collect_all_layers()ordering