@beeos-ai/cli 1.0.19 → 1.0.21
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 +172 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -761,18 +761,22 @@ function buildBindUrl(dashboardBaseUrl, bindId) {
|
|
|
761
761
|
const base = dashboardBaseUrl.replace(/\/+$/, "");
|
|
762
762
|
return `${base}/bind/${bindId}`;
|
|
763
763
|
}
|
|
764
|
-
async function agentBind(apiUrl, publicKey, fingerprint2, agentFramework, hostname) {
|
|
764
|
+
async function agentBind(apiUrl, publicKey, fingerprint2, agentFramework, hostname, osType) {
|
|
765
765
|
const p = getPlatformAdapter();
|
|
766
766
|
const url = `${apiUrl}/api/v1/agent/bind`;
|
|
767
|
+
const body = {
|
|
768
|
+
public_key: publicKey,
|
|
769
|
+
fingerprint: fingerprint2,
|
|
770
|
+
agent_framework: agentFramework,
|
|
771
|
+
hostname
|
|
772
|
+
};
|
|
773
|
+
if (osType && osType.length > 0) {
|
|
774
|
+
body.os_type = osType;
|
|
775
|
+
}
|
|
767
776
|
const resp = await p.fetch(url, {
|
|
768
777
|
method: "POST",
|
|
769
778
|
headers: { "Content-Type": "application/json" },
|
|
770
|
-
body: JSON.stringify(
|
|
771
|
-
public_key: publicKey,
|
|
772
|
-
fingerprint: fingerprint2,
|
|
773
|
-
agent_framework: agentFramework,
|
|
774
|
-
hostname
|
|
775
|
-
})
|
|
779
|
+
body: JSON.stringify(body)
|
|
776
780
|
});
|
|
777
781
|
if (!resp.ok) {
|
|
778
782
|
throw await bindHttpError(resp, "bind");
|
|
@@ -925,7 +929,7 @@ async function bindAgent(opts) {
|
|
|
925
929
|
const pollTimeoutMs = opts.pollTimeoutMs ?? 6e5;
|
|
926
930
|
let resp;
|
|
927
931
|
try {
|
|
928
|
-
resp = await agentBind(opts.apiUrl, opts.publicKey, opts.fingerprint, opts.agentFramework, opts.hostname);
|
|
932
|
+
resp = await agentBind(opts.apiUrl, opts.publicKey, opts.fingerprint, opts.agentFramework, opts.hostname, opts.osType);
|
|
929
933
|
} catch (e) {
|
|
930
934
|
if (isNetworkError(e) && opts.cachedBinding && opts.cachedBinding.fingerprint === opts.fingerprint) {
|
|
931
935
|
return {
|
|
@@ -2047,13 +2051,34 @@ var init_vnc_bridge = __esm({
|
|
|
2047
2051
|
* Build the environment map used when launching vnc-bridge for a
|
|
2048
2052
|
* device. Exposed separately so the service target-spec builder
|
|
2049
2053
|
* can reuse the same logic without duplicating it.
|
|
2054
|
+
*
|
|
2055
|
+
* Env-var names are aligned with the **vnc-bridge 0.3.6** clap
|
|
2056
|
+
* definitions (`devices/vnc-bridge/src/main.rs`):
|
|
2057
|
+
*
|
|
2058
|
+
* --vnc env: VNC_ADDR=host:port (combined, NOT VNC_HOST/VNC_PORT)
|
|
2059
|
+
* --gateway env: AGENT_GATEWAY_URL
|
|
2060
|
+
* --key-file env: AGENT_KEY_FILE (single combined key, NOT BRIDGE_PRIVATE/PUBLIC)
|
|
2061
|
+
* --mqtt env: MQTT_BROKER_URL (static mode only)
|
|
2062
|
+
* --topic env: DEVICE_TOPIC (static mode only)
|
|
2063
|
+
*
|
|
2064
|
+
* Pre-1.0.21 we shipped the older naming (VNC_HOST + VNC_PORT,
|
|
2065
|
+
* BRIDGE_PRIVATE_KEY_FILE etc.) which the binary silently ignored,
|
|
2066
|
+
* causing it to bail out with `Error: Either --gateway + --key-file
|
|
2067
|
+
* (bootstrap mode) or --mqtt + --topic (static mode) is required`
|
|
2068
|
+
* at every restart. The legacy fields are retained alongside the
|
|
2069
|
+
* new ones so any older Rust build that did read them still works.
|
|
2050
2070
|
*/
|
|
2051
2071
|
buildEnv(opts) {
|
|
2072
|
+
const vncPort = opts.vncPort ?? 5900;
|
|
2052
2073
|
return {
|
|
2074
|
+
// ── vnc-bridge 0.3.6 canonical env vars ────────────────
|
|
2075
|
+
VNC_ADDR: `${opts.vncHost}:${vncPort}`,
|
|
2076
|
+
AGENT_GATEWAY_URL: opts.agentGatewayUrl,
|
|
2077
|
+
AGENT_KEY_FILE: opts.bridgePrivateKeyFile,
|
|
2078
|
+
// ── Legacy names (pre-0.3.6 / future-compat / forensic) ─
|
|
2053
2079
|
DEVICE_ID: opts.deviceId,
|
|
2054
2080
|
VNC_HOST: opts.vncHost,
|
|
2055
|
-
VNC_PORT: String(
|
|
2056
|
-
AGENT_GATEWAY_URL: opts.agentGatewayUrl,
|
|
2081
|
+
VNC_PORT: String(vncPort),
|
|
2057
2082
|
BRIDGE_PRIVATE_KEY_FILE: opts.bridgePrivateKeyFile,
|
|
2058
2083
|
BRIDGE_PUBLIC_KEY_FILE: opts.bridgePublicKeyFile,
|
|
2059
2084
|
LOG_FORMAT: "json",
|
|
@@ -3244,6 +3269,74 @@ var init_agent_status = __esm({
|
|
|
3244
3269
|
}
|
|
3245
3270
|
});
|
|
3246
3271
|
|
|
3272
|
+
// ../core/dist/openclaw/desktop-detect.js
|
|
3273
|
+
function printMacosDesktopHint() {
|
|
3274
|
+
for (const line of MACOS_DESKTOP_HINT_LINES)
|
|
3275
|
+
console.log(line);
|
|
3276
|
+
}
|
|
3277
|
+
function readEnv(name) {
|
|
3278
|
+
return globalThis.process?.env?.[name];
|
|
3279
|
+
}
|
|
3280
|
+
async function probeLocalVnc(opts = {}) {
|
|
3281
|
+
if (readEnv("BEEOS_NO_DESKTOP") === "1")
|
|
3282
|
+
return null;
|
|
3283
|
+
const p = getPlatformAdapter();
|
|
3284
|
+
const platform = p.platform();
|
|
3285
|
+
if (platform !== "darwin" && platform !== "linux") {
|
|
3286
|
+
return null;
|
|
3287
|
+
}
|
|
3288
|
+
const host = "127.0.0.1";
|
|
3289
|
+
const timeoutMs = 200;
|
|
3290
|
+
if (platform === "darwin") {
|
|
3291
|
+
const ok2 = await p.tcpProbe(host, 5900, timeoutMs).catch(() => false);
|
|
3292
|
+
if (ok2) {
|
|
3293
|
+
return { kind: "macos", host, port: 5900, osType: "macos-desktop" };
|
|
3294
|
+
}
|
|
3295
|
+
return null;
|
|
3296
|
+
}
|
|
3297
|
+
const ok = await p.tcpProbe(host, 5901, timeoutMs).catch(() => false);
|
|
3298
|
+
if (ok) {
|
|
3299
|
+
return { kind: "linux", host, port: 5901, osType: "linux-desktop" };
|
|
3300
|
+
}
|
|
3301
|
+
if (opts.ttyHints) {
|
|
3302
|
+
for (const line of LINUX_VNC_HINT_LINES)
|
|
3303
|
+
console.log(line);
|
|
3304
|
+
}
|
|
3305
|
+
return null;
|
|
3306
|
+
}
|
|
3307
|
+
var MACOS_DESKTOP_HINT_LINES, MACOS_DESKTOP_DOCTOR_HINT_LINES, LINUX_VNC_HINT_LINES;
|
|
3308
|
+
var init_desktop_detect = __esm({
|
|
3309
|
+
"../core/dist/openclaw/desktop-detect.js"() {
|
|
3310
|
+
"use strict";
|
|
3311
|
+
init_platform_adapter();
|
|
3312
|
+
MACOS_DESKTOP_HINT_LINES = [
|
|
3313
|
+
"Detected macOS Screen Sharing on :5900. Starting vnc-bridge...",
|
|
3314
|
+
" If desktop view shows a black screen / connection error on the dashboard:",
|
|
3315
|
+
" \u2022 System Settings \u2192 General \u2192 Sharing \u2192 Screen Sharing must be enabled",
|
|
3316
|
+
" \u2022 System Settings \u2192 Privacy & Security \u2192 Screen Recording must grant",
|
|
3317
|
+
" permission to the macOS Screen Sharing process",
|
|
3318
|
+
" \u2022 If a VNC password was set, export BEEOS_VNC_PASSWORD=<password>",
|
|
3319
|
+
" before re-running `beeos init`."
|
|
3320
|
+
];
|
|
3321
|
+
MACOS_DESKTOP_DOCTOR_HINT_LINES = [
|
|
3322
|
+
"vnc-bridge-openclaw is failing on macOS. Likely causes:",
|
|
3323
|
+
" \u2022 System Settings \u2192 General \u2192 Sharing \u2192 Screen Sharing turned off",
|
|
3324
|
+
" \u2022 System Settings \u2192 Privacy & Security \u2192 Screen Recording missing",
|
|
3325
|
+
" permission for the macOS Screen Sharing process",
|
|
3326
|
+
" \u2022 A VNC password is set; export BEEOS_VNC_PASSWORD=<password>",
|
|
3327
|
+
" before `beeos start openclaw --force` to retry."
|
|
3328
|
+
];
|
|
3329
|
+
LINUX_VNC_HINT_LINES = [
|
|
3330
|
+
"Tip: no VNC server detected on :5901. To enable BeeOS desktop streaming:",
|
|
3331
|
+
" Debian/Ubuntu: sudo apt install tigervnc-standalone-server",
|
|
3332
|
+
" RHEL/Fedora: sudo dnf install tigervnc-server",
|
|
3333
|
+
" Arch: sudo pacman -S tigervnc",
|
|
3334
|
+
"Then run `vncserver :1` and re-run `beeos start openclaw`.",
|
|
3335
|
+
"Set BEEOS_NO_DESKTOP=1 to suppress this hint."
|
|
3336
|
+
];
|
|
3337
|
+
}
|
|
3338
|
+
});
|
|
3339
|
+
|
|
3247
3340
|
// ../core/dist/detect.js
|
|
3248
3341
|
async function detectExistingInstall() {
|
|
3249
3342
|
const p = getPlatformAdapter();
|
|
@@ -3486,12 +3579,20 @@ function buildVncBridgeTargetSpec(binary, opts) {
|
|
|
3486
3579
|
label: `vnc-bridge (${opts.serial})`
|
|
3487
3580
|
};
|
|
3488
3581
|
}
|
|
3582
|
+
function buildOpenclawDesktopVncBridgeSpec(binary, opts) {
|
|
3583
|
+
return buildVncBridgeTargetSpec(binary, {
|
|
3584
|
+
...opts,
|
|
3585
|
+
serial: OPENCLAW_VNC_BRIDGE_SERIAL
|
|
3586
|
+
});
|
|
3587
|
+
}
|
|
3588
|
+
var OPENCLAW_VNC_BRIDGE_SERIAL;
|
|
3489
3589
|
var init_target_spec = __esm({
|
|
3490
3590
|
"../core/dist/services/target-spec.js"() {
|
|
3491
3591
|
"use strict";
|
|
3492
3592
|
init_scrcpy_bridge();
|
|
3493
3593
|
init_vnc_bridge();
|
|
3494
3594
|
init_spawn_env2();
|
|
3595
|
+
OPENCLAW_VNC_BRIDGE_SERIAL = "openclaw";
|
|
3495
3596
|
}
|
|
3496
3597
|
});
|
|
3497
3598
|
|
|
@@ -4992,7 +5093,7 @@ function getCliVersion(moduleUrl, distTag) {
|
|
|
4992
5093
|
return { version, distTag: safeTag, display };
|
|
4993
5094
|
}
|
|
4994
5095
|
function resolveActiveDistTag() {
|
|
4995
|
-
const envTag =
|
|
5096
|
+
const envTag = readEnv2("BEEOS_CLI_TAG");
|
|
4996
5097
|
if (envTag && envTag.trim())
|
|
4997
5098
|
return envTag.trim();
|
|
4998
5099
|
const baked = readBakedDistTag();
|
|
@@ -5000,7 +5101,7 @@ function resolveActiveDistTag() {
|
|
|
5000
5101
|
return baked.trim();
|
|
5001
5102
|
return "latest";
|
|
5002
5103
|
}
|
|
5003
|
-
function
|
|
5104
|
+
function readEnv2(key) {
|
|
5004
5105
|
const env = globalThis.process?.env;
|
|
5005
5106
|
return env?.[key];
|
|
5006
5107
|
}
|
|
@@ -5090,6 +5191,7 @@ var init_dist = __esm({
|
|
|
5090
5191
|
init_driver2();
|
|
5091
5192
|
init_constants();
|
|
5092
5193
|
init_agent_status();
|
|
5194
|
+
init_desktop_detect();
|
|
5093
5195
|
init_detect();
|
|
5094
5196
|
init_registry();
|
|
5095
5197
|
init_target_spec();
|
|
@@ -6783,8 +6885,10 @@ async function run(agentFramework, options) {
|
|
|
6783
6885
|
};
|
|
6784
6886
|
const launchOutcome = await driver.launch(ctx, reporter);
|
|
6785
6887
|
const spec = launchOutcome.spec;
|
|
6786
|
-
const launchWarnings = launchOutcome.warnings;
|
|
6888
|
+
const launchWarnings = [...launchOutcome.warnings];
|
|
6787
6889
|
reporter.stop();
|
|
6890
|
+
const ttyHints = !options.json && process.stdin.isTTY === true;
|
|
6891
|
+
const vncEndpoint = agentFramework === OPENCLAW_ID ? await probeLocalVnc({ ttyHints }) : null;
|
|
6788
6892
|
const hostname = buildHostname();
|
|
6789
6893
|
const cachedBinding = await loadBindingInfo();
|
|
6790
6894
|
const outcome = await bindAgent({
|
|
@@ -6794,6 +6898,7 @@ async function run(agentFramework, options) {
|
|
|
6794
6898
|
fingerprint: fp,
|
|
6795
6899
|
agentFramework,
|
|
6796
6900
|
hostname,
|
|
6901
|
+
osType: vncEndpoint?.osType,
|
|
6797
6902
|
headless: options.browser === false,
|
|
6798
6903
|
cachedBinding: cachedBinding ? {
|
|
6799
6904
|
fingerprint: cachedBinding.fingerprint,
|
|
@@ -6898,6 +7003,19 @@ async function run(agentFramework, options) {
|
|
|
6898
7003
|
});
|
|
6899
7004
|
}
|
|
6900
7005
|
}
|
|
7006
|
+
if (vncEndpoint && !isOffline) {
|
|
7007
|
+
if (vncEndpoint.kind === "macos" && ttyHints) {
|
|
7008
|
+
printMacosDesktopHint();
|
|
7009
|
+
}
|
|
7010
|
+
const desktopWarning = await tryAttachOpenclawDesktopBridge({
|
|
7011
|
+
vncEndpoint,
|
|
7012
|
+
instanceId: boundInstanceId,
|
|
7013
|
+
keyFile,
|
|
7014
|
+
agentGatewayUrl,
|
|
7015
|
+
mgr
|
|
7016
|
+
});
|
|
7017
|
+
if (desktopWarning) launchWarnings.push(desktopWarning);
|
|
7018
|
+
}
|
|
6901
7019
|
const gatewayPid = status2.pid ?? void 0;
|
|
6902
7020
|
emit(options.json, {
|
|
6903
7021
|
status: isOffline ? "bound_offline" : "bound",
|
|
@@ -6910,6 +7028,36 @@ async function run(agentFramework, options) {
|
|
|
6910
7028
|
}, isOffline ? `Agent running (offline, cached instance: ${boundInstanceId})` : `Agent bound to instance: ${boundInstanceId}`);
|
|
6911
7029
|
if (!options.json) printLaunchWarnings(launchWarnings);
|
|
6912
7030
|
}
|
|
7031
|
+
async function tryAttachOpenclawDesktopBridge(params) {
|
|
7032
|
+
const reporter = new CliReporter();
|
|
7033
|
+
let binary = null;
|
|
7034
|
+
try {
|
|
7035
|
+
binary = await vncBridgeRuntime.ensureInstalled(reporter);
|
|
7036
|
+
} catch (e) {
|
|
7037
|
+
reporter.stop();
|
|
7038
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
7039
|
+
return `vnc-bridge install failed: ${reason}; OpenClaw is bound but desktop streaming is unavailable.`;
|
|
7040
|
+
}
|
|
7041
|
+
reporter.stop();
|
|
7042
|
+
if (!binary) {
|
|
7043
|
+
return `vnc-bridge binary unavailable (download or PATH lookup failed); OpenClaw is bound but desktop streaming is unavailable. Set BEEOS_VNC_BRIDGE_BIN to override.`;
|
|
7044
|
+
}
|
|
7045
|
+
const spec = buildOpenclawDesktopVncBridgeSpec(binary, {
|
|
7046
|
+
deviceId: params.instanceId,
|
|
7047
|
+
vncHost: params.vncEndpoint.host,
|
|
7048
|
+
vncPort: params.vncEndpoint.port,
|
|
7049
|
+
agentGatewayUrl: params.agentGatewayUrl,
|
|
7050
|
+
bridgePrivateKeyFile: params.keyFile,
|
|
7051
|
+
bridgePublicKeyFile: params.keyFile
|
|
7052
|
+
});
|
|
7053
|
+
try {
|
|
7054
|
+
await params.mgr.install(spec);
|
|
7055
|
+
} catch (e) {
|
|
7056
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
7057
|
+
return `vnc-bridge service install failed: ${reason}; OpenClaw is bound but desktop streaming is unavailable. Re-run \`beeos start openclaw --force\` to retry.`;
|
|
7058
|
+
}
|
|
7059
|
+
return null;
|
|
7060
|
+
}
|
|
6913
7061
|
function buildHostname() {
|
|
6914
7062
|
const machine = os6.hostname();
|
|
6915
7063
|
const user = process.env.USER || process.env.USERNAME || "";
|
|
@@ -7538,6 +7686,17 @@ async function run8(options) {
|
|
|
7538
7686
|
`service '${s.id}' looks like its Node binary moved (exit 127). Re-run \`beeos start ${s.id} --force\` to refresh the service definition with the current node path.`
|
|
7539
7687
|
);
|
|
7540
7688
|
}
|
|
7689
|
+
if (s.id === `vnc-bridge-${OPENCLAW_VNC_BRIDGE_SERIAL}`) {
|
|
7690
|
+
if (process.platform === "darwin") {
|
|
7691
|
+
for (const line of MACOS_DESKTOP_DOCTOR_HINT_LINES) {
|
|
7692
|
+
hints.push(line);
|
|
7693
|
+
}
|
|
7694
|
+
} else {
|
|
7695
|
+
hints.push(
|
|
7696
|
+
`vnc-bridge-${OPENCLAW_VNC_BRIDGE_SERIAL} is failing \u2014 see ${s.logFile} for the underlying error. Common causes: VNC server moved port, BEEOS_VNC_PASSWORD missing/incorrect, network blocking outbound MQTT.`
|
|
7697
|
+
);
|
|
7698
|
+
}
|
|
7699
|
+
}
|
|
7541
7700
|
}
|
|
7542
7701
|
}
|
|
7543
7702
|
if (!tools.adb.path) {
|