mbflash 0.0.0-stage → 1.2.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/LICENSE +21 -0
- package/README.md +262 -2
- package/mbflash.mjs +1451 -0
- package/package.json +42 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Taisuke Yamada
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,263 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mbflash
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/tai/mbflash/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/mbflash)
|
|
5
|
+
|
|
6
|
+
A dependency-free CLI for driving the micro:bit MakeCode editor over CDP:
|
|
7
|
+
load TypeScript, commit it to Blocks, compile/download the `.hex`, and flash it
|
|
8
|
+
by writing to the `MICROBIT` volume (no WebUSB pairing needed).
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
mbflash main.ts
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
That one command:
|
|
15
|
+
|
|
16
|
+
1. attaches to the MakeCode tab in a CDP-enabled Chromium,
|
|
17
|
+
2. loads `main.ts` into the editor and rebuilds the Blocks view,
|
|
18
|
+
3. compiles and downloads the `.hex`,
|
|
19
|
+
4. copies it to the micro:bit's DAPLink volume and waits for the remount.
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
- Node.js **22.4+** (uses the built-in `WebSocket` and `fetch`).
|
|
24
|
+
- A headed Chromium/Chrome launched with a debugging port:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
chromium --user-data-dir="$HOME/.config/chromium-agent" \
|
|
28
|
+
--remote-debugging-port=9222 \
|
|
29
|
+
--remote-debugging-address=127.0.0.1 \
|
|
30
|
+
"https://makecode.microbit.org/#editor"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- One or more MakeCode tabs. Select the intended one with `--project`,
|
|
34
|
+
`--target`, or `--index`; ambiguous matches are refused.
|
|
35
|
+
- The micro:bit mounted as `MICROBIT` (normally `/run/media/$USER/MICROBIT`).
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
From npm:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
npm install -g mbflash
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
From this GitHub repository:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
npm install -g github:tai/mbflash
|
|
49
|
+
# or: npm install -g git+https://github.com/tai/mbflash.git
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For development from a checkout:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
npm link # puts `mbflash` on PATH, pointing at ./mbflash.mjs
|
|
56
|
+
# or run directly:
|
|
57
|
+
node mbflash.mjs --help
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The package has no runtime dependencies and requires Node.js **22.4+**.
|
|
61
|
+
|
|
62
|
+
## Modes
|
|
63
|
+
|
|
64
|
+
| Command | What it does |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `mbflash main.ts` | load → Blocks → build → flash |
|
|
67
|
+
| `mbflash --load-only main.ts` | load → Blocks (no build/flash) |
|
|
68
|
+
| `mbflash --hex-only main.ts` | load → Blocks → build/download (no flash) |
|
|
69
|
+
| `mbflash --hex-only` | build/download the code already in the editor |
|
|
70
|
+
| `mbflash --flash-only` | build/flash the code already in the editor |
|
|
71
|
+
| `mbflash --flash-hex demo.hex` | flash an existing `.hex` (no CDP) |
|
|
72
|
+
| `mbflash --project Test1 --switch` | focus the Test1 project (no build) |
|
|
73
|
+
|
|
74
|
+
`--hex-only` with no file is useful when a human has edited Blocks and you just
|
|
75
|
+
want a `.hex`. `--flash-only` skips loading but still builds. `--switch` is the
|
|
76
|
+
tab manager: select by **project name** or target and bring it to the front.
|
|
77
|
+
|
|
78
|
+
If `--project` does not match an existing tab, `mbflash` creates a new project
|
|
79
|
+
with that name by driving the home page’s **New Project** dialog (open the home
|
|
80
|
+
tab, fill `#projectNameInput`, click **Create**, wait for the editor). Use
|
|
81
|
+
`--no-create` to make a missing project an error instead. Creation adds about
|
|
82
|
+
2–3 s.
|
|
83
|
+
|
|
84
|
+
## Multiple tabs / projects
|
|
85
|
+
|
|
86
|
+
All MakeCode tabs have the same URL and title. `mbflash` identifies them by
|
|
87
|
+
**CDP target id** and the **MakeCode project name** — the project header /
|
|
88
|
+
`pxt.json` name, read from the editor’s project-name field. No sidecar metadata
|
|
89
|
+
is written, and the tab title is not used for matching.
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
mbflash --list # ids, project names, URLs
|
|
93
|
+
mbflash --project Test1 --switch # focus Test1, no build
|
|
94
|
+
mbflash --project Test1 main.ts # load/build/flash Test1 only
|
|
95
|
+
mbflash --project Test2 --hex-only # build Test2's current code
|
|
96
|
+
mbflash --project Test3 main.ts # create Test3 if missing
|
|
97
|
+
mbflash --project Test3 --switch # create + focus an empty Test3
|
|
98
|
+
mbflash --label Test1 --switch # deprecated alias for --project
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Project names are what MakeCode stores (`pxt.json` `"name"`, and the workspace
|
|
102
|
+
header / `headers.name` in IndexedDB when persistent). In this session-only
|
|
103
|
+
profile the header lives in renderer memory, so `mbflash` reads the editor’s
|
|
104
|
+
project-name field. The tab title is cosmetic; add `--retitle` if you also want
|
|
105
|
+
the visible title changed to `MakeCode — <project>`.
|
|
106
|
+
|
|
107
|
+
If `--project` is missing, `mbflash` creates the project through the home page’s
|
|
108
|
+
New Project dialog (same tab, then `#editor`) and the new project is named after
|
|
109
|
+
`--project`. `--no-create` turns a missing project into an error.
|
|
110
|
+
|
|
111
|
+
Duplicate project names: select a specific tab with `--target <id>` or
|
|
112
|
+
`--index <n>`.
|
|
113
|
+
|
|
114
|
+
Practical notes for multiple projects:
|
|
115
|
+
|
|
116
|
+
- Work one at a time. `mbflash` brings the selected tab to the front by default
|
|
117
|
+
(hidden tabs are throttled by Chromium); `--no-focus` skips that.
|
|
118
|
+
- A shared `--download-dir` is fine: MakeCode names the `.hex` after the project
|
|
119
|
+
(`microbit-Test1.hex`, `microbit-Test2.hex`), so sequential builds keep
|
|
120
|
+
distinct files.
|
|
121
|
+
- On this profile the MakeCode workspace is **session-only**: each tab's project
|
|
122
|
+
lives in renderer memory and is lost on reload. Keep `main.ts` on disk.
|
|
123
|
+
- The tabs share origin storage (`localStorage`), but their in-memory projects
|
|
124
|
+
are independent. If you sign in or enable persistent workspaces, keep to one
|
|
125
|
+
tab per project and verify that the IDB workspace is not being shared.
|
|
126
|
+
- Only one board mount is used by default. For multiple boards, pass a different
|
|
127
|
+
`--device` per project.
|
|
128
|
+
|
|
129
|
+
## Options
|
|
130
|
+
|
|
131
|
+
### Target
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
mbflash --cdp 9222 main.ts # default 127.0.0.1:9222
|
|
135
|
+
mbflash --cdp 192.168.1.50:9222 main.ts # remote Chromium
|
|
136
|
+
mbflash --list # show page targets
|
|
137
|
+
mbflash --target ABCD1234 main.ts # exact page id
|
|
138
|
+
mbflash --index 2 main.ts # second match
|
|
139
|
+
mbflash --url makecode main.ts # URL substring or /regex/
|
|
140
|
+
mbflash --title "MakeCode" main.ts # title substring
|
|
141
|
+
mbflash --host makecode.microbit.org main.ts
|
|
142
|
+
mbflash --label Test1 --switch # deprecated alias for --project
|
|
143
|
+
mbflash --project Test1 --switch # focus a project tab
|
|
144
|
+
mbflash --project Test1 --switch --retitle # focus + set the visible title
|
|
145
|
+
mbflash --project Test3 main.ts # create Test3 if missing
|
|
146
|
+
mbflash --label NoSuch --switch --no-create # error instead of creating
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The default tab match is the exact hostname `makecode.microbit.org`. If more
|
|
150
|
+
than one tab matches (or two tabs have the same project name), the command
|
|
151
|
+
fails and lists them; pick one with `--target` or `--index`.
|
|
152
|
+
|
|
153
|
+
### Output / device
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
mbflash --download-dir ./build main.ts # where Chromium writes the .hex
|
|
157
|
+
mbflash --hex-out ./demo.hex main.ts # copy the built hex here
|
|
158
|
+
mbflash --device /run/media/$USER/MICROBIT main.ts
|
|
159
|
+
mbflash --wait 90 main.ts # flash timeout (s)
|
|
160
|
+
mbflash --timeout 180 main.ts # build/download timeout (s)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`--download-dir` defaults to `$XDG_CACHE_HOME/mbflash/hex` (usually
|
|
164
|
+
`~/.cache/mbflash/hex`). The new `.hex` is detected without deleting anything
|
|
165
|
+
already in that folder. `--hex-out` can be a file or an existing directory.
|
|
166
|
+
|
|
167
|
+
### Loading
|
|
168
|
+
|
|
169
|
+
```sh
|
|
170
|
+
mbflash --no-blocks main.ts # load TS only, do not rebuild Blocks
|
|
171
|
+
mbflash --roundtrip main.ts # JS -> Blocks -> JS sanity check
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`--roundtrip` catches icon/enum loss from the TS → Blocks conversion; a
|
|
175
|
+
textual difference is reported as a warning (harmless reformatting is common).
|
|
176
|
+
|
|
177
|
+
### Automation
|
|
178
|
+
|
|
179
|
+
```sh
|
|
180
|
+
mbflash --json --hex-only main.ts
|
|
181
|
+
mbflash --quiet main.ts # print only the hex path (or "ok")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
`--json` prints a single object on stdout with `ok`, `mode`, `hex`, `device`,
|
|
185
|
+
`markers`, `blocks`, `roundtrip`, `warnings`, and `timings`. On failure it
|
|
186
|
+
prints `{ "ok": false, "error": "...", "timings": ... }` and exits non-zero.
|
|
187
|
+
|
|
188
|
+
## Examples
|
|
189
|
+
|
|
190
|
+
```sh
|
|
191
|
+
# Normal development loop
|
|
192
|
+
mbflash main.ts
|
|
193
|
+
|
|
194
|
+
# Only check that the Blocks conversion works
|
|
195
|
+
mbflash --load-only main.ts
|
|
196
|
+
|
|
197
|
+
# Build a hex for someone else, no board attached
|
|
198
|
+
mbflash --hex-only --hex-out ./release.hex main.ts
|
|
199
|
+
|
|
200
|
+
# Reflash whatever the human has open in Blocks
|
|
201
|
+
mbflash --flash-only
|
|
202
|
+
|
|
203
|
+
# Flash a prebuilt artifact on a machine without a browser
|
|
204
|
+
mbflash --flash-hex ./release.hex --device /run/media/$USER/MICROBIT
|
|
205
|
+
|
|
206
|
+
# A second Chromium on another port
|
|
207
|
+
mbflash --cdp 127.0.0.1:9333 --target <id> main.ts
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Notes
|
|
211
|
+
|
|
212
|
+
- **Multiple tabs.** Tabs share an origin and can share persistent storage. On
|
|
213
|
+
a session-only workspace each tab has its own in-memory project, and
|
|
214
|
+
`mbflash` can address them with `--project`/`--target`. With persistent
|
|
215
|
+
workspaces, avoid opening the same project in two tabs; edit one project per
|
|
216
|
+
tab.
|
|
217
|
+
- **Session-only projects.** Some profiles keep the project only in page
|
|
218
|
+
memory. The CLI still works, but the project is lost on reload; keep the
|
|
219
|
+
`main.ts` and `.hex` on disk.
|
|
220
|
+
- **V1 vs V2.** The CLI flashes what you give it. V2-only APIs (logo touch,
|
|
221
|
+
`input.soundLevel`, audio) compile for a V1 board and then panic with code
|
|
222
|
+
**927** at boot. Check the board version before using those APIs.
|
|
223
|
+
- **Narrow windows.** MakeCode hides the Download control in its mobile
|
|
224
|
+
layout. The CLI temporarily emulates a 1400×900 viewport to reach the menu,
|
|
225
|
+
then clears the override.
|
|
226
|
+
- **Flashing** copies the `.hex` to the DAPLink volume and treats “volume
|
|
227
|
+
remounted, hex gone, no `FAIL.TXT`” as success. The copy of the ~1.3 MB
|
|
228
|
+
universal hex is usually the slowest part (~9 s); the flash itself is a few
|
|
229
|
+
seconds.
|
|
230
|
+
- **Typical full run** on a demo-sized project: ~2 s load + Blocks, ~4 s build,
|
|
231
|
+
~15 s flash command (copy + flash), ~21 s total.
|
|
232
|
+
- The downloaded filename follows the MakeCode project name; use `--hex-out`
|
|
233
|
+
to give it the name you want.
|
|
234
|
+
- **Not a simulator driver.** Like the skill, this tool does not verify
|
|
235
|
+
behaviour in the simulator; the human watches the board.
|
|
236
|
+
|
|
237
|
+
## Development
|
|
238
|
+
|
|
239
|
+
```sh
|
|
240
|
+
npm test # CLI tests; no browser or board required
|
|
241
|
+
npm run lint # node --check
|
|
242
|
+
npm pack --dry-run # inspect the npm package contents
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The test suite covers argument parsing, project/title semantics, and hex
|
|
246
|
+
validation. Browser/CDP loading and flashing require a real MakeCode tab and a
|
|
247
|
+
mounted micro:bit.
|
|
248
|
+
|
|
249
|
+
## Publishing
|
|
250
|
+
|
|
251
|
+
This repository is <https://github.com/tai/mbflash>.
|
|
252
|
+
|
|
253
|
+
```sh
|
|
254
|
+
npm test
|
|
255
|
+
npm publish
|
|
256
|
+
git tag v1.2.0 # use the new version
|
|
257
|
+
git push origin main --tags
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The `Publish npm` workflow runs on a published GitHub release (or manually). It
|
|
261
|
+
skips publishing when the version already exists on npm; otherwise it expects an
|
|
262
|
+
`NPM_TOKEN` repository secret. Keep the repository public for npm provenance. `npm pack --dry-run` shows exactly what would be published:
|
|
263
|
+
`mbflash.mjs`, `README.md`, `LICENSE`, and `package.json`.
|