boo-flash 0.1.5 → 0.1.7
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 +13 -0
- package/dist/app.js +395 -514
- package/package.json +2 -3
package/dist/app.js
CHANGED
|
@@ -2552,7 +2552,6 @@ import { createHash as createHash2 } from "node:crypto";
|
|
|
2552
2552
|
import { chmod as chmod2, mkdtemp, open as open2, rm } from "node:fs/promises";
|
|
2553
2553
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
2554
2554
|
import { dirname as dirname3, join as join5 } from "node:path";
|
|
2555
|
-
import { setTimeout as delay } from "node:timers/promises";
|
|
2556
2555
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2557
2556
|
|
|
2558
2557
|
// src/backends/macos.ts
|
|
@@ -2588,7 +2587,6 @@ function resolvePackage(name2) {
|
|
|
2588
2587
|
|
|
2589
2588
|
// src/dependencies.ts
|
|
2590
2589
|
var commonTools = ["curl", "zstd"];
|
|
2591
|
-
var candidateTools = ["gh", "unzip"];
|
|
2592
2590
|
function preferredExecutable(name2, platform3, path, macSystemExists) {
|
|
2593
2591
|
if (platform3 === "darwin" && (name2 === "curl" || name2 === "unzip") && macSystemExists) return `/usr/bin/${name2}`;
|
|
2594
2592
|
return path;
|
|
@@ -2643,7 +2641,7 @@ async function command(argv, signal, options = {}) {
|
|
|
2643
2641
|
if (!binary) throw new Error(`Missing ${argv[0]}. Refresh dependency setup before continuing.`);
|
|
2644
2642
|
const child = spawn(binary, argv.slice(1), {
|
|
2645
2643
|
stdio: options.terminal ? "inherit" : ["pipe", "pipe", "pipe"],
|
|
2646
|
-
env: { ...process.env,
|
|
2644
|
+
env: { ...process.env, PAGER: "cat" }
|
|
2647
2645
|
});
|
|
2648
2646
|
let failure;
|
|
2649
2647
|
const exited = new Promise((resolve) => {
|
|
@@ -2654,7 +2652,7 @@ async function command(argv, signal, options = {}) {
|
|
|
2654
2652
|
});
|
|
2655
2653
|
let stderr = "";
|
|
2656
2654
|
child.stderr?.on("data", (data) => {
|
|
2657
|
-
|
|
2655
|
+
stderr = (stderr + data.toString()).slice(-1500);
|
|
2658
2656
|
});
|
|
2659
2657
|
child.stdin?.on("error", (error) => {
|
|
2660
2658
|
failure = error;
|
|
@@ -2677,8 +2675,7 @@ async function command(argv, signal, options = {}) {
|
|
|
2677
2675
|
const code2 = await exited;
|
|
2678
2676
|
signal.throwIfAborted();
|
|
2679
2677
|
if (failure || code2 !== 0) {
|
|
2680
|
-
|
|
2681
|
-
throw new Error(message);
|
|
2678
|
+
throw new Error(`${argv[0].split("/").pop()} failed (${code2 ?? "not started"}). ${cleanText(stderr || failure?.message || "")}`);
|
|
2682
2679
|
}
|
|
2683
2680
|
return output;
|
|
2684
2681
|
} finally {
|
|
@@ -2690,10 +2687,9 @@ async function command(argv, signal, options = {}) {
|
|
|
2690
2687
|
|
|
2691
2688
|
// src/installers/homebrew.ts
|
|
2692
2689
|
import { spawn as spawn2 } from "node:child_process";
|
|
2693
|
-
var packages =
|
|
2694
|
-
function dependencies(
|
|
2695
|
-
const
|
|
2696
|
-
const absent = missing(required2);
|
|
2690
|
+
var packages = commonTools;
|
|
2691
|
+
function dependencies() {
|
|
2692
|
+
const absent = missing(packages);
|
|
2697
2693
|
return {
|
|
2698
2694
|
missing: absent,
|
|
2699
2695
|
installer: absent.length ? executable("brew") : null,
|
|
@@ -2804,8 +2800,6 @@ async function disks(signal, source, staging = tmpdir(), unmounted) {
|
|
|
2804
2800
|
const zstd = executable("zstd");
|
|
2805
2801
|
if (!zstd) throw new Error("Install zstd before flashing.");
|
|
2806
2802
|
protectedPaths2.push(zstd);
|
|
2807
|
-
const gh = executable("gh");
|
|
2808
|
-
if (gh) protectedPaths2.push(gh);
|
|
2809
2803
|
for (const path of protectedPaths2) {
|
|
2810
2804
|
const canonical = await realpath(path);
|
|
2811
2805
|
const device = (await command(["/usr/bin/stat", "-f", "%Sd", canonical], signal)).trim();
|
|
@@ -3044,7 +3038,7 @@ async function protectedPaths(source, staging) {
|
|
|
3044
3038
|
}
|
|
3045
3039
|
}
|
|
3046
3040
|
if (process.env.OTUI_ASSET_ROOT) paths.push(process.env.OTUI_ASSET_ROOT);
|
|
3047
|
-
for (const name2 of [...commonTools, ...
|
|
3041
|
+
for (const name2 of [...commonTools, ...tools]) {
|
|
3048
3042
|
const path = executable(name2);
|
|
3049
3043
|
if (path) paths.push(path);
|
|
3050
3044
|
}
|
|
@@ -3239,8 +3233,8 @@ async function disks2(signal, source, staging = tmpdir2(), unmounted) {
|
|
|
3239
3233
|
}
|
|
3240
3234
|
return result;
|
|
3241
3235
|
}
|
|
3242
|
-
function dependencies2(
|
|
3243
|
-
const required2 = [...commonTools, ...tools
|
|
3236
|
+
function dependencies2() {
|
|
3237
|
+
const required2 = [...commonTools, ...tools];
|
|
3244
3238
|
return {
|
|
3245
3239
|
missing: missing(required2),
|
|
3246
3240
|
installer: null,
|
|
@@ -3423,8 +3417,6 @@ async function clearCachedImages(signal) {
|
|
|
3423
3417
|
|
|
3424
3418
|
// src/backend.ts
|
|
3425
3419
|
var profiles = ["intel", "amd", "nvidia"];
|
|
3426
|
-
var repository = "anomalyco/boo";
|
|
3427
|
-
var repositoryIdentities = /* @__PURE__ */ new Set([repository, "anomalyco/ghostty-distro"]);
|
|
3428
3420
|
var releaseOrigin = "https://images.os.boo";
|
|
3429
3421
|
var diskID3 = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/;
|
|
3430
3422
|
var sha256 = /^[a-f0-9]{64}$/;
|
|
@@ -3529,152 +3521,97 @@ async function discoverImages(signal) {
|
|
|
3529
3521
|
});
|
|
3530
3522
|
return { run: build, version: channel.version, revision: channel.revision, timestamp, images };
|
|
3531
3523
|
}
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
const
|
|
3540
|
-
if (!
|
|
3541
|
-
|
|
3542
|
-
const match = /^boo-(intel|amd|nvidia)-candidate-([a-f0-9]{40})$/.exec(a.name);
|
|
3543
|
-
if (!match || a.expired !== false || !(Date.parse(a.expires_at) > Date.now()) || !positive(a.id) || !positive(a.size_in_bytes) || !/^sha256:[a-f0-9]{64}$/.test(a.digest) || batch.artifacts.filter((other) => other.name === a.name).length !== 1) continue;
|
|
3544
|
-
candidates.push({
|
|
3545
|
-
run: run.id,
|
|
3546
|
-
revision: match[2],
|
|
3547
|
-
timestamp: new Date(run.created_at).toISOString(),
|
|
3548
|
-
images: [{
|
|
3549
|
-
profile: match[1],
|
|
3550
|
-
id: a.id,
|
|
3551
|
-
name: a.name,
|
|
3552
|
-
bytes: a.size_in_bytes,
|
|
3553
|
-
digest: a.digest.slice(7)
|
|
3554
|
-
}],
|
|
3555
|
-
candidate: { number: run.run_number }
|
|
3556
|
-
});
|
|
3557
|
-
if (candidates.length === 10) return candidates;
|
|
3524
|
+
function candidateCatalog(result) {
|
|
3525
|
+
if (result?.schema !== 1 || !Array.isArray(result.candidates) || result.candidates.length > 10) {
|
|
3526
|
+
throw new Error("Invalid Boo candidate catalog.");
|
|
3527
|
+
}
|
|
3528
|
+
return result.candidates.map((candidate) => {
|
|
3529
|
+
const profile = candidate?.profile;
|
|
3530
|
+
const image = candidate?.image;
|
|
3531
|
+
const name2 = `boo-${candidate?.version}-candidate-${candidate?.revision?.slice(0, 12)}-x86_64-${profile}.raw.zst`;
|
|
3532
|
+
if (!positive(candidate?.number) || !Number.isFinite(Date.parse(candidate?.timestamp)) || !/^[a-f0-9]{40}$/.test(candidate?.revision) || !profiles.includes(profile) || !semanticVersion.test(candidate?.version) || image?.file !== name2 || image?.prefix !== `candidates/${candidate.revision}/${profile}` || !positive(image?.bytes) || !sha256.test(image?.sha256) || !positive(image?.raw_bytes) || !sha256.test(image?.raw_sha256)) {
|
|
3533
|
+
throw new Error("Invalid Boo candidate metadata.");
|
|
3558
3534
|
}
|
|
3559
|
-
|
|
3560
|
-
|
|
3535
|
+
return {
|
|
3536
|
+
run: candidate.number,
|
|
3537
|
+
version: candidate.version,
|
|
3538
|
+
revision: candidate.revision,
|
|
3539
|
+
timestamp: new Date(candidate.timestamp).toISOString(),
|
|
3540
|
+
candidate: { number: candidate.number },
|
|
3541
|
+
images: [{
|
|
3542
|
+
profile,
|
|
3543
|
+
id: candidate.number,
|
|
3544
|
+
name: name2,
|
|
3545
|
+
bytes: image.bytes,
|
|
3546
|
+
digest: image.sha256,
|
|
3547
|
+
cacheKind: "raw.zst",
|
|
3548
|
+
url: `${releaseOrigin}/${image.prefix}/${name2}`,
|
|
3549
|
+
rawBytes: image.raw_bytes,
|
|
3550
|
+
rawDigest: image.raw_sha256
|
|
3551
|
+
}]
|
|
3552
|
+
};
|
|
3553
|
+
});
|
|
3554
|
+
}
|
|
3555
|
+
async function discoverCandidates(signal) {
|
|
3556
|
+
return candidateCatalog(JSON.parse(await command([
|
|
3557
|
+
"curl",
|
|
3558
|
+
"--fail",
|
|
3559
|
+
"--silent",
|
|
3560
|
+
"--show-error",
|
|
3561
|
+
"--proto",
|
|
3562
|
+
"=https",
|
|
3563
|
+
"--header",
|
|
3564
|
+
"Cache-Control: no-cache",
|
|
3565
|
+
`${releaseOrigin}/candidates/index.json`
|
|
3566
|
+
], signal, { limit: 1024 ** 2 })));
|
|
3561
3567
|
}
|
|
3562
3568
|
var FlashBackend = class {
|
|
3563
|
-
constructor(demo2) {
|
|
3564
|
-
this.demo = demo2;
|
|
3565
|
-
}
|
|
3566
|
-
demo;
|
|
3567
|
-
demoInstalled = false;
|
|
3568
3569
|
requirePlatform() {
|
|
3569
3570
|
if (process.platform === "darwin") return platform;
|
|
3570
3571
|
if (process.platform === "linux") return platform2;
|
|
3571
|
-
throw new Error("Boo Flash supports macOS and Linux.
|
|
3572
|
+
throw new Error("Boo Flash supports macOS and Linux.");
|
|
3572
3573
|
}
|
|
3573
3574
|
get platformLabel() {
|
|
3574
|
-
return this.
|
|
3575
|
+
return this.requirePlatform().label;
|
|
3575
3576
|
}
|
|
3576
3577
|
get successTitle() {
|
|
3577
|
-
return this.
|
|
3578
|
+
return this.requirePlatform().successTitle;
|
|
3578
3579
|
}
|
|
3579
3580
|
get successDetail() {
|
|
3580
|
-
return this.
|
|
3581
|
+
return this.requirePlatform().successDetail;
|
|
3581
3582
|
}
|
|
3582
3583
|
async clearCache(signal) {
|
|
3583
|
-
if (this.demo) return "Demo only: no cached images or USB contents were changed.";
|
|
3584
3584
|
return clearCachedImages(signal);
|
|
3585
3585
|
}
|
|
3586
|
-
dependencies(
|
|
3587
|
-
|
|
3588
|
-
const setup = this.demo.startsWith("setup") || this.demo === "no-homebrew";
|
|
3589
|
-
return {
|
|
3590
|
-
missing: !setup || this.demoInstalled ? [] : this.demo === "setup-gh" ? includeGitHub ? ["gh"] : [] : this.demo === "setup-zstd" ? ["zstd"] : includeGitHub ? ["gh", "zstd"] : ["zstd"],
|
|
3591
|
-
installer: this.demo === "no-homebrew" ? null : "Homebrew",
|
|
3592
|
-
guidance: "Demo dependency guidance."
|
|
3593
|
-
};
|
|
3586
|
+
dependencies() {
|
|
3587
|
+
return this.requirePlatform().dependencies();
|
|
3594
3588
|
}
|
|
3595
3589
|
async installDependencies(approved, signal, terminal) {
|
|
3596
|
-
|
|
3597
|
-
return terminal(() => this.requirePlatform().installDependencies(approved, signal));
|
|
3598
|
-
}
|
|
3599
|
-
await delay(2e3, void 0, { signal });
|
|
3600
|
-
return terminal(async () => {
|
|
3601
|
-
process.stdout.write("\nDEMO dependency setup: no software is installed.\nSimulating Homebrew terminal handoff. Ctrl-C cancels and quits.\n");
|
|
3602
|
-
await delay(3e3);
|
|
3603
|
-
if (this.demo === "setup-interrupted") process.stdout.write("Simulated Homebrew interruption result, without signaling Boo Flash. Quitting.\n");
|
|
3604
|
-
if (signal.aborted || this.demo === "setup-interrupted") return "cancelled";
|
|
3605
|
-
if (this.demo === "setup-error") throw new Error("Simulated Homebrew failure. No software was installed. Resolve the reported issue, then refresh to retry.");
|
|
3606
|
-
this.demoInstalled = true;
|
|
3607
|
-
return "installed";
|
|
3608
|
-
});
|
|
3590
|
+
return terminal(() => this.requirePlatform().installDependencies(approved, signal));
|
|
3609
3591
|
}
|
|
3610
3592
|
async catalog(signal) {
|
|
3611
|
-
|
|
3612
|
-
await delay(350, void 0, { signal });
|
|
3613
|
-
return { run: 149, version: "0.1.0+149", revision: "9b7574859120add5a1a478bc7923aeb1629be4ba", timestamp: new Date(Date.now() - 10 * 60 * 1e3).toISOString(), images: profiles.map((profile, index) => ({
|
|
3614
|
-
profile,
|
|
3615
|
-
id: index,
|
|
3616
|
-
name: `demo-${profile}`,
|
|
3617
|
-
bytes: 1083197973,
|
|
3618
|
-
digest: "demo"
|
|
3619
|
-
})) };
|
|
3593
|
+
return discoverImages(signal);
|
|
3620
3594
|
}
|
|
3621
3595
|
async candidates(signal) {
|
|
3622
|
-
|
|
3623
|
-
const catalog = await this.catalog(signal);
|
|
3624
|
-
return this.demo === "empty" ? [] : [{
|
|
3625
|
-
...catalog,
|
|
3626
|
-
timestamp: new Date(Date.now() - 5 * 60 * 1e3).toISOString(),
|
|
3627
|
-
images: [catalog.images[0]],
|
|
3628
|
-
candidate: { number: 1 }
|
|
3629
|
-
}];
|
|
3596
|
+
return discoverCandidates(signal);
|
|
3630
3597
|
}
|
|
3631
3598
|
async disks(signal, staging = tmpdir4(), unmounted) {
|
|
3632
|
-
if (this.demo) {
|
|
3633
|
-
await delay(250, void 0, { signal });
|
|
3634
|
-
return this.demo === "empty" ? [] : [
|
|
3635
|
-
{ id: "demo-usb-a", name: "SanDisk Ultra USB 3.0", bytes: 32 * 1024 ** 3, identity: "demo-a" },
|
|
3636
|
-
{ id: "demo-usb-b", name: "Kingston DataTraveler", bytes: 64 * 1024 ** 3, identity: "demo-b" }
|
|
3637
|
-
];
|
|
3638
|
-
}
|
|
3639
3599
|
if (process.getuid?.() === 0) throw new Error(`Run Boo Flash on ${this.requirePlatform().id === "macos" ? "macOS" : "Linux"} as your normal user, not with sudo.`);
|
|
3640
3600
|
return this.requirePlatform().disks(signal, moduleDirectory, staging, unmounted);
|
|
3641
3601
|
}
|
|
3642
3602
|
async flash(catalog, image, disk, signal, update, authorize2) {
|
|
3643
|
-
if (this.demo) {
|
|
3644
|
-
if (!disk.id.startsWith("demo-") || image.digest !== "demo") throw new Error("Invalid demo selection.");
|
|
3645
|
-
for (const stage of ["Downloading", "Verifying", "Unmounting", "Writing", "Flushing", "Ejecting"]) {
|
|
3646
|
-
const total = stage === "Downloading" ? image.bytes : stage === "Writing" ? 8 * 1024 ** 3 : void 0;
|
|
3647
|
-
for (let i = 0; i <= (total ? 30 : 5); i++) {
|
|
3648
|
-
signal.throwIfAborted();
|
|
3649
|
-
update({
|
|
3650
|
-
stage,
|
|
3651
|
-
detail: "Simulated activity. No disk commands are run.",
|
|
3652
|
-
total,
|
|
3653
|
-
bytes: total ? Math.round(total * i / 30) : void 0,
|
|
3654
|
-
speed: total ? total / 3 : void 0
|
|
3655
|
-
});
|
|
3656
|
-
await delay(100, void 0, { signal });
|
|
3657
|
-
if (this.demo === "error" && stage === "Writing" && i === 13) throw new Error("Demo write failure. No disks were written or ejected. Refresh to choose again.");
|
|
3658
|
-
}
|
|
3659
|
-
}
|
|
3660
|
-
return;
|
|
3661
|
-
}
|
|
3662
3603
|
const platform3 = this.requirePlatform();
|
|
3663
3604
|
if (process.getuid?.() === 0) throw new Error(`Run Boo Flash on ${platform3.id === "macos" ? "macOS" : "Linux"} as your normal user, not with sudo.`);
|
|
3664
3605
|
if (!diskID3.test(disk.id) || !catalog.images.includes(image) || !profiles.includes(image.profile) || !positive(image.id) || !positive(image.bytes) || !sha256.test(image.digest)) throw new Error("Invalid flash selection.");
|
|
3665
3606
|
if (catalog.candidate) {
|
|
3666
|
-
if (!positive(catalog.run) || !/^[a-f0-9]{40}$/.test(catalog.revision) || image.cacheKind || image.name !== `boo-${
|
|
3667
|
-
const artifact = JSON.parse(await command(["gh", "api", "--hostname", "github.com", `repos/${repository}/actions/artifacts/${image.id}`], signal));
|
|
3668
|
-
if (artifact.id !== image.id || artifact.name !== image.name || artifact.workflow_run?.id !== catalog.run || artifact.expired !== false || !(Date.parse(artifact.expires_at) > Date.now()) || artifact.size_in_bytes !== image.bytes || artifact.digest !== `sha256:${image.digest}`) {
|
|
3669
|
-
throw new Error("Selected candidate artifact changed or expired. Refresh Candidates. No disk was written.");
|
|
3670
|
-
}
|
|
3607
|
+
if (!positive(catalog.run) || !/^[a-f0-9]{40}$/.test(catalog.revision) || image.id !== catalog.run || image.cacheKind !== "raw.zst" || image.name !== `boo-${catalog.version}-candidate-${catalog.revision.slice(0, 12)}-x86_64-${image.profile}.raw.zst` || image.url !== `${releaseOrigin}/candidates/${catalog.revision}/${image.profile}/${image.name}` || !positive(image.rawBytes) || !sha256.test(image.rawDigest ?? "")) throw new Error("Invalid candidate selection.");
|
|
3671
3608
|
} else {
|
|
3672
3609
|
const build = Number(catalog.version?.slice(catalog.version.lastIndexOf("+") + 1));
|
|
3673
3610
|
const name2 = `boo-${catalog.version}-x86_64-${image.profile}.raw.zst`;
|
|
3674
3611
|
if (!releaseVersion.test(catalog.version ?? "") || !positive(build) || catalog.run !== build || image.id !== build || !/^[a-f0-9]{40}$/.test(catalog.revision) || image.name !== name2 || image.cacheKind !== "raw.zst" || image.url !== `${releaseOrigin}/releases/${catalog.version}/${name2}` || !positive(image.rawBytes) || !sha256.test(image.rawDigest ?? "")) throw new Error("Invalid Boo release selection.");
|
|
3675
3612
|
}
|
|
3676
3613
|
const staging = await mkdtemp(join5(tmpdir4(), "boo-flash-"));
|
|
3677
|
-
const payload = join5(staging,
|
|
3614
|
+
const payload = join5(staging, "image.raw.zst");
|
|
3678
3615
|
let unretained = false;
|
|
3679
3616
|
let destructive = false;
|
|
3680
3617
|
try {
|
|
@@ -3682,17 +3619,17 @@ var FlashBackend = class {
|
|
|
3682
3619
|
let count = 0;
|
|
3683
3620
|
if (!await reuseArchive(image, payload, signal, (count2) => update({
|
|
3684
3621
|
stage: "Using cached image",
|
|
3685
|
-
detail: `Verifying cached ${catalog.candidate ? "
|
|
3622
|
+
detail: `Verifying cached ${catalog.candidate ? "Boo candidate" : `Boo ${catalog.version} image`} size and SHA-256; no download.`,
|
|
3686
3623
|
bytes: count2,
|
|
3687
3624
|
total: image.bytes
|
|
3688
3625
|
}))) {
|
|
3689
3626
|
const payloadFile = await open2(payload, "wx", 384);
|
|
3690
3627
|
const payloadHash = createHash2("sha256");
|
|
3691
3628
|
const started = performance.now();
|
|
3692
|
-
const detail = catalog.candidate ? "Selected candidate
|
|
3629
|
+
const detail = catalog.candidate ? "Selected candidate from images.os.boo." : `Boo ${catalog.version} from images.os.boo.`;
|
|
3693
3630
|
update({ stage: "Downloading", detail, bytes: 0, total: image.bytes });
|
|
3694
3631
|
try {
|
|
3695
|
-
const argv =
|
|
3632
|
+
const argv = ["curl", "--fail", "--silent", "--show-error", "--proto", "=https", image.url];
|
|
3696
3633
|
await command(argv, signal, {
|
|
3697
3634
|
limit: image.bytes,
|
|
3698
3635
|
consume: async (chunk) => {
|
|
@@ -3712,60 +3649,17 @@ var FlashBackend = class {
|
|
|
3712
3649
|
await payloadFile.close();
|
|
3713
3650
|
}
|
|
3714
3651
|
if (count !== image.bytes || payloadHash.digest("hex") !== image.digest) {
|
|
3715
|
-
throw new Error(`${catalog.candidate ? "
|
|
3652
|
+
throw new Error(`${catalog.candidate ? "Candidate" : "Release"} image size or SHA-256 mismatch. No disk was written.`);
|
|
3716
3653
|
}
|
|
3717
3654
|
unretained = true;
|
|
3718
3655
|
await publishArchive(image, payload, signal);
|
|
3719
3656
|
unretained = false;
|
|
3720
3657
|
}
|
|
3721
3658
|
signal.throwIfAborted();
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
update({ stage: "Verifying", detail: "Checking GitHub ZIP digest, build identity and image checksums." });
|
|
3727
|
-
const names = (await command(["unzip", "-Z1", payload], signal)).trim().split("\n");
|
|
3728
|
-
for (const name2 of ["build-info.json", "SHA256SUMS", "SHA256SUMS.raw"]) {
|
|
3729
|
-
if (names.filter((n) => n === name2).length !== 1) throw new Error(`Archive is missing a unique ${name2}.`);
|
|
3730
|
-
}
|
|
3731
|
-
const extractText = (name2) => command(["unzip", "-p", payload, name2], signal, { limit: 1024 ** 2 });
|
|
3732
|
-
const metadata = JSON.parse(await extractText("build-info.json"));
|
|
3733
|
-
const basename2 = `boo-${image.profile}-x86_64.raw.zst`;
|
|
3734
|
-
if (metadata.semantic_version !== void 0 && (!semanticVersion.test(metadata.semantic_version) || metadata.build_number !== null || metadata.version !== metadata.semantic_version)) {
|
|
3735
|
-
throw new Error("Build metadata has an invalid candidate image version.");
|
|
3736
|
-
}
|
|
3737
|
-
if (metadata.image !== basename2 || names.filter((name2) => name2 === basename2).length !== 1 || metadata.schema !== 1 || !repositoryIdentities.has(metadata.repository) || metadata.revision !== catalog.revision || metadata.variant !== image.profile || metadata.source_state !== "clean" || !positive(metadata.compressed_bytes) || metadata.compressed_bytes > image.bytes || !positive(metadata.raw_apparent_bytes) || !sha256.test(metadata.compressed_sha256) || !sha256.test(metadata.raw_sha256)) {
|
|
3738
|
-
throw new Error("Build metadata does not match the selected candidate.");
|
|
3739
|
-
}
|
|
3740
|
-
if (metadata.candidate?.resolved_sha !== catalog.revision || metadata.candidate?.profile !== image.profile || metadata.candidate?.qualification !== "build-only" || typeof metadata.candidate?.source_ref !== "string" || !metadata.candidate.source_ref.trim()) {
|
|
3741
|
-
throw new Error("Candidate source metadata does not match the selected artifact.");
|
|
3742
|
-
}
|
|
3743
|
-
if ((await extractText("SHA256SUMS")).trim() !== `${metadata.compressed_sha256} ${basename2}` || (await extractText("SHA256SUMS.raw")).trim() !== `${metadata.raw_sha256} ${basename2.slice(0, -4)}`) {
|
|
3744
|
-
throw new Error("Image checksum manifests disagree with build metadata.");
|
|
3745
|
-
}
|
|
3746
|
-
compressed = join5(staging, basename2);
|
|
3747
|
-
const file = await open2(compressed, "wx", 384);
|
|
3748
|
-
const hash = createHash2("sha256");
|
|
3749
|
-
count = 0;
|
|
3750
|
-
try {
|
|
3751
|
-
await command(["unzip", "-p", payload, basename2], signal, {
|
|
3752
|
-
limit: metadata.compressed_bytes,
|
|
3753
|
-
consume: async (chunk) => {
|
|
3754
|
-
hash.update(chunk);
|
|
3755
|
-
await file.writeFile(chunk);
|
|
3756
|
-
count += chunk.length;
|
|
3757
|
-
update({ stage: "Verifying", detail: "Extracting only the selected image; checking compressed SHA-256.", bytes: count, total: metadata.compressed_bytes });
|
|
3758
|
-
}
|
|
3759
|
-
});
|
|
3760
|
-
} finally {
|
|
3761
|
-
await file.close();
|
|
3762
|
-
}
|
|
3763
|
-
if (count !== metadata.compressed_bytes || hash.digest("hex") !== metadata.compressed_sha256) throw new Error("Compressed image size or SHA-256 mismatch.");
|
|
3764
|
-
rawBytes = metadata.raw_apparent_bytes;
|
|
3765
|
-
rawDigest = metadata.raw_sha256;
|
|
3766
|
-
} else {
|
|
3767
|
-
update({ stage: "Verifying", detail: `Boo ${catalog.version} release metadata and compressed SHA-256 verified.` });
|
|
3768
|
-
}
|
|
3659
|
+
const compressed = payload;
|
|
3660
|
+
const rawBytes = image.rawBytes;
|
|
3661
|
+
const rawDigest = image.rawDigest;
|
|
3662
|
+
update({ stage: "Verifying", detail: `${catalog.candidate ? "Boo candidate" : `Boo ${catalog.version}`} metadata and compressed SHA-256 verified.` });
|
|
3769
3663
|
if (!positive(rawBytes) || !sha256.test(rawDigest ?? "")) throw new Error("Image raw-stream metadata is invalid.");
|
|
3770
3664
|
if (rawBytes > disk.bytes) throw new Error(`Image needs ${bytes(rawBytes)}; the selected USB is too small.`);
|
|
3771
3665
|
const revalidate = async (unmounted = false) => {
|
|
@@ -3830,7 +3724,6 @@ var FlashBackend = class {
|
|
|
3830
3724
|
}
|
|
3831
3725
|
}
|
|
3832
3726
|
async authorize(signal) {
|
|
3833
|
-
if (this.demo) return;
|
|
3834
3727
|
if (process.getuid?.() === 0) throw new Error("Run Boo Flash as your normal user, not with sudo.");
|
|
3835
3728
|
await this.requirePlatform().authorize(signal);
|
|
3836
3729
|
}
|
|
@@ -3885,7 +3778,12 @@ function App(props) {
|
|
|
3885
3778
|
const visible = () => dimensions().width >= 40 && dimensions().height >= 16;
|
|
3886
3779
|
const options = () => screen() === "profile" ? 5 : screen() === "cleared" ? 1 : screen() === "candidates" ? Math.max(1, candidates().length) : screen() === "disks" ? disks3().length : 2;
|
|
3887
3780
|
const percent = () => progress().total ? Math.min(100, Math.floor((progress().bytes ?? 0) / progress().total * 100)) : void 0;
|
|
3888
|
-
const path = (d) =>
|
|
3781
|
+
const path = (d) => `/dev/${d.id}`;
|
|
3782
|
+
const selection = () => {
|
|
3783
|
+
const c = catalog(), i = image();
|
|
3784
|
+
if (!c || !i) return "";
|
|
3785
|
+
return `Boo ${c.version}${c.candidate ? ` candidate #${c.candidate.number}` : ""} / ${i.profile.toUpperCase()}${c.candidate ? ` / ${c.revision.slice(0, 7)}` : ""}`;
|
|
3786
|
+
};
|
|
3889
3787
|
const operation = (work) => {
|
|
3890
3788
|
controller = new AbortController();
|
|
3891
3789
|
setStopping(false);
|
|
@@ -3896,8 +3794,8 @@ function App(props) {
|
|
|
3896
3794
|
} catch (e) {
|
|
3897
3795
|
if (!closing) {
|
|
3898
3796
|
const setup = screen() === "installing";
|
|
3899
|
-
setError(controller.signal.aborted && setup ? "Setup cancelled. Refresh to check what is still missing." :
|
|
3900
|
-
if (setup) setDependencies(props.backend.dependencies(
|
|
3797
|
+
setError(controller.signal.aborted && setup ? "Setup cancelled. Refresh to check what is still missing." : e instanceof Error ? e.message : "Operation failed. Refresh and try again.");
|
|
3798
|
+
if (setup) setDependencies(props.backend.dependencies());
|
|
3901
3799
|
setScreen(setup ? "setup" : "error");
|
|
3902
3800
|
setCursor(0);
|
|
3903
3801
|
}
|
|
@@ -3921,6 +3819,7 @@ function App(props) {
|
|
|
3921
3819
|
const refresh = () => {
|
|
3922
3820
|
setError("");
|
|
3923
3821
|
setCatalog(void 0);
|
|
3822
|
+
setImage(void 0);
|
|
3924
3823
|
setDisk(void 0);
|
|
3925
3824
|
setScreen("profile");
|
|
3926
3825
|
setCursor(0);
|
|
@@ -3932,7 +3831,7 @@ function App(props) {
|
|
|
3932
3831
|
setCursor(0);
|
|
3933
3832
|
setScreen("candidates");
|
|
3934
3833
|
operation(async (signal) => {
|
|
3935
|
-
const state = props.backend.dependencies(
|
|
3834
|
+
const state = props.backend.dependencies();
|
|
3936
3835
|
if (state.missing.length) {
|
|
3937
3836
|
setDependencies(state);
|
|
3938
3837
|
setScreen("setup");
|
|
@@ -3950,6 +3849,7 @@ function App(props) {
|
|
|
3950
3849
|
if (state.missing.length) {
|
|
3951
3850
|
setDependencies(state);
|
|
3952
3851
|
setCatalog(void 0);
|
|
3852
|
+
setImage(void 0);
|
|
3953
3853
|
setScreen("setup");
|
|
3954
3854
|
setCursor(0);
|
|
3955
3855
|
return;
|
|
@@ -4053,6 +3953,9 @@ function App(props) {
|
|
|
4053
3953
|
await props.backend.flash(catalog(), image(), disk(), signal, setProgress, async () => {
|
|
4054
3954
|
renderer.suspend();
|
|
4055
3955
|
try {
|
|
3956
|
+
process.stdout.write(`
|
|
3957
|
+
${selection()}
|
|
3958
|
+
`);
|
|
4056
3959
|
await props.backend.authorize(signal);
|
|
4057
3960
|
} finally {
|
|
4058
3961
|
renderer.resume();
|
|
@@ -4134,7 +4037,7 @@ function App(props) {
|
|
|
4134
4037
|
return _el$;
|
|
4135
4038
|
})();
|
|
4136
4039
|
return (() => {
|
|
4137
|
-
var _el$4 = createElement("box"), _el$5 = createElement("box"), _el$6 = createElement("box"), _el$7 = createElement("text"), _el$9 = createElement("text"), _el$0 = createElement("box"), _el$1 = createElement("box"), _el$
|
|
4040
|
+
var _el$4 = createElement("box"), _el$5 = createElement("box"), _el$6 = createElement("box"), _el$7 = createElement("text"), _el$9 = createElement("text"), _el$0 = createElement("box"), _el$1 = createElement("box"), _el$80 = createElement("text");
|
|
4138
4041
|
insertNode(_el$4, _el$5);
|
|
4139
4042
|
setProp(_el$4, "width", "100%");
|
|
4140
4043
|
setProp(_el$4, "height", "100%");
|
|
@@ -4143,7 +4046,7 @@ function App(props) {
|
|
|
4143
4046
|
insertNode(_el$5, _el$6);
|
|
4144
4047
|
insertNode(_el$5, _el$0);
|
|
4145
4048
|
insertNode(_el$5, _el$1);
|
|
4146
|
-
insertNode(_el$5, _el$
|
|
4049
|
+
insertNode(_el$5, _el$80);
|
|
4147
4050
|
setProp(_el$5, "border", true);
|
|
4148
4051
|
setProp(_el$5, "borderStyle", "single");
|
|
4149
4052
|
setProp(_el$5, "flexDirection", "column");
|
|
@@ -4167,56 +4070,67 @@ function App(props) {
|
|
|
4167
4070
|
},
|
|
4168
4071
|
get fallback() {
|
|
4169
4072
|
return (() => {
|
|
4170
|
-
var _el$
|
|
4171
|
-
insertNode(_el$
|
|
4172
|
-
effect((_$p) => setProp(_el$
|
|
4173
|
-
return _el$
|
|
4073
|
+
var _el$81 = createElement("text");
|
|
4074
|
+
insertNode(_el$81, createTextNode(`Enlarge the terminal to show the full choices and erase warning. Q quits.`));
|
|
4075
|
+
effect((_$p) => setProp(_el$81, "fg", palette.warning, _$p));
|
|
4076
|
+
return _el$81;
|
|
4174
4077
|
})();
|
|
4175
4078
|
},
|
|
4176
4079
|
get children() {
|
|
4177
4080
|
return [createComponent2(Show, {
|
|
4081
|
+
get when() {
|
|
4082
|
+
return selection();
|
|
4083
|
+
},
|
|
4084
|
+
get children() {
|
|
4085
|
+
var _el$10 = createElement("text");
|
|
4086
|
+
setProp(_el$10, "flexShrink", 0);
|
|
4087
|
+
insert(_el$10, selection);
|
|
4088
|
+
effect((_$p) => setProp(_el$10, "fg", palette.foreground, _$p));
|
|
4089
|
+
return _el$10;
|
|
4090
|
+
}
|
|
4091
|
+
}), createComponent2(Show, {
|
|
4178
4092
|
get when() {
|
|
4179
4093
|
return screen() === "profile";
|
|
4180
4094
|
},
|
|
4181
4095
|
get children() {
|
|
4182
4096
|
return [(() => {
|
|
4183
|
-
var _el$
|
|
4184
|
-
insertNode(_el$
|
|
4097
|
+
var _el$11 = createElement("text");
|
|
4098
|
+
insertNode(_el$11, createTextNode(`Choose the target computer's GPU`));
|
|
4185
4099
|
effect((_p$) => {
|
|
4186
4100
|
var _v$5 = palette.foreground, _v$6 = TextAttributes2.BOLD;
|
|
4187
|
-
_v$5 !== _p$.e && (_p$.e = setProp(_el$
|
|
4188
|
-
_v$6 !== _p$.t && (_p$.t = setProp(_el$
|
|
4101
|
+
_v$5 !== _p$.e && (_p$.e = setProp(_el$11, "fg", _v$5, _p$.e));
|
|
4102
|
+
_v$6 !== _p$.t && (_p$.t = setProp(_el$11, "attributes", _v$6, _p$.t));
|
|
4189
4103
|
return _p$;
|
|
4190
4104
|
}, {
|
|
4191
4105
|
e: void 0,
|
|
4192
4106
|
t: void 0
|
|
4193
4107
|
});
|
|
4194
|
-
return _el$
|
|
4108
|
+
return _el$11;
|
|
4195
4109
|
})(), (() => {
|
|
4196
|
-
var _el$
|
|
4197
|
-
insert(_el$
|
|
4110
|
+
var _el$13 = createElement("text");
|
|
4111
|
+
insert(_el$13, (() => {
|
|
4198
4112
|
var _c$ = memo2(() => !!loading());
|
|
4199
4113
|
return () => _c$() ? `${spinner()} Finding latest Boo release...` : memo2(() => !!catalog())() ? `Boo ${catalog().version} / ${catalog().revision.slice(0, 7)} / ${imageTime(catalog().timestamp, now())}` : "Dependencies needed. Enter to set up.";
|
|
4200
4114
|
})());
|
|
4201
|
-
effect((_$p) => setProp(_el$
|
|
4202
|
-
return _el$
|
|
4115
|
+
effect((_$p) => setProp(_el$13, "fg", palette.muted, _$p));
|
|
4116
|
+
return _el$13;
|
|
4203
4117
|
})(), (() => {
|
|
4204
|
-
var _el$
|
|
4205
|
-
setProp(_el$
|
|
4206
|
-
setProp(_el$
|
|
4207
|
-
setProp(_el$
|
|
4208
|
-
insert(_el$
|
|
4118
|
+
var _el$14 = createElement("box");
|
|
4119
|
+
setProp(_el$14, "gap", 0);
|
|
4120
|
+
setProp(_el$14, "marginBottom", 1);
|
|
4121
|
+
setProp(_el$14, "flexShrink", 0);
|
|
4122
|
+
insert(_el$14, createComponent2(For, {
|
|
4209
4123
|
each: profiles,
|
|
4210
4124
|
children: (profile, index) => row(profile.toUpperCase(), profile === "nvidia" ? "NVIDIA graphics" : `${profile === "intel" ? "Intel" : "AMD Radeon"} graphics`, index())
|
|
4211
4125
|
}), null);
|
|
4212
|
-
insert(_el$
|
|
4213
|
-
insert(_el$
|
|
4214
|
-
return _el$13;
|
|
4215
|
-
})(), (() => {
|
|
4216
|
-
var _el$14 = createElement("text");
|
|
4217
|
-
insertNode(_el$14, createTextNode(`All images support Intel and AMD x86_64 CPUs.`));
|
|
4218
|
-
effect((_$p) => setProp(_el$14, "fg", palette.muted, _$p));
|
|
4126
|
+
insert(_el$14, () => row("Candidates", "", 3), null);
|
|
4127
|
+
insert(_el$14, () => row("Clear cached images", "", 4), null);
|
|
4219
4128
|
return _el$14;
|
|
4129
|
+
})(), (() => {
|
|
4130
|
+
var _el$15 = createElement("text");
|
|
4131
|
+
insertNode(_el$15, createTextNode(`All images support Intel and AMD x86_64 CPUs.`));
|
|
4132
|
+
effect((_$p) => setProp(_el$15, "fg", palette.muted, _$p));
|
|
4133
|
+
return _el$15;
|
|
4220
4134
|
})()];
|
|
4221
4135
|
}
|
|
4222
4136
|
}), createComponent2(Show, {
|
|
@@ -4225,34 +4139,34 @@ function App(props) {
|
|
|
4225
4139
|
},
|
|
4226
4140
|
get children() {
|
|
4227
4141
|
return [(() => {
|
|
4228
|
-
var _el$
|
|
4229
|
-
insertNode(_el$
|
|
4142
|
+
var _el$17 = createElement("text");
|
|
4143
|
+
insertNode(_el$17, createTextNode(`Clear cached images?`));
|
|
4230
4144
|
effect((_p$) => {
|
|
4231
4145
|
var _v$7 = palette.warning, _v$8 = TextAttributes2.BOLD;
|
|
4232
|
-
_v$7 !== _p$.e && (_p$.e = setProp(_el$
|
|
4233
|
-
_v$8 !== _p$.t && (_p$.t = setProp(_el$
|
|
4146
|
+
_v$7 !== _p$.e && (_p$.e = setProp(_el$17, "fg", _v$7, _p$.e));
|
|
4147
|
+
_v$8 !== _p$.t && (_p$.t = setProp(_el$17, "attributes", _v$8, _p$.t));
|
|
4234
4148
|
return _p$;
|
|
4235
4149
|
}, {
|
|
4236
4150
|
e: void 0,
|
|
4237
4151
|
t: void 0
|
|
4238
4152
|
});
|
|
4239
|
-
return _el$
|
|
4153
|
+
return _el$17;
|
|
4240
4154
|
})(), (() => {
|
|
4241
|
-
var _el$
|
|
4242
|
-
insertNode(_el$
|
|
4243
|
-
effect((_$p) => setProp(_el$
|
|
4244
|
-
return _el$
|
|
4155
|
+
var _el$19 = createElement("text");
|
|
4156
|
+
insertNode(_el$19, createTextNode(`Removes downloaded archives only, NOT USB contents. Active flashes are unaffected.`));
|
|
4157
|
+
effect((_$p) => setProp(_el$19, "fg", palette.foreground, _$p));
|
|
4158
|
+
return _el$19;
|
|
4245
4159
|
})(), (() => {
|
|
4246
|
-
var _el$
|
|
4247
|
-
insertNode(_el$
|
|
4248
|
-
effect((_$p) => setProp(_el$
|
|
4249
|
-
return _el$
|
|
4160
|
+
var _el$21 = createElement("text");
|
|
4161
|
+
insertNode(_el$21, createTextNode(`Images will download again when needed. Pending downloads may still finish and be cached.`));
|
|
4162
|
+
effect((_$p) => setProp(_el$21, "fg", palette.muted, _$p));
|
|
4163
|
+
return _el$21;
|
|
4250
4164
|
})(), (() => {
|
|
4251
|
-
var _el$
|
|
4252
|
-
insert(_el$
|
|
4253
|
-
insert(_el$
|
|
4254
|
-
effect((_$p) => setProp(_el$
|
|
4255
|
-
return _el$
|
|
4165
|
+
var _el$23 = createElement("box");
|
|
4166
|
+
insert(_el$23, () => row("Go back", "", 0), null);
|
|
4167
|
+
insert(_el$23, () => row(loading() ? "Clearing..." : "Clear cached images", "", 1, true), null);
|
|
4168
|
+
effect((_$p) => setProp(_el$23, "gap", tight() ? 0 : 1, _$p));
|
|
4169
|
+
return _el$23;
|
|
4256
4170
|
})()];
|
|
4257
4171
|
}
|
|
4258
4172
|
}), createComponent2(Show, {
|
|
@@ -4261,23 +4175,23 @@ function App(props) {
|
|
|
4261
4175
|
},
|
|
4262
4176
|
get children() {
|
|
4263
4177
|
return [(() => {
|
|
4264
|
-
var _el$
|
|
4265
|
-
insertNode(_el$
|
|
4178
|
+
var _el$24 = createElement("text");
|
|
4179
|
+
insertNode(_el$24, createTextNode(`Cache cleared`));
|
|
4266
4180
|
effect((_p$) => {
|
|
4267
4181
|
var _v$9 = palette.success, _v$0 = TextAttributes2.BOLD;
|
|
4268
|
-
_v$9 !== _p$.e && (_p$.e = setProp(_el$
|
|
4269
|
-
_v$0 !== _p$.t && (_p$.t = setProp(_el$
|
|
4182
|
+
_v$9 !== _p$.e && (_p$.e = setProp(_el$24, "fg", _v$9, _p$.e));
|
|
4183
|
+
_v$0 !== _p$.t && (_p$.t = setProp(_el$24, "attributes", _v$0, _p$.t));
|
|
4270
4184
|
return _p$;
|
|
4271
4185
|
}, {
|
|
4272
4186
|
e: void 0,
|
|
4273
4187
|
t: void 0
|
|
4274
4188
|
});
|
|
4275
|
-
return _el$
|
|
4189
|
+
return _el$24;
|
|
4276
4190
|
})(), (() => {
|
|
4277
|
-
var _el$
|
|
4278
|
-
insert(_el$
|
|
4279
|
-
effect((_$p) => setProp(_el$
|
|
4280
|
-
return _el$
|
|
4191
|
+
var _el$26 = createElement("text");
|
|
4192
|
+
insert(_el$26, notice);
|
|
4193
|
+
effect((_$p) => setProp(_el$26, "fg", palette.foreground, _$p));
|
|
4194
|
+
return _el$26;
|
|
4281
4195
|
})(), memo2(() => row("Go back", "", 0))];
|
|
4282
4196
|
}
|
|
4283
4197
|
}), createComponent2(Show, {
|
|
@@ -4286,34 +4200,29 @@ function App(props) {
|
|
|
4286
4200
|
},
|
|
4287
4201
|
get children() {
|
|
4288
4202
|
return [(() => {
|
|
4289
|
-
var _el$
|
|
4290
|
-
insertNode(_el$
|
|
4203
|
+
var _el$27 = createElement("text");
|
|
4204
|
+
insertNode(_el$27, createTextNode(`Candidates`));
|
|
4291
4205
|
effect((_p$) => {
|
|
4292
4206
|
var _v$1 = palette.foreground, _v$10 = TextAttributes2.BOLD;
|
|
4293
|
-
_v$1 !== _p$.e && (_p$.e = setProp(_el$
|
|
4294
|
-
_v$10 !== _p$.t && (_p$.t = setProp(_el$
|
|
4207
|
+
_v$1 !== _p$.e && (_p$.e = setProp(_el$27, "fg", _v$1, _p$.e));
|
|
4208
|
+
_v$10 !== _p$.t && (_p$.t = setProp(_el$27, "attributes", _v$10, _p$.t));
|
|
4295
4209
|
return _p$;
|
|
4296
4210
|
}, {
|
|
4297
4211
|
e: void 0,
|
|
4298
4212
|
t: void 0
|
|
4299
4213
|
});
|
|
4300
|
-
return _el$
|
|
4301
|
-
})(), (() => {
|
|
4302
|
-
var _el$28 = createElement("text");
|
|
4303
|
-
insertNode(_el$28, createTextNode(`Build-only; not boot/install/hardware qualified.`));
|
|
4304
|
-
effect((_$p) => setProp(_el$28, "fg", palette.warning, _$p));
|
|
4305
|
-
return _el$28;
|
|
4214
|
+
return _el$27;
|
|
4306
4215
|
})(), createComponent2(Show, {
|
|
4307
4216
|
get when() {
|
|
4308
4217
|
return !loading();
|
|
4309
4218
|
},
|
|
4310
4219
|
get fallback() {
|
|
4311
4220
|
return (() => {
|
|
4312
|
-
var _el$
|
|
4313
|
-
insertNode(_el$
|
|
4314
|
-
insert(_el$
|
|
4315
|
-
effect((_$p) => setProp(_el$
|
|
4316
|
-
return _el$
|
|
4221
|
+
var _el$83 = createElement("text"), _el$84 = createTextNode(` Finding completed candidates...`);
|
|
4222
|
+
insertNode(_el$83, _el$84);
|
|
4223
|
+
insert(_el$83, spinner, _el$84);
|
|
4224
|
+
effect((_$p) => setProp(_el$83, "fg", palette.muted, _$p));
|
|
4225
|
+
return _el$83;
|
|
4317
4226
|
})();
|
|
4318
4227
|
},
|
|
4319
4228
|
get children() {
|
|
@@ -4323,31 +4232,31 @@ function App(props) {
|
|
|
4323
4232
|
},
|
|
4324
4233
|
get fallback() {
|
|
4325
4234
|
return [(() => {
|
|
4326
|
-
var _el$
|
|
4327
|
-
insertNode(_el$
|
|
4328
|
-
effect((_$p) => setProp(_el$
|
|
4329
|
-
return _el$
|
|
4235
|
+
var _el$85 = createElement("text");
|
|
4236
|
+
insertNode(_el$85, createTextNode(`No completed candidates available`));
|
|
4237
|
+
effect((_$p) => setProp(_el$85, "fg", palette.muted, _$p));
|
|
4238
|
+
return _el$85;
|
|
4330
4239
|
})(), memo2(() => row("Go back", "", 0))];
|
|
4331
4240
|
},
|
|
4332
4241
|
get children() {
|
|
4333
4242
|
return [(() => {
|
|
4334
|
-
var _el$
|
|
4335
|
-
setProp(_el$
|
|
4336
|
-
insert(_el$
|
|
4243
|
+
var _el$29 = createElement("box");
|
|
4244
|
+
setProp(_el$29, "gap", 0);
|
|
4245
|
+
insert(_el$29, createComponent2(For, {
|
|
4337
4246
|
get each() {
|
|
4338
4247
|
return candidates().slice(Math.max(0, cursor() - 2), Math.max(3, cursor() + 1));
|
|
4339
4248
|
},
|
|
4340
4249
|
children: (c, index) => row(`${c.images[0].profile.toUpperCase()} ${c.revision.slice(0, 7)} #${c.candidate.number}`, imageTime(c.timestamp, now()), index() + Math.max(0, cursor() - 2), false, true)
|
|
4341
4250
|
}));
|
|
4342
|
-
return _el$
|
|
4251
|
+
return _el$29;
|
|
4343
4252
|
})(), (() => {
|
|
4344
|
-
var _el$
|
|
4345
|
-
insertNode(_el$
|
|
4346
|
-
insertNode(_el$
|
|
4347
|
-
insert(_el$
|
|
4348
|
-
insert(_el$
|
|
4349
|
-
effect((_$p) => setProp(_el$
|
|
4350
|
-
return _el$
|
|
4253
|
+
var _el$30 = createElement("text"), _el$31 = createTextNode(` of `), _el$32 = createTextNode(` candidates / Enter to choose`);
|
|
4254
|
+
insertNode(_el$30, _el$31);
|
|
4255
|
+
insertNode(_el$30, _el$32);
|
|
4256
|
+
insert(_el$30, () => cursor() + 1, _el$31);
|
|
4257
|
+
insert(_el$30, () => candidates().length, _el$32);
|
|
4258
|
+
effect((_$p) => setProp(_el$30, "fg", palette.muted, _$p));
|
|
4259
|
+
return _el$30;
|
|
4351
4260
|
})()];
|
|
4352
4261
|
}
|
|
4353
4262
|
});
|
|
@@ -4360,71 +4269,61 @@ function App(props) {
|
|
|
4360
4269
|
},
|
|
4361
4270
|
get children() {
|
|
4362
4271
|
return [(() => {
|
|
4363
|
-
var _el$
|
|
4364
|
-
insertNode(_el$
|
|
4272
|
+
var _el$33 = createElement("text");
|
|
4273
|
+
insertNode(_el$33, createTextNode(`Set up required tools`));
|
|
4365
4274
|
effect((_p$) => {
|
|
4366
4275
|
var _v$11 = palette.accent, _v$12 = TextAttributes2.BOLD;
|
|
4367
|
-
_v$11 !== _p$.e && (_p$.e = setProp(_el$
|
|
4368
|
-
_v$12 !== _p$.t && (_p$.t = setProp(_el$
|
|
4276
|
+
_v$11 !== _p$.e && (_p$.e = setProp(_el$33, "fg", _v$11, _p$.e));
|
|
4277
|
+
_v$12 !== _p$.t && (_p$.t = setProp(_el$33, "attributes", _v$12, _p$.t));
|
|
4369
4278
|
return _p$;
|
|
4370
4279
|
}, {
|
|
4371
4280
|
e: void 0,
|
|
4372
4281
|
t: void 0
|
|
4373
4282
|
});
|
|
4374
|
-
return _el$
|
|
4283
|
+
return _el$33;
|
|
4375
4284
|
})(), (() => {
|
|
4376
|
-
var _el$
|
|
4377
|
-
insertNode(_el$
|
|
4378
|
-
insert(_el$
|
|
4379
|
-
effect((_$p) => setProp(_el$
|
|
4380
|
-
return _el$
|
|
4285
|
+
var _el$35 = createElement("text"), _el$36 = createTextNode(`Missing: `);
|
|
4286
|
+
insertNode(_el$35, _el$36);
|
|
4287
|
+
insert(_el$35, () => dependencies3().missing.join(", "), null);
|
|
4288
|
+
effect((_$p) => setProp(_el$35, "fg", palette.foreground, _$p));
|
|
4289
|
+
return _el$35;
|
|
4381
4290
|
})(), createComponent2(Show, {
|
|
4382
4291
|
get when() {
|
|
4383
4292
|
return !error();
|
|
4384
4293
|
},
|
|
4385
4294
|
get fallback() {
|
|
4386
4295
|
return (() => {
|
|
4387
|
-
var _el$
|
|
4388
|
-
insert(_el$
|
|
4389
|
-
effect((_$p) => setProp(_el$
|
|
4390
|
-
return _el$
|
|
4296
|
+
var _el$87 = createElement("text");
|
|
4297
|
+
insert(_el$87, error);
|
|
4298
|
+
effect((_$p) => setProp(_el$87, "fg", palette.warning, _$p));
|
|
4299
|
+
return _el$87;
|
|
4391
4300
|
})();
|
|
4392
4301
|
},
|
|
4393
4302
|
get children() {
|
|
4394
|
-
var _el$
|
|
4395
|
-
insert(_el$
|
|
4303
|
+
var _el$37 = createElement("text");
|
|
4304
|
+
insert(_el$37, (() => {
|
|
4396
4305
|
var _c$2 = memo2(() => !!dependencies3().installer);
|
|
4397
4306
|
return () => _c$2() ? `${dependencies3().installer} will install ${dependencies3().missing.join(" and ")} and required dependencies, then continue.` : dependencies3().guidance;
|
|
4398
4307
|
})());
|
|
4399
|
-
effect((_$p) => setProp(_el$
|
|
4400
|
-
return _el$
|
|
4308
|
+
effect((_$p) => setProp(_el$37, "fg", palette.muted, _$p));
|
|
4309
|
+
return _el$37;
|
|
4401
4310
|
}
|
|
4402
4311
|
}), createComponent2(Show, {
|
|
4403
4312
|
get when() {
|
|
4404
4313
|
return !tight();
|
|
4405
4314
|
},
|
|
4406
4315
|
get children() {
|
|
4407
|
-
var _el$
|
|
4408
|
-
insert(_el$
|
|
4409
|
-
effect((_$p) => setProp(_el$
|
|
4410
|
-
return _el$
|
|
4411
|
-
}
|
|
4412
|
-
}), createComponent2(Show, {
|
|
4413
|
-
get when() {
|
|
4414
|
-
return props.backend.demo;
|
|
4415
|
-
},
|
|
4416
|
-
get children() {
|
|
4417
|
-
var _el$40 = createElement("text");
|
|
4418
|
-
insertNode(_el$40, createTextNode(`Setup simulation; no software installed.`));
|
|
4419
|
-
effect((_$p) => setProp(_el$40, "fg", palette.warning, _$p));
|
|
4420
|
-
return _el$40;
|
|
4316
|
+
var _el$38 = createElement("text");
|
|
4317
|
+
insert(_el$38, () => dependencies3().installer ? "Uses the ordinary terminal. Ctrl-C cancels and quits." : "Boo Flash will not change system packages on this platform.");
|
|
4318
|
+
effect((_$p) => setProp(_el$38, "fg", palette.muted, _$p));
|
|
4319
|
+
return _el$38;
|
|
4421
4320
|
}
|
|
4422
4321
|
}), (() => {
|
|
4423
|
-
var _el$
|
|
4424
|
-
insert(_el$
|
|
4425
|
-
insert(_el$
|
|
4426
|
-
effect((_$p) => setProp(_el$
|
|
4427
|
-
return _el$
|
|
4322
|
+
var _el$39 = createElement("box");
|
|
4323
|
+
insert(_el$39, () => row("Go back", "", 0), null);
|
|
4324
|
+
insert(_el$39, () => row(dependencies3().installer ? `Install ${dependencies3().missing.join(" + ")}` : "Refresh", "", 1), null);
|
|
4325
|
+
effect((_$p) => setProp(_el$39, "gap", tight() ? 0 : 1, _$p));
|
|
4326
|
+
return _el$39;
|
|
4428
4327
|
})()];
|
|
4429
4328
|
}
|
|
4430
4329
|
}), createComponent2(Show, {
|
|
@@ -4433,44 +4332,34 @@ function App(props) {
|
|
|
4433
4332
|
},
|
|
4434
4333
|
get children() {
|
|
4435
4334
|
return [(() => {
|
|
4436
|
-
var _el$
|
|
4437
|
-
insertNode(_el$
|
|
4438
|
-
insert(_el$
|
|
4439
|
-
insert(_el$
|
|
4335
|
+
var _el$40 = createElement("text"), _el$41 = createTextNode(` `);
|
|
4336
|
+
insertNode(_el$40, _el$41);
|
|
4337
|
+
insert(_el$40, spinner, _el$41);
|
|
4338
|
+
insert(_el$40, () => stopping() ? "Waiting for setup to stop..." : "Installing required tools", null);
|
|
4440
4339
|
effect((_p$) => {
|
|
4441
4340
|
var _v$13 = palette.accent, _v$14 = TextAttributes2.BOLD;
|
|
4442
|
-
_v$13 !== _p$.e && (_p$.e = setProp(_el$
|
|
4443
|
-
_v$14 !== _p$.t && (_p$.t = setProp(_el$
|
|
4341
|
+
_v$13 !== _p$.e && (_p$.e = setProp(_el$40, "fg", _v$13, _p$.e));
|
|
4342
|
+
_v$14 !== _p$.t && (_p$.t = setProp(_el$40, "attributes", _v$14, _p$.t));
|
|
4444
4343
|
return _p$;
|
|
4445
4344
|
}, {
|
|
4446
4345
|
e: void 0,
|
|
4447
4346
|
t: void 0
|
|
4448
4347
|
});
|
|
4449
|
-
return _el$
|
|
4348
|
+
return _el$40;
|
|
4450
4349
|
})(), (() => {
|
|
4451
|
-
var _el$
|
|
4452
|
-
insertNode(_el$
|
|
4453
|
-
insert(_el$
|
|
4454
|
-
insert(_el$
|
|
4455
|
-
effect((_$p) => setProp(_el$
|
|
4456
|
-
return _el$
|
|
4350
|
+
var _el$42 = createElement("text"), _el$43 = createTextNode(` via `);
|
|
4351
|
+
insertNode(_el$42, _el$43);
|
|
4352
|
+
insert(_el$42, () => dependencies3().missing.join(" + "), _el$43);
|
|
4353
|
+
insert(_el$42, () => dependencies3().installer, null);
|
|
4354
|
+
effect((_$p) => setProp(_el$42, "fg", palette.foreground, _$p));
|
|
4355
|
+
return _el$42;
|
|
4457
4356
|
})(), (() => {
|
|
4458
|
-
var _el$
|
|
4459
|
-
insertNode(_el$
|
|
4460
|
-
insert(_el$
|
|
4461
|
-
effect((_$p) => setProp(_el$
|
|
4462
|
-
return _el$
|
|
4463
|
-
})()
|
|
4464
|
-
get when() {
|
|
4465
|
-
return props.backend.demo;
|
|
4466
|
-
},
|
|
4467
|
-
get children() {
|
|
4468
|
-
var _el$49 = createElement("text");
|
|
4469
|
-
insertNode(_el$49, createTextNode(`Setup simulation; no software installed.`));
|
|
4470
|
-
effect((_$p) => setProp(_el$49, "fg", palette.warning, _$p));
|
|
4471
|
-
return _el$49;
|
|
4472
|
-
}
|
|
4473
|
-
})];
|
|
4357
|
+
var _el$44 = createElement("text"), _el$45 = createTextNode(` uses the ordinary terminal. Ctrl-C cancels and quits; wait for cleanup.`);
|
|
4358
|
+
insertNode(_el$44, _el$45);
|
|
4359
|
+
insert(_el$44, () => dependencies3().installer, _el$45);
|
|
4360
|
+
effect((_$p) => setProp(_el$44, "fg", palette.muted, _$p));
|
|
4361
|
+
return _el$44;
|
|
4362
|
+
})()];
|
|
4474
4363
|
}
|
|
4475
4364
|
}), createComponent2(Show, {
|
|
4476
4365
|
get when() {
|
|
@@ -4478,26 +4367,26 @@ function App(props) {
|
|
|
4478
4367
|
},
|
|
4479
4368
|
get children() {
|
|
4480
4369
|
return [(() => {
|
|
4481
|
-
var _el$
|
|
4482
|
-
insertNode(_el$
|
|
4370
|
+
var _el$46 = createElement("text");
|
|
4371
|
+
insertNode(_el$46, createTextNode(`Choose a USB drive`));
|
|
4483
4372
|
effect((_p$) => {
|
|
4484
4373
|
var _v$15 = palette.foreground, _v$16 = TextAttributes2.BOLD;
|
|
4485
|
-
_v$15 !== _p$.e && (_p$.e = setProp(_el$
|
|
4486
|
-
_v$16 !== _p$.t && (_p$.t = setProp(_el$
|
|
4374
|
+
_v$15 !== _p$.e && (_p$.e = setProp(_el$46, "fg", _v$15, _p$.e));
|
|
4375
|
+
_v$16 !== _p$.t && (_p$.t = setProp(_el$46, "attributes", _v$16, _p$.t));
|
|
4487
4376
|
return _p$;
|
|
4488
4377
|
}, {
|
|
4489
4378
|
e: void 0,
|
|
4490
4379
|
t: void 0
|
|
4491
4380
|
});
|
|
4492
|
-
return _el$
|
|
4381
|
+
return _el$46;
|
|
4493
4382
|
})(), (() => {
|
|
4494
|
-
var _el$
|
|
4495
|
-
insert(_el$
|
|
4383
|
+
var _el$48 = createElement("text");
|
|
4384
|
+
insert(_el$48, (() => {
|
|
4496
4385
|
var _c$3 = memo2(() => !!loading());
|
|
4497
4386
|
return () => _c$3() ? `${spinner()} Checking disks and protected storage...` : "System, home and app storage are excluded.";
|
|
4498
4387
|
})());
|
|
4499
|
-
effect((_$p) => setProp(_el$
|
|
4500
|
-
return _el$
|
|
4388
|
+
effect((_$p) => setProp(_el$48, "fg", palette.muted, _$p));
|
|
4389
|
+
return _el$48;
|
|
4501
4390
|
})(), createComponent2(Show, {
|
|
4502
4391
|
get when() {
|
|
4503
4392
|
return !loading();
|
|
@@ -4509,31 +4398,31 @@ function App(props) {
|
|
|
4509
4398
|
},
|
|
4510
4399
|
get fallback() {
|
|
4511
4400
|
return (() => {
|
|
4512
|
-
var _el$
|
|
4513
|
-
insertNode(_el$
|
|
4514
|
-
effect((_$p) => setProp(_el$
|
|
4515
|
-
return _el$
|
|
4401
|
+
var _el$88 = createElement("text");
|
|
4402
|
+
insertNode(_el$88, createTextNode(`No eligible USB drives. Connect a writable external USB drive, then press R to refresh.`));
|
|
4403
|
+
effect((_$p) => setProp(_el$88, "fg", palette.warning, _$p));
|
|
4404
|
+
return _el$88;
|
|
4516
4405
|
})();
|
|
4517
4406
|
},
|
|
4518
4407
|
get children() {
|
|
4519
4408
|
return [(() => {
|
|
4520
|
-
var _el$
|
|
4521
|
-
setProp(_el$
|
|
4522
|
-
insert(_el$
|
|
4409
|
+
var _el$49 = createElement("box");
|
|
4410
|
+
setProp(_el$49, "gap", 0);
|
|
4411
|
+
insert(_el$49, createComponent2(For, {
|
|
4523
4412
|
get each() {
|
|
4524
4413
|
return disks3().slice(Math.max(0, cursor() - 2), Math.max(3, cursor() + 1));
|
|
4525
4414
|
},
|
|
4526
4415
|
children: (d, index) => row(d.name, `${path(d)} / ${bytes(d.bytes)} / USB`, index() + Math.max(0, cursor() - 2))
|
|
4527
4416
|
}));
|
|
4528
|
-
return _el$
|
|
4417
|
+
return _el$49;
|
|
4529
4418
|
})(), (() => {
|
|
4530
|
-
var _el$
|
|
4531
|
-
insert(_el$
|
|
4419
|
+
var _el$50 = createElement("text");
|
|
4420
|
+
insert(_el$50, (() => {
|
|
4532
4421
|
var _c$4 = memo2(() => cursor() < 0);
|
|
4533
4422
|
return () => _c$4() ? "Use arrows to select a drive. Nothing is selected yet." : `${cursor() + 1} of ${disks3().length} drives / Enter to review`;
|
|
4534
4423
|
})());
|
|
4535
|
-
effect((_$p) => setProp(_el$
|
|
4536
|
-
return _el$
|
|
4424
|
+
effect((_$p) => setProp(_el$50, "fg", palette.muted, _$p));
|
|
4425
|
+
return _el$50;
|
|
4537
4426
|
})()];
|
|
4538
4427
|
}
|
|
4539
4428
|
});
|
|
@@ -4546,64 +4435,55 @@ function App(props) {
|
|
|
4546
4435
|
},
|
|
4547
4436
|
get children() {
|
|
4548
4437
|
return [(() => {
|
|
4549
|
-
var _el$
|
|
4550
|
-
insertNode(_el$
|
|
4438
|
+
var _el$51 = createElement("text");
|
|
4439
|
+
insertNode(_el$51, createTextNode(`Erase this entire USB drive?`));
|
|
4551
4440
|
effect((_p$) => {
|
|
4552
4441
|
var _v$17 = palette.warning, _v$18 = TextAttributes2.BOLD;
|
|
4553
|
-
_v$17 !== _p$.e && (_p$.e = setProp(_el$
|
|
4554
|
-
_v$18 !== _p$.t && (_p$.t = setProp(_el$
|
|
4442
|
+
_v$17 !== _p$.e && (_p$.e = setProp(_el$51, "fg", _v$17, _p$.e));
|
|
4443
|
+
_v$18 !== _p$.t && (_p$.t = setProp(_el$51, "attributes", _v$18, _p$.t));
|
|
4555
4444
|
return _p$;
|
|
4556
4445
|
}, {
|
|
4557
4446
|
e: void 0,
|
|
4558
4447
|
t: void 0
|
|
4559
4448
|
});
|
|
4560
|
-
return _el$
|
|
4449
|
+
return _el$51;
|
|
4561
4450
|
})(), (() => {
|
|
4562
|
-
var _el$
|
|
4563
|
-
insertNode(_el$
|
|
4564
|
-
insertNode(_el$
|
|
4565
|
-
|
|
4566
|
-
setProp(_el$
|
|
4567
|
-
setProp(_el$
|
|
4568
|
-
|
|
4569
|
-
insert(_el$
|
|
4570
|
-
insert(_el$60, (() => {
|
|
4451
|
+
var _el$53 = createElement("box"), _el$54 = createElement("text"), _el$55 = createElement("text");
|
|
4452
|
+
insertNode(_el$53, _el$54);
|
|
4453
|
+
insertNode(_el$53, _el$55);
|
|
4454
|
+
setProp(_el$53, "paddingX", 1);
|
|
4455
|
+
setProp(_el$54, "height", 1);
|
|
4456
|
+
setProp(_el$54, "wrapMode", "none");
|
|
4457
|
+
insert(_el$54, () => disk()?.name);
|
|
4458
|
+
insert(_el$55, (() => {
|
|
4571
4459
|
var _c$5 = memo2(() => !!disk());
|
|
4572
4460
|
return () => _c$5() ? `${path(disk())} / ${bytes(disk().bytes)}` : "";
|
|
4573
4461
|
})());
|
|
4574
|
-
insertNode(_el$61, _el$62);
|
|
4575
|
-
insert(_el$61, () => image()?.profile.toUpperCase(), _el$62);
|
|
4576
|
-
insert(_el$61, (() => {
|
|
4577
|
-
var _c$6 = memo2(() => !!catalog()?.candidate);
|
|
4578
|
-
return () => _c$6() ? `candidate (build-only) ${catalog()?.revision.slice(0, 7)}` : `Boo ${catalog()?.version}`;
|
|
4579
|
-
})(), null);
|
|
4580
4462
|
effect((_p$) => {
|
|
4581
|
-
var _v$19 = palette.panelAlt, _v$20 = palette.foreground, _v$21 = TextAttributes2.BOLD, _v$22 = palette.accent
|
|
4582
|
-
_v$19 !== _p$.e && (_p$.e = setProp(_el$
|
|
4583
|
-
_v$20 !== _p$.t && (_p$.t = setProp(_el$
|
|
4584
|
-
_v$21 !== _p$.a && (_p$.a = setProp(_el$
|
|
4585
|
-
_v$22 !== _p$.o && (_p$.o = setProp(_el$
|
|
4586
|
-
_v$23 !== _p$.i && (_p$.i = setProp(_el$61, "fg", _v$23, _p$.i));
|
|
4463
|
+
var _v$19 = palette.panelAlt, _v$20 = palette.foreground, _v$21 = TextAttributes2.BOLD, _v$22 = palette.accent;
|
|
4464
|
+
_v$19 !== _p$.e && (_p$.e = setProp(_el$53, "backgroundColor", _v$19, _p$.e));
|
|
4465
|
+
_v$20 !== _p$.t && (_p$.t = setProp(_el$54, "fg", _v$20, _p$.t));
|
|
4466
|
+
_v$21 !== _p$.a && (_p$.a = setProp(_el$54, "attributes", _v$21, _p$.a));
|
|
4467
|
+
_v$22 !== _p$.o && (_p$.o = setProp(_el$55, "fg", _v$22, _p$.o));
|
|
4587
4468
|
return _p$;
|
|
4588
4469
|
}, {
|
|
4589
4470
|
e: void 0,
|
|
4590
4471
|
t: void 0,
|
|
4591
4472
|
a: void 0,
|
|
4592
|
-
o: void 0
|
|
4593
|
-
i: void 0
|
|
4473
|
+
o: void 0
|
|
4594
4474
|
});
|
|
4595
|
-
return _el$
|
|
4475
|
+
return _el$53;
|
|
4596
4476
|
})(), (() => {
|
|
4597
|
-
var _el$
|
|
4598
|
-
insertNode(_el$
|
|
4599
|
-
effect((_$p) => setProp(_el$
|
|
4600
|
-
return _el$
|
|
4477
|
+
var _el$56 = createElement("text");
|
|
4478
|
+
insertNode(_el$56, createTextNode(`ALL data and partitions on this drive will be lost. Back up anything you need before continuing.`));
|
|
4479
|
+
effect((_$p) => setProp(_el$56, "fg", palette.warning, _$p));
|
|
4480
|
+
return _el$56;
|
|
4601
4481
|
})(), (() => {
|
|
4602
|
-
var _el$
|
|
4603
|
-
insert(_el$
|
|
4604
|
-
insert(_el$
|
|
4605
|
-
effect((_$p) => setProp(_el$
|
|
4606
|
-
return _el$
|
|
4482
|
+
var _el$58 = createElement("box");
|
|
4483
|
+
insert(_el$58, () => row("Go back", "", 0), null);
|
|
4484
|
+
insert(_el$58, () => row("Erase & flash", "", 1, true), null);
|
|
4485
|
+
effect((_$p) => setProp(_el$58, "gap", tight() ? 0 : 1, _$p));
|
|
4486
|
+
return _el$58;
|
|
4607
4487
|
})()];
|
|
4608
4488
|
}
|
|
4609
4489
|
}), createComponent2(Show, {
|
|
@@ -4612,108 +4492,114 @@ function App(props) {
|
|
|
4612
4492
|
},
|
|
4613
4493
|
get children() {
|
|
4614
4494
|
return [(() => {
|
|
4615
|
-
var _el$
|
|
4616
|
-
insertNode(_el$
|
|
4617
|
-
insert(_el$
|
|
4618
|
-
insert(_el$
|
|
4619
|
-
var _c$
|
|
4620
|
-
return () => _c$
|
|
4495
|
+
var _el$59 = createElement("text"), _el$60 = createTextNode(` `);
|
|
4496
|
+
insertNode(_el$59, _el$60);
|
|
4497
|
+
insert(_el$59, spinner, _el$60);
|
|
4498
|
+
insert(_el$59, (() => {
|
|
4499
|
+
var _c$6 = memo2(() => !!stopping());
|
|
4500
|
+
return () => _c$6() ? "Stopping safely..." : progress().stage;
|
|
4621
4501
|
})(), null);
|
|
4622
4502
|
effect((_p$) => {
|
|
4623
|
-
var _v$
|
|
4624
|
-
_v$
|
|
4625
|
-
_v$
|
|
4503
|
+
var _v$23 = palette.accent, _v$24 = TextAttributes2.BOLD;
|
|
4504
|
+
_v$23 !== _p$.e && (_p$.e = setProp(_el$59, "fg", _v$23, _p$.e));
|
|
4505
|
+
_v$24 !== _p$.t && (_p$.t = setProp(_el$59, "attributes", _v$24, _p$.t));
|
|
4626
4506
|
return _p$;
|
|
4627
4507
|
}, {
|
|
4628
4508
|
e: void 0,
|
|
4629
4509
|
t: void 0
|
|
4630
4510
|
});
|
|
4631
|
-
return _el$
|
|
4511
|
+
return _el$59;
|
|
4632
4512
|
})(), (() => {
|
|
4633
|
-
var _el$
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
effect((_$p) => setProp(_el$68, "fg", palette.foreground, _$p));
|
|
4638
|
-
return _el$68;
|
|
4513
|
+
var _el$61 = createElement("text");
|
|
4514
|
+
insert(_el$61, () => disk()?.name);
|
|
4515
|
+
effect((_$p) => setProp(_el$61, "fg", palette.foreground, _$p));
|
|
4516
|
+
return _el$61;
|
|
4639
4517
|
})(), (() => {
|
|
4640
|
-
var _el$
|
|
4641
|
-
insert(_el$
|
|
4642
|
-
var _c$
|
|
4643
|
-
return () => _c$
|
|
4518
|
+
var _el$62 = createElement("text");
|
|
4519
|
+
insert(_el$62, (() => {
|
|
4520
|
+
var _c$7 = memo2(() => !!stopping());
|
|
4521
|
+
return () => _c$7() ? "Waiting for all child processes to stop. Keep the USB connected." : progress().detail;
|
|
4644
4522
|
})());
|
|
4645
|
-
effect((_$p) => setProp(_el$
|
|
4646
|
-
return _el$
|
|
4523
|
+
effect((_$p) => setProp(_el$62, "fg", palette.muted, _$p));
|
|
4524
|
+
return _el$62;
|
|
4647
4525
|
})(), createComponent2(Show, {
|
|
4648
4526
|
get when() {
|
|
4649
4527
|
return percent() !== void 0;
|
|
4650
4528
|
},
|
|
4651
4529
|
get children() {
|
|
4652
4530
|
return [(() => {
|
|
4653
|
-
var _el$
|
|
4654
|
-
setProp(_el$
|
|
4655
|
-
|
|
4656
|
-
insert(_el$71, createComponent2(Show, {
|
|
4531
|
+
var _el$63 = createElement("box");
|
|
4532
|
+
setProp(_el$63, "flexShrink", 0);
|
|
4533
|
+
insert(_el$63, createComponent2(Show, {
|
|
4657
4534
|
get when() {
|
|
4658
4535
|
return percent() > 0;
|
|
4659
4536
|
},
|
|
4660
4537
|
get children() {
|
|
4661
|
-
var _el$
|
|
4662
|
-
setProp(_el$
|
|
4538
|
+
var _el$64 = createElement("box");
|
|
4539
|
+
setProp(_el$64, "height", 1);
|
|
4663
4540
|
effect((_p$) => {
|
|
4664
|
-
var _v$
|
|
4665
|
-
_v$
|
|
4666
|
-
_v$
|
|
4541
|
+
var _v$25 = `${percent() ?? 0}%`, _v$26 = palette.accent;
|
|
4542
|
+
_v$25 !== _p$.e && (_p$.e = setProp(_el$64, "width", _v$25, _p$.e));
|
|
4543
|
+
_v$26 !== _p$.t && (_p$.t = setProp(_el$64, "backgroundColor", _v$26, _p$.t));
|
|
4667
4544
|
return _p$;
|
|
4668
4545
|
}, {
|
|
4669
4546
|
e: void 0,
|
|
4670
4547
|
t: void 0
|
|
4671
4548
|
});
|
|
4672
|
-
return _el$
|
|
4549
|
+
return _el$64;
|
|
4673
4550
|
}
|
|
4674
4551
|
}));
|
|
4675
4552
|
effect((_p$) => {
|
|
4676
|
-
var _v$28 = palette.accent, _v$29 = palette.panelAlt;
|
|
4677
|
-
_v$
|
|
4678
|
-
_v$
|
|
4553
|
+
var _v$27 = !tight(), _v$28 = palette.accent, _v$29 = tight() ? 1 : 3, _v$30 = palette.panelAlt;
|
|
4554
|
+
_v$27 !== _p$.e && (_p$.e = setProp(_el$63, "border", _v$27, _p$.e));
|
|
4555
|
+
_v$28 !== _p$.t && (_p$.t = setProp(_el$63, "borderColor", _v$28, _p$.t));
|
|
4556
|
+
_v$29 !== _p$.a && (_p$.a = setProp(_el$63, "height", _v$29, _p$.a));
|
|
4557
|
+
_v$30 !== _p$.o && (_p$.o = setProp(_el$63, "backgroundColor", _v$30, _p$.o));
|
|
4679
4558
|
return _p$;
|
|
4680
4559
|
}, {
|
|
4681
4560
|
e: void 0,
|
|
4682
|
-
t: void 0
|
|
4561
|
+
t: void 0,
|
|
4562
|
+
a: void 0,
|
|
4563
|
+
o: void 0
|
|
4683
4564
|
});
|
|
4684
|
-
return _el$
|
|
4565
|
+
return _el$63;
|
|
4685
4566
|
})(), (() => {
|
|
4686
|
-
var _el$
|
|
4687
|
-
insertNode(_el$
|
|
4688
|
-
insertNode(_el$
|
|
4689
|
-
insert(_el$
|
|
4690
|
-
insert(_el$
|
|
4691
|
-
insert(_el$
|
|
4567
|
+
var _el$65 = createElement("text"), _el$66 = createTextNode(`% `), _el$67 = createTextNode(` / `);
|
|
4568
|
+
insertNode(_el$65, _el$66);
|
|
4569
|
+
insertNode(_el$65, _el$67);
|
|
4570
|
+
insert(_el$65, percent, _el$66);
|
|
4571
|
+
insert(_el$65, () => bytes(progress().bytes ?? 0), _el$67);
|
|
4572
|
+
insert(_el$65, () => bytes(progress().total ?? 0), null);
|
|
4692
4573
|
effect((_p$) => {
|
|
4693
|
-
var _v$
|
|
4694
|
-
_v$
|
|
4695
|
-
_v$
|
|
4574
|
+
var _v$31 = palette.foreground, _v$32 = TextAttributes2.BOLD;
|
|
4575
|
+
_v$31 !== _p$.e && (_p$.e = setProp(_el$65, "fg", _v$31, _p$.e));
|
|
4576
|
+
_v$32 !== _p$.t && (_p$.t = setProp(_el$65, "attributes", _v$32, _p$.t));
|
|
4696
4577
|
return _p$;
|
|
4697
4578
|
}, {
|
|
4698
4579
|
e: void 0,
|
|
4699
4580
|
t: void 0
|
|
4700
4581
|
});
|
|
4701
|
-
return _el$
|
|
4702
|
-
})(), (
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4582
|
+
return _el$65;
|
|
4583
|
+
})(), createComponent2(Show, {
|
|
4584
|
+
get when() {
|
|
4585
|
+
return !tight();
|
|
4586
|
+
},
|
|
4587
|
+
get children() {
|
|
4588
|
+
var _el$68 = createElement("text");
|
|
4589
|
+
insert(_el$68, (() => {
|
|
4590
|
+
var _c$8 = memo2(() => !!progress().speed);
|
|
4591
|
+
return () => _c$8() ? `${bytes(progress().speed)} / s` : "";
|
|
4592
|
+
})());
|
|
4593
|
+
effect((_$p) => setProp(_el$68, "fg", palette.muted, _$p));
|
|
4594
|
+
return _el$68;
|
|
4595
|
+
}
|
|
4596
|
+
})];
|
|
4711
4597
|
}
|
|
4712
4598
|
}), (() => {
|
|
4713
|
-
var _el$
|
|
4714
|
-
insertNode(_el$
|
|
4715
|
-
effect((_$p) => setProp(_el$
|
|
4716
|
-
return _el$
|
|
4599
|
+
var _el$69 = createElement("text");
|
|
4600
|
+
insertNode(_el$69, createTextNode(`Keep the USB connected until safe removal succeeds.`));
|
|
4601
|
+
effect((_$p) => setProp(_el$69, "fg", palette.warning, _$p));
|
|
4602
|
+
return _el$69;
|
|
4717
4603
|
})()];
|
|
4718
4604
|
}
|
|
4719
4605
|
}), createComponent2(Show, {
|
|
@@ -4722,37 +4608,34 @@ function App(props) {
|
|
|
4722
4608
|
},
|
|
4723
4609
|
get children() {
|
|
4724
4610
|
return [(() => {
|
|
4725
|
-
var _el$
|
|
4726
|
-
insert(_el$
|
|
4611
|
+
var _el$71 = createElement("text");
|
|
4612
|
+
insert(_el$71, () => props.backend.successTitle);
|
|
4727
4613
|
effect((_p$) => {
|
|
4728
|
-
var _v$
|
|
4729
|
-
_v$
|
|
4730
|
-
_v$
|
|
4614
|
+
var _v$33 = palette.success, _v$34 = TextAttributes2.BOLD;
|
|
4615
|
+
_v$33 !== _p$.e && (_p$.e = setProp(_el$71, "fg", _v$33, _p$.e));
|
|
4616
|
+
_v$34 !== _p$.t && (_p$.t = setProp(_el$71, "attributes", _v$34, _p$.t));
|
|
4731
4617
|
return _p$;
|
|
4732
4618
|
}, {
|
|
4733
4619
|
e: void 0,
|
|
4734
4620
|
t: void 0
|
|
4735
4621
|
});
|
|
4736
|
-
return _el$
|
|
4622
|
+
return _el$71;
|
|
4737
4623
|
})(), (() => {
|
|
4738
|
-
var _el$
|
|
4739
|
-
insert(_el$
|
|
4740
|
-
effect((_$p) => setProp(_el$
|
|
4741
|
-
return _el$
|
|
4624
|
+
var _el$72 = createElement("text");
|
|
4625
|
+
insert(_el$72, () => props.backend.successDetail);
|
|
4626
|
+
effect((_$p) => setProp(_el$72, "fg", palette.foreground, _$p));
|
|
4627
|
+
return _el$72;
|
|
4742
4628
|
})(), (() => {
|
|
4743
|
-
var _el$
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
})());
|
|
4748
|
-
effect((_$p) => setProp(_el$81, "fg", palette.muted, _$p));
|
|
4749
|
-
return _el$81;
|
|
4629
|
+
var _el$73 = createElement("text");
|
|
4630
|
+
insertNode(_el$73, createTextNode(`Compressed image and raw stream verified. Not a device read-back.`));
|
|
4631
|
+
effect((_$p) => setProp(_el$73, "fg", palette.muted, _$p));
|
|
4632
|
+
return _el$73;
|
|
4750
4633
|
})(), (() => {
|
|
4751
|
-
var _el$
|
|
4752
|
-
setProp(_el$
|
|
4753
|
-
insert(_el$
|
|
4754
|
-
insert(_el$
|
|
4755
|
-
return _el$
|
|
4634
|
+
var _el$75 = createElement("box");
|
|
4635
|
+
setProp(_el$75, "gap", 1);
|
|
4636
|
+
insert(_el$75, () => row("Choose another image", "", 0), null);
|
|
4637
|
+
insert(_el$75, () => row("Quit", "", 1), null);
|
|
4638
|
+
return _el$75;
|
|
4756
4639
|
})()];
|
|
4757
4640
|
}
|
|
4758
4641
|
}), createComponent2(Show, {
|
|
@@ -4761,56 +4644,56 @@ function App(props) {
|
|
|
4761
4644
|
},
|
|
4762
4645
|
get children() {
|
|
4763
4646
|
return [(() => {
|
|
4764
|
-
var _el$
|
|
4765
|
-
insertNode(_el$
|
|
4647
|
+
var _el$76 = createElement("text");
|
|
4648
|
+
insertNode(_el$76, createTextNode(`Flash not completed`));
|
|
4766
4649
|
effect((_p$) => {
|
|
4767
|
-
var _v$
|
|
4768
|
-
_v$
|
|
4769
|
-
_v$
|
|
4650
|
+
var _v$35 = palette.danger, _v$36 = TextAttributes2.BOLD;
|
|
4651
|
+
_v$35 !== _p$.e && (_p$.e = setProp(_el$76, "fg", _v$35, _p$.e));
|
|
4652
|
+
_v$36 !== _p$.t && (_p$.t = setProp(_el$76, "attributes", _v$36, _p$.t));
|
|
4770
4653
|
return _p$;
|
|
4771
4654
|
}, {
|
|
4772
4655
|
e: void 0,
|
|
4773
4656
|
t: void 0
|
|
4774
4657
|
});
|
|
4775
|
-
return _el$
|
|
4658
|
+
return _el$76;
|
|
4776
4659
|
})(), (() => {
|
|
4777
|
-
var _el$
|
|
4778
|
-
insert(_el$
|
|
4779
|
-
effect((_$p) => setProp(_el$
|
|
4780
|
-
return _el$
|
|
4660
|
+
var _el$78 = createElement("text");
|
|
4661
|
+
insert(_el$78, error);
|
|
4662
|
+
effect((_$p) => setProp(_el$78, "fg", palette.foreground, _$p));
|
|
4663
|
+
return _el$78;
|
|
4781
4664
|
})(), (() => {
|
|
4782
|
-
var _el$
|
|
4783
|
-
setProp(_el$
|
|
4784
|
-
insert(_el$
|
|
4785
|
-
insert(_el$
|
|
4786
|
-
return _el$
|
|
4665
|
+
var _el$79 = createElement("box");
|
|
4666
|
+
setProp(_el$79, "gap", 1);
|
|
4667
|
+
insert(_el$79, () => row("Refresh & try again", "", 0), null);
|
|
4668
|
+
insert(_el$79, () => row("Quit", "", 1), null);
|
|
4669
|
+
return _el$79;
|
|
4787
4670
|
})()];
|
|
4788
4671
|
}
|
|
4789
4672
|
})];
|
|
4790
4673
|
}
|
|
4791
4674
|
}));
|
|
4792
|
-
setProp(_el$
|
|
4793
|
-
setProp(_el$
|
|
4794
|
-
setProp(_el$
|
|
4795
|
-
insert(_el$
|
|
4796
|
-
var _c$
|
|
4797
|
-
return () => _c$
|
|
4675
|
+
setProp(_el$80, "height", 1);
|
|
4676
|
+
setProp(_el$80, "flexShrink", 0);
|
|
4677
|
+
setProp(_el$80, "wrapMode", "none");
|
|
4678
|
+
insert(_el$80, (() => {
|
|
4679
|
+
var _c$9 = memo2(() => !!busy());
|
|
4680
|
+
return () => _c$9() ? "Esc cancel / Q stop & quit" : dimensions().width < 56 ? "Arrows / Enter / Esc / R / Q quit" : "Arrows / Enter / Esc back / R refresh / Q quit";
|
|
4798
4681
|
})());
|
|
4799
4682
|
effect((_p$) => {
|
|
4800
|
-
var _v$
|
|
4801
|
-
_v$
|
|
4802
|
-
_v$
|
|
4803
|
-
_v$
|
|
4804
|
-
_v$
|
|
4805
|
-
_v$
|
|
4806
|
-
_v$
|
|
4807
|
-
_v$
|
|
4808
|
-
_v$
|
|
4809
|
-
_v$
|
|
4810
|
-
_v$
|
|
4811
|
-
_v$
|
|
4812
|
-
_v$
|
|
4813
|
-
_v$
|
|
4683
|
+
var _v$37 = palette.background, _v$38 = dimensions().width <= 80 ? "100%" : 80, _v$39 = dimensions().height <= 24 ? "100%" : 24, _v$40 = palette.border, _v$41 = palette.card, _v$42 = palette.accent, _v$43 = TextAttributes2.BOLD, _v$44 = palette.muted, _v$45 = palette.danger, _v$46 = tight() ? 0 : 1, _v$47 = tight() ? 0 : 1, _v$48 = tight() || (compact() || dimensions().width < 56) && (screen() === "setup" || !!image()) ? 0 : 1, _v$49 = palette.muted;
|
|
4684
|
+
_v$37 !== _p$.e && (_p$.e = setProp(_el$4, "backgroundColor", _v$37, _p$.e));
|
|
4685
|
+
_v$38 !== _p$.t && (_p$.t = setProp(_el$5, "width", _v$38, _p$.t));
|
|
4686
|
+
_v$39 !== _p$.a && (_p$.a = setProp(_el$5, "height", _v$39, _p$.a));
|
|
4687
|
+
_v$40 !== _p$.o && (_p$.o = setProp(_el$5, "borderColor", _v$40, _p$.o));
|
|
4688
|
+
_v$41 !== _p$.i && (_p$.i = setProp(_el$5, "backgroundColor", _v$41, _p$.i));
|
|
4689
|
+
_v$42 !== _p$.n && (_p$.n = setProp(_el$7, "fg", _v$42, _p$.n));
|
|
4690
|
+
_v$43 !== _p$.s && (_p$.s = setProp(_el$7, "attributes", _v$43, _p$.s));
|
|
4691
|
+
_v$44 !== _p$.h && (_p$.h = setProp(_el$9, "fg", _v$44, _p$.h));
|
|
4692
|
+
_v$45 !== _p$.r && (_p$.r = setProp(_el$0, "backgroundColor", _v$45, _p$.r));
|
|
4693
|
+
_v$46 !== _p$.d && (_p$.d = setProp(_el$0, "marginTop", _v$46, _p$.d));
|
|
4694
|
+
_v$47 !== _p$.l && (_p$.l = setProp(_el$1, "paddingTop", _v$47, _p$.l));
|
|
4695
|
+
_v$48 !== _p$.u && (_p$.u = setProp(_el$1, "gap", _v$48, _p$.u));
|
|
4696
|
+
_v$49 !== _p$.c && (_p$.c = setProp(_el$80, "fg", _v$49, _p$.c));
|
|
4814
4697
|
return _p$;
|
|
4815
4698
|
}, {
|
|
4816
4699
|
e: void 0,
|
|
@@ -4833,10 +4716,8 @@ function App(props) {
|
|
|
4833
4716
|
|
|
4834
4717
|
// src/index.tsx
|
|
4835
4718
|
var args = process.argv.slice(2);
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
if (args.length > 1 || args.some((arg) => !["--demo", "--demo=empty", "--demo=error", "--demo=setup", "--demo=setup-gh", "--demo=setup-zstd", "--demo=setup-error", "--demo=setup-interrupted", "--demo=no-homebrew", "--list-images", "--clear-cache"].includes(arg))) {
|
|
4839
|
-
console.error("Usage: bun start [--demo[=empty|error|setup|setup-gh|setup-zstd|setup-error|setup-interrupted|no-homebrew] | --list-images | --clear-cache]");
|
|
4719
|
+
if (args.length > 1 || args.some((arg) => !["--list-images", "--clear-cache"].includes(arg))) {
|
|
4720
|
+
console.error("Usage: boo-flash [--list-images | --clear-cache]");
|
|
4840
4721
|
process.exitCode = 1;
|
|
4841
4722
|
} else if (args.includes("--clear-cache")) {
|
|
4842
4723
|
try {
|
|
@@ -4852,11 +4733,11 @@ if (args.length > 1 || args.some((arg) => !["--demo", "--demo=empty", "--demo=er
|
|
|
4852
4733
|
console.error(e instanceof Error ? e.message : "Image discovery failed.");
|
|
4853
4734
|
process.exitCode = 1;
|
|
4854
4735
|
}
|
|
4855
|
-
} else if (!
|
|
4856
|
-
console.error("Boo Flash requires macOS or Linux and a normal user account.
|
|
4736
|
+
} else if (!["darwin", "linux"].includes(process.platform) || process.getuid?.() === 0) {
|
|
4737
|
+
console.error("Boo Flash requires macOS or Linux and a normal user account.");
|
|
4857
4738
|
process.exitCode = 1;
|
|
4858
4739
|
} else {
|
|
4859
|
-
const backend = new FlashBackend(
|
|
4740
|
+
const backend = new FlashBackend();
|
|
4860
4741
|
const renderer = await createCliRenderer2({
|
|
4861
4742
|
backgroundColor: palette.background,
|
|
4862
4743
|
targetFps: 30,
|