Overlay-Aware Suggestion Rules in prs init¶
Version: 1.1 Date: 2026-04-04 Issue: #208 Parent: #199 (Phase 2) Status: Design
1. Problem¶
When both a base registry and an overlay registry define suggestion rules for the same file patterns, prs init shows them as independent unrelated entries. The user sees two skills with the same purpose and no indication that one extends the other.
2. Solution¶
Detect @extend relationships between suggested skills and collapse them into a single entry showing the overlay with attribution. The base skill is removed from the choice list since selecting the overlay implies the base.
3. Overlay detection¶
Two detection methods, tried in order:
3.1 Manifest metadata (primary)¶
Add optional extends to skill entries in registry-manifest.yaml:
entries:
skills/clm512-expert:
description: "CLM 5.12+ Expert with BU context"
extends: "@clm5core/skills/clm512-expert"
The extends value is the full registry path of the base skill.
3.2 .prs file scan (fallback)¶
When a suggested skill has no extends in manifest, read the skill's .prs file from the registry cache (~/.promptscript/cache/registries/) and perform a two-step scan:
Step 1: Extract @use alias mappings:
{ alias: "base" → path: "@clm5core/skills/clm512-expert" } Step 2: Extract @extend targets:
alias and skillName. Resolve alias through the map from step 1 to get the full extends path. If the resolved path matches another skill in the suggestion list, the relationship is detected. If the file cannot be found or read, the fallback silently skips — the skill appears as a normal unrelated entry.
4. Collapsed display¶
When a base/overlay relationship is detected:
Suggested configurations based on your project:
[x] @bu/skills/clm512-expert (extends @clm5core/clm512-expert)
[x] @core/security
[ ] @fragments/testing
The base skill does NOT appear as a separate checkbox. Selecting the overlay implies the base (that's what @extend does at compile time).
When no overlay relationship exists, skills display as today (independent entries).
When multiple overlays extend the same base, all overlays are shown with "(extends ...)" and the base is removed once.
5. Implementation¶
5.1 Type change¶
Add extends?: string to ManifestEntry in packages/core/src/types/manifest.ts.
5.2 collapseOverlays() function¶
New function in packages/cli/src/utils/suggestion-engine.ts:
function collapseOverlays(
skills: string[],
manifest: RegistryManifest
): CollapsedSkillSuggestion[]
- For each suggested skill, check if its manifest entry has
extends - If not, attempt
.prsfile scan fallback - If the extends target is also in the suggestions list, remove the base and annotate the overlay
- Guard against self-extends and circular references
- Return collapsed list
5.3 Display update¶
createSuggestionChoices() uses the annotation to append (extends @base/path) to the choice name when CollapsedSkillSuggestion.extends is set.
5.4 Types¶
6. Files changed¶
| File | Change |
|---|---|
packages/core/src/types/manifest.ts | Add extends?: string to ManifestEntry |
packages/cli/src/utils/suggestion-engine.ts | Add collapseOverlays(), update createSuggestionChoices() |
packages/cli/src/__tests__/suggestion-engine.spec.ts | Tests for overlay collapse |
7. Testing¶
| Test | Description |
|---|---|
Collapse via manifest extends | Base removed, overlay annotated |
Collapse via .prs fallback | Two-step alias scan detects extends |
| No collapse for unrelated skills | Independent skills shown normally |
| No collapse when base not suggested | Overlay extends a non-suggested skill — shown normally |
| No collapse on self-extends | Self-reference guarded |
.prs file not found | Fallback silently skips |
| Multiple overlays on same base | Both shown with "(extends ...)", base removed once |
| Display format | Choice shows "(extends base/path)" |
8. Scope exclusions¶
- Does not fix #214 (skill selection not applied to config)
- No changes to non-interactive mode beyond collapsed display
- No resolver or compiler changes