@codexhost/cli-darwin-x64 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
  }
@@ -14610,6 +15092,7 @@ var CONSOLE_HOST_METHODS = Object.freeze([
14610
15092
  "codexhost/harness/display-settings/get",
14611
15093
  "codexhost/harness/display-settings/set",
14612
15094
  "codexhost/harness/inspect",
15095
+ "codexhost/harness/installation",
14613
15096
  "codexhost/harness/launch-settings/get",
14614
15097
  "codexhost/harness/launch-settings/set",
14615
15098
  "codexhost/harness/web-ui/open",
@@ -15256,14 +15739,17 @@ var harnessLaunchSettingsSchema = external_exports.object({
15256
15739
  // ../../shared-contracts/dist/harness-installation.js
15257
15740
  var harnessInstallationParamsSchema = external_exports.object({
15258
15741
  harnessId: harnessIdSchema,
15259
- action: external_exports.enum(["check", "update"])
15742
+ action: external_exports.enum(["check", "update", "install"])
15260
15743
  }).strict();
15261
15744
  var harnessInstallationStateSchema = external_exports.object({
15262
15745
  currentVersion: external_exports.string().min(1).max(128),
15263
15746
  latestVersion: external_exports.string().min(1).max(128),
15264
15747
  updateAvailable: external_exports.boolean(),
15265
15748
  canUpdate: external_exports.boolean(),
15266
- message: external_exports.string().max(2048).optional()
15749
+ // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15750
+ message: external_exports.string().max(2048).optional(),
15751
+ messageCode: external_exports.string().min(1).max(128).optional(),
15752
+ latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15267
15753
  }).strict();
15268
15754
 
15269
15755
  // ../../shared-contracts/dist/codex-accounts.js
@@ -15565,6 +16051,38 @@ var updateStatusResultSchema = external_exports.strictObject({
15565
16051
  status: updateStatusSchema.nullable()
15566
16052
  });
15567
16053
 
16054
+ // ../../shared-contracts/dist/remote-runtime.js
16055
+ var remoteUpdatePhaseSchema = external_exports.enum([
16056
+ "idle",
16057
+ "installing",
16058
+ "restarting",
16059
+ "succeeded",
16060
+ "failed"
16061
+ ]);
16062
+ var runtimeStatusSchema = external_exports.object({
16063
+ runningVersion: external_exports.string().nullable(),
16064
+ installedVersion: external_exports.string().nullable(),
16065
+ restartRequired: external_exports.boolean(),
16066
+ remote: external_exports.boolean(),
16067
+ updateSupported: external_exports.boolean(),
16068
+ update: external_exports.object({
16069
+ phase: remoteUpdatePhaseSchema,
16070
+ targetVersion: external_exports.string().nullable(),
16071
+ error: external_exports.string().nullable()
16072
+ })
16073
+ });
16074
+ var remoteUpdateParamsSchema = external_exports.object({
16075
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
16076
+ }).strict();
16077
+ var remoteSshSetupParamsSchema = external_exports.object({
16078
+ hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
16079
+ port: external_exports.number().int().min(1).max(65535).nullable(),
16080
+ identity: external_exports.string().max(4096).nullable(),
16081
+ action: external_exports.enum(["inspect", "install", "update", "repair"]),
16082
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
16083
+ }).strict();
16084
+ var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
16085
+
15568
16086
  // ../../shared-contracts/dist/index.js
15569
16087
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15570
16088
 
@@ -15714,20 +16232,20 @@ function parseHostUsage(value) {
15714
16232
  }
15715
16233
  }
15716
16234
  for (const field of ["totalCredits", "contextUsagePercent"]) {
15717
- const candidate = value[field];
15718
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
16235
+ const candidate2 = value[field];
16236
+ if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isFinite(candidate2) || candidate2 < 0)) {
15719
16237
  throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
15720
16238
  }
15721
16239
  }
15722
16240
  for (const field of tokenFields) {
15723
- const candidate = value[field];
15724
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16241
+ const candidate2 = value[field];
16242
+ if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isSafeInteger(candidate2) || candidate2 < 0)) {
15725
16243
  throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
15726
16244
  }
15727
16245
  }
15728
16246
  for (const field of safeIntegerFields) {
15729
- const candidate = value[field];
15730
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16247
+ const candidate2 = value[field];
16248
+ if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isSafeInteger(candidate2) || candidate2 < 0)) {
15731
16249
  throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
15732
16250
  }
15733
16251
  }
@@ -15738,8 +16256,8 @@ function parseHostUsage(value) {
15738
16256
  throw new Error("Harness Usage 'totalCostUsd' must be a finite non-negative number");
15739
16257
  }
