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.
Files changed (345) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/template/.agents/skills/high-fidelity-html-prototype/SKILL.md +1 -18
  4. package/template/.agents/skills/llm-wiki/SKILL.md +60 -0
  5. package/template/.agents/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
  6. package/template/.agents/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
  7. package/template/.agents/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
  8. package/template/.agents/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
  9. 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
  10. package/template/.agents/skills/llm-wiki/references/compile.md +126 -0
  11. package/template/.agents/skills/llm-wiki/references/discover.md +41 -0
  12. package/template/.agents/skills/llm-wiki/references/ingest.md +36 -0
  13. package/template/.agents/skills/llm-wiki/references/lint.md +54 -0
  14. package/template/.agents/skills/llm-wiki/references/query.md +21 -0
  15. package/template/.agents/skills/llm-wiki/references/schema.md +45 -0
  16. package/template/.agents/skills/llm-wiki/references/writing.md +35 -0
  17. package/template/.agents/skills/llm-wiki/scripts/advise.mjs +196 -0
  18. package/template/.agents/skills/llm-wiki/scripts/advise.test.mjs +91 -0
  19. package/template/.agents/skills/llm-wiki/scripts/extract.mjs +55 -0
  20. package/template/.agents/skills/llm-wiki/scripts/extract.test.mjs +34 -0
  21. package/template/.agents/skills/llm-wiki/scripts/inventory.mjs +174 -0
  22. package/template/.agents/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
  23. package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
  24. package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
  25. package/template/.agents/skills/yss-antd-design/SKILL.md +34 -0
  26. package/template/.agents/skills/yss-antd-design/references/boundaries.md +30 -0
  27. package/template/.agents/skills/yss-antd-design/references/cli-matrix.md +38 -0
  28. package/template/.agents/skills/yss-antd-design/references/evidence.md +26 -0
  29. package/template/.agents/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
  30. package/template/.agents/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
  31. package/template/.agents/skills/yss-design-system/SKILL.md +9 -5
  32. package/template/.agents/skills/yss-design-system/references/design-qa-theme.md +64 -0
  33. package/template/.agents/skills/yss-design-system/references/design-system.md +20 -12
  34. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +1 -1
  35. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
  36. package/template/.agents/skills/yss-prototype-stage/SKILL.md +3 -1
  37. package/template/.agents/skills/yss-ui/SKILL.md +1 -1
  38. package/template/.claude/skills/high-fidelity-html-prototype/SKILL.md +1 -18
  39. package/template/.claude/skills/llm-wiki/SKILL.md +60 -0
  40. package/template/.claude/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
  41. package/template/.claude/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
  42. package/template/.claude/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
  43. package/template/.claude/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
  44. 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
  45. package/template/.claude/skills/llm-wiki/references/compile.md +126 -0
  46. package/template/.claude/skills/llm-wiki/references/discover.md +41 -0
  47. package/template/.claude/skills/llm-wiki/references/ingest.md +36 -0
  48. package/template/.claude/skills/llm-wiki/references/lint.md +54 -0
  49. package/template/.claude/skills/llm-wiki/references/query.md +21 -0
  50. package/template/.claude/skills/llm-wiki/references/schema.md +45 -0
  51. package/template/.claude/skills/llm-wiki/references/writing.md +35 -0
  52. package/template/.claude/skills/llm-wiki/scripts/advise.mjs +196 -0
  53. package/template/.claude/skills/llm-wiki/scripts/advise.test.mjs +91 -0
  54. package/template/.claude/skills/llm-wiki/scripts/extract.mjs +55 -0
  55. package/template/.claude/skills/llm-wiki/scripts/extract.test.mjs +34 -0
  56. package/template/.claude/skills/llm-wiki/scripts/inventory.mjs +174 -0
  57. package/template/.claude/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
  58. package/template/.claude/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
  59. package/template/.claude/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
  60. package/template/.claude/skills/yss-antd-design/SKILL.md +34 -0
  61. package/template/.claude/skills/yss-antd-design/references/boundaries.md +30 -0
  62. package/template/.claude/skills/yss-antd-design/references/cli-matrix.md +38 -0
  63. package/template/.claude/skills/yss-antd-design/references/evidence.md +26 -0
  64. package/template/.claude/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
  65. package/template/.claude/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
  66. package/template/.claude/skills/yss-design-system/SKILL.md +9 -5
  67. package/template/.claude/skills/yss-design-system/references/design-qa-theme.md +64 -0
  68. package/template/.claude/skills/yss-design-system/references/design-system.md +20 -12
  69. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +1 -1
  70. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
  71. package/template/.claude/skills/yss-prototype-stage/SKILL.md +3 -1
  72. package/template/.claude/skills/yss-ui/SKILL.md +1 -1
  73. package/template/.codex/skills/high-fidelity-html-prototype/SKILL.md +1 -18
  74. package/template/.codex/skills/llm-wiki/SKILL.md +60 -0
  75. package/template/.codex/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
  76. package/template/.codex/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
  77. package/template/.codex/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
  78. package/template/.codex/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
  79. 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
  80. package/template/.codex/skills/llm-wiki/references/compile.md +126 -0
  81. package/template/.codex/skills/llm-wiki/references/discover.md +41 -0
  82. package/template/.codex/skills/llm-wiki/references/ingest.md +36 -0
  83. package/template/.codex/skills/llm-wiki/references/lint.md +54 -0
  84. package/template/.codex/skills/llm-wiki/references/query.md +21 -0
  85. package/template/.codex/skills/llm-wiki/references/schema.md +45 -0
  86. package/template/.codex/skills/llm-wiki/references/writing.md +35 -0
  87. package/template/.codex/skills/llm-wiki/scripts/advise.mjs +196 -0
  88. package/template/.codex/skills/llm-wiki/scripts/advise.test.mjs +91 -0
  89. package/template/.codex/skills/llm-wiki/scripts/extract.mjs +55 -0
  90. package/template/.codex/skills/llm-wiki/scripts/extract.test.mjs +34 -0
  91. package/template/.codex/skills/llm-wiki/scripts/inventory.mjs +174 -0
  92. package/template/.codex/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
  93. package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
  94. package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
  95. package/template/.codex/skills/yss-antd-design/SKILL.md +34 -0
  96. package/template/.codex/skills/yss-antd-design/references/boundaries.md +30 -0
  97. package/template/.codex/skills/yss-antd-design/references/cli-matrix.md +38 -0
  98. package/template/.codex/skills/yss-antd-design/references/evidence.md +26 -0
  99. package/template/.codex/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
  100. package/template/.codex/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
  101. package/template/.codex/skills/yss-design-system/SKILL.md +9 -5
  102. package/template/.codex/skills/yss-design-system/references/design-qa-theme.md +64 -0
  103. package/template/.codex/skills/yss-design-system/references/design-system.md +20 -12
  104. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +1 -1
  105. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
  106. package/template/.codex/skills/yss-prototype-stage/SKILL.md +3 -1
  107. package/template/.codex/skills/yss-ui/SKILL.md +1 -1
  108. package/template/.cursor/skills/high-fidelity-html-prototype/SKILL.md +1 -18
  109. package/template/.cursor/skills/llm-wiki/SKILL.md +60 -0
  110. package/template/.cursor/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
  111. package/template/.cursor/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
  112. package/template/.cursor/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
  113. package/template/.cursor/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
  114. 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
  115. package/template/.cursor/skills/llm-wiki/references/compile.md +126 -0
  116. package/template/.cursor/skills/llm-wiki/references/discover.md +41 -0
  117. package/template/.cursor/skills/llm-wiki/references/ingest.md +36 -0
  118. package/template/.cursor/skills/llm-wiki/references/lint.md +54 -0
  119. package/template/.cursor/skills/llm-wiki/references/query.md +21 -0
  120. package/template/.cursor/skills/llm-wiki/references/schema.md +45 -0
  121. package/template/.cursor/skills/llm-wiki/references/writing.md +35 -0
  122. package/template/.cursor/skills/llm-wiki/scripts/advise.mjs +196 -0
  123. package/template/.cursor/skills/llm-wiki/scripts/advise.test.mjs +91 -0
  124. package/template/.cursor/skills/llm-wiki/scripts/extract.mjs +55 -0
  125. package/template/.cursor/skills/llm-wiki/scripts/extract.test.mjs +34 -0
  126. package/template/.cursor/skills/llm-wiki/scripts/inventory.mjs +174 -0
  127. package/template/.cursor/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
  128. package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
  129. package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
  130. package/template/.cursor/skills/yss-antd-design/SKILL.md +34 -0
  131. package/template/.cursor/skills/yss-antd-design/references/boundaries.md +30 -0
  132. package/template/.cursor/skills/yss-antd-design/references/cli-matrix.md +38 -0
  133. package/template/.cursor/skills/yss-antd-design/references/evidence.md +26 -0
  134. package/template/.cursor/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
  135. package/template/.cursor/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
  136. package/template/.cursor/skills/yss-design-system/SKILL.md +9 -5
  137. package/template/.cursor/skills/yss-design-system/references/design-qa-theme.md +64 -0
  138. package/template/.cursor/skills/yss-design-system/references/design-system.md +20 -12
  139. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +1 -1
  140. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
  141. package/template/.cursor/skills/yss-prototype-stage/SKILL.md +3 -1
  142. package/template/.cursor/skills/yss-ui/SKILL.md +1 -1
  143. package/template/.hermes/skills/high-fidelity-html-prototype/SKILL.md +1 -18
  144. package/template/.hermes/skills/llm-wiki/SKILL.md +60 -0
  145. package/template/.hermes/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
  146. package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
  147. package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
  148. package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
  149. 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
  150. package/template/.hermes/skills/llm-wiki/references/compile.md +126 -0
  151. package/template/.hermes/skills/llm-wiki/references/discover.md +41 -0
  152. package/template/.hermes/skills/llm-wiki/references/ingest.md +36 -0
  153. package/template/.hermes/skills/llm-wiki/references/lint.md +54 -0
  154. package/template/.hermes/skills/llm-wiki/references/query.md +21 -0
  155. package/template/.hermes/skills/llm-wiki/references/schema.md +45 -0
  156. package/template/.hermes/skills/llm-wiki/references/writing.md +35 -0
  157. package/template/.hermes/skills/llm-wiki/scripts/advise.mjs +196 -0
  158. package/template/.hermes/skills/llm-wiki/scripts/advise.test.mjs +91 -0
  159. package/template/.hermes/skills/llm-wiki/scripts/extract.mjs +55 -0
  160. package/template/.hermes/skills/llm-wiki/scripts/extract.test.mjs +34 -0
  161. package/template/.hermes/skills/llm-wiki/scripts/inventory.mjs +174 -0
  162. package/template/.hermes/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
  163. package/template/.hermes/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
  164. package/template/.hermes/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
  165. package/template/.hermes/skills/yss-antd-design/SKILL.md +34 -0
  166. package/template/.hermes/skills/yss-antd-design/references/boundaries.md +30 -0
  167. package/template/.hermes/skills/yss-antd-design/references/cli-matrix.md +38 -0
  168. package/template/.hermes/skills/yss-antd-design/references/evidence.md +26 -0
  169. package/template/.hermes/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
  170. package/template/.hermes/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
  171. package/template/.hermes/skills/yss-design-system/SKILL.md +9 -5
  172. package/template/.hermes/skills/yss-design-system/references/design-qa-theme.md +64 -0
  173. package/template/.hermes/skills/yss-design-system/references/design-system.md +20 -12
  174. package/template/.hermes/skills/yss-product-lifecycle/SKILL.md +1 -1
  175. package/template/.hermes/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
  176. package/template/.hermes/skills/yss-prototype-stage/SKILL.md +3 -1
  177. package/template/.hermes/skills/yss-ui/SKILL.md +1 -1
  178. package/template/.pi/skills/high-fidelity-html-prototype/SKILL.md +1 -18
  179. package/template/.pi/skills/llm-wiki/SKILL.md +60 -0
  180. package/template/.pi/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
  181. package/template/.pi/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
  182. package/template/.pi/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
  183. package/template/.pi/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
  184. 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
  185. package/template/.pi/skills/llm-wiki/references/compile.md +126 -0
  186. package/template/.pi/skills/llm-wiki/references/discover.md +41 -0
  187. package/template/.pi/skills/llm-wiki/references/ingest.md +36 -0
  188. package/template/.pi/skills/llm-wiki/references/lint.md +54 -0
  189. package/template/.pi/skills/llm-wiki/references/query.md +21 -0
  190. package/template/.pi/skills/llm-wiki/references/schema.md +45 -0
  191. package/template/.pi/skills/llm-wiki/references/writing.md +35 -0
  192. package/template/.pi/skills/llm-wiki/scripts/advise.mjs +196 -0
  193. package/template/.pi/skills/llm-wiki/scripts/advise.test.mjs +91 -0
  194. package/template/.pi/skills/llm-wiki/scripts/extract.mjs +55 -0
  195. package/template/.pi/skills/llm-wiki/scripts/extract.test.mjs +34 -0
  196. package/template/.pi/skills/llm-wiki/scripts/inventory.mjs +174 -0
  197. package/template/.pi/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
  198. package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
  199. package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
  200. package/template/.pi/skills/yss-antd-design/SKILL.md +34 -0
  201. package/template/.pi/skills/yss-antd-design/references/boundaries.md +30 -0
  202. package/template/.pi/skills/yss-antd-design/references/cli-matrix.md +38 -0
  203. package/template/.pi/skills/yss-antd-design/references/evidence.md +26 -0
  204. package/template/.pi/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
  205. package/template/.pi/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
  206. package/template/.pi/skills/yss-design-system/SKILL.md +9 -5
  207. package/template/.pi/skills/yss-design-system/references/design-qa-theme.md +64 -0
  208. package/template/.pi/skills/yss-design-system/references/design-system.md +20 -12
  209. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +1 -1
  210. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
  211. package/template/.pi/skills/yss-prototype-stage/SKILL.md +3 -1
  212. package/template/.pi/skills/yss-ui/SKILL.md +1 -1
  213. package/template/.qoder/skills/high-fidelity-html-prototype/SKILL.md +1 -18
  214. package/template/.qoder/skills/llm-wiki/SKILL.md +60 -0
  215. package/template/.qoder/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
  216. package/template/.qoder/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
  217. package/template/.qoder/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
  218. package/template/.qoder/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
  219. 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
  220. package/template/.qoder/skills/llm-wiki/references/compile.md +126 -0
  221. package/template/.qoder/skills/llm-wiki/references/discover.md +41 -0
  222. package/template/.qoder/skills/llm-wiki/references/ingest.md +36 -0
  223. package/template/.qoder/skills/llm-wiki/references/lint.md +54 -0
  224. package/template/.qoder/skills/llm-wiki/references/query.md +21 -0
  225. package/template/.qoder/skills/llm-wiki/references/schema.md +45 -0
  226. package/template/.qoder/skills/llm-wiki/references/writing.md +35 -0
  227. package/template/.qoder/skills/llm-wiki/scripts/advise.mjs +196 -0
  228. package/template/.qoder/skills/llm-wiki/scripts/advise.test.mjs +91 -0
  229. package/template/.qoder/skills/llm-wiki/scripts/extract.mjs +55 -0
  230. package/template/.qoder/skills/llm-wiki/scripts/extract.test.mjs +34 -0
  231. package/template/.qoder/skills/llm-wiki/scripts/inventory.mjs +174 -0
  232. package/template/.qoder/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
  233. package/template/.qoder/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
  234. package/template/.qoder/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
  235. package/template/.qoder/skills/yss-antd-design/SKILL.md +34 -0
  236. package/template/.qoder/skills/yss-antd-design/references/boundaries.md +30 -0
  237. package/template/.qoder/skills/yss-antd-design/references/cli-matrix.md +38 -0
  238. package/template/.qoder/skills/yss-antd-design/references/evidence.md +26 -0
  239. package/template/.qoder/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
  240. package/template/.qoder/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
  241. package/template/.qoder/skills/yss-design-system/SKILL.md +9 -5
  242. package/template/.qoder/skills/yss-design-system/references/design-qa-theme.md +64 -0
  243. package/template/.qoder/skills/yss-design-system/references/design-system.md +20 -12
  244. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +1 -1
  245. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
  246. package/template/.qoder/skills/yss-prototype-stage/SKILL.md +3 -1
  247. package/template/.qoder/skills/yss-ui/SKILL.md +1 -1
  248. package/template/.trae/skills/high-fidelity-html-prototype/SKILL.md +1 -18
  249. package/template/.trae/skills/llm-wiki/SKILL.md +60 -0
  250. package/template/.trae/skills/llm-wiki/assets/CLAUDE.md.template +26 -0
  251. package/template/.trae/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +3 -0
  252. package/template/.trae/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +5 -0
  253. package/template/.trae/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +1 -0
  254. 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
  255. package/template/.trae/skills/llm-wiki/references/compile.md +126 -0
  256. package/template/.trae/skills/llm-wiki/references/discover.md +41 -0
  257. package/template/.trae/skills/llm-wiki/references/ingest.md +36 -0
  258. package/template/.trae/skills/llm-wiki/references/lint.md +54 -0
  259. package/template/.trae/skills/llm-wiki/references/query.md +21 -0
  260. package/template/.trae/skills/llm-wiki/references/schema.md +45 -0
  261. package/template/.trae/skills/llm-wiki/references/writing.md +35 -0
  262. package/template/.trae/skills/llm-wiki/scripts/advise.mjs +196 -0
  263. package/template/.trae/skills/llm-wiki/scripts/advise.test.mjs +91 -0
  264. package/template/.trae/skills/llm-wiki/scripts/extract.mjs +55 -0
  265. package/template/.trae/skills/llm-wiki/scripts/extract.test.mjs +34 -0
  266. package/template/.trae/skills/llm-wiki/scripts/inventory.mjs +174 -0
  267. package/template/.trae/skills/llm-wiki/scripts/inventory.test.mjs +98 -0
  268. package/template/.trae/skills/llm-wiki/scripts/lint-wikilinks.mjs +177 -0
  269. package/template/.trae/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +212 -0
  270. package/template/.trae/skills/yss-antd-design/SKILL.md +34 -0
  271. package/template/.trae/skills/yss-antd-design/references/boundaries.md +30 -0
  272. package/template/.trae/skills/yss-antd-design/references/cli-matrix.md +38 -0
  273. package/template/.trae/skills/yss-antd-design/references/evidence.md +26 -0
  274. package/template/.trae/skills/yss-antd-design/scripts/validate-frontmatter.mjs +46 -0
  275. package/template/.trae/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +27 -0
  276. package/template/.trae/skills/yss-design-system/SKILL.md +9 -5
  277. package/template/.trae/skills/yss-design-system/references/design-qa-theme.md +64 -0
  278. package/template/.trae/skills/yss-design-system/references/design-system.md +20 -12
  279. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +1 -1
  280. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +1 -1
  281. package/template/.trae/skills/yss-prototype-stage/SKILL.md +3 -1
  282. package/template/.trae/skills/yss-ui/SKILL.md +1 -1
  283. package/template/AGENTS.md +4 -2
  284. package/template/CLAUDE.md +13 -0
  285. package/template/CONTEXT.md +2 -0
  286. package/template/docs/agents/yss-skill-registry.yaml +12 -0
  287. package/template/docs/design/README.md +5 -5
  288. package/template/docs/design/design.md +94 -29
  289. package/template/docs/design/templates/prototype-evidence-template.yaml +12 -1
  290. package/template/docs/design/tokens/theme.json +16 -9
  291. package/template/docs/design/tokens/tokens.compact.json +35 -32
  292. package/template/docs/design/tokens/tokens.dark.json +5 -5
  293. package/template/docs/design/tokens/tokens.default.json +41 -32
  294. package/template/docs/design/tokens/variables.css +62 -37
  295. package/template/docs/design/tokens/variables.dark.css +5 -5
  296. package/template/docs/process/implementation-repo-integration.md +9 -0
  297. 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
  298. package/template/skills-lock.json +37 -5
  299. package/template/wiki/.wiki-manifest.json +390 -0
  300. package/template/wiki/raw/AGENTS.md +42 -61
  301. package/template/wiki/raw/CONTEXT.md +27 -1
  302. package/template/wiki/raw/README.md +4 -1
  303. package/template/wiki/raw/create-yss-spec-repository-mode-contract.md +95 -0
  304. package/template/wiki/raw/harness-process-tailoring.md +64 -0
  305. package/template/wiki/raw/implementation-repo-integration.md +62 -0
  306. package/template/wiki/raw/issue-tracker.md +135 -0
  307. package/template/wiki/raw/lifecycle-registry.yaml +369 -0
  308. package/template/wiki/raw/maintenance-intensity.yaml +25 -0
  309. package/template/wiki/raw/skills-lock-names.md +92 -0
  310. package/template/wiki/raw/skills-maintenance.md +90 -0
  311. package/template/wiki/raw/spec-template.md +3 -4
  312. package/template/wiki/raw/triage-labels.md +15 -0
  313. package/template/wiki/raw/vertical-slice-ticket-template.md +14 -8
  314. package/template/wiki/raw/yss-skill-registry.yaml +504 -0
  315. package/template/wiki/wiki/Agent/345/205/245/345/217/243/350/247/204/345/210/231.md +17 -5
  316. package/template/wiki/wiki/CLAUDE.md +15 -11
  317. 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
  318. package/template/wiki/wiki/LLM Wiki.md +30 -0
  319. package/template/wiki/wiki/Matt/346/212/200/350/203/275/344/275/223/347/263/273.md +17 -5
  320. package/template/wiki/wiki/OpenAPI/345/245/221/347/272/246.md +16 -5
  321. package/template/wiki/wiki/SpecDelta.md +15 -5
  322. package/template/wiki/wiki/Spec/345/237/272/347/272/277.md +18 -5
  323. package/template/wiki/wiki/Ticket/344/270/216/346/265/201/347/250/213/347/212/266/346/200/201.md +17 -5
  324. 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
  325. 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
  326. package/template/wiki/wiki/concept-table.md +9 -0
  327. package/template/wiki/wiki/index.md +12 -11
  328. package/template/wiki/wiki/log.md +27 -0
  329. 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
  330. 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
  331. 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
  332. 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
  333. package/template/wiki/wiki//345/236/202/347/233/264/345/210/207/347/211/207Ticket.md +19 -5
  334. 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
  335. 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
  336. 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
  337. 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
  338. 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
  339. 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
  340. package/template/wiki/wiki//346/250/241/346/235/277/346/200/273/350/247/210.md +16 -5
  341. 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
  342. package/template/yss-public-skills.json +2 -0
  343. package/template.snapshot.json +4 -4
  344. package/template/wiki/raw/create-yss-spec-contract.md +0 -59
  345. package/template/wiki/raw/skills-lock.json +0 -1379
