@codexhost/cli-darwin-x64 0.10.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +1 -1
  2. package/THIRD_PARTY_NOTICES.txt +4 -0
  3. package/app/codexhost-distribution.json +1 -1
  4. package/app/console-server.mjs +18001 -0
  5. package/app/console-web.js +27674 -0
  6. package/app/desktop-controller.mjs +452 -110
  7. package/app/host-runtime.mjs +6670 -1272
  8. package/app/plugins/antigravity/plugin.mjs +686 -305
  9. package/app/plugins/claude-code/plugin.mjs +2283 -1450
  10. package/app/plugins/codebuddy/plugin.mjs +1272 -506
  11. package/app/plugins/cursor-cli/manifest.json +1 -1
  12. package/app/plugins/cursor-cli/plugin.mjs +1295 -497
  13. package/app/plugins/deepseek-harness/plugin.mjs +4718 -4925
  14. package/app/plugins/enabled.json +2 -1
  15. package/app/plugins/grok/plugin.mjs +1012 -369
  16. package/app/plugins/hermes/plugin.mjs +18587 -22714
  17. package/app/plugins/kimi-code/plugin.mjs +1283 -355
  18. package/app/plugins/kiro-cli/plugin.mjs +840 -299
  19. package/app/plugins/omp/plugin.mjs +1045 -328
  20. package/app/plugins/opencode/plugin.mjs +5341 -1686
  21. package/app/plugins/pi/plugin.mjs +1343 -534
  22. package/app/plugins/qoder/plugin.mjs +913 -258
  23. package/app/plugins/qoder-cn/plugin.mjs +712 -49
  24. package/app/plugins/workbuddy/plugin.mjs +531 -44
  25. package/app/plugins/zcode/assets/icon.svg +8 -0
  26. package/app/plugins/zcode/manifest.json +14 -0
  27. package/app/plugins/zcode/plugin.mjs +19202 -0
  28. package/app/renderer-extension.js +5011 -1899
  29. package/bin/codexhost +0 -0
  30. package/libexec/codexhost-shim +0 -0
  31. package/libexec/codexhost-updater +0 -0
  32. package/licenses/OpenCode-v2-Client-LICENSE.txt +21 -0
  33. package/package.json +1 -1
@@ -5,6 +5,488 @@ var __export = (target, all) => {
5
5
  __defProp(target, name, { get: all[name], enumerable: true });
6
6
  };
7
7
 
