bmad-module-skill-forge 0.8.4 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +5 -3
  2. package/docs/bmad-synergy.md +183 -0
  3. package/docs/concepts.md +30 -2
  4. package/docs/examples.md +57 -17
  5. package/docs/getting-started.md +17 -0
  6. package/docs/how-it-works.md +143 -29
  7. package/docs/index.md +1 -1
  8. package/docs/workflows.md +43 -5
  9. package/package.json +1 -1
  10. package/src/README.md +47 -0
  11. package/src/agents/forger.agent.yaml +8 -0
  12. package/src/knowledge/agentskills-spec.md +3 -0
  13. package/src/knowledge/overview.md +1 -0
  14. package/src/knowledge/provenance-tracking.md +3 -0
  15. package/src/knowledge/skf-knowledge-index.csv +1 -0
  16. package/src/knowledge/skill-lifecycle.md +19 -7
  17. package/src/knowledge/version-paths.md +243 -0
  18. package/src/module-help.csv +2 -0
  19. package/src/module.yaml +4 -0
  20. package/src/workflows/README.md +9 -1
  21. package/src/workflows/analyze-source/data/skill-brief-schema.md +4 -0
  22. package/src/workflows/analyze-source/steps-c/step-06-generate-briefs.md +5 -0
  23. package/src/workflows/audit-skill/steps-c/step-01-init.md +10 -6
  24. package/src/workflows/audit-skill/steps-c/step-02-re-index.md +1 -1
  25. package/src/workflows/audit-skill/steps-c/step-03-structural-diff.md +1 -1
  26. package/src/workflows/audit-skill/steps-c/step-04-semantic-diff.md +1 -1
  27. package/src/workflows/audit-skill/steps-c/step-05-severity-classify.md +1 -1
  28. package/src/workflows/audit-skill/steps-c/step-06-report.md +7 -2
  29. package/src/workflows/brief-skill/data/skill-brief-schema.md +11 -0
  30. package/src/workflows/brief-skill/steps-c/step-01-gather-intent.md +24 -1
  31. package/src/workflows/brief-skill/steps-c/step-02-analyze-target.md +10 -0
  32. package/src/workflows/brief-skill/steps-c/step-04-confirm-brief.md +9 -0
  33. package/src/workflows/brief-skill/steps-c/step-05-write-brief.md +18 -4
  34. package/src/workflows/create-skill/data/skill-sections.md +2 -0
  35. package/src/workflows/create-skill/data/source-resolution-protocols.md +40 -4
  36. package/src/workflows/create-skill/steps-c/step-03-extract.md +1 -1
  37. package/src/workflows/create-skill/steps-c/step-05-compile.md +1 -0
  38. package/src/workflows/create-skill/steps-c/step-07-generate-artifacts.md +48 -32
  39. package/src/workflows/create-skill/steps-c/step-08-report.md +16 -12
  40. package/src/workflows/create-stack-skill/data/compose-mode-rules.md +12 -6
  41. package/src/workflows/create-stack-skill/steps-c/step-01-init.md +4 -1
  42. package/src/workflows/create-stack-skill/steps-c/step-02-detect-manifests.md +11 -5
  43. package/src/workflows/create-stack-skill/steps-c/step-04-parallel-extract.md +1 -1
  44. package/src/workflows/create-stack-skill/steps-c/step-05-detect-integrations.md +1 -1
  45. package/src/workflows/create-stack-skill/steps-c/step-07-generate-output.md +40 -23
  46. package/src/workflows/create-stack-skill/steps-c/step-08-validate.md +6 -3
  47. package/src/workflows/create-stack-skill/steps-c/step-09-report.md +11 -4
  48. package/src/workflows/drop-skill/steps-c/step-01-select.md +298 -0
  49. package/src/workflows/drop-skill/steps-c/step-02-execute.md +290 -0
  50. package/src/workflows/drop-skill/steps-c/step-03-report.md +136 -0
  51. package/src/workflows/drop-skill/workflow.md +63 -0
  52. package/src/workflows/export-skill/data/managed-section-format.md +33 -8
  53. package/src/workflows/export-skill/data/snippet-format.md +16 -4
  54. package/src/workflows/export-skill/steps-c/step-01-load-skill.md +46 -7
  55. package/src/workflows/export-skill/steps-c/step-02-package.md +2 -2
  56. package/src/workflows/export-skill/steps-c/step-03-generate-snippet.md +39 -7
  57. package/src/workflows/export-skill/steps-c/step-04-update-context.md +185 -13
  58. package/src/workflows/export-skill/steps-c/step-05-token-report.md +2 -2
  59. package/src/workflows/export-skill/steps-c/step-06-summary.md +35 -8
  60. package/src/workflows/quick-skill/steps-c/step-01-resolve-target.md +10 -0
  61. package/src/workflows/quick-skill/steps-c/step-03-quick-extract.md +2 -0
  62. package/src/workflows/quick-skill/steps-c/step-05-validate.md +1 -1
  63. package/src/workflows/quick-skill/steps-c/step-06-write.md +36 -21
  64. package/src/workflows/refine-architecture/steps-c/step-01-init.md +8 -3
  65. package/src/workflows/refine-architecture/steps-c/step-06-report.md +7 -4
  66. package/src/workflows/rename-skill/steps-c/step-01-select.md +281 -0
  67. package/src/workflows/rename-skill/steps-c/step-02-execute.md +391 -0
  68. package/src/workflows/rename-skill/steps-c/step-03-report.md +133 -0
  69. package/src/workflows/rename-skill/workflow.md +64 -0
  70. package/src/workflows/setup-forge/steps-c/step-04-report.md +8 -5
  71. package/src/workflows/shared/health-check.md +231 -0
  72. package/src/workflows/test-skill/steps-c/step-01-init.md +14 -6
  73. package/src/workflows/test-skill/steps-c/step-02-detect-mode.md +1 -1
  74. package/src/workflows/test-skill/steps-c/step-06-report.md +4 -3
  75. package/src/workflows/update-skill/data/remote-source-resolution.md +18 -4
  76. package/src/workflows/update-skill/steps-c/step-01-init.md +15 -8
  77. package/src/workflows/update-skill/steps-c/step-06-write.md +43 -13
  78. package/src/workflows/update-skill/steps-c/step-07-report.md +13 -8
  79. package/src/workflows/verify-stack/steps-c/step-01-init.md +8 -3
  80. package/src/workflows/verify-stack/steps-c/step-06-report.md +6 -3
  81. package/tools/cli/lib/compiler.js +1 -1
  82. package/tools/cli/lib/ui.js +24 -2
