@telepath-computer/television 0.1.45 → 0.1.47

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.cjs CHANGED
@@ -33776,7 +33776,7 @@ var ValidationError = defineError("ValidationError");
33776
33776
  var NotFoundError = defineError("NotFoundError");
33777
33777
  var InvalidRequestError = defineError("InvalidRequestError");
33778
33778
 
33779
- // ../shared/src/acp-bridge-types.ts
33779
+ // ../shared/src/acp-types.ts
33780
33780
  function isACPBridgeClientMessage(value) {
33781
33781
  if (typeof value !== "object" || value === null || !("type" in value)) {
33782
33782
  return false;
@@ -34066,6 +34066,21 @@ var import_node_path2 = __toESM(require("node:path"), 1);
34066
34066
  var TRUE_ENV_VALUE = "true";
34067
34067
  var APP_HIDDEN_DIRECTORY = ".television";
34068
34068
  var TELEVISION_STORAGE_PATH_ENV = "TELEVISION_STORAGE_PATH";
34069
+ var TELEVISION_ACP_AGENT_ENV = "TELEVISION_ACP_AGENT";
34070
+ var ACP_AGENT_PROFILES = {
34071
+ openclaw: {
34072
+ agent: "openclaw",
34073
+ command: "openclaw",
34074
+ args: ["acp"],
34075
+ sessionIdStrategy: "deterministic"
34076
+ },
34077
+ hermes: {
34078
+ agent: "hermes",
34079
+ command: "hermes",
34080
+ args: ["acp"],
34081
+ sessionIdStrategy: "mapped"
34082
+ }
34083
+ };
34069
34084
  var DEFAULT_SERVER_HOST = "localhost";
34070
34085
  var DEFAULT_SERVER_PORT = 32848;
34071
34086
  var DEFAULT_SERVER_URL = buildServerURL(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT);
@@ -34075,6 +34090,16 @@ function buildServerURL(host, port) {
34075
34090
  function getTelevisionStoragePath() {
34076
34091
  return process.env[TELEVISION_STORAGE_PATH_ENV] ?? import_node_path2.default.join(import_node_os2.default.homedir(), APP_HIDDEN_DIRECTORY);
34077
34092
  }
34093
+ function resolveACPAgentProfile(env = process.env) {
34094
+ const rawAgent = env[TELEVISION_ACP_AGENT_ENV];
34095
+ const agent = rawAgent === void 0 ? "openclaw" : rawAgent.trim().toLowerCase();
34096
+ if (agent === "openclaw" || agent === "hermes") {
34097
+ return ACP_AGENT_PROFILES[agent];
34098
+ }
34099
+ throw new Error(
34100
+ `Unsupported TELEVISION_ACP_AGENT "${rawAgent}". Supported values: openclaw, hermes.`
34101
+ );
34102
+ }
34078
34103
  function isVitestRuntime() {
34079
34104
  return process.env.VITEST === TRUE_ENV_VALUE;
34080
34105
  }
@@ -48417,8 +48442,26 @@ var import_node_child_process2 = require("node:child_process");
48417
48442
  var import_promises2 = require("node:fs/promises");
48418
48443
  var import_node_os3 = require("node:os");
48419
48444
  var import_node_path5 = __toESM(require("node:path"), 1);
48420
- var ACP_COMMAND = "openclaw";
48421
- var ACP_ARGS = ["acp"];
48445
+ var launchACPProcess = (command, args, options) => {
48446
+ const child = (0, import_node_child_process2.spawn)(command, args, options);
48447
+ const directKill = child.kill.bind(child);
48448
+ child.kill = (signal) => {
48449
+ const pid = child.pid;
48450
+ const sig = signal ?? "SIGTERM";
48451
+ if (pid != null) {
48452
+ try {
48453
+ process.kill(-pid, sig);
48454
+ return true;
48455
+ } catch (error48) {
48456
+ if (error48.code === "ESRCH") {
48457
+ return true;
48458
+ }
48459
+ }
48460
+ }
48461
+ return directKill(sig);
48462
+ };
48463
+ return child;
48464
+ };
48422
48465
  var ACP_STOP_TIMEOUT_MS = 5e3;
48423
48466
  var ACP_STUB_CWD = import_node_path5.default.join((0, import_node_os3.homedir)(), ".television", "acp");
48424
48467
  var ACPBridge = class extends withDisposable(class {
@@ -48429,9 +48472,15 @@ var ACPBridge = class extends withDisposable(class {
48429
48472
  stdoutBuffer = "";
48430
48473
  stderrBuffer = "";
48431
48474
  send;
48432
- constructor(send) {
48475
+ profile;
48476
+ launchProcess;
48477
+ sessionCwd;
48478
+ constructor(options) {
48433
48479
  super();
48434
- this.send = send;
48480
+ this.send = options.send;
48481
+ this.profile = options.profile ?? resolveACPAgentProfile();
48482
+ this.launchProcess = options.launchProcess ?? launchACPProcess;
48483
+ this.sessionCwd = import_node_path5.default.resolve(process.cwd());
48435
48484
  }
48436
48485
  handleClientMessage(message) {
48437
48486
  switch (message.type) {
@@ -48478,9 +48527,10 @@ var ACPBridge = class extends withDisposable(class {
48478
48527
  this.error = null;
48479
48528
  this.sendStatus();
48480
48529
  await (0, import_promises2.mkdir)(ACP_STUB_CWD, { recursive: true });
48481
- const child = (0, import_node_child_process2.spawn)(ACP_COMMAND, ACP_ARGS, {
48530
+ const child = this.launchProcess(this.profile.command, this.profile.args, {
48482
48531
  cwd: ACP_STUB_CWD,
48483
- stdio: ["pipe", "pipe", "pipe"]
48532
+ stdio: ["pipe", "pipe", "pipe"],
48533
+ detached: true
48484
48534
  });
48485
48535
  this.child = child;
48486
48536
  child.once("spawn", () => {
@@ -48529,17 +48579,28 @@ var ACPBridge = class extends withDisposable(class {
48529
48579
  if (!line) {
48530
48580
  continue;
48531
48581
  }
48582
+ let message;
48532
48583
  try {
48533
- const message = JSON.parse(line);
48534
- this.send({ type: "acp-bridge-message", message });
48584
+ message = JSON.parse(line);
48535
48585
  } catch (error48) {
48536
- this.status = "error";
48537
- this.error = error48 instanceof Error ? error48.message : String(error48);
48538
- this.sendStatus();
48586
+ const reason = error48 instanceof Error ? error48.message : String(error48);
48587
+ console.error(`ACPBridge: dropping non-JSON stdout line (${reason}): ${line}`);
48588
+ continue;
48539
48589
  }
48590
+ this.send({ type: "acp-bridge-message", message });
48540
48591
  }
48541
48592
  }
48542
48593
  sendStatus() {
48594
+ if (this.status === "ready") {
48595
+ this.send({
48596
+ type: "acp-bridge-status",
48597
+ status: "ready",
48598
+ agent: this.profile.agent,
48599
+ sessionIdStrategy: this.profile.sessionIdStrategy,
48600
+ sessionCwd: this.sessionCwd
48601
+ });
48602
+ return;
48603
+ }
48543
48604
  const message = {
48544
48605
  type: "acp-bridge-status",
48545
48606
  status: this.status,
@@ -48560,19 +48621,24 @@ var ACPServer = class extends withDisposable(class {
48560
48621
  bridges = /* @__PURE__ */ new Map();
48561
48622
  authToken;
48562
48623
  publicServer;
48624
+ profile;
48563
48625
  constructor(options) {
48564
48626
  super();
48565
48627
  this.authToken = options.authToken;
48566
48628
  this.publicServer = options.publicServer;
48629
+ this.profile = resolveACPAgentProfile();
48567
48630
  this.wsServer = new import_websocket_server.default({ noServer: true });
48568
48631
  this.wsServer.on("connection", (socket, request) => {
48569
48632
  if (!this.publicServer && !isAuthorizedQueryToken(request.url, this.authToken)) {
48570
48633
  socket.close(AUTH_FAILED_CLOSE_CODE2, "Authentication failed");
48571
48634
  return;
48572
48635
  }
48573
- const bridge = new ACPBridge((message) => {
48574
- if (socket.readyState === import_websocket.default.OPEN) {
48575
- socket.send(JSON.stringify(message));
48636
+ const bridge = new ACPBridge({
48637
+ profile: this.profile,
48638
+ send: (message) => {
48639
+ if (socket.readyState === import_websocket.default.OPEN) {
48640
+ socket.send(JSON.stringify(message));
48641
+ }
48576
48642
  }
48577
48643
  });
48578
48644
  this.bridges.set(socket, bridge);
@@ -49513,8 +49579,8 @@ function getDevPackageDir() {
49513
49579
  return import_node_path7.default.resolve(import_node_path7.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url)), "..");
49514
49580
  }
49515
49581
  function readCLIVersion() {
49516
- if ("0.1.45".length > 0) {
49517
- return "0.1.45";
49582
+ if ("0.1.47".length > 0) {
49583
+ return "0.1.47";
49518
49584
  }
49519
49585
  const devPackageJsonPath = import_node_path7.default.join(getDevPackageDir(), "package.json");
49520
49586
  if (!(0, import_node_fs4.existsSync)(devPackageJsonPath)) {