bmad-module-skill-forge 1.4.1 → 1.5.1
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 +147 -16
- 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-manifest-ops.py +22 -6
- package/src/shared/scripts/skf-merge-ccc-exclusions.py +34 -4
- 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} +48 -14
- package/src/skf-analyze-source/{steps-c/step-01-init.md → references/init.md} +32 -9
- 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} +16 -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/{steps-c/step-01-init.md → references/init.md} +63 -19
- 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} +35 -17
- package/src/skf-brief-skill/SKILL.md +49 -19
- 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} +27 -15
- 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} +35 -29
- 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 +2 -2
- package/src/skf-brief-skill/{steps-c/step-03-scope-definition.md → references/scope-definition.md} +27 -20
- 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} +29 -16
- 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 +10 -8
- package/src/skf-create-skill/{steps-c/step-07-generate-artifacts.md → references/generate-artifacts.md} +11 -11
- 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} +48 -28
- 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} +37 -11
- package/src/skf-create-stack-skill/{steps-c/step-02-detect-manifests.md → references/detect-manifests.md} +32 -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} +44 -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} +11 -11
- 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} +11 -49
- 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 +79 -0
- package/src/skf-export-skill/{steps-c/step-06-summary.md → references/summary.md} +23 -11
- 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} +109 -113
- 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} +16 -31
- 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} +37 -73
- 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} +13 -9
- 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 +170 -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} +18 -14
- package/src/skf-verify-stack/{steps-c/step-06-report.md → references/report.md} +27 -42
- package/src/skf-verify-stack/{steps-c/step-04-requirements.md → references/requirements.md} +13 -9
- package/src/skf-verify-stack/{steps-c/step-05-synthesize.md → references/synthesize.md} +14 -10
- package/tools/validate-docs-drift.js +1 -1
- 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
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'health-check.md'
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
<!-- Config: communicate in {communication_language}. Render the report block in {document_output_language}. -->
|
|
6
|
+
|
|
5
7
|
# Step 3: Report Drop Results
|
|
6
8
|
|
|
7
9
|
## STEP GOAL:
|
|
@@ -10,14 +12,12 @@ Present a clear, final summary of what the drop workflow changed — manifest st
|
|
|
10
12
|
|
|
11
13
|
## Rules
|
|
12
14
|
|
|
13
|
-
- Focus only on reporting results stored in context by step
|
|
15
|
+
- Focus only on reporting results stored in context by step 2 — do not re-execute any part of the drop
|
|
14
16
|
- Do not hide verification errors or failed context file rebuilds
|
|
15
17
|
- Chains to the local health-check step via `{nextStepFile}` after completion — the user-facing report is NOT the terminal step
|
|
16
18
|
|
|
17
19
|
## MANDATORY SEQUENCE
|
|
18
20
|
|
|
19
|
-
**CRITICAL:** Follow this sequence exactly.
|
|
20
|
-
|
|
21
21
|
### 1. Determine Remaining Versions
|
|
22
22
|
|
|
23
23
|
**If `is_skill_level == true`:**
|
|
@@ -66,13 +66,21 @@ restore the managed section entry.
|
|
|
66
66
|
{if verification_errors is non-empty:}
|
|
67
67
|
**Verification warnings:**
|
|
68
68
|
{list each verification error}
|
|
69
|
-
These require manual review — see the error-handling guidance in step
|
|
69
|
+
These require manual review — see the error-handling guidance in step 2.
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
### Result Contract
|
|
73
73
|
|
|
74
74
|
Write the result contract per `shared/references/output-contract-schema.md`: the per-run record at `{skills_output_folder}/drop-skill-result-{YYYYMMDD-HHmmss}.json` (UTC timestamp, resolution to seconds) and a copy at `{skills_output_folder}/drop-skill-result-latest.json` (stable path for pipeline consumers — copy, not symlink). Include all purged file paths in `outputs`; include `target_skill`, `drop_mode`, and `versions_affected` in `summary`.
|
|
75
75
|
|
|
76
|
+
When `{headless_mode}` is true, also emit the single-line envelope on **stdout** before chaining to step 4 (matches the SKILL.md "Result Contract (Headless)" shape):
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
SKF_DROP_SKILL_RESULT_JSON: {"status":"success","skill":"{target_skill}","drop_mode":"{drop_mode}","versions_affected":{target_versions},"files_deleted":{files_deleted},"manifest_updated":{manifest_updated},"exit_code":0,"halt_reason":null}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Substitute `{target_versions}` as a JSON array (e.g. `["0.5.0"]`) or the literal string `"all"`; substitute `{files_deleted}` as a JSON array of absolute paths (`[]` in soft-drop mode); `manifest_updated` is the boolean from step 2's context.
|
|
83
|
+
|
|
76
84
|
### 3. Chain to Health Check
|
|
77
85
|
|
|
78
86
|
ONLY WHEN the report has been rendered and the result contract saved will you then load, read the full file, and execute `{nextStepFile}`. The health-check step is the true terminal step — do not stop here even though the report reads as final.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'execute.md'
|
|
3
3
|
versionPathsKnowledge: 'knowledge/version-paths.md'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
<!-- Config: communicate in {communication_language}. -->
|
|
7
|
+
|
|
6
8
|
# Step 1: Select Drop Target
|
|
7
9
|
|
|
8
10
|
## STEP GOAL:
|
|
@@ -18,8 +20,6 @@ Identify exactly what the user wants to drop — which skill, which version(s),
|
|
|
18
20
|
|
|
19
21
|
## MANDATORY SEQUENCE
|
|
20
22
|
|
|
21
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
22
|
-
|
|
23
23
|
### 1. Load Knowledge
|
|
24
24
|
|
|
25
25
|
Read `{versionPathsKnowledge}` completely and extract:
|
|
@@ -38,7 +38,7 @@ Load `{skills_output_folder}/.export-manifest.json` if it exists.
|
|
|
38
38
|
|
|
39
39
|
**If the file exists with entries:** Parse JSON and verify `schema_version` is `"2"`. If the manifest is v1 (no `schema_version` field), note this but continue — treat every entry as having a single active version derived from its current state. Store `manifest_exists = true`.
|
|
40
40
|
|
|
41
|
-
**Hard halt condition:** If the file exists but is malformed (not valid JSON), halt with: "**Export manifest is corrupt** at `{skills_output_folder}/.export-manifest.json` — fix or remove the file before dropping."
|
|
41
|
+
**Hard halt condition:** If the file exists but is malformed (not valid JSON), halt with: "**Export manifest is corrupt** at `{skills_output_folder}/.export-manifest.json` — fix or remove the file before dropping." HALT (exit code 3, `halt_reason: "manifest-corrupt"`). In headless mode, emit the error envelope per SKILL.md "Result Contract (Headless)" with `skill: null`, `drop_mode: null`, `versions_affected: []`.
|
|
42
42
|
|
|
43
43
|
### 3. List Available Skills
|
|
44
44
|
|
|
@@ -53,7 +53,7 @@ For each skill in the manifest's `exports` (only if `manifest_exists = true` and
|
|
|
53
53
|
|
|
54
54
|
Also scan `{skills_output_folder}/` for any top-level directories that are NOT present in the manifest's `exports` object. Record these as "(not in manifest)" — they represent draft or orphaned skills eligible for purge mode only. When the manifest is missing or empty, every on-disk skill appears in this category.
|
|
55
55
|
|
|
56
|
-
**If the combined list is empty** (no manifest entries AND no on-disk skill directories): halt with "**Drop Skill — nothing to drop.** No skills found in `{skills_output_folder}/` and no entries in `.export-manifest.json`. Run `[CS] Create Skill` first."
|
|
56
|
+
**If the combined list is empty** (no manifest entries AND no on-disk skill directories): halt with "**Drop Skill — nothing to drop.** No skills found in `{skills_output_folder}/` and no entries in `.export-manifest.json`. Run `[CS] Create Skill` first." HALT (exit code 3, `halt_reason: "nothing-to-drop"`). In headless mode, emit the error envelope with `skill: null`, `drop_mode: null`, `versions_affected: []`.
|
|
57
57
|
|
|
58
58
|
Display the combined list:
|
|
59
59
|
|
|
@@ -73,11 +73,12 @@ Available skills:
|
|
|
73
73
|
### 4. Ask Which Skill
|
|
74
74
|
|
|
75
75
|
"**Which skill would you like to drop?**
|
|
76
|
-
Enter the skill name or its number from the list above."
|
|
76
|
+
Enter the skill name or its number from the list above, or `cancel` / `exit` / `:q` to abort."
|
|
77
77
|
|
|
78
|
-
Wait for user input. Accept either the numeric index or the skill name (exact match). **GATE [default: use args]** — If `{headless_mode}` and skill name was provided as argument: select that skill and auto-proceed. If not provided, HALT: "headless mode requires skill name argument."
|
|
78
|
+
Wait for user input. Accept either the numeric index or the skill name (exact match). **GATE [default: use args]** — If `{headless_mode}` and skill name was provided as argument: select that skill and auto-proceed. If not provided, HALT (exit code 2, `halt_reason: "input-missing"`): "headless mode requires skill name argument." In headless mode, emit the error envelope with `skill: null`, `drop_mode: null`.
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
- If the user enters `cancel`, `exit`, `[X]`, `q`, or `:q`: Display "Cancelled — no changes were made." and HALT (exit code 6, `halt_reason: "user-cancelled"`).
|
|
81
|
+
- **If the user's input does not match any listed skill:** Re-display the list and ask again.
|
|
81
82
|
|
|
82
83
|
Store the selection as `target_skill`. Also store `target_in_manifest = true` if the selected skill has an entry in the manifest, `false` otherwise — subsequent sections use this flag to restrict the available drop options.
|
|
83
84
|
|
|
@@ -114,10 +115,13 @@ Store the selection as `target_skill`. Also store `target_in_manifest = true` if
|
|
|
114
115
|
"**Drop which version(s)?**
|
|
115
116
|
|
|
116
117
|
- **[N]** Specific version — soft deprecate or hard purge a single version
|
|
117
|
-
- **[A]** All versions — drops the entire skill (skill-level operation)
|
|
118
|
+
- **[A]** All versions — drops the entire skill (skill-level operation)
|
|
119
|
+
- **[X]** Cancel and exit (or type `cancel` / `exit` / `:q`)"
|
|
118
120
|
|
|
119
121
|
Wait for user selection.
|
|
120
122
|
|
|
123
|
+
- If the user enters `cancel`, `exit`, `[X]`, `q`, or `:q`: Display "Cancelled — no changes were made." and HALT (exit code 6, `halt_reason: "user-cancelled"`).
|
|
124
|
+
|
|
121
125
|
**If [N] Specific version:**
|
|
122
126
|
|
|
123
127
|
"**Which version?** Enter the version string (e.g. `0.5.0`)."
|
|
@@ -149,7 +153,7 @@ Set `target_versions = "all"` and `is_skill_level = true`.
|
|
|
149
153
|
|
|
150
154
|
**(b)** Use the `[A] All versions` option to drop every version of `{target_skill}` at once."
|
|
151
155
|
|
|
152
|
-
HALT the
|
|
156
|
+
HALT (exit code 5, `halt_reason: "active-version-guard-refused"`). In headless mode, emit the error envelope per SKILL.md "Result Contract (Headless)" with `skill: "{target_skill}"`, `drop_mode: null`, `versions_affected: ["{version}"]`. Do not proceed.
|
|
153
157
|
|
|
154
158
|
c. If the count is `0` → the active version is the ONLY version; allow the drop to continue (it is functionally equivalent to a skill-level drop on a single-version skill)
|
|
155
159
|
|
|
@@ -159,13 +163,20 @@ Set `target_versions = "all"` and `is_skill_level = true`.
|
|
|
159
163
|
|
|
160
164
|
**If `target_in_manifest = true`:**
|
|
161
165
|
|
|
166
|
+
**If `{defaultMode}` is non-empty (`"deprecate"` or `"purge"`)**: skip the prompt, set `drop_mode = "{defaultMode}"`, and log the override source for the headless decision trail (`"customize.toml.workflow.default_mode"`).
|
|
167
|
+
|
|
168
|
+
**Otherwise:**
|
|
169
|
+
|
|
162
170
|
"**How should this be dropped?**
|
|
163
171
|
|
|
164
172
|
- **[D]** Deprecate (soft) — Mark the version as `deprecated` in the manifest. Files remain on disk. Export-skill will exclude it from all platform context files. Reversible by editing the manifest.
|
|
165
|
-
- **[P]** Purge (hard) — Deprecate AND delete files from disk (`{skill_package}` and `{forge_version}`, or full `{skill_group}` and `{forge_group}` for a skill-level drop). **Irreversible.**
|
|
173
|
+
- **[P]** Purge (hard) — Deprecate AND delete files from disk (`{skill_package}` and `{forge_version}`, or full `{skill_group}` and `{forge_group}` for a skill-level drop). **Irreversible.**
|
|
174
|
+
- **[X]** Cancel and exit (or type `cancel` / `exit` / `:q`)"
|
|
166
175
|
|
|
167
176
|
Wait for user selection.
|
|
168
177
|
|
|
178
|
+
- If the user enters `cancel`, `exit`, `[X]`, `q`, or `:q`: Display "Cancelled — no changes were made." and HALT (exit code 6, `halt_reason: "user-cancelled"`).
|
|
179
|
+
|
|
169
180
|
Set `drop_mode` to `"deprecate"` (on D) or `"purge"` (on P).
|
|
170
181
|
|
|
171
182
|
### 9. Compute Affected Directories
|
|
@@ -187,9 +198,27 @@ Store the list as `affected_directories`.
|
|
|
187
198
|
|
|
188
199
|
If `drop_mode == "deprecate"`, record the list but present it as "retained" in the confirmation output — no deletion will occur.
|
|
189
200
|
|
|
201
|
+
#### 9b. Compute Blast-Radius Metrics (for §10 summary)
|
|
202
|
+
|
|
203
|
+
Compute three scalars to put in front of the path list at §10. The user's "I didn't know it would touch THAT" footgun is real — 12 paths can hide 50MB of on-disk content and a sweep across every IDE's managed section. A one-line summary makes the scale legible before the gate.
|
|
204
|
+
|
|
205
|
+
1. **`versions_count`** — the number of skill versions in scope:
|
|
206
|
+
- Version-level drop: `len(target_versions)` (typically `1`)
|
|
207
|
+
- Skill-level drop: count of non-deprecated versions in `exports.{target_skill}.versions` (the deprecated ones are already absent from the active managed sections)
|
|
208
|
+
|
|
209
|
+
2. **`bytes_total`** — recursive sum of byte sizes for every path in `affected_directories` that exists on disk. For each path, walk it and sum file sizes (`du -sb {path}` or equivalent). Skip non-existent paths silently — the §10 display is best-effort. Convert to a human-readable string for display (e.g. `"4.2 MB"`, `"812 KB"`); store the raw integer alongside as `bytes_total_raw` if a downstream step wants exact arithmetic. Defense in depth with execute.md §4 — that section will recompute per-path sizes for the canonical `disk_freed` reporting; this pre-compute is purely for the gate display and may slightly disagree if files change between gate and execute (acceptable for an "approximate" label).
|
|
210
|
+
|
|
211
|
+
3. **`context_files_count`** — the number of distinct context files the §3 rebuild loop will rewrite:
|
|
212
|
+
- Read `config.yaml.ides`
|
|
213
|
+
- For each entry, look up its `context_file` via the canonical mapping table in `skf-export-skill/assets/managed-section-format.md` (use `AGENTS.md` fallback for unknown IDEs)
|
|
214
|
+
- Deduplicate by `context_file`
|
|
215
|
+
- Count the result. If `config.yaml.ides` is absent or empty, default to `1` (the AGENTS.md fallback)
|
|
216
|
+
|
|
217
|
+
Store as `blast_radius = {versions_count, bytes_total, bytes_total_raw, context_files_count}` for §10's summary line.
|
|
218
|
+
|
|
190
219
|
### 10. Confirmation Gate
|
|
191
220
|
|
|
192
|
-
Display the full operation summary:
|
|
221
|
+
Display the full operation summary with the blast-radius summary line ahead of the path list so the user sees the scale before scanning paths:
|
|
193
222
|
|
|
194
223
|
```
|
|
195
224
|
**About to drop:**
|
|
@@ -197,6 +226,7 @@ Display the full operation summary:
|
|
|
197
226
|
Skill: {target_skill}
|
|
198
227
|
Version: {version or "ALL versions"}
|
|
199
228
|
Mode: {Deprecate (soft) | Purge (hard)}
|
|
229
|
+
Scope: {versions_count} version(s), ~{bytes_total} on disk, will rebuild {context_files_count} context file(s)
|
|
200
230
|
Files:
|
|
201
231
|
{for each path in affected_directories, list one per line}
|
|
202
232
|
{or "(retained on disk — soft drop)" if drop_mode == "deprecate"}
|
|
@@ -209,24 +239,42 @@ Display the full operation summary:
|
|
|
209
239
|
Proceed? [Y/N]
|
|
210
240
|
```
|
|
211
241
|
|
|
242
|
+
The `Scope:` line is the §9b-computed `blast_radius` rendered as one line. In `deprecate` mode the `~{bytes_total} on disk` reads as "size that will remain on disk (soft drop — files retained)"; the user is still served by knowing it. In `purge` mode it reads as "approximate disk that will be freed". The wording stays the same — the surrounding `Mode:` field disambiguates intent.
|
|
243
|
+
|
|
212
244
|
**GATE [default: Y]** — If `{headless_mode}`: auto-proceed with [Y], log: "headless: auto-confirmed drop of {target_skill}"
|
|
213
245
|
|
|
214
246
|
Wait for explicit user response.
|
|
215
247
|
|
|
248
|
+
**If `--dry-run` was passed**: skip the Y/N prompt entirely. Display the `[DRY RUN]` line followed by a copy-pasteable selection memo so the user can capture this preview in their shell history and re-run it (interactively, picking the same values) when they're ready to commit:
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
**[DRY RUN] No changes were made — preview above shows what would be dropped.**
|
|
252
|
+
|
|
253
|
+
To repeat this selection later:
|
|
254
|
+
Skill: {target_skill}
|
|
255
|
+
Version: {target_versions[0] if is_skill_level == false else "all"}
|
|
256
|
+
Mode: {Deprecate (soft) | Purge (hard)}
|
|
257
|
+
|
|
258
|
+
Re-invoke `/skf-drop-skill {target_skill}` and re-select these values, or
|
|
259
|
+
re-run with `--dry-run` to preview again.
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Then emit the success envelope per SKILL.md "Result Contract (Headless)" with `status: "dry-run"`, the resolved `skill`, `drop_mode`, and `versions_affected`, then HALT (exit code 0). The manifest, filesystem, and context files are untouched.
|
|
263
|
+
|
|
216
264
|
- **If `Y`** → proceed to section 11
|
|
217
|
-
- **If `N`** → "**Cancelled.** No changes were made." HALT the
|
|
265
|
+
- **If `N`** (or `cancel` / `exit` / `[X]` / `:q`) → "**Cancelled.** No changes were made. (Tip: invoke with `--dry-run` next time to preview the operation without reaching the commit prompt.)" HALT (exit code 6, `halt_reason: "user-cancelled"`). In headless mode, emit the error envelope per SKILL.md "Result Contract (Headless)" with the resolved `skill`, `drop_mode`, and `versions_affected`.
|
|
218
266
|
- **Any other input** → re-display the confirmation and ask again
|
|
219
267
|
|
|
220
268
|
### 11. Store Decisions in Context
|
|
221
269
|
|
|
222
|
-
Store the following decisions in workflow context for step
|
|
270
|
+
Store the following decisions in workflow context for step 2:
|
|
223
271
|
|
|
224
272
|
- `target_skill` — the skill name
|
|
225
273
|
- `target_in_manifest` — boolean (true if the skill has a manifest entry, false if it was discovered only by on-disk scan)
|
|
226
274
|
- `target_versions` — list of version strings (`[<version>]`) or the literal string `"all"`
|
|
227
275
|
- `drop_mode` — `"deprecate"` or `"purge"` (always `"purge"` when `target_in_manifest = false`)
|
|
228
276
|
- `is_skill_level` — boolean (true if all versions; always true when `target_in_manifest = false`)
|
|
229
|
-
- `affected_directories` — list of absolute directory paths that step
|
|
277
|
+
- `affected_directories` — list of absolute directory paths that step 2 will delete in purge mode (or retain in deprecate mode)
|
|
230
278
|
|
|
231
279
|
### 12. Load Next Step
|
|
232
280
|
|
|
@@ -9,6 +9,15 @@ description: Package for distribution and inject context into CLAUDE.md/AGENTS.m
|
|
|
9
9
|
|
|
10
10
|
Packages a completed skill as an agentskills.io-compliant package, generates context snippets, and updates the managed section in CLAUDE.md/.cursorrules/AGENTS.md for platform-aware context injection. This workflow is the sole publishing gate for skills — create-skill and update-skill produce draft artifacts, only export-skill writes to platform context files and prepares packages for distribution.
|
|
11
11
|
|
|
12
|
+
## Conventions
|
|
13
|
+
|
|
14
|
+
- Bare paths (e.g. `references/<name>.md`) resolve from the skill root.
|
|
15
|
+
- `references/` holds prompt content carved out of SKILL.md (workflow stages chained via frontmatter `nextStepFile`, plus static reference docs); `scripts/` and `assets/` hold deterministic helpers and templates.
|
|
16
|
+
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives, if present).
|
|
17
|
+
- `{project-root}`-prefixed paths resolve from the project working directory.
|
|
18
|
+
- `{skill-name}` resolves to the skill directory's basename.
|
|
19
|
+
- **Cross-skill data coupling (export-skill is a hub):** `assets/managed-section-format.md` is loaded by `skf-drop-skill/references/execute.md` and `skf-rename-skill/references/execute.md` (IDE→context-file mapping table and four-case logic). `references/update-context.md` §4a manifest-schema documentation is the source of truth for the v2 schema enforced by `skf-manifest-ops.py`. Other skills depend on these files at install time — schema-breaking changes here require coordinated updates across at least three skills.
|
|
20
|
+
|
|
12
21
|
## Role
|
|
13
22
|
|
|
14
23
|
You are a delivery and packaging specialist collaborating with a skill developer. You bring expertise in skill packaging, ecosystem compliance, and context injection patterns, while the user brings their completed skill and distribution requirements.
|
|
@@ -17,33 +26,57 @@ You are a delivery and packaging specialist collaborating with a skill developer
|
|
|
17
26
|
|
|
18
27
|
These rules apply to every step in this workflow:
|
|
19
28
|
|
|
20
|
-
- Read each step file completely before taking any action
|
|
21
|
-
- Follow the mandatory sequence in each step exactly — do not skip, reorder, or optimize
|
|
22
29
|
- Only load one step file at a time — never preload future steps
|
|
23
30
|
- Always communicate in `{communication_language}`
|
|
31
|
+
- At any interactive prompt, the inputs `cancel`, `exit`, `[X]`, `q`, or `:q` exit cleanly with exit code 6 (`halt_reason: "user-cancelled"`)
|
|
24
32
|
- If `{headless_mode}` is true, auto-proceed through confirmation gates with their default action and log each auto-decision
|
|
25
33
|
|
|
26
34
|
## Stages
|
|
27
35
|
|
|
28
36
|
| # | Step | File | Auto-proceed |
|
|
29
37
|
|---|------|------|--------------|
|
|
30
|
-
| 1 | Load Skill |
|
|
31
|
-
| 2 | Package |
|
|
32
|
-
| 3 | Generate Snippet |
|
|
33
|
-
| 4 | Update Context |
|
|
34
|
-
| 5 | Token Report |
|
|
35
|
-
| 6 | Summary |
|
|
36
|
-
| 7 | Workflow Health Check |
|
|
38
|
+
| 1 | Load Skill | references/load-skill.md | No (confirm) |
|
|
39
|
+
| 2 | Package | references/package.md | Yes |
|
|
40
|
+
| 3 | Generate Snippet | references/generate-snippet.md | Yes |
|
|
41
|
+
| 4 | Update Context | references/update-context.md | No (confirm) |
|
|
42
|
+
| 5 | Token Report | references/token-report.md | Yes |
|
|
43
|
+
| 6 | Summary | references/summary.md | Yes |
|
|
44
|
+
| 7 | Workflow Health Check | references/health-check.md | Yes |
|
|
37
45
|
|
|
38
46
|
## Invocation Contract
|
|
39
47
|
|
|
40
48
|
| Aspect | Detail |
|
|
41
49
|
|--------|--------|
|
|
42
|
-
| **Inputs** | skill_name [one or more, required unless `--all`]
|
|
43
|
-
| **
|
|
44
|
-
| **
|
|
45
|
-
| **
|
|
46
|
-
| **
|
|
50
|
+
| **Inputs** | `skill_name` [one or more, required unless `--all`] |
|
|
51
|
+
| **Flags** | `--headless` / `-H` (auto-resolve all gates); `--all` (export every non-deprecated skill in `.export-manifest.json`); `--dry-run` (resolve and stage everything but exit before §4 writes to context files; envelope `status="dry-run"`) |
|
|
52
|
+
| **Gates** | step 1: single Confirm Gate [C] for the whole batch | step 4: single Confirm Gate [C] for the whole batch |
|
|
53
|
+
| **Outputs** | Updated `.export-manifest.json` (every skill in the batch), updated context files (CLAUDE.md/AGENTS.md/.cursorrules), per-skill `context-snippet.md`, per-run result contract `export-skill-result-{timestamp}.json` and `export-skill-result-latest.json` |
|
|
54
|
+
| **Multi-skill mode** | Activated when more than one skill is selected (via `--all`, multi-selection, or multi-argument invocation). See `references/load-skill.md` §1c for the per-step iteration map. |
|
|
55
|
+
| **Headless** | All gates auto-resolve with default action when `{headless_mode}` is true. Each auto-resolved gate appends a `{gate, default_action, taken_action, reason}` entry to `headless_decisions[]`, surfaced in step 6's `SKF_EXPORT_RESULT_JSON` envelope so non-interactive runs can be audited post-hoc. |
|
|
56
|
+
| **Exit codes** | See "Exit Codes" below |
|
|
57
|
+
|
|
58
|
+
## Exit Codes
|
|
59
|
+
|
|
60
|
+
Every HARD HALT in this workflow exits with a stable code so headless automators can branch on the failure class without grepping message text:
|
|
61
|
+
|
|
62
|
+
| Code | Meaning | Raised by |
|
|
63
|
+
| ---- | -------------------- | -------------------------------------------------------------------------------------------- |
|
|
64
|
+
| 0 | success | step 7 (terminal); also `status="dry-run"` when `--dry-run` is set |
|
|
65
|
+
| 2 | input-missing / input-invalid | step 1 (no `skill_name` and no `--all` in headless) → `input-missing`; non-existent or malformed skill → `input-invalid` |
|
|
66
|
+
| 3 | resolution-failure | step 1 §2 (no skills found / required artifacts missing); step 1 §1c (multi-skill batch contains a stack-skill that requires re-composition) |
|
|
67
|
+
| 4 | write-failure | On-Activation §3 pre-flight write probe; step 4 §6 (managed-section rewrite); step 4 §9 (manifest write); step 6 §4 (result-contract write) |
|
|
68
|
+
| 5 | state-conflict | step 4 §3b/§4c.1 (orphan context-files or manifest-orphan rows when user selects [c] Cancel); step 4 (malformed `<!-- SKF:BEGIN/END -->` markers in target context file) |
|
|
69
|
+
| 6 | user-cancelled | step 1 §6 confirmation gate `[X]`/cancel; step 4 §8 confirmation gate `[X]`/cancel; any prompt that accepted `cancel`/`exit`/`:q` |
|
|
70
|
+
|
|
71
|
+
## Result Contract (Headless)
|
|
72
|
+
|
|
73
|
+
When `{headless_mode}` is true, step 6 emits a single-line JSON envelope on **stdout** before chaining to step 7, and every HARD HALT emits the same envelope shape on **stderr** with `status: "error"`:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
SKF_EXPORT_RESULT_JSON: {"status":"success|error|dry-run","skills":[],"context_files_updated":[],"manifest_path":"…|null","headless_decisions":[],"exit_code":0,"halt_reason":null}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`status` is `"success"` on the terminal happy path, `"dry-run"` when `--dry-run` was set and the workflow exited before §4 writes, `"error"` on any HALT. `halt_reason` is one of: `null` (success / dry-run), `"input-missing"`, `"input-invalid"`, `"resolution-failure"`, `"stack-redirect"`, `"orphan-cancelled"`, `"malformed-markers"`, `"manifest-write-failed"`, `"context-rebuild-failed"`, `"write-failed"`, `"user-cancelled"`. `exit_code` matches the table above.
|
|
47
80
|
|
|
48
81
|
## On Activation
|
|
49
82
|
|
|
@@ -52,6 +85,42 @@ These rules apply to every step in this workflow:
|
|
|
52
85
|
- `skills_output_folder`, `forge_data_folder`, `sidecar_path`
|
|
53
86
|
- `snippet_skill_root_override` (optional string) — when set, overrides the IDE-derived `skill_root` for snippet `root:` paths. Authoring repos that keep all skills under a single on-disk folder (e.g. `skills/`) set this once so exported snippets reference the real layout instead of a per-IDE directory that does not exist. Consuming projects omit it.
|
|
54
87
|
|
|
55
|
-
2. **
|
|
88
|
+
2. **Compute run-scoped variables:**
|
|
89
|
+
- `timestamp` ← UTC `YYYYMMDD-HHmmss` captured at activation time. Fixed for the entire workflow run; summary.md reuses this when writing the result contract.
|
|
90
|
+
|
|
91
|
+
3. **Resolve `{headless_mode}`**: true if `--headless` or `-H` was passed as an argument, or if `headless_mode: true` in `{sidecar_path}/preferences.yaml`. Default: false.
|
|
92
|
+
|
|
93
|
+
4. **Resolve workflow customization.** Run:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
python3 {project-root}/_bmad/scripts/resolve_customization.py \
|
|
97
|
+
--skill {skill-root} --key workflow
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The script merges the three customization layers per `bmad-customize`'s structural merge rules (scalars override, arrays append):
|
|
101
|
+
|
|
102
|
+
- `{skill-root}/customize.toml` — bundled defaults
|
|
103
|
+
- `_bmad/custom/<skill-name>.toml` under `{project-root}` — team overrides (committed)
|
|
104
|
+
- `_bmad/custom/<skill-name>.user.toml` under `{project-root}` — personal overrides (gitignored)
|
|
105
|
+
|
|
106
|
+
If the script fails or is missing, fall back to reading `{skill-root}/customize.toml` directly — the bundled defaults are an empty string for each path scalar.
|
|
107
|
+
|
|
108
|
+
Apply the path-scalar fallback now so stage files don't have to repeat the conditional logic. For each scalar, if the merged value is empty or absent, use the bundled default:
|
|
109
|
+
|
|
110
|
+
- `{managedSectionFormatPath}` ← `workflow.managed_section_format_path` if non-empty, else `assets/managed-section-format.md`
|
|
111
|
+
- `{snippetFormatPath}` ← `workflow.snippet_format_path` if non-empty, else `assets/snippet-format.md`
|
|
112
|
+
- `{exportManifestPath}` ← `workflow.export_manifest_path` if non-empty, else `{skills_output_folder}/.export-manifest.json`
|
|
113
|
+
|
|
114
|
+
Stash all three as workflow-context variables. Stage files reference them directly — no conditional at the usage site.
|
|
115
|
+
|
|
116
|
+
5. **Pre-flight write probe.** Verify `{skills_output_folder}` is writable. A read-only mount, full disk, or permissions-denied path otherwise only surfaces at step 4's managed-section rewrite — by then the user has already confirmed the batch:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
mkdir -p "{skills_output_folder}" && \
|
|
120
|
+
printf 'probe' > "{skills_output_folder}/.skf-write-probe" && \
|
|
121
|
+
rm "{skills_output_folder}/.skf-write-probe"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
On any non-zero exit: HALT (exit code 4, `halt_reason: "write-failed"`). In headless mode, emit the error envelope per **Result Contract (Headless)** with `skills: []`, `context_files_updated: []`, `manifest_path: null`.
|
|
56
125
|
|
|
57
|
-
|
|
126
|
+
6. Load, read the full file, and then execute `references/load-skill.md` to begin the workflow.
|
|
@@ -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
|
|
|
@@ -65,7 +65,7 @@ Store `{skill_root}` for use in snippet generation. The context-snippet.md writt
|
|
|
65
65
|
|
|
66
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
67
|
|
|
68
|
-
Read `{skills_output_folder}/.export-manifest.json` (the same file step
|
|
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
69
|
|
|
70
70
|
- **If new gotchas are derived:** Use them (they supersede any prior gotchas). Write as `|gotchas: {pitfall-1}, {pitfall-2}` with no marker.
|
|
71
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.
|
|
@@ -122,7 +122,7 @@ Estimate token count of generated snippet (approximate: words * 1.3).
|
|
|
122
122
|
|
|
123
123
|
**Estimated tokens:** {count}"
|
|
124
124
|
|
|
125
|
-
Hold content in context for step
|
|
125
|
+
Hold content in context for step 4.
|
|
126
126
|
|
|
127
127
|
**If NOT dry-run:**
|
|
128
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
|
|