@10up/relay-schemas
v0.4.0
Published
Shared JSON Schemas for Relay content (PRD, notebook, document, asset, path allowlist) consumed by the Relay Cloud MCP server and Relay utilities
Keywords
Readme
@10up/relay-schemas
Shared JSON Schemas for content stored in Relay. This package is the single source of truth for the frontmatter shapes and path-allowlist policy validated by the Relay Cloud MCP server and the Relay client utilities.
Zero runtime dependencies. Pure ESM.
Install
npm install @10up/relay-schemasWhat's in the box
| Export | Description |
| ------------------------------------- | -------------------------------------------------------------------------------- |
| notebookSchema | JSON Schema for notebook frontmatter (agenda, status report, retro, etc.) |
| prdSchema | JSON Schema for PRD frontmatter (status, domain, epic, version) |
| documentWriteSchema | JSON Schema for the Relay Document write-input contract (Claude-authored HTML) |
| pathAllowlistSchema | JSON Schema describing the shape of a path-allowlist policy |
| defaultPathPolicy | Sensible default policy values (allow/deny globs, size limits, secret patterns) |
| DOCUMENT_KINDS | Frozen array of document kinds (status-report, dashboard, allocation, …) |
| DOCUMENT_VISIBILITIES | Frozen array of document visibilities (private, shared) |
| DOCUMENT_STATUSES | Frozen array of document statuses (draft, published) |
| documentSlugPattern | RegExp for the document slug rule (lowercase alphanumeric + hyphens) |
| isValidDocumentSlug(slug) | Returns true if slug is 3+ chars and matches the document slug rule |
| resolveSchemaForPath(path, policy?) | Returns the schema id (prd.json / notebook.json) for a given path, or null |
| isAllowedPath(path, policy?) | Returns true if path is allowed and not denied |
| matchGlob(pattern, value) | Minimal glob matcher supporting ?, *, ** |
You can also import individual schema documents:
import notebookSchema from "@10up/relay-schemas/schemas/notebook.json" with { type: "json" }Quick example
import { notebookSchema, defaultPathPolicy, isAllowedPath } from "@10up/relay-schemas"
// Path policy
isAllowedPath("notebooks/agendas/2026-05-05.md") // → true
isAllowedPath("scripts/ci.sh") // → false (not in allow)
isAllowedPath("anything/.env") // → false (deny wins)
// Validate frontmatter against the notebook schema with your validator of choice.
// AJV example:
import Ajv from "ajv"
import addFormats from "ajv-formats"
const ajv = addFormats(new Ajv({ strict: false }))
const validate = ajv.compile(notebookSchema)
const ok = validate({
title: "Standup 2026-05-05",
kind: "agenda",
created: "2026-05-05T09:30:00Z",
})
console.log(ok, validate.errors)The schemas use the JSON Schema draft 2020-12 vocabulary. Any compliant validator works (AJV, hyperjump, jsonschema, etc.). This package does not bundle a validator.
Default path policy
defaultPathPolicy ships:
- allow:
requirements/**/*.md,requirements/**/*.prd.md,notebooks/**/*.md,research/**/*.md - deny:
**/.git/**,**/node_modules/**,**/.env*,**/secrets/**,**/*.key,**/*.pem - schema mapping:
**/*.prd.md→prd.json,notebooks/**/*.md→notebook.json - limits:
maxFileBytes200 KB,maxBatchBytes1 MB,maxBatchFiles20 - secretPatterns: AWS access keys, Google API keys, OpenAI keys, GitHub tokens, Slack tokens, PEM-format private keys
You can pass your own policy as the second argument to resolveSchemaForPath / isAllowedPath — it must conform to pathAllowlistSchema.
Relay Documents
documentWriteSchema is the canonical input contract for Claude-authored, Fueled-branded HTML documents (status reports, dashboards, allocation reports, QBRs) that Relay Cloud serves directly. These are deliberately separate from the markdown content store and the VitePress build pipeline — the content field carries only the HTML body, and the serving route supplies the brand shell. Documents are upserted by (project, slug).
import { documentWriteSchema, DOCUMENT_KINDS, isValidDocumentSlug } from "@10up/relay-schemas"
DOCUMENT_KINDS // ["status-report", "dashboard", "allocation", "qbr", "generic"]
isValidDocumentSlug("client-status-2026-06-03") // → true
isValidDocumentSlug("Bad Slug") // → falseBecause these schemas use the draft 2020-12 vocabulary, compile them with AJV's 2020 entry point: import Ajv from "ajv/dist/2020".
Versioning
Pre-1.0. Expect breaking changes between minor versions until 1.0.0. Schemas evolve as Relay's content model evolves; consumers should pin a known-good version.
License
MIT © 10up Inc.
