create-yss-spec 3.5.2 → 3.5.3

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 (438) hide show
  1. package/package.json +1 -1
  2. package/src/template/asset-runtime.js +3 -1
  3. package/template/.agents/skills/.strategic-design-skills-manifest.json +1 -1
  4. package/template/.agents/skills/codebase-design/SKILL.md +4 -0
  5. package/template/{.codex/skills/improve-codebase-architecture/SKILL.md → .agents/skills/codebase-design/references/architecture-audit.md} +3 -9
  6. package/template/.agents/skills/frontend-commit/SKILL.md +4 -93
  7. package/template/.agents/skills/git-commit-core/SKILL.md +18 -0
  8. package/template/.agents/skills/java-backend-commit/SKILL.md +4 -96
  9. package/template/.agents/skills/llm-wiki/SKILL.md +12 -13
  10. package/template/.agents/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  11. package/template/.agents/skills/llm-wiki/references/compile.md +21 -114
  12. package/template/.agents/skills/llm-wiki/references/ingest.md +8 -33
  13. package/template/.agents/skills/llm-wiki/references/lint.md +9 -46
  14. package/template/.agents/skills/llm-wiki/references/query.md +9 -18
  15. package/template/.agents/skills/llm-wiki/references/schema.md +56 -29
  16. package/template/.agents/skills/llm-wiki/references/transactions.md +48 -0
  17. package/template/.agents/skills/llm-wiki/references/writing.md +4 -4
  18. package/template/.agents/skills/llm-wiki/scripts/advise.mjs +46 -58
  19. package/template/.agents/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  20. package/template/.agents/skills/llm-wiki/scripts/core.mjs +262 -0
  21. package/template/.agents/skills/llm-wiki/scripts/extract.mjs +35 -18
  22. package/template/.agents/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  23. package/template/.agents/skills/llm-wiki/scripts/feedback.mjs +51 -0
  24. package/template/.agents/skills/llm-wiki/scripts/inventory.mjs +43 -171
  25. package/template/.agents/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  26. package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  27. package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  28. package/template/.agents/skills/llm-wiki/scripts/migrate.mjs +51 -0
  29. package/template/.agents/skills/llm-wiki/scripts/query.mjs +149 -0
  30. package/template/.agents/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  31. package/template/.agents/skills/llm-wiki/scripts/sources.mjs +166 -0
  32. package/template/.agents/skills/llm-wiki/scripts/transaction.mjs +384 -0
  33. package/template/.agents/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  34. package/template/.agents/skills/prototype/LOGIC.md +1 -1
  35. package/template/.agents/skills/prototype/SKILL.md +5 -19
  36. package/template/.agents/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  37. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  38. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  39. package/template/.agents/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  40. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +8 -8
  41. package/template/.agents/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  42. package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  43. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  44. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  45. package/template/.agents/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  46. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +1 -1
  47. package/template/.agents/skills/yss-research/SKILL.md +4 -0
  48. package/template/.codex/skills/codebase-design/SKILL.md +4 -0
  49. package/template/{.pi/skills/improve-codebase-architecture/SKILL.md → .codex/skills/codebase-design/references/architecture-audit.md} +3 -9
  50. package/template/.codex/skills/frontend-commit/SKILL.md +4 -93
  51. package/template/.codex/skills/git-commit-core/SKILL.md +18 -0
  52. package/template/.codex/skills/java-backend-commit/SKILL.md +4 -96
  53. package/template/.codex/skills/llm-wiki/SKILL.md +12 -13
  54. package/template/.codex/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  55. package/template/.codex/skills/llm-wiki/references/compile.md +21 -114
  56. package/template/.codex/skills/llm-wiki/references/ingest.md +8 -33
  57. package/template/.codex/skills/llm-wiki/references/lint.md +9 -46
  58. package/template/.codex/skills/llm-wiki/references/query.md +9 -18
  59. package/template/.codex/skills/llm-wiki/references/schema.md +56 -29
  60. package/template/.codex/skills/llm-wiki/references/transactions.md +48 -0
  61. package/template/.codex/skills/llm-wiki/references/writing.md +4 -4
  62. package/template/.codex/skills/llm-wiki/scripts/advise.mjs +46 -58
  63. package/template/.codex/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  64. package/template/.codex/skills/llm-wiki/scripts/core.mjs +262 -0
  65. package/template/.codex/skills/llm-wiki/scripts/extract.mjs +35 -18
  66. package/template/.codex/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  67. package/template/.codex/skills/llm-wiki/scripts/feedback.mjs +51 -0
  68. package/template/.codex/skills/llm-wiki/scripts/inventory.mjs +43 -171
  69. package/template/.codex/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  70. package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  71. package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  72. package/template/.codex/skills/llm-wiki/scripts/migrate.mjs +51 -0
  73. package/template/.codex/skills/llm-wiki/scripts/query.mjs +149 -0
  74. package/template/.codex/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  75. package/template/.codex/skills/llm-wiki/scripts/sources.mjs +166 -0
  76. package/template/.codex/skills/llm-wiki/scripts/transaction.mjs +384 -0
  77. package/template/.codex/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  78. package/template/.codex/skills/prototype/LOGIC.md +1 -1
  79. package/template/.codex/skills/prototype/SKILL.md +5 -19
  80. package/template/.codex/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  81. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  82. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  83. package/template/.codex/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  84. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +8 -8
  85. package/template/.codex/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  86. package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  87. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  88. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  89. package/template/.codex/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  90. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +1 -1
  91. package/template/.codex/skills/yss-research/SKILL.md +4 -0
  92. package/template/.cursor/skills/codebase-design/SKILL.md +4 -0
  93. package/template/.cursor/skills/{improve-codebase-architecture/SKILL.md → codebase-design/references/architecture-audit.md} +3 -9
  94. package/template/.cursor/skills/frontend-commit/SKILL.md +4 -93
  95. package/template/.cursor/skills/git-commit-core/SKILL.md +18 -0
  96. package/template/.cursor/skills/java-backend-commit/SKILL.md +4 -96
  97. package/template/.cursor/skills/llm-wiki/SKILL.md +12 -13
  98. package/template/.cursor/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  99. package/template/.cursor/skills/llm-wiki/references/compile.md +21 -114
  100. package/template/.cursor/skills/llm-wiki/references/ingest.md +8 -33
  101. package/template/.cursor/skills/llm-wiki/references/lint.md +9 -46
  102. package/template/.cursor/skills/llm-wiki/references/query.md +9 -18
  103. package/template/.cursor/skills/llm-wiki/references/schema.md +56 -29
  104. package/template/.cursor/skills/llm-wiki/references/transactions.md +48 -0
  105. package/template/.cursor/skills/llm-wiki/references/writing.md +4 -4
  106. package/template/.cursor/skills/llm-wiki/scripts/advise.mjs +46 -58
  107. package/template/.cursor/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  108. package/template/.cursor/skills/llm-wiki/scripts/core.mjs +262 -0
  109. package/template/.cursor/skills/llm-wiki/scripts/extract.mjs +35 -18
  110. package/template/.cursor/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  111. package/template/.cursor/skills/llm-wiki/scripts/feedback.mjs +51 -0
  112. package/template/.cursor/skills/llm-wiki/scripts/inventory.mjs +43 -171
  113. package/template/.cursor/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  114. package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  115. package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  116. package/template/.cursor/skills/llm-wiki/scripts/migrate.mjs +51 -0
  117. package/template/.cursor/skills/llm-wiki/scripts/query.mjs +149 -0
  118. package/template/.cursor/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  119. package/template/.cursor/skills/llm-wiki/scripts/sources.mjs +166 -0
  120. package/template/.cursor/skills/llm-wiki/scripts/transaction.mjs +384 -0
  121. package/template/.cursor/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  122. package/template/.cursor/skills/prototype/LOGIC.md +1 -1
  123. package/template/.cursor/skills/prototype/SKILL.md +5 -19
  124. package/template/.cursor/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  125. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  126. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  127. package/template/.cursor/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  128. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +8 -8
  129. package/template/.cursor/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  130. package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  131. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  132. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  133. package/template/.cursor/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  134. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +1 -1
  135. package/template/.cursor/skills/yss-research/SKILL.md +4 -0
  136. package/template/.pi/skills/codebase-design/SKILL.md +4 -0
  137. package/template/{.agents/skills/improve-codebase-architecture/SKILL.md → .pi/skills/codebase-design/references/architecture-audit.md} +3 -9
  138. package/template/.pi/skills/frontend-commit/SKILL.md +4 -93
  139. package/template/.pi/skills/git-commit-core/SKILL.md +18 -0
  140. package/template/.pi/skills/java-backend-commit/SKILL.md +4 -96
  141. package/template/.pi/skills/llm-wiki/SKILL.md +12 -13
  142. package/template/.pi/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  143. package/template/.pi/skills/llm-wiki/references/compile.md +21 -114
  144. package/template/.pi/skills/llm-wiki/references/ingest.md +8 -33
  145. package/template/.pi/skills/llm-wiki/references/lint.md +9 -46
  146. package/template/.pi/skills/llm-wiki/references/query.md +9 -18
  147. package/template/.pi/skills/llm-wiki/references/schema.md +56 -29
  148. package/template/.pi/skills/llm-wiki/references/transactions.md +48 -0
  149. package/template/.pi/skills/llm-wiki/references/writing.md +4 -4
  150. package/template/.pi/skills/llm-wiki/scripts/advise.mjs +46 -58
  151. package/template/.pi/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  152. package/template/.pi/skills/llm-wiki/scripts/core.mjs +262 -0
  153. package/template/.pi/skills/llm-wiki/scripts/extract.mjs +35 -18
  154. package/template/.pi/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  155. package/template/.pi/skills/llm-wiki/scripts/feedback.mjs +51 -0
  156. package/template/.pi/skills/llm-wiki/scripts/inventory.mjs +43 -171
  157. package/template/.pi/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  158. package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  159. package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  160. package/template/.pi/skills/llm-wiki/scripts/migrate.mjs +51 -0
  161. package/template/.pi/skills/llm-wiki/scripts/query.mjs +149 -0
  162. package/template/.pi/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  163. package/template/.pi/skills/llm-wiki/scripts/sources.mjs +166 -0
  164. package/template/.pi/skills/llm-wiki/scripts/transaction.mjs +384 -0
  165. package/template/.pi/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  166. package/template/.pi/skills/prototype/LOGIC.md +1 -1
  167. package/template/.pi/skills/prototype/SKILL.md +5 -19
  168. package/template/.pi/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  169. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  170. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  171. package/template/.pi/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  172. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +8 -8
  173. package/template/.pi/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  174. package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  175. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  176. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  177. package/template/.pi/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  178. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +1 -1
  179. package/template/.pi/skills/yss-research/SKILL.md +4 -0
  180. package/template/.template-spec/agents/README.md +1 -1
  181. package/template/.template-spec/agents/digital-human-roles.yaml +1 -1
  182. package/template/.template-spec/agents/skill-migrations.md +15 -0
  183. package/template/.template-spec/agents/yss-skill-registry.yaml +10 -29
  184. package/template/.template-spec/architecture/README.md +3 -34
  185. package/template/.template-spec/plan/templates/competitive-analysis-template.md +2 -2
  186. package/template/.template-spec/process/contract-reading.md +24 -0
  187. package/template/.template-spec/process/lifecycle-registry-baseline.json +3 -1
  188. package/template/.template-spec/process/lifecycle-registry.yaml +6 -0
  189. package/template/.template-spec/process/research-completion.md +23 -0
  190. package/template/.template-spec/process/schemas/digital-human-task-package.schema.json +202 -12
  191. package/template/.template-spec/process/schemas/frontend-implementation-evidence.schema.json +7 -15
  192. package/template/.template-spec/process/subagent-collaboration.md +8 -0
  193. package/template/.template-spec/process/templates/frontend-implementation-verification-template.yaml +15 -1
  194. package/template/AGENTS.md +1 -1
  195. package/template/CONTEXT.md +5 -1
  196. package/template/README.md +12 -24
  197. package/template/scripts/contract +5 -5
  198. package/template/scripts/lib/contract-views.mjs +57 -2
  199. package/template/scripts/lib/execution-evidence.mjs +51 -0
  200. package/template/scripts/lib/harness-execution-scope.mjs +1 -1
  201. package/template/scripts/lib/implementation-contract-compiler.mjs +2 -0
  202. package/template/scripts/lib/lifecycle-context-query.mjs +15 -3
  203. package/template/scripts/lib/lifecycle-status.mjs +32 -6
  204. package/template/scripts/lib/lifecycle-transition.mjs +19 -1
  205. package/template/scripts/lib/maintenance-research.mjs +63 -0
  206. package/template/scripts/lib/read-only-intake.mjs +132 -0
  207. package/template/scripts/lib/skill-registry.mjs +2 -1
  208. package/template/scripts/lib/skill-supply-chain.mjs +4 -0
  209. package/template/scripts/lib/slice-task-package.mjs +1 -1
  210. package/template/scripts/lib/task-package.mjs +9 -2
  211. package/template/scripts/lifecycle-status +2 -2
  212. package/template/scripts/prepare-read-only-intake +16 -0
  213. package/template/scripts/run-read-only-intake +14 -0
  214. package/template/scripts/verify-digital-human-task-package +2 -2
  215. package/template/scripts/verify-frontend-implementation-evidence +24 -1
  216. package/template/scripts/verify-maintenance-research +13 -0
  217. package/template/skills-lock.json +19 -76
  218. package/template.manifest.json +118 -29
  219. package/template.snapshot.json +5 -6
  220. package/template/.agents/skills/grill-with-docs/SKILL.md +0 -20
  221. package/template/.agents/skills/grill-with-docs/agents/openai.yaml +0 -5
  222. package/template/.agents/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  223. package/template/.agents/skills/prototype/UI.md +0 -112
  224. package/template/.agents/skills/setup-matt-pocock-skills/domain.md +0 -37
  225. package/template/.agents/skills/to-questionnaire/SKILL.md +0 -55
  226. package/template/.agents/skills/to-questionnaire/agents/openai.yaml +0 -5
  227. package/template/.agents/skills/wait-what/SKILL.md +0 -7
  228. package/template/.agents/skills/wait-what/agents/openai.yaml +0 -5
  229. package/template/.codex/skills/data-analytics/.app.json +0 -84
  230. package/template/.codex/skills/data-analytics/.codex-plugin/plugin.json +0 -66
  231. package/template/.codex/skills/data-analytics/.mcp.json +0 -30
  232. package/template/.codex/skills/data-analytics/AGENTS.md +0 -20
  233. package/template/.codex/skills/data-analytics/DEPENDENCIES.MD +0 -27
  234. package/template/.codex/skills/data-analytics/README.md +0 -60
  235. package/template/.codex/skills/data-analytics/__yss_dotfile__.gitignore +0 -2
  236. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html +0 -16
  237. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part001 +0 -1
  238. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part002 +0 -1
  239. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part003 +0 -1
  240. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part004 +0 -1
  241. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part005 +0 -1
  242. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part006 +0 -1
  243. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html +0 -16
  244. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part001 +0 -1
  245. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part002 +0 -1
  246. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part003 +0 -1
  247. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part004 +0 -1
  248. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part005 +0 -1
  249. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part006 +0 -1
  250. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part007 +0 -1
  251. package/template/.codex/skills/data-analytics/assets/datascience-small.svg +0 -5
  252. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html +0 -16
  253. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part001 +0 -1
  254. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part002 +0 -1
  255. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part003 +0 -1
  256. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part004 +0 -1
  257. package/template/.codex/skills/data-analytics/assets/datascience.png +0 -0
  258. package/template/.codex/skills/data-analytics/assets/datascience.svg +0 -10
  259. package/template/.codex/skills/data-analytics/mcp/server.cjs +0 -2964
  260. package/template/.codex/skills/data-analytics/package-lock.json +0 -3048
  261. package/template/.codex/skills/data-analytics/package.json +0 -43
  262. package/template/.codex/skills/data-analytics/scripts/normalize-widget-assets.mjs +0 -75
  263. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/SKILL.md +0 -137
  264. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/agents/openai.yaml +0 -6
  265. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/references/quality-checks.md +0 -29
  266. package/template/.codex/skills/data-analytics/skills/build-dashboard/SKILL.md +0 -148
  267. package/template/.codex/skills/data-analytics/skills/build-dashboard/agents/openai.yaml +0 -6
  268. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/bi-platform-dashboard.md +0 -18
  269. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/html-dashboard.md +0 -24
  270. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/mcp-artifact-dashboard.md +0 -71
  271. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/streamlit-dashboard.md +0 -85
  272. package/template/.codex/skills/data-analytics/skills/build-report/SKILL.md +0 -207
  273. package/template/.codex/skills/data-analytics/skills/build-report/agents/openai.yaml +0 -6
  274. package/template/.codex/skills/data-analytics/skills/build-report/assets/executive-report-shell.html +0 -70
  275. package/template/.codex/skills/data-analytics/skills/build-report/assets/technical-report-shell.html +0 -66
  276. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/SKILL.md +0 -108
  277. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/agents/openai.yaml +0 -6
  278. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/__init__.py +0 -1
  279. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/cli.py +0 -52
  280. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/constants.py +0 -61
  281. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/docx_writer.py +0 -362
  282. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/html_parser.py +0 -829
  283. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/model.py +0 -30
  284. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/plan.py +0 -127
  285. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/quality.py +0 -374
  286. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/rendering.py +0 -613
  287. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/table_utils.py +0 -54
  288. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/utils.py +0 -16
  289. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc_plan.py +0 -9
  290. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/tests/test_delivery_plan.py +0 -45
  291. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/SKILL.md +0 -77
  292. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/agents/openai.yaml +0 -6
  293. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/scripts/report_to_google_slides.py +0 -2379
  294. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/SKILL.md +0 -88
  295. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/agents/openai.yaml +0 -6
  296. package/template/.codex/skills/data-analytics/skills/build-report/specifications/executive-report.md +0 -97
  297. package/template/.codex/skills/data-analytics/skills/build-report/specifications/mcp-app-report.md +0 -59
  298. package/template/.codex/skills/data-analytics/skills/build-report/specifications/technical-report.md +0 -75
  299. package/template/.codex/skills/data-analytics/skills/design-kpis/SKILL.md +0 -103
  300. package/template/.codex/skills/data-analytics/skills/design-kpis/agents/openai.yaml +0 -6
  301. package/template/.codex/skills/data-analytics/skills/gather-business-context/SKILL.md +0 -68
  302. package/template/.codex/skills/data-analytics/skills/gather-business-context/agents/openai.yaml +0 -6
  303. package/template/.codex/skills/data-analytics/skills/index/SKILL.md +0 -251
  304. package/template/.codex/skills/data-analytics/skills/index/agents/openai.yaml +0 -6
  305. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/SKILL.md +0 -131
  306. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/agents/openai.yaml +0 -6
  307. package/template/.codex/skills/data-analytics/skills/kpi-reporting/SKILL.md +0 -141
  308. package/template/.codex/skills/data-analytics/skills/kpi-reporting/agents/openai.yaml +0 -6
  309. package/template/.codex/skills/data-analytics/skills/kpi-reporting/references/report-templates.md +0 -32
  310. package/template/.codex/skills/data-analytics/skills/market-sizing/SKILL.md +0 -106
  311. package/template/.codex/skills/data-analytics/skills/market-sizing/agents/openai.yaml +0 -6
  312. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/SKILL.md +0 -130
  313. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/agents/openai.yaml +0 -6
  314. package/template/.codex/skills/data-analytics/skills/product-business-analysis/SKILL.md +0 -141
  315. package/template/.codex/skills/data-analytics/skills/product-business-analysis/agents/openai.yaml +0 -6
  316. package/template/.codex/skills/data-analytics/skills/spreadsheets/SKILL.md +0 -178
  317. package/template/.codex/skills/data-analytics/skills/spreadsheets/agents/openai.yaml +0 -9
  318. package/template/.codex/skills/data-analytics/skills/spreadsheets/assets/file-spreadsheet.png +0 -0
  319. package/template/.codex/skills/data-analytics/skills/spreadsheets/charts.md +0 -31
  320. package/template/.codex/skills/data-analytics/skills/spreadsheets/references/artifact_tool_api.md +0 -466
  321. package/template/.codex/skills/data-analytics/skills/spreadsheets/style_guidelines.md +0 -99
  322. package/template/.codex/skills/data-analytics/skills/user-context/SKILL.md +0 -197
  323. package/template/.codex/skills/data-analytics/skills/user-context/agents/openai.yaml +0 -6
  324. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/automation-config.md +0 -26
  325. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/source-category-config.json +0 -51
  326. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/user-context-config.md +0 -66
  327. package/template/.codex/skills/data-analytics/skills/user-context/references/automation.md +0 -69
  328. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-examples.md +0 -204
  329. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-state-template.json +0 -87
  330. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding.md +0 -497
  331. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/connector-playbook.md +0 -74
  332. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/setup.md +0 -65
  333. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/skill-template.md +0 -160
  334. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/source-intake.md +0 -75
  335. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/weekly-polling-automation.md +0 -96
  336. package/template/.codex/skills/data-analytics/skills/user-context/references/source-category-runtime.md +0 -263
  337. package/template/.codex/skills/data-analytics/skills/user-context/scripts/data_analytics_preflight.py +0 -1462
  338. package/template/.codex/skills/data-analytics/skills/user-context/scripts/init_user_context_state.py +0 -128
  339. package/template/.codex/skills/data-analytics/skills/user-context/scripts/reset_user_context_state.py +0 -101
  340. package/template/.codex/skills/data-analytics/skills/user-context/scripts/validate_user_context_preflight.py +0 -499
  341. package/template/.codex/skills/data-analytics/skills/user-context/tests/test_state_helpers.py +0 -978
  342. package/template/.codex/skills/data-analytics/skills/validate-data/SKILL.md +0 -126
  343. package/template/.codex/skills/data-analytics/skills/validate-data/agents/openai.yaml +0 -6
  344. package/template/.codex/skills/data-analytics/skills/validate-data/references/validation-methods.md +0 -70
  345. package/template/.codex/skills/data-analytics/skills/visualize-data/SKILL.md +0 -157
  346. package/template/.codex/skills/data-analytics/skills/visualize-data/agents/openai.yaml +0 -6
  347. package/template/.codex/skills/data-analytics/skills/visualize-data/references/seaborn-templates.md +0 -774
  348. package/template/.codex/skills/data-analytics/src/DESIGN.md +0 -222
  349. package/template/.codex/skills/data-analytics/src/analytics-app/App.tsx +0 -3666
  350. package/template/.codex/skills/data-analytics/src/analytics-app/analytics-layout.test.mjs +0 -136
  351. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartFrame.tsx +0 -54
  352. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartLegend.tsx +0 -96
  353. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartRenderer.tsx +0 -1647
  354. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartTooltip.tsx +0 -245
  355. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-app-helpers.tsx +0 -462
  356. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-capabilities.ts +0 -107
  357. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-compatibility.ts +0 -164
  358. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-contract.ts +0 -192
  359. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-theme.ts +0 -203
  360. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-tokens.css +0 -619
  361. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-transforms.ts +0 -402
  362. package/template/.codex/skills/data-analytics/src/analytics-app/fonts/SystemSansVariableVF.woff2 +0 -0
  363. package/template/.codex/skills/data-analytics/src/analytics-app/imageExport.ts +0 -370
  364. package/template/.codex/skills/data-analytics/src/analytics-app/layout/AnalyticsLayoutCanvas.tsx +0 -536
  365. package/template/.codex/skills/data-analytics/src/analytics-app/layout/RichMarkdown.tsx +0 -681
  366. package/template/.codex/skills/data-analytics/src/analytics-app/layout/analyticsLayoutCore.ts +0 -164
  367. package/template/.codex/skills/data-analytics/src/analytics-app/main.tsx +0 -21
  368. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/chart_contract.py +0 -472
  369. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/check_analytics_app_runtime_links.py +0 -75
  370. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/design_contract.py +0 -142
  371. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/package_utils.py +0 -142
  372. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/tests/test_package_utils.py +0 -377
  373. package/template/.codex/skills/data-analytics/src/analytics-app/styles.css +0 -3468
  374. package/template/.codex/skills/data-analytics/src/analytics-app/tables/DataTable.d.ts +0 -44
  375. package/template/.codex/skills/data-analytics/src/analytics-app/tables/DataTable.jsx +0 -639
  376. package/template/.codex/skills/data-analytics/src/analytics-app/tables/data-table.css +0 -327
  377. package/template/.codex/skills/data-analytics/src/analytics-app/tokens.css +0 -225
  378. package/template/.codex/skills/data-analytics/src/analytics-app/types.ts +0 -204
  379. package/template/.codex/skills/data-analytics/src/analytics-app-core.md +0 -85
  380. package/template/.codex/skills/data-analytics/src/codex-style-contract.md +0 -30
  381. package/template/.codex/skills/data-analytics/src/datascience-artifact-widget.html +0 -12
  382. package/template/.codex/skills/data-analytics/src/datascience-artifact-widget.jsx +0 -1008
  383. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.css +0 -2117
  384. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.html +0 -122
  385. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.js +0 -3588
  386. package/template/.codex/skills/data-analytics/src/datascience-table-widget.css +0 -483
  387. package/template/.codex/skills/data-analytics/src/datascience-table-widget.html +0 -32
  388. package/template/.codex/skills/data-analytics/src/datascience-table-widget.js +0 -333
  389. package/template/.codex/skills/data-analytics/src/mcp-host.js +0 -153
  390. package/template/.codex/skills/data-analytics/src/recharts-config.js +0 -315
  391. package/template/.codex/skills/data-analytics/src/recharts-renderer.jsx +0 -294
  392. package/template/.codex/skills/data-analytics/src/sql-source-view.css +0 -33
  393. package/template/.codex/skills/data-analytics/src/sql-source-view.js +0 -157
  394. package/template/.codex/skills/data-analytics/src/styles/codex-theme.css +0 -121
  395. package/template/.codex/skills/data-analytics/src/table-renderer.jsx +0 -28
  396. package/template/.codex/skills/data-analytics/tests/chart-transforms.test.mjs +0 -87
  397. package/template/.codex/skills/data-analytics/tests/funnel-smoke.html +0 -105
  398. package/template/.codex/skills/data-analytics/tests/inline-widget-compare.html +0 -233
  399. package/template/.codex/skills/data-analytics/tests/mcp-server.test.mjs +0 -1500
  400. package/template/.codex/skills/data-analytics/tests/native-style-contract.test.mjs +0 -219
  401. package/template/.codex/skills/data-analytics/tests/recharts-config.test.mjs +0 -144
  402. package/template/.codex/skills/data-analytics/tests/recharts-renderer.test.mjs +0 -11
  403. package/template/.codex/skills/data-analytics/tests/rich-markdown.test.mjs +0 -54
  404. package/template/.codex/skills/data-analytics/tests/widget-render-harness.html +0 -321
  405. package/template/.codex/skills/data-analytics/tsconfig.json +0 -19
  406. package/template/.codex/skills/data-analytics/vite.config.ts +0 -46
  407. package/template/.codex/skills/grill-with-docs/SKILL.md +0 -20
  408. package/template/.codex/skills/grill-with-docs/agents/openai.yaml +0 -5
  409. package/template/.codex/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  410. package/template/.codex/skills/prototype/UI.md +0 -112
  411. package/template/.codex/skills/setup-matt-pocock-skills/domain.md +0 -37
  412. package/template/.codex/skills/to-questionnaire/SKILL.md +0 -55
  413. package/template/.codex/skills/to-questionnaire/agents/openai.yaml +0 -5
  414. package/template/.codex/skills/wait-what/SKILL.md +0 -7
  415. package/template/.codex/skills/wait-what/agents/openai.yaml +0 -5
  416. package/template/.cursor/skills/grill-with-docs/SKILL.md +0 -20
  417. package/template/.cursor/skills/grill-with-docs/agents/openai.yaml +0 -5
  418. package/template/.cursor/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  419. package/template/.cursor/skills/prototype/UI.md +0 -112
  420. package/template/.cursor/skills/setup-matt-pocock-skills/domain.md +0 -37
  421. package/template/.cursor/skills/to-questionnaire/SKILL.md +0 -55
  422. package/template/.cursor/skills/to-questionnaire/agents/openai.yaml +0 -5
  423. package/template/.cursor/skills/wait-what/SKILL.md +0 -7
  424. package/template/.cursor/skills/wait-what/agents/openai.yaml +0 -5
  425. package/template/.pi/skills/grill-with-docs/SKILL.md +0 -20
  426. package/template/.pi/skills/grill-with-docs/agents/openai.yaml +0 -5
  427. package/template/.pi/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  428. package/template/.pi/skills/prototype/UI.md +0 -112
  429. package/template/.pi/skills/setup-matt-pocock-skills/domain.md +0 -37
  430. package/template/.pi/skills/to-questionnaire/SKILL.md +0 -55
  431. package/template/.pi/skills/to-questionnaire/agents/openai.yaml +0 -5
  432. package/template/.pi/skills/wait-what/SKILL.md +0 -7
  433. package/template/.pi/skills/wait-what/agents/openai.yaml +0 -5
  434. package/template/.template-spec/agents/domain.md +0 -31
  435. /package/template/.agents/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
  436. /package/template/.codex/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
  437. /package/template/.cursor/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
  438. /package/template/.pi/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
