Skip to main content

CLI

The kog CLI is installed per-project (npx kog … or via package scripts). Everything is Node: flashing and deploying need no Python, ESP-IDF, or esptool. The desktop simulator is a separate native binary; see The simulator.

Every command that touches a board or the build (dev, build, flash, deploy, simulate, wifi) accepts --help (-h) and prints its usage without doing anything else. For example, kog flash --help shows the options and never touches your board. On macOS, --port accepts either the /dev/cu.* or the /dev/tty.* name for a device; they refer to the same port.

Commands​

kog dev​

Dev server + hot reload. Compiles on save and pushes to every target: the simulator and, when a blessed board is plugged in over USB, the board itself. The board gets the bundle compiled to MQuickJS bytecode, hot-reloaded over the serial dev-link. Streams the board's console.* and errors back to your terminal. A plugged-in board is targeted by default.

Hot reload to a board is over USB serial only; there is no Wi-Fi/network hot-reload path. (Wi-Fi on the device is for your app's own networking; it isn't a code-push channel.) Hot reload works on a board in development posture, which is the state kog flash leaves it in. A kog deployed board has hot reload off (see below).

To attach, kog dev pulses a reset on the board so it re-announces itself (a board sends its dev-link handshake once at boot); you'll see a Board linked … line once the ABI check passes. If no board is found it runs the simulator alone. kog dev looks for a board once, at startup: to add a board later, plug it in and restart kog dev.

  • --sim: simulator only (don't target a board)
  • --port <p>: use a specific serial port
  • --no-sim: skip the simulator (device + dev server only)
  • --headless: run the simulator without a window
  • --board <slug>: use a board's simulator size, HiDPI scale, and display shape
  • --size WxH: override the board's physical simulator size
  • --ui-scale <n>: override the board's HiDPI scale
  • --no-mask: disable display-shape masking and touch gating

kog build​

Type-check (tsc --noEmit, fails on type errors) → compile → bundle. Writes the ES5 JavaScript bundle for MQuickJS to dist/app.mjs. kog deploy doesn't read dist/: it runs its own build from source, compiles that to bytecode, and assembles the installable bundle.

  • --no-typecheck: skip the tsc --noEmit gate
  • -o <path>: output path (default dist/app.mjs)

It also writes dist/app.mjs.map, a source map from the bundle back to your files. The bundle doesn't reference it; kog simulate, kog dev and Studio use it to print error locations (see Error locations).

Every app module is checked for JavaScript the device's engine can't run, including plain .ts files. An unsupported feature, such as a WeakMap or a RegExp lookbehind, fails the build at its line, and a likely problem, such as localeCompare, is a warning (the full list). Third-party packages from node_modules are checked too, as warnings prefixed dependency:. Studio runs the same check with the same messages.

A --release build mode (optimizations, console stripped) is not implemented yet; the flag is currently ignored.

kog flash​

First-time or full flash over USB: detects the board, resolves the matching prebuilt runtime image (each part SHA-256-verified before writing), and writes the bootloader, partition table, OTA data, and runtime image in one pass, plus a development-posture NVS partition (which also carries any Wi-Fi credentials from kog.config). Writing that partition replaces the board's existing NVS contents. It's pure Node: no Python, no esptool install. The flash baud is chosen per USB bridge automatically (native-USB boards run fast; UART bridges like the CYD's CH340 drop to a safe rate). Leaves the board in development posture, with the dev-link reserved so kog dev can hot-reload it.

  • --port <p>: explicit serial port (otherwise auto-detected)
  • --board <id>: pick a board when chip detection is ambiguous (cyd | cyd-classic | waveshare-1.46b | waveshare-amoled-2.06)
  • --baud <n>: override the auto-selected flash baud
  • --manifest <path|url>: use a specific boards.json instead of the local build output or the hosted manifest

The board is matched from the chip, and boards that share a chip by their flash part's size, which the CLI reads after syncing (it prints it on the Chip: line). An ESP32-S3 with 32 MB flash is the Waveshare AMOLED-2.06, and one with 16 MB is the Waveshare 1.46B, so neither needs --board. If the flash id can't be read, the CLI stops with board-ambiguous and asks for --board. An explicit --board that contradicts the detected size is honored, with a warning that names the matching board.

The CYD needs --board: its two panel generations share one silkscreen and one chip id, so the CLI won't guess. Flash --board cyd first; a left/right-mirrored screen with orange-instead-of-blue UI means yours is the classic generation; reflash with --board cyd-classic. See Flash your board.

kog deploy​

Build and install the app bundle onto a connected board as its standalone app. This is the OTA install path (signed when you configure a key; see below). The bundle is staged to flash and committed with a rollback-pending flag that clears once the board boots it healthy, so a bundle that fails to boot is never promoted. (Restoring the previous app after a failed trial boot is a known issue; see OTA updates.) Survives power-cycles, unlike kog dev's RAM hot-reload. Uses the same USB port discovery as kog flash.

Puts the board in production posture: hot reload is turned off and the full RAM goes to your app. A deployed board has no code-push channel (the dev-link isn't reserved). To go back to developing on that board, run kog flash again.

By default the bundle is unsigned. A development board (keyless, the state kog flash leaves it in) accepts it (spec/05 §2). The bundle is signed only when you configure a key with ota.signingKey in kog.config, KOG_SIGNING_KEY, or --signing-key. That is the production path, where the board is provisioned with the matching public key.

After staging, the board is reset so it boots the deployed app immediately (OTA install itself doesn't reboot). Pass --no-reset to leave the running app in place; it boots the new bundle on the next manual reset.

  • --port <p>: explicit serial port
  • --signing-key <path>: sign with a specific Ed25519 key (overrides kog.config ota.signingKey)
  • --unsigned: force an unsigned bundle even if a signing key is configured
  • --no-reset: stage without resetting the board
note

kog flash/kog deploy device behavior is confirmed against live hardware in the hardware-validation pass; flag details here track the shipped commands.

kog simulate <bundle>​

Launch the simulator without the dev server, running the bundle you pass (for example kog build && kog simulate dist/app.mjs). It takes the same --headless, --board, --size, --ui-scale, and --no-mask options as kog dev.

Error locations​

The engine reports a stack frame as a position in the compiled bundle, <app>:LINE:COL. kog simulate, kog dev and Studio rewrite those frames through the build's source map, so an uncaught error reads:

Error: kaboom from util
at boom (src/util.ts:4:15)
at App (src/App.tsx:5:13)

Frames map to the exact file, line and column, in component files and plain .ts modules alike. kog dev maps errors from the simulator and from boards on the dev-link. An app installed with kog deploy runs on its own, with no host session to map its errors.

kog doctor​

Environment check covering Node version, the project, board.yaml presence, the simulator binary, and serial ports. Every failure is paired with its fix.

kog board validate (not yet available)​

Planned: validate board.yaml against the schema and explain any mismatch. In this build the command exits with a "not wired up yet" message.

kog firmware build (not yet available)​

Planned: compile a custom runtime from board.yaml (Tier C), bootstrapping the managed toolchain on first run. In this build the command exits with a "not wired up yet" message. See Boards.

kog wifi​

Provision Wi-Fi credentials over a USB-connected device, for your app's own networking (fetch, WebSocket, WiFi). It rewrites the board's NVS partition with them (and development posture, like kog flash), then resets the board. It takes --port, --board, --baud and --manifest like kog flash, but rarely needs --board: it works on either ESP32-S3 board and either CYD image, because each pair shares one NVS layout, so it proceeds even when it can't tell which board it has.

create-kog​

Project scaffolding, invoked as npm create kog@latest [name].