@beeos-ai/cli 1.0.19 → 1.0.20

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.
Files changed (2) hide show
  1. package/dist/index.js +149 -11
  2. 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 {
@@ -3244,6 +3248,74 @@ var init_agent_status = __esm({
3244
3248
  }
3245
3249
  });
3246
3250
 
3251
+ // ../core/dist/openclaw/desktop-detect.js
3252
+ function printMacosDesktopHint() {
3253
+ for (const line of MACOS_DESKTOP_HINT_LINES)
3254
+ console.log(line);
3255
+ }
3256
+ function readEnv(name) {
3257
+ return globalThis.process?.env?.[name];
3258
+ }
3259
+ async function probeLocalVnc(opts = {}) {
3260
+ if (readEnv("BEEOS_NO_DESKTOP") === "1")
3261
+ return null;
3262
+ const p = getPlatformAdapter();
3263
+ const platform = p.platform();
3264
+ if (platform !== "darwin" && platform !== "linux") {
3265
+ return null;
3266
+ }
3267
+ const host = "127.0.0.1";
3268
+ const timeoutMs = 200;
3269
+ if (platform === "darwin") {
3270
+ const ok2 = await p.tcpProbe(host, 5900, timeoutMs).catch(() => false);
3271
+ if (ok2) {
3272
+ return { kind: "macos", host, port: 5900, osType: "macos-desktop" };
3273
+ }
3274
+ return null;
3275
+ }
3276
+ const ok = await p.tcpProbe(host, 5901, timeoutMs).catch(() => false);
3277
+ if (ok) {
3278
+ return { kind: "linux", host, port: 5901, osType: "linux-desktop" };
3279
+ }
3280
+ if (opts.ttyHints) {
3281
+ for (const line of LINUX_VNC_HINT_LINES)
3282
+ console.log(line);
3283
+ }
3284
+ return null;
3285
+ }
3286
+ var MACOS_DESKTOP_HINT_LINES, MACOS_DESKTOP_DOCTOR_HINT_LINES, LINUX_VNC_HINT_LINES;
3287
+ var init_desktop_detect = __esm({
3288
+ "../core/dist/openclaw/desktop-detect.js"() {
3289
+ "use strict";
3290
+ init_platform_adapter();
3291
+ MACOS_DESKTOP_HINT_LINES = [
3292
+ "Detected macOS Screen Sharing on :5900. Starting vnc-bridge...",
3293
+ " If desktop view shows a black screen / connection error on the dashboard:",
3294
+ " \u2022 System Settings \u2192 General \u2192 Sharing \u2192 Screen Sharing must be enabled",
3295
+ " \u2022 System Settings \u2192 Privacy & Security \u2192 Screen Recording must grant",
3296
+ " permission to the macOS Screen Sharing process",
3297
+ " \u2022 If a VNC password was set, export BEEOS_VNC_PASSWORD=<password>",
3298
+ " before re-running `beeos init`."
3299
+ ];
3300
+ MACOS_DESKTOP_DOCTOR_HINT_LINES = [
3301
+ "vnc-bridge-openclaw is failing on macOS. Likely causes:",
3302
+ " \u2022 System Settings \u2192 General \u2192 Sharing \u2192 Screen Sharing turned off",
3303
+ " \u2022 System Settings \u2192 Privacy & Security \u2192 Screen Recording missing",
3304
+ " permission for the macOS Screen Sharing process",
3305
+ " \u2022 A VNC password is set; export BEEOS_VNC_PASSWORD=<password>",
3306
+ " before `beeos start openclaw --force` to retry."
3307
+ ];
3308
+ LINUX_VNC_HINT_LINES = [
3309
+ "Tip: no VNC server detected on :5901. To enable BeeOS desktop streaming:",
3310
+ " Debian/Ubuntu: sudo apt install tigervnc-standalone-server",
3311
+ " RHEL/Fedora: sudo dnf install tigervnc-server",
3312
+ " Arch: sudo pacman -S tigervnc",
3313
+ "Then run `vncserver :1` and re-run `beeos start openclaw`.",
3314
+ "Set BEEOS_NO_DESKTOP=1 to suppress this hint."
3315
+ ];
3316
+ }
3317
+ });
3318
+
3247
3319
  // ../core/dist/detect.js
3248
3320
  async function detectExistingInstall() {
3249
3321
  const p = getPlatformAdapter();
@@ -3486,12 +3558,20 @@ function buildVncBridgeTargetSpec(binary, opts) {
3486
3558
  label: `vnc-bridge (${opts.serial})`
3487
3559
  };
3488
3560
  }
3561
+ function buildOpenclawDesktopVncBridgeSpec(binary, opts) {
3562
+ return buildVncBridgeTargetSpec(binary, {
3563
+ ...opts,
3564
+ serial: OPENCLAW_VNC_BRIDGE_SERIAL
3565
+ });
3566
+ }
3567
+ var OPENCLAW_VNC_BRIDGE_SERIAL;
3489
3568
  var init_target_spec = __esm({
3490
3569
  "../core/dist/services/target-spec.js"() {
3491
3570
  "use strict";
3492
3571
  init_scrcpy_bridge();
3493
3572
  init_vnc_bridge();
3494
3573
  init_spawn_env2();
3574
+ OPENCLAW_VNC_BRIDGE_SERIAL = "openclaw";
3495
3575
  }
3496
3576
  });
3497
3577
 
@@ -4992,7 +5072,7 @@ function getCliVersion(moduleUrl, distTag) {
4992
5072
  return { version, distTag: safeTag, display };
4993
5073
  }
