@codexhost/cli-darwin-x64 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.
@@ -12694,6 +12694,373 @@ var require_content_type = __commonJS({
12694
12694
  }
12695
12695
  });
12696
12696
 
12697
+ // ../../harness-discovery/dist/environment.js
12698
+ import fs from "node:fs";
12699
+ import path from "node:path";
12700
+ function targetPath(platform) {
12701
+ return platform === "win32" ? path.win32 : path.posix;
12702
+ }
12703
+ function environmentValue(environment, name) {
12704
+ const lowered = name.toLowerCase();
12705
+ for (const [key, value] of Object.entries(environment)) {
12706
+ if (key.toLowerCase() === lowered)
12707
+ return value;
12708
+ }
12709
+ return void 0;
12710
+ }
12711
+ function pathDelimiter(platform) {
12712
+ return platform === "win32" ? ";" : ":";
12713
+ }
12714
+ function pathDirectories(environment, platform) {
12715
+ return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
12716
+ }
12717
+ function executableExtensions(command, platform, environment) {
12718
+ if (platform !== "win32")
12719
+ return [""];
12720
+ if (targetPath(platform).extname(command) !== "")
12721
+ return [""];
12722
+ return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
12723
+ }
12724
+ function isExecutableFile(filePath, platform) {
12725
+ try {
12726
+ fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
12727
+ return fs.statSync(filePath).isFile();
12728
+ } catch {
12729
+ return false;
12730
+ }
12731
+ }
12732
+ function subdirectoryNames(directory) {
12733
+ try {
12734
+ return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
12735
+ } catch {
12736
+ return [];
12737
+ }
12738
+ }
12739
+ function newestFirst(names) {
12740
+ return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
12741
+ }
12742
+
12743
+ // ../../harness-discovery/dist/invocation.js
12744
+ import path2 from "node:path";
12745
+ function commandInvocation(command, arguments_, environment, platform = process.platform) {
12746
+ const extension = path2.win32.extname(command).toLowerCase();
12747
+ if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
12748
+ return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
12749
+ }
12750
+ const quote2 = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
12751
+ const commandLine = [command, ...arguments_].map(quote2).join(" ");
12752
+ return {
12753
+ command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
12754
+ arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
12755
+ windowsVerbatimArguments: true
12756
+ };
12757
+ }
12758
+
12759
+ // ../../harness-discovery/dist/node-runtime.js
12760
+ import path3 from "node:path";
12761
+ function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
12762
+ const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
12763
+ const delimiter = platform === "win32" ? ";" : ":";
12764
+ const runtimeDirectory = path3.dirname(runtimeExecutable);
12765
+ const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
12766
+ const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
12767
+ if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
12768
+ directories.push(runtimeDirectory);
12769
+ }
12770
+ return { ...environment, [pathKey]: directories.join(delimiter) };
12771
+ }
12772
+
12773
+ // ../../harness-discovery/dist/resolve.js
12774
+ import os from "node:os";
12775
+
12776
+ // ../../harness-discovery/dist/version-managers.js
12777
+ function versionManagerBinaryDirectories(context) {
12778
+ const { platform, environment, home } = context;
12779
+ const list = context.subdirectories ?? subdirectoryNames;
12780
+ const pathFlavor = targetPath(platform);
12781
+ const value = (name) => environmentValue(environment, name);
12782
+ const directories = [];
12783
+ const versioned = (root, ...tail) => {
12784
+ for (const version2 of newestFirst(list(root))) {
12785
+ directories.push(pathFlavor.join(root, version2, ...tail));
12786
+ }
12787
+ };
12788
+ if (platform === "win32") {
12789
+ const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
12790
+ const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
12791
+ versioned(pathFlavor.join(appData, "nvm"));
12792
+ versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
12793
+ directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
12794
+ directories.push(pathFlavor.join(home, ".bun", "bin"));
12795
+ const pnpmHome2 = value("PNPM_HOME");
12796
+ if (pnpmHome2)
12797
+ directories.push(pnpmHome2);
12798
+ directories.push(pathFlavor.join(localAppData, "pnpm"));
12799
+ return directories;
12800
+ }
12801
+ versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
12802
+ const fnmRoots = [
12803
+ value("FNM_DIR"),
12804
+ pathFlavor.join(home, ".local", "share", "fnm"),
12805
+ pathFlavor.join(home, "Library", "Application Support", "fnm")
12806
+ ].filter((root) => root !== void 0);
12807
+ for (const root of fnmRoots) {
12808
+ versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
12809
+ }
12810
+ const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
12811
+ versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
12812
+ directories.push(pathFlavor.join(voltaHome, "bin"));
12813
+ const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
12814
+ versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
12815
+ directories.push(pathFlavor.join(asdfHome, "shims"));
12816
+ const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
12817
+ versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
12818
+ directories.push(pathFlavor.join(nodenvHome, "shims"));
12819
+ versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
12820
+ directories.push(pathFlavor.join(home, ".bun", "bin"));
12821
+ const pnpmHome = value("PNPM_HOME");
12822
+ if (pnpmHome)
12823
+ directories.push(pnpmHome);
12824
+ directories.push(pathFlavor.join(home, "Library", "pnpm"));
12825
+ directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
12826
+ for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
12827
+ for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
12828
+ directories.push(pathFlavor.join(prefix, formula, "bin"));
12829
+ }
12830
+ }
12831
+ return directories;
12832
+ }
12833
+
12834
+ // ../../harness-discovery/dist/resolve.js
12835
+ var VERSION_MANAGER_ROOTS = "<version-managers>";
12836
+ function installRootExtensions(platform) {
12837
+ return platform === "win32" ? [".exe", ".cmd"] : [""];
12838
+ }
12839
+ function resolveHomeDirectory(input) {
12840
+ return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
12841
+ }
12842
+ function templateVariables(environment, platform, home) {
12843
+ const pathFlavor = targetPath(platform);
12844
+ return {
12845
+ HOME: home,
12846
+ USERPROFILE: home,
12847
+ APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
12848
+ LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
12849
+ };
12850
+ }
12851
+ function joinTemplate(platform, value) {
12852
+ const pathFlavor = targetPath(platform);
12853
+ const segments = value.split("/");
12854
+ const head = segments[0] ?? "";
12855
+ const tail = segments.slice(1);
12856
+ if (head === "")
12857
+ return pathFlavor.join(pathFlavor.sep, ...tail);
12858
+ return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
12859
+ }
12860
+ function expandInstallRoot(template, environment, platform, home) {
12861
+ const variables = templateVariables(environment, platform, home);
12862
+ let unresolved = false;
12863
+ const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
12864
+ const value = variables[name] ?? environmentValue(environment, name);
12865
+ if (value === void 0 || value === "") {
12866
+ unresolved = true;
12867
+ return "";
12868
+ }
12869
+ return value;
12870
+ });
12871
+ return unresolved ? void 0 : joinTemplate(platform, substituted);
12872
+ }
12873
+ function installRootDirectories(spec, input, dependencies, platform, home) {
12874
+ const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
12875
+ const directories = [];
12876
+ for (const template of templates) {
12877
+ if (template === VERSION_MANAGER_ROOTS) {
12878
+ directories.push(...versionManagerBinaryDirectories({
12879
+ platform,
12880
+ environment: input.environment,
12881
+ home,
12882
+ ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
12883
+ }));
12884
+ continue;
12885
+ }
12886
+ const directory = expandInstallRoot(template, input.environment, platform, home);
12887
+ if (directory !== void 0)
12888
+ directories.push(directory);
12889
+ }
12890
+ return directories;
12891
+ }
12892
+ function harnessCandidates(spec, input, dependencies = {}) {
12893
+ const platform = input.platform ?? process.platform;
12894
+ const pathFlavor = targetPath(platform);
12895
+ const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
12896
+ const command = configured ?? spec.command;
12897
+ if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
12898
+ return [{ candidate: command, source: "configured" }];
12899
+ }
12900
+ const candidates = [];
12901
+ const extensions = executableExtensions(command, platform, input.environment);
12902
+ for (const directory of pathDirectories(input.environment, platform)) {
12903
+ for (const extension of extensions) {
12904
+ candidates.push({
12905
+ candidate: pathFlavor.join(directory, command + extension),
12906
+ source: "path"
12907
+ });
12908
+ }
12909
+ }
12910
+ if (configured !== void 0)
12911
+ return candidates;
12912
+ const home = resolveHomeDirectory(input);
12913
+ for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
12914
+ for (const extension of installRootExtensions(platform)) {
12915
+ candidates.push({
12916
+ candidate: pathFlavor.join(directory, spec.command + extension),
12917
+ source: "install-root"
12918
+ });
12919
+ }
12920
+ }
12921
+ return candidates;
12922
+ }
12923
+ function resolveHarnessExecutable(spec, input, dependencies = {}) {
12924
+ const platform = input.platform ?? process.platform;
12925
+ const isExecutable = dependencies.isExecutable ?? ((candidate) => isExecutableFile(candidate, platform));
12926
+ const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
12927
+ const context = { platform, isExecutable };
12928
+ for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
12929
+ const executable = runnable(candidate, context);
12930
+ if (executable !== void 0 && isExecutable(executable))
12931
+ return { executable, source };
12932
+ }
12933
+ return void 0;
12934
+ }
12935
+
12936
+ // ../../harness-discovery/dist/installation.js
12937
+ import { execFile } from "node:child_process";
12938
+ import { homedir } from "node:os";
12939
+ function runInstallationCommand(command, args, environment, timeout = 3e4) {
12940
+ const env = withNodeRuntimeOnPath(environment);
12941
+ const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
12942
+ return new Promise((resolve, reject) => {
12943
+ const child = execFile(invocation.command, invocation.arguments, {
12944
+ env,
12945
+ cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
12946
+ encoding: "utf8",
12947
+ timeout,
12948
+ killSignal: "SIGKILL",
12949
+ maxBuffer: 1024 * 1024,
12950
+ windowsHide: true,
12951
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments
12952
+ }, (error51, stdout, stderr) => {
12953
+ if (error51)
12954
+ reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
12955
+ else
12956
+ resolve((stdout || stderr).trim());
12957
+ });
12958
+ child.stdin?.end();
12959
+ });
12960
+ }
12961
+ function installationVersion(value) {
12962
+ if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
12963
+ throw new Error("Harness returned an invalid version");
12964
+ return value.trim().replace(/^v/, "");
12965
+ }
12966
+ function createInstallationManager(options) {
12967
+ let checking;
12968
+ let updating;
12969
+ const check2 = () => checking ??= options.check().finally(() => {
12970
+ checking = void 0;
12971
+ });
12972
+ return (action) => {
12973
+ if (updating)
12974
+ return updating;
12975
+ if (action === "check")
12976
+ return check2();
12977
+ updating = (async () => {
12978
+ const before = await check2();
12979
+ if (!before.updateAvailable)
12980
+ return before;
12981
+ if (!before.canUpdate)
12982
+ throw new Error(before.message ?? "This installation cannot be updated automatically");
12983
+ await options.update(before);
12984
+ const after = await check2();
12985
+ if (after.currentVersion === before.currentVersion)
12986
+ throw new Error("The Harness version did not change; check the native updater and retry");
12987
+ return after;
12988
+ })().finally(() => {
12989
+ updating = void 0;
12990
+ });
12991
+ return updating;
12992
+ };
12993
+ }
12994
+ async function fetchInstallationText(url2) {
12995
+ const request = async () => {
12996
+ const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
12997
+ if (!response.ok)
12998
+ throw new Error("Could not check the latest Harness version");
12999
+ return response.text();
13000
+ };
13001
+ try {
13002
+ return await request();
13003
+ } catch (error51) {
13004
+ if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
13005
+ throw error51;
13006
+ return request();
13007
+ }
13008
+ }
13009
+
13010
+ // ../../harness-discovery/dist/installer.js
13011
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
13012
+ import { tmpdir } from "node:os";
13013
+ import { join } from "node:path";
13014
+ function createHarnessInstaller(environment, source) {
13015
+ return async () => {
13016
+ if (!["darwin", "linux", "win32"].includes(process.platform))
13017
+ throw new Error("Unsupported installation platform");
13018
+ const env = withNodeRuntimeOnPath(environment);
13019
+ if ("npm" in source) {
13020
+ const npm = resolveHarnessExecutable({
13021
+ id: "npm",
13022
+ command: "npm",
13023
+ installRoots: {
13024
+ posix: [
13025
+ "~/.npm-global/bin",
13026
+ "~/.local/bin",
13027
+ VERSION_MANAGER_ROOTS,
13028
+ "/opt/homebrew/bin",
13029
+ "/usr/local/bin",
13030
+ "/usr/bin"
13031
+ ],
13032
+ windows: [
13033
+ "${APPDATA}/npm",
13034
+ VERSION_MANAGER_ROOTS,
13035
+ "${ProgramFiles}/nodejs",
13036
+ "${LOCALAPPDATA}/Programs/nodejs"
13037
+ ]
13038
+ }
13039
+ }, { environment: env });
13040
+ if (!npm)
13041
+ throw new Error("Install Node.js and npm first");
13042
+ await runInstallationCommand(npm.executable, ["install", "--global", source.npm], {
13043
+ ...env,
13044
+ ...source.allowScripts ? { npm_config_allow_scripts: source.allowScripts } : {}
13045
+ }, 6e5);
13046
+ return;
13047
+ }
13048
+ const windows = process.platform === "win32";
13049
+ const url2 = windows ? source.windows : source.posix;
13050
+ if (new URL(url2).protocol !== "https:")
13051
+ throw new Error("Installer requires HTTPS");
13052
+ const script = await fetchInstallationText(url2);
13053
+ const directory = await mkdtemp(join(tmpdir(), "codexhost-installer-"));
13054
+ try {
13055
+ const file2 = join(directory, windows ? "install.ps1" : "install.sh");
13056
+ await writeFile(file2, script, { mode: 384 });
13057
+ await runInstallationCommand(windows ? "powershell.exe" : source.shell ?? "bash", windows ? ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", file2] : [file2], env, 6e5);
13058
+ } finally {
13059
+ await rm(directory, { recursive: true, force: true });
13060
+ }
13061
+ };
13062
+ }
13063
+
12697
13064
  // ../../../node_modules/zod/v4/classic/external.js
12698
13065
  var external_exports = {};
12699
13066
  __export(external_exports, {
@@ -27278,6 +27645,20 @@ var harnessDisplaySetSchema = external_exports.strictObject({
27278
27645
  initializeOnly: external_exports.boolean().optional()
27279
27646
  });
27280
27647
 
27648
+ // ../../shared-contracts/dist/ids.js
27649
+ var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
27650
+ message: "Identifier must not be empty or whitespace"
27651
+ });
27652
+ var harnessIdSchema = opaqueIdSchema.brand();
27653
+ var hostThreadIdSchema = opaqueIdSchema.brand();
27654
+ var hostTurnIdSchema = opaqueIdSchema.brand();
27655
+ var hostItemIdSchema = opaqueIdSchema.brand();
27656
+ var hostInteractionIdSchema = opaqueIdSchema.brand();
27657
+
27658
+ // ../../shared-contracts/dist/thread-prewarm.js
27659
+ var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
27660
+ var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
27661
+
27281
27662
  // ../../shared-contracts/dist/console.js
27282
27663
  var consoleAnnouncementSchema = external_exports.strictObject({
27283
27664
  title: external_exports.string().trim().min(1).max(200),
@@ -27290,10 +27671,14 @@ var consoleOpenResultSchema = external_exports.strictObject({
27290
27671
  url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
27291
27672
  });
27292
27673
  var CONSOLE_HOST_METHODS = Object.freeze([
27674
+ "codexhost/console/remote-connections",
27675
+ "codexhost/runtime/status",
27676
+ "codexhost/remote/ssh-setup",
27293
27677
  "codexhost/harness/plugins/list",
27294
27678
  "codexhost/harness/display-settings/get",
27295
27679
  "codexhost/harness/display-settings/set",
27296
27680
  "codexhost/harness/inspect",
27681
+ "codexhost/harness/installation",
27297
27682
  "codexhost/harness/launch-settings/get",
27298
27683
  "codexhost/harness/launch-settings/set",
27299
27684
  "codexhost/harness/web-ui/open",
@@ -27355,16 +27740,6 @@ var loadedSessionsSchema = external_exports.array(external_exports.strictObject(
27355
27740
  inactiveMs: external_exports.number().nonnegative()
27356
27741
  }));
27357
27742
 
27358
- // ../../shared-contracts/dist/ids.js
27359
- var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
27360
- message: "Identifier must not be empty or whitespace"
27361
- });
27362
- var harnessIdSchema = opaqueIdSchema.brand();
27363
- var hostThreadIdSchema = opaqueIdSchema.brand();
27364
- var hostTurnIdSchema = opaqueIdSchema.brand();
27365
- var hostItemIdSchema = opaqueIdSchema.brand();
27366
- var hostInteractionIdSchema = opaqueIdSchema.brand();
27367
-
27368
27743
  // ../../shared-contracts/dist/manual-compaction.js
27369
27744
  var threadManualCompactionStartedSchema = external_exports.strictObject({
27370
27745
  threadId: hostThreadIdSchema,
@@ -27940,14 +28315,17 @@ var harnessLaunchSettingsSchema = external_exports.object({
27940
28315
  // ../../shared-contracts/dist/harness-installation.js
27941
28316
  var harnessInstallationParamsSchema = external_exports.object({
27942
28317
  harnessId: harnessIdSchema,
27943
- action: external_exports.enum(["check", "update"])
28318
+ action: external_exports.enum(["check", "update", "install"])
27944
28319
  }).strict();
27945
28320
  var harnessInstallationStateSchema = external_exports.object({
27946
28321
  currentVersion: external_exports.string().min(1).max(128),
27947
28322
  latestVersion: external_exports.string().min(1).max(128),
27948
28323
  updateAvailable: external_exports.boolean(),
27949
28324
  canUpdate: external_exports.boolean(),
27950
- message: external_exports.string().max(2048).optional()
28325
+ // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
28326
+ message: external_exports.string().max(2048).optional(),
28327
+ messageCode: external_exports.string().min(1).max(128).optional(),
28328
+ latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
27951
28329
  }).strict();
27952
28330
 
27953
28331
  // ../../shared-contracts/dist/codex-accounts.js
@@ -28249,6 +28627,80 @@ var updateStatusResultSchema = external_exports.strictObject({
28249
28627
  status: updateStatusSchema.nullable()
28250
28628
  });
28251
28629
 
28630
+ // ../../shared-contracts/dist/remote-runtime.js
28631
+ var remoteUpdatePhaseSchema = external_exports.enum([
28632
+ "idle",
28633
+ "installing",
28634
+ "restarting",
28635
+ "succeeded",
28636
+ "failed"
28637
+ ]);
28638
+ var runtimeStatusSchema = external_exports.object({
28639
+ runningVersion: external_exports.string().nullable(),
28640
+ installedVersion: external_exports.string().nullable(),
28641
+ restartRequired: external_exports.boolean(),
28642
+ remote: external_exports.boolean(),
28643
+ updateSupported: external_exports.boolean(),
28644
+ update: external_exports.object({
28645
+ phase: remoteUpdatePhaseSchema,
28646
+ targetVersion: external_exports.string().nullable(),
28647
+ error: external_exports.string().nullable()
28648
+ })
28649
+ });
28650
+ var remoteUpdateParamsSchema = external_exports.object({
28651
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
28652
+ }).strict();
28653
+ var remoteSshSetupParamsSchema = external_exports.object({
28654
+ hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
28655
+ port: external_exports.number().int().min(1).max(65535).nullable(),
28656
+ identity: external_exports.string().max(4096).nullable(),
28657
+ action: external_exports.enum(["inspect", "install", "update", "repair", "uninstall"]),
28658
+ uninstallPackage: external_exports.boolean().optional(),
28659
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
28660
+ }).strict();
28661
+ var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
28662
+
28663
+ // ../../shared-contracts/dist/remote-connections.js
28664
+ var hostId = external_exports.string().min(1).max(1024);
28665
+ var codexSshConnectionSchema = external_exports.object({
28666
+ hostId,
28667
+ displayName: external_exports.string().min(1).max(1024),
28668
+ source: external_exports.enum(["codex-managed", "discovered"]),
28669
+ sshAlias: external_exports.string().max(1024).nullable(),
28670
+ sshHost: external_exports.string().min(1).max(1024),
28671
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
28672
+ identity: external_exports.string().max(4096).nullable(),
28673
+ autoConnect: external_exports.boolean(),
28674
+ connectionAnalyticsId: external_exports.string().max(1024).optional()
28675
+ });
28676
+ var codexSshDraftSchema = external_exports.strictObject({
28677
+ displayName: external_exports.string().min(1).max(1024),
28678
+ hostname: external_exports.string().min(1).max(1024),
28679
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
28680
+ identity: external_exports.string().max(4096).nullable()
28681
+ });
28682
+ var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
28683
+ external_exports.strictObject({ action: external_exports.literal("list") }),
28684
+ external_exports.strictObject({
28685
+ action: external_exports.literal("save"),
28686
+ draft: codexSshDraftSchema,
28687
+ previous: codexSshConnectionSchema.nullable()
28688
+ }),
28689
+ external_exports.strictObject({ action: external_exports.literal("remove"), previous: codexSshConnectionSchema }),
28690
+ external_exports.strictObject({ action: external_exports.literal("connect"), hostId, enabled: external_exports.boolean() }),
28691
+ external_exports.strictObject({ action: external_exports.literal("state"), hostId }),
28692
+ external_exports.strictObject({ action: external_exports.literal("runtime"), hostId }),
28693
+ external_exports.strictObject({
28694
+ action: external_exports.literal("update"),
28695
+ hostId: hostId.refine((id) => id !== "local"),
28696
+ version: remoteUpdateParamsSchema.shape.version
28697
+ })
28698
+ ]);
28699
+ var remoteConnectionsReplySchema = external_exports.union([
28700
+ external_exports.strictObject({ result: jsonValueSchema }),
28701
+ external_exports.strictObject({ error: external_exports.strictObject({ code: external_exports.number().int(), message: external_exports.string() }) })
28702
+ ]);
28703
+
28252
28704
  // ../../shared-contracts/dist/index.js
28253
28705
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
28254
28706
 
@@ -28587,304 +29039,6 @@ function cursorCommandPrompt(command, catalog) {
28587
29039
  return { ok: true, value: `${descriptor.invocation}${text2 ? ` ${text2}` : ""}` };
28588
29040
  }
28589
29041
 
28590
- // ../../harness-discovery/dist/environment.js
28591
- import fs from "node:fs";
28592
- import path from "node:path";
28593
- function targetPath(platform) {
28594
- return platform === "win32" ? path.win32 : path.posix;
28595
- }
28596
- function environmentValue(environment, name) {
28597
- const lowered = name.toLowerCase();
28598
- for (const [key, value] of Object.entries(environment)) {
28599
- if (key.toLowerCase() === lowered)
28600
- return value;
28601
- }
28602
- return void 0;
28603
- }
28604
- function pathDelimiter(platform) {
28605
- return platform === "win32" ? ";" : ":";
28606
- }
28607
- function pathDirectories(environment, platform) {
28608
- return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
28609
- }
28610
- function executableExtensions(command, platform, environment) {
28611
- if (platform !== "win32")
28612
- return [""];
28613
- if (targetPath(platform).extname(command) !== "")
28614
- return [""];
28615
- return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
28616
- }
28617
- function isExecutableFile(filePath, platform) {
28618
- try {
28619
- fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
28620
- return fs.statSync(filePath).isFile();
28621
- } catch {
28622
- return false;
28623
- }
28624
- }
28625
- function subdirectoryNames(directory) {
28626
- try {
28627
- return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
28628
- } catch {
28629
- return [];
28630
- }
28631
- }
28632
- function newestFirst(names) {
28633
- return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
28634
- }
28635
-
28636
- // ../../harness-discovery/dist/invocation.js
28637
- import path2 from "node:path";
28638
- function commandInvocation(command, arguments_, environment, platform = process.platform) {
28639
- const extension = path2.win32.extname(command).toLowerCase();
28640
- if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
28641
- return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
28642
- }
28643
- const quote2 = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
28644
- const commandLine = [command, ...arguments_].map(quote2).join(" ");
28645
- return {
28646
- command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
28647
- arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
28648
- windowsVerbatimArguments: true
28649
- };
28650
- }
28651
-
28652
- // ../../harness-discovery/dist/node-runtime.js
28653
- import path3 from "node:path";
28654
- function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
28655
- const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
28656
- const delimiter = platform === "win32" ? ";" : ":";
28657
- const runtimeDirectory = path3.dirname(runtimeExecutable);
28658
- const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
28659
- const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
28660
- if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
28661
- directories.push(runtimeDirectory);
28662
- }
28663
- return { ...environment, [pathKey]: directories.join(delimiter) };
28664
- }
28665
-
28666
- // ../../harness-discovery/dist/resolve.js
28667
- import os from "node:os";
28668
-
28669
- // ../../harness-discovery/dist/version-managers.js
28670
- function versionManagerBinaryDirectories(context) {
28671
- const { platform, environment, home } = context;
28672
- const list = context.subdirectories ?? subdirectoryNames;
28673
- const pathFlavor = targetPath(platform);
28674
- const value = (name) => environmentValue(environment, name);
28675
- const directories = [];
28676
- const versioned = (root, ...tail) => {
28677
- for (const version2 of newestFirst(list(root))) {
28678
- directories.push(pathFlavor.join(root, version2, ...tail));
28679
- }
28680
- };
28681
- if (platform === "win32") {
28682
- const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
28683
- const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
28684
- versioned(pathFlavor.join(appData, "nvm"));
28685
- versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
28686
- directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
28687
- directories.push(pathFlavor.join(home, ".bun", "bin"));
28688
- const pnpmHome2 = value("PNPM_HOME");
28689
- if (pnpmHome2)
28690
- directories.push(pnpmHome2);
28691
- directories.push(pathFlavor.join(localAppData, "pnpm"));
28692
- return directories;
28693
- }
28694
- versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
28695
- const fnmRoots = [
28696
- value("FNM_DIR"),
28697
- pathFlavor.join(home, ".local", "share", "fnm"),
28698
- pathFlavor.join(home, "Library", "Application Support", "fnm")
28699
- ].filter((root) => root !== void 0);
28700
- for (const root of fnmRoots) {
28701
- versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
28702
- }
28703
- const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
28704
- versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
28705
- directories.push(pathFlavor.join(voltaHome, "bin"));
28706
- const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
28707
- versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
28708
- directories.push(pathFlavor.join(asdfHome, "shims"));
28709
- const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
28710
- versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
28711
- directories.push(pathFlavor.join(nodenvHome, "shims"));
28712
- versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
28713
- directories.push(pathFlavor.join(home, ".bun", "bin"));
28714
- const pnpmHome = value("PNPM_HOME");
28715
- if (pnpmHome)
28716
- directories.push(pnpmHome);
28717
- directories.push(pathFlavor.join(home, "Library", "pnpm"));
28718
- directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
28719
- for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
28720
- for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
28721
- directories.push(pathFlavor.join(prefix, formula, "bin"));
28722
- }
28723
- }
28724
- return directories;
28725
- }
28726
-
28727
- // ../../harness-discovery/dist/resolve.js
28728
- var VERSION_MANAGER_ROOTS = "<version-managers>";
28729
- function installRootExtensions(platform) {
28730
- return platform === "win32" ? [".exe", ".cmd"] : [""];
28731
- }
28732
- function resolveHomeDirectory(input) {
28733
- return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
28734
- }
28735
- function templateVariables(environment, platform, home) {
28736
- const pathFlavor = targetPath(platform);
28737
- return {
28738
- HOME: home,
28739
- USERPROFILE: home,
28740
- APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
28741
- LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
28742
- };
28743
- }
28744
- function joinTemplate(platform, value) {
28745
- const pathFlavor = targetPath(platform);
28746
- const segments = value.split("/");
28747
- const head = segments[0] ?? "";
28748
- const tail = segments.slice(1);
28749
- if (head === "")
28750
- return pathFlavor.join(pathFlavor.sep, ...tail);
28751
- return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
28752
- }
28753
- function expandInstallRoot(template, environment, platform, home) {
28754
- const variables = templateVariables(environment, platform, home);
28755
- let unresolved = false;
28756
- const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
28757
- const value = variables[name] ?? environmentValue(environment, name);
28758
- if (value === void 0 || value === "") {
28759
- unresolved = true;
28760
- return "";
28761
- }
28762
- return value;
28763
- });
28764
- return unresolved ? void 0 : joinTemplate(platform, substituted);
28765
- }
28766
- function installRootDirectories(spec, input, dependencies, platform, home) {
28767
- const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
28768
- const directories = [];
28769
- for (const template of templates) {
28770
- if (template === VERSION_MANAGER_ROOTS) {
28771
- directories.push(...versionManagerBinaryDirectories({
28772
- platform,
28773
- environment: input.environment,
28774
- home,
28775
- ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
28776
- }));
28777
- continue;
28778
- }
28779
- const directory = expandInstallRoot(template, input.environment, platform, home);
28780
- if (directory !== void 0)
28781
- directories.push(directory);
28782
- }
28783
- return directories;
28784
- }
28785
- function harnessCandidates(spec, input, dependencies = {}) {
28786
- const platform = input.platform ?? process.platform;
28787
- const pathFlavor = targetPath(platform);
28788
- const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
28789
- const command = configured ?? spec.command;
28790
- if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
28791
- return [{ candidate: command, source: "configured" }];
28792
- }
28793
- const candidates = [];
28794
- const extensions = executableExtensions(command, platform, input.environment);
28795
- for (const directory of pathDirectories(input.environment, platform)) {
28796
- for (const extension of extensions) {
28797
- candidates.push({
28798
- candidate: pathFlavor.join(directory, command + extension),
28799
- source: "path"
28800
- });
28801
- }
28802
- }
28803
- if (configured !== void 0)
28804
- return candidates;
28805
- const home = resolveHomeDirectory(input);
28806
- for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
28807
- for (const extension of installRootExtensions(platform)) {
28808
- candidates.push({
28809
- candidate: pathFlavor.join(directory, spec.command + extension),
28810
- source: "install-root"
28811
- });
28812
- }
28813
- }
28814
- return candidates;
28815
- }
28816
- function resolveHarnessExecutable(spec, input, dependencies = {}) {
28817
- const platform = input.platform ?? process.platform;
28818
- const isExecutable = dependencies.isExecutable ?? ((candidate) => isExecutableFile(candidate, platform));
28819
- const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
28820
- const context = { platform, isExecutable };
28821
- for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
28822
- const executable = runnable(candidate, context);
28823
- if (executable !== void 0 && isExecutable(executable))
28824
- return { executable, source };
28825
- }
28826
- return void 0;
28827
- }
28828
-
28829
- // ../../harness-discovery/dist/installation.js
28830
- import { execFile } from "node:child_process";
28831
- import { homedir } from "node:os";
28832
- function runInstallationCommand(command, args, environment, timeout = 3e4) {
28833
- const env = withNodeRuntimeOnPath(environment);
28834
- const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
28835
- return new Promise((resolve, reject) => {
28836
- const child = execFile(invocation.command, invocation.arguments, {
28837
- env,
28838
- cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
28839
- encoding: "utf8",
28840
- timeout,
28841
- killSignal: "SIGKILL",
28842
- maxBuffer: 1024 * 1024,
28843
- windowsHide: true,
28844
- windowsVerbatimArguments: invocation.windowsVerbatimArguments
28845
- }, (error51, stdout, stderr) => {
28846
- if (error51)
28847
- reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
28848
- else
28849
- resolve((stdout || stderr).trim());
28850
- });
28851
- child.stdin?.end();
28852
- });
28853
- }
28854
- function installationVersion(value) {
28855
- if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
28856
- throw new Error("Harness returned an invalid version");
28857
- return value.trim().replace(/^v/, "");
28858
- }
28859
- function createInstallationManager(options) {
28860
- let checking;
28861
- let updating;
28862
- const check2 = () => checking ??= options.check().finally(() => {
28863
- checking = void 0;
28864
- });
28865
- return (action) => {
28866
- if (updating)
28867
- return updating;
28868
- if (action === "check")
28869
- return check2();
28870
- updating = (async () => {
28871
- const before = await check2();
28872
- if (!before.updateAvailable)
28873
- return before;
28874
- if (!before.canUpdate)
28875
- throw new Error(before.message ?? "This installation cannot be updated automatically");
28876
- await options.update(before);
28877
- const after = await check2();
28878
- if (after.currentVersion === before.currentVersion)
28879
- throw new Error("The Harness version did not change; check the native updater and retry");
28880
- return after;
28881
- })().finally(() => {
28882
- updating = void 0;
28883
- });
28884
- return updating;
28885
- };
28886
- }
28887
-
28888
29042
  // dist/command.js
