@codexhost/cli-darwin-x64 0.10.2 → 0.12.0

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.
Files changed (33) hide show
  1. package/README.md +1 -1
  2. package/THIRD_PARTY_NOTICES.txt +4 -0
  3. package/app/codexhost-distribution.json +1 -1
  4. package/app/console-server.mjs +18001 -0
  5. package/app/console-web.js +27674 -0
  6. package/app/desktop-controller.mjs +452 -110
  7. package/app/host-runtime.mjs +6670 -1272
  8. package/app/plugins/antigravity/plugin.mjs +686 -305
  9. package/app/plugins/claude-code/plugin.mjs +2283 -1450
  10. package/app/plugins/codebuddy/plugin.mjs +1272 -506
  11. package/app/plugins/cursor-cli/manifest.json +1 -1
  12. package/app/plugins/cursor-cli/plugin.mjs +1295 -497
  13. package/app/plugins/deepseek-harness/plugin.mjs +4718 -4925
  14. package/app/plugins/enabled.json +2 -1
  15. package/app/plugins/grok/plugin.mjs +1012 -369
  16. package/app/plugins/hermes/plugin.mjs +18587 -22714
  17. package/app/plugins/kimi-code/plugin.mjs +1283 -355
  18. package/app/plugins/kiro-cli/plugin.mjs +840 -299
  19. package/app/plugins/omp/plugin.mjs +1045 -328
  20. package/app/plugins/opencode/plugin.mjs +5341 -1686
  21. package/app/plugins/pi/plugin.mjs +1343 -534
  22. package/app/plugins/qoder/plugin.mjs +913 -258
  23. package/app/plugins/qoder-cn/plugin.mjs +712 -49
  24. package/app/plugins/workbuddy/plugin.mjs +531 -44
  25. package/app/plugins/zcode/assets/icon.svg +8 -0
  26. package/app/plugins/zcode/manifest.json +14 -0
  27. package/app/plugins/zcode/plugin.mjs +19202 -0
  28. package/app/renderer-extension.js +5011 -1899
  29. package/bin/codexhost +0 -0
  30. package/libexec/codexhost-shim +0 -0
  31. package/libexec/codexhost-updater +0 -0
  32. package/licenses/OpenCode-v2-Client-LICENSE.txt +21 -0
  33. package/package.json +1 -1
@@ -3229,8 +3229,8 @@ var require_utils = __commonJS({
3229
3229
  }
3230
3230
  return ind;
3231
3231
  }
