Documentation
Browse documentation

DocumentationTools

The command-line tool

overcrow-widget creates, checks and packages PlayerVox OverCrow widgets, runs them in OverCrow while you write them, and tests them. It is one program for Linux and Windows, and it contains the same validators that OverCrow runs when it installs and starts a widget: a package it accepts is a package OverCrow reads.

SH
overcrow-widget init my-widget --template counter --id nova.my-widget
cd my-widget
overcrow-widget check
overcrow-widget package
overcrow-widget inspect dist/nova.my-widget-0.1.0.ocpkg
overcrow-widget doctor
overcrow-widget dev
overcrow-widget test
CommandDoes
initCreates a project from a template.
checkValidates a project without writing anything.
packageChecks, then writes the .ocpkg package.
inspectShows what a package holds and asks for.
devRuns the widget in PlayerVox OverCrow and reloads it when you save.
testPlays the project's test scenarios and compares their images.
doctorSays what your setup has and lacks.
admitRuns the admission of the creator space on your sources, a folder or a ZIP.
diffCompares two versions of a widget's sources.
submitSends a version to the creator space with a publish key, and follows its checks.
statusShows the versions of a widget, their checks and their review.

Every command takes the project directory as its argument and uses the current directory without one. Machine-readable output and exit status are stable for scripts.

Installing

Each PlayerVox OverCrow release carries the creator tools in one ZIP per platform: the tool with its license and third-party notices, OverCrow's headless runtime that test uses, a README.txt and a SHA256SUMS of every file.

PlatformZIPTool in the ZIP
Linux x86-64overcrow-creator-tools-VERSION-linux-x86_64.zipovercrow-widget-VERSION-linux-x86_64
Windows x64overcrow-creator-tools-VERSION-windows-x86_64.zipovercrow-widget-VERSION-windows-x86_64.exe

Unzip it, check the files, rename the tool overcrow-widget (overcrow-widget.exe on Windows), make it executable on Linux (chmod +x) and put it on your PATH. It needs nothing else to check and package a widget. overcrow-widget --version gives its version and the SDK it embeds.

SH
unzip overcrow-creator-tools-VERSION-linux-x86_64.zip
cd overcrow-creator-tools-VERSION-linux-x86_64
sha256sum --check SHA256SUMS
install -m 755 overcrow-widget-*-linux-x86_64 ~/.local/bin/overcrow-widget

The tool also builds from the public repository with Rust; the repository pins the toolchain it needs. The program is then target/dist/overcrow-widget.

SH
cargo build -p overcrow-widget-cli --profile dist --locked

The SDK types

check type-checks your logic with the project's own TypeScript, when Node.js 22 or later and node_modules/typescript are there; otherwise it warns that types were not checked (typecheck.skipped) and goes on. The SDK itself is inside the tool, so packaging never depends on node_modules.

@overcrow/sdk is on npm. The package.json of a project made by init names TypeScript and the SDK version the tool embeds: run npm install in the project. In another project, install the SDK with:

SH
npm install --save-dev --save-exact @overcrow/sdk@1.0.0

Keep the version the tool embeds (overcrow-widget --version). overcrow-widget doctor reports a missing TypeScript, and an SDK in node_modules whose version differs from the one the tool embeds.

Files of a project

FileRolePackaged
manifest.jsonThe manifest, packaged as written.yes
view.ocmlThe view, compiled to view.json.compiled
style.ocssThe style; optional.yes
logic.ts or logic.jsThe logic, one module; bundled with the SDK into logic.js.bundled
locales/en.json, locales/fr.jsonMessages; both or neither, with the same keys.yes
LICENSEThe license text of the package. The templates start with MIT; choose your own.yes
assets/PNG, JPEG or WebP images; optional. Hidden files (.DS_Store) and what the creator tools never send (dist/…) are skipped, as in source archives.yes
package.json, tsconfig.jsonTooling only: TypeScript and the SDK types.no
listing.jsonThe marketplace text of a submission; read by admit. In the creator space, where the listing is edited, only a proposal to import.no
tests/Scenarios (tests/<name>.scenario.json), their reference images (tests/reference/) and your unit tests. tests/output/ holds the images of failed runs.no

