@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,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();
|