bmad-module-skill-forge 2.2.0 → 4.0.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 +49 -49
- package/docs/404.md +10 -8
- package/docs/_data/pinned.yaml +22 -13
- package/docs/_internal/STABILITY.md +58 -35
- package/docs/agents.md +39 -53
- package/docs/architecture.md +65 -51
- package/docs/bmad-synergy.md +53 -51
- package/docs/campaign.md +127 -75
- package/docs/concepts.md +34 -28
- package/docs/examples.md +70 -68
- package/docs/forge-auto.md +34 -31
- package/docs/getting-started.md +118 -57
- package/docs/how-it-works.md +25 -21
- package/docs/index.md +15 -15
- package/docs/skill-model.md +70 -59
- package/docs/troubleshooting.md +143 -18
- package/docs/verifying-a-skill.md +87 -57
- package/docs/why-skf.md +24 -22
- package/docs/workflows.md +274 -110
- package/package.json +18 -10
- package/src/forger/preferences.yaml +8 -1
- package/src/knowledge/agentskills-spec.md +2 -0
- package/src/knowledge/ccc-bridge.md +40 -24
- package/src/knowledge/confidence-tiers.md +9 -5
- package/src/knowledge/overview.md +3 -3
- package/src/knowledge/progressive-capability.md +8 -8
- package/src/knowledge/provenance-tracking.md +9 -5
- package/src/knowledge/qmd-registry.md +3 -3
- package/src/knowledge/skf-knowledge-index.csv +2 -2
- package/src/knowledge/skill-lifecycle.md +18 -11
- package/src/knowledge/split-body-strategy.md +0 -3
- package/src/knowledge/tool-resolution.md +4 -2
- package/src/knowledge/version-paths.md +101 -15
- package/src/module-help.csv +3 -3
- package/src/module.yaml +10 -0
- package/src/shared/data/ast-grep-recipes.yaml +608 -0
- package/src/shared/data/ide-context-files.json +30 -0
- package/src/shared/health-check.md +31 -59
- package/src/shared/references/description-guard-protocol.md +12 -9
- package/src/shared/references/feasibility-report-schema.md +19 -13
- package/src/shared/references/headless-gate-convention.md +55 -3
- package/src/shared/references/output-contract-schema.md +19 -8
- package/src/shared/references/pipeline-contracts.md +94 -29
- package/src/shared/references/tessl-review.md +77 -0
- package/src/shared/scripts/schemas/skf-analyze-result-envelope.v1.json +194 -0
- package/src/shared/scripts/schemas/skf-audit-result-envelope.v1.json +192 -0
- package/src/shared/scripts/schemas/skf-brief-result-envelope.v1.json +32 -4
- package/src/shared/scripts/schemas/skf-campaign-result-envelope.v1.json +174 -0
- package/src/shared/scripts/schemas/skf-create-skill-result-envelope.v1.json +284 -0
- package/src/shared/scripts/schemas/skf-drop-skill-result-envelope.v1.json +164 -0
- package/src/shared/scripts/schemas/skf-export-result-envelope.v1.json +160 -0
- package/src/shared/scripts/schemas/skf-quick-skill-result-envelope.v1.json +261 -0
- package/src/shared/scripts/schemas/skf-refine-architecture-result-envelope.v1.json +192 -0
- package/src/shared/scripts/schemas/skf-rename-skill-result-envelope.v1.json +179 -0
- package/src/shared/scripts/schemas/skf-setup-result-envelope.v1.json +27 -11
- package/src/shared/scripts/schemas/skf-stack-result-envelope.v1.json +176 -0
- package/src/shared/scripts/schemas/skf-test-result-envelope.v1.json +173 -0
- package/src/shared/scripts/schemas/skf-update-result-envelope.v1.json +19 -5
- package/src/shared/scripts/schemas/skf-verify-stack-result-envelope.v1.json +180 -0
- package/src/shared/scripts/schemas/skill-brief.v1.json +34 -0
- package/src/shared/scripts/schemas/workspace-detection.v1.json +1 -1
- package/src/shared/scripts/skf-atomic-write.py +233 -64
- package/src/shared/scripts/skf-build-change-manifest.py +2753 -28
- package/src/shared/scripts/skf-ccc-git-hygiene.py +532 -0
- package/src/shared/scripts/skf-check-unit-records.py +184 -0
- package/src/shared/scripts/skf-check-workspace-drift.py +538 -9
- package/src/shared/scripts/skf-classify-changed-files.py +772 -0
- package/src/shared/scripts/skf-comention-pairs.py +1333 -123
- package/src/shared/scripts/skf-compare-file-hashes.py +267 -105
- package/src/shared/scripts/skf-count-imports.py +1867 -0
- package/src/shared/scripts/skf-count-tokens.py +1 -1
- package/src/shared/scripts/skf-derive-assembly-shape.py +21 -3
- package/src/shared/scripts/skf-description-guard.py +99 -11
- package/src/shared/scripts/skf-detect-docs.py +694 -2
- package/src/shared/scripts/skf-detect-language.py +486 -107
- package/src/shared/scripts/skf-detect-registry.py +887 -0
- package/src/shared/scripts/skf-detect-scripts-assets.py +197 -55
- package/src/shared/scripts/skf-detect-tools.py +209 -27
- package/src/shared/scripts/skf-detect-workspaces.py +506 -30
- package/src/shared/scripts/skf-disqualify-candidates.py +821 -182
- package/src/shared/scripts/skf-emit-brief-result-envelope.py +69 -191
- package/src/shared/scripts/skf-emit-result-envelope.py +1604 -106
- package/src/shared/scripts/skf-enumerate-stack-skills.py +986 -117
- package/src/shared/scripts/skf-extract-public-api.py +5247 -96
- package/src/shared/scripts/skf-extraction-inventory.py +1280 -0
- package/src/shared/scripts/skf-extraction-snapshot.py +664 -0
- package/src/shared/scripts/skf-fetch-temporal.py +674 -0
- package/src/shared/scripts/skf-find-cycles.py +97 -29
- package/src/shared/scripts/skf-find-test-report.py +476 -0
- package/src/shared/scripts/skf-forge-tier-rw.py +469 -205
- package/src/shared/scripts/skf-github-fetch.py +365 -0
- package/src/shared/scripts/skf-github-probe.py +700 -0
- package/src/shared/scripts/skf-hash-content.py +180 -20
- package/src/shared/scripts/skf-language-corpora.py +1 -1
- package/src/shared/scripts/skf-load-provenance.py +161 -27
- package/src/shared/scripts/skf-manifest-ops.py +1 -1
- package/src/shared/scripts/skf-merge-ccc-exclusions.py +2307 -223
- package/src/shared/scripts/skf-merge-doc-urls.py +143 -20
- package/src/shared/scripts/skf-names-present.py +221 -0
- package/src/shared/scripts/skf-pair-intersect.py +119 -28
- package/src/shared/scripts/skf-parse-gaps.py +1384 -0
- package/src/shared/scripts/skf-preapply.py +1 -1
- package/src/shared/scripts/skf-preflight.py +176 -28
- package/src/shared/scripts/skf-promote-staged.py +430 -0
- package/src/shared/scripts/skf-provenance-gap-dispatch.py +64 -8
- package/src/shared/scripts/skf-qmd-classify-collections.py +229 -45
- package/src/shared/scripts/skf-quick-batch.py +774 -0
- package/src/shared/scripts/skf-rebuild-managed-sections.py +972 -88
- package/src/shared/scripts/skf-recommend-scope-type.py +323 -156
- package/src/shared/scripts/skf-render-metadata-stats.py +156 -12
- package/src/shared/scripts/skf-render-quick-metadata.py +132 -28
- package/src/shared/scripts/skf-render-stack-metadata.py +976 -0
- package/src/shared/scripts/skf-resolve-authoritative-files.py +155 -14
- package/src/shared/scripts/skf-resolve-package.py +523 -106
- package/src/shared/scripts/skf-rewrite-skill-name.py +433 -47
- package/src/shared/scripts/skf-run-lock.py +577 -0
- package/src/shared/scripts/skf-scan-manifests.py +998 -57
- package/src/shared/scripts/skf-scan-skill-md-structure.py +1341 -37
- package/src/shared/scripts/skf-severity-classify.py +712 -108
- package/src/shared/scripts/skf-shape-detect.py +298 -204
- package/src/shared/scripts/skf-shard-body.py +9 -8
- package/src/shared/scripts/skf-skill-inventory.py +2412 -89
- package/src/shared/scripts/skf-skills-module.py +472 -0
- package/src/shared/scripts/skf-source-tree.py +1796 -0
- package/src/shared/scripts/skf-structural-diff.py +787 -121
- package/src/shared/scripts/skf-tessl-review.py +706 -0
- package/src/shared/scripts/skf-update-active-symlink.py +120 -67
- package/src/shared/scripts/skf-update-run-state.py +624 -0
- package/src/shared/scripts/skf-validate-brief-inputs.py +92 -29
- package/src/shared/scripts/skf-validate-brief-schema.py +23 -2
- package/src/shared/scripts/skf-validate-feasibility-report.py +577 -66
- package/src/shared/scripts/skf-validate-frontmatter.py +103 -26
- package/src/shared/scripts/skf-validate-output.py +712 -64
- package/src/shared/scripts/skf-validate-pins.py +1 -1
- package/src/shared/scripts/skf-verify-no-trace.py +116 -10
- package/src/shared/scripts/skf-verify-provenance-completeness.py +3945 -152
- package/src/shared/scripts/skf-write-skill-brief.py +406 -25
- package/src/shared/tool-requirements.yaml +201 -0
- package/src/skf-analyze-source/SKILL.md +41 -36
- package/src/skf-analyze-source/assets/skill-brief-schema.md +7 -8
- package/src/skf-analyze-source/customize.toml +36 -24
- package/src/skf-analyze-source/references/auto-docs-only.md +58 -20
- package/src/skf-analyze-source/references/continue.md +2 -13
- package/src/skf-analyze-source/references/discover-additional-source.md +147 -0
- package/src/skf-analyze-source/references/generate-briefs.md +121 -55
- package/src/skf-analyze-source/references/headless-contract.md +42 -15
- package/src/skf-analyze-source/references/identify-units.md +96 -110
- package/src/skf-analyze-source/references/init.md +73 -71
- package/src/skf-analyze-source/references/map-and-detect.md +123 -105
- package/src/skf-analyze-source/references/map-unit-exports.md +68 -0
- package/src/skf-analyze-source/references/recommend.md +51 -70
- package/src/skf-analyze-source/references/scan-project.md +60 -84
- package/src/skf-analyze-source/references/scan-root.md +39 -0
- package/src/skf-analyze-source/references/step-auto-scope-coexistence.md +47 -0
- package/src/skf-analyze-source/references/step-auto-scope-corpora.md +53 -0
- package/src/skf-analyze-source/references/step-auto-scope-split.md +91 -0
- package/src/skf-analyze-source/references/step-auto-scope.md +208 -293
- package/src/skf-analyze-source/references/step-shape-detect.md +14 -12
- package/src/skf-analyze-source/references/unit-detection-heuristics.md +37 -42
- package/src/skf-audit-skill/SKILL.md +43 -51
- package/src/skf-audit-skill/assets/drift-report-template.md +28 -3
- package/src/skf-audit-skill/customize.toml +41 -20
- package/src/skf-audit-skill/references/constituent-freshness.md +91 -0
- package/src/skf-audit-skill/references/doc-drift.md +141 -0
- package/src/skf-audit-skill/references/headless-contract.md +29 -0
- package/src/skf-audit-skill/references/health-check.md +2 -0
- package/src/skf-audit-skill/references/init.md +149 -210
- package/src/skf-audit-skill/references/re-index.md +103 -110
- package/src/skf-audit-skill/references/report.md +96 -33
- package/src/skf-audit-skill/references/semantic-diff.md +34 -25
- package/src/skf-audit-skill/references/severity-classify.md +79 -65
- package/src/skf-audit-skill/references/severity-rules.md +15 -6
- package/src/skf-audit-skill/references/structural-diff.md +80 -90
- package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
- package/src/skf-audit-skill/scripts/render-drift-tables.py +712 -0
- package/src/skf-brief-skill/SKILL.md +37 -26
- package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
- package/src/skf-brief-skill/assets/scope-templates.md +18 -25
- package/src/skf-brief-skill/assets/skill-brief-schema.md +30 -23
- package/src/skf-brief-skill/customize.toml +48 -20
- package/src/skf-brief-skill/references/analyze-target.md +144 -127
- package/src/skf-brief-skill/references/confirm-brief.md +11 -9
- package/src/skf-brief-skill/references/draft-checkpoint.md +36 -17
- package/src/skf-brief-skill/references/gather-intent-ratify.md +68 -0
- package/src/skf-brief-skill/references/gather-intent.md +87 -182
- package/src/skf-brief-skill/references/headless-args.md +84 -16
- package/src/skf-brief-skill/references/health-check.md +1 -1
- package/src/skf-brief-skill/references/invocation-contract.md +18 -13
- package/src/skf-brief-skill/references/portfolio-similarity-check.md +1 -1
- package/src/skf-brief-skill/references/qmd-collection-registration.md +7 -10
- package/src/skf-brief-skill/references/scope-definition.md +123 -47
- package/src/skf-brief-skill/references/step-auto-brief.md +26 -100
- package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
- package/src/skf-brief-skill/references/version-resolution.md +7 -10
- package/src/skf-brief-skill/references/write-brief.md +66 -57
- package/src/skf-campaign/SKILL.md +31 -34
- package/src/skf-campaign/assets/campaign-state-schema.json +25 -4
- package/src/skf-campaign/customize.toml +47 -16
- package/src/skf-campaign/references/campaign-contracts.md +39 -29
- package/src/skf-campaign/references/campaign-directive-spec.md +4 -2
- package/src/skf-campaign/references/health-check.md +7 -16
- package/src/skf-campaign/references/step-01-setup.md +46 -84
- package/src/skf-campaign/references/step-02-strategy.md +31 -30
- package/src/skf-campaign/references/step-03-pins.md +26 -18
- package/src/skf-campaign/references/step-04-provenance.md +24 -23
- package/src/skf-campaign/references/step-05-skill-loop.md +67 -48
- package/src/skf-campaign/references/step-06-batch.md +41 -34
- package/src/skf-campaign/references/step-07-capstone.md +40 -25
- package/src/skf-campaign/references/step-08-verify.md +28 -29
- package/src/skf-campaign/references/step-09-refine.md +29 -30
- package/src/skf-campaign/references/step-10-export.md +48 -36
- package/src/skf-campaign/references/step-11-maintenance.md +31 -34
- package/src/skf-campaign/references/step-resume.md +37 -68
- package/src/skf-campaign/scripts/campaign-deps.py +57 -18
- package/src/skf-campaign/scripts/campaign-parse-manifest.py +361 -54
- package/src/skf-campaign/scripts/campaign-provenance.py +96 -53
- package/src/skf-campaign/scripts/campaign-quality-gate.py +592 -0
- package/src/skf-campaign/scripts/campaign-render-batch.py +257 -49
- package/src/skf-campaign/scripts/campaign-render-kickoff.py +343 -50
- package/src/skf-campaign/scripts/campaign-report.py +204 -37
- package/src/skf-campaign/scripts/campaign-state.py +1128 -0
- package/src/skf-campaign/scripts/campaign-status.py +10 -74
- package/src/skf-campaign/scripts/campaign-validate-pins.py +30 -3
- package/src/skf-campaign/scripts/campaign-validate-state.py +34 -4
- package/src/skf-campaign/templates/campaign-brief-template.yaml +4 -5
- package/src/skf-campaign/templates/campaign-report-template.md +5 -1
- package/src/skf-campaign/templates/kickoff-template.md +0 -14
- package/src/skf-create-skill/SKILL.md +27 -20
- package/src/skf-create-skill/assets/compile-assembly-rules.md +11 -8
- package/src/skf-create-skill/assets/skill-sections.md +21 -11
- package/src/skf-create-skill/customize.toml +20 -8
- package/src/skf-create-skill/references/authoritative-files-protocol.md +36 -58
- package/src/skf-create-skill/references/batch-mode.md +81 -0
- package/src/skf-create-skill/references/ccc-index-check.md +27 -0
- package/src/skf-create-skill/references/compile.md +119 -70
- package/src/skf-create-skill/references/component-extraction.md +113 -91
- package/src/skf-create-skill/references/enrich.md +41 -23
- package/src/skf-create-skill/references/entry-points-by-hand.md +37 -0
- package/src/skf-create-skill/references/extract.md +204 -162
- package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
- package/src/skf-create-skill/references/extraction-patterns-tracing.md +11 -11
- package/src/skf-create-skill/references/extraction-patterns.md +588 -201
- package/src/skf-create-skill/references/generate-artifacts.md +145 -93
- package/src/skf-create-skill/references/health-check.md +1 -1
- package/src/skf-create-skill/references/load-brief.md +53 -36
- package/src/skf-create-skill/references/relabel-rule.md +12 -0
- package/src/skf-create-skill/references/report.md +37 -57
- package/src/skf-create-skill/references/source-resolution-protocols.md +58 -169
- package/src/skf-create-skill/references/step-auto-shard.md +20 -93
- package/src/skf-create-skill/references/step-doc-rot.md +44 -60
- package/src/skf-create-skill/references/step-doc-sources.md +28 -19
- package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
- package/src/skf-create-skill/references/sub/fetch-docs.md +106 -59
- package/src/skf-create-skill/references/sub/fetch-temporal.md +53 -166
- package/src/skf-create-skill/references/tier-degradation-rules.md +18 -9
- package/src/skf-create-skill/references/validate.md +173 -99
- package/src/skf-create-skill/scripts/scan-doc-rot.py +232 -99
- package/src/skf-create-stack-skill/SKILL.md +29 -56
- package/src/skf-create-stack-skill/assets/metadata-contract.md +51 -0
- package/src/skf-create-stack-skill/assets/provenance-map-schema.md +15 -15
- package/src/skf-create-stack-skill/assets/stack-skill-template.md +23 -57
- package/src/skf-create-stack-skill/customize.toml +23 -12
- package/src/skf-create-stack-skill/references/compile-stack.md +57 -66
- package/src/skf-create-stack-skill/references/compose-mode-rules.md +24 -44
- package/src/skf-create-stack-skill/references/detect-integrations.md +92 -95
- package/src/skf-create-stack-skill/references/detect-manifests.md +46 -71
- package/src/skf-create-stack-skill/references/generate-output.md +138 -128
- package/src/skf-create-stack-skill/references/init.md +90 -32
- package/src/skf-create-stack-skill/references/integration-patterns.md +1 -17
- package/src/skf-create-stack-skill/references/invocation-contract.md +34 -0
- package/src/skf-create-stack-skill/references/manifest-patterns.md +32 -20
- package/src/skf-create-stack-skill/references/parallel-extract.md +112 -38
- package/src/skf-create-stack-skill/references/rank-and-confirm.md +57 -75
- package/src/skf-create-stack-skill/references/report.md +39 -33
- package/src/skf-create-stack-skill/references/validate.md +20 -39
- package/src/skf-drop-skill/SKILL.md +28 -51
- package/src/skf-drop-skill/customize.toml +44 -30
- package/src/skf-drop-skill/references/execute.md +83 -146
- package/src/skf-drop-skill/references/health-check.md +2 -0
- package/src/skf-drop-skill/references/invocation-contract.md +64 -0
- package/src/skf-drop-skill/references/report.md +46 -30
- package/src/skf-drop-skill/references/select.md +122 -124
- package/src/skf-drop-skill/scripts/dir-sizes.py +54 -26
- package/src/skf-drop-skill/scripts/drop-roster.py +322 -0
- package/src/skf-export-skill/SKILL.md +40 -62
- package/src/skf-export-skill/assets/managed-section-format.md +14 -50
- package/src/skf-export-skill/assets/snippet-format.md +3 -1
- package/src/skf-export-skill/customize.toml +42 -13
- package/src/skf-export-skill/references/generate-snippet.md +54 -46
- package/src/skf-export-skill/references/health-check.md +2 -0
- package/src/skf-export-skill/references/invocation-contract.md +15 -0
- package/src/skf-export-skill/references/load-skill.md +88 -62
- package/src/skf-export-skill/references/manifest-rebuild.md +9 -10
- package/src/skf-export-skill/references/multi-skill-mode.md +4 -4
- package/src/skf-export-skill/references/orphan-context-detection.md +13 -5
- package/src/skf-export-skill/references/orphan-row-detection.md +31 -22
- package/src/skf-export-skill/references/package.md +15 -73
- package/src/skf-export-skill/references/preflight-snippet-root-probe.md +51 -70
- package/src/skf-export-skill/references/result-envelope.md +31 -16
- package/src/skf-export-skill/references/summary.md +41 -17
- package/src/skf-export-skill/references/token-report.md +4 -12
- package/src/skf-export-skill/references/update-context.md +118 -237
- package/src/skf-forger/SKILL.md +61 -37
- package/src/skf-forger/bmad-skill-manifest.yaml +4 -1
- package/src/skf-forger/customize.toml +43 -0
- package/src/skf-forger/references/pipeline-mode.md +73 -18
- package/src/skf-forger/scripts/forge-status.py +299 -0
- package/src/skf-forger/scripts/parse-pipeline.py +322 -54
- package/src/skf-forger/scripts/pipeline-gate.py +428 -0
- package/src/skf-forger/scripts/pipeline-journal.py +1052 -0
- package/src/skf-quick-skill/SKILL.md +54 -53
- package/src/skf-quick-skill/assets/skill-template.md +4 -2
- package/src/skf-quick-skill/customize.toml +51 -20
- package/src/skf-quick-skill/references/batch-mode.md +74 -21
- package/src/skf-quick-skill/references/compile.md +30 -31
- package/src/skf-quick-skill/references/ecosystem-check.md +7 -57
- package/src/skf-quick-skill/references/finalize.md +69 -18
- package/src/skf-quick-skill/references/halt-contract.md +41 -29
- package/src/skf-quick-skill/references/health-check.md +5 -3
- package/src/skf-quick-skill/references/quick-extract.md +114 -45
- package/src/skf-quick-skill/references/registry-resolution.md +9 -64
- package/src/skf-quick-skill/references/resolve-target.md +116 -66
- package/src/skf-quick-skill/references/write-and-validate.md +79 -40
- package/src/skf-refine-architecture/SKILL.md +43 -53
- package/src/skf-refine-architecture/customize.toml +49 -20
- package/src/skf-refine-architecture/references/compile.md +97 -54
- package/src/skf-refine-architecture/references/exit-codes.md +30 -0
- package/src/skf-refine-architecture/references/finding-storage.md +21 -0
- package/src/skf-refine-architecture/references/gap-analysis.md +101 -38
- package/src/skf-refine-architecture/references/improvements.md +14 -20
- package/src/skf-refine-architecture/references/init.md +98 -57
- package/src/skf-refine-architecture/references/issue-detection.md +32 -39
- package/src/skf-refine-architecture/references/refinement-rules.md +37 -48
- package/src/skf-refine-architecture/references/report.md +65 -54
- package/src/skf-refine-architecture/scripts/skf-check-preservation.py +1619 -0
- package/src/skf-rename-skill/SKILL.md +19 -54
- package/src/skf-rename-skill/customize.toml +32 -26
- package/src/skf-rename-skill/references/execute.md +230 -184
- package/src/skf-rename-skill/references/exit-codes.md +7 -7
- package/src/skf-rename-skill/references/health-check.md +1 -7
- package/src/skf-rename-skill/references/invocation-contract.md +25 -0
- package/src/skf-rename-skill/references/report.md +63 -52
- package/src/skf-rename-skill/references/select.md +197 -115
- package/src/skf-rename-skill/scripts/skf-validate-rename-name.py +161 -21
- package/src/skf-setup/SKILL.md +26 -26
- package/src/skf-setup/customize.toml +14 -10
- package/src/skf-setup/references/auto-index.md +50 -63
- package/src/skf-setup/references/ccc-index.md +29 -90
- package/src/skf-setup/references/detect-and-tier.md +58 -67
- package/src/skf-setup/references/health-check.md +2 -0
- package/src/skf-setup/references/invocation-contract.md +14 -0
- package/src/skf-setup/references/report.md +43 -166
- package/src/skf-setup/references/tier-rules.md +5 -5
- package/src/skf-setup/references/write-config.md +34 -57
- package/src/skf-test-skill/SKILL.md +17 -57
- package/src/skf-test-skill/assets/output-section-formats.md +33 -34
- package/src/skf-test-skill/customize.toml +27 -13
- package/src/skf-test-skill/references/coherence-check.md +134 -62
- package/src/skf-test-skill/references/coverage-check-tiers.md +35 -0
- package/src/skf-test-skill/references/coverage-check.md +209 -264
- package/src/skf-test-skill/references/detect-mode.md +5 -5
- package/src/skf-test-skill/references/external-validators.md +94 -82
- package/src/skf-test-skill/references/health-check.md +6 -7
- package/src/skf-test-skill/references/init.md +164 -91
- package/src/skf-test-skill/references/invocation-contract.md +66 -0
- package/src/skf-test-skill/references/migration-section-rules.md +5 -2
- package/src/skf-test-skill/references/report.md +164 -142
- package/src/skf-test-skill/references/score.md +80 -107
- package/src/skf-test-skill/references/scoring-rules.md +42 -155
- package/src/skf-test-skill/references/source-access-protocol.md +18 -94
- package/src/skf-test-skill/references/step-hard-gate.md +51 -33
- package/src/skf-test-skill/scripts/aggregate-coherence.py +218 -30
- package/src/skf-test-skill/scripts/build-result-context.py +380 -0
- package/src/skf-test-skill/scripts/check-metadata-coherence.py +37 -4
- package/src/skf-test-skill/scripts/combine-external-scores.py +23 -6
- package/src/skf-test-skill/scripts/compute-score.py +223 -45
- package/src/skf-test-skill/scripts/gap-ledger.py +1666 -0
- package/src/skf-test-skill/scripts/hard-gate.py +203 -0
- package/src/skf-test-skill/scripts/load-coverage-inputs.py +1198 -0
- package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
- package/src/skf-test-skill/scripts/reconcile-coverage.py +547 -79
- package/src/skf-test-skill/scripts/score-signatures.py +479 -0
- package/src/skf-test-skill/scripts/stage-helper-payload.py +148 -0
- package/src/skf-test-skill/scripts/validate-inventory.py +311 -16
- package/src/skf-test-skill/scripts/verify-declared-numerator.py +133 -56
- package/src/skf-test-skill/templates/test-report-template.md +21 -15
- package/src/skf-update-skill/SKILL.md +38 -25
- package/src/skf-update-skill/customize.toml +27 -12
- package/src/skf-update-skill/references/detect-changes.md +253 -223
- package/src/skf-update-skill/references/gap-driven.md +336 -0
- package/src/skf-update-skill/references/health-check.md +31 -5
- package/src/skf-update-skill/references/init.md +254 -84
- package/src/skf-update-skill/references/invocation-contract.md +12 -0
- package/src/skf-update-skill/references/manual-section-rules.md +6 -23
- package/src/skf-update-skill/references/merge.md +182 -49
- package/src/skf-update-skill/references/re-extract.md +53 -262
- package/src/skf-update-skill/references/report.md +102 -35
- package/src/skf-update-skill/references/write.md +357 -155
- package/src/skf-update-skill/scripts/skf-new-file-diff.py +183 -46
- package/src/skf-verify-stack/SKILL.md +23 -42
- package/src/skf-verify-stack/assets/feasibility-report-template.md +11 -5
- package/src/skf-verify-stack/customize.toml +55 -22
- package/src/skf-verify-stack/references/coverage-patterns.md +17 -8
- package/src/skf-verify-stack/references/coverage.md +67 -64
- package/src/skf-verify-stack/references/exit-codes.md +21 -8
- package/src/skf-verify-stack/references/init.md +107 -62
- package/src/skf-verify-stack/references/integration-verification-rules.md +12 -13
- package/src/skf-verify-stack/references/integrations.md +106 -65
- package/src/skf-verify-stack/references/report.md +59 -42
- package/src/skf-verify-stack/references/requirements.md +32 -9
- package/src/skf-verify-stack/references/synthesize.md +53 -39
- package/src/skf-verify-stack/scripts/skf-coverage-tally.py +398 -52
- package/src/skf-verify-stack/scripts/skf-previous-report.py +330 -0
- package/src/skf-verify-stack/scripts/skf-report-delta.py +453 -49
- package/src/skf-verify-stack/scripts/skf-verdict-rollup.py +240 -27
- package/tools/cli/commands/install.js +11 -4
- package/tools/cli/commands/status.js +15 -3
- package/tools/cli/commands/update.js +11 -4
- package/tools/cli/lib/tool-check.js +320 -0
- package/tools/cli/lib/version-check.js +22 -9
- package/tools/cli/skf-cli.js +4 -1
- package/.gitattributes +0 -16
- package/.nvmrc +0 -1
- package/docs/_internal/RELEASING.md +0 -679
- package/release-audits/v1.0.0-launch-audit.md +0 -728
- package/src/skf-audit-skill/references/step-doc-drift.md +0 -177
- package/src/skf-brief-skill/references/headless-source-authority-detection.md +0 -26
- package/src/skf-campaign/manifest.yaml +0 -15
- package/src/skf-create-skill/assets/tessl-dismissal-rules.md +0 -106
- package/src/skf-create-skill/references/ecosystem-check.md +0 -74
- package/src/skf-drop-skill/references/headless-contract.md +0 -18
- package/src/skf-update-skill/references/merge-conflict-rules.md +0 -15
- package/src/skf-update-skill/references/remote-source-resolution.md +0 -98
- package/src/skf-update-skill/references/validate.md +0 -124
- package/tools/validate-docs-drift.js +0 -233
- package/tools/validate-docs-links.js +0 -665
|
@@ -10,9 +10,15 @@ detectWorkspacesProbeOrder:
|
|
|
10
10
|
detectLanguageProbeOrder:
|
|
11
11
|
- '{project-root}/_bmad/skf/shared/scripts/skf-detect-language.py'
|
|
12
12
|
- '{project-root}/src/shared/scripts/skf-detect-language.py'
|
|
13
|
-
|
|
14
|
-
- '{project-root}/_bmad/skf/shared/scripts/skf-
|
|
15
|
-
- '{project-root}/src/shared/scripts/skf-
|
|
13
|
+
githubProbeProbeOrder:
|
|
14
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-github-probe.py'
|
|
15
|
+
- '{project-root}/src/shared/scripts/skf-github-probe.py'
|
|
16
|
+
githubFetchProbeOrder:
|
|
17
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-github-fetch.py'
|
|
18
|
+
- '{project-root}/src/shared/scripts/skf-github-fetch.py'
|
|
19
|
+
validatePinsProbeOrder:
|
|
20
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-validate-pins.py'
|
|
21
|
+
- '{project-root}/src/shared/scripts/skf-validate-pins.py'
|
|
16
22
|
---
|
|
17
23
|
|
|
18
24
|
<!-- Config: communicate in {communication_language}. -->
|
|
@@ -23,61 +29,100 @@ emitBriefEnvelopeProbeOrder:
|
|
|
23
29
|
|
|
24
30
|
- Do not make scoping decisions or recommendations
|
|
25
31
|
- Do not hallucinate or guess about repository contents
|
|
32
|
+
- **One display.** The §5 summary is this step's one display of the analysis. Before it, §2 to §4.3 show one progress line each, besides any warning, the truncation choice (§1), the monorepo pick (§1b) and §4.4's semantic signals; the values they compute stay in context for §5.
|
|
33
|
+
- **Staged inputs.** The helpers of this step read the repository from files in the run folder `{run_dir}` that step 1 §1 created, never from a list or a file's text typed into a command: `{run_dir}/tree.json` (the file list, §1), `{run_dir}/files/` (manifests and entry points fetched at `{analysis_ref}`, laid out like the repository), `{run_dir}/snapshot.json` (the tree's counts and module candidates, §2) and `{run_dir}/extract.json` (the exports, §4). Step 3 reads the same files.
|
|
34
|
+
- **Ratify run (`ratify_mode: true`):** this step runs only from step 4 `[R] Revise Scope`, to give step 3 an analysis of the brief's repository, and never replaces the hydrated `name`, `version` or `language`. §1 treats the hydrated `target_ref` and `target_version` as set in step 01, and a hydrated `version` without either as an implicit `target_version`: §1 resolves it to a tag the same way, and with no match analyzes `HEAD` without the zero-match warning. §1b selects, without asking, the workspace whose path begins the hydrated `scope.include` globs (the repo root when none does). §3 runs only to choose §4's path: the brief keeps the hydrated `language`, which the §5 summary shows with the hydrated `version`. Skip §4b. At §5, set `ratify_analyzed: true` in workflow context, so a later `[R]` goes straight to step 3.
|
|
26
35
|
|
|
27
36
|
## Sequence
|
|
28
37
|
|
|
38
|
+
### 0. Docs-Only Target
|
|
39
|
+
|
|
40
|
+
**If `source_type` is `docs-only`:** there is no repository to read, so skip §1 to §5 (no tree, manifests, extraction or version detection). Set `{language}` to the `language_hint` argument when one was supplied, else `documentation` (the language skf-analyze-source writes for a docs-only brief). Leave `detected_version` unset: the brief's version is `target_version` when step 1 collected one, else the `1.0.0` default (step 5's writer applies that precedence). Display:
|
|
41
|
+
|
|
42
|
+
"**Docs-only target: no repository to analyze.**
|
|
43
|
+
**Language:** {language}
|
|
44
|
+
**Version:** {target_version, or 1.0.0 (default)}"
|
|
45
|
+
|
|
46
|
+
Then load, read entire file, then execute {nextStepFile}.
|
|
47
|
+
|
|
48
|
+
**If `source_type` is `source`:** continue to §1.
|
|
49
|
+
|
|
29
50
|
### 1. Resolve Target Location
|
|
30
51
|
|
|
52
|
+
Display: "**Resolving target...**"
|
|
53
|
+
|
|
31
54
|
**For GitHub URLs:**
|
|
32
55
|
|
|
33
|
-
**Resolve the analysis ref first.** `{analysis_ref}` is the git ref every GitHub-API fetch in this step (tree, manifests, contents) reads from
|
|
34
|
-
- If neither `target_ref` nor `target_version` was set in step 01: `{analysis_ref}` = `HEAD` (default branch). This is the common case
|
|
35
|
-
- If `target_ref` is set (an explicit ref the user stated verbatim, highest priority): use it directly as `{analysis_ref}
|
|
36
|
-
- If `target_version` is set: resolve it to a tag
|
|
56
|
+
**Resolve the analysis ref first.** `{analysis_ref}` is the git ref every GitHub-API fetch in this step (tree, manifests, contents) reads from: resolve it before fetching anything so the analyzed structure matches the version being skilled.
|
|
57
|
+
- If neither `target_ref` nor `target_version` was set in step 01: `{analysis_ref}` = `HEAD` (default branch). This is the common case: skip straight to the listing below with no extra call.
|
|
58
|
+
- If `target_ref` is set (an explicit ref the user stated verbatim, highest priority): use it directly as `{analysis_ref}`, with no tag lookup.
|
|
59
|
+
- If `target_version` is set: resolve it to a tag with `{validatePinsHelper}` (resolve it from `{validatePinsProbeOrder}`; first existing path wins), which tries every form a tag writes a version in and prints one JSON line:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
uv run {validatePinsHelper} --repo-url "https://github.com/{owner}/{repo}" --pin "{target_version}" --format tag
|
|
63
|
+
```
|
|
37
64
|
|
|
38
|
-
-
|
|
39
|
-
- `
|
|
40
|
-
- `
|
|
41
|
-
-
|
|
65
|
+
- Exit 0: set `{analysis_ref}` to its `resolved_ref`.
|
|
66
|
+
- Exit 1 (`status: "invalid"`) with tags in `suggestions`: no tag matches. Warn `"No git tag matches version {target_version}; analyzing the default branch (HEAD) instead: structure and exports may not match the pinned version."`, naming those nearest tags.
|
|
67
|
+
- Exit 1 with an empty `suggestions`: the repository has no tag, or its tags could not be listed. Warn `"Could not find or list the tags of {owner}/{repo}; analyzing the default branch (HEAD) instead: structure and exports may not match the pinned version."`
|
|
68
|
+
- Exit 2 (`gh` missing, or a URL it does not accept), or no candidate path: warn `"Could not check the tags of {owner}/{repo} ({the error it printed}); analyzing the default branch (HEAD) instead: structure and exports may not match the pinned version."`
|
|
69
|
+
- On any of these warnings, add it to `workflow_warnings[]`, set `{analysis_ref}` = `HEAD`, and record the fallback in the §5 analysis summary.
|
|
42
70
|
|
|
43
|
-
**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
71
|
+
**List the repository.** Resolve `{githubProbeHelper}` from `{githubProbeProbeOrder}`; first existing path wins. Write its listing to the run folder in one call:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
uv run {githubProbeHelper} tree --repo "{owner}/{repo}" --ref "{analysis_ref}" --out "{run_dir}/tree.json"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`--out` writes the listing to `{run_dir}/tree.json`, where the helpers read it, and the call prints the rest as one JSON line: `status`, `cause`, `message`, `gh`, `count` and `truncated`. Branch on that line. Every branch below that halts emits its halt envelope first, per the SKILL.md Halt Contract:
|
|
78
|
+
|
|
79
|
+
- **`status: "unavailable"`** (exit 3): the repository or the ref cannot be read, and `message` names the cause and the fix.
|
|
80
|
+
- `cause` `gh-missing` or `gh-unauthenticated`: emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "gh-auth-failed"`, then HALT (exit code 3): "**Error:** {message}"
|
|
81
|
+
- `cause` `repo-not-found`, `no-access` or `ref-not-found` (or `unreachable`, `invalid-repo`): emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "target-inaccessible"`, then HALT (exit code 3): "**Error:** {message}"
|
|
82
|
+
- **No candidate path, or no JSON** (the helper exits 1 or 2): emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "target-inaccessible"`, then HALT (exit code 3): "**Error:** Cannot list `{url}`: {the first line of its stderr, or `skf-github-probe.py not found`}."
|
|
83
|
+
|
|
84
|
+
**Fetching files.** Every file this step and step 3 read from a GitHub source is fetched into `{run_dir}/files` at `{analysis_ref}`, laid out like the repository, by `{githubFetchHelper}` (resolve it from `{githubFetchProbeOrder}`; first existing path wins; HALT if no candidate exists), which §4.1's `--follow` runs too. It reads each file from `raw.githubusercontent.com`, which needs no `gh`, and through `gh` only when that fails (a private repository). A path the listing does not hold costs no request and is reported in `unmatched`, so each call names every candidate. On exit 3, its `failed` names each file it could not read: go on without them, and add `files not fetched: <their paths>` to `workflow_warnings[]`.
|
|
85
|
+
|
|
86
|
+
**Truncation.** When `truncated` is true, GitHub cut the listing short:
|
|
87
|
+
- Display: "Note: GitHub returned a truncated tree ({count} files). Full analysis may require a local clone." and add `tree listing truncated by GitHub ({count} files listed)` to `workflow_warnings[]`.
|
|
88
|
+
- Interactive: present
|
|
47
89
|
```
|
|
48
90
|
Tree is truncated. How would you like to proceed?
|
|
49
91
|
[L] Clone locally and re-analyze (slower but complete)
|
|
50
92
|
[P] Proceed with the partial tree (faster, may miss exports under deeper paths)
|
|
51
93
|
```
|
|
52
|
-
On `[L]`: shallow-clone
|
|
94
|
+
On `[L]`: shallow-clone the repository into the run folder at `{analysis_ref}`:
|
|
53
95
|
|
|
54
|
-
|
|
96
|
+
```bash
|
|
97
|
+
git clone --depth 1 --branch "{analysis_ref}" "https://github.com/{owner}/{repo}.git" "{run_dir}/clone"
|
|
98
|
+
```
|
|
55
99
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
- If `gh auth status` reports authenticated but the call still failed (404/403): emit the error envelope per **step 5 §4b** with `halt_reason: "target-inaccessible"`, then HALT (exit code 3, `halt_reason: "target-inaccessible"`) — "**Error:** Cannot access repository at `{url}`. The CLI is authenticated but the API returned `{status}`. Check the URL and that the account has access to private repositories if applicable."
|
|
59
|
-
- If `gh auth status` itself fails to run (binary missing): emit the error envelope per **step 5 §4b** with `halt_reason: "gh-auth-failed"`, then HALT (exit code 3, `halt_reason: "gh-auth-failed"`) — "**Error:** `gh` CLI not found on PATH. Install it from <https://cli.github.com> and re-run."
|
|
100
|
+
Leave `--branch` out when `{analysis_ref}` is `HEAD`. A commit SHA is no `--branch` value: clone it with `git clone --filter=blob:none --no-checkout "https://github.com/{owner}/{repo}.git" "{run_dir}/clone"`, then `git -C "{run_dir}/clone" checkout --quiet "{analysis_ref}"`. Set `{source_path}` ← `{run_dir}/clone` and restart this section for that local path: its listing replaces `{run_dir}/tree.json`, and every later `{source_path}`, in this step and in step 3, is the clone. Before any later HALT, remove the clone (`rm -rf "{run_dir}/clone"`): a halt keeps the files the run staged, never a copy of the repository. If a clone or checkout command fails, remove what it left (`rm -rf "{run_dir}/clone"`), warn `"Could not clone {owner}/{repo} at {analysis_ref} ({the first line of its stderr}); proceeding with the partial tree."`, add the warning to `workflow_warnings[]` and continue as `[P]`.
|
|
101
|
+
**GATE [default: P]**: on `[P]`, and under headless: record `tree_truncated: true` in the analysis summary and continue without HALT.
|
|
60
102
|
|
|
61
|
-
**For local paths:**
|
|
62
|
-
-
|
|
63
|
-
- List the
|
|
64
|
-
- If the path does not exist: HALT (exit code 3, `halt_reason: "target-inaccessible"`) — "**Error:** Directory not found at {path}. Verify the path is correct." In headless mode, emit the error envelope per **step 5 §4b** with `halt_reason: "target-inaccessible"` before the HALT (pass the resolved `{skill_name}`, or the `"unknown"` placeholder documented in §4b if it is not yet set), matching the GitHub-target failure branches above so a missing local path surfaces the same `SKF_BRIEF_RESULT_JSON` failure class.
|
|
103
|
+
**For local paths:** `{source_path}` is the path.
|
|
104
|
+
- If the directory does not exist (`test -d "{source_path}"` fails): emit the halt envelope first, `uv run {emitBriefEnvelopeHelper} emit --target stderr` with `halt_reason: "target-inaccessible"` (the failure class of a GitHub target the CLI cannot read), then HALT (exit code 3): "**Error:** Directory not found at {path}. Verify the path is correct."
|
|
105
|
+
- List its files into the run folder, the files git tracks and the untracked ones it does not ignore:
|
|
65
106
|
|
|
66
|
-
|
|
107
|
+
```bash
|
|
108
|
+
git -C "{source_path}" -c core.quotePath=false ls-files --cached --others --exclude-standard -- . ':(exclude,glob)**/.skf-run/**' > "{run_dir}/tree.json"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Outside a git work tree (the command fails): `(cd "{source_path}" && find . -type f -not -path './.git/*' -not -path '*/node_modules/*' -not -path '*/.skf-run/*') > "{run_dir}/tree.json"`. Both leave out SKF's run folders (`.skf-run`), which a listing of the project root would otherwise hold.
|
|
67
112
|
|
|
68
113
|
### 1b. Detect Monorepo / Workspace Layout
|
|
69
114
|
|
|
70
115
|
**Resolve `{detectWorkspacesHelper}`** from `{detectWorkspacesProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
71
116
|
|
|
72
|
-
Delegate workspace detection to `{detectWorkspacesHelper}`
|
|
117
|
+
Delegate workspace detection to `{detectWorkspacesHelper}`: it reads the file list from `{run_dir}/tree.json` and the root manifests from a folder laid out like the repository. For a GitHub source, `--manifest-files` lists the root manifests the detectors read that the listing holds (`rush.json` among them; Nx needs only the tree), the fetch writes them into `{run_dir}/files`, and the last line runs the detection:
|
|
73
118
|
|
|
74
119
|
```bash
|
|
75
|
-
|
|
76
|
-
|
|
120
|
+
uv run {detectWorkspacesHelper} --tree-file "{run_dir}/tree.json" --manifest-files > "{run_dir}/manifests.txt"
|
|
121
|
+
uv run {githubFetchHelper} --repo "{owner}/{repo}" --ref "{analysis_ref}" --tree-file "{run_dir}/tree.json" --dest "{run_dir}/files" --patterns-file "{run_dir}/manifests.txt"
|
|
122
|
+
uv run {detectWorkspacesHelper} --tree-file "{run_dir}/tree.json" --manifest-dir "{run_dir}/files"
|
|
77
123
|
```
|
|
78
124
|
|
|
79
|
-
|
|
80
|
-
- **`manifests`** — only the root manifests need contents; child-workspace manifests are looked up from the tree by the script. Include any of `package.json`, `Cargo.toml`, `pnpm-workspace.yaml`, `lerna.json` that appears at the repo root. Fetch them in **one message with N parallel Bash calls** (`gh api .../contents/{path}?ref={analysis_ref}` for GitHub, file reads for local), then base64-decode together. Per-workspace manifest contents (e.g. `packages/foo/package.json`) are optional — including them populates the workspace `name` field with the manifest's declared package name; omitting them falls back to the directory basename.
|
|
125
|
+
For a local source (or the `[L]` clone), drop the first two lines and pass the folder itself: `--manifest-dir "{source_path}"`. The manifest folder of this section is the one §2 and §4 pass again.
|
|
81
126
|
|
|
82
127
|
The script returns a JSON envelope: `{is_monorepo, manifest_kind, workspaces[], warnings[]}`. Apply the result deterministically — see `src/shared/scripts/schemas/workspace-detection.v1.json` for the full contract.
|
|
83
128
|
|
|
@@ -95,47 +140,39 @@ Which one should the skill cover? Pick a number, or type 'all' to scope at the r
|
|
|
95
140
|
|
|
96
141
|
Interactive: wait for the user choice. On a numbered choice, store `monorepo_workspace: {path}` and rebase §2-§4b against that path. On `'all'`, leave `monorepo_workspace` unset and proceed at the repo root with a note in the analysis summary that scope is unfiltered.
|
|
97
142
|
|
|
98
|
-
|
|
143
|
+
**GATE [default: the workspace an `include` glob names, else the repo root]**: headless, if the input contract supplied an `include` glob that begins with one of the workspace paths, auto-select that workspace (log `"headless: auto-selected workspace {name} from include glob"`). Otherwise default to repo root and log `"warn: monorepo detected ({manifest_kind}) but no workspace pre-selected; analyzing at repo root"`.
|
|
99
144
|
|
|
100
|
-
|
|
145
|
+
Log each non-empty `warnings[]` entry from the script and add it to `workflow_warnings[]`, so a malformed or unfetched root manifest is debuggable; the workflow does not HALT, because falling back to repo-root analysis is always safe.
|
|
101
146
|
|
|
102
147
|
**`cross-ecosystem workspace ignored` warning:** when a root workspace manifest from a different language ecosystem co-exists with the surfaced one (e.g. a root `Cargo.toml [workspace]` alongside a pnpm workspace), the script surfaces only the higher-priority kind and emits this warning naming the ignored kind and its member count. The ignored ecosystem's workspaces are **not** in `workspaces[]`, so the numbered menu above will not list them. When this warning is present, tell the operator both ecosystems exist and ask which the skill should cover; if they pick the ignored ecosystem, scope §2-§4b at its root (or the relevant member) rather than the surfaced workspace, and carry the ignored kind into §3 (see the `workspace_signal` note there).
|
|
103
148
|
|
|
104
149
|
### 2. Read Repository Structure
|
|
105
150
|
|
|
106
|
-
|
|
151
|
+
Display `Reading the repository structure...`, then take the structure from the tree snapshot `{detectWorkspacesHelper}` computes, never from a count of the listing by hand. Add `--root "{monorepo_workspace}"` when §1b picked a workspace:
|
|
107
152
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
{repo-name}/
|
|
111
|
-
├── {top-level files}
|
|
112
|
-
├── {top-level directories}/
|
|
113
|
-
│ └── ...
|
|
114
|
-
└── ...
|
|
153
|
+
```bash
|
|
154
|
+
uv run {detectWorkspacesHelper} --tree-file "{run_dir}/tree.json" --manifest-dir "<§1b's manifest folder>" --snapshot > "{run_dir}/snapshot.json"
|
|
115
155
|
```
|
|
116
|
-
|
|
156
|
+
|
|
157
|
+
It holds `file_count`, `source_file_count`, `dir_count`, `top_level_files`, `top_level_dirs`, `truncated` (the counts are then lower bounds), the `workspaces` detection found, and the module candidates §4.3 picks from.
|
|
117
158
|
|
|
118
159
|
### 3. Detect Primary Language
|
|
119
160
|
|
|
120
|
-
**Resolve `{detectLanguageHelper}`** from `{detectLanguageProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
161
|
+
Display `Detecting the language...`. **Resolve `{detectLanguageHelper}`** from `{detectLanguageProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
121
162
|
|
|
122
163
|
Delegate the rule walk to `{detectLanguageHelper}` instead of evaluating manifest presence and extension frequency in prose:
|
|
123
164
|
|
|
124
165
|
```bash
|
|
125
|
-
|
|
166
|
+
uv run {detectLanguageHelper} --tree-file "{run_dir}/tree.json" [--workspace-signal "<§1b manifest_kind>"]
|
|
126
167
|
```
|
|
127
168
|
|
|
128
|
-
Pass the §1b `manifest_kind` as `
|
|
129
|
-
|
|
130
|
-
**When §1b surfaced a `cross-ecosystem workspace ignored` warning and the operator chose the ignored ecosystem:** pass that ignored kind as `workspace_signal` (not the surfaced kind), so a co-located `cargo-workspace`/`python-multi-package` root resolves to rust/python instead of being pinned to the surfaced ecosystem's language by the workspace that won detection priority.
|
|
169
|
+
Pass the §1b `manifest_kind` as `--workspace-signal` (leave the flag out when it is `null` / not a monorepo). This gives the workspace root precedence: for a `cargo-workspace` or `python-multi-package` root, the script returns the root language (rust/python) instead of being misled into `typescript` by a nested `package.json` + `tsconfig.json` in a non-workspace subdirectory (e.g. a `docs/` or `website/` site). JS-family workspace kinds (`npm-workspaces`/`pnpm-workspaces`/`lerna`/`rush`/`nx`) carry no override: their root `package.json` resolves js/ts normally.
|
|
131
170
|
|
|
132
|
-
|
|
171
|
+
**When §1b surfaced a `cross-ecosystem workspace ignored` warning and the operator chose the ignored ecosystem:** pass that ignored kind as `--workspace-signal` (not the surfaced kind), so a co-located `cargo-workspace`/`python-multi-package` root resolves to rust/python instead of being pinned to the surfaced ecosystem's language by the workspace that won detection priority.
|
|
133
172
|
|
|
134
|
-
|
|
135
|
-
**Confidence:** {confidence}
|
|
136
|
-
**Detection source:** {detection_source}"
|
|
173
|
+
The script returns `{language, confidence, detection_source, fallback_to_extension_frequency, source_language, detected_languages}` after walking the documented rule table: the `workspace_signal` precedence above first, then the manifests nearest the tree's root, by folder depth and then rule order (package.json with tsconfig.json disambiguation, Cargo.toml, pyproject.toml/setup.py/setup.cfg, go.mod, pom.xml, build.gradle.kts, Package.swift, Gemfile, build.gradle Groovy with Java/Kotlin disambiguation, *.csproj/*.sln), where a manifest in a docs, examples, tests or other non-core folder, or in a hidden one, decides only when no other exists, then extension-frequency fallback. With no manifest at the root, the nearest one decides at `medium` confidence and `source_language` names the language most source files are in. Use the returned values directly: §5 shows them.
|
|
137
174
|
|
|
138
|
-
**Headless language override.** If `language_hint` was supplied as a headless argument, use it as the confirmed `{language}` (overriding the detected value) and carry it forward to §4 and step 03. The detector still runs so
|
|
175
|
+
**Headless language override.** If `language_hint` was supplied as a headless argument, use it as the confirmed `{language}` (overriding the detected value) and carry it forward to §4 and step 03. The detector still runs so §5's Detected-language line reflects what the source signals, but the explicit hint wins and the step 03 §4 low-confidence override does not fire. When `language_hint` is absent, carry the detected `{language}` forward.
|
|
139
176
|
|
|
140
177
|
If `confidence` is `low` (or `unknown` is returned for `language`) and no `language_hint` was supplied: flag for user override in step 03 §4.
|
|
141
178
|
|
|
@@ -143,61 +180,52 @@ If `confidence` is `low` (or `unknown` is returned for `language`) and no `langu
|
|
|
143
180
|
|
|
144
181
|
**Resolve `{extractPublicApiHelper}`** from `{extractPublicApiProbeOrder}`; first existing path wins. HALT if no candidate exists.
|
|
145
182
|
|
|
146
|
-
Identify the public API surface. **Delegate the parsing to `{extractPublicApiHelper}` whenever the detected language is supported
|
|
183
|
+
Identify the public API surface. **Delegate the parsing to `{extractPublicApiHelper}` whenever the detected language is supported:** it finds the entry files, parses the manifest, reads the exports and finds the version, so none of them is derived in prose.
|
|
147
184
|
|
|
148
185
|
**Script-supported languages** (use the script): `js`, `ts`, `javascript`, `typescript`, `python`, `rust`, `go`, `java`, `kotlin`.
|
|
149
186
|
|
|
150
|
-
This section runs exactly one of §4.1 (script path) or §4.2 (fallback path) based on the detected language, then always
|
|
187
|
+
Display `Listing the exports...`. This section runs exactly one of §4.1 (script path) or §4.2 (fallback path) based on the detected language, then always §4.3 (the modules and exports §5 shows) and conditionally §4.4 (semantic signals).
|
|
151
188
|
|
|
152
189
|
#### 4.1 Procedure — script-supported languages
|
|
153
190
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
| java | `pom.xml` | (manifest alone is sufficient for the modules listing) |
|
|
163
|
-
| kotlin | `build.gradle` / `build.gradle.kts` | (manifest alone) |
|
|
164
|
-
|
|
165
|
-
2. Build a JSON payload matching the script contract:
|
|
166
|
-
|
|
167
|
-
```json
|
|
168
|
-
{
|
|
169
|
-
"language": "<one of the supported values>",
|
|
170
|
-
"manifest": {"path": "<relative path>", "content": "<file contents>"},
|
|
171
|
-
"entries": [{"path": "<relative path>", "content": "<file contents>"}, ...],
|
|
172
|
-
"mode": "quick"
|
|
173
|
-
}
|
|
191
|
+
`<source root>` is `{run_dir}/files` for a GitHub source. For a local source, or the `[L]` clone, it is `{source_path}`, whose files need no fetch: leave the `{githubFetchHelper}` lines and step 2's `--repo` and `--ref` out. When §1b picked a workspace, prefix each manifest candidate with `{monorepo_workspace}/` and pass `--scope "{monorepo_workspace}"`.
|
|
192
|
+
|
|
193
|
+
1. **Find the entry files.** Fetch the manifest candidates (the listing decides which exist), let the extractor find the entry files in the listing by full mode's rules, and fetch the files it lists:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
uv run {githubFetchHelper} --repo "{owner}/{repo}" --ref "{analysis_ref}" --tree-file "{run_dir}/tree.json" --dest "{run_dir}/files" package.json pyproject.toml setup.py setup.cfg Cargo.toml go.mod pom.xml build.gradle.kts build.gradle
|
|
197
|
+
uv run {extractPublicApiHelper} --mode entries --language "<language>" --tree-file "{run_dir}/tree.json" --source-root "<source root>" [--scope "{monorepo_workspace}"] --fetch-list "{run_dir}/entries.txt" > "{run_dir}/entries.json"
|
|
198
|
+
uv run {githubFetchHelper} --repo "{owner}/{repo}" --ref "{analysis_ref}" --tree-file "{run_dir}/tree.json" --dest "{run_dir}/files" --patterns-file "{run_dir}/entries.txt"
|
|
174
199
|
```
|
|
175
200
|
|
|
176
|
-
|
|
201
|
+
`{run_dir}/entries.json` names the `manifest` the extractor read and its `entry_files`: never pick an entry file yourself. Its `unresolved` and `warnings` join the extraction warnings §5 shows. When the entries call exits non-zero, or it names neither a manifest nor an entry file, there is nothing to parse: skip the rest of §4.1 and take §4.2.
|
|
202
|
+
|
|
203
|
+
2. **Parse them and follow their re-exports** by path: the `manifest` (no `--manifest-file` when it is null) and one `--entry-file` per entry file (for a GitHub source, each one the fetch `fetched`):
|
|
177
204
|
|
|
178
205
|
```bash
|
|
179
|
-
|
|
206
|
+
uv run {extractPublicApiHelper} --mode quick --language "<language>" --source-root "<source root>" --tree-file "{run_dir}/tree.json" --manifest-file "<manifest path>" --entry-file "<entry path>" --follow --resolve-version [--repo "{owner}/{repo}" --ref "{analysis_ref}"] > "{run_dir}/extract.json"
|
|
180
207
|
```
|
|
181
208
|
|
|
182
|
-
|
|
209
|
+
`--follow` reads each module an `export *` or a star import passes names on from, round after round, so a chain is read to its end, and lists them in `followed`; for a GitHub source, `--repo` and `--ref` fetch each into `{run_dir}/files` first. A module it could not read stays in `unlisted[]`, and a warning names it. `--resolve-version` looks up a version the manifest does not state.
|
|
183
210
|
|
|
184
|
-
|
|
211
|
+
3. On a non-zero exit of the extractor (codes 1 or 2 per its docstring), log its stderr and fall through to §4.2 (the prose-fallback path), which writes over `{run_dir}/extract.json`: never HALT just because the script choked on an unusual manifest.
|
|
185
212
|
|
|
186
|
-
|
|
213
|
+
4. Keep `{run_dir}/extract.json`'s `package_name`, `exports` (each entry's `name`/`type`/`source_file`), `dependencies` and `warnings` for §5, which shows the package, its dependency count, the exports and the warnings. Its `version` feeds §4b, and step 3 counts its exports.
|
|
187
214
|
|
|
188
215
|
#### 4.2 Procedure — fallback (not script-supported)
|
|
189
216
|
|
|
190
217
|
Languages outside the script coverage (Ruby / C# / Swift / etc.) take this path. The §4.1 fall-through on script error also lands here.
|
|
191
218
|
|
|
192
|
-
Fall back to ad-hoc inspection
|
|
219
|
+
Fall back to ad-hoc inspection of `Gemfile` / `*.csproj` / `*.sln` / `Package.swift` / file extension frequency. Read the files you inspect from `{run_dir}/files` (fetched with §4.1's fetch line, naming them) or the local folder. Note any obvious entry points, and flag the limitation in the analysis summary so the user knows scoping is on coarser signals. Then stage an extraction with no export, so step 3 reads `{run_dir}/extract.json` on either path: `printf '{"exports": []}' > "{run_dir}/extract.json"`.
|
|
193
220
|
|
|
194
221
|
#### 4.3 Output format (both paths)
|
|
195
222
|
|
|
196
|
-
|
|
197
|
-
|
|
223
|
+
Display `Picking the top-level modules...`. The snapshot lists candidates and names no module on purpose: a folder-name rule misreads `LICENSES`, `ci`, `web` or lodash's `lib/`. **Pick the Top-Level Modules from `{run_dir}/snapshot.json`** (Maven and Gradle aside: there the §4.1 script's `modules` array is the list):
|
|
224
|
+
- The snapshot's `workspaces`, when it lists some.
|
|
225
|
+
- Else the `module_candidates` that hold the library's own code: not a folder with no source file (`source_file_count` 0), nor one of tests, docs, examples, scripts, build tooling or CI.
|
|
226
|
+
- When one candidate holds most of the source files, it is the package itself (`pandas/` at the root of pandas): run the snapshot again for that folder, `uv run {detectWorkspacesHelper} --tree-file "{run_dir}/tree.json" --snapshot --root "<that folder>" > "{run_dir}/package-snapshot.json"`, and pick among its candidates.
|
|
198
227
|
|
|
199
|
-
|
|
200
|
-
{numbered list of public-facing items found — from script output when available, ad-hoc inspection otherwise}"
|
|
228
|
+
The number of modules picked is `module_count`, which step 3 §2c passes the scope-type recommender (0 when none qualifies). Give each picked module a one-line description. The exports are the §4.1 script's `exports`, or the entry points §4.2 found.
|
|
201
229
|
|
|
202
230
|
#### 4.4 Semantic Signals (Forge+/Deep with ccc only)
|
|
203
231
|
|
|
@@ -217,56 +245,60 @@ If results are returned, display:
|
|
|
217
245
|
"**Semantic Signals (ccc):**
|
|
218
246
|
{numbered list of file:snippet pairs from CCC results — top 5 most relevant}"
|
|
219
247
|
|
|
220
|
-
This supplements
|
|
248
|
+
This supplements, and never replaces, the module list §4.3 picked. CCC may surface non-obvious entry points (dynamically constructed exports, re-export chains) that static directory analysis misses.
|
|
221
249
|
|
|
222
250
|
If CCC is unavailable or returns no results: skip this subsection silently.
|
|
223
251
|
|
|
224
252
|
### 4b. Detect Source Version
|
|
225
253
|
|
|
226
|
-
**When
|
|
227
|
-
|
|
228
|
-
**When the language was not script-supported:** load `{versionResolutionFile}` and follow the prose Detection Algorithm directly (Ruby / C# / Swift / etc. fall outside the script's coverage).
|
|
229
|
-
|
|
230
|
-
Surface the result regardless of which path produced it:
|
|
231
|
-
|
|
232
|
-
**If `target_version` was provided in step 01:**
|
|
233
|
-
- Display: "**Target version:** {target_version} (user-specified)"
|
|
254
|
+
**When §4.1 ran:** `{run_dir}/extract.json`'s `version` is the detected version, null when the extractor found none. Do not derive it again or load `{versionResolutionFile}`.
|
|
234
255
|
|
|
235
|
-
|
|
256
|
+
**When §4.2 ran:** load `{versionResolutionFile}` and run its Detection Algorithm.
|
|
236
257
|
|
|
237
|
-
|
|
238
|
-
"**Note:** Detected version ({detected_version}) differs from your target version ({target_version}). Using target version (per `references/version-resolution.md` precedence rules)."
|
|
239
|
-
|
|
240
|
-
If detection fails or returns a non-semver value: note that version will default to `"1.0.0"` and the user can override in step 04. The actual write happens in step 05.
|
|
258
|
+
Whichever path produced it, keep the detected version for §5, which shows it beside `target_version`. The actual write happens in step 05.
|
|
241
259
|
|
|
242
260
|
### 5. Report Analysis Summary
|
|
243
261
|
|
|
244
|
-
Present the complete analysis
|
|
262
|
+
Present the complete analysis, the counts and notable files read from `{run_dir}/snapshot.json`:
|
|
245
263
|
|
|
246
264
|
"**Analysis Complete**
|
|
247
265
|
|
|
248
266
|
---
|
|
249
267
|
|
|
250
268
|
**Target:** {repo URL or path}
|
|
251
|
-
|
|
252
|
-
**
|
|
269
|
+
{If §4.1 returned a `package_name`:}
|
|
270
|
+
**Package:** {package_name} ({the number of its `dependencies`} dependencies)
|
|
271
|
+
**Detected language:** {the detector's language} ({confidence}, {detection_source})
|
|
272
|
+
{If a `language_hint` or a ratified brief set the language:}
|
|
273
|
+
**Language:** {language} (kept over the detected one)
|
|
274
|
+
**Structure:** {file_count} files ({source_file_count} source files) across {dir_count} directories
|
|
253
275
|
|
|
254
|
-
**Key Modules ({
|
|
255
|
-
{bulleted list of modules}
|
|
276
|
+
**Key Modules ({module_count}):**
|
|
277
|
+
{bulleted list of the §4.3 modules, each with its one-line description}
|
|
256
278
|
|
|
257
279
|
**Public Exports/Entry Points ({count}):**
|
|
258
|
-
{bulleted list of exports}
|
|
280
|
+
{bulleted list of the §4.3 exports}
|
|
281
|
+
|
|
282
|
+
**Version:** {on a ratify run, the hydrated `version`; otherwise:}
|
|
283
|
+
- Detected version: {the §4b version, or `not detected: defaulting to 1.0.0, which you can change when you confirm the brief` when detection failed or returned a non-semver value}
|
|
284
|
+
{If `target_version` was provided in step 01:}
|
|
285
|
+
- Target version: {target_version} (user-specified)
|
|
286
|
+
{If `target_version` was provided AND the detected version differs:}
|
|
287
|
+
- Note: the detected version ({detected_version}) differs from your target version ({target_version}). Using target version (per `references/version-resolution.md` precedence rules).
|
|
288
|
+
|
|
289
|
+
{If §4.1 returned `warnings`:}
|
|
290
|
+
**Extraction warnings:**
|
|
291
|
+
{one bullet per warning}
|
|
259
292
|
|
|
260
293
|
**Notable Files:**
|
|
261
|
-
- README: {
|
|
262
|
-
- Tests: {
|
|
263
|
-
- Docs: {
|
|
264
|
-
- Config: {
|
|
265
|
-
- Version: {detected version or "Not detected — defaulting to 1.0.0"}
|
|
294
|
+
- README: {a README file in `top_level_files`, or not found}
|
|
295
|
+
- Tests: {a tests folder in `top_level_dirs` (`test`, `tests`, `__tests__`, `spec`), or not found}
|
|
296
|
+
- Docs: {a docs folder in `top_level_dirs` (`docs`, `doc`, `documentation`), or not found}
|
|
297
|
+
- Config: {the configuration files in `top_level_files`}
|
|
266
298
|
{If the target was a GitHub URL:}
|
|
267
299
|
- Analysis ref: {analysis_ref} {append " (resolved from target_version {target_version})" when a tag was matched, or " (no tag matched {target_version} — analyzed default branch)" on the zero-match fallback}
|
|
268
300
|
|
|
269
|
-
Store `{analysis_ref}` in workflow context
|
|
301
|
+
Store `{analysis_ref}` and `module_count` in workflow context: step 03 (`scope-definition.md`) reuses them, with `{run_dir}/tree.json`, the fetched files and `{run_dir}/extract.json`, so scope analysis reads the same ref as this step.
|
|
270
302
|
|
|
271
303
|
---
|
|
272
304
|
|
|
@@ -275,21 +307,6 @@ Store `{analysis_ref}` in workflow context — step 03 (`scope-definition.md`) r
|
|
|
275
307
|
|
|
276
308
|
Moving to scope definition where you'll choose what to include and exclude."
|
|
277
309
|
|
|
278
|
-
### 6.
|
|
279
|
-
|
|
280
|
-
Display: "**Proceeding to scope definition...**
|
|
281
|
-
|
|
282
|
-
Review the analysis above. If anything looks wrong, let me know now — otherwise I'll proceed to scope definition."
|
|
283
|
-
|
|
284
|
-
Pause briefly for user input. If the user provides corrections or asks questions, address them and re-present any updated analysis findings. Then proceed.
|
|
285
|
-
|
|
286
|
-
#### Menu Handling Logic:
|
|
287
|
-
|
|
288
|
-
- After analysis report is presented to user and any corrections addressed, load, read entire file, then execute {nextStepFile}
|
|
289
|
-
|
|
290
|
-
#### Execution rules:
|
|
291
|
-
|
|
292
|
-
- This is a soft auto-proceed step — present the pause prompt, wait briefly for user input
|
|
293
|
-
- If user provides corrections: address them, then proceed
|
|
294
|
-
- If no user input after a brief pause: proceed directly to step 03
|
|
310
|
+
### 6. Proceed to Scope Definition
|
|
295
311
|
|
|
312
|
+
In the same turn as the §5 summary, load, read entire file, then execute {nextStepFile}: step 3 §1 asks whether anything in this analysis is wrong, and applies a correction before a scope decision relies on it.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'write-brief.md'
|
|
3
3
|
reviseStepFile: 'scope-definition.md'
|
|
4
|
+
analyzeStepFile: 'analyze-target.md'
|
|
4
5
|
advancedElicitationSkill: '/bmad-advanced-elicitation'
|
|
5
6
|
partyModeSkill: '/bmad-party-mode'
|
|
6
7
|
---
|
|
@@ -17,9 +18,11 @@ partyModeSkill: '/bmad-party-mode'
|
|
|
17
18
|
|
|
18
19
|
### 1. Assemble Complete Brief
|
|
19
20
|
|
|
20
|
-
Use the values already accepted in steps 01-03 directly
|
|
21
|
+
Use the values already accepted in steps 01-03 directly: do not load `assets/skill-brief-schema.md` here. The 18 fields below are all in conversation; the schema is only consulted in §4 if an inline adjustment needs a specific field's validation rule cited.
|
|
21
22
|
|
|
22
|
-
**Ratify run (`ratify_mode: true`):** steps 2-3 were skipped (
|
|
23
|
+
**Ratify run (`ratify_mode: true`):** steps 2-3 were skipped (step 1 ratified a brief through `references/gather-intent-ratify.md`: a brief path at the first prompt, or a headless `from_brief`), so there is no fresh steps 01-03 output to compile. Use the brief context variables **hydrated from the parsed brief** at step 1 in place of that output: the hydrated variable names match the field references below one-for-one. `detected_version` is absent on this path; rely on the hydrated `version` (step 5 writes from the ratified file, which keeps it).
|
|
24
|
+
|
|
25
|
+
After a `[R]` pass on a ratify run, take `scope.*`, `scripts_intent`, `assets_intent` and `doc_urls` from step 3, except `scope.amendments`, which step 3 never writes; every other field, `scope.amendments` included, stays hydrated.
|
|
23
26
|
|
|
24
27
|
Compile all gathered data from steps 01-03 into the complete brief:
|
|
25
28
|
|
|
@@ -57,6 +60,7 @@ Skill Brief: {name}
|
|
|
57
60
|
====================
|
|
58
61
|
|
|
59
62
|
Target: {source_repo}
|
|
63
|
+
Target ref: {target_ref; omit this line entirely when target_ref is unset}
|
|
60
64
|
Language: {language}
|
|
61
65
|
Forge Tier: {forge_tier} — {tier_gloss}
|
|
62
66
|
Description: {description}
|
|
@@ -104,7 +108,7 @@ Glosses (substitute the matching one-liner for `{tier_gloss}`, `{scripts_gloss}`
|
|
|
104
108
|
- `Deep`: full pipeline — AST + ccc + qmd portfolio search + LLM re-ranking
|
|
105
109
|
|
|
106
110
|
- **`scripts_intent` / `assets_intent` glosses** —
|
|
107
|
-
- `detect`: SKF will scan source for the standard `scripts/`/`bin/`/`tools/`/`cli/` (or `assets/`/`templates/`/`schemas/`/`configs/`) directories during create-skill and decide automatically
|
|
111
|
+
- `detect`: SKF will scan source for the standard `scripts/`/`bin/`/`tools/`/`cli/` (or `assets/`/`templates/`/`schemas/`/`configs/`) directories during create-skill and decide automatically (when one of the four script folders is a Python package, holding `__init__.py`, only its `__main__.py` and the modules with a shebang or a `__main__` block count as scripts)
|
|
108
112
|
- `none`: no script/asset packaging — create-skill will skip the detection pass
|
|
109
113
|
- free-text (anything else): a description of what to package; create-skill treats it as the user's spec
|
|
110
114
|
|
|
@@ -117,7 +121,7 @@ Flag any fields that may need review:
|
|
|
117
121
|
{If language was overridden or low confidence:}
|
|
118
122
|
"**Note:** Language was {auto-detected / manually overridden}."
|
|
119
123
|
|
|
120
|
-
"**Description:** synthesized
|
|
124
|
+
"**Description:** synthesized in step 1 and accepted there. This is the text agents read when deciding whether to route to your skill: refine it here if you want to tighten it now that the full brief is visible."
|
|
121
125
|
|
|
122
126
|
{If forge tier was defaulted:}
|
|
123
127
|
"**Note:** Forge tier defaulted to Quick (no forge-tier.yaml found)."
|
|
@@ -138,7 +142,7 @@ You can:
|
|
|
138
142
|
### 4. Handle Inline Adjustments
|
|
139
143
|
|
|
140
144
|
If the user requests changes to specific fields (name, description, version, etc.):
|
|
141
|
-
- If the adjustment requires explaining a field's validation rule or allowed values, load `
|
|
145
|
+
- If the adjustment requires explaining a field's validation rule or allowed values, load `assets/skill-brief-schema.md` now (otherwise skip the read: the common path does not need it)
|
|
142
146
|
- Make the adjustment
|
|
143
147
|
- Re-present the updated brief
|
|
144
148
|
- Return to the menu
|
|
@@ -149,16 +153,14 @@ Display: **Select an Option:** [R] Revise Scope [A] Advanced Elicitation [P] Par
|
|
|
149
153
|
|
|
150
154
|
#### Menu Handling Logic:
|
|
151
155
|
|
|
152
|
-
- IF R:
|
|
156
|
+
- IF R: When `ratify_mode` is true, `source_type` is not `docs-only` and `ratify_analyzed` is not set, load, read entire file, then execute {analyzeStepFile}, which chains to scope definition. Otherwise load, read entire file, then execute {reviseStepFile} to re-enter scope definition
|
|
153
157
|
- IF A: Invoke {advancedElicitationSkill}, and when finished redisplay the menu
|
|
154
158
|
- IF P: Invoke {partyModeSkill}, and when finished redisplay the menu
|
|
155
159
|
- IF C: Load, read entire file, then execute {nextStepFile}
|
|
156
|
-
- IF X: Treat as user-cancellation.
|
|
160
|
+
- IF X: Treat as user-cancellation. Remove the run folder (`case "{run_dir}" in "{project-root}/_bmad-output/.skf-run/skf-brief-skill-"*) rm -rf "{run_dir}" ;; esac`), display `"Cancelled: no brief was written."` and HALT (exit code 6, `halt_reason: "user-cancelled"`). Step 5 has not run, so no brief was written; a saved draft stays for a later resume. `[X]` is interactive-only; the headless GATE never reaches this branch.
|
|
157
161
|
- IF Any other comments or queries: help user respond, apply any field adjustments, re-present brief if changed, then [Redisplay Menu Options](#5-present-menu-options)
|
|
158
162
|
|
|
159
163
|
#### Execution rules:
|
|
160
164
|
|
|
161
165
|
- **GATE [default: C]** — If `{headless_mode}`: auto-proceed with [C] Confirm, log: "headless: auto-confirm brief"
|
|
162
|
-
- After other menu items execution, return to this menu
|
|
163
|
-
- User can chat, request field changes, or ask questions — always respond and then redisplay menu
|
|
164
166
|
|