@codexhost/cli-linux-arm64 0.10.2 → 0.11.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.
@@ -771,10 +771,10 @@ function mergeDefs(...defs) {
771
771
  function cloneDef(schema) {
772
772
  return mergeDefs(schema._zod.def);
773
773
  }
774
- function getElementAtPath(obj, path8) {
775
- if (!path8)
774
+ function getElementAtPath(obj, path9) {
775
+ if (!path9)
776
776
  return obj;
777
- return path8.reduce((acc, key) => acc?.[key], obj);
777
+ return path9.reduce((acc, key) => acc?.[key], obj);
778
778
  }
779
779
  function promiseAllObject(promisesObj) {
780
780
  const keys = Object.keys(promisesObj);
@@ -1183,11 +1183,11 @@ function explicitlyAborted(x, startIndex = 0) {
1183
1183
  }
1184
1184
  return false;
1185
1185
  }
1186
- function prefixIssues(path8, issues) {
1186
+ function prefixIssues(path9, issues) {
1187
1187
  return issues.map((iss) => {
1188
1188
  var _a3;
1189
1189
  (_a3 = iss).path ?? (_a3.path = []);
1190
- iss.path.unshift(path8);
1190
+ iss.path.unshift(path9);
1191
1191
  return iss;
1192
1192
  });
1193
1193
  }
@@ -1334,16 +1334,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1334
1334
  }
1335
1335
  function formatError(error51, mapper = (issue2) => issue2.message) {
1336
1336
  const fieldErrors = { _errors: [] };
1337
- const processError = (error52, path8 = []) => {
1337
+ const processError = (error52, path9 = []) => {
1338
1338
  for (const issue2 of error52.issues) {
1339
1339
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1340
- issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
1340
+ issue2.errors.map((issues) => processError({ issues }, [...path9, ...issue2.path]));
1341
1341
  } else if (issue2.code === "invalid_key") {
1342
- processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
1342
+ processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1343
1343
  } else if (issue2.code === "invalid_element") {
1344
- processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
1344
+ processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1345
1345
  } else {
1346
- const fullpath = [...path8, ...issue2.path];
1346
+ const fullpath = [...path9, ...issue2.path];
1347
1347
  if (fullpath.length === 0) {
1348
1348
  fieldErrors._errors.push(mapper(issue2));
1349
1349
  } else {
@@ -1370,17 +1370,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1370
1370
  }
1371
1371
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1372
1372
  const result = { errors: [] };
1373
- const processError = (error52, path8 = []) => {
1373
+ const processError = (error52, path9 = []) => {
1374
1374
  var _a3, _b;
1375
1375
  for (const issue2 of error52.issues) {
1376
1376
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1377
- issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
1377
+ issue2.errors.map((issues) => processError({ issues }, [...path9, ...issue2.path]));
1378
1378
  } else if (issue2.code === "invalid_key") {
1379
- processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
1379
+ processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1380
1380
  } else if (issue2.code === "invalid_element") {
1381
- processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
1381
+ processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
1382
1382
  } else {
1383
- const fullpath = [...path8, ...issue2.path];
1383
+ const fullpath = [...path9, ...issue2.path];
1384
1384
  if (fullpath.length === 0) {
1385
1385
  result.errors.push(mapper(issue2));
1386
1386
  continue;
@@ -1412,8 +1412,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
1412
1412
  }
1413
1413
  function toDotPath(_path) {
1414
1414
  const segs = [];
1415
- const path8 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1416
- for (const seg of path8) {
1415
+ const path9 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1416
+ for (const seg of path9) {
1417
1417
  if (typeof seg === "number")
1418
1418
  segs.push(`[${seg}]`);
1419
1419
  else if (typeof seg === "symbol")
@@ -14105,13 +14105,13 @@ function resolveRef(ref, ctx) {
14105
14105
  if (!ref.startsWith("#")) {
14106
14106
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14107
14107
  }
14108
- const path8 = ref.slice(1).split("/").filter(Boolean);
14109
- if (path8.length === 0) {
14108
+ const path9 = ref.slice(1).split("/").filter(Boolean);
14109
+ if (path9.length === 0) {
14110
14110
  return ctx.rootSchema;
14111
14111
  }
14112
14112
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14113
- if (path8[0] === defsKey) {
14114
- const key = path8[1];
14113
+ if (path9[0] === defsKey) {
14114
+ const key = path9[1];
14115
14115
  if (!key || !ctx.defs[key]) {
14116
14116
  throw new Error(`Reference not found: ${ref}`);
14117
14117
  }
@@ -14574,6 +14574,55 @@ var credentialImportsParamsSchema = external_exports.object({
14574
14574
  request: credentialImportsRequestSchema
14575
14575
  }).strict();
14576
14576
 
14577
+ // ../../shared-contracts/dist/harness-display-settings.js
14578
+ var harnessDisplayEntriesSchema = external_exports.array(external_exports.strictObject({
14579
+ agent: external_exports.string().min(1).max(128),
14580
+ section: external_exports.enum(["main", "more", "auto"])
14581
+ })).max(256).refine((entries) => new Set(entries.map((entry) => entry.agent)).size === entries.length, "Duplicate Harness IDs");
14582
+ var harnessDisplaySettingsSchema = external_exports.strictObject({
14583
+ entries: harnessDisplayEntriesSchema.nullable()
14584
+ });
14585
+ var harnessDisplayGetSchema = external_exports.strictObject({});
14586
+ var harnessDisplaySetSchema = external_exports.strictObject({
14587
+ entries: harnessDisplayEntriesSchema,
14588
+ /** Import legacy Desktop preferences only if no shared settings exist yet. */
14589
+ initializeOnly: external_exports.boolean().optional()
14590
+ });
14591
+
14592
+ // ../../shared-contracts/dist/console.js
14593
+ var consoleAnnouncementSchema = external_exports.strictObject({
14594
+ title: external_exports.string().trim().min(1).max(200),
14595
+ type: external_exports.enum(["info", "warning", "danger"]),
14596
+ body: external_exports.string().trim().min(1).max(16 * 1024)
14597
+ });
14598
+ var consoleOpenParamsSchema = external_exports.strictObject({});
14599
+ var consoleOpenResultSchema = external_exports.strictObject({
14600
+ /** The console address. */
14601
+ url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
14602
+ });
14603
+ var CONSOLE_HOST_METHODS = Object.freeze([
14604
+ "codexhost/harness/plugins/list",
14605
+ "codexhost/harness/display-settings/get",
14606
+ "codexhost/harness/display-settings/set",
14607
+ "codexhost/harness/inspect",
14608
+ "codexhost/harness/launch-settings/get",
14609
+ "codexhost/harness/launch-settings/set",
14610
+ "codexhost/harness/web-ui/open",
14611
+ "codexhost/harness/accounts/sources",
14612
+ "codexhost/harness/accounts/list",
14613
+ "codexhost/harness/accounts/inspect",
14614
+ "codexhost/harness/credential-imports",
14615
+ "codexhost/harness/session-import/sources",
14616
+ "codexhost/harness/session-import/list",
14617
+ "codexhost/harness/session-import/import",
14618
+ "codexhost/account/list",
14619
+ "codexhost/account/refresh",
14620
+ "codexhost/account/usage/inspect",
14621
+ "codexhost/update/check",
14622
+ "codexhost/update/start",
14623
+ "codexhost/update/status"
14624
+ ]);
14625
+
14577
14626
  // ../../shared-contracts/dist/version.js
14578
14627
  var WORKSPACE_CONTRACT_VERSION = 1;
14579
14628
 
@@ -14627,6 +14676,12 @@ var hostTurnIdSchema = opaqueIdSchema.brand();
14627
14676
  var hostItemIdSchema = opaqueIdSchema.brand();
14628
14677
  var hostInteractionIdSchema = opaqueIdSchema.brand();
14629
14678
 
14679
+ // ../../shared-contracts/dist/manual-compaction.js
14680
+ var threadManualCompactionStartedSchema = external_exports.strictObject({
14681
+ threadId: hostThreadIdSchema,
14682
+ turnId: hostTurnIdSchema
14683
+ });
14684
+
14630
14685
  // ../../shared-contracts/dist/thread-usage.js
14631
14686
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
14632
14687
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
@@ -14687,6 +14742,10 @@ var threadUsageSnapshotSchema = external_exports.object({
14687
14742
  var usagePercentSchema = external_exports.number().finite().min(0).max(100);
14688
14743
  var accountCreditsProductUsageSchema = external_exports.object({
14689
14744
  product: external_exports.string().min(1),
14745
+ used: external_exports.number().finite().nonnegative().optional(),
14746
+ // Zero is a real empty cap, not an absent field.
14747
+ limit: external_exports.number().finite().nonnegative().optional(),
14748
+ unit: external_exports.string().min(1).max(32).optional(),
14690
14749
  usagePercent: usagePercentSchema,
14691
14750
  resetsAt: external_exports.string().min(1).optional()
14692
14751
  }).strict();
@@ -14696,6 +14755,10 @@ var accountResetCreditsSchema = external_exports.object({
14696
14755
  expiresAt: external_exports.array(external_exports.string().min(1)).min(1).max(32).optional()
14697
14756
  }).strict();
14698
14757
  var accountCreditsSnapshotSchema = external_exports.object({
14758
+ used: external_exports.number().finite().nonnegative().optional(),
14759
+ // Zero is a real empty cap, not an absent field.
14760
+ limit: external_exports.number().finite().nonnegative().optional(),
14761
+ unit: external_exports.string().min(1).max(32).optional(),
14699
14762
  /** Native label when the primary limit is scoped to a model or product group. */
14700
14763
  label: external_exports.string().min(1).optional(),
14701
14764
  usedPercent: usagePercentSchema,
@@ -14715,12 +14778,27 @@ var threadUsageInspectionSchema = external_exports.object({
14715
14778
  }).strict();
14716
14779
 
14717
14780
  // ../../shared-contracts/dist/harness-accounts.js
14718
- var harnessAccountSnapshotSchema = external_exports.object({
14781
+ var accountBalanceSnapshotSchema = external_exports.object({
14782
+ amount: external_exports.number().finite().nonnegative(),
14783
+ /** ISO 4217 code as reported by the Provider, for example `CNY`. */
14784
+ currency: external_exports.string().trim().min(1).max(8),
14785
+ /** Native label when the Harness exposes several Billing Sources. */
14786
+ label: external_exports.string().trim().min(1).max(128).optional()
14787
+ }).strict();
14788
+ var harnessAccountSnapshotObject = external_exports.object({
14719
14789
  email: external_exports.string().trim().min(1).max(320).optional(),
14720
14790
  label: external_exports.string().trim().min(1).max(256).optional(),
14721
14791
  plan: external_exports.string().trim().min(1).max(128).optional(),
14722
- credits: accountCreditsSnapshotSchema
14792
+ credits: accountCreditsSnapshotSchema.optional(),
14793
+ balance: accountBalanceSnapshotSchema.optional()
14723
14794
  }).strict();
14795
+ function requireReportedQuota(schema) {
14796
+ return schema.refine((value) => {
14797
+ const reported = value;
14798
+ return reported.credits !== void 0 || reported.balance !== void 0;
14799
+ }, { message: "Account must report either credits or a balance" });
14800
+ }
14801
+ var harnessAccountSnapshotSchema = requireReportedQuota(harnessAccountSnapshotObject);
14724
14802
  var harnessAccountIdentityShape = {
14725
14803
  harnessId: harnessIdSchema,
14726
14804
  harnessName: external_exports.string().trim().min(1).max(128)
@@ -14731,11 +14809,13 @@ var harnessAccountSourceListResultSchema = external_exports.object({ sources: ex
14731
14809
  var harnessAccountInspectParamsSchema = external_exports.object({ harnessId: harnessIdSchema, refresh: external_exports.boolean().optional() }).strict();
14732
14810
  var harnessAccountInspectResultSchema = external_exports.object({
14733
14811
  ...harnessAccountIdentityShape,
14734
- account: harnessAccountSnapshotSchema.nullable()
14812
+ account: harnessAccountSnapshotSchema.nullable(),
14813
+ /** Every Billing Source from one Harness; `account` remains the first for older clients. */
14814
+ accounts: external_exports.array(harnessAccountSnapshotSchema).max(8).optional()
14735
14815
  }).strict();
14736
14816
  var harnessAccountListParamsSchema = external_exports.object({ refresh: external_exports.boolean().optional() }).strict();
14737
14817
  var harnessAccountListResultSchema = external_exports.object({
14738
- accounts: external_exports.array(harnessAccountSnapshotSchema.extend(harnessAccountIdentityShape)).max(128)
14818
+ accounts: external_exports.array(requireReportedQuota(harnessAccountSnapshotObject.extend(harnessAccountIdentityShape))).max(128)
14739
14819
  }).strict();
14740
14820
 
14741
14821
  // ../../shared-contracts/dist/json-value.js
@@ -14873,6 +14953,8 @@ var harnessModelSchema = external_exports.object({
14873
14953
  ref: harnessModelRefSchema,
14874
14954
  label: nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH),
14875
14955
  resolvedModelLabel: harnessResolvedModelLabelSchema.optional(),
14956
+ /** Optional opaque selection for this same Model with priority processing enabled. */
14957
+ fastModel: harnessModelRefSchema.optional(),
14876
14958
  supportedThinkingOptionIds: external_exports.array(harnessThinkingOptionIdSchema).optional()
14877
14959
  }).strict();
14878
14960
  var harnessThinkingOptionsSchema = external_exports.array(harnessThinkingOptionSchema).superRefine((options, context) => {
@@ -14905,6 +14987,16 @@ var harnessModelCatalogSchema = external_exports.object({
14905
14987
  });
14906
14988
  }
14907
14989
  refs.add(model.ref.id);
14990
+ if (model.fastModel) {
14991
+ if (refs.has(model.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model.fastModel?.id)) {
14992
+ context.addIssue({
14993
+ code: "custom",
14994
+ message: "Fast Model refs must be distinct and unique",
14995
+ path: ["models", index, "fastModel"]
14996
+ });
14997
+ }
14998
+ refs.add(model.fastModel.id);
14999
+ }
14908
15000
  const supportedThinkingIds = /* @__PURE__ */ new Set();
14909
15001
  for (const [optionIndex, optionId] of (model.supportedThinkingOptionIds ?? []).entries()) {
14910
15002
  if (supportedThinkingIds.has(optionId)) {
@@ -15024,11 +15116,13 @@ var threadThinkingSelectParamsSchema = external_exports.object({
15024
15116
  thinkingOptionId: harnessThinkingOptionIdSchema
15025
15117
  }).strict();
15026
15118
  var threadInspectionParamsSchema = external_exports.object({
15027
- threadId: hostThreadIdSchema
15119
+ threadId: hostThreadIdSchema,
15120
+ includeReferenceCapability: external_exports.boolean().optional()
15028
15121
  }).strict();
15029
15122
  var codexThreadInspectionSchema = external_exports.object({
15030
15123
  owner: external_exports.literal("codex"),
15031
- locked: external_exports.literal(true)
15124
+ locked: external_exports.literal(true),
15125
+ supportsThreadReferences: external_exports.literal(true).optional()
15032
15126
  }).strict();
15033
15127
  var externalThreadInspectionSchema = external_exports.object({
15034
15128
  owner: external_exports.literal("external"),
@@ -15154,6 +15248,19 @@ var harnessLaunchSettingsSchema = external_exports.object({
15154
15248
  restartRequired: external_exports.boolean()
15155
15249
  }).strict();
15156
15250
 
15251
+ // ../../shared-contracts/dist/harness-installation.js
15252
+ var harnessInstallationParamsSchema = external_exports.object({
15253
+ harnessId: harnessIdSchema,
15254
+ action: external_exports.enum(["check", "update"])
15255
+ }).strict();
15256
+ var harnessInstallationStateSchema = external_exports.object({
15257
+ currentVersion: external_exports.string().min(1).max(128),
15258
+ latestVersion: external_exports.string().min(1).max(128),
15259
+ updateAvailable: external_exports.boolean(),
15260
+ canUpdate: external_exports.boolean(),
15261
+ message: external_exports.string().max(2048).optional()
15262
+ }).strict();
15263
+
15157
15264
  // ../../shared-contracts/dist/codex-accounts.js
15158
15265
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
15159
15266
  var nonBlankTextSchema3 = external_exports.string().trim().min(1);
@@ -15876,7 +15983,7 @@ function commandPrompt(command, catalog, profile = CODEBUDDY_RUNTIME_PROFILE) {
15876
15983
  import { stat as stat2 } from "node:fs/promises";
15877
15984
 
15878
15985
  // dist/acp-client.js
15879
- import { execFile, spawn } from "node:child_process";
15986
+ import { execFile as execFile2, spawn } from "node:child_process";
15880
15987
  import { Readable as Readable2, Writable } from "node:stream";
15881
15988
 
15882
15989
  // ../../../node_modules/@agentclientprotocol/sdk/dist/schema/index.js
@@ -20341,6 +20448,195 @@ function resolveHarnessExecutable(spec, input, dependencies = {}) {
20341
20448
  return void 0;
20342
20449
  }
20343
20450
 
20451
+ // ../../harness-discovery/dist/installation.js
20452
+ import { execFile } from "node:child_process";
20453
+ import { homedir } from "node:os";
20454
+ function runInstallationCommand(command, args, environment, timeout = 3e4) {
20455
+ const env = withNodeRuntimeOnPath(environment);
20456
+ const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
20457
+ return new Promise((resolve, reject) => {
20458
+ const child = execFile(invocation.command, invocation.arguments, {
20459
+ env,
20460
+ cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
20461
+ encoding: "utf8",
20462
+ timeout,
20463
+ killSignal: "SIGKILL",
20464
+ maxBuffer: 1024 * 1024,
20465
+ windowsHide: true,
20466
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments
20467
+ }, (error51, stdout, stderr) => {
20468
+ if (error51)
20469
+ reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
20470
+ else
20471
+ resolve((stdout || stderr).trim());
20472
+ });
20473
+ child.stdin?.end();
20474
+ });
20475
+ }
20476
+ function installationVersion(value) {
20477
+ if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
20478
+ throw new Error("Harness returned an invalid version");
20479
+ return value.trim().replace(/^v/, "");
20480
+ }
20481
+ function versionFromOutput(output) {
20482
+ return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
20483
+ }
20484
+ function newerInstallationVersion(current, latest) {
20485
+ const a = installationVersion(current).replace(/\+.*/, "");
20486
+ const b = installationVersion(latest).replace(/\+.*/, "");
20487
+ const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
20488
+ const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
20489
+ for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
20490
+ if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
20491
+ return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
20492
+ }
20493
+ const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
20494
+ const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
20495
+ if (!preA.length || !preB.length)
20496
+ return !!preA.length && !preB.length;
20497
+ for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
20498
+ const x = preA[i];
20499
+ const y = preB[i];
20500
+ if (x === y)
20501
+ continue;
20502
+ if (x === void 0 || y === void 0)
20503
+ return x === void 0;
20504
+ const numericX = /^\d+$/.test(x);
20505
+ const numericY = /^\d+$/.test(y);
20506
+ if (numericX && numericY) {
20507
+ if (BigInt(x) === BigInt(y))
20508
+ continue;
20509
+ return BigInt(y) > BigInt(x);
20510
+ }
20511
+ if (numericX !== numericY)
20512
+ return numericX;
20513
+ return y > x;
20514
+ }
20515
+ return false;
20516
+ }
20517
+ function createInstallationManager(options) {
20518
+ let checking;
20519
+ let updating;
20520
+ const check2 = () => checking ??= options.check().finally(() => {
20521
+ checking = void 0;
20522
+ });
20523
+ return (action) => {
20524
+ if (updating)
20525
+ return updating;
20526
+ if (action === "check")
20527
+ return check2();
20528
+ updating = (async () => {
20529
+ const before = await check2();
20530
+ if (!before.updateAvailable)
20531
+ return before;
20532
+ if (!before.canUpdate)
20533
+ throw new Error(before.message ?? "This installation cannot be updated automatically");
20534
+ await options.update(before);
20535
+ const after = await check2();
20536
+ if (after.currentVersion === before.currentVersion)
20537
+ throw new Error("The Harness version did not change; check the native updater and retry");
20538
+ return after;
20539
+ })().finally(() => {
20540
+ updating = void 0;
20541
+ });
20542
+ return updating;
20543
+ };
20544
+ }
20545
+ async function fetchInstallationText(url2) {
20546
+ const request = async () => {
20547
+ const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
20548
+ if (!response.ok)
20549
+ throw new Error("Could not check the latest Harness version");
20550
+ return response.text();
20551
+ };
20552
+ try {
20553
+ return await request();
20554
+ } catch (error51) {
20555
+ if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
20556
+ throw error51;
20557
+ return request();
20558
+ }
20559
+ }
20560
+
20561
+ // ../../harness-discovery/dist/npm-installation.js
20562
+ import { readFile, realpath } from "node:fs/promises";
20563
+ import path4 from "node:path";
20564
+ function referencesNpmBin(shim, name, bin) {
20565
+ if (bin.includes(".."))
20566
+ return false;
20567
+ const target = `node_modules/${name}/${bin.replace(/^\.\//, "")}`.toLowerCase();
20568
+ const text2 = shim.replaceAll("\\", "/").toLowerCase();
20569
+ return text2.includes(`%dp0%/${target}"`) || text2.includes(`%~dp0/${target}"`);
20570
+ }
20571
+ async function npmInstallation(command, packages, environment) {
20572
+ let selected = await realpath(command);
20573
+ if (process.platform === "win32" && /\.(cmd|bat)$/i.test(selected)) {
20574
+ const shim = (await readFile(selected, "utf8")).replaceAll("\\", "/");
20575
+ const root = path4.dirname(selected);
20576
+ for (const name of packages) {
20577
+ const directory2 = path4.join(root, "node_modules", ...name.split("/"));
20578
+ const metadata = await readFile(path4.join(directory2, "package.json"), "utf8").then((text2) => JSON.parse(text2)).catch(() => null);
20579
+ const bins = typeof metadata?.bin === "string" ? [metadata.bin] : Object.values(metadata?.bin ?? {});
20580
+ const bin = bins.find((entry) => referencesNpmBin(shim, name, entry));
20581
+ if (bin) {
20582
+ selected = await realpath(path4.join(directory2, bin));
20583
+ break;
20584
+ }
20585
+ }
20586
+ }
20587
+ let directory = path4.dirname(selected);
20588
+ for (let depth = 0; depth < 8; depth++) {
20589
+ const metadata = await readFile(path4.join(directory, "package.json"), "utf8").then((text2) => JSON.parse(text2)).catch(() => null);
20590
+ if (metadata?.name && packages.includes(metadata.name)) {
20591
+ const name = metadata.name;
20592
+ const currentVersion = installationVersion(metadata.version);
20593
+ const segments = name.split("/");
20594
+ let modules = directory;
20595
+ for (let index = 0; index < segments.length; index++)
20596
+ modules = path4.dirname(modules);
20597
+ const prefix = process.platform === "win32" ? path4.dirname(modules) : path4.dirname(path4.dirname(modules));
20598
+ const globalRoot = process.platform === "win32" ? path4.join(prefix, "node_modules") : path4.join(prefix, "lib", "node_modules");
20599
+ const env = withNodeRuntimeOnPath(environment);
20600
+ const npm = resolveHarnessExecutable({ id: "npm", command: "npm", installRoots: { posix: [], windows: [] } }, { environment: env });
20601
+ let globalInstall = modules === globalRoot;
20602
+ if (process.platform === "win32") {
20603
+ 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);
20604
+ const bins = typeof metadata.bin === "string" ? { [name.split("/").at(-1) ?? name]: metadata.bin } : metadata.bin ?? {};
20605
+ const launchers = await Promise.all(Object.entries(bins).map(async ([bin, entry]) => {
20606
+ if (path4.basename(bin) !== bin || entry.includes(".."))
20607
+ return false;
20608
+ const target = await realpath(path4.join(directory, entry)).catch(() => "");
20609
+ if (target.toLowerCase() !== selected.toLowerCase())
20610
+ return false;
20611
+ const shim = await readFile(path4.join(prefix, `${bin}.cmd`), "utf8").catch(() => "");
20612
+ return referencesNpmBin(shim, name, entry);
20613
+ }));
20614
+ globalInstall = globalInstall && !project && launchers.some(Boolean);
20615
+ }
20616
+ const canUpdate = globalInstall && !!npm;
20617
+ return {
20618
+ prefix,
20619
+ currentVersion,
20620
+ canUpdate,
20621
+ latest: async () => {
20622
+ const data = JSON.parse(await fetchInstallationText(`https://registry.npmjs.org/${encodeURIComponent(name)}/latest`));
20623
+ return installationVersion(data.version);
20624
+ },
20625
+ update: async (version2) => {
20626
+ if (!canUpdate || !npm)
20627
+ throw new Error("Use the original package manager to update this installation");
20628
+ await runInstallationCommand(npm.executable, ["install", "--global", "--prefix", prefix, `${name}@${installationVersion(version2)}`], env, 3e5);
20629
+ }
20630
+ };
20631
+ }
20632
+ const parent = path4.dirname(directory);
20633
+ if (parent === directory)
20634
+ break;
20635
+ directory = parent;
20636
+ }
20637
+ return null;
20638
+ }
20639
+
20344
20640
  // dist/command.js
20345
20641
  var codeBuddyDiscoverySpec = {
20346
20642
  id: "codebuddy",
@@ -20533,7 +20829,7 @@ var CodeBuddyAcpClient = class {
20533
20829
  }
20534
20830
  const pid = this.#child.pid;
20535
20831
  if (pid && process.platform === "win32") {
20536
- await new Promise((resolve) => execFile("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
20832
+ await new Promise((resolve) => execFile2("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => resolve()));
20537
20833
  } else if (pid) {
20538
20834
  try {
20539
20835
  process.kill(-pid, "SIGKILL");
@@ -20625,17 +20921,17 @@ function confirmedConfiguration(response, id, value, profile = CODEBUDDY_RUNTIME
20625
20921
 
20626
20922
  // dist/derivation.js
20627
20923
  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";
20924
+ import { execFile as execFile3, spawn as spawn2 } from "node:child_process";
20925
+ import { lstat, mkdir, readFile as readFile3, realpath as realpath5, unlink, writeFile } from "node:fs/promises";
20926
+ import path6 from "node:path";
20631
20927
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
20632
20928
 
20633
20929
  // dist/history.js
20634
20930
  import { createHash } from "node:crypto";
20635
20931
  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";
20932
+ import { access, readdir, realpath as realpath3 } from "node:fs/promises";
20933
+ import { homedir as homedir2 } from "node:os";
20934
+ import path5 from "node:path";
20639
20935
  import { isDeepStrictEqual } from "node:util";
20640
20936
 
20641
20937
  // ../../../node_modules/diff/libesm/diff/base.js
@@ -20738,16 +21034,16 @@ var Diff = class {
20738
21034
  }
20739
21035
  }
20740
21036
  }
20741
- addToPath(path8, added, removed, oldPosInc, options) {
20742
- const last = path8.lastComponent;
21037
+ addToPath(path9, added, removed, oldPosInc, options) {
21038
+ const last = path9.lastComponent;
20743
21039
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
20744
21040
  return {
20745
- oldPos: path8.oldPos + oldPosInc,
21041
+ oldPos: path9.oldPos + oldPosInc,
20746
21042
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
20747
21043
  };
20748
21044
  } else {
20749
21045
  return {
20750
- oldPos: path8.oldPos + oldPosInc,
21046
+ oldPos: path9.oldPos + oldPosInc,
20751
21047
  lastComponent: { count: 1, added, removed, previousComponent: last }
20752
21048
  };
20753
21049
  }
@@ -21299,9 +21595,9 @@ function codeBuddyDelegation(callId, input, status, childId, displayName = "Code
21299
21595
  }
21300
21596
 
21301
21597
  // dist/file-observation.js
21302
- import { readFile, realpath, stat } from "node:fs/promises";
21598
+ import { readFile as readFile2, realpath as realpath2, stat } from "node:fs/promises";
21303
21599
  async function codeBuddyFileVersion(file2) {
21304
- const [realFile, value] = await Promise.all([realpath(file2), stat(file2, { bigint: true })]);
21600
+ const [realFile, value] = await Promise.all([realpath2(file2), stat(file2, { bigint: true })]);
21305
21601
  return {
21306
21602
  realFile,
21307
21603
  fingerprint: `${value.dev}:${value.ino}:${value.size}:${value.mtimeNs}:${value.ctimeNs}`,
@@ -21315,7 +21611,7 @@ async function readCodeBuddyVersionedText(file2, maximumBytes, tooLargeMessage,
21315
21611
  const observedBefore = before ?? await codeBuddyFileVersion(file2);
21316
21612
  if (observedBefore.size > maximumBytes)
21317
21613
  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;
21614
+ 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
21615
  if (bytesRead > maximumBytes || after.size > maximumBytes)
21320
21616
  throw new CodeBuddyError("unsupported", tooLargeMessage);
21321
21617
  return { contents, reusableVersion };
@@ -21332,15 +21628,15 @@ function codeBuddyCanonicalCwd(cwd) {
21332
21628
  try {
21333
21629
  return realpathSync.native(cwd);
21334
21630
  } catch {
21335
- return path4.resolve(cwd);
21631
+ return path5.resolve(cwd);
21336
21632
  }
21337
21633
  }
21338
21634
  function codeBuddyConfigRoot(environment, profile) {
21339
21635
  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);
21636
+ return configuredRoot || path5.join(environment.HOME || environment.USERPROFILE || homedir2(), profile.defaultConfigDirectoryName);
21341
21637
  }
21342
21638
  function codeBuddyPrimaryHistoryPath(cwd, ref, environment, profile = CODEBUDDY_RUNTIME_PROFILE) {
21343
- return path4.join(codeBuddyConfigRoot(environment, profile), "projects", codeBuddyProjectSlug(cwd, profile), `${ref.nativeSessionId}.jsonl`);
21639
+ return path5.join(codeBuddyConfigRoot(environment, profile), "projects", codeBuddyProjectSlug(cwd, profile), `${ref.nativeSessionId}.jsonl`);
21344
21640
  }
21345
21641
  function derivedLocator(ref) {
21346
21642
  const locator = record2(ref.locator);
@@ -21374,8 +21670,8 @@ function validateNativeRef(ref, profile = CODEBUDDY_RUNTIME_PROFILE) {
21374
21670
  }
21375
21671
  }
21376
21672
  async function sameCwd(left, right) {
21377
- const b = await realpath2(right);
21378
- const a = await realpath2(left).catch((error51) => {
21673
+ const b = await realpath3(right);
21674
+ const a = await realpath3(left).catch((error51) => {
21379
21675
  if (["ENOENT", "ENOTDIR"].includes(String(record2(error51).code)))
21380
21676
  throw new CodeBuddyError("invalidRequest", "Native Session historical working directory is unavailable; ownership cannot be verified");
21381
21677
  throw error51;
@@ -21383,9 +21679,9 @@ async function sameCwd(left, right) {
21383
21679
  return process.platform === "win32" ? a.toLowerCase() === b.toLowerCase() : a === b;
21384
21680
  }
21385
21681
  async function matchesAnyHistoricalCwd(value, candidates) {
21386
- const resolved = path4.resolve(value);
21682
+ const resolved = path5.resolve(value);
21387
21683
  for (const candidate of candidates) {
21388
- const other = path4.resolve(candidate);
21684
+ const other = path5.resolve(candidate);
21389
21685
  if (process.platform === "win32" ? resolved.toLowerCase() === other.toLowerCase() : resolved === other)
21390
21686
  return true;
21391
21687
  try {
@@ -21409,9 +21705,9 @@ async function codeBuddyLiveNativeHistory(cwd, ref, environment, profile = CODEB
21409
21705
  async function codeBuddyHistory(cwd, ref, environment, tolerateIncompleteTail, profile, transaction) {
21410
21706
  validateNativeRef(ref, profile);
21411
21707
  const configRoot = codeBuddyConfigRoot(environment, profile);
21412
- const root = path4.join(configRoot, "projects");
21708
+ const root = path5.join(configRoot, "projects");
21413
21709
  const slug = codeBuddyProjectSlug(cwd, profile);
21414
- const primary = path4.join(root, slug, `${ref.nativeSessionId}.jsonl`);
21710
+ const primary = path5.join(root, slug, `${ref.nativeSessionId}.jsonl`);
21415
21711
  const provenance = derivedLocator(ref);
21416
21712
  let candidates = [];
21417
21713
  try {
@@ -21430,7 +21726,7 @@ async function codeBuddyHistory(cwd, ref, environment, tolerateIncompleteTail, p
21430
21726
  for (const directory of directories) {
21431
21727
  if (!directory.isDirectory())
21432
21728
  continue;
21433
- const file3 = path4.join(root, directory.name, `${ref.nativeSessionId}.jsonl`);
21729
+ const file3 = path5.join(root, directory.name, `${ref.nativeSessionId}.jsonl`);
21434
21730
  try {
21435
21731
  await access(file3);
21436
21732
  candidates.push(file3);
@@ -21445,7 +21741,7 @@ async function codeBuddyHistory(cwd, ref, environment, tolerateIncompleteTail, p
21445
21741
  const file2 = candidates[0];
21446
21742
  if (!file2)
21447
21743
  throw new CodeBuddyError("sessionNotFound", "Native Session history was not found");
21448
- if (profile.historyCapabilities?.fork && !transaction && path4.resolve(file2) !== path4.resolve(primary))
21744
+ if (profile.historyCapabilities?.fork && !transaction && path5.resolve(file2) !== path5.resolve(primary))
21449
21745
  throw new CodeBuddyError("invalidRequest", "Native Session is not stored in the requested working directory");
21450
21746
  const source = await readCodeBuddyVersionedText(file2, 64e6, "Native history exceeds the supported 64 MB snapshot size"), parsed = parseJsonl(source.contents, tolerateIncompleteTail);
21451
21747
  const checkedDirectories = /* @__PURE__ */ new Set();
@@ -21474,7 +21770,7 @@ async function codeBuddyHistory(cwd, ref, environment, tolerateIncompleteTail, p
21474
21770
  }
21475
21771
  }
21476
21772
  } else if (provenance) {
21477
- if (!await sameCwd(provenance.boundCwd, cwd) || provenance.targetProjectSlug !== slug || path4.resolve(file2) !== path4.resolve(primary))
21773
+ if (!await sameCwd(provenance.boundCwd, cwd) || provenance.targetProjectSlug !== slug || path5.resolve(file2) !== path5.resolve(primary))
21478
21774
  throw new CodeBuddyError("invalidRequest", "Derived Native Session target binding changed");
21479
21775
  const active = nativeHistoryRows(parsed.contents);
21480
21776
  if (provenance.inheritedPrefixRows > active.length || nativeRowsDigest(active.slice(0, provenance.inheritedPrefixRows)) !== provenance.inheritedPrefixSha256)
@@ -21768,7 +22064,7 @@ function historyUsage(contents) {
21768
22064
 
21769
22065
  // dist/child-provenance.js
21770
22066
  import { createHash as createHash2 } from "node:crypto";
21771
- import { realpath as realpath3 } from "node:fs/promises";
22067
+ import { realpath as realpath4 } from "node:fs/promises";
21772
22068
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
21773
22069
  var CODEBUDDY_CHILD_MAX_BYTES = 8e6;
21774
22070
  var equalPath = (left, right) => process.platform === "win32" ? left.toLowerCase() === right.toLowerCase() : left === right;
@@ -21836,7 +22132,7 @@ function codeBuddyInheritedChild(parent, childId) {
21836
22132
  async function canonicalCwds(cwds) {
21837
22133
  const result = /* @__PURE__ */ new Map();
21838
22134
  for (const cwd of new Set(cwds)) {
21839
- const canonical = await realpath3(cwd).catch((error51) => {
22135
+ const canonical = await realpath4(cwd).catch((error51) => {
21840
22136
  if (["ENOENT", "ENOTDIR"].includes(String(record2(error51).code)))
21841
22137
  throw new CodeBuddyError("invalidRequest", "Subagent historical working directory is unavailable; ownership cannot be verified");
21842
22138
  throw error51;
@@ -21875,7 +22171,7 @@ async function validateCodeBuddyChildContents(contents, parent, childId, cwd, to
21875
22171
  throw new CodeBuddyError("protocolError", "Inherited Subagent identity changed");
21876
22172
  inheritedEntries = prefixParsed.entries;
21877
22173
  }
21878
- const target = await realpath3(cwd);
22174
+ const target = await realpath4(cwd);
21879
22175
  const inheritedCwds = inheritedEntries.flatMap((row) => typeof row.cwd === "string" ? [row.cwd] : []);
21880
22176
  const suffixCwds = parsed.entries.slice(inheritedEntries.length).flatMap((row) => typeof row.cwd === "string" ? [row.cwd] : []);
21881
22177
  const canonical = await canonicalCwds(suffixCwds);
@@ -22011,7 +22307,7 @@ async function copyCodeBuddySession(cwd, sourceId, targetId, environment, signal
22011
22307
  child.stderr.destroy();
22012
22308
  } else if (process.platform === "win32" && child.pid) {
22013
22309
  termination = new Promise((done) => {
22014
- execFile2("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
22310
+ execFile3("taskkill", ["/PID", String(child.pid), "/T", "/F"], { windowsHide: true, timeout: 3e3 }, () => {
22015
22311
  child.kill();
22016
22312
  done();
22017
22313
  });
@@ -22118,20 +22414,20 @@ async function bridgeCopyToTarget(sourceCwd, targetCwd, ref, contents, environme
22118
22414
  const targetFile = codeBuddyPrimaryHistoryPath(targetCwd, ref, environment, profile);
22119
22415
  if (sameResolvedPath(sourceFile, targetFile))
22120
22416
  return void 0;
22121
- const targetDirectory = path5.dirname(targetFile);
22122
- const projectsDirectory = path5.dirname(targetDirectory);
22417
+ const targetDirectory = path6.dirname(targetFile);
22418
+ const projectsDirectory = path6.dirname(targetDirectory);
22123
22419
  await mkdir(targetDirectory, { recursive: true });
22124
22420
  const [realProjects, realTargetDirectory] = await Promise.all([
22125
- realpath4(projectsDirectory),
22126
- realpath4(targetDirectory)
22421
+ realpath5(projectsDirectory),
22422
+ realpath5(targetDirectory)
22127
22423
  ]);
22128
- if (!sameResolvedPath(realTargetDirectory, path5.join(realProjects, codeBuddyProjectSlug(targetCwd, profile))))
22424
+ if (!sameResolvedPath(realTargetDirectory, path6.join(realProjects, codeBuddyProjectSlug(targetCwd, profile))))
22129
22425
  throw new CodeBuddyError("invalidRequest", "Cross-directory history bridge target escaped the native projects root");
22130
22426
  const expected = Buffer.from(contents, "utf8");
22131
22427
  await writeFile(targetFile, expected, { flag: "wx", mode: 384 });
22132
22428
  const bridge = { file: targetFile, expected };
22133
22429
  try {
22134
- const persisted = await readFile2(targetFile);
22430
+ const persisted = await readFile3(targetFile);
22135
22431
  if (!isDeepStrictEqual3(persisted, expected))
22136
22432
  throw new CodeBuddyError("nativeFailure", "Cross-directory history bridge changed native bytes");
22137
22433
  return bridge;
@@ -22146,7 +22442,7 @@ async function cleanupBridge(bridge) {
22146
22442
  const info = await lstat(bridge.file);
22147
22443
  if (!info.isFile() || process.platform !== "win32" && (info.mode & 63) !== 0)
22148
22444
  return;
22149
- if (!isDeepStrictEqual3(await readFile2(bridge.file), bridge.expected))
22445
+ if (!isDeepStrictEqual3(await readFile3(bridge.file), bridge.expected))
22150
22446
  return;
22151
22447
  await unlink(bridge.file);
22152
22448
  } catch (error51) {
@@ -22232,7 +22528,7 @@ function assertChildRanges(rows2, child) {
22232
22528
  }
22233
22529
  }
22234
22530
  async function plainDirectory(parent, name) {
22235
- const directory = path5.join(parent, name);
22531
+ const directory = path6.join(parent, name);
22236
22532
  await mkdir(directory, { mode: 448 }).catch((error51) => {
22237
22533
  if (record2(error51).code !== "EEXIST")
22238
22534
  throw error51;
@@ -22240,7 +22536,7 @@ async function plainDirectory(parent, name) {
22240
22536
  const info = await lstat(directory);
22241
22537
  if (!info.isDirectory() || info.isSymbolicLink() || process.platform !== "win32" && (info.mode & 18) !== 0)
22242
22538
  throw new CodeBuddyError("invalidRequest", "Redirected native Subagent directory");
22243
- const actual = await realpath4(directory);
22539
+ const actual = await realpath5(directory);
22244
22540
  if (!sameResolvedPath(actual, directory))
22245
22541
  throw new CodeBuddyError("invalidRequest", "Redirected native Subagent directory");
22246
22542
  return directory;
@@ -22249,7 +22545,7 @@ async function verifiedChildFile(file2, expected) {
22249
22545
  const info = await lstat(file2);
22250
22546
  if (!info.isFile() || info.isSymbolicLink() || process.platform !== "win32" && (info.mode & 63) !== 0)
22251
22547
  throw new CodeBuddyError("invalidRequest", "Unsafe derived Subagent transcript");
22252
- if (!sameResolvedPath(await realpath4(file2), file2))
22548
+ if (!sameResolvedPath(await realpath5(file2), file2))
22253
22549
  throw new CodeBuddyError("invalidRequest", "Redirected derived Subagent transcript");
22254
22550
  const before = await codeBuddyFileVersion(file2);
22255
22551
  const actual = await readCodeBuddyVersionedText(file2, CODEBUDDY_CHILD_MAX_BYTES, "Subagent transcript exceeds 8 MB", before);
@@ -22277,19 +22573,19 @@ async function copyInheritedChildren(options) {
22277
22573
  const { references } = options;
22278
22574
  if (!references.length)
22279
22575
  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`)))
22576
+ const sourceHistoryFile = await realpath5(options.sourceHistoryFile);
22577
+ const sourceProject = path6.dirname(sourceHistoryFile);
22578
+ if (!sameResolvedPath(sourceHistoryFile, path6.join(sourceProject, `${options.sourceRef.nativeSessionId}.jsonl`)))
22283
22579
  throw new CodeBuddyError("invalidRequest", "Unexpected source history location");
22284
- const sourceDirectory = path5.join(sourceProject, options.sourceRef.nativeSessionId, "subagents");
22580
+ const sourceDirectory = path6.join(sourceProject, options.sourceRef.nativeSessionId, "subagents");
22285
22581
  const sourceDirectoryInfo = await lstat(sourceDirectory);
22286
22582
  if (!sourceDirectoryInfo.isDirectory() || sourceDirectoryInfo.isSymbolicLink())
22287
22583
  throw new CodeBuddyError("invalidRequest", "Redirected source Subagent directory");
22288
- if (!sameResolvedPath(await realpath4(sourceDirectory), sourceDirectory))
22584
+ if (!sameResolvedPath(await realpath5(sourceDirectory), sourceDirectory))
22289
22585
  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`)))
22586
+ const targetHistoryFile = await realpath5(options.targetHistoryFile);
22587
+ const targetProject = path6.dirname(targetHistoryFile);
22588
+ if (!sameResolvedPath(targetHistoryFile, path6.join(targetProject, `${options.targetRef.nativeSessionId}.jsonl`)))
22293
22589
  throw new CodeBuddyError("invalidRequest", "Unexpected target history location");
22294
22590
  const targetSessionDirectory = await plainDirectory(targetProject, options.targetRef.nativeSessionId);
22295
22591
  const targetDirectory = await plainDirectory(targetSessionDirectory, "subagents");
@@ -22297,7 +22593,7 @@ async function copyInheritedChildren(options) {
22297
22593
  const created = [];
22298
22594
  try {
22299
22595
  for (const reference of references) {
22300
- const sourceFile = path5.join(sourceDirectory, `${reference.childId}.jsonl`);
22596
+ const sourceFile = path6.join(sourceDirectory, `${reference.childId}.jsonl`);
22301
22597
  const sourceInfo = await lstat(sourceFile);
22302
22598
  if (!sourceInfo.isFile() || sourceInfo.isSymbolicLink())
22303
22599
  throw new CodeBuddyError("invalidRequest", "Redirected source Subagent transcript");
@@ -22316,7 +22612,7 @@ async function copyInheritedChildren(options) {
22316
22612
  throw new CodeBuddyError("protocolError", "Missing Agent result child range");
22317
22613
  const prefix = await codeBuddyChildPrefixThrough(source.contents, last, validated);
22318
22614
  const expected = Buffer.from(prefix.contents, "utf8");
22319
- const targetFile = path5.join(targetDirectory, `${reference.childId}.jsonl`);
22615
+ const targetFile = path6.join(targetDirectory, `${reference.childId}.jsonl`);
22320
22616
  const copy = await persistChildCopy(targetFile, expected);
22321
22617
  if (copy)
22322
22618
  created.push(copy);
@@ -22695,8 +22991,8 @@ var CodeBuddyInteractions = class {
22695
22991
  };
22696
22992
 
22697
22993
  // dist/subagent-history.js
22698
- import { readdir as readdir2, realpath as realpath5 } from "node:fs/promises";
22699
- import path6 from "node:path";
22994
+ import { readdir as readdir2, realpath as realpath6 } from "node:fs/promises";
22995
+ import path7 from "node:path";
22700
22996
  var equalPath2 = (a, b) => process.platform === "win32" ? a.toLowerCase() === b.toLowerCase() : a === b;
22701
22997
  var MAX_CACHED_CHILDREN = 16;
22702
22998
  var CodeBuddyChildObserver = class {
@@ -22723,9 +23019,9 @@ var CodeBuddyChildObserver = class {
22723
23019
  throw new CodeBuddyError("invalidRequest", "Subagent observer is closed");
22724
23020
  }
22725
23021
  async #validateWorkspaces(cwds) {
22726
- const expected = await realpath5(this.cwd);
23022
+ const expected = await realpath6(this.cwd);
22727
23023
  for (const cwd of new Set(cwds)) {
22728
- const actual = await realpath5(cwd).catch((error51) => {
23024
+ const actual = await realpath6(cwd).catch((error51) => {
22729
23025
  if (["ENOENT", "ENOTDIR"].includes(String(record2(error51).code)))
22730
23026
  throw new CodeBuddyError("invalidRequest", "Native Session historical working directory is unavailable; ownership cannot be verified");
22731
23027
  throw error51;
@@ -22760,9 +23056,9 @@ var CodeBuddyChildObserver = class {
22760
23056
  }
22761
23057
  async #directory() {
22762
23058
  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);
23059
+ const project = path7.dirname(await realpath6(history.file));
23060
+ const expected = path7.join(project, this.parent.nativeSessionId, "subagents");
23061
+ const actual = await realpath6(expected);
22766
23062
  this.#assertOpen();
22767
23063
  if (!equalPath2(actual, expected))
22768
23064
  throw new CodeBuddyError("invalidRequest", `Redirected ${this.profile.displayName} Subagent directory`);
@@ -22771,7 +23067,7 @@ var CodeBuddyChildObserver = class {
22771
23067
  async #child(directory, childId) {
22772
23068
  if (!validCodeBuddyChildId(childId))
22773
23069
  throw new CodeBuddyError("invalidRequest", "Invalid native Subagent ID");
22774
- const file2 = path6.join(directory, `${childId}.jsonl`);
23070
+ const file2 = path7.join(directory, `${childId}.jsonl`);
22775
23071
  const before = await codeBuddyFileVersion(file2);
22776
23072
  if (!equalPath2(before.realFile, file2))
22777
23073
  throw new CodeBuddyError("invalidRequest", "Redirected Subagent transcript");
@@ -23655,9 +23951,40 @@ var CodeBuddyAdapter = class {
23655
23951
  }
23656
23952
  };
23657
23953
 
23954
+ // dist/installation.js
23955
+ function createCodeBuddyInstallation(environment) {
23956
+ let update;
23957
+ return createInstallationManager({
23958
+ async check() {
23959
+ const resolved = resolveHarnessExecutable(codeBuddyDiscoverySpec, { environment });
23960
+ if (!resolved)
23961
+ throw new Error("CodeBuddy is not installed");
23962
+ const currentVersion = versionFromOutput(await runInstallationCommand(resolved.executable, ["--version"], environment));
23963
+ const npm = await npmInstallation(resolved.executable, ["@tencent-ai/codebuddy-code"], environment);
23964
+ update = npm?.update;
23965
+ const latestVersion = npm ? await npm.latest() : "Unknown";
23966
+ const canUpdate = npm?.canUpdate ?? false;
23967
+ return {
23968
+ currentVersion,
23969
+ latestVersion,
23970
+ updateAvailable: !!npm && newerInstallationVersion(currentVersion, latestVersion),
23971
+ canUpdate,
23972
+ ...!canUpdate ? {
23973
+ message: "Use CodeBuddy's native updater or original package manager for this installation. Latest-version checks here require an identified npm installation."
23974
+ } : {}
23975
+ };
23976
+ },
23977
+ async update(state) {
23978
+ if (!update)
23979
+ throw new Error("This CodeBuddy installation requires a manual update");
23980
+ await update(state.latestVersion);
23981
+ }
23982
+ });
23983
+ }
23984
+
23658
23985
  // ../../harness-broker/dist/client.js
23659
23986
  import { randomUUID as randomUUID2 } from "node:crypto";
23660
- import { lstat as lstat2, readFile as readFile3 } from "node:fs/promises";
23987
+ import { lstat as lstat2, readFile as readFile4 } from "node:fs/promises";
23661
23988
  import net, {} from "node:net";
23662
23989
 
23663
23990
  // ../../harness-broker/dist/protocol.js
@@ -23772,24 +24099,25 @@ function consumeBrokerFrames(socket, onFrame, onError) {
23772
24099
 
23773
24100
  // ../../harness-broker/dist/paths.js
23774
24101
  import os2 from "node:os";
23775
- import path7 from "node:path";
24102
+ import path8 from "node:path";
23776
24103
  var HARNESS_BROKER_DESCRIPTOR_ENV = "CODEXHOST_CLAUDE_BROKER_DESCRIPTOR";
23777
24104
  var HARNESS_BROKER_DESCRIPTOR_FILE = "claude-code-broker-v1.json";
23778
24105
  function defaultHarnessBrokerDirectory(environment = process.env) {
23779
24106
  const home = environment.HOME || os2.homedir();
23780
- return path7.join(home, ".codexhost", "harness-broker");
24107
+ return path8.join(home, ".codexhost", "harness-broker");
23781
24108
  }
23782
24109
  function defaultHarnessBrokerDescriptorPath(environment = process.env, harnessId = "claude-code") {
23783
24110
  harnessPluginIdSchema.parse(harnessId);
23784
24111
  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);
24112
+ return path8.join(defaultHarnessBrokerDirectory(environment), `${harnessId}-broker-v1.json`);
24113
+ return environment[HARNESS_BROKER_DESCRIPTOR_ENV] ?? path8.join(defaultHarnessBrokerDirectory(environment), HARNESS_BROKER_DESCRIPTOR_FILE);
23787
24114
  }
23788
24115
 
23789
24116
  // ../../harness-broker/dist/validation.js
23790
24117
  var cwdSchema = external_exports.string().min(1).max(16384);
23791
24118
  var brokerEnvironmentSchema = external_exports.object({
23792
24119
  CODEXHOST_CLI_PATH: external_exports.string().max(16384).optional(),
24120
+ CODEXHOST_CLI_NODE_PATH: external_exports.string().max(16384).optional(),
23793
24121
  CODEXHOST_RUNTIME_ENDPOINT: external_exports.string().max(16384).optional(),
23794
24122
  CODEXHOST_RUNTIME_TOKEN: external_exports.string().max(16384).optional(),
23795
24123
  CODEXHOST_THREAD_ID: external_exports.string().max(256).optional()
@@ -23944,6 +24272,7 @@ var eventKeys = /* @__PURE__ */ new Map([
23944
24272
  ["item.started", /* @__PURE__ */ new Set(["type", "turnId", "item"])],
23945
24273
  ["item.updated", /* @__PURE__ */ new Set(["type", "turnId", "itemId", "update"])],
23946
24274
  ["item.completed", /* @__PURE__ */ new Set(["type", "turnId", "snapshot"])],
24275
+ ["item.detached", /* @__PURE__ */ new Set(["type", "turnId", "itemId"])],
23947
24276
  ["interaction.closed", /* @__PURE__ */ new Set(["type", "interactionId", "turnId", "reason"])],
23948
24277
  ["turn.completed", /* @__PURE__ */ new Set(["type", "turnId", "nativeTurnRef", "outcome"])],
23949
24278
  ["session.faulted", /* @__PURE__ */ new Set(["type", "error"])]
@@ -24072,7 +24401,7 @@ async function readDescriptor(descriptorPath) {
24072
24401
  throw new Error("Aqua Harness broker descriptor belongs to another user");
24073
24402
  }
24074
24403
  }
24075
- const descriptor = harnessBrokerDescriptorSchema.parse(JSON.parse(await readFile3(descriptorPath, "utf8")));
24404
+ const descriptor = harnessBrokerDescriptorSchema.parse(JSON.parse(await readFile4(descriptorPath, "utf8")));
24076
24405
  if (process.platform === "darwin" && Buffer.byteLength(descriptor.socketPath) > 103) {
24077
24406
  throw new Error("Aqua Harness broker socket path is too long for macOS");
24078
24407
  }
@@ -24512,6 +24841,7 @@ var BrokeredHarnessAdapter = class {
24512
24841
  if (this.#forwardEnvironment && input.environment) {
24513
24842
  const allowed = [
24514
24843
  "CODEXHOST_CLI_PATH",
24844
+ "CODEXHOST_CLI_NODE_PATH",
24515
24845
  "CODEXHOST_RUNTIME_ENDPOINT",
24516
24846
  "CODEXHOST_RUNTIME_TOKEN",
24517
24847
  "CODEXHOST_THREAD_ID"
@@ -24577,7 +24907,10 @@ function createHarnessAdapter(context) {
24577
24907
  liveCommandCatalog: true,
24578
24908
  environment: { ...context.environment }
24579
24909
  });
24580
- return new CodeBuddyAdapter({ environment: { ...context.environment } });
24910
+ const environment = { ...context.environment };
24911
+ return Object.assign(new CodeBuddyAdapter({ environment }), {
24912
+ installation: createCodeBuddyInstallation(environment)
24913
+ });
24581
24914
  }
24582
24915
  export {
24583
24916
  createHarnessAdapter