bmad-module-skill-forge 2.1.0 → 3.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 +51 -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 +135 -18
- package/docs/verifying-a-skill.md +83 -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 +2 -2
- 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 +32 -12
- package/src/shared/references/description-guard-protocol.md +14 -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 +30 -14
- package/src/shared/scripts/skf-build-change-manifest.py +2203 -24
- 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 +694 -0
- package/src/shared/scripts/skf-comention-pairs.py +1333 -123
- package/src/shared/scripts/skf-compare-file-hashes.py +1 -1
- 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 +3 -2
- package/src/shared/scripts/skf-description-guard.py +117 -9
- package/src/shared/scripts/skf-detect-docs.py +892 -4
- 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 +1 -1
- package/src/shared/scripts/skf-detect-tools.py +215 -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 +4084 -85
- package/src/shared/scripts/skf-extraction-inventory.py +746 -0
- package/src/shared/scripts/skf-extraction-snapshot.py +539 -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 +444 -203
- package/src/shared/scripts/skf-github-fetch.py +365 -0
- package/src/shared/scripts/skf-github-probe.py +661 -0
- package/src/shared/scripts/skf-hash-content.py +166 -12
- package/src/shared/scripts/skf-language-corpora.py +1 -1
- package/src/shared/scripts/skf-load-provenance.py +159 -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 +1 -1
- 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 +161 -27
- package/src/shared/scripts/skf-promote-staged.py +430 -0
- package/src/shared/scripts/skf-provenance-gap-dispatch.py +39 -7
- 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 +128 -13
- 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 +670 -119
- package/src/shared/scripts/skf-tessl-review.py +706 -0
- package/src/shared/scripts/skf-update-active-symlink.py +5 -5
- 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 +4 -1
- 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 +2919 -54
- package/src/shared/scripts/skf-write-skill-brief.py +367 -19
- 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 +27 -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/init.md +148 -210
- package/src/skf-audit-skill/references/re-index.md +96 -108
- package/src/skf-audit-skill/references/report.md +96 -33
- package/src/skf-audit-skill/references/semantic-diff.md +27 -18
- 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 +75 -90
- package/src/skf-audit-skill/references/upstream-checkout.md +77 -0
- package/src/skf-audit-skill/scripts/render-drift-tables.py +685 -0
- package/src/skf-brief-skill/SKILL.md +36 -25
- package/src/skf-brief-skill/assets/description-voice-examples.md +1 -1
- package/src/skf-brief-skill/assets/scope-templates.md +17 -24
- package/src/skf-brief-skill/assets/skill-brief-schema.md +29 -15
- package/src/skf-brief-skill/customize.toml +48 -20
- package/src/skf-brief-skill/references/analyze-target.md +142 -125
- package/src/skf-brief-skill/references/confirm-brief.md +10 -8
- 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 +24 -80
- package/src/skf-brief-skill/references/step-auto-validate.md +20 -121
- package/src/skf-brief-skill/references/version-resolution.md +3 -2
- 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 +6 -5
- package/src/skf-create-skill/assets/skill-sections.md +17 -6
- package/src/skf-create-skill/customize.toml +20 -8
- package/src/skf-create-skill/references/authoritative-files-protocol.md +41 -42
- 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 +107 -29
- 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 +20 -0
- package/src/skf-create-skill/references/extract.md +200 -161
- package/src/skf-create-skill/references/extraction-patterns-by-hand.md +141 -0
- package/src/skf-create-skill/references/extraction-patterns-tracing.md +2 -2
- package/src/skf-create-skill/references/extraction-patterns.md +584 -196
- 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 +28 -59
- package/src/skf-create-skill/references/source-resolution-protocols.md +49 -155
- 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 +55 -18
- package/src/skf-create-skill/references/sub/ccc-discover.md +18 -7
- package/src/skf-create-skill/references/sub/fetch-docs.md +106 -57
- 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 +79 -146
- 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 +118 -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 -89
- package/src/skf-setup/references/detect-and-tier.md +58 -66
- 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 +217 -254
- 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 +163 -88
- 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 +162 -142
- package/src/skf-test-skill/references/score.md +80 -107
- package/src/skf-test-skill/references/scoring-rules.md +41 -155
- package/src/skf-test-skill/references/source-access-protocol.md +19 -92
- 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 +287 -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 +1381 -0
- package/src/skf-test-skill/scripts/hard-gate.py +203 -0
- package/src/skf-test-skill/scripts/load-coverage-inputs.py +760 -0
- package/src/skf-test-skill/scripts/locate-export-segments.py +835 -0
- package/src/skf-test-skill/scripts/reconcile-coverage.py +273 -79
- package/src/skf-test-skill/scripts/score-signatures.py +459 -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 +127 -52
- 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 +233 -222
- 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 +250 -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 +180 -47
- package/src/skf-update-skill/references/re-extract.md +53 -262
- package/src/skf-update-skill/references/report.md +100 -35
- package/src/skf-update-skill/references/write.md +331 -149
- package/src/skf-update-skill/scripts/skf-new-file-diff.py +29 -7
- 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 -645
- 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
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
nextStepFile: 'compile.md'
|
|
3
|
+
githubFetchProbeOrder:
|
|
4
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-github-fetch.py'
|
|
5
|
+
- '{project-root}/src/shared/scripts/skf-github-fetch.py'
|
|
6
|
+
skillsModuleProbeOrder:
|
|
7
|
+
- '{project-root}/_bmad/skf/shared/scripts/skf-skills-module.py'
|
|
8
|
+
- '{project-root}/src/shared/scripts/skf-skills-module.py'
|
|
3
9
|
publicApiExtractorProbeOrder:
|
|
4
10
|
- '{project-root}/_bmad/skf/shared/scripts/skf-extract-public-api.py'
|
|
5
11
|
- '{project-root}/src/shared/scripts/skf-extract-public-api.py'
|
|
@@ -18,16 +24,34 @@ To read the resolved GitHub repository source and extract the public API surface
|
|
|
18
24
|
- Best-effort extraction — completeness is not required; surface-level reading only, no AST
|
|
19
25
|
- Do not begin compilation or write output files
|
|
20
26
|
- If no exports found, use README content as fallback
|
|
27
|
+
- A HARD HALT prints, after its envelope, this step's `halt` event when `{headless_mode}` is true. Under `--batch` it ends only this target: then return to `references/batch-mode.md` §3, even when the halt reads as the end of the run (`references/halt-contract.md`).
|
|
21
28
|
|
|
22
29
|
## Steps
|
|
23
30
|
|
|
24
|
-
**
|
|
31
|
+
**Reading the repository.** Step 1 §4 wrote the repository's file listing, at the ref this step reads (`source_ref`, or the default branch when it is unset), to `{run_dir}/tree.json`. Every file this step reads is fetched from that listing into `{run_dir}/src/`, laid out as in the repository, and the helpers read it there by path: no file's text passes through a shell string, and none is read by web browsing, which gives a rendered page rather than the file's bytes. Resolve `{githubFetch}` from `{githubFetchProbeOrder}`; first existing path wins. If no candidate exists, HARD HALT with **exit code 3 (resolution-failure)**, in interactive mode too: "**Cannot read the files of `{owner}/{repo}`.** SKF's GitHub fetch helper (`skf-github-fetch.py`) is missing from `{project-root}/_bmad/skf/shared/scripts/`, so re-install SKF." Stage `{"phase": "quick-extract", "halt_reason": "resolution-failure", "reason": "Cannot read the files of {owner}/{repo}.", "skill_package": null, "details": {"cause": "github-fetch-missing"}}` as `{run_dir}/halt.json` and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`. No file is fetched by hand. One call fetches every file a step names:
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
```bash
|
|
34
|
+
uv run {githubFetch} --repo {owner}/{repo} --ref {source_ref or HEAD} --tree-file "{run_dir}/tree.json" --dest "{run_dir}/src" [--limit <n>] [--exclude <glob>]... <path or glob>...
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
It reads each file from `raw.githubusercontent.com` at the ref, which needs no gh, and through `gh api` when that fails (a private repository). A path or glob the listing does not hold is reported in `unmatched` and costs no request, so name every candidate a step lists and use the ones it `fetched`. When the listing is `truncated` (GitHub cut a very large tree short), a path with no `*` or `?` that the listing lacks is read anyway, one request, and stays in `unmatched` when it cannot be read. On `status` `partial` or `unavailable` (exit 3), `failed` names each file it could not read: go on without them and say so in §5.
|
|
38
|
+
|
|
39
|
+
### 1. Read the Listing and README
|
|
40
|
+
|
|
41
|
+
Clear the extraction files an earlier attempt of this step left first (§4.5 [R] and step 4's [S] run this step again under a new scope, and step 4 passes the files it finds), so no export, package name or version of the old scope reaches `metadata.json`:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
rm -f "{run_dir}"/extract*.json
|
|
45
|
+
```
|
|
27
46
|
|
|
28
|
-
|
|
47
|
+
Fetch the root `package.json` (the sniff below reads it; nothing is fetched when the listing has none), then sniff the listing, which §1.5 classifies from. Resolve `{skillsModuleHelper}` from `{skillsModuleProbeOrder}`; first existing path wins. If no candidate exists, HARD HALT with **exit code 3 (resolution-failure)**, in interactive mode too: "**Cannot classify `{owner}/{repo}`.** SKF's skills-module helper (`skf-skills-module.py`) is missing from `{project-root}/_bmad/skf/shared/scripts/`, so re-install SKF." Stage `{"phase": "quick-extract", "halt_reason": "resolution-failure", "reason": "Cannot classify {owner}/{repo}.", "skill_package": null, "details": {"cause": "skills-module-missing"}}` as `{run_dir}/halt.json` and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`. Otherwise run:
|
|
29
48
|
|
|
30
|
-
|
|
49
|
+
```bash
|
|
50
|
+
uv run {githubFetch} --repo {owner}/{repo} --ref {source_ref or HEAD} --tree-file "{run_dir}/tree.json" --dest "{run_dir}/src" package.json
|
|
51
|
+
uv run {skillsModuleHelper} sniff --tree-file "{run_dir}/tree.json" --package-json "{run_dir}/src/package.json" [--scope-hint "{scope_hint}"] --fetch-list "{run_dir}/skills-fetch.txt" > "{run_dir}/sniff.json"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Pass `--scope-hint` when `scope_hint` is set. Then fetch the README that `{run_dir}/sniff.json` names in `readme` with the same fetch call (`README.md`, or another root `README` file), and read it from `{run_dir}/src/`.
|
|
31
55
|
|
|
32
56
|
Extract:
|
|
33
57
|
- **Description:** What the package does (first paragraph or tagline)
|
|
@@ -35,20 +59,23 @@ Extract:
|
|
|
35
59
|
- **Usage patterns:** Code examples showing common usage
|
|
36
60
|
- **Installation:** Package manager install command (confirms package name)
|
|
37
61
|
|
|
38
|
-
If
|
|
62
|
+
If `readme` is null or the README could not be fetched, note and continue.
|
|
39
63
|
|
|
40
64
|
### 1.5. Repo-Shape Sniff
|
|
41
65
|
|
|
42
|
-
|
|
66
|
+
Quick-skill wraps a library: classify the repo shape before spending effort on extraction.
|
|
67
|
+
|
|
68
|
+
The signals are the README and `{run_dir}/sniff.json`, which `{skillsModuleHelper}` computed from the whole listing: `root_files` (the files at the repository root), `skills_module` with its `skills_root`, `module_root` and `skill_folders`, the `candidates` it weighed, `suggested_scope`, and `asset_dirs` with `asset_dir_count`. It applies the skills-module rules: a skill folder holds its own `SKILL.md`; a folder that directly holds `module.yaml` or `module-help.csv` (not a copy inside a skill folder) is a module root, whose skill folders sit at any depth below it; when `scope_hint` is set it is the only candidate; and a top-level folder of skill folders counts only when it is a module root or the root ships no code. Read its answer; do not re-derive it from the listing.
|
|
43
69
|
|
|
44
70
|
**Classify as one of:**
|
|
45
71
|
|
|
72
|
+
- **skills-module**: `skills_module` is true: the repository ships agent skills rather than code, in the skill folders of `skills_root`. Skill folders alone qualify (a plain Agent Skills package), and a `module-help.csv` adds menu codes. The shape is library-like: record `repo_shape: skills-module` and `skills_root` in the extraction inventory, proceed with no gate, and follow the skills-module branch of §2 and §3. A library with a manifest and one `skill/SKILL.md` stays a library: the helper gives it `skills_module: false`.
|
|
46
73
|
- **library** (default) — README has installation / usage / API content; manifest at root with publishable metadata. Proceed normally.
|
|
47
74
|
- **awesome-list** — README H1 contains "awesome" (case-insensitive) or `awesome-` is in the repo name; README body is dominated by curated bullet links of the form `- [name](url) — desc`; no manifest at root.
|
|
48
75
|
- **docs-site / website** — README is short (under ~50 non-empty lines) and primarily points elsewhere ("See https://… for docs"); root has no manifest, or only a docs-framework manifest (e.g. `docusaurus.config.js`, `astro.config.mjs`, `mkdocs.yml`).
|
|
49
76
|
- **examples-only / tutorial** — README explicitly labels the repo as examples or a tutorial ("Code examples for…", "Tutorial: …", "Learn X by building Y"); typically no published package; many small standalone files instead of a single API surface.
|
|
50
77
|
|
|
51
|
-
**If
|
|
78
|
+
**If an awesome-list, docs-site or examples-only shape is detected**, soft-warn and gate before continuing:
|
|
52
79
|
|
|
53
80
|
"**Heads up — `{repo_name}` looks like a `{shape}` repo, not a library.**
|
|
54
81
|
|
|
@@ -56,55 +83,89 @@ Quick-skill is designed to wrap a library's public API. The compiled SKILL.md wi
|
|
|
56
83
|
|
|
57
84
|
Select: [C] Continue anyway · [A] Abort"
|
|
58
85
|
|
|
59
|
-
- **IF C
|
|
60
|
-
- **IF A
|
|
86
|
+
- **IF C**: log "user accepted `{shape}` shape" and proceed to §2. Set `extraction_inventory.repo_shape` to the detected shape, `awesome-list`, `docs-site` or `examples-only`.
|
|
87
|
+
- **IF A**: HARD HALT with **exit code 3 (resolution-failure)**: "Aborted. `{shape}` repos are best wrapped manually with `/skf-create-skill` from a brief, not auto-extracted." Stage `{"phase": "quick-extract", "halt_reason": "resolution-failure", "reason": "Aborted: a {shape} repo, not a library.", "skill_package": null, "details": {"repo_shape": "{shape}"}}` as `{run_dir}/halt.json` and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"` (`references/halt-contract.md`).
|
|
61
88
|
|
|
62
|
-
**GATE [default: C]
|
|
89
|
+
**GATE [default: C]**: in headless mode, log "headless: detected `{shape}` repo, continuing anyway", set `extraction_inventory.repo_shape` as [C] does, record the decision (stage `{"gate": "quick-extract.repo-shape", "default_action": "C", "taken_action": "C", "reason": "headless: continued with a {shape} repo"}` as `{run_dir}/decision.json` and run `uv run {emitEnvelopeHelper} record --workflow skf-quick-skill --run-dir "{run_dir}" --decision < "{run_dir}/decision.json"`) and proceed.
|
|
63
90
|
|
|
64
91
|
### 2. Fetch Source Files
|
|
65
92
|
|
|
66
|
-
|
|
93
|
+
**Resolve `{publicApiExtractor}`** from `{publicApiExtractorProbeOrder}`; first existing path wins. If no candidate exists, HARD HALT with **exit code 3 (resolution-failure)**, in interactive mode too: "**Cannot read the public API of `{repo_name}`.** SKF's public-API extractor (`skf-extract-public-api.py`) is missing from `{project-root}/_bmad/skf/shared/scripts/`, so re-install SKF." Stage `{"phase": "quick-extract", "halt_reason": "resolution-failure", "reason": "Cannot read the public API of {repo_name}.", "skill_package": null, "details": {"cause": "public-api-extractor-missing"}}` as `{run_dir}/halt.json` and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`.
|
|
94
|
+
|
|
95
|
+
Fetch the manifest for the detected language with the fetch call above, naming every candidate its row lists (the listing decides which exist; §1 already fetched a root `package.json`):
|
|
96
|
+
|
|
97
|
+
| Language | Manifest |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| JavaScript / TypeScript | `package.json` |
|
|
100
|
+
| Python | `pyproject.toml`, `setup.py` or `setup.cfg` |
|
|
101
|
+
| Rust | `Cargo.toml` |
|
|
102
|
+
| Go | `go.mod` |
|
|
103
|
+
| Java (Maven) | `pom.xml` |
|
|
104
|
+
| Kotlin (Gradle) | `build.gradle.kts` or `build.gradle`; also fetch `settings.gradle` or `settings.gradle.kts` for `include(...)` entries when present |
|
|
105
|
+
|
|
106
|
+
Then, for a language of §3's list, the extractor finds the entry files in the listing from the manifest it reads; fetch the files it lists:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv run {publicApiExtractor} --mode entries --language <lang> --tree-file "{run_dir}/tree.json" --source-root "{run_dir}/src" [--scope "{scope_hint}"] --fetch-list "{run_dir}/entries.txt" > "{run_dir}/entries.json"
|
|
110
|
+
uv run {githubFetch} --repo {owner}/{repo} --ref {source_ref or HEAD} --tree-file "{run_dir}/tree.json" --dest "{run_dir}/src" --patterns-file "{run_dir}/entries.txt"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`<lang>` is §3's. `{run_dir}/entries.json` names the `manifest` the extractor read and its `entry_files`, §3's `--entry-file` list, and `unresolved` names what no listed file answered, which §5 reports. Never derive an entry file from the package name yourself. For a language outside §3's list, or when the entries call exits non-zero (1 for a language it does not know, 2 for an input error, its error line on stderr), take no entry file and skip the fetch: §3 reads the manifest alone, or, when §2 fetched none, stages its empty envelope with that error line in place of `no source file was fetched`.
|
|
114
|
+
|
|
115
|
+
**If `scope_hint` provided:** fetch the manifest under `{scope_hint}/` when the listing holds one, and pass `--scope "{scope_hint}"` to the entries call, so extraction reads the scoped folder instead of the repo root.
|
|
67
116
|
|
|
68
|
-
|
|
69
|
-
| --- | --- | --- |
|
|
70
|
-
| JavaScript / TypeScript | `package.json` | `index.{js,ts}`, `src/index.{ts,js}`, or the file pointed to by the `main` field |
|
|
71
|
-
| Python | `pyproject.toml` or `setup.py` | `__init__.py`, `src/{package}/__init__.py` |
|
|
72
|
-
| Rust | `Cargo.toml` | `src/lib.rs` |
|
|
73
|
-
| Go | `go.mod` | top-level `*.go` files (3–5 best-effort) |
|
|
74
|
-
| Java (Maven) | `pom.xml` | top-level `*.java` files under `src/main/java/<groupId-as-path>/` (3–5 best-effort) |
|
|
75
|
-
| Kotlin (Gradle) | `build.gradle.kts` or `build.gradle` | top-level `*.kt` files under `src/main/kotlin/` (3–5 best-effort); also fetch `settings.gradle[.kts]` for `include(...)` entries when present |
|
|
117
|
+
For multi-module Maven (`<modules>`) and multi-project Gradle (`include(...)`) builds, fetch the parent manifest first: §3's multi-module loop fetches the modules.
|
|
76
118
|
|
|
77
|
-
**
|
|
119
|
+
**Skills module** (`repo_shape: skills-module`): run no entries call and fetch no entry-point files. Fetch the manifest from the table when the root has one and §1 did not fetch it, and the files the sniff listed in `{run_dir}/skills-fetch.txt`, each skill folder's `SKILL.md` and then the `module-help.csv` directly in the skills root (`<skills root>/module-help.csv`) when the listing shows one:
|
|
78
120
|
|
|
79
|
-
|
|
121
|
+
```bash
|
|
122
|
+
uv run {githubFetch} --repo {owner}/{repo} --ref {source_ref or HEAD} --tree-file "{run_dir}/tree.json" --dest "{run_dir}/src" --patterns-file "{run_dir}/skills-fetch.txt"
|
|
123
|
+
```
|
|
80
124
|
|
|
81
125
|
### 3. Parse Manifest and Scan Exports
|
|
82
126
|
|
|
83
|
-
Run the shared extractor
|
|
127
|
+
Run the shared extractor on the files §2 staged. The helper does manifest parse + export scan in one invocation, reads each file from `{run_dir}/src/` by its repo-relative path, and writes a structured envelope ready to feed §4's inventory. No manifest or entry-point file is parsed in the prompt.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
uv run {publicApiExtractor} --mode quick --language <lang> --source-root "{run_dir}/src" --tree-file "{run_dir}/tree.json" --manifest-file <manifest path> --entry-file <entry path> [--entry-file <entry path>]... --follow --repo {owner}/{repo} --ref {source_ref or HEAD} > "{run_dir}/extract.json"
|
|
131
|
+
```
|
|
84
132
|
|
|
85
|
-
|
|
133
|
+
Where `<lang>` is one of `js`, `ts`, `javascript`, `typescript`, `python`, `rust`, `go`, `java`, `kotlin`. Pass `{run_dir}/entries.json`'s `manifest` and each of its `entry_files` that §2's fetch `fetched`, by its path in the repository: one `--entry-file` per entry point, and no `--manifest-file` when §2 fetched no manifest. The helper aggregates exports across every entry. `--follow` reads each module an `unlisted[]` record names, fetched into `{run_dir}/src` first, round after round, so an `export *` chain is followed to its end.
|
|
86
134
|
|
|
87
|
-
|
|
135
|
+
**When §2 fetched neither a manifest nor an entry point** (the listing holds no candidate, the language has no row in §2's table, or the fetch read none of them), do not run the extractor: it needs at least one file. Stage the empty envelope instead, so §4 builds an inventory with no exports and §4.5 decides what follows:
|
|
88
136
|
|
|
89
137
|
```bash
|
|
90
|
-
|
|
91
|
-
|
|
138
|
+
cat > "{run_dir}/extract.json" <<'SKF_JSON'
|
|
139
|
+
{"language": "{language}", "package_name": null, "version": null, "description": null, "exports": [], "dependencies": [], "modules": [], "warnings": ["no source file was fetched"]}
|
|
140
|
+
SKF_JSON
|
|
92
141
|
```
|
|
93
142
|
|
|
94
|
-
|
|
143
|
+
Stage it the same way when the extractor exits non-zero, which leaves `{run_dir}/extract.json` empty, with its error line in place of `no source file was fetched` (a JSON string, any `"` or `\` escaped).
|
|
144
|
+
|
|
145
|
+
The helper writes JSON to `{run_dir}/extract.json` with:
|
|
146
|
+
|
|
147
|
+
- `package_name`, `version`, `description`: parsed from the manifest
|
|
148
|
+
- `exports[]`: `{name, type, source_file}` per discovered top-level public symbol
|
|
149
|
+
- `dependencies[]`: declared direct dependencies
|
|
150
|
+
- `modules[]` and `module_folders[]`: for Maven `<modules>` and Gradle `include(...)`, the names of sub-modules to iterate, and the folder of each in the repository
|
|
151
|
+
- `extra`: language-specific extras (e.g. `group_id` for Maven)
|
|
152
|
+
- `warnings[]`: manifest parse failures and scanner errors (advisory only; the envelope is still valid), and each statement whose names the entry file alone cannot give: `export * from`, a star import from the package, an `__all__` built from another module, `pub use x::*`, `module.exports = require(...)`, or an anonymous or conditional export. Each names its file, line and statement.
|
|
153
|
+
- `unlisted[]`: one record per statement that passes on another module's names, `{file, line, statement, specifier, module_file}`: `module_file` is the listed file the statement's module is, null when the listing holds none. A statement whose module the extractor already reads is not listed.
|
|
154
|
+
- `followed[]`: the modules `--follow` read, in the order it read them.
|
|
155
|
+
|
|
156
|
+
Read `{run_dir}/extract.json` into the extraction context. The shape of the envelope is the same for every language; §4 builds the inventory from it without per-language branching.
|
|
95
157
|
|
|
96
|
-
|
|
158
|
+
**Read the statements `unlisted[]` still names** before §4. `--follow` read every module it could, so read by eye only the `unlisted[]` records left, whose `module_file` is null or could not be read (a warning says why): list the names each adds, from the README's API section or the module's documentation, and stage them through a quoted heredoc as `{run_dir}/extract-added.json`, `{"exports": [{"name": "<name>", "type": "re-export", "source_file": "<the record's file>"}]}`, which step 4 §4 passes with the other extraction files. Leave the other warnings for §5.
|
|
97
159
|
|
|
98
|
-
- `
|
|
99
|
-
- `exports[]` — `{name, type, source_file}` per discovered top-level public symbol
|
|
100
|
-
- `dependencies[]` — declared direct dependencies
|
|
101
|
-
- `modules[]` — for Maven `<modules>` and Gradle `include(...)`, the names of sub-modules to iterate (loop §2+§3 per entry)
|
|
102
|
-
- `extra` — language-specific extras (e.g. `group_id` for Maven)
|
|
103
|
-
- `warnings[]` — manifest parse failures or scanner errors (advisory only; the envelope is still valid)
|
|
160
|
+
**Multi-module loop:** when `modules[]` is non-empty, fetch every sub-module's manifest in one §2 call, each under its `module_folders[]` entry. Then, per module, run §2's entries call with `--scope "<its module_folders[] entry>"`, its list and output written to `{run_dir}/entries-module-<n>.txt` and `{run_dir}/entries-module-<n>.json`, fetch the files it lists, and run the helper (§3) on them, writing each to `{run_dir}/extract-module-<n>.json`, `<n>` counting from 1 in `modules[]` order (a module is a path such as `modules/core` or a Gradle name such as `core:api`, so it never names the file). Step 4 §4 passes `{run_dir}/extract.json` (the parent manifest, which names the `package_name`) first and then each module's file in that order, and the renderer aggregates `exports[]` and `dependencies[]` across them.
|
|
104
161
|
|
|
105
|
-
|
|
162
|
+
**Skills module** (`repo_shape: skills-module`): when §2 fetched a manifest, run the helper as above with that `--manifest-file` and no `--entry-file`, writing `{run_dir}/extract-manifest.json`. It still reads `package_name`, `version`, `description` and `dependencies`, and returns no exports. Then build the module's envelope from the staged `SKILL.md` files and `module-help.csv`:
|
|
106
163
|
|
|
107
|
-
|
|
164
|
+
```bash
|
|
165
|
+
uv run {skillsModuleHelper} extract --sniff "{run_dir}/sniff.json" --source-root "{run_dir}/src" [--package "{run_dir}/extract-manifest.json"] --name {repo_name} > "{run_dir}/extract.json"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Pass `--package` only when that file exists; without it `package_name` is `{repo_name}`. Read the `exports[]` it lists: one `skill` per skill folder in the sniff's order, named by its frontmatter `name` (the folder name when it has none) with its `description`, then one `menu-code` per `module-help.csv` row that has a menu code, in file order. Its `usage_patterns[]` give §4 one usage pattern per `module-help.csv` row (the `_meta` row and rows with no skill left out), and its `confidence` is the module's. Do not read the `SKILL.md` files or the CSV yourself: the helper parses them.
|
|
108
169
|
|
|
109
170
|
### 4. Build Extraction Inventory
|
|
110
171
|
|
|
@@ -116,22 +177,27 @@ extraction_inventory:
|
|
|
116
177
|
package_name: {from manifest}
|
|
117
178
|
version: {from manifest}
|
|
118
179
|
language: {detected}
|
|
180
|
+
repo_shape: {the §1.5 shape, when one was recorded}
|
|
181
|
+
skills_root: {skills-module only: the folder that holds the skill folders}
|
|
119
182
|
exports: [{name, type, brief_description}]
|
|
120
|
-
usage_patterns: [{pattern from README examples}]
|
|
183
|
+
usage_patterns: [{pattern from README examples, or the skills-module helper's usage_patterns}]
|
|
121
184
|
dependencies: [{key deps from manifest}]
|
|
122
185
|
confidence: {high/medium/low based on data quality}
|
|
123
186
|
```
|
|
124
187
|
|
|
188
|
+
For a skills module, confidence is the helper's `confidence`: `high` when every skill folder's frontmatter gave a `name` and a `description`, else `medium`.
|
|
189
|
+
|
|
125
190
|
**If no exports found:**
|
|
126
191
|
- Set confidence to `low`
|
|
127
192
|
- Use README description and features as fallback content
|
|
128
|
-
- Note: "No exports detected
|
|
193
|
+
- Note: "No exports detected: SKILL.md will be based on README content only"
|
|
194
|
+
- If the sniff's `suggested_scope` is set (a folder below the repository root holds skill folders), add to the note: "`{suggested_scope}` holds skill folders: re-run with `--scope-hint {suggested_scope}` (a batch line's `scope={suggested_scope}`) to document them as a skills module." The helper names the module root with the most skill folders or, when the listing shows no module root, the folder with the most.
|
|
129
195
|
|
|
130
196
|
### 4.5. Zero-Exports Soft Gate (rescue mode)
|
|
131
197
|
|
|
132
198
|
Run this gate **only when** `extraction_inventory.exports.length == 0` and `extraction_inventory.description` is empty (no usable README content either). When either is non-empty, the README-fallback in §4 produces a usable skill and this section is skipped.
|
|
133
199
|
|
|
134
|
-
|
|
200
|
+
Offer the user a chance to retry with hints before producing a degenerate output:
|
|
135
201
|
|
|
136
202
|
"**Extraction yielded zero exports and no README description.**
|
|
137
203
|
|
|
@@ -144,11 +210,11 @@ Common causes:
|
|
|
144
210
|
|
|
145
211
|
Select: [R] Retry with new hints · [P] Proceed anyway (low-confidence skill) · [A] Abort"
|
|
146
212
|
|
|
147
|
-
- **IF R
|
|
148
|
-
- **IF P
|
|
149
|
-
- **IF A
|
|
213
|
+
- **IF R**: prompt for new `scope_hint` ("New scope hint (e.g. `src/server/`):") and optional new `language_hint` ("New language hint (or empty to keep `{language}`):"). A non-empty new language hint sets `language` to it, `language_resolution` to `hint` and `detected_languages` to `[]`, as step 1 §4 does for a hint, so the result contract reports where the language came from. Update the extraction context with the new hints, then **re-execute step 3 from §1** with the new values: §1 sniffs the same `{run_dir}/tree.json` again under the new scope. Discards the prior empty inventory.
|
|
214
|
+
- **IF P**: log "user accepted zero-exports outcome" and proceed to §5. The compiled skill will be README-content-only with confidence `low`. Record `zero_exports_rescue: "user-accepted"` in the inventory so the result contract summary surfaces it.
|
|
215
|
+
- **IF A**: HARD HALT with **exit code 3 (resolution-failure)**: "Aborted. Run `/skf-create-skill` from a brief if you want a guided extraction with provenance tracking." Stage `{"phase": "quick-extract", "halt_reason": "resolution-failure", "reason": "Aborted: zero exports and no README description.", "skill_package": null, "details": {"exports_found": 0, "description_empty": true, "language": "{language}", "scope": "{scope_hint or 'entire repo'}"}}` as `{run_dir}/halt.json` and run `uv run {emitEnvelopeHelper} emit-halt --workflow skf-quick-skill --run-dir "{run_dir}" --target stderr < "{run_dir}/halt.json"`.
|
|
150
216
|
|
|
151
|
-
**GATE [default: P]
|
|
217
|
+
**GATE [default: P]**: in headless mode, log "headless: zero exports + empty description, proceeding with low-confidence skill", record `zero_exports_rescue: "auto-proceeded"` in the inventory so the result contract summary lets automators re-run these targets with stricter hints (`--scope-hint` or `--language-hint`, or a batch line's `scope=` or `language=`), record the decision (stage `{"gate": "quick-extract.zero-exports", "default_action": "P", "taken_action": "P", "reason": "headless: compiled a low-confidence skill"}` as `{run_dir}/decision.json` and run `uv run {emitEnvelopeHelper} record --workflow skf-quick-skill --run-dir "{run_dir}" --decision < "{run_dir}/decision.json"`) and proceed.
|
|
152
218
|
|
|
153
219
|
### 5. Report Extraction Summary
|
|
154
220
|
|
|
@@ -156,13 +222,16 @@ Select: [R] Retry with new hints · [P] Proceed anyway (low-confidence skill) ·
|
|
|
156
222
|
|
|
157
223
|
- **Package:** {package_name} v{version}
|
|
158
224
|
- **Language:** {language}
|
|
225
|
+
{If `repo_shape` was recorded, add:} - **Repo shape:** {repo_shape} (for `skills-module`: {skill count} skills and {menu code count} menu codes in `{skills_root}`)
|
|
159
226
|
- **Exports found:** {count}
|
|
160
227
|
- **Confidence:** {confidence}
|
|
161
|
-
- **Source files read:** {count}
|
|
228
|
+
- **Source files read:** {count} (the files §1 and §2 fetched and the extraction's `followed`; name each one that could not be read)
|
|
229
|
+
{If the fetch output's `truncated` was true, add:} - **Listing:** truncated by GitHub (a very large tree), so a file a glob names may have been missed
|
|
230
|
+
{If `{run_dir}/entries.json` lists `unresolved` entries, add:} - **Entry points not found:** {each one's `package` and `subpath`, with the `targets` tried}
|
|
162
231
|
|
|
163
232
|
**Proceeding to compilation...**"
|
|
164
233
|
|
|
165
234
|
### 6. Auto-Proceed to Compilation
|
|
166
235
|
|
|
167
|
-
Once extraction_inventory is assembled (even if minimal or low-confidence), load and execute {nextStepFile} to compile.
|
|
236
|
+
Once extraction_inventory is assembled (even if minimal or low-confidence), load and execute {nextStepFile} to compile; when `{headless_mode}` is true, print this step's `done` event and step 4's `start` event first (`references/halt-contract.md`).
|
|
168
237
|
|
|
@@ -1,73 +1,18 @@
|
|
|
1
1
|
<!-- Config: communicate in {communication_language}. -->
|
|
2
2
|
|
|
3
|
-
# Registry Resolution
|
|
3
|
+
# Registry Resolution: Web Search Fallback
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`skf-resolve-package.py` reads every target and asks the registries, npm, PyPI and crates.io, and resolve-target §1b to §3 act on its JSON. This file holds what the script leaves to judgment: the web search for a name no registry resolved (resolve-target §3, `status: "fallthrough"`), which a Go module path or a Maven coordinate also tries (resolve-target §2).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Search
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Search `"{package_name} github repository"`, spending at most 15 seconds, and read the top results for a `github.com/<owner>/<repo>` URL.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- **Package name:** Everything else — enter resolution chain below
|
|
11
|
+
## Pick the Repository
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
Take a URL only when that repository is the package's source: its name, or the package or module name its page shows, matches `{package_name}` (`uber-go/zap` for `go.uber.org/zap`, `google/guava` for `com.google.guava:guava`). Prefer the project's own repository over a fork, a mirror or a list that links to it, and keep a `/tree/<ref>/<folder>` URL whole when the package is one folder of a larger repository.
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
## Result
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
#### 1. npm Registry (JavaScript/TypeScript)
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
URL: https://registry.npmjs.org/{package_name}
|
|
24
|
-
Field: repository.url
|
|
25
|
-
Fallback field: homepage
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Extract `repository.url`, strip `git+` prefix and `.git` suffix if present.
|
|
29
|
-
|
|
30
|
-
#### 2. PyPI Registry (Python)
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
URL: https://pypi.org/pypi/{package_name}/json
|
|
34
|
-
Field: info.project_urls.Source OR info.project_urls.Repository OR info.home_page
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Check `project_urls` keys in order: Source, Repository, Homepage. Filter for GitHub URLs.
|
|
38
|
-
|
|
39
|
-
#### 3. crates.io Registry (Rust)
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
URL: https://crates.io/api/v1/crates/{package_name}
|
|
43
|
-
Field: crate.repository
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Direct `repository` field usually points to GitHub.
|
|
47
|
-
|
|
48
|
-
#### 4. Web Search Fallback
|
|
49
|
-
|
|
50
|
-
If all registry lookups fail:
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
Search: "{package_name} github repository"
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Look for GitHub URL in top results. Verify it matches the package name.
|
|
57
|
-
|
|
58
|
-
#### 5. Resolution Failure
|
|
59
|
-
|
|
60
|
-
If all methods fail:
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
"Could not resolve '{package_name}' to a GitHub repository.
|
|
64
|
-
|
|
65
|
-
Please provide the GitHub URL directly, or check:
|
|
66
|
-
- Is the package name spelled correctly?
|
|
67
|
-
- Is it a private package?
|
|
68
|
-
- Is the source hosted on a non-GitHub platform?"
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**Hard halt** — cannot proceed without a resolved source.
|
|
72
|
-
|
|
73
|
-
Language detection is authoritative in `resolve-target.md` §4 (Detect Language) — this file covers only the package-to-repo registry chain.
|
|
17
|
+
- **A URL:** resolve-target takes it as the target and parses it again from §1b.
|
|
18
|
+
- **None, or the search timed out:** resolve-target halts with its resolution failure.
|