28889
29043
  import { existsSync, readdirSync } from "node:fs";
28890
29044
  import path4 from "node:path";
@@ -28903,11 +29057,13 @@ function cursorDiscoverySpec(skipPinnedVersions) {
28903
29057
  } : {}
28904
29058
  };
28905
29059
  }
29060
+ var CursorNotInstalledError = class extends Error {
29061
+ };
28906
29062
  function resolveCursorExecutable(environment, command) {
28907
29063
  const input = { environment, ...command ? { command } : {} };
28908
29064
  const pinned = resolveHarnessExecutable(cursorDiscoverySpec(false), input);
28909
29065
  if (!pinned)
28910
- throw new Error("Cursor CLI is not installed; install cursor-agent or set CODEXHOST_CURSOR_COMMAND");
29066
+ throw new CursorNotInstalledError("Cursor CLI is not installed; install cursor-agent or set CODEXHOST_CURSOR_COMMAND");
28911
29067
  const explicit = command?.trim() || environment.CODEXHOST_CURSOR_COMMAND?.trim();
28912
29068
  if (explicit || !PINNED_VERSION_AGENT.test(pinned.executable))
28913
29069
  return pinned;
@@ -29051,6 +29207,99 @@ async function fetchCursorAccount(input = {}) {
29051
29207
  import { lstat, opendir, readFile as readFile2, realpath, stat } from "node:fs/promises";
29052
29208
  import path7 from "node:path";
29053
29209
 
29210
+ // ../../harness-adapter/dist/session-import.js
29211
+ var SessionImportChangedError = class extends Error {
29212
+ constructor(message = "Native Session changed during discovery; refresh and retry") {
29213
+ super(message);
29214
+ this.name = "SessionImportChangedError";
29215
+ }
29216
+ };
29217
+ function isMissingFileError(error51) {
29218
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT";
29219
+ }
29220
+ function sameFileFingerprint(left, right) {
29221
+ 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;
29222
+ }
29223
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
29224
+ if (typeof value !== "string")
29225
+ return null;
29226
+ const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
29227
+ if (!normalized)
29228
+ return null;
29229
+ if (normalized.length <= maxLength)
29230
+ return normalized;
29231
+ const characters = [...normalized];
29232
+ if (characters.length <= maxLength)
29233
+ return normalized;
29234
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
29235
+ }
29236
+ function sessionImportCandidate(input) {
29237
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
29238
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
29239
+ nativeSessionId: input.nativeSessionId,
29240
+ cwd: input.cwd,
29241
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
29242
+ updatedAt: Math.floor(time3),
29243
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
29244
+ running: typeof input.running === "boolean" ? input.running : null
29245
+ });
29246
+ return parsed.success ? parsed.data : null;
29247
+ }
29248
+ var SessionImportScope = class {
29249
+ #abort = new AbortController();
29250
+ #options;
29251
+ #pending = /* @__PURE__ */ new Set();
29252
+ constructor(options) {
29253
+ this.#options = options;
29254
+ }
29255
+ #closed() {
29256
+ return {
29257
+ ok: false,
29258
+ error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
29259
+ };
29260
+ }
29261
+ read(operation) {
29262
+ const signal = this.#abort.signal;
29263
+ if (signal.aborted)
29264
+ return Promise.resolve(this.#closed());
29265
+ let started;
29266
+ try {
29267
+ started = operation(signal);
29268
+ } catch (error51) {
29269
+ started = Promise.reject(error51 instanceof Error ? error51 : new Error("Session read failed"));
29270
+ }
29271
+ const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
29272
+ ok: false,
29273
+ error: {
29274
+ code: "unavailable",
29275
+ message: this.#options.unavailableMessage,
29276
+ retryable: true
29277
+ }
29278
+ }).finally(() => this.#pending.delete(request));
29279
+ this.#pending.add(request);
29280
+ return request;
29281
+ }
29282
+ /** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
29283
+ async resolve(operation) {
29284
+ const result = await this.read(operation);
29285
+ if (!result.ok)
29286
+ return result;
29287
+ return result.value ? { ok: true, value: result.value } : {
29288
+ ok: false,
29289
+ error: {
29290
+ code: "sessionNotFound",
29291
+ message: this.#options.notFoundMessage,
29292
+ retryable: false
29293
+ }
29294
+ };
29295
+ }
29296
+ /** Idempotent. Resolves after every started read has settled. */
29297
+ async close() {
29298
+ this.#abort.abort();
29299
+ await Promise.allSettled(this.#pending);
29300
+ }
29301
+ };
29302
+
29054
29303
  // dist/native-history.js