@@ -1,18 +1,25 @@
1
1
  import assert from "node:assert/strict";
2
2
  import { spawnSync } from "node:child_process";
3
- import { mkdir, mkdtemp, writeFile } from "node:fs/promises";
3
+ import { mkdir, mkdtemp, writeFile, readFile } from "node:fs/promises";
4
4
  import { tmpdir } from "node:os";
5
5
  import path from "node:path";
6
6
  import test from "node:test";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { drift, hashSources, sha256, unmappedCandidates } from "./inventory.mjs";
9
-
10
9
  const inventoryCli = fileURLToPath(new URL("./inventory.mjs", import.meta.url));
11
-
12
10
  async function seed() {
13
11
  const repo = await mkdtemp(path.join(tmpdir(), "llm-wiki-inv-"));
14
12
  const wiki = path.join(repo, "wiki-root");
15
13
  await mkdir(path.join(wiki, "raw"), { recursive: true });
14
+ await mkdir(path.join(wiki, "wiki"));
15
+ await writeFile(path.join(wiki, "raw/api.md"), "v1\n");
16
+ for (const id of ["API契约", "人工页"]) await writeFile(path.join(wiki, `wiki/${id}.md`), `# ${id}
17
+
18
+ Summary.
19
+
20
+ ## 来源
21
+ - api.md
22
+ `);
16
23
  const liveRel = "docs/api.md";
17
24
  const live = path.join(repo, liveRel);
18
25
  await mkdir(path.dirname(live), { recursive: true });
@@ -29,28 +36,31 @@ async function seed() {
29
36
  kind: "document",
30
37
  livePath: liveRel,
31
38
  rawPath: "raw/api.md",
32
- sha256: "",
33
- role: "copy",
34
- },
39
+ sha256: sha256("v1\n"),
40
+ role: "copy"
41
+ }
35
42
  ],