8
+ // ../../harness-discovery/dist/environment.js
9
+ import fs from "node:fs";
10
+ import path from "node:path";
11
+ function targetPath(platform) {
12
+ return platform === "win32" ? path.win32 : path.posix;
13
+ }
14
+ function environmentValue(environment, name) {
15
+ const lowered = name.toLowerCase();
16
+ for (const [key, value] of Object.entries(environment)) {
17
+ if (key.toLowerCase() === lowered)
18
+ return value;
19
+ }
20
+ return void 0;
21
+ }
22
+ function pathDelimiter(platform) {
23
+ return platform === "win32" ? ";" : ":";
24
+ }
25
+ function pathDirectories(environment, platform) {
26
+ return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
27
+ }
28
+ function executableExtensions(command, platform, environment) {
29
+ if (platform !== "win32")
30
+ return [""];
31
+ if (targetPath(platform).extname(command) !== "")
32
+ return [""];
33
+ return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
34
+ }
35
+ function isExecutableFile(filePath, platform) {
36
+ try {
37
+ fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
38
+ return fs.statSync(filePath).isFile();
39
+ } catch {
40
+ return false;
41
+ }
42
+ }
43
+ function subdirectoryNames(directory) {
44
+ try {
45
+ return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
46
+ } catch {
47
+ return [];
48
+ }
49
+ }
50
+ function newestFirst(names) {
51
+ return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
52
+ }
53
+
54
+ // ../../harness-discovery/dist/invocation.js
55
+ import path2 from "node:path";
56
+ function commandInvocation(command, arguments_, environment, platform = process.platform) {
57
+ const extension = path2.win32.extname(command).toLowerCase();
58
+ if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
59
+ return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
60
+ }
61
+ const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
62
+ const commandLine = [command, ...arguments_].map(quote).join(" ");
63
+ return {
64
+ command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
65
+ arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
66
+ windowsVerbatimArguments: true
67
+ };
68
+ }
69
+
70
+ // ../../harness-discovery/dist/node-runtime.js
71
+ import path3 from "node:path";
72
+ function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
73
+ const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
74
+ const delimiter = platform === "win32" ? ";" : ":";
75
+ const runtimeDirectory = path3.dirname(runtimeExecutable);
76
+ const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
77
+ const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
78
+ if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
79
+ directories.push(runtimeDirectory);
80
+ }
81
+ return { ...environment, [pathKey]: directories.join(delimiter) };
82
+ }
83
+
84
+ // ../../harness-discovery/dist/resolve.js
85
+ import os from "node:os";
86
+
87
+ // ../../harness-discovery/dist/version-managers.js
88
+ function versionManagerBinaryDirectories(context) {
89
+ const { platform, environment, home } = context;
90
+ const list = context.subdirectories ?? subdirectoryNames;
91
+ const pathFlavor = targetPath(platform);
92
+ const value = (name) => environmentValue(environment, name);
93
+ const directories = [];
94
+ const versioned = (root, ...tail) => {
95
+ for (const version2 of newestFirst(list(root))) {
96
+ directories.push(pathFlavor.join(root, version2, ...tail));
97
+ }
98
+ };
99
+ if (platform === "win32") {
100
+ const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
101
+ const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
102
+ versioned(pathFlavor.join(appData, "nvm"));
103
+ versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
104
+ directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
105
+ directories.push(pathFlavor.join(home, ".bun", "bin"));
106
+ const pnpmHome2 = value("PNPM_HOME");
107
+ if (pnpmHome2)
108
+ directories.push(pnpmHome2);
109
+ directories.push(pathFlavor.join(localAppData, "pnpm"));
110
+ return directories;
111
+ }
112
+ versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
113
+ const fnmRoots = [
114
+ value("FNM_DIR"),
115
+ pathFlavor.join(home, ".local", "share", "fnm"),
116
+ pathFlavor.join(home, "Library", "Application Support", "fnm")
117
+ ].filter((root) => root !== void 0);
118
+ for (const root of fnmRoots) {
119
+ versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
120
+ }
121
+ const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
122
+ versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
123
+ directories.push(pathFlavor.join(voltaHome, "bin"));
124
+ const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
125
+ versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
126
+ directories.push(pathFlavor.join(asdfHome, "shims"));
127
+ const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
128
+ versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
129
+ directories.push(pathFlavor.join(nodenvHome, "shims"));
130
+ versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
131
+ directories.push(pathFlavor.join(home, ".bun", "bin"));
132
+ const pnpmHome = value("PNPM_HOME");
133
+ if (pnpmHome)
134
+ directories.push(pnpmHome);
135
+ directories.push(pathFlavor.join(home, "Library", "pnpm"));
136
+ directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
137
+ for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
138
+ for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
139
+ directories.push(pathFlavor.join(prefix, formula, "bin"));
140
+ }
141
+ }
142
+ return directories;
143
+ }
144
+
145
+ // ../../harness-discovery/dist/resolve.js
146
+ var VERSION_MANAGER_ROOTS = "<version-managers>";
147
+ function installRootExtensions(platform) {
148
+ return platform === "win32" ? [".exe", ".cmd"] : [""];
149
+ }
150
+ function resolveHomeDirectory(input) {
151
+ return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
152
+ }
153
+ function templateVariables(environment, platform, home) {
154
+ const pathFlavor = targetPath(platform);
155
+ return {
156
+ HOME: home,
157
+ USERPROFILE: home,
158
+ APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
159
+ LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
160
+ };
161
+ }
162
+ function joinTemplate(platform, value) {
163
+ const pathFlavor = targetPath(platform);
164
+ const segments = value.split("/");
165
+ const head = segments[0] ?? "";
166
+ const tail = segments.slice(1);
167
+ if (head === "")
168
+ return pathFlavor.join(pathFlavor.sep, ...tail);
169
+ return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
170
+ }
171
+ function expandInstallRoot(template, environment, platform, home) {
172
+ const variables = templateVariables(environment, platform, home);
173
+ let unresolved = false;
174
+ const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
175
+ const value = variables[name] ?? environmentValue(environment, name);
176
+ if (value === void 0 || value === "") {
177
+ unresolved = true;
178
+ return "";
179
+ }
180
+ return value;
181
+ });
182
+ return unresolved ? void 0 : joinTemplate(platform, substituted);
183
+ }
184
+ function installRootDirectories(spec, input, dependencies, platform, home) {
185
+ const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
186
+ const directories = [];
187
+ for (const template of templates) {
188
+ if (template === VERSION_MANAGER_ROOTS) {
189
+ directories.push(...versionManagerBinaryDirectories({
190
+ platform,
191
+ environment: input.environment,
192
+ home,
193
+ ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
194
+ }));
195
+ continue;
196
+ }
197
+ const directory = expandInstallRoot(template, input.environment, platform, home);
198
+ if (directory !== void 0)
199
+ directories.push(directory);
200
+ }
201
+ return directories;
202
+ }
203
+ function harnessCandidates(spec, input, dependencies = {}) {
204
+ const platform = input.platform ?? process.platform;
205
+ const pathFlavor = targetPath(platform);
206
+ const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
207
+ const command = configured ?? spec.command;
208
+ if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
209
+ return [{ candidate: command, source: "configured" }];
210
+ }
211
+ const candidates = [];
212
+ const extensions = executableExtensions(command, platform, input.environment);
213
+ for (const directory of pathDirectories(input.environment, platform)) {
214
+ for (const extension of extensions) {
215
+ candidates.push({
216
+ candidate: pathFlavor.join(directory, command + extension),
217
+ source: "path"
218
+ });
219
+ }
220
+ }
221
+ if (configured !== void 0)
222
+ return candidates;
223
+ const home = resolveHomeDirectory(input);
224
+ for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
225
+ for (const extension of installRootExtensions(platform)) {
226
+ candidates.push({
227
+ candidate: pathFlavor.join(directory, spec.command + extension),
228
+ source: "install-root"
229
+ });
230
+ }
231
+ }
232
+ return candidates;
233
+ }
234
+ function resolveHarnessExecutable(spec, input, dependencies = {}) {
235
+ const platform = input.platform ?? process.platform;
236
+ const isExecutable = dependencies.isExecutable ?? ((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 text2 = shim.replaceAll("\\", "/").toLowerCase();
365
+ return text2.includes(`%dp0%/${target}"`) || text2.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((text2) => JSON.parse(text2)).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((text2) => JSON.parse(text2)).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
  // ../../../node_modules/zod/v4/classic/external.js
9
491
  var external_exports = {};
10
492
  __export(external_exports, {
@@ -771,10 +1253,10 @@ function mergeDefs(...defs) {
771
1253
  function cloneDef(schema) {
772
1254
  return mergeDefs(schema._zod.def);
773
1255
  }
774
- function getElementAtPath(obj, path8) {
775
- if (!path8)
1256
+ function getElementAtPath(obj, path10) {
1257
+ if (!path10)
776
1258
  return obj;
777
- return path8.reduce((acc, key) => acc?.[key], obj);
1259
+ return path10.reduce((acc, key) => acc?.[key], obj);
778
1260
  }
779
1261
  function promiseAllObject(promisesObj) {
780
1262
  const keys = Object.keys(promisesObj);
@@ -1183,11 +1665,11 @@ function explicitlyAborted(x, startIndex = 0) {
1183
1665
  }
1184
1666
  return false;
1185
1667
  }
1186
- function prefixIssues(path8, issues) {
1668
+ function prefixIssues(path10, issues) {
1187
1669
  return issues.map((iss) => {
1188
1670
  var _a3;
1189
1671
  (_a3 = iss).path ?? (_a3.path = []);
1190
- iss.path.unshift(path8);
1672
+ iss.path.unshift(path10);
1191
1673
  return iss;
1192
1674
  });
1193
1675
  }
@@ -1334,16 +1816,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1334
1816
  }
1335
1817
  function formatError(error51, mapper = (issue2) => issue2.message) {
1336
1818
  const fieldErrors = { _errors: [] };
1337
- const processError = (error52, path8 = []) => {
1819
+ const processError = (error52, path10 = []) => {
1338
1820
  for (const issue2 of error52.issues) {
1339
1821
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1340
- issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
1822
+ issue2.errors.map((issues) => processError({ issues }, [...path10, ...issue2.path]));
1341
1823
  } else if (issue2.code === "invalid_key") {
1342
- processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
1824
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1343
1825
  } else if (issue2.code === "invalid_element") {
1344
- processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
1826
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1345
1827
  } else {
1346
- const fullpath = [...path8, ...issue2.path];
1828
+ const fullpath = [...path10, ...issue2.path];
1347
1829
  if (fullpath.length === 0) {
1348
1830
  fieldErrors._errors.push(mapper(issue2));
1349
1831
  } else {
@@ -1370,17 +1852,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1370
1852
  }
1371
1853
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1372
1854
  const result = { errors: [] };
1373
- const processError = (error52, path8 = []) => {
1855
+ const processError = (error52, path10 = []) => {
1374
1856
  var _a3, _b;
1375
1857
  for (const issue2 of error52.issues) {
1376
1858
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1377
- issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
1859
+ issue2.errors.map((issues) => processError({ issues }, [...path10, ...issue2.path]));
1378
1860
  } else if (issue2.code === "invalid_key") {
1379
- processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
1861
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1380
1862
  } else if (issue2.code === "invalid_element") {
1381
- processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
1863
+ processError({ issues: issue2.issues }, [...path10, ...issue2.path]);
1382
1864
  } else {
1383
- const fullpath = [...path8, ...issue2.path];
1865
+ const fullpath = [...path10, ...issue2.path];
1384
1866
  if (fullpath.length === 0) {
1385
1867
  result.errors.push(mapper(issue2));
1386
1868
  continue;
@@ -1412,8 +1894,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
1412
1894
  }
1413
1895
  function toDotPath(_path) {
1414
1896
  const segs = [];
1415
- const path8 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1416
- for (const seg of path8) {
1897
+ const path10 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1898
+ for (const seg of path10) {
1417
1899
  if (typeof seg === "number")
1418
1900
  segs.push(`[${seg}]`);
1419
1901
  else if (typeof seg === "symbol")
@@ -14105,13 +14587,13 @@ function resolveRef(ref, ctx) {
14105
14587
  if (!ref.startsWith("#")) {
14106
14588
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14107
14589
  }
14108
- const path8 = ref.slice(1).split("/").filter(Boolean);
14109
- if (path8.length === 0) {
14590
+ const path10 = ref.slice(1).split("/").filter(Boolean);
14591
+ if (path10.length === 0) {
14110
14592
  return ctx.rootSchema;
14111
14593
  }
14112
14594
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14113
- if (path8[0] === defsKey) {
14114
- const key = path8[1];
14595
+ if (path10[0] === defsKey) {
14596
+ const key = path10[1];
14115
14597
  if (!key || !ctx.defs[key]) {
14116
14598
  throw new Error(`Reference not found: ${ref}`);
14117
14599
  }
@@ -14574,6 +15056,56 @@ var credentialImportsParamsSchema = external_exports.object({
14574
15056
  request: credentialImportsRequestSchema
14575
15057
  }).strict();
14576
15058
 
15059
+ // ../../shared-contracts/dist/harness-display-settings.js
15060
+ var harnessDisplayEntriesSchema = external_exports.array(external_exports.strictObject({
15061
+ agent: external_exports.string().min(1).max(128),
15062
+ section: external_exports.enum(["main", "more", "auto"])
15063
+ })).max(256).refine((entries) => new Set(entries.map((entry) => entry.agent)).size === entries.length, "Duplicate Harness IDs");
15064
+ var harnessDisplaySettingsSchema = external_exports.strictObject({
15065
+ entries: harnessDisplayEntriesSchema.nullable()
15066
+ });
15067
+ var harnessDisplayGetSchema = external_exports.strictObject({});
15068
+ var harnessDisplaySetSchema = external_exports.strictObject({
15069
+ entries: harnessDisplayEntriesSchema,
15070
+ /** Import legacy Desktop preferences only if no shared settings exist yet. */
15071
+ initializeOnly: external_exports.boolean().optional()
15072
+ });
15073
+
15074
+ // ../../shared-contracts/dist/console.js
15075
+ var consoleAnnouncementSchema = external_exports.strictObject({
15076
+ title: external_exports.string().trim().min(1).max(200),
15077
+ type: external_exports.enum(["info", "warning", "danger"]),
15078
+ body: external_exports.string().trim().min(1).max(16 * 1024)
15079
+ });
15080
+ var consoleOpenParamsSchema = external_exports.strictObject({});
15081
+ var consoleOpenResultSchema = external_exports.strictObject({
15082
+ /** The console address. */
15083
+ url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
15084
+ });
15085
+ var CONSOLE_HOST_METHODS = Object.freeze([
15086
+ "codexhost/harness/plugins/list",
15087
+ "codexhost/harness/display-settings/get",
15088
+ "codexhost/harness/display-settings/set",
15089
+ "codexhost/harness/inspect",
15090
+ "codexhost/harness/installation",
15091
+ "codexhost/harness/launch-settings/get",
15092
+ "codexhost/harness/launch-settings/set",
15093
+ "codexhost/harness/web-ui/open",
15094
+ "codexhost/harness/accounts/sources",
15095
+ "codexhost/harness/accounts/list",
15096
+ "codexhost/harness/accounts/inspect",
15097
+ "codexhost/harness/credential-imports",
15098
+ "codexhost/harness/session-import/sources",
15099
+ "codexhost/harness/session-import/list",
15100
+ "codexhost/harness/session-import/import",
15101
+ "codexhost/account/list",
15102
+ "codexhost/account/refresh",
15103
+ "codexhost/account/usage/inspect",
15104
+ "codexhost/update/check",
15105
+ "codexhost/update/start",
15106
+ "codexhost/update/status"
15107
+ ]);
15108
+
14577
15109
  // ../../shared-contracts/dist/version.js
14578
15110
  var WORKSPACE_CONTRACT_VERSION = 1;
14579
15111
 
@@ -14627,6 +15159,12 @@ var hostTurnIdSchema = opaqueIdSchema.brand();
14627
15159
  var hostItemIdSchema = opaqueIdSchema.brand();
14628
15160
  var hostInteractionIdSchema = opaqueIdSchema.brand();
14629
15161
 
15162
+ // ../../shared-contracts/dist/manual-compaction.js
15163
+ var threadManualCompactionStartedSchema = external_exports.strictObject({
15164
+ threadId: hostThreadIdSchema,
15165
+ turnId: hostTurnIdSchema
15166
+ });
15167
+
14630
15168
  // ../../shared-contracts/dist/thread-usage.js
14631
15169
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
14632
15170
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
@@ -14687,6 +15225,10 @@ var threadUsageSnapshotSchema = external_exports.object({
14687
15225
  var usagePercentSchema = external_exports.number().finite().min(0).max(100);
14688
15226
  var accountCreditsProductUsageSchema = external_exports.object({
14689
15227
  product: external_exports.string().min(1),
15228
+ used: external_exports.number().finite().nonnegative().optional(),
15229
+ // Zero is a real empty cap, not an absent field.
15230
+ limit: external_exports.number().finite().nonnegative().optional(),
15231
+ unit: external_exports.string().min(1).max(32).optional(),
14690
15232
  usagePercent: usagePercentSchema,
14691
15233
  resetsAt: external_exports.string().min(1).optional()
14692
15234
  }).strict();
@@ -14696,6 +15238,10 @@ var accountResetCreditsSchema = external_exports.object({
14696
15238
  expiresAt: external_exports.array(external_exports.string().min(1)).min(1).max(32).optional()
14697
15239
  }).strict();
14698
15240
  var accountCreditsSnapshotSchema = external_exports.object({
15241
+ used: external_exports.number().finite().nonnegative().optional(),
15242
+ // Zero is a real empty cap, not an absent field.
15243
+ limit: external_exports.number().finite().nonnegative().optional(),
15244
+ unit: external_exports.string().min(1).max(32).optional(),
14699
15245
  /** Native label when the primary limit is scoped to a model or product group. */
14700
15246
  label: external_exports.string().min(1).optional(),
14701
15247
  usedPercent: usagePercentSchema,
@@ -14715,12 +15261,27 @@ var threadUsageInspectionSchema = external_exports.object({
14715
15261
  }).strict();
14716
15262
 
14717
15263
  // ../../shared-contracts/dist/harness-accounts.js
14718
- var harnessAccountSnapshotSchema = external_exports.object({
15264
+ var accountBalanceSnapshotSchema = external_exports.object({
15265
+ amount: external_exports.number().finite().nonnegative(),
15266
+ /** ISO 4217 code as reported by the Provider, for example `CNY`. */
15267
+ currency: external_exports.string().trim().min(1).max(8),
15268
+ /** Native label when the Harness exposes several Billing Sources. */
15269
+ label: external_exports.string().trim().min(1).max(128).optional()
15270
+ }).strict();
15271
+ var harnessAccountSnapshotObject = external_exports.object({
14719
15272
  email: external_exports.string().trim().min(1).max(320).optional(),
14720
15273
  label: external_exports.string().trim().min(1).max(256).optional(),
14721
15274
  plan: external_exports.string().trim().min(1).max(128).optional(),
14722
- credits: accountCreditsSnapshotSchema
15275
+ credits: accountCreditsSnapshotSchema.optional(),
15276
+ balance: accountBalanceSnapshotSchema.optional()
14723
15277
  }).strict();
15278
+ function requireReportedQuota(schema) {
15279
+ return schema.refine((value) => {
15280
+ const reported = value;
15281
+ return reported.credits !== void 0 || reported.balance !== void 0;
15282
+ }, { message: "Account must report either credits or a balance" });
15283
+ }
15284
+ var harnessAccountSnapshotSchema = requireReportedQuota(harnessAccountSnapshotObject);
14724
15285
  var harnessAccountIdentityShape = {
14725
15286
  harnessId: harnessIdSchema,
14726
15287
  harnessName: external_exports.string().trim().min(1).max(128)
@@ -14731,11 +15292,13 @@ var harnessAccountSourceListResultSchema = external_exports.object({ sources: ex
14731
15292
  var harnessAccountInspectParamsSchema = external_exports.object({ harnessId: harnessIdSchema, refresh: external_exports.boolean().optional() }).strict();
14732
15293
  var harnessAccountInspectResultSchema = external_exports.object({
14733
15294
  ...harnessAccountIdentityShape,
14734
- account: harnessAccountSnapshotSchema.nullable()
15295
+ account: harnessAccountSnapshotSchema.nullable(),
15296
+ /** Every Billing Source from one Harness; `account` remains the first for older clients. */
15297
+ accounts: external_exports.array(harnessAccountSnapshotSchema).max(8).optional()
14735
15298
  }).strict();
14736
15299
  var harnessAccountListParamsSchema = external_exports.object({ refresh: external_exports.boolean().optional() }).strict();
14737
15300
  var harnessAccountListResultSchema = external_exports.object({
14738
- accounts: external_exports.array(harnessAccountSnapshotSchema.extend(harnessAccountIdentityShape)).max(128)
15301
+ accounts: external_exports.array(requireReportedQuota(harnessAccountSnapshotObject.extend(harnessAccountIdentityShape))).max(128)
14739
15302
  }).strict();
14740
15303
 
14741
15304
  // ../../shared-contracts/dist/json-value.js
@@ -14873,6 +15436,8 @@ var harnessModelSchema = external_exports.object({
14873
15436
  ref: harnessModelRefSchema,
14874
15437
  label: nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH),
14875
15438
  resolvedModelLabel: harnessResolvedModelLabelSchema.optional(),
15439
+ /** Optional opaque selection for this same Model with priority processing enabled. */
15440
+ fastModel: harnessModelRefSchema.optional(),
14876
15441
  supportedThinkingOptionIds: external_exports.array(harnessThinkingOptionIdSchema).optional()
14877
15442
  }).strict();
14878
15443
  var harnessThinkingOptionsSchema = external_exports.array(harnessThinkingOptionSchema).superRefine((options, context) => {
@@ -14905,6 +15470,16 @@ var harnessModelCatalogSchema = external_exports.object({
14905
15470
  });
14906
15471
  }
14907
15472
  refs.add(model.ref.id);
15473
+ if (model.fastModel) {
15474
+ if (refs.has(model.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model.fastModel?.id)) {
15475
+ context.addIssue({
15476
+ code: "custom",
15477
+ message: "Fast Model refs must be distinct and unique",
15478
+ path: ["models", index, "fastModel"]
15479
+ });
15480
+ }
15481
+ refs.add(model.fastModel.id);
15482
+ }
14908
15483
  const supportedThinkingIds = /* @__PURE__ */ new Set();
14909
15484
  for (const [optionIndex, optionId] of (model.supportedThinkingOptionIds ?? []).entries()) {
14910
15485
  if (supportedThinkingIds.has(optionId)) {
@@ -15024,11 +15599,13 @@ var threadThinkingSelectParamsSchema = external_exports.object({
15024
15599
  thinkingOptionId: harnessThinkingOptionIdSchema
15025
15600
  }).strict();
15026
15601
  var threadInspectionParamsSchema = external_exports.object({
15027
- threadId: hostThreadIdSchema
15602
+ threadId: hostThreadIdSchema,
15603
+ includeReferenceCapability: external_exports.boolean().optional()
15028
15604
  }).strict();
15029
15605
  var codexThreadInspectionSchema = external_exports.object({
15030
15606
  owner: external_exports.literal("codex"),
15031
- locked: external_exports.literal(true)
15607
+ locked: external_exports.literal(true),
15608
+ supportsThreadReferences: external_exports.literal(true).optional()
15032
15609
  }).strict();
15033
15610
  var externalThreadInspectionSchema = external_exports.object({
15034
15611
  owner: external_exports.literal("external"),
@@ -15154,6 +15731,22 @@ var harnessLaunchSettingsSchema = external_exports.object({
15154
15731
  restartRequired: external_exports.boolean()
15155
15732
  }).strict();
15156
15733
 
15734
+ // ../../shared-contracts/dist/harness-installation.js
15735
+ var harnessInstallationParamsSchema = external_exports.object({
15736
+ harnessId: harnessIdSchema,
15737
+ action: external_exports.enum(["check", "update", "install"])
15738
+ }).strict();
15739
+ var harnessInstallationStateSchema = external_exports.object({
15740
+ currentVersion: external_exports.string().min(1).max(128),
15741
+ latestVersion: external_exports.string().min(1).max(128),
15742
+ updateAvailable: external_exports.boolean(),
15743
+ canUpdate: external_exports.boolean(),
15744
+ // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15745
+ message: external_exports.string().max(2048).optional(),
15746
+ messageCode: external_exports.string().min(1).max(128).optional(),
15747
+ latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15748
+ }).strict();
15749
+
15157
15750
  // ../../shared-contracts/dist/codex-accounts.js
15158
15751
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
15159
15752
  var nonBlankTextSchema3 = external_exports.string().trim().min(1);
@@ -15453,6 +16046,38 @@ var updateStatusResultSchema = external_exports.strictObject({
15453
16046
  status: updateStatusSchema.nullable()
15454
16047
  });
15455
16048
 
16049
+ // ../../shared-contracts/dist/remote-runtime.js
16050
+ var remoteUpdatePhaseSchema = external_exports.enum([
16051
+ "idle",
16052
+ "installing",
16053
+ "restarting",
16054
+ "succeeded",
16055
+ "failed"
16056
+ ]);
16057
+ var runtimeStatusSchema = external_exports.object({
16058
+ runningVersion: external_exports.string().nullable(),
16059
+ installedVersion: external_exports.string().nullable(),
16060
+ restartRequired: external_exports.boolean(),
16061
+ remote: external_exports.boolean(),
16062
+ updateSupported: external_exports.boolean(),
16063
+ update: external_exports.object({
16064
+ phase: remoteUpdatePhaseSchema,
16065
+ targetVersion: external_exports.string().nullable(),
16066
+ error: external_exports.string().nullable()
16067
+ })
16068
+ });
16069
+ var remoteUpdateParamsSchema = external_exports.object({
16070
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
16071
+ }).strict();
16072
+ var remoteSshSetupParamsSchema = external_exports.object({
16073
+ hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
16074
+ port: external_exports.number().int().min(1).max(65535).nullable(),
16075
+ identity: external_exports.string().max(4096).nullable(),
16076
+ action: external_exports.enum(["inspect", "install", "update", "repair"]),
16077
+ version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
16078
+ }).strict();
16079
+ var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
16080
+
15456
16081
  // ../../shared-contracts/dist/index.js
15457
16082
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15458
16083
 
@@ -15873,10 +16498,10 @@ function commandPrompt(command, catalog, profile = CODEBUDDY_RUNTIME_PROFILE) {
15873
16498
  }
15874
16499
 
15875
16500
  // dist/codebuddy-adapter.js
15876
- import { stat as stat2 } from "node:fs/promises";
16501
+ import { stat as stat3 } from "node:fs/promises";
15877
16502
 
15878
16503
  // dist/acp-client.js
15879
- import { execFile, spawn } from "node:child_process";
16504
+ import { execFile as execFile2, spawn } from "node:child_process";
15880
16505
  import { Readable as Readable2, Writable } from "node:stream";
15881
16506
 
15882
16507
  // ../../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -19920,426 +20545,187 @@ var ClientSideConnection = class {
19920
20545
  *
19921
20546
  * Notifies the agent that a document was closed.
19922
20547
  *
19923
- * @experimental
19924
- */
19925
- unstable_didCloseDocument(params) {
19926
- return this.connection.sendNotification(AGENT_METHODS.document_did_close, params);
19927
- }
19928
- /**
19929
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19930
- *
19931
- * Notifies the agent that a document was saved.
19932
- *
19933
- * @experimental
19934
- */
19935
- unstable_didSaveDocument(params) {
19936
- return this.connection.sendNotification(AGENT_METHODS.document_did_save, params);
19937
- }
19938
- /**
19939
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19940
- *
19941
- * Notifies the agent that a document received focus.
19942
- *
19943
- * @experimental
19944
- */
19945
- unstable_didFocusDocument(params) {
19946
- return this.connection.sendNotification(AGENT_METHODS.document_did_focus, params);
19947
- }
19948
- /**
19949
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19950
- *
19951
- * Notifies the agent that a NES suggestion was accepted.
19952
- *
19953
- * @experimental
19954
- */
19955
- unstable_acceptNes(params) {
19956
- return this.connection.sendNotification(AGENT_METHODS.nes_accept, params);
19957
- }
19958
- /**
19959
- * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
19960
- *
19961
- * Notifies the agent that a NES suggestion was rejected.
19962
- *
19963
- * @experimental
19964
- */
19965
- unstable_rejectNes(params) {
19966
- return this.connection.sendNotification(AGENT_METHODS.nes_reject, params);
19967
- }
19968
- request(method, params, options) {
19969
- const spec = agentRequestSpecsByMethod[method];
19970
- return this.connection.sendRequest(method, params, spec?.mapResponse, options);
19971
- }
19972
- notify(method, params) {
19973
- return this.connection.sendNotification(method, params);
19974
- }
19975
- /**
19976
- * Extension method.
19977
- *
19978
- * @deprecated Use {@link request}.
19979
- */
19980
- extMethod(method, params) {
19981
- return this.request(method, params);
19982
- }
19983
- /**
19984
- * Extension notification.
19985
- *
19986
- * @deprecated Use {@link notify}.
19987
- */
19988
- extNotification(method, params) {
19989
- return this.notify(method, params);
19990
- }
19991
- /**
19992
- * AbortSignal that aborts when the connection closes.
19993
- *
19994
- * This signal can be used to:
19995
- * - Listen for connection closure: `connection.signal.addEventListener('abort', () => {...})`
19996
- * - Check connection status synchronously: `if (connection.signal.aborted) {...}`
19997
- * - Pass to other APIs (fetch, setTimeout) for automatic cancellation
19998
- *
19999
- * The connection closes when the underlying stream ends, either normally or due to an error.
20000
- *
20001
- * @example
20002
- * ```typescript
20003
- * const connection = new ClientSideConnection(client, stream);
20004
- *
20005
- * // Listen for closure
20006
- * connection.signal.addEventListener('abort', () => {
20007
- * console.log('Connection closed - performing cleanup');
20008
- * });
20009
- *
20010
- * // Check status
20011
- * if (connection.signal.aborted) {
20012
- * console.log('Connection is already closed');
20013
- * }
20014
- *
20015
- * // Pass to other APIs
20016
- * fetch(url, { signal: connection.signal });
20017
- * ```
20018
- */
20019
- get signal() {
20020
- return this.connection.signal;
20021
- }
20022
- /**
20023
- * Promise that resolves when the connection closes.
20024
- *
20025
- * The connection closes when the underlying stream ends, either normally or due to an error.
20026
- * Once closed, the connection cannot send or receive any more messages.
20027
- *
20028
- * This is useful for async/await style cleanup:
20029
- *
20030
- * @example
20031
- * ```typescript
20032
- * const connection = new ClientSideConnection(client, stream);
20033
- * await connection.closed;
20034
- * console.log('Connection closed - performing cleanup');
20035
- * ```
20036
- */
20037
- get closed() {
20038
- return this.connection.closed;
20039
- }
20040
- };
20041
-
20042
- // dist/copy-cleanup.js
20043
- import { randomBytes } from "node:crypto";
20044
- import { createInterface } from "node:readline";
20045
- import { stripVTControlCharacters } from "node:util";
20046
- import { Readable } from "node:stream";
20047
- var CodeBuddyCopyCleanup = class {
20048
- copyId;
20049
- cwd;
20050
- password = randomBytes(32).toString("base64url");
20051
- arguments = [
20052
- "--acp",
20053
- "--serve",
20054
- "--host",
20055
- "127.0.0.1",
20056
- "--port",
20057
- "0",
20058
- "--auth",
20059
- "password"
20060
- ];
20061
- #endpoint;
20062
- constructor(copyId, cwd) {
20063
- this.copyId = copyId;
20064
- this.cwd = cwd;
20065
- }
20066
- environment(environment) {
20067
- return {
20068
- ...environment,
20069
- CODEBUDDY_GATEWAY_AUTH: "password",
20070
- CODEBUDDY_GATEWAY_PASSWORD: this.password,
20071
- CODEBUDDY_GATEWAY_BASE_PATH: ""
20072
- };
20073
- }
20074
- /** Native --serve banners include its password; never pass them to the ACP parser/logs. */
20075
- protocolOutput(stdout) {
20076
- return Readable.from(this.#protocolLines(stdout));
20077
- }
20078
- async *#protocolLines(stdout) {
20079
- for await (const line of createInterface({ input: stdout })) {
20080
- const endpoint = /^\s*Endpoint\s+(http:\/\/127\.0\.0\.1:\d+)\s*$/u.exec(stripVTControlCharacters(line));
20081
- if (endpoint)
20082
- this.#endpoint = endpoint[1];
20083
- if (line.trimStart().startsWith("{"))
20084
- yield Buffer.from(`${line}
20085
- `);
20086
- }
20087
- }
20088
- async remove() {
20089
- if (!this.#endpoint)
20090
- throw new CodeBuddyError("nativeFailure", `Native cleanup endpoint was not reported; temporary Session ${this.copyId} remains`);
20091
- const response = await fetch(`${this.#endpoint}/api/v1/sessions/${encodeURIComponent(this.copyId)}?cwd=${encodeURIComponent(this.cwd)}`, {
20092
- method: "DELETE",
20093
- headers: { Authorization: `Bearer ${this.password}`, "x-codebuddy-request": "true" },
20094
- signal: AbortSignal.timeout(5e3),
20095
- redirect: "error"
20096
- }).catch(() => {
20097
- throw new CodeBuddyError("nativeFailure", `Native cleanup request failed; temporary Session ${this.copyId} remains`);
20098
- });
20099
- await response.body?.cancel();
20100
- if (response.status !== 204)
20101
- throw new CodeBuddyError("nativeFailure", `Native cleanup failed (${response.status}); temporary Session ${this.copyId} remains`);
20548
+ * @experimental
20549
+ */
20550
+ unstable_didCloseDocument(params) {
20551
+ return this.connection.sendNotification(AGENT_METHODS.document_did_close, params);
20102
20552
  }
20103
- };
20104
-
20105
- // ../../harness-discovery/dist/environment.js
20106
- import fs from "node:fs";
20107
- import path from "node:path";
20108
- function targetPath(platform) {
20109
- return platform === "win32" ? path.win32 : path.posix;
20110
- }
20111
- function environmentValue(environment, name) {
20112
- const lowered = name.toLowerCase();
20113
- for (const [key, value] of Object.entries(environment)) {
20114
- if (key.toLowerCase() === lowered)
20115
- return value;
20553
+ /**
20554
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20555
+ *
20556
+ * Notifies the agent that a document was saved.
20557
+ *
20558
+ * @experimental
20559
+ */
20560
+ unstable_didSaveDocument(params) {
20561
+ return this.connection.sendNotification(AGENT_METHODS.document_did_save, params);
20116
20562
  }
20117
- return void 0;
20118
- }
20119
- function pathDelimiter(platform) {
20120
- return platform === "win32" ? ";" : ":";
20121
- }
20122
- function pathDirectories(environment, platform) {
20123
- return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
20124
- }
20125
- function executableExtensions(command, platform, environment) {
20126
- if (platform !== "win32")
20127
- return [""];
20128
- if (targetPath(platform).extname(command) !== "")
20129
- return [""];
20130
- return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
20131
- }
20132
- function isExecutableFile(filePath, platform) {
20133
- try {
20134
- fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
20135
- return fs.statSync(filePath).isFile();
20136
- } catch {
20137
- return false;
20563
+ /**
20564
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20565
+ *
20566
+ * Notifies the agent that a document received focus.
20567
+ *
20568
+ * @experimental
20569
+ */
20570
+ unstable_didFocusDocument(params) {
20571
+ return this.connection.sendNotification(AGENT_METHODS.document_did_focus, params);
20138
20572
  }
20139
- }
20140
- function subdirectoryNames(directory) {
20141
- try {
20142
- return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
20143
- } catch {
20144
- return [];
20573
+ /**
20574
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20575
+ *
20576
+ * Notifies the agent that a NES suggestion was accepted.
20577
+ *
20578
+ * @experimental
20579
+ */
20580
+ unstable_acceptNes(params) {
20581
+ return this.connection.sendNotification(AGENT_METHODS.nes_accept, params);
20145
20582
  }
20146
- }
20147
- function newestFirst(names) {
20148
- return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
20149
- }
20150
-
20151
- // ../../harness-discovery/dist/invocation.js
20152
- import path2 from "node:path";
20153
- function commandInvocation(command, arguments_, environment, platform = process.platform) {
20154
- const extension = path2.win32.extname(command).toLowerCase();
20155
- if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
20156
- return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
20583
+ /**
20584
+ * **UNSTABLE**: This capability is not part of the spec yet, and may be removed or changed at any point.
20585
+ *
20586
+ * Notifies the agent that a NES suggestion was rejected.
20587
+ *
20588
+ * @experimental
20589
+ */
20590
+ unstable_rejectNes(params) {
20591
+ return this.connection.sendNotification(AGENT_METHODS.nes_reject, params);
20157
20592
  }
20158
- const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
20159
- const commandLine = [command, ...arguments_].map(quote).join(" ");
20160
- return {
20161
- command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
20162
- arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
20163
- windowsVerbatimArguments: true
20164
- };
20165
- }
20166
-
20167
- // ../../harness-discovery/dist/node-runtime.js
20168
- import path3 from "node:path";
20169
- function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
20170
- const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
20171
- const delimiter = platform === "win32" ? ";" : ":";
20172
- const runtimeDirectory = path3.dirname(runtimeExecutable);
20173
- const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
20174
- const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
20175
- if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
20176
- directories.push(runtimeDirectory);
20593
+ request(method, params, options) {
20594
+ const spec = agentRequestSpecsByMethod[method];
20595
+ return this.connection.sendRequest(method, params, spec?.mapResponse, options);
20177
20596
  }
20178
- return { ...environment, [pathKey]: directories.join(delimiter) };
20179
- }
20180
-
20181
- // ../../harness-discovery/dist/resolve.js
20182
- import os from "node:os";
20183
-
20184
- // ../../harness-discovery/dist/version-managers.js
20185
- function versionManagerBinaryDirectories(context) {
20186
- const { platform, environment, home } = context;
20187
- const list = context.subdirectories ?? subdirectoryNames;
20188
- const pathFlavor = targetPath(platform);
20189
- const value = (name) => environmentValue(environment, name);
20190
- const directories = [];
20191
- const versioned = (root, ...tail) => {
20192
- for (const version2 of newestFirst(list(root))) {
20193
- directories.push(pathFlavor.join(root, version2, ...tail));
20194
- }
20195
- };
20196
- if (platform === "win32") {
20197
- const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
20198
- const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
20199
- versioned(pathFlavor.join(appData, "nvm"));
20200
- versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
20201
- directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
20202
- directories.push(pathFlavor.join(home, ".bun", "bin"));
20203
- const pnpmHome2 = value("PNPM_HOME");
20204
- if (pnpmHome2)
20205
- directories.push(pnpmHome2);
20206
- directories.push(pathFlavor.join(localAppData, "pnpm"));
20207
- return directories;
20597
+ notify(method, params) {
20598
+ return this.connection.sendNotification(method, params);
20208
20599
  }
20209
- versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
20210
- const fnmRoots = [
20211
- value("FNM_DIR"),
20212
- pathFlavor.join(home, ".local", "share", "fnm"),
20213
- pathFlavor.join(home, "Library", "Application Support", "fnm")
20214
- ].filter((root) => root !== void 0);
20215
- for (const root of fnmRoots) {
20216
- versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
20600
+ /**
20601
+ * Extension method.
20602
+ *
20603
+ * @deprecated Use {@link request}.
20604
+ */
20605
+ extMethod(method, params) {
20606
+ return this.request(method, params);
20217
20607
  }
20218
- const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
20219
- versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
20220
- directories.push(pathFlavor.join(voltaHome, "bin"));
20221
- const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
20222
- versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
20223
- directories.push(pathFlavor.join(asdfHome, "shims"));
20224
- const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
20225
- versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
20226
- directories.push(pathFlavor.join(nodenvHome, "shims"));
20227
- versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
20228
- directories.push(pathFlavor.join(home, ".bun", "bin"));
20229
- const pnpmHome = value("PNPM_HOME");
20230
- if (pnpmHome)
20231
- directories.push(pnpmHome);
20232
- directories.push(pathFlavor.join(home, "Library", "pnpm"));
20233
- directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
20234
- for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
20235
- for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
20236
- directories.push(pathFlavor.join(prefix, formula, "bin"));
20237
- }
20608
+ /**
20609
+ * Extension notification.
20610
+ *
20611
+ * @deprecated Use {@link notify}.
20612
+ */
20613
+ extNotification(method, params) {
20614
+ return this.notify(method, params);
20238
20615
  }
20239
- return directories;
20240
- }
20241
-
20242
- // ../../harness-discovery/dist/resolve.js
20243
- var VERSION_MANAGER_ROOTS = "<version-managers>";
20244
- function installRootExtensions(platform) {
20245
- return platform === "win32" ? [".exe", ".cmd"] : [""];
20246
- }
20247
- function resolveHomeDirectory(input) {
20248
- return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
20249
- }
20250
- function templateVariables(environment, platform, home) {
20251
- const pathFlavor = targetPath(platform);
20252
- return {
20253
- HOME: home,
20254
- USERPROFILE: home,
20255
- APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
20256
- LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
20257
- };
20258
- }
20259
- function joinTemplate(platform, value) {
20260
- const pathFlavor = targetPath(platform);
20261
- const segments = value.split("/");
20262
- const head = segments[0] ?? "";
20263
- const tail = segments.slice(1);
20264
- if (head === "")
20265
- return pathFlavor.join(pathFlavor.sep, ...tail);
20266
- return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
20267
- }
20268
- function expandInstallRoot(template, environment, platform, home) {
20269
- const variables = templateVariables(environment, platform, home);
20270
- let unresolved = false;
20271
- const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
20272
- const value = variables[name] ?? environmentValue(environment, name);
20273
- if (value === void 0 || value === "") {
20274
- unresolved = true;
20275
- return "";
20276
- }
20277
- return value;
20278
- });
20279
- return unresolved ? void 0 : joinTemplate(platform, substituted);
20280
- }
20281
- function installRootDirectories(spec, input, dependencies, platform, home) {
20282
- const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
20283
- const directories = [];
20284
- for (const template of templates) {
20285
- if (template === VERSION_MANAGER_ROOTS) {
20286
- directories.push(...versionManagerBinaryDirectories({
20287
- platform,
20288
- environment: input.environment,
20289
- home,
20290
- ...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
20291
- }));
20292
- continue;
20293
- }
20294
- const directory = expandInstallRoot(template, input.environment, platform, home);
20295
- if (directory !== void 0)
20296
- directories.push(directory);
20616
+ /**
20617
+ * AbortSignal that aborts when the connection closes.
20618
+ *
20619
+ * This signal can be used to:
20620
+ * - Listen for connection closure: `connection.signal.addEventListener('abort', () => {...})`
20621
+ * - Check connection status synchronously: `if (connection.signal.aborted) {...}`
20622
+ * - Pass to other APIs (fetch, setTimeout) for automatic cancellation
20623
+ *
20624
+ * The connection closes when the underlying stream ends, either normally or due to an error.
20625
+ *
20626
+ * @example
20627
+ * ```typescript
20628
+ * const connection = new ClientSideConnection(client, stream);
20629
+ *
20630
+ * // Listen for closure
20631
+ * connection.signal.addEventListener('abort', () => {
20632
+ * console.log('Connection closed - performing cleanup');
20633
+ * });
20634
+ *
20635
+ * // Check status
20636
+ * if (connection.signal.aborted) {
20637
+ * console.log('Connection is already closed');
20638
+ * }
20639
+ *
20640
+ * // Pass to other APIs
20641
+ * fetch(url, { signal: connection.signal });
20642
+ * ```
20643
+ */
20644
+ get signal() {
20645
+ return this.connection.signal;
20297
20646
  }
20298
- return directories;
20299
- }
20300
- function harnessCandidates(spec, input, dependencies = {}) {
20301
- const platform = input.platform ?? process.platform;
20302
- const pathFlavor = targetPath(platform);
20303
- const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
20304
- const command = configured ?? spec.command;
20305
- if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
20306
- return [{ candidate: command, source: "configured" }];
20647
+ /**
20648
+ * Promise that resolves when the connection closes.
20649
+ *
20650
+ * The connection closes when the underlying stream ends, either normally or due to an error.
20651
+ * Once closed, the connection cannot send or receive any more messages.
20652
+ *
20653
+ * This is useful for async/await style cleanup:
20654
+ *
20655
+ * @example
20656
+ * ```typescript
20657
+ * const connection = new ClientSideConnection(client, stream);
20658
+ * await connection.closed;
20659
+ * console.log('Connection closed - performing cleanup');
20660
+ * ```
20661
+ */
20662
+ get closed() {
20663
+ return this.connection.closed;
20307
20664
  }
20308
- const candidates = [];
20309
- const extensions = executableExtensions(command, platform, input.environment);
20310
- for (const directory of pathDirectories(input.environment, platform)) {
20311
- for (const extension of extensions) {
20312
- candidates.push({
20313
- candidate: pathFlavor.join(directory, command + extension),
20314
- source: "path"
20315
- });
20316
- }
20665
+ };
20666
+
20667
+ // dist/copy-cleanup.js
20668
+ import { randomBytes } from "node:crypto";
20669
+ import { createInterface } from "node:readline";
20670
+ import { stripVTControlCharacters } from "node:util";
20671
+ import { Readable } from "node:stream";
20672
+ var CodeBuddyCopyCleanup = class {
20673
+ copyId;
20674
+ cwd;
20675
+ password = randomBytes(32).toString("base64url");
20676
+ arguments = [
20677
+ "--acp",
20678
+ "--serve",
20679
+ "--host",
20680
+ "127.0.0.1",
20681
+ "--port",
20682
+ "0",
20683
+ "--auth",
20684
+ "password"
20685
+ ];
20686
+ #endpoint;
20687
+ constructor(copyId, cwd) {
20688
+ this.copyId = copyId;
20689
+ this.cwd = cwd;
20317
20690
  }
20318
- if (configured !== void 0)
20319
- return candidates;
20320
- const home = resolveHomeDirectory(input);
20321
- for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
20322
- for (const extension of installRootExtensions(platform)) {
20323
- candidates.push({
20324
- candidate: pathFlavor.join(directory, spec.command + extension),
20325
- source: "install-root"
20326
- });
20691
+ environment(environment) {
20692
+ return {
20693
+ ...environment,
20694
+ CODEBUDDY_GATEWAY_AUTH: "password",
20695
+ CODEBUDDY_GATEWAY_PASSWORD: this.password,
20696
+ CODEBUDDY_GATEWAY_BASE_PATH: ""
20697
+ };
20698
+ }
20699
+ /** Native --serve banners include its password; never pass them to the ACP parser/logs. */
20700
+ protocolOutput(stdout) {
20701
+ return Readable.from(this.#protocolLines(stdout));
20702
+ }
20703
+ async *#protocolLines(stdout) {
20704
+ for await (const line of createInterface({ input: stdout })) {
20705
+ const endpoint = /^\s*Endpoint\s+(http:\/\/127\.0\.0\.1:\d+)\s*$/u.exec(stripVTControlCharacters(line));
20706
+ if (endpoint)
20707
+ this.#endpoint = endpoint[1];
20708
+ if (line.trimStart().startsWith("{"))
20709
+ yield Buffer.from(`${line}
20710
+ `);
20327
20711
  }
20328
20712
  }
20329
- return candidates;
20330
- }
20331
- function resolveHarnessExecutable(spec, input, dependencies = {}) {
20332
- const platform = input.platform ?? process.platform;
20333
- const isExecutable = dependencies.isExecutable ?? ((candidate) => isExecutableFile(candidate, platform));
20334
- const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
20335
- const context = { platform, isExecutable };
20336
- for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
20337
- const executable = runnable(candidate, context);
20338
- if (executable !== void 0 && isExecutable(executable))
20339
- return { executable, source };
20713
+ async remove() {
20714
+ if (!this.#endpoint)
20715
+ throw new CodeBuddyError("nativeFailure", `Native cleanup endpoint was not reported; temporary Session ${this.copyId} remains`);
20716
+ const response = await fetch(`${this.#endpoint}/api/v1/sessions/${encodeURIComponent(this.copyId)}?cwd=${encodeURIComponent(this.cwd)}`, {
20717
+ method: "DELETE",
20718
+ headers: { Authorization: `Bearer ${this.password}`, "x-codebuddy-request": "true" },
20719
+ signal: AbortSignal.timeout(5e3),
20720
+ redirect: "error"
20721
+ }).catch(() => {
20722
+ throw new CodeBuddyError("nativeFailure", `Native cleanup request failed; temporary Session ${this.copyId} remains`);
20723
+ });
20724
+ await response.body?.cancel();
20725
+ if (response.status !== 204)
20726
+ throw new CodeBuddyError("nativeFailure", `Native cleanup failed (${response.status}); temporary Session ${this.copyId} remains`);
20340
20727
  }
20341
- return void 0;
20342
- }
20728
+ };
20343
20729
 
20344
20730
  // dist/command.js
20345
20731
  var codeBuddyDiscoverySpec = {
@@ -20533,7 +20919,7 @@ var CodeBuddyAcpClient = class {
20533
20919
  }
20534
20920
  const pid = this.#child.pid;
20535
20921
  if (pid && process.platform === "win32") {
20536
- await new Promise((resolve) => execFile("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
20922
+ await new Promise((resolve) => execFile2("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
20537
20923
  } else if (pid) {
20538
20924
  try {
20539
20925
  process.kill(-pid, "SIGKILL");
@@ -20625,17 +21011,17 @@ function confirmedConfiguration(response, id, value, profile = CODEBUDDY_RUNTIME
20625
21011
 
20626
21012
  // dist/derivation.js
20627
21013
  import { randomUUID } from "node:crypto";
20628
- import { execFile as execFile2, spawn as spawn2 } from "node:child_process";
20629
- import { lstat, mkdir, readFile as readFile2, realpath as realpath4, unlink, writeFile } from "node:fs/promises";
20630
- import path5 from "node:path";
21014
+ import { execFile as execFile3, spawn as spawn2 } from "node:child_process";
21015
+ import { lstat, mkdir, readFile as readFile3, realpath as realpath5, unlink, writeFile as writeFile2 } from "node:fs/promises";
21016
+ import path6 from "node:path";
20631
21017
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
20632
21018
 
20633
21019
  // dist/history.js
20634
21020
  import { createHash } from "node:crypto";
20635
21021
  import { realpathSync } from "node:fs";
20636
- import { access, readdir, realpath as realpath2 } from "node:fs/promises";
20637
- import { homedir } from "node:os";
20638
- import path4 from "node:path";
21022
+ import { access, readdir, realpath as realpath3 } from "node:fs/promises";
21023
+ import { homedir as homedir2 } from "node:os";
21024
+ import path5 from "node:path";
20639
21025
  import { isDeepStrictEqual } from "node:util";
20640
21026
 
20641
21027
  // ../../../node_modules/diff/libesm/diff/base.js
@@ -20738,16 +21124,16 @@ var Diff = class {
20738
21124
  }
20739
21125
  }
20740
21126
  }
20741
- addToPath(path8, added, removed, oldPosInc, options) {
20742
- const last = path8.lastComponent;
21127
+ addToPath(path10, added, removed, oldPosInc, options) {
21128
+ const last = path10.lastComponent;
20743
21129
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
20744
21130
  return {
20745
- oldPos: path8.oldPos + oldPosInc,
21131
+ oldPos: path10.oldPos + oldPosInc,
20746
21132
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
20747
21133
  };
20748
21134
  } else {
20749
21135
  return {
20750
- oldPos: path8.oldPos + oldPosInc,
21136
+ oldPos: path10.oldPos + oldPosInc,
20751
21137
  lastComponent: { count: 1, added, removed, previousComponent: last }
20752
21138
  };
20753
21139
  }
@@ -21299,9 +21685,9 @@ function codeBuddyDelegation(callId, input, status, childId, displayName = "Code
21299
21685
  }
21300
21686
 
21301
21687
  // dist/file-observation.js
21302
- import { readFile, realpath, stat } from "node:fs/promises";
21688
+ import { readFile as readFile2, realpath as realpath2, stat } from "node:fs/promises";
21303
21689
  async function codeBuddyFileVersion(file2) {
21304
- const [realFile, value] = await Promise.all([realpath(file2), stat(file2, { bigint: true })]);
21690
+ const [realFile, value] = await Promise.all([realpath2(file2), stat(file2, { bigint: true })]);
21305
21691
  return {
21306
21692
  realFile,
21307
21693
  fingerprint: `${value.dev}:${value.ino}:${value.size}:${value.mtimeNs}:${value.ctimeNs}`,
@@ -21315,7 +21701,7 @@ async function readCodeBuddyVersionedText(file2, maximumBytes, tooLargeMessage,
21315
21701
  const observedBefore = before ?? await codeBuddyFileVersion(file2);
21316
21702
  if (observedBefore.size > maximumBytes)
21317
21703
  throw new CodeBuddyError("unsupported", tooLargeMessage);
21318
- const contents = await readFile(file2, "utf8"), after = await codeBuddyFileVersion(file2), bytesRead = Buffer.byteLength(contents), reusableVersion = sameCodeBuddyFileVersion(observedBefore, after) && bytesRead === after.size ? after : void 0;
21704
+ const contents = await readFile2(file2, "utf8"), after = await codeBuddyFileVersion(file2), bytesRead = Buffer.byteLength(contents), reusableVersion = sameCodeBuddyFileVersion(observedBefore, after) && bytesRead === after.size ? after : void 0;
21319
21705
  if (bytesRead > maximumBytes || after.size > maximumBytes)
21320
21706
  throw new CodeBuddyError("unsupported", tooLargeMessage);
21321
21707
  return { contents, reusableVersion };
@@ -21332,15 +21718,15 @@ function codeBuddyCanonicalCwd(cwd) {
21332
21718
  try {
21333
21719
  return realpathSync.native(cwd);
21334
21720
  } catch {
21335
- return path4.resolve(cwd);
21721
+ return path5.resolve(cwd);
21336
21722
  }
21337
21723
  }
21338
21724
  function codeBuddyConfigRoot(environment, profile) {
21339
21725
  const configuredRoot = profile.configDirectoryEnvironmentVariables.map((name) => environment[name]).find((value) => typeof value === "string" && value.trim().length > 0);
21340
- return configuredRoot || path4.join(environment.HOME || environment.USERPROFILE || homedir(), profile.defaultConfigDirectoryName);
21726
+ return configuredRoot || path5.join(environment.HOME || environment.USERPROFILE || homedir2(), profile.defaultConfigDirectoryName);
21341
21727
  }
21342
21728
  function codeBuddyPrimaryHistoryPath(cwd, ref, environment, profile = CODEBUDDY_RUNTIME_PROFILE) {
21343
- return path4.join(codeBuddyConfigRoot(environment, profile), "projects", codeBuddyProjectSlug(cwd, profile), `${ref.nativeSessionId}.jsonl`);
21729
+ return path5.join(codeBuddyConfigRoot(environment, profile), "projects", codeBuddyProjectSlug(cwd, profile), `${ref.nativeSessionId}.jsonl`);
21344
21730
  }
21345
21731
  function derivedLocator(ref) {
21346
21732
  const locator = record2(ref.locator);
@@ -21374,8 +21760,8 @@ function validateNativeRef(ref, profile = CODEBUDDY_RUNTIME_PROFILE) {
21374
21760
  }
21375
21761
  }
21376
21762
  async function sameCwd(left, right) {
21377
- const b = await realpath2(right);
21378
- const a = await realpath2(left).catch((error51) => {
21763
+ const b = await realpath3(right);
21764
+ const a = await realpath3(left).catch((error51) => {
21379
21765
  if (["ENOENT", "ENOTDIR"].includes(String(record2(error51).code)))
21380
21766
  throw new CodeBuddyError("invalidRequest", "Native Session historical working directory is unavailable; ownership cannot be verified");
21381
21767
  throw error51;
@@ -21383,9 +21769,9 @@ async function sameCwd(left, right) {
21383
21769
  return process.platform === "win32" ? a.toLowerCase() === b.toLowerCase() : a === b;
21384
21770
  }
21385
21771
  async function matchesAnyHistoricalCwd(value, candidates) {
21386
- const resolved = path4.resolve(value);
21772
+ const resolved = path5.resolve(value);
21387
21773
  for (const candidate of candidates) {
21388
- const other = path4.resolve(candidate);
21774
+ const other = path5.resolve(candidate);
21389
21775
  if (process.platform === "win32" ? resolved.toLowerCase() === other.toLowerCase() : resolved === other)
21390
21776
  return true;
21391
21777
  try {
@@ -21409,9 +21795,9 @@ async function codeBuddyLiveNativeHistory(cwd, ref, environment, profile = CODEB
21409
21795
  async function codeBuddyHistory(cwd, ref, environment, tolerateIncompleteTail, profile, transaction) {
21410
21796
  validateNativeRef(ref, profile);
21411
21797
  const configRoot = codeBuddyConfigRoot(environment, profile);
21412
- const root = path4.join(configRoot, "projects");
21798
+ const root = path5.join(configRoot, "projects");
21413
21799
  const slug = codeBuddyProjectSlug(cwd, profile);
21414
- const primary = path4.join(root, slug, `${ref.nativeSessionId}.jsonl`);
21800
+ const primary = path5.join(root, slug, `${ref.nativeSessionId}.jsonl`);
21415
21801
  const provenance = derivedLocator(ref);
21416
21802
  let candidates = [];
21417
21803
  try {
@@ -21430,7 +21816,7 @@ async function codeBuddyHistory(cwd, ref, environment, tolerateIncompleteTail, p
21430
21816
  for (const directory of directories) {
21431
21817
  if (!directory.isDirectory())
21432
21818
  continue;
21433
- const file3 = path4.join(root, directory.name, `${ref.nativeSessionId}.jsonl`);
21819
+ const file3 = path5.join(root, directory.name, `${ref.nativeSessionId}.jsonl`);
21434
21820
  try {
21435
21821
  await access(file3);
21436
21822
  candidates.push(file3);
@@ -21445,7 +21831,7 @@ async function codeBuddyHistory(cwd, ref, environment, tolerateIncompleteTail, p
21445
21831
  const file2 = candidates[0];
21446
21832
  if (!file2)
21447
21833
  throw new CodeBuddyError("sessionNotFound", "Native Session history was not found");
21448
- if (profile.historyCapabilities?.fork && !transaction && path4.resolve(file2) !== path4.resolve(primary))
21834
+ if (profile.historyCapabilities?.fork && !transaction && path5.resolve(file2) !== path5.resolve(primary))
21449
21835
  throw new CodeBuddyError("invalidRequest", "Native Session is not stored in the requested working directory");
21450
21836
  const source = await readCodeBuddyVersionedText(file2, 64e6, "Native history exceeds the supported 64 MB snapshot size"), parsed = parseJsonl(source.contents, tolerateIncompleteTail);
21451
21837
  const checkedDirectories = /* @__PURE__ */ new Set();
@@ -21474,7 +21860,7 @@ async function codeBuddyHistory(cwd, ref, environment, tolerateIncompleteTail, p
21474
21860
  }
21475
21861
  }
21476
21862
  } else if (provenance) {
21477
- if (!await sameCwd(provenance.boundCwd, cwd) || provenance.targetProjectSlug !== slug || path4.resolve(file2) !== path4.resolve(primary))
21863
+ if (!await sameCwd(provenance.boundCwd, cwd) || provenance.targetProjectSlug !== slug || path5.resolve(file2) !== path5.resolve(primary))
21478
21864
  throw new CodeBuddyError("invalidRequest", "Derived Native Session target binding changed");
21479
21865
  const active = nativeHistoryRows(parsed.contents);
21480
21866
  if (provenance.inheritedPrefixRows > active.length || nativeRowsDigest(active.slice(0, provenance.inheritedPrefixRows)) !== provenance.inheritedPrefixSha256)
@@ -21768,7 +22154,7 @@ function historyUsage(contents) {
21768
22154
 
21769
22155
  // dist/child-provenance.js
21770
22156
  import { createHash as createHash2 } from "node:crypto";
21771
- import { realpath as realpath3 } from "node:fs/promises";
22157
+ import { realpath as realpath4 } from "node:fs/promises";
21772
22158
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
21773
22159
  var CODEBUDDY_CHILD_MAX_BYTES = 8e6;
21774
22160
  var equalPath = (left, right) => process.platform === "win32" ? left.toLowerCase() === right.toLowerCase() : left === right;
@@ -21836,7 +22222,7 @@ function codeBuddyInheritedChild(parent, childId) {
21836
22222
  async function canonicalCwds(cwds) {
21837
22223
  const result = /* @__PURE__ */ new Map();
21838
22224
  for (const cwd of new Set(cwds)) {
21839
- const canonical = await realpath3(cwd).catch((error51) => {
22225
+ const canonical = await realpath4(cwd).catch((error51) => {
21840
22226
  if (["ENOENT", "ENOTDIR"].includes(String(record2(error51).code)))
21841
22227
  throw new CodeBuddyError("invalidRequest", "Subagent historical working directory is unavailable; ownership cannot be verified");
21842
22228
  throw error51;
@@ -21875,7 +22261,7 @@ async function validateCodeBuddyChildContents(contents, parent, childId, cwd, to
21875
22261
  throw new CodeBuddyError("protocolError", "Inherited Subagent identity changed");
21876
22262
  inheritedEntries = prefixParsed.entries;
21877
22263
  }
21878
- const target = await realpath3(cwd);
22264
+ const target = await realpath4(cwd);
21879
22265
  const inheritedCwds = inheritedEntries.flatMap((row) => typeof row.cwd === "string" ? [row.cwd] : []);
21880
22266
  const suffixCwds = parsed.entries.slice(inheritedEntries.length).flatMap((row) => typeof row.cwd === "string" ? [row.cwd] : []);
21881
22267
  const canonical = await canonicalCwds(suffixCwds);
@@ -22011,7 +22397,7 @@ async function copyCodeBuddySession(cwd, sourceId, targetId, environment, signal
22011
22397
  child.stderr.destroy();
22012
22398
  } else if (process.platform === "win32" && child.pid) {
22013
22399
  termination = new Promise((done) => {
22014
- execFile2("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
22400
+ execFile3("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
22015
22401
  child.kill();
22016
22402
  done();
22017
22403
  });
@@ -22118,20 +22504,20 @@ async function bridgeCopyToTarget(sourceCwd, targetCwd, ref, contents, environme
22118
22504
  const targetFile = codeBuddyPrimaryHistoryPath(targetCwd, ref, environment, profile);
22119
22505
  if (sameResolvedPath(sourceFile, targetFile))
22120
22506
  return void 0;
22121
- const targetDirectory = path5.dirname(targetFile);
22122
- const projectsDirectory = path5.dirname(targetDirectory);
22507
+ const targetDirectory = path6.dirname(targetFile);
22508
+ const projectsDirectory = path6.dirname(targetDirectory);
22123
22509
  await mkdir(targetDirectory, { recursive: true });
22124
22510
  const [realProjects, realTargetDirectory] = await Promise.all([
22125
- realpath4(projectsDirectory),
22126
- realpath4(targetDirectory)
22511
+ realpath5(projectsDirectory),
22512
+ realpath5(targetDirectory)
22127
22513
  ]);
22128
- if (!sameResolvedPath(realTargetDirectory, path5.join(realProjects, codeBuddyProjectSlug(targetCwd, profile))))
22514
+ if (!sameResolvedPath(realTargetDirectory, path6.join(realProjects, codeBuddyProjectSlug(targetCwd, profile))))
22129
22515
  throw new CodeBuddyError("invalidRequest", "Cross-directory history bridge target escaped the native projects root");
22130
22516
  const expected = Buffer.from(contents, "utf8");
22131
- await writeFile(targetFile, expected, { flag: "wx", mode: 384 });
22517
+ await writeFile2(targetFile, expected, { flag: "wx", mode: 384 });
22132
22518
  const bridge = { file: targetFile, expected };
22133
22519
  try {
22134
- const persisted = await readFile2(targetFile);
22520
+ const persisted = await readFile3(targetFile);
22135
22521
  if (!isDeepStrictEqual3(persisted, expected))
22136
22522
  throw new CodeBuddyError("nativeFailure", "Cross-directory history bridge changed native bytes");
22137
22523
  return bridge;
@@ -22146,7 +22532,7 @@ async function cleanupBridge(bridge) {
22146
22532
  const info = await lstat(bridge.file);
22147
22533
  if (!info.isFile() || process.platform !== "win32" && (info.mode & 63) !== 0)
22148
22534
  return;
22149
- if (!isDeepStrictEqual3(await readFile2(bridge.file), bridge.expected))
22535
+ if (!isDeepStrictEqual3(await readFile3(bridge.file), bridge.expected))
22150
22536
  return;
22151
22537
  await unlink(bridge.file);
22152
22538
  } catch (error51) {
@@ -22232,7 +22618,7 @@ function assertChildRanges(rows2, child) {
22232
22618
  }
22233
22619
  }
22234
22620
  async function plainDirectory(parent, name) {
22235
- const directory = path5.join(parent, name);
22621
+ const directory = path6.join(parent, name);
22236
22622
  await mkdir(directory, { mode: 448 }).catch((error51) => {
22237
22623
  if (record2(error51).code !== "EEXIST")
22238
22624
  throw error51;
@@ -22240,7 +22626,7 @@ async function plainDirectory(parent, name) {
22240
22626
  const info = await lstat(directory);
22241
22627
  if (!info.isDirectory() || info.isSymbolicLink() || process.platform !== "win32" && (info.mode & 18) !== 0)
22242
22628
  throw new CodeBuddyError("invalidRequest", "Redirected native Subagent directory");
22243
- const actual = await realpath4(directory);
22629
+ const actual = await realpath5(directory);
22244
22630
  if (!sameResolvedPath(actual, directory))
22245
22631
  throw new CodeBuddyError("invalidRequest", "Redirected native Subagent directory");
22246
22632
  return directory;
@@ -22249,7 +22635,7 @@ async function verifiedChildFile(file2, expected) {
22249
22635
  const info = await lstat(file2);
22250
22636
  if (!info.isFile() || info.isSymbolicLink() || process.platform !== "win32" && (info.mode & 63) !== 0)
22251
22637
  throw new CodeBuddyError("invalidRequest", "Unsafe derived Subagent transcript");
22252
- if (!sameResolvedPath(await realpath4(file2), file2))
22638
+ if (!sameResolvedPath(await realpath5(file2), file2))
22253
22639
  throw new CodeBuddyError("invalidRequest", "Redirected derived Subagent transcript");
22254
22640
  const before = await codeBuddyFileVersion(file2);
22255
22641
  const actual = await readCodeBuddyVersionedText(file2, CODEBUDDY_CHILD_MAX_BYTES, "Subagent transcript exceeds 8 MB", before);
@@ -22258,7 +22644,7 @@ async function verifiedChildFile(file2, expected) {
22258
22644
  }
22259
22645
  async function persistChildCopy(file2, expected) {
22260
22646
  try {
22261
- await writeFile(file2, expected, { flag: "wx", mode: 384 });
22647
+ await writeFile2(file2, expected, { flag: "wx", mode: 384 });
22262
22648
  } catch (error51) {
22263
22649
  if (record2(error51).code !== "EEXIST")
22264
22650
  throw error51;
@@ -22277,19 +22663,19 @@ async function copyInheritedChildren(options) {
22277
22663
  const { references } = options;
22278
22664
  if (!references.length)
22279
22665
  return { descriptors: [], created: [] };
22280
- const sourceHistoryFile = await realpath4(options.sourceHistoryFile);
22281
- const sourceProject = path5.dirname(sourceHistoryFile);
22282
- if (!sameResolvedPath(sourceHistoryFile, path5.join(sourceProject, `${options.sourceRef.nativeSessionId}.jsonl`)))
22666
+ const sourceHistoryFile = await realpath5(options.sourceHistoryFile);
22667
+ const sourceProject = path6.dirname(sourceHistoryFile);
22668
+ if (!sameResolvedPath(sourceHistoryFile, path6.join(sourceProject, `${options.sourceRef.nativeSessionId}.jsonl`)))
22283
22669
  throw new CodeBuddyError("invalidRequest", "Unexpected source history location");
22284
- const sourceDirectory = path5.join(sourceProject, options.sourceRef.nativeSessionId, "subagents");
22670
+ const sourceDirectory = path6.join(sourceProject, options.sourceRef.nativeSessionId, "subagents");
22285
22671
  const sourceDirectoryInfo = await lstat(sourceDirectory);
22286
22672
  if (!sourceDirectoryInfo.isDirectory() || sourceDirectoryInfo.isSymbolicLink())
22287
22673
  throw new CodeBuddyError("invalidRequest", "Redirected source Subagent directory");
22288
- if (!sameResolvedPath(await realpath4(sourceDirectory), sourceDirectory))
22674
+ if (!sameResolvedPath(await realpath5(sourceDirectory), sourceDirectory))
22289
22675
  throw new CodeBuddyError("invalidRequest", "Redirected source Subagent directory");
22290
- const targetHistoryFile = await realpath4(options.targetHistoryFile);
22291
- const targetProject = path5.dirname(targetHistoryFile);
22292
- if (!sameResolvedPath(targetHistoryFile, path5.join(targetProject, `${options.targetRef.nativeSessionId}.jsonl`)))
22676
+ const targetHistoryFile = await realpath5(options.targetHistoryFile);
22677
+ const targetProject = path6.dirname(targetHistoryFile);
22678
+ if (!sameResolvedPath(targetHistoryFile, path6.join(targetProject, `${options.targetRef.nativeSessionId}.jsonl`)))
22293
22679
  throw new CodeBuddyError("invalidRequest", "Unexpected target history location");
22294
22680
  const targetSessionDirectory = await plainDirectory(targetProject, options.targetRef.nativeSessionId);
22295
22681
  const targetDirectory = await plainDirectory(targetSessionDirectory, "subagents");
@@ -22297,7 +22683,7 @@ async function copyInheritedChildren(options) {
22297
22683
  const created = [];
22298
22684
  try {
22299
22685
  for (const reference of references) {
22300
- const sourceFile = path5.join(sourceDirectory, `${reference.childId}.jsonl`);
22686
+ const sourceFile = path6.join(sourceDirectory, `${reference.childId}.jsonl`);
22301
22687
  const sourceInfo = await lstat(sourceFile);
22302
22688
  if (!sourceInfo.isFile() || sourceInfo.isSymbolicLink())
22303
22689
  throw new CodeBuddyError("invalidRequest", "Redirected source Subagent transcript");
@@ -22316,7 +22702,7 @@ async function copyInheritedChildren(options) {
22316
22702
  throw new CodeBuddyError("protocolError", "Missing Agent result child range");
22317
22703
  const prefix = await codeBuddyChildPrefixThrough(source.contents, last, validated);
22318
22704
  const expected = Buffer.from(prefix.contents, "utf8");
22319
- const targetFile = path5.join(targetDirectory, `${reference.childId}.jsonl`);
22705
+ const targetFile = path6.join(targetDirectory, `${reference.childId}.jsonl`);
22320
22706
  const copy = await persistChildCopy(targetFile, expected);
22321
22707
  if (copy)
22322
22708
  created.push(copy);
@@ -22553,6 +22939,345 @@ async function deriveCodeBuddySession(options) {
22553
22939
  }
22554
22940
  }
22555
22941
 
22942
+ // dist/session-import.js
22943
+ import { createReadStream } from "node:fs";
22944
+ import { opendir, readFile as readFile4, stat as stat2 } from "node:fs/promises";
22945
+ import path7 from "node:path";
22946
+ import { createInterface as createInterface2 } from "node:readline";
22947
+
22948
+ // ../../harness-adapter/dist/session-import.js
22949
+ import { lstat as lstat2 } from "node:fs/promises";
22950
+ var SessionImportChangedError = class extends Error {
22951
+ constructor(message = "Native Session changed during discovery; refresh and retry") {
22952
+ super(message);
22953
+ this.name = "SessionImportChangedError";
22954
+ }
22955
+ };
22956
+ function isMissingFileError(error51) {
22957
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT";
22958
+ }
22959
+ function sameFileFingerprint(left, right) {
22960
+ 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;
22961
+ }
22962
+ var STORAGE_ACCESS_ERRORS = /* @__PURE__ */ new Set(["EACCES", "EPERM", "EIO", "EMFILE", "ENFILE"]);
22963
+ function isStorageAccessError(error51) {
22964
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && typeof error51.code === "string" && STORAGE_ACCESS_ERRORS.has(error51.code);
22965
+ }
22966
+ async function optionalLstat(file2) {
22967
+ try {
22968
+ return await lstat2(file2);
22969
+ } catch (error51) {
22970
+ if (isMissingFileError(error51))
22971
+ return null;
22972
+ throw error51;
22973
+ }
22974
+ }
22975
+ async function readStableFiles(files, read) {
22976
+ const before = await Promise.all(files.map(optionalLstat));
22977
+ const value = await read(before);
22978
+ const after = await Promise.all(files.map(optionalLstat));
22979
+ if (before.some((info, index) => !sameFileFingerprint(info, after[index] ?? null)))
22980
+ throw new SessionImportChangedError();
22981
+ return value;
22982
+ }
22983
+ function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
22984
+ if (typeof value !== "string")
22985
+ return null;
22986
+ const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
22987
+ if (!normalized)
22988
+ return null;
22989
+ if (normalized.length <= maxLength)
22990
+ return normalized;
22991
+ const characters = [...normalized];
22992
+ if (characters.length <= maxLength)
22993
+ return normalized;
22994
+ return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
22995
+ }
22996
+ function sessionImportCandidate(input) {
22997
+ const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
22998
+ const parsed = harnessSessionImportCandidateSchema.safeParse({
22999
+ nativeSessionId: input.nativeSessionId,
23000
+ cwd: input.cwd,
23001
+ title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
23002
+ updatedAt: Math.floor(time3),
23003
+ // Unknown must stay unknown; only an explicit boolean is a native statement.
23004
+ running: typeof input.running === "boolean" ? input.running : null
23005
+ });
23006
+ return parsed.success ? parsed.data : null;
23007
+ }
23008
+ var SessionImportScope = class {
23009
+ #abort = new AbortController();
23010
+ #options;
23011
+ #pending = /* @__PURE__ */ new Set();
23012
+ constructor(options) {
23013
+ this.#options = options;
23014
+ }
23015
+ #closed() {
23016
+ return {
23017
+ ok: false,
23018
+ error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
23019
+ };
23020
+ }
23021
+ read(operation) {
23022
+ const signal = this.#abort.signal;
23023
+ if (signal.aborted)
23024
+ return Promise.resolve(this.#closed());
23025
+ let started;
23026
+ try {
23027
+ started = operation(signal);
23028
+ } catch (error51) {
23029
+ started = Promise.reject(error51 instanceof Error ? error51 : new Error("Session read failed"));
23030
+ }
23031
+ const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
23032
+ ok: false,
23033
+ error: {
23034
+ code: "unavailable",
23035
+ message: this.#options.unavailableMessage,
23036
+ retryable: true
23037
+ }
23038
+ }).finally(() => this.#pending.delete(request));
23039
+ this.#pending.add(request);
23040
+ return request;
23041
+ }
23042
+ /** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
23043
+ async resolve(operation) {
23044
+ const result = await this.read(operation);
23045
+ if (!result.ok)
23046
+ return result;
23047
+ return result.value ? { ok: true, value: result.value } : {
23048
+ ok: false,
23049
+ error: {
23050
+ code: "sessionNotFound",
23051
+ message: this.#options.notFoundMessage,
23052
+ retryable: false
23053
+ }
23054
+ };
23055
+ }
23056
+ /** Idempotent. Resolves after every started read has settled. */
23057
+ async close() {
23058
+ this.#abort.abort();
23059
+ await Promise.allSettled(this.#pending);
23060
+ }
23061
+ };
23062
+
23063
+ // dist/session-import.js
23064
+ var SESSION_FILE = /^([A-Za-z0-9][A-Za-z0-9_-]{0,199})\.jsonl$/u;
23065
+ var MAX_HISTORY_BYTES = 64e6;
23066
+ var MAX_MARKER_BYTES = 64 * 1024;
23067
+ function processAlive(pid) {
23068
+ if (typeof pid !== "number" || !Number.isSafeInteger(pid) || pid <= 0)
23069
+ return false;
23070
+ try {
23071
+ process.kill(pid, 0);
23072
+ return true;
23073
+ } catch (error51) {
23074
+ return record2(error51).code === "EPERM";
23075
+ }
23076
+ }
23077
+ function userText(row) {
23078
+ if (row.type !== "message" || row.role !== "user")
23079
+ return null;
23080
+ const { content } = row;
23081
+ if (typeof content === "string")
23082
+ return content;
23083
+ if (!Array.isArray(content))
23084
+ return "";
23085
+ return content.map((part) => record2(part)).filter((part) => typeof part.text === "string").map((part) => String(part.text)).join(" ");
23086
+ }
23087
+ async function readFacts(file2, signal) {
23088
+ const stream = createReadStream(file2, { encoding: "utf8", signal });
23089
+ const lines = createInterface2({ input: stream, crlfDelay: Infinity });
23090
+ let cwd = null;
23091
+ let customTitle = null;
23092
+ let generatedTitle = null;
23093
+ let firstPrompt = null;
23094
+ let hasUser = false;
23095
+ let updatedAt = null;
23096
+ try {
23097
+ for await (const line of lines) {
23098
+ signal.throwIfAborted();
23099
+ if (!line.trim())
23100
+ continue;
23101
+ let parsed;
23102
+ try {
23103
+ parsed = JSON.parse(line);
23104
+ } catch {
23105
+ return null;
23106
+ }
23107
+ const row = record2(parsed);
23108
+ if (typeof row.cwd === "string" && path7.isAbsolute(row.cwd))
23109
+ cwd ??= row.cwd;
23110
+ if (typeof row.timestamp === "number" && Number.isFinite(row.timestamp))
23111
+ updatedAt = row.timestamp;
23112
+ if (row.type === "custom-title")
23113
+ customTitle = sessionImportTitle(row.customTitle);
23114
+ else if (row.type === "ai-title")
23115
+ generatedTitle = sessionImportTitle(row.aiTitle);
23116
+ else {
23117
+ const text2 = userText(row);
23118
+ if (text2 !== null) {
23119
+ hasUser = true;
23120
+ firstPrompt ??= sessionImportTitle(text2);
23121
+ }
23122
+ }
23123
+ }
23124
+ } finally {
23125
+ lines.close();
23126
+ stream.destroy();
23127
+ }
23128
+ if (!hasUser || !cwd)
23129
+ return null;
23130
+ return { cwd, title: customTitle ?? generatedTitle ?? firstPrompt, updatedAt };
23131
+ }
23132
+ var CodeBuddySessionImport = class {
23133
+ #environment;
23134
+ #profile;
23135
+ #scope;
23136
+ constructor(environment, profile = CODEBUDDY_RUNTIME_PROFILE) {
23137
+ this.#environment = { ...environment };
23138
+ this.#profile = profile;
23139
+ this.#scope = new SessionImportScope({
23140
+ closedMessage: `${profile.displayName} Session import is closed`,
23141
+ unavailableMessage: `${profile.displayName} sessions could not be read; close native clients, check storage access and retry`,
23142
+ notFoundMessage: `${profile.displayName} Session is no longer importable`
23143
+ });
23144
+ }
23145
+ listCandidates() {
23146
+ return this.#scope.read(async (signal) => {
23147
+ const active = await this.#activeSessions(signal);
23148
+ const candidates = [];
23149
+ for (const [nativeSessionId, files] of await this.#sessionFiles(signal)) {
23150
+ if (files.length !== 1 || !files[0])
23151
+ continue;
23152
+ try {
23153
+ const source = await this.#source(nativeSessionId, files[0], active, signal);
23154
+ if (source)
23155
+ candidates.push(source.candidate);
23156
+ } catch (error51) {
23157
+ if (!(error51 instanceof SessionImportChangedError))
23158
+ throw error51;
23159
+ }
23160
+ }
23161
+ return candidates;
23162
+ });
23163
+ }
23164
+ resolveCandidate(nativeSessionId) {
23165
+ return this.#scope.resolve(async (signal) => {
23166
+ const files = (await this.#sessionFiles(signal)).get(nativeSessionId);
23167
+ if (files?.length !== 1 || !files[0])
23168
+ return null;
23169
+ return this.#source(nativeSessionId, files[0], await this.#activeSessions(signal), signal);
23170
+ });
23171
+ }
23172
+ close() {
23173
+ return this.#scope.close();
23174
+ }
23175
+ #root() {
23176
+ return codeBuddyConfigRoot(this.#environment, this.#profile);
23177
+ }
23178
+ /** IDs a live native process registered in `<config>/sessions/<pid>.json`. */
23179
+ async #activeSessions(signal) {
23180
+ const active = /* @__PURE__ */ new Set();
23181
+ const directory = path7.join(this.#root(), "sessions");
23182
+ const markers = await opendir(directory).catch((error51) => {
23183
+ if (isMissingFileError(error51) || record2(error51).code === "ENOTDIR")
23184
+ return null;
23185
+ throw error51;
23186
+ });
23187
+ if (!markers)
23188
+ return active;
23189
+ for await (const marker of markers) {
23190
+ signal.throwIfAborted();
23191
+ if (!marker.isFile() || !marker.name.endsWith(".json"))
23192
+ continue;
23193
+ try {
23194
+ const file2 = path7.join(directory, marker.name);
23195
+ if ((await stat2(file2)).size > MAX_MARKER_BYTES)
23196
+ continue;
23197
+ const entry = record2(JSON.parse(await readFile4(file2, { encoding: "utf8", signal })));
23198
+ if (typeof entry.sessionId === "string" && processAlive(entry.pid))
23199
+ active.add(entry.sessionId);
23200
+ } catch (error51) {
23201
+ signal.throwIfAborted();
23202
+ if (isStorageAccessError(error51))
23203
+ throw error51;
23204
+ }
23205
+ }
23206
+ return active;
23207
+ }
23208
+ /** Session ID to every project file claiming it. Enumerated links are not followed. */
23209
+ async #sessionFiles(signal) {
23210
+ const root = path7.join(this.#root(), "projects");
23211
+ const found = /* @__PURE__ */ new Map();
23212
+ const info = await optionalLstat(root);
23213
+ if (!info)
23214
+ return found;
23215
+ if (!info.isDirectory())
23216
+ throw new Error(`${this.#profile.displayName} Session store is not a directory`);
23217
+ for await (const project of await opendir(root)) {
23218
+ signal.throwIfAborted();
23219
+ if (!project.isDirectory())
23220
+ continue;
23221
+ const projectDirectory = path7.join(root, project.name);
23222
+ const entries = await opendir(projectDirectory).catch((error51) => {
23223
+ if (isMissingFileError(error51))
23224
+ return null;
23225
+ throw error51;
23226
+ });
23227
+ if (!entries)
23228
+ continue;
23229
+ for await (const entry of entries) {
23230
+ signal.throwIfAborted();
23231
+ const nativeSessionId = entry.isFile() ? SESSION_FILE.exec(entry.name)?.[1] : void 0;
23232
+ if (!nativeSessionId)
23233
+ continue;
23234
+ const files = found.get(nativeSessionId) ?? [];
23235
+ files.push(path7.join(projectDirectory, entry.name));
23236
+ found.set(nativeSessionId, files);
23237
+ }
23238
+ }
23239
+ return found;
23240
+ }
23241
+ async #source(nativeSessionId, file2, active, signal) {
23242
+ signal.throwIfAborted();
23243
+ return readStableFiles([file2], async ([info]) => {
23244
+ if (!info?.isFile() || info.size === 0 || info.size > MAX_HISTORY_BYTES)
23245
+ return null;
23246
+ try {
23247
+ const facts = await readFacts(file2, signal);
23248
+ if (!facts)
23249
+ return null;
23250
+ const cwd = path7.resolve(facts.cwd);
23251
+ if (!(await stat2(cwd)).isDirectory())
23252
+ return null;
23253
+ const nativeRef = nativeSessionRefSchema.parse({
23254
+ harnessId: this.#profile.harnessId,
23255
+ nativeSessionId,
23256
+ formatVersion: 1
23257
+ });
23258
+ signal.throwIfAborted();
23259
+ const history = await codeBuddyNativeHistory(cwd, nativeRef, this.#environment, this.#profile);
23260
+ if (path7.resolve(history.file) !== path7.resolve(file2))
23261
+ return null;
23262
+ const candidate = sessionImportCandidate({
23263
+ nativeSessionId,
23264
+ cwd,
23265
+ title: facts.title,
23266
+ updatedAt: facts.updatedAt ?? info.mtimeMs,
23267
+ // A registered live process holds the Session. Absence is not proof of idleness.
23268
+ running: active.has(nativeSessionId) ? true : null
23269
+ });
23270
+ return candidate ? { candidate, nativeRef } : null;
23271
+ } catch (error51) {
23272
+ signal.throwIfAborted();
23273
+ if (isStorageAccessError(error51))
23274
+ throw error51;
23275
+ return null;
23276
+ }
23277
+ });
23278
+ }
23279
+ };
23280
+
22556
23281
  // dist/interactions.js
22557
23282
  var CodeBuddyInteractions = class {
22558
23283
  emit;
@@ -22695,8 +23420,8 @@ var CodeBuddyInteractions = class {
22695
23420
  };
22696
23421
 
22697
23422
  // dist/subagent-history.js
22698
- import { readdir as readdir2, realpath as realpath5 } from "node:fs/promises";
22699
- import path6 from "node:path";
23423
+ import { readdir as readdir2, realpath as realpath6 } from "node:fs/promises";
23424
+ import path8 from "node:path";
22700
23425
  var equalPath2 = (a, b) => process.platform === "win32" ? a.toLowerCase() === b.toLowerCase() : a === b;
22701
23426
  var MAX_CACHED_CHILDREN = 16;
22702
23427
  var CodeBuddyChildObserver = class {
@@ -22723,9 +23448,9 @@ var CodeBuddyChildObserver = class {
22723
23448
  throw new CodeBuddyError("invalidRequest", "Subagent observer is closed");
22724
23449
  }
22725
23450
  async #validateWorkspaces(cwds) {
22726
- const expected = await realpath5(this.cwd);
23451
+ const expected = await realpath6(this.cwd);
22727
23452
  for (const cwd of new Set(cwds)) {
22728
- const actual = await realpath5(cwd).catch((error51) => {
23453
+ const actual = await realpath6(cwd).catch((error51) => {
22729
23454
  if (["ENOENT", "ENOTDIR"].includes(String(record2(error51).code)))
22730
23455
  throw new CodeBuddyError("invalidRequest", "Native Session historical working directory is unavailable; ownership cannot be verified");
22731
23456
  throw error51;
@@ -22760,9 +23485,9 @@ var CodeBuddyChildObserver = class {
22760
23485
  }
22761
23486
  async #directory() {
22762
23487
  const history = await this.#parentHistory();
22763
- const project = path6.dirname(await realpath5(history.file));
22764
- const expected = path6.join(project, this.parent.nativeSessionId, "subagents");
22765
- const actual = await realpath5(expected);
23488
+ const project = path8.dirname(await realpath6(history.file));
23489
+ const expected = path8.join(project, this.parent.nativeSessionId, "subagents");
23490
+ const actual = await realpath6(expected);
22766
23491
  this.#assertOpen();
22767
23492
  if (!equalPath2(actual, expected))
22768
23493
  throw new CodeBuddyError("invalidRequest", `Redirected ${this.profile.displayName} Subagent directory`);
@@ -22771,7 +23496,7 @@ var CodeBuddyChildObserver = class {
22771
23496
  async #child(directory, childId) {
22772
23497
  if (!validCodeBuddyChildId(childId))
22773
23498
  throw new CodeBuddyError("invalidRequest", "Invalid native Subagent ID");
22774
- const file2 = path6.join(directory, `${childId}.jsonl`);
23499
+ const file2 = path8.join(directory, `${childId}.jsonl`);
22775
23500
  const before = await codeBuddyFileVersion(file2);
22776
23501
  if (!equalPath2(before.realFile, file2))
22777
23502
  throw new CodeBuddyError("invalidRequest", "Redirected Subagent transcript");
@@ -23483,6 +24208,7 @@ var CodeBuddyAdapter = class {
23483
24208
  harnessId;
23484
24209
  commandCatalog;
23485
24210
  liveCommandCatalog = true;
24211
+ sessionImport;
23486
24212
  subagents = {
23487
24213
  readSnapshot: async ({ parent, nativeSubagentId, cwd }) => {
23488
24214
  try {
@@ -23516,6 +24242,7 @@ var CodeBuddyAdapter = class {
23516
24242
  this.commandCatalog = commandCatalog2;
23517
24243
  }
23518
24244
  this.#environment = { ...options.environment ?? process.env };
24245
+ this.sessionImport = new CodeBuddySessionImport(this.#environment, this.#profile);
23519
24246
  this.#invocation = options.invocationFactory ?? codeBuddyInvocation;
23520
24247
  this.#factory = options.clientFactory ?? ((clientOptions) => new CodeBuddyAcpClient(clientOptions, void 0, this.#invocation));
23521
24248
  }
@@ -23535,7 +24262,7 @@ var CodeBuddyAdapter = class {
23535
24262
  try {
23536
24263
  if (this.#closed)
23537
24264
  throw new CodeBuddyError("invalidState", "Adapter is closed");
23538
- if (!(await stat2(cwd)).isDirectory())
24265
+ if (!(await stat3(cwd)).isDirectory())
23539
24266
  throw new CodeBuddyError("invalidRequest", "Working directory is not a directory");
23540
24267
  client2 = this.#factory({
23541
24268
  cwd,
@@ -23581,7 +24308,7 @@ var CodeBuddyAdapter = class {
23581
24308
  return failure("invalidRequest", "Unattended execution requires native fullAccess permissions", this.#profile);
23582
24309
  let session;
23583
24310
  try {
23584
- if (!(await stat2(input.cwd)).isDirectory())
24311
+ if (!(await stat3(input.cwd)).isDirectory())
23585
24312
  throw new CodeBuddyError("invalidRequest", "Working directory is not a directory");
23586
24313
  if (this.#closed)
23587
24314
  throw new CodeBuddyError("invalidState", "Adapter closed while opening Session");
@@ -23644,7 +24371,7 @@ var CodeBuddyAdapter = class {
23644
24371
  async close() {
23645
24372
  this.#closed = true;
23646
24373
  this.#abort.abort();
23647
- await Promise.allSettled([...this.#derivations]);
24374
+ await Promise.allSettled([this.sessionImport.close(), ...this.#derivations]);
23648
24375
  const results = await Promise.allSettled([...this.#sessions, ...this.#inspections].map((resource) => resource.close()));
23649
24376
  this.#sessions.clear();
23650
24377
  this.#inspections.clear();
@@ -23655,9 +24382,41 @@ var CodeBuddyAdapter = class {
23655
24382
  }
23656
24383
  };
23657
24384
 
24385
+ // dist/installation.js
24386
+ function createCodeBuddyInstallation(environment) {
24387
+ let update;
24388
+ return createInstallationManager({
24389
+ async check() {
24390
+ const resolved = resolveHarnessExecutable(codeBuddyDiscoverySpec, { environment });
24391
+ if (!resolved)
24392
+ throw new Error("CodeBuddy is not installed");
24393
+ const currentVersion = versionFromOutput(await runInstallationCommand(resolved.executable, ["--version"], environment));
24394
+ const npm = await npmInstallation(resolved.executable, ["@tencent-ai/codebuddy-code"], environment);
24395
+ update = npm?.update;
24396
+ const latestVersion = npm ? await npm.latest() : "Unknown";
24397
+ const canUpdate = npm?.canUpdate ?? false;
24398
+ return {
24399
+ currentVersion,
24400
+ latestVersion,
24401
+ updateAvailable: !!npm && newerInstallationVersion(currentVersion, latestVersion),
24402
+ canUpdate,
24403
+ ...!canUpdate ? {
24404
+ messageCode: "codebuddy-npm-required",
24405
+ message: "Use CodeBuddy's native updater or original package manager for this installation. Latest-version checks here require an identified npm installation."
24406
+ } : {}
24407
+ };
24408
+ },
24409
+ async update(state) {
24410
+ if (!update)
24411
+ throw new Error("This CodeBuddy installation requires a manual update");
24412
+ await update(state.latestVersion);
24413
+ }
24414
+ });
24415
+ }
24416
+
23658
24417
  // ../../harness-broker/dist/client.js
23659
24418
  import { randomUUID as randomUUID2 } from "node:crypto";
23660
- import { lstat as lstat2, readFile as readFile3 } from "node:fs/promises";
24419
+ import { lstat as lstat3, readFile as readFile5 } from "node:fs/promises";
23661
24420
  import net, {} from "node:net";
23662
24421
 
23663
24422
  // ../../harness-broker/dist/protocol.js
@@ -23772,24 +24531,25 @@ function consumeBrokerFrames(socket, onFrame, onError) {
23772
24531
 
23773
24532
  // ../../harness-broker/dist/paths.js
23774
24533
  import os2 from "node:os";
23775
- import path7 from "node:path";
24534
+ import path9 from "node:path";
23776
24535
  var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
23777
24536
  var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
23778
24537
  function defaultHarnessBrokerDirectory(environment = process.env) {
23779
24538
  const home = environment.HOME || os2.homedir();
23780
- return path7.join(home, ".codexhost", "harness-broker");
24539
+ return path9.join(home, ".codexhost", "harness-broker");
23781
24540
  }
23782
24541
  function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId = "claude-code") {
23783
24542
  harnessPluginIdSchema.parse(harnessId);
23784
24543
  if (harnessId !== "claude-code")
23785
- return path7.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
23786
- return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path7.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
24544
+ return path9.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
24545
+ return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path9.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
23787
24546
  }
23788
24547
 
23789
24548
  // ../../harness-broker/dist/validation.js
23790
24549
  var cwdSchema = external_exports.string().min(1).max(16384);
23791
24550
  var brokerEnvironmentSchema = external_exports.object({
23792
24551
  CODEXHOST_CLI_PATH: external_exports.string().max(16384).optional(),
24552
+ CODEXHOST_CLI_NODE_PATH: external_exports.string().max(16384).optional(),
23793
24553
  CODEXHOST_RUNTIME_ENDPOINT: external_exports.string().max(16384).optional(),
23794
24554
  CODEXHOST_RUNTIME_TOKEN: external_exports.string().max(16384).optional(),
23795
24555
  CODEXHOST_THREAD_ID: external_exports.string().max(256).optional()
@@ -23944,6 +24704,7 @@ var eventKeys = /* @__PURE__ */ new Map([
23944
24704
  ["item.started", /* @__PURE__ */ new Set(["type", "turnId", "item"])],
23945
24705
  ["item.updated", /* @__PURE__ */ new Set(["type", "turnId", "itemId", "update"])],
23946
24706
  ["item.completed", /* @__PURE__ */ new Set(["type", "turnId", "snapshot"])],
24707
+ ["item.detached", /* @__PURE__ */ new Set(["type", "turnId", "itemId"])],
23947
24708
  ["interaction.closed", /* @__PURE__ */ new Set(["type", "interactionId", "turnId", "reason"])],
23948
24709
  ["turn.completed", /* @__PURE__ */ new Set(["type", "turnId", "nativeTurnRef", "outcome"])],
23949
24710
  ["session.faulted", /* @__PURE__ */ new Set(["type", "error"])]
@@ -24060,7 +24821,7 @@ function parseSessionMetadata(value) {
24060
24821
  };
24061
24822
  }
24062
24823
  async function readDescriptor(descriptorPath) {
24063
- const metadata = await lstat2(descriptorPath);
24824
+ const metadata = await lstat3(descriptorPath);
24064
24825
  if (metadata.isSymbolicLink())
24065
24826
  throw new Error("Aqua Harness broker descriptor must not be a symlink");
24066
24827
  if (!metadata.isFile())
@@ -24072,12 +24833,12 @@ async function readDescriptor(descriptorPath) {
24072
24833
  throw new Error("Aqua Harness broker descriptor belongs to another user");
24073
24834
  }
24074
24835
  }
24075
- const descriptor = harnessBrokerDescriptorSchema.parse(JSON.parse(await readFile3(descriptorPath, "utf8")));
24836
+ const descriptor = harnessBrokerDescriptorSchema.parse(JSON.parse(await readFile5(descriptorPath, "utf8")));
24076
24837
  if (process.platform === "darwin" && Buffer.byteLength(descriptor.socketPath) > 103) {
24077
24838
  throw new Error("Aqua Harness broker socket path is too long for macOS");
24078
24839
  }
24079
24840
  if (process.platform !== "win32") {
24080
- const socket = await lstat2(descriptor.socketPath);
24841
+ const socket = await lstat3(descriptor.socketPath);
24081
24842
  if (socket.isSymbolicLink() || !socket.isSocket()) {
24082
24843
  throw new Error("Aqua Harness broker endpoint is not a Unix socket");
24083
24844
  }
@@ -24512,6 +25273,7 @@ var BrokeredHarnessAdapter = class {
24512
25273
  if (this.#forwardEnvironment && input.environment) {
24513
25274
  const allowed = [
24514
25275
  "CODEXHOST_CLI_PATH",
25276
+ "CODEXHOST_CLI_NODE_PATH",
24515
25277
  "CODEXHOST_RUNTIME_ENDPOINT",
24516
25278
  "CODEXHOST_RUNTIME_TOKEN",
24517
25279
  "CODEXHOST_THREAD_ID"
@@ -24577,7 +25339,11 @@ function createHarnessAdapter(context) {
24577
25339
  liveCommandCatalog: true,
24578
25340
  environment: { ...context.environment }
24579
25341
  });
24580
- return new CodeBuddyAdapter({ environment: { ...context.environment } });
25342
+ const environment = { ...context.environment };
25343
+ return Object.assign(new CodeBuddyAdapter({ environment }), {
25344
+ installation: createCodeBuddyInstallation(environment),
25345
+ install: createHarnessInstaller(environment, { npm: "@tencent-ai/codebuddy-code" })
25346
+ });
24581
25347
  }
24582
25348
  export {
24583
25349
  createHarnessAdapter