@beeos-ai/cli 1.0.3 → 1.0.4

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 +215 -117
  2. package/package.json +10 -11
package/dist/index.js CHANGED
@@ -67,17 +67,17 @@ function bindingPath() {
67
67
  const p = getPlatformAdapter();
68
68
  return p.joinPath(beeoHome(), "binding.json");
69
69
  }
70
- function agentDir(agentType) {
70
+ function agentDir(agentFramework) {
71
71
  const p = getPlatformAdapter();
72
- return p.joinPath(beeoHome(), "agents", agentType);
72
+ return p.joinPath(beeoHome(), "agents", agentFramework);
73
73
  }
74
- function agentHome(agentType) {
74
+ function agentHome(agentFramework) {
75
75
  const p = getPlatformAdapter();
76
- return p.joinPath(agentDir(agentType), "home");
76
+ return p.joinPath(agentDir(agentFramework), "home");
77
77
  }
78
- function pidFile(agentType) {
78
+ function pidFile(agentFramework) {
79
79
  const p = getPlatformAdapter();
80
- return p.joinPath(beeoHome(), `${agentType}.pid`);
80
+ return p.joinPath(beeoHome(), `${agentFramework}.pid`);
81
81
  }
82
82
  async function loadOrCreateConfig() {
83
83
  const p = getPlatformAdapter();
@@ -188,41 +188,54 @@ async function loadOrCreateGatewayToken() {
188
188
  }
189
189
  return token;
190
190
  }
191
- async function readPid(agentType) {
191
+ async function readPid(agentFramework) {
192
192
  const p = getPlatformAdapter();
193
- const path2 = pidFile(agentType);
193
+ const path2 = pidFile(agentFramework);
194
194
  if (!await p.exists(path2))
195
195
  return null;
196
196
  const raw = (await p.readFile(path2)).trim();
197
197
  const pid = parseInt(raw, 10);
198
198
  return isNaN(pid) ? null : pid;
199
199
  }
200
- async function writePid(agentType, pid) {
200
+ async function writePid(agentFramework, pid) {
201
201
  const p = getPlatformAdapter();
202
- await p.writeFile(pidFile(agentType), String(pid));
202
+ await p.writeFile(pidFile(agentFramework), String(pid));
203
203
  }
204
- async function removePid(agentType) {
204
+ async function removePid(agentFramework) {
205
205
  const p = getPlatformAdapter();
206
- const path2 = pidFile(agentType);
206
+ const path2 = pidFile(agentFramework);
207
207
  if (await p.exists(path2)) {
208
208
  await p.rm(path2);
209
209
  }
210
210
  }
211
211
 
212
212
  // ../core/dist/identity/keypair.js
213
- import { createHash } from "crypto";
214
213
  import * as ed from "@noble/ed25519";
215
214
  import { sha512 } from "@noble/hashes/sha512";
215
+ import { sha256 } from "@noble/hashes/sha256";
216
+ import { bytesToHex } from "@noble/hashes/utils";
216
217
  ed.etc.sha512Sync = (...m) => sha512(ed.etc.concatBytes(...m));
218
+ function toBase64(bytes) {
219
+ let binary = "";
220
+ for (let i = 0; i < bytes.length; i++)
221
+ binary += String.fromCharCode(bytes[i]);
222
+ return btoa(binary);
223
+ }
224
+ function fromBase64(b64) {
225
+ const binary = atob(b64);
226
+ const bytes = new Uint8Array(binary.length);
227
+ for (let i = 0; i < binary.length; i++)
228
+ bytes[i] = binary.charCodeAt(i);
229
+ return bytes;
230
+ }
217
231
  function publicKeyB64(id) {
218
- return Buffer.from(id.publicKey).toString("base64");
232
+ return toBase64(id.publicKey);
219
233
  }
220
234
  function fingerprint(id) {
221
- return createHash("sha256").update(id.publicKey).digest("hex");
235
+ return bytesToHex(sha256(id.publicKey));
222
236
  }
223
237
  function fingerprintFromB64(pubkeyB64) {
224
- const raw = Buffer.from(pubkeyB64, "base64");
225
- return createHash("sha256").update(raw).digest("hex");
238
+ return bytesToHex(sha256(fromBase64(pubkeyB64)));
226
239
  }
227
240
  async function loadOrCreateIdentity() {
228
241
  const p = getPlatformAdapter();
@@ -240,8 +253,8 @@ async function ensureDeviceKey(keyPath) {
240
253
  return;
241
254
  const id = generate();
242
255
  const stored = {
243
- publicKey: Buffer.from(id.publicKey).toString("base64"),
244
- privateKey: Buffer.from(id.privateKey).toString("base64")
256
+ publicKey: toBase64(id.publicKey),
257
+ privateKey: toBase64(id.privateKey)
245
258
  };
246
259
  await p.mkdir(p.dirname(keyPath));
247
260
  await p.writeFile(keyPath, JSON.stringify(stored, null, 2));
@@ -269,7 +282,7 @@ async function loadFromFile(path2) {
269
282
  const p = getPlatformAdapter();
270
283
  const raw = await p.readFile(path2);
271
284
  const stored = JSON.parse(raw);
272
- const privateKey = new Uint8Array(Buffer.from(stored.privateKey, "base64"));
285
+ const privateKey = fromBase64(stored.privateKey);
273
286
  if (privateKey.length !== 32) {
274
287
  throw new Error(`private key seed must be 32 bytes, got ${privateKey.length}`);
275
288
  }
@@ -284,8 +297,8 @@ function generate() {
284
297
  async function save(id) {
285
298
  const p = getPlatformAdapter();
286
299
  const stored = {
287
- publicKey: Buffer.from(id.publicKey).toString("base64"),
288
- privateKey: Buffer.from(id.privateKey).toString("base64")
300
+ publicKey: toBase64(id.publicKey),
301
+ privateKey: toBase64(id.privateKey)
289
302
  };
290
303
  const kpPath = keypairPath();
291
304
  await p.mkdir(p.dirname(kpPath));
@@ -353,7 +366,7 @@ function buildBindUrl(dashboardBaseUrl, bindId) {
353
366
  const base = dashboardBaseUrl.replace(/\/+$/, "");
354
367
  return `${base}/bind/${bindId}`;
355
368
  }
356
- async function agentBind(apiUrl, publicKey, fingerprint2, agentType, hostname) {
369
+ async function agentBind(apiUrl, publicKey, fingerprint2, agentFramework, hostname) {
357
370
  const p = getPlatformAdapter();
358
371
  const url = `${apiUrl}/api/v1/agent/bind`;
359
372
  const resp = await p.fetch(url, {
@@ -362,7 +375,7 @@ async function agentBind(apiUrl, publicKey, fingerprint2, agentType, hostname) {
362
375
  body: JSON.stringify({
363
376
  public_key: publicKey,
364
377
  fingerprint: fingerprint2,
365
- agent_type: agentType,
378
+ agent_framework: agentFramework,
366
379
  hostname
367
380
  })
368
381
  });
@@ -761,7 +774,7 @@ ${stderr}`);
761
774
 
762
775
  // ../core/dist/runtime/device.js
763
776
  var deviceRuntime = {
764
- agentType() {
777
+ agentFramework() {
765
778
  return "device";
766
779
  },
767
780
  displayName() {
@@ -872,9 +885,9 @@ var GATEWAY_PORT = 18789;
872
885
  async function isGatewayRunning() {
873
886
  return getPlatformAdapter().tcpProbe("127.0.0.1", GATEWAY_PORT, 500);
874
887
  }
875
- async function managedBinary2(agentType) {
888
+ async function managedBinary2(agentFramework) {
876
889
  const p = getPlatformAdapter();
877
- const base = agentDir(agentType);
890
+ const base = agentDir(agentFramework);
878
891
  const currentLink = p.joinPath(base, "versions", "current");
879
892
  if (!await p.exists(currentLink))
880
893
  return null;
@@ -895,15 +908,35 @@ async function managedBinary2(agentType) {
895
908
  const mjs = p.joinPath(resolved, "node_modules", "openclaw", "openclaw.mjs");
896
909
  if (await p.exists(mjs))
897
910
  return mjs;
911
+ const rootMjs = p.joinPath(resolved, "openclaw.mjs");
912
+ if (await p.exists(rootMjs))
913
+ return rootMjs;
914
+ return null;
915
+ }
916
+ async function readLocalPluginVersion(agentHome2) {
917
+ const p = getPlatformAdapter();
918
+ for (const rel of [
919
+ p.joinPath("extensions", "beeos-claw", "package.json"),
920
+ p.joinPath("extensions", "beeos-claw", "node_modules", "beeos-claw", "package.json")
921
+ ]) {
922
+ const fullPath = p.joinPath(agentHome2, rel);
923
+ try {
924
+ const raw = await p.readFile(fullPath);
925
+ const parsed = JSON.parse(raw);
926
+ if (typeof parsed.version === "string")
927
+ return parsed.version;
928
+ } catch {
929
+ }
930
+ }
898
931
  return null;
899
932
  }
900
933
  async function findAgent(driver) {
901
- const managed = await managedBinary2(driver.agentType());
934
+ const managed = await managedBinary2(driver.agentFramework());
902
935
  if (managed) {
903
936
  return {
904
937
  type: "managed",
905
938
  binary: managed,
906
- home: agentHome(driver.agentType())
939
+ home: agentHome(driver.agentFramework())
907
940
  };
908
941
  }
909
942
  const local = await driver.detectLocal();
@@ -919,7 +952,7 @@ async function findAgent(driver) {
919
952
  }
920
953
 
921
954
  // ../core/dist/agent/downloader.js
922
- async function downloadAgent(npmPackage, requestedVersion, agentType, progress) {
955
+ async function downloadAgent(npmPackage, requestedVersion, agentFramework, progress) {
923
956
  const p = getPlatformAdapter();
924
957
  const info = await fetchNpmPackageInfo(npmPackage);
925
958
  const version = requestedVersion ?? info["dist-tags"]["latest"];
@@ -928,7 +961,7 @@ async function downloadAgent(npmPackage, requestedVersion, agentType, progress)
928
961
  const verInfo = info.versions[version];
929
962
  if (!verInfo)
930
963
  throw new Error(`version ${version} not found in npm registry`);
931
- const versionsDir = p.joinPath(agentDir(agentType), "versions");
964
+ const versionsDir = p.joinPath(agentDir(agentFramework), "versions");
932
965
  const dest = p.joinPath(versionsDir, version);
933
966
  if (await p.exists(dest)) {
934
967
  progress.onStatus(`${npmPackage} v${version} already downloaded`);
@@ -954,19 +987,28 @@ async function downloadAgent(npmPackage, requestedVersion, agentType, progress)
954
987
  }
955
988
  return dest;
956
989
  }
957
- async function downloadPlugin(pluginPackage, agentType, progress) {
990
+ async function downloadPlugin(pluginPackage, agentFramework, progress, installedVersion) {
958
991
  const p = getPlatformAdapter();
959
992
  const info = await fetchNpmPackageInfo(pluginPackage);
960
993
  const version = info["dist-tags"]["latest"];
961
994
  if (!version)
962
995
  throw new Error("no 'latest' tag for plugin");
996
+ if (installedVersion && semverGte(installedVersion, version)) {
997
+ progress.onStatus(`${pluginPackage} v${installedVersion} is up to date`);
998
+ const cacheDir2 = p.joinPath(agentDir(agentFramework), "beeos-claw");
999
+ const existing = p.joinPath(cacheDir2, version);
1000
+ if (await p.exists(existing))
1001
+ return existing;
1002
+ }
963
1003
  const verInfo = info.versions[version];
964
1004
  if (!verInfo)
965
1005
  throw new Error("plugin version not found");
966
- const cacheDir = p.joinPath(agentDir(agentType), "beeos-claw");
1006
+ const cacheDir = p.joinPath(agentDir(agentFramework), "beeos-claw");
967
1007
  const dest = p.joinPath(cacheDir, version);
968
- if (await p.exists(dest))
1008
+ if (await p.exists(dest)) {
1009
+ progress.onStatus(`${pluginPackage} v${version} already cached`);
969
1010
  return dest;
1011
+ }
970
1012
  progress.onStatus(`Downloading ${pluginPackage} v${version} ...`);
971
1013
  const data = await downloadTarball(verInfo.dist.tarball);
972
1014
  await extractTarball(data, dest);
@@ -974,6 +1016,7 @@ async function downloadPlugin(pluginPackage, agentType, progress) {
974
1016
  if (await p.exists(pkgJson)) {
975
1017
  await runNpmInstall(dest);
976
1018
  }
1019
+ progress.onComplete(`${pluginPackage} v${version} ready`);
977
1020
  return dest;
978
1021
  }
979
1022
  async function extractTarball(data, dest) {
@@ -1004,9 +1047,22 @@ async function runNpmInstall(dir) {
1004
1047
  throw new Error(`npm install failed with exit code ${result.code}`);
1005
1048
  }
1006
1049
  }
1050
+ function semverGte(version, minVersion) {
1051
+ const parse2 = (s) => s.split(".").map((p) => parseInt(p, 10) || 0);
1052
+ const a = parse2(version);
1053
+ const b = parse2(minVersion);
1054
+ for (let i = 0; i < 3; i++) {
1055
+ if ((a[i] ?? 0) > (b[i] ?? 0))
1056
+ return true;
1057
+ if ((a[i] ?? 0) < (b[i] ?? 0))
1058
+ return false;
1059
+ }
1060
+ return true;
1061
+ }
1007
1062
 
1008
1063
  // ../core/dist/agent/launcher.js
1009
- import { createHash as createHash2 } from "crypto";
1064
+ import { sha256 as sha2562 } from "@noble/hashes/sha256";
1065
+ import { bytesToHex as bytesToHex2 } from "@noble/hashes/utils";
1010
1066
  var MAX_BACKUPS = 5;
1011
1067
  async function backupOpenclawConfig(agentHome2) {
1012
1068
  const p = getPlatformAdapter();
@@ -1152,6 +1208,28 @@ async function spawnOpenclaw(ctx) {
1152
1208
  });
1153
1209
  return result.pid;
1154
1210
  }
1211
+ async function installPluginToHome(agentHome2, pluginDir) {
1212
+ const p = getPlatformAdapter();
1213
+ const dest = p.joinPath(agentHome2, "extensions", "beeos-claw");
1214
+ if (await p.exists(dest)) {
1215
+ await p.rmdir(dest);
1216
+ }
1217
+ await copyDirRecursive(pluginDir, dest);
1218
+ }
1219
+ async function copyDirRecursive(src, dst) {
1220
+ const p = getPlatformAdapter();
1221
+ await p.mkdir(dst);
1222
+ const entries = await p.readdir(src);
1223
+ for (const name of entries) {
1224
+ const srcPath = p.joinPath(src, name);
1225
+ const dstPath = p.joinPath(dst, name);
1226
+ if (await p.isDirectory(srcPath)) {
1227
+ await copyDirRecursive(srcPath, dstPath);
1228
+ } else {
1229
+ await p.copyFile(srcPath, dstPath);
1230
+ }
1231
+ }
1232
+ }
1155
1233
  async function writePairedJson(home, keyFile) {
1156
1234
  const p = getPlatformAdapter();
1157
1235
  const devicesDir = p.joinPath(home, "devices");
@@ -1167,8 +1245,11 @@ async function writePairedJson(home, keyFile) {
1167
1245
  }
1168
1246
  let deviceId = "beeos-claw-device";
1169
1247
  if (pubKeyB64) {
1170
- const decoded = Buffer.from(pubKeyB64, "base64");
1171
- const hash = createHash2("sha256").update(decoded).digest("hex");
1248
+ const binary = atob(pubKeyB64);
1249
+ const decoded = new Uint8Array(binary.length);
1250
+ for (let i = 0; i < binary.length; i++)
1251
+ decoded[i] = binary.charCodeAt(i);
1252
+ const hash = bytesToHex2(sha2562(decoded));
1172
1253
  deviceId = `beeos-claw-${hash.slice(0, 12)}`;
1173
1254
  }
1174
1255
  const paired = {
@@ -1188,7 +1269,7 @@ async function writePairedJson(home, keyFile) {
1188
1269
 
1189
1270
  // ../core/dist/agent/registry.js
1190
1271
  var openClawDriver = {
1191
- agentType() {
1272
+ agentFramework() {
1192
1273
  return "openclaw";
1193
1274
  },
1194
1275
  npmPackage() {
@@ -1223,7 +1304,7 @@ var openClawDriver = {
1223
1304
  // ../core/dist/runtime/openclaw.js
1224
1305
  var GATEWAY_PORT2 = 18789;
1225
1306
  var openclawRuntime = {
1226
- agentType() {
1307
+ agentFramework() {
1227
1308
  return "openclaw";
1228
1309
  },
1229
1310
  displayName() {
@@ -1259,11 +1340,11 @@ var openclawRuntime = {
1259
1340
  async isHealthy() {
1260
1341
  return getPlatformAdapter().tcpProbe("127.0.0.1", GATEWAY_PORT2, 500);
1261
1342
  },
1262
- async stop(agentType) {
1263
- const pid = await readPid(agentType);
1343
+ async stop(agentFramework) {
1344
+ const pid = await readPid(agentFramework);
1264
1345
  if (pid != null) {
1265
1346
  killProcess(pid);
1266
- await removePid(agentType);
1347
+ await removePid(agentFramework);
1267
1348
  }
1268
1349
  },
1269
1350
  async update(progress) {
@@ -1272,6 +1353,48 @@ var openclawRuntime = {
1272
1353
  }
1273
1354
  };
1274
1355
 
1356
+ // ../core/dist/service/local-agent.js
1357
+ async function ensurePlugin(agentFramework, agentHomeDir, progress) {
1358
+ const currentVersion = await readLocalPluginVersion(agentHomeDir) ?? void 0;
1359
+ const pluginDir = await downloadPlugin(openClawDriver.pluginPackage(), agentFramework, progress, currentVersion);
1360
+ await installPluginToHome(agentHomeDir, pluginDir);
1361
+ }
1362
+ async function bind(options) {
1363
+ const resp = await agentBind(options.apiUrl, options.publicKey, options.fingerprint, options.agentFramework, options.hostname);
1364
+ if (resp.status === "bound") {
1365
+ const instanceId = resp.instance_id ?? "";
1366
+ await saveBindingInfo({
1367
+ fingerprint: options.fingerprint,
1368
+ instance_id: instanceId,
1369
+ bound_at: Math.floor(Date.now() / 1e3)
1370
+ });
1371
+ return { status: "bound", instanceId };
1372
+ }
1373
+ if (resp.status === "pending") {
1374
+ const bindId = resp.bind_id ?? "";
1375
+ const bindUrl = buildBindUrl(options.dashboardBaseUrl, bindId);
1376
+ await removeBindingInfo();
1377
+ if (options.confirmFn) {
1378
+ const instanceId2 = await options.confirmFn(bindId);
1379
+ await saveBindingInfo({
1380
+ fingerprint: options.fingerprint,
1381
+ instance_id: instanceId2,
1382
+ bound_at: Math.floor(Date.now() / 1e3)
1383
+ });
1384
+ return { status: "bound", instanceId: instanceId2 };
1385
+ }
1386
+ await presentBindUrl(bindUrl, options.headless ?? false);
1387
+ const instanceId = await pollUntilBound(options.apiUrl, bindId, 6e5);
1388
+ await saveBindingInfo({
1389
+ fingerprint: options.fingerprint,
1390
+ instance_id: instanceId,
1391
+ bound_at: Math.floor(Date.now() / 1e3)
1392
+ });
1393
+ return { status: "bound", instanceId };
1394
+ }
1395
+ throw new Error(`unexpected bind status: ${resp.status}`);
1396
+ }
1397
+
1275
1398
  // src/node-adapter.ts
1276
1399
  import {
1277
1400
  execFile,
@@ -1515,13 +1638,13 @@ var CliReporter = class {
1515
1638
  };
1516
1639
 
1517
1640
  // src/commands/start.ts
1518
- async function run(agentType, options) {
1641
+ async function run(agentFramework, options) {
1519
1642
  const p = getPlatformAdapter();
1520
1643
  await ensureDirs();
1521
1644
  const cfg = await loadOrCreateConfig();
1522
1645
  const reporter = new CliReporter();
1523
- if (agentType !== "openclaw") {
1524
- throw new Error(`Agent type '${agentType}' is not yet supported. Use 'openclaw'.`);
1646
+ if (agentFramework !== "openclaw") {
1647
+ throw new Error(`Agent framework '${agentFramework}' is not yet supported. Use 'openclaw'.`);
1525
1648
  }
1526
1649
  const identity = await loadOrCreateIdentity();
1527
1650
  const fp = fingerprint(identity);
@@ -1536,13 +1659,16 @@ async function run(agentType, options) {
1536
1659
  if (location.type === "managed") {
1537
1660
  binary = location.binary;
1538
1661
  home = location.home;
1662
+ try {
1663
+ await ensurePlugin(agentFramework, home, reporter);
1664
+ } catch {
1665
+ }
1539
1666
  } else if (location.type === "system") {
1540
1667
  binary = location.binary;
1541
1668
  home = location.home;
1542
1669
  isSystemHome = true;
1543
1670
  try {
1544
- const pluginDir = await downloadPlugin(openClawDriver.pluginPackage(), agentType, reporter);
1545
- await installPluginToHome(home, pluginDir, binary);
1671
+ await ensurePlugin(agentFramework, home, reporter);
1546
1672
  } catch {
1547
1673
  }
1548
1674
  const systemToken = await readExistingGatewayToken(home);
@@ -1569,11 +1695,11 @@ async function run(agentType, options) {
1569
1695
  }
1570
1696
  } else {
1571
1697
  reporter.onStatus(`Downloading ${openClawDriver.npmPackage()}...`);
1572
- await downloadAgent(openClawDriver.npmPackage(), options.version ?? void 0, agentType, reporter);
1573
- home = agentHome(agentType);
1698
+ await downloadAgent(openClawDriver.npmPackage(), options.version ?? void 0, agentFramework, reporter);
1699
+ home = agentHome(agentFramework);
1574
1700
  await p.mkdir(home);
1575
- await downloadPlugin(openClawDriver.pluginPackage(), agentType, reporter);
1576
- const managedBin = await managedBinary2(agentType);
1701
+ await ensurePlugin(agentFramework, home, reporter);
1702
+ const managedBin = await managedBinary2(agentFramework);
1577
1703
  if (!managedBin) throw new Error("agent binary not found after download");
1578
1704
  binary = managedBin;
1579
1705
  }
@@ -1595,7 +1721,7 @@ async function run(agentType, options) {
1595
1721
  await generateOpenclawConfig(ctx);
1596
1722
  }
1597
1723
  const pid = await spawnOpenclaw(ctx);
1598
- await writePid(agentType, pid);
1724
+ await writePid(agentFramework, pid);
1599
1725
  gatewayPid = pid;
1600
1726
  let alive = false;
1601
1727
  for (let i = 0; i < 10; i++) {
@@ -1609,55 +1735,52 @@ async function run(agentType, options) {
1609
1735
  throw new Error("Agent gateway did not start within 5s");
1610
1736
  }
1611
1737
  } else {
1612
- gatewayPid = await readPid(agentType) ?? void 0;
1738
+ gatewayPid = await readPid(agentFramework) ?? void 0;
1613
1739
  }
1614
1740
  const hostname = buildHostname();
1615
1741
  try {
1616
- const resp = await agentBind(cfg.platform.api_url, pubkey, fp, agentType, hostname);
1617
- if (resp.status === "bound") {
1618
- const instanceId = resp.instance_id ?? "";
1619
- await saveBindingInfo({ fingerprint: fp, instance_id: instanceId, bound_at: nowUnix() });
1620
- const result = {
1742
+ const result = await bind({
1743
+ apiUrl: cfg.platform.api_url,
1744
+ dashboardBaseUrl: cfg.platform.dashboard_base_url,
1745
+ publicKey: pubkey,
1746
+ fingerprint: fp,
1747
+ agentFramework,
1748
+ hostname,
1749
+ headless: options.browser === false
1750
+ });
1751
+ if (result.status === "bound") {
1752
+ const out = {
1621
1753
  status: "bound",
1622
1754
  public_key: pubkey,
1623
1755
  fingerprint: fp,
1624
1756
  gateway_url: "http://127.0.0.1:18789",
1625
1757
  gateway_pid: gatewayPid,
1626
1758
  bridge_url: cfg.platform.bridge_url,
1627
- instance_id: instanceId
1759
+ instance_id: result.instanceId
1628
1760
  };
1629
1761
  if (options.json) {
1630
- console.log(JSON.stringify(result, null, 2));
1762
+ console.log(JSON.stringify(out, null, 2));
1631
1763
  } else {
1632
- console.log(`Agent bound to instance: ${instanceId}`);
1764
+ console.log(`Agent bound to instance: ${result.instanceId}`);
1633
1765
  }
1634
1766
  return;
1635
1767
  }
1636
- if (resp.status === "pending") {
1637
- const bindId = resp.bind_id ?? "";
1638
- const bindUrl = buildBindUrl(cfg.platform.dashboard_base_url, bindId);
1639
- await removeBindingInfo();
1768
+ if (result.status === "pending") {
1640
1769
  if (options.json) {
1641
- const result = {
1770
+ const out = {
1642
1771
  status: "pending",
1643
1772
  public_key: pubkey,
1644
1773
  fingerprint: fp,
1645
- bind_id: bindId,
1646
- bind_url: bindUrl,
1647
- qr_data: bindUrl,
1774
+ bind_id: result.bindId,
1775
+ bind_url: result.bindUrl,
1776
+ qr_data: result.bindUrl,
1648
1777
  gateway_url: "http://127.0.0.1:18789",
1649
1778
  gateway_pid: gatewayPid,
1650
1779
  bridge_url: cfg.platform.bridge_url
1651
1780
  };
1652
- console.log(JSON.stringify(result, null, 2));
1781
+ console.log(JSON.stringify(out, null, 2));
1653
1782
  return;
1654
1783
  }
1655
- await presentBindUrl(bindUrl, options.browser === false);
1656
- console.log("");
1657
- console.log(" Waiting for bind approval (timeout: 10min)...");
1658
- const instanceId = await pollUntilBound(cfg.platform.api_url, bindId, 6e5);
1659
- await saveBindingInfo({ fingerprint: fp, instance_id: instanceId, bound_at: nowUnix() });
1660
- console.log(` Bind confirmed! Instance: ${instanceId}`);
1661
1784
  }
1662
1785
  } catch (e) {
1663
1786
  const cached = await loadBindingInfo();
@@ -1680,50 +1803,25 @@ async function run(agentType, options) {
1680
1803
  throw new Error(`Cannot reach platform to bind agent: ${e}`);
1681
1804
  }
1682
1805
  }
1683
- async function installPluginToHome(home, pluginDir, binary) {
1684
- const p = getPlatformAdapter();
1685
- const dest = p.joinPath(home, "extensions", "beeos-claw");
1686
- if (await p.exists(dest)) {
1687
- await p.rmdir(dest);
1688
- }
1689
- await copyDirRecursive(pluginDir, dest);
1690
- }
1691
- async function copyDirRecursive(src, dst) {
1692
- const p = getPlatformAdapter();
1693
- await p.mkdir(dst);
1694
- const entries = await p.readdir(src);
1695
- for (const name of entries) {
1696
- const srcPath = p.joinPath(src, name);
1697
- const dstPath = p.joinPath(dst, name);
1698
- if (await p.isDirectory(srcPath)) {
1699
- await copyDirRecursive(srcPath, dstPath);
1700
- } else {
1701
- await p.copyFile(srcPath, dstPath);
1702
- }
1703
- }
1704
- }
1705
1806
  function buildHostname() {
1706
1807
  const machine = os2.hostname();
1707
1808
  const user = process.env.USER || process.env.USERNAME || "";
1708
1809
  return user ? `${user}@${machine}` : machine;
1709
1810
  }
1710
- function nowUnix() {
1711
- return Math.floor(Date.now() / 1e3);
1712
- }
1713
1811
  function sleep2(ms) {
1714
1812
  return new Promise((resolve) => setTimeout(resolve, ms));
1715
1813
  }
1716
1814
 
1717
1815
  // src/commands/stop.ts
1718
- async function run2(agentType) {
1719
- const pid = await readPid(agentType);
1816
+ async function run2(agentFramework) {
1817
+ const pid = await readPid(agentFramework);
1720
1818
  if (pid == null) {
1721
- console.log(`No running ${agentType} agent found`);
1819
+ console.log(`No running ${agentFramework} agent found`);
1722
1820
  return;
1723
1821
  }
1724
1822
  killProcess(pid);
1725
- await removePid(agentType);
1726
- console.log(`Stopped ${agentType} agent (pid ${pid})`);
1823
+ await removePid(agentFramework);
1824
+ console.log(`Stopped ${agentFramework} agent (pid ${pid})`);
1727
1825
  }
1728
1826
 
1729
1827
  // src/commands/status.ts
@@ -1757,25 +1855,25 @@ async function run3() {
1757
1855
  }
1758
1856
 
1759
1857
  // src/commands/update.ts
1760
- async function run4(agentType) {
1858
+ async function run4(agentFramework) {
1761
1859
  const reporter = new CliReporter();
1762
- const pid = await readPid(agentType);
1860
+ const pid = await readPid(agentFramework);
1763
1861
  const wasRunning = pid != null && isProcessAlive(pid);
1764
1862
  if (wasRunning) {
1765
- await run2(agentType);
1863
+ await run2(agentFramework);
1766
1864
  }
1767
- if (agentType === "openclaw") {
1865
+ if (agentFramework === "openclaw") {
1768
1866
  await openclawRuntime.update(reporter);
1769
- } else if (agentType === "device") {
1867
+ } else if (agentFramework === "device") {
1770
1868
  await deviceRuntime.update(reporter);
1771
1869
  } else {
1772
- throw new Error(`Unknown agent type: ${agentType}`);
1870
+ throw new Error(`Unknown agent framework: ${agentFramework}`);
1773
1871
  }
1774
1872
  reporter.stop();
1775
- console.log(`${agentType} updated`);
1873
+ console.log(`${agentFramework} updated`);
1776
1874
  if (wasRunning) {
1777
1875
  console.log("Restarting agent...");
1778
- await run(agentType, { force: true });
1876
+ await run(agentFramework, { force: true });
1779
1877
  }
1780
1878
  }
1781
1879
 
@@ -2116,10 +2214,10 @@ function sleep3(ms) {
2116
2214
  setPlatformAdapter(new NodePlatformAdapter());
2117
2215
  var program = new Command();
2118
2216
  program.name("beeos").version("1.0.0").description("BeeOS \u2014 run AI agents from your desktop");
2119
- program.command("start").description("Install and start an agent").argument("<agent_type>", "Agent type to start (e.g. openclaw)").option("--version <version>", "Pin to a specific version instead of latest").option("--force", "Skip confirmation prompts", false).option("--json", "Output machine-readable JSON to stdout (implies --force)", false).option("--no-browser", "Don't auto-open browser for bind confirmation").action(run);
2120
- program.command("stop").description("Stop a running agent").argument("<agent_type>", "Agent type to stop").action(run2);
2217
+ program.command("start").description("Install and start an agent").argument("<agent_type>", "Agent type to start (e.g. openclaw)").option("--version <version>", "Pin to a specific version instead of latest").option("--force", "Skip confirmation prompts", false).option("--json", "Output machine-readable JSON to stdout (implies --force)", false).option("--no-browser", "Don't auto-open browser for bind confirmation").action((agentFramework, options) => run(agentFramework, options));
2218
+ program.command("stop").description("Stop a running agent").argument("<agent_type>", "Agent type to stop").action((agentFramework) => run2(agentFramework));
2121
2219
  program.command("status").description("Show status of managed agents").action(run3);
2122
- program.command("update").description("Update an agent to the latest version").argument("<agent_type>", "Agent type to update").action(run4);
2220
+ program.command("update").description("Update an agent to the latest version").argument("<agent_type>", "Agent type to update").action((agentFramework) => run4(agentFramework));
2123
2221
  program.command("bind-status").description("Check agent binding status").argument("<bind_id>", "Bind session ID returned by `beeos start --json`").option("--json", "Output machine-readable JSON", false).action(run5);
2124
2222
  var deviceCmd = program.command("device").description("Manage device agents (Android/Desktop/ChromeOS)");
2125
2223
  deviceCmd.command("attach").description("Attach an ADB-connected device as an AI agent").option("--serial <serial>", "ADB device serial number").option("--name <name>", "Human-readable device name").option("--all", "Attach all connected ADB devices", false).action(attach);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beeos-ai/cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "type": "module",
5
5
  "description": "BeeOS CLI — run AI agents from your desktop",
6
6
  "bin": {
@@ -13,13 +13,6 @@
13
13
  "dist/",
14
14
  "README.md"
15
15
  ],
16
- "scripts": {
17
- "build": "tsup",
18
- "type-check": "tsc --noEmit",
19
- "lint": "eslint src/",
20
- "test": "vitest run --passWithNoTests",
21
- "prepublishOnly": "pnpm build"
22
- },
23
16
  "dependencies": {
24
17
  "@noble/ed25519": "^2.2.0",
25
18
  "@noble/hashes": "^1.7.0",
@@ -33,19 +26,25 @@
33
26
  "which": "^5.0.0"
34
27
  },
35
28
  "devDependencies": {
36
- "@beeos/core": "workspace:*",
37
29
  "@types/node": "^22.0.0",
38
30
  "@types/proper-lockfile": "^4.1.4",
39
31
  "@types/qrcode": "^1.5.5",
40
32
  "@types/which": "^3.0.4",
41
33
  "tsup": "^8.3.0",
42
34
  "typescript": "^5.7.0",
43
- "vitest": "^3.0.0"
35
+ "vitest": "^3.0.0",
36
+ "@beeos/core": "0.1.0"
44
37
  },
45
38
  "engines": {
46
39
  "node": ">=18"
47
40
  },
48
41
  "publishConfig": {
49
42
  "access": "public"
43
+ },
44
+ "scripts": {
45
+ "build": "tsup",
46
+ "type-check": "tsc --noEmit",
47
+ "lint": "eslint src/",
48
+ "test": "vitest run --passWithNoTests"
50
49
  }
51
- }
50
+ }