@codexhost/cli-win32-arm64 0.11.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,10 +14621,14 @@ 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",
14612
14630
  "codexhost/harness/inspect",
14631
+ "codexhost/harness/installation",
14613
14632
  "codexhost/harness/launch-settings/get",
14614
14633
  "codexhost/harness/launch-settings/set",
14615
14634
  "codexhost/harness/web-ui/open",
@@ -14671,16 +14690,6 @@ var loadedSessionsSchema = external_exports.array(external_exports.strictObject(
14671
14690
  inactiveMs: external_exports.number().nonnegative()
14672
14691
  }));
14673
14692
 
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
14693
  // ../../shared-contracts/dist/manual-compaction.js
14685
14694
  var threadManualCompactionStartedSchema = external_exports.strictObject({
14686
14695
  threadId: hostThreadIdSchema,
@@ -15256,14 +15265,17 @@ var harnessLaunchSettingsSchema = external_exports.object({
15256
15265
  // ../../shared-contracts/dist/harness-installation.js
15257
15266
  var harnessInstallationParamsSchema = external_exports.object({
15258
15267
  harnessId: harnessIdSchema,
15259
- action: external_exports.enum(["check", "update"])
15268
+ action: external_exports.enum(["check", "update", "install"])
15260
15269
  }).strict();
15261
15270
  var harnessInstallationStateSchema = external_exports.object({
15262
15271
  currentVersion: external_exports.string().min(1).max(128),
15263
15272
  latestVersion: external_exports.string().min(1).max(128),
15264
15273
  updateAvailable: external_exports.boolean(),
15265
15274
  canUpdate: external_exports.boolean(),
15266
- message: external_exports.string().max(2048).optional()
15275
+ // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15276
+ message: external_exports.string().max(2048).optional(),
15277
+ messageCode: external_exports.string().min(1).max(128).optional(),
15278
+ latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15267
15279
  }).strict();
15268
15280
 
15269
15281
  // ../../shared-contracts/dist/codex-accounts.js
@@ -15565,6 +15577,80 @@ var updateStatusResultSchema = external_exports.strictObject({
15565
15577
  status: updateStatusSchema.nullable()
15566
15578
  });
15567
15579
 
15580
+ // ../../shared-contracts/dist/remote-runtime.js
15581
+ var remoteUpdatePhaseSchema = external_exports.enum([
15582
+ "idle",
15583
+ "installing",
15584
+ "restarting",
15585
+ "succeeded",
15586
+ "failed"
15587
+ ]);
15588
+ var runtimeStatusSchema = external_exports.object({
15589
+ runningVersion: external_exports.string().nullable(),
15590
+ installedVersion: external_exports.string().nullable(),
15591
+ restartRequired: external_exports.boolean(),
15592
+ remote: external_exports.boolean(),
15593
+ updateSupported: external_exports.boolean(),
15594
+ update: external_exports.object({
15595
+ phase: remoteUpdatePhaseSchema,
15596
+ targetVersion: external_exports.string().nullable(),
15597
+ error: external_exports.string().nullable()
15598
+ })
15599
+ });
15600
+ var remoteUpdateParamsSchema = external_exports.object({
15601
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
15602
+ }).strict();
15603
+ var remoteSshSetupParamsSchema = external_exports.object({
15604
+ hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
15605
+ port: external_exports.number().int().min(1).max(65535).nullable(),
15606
+ identity: external_exports.string().max(4096).nullable(),
15607
+ action: external_exports.enum(["inspect", "install", "update", "repair", "uninstall"]),
15608
+ uninstallPackage: external_exports.boolean().optional(),
15609
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
15610
+ }).strict();
15611
+ var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
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
+
15568
15654
  // ../../shared-contracts/dist/index.js
15569
15655
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15570
15656
 
@@ -15883,9 +15969,12 @@ var HARNESS_BROKER_PROTOCOL_VERSION = 1;
15883
15969
  var HARNESS_BROKER_MAX_FRAME_BYTES = 8 * 1024 * 1024;
15884
15970
  var HARNESS_BROKER_MAX_PENDING_REQUESTS = 32;
15885
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";
15886
15974
  var harnessBrokerMethodSchema = external_exports.enum([
15887
15975
  "adapter.inspect",
15888
15976
  "adapter.inspectAccount",
15977
+ "adapter.credits",
15889
15978
  "adapter.open",
15890
15979
  "adapter.subagent.readSnapshot",
15891
15980
  "session.readSnapshot",
@@ -16003,6 +16092,14 @@ function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId
16003
16092
  return path.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
16004
16093
  return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
16005
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
+ }
16006
16103
 
16007
16104
  // ../../harness-broker/dist/validation.js
16008
16105
  var cwdSchema = external_exports.string().min(1).max(16384);
@@ -16308,10 +16405,55 @@ async function readDescriptor(descriptorPath) {
16308
16405
  try {
16309
16406
  process.kill(descriptor.ownerPid, 0);
16310
16407
  } catch {
16311
- throw new Error("Aqua Harness broker owner process is unavailable");
16408
+ throw new BrokerNotRunningError("its owner process has exited");
16312
16409
  }
16313
16410
  return descriptor;
16314
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
+ }
16315
16457
  var BrokerConnection = class _BrokerConnection {
16316
16458
  #onClose;
16317
16459
  onClose(callback) {
@@ -16335,21 +16477,31 @@ var BrokerConnection = class _BrokerConnection {
16335
16477
  socket.once("error", (error52) => this.#fail(error52));
16336
16478
  }
16337
16479
  static async connect(descriptorPath, harnessId) {
16338
- const descriptor = await readDescriptor(descriptorPath);
16339
- if (descriptor.harnessId !== harnessId)
16340
- throw new Error("Aqua broker belongs to another Harness");
16341
- const socket = net.createConnection(descriptor.socketPath);
16342
- await new Promise((resolve2, reject) => {
16343
- const timeout = setTimeout(() => reject(new Error("Timed out connecting to Aqua Harness broker")), HARNESS_BROKER_REQUEST_TIMEOUT_MS);
16344
- socket.once("connect", () => {
16345
- clearTimeout(timeout);
16346
- resolve2();
16347
- });
16348
- socket.once("error", (error52) => {
16349
- clearTimeout(timeout);
16350
- 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
+ });
16351
16499
  });
16352
- });
16500
+ socket = pending;
16501
+ } catch (error52) {
16502
+ connecting?.destroy();
16503
+ throw classifyConnectFailure(error52);
16504
+ }
16353
16505
  const connection = new _BrokerConnection(descriptor, socket);
16354
16506
  const hello = connection.#waitForHello();
16355
16507
  await writeBrokerFrame(socket, {
@@ -16402,15 +16554,24 @@ var BrokerConnection = class _BrokerConnection {
16402
16554
  }, HARNESS_BROKER_REQUEST_TIMEOUT_MS);
16403
16555
  this.#pending.set(id, { resolve: resolve2, reject, timeout });
16404
16556
  });
16405
- await writeBrokerFrame(this.#socket, {
16406
- version: HARNESS_BROKER_PROTOCOL_VERSION,
16407
- generation: this.#descriptor.generation,
16408
- sequence: this.#inputSequence,
16409
- kind: "request",
16410
- id,
16411
- method,
16412
- params
16413
- });
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
+ }
16414
16575
  return response;
16415
16576
  }
16416
16577
  close() {
@@ -16454,6 +16615,8 @@ var BrokerConnection = class _BrokerConnection {
16454
16615
  this.#pending.delete(frame.id);
16455
16616
  if (frame.ok)
16456
16617
  pending.resolve(frame.value);
16618
+ else if (frame.error?.code === HARNESS_BROKER_RETIRING_ERROR_CODE)
16619
+ pending.reject(new BrokerRetiringError(frame.error.message));
16457
16620
  else
16458
16621
  pending.reject(new Error(frame.error?.message ?? "Broker request failed"));
16459
16622
  }
@@ -16679,17 +16842,19 @@ var BrokeredHarnessAdapter = class {
16679
16842
  harnessId;
16680
16843
  #descriptorPath;
16681
16844
  #forwardEnvironment;
16845
+ #isInstalled;
16846
+ #startBroker;
16847
+ #startTimeoutMs;
16682
16848
  #connection = null;
16683
16849
  #closed = false;
16850
+ #credits = null;
16851
+ #creditsRefresh = null;
16684
16852
  subagents = {
16685
16853
  readSnapshot: async (input) => {
16686
16854
  try {
16687
- return parseHarnessResult(await (await this.#connect()).request("adapter.subagent.readSnapshot", input));
16855
+ return parseHarnessResult(await this.#request("adapter.subagent.readSnapshot", input));
16688
16856
  } catch (error52) {
16689
- return {
16690
- ok: false,
16691
- error: unavailable(error52 instanceof Error ? error52.message : String(error52))
16692
- };
16857
+ return { ok: false, error: this.#error(error52) };
16693
16858
  }
16694
16859
  }
16695
16860
  };
@@ -16701,12 +16866,39 @@ var BrokeredHarnessAdapter = class {
16701
16866
  if (input.liveCommandCatalog)
16702
16867
  this.liveCommandCatalog = true;
16703
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;
16704
16896
  }
16705
16897
  async inspectAccount() {
16706
16898
  if (this.#closed)
16707
16899
  return null;
16708
16900
  try {
16709
- const value = await (await this.#connect()).request("adapter.inspectAccount", {});
16901
+ const value = await this.#request("adapter.inspectAccount", {}, true);
16710
16902
  return harnessAccountSnapshotSchema.nullable().parse(value);
16711
16903
  } catch {
16712
16904
  return null;
@@ -16716,33 +16908,46 @@ var BrokeredHarnessAdapter = class {
16716
16908
  if (this.#closed)
16717
16909
  return failedInspection("Aqua Harness broker adapter is closed");
16718
16910
  try {
16719
- return harnessInspectionSchema.parse(await (await this.#connect()).request("adapter.inspect", input));
16911
+ return harnessInspectionSchema.parse(await this.#request("adapter.inspect", input, true));
16720
16912
  } catch (error52) {
16721
16913
  this.#connection = null;
16722
- 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));
16723
16917
  }
16724
16918
  }
16725
16919
  async open(input) {
16726
16920
  if (this.#closed)
16727
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
+ }
16728
16936
  let connection;
16729
16937
  try {
16730
- const safeInput = { ...input };
16731
- delete safeInput.environment;
16732
- if (this.#forwardEnvironment && input.environment) {
16733
- const allowed2 = [
16734
- "CODEXHOST_CLI_PATH",
16735
- "CODEXHOST_CLI_NODE_PATH",
16736
- "CODEXHOST_RUNTIME_ENDPOINT",
16737
- "CODEXHOST_RUNTIME_TOKEN",
16738
- "CODEXHOST_THREAD_ID"
16739
- ];
16740
- const environment = Object.fromEntries(Object.entries(input.environment).filter(([key, value]) => allowed2.includes(key) && value !== void 0));
16741
- if (Object.keys(environment).length)
16742
- safeInput.environment = environment;
16743
- }
16744
- connection = await this.#connect();
16745
- 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);
16746
16951
  if (!result.ok)
16747
16952
  return result;
16748
16953
  const session = new BrokeredHarnessSession(connection, parseSessionMetadata(result.value), this.harnessId, safeInput, () => this.#connect(), () => {
@@ -16753,25 +16958,51 @@ var BrokeredHarnessAdapter = class {
16753
16958
  } catch (error52) {
16754
16959
  connection?.close();
16755
16960
  this.#connection = null;
16756
- return {
16757
- ok: false,
16758
- error: unavailable(error52 instanceof Error ? error52.message : String(error52))
16759
- };
16961
+ return { ok: false, error: this.#error(error52) };
16760
16962
  }
16761
16963
  }
16762
16964
  async close() {
16763
16965
  this.#closed = true;
16966
+ this.#credits = null;
16764
16967
  await Promise.allSettled([...this.#sessions].map((session) => session.close()));
16765
16968
  this.#sessions.clear();
16766
16969
  const connection = await this.#connection?.catch(() => null);
16767
16970
  await connection?.dispose();
16768
16971
  this.#connection = null;
16769
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
+ }
16770
17001
  #connect() {
16771
17002
  if (this.#closed)
16772
17003
  return Promise.reject(new Error("Aqua Harness broker adapter is closed"));
16773
17004
  if (!this.#connection) {
16774
- const pending = BrokerConnection.connect(this.#descriptorPath, this.harnessId).then((connection) => {
17005
+ const pending = this.#establish().then((connection) => {
16775
17006
  connection.onClose(() => {
16776
17007
  if (this.#connection === pending)
16777
17008
  this.#connection = null;
@@ -16786,6 +17017,28 @@ var BrokeredHarnessAdapter = class {
16786
17017
  }
16787
17018
  return this.#connection;
16788
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
+ }
16789
17042
  };
16790
17043
 
16791
17044
  // dist/claude-code-adapter.js
@@ -42487,32 +42740,109 @@ import { opendir, realpath, stat } from "node:fs/promises";
42487
42740
  import os2 from "node:os";
42488
42741
  import path2 from "node:path";
42489
42742
  import { createInterface } from "node:readline";
42490
- var CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH = 120;
42491
- var CLAUDE_INTERNAL_USER_TEXT = /^<(?:local-command-|command-)/u;
42492
- var ClaudeSessionChangedError = class extends Error {
42493
- constructor() {
42494
- super("Claude Code Session changed during discovery; refresh and retry");
42743
+
42744
+ // ../../harness-adapter/dist/session-import.js
42745
+ var SessionImportChangedError = class extends Error {
42746
+ constructor(message = "Native Session changed during discovery; refresh and retry") {
42747
+ super(message);
42748
+ this.name = "SessionImportChangedError";
42495
42749
  }
42496
42750
  };
42497
- function isRecord2(value) {
42498
- return typeof value === "object" && value !== null && !Array.isArray(value);
42499
- }
42500
- function missing(error52) {
42501
- return isRecord2(error52) && error52.code === "ENOENT";
42751
+ function isMissingFileError(error52) {
42752
+ return typeof error52 === "object" && error52 !== null && "code" in error52 && error52.code === "ENOENT";
42502
42753
  }
42503
- function sameFile(left, right) {
42504
- return left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs && left.ino === right.ino && left.dev === right.dev;
42754
+ function sameFileFingerprint(left, right) {
42755
+ return left === null || right === null ? left === right : left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
42505
42756
  }
42506
- function cleanText(value) {
42757
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
42507
42758
  if (typeof value !== "string")
42508
42759
  return null;
42509
42760
  const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
42510
42761
  if (!normalized)
42511
42762
  return null;
42763
+ if (normalized.length <= maxLength)
42764
+ return normalized;
42512
42765
  const characters = [...normalized];
42513
- if (characters.length <= CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH)
42766
+ if (characters.length <= maxLength)
42514
42767
  return normalized;
42515
- return `${characters.slice(0, CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH - 1).join("").trimEnd()}…`;
42768
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
42769
+ }
42770
+ function sessionImportCandidate(input) {
42771
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
42772
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
42773
+ nativeSessionId: input.nativeSessionId,
42774
+ cwd: input.cwd,
42775
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
42776
+ updatedAt: Math.floor(time3),
42777
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
42778
+ running: typeof input.running === "boolean" ? input.running : null
42779
+ });
42780
+ return parsed.success ? parsed.data : null;
42781
+ }
42782
+ var SessionImportScope = class {
42783
+ #abort = new AbortController();
42784
+ #options;
42785
+ #pending = /* @__PURE__ */ new Set();
42786
+ constructor(options) {
42787
+ this.#options = options;
42788
+ }
42789
+ #closed() {
42790
+ return {
42791
+ ok: false,
42792
+ error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
42793
+ };
42794
+ }
42795
+ read(operation) {
42796
+ const signal = this.#abort.signal;
42797
+ if (signal.aborted)
42798
+ return Promise.resolve(this.#closed());
42799
+ let started;
42800
+ try {
42801
+ started = operation(signal);
42802
+ } catch (error52) {
42803
+ started = Promise.reject(error52 instanceof Error ? error52 : new Error("Session read failed"));
42804
+ }
42805
+ const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
42806
+ ok: false,
42807
+ error: {
42808
+ code: "unavailable",
42809
+ message: this.#options.unavailableMessage,
42810
+ retryable: true
42811
+ }
42812
+ }).finally(() => this.#pending.delete(request));
42813
+ this.#pending.add(request);
42814
+ return request;
42815
+ }
42816
+ /** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
42817
+ async resolve(operation) {
42818
+ const result = await this.read(operation);
42819
+ if (!result.ok)
42820
+ return result;
42821
+ return result.value ? { ok: true, value: result.value } : {
42822
+ ok: false,
42823
+ error: {
42824
+ code: "sessionNotFound",
42825
+ message: this.#options.notFoundMessage,
42826
+ retryable: false
42827
+ }
42828
+ };
42829
+ }
42830
+ /** Idempotent. Resolves after every started read has settled. */
42831
+ async close() {
42832
+ this.#abort.abort();
42833
+ await Promise.allSettled(this.#pending);
42834
+ }
42835
+ };
42836
+
42837
+ // dist/claude-session-import.js
42838
+ var CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH = 120;
42839
+ var CLAUDE_INTERNAL_USER_TEXT = /^<(?:local-command-|command-)/u;
42840
+ var CLAUDE_SESSION_CHANGED = "Claude Code Session changed during discovery; refresh and retry";
42841
+ function isRecord2(value) {
42842
+ return typeof value === "object" && value !== null && !Array.isArray(value);
42843
+ }
42844
+ function cleanText(value) {
42845
+ return sessionImportTitle(value, CLAUDE_SESSION_IMPORT_TITLE_MAX_LENGTH);
42516
42846
  }
42517
42847
  function userText(message) {
42518
42848
  if (!isRecord2(message) || message.role !== "user")
@@ -42528,7 +42858,7 @@ function claudeProjectsDirectory(environment) {
42528
42858
  async function sessionFiles(directory, signal) {
42529
42859
  signal.throwIfAborted();
42530
42860
  const projects = await opendir(directory).catch((error52) => {
42531
- if (missing(error52))
42861
+ if (isMissingFileError(error52))
42532
42862
  return null;
42533
42863
  throw error52;
42534
42864
  });
@@ -42540,7 +42870,7 @@ async function sessionFiles(directory, signal) {
42540
42870
  if (!project.isDirectory())
42541
42871
  continue;
42542
42872
  const entries = await opendir(path2.join(directory, project.name)).catch((error52) => {
42543
- if (missing(error52))
42873
+ if (isMissingFileError(error52))
42544
42874
  return null;
42545
42875
  throw error52;
42546
42876
  });
@@ -42607,24 +42937,23 @@ async function readCandidate(file2, signal) {
42607
42937
  if (!hasConversation || !cwd)
42608
42938
  return null;
42609
42939
  const after = await stat(file2);
42610
- if (!sameFile(before, after))
42611
- throw new ClaudeSessionChangedError();
42940
+ if (!sameFileFingerprint(before, after))
42941
+ throw new SessionImportChangedError(CLAUDE_SESSION_CHANGED);
42612
42942
  const resolvedCwd = await realpath(cwd);
42613
42943
  if (!(await stat(resolvedCwd)).isDirectory())
42614
42944
  return null;
42615
- const candidate = harnessSessionImportCandidateSchema.safeParse({
42945
+ const candidate = sessionImportCandidate({
42616
42946
  nativeSessionId,
42617
42947
  title: customTitle ?? generatedTitle ?? firstPrompt,
42618
- updatedAt: Math.floor(before.mtimeMs),
42619
- cwd: resolvedCwd,
42620
- running: null
42948
+ updatedAt: before.mtimeMs,
42949
+ cwd: resolvedCwd
42621
42950
  });
42622
42951
  const nativeRef = nativeSessionRefSchema.safeParse({
42623
42952
  harnessId: "claude-code",
42624
42953
  nativeSessionId,
42625
42954
  formatVersion: 1
42626
42955
  });
42627
- return candidate.success && nativeRef.success ? { candidate: candidate.data, nativeRef: nativeRef.data } : null;
42956
+ return candidate && nativeRef.success ? { candidate, nativeRef: nativeRef.data } : null;
42628
42957
  }
42629
42958
  var ClaudeSessionImportIndex = class {
42630
42959
  #directory;
@@ -42648,7 +42977,7 @@ var ClaudeSessionImportIndex = class {
42648
42977
  try {
42649
42978
  const fingerprint = await stat(file2);
42650
42979
  const cached2 = this.#cache.get(file2);
42651
- const source = cached2 && sameFile(cached2.fingerprint, fingerprint) ? cached2.source : await readCandidate(file2, signal);
42980
+ const source = cached2 && sameFileFingerprint(cached2.fingerprint, fingerprint) ? cached2.source : await readCandidate(file2, signal);
42652
42981
  if (!source)
42653
42982
  continue;
42654
42983
  if (!(await stat(source.candidate.cwd)).isDirectory())
@@ -42660,7 +42989,7 @@ var ClaudeSessionImportIndex = class {
42660
42989
  next.set(file2, { fingerprint, source });
42661
42990
  sources.push(source);
42662
42991
  } catch (error52) {
42663
- if (!missing(error52) && !(error52 instanceof ClaudeSessionChangedError))
42992
+ if (!isMissingFileError(error52) && !(error52 instanceof SessionImportChangedError))
42664
42993
  throw error52;
42665
42994
  }
42666
42995
  }
@@ -42685,7 +43014,7 @@ var ClaudeSessionImportIndex = class {
42685
43014
  const source = await readCandidate(selected, signal);
42686
43015
  return source?.candidate.nativeSessionId === nativeSessionId ? source : null;
42687
43016
  } catch (error52) {
42688
- if (missing(error52))
43017
+ if (isMissingFileError(error52))
42689
43018
  return null;
42690
43019
  throw error52;
42691
43020
  }
@@ -42935,13 +43264,13 @@ function resolveHarnessExecutable(spec, input, dependencies = {}) {
42935
43264
  }
42936
43265
 
42937
43266
  // ../../harness-discovery/dist/installation.js
42938
- import { execFile } from "node:child_process";
43267
+ import { execFile as execFile2 } from "node:child_process";
42939
43268
  import { homedir } from "node:os";
42940
43269
  function runInstallationCommand(command, args, environment, timeout = 3e4) {
42941
43270
  const env = withNodeRuntimeOnPath(environment);
42942
43271
  const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
42943
43272
  return new Promise((resolve2, reject) => {
42944
- const child = execFile(invocation.command, invocation.arguments, {
43273
+ const child = execFile2(invocation.command, invocation.arguments, {
42945
43274
  env,
42946
43275
  cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
42947
43276
  encoding: "utf8",
@@ -43123,6 +43452,60 @@ async function npmInstallation(command, packages, environment) {
43123
43452
  return null;
43124
43453
  }
43125
43454
 
43455
+ // ../../harness-discovery/dist/installer.js
43456
+ import { mkdtemp, rm as rm2, writeFile } from "node:fs/promises";
43457
+ import { tmpdir } from "node:os";
43458
+ import { join as join2 } from "node:path";
43459
+ function createHarnessInstaller(environment, source) {
43460
+ return async () => {
43461
+ if (!["darwin", "linux", "win32"].includes(process.platform))
43462
+ throw new Error("Unsupported installation platform");
43463
+ const env = withNodeRuntimeOnPath(environment);
43464
+ if ("npm" in source) {
43465
+ const npm = resolveHarnessExecutable({
43466
+ id: "npm",
43467
+ command: "npm",
43468
+ installRoots: {
43469
+ posix: [
43470
+ "~/.npm-global/bin",
43471
+ "~/.local/bin",
43472
+ VERSION_MANAGER_ROOTS,
43473
+ "/opt/homebrew/bin",
43474
+ "/usr/local/bin",
43475
+ "/usr/bin"
43476
+ ],
43477
+ windows: [
43478
+ "${APPDATA}/npm",
43479
+ VERSION_MANAGER_ROOTS,
43480
+ "${ProgramFiles}/nodejs",
43481
+ "${LOCALAPPDATA}/Programs/nodejs"
43482
+ ]
43483
+ }
43484
+ }, { environment: env });
43485
+ if (!npm)
43486
+ throw new Error("Install Node.js and npm first");
43487
+ await runInstallationCommand(npm.executable, ["install", "--global", source.npm], {
43488
+ ...env,
43489
+ ...source.allowScripts ? { npm_config_allow_scripts: source.allowScripts } : {}
43490
+ }, 6e5);
43491
+ return;
43492
+ }
43493
+ const windows = process.platform === "win32";
43494
+ const url2 = windows ? source.windows : source.posix;
43495
+ if (new URL(url2).protocol !== "https:")
43496
+ throw new Error("Installer requires HTTPS");
43497
+ const script = await fetchInstallationText(url2);
43498
+ const directory = await mkdtemp(join2(tmpdir(), "codexhost-installer-"));
43499
+ try {
43500
+ const file2 = join2(directory, windows ? "install.ps1" : "install.sh");
43501
+ await writeFile(file2, script, { mode: 384 });
43502
+ await runInstallationCommand(windows ? "powershell.exe" : source.shell ?? "bash", windows ? ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", file2] : [file2], env, 6e5);
43503
+ } finally {
43504
+ await rm2(directory, { recursive: true, force: true });
43505
+ }
43506
+ };
43507
+ }
43508
+
43126
43509
  // dist/command.js
43127
43510
  var ClaudeCodeExecutableError = class extends Error {
43128
43511
  code = "CLAUDE_NOT_FOUND";
@@ -43174,7 +43557,7 @@ function resolveClaudeCodeExecutable(input = {}, dependencies = {}) {
43174
43557
 
43175
43558
  // dist/pending-session.js
43176
43559
  import { randomUUID as randomUUID2 } from "node:crypto";
43177
- import { mkdir, open, readFile as readFile3, rename, rm as rm2, stat as stat2, unlink } from "node:fs/promises";
43560
+ import { mkdir, open, readFile as readFile3, rename, rm as rm3, stat as stat2, unlink } from "node:fs/promises";
43178
43561
  import os4 from "node:os";
43179
43562
  import path8 from "node:path";
43180
43563
  var reservationSchema = external_exports.strictObject({
@@ -43222,7 +43605,7 @@ var ClaudePendingSessions = class {
43222
43605
  await file2.close();
43223
43606
  }
43224
43607
  } catch (error52) {
43225
- await rm2(directory, { recursive: true, force: true });
43608
+ await rm3(directory, { recursive: true, force: true });
43226
43609
  throw error52;
43227
43610
  }
43228
43611
  await this.#sync(directory);
@@ -43267,7 +43650,7 @@ var ClaudePendingSessions = class {
43267
43650
  await rename(temporary, path8.join(directory, "session.json"));
43268
43651
  await this.#sync(directory);
43269
43652
  } finally {
43270
- await rm2(temporary, { force: true });
43653
+ await rm3(temporary, { force: true });
43271
43654
  }
43272
43655
  }
43273
43656
  async #sync(directory) {
@@ -43296,7 +43679,7 @@ var ClaudePendingSessions = class {
43296
43679
  await this.#sync(this.#path(ref, cwd));
43297
43680
  }
43298
43681
  async discard(ref, cwd) {
43299
- await rm2(this.#path(ref, cwd), { recursive: true, force: true });
43682
+ await rm3(this.#path(ref, cwd), { recursive: true, force: true });
43300
43683
  }
43301
43684
  };
43302
43685
 
@@ -45219,11 +45602,11 @@ function projectClaudeAccountUsage(usage, account) {
45219
45602
  }
45220
45603
 
45221
45604
  // dist/process-fence.js
45222
- import { execFile as execFile2 } from "node:child_process";
45605
+ import { execFile as execFile3 } from "node:child_process";
45223
45606
  import path13 from "node:path";
45224
45607
  import { setTimeout as setTimeout2 } from "node:timers/promises";
45225
45608
  import { promisify } from "node:util";
45226
- var executeFile = promisify(execFile2);
45609
+ var executeFile = promisify(execFile3);
45227
45610
  function signalGroup(pid, signal) {
45228
45611
  try {
45229
45612
  process.kill(-pid, signal);
@@ -47073,6 +47456,9 @@ var ClaudeHarnessSession = class {
47073
47456
  this.#statePublished = durable;
47074
47457
  this.outputs = this.#channel.outputs;
47075
47458
  }
47459
+ get nativeWriterRef() {
47460
+ return this.#nativeRef;
47461
+ }
47076
47462
  async readSnapshot() {
47077
47463
  if (this.#phase !== "open") {
47078
47464
  return { ok: false, error: invalidState("Claude Code Session is not open") };
@@ -48749,22 +49135,10 @@ var ClaudeCodeAdapter = class {
48749
49135
  harnessId = claudeCodeHarnessId2;
48750
49136
  sessionImport = Object.freeze({
48751
49137
  listCandidates: async () => {
48752
- const result = await this.#readImport((signal) => this.#importIndex.list(signal));
49138
+ const result = await this.#importScope.read((signal) => this.#importIndex.list(signal));
48753
49139
  return result.ok ? { ok: true, value: result.value.map(({ candidate }) => candidate) } : result;
48754
49140
  },
48755
- resolveCandidate: async (nativeSessionId) => {
48756
- const result = await this.#readImport((signal) => this.#importIndex.resolve(nativeSessionId, signal));
48757
- if (!result.ok)
48758
- return result;
48759
- return result.value ? { ok: true, value: result.value } : {
48760
- ok: false,
48761
- error: {
48762
- code: "sessionNotFound",
48763
- message: "Claude Code Session is no longer importable",
48764
- retryable: false
48765
- }
48766
- };
48767
- }
49141
+ resolveCandidate: (nativeSessionId) => this.#importScope.resolve((signal) => this.#importIndex.resolve(nativeSessionId, signal))
48768
49142
  });
48769
49143
  subagents = {
48770
49144
  readSnapshot: async (input) => {
@@ -48809,9 +49183,12 @@ var ClaudeCodeAdapter = class {
48809
49183
  #cancelTimeoutMs;
48810
49184
  #closeTimeoutMs;
48811
49185
  #dependencies;
48812
- #importAbort = new AbortController();
48813
49186
  #importIndex;
48814
- #importRequests = /* @__PURE__ */ new Set();
49187
+ #importScope = new SessionImportScope({
49188
+ closedMessage: "Claude Code Adapter is closed",
49189
+ unavailableMessage: "Claude Code Session discovery failed; check storage access and duplicate Session identities, then retry after closing native clients",
49190
+ notFoundMessage: "Claude Code Session is no longer importable"
49191
+ });
48815
49192
  #pendingSessions;
48816
49193
  #toolOutputLimit;
48817
49194
  #continuationQuiescenceMs;
@@ -48880,24 +49257,6 @@ var ClaudeCodeAdapter = class {
48880
49257
  readSubagentMessages: ({ cwd, sessionId, nativeSubagentId: nativeSubagentId2 }) => jkt(sessionId, nativeSubagentId2, { dir: cwd })
48881
49258
  };
48882
49259
  }
48883
- #readImport(operation) {
48884
- if (this.#importAbort.signal.aborted) {
48885
- return Promise.resolve({
48886
- ok: false,
48887
- error: invalidState("Claude Code Adapter is closed")
48888
- });
48889
- }
48890
- const request = operation(this.#importAbort.signal).then((value) => ({ ok: true, value })).catch(() => ({
48891
- ok: false,
48892
- error: {
48893
- code: "unavailable",
48894
- message: "Claude Code Session discovery failed; check storage access and duplicate Session identities, then retry after closing native clients",
48895
- retryable: true
48896
- }
48897
- })).finally(() => this.#importRequests.delete(request));
48898
- this.#importRequests.add(request);
48899
- return request;
48900
- }
48901
49260
  async inspect(input = {}) {
48902
49261
  if (this.#closePromise) {
48903
49262
  return {
@@ -49213,10 +49572,9 @@ var ClaudeCodeAdapter = class {
49213
49572
  }
49214
49573
  close() {
49215
49574
  if (!this.#closePromise) {
49216
- this.#importAbort.abort();
49217
49575
  this.#inspectionCache.clear();
49218
49576
  this.#closePromise = Promise.all([
49219
- ...this.#importRequests,
49577
+ this.#importScope.close(),
49220
49578
  ...[...this.#inspectors].map((inspector) => inspector.close()),
49221
49579
  ...[...this.#sessions].map((session) => session.close()),
49222
49580
  ...this.#inspectionInFlight.values()
@@ -49281,6 +49639,7 @@ function createClaudeInstallation(environment, command) {
49281
49639
  updateAvailable: newerInstallationVersion(currentVersion, latestVersion),
49282
49640
  canUpdate,
49283
49641
  ...!canUpdate ? {
49642
+ messageCode: blocked ? "claude-policy-restricted" : "original-installer",
49284
49643
  message: blocked ? "Claude updates are restricted by the installation's settings or policy." : "Use the original installer or package manager for this Claude installation."
49285
49644
  } : {}
49286
49645
  };
@@ -49293,7 +49652,7 @@ function createClaudeInstallation(environment, command) {
49293
49652
 
49294
49653
  // dist/user-shell-environment.js
49295
49654
  import path16 from "node:path";
49296
- import { execFile as execFile3 } from "node:child_process";
49655
+ import { execFile as execFile4 } from "node:child_process";
49297
49656
  var ENVIRONMENT_MARKER = Buffer.from("\0CODEXHOST_USER_SHELL_ENV_V1\0");
49298
49657
  var ENVIRONMENT_COMMAND = "printf '\\0CODEXHOST_USER_SHELL_ENV_V1\\0'; /usr/bin/env -0";
49299
49658
  var SHELL_ENVIRONMENT_TIMEOUT_MS = 3e3;
@@ -49342,7 +49701,7 @@ async function withUserShellEnvironment(environment, dependencies) {
49342
49701
  if (cached2)
49343
49702
  return mergeMissingEnvironment(environment, cached2);
49344
49703
  const run = dependencies?.run ?? ((command, arguments_, options) => new Promise((resolve2) => {
49345
- const child = execFile3(command, arguments_, {
49704
+ const child = execFile4(command, arguments_, {
49346
49705
  ...options,
49347
49706
  encoding: "buffer",
49348
49707
  killSignal: "SIGKILL"
@@ -49376,15 +49735,34 @@ async function createHarnessAdapter(context) {
49376
49735
  commandCatalog: claudeCommandCatalog,
49377
49736
  liveCommandCatalog: true,
49378
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
+ },
49379
49749
  ...context.brokerDescriptorPath ? { descriptorPath: context.brokerDescriptorPath } : {}
49380
49750
  });
49381
49751
  }
49382
49752
  return Object.assign(new ClaudeCodeAdapter({
49383
49753
  ...environment[CLAUDE_CODE_COMMAND_ENV] ? { command: environment[CLAUDE_CODE_COMMAND_ENV] } : {},
49384
49754
  environment
49385
- }), { installation: createClaudeInstallation(environment, environment[CLAUDE_CODE_COMMAND_ENV]) });
49755
+ }), {
49756
+ installation: createClaudeInstallation(environment, environment[CLAUDE_CODE_COMMAND_ENV]),
49757
+ install: createHarnessInstaller(environment, {
49758
+ posix: "https://claude.ai/install.sh",
49759
+ windows: "https://claude.ai/install.ps1"
49760
+ })
49761
+ });
49386
49762
  }
49387
49763
  async function warmup(adapter) {
49764
+ if (adapter instanceof BrokeredHarnessAdapter)
49765
+ return;
49388
49766
  try {
49389
49767
  await adapter.inspect();
49390
49768
  } catch {