@@ -0,0 +1,21 @@
1
+ # Query
2
+
3
+ Query is not a compile mode. It reads the wiki; it does not write `raw/`, articles, `index.md`, `log.md`, or `.wiki-manifest.json`.
4
+
5
+ Use this algorithm when the user asks a repository question and a wiki exists, or asks to answer from the wiki. Do not open the whole corpus, and do not treat wiki prose as live fact.
6
+
7
+ ## Steps
8
+
9
+ 1. **Detect.** If `wiki/index.md` is absent, say the question is outside query: no wiki exists. Suggest `init`. Stop.
10
+
11
+ 2. **Freshness.** If `.wiki-manifest.json` exists, run `inventory.mjs status --wiki <wiki-root>` (same JSON as `drift`). Read `changed`, `missing`, `unchanged`, `articles`, `unmapped`, `humanOwned`. Exit `0` is a valid report, not a failure. Exit `2` is a script error. Show that source-status table. Non-empty `changed` or `missing` means stale: name those sources, ask whether to `refresh`, and do not present drifted pages as current fact. If the user still wants an answer, mark every claim that depends on a drifted source as stale.
12
+
13
+ 3. **Select pages.** First match proper nouns and distinctive terms against `index.md` category headings (`##`) and `[[wikilink]]` targets. If that set is empty or clearly too narrow for the question, search H1 and the first paragraph of each non-infrastructure `wiki/*.md` with the question's distinctive terms and obvious synonyms (`rg` is enough; do not build an index). Open at most `N = min(8, hit count)` articles. Do not open the whole wiki. Do not answer from one summary paragraph when more hit pages exist.
14
+
15
+ 4. **Verify claims.** For each assertion, re-read the live paths in that page's `## 来源` (repo-relative live files, not the wiki sentence). If wiki text conflicts with live, cite live and record wiki drift. Do not rewrite the wiki during query. Do not ingest.
16
+
17
+ 5. **Zero hits.** Only after **both** the index/`[[wikilink]]` pass and the H1/summary search are empty may you say the wiki does not cover the question. List the index categories considered and the search terms used. Do not invent article ids, pages, or facts.
18
+
19
+ ## Done when
20
+
21
+ The answer cites the pages actually opened and the live sources actually re-read, or it states non-coverage. Query never completes via lint, `CREATE`, `REFRESH`, `REBUILD`, or `INGEST`.
@@ -0,0 +1,45 @@
1
+ # Wiki schema
2
+
3
+ Karpathy three-layer wiki. Detectable by `index.md`, `[[wikilink]]`, optional `raw/`, and `CLAUDE.md` or `AGENTS.md`.
4
+
5
+ ## Layers
6
+
7
+ - **raw/** — immutable sources. The agent reads them; it does not edit them to "fix" facts. Wrong facts are fixed by recompiling the wiki from live paths. Allowed contents: copies of documents, and derived extracts that name their live inputs and an `extract` recipe (see [compile.md](compile.md)).
8
+ - **wiki/** — LLM-owned markdown. Humans read; the agent writes. Article id = filename without `.md`, globally unique. Infrastructure files are not articles: `index.md`, `log.md`, `CLAUDE.md`, `AGENTS.md`, `soul.md`, `concept-table.md`.
9
+ - **schema** — `wiki/CLAUDE.md` (this repo also accepts `AGENTS.md`). Conventions for ingest, refresh, rebuild, and lint. Co-evolve it with the domain; start from `assets/CLAUDE.md.template`.
10
+ - **.wiki-manifest.json** — compile graph, sibling of `raw/` and `wiki/`. Not an article. Not a raw source.
11
+
12
+ ## index.md
13
+
14
+ `##` headings are categories (taxonomy). Listed `[[wikilink]]` assign articles to categories. Categories come from index headings, not filename prefixes.
15
+
16
+ ## log.md
17
+
18
+ Append-only. Format: `## [YYYY-MM-DD] OPERATION | 描述`
19
+
20
+ Operations: `CREATE` `UPDATE` `LINK` `FIX` `REFRESH` `REBUILD` `RETIRE` `LINT` `INGEST`.
21
+
22
+ ## concept-table.md
23
+
24
+ Optional. Infrastructure, same class as `index.md`. A table of concept, relationship, and article id. Rebuild may rewrite it. Do not move articles into `wiki/entities/`.
25
+
26
+ ## Articles
27
+
28
+ 1. `# H1` then a one-paragraph summary (parsers use this as summary).
29
+ 2. Body uses `[[ArticleId]]`. Target must be a wiki article filename without `.md`.
30
+ 3. Every claim traces to `raw/` or a live code path. End with a `## 来源` section.
31
+ 4. Optional YAML frontmatter: `human-owned: true` — refresh/rebuild must not rewrite the body; they may fix wikilinks only.
32
+ 5. Optional `## Status` when multiple `sourceIds` disagree, or live disagrees with old raw:
33
+
34
+ ```markdown
35
+ ## Status
36
+ - kind: Disputed | Outdated
37
+ - sources: <sourceId>, <sourceId>
38
+ - note: one-line conflict
39
+ ```
40
+
41
+ Do not write Status when a single live source is correct. Refresh that finds a conflict keeps both citations and the Status block; it must not silently overwrite with the newest live text and pretend there was no conflict. `human-owned` pages do not get a Status rewrite. Status is not an article id and is not an index category. Missing Status is not a lint failure.
42
+
43
+ ## Language
44
+
45
+ Body language follows the host project's document-language rule. Keep identifiers, enums, table names, API paths, and filenames verbatim.
@@ -0,0 +1,35 @@
1
+ # Writing
2
+
3
+ ## Page shape
4
+
5
+ - `# H1` immediately followed by a summary paragraph.
6
+ - `[[ArticleId]]` only; no relative `[[../other-wiki]]` inside a Karpathy wiki (cross-wiki use markdown links).
7
+ - Close with `## 来源` listing raw files and live code paths actually read.
8
+ - Optional `## Status` only when cited sources conflict or live disagrees with old raw. See [schema.md](schema.md). Missing Status is not a defect.
9
+ - Do not invent enum values, table names, or endpoints. If unread, write「见源码」.
10
+
11
+ ## Fact order
12
+
13
+ 1. Called implementation (application service, domain method, mapper SQL).
14
+ 2. Table comments / OpenAPI / config defaults.
15
+ 3. Stale raw copies.
16
+
17
+ A column default is not proof the runtime uses it. A freeze OpenAPI is not the full controller surface.
18
+
19
+ ## Coverage
20
+
21
+ Core pages: deep (state machines, HTTP semantics, transactions). Extension pages: overview (models, enums, tables, links). Match the user's coverage choice from init.
22
+
23
+ ## Subagents
24
+
25
+ When 2+ article groups have no shared files:
26
+
27
+ - Each prompt lists exact write paths. Those agents must not touch `index.md`, `log.md`, `.wiki-manifest.json`, or `CLAUDE.md`.
28
+ - Return: paths written + wikilink count per file.
29
+ - Orchestrator merges, lints, samples facts, appends log.
30
+
31
+ When article groups share no files, dispatch parallel subagents with disjoint write scopes.
32
+
33
+ ## Human-owned
34
+
35
+ Frontmatter `human-owned: true` or manifest `humanOwned: true`. Refresh/rebuild leave the body; they may repair `[[wikilink]]` targets only. Do not add or rewrite `## Status` on these pages.
@@ -0,0 +1,196 @@
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 { exists } from "./inventory.mjs";
6
+ import { articlesDir, extractLinks, INFRA } from "./lint-wikilinks.mjs";
7
+
8
+ const SOURCE_HEADING_RE = /^##\s+来源\s*$/m;
9
+ const H1_RE = /^#\s+(.+?)\s*$/m;
10
+ const NUMBER_RE = /\b\d+(?:\.\d+)?[A-Za-z%]+\b/g;
11
+ const ISO_DATE_RE = /\b\d{4}-\d{2}-\d{2}\b/g;
12
+ const LONG_QUOTE_RE = /[“"]([^”"]{12,})[”"]/g;
13
+ const BACKTICK_RE = /`([^`\n]{2,64})`/g;
14
+ const BOLD_RE = /\*\*([^*]{2,32})\*\*/g;
15
+ const HEADING_RE = /^#{2,6}\s+(.+)$/gm;
16
+
17
+ export function sourceSection(text) {
18
+ const match = text.match(SOURCE_HEADING_RE);
19
+ if (!match) return "";
20
+ return text.slice(match.index + match[0].length);
21
+ }
22
+
23
+ export function firstParagraph(text) {
24
+ const afterH1 = text.replace(/^---[\s\S]*?---\s*/, "").replace(H1_RE, "").trimStart();
25
+ const block = afterH1.split(/\n\s*\n/)[0] || "";
26
+ return block.trim();
27
+ }
28
+
29
+ export function articleBody(text) {
30
+ const source = text.search(SOURCE_HEADING_RE);
31
+ const head = source === -1 ? text : text.slice(0, source);
32
+ return head.replace(/^---[\s\S]*?---\s*/, "");
33
+ }
34
+
35
+ export function highSignalLiterals(text) {
36
+ const found = new Set();
37
+ for (const match of text.matchAll(NUMBER_RE)) found.add(match[0]);
38
+ for (const match of text.matchAll(ISO_DATE_RE)) found.add(match[0]);
39
+ for (const match of text.matchAll(LONG_QUOTE_RE)) found.add(match[1]);
40
+ return [...found];
41
+ }
42
+
43
+ function addTerm(counter, term) {
44
+ const value = term.trim();
45
+ if (!value) return;
46
+ counter.set(value, (counter.get(value) || 0) + 1);
47
+ }
48
+
49
+ export function collectTerms(text) {
50
+ const body = articleBody(text);
51
+ const counter = new Map();
52
+ for (const match of body.matchAll(BACKTICK_RE)) addTerm(counter, match[1]);
53
+ for (const match of body.matchAll(BOLD_RE)) addTerm(counter, match[1]);
54
+ for (const match of body.matchAll(HEADING_RE)) addTerm(counter, match[1]);
55
+ return counter;
56
+ }
57
+
58
+ export async function loadArticles(wikiRoot) {
59
+ const dir = articlesDir(wikiRoot);
60
+ const names = (await readdir(dir)).filter((name) => name.endsWith(".md"));
61
+ const files = names.filter((name) => !INFRA.has(name.toLowerCase()));
62
+ const articles = [];
63
+ for (const file of files) {
64
+ const text = await readFile(path.join(dir, file), "utf8");
65
+ articles.push({
66
+ id: file.slice(0, -3),
67
+ file,
68
+ text,
69
+ links: extractLinks(text).ids,
70
+ });
71
+ }
72
+ return articles;
73
+ }
74
+
75
+ export function oneWayLinks(articles) {
76
+ const inbound = new Map();
77
+ for (const article of articles) inbound.set(article.id, new Set());
78
+ for (const article of articles) {
79
+ for (const target of article.links) {
80
+ if (!inbound.has(target)) continue;
81
+ inbound.get(target).add(article.id);
82
+ }
83
+ }
84
+ const findings = [];
85
+ for (const article of articles) {
86
+ for (const target of new Set(article.links)) {
87
+ if (target === article.id) continue;
88
+ if (!inbound.has(target)) continue;
89
+ if (inbound.get(article.id).has(target)) continue;
90
+ findings.push({ from: article.id, to: target });
91
+ }
92
+ }
93
+ return findings;
94
+ }
95
+
96
+ export function missingTermPages(articles) {
97
+ const ids = new Set(articles.map((article) => article.id));
98
+ const counts = new Map();
99
+ for (const article of articles) {
100
+ const local = collectTerms(article.text);
101
+ for (const [term, count] of local) {
102
+ if (ids.has(term)) continue;
103
+ counts.set(term, (counts.get(term) || 0) + count);
104
+ }
105
+ }
106
+ return [...counts.entries()]
107
+ .filter(([, count]) => count >= 2)
108
+ .map(([term, count]) => ({ term, count }))
109
+ .sort((a, b) => b.count - a.count || a.term.localeCompare(b.term));
110
+ }
111
+
112
+ export function unreferencedRaws(manifest, articles) {
113
+ const cited = articles.map((article) => sourceSection(article.text)).join("\n");
114
+ const findings = [];
115
+ for (const source of manifest.sources || []) {
116
+ if (!source.rawPath) continue;
117
+ if (cited.includes(source.rawPath) || cited.includes(source.id)) continue;
118
+ findings.push({ id: source.id, rawPath: source.rawPath });
119
+ }
120
+ return findings;
121
+ }
122
+
123
+ async function citedCorpus({ wikiRoot, repoRoot, article, manifest }) {
124
+ const cited = sourceSection(article.text);
125
+ const chunks = [cited];
126
+ for (const source of manifest.sources || []) {
127
+ const mentioned =
128
+ (source.rawPath && cited.includes(source.rawPath)) ||
129
+ (source.id && cited.includes(source.id)) ||
130
+ (source.livePath && cited.includes(source.livePath));
131
+ if (!mentioned) continue;
132
+ if (source.rawPath) {
133
+ const raw = path.resolve(wikiRoot, source.rawPath);
134
+ if (await exists(raw)) chunks.push(await readFile(raw, "utf8"));
135
+ }
136
+ if (source.livePath) {
137
+ const live = path.resolve(repoRoot, source.livePath);
138
+ if (await exists(live)) chunks.push(await readFile(live, "utf8"));
139
+ }
140
+ }
141
+ return chunks.join("\n");
142
+ }
143
+
144
+ export async function evidenceSuspects({ wikiRoot, repoRoot, articles, manifest }) {
145
+ const findings = [];
146
+ for (const article of articles) {
147
+ const literals = highSignalLiterals(articleBody(article.text));
148
+ if (!literals.length) continue;
149
+ const corpus = await citedCorpus({ wikiRoot, repoRoot, article, manifest });
150
+ for (const value of literals) {
151
+ if (!corpus.includes(value)) {
152
+ findings.push({ article: article.id, value });
153
+ }
154
+ }
155
+ }
156
+ return findings;
157
+ }
158
+
159
+ export async function adviseWiki(wikiRoot, { repoRoot = process.cwd() } = {}) {
160
+ const articles = await loadArticles(wikiRoot);
161
+ const manifestFile = path.join(wikiRoot, ".wiki-manifest.json");
162
+ const manifest = (await exists(manifestFile))
163
+ ? JSON.parse(await readFile(manifestFile, "utf8"))
164
+ : { sources: [] };
165
+ return {
166
+ oneWayLinks: oneWayLinks(articles),
167
+ missingTermPages: missingTermPages(articles),
168
+ unreferencedRaws: unreferencedRaws(manifest, articles),
169
+ suspects: await evidenceSuspects({ wikiRoot, repoRoot, articles, manifest }),
170
+ };
171
+ }
172
+
173
+ function parseArgs(argv) {
174
+ const args = { wiki: null, repo: process.cwd() };
175
+ for (let i = 0; i < argv.length; i += 1) {
176
+ if (argv[i] === "--repo") args.repo = argv[++i];
177
+ else if (argv[i] === "--wiki") args.wiki = argv[++i];
178
+ else if (!args.wiki && !argv[i].startsWith("-")) args.wiki = argv[i];
179
+ }
180
+ return args;
181
+ }
182
+
183
+ async function main(argv = process.argv.slice(2)) {
184
+ const args = parseArgs(argv);
185
+ if (!args.wiki) throw new Error("usage: advise.mjs <wiki-root> [--repo <repo-root>]");
186
+ const wikiRoot = path.resolve(args.repo, args.wiki);
187
+ const report = await adviseWiki(wikiRoot, { repoRoot: path.resolve(args.repo) });
188
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
189
+ }
190
+
191
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
192
+ main().catch((error) => {
193
+ process.stderr.write(`${error.message}\n`);
194
+ process.exitCode = 2;
195
+ });
196
+ }
@@ -0,0 +1,91 @@
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 { sha256 } from "./inventory.mjs";
9
+ import { adviseWiki } from "./advise.mjs";
10
+ import { lintWiki } from "./lint-wikilinks.mjs";
11
+
12
+ const adviseCli = fileURLToPath(new URL("./advise.mjs", import.meta.url));
13
+
14
+ async function seedAdvise() {
15
+ const repo = await mkdtemp(path.join(tmpdir(), "llm-wiki-advise-"));
16
+ const wikiRoot = path.join(repo, "wiki-root");
17
+ const wiki = path.join(wikiRoot, "wiki");
18
+ await mkdir(wiki, { recursive: true });
19
+ await mkdir(path.join(wikiRoot, "raw"), { recursive: true });
20
+ await mkdir(path.join(repo, "docs"), { recursive: true });
21
+ await writeFile(path.join(repo, "docs", "api.md"), "version one\n", "utf8");
22
+ await writeFile(path.join(wikiRoot, "raw", "api.md"), "version one\n", "utf8");
23
+ await writeFile(path.join(wikiRoot, "raw", "orphan-raw.md"), "unused\n", "utf8");
24
+ await writeFile(path.join(wiki, "index.md"), "# index\n\n## 分类\n\n- [[Alpha]]\n- [[Beta]]\n", "utf8");
25
+ await writeFile(
26
+ path.join(wiki, "Alpha.md"),
27
+ "# Alpha\n\nSee [[Beta]] and **孤立术语**. The figure is 42K.\n\n## 来源\n\n- raw/api.md\n",
28
+ "utf8",
29
+ );
30
+ await writeFile(
31
+ path.join(wiki, "Beta.md"),
32
+ "# Beta\n\nMentions **孤立术语** again.\n\n## 来源\n\n- raw/api.md\n",
33
+ "utf8",
34
+ );
35
+ await writeFile(path.join(wiki, "concept-table.md"), "# concepts\n", "utf8");
36
+ await writeFile(
37
+ path.join(wikiRoot, ".wiki-manifest.json"),
38
+ JSON.stringify({
39
+ schemaVersion: 1,
40
+ profile: "documents",
41
+ sources: [
42
+ {
43
+ id: "api.md",
44
+ kind: "document",
45
+ livePath: "docs/api.md",
46
+ rawPath: "raw/api.md",
47
+ sha256: sha256(Buffer.from("version one\n")),
48
+ },
49
+ {
50
+ id: "orphan-raw.md",
51
+ kind: "document",
52
+ livePath: "docs/api.md",
53
+ rawPath: "raw/orphan-raw.md",
54
+ sha256: sha256(Buffer.from("version one\n")),
55
+ },
56
+ ],
57
+ articles: [
58
+ { id: "Alpha", file: "wiki/Alpha.md", sourceIds: ["api.md"] },
59
+ { id: "Beta", file: "wiki/Beta.md", sourceIds: ["api.md"] },
60
+ ],
61
+ }),
62
+ "utf8",
63
+ );
64
+ return { repo, wikiRoot };
65
+ }
66
+
67
+ test("advise reports one-way links, missing terms, unreferenced raw, and suspects without failing lint", async () => {
68
+ const { repo, wikiRoot } = await seedAdvise();
69
+ const lint = await lintWiki(wikiRoot, { repoRoot: repo });
70
+ assert.equal(lint.ok, true, lint.errors.join("\n"));
71
+ const report = await adviseWiki(wikiRoot, { repoRoot: repo });
72
+ assert.ok(report.oneWayLinks.some((item) => item.from === "Alpha" && item.to === "Beta"));
73
+ assert.ok(report.missingTermPages.some((item) => item.term === "孤立术语" && item.count >= 2));
74
+ assert.ok(report.unreferencedRaws.some((item) => item.rawPath === "raw/orphan-raw.md"));
75
+ assert.ok(report.suspects.some((item) => item.article === "Alpha" && item.value === "42K"));
76
+ });
77
+
78
+ test("advise CLI exits 0 and prints JSON", async () => {
79
+ const { repo, wikiRoot } = await seedAdvise();
80
+ const ran = spawnSync(process.execPath, [adviseCli, wikiRoot, "--repo", repo], { encoding: "utf8" });
81
+ assert.equal(ran.status, 0, ran.stderr);
82
+ const report = JSON.parse(ran.stdout);
83
+ assert.ok(Array.isArray(report.suspects));
84
+ });
85
+
86
+ test("concept-table.md is infrastructure and does not fail lint as an orphan", async () => {
87
+ const { repo, wikiRoot } = await seedAdvise();
88
+ const lint = await lintWiki(wikiRoot, { repoRoot: repo });
89
+ assert.equal(lint.ok, true, lint.errors.join("\n"));
90
+ assert.equal(lint.counts.articles, 2);
91
+ });
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ export const EXTRACT_KINDS = Object.freeze(["skill-names", "heading-list", "prose-note"]);
7
+
8
+ function namesOf(value) {
9
+ if (!value || typeof value !== "object" || Array.isArray(value)) return [];
10
+ return Object.keys(value).sort((a, b) => a.localeCompare(b));
11
+ }
12
+
13
+ export function extractSkillNames(lock) {
14
+ if (!lock || typeof lock !== "object" || Array.isArray(lock)) {
15
+ throw new TypeError("skill-names input must be a lock object");
16
+ }
17
+ const shared = namesOf(lock.skills?.shared);
18
+ const platform = lock.skills?.platform && typeof lock.skills.platform === "object" ? lock.skills.platform : {};
19
+ const lines = ["# skills-lock names", "", "Derived names only. Do not copy hashes, paths, or the lock file.", "", "## shared", ""];
20
+ for (const name of shared) lines.push(`- \`${name}\``);
21
+ const roots = namesOf(platform);
22
+ if (roots.length) {
23
+ lines.push("", "## platform", "");
24
+ for (const root of roots) {
25
+ lines.push(`### \`${root}\``, "");
26
+ for (const name of namesOf(platform[root])) lines.push(`- \`${name}\``);
27
+ lines.push("");
28
+ }
29
+ }
30
+ return `${lines.join("\n").replace(/\n+$/, "")}\n`;
31
+ }
32
+
33
+ async function main(argv = process.argv.slice(2)) {
34
+ const kind = argv[0];
35
+ let input;
36
+ let output;
37
+ for (let i = 1; i < argv.length; i += 1) {
38
+ if (argv[i] === "--in") input = argv[++i];
39
+ else if (argv[i] === "--out") output = argv[++i];
40
+ }
41
+ if (kind !== "skill-names" || !input || !output) {
42
+ throw new Error("usage: extract.mjs skill-names --in <lock.json> --out <raw.md>");
43
+ }
44
+ const text = extractSkillNames(JSON.parse(await readFile(input, "utf8")));
45
+ await mkdir(path.dirname(output), { recursive: true });
46
+ await writeFile(output, text, "utf8");
47
+ process.stdout.write(`${output}\n`);
48
+ }
49
+
50
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
51
+ main().catch((error) => {
52
+ process.stderr.write(`${error.message}\n`);
53
+ process.exitCode = 2;
54
+ });
55
+ }
@@ -0,0 +1,34 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { EXTRACT_KINDS, extractSkillNames } from "./extract.mjs";
4
+
5
+ test("skill-names lists shared and platform keys, sorted, without hashes", () => {
6
+ const text = extractSkillNames({
7
+ skills: {
8
+ shared: {
9
+ zeta: { effectiveHash: "aaa", skillPath: "hidden" },
10
+ alpha: { effectiveHash: "bbb" },
11
+ },
12
+ platform: {
13
+ ".codex/skills": {
14
+ "product-design": { effectiveHash: "ccc" },
15
+ "data-analytics": { effectiveHash: "ddd" },
16
+ },
17
+ },
18
+ },
19
+ });
20
+ assert.match(text, /## shared/);
21
+ assert.match(text, /## platform/);
22
+ assert.ok(text.indexOf("`alpha`") < text.indexOf("`zeta`"));
23
+ assert.ok(text.indexOf("`data-analytics`") < text.indexOf("`product-design`"));
24
+ assert.doesNotMatch(text, /aaa|bbb|ccc|ddd|skillPath|effectiveHash/);
25
+ assert.doesNotMatch(text, /"version"|canonicalRoot/);
26
+ });
27
+
28
+ test("skill-names rejects a whole-file dump of a non-object", () => {
29
+ assert.throws(() => extractSkillNames("not-json-object"), /lock object/);
30
+ });
31
+
32
+ test("declared extract kinds stay the documented set", () => {
33
+ assert.deepEqual([...EXTRACT_KINDS], ["skill-names", "heading-list", "prose-note"]);
34
+ });
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env node
2
+ import { createHash } from "node:crypto";
3
+ import { execFileSync } from "node:child_process";
4
+ import { readFile, writeFile, access } from "node:fs/promises";
5
+ import path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const MANIFEST = ".wiki-manifest.json";
9
+
10
+ export function sha256(buffer) {
11
+ return createHash("sha256").update(buffer).digest("hex");
12
+ }
13
+
14
+ export function resolveWikiRoot(wikiArg, cwd = process.cwd()) {
15
+ if (!wikiArg) throw new Error("missing --wiki <wiki-root>");
16
+ return path.resolve(cwd, wikiArg);
17
+ }
18
+
19
+ export function manifestPath(wikiRoot) {
20
+ return path.join(wikiRoot, MANIFEST);
21
+ }
22
+
23
+ export async function loadManifest(wikiRoot) {
24
+ const file = manifestPath(wikiRoot);
25
+ const raw = await readFile(file, "utf8");
26
+ return JSON.parse(raw);
27
+ }
28
+
29
+ export async function saveManifest(wikiRoot, manifest) {
30
+ const file = manifestPath(wikiRoot);
31
+ await writeFile(file, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
32
+ return file;
33
+ }
34
+
35
+ export async function exists(file) {
36
+ try {
37
+ await access(file);
38
+ return true;
39
+ } catch {
40
+ return false;
41
+ }
42
+ }
43
+
44
+ export function gitCommit(repoRoot) {
45
+ try {
46
+ return execFileSync("git", ["-C", repoRoot, "rev-parse", "HEAD"], {
47
+ encoding: "utf8",
48
+ stdio: ["ignore", "pipe", "ignore"],
49
+ }).trim();
50
+ } catch {
51
+ return "";
52
+ }
53
+ }
54
+
55
+ export async function hashSources({ wikiRoot, repoRoot, now = new Date().toISOString() }) {
56
+ const manifest = await loadManifest(wikiRoot);
57
+ const missing = [];
58
+ for (const source of manifest.sources || []) {
59
+ if (!source.livePath) {
60
+ source.sha256 = "";
61
+ continue;
62
+ }
63
+ const live = path.resolve(repoRoot, source.livePath);
64
+ if (!(await exists(live))) {
65
+ missing.push(source.id);
66
+ source.sha256 = "";
67
+ continue;
68
+ }
69
+ source.sha256 = sha256(await readFile(live));
70
+ }
71
+ manifest.compiledAt = now;
72
+ manifest.gitCommit = gitCommit(repoRoot);
73
+ await saveManifest(wikiRoot, manifest);
74
+ return { manifest, missing };
75
+ }
76
+
77
+ export function normalizeLivePath(livePath) {
78
+ return String(livePath || "").replace(/\\/g, "/").replace(/^\.\/+/, "");
79
+ }
80
+
81
+ export function unmappedCandidates(sources, candidates = []) {
82
+ const mapped = new Set(
83
+ (sources || []).map((source) => normalizeLivePath(source.livePath)).filter(Boolean),
84
+ );
85
+ const unmapped = [];
86
+ const seen = new Set();
87
+ for (const candidate of candidates) {
88
+ const livePath = normalizeLivePath(candidate);
89
+ if (!livePath || mapped.has(livePath) || seen.has(livePath)) continue;
90
+ seen.add(livePath);
91
+ unmapped.push(livePath);
92
+ }
93
+ return unmapped;
94
+ }
95
+
96
+ export async function drift({ wikiRoot, repoRoot, candidates = [] }) {
97
+ const manifest = await loadManifest(wikiRoot);
98
+ const changed = [];
99
+ const missing = [];
100
+ const unchanged = [];
101
+ for (const source of manifest.sources || []) {
102
+ if (!source.livePath) {
103
+ unchanged.push(source.id);
104
+ continue;
105
+ }
106
+ const live = path.resolve(repoRoot, source.livePath);
107
+ if (!(await exists(live))) {
108
+ missing.push(source.id);
109
+ continue;
110
+ }
111
+ const current = sha256(await readFile(live));
112
+ if (current !== source.sha256) changed.push(source.id);
113
+ else unchanged.push(source.id);
114
+ }
115
+ const hit = new Set([...changed, ...missing]);
116
+ const articles = [];
117
+ const humanOwned = [];
118
+ for (const article of manifest.articles || []) {
119
+ const impacted = (article.sourceIds || []).some((id) => hit.has(id));
120
+ if (!impacted) continue;
121
+ articles.push(article.id);
122
+ if (article.humanOwned === true) humanOwned.push(article.id);
123
+ }
124
+ return {
125
+ changed,
126
+ missing,
127
+ unchanged,
128
+ articles,
129
+ unmapped: unmappedCandidates(manifest.sources, candidates),
130
+ humanOwned,
131
+ };
132
+ }
133
+
134
+ function parseArgs(argv) {
135
+ const args = { command: argv[0], wiki: null, repo: process.cwd(), candidates: [] };
136
+ for (let i = 1; i < argv.length; i += 1) {
137
+ if (argv[i] === "--wiki") args.wiki = argv[++i];
138
+ else if (argv[i] === "--repo") args.repo = argv[++i];
139
+ else if (argv[i] === "--candidate") args.candidates.push(argv[++i]);
140
+ else if (!args.wiki && !argv[i].startsWith("-")) args.wiki = argv[i];
141
+ }
142
+ return args;
143
+ }
144
+
145
+ async function main(argv = process.argv.slice(2)) {
146
+ const args = parseArgs(argv);
147
+ if (!args.command || !["hash", "drift", "status"].includes(args.command)) {
148
+ throw new Error(
149
+ "usage: inventory.mjs hash|drift|status --wiki <wiki-root> [--repo <repo-root>] [--candidate <livePath>]",
150
+ );
151
+ }
152
+ const wikiRoot = resolveWikiRoot(args.wiki, args.repo);
153
+ const repoRoot = path.resolve(args.repo);
154
+ if (!(await exists(manifestPath(wikiRoot)))) {
155
+ throw new Error(`manifest not found: ${manifestPath(wikiRoot)}`);
156
+ }
157
+ if (args.command === "hash") {
158
+ const result = await hashSources({ wikiRoot, repoRoot });
159
+ process.stdout.write(
160
+ `${JSON.stringify({ hashed: (result.manifest.sources || []).length, missing: result.missing }, null, 2)}\n`,
161
+ );
162
+ if (result.missing.length) process.exitCode = 1;
163
+ return;
164
+ }
165
+ const report = await drift({ wikiRoot, repoRoot, candidates: args.candidates });
166
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
167
+ }
168
+
169
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
170
+ main().catch((error) => {
171
+ process.stderr.write(`${error.message}\n`);
172
+ process.exitCode = 2;
173
+ });
174
+ }