caputchin
All docs
View raw .md

Marketplace

The discoverable default for game distribution. Authors publish a GitHub repo; the platform indexes it; customers browse and pick games.

Discovery

The platform indexer queries the GitHub API for repos tagged with the topic caputchin-game. There is no manual submission, no review, no signing. Author chooses to be discovered by adding the topic to their repo.

Manifest

A caputchin.json file at the repo root. The manifest is pure metadata for the marketplace UI and the resolver — the runtime never reads it directly. The actual game contract is the SDK register() call, not the manifest. The indexer reads the manifest, fetches the built JS at the derived jsDelivr URL, computes a SHA-384 integrity hash, and stores the { url, integrity } pair under the game ID. The widget reaches that pair through /games/:id/resolve at mount time and passes it into the sandboxed iframe via <script src integrity>. See ADR-0015.

Single game

{
  "id": "@cooperative-games/bubble-pop",
  "version": "1.2.0",
  "displayName": "Bubble Pop",
  "description": "Pop the floating bubbles",
  "support": {
    "responsive": true,
    "touch": true,
    "accessible": false,
    "audio": "optional",
    "languages": ["en", "es"]
  },
  "npm": "@cooperative-games/bubble-pop",
  "script": "dist/bubble-pop.js",
  "preview": "preview.gif"
}

Collection (first-class with a marketplace page)

{
  "id": "@cooperative-games/casual-pack",
  "version": "2.0.0",
  "displayName": "Casual Pack",
  "npm": "@cooperative-games/casual-pack",
  "script": "dist/casual-pack.js",
  "games": ["./bubble-pop", "./memory-match", "./color-sort"]
}

Unnamed multi-game wrapper (no collection identity)

{
  "games": ["./bubble-pop", "./memory-match"]
}

Manifest fields

Field Required Purpose
id for indexed games / collections Author-declared, conventionally @org/name. Format-validated only.
version yes Display only — not enforced
displayName yes Marketplace UI
description yes Marketplace UI
preview recommended Path or URL to a preview image / GIF
support recommended Author-declared compatibility flags — see below
npm optional Informational only. Indexed for marketplace UI display. Not a runtime distribution path — games execute inside a sandboxed iframe and must reach it as a URL. Customer-bundled games are loaded via game-src on the widget, not by importing the npm package.
script optional Path inside the repo; the indexer derives the jsDelivr CDN URL
games optional Sub-manifest paths for collections / multi-game repos

Indexer rules

  • Fetch the root manifest only; for collections, follow the paths in games to read sub-manifests.
  • Compute the SHA-384 SRI hash of the built JS pointed at by script (jsDelivr URL). Store { url, integrity } keyed by game ID for the resolver endpoint.
  • id + games → indexed as a collection (gets its own marketplace page plus child entries).
  • games only → unbundled multi-game repo; child games index, the wrapper does not.
  • id, no games → single game.
  • No path traversal — games paths must stay inside the repo.
  • No external URLs in games.
  • Sane size cap on manifests.
  • Skip broken sub-manifests; do not fail the whole repo.
  • No deduplication of conflicting IDs across repos. Customers choose. See game-distribution.

Support flags

All author-declared, never verified by the platform. The marketplace surfaces them as filters and badges so customers can pick games matching their site's needs. See ADR-0006 for why honesty beats fake validation.

Flag Type Meaning
responsive bool Adapts to container size
touch bool Works with touch input
accessible bool Screen-reader and keyboard navigable
audio "none" / "optional" / "required" Sound design
languages string[] Language codes; empty / omitted = English-only or no text

What's not in the manifest

  • No code signing. Out of scope at MVP. SRI on the indexer's stored hash protects against jsDelivr tampering between index time and load time, not against author-side malice. Sandbox isolation is what bounds malicious-author blast radius — see ADR-0015.
  • No revenue share. Deferred entirely.
  • No platform-hosted CDN. Games ship via jsDelivr (marketplace), customer's host (self-hosted), or bundled. No platform-side asset delivery.
  • No review process. Discovery is open; quality is conveyed via the support flags and customer choice.

Authoring a manifest

See the publish-to-marketplace guide.