Command-line front door for GeaStack.
This repo contains the gea CLI orchestrator and the create-geastack
scaffolder. The CLI turns GeaStack into an npm-first developer workflow while
keeping target-specific build logic behind stable backend contracts.
npm install --global @geastack/cli
gea create my-panel
cd my-panel
gea doctor
gea setup
gea dev
gea build --target web
gea build --target ios
gea flash --board amoled --monitor
gea screenshot board.png --board amoled
gea monitor --board amoled
gea inspect --jsonflowchart TD
create["gea create my-app"] --> identity["Resolve app identity<br/>argument, optional --id, optional --name"]
identity --> starter{"Starter app?"}
starter -->|"Embedded component counter"| counter["Copy the touchscreen counter used in the embedded tutorial"]
starter -->|"Blank application"| emptyTarget{"Where should it run?"}
emptyTarget -->|"Web browser"| emptyWeb["Generate browser entry, HTML, and Vite config"]
emptyTarget -->|"ESP32 board"| emptyEsp["Generate native entry<br/>Ask whether to enable Bluetooth updates"]
emptyTarget -->|"Other native target"| emptyNative["Generate native entry for the selected platform"]
starter -->|"Example application"| pickExample["Pick from the example gallery<br/>web, ESP32, GeaOS, iOS, macOS, Android"]
pickExample --> fetchExample["Fetch selected app from GitHub"]
fetchExample --> copyExample["Copy fetched example files"]
copyExample --> rewriteExample["Rewrite package name and gea manifest"]
counter --> projectWiring["Add @geastack/core and @geastack/cli"]
rewriteExample --> projectWiring["Add @geastack/core and @geastack/cli"]
emptyWeb --> projectWiring
emptyEsp --> projectWiring
emptyNative --> projectWiring
projectWiring --> boardConfig["Create .gea/boards.json"]
boardConfig --> install["Install npm dependencies<br/>(interactive default)"]
install --> setup["Next: npx gea setup"]
auto["Automation flags"] -.-> starter
auto --> autoEmpty["--starter blank --yes"]
auto --> autoExample["--starter example --example watch"]
flowchart TD
setup["npx gea setup"] --> mode{"Mode?"}
mode -->|"--esp-idf"| directIdf["Install or check ESP-IDF v6.0.2"]
mode -->|"--board alias"| directBoard["Run target setup for board alias"]
mode -->|"--target target-id"| directTarget["Run target setup directly"]
mode -->|"Interactive"| interactive{"What do you want to set up?"}
interactive -->|"Known supported board"| knownBoard["Pick board"]
knownBoard --> alias["Set board alias"]
alias --> serial["Detect serial devices"]
serial --> saveSerial["Detect the USB serial (registry + GEADEV ping)"]
saveSerial --> ota["Optional OTA host"]
ota --> reviewKnown["Review board setup"]
reviewKnown --> writeKnown["Write .gea/boards.json"]
interactive -->|"Custom board target"| custom["Choose MCU and compatible chips"]
custom --> chipConfig["Ask interface and pin questions<br/>from @geastack/chips/catalog.json"]
chipConfig --> features["Optional microSD and launcher button"]
features --> connection["Detect initial USB connection"]
connection --> reviewCustom["Review native composition"]
reviewCustom --> writeProfile["Write .gea/targets/alias.json"]
writeProfile --> writeCustomAlias["Write alias to .gea/boards.json"]
interactive -->|"npm dependencies only"| npmInstall["Run npm install when package.json exists"]
interactive -->|"ESP-IDF toolchain only"| idfOnly["Install or check ESP-IDF v6.0.2"]
writeKnown --> initialize["Initialize board target"]
writeCustomAlias --> initialize
initialize --> ready["Ready: npx gea flash --board alias --monitor"]
npmInstall --> done
idfOnly --> done
directIdf --> done
directBoard --> done
directTarget --> done
The CLI resolves @geastack/core, @geastack/targets, the compiler, chips,
host bindings, and the other native packages from npm. A project can use a
local CLI with npx gea or a global installation with gea; neither command
depends on a GeaStack source checkout.
Boards are managed without editing JSON by hand; aliases live in
~/.geastack/boards.json (this machine) and the project's .gea/boards.json
(overrides):
gea boards discover # which registered board is on which USB port, its app and IP
gea boards list
gea boards set amoled host 192.168.1.100
gea boards rename amoled desk-amoled
gea boards remove desk-amoledCustom boards remain editable after setup:
gea chips list
gea chips info co5300
gea chips add co5300 ft3168 --board my-board
gea chips remove ft3168 --board my-boardThese commands update the app-local target definition. They do not copy native
sources into the application; the target adapter compiles the selected drivers
directly from the installed @geastack/chips package.
npm test
npm run checkRun from this repo during local development:
node bin/gea.mjs doctor
node bin/gea.mjs --help
node bin/create-geastack.mjs demo-panel --dir ./demo-panel --dry-runUse docs/SETUP.md for Node/npm, ESP-IDF, Emscripten, Xcode,
Python, and board configuration. For the Waveshare ESP32-S3 AMOLED path, use
docs/ESP32-WAVESHARE-AMOLED-QUICKSTART.md.
npx gea doctor checks the same dependencies and prints warnings for optional
target toolchains that are not installed.
The CLI should own:
- command parsing and help output;
- project scaffolding;
- Gea app manifest validation;
- target discovery and target backend dispatch;
- consistent output, diagnostics, and exit codes;
doctorchecks for local toolchains, board config, and target backends.
The CLI should not own target implementation details. ESP32, GeaOS, Apple, and web targets should keep their target-specific build logic in their own repos and expose stable command contracts.
- docs/SPEC.md: command surface, manifest expectations, and backend contract for the first implementation.
- docs/SETUP.md: toolchains per target, the ESP-IDF version GeaStack resolves, and the board configuration files.
- docs/DEVICE-CONTROL.md:
gea devctlin full, both wire protocols, and the display knobs.
First implementation is in place:
doctorfor local toolchain checks;- npm-resolved embedded board builds for ESP32 and RP2350;
flash,monitor, WiFi OTA, and BLE OTA through@geastack/targets;listandinspecthelpers;create-geastackwith a bundled counter starter, a blank application, and a GitHub-backed rich example flow for web, embedded, GeaOS, iOS, macOS, and Android apps, all with.gea/boards.json, plusgea boardsfor machine-wide aliases in~/.geastack/boards.json.
Apache-2.0 (see LICENSE). You can ship closed-source products
built on it. The only GeaStack code under a different license is
the embedded board support (targets and @geastack/chips, GPL-3.0-only):
shipping closed-source firmware through those needs a commercial license.
Contact contact@geastack.com for commercial terms, support and hosted builds.
gea dev (equivalently gea dev --target web) runs the Gea DOM/CSS app with
Vite HMR. gea simulate uses that same pipeline inside a device viewport and
opens the browser. Use --no-open to suppress opening, and --width, --height,
--zoom, and --dpr to configure the preview. DPR is a simulated Display API
value; it does not override the browser's pixel ratio.
The default for simulate changed from WASM to DOM. To retain the embedded
renderer and framebuffer workflow, use gea simulate --renderer wasm; this
explicit mode still requires Emscripten. Unknown renderer values are rejected.
gea build --target web emits HTML/JS/CSS into .gea/build/web/site (override
with --out-dir). The app's index.html is honored. Web-only Vite customization
belongs in vite.web.config.ts; new web apps scaffold this file. Existing
vite.config.* files remain dedicated to their previous build pipeline.
Compatible component edits and CSS changes update without reloading the page; reactive state is preserved for compatible component edits. Incompatible edits reload. Browser previews use simulated device APIs and browser layout; use the WASM renderer or a physical device to validate embedded rendering.