@codexhost/cli-linux-arm64 0.10.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +1 -1
  2. package/THIRD_PARTY_NOTICES.txt +4 -0
  3. package/app/codexhost-distribution.json +1 -1
  4. package/app/console-server.mjs +18001 -0
  5. package/app/console-web.js +27674 -0
  6. package/app/desktop-controller.mjs +452 -110
  7. package/app/host-runtime.mjs +6670 -1272
  8. package/app/plugins/antigravity/plugin.mjs +686 -305
  9. package/app/plugins/claude-code/plugin.mjs +2283 -1450
  10. package/app/plugins/codebuddy/plugin.mjs +1272 -506
  11. package/app/plugins/cursor-cli/manifest.json +1 -1
  12. package/app/plugins/cursor-cli/plugin.mjs +1295 -497
  13. package/app/plugins/deepseek-harness/plugin.mjs +4718 -4925
  14. package/app/plugins/enabled.json +2 -1
  15. package/app/plugins/grok/plugin.mjs +1012 -369
  16. package/app/plugins/hermes/plugin.mjs +18587 -22714
  17. package/app/plugins/kimi-code/plugin.mjs +1283 -355
  18. package/app/plugins/kiro-cli/plugin.mjs +840 -299
  19. package/app/plugins/omp/plugin.mjs +1045 -328
  20. package/app/plugins/opencode/plugin.mjs +5341 -1686
  21. package/app/plugins/pi/plugin.mjs +1343 -534
  22. package/app/plugins/qoder/plugin.mjs +913 -258
  23. package/app/plugins/qoder-cn/plugin.mjs +712 -49
  24. package/app/plugins/workbuddy/plugin.mjs +531 -44
  25. package/app/plugins/zcode/assets/icon.svg +8 -0
  26. package/app/plugins/zcode/manifest.json +14 -0
  27. package/app/plugins/zcode/plugin.mjs +19202 -0
  28. package/app/renderer-extension.js +5011 -1899
  29. package/bin/codexhost +0 -0
  30. package/libexec/codexhost-shim +0 -0
  31. package/libexec/codexhost-updater +0 -0
  32. package/licenses/OpenCode-v2-Client-LICENSE.txt +21 -0
  33. package/package.json +1 -1
