QORMQORM v0.9.8 api Get started

CLI: qorm

Hand-written reference for the qorm binary (implemented in cmd/qorm/). Unlike the other pages here it is not generated — update it when the CLI changes.

One binary is the whole toolchain: scaffold, run, render, measure, verify, sign, package, publish, and serve agents. Pure Go by default (cross-compiles everywhere); the default shot, measure, and check paths use the headless software canvas. A macOS -tags desktop build adds WebKit page/URL/window capture, preview, WebView-backed check flows, and HTML-path measurement.

CommandWhat it does
newscaffold a runnable app
runserve an app live (browser + agent share the runtime)
renderwrite a static HTML snapshot
shotrender an app with pure Canvas, or capture a WebKit page/window, to PNG
measurerender + self-measure canvas or WebView layout and styles
checkverify canvas or WebView render against expectations
buildcompile (+ optionally sign) a bundle
keygengenerate an ed25519 signing keypair
signsign an existing bundle
verifyverify a bundle's integrity / signature / revocation
mcpserve an app to agents over MCP (stdio)
previewrender a packaged app and report its layout (-tags desktop)
packagepackage as an installable app (web / iOS / Android / mac / miniapp)
docsrender a markdown docs tree to a static HTML site
auditverify a hash-chained activity audit log
updatesOTA publish server with staged (canary) rollout
updateself-update the CLI (verifies signed checksums)
versionprint the version

Conventions

VariableUsed by
QORM_KEYSTORE_PASS / QORM_KEY_PASSpackage -p android --release — keystore / key passwords (else prompted)
ANDROID_HOME / ANDROID_SDK_ROOTpackage -p android — locating the Android SDK

new

qorm new <dir> [--name "App Name"]

Scaffolds a minimal runnable app: qorm.json (manifest; the app id is sanitized from the directory name), scenes/main.json (a counter screen), and actions/inc.json. Refuses a non-empty directory (exit 1). --name sets the display name (default: the directory base name).

run

qorm run <app-dir|bundle> [flags]

Serves the app live: the browser UI, the SSE push channel, and the agent endpoint at /mcp all share one runtime. See HTTP & SSE for the endpoint contract.

FlagEffect
--port Nlisten port (default 10383; if taken, falls back to a random free port and prints it)
--no-opendo not open a browser window
--appstandalone window: a native WebView in a -tags desktop build, otherwise a chromeless Chromium-family window (--app=<url>), falling back to a normal tab
--consoleopen the collaboration console (/console) instead of the app page
--lanbind 0.0.0.0 so physical devices join the same session; prints the Wi-Fi URL and runs adb reverse for attached Android devices; implies --no-open
--tlsHTTPS with a self-signed certificate covering localhost + the LAN IPs (a secure context, required by camera/mic/location Web APIs on a device); implies --lan
--mcp-read-onlythe shared MCP session rejects mutating tools (qorm_dispatch, qorm_set_state, qorm_apply_patch, qorm_undo); inspection and preview tools keep working
--no-watchdisable hot-reload
--trust pub.keyrequire a bundle to carry a valid signature from this key
--revoked list.jsonreject bundles signed by a revoked key
--audit-log fileappend every activity entry to a hash-chained JSONL log (verify with qorm audit); the chain resumes across restarts

Behavior notes:

render

qorm render <app-dir|scene.json|bundle> [-o out.html]

Writes a static HTML snapshot (the server-side first frame; no live client). Default output: <input base name>.html. A bundle input is integrity-checked only — this command has no --trust, so a warning notes authenticity is not verified.

shot

qorm shot <app-dir> -o out.png [--width W --height H]
qorm shot --html page.html -o out.png
qorm shot --url URL -o out.png
qorm shot --live "window title" -o out.png

App-directory capture works in the default build: QORM renders one deterministic, headless pure-Go Canvas frame, settles entrance effects, and encodes the actual software pixel buffer. It needs neither a WebView nor a GUI. Default size is 440x720; default output is <dir>.png.

On the default Canvas path, the output argument is the exact path (relative paths are relative to the current working directory), must end in .png, and its parent directory must already exist. An existing regular file is replaced; symlinks, directories, and special files are rejected. Dimensions must be positive, no edge may exceed 4096 px, and the surface is capped at 16,777,216 pixels.