init

SH
overcrow-widget init my-widget --template list --id nova.my-widget --name "My widget"

Writes a new project into the directory, which must not exist or must be empty: init never overwrites a file.

TemplateShows
blank (default)A title from the locales and an empty state.
counterA value and two buttons whose handlers the logic exports.
listA keyed checklist: for, handlers with arguments, t() with parameters.
chartA live chart updated by a timer.

Pass --id with your widget's ID: <handle>.<name>, your publisher handle in the PlayerVox OverCrow creator space and a name (nova.lol-timers), or a reverse domain you verified and a name (gg.nova.lol-timers); see the manifest. Without --id, the ID is yourhandle.<dir>: replace yourhandle before you submit, as admit refuses it. com.playervox.* is reserved. Every template comes with a test scenario, tests/example.scenario.json, and counter, list and chart with its reference images.

check

SH
overcrow-widget check
overcrow-widget check --deny-warnings --format json

Runs every check, in this order, and writes nothing:

  1. Project files: the required files are there and within their size bounds, one logic module, both locale files or neither.
  2. Manifest: PlayerVox OverCrow's own manifest validator.
  3. View: view.ocml is compiled and the result validated; static images must exist in assets/.
  4. Style: style.ocss is parsed with PlayerVox OverCrow's parser.
  5. Locales: objects of strings with valid keys, the same keys in both files. A t("key") of the view whose key has no message is a warning.
  6. Logic: the lint, and the exports the view calls.
  7. Types: the project's tsc --noEmit -p tsconfig.json.
  8. Package: logic.js is built, the package is written in memory and read back exactly as PlayerVox OverCrow will read it.

Options: --no-typecheck, --deny-warnings (a warning fails the command), --format json.

package

SH
overcrow-widget package
overcrow-widget package --out build/my-widget.ocpkg

Runs check, then writes the package to dist/<id>-<version>.ocpkg, or to --out. It prints the path, the size and the SHA-256 of the archive.

With --source-map FILE, it also writes the code map of logic.js to that file. The map never goes into the package: the package is the same with or without it.

Packaging is deterministic: the same sources and the same version of the tool give the same bytes on every run and every system. What the package holds is described in the package.

inspect

SH
overcrow-widget inspect dist/nova.my-widget-0.1.0.ocpkg

Validates a package as PlayerVox OverCrow does, then shows it as a reviewer sees it: the ID, version and names; the size and SHA-256 of the archive; the SDK version its logic.js contains; each permission in words (network routes with their parameter constraints and declared response bound, storage, clipboard, game events); each capability with its summary and whether it is sensitive or needs an account; the number of menu rows; and every file with its size and SHA-256. A package that OverCrow would refuse is reported instead, with the reason.

dev

SH
overcrow-widget dev

Runs the widget in the PlayerVox OverCrow overlay running on your machine, while you edit it:

  1. it connects to the overlay, which must have been started with development installs allowed;
  2. it builds the package as package does and sends it to the overlay, which validates it in full and shows it marked Unverified · development package, with the permissions of its manifest granted for the session only;
  3. it watches the project's files and, 200 ms after the last change, rebuilds and reloads the widget. A build with errors is not sent: the widget keeps running its last good build;
  4. it prints what the overlay reports: the widget's states (starting, running, restarting with the failure, failed…) and the log.* output of its logic;
  5. on Ctrl+C, it removes the widget from the overlay.

Options: --no-typecheck, --format json (one JSON object per line). Exit status: 0 after Ctrl+C, 1 when the overlay ends the session, 2 when no overlay is reachable. The development channel says how to start PlayerVox OverCrow for it, and what each state and refusal means.

test