36
43
  articles: [
37
44
  { id: "API契约", file: "wiki/API契约.md", sourceIds: ["api.md"], humanOwned: false },
38
- { id: "人工页", file: "wiki/人工页.md", sourceIds: ["api.md"], humanOwned: true },
39
- ],
45
+ { id: "人工页", file: "wiki/人工页.md", sourceIds: ["api.md"], humanOwned: true }
46
+ ]
40
47
  }),
41
- "utf8",
48
+ "utf8"
42
49
  );
43
50
  return { repo, wiki, live, liveRel };
44
51
  }
45
-
46
- test("hash-sources fills sha256; drift is empty until live file changes", async () => {
52
+ test("hash-sources only observes; v1 remains unverified until compiled", async () => {
47
53
  const { repo, wiki, live } = await seed();
54
+ const before = await readFile(path.join(wiki, ".wiki-manifest.json"));
48
55
  const hashed = await hashSources({ wikiRoot: wiki, repoRoot: repo, now: "2026-01-01T00:00:00Z" });
49
56
  assert.equal(hashed.missing.length, 0);
57
+ assert.deepEqual(await readFile(path.join(wiki, ".wiki-manifest.json")), before);
58
+ assert.equal(hashed.observations[0].originalDigest, sha256("v1\n"));
50
59
  assert.equal(hashed.manifest.sources[0].sha256, sha256(Buffer.from("v1\n")));
51
60
  const clean = await drift({ wikiRoot: wiki, repoRoot: repo });
52
61
  assert.deepEqual(clean.changed, []);
53
- assert.deepEqual(clean.articles, []);
62
+ assert.deepEqual(clean.articles, ["API契约", "人工页"]);
63
+ assert.equal(clean.articleStates.every((a) => a.state === "unverified"), true);
54
64
  await writeFile(live, "v2\n", "utf8");
55
65
  const dirty = await drift({ wikiRoot: wiki, repoRoot: repo });
56
66
  assert.deepEqual(dirty.changed, ["api.md"]);
@@ -58,20 +68,18 @@ test("hash-sources fills sha256; drift is empty until live file changes", async
58
68
  assert.deepEqual(dirty.humanOwned, ["人工页"]);
59
69
  assert.deepEqual(dirty.unmapped, []);
60
70
  });
61
-
62
71
  test("unmapped candidates are listed without scanning the tree", () => {
63
72
  const sources = [{ livePath: "docs/api.md" }];
64
73
  assert.deepEqual(unmappedCandidates(sources, ["docs/api.md", "docs/new.md", "./docs/new.md"]), [
65
- "docs/new.md",
74
+ "docs/new.md"
66
75
  ]);
67
76
  });
68
-
69
77
  test("drift CLI exits 0 when sources changed and prints JSON", async () => {
70
78
  const { repo, wiki, live } = await seed();
71
79
  await hashSources({ wikiRoot: wiki, repoRoot: repo, now: "2026-01-01T00:00:00Z" });
72
80
  await writeFile(live, "v2\n", "utf8");
73
81
  const ran = spawnSync(process.execPath, [inventoryCli, "drift", "--wiki", wiki, "--repo", repo], {
74
- encoding: "utf8",
82
+ encoding: "utf8"
75
83
  });
76
84
  assert.equal(ran.status, 0, ran.stderr);
77
85
  const report = JSON.parse(ran.stdout);
@@ -80,7 +88,6 @@ test("drift CLI exits 0 when sources changed and prints JSON", async () => {
80
88
  assert.deepEqual(report.humanOwned, ["人工页"]);
81
89
  assert.deepEqual(report.unmapped, []);
82
90
  });
83
-
84
91
  test("status CLI exits 0 and lists unmapped candidates", async () => {
85
92
  const { repo, wiki, live } = await seed();
86
93
  await hashSources({ wikiRoot: wiki, repoRoot: repo, now: "2026-01-01T00:00:00Z" });
@@ -88,7 +95,7 @@ test("status CLI exits 0 and lists unmapped candidates", async () => {
88
95
  const ran = spawnSync(
89
96
  process.execPath,
90
97
  [inventoryCli, "status", "--wiki", wiki, "--repo", repo, "--candidate", "docs/extra.md"],
91
- { encoding: "utf8" },
98
+ { encoding: "utf8" }
92
99
  );
93
100
  assert.equal(ran.status, 0, ran.stderr);
94
101
  const report = JSON.parse(ran.stdout);
@@ -2,31 +2,28 @@
2
2
  import { readFile, readdir } from "node:fs/promises";
3
3
  import path from "node:path";
4
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([
5
+ import { exists, safePath, frontmatter, sourceSection, validateManifest, checkPaths, ownership, transactionState, cliError } from "./core.mjs";
6
+ import { drift } from "./inventory.mjs";
7
+ const INFRA = /* @__PURE__ */ new Set([
9
8
  "index.md",
10
9
  "log.md",
11
10
  "claude.md",
12
11
  "agents.md",
13
12
  "soul.md",
14
- "concept-table.md",
13
+ "concept-table.md"
15
14
  ]);
16
15
  const WIKILINK_RE = /\[\[([^\]|#]+)(?:[|#][^\]]*)?\]\]/g;
17
16
  const SOURCE_HEADING_RE = /^##\s+来源\s*$/m;
18
17
  const H1_RE = /^#\s+(.+?)\s*$/m;
19
-
20
- export function articlesDir(wikiRoot) {
18
+ function articlesDir(wikiRoot) {
21
19
  return path.join(wikiRoot, "wiki");
22
20
  }
23
-
24
- export function extractLinks(text) {
21
+ function extractLinks(text) {
25
22
  const ids = [];
26
23
  const invalid = [];
27
24
  WIKILINK_RE.lastIndex = 0;
28
25
  let match;
29
- while ((match = WIKILINK_RE.exec(text))) {
26
+ while (match = WIKILINK_RE.exec(text)) {
30
27
  const target = match[1].trim();
31
28
  if (!target) continue;
32
29
  if (target.startsWith("../") || target.includes("/")) {
@@ -37,34 +34,61 @@ export function extractLinks(text) {
37
34
  }
38
35
  return { ids, invalid };
39
36
  }
40
-
41
- export async function lintWiki(wikiRoot, { repoRoot = process.cwd() } = {}) {
37
+ async function lintWiki(wikiRoot, { repoRoot = process.cwd(), structureOnly = false } = {}) {
38
+ const errors = [];
39
+ let manifest;
40
+ try {
41
+ const mf = await safePath(wikiRoot, ".wiki-manifest.json");
42
+ if (await exists(mf)) {
43
+ manifest = JSON.parse(await readFile(mf, "utf8"));
44
+ errors.push(...validateManifest(manifest));
45
+ if (!errors.length) await checkPaths(manifest, { wikiRoot, repoRoot });
46
+ }
47
+ await safePath(wikiRoot, "wiki/index.md");
48
+ } catch (error) {
49
+ errors.push(error.message);
50
+ }
51
+ if (errors.length) {
52
+ try {
53
+ const files = await readdir(await safePath(wikiRoot, "wiki"));
54
+ for (const file of files.filter((f) => f.endsWith(".md") && !INFRA.has(f.toLowerCase())))
55
+ if (!manifest?.articles?.some((a) => a.file === `wiki/${file}`)) errors.push(`UNLISTED ARTICLE: ${file}`);
56
+ } catch {
57
+ }
58
+ return { ok: false, errors, counts: {} };
59
+ }
42
60
  const dir = articlesDir(wikiRoot);
43
- if (!(await exists(path.join(dir, "index.md")))) {
61
+ if (!await exists(path.join(dir, "index.md"))) {
44
62
  return { ok: false, errors: [`missing ${path.join(dir, "index.md")}`], counts: {} };
45
63
  }
46
64
  const names = (await readdir(dir)).filter((name) => name.endsWith(".md"));
47
65
  const articleFiles = names.filter((name) => !INFRA.has(name.toLowerCase()));
48
66
  const articleIds = new Set(articleFiles.map((name) => name.slice(0, -3)));
49
- const errors = [];
50
67
  let linkCount = 0;
51
-
52
- const indexText = await readFile(path.join(dir, "index.md"), "utf8");
68
+ const indexText = await readFile(await safePath(wikiRoot, "wiki/index.md"), "utf8");
53
69
  const indexLinks = extractLinks(indexText);
54
70
  linkCount += indexLinks.ids.length;
55
71
  for (const target of indexLinks.invalid) errors.push(`CROSS-WIKI (index): [[${target}]]`);
56
- const indexed = new Set();
72
+ const indexed = /* @__PURE__ */ new Set();
57
73
  for (const id of indexLinks.ids) {
58
74
  indexed.add(id);
59
75
  if (!articleIds.has(id)) errors.push(`MISSING (index): [[${id}]]`);
60
76
  }
61
-
62
77
  for (const file of articleFiles) {
63
78
  const id = file.slice(0, -3);
64
- const text = await readFile(path.join(dir, file), "utf8");
79
+ let text;
80
+ try {
81
+ text = await readFile(await safePath(wikiRoot, `wiki/${file}`), "utf8");
82
+ frontmatter(text);
83
+ } catch (error) {
84
+ errors.push(error.message);
85
+ continue;
86
+ }
65
87
  const heading = text.match(H1_RE);
66
88
  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}`);
89
+ if (!sourceSection(text)) errors.push(`NO SOURCE SECTION: ${file}`);
90
+ const article = manifest?.articles.find((a) => a.id === id);
91
+ if (article && ownership(article, text).conflict) errors.push(`OWNERSHIP_CONFLICT: ${id}`);
68
92
  if (!indexed.has(id)) errors.push(`ORPHAN: ${file}`);
69
93
  const links = extractLinks(text);
70
94
  for (const target of links.invalid) errors.push(`CROSS-WIKI: ${file} -> [[${target}]]`);
@@ -73,76 +97,25 @@ export async function lintWiki(wikiRoot, { repoRoot = process.cwd() } = {}) {
73
97
  if (!articleIds.has(target)) errors.push(`MISSING: ${file} -> [[${target}]]`);
74
98
  }
75
99
  }
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
- }
100
+ if (manifest) {
101
+ const listed = new Set(manifest.articles.map((a) => a.file));
102
+ for (const file of articleFiles) if (!listed.has(`wiki/${file}`)) errors.push(`UNLISTED ARTICLE: ${file}`);
103
+ for (const a of manifest.articles) if (!await exists(await safePath(wikiRoot, a.file))) errors.push(`MANIFEST ARTICLE MISSING: ${a.file}`);
104
+ for (const s of manifest.sources) if (s.rawPath && !await exists(await safePath(wikiRoot, s.rawPath))) errors.push(`RAW MISSING: ${s.id} (${s.rawPath})`);
105
+ if (!structureOnly) {
106
+ const report = await drift({ wikiRoot, repoRoot });
107
+ for (const s of report.sourceStates) if (!["current", "archived"].includes(s.state)) errors.push(`STALE HASH / ${s.state}: ${s.id} (${s.reason})`);
108
+ for (const a of report.articleStates) if (!["current", "archived"].includes(a.state)) errors.push(`ARTICLE ${a.state}: ${a.id} (${a.reason})`);
136
109
  }
137
110
  }
138
-
111
+ const tx = await transactionState(wikiRoot);
112
+ if (tx.incomplete || tx.state === "locked") errors.push("TRANSACTION_INCOMPLETE");
139
113
  return {
140
114
  ok: errors.length === 0,
141
115
  errors,
142
- counts: { articles: articleFiles.length, links: linkCount },
116
+ counts: { articles: articleFiles.length, links: linkCount }
143
117
  };
144
118
  }
145
-
146
119
  async function main(argv = process.argv.slice(2)) {
147
120
  let wikiArg;
148
121
  let repoRoot = process.cwd();
@@ -155,23 +128,27 @@ async function main(argv = process.argv.slice(2)) {
155
128
  throw new Error("usage: lint-wikilinks.mjs <wiki-root> [--repo <repo-root>]");
156
129
  }
157
130
  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`);
131
+ const result = await lintWiki(wikiRoot, { repoRoot, structureOnly: argv.includes("--structure-only") });
132
+ for (const error of result.errors) process.stdout.write(`${error}
133
+ `);
160
134
  process.stdout.write(
161
- `校验完成:${result.counts.articles || 0} 篇文章,${result.counts.links || 0} 条 wikilink\n`,
135
+ `校验完成:${result.counts.articles || 0} 篇文章,${result.counts.links || 0} 条 wikilink
136
+ `
162
137
  );
163
138
  if (result.ok) process.stdout.write("通过:所有 wikilink / 来源 / 索引检查通过\n");
164
139
  else {
165
140
  process.stdout.write(
166
- "失败:存在缺失的 wikilink、孤儿页、来源小节、跨路径链接、H1 或 manifest 闭合问题\n",
141
+ "失败:存在缺失的 wikilink、孤儿页、来源小节、跨路径链接、H1 或 manifest 闭合问题\n"
167
142
  );
168
143
  process.exitCode = 1;
169
144
  }
170
145
  }
171
-
172
146
  if (process.argv[1] === fileURLToPath(import.meta.url)) {
173
- main().catch((error) => {
174
- process.stderr.write(`${error.message}\n`);
175
- process.exitCode = 2;
176
- });
147
+ main().catch(cliError);
177
148
  }
149
+ export {
150
+ INFRA,
151
+ articlesDir,
152
+ extractLinks,
153
+ lintWiki
154
+ };
@@ -6,16 +6,13 @@ import test from "node:test";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { sha256 } from "./inventory.mjs";
8
8
  import { lintWiki } from "./lint-wikilinks.mjs";
9
-
10
9
  const skillRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
11
10
  const broken = path.join(skillRoot, "assets/fixtures/broken-wiki");
12
-
13
11
  test("broken fixture fails on dangling wikilink", async () => {
14
12
  const result = await lintWiki(broken);
15
13
  assert.equal(result.ok, false);
16
14
  assert.ok(result.errors.some((line) => line.includes("[[不存在的页]]")));
17
15
  });
18
-
19
16
  test("complete wiki passes wikilink, index, and source-section checks", async () => {
20
17
  const root = await mkdtemp(path.join(tmpdir(), "llm-wiki-lint-"));
21
18
  const wiki = path.join(root, "wiki");
@@ -23,19 +20,18 @@ test("complete wiki passes wikilink, index, and source-section checks", async ()
23
20
  await writeFile(
24
21
  path.join(wiki, "index.md"),
25
22
  "# index\n\n## 分类\n\n- [[Alpha]]\n",
26
- "utf8",
23
+ "utf8"
27
24
  );
28
25
  await writeFile(
29
26
  path.join(wiki, "Alpha.md"),
30
27
  "# Alpha\n\nSee [[Alpha]].\n\n## 来源\n\n- live\n",
31
- "utf8",
28
+ "utf8"
32
29
  );
33
30
  await writeFile(path.join(wiki, "CLAUDE.md"), "# schema\n", "utf8");
34
31
  const result = await lintWiki(root);
35
32
  assert.equal(result.ok, true, result.errors.join("\n"));
36
33
  assert.equal(result.counts.articles, 1);
37
34
  });
38
-
39
35
  test("cross-path wikilink fails instead of being ignored", async () => {
40
36
  const root = await mkdtemp(path.join(tmpdir(), "llm-wiki-cross-"));
41
37
  const wiki = path.join(root, "wiki");
@@ -44,13 +40,12 @@ test("cross-path wikilink fails instead of being ignored", async () => {
44
40
  await writeFile(
45
41
  path.join(wiki, "Alpha.md"),
46
42
  "# Alpha\n\nSee [[../other]]\n\n## 来源\n\n- live\n",
47
- "utf8",
43
+ "utf8"
48
44
  );
49
45
  const result = await lintWiki(root);
50
46
  assert.equal(result.ok, false);
51
47
  assert.ok(result.errors.some((line) => line.includes("CROSS-WIKI") && line.includes("[[../other]]")));
52
48
  });
53
-
54
49
  test("manifest sha256 mismatch is stale", async () => {
55
50
  const repo = await mkdtemp(path.join(tmpdir(), "llm-wiki-hash-"));
56
51
  const wikiRoot = path.join(repo, "wiki-root");
@@ -73,18 +68,17 @@ test("manifest sha256 mismatch is stale", async () => {
73
68
  kind: "document",
74
69
  livePath: liveRel,
75
70
  rawPath: "raw/api.md",
76
- sha256: sha256(Buffer.from("v1\n")),
77
- },
71
+ sha256: sha256(Buffer.from("v1\n"))
72
+ }
78
73
  ],
79
- articles: [{ id: "API", file: "wiki/API.md", sourceIds: ["api.md"] }],
74
+ articles: [{ id: "API", file: "wiki/API.md", sourceIds: ["api.md"] }]
80
75
  }),
81
- "utf8",
76
+ "utf8"
82
77
  );
83
78
  const result = await lintWiki(wikiRoot, { repoRoot: repo });
84
79
  assert.equal(result.ok, false);
85
80
  assert.ok(result.errors.some((line) => line.includes("STALE HASH") && line.includes("api.md")));
86
81
  });
87
-
88
82
  async function seedClosedWiki() {
89
83
  const repo = await mkdtemp(path.join(tmpdir(), "llm-wiki-closed-"));
90
84
  const wikiRoot = path.join(repo, "wiki-root");
@@ -99,7 +93,7 @@ async function seedClosedWiki() {
99
93
  await writeFile(
100
94
  path.join(wiki, "Alpha.md"),
101
95
  "# Alpha\n\nSee [[Alpha]].\n\n## 来源\n\n- live\n",
102
- "utf8",
96
+ "utf8"
103
97
  );
104
98
  const manifest = {
105
99
  schemaVersion: 1,
@@ -110,21 +104,19 @@ async function seedClosedWiki() {
110
104
  kind: "document",
111
105
  livePath: liveRel,
112
106
  rawPath: "raw/api.md",
113
- sha256: sha256(Buffer.from("v1\n")),
114
- },
107
+ sha256: sha256(Buffer.from("v1\n"))
108
+ }
115
109
  ],
116
- articles: [{ id: "Alpha", file: "wiki/Alpha.md", sourceIds: ["api.md"] }],
110
+ articles: [{ id: "Alpha", file: "wiki/Alpha.md", sourceIds: ["api.md"] }]
117
111
  };
118
112
  await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
119
113
  return { repo, wikiRoot, wiki, manifest };
120
114
  }
121
-
122
115
  test("closed manifest passes listing, id, sourceIds, profile, and rawPath checks", async () => {
123
116
  const { repo, wikiRoot } = await seedClosedWiki();
124
- const result = await lintWiki(wikiRoot, { repoRoot: repo });
117
+ const result = await lintWiki(wikiRoot, { repoRoot: repo, structureOnly: true });
125
118
  assert.equal(result.ok, true, result.errors.join("\n"));
126
119
  });
127
-
128
120
  test("open manifest fails unlisted article, id mismatch, unknown source, profile kind, and rawPath", async () => {
129
121
  const repo = await mkdtemp(path.join(tmpdir(), "llm-wiki-open-"));
130
122
  const wikiRoot = path.join(repo, "wiki-root");
@@ -146,27 +138,27 @@ test("open manifest fails unlisted article, id mismatch, unknown source, profile
146
138
  kind: "code-surface",
147
139
  livePath: "docs/api.md",
148
140
  rawPath: "raw/should-not-exist.md",
149
- sha256: sha256(Buffer.from("v1\n")),
141
+ sha256: sha256(Buffer.from("v1\n"))
150
142
  },
151
143
  {
152
144
  id: "note",
153
145
  kind: "document",
154
146
  livePath: "docs/api.md",
155
147
  rawPath: "",
156
- sha256: sha256(Buffer.from("v1\n")),
157
- },
148
+ sha256: sha256(Buffer.from("v1\n"))
149
+ }
158
150
  ],
159
151
  articles: [
160
152
  {
161
153
  id: "WrongId",
162
154
  file: "wiki/Alpha.md",
163
- sourceIds: ["api.md", "ghost"],
164
- },
165
- ],
155
+ sourceIds: ["api.md", "ghost"]
156
+ }
157
+ ]
166
158
  }),
167
- "utf8",
159
+ "utf8"
168
160
  );
169
- const result = await lintWiki(wikiRoot, { repoRoot: repo });
161
+ const result = await lintWiki(wikiRoot, { repoRoot: repo, structureOnly: true });
170
162
  assert.equal(result.ok, false);
171
163
  assert.ok(result.errors.some((line) => line.includes("UNLISTED ARTICLE") && line.includes("Beta.md")));
172
164
  assert.ok(result.errors.some((line) => line.includes("MANIFEST ID MISMATCH") && line.includes("WrongId")));
@@ -175,7 +167,6 @@ test("open manifest fails unlisted article, id mismatch, unknown source, profile
175
167
  assert.ok(result.errors.some((line) => line.includes("RAW PATH REQUIRED") && line.includes("note")));
176
168
  assert.ok(result.errors.some((line) => line.includes("RAW PATH FORBIDDEN") && line.includes("api.md")));
177
169
  });
178
-
179
170
  test("derived source requires a known extract.kind", async () => {
180
171
  const { repo, wikiRoot, manifest } = await seedClosedWiki();
181
172
  manifest.sources.push({
@@ -183,30 +174,27 @@ test("derived source requires a known extract.kind", async () => {
183
174
  kind: "derived",
184
175
  livePath: "docs/api.md",
185
176
  rawPath: "raw/api.md",
186
- sha256: sha256(Buffer.from("v1\n")),
177
+ sha256: sha256(Buffer.from("v1\n"))
187
178
  });
188
179
  await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
189
- const missing = await lintWiki(wikiRoot, { repoRoot: repo });
180
+ const missing = await lintWiki(wikiRoot, { repoRoot: repo, structureOnly: true });
190
181
  assert.equal(missing.ok, false);
191
182
  assert.ok(missing.errors.some((line) => line.includes("EXTRACT REQUIRED") && line.includes("lock")));
192
-
193
183
  manifest.sources.at(-1).extract = { kind: "whole-file" };
194
184
  await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
195
- const unknown = await lintWiki(wikiRoot, { repoRoot: repo });
185
+ const unknown = await lintWiki(wikiRoot, { repoRoot: repo, structureOnly: true });
196
186
  assert.equal(unknown.ok, false);
197
187
  assert.ok(unknown.errors.some((line) => line.includes("EXTRACT KIND") && line.includes("whole-file")));
198
-
199
188
  manifest.sources.at(-1).extract = { kind: "skill-names" };
200
189
  await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
201
- const ok = await lintWiki(wikiRoot, { repoRoot: repo });
190
+ const ok = await lintWiki(wikiRoot, { repoRoot: repo, structureOnly: true });
202
191
  assert.equal(ok.ok, true, ok.errors.join("\n"));
203
192
  });
204
-
205
193
  test("document rawPath must exist on disk", async () => {
206
194
  const { repo, wikiRoot, manifest } = await seedClosedWiki();
207
195
  manifest.sources[0].rawPath = "raw/missing.md";
208
196
  await writeFile(path.join(wikiRoot, ".wiki-manifest.json"), JSON.stringify(manifest), "utf8");
209
- const result = await lintWiki(wikiRoot, { repoRoot: repo });
197
+ const result = await lintWiki(wikiRoot, { repoRoot: repo, structureOnly: true });
210
198
  assert.equal(result.ok, false);
211
199
  assert.ok(result.errors.some((line) => line.includes("RAW MISSING") && line.includes("raw/missing.md")));
212
200
  });
@@ -0,0 +1,51 @@
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
+ import { loadManifest, safePath, digestFile, sha256, json, ownership, fail, args, cliError } from "./core.mjs";
6
+ import { createPlan, applyPlan } from "./transaction.mjs";
7
+ async function migrate({ wikiRoot, repoRoot = process.cwd(), apply = false }) {
8
+ const prior = await loadManifest(wikiRoot, { repoRoot });
9
+ if (prior.schemaVersion === 2) return { schemaVersion: 2, changed: false, readOnly: !apply };
10
+ const original = await readFile(await safePath(wikiRoot, ".wiki-manifest.json"), "utf8");
11
+ const manifest = structuredClone(prior);
12
+ manifest.schemaVersion = 2;
13
+ manifest.profile ||= "mixed";
14
+ manifest.feedback = [];
15
+ for (const s of manifest.sources) {
16
+ s.originalDigest = s.sha256 || null;
17
+ s.effectiveDigest = s.kind === "derived" ? null : s.sha256 || null;
18
+ s.rawDigest = s.rawPath ? await digestFile(await safePath(wikiRoot, s.rawPath)) : null;
19
+ s.location = s.livePath || s.url || `snapshot:${s.rawPath}`;
20
+ if (s.kind === "derived") {
21
+ s.extract = { ...s.extract, version: "1", inputs: s.extract?.inputs || [s.livePath].filter(Boolean) };
22
+ if (s.extract.kind === "prose-note") {
23
+ s.extract.inputDigests = {};
24
+ s.extract.rules ||= "legacy-unknown; explicit recipe required before recompilation";
25
+ }
26
+ }
27
+ }
28
+ for (const a of manifest.articles) {
29
+ a.articleDigest = null;
30
+ a.compiledFrom = {};
31
+ a.compiledDependencies = {};
32
+ a.verification = null;
33
+ a.dependsOnArticles ||= [];
34
+ a.aliases ||= [];
35
+ const text = await readFile(await safePath(wikiRoot, a.file), "utf8");
36
+ a.humanOwned = ownership(a, text).protected;
37
+ }
38
+ const backup = `.wiki-backups/manifest-v1-${sha256(original)}.json`;
39
+ const plan = await createPlan({ wikiRoot, repoRoot, request: { operation: "migrate", manifest, writes: [{ path: backup, content: original }], authorization: { confirmed: true, paths: [backup, ".wiki-manifest.json", "wiki/log.md"] } } });
40
+ if (!apply) return { changed: true, readOnly: true, backup, plan };
41
+ return { ...await applyPlan({ wikiRoot, repoRoot, plan }), changed: true, backup, remaining: "unverified; migration does not compile articles" };
42
+ }
43
+ async function main() {
44
+ const a = args(process.argv.slice(2));
45
+ if (!a.wiki) fail("USAGE", "migrate.mjs --wiki <root> [--repo <root>] [--apply]");
46
+ process.stdout.write(json(await migrate({ wikiRoot: path.resolve(a.repo, a.wiki), repoRoot: path.resolve(a.repo), apply: a.apply === true })));
47
+ }
48
+ if (process.argv[1] === fileURLToPath(import.meta.url)) main().catch(cliError);
49
+ export {
50
+ migrate
51
+ };