15740
16258
  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)) {
16259
+ const candidate2 = value[field];
16260
+ if (candidate2 !== void 0 && (typeof candidate2 !== "number" || !Number.isFinite(candidate2) || candidate2 < 0 || candidate2 > 100)) {
15743
16261
  throw new Error(`Harness Usage '${field}' must be between 0 and 100`);
15744
16262
  }
15745
16263
  }
@@ -15852,7 +16370,7 @@ function normalizeOpenCodeModelCatalog(catalog) {
15852
16370
  ...Object.keys(model.variants ?? {}).sort(compareText).map(encodeOpenCodeVariant)
15853
16371
  ]
15854
16372
  })).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);
16373
+ const defaultNative = catalog.connected.map((providerID) => ({ providerID, modelID: catalog.default[providerID] })).find((candidate2) => typeof candidate2.modelID === "string" && candidate2.modelID.length > 0);
15856
16374
  const defaultModel = defaultNative ? encodeOpenCodeModelRef(defaultNative) : void 0;
15857
16375
  return harnessModelCatalogSchema.parse({
15858
16376
  models,
@@ -16185,7 +16703,7 @@ import { randomBytes } from "node:crypto";
16185
16703
  import { spawn, spawnSync } from "node:child_process";
16186
16704
  import fs2 from "node:fs";
16187
16705
  import { createServer } from "node:net";
16188
- import { homedir as homedir2, tmpdir } from "node:os";
16706
+ import { homedir as homedir2, tmpdir as tmpdir2 } from "node:os";
16189
16707
  import path6 from "node:path";
16190
16708
 
16191
16709
  // ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js
@@ -16412,7 +16930,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
16412
16930
 
16413
16931
  // ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/utils.gen.js
16414
16932
  var PATH_PARAM_RE = /\{[^{}]+\}/g;
16415
- var defaultPathSerializer = ({ path: path12, url: _url2 }) => {
16933
+ var defaultPathSerializer = ({ path: path13, url: _url2 }) => {
16416
16934
  let url2 = _url2;
16417
16935
  const matches = _url2.match(PATH_PARAM_RE);
16418
16936
  if (matches) {
@@ -16431,7 +16949,7 @@ var defaultPathSerializer = ({ path: path12, url: _url2 }) => {
16431
16949
  name = name.substring(1);
16432
16950
  style = "matrix";
16433
16951
  }
16434
- const value = path12[name];
16952
+ const value = path13[name];
16435
16953
  if (value === void 0 || value === null) {
16436
16954
  continue;
16437
16955
  }
@@ -16462,11 +16980,11 @@ var defaultPathSerializer = ({ path: path12, url: _url2 }) => {
16462
16980
  }
16463
16981
  return url2;
16464
16982
  };
16465
- var getUrl = ({ baseUrl, path: path12, query, querySerializer, url: _url2 }) => {
16983
+ var getUrl = ({ baseUrl, path: path13, query, querySerializer, url: _url2 }) => {
16466
16984
  const pathUrl = _url2.startsWith("/") ? _url2 : `/${_url2}`;
16467
16985
  let url2 = (baseUrl ?? "") + pathUrl;
16468
- if (path12) {
16469
- url2 = defaultPathSerializer({ path: path12, url: url2 });
16986
+ if (path13) {
16987
+ url2 = defaultPathSerializer({ path: path13, url: url2 });
16470
16988
  }
16471
16989
  let search = query ? querySerializer(query) : "";
16472
16990
  if (search.startsWith("?")) {
@@ -21360,666 +21878,236 @@ var V2 = class extends HeyApiClient {
21360
21878
  get question() {
21361
21879
  return this._question ??= new Question3({ client: this.client });
21362
21880
  }
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 });
21881
+ _reference;
21882
+ get reference() {
21883
+ return this._reference ??= new Reference({ client: this.client });
21481
21884
  }
21482
- _v2;
21483
- get v2() {
21484
- return this._v2 ??= new V2({ client: this.client });
21885
+ _projectCopy;
21886
+ get projectCopy() {
21887
+ return this._projectCopy ??= new ProjectCopy2({ client: this.client });
21485
21888
  }
21486
21889
  };
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 } });
21890
+ var OpencodeClient = class _OpencodeClient extends HeyApiClient {
21891
+ static __registry = new HeyApiRegistry();
21892
+ constructor(args) {
21893
+ super(args);
21894
+ _OpencodeClient.__registry.set(this, args?.key);
21498
21895
  }
21499
- if (typeof error51 === "string" && error51.length > 0) {
21500
- return new Error(error51, { cause: { body: error51, status: response?.status } });
21896
+ _auth;
21897
+ get auth() {
21898
+ return this._auth ??= new Auth({ client: this.client });
21501
21899
  }
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;
21900
+ _app;
21901
+ get app() {
21902
+ return this._app ??= new App({ client: this.client });
21545
21903
  }
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
- };
21904
+ _experimental;
21905
+ get experimental() {
21906
+ return this._experimental ??= new Experimental({ client: this.client });
21563
21907
  }
21564
- if (config2?.directory) {
21565
- config2.headers = {
21566
- ...config2.headers,
21567
- "x-opencode-directory": encodeURIComponent(config2.directory)
21568
- };
21908
+ _global;
21909
+ get global() {
21910
+ return this._global ??= new Global({ client: this.client });
21569
21911
  }
21570
- if (config2?.experimental_workspaceID) {
21571
- config2.headers = {
21572
- ...config2.headers,
21573
- "x-opencode-workspace": config2.experimental_workspaceID
21574
- };
21912
+ _event;
21913
+ get event() {
21914
+ return this._event ??= new Event({ client: this.client });
21575
21915
  }
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;
21916
+ _config;
21917
+ get config() {
21918
+ return this._config ??= new Config2({ client: this.client });
21605
21919
  }
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;
21920
+ _tool;
21921
+ get tool() {
21922
+ return this._tool ??= new Tool({ client: this.client });
21627
21923
  }
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 [];
21924
+ _worktree;
21925
+ get worktree() {
21926
+ return this._worktree ??= new Worktree({ client: this.client });
21634
21927
  }
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 };
21928
+ _find;
21929
+ get find() {
21930
+ return this._find ??= new Find({ client: this.client });
21646
21931
  }
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);
21932
+ _file;
21933
+ get file() {
21934
+ return this._file ??= new File2({ client: this.client });
21666
21935
  }
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;
21936
+ _instance;
21937
+ get instance() {
21938
+ return this._instance ??= new Instance({ client: this.client });
21939
+ }
21940
+ _path;
21941
+ get path() {
21942
+ return this._path ??= new Path({ client: this.client });
21943
+ }
21944
+ _vcs;
21945
+ get vcs() {
21946
+ return this._vcs ??= new Vcs({ client: this.client });
21697
21947
  }
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");
21948
+ _command;
21949
+ get command() {
21950
+ return this._command ??= new Command({ client: this.client });
21706
21951
  }
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
- }
21952
+ _lsp;
21953
+ get lsp() {
21954
+ return this._lsp ??= new Lsp({ client: this.client });
21727
21955
  }
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);
21956
+ _formatter;
21957
+ get formatter() {
21958
+ return this._formatter ??= new Formatter({ client: this.client });
21786
21959
  }
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" }];
21960
+ _mcp;
21961
+ get mcp() {
21962
+ return this._mcp ??= new Mcp({ client: this.client });
21796
21963
  }
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
- }
21964
+ _project;
21965
+ get project() {
21966
+ return this._project ??= new Project({ client: this.client });
21806
21967
  }
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
- }
21968
+ _pty;
21969
+ get pty() {
21970
+ return this._pty ??= new Pty({ client: this.client });
21817
21971
  }
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 };
21972
+ _question;
21973
+ get question() {
21974
+ return this._question ??= new Question({ client: this.client });
21829
21975
  }
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);
21976
+ _permission;
21977
+ get permission() {
21978
+ return this._permission ??= new Permission({ client: this.client });
21874
21979
  }
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;
21980
+ _provider;
21981
+ get provider() {
21982
+ return this._provider ??= new Provider({ client: this.client });
21896
21983
  }
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;
21984
+ _session;
21985
+ get session() {
21986
+ return this._session ??= new Session2({ client: this.client });
21987
+ }
21988
+ _part;
21989
+ get part() {
21990
+ return this._part ??= new Part({ client: this.client });
21991
+ }
21992
+ _sync;
21993
+ get sync() {
21994
+ return this._sync ??= new Sync({ client: this.client });
21995
+ }
21996
+ _tui;
21997
+ get tui() {
21998
+ return this._tui ??= new Tui({ client: this.client });
21999
+ }
22000
+ _v2;
22001
+ get v2() {
22002
+ return this._v2 ??= new V2({ client: this.client });
22003
+ }
22004
+ };
22005
+
22006
+ // ../../../node_modules/@opencode-ai/sdk/dist/error-interceptor.js
22007
+ function wrapClientError(error51, response, request, opts) {
22008
+ if (!opts?.throwOnError)
22009
+ return error51;
22010
+ if (error51 instanceof Error)
22011
+ return error51;
22012
+ if (typeof error51 === "object" && error51 !== null && Object.keys(error51).length > 0) {
22013
+ const obj = error51;
22014
+ 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);
22015
+ return new Error(message, { cause: { body: error51, status: response?.status } });
22016
+ }
22017
+ if (typeof error51 === "string" && error51.length > 0) {
22018
+ return new Error(error51, { cause: { body: error51, status: response?.status } });
22019
+ }
22020
+ const reason = response ? "(empty response body)" : "network error (no response)";
22021
+ return new Error(`opencode server ${describe3(request, response)}: ${reason}`, {
22022
+ cause: { body: error51, status: response?.status }
21904
22023
  });
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
22024
  }
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
- }
22025
+ function describe3(request, response) {
22026
+ const method = request?.method ?? "?";
22027
+ const url2 = request?.url ?? "?";
22028
+ const status = response?.status;
22029
+ const statusText = response?.statusText;
22030
+ return `${method} ${url2}${status ? " → " + status : ""}${statusText ? " " + statusText : ""}`;
21941
22031
  }
