@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.
@@ -5,6 +5,488 @@ var __export = (target, all) => {
5
5
  __defProp(target, name, { get: all[name], enumerable: true });
6
6
  };
7
7
 
8
+ // ../../harness-discovery/dist/environment.js
9
+ import fs from "node:fs";
10
+ import path from "node:path";
11
+ function targetPath(platform) {
12
+ return platform === "win32" ? path.win32 : path.posix;
13
+ }
14
+ function environmentValue(environment, name) {
15
+ const lowered = name.toLowerCase();
16
+ for (const [key, value] of Object.entries(environment)) {
17
+ if (key.toLowerCase() === lowered)
18
+ return value;
19
+ }
20
+ return void 0;
21
+ }
22
+ function pathDelimiter(platform) {
23
+ return platform === "win32" ? ";" : ":";
24
+ }
25
+ function pathDirectories(environment, platform) {
26
+ return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
27
+ }
28
+ function executableExtensions(command, platform, environment) {
29
+ if (platform !== "win32")
30
+ return [""];
31
+ if (targetPath(platform).extname(command) !== "")
32
+ return [""];
33
+ return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
34
+ }
35
+ function isExecutableFile(filePath, platform) {
36
+ try {
37
+ fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
38
+ return fs.statSync(filePath).isFile();
39
+ } catch {
40
+ return false;
41
+ }
42
+ }
43
+ function subdirectoryNames(directory) {
44
+ try {
45
+ return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
46
+ } catch {
47
+ return [];
48
+ }
49
+ }
50
+ function newestFirst(names) {
51
+ return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
52
+ }
53
+
54
+ // ../../harness-discovery/dist/invocation.js
55
+ import path2 from "node:path";
56
+ function commandInvocation(command, arguments_, environment, platform = process.platform) {
57
+ const extension = path2.win32.extname(command).toLowerCase();
58
+ if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
59
+ return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
60
+ }
61
+ const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
62
+ const commandLine = [command, ...arguments_].map(quote).join(" ");
63
+ return {
64
+ command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
65
+ arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
66
+ windowsVerbatimArguments: true
67
+ };
68
+ }
69
+
70
+ // ../../harness-discovery/dist/node-runtime.js
71
+ import path3 from "node:path";
72
+ function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
73
+ const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
74
+ const delimiter = platform === "win32" ? ";" : ":";
75
+ const runtimeDirectory = path3.dirname(runtimeExecutable);
76
+ const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
77
+ const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
78
+ if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
79
+ directories.push(runtimeDirectory);
80
+ }
81
+ return { ...environment, [pathKey]: directories.join(delimiter) };
82
+ }
83
+
84
+ // ../../harness-discovery/dist/resolve.js
85
+ import os from "node:os";
86
+
87
+ // ../../harness-discovery/dist/version-managers.js
88
+ function versionManagerBinaryDirectories(context) {
89
+ const { platform, environment, home } = context;
90
+ const list = context.subdirectories ?? subdirectoryNames;
91
+ const pathFlavor = targetPath(platform);
92
+ const value = (name) => environmentValue(environment, name);
93
+ const directories = [];
94
+ const versioned = (root, ...tail) => {
95
+ for (const version2 of newestFirst(list(root))) {
96
+ directories.push(pathFlavor.join(root, version2, ...tail));
97
+ }
98
+ };
99
+ if (platform === "win32") {
100
+ const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
101
+ const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
102
+ versioned(pathFlavor.join(appData, "nvm"));
103
+ versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
104
+ directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
105
+ directories.push(pathFlavor.join(home, ".bun", "bin"));
106
+ const pnpmHome2 = value("PNPM_HOME");
107
+ if (pnpmHome2)
108
+ directories.push(pnpmHome2);
109
+ directories.push(pathFlavor.join(localAppData, "pnpm"));
110
+ return directories;
111
+ }
112
+ versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
113
+ const fnmRoots = [
114
+ value("FNM_DIR"),
115
+ pathFlavor.join(home, ".local", "share", "fnm"),
116
+ pathFlavor.join(home, "Library", "Application Support", "fnm")
117
+ ].filter((root) => root !== void 0);
118
+ for (const root of fnmRoots) {
119
+ versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
120
+ }
121
+ const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
122
+ versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
123
+ directories.push(pathFlavor.join(voltaHome, "bin"));
124
+ const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
125
+ versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
126
+ directories.push(pathFlavor.join(asdfHome, "shims"));
127
+ const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
128
+ versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
129
+ directories.push(pathFlavor.join(nodenvHome, "shims"));
130
+ versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
131
+ directories.push(pathFlavor.join(home, ".bun", "bin"));
132
+ const pnpmHome = value("PNPM_HOME");
133
+ if (pnpmHome)
134
+ directories.push(pnpmHome);
135
+ directories.push(pathFlavor.join(home, "Library", "pnpm"));
136
+ directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
137
+ for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
138
+ for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
139
+ directories.push(pathFlavor.join(prefix, formula, "bin"));
140
+ }
141
+ }
142
+ return directories;
143
+ }
144
+
145
+ // ../../harness-discovery/dist/resolve.js
146
+ var VERSION_MANAGER_ROOTS = "<version-managers>";
147
+ function installRootExtensions(platform) {
148
+ return platform === "win32" ? [".exe", ".cmd"] : [""];
149
+ }
150
+ function resolveHomeDirectory(input) {
151
+ return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
152
+ }
153
+ function templateVariables(environment, platform, home) {
154
+ const pathFlavor = targetPath(platform);
155
+ return {
156
+ HOME: home,
157
+ USERPROFILE: home,
158
+ APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
159
+ LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
160
+ };
161
+ }
162
+ function joinTemplate(platform, value) {
163
+ const pathFlavor = targetPath(platform);
164
+ const segments = value.split("/");
165
+ const head = segments[0] ?? "";
166
+ const tail = segments.slice(1);
167
+ if (head === "")
168
+ return pathFlavor.join(pathFlavor.sep, ...tail);
169
+ return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
170
+ }
171
+ function expandInstallRoot(template, environment, platform, home) {
172
+ const variables = templateVariables(environment, platform, home);
173
+ let unresolved = false;
174
+ const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
175
+ const value = variables[name] ?? environmentValue(environment, name);
176
+ if (value === void 0 || value === "") {
177
+ unresolved = true;
178
+ return "";
179
+ }
180
+ return value;
181
+ });
182
+ return unresolved ? void 0 : joinTemplate(platform, substituted);
183
+ }
184
+ function installRootDirectories(spec, input, dependencies, platform, home) {
185
+ const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
186
+ const directories = [];
187
+ for (const template of templates) {
188
+ if (template === VERSION_MANAGER_ROOTS) {
189
+ directories.push(...versionManagerBinaryDirectories({
190
+ platform,
191
+ environment: input.environment,
192
+ home,
193
+ ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
194
+ }));
195
+ continue;
196
+ }
197
+ const directory = expandInstallRoot(template, input.environment, platform, home);
198
+ if (directory !== void 0)
199
+ directories.push(directory);
200
+ }
201
+ return directories;
202
+ }
203
+ function harnessCandidates(spec, input, dependencies = {}) {
204
+ const platform = input.platform ?? process.platform;
205
+ const pathFlavor = targetPath(platform);
206
+ const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
207
+ const command = configured ?? spec.command;
208
+ if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
209
+ return [{ candidate: command, source: "configured" }];
210
+ }
211
+ const candidates = [];
212
+ const extensions = executableExtensions(command, platform, input.environment);
213
+ for (const directory of pathDirectories(input.environment, platform)) {
214
+ for (const extension of extensions) {
215
+ candidates.push({
216
+ candidate: pathFlavor.join(directory, command + extension),
217
+ source: "path"
218
+ });
219
+ }
220
+ }
221
+ if (configured !== void 0)
222
+ return candidates;
223
+ const home = resolveHomeDirectory(input);
224
+ for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
225
+ for (const extension of installRootExtensions(platform)) {
226
+ candidates.push({
227
+ candidate: pathFlavor.join(directory, spec.command + extension),
228
+ source: "install-root"
229
+ });
230
+ }
231
+ }
232
+ return candidates;
233
+ }
234
+ function resolveHarnessExecutable(spec, input, dependencies = {}) {
235
+ const platform = input.platform ?? process.platform;
236
+ const isExecutable = dependencies.isExecutable ?? ((candidate2) => isExecutableFile(candidate2, platform));
237
+ const runnable = spec.runnableCandidate ?? ((candidate2) => candidate2);
238
+ const context = { platform, isExecutable };
239
+ for (const { candidate: candidate2, source } of harnessCandidates(spec, input, dependencies)) {
240
+ const executable = runnable(candidate2, context);
241
+ if (executable !== void 0 && isExecutable(executable))
242
+ return { executable, source };
243
+ }
244
+ return void 0;
245
+ }
246
+
247
+ // ../../harness-discovery/dist/installation.js
248
+ import { execFile } from "node:child_process";
249
+ import { homedir } from "node:os";
250
+ function runInstallationCommand(command, args, environment, timeout = 3e4) {
251
+ const env = withNodeRuntimeOnPath(environment);
252
+ const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
253
+ return new Promise((resolve, reject) => {
254
+ const child = execFile(invocation.command, invocation.arguments, {
255
+ env,
256
+ cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
257
+ encoding: "utf8",
258
+ timeout,
259
+ killSignal: "SIGKILL",
260
+ maxBuffer: 1024 * 1024,
261
+ windowsHide: true,
262
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments
263
+ }, (error51, stdout, stderr) => {
264
+ if (error51)
265
+ reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
266
+ else
267
+ resolve((stdout || stderr).trim());
268
+ });
269
+ child.stdin?.end();
270
+ });
271
+ }
272
+ function installationVersion(value) {
273
+ if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
274
+ throw new Error("Harness returned an invalid version");
275
+ return value.trim().replace(/^v/, "");
276
+ }
277
+ function versionFromOutput(output) {
278
+ return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
279
+ }
280
+ function newerInstallationVersion(current, latest) {
281
+ const a = installationVersion(current).replace(/\+.*/, "");
282
+ const b = installationVersion(latest).replace(/\+.*/, "");
283
+ const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
284
+ const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
285
+ for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
286
+ if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
287
+ return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
288
+ }
289
+ const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
290
+ const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
291
+ if (!preA.length || !preB.length)
292
+ return !!preA.length && !preB.length;
293
+ for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
294
+ const x = preA[i];
295
+ const y = preB[i];
296
+ if (x === y)
297
+ continue;
298
+ if (x === void 0 || y === void 0)
299
+ return x === void 0;
300
+ const numericX = /^\d+$/.test(x);
301
+ const numericY = /^\d+$/.test(y);
302
+ if (numericX && numericY) {
303
+ if (BigInt(x) === BigInt(y))
304
+ continue;
305
+ return BigInt(y) > BigInt(x);
306
+ }
307
+ if (numericX !== numericY)
308
+ return numericX;
309
+ return y > x;
310
+ }
311
+ return false;
312
+ }
313
+ function createInstallationManager(options) {
314
+ let checking;
315
+ let updating;
316
+ const check2 = () => checking ??= options.check().finally(() => {
317
+ checking = void 0;
318
+ });
319
+ return (action) => {
320
+ if (updating)
321
+ return updating;
322
+ if (action === "check")
323
+ return check2();
324
+ updating = (async () => {
325
+ const before = await check2();
326
+ if (!before.updateAvailable)
327
+ return before;
328
+ if (!before.canUpdate)
329
+ throw new Error(before.message ?? "This installation cannot be updated automatically");
330
+ await options.update(before);
331
+ const after = await check2();
332
+ if (after.currentVersion === before.currentVersion)
333
+ throw new Error("The Harness version did not change; check the native updater and retry");
334
+ return after;
335
+ })().finally(() => {
336
+ updating = void 0;
337
+ });
338
+ return updating;
339
+ };
340
+ }
341
+ async function fetchInstallationText(url2) {
342
+ const request = async () => {
343
+ const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
344
+ if (!response.ok)
345
+ throw new Error("Could not check the latest Harness version");
346
+ return response.text();
347
+ };
348
+ try {
349
+ return await request();
350
+ } catch (error51) {
351
+ if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
352
+ throw error51;
353
+ return request();
354
+ }
355
+ }
356
+
357
+ // ../../harness-discovery/dist/npm-installation.js
358
+ import { readFile, realpath } from "node:fs/promises";
359
+ import path4 from "node:path";
360
+ function referencesNpmBin(shim, name, bin) {
361
+ if (bin.includes(".."))
362
+ return false;
363
+ const target = `node_modules/${name}/${bin.replace(/^\.\//, "")}`.toLowerCase();
364
+ const text = shim.replaceAll("\\", "/").toLowerCase();
365
+ return text.includes(`%dp0%/${target}"`) || text.includes(`%~dp0/${target}"`);
366
+ }
367
+ async function npmInstallation(command, packages, environment) {
368
+ let selected = await realpath(command);
369
+ if (process.platform === "win32" && /\.(cmd|bat)$/i.test(selected)) {
370
+ const shim = (await readFile(selected, "utf8")).replaceAll("\\", "/");
371
+ const root = path4.dirname(selected);
372
+ for (const name of packages) {
373
+ const directory2 = path4.join(root, "node_modules", ...name.split("/"));
374
+ const metadata = await readFile(path4.join(directory2, "package.json"), "utf8").then((text) => JSON.parse(text)).catch(() => null);
375
+ const bins = typeof metadata?.bin === "string" ? [metadata.bin] : Object.values(metadata?.bin ?? {});
376
+ const bin = bins.find((entry) => referencesNpmBin(shim, name, entry));
377
+ if (bin) {
378
+ selected = await realpath(path4.join(directory2, bin));
379
+ break;
380
+ }
381
+ }
382
+ }
383
+ let directory = path4.dirname(selected);
384
+ for (let depth = 0; depth < 8; depth++) {
385
+ const metadata = await readFile(path4.join(directory, "package.json"), "utf8").then((text) => JSON.parse(text)).catch(() => null);
386
+ if (metadata?.name && packages.includes(metadata.name)) {
387
+ const name = metadata.name;
388
+ const currentVersion = installationVersion(metadata.version);
389
+ const segments = name.split("/");
390
+ let modules = directory;
391
+ for (let index = 0; index < segments.length; index++)
392
+ modules = path4.dirname(modules);
393
+ const prefix = process.platform === "win32" ? path4.dirname(modules) : path4.dirname(path4.dirname(modules));
394
+ const globalRoot = process.platform === "win32" ? path4.join(prefix, "node_modules") : path4.join(prefix, "lib", "node_modules");
395
+ const env = withNodeRuntimeOnPath(environment);
396
+ const npm = resolveHarnessExecutable({ id: "npm", command: "npm", installRoots: { posix: [], windows: [] } }, { environment: env });
397
+ let globalInstall = modules === globalRoot;
398
+ if (process.platform === "win32") {
399
+ const project = (await Promise.all(["package.json", "package-lock.json", "npm-shrinkwrap.json"].map((file2) => readFile(path4.join(prefix, file2), "utf8").then(() => true, (error51) => error51.code !== "ENOENT")))).some(Boolean);
400
+ const bins = typeof metadata.bin === "string" ? { [name.split("/").at(-1) ?? name]: metadata.bin } : metadata.bin ?? {};
401
+ const launchers = await Promise.all(Object.entries(bins).map(async ([bin, entry]) => {
402
+ if (path4.basename(bin) !== bin || entry.includes(".."))
403
+ return false;
404
+ const target = await realpath(path4.join(directory, entry)).catch(() => "");
405
+ if (target.toLowerCase() !== selected.toLowerCase())
406
+ return false;
407
+ const shim = await readFile(path4.join(prefix, `${bin}.cmd`), "utf8").catch(() => "");
408
+ return referencesNpmBin(shim, name, entry);
409
+ }));
410
+ globalInstall = globalInstall && !project && launchers.some(Boolean);
411
+ }
412
+ const canUpdate = globalInstall && !!npm;
413
+ return {
414
+ prefix,
415
+ currentVersion,
416
+ canUpdate,
417
+ latest: async () => {
418
+ const data = JSON.parse(await fetchInstallationText(`https://registry.npmjs.org/${encodeURIComponent(name)}/latest`));
419
+ return installationVersion(data.version);
420
+ },
421
+ update: async (version2) => {
422
+ if (!canUpdate || !npm)
423
+ throw new Error("Use the original package manager to update this installation");
424
+ await runInstallationCommand(npm.executable, ["install", "--global", "--prefix", prefix, `${name}@${installationVersion(version2)}`], env, 3e5);
425
+ }
426
+ };
427
+ }
428
+ const parent = path4.dirname(directory);
429
+ if (parent === directory)
430
+ break;
431
+ directory = parent;
432
+ }
433
+ return null;
434
+ }
435
+
436
+ // ../../harness-discovery/dist/installer.js
437
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
438
+ import { tmpdir } from "node:os";
439
+ import { join } from "node:path";
440
+ function createHarnessInstaller(environment, source) {
441
+ return async () => {
442
+ if (!["darwin", "linux", "win32"].includes(process.platform))
443
+ throw new Error("Unsupported installation platform");
444
+ const env = withNodeRuntimeOnPath(environment);
445
+ if ("npm" in source) {
446
+ const npm = resolveHarnessExecutable({
447
+ id: "npm",
448
+ command: "npm",
449
+ installRoots: {
450
+ posix: [
451
+ "~/.npm-global/bin",
452
+ "~/.local/bin",
453
+ VERSION_MANAGER_ROOTS,
454
+ "/opt/homebrew/bin",
455
+ "/usr/local/bin",
456
+ "/usr/bin"
457
+ ],
458
+ windows: [
459
+ "${APPDATA}/npm",
460
+ VERSION_MANAGER_ROOTS,
461
+ "${ProgramFiles}/nodejs",
462
+ "${LOCALAPPDATA}/Programs/nodejs"
463
+ ]
464
+ }
465
+ }, { environment: env });
466
+ if (!npm)
467
+ throw new Error("Install Node.js and npm first");
468
+ await runInstallationCommand(npm.executable, ["install", "--global", source.npm], {
469
+ ...env,
470
+ ...source.allowScripts ? { npm_config_allow_scripts: source.allowScripts } : {}
471
+ }, 6e5);
472
+ return;
473
+ }
474
+ const windows = process.platform === "win32";
475
+ const url2 = windows ? source.windows : source.posix;
476
+ if (new URL(url2).protocol !== "https:")
477
+ throw new Error("Installer requires HTTPS");
478
+ const script = await fetchInstallationText(url2);
479
+ const directory = await mkdtemp(join(tmpdir(), "codexhost-installer-"));
480
+ try {
481
+ const file2 = join(directory, windows ? "install.ps1" : "install.sh");
482
+ await writeFile(file2, script, { mode: 384 });
483
+ await runInstallationCommand(windows ? "powershell.exe" : source.shell ?? "bash", windows ? ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", file2] : [file2], env, 6e5);
484
+ } finally {
485
+ await rm(directory, { recursive: true, force: true });
486
+ }
487
+ };
488
+ }
489
+
8
490
  // dist/opencode-adapter.js
9
491
  import { randomUUID } from "node:crypto";
10
492
  import fs4 from "node:fs";
@@ -776,10 +1258,10 @@ function mergeDefs(...defs) {
776
1258
  function cloneDef(schema) {
777
1259
  return mergeDefs(schema._zod.def);
778
1260
  }
779
- function getElementAtPath(obj, path12) {
780
- if (!path12)
1261
+ function getElementAtPath(obj, path13) {
1262
+ if (!path13)
781
1263
  return obj;
782
- return path12.reduce((acc, key) => acc?.[key], obj);
1264
+ return path13.reduce((acc, key) => acc?.[key], obj);
783
1265
  }
784
1266
  function promiseAllObject(promisesObj) {
785
1267
  const keys = Object.keys(promisesObj);
@@ -1188,11 +1670,11 @@ function explicitlyAborted(x, startIndex = 0) {
1188
1670
  }
1189
1671
  return false;
1190
1672
  }
1191
- function prefixIssues(path12, issues) {
1673
+ function prefixIssues(path13, issues) {
1192
1674
  return issues.map((iss) => {
1193
1675
  var _a3;
1194
1676
  (_a3 = iss).path ?? (_a3.path = []);
1195
- iss.path.unshift(path12);
1677
+ iss.path.unshift(path13);
1196
1678
  return iss;
1197
1679
  });
1198
1680
  }
@@ -1339,16 +1821,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1339
1821
  }
1340
1822
  function formatError(error51, mapper = (issue2) => issue2.message) {
1341
1823
  const fieldErrors = { _errors: [] };
1342
- const processError = (error52, path12 = []) => {
1824
+ const processError = (error52, path13 = []) => {
1343
1825
  for (const issue2 of error52.issues) {
1344
1826
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1345
- issue2.errors.map((issues) => processError({ issues }, [...path12, ...issue2.path]));
1827
+ issue2.errors.map((issues) => processError({ issues }, [...path13, ...issue2.path]));
1346
1828
  } else if (issue2.code === "invalid_key") {
1347
- processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
1829
+ processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
1348
1830
  } else if (issue2.code === "invalid_element") {
1349
- processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
1831
+ processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
1350
1832
  } else {
1351
- const fullpath = [...path12, ...issue2.path];
1833
+ const fullpath = [...path13, ...issue2.path];
1352
1834
  if (fullpath.length === 0) {
1353
1835
  fieldErrors._errors.push(mapper(issue2));
1354
1836
  } else {
@@ -1375,17 +1857,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1375
1857
  }
1376
1858
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1377
1859
  const result = { errors: [] };
1378
- const processError = (error52, path12 = []) => {
1860
+ const processError = (error52, path13 = []) => {
1379
1861
  var _a3, _b;
1380
1862
  for (const issue2 of error52.issues) {
1381
1863
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1382
- issue2.errors.map((issues) => processError({ issues }, [...path12, ...issue2.path]));
1864
+ issue2.errors.map((issues) => processError({ issues }, [...path13, ...issue2.path]));
1383
1865
  } else if (issue2.code === "invalid_key") {
1384
- processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
1866
+ processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
1385
1867
  } else if (issue2.code === "invalid_element") {
1386
- processError({ issues: issue2.issues }, [...path12, ...issue2.path]);
1868
+ processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
1387
1869
  } else {
1388
- const fullpath = [...path12, ...issue2.path];
1870
+ const fullpath = [...path13, ...issue2.path];
1389
1871
  if (fullpath.length === 0) {
1390
1872
  result.errors.push(mapper(issue2));
1391
1873
  continue;
@@ -1417,8 +1899,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
1417
1899
  }
1418
1900
  function toDotPath(_path) {
1419
1901
  const segs = [];
1420
- const path12 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1421
- for (const seg of path12) {
1902
+ const path13 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1903
+ for (const seg of path13) {
1422
1904
  if (typeof seg === "number")
1423
1905
  segs.push(`[${seg}]`);
1424
1906
  else if (typeof seg === "symbol")
@@ -14110,13 +14592,13 @@ function resolveRef(ref, ctx) {
14110
14592
  if (!ref.startsWith("#")) {
14111
14593
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14112
14594
  }
14113
- const path12 = ref.slice(1).split("/").filter(Boolean);
14114
- if (path12.length === 0) {
14595
+ const path13 = ref.slice(1).split("/").filter(Boolean);
14596
+ if (path13.length === 0) {
14115
14597
  return ctx.rootSchema;
14116
14598
  }
14117
14599
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14118
- if (path12[0] === defsKey) {
14119
- const key = path12[1];
14600
+ if (path13[0] === defsKey) {
14601
+ const key = path13[1];
14120
14602
  if (!key || !ctx.defs[key]) {
14121
14603
  throw new Error(`Reference not found: ${ref}`);
14122
14604
  }
@@ -14594,6 +15076,20 @@ var harnessDisplaySetSchema = external_exports.strictObject({
14594
15076
  initializeOnly: external_exports.boolean().optional()
14595
15077
  });
14596
15078
 
15079
+ // ../../shared-contracts/dist/ids.js
15080
+ var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
15081
+ message: "Identifier must not be empty or whitespace"
15082
+ });
15083
+ var harnessIdSchema = opaqueIdSchema.brand();
15084
+ var hostThreadIdSchema = opaqueIdSchema.brand();
15085
+ var hostTurnIdSchema = opaqueIdSchema.brand();
15086
+ var hostItemIdSchema = opaqueIdSchema.brand();
15087
+ var hostInteractionIdSchema = opaqueIdSchema.brand();
15088
+
15089
+ // ../../shared-contracts/dist/thread-prewarm.js
15090
+ var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
15091
+ var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
15092
+
14597
15093
  // ../../shared-contracts/dist/console.js
14598
15094
  var consoleAnnouncementSchema = external_exports.strictObject({
14599
15095
  title: external_exports.string().trim().min(1).max(200),
@@ -14606,10 +15102,14 @@ var consoleOpenResultSchema = external_exports.strictObject({
14606
15102
  url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
14607
15103
  });
14608
15104
  var CONSOLE_HOST_METHODS = Object.freeze([
15105
+ "codexhost/console/remote-connections",
15106
+ "codexhost/runtime/status",
15107
+ "codexhost/remote/ssh-setup",
14609
15108
  "codexhost/harness/plugins/list",
14610
15109
  "codexhost/harness/display-settings/get",
14611
15110
  "codexhost/harness/display-settings/set",
14612
15111
  "codexhost/harness/inspect",
15112
+ "codexhost/harness/installation",
14613
15113
  "codexhost/harness/launch-settings/get",
14614
15114
  "codexhost/harness/launch-settings/set",
14615
15115
  "codexhost/harness/web-ui/open",
@@ -14671,16 +15171,6 @@ var loadedSessionsSchema = external_exports.array(external_exports.strictObject(
14671
15171
  inactiveMs: external_exports.number().nonnegative()
14672
15172
  }));
14673
15173
 
14674
- // ../../shared-contracts/dist/ids.js
14675
- var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
14676
- message: "Identifier must not be empty or whitespace"
14677
- });
14678
- var harnessIdSchema = opaqueIdSchema.brand();
14679
- var hostThreadIdSchema = opaqueIdSchema.brand();
14680
- var hostTurnIdSchema = opaqueIdSchema.brand();
14681
- var hostItemIdSchema = opaqueIdSchema.brand();
14682
- var hostInteractionIdSchema = opaqueIdSchema.brand();
14683
-
14684
15174
  // ../../shared-contracts/dist/manual-compaction.js
14685
15175
  var threadManualCompactionStartedSchema = external_exports.strictObject({
14686
15176
  threadId: hostThreadIdSchema,
@@ -15256,14 +15746,17 @@ var harnessLaunchSettingsSchema = external_exports.object({
15256
15746
  // ../../shared-contracts/dist/harness-installation.js
15257
15747
  var harnessInstallationParamsSchema = external_exports.object({
15258
15748
  harnessId: harnessIdSchema,
15259
- action: external_exports.enum(["check", "update"])
15749
+ action: external_exports.enum(["check", "update", "install"])
15260
15750
  }).strict();
15261
15751
  var harnessInstallationStateSchema = external_exports.object({
15262
15752
  currentVersion: external_exports.string().min(1).max(128),
15263
15753
  latestVersion: external_exports.string().min(1).max(128),
15264
15754
  updateAvailable: external_exports.boolean(),
15265
15755
  canUpdate: external_exports.boolean(),
15266
- message: external_exports.string().max(2048).optional()
15756
+ // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15757
+ message: external_exports.string().max(2048).optional(),
15758
+ messageCode: external_exports.string().min(1).max(128).optional(),
15759
+ latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15267
15760
  }).strict();
15268
15761
 
15269
15762
  // ../../shared-contracts/dist/codex-accounts.js
@@ -15565,6 +16058,80 @@ var updateStatusResultSchema = external_exports.strictObject({
15565
16058
  status: updateStatusSchema.nullable()
15566
16059
  });
15567
16060
 
16061
+ // ../../shared-contracts/dist/remote-runtime.js
16062
+ var remoteUpdatePhaseSchema = external_exports.enum([
16063
+ "idle",
16064
+ "installing",
16065
+ "restarting",
16066
+ "succeeded",
16067
+ "failed"
16068
+ ]);
16069
+ var runtimeStatusSchema = external_exports.object({
16070
+ runningVersion: external_exports.string().nullable(),
16071
+ installedVersion: external_exports.string().nullable(),
16072
+ restartRequired: external_exports.boolean(),
16073
+ remote: external_exports.boolean(),
16074
+ updateSupported: external_exports.boolean(),
16075
+ update: external_exports.object({
16076
+ phase: remoteUpdatePhaseSchema,
16077
+ targetVersion: external_exports.string().nullable(),
16078
+ error: external_exports.string().nullable()
16079
+ })
16080
+ });
16081
+ var remoteUpdateParamsSchema = external_exports.object({
16082
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
16083
+ }).strict();
16084
+ var remoteSshSetupParamsSchema = external_exports.object({
16085
+ hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
16086
+ port: external_exports.number().int().min(1).max(65535).nullable(),
16087
+ identity: external_exports.string().max(4096).nullable(),
16088
+ action: external_exports.enum(["inspect", "install", "update", "repair", "uninstall"]),
16089
+ uninstallPackage: external_exports.boolean().optional(),
16090
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
16091
+ }).strict();
16092
+ var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
16093
+
16094
+ // ../../shared-contracts/dist/remote-connections.js
16095
+ var hostId = external_exports.string().min(1).max(1024);
16096
+ var codexSshConnectionSchema = external_exports.object({
16097
+ hostId,
16098
+ displayName: external_exports.string().min(1).max(1024),
16099
+ source: external_exports.enum(["codex-managed", "discovered"]),
16100
+ sshAlias: external_exports.string().max(1024).nullable(),
16101
+ sshHost: external_exports.string().min(1).max(1024),
16102
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
16103
+ identity: external_exports.string().max(4096).nullable(),
16104
+ autoConnect: external_exports.boolean(),
16105
+ connectionAnalyticsId: external_exports.string().max(1024).optional()
16106
+ });
16107
+ var codexSshDraftSchema = external_exports.strictObject({
16108
+ displayName: external_exports.string().min(1).max(1024),
16109
+ hostname: external_exports.string().min(1).max(1024),
16110
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
16111
+ identity: external_exports.string().max(4096).nullable()
16112
+ });
16113
+ var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
16114
+ external_exports.strictObject({ action: external_exports.literal("list") }),
16115
+ external_exports.strictObject({
16116
+ action: external_exports.literal("save"),
16117
+ draft: codexSshDraftSchema,
16118
+ previous: codexSshConnectionSchema.nullable()
16119
+ }),
16120
+ external_exports.strictObject({ action: external_exports.literal("remove"), previous: codexSshConnectionSchema }),
16121
+ external_exports.strictObject({ action: external_exports.literal("connect"), hostId, enabled: external_exports.boolean() }),
16122
+ external_exports.strictObject({ action: external_exports.literal("state"), hostId }),
16123
+ external_exports.strictObject({ action: external_exports.literal("runtime"), hostId }),
16124
+ external_exports.strictObject({
16125
+ action: external_exports.literal("update"),
16126
+ hostId: hostId.refine((id) => id !== "local"),
16127
+ version: remoteUpdateParamsSchema.shape.version
16128
+ })
16129
+ ]);
16130
+ var remoteConnectionsReplySchema = external_exports.union([
16131
+ external_exports.strictObject({ result: jsonValueSchema }),
16132
+ external_exports.strictObject({ error: external_exports.strictObject({ code: external_exports.number().int(), message: external_exports.string() }) })
16133
+ ]);
16134
+
15568
16135
  // ../../shared-contracts/dist/index.js
15569
16136
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15570
16137
 
@@ -15714,20 +16281,20 @@ function parseHostUsage(value) {
15714
16281
  }
15715
16282
  }
15716
16283
  for (const field of ["totalCredits", "contextUsagePercent"]) {
15717
- const candidate = value[field];
15718
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
16284
+ const candidate2 = value[field];
16285
+ if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isFinite(candidate2) || candidate2 < 0)) {
15719
16286
  throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
15720
16287
  }
15721
16288
  }
15722
16289
  for (const field of tokenFields) {
15723
- const candidate = value[field];
15724
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16290
+ const candidate2 = value[field];
16291
+ if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isSafeInteger(candidate2) || candidate2 < 0)) {
15725
16292
  throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
15726
16293
  }
15727
16294
  }
15728
16295
  for (const field of safeIntegerFields) {
15729
- const candidate = value[field];
15730
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16296
+ const candidate2 = value[field];
16297
+ if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isSafeInteger(candidate2) || candidate2 < 0)) {
15731
16298
  throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
15732
16299
  }
15733
16300
  }
@@ -15738,8 +16305,8 @@ function parseHostUsage(value) {
15738
16305
  throw new Error("Harness Usage 'totalCostUsd' must be a finite non-negative number");
15739
16306
  }
15740
16307
  for (const field of percentFields) {
15741
- const candidate = value[field];
15742
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0 || candidate > 100)) {
16308
+ const candidate2 = value[field];
16309
+ if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isFinite(candidate2) || candidate2 < 0 || candidate2 > 100)) {
15743
16310
  throw new Error(`Harness Usage '${field}' must be between 0 and 100`);
15744
16311
  }
15745
16312
  }
@@ -15852,7 +16419,7 @@ function normalizeOpenCodeModelCatalog(catalog) {
15852
16419
  ...Object.keys(model.variants ?? {}).sort(compareText).map(encodeOpenCodeVariant)
15853
16420
  ]
15854
16421
  })).sort((left, right) => compareText(left.label, right.label) || compareText(left.ref.id, right.ref.id));
15855
- const defaultNative = catalog.connected.map((providerID) => ({ providerID, modelID: catalog.default[providerID] })).find((candidate) => typeof candidate.modelID === "string" && candidate.modelID.length > 0);
16422
+ const defaultNative = catalog.connected.map((providerID) => ({ providerID, modelID: catalog.default[providerID] })).find((candidate2) => typeof candidate2.modelID === "string" && candidate2.modelID.length > 0);
15856
16423
  const defaultModel = defaultNative ? encodeOpenCodeModelRef(defaultNative) : void 0;
15857
16424
  return harnessModelCatalogSchema.parse({
15858
16425
  models,
@@ -16185,7 +16752,7 @@ import { randomBytes } from "node:crypto";
16185
16752
  import { spawn, spawnSync } from "node:child_process";
16186
16753
  import fs2 from "node:fs";
16187
16754
  import { createServer } from "node:net";
16188
- import { homedir as homedir2, tmpdir } from "node:os";
16755
+ import { homedir as homedir2, tmpdir as tmpdir2 } from "node:os";
16189
16756
  import path6 from "node:path";
16190
16757
 
16191
16758
  // ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js
@@ -16412,7 +16979,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
16412
16979
 
16413
16980
  // ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/utils.gen.js
16414
16981
  var PATH_PARAM_RE = /\{[^{}]+\}/g;
16415
- var defaultPathSerializer = ({ path: path12, url: _url2 }) => {
16982
+ var defaultPathSerializer = ({ path: path13, url: _url2 }) => {
16416
16983
  let url2 = _url2;
16417
16984
  const matches = _url2.match(PATH_PARAM_RE);
16418
16985
  if (matches) {
@@ -16431,7 +16998,7 @@ var defaultPathSerializer = ({ path: path12, url: _url2 }) => {
16431
16998
  name = name.substring(1);
16432
16999
  style = "matrix";
16433
17000
  }
16434
- const value = path12[name];
17001
+ const value = path13[name];
16435
17002
  if (value === void 0 || value === null) {
16436
17003
  continue;
16437
17004
  }
@@ -16462,11 +17029,11 @@ var defaultPathSerializer = ({ path: path12, url: _url2 }) => {
16462
17029
  }
16463
17030
  return url2;
16464
17031
  };
16465
- var getUrl = ({ baseUrl, path: path12, query, querySerializer, url: _url2 }) => {
17032
+ var getUrl = ({ baseUrl, path: path13, query, querySerializer, url: _url2 }) => {
16466
17033
  const pathUrl = _url2.startsWith("/") ? _url2 : `/${_url2}`;
16467
17034
  let url2 = (baseUrl ?? "") + pathUrl;
16468
- if (path12) {
16469
- url2 = defaultPathSerializer({ path: path12, url: url2 });
17035
+ if (path13) {
17036
+ url2 = defaultPathSerializer({ path: path13, url: url2 });
16470
17037
  }
16471
17038
  let search = query ? querySerializer(query) : "";
16472
17039
  if (search.startsWith("?")) {
@@ -21360,666 +21927,236 @@ var V2 = class extends HeyApiClient {
21360
21927
  get question() {
21361
21928
  return this._question ??= new Question3({ client: this.client });
21362
21929
  }
21363
- _reference;
21364
- get reference() {
21365
- return this._reference ??= new Reference({ client: this.client });
21366
- }
21367
- _projectCopy;
21368
- get projectCopy() {
21369
- return this._projectCopy ??= new ProjectCopy2({ client: this.client });
21370
- }
21371
- };
21372
- var OpencodeClient = class _OpencodeClient extends HeyApiClient {
21373
- static __registry = new HeyApiRegistry();
21374
- constructor(args) {
21375
- super(args);
21376
- _OpencodeClient.__registry.set(this, args?.key);
21377
- }
21378
- _auth;
21379
- get auth() {
21380
- return this._auth ??= new Auth({ client: this.client });
21381
- }
21382
- _app;
21383
- get app() {
21384
- return this._app ??= new App({ client: this.client });
21385
- }
21386
- _experimental;
21387
- get experimental() {
21388
- return this._experimental ??= new Experimental({ client: this.client });
21389
- }
21390
- _global;
21391
- get global() {
21392
- return this._global ??= new Global({ client: this.client });
21393
- }
21394
- _event;
21395
- get event() {
21396
- return this._event ??= new Event({ client: this.client });
21397
- }
21398
- _config;
21399
- get config() {
21400
- return this._config ??= new Config2({ client: this.client });
21401
- }
21402
- _tool;
21403
- get tool() {
21404
- return this._tool ??= new Tool({ client: this.client });
21405
- }
21406
- _worktree;
21407
- get worktree() {
21408
- return this._worktree ??= new Worktree({ client: this.client });
21409
- }
21410
- _find;
21411
- get find() {
21412
- return this._find ??= new Find({ client: this.client });
21413
- }
21414
- _file;
21415
- get file() {
21416
- return this._file ??= new File2({ client: this.client });
21417
- }
21418
- _instance;
21419
- get instance() {
21420
- return this._instance ??= new Instance({ client: this.client });
21421
- }
21422
- _path;
21423
- get path() {
21424
- return this._path ??= new Path({ client: this.client });
21425
- }
21426
- _vcs;
21427
- get vcs() {
21428
- return this._vcs ??= new Vcs({ client: this.client });
21429
- }
21430
- _command;
21431
- get command() {
21432
- return this._command ??= new Command({ client: this.client });
21433
- }
21434
- _lsp;
21435
- get lsp() {
21436
- return this._lsp ??= new Lsp({ client: this.client });
21437
- }
21438
- _formatter;
21439
- get formatter() {
21440
- return this._formatter ??= new Formatter({ client: this.client });
21441
- }
21442
- _mcp;
21443
- get mcp() {
21444
- return this._mcp ??= new Mcp({ client: this.client });
21445
- }
21446
- _project;
21447
- get project() {
21448
- return this._project ??= new Project({ client: this.client });
21449
- }
21450
- _pty;
21451
- get pty() {
21452
- return this._pty ??= new Pty({ client: this.client });
21453
- }
21454
- _question;
21455
- get question() {
21456
- return this._question ??= new Question({ client: this.client });
21457
- }
21458
- _permission;
21459
- get permission() {
21460
- return this._permission ??= new Permission({ client: this.client });
21461
- }
21462
- _provider;
21463
- get provider() {
21464
- return this._provider ??= new Provider({ client: this.client });
21465
- }
21466
- _session;
21467
- get session() {
21468
- return this._session ??= new Session2({ client: this.client });
21469
- }
21470
- _part;
21471
- get part() {
21472
- return this._part ??= new Part({ client: this.client });
21473
- }
21474
- _sync;
21475
- get sync() {
21476
- return this._sync ??= new Sync({ client: this.client });
21477
- }
21478
- _tui;
21479
- get tui() {
21480
- return this._tui ??= new Tui({ client: this.client });
21930
+ _reference;
21931
+ get reference() {
21932
+ return this._reference ??= new Reference({ client: this.client });
21481
21933
  }
21482
- _v2;
21483
- get v2() {
21484
- return this._v2 ??= new V2({ client: this.client });
21934
+ _projectCopy;
21935
+ get projectCopy() {
21936
+ return this._projectCopy ??= new ProjectCopy2({ client: this.client });
21485
21937
  }
21486
21938
  };
21487
-
21488
- // ../../../node_modules/@opencode-ai/sdk/dist/error-interceptor.js
21489
- function wrapClientError(error51, response, request, opts) {
21490
- if (!opts?.throwOnError)
21491
- return error51;
21492
- if (error51 instanceof Error)
21493
- return error51;
21494
- if (typeof error51 === "object" && error51 !== null && Object.keys(error51).length > 0) {
21495
- const obj = error51;
21496
- const message = typeof obj.data?.message === "string" && obj.data.message || typeof obj.message === "string" && obj.message || typeof obj.name === "string" && obj.name || describe3(request, response);
21497
- return new Error(message, { cause: { body: error51, status: response?.status } });
21939
+ var OpencodeClient = class _OpencodeClient extends HeyApiClient {
21940
+ static __registry = new HeyApiRegistry();
21941
+ constructor(args) {
21942
+ super(args);
21943
+ _OpencodeClient.__registry.set(this, args?.key);
21498
21944
  }
21499
- if (typeof error51 === "string" && error51.length > 0) {
21500
- return new Error(error51, { cause: { body: error51, status: response?.status } });
21945
+ _auth;
21946
+ get auth() {
21947
+ return this._auth ??= new Auth({ client: this.client });
21501
21948
  }
21502
- const reason = response ? "(empty response body)" : "network error (no response)";
21503
- return new Error(`opencode server ${describe3(request, response)}: ${reason}`, {
21504
- cause: { body: error51, status: response?.status }
21505
- });
21506
- }
21507
- function describe3(request, response) {
21508
- const method = request?.method ?? "?";
21509
- const url2 = request?.url ?? "?";
21510
- const status = response?.status;
21511
- const statusText = response?.statusText;
21512
- return `${method} ${url2}${status ? " → " + status : ""}${statusText ? " " + statusText : ""}`;
21513
- }
21514
-
21515
- // ../../../node_modules/@opencode-ai/sdk/dist/v2/client.js
21516
- function pick2(value, fallback, encode3) {
21517
- if (!value)
21518
- return;
21519
- if (!fallback)
21520
- return value;
21521
- if (value === fallback)
21522
- return fallback;
21523
- if (encode3 && value === encode3(fallback))
21524
- return fallback;
21525
- return value;
21526
- }
21527
- function rewrite(request, values) {
21528
- if (request.method !== "GET" && request.method !== "HEAD")
21529
- return request;
21530
- const url2 = new URL(request.url);
21531
- let changed = false;
21532
- for (const [name, key] of [
21533
- ["x-opencode-directory", "directory"],
21534
- ["x-opencode-workspace", "workspace"]
21535
- ]) {
21536
- const value = pick2(request.headers.get(name), key === "directory" ? values.directory : values.workspace, key === "directory" ? encodeURIComponent : void 0);
21537
- if (!value)
21538
- continue;
21539
- for (const query of url2.pathname.startsWith("/api/") ? [key, `location[${key}]`] : [key]) {
21540
- if (!url2.searchParams.has(query)) {
21541
- url2.searchParams.set(query, value);
21542
- }
21543
- }
21544
- changed = true;
21949
+ _app;
21950
+ get app() {
21951
+ return this._app ??= new App({ client: this.client });
21545
21952
  }
21546
- if (!changed)
21547
- return request;
21548
- const next = new Request(url2, request);
21549
- next.headers.delete("x-opencode-directory");
21550
- next.headers.delete("x-opencode-workspace");
21551
- return next;
21552
- }
21553
- function createOpencodeClient(config2) {
21554
- if (!config2?.fetch) {
21555
- const customFetch = (req) => {
21556
- req.timeout = false;
21557
- return fetch(req);
21558
- };
21559
- config2 = {
21560
- ...config2,
21561
- fetch: customFetch
21562
- };
21953
+ _experimental;
21954
+ get experimental() {
21955
+ return this._experimental ??= new Experimental({ client: this.client });
21563
21956
  }
21564
- if (config2?.directory) {
21565
- config2.headers = {
21566
- ...config2.headers,
21567
- "x-opencode-directory": encodeURIComponent(config2.directory)
21568
- };
21957
+ _global;
21958
+ get global() {
21959
+ return this._global ??= new Global({ client: this.client });
21569
21960
  }
21570
- if (config2?.experimental_workspaceID) {
21571
- config2.headers = {
21572
- ...config2.headers,
21573
- "x-opencode-workspace": config2.experimental_workspaceID
21574
- };
21961
+ _event;
21962
+ get event() {
21963
+ return this._event ??= new Event({ client: this.client });
21575
21964
  }
21576
- const client2 = createClient(config2);
21577
- client2.interceptors.request.use((request) => rewrite(request, {
21578
- directory: config2?.directory,
21579
- workspace: config2?.experimental_workspaceID
21580
- }));
21581
- client2.interceptors.response.use((response) => {
21582
- const contentType = response.headers.get("content-type");
21583
- if (contentType === "text/html")
21584
- throw new Error("Request is not supported by this version of OpenCode Server (Server responded with text/html)");
21585
- return response;
21586
- });
21587
- client2.interceptors.error.use(wrapClientError);
21588
- return new OpencodeClient({ client: client2 });
21589
- }
21590
-
21591
- // dist/command.js
21592
- import path5 from "node:path";
21593
-
21594
- // ../../harness-discovery/dist/environment.js
21595
- import fs from "node:fs";
21596
- import path from "node:path";
21597
- function targetPath(platform) {
21598
- return platform === "win32" ? path.win32 : path.posix;
21599
- }
21600
- function environmentValue(environment, name) {
21601
- const lowered = name.toLowerCase();
21602
- for (const [key, value] of Object.entries(environment)) {
21603
- if (key.toLowerCase() === lowered)
21604
- return value;
21965
+ _config;
21966
+ get config() {
21967
+ return this._config ??= new Config2({ client: this.client });
21605
21968
  }
21606
- return void 0;
21607
- }
21608
- function pathDelimiter(platform) {
21609
- return platform === "win32" ? ";" : ":";
21610
- }
21611
- function pathDirectories(environment, platform) {
21612
- return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
21613
- }
21614
- function executableExtensions(command, platform, environment) {
21615
- if (platform !== "win32")
21616
- return [""];
21617
- if (targetPath(platform).extname(command) !== "")
21618
- return [""];
21619
- return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
21620
- }
21621
- function isExecutableFile(filePath, platform) {
21622
- try {
21623
- fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
21624
- return fs.statSync(filePath).isFile();
21625
- } catch {
21626
- return false;
21969
+ _tool;
21970
+ get tool() {
21971
+ return this._tool ??= new Tool({ client: this.client });
21627
21972
  }
21628
- }
21629
- function subdirectoryNames(directory) {
21630
- try {
21631
- return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
21632
- } catch {
21633
- return [];
21973
+ _worktree;
21974
+ get worktree() {
21975
+ return this._worktree ??= new Worktree({ client: this.client });
21634
21976
  }
21635
- }
21636
- function newestFirst(names) {
21637
- return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
21638
- }
21639
-
21640
- // ../../harness-discovery/dist/invocation.js
21641
- import path2 from "node:path";
21642
- function commandInvocation(command, arguments_, environment, platform = process.platform) {
21643
- const extension = path2.win32.extname(command).toLowerCase();
21644
- if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
21645
- return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
21977
+ _find;
21978
+ get find() {
21979
+ return this._find ??= new Find({ client: this.client });
21646
21980
  }
21647
- const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
21648
- const commandLine = [command, ...arguments_].map(quote).join(" ");
21649
- return {
21650
- command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
21651
- arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
21652
- windowsVerbatimArguments: true
21653
- };
21654
- }
21655
-
21656
- // ../../harness-discovery/dist/node-runtime.js
21657
- import path3 from "node:path";
21658
- function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
21659
- const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
21660
- const delimiter = platform === "win32" ? ";" : ":";
21661
- const runtimeDirectory = path3.dirname(runtimeExecutable);
21662
- const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
21663
- const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
21664
- if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
21665
- directories.push(runtimeDirectory);
21981
+ _file;
21982
+ get file() {
21983
+ return this._file ??= new File2({ client: this.client });
21666
21984
  }
21667
- return { ...environment, [pathKey]: directories.join(delimiter) };
21668
- }
21669
-
21670
- // ../../harness-discovery/dist/resolve.js
21671
- import os from "node:os";
21672
-
21673
- // ../../harness-discovery/dist/version-managers.js
21674
- function versionManagerBinaryDirectories(context) {
21675
- const { platform, environment, home } = context;
21676
- const list = context.subdirectories ?? subdirectoryNames;
21677
- const pathFlavor = targetPath(platform);
21678
- const value = (name) => environmentValue(environment, name);
21679
- const directories = [];
21680
- const versioned = (root, ...tail) => {
21681
- for (const version2 of newestFirst(list(root))) {
21682
- directories.push(pathFlavor.join(root, version2, ...tail));
21683
- }
21684
- };
21685
- if (platform === "win32") {
21686
- const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
21687
- const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
21688
- versioned(pathFlavor.join(appData, "nvm"));
21689
- versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
21690
- directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
21691
- directories.push(pathFlavor.join(home, ".bun", "bin"));
21692
- const pnpmHome2 = value("PNPM_HOME");
21693
- if (pnpmHome2)
21694
- directories.push(pnpmHome2);
21695
- directories.push(pathFlavor.join(localAppData, "pnpm"));
21696
- return directories;
21985
+ _instance;
21986
+ get instance() {
21987
+ return this._instance ??= new Instance({ client: this.client });
21988
+ }
21989
+ _path;
21990
+ get path() {
21991
+ return this._path ??= new Path({ client: this.client });
21992
+ }
21993
+ _vcs;
21994
+ get vcs() {
21995
+ return this._vcs ??= new Vcs({ client: this.client });
21697
21996
  }
21698
- versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
21699
- const fnmRoots = [
21700
- value("FNM_DIR"),
21701
- pathFlavor.join(home, ".local", "share", "fnm"),
21702
- pathFlavor.join(home, "Library", "Application Support", "fnm")
21703
- ].filter((root) => root !== void 0);
21704
- for (const root of fnmRoots) {
21705
- versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
21997
+ _command;
21998
+ get command() {
21999
+ return this._command ??= new Command({ client: this.client });
21706
22000
  }
21707
- const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
21708
- versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
21709
- directories.push(pathFlavor.join(voltaHome, "bin"));
21710
- const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
21711
- versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
21712
- directories.push(pathFlavor.join(asdfHome, "shims"));
21713
- const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
21714
- versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
21715
- directories.push(pathFlavor.join(nodenvHome, "shims"));
21716
- versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
21717
- directories.push(pathFlavor.join(home, ".bun", "bin"));
21718
- const pnpmHome = value("PNPM_HOME");
21719
- if (pnpmHome)
21720
- directories.push(pnpmHome);
21721
- directories.push(pathFlavor.join(home, "Library", "pnpm"));
21722
- directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
21723
- for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
21724
- for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
21725
- directories.push(pathFlavor.join(prefix, formula, "bin"));
21726
- }
22001
+ _lsp;
22002
+ get lsp() {
22003
+ return this._lsp ??= new Lsp({ client: this.client });
21727
22004
  }
21728
- return directories;
21729
- }
21730
-
21731
- // ../../harness-discovery/dist/resolve.js
21732
- var VERSION_MANAGER_ROOTS = "<version-managers>";
21733
- function installRootExtensions(platform) {
21734
- return platform === "win32" ? [".exe", ".cmd"] : [""];
21735
- }
21736
- function resolveHomeDirectory(input) {
21737
- return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
21738
- }
21739
- function templateVariables(environment, platform, home) {
21740
- const pathFlavor = targetPath(platform);
21741
- return {
21742
- HOME: home,
21743
- USERPROFILE: home,
21744
- APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
21745
- LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
21746
- };
21747
- }
21748
- function joinTemplate(platform, value) {
21749
- const pathFlavor = targetPath(platform);
21750
- const segments = value.split("/");
21751
- const head = segments[0] ?? "";
21752
- const tail = segments.slice(1);
21753
- if (head === "")
21754
- return pathFlavor.join(pathFlavor.sep, ...tail);
21755
- return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
21756
- }
21757
- function expandInstallRoot(template, environment, platform, home) {
21758
- const variables = templateVariables(environment, platform, home);
21759
- let unresolved = false;
21760
- const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
21761
- const value = variables[name] ?? environmentValue(environment, name);
21762
- if (value === void 0 || value === "") {
21763
- unresolved = true;
21764
- return "";
21765
- }
21766
- return value;
21767
- });
21768
- return unresolved ? void 0 : joinTemplate(platform, substituted);
21769
- }
21770
- function installRootDirectories(spec, input, dependencies, platform, home) {
21771
- const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
21772
- const directories = [];
21773
- for (const template of templates) {
21774
- if (template === VERSION_MANAGER_ROOTS) {
21775
- directories.push(...versionManagerBinaryDirectories({
21776
- platform,
21777
- environment: input.environment,
21778
- home,
21779
- ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
21780
- }));
21781
- continue;
21782
- }
21783
- const directory = expandInstallRoot(template, input.environment, platform, home);
21784
- if (directory !== void 0)
21785
- directories.push(directory);
22005
+ _formatter;
22006
+ get formatter() {
22007
+ return this._formatter ??= new Formatter({ client: this.client });
21786
22008
  }
21787
- return directories;
21788
- }
21789
- function harnessCandidates(spec, input, dependencies = {}) {
21790
- const platform = input.platform ?? process.platform;
21791
- const pathFlavor = targetPath(platform);
21792
- const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
21793
- const command = configured ?? spec.command;
21794
- if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
21795
- return [{ candidate: command, source: "configured" }];
22009
+ _mcp;
22010
+ get mcp() {
22011
+ return this._mcp ??= new Mcp({ client: this.client });
21796
22012
  }
21797
- const candidates = [];
21798
- const extensions = executableExtensions(command, platform, input.environment);
21799
- for (const directory of pathDirectories(input.environment, platform)) {
21800
- for (const extension of extensions) {
21801
- candidates.push({
21802
- candidate: pathFlavor.join(directory, command + extension),
21803
- source: "path"
21804
- });
21805
- }
22013
+ _project;
22014
+ get project() {
22015
+ return this._project ??= new Project({ client: this.client });
21806
22016
  }
21807
- if (configured !== void 0)
21808
- return candidates;
21809
- const home = resolveHomeDirectory(input);
21810
- for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
21811
- for (const extension of installRootExtensions(platform)) {
21812
- candidates.push({
21813
- candidate: pathFlavor.join(directory, spec.command + extension),
21814
- source: "install-root"
21815
- });
21816
- }
22017
+ _pty;
22018
+ get pty() {
22019
+ return this._pty ??= new Pty({ client: this.client });
21817
22020
  }
21818
- return candidates;
21819
- }
21820
- function resolveHarnessExecutable(spec, input, dependencies = {}) {
21821
- const platform = input.platform ?? process.platform;
21822
- const isExecutable = dependencies.isExecutable ?? ((candidate) => isExecutableFile(candidate, platform));
21823
- const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
21824
- const context = { platform, isExecutable };
21825
- for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
21826
- const executable = runnable(candidate, context);
21827
- if (executable !== void 0 && isExecutable(executable))
21828
- return { executable, source };
22021
+ _question;
22022
+ get question() {
22023
+ return this._question ??= new Question({ client: this.client });
21829
22024
  }
21830
- return void 0;
21831
- }
21832
-
21833
- // ../../harness-discovery/dist/installation.js
21834
- import { execFile } from "node:child_process";
21835
- import { homedir } from "node:os";
21836
- function runInstallationCommand(command, args, environment, timeout = 3e4) {
21837
- const env = withNodeRuntimeOnPath(environment);
21838
- const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
21839
- return new Promise((resolve, reject) => {
21840
- const child = execFile(invocation.command, invocation.arguments, {
21841
- env,
21842
- cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
21843
- encoding: "utf8",
21844
- timeout,
21845
- killSignal: "SIGKILL",
21846
- maxBuffer: 1024 * 1024,
21847
- windowsHide: true,
21848
- windowsVerbatimArguments: invocation.windowsVerbatimArguments
21849
- }, (error51, stdout, stderr) => {
21850
- if (error51)
21851
- reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
21852
- else
21853
- resolve((stdout || stderr).trim());
21854
- });
21855
- child.stdin?.end();
21856
- });
21857
- }
21858
- function installationVersion(value) {
21859
- if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
21860
- throw new Error("Harness returned an invalid version");
21861
- return value.trim().replace(/^v/, "");
21862
- }
21863
- function versionFromOutput(output) {
21864
- return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
21865
- }
21866
- function newerInstallationVersion(current, latest) {
21867
- const a = installationVersion(current).replace(/\+.*/, "");
21868
- const b = installationVersion(latest).replace(/\+.*/, "");
21869
- const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
21870
- const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
21871
- for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
21872
- if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
21873
- return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
22025
+ _permission;
22026
+ get permission() {
22027
+ return this._permission ??= new Permission({ client: this.client });
21874
22028
  }
21875
- const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
21876
- const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
21877
- if (!preA.length || !preB.length)
21878
- return !!preA.length && !preB.length;
21879
- for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
21880
- const x = preA[i];
21881
- const y = preB[i];
21882
- if (x === y)
21883
- continue;
21884
- if (x === void 0 || y === void 0)
21885
- return x === void 0;
21886
- const numericX = /^\d+$/.test(x);
21887
- const numericY = /^\d+$/.test(y);
21888
- if (numericX && numericY) {
21889
- if (BigInt(x) === BigInt(y))
21890
- continue;
21891
- return BigInt(y) > BigInt(x);
21892
- }
21893
- if (numericX !== numericY)
21894
- return numericX;
21895
- return y > x;
22029
+ _provider;
22030
+ get provider() {
22031
+ return this._provider ??= new Provider({ client: this.client });
21896
22032
  }
21897
- return false;
21898
- }
21899
- function createInstallationManager(options) {
21900
- let checking;
21901
- let updating;
21902
- const check2 = () => checking ??= options.check().finally(() => {
21903
- checking = void 0;
22033
+ _session;
22034
+ get session() {
22035
+ return this._session ??= new Session2({ client: this.client });
22036
+ }
22037
+ _part;
22038
+ get part() {
22039
+ return this._part ??= new Part({ client: this.client });
22040
+ }
22041
+ _sync;
22042
+ get sync() {
22043
+ return this._sync ??= new Sync({ client: this.client });
22044
+ }
22045
+ _tui;
22046
+ get tui() {
22047
+ return this._tui ??= new Tui({ client: this.client });
22048
+ }
22049
+ _v2;
22050
+ get v2() {
22051
+ return this._v2 ??= new V2({ client: this.client });
22052
+ }
22053
+ };
22054
+
22055
+ // ../../../node_modules/@opencode-ai/sdk/dist/error-interceptor.js
22056
+ function wrapClientError(error51, response, request, opts) {
22057
+ if (!opts?.throwOnError)
22058
+ return error51;
22059
+ if (error51 instanceof Error)
22060
+ return error51;
22061
+ if (typeof error51 === "object" && error51 !== null && Object.keys(error51).length > 0) {
22062
+ const obj = error51;
22063
+ const message = typeof obj.data?.message === "string" && obj.data.message || typeof obj.message === "string" && obj.message || typeof obj.name === "string" && obj.name || describe3(request, response);
22064
+ return new Error(message, { cause: { body: error51, status: response?.status } });
22065
+ }
22066
+ if (typeof error51 === "string" && error51.length > 0) {
22067
+ return new Error(error51, { cause: { body: error51, status: response?.status } });
22068
+ }
22069
+ const reason = response ? "(empty response body)" : "network error (no response)";
22070
+ return new Error(`opencode server ${describe3(request, response)}: ${reason}`, {
22071
+ cause: { body: error51, status: response?.status }
21904
22072
  });
21905
- return (action) => {
21906
- if (updating)
21907
- return updating;
21908
- if (action === "check")
21909
- return check2();
21910
- updating = (async () => {
21911
- const before = await check2();
21912
- if (!before.updateAvailable)
21913
- return before;
21914
- if (!before.canUpdate)
21915
- throw new Error(before.message ?? "This installation cannot be updated automatically");
21916
- await options.update(before);
21917
- const after = await check2();
21918
- if (after.currentVersion === before.currentVersion)
21919
- throw new Error("The Harness version did not change; check the native updater and retry");
21920
- return after;
21921
- })().finally(() => {
21922
- updating = void 0;
21923
- });
21924
- return updating;
21925
- };
21926
22073
  }
21927
- async function fetchInstallationText(url2) {
21928
- const request = async () => {
21929
- const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
21930
- if (!response.ok)
21931
- throw new Error("Could not check the latest Harness version");
21932
- return response.text();
21933
- };
21934
- try {
21935
- return await request();
21936
- } catch (error51) {
21937
- if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
21938
- throw error51;
21939
- return request();
21940
- }
22074
+ function describe3(request, response) {
22075
+ const method = request?.method ?? "?";
22076
+ const url2 = request?.url ?? "?";
22077
+ const status = response?.status;
22078
+ const statusText = response?.statusText;
22079
+ return `${method} ${url2}${status ? " → " + status : ""}${statusText ? " " + statusText : ""}`;
21941
22080
  }
21942
22081
 
21943
- // ../../harness-discovery/dist/npm-installation.js
21944
- import { readFile, realpath } from "node:fs/promises";
21945
- import path4 from "node:path";
21946
- function referencesNpmBin(shim, name, bin) {
21947
- if (bin.includes(".."))
21948
- return false;
21949
- const target = `node_modules/${name}/${bin.replace(/^\.\//, "")}`.toLowerCase();
21950
- const text = shim.replaceAll("\\", "/").toLowerCase();
21951
- return text.includes(`%dp0%/${target}"`) || text.includes(`%~dp0/${target}"`);
22082
+ // ../../../node_modules/@opencode-ai/sdk/dist/v2/client.js
22083
+ function pick2(value, fallback, encode3) {
22084
+ if (!value)
22085
+ return;
22086
+ if (!fallback)
22087
+ return value;
22088
+ if (value === fallback)
22089
+ return fallback;
22090
+ if (encode3 && value === encode3(fallback))
22091
+ return fallback;
22092
+ return value;
21952
22093
  }
21953
- async function npmInstallation(command, packages, environment) {
21954
- let selected = await realpath(command);
21955
- if (process.platform === "win32" && /\.(cmd|bat)$/i.test(selected)) {
21956
- const shim = (await readFile(selected, "utf8")).replaceAll("\\", "/");
21957
- const root = path4.dirname(selected);
21958
- for (const name of packages) {
21959
- const directory2 = path4.join(root, "node_modules", ...name.split("/"));
21960
- const metadata = await readFile(path4.join(directory2, "package.json"), "utf8").then((text) => JSON.parse(text)).catch(() => null);
21961
- const bins = typeof metadata?.bin === "string" ? [metadata.bin] : Object.values(metadata?.bin ?? {});
21962
- const bin = bins.find((entry) => referencesNpmBin(shim, name, entry));
21963
- if (bin) {
21964
- selected = await realpath(path4.join(directory2, bin));
21965
- break;
22094
+ function rewrite(request, values) {
22095
+ if (request.method !== "GET" && request.method !== "HEAD")
22096
+ return request;
22097
+ const url2 = new URL(request.url);
22098
+ let changed = false;
22099
+ for (const [name, key] of [
22100
+ ["x-opencode-directory", "directory"],
22101
+ ["x-opencode-workspace", "workspace"]
22102
+ ]) {
22103
+ const value = pick2(request.headers.get(name), key === "directory" ? values.directory : values.workspace, key === "directory" ? encodeURIComponent : void 0);
22104
+ if (!value)
22105
+ continue;
22106
+ for (const query of url2.pathname.startsWith("/api/") ? [key, `location[${key}]`] : [key]) {
22107
+ if (!url2.searchParams.has(query)) {
22108
+ url2.searchParams.set(query, value);
21966
22109
  }
21967
22110
  }
22111
+ changed = true;
21968
22112
  }
21969
- let directory = path4.dirname(selected);
21970
- for (let depth = 0; depth < 8; depth++) {
21971
- const metadata = await readFile(path4.join(directory, "package.json"), "utf8").then((text) => JSON.parse(text)).catch(() => null);
21972
- if (metadata?.name && packages.includes(metadata.name)) {
21973
- const name = metadata.name;
21974
- const currentVersion = installationVersion(metadata.version);
21975
- const segments = name.split("/");
21976
- let modules = directory;
21977
- for (let index = 0; index < segments.length; index++)
21978
- modules = path4.dirname(modules);
21979
- const prefix = process.platform === "win32" ? path4.dirname(modules) : path4.dirname(path4.dirname(modules));
21980
- const globalRoot = process.platform === "win32" ? path4.join(prefix, "node_modules") : path4.join(prefix, "lib", "node_modules");
21981
- const env = withNodeRuntimeOnPath(environment);
21982
- const npm = resolveHarnessExecutable({ id: "npm", command: "npm", installRoots: { posix: [], windows: [] } }, { environment: env });
21983
- let globalInstall = modules === globalRoot;
21984
- if (process.platform === "win32") {
21985
- const project = (await Promise.all(["package.json", "package-lock.json", "npm-shrinkwrap.json"].map((file2) => readFile(path4.join(prefix, file2), "utf8").then(() => true, (error51) => error51.code !== "ENOENT")))).some(Boolean);
21986
- const bins = typeof metadata.bin === "string" ? { [name.split("/").at(-1) ?? name]: metadata.bin } : metadata.bin ?? {};
21987
- const launchers = await Promise.all(Object.entries(bins).map(async ([bin, entry]) => {
21988
- if (path4.basename(bin) !== bin || entry.includes(".."))
21989
- return false;
21990
- const target = await realpath(path4.join(directory, entry)).catch(() => "");
21991
- if (target.toLowerCase() !== selected.toLowerCase())
21992
- return false;
21993
- const shim = await readFile(path4.join(prefix, `${bin}.cmd`), "utf8").catch(() => "");
21994
- return referencesNpmBin(shim, name, entry);
21995
- }));
21996
- globalInstall = globalInstall && !project && launchers.some(Boolean);
21997
- }
21998
- const canUpdate = globalInstall && !!npm;
21999
- return {
22000
- prefix,
22001
- currentVersion,
22002
- canUpdate,
22003
- latest: async () => {
22004
- const data = JSON.parse(await fetchInstallationText(`https://registry.npmjs.org/${encodeURIComponent(name)}/latest`));
22005
- return installationVersion(data.version);
22006
- },
22007
- update: async (version2) => {
22008
- if (!canUpdate || !npm)
22009
- throw new Error("Use the original package manager to update this installation");
22010
- await runInstallationCommand(npm.executable, ["install", "--global", "--prefix", prefix, `${name}@${installationVersion(version2)}`], env, 3e5);
22011
- }
22012
- };
22013
- }
22014
- const parent = path4.dirname(directory);
22015
- if (parent === directory)
22016
- break;
22017
- directory = parent;
22113
+ if (!changed)
22114
+ return request;
22115
+ const next = new Request(url2, request);
22116
+ next.headers.delete("x-opencode-directory");
22117
+ next.headers.delete("x-opencode-workspace");
22118
+ return next;
22119
+ }
22120
+ function createOpencodeClient(config2) {
22121
+ if (!config2?.fetch) {
22122
+ const customFetch = (req) => {
22123
+ req.timeout = false;
22124
+ return fetch(req);
22125
+ };
22126
+ config2 = {
22127
+ ...config2,
22128
+ fetch: customFetch
22129
+ };
22018
22130
  }
22019
- return null;
22131
+ if (config2?.directory) {
22132
+ config2.headers = {
22133
+ ...config2.headers,
22134
+ "x-opencode-directory": encodeURIComponent(config2.directory)
22135
+ };
22136
+ }
22137
+ if (config2?.experimental_workspaceID) {
22138
+ config2.headers = {
22139
+ ...config2.headers,
22140
+ "x-opencode-workspace": config2.experimental_workspaceID
22141
+ };
22142
+ }
22143
+ const client2 = createClient(config2);
22144
+ client2.interceptors.request.use((request) => rewrite(request, {
22145
+ directory: config2?.directory,
22146
+ workspace: config2?.experimental_workspaceID
22147
+ }));
22148
+ client2.interceptors.response.use((response) => {
22149
+ const contentType = response.headers.get("content-type");
22150
+ if (contentType === "text/html")
22151
+ throw new Error("Request is not supported by this version of OpenCode Server (Server responded with text/html)");
22152
+ return response;
22153
+ });
22154
+ client2.interceptors.error.use(wrapClientError);
22155
+ return new OpencodeClient({ client: client2 });
22020
22156
  }
22021
22157
 
22022
22158
  // dist/command.js
22159
+ import path5 from "node:path";
22023
22160
  var OpenCodeExecutableError = class extends Error {
22024
22161
  code = "OPENCODE_NOT_FOUND";
22025
22162
  constructor(message = "OpenCode CLI is not installed") {
@@ -22148,15 +22285,15 @@ function signalProcessTree(child, signal) {
22148
22285
  }
22149
22286
  }
22150
22287
  function safeOpenCodeServerCwd(environment) {
22151
- const candidates = [environment.USERPROFILE, environment.HOME, homedir2(), tmpdir()];
22152
- for (const candidate of candidates) {
22153
- if (!candidate || !path6.isAbsolute(candidate))
22288
+ const candidates = [environment.USERPROFILE, environment.HOME, homedir2(), tmpdir2()];
22289
+ for (const candidate2 of candidates) {
22290
+ if (!candidate2 || !path6.isAbsolute(candidate2))
22154
22291
  continue;
22155
22292
  try {
22156
- if (!fs2.statSync(candidate).isDirectory())
22293
+ if (!fs2.statSync(candidate2).isDirectory())
22157
22294
  continue;
22158
- fs2.accessSync(candidate, fs2.constants.R_OK | fs2.constants.W_OK);
22159
- return candidate;
22295
+ fs2.accessSync(candidate2, fs2.constants.R_OK | fs2.constants.W_OK);
22296
+ return candidate2;
22160
22297
  } catch {
22161
22298
  }
22162
22299
  }
@@ -22611,19 +22748,19 @@ function hasDotPathSegment(value) {
22611
22748
  return segments.some((segment) => segment === "." || segment === "..");
22612
22749
  }
22613
22750
  function canonicalDirectoryPath(value) {
22614
- let candidate = path7.resolve(value);
22751
+ let candidate2 = path7.resolve(value);
22615
22752
  const missingSegments = [];
22616
22753
  for (; ; ) {
22617
22754
  try {
22618
- return path7.join(fs3.realpathSync.native(candidate), ...missingSegments);
22755
+ return path7.join(fs3.realpathSync.native(candidate2), ...missingSegments);
22619
22756
  } catch (error51) {
22620
22757
  if (!missingPath(error51))
22621
22758
  return void 0;
22622
- const parent = path7.dirname(candidate);
22623
- if (parent === candidate)
22759
+ const parent = path7.dirname(candidate2);
22760
+ if (parent === candidate2)
22624
22761
  return void 0;
22625
- missingSegments.unshift(path7.basename(candidate));
22626
- candidate = parent;
22762
+ missingSegments.unshift(path7.basename(candidate2));
22763
+ candidate2 = parent;
22627
22764
  }
22628
22765
  }
22629
22766
  }
@@ -22632,8 +22769,8 @@ function canonicalFilePath(value) {
22632
22769
  const parent = canonicalDirectoryPath(path7.dirname(absolute));
22633
22770
  return parent ? path7.join(parent, path7.basename(absolute)) : void 0;
22634
22771
  }
22635
- function pathIsWithin(root, candidate, allowRoot) {
22636
- const relative = path7.relative(root, candidate);
22772
+ function pathIsWithin(root, candidate2, allowRoot) {
22773
+ const relative = path7.relative(root, candidate2);
22637
22774
  return allowRoot && relative === "" || relative !== "" && relative !== ".." && !relative.startsWith(`..${path7.sep}`) && !path7.isAbsolute(relative);
22638
22775
  }
22639
22776
  function verifiedOpenCodeWorktree(sessionDirectory, paths) {
@@ -22652,8 +22789,8 @@ function openCodeFileIdentity(file2, worktree) {
22652
22789
  if (typeof file2 !== "string" || typeof worktree !== "string" || hasDotPathSegment(file2) || hasDotPathSegment(worktree) || !path7.isAbsolute(worktree) || !file2 || file2.includes("\0") || file2.includes("\n") || file2.includes("\r")) {
22653
22790
  return void 0;
22654
22791
  }
22655
- const candidate = canonicalFilePath(path7.isAbsolute(file2) ? file2 : path7.resolve(worktree, file2));
22656
- return candidate && pathIsWithin(worktree, candidate, false) ? candidate : void 0;
22792
+ const candidate2 = canonicalFilePath(path7.isAbsolute(file2) ? file2 : path7.resolve(worktree, file2));
22793
+ return candidate2 && pathIsWithin(worktree, candidate2, false) ? candidate2 : void 0;
22657
22794
  }
22658
22795
 
22659
22796
  // dist/usage.js
@@ -22882,20 +23019,20 @@ async function deriveOpenCodeHistory(options) {
22882
23019
  retainedCount = boundary.sourceTurnCount - 1;
22883
23020
  }
22884
23021
  const expectedHistory = structuredClone(semanticHistory(before.snapshot).slice(0, retainedCount));
22885
- let candidate = await transport.forkSession(source.id, messageID);
22886
- if (candidate.id === source.id) {
23022
+ let candidate2 = await transport.forkSession(source.id, messageID);
23023
+ if (candidate2.id === source.id) {
22887
23024
  throw new OpenCodeTransportError("protocolError", "OpenCode Fork did not create a distinct Native Session");
22888
23025
  }
22889
- const candidateID = candidate.id;
22890
- options.onCreated(candidate);
22891
- if (candidate.directory !== expectedSource.directory) {
23026
+ const candidateID = candidate2.id;
23027
+ options.onCreated(candidate2);
23028
+ if (candidate2.directory !== expectedSource.directory) {
22892
23029
  throw new OpenCodeTransportError("protocolError", "OpenCode Fork changed working directory");
22893
23030
  }
22894
23031
  if (expectedSource.model) {
22895
- candidate = await transport.updateSessionMetadata(candidateID, selectionMetadata(candidate, expectedSource.model, expectedSource.variant));
23032
+ candidate2 = await transport.updateSessionMetadata(candidateID, selectionMetadata(candidate2, expectedSource.model, expectedSource.variant));
22896
23033
  }
22897
- if (!isDeepStrictEqual(candidate.permission ?? [], expectedSource.permission ?? [])) {
22898
- candidate = await transport.updateSessionPermission(candidateID, expectedSource.permission ?? []);
23034
+ if (!isDeepStrictEqual(candidate2.permission ?? [], expectedSource.permission ?? [])) {
23035
+ candidate2 = await transport.updateSessionPermission(candidateID, expectedSource.permission ?? []);
22899
23036
  }
22900
23037
  const [derived, after, candidateStatus, sourceStatus] = await Promise.all([
22901
23038
  read(candidateID),
@@ -22903,7 +23040,7 @@ async function deriveOpenCodeHistory(options) {
22903
23040
  transport.getStatus(candidateID),
22904
23041
  transport.getStatus(source.id)
22905
23042
  ]);
22906
- if (derived.session.id !== candidateID || candidate.id !== candidateID || derived.session.directory !== before.session.directory || candidateStatus.type !== "idle" || sourceStatus.type !== "idle" || !isDeepStrictEqual(semanticHistory(derived.snapshot), expectedHistory) || !isDeepStrictEqual(sourceState(after), expectedSource) || !isDeepStrictEqual(derived.model, expectedSource.model) || derived.variant !== expectedSource.variant || !isDeepStrictEqual(derived.session.permission ?? [], expectedSource.permission ?? [])) {
23043
+ if (derived.session.id !== candidateID || candidate2.id !== candidateID || derived.session.directory !== before.session.directory || candidateStatus.type !== "idle" || sourceStatus.type !== "idle" || !isDeepStrictEqual(semanticHistory(derived.snapshot), expectedHistory) || !isDeepStrictEqual(sourceState(after), expectedSource) || !isDeepStrictEqual(derived.model, expectedSource.model) || derived.variant !== expectedSource.variant || !isDeepStrictEqual(derived.session.permission ?? [], expectedSource.permission ?? [])) {
22907
23044
  throw new OpenCodeTransportError("protocolError", "OpenCode derived history, source or configuration changed during Fork");
22908
23045
  }
22909
23046
  return derived.session;
@@ -24035,9 +24172,9 @@ var OpenCodeHarnessSession = class {
24035
24172
  if (active.userMessageID)
24036
24173
  return;
24037
24174
  const candidates = messages.filter(({ info }) => info.role === "user" && !active.preexistingUserMessageIds.has(info.id));
24038
- const [candidate] = candidates;
24039
- if (candidates.length === 1 && candidate) {
24040
- this.#bindUserMessage(active, candidate.info.id);
24175
+ const [candidate2] = candidates;
24176
+ if (candidates.length === 1 && candidate2) {
24177
+ this.#bindUserMessage(active, candidate2.info.id);
24041
24178
  return;
24042
24179
  }
24043
24180
  const parents = new Set(messages.filter(({ info }) => info.role === "assistant").map(({ info }) => info.parentID));
@@ -24255,8 +24392,8 @@ var OpenCodeAdapter = class {
24255
24392
  input,
24256
24393
  providers,
24257
24394
  toolOutputLimit: this.#toolOutputLimit,
24258
- onCreated: (candidate) => {
24259
- createdForCleanup = candidate;
24395
+ onCreated: (candidate2) => {
24396
+ createdForCleanup = candidate2;
24260
24397
  }
24261
24398
  });
24262
24399
  }
@@ -24323,7 +24460,7 @@ async function detectOpenCode(options) {
24323
24460
  }
24324
24461
 
24325
24462
  // dist/v2/adapter.js
24326
- import fs6 from "node:fs";
24463
+ import fs7 from "node:fs";
24327
24464
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
24328
24465
 
24329
24466
  // dist/v2/state.js
@@ -24398,7 +24535,7 @@ function v2Permissions(current = [], mode) {
24398
24535
  }
24399
24536
  function v2State(session, catalog, policy) {
24400
24537
  const model = session.model ? encodeOpenCodeModelRef({ providerID: session.model.providerID, modelID: session.model.id }) : void 0;
24401
- const entry = catalog.models.find((candidate) => candidate.ref.id === model?.id);
24538
+ const entry = catalog.models.find((candidate2) => candidate2.ref.id === model?.id);
24402
24539
  const mode = session.permissions?.findLast((rule) => rule.action === "*" && rule.resource === "*");
24403
24540
  return {
24404
24541
  nativeRef: v2Ref(session, policy),
@@ -26431,6 +26568,110 @@ function terminalItemOutcome(outcome) {
26431
26568
  return outcome.status === "unknown" ? { status: "failed", error: failure(outcome.reason, "protocolError") } : outcome;
26432
26569
  }
26433
26570
 
26571
+ // dist/v2/session-import.js
26572
+ import fs6 from "node:fs";
26573
+ import path11 from "node:path";
26574
+
26575
+ // ../../harness-adapter/dist/session-import.js
26576
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
26577
+ if (typeof value !== "string")
26578
+ return null;
26579
+ const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
26580
+ if (!normalized)
26581
+ return null;
26582
+ if (normalized.length <= maxLength)
26583
+ return normalized;
26584
+ const characters = [...normalized];
26585
+ if (characters.length <= maxLength)
26586
+ return normalized;
26587
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
26588
+ }
26589
+ function sessionImportCandidate(input) {
26590
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
26591
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
26592
+ nativeSessionId: input.nativeSessionId,
26593
+ cwd: input.cwd,
26594
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
26595
+ updatedAt: Math.floor(time3),
26596
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
26597
+ running: typeof input.running === "boolean" ? input.running : null
26598
+ });
26599
+ return parsed.success ? parsed.data : null;
26600
+ }
26601
+
26602
+ // dist/v2/session-import.js
26603
+ var PAGE_SIZE = 200;
26604
+ var MAX_PAGES = 1e4;
26605
+ function existingDirectory(directory) {
26606
+ if (typeof directory !== "string" || !path11.isAbsolute(directory))
26607
+ return null;
26608
+ try {
26609
+ return fs6.statSync(directory).isDirectory() ? directory : null;
26610
+ } catch {
26611
+ return null;
26612
+ }
26613
+ }
26614
+ function candidate(info, active) {
26615
+ if (info.parentID || info.time.archived !== void 0)
26616
+ return null;
26617
+ const cwd = existingDirectory(info.location.directory);
26618
+ if (!cwd)
26619
+ return null;
26620
+ return sessionImportCandidate({
26621
+ nativeSessionId: info.id,
26622
+ cwd,
26623
+ title: sessionImportTitle(info.title),
26624
+ updatedAt: info.time.updated,
26625
+ // This server only knows its own executions; another process may still hold the Session.
26626
+ running: active[info.id] ? true : null
26627
+ });
26628
+ }
26629
+ async function listV2SessionCandidates(client2) {
26630
+ const active = await client2.session.active();
26631
+ const candidates = /* @__PURE__ */ new Map();
26632
+ const cursors = /* @__PURE__ */ new Set();
26633
+ let cursor;
26634
+ for (let page = 0; page < MAX_PAGES; page += 1) {
26635
+ const response = await client2.session.list({
26636
+ limit: PAGE_SIZE,
26637
+ ...cursor ? { cursor } : {}
26638
+ });
26639
+ for (const info of response.data) {
26640
+ const entry = candidate(info, active);
26641
+ if (entry)
26642
+ candidates.set(entry.nativeSessionId, entry);
26643
+ }
26644
+ const next = response.cursor.next;
26645
+ if (!next || cursors.has(next))
26646
+ break;
26647
+ cursors.add(next);
26648
+ cursor = next;
26649
+ }
26650
+ return [...candidates.values()];
26651
+ }
26652
+ async function resolveV2SessionCandidate(client2, nativeSessionId) {
26653
+ const active = await client2.session.active();
26654
+ const cursors = /* @__PURE__ */ new Set();
26655
+ let cursor;
26656
+ for (let page = 0; page < MAX_PAGES; page += 1) {
26657
+ const response = await client2.session.list({
26658
+ limit: PAGE_SIZE,
26659
+ ...cursor ? { cursor } : {}
26660
+ });
26661
+ const info = response.data.find((entry) => entry.id === nativeSessionId);
26662
+ if (info) {
26663
+ const entry = candidate(info, active);
26664
+ return entry ? { candidate: entry, nativeRef: v2Ref(info, "default") } : null;
26665
+ }
26666
+ const next = response.cursor.next;
26667
+ if (!next || cursors.has(next))
26668
+ break;
26669
+ cursors.add(next);
26670
+ cursor = next;
26671
+ }
26672
+ return null;
26673
+ }
26674
+
26434
26675
  // dist/v2/interactions.js
26435
26676
  function permissionInteraction(request, turnId) {
26436
26677
  return {
@@ -27061,9 +27302,42 @@ var V2Adapter = class {
27061
27302
  this.#connections.delete(connection);
27062
27303
  }
27063
27304
  }
27305
+ sessionImport = {
27306
+ listCandidates: () => this.#discover((client2) => listV2SessionCandidates(client2)),
27307
+ resolveCandidate: async (nativeSessionId) => {
27308
+ const source = await this.#discover((client2) => resolveV2SessionCandidate(client2, nativeSessionId));
27309
+ if (!source.ok)
27310
+ return source;
27311
+ return source.value ? { ok: true, value: source.value } : {
27312
+ ok: false,
27313
+ error: failure("OpenCode Session is no longer importable", "sessionNotFound")
27314
+ };
27315
+ }
27316
+ };
27317
+ /** Read-only discovery on a private server: no Session is created, loaded or prompted. */
27318
+ async #discover(read) {
27319
+ if (this.#closed)
27320
+ return { ok: false, error: failure("OpenCode Adapter is closed", "invalidState") };
27321
+ const connection = new V2Connection(this.options, process.cwd());
27322
+ this.#connections.add(connection);
27323
+ try {
27324
+ const value = await read(await connection.client());
27325
+ if (this.#closed)
27326
+ throw new Error("OpenCode Adapter closed during Session discovery");
27327
+ return { ok: true, value };
27328
+ } catch {
27329
+ return {
27330
+ ok: false,
27331
+ error: this.#closed ? failure("OpenCode Adapter is closed", "invalidState") : failure("OpenCode sessions could not be read; check the installation and retry", "unavailable")
27332
+ };
27333
+ } finally {
27334
+ await connection.close();
27335
+ this.#connections.delete(connection);
27336
+ }
27337
+ }
27064
27338
  async open(input) {
27065
27339
  try {
27066
- input = { ...input, cwd: fs6.realpathSync(input.cwd) };
27340
+ input = { ...input, cwd: fs7.realpathSync(input.cwd) };
27067
27341
  } catch (error51) {
27068
27342
  return errorResult(error51);
27069
27343
  }
@@ -27243,6 +27517,36 @@ var OpenCodeAdapter2 = class {
27243
27517
  this.#adapters.add(adapter);
27244
27518
  return adapter;
27245
27519
  }
27520
+ sessionImport = {
27521
+ listCandidates: () => this.#discover((imports) => imports.listCandidates()),
27522
+ resolveCandidate: (nativeSessionId) => this.#discover((imports) => imports.resolveCandidate(nativeSessionId))
27523
+ };
27524
+ /** Session import follows the selected CLI's protocol, like every other operation. */
27525
+ async #discover(read) {
27526
+ if (this.#closed)
27527
+ return { ok: false, error: failure("OpenCode Adapter is closed", "invalidState") };
27528
+ let adapter;
27529
+ try {
27530
+ adapter = await this.#select();
27531
+ if (!(adapter instanceof V2Adapter))
27532
+ return {
27533
+ ok: false,
27534
+ // v1 answers per project only; there is no native listing across projects to import from.
27535
+ error: failure("OpenCode Session import requires OpenCode v2", "unsupported")
27536
+ };
27537
+ return await read(adapter.sessionImport);
27538
+ } catch (error51) {
27539
+ return {
27540
+ ok: false,
27541
+ error: this.#closed ? failure("OpenCode Adapter is closed", "invalidState") : normalize(error51)
27542
+ };
27543
+ } finally {
27544
+ if (adapter) {
27545
+ await adapter.close();
27546
+ this.#adapters.delete(adapter);
27547
+ }
27548
+ }
27549
+ }
27246
27550
  async inspect(input = {}) {
27247
27551
  let adapter;
27248
27552
  try {
@@ -27299,7 +27603,7 @@ function normalize(error51) {
27299
27603
  // dist/installation.js
27300
27604
  import { realpath as realpath2 } from "node:fs/promises";
27301
27605
  import { homedir as homedir3 } from "node:os";
27302
- import path11 from "node:path";
27606
+ import path12 from "node:path";
27303
27607
  function createOpenCodeInstallation(environment, command) {
27304
27608
  let update;
27305
27609
  return createInstallationManager({
@@ -27320,8 +27624,8 @@ function createOpenCodeInstallation(environment, command) {
27320
27624
  const release = JSON.parse(await fetchInstallationText("https://api.github.com/repos/anomalyco/opencode/releases/latest"));
27321
27625
  latestVersion = installationVersion(release.tag_name);
27322
27626
  const home = environment.HOME ?? environment.USERPROFILE ?? homedir3();
27323
- const standard = path11.join(home, ".opencode", "bin", process.platform === "win32" ? "opencode.exe" : "opencode");
27324
- canUpdate = process.platform !== "win32" && path11.resolve(executable) === standard && await realpath2(executable) === standard;
27627
+ const standard = path12.join(home, ".opencode", "bin", process.platform === "win32" ? "opencode.exe" : "opencode");
27628
+ canUpdate = process.platform !== "win32" && path12.resolve(executable) === standard && await realpath2(executable) === standard;
27325
27629
  update = async (version2) => {
27326
27630
  await runInstallationCommand(executable, ["upgrade", version2, "--method", "curl"], environment, 3e5);
27327
27631
  };
@@ -27331,7 +27635,10 @@ function createOpenCodeInstallation(environment, command) {
27331
27635
  latestVersion,
27332
27636
  updateAvailable: newerInstallationVersion(currentVersion, latestVersion),
27333
27637
  canUpdate,
27334
- ...!canUpdate ? { message: "Use the original package manager to update this OpenCode installation." } : {}
27638
+ ...!canUpdate ? {
27639
+ messageCode: "original-installer",
27640
+ message: "Use the original package manager to update this OpenCode installation."
27641
+ } : {}
27335
27642
  };
27336
27643
  },
27337
27644
  async update(state) {
@@ -27347,7 +27654,10 @@ function createHarnessAdapter(context) {
27347
27654
  return Object.assign(new OpenCodeAdapter2({
27348
27655
  ...environment[OPENCODE_COMMAND_ENV] ? { command: environment[OPENCODE_COMMAND_ENV] } : {},
27349
27656
  environment
27350
- }), { installation: createOpenCodeInstallation(environment, environment[OPENCODE_COMMAND_ENV]) });
27657
+ }), {
27658
+ installation: createOpenCodeInstallation(environment, environment[OPENCODE_COMMAND_ENV]),
27659
+ install: createHarnessInstaller(environment, { npm: "opencode-ai" })
27660
+ });
27351
27661
  }
27352
27662
  export {
27353
27663
  OPENCODE_COMMAND_ENV,