@codexhost/cli-win32-arm64 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.
@@ -15071,6 +15071,20 @@ var harnessDisplaySetSchema = external_exports.strictObject({
15071
15071
  initializeOnly: external_exports.boolean().optional()
15072
15072
  });
15073
15073
 
15074
+ // ../../shared-contracts/dist/ids.js
15075
+ var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
15076
+ message: "Identifier must not be empty or whitespace"
15077
+ });
15078
+ var harnessIdSchema = opaqueIdSchema.brand();
15079
+ var hostThreadIdSchema = opaqueIdSchema.brand();
15080
+ var hostTurnIdSchema = opaqueIdSchema.brand();
15081
+ var hostItemIdSchema = opaqueIdSchema.brand();
15082
+ var hostInteractionIdSchema = opaqueIdSchema.brand();
15083
+
15084
+ // ../../shared-contracts/dist/thread-prewarm.js
15085
+ var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
15086
+ var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
15087
+
15074
15088
  // ../../shared-contracts/dist/console.js
15075
15089
  var consoleAnnouncementSchema = external_exports.strictObject({
15076
15090
  title: external_exports.string().trim().min(1).max(200),
@@ -15083,6 +15097,9 @@ var consoleOpenResultSchema = external_exports.strictObject({
15083
15097
  url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
15084
15098
  });
15085
15099
  var CONSOLE_HOST_METHODS = Object.freeze([
15100
+ "codexhost/console/remote-connections",
15101
+ "codexhost/runtime/status",
15102
+ "codexhost/remote/ssh-setup",
15086
15103
  "codexhost/harness/plugins/list",
15087
15104
  "codexhost/harness/display-settings/get",
15088
15105
  "codexhost/harness/display-settings/set",
@@ -15149,16 +15166,6 @@ var loadedSessionsSchema = external_exports.array(external_exports.strictObject(
15149
15166
  inactiveMs: external_exports.number().nonnegative()
15150
15167
  }));
15151
15168
 
15152
- // ../../shared-contracts/dist/ids.js
15153
- var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
15154
- message: "Identifier must not be empty or whitespace"
15155
- });
15156
- var harnessIdSchema = opaqueIdSchema.brand();
15157
- var hostThreadIdSchema = opaqueIdSchema.brand();
15158
- var hostTurnIdSchema = opaqueIdSchema.brand();
15159
- var hostItemIdSchema = opaqueIdSchema.brand();
15160
- var hostInteractionIdSchema = opaqueIdSchema.brand();
15161
-
15162
15169
  // ../../shared-contracts/dist/manual-compaction.js
15163
15170
  var threadManualCompactionStartedSchema = external_exports.strictObject({
15164
15171
  threadId: hostThreadIdSchema,
@@ -16073,11 +16080,53 @@ var remoteSshSetupParamsSchema = external_exports.object({
16073
16080
  hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
16074
16081
  port: external_exports.number().int().min(1).max(65535).nullable(),
16075
16082
  identity: external_exports.string().max(4096).nullable(),
16076
- action: external_exports.enum(["inspect", "install", "update", "repair"]),
16083
+ action: external_exports.enum(["inspect", "install", "update", "repair", "uninstall"]),
16084
+ uninstallPackage: external_exports.boolean().optional(),
16077
16085
  version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
16078
16086
  }).strict();
16079
16087
  var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
16080
16088
 
16089
+ // ../../shared-contracts/dist/remote-connections.js
16090
+ var hostId = external_exports.string().min(1).max(1024);
16091
+ var codexSshConnectionSchema = external_exports.object({
16092
+ hostId,
16093
+ displayName: external_exports.string().min(1).max(1024),
16094
+ source: external_exports.enum(["codex-managed", "discovered"]),
16095
+ sshAlias: external_exports.string().max(1024).nullable(),
16096
+ sshHost: external_exports.string().min(1).max(1024),
16097
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
16098
+ identity: external_exports.string().max(4096).nullable(),
16099
+ autoConnect: external_exports.boolean(),
16100
+ connectionAnalyticsId: external_exports.string().max(1024).optional()
16101
+ });
16102
+ var codexSshDraftSchema = external_exports.strictObject({
16103
+ displayName: external_exports.string().min(1).max(1024),
16104
+ hostname: external_exports.string().min(1).max(1024),
16105
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
16106
+ identity: external_exports.string().max(4096).nullable()
16107
+ });
16108
+ var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
16109
+ external_exports.strictObject({ action: external_exports.literal("list") }),
16110
+ external_exports.strictObject({
16111
+ action: external_exports.literal("save"),
16112
+ draft: codexSshDraftSchema,
16113
+ previous: codexSshConnectionSchema.nullable()
16114
+ }),
16115
+ external_exports.strictObject({ action: external_exports.literal("remove"), previous: codexSshConnectionSchema }),
16116
+ external_exports.strictObject({ action: external_exports.literal("connect"), hostId, enabled: external_exports.boolean() }),
16117
+ external_exports.strictObject({ action: external_exports.literal("state"), hostId }),
16118
+ external_exports.strictObject({ action: external_exports.literal("runtime"), hostId }),
16119
+ external_exports.strictObject({
16120
+ action: external_exports.literal("update"),
16121
+ hostId: hostId.refine((id) => id !== "local"),
16122
+ version: remoteUpdateParamsSchema.shape.version
16123
+ })
16124
+ ]);
16125
+ var remoteConnectionsReplySchema = external_exports.union([
16126
+ external_exports.strictObject({ result: jsonValueSchema }),
16127
+ external_exports.strictObject({ error: external_exports.strictObject({ code: external_exports.number().int(), message: external_exports.string() }) })
16128
+ ]);
16129
+
16081
16130
  // ../../shared-contracts/dist/index.js
16082
16131
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
16083
16132
 
@@ -16420,6 +16469,44 @@ async function bounded(operation, milliseconds, label, onTimeout) {
16420
16469
  }
16421
16470
  }
