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
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'generate-snippet.md'
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
<!-- Config: communicate in {communication_language}. Validate package contents in {document_output_language}. -->
|
|
6
|
+
|
|
5
7
|
# Step 2: Package
|
|
6
8
|
|
|
7
9
|
## STEP GOAL:
|
|
@@ -12,21 +14,19 @@ To assemble and validate an agentskills.io-compliant package structure from the
|
|
|
12
14
|
|
|
13
15
|
- Focus only on package structure assembly and validation — do not modify SKILL.md content
|
|
14
16
|
- Auto-proceed when complete
|
|
15
|
-
- **Multi-skill mode:** when step
|
|
17
|
+
- **Multi-skill mode:** when step 1 loaded more than one skill (`len(skill_batch) > 1`), iterate sections 1–4 below per skill using each skill's `{resolved_skill_package}`. Collect per-skill status; report the aggregate in §4 as one row per skill. Halt the batch if any skill is NOT READY. See step 1 §1c.
|
|
16
18
|
|
|
17
19
|
## MANDATORY SEQUENCE
|
|
18
20
|
|
|
19
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
20
|
-
|
|
21
21
|
### 1. Validate Package Structure
|
|
22
22
|
|
|
23
|
-
Verify the skill package at `{resolved_skill_package}` (resolved in step
|
|
23
|
+
Verify the skill package at `{resolved_skill_package}` (resolved in step 1 via manifest or `active` symlink — see `knowledge/version-paths.md`) contains the expected agentskills.io package layout:
|
|
24
24
|
|
|
25
25
|
```
|
|
26
26
|
{skill_package} = {skills_output_folder}/{skill-name}/{version}/{skill-name}/
|
|
27
27
|
├── SKILL.md ← Required: Active skill document
|
|
28
28
|
├── metadata.json ← Required: Machine-readable metadata
|
|
29
|
-
├── context-snippet.md ← Will be generated/updated in step
|
|
29
|
+
├── context-snippet.md ← Will be generated/updated in step 3
|
|
30
30
|
├── references/ ← Optional: Progressive disclosure
|
|
31
31
|
│ ├── {function-a}.md
|
|
32
32
|
│ └── {function-b}.md
|
|
@@ -66,7 +66,7 @@ Determine package status:
|
|
|
66
66
|
|
|
67
67
|
**READY:** All required files present, all required metadata fields valid
|
|
68
68
|
**WARNINGS:** Ready but with missing recommended fields or empty references/
|
|
69
|
-
**NOT READY:** Missing required files or required metadata fields (should not reach here — step
|
|
69
|
+
**NOT READY:** Missing required files or required metadata fields (should not reach here — step 1 would have halted)
|
|
70
70
|
|
|
71
71
|
### 4. Report Package Status
|
|
72
72
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Static reference loaded by load-skill.md §1b only when
|
|
3
|
+
# `snippet_skill_root_override` is UNSET in config.yaml. When the
|
|
4
|
+
# override is set, every existing snippet's on-disk prefix is ground
|
|
5
|
+
# truth by contract — no probe needed and the entire authoring-repo
|
|
6
|
+
# escape hatch is already configured. Loaded once per export run, not
|
|
7
|
+
# per skill.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<!-- Config: communicate in {communication_language}. Render the warning and gate prompt in {document_output_language}. -->
|
|
11
|
+
|
|
12
|
+
# Snippet Root Prefix Mismatch — Pre-flight Probe
|
|
13
|
+
|
|
14
|
+
## Purpose
|
|
15
|
+
|
|
16
|
+
Catch the authoring-repo case before step 4 silently rewrites root paths. In an authoring repo, skills typically live under a single shared directory (`skills/`) that does not match any per-IDE `skill_root` (`.claude/skills/`, `.cursor/skills/`, etc.). Without this probe, step 4's root-rewrite algorithm would replace the on-disk prefix with an IDE-mapped one that the snippet files do not actually reside under.
|
|
17
|
+
|
|
18
|
+
Loaded by `load-skill.md` §1b after `target_context_files` is resolved and `snippet_skill_root_override` is confirmed unset.
|
|
19
|
+
|
|
20
|
+
## Inputs
|
|
21
|
+
|
|
22
|
+
- `target_context_files[0].skill_root` — the reference IDE-mapped skill root (used because step 3 §2.7 picks this same entry for snippet generation when no override is set)
|
|
23
|
+
- `{skills_output_folder}` — for manifest-driven candidate enumeration
|
|
24
|
+
- Current skill's snippet path (resolved via manifest / `active` symlink / flat path per `knowledge/version-paths.md`)
|
|
25
|
+
- `{headless_mode}` — boolean flag from workflow context
|
|
26
|
+
|
|
27
|
+
## Probe Algorithm
|
|
28
|
+
|
|
29
|
+
1. Collect candidate snippet paths:
|
|
30
|
+
- 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`.
|
|
31
|
+
- Also include the current skill's snippet if present.
|
|
32
|
+
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/`).
|
|
33
|
+
3. Collect unique prefixes into `observed_prefixes`.
|
|
34
|
+
4. Compare against `target_context_files[0].skill_root` (the reference).
|
|
35
|
+
|
|
36
|
+
## Mismatch Gate
|
|
37
|
+
|
|
38
|
+
**If `observed_prefixes` contains any value that does not match the reference `skill_root`:**
|
|
39
|
+
|
|
40
|
+
Emit a single warning (once, not per snippet) and present resolution options before continuing to §2:
|
|
41
|
+
|
|
42
|
+
> **Snippet root prefix mismatch detected.**
|
|
43
|
+
> Existing snippets use: `{observed_prefixes}`
|
|
44
|
+
> IDE-mapped skill_root: `{target_context_files[0].skill_root}`
|
|
45
|
+
>
|
|
46
|
+
> This usually means you are in an authoring repo where skills live under a single shared directory. Options:
|
|
47
|
+
>
|
|
48
|
+
> - **(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.
|
|
49
|
+
> - **(b) Proceed with IDE mapping** — step 4 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.
|
|
50
|
+
> - **(c) Cancel** — abort export and investigate.
|
|
51
|
+
>
|
|
52
|
+
> If multiple distinct prefixes were observed, the snippets disagree with each other — investigate before choosing (a).
|
|
53
|
+
|
|
54
|
+
Wait for user choice.
|
|
55
|
+
|
|
56
|
+
**Headless default:** when `{headless_mode}`, default to **(b) Proceed with IDE mapping** and log the observed prefix(es) so the mismatch is visible in run logs (not silent).
|
|
57
|
+
|
|
58
|
+
## Choice handling
|
|
59
|
+
|
|
60
|
+
### (a) Set override
|
|
61
|
+
|
|
62
|
+
Halt and instruct the user to update `config.yaml` with `snippet_skill_root_override: {observed_prefix}`, then re-run export. Exit code 6, `halt_reason: "user-cancelled"` (configuration change is out-of-band — workflow does not edit config.yaml on the user's behalf).
|
|
63
|
+
|
|
64
|
+
### (b) Proceed with IDE mapping
|
|
65
|
+
|
|
66
|
+
Continue to §2. Step 4's root-rewrite algorithm will rewrite every snippet's prefix to the reference `skill_root`. The user is accepting that the IDE's skill directory contains the actual files; if it does not, the resulting managed section will reference paths that don't resolve.
|
|
67
|
+
|
|
68
|
+
### (c) Cancel
|
|
69
|
+
|
|
70
|
+
HALT. Exit code 6, `halt_reason: "user-cancelled"`. No files written.
|
|
71
|
+
|
|
72
|
+
## No-mismatch fast path
|
|
73
|
+
|
|
74
|
+
**If all observed prefixes match the reference `skill_root` (or no existing snippets were found):** no warning, no gate. Return control to §1b and proceed silently to §2.
|
|
@@ -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 user-facing summary in {document_output_language}. -->
|
|
6
|
+
|
|
5
7
|
# Step 6: Summary
|
|
6
8
|
|
|
7
9
|
## STEP GOAL:
|
|
@@ -12,12 +14,10 @@ To present a complete export summary showing all files written, token counts, an
|
|
|
12
14
|
|
|
13
15
|
- Focus only on summarizing what was done and providing next steps — no additional file writes
|
|
14
16
|
- Chains to the local health-check step via `{nextStepFile}` after completion — the user-facing summary is NOT the terminal step
|
|
15
|
-
- **Multi-skill mode:** emit ONE consolidated summary and ONE result contract for the whole batch. The files-written table lists every skill in `skill_batch` (one row per skill's `context-snippet.md` + one row per target managed-section file, shared across the batch). The result contract's `outputs` enumerates every context-snippet file plus every target context file. Distribution instructions (§2) key off `source_authority` per skill — present one block per distinct authority value observed in the batch, listing the skills it applies to. See step
|
|
17
|
+
- **Multi-skill mode:** emit ONE consolidated summary and ONE result contract for the whole batch. The files-written table lists every skill in `skill_batch` (one row per skill's `context-snippet.md` + one row per target managed-section file, shared across the batch). The result contract's `outputs` enumerates every context-snippet file plus every target context file. Distribution instructions (§2) key off `source_authority` per skill — present one block per distinct authority value observed in the batch, listing the skills it applies to. See step 1 §1c.
|
|
16
18
|
|
|
17
19
|
## MANDATORY SEQUENCE
|
|
18
20
|
|
|
19
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
20
|
-
|
|
21
21
|
### 1. Compile Export Summary
|
|
22
22
|
|
|
23
23
|
"**Export Complete{if dry-run: ' (Dry Run)'}**
|
|
@@ -99,7 +99,7 @@ To install this skill into the current project right now:
|
|
|
99
99
|
npx skills add {resolved_skill_package}
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
Replace `{resolved_skill_package}` with the absolute path to the package folder shown above (from step
|
|
102
|
+
Replace `{resolved_skill_package}` with the absolute path to the package folder shown above (from step 2), e.g. `{skills_output_folder}/{skill-name}/{version}/{skill-name}/`.
|
|
103
103
|
|
|
104
104
|
For other source formats (registry name, git URL, tarball, etc.), see the **Installation → Source Formats** section at <https://www.npmjs.com/package/skills>.
|
|
105
105
|
|
|
@@ -130,7 +130,31 @@ No files were written. To run the export for real:
|
|
|
130
130
|
|
|
131
131
|
### 6. Result Contract
|
|
132
132
|
|
|
133
|
-
Write the result contract per `shared/references/output-contract-schema.md`: the per-run record at `{skills_output_folder}/export-skill-result-{
|
|
133
|
+
Write the result contract per `shared/references/output-contract-schema.md`: the per-run record at `{skills_output_folder}/export-skill-result-{timestamp}.json` (reuse the activation-stored `{timestamp}`, resolution to seconds) and a copy at `{skills_output_folder}/export-skill-result-latest.json` (stable path for pipeline consumers — copy, not symlink). Include all context files and target managed-section files in `outputs`; include total always-on and on-trigger token counts in `summary`.
|
|
134
|
+
|
|
135
|
+
When `{headless_mode}` is true, also emit the single-line envelope on **stdout** before chaining to step 7 (matches the SKILL.md "Result Contract (Headless)" shape):
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
SKF_EXPORT_RESULT_JSON: {"status":"success","skills":{skill_batch_names},"context_files_updated":{context_files_updated},"manifest_path":"{skills_output_folder}/.export-manifest.json","headless_decisions":{headless_decisions},"exit_code":0,"halt_reason":null}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Substitute `{skill_batch_names}`, `{context_files_updated}`, and `{headless_decisions}` as JSON arrays. When `--dry-run` was set, emit `"status":"dry-run"` instead and report what *would* have been written without performing the writes.
|
|
142
|
+
|
|
143
|
+
**`deviations[]` field (export-skill-specific extension):** when step 4 §4c.1 detected manifest-orphan managed rows and the operator (or `{headless_mode}`) chose **(b) Preserve verbatim**, also include a `deviations[]` array in the contract. Each entry has the shape:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"kind": "preserve_external_skills",
|
|
148
|
+
"skills": [
|
|
149
|
+
{"name": "skill-name", "version": "1.0.0", "source_files": ["CLAUDE.md", ".cursorrules"]}
|
|
150
|
+
],
|
|
151
|
+
"rationale": "managed-section row exists but no manifest entry / no source draft"
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`source_files` per skill records the prior context files the orphan was found in (the §4c.1 multi-file scan deduplicates by `(skill, version)` and tracks which target context files originally carried the row — useful when an operator later debugs which IDE's managed section first introduced the external skill).
|
|
156
|
+
|
|
157
|
+
Other workflow choices that diverge from the strict spec path may add their own entries with a distinct `kind` value — auditors then have one place to look for "what did this run choose to do differently from the canonical flow." Omit the field when there are no deviations rather than writing an empty array, so the absence is readable as "ran the canonical path."
|
|
134
158
|
|
|
135
159
|
### 7. Chain to Health Check
|
|
136
160
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
2
|
+
nextStepFile: 'summary.md'
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
<!-- Config: communicate in {communication_language}. Render the token report in {document_output_language}. -->
|
|
6
|
+
|
|
5
7
|
# Step 5: Token Report
|
|
6
8
|
|
|
7
9
|
## STEP GOAL:
|
|
@@ -12,15 +14,13 @@ To calculate approximate token counts for all exported artifacts and present a c
|
|
|
12
14
|
|
|
13
15
|
- Focus only on token counting and reporting — read-only measurement
|
|
14
16
|
- Auto-proceed when complete
|
|
15
|
-
- **Multi-skill mode:** when step
|
|
17
|
+
- **Multi-skill mode:** when step 1 loaded more than one skill (`len(skill_batch) > 1`), compute token counts per skill, then present one aggregate table with one row per skill (context-snippet.md, SKILL.md, metadata.json, references/, package total). Measure the managed section once for the run — it is shared across the batch. See step 1 §1c.
|
|
16
18
|
|
|
17
19
|
## MANDATORY SEQUENCE
|
|
18
20
|
|
|
19
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
20
|
-
|
|
21
21
|
### 1. Calculate Token Counts
|
|
22
22
|
|
|
23
|
-
For each artifact, estimate tokens using the heuristic: **words * 1.3** (approximate for GPT/Claude tokenizers). This same heuristic is used in step
|
|
23
|
+
For each artifact, estimate tokens using the heuristic: **words * 1.3** (approximate for GPT/Claude tokenizers). This same heuristic is used in step 3 for snippet token estimation.
|
|
24
24
|
|
|
25
25
|
**Artifacts to measure:**
|
|
26
26
|
|
package/src/skf-export-skill/{steps-c/step-04-update-context.md → references/update-context.md}
RENAMED
|
@@ -1,8 +1,32 @@
|
|
|
1
1
|
---
|
|
2
|
-
nextStepFile: '
|
|
3
|
-
managedSectionData: '
|
|
2
|
+
nextStepFile: 'token-report.md'
|
|
3
|
+
managedSectionData: '{managedSectionFormatPath}'
|
|
4
|
+
# Resolve `{rebuildManagedSectionsHelper}` by probing
|
|
5
|
+
# `{rebuildManagedSectionsProbeOrder}` in order (installed SKF module path
|
|
6
|
+
# first, src/ dev-checkout fallback); first existing path wins. §9 uses
|
|
7
|
+
# the `replace` action for the surgical between-marker swap with
|
|
8
|
+
# atomic temp-file + rename, marker preservation, and post-write verify.
|
|
9
|
+
# HALT if no candidate exists — the in-prompt prose path silently regresses
|
|
10
|
+
# the Case 4 (malformed markers) HARD HALT guarantee.
|
|
11
|
+
rebuildManagedSectionsProbeOrder:
|
|
12
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-rebuild-managed-sections.py'
|
|
13
|
+
- '{project-root}/src/shared/scripts/skf-rebuild-managed-sections.py'
|
|
14
|
+
# Resolve `{manifestOpsHelper}` similarly. §9b uses `read` / `set` for
|
|
15
|
+
# atomic v2-schema-aware manifest mutation (handles v1→v2 migration and
|
|
16
|
+
# `platforms`→`ides` rename internally).
|
|
17
|
+
manifestOpsProbeOrder:
|
|
18
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-manifest-ops.py'
|
|
19
|
+
- '{project-root}/src/shared/scripts/skf-manifest-ops.py'
|
|
20
|
+
# Resolve `{atomicWriteHelper}` similarly. §6 Case 1 (Create) and §6
|
|
21
|
+
# Case 2 (Append) use it via `write` for safe artifact emission — the
|
|
22
|
+
# in-prompt write would risk half-written files on process kill.
|
|
23
|
+
atomicWriteProbeOrder:
|
|
24
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-atomic-write.py'
|
|
25
|
+
- '{project-root}/src/shared/scripts/skf-atomic-write.py'
|
|
4
26
|
---
|
|
5
27
|
|
|
28
|
+
<!-- Config: communicate in {communication_language}. Render the change preview and managed section in {document_output_language}. -->
|
|
29
|
+
|
|
6
30
|
# Step 4: Update Context
|
|
7
31
|
|
|
8
32
|
## STEP GOAL:
|
|
@@ -14,16 +38,14 @@ To update the managed `<!-- SKF:BEGIN/END -->` section in the platform-appropria
|
|
|
14
38
|
- Focus only on the managed section update in the target context file
|
|
15
39
|
- Do not modify any content outside `<!-- SKF:BEGIN -->` and `<!-- SKF:END -->` markers
|
|
16
40
|
- Do not write without user confirmation — this modifies shared project files
|
|
17
|
-
- If `passive_context: false` was detected in step
|
|
18
|
-
- **Multi-skill mode:** this step executes ONCE for the whole batch, not once per skill. §4b already builds the exported skill set from the manifest (plus current export targets), so a multi-skill run naturally appears as a single rebuild. The only batch adjustment is in §9b: update the manifest entry for every skill in `skill_batch` (not just one), and include all of them when computing `ides_written`. See step
|
|
41
|
+
- If `passive_context: false` was detected in step 1, skip this step entirely
|
|
42
|
+
- **Multi-skill mode:** this step executes ONCE for the whole batch, not once per skill. §4b already builds the exported skill set from the manifest (plus current export targets), so a multi-skill run naturally appears as a single rebuild. The only batch adjustment is in §9b: update the manifest entry for every skill in `skill_batch` (not just one), and include all of them when computing `ides_written`. See step 1 §1c.
|
|
19
43
|
|
|
20
44
|
## MANDATORY SEQUENCE
|
|
21
45
|
|
|
22
|
-
**CRITICAL:** Follow this sequence exactly. Do not skip, reorder, or improvise unless user explicitly requests a change.
|
|
23
|
-
|
|
24
46
|
### 1. Check Passive Context Setting
|
|
25
47
|
|
|
26
|
-
**If `passive_context: false` was detected in step
|
|
48
|
+
**If `passive_context: false` was detected in step 1:**
|
|
27
49
|
|
|
28
50
|
"**Passive context disabled in preferences.yaml. Skipping context update.**"
|
|
29
51
|
|
|
@@ -37,7 +59,7 @@ Load {managedSectionData} and read the complete format template and four-case lo
|
|
|
37
59
|
|
|
38
60
|
### 3. Determine Target File(s)
|
|
39
61
|
|
|
40
|
-
Using the `target_context_files` list resolved in step
|
|
62
|
+
Using the `target_context_files` list resolved in step 1, determine all target files. Each entry has `{context_file, skill_root}` — the context file to write and the IDE's skill directory for root path resolution.
|
|
41
63
|
|
|
42
64
|
For each entry in `target_context_files`, resolve target file path: `{context_file}`
|
|
43
65
|
|
|
@@ -49,87 +71,29 @@ For each entry in `target_context_files`, resolve target file path: `{context_fi
|
|
|
49
71
|
|
|
50
72
|
A context file becomes orphaned when its IDE is removed from `config.yaml` after a prior export. The file still contains an SKF managed section pointing to stale skill versions, but no future export will rewrite it.
|
|
51
73
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
1. For each known context file in `{CLAUDE.md, .cursorrules, AGENTS.md}`:
|
|
55
|
-
- If the context file is in `target_context_files`, skip (it will be rewritten in the main loop)
|
|
56
|
-
- Otherwise, check whether the file exists at `{context_file}`
|
|
57
|
-
- If the file exists, read it and check for the `<!-- SKF:BEGIN -->` marker
|
|
58
|
-
- If the marker is present, add the file path to `orphaned_context_files` along with the context file name
|
|
59
|
-
|
|
60
|
-
2. If `orphaned_context_files` is non-empty, emit a warning:
|
|
61
|
-
|
|
62
|
-
"**Orphaned context files detected.** The following files contain SKF managed sections but no configured IDEs target them:
|
|
63
|
-
{list: context file → file path}
|
|
64
|
-
|
|
65
|
-
The managed sections in these files are stale. Options:
|
|
66
|
-
- **(a) clear** — remove the SKF managed section from each orphaned file (surgical marker replacement, leaves user content intact)
|
|
67
|
-
- **(b) keep** — leave them untouched (they will remain stale until you re-add an IDE that targets this file or delete the file)
|
|
68
|
-
- **(c) rewrite** — also rewrite the orphaned files with the current skill index (use this if the IDE was removed by mistake)"
|
|
69
|
-
|
|
70
|
-
3. Wait for user choice. In non-interactive mode (dry-run or unattended), default to **(b) keep** and print the warning only.
|
|
71
|
-
|
|
72
|
-
4. If the user chose **(a) clear**: for each orphaned file, replace everything between `<!-- SKF:BEGIN` and `<!-- SKF:END -->` (inclusive) with an empty string, preserving surrounding content byte-exactly. Record the cleared files in `orphans_cleared`.
|
|
73
|
-
|
|
74
|
-
5. If the user chose **(c) rewrite**: add each orphaned context file to a separate `rewrite_context_files` list (kept distinct from `target_context_files` so the user's intent to only export to configured IDEs is preserved in the manifest). Use `.agents/skills/` as the default skill root for rewritten orphans. Sections 4–9a will loop over `target_context_files + rewrite_context_files` for this run only. Record the rewritten files in `orphans_rewritten`.
|
|
74
|
+
**Cheap pre-check (always run, ~3 file existence checks):** build `orphaned_context_files` — for each known context file in `{CLAUDE.md, .cursorrules, AGENTS.md}` that is NOT in `target_context_files`, check whether it exists on disk and contains the `<!-- SKF:BEGIN -->` marker. If yes, add `{context_file, file_path}` to `orphaned_context_files`.
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
**If `orphaned_context_files` is non-empty:** load `references/orphan-context-detection.md` and follow its (a) clear / (b) keep / (c) rewrite gate protocol. The reference handles user prompting, headless default (keep), and downstream-state recording (`orphans_cleared`, `orphans_rewritten`, `rewrite_context_files`). When the user chooses (c), the §4–§9a loop iterates over `target_context_files + rewrite_context_files`.
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
**If `orphaned_context_files` is empty:** proceed to §4.
|
|
79
79
|
|
|
80
80
|
### 4. Rebuild Complete Skill Index
|
|
81
81
|
|
|
82
82
|
#### 4a. Read Export Manifest (v2 — version-aware)
|
|
83
83
|
|
|
84
|
-
Read `{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
**v2 manifest** (`schema_version: "2"`):
|
|
89
|
-
```json
|
|
90
|
-
{
|
|
91
|
-
"schema_version": "2",
|
|
92
|
-
"exports": {
|
|
93
|
-
"skill-name": {
|
|
94
|
-
"active_version": "0.6.0",
|
|
95
|
-
"versions": {
|
|
96
|
-
"0.1.0": {
|
|
97
|
-
"ides": ["claude-code"],
|
|
98
|
-
"last_exported": "2026-01-15",
|
|
99
|
-
"status": "deprecated"
|
|
100
|
-
},
|
|
101
|
-
"0.5.0": {
|
|
102
|
-
"ides": ["claude-code"],
|
|
103
|
-
"last_exported": "2026-03-15",
|
|
104
|
-
"status": "archived"
|
|
105
|
-
},
|
|
106
|
-
"0.6.0": {
|
|
107
|
-
"ides": ["claude-code", "github-copilot"],
|
|
108
|
-
"last_exported": "2026-04-04",
|
|
109
|
-
"status": "active"
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
84
|
+
Read the manifest via `{manifestOpsHelper}` (resolved at §9 from `{manifestOpsProbeOrder}` — see frontmatter):
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
python3 {manifestOpsHelper} {skills_output_folder} read
|
|
115
88
|
```
|
|
116
89
|
|
|
117
|
-
|
|
118
|
-
- `"active"` — currently exported; snippet appears in managed sections
|
|
119
|
-
- `"archived"` — previously exported, not active; files retained for rollback
|
|
120
|
-
- `"deprecated"` — dropped via drop-skill workflow; excluded from all exports (files may or may not exist on disk)
|
|
121
|
-
- `"draft"` — created but never exported
|
|
90
|
+
The helper handles v2-schema enforcement, v1→v2 migration, and the `platforms`→`ides` rename internally. The returned JSON is always in canonical v2 shape regardless of on-disk state.
|
|
122
91
|
|
|
123
|
-
**
|
|
92
|
+
**Schema reference:** `references/manifest-rebuild.md` documents the v2 shape, the status enum (`active`/`archived`/`deprecated`/`draft`), the v1 migration path, and the `active_version` integrity invariant. Load that file only when an inline schema reminder is needed — the helper enforces the shape so the in-prompt prose is not load-bearing.
|
|
124
93
|
|
|
125
|
-
**
|
|
126
|
-
1. For each entry in `exports`, read its `last_exported` (v1 had no per-version IDE list)
|
|
127
|
-
2. Resolve the skill's current version from `{resolved_skill_package}/metadata.json`
|
|
128
|
-
3. Wrap in v2 structure: set `active_version` to the resolved version, create a single entry in `versions` with `status: "active"`, `ides: []` (unknown — will be filled on next successful export), and `last_exported`
|
|
129
|
-
4. Set `schema_version: "2"` at root
|
|
130
|
-
5. Hold the migrated structure in context (it will be written in section 9b)
|
|
94
|
+
**Integrity guard:** if the helper returns an entry where `active_version` does not resolve to a key in `versions`, the manifest is inconsistent. Skip the affected skill and log: "**Manifest integrity warning:** `{skill-name}.active_version = v{active_version}` has no matching entry under `versions`. Skipping. Re-run `[EX] Export Skill` on `{skill-name}` to repair the manifest entry."
|
|
131
95
|
|
|
132
|
-
**If the
|
|
96
|
+
**If the manifest does not exist** (first export or fresh forge): the helper returns `{"schema_version": "2", "exports": {}}`. Only the current export target will appear in the rebuilt index.
|
|
133
97
|
|
|
134
98
|
#### 4b. Build Exported Skill Set (version-aware)
|
|
135
99
|
|
|
@@ -156,6 +120,26 @@ Instead of globbing `{skills_output_folder}/*/context-snippet.md`, resolve snipp
|
|
|
156
120
|
|
|
157
121
|
**If no snippets pass the filter:** Generate managed section with zero skills — header only, no skill entries.
|
|
158
122
|
|
|
123
|
+
#### 4c.1 Detect Orphaned Managed-Section Rows (manifest-absent skills)
|
|
124
|
+
|
|
125
|
+
A managed-section row becomes orphaned when a `[skill-name v...]` entry already exists in the prior managed section but the skill is not in the exported skill set built in 4b — typically an externally-installed skill authored in a different repo and dropped into `{skills_output_folder}` without going through export-skill. Strict ADR-K would silently drop such rows, but the user's managed section is load-bearing — silent removal is a regression.
|
|
126
|
+
|
|
127
|
+
**Cheap pre-check (always run before §5 assembly).** Scan **every** target context file (not just the first), deduplicate by `(skill_name, version)`, and present one consolidated gate. Asymmetric orphans — a row present in `.cursorrules` but absent from `CLAUDE.md`, or vice versa — must be detected; otherwise the §4 rebuild loop silently overwrites the orphan-bearing file's content (ADR-J violation: silent loss of user content).
|
|
128
|
+
|
|
129
|
+
1. Initialize `orphan_managed_rows = []` (a list of `{skill_name, version, snippet_text, source_files: []}` entries — `source_files` carries provenance for the gate display and the audit `deviations[]` entry).
|
|
130
|
+
2. **Iterate every entry in `target_context_files`:**
|
|
131
|
+
a. Read the prior managed section from `{entry.context_file}`. If the file does not exist or has no `<!-- SKF:BEGIN -->` marker, skip this entry — it has no orphans by definition.
|
|
132
|
+
b. Parse the `[skill-name v...]` rows between `<!-- SKF:BEGIN -->` and `<!-- SKF:END -->` into `file_rows` — a list of `{skill_name, version, snippet_text}` triples (capture the original snippet line(s) verbatim so they can be re-emitted unchanged if (b) is chosen).
|
|
133
|
+
c. For each `row` in `file_rows`:
|
|
134
|
+
- If `row.skill_name` is in the exported skill set built in 4b (manifest entries plus current-export targets), skip — not an orphan.
|
|
135
|
+
- Otherwise look up `(row.skill_name, row.version)` in `orphan_managed_rows`:
|
|
136
|
+
- If already present, append `entry.context_file` to that row's `source_files` list (deduplicated). Keep the first-encountered `snippet_text` — divergent snippets across files for the same `(skill, version)` are themselves a user-content asymmetry but the `(b) Preserve verbatim` semantic writes one canonical row to every target file, so picking the first is deterministic and avoids silently choosing.
|
|
137
|
+
- If new, append `{skill_name: row.skill_name, version: row.version, snippet_text: row.snippet_text, source_files: [entry.context_file]}`.
|
|
138
|
+
|
|
139
|
+
**If `orphan_managed_rows` is non-empty:** load `references/orphan-row-detection.md` and follow its (a) Drop / (b) Preserve verbatim / (c) Cancel gate protocol. The reference handles user prompting (with per-orphan `source_files` provenance), headless default (Preserve verbatim), `deviations[]` recording (including `source_files` per orphan for audit), and §6 result-contract integration.
|
|
140
|
+
|
|
141
|
+
**If `orphan_managed_rows` is empty:** proceed to §4d.
|
|
142
|
+
|
|
159
143
|
#### 4d. Rewrite Root Paths for Target Context File
|
|
160
144
|
|
|
161
145
|
The context-snippet.md files on disk contain root paths for the IDE they were originally exported to. When assembling the managed section for the current target context file, rewrite root paths if they differ from the target's `skill_root`.
|
|
@@ -217,8 +201,9 @@ Assemble the complete managed section:
|
|
|
217
201
|
- Preserved: ALL content before `<!-- SKF:BEGIN` and after `<!-- SKF:END -->`
|
|
218
202
|
|
|
219
203
|
**Case 4: Malformed markers (file contains `<!-- SKF:BEGIN` but no `<!-- SKF:END -->`)**
|
|
220
|
-
- Action: HALT with warning: "Malformed SKF markers detected in `{target-file}` — `<!-- SKF:BEGIN` found but `<!-- SKF:END -->` is missing. Please restore the end marker manually before running export."
|
|
221
|
-
- Do NOT attempt to write or append — the file is in an inconsistent state
|
|
204
|
+
- Action: HALT (exit code 5, `halt_reason: "malformed-markers"`) with warning: "Malformed SKF markers detected in `{target-file}` — `<!-- SKF:BEGIN` found but `<!-- SKF:END -->` is missing. Please restore the end marker manually before running export."
|
|
205
|
+
- Do NOT attempt to write or append — the file is in an inconsistent state.
|
|
206
|
+
- In headless mode, emit the error envelope per SKILL.md "Result Contract (Headless)" with `manifest_path: null`, `context_files_updated: []`.
|
|
222
207
|
|
|
223
208
|
### 7. Present Change Preview
|
|
224
209
|
|
|
@@ -251,18 +236,19 @@ Auto-proceed to {nextStepFile}.
|
|
|
251
236
|
|
|
252
237
|
**If NOT dry-run:**
|
|
253
238
|
|
|
254
|
-
Display: "**Select:** [C] Continue — write changes to {target-file}"
|
|
239
|
+
Display: "**Select:** [C] Continue — write changes to {target-file} | [X] Cancel and exit (or type `cancel` / `exit` / `:q`)"
|
|
255
240
|
|
|
256
241
|
**Multi-target behavior:** When processing multiple context files, present all previews together before asking for a single confirmation. After confirmation, write all target files sequentially, verifying each one.
|
|
257
242
|
|
|
258
243
|
"**Targets:** {list all context-file → target-file pairs}
|
|
259
244
|
**Ready to write changes to all targets?**"
|
|
260
245
|
|
|
261
|
-
Display: "**Select:** [C] Continue — write changes to all targets"
|
|
246
|
+
Display: "**Select:** [C] Continue — write changes to all targets | [X] Cancel and exit"
|
|
262
247
|
|
|
263
248
|
#### Menu Handling Logic:
|
|
264
249
|
|
|
265
250
|
- IF C: Write the changes to all target files (or single target), verify each write succeeded, then load, read entire file, then execute {nextStepFile}
|
|
251
|
+
- IF X (or `cancel` / `exit` / `:q`): Display "Cancelled — no context files were written." 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`.
|
|
266
252
|
- IF Any other: help user respond, then [Redisplay Menu Options](#8-present-menu-options)
|
|
267
253
|
|
|
268
254
|
#### EXECUTION RULES:
|
|
@@ -274,16 +260,49 @@ Display: "**Select:** [C] Continue — write changes to all targets"
|
|
|
274
260
|
|
|
275
261
|
### 9. Write and Verify (Non-Dry-Run Only)
|
|
276
262
|
|
|
277
|
-
After user confirms with 'C':
|
|
263
|
+
After user confirms with 'C', resolve the helpers in parallel — these are independent file-existence checks that batch into one tool-call message:
|
|
264
|
+
|
|
265
|
+
- `{rebuildManagedSectionsHelper}` ← first existing path in `{rebuildManagedSectionsProbeOrder}` (used for Cases 2 and 3)
|
|
266
|
+
- `{atomicWriteHelper}` ← first existing path in `{atomicWriteProbeOrder}` (used for Case 1)
|
|
267
|
+
- `{manifestOpsHelper}` ← first existing path in `{manifestOpsProbeOrder}` (used in §9b)
|
|
268
|
+
|
|
269
|
+
If any helper has no existing candidate, HALT (exit code 4, `halt_reason: "context-rebuild-failed"`) and emit the error envelope per SKILL.md "Result Contract (Headless)" — the rewrite's safety guarantees depend on these helpers and a fall-through to LLM-driven writes would silently regress atomicity, marker preservation, and the Case 4 malformed-marker HARD HALT contract.
|
|
278
270
|
|
|
279
|
-
|
|
280
|
-
2. Re-read the written file
|
|
281
|
-
3. Verify `<!-- SKF:BEGIN` and `<!-- SKF:END -->` markers are present
|
|
282
|
-
4. Verify content outside markers is unchanged (for Cases 2 and 3)
|
|
283
|
-
5. Report: "**{target-file} updated successfully.** Verified: markers present, external content preserved."
|
|
271
|
+
For each target context file, dispatch by case:
|
|
284
272
|
|
|
285
|
-
**
|
|
286
|
-
|
|
273
|
+
**Case 1 (Create — file does not exist):**
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
echo "{new_managed_section_text}" | python3 {atomicWriteHelper} write "{target-file}"
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
The helper stages the content into `<target>.skf-tmp`, fsyncs, and atomically renames into place.
|
|
280
|
+
|
|
281
|
+
**Case 2 (Append — file exists, no `<!-- SKF:BEGIN` marker):**
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
python3 {rebuildManagedSectionsHelper} {target-file} insert --content "{new_managed_section_text}"
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
The helper appends the managed section to the end of the file via the same atomic temp-file + rename pattern.
|
|
288
|
+
|
|
289
|
+
**Case 3 (Regenerate — file contains `<!-- SKF:BEGIN` and `<!-- SKF:END -->`):**
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
python3 {rebuildManagedSectionsHelper} {target-file} replace --content "{new_managed_section_text}"
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
The helper performs the surgical between-marker swap with post-write verification (markers present, content outside markers byte-identical).
|
|
296
|
+
|
|
297
|
+
**Case 4 (malformed markers — already HALTed in §6):** never reaches here.
|
|
298
|
+
|
|
299
|
+
**Verification (deferred to helpers):** the `replace`/`insert`/`write` actions above each perform their own verification. Treat any non-zero exit as a write failure:
|
|
300
|
+
|
|
301
|
+
- HALT (exit code 4, `halt_reason: "context-rebuild-failed"`) and report `{target-file}: {captured stderr}`.
|
|
302
|
+
- In headless mode, emit the error envelope.
|
|
303
|
+
- Continue to the next target file only on success — partial-batch writes are acceptable in single-skill mode but the overall envelope reports per-target outcomes.
|
|
304
|
+
|
|
305
|
+
On success per file, report: "**{target-file} updated successfully.** Verified by `{rebuildManagedSectionsHelper}` (or `{atomicWriteHelper}` for Case 1)."
|
|
287
306
|
|
|
288
307
|
### 9b. Update Export Manifest (Non-Dry-Run Only)
|
|
289
308
|
|
|
@@ -313,11 +332,17 @@ After user confirms with 'C':
|
|
|
313
332
|
- If the version already exists in `versions`, union its existing `ides` with `ides_written` (deduplicate, keep sorted), refresh `last_exported`, and set `status: "active"`
|
|
314
333
|
- If this is a new version, add it to `versions` with `status: "active"` and set any previously-active version's status to `"archived"`
|
|
315
334
|
- Preserve all other version entries in `versions` (do not delete archived versions)
|
|
316
|
-
5. Write the updated manifest
|
|
335
|
+
5. Write the updated manifest atomically via `{manifestOpsHelper}` after all skills in the batch have been applied. For each skill / version pair, invoke:
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
python3 {manifestOpsHelper} {skills_output_folder} set {skill-name} {version}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
The helper handles v2-schema validation, v1→v2 migration, and `platforms`→`ides` rename internally — no in-prompt JSON manipulation needed. Each `set` invocation merges the per-version `ides` and `last_exported` fields into the existing entry. After all skills have been set, re-read the manifest via `{manifestOpsHelper} {skills_output_folder} read` to confirm the final state matches expectations.
|
|
317
342
|
|
|
318
343
|
**Dry-run mode:** Do NOT update the manifest. Display: "**[DRY RUN] Export manifest would be updated for {skill-name-list} — ides: {ides_written}.**" (list every skill in `skill_batch`)
|
|
319
344
|
|
|
320
|
-
**Error handling:** If
|
|
345
|
+
**Error handling:** If `{manifestOpsHelper}` exits non-zero, HALT (exit code 4, `halt_reason: "manifest-write-failed"`) with the captured `stderr`. The managed section was already written successfully; the operator's recovery path is to manually reconcile the on-disk managed section with the manifest, then re-run `[EX] Export Skill --all` to refresh the manifest. In headless mode, emit the error envelope per SKILL.md "Result Contract (Headless)" with `manifest_path: null` and the partial `context_files_updated` list.
|
|
321
346
|
|
|
322
347
|
## CRITICAL STEP COMPLETION NOTE
|
|
323
348
|
|