@@ -59,23 +59,59 @@ To load the target skill's artifacts, validate they meet agentskills.io spec com
59
59
 
60
60
  Determine the skill to export and any flags:
61
61
 
62
- **Skill Path Discovery:**
62
+ **Skill Path Discovery (version-aware — see [knowledge/version-paths.md](../../../knowledge/version-paths.md)):**
63
63
  - If user provided a skill name or path as argument, use that
64
- - If not provided, search `{skills_output_folder}/*/SKILL.md` for available skills
64
+ - If not provided, discover available skills using the export manifest:
65
+ 1. Read `{skills_output_folder}/.export-manifest.json` — list skill names from `exports`
66
+ 2. For each skill group directory in `{skills_output_folder}/`, check for `{skill_group}/active/{skill-name}/SKILL.md`
67
+ 3. If neither manifest nor `active` symlink yields results, fall back to flat path: `{skills_output_folder}/{skill-name}/SKILL.md`
65
68
  - If multiple skills found, present list and ask user to select
66
69
  - If no skills found, halt: "No skills found in {skills_output_folder}/. Run create-skill first."
67
70
 
68
71
  **Flag Parsing:**
69
- - `--platform` flag: Check if provided (claude/cursor/copilot). Default: `claude`
72
+ - `--platform` flag: Check if explicitly provided (claude/cursor/copilot)
70
73
  - `--dry-run` flag: Check if provided. Default: `false`
71
74
 
75
+ **Platform Resolution:**
76
+
77
+ If `--platform` is explicitly provided, use that single platform as the sole target. If other IDEs are configured in config.yaml, emit a note: "**Note:** Exporting to {platform} only. config.yaml also lists: {other-ides}. Run without `--platform` to export to all configured IDEs."
78
+
79
+ If `--platform` is NOT provided, read the `ides` list from config.yaml and map each IDE to a target platform. Every IDE the installer offers has an explicit mapping — no silent skips.
80
+
81
+ | config.yaml IDE value | Platform | Rationale |
82
+ |----------------------|----------|-----------|
83
+ | `claude-code` | `claude` | native — reads `CLAUDE.md` and `.claude/skills/` |
84
+ | `cursor` | `cursor` | native — reads `.cursorrules` and `.cursor/skills/` |
85
+ | `github-copilot` | `copilot` | native — reads `AGENTS.md` and `.agents/skills/` |
86
+ | `codex` | `copilot` | OpenAI Codex reads `AGENTS.md` (same convention as copilot) |
87
+ | `cline` | `copilot` | uses `AGENTS.md` as a fallback context file |
88
+ | `roo` | `copilot` | uses `AGENTS.md` as a fallback context file |
89
+ | `windsurf` | `copilot` | uses `AGENTS.md` as a fallback context file |
90
+ | `other` | `copilot` | generic AGENTS.md fallback |
91
+ | Any other value | `copilot` | warn: "Unknown IDE '{value}' in config.yaml — defaulting to copilot (AGENTS.md)" |
92
+
93
+ When the same platform is produced by multiple IDE entries (e.g. both `codex` and `cline` map to `copilot`), deduplicate so each platform appears in `target_platforms` only once. Report the deduplication: "Multiple IDEs target the same platform — exporting to {platform} once."
94
+
95
+ **Missing-key handling:** If the `ides` key is absent from config.yaml (older installation or manually edited file), treat it as an empty list.
96
+
97
+ - If mapping produces one or more platforms (after dedup), store as `target_platforms` list
98
+ - If mapping produces zero platforms (empty ides list and no recognized entries), fall back to `["copilot"]` with note: "No IDEs configured in config.yaml — defaulting to copilot (AGENTS.md / .agents/skills/)."
99
+
72
100
  "**Skill:** {skill-name}
73
- **Platform:** {platform} ({target-file})
101
+ **Platform(s):** {platform-list} ({target-file-list})
74
102
  **Dry Run:** {yes/no}"
75
103
 
76
104
  ### 2. Load and Validate Skill Artifacts
77
105
 
78
- Load all files from the skill directory `{skills_output_folder}/{skill-name}/`:
106
+ Resolve the skill's versioned path before loading artifacts:
107
+
108
+ 1. Read `{skills_output_folder}/.export-manifest.json` and look up `{skill-name}` in `exports` to get `active_version`
109
+ 2. If found: resolve to `{skill_package}` = `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/`
110
+ 3. If not in manifest: check for `active` symlink at `{skills_output_folder}/{skill-name}/active` — resolve to `{skill_group}/active/{skill-name}/`
111
+ 4. If neither: fall back to flat path `{skills_output_folder}/{skill-name}/`. If SKILL.md exists at the flat path, auto-migrate per `knowledge/version-paths.md` migration rules
112
+ 5. Store the resolved path as `{resolved_skill_package}` for all subsequent artifact loading
113
+
114
+ Load all files from `{resolved_skill_package}`:
79
115
 
80
116
  **Required Files (hard halt if missing):**
81
117
  - `SKILL.md` — The main skill document
@@ -117,7 +153,7 @@ Load `{sidecar_path}/preferences.yaml` (if exists):
117
153
 
118
154
  ### 4b. Check Test Report (Quality Gate)
119
155
 
120
- Search for a test report at `{forge_data_folder}/{skill_name}/test-report-{skill_name}.md`:
156
+ Search for a test report at `{forge_data_folder}/{skill_name}/{active_version}/test-report-{skill_name}.md` (i.e., `{forge_version}/test-report-{skill_name}.md`). If not found at the versioned path, fall back to `{forge_data_folder}/{skill_name}/test-report-{skill_name}.md`:
121
157
 