@@ -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 readFile3 } from "node:fs/promises";
10
- import path6 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, path7) {
780
- if (!path7)
1261
+ function getElementAtPath(obj, path10) {
1262
+ if (!path10)
781
1263
  return obj;
782
- return path7.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(path7, 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(path7);
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, path7 = []) => {
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 }, [...path7, ...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 }, [...path7, ...issue2.path]);
1829
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1348
1830
  } else if (issue2.code === "invalid_element") {
1349
- processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1831
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1350
1832
  } else {
1351
- const fullpath = [...path7, ...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, path7 = []) => {
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 }, [...path7, ...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 }, [...path7, ...issue2.path]);
1866
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1385
1867
  } else if (issue2.code === "invalid_element") {
1386
- processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1868
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1387
1869
  } else {
1388
- const fullpath = [...path7, ...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 path7 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1421
- for (const seg of path7) {
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 path7 = ref.slice(1).split("/").filter(Boolean);
14114
- if (path7.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 (path7[0] === defsKey) {
14119
- const key = path7[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
  }
@@ -14579,6 +15061,56 @@ var credentialImportsParamsSchema = external_exports.object({
14579
15061
  request: credentialImportsRequestSchema
14580
15062
  }).strict();
14581
15063
 
15064
+ // ../../shared-contracts/dist/harness-display-settings.js
15065
+ var harnessDisplayEntriesSchema = external_exports.array(external_exports.strictObject({
15066
+ agent: external_exports.string().min(1).max(128),
15067
+ section: external_exports.enum(["main", "more", "auto"])
15068
+ })).max(256).refine((entries) => new Set(entries.map((entry) => entry.agent)).size === entries.length, "Duplicate Harness IDs");
15069
+ var harnessDisplaySettingsSchema = external_exports.strictObject({
15070
+ entries: harnessDisplayEntriesSchema.nullable()
15071
+ });
15072
+ var harnessDisplayGetSchema = external_exports.strictObject({});
15073
+ var harnessDisplaySetSchema = external_exports.strictObject({
15074
+ entries: harnessDisplayEntriesSchema,
15075
+ /** Import legacy Desktop preferences only if no shared settings exist yet. */
15076
+ initializeOnly: external_exports.boolean().optional()
15077
+ });
15078
+
15079
+ // ../../shared-contracts/dist/console.js
15080
+ var consoleAnnouncementSchema = external_exports.strictObject({
15081
+ title: external_exports.string().trim().min(1).max(200),
15082
+ type: external_exports.enum(["info", "warning", "danger"]),
15083
+ body: external_exports.string().trim().min(1).max(16 * 1024)
15084
+ });
15085
+ var consoleOpenParamsSchema = external_exports.strictObject({});
15086
+ var consoleOpenResultSchema = external_exports.strictObject({
15087
+ /** The console address. */
15088
+ url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
15089
+ });
15090
+ var CONSOLE_HOST_METHODS = Object.freeze([
15091
+ "codexhost/harness/plugins/list",
15092
+ "codexhost/harness/display-settings/get",
15093
+ "codexhost/harness/display-settings/set",
15094
+ "codexhost/harness/inspect",
15095
+ "codexhost/harness/installation",
15096
+ "codexhost/harness/launch-settings/get",
15097
+ "codexhost/harness/launch-settings/set",
15098
+ "codexhost/harness/web-ui/open",
15099
+ "codexhost/harness/accounts/sources",
15100
+ "codexhost/harness/accounts/list",
15101
+ "codexhost/harness/accounts/inspect",
15102
+ "codexhost/harness/credential-imports",
15103
+ "codexhost/harness/session-import/sources",
15104
+ "codexhost/harness/session-import/list",
15105
+ "codexhost/harness/session-import/import",
15106
+ "codexhost/account/list",
15107
+ "codexhost/account/refresh",
15108
+ "codexhost/account/usage/inspect",
15109
+ "codexhost/update/check",
15110
+ "codexhost/update/start",
15111
+ "codexhost/update/status"
15112
+ ]);
15113
+
14582
15114
  // ../../shared-contracts/dist/version.js
14583
15115
  var WORKSPACE_CONTRACT_VERSION = 1;
14584
15116
 
@@ -14632,6 +15164,12 @@ var hostTurnIdSchema = opaqueIdSchema.brand();
14632
15164
  var hostItemIdSchema = opaqueIdSchema.brand();
14633
15165
  var hostInteractionIdSchema = opaqueIdSchema.brand();
14634
15166
 
15167
+ // ../../shared-contracts/dist/manual-compaction.js
15168
+ var threadManualCompactionStartedSchema = external_exports.strictObject({
15169
+ threadId: hostThreadIdSchema,
15170
+ turnId: hostTurnIdSchema
15171
+ });
15172
+
14635
15173
  // ../../shared-contracts/dist/thread-usage.js
14636
15174
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
14637
15175
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
@@ -14692,6 +15230,10 @@ var threadUsageSnapshotSchema = external_exports.object({
14692
15230
  var usagePercentSchema = external_exports.number().finite().min(0).max(100);
14693
15231
  var accountCreditsProductUsageSchema = external_exports.object({
14694
15232
  product: external_exports.string().min(1),
15233
+ used: external_exports.number().finite().nonnegative().optional(),
15234
+ // Zero is a real empty cap, not an absent field.
15235
+ limit: external_exports.number().finite().nonnegative().optional(),
15236
+ unit: external_exports.string().min(1).max(32).optional(),
14695
15237
  usagePercent: usagePercentSchema,
14696
15238
  resetsAt: external_exports.string().min(1).optional()
14697
15239
  }).strict();
@@ -14701,6 +15243,10 @@ var accountResetCreditsSchema = external_exports.object({
14701
15243
  expiresAt: external_exports.array(external_exports.string().min(1)).min(1).max(32).optional()
14702
15244
  }).strict();
14703
15245
  var accountCreditsSnapshotSchema = external_exports.object({
15246
+ used: external_exports.number().finite().nonnegative().optional(),
15247
+ // Zero is a real empty cap, not an absent field.
15248
+ limit: external_exports.number().finite().nonnegative().optional(),
15249
+ unit: external_exports.string().min(1).max(32).optional(),
14704
15250
  /** Native label when the primary limit is scoped to a model or product group. */
14705
15251
  label: external_exports.string().min(1).optional(),
14706
15252
  usedPercent: usagePercentSchema,
@@ -14720,12 +15266,27 @@ var threadUsageInspectionSchema = external_exports.object({
14720
15266
  }).strict();
14721
15267
 
14722
15268
  // ../../shared-contracts/dist/harness-accounts.js
14723
- var harnessAccountSnapshotSchema = external_exports.object({
15269
+ var accountBalanceSnapshotSchema = external_exports.object({
15270
+ amount: external_exports.number().finite().nonnegative(),
15271
+ /** ISO 4217 code as reported by the Provider, for example `CNY`. */
15272
+ currency: external_exports.string().trim().min(1).max(8),
15273
+ /** Native label when the Harness exposes several Billing Sources. */
15274
+ label: external_exports.string().trim().min(1).max(128).optional()
15275
+ }).strict();
15276
+ var harnessAccountSnapshotObject = external_exports.object({
14724
15277
  email: external_exports.string().trim().min(1).max(320).optional(),
14725
15278
  label: external_exports.string().trim().min(1).max(256).optional(),
14726
15279
  plan: external_exports.string().trim().min(1).max(128).optional(),
14727
- credits: accountCreditsSnapshotSchema
15280
+ credits: accountCreditsSnapshotSchema.optional(),
15281
+ balance: accountBalanceSnapshotSchema.optional()
14728
15282
  }).strict();
15283
+ function requireReportedQuota(schema) {
15284
+ return schema.refine((value) => {
15285
+ const reported = value;
15286
+ return reported.credits !== void 0 || reported.balance !== void 0;
15287
+ }, { message: "Account must report either credits or a balance" });
15288
+ }
15289
+ var harnessAccountSnapshotSchema = requireReportedQuota(harnessAccountSnapshotObject);
14729
15290
  var harnessAccountIdentityShape = {
14730
15291
  harnessId: harnessIdSchema,
14731
15292
  harnessName: external_exports.string().trim().min(1).max(128)
@@ -14736,11 +15297,13 @@ var harnessAccountSourceListResultSchema = external_exports.object({ sources: ex
14736
15297
  var harnessAccountInspectParamsSchema = external_exports.object({ harnessId: harnessIdSchema, refresh: external_exports.boolean().optional() }).strict();
14737
15298
  var harnessAccountInspectResultSchema = external_exports.object({
14738
15299
  ...harnessAccountIdentityShape,
14739
- account: harnessAccountSnapshotSchema.nullable()
15300
+ account: harnessAccountSnapshotSchema.nullable(),
15301
+ /** Every Billing Source from one Harness; `account` remains the first for older clients. */
15302
+ accounts: external_exports.array(harnessAccountSnapshotSchema).max(8).optional()
14740
15303
  }).strict();
14741
15304
  var harnessAccountListParamsSchema = external_exports.object({ refresh: external_exports.boolean().optional() }).strict();
14742
15305
  var harnessAccountListResultSchema = external_exports.object({
14743
- accounts: external_exports.array(harnessAccountSnapshotSchema.extend(harnessAccountIdentityShape)).max(128)
15306
+ accounts: external_exports.array(requireReportedQuota(harnessAccountSnapshotObject.extend(harnessAccountIdentityShape))).max(128)
14744
15307
  }).strict();
14745
15308
 
14746
15309
  // ../../shared-contracts/dist/json-value.js
@@ -14878,6 +15441,8 @@ var harnessModelSchema = external_exports.object({
14878
15441
  ref: harnessModelRefSchema,
14879
15442
  label: nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH),
14880
15443
  resolvedModelLabel: harnessResolvedModelLabelSchema.optional(),
15444
+ /** Optional opaque selection for this same Model with priority processing enabled. */
15445
+ fastModel: harnessModelRefSchema.optional(),
14881
15446
  supportedThinkingOptionIds: external_exports.array(harnessThinkingOptionIdSchema).optional()
14882
15447
  }).strict();
14883
15448
  var harnessThinkingOptionsSchema = external_exports.array(harnessThinkingOptionSchema).superRefine((options, context) => {
@@ -14910,6 +15475,16 @@ var harnessModelCatalogSchema = external_exports.object({
14910
15475
  });
14911
15476
  }
14912
15477
  refs.add(model.ref.id);
15478
+ if (model.fastModel) {
15479
+ if (refs.has(model.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model.fastModel?.id)) {
15480
+ context.addIssue({
15481
+ code: "custom",
15482
+ message: "Fast Model refs must be distinct and unique",
15483
+ path: ["models", index, "fastModel"]
15484
+ });
15485
+ }
15486
+ refs.add(model.fastModel.id);
15487
+ }
14913
15488
  const supportedThinkingIds = /* @__PURE__ */ new Set();
14914
15489
  for (const [optionIndex, optionId] of (model.supportedThinkingOptionIds ?? []).entries()) {
14915
15490
  if (supportedThinkingIds.has(optionId)) {
@@ -15029,11 +15604,13 @@ var threadThinkingSelectParamsSchema = external_exports.object({
15029
15604
  thinkingOptionId: harnessThinkingOptionIdSchema
15030
15605
  }).strict();
15031
15606
  var threadInspectionParamsSchema = external_exports.object({
15032
- threadId: hostThreadIdSchema
15607
+ threadId: hostThreadIdSchema,
15608
+ includeReferenceCapability: external_exports.boolean().optional()
15033
15609
  }).strict();
15034
15610
  var codexThreadInspectionSchema = external_exports.object({
15035
15611
  owner: external_exports.literal("codex"),
15036
- locked: external_exports.literal(true)
15612
+ locked: external_exports.literal(true),
15613
+ supportsThreadReferences: external_exports.literal(true).optional()
15037
15614
  }).strict();
15038
15615
  var externalThreadInspectionSchema = external_exports.object({
15039
15616
  owner: external_exports.literal("external"),
@@ -15159,6 +15736,22 @@ var harnessLaunchSettingsSchema = external_exports.object({
15159
15736
  restartRequired: external_exports.boolean()
15160
15737
  }).strict();
15161
15738
 
15739
+ // ../../shared-contracts/dist/harness-installation.js
15740
+ var harnessInstallationParamsSchema = external_exports.object({
15741
+ harnessId: harnessIdSchema,
15742
+ action: external_exports.enum(["check", "update", "install"])
15743
+ }).strict();
15744
+ var harnessInstallationStateSchema = external_exports.object({
15745
+ currentVersion: external_exports.string().min(1).max(128),
15746
+ latestVersion: external_exports.string().min(1).max(128),
15747
+ updateAvailable: external_exports.boolean(),
15748
+ canUpdate: external_exports.boolean(),
15749
+ // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15750
+ message: external_exports.string().max(2048).optional(),
15751
+ messageCode: external_exports.string().min(1).max(128).optional(),
15752
+ latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15753
+ }).strict();
15754
+
15162
15755
  // ../../shared-contracts/dist/codex-accounts.js
15163
15756
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
15164
15757
  var nonBlankTextSchema3 = external_exports.string().trim().min(1);
@@ -15458,6 +16051,38 @@ var updateStatusResultSchema = external_exports.strictObject({
15458
16051
  status: updateStatusSchema.nullable()
15459
16052
  });
15460
16053
 
16054
+ // ../../shared-contracts/dist/remote-runtime.js
16055
+ var remoteUpdatePhaseSchema = external_exports.enum([
16056
+ "idle",
16057
+ "installing",
16058
+ "restarting",
16059
+ "succeeded",
16060
+ "failed"
16061
+ ]);
16062
+ var runtimeStatusSchema = external_exports.object({
16063
+ runningVersion: external_exports.string().nullable(),
16064
+ installedVersion: external_exports.string().nullable(),
16065
+ restartRequired: external_exports.boolean(),
16066
+ remote: external_exports.boolean(),
16067
+ updateSupported: external_exports.boolean(),
16068
+ update: external_exports.object({
16069
+ phase: remoteUpdatePhaseSchema,
16070
+ targetVersion: external_exports.string().nullable(),
16071
+ error: external_exports.string().nullable()
16072
+ })
16073
+ });
16074
+ var remoteUpdateParamsSchema = external_exports.object({
16075
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
16076
+ }).strict();
16077
+ var remoteSshSetupParamsSchema = external_exports.object({
16078
+ hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
16079
+ port: external_exports.number().int().min(1).max(65535).nullable(),
16080
+ identity: external_exports.string().max(4096).nullable(),
16081
+ action: external_exports.enum(["inspect", "install", "update", "repair"]),
16082
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
16083
+ }).strict();
16084
+ var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
16085
+
15461
16086
  // ../../shared-contracts/dist/index.js
15462
16087
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15463
16088
 
@@ -19758,294 +20383,67 @@ var ClientSideConnection = class {
19758
20383
  extMethod(method, params) {
19759
20384
  return this.request(method, params);
19760
20385
  }
19761
- /**
19762
- * Extension notification.
19763
- *
19764
- * @deprecated Use {@link notify}.
19765
- */
19766
- extNotification(method, params) {
19767
- return this.notify(method, params);
19768
- }
19769
- /**
19770
- * AbortSignal that aborts when the connection closes.
19771
- *
19772
- * This signal can be used to:
19773
- * - Listen for connection closure: `connection.signal.addEventListener('abort', () => {...})`
19774
- * - Check connection status synchronously: `if (connection.signal.aborted) {...}`
19775
- * - Pass to other APIs (fetch, setTimeout) for automatic cancellation
19776
- *
19777
- * The connection closes when the underlying stream ends, either normally or due to an error.
19778
- *
19779
- * @example
19780
- * ```typescript
19781
- * const connection = new ClientSideConnection(client, stream);
19782
- *
19783
- * // Listen for closure
19784
- * connection.signal.addEventListener('abort', () => {
19785
- * console.log('Connection closed - performing cleanup');
19786
- * });
19787
- *
19788
- * // Check status
19789
- * if (connection.signal.aborted) {
19790
- * console.log('Connection is already closed');
19791
- * }
19792
- *
19793
- * // Pass to other APIs
19794
- * fetch(url, { signal: connection.signal });
19795
- * ```
19796
- */
19797
- get signal() {
19798
- return this.connection.signal;
19799
- }
19800
- /**
19801
- * Promise that resolves when the connection closes.
19802
- *
19803
- * The connection closes when the underlying stream ends, either normally or due to an error.
19804
- * Once closed, the connection cannot send or receive any more messages.
19805
- *
19806
- * This is useful for async/await style cleanup:
19807
- *
19808
- * @example
19809
- * ```typescript
19810
- * const connection = new ClientSideConnection(client, stream);
19811
- * await connection.closed;
19812
- * console.log('Connection closed - performing cleanup');
19813
- * ```
19814
- */
19815
- get closed() {
19816
- return this.connection.closed;
19817
- }
19818
- };
19819
-
19820
- // dist/command.js
19821
- import path3 from "node:path";
19822
-
19823
- // ../../harness-discovery/dist/environment.js
19824
- import fs from "node:fs";
19825
- import path from "node:path";
19826
- function targetPath(platform) {
19827
- return platform === "win32" ? path.win32 : path.posix;
19828
- }
19829
- function environmentValue(environment, name) {
19830
- const lowered = name.toLowerCase();
19831
- for (const [key, value] of Object.entries(environment)) {
19832
- if (key.toLowerCase() === lowered)
19833
- return value;
19834
- }
19835
- return void 0;
19836
- }
19837
- function pathDelimiter(platform) {
19838
- return platform === "win32" ? ";" : ":";
19839
- }
19840
- function pathDirectories(environment, platform) {
19841
- return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
19842
- }
19843
- function executableExtensions(command, platform, environment) {
19844
- if (platform !== "win32")
19845
- return [""];
19846
- if (targetPath(platform).extname(command) !== "")
19847
- return [""];
19848
- return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
19849
- }
19850
- function isExecutableFile(filePath, platform) {
19851
- try {
19852
- fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
19853
- return fs.statSync(filePath).isFile();
19854
- } catch {
19855
- return false;
19856
- }
19857
- }
19858
- function subdirectoryNames(directory) {
19859
- try {
19860
- return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
19861
- } catch {
19862
- return [];
19863
- }
19864
- }
19865
- function newestFirst(names) {
19866
- return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
19867
- }
19868
-
19869
- // ../../harness-discovery/dist/invocation.js
19870
- import path2 from "node:path";
19871
- function commandInvocation(command, arguments_, environment, platform = process.platform) {
19872
- const extension = path2.win32.extname(command).toLowerCase();
19873
- if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
19874
- return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
19875
- }
19876
- const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
19877
- const commandLine = [command, ...arguments_].map(quote).join(" ");
19878
- return {
19879
- command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
19880
- arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
19881
- windowsVerbatimArguments: true
19882
- };
19883
- }
19884
-
19885
- // ../../harness-discovery/dist/resolve.js
19886
- import os from "node:os";
19887
-
19888
- // ../../harness-discovery/dist/version-managers.js
19889
- function versionManagerBinaryDirectories(context) {
19890
- const { platform, environment, home } = context;
19891
- const list = context.subdirectories ?? subdirectoryNames;
19892
- const pathFlavor = targetPath(platform);
19893
- const value = (name) => environmentValue(environment, name);
19894
- const directories = [];
19895
- const versioned = (root, ...tail) => {
19896
- for (const version2 of newestFirst(list(root))) {
19897
- directories.push(pathFlavor.join(root, version2, ...tail));
19898
- }
19899
- };
19900
- if (platform === "win32") {
19901
- const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
19902
- const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
19903
- versioned(pathFlavor.join(appData, "nvm"));
19904
- versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
19905
- directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
19906
- directories.push(pathFlavor.join(home, ".bun", "bin"));
19907
- const pnpmHome2 = value("PNPM_HOME");
19908
- if (pnpmHome2)
19909
- directories.push(pnpmHome2);
19910
- directories.push(pathFlavor.join(localAppData, "pnpm"));
19911
- return directories;
19912
- }
19913
- versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
19914
- const fnmRoots = [
19915
- value("FNM_DIR"),
19916
- pathFlavor.join(home, ".local", "share", "fnm"),
19917
- pathFlavor.join(home, "Library", "Application Support", "fnm")
19918
- ].filter((root) => root !== void 0);
19919
- for (const root of fnmRoots) {
19920
- versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
19921
- }
19922
- const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
19923
- versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
19924
- directories.push(pathFlavor.join(voltaHome, "bin"));
19925
- const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
19926
- versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
19927
- directories.push(pathFlavor.join(asdfHome, "shims"));
19928
- const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
19929
- versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
19930
- directories.push(pathFlavor.join(nodenvHome, "shims"));
19931
- versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
19932
- directories.push(pathFlavor.join(home, ".bun", "bin"));
19933
- const pnpmHome = value("PNPM_HOME");
19934
- if (pnpmHome)
19935
- directories.push(pnpmHome);
19936
- directories.push(pathFlavor.join(home, "Library", "pnpm"));
19937
- directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
19938
- for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
19939
- for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
19940
- directories.push(pathFlavor.join(prefix, formula, "bin"));
19941
- }
19942
- }
19943
- return directories;
19944
- }
19945
-
19946
- // ../../harness-discovery/dist/resolve.js
19947
- var VERSION_MANAGER_ROOTS = "<version-managers>";
19948
- function installRootExtensions(platform) {
19949
- return platform === "win32" ? [".exe", ".cmd"] : [""];
19950
- }
19951
- function resolveHomeDirectory(input) {
19952
- return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
19953
- }
19954
- function templateVariables(environment, platform, home) {
19955
- const pathFlavor = targetPath(platform);
19956
- return {
19957
- HOME: home,
19958
- USERPROFILE: home,
19959
- APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
19960
- LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
19961
- };
19962
- }
19963
- function joinTemplate(platform, value) {
19964
- const pathFlavor = targetPath(platform);
19965
- const segments = value.split("/");
19966
- const head = segments[0] ?? "";
19967
- const tail = segments.slice(1);
19968
- if (head === "")
19969
- return pathFlavor.join(pathFlavor.sep, ...tail);
19970
- return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
19971
- }
19972
- function expandInstallRoot(template, environment, platform, home) {
19973
- const variables = templateVariables(environment, platform, home);
19974
- let unresolved = false;
19975
- const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
19976
- const value = variables[name] ?? environmentValue(environment, name);
19977
- if (value === void 0 || value === "") {
19978
- unresolved = true;
19979
- return "";
19980
- }
19981
- return value;
19982
- });
19983
- return unresolved ? void 0 : joinTemplate(platform, substituted);
19984
- }
19985
- function installRootDirectories(spec, input, dependencies, platform, home) {
19986
- const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
19987
- const directories = [];
19988
- for (const template of templates) {
19989
- if (template === VERSION_MANAGER_ROOTS) {
19990
- directories.push(...versionManagerBinaryDirectories({
19991
- platform,
19992
- environment: input.environment,
19993
- home,
19994
- ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
19995
- }));
19996
- continue;
19997
- }
19998
- const directory = expandInstallRoot(template, input.environment, platform, home);
19999
- if (directory !== void 0)
20000
- directories.push(directory);
20001
- }
20002
- return directories;
20003
- }
20004
- function harnessCandidates(spec, input, dependencies = {}) {
20005
- const platform = input.platform ?? process.platform;
20006
- const pathFlavor = targetPath(platform);
20007
- const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
20008
- const command = configured ?? spec.command;
20009
- if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
20010
- return [{ candidate: command, source: "configured" }];
20011
- }
20012
- const candidates = [];
20013
- const extensions = executableExtensions(command, platform, input.environment);
20014
- for (const directory of pathDirectories(input.environment, platform)) {
20015
- for (const extension of extensions) {
20016
- candidates.push({
20017
- candidate: pathFlavor.join(directory, command + extension),
20018
- source: "path"
20019
- });
20020
- }
20386
+ /**
20387
+ * Extension notification.
20388
+ *
20389
+ * @deprecated Use {@link notify}.
20390
+ */
20391
+ extNotification(method, params) {
20392
+ return this.notify(method, params);
20021
20393
  }
20022
- if (configured !== void 0)
20023
- return candidates;
20024
- const home = resolveHomeDirectory(input);
20025
- for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
20026
- for (const extension of installRootExtensions(platform)) {
20027
- candidates.push({
20028
- candidate: pathFlavor.join(directory, spec.command + extension),
20029
- source: "install-root"
20030
- });
20031
- }
20394
+ /**
20395
+ * AbortSignal that aborts when the connection closes.
20396
+ *
20397
+ * This signal can be used to:
20398
+ * - Listen for connection closure: `connection.signal.addEventListener('abort', () => {...})`
20399
+ * - Check connection status synchronously: `if (connection.signal.aborted) {...}`
20400
+ * - Pass to other APIs (fetch, setTimeout) for automatic cancellation
20401
+ *
20402
+ * The connection closes when the underlying stream ends, either normally or due to an error.
20403
+ *
20404
+ * @example
20405
+ * ```typescript
20406
+ * const connection = new ClientSideConnection(client, stream);
20407
+ *
20408
+ * // Listen for closure
20409
+ * connection.signal.addEventListener('abort', () => {
20410
+ * console.log('Connection closed - performing cleanup');
20411
+ * });
20412
+ *
20413
+ * // Check status
20414
+ * if (connection.signal.aborted) {
20415
+ * console.log('Connection is already closed');
20416
+ * }
20417
+ *
20418
+ * // Pass to other APIs
20419
+ * fetch(url, { signal: connection.signal });
20420
+ * ```
20421
+ */
20422
+ get signal() {
20423
+ return this.connection.signal;
20032
20424
  }
20033
- return candidates;
20034
- }
20035
- function resolveHarnessExecutable(spec, input, dependencies = {}) {
20036
- const platform = input.platform ?? process.platform;
20037
- const isExecutable = dependencies.isExecutable ?? ((candidate) => isExecutableFile(candidate, platform));
20038
- const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
20039
- const context = { platform, isExecutable };
20040
- for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
20041
- const executable = runnable(candidate, context);
20042
- if (executable !== void 0 && isExecutable(executable))
20043
- return { executable, source };
20425
+ /**
20426
+ * Promise that resolves when the connection closes.
20427
+ *
20428
+ * The connection closes when the underlying stream ends, either normally or due to an error.
20429
+ * Once closed, the connection cannot send or receive any more messages.
20430
+ *
20431
+ * This is useful for async/await style cleanup:
20432
+ *
20433
+ * @example
20434
+ * ```typescript
20435
+ * const connection = new ClientSideConnection(client, stream);
20436
+ * await connection.closed;
20437
+ * console.log('Connection closed - performing cleanup');
20438
+ * ```
20439
+ */
20440
+ get closed() {
20441
+ return this.connection.closed;
20044
20442
  }
20045
- return void 0;
20046
- }
20443
+ };
20047
20444
 
20048
20445
  // dist/command.js
20446
+ import path5 from "node:path";
20049
20447
  var KimiExecutableError = class extends Error {
20050
20448
  code = "KIMI_NOT_FOUND";
20051
20449
  };
@@ -20069,7 +20467,7 @@ function resolveKimiExecutable(input = {}) {
20069
20467
  });
20070
20468
  if (!resolution)
20071
20469
  throw new KimiExecutableError("Kimi Code CLI is not installed");
20072
- return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path3.resolve(resolution.executable);
20470
+ return targetPath(platform).isAbsolute(resolution.executable) ? resolution.executable : path5.resolve(resolution.executable);
20073
20471
  }
20074
20472
  function kimiInvocation(command, environment = process.env, platform = process.platform) {
20075
20473
  return commandInvocation(command, ["acp"], environment, platform);
@@ -20513,10 +20911,229 @@ var KimiAcpTransport = class {
20513
20911
  }
20514
20912
  };
20515
20913
 
20914
+ // dist/account-identity.js
20915
+ import { randomUUID } from "node:crypto";
20916
+ import { readFile as readFile2, rename, unlink, writeFile as writeFile2 } from "node:fs/promises";
20917
+ import { homedir as homedir2 } from "node:os";
20918
+ import { join as join2 } from "node:path";
20919
+ var KIMI_USAGES_ENDPOINT = "https://api.kimi.com/coding/v1/usages";
20920
+ var KIMI_OAUTH_TOKEN_ENDPOINT = "https://auth.kimi.com/api/oauth/token";
20921
+ var KIMI_CODE_CLIENT_ID = "17e5f671-d194-4dfb-9706-5516cb48c098";
20922
+ var REQUEST_TIMEOUT_MS = 8e3;
20923
+ var REFRESH_SKEW_MS = 6e4;
20924
+ var credentialSchema = external_exports.object({
20925
+ access_token: external_exports.string().min(1),
20926
+ refresh_token: external_exports.string().min(1).optional(),
20927
+ expires_at: external_exports.number().optional(),
20928
+ expires_in: external_exports.number().optional(),
20929
+ scope: external_exports.string().optional(),
20930
+ token_type: external_exports.string().optional()
20931
+ });
20932
+ var refreshResponseSchema = external_exports.object({
20933
+ access_token: external_exports.string().min(1),
20934
+ refresh_token: external_exports.string().min(1).optional(),
20935
+ expires_in: external_exports.number().positive().optional(),
20936
+ scope: external_exports.string().optional(),
20937
+ token_type: external_exports.string().optional()
20938
+ });
20939
+ function kimiHome(environment) {
20940
+ return environment.KIMI_CODE_HOME ?? join2(environment.HOME ?? homedir2(), ".kimi-code");
20941
+ }
20942
+ function credentialPath(environment) {
20943
+ return join2(kimiHome(environment), "credentials", "kimi-code.json");
20944
+ }
20945
+ function oauthTokenUrl(environment) {
20946
+ const host = environment.KIMI_CODE_OAUTH_HOST ?? environment.KIMI_OAUTH_HOST;
20947
+ return host ? `${host.replace(/\/$/u, "")}/api/oauth/token` : KIMI_OAUTH_TOKEN_ENDPOINT;
20948
+ }
20949
+ function isRecord3(value) {
20950
+ return typeof value === "object" && value !== null && !Array.isArray(value);
20951
+ }
20952
+ function quantity(value) {
20953
+ if (typeof value === "number" && Number.isFinite(value))
20954
+ return value;
20955
+ if (typeof value === "string" && value.trim()) {
20956
+ const parsed = Number(value);
20957
+ if (Number.isFinite(parsed))
20958
+ return parsed;
20959
+ }
20960
+ return void 0;
20961
+ }
20962
+ function isFiveHourWindow(window) {
20963
+ if (!isRecord3(window))
20964
+ return false;
20965
+ const duration3 = quantity(window.duration);
20966
+ const unit = String(window.timeUnit ?? "").toLowerCase();
20967
+ return duration3 === 300 && unit.includes("minute");
20968
+ }
20969
+ function usageShare(detail) {
20970
+ if (!isRecord3(detail))
20971
+ return void 0;
20972
+ const limit = quantity(detail.limit);
20973
+ const remaining = quantity(detail.remaining);
20974
+ const used = quantity(detail.used) ?? (limit !== void 0 && remaining !== void 0 ? Math.max(0, limit - remaining) : void 0);
20975
+ if (limit === void 0 || limit <= 0 || used === void 0 || used < 0)
20976
+ return void 0;
20977
+ const resetsAt = typeof detail.resetTime === "string" && detail.resetTime ? detail.resetTime : void 0;
20978
+ return { usedPercent: Math.min(100, used / limit * 100), ...resetsAt ? { resetsAt } : {} };
20979
+ }
20980
+ function membershipPlan(user) {
20981
+ if (!isRecord3(user) || !isRecord3(user.membership) || typeof user.membership.level !== "string")
20982
+ return void 0;
20983
+ return user.membership.level.replace(/^LEVEL_/u, "").trim() || void 0;
20984
+ }
20985
+ function nickname(user) {
20986
+ if (!isRecord3(user) || typeof user.nickname !== "string")
20987
+ return void 0;
20988
+ return user.nickname.trim() || void 0;
20989
+ }
20990
+ function expiresAtMs(expiresAt) {
20991
+ if (expiresAt === void 0 || !Number.isFinite(expiresAt))
20992
+ return void 0;
20993
+ return expiresAt < 1e12 ? expiresAt * 1e3 : expiresAt;
20994
+ }
20995
+ function accessTokenFresh(credentials, now) {
20996
+ const expires = expiresAtMs(credentials.expires_at);
20997
+ return expires === void 0 || expires - REFRESH_SKEW_MS > now;
20998
+ }
20999
+ function projectKimiUsages(payload) {
21000
+ if (!isRecord3(payload))
21001
+ return null;
21002
+ const weekly = usageShare(payload.usage);
21003
+ if (!weekly)
21004
+ return null;
21005
+ const productUsage = (Array.isArray(payload.limits) ? payload.limits : []).flatMap((entry) => {
21006
+ if (!isRecord3(entry))
21007
+ return [];
21008
+ const share = usageShare(entry.detail);
21009
+ if (!share || !isFiveHourWindow(entry.window))
21010
+ return [];
21011
+ return [
21012
+ {
21013
+ product: "Kimi Code · 5-hour window",
21014
+ usagePercent: share.usedPercent,
21015
+ ...share.resetsAt ? { resetsAt: share.resetsAt } : {}
21016
+ }
21017
+ ];
21018
+ });
21019
+ const credits = {
21020
+ usedPercent: weekly.usedPercent,
21021
+ periodType: "weekly",
21022
+ ...weekly.resetsAt ? { resetsAt: weekly.resetsAt } : {},
21023
+ ...productUsage.length ? { productUsage } : {}
21024
+ };
21025
+ const plan = membershipPlan(payload.user);
21026
+ const label = nickname(payload.user);
21027
+ const parsed = harnessAccountSnapshotSchema.safeParse({
21028
+ label: label || "Kimi Code",
21029
+ ...plan ? { plan } : {},
21030
+ credits
21031
+ });
21032
+ return parsed.success ? parsed.data : null;
21033
+ }
21034
+ async function readNativeCredentials(filePath, readAuthFile) {
21035
+ try {
21036
+ const raw = JSON.parse(await readAuthFile(filePath));
21037
+ if (!isRecord3(raw))
21038
+ return void 0;
21039
+ const parsed = credentialSchema.safeParse(raw);
21040
+ return parsed.success ? { raw, credentials: parsed.data } : void 0;
21041
+ } catch {
21042
+ return void 0;
21043
+ }
21044
+ }
21045
+ async function defaultWriteAuthFile(filePath, contents) {
21046
+ const temporary = `${filePath}.${randomUUID()}.tmp`;
21047
+ try {
21048
+ await writeFile2(temporary, contents, { encoding: "utf8", mode: 384, flag: "wx" });
21049
+ await rename(temporary, filePath);
21050
+ } finally {
21051
+ await unlink(temporary).catch(() => void 0);
21052
+ }
21053
+ }
21054
+ async function refreshNativeCredentials(environment, stored, filePath, fetchImpl, writeAuthFile, signal, now) {
21055
+ const refreshToken = stored.credentials.refresh_token;
21056
+ if (!refreshToken)
21057
+ return void 0;
21058
+ const response = await fetchImpl(oauthTokenUrl(environment), {
21059
+ method: "POST",
21060
+ headers: { Accept: "application/json", "Content-Type": "application/x-www-form-urlencoded" },
21061
+ body: new URLSearchParams({
21062
+ client_id: KIMI_CODE_CLIENT_ID,
21063
+ grant_type: "refresh_token",
21064
+ refresh_token: refreshToken
21065
+ }),
21066
+ signal
21067
+ });
21068
+ if (!response.ok)
21069
+ return void 0;
21070
+ const parsed = refreshResponseSchema.safeParse(await response.json());
21071
+ if (!parsed.success)
21072
+ return void 0;
21073
+ const expiresIn = parsed.data.expires_in ?? stored.credentials.expires_in ?? 900;
21074
+ const next = {
21075
+ ...stored.raw,
21076
+ access_token: parsed.data.access_token,
21077
+ refresh_token: parsed.data.refresh_token ?? refreshToken,
21078
+ expires_in: expiresIn,
21079
+ expires_at: now / 1e3 + expiresIn,
21080
+ ...parsed.data.scope ? { scope: parsed.data.scope } : {},
21081
+ ...parsed.data.token_type ? { token_type: parsed.data.token_type } : {}
21082
+ };
21083
+ await writeAuthFile(filePath, `${JSON.stringify(next, void 0, 2)}
21084
+ `).catch(() => void 0);
21085
+ stored.raw = next;
21086
+ stored.credentials = {
21087
+ ...stored.credentials,
21088
+ access_token: parsed.data.access_token,
21089
+ refresh_token: parsed.data.refresh_token ?? refreshToken,
21090
+ expires_in: expiresIn,
21091
+ expires_at: now / 1e3 + expiresIn
21092
+ };
21093
+ return parsed.data.access_token;
21094
+ }
21095
+ async function fetchKimiAccount(input = {}) {
21096
+ try {
21097
+ const environment = input.environment ?? process.env;
21098
+ const fromEnv = environment.KIMI_CODE_API_KEY?.trim() || environment.KIMI_API_KEY?.trim();
21099
+ const readAuthFile = input.readAuthFile ?? ((filePath2) => readFile2(filePath2, "utf8"));
21100
+ const writeAuthFile = input.writeAuthFile ?? defaultWriteAuthFile;
21101
+ const fetchImpl = input.fetch ?? fetch;
21102
+ const requestSignal = () => input.signal ? AbortSignal.any([input.signal, AbortSignal.timeout(REQUEST_TIMEOUT_MS)]) : AbortSignal.timeout(REQUEST_TIMEOUT_MS);
21103
+ const now = input.now ?? Date.now();
21104
+ const filePath = credentialPath(environment);
21105
+ const stored = fromEnv ? void 0 : await readNativeCredentials(filePath, readAuthFile);
21106
+ let token = fromEnv ?? stored?.credentials.access_token;
21107
+ if (!token)
21108
+ return null;
21109
+ if (stored && !accessTokenFresh(stored.credentials, now)) {
21110
+ token = await refreshNativeCredentials(environment, stored, filePath, fetchImpl, writeAuthFile, requestSignal(), now) ?? token;
21111
+ }
21112
+ const requestUsages = (accessToken) => fetchImpl(KIMI_USAGES_ENDPOINT, {
21113
+ method: "GET",
21114
+ headers: { Authorization: `Bearer ${accessToken}`, Accept: "application/json" },
21115
+ signal: requestSignal()
21116
+ });
21117
+ let response = await requestUsages(token);
21118
+ if (response.status === 401 && stored?.credentials.refresh_token) {
21119
+ const refreshed = await refreshNativeCredentials(environment, stored, filePath, fetchImpl, writeAuthFile, requestSignal(), now);
21120
+ if (!refreshed)
21121
+ return null;
21122
+ token = refreshed;
21123
+ response = await requestUsages(token);
21124
+ }
21125
+ if (!response.ok)
21126
+ return null;
21127
+ return projectKimiUsages(await response.json());
21128
+ } catch {
21129
+ return null;
21130
+ }
21131
+ }
21132
+
20516
21133
  // dist/history.js
20517
- import { readFile } from "node:fs/promises";
21134
+ import { readFile as readFile3 } from "node:fs/promises";
20518
21135
  import os2 from "node:os";
20519
- import path4 from "node:path";
21136
+ import path6 from "node:path";
20520
21137
 
20521
21138
  // ../../../node_modules/diff/libesm/diff/base.js
20522
21139
  var Diff = class {
@@ -20618,16 +21235,16 @@ var Diff = class {
20618
21235
  }
20619
21236
  }
20620
21237
  }
20621
- addToPath(path7, added, removed, oldPosInc, options) {
20622
- const last = path7.lastComponent;
21238
+ addToPath(path10, added, removed, oldPosInc, options) {
21239
+ const last = path10.lastComponent;
20623
21240
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
20624
21241
  return {
20625
- oldPos: path7.oldPos + oldPosInc,
21242
+ oldPos: path10.oldPos + oldPosInc,
20626
21243
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
20627
21244
  };
20628
21245
  } else {
20629
21246
  return {
20630
- oldPos: path7.oldPos + oldPosInc,
21247
+ oldPos: path10.oldPos + oldPosInc,
20631
21248
  lastComponent: { count: 1, added, removed, previousComponent: last }
20632
21249
  };
20633
21250
  }
@@ -21759,9 +22376,9 @@ function readKimiThinkingOptions(configOptions) {
21759
22376
  }
21760
22377
 
21761
22378
  // dist/projection.js
21762
- import { randomUUID } from "node:crypto";
22379
+ import { randomUUID as randomUUID2 } from "node:crypto";
21763
22380
  function projectKimiApprovalRequest(turnId, request) {
21764
- const interactionId = hostInteractionIdSchema.parse(randomUUID());
22381
+ const interactionId = hostInteractionIdSchema.parse(randomUUID2());
21765
22382
  const optionIdByActionId = /* @__PURE__ */ new Map();
21766
22383
  const actions = [];
21767
22384
  const description = readAcpToolContentText(request.toolCall.content);
@@ -21805,7 +22422,7 @@ function projectKimiApprovalRequest(turnId, request) {
21805
22422
  return { interaction, optionIdByActionId };
21806
22423
  }
21807
22424
  function projectKimiElicitationRequest(turnId, request) {
21808
- const interactionId = hostInteractionIdSchema.parse(randomUUID());
22425
+ const interactionId = hostInteractionIdSchema.parse(randomUUID2());
21809
22426
  const questions = [];
21810
22427
  const schemaProperties = {};
21811
22428
  const req = request;
@@ -21875,18 +22492,18 @@ function formatElicitationResponse(response, schemaProperties) {
21875
22492
  }
21876
22493
  return { action: "accept", content };
21877
22494
  }
21878
- function isRecord3(value) {
22495
+ function isRecord4(value) {
21879
22496
  return typeof value === "object" && value !== null && !Array.isArray(value);
21880
22497
  }
21881
22498
  function canonicalizeKimiToolName(name, kind, rawInput) {
21882
22499
  const trimmed = name?.trim();
21883
22500
  const lower = trimmed?.toLowerCase() ?? "";
21884
22501
  if (lower.startsWith("write") || lower.startsWith("writ")) {
21885
- const isEdit = isRecord3(rawInput) && ("old_string" in rawInput || "oldText" in rawInput || "old" in rawInput);
22502
+ const isEdit = isRecord4(rawInput) && ("old_string" in rawInput || "oldText" in rawInput || "old" in rawInput);
21886
22503
  return isEdit ? "Edit" : "Write";
21887
22504
  }
21888
22505
  if (kind === "edit" || lower.startsWith("edit")) {
21889
- const isWrite = isRecord3(rawInput) && ("content" in rawInput || "text" in rawInput) && !("old_string" in rawInput || "oldText" in rawInput || "old" in rawInput);
22506
+ const isWrite = isRecord4(rawInput) && ("content" in rawInput || "text" in rawInput) && !("old_string" in rawInput || "oldText" in rawInput || "old" in rawInput);
21890
22507
  return isWrite ? "Write" : "Edit";
21891
22508
  }
21892
22509
  if (kind === "execute" || lower.startsWith("bash") || lower.startsWith("shell") || lower.startsWith("run")) {
@@ -22095,14 +22712,14 @@ function createKimiNativeCheckpointRef(sessionId, turnId) {
22095
22712
  });
22096
22713
  }
22097
22714
  function getKimiCodeHome(homeDirectory, environment = process.env) {
22098
- return environment.KIMI_CODE_HOME || (homeDirectory ? path4.join(homeDirectory, ".kimi-code") : path4.join(os2.homedir(), ".kimi-code"));
22715
+ return environment.KIMI_CODE_HOME || (homeDirectory ? path6.join(homeDirectory, ".kimi-code") : path6.join(os2.homedir(), ".kimi-code"));
22099
22716
  }
22100
22717
  async function locateKimiSession(sessionId, options = {}) {
22101
- const kimiHome = options.kimiCodeHome || getKimiCodeHome(options.homeDirectory);
22102
- const indexFile = path4.join(kimiHome, "session_index.jsonl");
22718
+ const kimiHome2 = options.kimiCodeHome || getKimiCodeHome(options.homeDirectory);
22719
+ const indexFile = path6.join(kimiHome2, "session_index.jsonl");
22103
22720
  let content;
22104
22721
  try {
22105
- content = await readFile(indexFile, "utf8");
22722
+ content = await readFile3(indexFile, "utf8");
22106
22723
  } catch {
22107
22724
  return null;
22108
22725
  }
@@ -22123,15 +22740,15 @@ async function locateKimiSession(sessionId, options = {}) {
22123
22740
  if (!targetEntry || targetEntry.deleted || !targetEntry.sessionDir) {
22124
22741
  return null;
22125
22742
  }
22126
- const sessionDir = path4.resolve(targetEntry.sessionDir);
22127
- const normalizedKimiHome = path4.resolve(kimiHome);
22128
- const relativeToHome = path4.relative(normalizedKimiHome, sessionDir);
22129
- if (relativeToHome.startsWith("..") || path4.isAbsolute(relativeToHome)) {
22743
+ const sessionDir = path6.resolve(targetEntry.sessionDir);
22744
+ const normalizedKimiHome = path6.resolve(kimiHome2);
22745
+ const relativeToHome = path6.relative(normalizedKimiHome, sessionDir);
22746
+ if (relativeToHome.startsWith("..") || path6.isAbsolute(relativeToHome)) {
22130
22747
  throw new Error(`Session directory ${sessionDir} is outside KIMI_CODE_HOME`);
22131
22748
  }
22132
22749
  let state;
22133
22750
  try {
22134
- const stateContent = await readFile(path4.join(sessionDir, "state.json"), "utf8");
22751
+ const stateContent = await readFile3(path6.join(sessionDir, "state.json"), "utf8");
22135
22752
  state = JSON.parse(stateContent);
22136
22753
  } catch {
22137
22754
  return null;
@@ -22139,7 +22756,7 @@ async function locateKimiSession(sessionId, options = {}) {
22139
22756
  if (state.id !== sessionId) {
22140
22757
  throw new Error(`State JSON session ID mismatch: expected ${sessionId}, found ${state.id}`);
22141
22758
  }
22142
- const mainHomeDir = state.agents?.main?.homedir ? path4.resolve(state.agents.main.homedir) : path4.join(sessionDir, "agents", "main");
22759
+ const mainHomeDir = state.agents?.main?.homedir ? path6.resolve(state.agents.main.homedir) : path6.join(sessionDir, "agents", "main");
22143
22760
  return { sessionDir, mainHomeDir, state };
22144
22761
  }
22145
22762
  async function parseKimiWireLog(wireContent, sessionId, mainHomeDir) {
@@ -22432,14 +23049,14 @@ async function parseKimiWireLog(wireContent, sessionId, mainHomeDir) {
22432
23049
  let newContent = "";
22433
23050
  if (tracked?.key) {
22434
23051
  try {
22435
- oldContent = await readFile(path4.join(mainHomeDir, tracked.key), "utf8");
23052
+ oldContent = await readFile3(path6.join(mainHomeDir, tracked.key), "utf8");
22436
23053
  } catch {
22437
23054
  oldContent = "";
22438
23055
  }
22439
23056
  }
22440
23057
  if (checkpoint?.key) {
22441
23058
  try {
22442
- newContent = await readFile(path4.join(mainHomeDir, checkpoint.key), "utf8");
23059
+ newContent = await readFile3(path6.join(mainHomeDir, checkpoint.key), "utf8");
22443
23060
  } catch {
22444
23061
  newContent = "";
22445
23062
  }
@@ -22512,10 +23129,10 @@ async function readKimiSessionSnapshot(sessionId, options = {}) {
22512
23129
  if (!located) {
22513
23130
  throw new Error(`Kimi native session not found: ${sessionId}`);
22514
23131
  }
22515
- const wirePath = path4.join(located.mainHomeDir, "wire.jsonl");
23132
+ const wirePath = path6.join(located.mainHomeDir, "wire.jsonl");
22516
23133
  let wireContent = "";
22517
23134
  try {
22518
- wireContent = await readFile(wirePath, "utf8");
23135
+ wireContent = await readFile3(wirePath, "utf8");
22519
23136
  } catch (error51) {
22520
23137
  throw new Error(`Failed to read Kimi native history ${wirePath}: ${error51 instanceof Error ? error51.message : String(error51)}`, { cause: error51 });
22521
23138
  }
@@ -22572,28 +23189,268 @@ async function readKimiSessionUsage(sessionId, options = {}) {
22572
23189
  const located = await locateKimiSession(sessionId, options);
22573
23190
  if (!located)
22574
23191
  return null;
22575
- const wirePath = path4.join(located.mainHomeDir, "wire.jsonl");
23192
+ const wirePath = path6.join(located.mainHomeDir, "wire.jsonl");
22576
23193
  try {
22577
- const wireContent = await readFile(wirePath, "utf8");
23194
+ const wireContent = await readFile3(wirePath, "utf8");
22578
23195
  return extractKimiUsageFromWireLog(wireContent, options.contextWindowTokens);
22579
23196
  } catch {
22580
23197
  return null;
22581
23198
  }
22582
23199
  }
22583
23200
 
23201
+ // dist/session-import.js
23202
+ import { readFile as readFile4, stat } from "node:fs/promises";
23203
+ import path7 from "node:path";
23204
+
23205
+ // ../../harness-adapter/dist/session-import.js
23206
+ import { lstat } from "node:fs/promises";
23207
+ var SessionImportChangedError = class extends Error {
23208
+ constructor(message = "Native Session changed during discovery; refresh and retry") {
23209
+ super(message);
23210
+ this.name = "SessionImportChangedError";
23211
+ }
23212
+ };
23213
+ function isMissingFileError(error51) {
23214
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT";
23215
+ }
23216
+ function sameFileFingerprint(left, right) {
23217
+ 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;
23218
+ }
23219
+ var STORAGE_ACCESS_ERRORS = /* @__PURE__ */ new Set(["EACCES", "EPERM", "EIO", "EMFILE", "ENFILE"]);
23220
+ function isStorageAccessError(error51) {
23221
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && typeof error51.code === "string" && STORAGE_ACCESS_ERRORS.has(error51.code);
23222
+ }
23223
+ async function optionalLstat(file2) {
23224
+ try {
23225
+ return await lstat(file2);
23226
+ } catch (error51) {
23227
+ if (isMissingFileError(error51))
23228
+ return null;
23229
+ throw error51;
23230
+ }
23231
+ }
23232
+ async function readStableFiles(files, read) {
23233
+ const before = await Promise.all(files.map(optionalLstat));
23234
+ const value = await read(before);
23235
+ const after = await Promise.all(files.map(optionalLstat));
23236
+ if (before.some((info, index) => !sameFileFingerprint(info, after[index] ?? null)))
23237
+ throw new SessionImportChangedError();
23238
+ return value;
23239
+ }
23240
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
23241
+ if (typeof value !== "string")
23242
+ return null;
23243
+ const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
23244
+ if (!normalized)
23245
+ return null;
23246
+ if (normalized.length <= maxLength)
23247
+ return normalized;
23248
+ const characters = [...normalized];
23249
+ if (characters.length <= maxLength)
23250
+ return normalized;
23251
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
23252
+ }
23253
+ function sessionImportCandidate(input) {
23254
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
23255
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
23256
+ nativeSessionId: input.nativeSessionId,
23257
+ cwd: input.cwd,
23258
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
23259
+ updatedAt: Math.floor(time3),
23260
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
23261
+ running: typeof input.running === "boolean" ? input.running : null
23262
+ });
23263
+ return parsed.success ? parsed.data : null;
23264
+ }
23265
+ var SessionImportScope = class {
23266
+ #abort = new AbortController();
23267
+ #options;
23268
+ #pending = /* @__PURE__ */ new Set();
23269
+ constructor(options) {
23270
+ this.#options = options;
23271
+ }
23272
+ #closed() {
23273
+ return {
23274
+ ok: false,
23275
+ error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
23276
+ };
23277
+ }
23278
+ read(operation) {
23279
+ const signal = this.#abort.signal;
23280
+ if (signal.aborted)
23281
+ return Promise.resolve(this.#closed());
23282
+ let started;
23283
+ try {
23284
+ started = operation(signal);
23285
+ } catch (error51) {
23286
+ started = Promise.reject(error51 instanceof Error ? error51 : new Error("Session read failed"));
23287
+ }
23288
+ const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
23289
+ ok: false,
23290
+ error: {
23291
+ code: "unavailable",
23292
+ message: this.#options.unavailableMessage,
23293
+ retryable: true
23294
+ }
23295
+ }).finally(() => this.#pending.delete(request));
23296
+ this.#pending.add(request);
23297
+ return request;
23298
+ }
23299
+ /** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
23300
+ async resolve(operation) {
23301
+ const result = await this.read(operation);
23302
+ if (!result.ok)
23303
+ return result;
23304
+ return result.value ? { ok: true, value: result.value } : {
23305
+ ok: false,
23306
+ error: {
23307
+ code: "sessionNotFound",
23308
+ message: this.#options.notFoundMessage,
23309
+ retryable: false
23310
+ }
23311
+ };
23312
+ }
23313
+ /** Idempotent. Resolves after every started read has settled. */
23314
+ async close() {
23315
+ this.#abort.abort();
23316
+ await Promise.allSettled(this.#pending);
23317
+ }
23318
+ };
23319
+
23320
+ // dist/session-import.js
23321
+ function isRecord5(value) {
23322
+ return typeof value === "object" && value !== null && !Array.isArray(value);
23323
+ }
23324
+ var KimiSessionImport = class {
23325
+ #home;
23326
+ #scope = new SessionImportScope({
23327
+ closedMessage: "Kimi Session import is closed",
23328
+ unavailableMessage: "Kimi sessions could not be read; close native clients, check storage access and retry",
23329
+ notFoundMessage: "Kimi Session is no longer importable"
23330
+ });
23331
+ constructor(options) {
23332
+ this.#home = getKimiCodeHome(options.homeDirectory, options.environment);
23333
+ }
23334
+ listCandidates() {
23335
+ return this.#scope.read(async (signal) => {
23336
+ const candidates = [];
23337
+ for (const nativeSessionId of await this.#indexedSessions(signal)) {
23338
+ try {
23339
+ const source = await this.#source(nativeSessionId, signal);
23340
+ if (source)
23341
+ candidates.push(source.candidate);
23342
+ } catch (error51) {
23343
+ if (!(error51 instanceof SessionImportChangedError))
23344
+ throw error51;
23345
+ }
23346
+ }
23347
+ return candidates;
23348
+ });
23349
+ }
23350
+ resolveCandidate(nativeSessionId) {
23351
+ return this.#scope.resolve(async (signal) => (await this.#indexedSessions(signal)).has(nativeSessionId) ? this.#source(nativeSessionId, signal) : null);
23352
+ }
23353
+ close() {
23354
+ return this.#scope.close();
23355
+ }
23356
+ /** Live identities in Kimi's index. The last record of an identity decides, as in resume. */
23357
+ async #indexedSessions(signal) {
23358
+ const live = /* @__PURE__ */ new Set();
23359
+ let content;
23360
+ try {
23361
+ content = await readFile4(path7.join(this.#home, "session_index.jsonl"), {
23362
+ encoding: "utf8",
23363
+ signal
23364
+ });
23365
+ } catch (error51) {
23366
+ signal.throwIfAborted();
23367
+ if (isMissingFileError(error51))
23368
+ return live;
23369
+ throw error51;
23370
+ }
23371
+ for (const line of content.split("\n")) {
23372
+ if (!line.trim())
23373
+ continue;
23374
+ let entry;
23375
+ try {
23376
+ entry = JSON.parse(line);
23377
+ } catch {
23378
+ continue;
23379
+ }
23380
+ if (!isRecord5(entry) || typeof entry.sessionId !== "string" || !entry.sessionId)
23381
+ continue;
23382
+ if (entry.deleted || typeof entry.sessionDir !== "string")
23383
+ live.delete(entry.sessionId);
23384
+ else
23385
+ live.add(entry.sessionId);
23386
+ }
23387
+ return live;
23388
+ }
23389
+ async #source(nativeSessionId, signal) {
23390
+ signal.throwIfAborted();
23391
+ const options = { kimiCodeHome: this.#home };
23392
+ let located;
23393
+ try {
23394
+ located = await locateKimiSession(nativeSessionId, options);
23395
+ } catch (error51) {
23396
+ if (isStorageAccessError(error51))
23397
+ throw error51;
23398
+ return null;
23399
+ }
23400
+ if (!located)
23401
+ return null;
23402
+ const { state } = located;
23403
+ const files = [
23404
+ path7.join(located.sessionDir, "state.json"),
23405
+ path7.join(located.mainHomeDir, "wire.jsonl")
23406
+ ];
23407
+ return readStableFiles(files, async ([stateInfo, wire]) => {
23408
+ if (!stateInfo?.isFile() || !wire?.isFile())
23409
+ return null;
23410
+ try {
23411
+ if (typeof state.cwd !== "string" || !path7.isAbsolute(state.cwd))
23412
+ return null;
23413
+ const cwd = path7.resolve(state.cwd);
23414
+ if (!(await stat(cwd)).isDirectory())
23415
+ return null;
23416
+ signal.throwIfAborted();
23417
+ const { turns } = await readKimiSessionSnapshot(nativeSessionId, options);
23418
+ const prompt = turns.flatMap((turn) => turn.input).find((input) => input.type === "text" && input.text.trim().length > 0);
23419
+ if (!prompt)
23420
+ return null;
23421
+ const activity = turns.flatMap((turn) => [turn.completedAtMs, turn.startedAtMs]).filter((time3) => typeof time3 === "number" && Number.isFinite(time3));
23422
+ const candidate = sessionImportCandidate({
23423
+ nativeSessionId,
23424
+ cwd,
23425
+ title: sessionImportTitle(state.title) ?? sessionImportTitle(prompt.text),
23426
+ // Wire record times are milliseconds; the state file's unit is not documented.
23427
+ updatedAt: activity.length > 0 ? Math.max(...activity) : wire.mtimeMs
23428
+ // Kimi has no cross-process activity marker: idleness cannot be established.
23429
+ });
23430
+ return candidate ? { candidate, nativeRef: createKimiNativeSessionRef(nativeSessionId, cwd) } : null;
23431
+ } catch (error51) {
23432
+ signal.throwIfAborted();
23433
+ if (isStorageAccessError(error51))
23434
+ throw error51;
23435
+ return null;
23436
+ }
23437
+ });
23438
+ }
23439
+ };
23440
+
22584
23441
  // dist/kimi-session.js
22585
23442
  import { setTimeout as delay } from "node:timers/promises";
22586
23443
 
22587
23444
  // dist/command-history.js
22588
- import { appendFile, readFile as readFile2, writeFile } from "node:fs/promises";
22589
- import path5 from "node:path";
23445
+ import { appendFile, readFile as readFile5, writeFile as writeFile3 } from "node:fs/promises";
23446
+ import path8 from "node:path";
22590
23447
  async function readKimiCommandHistory(sessionId, options) {
22591
23448
  const located = await locateKimiSession(sessionId, options);
22592
23449
  if (!located)
22593
23450
  return [];
22594
23451
  let content;
22595
23452
  try {
22596
- content = await readFile2(path5.join(located.sessionDir, "codexhost-commands.jsonl"), "utf8");
23453
+ content = await readFile5(path8.join(located.sessionDir, "codexhost-commands.jsonl"), "utf8");
22597
23454
  } catch (error51) {
22598
23455
  if (error51.code === "ENOENT")
22599
23456
  return [];
@@ -22623,7 +23480,7 @@ async function appendKimiCommandHistory(turn, options) {
22623
23480
  const located = await locateKimiSession(turn.nativeTurnRef.nativeSessionId, options);
22624
23481
  if (!located)
22625
23482
  throw new Error("Cannot persist Kimi command: native session is missing");
22626
- await appendFile(path5.join(located.sessionDir, "codexhost-commands.jsonl"), `${JSON.stringify(turn)}
23483
+ await appendFile(path8.join(located.sessionDir, "codexhost-commands.jsonl"), `${JSON.stringify(turn)}
22627
23484
  `, "utf8");
22628
23485
  }
22629
23486
  async function copyKimiCommandHistory(turns, sessionId, options) {
@@ -22637,7 +23494,7 @@ async function copyKimiCommandHistory(turns, sessionId, options) {
22637
23494
  nativeTurnRef: { ...turn.nativeTurnRef, nativeSessionId: sessionId },
22638
23495
  ...turn.checkpoint ? { checkpoint: { ...turn.checkpoint, nativeSessionId: sessionId } } : {}
22639
23496
  }));
22640
- await writeFile(path5.join(located.sessionDir, "codexhost-commands.jsonl"), copied.map((turn) => `${JSON.stringify(turn)}
23497
+ await writeFile3(path8.join(located.sessionDir, "codexhost-commands.jsonl"), copied.map((turn) => `${JSON.stringify(turn)}
22641
23498
  `).join(""), "utf8");
22642
23499
  }
22643
23500
 
@@ -23806,6 +24663,7 @@ function stateFromConfig(sessionId, cwd, configOptions) {
23806
24663
  }
23807
24664
  var KimiAdapter = class {
23808
24665
  harnessId = kimiHarnessId3;
24666
+ sessionImport;
23809
24667
  #options;
23810
24668
  #deps;
23811
24669
  #sessions = /* @__PURE__ */ new Set();
@@ -23818,6 +24676,15 @@ var KimiAdapter = class {
23818
24676
  constructor(options = {}, dependencies = {}) {
23819
24677
  this.#options = options;
23820
24678
  this.#deps = dependencies;
24679
+ this.sessionImport = new KimiSessionImport({
24680
+ environment: { ...process.env, ...options.environment },
24681
+ homeDirectory: options.homeDirectory
24682
+ });
24683
+ }
24684
+ async inspectAccount() {
24685
+ if (this.#closed)
24686
+ return null;
24687
+ return fetchKimiAccount({ environment: { ...process.env, ...this.#options.environment } });
23821
24688
  }
23822
24689
  #createTransport(options) {
23823
24690
  return this.#deps.createTransport ? this.#deps.createTransport(options) : new KimiAcpTransport(options);
@@ -23850,11 +24717,11 @@ var KimiAdapter = class {
23850
24717
  this.#inspectionCache = result;
23851
24718
  return result;
23852
24719
  }
23853
- const kimiHome = getKimiCodeHome(this.#options.homeDirectory, environment);
23854
- const configPath = path6.join(kimiHome, "config.toml");
24720
+ const kimiHome2 = getKimiCodeHome(this.#options.homeDirectory, environment);
24721
+ const configPath = path9.join(kimiHome2, "config.toml");
23855
24722
  let nativeConfig = null;
23856
24723
  try {
23857
- const configContent = await readFile3(configPath, "utf8");
24724
+ const configContent = await readFile6(configPath, "utf8");
23858
24725
  nativeConfig = parseKimiConfigToml(configContent);
23859
24726
  } catch {
23860
24727
  nativeConfig = null;
@@ -23964,11 +24831,11 @@ var KimiAdapter = class {
23964
24831
  ...this.#options.closeTimeoutMs ? { closeTimeoutMs: this.#options.closeTimeoutMs } : {},
23965
24832
  onFault: (error51) => session?.handleTransportFault(error51)
23966
24833
  });
23967
- const kimiHome = getKimiCodeHome(this.#options.homeDirectory, environment);
23968
- const configPath = path6.join(kimiHome, "config.toml");
24834
+ const kimiHome2 = getKimiCodeHome(this.#options.homeDirectory, environment);
24835
+ const configPath = path9.join(kimiHome2, "config.toml");
23969
24836
  let nativeConfig = null;
23970
24837
  try {
23971
- const configContent = await readFile3(configPath, "utf8");
24838
+ const configContent = await readFile6(configPath, "utf8");
23972
24839
  nativeConfig = parseKimiConfigToml(configContent);
23973
24840
  } catch {
23974
24841
  nativeConfig = null;
@@ -24025,7 +24892,7 @@ var KimiAdapter = class {
24025
24892
  await transport.close().catch(() => void 0);
24026
24893
  return err2("checkpointNotFound", "Kimi Checkpoint does not belong to the source Native Session");
24027
24894
  }
24028
- if (path6.resolve(cwd) !== path6.resolve(located.state.cwd)) {
24895
+ if (path9.resolve(cwd) !== path9.resolve(located.state.cwd)) {
24029
24896
  await transport.close().catch(() => void 0);
24030
24897
  return err2("unsupported", "Kimi Code cannot fork across different working directories");
24031
24898
  }
@@ -24148,7 +25015,7 @@ var KimiAdapter = class {
24148
25015
  const located = await locateKimiSession(sourceId, historyOptions);
24149
25016
  if (!located)
24150
25017
  return err2("sessionNotFound", "Kimi source session was not found");
24151
- if (path6.resolve(input.cwd) !== path6.resolve(located.state.cwd))
25018
+ if (path9.resolve(input.cwd) !== path9.resolve(located.state.cwd))
24152
25019
  return err2("unsupported", "Kimi cannot roll back into another working directory");
24153
25020
  const source = [...this.#sessions].find((candidate) => candidate.initialState.nativeRef?.nativeSessionId === sourceId);
24154
25021
  if (source) {
@@ -24206,6 +25073,7 @@ var KimiAdapter = class {
24206
25073
  return;
24207
25074
  this.#closed = true;
24208
25075
  this.#commandCatalog = KIMI_DEFAULT_COMMAND_CATALOG;
25076
+ await this.sessionImport.close();
24209
25077
  for (const session of this.#sessions) {
24210
25078
  await session.close().catch(() => void 0);
24211
25079
  }
@@ -24213,12 +25081,72 @@ var KimiAdapter = class {
24213
25081
  }
24214
25082
  };
24215
25083
 
25084
+ // dist/installation.js
25085
+ import { open, readFile as readFile7 } from "node:fs/promises";
25086
+ import { homedir as homedir3 } from "node:os";
25087
+ import { join as join3 } from "node:path";
25088
+ function createKimiInstallation(environment) {
25089
+ const executable = () => resolveKimiExecutable({ environment });
25090
+ const run = (args, timeout) => runInstallationCommand(executable(), args, { ...environment, KIMI_CODE_NO_AUTO_UPDATE: "1" }, timeout);
25091
+ const nativeUpdaterAvailable = async () => {
25092
+ const file2 = await open(executable(), "r");
25093
+ try {
25094
+ const header = Buffer.alloc(4);
25095
+ await file2.read(header, 0, 4, 0);
25096
+ const magic = header.toString("hex");
25097
+ if (!["cffaedfe", "cefaedfe", "cafebabe", "7f454c46"].includes(magic) && !magic.startsWith("4d5a"))
25098
+ return false;
25099
+ } finally {
25100
+ await file2.close();
25101
+ }
25102
+ return /--manual/.test(await run(["__update_download", "--help"]));
25103
+ };
25104
+ return createInstallationManager({
25105
+ async check() {
25106
+ const currentVersion = versionFromOutput(await run(["--version"]));
25107
+ const home = environment.KIMI_CODE_HOME ?? join3(environment.HOME ?? homedir3(), ".kimi-code");
25108
+ const region = await readFile7(join3(home, "region"), "utf8").catch(() => "");
25109
+ const base = region.trim() === "global" ? "https://code.kimi.ai/kimi-code" : "https://code.kimi.com/kimi-code";
25110
+ const latestVersion = installationVersion(await fetchInstallationText(`${base}/latest`));
25111
+ const npm = await npmInstallation(executable(), ["@moonshot-ai/kimi-code"], environment);
25112
+ const canUpdate = npm ? npm.canUpdate : await nativeUpdaterAvailable();
25113
+ return {
25114
+ currentVersion,
25115
+ latestVersion,
25116
+ updateAvailable: newerInstallationVersion(currentVersion, latestVersion),
25117
+ canUpdate,
25118
+ ...!canUpdate ? {
25119
+ messageCode: "original-installer",
25120
+ message: "Use the original installer to update this Kimi installation"
25121
+ } : {}
25122
+ };
25123
+ },
25124
+ async update(state) {
25125
+ const npm = await npmInstallation(executable(), ["@moonshot-ai/kimi-code"], environment);
25126
+ if (npm)
25127
+ await npm.update(state.latestVersion);
25128
+ else {
25129
+ if (!await nativeUpdaterAvailable())
25130
+ throw new Error("Kimi native updater is unavailable");
25131
+ await run(["__update_download", state.latestVersion, "--manual"], 3e5);
25132
+ await run(["--version"]);
25133
+ }
25134
+ }
25135
+ });
25136
+ }
25137
+
24216
25138
  // dist/plugin.js
24217
25139
  function createHarnessAdapter(context) {
24218
25140
  const environment = { ...context.environment };
24219
- return new KimiAdapter({
25141
+ return Object.assign(new KimiAdapter({
24220
25142
  ...environment[KIMI_COMMAND_ENV] ? { command: environment[KIMI_COMMAND_ENV] } : {},
24221
25143
  environment
25144
+ }), {
25145
+ installation: createKimiInstallation(environment),
25146
+ install: createHarnessInstaller(environment, {
25147
+ posix: "https://code.kimi.com/kimi-code/install.sh",
25148
+ windows: "https://code.kimi.com/kimi-code/install.ps1"
25149
+ })
24222
25150
  });
24223
25151
  }
24224
25152
  export {