SH
overcrow-widget test
overcrow-widget test --scenario example
overcrow-widget test --update

Plays the scenarios of tests/ in PlayerVox OverCrow's headless runtime and compares the images it renders with the references:

  1. it builds the package as package does;
  2. it reads every tests/<name>.scenario.json and checks it against the manifest before anything runs; a mistake in a scenario is a test.scenario diagnostic in its file;
  3. it runs each scenario in the headless runtime this tool pins, or the one given by --runtime, and prints the runtime's version and SHA-256. The first time, it downloads the pinned runtime;
  4. it compares each captured image with tests/reference/<name>/<image>.png. A difference, a size change or a missing reference fails the scenario and writes tests/output/<name>/<image>.actual.png and, for a difference, <image>.diff.png.

Options: --runtime <path> (another overcrow-widget-headless program), --offline (never download the runtime), --scenario <name> (only that one), --update (records the captured images as the references: review them before you commit them), --format json, --no-typecheck.

Exit status: 0 when every scenario passed, 1 when one failed, 2 when no runtime can run. Scenarios are described in testing a widget.

doctor

SH
overcrow-widget doctor
LineChecked
cli, sdkThe version of the tool, its widget API, and the @overcrow/sdk it embeds.
platformOperating system and architecture.
overcrowAn installed OverCrow.
developmentA running overlay that allows development installs, and its version.
node, typescript, project sdkIn a widget project: Node.js on PATH, node_modules/typescript, and the version of node_modules/@overcrow/sdk.
CodeSeverityMeaning
doctor.overcrow_missingwarningOverCrow is not installed.
doctor.development_offwarningNo overlay allows development installs; the help gives the commands to restart PlayerVox OverCrow with them.
doctor.channel_busywarningThe overlay already serves its maximum of dev sessions.
doctor.channel_iowarningThe connection to the overlay failed.
doctor.channel_untrustederrorWhat answers is not this user's overlay.
doctor.protocol_versionerrorThe overlay and the tool do not speak the same version of the development channel.
doctor.node_missing, doctor.node_versionwarningNo Node.js, or older than 22: check cannot type-check.
doctor.typescript_missing, doctor.sdk_missingwarningTypeScript or the SDK types are not installed in the project.
doctor.sdk_versionwarningnode_modules/@overcrow/sdk differs from the SDK in the tool.

Options: --format json, --deny-warnings.

admit

SH
overcrow-widget admit --publisher nova
overcrow-widget admit lol-timers.zip --publisher nova --previous lol-timers-1.0.0.ocpkg
overcrow-widget admit --publisher nova --package dist/nova.my-widget-0.1.0.ocpkg

Runs the static admission that the creator space runs on every version you send. The sources are the project folder or a ZIP of it, read as the creator space receives them (source archives). It never runs your code or tsc:

  1. the sources are built as package builds them;
  2. with --package, that archive's compiled view must be byte for byte what view.ocml compiles to;
  3. the ID belongs to the publisher given by --publisher (its <handle>.<name> IDs, and with --domain, the IDs under a domain it verified); without --publisher, it is neither reserved, nor an example ID (nova.*, yourhandle.*, gg.nova.*, com.example.*…), nor under a handle nobody can register (admin.*, com.*). listing.json is valid, its preview is a packaged PNG of at most 256 KiB;
  4. the authority the widget asks for is listed for the reviewer: capabilities (the sensitive ones marked), network routes with their response bound, clipboard writes, storage and game events;
  5. with --previous, the last approved version (its manifest.json, its package, its folder or its ZIP): the ID must be the same and the version higher, and the report lists the permission keys added, widened and removed, and the review the version needs.
