create-yss-spec 2.1.11 → 2.1.13
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/README.md +1 -1
- package/package.json +1 -1
- package/template/.agents/skills/high-fidelity-html-prototype/SKILL.md +1 -18
- package/template/.agents/skills/llm-wiki/SKILL.md +60 -0
- package/template/.agents/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
- package/template/.agents/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
- package/template/.agents/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
- package/template/.agents/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
- package/template/.agents/skills/llm-wiki/assets/fixtures/broken-wiki/wiki//345/255/230/345/234/250/347/232/204/351/241/265.md +7 -0
- package/template/.agents/skills/llm-wiki/references/compile.md +126 -0
- package/template/.agents/skills/llm-wiki/references/discover.md +41 -0
- package/template/.agents/skills/llm-wiki/references/ingest.md +36 -0
- package/template/.agents/skills/llm-wiki/references/lint.md +54 -0
- package/template/.agents/skills/llm-wiki/references/query.md +21 -0
- package/template/.agents/skills/llm-wiki/references/schema.md +45 -0
- package/template/.agents/skills/llm-wiki/references/writing.md +35 -0
- package/template/.agents/skills/llm-wiki/scripts/advise.mjs +196 -0
- package/template/.agents/skills/llm-wiki/scripts/advise.test.mjs +91 -0
- package/template/.agents/skills/llm-wiki/scripts/extract.mjs +55 -0
- package/template/.agents/skills/llm-wiki/scripts/extract.test.mjs +34 -0
- package/template/.agents/skills/llm-wiki/scripts/inventory.mjs +174 -0
- package/template/.agents/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
- package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
- package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
- package/template/.agents/skills/yss-antd-design/SKILL.md +34 -0
- package/template/.agents/skills/yss-antd-design/references/boundaries.md +30 -0
- package/template/.agents/skills/yss-antd-design/references/cli-matrix.md +38 -0
- package/template/.agents/skills/yss-antd-design/references/evidence.md +26 -0
- package/template/.agents/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
- package/template/.agents/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
- package/template/.agents/skills/yss-design-system/SKILL.md +9 -5
- package/template/.agents/skills/yss-design-system/references/design-qa-theme.md +64 -0
- package/template/.agents/skills/yss-design-system/references/design-system.md +20 -12
- package/template/.agents/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
- package/template/.agents/skills/yss-prototype-stage/SKILL.md +3 -1
- package/template/.agents/skills/yss-ui/SKILL.md +1 -1
- package/template/.claude/skills/high-fidelity-html-prototype/SKILL.md +1 -18
- package/template/.claude/skills/llm-wiki/SKILL.md +60 -0
- package/template/.claude/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
- package/template/.claude/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
- package/template/.claude/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
- package/template/.claude/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
- package/template/.claude/skills/llm-wiki/assets/fixtures/broken-wiki/wiki//345/255/230/345/234/250/347/232/204/351/241/265.md +7 -0
- package/template/.claude/skills/llm-wiki/references/compile.md +126 -0
- package/template/.claude/skills/llm-wiki/references/discover.md +41 -0
- package/template/.claude/skills/llm-wiki/references/ingest.md +36 -0
- package/template/.claude/skills/llm-wiki/references/lint.md +54 -0
- package/template/.claude/skills/llm-wiki/references/query.md +21 -0
- package/template/.claude/skills/llm-wiki/references/schema.md +45 -0
- package/template/.claude/skills/llm-wiki/references/writing.md +35 -0
- package/template/.claude/skills/llm-wiki/scripts/advise.mjs +196 -0
- package/template/.claude/skills/llm-wiki/scripts/advise.test.mjs +91 -0
- package/template/.claude/skills/llm-wiki/scripts/extract.mjs +55 -0
- package/template/.claude/skills/llm-wiki/scripts/extract.test.mjs +34 -0
- package/template/.claude/skills/llm-wiki/scripts/inventory.mjs +174 -0
- package/template/.claude/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
- package/template/.claude/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
- package/template/.claude/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
- package/template/.claude/skills/yss-antd-design/SKILL.md +34 -0
- package/template/.claude/skills/yss-antd-design/references/boundaries.md +30 -0
- package/template/.claude/skills/yss-antd-design/references/cli-matrix.md +38 -0
- package/template/.claude/skills/yss-antd-design/references/evidence.md +26 -0
- package/template/.claude/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
- package/template/.claude/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
- package/template/.claude/skills/yss-design-system/SKILL.md +9 -5
- package/template/.claude/skills/yss-design-system/references/design-qa-theme.md +64 -0
- package/template/.claude/skills/yss-design-system/references/design-system.md +20 -12
- package/template/.claude/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
- package/template/.claude/skills/yss-prototype-stage/SKILL.md +3 -1
- package/template/.claude/skills/yss-ui/SKILL.md +1 -1
- package/template/.codex/skills/high-fidelity-html-prototype/SKILL.md +1 -18
- package/template/.codex/skills/llm-wiki/SKILL.md +60 -0
- package/template/.codex/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
- package/template/.codex/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
- package/template/.codex/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
- package/template/.codex/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
- package/template/.codex/skills/llm-wiki/assets/fixtures/broken-wiki/wiki//345/255/230/345/234/250/347/232/204/351/241/265.md +7 -0
- package/template/.codex/skills/llm-wiki/references/compile.md +126 -0
- package/template/.codex/skills/llm-wiki/references/discover.md +41 -0
- package/template/.codex/skills/llm-wiki/references/ingest.md +36 -0
- package/template/.codex/skills/llm-wiki/references/lint.md +54 -0
- package/template/.codex/skills/llm-wiki/references/query.md +21 -0
- package/template/.codex/skills/llm-wiki/references/schema.md +45 -0
- package/template/.codex/skills/llm-wiki/references/writing.md +35 -0
- package/template/.codex/skills/llm-wiki/scripts/advise.mjs +196 -0
- package/template/.codex/skills/llm-wiki/scripts/advise.test.mjs +91 -0
- package/template/.codex/skills/llm-wiki/scripts/extract.mjs +55 -0
- package/template/.codex/skills/llm-wiki/scripts/extract.test.mjs +34 -0
- package/template/.codex/skills/llm-wiki/scripts/inventory.mjs +174 -0
- package/template/.codex/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
- package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
- package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
- package/template/.codex/skills/yss-antd-design/SKILL.md +34 -0
- package/template/.codex/skills/yss-antd-design/references/boundaries.md +30 -0
- package/template/.codex/skills/yss-antd-design/references/cli-matrix.md +38 -0
- package/template/.codex/skills/yss-antd-design/references/evidence.md +26 -0
- package/template/.codex/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
- package/template/.codex/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
- package/template/.codex/skills/yss-design-system/SKILL.md +9 -5
- package/template/.codex/skills/yss-design-system/references/design-qa-theme.md +64 -0
- package/template/.codex/skills/yss-design-system/references/design-system.md +20 -12
- package/template/.codex/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
- package/template/.codex/skills/yss-prototype-stage/SKILL.md +3 -1
- package/template/.codex/skills/yss-ui/SKILL.md +1 -1
- package/template/.cursor/skills/high-fidelity-html-prototype/SKILL.md +1 -18
- package/template/.cursor/skills/llm-wiki/SKILL.md +60 -0
- package/template/.cursor/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
- package/template/.cursor/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
- package/template/.cursor/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
- package/template/.cursor/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
- package/template/.cursor/skills/llm-wiki/assets/fixtures/broken-wiki/wiki//345/255/230/345/234/250/347/232/204/351/241/265.md +7 -0
- package/template/.cursor/skills/llm-wiki/references/compile.md +126 -0
- package/template/.cursor/skills/llm-wiki/references/discover.md +41 -0
- package/template/.cursor/skills/llm-wiki/references/ingest.md +36 -0
- package/template/.cursor/skills/llm-wiki/references/lint.md +54 -0
- package/template/.cursor/skills/llm-wiki/references/query.md +21 -0
- package/template/.cursor/skills/llm-wiki/references/schema.md +45 -0
- package/template/.cursor/skills/llm-wiki/references/writing.md +35 -0
- package/template/.cursor/skills/llm-wiki/scripts/advise.mjs +196 -0
- package/template/.cursor/skills/llm-wiki/scripts/advise.test.mjs +91 -0
- package/template/.cursor/skills/llm-wiki/scripts/extract.mjs +55 -0
- package/template/.cursor/skills/llm-wiki/scripts/extract.test.mjs +34 -0
- package/template/.cursor/skills/llm-wiki/scripts/inventory.mjs +174 -0
- package/template/.cursor/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
- package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
- package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
- package/template/.cursor/skills/yss-antd-design/SKILL.md +34 -0
- package/template/.cursor/skills/yss-antd-design/references/boundaries.md +30 -0
- package/template/.cursor/skills/yss-antd-design/references/cli-matrix.md +38 -0
- package/template/.cursor/skills/yss-antd-design/references/evidence.md +26 -0
- package/template/.cursor/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
- package/template/.cursor/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
- package/template/.cursor/skills/yss-design-system/SKILL.md +9 -5
- package/template/.cursor/skills/yss-design-system/references/design-qa-theme.md +64 -0
- package/template/.cursor/skills/yss-design-system/references/design-system.md +20 -12
- package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
- package/template/.cursor/skills/yss-prototype-stage/SKILL.md +3 -1
- package/template/.cursor/skills/yss-ui/SKILL.md +1 -1
- package/template/.hermes/skills/high-fidelity-html-prototype/SKILL.md +1 -18
- package/template/.hermes/skills/llm-wiki/SKILL.md +60 -0
- package/template/.hermes/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
- package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
- package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
- package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
- package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki//345/255/230/345/234/250/347/232/204/351/241/265.md +7 -0
- package/template/.hermes/skills/llm-wiki/references/compile.md +126 -0
- package/template/.hermes/skills/llm-wiki/references/discover.md +41 -0
- package/template/.hermes/skills/llm-wiki/references/ingest.md +36 -0
- package/template/.hermes/skills/llm-wiki/references/lint.md +54 -0
- package/template/.hermes/skills/llm-wiki/references/query.md +21 -0
- package/template/.hermes/skills/llm-wiki/references/schema.md +45 -0
- package/template/.hermes/skills/llm-wiki/references/writing.md +35 -0
- package/template/.hermes/skills/llm-wiki/scripts/advise.mjs +196 -0
- package/template/.hermes/skills/llm-wiki/scripts/advise.test.mjs +91 -0
- package/template/.hermes/skills/llm-wiki/scripts/extract.mjs +55 -0
- package/template/.hermes/skills/llm-wiki/scripts/extract.test.mjs +34 -0
- package/template/.hermes/skills/llm-wiki/scripts/inventory.mjs +174 -0
- package/template/.hermes/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
- package/template/.hermes/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
- package/template/.hermes/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
- package/template/.hermes/skills/yss-antd-design/SKILL.md +34 -0
- package/template/.hermes/skills/yss-antd-design/references/boundaries.md +30 -0
- package/template/.hermes/skills/yss-antd-design/references/cli-matrix.md +38 -0
- package/template/.hermes/skills/yss-antd-design/references/evidence.md +26 -0
- package/template/.hermes/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
- package/template/.hermes/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
- package/template/.hermes/skills/yss-design-system/SKILL.md +9 -5
- package/template/.hermes/skills/yss-design-system/references/design-qa-theme.md +64 -0
- package/template/.hermes/skills/yss-design-system/references/design-system.md +20 -12
- package/template/.hermes/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.hermes/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
- package/template/.hermes/skills/yss-prototype-stage/SKILL.md +3 -1
- package/template/.hermes/skills/yss-ui/SKILL.md +1 -1
- package/template/.pi/skills/high-fidelity-html-prototype/SKILL.md +1 -18
- package/template/.pi/skills/llm-wiki/SKILL.md +60 -0
- package/template/.pi/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
- package/template/.pi/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
- package/template/.pi/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
- package/template/.pi/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
- package/template/.pi/skills/llm-wiki/assets/fixtures/broken-wiki/wiki//345/255/230/345/234/250/347/232/204/351/241/265.md +7 -0
- package/template/.pi/skills/llm-wiki/references/compile.md +126 -0
- package/template/.pi/skills/llm-wiki/references/discover.md +41 -0
- package/template/.pi/skills/llm-wiki/references/ingest.md +36 -0
- package/template/.pi/skills/llm-wiki/references/lint.md +54 -0
- package/template/.pi/skills/llm-wiki/references/query.md +21 -0
- package/template/.pi/skills/llm-wiki/references/schema.md +45 -0
- package/template/.pi/skills/llm-wiki/references/writing.md +35 -0
- package/template/.pi/skills/llm-wiki/scripts/advise.mjs +196 -0
- package/template/.pi/skills/llm-wiki/scripts/advise.test.mjs +91 -0
- package/template/.pi/skills/llm-wiki/scripts/extract.mjs +55 -0
- package/template/.pi/skills/llm-wiki/scripts/extract.test.mjs +34 -0
- package/template/.pi/skills/llm-wiki/scripts/inventory.mjs +174 -0
- package/template/.pi/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
- package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
- package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
- package/template/.pi/skills/yss-antd-design/SKILL.md +34 -0
- package/template/.pi/skills/yss-antd-design/references/boundaries.md +30 -0
- package/template/.pi/skills/yss-antd-design/references/cli-matrix.md +38 -0
- package/template/.pi/skills/yss-antd-design/references/evidence.md +26 -0
- package/template/.pi/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
- package/template/.pi/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
- package/template/.pi/skills/yss-design-system/SKILL.md +9 -5
- package/template/.pi/skills/yss-design-system/references/design-qa-theme.md +64 -0
- package/template/.pi/skills/yss-design-system/references/design-system.md +20 -12
- package/template/.pi/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
- package/template/.pi/skills/yss-prototype-stage/SKILL.md +3 -1
- package/template/.pi/skills/yss-ui/SKILL.md +1 -1
- package/template/.qoder/skills/high-fidelity-html-prototype/SKILL.md +1 -18
- package/template/.qoder/skills/llm-wiki/SKILL.md +60 -0
- package/template/.qoder/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
- package/template/.qoder/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
- package/template/.qoder/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
- package/template/.qoder/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
- package/template/.qoder/skills/llm-wiki/assets/fixtures/broken-wiki/wiki//345/255/230/345/234/250/347/232/204/351/241/265.md +7 -0
- package/template/.qoder/skills/llm-wiki/references/compile.md +126 -0
- package/template/.qoder/skills/llm-wiki/references/discover.md +41 -0
- package/template/.qoder/skills/llm-wiki/references/ingest.md +36 -0
- package/template/.qoder/skills/llm-wiki/references/lint.md +54 -0
- package/template/.qoder/skills/llm-wiki/references/query.md +21 -0
- package/template/.qoder/skills/llm-wiki/references/schema.md +45 -0
- package/template/.qoder/skills/llm-wiki/references/writing.md +35 -0
- package/template/.qoder/skills/llm-wiki/scripts/advise.mjs +196 -0
- package/template/.qoder/skills/llm-wiki/scripts/advise.test.mjs +91 -0
- package/template/.qoder/skills/llm-wiki/scripts/extract.mjs +55 -0
- package/template/.qoder/skills/llm-wiki/scripts/extract.test.mjs +34 -0
- package/template/.qoder/skills/llm-wiki/scripts/inventory.mjs +174 -0
- package/template/.qoder/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
- package/template/.qoder/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
- package/template/.qoder/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
- package/template/.qoder/skills/yss-antd-design/SKILL.md +34 -0
- package/template/.qoder/skills/yss-antd-design/references/boundaries.md +30 -0
- package/template/.qoder/skills/yss-antd-design/references/cli-matrix.md +38 -0
- package/template/.qoder/skills/yss-antd-design/references/evidence.md +26 -0
- package/template/.qoder/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
- package/template/.qoder/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
- package/template/.qoder/skills/yss-design-system/SKILL.md +9 -5
- package/template/.qoder/skills/yss-design-system/references/design-qa-theme.md +64 -0
- package/template/.qoder/skills/yss-design-system/references/design-system.md +20 -12
- package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
- package/template/.qoder/skills/yss-prototype-stage/SKILL.md +3 -1
- package/template/.qoder/skills/yss-ui/SKILL.md +1 -1
- package/template/.trae/skills/high-fidelity-html-prototype/SKILL.md +1 -18
- package/template/.trae/skills/llm-wiki/SKILL.md +60 -0
- package/template/.trae/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
- package/template/.trae/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
- package/template/.trae/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
- package/template/.trae/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
- package/template/.trae/skills/llm-wiki/assets/fixtures/broken-wiki/wiki//345/255/230/345/234/250/347/232/204/351/241/265.md +7 -0
- package/template/.trae/skills/llm-wiki/references/compile.md +126 -0
- package/template/.trae/skills/llm-wiki/references/discover.md +41 -0
- package/template/.trae/skills/llm-wiki/references/ingest.md +36 -0
- package/template/.trae/skills/llm-wiki/references/lint.md +54 -0
- package/template/.trae/skills/llm-wiki/references/query.md +21 -0
- package/template/.trae/skills/llm-wiki/references/schema.md +45 -0
- package/template/.trae/skills/llm-wiki/references/writing.md +35 -0
- package/template/.trae/skills/llm-wiki/scripts/advise.mjs +196 -0
- package/template/.trae/skills/llm-wiki/scripts/advise.test.mjs +91 -0
- package/template/.trae/skills/llm-wiki/scripts/extract.mjs +55 -0
- package/template/.trae/skills/llm-wiki/scripts/extract.test.mjs +34 -0
- package/template/.trae/skills/llm-wiki/scripts/inventory.mjs +174 -0
- package/template/.trae/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
- package/template/.trae/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
- package/template/.trae/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
- package/template/.trae/skills/yss-antd-design/SKILL.md +34 -0
- package/template/.trae/skills/yss-antd-design/references/boundaries.md +30 -0
- package/template/.trae/skills/yss-antd-design/references/cli-matrix.md +38 -0
- package/template/.trae/skills/yss-antd-design/references/evidence.md +26 -0
- package/template/.trae/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
- package/template/.trae/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
- package/template/.trae/skills/yss-design-system/SKILL.md +9 -5
- package/template/.trae/skills/yss-design-system/references/design-qa-theme.md +64 -0
- package/template/.trae/skills/yss-design-system/references/design-system.md +20 -12
- package/template/.trae/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
- package/template/.trae/skills/yss-prototype-stage/SKILL.md +3 -1
- package/template/.trae/skills/yss-ui/SKILL.md +1 -1
- package/template/AGENTS.md +4 -2
- package/template/CLAUDE.md +13 -0
- package/template/CONTEXT.md +2 -0
- package/template/docs/agents/yss-skill-registry.yaml +12 -0
- package/template/docs/design/README.md +5 -5
- package/template/docs/design/design.md +94 -29
- package/template/docs/design/templates/prototype-evidence-template.yaml +12 -1
- package/template/docs/design/tokens/theme.json +16 -9
- package/template/docs/design/tokens/tokens.compact.json +35 -32
- package/template/docs/design/tokens/tokens.dark.json +5 -5
- package/template/docs/design/tokens/tokens.default.json +41 -32
- package/template/docs/design/tokens/variables.css +62 -37
- package/template/docs/design/tokens/variables.dark.css +5 -5
- package/template/docs/process/implementation-repo-integration.md +9 -0
- package/template/docs/user-guide//344/272/247/345/223/201/347/240/224/345/217/221/345/205/250/347/224/237/345/221/275/345/221/250/346/234/237/346/234/200/344/275/263/345/256/236/350/267/265.md +3 -3
- package/template/skills-lock.json +37 -5
- package/template/wiki/.wiki-manifest.json +390 -0
- package/template/wiki/raw/AGENTS.md +42 -61
- package/template/wiki/raw/CONTEXT.md +27 -1
- package/template/wiki/raw/README.md +4 -1
- package/template/wiki/raw/create-yss-spec-repository-mode-contract.md +95 -0
- package/template/wiki/raw/harness-process-tailoring.md +64 -0
- package/template/wiki/raw/implementation-repo-integration.md +62 -0
- package/template/wiki/raw/issue-tracker.md +135 -0
- package/template/wiki/raw/lifecycle-registry.yaml +369 -0
- package/template/wiki/raw/maintenance-intensity.yaml +25 -0
- package/template/wiki/raw/skills-lock-names.md +92 -0
- package/template/wiki/raw/skills-maintenance.md +90 -0
- package/template/wiki/raw/spec-template.md +3 -4
- package/template/wiki/raw/triage-labels.md +15 -0
- package/template/wiki/raw/vertical-slice-ticket-template.md +14 -8
- package/template/wiki/raw/yss-skill-registry.yaml +504 -0
- package/template/wiki/wiki/Agent/345/205/245/345/217/243/350/247/204/345/210/231.md +17 -5
- package/template/wiki/wiki/CLAUDE.md +15 -11
- package/template/wiki/wiki/Fresh/351/252/214/350/257/201/344/270/216/347/213/254/347/253/213/345/256/241/346/237/245.md +15 -5
- package/template/wiki/wiki/LLM Wiki.md +30 -0
- package/template/wiki/wiki/Matt/346/212/200/350/203/275/344/275/223/347/263/273.md +17 -5
- package/template/wiki/wiki/OpenAPI/345/245/221/347/272/246.md +16 -5
- package/template/wiki/wiki/SpecDelta.md +15 -5
- package/template/wiki/wiki/Spec/345/237/272/347/272/277.md +18 -5
- package/template/wiki/wiki/Ticket/344/270/216/346/265/201/347/250/213/347/212/266/346/200/201.md +17 -5
- package/template/wiki/wiki/YSS/345/267/245/347/250/213/346/212/200/350/203/275/344/275/223/347/263/273.md +19 -5
- package/template/wiki/wiki/YSS/350/267/257/347/224/261/344/270/216/345/220/210/345/220/214/347/274/226/350/257/221.md +16 -5
- package/template/wiki/wiki/concept-table.md +9 -0
- package/template/wiki/wiki/index.md +12 -11
- package/template/wiki/wiki/log.md +27 -0
- package/template/wiki/wiki//344/272/247/345/223/201/347/240/224/345/217/221/347/224/237/345/221/275/345/221/250/346/234/237.md +15 -4
- package/template/wiki/wiki//344/272/247/345/223/201/350/256/276/350/256/241/345/275/261/345/223/215/344/270/216/345/216/237/345/236/213.md +14 -4
- package/template/wiki/wiki//344/273/223/345/272/223/350/272/253/344/273/275/344/270/216/350/267/257/347/224/261.md +15 -4
- package/template/wiki/wiki//345/210/207/347/211/207/345/256/236/347/216/260/345/220/210/345/220/214.md +17 -5
- package/template/wiki/wiki//345/236/202/347/233/264/345/210/207/347/211/207Ticket.md +19 -5
- package/template/wiki/wiki//345/244/215/347/233/230/344/270/216/346/235/203/345/250/201/350/265/204/344/272/247/344/277/256/350/256/242.md +15 -4
- package/template/wiki/wiki//345/256/236/347/216/260/344/273/223/345/272/223/344/270/216/350/267/250/344/273/223/345/272/223/345/245/221/347/272/246.md +17 -4
- package/template/wiki/wiki//345/275/261/345/223/215/351/235/242/345/210/206/350/257/212/344/270/216/346/265/201/347/250/213/350/243/201/345/211/252.md +15 -4
- package/template/wiki/wiki//346/212/200/350/203/275/346/212/225/345/275/261/344/270/216/351/224/201/345/256/232.md +18 -4
- package/template/wiki/wiki//346/235/241/344/273/266/345/274/272/345/210/266/351/227/250/347/246/201.md +13 -4
- package/template/wiki/wiki//346/250/241/346/235/277/345/217/221/345/270/203/351/227/250/347/246/201/344/270/216/351/252/214/350/257/201.md +17 -4
- package/template/wiki/wiki//346/250/241/346/235/277/346/200/273/350/247/210.md +16 -5
- package/template/wiki/wiki//346/250/241/346/235/277/347/273/264/346/212/244/346/265/201/347/250/213.md +14 -4
- package/template/yss-public-skills.json +2 -0
- package/template.snapshot.json +4 -4
- package/template/wiki/raw/create-yss-spec-contract.md +0 -59
- package/template/wiki/raw/skills-lock.json +0 -1379
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { mkdir, mkdtemp, writeFile } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { drift, hashSources, sha256, unmappedCandidates } from "./inventory.mjs";
|
|
9
|
+
|
|
10
|
+
const inventoryCli = fileURLToPath(new URL("./inventory.mjs", import.meta.url));
|
|
11
|
+
|
|
12
|
+
async function seed() {
|
|
13
|
+
const repo = await mkdtemp(path.join(tmpdir(), "llm-wiki-inv-"));
|
|
14
|
+
const wiki = path.join(repo, "wiki-root");
|
|
15
|
+
await mkdir(path.join(wiki, "raw"), { recursive: true });
|
|
16
|
+
const liveRel = "docs/api.md";
|
|
17
|
+
const live = path.join(repo, liveRel);
|
|
18
|
+
await mkdir(path.dirname(live), { recursive: true });
|
|
19
|
+
await writeFile(live, "v1\n", "utf8");
|
|
20
|
+
await writeFile(
|
|
21
|
+
path.join(wiki, ".wiki-manifest.json"),
|
|
22
|
+
JSON.stringify({
|
|
23
|
+
schemaVersion: 1,
|
|
24
|
+
wikiRoot: "wiki-root",
|
|
25
|
+
profile: "documents",
|
|
26
|
+
sources: [
|
|
27
|
+
{
|
|
28
|
+
id: "api.md",
|
|
29
|
+
kind: "document",
|
|
30
|
+
livePath: liveRel,
|
|
31
|
+
rawPath: "raw/api.md",
|
|
32
|
+
sha256: "",
|
|
33
|
+
role: "copy",
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
articles: [
|
|
37
|
+
{ id: "API契约", file: "wiki/API契约.md", sourceIds: ["api.md"], humanOwned: false },
|
|
38
|
+
{ id: "人工页", file: "wiki/人工页.md", sourceIds: ["api.md"], humanOwned: true },
|
|
39
|
+
],
|
|
40
|
+
}),
|
|
41
|
+
"utf8",
|
|
42
|
+
);
|
|
43
|
+
return { repo, wiki, live, liveRel };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
test("hash-sources fills sha256; drift is empty until live file changes", async () => {
|
|
47
|
+
const { repo, wiki, live } = await seed();
|
|
48
|
+
const hashed = await hashSources({ wikiRoot: wiki, repoRoot: repo, now: "2026-01-01T00:00:00Z" });
|
|
49
|
+
assert.equal(hashed.missing.length, 0);
|
|
50
|
+
assert.equal(hashed.manifest.sources[0].sha256, sha256(Buffer.from("v1\n")));
|
|
51
|
+
const clean = await drift({ wikiRoot: wiki, repoRoot: repo });
|
|
52
|
+
assert.deepEqual(clean.changed, []);
|
|
53
|
+
assert.deepEqual(clean.articles, []);
|
|
54
|
+
await writeFile(live, "v2\n", "utf8");
|
|
55
|
+
const dirty = await drift({ wikiRoot: wiki, repoRoot: repo });
|
|
56
|
+
assert.deepEqual(dirty.changed, ["api.md"]);
|
|
57
|
+
assert.deepEqual(dirty.articles, ["API契约", "人工页"]);
|
|
58
|
+
assert.deepEqual(dirty.humanOwned, ["人工页"]);
|
|
59
|
+
assert.deepEqual(dirty.unmapped, []);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("unmapped candidates are listed without scanning the tree", () => {
|
|
63
|
+
const sources = [{ livePath: "docs/api.md" }];
|
|
64
|
+
assert.deepEqual(unmappedCandidates(sources, ["docs/api.md", "docs/new.md", "./docs/new.md"]), [
|
|
65
|
+
"docs/new.md",
|
|
66
|
+
]);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("drift CLI exits 0 when sources changed and prints JSON", async () => {
|
|
70
|
+
const { repo, wiki, live } = await seed();
|
|
71
|
+
await hashSources({ wikiRoot: wiki, repoRoot: repo, now: "2026-01-01T00:00:00Z" });
|
|
72
|
+
await writeFile(live, "v2\n", "utf8");
|
|
73
|
+
const ran = spawnSync(process.execPath, [inventoryCli, "drift", "--wiki", wiki, "--repo", repo], {
|
|
74
|
+
encoding: "utf8",
|
|
75
|
+
});
|
|
76
|
+
assert.equal(ran.status, 0, ran.stderr);
|
|
77
|
+
const report = JSON.parse(ran.stdout);
|
|
78
|
+
assert.deepEqual(report.changed, ["api.md"]);
|
|
79
|
+
assert.deepEqual(report.articles, ["API契约", "人工页"]);
|
|
80
|
+
assert.deepEqual(report.humanOwned, ["人工页"]);
|
|
81
|
+
assert.deepEqual(report.unmapped, []);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("status CLI exits 0 and lists unmapped candidates", async () => {
|
|
85
|
+
const { repo, wiki, live } = await seed();
|
|
86
|
+
await hashSources({ wikiRoot: wiki, repoRoot: repo, now: "2026-01-01T00:00:00Z" });
|
|
87
|
+
await writeFile(live, "v2\n", "utf8");
|
|
88
|
+
const ran = spawnSync(
|
|
89
|
+
process.execPath,
|
|
90
|
+
[inventoryCli, "status", "--wiki", wiki, "--repo", repo, "--candidate", "docs/extra.md"],
|
|
91
|
+
{ encoding: "utf8" },
|
|
92
|
+
);
|
|
93
|
+
assert.equal(ran.status, 0, ran.stderr);
|
|
94
|
+
const report = JSON.parse(ran.stdout);
|
|
95
|
+
assert.deepEqual(report.changed, ["api.md"]);
|
|
96
|
+
assert.deepEqual(report.unmapped, ["docs/extra.md"]);
|
|
97
|
+
assert.deepEqual(report.humanOwned, ["人工页"]);
|
|
98
|
+
});
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { EXTRACT_KINDS } from "./extract.mjs";
|
|
6
|
+
import { exists, sha256 } from "./inventory.mjs";
|
|
7
|
+
|
|
8
|
+
export const INFRA = new Set([
|
|
9
|
+
"index.md",
|
|
10
|
+
"log.md",
|
|
11
|
+
"claude.md",
|
|
12
|
+
"agents.md",
|
|
13
|
+
"soul.md",
|
|
14
|
+
"concept-table.md",
|
|
15
|
+
]);
|
|
16
|
+
const WIKILINK_RE = /\[\[([^\]|#]+)(?:[|#][^\]]*)?\]\]/g;
|
|
17
|
+
const SOURCE_HEADING_RE = /^##\s+来源\s*$/m;
|
|
18
|
+
const H1_RE = /^#\s+(.+?)\s*$/m;
|
|
19
|
+
|
|
20
|
+
export function articlesDir(wikiRoot) {
|
|
21
|
+
return path.join(wikiRoot, "wiki");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function extractLinks(text) {
|
|
25
|
+
const ids = [];
|
|
26
|
+
const invalid = [];
|
|
27
|
+
WIKILINK_RE.lastIndex = 0;
|
|
28
|
+
let match;
|
|
29
|
+
while ((match = WIKILINK_RE.exec(text))) {
|
|
30
|
+
const target = match[1].trim();
|
|
31
|
+
if (!target) continue;
|
|
32
|
+
if (target.startsWith("../") || target.includes("/")) {
|
|
33
|
+
invalid.push(target);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
ids.push(target);
|
|
37
|
+
}
|
|
38
|
+
return { ids, invalid };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function lintWiki(wikiRoot, { repoRoot = process.cwd() } = {}) {
|
|
42
|
+
const dir = articlesDir(wikiRoot);
|
|
43
|
+
if (!(await exists(path.join(dir, "index.md")))) {
|
|
44
|
+
return { ok: false, errors: [`missing ${path.join(dir, "index.md")}`], counts: {} };
|
|
45
|
+
}
|
|
46
|
+
const names = (await readdir(dir)).filter((name) => name.endsWith(".md"));
|
|
47
|
+
const articleFiles = names.filter((name) => !INFRA.has(name.toLowerCase()));
|
|
48
|
+
const articleIds = new Set(articleFiles.map((name) => name.slice(0, -3)));
|
|
49
|
+
const errors = [];
|
|
50
|
+
let linkCount = 0;
|
|
51
|
+
|
|
52
|
+
const indexText = await readFile(path.join(dir, "index.md"), "utf8");
|
|
53
|
+
const indexLinks = extractLinks(indexText);
|
|
54
|
+
linkCount += indexLinks.ids.length;
|
|
55
|
+
for (const target of indexLinks.invalid) errors.push(`CROSS-WIKI (index): [[${target}]]`);
|
|
56
|
+
const indexed = new Set();
|
|
57
|
+
for (const id of indexLinks.ids) {
|
|
58
|
+
indexed.add(id);
|
|
59
|
+
if (!articleIds.has(id)) errors.push(`MISSING (index): [[${id}]]`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const file of articleFiles) {
|
|
63
|
+
const id = file.slice(0, -3);
|
|
64
|
+
const text = await readFile(path.join(dir, file), "utf8");
|
|
65
|
+
const heading = text.match(H1_RE);
|
|
66
|
+
if (!heading || heading[1] !== id) errors.push(`H1 MISMATCH: ${file} expected # ${id}`);
|
|
67
|
+
if (!SOURCE_HEADING_RE.test(text)) errors.push(`NO SOURCE SECTION: ${file}`);
|
|
68
|
+
if (!indexed.has(id)) errors.push(`ORPHAN: ${file}`);
|
|
69
|
+
const links = extractLinks(text);
|
|
70
|
+
for (const target of links.invalid) errors.push(`CROSS-WIKI: ${file} -> [[${target}]]`);
|
|
71
|
+
for (const target of links.ids) {
|
|
72
|
+
linkCount += 1;
|
|
73
|
+
if (!articleIds.has(target)) errors.push(`MISSING: ${file} -> [[${target}]]`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const manifestFile = path.join(wikiRoot, ".wiki-manifest.json");
|
|
78
|
+
if (await exists(manifestFile)) {
|
|
79
|
+
const manifest = JSON.parse(await readFile(manifestFile, "utf8"));
|
|
80
|
+
const sourceById = new Map();
|
|
81
|
+
for (const source of manifest.sources || []) {
|
|
82
|
+
if (source?.id) sourceById.set(source.id, source);
|
|
83
|
+
}
|
|
84
|
+
const listedFiles = new Set();
|
|
85
|
+
for (const article of manifest.articles || []) {
|
|
86
|
+
const rel = path.posix.normalize(article.file || "");
|
|
87
|
+
listedFiles.add(rel);
|
|
88
|
+
const expectedId = path.posix.basename(rel, ".md");
|
|
89
|
+
if (article.id !== expectedId) {
|
|
90
|
+
errors.push(`MANIFEST ID MISMATCH: ${article.file} id=${article.id} expected ${expectedId}`);
|
|
91
|
+
}
|
|
92
|
+
const file = path.resolve(wikiRoot, article.file);
|
|
93
|
+
if (!(await exists(file))) errors.push(`MANIFEST ARTICLE MISSING: ${article.file}`);
|
|
94
|
+
for (const sourceId of article.sourceIds || []) {
|
|
95
|
+
if (!sourceById.has(sourceId)) {
|
|
96
|
+
errors.push(`UNKNOWN SOURCE ID: ${article.id} -> ${sourceId}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const file of articleFiles) {
|
|
101
|
+
const rel = path.posix.join("wiki", file);
|
|
102
|
+
if (!listedFiles.has(rel)) errors.push(`UNLISTED ARTICLE: ${file}`);
|
|
103
|
+
}
|
|
104
|
+
for (const source of manifest.sources || []) {
|
|
105
|
+
if (manifest.profile === "documents" && source.kind === "code-surface") {
|
|
106
|
+
errors.push(`PROFILE KIND: documents forbids code-surface (${source.id})`);
|
|
107
|
+
}
|
|
108
|
+
if (source.kind === "document" || source.kind === "derived") {
|
|
109
|
+
if (!source.rawPath) {
|
|
110
|
+
errors.push(`RAW PATH REQUIRED: ${source.id} (${source.kind})`);
|
|
111
|
+
} else {
|
|
112
|
+
const raw = path.resolve(wikiRoot, source.rawPath);
|
|
113
|
+
if (!(await exists(raw))) errors.push(`RAW MISSING: ${source.id} (${source.rawPath})`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (source.kind === "derived") {
|
|
117
|
+
const extractKind = source.extract?.kind;
|
|
118
|
+
if (!extractKind) errors.push(`EXTRACT REQUIRED: ${source.id}`);
|
|
119
|
+
else if (!EXTRACT_KINDS.includes(extractKind)) {
|
|
120
|
+
errors.push(`EXTRACT KIND: ${source.id} (${extractKind})`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (source.kind === "code-surface" && source.rawPath != null) {
|
|
124
|
+
errors.push(`RAW PATH FORBIDDEN: ${source.id} (code-surface)`);
|
|
125
|
+
}
|
|
126
|
+
if (!source.livePath) continue;
|
|
127
|
+
const live = path.resolve(repoRoot, source.livePath);
|
|
128
|
+
if (!(await exists(live))) {
|
|
129
|
+
errors.push(`MANIFEST SOURCE MISSING: ${source.id} (${source.livePath})`);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const current = sha256(await readFile(live));
|
|
133
|
+
if (!source.sha256 || current !== source.sha256) {
|
|
134
|
+
errors.push(`STALE HASH: ${source.id} (${source.livePath})`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
ok: errors.length === 0,
|
|
141
|
+
errors,
|
|
142
|
+
counts: { articles: articleFiles.length, links: linkCount },
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function main(argv = process.argv.slice(2)) {
|
|
147
|
+
let wikiArg;
|
|
148
|
+
let repoRoot = process.cwd();
|
|
149
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
150
|
+
if (argv[i] === "--repo") repoRoot = argv[++i];
|
|
151
|
+
else if (!wikiArg && !argv[i].startsWith("-")) wikiArg = argv[i];
|
|
152
|
+
}
|
|
153
|
+
repoRoot = path.resolve(repoRoot);
|
|
154
|
+
if (!wikiArg) {
|
|
155
|
+
throw new Error("usage: lint-wikilinks.mjs <wiki-root> [--repo <repo-root>]");
|
|
156
|
+
}
|
|
157
|
+
const wikiRoot = path.resolve(repoRoot, wikiArg);
|
|
158
|
+
const result = await lintWiki(wikiRoot, { repoRoot });
|
|
159
|
+
for (const error of result.errors) process.stdout.write(`${error}\n`);
|
|
160
|
+
process.stdout.write(
|
|
161
|
+
`校验完成:${result.counts.articles || 0} 篇文章,${result.counts.links || 0} 条 wikilink\n`,
|
|
162
|
+
);
|
|
163
|
+
if (result.ok) process.stdout.write("通过:所有 wikilink / 来源 / 索引检查通过\n");
|
|
164
|
+
else {
|
|
165
|
+
process.stdout.write(
|
|
166
|
+
"失败:存在缺失的 wikilink、孤儿页、来源小节、跨路径链接、H1 或 manifest 闭合问题\n",
|
|
167
|
+
);
|
|
168
|
+
process.exitCode = 1;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
173
|
+
main().catch((error) => {
|
|
174
|
+
process.stderr.write(`${error.message}\n`);
|
|
175
|
+
process.exitCode = 2;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdir, mkdtemp, writeFile } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { sha256 } from "./inventory.mjs";
|
|
8
|
+
import { lintWiki } from "./lint-wikilinks.mjs";
|
|
9
|
+
|
|
10
|
+
const skillRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
|
+
const broken = path.join(skillRoot, "assets/fixtures/broken-wiki");
|
|
12
|
+
|
|
13
|
+
test("broken fixture fails on dangling wikilink", async () => {
|
|
14
|
+
const result = await lintWiki(broken);
|
|
15
|
+
assert.equal(result.ok, false);
|
|
16
|
+
assert.ok(result.errors.some((line) => line.includes("[[不存在的页]]")));
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("complete wiki passes wikilink, index, and source-section checks", async () => {
|
|
20
|
+
const root = await mkdtemp(path.join(tmpdir(), "llm-wiki-lint-"));
|
|
21
|
+
const wiki = path.join(root, "wiki");
|
|
22
|
+
await mkdir(wiki, { recursive: true });
|
|
23
|
+
await writeFile(
|
|
24
|
+
path.join(wiki, "index.md"),
|
|
25
|
+
"# index\n\n## 分类\n\n- [[Alpha]]\n",
|
|
26
|
+
"utf8",
|
|
27
|
+
);
|
|
28
|
+
await writeFile(
|
|
29
|
+
path.join(wiki, "Alpha.md"),
|
|
30
|
+
"# Alpha\n\nSee [[Alpha]].\n\n## 来源\n\n- live\n",
|
|
31
|
+
"utf8",
|
|
32
|
+
);
|
|
33
|
+
await writeFile(path.join(wiki, "CLAUDE.md"), "# schema\n", "utf8");
|
|
34
|
+
const result = await lintWiki(root);
|
|
35
|
+
assert.equal(result.ok, true, result.errors.join("\n"));
|
|
36
|
+
assert.equal(result.counts.articles, 1);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("cross-path wikilink fails instead of being ignored", async () => {
|
|
40
|
+
const root = await mkdtemp(path.join(tmpdir(), "llm-wiki-cross-"));
|
|
41
|
+
const wiki = path.join(root, "wiki");
|
|
42
|
+
await mkdir(wiki, { recursive: true });
|
|
43
|
+
await writeFile(path.join(wiki, "index.md"), "# index\n\n## 分类\n\n- [[Alpha]]\n", "utf8");
|
|
44
|
+
await writeFile(
|
|
45
|
+
path.join(wiki, "Alpha.md"),
|
|
46
|
+
"# Alpha\n\nSee [[../other]]\n\n## 来源\n\n- live\n",
|
|
47
|
+
"utf8",
|
|
48
|
+
);
|
|
49
|
+
const result = await lintWiki(root);
|
|
50
|
+
assert.equal(result.ok, false);
|
|
51
|
+
assert.ok(result.errors.some((line) => line.includes("CROSS-WIKI") && line.includes("[[../other]]")));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("manifest sha256 mismatch is stale", async () => {
|
|
55
|
+
const repo = await mkdtemp(path.join(tmpdir(), "llm-wiki-hash-"));
|
|
56
|
+
const wikiRoot = path.join(repo, "wiki-root");
|
|
57
|
+
const wiki = path.join(wikiRoot, "wiki");
|
|
58
|
+
await mkdir(wiki, { recursive: true });
|
|
59
|
+
await mkdir(path.join(wikiRoot, "raw"), { recursive: true });
|
|
60
|
+
await mkdir(path.join(repo, "docs"), { recursive: true });
|
|
61
|
+
const liveRel = "docs/api.md";
|
|
62
|
+
await writeFile(path.join(repo, liveRel), "v2\n", "utf8");
|
|
63
|
+
await writeFile(path.join(wikiRoot, "raw", "api.md"), "v1\n", "utf8");
|
|
64
|
+
await writeFile(path.join(wiki, "index.md"), "# index\n\n## 分类\n\n- [[API]]\n", "utf8");
|
|
65
|
+
await writeFile(path.join(wiki, "API.md"), "# API\n\nSummary.\n\n## 来源\n\n- live\n", "utf8");
|
|
66
|
+
await writeFile(
|
|
67
|
+
path.join(wikiRoot, ".wiki-manifest.json"),
|
|
68
|
+
JSON.stringify({
|
|
69
|
+
schemaVersion: 1,
|
|
70
|
+
sources: [
|
|
71
|
+
{
|
|
72
|
+
id: "api.md",
|
|
73
|
+
kind: "document",
|
|
74
|
+
livePath: liveRel,
|
|
75
|
+
rawPath: "raw/api.md",
|
|
76
|
+
sha256: sha256(Buffer.from("v1\n")),
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
articles: [{ id: "API", file: "wiki/API.md", sourceIds: ["api.md"] }],
|
|
80
|
+
}),
|
|
81
|
+
"utf8",
|
|
82
|
+
);
|
|
83
|
+
const result = await lintWiki(wikiRoot, { repoRoot: repo });
|
|
84
|
+
assert.equal(result.ok, false);
|
|
85
|
+
assert.ok(result.errors.some((line) => line.includes("STALE HASH") && line.includes("api.md")));
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
async function seedClosedWiki() {
|
|
89
|
+
const repo = await mkdtemp(path.join(tmpdir(), "llm-wiki-closed-"));
|
|
90
|
+
const wikiRoot = path.join(repo, "wiki-root");
|
|
91
|
+
const wiki = path.join(wikiRoot, "wiki");
|
|
92
|
+
await mkdir(wiki, { recursive: true });
|
|
93
|
+
await mkdir(path.join(wikiRoot, "raw"), { recursive: true });
|
|
94
|
+
await mkdir(path.join(repo, "docs"), { recursive: true });
|
|
95
|
+
const liveRel = "docs/api.md";
|
|
96
|
+
await writeFile(path.join(repo, liveRel), "v1\n", "utf8");
|
|
97
|
+
await writeFile(path.join(wikiRoot, "raw", "api.md"), "v1\n", "utf8");
|
|
98
|
+
await writeFile(path.join(wiki, "index.md"), "# index\n\n## 分类\n\n- [[Alpha]]\n", "utf8");
|
|
99
|
+
await writeFile(
|
|
100
|
+
path.join(wiki, "Alpha.md"),
|
|
101
|
+
"# Alpha\n\nSee [[Alpha]].\n\n## 来源\n\n- live\n",
|
|
102
|
+
"utf8",
|
|
103
|
+
);
|
|
104
|
+
const manifest = {
|
|
105
|
+
schemaVersion: 1,
|
|
106
|
+
profile: "documents",
|
|
107
|
+
sources: [
|
|
108
|
+
{
|
|
109
|
+
id: "api.md",
|
|
110
|
+
kind: "document",
|
|
111
|
+
livePath: liveRel,
|
|
112
|
+
rawPath: "raw/api.md",
|
|
113
|
+
sha256: sha256(Buffer.from("v1\n")),
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
articles: [{ id: "Alpha", file: "wiki/Alpha.md", sourceIds: ["api.md"] }],
|
|
117
|
+
};
|
|
118
|
+
await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
|
|
119
|
+
return { repo, wikiRoot, wiki, manifest };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
test("closed manifest passes listing, id, sourceIds, profile, and rawPath checks", async () => {
|
|
123
|
+
const { repo, wikiRoot } = await seedClosedWiki();
|
|
124
|
+
const result = await lintWiki(wikiRoot, { repoRoot: repo });
|
|
125
|
+
assert.equal(result.ok, true, result.errors.join("\n"));
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("open manifest fails unlisted article, id mismatch, unknown source, profile kind, and rawPath", async () => {
|
|
129
|
+
const repo = await mkdtemp(path.join(tmpdir(), "llm-wiki-open-"));
|
|
130
|
+
const wikiRoot = path.join(repo, "wiki-root");
|
|
131
|
+
const wiki = path.join(wikiRoot, "wiki");
|
|
132
|
+
await mkdir(wiki, { recursive: true });
|
|
133
|
+
await mkdir(path.join(repo, "docs"), { recursive: true });
|
|
134
|
+
await writeFile(path.join(repo, "docs", "api.md"), "v1\n", "utf8");
|
|
135
|
+
await writeFile(path.join(wiki, "index.md"), "# index\n\n## 分类\n\n- [[Alpha]]\n- [[Beta]]\n", "utf8");
|
|
136
|
+
await writeFile(path.join(wiki, "Alpha.md"), "# Alpha\n\nSee [[Beta]].\n\n## 来源\n\n- live\n", "utf8");
|
|
137
|
+
await writeFile(path.join(wiki, "Beta.md"), "# Beta\n\nSee [[Alpha]].\n\n## 来源\n\n- live\n", "utf8");
|
|
138
|
+
await writeFile(
|
|
139
|
+
path.join(wikiRoot, ".wiki-manifest.json"),
|
|
140
|
+
JSON.stringify({
|
|
141
|
+
schemaVersion: 1,
|
|
142
|
+
profile: "documents",
|
|
143
|
+
sources: [
|
|
144
|
+
{
|
|
145
|
+
id: "api.md",
|
|
146
|
+
kind: "code-surface",
|
|
147
|
+
livePath: "docs/api.md",
|
|
148
|
+
rawPath: "raw/should-not-exist.md",
|
|
149
|
+
sha256: sha256(Buffer.from("v1\n")),
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: "note",
|
|
153
|
+
kind: "document",
|
|
154
|
+
livePath: "docs/api.md",
|
|
155
|
+
rawPath: "",
|
|
156
|
+
sha256: sha256(Buffer.from("v1\n")),
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
articles: [
|
|
160
|
+
{
|
|
161
|
+
id: "WrongId",
|
|
162
|
+
file: "wiki/Alpha.md",
|
|
163
|
+
sourceIds: ["api.md", "ghost"],
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
}),
|
|
167
|
+
"utf8",
|
|
168
|
+
);
|
|
169
|
+
const result = await lintWiki(wikiRoot, { repoRoot: repo });
|
|
170
|
+
assert.equal(result.ok, false);
|
|
171
|
+
assert.ok(result.errors.some((line) => line.includes("UNLISTED ARTICLE") && line.includes("Beta.md")));
|
|
172
|
+
assert.ok(result.errors.some((line) => line.includes("MANIFEST ID MISMATCH") && line.includes("WrongId")));
|
|
173
|
+
assert.ok(result.errors.some((line) => line.includes("UNKNOWN SOURCE ID") && line.includes("ghost")));
|
|
174
|
+
assert.ok(result.errors.some((line) => line.includes("PROFILE KIND") && line.includes("code-surface")));
|
|
175
|
+
assert.ok(result.errors.some((line) => line.includes("RAW PATH REQUIRED") && line.includes("note")));
|
|
176
|
+
assert.ok(result.errors.some((line) => line.includes("RAW PATH FORBIDDEN") && line.includes("api.md")));
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test("derived source requires a known extract.kind", async () => {
|
|
180
|
+
const { repo, wikiRoot, manifest } = await seedClosedWiki();
|
|
181
|
+
manifest.sources.push({
|
|
182
|
+
id: "lock",
|
|
183
|
+
kind: "derived",
|
|
184
|
+
livePath: "docs/api.md",
|
|
185
|
+
rawPath: "raw/api.md",
|
|
186
|
+
sha256: sha256(Buffer.from("v1\n")),
|
|
187
|
+
});
|
|
188
|
+
await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
|
|
189
|
+
const missing = await lintWiki(wikiRoot, { repoRoot: repo });
|
|
190
|
+
assert.equal(missing.ok, false);
|
|
191
|
+
assert.ok(missing.errors.some((line) => line.includes("EXTRACT REQUIRED") && line.includes("lock")));
|
|
192
|
+
|
|
193
|
+
manifest.sources.at(-1).extract = { kind: "whole-file" };
|
|
194
|
+
await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
|
|
195
|
+
const unknown = await lintWiki(wikiRoot, { repoRoot: repo });
|
|
196
|
+
assert.equal(unknown.ok, false);
|
|
197
|
+
assert.ok(unknown.errors.some((line) => line.includes("EXTRACT KIND") && line.includes("whole-file")));
|
|
198
|
+
|
|
199
|
+
manifest.sources.at(-1).extract = { kind: "skill-names" };
|
|
200
|
+
await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
|
|
201
|
+
const ok = await lintWiki(wikiRoot, { repoRoot: repo });
|
|
202
|
+
assert.equal(ok.ok, true, ok.errors.join("\n"));
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("document rawPath must exist on disk", async () => {
|
|
206
|
+
const { repo, wikiRoot, manifest } = await seedClosedWiki();
|
|
207
|
+
manifest.sources[0].rawPath = "raw/missing.md";
|
|
208
|
+
await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
|
|
209
|
+
const result = await lintWiki(wikiRoot, { repoRoot: repo });
|
|
210
|
+
assert.equal(result.ok, false);
|
|
211
|
+
assert.ok(result.errors.some((line) => line.includes("RAW MISSING") && line.includes("raw/missing.md")));
|
|
212
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yss-antd-design
|
|
3
|
+
description: Use when 原型设计或高保真构建需要查询 Ant Design v6 设计语言、组件 API/demo/token/semantic,或落盘 AntD CLI 证据。不用于前端代码落地(改用 yss-ui)、Vue 生产 API、生命周期批准、安装官方 antd skill,或替代 yss-prototype-stage。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# YSS Ant Design 事实
|
|
7
|
+
|
|
8
|
+
只服务原型设计与高保真构建。把官方 `@ant-design/cli`、`design.md`、MCP 与 LLMs.txt 收成可追溯的事实引擎。阶段合同仍是 `yss-prototype-stage`。前端代码落地一律改用 `yss-ui`,不要继续调用本技能。
|
|
9
|
+
|
|
10
|
+
## 何时使用
|
|
11
|
+
|
|
12
|
+
- 已进入 `yss-prototype-stage` 的高保真产出前后,需要 Ant Design v6 组件 / token / demo / semantic / 上游 `design.md` 事实。
|
|
13
|
+
- 需要写入 `prototype-evidence.yaml` 的 AntD 段。
|
|
14
|
+
|
|
15
|
+
不要用本技能:前端实现、Vue / Ant Design Vue 生产代码、批准门禁、生成页面流、安装官方 `antd` skill,或运行 `antd setup`。进入实现切片后停用本技能,改走 `yss-ui`。
|
|
16
|
+
|
|
17
|
+
## 步骤
|
|
18
|
+
|
|
19
|
+
1. 检测 CLI:优先已安装的 `antd`,否则用 `npx -y @ant-design/cli`。记录实际 CLI 版本。不要在模板源执行 `npm install -g`。
|
|
20
|
+
2. 读项目 `docs/design/design.md` 与 `docs/design/tokens/*`。
|
|
21
|
+
3. 选定 `<target_antd_version>`(项目已选的 v6;未选则先查再记录,不得依赖空仓库自动检测)。此后每次知识查询都传同一版本。
|
|
22
|
+
4. 设置 `ANTD_NO_AUTO_REPORT=1`。一律 `--format json`,对外说明用 `--lang zh`。
|
|
23
|
+
5. 查询官方 `design.md`,再按选用组件跑 `info` / `demo` / `token` / `semantic`。命令矩阵见 `references/cli-matrix.md`。
|
|
24
|
+
6. 把 JSON 路径写入证据清单。字段与 lint 适用范围见 `references/evidence.md`。
|
|
25
|
+
7. 上游默认与项目 token 冲突时,以项目覆盖为准,并标记 `project_override_reviewed`。
|
|
26
|
+
|
|
27
|
+
## 硬规则
|
|
28
|
+
|
|
29
|
+
- 禁止凭记忆写 Ant Design v6 API。
|
|
30
|
+
- 禁止 `antd setup`、`npx skills add ant-design/ant-design-cli`,以及把官方 `skills/antd` 拷进 `.agents/skills`。
|
|
31
|
+
- 禁止把官方 `design.md` 的默认色、圆角、间距写回项目实现或覆盖项目 token。
|
|
32
|
+
- 禁止在前端代码落地、垂直切片实现或 `yss-ui` 任务中调用本技能。
|
|
33
|
+
- 禁止把 React props / demo / hook 当作 `yss-ui` 或 Ant Design Vue API。
|
|
34
|
+
- MCP 与 `llms-full.txt` 不是门禁证据。边界见 `references/boundaries.md`。
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# 边界与官方资料
|
|
2
|
+
|
|
3
|
+
官方文档只提供 React `antd` 事实,不提供 YSS 阶段合同。入口对照:
|
|
4
|
+
|
|
5
|
+
| 官方资料 | 本技能用法 |
|
|
6
|
+
|---|---|
|
|
7
|
+
| https://ant.design/docs/react/for-agents-cn | 了解 CLI / skill / MCP / LLMs 分层。不要把其中的 “安装 skill” prompt 写进 `AGENTS.md` |
|
|
8
|
+
| https://ant.design/docs/react/cli-cn | 命令与参数的权威说明 |
|
|
9
|
+
| https://ant.design/docs/react/design-md-cn | 上游 `design.md` 定位。项目覆盖是 `docs/design/design.md` |
|
|
10
|
+
| https://ant.design/docs/react/mcp-cn | MCP 是 IDE 加速,8 个知识工具不含 `lint` |
|
|
11
|
+
| https://ant.design/docs/react/llms-cn | CLI 不可用时的降级目录。不要默认注入 `llms-full.txt` |
|
|
12
|
+
| https://ant.design/design.md | 与 `antd design.md` 同一份 v6 上游默认 |
|
|
13
|
+
|
|
14
|
+
## 与其他技能
|
|
15
|
+
|
|
16
|
+
- `yss-prototype-stage`:阶段顺序、评审、浏览器验证、用户确认。本技能只回写 AntD 事实段。
|
|
17
|
+
- `yss-design-system`:项目风格与 token 规范。本技能查询上游事实,不得改项目 token。
|
|
18
|
+
- `product-design:index`:Codex 视觉产出。本技能不替代它,也不使用 `antd-page-generator`。
|
|
19
|
+
- `yss-ui`:前端代码落地的唯一 UI 入口。进入实现后不得再查本技能或 `@ant-design/cli` 的 React API。
|
|
20
|
+
- 官方 `antd` skill:不安装、不锁定、不投影。
|
|
21
|
+
|
|
22
|
+
## MCP 与 LLMs.txt
|
|
23
|
+
|
|
24
|
+
开发者本机可以运行 `npx -y @ant-design/cli mcp --version <target_antd_version> --lang zh`,但:
|
|
25
|
+
|
|
26
|
+
- 不把 `.cursor/mcp.json` 提交为模板默认。
|
|
27
|
+
- 不把 MCP 调用记录当成 `evidence.antd-cli-validation`。
|
|
28
|
+
- `antd-page-generator` 不是原型阶段入口。
|
|
29
|
+
|
|
30
|
+
CLI 不可用时,可用 `https://ant.design/llms.txt` 定位单组件 `.md`,并在证据里写明降级原因。恢复 CLI 后补 JSON 落盘。
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# CLI 命令矩阵
|
|
2
|
+
|
|
3
|
+
运行时入口:已安装的 `antd`,或 `npx -y @ant-design/cli`。记录实际 CLI 版本。知识查询必须带 `--format json`、`--lang zh` 和同一 `<target_antd_version>`。
|
|
4
|
+
|
|
5
|
+
官方命令说明:https://ant.design/docs/react/cli-cn
|
|
6
|
+
|
|
7
|
+
## 允许(原型 / 设计事实)
|
|
8
|
+
|
|
9
|
+
| 命令 | 用途 |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `antd design.md --version <target_antd_version> --lang zh --format json` | 上游默认 Light 主题。只对 antd v6 发布 |
|
|
12
|
+
| `antd list --version <target_antd_version> --format json` | 组件选型 |
|
|
13
|
+
| `antd info <Component> --version <target_antd_version> --format json` | props / 类型 / 默认值 |
|
|
14
|
+
| `antd demo <Component> [name] --version <target_antd_version> --format json` | 可运行 demo 源码(React/TSX) |
|
|
15
|
+
| `antd token <Component> --version <target_antd_version> --format json` | 组件或全局 token |
|
|
16
|
+
| `antd semantic <Component> --version <target_antd_version> --format json` | `classNames` / `styles` 结构 |
|
|
17
|
+
| `antd doc <Component> --version <target_antd_version> --lang zh --format json` | 需要完整文档时 |
|
|
18
|
+
| `antd changelog <v1> <v2> [Component] --format json` | 仅当版本差异影响当前决策 |
|
|
19
|
+
|
|
20
|
+
`design.md` 对 v5 返回 `UNSUPPORTED_VERSION_FEATURE`。空仓库不传 `--version` 时的回退版本不要假设;必须写进证据。
|
|
21
|
+
|
|
22
|
+
## 条件允许
|
|
23
|
+
|
|
24
|
+
| 命令 | 条件 |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `antd lint <tsx-or-src> --format json` | 产物是 React/TSX 源码。HTML 原型不得当作通过 |
|
|
27
|
+
| `antd doctor` / `antd usage` / `antd migrate` | 仅已登记的 React + `antd` 实现仓 |
|
|
28
|
+
| `antd env --format json` | 排障需要环境快照时 |
|
|
29
|
+
|
|
30
|
+
## 默认禁止
|
|
31
|
+
|
|
32
|
+
| 命令 | 原因 |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `antd setup` | 会写入 `.agents/skills/antd` 和 `AGENTS.md`,绕过 `skills-lock.json` |
|
|
35
|
+
| `npx skills add ant-design/ant-design-cli` | 同上,安装官方 skill |
|
|
36
|
+
| `antd bug` / `antd bug-cli` | 与 YSS Ticket 无关。保持 `ANTD_NO_AUTO_REPORT=1` |
|
|
37
|
+
| `antd upgrade` | 不得在模板源或未授权时改动全局 CLI |
|
|
38
|
+
| `antd mcp` 作为证据采集 | MCP 调用默认不落盘,见 `boundaries.md` |
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# AntD 事实证据
|
|
2
|
+
|
|
3
|
+
目标文件:`docs/.scratch/<feature>/verification/prototype-evidence.yaml`,字段以 `docs/design/templates/prototype-evidence-template.yaml` 为准。本文件只说明如何填 AntD 段。
|
|
4
|
+
|
|
5
|
+
## 必填
|
|
6
|
+
|
|
7
|
+
- `antd.cli_command`:实际调用的可执行文件,`antd` 或 `npx -y @ant-design/cli`。
|
|
8
|
+
- `antd.cli_version`:本轮 `antd -V` 或等价输出,禁止写死模板默认值。
|
|
9
|
+
- `antd.target_antd_version`:本轮全部知识查询使用的同一 v6 版本。
|
|
10
|
+
- `antd.queries.design_md`:`antd design.md ... --format json` 的落盘路径。
|
|
11
|
+
- `antd.queries.components[]`:每个选用组件的 `info_ref` / `demo_ref` / `token_ref` / `semantic_ref`。
|
|
12
|
+
- `design_baseline.project_design_ref`:`docs/design/design.md`。
|
|
13
|
+
- `design_baseline.project_override_reviewed`:上游默认与项目 token 已对照。
|
|
14
|
+
|
|
15
|
+
JSON 输出存为相邻文件,证据清单只引用路径。不要把整份 `llms-full.txt` 或 MCP 对话贴进清单。
|
|
16
|
+
|
|
17
|
+
## lint
|
|
18
|
+
|
|
19
|
+
`antd lint` 只对可解析的 React/TSX 源码有规则命中。HTML 原型会出现空 issues(假绿)或 `skippedFiles` / `parse-error` / `partial: true`。
|
|
20
|
+
|
|
21
|
+
| 产物 | `lint_applicable` | 做法 |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `docs/.scratch/<feature>/design/prototypes/index.html` | `not-applicable` | 写 `lint_reason: html-prototype`;`lint_ref` 可空;`lint_passed` 保持 `false`,不得改成 `true` |
|
|
24
|
+
| React/TSX 原型源 | `true` | 对变更文件跑 `antd lint --format json`,保存输出;无 issue 才把 `lint_passed` 设为 `true` |
|
|
25
|
+
|
|
26
|
+
浏览器验证仍由 `yss-prototype-stage` 采集,不在本技能宣布 `gate.prototype-verified` 通过。
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
export function validateFrontmatter(text) {
|
|
7
|
+
const match = /^---\n([\s\S]*?)\n---/.exec(text);
|
|
8
|
+
if (!match) throw new Error("Invalid SKILL.md frontmatter block");
|
|
9
|
+
const fields = new Map();
|
|
10
|
+
for (const line of match[1].split("\n")) {
|
|
11
|
+
if (!line.trim()) continue;
|
|
12
|
+
const index = line.indexOf(":");
|
|
13
|
+
if (index < 0) throw new Error(`Invalid frontmatter line: ${line}`);
|
|
14
|
+
fields.set(line.slice(0, index).trim(), line.slice(index + 1).trim());
|
|
15
|
+
}
|
|
16
|
+
const keys = [...fields.keys()].sort();
|
|
17
|
+
if (keys.join(",") !== "description,name") throw new Error(`Expected keys ['description', 'name'], got ${JSON.stringify(keys)}`);
|
|
18
|
+
const name = fields.get("name");
|
|
19
|
+
const description = fields.get("description");
|
|
20
|
+
if (name !== "yss-antd-design") throw new Error("Invalid skill name: " + name);
|
|
21
|
+
if (!description || description.length > 1024) throw new Error("Description must be present and <= 1024 chars");
|
|
22
|
+
if (!/yss-ui|官方 antd skill|yss-prototype-stage/.test(description)) {
|
|
23
|
+
throw new Error("Description must exclude frontend landing via yss-ui, official antd skill, and stage-contract takeover");
|
|
24
|
+
}
|
|
25
|
+
return name;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function validateSetupBan(text) {
|
|
29
|
+
if (!/禁止 `antd setup`/.test(text)) throw new Error("SKILL.md must forbid antd setup");
|
|
30
|
+
if (!/npx skills add ant-design\/ant-design-cli/.test(text)) throw new Error("SKILL.md must forbid official skill installer");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function main() {
|
|
34
|
+
const skill = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "SKILL.md");
|
|
35
|
+
try {
|
|
36
|
+
const text = await readFile(skill, "utf8");
|
|
37
|
+
const name = validateFrontmatter(text);
|
|
38
|
+
validateSetupBan(text);
|
|
39
|
+
console.log(`${name} frontmatter ok`);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error(error.message);
|
|
42
|
+
process.exitCode = 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main();
|