29055
29304
  import { existsSync as existsSync2, readFileSync, realpathSync } from "node:fs";
29056
29305
  import os2 from "node:os";
@@ -29196,8 +29445,6 @@ function cursorExecutionPolicy(ref) {
29196
29445
  // dist/session-import.js
29197
29446
  var SESSION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;
29198
29447
  var MAX_METADATA_BYTES = 1024 * 1024;
29199
- var CursorSessionChangedError = class extends Error {
29200
- };
29201
29448
  function errorCode(error51) {
29202
29449
  return typeof error51 === "object" && error51 !== null && "code" in error51 && typeof error51.code === "string" ? error51.code : void 0;
29203
29450
  }
@@ -29205,23 +29452,23 @@ async function optionalStat(file2) {
29205
29452
  try {
29206
29453
  return await lstat(file2);
29207
29454
  } catch (error51) {
29208
- if (errorCode(error51) === "ENOENT")
29455
+ if (isMissingFileError(error51))
29209
29456
  return null;
29210
29457
  throw error51;
29211
29458
  }
29212
29459
  }
29213
- function sameFile(left, right) {
29214
- 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;
29215
- }
29216
29460
  var CursorSessionImport = class {
29217
29461
  #environment;
29218
- #abort = new AbortController();
29219
- #pending = /* @__PURE__ */ new Set();
29462
+ #scope = new SessionImportScope({
29463
+ closedMessage: "Cursor Session import is closed",
29464
+ unavailableMessage: "Cursor ACP sessions could not be read; close native clients, check storage access and retry",
29465
+ notFoundMessage: "Cursor ACP Session is no longer importable"
29466
+ });
29220
29467
  constructor(environment) {
29221
29468
  this.#environment = { ...environment };
29222
29469
  }