CodeSeverityMeaning
admission.reserved_iderrorA com.playervox.* ID, reserved for PlayerVox; without --publisher, also an ID under a reserved handle (playervox.*, admin.*…).
admission.placeholder_iderrorAn example ID, without --publisher.
admission.id_not_ownederrorThe ID does not belong to the publisher, or, without --publisher, cannot belong to any.
admission.listing_missing, admission.listingerrorNo listing.json, or one that breaks the listing's rules (a warning with --listing optional).
admission.previewerrorpreview does not name a packaged PNG within bounds (a warning with --listing optional).
admission.licenseerrorA PlayerVox widget whose license is not MIT (a warning with --listing optional).
admission.view_not_reproducibleerrorThe submitted compiled view differs from what view.ocml compiles to.
admission.previouserrorThe previous version cannot be read.
admission.previous_mismatcherrorThe previous version is another widget.
admission.version_not_newererrorThe version is not above the previous one.
admission.package_rebuiltwarningThe submitted archive differs from the rebuild in other files.
admission.not_rebuiltwarningAn archive was admitted without its sources.

Options: --publisher HANDLE, --domain DOMAIN (repeatable), --previous FILE, --package FILE, --source-map FILE (the code map, written when the sources are admitted), --out DIR (writes the admitted package, its listing and a report into an empty directory), --format json, --deny-warnings. admit <file.ocpkg> --listing FILE checks an archive without its sources.

--listing required|optional is for sources. required, the default, refuses sources without a valid listing.json. optional is the creator space's way: the listing is edited there, so listing.json may be absent, and one with a problem is left out (no listing in the report or in --out) with warnings instead of refusing the sources. Exit status: 0 admitted, 1 refused, 2 on a usage or file error. See checks and the catalog.

Permission keys

Each permission has a stable key, the same in the creator space:

KeyPermission
network:GET https://api.nova.gg/v1/timersA network route: method, origin and path.
storageStorage.
clipboardWriteClipboard writes.
capability:<name>A capability.
gameEvent:<name>A game event.

A key is added when the previous version did not have it, widened when its route stays but its rule changes (path or query constraints, response bound), and removed when it goes. An added or widened key calls for a full review; otherwise the review is quick.

diff

SH
overcrow-widget diff lol-timers-1.0.0.zip .
overcrow-widget diff old/ new/ --format json

Shows what changed between two versions of a widget's sources, each a folder or a ZIP, read as admit reads them: the files the creator space receives. Files are sorted by path; each added, modified or removed file comes with its unified changes (three lines of context) and its added and removed line counts. A file that is not UTF-8 text is binary: only its SHA-256 is compared. So is a text above 1 MiB or 20,000 lines, or once 200,000 lines were compared in one diff (tooLarge). When both versions have a valid manifest, the permission keys the new version adds, widens and removes are listed, with the review it needs.

Option: --format json. Exit status: 0 when both versions were read, whether or not they differ; 1 when one is refused; 2 on a usage or file error (a version missing or unreadable).

submit

SH
overcrow-widget submit --dry-run --submission submission.json
overcrow-widget submit --submission submission.json

Sends a version of your widget to the PlayerVox OverCrow creator space, from a terminal or a CI job, then follows its checks. It never asks a question: what is missing is said, with a stable exit status. It takes the widget folder (the current one without argument) or a ZIP of it.

The publish key

  • Create it in the creator space (Publisher, Publish keys). A key can only submit versions of one widget, for up to a year (90 days by default), and is shown once.
  • submit and status read it from the environment variable OVERCROW_PUBLISH_KEY, and only there: never from an argument or a file of the project. In a CI, keep it as a secret.
  • The tool never shows it: any ocw_pub_… text is masked in its output, its errors and its logs. Whatever the command, it removes the variable from the environment of the programs it starts (TypeScript, the runtime).
  • A key that expires within 14 days gives a warning. An expired or revoked key ends with status 2: create a new one and replace the secret.
  • Every request names the widget of the sources' manifest.json (header Overcrow-Widget). A key that covers several widgets of its publisher (reserved to PlayerVox for now) submits the one named; status then takes --widget.

