bmad-module-skill-forge 2.2.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 +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 +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 +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 +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 +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 +1 -1
- 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 +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 +15 -5
- 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 +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 +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 -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 +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 -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
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Running the Recipes by Hand
|
|
2
|
+
|
|
3
|
+
Load this file only when the recipe runner cannot run (**When the Runner Cannot Run** in `extraction-patterns.md`). It holds what running the recipes one at a time needs besides the part of `extraction-patterns.md` from **Running the Recipes Without the Runner** on (the decision tree, the CLI streaming template and the recipes themselves, which the runner's recipe file mirrors and `kind-at` reads there): how to pass a recipe, each recipe's notes, and the Known ast-grep Limitations of patterns run by hand.
|
|
4
|
+
|
|
5
|
+
## Passing a Recipe
|
|
6
|
+
|
|
7
|
+
Every recipe's `rule` declares `kind`, the kind of the node it matches, and captures the export's own name as `$NAME`; each was verified on ast-grep 0.45.3 against fixtures holding the forms it must find and the forms it must skip. A JS/TS export recipe matches the whole `export_statement`, not the declaration inside it, except `js-reexports` and `js-local-exports`, which match each `export_specifier`; a pattern without `export`, such as the type-alias workaround `type $NAME = $T` (#9), matches the declaration itself (`type_alias_declaration`), even inside an `export type`. A decorated Python `def` matches the inner `function_definition`, not `decorated_definition`. ast-grep's JSON output never reports the kind of a match, so an export a recipe matched records the recipe's `kind` as its `ast_node_type`.
|
|
8
|
+
|
|
9
|
+
Most recipes are relational rules (`inside`, `has`, `not`) rather than one pattern, so pass a recipe whole: to `find_code_by_rule`, or as the CLI streaming template's `{recipe_file}`. Never drop the `kind`: without it, ast-grep rejects a pattern that is not a whole statement on its own, such as `def $NAME`. A recipe can match one name more than once (each overload signature, a `def` in both branches of an `if`), so merge its matches by name and file. Known Limitation #11 lists the forms each recipe deliberately does not cover.
|
|
10
|
+
|
|
11
|
+
## ast-grep Patterns
|
|
12
|
+
|
|
13
|
+
Each export shape below is matched by one recipe from the YAML Rule Recipes in `extraction-patterns.md`: its `id` is what the entry records as `ast_recipe`, and the `kind` it declares is what the entry records as `ast_node_type`.
|
|
14
|
+
|
|
15
|
+
| Export shape | Recipe (`ast_recipe`) | Kind (`ast_node_type`) |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Python: a module-level `def` or `async def` | `python-public-functions` | `function_definition` |
|
|
18
|
+
| Python: a module-level `class` | `python-public-classes` | `class_definition` |
|
|
19
|
+
| JS/TS: a top-level `export function` (async, generator, generic, each overload signature, `export default function Name`, `export declare function`) | `js-exported-functions` | `export_statement` |
|
|
20
|
+
| JS/TS: `export const NAME = ...` | `js-exported-constants` | `export_statement` |
|
|
21
|
+
| JS/TS: `export const NAME = (...) => ...` | `js-exported-arrow-functions` | `export_statement` |
|
|
22
|
+
| JS/TS: `export class` | `js-exported-classes` | `export_statement` |
|
|
23
|
+
| TypeScript: a top-level `export interface`, `export type` alias or `export enum` (generic, `extends`, `const enum` and `export declare` forms included) | `ts-exported-types` | `export_statement` |
|
|
24
|
+
| JS/TS: each name of `export { a, b as c } from '...'` | `js-reexports` | `export_specifier` |
|
|
25
|
+
| JS/TS: `export * as ns from '...'` | `js-namespace-reexports` | `export_statement` |
|
|
26
|
+
| JS/TS: each name of a local `export { a, b as c }` with no `from` | `js-local-exports` | `export_specifier` |
|
|
27
|
+
| Rust: a top-level `pub fn`, outside `impl` blocks | `rust-public-functions` | `function_item` |
|
|
28
|
+
| Go: an exported function, not a method | `go-exported-functions` | `function_declaration` |
|
|
29
|
+
| React: `export interface NameProps` | `react-props-interfaces` | `export_statement` |
|
|
30
|
+
| React: a PascalCase `export function` | `react-component-functions` | `export_statement` |
|
|
31
|
+
| React: a PascalCase `export const Name = (...) => ...` | `react-component-arrow-functions` | `export_statement` |
|
|
32
|
+
| React: a PascalCase `export const Name = memo(...)`, `forwardRef(...)` or `lazy(...)`, with or without `React.` | `react-wrapped-components` | `export_statement` |
|
|
33
|
+
| Vue: a top-level `defineProps<T>()` | `vue-define-props` (`vue-define-props-tsx` for `<script setup lang="tsx">`) | `call_expression` |
|
|
34
|
+
|
|
35
|
+
- A `find_code` pattern is only the fallback of Known Limitation #4: an export it matched records the pattern as `ast_recipe` and the kind of its shape from this table.
|
|
36
|
+
|
|
37
|
+
## MCP Tool Usage
|
|
38
|
+
|
|
39
|
+
**Recipe search (up to 500 files in scope):**
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
find_code_by_rule(
|
|
43
|
+
project_folder="{source_path}",
|
|
44
|
+
yaml="id: public-api\nlanguage: python\nrule:\n pattern: 'def $NAME'\n kind: function_definition\n inside:\n kind: module\n stopBy:\n any:\n - kind: function_definition\n - kind: class_definition\n not:\n inside:\n kind: block\n stopBy: end\n inside:\n kind: if_statement\n has:\n field: condition\n regex: '^\\(?\\s*(__name__\\s*==\\s*[''\"]__main__[''\"]|[''\"]__main__[''\"]\\s*==\\s*__name__)\\s*\\)?$'\nconstraints:\n NAME:\n regex: '^[^_]'",
|
|
45
|
+
max_results=150,
|
|
46
|
+
output_format="json"
|
|
47
|
+
)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The `yaml` string is the `python-public-functions` recipe as a JSON string (`\n` for each line break, `\"` for each quote, `\\` for each backslash). Ask for `output_format="json"`, whose matches carry `metaVariables.single.NAME` (and `SOURCE`) and `$NAME`'s line; `output_format="text"` loses both and cites a match's first line.
|
|
51
|
+
|
|
52
|
+
## When a Recipe Run Fails
|
|
53
|
+
|
|
54
|
+
**Safety valve.** If any ast-grep operation (MCP or CLI) visibly causes a timeout, returns an error related to output size, or produces unexpectedly large output: immediately switch to the CLI streaming template (`ast-grep scan -r {recipe_file} --json=stream`, in directory batches). Do not retry the same approach. When falling back to the CLI streaming template, inject the brief's `scope.exclude` patterns into the `EXCLUDES` list (use `[]` if absent); this applies regardless of which path triggered the fallback. Note: `max_results` in the MCP tool and `| head -N` in the CLI path provide hard caps, but this safety valve covers cases where the upstream tool itself fails before returning results (e.g., OOM during JSON serialization).
|
|
55
|
+
|
|
56
|
+
**Simple pattern search (fallback only):**
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
find_code(
|
|
60
|
+
project_folder="{source_path}",
|
|
61
|
+
pattern="async def $NAME($$$PARAMS)",
|
|
62
|
+
language="python",
|
|
63
|
+
max_results=100,
|
|
64
|
+
output_format="text"
|
|
65
|
+
)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`find_code` takes a pattern and no `kind` or relational clauses, so it cannot keep a recipe's scope: methods, nested and private definitions come back too. Use it only as Known Limitation #4's fallback, and record the kind of the pattern's shape from the ast-grep Patterns table above, in this file (`function_definition` here, since an `async def` is a `function_definition`).
|
|
69
|
+
|
|
70
|
+
## Recipe Notes
|
|
71
|
+
|
|
72
|
+
### Python
|
|
73
|
+
|
|
74
|
+
**Scope note:** Both Python recipes match module-level definitions only, decorated or not (a decorated one at its `def` or `class` line) and generic or not, and only names that do not start with `_`. Their `inside: module` clause stops at the first enclosing `def` or `class`, so a method, a nested `def` and a nested class never match, while a definition under a module-level `if`, `try`, `with`, `for`, `while` or `match` (`if TYPE_CHECKING:` included) does. The `not:` clause drops a definition under `if __name__ == "__main__":` (or `"__main__" == __name__`, with or without parentheses), which exists only when the file runs as a script; the `else:` branch of that `if` still matches, and so does a definition under an `elif __name__ == "__main__":` or a compound guard (#11). The function pattern is `def $NAME`, not `def $NAME($$$PARAMS)`: in a PEP 695 generic `def name[T](...)` the type parameters sit between the name and the parameters, so the longer pattern misses it (#7). Neither recipe reads `__all__`.
|
|
75
|
+
|
|
76
|
+
**Pattern note:** The minimal `class $NAME` pattern, with `kind: class_definition`, matches every class, with or without bases, keywords, decorators or PEP 695 type parameters. The `class $NAME($$$BASES)` and `class $NAME($$$BASES):` variants return zero (see Known Limitations #7). A bare `ast-grep run -p 'class $NAME' -l python` also returns classes nested in a class or a function, since a pattern alone cannot carry the module-level scope: run the recipe as a rule file instead.
|
|
77
|
+
|
|
78
|
+
### JavaScript and TypeScript
|
|
79
|
+
|
|
80
|
+
**Language selection:** Use `language: typescript` for `.ts`, `.mts`, `.cts` and `.d.ts` files and `language: tsx` for `.tsx` files. They use different tree-sitter parsers, and a rule scans only the files of its own language, so for a mixed codebase run each recipe once per language, changing only `language`, and merge the results. For `.js`, `.jsx`, `.mjs` and `.cjs` files use `language: javascript`: `js-exported-constants`, `js-exported-arrow-functions`, `js-exported-classes`, `js-reexports`, `js-namespace-reexports`, `js-local-exports`, `react-component-arrow-functions` and `react-wrapped-components` run unchanged, `js-exported-functions` and `react-component-functions` have `javascript` forms in `extraction-patterns.md` (ast-grep rejects their TypeScript forms there, since `function_signature` and `ambient_declaration` are not JavaScript kinds), and `react-props-interfaces` and `ts-exported-types` are TypeScript only.
|
|
81
|
+
|
|
82
|
+
**Overloads, defaults and scope:** Each overload signature matches, all with the same `$NAME`, and the implementation after them does not, since callers see only the signatures: the `not:` clause looks at the nearest statement before the implementation that is not a comment. Async, generator and generic functions match, and so do `export default function Name` (with `Name` as `$NAME`) and `export declare function`. The `inside: program` clause keeps the recipe to top-level exports, so an `export function` inside a `namespace`, `declare module` or `declare global` block does not match.
|
|
83
|
+
|
|
84
|
+
**JS/TS Pattern Merging:** Modern TypeScript codebases often use `export const` exclusively for all exports (arrow functions, objects, constants). Run all the JS/TS recipes (functions, arrow functions, constants, classes, interfaces, type aliases and enums, re-exports and local export lists) and merge results by `$NAME`. Priority when deduplicating: arrow function match > function declaration match > constant match. Both `const` recipes bind the declarator's value as `$VALUE`: for an arrow-function match that is the whole arrow, typed, `async` or generic, with its parameters and return type in it; a constant match needs `$VALUE` inspected to extract a signature. Both take `const` declarations only, with a plain identifier as the name.
|
|
85
|
+
|
|
86
|
+
**Important:** The recipe matches an `export_statement` whose declaration has a name and a `class_body`, so plain, generic, `extends`, `implements`, `abstract` and decorated classes all match, with the class name as `$NAME`. A decorated class matches from its first decorator, so the match, and its line, start at the decorator. `export default class` does not match (its exposed name is `default`), and neither does `export declare class`. The `find_code` patterns are narrower: the bare `export class $NAME` returns zero with a `Pattern contains an ERROR node` warning, and `export class $NAME { $$$ }` matches only a class with no type parameters and no `extends` (see Known Limitations #9 and #10). Either way a match is the whole `export_statement`, the kind the recipe declares, not the `class_declaration` inside it.
|
|
87
|
+
|
|
88
|
+
**Types note:** The recipe matches a top-level `export interface`, `export type` alias or `export enum` as an `export_statement`, with the declared name as `$NAME`: generic and `extends` interfaces, generic type aliases, `const enum`, and the `export declare` form of each, on the name's own line when the name follows its keyword on the next line. It skips `export default interface`, whose exposed name is `default`, and an interface, type alias or enum inside a `namespace`, `declare module` or `declare global` block, a member rather than a module export. A type exported through a list (`export type { T }`, `export { type T }`) is found by `js-local-exports`, or by `js-reexports` when the list has a `from`. The recipe is TypeScript only: ast-grep rejects it under `language: javascript`, whose grammar has no interface, type alias or enum.
|
|
89
|
+
|
|
90
|
+
**Re-export note:** `js-reexports` matches each name of `export { a, b as c } from '...'` on its own, as an `export_specifier`: `$NAME` is the name the module exposes (the alias when there is one, without quotes when it is a string) and `$SOURCE` the module path without quotes. Type-only re-exports (`export type { T } from`, `export { type T } from`) match too, since their names are exported. `js-local-exports` matches each name of a local list with no `from` the same way, such as the `export { Button, buttonVariants }` that ends a shadcn/ui component file, type-only lists included: these two are the JS/TS recipes whose kind is `export_specifier`, not `export_statement`. A local list names a binding the file defines or imports, and the line cited is the list's. Both record the exposed name, so `export { x as default }` records `default`. `js-namespace-reexports` matches `export * as ns from '...'` as an `export_statement`, with `ns` as `$NAME`. None of them covers a bare `export * from '...'`, which exposes no name of its own: follow it, and the module each `$SOURCE` names, with the Re-Export Tracing protocol in `extraction-patterns-tracing.md`.
|
|
91
|
+
|
|
92
|
+
### Rust
|
|
93
|
+
|
|
94
|
+
**Scope note:** The recipe matches a `function_item` with a bare `pub` (async, `const`, `unsafe`, `extern "C"` and generic functions included) at the top of the file or inside a chain of `pub mod` blocks, which a pattern such as `pub fn $NAME($$$PARAMS)` never finds: it parses as a bodyless `function_signature_item`. It does not match a `pub(crate)`, `pub(super)`, `pub(self)` or `pub(in ...)` function, a `pub fn` under a private or `pub(crate)` inline `mod`, inside a function body or a `const` block, or a `pub fn` in an `impl` block (see Known Limitation #8).
|
|
95
|
+
|
|
96
|
+
### Go
|
|
97
|
+
|
|
98
|
+
**Scope note:** The recipe matches every function declaration with a capitalized name, generic and bodyless (assembly-backed) ones included, whatever comments sit between the name and its parameters. Methods (`func (r T) Name()`) never match.
|
|
99
|
+
|
|
100
|
+
### Component Library Recipes
|
|
101
|
+
|
|
102
|
+
**`react-props-interfaces`:** The recipe matches plain, generic and `extends` interfaces whose name ends in `Props`, but not `export default interface`, `export declare interface` or a props type written as a type alias (`export type XProps = {...}`).
|
|
103
|
+
|
|
104
|
+
**`react-component-functions`:** Use `language: tsx` for `.tsx` files and `language: typescript` for `.ts` files; the rule body is the same. The rule is `js-exported-functions` without generator functions (React cannot render one) plus a PascalCase `$NAME`, so async, generic and default-exported components match, and so does each overload signature. For `.js` and `.jsx` files use its `javascript` form in `extraction-patterns.md`. `^\p{Lu}` accepts any uppercase first letter, non-ASCII ones included.
|
|
105
|
+
|
|
106
|
+
**`react-component-arrow-functions`:** The name's `regex` sits inside the declarator's `has` as well as under `constraints`: a constraint is checked after the match, so on its own it would drop `export const helper = () => 1, Card = () => null` instead of matching `Card`.
|
|
107
|
+
|
|
108
|
+
**`react-wrapped-components`:** Use `language: tsx` for `.tsx` files, `language: typescript` for `.ts` files and `language: javascript` for `.js` and `.jsx` files; the rule body is the same. The recipe matches a top-level `export const` whose PascalCase name is bound to a call of `memo`, `forwardRef` or `lazy`, with or without `React.` and with type arguments (`React.forwardRef<HTMLDivElement, Props>(...)`): the wrapped components `react-component-arrow-functions` skips, which `js-exported-constants` reports as constants. Like the arrow-function recipe, it finds a later declarator of an `export const` list when the first one does not match.
|
|
109
|
+
|
|
110
|
+
**Vue note:** ast-grep reads a `.vue` file only when an `sgconfig.yml` maps it to HTML (`languageGlobs:` with `html: ["*.vue"]`); without one it skips every `.vue` file silently, with exit code 0. `find_code_by_rule` takes no config, so it never reaches a `.vue` file: run the Vue recipes with the CLI streaming template and add `-c {scratch}/sgconfig.yml`, a file holding those two lines that you write in a scratch folder, never in the user's source tree. With it, a `language: typescript` rule runs inside each `<script lang="ts">` block and a `language: tsx` rule inside each `<script lang="tsx">` block, at the `.vue` file's own line numbers, which is why the tsx block needs its own recipe. Both recipes match a top-level `defineProps<T>()` call, with the props type as `$NAME` whatever its form (a type name, an inline type literal, `Types.Props`, `Props<T>`, a union); the `not:` clause skips a call inside a function, an arrow function, a class, a block, or an `if`, `for`, `while` or `switch` statement, which Vue's compiler rejects anyway.
|
|
111
|
+
|
|
112
|
+
## Known ast-grep Limitations of Patterns Run by Hand
|
|
113
|
+
|
|
114
|
+
These concern patterns run by hand. Two more stay in `extraction-patterns.md`: #4, the `find_code` fallback of a recipe run by hand, and #11, the forms the recipes do not cover, which every run reads.
|
|
115
|
+
|
|
116
|
+
1. **`export class $NAME` needs a body on 0.42.x; `find_code_by_rule` takes the recipe's `kind`:** The bare `export class $NAME` pattern returns zero through **both** `find_code()` and the CLI on ast-grep 0.42.x: add the body, `export class $NAME { $$$ }` (see #9). With `find_code_by_rule`, pass the `js-exported-classes` recipe with its `kind: export_statement`: the recipe matches the whole export, so a rule naming the inner `class_declaration` finds nothing.
|
|
117
|
+
|
|
118
|
+
2. **A re-export statement holds several names:** `export { A, B as C } from './module'` is one `export_statement` with one `export_specifier` per name. The `js-reexports` recipe matches each specifier, with the name the module exposes as `$NAME` (`A`, `C`), so no splitting is needed. The pattern `export { $$$NAMES } from $SOURCE` is rejected on 0.42.2 and 0.45.3 (`Multiple AST nodes are detected`); `export { $$$NAMES } from "$SOURCE"` and `export { $$$NAMES } from '$SOURCE'` each match one quote style, as an `export_statement`.
|
|
119
|
+
|
|
120
|
+
3. **Default anonymous exports capture no name:** `export default function $NAME` works, but `export default $EXPR` (anonymous default export) captures no name in `$NAME`. Fall back to source reading (T1-low) for anonymous defaults.
|
|
121
|
+
|
|
122
|
+
5. **The `export function $NAME($$$PARAMS)` pattern returns zero in `.tsx` files:** on ast-grep 0.41.x and still on 0.45.3 (with plain `typescript` too, #9), through both the MCP tools and the CLI. The recipes do not use it: `js-exported-functions` with `language: tsx` and `react-component-functions` match every `export function` form their notes list in `.tsx` files, so run them instead of reading `export function` declarations by eye. Read by eye (T1-low) only the forms Known Limitation #11 lists. When a TSX codebase shows zero recipe matches for `export function` while its source clearly holds some, log it in the evidence report as an extraction gap.
|
|
123
|
+
|
|
124
|
+
6. **CLI `--json=stream` may produce no output (ast-grep 0.41.x):** On 0.41.x, `--json=stream` could produce empty output for certain patterns, and it needed the explicit `run` subcommand (`ast-grep run -p '{pattern}' --json=stream`, not `ast-grep -p '{pattern}' --json=stream`). On 0.45.3 it works with `scan`, as the CLI streaming template runs it (`ast-grep scan -r {recipe_file} --json=stream`), and with `run`. If streaming still produces no output where matches are expected, fall back to `find_code_by_rule` or source reading.
|
|
125
|
+
|
|
126
|
+
7. **Python class patterns with bases/colon return zero (ast-grep 0.42.x); `def $NAME($$$PARAMS)` misses generic functions (0.45.3):** The patterns `class $NAME($$$BASES)` and `class $NAME($$$BASES):` return zero matches on real Python sources with ast-grep 0.42.0, even on files containing dozens of subclassed public classes. `find_code_by_rule` also rejects the bare inline rule without `kind` as `Rule must specify a set of AST kinds to match. Try adding \`kind\` rule.`, and so does the function pattern `def $NAME($$$PARAMS)`. With `kind: function_definition`, `def $NAME($$$PARAMS)` matches every `def` and `async def` on 0.45.3 except a PEP 695 generic `def name[T](...)`, whose type parameters sit between the name and the parameters. **Workaround:** the recipes use the prefix patterns `class $NAME` and `def $NAME` with their `kind` (`class_definition`, `function_definition`), which match every class and every `def` / `async def`, generic or not, a decorated one at its `class` / `def` line. Their `inside: module` clause stops at the first enclosing `def` or `class`, so they return module-level definitions only, never methods or nested definitions, and their `^[^_]` constraint keeps the public names. A bare CLI `ast-grep run -p 'class $NAME' -l python` (or `'def $NAME'`) cannot carry that scope and returns nested definitions too, so run the recipes as rule files. See the Python public classes and public functions recipes in `extraction-patterns.md`.
|
|
127
|
+
|
|
128
|
+
8. **Rust `pub fn` patterns find no function definitions (ast-grep 0.42.x and 0.45.3):** `pub fn $NAME($$$PARAMS)` and `pub fn $NAME($$$PARAMS) -> $RET` parse as a `function_signature_item` (a `fn` with no body, as in an `extern` block), so they return "No matches found" on real crates, even on crates containing 200+ public functions, and with `kind: function_item` they match nothing at all. `pub fn $NAME($$$PARAMS) { $$$ }` matches, but it also matches `pub(crate)` and `pub(super)` functions, methods, and functions in private modules, which are **not** public API. **The `rust-public-functions` recipe** has no pattern: it matches `function_item` nodes with a bare `pub` at the top of the file or in a chain of `pub mod` blocks (see the scope note under the recipe). It leaves out every `pub fn` in an `impl` block on purpose: whether a method is reachable depends on whether its type is, which one file cannot show, and a method's `$NAME` alone loses its type (every type's `new` would merge into one). Take public methods from the `impl` blocks of the public types by source reading, at T1-low confidence. Never silently accept zero results for Rust public functions.
|
|
129
|
+
|
|
130
|
+
9. **Plain `language: typescript` declaration patterns without a body return zero (ast-grep 0.42.x and 0.45.3):** The incomplete-statement patterns `export class $NAME`, `export function $NAME($$$PARAMS)`, `export type $NAME`, and `export enum $NAME` all return **zero** matches against real `.ts` sources on ast-grep 0.42.2 and 0.45.3; `export class` / `export type` / `export enum` additionally print `Pattern contains an ERROR node`. This affects the CLI (`ast-grep run -p ... -l typescript`) and the MCP `find_code()` API **identically**: `find_code()` is not a workaround. The cause is that a declaration pattern missing its body or initializer does not parse as a complete statement. The recipes do not use these patterns: `js-exported-functions`, `js-exported-classes`, `ts-exported-types` and `react-props-interfaces` match the `export_statement` and test its `declaration` node, so they find every function, class, interface, type alias and enum form their notes list. Run them, not a `find_code` pattern. The complete patterns match (verified on 0.42.2 and 0.45.3 via both CLI and `find_code`), but on 0.45.3 each misses forms the recipes find, and each also returns the members of an `export namespace` block, which are not module exports:
|
|
131
|
+
- **enum:** `export enum $NAME { $$$ }` (with the body) matches, `const enum` included, but not `export declare enum`.
|
|
132
|
+
- **type alias:** `type $NAME = $T` (no `export`, with the initializer) matches `export type` and bare `type` declarations alike, but not a generic alias (`type $NAME<T> = ...`).
|
|
133
|
+
- **class, interface, function:** `export class $NAME { $$$ }` and `export interface $NAME { $$$ }` carry a body and match, but miss generic and `extends` forms (#10), and `export function $NAME($$$PARAMS) { $$$ }` misses every function with a return-type annotation (and, on 0.42.2, every `async` one).
|
|
134
|
+
|
|
135
|
+
Never silently accept zero results for a declaration form the source language commonly uses.
|
|
136
|
+
|
|
137
|
+
Kinds (verified on 0.45.3): each `export ...` pattern above matches an `export_statement`. The type-alias workaround `type $NAME = $T` has no `export`, so it matches the `type_alias_declaration`, inside an `export type` too, and an export it matched records `type_alias_declaration`.
|
|
138
|
+
|
|
139
|
+
10. **Generic class declarations do not match non-generic class patterns (ast-grep 0.42.x and 0.45.3):** The non-generic `find_code` patterns `export class $NAME { $$$ }` and `export class $NAME extends $BASE { $$$ }` silently skip every generic form. On ast-grep 0.42.2, verified via both the CLI (`ast-grep run -p ... -l typescript`) and `find_code()`, the first matched only a plain `Plain` and the second only a plain `PlainExtends` on a fixture of `Plain` / `Generic<T>` / `GenericExtends<T> extends Base<T>` / `abstract AbstractGeneric<T>` / `PlainExtends`, and 0.45.3 does the same. The per-shape generic patterns `export class $NAME<$$$P> { $$$ }`, `export class $NAME<$$$P> extends $BASE { $$$ }`, and `export abstract class $NAME<$$$P> { $$$ }` each match exactly **one** shape. **The `js-exported-classes` recipe** has no pattern: it matches an `export_statement` whose declaration has a name and a `class_body`, so it finds all five shapes, and `implements` and decorated classes too. Use it rather than the patterns. When only `find_code` is available, run a source-read fallback `^export (abstract )?class` over the in-scope `.ts` sources (T1-low) and merge by name+file with the AST results. Never accept a class inventory that omits generic classes when the source uses them.
|
|
140
|
+
|
|
141
|
+
Kinds (verified on 0.45.3): the recipe, and each `export class` pattern above, generic, `extends` and `abstract` forms included, match an `export_statement`. The bare `class $NAME` pattern matches the declaration itself: a `class_declaration`, or an `abstract_class_declaration` for an `abstract` class.
|
|
@@ -18,7 +18,7 @@ After initial AST extraction, some top-level exports may resolve to **module imp
|
|
|
18
18
|
- If directory: read its `__init__.py` to find the actual re-exported symbol
|
|
19
19
|
- **Handle aliases:** Check for `from .module import A as B` patterns in the intermediate `__init__.py`. If the parent imports `B`, trace through to `A` in `.module`. If the parent imports `A` but the `__init__.py` only exports it as `B` (via `from .module import A as B`), match by original name `A` and note the alias
|
|
20
20
|
- Trace the symbol to its definition file and run AST extraction on that file
|
|
21
|
-
3. Cite the actual definition location: `[AST:{definition_file}:L{line}]`
|
|
21
|
+
3. Cite the actual definition location by the tool that found it: `[AST:{definition_file}:L{line}]` (T1, `extraction_method: ast-grep`, and as `ast_node_type` the `kind` its recipe declares in `extraction-patterns.md`, or the kind the ast-grep Patterns table in `extraction-patterns-by-hand.md` gives a `find_code` pattern) when an ast-grep rule matched the definition, or `[SRC:{definition_file}:L{line}]` (T1-low, `extraction_method: source-read`, `ast_node_type: null`) when you read it by eye
|
|
22
22
|
|
|
23
23
|
**Examples:**
|
|
24
24
|
|
|
@@ -89,7 +89,7 @@ Scripts and assets are file-level artifacts, not code exports. They follow the *
|
|
|
89
89
|
Each extracted file receives:
|
|
90
90
|
- Citation: `[SRC:{source_path}:L1]` (T1-low — file verified to exist but content not AST-analyzed)
|
|
91
91
|
- Content hash: SHA-256 of file content (for drift detection in audit-skill)
|
|
92
|
-
- Extraction method: `"file-copy"` (distinct from `"
|
|
92
|
+
- Extraction method: `"file-copy"` (distinct from `"ast-grep"` and `"source-read"`, the values code exports carry)
|
|
93
93
|
|
|
94
94
|
### Inventory Structure
|
|
95
95
|
|