{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://wai.transaction.science/schema/wai.json/1", "title": "wai.json, a WAI project file, version 1", "description": "The project file `wai create` writes and `wai dev`, `wai app check`, `wai create`, `wai lock`, `wai check` and `wai build` read. Every member is optional; a member not listed here is refused. Paths are relative to the file's directory. A whole number may be written with a zero fraction (4.0 is 4), and none is above 9007199254740991 (2^53 - 1), the largest every JSON reader holds exactly. Secrets never belong in it.", "type": "object", "additionalProperties": false, "properties": { "$schema": { "description": "This schema: an editor or an agent validates the file with it.", "const": "https://wai.transaction.science/schema/wai.json/1" }, "wai": { "description": "The project file's version. A file without it is of version 1; a reader of version 1 refuses a later one.", "const": 1 }, "name": { "description": "The project's machine name, the name it is deployed by: a DNS label, lowercase letters, digits and hyphens, at most 63, beginning with a letter and not ending with a hyphen. `wai create` names a project for its directory.", "type": "string", "pattern": "^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$" }, "template": { "description": "The template the project was made from.", "type": "string" }, "title": { "description": "The project's title, for people.", "type": "string" }, "summary": { "description": "One line on what the project does.", "type": "string" }, "app": { "description": "A program made with Create (app.oui), which the project's page renders: a path relative to the file.", "type": "string" }, "requires": { "description": "What the project needs; `wai check` holds it to this wai's registry.", "type": "object", "additionalProperties": false, "properties": { "capabilities": { "description": "The registered capabilities the project needs. One that decodes against a parameter set needs a parameter set named under `priors`.", "type": "array", "items": { "type": "string" } } } }, "priors": { "description": "Each parameter set the project decodes against, by the name it goes by: a path relative to the file, a directory (a wai.prior.set, whose listing is pinned) or one file. `wai lock` pins each by its digest.", "type": "object", "additionalProperties": { "type": "string" } }, "package": { "description": "What `wai build` packages with the reference packager, into dist/.", "type": "object", "additionalProperties": false, "required": ["policy"], "properties": { "policy": { "description": "The packaging policy (wai.pack.policy/1): a path relative to the file. `wai lock` pins its canonical digest.", "type": "string" }, "sources": { "description": "A component's source by its id, where it is not the one the policy names: a path relative to the file.", "type": "object", "additionalProperties": { "type": "string" } }, "out": { "description": "The package's directory under dist/; `package` when absent.", "type": "string" } } }, "conform": { "description": "What the project conforms against.", "type": "object", "additionalProperties": false, "properties": { "suites": { "description": "Conformance suites, each / as `wai conform --list` names them. `wai lock` pins each corpus by its digest.", "type": "array", "items": { "type": "string", "pattern": "^[a-z-]+/[a-z-]+$" } } } }, "targets": { "description": "The services the project's operations act on, by the name `--target` gives (`wai target add` writes it). A target is an address and whether it is read-only, never a key: `wai auth login` keeps a key, outside the project, and a member of a target that is not listed here is refused.", "type": "object", "propertyNames": { "pattern": "^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$", "not": { "const": "local" } }, "additionalProperties": { "type": "object", "additionalProperties": false, "required": ["url"], "properties": { "url": { "description": "The service's address: http:// or https://, a host in lowercase (an IPv6 literal in brackets), a port of 1 to 65535 and the path the service is under; no user, no query and no fragment.", "type": "string", "pattern": "^https?://([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*|\\[[0-9a-f:.]+\\])(:([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?(/[A-Za-z0-9._~!$&'()*+,;=:%/-]*)?$" }, "read_only": { "description": "Whether every operation that would change the service is refused, before anything is sent.", "type": "boolean" } } } }, "dev": { "description": "What `wai dev` runs in the project's directory; a flag on its command line wins over each member.", "type": "object", "additionalProperties": false, "properties": { "site": { "description": "The directory served at /, the project's own page: a path relative to the file.", "type": "string" }, "page": { "description": "The page `wai dev` names first when it is ready, a path on its origin.", "type": "string" }, "mode": { "description": "The room `wai dev` runs: a room, a watch room, a call, a remote desktop room, or a show (a room with co-performance: hosts on camera and an audience that votes).", "enum": ["room", "watch", "call", "remote", "show"] }, "publishers": { "description": "Publishers at once.", "type": "integer", "minimum": 0, "maximum": 4294967295 }, "watch": { "description": "A watch room's source: a path relative to the file.", "type": "string" }, "watch_ms": { "description": "The source's duration in milliseconds, where it is not a WAV file.", "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "messaging": { "description": "A conversation beside the room.", "type": "boolean" }, "e2ee": { "description": "The room end-to-end encrypted.", "type": "boolean" }, "audience": { "description": "A show's inputs per viewer per poll; a show's alone.", "type": "integer", "minimum": 1, "maximum": 255 } }, "if": { "required": ["audience"] }, "then": { "required": ["mode"], "properties": { "mode": { "const": "show" } } } } } }