What it does

  1. It checks the key, and reads what the creator space needs for this widget: the last approved version, the lowest version it takes now, the submissions left (20 over 24 hours), whether the listing has a privacy policy.
  2. It checks exactly what it will send. The folder is zipped as the creator space reads it (source archives), read back and admitted as the creator space admits it, listing.json being optional; a ZIP given instead is sent byte for byte. The manifest ID must be the key's widget and the version above the last approved one. Each permission the version adds or widens (each permission, for a first version) needs a justification, by its key. The texts must follow the creator space's rules. If anything is wrong, nothing is sent (status 1).
  3. It sends the archive, then follows the six checks of the creator space, about a minute: manifest, version number, code analysis, package build, permissions, size and resources.
  4. It ends when the version enters review (status 0), when a check fails (status 1: each problem is shown on the line of your file), or when the version passed its checks but waits in the creator space for what only the creator space takes (status 3): a privacy policy when the widget uses the network, a complete listing for a first version, or the review slot of a new publisher. The link to finish there is shown.

A version the creator space already has

Before checking anything else, submit looks for a version of the same number in the creator space. When it has the same sources (byte for byte, as submit zips them) or, once admitted, the same package, nothing is sent: the run ends on that version's state, with outcome already_known.

  • Status 0: it is published, approved, in review, or waits for your answer to requested changes.
  • Status 3: it waits in the creator space (the link to finish is shown).
  • Status 1: it failed its checks, was refused, withdrawn or discarded: raise the version in manifest.json to send other sources.
  • A version still being checked is followed, as after a submission.

The same number with another package is refused before sending (submit.version_known_differs): raise the version in manifest.json. A CI job can therefore run submit on every push: a version already sent changes nothing.

Ctrl+C while the checks run stops following them; they go on in the creator space, and overcrow-widget status --version 1.3.1 --wait follows them again (status 4). A run cut short before the end (network, Ctrl+C) resumes the same submission when you run the same command again; changed sources or texts make a new submission. A submission not finished within an hour expires, and every submission counts in the daily limit.

OptionEffect
--submission FILEThe texts of the version (below).
--release-notes-en TEXT, --release-notes-fr TEXT, --review-message TEXTReplace those of the file.
--dry-runSteps 1 and 2 only, nothing sent: what the creator space will ask for (justifications, privacy policy, review type, lowest version, submissions left) and the archive's SHA-256. For a first version, the creator space also checks the whole listing, which only it knows: a dry run that ends with 0 may still end with 3.
--expect-sha256 HEXSends only an archive with this SHA-256, the archive.sha256 of a --dry-run: what is sent is what was checked.
--no-waitEnds after the upload (status 4).
--format jsonOne JSON object (machine-readable output).
--verboseOne line per request on the error output: method, address without its query, status and time; never a header, a key or a body.

The texts file

JSONdocs/content/examples/weather/submission.json
{
  "releaseNotes": {
    "en": "First version: the forecast of your city, in metric or imperial units.",
    "fr": "Première version : les prévisions de votre ville, en unités métriques ou impériales."
  },
  "justifications": [
    {
      "permission": "network:GET https://api.example.com/v1/forecast/{city}",
      "text": "Reads the forecast of the city the player chose, every 30 minutes at most."
    },
    {
      "permission": "storage",
      "text": "Keeps the chosen city and units between two games."
    }
  ],
  "reviewMessage": "The forecast API needs no account and receives only the city."
}
KeyValue
releaseNotesThe public notes of the version, shown to players: en (needed as soon as there are notes) and fr, 500 characters each, plain text, line breaks allowed.
justificationsFor the reviewer, one {permission, text} per new or widened permission, by its key; 500 characters each.
reviewMessageA private message to the reviewer, 2,000 characters.

Every key is optional; any other key is refused. The PlayerVox OverCrow MCP server writes this file.

In a CI job

A GitHub Actions workflow that installs the tool (installing) and submits the example widget nova.weather on every version tag, with the key in the repository's secrets:

