@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,374 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * export-skill.js - SKILL.md export transform.
4
+ *
5
+ * Reads a Skill Graph SKILL.md, moves every Skill Graph extension field under
6
+ * the plain `metadata:` key, and writes a SKILL.md-format export to the skill
7
+ * directory (or to --output <path>).
8
+ *
9
+ * The resulting file has at most 6 top-level fields:
10
+ * name, description, license, compatibility, allowed-tools, metadata
11
+ *
12
+ * Plain SKILL.md metadata is a string-to-string map. Structured Skill Graph
13
+ * extension values are therefore JSON-encoded as strings under metadata.
14
+ *
15
+ * Only the fields that are present in the source are included. Fields that are
16
+ * absent (e.g. license is optional) are omitted from the output rather than
17
+ * written as null.
18
+ *
19
+ * Usage:
20
+ * node scripts/export-skill.js <skill-dir>
21
+ * node scripts/export-skill.js skills/documentation
22
+ * node scripts/export-skill.js skills/documentation --output /tmp/doc.skill-md.md
23
+ *
24
+ * Exit 0 on success, 1 on error.
25
+ *
26
+ * Self-contained. Only uses Node built-ins - no external dependencies.
27
+ */
28
+
29
+ 'use strict';
30
+
31
+ const fs = require('fs');
32
+ const path = require('path');
33
+ const { parseFrontmatter } = require('./lib/parse-frontmatter');
34
+
35
+ // Plain SKILL.md fields that stay at the top level of the output.
36
+ // Order matters for the generated YAML - base fields appear first.
37
+ const SKILL_MD_BASE_FIELDS = ['name', 'description', 'license', 'compatibility', 'allowed-tools'];
38
+
39
+ // Skill Graph extension fields that move under metadata:.
40
+ // Every known Skill Graph extension field is listed here so the set is
41
+ // explicit and auditable. Unknown fields that appear in the frontmatter but
42
+ // are not in either list are placed under metadata: too (fail-safe).
43
+ //
44
+ // Updated for schema_version 4: `category` is the flat browse shelf,
45
+ // `domain` is the hierarchical domain path, `workspace_tags` is authored
46
+ // relevance, and `routing_bundles` is the activation-bundle field. The
47
+ // legacy `family` remains in the set for back-compat with v2 skills during
48
+ // the migration window.
49
+ const SKILL_GRAPH_EXTENSION_FIELDS = new Set([
50
+ 'schema_version',
51
+ 'urn',
52
+ 'version',
53
+ 'type',
54
+ 'archetype',
55
+ 'category',
56
+ 'category',
57
+ 'domain',
58
+ 'family',
59
+ 'scope',
60
+ 'owner',
61
+ 'freshness',
62
+ 'reviewed_at',
63
+ 'drift_check',
64
+ 'eval_artifacts',
65
+ 'eval_state',
66
+ 'routing_eval',
67
+ 'comprehension_state',
68
+ 'eval_last_run',
69
+ 'eval',
70
+ 'stability',
71
+ 'superseded_by',
72
+ 'relations',
73
+ 'grounding',
74
+ 'portability',
75
+ 'concept',
76
+ 'triggers',
77
+ 'keywords',
78
+ 'paths',
79
+ 'workspace_tags',
80
+ 'routing_bundles',
81
+ 'lifecycle',
82
+ 'runtime_telemetry',
83
+ 'extends',
84
+ 'allowed_tools',
85
+ ]);
86
+
87
+ /**
88
+ * Flatten a v3 `compatibility` object to a single free-text string suitable
89
+ * for the plain SKILL.md `compatibility` field.
90
+ *
91
+ * v3 shape: { runtimes?: string[], node?: string, notes?: string }
92
+ * v2 shape: string (passed through unchanged)
93
+ *
94
+ * Concatenation order: runtimes, node, notes - joined with "; ".
95
+ */
96
+ function flattenCompatibility(value) {
97
+ if (typeof value === 'string') return value;
98
+ if (!value || typeof value !== 'object') return null;
99
+ const parts = [];
100
+ const runtimes = Array.isArray(value.runtimes) && value.runtimes.length > 0
101
+ ? value.runtimes
102
+ : value.agent_runtimes;
103
+ if (Array.isArray(runtimes) && runtimes.length > 0) {
104
+ parts.push(runtimes.join(', '));
105
+ }
106
+ const nodeVersion = value.node || value.node_version;
107
+ if (nodeVersion) parts.push(`node ${nodeVersion}`);
108
+ if (value.notes) parts.push(value.notes);
109
+ return parts.join('; ');
110
+ }
111
+
112
+ function validateName(name) {
113
+ return typeof name === 'string' && name.length > 0
114
+ ? { ok: true }
115
+ : { ok: false };
116
+ }
117
+
118
+ function normalizeExportName(name) {
119
+ return String(name || '')
120
+ .replace(/[/:]/g, '-')
121
+ .replace(/-+/g, '-')
122
+ .replace(/^-|-$/g, '');
123
+ }
124
+
125
+ /**
126
+ * Serialize a JavaScript value to YAML-compatible text at the given
127
+ * indentation depth. Handles strings, numbers, booleans, null, arrays,
128
+ * and plain objects. Does not handle multi-line strings or anchors.
129
+ *
130
+ * @param {*} value - Value to serialize.
131
+ * @param {number} depth - Current indent depth (2 spaces per level).
132
+ * @returns {string} YAML fragment (no trailing newline).
133
+ */
134
+ function serializeValue(value, depth) {
135
+ const indent = ' '.repeat(depth);
136
+
137
+ if (value === null || value === undefined) {
138
+ return 'null';
139
+ }
140
+ if (typeof value === 'boolean' || typeof value === 'number') {
141
+ return String(value);
142
+ }
143
+ if (typeof value === 'string') {
144
+ // Quote strings that contain special YAML characters or that look
145
+ // like numbers/booleans, to avoid silent type coercion on re-parse.
146
+ const needsQuote = /[:#\[\]{}&*!|>'"%@`,]/.test(value)
147
+ || /^\s/.test(value)
148
+ || /\s$/.test(value)
149
+ || value === ''
150
+ || /^(true|false|null|~|\d.*)$/i.test(value);
151
+ if (needsQuote) {
152
+ return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
153
+ }
154
+ return value;
155
+ }
156
+ if (Array.isArray(value)) {
157
+ if (value.length === 0) return '[]';
158
+ return '\n' + value
159
+ .map(item => `${indent}- ${serializeValue(item, depth + 1)}`)
160
+ .join('\n');
161
+ }
162
+ if (typeof value === 'object') {
163
+ const keys = Object.keys(value);
164
+ if (keys.length === 0) return '{}';
165
+ return '\n' + keys
166
+ .map(k => {
167
+ const v = value[k];
168
+ const serialized = serializeValue(v, depth + 1);
169
+ // If the serialized value starts with a newline, the key goes on its
170
+ // own line (block mapping); otherwise it is an inline scalar.
171
+ if (serialized.startsWith('\n')) {
172
+ return `${indent}${k}:${serialized}`;
173
+ }
174
+ return `${indent}${k}: ${serialized}`;
175
+ })
176
+ .join('\n');
177
+ }
178
+ return String(value);
179
+ }
180
+
181
+ /**
182
+ * Convert a Skill Graph extension value into a plain SKILL.md metadata string.
183
+ * Metadata exports use string keys to string values, so objects and arrays are
184
+ * preserved as compact JSON strings.
185
+ *
186
+ * @param {*} value - Parsed Skill Graph frontmatter value.
187
+ * @returns {string|null} Metadata-safe string value.
188
+ */
189
+ function metadataStringValue(value) {
190
+ if (value === null || value === undefined) return null;
191
+ if (typeof value === 'string') return value;
192
+ if (typeof value === 'number' || typeof value === 'boolean') return String(value);
193
+ try {
194
+ return JSON.stringify(value);
195
+ } catch (e) {
196
+ return String(value);
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Build the output YAML frontmatter from the parsed frontmatter object.
202
+ * Only includes fields that are actually present in the source.
203
+ *
204
+ * @param {object} fm - Parsed frontmatter.
205
+ * @returns {string} - Full frontmatter block including --- delimiters.
206
+ */
207
+ function buildFrontmatter(fm, options = {}) {
208
+ const lines = ['---'];
209
+
210
+ // 1. Top-level plain SKILL.md fields (in canonical order).
211
+ for (const field of SKILL_MD_BASE_FIELDS) {
212
+ if (!(field in fm) || fm[field] === null || fm[field] === undefined) {
213
+ if (field !== 'allowed-tools' || fm.allowed_tools === null || fm.allowed_tools === undefined) continue;
214
+ }
215
+ // v3: compatibility is an object; plain SKILL.md wants a string. Flatten.
216
+ let value = field === 'allowed-tools' && !(field in fm) ? fm.allowed_tools : fm[field];
217
+ if (field === 'name') {
218
+ value = normalizeExportName(value);
219
+ }
220
+ if (field === 'compatibility' && typeof value === 'object' && value !== null) {
221
+ value = flattenCompatibility(value);
222
+ if (!value) continue;
223
+ }
224
+ const serialized = serializeValue(value, 1);
225
+ if (serialized.startsWith('\n')) {
226
+ lines.push(`${field}:${serialized}`);
227
+ } else {
228
+ lines.push(`${field}: ${serialized}`);
229
+ }
230
+ }
231
+
232
+ // 2. Gather all fields that belong under metadata:.
233
+ // Metadata export values are strings, so structured extension values
234
+ // are JSON-encoded rather than emitted as nested YAML objects.
235
+ const metadataEntries = {};
236
+ for (const [key, value] of Object.entries(fm)) {
237
+ if (SKILL_MD_BASE_FIELDS.includes(key)) continue;
238
+ if (key === 'allowed_tools') continue;
239
+ if (value === null || value === undefined) continue;
240
+ const metadataValue = metadataStringValue(value);
241
+ if (metadataValue !== null) metadataEntries[key] = metadataValue;
242
+ }
243
+
244
+ if (options.metadata && typeof options.metadata === 'object') {
245
+ for (const [key, value] of Object.entries(options.metadata)) {
246
+ const metadataValue = metadataStringValue(value);
247
+ if (metadataValue !== null) metadataEntries[key] = metadataValue;
248
+ }
249
+ }
250
+
251
+ if (Object.keys(metadataEntries).length > 0) {
252
+ lines.push('metadata:');
253
+ for (const [key, value] of Object.entries(metadataEntries)) {
254
+ const serialized = serializeValue(value, 2);
255
+ if (serialized.startsWith('\n')) {
256
+ lines.push(` ${key}:${serialized}`);
257
+ } else {
258
+ lines.push(` ${key}: ${serialized}`);
259
+ }
260
+ }
261
+ }
262
+
263
+ lines.push('---');
264
+ return lines.join('\n');
265
+ }
266
+
267
+ /**
268
+ * Extract the Markdown body (everything after the closing ---).
269
+ *
270
+ * @param {string} text - Full file contents.
271
+ * @returns {string} - Body text (may be empty string).
272
+ */
273
+ function extractBody(text) {
274
+ const m = text.match(/^\uFEFF?---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)([\s\S]*)$/);
275
+ return m ? m[1] : '';
276
+ }
277
+
278
+ function buildExportedSkill(text, options = {}) {
279
+ const fm = parseFrontmatter(text);
280
+ if (!fm) return null;
281
+ const exportFm = { ...fm };
282
+ if (options.description) exportFm.description = options.description;
283
+ const frontmatter = buildFrontmatter(exportFm, options);
284
+ const body = extractBody(text);
285
+ return body.trimEnd()
286
+ ? `${frontmatter}\n${body}`
287
+ : `${frontmatter}\n`;
288
+ }
289
+
290
+ function main() {
291
+ const args = process.argv.slice(2);
292
+
293
+ if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
294
+ console.log(`Usage: node scripts/export-skill.js <skill-dir> [--output <path>]
295
+
296
+ Exports a Skill Graph SKILL.md as a plain SKILL.md-format file.
297
+
298
+ Arguments:
299
+ <skill-dir> Path to the skill directory (must contain SKILL.md)
300
+ --output <path> Write output to this path instead of
301
+ <skill-dir>/SKILL.skill-md.md
302
+
303
+ Exit 0 on success, 1 on error.`);
304
+ process.exit(0);
305
+ }
306
+
307
+ // Parse --output flag
308
+ let outputPath = null;
309
+ const outputIdx = args.indexOf('--output');
310
+ if (outputIdx !== -1) {
311
+ if (!args[outputIdx + 1]) {
312
+ console.error('Error: --output requires a path argument.');
313
+ process.exit(1);
314
+ }
315
+ outputPath = path.resolve(args[outputIdx + 1]);
316
+ args.splice(outputIdx, 2);
317
+ }
318
+
319
+ // First remaining non-flag arg is the skill directory
320
+ const skillDir = args.find(a => !a.startsWith('--'));
321
+ if (!skillDir) {
322
+ console.error('Error: no skill directory specified.');
323
+ process.exit(1);
324
+ }
325
+
326
+ const skillDirAbs = path.resolve(skillDir);
327
+ const skillMd = path.join(skillDirAbs, 'SKILL.md');
328
+
329
+ if (!fs.existsSync(skillMd)) {
330
+ console.error(`Error: ${skillMd} not found.`);
331
+ process.exit(1);
332
+ }
333
+
334
+ const text = fs.readFileSync(skillMd, 'utf8');
335
+ const fm = parseFrontmatter(text);
336
+
337
+ if (!fm) {
338
+ console.error(`Error: no YAML frontmatter found in ${skillMd}.`);
339
+ process.exit(1);
340
+ }
341
+
342
+ // Validate required identity field.
343
+ if (!fm.name) {
344
+ console.error('Error: frontmatter is missing the required "name" field.');
345
+ process.exit(1);
346
+ }
347
+ const nameCheck = validateName(fm.name);
348
+ if (!nameCheck.ok) {
349
+ console.error('Error: frontmatter field "name" must be a non-empty string.');
350
+ process.exit(1);
351
+ }
352
+
353
+ const output = buildExportedSkill(text);
354
+
355
+ const dest = outputPath || path.join(skillDirAbs, 'SKILL.skill-md.md');
356
+ fs.writeFileSync(dest, output, 'utf8');
357
+ console.log(`Exported: ${dest}`);
358
+ process.exit(0);
359
+ }
360
+
361
+ module.exports = {
362
+ SKILL_MD_BASE_FIELDS,
363
+ SKILL_GRAPH_EXTENSION_FIELDS,
364
+ buildFrontmatter,
365
+ buildExportedSkill,
366
+ extractBody,
367
+ flattenCompatibility,
368
+ metadataStringValue,
369
+ normalizeExportName,
370
+ serializeValue,
371
+ validateName,
372
+ };
373
+
374
+ if (require.main === module) main();