@codexhost/cli-darwin-x64 0.11.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,9 +5,491 @@ 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 ?? ((candidate) => isExecutableFile(candidate, platform));
237
+ const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
238
+ const context = { platform, isExecutable };
239
+ for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
240
+ const executable = runnable(candidate, 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/kimi-adapter.js
9
- import { readFile as readFile5 } from "node:fs/promises";
10
- import path8 from "node:path";
491
+ import { readFile as readFile6 } from "node:fs/promises";
492
+ import path9 from "node:path";
11
493
  import { isDeepStrictEqual } from "node:util";
12
494
 
13
495
  // ../../../node_modules/zod/v4/classic/external.js
@@ -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, path9) {
780
- if (!path9)
1261
+ function getElementAtPath(obj, path10) {
1262
+ if (!path10)
781
1263
  return obj;
782
- return path9.reduce((acc, key) => acc?.[key], obj);
1264
+ return path10.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(path9, issues) {
1673
+ function prefixIssues(path10, issues) {
1192
1674
  return issues.map((iss) => {
1193
1675
  var _a3;
1194
1676
  (_a3 = iss).path ?? (_a3.path = []);
1195
- iss.path.unshift(path9);
1677
+ iss.path.unshift(path10);
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, path9 = []) => {
1824
+ const processError = (error52, path10 = []) => {
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 }, [...path9, ...issue2.path]));
1827
+ issue2.errors.map((issues) => processError({ issues }, [...path10, ...issue2.path]));
1346
1828
  } else if (issue2.code === "invalid_key") {
1347
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1829
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1348
1830
  } else if (issue2.code === "invalid_element") {
1349
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1831
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1350
1832
  } else {
1351
- const fullpath = [...path9, ...issue2.path];
1833
+ const fullpath = [...path10, ...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, path9 = []) => {
1860
+ const processError = (error52, path10 = []) => {
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 }, [...path9, ...issue2.path]));
1864
+ issue2.errors.map((issues) => processError({ issues }, [...path10, ...issue2.path]));
1383
1865
  } else if (issue2.code === "invalid_key") {
1384
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1866
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1385
1867
  } else if (issue2.code === "invalid_element") {
1386
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1868
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1387
1869
  } else {
1388
- const fullpath = [...path9, ...issue2.path];
1870
+ const fullpath = [...path10, ...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 path9 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1421
- for (const seg of path9) {
1902
+ const path10 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1903
+ for (const seg of path10) {
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 path9 = ref.slice(1).split("/").filter(Boolean);
14114
- if (path9.length === 0) {
14595
+ const path10 = ref.slice(1).split("/").filter(Boolean);
14596
+ if (path10.length === 0) {
14115
14597
  return ctx.rootSchema;
14116
14598
  }
14117
14599
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14118
- if (path9[0] === defsKey) {
14119
- const key = path9[1];
14600
+ if (path10[0] === defsKey) {
14601
+ const key = path10[1];
14120
14602
  if (!key || !ctx.defs[key]) {
14121
14603
  throw new Error(`Reference not found: ${ref}`);
14122
14604
  }
@@ -14594,6 +15076,20 @@ var harnessDisplaySetSchema = external_exports.strictObject({
14594
15076
  initializeOnly: external_exports.boolean().optional()
14595
15077
  });
14596
15078
 
15079
+ // ../../shared-contracts/dist/ids.js
15080
+ var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
15081
+ message: "Identifier must not be empty or whitespace"
15082
+ });
15083
+ var harnessIdSchema = opaqueIdSchema.brand();
15084
+ var hostThreadIdSchema = opaqueIdSchema.brand();
15085
+ var hostTurnIdSchema = opaqueIdSchema.brand();
15086
+ var hostItemIdSchema = opaqueIdSchema.brand();
15087
+ var hostInteractionIdSchema = opaqueIdSchema.brand();
15088
+
15089
+ // ../../shared-contracts/dist/thread-prewarm.js
15090
+ var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
15091
+ var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
15092
+
14597
15093
  // ../../shared-contracts/dist/console.js
14598
15094
  var consoleAnnouncementSchema = external_exports.strictObject({
14599
15095
  title: external_exports.string().trim().min(1).max(200),
@@ -14606,10 +15102,14 @@ var consoleOpenResultSchema = external_exports.strictObject({
14606
15102
  url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
14607
15103
  });
14608
15104
  var CONSOLE_HOST_METHODS = Object.freeze([
15105
+ "codexhost/console/remote-connections",
15106
+ "codexhost/runtime/status",
15107
+ "codexhost/remote/ssh-setup",
14609
15108
  "codexhost/harness/plugins/list",
14610
15109
  "codexhost/harness/display-settings/get",
14611
15110
  "codexhost/harness/display-settings/set",
14612
15111
  "codexhost/harness/inspect",
15112
+ "codexhost/harness/installation",
14613
15113
  "codexhost/harness/launch-settings/get",
14614
15114
  "codexhost/harness/launch-settings/set",
14615
15115
  "codexhost/harness/web-ui/open",
@@ -14671,16 +15171,6 @@ var loadedSessionsSchema = external_exports.array(external_exports.strictObject(
14671
15171
  inactiveMs: external_exports.number().nonnegative()
14672
15172
  }));
14673
15173
 
14674
- // ../../shared-contracts/dist/ids.js
14675
- var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
14676
- message: "Identifier must not be empty or whitespace"
14677
- });
14678
- var harnessIdSchema = opaqueIdSchema.brand();
14679
- var hostThreadIdSchema = opaqueIdSchema.brand();
14680
- var hostTurnIdSchema = opaqueIdSchema.brand();
14681
- var hostItemIdSchema = opaqueIdSchema.brand();
14682
- var hostInteractionIdSchema = opaqueIdSchema.brand();
14683
-
14684
15174
  // ../../shared-contracts/dist/manual-compaction.js
14685
15175
  var threadManualCompactionStartedSchema = external_exports.strictObject({
14686
15176
  threadId: hostThreadIdSchema,
@@ -15256,14 +15746,17 @@ var harnessLaunchSettingsSchema = external_exports.object({
15256
15746
  // ../../shared-contracts/dist/harness-installation.js
15257
15747
  var harnessInstallationParamsSchema = external_exports.object({
15258
15748
  harnessId: harnessIdSchema,
15259
- action: external_exports.enum(["check", "update"])
15749
+ action: external_exports.enum(["check", "update", "install"])
15260
15750
  }).strict();
15261
15751
  var harnessInstallationStateSchema = external_exports.object({
15262
15752
  currentVersion: external_exports.string().min(1).max(128),
15263
15753
  latestVersion: external_exports.string().min(1).max(128),
15264
15754
  updateAvailable: external_exports.boolean(),
15265
15755
  canUpdate: external_exports.boolean(),
15266
- message: external_exports.string().max(2048).optional()
15756
+ // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15757
+ message: external_exports.string().max(2048).optional(),
15758
+ messageCode: external_exports.string().min(1).max(128).optional(),
15759
+ latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15267
15760
  }).strict();
15268
15761
 
15269
15762
  // ../../shared-contracts/dist/codex-accounts.js
@@ -15565,6 +16058,80 @@ var updateStatusResultSchema = external_exports.strictObject({
15565
16058
  status: updateStatusSchema.nullable()
15566
16059
  });
15567
16060
 
16061
+ // ../../shared-contracts/dist/remote-runtime.js
16062
+ var remoteUpdatePhaseSchema = external_exports.enum([
16063
+ "idle",
16064
+ "installing",
16065
+ "restarting",
16066
+ "succeeded",
16067
+ "failed"
16068
+ ]);
16069
+ var runtimeStatusSchema = external_exports.object({
16070
+ runningVersion: external_exports.string().nullable(),
16071
+ installedVersion: external_exports.string().nullable(),
16072
+ restartRequired: external_exports.boolean(),
16073
+ remote: external_exports.boolean(),
16074
+ updateSupported: external_exports.boolean(),
16075
+ update: external_exports.object({
16076
+ phase: remoteUpdatePhaseSchema,
16077
+ targetVersion: external_exports.string().nullable(),
16078
+ error: external_exports.string().nullable()
16079
+ })
16080
+ });
16081
+ var remoteUpdateParamsSchema = external_exports.object({
16082
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
16083
+ }).strict();
16084
+ var remoteSshSetupParamsSchema = external_exports.object({
16085
+ hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
16086
+ port: external_exports.number().int().min(1).max(65535).nullable(),
16087
+ identity: external_exports.string().max(4096).nullable(),
16088
+ action: external_exports.enum(["inspect", "install", "update", "repair", "uninstall"]),
16089
+ uninstallPackage: external_exports.boolean().optional(),
16090
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
16091
+ }).strict();
16092
+ var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
16093
+
16094
+ // ../../shared-contracts/dist/remote-connections.js
16095
+ var hostId = external_exports.string().min(1).max(1024);
16096
+ var codexSshConnectionSchema = external_exports.object({
16097
+ hostId,
16098
+ displayName: external_exports.string().min(1).max(1024),
16099
+ source: external_exports.enum(["codex-managed", "discovered"]),
16100
+ sshAlias: external_exports.string().max(1024).nullable(),
16101
+ sshHost: external_exports.string().min(1).max(1024),
16102
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
16103
+ identity: external_exports.string().max(4096).nullable(),
16104
+ autoConnect: external_exports.boolean(),
16105
+ connectionAnalyticsId: external_exports.string().max(1024).optional()
16106
+ });
16107
+ var codexSshDraftSchema = external_exports.strictObject({
16108
+ displayName: external_exports.string().min(1).max(1024),
16109
+ hostname: external_exports.string().min(1).max(1024),
16110
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
16111
+ identity: external_exports.string().max(4096).nullable()
16112
+ });
16113
+ var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
16114
+ external_exports.strictObject({ action: external_exports.literal("list") }),
16115
+ external_exports.strictObject({
16116
+ action: external_exports.literal("save"),
16117
+ draft: codexSshDraftSchema,
16118
+ previous: codexSshConnectionSchema.nullable()
16119
+ }),
16120
+ external_exports.strictObject({ action: external_exports.literal("remove"), previous: codexSshConnectionSchema }),
16121
+ external_exports.strictObject({ action: external_exports.literal("connect"), hostId, enabled: external_exports.boolean() }),
16122
+ external_exports.strictObject({ action: external_exports.literal("state"), hostId }),
16123
+ external_exports.strictObject({ action: external_exports.literal("runtime"), hostId }),
16124
+ external_exports.strictObject({
16125
+ action: external_exports.literal("update"),
16126
+ hostId: hostId.refine((id) => id !== "local"),
16127
+ version: remoteUpdateParamsSchema.shape.version
16128
+ })
16129
+ ]);
16130
+ var remoteConnectionsReplySchema = external_exports.union([
16131
+ external_exports.strictObject({ result: jsonValueSchema }),
16132
+ external_exports.strictObject({ error: external_exports.strictObject({ code: external_exports.number().int(), message: external_exports.string() }) })
16133
+ ]);
16134
+
15568
16135
  // ../../shared-contracts/dist/index.js
15569
16136
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15570
16137
 
@@ -19679,683 +20246,253 @@ var ClientSideConnection = class {
19679
20246
  *
19680
20247
  * This method is only available if the agent advertises the `providers` capability.
19681
20248
  *
19682
- * @experimental
19683
- */
19684
- unstable_listProviders(params) {
19685
- return this.connection.sendRequest(AGENT_METHODS.providers_list, params);
19686
- }
19687
- /**
19688
- * **UNSTABLE**
19689
- *
19690
- * This capability is not part of the spec yet, and may be removed or changed at any point.
19691
- *
19692
- * Replaces the configuration for a provider.
19693
- *
19694
- * This method is only available if the agent advertises the `providers` capability.
19695
- *
19696
- * @experimental
19697
- */
19698
- unstable_setProvider(params) {
19699
- return this.connection.sendRequest(AGENT_METHODS.providers_set, params, emptyObjectResponse);
19700
- }
19701
- /**
19702
- * **UNSTABLE**
19703
- *
19704
- * This capability is not part of the spec yet, and may be removed or changed at any point.
19705
- *
19706
- * Disables a provider.
19707
- *
19708
- * This method is only available if the agent advertises the `providers` capability.
19709
- *
19710
- * @experimental
19711
- */
19712
- unstable_disableProvider(params) {
19713
- return this.connection.sendRequest(AGENT_METHODS.providers_disable, params, emptyObjectResponse);
19714
- }
19715
- /**
19716
- * Logout of the current authentication method.
19717
- */
19718
- logout(params) {
19719
- return this.connection.sendRequest(AGENT_METHODS.logout, params, emptyObjectResponse);
19720
- }
19721
- /**
19722
- * Processes a user prompt within a session.
19723
- *
19724
- * This method handles the whole lifecycle of a prompt:
19725
- * - Receives user messages with optional context (files, images, etc.)
19726
- * - Processes the prompt using language models
19727
- * - Reports language model content and tool calls to the Clients
19728
- * - Requests permission to run tools
19729
- * - Executes any requested tool calls
19730
- * - Returns when the turn is complete with a stop reason
19731
- *
19732
- * See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
19733
- */
19734
- prompt(params) {
19735
- return this.connection.sendRequest(AGENT_METHODS.session_prompt, params);
19736
- }
19737
- /**
19738
- * Cancels ongoing operations for a session.
19739
- *
19740
- * This is a notification sent by the client to cancel an ongoing prompt turn.
19741
- *
19742
- * Upon receiving this notification, the Agent SHOULD:
19743
- * - Stop all language model requests as soon as possible
19744
- * - Abort all tool call invocations in progress
19745
- * - Send any pending `session/update` notifications
19746
- * - Respond to the original `session/prompt` request with `StopReason::Cancelled`
19747
- *
19748
- * See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
19749
- */
19750
- cancel(params) {
19751
- return this.connection.sendNotification(AGENT_METHODS.session_cancel, params);
19752
- }
19753
- /**
19754
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19755
- *
19756
- * Starts a NES (Next Edit Suggestions) session.
19757
- *
19758
- * @experimental
19759
- */
19760
- unstable_startNes(params) {
19761
- return this.connection.sendRequest(AGENT_METHODS.nes_start, params);
19762
- }
19763
- /**
19764
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19765
- *
19766
- * Sends a NES suggestion request.
19767
- *
19768
- * @experimental
19769
- */
19770
- unstable_suggestNes(params) {
19771
- return this.connection.sendRequest(AGENT_METHODS.nes_suggest, params);
19772
- }
19773
- /**
19774
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19775
- *
19776
- * Closes a NES session.
19777
- *
19778
- * @experimental
19779
- */
19780
- unstable_closeNes(params) {
19781
- return this.connection.sendRequest(AGENT_METHODS.nes_close, params, emptyObjectResponse);
19782
- }
19783
- /**
19784
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19785
- *
19786
- * Notifies the agent that a document was opened.
19787
- *
19788
- * @experimental
19789
- */
19790
- unstable_didOpenDocument(params) {
19791
- return this.connection.sendNotification(AGENT_METHODS.document_did_open, params);
19792
- }
19793
- /**
19794
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19795
- *
19796
- * Notifies the agent that a document was changed.
19797
- *
19798
- * @experimental
19799
- */
19800
- unstable_didChangeDocument(params) {
19801
- return this.connection.sendNotification(AGENT_METHODS.document_did_change, params);
19802
- }
19803
- /**
19804
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19805
- *
19806
- * Notifies the agent that a document was closed.
19807
- *
19808
- * @experimental
19809
- */
19810
- unstable_didCloseDocument(params) {
19811
- return this.connection.sendNotification(AGENT_METHODS.document_did_close, params);
19812
- }
19813
- /**
19814
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19815
- *
19816
- * Notifies the agent that a document was saved.
19817
- *
19818
- * @experimental
19819
- */
19820
- unstable_didSaveDocument(params) {
19821
- return this.connection.sendNotification(AGENT_METHODS.document_did_save, params);
19822
- }
19823
- /**
19824
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19825
- *
19826
- * Notifies the agent that a document received focus.
19827
- *
19828
- * @experimental
19829
- */
19830
- unstable_didFocusDocument(params) {
19831
- return this.connection.sendNotification(AGENT_METHODS.document_did_focus, params);
19832
- }
19833
- /**
19834
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19835
- *
19836
- * Notifies the agent that a NES suggestion was accepted.
19837
- *
19838
- * @experimental
19839
- */
19840
- unstable_acceptNes(params) {
19841
- return this.connection.sendNotification(AGENT_METHODS.nes_accept, params);
19842
- }
19843
- /**
19844
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19845
- *
19846
- * Notifies the agent that a NES suggestion was rejected.
19847
- *
19848
- * @experimental
19849
- */
19850
- unstable_rejectNes(params) {
19851
- return this.connection.sendNotification(AGENT_METHODS.nes_reject, params);
19852
- }
19853
- request(method, params, options) {
19854
- const spec = agentRequestSpecsByMethod[method];
19855
- return this.connection.sendRequest(method, params, spec?.mapResponse, options);
19856
- }
19857
- notify(method, params) {
19858
- return this.connection.sendNotification(method, params);
19859
- }
19860
- /**
19861
- * Extension method.
19862
- *
19863
- * @deprecated Use {@link request}.
19864
- */
19865
- extMethod(method, params) {
19866
- return this.request(method, params);
19867
- }
19868
- /**
19869
- * Extension notification.
19870
- *
19871
- * @deprecated Use {@link notify}.
19872
- */
19873
- extNotification(method, params) {
19874
- return this.notify(method, params);
19875
- }
19876
- /**
19877
- * AbortSignal that aborts when the connection closes.
19878
- *
19879
- * This signal can be used to:
19880
- * - Listen for connection closure: `connection.signal.addEventListener('abort', () => {...})`
19881
- * - Check connection status synchronously: `if (connection.signal.aborted) {...}`
19882
- * - Pass to other APIs (fetch, setTimeout) for automatic cancellation
19883
- *
19884
- * The connection closes when the underlying stream ends, either normally or due to an error.
20249
+ * @experimental
20250
+ */
20251
+ unstable_listProviders(params) {
20252
+ return this.connection.sendRequest(AGENT_METHODS.providers_list, params);
20253
+ }
20254
+ /**
20255
+ * **UNSTABLE**
19885
20256
  *
19886
- * @example
19887
- * ```typescript
19888
- * const connection = new ClientSideConnection(client, stream);
20257
+ * This capability is not part of the spec yet, and may be removed or changed at any point.
19889
20258
  *
19890
- * // Listen for closure
19891
- * connection.signal.addEventListener('abort', () => {
19892
- * console.log('Connection closed - performing cleanup');
19893
- * });
20259
+ * Replaces the configuration for a provider.
19894
20260
  *
19895
- * // Check status
19896
- * if (connection.signal.aborted) {
19897
- * console.log('Connection is already closed');
19898
- * }
20261
+ * This method is only available if the agent advertises the `providers` capability.
19899
20262
  *
19900
- * // Pass to other APIs
19901
- * fetch(url, { signal: connection.signal });
19902
- * ```
20263
+ * @experimental
19903
20264
  */
19904
- get signal() {
19905
- return this.connection.signal;
20265
+ unstable_setProvider(params) {
20266
+ return this.connection.sendRequest(AGENT_METHODS.providers_set, params, emptyObjectResponse);
19906
20267
  }
19907
20268
  /**
19908
- * Promise that resolves when the connection closes.
20269
+ * **UNSTABLE**
19909
20270
  *
19910
- * The connection closes when the underlying stream ends, either normally or due to an error.
19911
- * Once closed, the connection cannot send or receive any more messages.
20271
+ * This capability is not part of the spec yet, and may be removed or changed at any point.
19912
20272
  *
19913
- * This is useful for async/await style cleanup:
20273
+ * Disables a provider.
19914
20274
  *
19915
- * @example
19916
- * ```typescript
19917
- * const connection = new ClientSideConnection(client, stream);
19918
- * await connection.closed;
19919
- * console.log('Connection closed - performing cleanup');
19920
- * ```
20275
+ * This method is only available if the agent advertises the `providers` capability.
20276
+ *
20277
+ * @experimental
19921
20278
  */
19922
- get closed() {
19923
- return this.connection.closed;
19924
- }
19925
- };
19926
-
19927
- // dist/command.js
19928
- import path5 from "node:path";
19929
-
19930
- // ../../harness-discovery/dist/environment.js
19931
- import fs from "node:fs";
19932
- import path from "node:path";
19933
- function targetPath(platform) {
19934
- return platform === "win32" ? path.win32 : path.posix;
19935
- }
19936
- function environmentValue(environment, name) {
19937
- const lowered = name.toLowerCase();
19938
- for (const [key, value] of Object.entries(environment)) {
19939
- if (key.toLowerCase() === lowered)
19940
- return value;
19941
- }
19942
- return void 0;
19943
- }
19944
- function pathDelimiter(platform) {
19945
- return platform === "win32" ? ";" : ":";
19946
- }
19947
- function pathDirectories(environment, platform) {
19948
- return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
19949
- }
19950
- function executableExtensions(command, platform, environment) {
19951
- if (platform !== "win32")
19952
- return [""];
19953
- if (targetPath(platform).extname(command) !== "")
19954
- return [""];
19955
- return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
19956
- }
19957
- function isExecutableFile(filePath, platform) {
19958
- try {
19959
- fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
19960
- return fs.statSync(filePath).isFile();
19961
- } catch {
19962
- return false;
19963
- }
19964
- }
19965
- function subdirectoryNames(directory) {
19966
- try {
19967
- return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
19968
- } catch {
19969
- return [];
19970
- }
19971
- }
19972
- function newestFirst(names) {
19973
- return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
19974
- }
19975
-
19976
- // ../../harness-discovery/dist/invocation.js
19977
- import path2 from "node:path";
19978
- function commandInvocation(command, arguments_, environment, platform = process.platform) {
19979
- const extension = path2.win32.extname(command).toLowerCase();
19980
- if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
19981
- return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
19982
- }
19983
- const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
19984
- const commandLine = [command, ...arguments_].map(quote).join(" ");
19985
- return {
19986
- command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
19987
- arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
19988
- windowsVerbatimArguments: true
19989
- };
19990
- }
19991
-
19992
- // ../../harness-discovery/dist/node-runtime.js
19993
- import path3 from "node:path";
19994
- function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
19995
- const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
19996
- const delimiter = platform === "win32" ? ";" : ":";
19997
- const runtimeDirectory = path3.dirname(runtimeExecutable);
19998
- const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
19999
- const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
20000
- if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
20001
- directories.push(runtimeDirectory);
20002
- }
20003
- return { ...environment, [pathKey]: directories.join(delimiter) };
20004
- }
20005
-
20006
- // ../../harness-discovery/dist/resolve.js
20007
- import os from "node:os";
20008
-
20009
- // ../../harness-discovery/dist/version-managers.js
20010
- function versionManagerBinaryDirectories(context) {
20011
- const { platform, environment, home } = context;
20012
- const list = context.subdirectories ?? subdirectoryNames;
20013
- const pathFlavor = targetPath(platform);
20014
- const value = (name) => environmentValue(environment, name);
20015
- const directories = [];
20016
- const versioned = (root, ...tail) => {
20017
- for (const version2 of newestFirst(list(root))) {
20018
- directories.push(pathFlavor.join(root, version2, ...tail));
20019
- }
20020
- };
20021
- if (platform === "win32") {
20022
- const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
20023
- const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
20024
- versioned(pathFlavor.join(appData, "nvm"));
20025
- versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
20026
- directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
20027
- directories.push(pathFlavor.join(home, ".bun", "bin"));
20028
- const pnpmHome2 = value("PNPM_HOME");
20029
- if (pnpmHome2)
20030
- directories.push(pnpmHome2);
20031
- directories.push(pathFlavor.join(localAppData, "pnpm"));
20032
- return directories;
20033
- }
20034
- versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
20035
- const fnmRoots = [
20036
- value("FNM_DIR"),
20037
- pathFlavor.join(home, ".local", "share", "fnm"),
20038
- pathFlavor.join(home, "Library", "Application Support", "fnm")
20039
- ].filter((root) => root !== void 0);
20040
- for (const root of fnmRoots) {
20041
- versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
20279
+ unstable_disableProvider(params) {
20280
+ return this.connection.sendRequest(AGENT_METHODS.providers_disable, params, emptyObjectResponse);
20042
20281
  }
20043
- const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
20044
- versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
20045
- directories.push(pathFlavor.join(voltaHome, "bin"));
20046
- const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
20047
- versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
20048
- directories.push(pathFlavor.join(asdfHome, "shims"));
20049
- const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
20050
- versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
20051
- directories.push(pathFlavor.join(nodenvHome, "shims"));
20052
- versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
20053
- directories.push(pathFlavor.join(home, ".bun", "bin"));
20054
- const pnpmHome = value("PNPM_HOME");
20055
- if (pnpmHome)
20056
- directories.push(pnpmHome);
20057
- directories.push(pathFlavor.join(home, "Library", "pnpm"));
20058
- directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
20059
- for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
20060
- for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
20061
- directories.push(pathFlavor.join(prefix, formula, "bin"));
20062
- }
20282
+ /**
20283
+ * Logout of the current authentication method.
20284
+ */
20285
+ logout(params) {
20286
+ return this.connection.sendRequest(AGENT_METHODS.logout, params, emptyObjectResponse);
20063
20287
  }
20064
- return directories;
20065
- }
20066
-
20067
- // ../../harness-discovery/dist/resolve.js
20068
- var VERSION_MANAGER_ROOTS = "<version-managers>";
20069
- function installRootExtensions(platform) {
20070
- return platform === "win32" ? [".exe", ".cmd"] : [""];
20071
- }
20072
- function resolveHomeDirectory(input) {
20073
- return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
20074
- }
20075
- function templateVariables(environment, platform, home) {
20076
- const pathFlavor = targetPath(platform);
20077
- return {
20078
- HOME: home,
20079
- USERPROFILE: home,
20080
- APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
20081
- LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
20082
- };
20083
- }
20084
- function joinTemplate(platform, value) {
20085
- const pathFlavor = targetPath(platform);
20086
- const segments = value.split("/");
20087
- const head = segments[0] ?? "";
20088
- const tail = segments.slice(1);
20089
- if (head === "")
20090
- return pathFlavor.join(pathFlavor.sep, ...tail);
20091
- return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
20092
- }
20093
- function expandInstallRoot(template, environment, platform, home) {
20094
- const variables = templateVariables(environment, platform, home);
20095
- let unresolved = false;
20096
- const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
20097
- const value = variables[name] ?? environmentValue(environment, name);
20098
- if (value === void 0 || value === "") {
20099
- unresolved = true;
20100
- return "";
20101
- }
20102
- return value;
20103
- });
20104
- return unresolved ? void 0 : joinTemplate(platform, substituted);
20105
- }
20106
- function installRootDirectories(spec, input, dependencies, platform, home) {
20107
- const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
20108
- const directories = [];
20109
- for (const template of templates) {
20110
- if (template === VERSION_MANAGER_ROOTS) {
20111
- directories.push(...versionManagerBinaryDirectories({
20112
- platform,
20113
- environment: input.environment,
20114
- home,
20115
- ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
20116
- }));
20117
- continue;
20118
- }
20119
- const directory = expandInstallRoot(template, input.environment, platform, home);
20120
- if (directory !== void 0)
20121
- directories.push(directory);
20288
+ /**
20289
+ * Processes a user prompt within a session.
20290
+ *
20291
+ * This method handles the whole lifecycle of a prompt:
20292
+ * - Receives user messages with optional context (files, images, etc.)
20293
+ * - Processes the prompt using language models
20294
+ * - Reports language model content and tool calls to the Clients
20295
+ * - Requests permission to run tools
20296
+ * - Executes any requested tool calls
20297
+ * - Returns when the turn is complete with a stop reason
20298
+ *
20299
+ * See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
20300
+ */
20301
+ prompt(params) {
20302
+ return this.connection.sendRequest(AGENT_METHODS.session_prompt, params);
20122
20303
  }
20123
- return directories;
20124
- }
20125
- function harnessCandidates(spec, input, dependencies = {}) {
20126
- const platform = input.platform ?? process.platform;
20127
- const pathFlavor = targetPath(platform);
20128
- const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
20129
- const command = configured ?? spec.command;
20130
- if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
20131
- return [{ candidate: command, source: "configured" }];
20304
+ /**
20305
+ * Cancels ongoing operations for a session.
20306
+ *
20307
+ * This is a notification sent by the client to cancel an ongoing prompt turn.
20308
+ *
20309
+ * Upon receiving this notification, the Agent SHOULD:
20310
+ * - Stop all language model requests as soon as possible
20311
+ * - Abort all tool call invocations in progress
20312
+ * - Send any pending `session/update` notifications
20313
+ * - Respond to the original `session/prompt` request with `StopReason::Cancelled`
20314
+ *
20315
+ * See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
20316
+ */
20317
+ cancel(params) {
20318
+ return this.connection.sendNotification(AGENT_METHODS.session_cancel, params);
20132
20319
  }
20133
- const candidates = [];
20134
- const extensions = executableExtensions(command, platform, input.environment);
20135
- for (const directory of pathDirectories(input.environment, platform)) {
20136
- for (const extension of extensions) {
20137
- candidates.push({
20138
- candidate: pathFlavor.join(directory, command + extension),
20139
- source: "path"
20140
- });
20141
- }
20320
+ /**
20321
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20322
+ *
20323
+ * Starts a NES (Next Edit Suggestions) session.
20324
+ *
20325
+ * @experimental
20326
+ */
20327
+ unstable_startNes(params) {
20328
+ return this.connection.sendRequest(AGENT_METHODS.nes_start, params);
20142
20329
  }
20143
- if (configured !== void 0)
20144
- return candidates;
20145
- const home = resolveHomeDirectory(input);
20146
- for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
20147
- for (const extension of installRootExtensions(platform)) {
20148
- candidates.push({
20149
- candidate: pathFlavor.join(directory, spec.command + extension),
20150
- source: "install-root"
20151
- });
20152
- }
20330
+ /**
20331
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20332
+ *
20333
+ * Sends a NES suggestion request.
20334
+ *
20335
+ * @experimental
20336
+ */
20337
+ unstable_suggestNes(params) {
20338
+ return this.connection.sendRequest(AGENT_METHODS.nes_suggest, params);
20153
20339
  }
20154
- return candidates;
20155
- }
20156
- function resolveHarnessExecutable(spec, input, dependencies = {}) {
20157
- const platform = input.platform ?? process.platform;
20158
- const isExecutable = dependencies.isExecutable ?? ((candidate) => isExecutableFile(candidate, platform));
20159
- const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
20160
- const context = { platform, isExecutable };
20161
- for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
20162
- const executable = runnable(candidate, context);
20163
- if (executable !== void 0 && isExecutable(executable))
20164
- return { executable, source };
20340
+ /**
20341
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20342
+ *
20343
+ * Closes a NES session.
20344
+ *
20345
+ * @experimental
20346
+ */
20347
+ unstable_closeNes(params) {
20348
+ return this.connection.sendRequest(AGENT_METHODS.nes_close, params, emptyObjectResponse);
20165
20349
  }
20166
- return void 0;
20167
- }
20168
-
20169
- // ../../harness-discovery/dist/installation.js
20170
- import { execFile } from "node:child_process";
20171
- import { homedir } from "node:os";
20172
- function runInstallationCommand(command, args, environment, timeout = 3e4) {
20173
- const env = withNodeRuntimeOnPath(environment);
20174
- const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
20175
- return new Promise((resolve, reject) => {
20176
- const child = execFile(invocation.command, invocation.arguments, {
20177
- env,
20178
- cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
20179
- encoding: "utf8",
20180
- timeout,
20181
- killSignal: "SIGKILL",
20182
- maxBuffer: 1024 * 1024,
20183
- windowsHide: true,
20184
- windowsVerbatimArguments: invocation.windowsVerbatimArguments
20185
- }, (error51, stdout, stderr) => {
20186
- if (error51)
20187
- reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
20188
- else
20189
- resolve((stdout || stderr).trim());
20190
- });
20191
- child.stdin?.end();
20192
- });
20193
- }
20194
- function installationVersion(value) {
20195
- if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
20196
- throw new Error("Harness returned an invalid version");
20197
- return value.trim().replace(/^v/, "");
20198
- }
20199
- function versionFromOutput(output) {
20200
- return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
20201
- }
20202
- function newerInstallationVersion(current, latest) {
20203
- const a = installationVersion(current).replace(/\+.*/, "");
20204
- const b = installationVersion(latest).replace(/\+.*/, "");
20205
- const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
20206
- const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
20207
- for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
20208
- if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
20209
- return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
20350
+ /**
20351
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20352
+ *
20353
+ * Notifies the agent that a document was opened.
20354
+ *
20355
+ * @experimental
20356
+ */
20357
+ unstable_didOpenDocument(params) {
20358
+ return this.connection.sendNotification(AGENT_METHODS.document_did_open, params);
20210
20359
  }
20211
- const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
20212
- const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
20213
- if (!preA.length || !preB.length)
20214
- return !!preA.length && !preB.length;
20215
- for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
20216
- const x = preA[i];
20217
- const y = preB[i];
20218
- if (x === y)
20219
- continue;
20220
- if (x === void 0 || y === void 0)
20221
- return x === void 0;
20222
- const numericX = /^\d+$/.test(x);
20223
- const numericY = /^\d+$/.test(y);
20224
- if (numericX && numericY) {
20225
- if (BigInt(x) === BigInt(y))
20226
- continue;
20227
- return BigInt(y) > BigInt(x);
20228
- }
20229
- if (numericX !== numericY)
20230
- return numericX;
20231
- return y > x;
20360
+ /**
20361
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20362
+ *
20363
+ * Notifies the agent that a document was changed.
20364
+ *
20365
+ * @experimental
20366
+ */
20367
+ unstable_didChangeDocument(params) {
20368
+ return this.connection.sendNotification(AGENT_METHODS.document_did_change, params);
20232
20369
  }
20233
- return false;
20234
- }
20235
- function createInstallationManager(options) {
20236
- let checking;
20237
- let updating;
20238
- const check2 = () => checking ??= options.check().finally(() => {
20239
- checking = void 0;
20240
- });
20241
- return (action) => {
20242
- if (updating)
20243
- return updating;
20244
- if (action === "check")
20245
- return check2();
20246
- updating = (async () => {
20247
- const before = await check2();
20248
- if (!before.updateAvailable)
20249
- return before;
20250
- if (!before.canUpdate)
20251
- throw new Error(before.message ?? "This installation cannot be updated automatically");
20252
- await options.update(before);
20253
- const after = await check2();
20254
- if (after.currentVersion === before.currentVersion)
20255
- throw new Error("The Harness version did not change; check the native updater and retry");
20256
- return after;
20257
- })().finally(() => {
20258
- updating = void 0;
20259
- });
20260
- return updating;
20261
- };
20262
- }
20263
- async function fetchInstallationText(url2) {
20264
- const request = async () => {
20265
- const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
20266
- if (!response.ok)
20267
- throw new Error("Could not check the latest Harness version");
20268
- return response.text();
20269
- };
20270
- try {
20271
- return await request();
20272
- } catch (error51) {
20273
- if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
20274
- throw error51;
20275
- return request();
20370
+ /**
20371
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20372
+ *
20373
+ * Notifies the agent that a document was closed.
20374
+ *
20375
+ * @experimental
20376
+ */
20377
+ unstable_didCloseDocument(params) {
20378
+ return this.connection.sendNotification(AGENT_METHODS.document_did_close, params);
20379
+ }
20380
+ /**
20381
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20382
+ *
20383
+ * Notifies the agent that a document was saved.
20384
+ *
20385
+ * @experimental
20386
+ */
20387
+ unstable_didSaveDocument(params) {
20388
+ return this.connection.sendNotification(AGENT_METHODS.document_did_save, params);
20389
+ }
20390
+ /**
20391
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20392
+ *
20393
+ * Notifies the agent that a document received focus.
20394
+ *
20395
+ * @experimental
20396
+ */
20397
+ unstable_didFocusDocument(params) {
20398
+ return this.connection.sendNotification(AGENT_METHODS.document_did_focus, params);
20399
+ }
20400
+ /**
20401
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20402
+ *
20403
+ * Notifies the agent that a NES suggestion was accepted.
20404
+ *
20405
+ * @experimental
20406
+ */
20407
+ unstable_acceptNes(params) {
20408
+ return this.connection.sendNotification(AGENT_METHODS.nes_accept, params);
20276
20409
  }
20277
- }
20278
-
20279
- // ../../harness-discovery/dist/npm-installation.js
20280
- import { readFile, realpath } from "node:fs/promises";
20281
- import path4 from "node:path";
20282
- function referencesNpmBin(shim, name, bin) {
20283
- if (bin.includes(".."))
20284
- return false;
20285
- const target = `node_modules/${name}/${bin.replace(/^\.\//, "")}`.toLowerCase();
20286
- const text = shim.replaceAll("\\", "/").toLowerCase();
20287
- return text.includes(`%dp0%/${target}"`) || text.includes(`%~dp0/${target}"`);
20288
- }
20289
- async function npmInstallation(command, packages, environment) {
20290
- let selected = await realpath(command);
20291
- if (process.platform === "win32" && /\.(cmd|bat)$/i.test(selected)) {
20292
- const shim = (await readFile(selected, "utf8")).replaceAll("\\", "/");
20293
- const root = path4.dirname(selected);
20294
- for (const name of packages) {
20295
- const directory2 = path4.join(root, "node_modules", ...name.split("/"));
20296
- const metadata = await readFile(path4.join(directory2, "package.json"), "utf8").then((text) => JSON.parse(text)).catch(() => null);
20297
- const bins = typeof metadata?.bin === "string" ? [metadata.bin] : Object.values(metadata?.bin ?? {});
20298
- const bin = bins.find((entry) => referencesNpmBin(shim, name, entry));
20299
- if (bin) {
20300
- selected = await realpath(path4.join(directory2, bin));
20301
- break;
20302
- }
20303
- }
20410
+ /**
20411
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20412
+ *
20413
+ * Notifies the agent that a NES suggestion was rejected.
20414
+ *
20415
+ * @experimental
20416
+ */
20417
+ unstable_rejectNes(params) {
20418
+ return this.connection.sendNotification(AGENT_METHODS.nes_reject, params);
20304
20419
  }
20305
- let directory = path4.dirname(selected);
20306
- for (let depth = 0; depth < 8; depth++) {
20307
- const metadata = await readFile(path4.join(directory, "package.json"), "utf8").then((text) => JSON.parse(text)).catch(() => null);
20308
- if (metadata?.name && packages.includes(metadata.name)) {
20309
- const name = metadata.name;
20310
- const currentVersion = installationVersion(metadata.version);
20311
- const segments = name.split("/");
20312
- let modules = directory;
20313
- for (let index = 0; index < segments.length; index++)
20314
- modules = path4.dirname(modules);
20315
- const prefix = process.platform === "win32" ? path4.dirname(modules) : path4.dirname(path4.dirname(modules));
20316
- const globalRoot = process.platform === "win32" ? path4.join(prefix, "node_modules") : path4.join(prefix, "lib", "node_modules");
20317
- const env = withNodeRuntimeOnPath(environment);
20318
- const npm = resolveHarnessExecutable({ id: "npm", command: "npm", installRoots: { posix: [], windows: [] } }, { environment: env });
20319
- let globalInstall = modules === globalRoot;
20320
- if (process.platform === "win32") {
20321
- 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);
20322
- const bins = typeof metadata.bin === "string" ? { [name.split("/").at(-1) ?? name]: metadata.bin } : metadata.bin ?? {};
20323
- const launchers = await Promise.all(Object.entries(bins).map(async ([bin, entry]) => {
20324
- if (path4.basename(bin) !== bin || entry.includes(".."))
20325
- return false;
20326
- const target = await realpath(path4.join(directory, entry)).catch(() => "");
20327
- if (target.toLowerCase() !== selected.toLowerCase())
20328
- return false;
20329
- const shim = await readFile(path4.join(prefix, `${bin}.cmd`), "utf8").catch(() => "");
20330
- return referencesNpmBin(shim, name, entry);
20331
- }));
20332
- globalInstall = globalInstall && !project && launchers.some(Boolean);
20333
- }
20334
- const canUpdate = globalInstall && !!npm;
20335
- return {
20336
- prefix,
20337
- currentVersion,
20338
- canUpdate,
20339
- latest: async () => {
20340
- const data = JSON.parse(await fetchInstallationText(`https://registry.npmjs.org/${encodeURIComponent(name)}/latest`));
20341
- return installationVersion(data.version);
20342
- },
20343
- update: async (version2) => {
20344
- if (!canUpdate || !npm)
20345
- throw new Error("Use the original package manager to update this installation");
20346
- await runInstallationCommand(npm.executable, ["install", "--global", "--prefix", prefix, `${name}@${installationVersion(version2)}`], env, 3e5);
20347
- }
20348
- };
20349
- }
20350
- const parent = path4.dirname(directory);
20351
- if (parent === directory)
20352
- break;
20353
- directory = parent;
20420
+ request(method, params, options) {
20421
+ const spec = agentRequestSpecsByMethod[method];
20422
+ return this.connection.sendRequest(method, params, spec?.mapResponse, options);
20354
20423
  }
20355
- return null;
20356
- }
20424
+ notify(method, params) {
20425
+ return this.connection.sendNotification(method, params);
20426
+ }
20427
+ /**
20428
+ * Extension method.
20429
+ *
20430
+ * @deprecated Use {@link request}.
20431
+ */
20432
+ extMethod(method, params) {
20433
+ return this.request(method, params);
20434
+ }
20435
+ /**
20436
+ * Extension notification.
20437
+ *
20438
+ * @deprecated Use {@link notify}.
20439
+ */
20440
+ extNotification(method, params) {
20441
+ return this.notify(method, params);
20442
+ }
20443
+ /**
20444
+ * AbortSignal that aborts when the connection closes.
20445
+ *
20446
+ * This signal can be used to:
20447
+ * - Listen for connection closure: `connection.signal.addEventListener('abort', () => {...})`
20448
+ * - Check connection status synchronously: `if (connection.signal.aborted) {...}`
20449
+ * - Pass to other APIs (fetch, setTimeout) for automatic cancellation
20450
+ *
20451
+ * The connection closes when the underlying stream ends, either normally or due to an error.
20452
+ *
20453
+ * @example
20454
+ * ```typescript
20455
+ * const connection = new ClientSideConnection(client, stream);
20456
+ *
20457
+ * // Listen for closure
20458
+ * connection.signal.addEventListener('abort', () => {
20459
+ * console.log('Connection closed - performing cleanup');
20460
+ * });
20461
+ *
20462
+ * // Check status
20463
+ * if (connection.signal.aborted) {
20464
+ * console.log('Connection is already closed');
20465
+ * }
20466
+ *
20467
+ * // Pass to other APIs
20468
+ * fetch(url, { signal: connection.signal });
20469
+ * ```
20470
+ */
20471
+ get signal() {
20472
+ return this.connection.signal;
20473
+ }
20474
+ /**
20475
+ * Promise that resolves when the connection closes.
20476
+ *
20477
+ * The connection closes when the underlying stream ends, either normally or due to an error.
20478
+ * Once closed, the connection cannot send or receive any more messages.
20479
+ *
20480
+ * This is useful for async/await style cleanup:
20481
+ *
20482
+ * @example
20483
+ * ```typescript
20484
+ * const connection = new ClientSideConnection(client, stream);
20485
+ * await connection.closed;
20486
+ * console.log('Connection closed - performing cleanup');
20487
+ * ```
20488
+ */
20489
+ get closed() {
20490
+ return this.connection.closed;
20491
+ }
20492
+ };
20357
20493
 
20358
20494
  // dist/command.js
20495
+ import path5 from "node:path";
20359
20496
  var KimiExecutableError = class extends Error {
20360
20497
  code = "KIMI_NOT_FOUND";
20361
20498
  };
@@ -20825,9 +20962,9 @@ var KimiAcpTransport = class {
20825
20962
 
20826
20963
  // dist/account-identity.js
20827
20964
  import { randomUUID } from "node:crypto";
20828
- import { readFile as readFile2, rename, unlink, writeFile } from "node:fs/promises";
20965
+ import { readFile as readFile2, rename, unlink, writeFile as writeFile2 } from "node:fs/promises";
20829
20966
  import { homedir as homedir2 } from "node:os";
20830
- import { join } from "node:path";
20967
+ import { join as join2 } from "node:path";
20831
20968
  var KIMI_USAGES_ENDPOINT = "https://api.kimi.com/coding/v1/usages";
20832
20969
  var KIMI_OAUTH_TOKEN_ENDPOINT = "https://auth.kimi.com/api/oauth/token";
20833
20970
  var KIMI_CODE_CLIENT_ID = "17e5f671-d194-4dfb-9706-5516cb48c098";
@@ -20849,10 +20986,10 @@ var refreshResponseSchema = external_exports.object({
20849
20986
  token_type: external_exports.string().optional()
20850
20987
  });
20851
20988
  function kimiHome(environment) {
20852
- return environment.KIMI_CODE_HOME ?? join(environment.HOME ?? homedir2(), ".kimi-code");
20989
+ return environment.KIMI_CODE_HOME ?? join2(environment.HOME ?? homedir2(), ".kimi-code");
20853
20990
  }
20854
20991
  function credentialPath(environment) {
20855
- return join(kimiHome(environment), "credentials", "kimi-code.json");
20992
+ return join2(kimiHome(environment), "credentials", "kimi-code.json");
20856
20993
  }
20857
20994
  function oauthTokenUrl(environment) {
20858
20995
  const host = environment.KIMI_CODE_OAUTH_HOST ?? environment.KIMI_OAUTH_HOST;
@@ -20957,7 +21094,7 @@ async function readNativeCredentials(filePath, readAuthFile) {
20957
21094
  async function defaultWriteAuthFile(filePath, contents) {
20958
21095
  const temporary = `${filePath}.${randomUUID()}.tmp`;
20959
21096
  try {
20960
- await writeFile(temporary, contents, { encoding: "utf8", mode: 384, flag: "wx" });
21097
+ await writeFile2(temporary, contents, { encoding: "utf8", mode: 384, flag: "wx" });
20961
21098
  await rename(temporary, filePath);
20962
21099
  } finally {
20963
21100
  await unlink(temporary).catch(() => void 0);
@@ -21147,16 +21284,16 @@ var Diff = class {
21147
21284
  }
21148
21285
  }
21149
21286
  }
21150
- addToPath(path9, added, removed, oldPosInc, options) {
21151
- const last = path9.lastComponent;
21287
+ addToPath(path10, added, removed, oldPosInc, options) {
21288
+ const last = path10.lastComponent;
21152
21289
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
21153
21290
  return {
21154
- oldPos: path9.oldPos + oldPosInc,
21291
+ oldPos: path10.oldPos + oldPosInc,
21155
21292
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
21156
21293
  };
21157
21294
  } else {
21158
21295
  return {
21159
- oldPos: path9.oldPos + oldPosInc,
21296
+ oldPos: path10.oldPos + oldPosInc,
21160
21297
  lastComponent: { count: 1, added, removed, previousComponent: last }
21161
21298
  };
21162
21299
  }
@@ -23110,19 +23247,259 @@ async function readKimiSessionUsage(sessionId, options = {}) {
23110
23247
  }
23111
23248
  }
23112
23249
 
23250
+ // dist/session-import.js
23251
+ import { readFile as readFile4, stat } from "node:fs/promises";
23252
+ import path7 from "node:path";
23253
+
23254
+ // ../../harness-adapter/dist/session-import.js
23255
+ import { lstat } from "node:fs/promises";
23256
+ var SessionImportChangedError = class extends Error {
23257
+ constructor(message = "Native Session changed during discovery; refresh and retry") {
23258
+ super(message);
23259
+ this.name = "SessionImportChangedError";
23260
+ }
23261
+ };
23262
+ function isMissingFileError(error51) {
23263
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT";
23264
+ }
23265
+ function sameFileFingerprint(left, right) {
23266
+ return left === null || right === null ? left === right : left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
23267
+ }
23268
+ var STORAGE_ACCESS_ERRORS = /* @__PURE__ */ new Set(["EACCES", "EPERM", "EIO", "EMFILE", "ENFILE"]);
23269
+ function isStorageAccessError(error51) {
23270
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && typeof error51.code === "string" && STORAGE_ACCESS_ERRORS.has(error51.code);
23271
+ }
23272
+ async function optionalLstat(file2) {
23273
+ try {
23274
+ return await lstat(file2);
23275
+ } catch (error51) {
23276
+ if (isMissingFileError(error51))
23277
+ return null;
23278
+ throw error51;
23279
+ }
23280
+ }
23281
+ async function readStableFiles(files, read) {
23282
+ const before = await Promise.all(files.map(optionalLstat));
23283
+ const value = await read(before);
23284
+ const after = await Promise.all(files.map(optionalLstat));
23285
+ if (before.some((info, index) => !sameFileFingerprint(info, after[index] ?? null)))
23286
+ throw new SessionImportChangedError();
23287
+ return value;
23288
+ }
23289
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
23290
+ if (typeof value !== "string")
23291
+ return null;
23292
+ const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
23293
+ if (!normalized)
23294
+ return null;
23295
+ if (normalized.length <= maxLength)
23296
+ return normalized;
23297
+ const characters = [...normalized];
23298
+ if (characters.length <= maxLength)
23299
+ return normalized;
23300
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
23301
+ }
23302
+ function sessionImportCandidate(input) {
23303
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
23304
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
23305
+ nativeSessionId: input.nativeSessionId,
23306
+ cwd: input.cwd,
23307
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
23308
+ updatedAt: Math.floor(time3),
23309
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
23310
+ running: typeof input.running === "boolean" ? input.running : null
23311
+ });
23312
+ return parsed.success ? parsed.data : null;
23313
+ }
23314
+ var SessionImportScope = class {
23315
+ #abort = new AbortController();
23316
+ #options;
23317
+ #pending = /* @__PURE__ */ new Set();
23318
+ constructor(options) {
23319
+ this.#options = options;
23320
+ }
23321
+ #closed() {
23322
+ return {
23323
+ ok: false,
23324
+ error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
23325
+ };
23326
+ }
23327
+ read(operation) {
23328
+ const signal = this.#abort.signal;
23329
+ if (signal.aborted)
23330
+ return Promise.resolve(this.#closed());
23331
+ let started;
23332
+ try {
23333
+ started = operation(signal);
23334
+ } catch (error51) {
23335
+ started = Promise.reject(error51 instanceof Error ? error51 : new Error("Session read failed"));
23336
+ }
23337
+ const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
23338
+ ok: false,
23339
+ error: {
23340
+ code: "unavailable",
23341
+ message: this.#options.unavailableMessage,
23342
+ retryable: true
23343
+ }
23344
+ }).finally(() => this.#pending.delete(request));
23345
+ this.#pending.add(request);
23346
+ return request;
23347
+ }
23348
+ /** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
23349
+ async resolve(operation) {
23350
+ const result = await this.read(operation);
23351
+ if (!result.ok)
23352
+ return result;
23353
+ return result.value ? { ok: true, value: result.value } : {
23354
+ ok: false,
23355
+ error: {
23356
+ code: "sessionNotFound",
23357
+ message: this.#options.notFoundMessage,
23358
+ retryable: false
23359
+ }
23360
+ };
23361
+ }
23362
+ /** Idempotent. Resolves after every started read has settled. */
23363
+ async close() {
23364
+ this.#abort.abort();
23365
+ await Promise.allSettled(this.#pending);
23366
+ }
23367
+ };
23368
+
23369
+ // dist/session-import.js
23370
+ function isRecord5(value) {
23371
+ return typeof value === "object" && value !== null && !Array.isArray(value);
23372
+ }
23373
+ var KimiSessionImport = class {
23374
+ #home;
23375
+ #scope = new SessionImportScope({
23376
+ closedMessage: "Kimi Session import is closed",
23377
+ unavailableMessage: "Kimi sessions could not be read; close native clients, check storage access and retry",
23378
+ notFoundMessage: "Kimi Session is no longer importable"
23379
+ });
23380
+ constructor(options) {
23381
+ this.#home = getKimiCodeHome(options.homeDirectory, options.environment);
23382
+ }
23383
+ listCandidates() {
23384
+ return this.#scope.read(async (signal) => {
23385
+ const candidates = [];
23386
+ for (const nativeSessionId of await this.#indexedSessions(signal)) {
23387
+ try {
23388
+ const source = await this.#source(nativeSessionId, signal);
23389
+ if (source)
23390
+ candidates.push(source.candidate);
23391
+ } catch (error51) {
23392
+ if (!(error51 instanceof SessionImportChangedError))
23393
+ throw error51;
23394
+ }
23395
+ }
23396
+ return candidates;
23397
+ });
23398
+ }
23399
+ resolveCandidate(nativeSessionId) {
23400
+ return this.#scope.resolve(async (signal) => (await this.#indexedSessions(signal)).has(nativeSessionId) ? this.#source(nativeSessionId, signal) : null);
23401
+ }
23402
+ close() {
23403
+ return this.#scope.close();
23404
+ }
23405
+ /** Live identities in Kimi's index. The last record of an identity decides, as in resume. */
23406
+ async #indexedSessions(signal) {
23407
+ const live = /* @__PURE__ */ new Set();
23408
+ let content;
23409
+ try {
23410
+ content = await readFile4(path7.join(this.#home, "session_index.jsonl"), {
23411
+ encoding: "utf8",
23412
+ signal
23413
+ });
23414
+ } catch (error51) {
23415
+ signal.throwIfAborted();
23416
+ if (isMissingFileError(error51))
23417
+ return live;
23418
+ throw error51;
23419
+ }
23420
+ for (const line of content.split("\n")) {
23421
+ if (!line.trim())
23422
+ continue;
23423
+ let entry;
23424
+ try {
23425
+ entry = JSON.parse(line);
23426
+ } catch {
23427
+ continue;
23428
+ }
23429
+ if (!isRecord5(entry) || typeof entry.sessionId !== "string" || !entry.sessionId)
23430
+ continue;
23431
+ if (entry.deleted || typeof entry.sessionDir !== "string")
23432
+ live.delete(entry.sessionId);
23433
+ else
23434
+ live.add(entry.sessionId);
23435
+ }
23436
+ return live;
23437
+ }
23438
+ async #source(nativeSessionId, signal) {
23439
+ signal.throwIfAborted();
23440
+ const options = { kimiCodeHome: this.#home };
23441
+ let located;
23442
+ try {
23443
+ located = await locateKimiSession(nativeSessionId, options);
23444
+ } catch (error51) {
23445
+ if (isStorageAccessError(error51))
23446
+ throw error51;
23447
+ return null;
23448
+ }
23449
+ if (!located)
23450
+ return null;
23451
+ const { state } = located;
23452
+ const files = [
23453
+ path7.join(located.sessionDir, "state.json"),
23454
+ path7.join(located.mainHomeDir, "wire.jsonl")
23455
+ ];
23456
+ return readStableFiles(files, async ([stateInfo, wire]) => {
23457
+ if (!stateInfo?.isFile() || !wire?.isFile())
23458
+ return null;
23459
+ try {
23460
+ if (typeof state.cwd !== "string" || !path7.isAbsolute(state.cwd))
23461
+ return null;
23462
+ const cwd = path7.resolve(state.cwd);
23463
+ if (!(await stat(cwd)).isDirectory())
23464
+ return null;
23465
+ signal.throwIfAborted();
23466
+ const { turns } = await readKimiSessionSnapshot(nativeSessionId, options);
23467
+ const prompt = turns.flatMap((turn) => turn.input).find((input) => input.type === "text" && input.text.trim().length > 0);
23468
+ if (!prompt)
23469
+ return null;
23470
+ const activity = turns.flatMap((turn) => [turn.completedAtMs, turn.startedAtMs]).filter((time3) => typeof time3 === "number" && Number.isFinite(time3));
23471
+ const candidate = sessionImportCandidate({
23472
+ nativeSessionId,
23473
+ cwd,
23474
+ title: sessionImportTitle(state.title) ?? sessionImportTitle(prompt.text),
23475
+ // Wire record times are milliseconds; the state file's unit is not documented.
23476
+ updatedAt: activity.length > 0 ? Math.max(...activity) : wire.mtimeMs
23477
+ // Kimi has no cross-process activity marker: idleness cannot be established.
23478
+ });
23479
+ return candidate ? { candidate, nativeRef: createKimiNativeSessionRef(nativeSessionId, cwd) } : null;
23480
+ } catch (error51) {
23481
+ signal.throwIfAborted();
23482
+ if (isStorageAccessError(error51))
23483
+ throw error51;
23484
+ return null;
23485
+ }
23486
+ });
23487
+ }
23488
+ };
23489
+
23113
23490
  // dist/kimi-session.js
23114
23491
  import { setTimeout as delay } from "node:timers/promises";
23115
23492
 
23116
23493
  // dist/command-history.js
23117
- import { appendFile, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
23118
- import path7 from "node:path";
23494
+ import { appendFile, readFile as readFile5, writeFile as writeFile3 } from "node:fs/promises";
23495
+ import path8 from "node:path";
23119
23496
  async function readKimiCommandHistory(sessionId, options) {
23120
23497
  const located = await locateKimiSession(sessionId, options);
23121
23498
  if (!located)
23122
23499
  return [];
23123
23500
  let content;
23124
23501
  try {
23125
- content = await readFile4(path7.join(located.sessionDir, "codexhost-commands.jsonl"), "utf8");
23502
+ content = await readFile5(path8.join(located.sessionDir, "codexhost-commands.jsonl"), "utf8");
23126
23503
  } catch (error51) {
23127
23504
  if (error51.code === "ENOENT")
23128
23505
  return [];
@@ -23152,7 +23529,7 @@ async function appendKimiCommandHistory(turn, options) {
23152
23529
  const located = await locateKimiSession(turn.nativeTurnRef.nativeSessionId, options);
23153
23530
  if (!located)
23154
23531
  throw new Error("Cannot persist Kimi command: native session is missing");
23155
- await appendFile(path7.join(located.sessionDir, "codexhost-commands.jsonl"), `${JSON.stringify(turn)}
23532
+ await appendFile(path8.join(located.sessionDir, "codexhost-commands.jsonl"), `${JSON.stringify(turn)}
23156
23533
  `, "utf8");
23157
23534
  }
23158
23535
  async function copyKimiCommandHistory(turns, sessionId, options) {
@@ -23166,7 +23543,7 @@ async function copyKimiCommandHistory(turns, sessionId, options) {
23166
23543
  nativeTurnRef: { ...turn.nativeTurnRef, nativeSessionId: sessionId },
23167
23544
  ...turn.checkpoint ? { checkpoint: { ...turn.checkpoint, nativeSessionId: sessionId } } : {}
23168
23545
  }));
23169
- await writeFile2(path7.join(located.sessionDir, "codexhost-commands.jsonl"), copied.map((turn) => `${JSON.stringify(turn)}
23546
+ await writeFile3(path8.join(located.sessionDir, "codexhost-commands.jsonl"), copied.map((turn) => `${JSON.stringify(turn)}
23170
23547
  `).join(""), "utf8");
23171
23548
  }
23172
23549
 
@@ -24335,6 +24712,7 @@ function stateFromConfig(sessionId, cwd, configOptions) {
24335
24712
  }
24336
24713
  var KimiAdapter = class {
24337
24714
  harnessId = kimiHarnessId3;
24715
+ sessionImport;
24338
24716
  #options;
24339
24717
  #deps;
24340
24718
  #sessions = /* @__PURE__ */ new Set();
@@ -24347,6 +24725,10 @@ var KimiAdapter = class {
24347
24725
  constructor(options = {}, dependencies = {}) {
24348
24726
  this.#options = options;
24349
24727
  this.#deps = dependencies;
24728
+ this.sessionImport = new KimiSessionImport({
24729
+ environment: { ...process.env, ...options.environment },
24730
+ homeDirectory: options.homeDirectory
24731
+ });
24350
24732
  }
24351
24733
  async inspectAccount() {
24352
24734
  if (this.#closed)
@@ -24385,10 +24767,10 @@ var KimiAdapter = class {
24385
24767
  return result;
24386
24768
  }
24387
24769
  const kimiHome2 = getKimiCodeHome(this.#options.homeDirectory, environment);
24388
- const configPath = path8.join(kimiHome2, "config.toml");
24770
+ const configPath = path9.join(kimiHome2, "config.toml");
24389
24771
  let nativeConfig = null;
24390
24772
  try {
24391
- const configContent = await readFile5(configPath, "utf8");
24773
+ const configContent = await readFile6(configPath, "utf8");
24392
24774
  nativeConfig = parseKimiConfigToml(configContent);
24393
24775
  } catch {
24394
24776
  nativeConfig = null;
@@ -24499,10 +24881,10 @@ var KimiAdapter = class {
24499
24881
  onFault: (error51) => session?.handleTransportFault(error51)
24500
24882
  });
24501
24883
  const kimiHome2 = getKimiCodeHome(this.#options.homeDirectory, environment);
24502
- const configPath = path8.join(kimiHome2, "config.toml");
24884
+ const configPath = path9.join(kimiHome2, "config.toml");
24503
24885
  let nativeConfig = null;
24504
24886
  try {
24505
- const configContent = await readFile5(configPath, "utf8");
24887
+ const configContent = await readFile6(configPath, "utf8");
24506
24888
  nativeConfig = parseKimiConfigToml(configContent);
24507
24889
  } catch {
24508
24890
  nativeConfig = null;
@@ -24559,7 +24941,7 @@ var KimiAdapter = class {
24559
24941
  await transport.close().catch(() => void 0);
24560
24942
  return err2("checkpointNotFound", "Kimi Checkpoint does not belong to the source Native Session");
24561
24943
  }
24562
- if (path8.resolve(cwd) !== path8.resolve(located.state.cwd)) {
24944
+ if (path9.resolve(cwd) !== path9.resolve(located.state.cwd)) {
24563
24945
  await transport.close().catch(() => void 0);
24564
24946
  return err2("unsupported", "Kimi Code cannot fork across different working directories");
24565
24947
  }
@@ -24682,7 +25064,7 @@ var KimiAdapter = class {
24682
25064
  const located = await locateKimiSession(sourceId, historyOptions);
24683
25065
  if (!located)
24684
25066
  return err2("sessionNotFound", "Kimi source session was not found");
24685
- if (path8.resolve(input.cwd) !== path8.resolve(located.state.cwd))
25067
+ if (path9.resolve(input.cwd) !== path9.resolve(located.state.cwd))
24686
25068
  return err2("unsupported", "Kimi cannot roll back into another working directory");
24687
25069
  const source = [...this.#sessions].find((candidate) => candidate.initialState.nativeRef?.nativeSessionId === sourceId);
24688
25070
  if (source) {
@@ -24740,6 +25122,7 @@ var KimiAdapter = class {
24740
25122
  return;
24741
25123
  this.#closed = true;
24742
25124
  this.#commandCatalog = KIMI_DEFAULT_COMMAND_CATALOG;
25125
+ await this.sessionImport.close();
24743
25126
  for (const session of this.#sessions) {
24744
25127
  await session.close().catch(() => void 0);
24745
25128
  }
@@ -24748,9 +25131,9 @@ var KimiAdapter = class {
24748
25131
  };
24749
25132
 
24750
25133
  // dist/installation.js
24751
- import { open, readFile as readFile6 } from "node:fs/promises";
25134
+ import { open, readFile as readFile7 } from "node:fs/promises";
24752
25135
  import { homedir as homedir3 } from "node:os";
24753
- import { join as join2 } from "node:path";
25136
+ import { join as join3 } from "node:path";
24754
25137
  function createKimiInstallation(environment) {
24755
25138
  const executable = () => resolveKimiExecutable({ environment });
24756
25139
  const run = (args, timeout) => runInstallationCommand(executable(), args, { ...environment, KIMI_CODE_NO_AUTO_UPDATE: "1" }, timeout);
@@ -24770,8 +25153,8 @@ function createKimiInstallation(environment) {
24770
25153
  return createInstallationManager({
24771
25154
  async check() {
24772
25155
  const currentVersion = versionFromOutput(await run(["--version"]));
24773
- const home = environment.KIMI_CODE_HOME ?? join2(environment.HOME ?? homedir3(), ".kimi-code");
24774
- const region = await readFile6(join2(home, "region"), "utf8").catch(() => "");
25156
+ const home = environment.KIMI_CODE_HOME ?? join3(environment.HOME ?? homedir3(), ".kimi-code");
25157
+ const region = await readFile7(join3(home, "region"), "utf8").catch(() => "");
24775
25158
  const base = region.trim() === "global" ? "https://code.kimi.ai/kimi-code" : "https://code.kimi.com/kimi-code";
24776
25159
  const latestVersion = installationVersion(await fetchInstallationText(`${base}/latest`));
24777
25160
  const npm = await npmInstallation(executable(), ["@moonshot-ai/kimi-code"], environment);
@@ -24781,7 +25164,10 @@ function createKimiInstallation(environment) {
24781
25164
  latestVersion,
24782
25165
  updateAvailable: newerInstallationVersion(currentVersion, latestVersion),
24783
25166
  canUpdate,
24784
- ...!canUpdate ? { message: "Use the original installer to update this Kimi installation" } : {}
25167
+ ...!canUpdate ? {
25168
+ messageCode: "original-installer",
25169
+ message: "Use the original installer to update this Kimi installation"
25170
+ } : {}
24785
25171
  };
24786
25172
  },
24787
25173
  async update(state) {
@@ -24804,7 +25190,13 @@ function createHarnessAdapter(context) {
24804
25190
  return Object.assign(new KimiAdapter({
24805
25191
  ...environment[KIMI_COMMAND_ENV] ? { command: environment[KIMI_COMMAND_ENV] } : {},
24806
25192
  environment
24807
- }), { installation: createKimiInstallation(environment) });
25193
+ }), {
25194
+ installation: createKimiInstallation(environment),
25195
+ install: createHarnessInstaller(environment, {
25196
+ posix: "https://code.kimi.com/kimi-code/install.sh",
25197
+ windows: "https://code.kimi.com/kimi-code/install.ps1"
25198
+ })
25199
+ });
24808
25200
  }
24809
25201
  export {
24810
25202
  createHarnessAdapter