YAMLdocs/content/examples/weather/.github/workflows/submit.yml
# Sends the widget to the PlayerVox OverCrow creator space when a version
# tag is pushed. The publish key is a secret of the repository, and the
# OverCrow release whose creator tools to use is a variable of the
# repository.
name: Submit to PlayerVox OverCrow

on:
  push:
    tags: ["v*"]

permissions:
  contents: read

jobs:
  submit:
    runs-on: ubuntu-24.04
    env:
      OVERCROW_VERSION: ${{ vars.OVERCROW_VERSION }}
    steps:
      - uses: actions/checkout@v4
      - name: Install overcrow-widget
        run: |
          tools="overcrow-creator-tools-$OVERCROW_VERSION-linux-x86_64"
          curl --fail --location --silent --show-error --remote-name \
            "https://github.com/Valhallab/playervox-overcrow-releases/releases/download/v$OVERCROW_VERSION/$tools.zip"
          unzip -q "$tools.zip"
          (cd "$tools" && sha256sum --check --quiet SHA256SUMS)
          install -D -m 755 "$tools"/overcrow-widget-*-linux-x86_64 "$HOME/.local/bin/overcrow-widget"
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
      - name: Submit to PlayerVox OverCrow
        run: overcrow-widget submit --submission submission.json
        env:
          OVERCROW_PUBLISH_KEY: ${{ secrets.OVERCROW_PUBLISH_KEY }}

The job fails on any status but 0. OVERCROW_API_URL points submit and status to another API, for tests only: https://, or http:// to 127.0.0.1, localhost or [::1], with a warning every time. Never set it in a real job; the PlayerVox OverCrow MCP server never sets it.

status

SH
overcrow-widget status
overcrow-widget status --version 1.3.1 --wait

Shows the versions of the key's widget, with their state and review type. With --version, one version, by its number (the latest of that number) or its ID: its six checks and their problems, what keeps it out of review, the reviewer's remarks and the review delay. --wait follows a version still being checked. --widget ID names the widget, for a key that covers several (status 2 without it, with the widgets the key covers). Options: --widget ID, --version VERSION|ID, --wait, --format json, --verbose. Status: 0 when read, 2 on an error; with --wait, the statuses of submit.

StateMeaning
checkingThe checks run.
checks_failedA check failed: nothing reached the reviewers.
readyThe checks passed; the version waits in the creator space.
in_reviewA person reviews it.
changes_requested, approved, rejectedThe review's decision.
publishedIn the catalog.
superseded, discardedReplaced by a newer submission, or abandoned.
withdrawn, suspendedOut of the catalog.

Source archives

admit and diff take the widget folder or a ZIP of it (its name ends in .zip), as the creator space receives it. The ZIP may hold the files directly, or one folder that holds them all, as Windows and macOS make it. It may carry a short archive comment (1,024 bytes at most), as GitHub's "Download ZIP" and git archive write it; the comment is never read.