21942
22032
 
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}"`);
22033
+ // ../../../node_modules/@opencode-ai/sdk/dist/v2/client.js
22034
+ function pick2(value, fallback, encode3) {
22035
+ if (!value)
22036
+ return;
22037
+ if (!fallback)
22038
+ return value;
22039
+ if (value === fallback)
22040
+ return fallback;
22041
+ if (encode3 && value === encode3(fallback))
22042
+ return fallback;
22043
+ return value;
21952
22044
  }
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;
22045
+ function rewrite(request, values) {
22046
+ if (request.method !== "GET" && request.method !== "HEAD")
22047
+ return request;
22048
+ const url2 = new URL(request.url);
22049
+ let changed = false;
22050
+ for (const [name, key] of [
22051
+ ["x-opencode-directory", "directory"],
22052
+ ["x-opencode-workspace", "workspace"]
22053
+ ]) {
22054
+ const value = pick2(request.headers.get(name), key === "directory" ? values.directory : values.workspace, key === "directory" ? encodeURIComponent : void 0);
22055
+ if (!value)
22056
+ continue;
22057
+ for (const query of url2.pathname.startsWith("/api/") ? [key, `location[${key}]`] : [key]) {
22058
+ if (!url2.searchParams.has(query)) {
22059
+ url2.searchParams.set(query, value);
21966
22060
  }
21967
22061
  }
22062
+ changed = true;
21968
22063
  }
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;
22064
+ if (!changed)
22065
+ return request;
22066
+ const next = new Request(url2, request);
22067
+ next.headers.delete("x-opencode-directory");
22068
+ next.headers.delete("x-opencode-workspace");
22069
+ return next;
22070
+ }
22071
+ function createOpencodeClient(config2) {
22072
+ if (!config2?.fetch) {
22073
+ const customFetch = (req) => {
22074
+ req.timeout = false;
22075
+ return fetch(req);
22076
+ };
22077
+ config2 = {
22078
+ ...config2,
22079
+ fetch: customFetch
22080
+ };
22018
22081
  }
22019
- return null;
22082
+ if (config2?.directory) {
22083
+ config2.headers = {
22084
+ ...config2.headers,
22085
+ "x-opencode-directory": encodeURIComponent(config2.directory)
22086
+ };
22087
+ }
22088
+ if (config2?.experimental_workspaceID) {
22089
+ config2.headers = {
22090
+ ...config2.headers,
22091
+ "x-opencode-workspace": config2.experimental_workspaceID
22092
+ };
22093
+ }
22094
+ const client2 = createClient(config2);
22095
+ client2.interceptors.request.use((request) => rewrite(request, {
22096
+ directory: config2?.directory,
22097
+ workspace: config2?.experimental_workspaceID
22098
+ }));
22099
+ client2.interceptors.response.use((response) => {
22100
+ const contentType = response.headers.get("content-type");
22101
+ if (contentType === "text/html")
22102
+ throw new Error("Request is not supported by this version of OpenCode Server (Server responded with text/html)");
22103
+ return response;
22104
+ });
22105
+ client2.interceptors.error.use(wrapClientError);
22106
+ return new OpencodeClient({ client: client2 });
22020
22107
  }
