bmad-module-skill-forge 1.4.0 → 1.5.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +0 -8
- package/docs/_data/pinned.yaml +1 -1
- package/docs/_internal/STABILITY.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/examples.md +1 -1
- package/docs/workflows.md +5 -5
- package/package.json +2 -2
- package/src/README.md +1 -1
- package/src/knowledge/ccc-bridge.md +12 -12
- package/src/knowledge/qmd-registry.md +5 -5
- package/src/shared/health-check.md +5 -5
- package/src/shared/references/description-guard-protocol.md +100 -0
- package/src/shared/references/output-contract-schema.md +1 -1
- package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +6 -6
- package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +9 -3
- package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +149 -0
- package/src/shared/scripts/schemas/skill-brief.v1.json +22 -2
- package/src/shared/scripts/skf-build-change-manifest.py +420 -0
- package/src/shared/scripts/skf-check-workspace-drift.py +321 -0
- package/src/shared/scripts/skf-compare-file-hashes.py +357 -0
- package/src/shared/scripts/skf-description-guard.py +359 -0
- package/src/shared/scripts/skf-detect-language.py +2 -2
- package/src/shared/scripts/skf-detect-scripts-assets.py +613 -0
- package/src/shared/scripts/skf-detect-tools.py +97 -8
- package/src/shared/scripts/skf-detect-workspaces.py +1 -1
- package/src/shared/scripts/skf-disqualify-candidates.py +576 -0
- package/src/shared/scripts/skf-emit-brief-result-envelope.py +3 -3
- package/src/shared/scripts/skf-emit-result-envelope.py +93 -9
- package/src/shared/scripts/skf-enumerate-stack-skills.py +514 -0
- package/src/shared/scripts/skf-forge-tier-rw.py +11 -11
- package/src/shared/scripts/skf-hash-content.py +284 -0
- package/src/shared/scripts/skf-load-provenance.py +295 -0
- package/src/shared/scripts/skf-merge-ccc-exclusions.py +45 -1
- package/src/shared/scripts/skf-pair-intersect.py +250 -0
- package/src/shared/scripts/skf-provenance-gap-dispatch.py +433 -0
- package/src/shared/scripts/skf-qmd-classify-collections.py +42 -8
- package/src/shared/scripts/skf-recommend-scope-type.py +2 -2
- package/src/shared/scripts/skf-render-quick-metadata.py +2 -2
- package/src/shared/scripts/skf-resolve-authoritative-files.py +504 -0
- package/src/shared/scripts/skf-scan-manifests.py +738 -0
- package/src/shared/scripts/skf-scan-skill-md-structure.py +375 -0
- package/src/shared/scripts/skf-update-active-symlink.py +315 -0
- package/src/shared/scripts/skf-validate-brief-inputs.py +5 -5
- package/src/shared/scripts/skf-validate-brief-schema.py +348 -0
- package/src/shared/scripts/skf-write-skill-brief.py +61 -5
- package/src/skf-analyze-source/SKILL.md +69 -16
- package/src/skf-analyze-source/assets/skill-brief-schema.md +1 -1
- package/src/skf-analyze-source/customize.toml +55 -0
- package/src/skf-analyze-source/{steps-c/step-01b-continue.md → references/continue.md} +12 -12
- package/src/skf-analyze-source/{steps-c/step-06-generate-briefs.md → references/generate-briefs.md} +29 -10
- package/src/skf-analyze-source/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
- package/src/skf-analyze-source/{steps-c/step-03-identify-units.md → references/identify-units.md} +44 -14
- package/src/skf-analyze-source/{steps-c/step-01-init.md → references/init.md} +27 -6
- package/src/skf-analyze-source/{steps-c/step-04-map-and-detect.md → references/map-and-detect.md} +52 -25
- package/src/skf-analyze-source/{steps-c/step-05-recommend.md → references/recommend.md} +15 -8
- package/src/skf-analyze-source/{steps-c/step-02-scan-project.md → references/scan-project.md} +12 -10
- package/src/skf-analyze-source/references/unit-detection-heuristics.md +2 -0
- package/src/skf-analyze-source/templates/analysis-report-template.md +6 -6
- package/src/skf-audit-skill/SKILL.md +66 -15
- package/src/skf-audit-skill/assets/drift-report-template.md +6 -5
- package/src/skf-audit-skill/customize.toml +49 -0
- package/src/skf-audit-skill/{steps-c/step-07-health-check.md → references/health-check.md} +5 -3
- package/src/skf-audit-skill/references/init.md +305 -0
- package/src/skf-audit-skill/{steps-c/step-02-re-index.md → references/re-index.md} +11 -11
- package/src/skf-audit-skill/{steps-c/step-06-report.md → references/report.md} +25 -7
- package/src/skf-audit-skill/{steps-c/step-04-semantic-diff.md → references/semantic-diff.md} +6 -6
- package/src/skf-audit-skill/{steps-c/step-05-severity-classify.md → references/severity-classify.md} +5 -5
- package/src/skf-audit-skill/references/severity-rules.md +2 -0
- package/src/skf-audit-skill/{steps-c/step-03-structural-diff.md → references/structural-diff.md} +29 -16
- package/src/skf-brief-skill/SKILL.md +48 -18
- package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
- package/src/skf-brief-skill/assets/skill-brief-schema.md +32 -2
- package/src/skf-brief-skill/customize.toml +44 -0
- package/src/skf-brief-skill/{steps-c/step-02-analyze-target.md → references/analyze-target.md} +5 -5
- package/src/skf-brief-skill/{steps-c/step-04-confirm-brief.md → references/confirm-brief.md} +13 -10
- package/src/skf-brief-skill/references/draft-checkpoint.md +4 -4
- package/src/skf-brief-skill/{steps-c/step-01-gather-intent.md → references/gather-intent.md} +24 -24
- package/src/skf-brief-skill/references/headless-args.md +9 -9
- package/src/skf-brief-skill/references/headless-source-authority-detection.md +1 -1
- package/src/skf-brief-skill/{steps-c/step-06-health-check.md → references/health-check.md} +4 -2
- package/src/skf-brief-skill/references/portfolio-similarity-check.md +2 -2
- package/src/skf-brief-skill/references/qmd-collection-registration.md +1 -1
- package/src/skf-brief-skill/{steps-c/step-03-scope-definition.md → references/scope-definition.md} +19 -16
- package/src/skf-brief-skill/references/version-resolution.md +2 -2
- package/src/skf-brief-skill/{steps-c/step-05-write-brief.md → references/write-brief.md} +11 -10
- package/src/skf-create-skill/SKILL.md +25 -19
- package/src/skf-create-skill/assets/compile-assembly-rules.md +3 -3
- package/src/skf-create-skill/assets/skill-sections.md +5 -5
- package/src/skf-create-skill/assets/tessl-dismissal-rules.md +11 -11
- package/src/skf-create-skill/customize.toml +35 -0
- package/src/skf-create-skill/references/authoritative-files-protocol.md +142 -0
- package/src/skf-create-skill/{steps-c/step-05-compile.md → references/compile.md} +16 -16
- package/src/skf-create-skill/{steps-c/step-03d-component-extraction.md → references/component-extraction.md} +16 -16
- package/src/skf-create-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +4 -4
- package/src/skf-create-skill/{steps-c/step-04-enrich.md → references/enrich.md} +3 -3
- package/src/skf-create-skill/{steps-c/step-03-extract.md → references/extract.md} +52 -120
- package/src/skf-create-skill/references/extraction-patterns.md +8 -8
- package/src/skf-create-skill/{steps-c/step-07-generate-artifacts.md → references/generate-artifacts.md} +17 -9
- package/src/skf-create-skill/{steps-c/step-09-health-check.md → references/health-check.md} +4 -2
- package/src/skf-create-skill/{steps-c/step-01-load-brief.md → references/load-brief.md} +40 -32
- package/src/skf-create-skill/{steps-c/step-08-report.md → references/report.md} +8 -8
- package/src/skf-create-skill/references/source-resolution-protocols.md +6 -6
- package/src/skf-create-skill/{steps-c/sub/step-02b-ccc-discover.md → references/sub/ccc-discover.md} +5 -5
- package/src/skf-create-skill/{steps-c/sub/step-03c-fetch-docs.md → references/sub/fetch-docs.md} +28 -12
- package/src/skf-create-skill/{steps-c/sub/step-03b-fetch-temporal.md → references/sub/fetch-temporal.md} +81 -50
- package/src/skf-create-skill/{steps-c/step-06-validate.md → references/validate.md} +46 -26
- package/src/skf-create-stack-skill/SKILL.md +76 -17
- package/src/skf-create-stack-skill/assets/provenance-map-schema.md +102 -0
- package/src/skf-create-stack-skill/assets/stack-skill-template.md +1 -1
- package/src/skf-create-stack-skill/customize.toml +46 -0
- package/src/skf-create-stack-skill/{steps-c/step-06-compile-stack.md → references/compile-stack.md} +6 -5
- package/src/skf-create-stack-skill/references/compose-mode-rules.md +3 -1
- package/src/skf-create-stack-skill/{steps-c/step-05-detect-integrations.md → references/detect-integrations.md} +32 -11
- package/src/skf-create-stack-skill/{steps-c/step-02-detect-manifests.md → references/detect-manifests.md} +28 -28
- package/src/skf-create-stack-skill/{steps-c/step-07-generate-output.md → references/generate-output.md} +11 -85
- package/src/skf-create-stack-skill/{steps-c/step-10-health-check.md → references/health-check.md} +4 -2
- package/src/skf-create-stack-skill/{steps-c/step-01-init.md → references/init.md} +70 -4
- package/src/skf-create-stack-skill/references/integration-patterns.md +2 -0
- package/src/skf-create-stack-skill/references/manifest-patterns.md +2 -0
- package/src/skf-create-stack-skill/{steps-c/step-04-parallel-extract.md → references/parallel-extract.md} +40 -17
- package/src/skf-create-stack-skill/{steps-c/step-03-rank-and-confirm.md → references/rank-and-confirm.md} +5 -4
- package/src/skf-create-stack-skill/{steps-c/step-09-report.md → references/report.md} +3 -3
- package/src/skf-create-stack-skill/{steps-c/step-08-validate.md → references/validate.md} +6 -6
- package/src/skf-drop-skill/SKILL.md +84 -12
- package/src/skf-drop-skill/customize.toml +57 -0
- package/src/skf-drop-skill/{steps-c/step-02-execute.md → references/execute.md} +49 -34
- package/src/skf-drop-skill/{steps-c/step-04-health-check.md → references/health-check.md} +6 -4
- package/src/skf-drop-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
- package/src/skf-drop-skill/{steps-c/step-01-select.md → references/select.md} +63 -15
- package/src/skf-export-skill/SKILL.md +85 -16
- package/src/skf-export-skill/assets/managed-section-format.md +3 -3
- package/src/skf-export-skill/assets/snippet-format.md +2 -2
- package/src/skf-export-skill/customize.toml +49 -0
- package/src/skf-export-skill/{steps-c/step-03-generate-snippet.md → references/generate-snippet.md} +18 -12
- package/src/skf-export-skill/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
- package/src/skf-export-skill/{steps-c/step-01-load-skill.md → references/load-skill.md} +21 -51
- package/src/skf-export-skill/references/manifest-rebuild.md +68 -0
- package/src/skf-export-skill/references/multi-skill-mode.md +38 -0
- package/src/skf-export-skill/references/orphan-context-detection.md +75 -0
- package/src/skf-export-skill/references/orphan-row-detection.md +102 -0
- package/src/skf-export-skill/{steps-c/step-02-package.md → references/package.md} +7 -7
- package/src/skf-export-skill/references/preflight-snippet-root-probe.md +74 -0
- package/src/skf-export-skill/{steps-c/step-06-summary.md → references/summary.md} +30 -6
- package/src/skf-export-skill/{steps-c/step-05-token-report.md → references/token-report.md} +5 -5
- package/src/skf-export-skill/{steps-c/step-04-update-context.md → references/update-context.md} +116 -91
- package/src/skf-quick-skill/SKILL.md +63 -123
- package/src/skf-quick-skill/customize.toml +44 -0
- package/src/skf-quick-skill/references/batch-mode.md +102 -0
- package/src/skf-quick-skill/{steps-c/step-04-compile.md → references/compile.md} +10 -10
- package/src/skf-quick-skill/{steps-c/step-02-ecosystem-check.md → references/ecosystem-check.md} +5 -5
- package/src/skf-quick-skill/{steps-c/step-06-finalize.md → references/finalize.md} +7 -7
- package/src/skf-quick-skill/{steps-c/step-07-health-check.md → references/health-check.md} +3 -3
- package/src/skf-quick-skill/{steps-c/step-03-quick-extract.md → references/quick-extract.md} +5 -5
- package/src/skf-quick-skill/references/registry-resolution.md +2 -0
- package/src/skf-quick-skill/{steps-c/step-01-resolve-target.md → references/resolve-target.md} +14 -10
- package/src/skf-quick-skill/{steps-c/step-05-write-and-validate.md → references/write-and-validate.md} +4 -4
- package/src/skf-refine-architecture/SKILL.md +86 -16
- package/src/skf-refine-architecture/customize.toml +49 -0
- package/src/skf-refine-architecture/{steps-c/step-05-compile.md → references/compile.md} +4 -4
- package/src/skf-refine-architecture/{steps-c/step-02-gap-analysis.md → references/gap-analysis.md} +5 -5
- package/src/skf-refine-architecture/{steps-c/step-07-health-check.md → references/health-check.md} +6 -4
- package/src/skf-refine-architecture/{steps-c/step-04-improvements.md → references/improvements.md} +5 -5
- package/src/skf-refine-architecture/references/init.md +144 -0
- package/src/skf-refine-architecture/{steps-c/step-03-issue-detection.md → references/issue-detection.md} +5 -5
- package/src/skf-refine-architecture/references/refinement-rules.md +2 -0
- package/src/skf-refine-architecture/{steps-c/step-06-report.md → references/report.md} +14 -5
- package/src/skf-rename-skill/SKILL.md +82 -12
- package/src/skf-rename-skill/customize.toml +52 -0
- package/src/skf-rename-skill/{steps-c/step-02-execute.md → references/execute.md} +94 -99
- package/src/skf-rename-skill/references/health-check.md +30 -0
- package/src/skf-rename-skill/references/rebuild-context.md +110 -0
- package/src/skf-rename-skill/{steps-c/step-03-report.md → references/report.md} +13 -5
- package/src/skf-rename-skill/{steps-c/step-01-select.md → references/select.md} +59 -20
- package/src/skf-setup/SKILL.md +35 -35
- package/src/skf-setup/customize.toml +33 -0
- package/src/skf-setup/{steps-c/step-03-auto-index.md → references/auto-index.md} +10 -18
- package/src/skf-setup/{steps-c/step-01b-ccc-index.md → references/ccc-index.md} +14 -22
- package/src/skf-setup/{steps-c/step-01-detect-and-tier.md → references/detect-and-tier.md} +23 -10
- package/src/skf-setup/{steps-c/step-05-health-check.md → references/health-check.md} +1 -1
- package/src/skf-setup/{steps-c/step-04-report.md → references/report.md} +21 -19
- package/src/skf-setup/references/tier-rules.md +1 -1
- package/src/skf-setup/{steps-c/step-02-write-config.md → references/write-config.md} +14 -13
- package/src/skf-test-skill/SKILL.md +77 -15
- package/src/skf-test-skill/customize.toml +54 -0
- package/src/skf-test-skill/{steps-c/step-04-coherence-check.md → references/coherence-check.md} +28 -71
- package/src/skf-test-skill/{steps-c/step-03-coverage-check.md → references/coverage-check.md} +16 -39
- package/src/skf-test-skill/{steps-c/step-02-detect-mode.md → references/detect-mode.md} +4 -26
- package/src/skf-test-skill/{steps-c/step-04b-external-validators.md → references/external-validators.md} +6 -28
- package/src/skf-test-skill/references/health-check.md +14 -0
- package/src/skf-test-skill/{steps-c/step-01-init.md → references/init.md} +21 -37
- package/src/skf-test-skill/references/migration-section-rules.md +4 -2
- package/src/skf-test-skill/{steps-c/step-06-report.md → references/report.md} +41 -51
- package/src/skf-test-skill/{steps-c/step-05-score.md → references/score.md} +26 -43
- package/src/skf-test-skill/references/scoring-rules.md +8 -6
- package/src/skf-test-skill/references/source-access-protocol.md +7 -5
- package/src/skf-test-skill/scripts/compute-score.py +88 -17
- package/src/skf-test-skill/templates/test-report-template.md +13 -13
- package/src/skf-update-skill/SKILL.md +23 -14
- package/src/skf-update-skill/customize.toml +44 -0
- package/src/skf-update-skill/{steps-c/step-02-detect-changes.md → references/detect-changes.md} +176 -68
- package/src/skf-update-skill/references/health-check.md +32 -0
- package/src/skf-update-skill/{steps-c/step-01-init.md → references/init.md} +56 -8
- package/src/skf-update-skill/references/manual-section-rules.md +4 -0
- package/src/skf-update-skill/references/merge-conflict-rules.md +4 -0
- package/src/skf-update-skill/{steps-c/step-04-merge.md → references/merge.md} +8 -8
- package/src/skf-update-skill/{steps-c/step-03-re-extract.md → references/re-extract.md} +53 -44
- package/src/skf-update-skill/references/remote-source-resolution.md +5 -1
- package/src/skf-update-skill/references/report.md +214 -0
- package/src/skf-update-skill/{steps-c/step-05-validate.md → references/validate.md} +5 -5
- package/src/skf-update-skill/{steps-c/step-06-write.md → references/write.md} +73 -51
- package/src/skf-verify-stack/SKILL.md +89 -17
- package/src/skf-verify-stack/assets/feasibility-report-template.md +4 -4
- package/src/skf-verify-stack/customize.toml +50 -0
- package/src/skf-verify-stack/references/coverage-patterns.md +2 -2
- package/src/skf-verify-stack/{steps-c/step-02-coverage.md → references/coverage.md} +7 -7
- package/src/skf-verify-stack/{steps-c/step-07-health-check.md → references/health-check.md} +7 -5
- package/src/skf-verify-stack/references/init.md +166 -0
- package/src/skf-verify-stack/references/integration-verification-rules.md +1 -1
- package/src/skf-verify-stack/{steps-c/step-03-integrations.md → references/integrations.md} +12 -12
- package/src/skf-verify-stack/{steps-c/step-06-report.md → references/report.md} +22 -41
- package/src/skf-verify-stack/{steps-c/step-04-requirements.md → references/requirements.md} +7 -7
- package/src/skf-verify-stack/{steps-c/step-05-synthesize.md → references/synthesize.md} +8 -8
- package/tools/validate-docs-drift.js +1 -1
- package/src/skf-audit-skill/steps-c/step-01-init.md +0 -221
- package/src/skf-refine-architecture/steps-c/step-01-init.md +0 -136
- package/src/skf-rename-skill/steps-c/step-04-health-check.md +0 -22
- package/src/skf-test-skill/steps-c/step-07-health-check.md +0 -25
- package/src/skf-update-skill/steps-c/step-07-report.md +0 -148
- package/src/skf-update-skill/steps-c/step-08-health-check.md +0 -22
- package/src/skf-verify-stack/steps-c/step-01-init.md +0 -178
|
@@ -70,14 +70,14 @@ All other IDEs use AGENTS.md as the context file, each with its own skill direct
|
|
|
70
70
|
|
|
71
71
|
**`snippet_skill_root_override` (optional):** Authoring repos where all skills live under one shared on-disk directory (e.g. `skills/`) that does not match any per-IDE skill root may set `snippet_skill_root_override: skills/` in `config.yaml`. When set:
|
|
72
72
|
|
|
73
|
-
- `export-skill/step
|
|
74
|
-
- `export-skill/step
|
|
73
|
+
- `export-skill/step 3` §2.7 uses the override as `{skill_root}` for snippet generation instead of the IDE-mapped value
|
|
74
|
+
- `export-skill/step 4` §4d (and its equivalents in `drop-skill/step 2` and `rename-skill/step 2`) treat the override as the effective target prefix for the managed-section rebuild: snippets whose prefix already matches the override pass through unchanged, and any other prefix — including per-IDE prefixes carried by sibling snippets that were exported before the override was adopted, and legacy `skills/` drafts — is rewritten to the override so the rebuilt managed section uniformly references the real on-disk location
|
|
75
75
|
|
|
76
76
|
Consuming projects (the common case) omit the field and keep the default IDE-mapping behavior. The override is a narrow escape hatch for repos that author skills into `{skills_output_folder}` and never duplicate them into `.claude/skills/`-style directories.
|
|
77
77
|
|
|
78
78
|
### Consumers
|
|
79
79
|
|
|
80
|
-
This mapping is the single source of truth. Workflows that need it: `export-skill/step
|
|
80
|
+
This mapping is the single source of truth. Workflows that need it: `export-skill/step 1` (resolves `target_context_files` from config.yaml IDE list), `export-skill/step 4` (applies four-case logic and rewrites root paths when writing managed sections), `drop-skill/step 2` and `rename-skill/step 2` (rebuild context files after a management operation).
|
|
81
81
|
|
|
82
82
|
## Four-Case Logic
|
|
83
83
|
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
The snippet `root:` path must reflect the IDE's actual skill directory — its `skill_root` from the IDE → Context File Mapping table in `managed-section-format.md`. Each IDE has its own skill directory (e.g., `.claude/skills/`, `.windsurf/skills/`, `.github/skills/`).
|
|
6
6
|
|
|
7
|
-
The root path in context-snippet.md on disk uses the **`skill_root` of the first entry in `target_context_files`** (resolved in step
|
|
7
|
+
The root path in context-snippet.md on disk uses the **`skill_root` of the first entry in `target_context_files`** (resolved in step 1 from config.yaml IDE mapping). When assembling managed sections for other context files, step 4 rewrites root paths to match the target context file's skill root.
|
|
8
8
|
|
|
9
|
-
**Authoring-repo override:** If `snippet_skill_root_override` is set in `config.yaml`, it replaces the IDE-mapped value for snippet generation and freezes matching prefixes against step
|
|
9
|
+
**Authoring-repo override:** If `snippet_skill_root_override` is set in `config.yaml`, it replaces the IDE-mapped value for snippet generation and freezes matching prefixes against step 4 rewrites. See the "Resolution rules" section in `managed-section-format.md` for the full semantics.
|
|
10
10
|
|
|
11
11
|
## Format Rules
|
|
12
12
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# DO NOT EDIT -- overwritten on every update.
|
|
2
|
+
#
|
|
3
|
+
# Workflow customization surface for skf-export-skill.
|
|
4
|
+
|
|
5
|
+
[workflow]
|
|
6
|
+
|
|
7
|
+
# --- Configurable below. Overrides merge per BMad structural rules: ---
|
|
8
|
+
# scalars: override wins • arrays (persistent_facts, activation_steps_*): append
|
|
9
|
+
# arrays-of-tables with `code`/`id`: replace matching items, append new ones.
|
|
10
|
+
|
|
11
|
+
# Steps to run before the standard activation (uv probe, config load).
|
|
12
|
+
# Overrides append. Use for org-wide pre-flight checks (auth, network,
|
|
13
|
+
# compliance) that must precede any export work.
|
|
14
|
+
|
|
15
|
+
activation_steps_prepend = []
|
|
16
|
+
|
|
17
|
+
# Steps to run after activation but before the first stage executes.
|
|
18
|
+
# Overrides append. Use for context loads or banner customization that
|
|
19
|
+
# should run once activation completes successfully.
|
|
20
|
+
|
|
21
|
+
activation_steps_append = []
|
|
22
|
+
|
|
23
|
+
# Persistent facts the workflow keeps in mind for the whole run
|
|
24
|
+
# (publishing standards, distribution-instruction house style, snippet
|
|
25
|
+
# token-budget guardrails). Overrides append.
|
|
26
|
+
#
|
|
27
|
+
# Each entry is either:
|
|
28
|
+
# - a literal sentence, e.g. "All exported skills must include a CHANGELOG entry."
|
|
29
|
+
# - a file reference prefixed with `file:`, e.g.
|
|
30
|
+
# "file:{project-root}/docs/export-policy.md" (globs supported; file
|
|
31
|
+
# contents are loaded and treated as facts).
|
|
32
|
+
|
|
33
|
+
persistent_facts = [
|
|
34
|
+
"file:{project-root}/**/project-context.md",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
# --- Optional asset overrides ---
|
|
38
|
+
#
|
|
39
|
+
# Lift the canonical asset paths so orgs can substitute house-style copies
|
|
40
|
+
# without forking the skill. Empty string = use the bundled default.
|
|
41
|
+
|
|
42
|
+
managed_section_format_path = ""
|
|
43
|
+
snippet_format_path = ""
|
|
44
|
+
|
|
45
|
+
# Override the manifest location. Empty = use
|
|
46
|
+
# {skills_output_folder}/.export-manifest.json. Useful for orgs that want
|
|
47
|
+
# a cross-project manifest at a stable path (e.g. ~/.skf/export-manifest.json).
|
|
48
|
+
|
|
49
|
+
export_manifest_path = ""
|
package/src/skf-export-skill/{steps-c/step-03-generate-snippet.md → references/generate-snippet.md}
RENAMED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
3
|
-
snippetFormatData: '
|
|
2
|
+
nextStepFile: 'update-context.md'
|
|
3
|
+
snippetFormatData: '{snippetFormatPath}'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
<!-- Config: communicate in {communication_language}. Generate snippet content in {document_output_language}. -->
|
|
7
|
+
|
|
6
8
|
# Step 3: Generate Snippet
|
|
7
9
|
|
|
8
10
|
## STEP GOAL:
|
|
@@ -12,16 +14,14 @@ To generate or update context-snippet.md for the skill in the Vercel-aligned ind
|
|
|
12
14
|
## Rules
|
|
13
15
|
|
|
14
16
|
- Focus only on generating the context-snippet.md content — T1-now only, no T2 annotations
|
|
15
|
-
- If `passive_context: false` was detected in step
|
|
16
|
-
- **Multi-skill mode:** when step
|
|
17
|
+
- If `passive_context: false` was detected in step 1, skip this step entirely
|
|
18
|
+
- **Multi-skill mode:** when step 1 loaded more than one skill (`len(skill_batch) > 1`), iterate sections 2–5 per skill. Each skill has its own prior-gotchas carry-forward state (§2.5) — do not share state across skills. §2.7 resolves `{skill_root}` once for the run (it depends on `target_context_files`, not the skill). See step 1 §1c.
|
|
17
19
|
|
|
18
20
|
## MANDATORY SEQUENCE
|
|
19
21
|
|
|
20
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
21
|
-
|
|
22
22
|
### 1. Check Passive Context Setting
|
|
23
23
|
|
|
24
|
-
**If `passive_context: false` was detected in step
|
|
24
|
+
**If `passive_context: false` was detected in step 1:**
|
|
25
25
|
|
|
26
26
|
"**Passive context disabled in preferences.yaml. Skipping snippet generation.**"
|
|
27
27
|
|
|
@@ -37,7 +37,7 @@ Load {snippetFormatData} and read the format template for the skill type.
|
|
|
37
37
|
|
|
38
38
|
Before generating new snippet content, check for a prior snippet:
|
|
39
39
|
|
|
40
|
-
1. Read `{resolved_skill_package}/context-snippet.md` if it exists (resolved in step
|
|
40
|
+
1. Read `{resolved_skill_package}/context-snippet.md` if it exists (resolved in step 1 — see `knowledge/version-paths.md`)
|
|
41
41
|
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`.
|
|
42
42
|
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`.
|
|
43
43
|
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.
|
|
@@ -49,7 +49,7 @@ These values will be used as a fallback in section 3 if new gotchas cannot be de
|
|
|
49
49
|
|
|
50
50
|
**If `snippet_skill_root_override` is set in config.yaml:** Use its value directly as `{skill_root}` and skip the IDE-mapping lookup below. This is the authoring-repo escape hatch — repos where skills live under a single shared directory (e.g. `skills/`) that does not match any per-IDE skill root. Log: "Using snippet_skill_root_override: `{override}` — bypassing IDE mapping for snippet root path."
|
|
51
51
|
|
|
52
|
-
**Otherwise (default):** Using the first entry in `target_context_files` (resolved in step
|
|
52
|
+
**Otherwise (default):** Using the first entry in `target_context_files` (resolved in step 1), take its `skill_root` value. This is the IDE's actual skill directory (e.g., `.claude/skills/`, `.windsurf/skills/`, `.github/skills/`).
|
|
53
53
|
|
|
54
54
|
Store `{skill_root}` for use in snippet generation. The context-snippet.md written to disk uses this resolved skill root path.
|
|
55
55
|
|
|
@@ -62,9 +62,15 @@ Store `{skill_root}` for use in snippet generation. The context-snippet.md writt
|
|
|
62
62
|
3. Read SKILL.md to extract: heading slugs for `#quick-start` and `#key-types`, inline summary of key types (~10 words)
|
|
63
63
|
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.
|
|
64
64
|
5. Derive gotchas from: T2-future annotations in evidence report (breaking changes), async requirements, version-specific behavior.
|
|
65
|
+
|
|
66
|
+
**Detect first-export state before applying carry-forward logic.** The `[CARRIED]` one-cycle expiry is meaningful only on a *re-export*. On a first export, the prior `context-snippet.md` was authored by `create-skill` (or `update-skill`) from the evidence report inside the same forge cycle — those gotchas are freshly derived, not "left over from a previous export." Treating them as carry-forward primes them for premature expiry on the second export.
|
|
67
|
+
|
|
68
|
+
Read `{skills_output_folder}/.export-manifest.json` (the same file step 4 §4a will rewrite). If the skill name is **absent** from `exports`, OR present with no resolvable `last_exported` for any version under `versions`, this is a first export — set `is_first_export = true`. Otherwise `is_first_export = false`. (Step-04 reads the manifest authoritatively for the rebuild; this read is the lightweight probe step 3 needs to choose the right branch below.)
|
|
69
|
+
|
|
65
70
|
- **If new gotchas are derived:** Use them (they supersede any prior gotchas). Write as `|gotchas: {pitfall-1}, {pitfall-2}` with no marker.
|
|
66
|
-
- **If NO new gotchas are derived
|
|
67
|
-
- **If NO new gotchas are derived
|
|
71
|
+
- **If NO new gotchas are derived AND `is_first_export == true` AND `prior_gotchas` exists:** Treat the prior gotchas as **freshly derived** by create-skill/update-skill — write them **without** the `[CARRIED]` marker. (The marker only applies to re-exports.) No warning needed; this is the normal first-export shape.
|
|
72
|
+
- **If NO new gotchas are derived BUT `prior_gotchas` exists AND `is_first_export == false` AND `prior_gotchas_already_carried == false`:** First carry-forward cycle on a re-export — 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."
|
|
73
|
+
- **If NO new gotchas are derived AND `prior_gotchas` exists AND `prior_gotchas_already_carried == true`:** Expiry reached (re-export only — first-export branch above takes precedence) — 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."
|
|
68
74
|
- **If NO new gotchas derived AND no `prior_gotchas`:** Omit the gotchas line.
|
|
69
75
|
|
|
70
76
|
Generate:
|
|
@@ -116,7 +122,7 @@ Estimate token count of generated snippet (approximate: words * 1.3).
|
|
|
116
122
|
|
|
117
123
|
**Estimated tokens:** {count}"
|
|
118
124
|
|
|
119
|
-
Hold content in context for step
|
|
125
|
+
Hold content in context for step 4.
|
|
120
126
|
|
|
121
127
|
**If NOT dry-run:**
|
|
122
128
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
# `shared/health-check.md` resolves relative to the SKF module root
|
|
3
|
-
# (
|
|
4
|
-
# to this step file.
|
|
2
|
+
# Note: `shared/health-check.md` resolves relative to the SKF module root
|
|
3
|
+
# ({project-root}/_bmad/skf/ when installed, {project-root}/src/ during
|
|
4
|
+
# development), NOT relative to this step file.
|
|
5
5
|
nextStepFile: 'shared/health-check.md'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
9
|
+
|
|
8
10
|
# Step 7: Workflow Health Check
|
|
9
11
|
|
|
10
12
|
## STEP GOAL:
|
|
@@ -13,7 +15,7 @@ Chain to the shared workflow self-improvement health check at `{nextStepFile}`.
|
|
|
13
15
|
|
|
14
16
|
## Rules
|
|
15
17
|
|
|
16
|
-
- No user-facing reports, file writes, or result contracts in this step — those belong in step
|
|
18
|
+
- No user-facing reports, file writes, or result contracts in this step — those belong in step 6
|
|
17
19
|
- Delegate directly to `{nextStepFile}` with no additional commentary
|
|
18
20
|
- Do not attempt any other action between loading this step and executing `{nextStepFile}`
|
|
19
21
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'package.md'
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
6
|
+
|
|
5
7
|
# Step 1: Load Skill
|
|
6
8
|
|
|
7
9
|
## STEP GOAL:
|
|
@@ -15,8 +17,6 @@ To load the target skill's artifacts, validate they meet agentskills.io spec com
|
|
|
15
17
|
|
|
16
18
|
## MANDATORY SEQUENCE
|
|
17
19
|
|
|
18
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
19
|
-
|
|
20
20
|
### 1. Parse Export Arguments
|
|
21
21
|
|
|
22
22
|
"**Starting skill export...**"
|
|
@@ -25,7 +25,7 @@ Determine the skill(s) to export and any flags:
|
|
|
25
25
|
|
|
26
26
|
**Skill Path Discovery (version-aware — see `knowledge/version-paths.md`):**
|
|
27
27
|
- If user provided one or more skill names or paths as arguments, use that list directly
|
|
28
|
-
- If `--all` was passed, build the list from every skill in `{skills_output_folder}/.export-manifest.json.exports` whose `active_version` entry is not `status: "deprecated"` (deprecated skills are excluded from all exports — see step
|
|
28
|
+
- If `--all` was passed, build the list from every skill in `{skills_output_folder}/.export-manifest.json.exports` whose `active_version` entry is not `status: "deprecated"` (deprecated skills are excluded from all exports — see step 4 §4b)
|
|
29
29
|
- If no explicit skill and no `--all`, discover available skills using the export manifest:
|
|
30
30
|
1. Read `{skills_output_folder}/.export-manifest.json` — list skill names from `exports`
|
|
31
31
|
2. For each skill group directory in `{skills_output_folder}/`, check for `{skill_group}/active/{skill-name}/SKILL.md`
|
|
@@ -64,54 +64,15 @@ For each IDE in `config.yaml.ides`:
|
|
|
64
64
|
|
|
65
65
|
### 1b. Detect Snippet Root Prefix Mismatch
|
|
66
66
|
|
|
67
|
-
**Skip entirely if `snippet_skill_root_override` is
|
|
68
|
-
|
|
69
|
-
Otherwise, probe existing snippets to catch the authoring-repo case (skills live under a single shared directory like `skills/` that does not match any per-IDE `skill_root`) before step-04 silently rewrites their root paths:
|
|
70
|
-
|
|
71
|
-
1. Collect candidate snippet paths:
|
|
72
|
-
- Read `{skills_output_folder}/.export-manifest.json` if it exists. For each skill in `exports` with a resolvable `active_version`, add `{skills_output_folder}/{skill-name}/{active_version}/{skill-name}/context-snippet.md`
|
|
73
|
-
- Also include the current skill's snippet if present (resolved via manifest / `active` symlink / flat path per `knowledge/version-paths.md`)
|
|
74
|
-
2. For each snippet that exists on disk, read the first line and parse the `root:` value. Strip the trailing `{skill-name}/` to extract the prefix (e.g. `skills/`, `.claude/skills/`)
|
|
75
|
-
3. Collect unique prefixes into `observed_prefixes`
|
|
76
|
-
4. Compare against `target_context_files[0].skill_root` (the first entry's IDE-mapped skill root — used as reference since step-03 §2.7 picks this same entry for snippet generation when no override is set)
|
|
77
|
-
|
|
78
|
-
**If `observed_prefixes` contains any value that does not match the reference `skill_root`:**
|
|
79
|
-
|
|
80
|
-
Emit a single warning (once, not per snippet) and present resolution options before proceeding:
|
|
81
|
-
|
|
82
|
-
"**Snippet root prefix mismatch detected.**
|
|
83
|
-
Existing snippets use: `{observed_prefixes}`
|
|
84
|
-
IDE-mapped skill_root: `{target_context_files[0].skill_root}`
|
|
85
|
-
|
|
86
|
-
This usually means you are in an authoring repo where skills live under a single shared directory. Options:
|
|
87
|
-
- **(a) Set override** — add `snippet_skill_root_override: {observed_prefix}` to `config.yaml`. Snippets keep their on-disk prefix; the managed section references the real location.
|
|
88
|
-
- **(b) Proceed with IDE mapping** — step-04 will rewrite every snippet's root path to the IDE's skill_root. Use this only if the IDE's skill directory actually contains the skill files.
|
|
89
|
-
- **(c) Cancel** — abort export and investigate.
|
|
67
|
+
**Skip entirely if `snippet_skill_root_override` is set in `config.yaml`** — the authoring-repo escape hatch is already configured and any on-disk prefix that matches it is ground truth (see `assets/managed-section-format.md` override rules).
|
|
90
68
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
In `{headless_mode}`, default to (b) and log the observed prefix(es) so the mismatch is visible in run logs. In interactive mode, wait for user choice before continuing to section 2.
|
|
94
|
-
|
|
95
|
-
**If all observed prefixes match the reference `skill_root` (or no existing snippets were found):** Proceed silently.
|
|
69
|
+
**Otherwise:** load `references/preflight-snippet-root-probe.md` and follow its probe + (a) Set override / (b) Proceed with IDE mapping / (c) Cancel gate protocol. The reference handles candidate snippet collection (manifest-driven), prefix observation, the mismatch warning, and headless default ((b) Proceed). Returns control to §1c on no-mismatch fast path or after a (b) choice.
|
|
96
70
|
|
|
97
71
|
### 1c. Multi-skill Mode (when `len(skill_batch) > 1`)
|
|
98
72
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
| Step | Behavior in multi-skill mode |
|
|
102
|
-
|------|------------------------------|
|
|
103
|
-
| step-01 §2–5 | **Iterate per skill** — load, validate, read metadata, and check the test report for every skill in `skill_batch`. Collect per-skill results. |
|
|
104
|
-
| step-01 §6 | **Single gate** — present one consolidated summary table (one row per skill) and a single [C] gate for the whole batch. |
|
|
105
|
-
| step-02 | **Iterate per skill** — validate each skill's package structure and collect per-skill readiness. |
|
|
106
|
-
| step-03 | **Iterate per skill** — regenerate each skill's `context-snippet.md` independently (each skill has its own prior-gotchas carry-forward state). |
|
|
107
|
-
| step-04 | **Batch once** — §3b orphan detection, §4 skill-index rebuild, §5 managed-section assembly, and §6–9 diff + write all execute once for the entire batch. The exported skill set in §4b already enumerates every skill in the manifest — it does not need per-skill iteration. §9b adds/updates a manifest entry per skill in `skill_batch` (not just the last one), then writes the manifest once. |
|
|
108
|
-
| step-05 | **Iterate per skill** — compute token counts per skill, then present one aggregate report. |
|
|
109
|
-
| step-06 | **One batch summary + one result contract** — the files-written table lists every skill; the result contract JSON covers the whole run, and `outputs` enumerates every context-snippet + target context file touched. |
|
|
110
|
-
| step-07 | **Runs once** — health check is per-workflow-run, not per-skill. |
|
|
111
|
-
|
|
112
|
-
**Halt semantics in batch mode:** if any single skill fails validation in §2 (required-file or metadata-field failure), halt the entire batch before §5 — do not partially export. Report which skill failed and why.
|
|
73
|
+
**If `len(skill_batch) == 1`:** single-skill mode (legacy behavior) — every section below operates on the one skill without iteration. Skip this subsection.
|
|
113
74
|
|
|
114
|
-
**
|
|
75
|
+
**If `len(skill_batch) > 1`:** load `references/multi-skill-mode.md` and apply its per-step behavior matrix. The reference partitions work so that step 1 §2–5 iterates per skill, step 1 §6 presents a single consolidated [C] gate, step 4 batches once across the whole run, and step 7 health check runs once. It also defines the all-or-nothing halt semantics if any single skill fails §2 validation.
|
|
115
76
|
|
|
116
77
|
### 2. Load and Validate Skill Artifacts
|
|
117
78
|
|
|
@@ -165,14 +126,22 @@ Load `{sidecar_path}/preferences.yaml` (if exists):
|
|
|
165
126
|
|
|
166
127
|
### 4b. Check Test Report (Quality Gate)
|
|
167
128
|
|
|
168
|
-
|
|
129
|
+
`skf-test-skill` writes timestamped test-report filenames (`test-report-{skill_name}-{ISO-TIMESTAMP}-{HASH}.md`) — there is no exact-name `test-report-{skill_name}.md` on disk. Locate the most recent report by glob, not by exact filename:
|
|
130
|
+
|
|
131
|
+
1. Glob `{forge_data_folder}/{skill_name}/{active_version}/test-report-{skill_name}-*.md` (i.e. `{forge_version}/test-report-{skill_name}-*.md`). Sort matches descending by the parsed ISO-timestamp segment in the filename (`YYYYMMDDTHHMMSSZ` between the skill name and the hash — `sort -r` on the filename works because the timestamp is the first variable component). Take the first match.
|
|
132
|
+
2. If the versioned glob returns nothing, fall back to the same glob at the flat path `{forge_data_folder}/{skill_name}/test-report-{skill_name}-*.md`. Pick the newest by parsed timestamp.
|
|
133
|
+
3. If neither glob returns anything, look for the stable companion `skf-test-skill-result-latest.json` in the same two directories (versioned first, then flat). Read the report path from `outputs[]` per the canonical contract documented at `shared/references/output-contract-schema.md` (resolved by skf-test-skill step 6 §4c) and load that file.
|
|
134
|
+
4. If all three lookups fail, the skill has no test report.
|
|
135
|
+
|
|
136
|
+
**If a test report is found:**
|
|
169
137
|
|
|
170
|
-
**If test report found:**
|
|
171
138
|
- Read frontmatter `testResult` and `score`
|
|
172
139
|
- If `testResult: fail`: warn: "**Warning:** This skill failed its last test (score: {score}%). Consider running `@Ferris TS` and addressing gaps before export."
|
|
173
140
|
- If `testResult: pass`: note: "Last test: **PASS** ({score}%)"
|
|
141
|
+
- Always surface the actual file picked in the message (e.g. `test-report-my-base-ui-20260507T050917Z-487606-9b2f.md`) — not the no-longer-existent `test-report-{skill_name}.md` — so an operator can navigate to the report from the log.
|
|
142
|
+
|
|
143
|
+
**If no test report found** (all three lookups returned nothing):
|
|
174
144
|
|
|
175
|
-
**If no test report found:**
|
|
176
145
|
- Warn: "**Note:** No test report found for this skill. Consider running `@Ferris TS` before export to verify completeness."
|
|
177
146
|
|
|
178
147
|
Continue to step 5 regardless — this is advisory, not blocking.
|
|
@@ -228,11 +197,12 @@ Continue to step 5 regardless — this is advisory, not blocking.
|
|
|
228
197
|
|
|
229
198
|
### 6. Present MENU OPTIONS
|
|
230
199
|
|
|
231
|
-
Display: "**Select:** [C] Continue to packaging" (multi-skill mode: the single [C] gate covers the whole batch)
|
|
200
|
+
Display: "**Select:** [C] Continue to packaging | [X] Cancel and exit (or type `cancel` / `exit` / `:q`)" (multi-skill mode: the single [C] gate covers the whole batch)
|
|
232
201
|
|
|
233
202
|
#### Menu Handling Logic:
|
|
234
203
|
|
|
235
204
|
- IF C: Proceed with loaded skill data, then load, read entire file, then execute {nextStepFile}
|
|
205
|
+
- IF X (or `cancel` / `exit` / `:q`): Display "Cancelled — no packaging or context file writes were performed." and HALT (exit code 6, `halt_reason: "user-cancelled"`). In headless, emit the error envelope per SKILL.md "Result Contract (Headless)" with the resolved `skills`, `context_files_updated: []`, and `manifest_path: null`.
|
|
236
206
|
- IF Any other: help user respond, then [Redisplay Menu Options](#6-present-menu-options)
|
|
237
207
|
|
|
238
208
|
#### EXECUTION RULES:
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Static reference loaded by update-context.md §4a only when manifest
|
|
3
|
+
# schema documentation is needed (the in-prompt schema is otherwise
|
|
4
|
+
# delegated to skf-manifest-ops.py which handles v2 enforcement and
|
|
5
|
+
# v1→v2 migration internally).
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
9
|
+
|
|
10
|
+
# Export Manifest v2 — Schema Reference
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
Reference for the v2 export manifest schema enforced by `skf-manifest-ops.py` and consumed by every workflow that touches `{skills_output_folder}/.export-manifest.json`. This file is the source of truth for the v2 shape; the helper script implements it; downstream skills (drop-skill, rename-skill, update-skill) read this same file to stay aligned.
|
|
15
|
+
|
|
16
|
+
## v2 Schema
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"schema_version": "2",
|
|
21
|
+
"exports": {
|
|
22
|
+
"skill-name": {
|
|
23
|
+
"active_version": "0.6.0",
|
|
24
|
+
"versions": {
|
|
25
|
+
"0.1.0": {
|
|
26
|
+
"ides": ["claude-code"],
|
|
27
|
+
"last_exported": "2026-01-15",
|
|
28
|
+
"status": "deprecated"
|
|
29
|
+
},
|
|
30
|
+
"0.5.0": {
|
|
31
|
+
"ides": ["claude-code"],
|
|
32
|
+
"last_exported": "2026-03-15",
|
|
33
|
+
"status": "archived"
|
|
34
|
+
},
|
|
35
|
+
"0.6.0": {
|
|
36
|
+
"ides": ["claude-code", "github-copilot"],
|
|
37
|
+
"last_exported": "2026-04-04",
|
|
38
|
+
"status": "active"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Status enum
|
|
47
|
+
|
|
48
|
+
- `"active"` — currently exported; snippet appears in managed sections
|
|
49
|
+
- `"archived"` — previously exported, not active; files retained for rollback
|
|
50
|
+
- `"deprecated"` — dropped via drop-skill workflow; excluded from all exports (files may or may not exist on disk)
|
|
51
|
+
- `"draft"` — created but never exported
|
|
52
|
+
|
|
53
|
+
## v1 → v2 migration (handled by `skf-manifest-ops.py`)
|
|
54
|
+
|
|
55
|
+
Pre-rename v2 manifests used a `platforms` array at the version level. If a version entry contains `platforms` instead of (or in addition to) `ides`, the helper treats `platforms` as `ides` and rewrites it on the next manifest write — silent in-place upgrade, no user prompt.
|
|
56
|
+
|
|
57
|
+
For v1 manifests (no `schema_version` field), the helper migrates in-place on the first read:
|
|
58
|
+
|
|
59
|
+
1. For each entry in `exports`, read its `last_exported`
|
|
60
|
+
2. Resolve the skill's current version from `{resolved_skill_package}/metadata.json`
|
|
61
|
+
3. Wrap in v2 structure: `active_version` ← resolved version, single entry in `versions` with `status: "active"`, `ides: []` (unknown — fills on next successful export), and `last_exported`
|
|
62
|
+
4. Set `schema_version: "2"` at root
|
|
63
|
+
|
|
64
|
+
Workflows that load the manifest via `skf-manifest-ops.py read` always receive the v2 shape regardless of on-disk state.
|
|
65
|
+
|
|
66
|
+
## Integrity invariant
|
|
67
|
+
|
|
68
|
+
`active_version` must resolve to a `versions` entry. If `active_version` is set but there is no matching key under `versions`, the manifest is inconsistent (possible corruption or a botched v1→v2 migration). Workflows must skip the affected skill and surface a loud warning rather than fall through to a degraded state. The recommended recovery is to re-run `[EX] Export Skill` on the affected skill — the export pass rebuilds the version entry from `metadata.json` ground truth.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Static reference loaded by load-skill.md §1c only when
|
|
3
|
+
# `len(skill_batch) > 1` (multi-skill mode activated via `--all`,
|
|
4
|
+
# multi-selection at the discovery menu, or explicit multi-argument
|
|
5
|
+
# invocation). In single-skill mode the per-step matrix below does
|
|
6
|
+
# not apply and this file is never loaded. Loaded once per export run.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
10
|
+
|
|
11
|
+
# Multi-skill Mode — Per-step Behavior Matrix
|
|
12
|
+
|
|
13
|
+
## Purpose
|
|
14
|
+
|
|
15
|
+
When multiple skills are exported in a single run, the workflow does NOT loop the full step 1 → step 7 sequence once per skill. Instead, it partitions work across steps to avoid repeated gates and redundant batch work (one §3b orphan-detection pass, one §4 skill-index rebuild, one §6 user gate, one health check, etc.).
|
|
16
|
+
|
|
17
|
+
Loaded by `load-skill.md` §1c when `len(skill_batch) > 1`.
|
|
18
|
+
|
|
19
|
+
## Per-step matrix
|
|
20
|
+
|
|
21
|
+
| Step | Behavior in multi-skill mode |
|
|
22
|
+
|------|------------------------------|
|
|
23
|
+
| step 1 §2–5 | **Iterate per skill** — load, validate, read metadata, and check the test report for every skill in `skill_batch`. Collect per-skill results. |
|
|
24
|
+
| step 1 §6 | **Single gate** — present one consolidated summary table (one row per skill) and a single [C] gate for the whole batch. |
|
|
25
|
+
| step 2 | **Iterate per skill** — validate each skill's package structure and collect per-skill readiness. |
|
|
26
|
+
| step 3 | **Iterate per skill** — regenerate each skill's `context-snippet.md` independently (each skill has its own prior-gotchas carry-forward state). |
|
|
27
|
+
| step 4 | **Batch once** — §3b orphan detection, §4 skill-index rebuild, §5 managed-section assembly, and §6–9 diff + write all execute once for the entire batch. The exported skill set in §4b already enumerates every skill in the manifest — it does not need per-skill iteration. §9b adds/updates a manifest entry per skill in `skill_batch` (not just the last one), then writes the manifest once. |
|
|
28
|
+
| step 5 | **Iterate per skill** — compute token counts per skill, then present one aggregate report. |
|
|
29
|
+
| step 6 | **One batch summary + one result contract** — the files-written table lists every skill; the result contract JSON covers the whole run, and `outputs` enumerates every context-snippet + target context file touched. |
|
|
30
|
+
| step 7 | **Runs once** — health check is per-workflow-run, not per-skill. |
|
|
31
|
+
|
|
32
|
+
## Halt semantics
|
|
33
|
+
|
|
34
|
+
If any single skill fails validation in step 1 §2 (required-file or metadata-field failure), halt the entire batch before step 4 §5 — do not partially export. Report which skill failed and why. The principle: a multi-skill run is a unit of work, not a per-skill best-effort sweep — partial exports leave the manifest and managed sections in an ambiguous state that's expensive for the operator to reconcile.
|
|
35
|
+
|
|
36
|
+
## Single-skill mode (reference)
|
|
37
|
+
|
|
38
|
+
`len(skill_batch) == 1` preserves the legacy behavior: every section operates on the one skill without iteration, no gate consolidation, no per-step table consultation. This file does not need to be loaded.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Static reference loaded by update-context.md §3b only when
|
|
3
|
+
# `orphaned_context_files` is non-empty (i.e. the cheap pre-check in
|
|
4
|
+
# §3b found a context file on disk with an SKF managed section that
|
|
5
|
+
# is no longer in the current `target_context_files`). The reference
|
|
6
|
+
# carries the (a)/(b)/(c) gate protocol, headless default, and
|
|
7
|
+
# downstream-state contract; the trigger detection itself stays
|
|
8
|
+
# inline in §3b so the LLM knows when to invoke this protocol.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<!-- Config: communicate in {communication_language}. Render the orphan list and gate prompt in {document_output_language}. -->
|
|
12
|
+
|
|
13
|
+
# Orphan Context-File Detection — Gate Protocol
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
Handle the (a) clear / (b) keep / (c) rewrite gate when one or more known context files (`CLAUDE.md`, `.cursorrules`, `AGENTS.md`) on disk contain an SKF managed section but their owning IDE is no longer listed in `config.yaml.ides`. Loaded by `update-context.md` §3b after the cheap pre-check populates `orphaned_context_files`.
|
|
18
|
+
|
|
19
|
+
## Inputs
|
|
20
|
+
|
|
21
|
+
- `orphaned_context_files` — list of `{context_file, file_path}` entries built by §3b's pre-check
|
|
22
|
+
- `target_context_files` — current export's IDE → context-file map (from step 1)
|
|
23
|
+
- `{headless_mode}` — boolean flag from workflow context
|
|
24
|
+
|
|
25
|
+
## Gate Protocol
|
|
26
|
+
|
|
27
|
+
Emit the warning and gate:
|
|
28
|
+
|
|
29
|
+
> **Orphaned context files detected.** The following files contain SKF managed sections but no configured IDEs target them:
|
|
30
|
+
> {list: context file → file path}
|
|
31
|
+
>
|
|
32
|
+
> The managed sections in these files are stale. Options:
|
|
33
|
+
>
|
|
34
|
+
> - **(a) clear** — remove the SKF managed section from each orphaned file (surgical marker replacement, leaves user content intact)
|
|
35
|
+
> - **(b) keep** — leave them untouched (they will remain stale until you re-add an IDE that targets this file or delete the file)
|
|
36
|
+
> - **(c) rewrite** — also rewrite the orphaned files with the current skill index (use this if the IDE was removed by mistake)
|
|
37
|
+
|
|
38
|
+
Wait for user choice.
|
|
39
|
+
|
|
40
|
+
**Headless / non-interactive default:** when `{headless_mode}` (or dry-run, or unattended), default to **(b) keep** and print the warning only — no destructive action without explicit consent.
|
|
41
|
+
|
|
42
|
+
## Choice handling
|
|
43
|
+
|
|
44
|
+
### (a) clear
|
|
45
|
+
|
|
46
|
+
For each file in `orphaned_context_files`:
|
|
47
|
+
|
|
48
|
+
1. Replace everything between `<!-- SKF:BEGIN` and `<!-- SKF:END -->` (inclusive) with an empty string, preserving surrounding content byte-exactly.
|
|
49
|
+
2. Append the file path to `orphans_cleared` (workflow-context list, surfaced in the §6 result contract).
|
|
50
|
+
|
|
51
|
+
### (b) keep
|
|
52
|
+
|
|
53
|
+
Record nothing. The orphaned files remain on disk, untouched. Proceed.
|
|
54
|
+
|
|
55
|
+
### (c) rewrite
|
|
56
|
+
|
|
57
|
+
Add each entry in `orphaned_context_files` to a separate `rewrite_context_files` list. This list is kept distinct from `target_context_files` so the user's intent to only export to configured IDEs is preserved in the manifest update at §9b — `rewrite_context_files` participates in the §4–§9a write loop for this run only and is not promoted into the manifest's `ides` arrays.
|
|
58
|
+
|
|
59
|
+
Use `.agents/skills/` as the default skill root for rewritten orphans (the IDE-neutral path used when the original IDE mapping is no longer available).
|
|
60
|
+
|
|
61
|
+
Record each rewritten file in `orphans_rewritten` (workflow-context list, surfaced in the §6 result contract).
|
|
62
|
+
|
|
63
|
+
## Downstream contract
|
|
64
|
+
|
|
65
|
+
After this protocol completes, §3b returns control to §4 with these workflow-context variables populated:
|
|
66
|
+
|
|
67
|
+
- `orphans_cleared: []` — set when the user chose (a) or stayed empty otherwise
|
|
68
|
+
- `orphans_rewritten: []` — set when the user chose (c) or stayed empty otherwise
|
|
69
|
+
- `rewrite_context_files: []` — extends the per-context-file iteration in §4–§9a when the user chose (c)
|
|
70
|
+
|
|
71
|
+
The §4–§9a loop iterates over `target_context_files + rewrite_context_files`. The §9b manifest update reads only `target_context_files` (rewritten orphans are not promoted into the manifest).
|
|
72
|
+
|
|
73
|
+
## Scope note
|
|
74
|
+
|
|
75
|
+
This cleanup only runs during interactive export (and the headless default explicitly does nothing destructive). Drop-skill and rename-skill operate on the manifest's declared context files and are not responsible for orphan detection — their scope is the active manifest, not arbitrary on-disk markers.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Static reference loaded by update-context.md §4c.1 only when
|
|
3
|
+
# `orphan_managed_rows` is non-empty (i.e. the cheap pre-check in
|
|
4
|
+
# §4c.1 found `[skill-name v...]` entries in the prior managed
|
|
5
|
+
# section that are absent from the manifest-driven exported skill
|
|
6
|
+
# set built in §4b). The reference carries the (a)/(b)/(c) gate
|
|
7
|
+
# protocol, headless default, deviations[] contract, and §6
|
|
8
|
+
# result-contract integration; the trigger detection itself stays
|
|
9
|
+
# inline in §4c.1 so the LLM knows when to invoke this protocol.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!-- Config: communicate in {communication_language}. Render the orphan list and gate prompt in {document_output_language}. -->
|
|
13
|
+
|
|
14
|
+
# Orphan Managed-Section Rows — Gate Protocol
|
|
15
|
+
|
|
16
|
+
## Purpose
|
|
17
|
+
|
|
18
|
+
Handle the (a) Drop / (b) Preserve verbatim / (c) Cancel gate when the prior managed section in the first target context file contains `[skill-name v...]` rows for skills that are not in the manifest-driven exported skill set — typically externally-installed skills authored in a different repo and dropped into `{skills_output_folder}` without going through export-skill.
|
|
19
|
+
|
|
20
|
+
Strict ADR-K would silently drop such rows, but the user's managed section is load-bearing — silent removal of an installed skill is a regression. The convention captured in `skills/export-skill-result-latest.json` deviations is to make this an explicit operator (or `{headless_mode}`) choice.
|
|
21
|
+
|
|
22
|
+
## Inputs
|
|
23
|
+
|
|
24
|
+
- `orphan_managed_rows` — list of `{skill_name, version, snippet_text, source_files: []}` entries built by §4c.1's pre-check across **every** target context file, deduplicated by `(skill_name, version)`. `source_files` carries the file paths the orphan appeared in (one entry per file in which the row was found). `snippet_text` is the original snippet line(s) captured verbatim from the first encountered occurrence, used for re-emission if (b) is chosen.
|
|
25
|
+
- `target_context_files` — the full IDE → context-file list (referenced in the gate's framing copy so the user understands the consolidation scope)
|
|
26
|
+
- `{headless_mode}` — boolean flag from workflow context
|
|
27
|
+
|
|
28
|
+
## Gate Protocol
|
|
29
|
+
|
|
30
|
+
Emit the gate:
|
|
31
|
+
|
|
32
|
+
> **Managed-section rows present but absent from manifest** (consolidated across {len(target_context_files)} target context file(s)):
|
|
33
|
+
>
|
|
34
|
+
> {list each as `- {skill_name} v{version} (in: {comma-separated source_files})`}
|
|
35
|
+
>
|
|
36
|
+
> These skills appear in one or more existing managed sections but no entry exists in `.export-manifest.json` and no source draft exists under `{skills_output_folder}/{skill_name}/`. They were likely installed from a different repo and never run through export-skill in this project. Options:
|
|
37
|
+
>
|
|
38
|
+
> - **(a) Drop** — remove these rows from the rebuilt managed section across **all** target context files (strict ADR-K behavior). The skills' on-disk files are not touched, but they will no longer appear in any context file's managed index.
|
|
39
|
+
> - **(b) Preserve verbatim** — copy each orphan's existing snippet line(s) into the rebuilt managed section across **all** target context files unchanged (one canonical row per `(skill, version)` written everywhere — orphans become symmetric across IDEs as a side effect, which is the correct outcome since the user's intent is "these external skills should appear in my managed index"). Records `deviations[].kind = "preserve_external_skills"` with the affected skill names, versions, and `source_files` in the result contract for audit.
|
|
40
|
+
> - **(c) Cancel** — abort export. Run export-skill against each external skill (or remove the orphan rows from the context files manually) before re-running.
|
|
41
|
+
|
|
42
|
+
Wait for user choice.
|
|
43
|
+
|
|
44
|
+
**Headless default** (when `{headless_mode}`): auto-select **(b) Preserve verbatim**, with the same `deviations[]` entry. Emit a loud log line:
|
|
45
|
+
|
|
46
|
+
> `headless: {N} managed-section rows had no manifest entry; preserving verbatim with deviations[].kind = preserve_external_skills. Run export-skill against each to migrate them into the manifest.`
|
|
47
|
+
|
|
48
|
+
Silent drop under automation would regress the user's managed section without consent; cancel under automation would block the whole export over an externally-installed skill the user did not author. Preservation matches the prior-attentive-operator convention.
|
|
49
|
+
|
|
50
|
+
## Choice handling
|
|
51
|
+
|
|
52
|
+
### (a) Drop
|
|
53
|
+
|
|
54
|
+
Do not include any orphan rows in the rebuilt section. Record:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
orphans_dropped = [{skill_name, version}, …]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
in workflow context for the §6 result contract.
|
|
61
|
+
|
|
62
|
+
### (b) Preserve verbatim
|
|
63
|
+
|
|
64
|
+
Append each captured `snippet_text` to the assembled section after the manifest-driven entries, preserving alphabetical order in the merged list (sort the combined set of `manifest-driven` + `orphan` snippets by `skill_name`). Each `(skill, version)` is written **once** per rebuilt managed section — the deduplication done by §4c.1 means there is no per-file divergence to reconcile here.
|
|
65
|
+
|
|
66
|
+
Append the following entry to the `deviations[]` array in the §6 result contract:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"kind": "preserve_external_skills",
|
|
71
|
+
"skills": [
|
|
72
|
+
{"name": "...", "version": "...", "source_files": ["..."]}
|
|
73
|
+
],
|
|
74
|
+
"rationale": "managed-section row exists but no manifest entry / no source draft"
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`source_files` per skill records the prior context files the orphan was found in (asymmetric provenance preserved for audit) — useful when an operator later debugs which IDE's managed section originally carried the row.
|
|
79
|
+
|
|
80
|
+
The same orphans are written to **every** target context file in the §4–§9a loop, so all configured IDEs end up with consistent managed sections (asymmetric prior orphans become symmetric — the correct outcome for the "preserve external skills" intent).
|
|
81
|
+
|
|
82
|
+
### (c) Cancel
|
|
83
|
+
|
|
84
|
+
HALT the workflow:
|
|
85
|
+
|
|
86
|
+
- Do not rewrite any context file.
|
|
87
|
+
- Do not update the manifest.
|
|
88
|
+
- Do not produce a result contract.
|
|
89
|
+
- Exit code 6, `halt_reason: "user-cancelled"` (matches the §8 Menu cancel semantics).
|
|
90
|
+
- In headless mode this branch is never taken (headless default is (b)), so this exit path is interactive-only.
|
|
91
|
+
|
|
92
|
+
## Downstream contract
|
|
93
|
+
|
|
94
|
+
After this protocol completes, §4c.1 returns control to §4d with these workflow-context variables populated:
|
|
95
|
+
|
|
96
|
+
- `orphans_dropped: []` — set when the user chose (a) or stayed empty otherwise
|
|
97
|
+
- `deviations[]` — extended with the `preserve_external_skills` entry when the user chose (b)
|
|
98
|
+
- The assembled managed section contains the orphan rows verbatim when (b) was chosen, and excludes them when (a) was chosen
|
|
99
|
+
|
|
100
|
+
## Scope note
|
|
101
|
+
|
|
102
|
+
This detection runs once per export run (not per target context file) — the §4c.1 pre-check iterates **every** entry in `target_context_files` and deduplicates by `(skill_name, version)` before invoking this protocol, so the gate's choice applies globally and asymmetric orphans (a row present in `.cursorrules` but not in `CLAUDE.md`, or vice versa) are detected and surfaced with `source_files` provenance.
|