@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
 
@@ -15919,9 +15969,12 @@ var HARNESS_BROKER_PROTOCOL_VERSION = 1;
15919
15969
  var HARNESS_BROKER_MAX_FRAME_BYTES = 8 * 1024 * 1024;
15920
15970
  var HARNESS_BROKER_MAX_PENDING_REQUESTS = 32;
15921
15971
  var HARNESS_BROKER_REQUEST_TIMEOUT_MS = 15e3;
15972
+ var HARNESS_BROKER_IDLE_TIMEOUT_MS = 60 * 60 * 1e3;
15973
+ var HARNESS_BROKER_RETIRING_ERROR_CODE = "brokerRetiring";
15922
15974
  var harnessBrokerMethodSchema = external_exports.enum([
15923
15975
  "adapter.inspect",
15924
15976
  "adapter.inspectAccount",
15977
+ "adapter.credits",
15925
15978
  "adapter.open",
15926
15979
  "adapter.subagent.readSnapshot",
15927
15980
  "session.readSnapshot",
@@ -16039,6 +16092,14 @@ function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId
16039
16092
  return path.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
16040
16093
  return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
16041
16094
  }
16095
+ function harnessBrokerLaunchAgentLabel(harnessId = "claude-code") {
16096
+ harnessPluginIdSchema.parse(harnessId);
16097
+ return harnessId === "claude-code" ? "ai.bytepioneer.codexhost.native-harness-broker" : `ai.bytepioneer.codexhost.${harnessId}-broker`;
16098
+ }
16099
+ function harnessBrokerLaunchAgentPlistPath(environment = process.env, harnessId = "claude-code") {
16100
+ const home = environment.HOME || os.homedir();
16101
+ return path.join(home, "Library", "LaunchAgents", `${harnessBrokerLaunchAgentLabel(harnessId)}.plist`);
16102
+ }
16042
16103
 
16043
16104
  // ../../harness-broker/dist/validation.js
16044
16105
  var cwdSchema = external_exports.string().min(1).max(16384);
@@ -16344,10 +16405,55 @@ async function readDescriptor(descriptorPath) {
16344
16405
  try {
16345
16406
  process.kill(descriptor.ownerPid, 0);
16346
16407
  } catch {
16347
- throw new Error("Aqua Harness broker owner process is unavailable");
16408
+ throw new BrokerNotRunningError("its owner process has exited");
16348
16409
  }
16349
16410
  return descriptor;
16350
16411
  }
16412
+ var BrokerNotRunningError = class extends Error {
16413
+ };
16414
+ var BrokerRetiringError = class extends Error {
16415
+ };
16416
+ var BrokerRequestNotDeliveredError = class extends Error {
16417
+ };
16418
+ var HarnessNotInstalledError = class extends Error {
16419
+ };
16420
+ var BROKER_NOT_RUNNING_CODES = /* @__PURE__ */ new Set(["ENOENT", "ECONNREFUSED"]);
16421
+ var BROKER_START_TIMEOUT_MS = 15e3;
16422
+ var BROKER_START_POLL_MS = 250;
16423
+ function classifyConnectFailure(error52) {
16424
+ if (error52 instanceof BrokerNotRunningError)
16425
+ return error52;
16426
+ const code = error52?.code;
16427
+ if (code && BROKER_NOT_RUNNING_CODES.has(code)) {
16428
+ return new BrokerNotRunningError(code === "ENOENT" ? "its descriptor or socket is missing" : "its socket refused the connection");
16429
+ }
16430
+ return error52 instanceof Error ? error52 : new Error(String(error52));
16431
+ }
16432
+ function describeBrokerFailure(error52, harnessId) {
16433
+ if (error52 instanceof BrokerNotRunningError) {
16434
+ return `The ${harnessId} Aqua Harness broker on this Mac could not be started (${error52.message}). Keep the desktop user logged in, then repair the remote service or run on this Mac: codexhost broker install --harness ${harnessId}`;
16435
+ }
16436
+ return error52 instanceof Error ? error52.message : String(error52);
16437
+ }
16438
+ function runLaunchctl(arguments_) {
16439
+ return new Promise((resolve2) => {
16440
+ execFile("/bin/launchctl", arguments_, { timeout: 1e4 }, (error52) => resolve2(!error52));
16441
+ });
16442
+ }
16443
+ async function startBrokerLaunchAgent(harnessId, environment) {
16444
+ const uid = process.getuid?.();
16445
+ if (uid === void 0)
16446
+ return;
16447
+ const target = `gui/${uid}/${harnessBrokerLaunchAgentLabel(harnessId)}`;
16448
+ if (await runLaunchctl(["kickstart", target]))
16449
+ return;
16450
+ await runLaunchctl([
16451
+ "bootstrap",
16452
+ `gui/${uid}`,
16453
+ harnessBrokerLaunchAgentPlistPath(environment, harnessId)
16454
+ ]);
16455
+ await runLaunchctl(["kickstart", target]);
16456
+ }
16351
16457
  var BrokerConnection = class _BrokerConnection {
16352
16458
  #onClose;
16353
16459
  onClose(callback) {
@@ -16371,21 +16477,31 @@ var BrokerConnection = class _BrokerConnection {
16371
16477
  socket.once("error", (error52) => this.#fail(error52));
16372
16478
  }
16373
16479
  static async connect(descriptorPath, harnessId) {
16374
- const descriptor = await readDescriptor(descriptorPath);
16375
- if (descriptor.harnessId !== harnessId)
16376
- throw new Error("Aqua broker belongs to another Harness");
16377
- const socket = net.createConnection(descriptor.socketPath);
16378
- await new Promise((resolve2, reject) => {
16379
- const timeout = setTimeout(() => reject(new Error("Timed out connecting to Aqua Harness broker")), HARNESS_BROKER_REQUEST_TIMEOUT_MS);
16380
- socket.once("connect", () => {
16381
- clearTimeout(timeout);
16382
- resolve2();
16383
- });
16384
- socket.once("error", (error52) => {
16385
- clearTimeout(timeout);
16386
- reject(error52);
16480
+ let descriptor;
16481
+ let socket;
16482
+ let connecting;
16483
+ try {
16484
+ descriptor = await readDescriptor(descriptorPath);
16485
+ if (descriptor.harnessId !== harnessId)
16486
+ throw new Error("Aqua broker belongs to another Harness");
16487
+ connecting = net.createConnection(descriptor.socketPath);
16488
+ const pending = connecting;
16489
+ await new Promise((resolve2, reject) => {
16490
+ const timeout = setTimeout(() => reject(new Error("Timed out connecting to Aqua Harness broker")), HARNESS_BROKER_REQUEST_TIMEOUT_MS);
16491
+ pending.once("connect", () => {
16492
+ clearTimeout(timeout);
16493
+ resolve2();
16494
+ });
16495
+ pending.once("error", (error52) => {
16496
+ clearTimeout(timeout);
16497
+ reject(error52);
16498
+ });
16387
16499
  });
16388
- });
16500
+ socket = pending;
16501
+ } catch (error52) {
16502
+ connecting?.destroy();
16503
+ throw classifyConnectFailure(error52);
16504
+ }
16389
16505
  const connection = new _BrokerConnection(descriptor, socket);
16390
16506
  const hello = connection.#waitForHello();
16391
16507
  await writeBrokerFrame(socket, {
@@ -16438,15 +16554,24 @@ var BrokerConnection = class _BrokerConnection {
16438
16554
  }, HARNESS_BROKER_REQUEST_TIMEOUT_MS);
16439
16555
  this.#pending.set(id, { resolve: resolve2, reject, timeout });
16440
16556
  });
16441
- await writeBrokerFrame(this.#socket, {
16442
- version: HARNESS_BROKER_PROTOCOL_VERSION,
16443
- generation: this.#descriptor.generation,
16444
- sequence: this.#inputSequence,
16445
- kind: "request",
16446
- id,
16447
- method,
16448
- params
16449
- });
16557
+ try {
16558
+ await writeBrokerFrame(this.#socket, {
16559
+ version: HARNESS_BROKER_PROTOCOL_VERSION,
16560
+ generation: this.#descriptor.generation,
16561
+ sequence: this.#inputSequence,
16562
+ kind: "request",
16563
+ id,
16564
+ method,
16565
+ params
16566
+ });
16567
+ } catch (error52) {
16568
+ const pending = this.#pending.get(id);
16569
+ if (pending)
16570
+ clearTimeout(pending.timeout);
16571
+ this.#pending.delete(id);
16572
+ response.catch(() => void 0);
16573
+ throw new BrokerRequestNotDeliveredError(error52 instanceof Error ? error52.message : String(error52));
16574
+ }
16450
16575
  return response;
16451
16576
  }
16452
16577
  close() {
@@ -16490,6 +16615,8 @@ var BrokerConnection = class _BrokerConnection {
16490
16615
  this.#pending.delete(frame.id);
16491
16616
  if (frame.ok)
16492
16617
  pending.resolve(frame.value);
16618
+ else if (frame.error?.code === HARNESS_BROKER_RETIRING_ERROR_CODE)
16619
+ pending.reject(new BrokerRetiringError(frame.error.message));
16493
16620
  else
16494
16621
  pending.reject(new Error(frame.error?.message ?? "Broker request failed"));
16495
16622
  }
@@ -16715,17 +16842,19 @@ var BrokeredHarnessAdapter = class {
16715
16842
  harnessId;
16716
16843
  #descriptorPath;
16717
16844
  #forwardEnvironment;
16845
+ #isInstalled;
16846
+ #startBroker;
16847
+ #startTimeoutMs;
16718
16848
  #connection = null;
16719
16849
  #closed = false;
16850
+ #credits = null;
16851
+ #creditsRefresh = null;
16720
16852
  subagents = {
16721
16853
  readSnapshot: async (input) => {
16722
16854
  try {
16723
- return parseHarnessResult(await (await this.#connect()).request("adapter.subagent.readSnapshot", input));
16855
+ return parseHarnessResult(await this.#request("adapter.subagent.readSnapshot", input));
16724
16856
  } catch (error52) {
16725
- return {
16726
- ok: false,
16727
- error: unavailable(error52 instanceof Error ? error52.message : String(error52))
16728
- };
16857
+ return { ok: false, error: this.#error(error52) };
16729
16858
  }
16730
16859
  }
16731
16860
  };
@@ -16737,12 +16866,39 @@ var BrokeredHarnessAdapter = class {
16737
16866
  if (input.liveCommandCatalog)
16738
16867
  this.liveCommandCatalog = true;
16739
16868
  this.#descriptorPath = input.descriptorPath ?? defaultHarnessBrokerDescriptorPath(input.environment, this.harnessId);
16869
+ this.#isInstalled = input.isInstalled;
16870
+ const environment = input.environment ?? process.env;
16871
+ this.#startBroker = input.startBroker === false ? void 0 : input.startBroker ?? (process.platform === "darwin" && !input.descriptorPath ? () => startBrokerLaunchAgent(this.harnessId, environment) : void 0);
16872
+ this.#startTimeoutMs = input.startTimeoutMs ?? BROKER_START_TIMEOUT_MS;
16873
+ }
16874
+ credits() {
16875
+ return this.#credits;
16876
+ }
16877
+ refreshCredits() {
16878
+ if (this.#closed)
16879
+ return Promise.resolve(null);
16880
+ if (this.#creditsRefresh)
16881
+ return this.#creditsRefresh;
16882
+ this.#creditsRefresh = this.#readCredits().finally(() => {
16883
+ this.#creditsRefresh = null;
16884
+ });
16885
+ return this.#creditsRefresh;
16886
+ }
16887
+ async #readCredits() {
16888
+ try {
16889
+ const value = await this.#request("adapter.credits", {}, true);
16890
+ const credits = accountCreditsSnapshotSchema.nullable().parse(value);
16891
+ if (!this.#closed)
16892
+ this.#credits = credits;
16893
+ } catch {
16894
+ }
16895
+ return this.#credits;
16740
16896
  }
16741
16897
  async inspectAccount() {
16742
16898
  if (this.#closed)
16743
16899
  return null;
16744
16900
  try {
16745
- const value = await (await this.#connect()).request("adapter.inspectAccount", {});
16901
+ const value = await this.#request("adapter.inspectAccount", {}, true);
16746
16902
  return harnessAccountSnapshotSchema.nullable().parse(value);
16747
16903
  } catch {
16748
16904
  return null;
@@ -16752,33 +16908,46 @@ var BrokeredHarnessAdapter = class {
16752
16908
  if (this.#closed)
16753
16909
  return failedInspection("Aqua Harness broker adapter is closed");
16754
16910
  try {
16755
- return harnessInspectionSchema.parse(await (await this.#connect()).request("adapter.inspect", input));
16911
+ return harnessInspectionSchema.parse(await this.#request("adapter.inspect", input, true));
16756
16912
  } catch (error52) {
16757
16913
  this.#connection = null;
16758
- return failedInspection(error52 instanceof Error ? error52.message : String(error52));
16914
+ if (error52 instanceof HarnessNotInstalledError)
16915
+ return { status: "notInstalled", error: this.#error(error52) };
16916
+ return failedInspection(describeBrokerFailure(error52, this.harnessId));
16759
16917
  }
16760
16918
  }
16761
16919
  async open(input) {
16762
16920
  if (this.#closed)
16763
16921
  return { ok: false, error: unavailable("Aqua Harness broker adapter is closed", false) };
16922
+ const safeInput = { ...input };
16923
+ delete safeInput.environment;
16924
+ if (this.#forwardEnvironment && input.environment) {
16925
+ const allowed2 = [
16926
+ "CODEXHOST_CLI_PATH",
16927
+ "CODEXHOST_CLI_NODE_PATH",
16928
+ "CODEXHOST_RUNTIME_ENDPOINT",
16929
+ "CODEXHOST_RUNTIME_TOKEN",
16930
+ "CODEXHOST_THREAD_ID"
16931
+ ];
16932
+ const environment = Object.fromEntries(Object.entries(input.environment).filter(([key, value]) => allowed2.includes(key) && value !== void 0));
16933
+ if (Object.keys(environment).length)
16934
+ safeInput.environment = environment;
16935
+ }
16764
16936
  let connection;
16765
16937
  try {
16766
- const safeInput = { ...input };
16767
- delete safeInput.environment;
16768
- if (this.#forwardEnvironment && input.environment) {
16769
- const allowed2 = [
16770
- "CODEXHOST_CLI_PATH",
16771
- "CODEXHOST_CLI_NODE_PATH",
16772
- "CODEXHOST_RUNTIME_ENDPOINT",
16773
- "CODEXHOST_RUNTIME_TOKEN",
16774
- "CODEXHOST_THREAD_ID"
16775
- ];
16776
- const environment = Object.fromEntries(Object.entries(input.environment).filter(([key, value]) => allowed2.includes(key) && value !== void 0));
16777
- if (Object.keys(environment).length)
16778
- safeInput.environment = environment;
16779
- }
16780
- connection = await this.#connect();
16781
- const result = parseHarnessResult(await connection.request("adapter.open", safeInput));
16938
+ let value;
16939
+ for (let attempt = 0; ; attempt += 1) {
16940
+ connection = await this.#connect();
16941
+ try {
16942
+ value = await connection.request("adapter.open", safeInput);
16943
+ break;
16944
+ } catch (error52) {
16945
+ if (attempt > 0 || !(error52 instanceof BrokerRetiringError || error52 instanceof BrokerRequestNotDeliveredError))
16946
+ throw error52;
16947
+ this.#connection = null;
16948
+ }
16949
+ }
16950
+ const result = parseHarnessResult(value);
16782
16951
  if (!result.ok)
16783
16952
  return result;
16784
16953
  const session = new BrokeredHarnessSession(connection, parseSessionMetadata(result.value), this.harnessId, safeInput, () => this.#connect(), () => {
@@ -16789,25 +16958,51 @@ var BrokeredHarnessAdapter = class {
16789
16958
  } catch (error52) {
16790
16959
  connection?.close();
16791
16960
  this.#connection = null;
16792
- return {
16793
- ok: false,
16794
- error: unavailable(error52 instanceof Error ? error52.message : String(error52))
16795
- };
16961
+ return { ok: false, error: this.#error(error52) };
16796
16962
  }
16797
16963
  }
16798
16964
  async close() {
16799
16965
  this.#closed = true;
16966
+ this.#credits = null;
16800
16967
  await Promise.allSettled([...this.#sessions].map((session) => session.close()));
16801
16968
  this.#sessions.clear();
16802
16969
  const connection = await this.#connection?.catch(() => null);
16803
16970
  await connection?.dispose();
16804
16971
  this.#connection = null;
16805
16972
  }
16973
+ #error(error52) {
16974
+ if (error52 instanceof HarnessNotInstalledError)
16975
+ return {
16976
+ code: "notInstalled",
16977
+ message: error52.message,
16978
+ retryable: false,
16979
+ stage: "harnessBroker"
16980
+ };
16981
+ return unavailable(describeBrokerFailure(error52, this.harnessId));
16982
+ }
16983
+ /**
16984
+ * Sends one adapter-level request. A broker that retired between requests refuses it
16985
+ * unprocessed, so it is retried once on a fresh broker. Idempotent reads also retry
16986
+ * once after a plain disconnect.
16987
+ */
16988
+ async #request(method, params, idempotent = false) {
16989
+ for (let attempt = 0; ; attempt += 1) {
16990
+ const connection = await this.#connect();
16991
+ try {
16992
+ return await connection.request(method, params);
16993
+ } catch (error52) {
16994
+ const retryable = error52 instanceof BrokerRetiringError || error52 instanceof BrokerRequestNotDeliveredError || idempotent && connection.closed;
16995
+ if (attempt > 0 || !retryable)
16996
+ throw error52;
16997
+ this.#connection = null;
16998
+ }
16999
+ }
17000
+ }
16806
17001
  #connect() {
16807
17002
  if (this.#closed)
16808
17003
  return Promise.reject(new Error("Aqua Harness broker adapter is closed"));
16809
17004
  if (!this.#connection) {
16810
- const pending = BrokerConnection.connect(this.#descriptorPath, this.harnessId).then((connection) => {
17005
+ const pending = this.#establish().then((connection) => {
16811
17006
  connection.onClose(() => {
16812
17007
  if (this.#connection === pending)
16813
17008
  this.#connection = null;
@@ -16822,6 +17017,28 @@ var BrokeredHarnessAdapter = class {
16822
17017
  }
16823
17018
  return this.#connection;
16824
17019
  }
17020
+ async #establish() {
17021
+ try {
17022
+ return await BrokerConnection.connect(this.#descriptorPath, this.harnessId);
17023
+ } catch (error52) {
17024
+ if (!(error52 instanceof BrokerNotRunningError) || !this.#startBroker)
17025
+ throw error52;
17026
+ }
17027
+ if (this.#isInstalled && !this.#isInstalled()) {
17028
+ throw new HarnessNotInstalledError(`${this.harnessId} is not installed on this Mac`);
17029
+ }
17030
+ const deadline = Date.now() + this.#startTimeoutMs;
17031
+ for (; ; ) {
17032
+ await this.#startBroker();
17033
+ try {
17034
+ return await BrokerConnection.connect(this.#descriptorPath, this.harnessId);
17035
+ } catch (error52) {
17036
+ if (!(error52 instanceof BrokerNotRunningError) || Date.now() >= deadline)
17037
+ throw error52;
17038
+ }
17039
+ await new Promise((resolve2) => setTimeout(resolve2, BROKER_START_POLL_MS));
17040
+ }
17041
+ }
16825
17042
  };
16826
17043
 
16827
17044
  // dist/claude-code-adapter.js
@@ -43047,13 +43264,13 @@ function resolveHarnessExecutable(spec, input, dependencies = {}) {
43047
43264
  }
43048
43265
 
43049
43266
  // ../../harness-discovery/dist/installation.js
43050
- import { execFile } from "node:child_process";
43267
+ import { execFile as execFile2 } from "node:child_process";
43051
43268
  import { homedir } from "node:os";
43052
43269
  function runInstallationCommand(command, args, environment, timeout = 3e4) {
43053
43270
  const env = withNodeRuntimeOnPath(environment);
43054
43271
  const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
43055
43272
  return new Promise((resolve2, reject) => {
43056
- const child = execFile(invocation.command, invocation.arguments, {
43273
+ const child = execFile2(invocation.command, invocation.arguments, {
43057
43274
  env,
43058
43275
  cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
43059
43276
  encoding: "utf8",
@@ -45385,11 +45602,11 @@ function projectClaudeAccountUsage(usage, account) {
45385
45602
  }
45386
45603
 
45387
45604
  // dist/process-fence.js
45388
- import { execFile as execFile2 } from "node:child_process";
45605
+ import { execFile as execFile3 } from "node:child_process";
45389
45606
  import path13 from "node:path";
45390
45607
  import { setTimeout as setTimeout2 } from "node:timers/promises";
45391
45608
  import { promisify } from "node:util";
45392
- var executeFile = promisify(execFile2);
45609
+ var executeFile = promisify(execFile3);
45393
45610
  function signalGroup(pid, signal) {
45394
45611
  try {
45395
45612
  process.kill(-pid, signal);
@@ -47239,6 +47456,9 @@ var ClaudeHarnessSession = class {
47239
47456
  this.#statePublished = durable;
47240
47457
  this.outputs = this.#channel.outputs;
47241
47458
  }
47459
+ get nativeWriterRef() {
47460
+ return this.#nativeRef;
47461
+ }
47242
47462
  async readSnapshot() {
47243
47463
  if (this.#phase !== "open") {
47244
47464
  return { ok: false, error: invalidState("Claude Code Session is not open") };
@@ -49432,7 +49652,7 @@ function createClaudeInstallation(environment, command) {
49432
49652
 
49433
49653
  // dist/user-shell-environment.js
49434
49654
  import path16 from "node:path";
49435
- import { execFile as execFile3 } from "node:child_process";
49655
+ import { execFile as execFile4 } from "node:child_process";
49436
49656
  var ENVIRONMENT_MARKER = Buffer.from("\0CODEXHOST_USER_SHELL_ENV_V1\0");
49437
49657
  var ENVIRONMENT_COMMAND = "printf '\\0CODEXHOST_USER_SHELL_ENV_V1\\0'; /usr/bin/env -0";
49438
49658
  var SHELL_ENVIRONMENT_TIMEOUT_MS = 3e3;
@@ -49481,7 +49701,7 @@ async function withUserShellEnvironment(environment, dependencies) {
49481
49701
  if (cached2)
49482
49702
  return mergeMissingEnvironment(environment, cached2);
49483
49703
  const run = dependencies?.run ?? ((command, arguments_, options) => new Promise((resolve2) => {
49484
- const child = execFile3(command, arguments_, {
49704
+ const child = execFile4(command, arguments_, {
49485
49705
  ...options,
49486
49706
  encoding: "buffer",
49487
49707
  killSignal: "SIGKILL"
@@ -49515,6 +49735,17 @@ async function createHarnessAdapter(context) {
49515
49735
  commandCatalog: claudeCommandCatalog,
49516
49736
  liveCommandCatalog: true,
49517
49737
  environment,
49738
+ isInstalled: () => {
49739
+ try {
49740
+ resolveClaudeCodeExecutable({
49741
+ ...environment[CLAUDE_CODE_COMMAND_ENV] ? { command: environment[CLAUDE_CODE_COMMAND_ENV] } : {},
49742
+ environment
49743
+ });
49744
+ return true;
49745
+ } catch (error52) {
49746
+ return !(error52 instanceof ClaudeCodeExecutableError);
49747
+ }
49748
+ },
49518
49749
  ...context.brokerDescriptorPath ? { descriptorPath: context.brokerDescriptorPath } : {}
49519
49750
  });
49520
49751
  }
@@ -49530,6 +49761,8 @@ async function createHarnessAdapter(context) {
49530
49761
  });
49531
49762
  }
49532
49763
  async function warmup(adapter) {
49764
+ if (adapter instanceof BrokeredHarnessAdapter)
49765
+ return;
49533
49766
  try {
49534
49767
  await adapter.inspect();
49535
49768
  } catch {