@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.
- package/CHANGELOG.md +247 -0
- package/LICENSE +200 -0
- package/NOTICE +62 -0
- package/README.md +398 -0
- package/SKILL_GRAPH.md +443 -0
- package/bin/skill-graph.js +374 -0
- package/docs/ADOPTION.md +117 -0
- package/docs/CONFORMANCE.md +66 -0
- package/docs/PRIMER.md +384 -0
- package/docs/QUICKSTART-30MIN.md +333 -0
- package/docs/ROUTING-METRICS.md +120 -0
- package/docs/SKILL-MD-FORMAT-COMPATIBILITY.md +127 -0
- package/docs/SKILL_AUDIT_CHECKLIST.md +199 -0
- package/docs/SKILL_AUDIT_LOOP.md +195 -0
- package/docs/SKILL_METADATA_PROTOCOL.md +609 -0
- package/docs/_archived/marketplace-publication-priority-2026-05-18.md +239 -0
- package/docs/adr/0001-predicate-set.md +69 -0
- package/docs/adr/0002-json-ld-context.md +82 -0
- package/docs/adr/0003-ontoclean-rigidity-tags.md +65 -0
- package/docs/adr/0004-persistent-identifiers.md +74 -0
- package/docs/adr/0005-freshness-consolidation.md +70 -0
- package/docs/adr/0006-revise-predicate-rename.md +105 -0
- package/docs/adr/0007-audit-loop-cadence.md +99 -0
- package/docs/adr/0008-skill-surface-split-and-curation-policy.md +93 -0
- package/docs/category-consumers.md +168 -0
- package/docs/concept-map.md +194 -0
- package/docs/diagrams/drift-states.mmd +21 -0
- package/docs/diagrams/manifest-pipeline.mmd +25 -0
- package/docs/diagrams/routing-harness.mmd +41 -0
- package/docs/diagrams/starter-graph.mmd +53 -0
- package/docs/field-decision-guide.md +315 -0
- package/docs/field-rationale.md +211 -0
- package/docs/field-reference.generated.md +624 -0
- package/docs/field-reference.md +1426 -0
- package/docs/glossary.md +190 -0
- package/docs/head-noun-glossary.md +63 -0
- package/docs/images/audit-phases.png +0 -0
- package/docs/images/drift-states.png +0 -0
- package/docs/images/graded-mode.png +0 -0
- package/docs/images/manifest-pipeline.png +0 -0
- package/docs/images/routing-harness.png +0 -0
- package/docs/images/skill-anatomy.png +0 -0
- package/docs/images/starter-graph.png +0 -0
- package/docs/images/system-model.png +0 -0
- package/docs/integrations/github-actions.md +155 -0
- package/docs/manifest-field-mapping.md +443 -0
- package/docs/marketplace-publication-queue.generated.md +240 -0
- package/docs/marketplace-release-agent-prompt.md +82 -0
- package/docs/marketplace-skill-candidate-list.md +272 -0
- package/docs/marketplace-syndication.md +222 -0
- package/docs/migration-sample-review.md +155 -0
- package/docs/migrations/v4-to-v5.md +168 -0
- package/docs/migrations/v5-to-v6.md +221 -0
- package/docs/name-exceptions.yaml +37 -0
- package/docs/plans/marketplace-p1-public-migration-plan.md +41 -0
- package/docs/plans/multi-root-workspace.md +148 -0
- package/docs/plans/scripts-roadmap.md +107 -0
- package/docs/plans/v4-schema-bump.md +160 -0
- package/docs/plans/wave-2-extraction.md +122 -0
- package/docs/positioning-vs-marketplaces.md +175 -0
- package/docs/proposals/skill-audit-loop-positioning.md +160 -0
- package/docs/quality-doctrine.md +138 -0
- package/docs/recommended-skills.md +150 -0
- package/docs/research/skill-comprehension-eval-research.md +1830 -0
- package/docs/research/skill-retrieval-evidence.md +66 -0
- package/docs/skill-metadata-protocol.md +471 -0
- package/docs/skills-sh-maintainer-cleanup-request.md +80 -0
- package/examples/audits/a11y/findings.md +52 -0
- package/examples/audits/a11y/scorecard.md +21 -0
- package/examples/audits/a11y/verdict.md +44 -0
- package/examples/audits/debugging/findings.md +59 -0
- package/examples/audits/debugging/scorecard.md +22 -0
- package/examples/audits/debugging/verdict.md +33 -0
- package/examples/audits/documentation/findings.md +59 -0
- package/examples/audits/documentation/scorecard.md +22 -0
- package/examples/audits/documentation/verdict.md +33 -0
- package/examples/evals/a11y.json +140 -0
- package/examples/evals/api-design.json +52 -0
- package/examples/evals/code-review.json +52 -0
- package/examples/evals/data-modeling.json +52 -0
- package/examples/evals/database-migration.json +52 -0
- package/examples/evals/debugging.json +118 -0
- package/examples/evals/dependency-architecture.json +52 -0
- package/examples/evals/design-system-architecture.json +52 -0
- package/examples/evals/error-tracking.json +52 -0
- package/examples/evals/event-contract-design.json +52 -0
- package/examples/evals/form-ux-architecture.json +52 -0
- package/examples/evals/framework-fit-analysis.json +52 -0
- package/examples/evals/graph-audit.json +139 -0
- package/examples/evals/information-architecture.json +52 -0
- package/examples/evals/interaction-feedback.json +52 -0
- package/examples/evals/interaction-patterns.json +52 -0
- package/examples/evals/layout-composition.json +52 -0
- package/examples/evals/lint-overlay.json +117 -0
- package/examples/evals/microcopy.json +52 -0
- package/examples/evals/observability-modeling.json +52 -0
- package/examples/evals/pattern-recognition.json +96 -0
- package/examples/evals/performance-engineering.json +52 -0
- package/examples/evals/refactor.json +128 -0
- package/examples/evals/semiotics.json +52 -0
- package/examples/evals/skill-infrastructure.json +96 -0
- package/examples/evals/skill-router.json +140 -0
- package/examples/evals/skill-router.routing.json +113 -0
- package/examples/evals/system-interface-contracts.json +52 -0
- package/examples/evals/task-analysis.json +52 -0
- package/examples/evals/testing-strategy.json +118 -0
- package/examples/evals/type-safety.json +249 -0
- package/examples/evals/visual-design-foundations.json +52 -0
- package/examples/evals/webhook-integration.json +52 -0
- package/examples/exports/a11y.skill-md.md +80 -0
- package/examples/exports/debugging.skill-md.md +80 -0
- package/examples/exports/refactor.skill-md.md +78 -0
- package/examples/exports/testing-strategy.skill-md.md +81 -0
- package/examples/projects/markdown-static-site/README.md +115 -0
- package/examples/projects/markdown-static-site/skills/content-source-router/SKILL.md +131 -0
- package/examples/projects/markdown-static-site/skills/image-optimization-pipeline-config/SKILL.md +132 -0
- package/examples/projects/markdown-static-site/skills/link-rot-detection/SKILL.md +103 -0
- package/examples/projects/markdown-static-site/skills/markdown-post-frontmatter-validation/SKILL.md +133 -0
- package/examples/projects/markdown-static-site/skills/migrate-posts-to-v2-frontmatter/SKILL.md +140 -0
- package/examples/projects/saas-stripe-postgres/README.md +208 -0
- package/examples/projects/saas-stripe-postgres/db/migrations/0004_canonicalize_orders.sql +37 -0
- package/examples/projects/saas-stripe-postgres/db/schema.sql +112 -0
- package/examples/projects/saas-stripe-postgres/skills/migrate-orders-to-canonical-schema/SKILL.md +149 -0
- package/examples/projects/saas-stripe-postgres/skills/nextjs-server-action-validation/SKILL.md +154 -0
- package/examples/projects/saas-stripe-postgres/skills/payment-provider-router/SKILL.md +153 -0
- package/examples/projects/saas-stripe-postgres/skills/postgres-rls-pattern/SKILL.md +163 -0
- package/examples/projects/saas-stripe-postgres/skills/stripe-webhook-signature-verification/SKILL.md +137 -0
- package/examples/protocol/skill-metadata-template.md +301 -0
- package/examples/protocol/skills.manifest.sample.json +13245 -0
- package/examples/skill-metadata-template.md +317 -0
- package/examples/skills.manifest.sample.json +13519 -0
- package/examples/tests/v3-1-skos-fixture/SKILL.md +93 -0
- package/marketplace/README.md +17 -0
- package/marketplace/skills/a11y/SKILL.md +66 -0
- package/marketplace/skills/acid-fundamentals/SKILL.md +106 -0
- package/marketplace/skills/agent-engineering/SKILL.md +386 -0
- package/marketplace/skills/agent-eval-design/SKILL.md +55 -0
- package/marketplace/skills/ai-native-development/SKILL.md +294 -0
- package/marketplace/skills/api-design/SKILL.md +60 -0
- package/marketplace/skills/architecture-decision-records/SKILL.md +55 -0
- package/marketplace/skills/background-jobs/SKILL.md +265 -0
- package/marketplace/skills/bounded-context-mapping/SKILL.md +55 -0
- package/marketplace/skills/cap-theorem-tradeoffs/SKILL.md +127 -0
- package/marketplace/skills/client-server-boundary/SKILL.md +187 -0
- package/marketplace/skills/code-review/SKILL.md +120 -0
- package/marketplace/skills/color-system-design/SKILL.md +43 -0
- package/marketplace/skills/component-architecture/SKILL.md +126 -0
- package/marketplace/skills/compression/SKILL.md +112 -0
- package/marketplace/skills/conceptual-modeling/SKILL.md +181 -0
- package/marketplace/skills/connection-pooling/SKILL.md +105 -0
- package/marketplace/skills/constraint-awareness/SKILL.md +287 -0
- package/marketplace/skills/content-monitor/SKILL.md +209 -0
- package/marketplace/skills/context-engineering/SKILL.md +320 -0
- package/marketplace/skills/context-graph/SKILL.md +174 -0
- package/marketplace/skills/context-management/SKILL.md +174 -0
- package/marketplace/skills/context-window/SKILL.md +239 -0
- package/marketplace/skills/contract-testing/SKILL.md +120 -0
- package/marketplace/skills/cron-scheduling/SKILL.md +223 -0
- package/marketplace/skills/dark-mode-implementation/SKILL.md +47 -0
- package/marketplace/skills/data-modeling/SKILL.md +59 -0
- package/marketplace/skills/data-modeling-fundamentals/SKILL.md +117 -0
- package/marketplace/skills/database-migration/SKILL.md +429 -0
- package/marketplace/skills/debugging/SKILL.md +67 -0
- package/marketplace/skills/dependency-architecture/SKILL.md +58 -0
- package/marketplace/skills/design-module-composition/SKILL.md +43 -0
- package/marketplace/skills/design-system-architecture/SKILL.md +61 -0
- package/marketplace/skills/design-thinking/SKILL.md +44 -0
- package/marketplace/skills/diagnosis/SKILL.md +296 -0
- package/marketplace/skills/diff-analysis/SKILL.md +188 -0
- package/marketplace/skills/e2e-test-design/SKILL.md +113 -0
- package/marketplace/skills/entity-relationship-modeling/SKILL.md +218 -0
- package/marketplace/skills/epistemic-grounding/SKILL.md +112 -0
- package/marketplace/skills/error-boundary/SKILL.md +235 -0
- package/marketplace/skills/error-tracking/SKILL.md +261 -0
- package/marketplace/skills/eval-driven-development/SKILL.md +147 -0
- package/marketplace/skills/evaluation/SKILL.md +113 -0
- package/marketplace/skills/event-contract-design/SKILL.md +60 -0
- package/marketplace/skills/event-storming/SKILL.md +56 -0
- package/marketplace/skills/form-ux-architecture/SKILL.md +60 -0
- package/marketplace/skills/framework-fit-analysis/SKILL.md +59 -0
- package/marketplace/skills/frontend-architecture/SKILL.md +43 -0
- package/marketplace/skills/generative-ui/SKILL.md +118 -0
- package/marketplace/skills/graph-audit/SKILL.md +81 -0
- package/marketplace/skills/guardrails/SKILL.md +118 -0
- package/marketplace/skills/hooks-patterns/SKILL.md +185 -0
- package/marketplace/skills/http-semantics/SKILL.md +136 -0
- package/marketplace/skills/ideation/SKILL.md +41 -0
- package/marketplace/skills/indexing-strategy/SKILL.md +108 -0
- package/marketplace/skills/information-architecture/SKILL.md +59 -0
- package/marketplace/skills/integration-test-design/SKILL.md +111 -0
- package/marketplace/skills/intent-recognition/SKILL.md +136 -0
- package/marketplace/skills/interaction-feedback/SKILL.md +59 -0
- package/marketplace/skills/interaction-patterns/SKILL.md +59 -0
- package/marketplace/skills/journey-mapping/SKILL.md +41 -0
- package/marketplace/skills/keywords/SKILL.md +213 -0
- package/marketplace/skills/knowledge-modeling/SKILL.md +232 -0
- package/marketplace/skills/layout-composition/SKILL.md +59 -0
- package/marketplace/skills/linguistics/SKILL.md +429 -0
- package/marketplace/skills/lint-overlay/SKILL.md +76 -0
- package/marketplace/skills/mental-models/SKILL.md +126 -0
- package/marketplace/skills/merge-queue/SKILL.md +94 -0
- package/marketplace/skills/methodology/SKILL.md +317 -0
- package/marketplace/skills/microcopy/SKILL.md +232 -0
- package/marketplace/skills/middleware-patterns/SKILL.md +363 -0
- package/marketplace/skills/mobile-responsive-ux/SKILL.md +287 -0
- package/marketplace/skills/mutation-testing/SKILL.md +112 -0
- package/marketplace/skills/naming-conventions/SKILL.md +112 -0
- package/marketplace/skills/observability-modeling/SKILL.md +59 -0
- package/marketplace/skills/ontology-modeling/SKILL.md +67 -0
- package/marketplace/skills/owasp-security/SKILL.md +153 -0
- package/marketplace/skills/pattern-recognition/SKILL.md +472 -0
- package/marketplace/skills/performance-budgets/SKILL.md +185 -0
- package/marketplace/skills/performance-engineering/SKILL.md +58 -0
- package/marketplace/skills/performance-testing/SKILL.md +125 -0
- package/marketplace/skills/printify/SKILL.md +42 -0
- package/marketplace/skills/prioritization/SKILL.md +118 -0
- package/marketplace/skills/problem-framing/SKILL.md +41 -0
- package/marketplace/skills/problem-locating-solving/SKILL.md +203 -0
- package/marketplace/skills/project-knowledge-extraction/SKILL.md +54 -0
- package/marketplace/skills/prompt-craft/SKILL.md +134 -0
- package/marketplace/skills/prompt-injection-defense/SKILL.md +132 -0
- package/marketplace/skills/property-based-testing/SKILL.md +100 -0
- package/marketplace/skills/prototyping/SKILL.md +43 -0
- package/marketplace/skills/query-optimization/SKILL.md +144 -0
- package/marketplace/skills/real-time-updates/SKILL.md +324 -0
- package/marketplace/skills/ref-patterns/SKILL.md +284 -0
- package/marketplace/skills/refactor/SKILL.md +65 -0
- package/marketplace/skills/rendering-models/SKILL.md +142 -0
- package/marketplace/skills/replication-patterns/SKILL.md +110 -0
- package/marketplace/skills/research-synthesis/SKILL.md +41 -0
- package/marketplace/skills/route-handler-design/SKILL.md +347 -0
- package/marketplace/skills/schema-evolution/SKILL.md +140 -0
- package/marketplace/skills/security-fundamentals/SKILL.md +139 -0
- package/marketplace/skills/semantic-center/SKILL.md +194 -0
- package/marketplace/skills/semantic-relations/SKILL.md +250 -0
- package/marketplace/skills/semantics/SKILL.md +366 -0
- package/marketplace/skills/semiotics/SKILL.md +230 -0
- package/marketplace/skills/seo-strategy/SKILL.md +260 -0
- package/marketplace/skills/server-actions-design/SKILL.md +243 -0
- package/marketplace/skills/server-components-design/SKILL.md +190 -0
- package/marketplace/skills/sharding-strategy/SKILL.md +123 -0
- package/marketplace/skills/shopify/SKILL.md +42 -0
- package/marketplace/skills/skill-infrastructure/SKILL.md +320 -0
- package/marketplace/skills/skill-router/SKILL.md +71 -0
- package/marketplace/skills/skill-scaffold/SKILL.md +105 -0
- package/marketplace/skills/snapshot-testing/SKILL.md +120 -0
- package/marketplace/skills/spec-driven-development/SKILL.md +148 -0
- package/marketplace/skills/state-machine-modeling/SKILL.md +56 -0
- package/marketplace/skills/state-management/SKILL.md +134 -0
- package/marketplace/skills/streaming-architecture/SKILL.md +194 -0
- package/marketplace/skills/summarization/SKILL.md +156 -0
- package/marketplace/skills/suspense-patterns/SKILL.md +265 -0
- package/marketplace/skills/system-interface-contracts/SKILL.md +59 -0
- package/marketplace/skills/task-analysis/SKILL.md +201 -0
- package/marketplace/skills/taxonomy-design/SKILL.md +66 -0
- package/marketplace/skills/test-coverage-strategy/SKILL.md +108 -0
- package/marketplace/skills/test-doubles-design/SKILL.md +98 -0
- package/marketplace/skills/test-driven-development/SKILL.md +96 -0
- package/marketplace/skills/testing-strategy/SKILL.md +67 -0
- package/marketplace/skills/theme-system-design/SKILL.md +43 -0
- package/marketplace/skills/tool-call-flow/SKILL.md +229 -0
- package/marketplace/skills/tool-call-strategy/SKILL.md +292 -0
- package/marketplace/skills/transaction-isolation/SKILL.md +98 -0
- package/marketplace/skills/type-safety/SKILL.md +177 -0
- package/marketplace/skills/typography-system/SKILL.md +43 -0
- package/marketplace/skills/usability-testing/SKILL.md +43 -0
- package/marketplace/skills/user-research/SKILL.md +43 -0
- package/marketplace/skills/vercel-composition-patterns/SKILL.md +157 -0
- package/marketplace/skills/version-control/SKILL.md +233 -0
- package/marketplace/skills/visual-design-foundations/SKILL.md +59 -0
- package/marketplace/skills/visual-hierarchy/SKILL.md +43 -0
- package/marketplace/skills/webhook-integration/SKILL.md +331 -0
- package/marketplace/skills/writing-humanizer/SKILL.md +380 -0
- package/package.json +67 -0
- package/schemas/manifest.schema.json +811 -0
- package/schemas/manifest.v2.schema.json +164 -0
- package/schemas/manifest.v3.schema.json +758 -0
- package/schemas/manifest.v4.schema.json +755 -0
- package/schemas/manifest.v5.schema.json +755 -0
- package/schemas/manifest.v6.schema.json +811 -0
- package/schemas/skill.context.jsonld +279 -0
- package/schemas/skill.schema.json +919 -0
- package/schemas/skill.v2.schema.json +201 -0
- package/schemas/skill.v3.schema.json +827 -0
- package/schemas/skill.v4.schema.json +822 -0
- package/schemas/skill.v5.schema.json +830 -0
- package/schemas/skill.v6.schema.json +946 -0
- package/schemas/vocabulary/keywords.json +180 -0
- package/schemas/vocabulary/workspace_tags.json +23 -0
- package/scripts/__tests__/migrate-skill-v2-to-v3.test.js +161 -0
- package/scripts/__tests__/migrate-skill-v3-to-v4.test.js +158 -0
- package/scripts/__tests__/test-export-parser-drift.js +149 -0
- package/scripts/__tests__/test-marketplace-export.js +114 -0
- package/scripts/__tests__/test-router-paths.js +82 -0
- package/scripts/__tests__/test-stability-promotion.js +244 -0
- package/scripts/__tests__/test-v3-1-alias-contract.js +109 -0
- package/scripts/__tests__/test-v3-1-skos-runtime.js +116 -0
- package/scripts/backfill-schema-version.js +198 -0
- package/scripts/build-field-reference.js +160 -0
- package/scripts/build-retrieval-baseline.js +511 -0
- package/scripts/check-markdown-links.js +211 -0
- package/scripts/check-protocol-consistency.js +979 -0
- package/scripts/export-marketplace-skills.js +610 -0
- package/scripts/export-skill.js +374 -0
- package/scripts/generate-manifest.js +787 -0
- package/scripts/lib/alias-contract.js +83 -0
- package/scripts/lib/audit-prompt-builder.js +771 -0
- package/scripts/lib/mock-grader.js +134 -0
- package/scripts/lib/parse-frontmatter.js +429 -0
- package/scripts/lib/roots.js +119 -0
- package/scripts/lint/check-archetype-sections.js +185 -0
- package/scripts/lint/check-category-enum.js +83 -0
- package/scripts/lint/check-routing-eval.js +146 -0
- package/scripts/lint/check-routing-quality.js +211 -0
- package/scripts/lint/check-stability-promotion.js +220 -0
- package/scripts/lint/format-code-frame.js +206 -0
- package/scripts/marketplace-install.js +125 -0
- package/scripts/migrate-category-to-enum.js +169 -0
- package/scripts/migrate-skill-v2-to-v3.js +424 -0
- package/scripts/migrate-skill-v3-to-v4.js +200 -0
- package/scripts/migrate-skill-v5-to-v6.js +304 -0
- package/scripts/restructure-by-category.js +85 -0
- package/scripts/seed-publication-classification.js +282 -0
- package/scripts/skill-audit.js +893 -0
- package/scripts/skill-graph-drift.js +483 -0
- package/scripts/skill-graph-route.js +766 -0
- package/scripts/skill-graph-routing-eval.js +393 -0
- package/scripts/skill-lint.js +1317 -0
- package/scripts/skill-overlap.js +213 -0
- 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();
|