@geastack/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # @geastack/cli
2
+
3
+ Command-line front door for GeaStack.
4
+
5
+ This repo contains the `gea` CLI orchestrator and the `create-geastack`
6
+ scaffolder. The CLI turns GeaStack into an npm-first developer workflow while
7
+ keeping target-specific build logic behind stable backend contracts.
8
+
9
+ ## Commands
10
+
11
+ ```sh
12
+ npx @geastack/create-geastack my-panel
13
+ cd my-panel
14
+ npx gea doctor
15
+ npx gea setup
16
+ npx gea dev
17
+ npx gea build --target web
18
+ npx gea build --target ios
19
+ npx gea flash --board amoled --monitor
20
+ npx gea monitor --board amoled
21
+ npx gea inspect --json
22
+ ```
23
+
24
+ ## Interactive Menu Map
25
+
26
+ ```mermaid
27
+ flowchart TD
28
+ create["npx @geastack/create-geastack my-app"] --> identity["Resolve app identity<br/>argument, optional --id, optional --name"]
29
+ identity --> starter{"Starter app?"}
30
+
31
+ starter -->|"Counter starter"| counter["Copy bundled minimal JSX counter"]
32
+
33
+ starter -->|"Empty app"| empty["Generate minimal app files"]
34
+ empty --> emptyFiles["index.tsx, styles.css, index.html,<br/>tsconfig.json, vite.config.ts"]
35
+
36
+ starter -->|"Rich example"| pickExample["Pick from hard-coded example list<br/>web, ESP32, GeaOS, iOS, macOS, Android"]
37
+ pickExample --> fetchExample["Fetch selected app from GitHub"]
38
+ fetchExample --> copyExample["Copy fetched example files"]
39
+ copyExample --> rewriteExample["Rewrite package name and gea manifest"]
40
+
41
+ counter --> projectWiring["Add @geastack/core and @geastack/cli"]
42
+ rewriteExample --> projectWiring["Add @geastack/core and @geastack/cli"]
43
+ emptyFiles --> projectWiring
44
+ projectWiring --> boardConfig["Create .gea/boards.json"]
45
+ boardConfig --> install["Install npm dependencies<br/>(interactive default)"]
46
+ install --> setup["Next: npx gea setup"]
47
+
48
+ auto["Automation flags"] -.-> starter
49
+ auto --> autoEmpty["--starter empty --yes"]
50
+ auto --> autoExample["--starter example --example watch"]
51
+ ```
52
+
53
+ ```mermaid
54
+ flowchart TD
55
+ setup["npx gea setup"] --> mode{"Mode?"}
56
+
57
+ mode -->|"--esp-idf"| directIdf["Install or check ESP-IDF v6.0.1"]
58
+ mode -->|"--board alias"| directBoard["Run target setup for board alias"]
59
+ mode -->|"--target target-id"| directTarget["Run target setup directly"]
60
+
61
+ mode -->|"Interactive"| interactive{"What do you want to set up?"}
62
+
63
+ interactive -->|"Known supported board"| knownBoard["Pick board"]
64
+ knownBoard --> alias["Set board alias"]
65
+ alias --> serial["Detect serial devices"]
66
+ serial --> saveSerial["Save stable USB serial"]
67
+ saveSerial --> ota["Optional OTA host"]
68
+ ota --> reviewKnown["Review board setup"]
69
+ reviewKnown --> writeKnown["Write .gea/boards.json"]
70
+
71
+ interactive -->|"Custom board profile"| custom["Collect hardware profile"]
72
+ custom --> core["Alias, MCU, closest base target"]
73
+ core --> depth{"Detail level?"}
74
+ depth -->|"Full"| chips["Display, touch,<br/>WiFi/BLE, GPS, audio"]
75
+ depth -->|"Fast"| fast["Display, touch,<br/>default peripherals"]
76
+ chips --> peripherals["Storage, sensors, power,<br/>USB serial or OTA"]
77
+ fast --> connection["USB serial or OTA"]
78
+ peripherals --> connection
79
+ connection --> notes["Notes and datasheet links"]
80
+ notes --> reviewCustom["Review custom profile"]
81
+ reviewCustom --> writeProfile["Write .gea/boards/alias.json"]
82
+ writeProfile --> maybeAlias{"Base target selected?"}
83
+ maybeAlias -->|"Yes"| writeCustomAlias["Write alias to .gea/boards.json"]
84
+ maybeAlias -->|"No"| profileOnly["Profile only, not flash-ready yet"]
85
+
86
+ interactive -->|"npm dependencies only"| npmInstall["Run npm install when package.json exists"]
87
+ interactive -->|"ESP-IDF toolchain only"| idfOnly["Install or check ESP-IDF v6.0.1"]
88
+
89
+ writeKnown --> initialize["Initialize board target"]
90
+ writeCustomAlias --> initialize
91
+ initialize --> ready["Ready: npx gea flash --board alias --monitor"]
92
+ profileOnly --> done["Done"]
93
+ npmInstall --> done
94
+ idfOnly --> done
95
+ directIdf --> done
96
+ directBoard --> done
97
+ directTarget --> done
98
+ ```
99
+
100
+ The CLI resolves `@geastack/core`, `@geastack/targets`, the compiler, chips,
101
+ host bindings, and the other native packages from npm. A project can use a
102
+ local CLI with `npx gea` or a global installation with `gea`; neither command
103
+ depends on a GeaStack source checkout.
104
+
105
+ ## Development
106
+
107
+ ```sh
108
+ npm test
109
+ npm run check
110
+ ```
111
+
112
+ Run from this repo during local development:
113
+
114
+ ```sh
115
+ node bin/gea.mjs doctor
116
+ node bin/gea.mjs --help
117
+ node bin/create-geastack.mjs demo-panel --dir ./demo-panel --dry-run
118
+ ```
119
+
120
+ ## Machine Setup
121
+
122
+ Use [docs/SETUP.md](docs/SETUP.md) for Node/npm, ESP-IDF, Emscripten, Xcode,
123
+ Python, and board configuration. For the Waveshare ESP32-S3 AMOLED path, use
124
+ [docs/ESP32-WAVESHARE-AMOLED-QUICKSTART.md](docs/ESP32-WAVESHARE-AMOLED-QUICKSTART.md).
125
+ `npx gea doctor` checks the same dependencies and prints warnings for optional
126
+ target toolchains that are not installed.
127
+
128
+ [docs/NPX-COMMANDS.md](docs/NPX-COMMANDS.md) captures the private npmjs
129
+ `npx` command shape for release.
130
+
131
+ ## Responsibilities
132
+
133
+ The CLI should own:
134
+
135
+ - command parsing and help output;
136
+ - project scaffolding;
137
+ - Gea app manifest validation;
138
+ - target discovery and target backend dispatch;
139
+ - consistent output, diagnostics, and exit codes;
140
+ - `doctor` checks for local toolchains, board config, and target backends.
141
+
142
+ The CLI should not own target implementation details. ESP32, GeaOS, Apple, and
143
+ web targets should keep their target-specific build logic in their own repos and
144
+ expose stable command contracts.
145
+
146
+ ## Documentation
147
+
148
+ - [docs/SPEC.md](docs/SPEC.md): command surface, manifest expectations, and
149
+ backend contract for the first implementation.
150
+
151
+ ## Current Status
152
+
153
+ First implementation is in place:
154
+
155
+ - `doctor` for local toolchain checks;
156
+ - npm-resolved embedded board builds for ESP32 and RP2350;
157
+ - `flash`, `monitor`, WiFi OTA, and BLE OTA through `@geastack/targets`;
158
+ - `list` and `inspect` helpers;
159
+ - `create-geastack` with a bundled counter starter, an empty starter, and a
160
+ GitHub-backed rich example flow for web, embedded, GeaOS, iOS, macOS, and Android apps,
161
+ all with `.gea/boards.json`.
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import { runCreateGeastack } from '../src/create-geastack.mjs'
3
+ import { CliError } from '../src/errors.mjs'
4
+
5
+ try {
6
+ const exitCode = await runCreateGeastack(process.argv.slice(2))
7
+ if (exitCode) process.exit(exitCode)
8
+ } catch (error) {
9
+ if (error instanceof CliError) {
10
+ console.error(error.message)
11
+ process.exit(error.exitCode)
12
+ }
13
+ console.error(error && error.stack ? error.stack : String(error))
14
+ process.exit(1)
15
+ }
package/bin/gea.mjs ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import { runGea } from '../src/gea.mjs'
3
+ import { CliError } from '../src/errors.mjs'
4
+
5
+ try {
6
+ const exitCode = await runGea(process.argv.slice(2))
7
+ if (exitCode) process.exit(exitCode)
8
+ } catch (error) {
9
+ if (error instanceof CliError) {
10
+ console.error(error.message)
11
+ process.exit(error.exitCode)
12
+ }
13
+ console.error(error && error.stack ? error.stack : String(error))
14
+ process.exit(1)
15
+ }
@@ -0,0 +1,133 @@
1
+ # ESP32 Waveshare AMOLED Quickstart
2
+
3
+ Goal: fresh computer to flashed Waveshare ESP32-S3 Touch AMOLED app without cloning any GeaStack repo.
4
+
5
+ You should only need four moves:
6
+
7
+ 1. Install the system basics.
8
+ 2. Create a Gea app.
9
+ 3. Run the setup wizard.
10
+ 4. Flash the board.
11
+
12
+ ## 1. Install The Basics
13
+
14
+ Install:
15
+
16
+ - Git
17
+ - Node.js 20.19 or newer
18
+ - npm
19
+ - Python 3
20
+
21
+ On macOS, also make sure Apple command line tools are installed:
22
+
23
+ ```sh
24
+ xcode-select --install
25
+ ```
26
+
27
+ You do not clone GeaStack.
28
+
29
+ ## 2. Create The App
30
+
31
+ ```sh
32
+ npm login
33
+ npx @geastack/create-geastack my-app
34
+ cd my-app
35
+ ```
36
+
37
+ When the wizard asks what to create, choose:
38
+
39
+ ```text
40
+ ? What do you want to create?
41
+ Counter starter - bundled minimal JSX app
42
+ Empty app - minimal blank Gea app
43
+ Rich example - fetch from GitHub examples repo
44
+ ```
45
+
46
+ For the fastest first flash, choose `Counter starter`.
47
+
48
+ That creates a tiny JSX app with one store and installs the project-local Gea CLI, so inside the app you can run `npx gea`.
49
+
50
+ ## 3. Set Up The Board
51
+
52
+ ```sh
53
+ npx gea setup
54
+ ```
55
+
56
+ Choose:
57
+
58
+ ```text
59
+ ? What do you want to set up?
60
+ Known supported board
61
+
62
+ ? Board
63
+ Waveshare ESP32-S3 Touch AMOLED 2.06
64
+
65
+ ? Board alias
66
+ amoled
67
+
68
+ ? Save this board setup?
69
+ Yes
70
+ ```
71
+
72
+ If ESP-IDF is not installed, accept the installer when offered:
73
+
74
+ ```text
75
+ ? ESP-IDF was not found. Install it now?
76
+ Yes
77
+ ```
78
+
79
+ If ESP-IDF was installed, the CLI prints this for future shells:
80
+
81
+ ```sh
82
+ . "$HOME/esp/esp-idf/export.sh"
83
+ ```
84
+
85
+ You do not need to run that before every command unless `npx gea doctor` says ESP-IDF is not active.
86
+
87
+ If the wizard finds a connected serial device, pick it. If no board is plugged in yet, that is fine; you can provide the port later.
88
+
89
+ The wizard writes the board config into your app at `.gea/boards.json` and initializes the selected board target.
90
+
91
+ ## 4. Flash
92
+
93
+ Flash and open the serial monitor:
94
+
95
+ ```sh
96
+ npx gea flash --board amoled --monitor
97
+ ```
98
+
99
+ If you need to specify the serial port manually:
100
+
101
+ ```sh
102
+ npx gea flash --board amoled --port /dev/cu.usbmodemXXXX --monitor
103
+ ```
104
+
105
+ ## Rich Examples
106
+
107
+ The bundled starter is intentionally tiny. Rich examples live in the GeaStack examples repo and are fetched on demand by name.
108
+
109
+ For example:
110
+
111
+ ```sh
112
+ npx @geastack/create-geastack watch-demo --starter example --example watch
113
+ cd watch-demo
114
+ npx gea setup
115
+ npx gea flash --board amoled --monitor
116
+ ```
117
+
118
+ The CLI owns the example catalog, so the user does not need to clone the examples repo.
119
+
120
+ ## If Something Fails
121
+
122
+ Run:
123
+
124
+ ```sh
125
+ npx gea doctor
126
+ ```
127
+
128
+ Most first-run issues are one of:
129
+
130
+ - ESP-IDF is not activated in the current shell.
131
+ - The USB cable is power-only.
132
+ - The serial port needs to be passed with `--port`.
133
+ - The board alias does not match the name in `.gea/boards.json`.
@@ -0,0 +1,144 @@
1
+ # Private npm Command Shape
2
+
3
+ The intended private npmjs onboarding should not require cloning GeaStack repos.
4
+
5
+ Desired user flow:
6
+
7
+ ```sh
8
+ npm login
9
+ npx @geastack/create-geastack my-app
10
+ cd my-app
11
+ npx gea setup
12
+ npx gea flash --board amoled --monitor
13
+ ```
14
+
15
+ ## Package Name Reality
16
+
17
+ There should not be an unscoped npm package. Private npmjs packages must be
18
+ scoped.
19
+
20
+ Use these release packages instead:
21
+
22
+ - `@geastack/create-geastack`: scoped private project/app scaffolder exposing
23
+ the `create-geastack` bin.
24
+ - `@geastack/cli`: scoped private Gea CLI package exposing the `gea` bin.
25
+
26
+ `create-geastack` should add `@geastack/cli` as a devDependency in generated
27
+ projects and install dependencies by default in interactive terminals. After
28
+ that, inside the project, `npx gea ...` works because npm finds the local
29
+ `node_modules/.bin/gea` binary. It does not require an npm package named `gea`.
30
+
31
+ If someone is wiring an existing app by hand, install the package first:
32
+
33
+ ```sh
34
+ npm install --save-dev @geastack/cli
35
+ npx gea setup
36
+ ```
37
+
38
+ Creator-style scaffolding is:
39
+
40
+ ```sh
41
+ npx @geastack/create-geastack my-app
42
+ ```
43
+
44
+ In an interactive terminal, `create-geastack` asks:
45
+
46
+ ```text
47
+ Starter app
48
+ 1. Counter starter - bundled minimal JSX app
49
+ 2. Empty app - minimal blank Gea app
50
+ 3. Rich example - fetch from GitHub examples repo
51
+ ```
52
+
53
+ `Counter starter` is the only bundled source starter. It is intentionally tiny:
54
+ JSX, one `store.ts`, and enough styling to run.
55
+
56
+ `Empty app` creates the smallest starter: `index.tsx`, `styles.css`,
57
+ `index.html`, `tsconfig.json`, `vite.config.ts`, `package.json`, and
58
+ `.gea/boards.json`.
59
+
60
+ `Rich example` opens an example picker populated from the hard-coded
61
+ `examples/catalog.json` shipped inside `@geastack/cli`. The catalog contains web,
62
+ ESP32, GeaOS, iOS, macOS, and Android examples with names, descriptions, target
63
+ flags, and GitHub paths. When the user selects an example, the CLI fetches that app from
64
+ `geastack/examples`, copies it into the new project, then rewrites
65
+ `package.json`, app id, app name, `@geastack/core`, `@geastack/cli`, and
66
+ `.gea/boards.json`.
67
+
68
+ Automation can skip prompts:
69
+
70
+ ```sh
71
+ npx @geastack/create-geastack my-app --starter counter
72
+ npx @geastack/create-geastack my-app --starter empty --yes
73
+ npx @geastack/create-geastack my-app --starter example --example watch
74
+ npx @geastack/create-geastack my-ios-app --starter example --example ios-native-showcase
75
+ npx gea build --target ios --mode simulator
76
+ npx @geastack/create-geastack cube-app --starter example --example css-3d-cube
77
+ npx gea build --target android --mode device
78
+ ```
79
+
80
+ The private npmjs flow does not depend on a cloned examples repo. The rich
81
+ examples are fetched by the CLI when selected.
82
+
83
+ Do not change GitHub repository privacy while preparing this shape. The npm
84
+ packages are scoped and configured for restricted npmjs publication.
85
+
86
+ ## Setup Wizard Contract
87
+
88
+ `gea setup` with no `--board` or `--target` opens a guided setup flow:
89
+
90
+ - known supported board, with descriptions for each board;
91
+ - custom board profile, with fast and full hardware paths;
92
+ - npm dependency check/install only;
93
+ - ESP-IDF toolchain check/install only.
94
+
95
+ Known-board setup detects attached serial devices, asks for a stable USB serial,
96
+ shows a review screen, writes a board alias into the active boards config, then
97
+ initializes the selected board target so the next command can be
98
+ `npx gea flash --board <alias> --monitor`. In generated apps, that config is:
99
+
100
+ ```text
101
+ .gea/boards.json
102
+ ```
103
+
104
+ Custom-board setup can run in two depths:
105
+
106
+ - `Full hardware profile`: display, touch, WiFi/BLE, GPS, audio, storage,
107
+ sensors, power, transport, and notes.
108
+ - `Fast profile`: core board identity, display/touch, transport, and inferred
109
+ defaults for optional peripherals.
110
+
111
+ Both paths show a review screen before writing a profile under:
112
+
113
+ ```text
114
+ .gea/boards/<alias>.json
115
+ ```
116
+
117
+ The full profile captures:
118
+
119
+ - MCU / SoC;
120
+ - closest existing base target;
121
+ - display type, controller, interface, resolution;
122
+ - touch controller and interface;
123
+ - WiFi and BLE;
124
+ - GPS module and interface;
125
+ - audio codec, input, and output;
126
+ - storage;
127
+ - sensors;
128
+ - power path;
129
+ - USB serial and OTA transports;
130
+ - notes/datasheet links.
131
+
132
+ If the user selects a base target, the wizard also writes an experimental board
133
+ alias that points at that base target and references the custom profile. If no
134
+ base target is selected, the profile is generated without claiming the board is
135
+ flash-ready.
136
+
137
+ ESP-IDF setup is available as:
138
+
139
+ ```sh
140
+ npx gea setup --esp-idf
141
+ ```
142
+
143
+ It installs or dry-runs ESP-IDF v6.0.1 with the ESP32, ESP32-S3, and ESP32-P4
144
+ toolchains.