Left out of both, and never sent by the creator tools: hidden files and folders (.env, .git/, assets/.DS_Store…), node_modules/, dist/, tests/output/, __MACOSX/, built packages, key files and system files, and, in a folder, links and names that are not portable ASCII. In a ZIP, they still count toward the bounds below and are checked like the rest. A name that holds a character Windows forbids (\ : * ? " < > |) is refused, in a folder too.

BoundValue
Archive32 MiB
Uncompressed64 MiB
Files2,000

Everything is checked before a byte is written: a refused archive writes nothing, and an admitted one is written only into a private work folder, removed at the end.

CodeThe archive holds
sources.archive_sizeMore than 32 MiB.
sources.too_large, sources.too_many_filesMore than 64 MiB or 2,000 files once uncompressed.
sources.unsafe_nameA name that could leave the widget folder (../, / first), or that some system cannot use: a character Windows forbids (\, :, *, ?, ", <, >, |), anything but printable ASCII, a final dot or space, CON, NUL, COM1… The message names the character and the file.
sources.backslashFolders separated by \, as Windows PowerShell 5.1 Compress-Archive writes them. Send the widget folder itself in the creator space, or use submit, which makes a correct ZIP.
sources.duplicate_nameTwo names that differ only by case, or a file that is also a folder.
sources.link, sources.special_fileA link, or a device, a FIFO or a socket.
sources.bombAn entry that inflates far beyond its compressed size, or beyond its declared size.
sources.readThe file cannot be read (exit status 2).
sources.encryptedAn encrypted entry.
sources.zip64ZIP64, which sources never need.
sources.archiveAnything else a ZIP should not hold: a comment above 1,024 bytes or holding an end record, bytes before, between or after the entries or after an entry's compressed data, another name in an extra field, sizes or checksums that disagree.

The code map

--source-map FILE writes a map from each position of the shipped logic.js, bundled and minified, back to the file, line and column of your sources: a Source Map v3. The creator space keeps it private and uses it to show you the errors of your widget in your own code.

  • sources: logic.ts (or logic.js), the files of @overcrow/sdk (listed in ignoreList) and overcrow:view-table, the expression table generated from view.ocml, whose text is in sourcesContent.
  • x_overcrow_functions: the named functions of the sources, {"source", "name", "start": [line, column], "end": [line, column]}, zero-based, columns in UTF-16 units like mappings. The function of a position is the innermost one around it. The expressions of the view table are named view expression <n>, <n> being their index in view.json.

The same sources always give the same map. It is never part of the package, and logic.js does not point to it.

Diagnostics

Every problem is one diagnostic, with a stable code, a position and, when there is one, a suggestion:

TEXT
error[view.unknown_attribute]: `clas` is not an attribute of <text>
  --> view.ocml:4:9
   |
 4 |   <text clas="value">{state.count}</text>
   |         ^
   = help: did you mean `class`?
check: 1 error(s), 0 warning(s)

The code is <domain>.<category>:

DomainFromCodes
projectThe files of the projectmissing_file, file_size, encoding, ambiguous_logic, asset_path, entry_limit, read
manifestmanifest.jsonsee the manifest
viewview.ocmlsee the view
stylestyle.ocsssee the style
localeslocales/*.jsonmissing_file, json, shape, key, value, keys, entry_limit, unknown_key
logiclogic.tssee the logic
typecheckTypeScripttsc (TypeScript's own message), skipped, sdk_version, timeout
packageThe package read backarchive_size, file_size and the categories of OverCrow's package reader
testScenariosscenario, scenario_name, too_many_scenarios
sourcesA source archivesee source archives
init, doctor, admissionThose commandslisted above
submitWhat submit checks before sendingwidget_not_submittable, agreement_required, limit_reached, version_too_low, justification_missing, archive_too_large, archive_mismatch, release_notes, justification, review_message
  • Lines and columns start at 1; a column counts characters, not bytes.
  • An unknown name comes with the closest name that exists.
  • With --format json, each diagnostic is one JSON object on a line of the standard output: {"severity","code","file","line","column","message","help"}, with null for what is unknown. package --format json ends with one {"package","bytes","sha256","logicBytes","sourceMap"} object; admit and diff print one report (machine-readable output).
  • Texts that come from a widget (its logs, its names) are shown with terminal control characters neutralized.

Scripts should match the codes: messages and help texts may be reworded.

Machine-readable output

With --format json, admit, diff, submit and status print one JSON object on one line. Fields are only ever added; a formatVersion change announces any other change.

admit:

FieldValue
formatVersion1.
admittedWhether the sources are admitted.
publisherThe --publisher handle, or third-party.
id, version, reservedIdThe widget; null when the sources were refused before the build.
packagebytes, sha256 and each file's bytes and sha256.
reproducibleviewJson and archive, compared with --package, else null.
listingbytes, sha256, spdxLicense and preview of listing.json.
sourceskind (folder or archive), files, bytes, ignored (path, reason) and, for a ZIP, sha256 and prefix (the wrapping folder).
reviewThe authority to review, one object per item (kind, then its fields).
permissionskeys; with --previous, also previous (id, version), added, changed, removed and reviewType (full or quick), else null.
listingPolicyrequired or optional (--listing).
diagnosticsThe diagnostics, as above.

diff:

FieldValue
formatVersion1.
comparedfalse when a version is refused; then only diagnostics follows.
old, newkind, files, bytes, sha256, prefix, ignored, id and version of each version.
filesChanged files by path: path, status (added, modified, removed), binary, tooLarge, oldSha256, newSha256, additions, deletions and hunks (oldStart, oldLines, newStart, newLines, lines, each line starting with , -, + or \).
totalsadded, modified, removed, additions, deletions.
permissionsadded, changed, removed and reviewType, or null without two valid manifests.
diagnosticsThe diagnostics.

submit and status:

FieldValue
formatVersion, command1; submit or status.
outcome, exitCodeHow the run ended (below) and its exit status.
dryRunsubmit: whether nothing was to be sent.
keyname, hint (the four characters after ocw_pub_), expiresAt, expiresSoon, widgets (the widgets the key covers).
widgetid; submit: publisher, status; status: name.
archivesubmit: kind (folder, zipped by the tool, or archive), bytes, sha256, files, uncompressedBytes, ignored.
localsubmit: admitted, version, minimumVersion, previousVersion, permissions (keys, added, changed, removed, reviewType), diagnostics.
requirementssubmit: justifications (required, given, missing, unused), privacyPolicy (required, present), reviewType, submissions (limit, remaining, nextSubmissionAt), review (available, blockedBy), agreement (version, accepted), blockers (code).
knownsubmit: the version the creator space already has (nothing was sent): versionId, state, match (sources or package).
submissionsubmit: id, state, resumed, quota.
versionThe creator space's version, its fields in camelCase: id, version, state, reviewType, checks (key, status, diagnostics), reviewBlockers, completeInPortal (message, url), permissions, remarks, deadline, history…
versionsstatus without --version: every version.
errorcode, message and, when known, httpStatus, retryAfter, nextSubmissionAt, minimumVersion, expiredAt, fields; else null.

outcome is ready_to_send (--dry-run), refused_locally, refused (the creator space refused the submission), complete_in_portal, already_known (nothing sent, see known), error, or the version's state; status without --wait has none. Error codes are the creator space's (version_not_newer, submission_limit_reached, publish_key_expired, publish_key_revoked, publish_key_owner_suspended, widget_required, publish_key_widget_not_covered…) or the tool's: publish_key_missing, invalid_publish_key, api_url_invalid, submission_file, sources, sources.read, network, timeout, server, response, redirect, upload_refused, build_failed, submission_state, not_found, internal. Problems found before sending are diagnostics: sources.*, project.missing_file (not the widget's folder), admission.* and submit.* (widget_not_submittable, agreement_required, limit_reached, version_too_low, justification_missing, archive_too_large, archive_mismatch, version_known_differs, release_notes, justification, review_message).

Exit status

StatusMeaning
0Success. Warnings are allowed unless --deny-warnings. diff read both versions, whether or not they differ. submit: the version is in review (with --dry-run, it would enter review), or already past it (approved, published, withdrawn), or the creator space already had it in review, with changes requested, approved or published.
1Errors were found; admit refused the sources; diff refused a version; a scenario of test failed; the overlay ended a dev session. submit: something to fix (a check before sending, a refusal of the creator space, a failed check, a version the creator space already refused, withdrew or discarded).
2A usage or file error; no overlay for dev; no runtime for test. submit, status: the key (missing, invalid, expired, revoked), the network or the server.
3submit, status --wait: the version passed its checks and waits in the creator space.
4submit, status --wait: the version is still being checked (Ctrl+C, --no-wait, or 15 minutes).

These meanings do not change from one version of the tool to the next.