@rom-weaver/cli 0.11.0 → 0.12.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 CHANGED
@@ -7,7 +7,7 @@
7
7
  <p align="center">
8
8
  <a href="https://www.npmjs.com/package/rom-weaver"><img alt="npm version" src="https://img.shields.io/npm/v/rom-weaver?logo=npm&amp;logoColor=white&amp;label=npm&amp;color=d9690f"></a>
9
9
  <a href="https://crates.io/crates/rom-weaver-cli"><img alt="crates.io version" src="https://img.shields.io/crates/v/rom-weaver-cli?logo=rust&amp;logoColor=white&amp;label=crates.io&amp;color=d9690f"></a>
10
- <a href="https://github.com/users/brandonocasey/packages/container/package/rom-weaver-cli"><img alt="Container images on GitHub Container Registry" src="https://img.shields.io/badge/ghcr.io-rom--weaver-d9690f?logo=docker&amp;logoColor=white"></a>
10
+ <a href="https://github.com/orgs/rom-weaver/packages/container/package/rom-weaver-cli"><img alt="Container images on GitHub Container Registry" src="https://img.shields.io/badge/ghcr.io-rom--weaver-d9690f?logo=docker&amp;logoColor=white"></a>
11
11
  <a href="https://github.com/rom-weaver/homebrew-tap"><img alt="Homebrew tap" src="https://img.shields.io/badge/homebrew-rom--weaver%2Ftap-d9690f?logo=homebrew&amp;logoColor=white"></a>
12
12
  </p>
13
13
 
@@ -20,18 +20,20 @@
20
20
 
21
21
  <p align="center">
22
22
  <a href="https://rom-weaver.com/apply">Open the webapp</a>
23
- · <a href="docs/README.md">Docs index</a>
24
23
  · <a href="https://github.com/sponsors/brandonocasey">Sponsor on GitHub</a>
25
24
  · <a href="https://ko-fi.com/brandonocasey">Support on Ko-fi</a>
26
25
  </p>
27
26
 
28
27
  <!-- START doctoc -->
29
28
 