3232
- function removeDotSegments(path4) {
3233
- let input = path4;
3232
+ function removeDotSegments(path7) {
3233
+ let input = path7;
3234
3234
  const output = [];
3235
3235
  let nextSlash = -1;
3236
3236
  let len = 0;
@@ -3482,8 +3482,8 @@ var require_schemes = __commonJS({
3482
3482
  wsComponent.secure = void 0;
3483
3483
  }
3484
3484
  if (wsComponent.resourceName) {
3485
- const [path4, query] = wsComponent.resourceName.split("?");
3486
- wsComponent.path = path4 && path4 !== "/" ? path4 : void 0;
3485
+ const [path7, query] = wsComponent.resourceName.split("?");
3486
+ wsComponent.path = path7 && path7 !== "/" ? path7 : void 0;
3487
3487
  wsComponent.query = query;
3488
3488
  wsComponent.resourceName = void 0;
3489
3489
  }
@@ -12590,9 +12590,412 @@ var require_dist = __commonJS({
12590
12590
  }
12591
12591
  });
12592
12592
 
12593
+ // ../../harness-discovery/dist/environment.js
12594
+ import fs from "node:fs";
12595
+ import path from "node:path";
12596
+ function targetPath(platform) {
12597
+ return platform === "win32" ? path.win32 : path.posix;
12598
+ }
12599
+ function environmentValue(environment, name) {
12600
+ const lowered = name.toLowerCase();
12601
+ for (const [key, value] of Object.entries(environment)) {
12602
+ if (key.toLowerCase() === lowered)
12603
+ return value;
12604
+ }
12605
+ return void 0;
12606
+ }
12607
+ function pathDelimiter(platform) {
12608
+ return platform === "win32" ? ";" : ":";
12609
+ }
12610
+ function pathDirectories(environment, platform) {
12611
+ return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
12612
+ }
12613
+ function executableExtensions(command, platform, environment) {
12614
+ if (platform !== "win32")
12615
+ return [""];
12616
+ if (targetPath(platform).extname(command) !== "")
12617
+ return [""];
12618
+ return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
12619
+ }
12620
+ function isExecutableFile(filePath, platform) {
12621
+ try {
12622
+ fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
12623
+ return fs.statSync(filePath).isFile();
12624
+ } catch {
12625
+ return false;
12626
+ }
12627
+ }
12628
+ function subdirectoryNames(directory) {
12629
+ try {
12630
+ return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
12631
+ } catch {
12632
+ return [];
12633
+ }
12634
+ }
12635
+ function newestFirst(names) {
12636
+ return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
12637
+ }
12638
+
12639
+ // ../../harness-discovery/dist/invocation.js
12640
+ import path2 from "node:path";
12641
+ function commandInvocation(command, arguments_, environment, platform = process.platform) {
12642
+ const extension = path2.win32.extname(command).toLowerCase();
12643
+ if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
12644
+ return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
12645
+ }
12646
+ const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
12647
+ const commandLine = [command, ...arguments_].map(quote).join(" ");
12648
+ return {
12649
+ command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
12650
+ arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
12651
+ windowsVerbatimArguments: true
12652
+ };
12653
+ }
12654
+
12655
+ // ../../harness-discovery/dist/node-runtime.js
12656
+ import path3 from "node:path";
12657
+ function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
12658
+ const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
12659
+ const delimiter = platform === "win32" ? ";" : ":";
12660
+ const runtimeDirectory = path3.dirname(runtimeExecutable);
12661
+ const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
12662
+ const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
12663
+ if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
12664
+ directories.push(runtimeDirectory);
12665
+ }
12666
+ return { ...environment, [pathKey]: directories.join(delimiter) };
12667
+ }
12668
+
12669
+ // ../../harness-discovery/dist/resolve.js
12670
+ import os from "node:os";
12671
+
12672
+ // ../../harness-discovery/dist/version-managers.js
12673
+ function versionManagerBinaryDirectories(context) {
12674
+ const { platform, environment, home } = context;
12675
+ const list = context.subdirectories ?? subdirectoryNames;
12676
+ const pathFlavor = targetPath(platform);
12677
+ const value = (name) => environmentValue(environment, name);
12678
+ const directories = [];
12679
+ const versioned = (root, ...tail) => {
12680
+ for (const version2 of newestFirst(list(root))) {
12681
+ directories.push(pathFlavor.join(root, version2, ...tail));
12682
+ }
12683
+ };
12684
+ if (platform === "win32") {
12685
+ const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
12686
+ const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
12687
+ versioned(pathFlavor.join(appData, "nvm"));
12688
+ versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
12689
+ directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
12690
+ directories.push(pathFlavor.join(home, ".bun", "bin"));
12691
+ const pnpmHome2 = value("PNPM_HOME");
12692
+ if (pnpmHome2)
12693
+ directories.push(pnpmHome2);
12694
+ directories.push(pathFlavor.join(localAppData, "pnpm"));
12695
+ return directories;
12696
+ }
12697
+ versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
12698
+ const fnmRoots = [
12699
+ value("FNM_DIR"),
12700
+ pathFlavor.join(home, ".local", "share", "fnm"),
12701
+ pathFlavor.join(home, "Library", "Application Support", "fnm")
12702
+ ].filter((root) => root !== void 0);
12703
+ for (const root of fnmRoots) {
12704
+ versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
12705
+ }
12706
+ const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
12707
+ versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
12708
+ directories.push(pathFlavor.join(voltaHome, "bin"));
12709
+ const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
12710
+ versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
12711
+ directories.push(pathFlavor.join(asdfHome, "shims"));
12712
+ const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
12713
+ versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
12714
+ directories.push(pathFlavor.join(nodenvHome, "shims"));
12715
+ versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
12716
+ directories.push(pathFlavor.join(home, ".bun", "bin"));
12717
+ const pnpmHome = value("PNPM_HOME");
12718
+ if (pnpmHome)
12719
+ directories.push(pnpmHome);
12720
+ directories.push(pathFlavor.join(home, "Library", "pnpm"));
12721
+ directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
12722
+ for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
12723
+ for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
12724
+ directories.push(pathFlavor.join(prefix, formula, "bin"));
12725
+ }
12726
+ }
12727
+ return directories;
12728
+ }
12729
+
12730
+ // ../../harness-discovery/dist/resolve.js
12731
+ var VERSION_MANAGER_ROOTS = "<version-managers>";
12732
+ function installRootExtensions(platform) {
12733
+ return platform === "win32" ? [".exe", ".cmd"] : [""];
12734
+ }
12735
+ function resolveHomeDirectory(input) {
12736
+ return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
12737
+ }
12738
+ function templateVariables(environment, platform, home) {
12739
+ const pathFlavor = targetPath(platform);
12740
+ return {
12741
+ HOME: home,
12742
+ USERPROFILE: home,
12743
+ APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
12744
+ LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
12745
+ };
12746
+ }
12747
+ function joinTemplate(platform, value) {
12748
+ const pathFlavor = targetPath(platform);
12749
+ const segments = value.split("/");
12750
+ const head = segments[0] ?? "";
12751
+ const tail = segments.slice(1);
12752
+ if (head === "")
12753
+ return pathFlavor.join(pathFlavor.sep, ...tail);
12754
+ return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
12755
+ }
12756
+ function expandInstallRoot(template, environment, platform, home) {
12757
+ const variables = templateVariables(environment, platform, home);
12758
+ let unresolved = false;
12759
+ const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
12760
+ const value = variables[name] ?? environmentValue(environment, name);
12761
+ if (value === void 0 || value === "") {
12762
+ unresolved = true;
12763
+ return "";
12764
+ }
12765
+ return value;
12766
+ });
12767
+ return unresolved ? void 0 : joinTemplate(platform, substituted);
12768
+ }
12769
+ function installRootDirectories(spec, input, dependencies, platform, home) {
12770
+ const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
12771
+ const directories = [];
12772
+ for (const template of templates) {
12773
+ if (template === VERSION_MANAGER_ROOTS) {
12774
+ directories.push(...versionManagerBinaryDirectories({
12775
+ platform,
12776
+ environment: input.environment,
12777
+ home,
12778
+ ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
12779
+ }));
12780
+ continue;
12781
+ }
12782
+ const directory = expandInstallRoot(template, input.environment, platform, home);
12783
+ if (directory !== void 0)
12784
+ directories.push(directory);
12785
+ }
12786
+ return directories;
12787
+ }
12788
+ function harnessCandidates(spec, input, dependencies = {}) {
12789
+ const platform = input.platform ?? process.platform;
12790
+ const pathFlavor = targetPath(platform);
12791
+ const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
12792
+ const command = configured ?? spec.command;
12793
+ if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
12794
+ return [{ candidate: command, source: "configured" }];
12795
+ }
12796
+ const candidates = [];
12797
+ const extensions = executableExtensions(command, platform, input.environment);
12798
+ for (const directory of pathDirectories(input.environment, platform)) {
12799
+ for (const extension of extensions) {
12800
+ candidates.push({
12801
+ candidate: pathFlavor.join(directory, command + extension),
12802
+ source: "path"
12803
+ });
12804
+ }
12805
+ }
12806
+ if (configured !== void 0)
12807
+ return candidates;
12808
+ const home = resolveHomeDirectory(input);
12809
+ for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
12810
+ for (const extension of installRootExtensions(platform)) {
12811
+ candidates.push({
12812
+ candidate: pathFlavor.join(directory, spec.command + extension),
12813
+ source: "install-root"
12814
+ });
12815
+ }
12816
+ }
12817
+ return candidates;
12818
+ }
12819
+ function resolveHarnessExecutable(spec, input, dependencies = {}) {
12820
+ const platform = input.platform ?? process.platform;
12821
+ const isExecutable = dependencies.isExecutable ?? ((candidate) => isExecutableFile(candidate, platform));
12822
+ const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
12823
+ const context = { platform, isExecutable };
12824
+ for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
12825
+ const executable = runnable(candidate, context);
12826
+ if (executable !== void 0 && isExecutable(executable))
12827
+ return { executable, source };
12828
+ }
12829
+ return void 0;
12830
+ }
12831
+
12832
+ // ../../harness-discovery/dist/installation.js
12833
+ import { execFile } from "node:child_process";
12834
+ import { homedir } from "node:os";
12835
+ function runInstallationCommand(command, args, environment, timeout = 3e4) {
12836
+ const env = withNodeRuntimeOnPath(environment);
12837
+ const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
12838
+ return new Promise((resolve, reject) => {
12839
+ const child = execFile(invocation.command, invocation.arguments, {
12840
+ env,
12841
+ cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
12842
+ encoding: "utf8",
12843
+ timeout,
12844
+ killSignal: "SIGKILL",
12845
+ maxBuffer: 1024 * 1024,
12846
+ windowsHide: true,
12847
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments
12848
+ }, (error51, stdout, stderr) => {
12849
+ if (error51)
12850
+ reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
12851
+ else
12852
+ resolve((stdout || stderr).trim());
12853
+ });
12854
+ child.stdin?.end();
12855
+ });
12856
+ }
12857
+ function installationVersion(value) {
12858
+ if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
12859
+ throw new Error("Harness returned an invalid version");
12860
+ return value.trim().replace(/^v/, "");
12861
+ }
12862
+ function versionFromOutput(output) {
12863
+ return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
12864
+ }
12865
+ function newerInstallationVersion(current, latest) {
12866
+ const a = installationVersion(current).replace(/\+.*/, "");
12867
+ const b = installationVersion(latest).replace(/\+.*/, "");
12868
+ const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
12869
+ const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
12870
+ for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
12871
+ if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
12872
+ return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
12873
+ }
12874
+ const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
12875
+ const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
12876
+ if (!preA.length || !preB.length)
12877
+ return !!preA.length && !preB.length;
12878
+ for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
12879
+ const x3 = preA[i];
12880
+ const y = preB[i];
12881
+ if (x3 === y)
12882
+ continue;
12883
+ if (x3 === void 0 || y === void 0)
12884
+ return x3 === void 0;
12885
+ const numericX = /^\d+$/.test(x3);
12886
+ const numericY = /^\d+$/.test(y);
12887
+ if (numericX && numericY) {
12888
+ if (BigInt(x3) === BigInt(y))
12889
+ continue;
12890
+ return BigInt(y) > BigInt(x3);
12891
+ }
12892
+ if (numericX !== numericY)
12893
+ return numericX;
12894
+ return y > x3;
12895
+ }
12896
+ return false;
12897
+ }
12898
+ function createInstallationManager(options) {
12899
+ let checking;
12900
+ let updating;
12901
+ const check2 = () => checking ??= options.check().finally(() => {
12902
+ checking = void 0;
12903
+ });
12904
+ return (action) => {
12905
+ if (updating)
12906
+ return updating;
12907
+ if (action === "check")
12908
+ return check2();
12909
+ updating = (async () => {
12910
+ const before = await check2();
12911
+ if (!before.updateAvailable)
12912
+ return before;
12913
+ if (!before.canUpdate)
12914
+ throw new Error(before.message ?? "This installation cannot be updated automatically");
12915
+ await options.update(before);
12916
+ const after = await check2();
12917
+ if (after.currentVersion === before.currentVersion)
12918
+ throw new Error("The Harness version did not change; check the native updater and retry");
12919
+ return after;
12920
+ })().finally(() => {
12921
+ updating = void 0;
12922
+ });
12923
+ return updating;
12924
+ };
12925
+ }
12926
+ async function fetchInstallationText(url2) {
12927
+ const request = async () => {
12928
+ const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
12929
+ if (!response.ok)
12930
+ throw new Error("Could not check the latest Harness version");
12931
+ return response.text();
12932
+ };
12933
+ try {
12934
+ return await request();
12935
+ } catch (error51) {
12936
+ if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
12937
+ throw error51;
12938
+ return request();
12939
+ }
12940
+ }
12941
+
12942
+ // ../../harness-discovery/dist/installer.js
12943
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
12944
+ import { tmpdir } from "node:os";
12945
+ import { join } from "node:path";
12946
+ function createHarnessInstaller(environment, source) {
12947
+ return async () => {
12948
+ if (!["darwin", "linux", "win32"].includes(process.platform))
12949
+ throw new Error("Unsupported installation platform");
12950
+ const env = withNodeRuntimeOnPath(environment);
12951
+ if ("npm" in source) {
12952
+ const npm = resolveHarnessExecutable({
12953
+ id: "npm",
12954
+ command: "npm",
12955
+ installRoots: {
12956
+ posix: [
12957
+ "~/.npm-global/bin",
12958
+ "~/.local/bin",
12959
+ VERSION_MANAGER_ROOTS,
12960
+ "/opt/homebrew/bin",
12961
+ "/usr/local/bin",
12962
+ "/usr/bin"
12963
+ ],
12964
+ windows: [
12965
+ "${APPDATA}/npm",
12966
+ VERSION_MANAGER_ROOTS,
12967
+ "${ProgramFiles}/nodejs",
12968
+ "${LOCALAPPDATA}/Programs/nodejs"
12969
+ ]
12970
+ }
12971
+ }, { environment: env });
12972
+ if (!npm)
12973
+ throw new Error("Install Node.js and npm first");
12974
+ await runInstallationCommand(npm.executable, ["install", "--global", source.npm], {
12975
+ ...env,
12976
+ ...source.allowScripts ? { npm_config_allow_scripts: source.allowScripts } : {}
12977
+ }, 6e5);
12978
+ return;
12979
+ }
12980
+ const windows = process.platform === "win32";
12981
+ const url2 = windows ? source.windows : source.posix;
12982
+ if (new URL(url2).protocol !== "https:")
12983
+ throw new Error("Installer requires HTTPS");
12984
+ const script = await fetchInstallationText(url2);
12985
+ const directory = await mkdtemp(join(tmpdir(), "codexhost-installer-"));
12986
+ try {
12987
+ const file2 = join(directory, windows ? "install.ps1" : "install.sh");
12988
+ await writeFile(file2, script, { mode: 384 });
12989
+ await runInstallationCommand(windows ? "powershell.exe" : source.shell ?? "bash", windows ? ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", file2] : [file2], env, 6e5);
12990
+ } finally {
12991
+ await rm(directory, { recursive: true, force: true });
12992
+ }
12993
+ };
12994
+ }
12995
+
12593
12996
  // dist/qoder-adapter.js
12594
12997
  import { randomUUID as randomUUID2 } from "node:crypto";
12595
- import path3 from "node:path";
12998
+ import path6 from "node:path";
12596
12999
 
12597
13000
  // ../../../node_modules/zod/v4/classic/external.js
12598
13001
  var external_exports = {};
@@ -13360,10 +13763,10 @@ function mergeDefs(...defs) {
13360
13763
  function cloneDef(schema) {
13361
13764
  return mergeDefs(schema._zod.def);
13362
13765
  }
13363
- function getElementAtPath(obj, path4) {
13364
- if (!path4)
13766
+ function getElementAtPath(obj, path7) {
13767
+ if (!path7)
13365
13768
  return obj;
13366
- return path4.reduce((acc, key) => acc?.[key], obj);
13769
+ return path7.reduce((acc, key) => acc?.[key], obj);
13367
13770
  }
13368
13771
  function promiseAllObject(promisesObj) {
13369
13772
  const keys = Object.keys(promisesObj);
@@ -13772,11 +14175,11 @@ function explicitlyAborted(x3, startIndex = 0) {
13772
14175
  }
13773
14176
  return false;
13774
14177
  }
13775
- function prefixIssues(path4, issues) {
14178
+ function prefixIssues(path7, issues) {
13776
14179
  return issues.map((iss) => {
13777
14180
  var _a5;
13778
14181
  (_a5 = iss).path ?? (_a5.path = []);
13779
- iss.path.unshift(path4);
14182
+ iss.path.unshift(path7);
13780
14183
  return iss;
13781
14184
  });
13782
14185
  }
@@ -13923,16 +14326,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
13923
14326
  }
13924
14327
  function formatError(error51, mapper = (issue2) => issue2.message) {
13925
14328
  const fieldErrors = { _errors: [] };
13926
- const processError = (error52, path4 = []) => {
14329
+ const processError = (error52, path7 = []) => {
13927
14330
  for (const issue2 of error52.issues) {
13928
14331
  if (issue2.code === "invalid_union" && issue2.errors.length) {
13929
- issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
14332
+ issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
13930
14333
  } else if (issue2.code === "invalid_key") {
13931
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
14334
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
13932
14335
  } else if (issue2.code === "invalid_element") {
13933
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
14336
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
13934
14337
  } else {
13935
- const fullpath = [...path4, ...issue2.path];
14338
+ const fullpath = [...path7, ...issue2.path];
13936
14339
  if (fullpath.length === 0) {
13937
14340
  fieldErrors._errors.push(mapper(issue2));
13938
14341
  } else {
@@ -13959,17 +14362,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
13959
14362
  }
13960
14363
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
13961
14364
  const result = { errors: [] };
13962
- const processError = (error52, path4 = []) => {
14365
+ const processError = (error52, path7 = []) => {
13963
14366
  var _a5, _b;
13964
14367
  for (const issue2 of error52.issues) {
13965
14368
  if (issue2.code === "invalid_union" && issue2.errors.length) {
13966
- issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
14369
+ issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
13967
14370
  } else if (issue2.code === "invalid_key") {
13968
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
14371
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
13969
14372
  } else if (issue2.code === "invalid_element") {
13970
- processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
14373
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
13971
14374
  } else {
13972
- const fullpath = [...path4, ...issue2.path];
14375
+ const fullpath = [...path7, ...issue2.path];
13973
14376
  if (fullpath.length === 0) {
13974
14377
  result.errors.push(mapper(issue2));
13975
14378
  continue;
@@ -14001,8 +14404,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
14001
14404
  }
14002
14405
  function toDotPath(_path) {
14003
14406
  const segs = [];
14004
- const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
14005
- for (const seg of path4) {
14407
+ const path7 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
14408
+ for (const seg of path7) {
14006
14409
  if (typeof seg === "number")
14007
14410
  segs.push(`[${seg}]`);
14008
14411
  else if (typeof seg === "symbol")
@@ -26694,13 +27097,13 @@ function resolveRef(ref, ctx) {
26694
27097
  if (!ref.startsWith("#")) {
26695
27098
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
26696
27099
  }
26697
- const path4 = ref.slice(1).split("/").filter(Boolean);
26698
- if (path4.length === 0) {
27100
+ const path7 = ref.slice(1).split("/").filter(Boolean);
27101
+ if (path7.length === 0) {
26699
27102
  return ctx.rootSchema;
26700
27103
  }
26701
27104
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
26702
- if (path4[0] === defsKey) {
26703
- const key = path4[1];
27105
+ if (path7[0] === defsKey) {
27106
+ const key = path7[1];
26704
27107
  if (!key || !ctx.defs[key]) {
26705
27108
  throw new Error(`Reference not found: ${ref}`);
26706
27109
  }
@@ -27163,6 +27566,56 @@ var credentialImportsParamsSchema = external_exports.object({
27163
27566
  request: credentialImportsRequestSchema
27164
27567
  }).strict();
27165
27568
 
27569
+ // ../../shared-contracts/dist/harness-display-settings.js
27570
+ var harnessDisplayEntriesSchema = external_exports.array(external_exports.strictObject({
27571
+ agent: external_exports.string().min(1).max(128),
27572
+ section: external_exports.enum(["main", "more", "auto"])
27573
+ })).max(256).refine((entries) => new Set(entries.map((entry) => entry.agent)).size === entries.length, "Duplicate Harness IDs");
27574
+ var harnessDisplaySettingsSchema = external_exports.strictObject({
27575
+ entries: harnessDisplayEntriesSchema.nullable()
27576
+ });
27577
+ var harnessDisplayGetSchema = external_exports.strictObject({});
27578
+ var harnessDisplaySetSchema = external_exports.strictObject({
27579
+ entries: harnessDisplayEntriesSchema,
27580
+ /** Import legacy Desktop preferences only if no shared settings exist yet. */
27581
+ initializeOnly: external_exports.boolean().optional()
27582
+ });
27583
+
27584
+ // ../../shared-contracts/dist/console.js
27585
+ var consoleAnnouncementSchema = external_exports.strictObject({
27586
+ title: external_exports.string().trim().min(1).max(200),
27587
+ type: external_exports.enum(["info", "warning", "danger"]),
27588
+ body: external_exports.string().trim().min(1).max(16 * 1024)
27589
+ });
27590
+ var consoleOpenParamsSchema = external_exports.strictObject({});
27591
+ var consoleOpenResultSchema = external_exports.strictObject({
27592
+ /** The console address. */
27593
+ url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
27594
+ });
27595
+ var CONSOLE_HOST_METHODS = Object.freeze([
27596
+ "codexhost/harness/plugins/list",
27597
+ "codexhost/harness/display-settings/get",
27598
+ "codexhost/harness/display-settings/set",
27599
+ "codexhost/harness/inspect",
27600
+ "codexhost/harness/installation",
27601
+ "codexhost/harness/launch-settings/get",
27602
+ "codexhost/harness/launch-settings/set",
27603
+ "codexhost/harness/web-ui/open",
27604
+ "codexhost/harness/accounts/sources",
27605
+ "codexhost/harness/accounts/list",
27606
+ "codexhost/harness/accounts/inspect",
27607
+ "codexhost/harness/credential-imports",
27608
+ "codexhost/harness/session-import/sources",
27609
+ "codexhost/harness/session-import/list",
27610
+ "codexhost/harness/session-import/import",
27611
+ "codexhost/account/list",
27612
+ "codexhost/account/refresh",
27613
+ "codexhost/account/usage/inspect",
27614
+ "codexhost/update/check",
27615
+ "codexhost/update/start",
27616
+ "codexhost/update/status"
27617
+ ]);
27618
+
27166
27619
  // ../../shared-contracts/dist/version.js
27167
27620
  var WORKSPACE_CONTRACT_VERSION = 1;
27168
27621
 
@@ -27216,6 +27669,12 @@ var hostTurnIdSchema = opaqueIdSchema.brand();
27216
27669
  var hostItemIdSchema = opaqueIdSchema.brand();
27217
27670
  var hostInteractionIdSchema = opaqueIdSchema.brand();
27218
27671
 
27672
+ // ../../shared-contracts/dist/manual-compaction.js
27673
+ var threadManualCompactionStartedSchema = external_exports.strictObject({
27674
+ threadId: hostThreadIdSchema,
27675
+ turnId: hostTurnIdSchema
27676
+ });
27677
+
27219
27678
  // ../../shared-contracts/dist/thread-usage.js
27220
27679
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
27221
27680
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
@@ -27276,6 +27735,10 @@ var threadUsageSnapshotSchema = external_exports.object({
27276
27735
  var usagePercentSchema = external_exports.number().finite().min(0).max(100);
27277
27736
  var accountCreditsProductUsageSchema = external_exports.object({
27278
27737
  product: external_exports.string().min(1),
27738
+ used: external_exports.number().finite().nonnegative().optional(),
27739
+ // Zero is a real empty cap, not an absent field.
27740
+ limit: external_exports.number().finite().nonnegative().optional(),
27741
+ unit: external_exports.string().min(1).max(32).optional(),
27279
27742
  usagePercent: usagePercentSchema,
27280
27743
  resetsAt: external_exports.string().min(1).optional()
27281
27744
  }).strict();
@@ -27285,6 +27748,10 @@ var accountResetCreditsSchema = external_exports.object({
27285
27748
  expiresAt: external_exports.array(external_exports.string().min(1)).min(1).max(32).optional()
27286
27749
  }).strict();
27287
27750
  var accountCreditsSnapshotSchema = external_exports.object({
27751
+ used: external_exports.number().finite().nonnegative().optional(),
27752
+ // Zero is a real empty cap, not an absent field.
27753
+ limit: external_exports.number().finite().nonnegative().optional(),
27754
+ unit: external_exports.string().min(1).max(32).optional(),
27288
27755
  /** Native label when the primary limit is scoped to a model or product group. */
27289
27756
  label: external_exports.string().min(1).optional(),
27290
27757
  usedPercent: usagePercentSchema,
@@ -27304,12 +27771,27 @@ var threadUsageInspectionSchema = external_exports.object({
27304
27771
  }).strict();
27305
27772
 
27306
27773
  // ../../shared-contracts/dist/harness-accounts.js
27307
- var harnessAccountSnapshotSchema = external_exports.object({
27774
+ var accountBalanceSnapshotSchema = external_exports.object({
27775
+ amount: external_exports.number().finite().nonnegative(),
27776
+ /** ISO 4217 code as reported by the Provider, for example `CNY`. */
27777
+ currency: external_exports.string().trim().min(1).max(8),
27778
+ /** Native label when the Harness exposes several Billing Sources. */
27779
+ label: external_exports.string().trim().min(1).max(128).optional()
27780
+ }).strict();
27781
+ var harnessAccountSnapshotObject = external_exports.object({
27308
27782
  email: external_exports.string().trim().min(1).max(320).optional(),
27309
27783
  label: external_exports.string().trim().min(1).max(256).optional(),
27310
27784
  plan: external_exports.string().trim().min(1).max(128).optional(),
27311
- credits: accountCreditsSnapshotSchema
27785
+ credits: accountCreditsSnapshotSchema.optional(),
27786
+ balance: accountBalanceSnapshotSchema.optional()
27312
27787
  }).strict();
27788
+ function requireReportedQuota(schema) {
27789
+ return schema.refine((value) => {
27790
+ const reported = value;
27791
+ return reported.credits !== void 0 || reported.balance !== void 0;
27792
+ }, { message: "Account must report either credits or a balance" });
27793
+ }
27794
+ var harnessAccountSnapshotSchema = requireReportedQuota(harnessAccountSnapshotObject);
27313
27795
  var harnessAccountIdentityShape = {
27314
27796
  harnessId: harnessIdSchema,
27315
27797
  harnessName: external_exports.string().trim().min(1).max(128)
@@ -27320,11 +27802,13 @@ var harnessAccountSourceListResultSchema = external_exports.object({ sources: ex
27320
27802
  var harnessAccountInspectParamsSchema = external_exports.object({ harnessId: harnessIdSchema, refresh: external_exports.boolean().optional() }).strict();
27321
27803
  var harnessAccountInspectResultSchema = external_exports.object({
27322
27804
  ...harnessAccountIdentityShape,
27323
- account: harnessAccountSnapshotSchema.nullable()
27805
+ account: harnessAccountSnapshotSchema.nullable(),
27806
+ /** Every Billing Source from one Harness; `account` remains the first for older clients. */
27807
+ accounts: external_exports.array(harnessAccountSnapshotSchema).max(8).optional()
27324
27808
  }).strict();
27325
27809
  var harnessAccountListParamsSchema = external_exports.object({ refresh: external_exports.boolean().optional() }).strict();
27326
27810
  var harnessAccountListResultSchema = external_exports.object({
27327
- accounts: external_exports.array(harnessAccountSnapshotSchema.extend(harnessAccountIdentityShape)).max(128)
27811
+ accounts: external_exports.array(requireReportedQuota(harnessAccountSnapshotObject.extend(harnessAccountIdentityShape))).max(128)
27328
27812
  }).strict();
27329
27813
 
27330
27814
  // ../../shared-contracts/dist/json-value.js
@@ -27462,6 +27946,8 @@ var harnessModelSchema = external_exports.object({
27462
27946
  ref: harnessModelRefSchema,
27463
27947
  label: nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH),
27464
27948
  resolvedModelLabel: harnessResolvedModelLabelSchema.optional(),
27949
+ /** Optional opaque selection for this same Model with priority processing enabled. */
27950
+ fastModel: harnessModelRefSchema.optional(),
27465
27951
  supportedThinkingOptionIds: external_exports.array(harnessThinkingOptionIdSchema).optional()
27466
27952
  }).strict();
27467
27953
  var harnessThinkingOptionsSchema = external_exports.array(harnessThinkingOptionSchema).superRefine((options, context) => {
@@ -27494,6 +27980,16 @@ var harnessModelCatalogSchema = external_exports.object({
27494
27980
  });
27495
27981
  }
27496
27982
  refs.add(model.ref.id);
27983
+ if (model.fastModel) {
27984
+ if (refs.has(model.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model.fastModel?.id)) {
27985
+ context.addIssue({
27986
+ code: "custom",
27987
+ message: "Fast Model refs must be distinct and unique",
27988
+ path: ["models", index, "fastModel"]
27989
+ });
27990
+ }
27991
+ refs.add(model.fastModel.id);
27992
+ }
27497
27993
  const supportedThinkingIds = /* @__PURE__ */ new Set();
27498
27994
  for (const [optionIndex, optionId] of (model.supportedThinkingOptionIds ?? []).entries()) {
27499
27995
  if (supportedThinkingIds.has(optionId)) {
@@ -27613,11 +28109,13 @@ var threadThinkingSelectParamsSchema = external_exports.object({
27613
28109
  thinkingOptionId: harnessThinkingOptionIdSchema
27614
28110
  }).strict();
27615
28111
  var threadInspectionParamsSchema = external_exports.object({
27616
- threadId: hostThreadIdSchema
28112
+ threadId: hostThreadIdSchema,
28113
+ includeReferenceCapability: external_exports.boolean().optional()
27617
28114
  }).strict();
27618
28115
  var codexThreadInspectionSchema = external_exports.object({
27619
28116
  owner: external_exports.literal("codex"),
27620
- locked: external_exports.literal(true)
28117
+ locked: external_exports.literal(true),
28118
+ supportsThreadReferences: external_exports.literal(true).optional()
27621
28119
  }).strict();
27622
28120
  var externalThreadInspectionSchema = external_exports.object({
27623
28121
  owner: external_exports.literal("external"),
@@ -27743,6 +28241,22 @@ var harnessLaunchSettingsSchema = external_exports.object({
27743
28241
  restartRequired: external_exports.boolean()
27744
28242
  }).strict();
27745
28243
 
28244
+ // ../../shared-contracts/dist/harness-installation.js
28245
+ var harnessInstallationParamsSchema = external_exports.object({
28246
+ harnessId: harnessIdSchema,
28247
+ action: external_exports.enum(["check", "update", "install"])
28248
+ }).strict();
28249
+ var harnessInstallationStateSchema = external_exports.object({
28250
+ currentVersion: external_exports.string().min(1).max(128),
28251
+ latestVersion: external_exports.string().min(1).max(128),
28252
+ updateAvailable: external_exports.boolean(),
28253
+ canUpdate: external_exports.boolean(),
28254
+ // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
28255
+ message: external_exports.string().max(2048).optional(),
28256
+ messageCode: external_exports.string().min(1).max(128).optional(),
28257
+ latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
28258
+ }).strict();
28259
+
27746
28260
  // ../../shared-contracts/dist/codex-accounts.js
27747
28261
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
27748
28262
  var nonBlankTextSchema3 = external_exports.string().trim().min(1);
@@ -28042,222 +28556,43 @@ var updateStatusResultSchema = external_exports.strictObject({
28042
28556
  status: updateStatusSchema.nullable()
28043
28557
  });
28044
28558
 
28559
+ // ../../shared-contracts/dist/remote-runtime.js
28560
+ var remoteUpdatePhaseSchema = external_exports.enum([
28561
+ "idle",
28562
+ "installing",
28563
+ "restarting",
28564
+ "succeeded",
28565
+ "failed"
28566
+ ]);
28567
+ var runtimeStatusSchema = external_exports.object({
28568
+ runningVersion: external_exports.string().nullable(),
28569
+ installedVersion: external_exports.string().nullable(),
28570
+ restartRequired: external_exports.boolean(),
28571
+ remote: external_exports.boolean(),
28572
+ updateSupported: external_exports.boolean(),
28573
+ update: external_exports.object({
28574
+ phase: remoteUpdatePhaseSchema,
28575
+ targetVersion: external_exports.string().nullable(),
28576
+ error: external_exports.string().nullable()
28577
+ })
28578
+ });
28579
+ var remoteUpdateParamsSchema = external_exports.object({
28580
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
28581
+ }).strict();
28582
+ var remoteSshSetupParamsSchema = external_exports.object({
28583
+ hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
28584
+ port: external_exports.number().int().min(1).max(65535).nullable(),
28585
+ identity: external_exports.string().max(4096).nullable(),
28586
+ action: external_exports.enum(["inspect", "install", "update", "repair"]),
28587
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
28588
+ }).strict();
28589
+ var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
28590
+
28045
28591
  // ../../shared-contracts/dist/index.js
28046
28592
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
28047
28593
 
28048
28594
  // dist/qoder-command.js
28049
- import path2 from "node:path";
28050
-
28051
- // ../../harness-discovery/dist/environment.js
28052
- import fs from "node:fs";
28053
- import path from "node:path";
28054
- function targetPath(platform) {
28055
- return platform === "win32" ? path.win32 : path.posix;
28056
- }
28057
- function environmentValue(environment, name) {
28058
- const lowered = name.toLowerCase();
28059
- for (const [key, value] of Object.entries(environment)) {
28060
- if (key.toLowerCase() === lowered)
28061
- return value;
28062
- }
28063
- return void 0;
28064
- }
28065
- function pathDelimiter(platform) {
28066
- return platform === "win32" ? ";" : ":";
28067
- }
28068
- function pathDirectories(environment, platform) {
28069
- return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
28070
- }
28071
- function executableExtensions(command, platform, environment) {
28072
- if (platform !== "win32")
28073
- return [""];
28074
- if (targetPath(platform).extname(command) !== "")
28075
- return [""];
28076
- return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
28077
- }
28078
- function isExecutableFile(filePath, platform) {
28079
- try {
28080
- fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
28081
- return fs.statSync(filePath).isFile();
28082
- } catch {
28083
- return false;
28084
- }
28085
- }
28086
- function subdirectoryNames(directory) {
28087
- try {
28088
- return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
28089
- } catch {
28090
- return [];
28091
- }
28092
- }
28093
- function newestFirst(names) {
28094
- return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
28095
- }
28096
-
28097
- // ../../harness-discovery/dist/resolve.js
28098
- import os from "node:os";
28099
-
28100
- // ../../harness-discovery/dist/version-managers.js
28101
- function versionManagerBinaryDirectories(context) {
28102
- const { platform, environment, home } = context;
28103
- const list = context.subdirectories ?? subdirectoryNames;
28104
- const pathFlavor = targetPath(platform);
28105
- const value = (name) => environmentValue(environment, name);
28106
- const directories = [];
28107
- const versioned = (root, ...tail) => {
28108
- for (const version2 of newestFirst(list(root))) {
28109
- directories.push(pathFlavor.join(root, version2, ...tail));
28110
- }
28111
- };
28112
- if (platform === "win32") {
28113
- const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
28114
- const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
28115
- versioned(pathFlavor.join(appData, "nvm"));
28116
- versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
28117
- directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
28118
- directories.push(pathFlavor.join(home, ".bun", "bin"));
28119
- const pnpmHome2 = value("PNPM_HOME");
28120
- if (pnpmHome2)
28121
- directories.push(pnpmHome2);
28122
- directories.push(pathFlavor.join(localAppData, "pnpm"));
28123
- return directories;
28124
- }
28125
- versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
28126
- const fnmRoots = [
28127
- value("FNM_DIR"),
28128
- pathFlavor.join(home, ".local", "share", "fnm"),
28129
- pathFlavor.join(home, "Library", "Application Support", "fnm")
28130
- ].filter((root) => root !== void 0);
28131
- for (const root of fnmRoots) {
28132
- versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
28133
- }
28134
- const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
28135
- versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
28136
- directories.push(pathFlavor.join(voltaHome, "bin"));
28137
- const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
28138
- versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
28139
- directories.push(pathFlavor.join(asdfHome, "shims"));
28140
- const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
28141
- versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
28142
- directories.push(pathFlavor.join(nodenvHome, "shims"));
28143
- versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
28144
- directories.push(pathFlavor.join(home, ".bun", "bin"));
28145
- const pnpmHome = value("PNPM_HOME");
28146
- if (pnpmHome)
28147
- directories.push(pnpmHome);
28148
- directories.push(pathFlavor.join(home, "Library", "pnpm"));
28149
- directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
28150
- for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
28151
- for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
28152
- directories.push(pathFlavor.join(prefix, formula, "bin"));
28153
- }
28154
- }
28155
- return directories;
28156
- }
28157
-
28158
- // ../../harness-discovery/dist/resolve.js
28159
- var VERSION_MANAGER_ROOTS = "<version-managers>";
28160
- function installRootExtensions(platform) {
28161
- return platform === "win32" ? [".exe", ".cmd"] : [""];
28162
- }
28163
- function resolveHomeDirectory(input) {
28164
- return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
28165
- }
28166
- function templateVariables(environment, platform, home) {
28167
- const pathFlavor = targetPath(platform);
28168
- return {
28169
- HOME: home,
28170
- USERPROFILE: home,
28171
- APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
28172
- LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
28173
- };
28174
- }
28175
- function joinTemplate(platform, value) {
28176
- const pathFlavor = targetPath(platform);
28177
- const segments = value.split("/");
28178
- const head = segments[0] ?? "";
28179
- const tail = segments.slice(1);
28180
- if (head === "")
28181
- return pathFlavor.join(pathFlavor.sep, ...tail);
28182
- return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
28183
- }
28184
- function expandInstallRoot(template, environment, platform, home) {
28185
- const variables = templateVariables(environment, platform, home);
28186
- let unresolved = false;
28187
- const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
28188
- const value = variables[name] ?? environmentValue(environment, name);
28189
- if (value === void 0 || value === "") {
28190
- unresolved = true;
28191
- return "";
28192
- }
28193
- return value;
28194
- });
28195
- return unresolved ? void 0 : joinTemplate(platform, substituted);
28196
- }
28197
- function installRootDirectories(spec, input, dependencies, platform, home) {
28198
- const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
28199
- const directories = [];
28200
- for (const template of templates) {
28201
- if (template === VERSION_MANAGER_ROOTS) {
28202
- directories.push(...versionManagerBinaryDirectories({
28203
- platform,
28204
- environment: input.environment,
28205
- home,
28206
- ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
28207
- }));
28208
- continue;
28209
- }
28210
- const directory = expandInstallRoot(template, input.environment, platform, home);
28211
- if (directory !== void 0)
28212
- directories.push(directory);
28213
- }
28214
- return directories;
28215
- }
28216
- function harnessCandidates(spec, input, dependencies = {}) {
28217
- const platform = input.platform ?? process.platform;
28218
- const pathFlavor = targetPath(platform);
28219
- const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
28220
- const command = configured ?? spec.command;
28221
- if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
28222
- return [{ candidate: command, source: "configured" }];
28223
- }
28224
- const candidates = [];
28225
- const extensions = executableExtensions(command, platform, input.environment);
28226
- for (const directory of pathDirectories(input.environment, platform)) {
28227
- for (const extension of extensions) {
28228
- candidates.push({
28229
- candidate: pathFlavor.join(directory, command + extension),
28230
- source: "path"
28231
- });
28232
- }
28233
- }
28234
- if (configured !== void 0)
28235
- return candidates;
28236
- const home = resolveHomeDirectory(input);
28237
- for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
28238
- for (const extension of installRootExtensions(platform)) {
28239
- candidates.push({
28240
- candidate: pathFlavor.join(directory, spec.command + extension),
28241
- source: "install-root"
28242
- });
28243
- }
28244
- }
28245
- return candidates;
28246
- }
28247
- function resolveHarnessExecutable(spec, input, dependencies = {}) {
28248
- const platform = input.platform ?? process.platform;
28249
- const isExecutable = dependencies.isExecutable ?? ((candidate) => isExecutableFile(candidate, platform));
28250
- const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
28251
- const context = { platform, isExecutable };
28252
- for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
28253
- const executable = runnable(candidate, context);
28254
- if (executable !== void 0 && isExecutable(executable))
28255
- return { executable, source };
28256
- }
28257
- return void 0;
28258
- }
28259
-
28260
- // dist/qoder-command.js
28595
+ import path4 from "node:path";
28261
28596
  var QoderExecutableError = class extends Error {
28262
28597
  code = "QODER_NOT_FOUND";
28263
28598
  };
@@ -28320,7 +28655,52 @@ function resolveQoderExecutable(input = {}, dependencies = {}) {
28320
28655
  }, dependencies);
28321
28656
  if (!resolution)
28322
28657
  throw new QoderExecutableError("Qoder CLI is not installed");
28323
- return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path2.resolve(resolution.executable);
28658
+ return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path4.resolve(resolution.executable);
28659
+ }
28660
+
28661
+ // dist/qoder-account.js
28662
+ var record2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
28663
+ var nonnegative = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
28664
+ function creditAmount(used, limit, unit) {
28665
+ if (!nonnegative(used) || !nonnegative(limit))
28666
+ return void 0;
28667
+ return {
28668
+ used,
28669
+ limit,
28670
+ unit: typeof unit === "string" && unit.trim() ? unit : "credits"
28671
+ };
28672
+ }
28673
+ function projectQoderAccount(usage, identity) {
28674
+ const data = record2(usage);
28675
+ const account = record2(identity);
28676
+ const quota = record2(data.userQuota);
28677
+ const shared = record2(data.orgResourcePackage);
28678
+ const nativePercent = quota.percentage ?? data.totalUsagePercentage;
28679
+ const usedPercent = nonnegative(nativePercent) ? Math.min(100, nativePercent) : nonnegative(quota.used) && nonnegative(quota.total) && quota.total > 0 ? Math.min(100, quota.used / quota.total * 100) : void 0;
28680
+ if (usedPercent === void 0)
28681
+ return null;
28682
+ const result = harnessAccountSnapshotSchema.safeParse({
28683
+ ...typeof account.email === "string" && account.email ? { email: account.email } : {},
28684
+ ...typeof account.subscriptionType === "string" && account.subscriptionType ? { plan: account.subscriptionType } : typeof data.userType === "string" ? { plan: data.userType } : {},
28685
+ credits: {
28686
+ usedPercent,
28687
+ periodType: "unknown",
28688
+ label: "Plan credits",
28689
+ ...shared.available === true && nonnegative(shared.percentage) && nonnegative(shared.used) && nonnegative(shared.cap) && shared.cap > 0 ? {
28690
+ productUsage: [
28691
+ {
28692
+ product: "Shared resource credits",
28693
+ usagePercent: Math.min(100, shared.percentage),
28694
+ used: shared.used,
28695
+ limit: shared.cap,
28696
+ unit: typeof shared.unit === "string" ? shared.unit : "credits"
28697
+ }
28698
+ ]
28699
+ } : {},
28700
+ ...creditAmount(quota.used, quota.total, quota.unit)
28701
+ }
28702
+ });
28703
+ return result.success ? result.data : null;
28324
28704
  }
28325
28705
 
28326
28706
  // dist/qoder-errors.js
@@ -28468,6 +28848,26 @@ function mapQoderException(error51) {
28468
28848
  };
28469
28849
  }
28470
28850
 
28851
+ // dist/qoder-login-check.js
28852
+ import { execFile as execFile2 } from "node:child_process";
28853
+ function qoderLoginRequired(text) {
28854
+ return /\bnot logged in\b|\bauthentication (?:required|expired)\b/i.test(text);
28855
+ }
28856
+ function checkQoderLogin(executable, environment, cwd) {
28857
+ return new Promise((resolve) => {
28858
+ execFile2(executable, ["--list-models"], {
28859
+ env: environment,
28860
+ cwd,
28861
+ timeout: 1e4,
28862
+ maxBuffer: 64 * 1024,
28863
+ windowsHide: true
28864
+ }, (error51, stdout, stderr) => {
28865
+ resolve(Boolean(error51 && !error51.killed && qoderLoginRequired(`${stdout}
28866
+ ${stderr}`)));
28867
+ });
28868
+ });
28869
+ }
28870
+
28471
28871
  // ../../harness-adapter/dist/approval.js
28472
28872
  function invalidRequest(message) {
28473
28873
  return { code: "invalidRequest", message, retryable: false };
@@ -29819,8 +30219,8 @@ function getErrorMap2() {
29819
30219
 
29820
30220
  // ../../../node_modules/zod/v3/helpers/parseUtil.js
29821
30221
  var makeIssue = (params) => {
29822
- const { data, path: path4, errorMaps, issueData } = params;
29823
- const fullPath = [...path4, ...issueData.path || []];
30222
+ const { data, path: path7, errorMaps, issueData } = params;
30223
+ const fullPath = [...path7, ...issueData.path || []];
29824
30224
  const fullIssue = {
29825
30225
  ...issueData,
29826
30226
  path: fullPath
@@ -29935,11 +30335,11 @@ var errorUtil;
29935
30335
 
29936
30336
  // ../../../node_modules/zod/v3/types.js
29937
30337
  var ParseInputLazyPath = class {
29938
- constructor(parent, value, path4, key) {
30338
+ constructor(parent, value, path7, key) {
29939
30339
  this._cachedPath = [];
29940
30340
  this.parent = parent;
29941
30341
  this.data = value;
29942
- this._path = path4;
30342
+ this._path = path7;
29943
30343
  this._key = key;
29944
30344
  }
29945
30345
  get path() {
@@ -33466,11 +33866,11 @@ function normalizeObjectSchema(schema) {
33466
33866
  }
33467
33867
  return void 0;
33468
33868
  }
33469
- function getDotPath(path4) {
33470
- if (path4.length === 0) {
33869
+ function getDotPath(path7) {
33870
+ if (path7.length === 0) {
33471
33871
  return "object root";
33472
33872
  }
33473
- return path4.reduce((acc, seg, index) => {
33873
+ return path7.reduce((acc, seg, index) => {
33474
33874
  if (index === 0) {
33475
33875
  return String(seg);
33476
33876
  }
@@ -52041,12 +52441,171 @@ var QoderSession = class {
52041
52441
  }
52042
52442
  };
52043
52443
 
52444
+ // dist/qoder-session-import.js
52445
+ import { stat } from "node:fs/promises";
52446
+ import path5 from "node:path";
52447
+
52448
+ // ../../harness-adapter/dist/session-import.js
52449
+ var STORAGE_ACCESS_ERRORS = /* @__PURE__ */ new Set(["EACCES", "EPERM", "EIO", "EMFILE", "ENFILE"]);
52450
+ function isStorageAccessError(error51) {
52451
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && typeof error51.code === "string" && STORAGE_ACCESS_ERRORS.has(error51.code);
52452
+ }
52453
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
52454
+ if (typeof value !== "string")
52455
+ return null;
52456
+ const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
52457
+ if (!normalized)
52458
+ return null;
52459
+ if (normalized.length <= maxLength)
52460
+ return normalized;
52461
+ const characters = [...normalized];
52462
+ if (characters.length <= maxLength)
52463
+ return normalized;
52464
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
52465
+ }
52466
+ function sessionImportCandidate(input) {
52467
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
52468
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
52469
+ nativeSessionId: input.nativeSessionId,
52470
+ cwd: input.cwd,
52471
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
52472
+ updatedAt: Math.floor(time3),
52473
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
52474
+ running: typeof input.running === "boolean" ? input.running : null
52475
+ });
52476
+ return parsed.success ? parsed.data : null;
52477
+ }
52478
+ var SessionImportScope = class {
52479
+ #abort = new AbortController();
52480
+ #options;
52481
+ #pending = /* @__PURE__ */ new Set();
52482
+ constructor(options) {
52483
+ this.#options = options;
52484
+ }
52485
+ #closed() {
52486
+ return {
52487
+ ok: false,
52488
+ error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
52489
+ };
52490
+ }
52491
+ read(operation) {
52492
+ const signal = this.#abort.signal;
52493
+ if (signal.aborted)
52494
+ return Promise.resolve(this.#closed());
52495
+ let started;
52496
+ try {
52497
+ started = operation(signal);
52498
+ } catch (error51) {
52499
+ started = Promise.reject(error51 instanceof Error ? error51 : new Error("Session read failed"));
52500
+ }
52501
+ const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
52502
+ ok: false,
52503
+ error: {
52504
+ code: "unavailable",
52505
+ message: this.#options.unavailableMessage,
52506
+ retryable: true
52507
+ }
52508
+ }).finally(() => this.#pending.delete(request));
52509
+ this.#pending.add(request);
52510
+ return request;
52511
+ }
52512
+ /** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
52513
+ async resolve(operation) {
52514
+ const result = await this.read(operation);
52515
+ if (!result.ok)
52516
+ return result;
52517
+ return result.value ? { ok: true, value: result.value } : {
52518
+ ok: false,
52519
+ error: {
52520
+ code: "sessionNotFound",
52521
+ message: this.#options.notFoundMessage,
52522
+ retryable: false
52523
+ }
52524
+ };
52525
+ }
52526
+ /** Idempotent. Resolves after every started read has settled. */
52527
+ async close() {
52528
+ this.#abort.abort();
52529
+ await Promise.allSettled(this.#pending);
52530
+ }
52531
+ };
52532
+
52533
+ // dist/qoder-session-import.js
52534
+ var QoderSessionImport = class {
52535
+ #dependencies;
52536
+ #scope;
52537
+ constructor(dependencies) {
52538
+ this.#dependencies = dependencies;
52539
+ const name = dependencies.displayName;
52540
+ this.#scope = new SessionImportScope({
52541
+ closedMessage: `${name} Session import is closed`,
52542
+ unavailableMessage: `${name} sessions could not be read; check storage access and retry`,
52543
+ notFoundMessage: `${name} Session is no longer importable`
52544
+ });
52545
+ }
52546
+ listCandidates() {
52547
+ return this.#scope.read(async (signal) => {
52548
+ const candidates = /* @__PURE__ */ new Map();
52549
+ for (const info of await this.#dependencies.listSessions()) {
52550
+ signal.throwIfAborted();
52551
+ const candidate = await this.#candidate(info);
52552
+ if (candidate && !candidates.has(candidate.nativeSessionId))
52553
+ candidates.set(candidate.nativeSessionId, candidate);
52554
+ }
52555
+ return [...candidates.values()];
52556
+ });
52557
+ }
52558
+ resolveCandidate(nativeSessionId) {
52559
+ return this.#scope.resolve(async (signal) => {
52560
+ const info = await this.#dependencies.getSessionInfo(nativeSessionId);
52561
+ signal.throwIfAborted();
52562
+ if (info?.sessionId !== nativeSessionId)
52563
+ return null;
52564
+ const candidate = await this.#candidate(info);
52565
+ if (!candidate)
52566
+ return null;
52567
+ return {
52568
+ candidate,
52569
+ nativeRef: nativeSessionRefSchema.parse({
52570
+ harnessId: this.#dependencies.harnessId,
52571
+ nativeSessionId,
52572
+ formatVersion: 1
52573
+ })
52574
+ };
52575
+ });
52576
+ }
52577
+ close() {
52578
+ return this.#scope.close();
52579
+ }
52580
+ async #candidate(info) {
52581
+ if (typeof info.cwd !== "string" || !path5.isAbsolute(info.cwd))
52582
+ return null;
52583
+ const cwd = path5.resolve(info.cwd);
52584
+ try {
52585
+ if (!(await stat(cwd)).isDirectory())
52586
+ return null;
52587
+ } catch (error51) {
52588
+ if (isStorageAccessError(error51))
52589
+ throw error51;
52590
+ return null;
52591
+ }
52592
+ return sessionImportCandidate({
52593
+ nativeSessionId: info.sessionId,
52594
+ cwd,
52595
+ title: sessionImportTitle(info.customTitle) ?? sessionImportTitle(info.summary) ?? sessionImportTitle(info.firstPrompt),
52596
+ updatedAt: info.lastModified
52597
+ // The SDK exposes no cross-process activity marker: idleness cannot be established.
52598
+ });
52599
+ }
52600
+ };
52601
+
52044
52602
  // dist/qoder-adapter.js
52045
52603
  var QoderAdapter = class {
52046
52604
  harnessId;
52047
52605
  #variant;
52048
52606
  commandCatalog = QODER_FALLBACK_COMMAND_CATALOG;
52049
52607
  liveCommandCatalog = true;
52608
+ sessionImport;
52050
52609
  #commandOverride;
52051
52610
  #environment;
52052
52611
  #platform;
@@ -52070,9 +52629,49 @@ var QoderAdapter = class {
52070
52629
  this.#forkSession = options.forkSession ?? runtime.sdk.forkSession;
52071
52630
  this.#getSessionMessages = options.getSessionMessages ?? runtime.sdk.getSessionMessages;
52072
52631
  this.#getSessionInfo = options.getSessionInfo ?? runtime.sdk.getSessionInfo;
52632
+ this.sessionImport = new QoderSessionImport({
52633
+ harnessId: this.harnessId,
52634
+ displayName: this.#variant === "cn" ? "Qoder CN" : "Qoder",
52635
+ listSessions: options.listSessions ?? (() => runtime.sdk.listSessions()),
52636
+ getSessionInfo: this.#getSessionInfo
52637
+ });
52073
52638
  this.#getAvailableModels = options.getAvailableModels;
52074
52639
  this.#resolveExecutable = options.resolveExecutable ?? ((input, dependencies) => resolveQoderExecutable({ ...input, variant: this.#variant }, dependencies));
52075
52640
  }
52641
+ async inspectAccount() {
52642
+ let probe;
52643
+ let timer;
52644
+ try {
52645
+ const executable = this.#resolveExecutable({
52646
+ ...this.#commandOverride ? { command: this.#commandOverride } : {},
52647
+ environment: this.#environment,
52648
+ platform: this.#platform
52649
+ });
52650
+ probe = this.#queryFactory({
52651
+ prompt: "",
52652
+ options: {
52653
+ cwd: process.cwd(),
52654
+ pathToQoderCLIExecutable: executable,
52655
+ ...this.#environment ? { env: this.#environment } : {},
52656
+ auth: qoderAuthForEnvironment(this.#variant, this.#environment)
52657
+ }
52658
+ });
52659
+ return await Promise.race([
52660
+ Promise.all([probe.getUsageInfo?.(), probe.accountInfo?.().catch(() => void 0)]).then(([usage, identity]) => projectQoderAccount(usage, identity)),
52661
+ new Promise((resolve) => {
52662
+ timer = setTimeout(() => resolve(null), 1e4);
52663
+ })
52664
+ ]);
52665
+ } catch {
52666
+ return null;
52667
+ } finally {
52668
+ clearTimeout(timer);
52669
+ try {
52670
+ await probe?.close();
52671
+ } catch {
52672
+ }
52673
+ }
52674
+ }
52076
52675
  async inspect(input) {
52077
52676
  const cacheKey = input?.cwd ?? "";
52078
52677
  if (input?.refresh) {
@@ -52100,11 +52699,15 @@ var QoderAdapter = class {
52100
52699
  } catch {
52101
52700
  }
52102
52701
  } else {
52702
+ let stderr = "";
52103
52703
  try {
52104
52704
  const probeQuery = this.#queryFactory({
52105
52705
  prompt: "",
52106
52706
  options: {
52107
52707
  cwd: input?.cwd ?? process.cwd(),
52708
+ stderr: (chunk) => {
52709
+ stderr = (stderr + chunk).slice(-8192);
52710
+ },
52108
52711
  pathToQoderCLIExecutable: executable,
52109
52712
  ...this.#environment ? { env: this.#environment } : {},
52110
52713
  auth: qoderAuthForEnvironment(this.#variant, this.#environment)
@@ -52121,9 +52724,14 @@ var QoderAdapter = class {
52121
52724
  }
52122
52725
  }
52123
52726
  } catch (error51) {
52727
+ const needsLogin = qoderLoginRequired(stderr) || error51 instanceof Error && error51.message === "Transport closed" && qoderAuthForEnvironment(this.#variant, this.#environment).type === "qodercli" && await checkQoderLogin(executable, this.#environment, input?.cwd);
52124
52728
  const result2 = {
52125
52729
  status: "unavailable",
52126
- error: mapQoderException(error51)
52730
+ error: needsLogin ? {
52731
+ code: "authenticationRequired",
52732
+ message: `Please run ${this.#variant === "cn" ? "qoderclicn" : "qodercli"} login to authenticate.`,
52733
+ retryable: false
52734
+ } : mapQoderException(error51)
52127
52735
  };
52128
52736
  return result2;
52129
52737
  }
@@ -52245,7 +52853,7 @@ var QoderAdapter = class {
52245
52853
  sourceInfo = await this.#getSessionInfo(sourceRef.data.nativeSessionId, { dir: input.cwd });
52246
52854
  } catch {
52247
52855
  }
52248
- if (sourceInfo?.cwd && path3.resolve(sourceInfo.cwd) !== path3.resolve(input.cwd)) {
52856
+ if (sourceInfo?.cwd && path6.resolve(sourceInfo.cwd) !== path6.resolve(input.cwd)) {
52249
52857
  return {
52250
52858
  ok: false,
52251
52859
  error: {
@@ -52395,17 +53003,64 @@ var QoderAdapter = class {
52395
53003
  this.#sessions.clear();
52396
53004
  this.#inspections.clear();
52397
53005
  this.#inFlightInspections.clear();
52398
- await Promise.all(sessions.map((s) => s.close()));
53006
+ await Promise.all([this.sessionImport.close(), ...sessions.map((s) => s.close())]);
52399
53007
  }
52400
53008
  };
52401
53009
 
53010
+ // dist/installation.js
53011
+ function createQoderInstallation(environment, command, variant = "global") {
53012
+ const run = (args, timeout) => runInstallationCommand(resolveQoderExecutable({ environment, variant, ...command ? { command } : {} }), args, environment, timeout);
53013
+ return createInstallationManager({
53014
+ async check() {
53015
+ const currentVersion = versionFromOutput(await run(["--version"]));
53016
+ if (variant === "cn" && !(await run(["update", "--help"]).catch(() => "")).includes("--check"))
53017
+ return {
53018
+ currentVersion,
53019
+ latestVersion: "Unknown",
53020
+ updateAvailable: false,
53021
+ canUpdate: false,
53022
+ messageCode: "qoder-check-unavailable",
53023
+ message: "This Qoder China release does not expose a non-installing update check. Use its original installer."
53024
+ };
53025
+ const output = await run(["update", "--check"]);
53026
+ const available = output.match(/Update available:\s*\S+\s*(?:->|\u2192)\s*(\S+)/i);
53027
+ if (available?.[1])
53028
+ return {
53029
+ currentVersion,
53030
+ latestVersion: installationVersion(available[1]),
53031
+ updateAvailable: newerInstallationVersion(currentVersion, installationVersion(available[1])),
53032
+ canUpdate: true
53033
+ };
53034
+ if (!/already\s+(?:on|at)\s+(?:the\s+)?latest|up.to.date|no updates?\s+available/i.test(output))
53035
+ throw new Error("Qoder update check returned an unknown response");
53036
+ return {
53037
+ currentVersion,
53038
+ latestVersion: currentVersion,
53039
+ updateAvailable: false,
53040
+ canUpdate: true
53041
+ };
53042
+ },
53043
+ async update() {
53044
+ await run(["update"], 3e5);
53045
+ }
53046
+ });
53047
+ }
53048
+
52402
53049
  // dist/plugin.js
52403
- function createHarnessAdapter(context) {
53050
+ function createHarnessAdapter(context, variant = "global") {
52404
53051
  const environment = { ...context.environment };
52405
- return new QoderAdapter({
52406
- ...environment[CODEXHOST_QODER_COMMAND] ? { commandOverride: environment[CODEXHOST_QODER_COMMAND] } : {},
53052
+ const command = environment[variant === "cn" ? CODEXHOST_QODERCN_COMMAND : CODEXHOST_QODER_COMMAND];
53053
+ return Object.assign(new QoderAdapter({
53054
+ ...command ? { commandOverride: command } : {},
53055
+ variant,
52407
53056
  environment,
52408
53057
  platform: context.platform
53058
+ }), {
53059
+ installation: createQoderInstallation(environment, command, variant),
53060
+ install: createHarnessInstaller(environment, variant === "cn" ? {
53061
+ posix: "https://static.qoder.com.cn/qoder-cli-cn/install.sh",
53062
+ windows: "https://static.qoder.com.cn/qoder-cli-cn/install.ps1"
53063
+ } : { posix: "https://qoder.com/install", windows: "https://qoder.com/install.ps1" })
52409
53064
  });
52410
53065
  }
52411
53066
  export {