4994
5074
  function resolveActiveDistTag() {
4995
- const envTag = readEnv("BEEOS_CLI_TAG");
5075
+ const envTag = readEnv2("BEEOS_CLI_TAG");
4996
5076
  if (envTag && envTag.trim())
4997
5077
  return envTag.trim();
4998
5078
  const baked = readBakedDistTag();
@@ -5000,7 +5080,7 @@ function resolveActiveDistTag() {
5000
5080
  return baked.trim();
5001
5081
  return "latest";
5002
5082
  }
5003
- function readEnv(key) {
5083
+ function readEnv2(key) {
5004
5084
  const env = globalThis.process?.env;
5005
5085
  return env?.[key];
5006
5086
  }
@@ -5090,6 +5170,7 @@ var init_dist = __esm({
5090
5170
  init_driver2();
5091
5171
  init_constants();
5092
5172
  init_agent_status();
5173
+ init_desktop_detect();
5093
5174
  init_detect();
5094
5175
  init_registry();
5095
5176
  init_target_spec();
@@ -6783,8 +6864,10 @@ async function run(agentFramework, options) {
6783
6864
  };
6784
6865
  const launchOutcome = await driver.launch(ctx, reporter);
6785
6866
  const spec = launchOutcome.spec;
6786
- const launchWarnings = launchOutcome.warnings;
6867
+ const launchWarnings = [...launchOutcome.warnings];
6787
6868
  reporter.stop();
6869
+ const ttyHints = !options.json && process.stdin.isTTY === true;
6870
+ const vncEndpoint = agentFramework === OPENCLAW_ID ? await probeLocalVnc({ ttyHints }) : null;
6788
6871
  const hostname = buildHostname();
6789
6872
  const cachedBinding = await loadBindingInfo();
6790
6873
  const outcome = await bindAgent({
@@ -6794,6 +6877,7 @@ async function run(agentFramework, options) {
6794
6877
  fingerprint: fp,
6795
6878
  agentFramework,
6796
6879
  hostname,
6880
+ osType: vncEndpoint?.osType,
6797
6881
  headless: options.browser === false,
6798
6882
  cachedBinding: cachedBinding ? {
6799
6883
  fingerprint: cachedBinding.fingerprint,
@@ -6898,6 +6982,19 @@ async function run(agentFramework, options) {
6898
6982
  });
6899
6983
  }
6900
6984
  }
6985
+ if (vncEndpoint && !isOffline) {
6986
+ if (vncEndpoint.kind === "macos" && ttyHints) {
6987
+ printMacosDesktopHint();
6988
+ }
6989
+ const desktopWarning = await tryAttachOpenclawDesktopBridge({
6990
+ vncEndpoint,
6991
+ instanceId: boundInstanceId,
6992
+ keyFile,
6993
+ agentGatewayUrl,
6994
+ mgr
6995
+ });
6996
+ if (desktopWarning) launchWarnings.push(desktopWarning);
6997
+ }
6901
6998
  const gatewayPid = status2.pid ?? void 0;
6902
6999
  emit(options.json, {
6903
7000
  status: isOffline ? "bound_offline" : "bound",
@@ -6910,6 +7007,36 @@ async function run(agentFramework, options) {
6910
7007
  }, isOffline ? `Agent running (offline, cached instance: ${boundInstanceId})` : `Agent bound to instance: ${boundInstanceId}`);
6911
7008
  if (!options.json) printLaunchWarnings(launchWarnings);
6912
7009
  }
7010
+ async function tryAttachOpenclawDesktopBridge(params) {
7011
+ const reporter = new CliReporter();
7012
+ let binary = null;
7013
+ try {
7014
+ binary = await vncBridgeRuntime.ensureInstalled(reporter);
7015
+ } catch (e) {
7016
+ reporter.stop();
7017
+ const reason = e instanceof Error ? e.message : String(e);
7018
+ return `vnc-bridge install failed: ${reason}; OpenClaw is bound but desktop streaming is unavailable.`;
7019
+ }
7020
+ reporter.stop();
7021
+ if (!binary) {
7022
+ 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.`;
7023
+ }
7024
+ const spec = buildOpenclawDesktopVncBridgeSpec(binary, {
7025
+ deviceId: params.instanceId,
7026
+ vncHost: params.vncEndpoint.host,
7027
+ vncPort: params.vncEndpoint.port,
7028
+ agentGatewayUrl: params.agentGatewayUrl,
7029
+ bridgePrivateKeyFile: params.keyFile,
7030
+ bridgePublicKeyFile: params.keyFile
7031
+ });
7032
+ try {
7033
+ await params.mgr.install(spec);
7034
+ } catch (e) {
7035
+ const reason = e instanceof Error ? e.message : String(e);
7036
+ return `vnc-bridge service install failed: ${reason}; OpenClaw is bound but desktop streaming is unavailable. Re-run \`beeos start openclaw --force\` to retry.`;
7037
+ }
7038
+ return null;
7039
+ }
6913
7040
  function buildHostname() {
6914
7041
  const machine = os6.hostname();
6915
7042
  const user = process.env.USER || process.env.USERNAME || "";
@@ -7538,6 +7665,17 @@ async function run8(options) {
7538
7665
  `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
7666
  );
7540
7667
  }
7668
+ if (s.id === `vnc-bridge-${OPENCLAW_VNC_BRIDGE_SERIAL}`) {
7669
+ if (process.platform === "darwin") {
7670
+ for (const line of MACOS_DESKTOP_DOCTOR_HINT_LINES) {
7671
+ hints.push(line);
7672
+ }
7673
+ } else {
7674
+ hints.push(
7675
+ `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.`
7676
+ );
7677
+ }
7678
+ }
7541
7679
  }
7542
7680
  }
7543
7681
  if (!tools.adb.path) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beeos-ai/cli",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "type": "module",
5
5
  "description": "BeeOS CLI — run AI agents from your desktop",
6
6
  "bin": {