@codexhost/cli-darwin-x64 0.12.0 → 0.12.1

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.
@@ -6,6 +6,7 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // ../../harness-broker/dist/client.js
9
+ import { execFile } from "node:child_process";
9
10
  import { randomUUID } from "node:crypto";
10
11
  import { lstat, readFile } from "node:fs/promises";
11
12
  import net, {} from "node:net";
@@ -14594,6 +14595,20 @@ var harnessDisplaySetSchema = external_exports.strictObject({
14594
14595
  initializeOnly: external_exports.boolean().optional()
14595
14596
  });
14596
14597
 
14598
+ // ../../shared-contracts/dist/ids.js
14599
+ var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
14600
+ message: "Identifier must not be empty or whitespace"
14601
+ });
14602
+ var harnessIdSchema = opaqueIdSchema.brand();
14603
+ var hostThreadIdSchema = opaqueIdSchema.brand();
14604
+ var hostTurnIdSchema = opaqueIdSchema.brand();
14605
+ var hostItemIdSchema = opaqueIdSchema.brand();
14606
+ var hostInteractionIdSchema = opaqueIdSchema.brand();
14607
+
14608
+ // ../../shared-contracts/dist/thread-prewarm.js
14609
+ var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
14610
+ var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
14611
+
14597
14612
  // ../../shared-contracts/dist/console.js