A macOS + -tags desktop build instead uses WebKit for app-directory/HTML/URL capture and additionally supports live operating-system windows. Those modes require a GUI session; --live also needs Screen Recording permission. CSS animations are frozen at their final state before WebKit capture. Default builds reject --html, --url, and --live explicitly rather than silently substituting Canvas.

measure

qorm measure <app-dir> [--width N] [--physical] [-o report.json]

The default build renders the app once with the headless pure-Go canvas and prints a JSON report joining each node's intent (type / text / binding) with the rendered result (rect + computed styles) — to stdout, or to -o. Viewport width defaults to 400; height comes from the manifest window and otherwise defaults to 820. Coordinates use logical CSS pixels; --physical keeps canvas device pixels.

A -tags desktop build measures the HTML path in a native WebView instead. WebView reports CSS pixels, so --physical is accepted for CLI parity but has no effect. Report fields and backend boundaries: Interpreting & verifying a QORM app.

check

qorm check <app-dir> (--checks checks.json | --audit) [--width N] [--physical] [-o report.json]

Measures the app like measure, then evaluates expectations against that backend's render. Static checks and --audit work on the default pure-Go canvas path and the -tags desktop WebView path.

Exit status: 0 even when checks fail — pass/fail lives in the report's ok field. Non-zero only on runtime errors (bad checks JSON, load failure). Assertion schema and report format: verification.

build

qorm build <app-dir> [-o app.qorm.bundle] [--key priv.key] [--version V] [--require-capability camera,location]

Compiles the app into a single bundle (qorm-bundle/1 JSON): the content (manifest + scenes + actions + locales), a contentHash over its canonical encoding, and — with --key — a detached ed25519 signature. Default output: <dir base name>.qorm.bundle.

keygen

qorm keygen [--out-dir .]

Generates an ed25519 keypair: qorm_key (private, mode 0600) and qorm_key.pub in --out-dir, and prints the 12-character key id. Key files are two lines of text — a header line plus base64 key bytes — easy to inspect and move.

sign

qorm sign <bundle> --key priv.key [-o out]

Signs an existing bundle — e.g. one exported from a live design session via the MCP qorm_export_bundle tool. Without -o the input file is overwritten in place.

verify

qorm verify <bundle> [--trust pub.key] [--revoked list.json]

Verifies a bundle in layers and prints the scope it proved: integrity (content hash recomputed) always, + signature with --trust, + revocation with --revoked. Also prints any required capabilities the bundle declares.

mcp

qorm mcp <app-dir|bundle> [--trust pub.key] [--revoked list.json]

Serves the app to an AI agent over MCP (stdio JSON-RPC) — the same tool set a running qorm run exposes at /mcp, but on its own private runtime (no shared browser session). Tool reference: MCP tools.

preview

qorm preview <package-dir> [--width N] [--eval JS] [-o report.json]

Verifies a packaged app, not the source: serves the static output of qorm package -p web, lets its client-side WASM runtime boot and render with no app server, and captures the app's self-measurement (stdout, or -o). --eval JS runs JavaScript in the page after the first measurement — e.g. qorm(0) to press the first action button — then re-measures, so the packaged build's interactivity is exercised too. Needs a -tags desktop build.

Not to be confused with the MCP qorm_preview_patch tool, which previews a design patch on a live session.

package

qorm package <app-dir> [-p web|ios|android|mac|miniapp] [-o out-dir] [flags]

Compiles the app into an installable, fully offline package. Default platform web; default output <app dir name>-<platform>. Before building, a capability matrix prints to stderr warning about features the target platform does not support (and about a native middle layer missing for the target).

PlatformOutput
webinstallable, offline-capable PWA: index.html + bundle.json + qorm.wasm + wasm_exec.js + manifest + icons + sw.js
iosan Xcode project; with xcodegen + xcodebuild installed it also builds (unsigned simulator build, or a signed device build with --team)
androida Gradle project; with gradle + an Android SDK (ANDROID_HOME / ANDROID_SDK_ROOT) it also builds (wrapper pinned to Gradle 8.9)
maca macOS .app with the desktop binary compiled in (needs macOS + cgo); ad-hoc code-signed for development
miniappa WeChat-style mini-program project (WXML/WXSS static export of the initial UI; open in WeChat DevTools)