122
158
  **If test report found:**
123
159
  - Read frontmatter `testResult` and `score`
@@ -146,7 +182,8 @@ Continue to step 5 regardless — this is advisory, not blocking.
146
182
  **Export Configuration:**
147
183
  | Setting | Value |
148
184
  |---------|-------|
149
- | **Platform** | {platform} → {target-file} |
185
+ | **Platform(s)** | {platform-list} → {target-file-list} |
186
+ | **Explicit --platform** | {yes (user-specified) / no (from config.yaml)} |
150
187
  | **Dry Run** | {yes/no} |
151
188
  | **Passive Context** | {enabled/disabled} |
152
189
 
@@ -183,6 +220,7 @@ ONLY WHEN the user confirms the correct skill is loaded by selecting 'C' will yo
183
220
  - All required files loaded and validated
184
221
  - metadata.json parsed with required fields
185
222
  - Export flags parsed (platform, dry-run)
223
+ - config.yaml ides list consumed for multi-platform resolution when --platform not provided
186
224
  - Forge config checked for passive_context
187
225
  - Clear summary presented to user
188
226
  - User confirms correct skill
@@ -193,6 +231,7 @@ ONLY WHEN the user confirms the correct skill is loaded by selecting 'C' will yo
193
231
  - Not validating metadata.json fields
194
232
  - Not checking preferences.yaml for passive_context opt-out
195
233
  - Proceeding without user confirmation
234
+ - Ignoring config.yaml ides list when no --platform flag is provided
196
235
  - Modifying any skill files (read-only step)
197
236
 
198
237
  **Master Rule:** Skipping steps, optimizing sequences, or not following exact instructions is FORBIDDEN and constitutes SYSTEM FAILURE.
@@ -52,10 +52,10 @@ To assemble and validate an agentskills.io-compliant package structure from the
52
52
 
53
53
  ### 1. Validate Package Structure
54
54
 
55
- Verify the skill directory contains the expected agentskills.io package layout:
55
+ Verify the skill package at `{resolved_skill_package}` (resolved in step-01 via manifest or `active` symlink — see [knowledge/version-paths.md](../../../knowledge/version-paths.md)) contains the expected agentskills.io package layout:
56
56
 
57
57
  ```
58
- {skills_output_folder}/{skill-name}/
58
+ {skill_package} = {skills_output_folder}/{skill-name}/{version}/{skill-name}/
59
59
  ├── SKILL.md ← Required: Active skill document
60
60
  ├── metadata.json ← Required: Machine-readable metadata
61
61
  ├── context-snippet.md ← Will be generated/updated in step-03
@@ -66,6 +66,30 @@ Auto-proceed immediately to {nextStepFile}.
66
66
 
67
67
  Load {snippetFormatData} and read the format template for the skill type.
68
68
 
69
+ ### 2.5. Check Existing Snippet
70
+
71
+ Before generating new snippet content, check for a prior snippet:
72
+
73
+ 1. Read `{resolved_skill_package}/context-snippet.md` if it exists (resolved in step-01 — see [knowledge/version-paths.md](../../../knowledge/version-paths.md))
74
+ 2. If it exists, extract the `|gotchas:` line (if any). Trim leading whitespace and the `|gotchas:` prefix, then capture the remaining content as `prior_gotchas_content`.
75
+ 3. **Detect the carry-forward marker:** If `prior_gotchas_content` starts with the token `[CARRIED]` (whitespace-insensitive), set `prior_gotchas_already_carried = true` and strip the marker before storing the remainder. Otherwise set `prior_gotchas_already_carried = false`.
76
+ 4. **Distinguish empty from absent:** If the `|gotchas:` line exists but has no non-whitespace content after the prefix, treat it as **absent** — set `prior_gotchas = null`. Only a non-empty value counts as a prior gotchas line worth carrying forward.
77
+ 5. If no prior snippet exists at all, set `prior_gotchas = null` and `prior_gotchas_already_carried = false`.
78
+
79
+ These values will be used as a fallback in section 3 if new gotchas cannot be derived. The `[CARRIED]` marker provides a **hard one-cycle expiry**: gotchas that were already carried once will be dropped on the next carry-forward attempt rather than preserved indefinitely.
80
+
81
+ ### 2.7. Resolve Platform Root Path
82
+
83
+ Using the first platform in `target_platforms` (resolved in step-01), resolve the root path prefix:
84
+
85
+ | Platform | `{platform_root}` |
86
+ |----------|-------------------|
87
+ | `claude` | `.claude/skills/` |
88
+ | `cursor` | `.cursor/skills/` |
89
+ | `copilot` | `.agents/skills/` |
90
+
91
+ Store `{platform_root}` for use in snippet generation. The context-snippet.md written to disk uses this platform's root path.
92
+
69
93
  ### 3. Generate Snippet Content
70
94
 
71
95
  **For single skills (`skill_type: "single"`):**
@@ -74,11 +98,15 @@ Load {snippetFormatData} and read the format template for the skill type.
74
98
  2. Select top exports (up to 10 for Deep tier, 5 otherwise). Append `()` to function names.
75
99
  3. Read SKILL.md to extract: heading slugs for `#quick-start` and `#key-types`, inline summary of key types (~10 words)