14598
14613
  var consoleAnnouncementSchema = external_exports.strictObject({
14599
14614
  title: external_exports.string().trim().min(1).max(200),
@@ -14606,6 +14621,9 @@ var consoleOpenResultSchema = external_exports.strictObject({
14606
14621
  url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
14607
14622
  });
14608
14623
  var CONSOLE_HOST_METHODS = Object.freeze([
14624
+ "codexhost/console/remote-connections",
14625
+ "codexhost/runtime/status",
14626
+ "codexhost/remote/ssh-setup",
14609
14627
  "codexhost/harness/plugins/list",
14610
14628
  "codexhost/harness/display-settings/get",
14611
14629
  "codexhost/harness/display-settings/set",
@@ -14672,16 +14690,6 @@ var loadedSessionsSchema = external_exports.array(external_exports.strictObject(
14672
14690
  inactiveMs: external_exports.number().nonnegative()
14673
14691
  }));
14674
14692
 
14675
- // ../../shared-contracts/dist/ids.js
14676
- var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
14677
- message: "Identifier must not be empty or whitespace"
14678
- });
14679
- var harnessIdSchema = opaqueIdSchema.brand();
14680
- var hostThreadIdSchema = opaqueIdSchema.brand();
14681
- var hostTurnIdSchema = opaqueIdSchema.brand();
14682
- var hostItemIdSchema = opaqueIdSchema.brand();
14683
- var hostInteractionIdSchema = opaqueIdSchema.brand();
14684
-
14685
14693
  // ../../shared-contracts/dist/manual-compaction.js
14686
14694
  var threadManualCompactionStartedSchema = external_exports.strictObject({
14687
14695
  threadId: hostThreadIdSchema,
@@ -15596,11 +15604,53 @@ var remoteSshSetupParamsSchema = external_exports.object({
15596
15604
  hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
15597
15605
  port: external_exports.number().int().min(1).max(65535).nullable(),
15598
15606
  identity: external_exports.string().max(4096).nullable(),
15599
- action: external_exports.enum(["inspect", "install", "update", "repair"]),
15607
+ action: external_exports.enum(["inspect", "install", "update", "repair", "uninstall"]),
15608
+ uninstallPackage: external_exports.boolean().optional(),
15600
15609
  version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
15601
15610
  }).strict();
15602
15611
  var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
15603
15612
 
15613
+ // ../../shared-contracts/dist/remote-connections.js
15614
+ var hostId = external_exports.string().min(1).max(1024);
15615
+ var codexSshConnectionSchema = external_exports.object({
15616
+ hostId,
15617
+ displayName: external_exports.string().min(1).max(1024),
15618
+ source: external_exports.enum(["codex-managed", "discovered"]),
15619
+ sshAlias: external_exports.string().max(1024).nullable(),
15620
+ sshHost: external_exports.string().min(1).max(1024),
15621
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
15622
+ identity: external_exports.string().max(4096).nullable(),
15623
+ autoConnect: external_exports.boolean(),
15624
+ connectionAnalyticsId: external_exports.string().max(1024).optional()
15625
+ });
15626
+ var codexSshDraftSchema = external_exports.strictObject({
15627
+ displayName: external_exports.string().min(1).max(1024),
15628
+ hostname: external_exports.string().min(1).max(1024),
15629
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
15630
+ identity: external_exports.string().max(4096).nullable()
15631
+ });
15632
+ var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
15633
+ external_exports.strictObject({ action: external_exports.literal("list") }),
15634
+ external_exports.strictObject({
15635
+ action: external_exports.literal("save"),
15636
+ draft: codexSshDraftSchema,
15637
+ previous: codexSshConnectionSchema.nullable()
15638
+ }),
15639
+ external_exports.strictObject({ action: external_exports.literal("remove"), previous: codexSshConnectionSchema }),
15640
+ external_exports.strictObject({ action: external_exports.literal("connect"), hostId, enabled: external_exports.boolean() }),
15641
+ external_exports.strictObject({ action: external_exports.literal("state"), hostId }),
15642
+ external_exports.strictObject({ action: external_exports.literal("runtime"), hostId }),
15643
+ external_exports.strictObject({
15644
+ action: external_exports.literal("update"),
15645
+ hostId: hostId.refine((id) => id !== "local"),
15646
+ version: remoteUpdateParamsSchema.shape.version
15647
+ })
15648
+ ]);
15649
+ var remoteConnectionsReplySchema = external_exports.union([
15650
+ external_exports.strictObject({ result: jsonValueSchema }),
15651
+ external_exports.strictObject({ error: external_exports.strictObject({ code: external_exports.number().int(), message: external_exports.string() }) })
15652
+ ]);
15653
+
15604
15654
  // ../../shared-contracts/dist/index.js
15605
15655
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15606
15656
 
@@ -15894,9 +15944,12 @@ var HARNESS_BROKER_PROTOCOL_VERSION = 1;
15894
15944
  var HARNESS_BROKER_MAX_FRAME_BYTES = 8 * 1024 * 1024;
15895
15945
  var HARNESS_BROKER_MAX_PENDING_REQUESTS = 32;
15896
15946
  var HARNESS_BROKER_REQUEST_TIMEOUT_MS = 15e3;
15947
+ var HARNESS_BROKER_IDLE_TIMEOUT_MS = 60 * 60 * 1e3;
15948
+ var HARNESS_BROKER_RETIRING_ERROR_CODE = "brokerRetiring";
15897
15949
  var harnessBrokerMethodSchema = external_exports.enum([
15898
15950
  "adapter.inspect",
15899
15951
  "adapter.inspectAccount",
15952
+ "adapter.credits",
15900
15953
  "adapter.open",
15901
15954
  "adapter.subagent.readSnapshot",
15902
15955
  "session.readSnapshot",
@@ -16014,6 +16067,14 @@ function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId
16014
16067
  return path.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
16015
16068
  return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
16016
16069
  }
16070
+ function harnessBrokerLaunchAgentLabel(harnessId = "claude-code") {
16071
+ harnessPluginIdSchema.parse(harnessId);
16072
+ return harnessId === "claude-code" ? "ai.bytepioneer.codexhost.native-harness-broker" : `ai.bytepioneer.codexhost.${harnessId}-broker`;
16073
+ }
16074
+ function harnessBrokerLaunchAgentPlistPath(environment = process.env, harnessId = "claude-code") {
16075
+ const home = environment.HOME || os.homedir();
16076
+ return path.join(home, "Library", "LaunchAgents", `${harnessBrokerLaunchAgentLabel(harnessId)}.plist`);
16077
+ }
16017
16078
 
16018
16079
  // ../../harness-broker/dist/validation.js
16019
16080
  var cwdSchema = external_exports.string().min(1).max(16384);
@@ -16319,10 +16380,55 @@ async function readDescriptor(descriptorPath) {
16319
16380
  try {
16320
16381
  process.kill(descriptor.ownerPid, 0);
16321
16382
  } catch {
16322
- throw new Error("Aqua Harness broker owner process is unavailable");
16383
+ throw new BrokerNotRunningError("its owner process has exited");
16323
16384
  }
16324
16385
  return descriptor;
16325
16386
  }
16387
+ var BrokerNotRunningError = class extends Error {
16388
+ };
16389
+ var BrokerRetiringError = class extends Error {
16390
+ };
16391
+ var BrokerRequestNotDeliveredError = class extends Error {
16392
+ };
16393
+ var HarnessNotInstalledError = class extends Error {
16394
+ };
16395
+ var BROKER_NOT_RUNNING_CODES = /* @__PURE__ */ new Set(["ENOENT", "ECONNREFUSED"]);
16396
+ var BROKER_START_TIMEOUT_MS = 15e3;
16397
+ var BROKER_START_POLL_MS = 250;
16398
+ function classifyConnectFailure(error51) {
16399
+ if (error51 instanceof BrokerNotRunningError)
16400
+ return error51;
16401
+ const code = error51?.code;
16402
+ if (code && BROKER_NOT_RUNNING_CODES.has(code)) {
16403
+ return new BrokerNotRunningError(code === "ENOENT" ? "its descriptor or socket is missing" : "its socket refused the connection");
16404
+ }
16405
+ return error51 instanceof Error ? error51 : new Error(String(error51));
16406
+ }
16407
+ function describeBrokerFailure(error51, harnessId) {
16408
+ if (error51 instanceof BrokerNotRunningError) {
16409
+ return `The ${harnessId} Aqua Harness broker on this Mac could not be started (${error51.message}). Keep the desktop user logged in, then repair the remote service or run on this Mac: codexhost broker install --harness ${harnessId}`;
16410
+ }
16411
+ return error51 instanceof Error ? error51.message : String(error51);
16412
+ }
16413
+ function runLaunchctl(arguments_) {
16414
+ return new Promise((resolve) => {
16415
+ execFile("/bin/launchctl", arguments_, { timeout: 1e4 }, (error51) => resolve(!error51));
16416
+ });
16417
+ }
16418
+ async function startBrokerLaunchAgent(harnessId, environment) {
16419
+ const uid = process.getuid?.();
16420
+ if (uid === void 0)
16421
+ return;
16422
+ const target = `gui/${uid}/${harnessBrokerLaunchAgentLabel(harnessId)}`;
16423
+ if (await runLaunchctl(["kickstart", target]))
16424
+ return;
16425
+ await runLaunchctl([
16426
+ "bootstrap",
16427
+ `gui/${uid}`,
16428
+ harnessBrokerLaunchAgentPlistPath(environment, harnessId)
16429
+ ]);
16430
+ await runLaunchctl(["kickstart", target]);
16431
+ }
16326
16432
  var BrokerConnection = class _BrokerConnection {
16327
16433
  #onClose;
16328
16434
  onClose(callback) {
@@ -16346,21 +16452,31 @@ var BrokerConnection = class _BrokerConnection {
16346
16452
  socket.once("error", (error51) => this.#fail(error51));
16347
16453
  }
16348
16454
  static async connect(descriptorPath, harnessId) {
16349
- const descriptor = await readDescriptor(descriptorPath);
16350
- if (descriptor.harnessId !== harnessId)
16351
- throw new Error("Aqua broker belongs to another Harness");
16352
- const socket = net.createConnection(descriptor.socketPath);
16353
- await new Promise((resolve, reject) => {
16354
- const timeout = setTimeout(() => reject(new Error("Timed out connecting to Aqua Harness broker")), HARNESS_BROKER_REQUEST_TIMEOUT_MS);
16355
- socket.once("connect", () => {
16356
- clearTimeout(timeout);
16357
- resolve();
16358
- });
16359
- socket.once("error", (error51) => {
16360
- clearTimeout(timeout);
16361
- reject(error51);
16455
+ let descriptor;
16456
+ let socket;
16457
+ let connecting;
16458
+ try {
16459
+ descriptor = await readDescriptor(descriptorPath);
16460
+ if (descriptor.harnessId !== harnessId)
16461
+ throw new Error("Aqua broker belongs to another Harness");
16462
+ connecting = net.createConnection(descriptor.socketPath);
16463
+ const pending = connecting;
16464
+ await new Promise((resolve, reject) => {
16465
+ const timeout = setTimeout(() => reject(new Error("Timed out connecting to Aqua Harness broker")), HARNESS_BROKER_REQUEST_TIMEOUT_MS);
16466
+ pending.once("connect", () => {
16467
+ clearTimeout(timeout);
16468
+ resolve();
16469
+ });
16470
+ pending.once("error", (error51) => {
16471
+ clearTimeout(timeout);
16472
+ reject(error51);
16473
+ });
16362
16474
  });
16363
- });
16475
+ socket = pending;
16476
+ } catch (error51) {
16477
+ connecting?.destroy();
16478
+ throw classifyConnectFailure(error51);
16479
+ }
16364
16480
  const connection = new _BrokerConnection(descriptor, socket);
16365
16481
  const hello = connection.#waitForHello();
16366
16482
  await writeBrokerFrame(socket, {
@@ -16413,15 +16529,24 @@ var BrokerConnection = class _BrokerConnection {
16413
16529
  }, HARNESS_BROKER_REQUEST_TIMEOUT_MS);
16414
16530
  this.#pending.set(id, { resolve, reject, timeout });
16415
16531
  });
16416
- await writeBrokerFrame(this.#socket, {
16417
- version: HARNESS_BROKER_PROTOCOL_VERSION,
16418
- generation: this.#descriptor.generation,
16419
- sequence: this.#inputSequence,
16420
- kind: "request",
16421
- id,
16422
- method,
16423
- params
16424
- });
16532
+ try {
16533
+ await writeBrokerFrame(this.#socket, {
16534
+ version: HARNESS_BROKER_PROTOCOL_VERSION,
16535
+ generation: this.#descriptor.generation,
16536
+ sequence: this.#inputSequence,
16537
+ kind: "request",
16538
+ id,
16539
+ method,
16540
+ params
16541
+ });
16542
+ } catch (error51) {
16543
+ const pending = this.#pending.get(id);
16544
+ if (pending)
16545
+ clearTimeout(pending.timeout);
16546
+ this.#pending.delete(id);
16547
+ response.catch(() => void 0);
16548
+ throw new BrokerRequestNotDeliveredError(error51 instanceof Error ? error51.message : String(error51));
16549
+ }
16425
16550
  return response;
16426
16551
  }
16427
16552
  close() {
@@ -16465,6 +16590,8 @@ var BrokerConnection = class _BrokerConnection {
16465
16590
  this.#pending.delete(frame.id);
16466
16591
  if (frame.ok)
16467
16592
  pending.resolve(frame.value);
16593
+ else if (frame.error?.code === HARNESS_BROKER_RETIRING_ERROR_CODE)
16594
+ pending.reject(new BrokerRetiringError(frame.error.message));
16468
16595
  else
16469
16596
  pending.reject(new Error(frame.error?.message ?? "Broker request failed"));
16470
16597
  }
@@ -16690,17 +16817,19 @@ var BrokeredHarnessAdapter = class {
16690
16817
  harnessId;
16691
16818
  #descriptorPath;
16692
16819
  #forwardEnvironment;
16820
+ #isInstalled;
16821
+ #startBroker;
16822
+ #startTimeoutMs;
16693
16823
  #connection = null;
16694
16824
  #closed = false;
16825
+ #credits = null;
16826
+ #creditsRefresh = null;
16695
16827
  subagents = {
16696
16828
  readSnapshot: async (input) => {
16697
16829
  try {
16698
- return parseHarnessResult(await (await this.#connect()).request("adapter.subagent.readSnapshot", input));
16830
+ return parseHarnessResult(await this.#request("adapter.subagent.readSnapshot", input));
16699
16831
  } catch (error51) {
16700
- return {
16701
- ok: false,
16702
- error: unavailable(error51 instanceof Error ? error51.message : String(error51))
16703
- };
16832
+ return { ok: false, error: this.#error(error51) };
16704
16833
  }
16705
16834
  }
16706
16835
  };
@@ -16712,12 +16841,39 @@ var BrokeredHarnessAdapter = class {
16712
16841
  if (input.liveCommandCatalog)
16713
16842
  this.liveCommandCatalog = true;
16714
16843
  this.#descriptorPath = input.descriptorPath ?? defaultHarnessBrokerDescriptorPath(input.environment, this.harnessId);
16844
+ this.#isInstalled = input.isInstalled;
16845
+ const environment = input.environment ?? process.env;
16846
+ this.#startBroker = input.startBroker === false ? void 0 : input.startBroker ?? (process.platform === "darwin" && !input.descriptorPath ? () => startBrokerLaunchAgent(this.harnessId, environment) : void 0);
16847
+ this.#startTimeoutMs = input.startTimeoutMs ?? BROKER_START_TIMEOUT_MS;
16848
+ }
16849
+ credits() {
16850
+ return this.#credits;
16851
+ }
16852
+ refreshCredits() {
16853
+ if (this.#closed)
16854
+ return Promise.resolve(null);
16855
+ if (this.#creditsRefresh)
16856
+ return this.#creditsRefresh;
16857
+ this.#creditsRefresh = this.#readCredits().finally(() => {
16858
+ this.#creditsRefresh = null;
16859
+ });
16860
+ return this.#creditsRefresh;
16861
+ }
16862
+ async #readCredits() {
16863
+ try {
16864
+ const value = await this.#request("adapter.credits", {}, true);
16865
+ const credits = accountCreditsSnapshotSchema.nullable().parse(value);
16866
+ if (!this.#closed)
16867
+ this.#credits = credits;
16868
+ } catch {
16869
+ }
16870
+ return this.#credits;
16715
16871
  }
16716
16872
  async inspectAccount() {
16717
16873
  if (this.#closed)
16718
16874
  return null;
16719
16875
  try {
16720
- const value = await (await this.#connect()).request("adapter.inspectAccount", {});
16876
+ const value = await this.#request("adapter.inspectAccount", {}, true);
16721
16877
  return harnessAccountSnapshotSchema.nullable().parse(value);
16722
16878
  } catch {
16723
16879
  return null;
@@ -16727,33 +16883,46 @@ var BrokeredHarnessAdapter = class {
16727
16883
  if (this.#closed)
16728
16884
  return failedInspection("Aqua Harness broker adapter is closed");
16729
16885
  try {
16730
- return harnessInspectionSchema.parse(await (await this.#connect()).request("adapter.inspect", input));
16886
+ return harnessInspectionSchema.parse(await this.#request("adapter.inspect", input, true));
16731
16887
  } catch (error51) {
16732
16888
  this.#connection = null;
16733
- return failedInspection(error51 instanceof Error ? error51.message : String(error51));
16889
+ if (error51 instanceof HarnessNotInstalledError)
16890
+ return { status: "notInstalled", error: this.#error(error51) };
16891
+ return failedInspection(describeBrokerFailure(error51, this.harnessId));
16734
16892
  }
16735
16893
  }
16736
16894
  async open(input) {
16737
16895
  if (this.#closed)
16738
16896
  return { ok: false, error: unavailable("Aqua Harness broker adapter is closed", false) };
16897
+ const safeInput = { ...input };
16898
+ delete safeInput.environment;
16899
+ if (this.#forwardEnvironment && input.environment) {
16900
+ const allowed = [
16901
+ "CODEXHOST_CLI_PATH",
16902
+ "CODEXHOST_CLI_NODE_PATH",
16903
+ "CODEXHOST_RUNTIME_ENDPOINT",
16904
+ "CODEXHOST_RUNTIME_TOKEN",
16905
+ "CODEXHOST_THREAD_ID"
16906
+ ];
16907
+ const environment = Object.fromEntries(Object.entries(input.environment).filter(([key, value]) => allowed.includes(key) && value !== void 0));
16908
+ if (Object.keys(environment).length)
16909
+ safeInput.environment = environment;
16910
+ }
16739
16911
  let connection;
16740
16912
  try {
16741
- const safeInput = { ...input };
16742
- delete safeInput.environment;
16743
- if (this.#forwardEnvironment && input.environment) {
16744
- const allowed = [
16745
- "CODEXHOST_CLI_PATH",
16746
- "CODEXHOST_CLI_NODE_PATH",
16747
- "CODEXHOST_RUNTIME_ENDPOINT",
16748
- "CODEXHOST_RUNTIME_TOKEN",
16749
- "CODEXHOST_THREAD_ID"
16750
- ];
16751
- const environment = Object.fromEntries(Object.entries(input.environment).filter(([key, value]) => allowed.includes(key) && value !== void 0));
16752
- if (Object.keys(environment).length)
16753
- safeInput.environment = environment;
16754
- }
16755
- connection = await this.#connect();
16756
- const result = parseHarnessResult(await connection.request("adapter.open", safeInput));
16913
+ let value;
16914
+ for (let attempt = 0; ; attempt += 1) {
16915
+ connection = await this.#connect();
16916
+ try {
16917
+ value = await connection.request("adapter.open", safeInput);
16918
+ break;
16919
+ } catch (error51) {
16920
+ if (attempt > 0 || !(error51 instanceof BrokerRetiringError || error51 instanceof BrokerRequestNotDeliveredError))
16921
+ throw error51;
16922
+ this.#connection = null;
16923
+ }
16924
+ }
16925
+ const result = parseHarnessResult(value);
16757
16926
  if (!result.ok)
16758
16927
  return result;
16759
16928
  const session = new BrokeredHarnessSession(connection, parseSessionMetadata(result.value), this.harnessId, safeInput, () => this.#connect(), () => {
@@ -16764,25 +16933,51 @@ var BrokeredHarnessAdapter = class {
16764
16933
  } catch (error51) {
16765
16934
  connection?.close();
16766
16935
  this.#connection = null;
16767
- return {
16768
- ok: false,
16769
- error: unavailable(error51 instanceof Error ? error51.message : String(error51))
16770
- };
16936
+ return { ok: false, error: this.#error(error51) };
16771
16937
  }
16772
16938
  }
16773
16939
  async close() {
16774
16940
  this.#closed = true;
16941
+ this.#credits = null;
16775
16942
  await Promise.allSettled([...this.#sessions].map((session) => session.close()));
16776
16943
  this.#sessions.clear();
16777
16944
  const connection = await this.#connection?.catch(() => null);
16778
16945
  await connection?.dispose();
16779
16946
  this.#connection = null;
16780
16947
  }
16948
+ #error(error51) {
16949
+ if (error51 instanceof HarnessNotInstalledError)
16950
+ return {
16951
+ code: "notInstalled",
16952
+ message: error51.message,
16953
+ retryable: false,
16954
+ stage: "harnessBroker"
16955
+ };
16956
+ return unavailable(describeBrokerFailure(error51, this.harnessId));
16957
+ }
16958
+ /**
16959
+ * Sends one adapter-level request. A broker that retired between requests refuses it
16960
+ * unprocessed, so it is retried once on a fresh broker. Idempotent reads also retry
16961
+ * once after a plain disconnect.
16962
+ */
16963
+ async #request(method, params, idempotent = false) {
16964
+ for (let attempt = 0; ; attempt += 1) {
16965
+ const connection = await this.#connect();
16966
+ try {
16967
+ return await connection.request(method, params);
16968
+ } catch (error51) {
16969
+ const retryable = error51 instanceof BrokerRetiringError || error51 instanceof BrokerRequestNotDeliveredError || idempotent && connection.closed;
16970
+ if (attempt > 0 || !retryable)
16971
+ throw error51;
16972
+ this.#connection = null;
16973
+ }
16974
+ }
16975
+ }
16781
16976
  #connect() {
16782
16977
  if (this.#closed)
16783
16978
  return Promise.reject(new Error("Aqua Harness broker adapter is closed"));
16784
16979
  if (!this.#connection) {
16785
- const pending = BrokerConnection.connect(this.#descriptorPath, this.harnessId).then((connection) => {
16980
+ const pending = this.#establish().then((connection) => {
16786
16981
  connection.onClose(() => {
16787
16982
  if (this.#connection === pending)
16788
16983
  this.#connection = null;
@@ -16797,13 +16992,35 @@ var BrokeredHarnessAdapter = class {
16797
16992
  }
16798
16993
  return this.#connection;
16799
16994
  }
16995
+ async #establish() {
16996
+ try {
16997
+ return await BrokerConnection.connect(this.#descriptorPath, this.harnessId);
16998
+ } catch (error51) {
16999
+ if (!(error51 instanceof BrokerNotRunningError) || !this.#startBroker)
17000
+ throw error51;
17001
+ }
17002
+ if (this.#isInstalled && !this.#isInstalled()) {
17003
+ throw new HarnessNotInstalledError(`${this.harnessId} is not installed on this Mac`);
17004
+ }
17005
+ const deadline = Date.now() + this.#startTimeoutMs;
17006
+ for (; ; ) {
17007
+ await this.#startBroker();
17008
+ try {
17009
+ return await BrokerConnection.connect(this.#descriptorPath, this.harnessId);
17010
+ } catch (error51) {
17011
+ if (!(error51 instanceof BrokerNotRunningError) || Date.now() >= deadline)
17012
+ throw error51;
17013
+ }
17014
+ await new Promise((resolve) => setTimeout(resolve, BROKER_START_POLL_MS));
17015
+ }
17016
+ }
16800
17017
  };
16801
17018
 
16802
17019
  // ../codebuddy/dist/codebuddy-adapter.js
16803
17020
  import { stat as stat3 } from "node:fs/promises";
16804
17021
 
16805
17022
  // ../codebuddy/dist/acp-client.js
16806
- import { execFile, spawn } from "node:child_process";
17023
+ import { execFile as execFile2, spawn } from "node:child_process";
16807
17024
  import { Readable as Readable2, Writable } from "node:stream";
16808
17025
 
16809
17026
  // ../../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -21523,7 +21740,7 @@ var CodeBuddyAcpClient = class {
21523
21740
  }
21524
21741
  const pid = this.#child.pid;
21525
21742
  if (pid && process.platform === "win32") {
21526
- await new Promise((resolve) => execFile("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
21743
+ await new Promise((resolve) => execFile2("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
21527
21744
  } else if (pid) {
21528
21745
  try {
21529
21746
  process.kill(-pid, "SIGKILL");
@@ -21615,7 +21832,7 @@ function confirmedConfiguration(response, id, value, profile = CODEBUDDY_RUNTIME
21615
21832
 
21616
21833
  // ../codebuddy/dist/derivation.js
21617
21834
  import { randomUUID as randomUUID2 } from "node:crypto";
21618
- import { execFile as execFile2, spawn as spawn2 } from "node:child_process";
21835
+ import { execFile as execFile3, spawn as spawn2 } from "node:child_process";
21619
21836
  import { lstat as lstat2, mkdir, readFile as readFile3, realpath as realpath4, unlink, writeFile } from "node:fs/promises";
21620
21837
  import path6 from "node:path";
21621
21838
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
@@ -23078,7 +23295,7 @@ async function copyCodeBuddySession(cwd, sourceId, targetId, environment, signal
23078
23295
  child.stderr.destroy();
23079
23296
  } else if (process.platform === "win32" && child.pid) {
23080
23297
  termination = new Promise((done) => {
23081
- execFile2("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
23298
+ execFile3("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
23082
23299
  child.kill();
23083
23300
  done();
23084
23301
  });
@@ -25437,14 +25654,27 @@ var WorkBuddyAdapter = class extends CodeBuddyAdapter {
25437
25654
 
25438
25655
  // dist/plugin.js
25439
25656
  function createHarnessAdapter(context) {
25440
- if (context.platform === "darwin" && context.managedRemoteHost)
25657
+ if (context.platform === "darwin" && context.managedRemoteHost) {
25658
+ const environment = {
25659
+ ...context.environment,
25660
+ ...context.launchCommand ? { CODEXHOST_WORKBUDDY_COMMAND: context.launchCommand } : {}
25661
+ };
25441
25662
  return new BrokeredHarnessAdapter({
25442
25663
  harnessId: "workbuddy",
25443
25664
  commandCatalog: WORKBUDDY_COMMAND_CATALOG,
25444
25665
  forwardDelegationEnvironment: true,
25445
25666
  environment: { ...context.environment },
25667
+ isInstalled: () => {
25668
+ try {
25669
+ workBuddyInvocation(environment, true);
25670
+ return true;
25671
+ } catch (error51) {
25672
+ return !(error51 instanceof CodeBuddyError && error51.code === "notInstalled");
25673
+ }
25674
+ },
25446
25675
  ...context.brokerDescriptorPath ? { descriptorPath: context.brokerDescriptorPath } : {}
25447
25676
  });
25677
+ }
25448
25678
  return new WorkBuddyAdapter({
25449
25679
  environment: {
25450
25680
  ...context.environment,
@@ -14593,6 +14593,20 @@ var harnessDisplaySetSchema = external_exports.strictObject({
14593
14593
  initializeOnly: external_exports.boolean().optional()
14594
14594
  });
14595
14595
 
14596
+ // ../../shared-contracts/dist/ids.js
14597
+ var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
14598
+ message: "Identifier must not be empty or whitespace"
14599
+ });
14600
+ var harnessIdSchema = opaqueIdSchema.brand();
14601
+ var hostThreadIdSchema = opaqueIdSchema.brand();
14602
+ var hostTurnIdSchema = opaqueIdSchema.brand();
14603
+ var hostItemIdSchema = opaqueIdSchema.brand();
14604
+ var hostInteractionIdSchema = opaqueIdSchema.brand();
14605
+
14606
+ // ../../shared-contracts/dist/thread-prewarm.js
14607
+ var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
14608
+ var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
14609
+
14596
14610
  // ../../shared-contracts/dist/console.js
14597
14611
  var consoleAnnouncementSchema = external_exports.strictObject({
14598
14612
  title: external_exports.string().trim().min(1).max(200),
@@ -14605,6 +14619,9 @@ var consoleOpenResultSchema = external_exports.strictObject({
14605
14619
  url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
14606
14620
  });
14607
14621
  var CONSOLE_HOST_METHODS = Object.freeze([
14622
+ "codexhost/console/remote-connections",
14623
+ "codexhost/runtime/status",
14624
+ "codexhost/remote/ssh-setup",
14608
14625
  "codexhost/harness/plugins/list",
14609
14626
  "codexhost/harness/display-settings/get",
14610
14627
  "codexhost/harness/display-settings/set",
@@ -14671,16 +14688,6 @@ var loadedSessionsSchema = external_exports.array(external_exports.strictObject(
14671
14688
  inactiveMs: external_exports.number().nonnegative()
14672
14689
  }));
14673
14690
 
14674
- // ../../shared-contracts/dist/ids.js
14675
- var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
14676
- message: "Identifier must not be empty or whitespace"
14677
- });
14678
- var harnessIdSchema = opaqueIdSchema.brand();
14679
- var hostThreadIdSchema = opaqueIdSchema.brand();
14680
- var hostTurnIdSchema = opaqueIdSchema.brand();
14681
- var hostItemIdSchema = opaqueIdSchema.brand();
14682
- var hostInteractionIdSchema = opaqueIdSchema.brand();
14683
-
14684
14691
  // ../../shared-contracts/dist/manual-compaction.js
14685
14692
  var threadManualCompactionStartedSchema = external_exports.strictObject({
14686
14693
  threadId: hostThreadIdSchema,
@@ -15595,11 +15602,53 @@ var remoteSshSetupParamsSchema = external_exports.object({
15595
15602
  hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
15596
15603
  port: external_exports.number().int().min(1).max(65535).nullable(),
15597
15604
  identity: external_exports.string().max(4096).nullable(),
15598
- action: external_exports.enum(["inspect", "install", "update", "repair"]),
15605
+ action: external_exports.enum(["inspect", "install", "update", "repair", "uninstall"]),
15606
+ uninstallPackage: external_exports.boolean().optional(),
15599
15607
  version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
15600
15608
  }).strict();
15601
15609
  var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
15602
15610
 
15611
+ // ../../shared-contracts/dist/remote-connections.js
15612
+ var hostId = external_exports.string().min(1).max(1024);
15613
+ var codexSshConnectionSchema = external_exports.object({
15614
+ hostId,
15615
+ displayName: external_exports.string().min(1).max(1024),
15616
+ source: external_exports.enum(["codex-managed", "discovered"]),
15617
+ sshAlias: external_exports.string().max(1024).nullable(),
15618
+ sshHost: external_exports.string().min(1).max(1024),
15619
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
15620
+ identity: external_exports.string().max(4096).nullable(),
15621
+ autoConnect: external_exports.boolean(),
15622
+ connectionAnalyticsId: external_exports.string().max(1024).optional()
15623
+ });
15624
+ var codexSshDraftSchema = external_exports.strictObject({
15625
+ displayName: external_exports.string().min(1).max(1024),
15626
+ hostname: external_exports.string().min(1).max(1024),
15627
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
15628
+ identity: external_exports.string().max(4096).nullable()
15629
+ });
15630
+ var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
15631
+ external_exports.strictObject({ action: external_exports.literal("list") }),
15632
+ external_exports.strictObject({
15633
+ action: external_exports.literal("save"),
15634
+ draft: codexSshDraftSchema,
15635
+ previous: codexSshConnectionSchema.nullable()
15636
+ }),
15637
+ external_exports.strictObject({ action: external_exports.literal("remove"), previous: codexSshConnectionSchema }),
15638
+ external_exports.strictObject({ action: external_exports.literal("connect"), hostId, enabled: external_exports.boolean() }),
15639
+ external_exports.strictObject({ action: external_exports.literal("state"), hostId }),
15640
+ external_exports.strictObject({ action: external_exports.literal("runtime"), hostId }),
15641
+ external_exports.strictObject({
15642
+ action: external_exports.literal("update"),
15643
+ hostId: hostId.refine((id) => id !== "local"),
15644
+ version: remoteUpdateParamsSchema.shape.version
15645
+ })
15646
+ ]);
15647
+ var remoteConnectionsReplySchema = external_exports.union([
15648
+ external_exports.strictObject({ result: jsonValueSchema }),
15649
+ external_exports.strictObject({ error: external_exports.strictObject({ code: external_exports.number().int(), message: external_exports.string() }) })
15650
+ ]);
15651
+
15603
15652
  // ../../shared-contracts/dist/index.js
15604
15653
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15605
15654