@skill-graph/cli 0.5.6

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 (330) hide show
  1. package/CHANGELOG.md +247 -0
  2. package/LICENSE +200 -0
  3. package/NOTICE +62 -0
  4. package/README.md +398 -0
  5. package/SKILL_GRAPH.md +443 -0
  6. package/bin/skill-graph.js +374 -0
  7. package/docs/ADOPTION.md +117 -0
  8. package/docs/CONFORMANCE.md +66 -0
  9. package/docs/PRIMER.md +384 -0
  10. package/docs/QUICKSTART-30MIN.md +333 -0
  11. package/docs/ROUTING-METRICS.md +120 -0
  12. package/docs/SKILL-MD-FORMAT-COMPATIBILITY.md +127 -0
  13. package/docs/SKILL_AUDIT_CHECKLIST.md +199 -0
  14. package/docs/SKILL_AUDIT_LOOP.md +195 -0
  15. package/docs/SKILL_METADATA_PROTOCOL.md +609 -0
  16. package/docs/_archived/marketplace-publication-priority-2026-05-18.md +239 -0
  17. package/docs/adr/0001-predicate-set.md +69 -0
  18. package/docs/adr/0002-json-ld-context.md +82 -0
  19. package/docs/adr/0003-ontoclean-rigidity-tags.md +65 -0
  20. package/docs/adr/0004-persistent-identifiers.md +74 -0
  21. package/docs/adr/0005-freshness-consolidation.md +70 -0
  22. package/docs/adr/0006-revise-predicate-rename.md +105 -0
  23. package/docs/adr/0007-audit-loop-cadence.md +99 -0
  24. package/docs/adr/0008-skill-surface-split-and-curation-policy.md +93 -0
  25. package/docs/category-consumers.md +168 -0
  26. package/docs/concept-map.md +194 -0
  27. package/docs/diagrams/drift-states.mmd +21 -0
  28. package/docs/diagrams/manifest-pipeline.mmd +25 -0
  29. package/docs/diagrams/routing-harness.mmd +41 -0
  30. package/docs/diagrams/starter-graph.mmd +53 -0
  31. package/docs/field-decision-guide.md +315 -0
  32. package/docs/field-rationale.md +211 -0
  33. package/docs/field-reference.generated.md +624 -0
  34. package/docs/field-reference.md +1426 -0
  35. package/docs/glossary.md +190 -0
  36. package/docs/head-noun-glossary.md +63 -0
  37. package/docs/images/audit-phases.png +0 -0
  38. package/docs/images/drift-states.png +0 -0
  39. package/docs/images/graded-mode.png +0 -0
  40. package/docs/images/manifest-pipeline.png +0 -0
  41. package/docs/images/routing-harness.png +0 -0
  42. package/docs/images/skill-anatomy.png +0 -0
  43. package/docs/images/starter-graph.png +0 -0
  44. package/docs/images/system-model.png +0 -0
  45. package/docs/integrations/github-actions.md +155 -0
  46. package/docs/manifest-field-mapping.md +443 -0
  47. package/docs/marketplace-publication-queue.generated.md +240 -0
  48. package/docs/marketplace-release-agent-prompt.md +82 -0
  49. package/docs/marketplace-skill-candidate-list.md +272 -0
  50. package/docs/marketplace-syndication.md +222 -0
  51. package/docs/migration-sample-review.md +155 -0
  52. package/docs/migrations/v4-to-v5.md +168 -0
  53. package/docs/migrations/v5-to-v6.md +221 -0
  54. package/docs/name-exceptions.yaml +37 -0
  55. package/docs/plans/marketplace-p1-public-migration-plan.md +41 -0
  56. package/docs/plans/multi-root-workspace.md +148 -0
  57. package/docs/plans/scripts-roadmap.md +107 -0
  58. package/docs/plans/v4-schema-bump.md +160 -0
  59. package/docs/plans/wave-2-extraction.md +122 -0
  60. package/docs/positioning-vs-marketplaces.md +175 -0
  61. package/docs/proposals/skill-audit-loop-positioning.md +160 -0
  62. package/docs/quality-doctrine.md +138 -0
  63. package/docs/recommended-skills.md +150 -0
  64. package/docs/research/skill-comprehension-eval-research.md +1830 -0
  65. package/docs/research/skill-retrieval-evidence.md +66 -0
  66. package/docs/skill-metadata-protocol.md +471 -0
  67. package/docs/skills-sh-maintainer-cleanup-request.md +80 -0
  68. package/examples/audits/a11y/findings.md +52 -0
  69. package/examples/audits/a11y/scorecard.md +21 -0
  70. package/examples/audits/a11y/verdict.md +44 -0
  71. package/examples/audits/debugging/findings.md +59 -0
  72. package/examples/audits/debugging/scorecard.md +22 -0
  73. package/examples/audits/debugging/verdict.md +33 -0
  74. package/examples/audits/documentation/findings.md +59 -0
  75. package/examples/audits/documentation/scorecard.md +22 -0
  76. package/examples/audits/documentation/verdict.md +33 -0
  77. package/examples/evals/a11y.json +140 -0
  78. package/examples/evals/api-design.json +52 -0
  79. package/examples/evals/code-review.json +52 -0
  80. package/examples/evals/data-modeling.json +52 -0
  81. package/examples/evals/database-migration.json +52 -0
  82. package/examples/evals/debugging.json +118 -0
  83. package/examples/evals/dependency-architecture.json +52 -0
  84. package/examples/evals/design-system-architecture.json +52 -0
  85. package/examples/evals/error-tracking.json +52 -0
  86. package/examples/evals/event-contract-design.json +52 -0
  87. package/examples/evals/form-ux-architecture.json +52 -0
  88. package/examples/evals/framework-fit-analysis.json +52 -0
  89. package/examples/evals/graph-audit.json +139 -0
  90. package/examples/evals/information-architecture.json +52 -0
  91. package/examples/evals/interaction-feedback.json +52 -0
  92. package/examples/evals/interaction-patterns.json +52 -0
  93. package/examples/evals/layout-composition.json +52 -0
  94. package/examples/evals/lint-overlay.json +117 -0
  95. package/examples/evals/microcopy.json +52 -0
  96. package/examples/evals/observability-modeling.json +52 -0
  97. package/examples/evals/pattern-recognition.json +96 -0
  98. package/examples/evals/performance-engineering.json +52 -0
  99. package/examples/evals/refactor.json +128 -0
  100. package/examples/evals/semiotics.json +52 -0
  101. package/examples/evals/skill-infrastructure.json +96 -0
  102. package/examples/evals/skill-router.json +140 -0
  103. package/examples/evals/skill-router.routing.json +113 -0
  104. package/examples/evals/system-interface-contracts.json +52 -0
  105. package/examples/evals/task-analysis.json +52 -0
  106. package/examples/evals/testing-strategy.json +118 -0
  107. package/examples/evals/type-safety.json +249 -0
  108. package/examples/evals/visual-design-foundations.json +52 -0
  109. package/examples/evals/webhook-integration.json +52 -0
  110. package/examples/exports/a11y.skill-md.md +80 -0
  111. package/examples/exports/debugging.skill-md.md +80 -0
  112. package/examples/exports/refactor.skill-md.md +78 -0
  113. package/examples/exports/testing-strategy.skill-md.md +81 -0
  114. package/examples/projects/markdown-static-site/README.md +115 -0
  115. package/examples/projects/markdown-static-site/skills/content-source-router/SKILL.md +131 -0
  116. package/examples/projects/markdown-static-site/skills/image-optimization-pipeline-config/SKILL.md +132 -0
  117. package/examples/projects/markdown-static-site/skills/link-rot-detection/SKILL.md +103 -0
  118. package/examples/projects/markdown-static-site/skills/markdown-post-frontmatter-validation/SKILL.md +133 -0
  119. package/examples/projects/markdown-static-site/skills/migrate-posts-to-v2-frontmatter/SKILL.md +140 -0
  120. package/examples/projects/saas-stripe-postgres/README.md +208 -0
  121. package/examples/projects/saas-stripe-postgres/db/migrations/0004_canonicalize_orders.sql +37 -0
  122. package/examples/projects/saas-stripe-postgres/db/schema.sql +112 -0
  123. package/examples/projects/saas-stripe-postgres/skills/migrate-orders-to-canonical-schema/SKILL.md +149 -0
  124. package/examples/projects/saas-stripe-postgres/skills/nextjs-server-action-validation/SKILL.md +154 -0
  125. package/examples/projects/saas-stripe-postgres/skills/payment-provider-router/SKILL.md +153 -0
  126. package/examples/projects/saas-stripe-postgres/skills/postgres-rls-pattern/SKILL.md +163 -0
  127. package/examples/projects/saas-stripe-postgres/skills/stripe-webhook-signature-verification/SKILL.md +137 -0
  128. package/examples/protocol/skill-metadata-template.md +301 -0
  129. package/examples/protocol/skills.manifest.sample.json +13245 -0
  130. package/examples/skill-metadata-template.md +317 -0
  131. package/examples/skills.manifest.sample.json +13519 -0
  132. package/examples/tests/v3-1-skos-fixture/SKILL.md +93 -0
  133. package/marketplace/README.md +17 -0
  134. package/marketplace/skills/a11y/SKILL.md +66 -0
  135. package/marketplace/skills/acid-fundamentals/SKILL.md +106 -0
  136. package/marketplace/skills/agent-engineering/SKILL.md +386 -0
  137. package/marketplace/skills/agent-eval-design/SKILL.md +55 -0
  138. package/marketplace/skills/ai-native-development/SKILL.md +294 -0
  139. package/marketplace/skills/api-design/SKILL.md +60 -0
  140. package/marketplace/skills/architecture-decision-records/SKILL.md +55 -0
  141. package/marketplace/skills/background-jobs/SKILL.md +265 -0
  142. package/marketplace/skills/bounded-context-mapping/SKILL.md +55 -0
  143. package/marketplace/skills/cap-theorem-tradeoffs/SKILL.md +127 -0
  144. package/marketplace/skills/client-server-boundary/SKILL.md +187 -0
  145. package/marketplace/skills/code-review/SKILL.md +120 -0
  146. package/marketplace/skills/color-system-design/SKILL.md +43 -0
  147. package/marketplace/skills/component-architecture/SKILL.md +126 -0
  148. package/marketplace/skills/compression/SKILL.md +112 -0
  149. package/marketplace/skills/conceptual-modeling/SKILL.md +181 -0
  150. package/marketplace/skills/connection-pooling/SKILL.md +105 -0
  151. package/marketplace/skills/constraint-awareness/SKILL.md +287 -0
  152. package/marketplace/skills/content-monitor/SKILL.md +209 -0
  153. package/marketplace/skills/context-engineering/SKILL.md +320 -0
  154. package/marketplace/skills/context-graph/SKILL.md +174 -0
  155. package/marketplace/skills/context-management/SKILL.md +174 -0
  156. package/marketplace/skills/context-window/SKILL.md +239 -0
  157. package/marketplace/skills/contract-testing/SKILL.md +120 -0
  158. package/marketplace/skills/cron-scheduling/SKILL.md +223 -0
  159. package/marketplace/skills/dark-mode-implementation/SKILL.md +47 -0
  160. package/marketplace/skills/data-modeling/SKILL.md +59 -0
  161. package/marketplace/skills/data-modeling-fundamentals/SKILL.md +117 -0
  162. package/marketplace/skills/database-migration/SKILL.md +429 -0
  163. package/marketplace/skills/debugging/SKILL.md +67 -0
  164. package/marketplace/skills/dependency-architecture/SKILL.md +58 -0
  165. package/marketplace/skills/design-module-composition/SKILL.md +43 -0
  166. package/marketplace/skills/design-system-architecture/SKILL.md +61 -0
  167. package/marketplace/skills/design-thinking/SKILL.md +44 -0
  168. package/marketplace/skills/diagnosis/SKILL.md +296 -0
  169. package/marketplace/skills/diff-analysis/SKILL.md +188 -0
  170. package/marketplace/skills/e2e-test-design/SKILL.md +113 -0
  171. package/marketplace/skills/entity-relationship-modeling/SKILL.md +218 -0
  172. package/marketplace/skills/epistemic-grounding/SKILL.md +112 -0
  173. package/marketplace/skills/error-boundary/SKILL.md +235 -0
  174. package/marketplace/skills/error-tracking/SKILL.md +261 -0
  175. package/marketplace/skills/eval-driven-development/SKILL.md +147 -0
  176. package/marketplace/skills/evaluation/SKILL.md +113 -0
  177. package/marketplace/skills/event-contract-design/SKILL.md +60 -0
  178. package/marketplace/skills/event-storming/SKILL.md +56 -0
  179. package/marketplace/skills/form-ux-architecture/SKILL.md +60 -0
  180. package/marketplace/skills/framework-fit-analysis/SKILL.md +59 -0
  181. package/marketplace/skills/frontend-architecture/SKILL.md +43 -0
  182. package/marketplace/skills/generative-ui/SKILL.md +118 -0
  183. package/marketplace/skills/graph-audit/SKILL.md +81 -0
  184. package/marketplace/skills/guardrails/SKILL.md +118 -0
  185. package/marketplace/skills/hooks-patterns/SKILL.md +185 -0
  186. package/marketplace/skills/http-semantics/SKILL.md +136 -0
  187. package/marketplace/skills/ideation/SKILL.md +41 -0
  188. package/marketplace/skills/indexing-strategy/SKILL.md +108 -0
  189. package/marketplace/skills/information-architecture/SKILL.md +59 -0
  190. package/marketplace/skills/integration-test-design/SKILL.md +111 -0
  191. package/marketplace/skills/intent-recognition/SKILL.md +136 -0
  192. package/marketplace/skills/interaction-feedback/SKILL.md +59 -0
  193. package/marketplace/skills/interaction-patterns/SKILL.md +59 -0
  194. package/marketplace/skills/journey-mapping/SKILL.md +41 -0
  195. package/marketplace/skills/keywords/SKILL.md +213 -0
  196. package/marketplace/skills/knowledge-modeling/SKILL.md +232 -0
  197. package/marketplace/skills/layout-composition/SKILL.md +59 -0
  198. package/marketplace/skills/linguistics/SKILL.md +429 -0
  199. package/marketplace/skills/lint-overlay/SKILL.md +76 -0
  200. package/marketplace/skills/mental-models/SKILL.md +126 -0
  201. package/marketplace/skills/merge-queue/SKILL.md +94 -0
  202. package/marketplace/skills/methodology/SKILL.md +317 -0
  203. package/marketplace/skills/microcopy/SKILL.md +232 -0
  204. package/marketplace/skills/middleware-patterns/SKILL.md +363 -0
  205. package/marketplace/skills/mobile-responsive-ux/SKILL.md +287 -0
  206. package/marketplace/skills/mutation-testing/SKILL.md +112 -0
  207. package/marketplace/skills/naming-conventions/SKILL.md +112 -0
  208. package/marketplace/skills/observability-modeling/SKILL.md +59 -0
  209. package/marketplace/skills/ontology-modeling/SKILL.md +67 -0
  210. package/marketplace/skills/owasp-security/SKILL.md +153 -0
  211. package/marketplace/skills/pattern-recognition/SKILL.md +472 -0
  212. package/marketplace/skills/performance-budgets/SKILL.md +185 -0
  213. package/marketplace/skills/performance-engineering/SKILL.md +58 -0
  214. package/marketplace/skills/performance-testing/SKILL.md +125 -0
  215. package/marketplace/skills/printify/SKILL.md +42 -0
  216. package/marketplace/skills/prioritization/SKILL.md +118 -0
  217. package/marketplace/skills/problem-framing/SKILL.md +41 -0
  218. package/marketplace/skills/problem-locating-solving/SKILL.md +203 -0
  219. package/marketplace/skills/project-knowledge-extraction/SKILL.md +54 -0
  220. package/marketplace/skills/prompt-craft/SKILL.md +134 -0
  221. package/marketplace/skills/prompt-injection-defense/SKILL.md +132 -0
  222. package/marketplace/skills/property-based-testing/SKILL.md +100 -0
  223. package/marketplace/skills/prototyping/SKILL.md +43 -0
  224. package/marketplace/skills/query-optimization/SKILL.md +144 -0
  225. package/marketplace/skills/real-time-updates/SKILL.md +324 -0
  226. package/marketplace/skills/ref-patterns/SKILL.md +284 -0
  227. package/marketplace/skills/refactor/SKILL.md +65 -0
  228. package/marketplace/skills/rendering-models/SKILL.md +142 -0
  229. package/marketplace/skills/replication-patterns/SKILL.md +110 -0
  230. package/marketplace/skills/research-synthesis/SKILL.md +41 -0
  231. package/marketplace/skills/route-handler-design/SKILL.md +347 -0
  232. package/marketplace/skills/schema-evolution/SKILL.md +140 -0
  233. package/marketplace/skills/security-fundamentals/SKILL.md +139 -0
  234. package/marketplace/skills/semantic-center/SKILL.md +194 -0
  235. package/marketplace/skills/semantic-relations/SKILL.md +250 -0
  236. package/marketplace/skills/semantics/SKILL.md +366 -0
  237. package/marketplace/skills/semiotics/SKILL.md +230 -0
  238. package/marketplace/skills/seo-strategy/SKILL.md +260 -0
  239. package/marketplace/skills/server-actions-design/SKILL.md +243 -0
  240. package/marketplace/skills/server-components-design/SKILL.md +190 -0
  241. package/marketplace/skills/sharding-strategy/SKILL.md +123 -0
  242. package/marketplace/skills/shopify/SKILL.md +42 -0
  243. package/marketplace/skills/skill-infrastructure/SKILL.md +320 -0
  244. package/marketplace/skills/skill-router/SKILL.md +71 -0
  245. package/marketplace/skills/skill-scaffold/SKILL.md +105 -0
  246. package/marketplace/skills/snapshot-testing/SKILL.md +120 -0
  247. package/marketplace/skills/spec-driven-development/SKILL.md +148 -0
  248. package/marketplace/skills/state-machine-modeling/SKILL.md +56 -0
  249. package/marketplace/skills/state-management/SKILL.md +134 -0
  250. package/marketplace/skills/streaming-architecture/SKILL.md +194 -0
  251. package/marketplace/skills/summarization/SKILL.md +156 -0
  252. package/marketplace/skills/suspense-patterns/SKILL.md +265 -0
  253. package/marketplace/skills/system-interface-contracts/SKILL.md +59 -0
  254. package/marketplace/skills/task-analysis/SKILL.md +201 -0
  255. package/marketplace/skills/taxonomy-design/SKILL.md +66 -0
  256. package/marketplace/skills/test-coverage-strategy/SKILL.md +108 -0
  257. package/marketplace/skills/test-doubles-design/SKILL.md +98 -0
  258. package/marketplace/skills/test-driven-development/SKILL.md +96 -0
  259. package/marketplace/skills/testing-strategy/SKILL.md +67 -0
  260. package/marketplace/skills/theme-system-design/SKILL.md +43 -0
  261. package/marketplace/skills/tool-call-flow/SKILL.md +229 -0
  262. package/marketplace/skills/tool-call-strategy/SKILL.md +292 -0
  263. package/marketplace/skills/transaction-isolation/SKILL.md +98 -0
  264. package/marketplace/skills/type-safety/SKILL.md +177 -0
  265. package/marketplace/skills/typography-system/SKILL.md +43 -0
  266. package/marketplace/skills/usability-testing/SKILL.md +43 -0
  267. package/marketplace/skills/user-research/SKILL.md +43 -0
  268. package/marketplace/skills/vercel-composition-patterns/SKILL.md +157 -0
  269. package/marketplace/skills/version-control/SKILL.md +233 -0
  270. package/marketplace/skills/visual-design-foundations/SKILL.md +59 -0
  271. package/marketplace/skills/visual-hierarchy/SKILL.md +43 -0
  272. package/marketplace/skills/webhook-integration/SKILL.md +331 -0
  273. package/marketplace/skills/writing-humanizer/SKILL.md +380 -0
  274. package/package.json +67 -0
  275. package/schemas/manifest.schema.json +811 -0
  276. package/schemas/manifest.v2.schema.json +164 -0
  277. package/schemas/manifest.v3.schema.json +758 -0
  278. package/schemas/manifest.v4.schema.json +755 -0
  279. package/schemas/manifest.v5.schema.json +755 -0
  280. package/schemas/manifest.v6.schema.json +811 -0
  281. package/schemas/skill.context.jsonld +279 -0
  282. package/schemas/skill.schema.json +919 -0
  283. package/schemas/skill.v2.schema.json +201 -0
  284. package/schemas/skill.v3.schema.json +827 -0
  285. package/schemas/skill.v4.schema.json +822 -0
  286. package/schemas/skill.v5.schema.json +830 -0
  287. package/schemas/skill.v6.schema.json +946 -0
  288. package/schemas/vocabulary/keywords.json +180 -0
  289. package/schemas/vocabulary/workspace_tags.json +23 -0
  290. package/scripts/__tests__/migrate-skill-v2-to-v3.test.js +161 -0
  291. package/scripts/__tests__/migrate-skill-v3-to-v4.test.js +158 -0
  292. package/scripts/__tests__/test-export-parser-drift.js +149 -0
  293. package/scripts/__tests__/test-marketplace-export.js +114 -0
  294. package/scripts/__tests__/test-router-paths.js +82 -0
  295. package/scripts/__tests__/test-stability-promotion.js +244 -0
  296. package/scripts/__tests__/test-v3-1-alias-contract.js +109 -0
  297. package/scripts/__tests__/test-v3-1-skos-runtime.js +116 -0
  298. package/scripts/backfill-schema-version.js +198 -0
  299. package/scripts/build-field-reference.js +160 -0
  300. package/scripts/build-retrieval-baseline.js +511 -0
  301. package/scripts/check-markdown-links.js +211 -0
  302. package/scripts/check-protocol-consistency.js +979 -0
  303. package/scripts/export-marketplace-skills.js +610 -0
  304. package/scripts/export-skill.js +374 -0
  305. package/scripts/generate-manifest.js +787 -0
  306. package/scripts/lib/alias-contract.js +83 -0
  307. package/scripts/lib/audit-prompt-builder.js +771 -0
  308. package/scripts/lib/mock-grader.js +134 -0
  309. package/scripts/lib/parse-frontmatter.js +429 -0
  310. package/scripts/lib/roots.js +119 -0
  311. package/scripts/lint/check-archetype-sections.js +185 -0
  312. package/scripts/lint/check-category-enum.js +83 -0
  313. package/scripts/lint/check-routing-eval.js +146 -0
  314. package/scripts/lint/check-routing-quality.js +211 -0
  315. package/scripts/lint/check-stability-promotion.js +220 -0
  316. package/scripts/lint/format-code-frame.js +206 -0
  317. package/scripts/marketplace-install.js +125 -0
  318. package/scripts/migrate-category-to-enum.js +169 -0
  319. package/scripts/migrate-skill-v2-to-v3.js +424 -0
  320. package/scripts/migrate-skill-v3-to-v4.js +200 -0
  321. package/scripts/migrate-skill-v5-to-v6.js +304 -0
  322. package/scripts/restructure-by-category.js +85 -0
  323. package/scripts/seed-publication-classification.js +282 -0
  324. package/scripts/skill-audit.js +893 -0
  325. package/scripts/skill-graph-drift.js +483 -0
  326. package/scripts/skill-graph-route.js +766 -0
  327. package/scripts/skill-graph-routing-eval.js +393 -0
  328. package/scripts/skill-lint.js +1317 -0
  329. package/scripts/skill-overlap.js +213 -0
  330. package/scripts/verify-skill-md-export.js +201 -0
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * backfill-schema-version.js — ensure every SKILL.md declares `schema_version`
4
+ *
5
+ * Walks a skill tree and reports any SKILL.md that is missing the
6
+ * `schema_version` key in its YAML frontmatter. Optionally writes the
7
+ * current version into missing files.
8
+ *
9
+ * This script exists because the v3 schema requires `schema_version`, but
10
+ * libraries that existed before v3 (or that drift over time) may have
11
+ * SKILL.md files missing the field. Audit reports need a deterministic
12
+ * way to measure the gap and a safe way to close it.
13
+ *
14
+ * Usage:
15
+ * node scripts/backfill-schema-version.js # dry-run, default roots
16
+ * node scripts/backfill-schema-version.js --write # apply changes
17
+ * node scripts/backfill-schema-version.js --root <dir> # custom root
18
+ * node scripts/backfill-schema-version.js --version 3 # override version value
19
+ * node scripts/backfill-schema-version.js --report report.md # write a markdown report
20
+ *
21
+ * Default roots (in order, first existing wins):
22
+ * - ./skills
23
+ * - ./Skill Graph/skills
24
+ *
25
+ * Multi-root workspaces should pass `--root <dir>` per project root, or use
26
+ * `.skill-graph/config.json` (consumed by `scripts/generate-manifest.js`).
27
+ *
28
+ * No external dependencies.
29
+ */
30
+
31
+ const fs = require('fs');
32
+ const path = require('path');
33
+
34
+ const DEFAULT_ROOTS = [
35
+ 'skills',
36
+ 'Skill Graph/skills'
37
+ ];
38
+
39
+ const DEFAULT_VERSION = 3;
40
+
41
+ function parseArgs(argv) {
42
+ const args = {
43
+ write: false,
44
+ roots: [],
45
+ version: DEFAULT_VERSION,
46
+ report: null
47
+ };
48
+ for (let i = 2; i < argv.length; i++) {
49
+ const a = argv[i];
50
+ if (a === '--write') args.write = true;
51
+ else if (a === '--root') args.roots.push(path.resolve(argv[++i]));
52
+ else if (a === '--version') args.version = parseInt(argv[++i], 10);
53
+ else if (a === '--report') args.report = path.resolve(argv[++i]);
54
+ else if (a === '--help' || a === '-h') {
55
+ console.log('Usage: backfill-schema-version.js [--write] [--root <dir>]... [--version N] [--report <path>]');
56
+ process.exit(0);
57
+ } else {
58
+ console.error(`Unknown arg: ${a}`);
59
+ process.exit(2);
60
+ }
61
+ }
62
+ return args;
63
+ }
64
+
65
+ function resolveRoots(customRoots) {
66
+ if (customRoots.length) return customRoots;
67
+ const cwd = process.cwd();
68
+ const resolved = [];
69
+ for (const candidate of DEFAULT_ROOTS) {
70
+ const full = path.resolve(cwd, candidate);
71
+ if (fs.existsSync(full) && fs.statSync(full).isDirectory()) {
72
+ resolved.push(full);
73
+ }
74
+ }
75
+ return resolved;
76
+ }
77
+
78
+ function walkSkillFiles(root) {
79
+ const out = [];
80
+ const stack = [root];
81
+ while (stack.length) {
82
+ const dir = stack.pop();
83
+ let entries;
84
+ try { entries = fs.readdirSync(dir, { withFileTypes: true }); }
85
+ catch { continue; }
86
+ for (const ent of entries) {
87
+ const full = path.join(dir, ent.name);
88
+ if (ent.isDirectory()) {
89
+ if (ent.name === 'node_modules' || ent.name.startsWith('.git')) continue;
90
+ stack.push(full);
91
+ } else if (ent.isFile() && ent.name === 'SKILL.md') {
92
+ out.push(full);
93
+ }
94
+ }
95
+ }
96
+ return out.sort();
97
+ }
98
+
99
+ function parseFrontmatter(content) {
100
+ if (!content.startsWith('---\n')) return { start: -1, end: -1, lines: [] };
101
+ const rest = content.slice(4);
102
+ const endIdx = rest.indexOf('\n---\n');
103
+ if (endIdx === -1) return { start: -1, end: -1, lines: [] };
104
+ const fm = rest.slice(0, endIdx);
105
+ return { start: 4, end: 4 + endIdx + 5, lines: fm.split('\n') };
106
+ }
107
+
108
+ function hasSchemaVersion(lines) {
109
+ return lines.some(l => /^schema_version\s*:/.test(l));
110
+ }
111
+
112
+ function insertSchemaVersion(content, version) {
113
+ if (!content.startsWith('---\n')) {
114
+ return `---\nschema_version: ${version}\n---\n\n${content}`;
115
+ }
116
+ // insert as first frontmatter line
117
+ return content.replace(/^---\n/, `---\nschema_version: ${version}\n`);
118
+ }
119
+
120
+ function formatReport(results, version) {
121
+ const missing = results.filter(r => !r.hasSchemaVersion);
122
+ const present = results.filter(r => r.hasSchemaVersion);
123
+ const lines = [
124
+ '# schema_version Backfill Report',
125
+ '',
126
+ `Generated: ${new Date().toISOString()}`,
127
+ `Target version: ${version}`,
128
+ '',
129
+ `## Summary`,
130
+ '',
131
+ `- Total SKILL.md files scanned: **${results.length}**`,
132
+ `- With \`schema_version\` already: **${present.length}**`,
133
+ `- Missing \`schema_version\`: **${missing.length}**`,
134
+ `- Coverage: **${results.length ? Math.round((present.length / results.length) * 100) : 0}%**`,
135
+ '',
136
+ `## Missing (would add \`schema_version: ${version}\`)`,
137
+ ''
138
+ ];
139
+ if (missing.length === 0) {
140
+ lines.push('_None — every SKILL.md declares schema_version._');
141
+ } else {
142
+ for (const r of missing) lines.push(`- ${r.path}`);
143
+ }
144
+ return lines.join('\n') + '\n';
145
+ }
146
+
147
+ function main() {
148
+ const args = parseArgs(process.argv);
149
+ const roots = resolveRoots(args.roots);
150
+ if (roots.length === 0) {
151
+ console.error('No skill roots found. Pass --root <dir> or run from a directory containing one of:', DEFAULT_ROOTS.join(', '));
152
+ process.exit(2);
153
+ }
154
+
155
+ console.log(`[backfill] Mode: ${args.write ? 'WRITE' : 'DRY-RUN'} Version: ${args.version}`);
156
+ console.log(`[backfill] Scanning roots:`);
157
+ for (const r of roots) console.log(` - ${r}`);
158
+
159
+ const results = [];
160
+ for (const root of roots) {
161
+ const files = walkSkillFiles(root);
162
+ for (const file of files) {
163
+ const content = fs.readFileSync(file, 'utf8');
164
+ const fm = parseFrontmatter(content);
165
+ const has = fm.lines.length > 0 && hasSchemaVersion(fm.lines);
166
+ results.push({ path: path.relative(process.cwd(), file), hasSchemaVersion: has, absPath: file });
167
+
168
+ if (!has && args.write) {
169
+ const updated = insertSchemaVersion(content, args.version);
170
+ fs.writeFileSync(file, updated, 'utf8');
171
+ }
172
+ }
173
+ }
174
+
175
+ const missing = results.filter(r => !r.hasSchemaVersion);
176
+ const present = results.filter(r => r.hasSchemaVersion);
177
+
178
+ console.log(`[backfill] Scanned: ${results.length} With schema_version: ${present.length} Missing: ${missing.length}`);
179
+
180
+ if (missing.length) {
181
+ const display = missing.slice(0, 20);
182
+ console.log(`[backfill] ${args.write ? 'Updated' : 'Would update'} ${missing.length} files:`);
183
+ for (const r of display) console.log(` - ${r.path}`);
184
+ if (missing.length > display.length) console.log(` ... (${missing.length - display.length} more)`);
185
+ }
186
+
187
+ if (args.report) {
188
+ fs.writeFileSync(args.report, formatReport(results, args.version), 'utf8');
189
+ console.log(`[backfill] Wrote report to ${args.report}`);
190
+ }
191
+
192
+ if (!args.write && missing.length > 0) {
193
+ console.log(`[backfill] Dry-run only. Re-run with --write to apply.`);
194
+ process.exit(0); // dry-run is always success-exit
195
+ }
196
+ }
197
+
198
+ main();
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * build-field-reference.js — Schema → field-reference.generated.md
4
+ *
5
+ * Reads schemas/skill.schema.json (the current canonical schema) and emits
6
+ * docs/field-reference.generated.md
7
+ * with one section per top-level field. The prose is taken from the schema's
8
+ * `description` attributes; cross-links to the full reference + glossary are
9
+ * inserted automatically.
10
+ *
11
+ * Purpose: provide a drift-free field reference that is guaranteed in sync
12
+ * with the schema. The hand-authored `docs/field-reference.md` stays as the
13
+ * canonical prose (richer examples, when-to-use guidance, lint notes). This
14
+ * generator produces a thinner companion doc for consumers that want a
15
+ * machine-guaranteed index of every field.
16
+ *
17
+ * Usage:
18
+ * node scripts/build-field-reference.js # writes default path
19
+ * node scripts/build-field-reference.js --output <path> # custom path
20
+ * node scripts/build-field-reference.js --check # exit 1 if regeneration would differ
21
+ *
22
+ * No external dependencies.
23
+ */
24
+
25
+ const fs = require('fs');
26
+ const path = require('path');
27
+
28
+ const ROOT = path.resolve(__dirname, '..');
29
+ const SCHEMA_PATH = path.join(ROOT, 'schemas', 'skill.schema.json');
30
+ const DEFAULT_OUTPUT = path.join(ROOT, 'docs', 'field-reference.generated.md');
31
+
32
+ function parseArgs(argv) {
33
+ const args = { output: DEFAULT_OUTPUT, check: false };
34
+ for (let i = 2; i < argv.length; i++) {
35
+ const a = argv[i];
36
+ if (a === '--output' || a === '-o') args.output = path.resolve(argv[++i]);
37
+ else if (a === '--check') args.check = true;
38
+ else if (a === '--help' || a === '-h') {
39
+ console.log('Usage: build-field-reference.js [--output <path>] [--check]');
40
+ process.exit(0);
41
+ } else {
42
+ console.error(`Unknown arg: ${a}`);
43
+ process.exit(2);
44
+ }
45
+ }
46
+ return args;
47
+ }
48
+
49
+ function loadSchema() {
50
+ const raw = fs.readFileSync(SCHEMA_PATH, 'utf8');
51
+ return JSON.parse(raw);
52
+ }
53
+
54
+ function renderObjectShape(prop, indent = 0) {
55
+ if (prop.type === 'object' && prop.properties) {
56
+ const pad = ' '.repeat(indent);
57
+ const sub = Object.entries(prop.properties).map(([k, v]) => {
58
+ const req = (prop.required || []).includes(k);
59
+ const marker = req ? '*required*' : '*optional*';
60
+ const desc = v.description ? ` — ${v.description.split('.')[0]}.` : '';
61
+ const enumHint = v.enum ? ` (${v.enum.map(e => `\`${e}\``).join(' | ')})` : '';
62
+ return `${pad}- \`${k}\` ${marker}${enumHint}${desc}`;
63
+ });
64
+ return sub.join('\n');
65
+ }
66
+ return '';
67
+ }
68
+
69
+ function typeLabel(prop) {
70
+ if (prop.enum) return prop.enum.map(v => `\`${v}\``).join(' | ');
71
+ if (prop.oneOf) return 'multiple — see schema';
72
+ if (prop.type === 'array') {
73
+ const itemType = prop.items ? (prop.items.type || (prop.items.oneOf ? 'string | object' : 'string')) : 'any';
74
+ return `array of ${itemType}`;
75
+ }
76
+ if (prop.type) return prop.type;
77
+ return 'any';
78
+ }
79
+
80
+ function renderField(name, prop, requiredSet) {
81
+ const isRequired = requiredSet.has(name);
82
+ const requiredLabel = isRequired ? ' *(required)*' : ' *(optional)*';
83
+ const typeStr = typeLabel(prop);
84
+ const desc = prop.description || '_No description in schema._';
85
+
86
+ const parts = [
87
+ `### \`${name}\`${requiredLabel}`,
88
+ '',
89
+ `**Type:** ${typeStr}`,
90
+ '',
91
+ desc.trim(),
92
+ ''
93
+ ];
94
+
95
+ if (prop.pattern) parts.push('', `**Pattern:** \`${prop.pattern}\``, '');
96
+ if (prop.format) parts.push('', `**Format:** ${prop.format}`, '');
97
+ if (prop.minLength !== undefined) parts.push('', `**Min length:** ${prop.minLength}`, '');
98
+ if (prop.maxLength !== undefined) parts.push('', `**Max length:** ${prop.maxLength}`, '');
99
+
100
+ if (prop.type === 'object' && prop.properties) {
101
+ parts.push('', '**Sub-fields:**', '', renderObjectShape(prop), '');
102
+ }
103
+
104
+ if (prop.items && prop.items.type === 'object' && prop.items.properties) {
105
+ parts.push('', '**Item shape (object form):**', '', renderObjectShape(prop.items), '');
106
+ }
107
+
108
+ parts.push('', `**Full reference:** [\`docs/field-reference.md#${name}\`](field-reference.md#${name})`, '');
109
+
110
+ return parts.join('\n').replace(/\n{3,}/g, '\n\n');
111
+ }
112
+
113
+ function render(schema) {
114
+ const requiredSet = new Set(schema.required || []);
115
+ const now = new Date().toISOString().slice(0, 10);
116
+ const lines = [
117
+ '# Skill Graph Field Reference (Generated)',
118
+ '',
119
+ `> **Generated from** \`schemas/skill.schema.json\` on ${now} by \`scripts/build-field-reference.js\`.`,
120
+ '> **Do not edit by hand.** The canonical prose reference is [\`docs/field-reference.md\`](field-reference.md).',
121
+ '> **Predicate glossary:** [\`docs/glossary.md\`](glossary.md).',
122
+ '> **JSON-LD @context:** [\`schemas/skill.context.jsonld\`](../schemas/skill.context.jsonld).',
123
+ '',
124
+ `Schema version: **${schema.properties.schema_version?.oneOf?.[0]?.const ?? 'unknown'}** · Field count: **${Object.keys(schema.properties).length}** · Required: **${requiredSet.size}**`,
125
+ '',
126
+ '---',
127
+ ''
128
+ ];
129
+
130
+ for (const [name, prop] of Object.entries(schema.properties)) {
131
+ lines.push(renderField(name, prop, requiredSet));
132
+ lines.push('---');
133
+ lines.push('');
134
+ }
135
+
136
+ return lines.join('\n');
137
+ }
138
+
139
+ function main() {
140
+ const args = parseArgs(process.argv);
141
+ const schema = loadSchema();
142
+ const output = render(schema);
143
+
144
+ if (args.check) {
145
+ let existing = '';
146
+ try { existing = fs.readFileSync(args.output, 'utf8'); } catch {}
147
+ if (existing !== output) {
148
+ console.error(`[check] ${args.output} is out of date. Regenerate with: node scripts/build-field-reference.js`);
149
+ process.exit(1);
150
+ }
151
+ console.log(`[check] ${args.output} is up to date.`);
152
+ return;
153
+ }
154
+
155
+ fs.mkdirSync(path.dirname(args.output), { recursive: true });
156
+ fs.writeFileSync(args.output, output, 'utf8');
157
+ console.log(`Wrote ${args.output} (${output.length} bytes, ${Object.keys(schema.properties).length} fields)`);
158
+ }
159
+
160
+ main();