The web/ios/android payloads compile the client runtime with go build (GOOS=js GOARCH=wasm), so the Go toolchain and the QORM module must be reachable — run it from the QORM repo, or a directory whose go.mod requires github.com/qorm/platform. The app's own Go middle layer (native/desktop.go) is injected into that build, and into the desktop binary for mac.

General flags:

FlagEffect
--dev URL(ios/android only) build the thin QORM Dev client that connects to a live qorm run --lan server — install once, reuse for every app, changes hot-reload. Mutually exclusive with --release
--team IDApple development team for iOS signing
--no-brandingdrop the "Made with QORM" note
--subscribedconfirm a QORM membership non-interactively (see below)
--update-url URL + --trust pub.keywire the package to an OTA update server. The two flags must be given together (fail-closed: updates are only applied when signed by the trusted key); the URL must be http(s)
--revoked list.jsonwith --update-url/--trust: bake a signing-key revocation snapshot into the packaged OTA client (window.__QORM_UPDATE__.revoked). Refused without the OTA pair

Commercial gate (honour system). A custom icon.png in the app dir, or --no-branding, is commercial white-labeling: the packager prints a note and asks you to confirm a QORM Patreon membership — interactively, or via --subscribed. Non-interactive runs without --subscribed fail (exit 1). Personal / educational / open-source use (default icon, branding on) never triggers it.

Release flags — qorm package … --release produces a distributable, signed artifact:

FlagPlatformEffect
--app-version Vallmarketing version (default 1.0)
--build Nallbuild number (default 1)
--export-method Miosexport method (default app-store-connect)
--uploadiosupload to App Store Connect (TestFlight) after export
--api-key F --api-key-id ID --api-issuer UUIDiosApp Store Connect API credentials for unattended upload
--keystore F --key-alias Aandroidsign with an existing keystore (default alias qorm; passwords from QORM_KEYSTORE_PASS / QORM_KEY_PASS or a prompt)
--apkandroidalso produce a signed APK next to the AAB
--identity "Developer ID Application: …"macsigning identity (else auto-discovered)
--notarize [--keychain-profile P]macnotarize with notarytool
--no-dmgmacskip the DMG image

Android release signing without --keystore uses a managed keystore at <app-dir>/.qorm/release.keystore: generated with keytool on the first release (a JDK is required), passwords stored in keystore.properties (mode 0600), the whole .qorm directory git-ignored, and reused so every update carries the same signature. A macOS --release build never falls back to ad-hoc signing — it fails instead.

docs

qorm docs [--docs docs] [-o docs-site] [--name Name]

Renders a markdown tree into a static HTML site (this documentation site is built with it). Defaults: source docs/, output docs-site/, header label = the source directory's base name. The header is stamped with the version of the qorm binary doing the render.

audit

qorm audit <audit-log.jsonl>

Verifies a hash-chained activity log written by qorm run --audit-log: each entry's hash covers the previous entry's hash plus its own sequence, timestamp, source, and detail, so any edited, dropped, reordered, or re-attributed entry breaks the chain. Success prints AUDIT OK: N entries, hash chain intact; failure prints AUDIT FAIL after N verified entries: <reason> (locating the first bad entry) and exits 1. The chain is self-anchoring from the first entry — keep an out-of-band copy of the final hash to also detect truncation.

updates

qorm updates [bundles-dir] [--port N]

The publish side of OTA: an HTTP server that hands each client the bundle it should run, honoring a staged (canary) rollout. Defaults: directory ., port 0 (a random free port, printed on startup).

update

qorm update [--insecure-skip-verify]

Self-updates the CLI from the latest GitHub release. Already current (release tag equals the running version): prints so and exits 0. Otherwise, with a Go toolchain present it runs go install github.com/qorm/platform/cmd/qorm@latest; without one it downloads the qorm-<os>-<arch>[.exe] asset, verifies it against the release's SHA256SUMS + SHA256SUMS.sig using the release public keys embedded in the build (a build without embedded keys cannot verify and refuses), then swaps the executable — the old binary is renamed to <exe>.old first and restored if the swap fails. --insecure-skip-verify installs the download without verification (prints a warning; not recommended).

version

qorm version        # aliases: --version, -v

Prints qorm <version> (<go version> <os>/<arch>). The version is stamped at build time via -ldflags -X main.version=<tag>; un-stamped builds report the in-source dev default.