16422
16471
 
16472
+ // dist/command.js
16473
+ var codeBuddyDiscoverySpec = {
16474
+ id: "codebuddy",
16475
+ command: "codebuddy",
16476
+ commandEnvironmentVariable: "CODEXHOST_CODEBUDDY_COMMAND",
16477
+ installRoots: {
16478
+ windows: ["${APPDATA}/npm", "~/.local/bin", VERSION_MANAGER_ROOTS],
16479
+ posix: [
16480
+ "~/.local/bin",
16481
+ "~/.npm-global/bin",
16482
+ VERSION_MANAGER_ROOTS,
16483
+ "/opt/homebrew/bin",
16484
+ "/usr/local/bin"
16485
+ ]
16486
+ }
16487
+ };
16488
+ function codeBuddyInvocation(environment, ephemeral, argumentsOverride) {
16489
+ const resolved = resolveHarnessExecutable(codeBuddyDiscoverySpec, { environment });
16490
+ if (!resolved)
16491
+ throw new CodeBuddyError("notInstalled", "CLI is not installed; run codebuddy and sign in first");
16492
+ const env = withNodeRuntimeOnPath(environment);
16493
+ return {
16494
+ ...commandInvocation(resolved.executable, argumentsOverride ?? [
16495
+ "--acp",
16496
+ ...ephemeral ? ["--no-session-persistence"] : [],
16497
+ ...!ephemeral && [
16498
+ "CODEXHOST_CLI_PATH",
16499
+ "CODEXHOST_RUNTIME_ENDPOINT",
16500
+ "CODEXHOST_RUNTIME_TOKEN",
16501
+ "CODEXHOST_THREAD_ID"
16502
+ ].every((key) => environment[key]) ? ["--append-system-prompt", CODEBUDDY_DELEGATION_INSTRUCTIONS] : []
16503
+ ], env),
16504
+ environment: env
16505
+ };
16506
+ }
16507
+ var CODEBUDDY_DELEGATION_INSTRUCTIONS = `This Session runs inside codexhost.
16508
+ When the user requests cross-Harness agent delegation, use the executable at the CODEXHOST_CLI_PATH environment variable through your native shell tool. Start with its --help and harness list commands, then use delegate start and thread send/read/wait/cancel as documented by the CLI. Pass --format compact when reporting results. Keep the inherited CODEXHOST_RUNTIME_ENDPOINT, CODEXHOST_RUNTIME_TOKEN and CODEXHOST_THREAD_ID environment variables for all such calls; they identify this Runtime and parent Thread. Do not print or expose their values, replace the configured executable, or start delegation unless the user's request authorizes it. Native CodeBuddy Agent subagents remain available for CodeBuddy-only work.`;
16509
+
16423
16510
  // dist/slash-commands.js