22021
22108
 
22022
22109
  // dist/command.js
22110
+ import path5 from "node:path";
22023
22111
  var OpenCodeExecutableError = class extends Error {
22024
22112
  code = "OPENCODE_NOT_FOUND";
22025
22113
  constructor(message = "OpenCode CLI is not installed") {
@@ -22148,15 +22236,15 @@ function signalProcessTree(child, signal) {
22148
22236
  }
22149
22237
  }
22150
22238
  function safeOpenCodeServerCwd(environment) {
22151
- const candidates = [environment.USERPROFILE, environment.HOME, homedir2(), tmpdir()];
22152
- for (const candidate of candidates) {
22153
- if (!candidate || !path6.isAbsolute(candidate))
22239
+ const candidates = [environment.USERPROFILE, environment.HOME, homedir2(), tmpdir2()];
22240
+ for (const candidate2 of candidates) {
22241
+ if (!candidate2 || !path6.isAbsolute(candidate2))
22154
22242
  continue;
22155
22243
  try {
22156
- if (!fs2.statSync(candidate).isDirectory())
22244
+ if (!fs2.statSync(candidate2).isDirectory())
22157
22245
  continue;
22158
- fs2.accessSync(candidate, fs2.constants.R_OK | fs2.constants.W_OK);
22159
- return candidate;
22246
+ fs2.accessSync(candidate2, fs2.constants.R_OK | fs2.constants.W_OK);
22247
+ return candidate2;
22160
22248
  } catch {
22161
22249
  }
22162
22250
  }
@@ -22611,19 +22699,19 @@ function hasDotPathSegment(value) {
22611
22699
  return segments.some((segment) => segment === "." || segment === "..");
22612
22700
  }
22613
22701
  function canonicalDirectoryPath(value) {
22614
- let candidate = path7.resolve(value);
22702
+ let candidate2 = path7.resolve(value);
22615
22703
  const missingSegments = [];
22616
22704
  for (; ; ) {
22617
22705
  try {
22618
- return path7.join(fs3.realpathSync.native(candidate), ...missingSegments);
22706
+ return path7.join(fs3.realpathSync.native(candidate2), ...missingSegments);
22619
22707
  } catch (error51) {
22620
22708
  if (!missingPath(error51))
22621
22709
  return void 0;
22622
- const parent = path7.dirname(candidate);
22623
- if (parent === candidate)
22710
+ const parent = path7.dirname(candidate2);
22711
+ if (parent === candidate2)
22624
22712
  return void 0;
22625
- missingSegments.unshift(path7.basename(candidate));
22626
- candidate = parent;
22713
+ missingSegments.unshift(path7.basename(candidate2));
22714
+ candidate2 = parent;
22627
22715
  }
22628
22716
  }
22629
22717
  }
@@ -22632,8 +22720,8 @@ function canonicalFilePath(value) {
22632
22720
  const parent = canonicalDirectoryPath(path7.dirname(absolute));
22633
22721
  return parent ? path7.join(parent, path7.basename(absolute)) : void 0;
22634
22722
  }
22635
- function pathIsWithin(root, candidate, allowRoot) {
22636
- const relative = path7.relative(root, candidate);
22723
+ function pathIsWithin(root, candidate2, allowRoot) {
22724
+ const relative = path7.relative(root, candidate2);
22637
22725
  return allowRoot && relative === "" || relative !== "" && relative !== ".." && !relative.startsWith(`..${path7.sep}`) && !path7.isAbsolute(relative);
22638
22726
  }
22639
22727
  function verifiedOpenCodeWorktree(sessionDirectory, paths) {
@@ -22652,8 +22740,8 @@ function openCodeFileIdentity(file2, worktree) {
22652
22740
  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
22741
  return void 0;
22654
22742
  }
22655
- const candidate = canonicalFilePath(path7.isAbsolute(file2) ? file2 : path7.resolve(worktree, file2));
22656
- return candidate && pathIsWithin(worktree, candidate, false) ? candidate : void 0;
22743
+ const candidate2 = canonicalFilePath(path7.isAbsolute(file2) ? file2 : path7.resolve(worktree, file2));
22744
+ return candidate2 && pathIsWithin(worktree, candidate2, false) ? candidate2 : void 0;
22657
22745
  }
22658
22746
 
22659
22747
  // dist/usage.js
@@ -22882,20 +22970,20 @@ async function deriveOpenCodeHistory(options) {
22882
22970
  retainedCount = boundary.sourceTurnCount - 1;
22883
22971
  }
22884
22972
  const expectedHistory = structuredClone(semanticHistory(before.snapshot).slice(0, retainedCount));
22885
- let candidate = await transport.forkSession(source.id, messageID);
22886
- if (candidate.id === source.id) {
22973
+ let candidate2 = await transport.forkSession(source.id, messageID);
22974
+ if (candidate2.id === source.id) {
22887
22975
  throw new OpenCodeTransportError("protocolError", "OpenCode Fork did not create a distinct Native Session");
22888
22976
  }
22889
- const candidateID = candidate.id;
22890
- options.onCreated(candidate);
22891
- if (candidate.directory !== expectedSource.directory) {
22977
+ const candidateID = candidate2.id;
22978
+ options.onCreated(candidate2);
22979
+ if (candidate2.directory !== expectedSource.directory) {
22892
22980
  throw new OpenCodeTransportError("protocolError", "OpenCode Fork changed working directory");
22893
22981
  }
22894
22982
  if (expectedSource.model) {
22895
- candidate = await transport.updateSessionMetadata(candidateID, selectionMetadata(candidate, expectedSource.model, expectedSource.variant));
22983
+ candidate2 = await transport.updateSessionMetadata(candidateID, selectionMetadata(candidate2, expectedSource.model, expectedSource.variant));
22896
22984
  }
22897
- if (!isDeepStrictEqual(candidate.permission ?? [], expectedSource.permission ?? [])) {
22898
- candidate = await transport.updateSessionPermission(candidateID, expectedSource.permission ?? []);
22985
+ if (!isDeepStrictEqual(candidate2.permission ?? [], expectedSource.permission ?? [])) {
22986
+ candidate2 = await transport.updateSessionPermission(candidateID, expectedSource.permission ?? []);
22899
22987
  }
22900
22988
  const [derived, after, candidateStatus, sourceStatus] = await Promise.all([
22901
22989
  read(candidateID),
@@ -22903,7 +22991,7 @@ async function deriveOpenCodeHistory(options) {
22903
22991
  transport.getStatus(candidateID),
22904
22992
  transport.getStatus(source.id)
22905
22993
  ]);
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 ?? [])) {
22994
+ 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
22995
  throw new OpenCodeTransportError("protocolError", "OpenCode derived history, source or configuration changed during Fork");
22908
22996
  }
22909
22997
  return derived.session;
@@ -24035,9 +24123,9 @@ var OpenCodeHarnessSession = class {
24035
24123
  if (active.userMessageID)
24036
24124
  return;
24037
24125
  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);
24126
+ const [candidate2] = candidates;
24127
+ if (candidates.length === 1 && candidate2) {
24128
+ this.#bindUserMessage(active, candidate2.info.id);
24041
24129
  return;
24042
24130
  }
24043
24131
  const parents = new Set(messages.filter(({ info }) => info.role === "assistant").map(({ info }) => info.parentID));
@@ -24255,8 +24343,8 @@ var OpenCodeAdapter = class {
24255
24343
  input,
24256
24344
  providers,
24257
24345
  toolOutputLimit: this.#toolOutputLimit,
24258
- onCreated: (candidate) => {
24259
- createdForCleanup = candidate;
24346
+ onCreated: (candidate2) => {
24347
+ createdForCleanup = candidate2;
24260
24348
  }
24261
24349
  });
24262
24350
  }
@@ -24323,7 +24411,7 @@ async function detectOpenCode(options) {
24323
24411
  }
24324
24412
 
24325
24413
  // dist/v2/adapter.js
24326
- import fs6 from "node:fs";
24414
+ import fs7 from "node:fs";
24327
24415
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
24328
24416
 
24329
24417
  // dist/v2/state.js
@@ -24398,7 +24486,7 @@ function v2Permissions(current = [], mode) {
24398
24486
  }
24399
24487
  function v2State(session, catalog, policy) {
24400
24488
  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);
24489
+ const entry = catalog.models.find((candidate2) => candidate2.ref.id === model?.id);
24402
24490
  const mode = session.permissions?.findLast((rule) => rule.action === "*" && rule.resource === "*");
24403
24491
  return {
24404
24492
  nativeRef: v2Ref(session, policy),
@@ -26431,6 +26519,110 @@ function terminalItemOutcome(outcome) {
26431
26519
  return outcome.status === "unknown" ? { status: "failed", error: failure(outcome.reason, "protocolError") } : outcome;
26432
26520
  }
26433
26521
 
26522
+ // dist/v2/session-import.js
26523
+ import fs6 from "node:fs";
26524
+ import path11 from "node:path";
26525
+
26526
+ // ../../harness-adapter/dist/session-import.js
26527
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
26528
+ if (typeof value !== "string")
26529
+ return null;
26530
+ const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
26531
+ if (!normalized)
26532
+ return null;
26533
+ if (normalized.length <= maxLength)
26534
+ return normalized;
26535
+ const characters = [...normalized];
26536
+ if (characters.length <= maxLength)
26537
+ return normalized;
26538
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
26539
+ }
26540
+ function sessionImportCandidate(input) {
26541
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
26542
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
26543
+ nativeSessionId: input.nativeSessionId,
26544
+ cwd: input.cwd,
26545
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
26546
+ updatedAt: Math.floor(time3),
26547
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
26548
+ running: typeof input.running === "boolean" ? input.running : null
26549
+ });
26550
+ return parsed.success ? parsed.data : null;
26551
+ }
26552
+
26553
+ // dist/v2/session-import.js
26554
+ var PAGE_SIZE = 200;
26555
+ var MAX_PAGES = 1e4;
26556
+ function existingDirectory(directory) {
26557
+ if (typeof directory !== "string" || !path11.isAbsolute(directory))
26558
+ return null;
26559
+ try {
26560
+ return fs6.statSync(directory).isDirectory() ? directory : null;
26561
+ } catch {
26562
+ return null;
26563
+ }
26564
+ }
26565
+ function candidate(info, active) {
26566
+ if (info.parentID || info.time.archived !== void 0)
26567
+ return null;
26568
+ const cwd = existingDirectory(info.location.directory);
26569
+ if (!cwd)
26570
+ return null;
26571
+ return sessionImportCandidate({
26572
+ nativeSessionId: info.id,
26573
+ cwd,
26574
+ title: sessionImportTitle(info.title),
26575
+ updatedAt: info.time.updated,
26576
+ // This server only knows its own executions; another process may still hold the Session.
26577
+ running: active[info.id] ? true : null
26578
+ });
26579
+ }
26580
+ async function listV2SessionCandidates(client2) {
26581
+ const active = await client2.session.active();
26582
+ const candidates = /* @__PURE__ */ new Map();
26583
+ const cursors = /* @__PURE__ */ new Set();
26584
+ let cursor;
26585
+ for (let page = 0; page < MAX_PAGES; page += 1) {
26586
+ const response = await client2.session.list({
26587
+ limit: PAGE_SIZE,
26588
+ ...cursor ? { cursor } : {}
26589
+ });
26590
+ for (const info of response.data) {
26591
+ const entry = candidate(info, active);
26592
+ if (entry)
26593
+ candidates.set(entry.nativeSessionId, entry);
26594
+ }
26595
+ const next = response.cursor.next;
26596
+ if (!next || cursors.has(next))
26597
+ break;
26598
+ cursors.add(next);
26599
+ cursor = next;
26600
+ }
26601
+ return [...candidates.values()];
26602
+ }
26603
+ async function resolveV2SessionCandidate(client2, nativeSessionId) {
26604
+ const active = await client2.session.active();
26605
+ const cursors = /* @__PURE__ */ new Set();
26606
+ let cursor;
26607
+ for (let page = 0; page < MAX_PAGES; page += 1) {
26608
+ const response = await client2.session.list({
26609
+ limit: PAGE_SIZE,
26610
+ ...cursor ? { cursor } : {}
26611
+ });
26612
+ const info = response.data.find((entry) => entry.id === nativeSessionId);
26613
+ if (info) {
26614
+ const entry = candidate(info, active);
26615
+ return entry ? { candidate: entry, nativeRef: v2Ref(info, "default") } : null;
26616
+ }
26617
+ const next = response.cursor.next;
26618
+ if (!next || cursors.has(next))
26619
+ break;
26620
+ cursors.add(next);
26621
+ cursor = next;
26622
+ }
26623
+ return null;
26624
+ }
26625
+
26434
26626
  // dist/v2/interactions.js
26435
26627
  function permissionInteraction(request, turnId) {
26436
26628
  return {
@@ -27061,9 +27253,42 @@ var V2Adapter = class {
27061
27253
  this.#connections.delete(connection);
27062
27254
  }
27063
27255
  }
27256
+ sessionImport = {
27257
+ listCandidates: () => this.#discover((client2) => listV2SessionCandidates(client2)),
27258
+ resolveCandidate: async (nativeSessionId) => {
27259
+ const source = await this.#discover((client2) => resolveV2SessionCandidate(client2, nativeSessionId));
27260
+ if (!source.ok)
27261
+ return source;
27262
+ return source.value ? { ok: true, value: source.value } : {
27263
+ ok: false,
27264
+ error: failure("OpenCode Session is no longer importable", "sessionNotFound")
27265
+ };
27266
+ }
27267
+ };
27268
+ /** Read-only discovery on a private server: no Session is created, loaded or prompted. */
27269
+ async #discover(read) {
27270
+ if (this.#closed)
27271
+ return { ok: false, error: failure("OpenCode Adapter is closed", "invalidState") };
27272
+ const connection = new V2Connection(this.options, process.cwd());
27273
+ this.#connections.add(connection);
27274
+ try {
27275
+ const value = await read(await connection.client());
27276
+ if (this.#closed)
27277
+ throw new Error("OpenCode Adapter closed during Session discovery");
27278
+ return { ok: true, value };
27279
+ } catch {
27280
+ return {
27281
+ ok: false,
27282
+ error: this.#closed ? failure("OpenCode Adapter is closed", "invalidState") : failure("OpenCode sessions could not be read; check the installation and retry", "unavailable")
27283
+ };
27284
+ } finally {
27285
+ await connection.close();
27286
+ this.#connections.delete(connection);
27287
+ }
27288
+ }
27064
27289
  async open(input) {
27065
27290
  try {
27066
- input = { ...input, cwd: fs6.realpathSync(input.cwd) };
27291
+ input = { ...input, cwd: fs7.realpathSync(input.cwd) };
27067
27292
  } catch (error51) {
27068
27293
  return errorResult(error51);
27069
27294
  }
@@ -27243,6 +27468,36 @@ var OpenCodeAdapter2 = class {
27243
27468
  this.#adapters.add(adapter);
27244
27469
  return adapter;
27245
27470
  }
27471
+ sessionImport = {
27472
+ listCandidates: () => this.#discover((imports) => imports.listCandidates()),
27473
+ resolveCandidate: (nativeSessionId) => this.#discover((imports) => imports.resolveCandidate(nativeSessionId))
27474
+ };
27475
+ /** Session import follows the selected CLI's protocol, like every other operation. */
27476
+ async #discover(read) {
27477
+ if (this.#closed)
27478
+ return { ok: false, error: failure("OpenCode Adapter is closed", "invalidState") };
27479
+ let adapter;
27480
+ try {
27481
+ adapter = await this.#select();
27482
+ if (!(adapter instanceof V2Adapter))
27483
+ return {
27484
+ ok: false,
27485
+ // v1 answers per project only; there is no native listing across projects to import from.
27486
+ error: failure("OpenCode Session import requires OpenCode v2", "unsupported")
27487
+ };
27488
+ return await read(adapter.sessionImport);
27489
+ } catch (error51) {
27490
+ return {
27491
+ ok: false,
27492
+ error: this.#closed ? failure("OpenCode Adapter is closed", "invalidState") : normalize(error51)
27493
+ };
27494
+ } finally {
27495
+ if (adapter) {
27496
+ await adapter.close();
27497
+ this.#adapters.delete(adapter);
27498
+ }
27499
+ }
27500
+ }
27246
27501
  async inspect(input = {}) {
27247
27502
  let adapter;
27248
27503
  try {
@@ -27299,7 +27554,7 @@ function normalize(error51) {
27299
27554
  // dist/installation.js
27300
27555
  import { realpath as realpath2 } from "node:fs/promises";
27301
27556
  import { homedir as homedir3 } from "node:os";
27302
- import path11 from "node:path";
27557
+ import path12 from "node:path";
27303
27558
  function createOpenCodeInstallation(environment, command) {
27304
27559
  let update;
27305
27560
  return createInstallationManager({
@@ -27320,8 +27575,8 @@ function createOpenCodeInstallation(environment, command) {
27320
27575
  const release = JSON.parse(await fetchInstallationText("https://api.github.com/repos/anomalyco/opencode/releases/latest"));
27321
27576
  latestVersion = installationVersion(release.tag_name);
27322
27577
  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;
27578
+ const standard = path12.join(home, ".opencode", "bin", process.platform === "win32" ? "opencode.exe" : "opencode");
27579
+ canUpdate = process.platform !== "win32" && path12.resolve(executable) === standard && await realpath2(executable) === standard;
27325
27580
  update = async (version2) => {
27326
27581
  await runInstallationCommand(executable, ["upgrade", version2, "--method", "curl"], environment, 3e5);
27327
27582
  };
@@ -27331,7 +27586,10 @@ function createOpenCodeInstallation(environment, command) {
27331
27586
  latestVersion,
27332
27587
  updateAvailable: newerInstallationVersion(currentVersion, latestVersion),
27333
27588
  canUpdate,
27334
- ...!canUpdate ? { message: "Use the original package manager to update this OpenCode installation." } : {}
27589
+ ...!canUpdate ? {
27590
+ messageCode: "original-installer",
27591
+ message: "Use the original package manager to update this OpenCode installation."
27592
+ } : {}
27335
27593
  };
27336
27594
  },
27337
27595
  async update(state) {
@@ -27347,7 +27605,10 @@ function createHarnessAdapter(context) {
27347
27605
  return Object.assign(new OpenCodeAdapter2({
27348
27606
  ...environment[OPENCODE_COMMAND_ENV] ? { command: environment[OPENCODE_COMMAND_ENV] } : {},
27349
27607
  environment
27350
- }), { installation: createOpenCodeInstallation(environment, environment[OPENCODE_COMMAND_ENV]) });
27608
+ }), {
27609
+ installation: createOpenCodeInstallation(environment, environment[OPENCODE_COMMAND_ENV]),
27610
+ install: createHarnessInstaller(environment, { npm: "opencode-ai" })
27611
+ });
27351
27612
  }
27352
27613
  export {
27353
27614
  OPENCODE_COMMAND_ENV,