Files
hyperframes/packages/core/schemas/registry-item.json
Miguel Ángel 4d05b475f0 feat: add Stronkter catalog blocks (#570)
## Problem

The Catalog did not include the four prompt-matched Stronkter one-shot HyperFrames projects, and registry metadata only supported a plain author string, so there was no structured way to show creator attribution or the original generation prompt on generated catalog pages.

## What this fixes

- Adds four Catalog blocks matching the provided prompts, in order:
  - `north-korea-locked-down`
  - `apple-money-count`
  - `nyc-paris-flight`
  - `goonvpn-youtube-spot`
- Attributes each block to [Stronkter](https://x.com/Stronkter).
- Stores and renders the original source prompt for each generated catalog page.
- Adds a local realistic map plate for the North Korea block so rendering does not depend on live map tile requests.
- Extends registry item metadata/schema with `authorUrl` and `sourcePrompt`.
- Updates catalog page generation to read items from `registry/registry.json`, keeping generated docs aligned to the public registry manifest.
- Ignores normal browser media preload `net::ERR_ABORTED` request failures for media assets during `hyperframes validate`, while preserving failures for real missing assets.

## Root cause

The imported projects are Catalog-ready compositions, but the registry/docs pipeline did not have first-class source-prompt or linked-author fields to expose creator credit on generated MDX pages. The audio-backed compositions also surfaced a validation edge case: Chrome can report aborted media preload requests as `net::ERR_ABORTED` even when the audio file exists and playback is valid.

## Verification

### Local

- `bun run --filter @hyperframes/cli test src/commands/validate.test.ts`
- `bun run --filter @hyperframes/core test src/registry/types.test.ts`
- `bun run sync-schemas:check`
- `bunx oxlint packages/cli/src/commands/validate.ts packages/cli/src/commands/validate.test.ts packages/core/src/registry/types.ts packages/core/src/registry/types.test.ts scripts/generate-catalog-pages.ts`
- `bunx oxfmt --check ...` on changed source, registry, docs, and composition files
- `git diff --check`
- `bun packages/cli/src/cli.ts lint` and `validate` against temp installed projects for all four blocks
- Lefthook pre-commit: lint/format/typecheck on the initial commit, plus format on the amend
- Lefthook commit-msg: commitlint

### Browser

- Exercised all four blocks through HyperFrames preview routes with `agent-browser`.
- Captured playback screenshots and WebM recordings for:
  - `north-korea-locked-down`
  - `apple-money-count`
  - `nyc-paris-flight`
  - `goonvpn-youtube-spot`

## Notes

- The zip also contained unrelated project directories, but this PR intentionally includes only the four prompt-matched Catalog blocks requested here.
- The imported one-shot compositions may trigger the existing large-composition lint warning, but there are no lint errors and runtime validation passes.
2026-04-29 22:59:19 +02:00

150 lines
4.0 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://hyperframes.heygen.com/schema/registry-item.json",
"title": "Hyperframes Registry Item",
"description": "Manifest for a single distributable item (example, block, or component).",
"type": "object",
"required": ["name", "type", "title", "description", "files"],
"properties": {
"$schema": {
"type": "string",
"format": "uri"
},
"name": {
"type": "string",
"pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$",
"description": "Item name in kebab-case, must start and end with alphanumeric."
},
"type": {
"type": "string",
"enum": ["hyperframes:example", "hyperframes:block", "hyperframes:component"]
},
"title": {
"type": "string",
"minLength": 1
},
"description": {
"type": "string",
"minLength": 1
},
"tags": {
"type": "array",
"items": { "type": "string", "minLength": 1 }
},
"author": {
"type": "string",
"minLength": 1
},
"authorUrl": {
"type": "string",
"format": "uri"
},
"sourcePrompt": {
"type": "string",
"minLength": 1
},
"license": {
"type": "string",
"minLength": 1,
"description": "SPDX license identifier (e.g. \"Apache-2.0\", \"MIT\")."
},
"minCliVersion": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$",
"description": "Minimum `hyperframes` CLI version required to install this item."
},
"deprecated": {
"type": "string",
"minLength": 1,
"description": "If set, the item is deprecated; the value is the reason or migration note."
},
"dimensions": {
"type": "object",
"required": ["width", "height"],
"additionalProperties": false,
"properties": {
"width": { "type": "integer", "minimum": 1 },
"height": { "type": "integer", "minimum": 1 }
}
},
"duration": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Duration in seconds. Must be > 0."
},
"registryDependencies": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
}
},
"files": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["path", "target", "type"],
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"minLength": 1,
"description": "Source path, relative to registry-item.json."
},
"target": {
"type": "string",
"minLength": 1,
"description": "Destination path in the user's project, relative to project root. Must not traverse outside the project (no `..` segments, no absolute paths).",
"not": {
"anyOf": [
{ "pattern": "(^|[/\\\\])\\.\\.([/\\\\]|$)" },
{ "pattern": "^[/\\\\]" },
{ "pattern": "^[A-Za-z]:[/\\\\]" }
]
}
},
"type": {
"type": "string",
"enum": [
"hyperframes:composition",
"hyperframes:asset",
"hyperframes:snippet",
"hyperframes:style",
"hyperframes:timeline"
]
}
}
}
},
"preview": {
"type": "object",
"additionalProperties": false,
"properties": {
"video": { "type": "string" },
"poster": { "type": "string" }
}
},
"relatedSkill": {
"type": "string",
"minLength": 1
}
},
"allOf": [
{
"if": {
"required": ["type"],
"properties": { "type": { "const": "hyperframes:component" } }
},
"then": {
"not": {
"anyOf": [{ "required": ["dimensions"] }, { "required": ["duration"] }]
}
},
"else": {
"required": ["dimensions", "duration"]
}
}
]
}