16424
16511
  var excluded = /* @__PURE__ */ new Set([
16425
16512
  "background",
@@ -20727,44 +20814,6 @@ var CodeBuddyCopyCleanup = class {
20727
20814
  }
20728
20815
  };
20729
20816
 
20730
- // dist/command.js
20731
- var codeBuddyDiscoverySpec = {
20732
- id: "codebuddy",
20733
- command: "codebuddy",
20734
- commandEnvironmentVariable: "CODEXHOST_CODEBUDDY_COMMAND",
20735
- installRoots: {
20736
- windows: ["${APPDATA}/npm", "~/.local/bin", VERSION_MANAGER_ROOTS],
20737
- posix: [
20738
- "~/.local/bin",
20739
- "~/.npm-global/bin",
20740
- VERSION_MANAGER_ROOTS,
20741
- "/opt/homebrew/bin",
20742
- "/usr/local/bin"
20743
- ]
20744
- }
20745
- };
20746
- function codeBuddyInvocation(environment, ephemeral, argumentsOverride) {
20747
- const resolved = resolveHarnessExecutable(codeBuddyDiscoverySpec, { environment });
20748
- if (!resolved)
20749
- throw new CodeBuddyError("notInstalled", "CLI is not installed; run codebuddy and sign in first");
20750
- const env = withNodeRuntimeOnPath(environment);
20751
- return {
20752
- ...commandInvocation(resolved.executable, argumentsOverride ?? [
20753
- "--acp",
20754
- ...ephemeral ? ["--no-session-persistence"] : [],
20755
- ...!ephemeral && [
20756
- "CODEXHOST_CLI_PATH",
20757
- "CODEXHOST_RUNTIME_ENDPOINT",
20758
- "CODEXHOST_RUNTIME_TOKEN",
20759
- "CODEXHOST_THREAD_ID"
20760
- ].every((key) => environment[key]) ? ["--append-system-prompt", CODEBUDDY_DELEGATION_INSTRUCTIONS] : []
20761
- ], env),
20762
- environment: env
20763
- };
20764
- }
20765
- var CODEBUDDY_DELEGATION_INSTRUCTIONS = `This Session runs inside codexhost.
20766
- When the user requests cross-Harness agent delegation, use the executable at the CODEXHOST_CLI_PATH environment variable through your native shell tool. Start with its --help and harness list commands, then use delegate start and thread send/read/wait/cancel as documented by the CLI. Pass --format compact when reporting results. Keep the inherited CODEXHOST_RUNTIME_ENDPOINT, CODEXHOST_RUNTIME_TOKEN and CODEXHOST_THREAD_ID environment variables for all such calls; they identify this Runtime and parent Thread. Do not print or expose their values, replace the configured executable, or start delegation unless the user's request authorizes it. Native CodeBuddy Agent subagents remain available for CodeBuddy-only work.`;
20767
-
20768
20817
  // dist/acp-client.js
20769
20818
  var CodeBuddyAcpClient = class {
20770
20819
  options;
@@ -24415,6 +24464,7 @@ function createCodeBuddyInstallation(environment) {
24415
24464
  }
24416
24465
 
24417
24466
  // ../../harness-broker/dist/client.js
24467
+ import { execFile as execFile4 } from "node:child_process";
24418
24468
  import { randomUUID as randomUUID2 } from "node:crypto";
24419
24469
  import { lstat as lstat3, readFile as readFile5 } from "node:fs/promises";
24420
24470
  import net, {} from "node:net";
@@ -24424,9 +24474,12 @@ var HARNESS_BROKER_PROTOCOL_VERSION = 1;
24424
24474
  var HARNESS_BROKER_MAX_FRAME_BYTES = 8 * 1024 * 1024;
24425
24475
  var HARNESS_BROKER_MAX_PENDING_REQUESTS = 32;
24426
24476
  var HARNESS_BROKER_REQUEST_TIMEOUT_MS = 15e3;
24477
+ var HARNESS_BROKER_IDLE_TIMEOUT_MS = 60 * 60 * 1e3;
24478
+ var HARNESS_BROKER_RETIRING_ERROR_CODE = "brokerRetiring";
24427
24479
  var harnessBrokerMethodSchema = external_exports.enum([
24428
24480
  "adapter.inspect",
24429
24481
  "adapter.inspectAccount",
24482
+ "adapter.credits",
24430
24483
  "adapter.open",
24431
24484
  "adapter.subagent.readSnapshot",
24432
24485
  "session.readSnapshot",
@@ -24544,6 +24597,14 @@ function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId
24544
24597
  return path9.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
24545
24598
  return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path9.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
24546
24599
  }
24600
+ function harnessBrokerLaunchAgentLabel(harnessId = "claude-code") {
24601
+ harnessPluginIdSchema.parse(harnessId);
24602
+ return harnessId === "claude-code" ? "ai.bytepioneer.codexhost.native-harness-broker" : `ai.bytepioneer.codexhost.${harnessId}-broker`;
24603
+ }
24604
+ function harnessBrokerLaunchAgentPlistPath(environment = process.env, harnessId = "claude-code") {
24605
+ const home = environment.HOME || os2.homedir();
24606
+ return path9.join(home, "Library", "LaunchAgents", `${harnessBrokerLaunchAgentLabel(harnessId)}.plist`);
24607
+ }
24547
24608
 
24548
24609
  // ../../harness-broker/dist/validation.js
24549
24610
  var cwdSchema = external_exports.string().min(1).max(16384);
@@ -24849,10 +24910,55 @@ async function readDescriptor(descriptorPath) {
24849
24910
  try {
24850
24911
  process.kill(descriptor.ownerPid, 0);
24851
24912
  } catch {
24852
- throw new Error("Aqua Harness broker owner process is unavailable");
24913
+ throw new BrokerNotRunningError("its owner process has exited");
24853
24914
  }
24854
24915
  return descriptor;
24855
24916
  }
24917
+ var BrokerNotRunningError = class extends Error {
24918
+ };
24919
+ var BrokerRetiringError = class extends Error {
24920
+ };
24921
+ var BrokerRequestNotDeliveredError = class extends Error {
24922
+ };
24923
+ var HarnessNotInstalledError = class extends Error {
24924
+ };
24925
+ var BROKER_NOT_RUNNING_CODES = /* @__PURE__ */ new Set(["ENOENT", "ECONNREFUSED"]);
24926
+ var BROKER_START_TIMEOUT_MS = 15e3;
24927
+ var BROKER_START_POLL_MS = 250;
24928
+ function classifyConnectFailure(error51) {
24929
+ if (error51 instanceof BrokerNotRunningError)
24930
+ return error51;
24931
+ const code = error51?.code;
24932
+ if (code && BROKER_NOT_RUNNING_CODES.has(code)) {
24933
+ return new BrokerNotRunningError(code === "ENOENT" ? "its descriptor or socket is missing" : "its socket refused the connection");
24934
+ }
24935
+ return error51 instanceof Error ? error51 : new Error(String(error51));
24936
+ }
24937
+ function describeBrokerFailure(error51, harnessId) {
24938
+ if (error51 instanceof BrokerNotRunningError) {
24939
+ 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}`;
24940
+ }
24941
+ return error51 instanceof Error ? error51.message : String(error51);
24942
+ }
24943
+ function runLaunchctl(arguments_) {
24944
+ return new Promise((resolve) => {
24945
+ execFile4("/bin/launchctl", arguments_, { timeout: 1e4 }, (error51) => resolve(!error51));
24946
+ });
24947
+ }
24948
+ async function startBrokerLaunchAgent(harnessId, environment) {
24949
+ const uid = process.getuid?.();
24950
+ if (uid === void 0)
24951
+ return;
24952
+ const target = `gui/${uid}/${harnessBrokerLaunchAgentLabel(harnessId)}`;
24953
+ if (await runLaunchctl(["kickstart", target]))
24954
+ return;
24955
+ await runLaunchctl([
24956
+ "bootstrap",
24957
+ `gui/${uid}`,
24958
+ harnessBrokerLaunchAgentPlistPath(environment, harnessId)
24959
+ ]);
24960
+ await runLaunchctl(["kickstart", target]);
24961
+ }
24856
24962
  var BrokerConnection = class _BrokerConnection {
24857
24963
  #onClose;
24858
24964
  onClose(callback) {
@@ -24876,21 +24982,31 @@ var BrokerConnection = class _BrokerConnection {
24876
24982
  socket.once("error", (error51) => this.#fail(error51));
24877
24983
  }
24878
24984
  static async connect(descriptorPath, harnessId) {
24879
- const descriptor = await readDescriptor(descriptorPath);
24880
- if (descriptor.harnessId !== harnessId)
24881
- throw new Error("Aqua broker belongs to another Harness");
24882
- const socket = net.createConnection(descriptor.socketPath);
24883
- await new Promise((resolve, reject) => {
24884
- const timeout = setTimeout(() => reject(new Error("Timed out connecting to Aqua Harness broker")), HARNESS_BROKER_REQUEST_TIMEOUT_MS);
24885
- socket.once("connect", () => {
24886
- clearTimeout(timeout);
24887
- resolve();
24888
- });
24889
- socket.once("error", (error51) => {
24890
- clearTimeout(timeout);
24891
- reject(error51);
24985
+ let descriptor;
24986
+ let socket;
24987
+ let connecting;
24988
+ try {
24989
+ descriptor = await readDescriptor(descriptorPath);
24990
+ if (descriptor.harnessId !== harnessId)
24991
+ throw new Error("Aqua broker belongs to another Harness");
24992
+ connecting = net.createConnection(descriptor.socketPath);
24993
+ const pending = connecting;
24994
+ await new Promise((resolve, reject) => {
24995
+ const timeout = setTimeout(() => reject(new Error("Timed out connecting to Aqua Harness broker")), HARNESS_BROKER_REQUEST_TIMEOUT_MS);
24996
+ pending.once("connect", () => {
24997
+ clearTimeout(timeout);
24998
+ resolve();
24999
+ });
25000
+ pending.once("error", (error51) => {
25001
+ clearTimeout(timeout);
25002
+ reject(error51);
25003
+ });
24892
25004
  });
24893
- });
25005
+ socket = pending;
25006
+ } catch (error51) {
25007
+ connecting?.destroy();
25008
+ throw classifyConnectFailure(error51);
25009
+ }
24894
25010
  const connection = new _BrokerConnection(descriptor, socket);
24895
25011
  const hello = connection.#waitForHello();
24896
25012
  await writeBrokerFrame(socket, {
@@ -24943,15 +25059,24 @@ var BrokerConnection = class _BrokerConnection {
24943
25059
  }, HARNESS_BROKER_REQUEST_TIMEOUT_MS);
24944
25060
  this.#pending.set(id, { resolve, reject, timeout });
24945
25061
  });
24946
- await writeBrokerFrame(this.#socket, {
24947
- version: HARNESS_BROKER_PROTOCOL_VERSION,
24948
- generation: this.#descriptor.generation,
24949
- sequence: this.#inputSequence,
24950
- kind: "request",
24951
- id,
24952
- method,
24953
- params
24954
- });
25062
+ try {
25063
+ await writeBrokerFrame(this.#socket, {
25064
+ version: HARNESS_BROKER_PROTOCOL_VERSION,
25065
+ generation: this.#descriptor.generation,
25066
+ sequence: this.#inputSequence,
25067
+ kind: "request",
25068
+ id,
25069
+ method,
25070
+ params
25071
+ });
25072
+ } catch (error51) {
25073
+ const pending = this.#pending.get(id);
25074
+ if (pending)
25075
+ clearTimeout(pending.timeout);
25076
+ this.#pending.delete(id);
25077
+ response.catch(() => void 0);
25078
+ throw new BrokerRequestNotDeliveredError(error51 instanceof Error ? error51.message : String(error51));
25079
+ }
24955
25080
  return response;
24956
25081
  }
24957
25082
  close() {
@@ -24995,6 +25120,8 @@ var BrokerConnection = class _BrokerConnection {
24995
25120
  this.#pending.delete(frame.id);
24996
25121
  if (frame.ok)
24997
25122
  pending.resolve(frame.value);
25123
+ else if (frame.error?.code === HARNESS_BROKER_RETIRING_ERROR_CODE)
25124
+ pending.reject(new BrokerRetiringError(frame.error.message));
24998
25125
  else
24999
25126
  pending.reject(new Error(frame.error?.message ?? "Broker request failed"));
25000
25127
  }
@@ -25220,17 +25347,19 @@ var BrokeredHarnessAdapter = class {
25220
25347
  harnessId;
25221
25348
  #descriptorPath;
25222
25349
  #forwardEnvironment;
25350
+ #isInstalled;
25351
+ #startBroker;
25352
+ #startTimeoutMs;
25223
25353
  #connection = null;
25224
25354
  #closed = false;
25355
+ #credits = null;
25356
+ #creditsRefresh = null;
25225
25357
  subagents = {
25226
25358
  readSnapshot: async (input) => {
25227
25359
  try {
25228
- return parseHarnessResult(await (await this.#connect()).request("adapter.subagent.readSnapshot", input));
25360
+ return parseHarnessResult(await this.#request("adapter.subagent.readSnapshot", input));
25229
25361
  } catch (error51) {
25230
- return {
25231
- ok: false,
25232
- error: unavailable(error51 instanceof Error ? error51.message : String(error51))
25233
- };
25362
+ return { ok: false, error: this.#error(error51) };
25234
25363
  }
25235
25364
  }
25236
25365
  };
@@ -25242,12 +25371,39 @@ var BrokeredHarnessAdapter = class {
25242
25371
  if (input.liveCommandCatalog)
25243
25372
  this.liveCommandCatalog = true;
25244
25373
  this.#descriptorPath = input.descriptorPath ?? defaultHarnessBrokerDescriptorPath(input.environment, this.harnessId);
25374
+ this.#isInstalled = input.isInstalled;
25375
+ const environment = input.environment ?? process.env;
25376
+ this.#startBroker = input.startBroker === false ? void 0 : input.startBroker ?? (process.platform === "darwin" && !input.descriptorPath ? () => startBrokerLaunchAgent(this.harnessId, environment) : void 0);
25377
+ this.#startTimeoutMs = input.startTimeoutMs ?? BROKER_START_TIMEOUT_MS;
25378
+ }
25379
+ credits() {
25380
+ return this.#credits;
25381
+ }
25382
+ refreshCredits() {
25383
+ if (this.#closed)
25384
+ return Promise.resolve(null);
25385
+ if (this.#creditsRefresh)
25386
+ return this.#creditsRefresh;
25387
+ this.#creditsRefresh = this.#readCredits().finally(() => {
25388
+ this.#creditsRefresh = null;
25389
+ });
25390
+ return this.#creditsRefresh;
25391
+ }
25392
+ async #readCredits() {
25393
+ try {
25394
+ const value = await this.#request("adapter.credits", {}, true);
25395
+ const credits = accountCreditsSnapshotSchema.nullable().parse(value);
25396
+ if (!this.#closed)
25397
+ this.#credits = credits;
25398
+ } catch {
25399
+ }
25400
+ return this.#credits;
25245
25401
  }
25246
25402
  async inspectAccount() {
25247
25403
  if (this.#closed)
25248
25404
  return null;
25249
25405
  try {
25250
- const value = await (await this.#connect()).request("adapter.inspectAccount", {});
25406
+ const value = await this.#request("adapter.inspectAccount", {}, true);
25251
25407
  return harnessAccountSnapshotSchema.nullable().parse(value);
25252
25408
  } catch {
25253
25409
  return null;
@@ -25257,33 +25413,46 @@ var BrokeredHarnessAdapter = class {
25257
25413
  if (this.#closed)
25258
25414
  return failedInspection("Aqua Harness broker adapter is closed");
25259
25415
  try {
25260
- return harnessInspectionSchema.parse(await (await this.#connect()).request("adapter.inspect", input));
25416
+ return harnessInspectionSchema.parse(await this.#request("adapter.inspect", input, true));
25261
25417
  } catch (error51) {
25262
25418
  this.#connection = null;
25263
- return failedInspection(error51 instanceof Error ? error51.message : String(error51));
25419
+ if (error51 instanceof HarnessNotInstalledError)
25420
+ return { status: "notInstalled", error: this.#error(error51) };
25421
+ return failedInspection(describeBrokerFailure(error51, this.harnessId));
25264
25422
  }
25265
25423
  }
25266
25424
  async open(input) {
25267
25425
  if (this.#closed)
25268
25426
  return { ok: false, error: unavailable("Aqua Harness broker adapter is closed", false) };
25427
+ const safeInput = { ...input };
25428
+ delete safeInput.environment;
25429
+ if (this.#forwardEnvironment && input.environment) {
25430
+ const allowed = [
25431
+ "CODEXHOST_CLI_PATH",
25432
+ "CODEXHOST_CLI_NODE_PATH",
25433
+ "CODEXHOST_RUNTIME_ENDPOINT",
25434
+ "CODEXHOST_RUNTIME_TOKEN",
25435
+ "CODEXHOST_THREAD_ID"
25436
+ ];
25437
+ const environment = Object.fromEntries(Object.entries(input.environment).filter(([key, value]) => allowed.includes(key) && value !== void 0));
25438
+ if (Object.keys(environment).length)
25439
+ safeInput.environment = environment;
25440
+ }
25269
25441
  let connection;
25270
25442
  try {
25271
- const safeInput = { ...input };
25272
- delete safeInput.environment;
25273
- if (this.#forwardEnvironment && input.environment) {
25274
- const allowed = [
25275
- "CODEXHOST_CLI_PATH",
25276
- "CODEXHOST_CLI_NODE_PATH",
25277
- "CODEXHOST_RUNTIME_ENDPOINT",
25278
- "CODEXHOST_RUNTIME_TOKEN",
25279
- "CODEXHOST_THREAD_ID"
25280
- ];
25281
- const environment = Object.fromEntries(Object.entries(input.environment).filter(([key, value]) => allowed.includes(key) && value !== void 0));
25282
- if (Object.keys(environment).length)
25283
- safeInput.environment = environment;
25284
- }
25285
- connection = await this.#connect();
25286
- const result = parseHarnessResult(await connection.request("adapter.open", safeInput));
25443
+ let value;
25444
+ for (let attempt = 0; ; attempt += 1) {
25445
+ connection = await this.#connect();
25446
+ try {
25447
+ value = await connection.request("adapter.open", safeInput);
25448
+ break;
25449
+ } catch (error51) {
25450
+ if (attempt > 0 || !(error51 instanceof BrokerRetiringError || error51 instanceof BrokerRequestNotDeliveredError))
25451
+ throw error51;
25452
+ this.#connection = null;
25453
+ }
25454
+ }
25455
+ const result = parseHarnessResult(value);
25287
25456
  if (!result.ok)
25288
25457
  return result;
25289
25458
  const session = new BrokeredHarnessSession(connection, parseSessionMetadata(result.value), this.harnessId, safeInput, () => this.#connect(), () => {
@@ -25294,25 +25463,51 @@ var BrokeredHarnessAdapter = class {
25294
25463
  } catch (error51) {
25295
25464
  connection?.close();
25296
25465
  this.#connection = null;
25297
- return {
25298
- ok: false,
25299
- error: unavailable(error51 instanceof Error ? error51.message : String(error51))
25300
- };
25466
+ return { ok: false, error: this.#error(error51) };
25301
25467
  }
25302
25468
  }
25303
25469
  async close() {
25304
25470
  this.#closed = true;
25471
+ this.#credits = null;
25305
25472
  await Promise.allSettled([...this.#sessions].map((session) => session.close()));
25306
25473
  this.#sessions.clear();
25307
25474
  const connection = await this.#connection?.catch(() => null);
25308
25475
  await connection?.dispose();
25309
25476
  this.#connection = null;
25310
25477
  }
25478
+ #error(error51) {
25479
+ if (error51 instanceof HarnessNotInstalledError)
25480
+ return {
25481
+ code: "notInstalled",
25482
+ message: error51.message,
25483
+ retryable: false,
25484
+ stage: "harnessBroker"
25485
+ };
25486
+ return unavailable(describeBrokerFailure(error51, this.harnessId));
25487
+ }
25488
+ /**
25489
+ * Sends one adapter-level request. A broker that retired between requests refuses it
25490
+ * unprocessed, so it is retried once on a fresh broker. Idempotent reads also retry
25491
+ * once after a plain disconnect.
25492
+ */
25493
+ async #request(method, params, idempotent = false) {
25494
+ for (let attempt = 0; ; attempt += 1) {
25495
+ const connection = await this.#connect();
25496
+ try {
25497
+ return await connection.request(method, params);
25498
+ } catch (error51) {
25499
+ const retryable = error51 instanceof BrokerRetiringError || error51 instanceof BrokerRequestNotDeliveredError || idempotent && connection.closed;
25500
+ if (attempt > 0 || !retryable)
25501
+ throw error51;
25502
+ this.#connection = null;
25503
+ }
25504
+ }
25505
+ }
25311
25506
  #connect() {
25312
25507
  if (this.#closed)
25313
25508
  return Promise.reject(new Error("Aqua Harness broker adapter is closed"));
25314
25509
  if (!this.#connection) {
25315
- const pending = BrokerConnection.connect(this.#descriptorPath, this.harnessId).then((connection) => {
25510
+ const pending = this.#establish().then((connection) => {
25316
25511
  connection.onClose(() => {
25317
25512
  if (this.#connection === pending)
25318
25513
  this.#connection = null;
@@ -25327,18 +25522,43 @@ var BrokeredHarnessAdapter = class {
25327
25522
  }
25328
25523
  return this.#connection;
25329
25524
  }
25525
+ async #establish() {
25526
+ try {
25527
+ return await BrokerConnection.connect(this.#descriptorPath, this.harnessId);
25528
+ } catch (error51) {
25529
+ if (!(error51 instanceof BrokerNotRunningError) || !this.#startBroker)
25530
+ throw error51;
25531
+ }
25532
+ if (this.#isInstalled && !this.#isInstalled()) {
25533
+ throw new HarnessNotInstalledError(`${this.harnessId} is not installed on this Mac`);
25534
+ }
25535
+ const deadline = Date.now() + this.#startTimeoutMs;
25536
+ for (; ; ) {
25537
+ await this.#startBroker();
25538
+ try {
25539
+ return await BrokerConnection.connect(this.#descriptorPath, this.harnessId);
25540
+ } catch (error51) {
25541
+ if (!(error51 instanceof BrokerNotRunningError) || Date.now() >= deadline)
25542
+ throw error51;
25543
+ }
25544
+ await new Promise((resolve) => setTimeout(resolve, BROKER_START_POLL_MS));
25545
+ }
25546
+ }
25330
25547
  };
25331
25548
 
25332
25549
  // dist/plugin.js
25333
25550
  function createHarnessAdapter(context) {
25334
- if (context.platform === "darwin" && context.managedRemoteHost)
25551
+ if (context.platform === "darwin" && context.managedRemoteHost) {
25552
+ const environment2 = { ...context.environment };
25335
25553
  return new BrokeredHarnessAdapter({
25336
25554
  harnessId: "codebuddy",
25337
25555
  forwardDelegationEnvironment: true,
25338
25556
  commandCatalog: CODEBUDDY_COMMAND_CATALOG,
25339
25557
  liveCommandCatalog: true,
25340
- environment: { ...context.environment }
25558
+ environment: environment2,
25559
+ isInstalled: () => resolveHarnessExecutable(codeBuddyDiscoverySpec, { environment: environment2 }) !== void 0
25341
25560
  });
25561
+ }
25342
25562
  const environment = { ...context.environment };
25343
25563
  return Object.assign(new CodeBuddyAdapter({ environment }), {
25344
25564
  installation: createCodeBuddyInstallation(environment),