29223
29470
  listCandidates() {
29224
- return this.#read(async (signal) => {
29471
+ return this.#scope.read(async (signal) => {
29225
29472
  const root = path7.join(cursorConfigDirectory(this.#environment), "acp-sessions");
29226
29473
  const info = await optionalStat(root);
29227
29474
  if (!info)
@@ -29239,7 +29486,7 @@ var CursorSessionImport = class {
29239
29486
  if (candidate)
29240
29487
  candidates.push(candidate);
29241
29488
  } catch (error51) {
29242
- if (!(error51 instanceof CursorSessionChangedError))
29489
+ if (!(error51 instanceof SessionImportChangedError))
29243
29490
  throw error51;
29244
29491
  }
29245
29492
  }
@@ -29256,27 +29503,15 @@ var CursorSessionImport = class {
29256
29503
  retryable: false
29257
29504
  }
29258
29505
  };
29259
- const result = await this.#read((signal) => this.#candidate(nativeSessionId, signal));
29260
- if (!result.ok)
29261
- return result;
29262
- if (!result.value)
29263
- return {
29264
- ok: false,
29265
- error: {
29266
- code: "sessionNotFound",
29267
- message: "Cursor ACP Session is no longer importable",
29268
- retryable: false
29269
- }
29270
- };
29271
- return {
29272
- ok: true,
29273
- value: {
29274
- candidate: result.value,
29506
+ return this.#scope.resolve(async (signal) => {
29507
+ const candidate = await this.#candidate(nativeSessionId, signal);
29508
+ return candidate ? {
29509
+ candidate,
29275
29510
  // Native ACP stores do not attest to --force. Imported sessions must not
29276
29511
  // acquire unattended privileges from UI defaults or a guessed locator.
29277
29512
  nativeRef: cursorNativeSessionRef(nativeSessionId, "default")
29278
- }
29279
- };
29513
+ } : null;
29514
+ });
29280
29515
  }
