@beeos-ai/cli 1.0.11 → 1.0.12
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/dist/index.js +68 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1148,26 +1148,56 @@ function archiveName(cfg, target) {
|
|
|
1148
1148
|
const suffix = target.includes("windows") ? "zip" : "tar.gz";
|
|
1149
1149
|
return `${cfg.name}-${target}.${suffix}`;
|
|
1150
1150
|
}
|
|
1151
|
+
async function fetchArchiveBuffer(cfg, url, progress, maxAttempts = 3) {
|
|
1152
|
+
const p = getPlatformAdapter();
|
|
1153
|
+
let lastError = null;
|
|
1154
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1155
|
+
let resp;
|
|
1156
|
+
try {
|
|
1157
|
+
resp = await p.fetch(url);
|
|
1158
|
+
} catch (e) {
|
|
1159
|
+
lastError = String(e);
|
|
1160
|
+
progress.onStatus(`${cfg.name} download attempt ${attempt}/${maxAttempts} failed: ${lastError}`);
|
|
1161
|
+
if (attempt < maxAttempts) {
|
|
1162
|
+
await new Promise((r) => setTimeout(r, 1e3 * 2 ** (attempt - 1)));
|
|
1163
|
+
}
|
|
1164
|
+
continue;
|
|
1165
|
+
}
|
|
1166
|
+
if (!resp.ok) {
|
|
1167
|
+
progress.onStatus(`${cfg.name} download: ${resp.status} ${resp.statusText} (${url})`);
|
|
1168
|
+
if (resp.status === 404) {
|
|
1169
|
+
progress.onStatus(`Hint: the current release may not include the requested target. Try setting $${cfg.binaryEnv} to a locally built binary, ` + (cfg.releaseUrlEnv ? `or $${cfg.releaseUrlEnv} to a different release URL.` : `or check for a newer release.`));
|
|
1170
|
+
}
|
|
1171
|
+
if (resp.status === 404 || resp.status === 403 || resp.status === 401) {
|
|
1172
|
+
return null;
|
|
1173
|
+
}
|
|
1174
|
+
lastError = `${resp.status} ${resp.statusText}`;
|
|
1175
|
+
if (attempt < maxAttempts) {
|
|
1176
|
+
await new Promise((r) => setTimeout(r, 1e3 * 2 ** (attempt - 1)));
|
|
1177
|
+
}
|
|
1178
|
+
continue;
|
|
1179
|
+
}
|
|
1180
|
+
try {
|
|
1181
|
+
return new Uint8Array(await resp.arrayBuffer());
|
|
1182
|
+
} catch (e) {
|
|
1183
|
+
lastError = String(e);
|
|
1184
|
+
progress.onStatus(`${cfg.name} stream interrupted on attempt ${attempt}/${maxAttempts}: ${lastError}`);
|
|
1185
|
+
if (attempt < maxAttempts) {
|
|
1186
|
+
await new Promise((r) => setTimeout(r, 1e3 * 2 ** (attempt - 1)));
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
progress.onStatus(`${cfg.name} download gave up after ${maxAttempts} attempts (last: ${lastError ?? "unknown"}).`);
|
|
1191
|
+
return null;
|
|
1192
|
+
}
|
|
1151
1193
|
async function downloadManagedBinary(cfg, target, progress) {
|
|
1152
1194
|
const p = getPlatformAdapter();
|
|
1153
1195
|
const base = releaseBaseUrl(cfg);
|
|
1154
1196
|
const url = `${base}/${archiveName(cfg, target)}`;
|
|
1155
1197
|
progress.onStatus(`Downloading ${cfg.name} (${target})...`);
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
resp = await p.fetch(url);
|
|
1159
|
-
} catch (e) {
|
|
1160
|
-
progress.onStatus(`${cfg.name} download failed: ${String(e)}`);
|
|
1198
|
+
const data = await fetchArchiveBuffer(cfg, url, progress);
|
|
1199
|
+
if (!data)
|
|
1161
1200
|
return null;
|
|
1162
|
-
}
|
|
1163
|
-
if (!resp.ok) {
|
|
1164
|
-
progress.onStatus(`${cfg.name} download: ${resp.status} ${resp.statusText} (${url})`);
|
|
1165
|
-
if (resp.status === 404) {
|
|
1166
|
-
progress.onStatus(`Hint: the current release may not include ${target}. Try setting $${cfg.binaryEnv} to a locally built binary, ` + (cfg.releaseUrlEnv ? `or $${cfg.releaseUrlEnv} to a different release URL.` : `or check for a newer release.`));
|
|
1167
|
-
}
|
|
1168
|
-
return null;
|
|
1169
|
-
}
|
|
1170
|
-
const data = new Uint8Array(await resp.arrayBuffer());
|
|
1171
1201
|
const digestUrl = `${url}.sha256`;
|
|
1172
1202
|
let expected = null;
|
|
1173
1203
|
try {
|
|
@@ -4658,7 +4688,11 @@ async function registerVideoBridge(_mgr, reporter, params) {
|
|
|
4658
4688
|
if (!params.withVideo) return { mode: "none" };
|
|
4659
4689
|
const agentGatewayUrl = resolveAgentGatewayUrl(params.cfg);
|
|
4660
4690
|
if (params.vncHost) {
|
|
4661
|
-
const binary2 = await
|
|
4691
|
+
const binary2 = await ensureBridgeBinaryDegraded(
|
|
4692
|
+
vncBridgeRuntime.ensureInstalled.bind(vncBridgeRuntime),
|
|
4693
|
+
reporter,
|
|
4694
|
+
"vnc-bridge"
|
|
4695
|
+
);
|
|
4662
4696
|
if (!binary2) {
|
|
4663
4697
|
console.error(
|
|
4664
4698
|
` vnc-bridge binary unavailable \u2014 ${params.serial} will run without VNC streaming.`
|
|
@@ -4678,16 +4712,33 @@ async function registerVideoBridge(_mgr, reporter, params) {
|
|
|
4678
4712
|
await installService(_mgr, spec);
|
|
4679
4713
|
return { mode: "vnc" };
|
|
4680
4714
|
}
|
|
4681
|
-
const binary = await
|
|
4715
|
+
const binary = await ensureBridgeBinaryDegraded(
|
|
4716
|
+
scrcpyBridgeRuntime.ensureInstalled.bind(scrcpyBridgeRuntime),
|
|
4717
|
+
reporter,
|
|
4718
|
+
"scrcpy-bridge"
|
|
4719
|
+
);
|
|
4682
4720
|
if (!binary) {
|
|
4683
4721
|
console.error(
|
|
4684
4722
|
` scrcpy-bridge binary unavailable \u2014 ${params.serial} will run without WebRTC video.
|
|
4685
|
-
|
|
4723
|
+
ACP control + screenshots still work. To recover live video later:
|
|
4724
|
+
\u2022 re-run: beeos device attach --serial ${params.serial} (will retry the download)
|
|
4725
|
+
\u2022 or download from https://github.com/beeos-ai/scrcpy-bridge/releases
|
|
4726
|
+
and set BEEOS_SCRCPY_BRIDGE_BIN to its absolute path.`
|
|
4686
4727
|
);
|
|
4687
4728
|
return { mode: "none" };
|
|
4688
4729
|
}
|
|
4689
4730
|
return { mode: "scrcpy" };
|
|
4690
4731
|
}
|
|
4732
|
+
async function ensureBridgeBinaryDegraded(fn, reporter, label) {
|
|
4733
|
+
try {
|
|
4734
|
+
return await fn(reporter);
|
|
4735
|
+
} catch (e) {
|
|
4736
|
+
console.error(
|
|
4737
|
+
` ${label} install threw unexpectedly (${String(e)}) \u2014 degrading to no-video mode.`
|
|
4738
|
+
);
|
|
4739
|
+
return null;
|
|
4740
|
+
}
|
|
4741
|
+
}
|
|
4691
4742
|
async function ensureAdbAvailable(reporter) {
|
|
4692
4743
|
const existing = await findAdb();
|
|
4693
4744
|
if (existing) return;
|