agent-phonon 0.2.10 → 0.2.11

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/cli.js CHANGED
@@ -1725,12 +1725,12 @@ var init_rpc = __esm({
1725
1725
  requestRaw(method, params, timeoutMs = 12e4) {
1726
1726
  const id = this.nextId++;
1727
1727
  const msg = { jsonrpc: "2.0", id, method, params };
1728
- return new Promise((resolve5, reject) => {
1728
+ return new Promise((resolve6, reject) => {
1729
1729
  const timer = timeoutMs > 0 ? setTimeout(() => {
1730
1730
  this.pending.delete(id);
1731
1731
  reject(new PhononError("errInternal", `RPC timeout: ${method}`));
1732
1732
  }, timeoutMs) : void 0;
1733
- this.pending.set(id, { resolve: resolve5, reject, timer });
1733
+ this.pending.set(id, { resolve: resolve6, reject, timer });
1734
1734
  this.transport.send(JSON.stringify(msg));
1735
1735
  });
1736
1736
  }
@@ -2186,8 +2186,8 @@ var SessionEngine = class {
2186
2186
  this.interactionWaiters.delete(requestId);
2187
2187
  }
2188
2188
  }
2189
- registerInteractionWaiter(requestId, resolve5) {
2190
- this.interactionWaiters.set(requestId, resolve5);
2189
+ registerInteractionWaiter(requestId, resolve6) {
2190
+ this.interactionWaiters.set(requestId, resolve6);
2191
2191
  }
2192
2192
  list(tenantId, filter) {
2193
2193
  const all = [];
@@ -3762,7 +3762,7 @@ ${message}`;
3762
3762
  return void 0;
3763
3763
  }
3764
3764
  run(args2, signal, environment) {
3765
- return new Promise((resolve5, reject) => {
3765
+ return new Promise((resolve6, reject) => {
3766
3766
  const child = spawn2("openclaw", args2, { cwd: this.cwd, env: { ...process.env, ...environment ?? {} } });
3767
3767
  this.current = child;
3768
3768
  let out = "";
@@ -3780,9 +3780,9 @@ ${message}`;
3780
3780
  signal?.removeEventListener("abort", onAbort);
3781
3781
  this.current = void 0;
3782
3782
  if (killed)
3783
- return resolve5(null);
3783
+ return resolve6(null);
3784
3784
  if (code === 0)
3785
- resolve5(out);
3785
+ resolve6(out);
3786
3786
  else
3787
3787
  reject(new Error(`openclaw exited ${code}: ${err.slice(0, 500)}`));
3788
3788
  });
@@ -3834,12 +3834,12 @@ var OpenClawAdapter = class {
3834
3834
  return new OpenClawSession(params.sessionId, params.model, params.cwd, openclawAgent);
3835
3835
  }
3836
3836
  probeVersion() {
3837
- return new Promise((resolve5) => {
3837
+ return new Promise((resolve6) => {
3838
3838
  const child = spawn2("openclaw", ["--version"]);
3839
3839
  let out = "";
3840
3840
  child.stdout.on("data", (d) => out += d.toString());
3841
- child.on("error", () => resolve5(null));
3842
- child.on("close", (code) => resolve5(code === 0 ? out.trim() : null));
3841
+ child.on("error", () => resolve6(null));
3842
+ child.on("close", (code) => resolve6(code === 0 ? out.trim() : null));
3843
3843
  });
3844
3844
  }
3845
3845
  };
@@ -3872,7 +3872,7 @@ var GatewayClient = class {
3872
3872
  return this.connectPromise;
3873
3873
  }
3874
3874
  doConnect() {
3875
- return new Promise((resolve5, reject) => {
3875
+ return new Promise((resolve6, reject) => {
3876
3876
  const wsUrl = this.config.baseUrl.replace(/^http/, "ws");
3877
3877
  const ws = new WebSocket(wsUrl);
3878
3878
  this.ws = ws;
@@ -3903,7 +3903,7 @@ var GatewayClient = class {
3903
3903
  } else if (frame.type === "res" && frame.ok && frame.payload?.type === "hello-ok") {
3904
3904
  handshakeDone = true;
3905
3905
  this.connected = true;
3906
- resolve5();
3906
+ resolve6();
3907
3907
  } else if (frame.type === "res" && !frame.ok) {
3908
3908
  reject(new Error(`handshake failed: ${JSON.stringify(frame.error)}`));
3909
3909
  }
@@ -3949,13 +3949,13 @@ var GatewayClient = class {
3949
3949
  async rpc(method, params, timeoutMs = 12e4) {
3950
3950
  if (!this.connected)
3951
3951
  await this.connect();
3952
- return new Promise((resolve5, reject) => {
3952
+ return new Promise((resolve6, reject) => {
3953
3953
  const id = randomUUID();
3954
3954
  const timer = setTimeout(() => {
3955
3955
  this.pending.delete(id);
3956
3956
  reject(new Error(`RPC timeout: ${method}`));
3957
3957
  }, timeoutMs);
3958
- this.pending.set(id, { resolve: resolve5, reject, timer });
3958
+ this.pending.set(id, { resolve: resolve6, reject, timer });
3959
3959
  this.ws.send(JSON.stringify({ type: "req", id, method, params }));
3960
3960
  });
3961
3961
  }
@@ -4082,14 +4082,14 @@ var GatewaySession = class {
4082
4082
 
4083
4083
  ${input}`;
4084
4084
  }
4085
- await new Promise((resolve5) => {
4085
+ await new Promise((resolve6) => {
4086
4086
  let settled = false;
4087
4087
  const finish = () => {
4088
4088
  if (settled)
4089
4089
  return;
4090
4090
  settled = true;
4091
4091
  clearTimeout(guard);
4092
- resolve5();
4092
+ resolve6();
4093
4093
  };
4094
4094
  this.activeTurn = { turnId, emit, verbosity: opts.verbosity, done: finish, acc: "" };
4095
4095
  this.gw.rpc("chat.send", {
@@ -4350,7 +4350,7 @@ var PhononClient = class {
4350
4350
  }
4351
4351
  /** 连接并完成握手,resolve 后即可接收 server 的 session.* 下发。 */
4352
4352
  connect() {
4353
- return new Promise((resolve5, reject) => {
4353
+ return new Promise((resolve6, reject) => {
4354
4354
  const ws = new WebSocket2(this.serverUrl);
4355
4355
  this.ws = ws;
4356
4356
  const transport = {
@@ -4392,7 +4392,7 @@ var PhononClient = class {
4392
4392
  if (wAck && wAck.length > 0) {
4393
4393
  conn.replayPending(wAck.map((a) => ({ sessionId: a.sessionId, fromSeq: a.lastSeq })));
4394
4394
  }
4395
- resolve5({ tenantId: welcome.tenantId });
4395
+ resolve6({ tenantId: welcome.tenantId });
4396
4396
  } catch (err) {
4397
4397
  reject(err);
4398
4398
  }
@@ -4462,12 +4462,12 @@ var HookBridge = class {
4462
4462
  this.token = opts?.token;
4463
4463
  }
4464
4464
  listen(port = 4318, host = "127.0.0.1") {
4465
- return new Promise((resolve5) => {
4465
+ return new Promise((resolve6) => {
4466
4466
  const server = createServer((req, res) => this.onRequest(req, res));
4467
4467
  this.server = server;
4468
4468
  server.listen(port, host, () => {
4469
4469
  const addr = server.address();
4470
- resolve5(typeof addr === "object" && addr ? addr.port : port);
4470
+ resolve6(typeof addr === "object" && addr ? addr.port : port);
4471
4471
  });
4472
4472
  });
4473
4473
  }
@@ -4520,10 +4520,10 @@ var HookBridge = class {
4520
4520
  });
4521
4521
  }
4522
4522
  close() {
4523
- return new Promise((resolve5) => {
4523
+ return new Promise((resolve6) => {
4524
4524
  if (!this.server)
4525
- return resolve5();
4526
- this.server.close(() => resolve5());
4525
+ return resolve6();
4526
+ this.server.close(() => resolve6());
4527
4527
  });
4528
4528
  }
4529
4529
  };
@@ -4708,7 +4708,7 @@ function normalizeOpenAiModels(data) {
4708
4708
  return out;
4709
4709
  }
4710
4710
  function fetchJson(url, headers) {
4711
- return new Promise((resolve5, reject) => {
4711
+ return new Promise((resolve6, reject) => {
4712
4712
  const u = new URL(url);
4713
4713
  const req = (u.protocol === "http:" ? import("node:http") : import("node:https")).then((mod) => mod.request(url, { method: "GET", headers, timeout: 5e3 }, (res) => {
4714
4714
  let body = "";
@@ -4720,7 +4720,7 @@ function fetchJson(url, headers) {
4720
4720
  return;
4721
4721
  }
4722
4722
  try {
4723
- resolve5(JSON.parse(body));
4723
+ resolve6(JSON.parse(body));
4724
4724
  } catch (e) {
4725
4725
  reject(e);
4726
4726
  }
@@ -4782,7 +4782,7 @@ ${prompt}`;
4782
4782
  await this.run(args2, prompt, turnId, emit, opts);
4783
4783
  }
4784
4784
  run(args2, stdin, turnId, emit, opts) {
4785
- return new Promise((resolve5) => {
4785
+ return new Promise((resolve6) => {
4786
4786
  const child = spawn3(this.env.binPath ?? "codex", args2, {
4787
4787
  cwd: this.cwd,
4788
4788
  shell: process.platform === "win32",
@@ -4803,7 +4803,7 @@ ${prompt}`;
4803
4803
  } else {
4804
4804
  emit({ type: "result", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), text, status, final: true });
4805
4805
  }
4806
- resolve5();
4806
+ resolve6();
4807
4807
  };
4808
4808
  const guard = setTimeout(() => finish("timeout", acc), 18e5);
4809
4809
  opts.signal?.addEventListener("abort", () => {
@@ -4935,12 +4935,12 @@ var CodexAdapter = class {
4935
4935
  return base.length > 0 ? base : CODEX_FALLBACK_MODELS;
4936
4936
  }
4937
4937
  probeVersion() {
4938
- return new Promise((resolve5) => {
4938
+ return new Promise((resolve6) => {
4939
4939
  const child = spawn3(this.env.binPath ?? "codex", ["--version"], { shell: process.platform === "win32" });
4940
4940
  let out = "";
4941
4941
  child.stdout.on("data", (d) => out += d.toString());
4942
- child.on("error", () => resolve5(null));
4943
- child.on("close", (code) => resolve5(code === 0 ? out.trim() : null));
4942
+ child.on("error", () => resolve6(null));
4943
+ child.on("close", (code) => resolve6(code === 0 ? out.trim() : null));
4944
4944
  });
4945
4945
  }
4946
4946
  };
@@ -5016,7 +5016,7 @@ ${message}`;
5016
5016
  await this.run(args2, turnId, emit, opts);
5017
5017
  }
5018
5018
  run(args2, turnId, emit, opts) {
5019
- return new Promise((resolve5) => {
5019
+ return new Promise((resolve6) => {
5020
5020
  const child = spawn4(this.bin, args2, { cwd: this.cwd, stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, ...opts.environment ?? {} } });
5021
5021
  this.current = child;
5022
5022
  let buf = "";
@@ -5033,7 +5033,7 @@ ${message}`;
5033
5033
  } else {
5034
5034
  emit({ type: "result", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), text, status, final: true });
5035
5035
  }
5036
- resolve5();
5036
+ resolve6();
5037
5037
  };
5038
5038
  const guard = setTimeout(() => finish("timeout", acc), 18e5);
5039
5039
  opts.signal?.addEventListener("abort", () => {
@@ -5164,12 +5164,12 @@ var OpenCodeAdapter = class {
5164
5164
  return new OpenCodeSession(params.sessionId, model, params.cwd, this.bin);
5165
5165
  }
5166
5166
  probeVersion() {
5167
- return new Promise((resolve5) => {
5167
+ return new Promise((resolve6) => {
5168
5168
  const child = spawn4(this.bin, ["--version"]);
5169
5169
  let out = "";
5170
5170
  child.stdout.on("data", (d) => out += d.toString());
5171
- child.on("error", () => resolve5(null));
5172
- child.on("close", (code) => resolve5(code === 0 ? out.trim() : null));
5171
+ child.on("error", () => resolve6(null));
5172
+ child.on("close", (code) => resolve6(code === 0 ? out.trim() : null));
5173
5173
  });
5174
5174
  }
5175
5175
  };
@@ -5234,7 +5234,7 @@ function parseHermesConfig(configPath = join9(homedir7(), ".hermes", "config.yam
5234
5234
  return { defaultModel, provider, catalogUrl };
5235
5235
  }
5236
5236
  function fetchHermesCatalogModels(url, provider) {
5237
- return new Promise((resolve5) => {
5237
+ return new Promise((resolve6) => {
5238
5238
  const u = new URL(url);
5239
5239
  const reqMod = u.protocol === "http:" ? import("node:http") : import("node:https");
5240
5240
  reqMod.then((mod) => {
@@ -5248,21 +5248,21 @@ function fetchHermesCatalogModels(url, provider) {
5248
5248
  const providers = data.providers ?? {};
5249
5249
  const rows = provider ? providers[provider]?.models ?? [] : Object.values(providers).flatMap((p) => p.models ?? []);
5250
5250
  const seen = /* @__PURE__ */ new Set();
5251
- resolve5(rows.flatMap((m) => {
5251
+ resolve6(rows.flatMap((m) => {
5252
5252
  if (!m.id || seen.has(m.id))
5253
5253
  return [];
5254
5254
  seen.add(m.id);
5255
5255
  return [{ id: m.id, ...m.description ? { displayName: m.description } : {}, available: true }];
5256
5256
  }));
5257
5257
  } catch {
5258
- resolve5([]);
5258
+ resolve6([]);
5259
5259
  }
5260
5260
  });
5261
5261
  });
5262
5262
  req.on("timeout", () => req.destroy());
5263
- req.on("error", () => resolve5([]));
5263
+ req.on("error", () => resolve6([]));
5264
5264
  req.end();
5265
- }, () => resolve5([]));
5265
+ }, () => resolve6([]));
5266
5266
  });
5267
5267
  }
5268
5268
  var HermesSession = class {
@@ -5310,7 +5310,7 @@ ${prompt}`;
5310
5310
  await this.run(args2, turnId, emit, opts);
5311
5311
  }
5312
5312
  run(args2, turnId, emit, opts) {
5313
- return new Promise((resolve5) => {
5313
+ return new Promise((resolve6) => {
5314
5314
  const child = spawn5(this.env.binPath ?? "hermes", args2, {
5315
5315
  cwd: this.cwd,
5316
5316
  shell: process.platform === "win32",
@@ -5333,7 +5333,7 @@ ${prompt}`;
5333
5333
  emit({ type: "message", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), role: "assistant", text, delta: false });
5334
5334
  emit({ type: "result", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), text, status, final: true });
5335
5335
  }
5336
- resolve5();
5336
+ resolve6();
5337
5337
  };
5338
5338
  const guard = setTimeout(() => finish("timeout", out), 18e5);
5339
5339
  opts.signal?.addEventListener("abort", () => {
@@ -5493,11 +5493,11 @@ var HermesAdapter = class {
5493
5493
  }
5494
5494
  /** 枚举 Hermes profile(去 ANSI 色解析 profile list)。 */
5495
5495
  listProfiles() {
5496
- return new Promise((resolve5) => {
5496
+ return new Promise((resolve6) => {
5497
5497
  const child = spawn5(this.env.binPath ?? "hermes", ["profile", "list"], { shell: process.platform === "win32" });
5498
5498
  let out = "";
5499
5499
  child.stdout.on("data", (d) => out += d.toString());
5500
- child.on("error", () => resolve5([{ name: this.defaultProfile }]));
5500
+ child.on("error", () => resolve6([{ name: this.defaultProfile }]));
5501
5501
  child.on("close", () => {
5502
5502
  const clean = out.replace(/\u001b\[[0-9;]*m/g, "");
5503
5503
  const names = [];
@@ -5508,17 +5508,17 @@ var HermesAdapter = class {
5508
5508
  names.push({ name: m[1], model: rest[0] || void 0 });
5509
5509
  }
5510
5510
  }
5511
- resolve5(names.length > 0 ? names : [{ name: this.defaultProfile }]);
5511
+ resolve6(names.length > 0 ? names : [{ name: this.defaultProfile }]);
5512
5512
  });
5513
5513
  });
5514
5514
  }
5515
5515
  probeVersion() {
5516
- return new Promise((resolve5) => {
5516
+ return new Promise((resolve6) => {
5517
5517
  const child = spawn5(this.env.binPath ?? "hermes", ["--version"], { shell: process.platform === "win32" });
5518
5518
  let out = "";
5519
5519
  child.stdout.on("data", (d) => out += d.toString());
5520
- child.on("error", () => resolve5(null));
5521
- child.on("close", (code) => resolve5(code === 0 ? out.trim().split("\n")[0] ?? "hermes" : null));
5520
+ child.on("error", () => resolve6(null));
5521
+ child.on("close", (code) => resolve6(code === 0 ? out.trim().split("\n")[0] ?? "hermes" : null));
5522
5522
  });
5523
5523
  }
5524
5524
  };
@@ -5741,7 +5741,7 @@ ${prompt}`;
5741
5741
  await this.run(args2, envelope, turnId, emit, opts);
5742
5742
  }
5743
5743
  run(args2, stdin, turnId, emit, opts) {
5744
- return new Promise((resolve5) => {
5744
+ return new Promise((resolve6) => {
5745
5745
  const childEnv = {};
5746
5746
  for (const [k, v] of Object.entries(process.env)) {
5747
5747
  if (k === "CLAUDECODE" || k.startsWith("CLAUDECODE_") || k.startsWith("CLAUDE_CODE_"))
@@ -5773,7 +5773,7 @@ ${prompt}`;
5773
5773
  } else {
5774
5774
  emit({ type: "result", sessionId: this.sessionId, turnId, seq: 0, at: (/* @__PURE__ */ new Date()).toISOString(), text, status, final: true });
5775
5775
  }
5776
- resolve5();
5776
+ resolve6();
5777
5777
  };
5778
5778
  const guard = setTimeout(() => finish("timeout", acc), 18e5);
5779
5779
  opts.signal?.addEventListener("abort", () => {
@@ -5890,12 +5890,12 @@ var ClaudeCodeAdapter = class {
5890
5890
  return new ClaudeCodeSession(params.sessionId, params.model, params.cwd, this.env);
5891
5891
  }
5892
5892
  probeVersion() {
5893
- return new Promise((resolve5) => {
5893
+ return new Promise((resolve6) => {
5894
5894
  const child = spawn6(this.env.binPath ?? "claude", ["--version"], { shell: process.platform === "win32" });
5895
5895
  let out = "";
5896
5896
  child.stdout.on("data", (d) => out += d.toString());
5897
- child.on("error", () => resolve5(null));
5898
- child.on("close", (code) => resolve5(code === 0 ? out.trim() : null));
5897
+ child.on("error", () => resolve6(null));
5898
+ child.on("close", (code) => resolve6(code === 0 ? out.trim() : null));
5899
5899
  });
5900
5900
  }
5901
5901
  };
@@ -6301,9 +6301,9 @@ function readOpenClawGatewayToken() {
6301
6301
 
6302
6302
  // src/commands.ts
6303
6303
  import { spawnSync } from "node:child_process";
6304
- import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync7 } from "node:fs";
6304
+ import { existsSync as existsSync12, cpSync, mkdirSync as mkdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync7, chmodSync as chmodSync3 } from "node:fs";
6305
6305
  import { homedir as homedir10, platform as platform2 } from "node:os";
6306
- import { join as join12, dirname as dirname5, delimiter } from "node:path";
6306
+ import { join as join12, dirname as dirname5, delimiter, resolve as resolve5 } from "node:path";
6307
6307
  import { fileURLToPath } from "node:url";
6308
6308
  function probe(bin, args2 = ["--version"]) {
6309
6309
  const r = spawnSync(bin, args2, { timeout: 8e3, shell: platform2() === "win32" });
@@ -6483,6 +6483,75 @@ function cmdAdapterList() {
6483
6483
  console.log(`- ${a.type}${a.defaultAgent ? ` (agent: ${a.defaultAgent})` : ""}${auto}`);
6484
6484
  }
6485
6485
  }
6486
+ function systemctlUser(args2) {
6487
+ const r = spawnSync("systemctl", ["--user", ...args2], { stdio: "inherit" });
6488
+ if (r.status !== 0) fail(`systemctl --user ${args2.join(" ")} failed`);
6489
+ }
6490
+ function serviceUnitPath() {
6491
+ return join12(homedir10(), ".config", "systemd", "user", "agent-phonon.service");
6492
+ }
6493
+ function serviceUnitContent() {
6494
+ const node = process.execPath;
6495
+ const cli = resolve5(process.argv[1] ?? fileURLToPath(import.meta.url));
6496
+ return `[Unit]
6497
+ Description=agent-phonon device daemon
6498
+ After=network-online.target
6499
+ Wants=network-online.target
6500
+
6501
+ [Service]
6502
+ Type=simple
6503
+ ExecStart=${node} ${cli} start
6504
+ Restart=always
6505
+ RestartSec=5
6506
+ MemoryMax=256M
6507
+
6508
+ [Install]
6509
+ WantedBy=default.target
6510
+ `;
6511
+ }
6512
+ function cmdService(sub, opts = {}) {
6513
+ if (platform2() !== "linux") {
6514
+ fail(`service ${sub ?? ""} is currently implemented for Linux systemd --user only (platform=${platform2()})`);
6515
+ }
6516
+ const unit = serviceUnitPath();
6517
+ switch (sub) {
6518
+ case "install": {
6519
+ if (existsSync12(unit) && !opts.force) fail(`${unit} already exists (use --force to overwrite)`);
6520
+ mkdirSync4(dirname5(unit), { recursive: true });
6521
+ writeFileSync4(unit, serviceUnitContent(), { mode: 420 });
6522
+ chmodSync3(unit, 420);
6523
+ systemctlUser(["daemon-reload"]);
6524
+ systemctlUser(["enable", "agent-phonon.service"]);
6525
+ console.log(`installed systemd user service \u2192 ${unit}`);
6526
+ console.log("start it with: agent-phonon service start");
6527
+ if (!existsSync12(join12(homedir10(), ".agent-phonon", "config.json"))) console.log("config not found yet; run: agent-phonon init");
6528
+ break;
6529
+ }
6530
+ case "start":
6531
+ systemctlUser(["start", "agent-phonon.service"]);
6532
+ console.log("started agent-phonon.service");
6533
+ break;
6534
+ case "stop":
6535
+ systemctlUser(["stop", "agent-phonon.service"]);
6536
+ console.log("stopped agent-phonon.service");
6537
+ break;
6538
+ case "restart":
6539
+ systemctlUser(["restart", "agent-phonon.service"]);
6540
+ console.log("restarted agent-phonon.service");
6541
+ break;
6542
+ case "status":
6543
+ systemctlUser(["status", "agent-phonon.service", "--no-pager"]);
6544
+ break;
6545
+ case "uninstall":
6546
+ systemctlUser(["disable", "--now", "agent-phonon.service"]);
6547
+ rmSync3(unit, { force: true });
6548
+ systemctlUser(["daemon-reload"]);
6549
+ console.log(`removed ${unit}`);
6550
+ break;
6551
+ default:
6552
+ fail("usage: agent-phonon service install|start|stop|restart|status|uninstall [--force]");
6553
+ }
6554
+ }
6486
6555
  function cmdPluginInstall(which) {
6487
6556
  if (which !== "openclaw") return fail(`plugin install supports: openclaw (got: ${which})`);
6488
6557
  const here = dirname5(fileURLToPath(import.meta.url));
@@ -6521,13 +6590,13 @@ var ObsServer = class {
6521
6590
  deps.bus.onEvent((e) => this.broadcast(e));
6522
6591
  }
6523
6592
  listen(port = 4319, host = "127.0.0.1") {
6524
- return new Promise((resolve5) => {
6593
+ return new Promise((resolve6) => {
6525
6594
  const server = createServer2((req, res) => this.handle(req, res));
6526
6595
  this.server = server;
6527
6596
  server.listen(port, host, () => {
6528
6597
  const addr = server.address();
6529
6598
  this.actualPort = typeof addr === "object" && addr ? addr.port : port;
6530
- resolve5(this.actualPort);
6599
+ resolve6(this.actualPort);
6531
6600
  });
6532
6601
  });
6533
6602
  }
@@ -6605,11 +6674,11 @@ var ObsServer = class {
6605
6674
  return this.actualPort;
6606
6675
  }
6607
6676
  close() {
6608
- return new Promise((resolve5) => {
6677
+ return new Promise((resolve6) => {
6609
6678
  for (const c of this.sseClients) c.end();
6610
6679
  this.sseClients.clear();
6611
- if (!this.server) return resolve5();
6612
- this.server.close(() => resolve5());
6680
+ if (!this.server) return resolve6();
6681
+ this.server.close(() => resolve6());
6613
6682
  });
6614
6683
  }
6615
6684
  };
@@ -6835,6 +6904,10 @@ async function main() {
6835
6904
  }
6836
6905
  break;
6837
6906
  }
6907
+ case "service": {
6908
+ cmdService(args[0], { force: flag("force") });
6909
+ break;
6910
+ }
6838
6911
  case "plugin": {
6839
6912
  const sub = args[0];
6840
6913
  if (sub === "install") cmdPluginInstall(args[1] ?? "");
@@ -6852,6 +6925,7 @@ async function main() {
6852
6925
  console.log(" adapter add <type> [opts] configure an adapter override (auto-detect covers common local agents)");
6853
6926
  console.log(" adapter list list configured + auto-detected adapters");
6854
6927
  console.log(" plugin install openclaw install OpenClaw HITL plugin");
6928
+ console.log(" service install|start|status manage Linux systemd --user service");
6855
6929
  console.log(" server add <url> [--trust-local] [--device-key <k>]");
6856
6930
  console.log(" server list");
6857
6931
  console.log(" config [--show-secrets] show config (redacted by default)");