29
+ - [Install](#install)
30
+ - [Webapp](#webapp)
31
+ - [Self-hosting](#self-hosting)
32
+ - [CLI](#cli)
30
33
  - [Why](#why)
31
34
  - [Performance](#performance)
32
35
  - [Features](#features)
33
36
  - [Notices](#notices)
34
- - [Install](#install)
35
37
  - [Screenshots](#screenshots)
36
38
  - [Documentation](#documentation)
37
39
  - [Contributing and support](#contributing-and-support)
@@ -39,145 +41,31 @@
39
41
 
40
42
  <!-- END doctoc -->
41
43
 
42
- ## Why
43
-
44
- Every console generation brought its own compressed format, and each one came
45
- with its own tool. CHD for discs, RVZ for GameCube and Wii, Z3DS for 3DS, CSO
46
- and PBP for PSP, plus the usual ZIP and 7z on top. Those tools are scattered
47
- across projects, most are command-line only, and plenty of them only ship
48
- builds for one or two platforms. If you are on a Mac, or on Windows without a
49
- compiler handy, half of them are out of reach. Anyone who has tried to shrink a
50
- disc collection knows the routine: track down five programs, learn five sets of
51
- flags, and hope each one still builds.
52
-
53
- Patching has the same problem from a different angle. Most patchers take one
54
- patch at a time, so a translation plus a bugfix plus an undub means running the
55
- tool three times and keeping the intermediate files straight yourself. And
56
- because almost no patcher reads compressed input, the real sequence is
57
- decompress, patch, recompress - every time you want to try a different patch or
58
- redo one you already applied. That is a lot of disk churn and waiting for what
59
- should be a single step.
60
-
61
- The last piece is curation. Keeping a collection in order means storing ROMs
62
- compressed, keeping the patches next to them, and being able to prove months
63
- later that a patched file came from the ROM you think it did. rom-weaver
64
- handles all of it in one place: read and write every format above, chain as
65
- many patches as you want in a single pass without unpacking to disk first, and
66
- record the whole recipe - patch order, checksums, output names - in a bundle
67
- file you can hand to someone else. It runs the same on Linux, macOS, and
68
- Windows, and in the browser if you would rather not install anything.
69
-
70
- For the current measurements and trade-offs, see the [performance brief](#performance).
71
-
72
- ## Performance
73
-
74
- rom-weaver uses the same Rust engine in the CLI and threaded WASM webapp. In a
75
- representative 128 MiB GameCube ISO test, native RVZ compression completed in
76
- about 93 ms with four threads. The browser build completed the same operation
77
- in about 221 ms with one thread; four-thread RVZ creation is currently limited
78
- by a browser/OPFS threaded-I/O issue, so these numbers are not apples-to-apples.
79
-
80
- Production WASM runs `wasm-opt -O4`. In matched artifact measurements, that
81
- reduced the raw Wasm from 7.12 MB to 6.44 MB and the Brotli transfer size from
82
- 1.73 MB to 1.71 MB. The full browser codec matrix remains the source of truth
83
- for runtime comparisons, so these figures are indicative rather than a
84
- general speed claim.
85
-
86
- ## Features
87
-
88
- - **Apply and create patches.** Twenty-one formats, including IPS, BPS, UPS,
89
- xdelta/VCDIFF, PPF, RUP, BDF/BSDIFF40, APS, and DCP (Dreamcast), with ordered
90
- multi-patch chains, strict checksum validation, and cheat-code baking. Three
91
- of them (DCP, BSP, and HDiffPatch) can only be applied, not created.
92
- - **Inspect and extract containers.** ZIP, 7z, RAR, the tar family, CHD, RVZ,
93
- Z3DS, CSO, PBP, GCZ, WIA, WBFS, and more, including nested archives.
94
- - **Create compressed containers.** ZIP, 7z, CHD, RVZ, and Z3DS with
95
- codec-aware compression settings, validated against reference tools such as
96
- chdman and dolphin-tool.
97
- - **Checksum and verify.** CRC32, MD5, SHA-1, SHA-256, BLAKE3, and friends,
98
- with copier-header detection, header repair, and header-aware checksum
99
- variants.
100
- - **Trim and restore.** Trimming for NDS, GBA, 3DS, XISO, and RVZ scrub. NDS,
101
- GBA, and 3DS can be reverted, with an opt-in footer that restores the
102
- original file byte-for-byte.
103
- - **Share workflows.** Distributable [`rom-weaver-bundle.json`](./docs/rom-weaver-bundle-v1.schema.json)
104
- bundles pin patch order, checksums, and output naming so others can replay
105
- the exact workflow.
106
- - **Local-first and private.** Everything runs on your machine. The webapp is
107
- an installable PWA that works offline and never uploads your files.
108
- - **One engine, two frontends.** The same Rust core powers the terminal CLI
109
- and the threaded WASM webapp, with line-delimited JSON output for scripting.
110
-
111
- The complete format, codec, and checksum compatibility tables are maintained
112
- in the [CLI guide](./docs/reference/formats.md).
113
-
114
- ## Notices
115
-
116
- ### Beta status
117
-
118
- rom-weaver is beta software and follows Semantic Versioning, but until v1.0,
119
- breaking changes may still happen between minor releases. Patching,
120
- compressing, extracting, and bundling have all been tested extensively. That
121
- hands-on testing happens on macOS and Linux; Windows runs the same automated
122
- test suite in CI but has seen much less real-world use, so expect rougher
123
- edges there and please report anything Windows-specific. If you
124
- rely on the APIs or CLI flags, expect things to be a bit tougher: those
125
- interfaces may still change as the project heads toward v1.0. Trim and Tools are
126
- currently untested but theoretically working, so they are disabled in the
127
- current webapp. The `rom-weaver-core`, `-checksum`, `-containers`, and
128
- `-patches` crates are published to crates.io only so `rom-weaver-cli` can use
129
- them. The CLI and the webapp are the supported interfaces; using those crates as
130
- libraries in another project is not supported.
131
-
132
- ### First public release
133
-
134
- v0.7.2 is the first public version to install. The changelog and the git
135
- history go back further, but v0.6.0 through v0.7.1 failed partway through the
136
- release pipeline or were only partially published. v0.7.1 completed most of
137
- the pipeline, but it still missed the crates.io CLI package, shipped a broken
138
- unscoped npm launcher, and built the static webapp archive with mismatched
139
- release metadata. v0.7.2 is the first release intended to have all public
140
- install methods working together. Earlier version numbers describe development
141
- history or incomplete releases only.
142
-
143
- ### LLM-assisted development
144
-
145
- rom-weaver is built by a full-time software engineer in my spare time. Claude
146
- and ChatGPT are used during development for brainstorming, implementation,
147
- debugging, and review. I make the engineering decisions and review and test
148
- the resulting work myself; the goal is high-quality, dependable software, but
149
- AI-assisted code may still need extra scrutiny.
150
-
151
- ### Translations
152
-
153
- Localized translations are early and may be entirely wrong in places. Manual
154
- edits and corrections are welcome.
155
-
156
44
  ## Install
157
45
 
158
- ### Webapp
46
+ Choose the [webapp](#webapp), [self-hosting](#self-hosting), or [CLI](#cli)
47
+ path below.
48
+
49
+ ## Webapp
159
50
 
160
51
  Open the hosted webapp at **[rom-weaver.com/apply](https://rom-weaver.com/apply)**. You
161
- do not need to install anything or create an account. Choose **Weave**, add a
52
+ do not need to install anything or create an account. Choose **Apply**, add a
162
53
  ROM and one or more patches, review the detected formats and checksums, then run
163
54
  the workflow and save the result. Use **Create** to generate a distributable
164
55
  patch from an original and a modified file. Your files are processed locally
165
56
  and never leave the device. Install it as a PWA from the browser menu to use it
166
57
  offline.
167
- New here? [Try the sample weave](https://rom-weaver.com/apply?bundle=first-weave.zip)
58
+ New here? [Try the sample workflow](https://rom-weaver.com/apply?bundle=first-weave.zip)
168
59
  with a tiny original homebrew NES ROM and two patches that change “HELLO WORLD” to “MODIFIED ROM.”
169
60
  For a guided explanation, use
170
61
  [guided Apply](https://rom-weaver.com/apply?guide=apply),
171
62
  [guided Create](https://rom-weaver.com/create?guide=create), or
172
63
  [guided Bundle](https://rom-weaver.com/apply?guide=bundle).
173
64
  To run the webapp on your own host, see the
174
- [self-hosting guide](./docs/hosting/self-hosting.md) for the release tarball,
175
- Docker, and Docker Compose setups.
65
+ [Self-hosting](#self-hosting) section below or the
66
+ [full self-hosting guide](./docs/hosting/self-hosting.md).
176
67
 
177
- <a name="self-host-the-webapp"></a>
178
-
179
- <details>
180
- <summary>Self-host the webapp</summary>
68
+ ## Self-hosting
181
69
 
182
70
  For a quick setup, choose static files, Docker Run, or Docker Compose. The
183
71
  [full self-hosting guide](./docs/hosting/self-hosting.md) covers reverse proxies,
@@ -197,36 +85,42 @@ tar --extract --gzip --file rom-weaver-webapp.tar.gz --directory rom-weaver-weba
197
85
  Serve the extracted `rom-weaver-webapp` directory from an HTTPS static host.
198
86
  For a pinned release, replace `latest` in the URL with its tag.
199
87
 
200
- Docker Run:
88
+ Docker Run using the published GitHub Container Registry (GHCR) image:
201
89
 
202
90
  ```bash
203
91
  docker run --detach --name rom-weaver-webapp \
204
92
  --publish 8080:8080 \
205
- ghcr.io/brandonocasey/rom-weaver-webapp:latest
93
+ ghcr.io/rom-weaver/rom-weaver-webapp:latest
206
94
  ```
207
95
 
208
- Docker Compose, building from source:
96
+ Docker Compose using the same published GitHub Container Registry (GHCR) image:
97
+ Download the [Docker Compose template](https://github.com/rom-weaver/rom-weaver/blob/main/docker-compose.yml)
98
+ into a new directory:
209
99
 
210
100
  ```bash
211
- git clone https://github.com/rom-weaver/rom-weaver.git
212
- cd rom-weaver
213
- docker compose up --build --detach
101
+ mkdir -p rom-weaver-compose
102
+ cd rom-weaver-compose
103
+ curl --fail --location --proto '=https' --tlsv1.2 \
104
+ --output docker-compose.yml \
105
+ https://raw.githubusercontent.com/rom-weaver/rom-weaver/main/docker-compose.yml
106
+ docker compose pull
107
+ docker compose up --detach
214
108
  curl --fail --silent --show-error http://localhost:8080/health
215
109
  ```
216
110
 
217
- Only Docker with Compose is required; the image installs its own build
218
- toolchains. Set `PORT` to change the host port, for example
219
- `PORT=3000 docker compose up --build --detach`.
111
+ Only Docker with Compose is required. Set `PORT` to change the host port, for
112
+ example `PORT=3000 docker compose up --detach`. To build the image from source
113
+ instead, clone the repository and add `--build` to the `docker compose up`
114
+ command from its checkout; that path is slower and intended for development.
220
115
  For standalone TLS, mount a trusted certificate as described in the guide and
221
116
  set `HTTPS_PORT` instead.
222
117
 
223
- </details>
224
-
225
- ### CLI
118
+ ## CLI
226
119
 
227
- Every method below installs the same prebuilt binary from the GitHub release.
228
- The release covers macOS arm64 and x86-64; Linux x86-64 GNU plus x86-64,
229
- arm64, and i686 musl; and Windows arm64, x86-64, and x86.
120
+ Native release assets cover macOS arm64 and x86-64; Linux x86-64 GNU plus
121
+ x86-64, arm64, and i686 musl; and Windows arm64, x86-64, and x86. The package
122
+ manager and installer options below select the matching asset unless their
123
+ description says otherwise.
230
124
 
231
125
  <details>
232
126
  <summary>Homebrew (macOS arm64/Intel, Linux arm64/x86-64)</summary>
@@ -250,7 +144,8 @@ scoop install rom-weaver
250
144
  <details>
251
145
  <summary>Install script (macOS, Linux)</summary>
252
146
 
253
- Downloads the latest release to `~/.local/bin` and verifies its checksum.
147
+ Downloads the latest release to `~/.local/bin` and checks its GitHub build
148
+ attestation.
254
149
  Override with `ROM_WEAVER_INSTALL_DIR` or pin with `ROM_WEAVER_VERSION`.
255
150
  The script also installs manpages and shell completions for the current user.
256
151
 
@@ -298,8 +193,7 @@ npm install --save-dev @rom-weaver/cli
298
193
  <details>
299
194
  <summary>cargo-binstall</summary>
300
195
 
301
- Downloads the same release binary rather than compiling the workspace, so it is
302
- minutes faster than `cargo install`:
196
+ Downloads the same release binary rather than compiling the workspace:
303
197
 
304
198
  ```bash
305
199
  cargo binstall rom-weaver-cli
@@ -331,14 +225,13 @@ Runs from the published Linux image without installing anything:
331
225
  docker run --rm \
332
226
  --user "$(id -u):$(id -g)" \
333
227
  --volume "$PWD:/work" \
334
- ghcr.io/brandonocasey/rom-weaver-cli:latest \
228
+ ghcr.io/rom-weaver/rom-weaver-cli:latest \
335
229
  probe --input /work/game.iso
336
230
  ```
337
231
 
338
- Mount your ROM directory at `/work` and pass paths under it. `--user` matters:
339
- bind-mounted files keep their host ownership, so without it the container cannot
340
- read files it does not own and leaves anything it writes owned by an unknown uid.
341
- See [Run in Docker](./docs/cli/install.md#run-in-docker).
232
+ Mount your ROM directory at `/work` and pass paths under it. On Linux and
233
+ macOS, `--user` keeps files created in the bind mount owned by your host user.
234
+ See [Run in Docker](./docs/how-to/install-cli.md#run-in-docker).
342
235
 
343
236
  </details>
344
237
 
@@ -360,11 +253,120 @@ toolchain.
360
253
  </details>
361
254
 
362
255
  Hitting `Permission denied`? See
363
- [File permissions](./docs/cli/reference.md#file-permissions).
256
+ [File permissions](./docs/reference/cli.md#file-permissions).
364
257
 
365
258
  The [development guide](./docs/development/development.md) covers the full toolchain setup,
366
259
  webapp builds, and tests.
367
260
 
261
+ ## Why
262
+
263
+ Every console generation brought its own compressed format: CHD for discs, RVZ
264
+ for GameCube and Wii, Z3DS for 3DS ROMs, CSO and PBP for PSP, plus the usual ZIP
265
+ and 7z on top. Working across them can mean finding several separate programs,
266
+ learning different flags, and checking which builds are available for your
267
+ platform.
268
+
269
+ Patching adds another manual sequence. A translation, bugfix, and undub may
270
+ need to run in a specific order, with intermediate files kept straight and a
271
+ compressed input unpacked before the first patch and recompressed afterward.
272
+ Repeating that setup whenever the patch combination changes adds disk churn and
273
+ room for mistakes to what should be one workflow.
274
+
275
+ The last piece is curation. Keeping a collection in order means storing ROMs
276
+ compressed, keeping the patches next to them, and being able to prove months
277
+ later that a patched file came from the ROM you think it did. rom-weaver
278
+ handles all of it in one place. It reads every format above. It writes CHD, RVZ,
279
+ Z3DS, ZIP, and 7z archives. It chains as many patches as you want in a single pass
280
+ without manually unpacking first, and records the whole recipe - patch order,
281
+ checksums, and output names - in a bundle file you can hand to someone else.
282
+ Native CLI builds are
283
+ available for Linux, macOS, and Windows. The browser webapp handles patching
284
+ and bundle workflows without an install.
285
+
286
+ For the current measurements and trade-offs, see the [performance brief](#performance).
287
+
288
+ ## Performance
289
+
290
+ rom-weaver uses the same Rust engine in the CLI and threaded WASM webapp, but
291
+ browser worker, storage, and OPFS costs make cross-frontend timing comparisons
292
+ misleading. The [performance guide](./docs/development/performance.md) records
293
+ the machine, corpus, settings, reference-tool versions, and repeated runs for
294
+ each published result, and includes the commands needed to reproduce them.
295
+ Production WASM is optimized with `wasm-opt -O4`; the browser codec matrix is
296
+ the runtime check for the shipped worker and storage path.
297
+
298
+ ## Features
299
+
300
+ - **Apply and create patches.** Twenty-one formats, including IPS, BPS, UPS,
301
+ xdelta/VCDIFF, PPF, RUP, BDF/BSDIFF40, APS, and DCP (Dreamcast), with ordered
302
+ multi-patch chains, checksum validation when the format or bundle supplies
303
+ expected values, and cheat-code baking. Three of them (DCP, BSP, and
304
+ HDiffPatch) can only be applied, not created.
305
+ - **Inspect and extract containers.** ZIP, 7z, RAR, the tar family, CHD, RVZ,
306
+ Z3DS, CSO, PBP, GCZ, WIA, WBFS, and more, including nested archives.
307
+ - **Create format-specific compressed containers.** ZIP, 7z, CHD, RVZ, and Z3DS with
308
+ codec-aware compression settings. CHD and RVZ outputs are checked for
309
+ round-trip compatibility with chdman and dolphin-tool.
310
+ - **Checksum and verify.** CRC32, MD5, SHA-1, SHA-256, BLAKE3, and friends,
311
+ with copier-header detection, header repair, and header-aware checksum
312
+ variants.
313
+ - **Trim and restore.** Trimming for NDS, GBA, 3DS, XISO, and RVZ scrub. NDS,
314
+ GBA, and 3DS can be reverted, with an opt-in footer that restores the
315
+ original file byte-for-byte.
316
+ - **Share workflows.** Distributable [`rom-weaver-bundle.json`](./docs/rom-weaver-bundle-v1.schema.json)
317
+ bundles pin patch order, checksums, and output naming so others can replay
318
+ the exact workflow.
319
+ - **Local-first and private.** Everything runs on your machine. The webapp is
320
+ an installable PWA that works offline and never uploads your files.
321
+ - **One engine, two frontends.** The same Rust core powers the terminal CLI
322
+ and the threaded WASM webapp. CLI operation commands can emit line-delimited
323
+ JSON for scripting.
324
+
325
+ The complete format, codec, and checksum compatibility tables are maintained
326
+ in the [CLI guide](./docs/reference/formats.md).
327
+
328
+ ## Notices
329
+
330
+ ### Beta status
331
+
332
+ rom-weaver is beta software and follows Semantic Versioning, but until v1.0,
333
+ breaking changes may still happen between minor releases. Patching,
334
+ compressing, extracting, and bundling are covered by automated tests. Hands-on
335
+ testing happens on macOS and Linux; Windows is covered by hosted CI but has seen
336
+ much less real-world use, so expect rougher edges there and please report
337
+ anything Windows-specific. If you
338
+ rely on the APIs or CLI flags, expect things to be a bit tougher: those
339
+ interfaces may still change as the project heads toward v1.0. Trim and Tools are
340
+ still beta, so they are disabled by default in the webapp and can be enabled in
341
+ Settings. The `rom-weaver-core`, `-checksum`, `-containers`, and
342
+ `-patches` crates are published to crates.io only so `rom-weaver-cli` can use
343
+ them. The CLI and the webapp are the supported interfaces; using those crates as
344
+ libraries in another project is not supported.
345
+
346
+ ### First complete public release
347
+
348
+ v0.7.2 was the first complete public release. The changelog and the git
349
+ history go back further, but v0.6.0 through v0.7.1 failed partway through the
350
+ release pipeline or were only partially published. v0.7.1 completed most of
351
+ the pipeline, but it still missed the crates.io CLI package, shipped a broken
352
+ unscoped npm launcher, and built the static webapp archive with mismatched
353
+ release metadata. Starting with v0.7.2, all public install methods were intended
354
+ to work together. Install commands below resolve the current release unless you
355
+ explicitly pin a version.
356
+
357
+ ### LLM-assisted development
358
+
359
+ rom-weaver is built by a full-time software engineer in my spare time. Claude
360
+ and ChatGPT are used during development for brainstorming, implementation,
361
+ debugging, and review. I make the engineering decisions and review and test
362
+ the resulting work myself; the goal is high-quality, dependable software, but
363
+ AI-assisted code may still need extra scrutiny.
364
+
365
+ ### Translations
366
+
367
+ Localized translations are early and may be entirely wrong in places. Manual
368
+ edits and corrections are welcome.
369
+
368
370
  ## Screenshots
369
371
 
370
372
  [View every screenshot at full size.](./docs/development/screenshots.md)
@@ -381,8 +383,8 @@ webapp builds, and tests.
381
383
  <td>Desktop: ordered patch stack</td>
382
384
  <td>
383
385
  <picture>
384
- <source media="(prefers-color-scheme: dark)" srcset="packages/rom-weaver-webapp/design/apply-patches-desktop-dark.webp">
385
- <img src="packages/rom-weaver-webapp/design/apply-patches-desktop-light.webp" alt="Focused Weave patch stack with two ordered sample patches on desktop">
386
+ <source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/apply-patches-desktop-dark.webp">
387
+ <img src="docs/screenshots/apply-patches-desktop-light.webp" alt="Focused Apply patch stack with two ordered sample patches on desktop">
386
388
  </picture>
387
389
  </td>
388
390
  </tr>
@@ -390,8 +392,8 @@ webapp builds, and tests.
390
392
  <td>Desktop: create output</td>
391
393
  <td>
392
394
  <picture>
393
- <source media="(prefers-color-scheme: dark)" srcset="packages/rom-weaver-webapp/design/create-output-desktop-dark.webp">
394
- <img src="packages/rom-weaver-webapp/design/create-output-desktop-light.webp" alt="Focused Create output card with BPS selected on desktop">
395
+ <source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/create-output-desktop-dark.webp">
396
+ <img src="docs/screenshots/create-output-desktop-light.webp" alt="Focused Create output card with BPS selected on desktop">
395
397
  </picture>
396
398
  </td>
397
399
  </tr>
@@ -399,8 +401,8 @@ webapp builds, and tests.
399
401
  <td>Mobile: Original and Modified</td>
400
402
  <td align="center">
401
403
  <picture>
402
- <source media="(prefers-color-scheme: dark)" srcset="packages/rom-weaver-webapp/design/create-inputs-mobile-dark.webp">
403
- <img src="packages/rom-weaver-webapp/design/create-inputs-mobile-light.webp" alt="Focused Create Original and Modified cards on mobile" width="390">
404
+ <source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/create-inputs-mobile-dark.webp">
405
+ <img src="docs/screenshots/create-inputs-mobile-light.webp" alt="Focused Create Original and Modified cards on mobile" width="390">
404
406
  </picture>
405
407
  </td>
406
408
  </tr>
@@ -408,8 +410,8 @@ webapp builds, and tests.
408
410
  <td>Mobile: bundle output options</td>
409
411
  <td align="center">
410
412
  <picture>
411
- <source media="(prefers-color-scheme: dark)" srcset="packages/rom-weaver-webapp/design/bundle-output-mobile-dark.webp">
412
- <img src="packages/rom-weaver-webapp/design/bundle-output-mobile-light.webp" alt="Focused patch-only bundle controls on mobile" width="390">
413
+ <source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/bundle-output-mobile-dark.webp">
414
+ <img src="docs/screenshots/bundle-output-mobile-light.webp" alt="Focused patch-only bundle controls on mobile" width="390">
413
415
  </picture>
414
416
  </td>
415
417
  </tr>
@@ -421,7 +423,7 @@ webapp builds, and tests.
421
423
  Start with the browser-first [documentation home](https://rom-weaver.com/docs)
422
424
  or the repository [documentation index](./docs/README.md). The web docs include
423
425
  a task and tool picker, guided samples, focused screenshots, and a
424
- [FAQ](./docs/usage/faq.md). CLI, deployment, integration, development,
426
+ [FAQ](./docs/faq.md). CLI, deployment, integration, development,
425
427
  architecture, and format references each have their own guides.
426
428
 
427
429
  ## Contributing and support
@@ -430,10 +432,10 @@ Bug reports and contributions are welcome. Read the
430
432
  [contribution guide](CONTRIBUTING.md) and [code of conduct](.github/CODE_OF_CONDUCT.md)
431
433
  before submitting a change. Because rom-weaver is dual-licensed, code and
432
434
  documentation changes need a one-time signature on the
433
- [Contributor License Agreement](CLA.md) - the `CLA Signed` check asks for
434
- it on your first pull request, it covers every repository in the
435
- [`rom-weaver` organization](https://github.com/rom-weaver), and you keep the
436
- copyright in your work. Report
435
+ [Contributor License Agreement](CLA.md). The `CLA Signed` check asks for
436
+ it on your first pull request. One signature covers every repository in the
437
+ [`rom-weaver` organization](https://github.com/rom-weaver) whose contribution
438
+ process references the agreement. You keep the copyright in your work. Report
437
439
  suspected vulnerabilities through GitHub's private reporting form in the
438
440
  [security policy](.github/SECURITY.md). If rom-weaver has been useful to you, you can
439
441
  support continued development through
@@ -442,7 +444,7 @@ support continued development through
442
444
 
443
445
  ## License
444
446
 
445
- Copyright (C) Brandon Casey and rom-weaver contributors
447
+ Copyright © Brandon Casey and rom-weaver contributors
446
448
 
447
449
  The public distribution is licensed under
448
450
  [AGPL-3.0-or-later](LICENSE). [Commercial licensing](COMMERCIAL.md) is
@@ -89,8 +89,8 @@ _arguments "${_arguments_options[@]}" : \
89
89
  ;;
90
90
  (extract)
91
91
  _arguments "${_arguments_options[@]}" : \
92
- '-i+[Archive or disc image to unpack]:INPUT:_files' \
93
- '--input=[Archive or disc image to unpack]:INPUT:_files' \
92
+ '-i+[Archive or single-payload compressed format to unpack]:INPUT:_files' \
93
+ '--input=[Archive or single-payload compressed format to unpack]:INPUT:_files' \
94
94
  '*-s+[Extract only these files, by exact name, prefix, or glob (repeatable). For example\: --select '\''game.disc0?.bin'\'']:SELECT:_default' \
95
95
  '*--select=[Extract only these files, by exact name, prefix, or glob (repeatable). For example\: --select '\''game.disc0?.bin'\'']:SELECT:_default' \
96
96
  '*--filter=[Extract only files that look like a rom or a patch, judged by extension (repeatable, comma-separable)]:FILTER:(rom patch)' \
@@ -518,7 +518,7 @@ _arguments "${_arguments_options[@]}" : \
518
518
  '--input=[ROM the patches apply to. Its checksums and size are read from the file and recorded in the bundle]:INPUT:_files' \
519
519
  '*--assume-in=[Take the ROM'\''s checksum and size on trust rather than reading it, as in crc32=1234abcd,size=1048576 (repeatable, comma-separable)]:ALGO=HEX:_default' \
520
520
  '--rom-url=[Where the ROM can be downloaded from. With --input, the local file still supplies the checksums; on its own, the bundle records only this url]:ROM_URL:_default' \
521
- '--rom-name=[File name to show for the ROM, and to base the output name on]:ROM_NAME:_default' \
521
+ '--rom-name=[Expected ROM file name to show and use for output naming; a supplied ROM with a different name only warns]:ROM_NAME:_default' \
522
522
  '*--patch=[Patch to list in the bundle. Repeat once per patch, in the order they should be applied]:PATCH:_files' \
523
523
  '*--patch-id=[Identifier for the preceding --patch that stays the same across releases, so a replacement keeps its settings]:PATCH_ID:_default' \
524
524
  '*--patch-version=[Version of the preceding --patch, in whatever form its author uses]:PATCH_VERSION:_default' \
@@ -949,10 +949,10 @@ _rom-weaver_commands() {
949
949
  local commands; commands=(
950
950
  'probe:Identify a file\: its format, its platform, and any header it carries' \
951
951
  'inspect:Identify a file\: its format, its platform, and any header it carries' \
952
- 'extract:Unpack an archive or disc image' \
952
+ 'extract:Unpack an archive or single-payload compressed format' \
953
953
  'checksum:Compute checksums for a file, or for a ROM inside an archive' \
954
954
  'ingest:Sort a file into ROMs and patches, unpacking and hashing along the way' \
955
- 'compress:Pack files into an archive or a compressed disc image' \
955
+ 'compress:Pack files into an archive, disc image, or ROM-specific compressed format' \
956
956
  'trim:Cut the padding off a ROM, or put it back' \
957
957
  'patch:Apply, create, or check ROM patches' \
958
958
  'bundle:Build and read rom-weaver-bundle.json patch recipes' \
@@ -1043,10 +1043,10 @@ _rom-weaver__subcmd__extract_commands() {
1043
1043
  _rom-weaver__subcmd__help_commands() {
1044
1044
  local commands; commands=(
1045
1045
  'probe:Identify a file\: its format, its platform, and any header it carries' \
1046
- 'extract:Unpack an archive or disc image' \
1046
+ 'extract:Unpack an archive or single-payload compressed format' \
1047
1047
  'checksum:Compute checksums for a file, or for a ROM inside an archive' \
1048
1048
  'ingest:Sort a file into ROMs and patches, unpacking and hashing along the way' \
1049
- 'compress:Pack files into an archive or a compressed disc image' \
1049
+ 'compress:Pack files into an archive, disc image, or ROM-specific compressed format' \
1050
1050
  'trim:Cut the padding off a ROM, or put it back' \
1051
1051
  'patch:Apply, create, or check ROM patches' \
1052
1052
  'bundle:Build and read rom-weaver-bundle.json patch recipes' \
@@ -35,10 +35,10 @@ set edit:completion:arg-completer[rom-weaver] = {|@words|
35
35
  cand --version 'Print version'
36
36
  cand probe 'Identify a file: its format, its platform, and any header it carries'
37
37
  cand inspect 'Identify a file: its format, its platform, and any header it carries'
38
- cand extract 'Unpack an archive or disc image'
38
+ cand extract 'Unpack an archive or single-payload compressed format'
39
39
  cand checksum 'Compute checksums for a file, or for a ROM inside an archive'
40
40
  cand ingest 'Sort a file into ROMs and patches, unpacking and hashing along the way'
41
- cand compress 'Pack files into an archive or a compressed disc image'
41
+ cand compress 'Pack files into an archive, disc image, or ROM-specific compressed format'
42
42
  cand trim 'Cut the padding off a ROM, or put it back'
43
43
  cand patch 'Apply, create, or check ROM patches'
44
44
  cand bundle 'Build and read rom-weaver-bundle.json patch recipes'
@@ -93,8 +93,8 @@ set edit:completion:arg-completer[rom-weaver] = {|@words|
93
93
  cand --help 'Print help (see more with ''--help'')'
94
94
  }
95
95
  &'rom-weaver;extract'= {
96
- cand -i 'Archive or disc image to unpack'
97
- cand --input 'Archive or disc image to unpack'
96
+ cand -i 'Archive or single-payload compressed format to unpack'
97
+ cand --input 'Archive or single-payload compressed format to unpack'
98
98
  cand -s 'Extract only these files, by exact name, prefix, or glob (repeatable). For example: --select ''game.disc0?.bin'''
99
99
  cand --select 'Extract only these files, by exact name, prefix, or glob (repeatable). For example: --select ''game.disc0?.bin'''
100
100
  cand --filter 'Extract only files that look like a rom or a patch, judged by extension (repeatable, comma-separable)'
@@ -471,7 +471,7 @@ set edit:completion:arg-completer[rom-weaver] = {|@words|
471
471
  cand --input 'ROM the patches apply to. Its checksums and size are read from the file and recorded in the bundle'
472
472
  cand --assume-in 'Take the ROM''s checksum and size on trust rather than reading it, as in crc32=1234abcd,size=1048576 (repeatable, comma-separable)'
473
473
  cand --rom-url 'Where the ROM can be downloaded from. With --input, the local file still supplies the checksums; on its own, the bundle records only this url'
474
- cand --rom-name 'File name to show for the ROM, and to base the output name on'
474
+ cand --rom-name 'Expected ROM file name to show and use for output naming; a supplied ROM with a different name only warns'
475
475
  cand --patch 'Patch to list in the bundle. Repeat once per patch, in the order they should be applied'
476
476
  cand --patch-id 'Identifier for the preceding --patch that stays the same across releases, so a replacement keeps its settings'
477
477
  cand --patch-version 'Version of the preceding --patch, in whatever form its author uses'
@@ -698,10 +698,10 @@ set edit:completion:arg-completer[rom-weaver] = {|@words|
698
698
  }
699
699
  &'rom-weaver;help'= {
700
700
  cand probe 'Identify a file: its format, its platform, and any header it carries'
701
- cand extract 'Unpack an archive or disc image'
701
+ cand extract 'Unpack an archive or single-payload compressed format'
702
702
  cand checksum 'Compute checksums for a file, or for a ROM inside an archive'
703
703
  cand ingest 'Sort a file into ROMs and patches, unpacking and hashing along the way'
704
- cand compress 'Pack files into an archive or a compressed disc image'
704
+ cand compress 'Pack files into an archive, disc image, or ROM-specific compressed format'
705
705
  cand trim 'Cut the padding off a ROM, or put it back'
706
706
  cand patch 'Apply, create, or check ROM patches'
707
707
  cand bundle 'Build and read rom-weaver-bundle.json patch recipes'
@@ -42,10 +42,10 @@ complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -s h -l help -d 'Pri
42
42
  complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -s V -l version -d 'Print version'
43
43
  complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "probe" -d 'Identify a file: its format, its platform, and any header it carries'
44
44
  complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "inspect" -d 'Identify a file: its format, its platform, and any header it carries'
45
- complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "extract" -d 'Unpack an archive or disc image'
45
+ complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "extract" -d 'Unpack an archive or single-payload compressed format'
46
46
  complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "checksum" -d 'Compute checksums for a file, or for a ROM inside an archive'
47
47
  complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "ingest" -d 'Sort a file into ROMs and patches, unpacking and hashing along the way'
48
- complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "compress" -d 'Pack files into an archive or a compressed disc image'
48
+ complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "compress" -d 'Pack files into an archive, disc image, or ROM-specific compressed format'
49
49
  complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "trim" -d 'Cut the padding off a ROM, or put it back'
50
50
  complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "patch" -d 'Apply, create, or check ROM patches'
51
51
  complete -c rom-weaver -n "__fish_rom_weaver_needs_command" -f -a "bundle" -d 'Build and read rom-weaver-bundle.json patch recipes'
@@ -96,7 +96,7 @@ complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand inspect" -l dep-tr
96
96
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand inspect" -l color -d 'Keep colors even when output is piped'
97
97
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand inspect" -l no-color -d 'Turn colors off'
98
98
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand inspect" -s h -l help -d 'Print help (see more with \'--help\')'
99
- complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand extract" -s i -l input -d 'Archive or disc image to unpack' -r -F
99
+ complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand extract" -s i -l input -d 'Archive or single-payload compressed format to unpack' -r -F
100
100
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand extract" -s s -l select -d 'Extract only these files, by exact name, prefix, or glob (repeatable). For example: --select \'game.disc0?.bin\'' -r
101
101
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand extract" -l filter -d 'Extract only files that look like a rom or a patch, judged by extension (repeatable, comma-separable)' -r -f -a "rom\t''
102
102
  patch\t''"
@@ -479,7 +479,7 @@ complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand bundle; and not __
479
479
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand bundle; and __fish_seen_subcommand_from create" -s i -l input -d 'ROM the patches apply to. Its checksums and size are read from the file and recorded in the bundle' -r -F
480
480
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand bundle; and __fish_seen_subcommand_from create" -l assume-in -d 'Take the ROM\'s checksum and size on trust rather than reading it, as in crc32=1234abcd,size=1048576 (repeatable, comma-separable)' -r
481
481
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand bundle; and __fish_seen_subcommand_from create" -l rom-url -d 'Where the ROM can be downloaded from. With --input, the local file still supplies the checksums; on its own, the bundle records only this url' -r
482
- complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand bundle; and __fish_seen_subcommand_from create" -l rom-name -d 'File name to show for the ROM, and to base the output name on' -r
482
+ complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand bundle; and __fish_seen_subcommand_from create" -l rom-name -d 'Expected ROM file name to show and use for output naming; a supplied ROM with a different name only warns' -r
483
483
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand bundle; and __fish_seen_subcommand_from create" -l patch -d 'Patch to list in the bundle. Repeat once per patch, in the order they should be applied' -r -F
484
484
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand bundle; and __fish_seen_subcommand_from create" -l patch-id -d 'Identifier for the preceding --patch that stays the same across releases, so a replacement keeps its settings' -r
485
485
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand bundle; and __fish_seen_subcommand_from create" -l patch-version -d 'Version of the preceding --patch, in whatever form its author uses' -r
@@ -702,10 +702,10 @@ complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand completions" -l co
702
702
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand completions" -l no-color -d 'Turn colors off'
703
703
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand completions" -s h -l help -d 'Print help (see more with \'--help\')'
704
704
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "probe" -d 'Identify a file: its format, its platform, and any header it carries'
705
- complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "extract" -d 'Unpack an archive or disc image'
705
+ complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "extract" -d 'Unpack an archive or single-payload compressed format'
706
706
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "checksum" -d 'Compute checksums for a file, or for a ROM inside an archive'
707
707
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "ingest" -d 'Sort a file into ROMs and patches, unpacking and hashing along the way'
708
- complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "compress" -d 'Pack files into an archive or a compressed disc image'
708
+ complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "compress" -d 'Pack files into an archive, disc image, or ROM-specific compressed format'
709
709
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "trim" -d 'Cut the padding off a ROM, or put it back'
710
710
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "patch" -d 'Apply, create, or check ROM patches'
711
711
  complete -c rom-weaver -n "__fish_rom_weaver_using_subcommand help; and not __fish_seen_subcommand_from probe extract checksum ingest compress trim patch bundle tools plan-extract-batch weave completions help" -f -a "bundle" -d 'Build and read rom-weaver-bundle.json patch recipes'
@@ -38,10 +38,10 @@ Register-ArgumentCompleter -Native -CommandName 'rom-weaver' -ScriptBlock {
38
38
  [CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
39
39
  [CompletionResult]::new('probe', 'probe', [CompletionResultType]::ParameterValue, 'Identify a file: its format, its platform, and any header it carries')
40
40
  [CompletionResult]::new('inspect', 'inspect', [CompletionResultType]::ParameterValue, 'Identify a file: its format, its platform, and any header it carries')
41
- [CompletionResult]::new('extract', 'extract', [CompletionResultType]::ParameterValue, 'Unpack an archive or disc image')
41
+ [CompletionResult]::new('extract', 'extract', [CompletionResultType]::ParameterValue, 'Unpack an archive or single-payload compressed format')
42
42
  [CompletionResult]::new('checksum', 'checksum', [CompletionResultType]::ParameterValue, 'Compute checksums for a file, or for a ROM inside an archive')
43
43
  [CompletionResult]::new('ingest', 'ingest', [CompletionResultType]::ParameterValue, 'Sort a file into ROMs and patches, unpacking and hashing along the way')
44
- [CompletionResult]::new('compress', 'compress', [CompletionResultType]::ParameterValue, 'Pack files into an archive or a compressed disc image')
44
+ [CompletionResult]::new('compress', 'compress', [CompletionResultType]::ParameterValue, 'Pack files into an archive, disc image, or ROM-specific compressed format')
45
45
  [CompletionResult]::new('trim', 'trim', [CompletionResultType]::ParameterValue, 'Cut the padding off a ROM, or put it back')
46
46
  [CompletionResult]::new('patch', 'patch', [CompletionResultType]::ParameterValue, 'Apply, create, or check ROM patches')
47
47
  [CompletionResult]::new('bundle', 'bundle', [CompletionResultType]::ParameterValue, 'Build and read rom-weaver-bundle.json patch recipes')
@@ -99,8 +99,8 @@ Register-ArgumentCompleter -Native -CommandName 'rom-weaver' -ScriptBlock {
99
99
  break
100
100
  }
101
101
  'rom-weaver;extract' {
102
- [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Archive or disc image to unpack')
103
- [CompletionResult]::new('--input', '--input', [CompletionResultType]::ParameterName, 'Archive or disc image to unpack')
102
+ [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Archive or single-payload compressed format to unpack')
103
+ [CompletionResult]::new('--input', '--input', [CompletionResultType]::ParameterName, 'Archive or single-payload compressed format to unpack')
104
104
  [CompletionResult]::new('-s', '-s', [CompletionResultType]::ParameterName, 'Extract only these files, by exact name, prefix, or glob (repeatable). For example: --select ''game.disc0?.bin''')
105
105
  [CompletionResult]::new('--select', '--select', [CompletionResultType]::ParameterName, 'Extract only these files, by exact name, prefix, or glob (repeatable). For example: --select ''game.disc0?.bin''')
106
106
  [CompletionResult]::new('--filter', '--filter', [CompletionResultType]::ParameterName, 'Extract only files that look like a rom or a patch, judged by extension (repeatable, comma-separable)')
@@ -493,7 +493,7 @@ Register-ArgumentCompleter -Native -CommandName 'rom-weaver' -ScriptBlock {
493
493
  [CompletionResult]::new('--input', '--input', [CompletionResultType]::ParameterName, 'ROM the patches apply to. Its checksums and size are read from the file and recorded in the bundle')
494
494
  [CompletionResult]::new('--assume-in', '--assume-in', [CompletionResultType]::ParameterName, 'Take the ROM''s checksum and size on trust rather than reading it, as in crc32=1234abcd,size=1048576 (repeatable, comma-separable)')
495
495
  [CompletionResult]::new('--rom-url', '--rom-url', [CompletionResultType]::ParameterName, 'Where the ROM can be downloaded from. With --input, the local file still supplies the checksums; on its own, the bundle records only this url')
496
- [CompletionResult]::new('--rom-name', '--rom-name', [CompletionResultType]::ParameterName, 'File name to show for the ROM, and to base the output name on')
496
+ [CompletionResult]::new('--rom-name', '--rom-name', [CompletionResultType]::ParameterName, 'Expected ROM file name to show and use for output naming; a supplied ROM with a different name only warns')
497
497
  [CompletionResult]::new('--patch', '--patch', [CompletionResultType]::ParameterName, 'Patch to list in the bundle. Repeat once per patch, in the order they should be applied')
498
498
  [CompletionResult]::new('--patch-id', '--patch-id', [CompletionResultType]::ParameterName, 'Identifier for the preceding --patch that stays the same across releases, so a replacement keeps its settings')
499
499
  [CompletionResult]::new('--patch-version', '--patch-version', [CompletionResultType]::ParameterName, 'Version of the preceding --patch, in whatever form its author uses')
@@ -736,10 +736,10 @@ Register-ArgumentCompleter -Native -CommandName 'rom-weaver' -ScriptBlock {
736
736
  }
737
737
  'rom-weaver;help' {
738
738
  [CompletionResult]::new('probe', 'probe', [CompletionResultType]::ParameterValue, 'Identify a file: its format, its platform, and any header it carries')
739
- [CompletionResult]::new('extract', 'extract', [CompletionResultType]::ParameterValue, 'Unpack an archive or disc image')
739
+ [CompletionResult]::new('extract', 'extract', [CompletionResultType]::ParameterValue, 'Unpack an archive or single-payload compressed format')
740
740
  [CompletionResult]::new('checksum', 'checksum', [CompletionResultType]::ParameterValue, 'Compute checksums for a file, or for a ROM inside an archive')
741
741
  [CompletionResult]::new('ingest', 'ingest', [CompletionResultType]::ParameterValue, 'Sort a file into ROMs and patches, unpacking and hashing along the way')
742
- [CompletionResult]::new('compress', 'compress', [CompletionResultType]::ParameterValue, 'Pack files into an archive or a compressed disc image')
742
+ [CompletionResult]::new('compress', 'compress', [CompletionResultType]::ParameterValue, 'Pack files into an archive, disc image, or ROM-specific compressed format')
743
743
  [CompletionResult]::new('trim', 'trim', [CompletionResultType]::ParameterValue, 'Cut the padding off a ROM, or put it back')
744
744
  [CompletionResult]::new('patch', 'patch', [CompletionResultType]::ParameterValue, 'Apply, create, or check ROM patches')
745
745
  [CompletionResult]::new('bundle', 'bundle', [CompletionResultType]::ParameterValue, 'Build and read rom-weaver-bundle.json patch recipes')
@@ -10,7 +10,7 @@ Write a rom\-weaver\-bundle.json recipe from local ROM and patch files.
10
10
  .PP
11
11
  A bundle records which ROM the patches are for, what order they run in, and
12
12
  what the result should hash to. Hand it to someone else and
13
- `rom\-weaver weave \-\-bundle` reproduces your exact result.
13
+ `rom\-weaver patch apply \-\-bundle` reproduces your exact result.
14
14
  .PP
15
15
  Checksums come from the real files, so nothing here is taken on faith. Every
16
16
  \-\-patch\-* flag describes the \-\-patch before it.
@@ -29,7 +29,7 @@ Take the ROM\*(Aqs checksum and size on trust rather than reading it, as in crc3
29
29
  Where the ROM can be downloaded from. With \-\-input, the local file still supplies the checksums; on its own, the bundle records only this url
30
30
  .TP
31
31
  \fB\-\-rom\-name\fR \fI<ROM_NAME>\fR
32
- File name to show for the ROM, and to base the output name on
32
+ Expected ROM file name to show and use for output naming; a supplied ROM with a different name only warns
33
33
  .TP
34
34
  \fB\-\-patch\fR \fI<PATCH>\fR
35
35
  Patch to list in the bundle. Repeat once per patch, in the order they should be
@@ -17,7 +17,7 @@ Entries that name a file are looked for in the archive, or next to the recipe.
17
17
  Pass \-\-output to write those files out and get real paths back. Entries that
18
18
  name a url are reported as they are; nothing is downloaded.
19
19
  .PP
20
- To actually run a bundle, use `rom\-weaver weave \-\-bundle` instead.
20
+ To actually run a bundle, use `rom\-weaver patch apply \-\-bundle` instead.
21
21
  .SH OPTIONS
22
22
  .TP
23
23
  \fB\-i\fR, \fB\-\-input\fR \fI<INPUT>\fR
@@ -2,17 +2,18 @@
2
2
  .el .ds Aq '
3
3
  .TH rom-weaver-compress 1 "rom-weaver-compress "
4
4
  .SH NAME
5
- rom\-weaver\-compress \- Pack files into an archive or a compressed disc image
5
+ rom\-weaver\-compress \- Pack files into an archive, disc image, or ROM\-specific compressed format
6
6
  .SH SYNOPSIS
7
7
  \fBrom\-weaver compress\fR <\fB\-i\fR|\fB\-\-input\fR> [\fB\-\-json\fR] [\fB\-f\fR|\fB\-\-format\fR] [\fB\-\-progress\fR] [\fB\-\-no\-progress\fR] <\fB\-o\fR|\fB\-\-output\fR> [\fB\-\-codec\fR] [\fB\-\-log\-level\fR] [\fB\-\-level\fR] [\fB\-v\fR|\fB\-\-verbose\fR]... [\fB\-j\fR|\fB\-\-threads\fR] [\fB\-q\fR|\fB\-\-quiet\fR] [\fB\-\-dep\-trace\fR] [\fB\-\-color\fR] [\fB\-\-no\-color\fR] [\fB\-h\fR|\fB\-\-help\fR]
8
8
  .SH DESCRIPTION
9
- Pack files into an archive or a compressed disc image.
9
+ Pack files into an archive, disc image, or ROM\-specific compressed format.
10
10
  .PP
11
11
  The format comes from the \-\-output extension, so `\-\-output game.chd` writes a
12
12
  CHD. Formats that can be written: zip, 7z, chd, rvz, and z3ds.
13
13
  .PP
14
- Repeat \-\-input to put several files in one archive. Disc images take a single
15
- input instead: point \-\-input at the .cue or .gdi and its tracks come along.
14
+ Repeat \-\-input to put several files in one archive. Single\-payload formats take
15
+ one input instead: point \-\-input at the .cue or .gdi for a disc image, or at a
16
+ single 3DS ROM for Z3DS.
16
17
  .PP
17
18
  rom\-weaver compress \-\-input game.cue \-\-output game.chd
18
19
  .PP
@@ -2,11 +2,11 @@
2
2
  .el .ds Aq '
3
3
  .TH rom-weaver-extract 1 "rom-weaver-extract "
4
4
  .SH NAME
5
- rom\-weaver\-extract \- Unpack an archive or disc image
5
+ rom\-weaver\-extract \- Unpack an archive or single\-payload compressed format
6
6
  .SH SYNOPSIS
7
7
  \fBrom\-weaver extract\fR <\fB\-i\fR|\fB\-\-input\fR> [\fB\-\-json\fR] [\fB\-\-progress\fR] [\fB\-s\fR|\fB\-\-select\fR] [\fB\-\-filter\fR] [\fB\-\-no\-progress\fR] [\fB\-\-log\-level\fR] <\fB\-o\fR|\fB\-\-output\fR> [\fB\-\-split\-bin\fR] [\fB\-v\fR|\fB\-\-verbose\fR]... [\fB\-\-no\-ignore\fR] [\fB\-q\fR|\fB\-\-quiet\fR] [\fB\-\-dep\-trace\fR] [\fB\-\-no\-nested\-extract\fR] [\fB\-\-color\fR] [\fB\-\-force\fR] [\fB\-\-checksum\fR] [\fB\-\-no\-color\fR] [\fB\-\-checksum\-rom\fR] [\fB\-\-probe\fR] [\fB\-j\fR|\fB\-\-threads\fR] [\fB\-h\fR|\fB\-\-help\fR]
8
8
  .SH DESCRIPTION
9
- Unpack an archive or disc image into a directory.
9
+ Unpack an archive or single\-payload compressed format into a directory.
10
10
  .PP
11
11
  Archives found inside the input are unpacked too, up to eight levels deep. Pass
12
12
  \-\-no\-nested\-extract to stop after the first layer.
@@ -16,7 +16,7 @@ whole extraction stops before writing. Pass \-\-force to overwrite instead.
16
16
  .SH OPTIONS
17
17
  .TP
18
18
  \fB\-i\fR, \fB\-\-input\fR \fI<INPUT>\fR
19
- Archive or disc image to unpack
19
+ Archive or single\-payload compressed format to unpack
20
20
  .TP
21
21
  \fB\-s\fR, \fB\-\-select\fR \fI<SELECT>\fR
22
22
  Extract only these files, by exact name, prefix, or glob (repeatable). For example: \-\-select \*(Aqgame.disc0?.bin\*(Aq
@@ -8,13 +8,14 @@ rom\-weaver\-patch\-apply \- Apply one or more patches to a ROM, in order
8
8
  .SH DESCRIPTION
9
9
  Apply one or more patches to a ROM, in order.
10
10
  .PP
11
- `rom\-weaver weave` runs this same command under a shorter name, and is what
12
- most of the examples use.
11
+ Use `rom\-weaver patch apply` for the canonical command. The compatibility
12
+ spelling `rom\-weaver weave` runs the same command.
13
13
  .PP
14
14
  Repeat \-\-patch once per patch. They run left to right, each one on the result
15
- of the last. \-\-input takes a plain ROM, an archive or disc image (the ROM
16
- inside is found for you), or a rom\-weaver\-bundle.json that already names the
17
- ROM, the patches, and the output.
15
+ of the last. \-\-input takes a plain ROM, an archive, or a single\-payload
16
+ compressed format (the ROM inside is found for you), or a
17
+ rom\-weaver\-bundle.json that already names the ROM, the patches, and the
18
+ output.
18
19
  .PP
19
20
  The result is compressed by default, into whatever container the \-\-output
20
21
  extension names. Pass \-\-no\-compress for a plain ROM file.
@@ -340,17 +341,17 @@ Turn colors off
340
341
  .SH EXTRA
341
342
  Examples:
342
343
  # One patch, plain ROM out
343
- rom\-weaver weave \-\-input game.sfc \-\-patch hack.bps \\
344
+ rom\-weaver patch apply \-\-input game.sfc \-\-patch hack.bps \\
344
345
  \-\-output hacked.sfc \-\-no\-compress
345
346
 
346
347
  # Two patches in order, straight out of and back into a zip
347
- rom\-weaver weave \-\-input game.zip \\
348
+ rom\-weaver patch apply \-\-input game.zip \\
348
349
  \-\-patch translation.bps \-\-patch fixes.ips \-\-output hacked.zip
349
350
 
350
351
  # Replay someone else\*(Aqs published recipe
351
- rom\-weaver weave \-\-bundle rom\-weaver\-bundle.json \-\-input game.sfc
352
+ rom\-weaver patch apply \-\-bundle rom\-weaver\-bundle.json \-\-input game.sfc
352
353
 
353
354
  # Check the result against a checksum the patch author published
354
- rom\-weaver weave \-\-input game.sfc \-\-patch hack.bps \\
355
+ rom\-weaver patch apply \-\-input game.sfc \-\-patch hack.bps \\
355
356
  \-\-output hacked.sfc \-\-no\-compress \\
356
357
  \-\-expect\-out sha1=0123456789abcdef0123456789abcdef01234567
@@ -8,13 +8,14 @@ rom\-weaver\-weave \- Apply one or more patches to a ROM, in order (same as `pat
8
8
  .SH DESCRIPTION
9
9
  Apply one or more patches to a ROM, in order.
10
10
  .PP
11
- `rom\-weaver weave` runs this same command under a shorter name, and is what
12
- most of the examples use.
11
+ Use `rom\-weaver patch apply` for the canonical command. The compatibility
12
+ spelling `rom\-weaver weave` runs the same command.
13
13
  .PP
14
14
  Repeat \-\-patch once per patch. They run left to right, each one on the result
15
- of the last. \-\-input takes a plain ROM, an archive or disc image (the ROM
16
- inside is found for you), or a rom\-weaver\-bundle.json that already names the
17
- ROM, the patches, and the output.
15
+ of the last. \-\-input takes a plain ROM, an archive, or a single\-payload
16
+ compressed format (the ROM inside is found for you), or a
17
+ rom\-weaver\-bundle.json that already names the ROM, the patches, and the
18
+ output.
18
19
  .PP
19
20
  The result is compressed by default, into whatever container the \-\-output
20
21
  extension names. Pass \-\-no\-compress for a plain ROM file.
@@ -340,17 +341,17 @@ Turn colors off
340
341
  .SH EXTRA
341
342
  Examples:
342
343
  # One patch, plain ROM out
343
- rom\-weaver weave \-\-input game.sfc \-\-patch hack.bps \\
344
+ rom\-weaver patch apply \-\-input game.sfc \-\-patch hack.bps \\
344
345
  \-\-output hacked.sfc \-\-no\-compress
345
346
 
346
347
  # Two patches in order, straight out of and back into a zip
347
- rom\-weaver weave \-\-input game.zip \\
348
+ rom\-weaver patch apply \-\-input game.zip \\
348
349
  \-\-patch translation.bps \-\-patch fixes.ips \-\-output hacked.zip
349
350
 
350
351
  # Replay someone else\*(Aqs published recipe
351
- rom\-weaver weave \-\-bundle rom\-weaver\-bundle.json \-\-input game.sfc
352
+ rom\-weaver patch apply \-\-bundle rom\-weaver\-bundle.json \-\-input game.sfc
352
353
 
353
354
  # Check the result against a checksum the patch author published
354
- rom\-weaver weave \-\-input game.sfc \-\-patch hack.bps \\
355
+ rom\-weaver patch apply \-\-input game.sfc \-\-patch hack.bps \\
355
356
  \-\-output hacked.sfc \-\-no\-compress \\
356
357
  \-\-expect\-out sha1=0123456789abcdef0123456789abcdef01234567
@@ -1,6 +1,6 @@
1
1
  .ie \n(.g .ds Aq \(aq
2
2
  .el .ds Aq '
3
- .TH rom-weaver 1 "rom-weaver 0.11.0"
3
+ .TH rom-weaver 1 "rom-weaver 0.12.0"
4
4
  .SH NAME
5
5
  rom\-weaver \- Inspect, extract, checksum, compress, trim, and patch ROMs and disc images
6
6
  .SH SYNOPSIS
@@ -9,8 +9,8 @@ rom\-weaver \- Inspect, extract, checksum, compress, trim, and patch ROMs and di
9
9
  Inspect, extract, checksum, compress, trim, and patch ROMs and disc images.
10
10
  .PP
11
11
  rom\-weaver reads compressed input directly, so you rarely have to unpack a file
12
- first. Point \-\-input at an archive or disc image and the ROM inside it is found
13
- for you; pass \-\-no\-extract to work on the raw bytes instead.
12
+ first. Point \-\-input at an archive or single\-payload compressed format; the ROM
13
+ inside it is found for you. Pass \-\-no\-extract to work on the raw bytes instead.
14
14
  .PP
15
15
  Everything runs on your machine. Nothing is uploaded.
16
16
  .SH OPTIONS
@@ -72,7 +72,7 @@ rom\-weaver\-probe(1)
72
72
  Identify a file: its format, its platform, and any header it carries
73
73
  .TP
74
74
  rom\-weaver\-extract(1)
75
- Unpack an archive or disc image
75
+ Unpack an archive or single\-payload compressed format
76
76
  .TP
77
77
  rom\-weaver\-checksum(1)
78
78
  Compute checksums for a file, or for a ROM inside an archive
@@ -81,7 +81,7 @@ rom\-weaver\-ingest(1)
81
81
  Sort a file into ROMs and patches, unpacking and hashing along the way
82
82
  .TP
83
83
  rom\-weaver\-compress(1)
84
- Pack files into an archive or a compressed disc image
84
+ Pack files into an archive, disc image, or ROM\-specific compressed format
85
85
  .TP
86
86
  rom\-weaver\-trim(1)
87
87
  Cut the padding off a ROM, or put it back
@@ -106,11 +106,11 @@ Examples:
106
106
  rom\-weaver probe \-\-input game.iso
107
107
 
108
108
  # Apply a patch, writing a plain ROM
109
- rom\-weaver weave \-\-input game.sfc \-\-patch hack.bps \\
109
+ rom\-weaver patch apply \-\-input game.sfc \-\-patch hack.bps \\
110
110
  \-\-output hacked.sfc \-\-no\-compress
111
111
 
112
112
  # Two patches in order; the .zip extension compresses the result
113
- rom\-weaver weave \-\-input game.sfc \\
113
+ rom\-weaver patch apply \-\-input game.sfc \\
114
114
  \-\-patch base.ips \-\-patch fixes.ups \-\-output hacked.zip
115
115
 
116
116
  # Hash a ROM, including one inside an archive
@@ -119,6 +119,6 @@ Examples:
119
119
  # Shrink a disc image; the .cue brings its tracks along
120
120
  rom\-weaver compress \-\-input game.cue \-\-output game.chd
121
121
 
122
- Full guide: https://github.com/rom\-weaver/rom\-weaver/blob/main/docs/cli/reference.md
122
+ Full guide: https://rom\-weaver.com/docs/cli
123
123
  .SH VERSION
124
- v0.11.0
124
+ v0.12.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rom-weaver/cli",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "author": "Brandon Casey",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "description": "Local-first toolkit for ROMs and disc images: inspect, extract, compress, and apply, create, or bundle patches. Offline via a browser service-worker PWA or CLI.",
@@ -64,15 +64,15 @@
64
64
  "node": ">=22"
65
65
  },
66
66
  "optionalDependencies": {
67
- "@rom-weaver/darwin-arm64": "0.11.0",
68
- "@rom-weaver/darwin-x64": "0.11.0",
69
- "@rom-weaver/linux-arm64-musl": "0.11.0",
70
- "@rom-weaver/linux-ia32-musl": "0.11.0",
71
- "@rom-weaver/linux-x64-gnu": "0.11.0",
72
- "@rom-weaver/linux-x64-musl": "0.11.0",
73
- "@rom-weaver/win32-arm64-msvc": "0.11.0",
74
- "@rom-weaver/win32-ia32-msvc": "0.11.0",
75
- "@rom-weaver/win32-x64-msvc": "0.11.0"
67
+ "@rom-weaver/darwin-arm64": "0.12.0",
68
+ "@rom-weaver/darwin-x64": "0.12.0",
69
+ "@rom-weaver/linux-arm64-musl": "0.12.0",
70
+ "@rom-weaver/linux-ia32-musl": "0.12.0",
71
+ "@rom-weaver/linux-x64-gnu": "0.12.0",
72
+ "@rom-weaver/linux-x64-musl": "0.12.0",
73
+ "@rom-weaver/win32-arm64-msvc": "0.12.0",
74
+ "@rom-weaver/win32-ia32-msvc": "0.12.0",
75
+ "@rom-weaver/win32-x64-msvc": "0.12.0"
76
76
  },
77
77
  "scripts": {
78
78
  "docs:lint": "markdownlint-cli2",
@@ -82,6 +82,7 @@
82
82
  "hooks:install": "node scripts/lefthook-install.mjs",
83
83
  "hooks:run": "lefthook run pre-commit --force",
84
84
  "hooks:validate": "lefthook validate",
85
+ "lint:code": "oxlint scripts packages/rom-weaver-alias/bin --deny-warnings",
85
86
  "prepack": "mise run manpages",
86
87
  "test": "node --test scripts/*.test.mjs scripts/ci/*.test.mjs scripts/wasm/*.test.mjs",
87
88
  "audit:deps": "npm audit --audit-level=high",
@@ -95,6 +96,7 @@
95
96
  "cross-spawn": "7.0.6",
96
97
  "doctoc": "2.5.0",
97
98
  "lefthook": "2.1.10",
98
- "markdownlint-cli2": "0.23.2"
99
+ "markdownlint-cli2": "0.23.2",
100
+ "oxlint": "1.76.0"
99
101
  }
100
102
  }