76
100
  4. **Anchor verification (split-body awareness):** For each section anchor (`#quick-start`, `#key-types`), verify the heading exists in SKILL.md. If a `references/` directory exists and `## Full` headings in SKILL.md are absent or stubs (indicating split-body, not a stack skill's structural references), rewrite the anchor to point to the reference file path (e.g., `references/{file}.md#key-types`). If the heading cannot be resolved in either location, omit that anchor line from the snippet.
77
- 5. Derive gotchas from: T2-future annotations in evidence report (breaking changes), async requirements, version-specific behavior. If no gotchas, omit the gotchas line.
101
+ 5. Derive gotchas from: T2-future annotations in evidence report (breaking changes), async requirements, version-specific behavior.
102
+ - **If new gotchas are derived:** Use them (they supersede any prior gotchas). Write as `|gotchas: {pitfall-1}, {pitfall-2}` with no marker.
103
+ - **If NO new gotchas are derived BUT `prior_gotchas` exists AND `prior_gotchas_already_carried == false`:** First carry-forward cycle — preserve the prior gotchas line, prefixing the value with `[CARRIED]` so the next export can detect that expiry has been reached. Write as `|gotchas: [CARRIED] {prior gotchas content}`. Emit warning: "**Gotchas preserved from prior export (one-cycle carry-forward).** These gotchas will be DROPPED on the next export unless new gotchas are derived or you manually refresh them. Review now if they are still applicable."
104
+ - **If NO new gotchas are derived AND `prior_gotchas` exists AND `prior_gotchas_already_carried == true`:** Expiry reached — drop the gotchas line entirely. Emit warning: "**Stale gotchas dropped** — the prior gotchas were already carried forward once and cannot be derived from the current evidence report. The snippet now has no gotchas line. If the prior gotchas are still relevant, re-add them to the evidence report's T2-future section and re-run export."
105
+ - **If NO new gotchas derived AND no `prior_gotchas`:** Omit the gotchas line.
78
106
 
79
107
  Generate:
80
108
  ```
81
- [{skill-name} v{version}]|root: skills/{skill-name}/
109
+ [{skill-name} v{version}]|root: {platform_root}{skill-name}/
82
110
  |IMPORTANT: {skill-name} v{version} — read SKILL.md before writing {skill-name} code. Do NOT rely on training data.
83
111
  |quick-start:{SKILL.md#quick-start}
84
112
  |api: {export-1}(), {export-2}(), {export-3}, {export-4}(), {export-5}
@@ -88,19 +116,21 @@ Generate:
88
116
 
89
117
  **If fewer exports than limit:** List all available.
90
118
  **If no exports:** Omit the api line.
91
- **If no gotchas derivable:** Omit the gotchas line.
119
+ **If no gotchas derivable AND no prior gotchas to carry forward:** Omit the gotchas line.
92
120
 
93
121
  **For stack skills (`skill_type: "stack"`):**
94
122
 
95
123
  Generate:
96
124
  ```
97
- [{project}-stack v{version}]|root: skills/{project}-stack/
125
+ [{project}-stack v{version}]|root: {platform_root}{project}-stack/
98
126
  |IMPORTANT: {project}-stack — read SKILL.md before writing integration code. Do NOT rely on training data.
99
127
  |stack: {dep-1}@{v1}, {dep-2}@{v2}, {dep-3}@{v3}
100
128
  |integrations: {pattern-1}, {pattern-2}
101
129
  |gotchas: {pitfall-1}, {pitfall-2}
102
130
  ```
103
131
 
132
+ **Stack skill gotchas carry-forward:** Same one-cycle expiry logic as single skills. If no new gotchas derived and `prior_gotchas_already_carried == false`, preserve with the `[CARRIED]` prefix. If already carried once (`prior_gotchas_already_carried == true`), drop the line and warn loudly. See the single-skill steps for the complete protocol.
133
+
104
134
  ### 4. Verify Token Count
105
135
 
106
136
  Estimate token count of generated snippet (approximate: words * 1.3).
@@ -114,7 +144,7 @@ Estimate token count of generated snippet (approximate: words * 1.3).
114
144
  **If dry-run mode:**
115
145
 
116
146
  "**[DRY RUN] context-snippet.md would be written to:**
117
- `{skills_output_folder}/{skill-name}/context-snippet.md`
147
+ `{resolved_skill_package}/context-snippet.md`
118
148
 
119
149
  **Content:**
120
150
  ```
@@ -127,10 +157,10 @@ Hold content in context for step-04.
127
157
 
128
158
  **If NOT dry-run:**
129
159
 
130
- Write the generated content to `{skills_output_folder}/{skill-name}/context-snippet.md`.
160
+ Write the generated content to `{resolved_skill_package}/context-snippet.md`.
131
161
 
132
162
  "**context-snippet.md written.**
133
- **Path:** `{skills_output_folder}/{skill-name}/context-snippet.md`
163
+ **Path:** `{resolved_skill_package}/context-snippet.md`
134
164
  **Estimated tokens:** {count}"
135
165
 
136
166
  ### 6. Proceed to Context Update
@@ -162,10 +192,12 @@ ONLY WHEN snippet generation is complete (or skipped due to passive_context opt-
162
192
  - Token count estimated and within target
163
193
  - File written (or previewed in dry-run)
164
194
  - Passive context opt-out correctly handled (skip when disabled)
195
+ - Prior gotchas checked and carried forward when new derivation yields nothing (with warning)
165
196
  - Auto-proceed to step-04
166
197
 
167
198
  ### ❌ SYSTEM FAILURE:
168
199
 
200
+ - Silently dropping prior gotchas without checking for carry-forward
169
201
  - Deviating from Vercel-aligned indexed format
170
202
  - Including T2 annotations or temporal context
171
203
  - Not checking passive_context setting
@@ -69,27 +69,155 @@ Auto-proceed immediately to {nextStepFile}.
69
69
 
70
70
  Load {managedSectionData} and read the complete format template and three-case logic.
71
71
 
72
- ### 3. Determine Target File
72
+ ### 3. Determine Target File(s)
73
73
 
74
- Based on the `--platform` flag parsed in step-01:
74
+ Using the `target_platforms` list resolved in step-01, determine all target files:
75
75
 
76
76
  | Platform | Target File |
77
77
  |----------|-------------|
78
- | `claude` (default) | CLAUDE.md |
78
+ | `claude` | CLAUDE.md |
79
79
  | `cursor` | .cursorrules |
80
80
  | `copilot` | AGENTS.md |
81
81
 
82
- Resolve target file path at project root: `{project-root}/{target-file}`
82
+ For each platform in `target_platforms`, resolve target file path: `{project-root}/{target-file}`
83
+
84
+ **If multiple platforms:** Sections 4-9a execute as a loop — one full pass per target platform. Each iteration uses the same skill index but rewrites root paths per platform (section 4d) and writes to the platform-specific target file. Section 9b executes once after all iterations complete.
85
+
86
+ **Processing order:** Process platforms in the order listed in `target_platforms`.
87
+
88
+ #### 3b. Detect Orphaned Platform Files (Stale Managed Sections)
89
+
90
+ A platform file becomes orphaned when its IDE is removed from `config.yaml` after a prior export. The file still contains an SKF managed section pointing to stale skill versions, but no future export will rewrite it.
91
+
92
+ Build `orphaned_platform_files` — the set of platform context files that exist on disk with an `<!-- SKF:BEGIN -->` marker but whose platform is NOT in the current `target_platforms` list:
93
+
94
+ 1. For each platform in the full set `{claude, cursor, copilot}`:
95
+ - If the platform is in `target_platforms`, skip (it will be rewritten in the main loop)
96
+ - Otherwise, check whether its target file exists (`CLAUDE.md`, `.cursorrules`, or `AGENTS.md`)
97
+ - If the file exists, read it and check for the `<!-- SKF:BEGIN -->` marker
98
+ - If the marker is present, add the file path to `orphaned_platform_files` along with the platform name
99
+
100
+ 2. If `orphaned_platform_files` is non-empty, emit a warning:
101
+
102
+ "**Orphaned platform files detected.** The following files contain SKF managed sections but their platforms are no longer in `config.yaml` `ides`:
103
+ {list: platform → file path}
104
+
105
+ The managed sections in these files are stale. Options:
106
+ - **(a) clear** — remove the SKF managed section from each orphaned file (surgical marker replacement, leaves user content intact)
107
+ - **(b) keep** — leave them untouched (they will remain stale until you re-add the IDE or delete the file)
108
+ - **(c) rewrite** — also rewrite the orphaned files with the current skill index (use this if the IDE was removed by mistake)"
109
+
110
+ 3. Wait for user choice. In non-interactive mode (dry-run or unattended), default to **(b) keep** and print the warning only.
111
+
112
+ 4. If the user chose **(a) clear**: for each orphaned file, replace everything between `<!-- SKF:BEGIN` and `<!-- SKF:END -->` (inclusive) with an empty string, preserving surrounding content byte-exactly. Record the cleared files in `orphans_cleared`.
113
+
114
+ 5. If the user chose **(c) rewrite**: add each orphaned platform to a separate `rewrite_platforms` list (kept distinct from `target_platforms` so the user's intent to only export to configured IDEs is preserved in the manifest's `platforms` field). Sections 4–9a will loop over `target_platforms + rewrite_platforms` for this run only. Record the rewritten files in `orphans_rewritten`.
115
+
116
+ 6. If the user chose **(b) keep**: record nothing and proceed.
117
+
118
+ This cleanup only runs during interactive export. Drop-skill and rename-skill operate on the manifest's declared platforms and are not responsible for orphan detection.
83
119
 
84
120
  ### 4. Rebuild Complete Skill Index
85
121
 
86
- Scan `{skills_output_folder}/*/context-snippet.md` to find ALL exported skills (not just the current one).
122
+ #### 4a. Read Export Manifest (v2 version-aware)
123
+
124
+ Read `{skills_output_folder}/.export-manifest.json` — see [knowledge/version-paths.md](../../../knowledge/version-paths.md) for the full v2 schema:
125
+
126
+ **If the file exists:** Parse JSON. Check for `schema_version` field:
127
+
128
+ **v2 manifest** (`schema_version: "2"`):
129
+ ```json
130
+ {
131
+ "schema_version": "2",
132
+ "exports": {
133
+ "skill-name": {
134
+ "active_version": "0.6.0",
135
+ "versions": {
136
+ "0.1.0": {
137
+ "platforms": ["claude"],
138
+ "last_exported": "2026-01-15",
139
+ "status": "deprecated"
140
+ },
141
+ "0.5.0": {
142
+ "platforms": ["claude"],
143
+ "last_exported": "2026-03-15",
144
+ "status": "archived"
145
+ },
146
+ "0.6.0": {
147
+ "platforms": ["claude", "copilot"],
148
+ "last_exported": "2026-04-04",
149
+ "status": "active"
150
+ }
151
+ }
152
+ }
153
+ }
154
+ }
155
+ ```
156
+
157
+ **Status values:**
158
+ - `"active"` — currently exported; snippet appears in managed sections
159
+ - `"archived"` — previously exported, not active; files retained for rollback
160
+ - `"deprecated"` — dropped via drop-skill workflow; excluded from all exports (files may or may not exist on disk)
161
+ - `"draft"` — created but never exported
162
+
163
+ **v1 manifest** (no `schema_version` field — migrate in-place to v2):
164
+ 1. For each entry in `exports`, read its `platforms` and `last_exported`
165
+ 2. Resolve the skill's current version from `{resolved_skill_package}/metadata.json`
166
+ 3. Wrap in v2 structure: set `active_version` to the resolved version, create a single entry in `versions` with `status: "active"`, the original `platforms`, and `last_exported`
167
+ 4. Set `schema_version: "2"` at root
168
+ 5. Hold the migrated structure in context (it will be written in section 9b)
169
+
170
+ **If the file does not exist** (first export or migration): Treat as empty — only the current export target will appear in the rebuilt index.
87
171
 
88
- **If no context-snippet.md files are found:** Generate managed section with zero skills — header only, no skill entries.
172
+ #### 4b. Build Exported Skill Set (version-aware)
89
173
 
90
- For each found context-snippet.md:
91
- 1. Read snippet content
92
- 2. Add to skill index
174
+ Determine the set of skills to include in the rebuilt index:
175
+
176
+ 1. Start with all skill names listed in the manifest's `exports` object (if manifest exists)
177
+ 2. For each skill, record its `active_version` from the manifest (v2 schema)
178
+ 3. **Integrity guard — `active_version` must resolve to a versions entry:** Check that `versions[active_version]` exists as a key. If `active_version` is set but there is no matching entry under `versions`, the manifest is inconsistent (possible corruption or a botched v1→v2 migration). Skip this skill and log a loud warning: "**Manifest integrity warning:** `{skill-name}.active_version = v{active_version}` has no matching entry under `versions`. Skipping. Re-run `[EX] Export Skill` on `{skill-name}` to repair the manifest entry."
179
+ 4. **Exclude deprecated skills:** If the `active_version` entry in `versions.{active_version}` has `status: "deprecated"`, skip this skill entirely — it has been dropped via drop-skill workflow and must not appear in the managed section. Log: "Skipping {skill-name} — active version v{active_version} is deprecated"
180
+ 5. Add the current export target skill name (ensures it is always included even before manifest is written) — use the version from `{resolved_skill_package}/metadata.json` as its `active_version`
181
+ 6. This is the **exported skill set** — each entry has a skill name and its resolved `active_version`
182
+
183
+ #### 4c. Resolve and Filter Snippets (manifest-driven — replaces glob scan)
184
+
185
+ Instead of globbing `{skills_output_folder}/*/context-snippet.md`, resolve snippets from the exported skill set built in 4b:
186
+
187
+ **For each skill in the exported skill set:**
188
+ 1. Resolve `{skill_package}` using the skill's `active_version`: `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/`
189
+ 2. Read `{skill_package}/context-snippet.md`
190
+ 3. **If snippet exists:** Add to skill index
191
+ 4. **If snippet does not exist at the versioned path:** Check for `active` symlink at `{skills_output_folder}/{skill-name}/active/{skill-name}/context-snippet.md`. If still not found, skip with warning: "Snippet missing for {skill-name} v{active_version} — skipping from managed section"
192
+
193
+ **Skills NOT in the exported skill set are never scanned** — they have not been through export-skill and must not appear in the managed section (ADR-K).
194
+
195
+ **If no snippets pass the filter:** Generate managed section with zero skills — header only, no skill entries.
196
+
197
+ #### 4d. Rewrite Root Paths for Target Platform
198
+
199
+ The context-snippet.md files on disk contain root paths for the platform they were originally exported to. When assembling the managed section for the current target platform, rewrite root paths if they differ:
200
+
201
+ **Platform root path mapping:**
202
+
203
+ | Platform | Root Path Prefix |
204
+ |----------|-----------------|
205
+ | `claude` | `.claude/skills/` |
206
+ | `cursor` | `.cursor/skills/` |
207
+ | `copilot` | `.agents/skills/` |
208
+ | _(legacy)_ | `skills/` |
209
+
210
+ The legacy `skills/` prefix may appear in snippets exported before platform-aware root paths were introduced, or in draft snippets generated by create-skill/quick-skill.
211
+
212
+ For each snippet being included in the managed section:
213
+
214
+ 1. Read the `root:` value from the snippet's first line
215
+ 2. Detect the current root prefix by matching against the known prefixes above (check platform-specific prefixes first, then fall back to legacy `skills/`)
216
+ 3. If the detected prefix does not match the current target platform's prefix, rewrite it
217
+ 4. Example: if snippet has `root: .claude/skills/my-lib/` but target is `cursor`, rewrite to `root: .cursor/skills/my-lib/`
218
+ 5. Example: if snippet has legacy `root: skills/my-lib/` and target is `copilot`, rewrite to `root: .agents/skills/my-lib/`
219
+
220
+ This ensures each platform's managed section points to the correct platform-specific skill directory, including during migration from pre-platform-aware exports.
93
221
 
94
222
  **Sort skills alphabetically by name.**
95
223
 
@@ -139,7 +267,7 @@ Assemble the complete managed section:
139
267
 
140
268
  ### 7. Present Change Preview
141
269
 
142
- "**Context update prepared.**
270
+ "**Context update prepared.{if multi-platform: ' (platform {i}/{total}: {platform})'}**
143
271
 
144
272
  **Target:** `{project-root}/{target-file}`
145
273
  **Case:** {1: Create / 2: Append / 3: Regenerate}
@@ -170,9 +298,16 @@ Auto-proceed to {nextStepFile}.
170
298
 
171
299
  Display: "**Select:** [C] Continue — write changes to {target-file}"
172
300
 
301
+ **Multi-platform behavior:** When processing multiple platforms, present all platforms' previews together before asking for a single confirmation. After confirmation, write all target files sequentially, verifying each one.
302
+
303
+ "**Targets:** {list all platform → target-file pairs}
304
+ **Ready to write changes to all targets?**"
305
+
306
+ Display: "**Select:** [C] Continue — write changes to all targets"
307
+
173
308
  #### Menu Handling Logic:
174
309
 
175
- - IF C: Write the changes to target file, verify write succeeded, then load, read entire file, then execute {nextStepFile}
310
+ - IF C: Write the changes to all target files (or single target), verify each write succeeded, then load, read entire file, then execute {nextStepFile}
176
311
  - IF Any other: help user respond, then [Redisplay Menu Options](#8-present-menu-options)
177
312
 
178
313
  #### EXECUTION RULES:
@@ -194,6 +329,38 @@ After user confirms with 'C':
194
329
  **If verification fails:**
195
330
  "**WARNING: Write verification failed.** {describe issue}. File may need manual review."
196
331
 
332
+ ### 9b. Update Export Manifest (Non-Dry-Run Only)
333
+
334
+ **This section executes ONCE after all platform iterations complete** (outside the per-platform loop defined in section 3). Only platforms whose writes succeeded in section 9 are recorded.
335
+
336
+ 1. Read `{skills_output_folder}/.export-manifest.json` (or start with `{"schema_version": "2", "exports": {}}` if it does not exist)
337
+ 2. Ensure `schema_version` is `"2"` (if v1 was migrated in section 4a, the migrated structure is already in context)
338
+ 3. Add or update the current skill's entry in v2 format:
339
+ ```json
340
+ "{skill-name}": {
341
+ "active_version": "{version}",
342
+ "versions": {
343
+ "{version}": {
344
+ "platforms": ["{successfully-written platforms}"],
345
+ "last_exported": "{current-date}",
346
+ "status": "active"
347
+ }
348
+ }
349
+ }
350
+ ```
351
+ - `{version}` is the version from `{resolved_skill_package}/metadata.json`
352
+ - Set `platforms` to only the platforms that were successfully written and verified in section 9
353
+ - If the skill already has a manifest entry:
354
+ - Set `active_version` to the current version
355
+ - If the version already exists in `versions`, update its `platforms` (merge, deduplicate), `last_exported`, and set `status: "active"`
356
+ - If this is a new version, add it to `versions` with `status: "active"` and set any previously-active version's status to `"archived"`
357
+ - Preserve all other version entries in `versions` (do not delete archived versions)
358
+ 4. Write the updated manifest to `{skills_output_folder}/.export-manifest.json`
359
+
360
+ **Dry-run mode:** Do NOT update the manifest. Display: "**[DRY RUN] Export manifest would be updated for {skill-name} on platform(s) {platform-list}.**"
361
+
362
+ **Error handling:** If manifest write fails, warn but do not fail the workflow — the managed section was already written successfully.
363
+
197
364
  ## CRITICAL STEP COMPLETION NOTE
198
365
 
199
366
  ONLY WHEN the user confirms changes by selecting 'C' (or auto-proceed in dry-run) and the write is verified will you load and read fully `{nextStepFile}` to execute the token report.
@@ -205,8 +372,11 @@ ONLY WHEN the user confirms changes by selecting 'C' (or auto-proceed in dry-run
205
372
  ### ✅ SUCCESS:
206
373
 
207
374
  - Managed section format loaded from {managedSectionData}
208
- - Target file correctly determined from platform flag
209
- - Complete skill index rebuilt from all exported skills
375
+ - Target file(s) correctly determined from platform flag or config.yaml ides list
376
+ - Multi-platform loop executed for all target_platforms
377
+ - Root paths rewritten per platform in managed section
378
+ - Complete skill index rebuilt from exported skills only (filtered via .export-manifest.json per ADR-K)
379
+ - Export manifest updated after successful write (non-dry-run only)
210
380
  - Correct case detected (create/append/regenerate)
211
381
  - Clear diff preview shown to user
212
382
  - User confirmation received before writing
@@ -218,6 +388,8 @@ ONLY WHEN the user confirms changes by selecting 'C' (or auto-proceed in dry-run
218
388
 
219
389
  - Modifying content outside `<!-- SKF:BEGIN/END -->` markers
220
390
  - Not rebuilding the COMPLETE skill index (only adding current skill)
391
+ - Including un-exported skills in managed section (bypasses ADR-K publishing gate)
392
+ - Updating export manifest during dry-run
221
393
  - Writing without user confirmation
222
394
  - Not verifying write after completion
223
395
  - Not detecting the correct case (create/append/regenerate)
@@ -72,14 +72,14 @@ For each artifact, estimate tokens using the heuristic: **words * 1.3** (approxi
72
72
  | Artifact | Words | Est. Tokens | Notes |
73
73
  |----------|-------|-------------|-------|
74
74
  | context-snippet.md | {n} | ~{t} | Passive context (always-on) |
75
- | Managed section (all skills) | {n} | ~{t} | In {target-file}, all {count} skills |
75
+ | Managed section (all skills) | {n} | ~{t} | In {target-file-list}, all {count} skills |
76
76
  | SKILL.md | {n} | ~{t} | Active skill (on-trigger) |
77
77
  | metadata.json | {n} | ~{t} | Machine-readable |
78
78
  | references/ | {n} | ~{t} | {count} files |
79
79
  | **Package total** | **{n}** | **~{t}** | **All artifacts combined** |
80
80
 
81
81
  **Context Budget Impact:**
82
- - **Always-on cost:** ~{managed-section-tokens} tokens (managed section in {target-file})
82
+ - **Always-on cost:** ~{managed-section-tokens} tokens (managed section in {target-file-list})
83
83
  - **On-trigger cost:** ~{skill-tokens} tokens (when SKILL.md is loaded)
84
84
  - **Full disclosure cost:** ~{total-tokens} tokens (if references/ also loaded)
85
85
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: 'step-06-summary'
3
3
  description: 'Display export summary with distribution instructions'
4
+ nextStepFile: '../../shared/health-check.md'
4
5
  ---
5
6
 
6
7
  # Step 6: Summary
@@ -55,7 +56,7 @@ To present a complete export summary showing all files written, token counts, an
55
56
 
56
57
  **Skill:** {skill-name}
57
58
  **Type:** {skill_type} | **Authority:** {source_authority} | **Tier:** {confidence_tier}
58
- **Platform:** {platform} → {target-file}
59
+ **Platform(s):** {platform-list} → {target-file-list}
59
60
 
60
61
  ---
61
62
 
@@ -64,7 +65,8 @@ To present a complete export summary showing all files written, token counts, an
64
65
  | File | Status | Tokens |
65
66
  |------|--------|--------|
66
67
  | context-snippet.md | {✅ written / ⚠️ skipped (passive off) / 👁️ previewed} | ~{t} |
67
- | {target-file} managed section | {✅ updated (case {n}) / ⚠️ skipped / 👁️ previewed} | ~{t} |
68
+ | {target-file-1} managed section | {✅ updated (case {n}) / ⚠️ skipped / 👁️ previewed} | ~{t} |
69
+ | {target-file-N} managed section | {✅ updated (case {n}) / ⚠️ skipped / 👁️ previewed} | ~{t} |
68
70
  | Package structure | ✅ validated | ~{t} total |
69
71
 
70
72
  **Total context cost:** ~{always-on-tokens} tokens always-on, ~{on-trigger-tokens} tokens on-trigger"
@@ -102,7 +104,7 @@ Your skill is committed to the project's `skills/` directory and ships with your
102
104
 
103
105
  **Team members** will automatically have access when they pull the latest changes.
104
106
 
105
- **To update team context:** Ensure {target-file} is committed with the managed section update."
107
+ **To update team context:** Ensure all target files ({target-file-list}) are committed with the managed section updates."
106
108
 
107
109
  **If `community`:**
108
110
 
@@ -110,12 +112,30 @@ Your skill is committed to the project's `skills/` directory and ships with your
110
112
 
111
113
  Your skill is generated from an external dependency for local use.
112
114
 
113
- **Location:** `{skills_output_folder}/{skill-name}/`
115
+ **Location:** `{skills_output_folder}/{skill-name}/{version}/{skill-name}/`
114
116
  **Scope:** This project only — not for publishing to agentskills.io
115
117
 
116
118
  **Note:** Community skills are generated from third-party source code. Only `official` skills (generated by the library maintainer) should be published to the ecosystem."
117
119
 
118
- ### 3. Dry Run Reminder (If Applicable)
120
+ ### 3. Use It In This Project
121
+
122
+ Always show this section (regardless of `source_authority`) so the author can install the skill they just forged into the current project and try it immediately:
123
+
124
+ "### Use It In This Project
125
+
126
+ To install this skill into the current project right now:
127
+
128
+ ```
129
+ npx skills add {resolved_skill_package}
130
+ ```
131
+
132
+ Replace `{resolved_skill_package}` with the absolute path to the package folder shown above (from step-02), e.g. `{skills_output_folder}/{skill-name}/{version}/{skill-name}/`.
133
+
134
+ For other source formats (registry name, git URL, tarball, etc.), see the **Installation → Source Formats** section at <https://www.npmjs.com/package/skills>.
135
+
136
+ If the installed skill's commands are not available in the same IDE session, reload plugins (e.g. for Claude Code users, run `/reload-plugins`) or restart your AI editor. Next time you will see the command `/{skill-name}` (e.g. `/{skill-name}`)."
137
+
138
+ ### 4. Dry Run Reminder (If Applicable)
119
139
 
120
140
  **If dry-run mode was active:**
121
141
 
@@ -125,7 +145,7 @@ No files were written. To run the export for real:
125
145
 
126
146
  **Re-run without `--dry-run`** to write all files."
127
147
 
128
- ### 4. Recommended Next Steps
148
+ ### 5. Recommended Next Steps
129
149
 
130
150
  "### Next Steps
131
151
 
@@ -133,15 +153,19 @@ No files were written. To run the export for real:
133
153
  - **update-skill** — After refactoring source code, regenerate the skill
134
154
  - **test-skill** — Verify skill completeness and accuracy"
135
155
 
136
- ### 5. Workflow Complete
156
+ ### 6. Workflow Complete
137
157
 
138
158
  "---
139
159
 
140
160
  **Skill forged and delivered.** ⚒️"
141
161
 
162
+ ### 7. Workflow Health Check
163
+
164
+ Load and execute `{nextStepFile}` for workflow self-improvement check.
165
+
142
166
  ## CRITICAL STEP COMPLETION NOTE
143
167
 
144
- This is the final step. The workflow is complete. No further steps to load.
168
+ This step chains to the shared health check. After the health check completes, the export-skill workflow is fully done.
145
169
 
146
170
  ---
147
171
 
@@ -152,6 +176,8 @@ This is the final step. The workflow is complete. No further steps to load.
152
176
  - Complete summary with all files and their status
153
177
  - Token counts included from step-05
154
178
  - Distribution instructions appropriate for source_authority
179
+ - Local install command (`npx skills add {resolved_skill_package}`) displayed with npmjs.com/package/skills link for alternate source formats
180
+ - Plugin reload hint shown (reload plugins or restart AI editor to see `/{skill-name}`)
155
181
  - Dry-run correctly indicated (if applicable)
156
182
  - Recommended next workflows listed
157
183
  - Clear workflow completion signal
@@ -160,6 +186,7 @@ This is the final step. The workflow is complete. No further steps to load.
160
186
 
161
187
  - Missing files from summary
162
188
  - Wrong distribution instructions for source_authority
189
+ - Omitting the local install command / npmjs source-formats link
163
190
  - Not indicating dry-run status
164
191
  - Writing additional files (console-only step)
165
192
  - Not ending the workflow cleanly
@@ -69,6 +69,16 @@ Provide a **GitHub URL** or **package name** and I'll resolve it to source and c
69
69
 
70
70
  Wait for user input.
71
71
 
72
+ ### 1b. Parse Version Targeting
73
+
74
+ **Version targeting:** If the user input contains `@` followed by a semver-like string (e.g., `cognee@0.5.0`, `https://github.com/org/repo@2.1.0-beta`), parse it as:
75
+ - **Package/URL:** everything before the last `@`
76
+ - **Target version:** everything after the last `@`
77
+
78
+ Store the target version as `target_version` in the extraction context. When present, this version overrides auto-detection (same behavior as `target_version` in the skill-brief schema).
79
+
80
+ If no `@version` suffix is present, proceed as today — version will be auto-detected.
81
+
72
82
  ### 2. Classify Input Type
73
83
 
74
84
  **If input starts with `https://github.com/` or `github.com/`:**
@@ -54,6 +54,8 @@ To read the resolved GitHub repository source and extract the public API surface
54
54
 
55
55
  **CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
56
56
 
57
+ **Ref-aware source reading:** When `source_ref` is set from tag resolution (see step-01), append `?ref={source_ref}` to all GitHub API content and tree requests (e.g., `gh api repos/{owner}/{repo}/contents/{path}?ref={source_ref}`) to read from the tagged version. When using web browsing, use the tagged URL format (e.g., `github.com/{owner}/{repo}/blob/{source_ref}/{path}`). This ensures extraction reads from the same source version resolved during tag resolution.
58
+
57
59
  ### 1. Read README
58
60
 
59
61
  Read `README.md` from the repository root via web browsing.
@@ -105,7 +105,7 @@ Check that SKILL.md has these required sections populated:
105
105
  Check context-snippet.md format compliance:
106
106
 
107
107
  - [ ] **Vercel-aligned indexed format** — pipe-delimited with version, retrieval instruction, section anchors
108
- - [ ] **First line** matches pattern: `[{name} v{version}]|root: skills/{name}/`
108
+ - [ ] **First line** matches pattern: `[{name} v{version}]|root: {prefix}{name}/` where prefix is `skills/` or a platform root (`.claude/skills/`, `.cursor/skills/`, `.agents/skills/`)
109
109
  - [ ] **Second line** starts with: `|IMPORTANT:`
110
110
  - [ ] **Approximate token count** is ~80-120 tokens
111
111