29281
29516
  async #candidate(id, signal) {
29282
29517
  signal.throwIfAborted();
@@ -29307,7 +29542,7 @@ var CursorSessionImport = class {
29307
29542
  const turns = readCursorNativeTurns(id, cwd, this.#environment);
29308
29543
  if (!turns.length)
29309
29544
  return null;
29310
- title = turns[0]?.text.replaceAll("\0", "").replace(/\s+/gu, " ").trim().slice(0, HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) || null;
29545
+ title = sessionImportTitle(turns[0]?.text);
29311
29546
  } catch (error51) {
29312
29547
  signal.throwIfAborted();
29313
29548
  if (["EACCES", "EPERM", "EIO", "EMFILE", "ENFILE"].includes(errorCode(error51) ?? ""))
@@ -29316,46 +29551,17 @@ var CursorSessionImport = class {
29316
29551
  }
29317
29552
  signal.throwIfAborted();
29318
29553
  const after = await Promise.all(files.map(optionalStat));
29319
- if (before.some((info, index) => !sameFile(info, after[index] ?? null)))
29320
- throw new CursorSessionChangedError("Cursor Session changed during discovery");
29321
- const parsed = harnessSessionImportCandidateSchema.safeParse({
29554
+ if (before.some((info, index) => !sameFileFingerprint(info, after[index] ?? null)))
29555
+ throw new SessionImportChangedError("Cursor Session changed during discovery");
29556
+ return sessionImportCandidate({
29322
29557
  nativeSessionId: id,
29323
29558
  cwd,
29324
29559
  title,
29325
- updatedAt: Math.floor(Math.max(database.mtimeMs, wal?.mtimeMs ?? 0)),
29326
- // A stable read does not establish that another Cursor process is idle.
29327
- running: null
29560
+ updatedAt: Math.max(database.mtimeMs, wal?.mtimeMs ?? 0)
29328
29561
  });
29329
- return parsed.success ? parsed.data : null;
29330
- }
29331
- #read(operation) {
29332
- const signal = this.#abort.signal;
29333
- if (signal.aborted)
29334
- return Promise.resolve({
29335
- ok: false,
29336
- error: {
29337
- code: "invalidState",
29338
- message: "Cursor Session import is closed",
29339
- retryable: false
29340
- }
29341
- });
29342
- const request = operation(signal).then((value) => {
29343
- signal.throwIfAborted();
29344
- return { ok: true, value };
29345
- }).catch(() => ({
29346
- ok: false,
29347
- error: {
29348
- code: signal.aborted ? "invalidState" : "unavailable",
29349
- message: signal.aborted ? "Cursor Session import is closed" : "Cursor ACP sessions could not be read; close native clients, check storage access and retry",
29350
- retryable: !signal.aborted
29351
- }
29352
- })).finally(() => this.#pending.delete(request));
29353
- this.#pending.add(request);
29354
- return request;
29355
29562
  }
29356
- async close() {
29357
- this.#abort.abort();
29358
- await Promise.allSettled(this.#pending);
29563
+ close() {
29564
+ return this.#scope.close();
29359
29565
  }
29360
29566
  };
29361
29567
 
@@ -46538,7 +46744,7 @@ var CursorInteractions = class {
46538
46744
 
46539
46745
  // dist/fork.js
46540
46746
  import { createHash as createHash2 } from "node:crypto";
46541
- import { copyFile, mkdir, mkdtemp, readdir, readFile as readFile3, realpath as realpath2, rm, writeFile } from "node:fs/promises";
46747
+ import { copyFile, mkdir, mkdtemp as mkdtemp2, readdir, readFile as readFile3, realpath as realpath2, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
46542
46748
  import { readdirSync as readdirSync2 } from "node:fs";
46543
46749
  import os3 from "node:os";
46544
46750
  import path9 from "node:path";
@@ -46709,12 +46915,12 @@ async function forkCursorSession(source, checkpoint, options, signal) {
46709
46915
  if (rewindTurn && !rewindTurn.rewindRoot)
46710
46916
  throw new Error("Cursor target has no native rewind checkpoint");
46711
46917
  const original = storeIdentity(sourceDirectory);
46712
- const temporary = await mkdtemp(path9.join(os3.tmpdir(), "codexhost-cursor-fork-"));
46918
+ const temporary = await mkdtemp2(path9.join(os3.tmpdir(), "codexhost-cursor-fork-"));
46713
46919
  let target;
46714
46920
  let committed = false;
46715
46921
  const discard = async () => {
46716
46922
  if (target && !committed)
46717
- await rm(target, { recursive: true, force: true });
46923
+ await rm2(target, { recursive: true, force: true });
46718
46924
  };
46719
46925
  try {
46720
46926
  signal.throwIfAborted();
@@ -46731,7 +46937,7 @@ async function forkCursorSession(source, checkpoint, options, signal) {
46731
46937
  if (!(error51 instanceof Error && "code" in error51 && error51.code === "ENOENT"))
46732
46938
  throw error51;
46733
46939
  }
46734
- await writeFile(path9.join(config2, "cli-config.json"), JSON.stringify({ ...settings, rewind: true }), { mode: 384 });
46940
+ await writeFile2(path9.join(config2, "cli-config.json"), JSON.stringify({ ...settings, rewind: true }), { mode: 384 });
46735
46941
  const chats = path9.join(config2, "chats", createHash2("md5").update(await realpath2(options.cwd)).digest("hex"));
46736
46942
  const copy = path9.join(chats, source.nativeSessionId);
46737
46943
  await mkdir(copy, { recursive: true });
@@ -46785,7 +46991,7 @@ async function forkCursorSession(source, checkpoint, options, signal) {
46785
46991
  throw error51;
46786
46992
  } finally {
46787
46993
  try {
46788
- await rm(temporary, { recursive: true, force: true });
46994
+ await rm2(temporary, { recursive: true, force: true });
46789
46995
  } catch (error51) {
46790
46996
  await discard();
46791
46997
  throw error51;
@@ -47402,6 +47608,7 @@ var CursorSession = class {
47402
47608
  };
47403
47609
 
47404
47610
  // ../../harness-broker/dist/client.js
47611
+ import { execFile as execFile4 } from "node:child_process";
47405
47612
  import { randomUUID as randomUUID2 } from "node:crypto";
47406
47613
  import { lstat as lstat2, readFile as readFile4 } from "node:fs/promises";
47407
47614
  import net, {} from "node:net";
@@ -47411,9 +47618,12 @@ var HARNESS_BROKER_PROTOCOL_VERSION = 1;
47411
47618
  var HARNESS_BROKER_MAX_FRAME_BYTES = 8 * 1024 * 1024;
47412
47619
  var HARNESS_BROKER_MAX_PENDING_REQUESTS = 32;
47413
47620
  var HARNESS_BROKER_REQUEST_TIMEOUT_MS = 15e3;
47621
+ var HARNESS_BROKER_IDLE_TIMEOUT_MS = 60 * 60 * 1e3;
47622
+ var HARNESS_BROKER_RETIRING_ERROR_CODE = "brokerRetiring";
47414
47623
  var harnessBrokerMethodSchema = external_exports.enum([
47415
47624
  "adapter.inspect",
47416
47625
  "adapter.inspectAccount",
47626
+ "adapter.credits",
47417
47627
  "adapter.open",
47418
47628
  "adapter.subagent.readSnapshot",
47419
47629
  "session.readSnapshot",
@@ -47531,6 +47741,14 @@ function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId
47531
47741
  return path11.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
47532
47742
  return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path11.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
47533
47743
  }
47744
+ function harnessBrokerLaunchAgentLabel(harnessId = "claude-code") {
47745
+ harnessPluginIdSchema.parse(harnessId);
47746
+ return harnessId === "claude-code" ? "ai.bytepioneer.codexhost.native-harness-broker" : `ai.bytepioneer.codexhost.${harnessId}-broker`;
47747
+ }
47748
+ function harnessBrokerLaunchAgentPlistPath(environment = process.env, harnessId = "claude-code") {
47749
+ const home = environment.HOME || os4.homedir();
47750
+ return path11.join(home, "Library", "LaunchAgents", `${harnessBrokerLaunchAgentLabel(harnessId)}.plist`);
47751
+ }
47534
47752
 
47535
47753
  // ../../harness-broker/dist/validation.js
47536
47754
  var cwdSchema = external_exports.string().min(1).max(16384);
@@ -47836,10 +48054,55 @@ async function readDescriptor(descriptorPath) {
47836
48054
  try {
47837
48055
  process.kill(descriptor.ownerPid, 0);
47838
48056
  } catch {
47839
- throw new Error("Aqua Harness broker owner process is unavailable");
48057
+ throw new BrokerNotRunningError("its owner process has exited");
47840
48058
  }
47841
48059
  return descriptor;
47842
48060
  }
48061
+ var BrokerNotRunningError = class extends Error {
48062
+ };
48063
+ var BrokerRetiringError = class extends Error {
48064
+ };
48065
+ var BrokerRequestNotDeliveredError = class extends Error {
48066
+ };
48067
+ var HarnessNotInstalledError = class extends Error {
48068
+ };
48069
+ var BROKER_NOT_RUNNING_CODES = /* @__PURE__ */ new Set(["ENOENT", "ECONNREFUSED"]);
48070
+ var BROKER_START_TIMEOUT_MS = 15e3;
48071
+ var BROKER_START_POLL_MS = 250;
48072
+ function classifyConnectFailure(error51) {
48073
+ if (error51 instanceof BrokerNotRunningError)
48074
+ return error51;
48075
+ const code = error51?.code;
48076
+ if (code && BROKER_NOT_RUNNING_CODES.has(code)) {
48077
+ return new BrokerNotRunningError(code === "ENOENT" ? "its descriptor or socket is missing" : "its socket refused the connection");
48078
+ }
48079
+ return error51 instanceof Error ? error51 : new Error(String(error51));
48080
+ }
48081
+ function describeBrokerFailure(error51, harnessId) {
48082
+ if (error51 instanceof BrokerNotRunningError) {
48083
+ 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}`;
48084
+ }
48085
+ return error51 instanceof Error ? error51.message : String(error51);
48086
+ }
48087
+ function runLaunchctl(arguments_) {
48088
+ return new Promise((resolve) => {
48089
+ execFile4("/bin/launchctl", arguments_, { timeout: 1e4 }, (error51) => resolve(!error51));
48090
+ });
48091
+ }
48092
+ async function startBrokerLaunchAgent(harnessId, environment) {
48093
+ const uid = process.getuid?.();
48094
+ if (uid === void 0)
48095
+ return;
48096
+ const target = `gui/${uid}/${harnessBrokerLaunchAgentLabel(harnessId)}`;
48097
+ if (await runLaunchctl(["kickstart", target]))
48098
+ return;
48099
+ await runLaunchctl([
48100
+ "bootstrap",
48101
+ `gui/${uid}`,
48102
+ harnessBrokerLaunchAgentPlistPath(environment, harnessId)
48103
+ ]);
48104
+ await runLaunchctl(["kickstart", target]);
48105
+ }
47843
48106
  var BrokerConnection = class _BrokerConnection {
47844
48107
  #onClose;
47845
48108
  onClose(callback) {
@@ -47863,21 +48126,31 @@ var BrokerConnection = class _BrokerConnection {
47863
48126
  socket.once("error", (error51) => this.#fail(error51));
47864
48127
  }
47865
48128
  static async connect(descriptorPath, harnessId) {
47866
- const descriptor = await readDescriptor(descriptorPath);
47867
- if (descriptor.harnessId !== harnessId)
47868
- throw new Error("Aqua broker belongs to another Harness");
47869
- const socket = net.createConnection(descriptor.socketPath);
47870
- await new Promise((resolve, reject) => {
47871
- const timeout = setTimeout(() => reject(new Error("Timed out connecting to Aqua Harness broker")), HARNESS_BROKER_REQUEST_TIMEOUT_MS);
47872
- socket.once("connect", () => {
47873
- clearTimeout(timeout);
47874
- resolve();
47875
- });
47876
- socket.once("error", (error51) => {
47877
- clearTimeout(timeout);
47878
- reject(error51);
48129
+ let descriptor;
48130
+ let socket;
48131
+ let connecting;
48132
+ try {
48133
+ descriptor = await readDescriptor(descriptorPath);
48134
+ if (descriptor.harnessId !== harnessId)
48135
+ throw new Error("Aqua broker belongs to another Harness");
48136
+ connecting = net.createConnection(descriptor.socketPath);
48137
+ const pending = connecting;
48138
+ await new Promise((resolve, reject) => {
48139
+ const timeout = setTimeout(() => reject(new Error("Timed out connecting to Aqua Harness broker")), HARNESS_BROKER_REQUEST_TIMEOUT_MS);
48140
+ pending.once("connect", () => {
48141
+ clearTimeout(timeout);
48142
+ resolve();
48143
+ });
48144
+ pending.once("error", (error51) => {
48145
+ clearTimeout(timeout);
48146
+ reject(error51);
48147
+ });
47879
48148
  });
47880
- });
48149
+ socket = pending;
48150
+ } catch (error51) {
48151
+ connecting?.destroy();
48152
+ throw classifyConnectFailure(error51);
48153
+ }
47881
48154
  const connection = new _BrokerConnection(descriptor, socket);
47882
48155
  const hello = connection.#waitForHello();
47883
48156
  await writeBrokerFrame(socket, {
@@ -47930,15 +48203,24 @@ var BrokerConnection = class _BrokerConnection {
47930
48203
  }, HARNESS_BROKER_REQUEST_TIMEOUT_MS);
47931
48204
  this.#pending.set(id, { resolve, reject, timeout });
47932
48205
  });
47933
- await writeBrokerFrame(this.#socket, {
47934
- version: HARNESS_BROKER_PROTOCOL_VERSION,
47935
- generation: this.#descriptor.generation,
47936
- sequence: this.#inputSequence,
47937
- kind: "request",
47938
- id,
47939
- method,
47940
- params
47941
- });
48206
+ try {
48207
+ await writeBrokerFrame(this.#socket, {
48208
+ version: HARNESS_BROKER_PROTOCOL_VERSION,
48209
+ generation: this.#descriptor.generation,
48210
+ sequence: this.#inputSequence,
48211
+ kind: "request",
48212
+ id,
48213
+ method,
48214
+ params
48215
+ });
48216
+ } catch (error51) {
48217
+ const pending = this.#pending.get(id);
48218
+ if (pending)
48219
+ clearTimeout(pending.timeout);
48220
+ this.#pending.delete(id);
48221
+ response.catch(() => void 0);
48222
+ throw new BrokerRequestNotDeliveredError(error51 instanceof Error ? error51.message : String(error51));
48223
+ }
47942
48224
  return response;
47943
48225
  }
47944
48226
  close() {
@@ -47982,6 +48264,8 @@ var BrokerConnection = class _BrokerConnection {
47982
48264
  this.#pending.delete(frame.id);
47983
48265
  if (frame.ok)
47984
48266
  pending.resolve(frame.value);
48267
+ else if (frame.error?.code === HARNESS_BROKER_RETIRING_ERROR_CODE)
48268
+ pending.reject(new BrokerRetiringError(frame.error.message));
47985
48269
  else
47986
48270
  pending.reject(new Error(frame.error?.message ?? "Broker request failed"));
47987
48271
  }
@@ -48207,17 +48491,19 @@ var BrokeredHarnessAdapter = class {
48207
48491
  harnessId;
48208
48492
  #descriptorPath;
48209
48493
  #forwardEnvironment;
48494
+ #isInstalled;
48495
+ #startBroker;
48496
+ #startTimeoutMs;
48210
48497
  #connection = null;
48211
48498
  #closed = false;
48499
+ #credits = null;
48500
+ #creditsRefresh = null;
48212
48501
  subagents = {
48213
48502
  readSnapshot: async (input) => {
48214
48503
  try {
48215
- return parseHarnessResult(await (await this.#connect()).request("adapter.subagent.readSnapshot", input));
48504
+ return parseHarnessResult(await this.#request("adapter.subagent.readSnapshot", input));
48216
48505
  } catch (error51) {
48217
- return {
48218
- ok: false,
48219
- error: unavailable(error51 instanceof Error ? error51.message : String(error51))
48220
- };
48506
+ return { ok: false, error: this.#error(error51) };
48221
48507
  }
48222
48508
  }
48223
48509
  };
@@ -48229,12 +48515,39 @@ var BrokeredHarnessAdapter = class {
48229
48515
  if (input.liveCommandCatalog)
48230
48516
  this.liveCommandCatalog = true;
48231
48517
  this.#descriptorPath = input.descriptorPath ?? defaultHarnessBrokerDescriptorPath(input.environment, this.harnessId);
48518
+ this.#isInstalled = input.isInstalled;
48519
+ const environment = input.environment ?? process.env;
48520
+ this.#startBroker = input.startBroker === false ? void 0 : input.startBroker ?? (process.platform === "darwin" && !input.descriptorPath ? () => startBrokerLaunchAgent(this.harnessId, environment) : void 0);
48521
+ this.#startTimeoutMs = input.startTimeoutMs ?? BROKER_START_TIMEOUT_MS;
48522
+ }
48523
+ credits() {
48524
+ return this.#credits;
48525
+ }
48526
+ refreshCredits() {
48527
+ if (this.#closed)
48528
+ return Promise.resolve(null);
48529
+ if (this.#creditsRefresh)
48530
+ return this.#creditsRefresh;
48531
+ this.#creditsRefresh = this.#readCredits().finally(() => {
48532
+ this.#creditsRefresh = null;
48533
+ });
48534
+ return this.#creditsRefresh;
48535
+ }
48536
+ async #readCredits() {
48537
+ try {
48538
+ const value = await this.#request("adapter.credits", {}, true);
48539
+ const credits = accountCreditsSnapshotSchema.nullable().parse(value);
48540
+ if (!this.#closed)
48541
+ this.#credits = credits;
48542
+ } catch {
48543
+ }
48544
+ return this.#credits;
48232
48545
  }
48233
48546
  async inspectAccount() {
48234
48547
  if (this.#closed)
48235
48548
  return null;
48236
48549
  try {
48237
- const value = await (await this.#connect()).request("adapter.inspectAccount", {});
48550
+ const value = await this.#request("adapter.inspectAccount", {}, true);
48238
48551
  return harnessAccountSnapshotSchema.nullable().parse(value);
48239
48552
  } catch {
48240
48553
  return null;
@@ -48244,33 +48557,46 @@ var BrokeredHarnessAdapter = class {
48244
48557
  if (this.#closed)
48245
48558
  return failedInspection("Aqua Harness broker adapter is closed");
48246
48559
  try {
48247
- return harnessInspectionSchema.parse(await (await this.#connect()).request("adapter.inspect", input));
48560
+ return harnessInspectionSchema.parse(await this.#request("adapter.inspect", input, true));
48248
48561
  } catch (error51) {
48249
48562
  this.#connection = null;
48250
- return failedInspection(error51 instanceof Error ? error51.message : String(error51));
48563
+ if (error51 instanceof HarnessNotInstalledError)
48564
+ return { status: "notInstalled", error: this.#error(error51) };
48565
+ return failedInspection(describeBrokerFailure(error51, this.harnessId));
48251
48566
  }
48252
48567
  }
48253
48568
  async open(input) {
48254
48569
  if (this.#closed)
48255
48570
  return { ok: false, error: unavailable("Aqua Harness broker adapter is closed", false) };
48571
+ const safeInput = { ...input };
48572
+ delete safeInput.environment;
48573
+ if (this.#forwardEnvironment && input.environment) {
48574
+ const allowed = [
48575
+ "CODEXHOST_CLI_PATH",
48576
+ "CODEXHOST_CLI_NODE_PATH",
48577
+ "CODEXHOST_RUNTIME_ENDPOINT",
48578
+ "CODEXHOST_RUNTIME_TOKEN",
48579
+ "CODEXHOST_THREAD_ID"
48580
+ ];
48581
+ const environment = Object.fromEntries(Object.entries(input.environment).filter(([key, value]) => allowed.includes(key) && value !== void 0));
48582
+ if (Object.keys(environment).length)
48583
+ safeInput.environment = environment;
48584
+ }
48256
48585
  let connection;
48257
48586
  try {
48258
- const safeInput = { ...input };
48259
- delete safeInput.environment;
48260
- if (this.#forwardEnvironment && input.environment) {
48261
- const allowed = [
48262
- "CODEXHOST_CLI_PATH",
48263
- "CODEXHOST_CLI_NODE_PATH",
48264
- "CODEXHOST_RUNTIME_ENDPOINT",
48265
- "CODEXHOST_RUNTIME_TOKEN",
48266
- "CODEXHOST_THREAD_ID"
48267
- ];
48268
- const environment = Object.fromEntries(Object.entries(input.environment).filter(([key, value]) => allowed.includes(key) && value !== void 0));
48269
- if (Object.keys(environment).length)
48270
- safeInput.environment = environment;
48271
- }
48272
- connection = await this.#connect();
48273
- const result = parseHarnessResult(await connection.request("adapter.open", safeInput));
48587
+ let value;
48588
+ for (let attempt = 0; ; attempt += 1) {
48589
+ connection = await this.#connect();
48590
+ try {
48591
+ value = await connection.request("adapter.open", safeInput);
48592
+ break;
48593
+ } catch (error51) {
48594
+ if (attempt > 0 || !(error51 instanceof BrokerRetiringError || error51 instanceof BrokerRequestNotDeliveredError))
48595
+ throw error51;
48596
+ this.#connection = null;
48597
+ }
48598
+ }
48599
+ const result = parseHarnessResult(value);
48274
48600
  if (!result.ok)
48275
48601
  return result;
48276
48602
  const session = new BrokeredHarnessSession(connection, parseSessionMetadata(result.value), this.harnessId, safeInput, () => this.#connect(), () => {
@@ -48281,25 +48607,51 @@ var BrokeredHarnessAdapter = class {
48281
48607
  } catch (error51) {
48282
48608
  connection?.close();
48283
48609
  this.#connection = null;
48284
- return {
48285
- ok: false,
48286
- error: unavailable(error51 instanceof Error ? error51.message : String(error51))
48287
- };
48610
+ return { ok: false, error: this.#error(error51) };
48288
48611
  }
48289
48612
  }
48290
48613
  async close() {
48291
48614
  this.#closed = true;
48615
+ this.#credits = null;
48292
48616
  await Promise.allSettled([...this.#sessions].map((session) => session.close()));
48293
48617
  this.#sessions.clear();
48294
48618
  const connection = await this.#connection?.catch(() => null);
48295
48619
  await connection?.dispose();
48296
48620
  this.#connection = null;
48297
48621
  }
48622
+ #error(error51) {
48623
+ if (error51 instanceof HarnessNotInstalledError)
48624
+ return {
48625
+ code: "notInstalled",
48626
+ message: error51.message,
48627
+ retryable: false,
48628
+ stage: "harnessBroker"
48629
+ };
48630
+ return unavailable(describeBrokerFailure(error51, this.harnessId));
48631
+ }
48632
+ /**
48633
+ * Sends one adapter-level request. A broker that retired between requests refuses it
48634
+ * unprocessed, so it is retried once on a fresh broker. Idempotent reads also retry
48635
+ * once after a plain disconnect.
48636
+ */
48637
+ async #request(method, params, idempotent = false) {
48638
+ for (let attempt = 0; ; attempt += 1) {
48639
+ const connection = await this.#connect();
48640
+ try {
48641
+ return await connection.request(method, params);
48642
+ } catch (error51) {
48643
+ const retryable = error51 instanceof BrokerRetiringError || error51 instanceof BrokerRequestNotDeliveredError || idempotent && connection.closed;
48644
+ if (attempt > 0 || !retryable)
48645
+ throw error51;
48646
+ this.#connection = null;
48647
+ }
48648
+ }
48649
+ }
48298
48650
  #connect() {
48299
48651
  if (this.#closed)
48300
48652
  return Promise.reject(new Error("Aqua Harness broker adapter is closed"));
48301
48653
  if (!this.#connection) {
48302
- const pending = BrokerConnection.connect(this.#descriptorPath, this.harnessId).then((connection) => {
48654
+ const pending = this.#establish().then((connection) => {
48303
48655
  connection.onClose(() => {
48304
48656
  if (this.#connection === pending)
48305
48657
  this.#connection = null;
@@ -48314,21 +48666,57 @@ var BrokeredHarnessAdapter = class {
48314
48666
  }
48315
48667
  return this.#connection;
48316
48668
  }
48669
+ async #establish() {
48670
+ try {
48671
+ return await BrokerConnection.connect(this.#descriptorPath, this.harnessId);
48672
+ } catch (error51) {
48673
+ if (!(error51 instanceof BrokerNotRunningError) || !this.#startBroker)
48674
+ throw error51;
48675
+ }
48676
+ if (this.#isInstalled && !this.#isInstalled()) {
48677
+ throw new HarnessNotInstalledError(`${this.harnessId} is not installed on this Mac`);
48678
+ }
48679
+ const deadline = Date.now() + this.#startTimeoutMs;
48680
+ for (; ; ) {
48681
+ await this.#startBroker();
48682
+ try {
48683
+ return await BrokerConnection.connect(this.#descriptorPath, this.harnessId);
48684
+ } catch (error51) {
48685
+ if (!(error51 instanceof BrokerNotRunningError) || Date.now() >= deadline)
48686
+ throw error51;
48687
+ }
48688
+ await new Promise((resolve) => setTimeout(resolve, BROKER_START_POLL_MS));
48689
+ }
48690
+ }
48317
48691
  };
48318
48692
 
48319
48693
  // dist/plugin.js
48320
48694
  function createHarnessAdapter(context) {
48321
- if (context.platform === "darwin" && context.managedRemoteHost)
48695
+ if (context.platform === "darwin" && context.managedRemoteHost) {
48696
+ const environment2 = { ...context.environment };
48322
48697
  return new BrokeredHarnessAdapter({
48323
48698
  harnessId: "cursor-cli",
48324
48699
  forwardDelegationEnvironment: true,
48325
48700
  commandCatalog: CURSOR_COMMAND_CATALOG,
48326
48701
  liveCommandCatalog: true,
48327
- environment: { ...context.environment }
48702
+ environment: environment2,
48703
+ isInstalled: () => {
48704
+ try {
48705
+ resolveCursorExecutable(environment2);
48706
+ return true;
48707
+ } catch (error51) {
48708
+ return !(error51 instanceof CursorNotInstalledError);
48709
+ }
48710
+ }
48328
48711
  });
48712
+ }
48329
48713
  const environment = { ...context.environment };
48330
48714
  return Object.assign(new CursorAdapter({ environment }), {
48331
- installation: createCursorInstallation(environment)
48715
+ installation: createCursorInstallation(environment),
48716
+ install: createHarnessInstaller(environment, {
48717
+ posix: "https://cursor.com/install",
48718
+ windows: "https://cursor.com/install?win32=true"
48719
+ })
48332
48720
  });
48333
48721
  }
48334
48722
  export {