@geastack/cli 0.1.8 → 0.1.9
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 +7 -3
- package/docs/NPX-COMMANDS.md +4 -3
- package/docs/SPEC.md +2 -1
- package/package.json +1 -1
- package/src/create-geastack.mjs +64 -4
package/README.md
CHANGED
|
@@ -31,8 +31,10 @@ flowchart TD
|
|
|
31
31
|
|
|
32
32
|
starter -->|"Embedded component counter"| counter["Copy the touchscreen counter used in the embedded tutorial"]
|
|
33
33
|
|
|
34
|
-
starter -->|"Blank application"|
|
|
35
|
-
|
|
34
|
+
starter -->|"Blank application"| emptyTarget{"Where should it run?"}
|
|
35
|
+
emptyTarget -->|"Web browser"| emptyWeb["Generate browser entry, HTML, and Vite config"]
|
|
36
|
+
emptyTarget -->|"ESP32 board"| emptyEsp["Generate native entry<br/>Ask whether to enable Bluetooth updates"]
|
|
37
|
+
emptyTarget -->|"Other native target"| emptyNative["Generate native entry for the selected platform"]
|
|
36
38
|
|
|
37
39
|
starter -->|"Example application"| pickExample["Pick from the example gallery<br/>web, ESP32, GeaOS, iOS, macOS, Android"]
|
|
38
40
|
pickExample --> fetchExample["Fetch selected app from GitHub"]
|
|
@@ -41,7 +43,9 @@ flowchart TD
|
|
|
41
43
|
|
|
42
44
|
counter --> projectWiring["Add @geastack/core and @geastack/cli"]
|
|
43
45
|
rewriteExample --> projectWiring["Add @geastack/core and @geastack/cli"]
|
|
44
|
-
|
|
46
|
+
emptyWeb --> projectWiring
|
|
47
|
+
emptyEsp --> projectWiring
|
|
48
|
+
emptyNative --> projectWiring
|
|
45
49
|
projectWiring --> boardConfig["Create .gea/boards.json"]
|
|
46
50
|
boardConfig --> install["Install npm dependencies<br/>(interactive default)"]
|
|
47
51
|
install --> setup["Next: npx gea setup"]
|
package/docs/NPX-COMMANDS.md
CHANGED
|
@@ -53,9 +53,10 @@ What do you want to build?
|
|
|
53
53
|
`Embedded component counter` is the bundled tutorial starter. It uses local
|
|
54
54
|
component state, targets ESP32, and enables BLE updates.
|
|
55
55
|
|
|
56
|
-
`Blank application`
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
`Blank application` asks where the app should run. It creates the smallest
|
|
57
|
+
project for that target and, for ESP32, asks whether to enable wireless
|
|
58
|
+
firmware updates over Bluetooth. Browser-only files such as `index.html` and
|
|
59
|
+
`vite.config.ts` are added only when the web target is selected.
|
|
59
60
|
|
|
60
61
|
`Example application` opens an example picker populated from the hard-coded
|
|
61
62
|
`examples/catalog.json` shipped inside `@geastack/cli`. The catalog contains web,
|
package/docs/SPEC.md
CHANGED
|
@@ -132,7 +132,8 @@ Interactive starter choices must explain the tradeoff in-line:
|
|
|
132
132
|
|
|
133
133
|
- `Embedded component counter`: create a touchscreen counter with local
|
|
134
134
|
component state, an ESP32 target, and BLE updates enabled.
|
|
135
|
-
- `Blank application`:
|
|
135
|
+
- `Blank application`: ask where the app should run, generate the matching
|
|
136
|
+
minimal project, and ask whether to enable Bluetooth updates for ESP32.
|
|
136
137
|
- `Example application`: fetch a selected app from `geastack/examples`, then rewrite
|
|
137
138
|
package name, app id, dependencies, and board config for the new project.
|
|
138
139
|
|
package/package.json
CHANGED
package/src/create-geastack.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { flag, option, optionList, parseArgs } from './args.mjs'
|
|
|
5
5
|
import { createContext } from './context.mjs'
|
|
6
6
|
import { ExitCode, fail } from './errors.mjs'
|
|
7
7
|
import { exists, readJson, writeJson } from './fs-utils.mjs'
|
|
8
|
-
import { canPrompt, choose, createPrompt } from './prompts.mjs'
|
|
8
|
+
import { canPrompt, choose, confirm, createPrompt } from './prompts.mjs'
|
|
9
9
|
import { runExternal } from './run.mjs'
|
|
10
10
|
import {
|
|
11
11
|
copyStarterFiles,
|
|
@@ -67,12 +67,12 @@ export async function runCreateGeastack(argv, io = {}) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
const sourcePackage = readPackageJson(targetDir)
|
|
70
|
-
const sourceManifest = sourcePackage.gea || starter.starter?.manifest || starter.example?.manifest || {}
|
|
70
|
+
const sourceManifest = sourcePackage.gea || starter.manifest || starter.starter?.manifest || starter.example?.manifest || {}
|
|
71
71
|
const requestedTargets = optionList(parsed, 'targets')
|
|
72
72
|
const targets = requestedTargets.length > 0
|
|
73
73
|
? targetManifest(requestedTargets)
|
|
74
74
|
: starter.kind === 'empty'
|
|
75
|
-
? targetManifest(['web'])
|
|
75
|
+
? targetManifest(starter.targets || ['web'])
|
|
76
76
|
: targetManifestFromObject(sourceManifest.targets)
|
|
77
77
|
writeJson(path.join(targetDir, 'package.json'), packageJson({
|
|
78
78
|
appId,
|
|
@@ -121,7 +121,23 @@ async function resolveStarter(ctx, parsed, io) {
|
|
|
121
121
|
try {
|
|
122
122
|
const mode = requested || await chooseStarterMode({ interactive, prompt, bundled, examples })
|
|
123
123
|
|
|
124
|
-
if (mode === 'empty')
|
|
124
|
+
if (mode === 'empty') {
|
|
125
|
+
const requestedTargets = optionList(parsed, 'targets')
|
|
126
|
+
if (!interactive || requestedTargets.length > 0) return { kind: 'empty' }
|
|
127
|
+
|
|
128
|
+
const target = await chooseBlankTarget(prompt)
|
|
129
|
+
const enableBleOta = target === 'esp32'
|
|
130
|
+
? await confirm(prompt, {
|
|
131
|
+
message: 'Enable wireless firmware updates over Bluetooth?',
|
|
132
|
+
defaultValue: true
|
|
133
|
+
})
|
|
134
|
+
: false
|
|
135
|
+
return {
|
|
136
|
+
kind: 'empty',
|
|
137
|
+
targets: [target],
|
|
138
|
+
manifest: enableBleOta ? { ota: { ble: true } } : {}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
125
141
|
if (mode === 'bundled' || mode === 'counter') {
|
|
126
142
|
const requestedBundled = mode === 'counter' ? 'counter' : option(parsed, 'bundled') || option(parsed, 'starter-id') || ''
|
|
127
143
|
const starter = requestedBundled
|
|
@@ -191,6 +207,50 @@ async function chooseExample({ interactive, prompt, examples }) {
|
|
|
191
207
|
return examples.find((example) => example.id === id) || null
|
|
192
208
|
}
|
|
193
209
|
|
|
210
|
+
async function chooseBlankTarget(prompt) {
|
|
211
|
+
return choose(prompt, {
|
|
212
|
+
message: 'Where should this application run?',
|
|
213
|
+
choices: [
|
|
214
|
+
{
|
|
215
|
+
value: 'web',
|
|
216
|
+
label: 'Web browser',
|
|
217
|
+
description: 'A browser app with a local development server.'
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
value: 'esp32',
|
|
221
|
+
label: 'ESP32 board',
|
|
222
|
+
description: 'Native firmware for a supported ESP32 device.'
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
value: 'rp2350',
|
|
226
|
+
label: 'RP2350 board',
|
|
227
|
+
description: 'Native firmware for a supported Raspberry Pi RP2350 device.'
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
value: 'geaos',
|
|
231
|
+
label: 'GeaOS device',
|
|
232
|
+
description: 'A native application for GeaOS.'
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
value: 'macos',
|
|
236
|
+
label: 'macOS',
|
|
237
|
+
description: 'A native Mac application.'
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
value: 'ios',
|
|
241
|
+
label: 'iPhone or iPad',
|
|
242
|
+
description: 'A native iOS application.'
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
value: 'android',
|
|
246
|
+
label: 'Android',
|
|
247
|
+
description: 'A native Android application.'
|
|
248
|
+
}
|
|
249
|
+
],
|
|
250
|
+
defaultValue: 'web'
|
|
251
|
+
})
|
|
252
|
+
}
|
|
253
|
+
|
|
194
254
|
function ensureWritableTarget(targetDir, force) {
|
|
195
255
|
if (!exists(targetDir)) return
|
|
196
256
|
const entries = fs.readdirSync(targetDir).filter((entry) => entry !== '.DS_Store')
|